summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore6
-rw-r--r--qpid/LICENSE2
-rw-r--r--qpid/NOTICE2
-rw-r--r--qpid/QPID_VERSION.txt2
-rw-r--r--qpid/README.txt14
-rwxr-xr-xqpid/bin/release.sh36
-rw-r--r--qpid/cpp/Makefile.am4
-rw-r--r--qpid/cpp/bindings/qmf/python/Makefile.am4
-rw-r--r--qpid/cpp/bindings/qmf/ruby/Makefile.am4
-rw-r--r--qpid/cpp/bindings/qmf/tests/test_base.rb3
-rw-r--r--qpid/cpp/bindings/qmf2/python/Makefile.am4
-rw-r--r--qpid/cpp/bindings/qmf2/qmf2.i1
-rw-r--r--qpid/cpp/bindings/qmf2/ruby/Makefile.am4
-rw-r--r--qpid/cpp/bindings/qpid/Makefile.am2
-rw-r--r--qpid/cpp/bindings/qpid/dotnet/src/Address.cpp24
-rw-r--r--qpid/cpp/bindings/qpid/dotnet/src/Address.h1
-rw-r--r--qpid/cpp/bindings/qpid/dotnet/src/Connection.cpp24
-rw-r--r--qpid/cpp/bindings/qpid/dotnet/src/Connection.h1
-rw-r--r--qpid/cpp/bindings/qpid/dotnet/src/Duration.h12
-rw-r--r--qpid/cpp/bindings/qpid/dotnet/src/FailoverUpdates.h1
-rw-r--r--qpid/cpp/bindings/qpid/dotnet/src/Message.cpp26
-rw-r--r--qpid/cpp/bindings/qpid/dotnet/src/Message.h1
-rw-r--r--qpid/cpp/bindings/qpid/dotnet/src/Receiver.cpp25
-rw-r--r--qpid/cpp/bindings/qpid/dotnet/src/Receiver.h1
-rw-r--r--qpid/cpp/bindings/qpid/dotnet/src/Sender.cpp25
-rw-r--r--qpid/cpp/bindings/qpid/dotnet/src/Sender.h1
-rw-r--r--qpid/cpp/bindings/qpid/dotnet/src/Session.cpp51
-rw-r--r--qpid/cpp/bindings/qpid/dotnet/src/Session.h3
-rw-r--r--qpid/cpp/bindings/qpid/perl/CMakeLists.txt2
-rw-r--r--qpid/cpp/bindings/qpid/perl/Makefile.am4
-rw-r--r--qpid/cpp/bindings/qpid/python/Makefile.am6
-rw-r--r--qpid/cpp/bindings/qpid/python/python.i273
-rw-r--r--qpid/cpp/bindings/qpid/qpid.i1
-rw-r--r--qpid/cpp/bindings/qpid/ruby/CMakeLists.txt2
-rw-r--r--qpid/cpp/bindings/qpid/ruby/Makefile.am6
-rw-r--r--qpid/cpp/bindings/qpid/ruby/README.rdoc27
-rw-r--r--qpid/cpp/bindings/qpid/ruby/Rakefile74
-rw-r--r--qpid/cpp/bindings/qpid/ruby/lib/qpid.rb29
-rw-r--r--qpid/cpp/bindings/qpid/ruby/lib/qpid/address.rb125
-rw-r--r--qpid/cpp/bindings/qpid/ruby/lib/qpid/connection.rb134
-rw-r--r--qpid/cpp/bindings/qpid/ruby/lib/qpid/duration.rb63
-rw-r--r--qpid/cpp/bindings/qpid/ruby/lib/qpid/encoding.rb56
-rw-r--r--qpid/cpp/bindings/qpid/ruby/lib/qpid/errors.rb30
-rw-r--r--qpid/cpp/bindings/qpid/ruby/lib/qpid/message.rb129
-rw-r--r--qpid/cpp/bindings/qpid/ruby/lib/qpid/receiver.rb102
-rw-r--r--qpid/cpp/bindings/qpid/ruby/lib/qpid/sender.rb82
-rw-r--r--qpid/cpp/bindings/qpid/ruby/lib/qpid/session.rb186
-rw-r--r--qpid/cpp/bindings/qpid/ruby/lib/qpid/version.rb31
-rw-r--r--qpid/cpp/bindings/qpid/ruby/test/test_address.rb39
-rw-r--r--qpid/cpp/bindings/qpid/ruby/test/test_connection.rb257
-rw-r--r--qpid/cpp/bindings/qpid/ruby/test/test_encoding.rb146
-rw-r--r--qpid/cpp/bindings/qpid/ruby/test/test_message.rb307
-rw-r--r--qpid/cpp/bindings/qpid/ruby/test/test_receiver.rb238
-rw-r--r--qpid/cpp/bindings/qpid/ruby/test/test_sender.rb183
-rw-r--r--qpid/cpp/bindings/qpid/ruby/test/test_session.rb445
-rw-r--r--qpid/cpp/bindings/qpid/ruby/test/ts_bindings.rb30
-rw-r--r--qpid/cpp/bindings/swig_ruby_typemaps.i2
-rw-r--r--qpid/cpp/bld-winsdk.ps13
-rw-r--r--qpid/cpp/configure.ac21
-rw-r--r--qpid/cpp/docs/api/developer.doxygen.in2
-rw-r--r--qpid/cpp/docs/api/footer.html2
-rw-r--r--qpid/cpp/docs/api/user.doxygen.in2
-rw-r--r--qpid/cpp/docs/man/Makefile.am23
-rw-r--r--qpid/cpp/docs/man/qpidd.1247
-rw-r--r--qpid/cpp/docs/man/qpidd.x2
-rw-r--r--qpid/cpp/etc/Makefile.am23
-rw-r--r--qpid/cpp/etc/qpidd.conf2
-rw-r--r--qpid/cpp/etc/sasl2/qpidd.conf5
-rw-r--r--qpid/cpp/examples/CMakeLists.txt13
-rw-r--r--qpid/cpp/examples/Makefile.am16
-rw-r--r--qpid/cpp/examples/README.verify (renamed from qpid/cpp/examples/old_api/README.verify)0
-rw-r--r--qpid/cpp/examples/direct/CMakeLists.txt (renamed from qpid/cpp/examples/old_api/direct/CMakeLists.txt)0
-rw-r--r--qpid/cpp/examples/direct/Makefile.am47
-rw-r--r--qpid/cpp/examples/direct/declare_queues.cpp (renamed from qpid/cpp/examples/old_api/direct/declare_queues.cpp)0
-rw-r--r--qpid/cpp/examples/direct/direct_declare_queues.vcproj (renamed from qpid/cpp/examples/old_api/direct/direct_declare_queues.vcproj)0
-rw-r--r--qpid/cpp/examples/direct/direct_direct_producer.vcproj (renamed from qpid/cpp/examples/old_api/direct/direct_direct_producer.vcproj)0
-rw-r--r--qpid/cpp/examples/direct/direct_listener.vcproj (renamed from qpid/cpp/examples/old_api/direct/direct_listener.vcproj)0
-rw-r--r--qpid/cpp/examples/direct/direct_producer.cpp (renamed from qpid/cpp/examples/old_api/direct/direct_producer.cpp)0
-rw-r--r--qpid/cpp/examples/direct/listener.cpp (renamed from qpid/cpp/examples/old_api/direct/listener.cpp)0
-rw-r--r--qpid/cpp/examples/direct/verify (renamed from qpid/cpp/examples/old_api/direct/verify)0
-rw-r--r--qpid/cpp/examples/direct/verify.in (renamed from qpid/cpp/examples/old_api/direct/verify.in)0
-rw-r--r--qpid/cpp/examples/examples.sln24
-rw-r--r--qpid/cpp/examples/failover/CMakeLists.txt (renamed from qpid/cpp/examples/old_api/failover/CMakeLists.txt)0
-rw-r--r--qpid/cpp/examples/failover/Makefile.am47
-rw-r--r--qpid/cpp/examples/failover/declare_queues.cpp (renamed from qpid/cpp/examples/old_api/failover/declare_queues.cpp)0
-rw-r--r--qpid/cpp/examples/failover/failover_declare_queues.vcproj (renamed from qpid/cpp/examples/old_api/failover/failover_declare_queues.vcproj)0
-rw-r--r--qpid/cpp/examples/failover/failover_replaying_sender.vcproj (renamed from qpid/cpp/examples/old_api/failover/failover_replaying_sender.vcproj)0
-rw-r--r--qpid/cpp/examples/failover/failover_resuming_receiver.vcproj (renamed from qpid/cpp/examples/old_api/failover/failover_resuming_receiver.vcproj)0
-rw-r--r--qpid/cpp/examples/failover/replaying_sender.cpp (renamed from qpid/cpp/examples/old_api/failover/replaying_sender.cpp)0
-rw-r--r--qpid/cpp/examples/failover/resuming_receiver.cpp (renamed from qpid/cpp/examples/old_api/failover/resuming_receiver.cpp)0
-rw-r--r--qpid/cpp/examples/fanout/CMakeLists.txt (renamed from qpid/cpp/examples/old_api/fanout/CMakeLists.txt)0
-rw-r--r--qpid/cpp/examples/fanout/Makefile.am42
-rw-r--r--qpid/cpp/examples/fanout/fanout_fanout_producer.vcproj (renamed from qpid/cpp/examples/old_api/fanout/fanout_fanout_producer.vcproj)0
-rw-r--r--qpid/cpp/examples/fanout/fanout_listener.vcproj (renamed from qpid/cpp/examples/old_api/fanout/fanout_listener.vcproj)0
-rw-r--r--qpid/cpp/examples/fanout/fanout_producer.cpp (renamed from qpid/cpp/examples/old_api/fanout/fanout_producer.cpp)0
-rw-r--r--qpid/cpp/examples/fanout/listener.cpp (renamed from qpid/cpp/examples/old_api/fanout/listener.cpp)0
-rw-r--r--qpid/cpp/examples/fanout/verify (renamed from qpid/cpp/examples/old_api/fanout/verify)0
-rw-r--r--qpid/cpp/examples/fanout/verify.in (renamed from qpid/cpp/examples/old_api/fanout/verify.in)0
-rw-r--r--qpid/cpp/examples/messaging/drain.cpp2
-rw-r--r--qpid/cpp/examples/messaging/server.cpp4
-rw-r--r--qpid/cpp/examples/messaging/spout.cpp2
-rw-r--r--qpid/cpp/examples/old-examples.sln147
-rw-r--r--qpid/cpp/examples/old_api/CMakeLists.txt25
-rw-r--r--qpid/cpp/examples/old_api/Makefile.am48
-rw-r--r--qpid/cpp/examples/old_api/direct/Makefile.am47
-rw-r--r--qpid/cpp/examples/old_api/failover/Makefile.am47
-rw-r--r--qpid/cpp/examples/old_api/fanout/Makefile.am42
-rw-r--r--qpid/cpp/examples/old_api/old-examples.sln123
-rw-r--r--qpid/cpp/examples/old_api/pub-sub/Makefile.am43
-rw-r--r--qpid/cpp/examples/old_api/request-response/Makefile.am43
-rw-r--r--qpid/cpp/examples/old_api/tradedemo/Makefile.am46
-rwxr-xr-xqpid/cpp/examples/old_api/verify_all46
-rw-r--r--qpid/cpp/examples/old_api/xml-exchange/Makefile.am49
-rw-r--r--qpid/cpp/examples/pub-sub/CMakeLists.txt (renamed from qpid/cpp/examples/old_api/pub-sub/CMakeLists.txt)0
-rw-r--r--qpid/cpp/examples/pub-sub/Makefile.am43
-rw-r--r--qpid/cpp/examples/pub-sub/pub-sub_topic_listener.vcproj (renamed from qpid/cpp/examples/old_api/pub-sub/pub-sub_topic_listener.vcproj)0
-rw-r--r--qpid/cpp/examples/pub-sub/pub-sub_topic_publisher.vcproj (renamed from qpid/cpp/examples/old_api/pub-sub/pub-sub_topic_publisher.vcproj)0
-rw-r--r--qpid/cpp/examples/pub-sub/topic_listener.cpp (renamed from qpid/cpp/examples/old_api/pub-sub/topic_listener.cpp)0
-rw-r--r--qpid/cpp/examples/pub-sub/topic_publisher.cpp (renamed from qpid/cpp/examples/old_api/pub-sub/topic_publisher.cpp)0
-rw-r--r--qpid/cpp/examples/pub-sub/verify (renamed from qpid/cpp/examples/old_api/pub-sub/verify)0
-rw-r--r--qpid/cpp/examples/pub-sub/verify.in (renamed from qpid/cpp/examples/old_api/pub-sub/verify.in)0
-rw-r--r--qpid/cpp/examples/qmf-console/ping.cpp4
-rw-r--r--qpid/cpp/examples/qmf-console/printevents.cpp4
-rw-r--r--qpid/cpp/examples/request-response/CMakeLists.txt (renamed from qpid/cpp/examples/old_api/request-response/CMakeLists.txt)0
-rw-r--r--qpid/cpp/examples/request-response/Makefile.am43
-rw-r--r--qpid/cpp/examples/request-response/client.cpp (renamed from qpid/cpp/examples/old_api/request-response/client.cpp)0
-rw-r--r--qpid/cpp/examples/request-response/request-response_client.vcproj (renamed from qpid/cpp/examples/old_api/request-response/request-response_client.vcproj)0
-rw-r--r--qpid/cpp/examples/request-response/request-response_server.vcproj (renamed from qpid/cpp/examples/old_api/request-response/request-response_server.vcproj)0
-rw-r--r--qpid/cpp/examples/request-response/server.cpp (renamed from qpid/cpp/examples/old_api/request-response/server.cpp)0
-rw-r--r--qpid/cpp/examples/request-response/verify (renamed from qpid/cpp/examples/old_api/request-response/verify)0
-rw-r--r--qpid/cpp/examples/request-response/verify.in (renamed from qpid/cpp/examples/old_api/request-response/verify.in)0
-rw-r--r--qpid/cpp/examples/tradedemo/CMakeLists.txt (renamed from qpid/cpp/examples/old_api/tradedemo/CMakeLists.txt)0
-rw-r--r--qpid/cpp/examples/tradedemo/Makefile.am46
-rw-r--r--qpid/cpp/examples/tradedemo/declare_queues.cpp (renamed from qpid/cpp/examples/old_api/tradedemo/declare_queues.cpp)0
-rw-r--r--qpid/cpp/examples/tradedemo/topic_listener.cpp (renamed from qpid/cpp/examples/old_api/tradedemo/topic_listener.cpp)0
-rw-r--r--qpid/cpp/examples/tradedemo/topic_publisher.cpp (renamed from qpid/cpp/examples/old_api/tradedemo/topic_publisher.cpp)0
-rw-r--r--qpid/cpp/examples/tradedemo/tradedemo_declare_queues.vcproj (renamed from qpid/cpp/examples/old_api/tradedemo/tradedemo_declare_queues.vcproj)0
-rw-r--r--qpid/cpp/examples/tradedemo/tradedemo_topic_listener.vcproj (renamed from qpid/cpp/examples/old_api/tradedemo/tradedemo_topic_listener.vcproj)0
-rw-r--r--qpid/cpp/examples/tradedemo/tradedemo_topic_publisher.vcproj (renamed from qpid/cpp/examples/old_api/tradedemo/tradedemo_topic_publisher.vcproj)0
-rwxr-xr-xqpid/cpp/examples/verify (renamed from qpid/cpp/examples/old_api/verify)0
-rwxr-xr-xqpid/cpp/examples/verify_all46
-rw-r--r--qpid/cpp/examples/xml-exchange/CMakeLists.txt (renamed from qpid/cpp/examples/old_api/xml-exchange/CMakeLists.txt)0
-rw-r--r--qpid/cpp/examples/xml-exchange/Makefile.am49
-rw-r--r--qpid/cpp/examples/xml-exchange/README.txt (renamed from qpid/cpp/examples/old_api/xml-exchange/README.txt)0
-rw-r--r--qpid/cpp/examples/xml-exchange/declare_queues.cpp (renamed from qpid/cpp/examples/old_api/xml-exchange/declare_queues.cpp)0
-rw-r--r--qpid/cpp/examples/xml-exchange/listener.cpp (renamed from qpid/cpp/examples/old_api/xml-exchange/listener.cpp)0
-rw-r--r--qpid/cpp/examples/xml-exchange/xml_producer.cpp (renamed from qpid/cpp/examples/old_api/xml-exchange/xml_producer.cpp)0
-rw-r--r--qpid/cpp/include/qmf/Agent.h2
-rw-r--r--qpid/cpp/include/qmf/AgentEvent.h2
-rw-r--r--qpid/cpp/include/qmf/AgentSession.h42
-rw-r--r--qpid/cpp/include/qmf/ConsoleEvent.h2
-rw-r--r--qpid/cpp/include/qmf/ConsoleSession.h50
-rw-r--r--qpid/cpp/include/qmf/Data.h2
-rw-r--r--qpid/cpp/include/qmf/DataAddr.h5
-rw-r--r--qpid/cpp/include/qmf/Handle.h10
-rw-r--r--qpid/cpp/include/qmf/ImportExport.h16
-rw-r--r--qpid/cpp/include/qmf/Query.h4
-rw-r--r--qpid/cpp/include/qmf/Schema.h2
-rw-r--r--qpid/cpp/include/qmf/SchemaId.h2
-rw-r--r--qpid/cpp/include/qmf/SchemaMethod.h2
-rw-r--r--qpid/cpp/include/qmf/SchemaProperty.h2
-rw-r--r--qpid/cpp/include/qmf/Subscription.h4
-rw-r--r--qpid/cpp/include/qmf/engine/QmfEngineImportExport.h9
-rw-r--r--qpid/cpp/include/qmf/exceptions.h8
-rwxr-xr-xqpid/cpp/include/qpid/Address.h2
-rw-r--r--qpid/cpp/include/qpid/CommonImportExport.h14
-rw-r--r--qpid/cpp/include/qpid/Exception.h12
-rw-r--r--qpid/cpp/include/qpid/ImportExport.h71
-rw-r--r--qpid/cpp/include/qpid/Options.h88
-rw-r--r--qpid/cpp/include/qpid/Url.h2
-rw-r--r--qpid/cpp/include/qpid/agent/ManagementAgent.h4
-rw-r--r--qpid/cpp/include/qpid/agent/QmfAgentImportExport.h16
-rw-r--r--qpid/cpp/include/qpid/client/ClientImportExport.h14
-rw-r--r--qpid/cpp/include/qpid/client/Completion.h2
-rw-r--r--qpid/cpp/include/qpid/client/Connection.h10
-rw-r--r--qpid/cpp/include/qpid/client/ConnectionSettings.h2
-rw-r--r--qpid/cpp/include/qpid/client/FailoverListener.h2
-rw-r--r--qpid/cpp/include/qpid/client/FailoverManager.h2
-rw-r--r--qpid/cpp/include/qpid/client/Future.h2
-rw-r--r--qpid/cpp/include/qpid/client/FutureResult.h2
-rw-r--r--qpid/cpp/include/qpid/client/Handle.h10
-rw-r--r--qpid/cpp/include/qpid/client/LocalQueue.h2
-rw-r--r--qpid/cpp/include/qpid/client/Message.h2
-rw-r--r--qpid/cpp/include/qpid/client/MessageListener.h2
-rw-r--r--qpid/cpp/include/qpid/client/MessageReplayTracker.h2
-rw-r--r--qpid/cpp/include/qpid/client/QueueOptions.h2
-rw-r--r--qpid/cpp/include/qpid/client/SessionBase_0_10.h2
-rw-r--r--qpid/cpp/include/qpid/client/Subscription.h8
-rw-r--r--qpid/cpp/include/qpid/client/SubscriptionManager.h2
-rw-r--r--qpid/cpp/include/qpid/console/Agent.h14
-rw-r--r--qpid/cpp/include/qpid/console/Broker.h16
-rw-r--r--qpid/cpp/include/qpid/console/ConsoleImportExport.h14
-rw-r--r--qpid/cpp/include/qpid/framing/Array.h26
-rw-r--r--qpid/cpp/include/qpid/framing/Buffer.h16
-rw-r--r--qpid/cpp/include/qpid/framing/FieldTable.h6
-rw-r--r--qpid/cpp/include/qpid/framing/FieldValue.h21
-rw-r--r--qpid/cpp/include/qpid/framing/List.h25
-rw-r--r--qpid/cpp/include/qpid/framing/ProtocolVersion.h12
-rw-r--r--qpid/cpp/include/qpid/framing/SequenceNumber.h2
-rw-r--r--qpid/cpp/include/qpid/framing/SequenceSet.h2
-rw-r--r--qpid/cpp/include/qpid/framing/StructHelper.h2
-rw-r--r--qpid/cpp/include/qpid/framing/Uuid.h10
-rw-r--r--qpid/cpp/include/qpid/log/Logger.h6
-rw-r--r--qpid/cpp/include/qpid/log/Options.h2
-rw-r--r--qpid/cpp/include/qpid/management/ManagementObject.h18
-rw-r--r--qpid/cpp/include/qpid/messaging/Address.h2
-rw-r--r--qpid/cpp/include/qpid/messaging/Connection.h30
-rw-r--r--qpid/cpp/include/qpid/messaging/Duration.h8
-rw-r--r--qpid/cpp/include/qpid/messaging/FailoverUpdates.h2
-rw-r--r--qpid/cpp/include/qpid/messaging/Handle.h10
-rw-r--r--qpid/cpp/include/qpid/messaging/ImportExport.h14
-rw-r--r--qpid/cpp/include/qpid/messaging/Message.h101
-rw-r--r--qpid/cpp/include/qpid/messaging/Receiver.h2
-rw-r--r--qpid/cpp/include/qpid/messaging/Sender.h2
-rw-r--r--qpid/cpp/include/qpid/messaging/Session.h6
-rw-r--r--qpid/cpp/include/qpid/messaging/exceptions.h42
-rw-r--r--qpid/cpp/include/qpid/sys/ExceptionHolder.h13
-rwxr-xr-xqpid/cpp/include/qpid/sys/IntegerTypes.h2
-rw-r--r--qpid/cpp/include/qpid/sys/Runnable.h2
-rw-r--r--qpid/cpp/include/qpid/sys/Thread.h6
-rw-r--r--qpid/cpp/include/qpid/sys/Time.h5
-rwxr-xr-xqpid/cpp/include/qpid/sys/windows/IntegerTypes.h6
-rw-r--r--qpid/cpp/include/qpid/types/Exception.h2
-rw-r--r--qpid/cpp/include/qpid/types/ImportExport.h14
-rw-r--r--qpid/cpp/include/qpid/types/Uuid.h2
-rw-r--r--qpid/cpp/include/qpid/types/Variant.h6
-rw-r--r--qpid/cpp/managementgen/Makefile.am12
-rwxr-xr-xqpid/cpp/managementgen/qmfgen/schema.py4
-rwxr-xr-xqpid/cpp/rubygen/0-10/specification.rb2
-rwxr-xr-xqpid/cpp/rubygen/MethodBodyDefaultVisitor.rb2
-rwxr-xr-xqpid/cpp/rubygen/amqpgen.rb3
-rwxr-xr-xqpid/cpp/rubygen/cppgen.rb3
-rwxr-xr-xqpid/cpp/rubygen/framing.0-10/MethodBodyDefaultVisitor.rb2
-rwxr-xr-xqpid/cpp/rubygen/framing.0-10/OperationsInvoker.rb2
-rwxr-xr-xqpid/cpp/rubygen/framing.0-10/Proxy.rb4
-rwxr-xr-xqpid/cpp/rubygen/framing.0-10/Session.rb4
-rwxr-xr-xqpid/cpp/rubygen/framing.0-10/structs.rb2
-rw-r--r--qpid/cpp/src/CMakeLists.txt29
-rw-r--r--qpid/cpp/src/CMakeWinVersions.cmake12
-rw-r--r--qpid/cpp/src/Makefile.am39
-rw-r--r--qpid/cpp/src/acl.mk4
-rw-r--r--qpid/cpp/src/cluster.mk6
-rw-r--r--qpid/cpp/src/posix/QpiddBroker.cpp12
-rw-r--r--qpid/cpp/src/qmf/Agent.cpp29
-rw-r--r--qpid/cpp/src/qmf/AgentImpl.h1
-rw-r--r--qpid/cpp/src/qmf/AgentSession.cpp11
-rw-r--r--qpid/cpp/src/qmf/ConsoleSession.cpp32
-rw-r--r--qpid/cpp/src/qmf/ConsoleSessionImpl.h4
-rw-r--r--qpid/cpp/src/qmf/DataAddr.cpp6
-rw-r--r--qpid/cpp/src/qmf/DataAddrImpl.h4
-rw-r--r--qpid/cpp/src/qmf/PrivateImplRef.h2
-rw-r--r--qpid/cpp/src/qmf/engine/ResilientConnection.cpp6
-rw-r--r--qpid/cpp/src/qmf/engine/SchemaImpl.cpp9
-rw-r--r--qpid/cpp/src/qpid/BufferRef.h70
-rw-r--r--qpid/cpp/src/qpid/DisableExceptionLogging.h39
-rw-r--r--qpid/cpp/src/qpid/Exception.cpp16
-rw-r--r--qpid/cpp/src/qpid/Modules.cpp3
-rw-r--r--qpid/cpp/src/qpid/Options.cpp269
-rw-r--r--qpid/cpp/src/qpid/RefCounted.h6
-rw-r--r--qpid/cpp/src/qpid/RefCountedBuffer.cpp22
-rw-r--r--qpid/cpp/src/qpid/RefCountedBuffer.h61
-rw-r--r--qpid/cpp/src/qpid/SaslFactory.cpp17
-rw-r--r--qpid/cpp/src/qpid/acl/Acl.cpp5
-rw-r--r--qpid/cpp/src/qpid/agent/ManagementAgentImpl.cpp342
-rw-r--r--qpid/cpp/src/qpid/agent/ManagementAgentImpl.h4
-rw-r--r--qpid/cpp/src/qpid/amqp_0_10/Codecs.cpp6
-rw-r--r--qpid/cpp/src/qpid/amqp_0_10/SessionHandler.cpp8
-rw-r--r--qpid/cpp/src/qpid/amqp_0_10/SessionHandler.h6
-rw-r--r--qpid/cpp/src/qpid/broker/AsyncCompletion.h63
-rw-r--r--qpid/cpp/src/qpid/broker/Bridge.cpp6
-rw-r--r--qpid/cpp/src/qpid/broker/Bridge.h2
-rw-r--r--qpid/cpp/src/qpid/broker/Broker.cpp47
-rw-r--r--qpid/cpp/src/qpid/broker/Broker.h5
-rw-r--r--qpid/cpp/src/qpid/broker/BrokerImportExport.h23
-rw-r--r--qpid/cpp/src/qpid/broker/Connection.cpp43
-rw-r--r--qpid/cpp/src/qpid/broker/Connection.h9
-rw-r--r--qpid/cpp/src/qpid/broker/ConnectionHandler.cpp12
-rw-r--r--qpid/cpp/src/qpid/broker/ConnectionState.h9
-rw-r--r--qpid/cpp/src/qpid/broker/Consumer.h7
-rw-r--r--qpid/cpp/src/qpid/broker/Daemon.cpp5
-rw-r--r--qpid/cpp/src/qpid/broker/DeliverableMessage.h2
-rw-r--r--qpid/cpp/src/qpid/broker/DeliveryRecord.cpp4
-rw-r--r--qpid/cpp/src/qpid/broker/DirectExchange.cpp11
-rw-r--r--qpid/cpp/src/qpid/broker/Exchange.cpp83
-rw-r--r--qpid/cpp/src/qpid/broker/Exchange.h48
-rw-r--r--qpid/cpp/src/qpid/broker/ExchangeRegistry.cpp11
-rw-r--r--qpid/cpp/src/qpid/broker/ExpiryPolicy.cpp10
-rw-r--r--qpid/cpp/src/qpid/broker/ExpiryPolicy.h14
-rw-r--r--qpid/cpp/src/qpid/broker/Fairshare.cpp76
-rw-r--r--qpid/cpp/src/qpid/broker/Fairshare.h6
-rw-r--r--qpid/cpp/src/qpid/broker/FanOutExchange.cpp11
-rw-r--r--qpid/cpp/src/qpid/broker/HeadersExchange.cpp20
-rw-r--r--qpid/cpp/src/qpid/broker/LegacyLVQ.cpp6
-rw-r--r--qpid/cpp/src/qpid/broker/Link.cpp65
-rw-r--r--qpid/cpp/src/qpid/broker/Link.h10
-rw-r--r--qpid/cpp/src/qpid/broker/LinkRegistry.cpp6
-rw-r--r--qpid/cpp/src/qpid/broker/Message.cpp137
-rw-r--r--qpid/cpp/src/qpid/broker/Message.h67
-rw-r--r--qpid/cpp/src/qpid/broker/MessageBuilder.h2
-rw-r--r--qpid/cpp/src/qpid/broker/Messages.h3
-rw-r--r--qpid/cpp/src/qpid/broker/NullMessageStore.cpp4
-rw-r--r--qpid/cpp/src/qpid/broker/NullMessageStore.h4
-rw-r--r--qpid/cpp/src/qpid/broker/PersistableMessage.h11
-rw-r--r--qpid/cpp/src/qpid/broker/Queue.cpp184
-rw-r--r--qpid/cpp/src/qpid/broker/Queue.h66
-rw-r--r--qpid/cpp/src/qpid/broker/QueueCleaner.cpp18
-rw-r--r--qpid/cpp/src/qpid/broker/QueueCleaner.h14
-rw-r--r--qpid/cpp/src/qpid/broker/QueueFlowLimit.cpp174
-rw-r--r--qpid/cpp/src/qpid/broker/QueueFlowLimit.h13
-rw-r--r--qpid/cpp/src/qpid/broker/QueueListeners.cpp36
-rw-r--r--qpid/cpp/src/qpid/broker/QueueListeners.h4
-rw-r--r--qpid/cpp/src/qpid/broker/QueuePolicy.cpp20
-rw-r--r--qpid/cpp/src/qpid/broker/QueuePolicy.h3
-rw-r--r--qpid/cpp/src/qpid/broker/QueueRegistry.cpp20
-rw-r--r--qpid/cpp/src/qpid/broker/QueueRegistry.h7
-rw-r--r--qpid/cpp/src/qpid/broker/RateTracker.cpp51
-rw-r--r--qpid/cpp/src/qpid/broker/RateTracker.h57
-rw-r--r--qpid/cpp/src/qpid/broker/RecoveredDequeue.cpp1
-rw-r--r--qpid/cpp/src/qpid/broker/RecoveredEnqueue.cpp1
-rw-r--r--qpid/cpp/src/qpid/broker/RecoveryManagerImpl.cpp3
-rw-r--r--qpid/cpp/src/qpid/broker/SaslAuthenticator.cpp8
-rw-r--r--qpid/cpp/src/qpid/broker/SemanticState.cpp69
-rw-r--r--qpid/cpp/src/qpid/broker/SemanticState.h2
-rw-r--r--qpid/cpp/src/qpid/broker/SessionAdapter.cpp14
-rw-r--r--qpid/cpp/src/qpid/broker/SessionHandler.cpp5
-rw-r--r--qpid/cpp/src/qpid/broker/SessionState.cpp221
-rw-r--r--qpid/cpp/src/qpid/broker/SessionState.h135
-rw-r--r--qpid/cpp/src/qpid/broker/StatefulQueueObserver.h63
-rw-r--r--qpid/cpp/src/qpid/broker/ThresholdAlerts.cpp68
-rw-r--r--qpid/cpp/src/qpid/broker/ThresholdAlerts.h4
-rw-r--r--qpid/cpp/src/qpid/broker/TopicExchange.cpp84
-rw-r--r--qpid/cpp/src/qpid/broker/TopicExchange.h29
-rw-r--r--qpid/cpp/src/qpid/broker/TxPublish.cpp9
-rw-r--r--qpid/cpp/src/qpid/broker/TxPublish.h2
-rw-r--r--qpid/cpp/src/qpid/broker/windows/BrokerDefaults.cpp6
-rw-r--r--qpid/cpp/src/qpid/broker/windows/SaslAuthenticator.cpp8
-rw-r--r--qpid/cpp/src/qpid/broker/windows/SslProtocolFactory.cpp11
-rw-r--r--qpid/cpp/src/qpid/client/ConnectionHandler.cpp52
-rw-r--r--qpid/cpp/src/qpid/client/ConnectionImpl.cpp12
-rw-r--r--qpid/cpp/src/qpid/client/Connector.h2
-rw-r--r--qpid/cpp/src/qpid/client/RdmaConnector.cpp6
-rw-r--r--qpid/cpp/src/qpid/client/SessionImpl.cpp1
-rw-r--r--qpid/cpp/src/qpid/client/SslConnector.cpp6
-rw-r--r--qpid/cpp/src/qpid/client/TCPConnector.cpp6
-rw-r--r--qpid/cpp/src/qpid/client/TCPConnector.h2
-rw-r--r--qpid/cpp/src/qpid/client/amqp0_10/AcceptTracker.cpp42
-rw-r--r--qpid/cpp/src/qpid/client/amqp0_10/AcceptTracker.h5
-rw-r--r--qpid/cpp/src/qpid/client/amqp0_10/AddressResolution.cpp23
-rw-r--r--qpid/cpp/src/qpid/client/amqp0_10/ConnectionImpl.cpp164
-rw-r--r--qpid/cpp/src/qpid/client/amqp0_10/ConnectionImpl.h2
-rw-r--r--qpid/cpp/src/qpid/client/amqp0_10/IncomingMessages.cpp4
-rw-r--r--qpid/cpp/src/qpid/client/amqp0_10/IncomingMessages.h2
-rw-r--r--qpid/cpp/src/qpid/client/amqp0_10/OutgoingMessage.cpp4
-rw-r--r--qpid/cpp/src/qpid/client/amqp0_10/SenderImpl.cpp3
-rw-r--r--qpid/cpp/src/qpid/client/amqp0_10/SessionImpl.cpp18
-rw-r--r--qpid/cpp/src/qpid/client/amqp0_10/SessionImpl.h11
-rw-r--r--qpid/cpp/src/qpid/client/windows/SaslFactory.cpp4
-rw-r--r--qpid/cpp/src/qpid/client/windows/SslConnector.cpp4
-rw-r--r--qpid/cpp/src/qpid/cluster/Cluster.cpp74
-rw-r--r--qpid/cpp/src/qpid/cluster/Cluster.h20
-rw-r--r--qpid/cpp/src/qpid/cluster/ClusterMap.cpp5
-rw-r--r--qpid/cpp/src/qpid/cluster/ClusterPlugin.cpp1
-rw-r--r--qpid/cpp/src/qpid/cluster/ClusterSettings.h3
-rw-r--r--qpid/cpp/src/qpid/cluster/ClusterTimer.cpp4
-rw-r--r--qpid/cpp/src/qpid/cluster/Connection.cpp106
-rw-r--r--qpid/cpp/src/qpid/cluster/Connection.h35
-rw-r--r--qpid/cpp/src/qpid/cluster/Decoder.h2
-rw-r--r--qpid/cpp/src/qpid/cluster/ErrorCheck.h2
-rw-r--r--qpid/cpp/src/qpid/cluster/Event.cpp5
-rw-r--r--qpid/cpp/src/qpid/cluster/Event.h12
-rw-r--r--qpid/cpp/src/qpid/cluster/ExpiryPolicy.cpp95
-rw-r--r--qpid/cpp/src/qpid/cluster/ExpiryPolicy.h42
-rw-r--r--qpid/cpp/src/qpid/cluster/FailoverExchange.cpp26
-rw-r--r--qpid/cpp/src/qpid/cluster/FailoverExchange.h10
-rw-r--r--qpid/cpp/src/qpid/cluster/OutputInterceptor.cpp39
-rw-r--r--qpid/cpp/src/qpid/cluster/OutputInterceptor.h10
-rw-r--r--qpid/cpp/src/qpid/cluster/UpdateClient.cpp105
-rw-r--r--qpid/cpp/src/qpid/cluster/UpdateClient.h22
-rw-r--r--qpid/cpp/src/qpid/cluster/UpdateDataExchange.cpp10
-rw-r--r--qpid/cpp/src/qpid/cluster/UpdateDataExchange.h2
-rw-r--r--qpid/cpp/src/qpid/cluster/UpdateExchange.cpp27
-rw-r--r--qpid/cpp/src/qpid/cluster/types.h1
-rw-r--r--qpid/cpp/src/qpid/console/SessionManager.cpp3
-rw-r--r--qpid/cpp/src/qpid/framing/AMQBody.h2
-rw-r--r--qpid/cpp/src/qpid/framing/AMQContentBody.h12
-rw-r--r--qpid/cpp/src/qpid/framing/AMQFrame.cpp5
-rw-r--r--qpid/cpp/src/qpid/framing/AMQFrame.h7
-rw-r--r--qpid/cpp/src/qpid/framing/AMQHeaderBody.h14
-rw-r--r--qpid/cpp/src/qpid/framing/AMQHeartbeatBody.h2
-rw-r--r--qpid/cpp/src/qpid/framing/FieldTable.cpp2
-rw-r--r--qpid/cpp/src/qpid/framing/MethodBodyFactory.h1
-rw-r--r--qpid/cpp/src/qpid/framing/SendContent.h2
-rw-r--r--qpid/cpp/src/qpid/framing/TransferContent.h2
-rw-r--r--qpid/cpp/src/qpid/log/Logger.cpp21
-rw-r--r--qpid/cpp/src/qpid/log/Options.cpp4
-rw-r--r--qpid/cpp/src/qpid/log/windows/SinkOptions.cpp4
-rw-r--r--qpid/cpp/src/qpid/log/windows/SinkOptions.h2
-rw-r--r--qpid/cpp/src/qpid/management/ManagementAgent.cpp208
-rw-r--r--qpid/cpp/src/qpid/management/ManagementAgent.h6
-rw-r--r--qpid/cpp/src/qpid/messaging/AddressParser.cpp2
-rw-r--r--qpid/cpp/src/qpid/messaging/Duration.cpp10
-rw-r--r--qpid/cpp/src/qpid/messaging/Session.cpp3
-rw-r--r--qpid/cpp/src/qpid/messaging/SessionImpl.h2
-rw-r--r--qpid/cpp/src/qpid/replication/ReplicatingEventListener.cpp7
-rw-r--r--qpid/cpp/src/qpid/replication/ReplicationExchange.cpp9
-rw-r--r--qpid/cpp/src/qpid/store/StorageProvider.h2
-rw-r--r--qpid/cpp/src/qpid/sys/AggregateOutput.h2
-rw-r--r--qpid/cpp/src/qpid/sys/AsynchIO.h4
-rw-r--r--qpid/cpp/src/qpid/sys/AsynchIOHandler.h2
-rw-r--r--qpid/cpp/src/qpid/sys/AtomicValue.h7
-rw-r--r--qpid/cpp/src/qpid/sys/AtomicValue_gcc.h11
-rw-r--r--qpid/cpp/src/qpid/sys/ClusterSafe.cpp10
-rw-r--r--qpid/cpp/src/qpid/sys/ClusterSafe.h18
-rw-r--r--qpid/cpp/src/qpid/sys/PollableQueue.h21
-rw-r--r--qpid/cpp/src/qpid/sys/Poller.h2
-rw-r--r--qpid/cpp/src/qpid/sys/ProtocolFactory.h3
-rw-r--r--qpid/cpp/src/qpid/sys/RdmaIOPlugin.cpp24
-rw-r--r--qpid/cpp/src/qpid/sys/Socket.h27
-rw-r--r--qpid/cpp/src/qpid/sys/SocketAddress.h2
-rw-r--r--qpid/cpp/src/qpid/sys/SslPlugin.cpp11
-rw-r--r--qpid/cpp/src/qpid/sys/StateMonitor.h14
-rw-r--r--qpid/cpp/src/qpid/sys/TCPIOPlugin.cpp29
-rw-r--r--qpid/cpp/src/qpid/sys/Timer.cpp22
-rw-r--r--qpid/cpp/src/qpid/sys/Timer.h8
-rw-r--r--qpid/cpp/src/qpid/sys/TimerWarnings.cpp12
-rw-r--r--qpid/cpp/src/qpid/sys/alloca.h29
-rw-r--r--qpid/cpp/src/qpid/sys/cyrus/CyrusSecurityLayer.cpp2
-rw-r--r--qpid/cpp/src/qpid/sys/posix/AsynchIO.cpp14
-rwxr-xr-xqpid/cpp/src/qpid/sys/posix/LockFile.cpp3
-rw-r--r--qpid/cpp/src/qpid/sys/posix/Socket.cpp132
-rw-r--r--qpid/cpp/src/qpid/sys/posix/SocketAddress.cpp32
-rw-r--r--qpid/cpp/src/qpid/sys/posix/Thread.cpp3
-rw-r--r--qpid/cpp/src/qpid/sys/posix/Time.cpp7
-rw-r--r--qpid/cpp/src/qpid/sys/rdma/RdmaIO.cpp14
-rw-r--r--qpid/cpp/src/qpid/sys/rdma/rdma_wrap.cpp15
-rw-r--r--qpid/cpp/src/qpid/sys/rdma/rdma_wrap.h10
-rw-r--r--qpid/cpp/src/qpid/sys/ssl/SslHandler.h2
-rw-r--r--qpid/cpp/src/qpid/sys/ssl/SslIo.cpp2
-rw-r--r--qpid/cpp/src/qpid/sys/ssl/SslIo.h2
-rw-r--r--qpid/cpp/src/qpid/sys/ssl/SslSocket.cpp4
-rw-r--r--qpid/cpp/src/qpid/sys/ssl/SslSocket.h2
-rw-r--r--qpid/cpp/src/qpid/sys/windows/AsynchIO.cpp24
-rwxr-xr-xqpid/cpp/src/qpid/sys/windows/AsynchIoResult.h2
-rwxr-xr-xqpid/cpp/src/qpid/sys/windows/IocpPoller.cpp6
-rw-r--r--qpid/cpp/src/qpid/sys/windows/Shlib.cpp3
-rwxr-xr-xqpid/cpp/src/qpid/sys/windows/Socket.cpp96
-rw-r--r--qpid/cpp/src/qpid/sys/windows/SocketAddress.cpp7
-rwxr-xr-xqpid/cpp/src/qpid/sys/windows/StrError.cpp7
-rwxr-xr-xqpid/cpp/src/qpid/sys/windows/Thread.cpp285
-rw-r--r--qpid/cpp/src/qpid/sys/windows/Time.cpp36
-rw-r--r--qpid/cpp/src/qpid/sys/windows/mingw32_compat.h39
-rw-r--r--qpid/cpp/src/qpid/sys/windows/uuid.cpp6
-rw-r--r--qpid/cpp/src/qpid/types/Variant.cpp34
-rw-r--r--qpid/cpp/src/replication.mk6
-rw-r--r--qpid/cpp/src/ssl.mk6
-rw-r--r--qpid/cpp/src/tests/.valgrind.supp74
-rw-r--r--qpid/cpp/src/tests/Address.cpp11
-rw-r--r--qpid/cpp/src/tests/BrokerMgmtAgent.cpp3
-rw-r--r--qpid/cpp/src/tests/CMakeLists.txt2
-rw-r--r--qpid/cpp/src/tests/ClientSessionTest.cpp7
-rw-r--r--qpid/cpp/src/tests/ExchangeTest.cpp2
-rw-r--r--qpid/cpp/src/tests/ForkedBroker.cpp3
-rw-r--r--qpid/cpp/src/tests/Makefile.am17
-rw-r--r--qpid/cpp/src/tests/MessageUtils.h14
-rw-r--r--qpid/cpp/src/tests/MessagingSessionTests.cpp108
-rw-r--r--qpid/cpp/src/tests/QueueFlowLimitTest.cpp2
-rw-r--r--qpid/cpp/src/tests/QueuePolicyTest.cpp1
-rw-r--r--qpid/cpp/src/tests/QueueTest.cpp90
-rw-r--r--qpid/cpp/src/tests/SessionState.cpp8
-rw-r--r--qpid/cpp/src/tests/SocketProxy.h4
-rw-r--r--qpid/cpp/src/tests/TimerTest.cpp4
-rw-r--r--qpid/cpp/src/tests/TxPublishTest.cpp3
-rw-r--r--qpid/cpp/src/tests/Variant.cpp58
-rwxr-xr-xqpid/cpp/src/tests/acl.py155
-rwxr-xr-xqpid/cpp/src/tests/allhosts4
-rw-r--r--qpid/cpp/src/tests/brokertest.py303
-rwxr-xr-xqpid/cpp/src/tests/cli_tests.py24
-rwxr-xr-xqpid/cpp/src/tests/cluster_test_logs.py15
-rwxr-xr-xqpid/cpp/src/tests/cluster_tests.py572
-rwxr-xr-xqpid/cpp/src/tests/federation.py370
-rwxr-xr-xqpid/cpp/src/tests/federation_sys.py2180
-rwxr-xr-xqpid/cpp/src/tests/python_tests2
-rwxr-xr-xqpid/cpp/src/tests/qpid-cluster-benchmark47
-rwxr-xr-xqpid/cpp/src/tests/qpid-cpp-benchmark71
-rw-r--r--qpid/cpp/src/tests/qpid-perftest.cpp14
-rw-r--r--qpid/cpp/src/tests/qpid-receive.cpp7
-rw-r--r--qpid/cpp/src/tests/qpid-send.cpp2
-rw-r--r--qpid/cpp/src/tests/qrsh.cpp169
-rw-r--r--qpid/cpp/src/tests/qrsh_run.cpp321
-rw-r--r--qpid/cpp/src/tests/qrsh_server.cpp1068
-rwxr-xr-xqpid/cpp/src/tests/qrsh_utils/10_all30
-rwxr-xr-xqpid/cpp/src/tests/qrsh_utils/1_remote_run26
-rwxr-xr-xqpid/cpp/src/tests/qrsh_utils/2_forever26
-rwxr-xr-xqpid/cpp/src/tests/qrsh_utils/3_kill_it27
-rwxr-xr-xqpid/cpp/src/tests/qrsh_utils/4_wait_for_it26
-rwxr-xr-xqpid/cpp/src/tests/qrsh_utils/5_exited64
-rwxr-xr-xqpid/cpp/src/tests/qrsh_utils/6_get29
-rwxr-xr-xqpid/cpp/src/tests/qrsh_utils/7_get_output44
-rwxr-xr-xqpid/cpp/src/tests/qrsh_utils/8_any43
-rwxr-xr-xqpid/cpp/src/tests/qrsh_utils/9_alias38
-rw-r--r--qpid/cpp/src/tests/qrsh_utils/qrsh_example_command.cpp52
-rw-r--r--qpid/cpp/src/tests/qrsh_utils/qrsh_forever.cpp50
-rw-r--r--qpid/cpp/src/tests/qrsh_utils/qsh_doc.txt309
-rw-r--r--qpid/cpp/src/tests/queue_flow_limit_tests.py159
-rwxr-xr-xqpid/cpp/src/tests/replication_test2
-rwxr-xr-xqpid/cpp/src/tests/run_acl_tests2
-rwxr-xr-xqpid/cpp/src/tests/run_cli_tests5
-rwxr-xr-xqpid/cpp/src/tests/run_federation_sys_tests97
-rwxr-xr-xqpid/cpp/src/tests/run_federation_tests4
-rwxr-xr-xqpid/cpp/src/tests/run_header_test2
-rw-r--r--qpid/cpp/src/tests/run_long_federation_sys_tests24
-rwxr-xr-xqpid/cpp/src/tests/run_queue_flow_limit_tests4
-rwxr-xr-xqpid/cpp/src/tests/run_test2
-rw-r--r--qpid/cpp/src/tests/sasl.mk15
-rwxr-xr-xqpid/cpp/src/tests/sasl_fed2
-rwxr-xr-xqpid/cpp/src/tests/sasl_fed_ex306
-rwxr-xr-xqpid/cpp/src/tests/sasl_fed_ex_dynamic27
-rwxr-xr-xqpid/cpp/src/tests/sasl_fed_ex_dynamic_cluster28
-rwxr-xr-xqpid/cpp/src/tests/sasl_fed_ex_link27
-rwxr-xr-xqpid/cpp/src/tests/sasl_fed_ex_link_cluster28
-rwxr-xr-xqpid/cpp/src/tests/sasl_fed_ex_queue27
-rwxr-xr-xqpid/cpp/src/tests/sasl_fed_ex_queue_cluster28
-rwxr-xr-xqpid/cpp/src/tests/sasl_fed_ex_route27
-rwxr-xr-xqpid/cpp/src/tests/sasl_fed_ex_route_cluster28
-rwxr-xr-xqpid/cpp/src/tests/ssl_test2
-rw-r--r--qpid/cpp/src/tests/windows/DisableWin32ErrorWindows.cpp4
-rw-r--r--qpid/cpp/src/windows/QpiddBroker.cpp4
-rw-r--r--qpid/cpp/src/xml.mk2
-rw-r--r--qpid/cpp/xml/cluster.xml49
-rwxr-xr-xqpid/doc/book/build-book.sh12
-rw-r--r--qpid/doc/book/src/AMQP-Messaging-Broker-CPP-Book.xml1
-rw-r--r--qpid/doc/book/src/AMQP-Messaging-Broker-CPP.xml3
-rw-r--r--qpid/doc/book/src/Cheat-Sheet-for-configuring-Queue-Options.xml10
-rw-r--r--qpid/doc/book/src/Programming-In-Apache-Qpid.xml41
-rw-r--r--qpid/doc/book/src/Security.xml20
-rw-r--r--qpid/doc/book/src/producer-flow-control.xml351
-rw-r--r--qpid/doc/dev-readme/QPID-Component-README.odgbin12661 -> 14069 bytes
-rw-r--r--qpid/doc/dev-readme/QPID-Component-README.pdfbin38097 -> 39535 bytes
-rw-r--r--qpid/doc/website/README.txt28
-rwxr-xr-xqpid/doc/website/build.sh53
-rw-r--r--qpid/doc/website/content/.htaccess20
-rw-r--r--qpid/doc/website/content/acknowledgements.html39
-rw-r--r--qpid/doc/website/content/amqp.html71
-rw-r--r--qpid/doc/website/content/compatibility.html386
-rw-r--r--qpid/doc/website/content/documentation.html92
-rw-r--r--qpid/doc/website/content/download.cgi26
-rw-r--r--qpid/doc/website/content/download.html466
-rw-r--r--qpid/doc/website/content/getting_involved.html69
-rw-r--r--qpid/doc/website/content/getting_started.html85
-rw-r--r--qpid/doc/website/content/images/README.txt1
-rw-r--r--qpid/doc/website/content/images/jprofiler.pngbin0 -> 584 bytes
-rw-r--r--qpid/doc/website/content/images/structure101.jpgbin0 -> 3465 bytes
-rw-r--r--qpid/doc/website/content/index.html91
-rw-r--r--qpid/doc/website/content/mailing_lists.html82
-rw-r--r--qpid/doc/website/content/people.html98
-rw-r--r--qpid/doc/website/content/qpid_integrated_with.html40
-rw-r--r--qpid/doc/website/content/qpid_project_etiquette_guide.html104
-rw-r--r--qpid/doc/website/content/release_notes_0.8.html437
-rw-r--r--qpid/doc/website/content/source_repository.html74
-rw-r--r--qpid/doc/website/example/images/asf-logo.pngbin0 -> 4735 bytes
-rw-r--r--qpid/doc/website/example/images/asf_logo.gifbin0 -> 7279 bytes
-rw-r--r--qpid/doc/website/example/images/header.pngbin0 -> 22354 bytes
-rw-r--r--qpid/doc/website/example/images/main_body.pngbin0 -> 211 bytes
-rw-r--r--qpid/doc/website/example/images/main_bottom.pngbin0 -> 1719 bytes
-rw-r--r--qpid/doc/website/example/images/main_top.pngbin0 -> 295 bytes
-rw-r--r--qpid/doc/website/example/images/menu_body.pngbin0 -> 198 bytes
-rw-r--r--qpid/doc/website/example/images/menu_bottom.pngbin0 -> 264 bytes
-rw-r--r--qpid/doc/website/example/images/menu_top.pngbin0 -> 258 bytes
-rw-r--r--qpid/doc/website/example/images/qpid-logo-900x480.pngbin0 -> 39038 bytes
-rw-r--r--qpid/doc/website/example/images/qpid-logo.pngbin0 -> 5775 bytes
-rw-r--r--qpid/doc/website/example/index.html185
-rw-r--r--qpid/doc/website/example/style.css263
-rw-r--r--qpid/doc/website/template/images/asf-logo.pngbin0 -> 4735 bytes
-rw-r--r--qpid/doc/website/template/images/asf_logo.gifbin0 -> 7279 bytes
-rw-r--r--qpid/doc/website/template/images/header.pngbin0 -> 22576 bytes
-rw-r--r--qpid/doc/website/template/images/main_body.pngbin0 -> 211 bytes
-rw-r--r--qpid/doc/website/template/images/main_bottom.pngbin0 -> 1719 bytes
-rw-r--r--qpid/doc/website/template/images/main_top.pngbin0 -> 295 bytes
-rw-r--r--qpid/doc/website/template/images/menu_body.pngbin0 -> 198 bytes
-rw-r--r--qpid/doc/website/template/images/menu_bottom.pngbin0 -> 264 bytes
-rw-r--r--qpid/doc/website/template/images/menu_top.pngbin0 -> 258 bytes
-rw-r--r--qpid/doc/website/template/images/qpid-logo-900x480.pngbin0 -> 39038 bytes
-rw-r--r--qpid/doc/website/template/images/qpid-logo.pngbin0 -> 6600 bytes
-rw-r--r--qpid/doc/website/template/style.css276
-rw-r--r--qpid/doc/website/template/template.html126
-rwxr-xr-xqpid/doc/website/tools/generate56
-rwxr-xr-xqpid/doc/website/tools/wrap44
-rw-r--r--qpid/dotnet/LICENSE.txt757
-rw-r--r--qpid/dotnet/NOTICE.txt32
-rw-r--r--qpid/dotnet/Qpid.Buffer.Tests/Properties/AssemblyInfo.cs56
-rw-r--r--qpid/dotnet/Qpid.Buffer.Tests/Qpid.Buffer.Tests.csproj83
-rw-r--r--qpid/dotnet/Qpid.Buffer.Tests/SimpleByteBufferTests.cs333
-rw-r--r--qpid/dotnet/Qpid.Buffer.Tests/SlicedByteBufferTests.cs133
-rw-r--r--qpid/dotnet/Qpid.Buffer.Tests/default.build48
-rw-r--r--qpid/dotnet/Qpid.Buffer/BufferOverflowException.cs41
-rw-r--r--qpid/dotnet/Qpid.Buffer/BufferUnderflowException.cs42
-rw-r--r--qpid/dotnet/Qpid.Buffer/ByteBuffer.cs982
-rw-r--r--qpid/dotnet/Qpid.Buffer/ByteBufferHexDumper.cs79
-rw-r--r--qpid/dotnet/Qpid.Buffer/IByteBufferAllocator.cs50
-rw-r--r--qpid/dotnet/Qpid.Buffer/Properties/AssemblyInfo.cs53
-rw-r--r--qpid/dotnet/Qpid.Buffer/Qpid.Buffer.csproj77
-rw-r--r--qpid/dotnet/Qpid.Buffer/SimpleByteBuffer.cs120
-rw-r--r--qpid/dotnet/Qpid.Buffer/SimpleByteBufferAllocator.cs58
-rw-r--r--qpid/dotnet/Qpid.Buffer/SlicedByteBuffer.cs86
-rw-r--r--qpid/dotnet/Qpid.Buffer/default.build46
-rw-r--r--qpid/dotnet/Qpid.Client.Tests/App.config34
-rw-r--r--qpid/dotnet/Qpid.Client.Tests/BrokerDetails/BrokerDetailsTest.cs65
-rw-r--r--qpid/dotnet/Qpid.Client.Tests/Channel/ChannelMessageCreationTests.cs79
-rw-r--r--qpid/dotnet/Qpid.Client.Tests/Messages/MessageFactoryRegistryTests.cs114
-rw-r--r--qpid/dotnet/Qpid.Client.Tests/Properties/AssemblyInfo.cs53
-rw-r--r--qpid/dotnet/Qpid.Client.Tests/Qpid.Client.Tests.csproj158
-rw-r--r--qpid/dotnet/Qpid.Client.Tests/Security/CallbackHandlerRegistryTests.cs66
-rw-r--r--qpid/dotnet/Qpid.Client.Tests/default.build64
-rw-r--r--qpid/dotnet/Qpid.Client.Tests/interop/TopicListener.cs211
-rw-r--r--qpid/dotnet/Qpid.Client.Tests/interop/TopicPublisher.cs208
-rw-r--r--qpid/dotnet/Qpid.Client.Tests/lib/nunit/nunit-licence.txt23
-rw-r--r--qpid/dotnet/Qpid.Client.Tests/lib/nunit/nunit.framework.dllbin0 -> 45056 bytes
-rw-r--r--qpid/dotnet/Qpid.Client.Tests/log4net.config68
-rw-r--r--qpid/dotnet/Qpid.Client.Tests/url/ConnectionUrlTest.cs446
-rw-r--r--qpid/dotnet/Qpid.Client.Transport.Socket.Blocking/BlockingSocketProcessor.cs135
-rw-r--r--qpid/dotnet/Qpid.Client.Transport.Socket.Blocking/BlockingSocketTransport.cs121
-rw-r--r--qpid/dotnet/Qpid.Client.Transport.Socket.Blocking/ByteChannel.cs63
-rw-r--r--qpid/dotnet/Qpid.Client.Transport.Socket.Blocking/Properties/AssemblyInfo.cs53
-rw-r--r--qpid/dotnet/Qpid.Client.Transport.Socket.Blocking/Qpid.Client.Transport.Socket.Blocking.csproj92
-rw-r--r--qpid/dotnet/Qpid.Client.Transport.Socket.Blocking/Qpid.Client.Transport.Socket.Blocking.mdp50
-rw-r--r--qpid/dotnet/Qpid.Client/Client/AMQAuthenticationException.cs39
-rw-r--r--qpid/dotnet/Qpid.Client/Client/AMQConnection.cs873
-rw-r--r--qpid/dotnet/Qpid.Client/Client/AMQConnectionException.cs38
-rw-r--r--qpid/dotnet/Qpid.Client/Client/AMQDestination.cs234
-rw-r--r--qpid/dotnet/Qpid.Client/Client/AMQNoConsumersException.cs45
-rw-r--r--qpid/dotnet/Qpid.Client/Client/AMQNoRouteException.cs46
-rw-r--r--qpid/dotnet/Qpid.Client/Client/AmqBrokerInfo.cs322
-rw-r--r--qpid/dotnet/Qpid.Client/Client/AmqChannel.cs1241
-rw-r--r--qpid/dotnet/Qpid.Client/Client/BasicMessageConsumer.cs485
-rw-r--r--qpid/dotnet/Qpid.Client/Client/BasicMessageProducer.cs405
-rw-r--r--qpid/dotnet/Qpid.Client/Client/Closeable.cs83
-rw-r--r--qpid/dotnet/Qpid.Client/Client/Configuration/AuthenticationConfigurationSectionHandler.cs84
-rw-r--r--qpid/dotnet/Qpid.Client/Client/ConnectionTuneParameters.cs83
-rw-r--r--qpid/dotnet/Qpid.Client/Client/Failover/FailoverException.cs42
-rw-r--r--qpid/dotnet/Qpid.Client/Client/Failover/FailoverHandler.cs175
-rw-r--r--qpid/dotnet/Qpid.Client/Client/Failover/FailoverState.cs31
-rw-r--r--qpid/dotnet/Qpid.Client/Client/Failover/FailoverSupport.cs55
-rw-r--r--qpid/dotnet/Qpid.Client/Client/Handler/BasicDeliverMethodHandler.cs42
-rw-r--r--qpid/dotnet/Qpid.Client/Client/Handler/BasicReturnMethodHandler.cs44
-rw-r--r--qpid/dotnet/Qpid.Client/Client/Handler/ChannelCloseMethodHandler.cs68
-rw-r--r--qpid/dotnet/Qpid.Client/Client/Handler/ConnectionCloseMethodHandler.cs68
-rw-r--r--qpid/dotnet/Qpid.Client/Client/Handler/ConnectionCloseOkHandler.cs41
-rw-r--r--qpid/dotnet/Qpid.Client/Client/Handler/ConnectionOpenOkMethodHandler.cs35
-rw-r--r--qpid/dotnet/Qpid.Client/Client/Handler/ConnectionRedirectMethodHandler.cs68
-rw-r--r--qpid/dotnet/Qpid.Client/Client/Handler/ConnectionSecureMethodHandler.cs60
-rw-r--r--qpid/dotnet/Qpid.Client/Client/Handler/ConnectionStartMethodHandler.cs144
-rw-r--r--qpid/dotnet/Qpid.Client/Client/Handler/ConnectionTuneMethodHandler.cs63
-rw-r--r--qpid/dotnet/Qpid.Client/Client/Handler/QueueDeleteOkMethodHandler.cs44
-rw-r--r--qpid/dotnet/Qpid.Client/Client/Handler/QueuePurgeOkMethodHandler.cs44
-rw-r--r--qpid/dotnet/Qpid.Client/Client/Message/AMQMessage.cs58
-rw-r--r--qpid/dotnet/Qpid.Client/Client/Message/AMQMessageFactory.cs73
-rw-r--r--qpid/dotnet/Qpid.Client/Client/Message/AbstractQmsMessage.cs694
-rw-r--r--qpid/dotnet/Qpid.Client/Client/Message/IMessageFactory.cs52
-rw-r--r--qpid/dotnet/Qpid.Client/Client/Message/MessageFactoryRegistry.cs129
-rw-r--r--qpid/dotnet/Qpid.Client/Client/Message/QpidBytesMessage.cs353
-rw-r--r--qpid/dotnet/Qpid.Client/Client/Message/QpidBytesMessageFactory.cs75
-rw-r--r--qpid/dotnet/Qpid.Client/Client/Message/QpidHeaders.cs233
-rw-r--r--qpid/dotnet/Qpid.Client/Client/Message/QpidTextMessage.cs115
-rw-r--r--qpid/dotnet/Qpid.Client/Client/Message/QpidTextMessageFactory.cs40
-rw-r--r--qpid/dotnet/Qpid.Client/Client/Message/UnexpectedBodyReceivedException.cs57
-rw-r--r--qpid/dotnet/Qpid.Client/Client/Message/UnprocessedMessage.cs57
-rw-r--r--qpid/dotnet/Qpid.Client/Client/Protocol/AMQMethodEvent.cs76
-rw-r--r--qpid/dotnet/Qpid.Client/Client/Protocol/AMQProtocolListener.cs318
-rw-r--r--qpid/dotnet/Qpid.Client/Client/Protocol/AMQProtocolSession.cs267
-rw-r--r--qpid/dotnet/Qpid.Client/Client/Protocol/DefaultTimeouts.cs47
-rw-r--r--qpid/dotnet/Qpid.Client/Client/Protocol/IConnectionCloser.cs27
-rw-r--r--qpid/dotnet/Qpid.Client/Client/Protocol/IProtocolListener.cs36
-rw-r--r--qpid/dotnet/Qpid.Client/Client/Protocol/Listener/BlockingMethodFrameListener.cs110
-rw-r--r--qpid/dotnet/Qpid.Client/Client/Protocol/Listener/IAMQMethodListener.cs46
-rw-r--r--qpid/dotnet/Qpid.Client/Client/Protocol/Listener/SpecificMethodFrameListener.cs42
-rw-r--r--qpid/dotnet/Qpid.Client/Client/Protocol/ProtocolWriter.cs107
-rw-r--r--qpid/dotnet/Qpid.Client/Client/QpidConnectionInfo.cs504
-rw-r--r--qpid/dotnet/Qpid.Client/Client/Security/CallbackHandlerRegistry.cs129
-rw-r--r--qpid/dotnet/Qpid.Client/Client/Security/IAMQCallbackHandler.cs35
-rw-r--r--qpid/dotnet/Qpid.Client/Client/Security/UsernamePasswordCallbackHandler.cs56
-rw-r--r--qpid/dotnet/Qpid.Client/Client/SslOptions.cs81
-rw-r--r--qpid/dotnet/Qpid.Client/Client/State/AMQState.cs35
-rw-r--r--qpid/dotnet/Qpid.Client/Client/State/AMQStateChangedEvent.cs52
-rw-r--r--qpid/dotnet/Qpid.Client/Client/State/AMQStateManager.cs251
-rw-r--r--qpid/dotnet/Qpid.Client/Client/State/IAMQStateListener.cs29
-rw-r--r--qpid/dotnet/Qpid.Client/Client/State/IStateAwareMethodListener.cs31
-rw-r--r--qpid/dotnet/Qpid.Client/Client/State/IStateListener.cs33
-rw-r--r--qpid/dotnet/Qpid.Client/Client/State/IllegalStateTransitionException.cs74
-rw-r--r--qpid/dotnet/Qpid.Client/Client/State/StateWaiter.cs121
-rw-r--r--qpid/dotnet/Qpid.Client/Client/Transport/AMQProtocolProvider.cs47
-rw-r--r--qpid/dotnet/Qpid.Client/Client/Transport/AmqpChannel.cs111
-rw-r--r--qpid/dotnet/Qpid.Client/Client/Transport/IByteChannel.cs71
-rw-r--r--qpid/dotnet/Qpid.Client/Client/Transport/IProtocolChannel.cs32
-rw-r--r--qpid/dotnet/Qpid.Client/Client/Transport/IProtocolWriter.cs29
-rw-r--r--qpid/dotnet/Qpid.Client/Client/Transport/IStreamFilter.cs38
-rw-r--r--qpid/dotnet/Qpid.Client/Client/Transport/ITransport.cs32
-rw-r--r--qpid/dotnet/Qpid.Client/Client/Transport/IoHandler.cs322
-rw-r--r--qpid/dotnet/Qpid.Client/Client/Transport/ProtocolDecoderOutput.cs60
-rw-r--r--qpid/dotnet/Qpid.Client/Client/Transport/SingleProtocolEncoderOutput.cs40
-rw-r--r--qpid/dotnet/Qpid.Client/Client/Transport/Socket/Blocking/BlockingSocketTransport.cs150
-rw-r--r--qpid/dotnet/Qpid.Client/Client/Transport/Socket/Blocking/ByteChannel.cs92
-rw-r--r--qpid/dotnet/Qpid.Client/Client/Transport/Socket/Blocking/ISocketConnector.cs34
-rw-r--r--qpid/dotnet/Qpid.Client/Client/Transport/Socket/Blocking/SocketConnector.cs71
-rw-r--r--qpid/dotnet/Qpid.Client/Client/Transport/Socket/Blocking/SslSocketConnector.cs107
-rw-r--r--qpid/dotnet/Qpid.Client/Client/Util/FlowControlQueue.cs98
-rw-r--r--qpid/dotnet/Qpid.Client/Properties/AssemblyInfo.cs52
-rw-r--r--qpid/dotnet/Qpid.Client/Qpid.Client.csproj102
-rw-r--r--qpid/dotnet/Qpid.Client/default.build52
-rw-r--r--qpid/dotnet/Qpid.Client/qms/BrokerInfo.cs55
-rw-r--r--qpid/dotnet/Qpid.Client/qms/ConnectionInfo.cs63
-rw-r--r--qpid/dotnet/Qpid.Client/qms/FailoverPolicy.cs315
-rw-r--r--qpid/dotnet/Qpid.Client/qms/UrlSyntaxException.cs134
-rw-r--r--qpid/dotnet/Qpid.Client/qms/failover/FailoverMethod.cs78
-rw-r--r--qpid/dotnet/Qpid.Client/qms/failover/FailoverRoundRobin.cs255
-rw-r--r--qpid/dotnet/Qpid.Client/qms/failover/FailoverSingleServer.cs147
-rw-r--r--qpid/dotnet/Qpid.Codec/CumulativeProtocolDecoder.cs152
-rw-r--r--qpid/dotnet/Qpid.Codec/Demux/DemuxingProtocolCodecFactory.cs387
-rw-r--r--qpid/dotnet/Qpid.Codec/Demux/IMessageDecoder.cs56
-rw-r--r--qpid/dotnet/Qpid.Codec/Demux/IMessageDecoderFactory.cs32
-rw-r--r--qpid/dotnet/Qpid.Codec/Demux/IMessageEncoder.cs48
-rw-r--r--qpid/dotnet/Qpid.Codec/Demux/IMessageEncoderFactory.cs32
-rw-r--r--qpid/dotnet/Qpid.Codec/Demux/MessageDecoderResult.cs29
-rw-r--r--qpid/dotnet/Qpid.Codec/IProtocolCodecFactory.cs37
-rw-r--r--qpid/dotnet/Qpid.Codec/IProtocolDecoder.cs41
-rw-r--r--qpid/dotnet/Qpid.Codec/IProtocolDecoderOutput.cs35
-rw-r--r--qpid/dotnet/Qpid.Codec/IProtocolEncoder.cs41
-rw-r--r--qpid/dotnet/Qpid.Codec/IProtocolEncoderOutput.cs37
-rw-r--r--qpid/dotnet/Qpid.Codec/Properties/AssemblyInfo.cs53
-rw-r--r--qpid/dotnet/Qpid.Codec/ProtocolCodecException.cs49
-rw-r--r--qpid/dotnet/Qpid.Codec/ProtocolDecoderException.cs70
-rw-r--r--qpid/dotnet/Qpid.Codec/ProtocolEncoderException.cs49
-rw-r--r--qpid/dotnet/Qpid.Codec/Qpid.Codec.csproj82
-rw-r--r--qpid/dotnet/Qpid.Codec/Support/SimpleProtocolDecoderOutput.cs44
-rw-r--r--qpid/dotnet/Qpid.Codec/Support/SimpleProtocolEncoderOutput.cs43
-rw-r--r--qpid/dotnet/Qpid.Codec/default.build47
-rw-r--r--qpid/dotnet/Qpid.Common.Tests/Properties/AssemblyInfo.cs54
-rw-r--r--qpid/dotnet/Qpid.Common.Tests/Qpid.Common.Tests.csproj87
-rw-r--r--qpid/dotnet/Qpid.Common.Tests/Qpid/Collections/TestConsumerProducerQueue.cs85
-rw-r--r--qpid/dotnet/Qpid.Common.Tests/Qpid/Collections/TestLinkedHashtable.cs83
-rw-r--r--qpid/dotnet/Qpid.Common.Tests/Qpid/Framing/TestAMQType.cs270
-rw-r--r--qpid/dotnet/Qpid.Common.Tests/Qpid/Framing/TestEncodingUtils.cs60
-rw-r--r--qpid/dotnet/Qpid.Common.Tests/default.build52
-rw-r--r--qpid/dotnet/Qpid.Common/AMQChannelClosedException.cs40
-rw-r--r--qpid/dotnet/Qpid.Common/AMQConnectionClosedException.cs51
-rw-r--r--qpid/dotnet/Qpid.Common/AMQDisconnectedException.cs45
-rw-r--r--qpid/dotnet/Qpid.Common/AMQException.cs149
-rw-r--r--qpid/dotnet/Qpid.Common/AMQInvalidArgumentException.cs46
-rw-r--r--qpid/dotnet/Qpid.Common/AMQInvalidRoutingKeyException.cs46
-rw-r--r--qpid/dotnet/Qpid.Common/AMQUndeliveredException.cs59
-rw-r--r--qpid/dotnet/Qpid.Common/AssemblySettings.cs160
-rw-r--r--qpid/dotnet/Qpid.Common/Collections/BlockingQueue.cs95
-rw-r--r--qpid/dotnet/Qpid.Common/Collections/ConsumerProducerQueue.cs113
-rw-r--r--qpid/dotnet/Qpid.Common/Collections/LinkedBlockingQueue.cs384
-rw-r--r--qpid/dotnet/Qpid.Common/Collections/LinkedHashtable.cs327
-rw-r--r--qpid/dotnet/Qpid.Common/Collections/SynchronousQueue.cs375
-rw-r--r--qpid/dotnet/Qpid.Common/Framing/AMQDataBlockDecoder.cs155
-rw-r--r--qpid/dotnet/Qpid.Common/Framing/AMQDataBlockEncoder.cs65
-rw-r--r--qpid/dotnet/Qpid.Common/Framing/AMQFrame.cs107
-rw-r--r--qpid/dotnet/Qpid.Common/Framing/AMQFrameDecodingException.cs59
-rw-r--r--qpid/dotnet/Qpid.Common/Framing/AMQMethodBody.cs93
-rw-r--r--qpid/dotnet/Qpid.Common/Framing/AMQMethodBodyFactory.cs45
-rw-r--r--qpid/dotnet/Qpid.Common/Framing/AMQProtocolHeaderException.cs39
-rw-r--r--qpid/dotnet/Qpid.Common/Framing/AMQType.cs700
-rw-r--r--qpid/dotnet/Qpid.Common/Framing/AMQTypeMap.cs75
-rw-r--r--qpid/dotnet/Qpid.Common/Framing/AMQTypedValue.cs76
-rw-r--r--qpid/dotnet/Qpid.Common/Framing/BasicContentHeaderProperties.cs290
-rw-r--r--qpid/dotnet/Qpid.Common/Framing/CompositeAMQDataBlock.cs85
-rw-r--r--qpid/dotnet/Qpid.Common/Framing/ContentBody.cs100
-rw-r--r--qpid/dotnet/Qpid.Common/Framing/ContentBodyFactory.cs53
-rw-r--r--qpid/dotnet/Qpid.Common/Framing/ContentHeaderBody.cs118
-rw-r--r--qpid/dotnet/Qpid.Common/Framing/ContentHeaderBodyFactory.cs53
-rw-r--r--qpid/dotnet/Qpid.Common/Framing/ContentHeaderPropertiesFactory.cs63
-rw-r--r--qpid/dotnet/Qpid.Common/Framing/EncodingUtils.cs460
-rw-r--r--qpid/dotnet/Qpid.Common/Framing/FieldTable.cs633
-rw-r--r--qpid/dotnet/Qpid.Common/Framing/HeartbeatBody.cs64
-rw-r--r--qpid/dotnet/Qpid.Common/Framing/HeartbeatBodyFactory.cs32
-rw-r--r--qpid/dotnet/Qpid.Common/Framing/IBody.cs63
-rw-r--r--qpid/dotnet/Qpid.Common/Framing/IBodyFactory.cs38
-rw-r--r--qpid/dotnet/Qpid.Common/Framing/IContentHeaderProperties.cs65
-rw-r--r--qpid/dotnet/Qpid.Common/Framing/IDataBlock.cs47
-rw-r--r--qpid/dotnet/Qpid.Common/Framing/IEncodableAMQDataBlock.cs31
-rw-r--r--qpid/dotnet/Qpid.Common/Framing/ProtocolInitiation.cs158
-rw-r--r--qpid/dotnet/Qpid.Common/Properties/AssemblyInfo.cs52
-rw-r--r--qpid/dotnet/Qpid.Common/Protocol/AMQConstant.cs100
-rw-r--r--qpid/dotnet/Qpid.Common/Qpid.Common.csproj104
-rw-r--r--qpid/dotnet/Qpid.Common/amqp.xml3929
-rw-r--r--qpid/dotnet/Qpid.Common/build.xml95
-rw-r--r--qpid/dotnet/Qpid.Common/default.build49
-rw-r--r--qpid/dotnet/Qpid.Common/lib/log4net/log4net-licence.txt201
-rw-r--r--qpid/dotnet/Qpid.Common/lib/log4net/log4net.dllbin0 -> 266240 bytes
-rw-r--r--qpid/dotnet/Qpid.Common/lib/log4net/log4net.xml28676
-rw-r--r--qpid/dotnet/Qpid.Common/lib/saxon/saxon-licence.txt471
-rw-r--r--qpid/dotnet/Qpid.Common/lib/saxon/saxon8.jarbin0 -> 3118502 bytes
-rw-r--r--qpid/dotnet/Qpid.Common/lib/seclib-1.0.0/Org.Mentalis.Security.dllbin0 -> 184320 bytes
-rw-r--r--qpid/dotnet/Qpid.Common/lib/seclib-1.0.0/seclib-license.txt13
-rw-r--r--qpid/dotnet/Qpid.Common/resources/registry.template24
-rw-r--r--qpid/dotnet/Qpid.Common/stylesheets/csharp.xsl251
-rw-r--r--qpid/dotnet/Qpid.Common/stylesheets/framing.xsl65
-rw-r--r--qpid/dotnet/Qpid.Common/stylesheets/java.xsl230
-rw-r--r--qpid/dotnet/Qpid.Common/stylesheets/prepare1.xsl109
-rw-r--r--qpid/dotnet/Qpid.Common/stylesheets/prepare2.xsl68
-rw-r--r--qpid/dotnet/Qpid.Common/stylesheets/prepare3.xsl64
-rw-r--r--qpid/dotnet/Qpid.Common/stylesheets/readme.txt52
-rw-r--r--qpid/dotnet/Qpid.Common/stylesheets/registry.xsl33
-rw-r--r--qpid/dotnet/Qpid.Common/stylesheets/utils.xsl185
-rw-r--r--qpid/dotnet/Qpid.Integration.Tests/Properties/AssemblyInfo.cs53
-rwxr-xr-xqpid/dotnet/Qpid.Integration.Tests/Qpid.Integration.Tests.csproj124
-rw-r--r--qpid/dotnet/Qpid.Integration.Tests/README.txt3
-rw-r--r--qpid/dotnet/Qpid.Integration.Tests/default.build69
-rw-r--r--qpid/dotnet/Qpid.Integration.Tests/framework/Assertion.cs39
-rw-r--r--qpid/dotnet/Qpid.Integration.Tests/framework/Assertion.csx39
-rw-r--r--qpid/dotnet/Qpid.Integration.Tests/framework/AssertionBase.csx65
-rw-r--r--qpid/dotnet/Qpid.Integration.Tests/framework/BrokerLifecycleAware.csx67
-rw-r--r--qpid/dotnet/Qpid.Integration.Tests/framework/CauseFailure.csx41
-rw-r--r--qpid/dotnet/Qpid.Integration.Tests/framework/CauseFailureUserPrompt.csx63
-rw-r--r--qpid/dotnet/Qpid.Integration.Tests/framework/Circuit.cs102
-rw-r--r--qpid/dotnet/Qpid.Integration.Tests/framework/Circuit.csx103
-rw-r--r--qpid/dotnet/Qpid.Integration.Tests/framework/CircuitEnd.csx86
-rw-r--r--qpid/dotnet/Qpid.Integration.Tests/framework/CircuitEndBase.csx146
-rw-r--r--qpid/dotnet/Qpid.Integration.Tests/framework/ExceptionMonitor.csx184
-rw-r--r--qpid/dotnet/Qpid.Integration.Tests/framework/FrameworkBaseCase.cs282
-rw-r--r--qpid/dotnet/Qpid.Integration.Tests/framework/FrameworkBaseCase.csx272
-rw-r--r--qpid/dotnet/Qpid.Integration.Tests/framework/LocalCircuitFactory.csx301
-rw-r--r--qpid/dotnet/Qpid.Integration.Tests/framework/MessageMonitor.csx102
-rw-r--r--qpid/dotnet/Qpid.Integration.Tests/framework/MessagingTestConfigProperties.csx652
-rw-r--r--qpid/dotnet/Qpid.Integration.Tests/framework/NotApplicableAssertion.csx111
-rw-r--r--qpid/dotnet/Qpid.Integration.Tests/framework/Publisher.cs65
-rw-r--r--qpid/dotnet/Qpid.Integration.Tests/framework/Publisher.csx72
-rw-r--r--qpid/dotnet/Qpid.Integration.Tests/framework/README.txt3
-rw-r--r--qpid/dotnet/Qpid.Integration.Tests/framework/Receiver.cs80
-rw-r--r--qpid/dotnet/Qpid.Integration.Tests/framework/Receiver.csx88
-rw-r--r--qpid/dotnet/Qpid.Integration.Tests/framework/TestClientDetails.cs84
-rw-r--r--qpid/dotnet/Qpid.Integration.Tests/framework/TestClientDetails.csx82
-rw-r--r--qpid/dotnet/Qpid.Integration.Tests/framework/TestModel.cs657
-rw-r--r--qpid/dotnet/Qpid.Integration.Tests/framework/TestUtils.csx188
-rw-r--r--qpid/dotnet/Qpid.Integration.Tests/framework/alljava.csx7851
-rw-r--r--qpid/dotnet/Qpid.Integration.Tests/framework/clocksynch/ClockSynchFailureException.csx45
-rw-r--r--qpid/dotnet/Qpid.Integration.Tests/framework/clocksynch/ClockSynchThread.csx117
-rw-r--r--qpid/dotnet/Qpid.Integration.Tests/framework/clocksynch/ClockSynchronizer.csx66
-rw-r--r--qpid/dotnet/Qpid.Integration.Tests/framework/clocksynch/LocalClockSynchronizer.csx70
-rw-r--r--qpid/dotnet/Qpid.Integration.Tests/framework/clocksynch/UDPClockSynchronizer.csx453
-rw-r--r--qpid/dotnet/Qpid.Integration.Tests/framework/distributedcircuit/TestClient.csx493
-rw-r--r--qpid/dotnet/Qpid.Integration.Tests/framework/distributedcircuit/TestClientCircuitEnd.csx312
-rw-r--r--qpid/dotnet/Qpid.Integration.Tests/framework/distributedcircuit/TestClientControlledTest.csx104
-rw-r--r--qpid/dotnet/Qpid.Integration.Tests/framework/localcircuit/LocalCircuitImpl.csx290
-rw-r--r--qpid/dotnet/Qpid.Integration.Tests/framework/localcircuit/LocalPublisherImpl.csx164
-rw-r--r--qpid/dotnet/Qpid.Integration.Tests/framework/localcircuit/LocalReceiverImpl.csx137
-rw-r--r--qpid/dotnet/Qpid.Integration.Tests/framework/sequencers/BaseCircuitFactory.csx128
-rw-r--r--qpid/dotnet/Qpid.Integration.Tests/framework/sequencers/CircuitFactory.cs85
-rw-r--r--qpid/dotnet/Qpid.Integration.Tests/framework/sequencers/CircuitFactory.csx99
-rw-r--r--qpid/dotnet/Qpid.Integration.Tests/interactive/FailoverTest.cs397
-rw-r--r--qpid/dotnet/Qpid.Integration.Tests/interactive/SendReceiveTest.cs181
-rw-r--r--qpid/dotnet/Qpid.Integration.Tests/interop/InteropClientTestCase.cs87
-rw-r--r--qpid/dotnet/Qpid.Integration.Tests/interop/TestCases/TestCase1DummyRun.cs89
-rw-r--r--qpid/dotnet/Qpid.Integration.Tests/interop/TestCases/TestCase2BasicP2P.cs205
-rw-r--r--qpid/dotnet/Qpid.Integration.Tests/interop/TestCases/TestCase3BasicPubSub.cs244
-rw-r--r--qpid/dotnet/Qpid.Integration.Tests/interop/TestCases/TestCase4P2PMessageSize.cs244
-rw-r--r--qpid/dotnet/Qpid.Integration.Tests/interop/TestCases/TestCase5PubSubMessageSize.cs252
-rw-r--r--qpid/dotnet/Qpid.Integration.Tests/interop/TestClient.cs381
-rw-r--r--qpid/dotnet/Qpid.Integration.Tests/log4net.config69
-rw-r--r--qpid/dotnet/Qpid.Integration.Tests/old/ServiceProvidingClient.tmp150
-rw-r--r--qpid/dotnet/Qpid.Integration.Tests/old/ServiceRequestingClient.tmp182
-rw-r--r--qpid/dotnet/Qpid.Integration.Tests/testcases/BaseMessagingTestFixture.cs280
-rw-r--r--qpid/dotnet/Qpid.Integration.Tests/testcases/ChannelQueueTest.cs237
-rw-r--r--qpid/dotnet/Qpid.Integration.Tests/testcases/CommitRollbackTest.cs261
-rw-r--r--qpid/dotnet/Qpid.Integration.Tests/testcases/ConnectionTest.cs73
-rw-r--r--qpid/dotnet/Qpid.Integration.Tests/testcases/DurableSubscriptionTest.cs166
-rw-r--r--qpid/dotnet/Qpid.Integration.Tests/testcases/HeadersExchangeTest.cs282
-rw-r--r--qpid/dotnet/Qpid.Integration.Tests/testcases/MandatoryMessageTest.cs149
-rw-r--r--qpid/dotnet/Qpid.Integration.Tests/testcases/ProducerMultiConsumerTest.cs167
-rwxr-xr-xqpid/dotnet/Qpid.Integration.Tests/testcases/Qpid.Integration.Tests.csproj64
-rw-r--r--qpid/dotnet/Qpid.Integration.Tests/testcases/QueueBrowsingTest.cs121
-rw-r--r--qpid/dotnet/Qpid.Integration.Tests/testcases/SslConnectionTest.cs64
-rw-r--r--qpid/dotnet/Qpid.Integration.Tests/testcases/SustainedTest.cs109
-rw-r--r--qpid/dotnet/Qpid.Messaging/AcknowledgeMode.cs42
-rw-r--r--qpid/dotnet/Qpid.Messaging/ChannelLimitReachedException.cs60
-rw-r--r--qpid/dotnet/Qpid.Messaging/DeliveryMode.cs28
-rw-r--r--qpid/dotnet/Qpid.Messaging/ExchangeClassConstants.cs29
-rw-r--r--qpid/dotnet/Qpid.Messaging/ExchangeNameDefaults.cs42
-rw-r--r--qpid/dotnet/Qpid.Messaging/IBytesMessage.cs63
-rw-r--r--qpid/dotnet/Qpid.Messaging/IChannel.cs280
-rw-r--r--qpid/dotnet/Qpid.Messaging/ICloseable.cs38
-rw-r--r--qpid/dotnet/Qpid.Messaging/IConnection.cs55
-rw-r--r--qpid/dotnet/Qpid.Messaging/IConnectionFactory.cs28
-rw-r--r--qpid/dotnet/Qpid.Messaging/IConnectionListener.cs59
-rw-r--r--qpid/dotnet/Qpid.Messaging/IFieldTable.cs42
-rw-r--r--qpid/dotnet/Qpid.Messaging/IHeaders.cs67
-rw-r--r--qpid/dotnet/Qpid.Messaging/IMessage.cs97
-rw-r--r--qpid/dotnet/Qpid.Messaging/IMessageConsumer.cs79
-rw-r--r--qpid/dotnet/Qpid.Messaging/IMessagePublisher.cs92
-rw-r--r--qpid/dotnet/Qpid.Messaging/ITextMessage.cs27
-rw-r--r--qpid/dotnet/Qpid.Messaging/MessageConsumerBuilder.cs113
-rw-r--r--qpid/dotnet/Qpid.Messaging/MessageNotReadableException.cs39
-rw-r--r--qpid/dotnet/Qpid.Messaging/MessageNotWritableException.cs38
-rw-r--r--qpid/dotnet/Qpid.Messaging/MessagePublisherBuilder.cs91
-rw-r--r--qpid/dotnet/Qpid.Messaging/Properties/AssemblyInfo.cs56
-rw-r--r--qpid/dotnet/Qpid.Messaging/Qpid.Messaging.csproj115
-rw-r--r--qpid/dotnet/Qpid.Messaging/QpidException.cs43
-rw-r--r--qpid/dotnet/Qpid.Messaging/ResourceAllocationException.cs39
-rw-r--r--qpid/dotnet/Qpid.Messaging/default.build45
-rw-r--r--qpid/dotnet/Qpid.NET.FxCop16775
-rw-r--r--qpid/dotnet/Qpid.NET.sln116
-rw-r--r--qpid/dotnet/Qpid.Sasl.Tests/App.config33
-rw-r--r--qpid/dotnet/Qpid.Sasl.Tests/Mechanisms/AnonymousSaslClientTests.cs72
-rw-r--r--qpid/dotnet/Qpid.Sasl.Tests/Mechanisms/CramMD5SaslClientTests.cs90
-rw-r--r--qpid/dotnet/Qpid.Sasl.Tests/Mechanisms/DigestSaslClientTests.cs249
-rw-r--r--qpid/dotnet/Qpid.Sasl.Tests/Mechanisms/ExternalSaslClientTests.cs71
-rw-r--r--qpid/dotnet/Qpid.Sasl.Tests/Mechanisms/PlainSaslClientTests.cs88
-rw-r--r--qpid/dotnet/Qpid.Sasl.Tests/Properties/AssemblyInfo.cs56
-rw-r--r--qpid/dotnet/Qpid.Sasl.Tests/Qpid.Sasl.Tests.csproj86
-rw-r--r--qpid/dotnet/Qpid.Sasl.Tests/SaslTests.cs133
-rw-r--r--qpid/dotnet/Qpid.Sasl.Tests/TestClientFactory.cs75
-rw-r--r--qpid/dotnet/Qpid.Sasl.Tests/default.build52
-rw-r--r--qpid/dotnet/Qpid.Sasl/Callbacks.cs139
-rw-r--r--qpid/dotnet/Qpid.Sasl/Configuration/SaslConfiguration.cs90
-rw-r--r--qpid/dotnet/Qpid.Sasl/Configuration/SaslConfigurationSectionHandler.cs84
-rw-r--r--qpid/dotnet/Qpid.Sasl/DefaultClientFactory.cs99
-rw-r--r--qpid/dotnet/Qpid.Sasl/ISaslCallbackHandler.cs35
-rw-r--r--qpid/dotnet/Qpid.Sasl/ISaslClient.cs42
-rw-r--r--qpid/dotnet/Qpid.Sasl/ISaslClientFactory.cs40
-rw-r--r--qpid/dotnet/Qpid.Sasl/MD5HMAC.cs115
-rw-r--r--qpid/dotnet/Qpid.Sasl/Mechanisms/AnonymousSaslClient.cs69
-rw-r--r--qpid/dotnet/Qpid.Sasl/Mechanisms/CramMD5HexSaslClient.cs93
-rw-r--r--qpid/dotnet/Qpid.Sasl/Mechanisms/CramMD5SaslClient.cs91
-rw-r--r--qpid/dotnet/Qpid.Sasl/Mechanisms/DigestSaslClient.cs576
-rw-r--r--qpid/dotnet/Qpid.Sasl/Mechanisms/ExternalSaslClient.cs69
-rw-r--r--qpid/dotnet/Qpid.Sasl/Mechanisms/PlainSaslClient.cs81
-rw-r--r--qpid/dotnet/Qpid.Sasl/Properties/AssemblyInfo.cs57
-rw-r--r--qpid/dotnet/Qpid.Sasl/Qpid.Sasl.csproj73
-rw-r--r--qpid/dotnet/Qpid.Sasl/Sasl.cs115
-rw-r--r--qpid/dotnet/Qpid.Sasl/SaslClient.cs145
-rw-r--r--qpid/dotnet/Qpid.Sasl/SaslException.cs56
-rw-r--r--qpid/dotnet/Qpid.Sasl/SaslProperties.cs42
-rw-r--r--qpid/dotnet/Qpid.Sasl/default.build45
-rw-r--r--qpid/dotnet/README.txt68
-rw-r--r--qpid/dotnet/RELEASE_NOTES.txt11
-rw-r--r--qpid/dotnet/TestClient/Program.cs30
-rw-r--r--qpid/dotnet/TestClient/Properties/AssemblyInfo.cs53
-rw-r--r--qpid/dotnet/TestClient/TestClient.csproj115
-rw-r--r--qpid/dotnet/TestClient/default.build47
-rw-r--r--qpid/dotnet/TopicListener/Program.cs30
-rw-r--r--qpid/dotnet/TopicListener/Properties/AssemblyInfo.cs53
-rw-r--r--qpid/dotnet/TopicListener/TopicListener.csproj115
-rw-r--r--qpid/dotnet/TopicListener/default.build47
-rw-r--r--qpid/dotnet/TopicPublisher/Program.cs30
-rw-r--r--qpid/dotnet/TopicPublisher/Properties/AssemblyInfo.cs53
-rw-r--r--qpid/dotnet/TopicPublisher/TopicPublisher.csproj111
-rw-r--r--qpid/dotnet/TopicPublisher/default.build47
-rw-r--r--qpid/dotnet/build-framing.bat23
-rwxr-xr-xqpid/dotnet/build-mono21
-rw-r--r--qpid/dotnet/build-msbuild.bat22
-rwxr-xr-xqpid/dotnet/build-nant-release55
-rw-r--r--qpid/dotnet/build-nant.bat22
-rw-r--r--qpid/dotnet/client-010/App.config34
-rw-r--r--qpid/dotnet/client-010/LICENSE.txt757
-rw-r--r--qpid/dotnet/client-010/NOTICE.txt32
-rw-r--r--qpid/dotnet/client-010/README.txt69
-rw-r--r--qpid/dotnet/client-010/addins/ExcelAddIn/Excel.exe.config12
-rw-r--r--qpid/dotnet/client-010/addins/ExcelAddIn/ExcelAddIn.cs290
-rw-r--r--qpid/dotnet/client-010/addins/ExcelAddIn/ExcelAddIn.csproj89
-rw-r--r--qpid/dotnet/client-010/addins/ExcelAddIn/Properties/AssemblyInfo.cs56
-rw-r--r--qpid/dotnet/client-010/addins/ExcelAddInMessageProcessor/ExcelAddInMessageProcessor.csproj86
-rw-r--r--qpid/dotnet/client-010/addins/ExcelAddInMessageProcessor/Processor.cs44
-rw-r--r--qpid/dotnet/client-010/addins/ExcelAddInMessageProcessor/Properties/AssemblyInfo.cs56
-rw-r--r--qpid/dotnet/client-010/addins/ExcelAddInProducer/ExcelAddInProducer.csproj83
-rw-r--r--qpid/dotnet/client-010/addins/ExcelAddInProducer/Program.cs62
-rw-r--r--qpid/dotnet/client-010/addins/ExcelAddInProducer/Properties/AssemblyInfo.cs54
-rw-r--r--qpid/dotnet/client-010/addins/README.txt29
-rw-r--r--qpid/dotnet/client-010/client/Client.csproj242
-rw-r--r--qpid/dotnet/client-010/client/Properties/AssemblyInfo.cs56
-rw-r--r--qpid/dotnet/client-010/client/client.sln129
-rw-r--r--qpid/dotnet/client-010/client/client.suobin0 -> 572415 bytes
-rw-r--r--qpid/dotnet/client-010/client/client/Client.cs195
-rw-r--r--qpid/dotnet/client-010/client/client/ClientConnectionDelegate.cs128
-rw-r--r--qpid/dotnet/client-010/client/client/ClientInterface.cs59
-rw-r--r--qpid/dotnet/client-010/client/client/ClientSession.cs109
-rw-r--r--qpid/dotnet/client-010/client/client/ClientSessionDelegate.cs55
-rw-r--r--qpid/dotnet/client-010/client/client/ClosedListenerInterface.cs29
-rw-r--r--qpid/dotnet/client-010/client/client/ErrorCode.cs140
-rw-r--r--qpid/dotnet/client-010/client/client/IClient.cs82
-rw-r--r--qpid/dotnet/client-010/client/client/IClientSession.cs39
-rw-r--r--qpid/dotnet/client-010/client/client/IClosedListener.cs29
-rw-r--r--qpid/dotnet/client-010/client/client/IMessage.cs48
-rw-r--r--qpid/dotnet/client-010/client/client/IMessageListener.cs31
-rw-r--r--qpid/dotnet/client-010/client/client/Message.cs131
-rw-r--r--qpid/dotnet/client-010/client/default.build46
-rw-r--r--qpid/dotnet/client-010/client/transport/Binary.cs129
-rw-r--r--qpid/dotnet/client-010/client/transport/Binding.cs34
-rw-r--r--qpid/dotnet/client-010/client/transport/Channel.cs174
-rw-r--r--qpid/dotnet/client-010/client/transport/ChannelDelegate.cs41
-rw-r--r--qpid/dotnet/client-010/client/transport/ClientDelegate.cs35
-rw-r--r--qpid/dotnet/client-010/client/transport/Connection.cs168
-rw-r--r--qpid/dotnet/client-010/client/transport/ConnectionDelegate.cs108
-rw-r--r--qpid/dotnet/client-010/client/transport/Field.cs74
-rw-r--r--qpid/dotnet/client-010/client/transport/Future.cs38
-rw-r--r--qpid/dotnet/client-010/client/transport/Header.cs83
-rw-r--r--qpid/dotnet/client-010/client/transport/IBinding.cs34
-rw-r--r--qpid/dotnet/client-010/client/transport/IFuture.cs38
-rw-r--r--qpid/dotnet/client-010/client/transport/IProtocolDelegate.cs37
-rw-r--r--qpid/dotnet/client-010/client/transport/IProtocolEvent.cs42
-rw-r--r--qpid/dotnet/client-010/client/transport/IReceiver.cs38
-rw-r--r--qpid/dotnet/client-010/client/transport/ISender.cs32
-rw-r--r--qpid/dotnet/client-010/client/transport/ISession.cs73
-rw-r--r--qpid/dotnet/client-010/client/transport/Method.cs150
-rw-r--r--qpid/dotnet/client-010/client/transport/ProtocolDelegate.cs37
-rw-r--r--qpid/dotnet/client-010/client/transport/ProtocolError.cs85
-rw-r--r--qpid/dotnet/client-010/client/transport/ProtocolEvent.cs42
-rw-r--r--qpid/dotnet/client-010/client/transport/ProtocolHeader.cs124
-rw-r--r--qpid/dotnet/client-010/client/transport/Range.cs117
-rw-r--r--qpid/dotnet/client-010/client/transport/RangeSet.cs150
-rw-r--r--qpid/dotnet/client-010/client/transport/ReceivedPayload.cs43
-rw-r--r--qpid/dotnet/client-010/client/transport/Receiver.cs38
-rw-r--r--qpid/dotnet/client-010/client/transport/Sender.cs32
-rw-r--r--qpid/dotnet/client-010/client/transport/Session.cs522
-rw-r--r--qpid/dotnet/client-010/client/transport/SessionDelegate.cs126
-rw-r--r--qpid/dotnet/client-010/client/transport/Struct.cs121
-rw-r--r--qpid/dotnet/client-010/client/transport/codec/AbstractDecoder.cs399
-rw-r--r--qpid/dotnet/client-010/client/transport/codec/AbstractEncoder.cs590
-rw-r--r--qpid/dotnet/client-010/client/transport/codec/Decoder.cs72
-rw-r--r--qpid/dotnet/client-010/client/transport/codec/Encodable.cs37
-rw-r--r--qpid/dotnet/client-010/client/transport/codec/Encoder.cs70
-rw-r--r--qpid/dotnet/client-010/client/transport/codec/IDecoder.cs72
-rw-r--r--qpid/dotnet/client-010/client/transport/codec/IEncodable.cs37
-rw-r--r--qpid/dotnet/client-010/client/transport/codec/IEncoder.cs70
-rw-r--r--qpid/dotnet/client-010/client/transport/codec/MSDecoder.cs110
-rw-r--r--qpid/dotnet/client-010/client/transport/codec/MSEncoder.cs172
-rw-r--r--qpid/dotnet/client-010/client/transport/exception/ConnectionException.cs49
-rw-r--r--qpid/dotnet/client-010/client/transport/exception/ExceptionArgs.cs41
-rw-r--r--qpid/dotnet/client-010/client/transport/exception/ProtocolVersionException.cs59
-rw-r--r--qpid/dotnet/client-010/client/transport/exception/SessionClosedException.cs38
-rw-r--r--qpid/dotnet/client-010/client/transport/exception/SessionException.cs45
-rw-r--r--qpid/dotnet/client-010/client/transport/exception/TransportException.cs46
-rw-r--r--qpid/dotnet/client-010/client/transport/network/Assembler.cs254
-rw-r--r--qpid/dotnet/client-010/client/transport/network/Disassembler.cs222
-rw-r--r--qpid/dotnet/client-010/client/transport/network/Frame.cs143
-rw-r--r--qpid/dotnet/client-010/client/transport/network/IIoSender.cs28
-rw-r--r--qpid/dotnet/client-010/client/transport/network/INetworkDelegate.cs40
-rw-r--r--qpid/dotnet/client-010/client/transport/network/INetworkEvent.cs32
-rw-r--r--qpid/dotnet/client-010/client/transport/network/InputHandler.cs266
-rw-r--r--qpid/dotnet/client-010/client/transport/network/NetworkDelegate.cs40
-rw-r--r--qpid/dotnet/client-010/client/transport/network/NetworkEvent.cs32
-rw-r--r--qpid/dotnet/client-010/client/transport/network/io/IIoSender.cs28
-rw-r--r--qpid/dotnet/client-010/client/transport/network/io/IIoTransport.cs57
-rw-r--r--qpid/dotnet/client-010/client/transport/network/io/IoReceiver.cs185
-rw-r--r--qpid/dotnet/client-010/client/transport/network/io/IoSSLTransport.cs227
-rw-r--r--qpid/dotnet/client-010/client/transport/network/io/IoSender.cs137
-rw-r--r--qpid/dotnet/client-010/client/transport/network/io/IoTransport.cs141
-rw-r--r--qpid/dotnet/client-010/client/transport/util/ByteEncoder.cs218
-rw-r--r--qpid/dotnet/client-010/client/transport/util/CircularBuffer.cs132
-rw-r--r--qpid/dotnet/client-010/client/transport/util/Functions.cs41
-rw-r--r--qpid/dotnet/client-010/client/transport/util/Logger.cs114
-rw-r--r--qpid/dotnet/client-010/client/transport/util/ResultFuture.cs80
-rw-r--r--qpid/dotnet/client-010/client/transport/util/Serial.cs94
-rw-r--r--qpid/dotnet/client-010/client/transport/util/UUID.cs129
-rw-r--r--qpid/dotnet/client-010/default.build275
-rw-r--r--qpid/dotnet/client-010/demo/Demo.csproj110
-rw-r--r--qpid/dotnet/client-010/demo/Program.cs126
-rw-r--r--qpid/dotnet/client-010/demo/Properties/AssemblyInfo.cs54
-rw-r--r--qpid/dotnet/client-010/demo/Properties/Resources.Designer.cs84
-rw-r--r--qpid/dotnet/client-010/demo/Properties/Resources.resx137
-rw-r--r--qpid/dotnet/client-010/demo/Properties/Settings.Designer.cs47
-rw-r--r--qpid/dotnet/client-010/demo/Properties/Settings.settings27
-rw-r--r--qpid/dotnet/client-010/demo/default.build48
-rw-r--r--qpid/dotnet/client-010/examples/direct/example-direct-Listener/Listener.cs117
-rw-r--r--qpid/dotnet/client-010/examples/direct/example-direct-Listener/Properties/AssemblyInfo.cs54
-rw-r--r--qpid/dotnet/client-010/examples/direct/example-direct-Listener/default.build48
-rw-r--r--qpid/dotnet/client-010/examples/direct/example-direct-Listener/example-direct-Listener.csproj85
-rw-r--r--qpid/dotnet/client-010/examples/direct/example-direct-producer/Producer.cs92
-rw-r--r--qpid/dotnet/client-010/examples/direct/example-direct-producer/Properties/AssemblyInfo.cs54
-rw-r--r--qpid/dotnet/client-010/examples/direct/example-direct-producer/default.build48
-rw-r--r--qpid/dotnet/client-010/examples/direct/example-direct-producer/example-direct-producer.csproj85
-rw-r--r--qpid/dotnet/client-010/examples/direct/verify37
-rw-r--r--qpid/dotnet/client-010/examples/direct/verify.in14
-rw-r--r--qpid/dotnet/client-010/examples/direct/verify_cpp_dotnet29
-rw-r--r--qpid/dotnet/client-010/examples/direct/verify_cpp_dotnet.in14
-rw-r--r--qpid/dotnet/client-010/examples/direct/verify_dotnet_cpp29
-rw-r--r--qpid/dotnet/client-010/examples/direct/verify_dotnet_cpp.in15
-rw-r--r--qpid/dotnet/client-010/examples/fanout/example-fanout-Listener/Listener.cs126
-rw-r--r--qpid/dotnet/client-010/examples/fanout/example-fanout-Listener/Properties/AssemblyInfo.cs54
-rw-r--r--qpid/dotnet/client-010/examples/fanout/example-fanout-Listener/default.build48
-rw-r--r--qpid/dotnet/client-010/examples/fanout/example-fanout-Listener/example-fanout-Listener.csproj85
-rw-r--r--qpid/dotnet/client-010/examples/fanout/example-fanout-Producer/Producer.cs89
-rw-r--r--qpid/dotnet/client-010/examples/fanout/example-fanout-Producer/Properties/AssemblyInfo.cs54
-rw-r--r--qpid/dotnet/client-010/examples/fanout/example-fanout-Producer/default.build48
-rw-r--r--qpid/dotnet/client-010/examples/fanout/example-fanout-Producer/example-fanout-Producer.csproj85
-rw-r--r--qpid/dotnet/client-010/examples/fanout/verify36
-rw-r--r--qpid/dotnet/client-010/examples/fanout/verify.in14
-rw-r--r--qpid/dotnet/client-010/examples/fanout/verify_cpp_dotnet30
-rw-r--r--qpid/dotnet/client-010/examples/fanout/verify_cpp_dotnet.in14
-rw-r--r--qpid/dotnet/client-010/examples/fanout/verify_dotnet_cpp31
-rw-r--r--qpid/dotnet/client-010/examples/fanout/verify_dotnet_cpp.in15
-rw-r--r--qpid/dotnet/client-010/examples/pub-sub/example-pub-sub-Listener/Listener.cs143
-rw-r--r--qpid/dotnet/client-010/examples/pub-sub/example-pub-sub-Listener/Properties/AssemblyInfo.cs54
-rw-r--r--qpid/dotnet/client-010/examples/pub-sub/example-pub-sub-Listener/default.build48
-rw-r--r--qpid/dotnet/client-010/examples/pub-sub/example-pub-sub-Listener/example-pub-sub-Listener.csproj85
-rw-r--r--qpid/dotnet/client-010/examples/pub-sub/example-pub-sub-Publisher/Properties/AssemblyInfo.cs54
-rw-r--r--qpid/dotnet/client-010/examples/pub-sub/example-pub-sub-Publisher/Publisher.cs98
-rw-r--r--qpid/dotnet/client-010/examples/pub-sub/example-pub-sub-Publisher/default.build48
-rw-r--r--qpid/dotnet/client-010/examples/pub-sub/example-pub-sub-Publisher/example-pub-sub-Publisher.csproj85
-rw-r--r--qpid/dotnet/client-010/examples/pub-sub/verify36
-rw-r--r--qpid/dotnet/client-010/examples/pub-sub/verify.in95
-rw-r--r--qpid/dotnet/client-010/examples/pub-sub/verify_cpp_dotnet31
-rw-r--r--qpid/dotnet/client-010/examples/pub-sub/verify_cpp_dotnet.in55
-rw-r--r--qpid/dotnet/client-010/examples/pub-sub/verify_dotnet_cpp30
-rw-r--r--qpid/dotnet/client-010/examples/pub-sub/verify_dotnet_cpp.in99
-rw-r--r--qpid/dotnet/client-010/examples/request-response/example-request-response-Client/Properties/AssemblyInfo.cs54
-rw-r--r--qpid/dotnet/client-010/examples/request-response/example-request-response-Client/RequestResponseClient.cs142
-rw-r--r--qpid/dotnet/client-010/examples/request-response/example-request-response-Client/default.build48
-rw-r--r--qpid/dotnet/client-010/examples/request-response/example-request-response-Client/example-request-response-Client.csproj85
-rw-r--r--qpid/dotnet/client-010/examples/request-response/example-request-response-Server/Properties/AssemblyInfo.cs54
-rw-r--r--qpid/dotnet/client-010/examples/request-response/example-request-response-Server/Server.cs141
-rw-r--r--qpid/dotnet/client-010/examples/request-response/example-request-response-Server/default.build48
-rw-r--r--qpid/dotnet/client-010/examples/request-response/example-request-response-Server/example-request-response-Server.csproj85
-rw-r--r--qpid/dotnet/client-010/examples/request-response/verify36
-rw-r--r--qpid/dotnet/client-010/examples/request-response/verify.in16
-rw-r--r--qpid/dotnet/client-010/examples/request-response/verify_cpp_dotnet31
-rw-r--r--qpid/dotnet/client-010/examples/request-response/verify_cpp_dotnet.in17
-rw-r--r--qpid/dotnet/client-010/examples/request-response/verify_dotnet_cpp31
-rw-r--r--qpid/dotnet/client-010/examples/request-response/verify_dotnet_cpp.in18
-rw-r--r--qpid/dotnet/client-010/gentool/Composite.tpl291
-rw-r--r--qpid/dotnet/client-010/gentool/Constant.tpl37
-rw-r--r--qpid/dotnet/client-010/gentool/Enum.tpl59
-rw-r--r--qpid/dotnet/client-010/gentool/IInvoker.tpl57
-rw-r--r--qpid/dotnet/client-010/gentool/Invoker.tpl67
-rw-r--r--qpid/dotnet/client-010/gentool/MethodDelegate.tpl35
-rw-r--r--qpid/dotnet/client-010/gentool/Option.tpl42
-rw-r--r--qpid/dotnet/client-010/gentool/StructFactory.tpl64
-rw-r--r--qpid/dotnet/client-010/gentool/Type.tpl103
-rw-r--r--qpid/dotnet/client-010/gentool/build.xml52
-rw-r--r--qpid/dotnet/client-010/gentool/codegen86
-rw-r--r--qpid/dotnet/client-010/gentool/dotnetgenutil.py271
-rw-r--r--qpid/dotnet/client-010/lib/log4net/log4net-licence.txt201
-rw-r--r--qpid/dotnet/client-010/lib/log4net/log4net.dllbin0 -> 266240 bytes
-rw-r--r--qpid/dotnet/client-010/lib/log4net/log4net.xml28676
-rw-r--r--qpid/dotnet/client-010/lib/nunit/nunit-licence.txt23
-rw-r--r--qpid/dotnet/client-010/lib/nunit/nunit.framework.dllbin0 -> 45056 bytes
-rw-r--r--qpid/dotnet/client-010/lib/plossum/C5-License.txt27
-rw-r--r--qpid/dotnet/client-010/lib/plossum/C5.dllbin0 -> 274432 bytes
-rw-r--r--qpid/dotnet/client-010/lib/plossum/Plossum CommandLine.dllbin0 -> 98304 bytes
-rw-r--r--qpid/dotnet/client-010/lib/plossum/license.txt28
-rw-r--r--qpid/dotnet/client-010/log.xml46
-rw-r--r--qpid/dotnet/client-010/management/console/AbstractConsole.cs45
-rw-r--r--qpid/dotnet/client-010/management/console/Agent.cs75
-rw-r--r--qpid/dotnet/client-010/management/console/Broker.cs351
-rw-r--r--qpid/dotnet/client-010/management/console/BrokerURL.cs71
-rw-r--r--qpid/dotnet/client-010/management/console/ClassKey.cs107
-rw-r--r--qpid/dotnet/client-010/management/console/Console.cs46
-rw-r--r--qpid/dotnet/client-010/management/console/MethodResult.cs67
-rw-r--r--qpid/dotnet/client-010/management/console/ObjectID.cs88
-rw-r--r--qpid/dotnet/client-010/management/console/QMFEvent.cs74
-rw-r--r--qpid/dotnet/client-010/management/console/QMFObject.cs294
-rw-r--r--qpid/dotnet/client-010/management/console/SchemaArgument.cs59
-rw-r--r--qpid/dotnet/client-010/management/console/SchemaClass.cs141
-rw-r--r--qpid/dotnet/client-010/management/console/SchemaMethod.cs66
-rw-r--r--qpid/dotnet/client-010/management/console/SchemaProperty.cs59
-rw-r--r--qpid/dotnet/client-010/management/console/SchemaStatistic.cs54
-rw-r--r--qpid/dotnet/client-010/management/console/SchemaVariable.cs84
-rw-r--r--qpid/dotnet/client-010/management/console/SequenceManager.cs62
-rw-r--r--qpid/dotnet/client-010/management/console/Session.cs796
-rw-r--r--qpid/dotnet/client-010/management/console/Util.cs150
-rw-r--r--qpid/dotnet/client-010/management/console/XMLUtil.cs127
-rw-r--r--qpid/dotnet/client-010/management/console/console.csproj101
-rw-r--r--qpid/dotnet/client-010/management/console/console.sln46
-rw-r--r--qpid/dotnet/client-010/management/console/default.build54
-rw-r--r--qpid/dotnet/client-010/perftest/PerfTest.cs715
-rw-r--r--qpid/dotnet/client-010/perftest/Properties/AssemblyInfo.cs54
-rw-r--r--qpid/dotnet/client-010/perftest/README.txt38
-rw-r--r--qpid/dotnet/client-010/perftest/default.build50
-rw-r--r--qpid/dotnet/client-010/perftest/perftest.csproj92
-rw-r--r--qpid/dotnet/client-010/test/Helpers/ConfigHelpers.cs65
-rw-r--r--qpid/dotnet/client-010/test/Properties/AssemblyInfo.cs56
-rw-r--r--qpid/dotnet/client-010/test/Qpid Test.dll.config31
-rw-r--r--qpid/dotnet/client-010/test/Test.csproj102
-rw-r--r--qpid/dotnet/client-010/test/default.build55
-rw-r--r--qpid/dotnet/client-010/test/interop/Admin.cs90
-rw-r--r--qpid/dotnet/client-010/test/interop/ApplicationHeaders.cs83
-rw-r--r--qpid/dotnet/client-010/test/interop/ConnectionTests.cs80
-rw-r--r--qpid/dotnet/client-010/test/interop/Message.cs180
-rw-r--r--qpid/dotnet/client-010/test/interop/TestCase.cs96
-rw-r--r--qpid/dotnet/client-010/test/transport/util/ByteEncoderTest.cs106
-rw-r--r--qpid/dotnet/client-010/test/transport/util/CircularBufferTest.cs89
-rw-r--r--qpid/dotnet/client-010/test/transport/util/ResultFutureTest.cs103
-rw-r--r--qpid/dotnet/client-010/test/transport/util/SerialTest.cs75
-rw-r--r--qpid/dotnet/client-010/test/transport/util/UUIDTest.cs64
-rw-r--r--qpid/dotnet/client-010/wcf/Properties/AssemblyInfo.cs57
-rw-r--r--qpid/dotnet/client-010/wcf/demo/ConfigDemo.suobin0 -> 23552 bytes
-rw-r--r--qpid/dotnet/client-010/wcf/demo/Demo.suobin0 -> 33280 bytes
-rw-r--r--qpid/dotnet/client-010/wcf/demo/wcfBookingClient/Form1.Designer.cs185
-rw-r--r--qpid/dotnet/client-010/wcf/demo/wcfBookingClient/Form1.cs96
-rw-r--r--qpid/dotnet/client-010/wcf/demo/wcfBookingClient/Form1.resx143
-rw-r--r--qpid/dotnet/client-010/wcf/demo/wcfBookingClient/Program.cs41
-rw-r--r--qpid/dotnet/client-010/wcf/demo/wcfBookingClient/Properties/AssemblyInfo.cs57
-rw-r--r--qpid/dotnet/client-010/wcf/demo/wcfBookingClient/Properties/Resources.Designer.cs92
-rw-r--r--qpid/dotnet/client-010/wcf/demo/wcfBookingClient/Properties/Resources.resx137
-rw-r--r--qpid/dotnet/client-010/wcf/demo/wcfBookingClient/Properties/Settings.Designer.cs51
-rw-r--r--qpid/dotnet/client-010/wcf/demo/wcfBookingClient/Properties/Settings.settings27
-rw-r--r--qpid/dotnet/client-010/wcf/demo/wcfBookingClient/wcBookingClient.csproj123
-rw-r--r--qpid/dotnet/client-010/wcf/demo/wcfBookingServer/Booking.cs62
-rw-r--r--qpid/dotnet/client-010/wcf/demo/wcfBookingServer/IBooking.cs43
-rw-r--r--qpid/dotnet/client-010/wcf/demo/wcfBookingServer/Order.cs45
-rw-r--r--qpid/dotnet/client-010/wcf/demo/wcfBookingServer/Program.cs98
-rw-r--r--qpid/dotnet/client-010/wcf/demo/wcfBookingServer/Properties/AssemblyInfo.cs57
-rw-r--r--qpid/dotnet/client-010/wcf/demo/wcfBookingServer/Receipt.cs46
-rw-r--r--qpid/dotnet/client-010/wcf/demo/wcfBookingServer/wcfBookingServer.csproj97
-rw-r--r--qpid/dotnet/client-010/wcf/demo/wcfHelloClient/App.config56
-rw-r--r--qpid/dotnet/client-010/wcf/demo/wcfHelloClient/HelloClient.cs36
-rw-r--r--qpid/dotnet/client-010/wcf/demo/wcfHelloClient/IHelloService.cs33
-rw-r--r--qpid/dotnet/client-010/wcf/demo/wcfHelloClient/Program.cs48
-rw-r--r--qpid/dotnet/client-010/wcf/demo/wcfHelloClient/Properties/AssemblyInfo.cs57
-rw-r--r--qpid/dotnet/client-010/wcf/demo/wcfHelloClient/wcfHelloClient.csproj85
-rw-r--r--qpid/dotnet/client-010/wcf/demo/wcfHelloServer/App.config64
-rw-r--r--qpid/dotnet/client-010/wcf/demo/wcfHelloServer/HelloService.cs34
-rw-r--r--qpid/dotnet/client-010/wcf/demo/wcfHelloServer/IHelloService.cs32
-rw-r--r--qpid/dotnet/client-010/wcf/demo/wcfHelloServer/Program.cs47
-rw-r--r--qpid/dotnet/client-010/wcf/demo/wcfHelloServer/Properties/AssemblyInfo.cs57
-rw-r--r--qpid/dotnet/client-010/wcf/demo/wcfHelloServer/wcfHelloServer.csproj87
-rw-r--r--qpid/dotnet/client-010/wcf/demo/wcfRPC/IUpperCase.cs31
-rw-r--r--qpid/dotnet/client-010/wcf/demo/wcfRPC/Program.cs113
-rw-r--r--qpid/dotnet/client-010/wcf/demo/wcfRPC/Properties/AssemblyInfo.cs57
-rw-r--r--qpid/dotnet/client-010/wcf/demo/wcfRPC/QpidBindingConfigurationElement.cs205
-rw-r--r--qpid/dotnet/client-010/wcf/demo/wcfRPC/UpperCase.cs33
-rw-r--r--qpid/dotnet/client-010/wcf/demo/wcfRPC/wcfRPC.csproj93
-rw-r--r--qpid/dotnet/client-010/wcf/model/CommunicationOperation.cs31
-rw-r--r--qpid/dotnet/client-010/wcf/model/QpidBinding.cs185
-rw-r--r--qpid/dotnet/client-010/wcf/model/QpidChannelBase.cs167
-rw-r--r--qpid/dotnet/client-010/wcf/model/QpidChannelFactory.cs74
-rw-r--r--qpid/dotnet/client-010/wcf/model/QpidChannelListener.cs79
-rw-r--r--qpid/dotnet/client-010/wcf/model/QpidChannelListenerBase.cs111
-rw-r--r--qpid/dotnet/client-010/wcf/model/QpidInputChannel.cs218
-rw-r--r--qpid/dotnet/client-010/wcf/model/QpidInputChannelBase.cs101
-rw-r--r--qpid/dotnet/client-010/wcf/model/QpidOutputChannel.cs89
-rw-r--r--qpid/dotnet/client-010/wcf/model/QpidOutputChannelBase.cs77
-rw-r--r--qpid/dotnet/client-010/wcf/model/QpidTransportBindingElement.cs186
-rw-r--r--qpid/dotnet/client-010/wcf/model/QpidTransportElement.cs183
-rw-r--r--qpid/dotnet/client-010/wcf/wcf.csproj79
-rw-r--r--qpid/dotnet/client-010/wcf/wcf.sln70
-rw-r--r--qpid/dotnet/client-010/wcf/wcf.suobin0 -> 105984 bytes
-rw-r--r--qpid/dotnet/default.build252
-rwxr-xr-xqpid/extras/qmf/setup.py4
-rw-r--r--qpid/extras/qmf/src/py/qmf/console.py30
-rw-r--r--qpid/extras/qmf/src/py/qmf2/__init__.py (renamed from qpid/extras/qmf/src/py/qmf2-prototype/__init__.py)0
-rw-r--r--qpid/extras/qmf/src/py/qmf2/agent.py (renamed from qpid/extras/qmf/src/py/qmf2-prototype/agent.py)0
-rw-r--r--qpid/extras/qmf/src/py/qmf2/common.py (renamed from qpid/extras/qmf/src/py/qmf2-prototype/common.py)0
-rw-r--r--qpid/extras/qmf/src/py/qmf2/console.py (renamed from qpid/extras/qmf/src/py/qmf2-prototype/console.py)0
-rw-r--r--qpid/extras/qmf/src/py/qmf2/tests/__init__.py (renamed from qpid/extras/qmf/src/py/qmf2-prototype/tests/__init__.py)0
-rw-r--r--qpid/extras/qmf/src/py/qmf2/tests/agent_discovery.py (renamed from qpid/extras/qmf/src/py/qmf2-prototype/tests/agent_discovery.py)0
-rw-r--r--qpid/extras/qmf/src/py/qmf2/tests/agent_test.py (renamed from qpid/extras/qmf/src/py/qmf2-prototype/tests/agent_test.py)0
-rw-r--r--qpid/extras/qmf/src/py/qmf2/tests/async_method.py (renamed from qpid/extras/qmf/src/py/qmf2-prototype/tests/async_method.py)0
-rw-r--r--qpid/extras/qmf/src/py/qmf2/tests/async_query.py (renamed from qpid/extras/qmf/src/py/qmf2-prototype/tests/async_query.py)0
-rw-r--r--qpid/extras/qmf/src/py/qmf2/tests/basic_method.py (renamed from qpid/extras/qmf/src/py/qmf2-prototype/tests/basic_method.py)0
-rw-r--r--qpid/extras/qmf/src/py/qmf2/tests/basic_query.py (renamed from qpid/extras/qmf/src/py/qmf2-prototype/tests/basic_query.py)0
-rw-r--r--qpid/extras/qmf/src/py/qmf2/tests/console_test.py (renamed from qpid/extras/qmf/src/py/qmf2-prototype/tests/console_test.py)0
-rw-r--r--qpid/extras/qmf/src/py/qmf2/tests/events.py (renamed from qpid/extras/qmf/src/py/qmf2-prototype/tests/events.py)0
-rw-r--r--qpid/extras/qmf/src/py/qmf2/tests/multi_response.py (renamed from qpid/extras/qmf/src/py/qmf2-prototype/tests/multi_response.py)0
-rw-r--r--qpid/extras/qmf/src/py/qmf2/tests/obj_gets.py (renamed from qpid/extras/qmf/src/py/qmf2-prototype/tests/obj_gets.py)0
-rw-r--r--qpid/extras/qmf/src/py/qmf2/tests/subscriptions.py (renamed from qpid/extras/qmf/src/py/qmf2-prototype/tests/subscriptions.py)0
-rwxr-xr-xqpid/extras/sasl/bootstrap2
-rw-r--r--qpid/extras/sasl/configure.ac1
-rw-r--r--qpid/extras/sasl/python/Makefile.am3
-rw-r--r--qpid/extras/sasl/ruby/Makefile.am2
-rw-r--r--qpid/extras/sasl/src/Makefile.am1
-rw-r--r--qpid/java/broker-plugins/access-control/MANIFEST.MF1
-rw-r--r--qpid/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/RuleSet.java361
-rw-r--r--qpid/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/plugins/AccessControl.java15
-rw-r--r--qpid/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/plugins/AccessControlTest.java281
-rw-r--r--qpid/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/plugins/PlainConfigurationTest.java194
-rw-r--r--qpid/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/plugins/RuleSetTest.java229
-rw-r--r--qpid/java/broker-plugins/experimental/info/src/main/java/org/apache/qpid/info/Activator.java9
-rw-r--r--qpid/java/broker-plugins/experimental/info/src/main/java/org/apache/qpid/info/AppInfo.java2
-rwxr-xr-xqpid/java/broker-plugins/experimental/shutdown/src/main/java/shutdown.bnd2
-rw-r--r--qpid/java/broker-plugins/firewall/src/test/java/org/apache/qpid/server/security/access/FirewallConfigurationTest.java148
-rw-r--r--qpid/java/broker-plugins/firewall/src/test/java/org/apache/qpid/server/security/access/FirewallPluginTest.java21
-rw-r--r--qpid/java/broker-plugins/simple-xml/MANIFEST.MF36
-rw-r--r--qpid/java/broker-plugins/simple-xml/build.xml29
-rwxr-xr-xqpid/java/broker-plugins/simple-xml/src/main/java/org/apache/qpid/server/security/access/config/PrincipalPermissions.java687
-rw-r--r--qpid/java/broker-plugins/simple-xml/src/main/java/org/apache/qpid/server/security/access/plugins/SimpleXML.java427
-rw-r--r--qpid/java/broker-plugins/simple-xml/src/main/java/org/apache/qpid/server/security/access/plugins/SimpleXMLActivator.java42
-rw-r--r--qpid/java/broker-plugins/simple-xml/src/main/java/org/apache/qpid/server/security/access/plugins/SimpleXMLConfiguration.java57
-rw-r--r--qpid/java/broker-plugins/simple-xml/src/test/java/org/apache/qpid/server/security/access/PrincipalPermissionsTest.java209
-rw-r--r--qpid/java/broker/bin/qpid-server.bat12
-rw-r--r--qpid/java/broker/etc/access19
-rw-r--r--qpid/java/broker/etc/config.xml22
-rw-r--r--qpid/java/broker/etc/jmxremote.access23
-rw-r--r--qpid/java/broker/etc/passwdVhost19
-rw-r--r--qpid/java/broker/etc/qpid-server.conf.jpp3
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/qmf/QMFService.java11
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/AMQBrokerManagerMBean.java70
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/AMQChannel.java63
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/Broker.java420
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/BrokerOptions.java152
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/Main.java525
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/ProtocolExclusion.java73
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/ServerConfiguration.java178
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/ServerNetworkTransportConfiguration.java75
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/VirtualHostConfiguration.java28
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/plugins/ConfigurationPlugin.java33
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/connection/ConnectionRegistry.java51
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/connection/IConnectionRegistry.java15
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/AbstractExchangeMBean.java4
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/federation/BrokerLink.java1
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/filter/PropertyExpression.java9
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionSecureOkMethodHandler.java13
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionStartOkMethodHandler.java15
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/handler/QueueDeclareHandler.java4
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/information/management/ServerInformationMBean.java81
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/logging/messages/Broker_logmessages.properties5
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/logging/messages/Channel_logmessages.properties4
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/logging/messages/VirtualHost_logmessages.properties5
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/logging/subjects/ChannelLogSubject.java2
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/logging/subjects/ConnectionLogSubject.java6
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/management/DefaultManagedObject.java56
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/management/JMXManagedObjectRegistry.java61
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/management/MBeanInvocationHandlerImpl.java41
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/message/ContentHeaderBodyAdapter.java2
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/message/MessageMetaData.java4
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/plugins/Plugin.java2
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/plugins/PluginManager.java43
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQConnectionModel.java37
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolEngine.java196
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolEngineFactory.java9
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolSession.java10
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolSessionMBean.java115
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQSessionModel.java28
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AmqpProtocolVersion.java23
-rwxr-xr-xqpid/java/broker/src/main/java/org/apache/qpid/server/protocol/MultiVersionProtocolEngine.java73
-rwxr-xr-xqpid/java/broker/src/main/java/org/apache/qpid/server/protocol/MultiVersionProtocolEngineFactory.java30
-rwxr-xr-xqpid/java/broker/src/main/java/org/apache/qpid/server/protocol/ProtocolEngine_0_10.java29
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/queue/AMQPriorityQueue.java4
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueue.java16
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueueMBean.java7
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/queue/IncomingMessage.java8
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/queue/QueueEntry.java27
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/queue/QueueEntryImpl.java21
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/queue/QueueRunner.java84
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/queue/SimpleAMQQueue.java217
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/queue/SimpleQueueEntryList.java3
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/registry/ApplicationRegistry.java367
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/registry/BrokerConfigAdapter.java2
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/registry/IApplicationRegistry.java11
-rwxr-xr-xqpid/java/broker/src/main/java/org/apache/qpid/server/security/AuthorizationHolder.java53
-rwxr-xr-xqpid/java/broker/src/main/java/org/apache/qpid/server/security/PrincipalHolder.java29
-rwxr-xr-xqpid/java/broker/src/main/java/org/apache/qpid/server/security/SecurityManager.java34
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/ObjectProperties.java4
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/AuthenticationResult.java77
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/ConfigurationFilePrincipalDatabaseManager.java221
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PrincipalDatabaseManager.java35
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PropertiesPrincipalDatabaseManager.java49
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/management/AMQUserManagementMBean.java407
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/AuthenticationManager.java58
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/AuthenticationManagerPluginFactory.java32
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/PrincipalDatabaseAuthenticationManager.java406
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/rmi/RMIPasswordAuthenticator.java54
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/AuthenticationProviderInitialiser.java21
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/GroupPrincipal.java99
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/UsernamePrincipal.java58
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/amqplain/AmqPlainSaslServerFactory.java7
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/anonymous/AnonymousSaslServerFactory.java9
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/crammd5/CRAMMD5HexInitialiser.java2
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/plain/PlainSaslServerFactory.java7
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/state/AMQStateManager.java2
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/stats/StatisticsCounter.java163
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/stats/StatisticsGatherer.java118
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/subscription/SubscriptionList.java213
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/subscription/Subscription_0_10.java3
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/transport/QpidAcceptor.java12
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/transport/ServerConnection.java174
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/transport/ServerConnectionDelegate.java54
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/transport/ServerSession.java121
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/transport/ServerSessionDelegate.java96
-rwxr-xr-xqpid/java/broker/src/main/java/org/apache/qpid/server/txn/AutoCommitTransaction.java5
-rwxr-xr-xqpid/java/broker/src/main/java/org/apache/qpid/server/txn/LocalTransaction.java47
-rwxr-xr-xqpid/java/broker/src/main/java/org/apache/qpid/server/txn/ServerTransaction.java7
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/virtualhost/HouseKeepingTask.java4
-rwxr-xr-xqpid/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHost.java32
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHostImpl.java120
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/tools/messagestore/MessageStoreTool.java4
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/Show.java2
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/BrokerOptionsTest.java196
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/MainTest.java143
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/RunBrokerWithCommand.java132
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/configuration/ServerConfigurationTest.java767
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/configuration/VirtualHostConfigurationTest.java26
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/exchange/AbstractHeadersExchangeTestBase.java12
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/exchange/TopicExchangeTest.java2
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/logging/UnitTestMessageLogger.java16
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/management/AMQUserManagementMBeanTest.java202
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/protocol/InternalTestProtocolSession.java27
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/queue/AMQPriorityQueueTest.java2
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/queue/AMQQueueAlertTest.java2
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/queue/AMQQueueMBeanTest.java4
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/queue/AckTest.java2
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/queue/MockAMQQueue.java12
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/queue/MockQueueEntry.java10
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/queue/QueueEntryImplTest.java213
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/queue/SimpleAMQQueueTest.java754
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/queue/SimpleQueueEntryListTest.java53
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/manager/PrincipalDatabaseAuthenticationManagerTest.java358
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/rmi/RMIPasswordAuthenticatorTest.java269
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/sasl/CRAMMD5HexServerTest.java228
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/sasl/GroupPrincipalTest.java86
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/sasl/TestPrincipalUtils.java49
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/sasl/UsernamePrincipalTest.java122
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/stats/StatisticsCounterTest.java144
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/store/MessageStoreTest.java3
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/store/ReferenceCountingTest.java2
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/subscription/MockSubscription.java20
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/subscription/SubscriptionListTest.java429
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/txn/MockAction.java2
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/txn/MockServerMessage.java11
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/txn/MockStoreTransaction.java11
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/util/InternalBrokerBaseCase.java2
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/util/TestApplicationRegistry.java57
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/virtualhost/HouseKeepingTaskTest.java67
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/virtualhost/MockVirtualHost.java271
-rw-r--r--qpid/java/broker/src/velocity/java/org/apache/qpid/server/logging/GenerateLogMessages.java2
-rw-r--r--qpid/java/build.deps62
-rw-r--r--qpid/java/build.xml29
-rw-r--r--qpid/java/client/README.txt2
-rw-r--r--qpid/java/client/example/src/main/java/org/apache/qpid/example/pubsub/ConnectionSetup.java4
-rw-r--r--qpid/java/client/example/src/main/java/org/apache/qpid/example/pubsub/Publisher.java2
-rw-r--r--qpid/java/client/example/src/main/java/org/apache/qpid/example/transport/ExistingSocketConnectorDemo.java171
-rwxr-xr-xqpid/java/client/src/main/java/client.bnd2
-rw-r--r--qpid/java/client/src/main/java/org/apache/mina/transport/socket/nio/ExistingSocketConnector.java478
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/AMQAnyDestination.java13
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/AMQBrokerDetails.java38
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/AMQConnection.java111
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/AMQConnectionDelegate.java4
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/AMQConnectionDelegate_0_10.java52
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/AMQConnectionDelegate_8_0.java31
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/AMQConnectionURL.java19
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/AMQDestination.java112
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/AMQSession.java100
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/AMQSession_0_10.java113
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/AMQSession_0_8.java32
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/AMQTopic.java75
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/BasicMessageConsumer.java3
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/BasicMessageConsumer_0_10.java17
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/BasicMessageConsumer_0_8.java4
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/BasicMessageProducer_0_10.java51
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/ChannelToSessionMap.java20
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/CustomJMSXProperty.java29
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/QpidConnectionMetaData.java9
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/QueueSenderAdapter.java87
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/XAResourceImpl.java35
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/XASessionImpl.java2
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/handler/ConnectionStartMethodHandler.java2
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/message/AMQMessageDelegate_0_10.java35
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/message/AMQPEncodedMapMessage.java5
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/message/AbstractJMSMessageFactory.java2
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/message/MessageFactoryRegistry.java2
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/message/QpidMessageProperties.java34
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/messaging/address/AddressHelper.java35
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/messaging/address/Link.java15
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/protocol/AMQProtocolHandler.java52
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/protocol/AMQProtocolSession.java10
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/security/AMQCallbackHandler.java4
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/security/DynamicSaslRegistrar.properties1
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/security/UsernameHashedPasswordCallbackHandler.java30
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/security/UsernamePasswordCallbackHandler.java17
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/security/anonymous/AnonymousSaslClient.java52
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/security/anonymous/AnonymousSaslClientFactory.java52
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/transport/SocketTransportConnection.java90
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/transport/TransportConnection.java351
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/transport/VmPipeTransportConnection.java63
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/url/URLParser.java4
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/vmbroker/AMQVMBrokerCreationException.java60
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/filter/PropertyExpression.java13
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/jms/BrokerDetails.java2
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/jms/ConnectionURL.java2
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/jms/FailoverPolicy.java5
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/jms/failover/FailoverExchangeMethod.java6
-rw-r--r--qpid/java/client/src/test/java/org/apache/mina/transport/vmpipe/support/VmPipeIdleStatusChecker.java125
-rw-r--r--qpid/java/client/src/test/java/org/apache/qpid/client/MockAMQConnection.java5
-rw-r--r--qpid/java/client/src/test/java/org/apache/qpid/client/protocol/AMQProtocolHandlerTest.java23
-rw-r--r--qpid/java/client/src/test/java/org/apache/qpid/client/security/UsernameHashedPasswordCallbackHandlerTest.java99
-rw-r--r--qpid/java/client/src/test/java/org/apache/qpid/client/security/UsernamePasswordCallbackHandlerTest.java78
-rw-r--r--qpid/java/client/src/test/java/org/apache/qpid/jms/FailoverPolicyTest.java338
-rw-r--r--qpid/java/client/src/test/java/org/apache/qpid/test/unit/client/BrokerDetails/BrokerDetailsTest.java9
-rw-r--r--qpid/java/client/src/test/java/org/apache/qpid/test/unit/client/connectionurl/ConnectionURLTest.java99
-rw-r--r--qpid/java/client/src/test/java/org/apache/qpid/test/unit/message/TestAMQSession.java6
-rw-r--r--qpid/java/common.xml29
-rwxr-xr-xqpid/java/common/src/main/java/common.bnd2
-rw-r--r--qpid/java/common/src/main/java/org/apache/mina/common/FixedSizeByteBufferAllocator.java467
-rw-r--r--qpid/java/common/src/main/java/org/apache/mina/common/support/DefaultIoFuture.java227
-rw-r--r--qpid/java/common/src/main/java/org/apache/mina/common/support/IoServiceListenerSupport.java351
-rw-r--r--qpid/java/common/src/main/java/org/apache/mina/filter/WriteBufferFullExeception.java48
-rw-r--r--qpid/java/common/src/main/java/org/apache/mina/filter/WriteBufferLimitFilterBuilder.java272
-rw-r--r--qpid/java/common/src/main/java/org/apache/mina/filter/codec/OurCumulativeProtocolDecoder.java197
-rw-r--r--qpid/java/common/src/main/java/org/apache/mina/filter/codec/QpidProtocolCodecFilter.java440
-rw-r--r--qpid/java/common/src/main/java/org/apache/mina/transport/socket/nio/MultiThreadSocketAcceptor.java547
-rw-r--r--qpid/java/common/src/main/java/org/apache/mina/transport/socket/nio/MultiThreadSocketConnector.java486
-rw-r--r--qpid/java/common/src/main/java/org/apache/mina/transport/socket/nio/MultiThreadSocketFilterChain.java67
-rw-r--r--qpid/java/common/src/main/java/org/apache/mina/transport/socket/nio/MultiThreadSocketIoProcessor.java1026
-rw-r--r--qpid/java/common/src/main/java/org/apache/mina/transport/socket/nio/MultiThreadSocketSessionConfigImpl.java240
-rw-r--r--qpid/java/common/src/main/java/org/apache/mina/transport/socket/nio/MultiThreadSocketSessionImpl.java488
-rw-r--r--qpid/java/common/src/main/java/org/apache/mina/transport/vmpipe/QpidVmPipeConnector.java151
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/AMQChannelException.java3
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/AMQConnectionException.java3
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/AMQException.java16
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/ToyBroker.java208
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/ToyClient.java108
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/ToyExchange.java154
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/configuration/ClientProperties.java57
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/framing/AMQShortString.java83
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/framing/ContentHeaderBody.java12
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/protocol/ProtocolEngine.java5
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/protocol/ProtocolEngineFactory.java4
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/thread/QpidThreadExecutor.java2
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/transport/ClientDelegate.java6
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/transport/Connection.java50
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/transport/ConnectionDelegate.java1
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/transport/ConnectionSettings.java2
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/transport/NetworkDriver.java63
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/transport/NetworkDriverConfiguration.java44
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/transport/NetworkTransportConfiguration.java46
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/transport/ServerDelegate.java47
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/transport/Session.java96
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/transport/SessionDelegate.java16
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/transport/SocketConnectorFactory.java8
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/transport/TransportBuilder.java78
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/transport/codec/AbstractEncoder.java1
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/transport/network/IncomingNetworkTransport.java30
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/transport/network/NetworkConnection.java47
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/transport/network/NetworkTransport.java20
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/transport/network/OutgoingNetworkTransport.java32
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/transport/network/Transport.java123
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/transport/network/io/InputHandler_0_9.java130
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/transport/network/io/IoAcceptor.java (renamed from qpid/java/common/src/test/java/org/apache/qpid/transport/network/io/IoAcceptor.java)0
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/transport/network/io/IoContext.java35
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/transport/network/io/IoNetworkConnection.java93
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/transport/network/io/IoNetworkTransport.java87
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/transport/network/io/IoReceiver.java30
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/transport/network/io/IoSender.java51
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/transport/network/io/IoTransport.java231
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/transport/network/mina/MINANetworkDriver.java435
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/transport/network/mina/MinaHandler.java274
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/transport/network/mina/MinaNetworkConnection.java81
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/transport/network/mina/MinaNetworkHandler.java149
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/transport/network/mina/MinaNetworkTransport.java219
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/transport/network/mina/MinaSender.java65
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/transport/network/nio/NioHandler.java135
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/transport/network/nio/NioSender.java126
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/transport/network/security/SecurityLayer.java9
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/transport/network/security/sasl/SASLSender.java6
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/transport/network/security/ssl/QpidClientX509KeyManager.java12
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/url/URLHelper.java3
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/util/FileUtils.java25
-rw-r--r--qpid/java/common/src/test/java/org/apache/mina/SocketIOTest/IOWriterClient.java396
-rw-r--r--qpid/java/common/src/test/java/org/apache/mina/SocketIOTest/IOWriterServer.java157
-rw-r--r--qpid/java/common/src/test/java/org/apache/qpid/AMQExceptionTest.java13
-rw-r--r--qpid/java/common/src/test/java/org/apache/qpid/framing/AMQShortStringTest.java214
-rw-r--r--qpid/java/common/src/test/java/org/apache/qpid/test/utils/QpidTestCase.java55
-rw-r--r--qpid/java/common/src/test/java/org/apache/qpid/transport/MockSender.java47
-rw-r--r--qpid/java/common/src/test/java/org/apache/qpid/transport/TestNetworkConnection.java138
-rw-r--r--qpid/java/common/src/test/java/org/apache/qpid/transport/TestNetworkDriver.java133
-rw-r--r--qpid/java/common/src/test/java/org/apache/qpid/transport/network/TransportTest.java157
-rw-r--r--qpid/java/common/src/test/java/org/apache/qpid/transport/network/io/IoTransport.java165
-rw-r--r--qpid/java/common/src/test/java/org/apache/qpid/transport/network/mina/MINANetworkDriverTest.java494
-rw-r--r--qpid/java/common/src/test/java/org/apache/qpid/transport/network/mina/MinaNetworkHandlerTest.java534
-rw-r--r--qpid/java/common/src/test/java/org/apache/qpid/util/FileUtilsTest.java82
-rw-r--r--qpid/java/common/src/test/java/org/apache/qpid/util/default.properties2
-rw-r--r--qpid/java/common/src/test/java/org/apache/qpid/util/mydefaults.properties2
-rw-r--r--qpid/java/ivy.xml39
-rw-r--r--qpid/java/ivysettings-nexus.xml30
-rw-r--r--qpid/java/lib/backport-util-concurrent-2.2.jarbin0 -> 326319 bytes
-rw-r--r--qpid/java/lib/commons-pool-1.4.jarbin0 -> 87077 bytes
-rw-r--r--qpid/java/lib/core-3.1.1.jarbin0 -> 3566844 bytes
-rw-r--r--qpid/java/lib/geronimo-servlet_2.5_spec-1.2.jarbin0 -> 70593 bytes
-rw-r--r--qpid/java/lib/ivy/README.txt11
-rw-r--r--qpid/java/lib/javassist.jarbin0 -> 471005 bytes
-rw-r--r--qpid/java/lib/jline-0.9.94.jarbin0 -> 87325 bytes
-rw-r--r--qpid/java/lib/jsp-2.1.jarbin0 -> 1024681 bytes
-rw-r--r--qpid/java/lib/jsp-api-2.1.jarbin0 -> 134910 bytes
-rw-r--r--qpid/java/lib/junit-4.4.jarbin0 -> 161477 bytes
-rwxr-xr-xqpid/java/lib/mina-core-1.0.1.jarbin0 -> 313338 bytes
-rw-r--r--qpid/java/lib/mina-core-1.1.7.jarbin315582 -> 0 bytes
-rwxr-xr-xqpid/java/lib/mina-filter-ssl-1.0.1.jarbin0 -> 28950 bytes
-rw-r--r--qpid/java/lib/mina-filter-ssl-1.1.7.jarbin29188 -> 0 bytes
-rw-r--r--qpid/java/lib/muse-core-2.2.0.jarbin0 -> 121976 bytes
-rw-r--r--qpid/java/lib/muse-platform-mini-2.2.0.jarbin0 -> 8227 bytes
-rw-r--r--qpid/java/lib/muse-util-2.2.0.jarbin0 -> 23215 bytes
-rw-r--r--qpid/java/lib/muse-util-qname-2.2.0.jarbin0 -> 4968 bytes
-rw-r--r--qpid/java/lib/muse-util-xml-2.2.0.jarbin0 -> 19082 bytes
-rw-r--r--qpid/java/lib/muse-wsa-soap-2.2.0.jarbin0 -> 25030 bytes
-rw-r--r--qpid/java/lib/muse-wsdm-muws-adv-api-2.2.0.jarbin0 -> 4145 bytes
-rw-r--r--qpid/java/lib/muse-wsdm-muws-adv-impl-2.2.0.jarbin0 -> 10366 bytes
-rw-r--r--qpid/java/lib/muse-wsdm-muws-api-2.2.0.jarbin0 -> 18492 bytes
-rw-r--r--qpid/java/lib/muse-wsdm-muws-impl-2.2.0.jarbin0 -> 57860 bytes
-rw-r--r--qpid/java/lib/muse-wsdm-wef-api-2.2.0.jarbin0 -> 9125 bytes
-rw-r--r--qpid/java/lib/muse-wsdm-wef-impl-2.2.0.jarbin0 -> 18049 bytes
-rw-r--r--qpid/java/lib/muse-wsn-api-2.2.0.jarbin0 -> 29692 bytes
-rw-r--r--qpid/java/lib/muse-wsn-impl-2.2.0.jarbin0 -> 80531 bytes
-rw-r--r--qpid/java/lib/muse-wsrf-api-2.2.0.jarbin0 -> 58684 bytes
-rw-r--r--qpid/java/lib/muse-wsrf-impl-2.2.0.jarbin0 -> 127656 bytes
-rw-r--r--qpid/java/lib/muse-wsrf-rmd-2.2.0.jarbin0 -> 5625 bytes
-rw-r--r--qpid/java/lib/muse-wsx-api-2.2.0.jarbin0 -> 4624 bytes
-rw-r--r--qpid/java/lib/muse-wsx-impl-2.2.0.jarbin0 -> 9349 bytes
-rw-r--r--qpid/java/lib/poms/backport-util-concurrent-2.2.xml22
-rw-r--r--qpid/java/lib/poms/mina-core-1.0.1.xml22
-rw-r--r--qpid/java/lib/poms/mina-core-1.1.7.xml22
-rw-r--r--qpid/java/lib/poms/mina-filter-ssl-1.0.1.xml22
-rw-r--r--qpid/java/lib/poms/mina-filter-ssl-1.1.7.xml22
-rw-r--r--qpid/java/lib/start.jarbin0 -> 17125 bytes
-rw-r--r--qpid/java/lib/wsdl4j-1.6.1.jarbin0 -> 148522 bytes
-rw-r--r--qpid/java/lib/xercesImpl-2.8.1.jarbin0 -> 1212965 bytes
-rw-r--r--qpid/java/lib/xml-apis-1.3.03.jarbin0 -> 195119 bytes
-rw-r--r--qpid/java/management/agent/build.xml27
-rw-r--r--qpid/java/management/agent/src/main/java/org/apache/qpid/agent/Agent.java706
-rw-r--r--qpid/java/management/agent/src/main/java/org/apache/qpid/agent/AgentException.java45
-rw-r--r--qpid/java/management/agent/src/main/java/org/apache/qpid/agent/EventSeverity.java27
-rw-r--r--qpid/java/management/agent/src/main/java/org/apache/qpid/agent/ManagedEJB.java138
-rw-r--r--qpid/java/management/agent/src/main/java/org/apache/qpid/agent/ManagedObject.java52
-rw-r--r--qpid/java/management/agent/src/main/java/org/apache/qpid/agent/ManagedObjectBase.java72
-rw-r--r--qpid/java/management/agent/src/main/java/org/apache/qpid/agent/ManagedPOJO.java90
-rw-r--r--qpid/java/management/agent/src/main/java/org/apache/qpid/agent/annotations/QMFAgent.java34
-rw-r--r--qpid/java/management/agent/src/main/java/org/apache/qpid/agent/annotations/QMFEvent.java42
-rw-r--r--qpid/java/management/agent/src/main/java/org/apache/qpid/agent/annotations/QMFHide.java39
-rw-r--r--qpid/java/management/agent/src/main/java/org/apache/qpid/agent/annotations/QMFObject.java42
-rw-r--r--qpid/java/management/agent/src/main/java/org/apache/qpid/agent/annotations/QMFProperty.java39
-rw-r--r--qpid/java/management/agent/src/main/java/org/apache/qpid/agent/annotations/QMFSeeAlso.java40
-rw-r--r--qpid/java/management/agent/src/main/java/org/apache/qpid/agent/annotations/QMFType.java42
-rw-r--r--qpid/java/management/agent/src/main/java/org/apache/qpid/agent/binding/BindingContext.java213
-rw-r--r--qpid/java/management/agent/src/main/java/org/apache/qpid/agent/binding/BindingException.java50
-rw-r--r--qpid/java/management/agent/src/main/java/org/apache/qpid/agent/binding/BindingUtils.java137
-rw-r--r--qpid/java/management/agent/src/main/java/org/apache/qpid/agent/binding/ClassBinding.java601
-rw-r--r--qpid/java/management/agent/src/main/java/org/apache/qpid/agent/binding/EnumBinding.java108
-rw-r--r--qpid/java/management/agent/src/main/java/org/apache/qpid/agent/binding/ListBinding.java131
-rw-r--r--qpid/java/management/agent/src/main/java/org/apache/qpid/agent/binding/MapBinding.java95
-rw-r--r--qpid/java/management/agent/src/main/java/org/apache/qpid/agent/binding/MethodBinding.java91
-rw-r--r--qpid/java/management/agent/src/main/java/org/apache/qpid/agent/binding/ParameterBinding.java121
-rw-r--r--qpid/java/management/agent/src/main/java/org/apache/qpid/agent/binding/PropertyBinding.java131
-rw-r--r--qpid/java/management/agent/src/main/java/org/apache/qpid/agent/binding/QMFTypeBinding.java465
-rw-r--r--qpid/java/management/agent/src/main/java/org/apache/qpid/agent/binding/TypeBinding.java46
-rw-r--r--qpid/java/management/agent/src/test/java/org/apache/qpid/agent/Crumpet.java70
-rw-r--r--qpid/java/management/agent/src/test/java/org/apache/qpid/agent/Muppet.java113
-rw-r--r--qpid/java/management/agent/src/test/java/org/apache/qpid/agent/Pikelet.java52
-rw-r--r--qpid/java/management/agent/src/test/java/org/apache/qpid/agent/Puppet.java29
-rw-r--r--qpid/java/management/client/README.txt42
-rw-r--r--qpid/java/management/client/bin/qman-jmx.cmd78
-rw-r--r--qpid/java/management/client/bin/qman-jmx.sh76
-rw-r--r--qpid/java/management/client/bin/qman-wsdm-start.cmd88
-rw-r--r--qpid/java/management/client/bin/qman-wsdm-start.sh89
-rw-r--r--qpid/java/management/client/bin/qman-wsdm-stop.cmd37
-rw-r--r--qpid/java/management/client/bin/qman-wsdm-stop.sh38
-rw-r--r--qpid/java/management/client/build.xml213
-rw-r--r--qpid/java/management/client/console/brokers_management.jsp209
-rw-r--r--qpid/java/management/client/console/console.jsp122
-rw-r--r--qpid/java/management/client/console/error_page.jsp59
-rw-r--r--qpid/java/management/client/console/fragments/header.jsp36
-rw-r--r--qpid/java/management/client/console/fragments/menu.jsp31
-rw-r--r--qpid/java/management/client/console/images/asf-logo.pngbin0 -> 4735 bytes
-rw-r--r--qpid/java/management/client/console/images/menu.gifbin0 -> 1953 bytes
-rw-r--r--qpid/java/management/client/console/images/menuleft.gifbin0 -> 640 bytes
-rw-r--r--qpid/java/management/client/console/images/menuright.gifbin0 -> 1398 bytes
-rw-r--r--qpid/java/management/client/console/images/qpid-logo.pngbin0 -> 39056 bytes
-rw-r--r--qpid/java/management/client/console/images/style.css202
-rw-r--r--qpid/java/management/client/console/jmx_perspective.jsp157
-rw-r--r--qpid/java/management/client/console/logging_configuration.jsp241
-rw-r--r--qpid/java/management/client/console/resources_management.jsp105
-rw-r--r--qpid/java/management/client/console/tbd.jsp48
-rw-r--r--qpid/java/management/client/console/wsdm_operations_perspective.jsp174
-rw-r--r--qpid/java/management/client/console/wsdm_properties_perspective.jsp218
-rw-r--r--qpid/java/management/client/console/wsdm_rmd_perspective.jsp99
-rw-r--r--qpid/java/management/client/console/wsdm_wsdl_perspective.jsp99
-rw-r--r--qpid/java/management/client/doc/man/qman-jmx17
-rw-r--r--qpid/java/management/client/etc/jetty.xml47
-rw-r--r--qpid/java/management/client/etc/qman-config.xml68
-rw-r--r--qpid/java/management/client/etc/qman-config.xsd63
-rw-r--r--qpid/java/management/client/etc/qman.log4j29
-rw-r--r--qpid/java/management/client/src/example/ConnectWithBroker.out.ok81
-rw-r--r--qpid/java/management/client/src/example/GetMultipleResourceProperties.out.ok262
-rw-r--r--qpid/java/management/client/src/example/GetQManResourceMembers.out.ko54
-rw-r--r--qpid/java/management/client/src/example/GetQManResourceMembers.out.ok55
-rw-r--r--qpid/java/management/client/src/example/GetResourceMetadataDescriptor.out.ok188
-rw-r--r--qpid/java/management/client/src/example/GetResourcePropertyDocument.out.ok138
-rw-r--r--qpid/java/management/client/src/example/GetResourcePropertyRequest.out.ok588
-rw-r--r--qpid/java/management/client/src/example/GetWsdlMetadata.out.ko.no.resources58
-rw-r--r--qpid/java/management/client/src/example/GetWsdlMetadata.out.ok1968
-rw-r--r--qpid/java/management/client/src/example/PauseAndResumeSubscription.out.ok133
-rw-r--r--qpid/java/management/client/src/example/README.txt69
-rw-r--r--qpid/java/management/client/src/example/SetResourcePropertiesRequest.out.ok2316
-rw-r--r--qpid/java/management/client/src/example/org/apache/qpid/management/example/AbstractQManExample.java140
-rw-r--r--qpid/java/management/client/src/example/org/apache/qpid/management/example/ConnectWithBrokerExample.java240
-rw-r--r--qpid/java/management/client/src/example/org/apache/qpid/management/example/ConsumerAndProducerExample.java293
-rw-r--r--qpid/java/management/client/src/example/org/apache/qpid/management/example/GetMultipleResourcePropertiesExample.java179
-rw-r--r--qpid/java/management/client/src/example/org/apache/qpid/management/example/GetQManResourceMembersExample.java93
-rw-r--r--qpid/java/management/client/src/example/org/apache/qpid/management/example/GetResourceMetadataDescriptorExample.java156
-rw-r--r--qpid/java/management/client/src/example/org/apache/qpid/management/example/GetResourcePropertyDocumentExample.java111
-rw-r--r--qpid/java/management/client/src/example/org/apache/qpid/management/example/GetResourcePropertyExample.java172
-rw-r--r--qpid/java/management/client/src/example/org/apache/qpid/management/example/GetWSDLMetadataExample.java156
-rw-r--r--qpid/java/management/client/src/example/org/apache/qpid/management/example/PausableSubscriptionExample.java88
-rw-r--r--qpid/java/management/client/src/example/org/apache/qpid/management/example/SetResourcePropertyExample.java306
-rw-r--r--qpid/java/management/client/src/main/java/muse.xml209
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/Messages.java175
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/Names.java216
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/Protocol.java52
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/BrokerAlreadyConnectedException.java53
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/BrokerConnectionData.java280
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/BrokerConnectionDataParser.java136
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/BrokerConnectionException.java42
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/Configuration.java485
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/ConfigurationException.java51
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/Configurator.java240
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/IParser.java44
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/MessageHandlerMapping.java64
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/QpidDatasource.java249
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/Tag.java54
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/UnknownAccessCodeException.java53
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/UnknownBrokerException.java43
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/UnknownTypeCodeException.java53
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/WorkerManagerConfigurationParser.java109
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/base/BaseMessageHandler.java54
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/base/ContentIndicationMessageHandler.java114
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/base/IMessageHandler.java52
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/impl/ConfigurationMessageHandler.java57
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/impl/EventContentMessageHandler.java51
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/impl/HeartBeatIndicationMessageHandler.java39
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/impl/IMethodInvocationListener.java41
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/impl/InstrumentationMessageHandler.java57
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/impl/InvocationResult.java157
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/impl/MethodOrEventDataTransferObject.java68
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/impl/MethodResponseMessageHandler.java106
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/impl/QpidDomainObject.java314
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/impl/QpidDomainObjectMBean.java234
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/impl/SchemaResponseMessageHandler.java217
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/AccessMode.java33
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/Direction.java33
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/DomainModel.java239
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/IValidator.java38
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/InvocationEvent.java76
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/JmxService.java410
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/MissingFeatureAttributesException.java35
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidArgument.java123
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidAttribute.java105
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidClass.java833
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidClassMBean.java41
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidEntity.java184
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidEvent.java493
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidEventMBean.java41
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidFeature.java86
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidFeatureBuilder.java454
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidMethod.java147
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidPackage.java286
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidProperty.java295
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidStatistic.java34
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/UnableToBuildFeatureException.java51
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/ValidationException.java105
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/AbsTime.java44
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Binary.java169
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Boolean.java44
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/DeltaTime.java44
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Double.java44
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Float.java44
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Int16.java44
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Int32.java44
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Int64.java44
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Int8.java44
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Map.java45
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/ObjectReference.java44
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Str16.java44
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Str8.java44
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Type.java101
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Uint16.java44
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Uint32.java44
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Uint64.java44
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Uint8.java44
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Uuid.java46
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/services/BrokerMessageListener.java183
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/services/ManagementClient.java249
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/services/MessageTokenizer.java152
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/services/MethodInvocationException.java50
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/services/QMan.java412
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/services/QpidService.java361
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/services/SequenceNumberGenerator.java41
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/services/StartupFailureException.java42
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/services/UnableToComplyException.java31
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/jmx/EntityLifecycleNotification.java147
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/jmx/OperationHasBeenInvokedNotification.java168
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/messages/ManagementMessage.java189
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/messages/MethodInvocationRequestMessage.java161
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/messages/SchemaRequestMessage.java68
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/servlet/ConnectQManToBroker.java89
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/servlet/QManLifeCycleManager.java79
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/servlet/WSDMAdapter.java109
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/web/action/BrokerModel.java100
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/web/action/BrokersManagementAction.java204
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/web/action/ConsoleAction.java117
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/web/action/ConsoleModel.java158
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/web/action/JmxPerspectiveAction.java189
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/web/action/LoggingConfigurationAction.java114
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/web/action/ResourcesManagementAction.java91
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/web/action/WsdmOperationsPerspectiveAction.java191
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/web/action/WsdmPropertiesPerspectiveAction.java185
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/web/action/WsdmRmdPerspectiveAction.java139
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/web/action/WsdmWsdlPerspectiveAction.java140
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/QEmu.java130
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/QEmuInitializer.java95
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/QEmuMBean.java48
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/ArtifactsNotAvailableException.java76
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/BuilderException.java41
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/Constants.java44
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/ConsumerCapability.java68
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/DummyCapabilityBuilder.java86
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/IArtifactBuilder.java82
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/MBeanCapability.java219
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/MBeanCapabilityBuilder.java549
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/QManAdapterCapability.java557
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/QManMessageHandler.java104
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/QManMetadataExchangeCapability.java99
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/Result.java57
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/RmdBuilder.java135
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/WSDMArtifactsDirector.java196
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/WsArtifacts.java93
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/WsArtifactsFactory.java140
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/WsdlBuilder.java460
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/common/EntityInstanceNotFoundFault.java58
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/common/MethodInvocationFault.java79
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/common/NoSuchAttributeFault.java70
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/common/ObjectNameIdFactory.java61
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/common/QManFault.java72
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/common/QManResourceIdFactory.java57
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/common/ThreadSession.java105
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/common/ThreadSessionManager.java68
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/common/UnableToConnectWithBrokerFault.java86
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/muse/engine/WSDMAdapterEnvironment.java118
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/muse/engine/WSDMAdapterIsolationLayer.java57
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/muse/resources/QManWsResource.java762
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/muse/serializer/ByteArraySerializer.java83
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/muse/serializer/DateSerializer.java75
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/muse/serializer/InvocationResultSerializer.java85
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/muse/serializer/MapSerializer.java134
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/muse/serializer/ObjectSerializer.java202
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/muse/serializer/UUIDSerializer.java72
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/notifications/LifeCycleEvent.java149
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/notifications/LifeCycleEventType.java34
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/qman/debug/WsdlDebugger.java49
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/qman/debug/XmlDebugger.java92
-rw-r--r--qpid/java/management/client/src/main/java/router-entries/adapter/resource-instance-1.xml23
-rw-r--r--qpid/java/management/client/src/main/java/router-entries/consumer/resource-instance-1.xml23
-rw-r--r--qpid/java/management/client/src/main/java/wsdl/QManAdapter.rmd27
-rw-r--r--qpid/java/management/client/src/main/java/wsdl/QManAdapter.wsdl694
-rw-r--r--qpid/java/management/client/src/main/java/wsdl/QManWsResource.rmd17
-rw-r--r--qpid/java/management/client/src/main/java/wsdl/QManWsResource.wsdl507
-rw-r--r--qpid/java/management/client/src/main/java/wsdl/SOAP-Envelope-1_2.xsd181
-rw-r--r--qpid/java/management/client/src/main/java/wsdl/WS-Addressing-2005_08.xsd169
-rw-r--r--qpid/java/management/client/src/main/java/wsdl/WS-BaseFaults-1_2.xsd84
-rw-r--r--qpid/java/management/client/src/main/java/wsdl/WS-BaseNotification-1_3.wsdl449
-rw-r--r--qpid/java/management/client/src/main/java/wsdl/WS-BaseNotification-1_3.xsd577
-rw-r--r--qpid/java/management/client/src/main/java/wsdl/WS-MetadataExchange-2004_09.xsd134
-rw-r--r--qpid/java/management/client/src/main/java/wsdl/WS-Resource-1_2.wsdl54
-rw-r--r--qpid/java/management/client/src/main/java/wsdl/WS-Resource-1_2.xsd48
-rw-r--r--qpid/java/management/client/src/main/java/wsdl/WS-ResourceLifetime-1_2.wsdl83
-rw-r--r--qpid/java/management/client/src/main/java/wsdl/WS-ResourceLifetime-1_2.xsd130
-rw-r--r--qpid/java/management/client/src/main/java/wsdl/WS-ResourceMetadataDescriptor-CD-01.xsd325
-rw-r--r--qpid/java/management/client/src/main/java/wsdl/WS-ResourceProperties-1_2.wsdl395
-rw-r--r--qpid/java/management/client/src/main/java/wsdl/WS-ResourceProperties-1_2.xsd394
-rw-r--r--qpid/java/management/client/src/main/java/wsdl/WS-ServiceGroup-1_2.wsdl269
-rw-r--r--qpid/java/management/client/src/main/java/wsdl/WS-ServiceGroup-1_2.xsd233
-rw-r--r--qpid/java/management/client/src/main/java/wsdl/WS-ServiceGroupEntry-1_2.wsdl206
-rw-r--r--qpid/java/management/client/src/main/java/wsdl/WS-Topics-1_3.xsd185
-rw-r--r--qpid/java/management/client/src/main/java/wsdl/WSDM-MUWS-Part1-1_1.xsd114
-rw-r--r--qpid/java/management/client/src/main/java/wsdl/WSDM-MUWS-Part2-1_1.xsd677
-rw-r--r--qpid/java/management/client/src/main/java/wsdl/WsResource.rmd14
-rw-r--r--qpid/java/management/client/src/main/java/wsdl/WsResourceFactory.wsdl22
-rw-r--r--qpid/java/management/client/src/main/java/wsdl/XML-Namespace-1998.xsd46
-rw-r--r--qpid/java/management/client/src/test/java/org/apache/qpid/management/TestConstants.java67
-rw-r--r--qpid/java/management/client/src/test/java/org/apache/qpid/management/configuration/ConfigurationTest.java181
-rw-r--r--qpid/java/management/client/src/test/java/org/apache/qpid/management/configuration/ConfiguratorTest.java163
-rw-r--r--qpid/java/management/client/src/test/java/org/apache/qpid/management/configuration/MappingParsersTest.java79
-rw-r--r--qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/handler/base/ContentIndicationMessageHandlerTest.java59
-rw-r--r--qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/BaseDomainModelTestCase.java44
-rw-r--r--qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/BaseQpidFeatureBuilderTestCase.java96
-rw-r--r--qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/DomainModelTest.java55
-rw-r--r--qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/OptionalPropertiesTest.java187
-rw-r--r--qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/QpidClassTest.java408
-rw-r--r--qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/QpidEventTest.java293
-rw-r--r--qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/QpidMethodBuilderTest.java147
-rw-r--r--qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/QpidNumberPropertyTest.java171
-rw-r--r--qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/QpidPackageTest.java53
-rw-r--r--qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/QpidPropertyBuilderTest.java269
-rw-r--r--qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/QpidStatisticBuilderTest.java159
-rw-r--r--qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/QpidStringPropertyTest.java127
-rw-r--r--qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/type/BinaryTest.java59
-rw-r--r--qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/services/BrokerMessageListenerTest.java241
-rw-r--r--qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/services/MessageTokenizerTest.java140
-rw-r--r--qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/BaseWsDmAdapterTestCase.java143
-rw-r--r--qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/EnhancedReflectionProxyHandler.java72
-rw-r--r--qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/GetMultipleResourcePropertiesTestCase.java125
-rw-r--r--qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/GetResourcePropertiesTestCase.java105
-rw-r--r--qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/GetResourcePropertyDocumentTestCase.java134
-rw-r--r--qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/MetadataExchangeInterfaceTestCase.java169
-rw-r--r--qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/OperationInvocationInterfaceTestCase.java580
-rw-r--r--qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/ServerThread.java118
-rw-r--r--qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/SetResourcePropertiesTestCase.java219
-rw-r--r--qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/WebApplicationLifeCycleListener.java61
-rw-r--r--qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/WsDmAdapterTest.java156
-rw-r--r--qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/capabilities/MBeanCapabilityBuilderTest.java335
-rw-r--r--qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/capabilities/MBeanCapabilityTest.java204
-rw-r--r--qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/capabilities/QManAdapterCapabilityTest.java81
-rw-r--r--qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/capabilities/RmdBuilderTest.java110
-rw-r--r--qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/web.xml32
-rw-r--r--qpid/java/management/client/web.xml149
-rw-r--r--qpid/java/management/common/src/main/java/management-common.bnd2
-rw-r--r--qpid/java/management/common/src/main/java/org/apache/qpid/management/common/mbeans/ManagedBroker.java118
-rw-r--r--qpid/java/management/common/src/main/java/org/apache/qpid/management/common/mbeans/ManagedConnection.java127
-rw-r--r--qpid/java/management/common/src/main/java/org/apache/qpid/management/common/mbeans/ServerInformation.java121
-rw-r--r--qpid/java/management/common/src/main/java/org/apache/qpid/management/common/mbeans/UserManagement.java98
-rw-r--r--qpid/java/management/console/build.xml27
-rw-r--r--qpid/java/management/console/src/main/java/org/apache/qpid/console/AbstractConsole.java81
-rw-r--r--qpid/java/management/console/src/main/java/org/apache/qpid/console/Agent.java116
-rw-r--r--qpid/java/management/console/src/main/java/org/apache/qpid/console/Broker.java504
-rw-r--r--qpid/java/management/console/src/main/java/org/apache/qpid/console/ClassKey.java146
-rw-r--r--qpid/java/management/console/src/main/java/org/apache/qpid/console/Console.java51
-rw-r--r--qpid/java/management/console/src/main/java/org/apache/qpid/console/ConsoleException.java48
-rw-r--r--qpid/java/management/console/src/main/java/org/apache/qpid/console/EventSeverity.java37
-rw-r--r--qpid/java/management/console/src/main/java/org/apache/qpid/console/MethodResult.java88
-rw-r--r--qpid/java/management/console/src/main/java/org/apache/qpid/console/ObjectID.java93
-rw-r--r--qpid/java/management/console/src/main/java/org/apache/qpid/console/QMFEvent.java108
-rw-r--r--qpid/java/management/console/src/main/java/org/apache/qpid/console/QMFObject.java423
-rw-r--r--qpid/java/management/console/src/main/java/org/apache/qpid/console/SchemaArgument.java65
-rw-r--r--qpid/java/management/console/src/main/java/org/apache/qpid/console/SchemaClass.java251
-rw-r--r--qpid/java/management/console/src/main/java/org/apache/qpid/console/SchemaMethod.java125
-rw-r--r--qpid/java/management/console/src/main/java/org/apache/qpid/console/SchemaProperty.java81
-rw-r--r--qpid/java/management/console/src/main/java/org/apache/qpid/console/SchemaStatistic.java88
-rw-r--r--qpid/java/management/console/src/main/java/org/apache/qpid/console/SchemaVariable.java185
-rw-r--r--qpid/java/management/console/src/main/java/org/apache/qpid/console/SequenceManager.java57
-rw-r--r--qpid/java/management/console/src/main/java/org/apache/qpid/console/Session.java980
-rw-r--r--qpid/java/management/console/src/main/java/org/apache/qpid/console/Util.java184
-rw-r--r--qpid/java/management/console/src/main/java/org/apache/qpid/console/XMLUtil.java155
-rw-r--r--qpid/java/management/console/src/test/java/org/apache/qpid/console/ClassKeyTest.java39
-rw-r--r--qpid/java/management/eclipse-plugin/META-INF/MANIFEST.MF2
-rw-r--r--qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ApplicationRegistry.java2
-rw-r--r--qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/JMXManagedObject.java29
-rw-r--r--qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/model/NotificationObject.java25
-rw-r--r--qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/MBeanTabFolderFactory.java2
-rw-r--r--qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/users/LegacySupportingUserManagement.java132
-rw-r--r--qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/users/UserManagementTabControl.java199
-rw-r--r--qpid/java/management/tools/qpid-cli/Guide.txt143
-rw-r--r--qpid/java/management/tools/qpid-cli/LICENSE225
-rw-r--r--qpid/java/management/tools/qpid-cli/NOTICE12
-rw-r--r--qpid/java/management/tools/qpid-cli/README.txt64
-rwxr-xr-xqpid/java/management/tools/qpid-cli/bin/qpid-cli35
-rwxr-xr-xqpid/java/management/tools/qpid-cli/bin/qpid-cli.bat28
-rw-r--r--qpid/java/management/tools/qpid-cli/build.xml31
-rw-r--r--qpid/java/management/tools/qpid-cli/report.property26
-rw-r--r--qpid/java/management/tools/qpid-cli/src/org/apache/qpid/Command.java33
-rw-r--r--qpid/java/management/tools/qpid-cli/src/org/apache/qpid/CommandExecutionEngine.java76
-rw-r--r--qpid/java/management/tools/qpid-cli/src/org/apache/qpid/CommandLineInterpreter.java263
-rw-r--r--qpid/java/management/tools/qpid-cli/src/org/apache/qpid/Connector.java49
-rw-r--r--qpid/java/management/tools/qpid-cli/src/org/apache/qpid/ConnectorFactory.java50
-rw-r--r--qpid/java/management/tools/qpid-cli/src/org/apache/qpid/ReportGenerator.java195
-rw-r--r--qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/CommandImpl.java153
-rw-r--r--qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/Commanddelete.java199
-rw-r--r--qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/Commandget.java211
-rw-r--r--qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/Commandhelp.java56
-rw-r--r--qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/Commandinfo.java206
-rw-r--r--qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/Commandlist.java232
-rw-r--r--qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/Commandmove.java259
-rw-r--r--qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/Commandset.java260
-rw-r--r--qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/Commandview.java255
-rw-r--r--qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/Commandviewcontent.java248
-rw-r--r--qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/objects/AllObjects.java38
-rw-r--r--qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/objects/ConnectionObject.java46
-rw-r--r--qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/objects/ExchangeObject.java45
-rw-r--r--qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/objects/ObjectNames.java591
-rw-r--r--qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/objects/QueueObject.java67
-rw-r--r--qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/objects/UserManagementObject.java38
-rw-r--r--qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/objects/VirtualHostObject.java47
-rw-r--r--qpid/java/management/tools/qpid-cli/src/org/apache/qpid/utils/CommandLineOption.java104
-rw-r--r--qpid/java/management/tools/qpid-cli/src/org/apache/qpid/utils/CommandLineOptionConstants.java37
-rw-r--r--qpid/java/management/tools/qpid-cli/src/org/apache/qpid/utils/CommandLineOptionParser.java231
-rw-r--r--qpid/java/management/tools/qpid-cli/src/org/apache/qpid/utils/JMXConfigProperty.java29
-rw-r--r--qpid/java/management/tools/qpid-cli/src/org/apache/qpid/utils/JMXConfiguration.java182
-rw-r--r--qpid/java/management/tools/qpid-cli/src/org/apache/qpid/utils/JMXinfo.java53
-rw-r--r--qpid/java/management/tools/qpid-cli/test/org/apache/qpid/AllTest.java41
-rw-r--r--qpid/java/management/tools/qpid-cli/test/org/apache/qpid/ConnectionConstants.java30
-rw-r--r--qpid/java/management/tools/qpid-cli/test/org/apache/qpid/TestCommandExecutionEngine.java73
-rw-r--r--qpid/java/management/tools/qpid-cli/test/org/apache/qpid/TestCommandLineInterpreter.java80
-rw-r--r--qpid/java/management/tools/qpid-cli/test/org/apache/qpid/TestConnector.java79
-rw-r--r--qpid/java/management/tools/qpid-cli/test/org/apache/qpid/TestReportGenerator.java26
-rw-r--r--qpid/java/management/tools/qpid-cli/test/org/apache/qpid/commands/TestCommand.java79
-rw-r--r--qpid/java/management/tools/qpid-cli/test/org/apache/qpid/commands/TestCommanddelete.java79
-rw-r--r--qpid/java/management/tools/qpid-cli/test/org/apache/qpid/commands/TestCommandinfo.java77
-rw-r--r--qpid/java/management/tools/qpid-cli/test/org/apache/qpid/commands/TestCommandlist.java82
-rw-r--r--qpid/java/management/tools/qpid-cli/test/org/apache/qpid/commands/TestCommandmove.java80
-rw-r--r--qpid/java/management/tools/qpid-cli/test/org/apache/qpid/commands/TestCommandview.java78
-rw-r--r--qpid/java/management/tools/qpid-cli/test/org/apache/qpid/commands/TestCommandviewcontent.java78
-rw-r--r--qpid/java/management/tools/qpid-cli/test/org/apache/qpid/commands/objects/TestAllObject.java69
-rw-r--r--qpid/java/management/tools/qpid-cli/test/org/apache/qpid/commands/objects/TestConnectionObject.java83
-rw-r--r--qpid/java/management/tools/qpid-cli/test/org/apache/qpid/commands/objects/TestExchangeObject.java83
-rw-r--r--qpid/java/management/tools/qpid-cli/test/org/apache/qpid/commands/objects/TestObjectNames.java26
-rw-r--r--qpid/java/management/tools/qpid-cli/test/org/apache/qpid/commands/objects/TestQueueObject.java83
-rw-r--r--qpid/java/management/tools/qpid-cli/test/org/apache/qpid/commands/objects/TestUserManagementObject.java74
-rw-r--r--qpid/java/management/tools/qpid-cli/test/org/apache/qpid/commands/objects/TestVirtualHostObject.java84
-rw-r--r--qpid/java/management/tools/qpid-cli/test/org/apache/qpid/utils/TestCommandLineOption.java64
-rw-r--r--qpid/java/management/tools/qpid-cli/test/org/apache/qpid/utils/TestCommandLineOptionParser.java79
-rw-r--r--qpid/java/management/tools/qpid-cli/test/org/apache/qpid/utils/TestJMXConfigProperty.java26
-rw-r--r--qpid/java/management/tools/qpid-cli/test/org/apache/qpid/utils/TestJMXConfiguration.java64
-rw-r--r--qpid/java/management/tools/qpid-cli/test/org/apache/qpid/utils/TestJMXinfo.java30
-rw-r--r--qpid/java/maven-settings.xml2
-rw-r--r--qpid/java/module.xml127
-rw-r--r--qpid/java/perftests/src/main/java/org/apache/qpid/test/testcases/MessageThroughputPerf.java207
-rw-r--r--qpid/java/resources/NOTICE7
-rw-r--r--qpid/java/systests/etc/config-systests-ServerConfigurationTest-New.xml78
-rw-r--r--qpid/java/systests/etc/config-systests-ServerConfigurationTest-Old.xml92
-rw-r--r--qpid/java/systests/etc/config-systests-acl-settings.xml26
-rw-r--r--qpid/java/systests/etc/config-systests-acl.xml30
-rw-r--r--qpid/java/systests/etc/config-systests-firewall-2.xml22
-rw-r--r--qpid/java/systests/etc/config-systests-firewall-3.xml22
-rw-r--r--qpid/java/systests/etc/virtualhosts-ServerConfigurationTest-New.xml45
-rw-r--r--qpid/java/systests/etc/virtualhosts-systests-acl-settings.xml180
-rw-r--r--qpid/java/systests/etc/virtualhosts-systests-acl.xml29
-rw-r--r--qpid/java/systests/src/main/java/org/apache/mina/transport/vmpipe/support/VmPipeIdleStatusChecker.java125
-rw-r--r--qpid/java/systests/src/main/java/org/apache/qpid/client/AMQQueueDeferredOrderingTest.java1
-rw-r--r--qpid/java/systests/src/main/java/org/apache/qpid/client/DispatcherTest.java1
-rw-r--r--qpid/java/systests/src/main/java/org/apache/qpid/client/MultipleJCAProviderRegistrationTest.java82
-rw-r--r--qpid/java/systests/src/main/java/org/apache/qpid/client/message/AMQPEncodedMapMessageTest.java26
-rw-r--r--qpid/java/systests/src/main/java/org/apache/qpid/jms/xa/XAResourceTest.java116
-rw-r--r--qpid/java/systests/src/main/java/org/apache/qpid/management/jmx/MessageConnectionStatisticsTest.java102
-rw-r--r--qpid/java/systests/src/main/java/org/apache/qpid/management/jmx/MessageStatisticsConfigurationTest.java162
-rw-r--r--qpid/java/systests/src/main/java/org/apache/qpid/management/jmx/MessageStatisticsDeliveryTest.java110
-rw-r--r--qpid/java/systests/src/main/java/org/apache/qpid/management/jmx/MessageStatisticsReportingTest.java90
-rw-r--r--qpid/java/systests/src/main/java/org/apache/qpid/management/jmx/MessageStatisticsTest.java218
-rw-r--r--qpid/java/systests/src/main/java/org/apache/qpid/management/jmx/MessageStatisticsTestCase.java128
-rw-r--r--qpid/java/systests/src/main/java/org/apache/qpid/server/BrokerStartupTest.java6
-rw-r--r--qpid/java/systests/src/main/java/org/apache/qpid/server/configuration/ServerConfigurationFileTest.java15
-rw-r--r--qpid/java/systests/src/main/java/org/apache/qpid/server/exchange/MessagingTestConfigProperties.java8
-rw-r--r--qpid/java/systests/src/main/java/org/apache/qpid/server/failover/FailoverMethodTest.java110
-rw-r--r--qpid/java/systests/src/main/java/org/apache/qpid/server/logging/AlertingTest.java2
-rw-r--r--qpid/java/systests/src/main/java/org/apache/qpid/server/logging/BrokerLoggingTest.java13
-rw-r--r--qpid/java/systests/src/main/java/org/apache/qpid/server/logging/ChannelLoggingTest.java4
-rw-r--r--qpid/java/systests/src/main/java/org/apache/qpid/server/logging/ManagementLoggingTest.java17
-rw-r--r--qpid/java/systests/src/main/java/org/apache/qpid/server/persistent/NoLocalAfterRecoveryTest.java19
-rw-r--r--qpid/java/systests/src/main/java/org/apache/qpid/server/queue/MultipleTransactedBatchProducerTest.java246
-rw-r--r--qpid/java/systests/src/main/java/org/apache/qpid/server/queue/PriorityTest.java1
-rw-r--r--qpid/java/systests/src/main/java/org/apache/qpid/server/security/acl/AbstractACLTestCase.java6
-rw-r--r--qpid/java/systests/src/main/java/org/apache/qpid/server/security/acl/ExternalACLTest.java611
-rw-r--r--qpid/java/systests/src/main/java/org/apache/qpid/server/security/acl/SimpleACLTest.java644
-rw-r--r--qpid/java/systests/src/main/java/org/apache/qpid/server/security/firewall/FirewallConfigTest.java18
-rw-r--r--qpid/java/systests/src/main/java/org/apache/qpid/test/client/destination/AddressBasedDestinationTest.java542
-rw-r--r--qpid/java/systests/src/main/java/org/apache/qpid/test/client/message/SelectorTest.java56
-rw-r--r--qpid/java/systests/src/main/java/org/apache/qpid/test/framework/qpid/AMQPFeatureDecorator.java96
-rw-r--r--qpid/java/systests/src/main/java/org/apache/qpid/test/framework/qpid/CauseFailureDecorator.java95
-rw-r--r--qpid/java/systests/src/main/java/org/apache/qpid/test/framework/qpid/CauseFailureInVM.java70
-rw-r--r--qpid/java/systests/src/main/java/org/apache/qpid/test/framework/qpid/InVMBrokerDecorator.java136
-rw-r--r--qpid/java/systests/src/main/java/org/apache/qpid/test/unit/ack/Acknowledge2ConsumersTest.java4
-rw-r--r--qpid/java/systests/src/main/java/org/apache/qpid/test/unit/ack/QuickAcking.java2
-rw-r--r--qpid/java/systests/src/main/java/org/apache/qpid/test/unit/basic/MultipleConnectionTest.java1
-rw-r--r--qpid/java/systests/src/main/java/org/apache/qpid/test/unit/client/AMQConnectionTest.java6
-rw-r--r--qpid/java/systests/src/main/java/org/apache/qpid/test/unit/client/DynamicQueueExchangeCreateTest.java22
-rw-r--r--qpid/java/systests/src/main/java/org/apache/qpid/test/unit/client/channelclose/ChannelCloseOkTest.java1
-rw-r--r--qpid/java/systests/src/main/java/org/apache/qpid/test/unit/client/channelclose/ChannelCloseTest.java105
-rw-r--r--qpid/java/systests/src/main/java/org/apache/qpid/test/unit/client/connection/ConnectionTest.java64
-rw-r--r--qpid/java/systests/src/main/java/org/apache/qpid/test/unit/client/protocol/AMQProtocolSessionTest.java25
-rw-r--r--qpid/java/systests/src/main/java/org/apache/qpid/test/unit/close/MessageRequeueTest.java7
-rw-r--r--qpid/java/systests/src/main/java/org/apache/qpid/test/unit/ct/DurableSubscriberTest.java4
-rw-r--r--qpid/java/systests/src/main/java/org/apache/qpid/test/unit/message/JMSPropertiesTest.java41
-rw-r--r--qpid/java/systests/src/main/java/org/apache/qpid/test/unit/transacted/TransactionTimeoutConfigurationTest.java82
-rw-r--r--qpid/java/systests/src/main/java/org/apache/qpid/test/unit/transacted/TransactionTimeoutDisabledTest.java72
-rw-r--r--qpid/java/systests/src/main/java/org/apache/qpid/test/unit/transacted/TransactionTimeoutTest.java335
-rw-r--r--qpid/java/systests/src/main/java/org/apache/qpid/test/unit/transacted/TransactionTimeoutTestCase.java253
-rw-r--r--qpid/java/systests/src/main/java/org/apache/qpid/test/utils/BrokerHolder.java26
-rw-r--r--qpid/java/systests/src/main/java/org/apache/qpid/test/utils/FailoverBaseCase.java22
-rw-r--r--qpid/java/systests/src/main/java/org/apache/qpid/test/utils/InternalBrokerHolder.java50
-rw-r--r--qpid/java/systests/src/main/java/org/apache/qpid/test/utils/JMXTestUtils.java111
-rw-r--r--qpid/java/systests/src/main/java/org/apache/qpid/test/utils/QpidBrokerTestCase.java303
-rw-r--r--qpid/java/systests/src/main/java/org/apache/qpid/test/utils/SpawnedBrokerHolder.java58
-rw-r--r--qpid/java/test-profiles/08StandaloneExcludes39
-rwxr-xr-xqpid/java/test-profiles/CPPExcludes11
-rw-r--r--qpid/java/test-profiles/Excludes2
-rwxr-xr-xqpid/java/test-profiles/Java010Excludes16
-rw-r--r--qpid/java/test-profiles/JavaExcludes50
-rw-r--r--qpid/java/test-profiles/JavaInVMExcludes43
-rw-r--r--qpid/java/test-profiles/JavaPre010Excludes42
-rw-r--r--qpid/java/test-profiles/JavaStandaloneExcludes55
-rw-r--r--qpid/java/test-profiles/cpp.async.testprofile2
-rw-r--r--qpid/java/test-profiles/cpp.testprofile5
-rw-r--r--qpid/java/test-profiles/default.testprofile61
-rw-r--r--qpid/java/test-profiles/java-dby-spawn.0-10.testprofile30
-rw-r--r--qpid/java/test-profiles/java-dby-spawn.0-9-1.testprofile36
-rw-r--r--qpid/java/test-profiles/java-dby.0-10.testprofile30
-rw-r--r--qpid/java/test-profiles/java-dby.0-9-1.testprofile36
-rw-r--r--qpid/java/test-profiles/java-derby.0.10.testprofile29
-rw-r--r--qpid/java/test-profiles/java-derby.testprofile33
-rw-r--r--qpid/java/test-profiles/java-mms-spawn.0-10.testprofile30
-rw-r--r--qpid/java/test-profiles/java-mms-spawn.0-9-1.testprofile31
-rw-r--r--qpid/java/test-profiles/java-mms.0-10.testprofile27
-rw-r--r--qpid/java/test-profiles/java-mms.0-9-1.testprofile32
-rw-r--r--qpid/java/test-profiles/java.0.10.testprofile26
-rw-r--r--qpid/java/test-profiles/java.testprofile28
-rw-r--r--qpid/java/test-profiles/test-provider.properties4
-rw-r--r--qpid/java/test-profiles/testprofile.defaults60
-rwxr-xr-xqpid/java/tools/bin/Profile-run-from-source71
-rwxr-xr-xqpid/java/tools/bin/check-qpid-java-env38
-rw-r--r--qpid/java/tools/bin/controller132
-rwxr-xr-xqpid/java/tools/bin/perf-report137
-rwxr-xr-xqpid/java/tools/bin/perf_report.sh140
-rw-r--r--[-rwxr-xr-x]qpid/java/tools/bin/qpid-bench16
-rwxr-xr-xqpid/java/tools/bin/qpid-python-testkit11
-rwxr-xr-xqpid/java/tools/bin/run-pub28
-rwxr-xr-xqpid/java/tools/bin/run-sub32
-rw-r--r--qpid/java/tools/bin/run_pub.sh24
-rw-r--r--qpid/java/tools/bin/run_sub.sh25
-rw-r--r--qpid/java/tools/bin/set-testkit-env.sh88
-rw-r--r--qpid/java/tools/bin/setenv.sh49
-rw-r--r--qpid/java/tools/bin/start-consumers119
-rw-r--r--qpid/java/tools/bin/start-producers136
-rw-r--r--qpid/java/tools/etc/perf-report.gnu42
-rw-r--r--qpid/java/tools/src/main/java/org/apache/qpid/tools/Clock.java92
-rw-r--r--qpid/java/tools/src/main/java/org/apache/qpid/tools/LatencyTest.java12
-rw-r--r--qpid/java/tools/src/main/java/org/apache/qpid/tools/PerfBase.java166
-rw-r--r--qpid/java/tools/src/main/java/org/apache/qpid/tools/PerfConsumer.java224
-rw-r--r--qpid/java/tools/src/main/java/org/apache/qpid/tools/PerfProducer.java256
-rw-r--r--qpid/java/tools/src/main/java/org/apache/qpid/tools/PerfTestController.java422
-rw-r--r--qpid/java/tools/src/main/java/org/apache/qpid/tools/TestParams.java70
-rw-r--r--qpid/java/upload.xml90
-rw-r--r--qpid/packaging/windows/INSTALL_NOTES.html6
-rw-r--r--qpid/packaging/windows/installer.proj21
-rw-r--r--qpid/python/qpid/codec010.py17
-rw-r--r--qpid/python/qpid/messaging/driver.py15
-rw-r--r--qpid/python/qpid/messaging/endpoints.py5
-rw-r--r--qpid/python/qpid/messaging/transports.py18
-rw-r--r--qpid/python/qpid/tests/messaging/endpoints.py25
-rwxr-xr-xqpid/python/setup.py2
-rwxr-xr-xqpid/ruby/LICENSE.txt203
-rw-r--r--qpid/ruby/Makefile47
-rw-r--r--qpid/ruby/NOTICE.txt19
-rw-r--r--qpid/ruby/README.txt26
-rw-r--r--qpid/ruby/RELEASE_NOTES10
-rw-r--r--qpid/ruby/Rakefile116
-rwxr-xr-xqpid/ruby/examples/hello-world.rb61
-rw-r--r--qpid/ruby/examples/qmf-libvirt.rb80
-rw-r--r--qpid/ruby/ext/sasl/extconf.rb28
-rw-r--r--qpid/ruby/ext/sasl/sasl.c472
-rw-r--r--qpid/ruby/lib/qpid.rb41
-rw-r--r--qpid/ruby/lib/qpid/assembler.rb148
-rw-r--r--qpid/ruby/lib/qpid/client.rb136
-rw-r--r--qpid/ruby/lib/qpid/codec.rb457
-rw-r--r--qpid/ruby/lib/qpid/codec08.rb265
-rw-r--r--qpid/ruby/lib/qpid/config.rb32
-rw-r--r--qpid/ruby/lib/qpid/connection.rb222
-rw-r--r--qpid/ruby/lib/qpid/connection08.rb252
-rw-r--r--qpid/ruby/lib/qpid/datatypes.rb353
-rw-r--r--qpid/ruby/lib/qpid/delegates.rb237
-rw-r--r--qpid/ruby/lib/qpid/fields.rb49
-rw-r--r--qpid/ruby/lib/qpid/framer.rb212
-rw-r--r--qpid/ruby/lib/qpid/invoker.rb65
-rw-r--r--qpid/ruby/lib/qpid/packer.rb33
-rw-r--r--qpid/ruby/lib/qpid/peer.rb289
-rw-r--r--qpid/ruby/lib/qpid/qmf.rb1957
-rw-r--r--qpid/ruby/lib/qpid/queue.rb101
-rw-r--r--qpid/ruby/lib/qpid/session.rb458
-rw-r--r--qpid/ruby/lib/qpid/spec.rb183
-rw-r--r--qpid/ruby/lib/qpid/spec010.rb485
-rw-r--r--qpid/ruby/lib/qpid/spec08.rb190
-rw-r--r--qpid/ruby/lib/qpid/specs/amqp.0-10-qpid-errata.xml6654
-rw-r--r--qpid/ruby/lib/qpid/specs/amqp.0-10.dtd246
-rw-r--r--qpid/ruby/lib/qpid/test.rb35
-rw-r--r--qpid/ruby/lib/qpid/traverse.rb64
-rw-r--r--qpid/ruby/lib/qpid/util.rb75
-rw-r--r--qpid/ruby/tests/assembler.rb78
-rw-r--r--qpid/ruby/tests/codec010.rb122
-rw-r--r--qpid/ruby/tests/connection.rb246
-rw-r--r--qpid/ruby/tests/datatypes.rb224
-rw-r--r--qpid/ruby/tests/framer.rb99
-rw-r--r--qpid/ruby/tests/qmf.rb248
-rw-r--r--qpid/ruby/tests/queue.rb80
-rw-r--r--qpid/ruby/tests/spec010.rb80
-rw-r--r--qpid/ruby/tests/util.rb72
-rw-r--r--qpid/ruby/tests_0-8/basic.rb69
-rw-r--r--qpid/ruby/tests_0-8/channel.rb48
-rw-r--r--qpid/specs/management-schema.xml2
-rwxr-xr-xqpid/tests/setup.py2
-rw-r--r--qpid/tests/src/py/qpid_tests/broker_0_10/alternate_exchange.py125
-rw-r--r--qpid/tests/src/py/qpid_tests/broker_0_10/dtx.py102
-rw-r--r--qpid/tests/src/py/qpid_tests/broker_0_10/exchange.py4
-rw-r--r--qpid/tests/src/py/qpid_tests/broker_0_10/extensions.py58
-rw-r--r--qpid/tests/src/py/qpid_tests/broker_0_10/management.py67
-rw-r--r--qpid/tests/src/py/qpid_tests/broker_0_10/message.py16
-rw-r--r--qpid/tests/src/py/qpid_tests/broker_0_10/priority.py20
-rw-r--r--qpid/tests/src/py/qpid_tests/broker_0_10/threshold.py15
-rwxr-xr-xqpid/tools/setup.py5
-rwxr-xr-xqpid/tools/src/py/qpid-cluster9
-rwxr-xr-xqpid/tools/src/py/qpid-config64
-rwxr-xr-xqpid/tools/src/py/qpid-printevents28
-rwxr-xr-xqpid/tools/src/py/qpid-route56
-rwxr-xr-xqpid/tools/src/py/qpid-tool19
2187 files changed, 257317 insertions, 32796 deletions
diff --git a/.gitignore b/.gitignore
index 09e658593c..3562b0e191 100644
--- a/.gitignore
+++ b/.gitignore
@@ -6,9 +6,9 @@
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
@@ -35,6 +35,7 @@ autom4te.cache
aclocal.m4
developer.doxygen
user.doxygen
+qpidd.1
qpid/cpp/libtool
qpidc.spec
qpid/cpp/src/gen/
@@ -55,7 +56,6 @@ generated/
target
qpid/java/lib/cobertura
qpid/java/lib/findbugs
-qpid/java/lib/ivy
# Intellij Project files
*.iml
*.ipr
diff --git a/qpid/LICENSE b/qpid/LICENSE
index cd0c8d0a8b..5f84a6564b 100644
--- a/qpid/LICENSE
+++ b/qpid/LICENSE
@@ -1,5 +1,7 @@
Please see the individual LICENSE files for each language
cpp/LICENSE
+dotnet/LICENSE.txt
gentools/lib/LICENSE
java/resources/LICENSE
python/LICENSE.txt
+ruby/LICENSE.txt
diff --git a/qpid/NOTICE b/qpid/NOTICE
index 5691e0e1ac..ff65d299a9 100644
--- a/qpid/NOTICE
+++ b/qpid/NOTICE
@@ -1,6 +1,8 @@
Please see the individual NOTICE files for each language:
cpp/NOTICE
+dotnet/NOTICE.txt
gentools/lib/NOTICE
java/resources/NOTICE
python/NOTICE.txt
+ruby/NOTICE.txt
diff --git a/qpid/QPID_VERSION.txt b/qpid/QPID_VERSION.txt
index f3040840fd..b63ba696b7 100644
--- a/qpid/QPID_VERSION.txt
+++ b/qpid/QPID_VERSION.txt
@@ -1 +1 @@
-0.13
+0.9
diff --git a/qpid/README.txt b/qpid/README.txt
index ccd92c757b..00a56bdc3d 100644
--- a/qpid/README.txt
+++ b/qpid/README.txt
@@ -36,10 +36,22 @@ Python Client Libraries
./python
+Ruby Client Libraries
+
+ ./ruby
+
+.NET Client Libraries
+
+ ./dotnet
+
WCF Support
./wcf
+Messaging Client (implemented in Ruby):
+
+ ./ruby
+
Management Tools (implemented in Python):
./tools
@@ -54,4 +66,4 @@ Documentation:
Further information about the organization of Qpid source components may
-be found in ./doc/dev-readme/QPID-Component-README.pdf.
+be found in ./doc/dev-readme/QPID-0.8-Component-README.pdf.
diff --git a/qpid/bin/release.sh b/qpid/bin/release.sh
index 949cb57358..31c12e630c 100755
--- a/qpid/bin/release.sh
+++ b/qpid/bin/release.sh
@@ -41,8 +41,6 @@ usage()
echo "--ruby |-r : Generate the ruby artefacts"
echo "--python|-p : Generate the python artefacts"
echo "--wcf |-w : Generate the WCF artefacts"
- echo "--tools |-t : Generate the tools artefacts"
- echo "--qmf |-q : Generate the QMF artefacts"
echo "--source|-e : Generate the source artefact"
echo "--sign |-s : Sign generated artefacts"
echo "--upload|-u : Upload the artifacts directory to people.apache.org as qpid-\$VER"
@@ -76,11 +74,11 @@ for arg in $* ; do
;;
--all|-a)
CPP="CPP"
+ DOTNET="DOTNET"
JAVA="JAVA"
+ RUBY="RUBY"
PYTHON="PYTHON"
WCF="WCF"
- TOOLS="TOOLS"
- QMF="QMF"
SOURCE="SOURCE"
;;
--cpp|-c)
@@ -101,12 +99,6 @@ for arg in $* ; do
--wcf|-w)
WCF="WCF"
;;
- --tools|-t)
- TOOLS="TOOLS"
- ;;
- --qmf|-q)
- QMF="QMF"
- ;;
--source|-e)
SOURCE="SOURCE"
;;
@@ -226,8 +218,8 @@ if [ "JAVA" == "$JAVA" ] ; then
cp qpid-${VER}/java/management/eclipse-plugin/release/*.tar.gz qpid-${VER}/java/management/eclipse-plugin/release/*.zip artifacts/
# copy the Maven artifacts
- cp -a qpid-${VER}/java/client/release/maven artifacts/
- cp -a qpid-${VER}/java/common/release/maven artifacts/
+ cp qpid-${VER}/java/client/release/maven artifacts/
+ cp qpid-${VER}/java/common/release/maven artifacts/
fi
if [ "DOTNET" == "$DOTNET" ] ; then
@@ -247,26 +239,6 @@ if [ "DOTNET" == "$DOTNET" ] ; then
cp qpid-${VER}/dotnet/client-010/bin/mono-2.0/debug/*.zip artifacts/qpid-dotnet-0-10-${VER}.zip
fi
-if [ "TOOLS" = "$TOOLS" ] ; then
- pushd qpid-${VER}/tools
-
- python setup.py sdist
-
- popd
-
- cp qpid-${VER}/tools/dist/*.tar.gz artifacts/qpid-tools-${VER}.tar.gz
-fi
-
-if [ "QMF" = "$QMF" ]; then
- pushd qpid-${VER}/extras/qmf
-
- python setup.py sdist
-
- popd
-
- cp qpid-${VER}/extras/qmf/dist/*.tar.gz artifacts/qpid-qmf-${VER}.tar.gz
-fi
-
if [ "SIGN" == "$SIGN" ] ; then
pushd artifacts
sha1sum *.zip *.gz *.svnversion > SHA1SUM
diff --git a/qpid/cpp/Makefile.am b/qpid/cpp/Makefile.am
index 9f4b8e2082..01b8507454 100644
--- a/qpid/cpp/Makefile.am
+++ b/qpid/cpp/Makefile.am
@@ -33,7 +33,3 @@ SUBDIRS = managementgen etc src docs/api docs/man examples bindings/qmf bindings
# Update libtool, if needed.
libtool: $(LIBTOOL_DEPS)
$(SHELL) ./config.status --recheck
-
-check-long: all
- $(MAKE) -C src/tests check-long
- \ No newline at end of file
diff --git a/qpid/cpp/bindings/qmf/python/Makefile.am b/qpid/cpp/bindings/qmf/python/Makefile.am
index 8abad32959..421590f189 100644
--- a/qpid/cpp/bindings/qmf/python/Makefile.am
+++ b/qpid/cpp/bindings/qmf/python/Makefile.am
@@ -30,13 +30,11 @@ BUILT_SOURCES = $(generated_file_list)
SWIG_FLAGS = -w362,401
$(generated_file_list): $(srcdir)/python.i $(srcdir)/../qmfengine.i
- $(SWIG) -c++ -python $(SWIG_FLAGS) $(INCLUDES) $(QPID_CXXFLAGS) -I$(top_srcdir)/src/qmf -I/usr/include -o qmfengine.cpp $(srcdir)/python.i
+ swig -c++ -python $(SWIG_FLAGS) $(INCLUDES) $(QPID_CXXFLAGS) -I$(top_srcdir)/src/qmf -I/usr/include -o qmfengine.cpp $(srcdir)/python.i
pylibdir = $(PYTHON_LIB)
lib_LTLIBRARIES = _qmfengine.la
-qenginedir = $(pyexecdir)
-qengine_PYTHON = qmfengine.py qmf.py
#_qmfengine_la_LDFLAGS = -avoid-version -module -shrext "$(PYTHON_SO)"
#_qmfengine_la_LDFLAGS = -avoid-version -module -shrext ".so"
diff --git a/qpid/cpp/bindings/qmf/ruby/Makefile.am b/qpid/cpp/bindings/qmf/ruby/Makefile.am
index de8c4d10d5..cfb3a33870 100644
--- a/qpid/cpp/bindings/qmf/ruby/Makefile.am
+++ b/qpid/cpp/bindings/qmf/ruby/Makefile.am
@@ -35,9 +35,9 @@ qmfengine.cpp: $(srcdir)/ruby.i $(srcdir)/../qmfengine.i
rubylibarchdir = $(RUBY_LIB_ARCH)
rubylibarch_LTLIBRARIES = qmfengine.la
-qmfengine_la_LDFLAGS = -avoid-version -module -shared -shrext ".$(RUBY_DLEXT)"
+qmfengine_la_LDFLAGS = -avoid-version -module -shrext ".$(RUBY_DLEXT)"
qmfengine_la_LIBADD = $(RUBY_LIBS) -L$(top_builddir)/src/.libs -lqpidclient $(top_builddir)/src/libqmfengine.la
-qmfengine_la_CXXFLAGS = $(INCLUDES) -I$(RUBY_INC) -I$(RUBY_INC_ARCH) -fno-strict-aliasing
+qmfengine_la_CXXFLAGS = $(INCLUDES) -I$(RUBY_INC) -I$(RUBY_INC_ARCH)
nodist_qmfengine_la_SOURCES = qmfengine.cpp
CLEANFILES = qmfengine.cpp
diff --git a/qpid/cpp/bindings/qmf/tests/test_base.rb b/qpid/cpp/bindings/qmf/tests/test_base.rb
index 7d4609097c..3e4337a9c0 100644
--- a/qpid/cpp/bindings/qmf/tests/test_base.rb
+++ b/qpid/cpp/bindings/qmf/tests/test_base.rb
@@ -24,7 +24,6 @@ require 'socket'
class ConsoleTestBase < Qmf::ConsoleHandler
def initialize
- sleep(2)
@settings = Qmf::ConnectionSettings.new
@settings.host = ARGV[0] if ARGV.size > 0
@settings.port = ARGV[1].to_i if ARGV.size > 1
@@ -68,7 +67,7 @@ class ConsoleTestBase < Qmf::ConsoleHandler
def assert(condition, in_text=nil)
text = " (#{in_text})" if in_text
- raise "Assertion failed: #{condition} #{text}" unless condition
+ raise "Assertion failed: #{left} != #{right}#{text}" unless condition
end
def fail(text)
diff --git a/qpid/cpp/bindings/qmf2/python/Makefile.am b/qpid/cpp/bindings/qmf2/python/Makefile.am
index 3dc04e832f..7adc62eddb 100644
--- a/qpid/cpp/bindings/qmf2/python/Makefile.am
+++ b/qpid/cpp/bindings/qmf2/python/Makefile.am
@@ -30,12 +30,12 @@ BUILT_SOURCES = $(generated_file_list)
SWIG_FLAGS = -w362,401
$(generated_file_list): $(srcdir)/python.i $(srcdir)/../qmf2.i $(srcdir)/../../swig_python_typemaps.i
- $(SWIG) -c++ -python $(SWIG_FLAGS) $(INCLUDES) $(QPID_CXXFLAGS) -I/usr/include -o cqmf2.cpp $(srcdir)/python.i
+ swig -c++ -python $(SWIG_FLAGS) $(INCLUDES) $(QPID_CXXFLAGS) -I/usr/include -o cqmf2.cpp $(srcdir)/python.i
pylibdir = $(PYTHON_LIB)
lib_LTLIBRARIES = _cqmf2.la
-cqpiddir = $(pyexecdir)
+cqpiddir = $(pythondir)
cqpid_PYTHON = qmf2.py cqmf2.py
_cqmf2_la_LDFLAGS = -avoid-version -module -shared
diff --git a/qpid/cpp/bindings/qmf2/qmf2.i b/qpid/cpp/bindings/qmf2/qmf2.i
index 0f573fe3e6..a09a95168f 100644
--- a/qpid/cpp/bindings/qmf2/qmf2.i
+++ b/qpid/cpp/bindings/qmf2/qmf2.i
@@ -37,7 +37,6 @@
%}
-%include <qpid/ImportExport.h>
%include <qpid/messaging/ImportExport.h>
%include <qpid/messaging/Duration.h>
diff --git a/qpid/cpp/bindings/qmf2/ruby/Makefile.am b/qpid/cpp/bindings/qmf2/ruby/Makefile.am
index 97bbc6f385..ae840f87c6 100644
--- a/qpid/cpp/bindings/qmf2/ruby/Makefile.am
+++ b/qpid/cpp/bindings/qmf2/ruby/Makefile.am
@@ -34,9 +34,9 @@ rubylibarchdir = $(RUBY_LIB_ARCH)
rubylibarch_LTLIBRARIES = cqmf2.la
dist_rubylib_DATA = qmf2.rb
-cqmf2_la_LDFLAGS = -avoid-version -module -shared -shrext ".$(RUBY_DLEXT)"
+cqmf2_la_LDFLAGS = -avoid-version -module -shrext ".$(RUBY_DLEXT)"
cqmf2_la_LIBADD = $(RUBY_LIBS) -L$(top_builddir)/src/.libs -lqmf2 $(top_builddir)/src/libqmf2.la
-cqmf2_la_CXXFLAGS = $(INCLUDES) -I$(RUBY_INC) -I$(RUBY_INC_ARCH) -fno-strict-aliasing
+cqmf2_la_CXXFLAGS = $(INCLUDES) -I$(RUBY_INC) -I$(RUBY_INC_ARCH)
nodist_cqmf2_la_SOURCES = cqmf2.cpp
CLEANFILES = cqmf2.cpp
diff --git a/qpid/cpp/bindings/qpid/Makefile.am b/qpid/cpp/bindings/qpid/Makefile.am
index 31bce5d1d5..ca9eda0c73 100644
--- a/qpid/cpp/bindings/qpid/Makefile.am
+++ b/qpid/cpp/bindings/qpid/Makefile.am
@@ -21,7 +21,7 @@ SUBDIRS = dotnet
if HAVE_SWIG
-EXTRA_DIST = CMakeLists.txt qpid.i
+EXTRA_DIST = qpid.i
if HAVE_RUBY_DEVEL
SUBDIRS += ruby
diff --git a/qpid/cpp/bindings/qpid/dotnet/src/Address.cpp b/qpid/cpp/bindings/qpid/dotnet/src/Address.cpp
index 79a8021d9a..b688d973ed 100644
--- a/qpid/cpp/bindings/qpid/dotnet/src/Address.cpp
+++ b/qpid/cpp/bindings/qpid/dotnet/src/Address.cpp
@@ -141,7 +141,7 @@ namespace Messaging {
}
}
- // Copy constructor look-alike (C#)
+ // copy constructor
Address::Address(const Address ^ address)
{
System::Exception ^ newException = nullptr;
@@ -163,28 +163,6 @@ namespace Messaging {
}
}
- // Copy constructor implicitly dereferenced (C++)
- Address::Address(const Address % address)
- {
- System::Exception ^ newException = nullptr;
-
- try
- {
- addressp = new ::qpid::messaging::Address(
- *(const_cast<Address %>(address).NativeAddress));
- }
- catch (const ::qpid::types::Exception & error)
- {
- String ^ errmsg = gcnew String(error.what());
- newException = gcnew QpidException(errmsg);
- }
-
- if (newException != nullptr)
- {
- throw newException;
- }
- }
-
// unmanaged clone
Address::Address(const ::qpid::messaging::Address & addrp)
{
diff --git a/qpid/cpp/bindings/qpid/dotnet/src/Address.h b/qpid/cpp/bindings/qpid/dotnet/src/Address.h
index 8bbc207d4e..e5a00d8f11 100644
--- a/qpid/cpp/bindings/qpid/dotnet/src/Address.h
+++ b/qpid/cpp/bindings/qpid/dotnet/src/Address.h
@@ -64,7 +64,6 @@ namespace Messaging {
// copy constructor
Address(const Address ^ address);
- Address(const Address % address);
// unmanaged clone
Address(const ::qpid::messaging::Address & addrp);
diff --git a/qpid/cpp/bindings/qpid/dotnet/src/Connection.cpp b/qpid/cpp/bindings/qpid/dotnet/src/Connection.cpp
index 12c0e29f74..69ace7db52 100644
--- a/qpid/cpp/bindings/qpid/dotnet/src/Connection.cpp
+++ b/qpid/cpp/bindings/qpid/dotnet/src/Connection.cpp
@@ -114,7 +114,7 @@ namespace Messaging {
}
- // Copy constructor look-alike (C#)
+ // Copy constructor
Connection::Connection(const Connection ^ connection)
{
System::Exception ^ newException = nullptr;
@@ -136,28 +136,6 @@ namespace Messaging {
}
}
- // Copy constructor implicitly dereferenced (C++)
- Connection::Connection(const Connection % connection)
- {
- System::Exception ^ newException = nullptr;
-
- try
- {
- connectionp = new ::qpid::messaging::Connection(
- *(const_cast<Connection %>(connection).NativeConnection));
- }
- catch (const ::qpid::types::Exception & error)
- {
- String ^ errmsg = gcnew String(error.what());
- newException = gcnew QpidException(errmsg);
- }
-
- if (newException != nullptr)
- {
- throw newException;
- }
- }
-
// Destructor
Connection::~Connection()
diff --git a/qpid/cpp/bindings/qpid/dotnet/src/Connection.h b/qpid/cpp/bindings/qpid/dotnet/src/Connection.h
index 0788f5d225..f9b62d4a08 100644
--- a/qpid/cpp/bindings/qpid/dotnet/src/Connection.h
+++ b/qpid/cpp/bindings/qpid/dotnet/src/Connection.h
@@ -56,7 +56,6 @@ namespace Messaging {
// copy constructor
Connection(const Connection ^ connection);
- Connection(const Connection % connection);
// unmanaged clone
// not defined
diff --git a/qpid/cpp/bindings/qpid/dotnet/src/Duration.h b/qpid/cpp/bindings/qpid/dotnet/src/Duration.h
index d4239fae88..213c338a59 100644
--- a/qpid/cpp/bindings/qpid/dotnet/src/Duration.h
+++ b/qpid/cpp/bindings/qpid/dotnet/src/Duration.h
@@ -81,17 +81,7 @@ namespace Messaging {
Duration ^ result = gcnew Duration(multiplier * dur->Milliseconds);
return result;
}
-
- static bool operator == (Duration ^ a, Duration ^ b)
- {
- return a->Milliseconds == b->Milliseconds;
- }
-
- static bool operator != (Duration ^ a, Duration ^ b)
- {
- return a->Milliseconds != b->Milliseconds;
- }
-};
+ };
public ref class DurationConstants sealed
{
diff --git a/qpid/cpp/bindings/qpid/dotnet/src/FailoverUpdates.h b/qpid/cpp/bindings/qpid/dotnet/src/FailoverUpdates.h
index d82e276fc8..1dd92b8688 100644
--- a/qpid/cpp/bindings/qpid/dotnet/src/FailoverUpdates.h
+++ b/qpid/cpp/bindings/qpid/dotnet/src/FailoverUpdates.h
@@ -54,7 +54,6 @@ namespace Messaging {
// copy constructor
FailoverUpdates(const FailoverUpdates ^ failoverUpdates) {}
- FailoverUpdates(const FailoverUpdates % failoverUpdates) {}
// assignment operator
FailoverUpdates % operator=(const FailoverUpdates % rhs)
diff --git a/qpid/cpp/bindings/qpid/dotnet/src/Message.cpp b/qpid/cpp/bindings/qpid/dotnet/src/Message.cpp
index e5dbf845b3..fe7825134d 100644
--- a/qpid/cpp/bindings/qpid/dotnet/src/Message.cpp
+++ b/qpid/cpp/bindings/qpid/dotnet/src/Message.cpp
@@ -235,7 +235,7 @@ namespace Messaging {
}
}
- // Copy constructor look-alike (C#)
+ // Copy constructor
Message::Message(const Message ^ message)
{
System::Exception ^ newException = nullptr;
@@ -257,29 +257,7 @@ namespace Messaging {
}
}
- // Copy constructor implicitly dereferenced (C++)
- Message::Message(const Message % message)
- {
- System::Exception ^ newException = nullptr;
-
- try
- {
- messagep = new ::qpid::messaging::Message(
- *(const_cast<Message %>(message).NativeMessage));
- }
- catch (const ::qpid::types::Exception & error)
- {
- String ^ errmsg = gcnew String(error.what());
- newException = gcnew QpidException(errmsg);
- }
-
- if (newException != nullptr)
- {
- throw newException;
- }
- }
-
- // Property
+ // Property
void Message::SetProperty(System::String ^ name, System::Object ^ value)
{
System::Exception ^ newException = nullptr;
diff --git a/qpid/cpp/bindings/qpid/dotnet/src/Message.h b/qpid/cpp/bindings/qpid/dotnet/src/Message.h
index ac7f285fe5..b92cc4200b 100644
--- a/qpid/cpp/bindings/qpid/dotnet/src/Message.h
+++ b/qpid/cpp/bindings/qpid/dotnet/src/Message.h
@@ -71,7 +71,6 @@ namespace Messaging {
// Copy constructor
Message(const Message ^ message);
- Message(const Message % message);
// unmanaged clone
Message(const ::qpid::messaging::Message & msgp);
diff --git a/qpid/cpp/bindings/qpid/dotnet/src/Receiver.cpp b/qpid/cpp/bindings/qpid/dotnet/src/Receiver.cpp
index 8aa77effbd..3c0d79b393 100644
--- a/qpid/cpp/bindings/qpid/dotnet/src/Receiver.cpp
+++ b/qpid/cpp/bindings/qpid/dotnet/src/Receiver.cpp
@@ -89,7 +89,7 @@ namespace Messaging {
}
- // Copy constructor look-alike (C#)
+ // Copy constructor
Receiver::Receiver(const Receiver ^ receiver) :
parentSession(receiver->parentSession)
{
@@ -112,29 +112,6 @@ namespace Messaging {
}
}
- // Copy constructor implicitly dereferenced (C++)
- Receiver::Receiver(const Receiver % receiver) :
- parentSession(receiver.parentSession)
- {
- System::Exception ^ newException = nullptr;
-
- try
- {
- receiverp = new ::qpid::messaging::Receiver(
- *(const_cast<Receiver %>(receiver).NativeReceiver));
- }
- catch (const ::qpid::types::Exception & error)
- {
- String ^ errmsg = gcnew String(error.what());
- newException = gcnew QpidException(errmsg);
- }
-
- if (newException != nullptr)
- {
- throw newException;
- }
- }
-
//
// Get(message)
diff --git a/qpid/cpp/bindings/qpid/dotnet/src/Receiver.h b/qpid/cpp/bindings/qpid/dotnet/src/Receiver.h
index 8ddcc9ac01..e9912a61dd 100644
--- a/qpid/cpp/bindings/qpid/dotnet/src/Receiver.h
+++ b/qpid/cpp/bindings/qpid/dotnet/src/Receiver.h
@@ -65,7 +65,6 @@ namespace Messaging {
// copy constructor
Receiver(const Receiver ^ receiver);
- Receiver(const Receiver % receiver);
// unmanaged clone
// undefined
diff --git a/qpid/cpp/bindings/qpid/dotnet/src/Sender.cpp b/qpid/cpp/bindings/qpid/dotnet/src/Sender.cpp
index 3225f1a6e1..584075ef5f 100644
--- a/qpid/cpp/bindings/qpid/dotnet/src/Sender.cpp
+++ b/qpid/cpp/bindings/qpid/dotnet/src/Sender.cpp
@@ -84,7 +84,7 @@ namespace Messaging {
}
- // Copy constructor look-alike (C#)
+ // Copy constructor
Sender::Sender(const Sender ^ sender)
: parentSession(sender->parentSession)
{
@@ -107,29 +107,6 @@ namespace Messaging {
}
}
- // Copy constructor implicitly dereferenced (C++)
- Sender::Sender(const Sender % sender)
- : parentSession(sender.parentSession)
- {
- System::Exception ^ newException = nullptr;
-
- try
- {
- senderp = new ::qpid::messaging::Sender(
- *(const_cast<Sender %>(sender).NativeSender));
- }
- catch (const ::qpid::types::Exception & error)
- {
- String ^ errmsg = gcnew String(error.what());
- newException = gcnew QpidException(errmsg);
- }
-
- if (newException != nullptr)
- {
- throw newException;
- }
- }
-
//
// Send(msg)
diff --git a/qpid/cpp/bindings/qpid/dotnet/src/Sender.h b/qpid/cpp/bindings/qpid/dotnet/src/Sender.h
index 4054e87316..0e90a9f4a4 100644
--- a/qpid/cpp/bindings/qpid/dotnet/src/Sender.h
+++ b/qpid/cpp/bindings/qpid/dotnet/src/Sender.h
@@ -62,7 +62,6 @@ namespace Messaging {
// copy constructor
Sender(const Sender ^ sender);
- Sender(const Sender % sender);
~Sender();
!Sender();
diff --git a/qpid/cpp/bindings/qpid/dotnet/src/Session.cpp b/qpid/cpp/bindings/qpid/dotnet/src/Session.cpp
index 0e918769a3..880331c588 100644
--- a/qpid/cpp/bindings/qpid/dotnet/src/Session.cpp
+++ b/qpid/cpp/bindings/qpid/dotnet/src/Session.cpp
@@ -89,7 +89,7 @@ namespace Messaging {
}
- // Copy constructor look-alike (C#)
+ // Copy constructor
Session::Session(const Session ^ session)
: parentConnectionp(session->parentConnectionp)
{
@@ -113,30 +113,6 @@ namespace Messaging {
}
}
- // Copy constructor implicitly dereferenced (C++)
- Session::Session(const Session % session)
- : parentConnectionp(session.parentConnectionp)
- {
- System::Exception ^ newException = nullptr;
-
- try
- {
- sessionp = new ::qpid::messaging::Session(
- *(const_cast<Session %>(session).NativeSession));
-
- }
- catch (const ::qpid::types::Exception & error)
- {
- String ^ errmsg = gcnew String(error.what());
- newException = gcnew QpidException(errmsg);
- }
-
- if (newException != nullptr)
- {
- throw newException;
- }
- }
-
void Session::Close()
{
@@ -248,31 +224,6 @@ namespace Messaging {
}
}
- void Session::AcknowledgeUpTo(Message ^ message)
- {
- AcknowledgeUpTo(message, false);
- }
-
- void Session::AcknowledgeUpTo(Message ^ message, bool sync)
- {
- System::Exception ^ newException = nullptr;
-
- try
- {
- sessionp->acknowledgeUpTo(*(message->NativeMessage), sync);
- }
- catch (const ::qpid::types::Exception & error)
- {
- String ^ errmsg = gcnew String(error.what());
- newException = gcnew QpidException(errmsg);
- }
-
- if (newException != nullptr)
- {
- throw newException;
- }
- }
-
void Session::Reject(Message ^ message)
{
System::Exception ^ newException = nullptr;
diff --git a/qpid/cpp/bindings/qpid/dotnet/src/Session.h b/qpid/cpp/bindings/qpid/dotnet/src/Session.h
index 4b98a37f18..7eaad8a0a5 100644
--- a/qpid/cpp/bindings/qpid/dotnet/src/Session.h
+++ b/qpid/cpp/bindings/qpid/dotnet/src/Session.h
@@ -69,7 +69,6 @@ namespace Messaging {
// copy constructor
Session(const Session ^ session);
- Session(const Session % session);
~Session();
!Session();
@@ -104,8 +103,6 @@ namespace Messaging {
void Acknowledge(bool sync);
void Acknowledge(Message ^ message);
void Acknowledge(Message ^ message, bool sync);
- void AcknowledgeUpTo(Message ^ message);
- void AcknowledgeUpTo(Message ^ message, bool sync);
void Reject(Message ^);
void Release(Message ^);
void Sync();
diff --git a/qpid/cpp/bindings/qpid/perl/CMakeLists.txt b/qpid/cpp/bindings/qpid/perl/CMakeLists.txt
index 6edaf284b1..92ec5340e0 100644
--- a/qpid/cpp/bindings/qpid/perl/CMakeLists.txt
+++ b/qpid/cpp/bindings/qpid/perl/CMakeLists.txt
@@ -26,7 +26,7 @@ set_source_files_properties(${CMAKE_CURRENT_SOURCE_DIR}/perl.i PROPERTIES SWIG_F
swig_add_module(cqpid_perl perl ${CMAKE_CURRENT_SOURCE_DIR}/perl.i)
swig_link_libraries(cqpid_perl qpidmessaging qpidtypes qmf2 ${PERL_LIBRARY})
-set_source_files_properties(${swig_generated_file_fullname} PROPERTIES COMPILE_FLAGS "-fno-strict-aliasing -I${PERL_INCLUDE_PATH} -I${qpid-cpp_SOURCE_DIR}/include")
+set_source_files_properties(${swig_generated_file_fullname} PROPERTIES COMPILE_FLAGS "-I${PERL_INCLUDE_PATH} -I${qpid-cpp_SOURCE_DIR}/include")
##----------------------------------
## Install the complete Perl binding
diff --git a/qpid/cpp/bindings/qpid/perl/Makefile.am b/qpid/cpp/bindings/qpid/perl/Makefile.am
index da082896e8..13ab66f032 100644
--- a/qpid/cpp/bindings/qpid/perl/Makefile.am
+++ b/qpid/cpp/bindings/qpid/perl/Makefile.am
@@ -21,7 +21,7 @@ if HAVE_PERL_DEVEL
INCLUDES = -I$(top_srcdir)/include -I$(top_builddir)/include -I$(top_srcdir)/src -I$(top_builddir)/src -I$(PERL_INC)
-EXTRA_DIST = CMakeLists.txt perl.i
+EXTRA_DIST = perl.i
BUILT_SOURCES = cqpid_perl.cpp
SWIG_FLAGS = -w362,401
@@ -34,7 +34,7 @@ cqpid_perl_PERL = cqpid_perl.pm
libcqpid_perl_la_LDFLAGS = -avoid-version -shared
libcqpid_perl_la_LIBADD = -L$(top_builddir)/src/.libs -lqpidmessaging -lqpidtypes \
$(top_builddir)/src/libqpidmessaging.la $(top_builddir)/src/libqpidtypes.la
-libcqpid_perl_la_CXXFLAGS = $(INCLUDES) -fno-strict-aliasing
+libcqpid_perl_la_CXXFLAGS = $(INCLUDES)
nodist_libcqpid_perl_la_SOURCES = cqpid_perl.cpp
CLEANFILES = cqpid_perl.cpp cqpid_perl.pm
diff --git a/qpid/cpp/bindings/qpid/python/Makefile.am b/qpid/cpp/bindings/qpid/python/Makefile.am
index dd25f34829..7fa4106be0 100644
--- a/qpid/cpp/bindings/qpid/python/Makefile.am
+++ b/qpid/cpp/bindings/qpid/python/Makefile.am
@@ -25,17 +25,17 @@ generated_file_list = \
cqpid.cpp \
cqpid.py
-EXTRA_DIST = CMakeLists.txt python.i
+EXTRA_DIST = python.i
BUILT_SOURCES = $(generated_file_list)
SWIG_FLAGS = -w362,401
$(generated_file_list): $(srcdir)/python.i $(srcdir)/../qpid.i $(srcdir)/../../swig_python_typemaps.i
- $(SWIG) -c++ -python $(SWIG_FLAGS) $(INCLUDES) $(QPID_CXXFLAGS) -I$(top_srcdir)/src/qmf -I/usr/include -o cqpid.cpp $(srcdir)/python.i
+ swig -c++ -python $(SWIG_FLAGS) $(INCLUDES) $(QPID_CXXFLAGS) -I$(top_srcdir)/src/qmf -I/usr/include -o cqpid.cpp $(srcdir)/python.i
pylibdir = $(PYTHON_LIB)
lib_LTLIBRARIES = _cqpid.la
-cqpiddir = $(pyexecdir)
+cqpiddir = $(pythondir)
cqpid_PYTHON = cqpid.py
_cqpid_la_LDFLAGS = -avoid-version -module -shared
diff --git a/qpid/cpp/bindings/qpid/python/python.i b/qpid/cpp/bindings/qpid/python/python.i
index 2eeaf4989e..bf61cb10b7 100644
--- a/qpid/cpp/bindings/qpid/python/python.i
+++ b/qpid/cpp/bindings/qpid/python/python.i
@@ -21,292 +21,21 @@
%include "std_string.i"
%include "../../swig_python_typemaps.i"
-/* Needed for get/setPriority methods. Surprising SWIG 1.3.40 doesn't
- * convert uint8_t by default. */
-%apply unsigned char { uint8_t };
-
-%{
-static PyObject* pNoMessageAvailable;
-%}
-
-%init %{
- pNoMessageAvailable = PyErr_NewException(
- "_cqpid.NoMessageAvailable", NULL, NULL);
- Py_INCREF(pNoMessageAvailable);
- PyModule_AddObject(m, "NoMessageAvailable", pNoMessageAvailable);
-%}
-
-%pythoncode %{
- Empty = _cqpid.NoMessageAvailable
-%}
-
/* Define the general-purpose exception handling */
%exception {
- PyObject * pExceptionType = NULL;
std::string error;
Py_BEGIN_ALLOW_THREADS;
try {
$action
- } catch (qpid::messaging::NoMessageAvailable & ex) {
- pExceptionType = pNoMessageAvailable;
- error = ex.what();
} catch (qpid::types::Exception& ex) {
- pExceptionType = PyExc_RuntimeError;
error = ex.what();
}
Py_END_ALLOW_THREADS;
if (!error.empty()) {
- PyErr_SetString(pExceptionType, error.c_str());
+ PyErr_SetString(PyExc_RuntimeError, error.c_str());
return NULL;
}
}
-/* This only renames the non-const version (I believe). Then again, I
- * don't even know why there is a non-const version of the method. */
-%rename(opened) qpid::messaging::Connection::isOpen();
-%rename(receiver) qpid::messaging::Session::createReceiver;
-%rename(sender) qpid::messaging::Session::createSender;
-%rename(_acknowledge_all) qpid::messaging::Session::acknowledge(bool);
-%rename(_acknowledge_msg) qpid::messaging::Session::acknowledge(
- Message &, bool);
-
-%rename(_fetch) qpid::messaging::Receiver::fetch;
-%rename(unsettled) qpid::messaging::Receiver::getUnsettled;
-%rename(available) qpid::messaging::Receiver::getAvailable;
-
-%rename(unsettled) qpid::messaging::Sender::getUnsettled;
-%rename(available) qpid::messaging::Sender::getAvailable;
-%rename(_send) qpid::messaging::Sender::send;
-
-%rename(_getReplyTo) qpid::messaging::Message::getReplyTo;
-%rename(_setReplyTo) qpid::messaging::Message::setReplyTo;
-%rename(_getTtl) qpid::messaging::Message::getTtl;
-%rename(_setTtl) qpid::messaging::Message::setTtl;
-
-
%include "../qpid.i"
-%extend qpid::messaging::Connection {
- %pythoncode %{
- # Handle the different options by converting underscores to hyphens.
- # Also, the sasl_mechanisms option in Python has no direct
- # equivalent in C++, so we will translate them to sasl_mechanism
- # when possible.
- def __init__(self, url=None, **options):
- args = [url] if url else []
- if options :
- if "sasl_mechanisms" in options :
- if ' ' in options.get("sasl_mechanisms",'') :
- raise Exception(
- "C++ Connection objects are unable to handle "
- "multiple sasl-mechanisms")
- options["sasl_mechanism"] = options.pop("sasl_mechanisms")
- args.append(options)
- this = _cqpid.new_Connection(*args)
- try: self.this.append(this)
- except: self.this = this
- %}
-
- /* Return a pre-existing session with the given name, if one
- * exists, otherwise return a new one. (Note that if a
- * pre-existing session exists, the transactional argument is
- * ignored, and the returned session might not satisfy the desired
- * setting. */
- qpid::messaging::Session _session(const std::string & name,
- bool transactional) {
- if (!name.empty()) {
- try {
- return self->getSession(name);
- }
- catch (const qpid::messaging::KeyError &) {
- }
- }
- if (transactional) {
- return self->createTransactionalSession(name);
- }
- else {
- return self->createSession(name);
- }
- }
-
- %pythoncode %{
- def session(self, name=None, transactional=False) :
- if name is None :
- name = ''
- return self._session(name, transactional)
- %}
-
- %pythoncode %{
- @staticmethod
- def establish(url=None, **options) :
- conn = Connection(url, **options)
- conn.open()
- return conn
- %}
-}
-
-%extend qpid::messaging::Session {
- %pythoncode %{
- def acknowledge(self, message=None, disposition=None, sync=True) :
- if disposition :
- raise Exception("SWIG does not support dispositions yet. Use "
- "Session.reject and Session.release instead")
- if message :
- self._acknowledge_msg(message, sync)
- else :
- self._acknowledge_all(sync)
- %}
-}
-
-
-%extend qpid::messaging::Receiver {
- %pythoncode %{
- __swig_getmethods__["capacity"] = getCapacity
- __swig_setmethods__["capacity"] = setCapacity
- if _newclass: capacity = _swig_property(getCapacity, setCapacity)
- %}
-
- %pythoncode %{
- def fetch(self, timeout=None) :
- if timeout is None :
- return self._fetch()
- else :
- # Python API uses timeouts in seconds,
- # but C++ API uses milliseconds
- return self._fetch(Duration(int(1000*timeout)))
- %}
-}
-
-%extend qpid::messaging::Sender {
- %pythoncode %{
- def send(self, object, sync=True) :
- if isinstance(object, Message):
- message = object
- else:
- message = Message(object)
- return self._send(message, sync)
-
- __swig_getmethods__["capacity"] = getCapacity
- __swig_setmethods__["capacity"] = setCapacity
- if _newclass: capacity = _swig_property(getCapacity, setCapacity)
- %}
-}
-
-
-%extend qpid::messaging::Message {
- %pythoncode %{
- # UNSPECIFIED was module level before, but I do not
- # know how to insert python code at the top of the module.
- # (A bare "%pythoncode" inserts at the end.
- UNSPECIFIED=object()
- def __init__(self, content=None, content_type=UNSPECIFIED, id=None,
- subject=None, user_id=None, reply_to=None,
- correlation_id=None, durable=None, priority=None,
- ttl=None, properties=None):
- this = _cqpid.new_Message(content if content else '')
- try: self.this.append(this)
- except: self.this = this
- if content_type != UNSPECIFIED :
- self.content_type = content_type
- if id is not None :
- self.id = id
- if subject is not None :
- self.subject = subject
- if user_id is not None :
- self.user_id = user_id
- if reply_to is not None :
- self.reply_to = reply_to
- if correlation_id is not None :
- self.correlation_id = correlation_id
- if durable is not None :
- self.durable = durable
- if priority is not None :
- self.priority = priority
- if ttl is not None :
- self.ttl = ttl
- if properties is not None :
- # Can't set properties via (inst).getProperties, because
- # the typemaps make a copy of the underlying properties.
- # Instead, set via setProperty for the time-being
- for k, v in properties.iteritems() :
- self.setProperty(k, v)
-
- __swig_getmethods__["content"] = getContent
- __swig_setmethods__["content"] = setContent
- if _newclass: content = _swig_property(getContent, setContent)
-
- __swig_getmethods__["content_type"] = getContentType
- __swig_setmethods__["content_type"] = setContentType
- if _newclass: content_type = _swig_property(getContentType,
- setContentType)
-
- __swig_getmethods__["id"] = getMessageId
- __swig_setmethods__["id"] = setMessageId
- if _newclass: id = _swig_property(getMessageId, setMessageId)
-
- __swig_getmethods__["subject"] = getSubject
- __swig_setmethods__["subject"] = setSubject
- if _newclass: subject = _swig_property(getSubject, setSubject)
-
- __swig_getmethods__["priority"] = getPriority
- __swig_setmethods__["priority"] = setPriority
- if _newclass: priority = _swig_property(getPriority, setPriority)
-
- def getTtl(self) :
- return self._getTtl().getMilliseconds()/1000.0
- def setTtl(self, duration) :
- self._setTtl(Duration(int(1000*duration)))
- __swig_getmethods__["ttl"] = getTtl
- __swig_setmethods__["ttl"] = setTtl
- if _newclass: ttl = _swig_property(getTtl, setTtl)
-
- __swig_getmethods__["user_id"] = getUserId
- __swig_setmethods__["user_id"] = setUserId
- if _newclass: user_id = _swig_property(getUserId, setUserId)
-
- __swig_getmethods__["correlation_id"] = getCorrelationId
- __swig_setmethods__["correlation_id"] = setCorrelationId
- if _newclass: correlation_id = _swig_property(getCorrelationId,
- setCorrelationId)
-
- __swig_getmethods__["redelivered"] = getRedelivered
- __swig_setmethods__["redelivered"] = setRedelivered
- if _newclass: redelivered = _swig_property(getRedelivered,
- setRedelivered)
-
- __swig_getmethods__["durable"] = getDurable
- __swig_setmethods__["durable"] = setDurable
- if _newclass: durable = _swig_property(getDurable, setDurable)
-
- __swig_getmethods__["properties"] = getProperties
- if _newclass: properties = _swig_property(getProperties)
-
- def getReplyTo(self) :
- return self._getReplyTo().str()
- def setReplyTo(self, address_str) :
- self._setReplyTo(Address(address_str))
- __swig_getmethods__["reply_to"] = getReplyTo
- __swig_setmethods__["reply_to"] = setReplyTo
- if _newclass: reply_to = _swig_property(getReplyTo, setReplyTo)
-
- def __repr__(self):
- args = []
- for name in ["id", "subject", "user_id", "reply_to",
- "correlation_id", "priority", "ttl",
- "durable", "redelivered", "properties",
- "content_type"] :
- value = getattr(self, name)
- if value : args.append("%s=%r" % (name, value))
- if self.content is not None:
- if args:
- args.append("content=%r" % self.content)
- else:
- args.append(repr(self.content))
- return "Message(%s)" % ", ".join(args)
- %}
-}
-
-%pythoncode %{
-# Bring into module scope
-UNSPECIFIED = Message.UNSPECIFIED
-%}
diff --git a/qpid/cpp/bindings/qpid/qpid.i b/qpid/cpp/bindings/qpid/qpid.i
index 352bafa3c8..01f9bff64d 100644
--- a/qpid/cpp/bindings/qpid/qpid.i
+++ b/qpid/cpp/bindings/qpid/qpid.i
@@ -49,7 +49,6 @@ qpid::types::Variant::List& decodeList(const qpid::messaging::Message& msg) {
%}
-%include <qpid/ImportExport.h>
%include <qpid/messaging/ImportExport.h>
%include <qpid/messaging/Address.h>
%include <qpid/messaging/Duration.h>
diff --git a/qpid/cpp/bindings/qpid/ruby/CMakeLists.txt b/qpid/cpp/bindings/qpid/ruby/CMakeLists.txt
index 96c00154ba..d403f3fdee 100644
--- a/qpid/cpp/bindings/qpid/ruby/CMakeLists.txt
+++ b/qpid/cpp/bindings/qpid/ruby/CMakeLists.txt
@@ -26,7 +26,7 @@ set_source_files_properties(${CMAKE_CURRENT_SOURCE_DIR}/ruby.i PROPERTIES SWIG_F
swig_add_module(cqpid ruby ${CMAKE_CURRENT_SOURCE_DIR}/ruby.i)
swig_link_libraries(cqpid qpidmessaging qpidtypes qmf2 ${RUBY_LIBRARY})
-set_source_files_properties(${swig_generated_file_fullname} PROPERTIES COMPILE_FLAGS "-fno-strict-aliasing -I${RUBY_INCLUDE_DIR} -I${qpid-cpp_SOURCE_DIR}/include")
+set_source_files_properties(${swig_generated_file_fullname} PROPERTIES COMPILE_FLAGS "-I${RUBY_INCLUDE_DIR} -I${qpid-cpp_SOURCE_DIR}/include")
##----------------------------------
## Install the complete Ruby binding
diff --git a/qpid/cpp/bindings/qpid/ruby/Makefile.am b/qpid/cpp/bindings/qpid/ruby/Makefile.am
index a2a5dd76bd..67a3615362 100644
--- a/qpid/cpp/bindings/qpid/ruby/Makefile.am
+++ b/qpid/cpp/bindings/qpid/ruby/Makefile.am
@@ -21,7 +21,7 @@ if HAVE_RUBY_DEVEL
INCLUDES = -I$(top_srcdir)/include -I$(top_builddir)/include -I$(top_srcdir)/src -I$(top_builddir)/src
-EXTRA_DIST = CMakeLists.txt ruby.i
+EXTRA_DIST = ruby.i
BUILT_SOURCES = cqpid.cpp
SWIG_FLAGS = -w362,401
@@ -33,10 +33,10 @@ cqpid.cpp: $(srcdir)/ruby.i $(srcdir)/../qpid.i $(srcdir)/../../swig_ruby_typema
rubylibarchdir = $(RUBY_LIB_ARCH)
rubylibarch_LTLIBRARIES = cqpid.la
-cqpid_la_LDFLAGS = -avoid-version -module -shared -shrext ".$(RUBY_DLEXT)"
+cqpid_la_LDFLAGS = -avoid-version -module -shrext ".$(RUBY_DLEXT)"
cqpid_la_LIBADD = $(RUBY_LIBS) -L$(top_builddir)/src/.libs -lqpidmessaging -lqpidtypes \
$(top_builddir)/src/libqpidmessaging.la $(top_builddir)/src/libqpidtypes.la
-cqpid_la_CXXFLAGS = $(INCLUDES) -I$(RUBY_INC) -I$(RUBY_INC_ARCH) -fno-strict-aliasing
+cqpid_la_CXXFLAGS = $(INCLUDES) -I$(RUBY_INC) -I$(RUBY_INC_ARCH)
nodist_cqpid_la_SOURCES = cqpid.cpp
CLEANFILES = cqpid.cpp
diff --git a/qpid/cpp/bindings/qpid/ruby/README.rdoc b/qpid/cpp/bindings/qpid/ruby/README.rdoc
deleted file mode 100644
index 960fdf6107..0000000000
--- a/qpid/cpp/bindings/qpid/ruby/README.rdoc
+++ /dev/null
@@ -1,27 +0,0 @@
-= Qpid - Open Source AMQP Messaging
-
-Qpid is an cross-platform enterprise messaging system.
-
-Version :: 0.10.0.alpha.0
-
-= Links
-
-Documents :: http://qpid.apache.org/
-
-= Installation
-
-You can install Qpid with the following command.
-
- $ gem install qpid
-
-== Examples
-
-Take a look at the integration tests for examples on how to leverage
-the messaging capabilities of Qpid in your Ruby applications.
-
-== License
-
-Licensed to the Apache Software Foundation (ASF) under one or more
-contributor licensing agreements.
-
-
diff --git a/qpid/cpp/bindings/qpid/ruby/Rakefile b/qpid/cpp/bindings/qpid/ruby/Rakefile
deleted file mode 100644
index ef2b158eba..0000000000
--- a/qpid/cpp/bindings/qpid/ruby/Rakefile
+++ /dev/null
@@ -1,74 +0,0 @@
-# Rakefile for Qpid -*- ruby -*-
-#
-# 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.
-#
-
-task :noop
-
-require 'rubygems'
-require 'rake/clean'
-require 'rake/rdoctask'
-require 'rake/testtask'
-
-CLOBBER.include('pkg')
-
-load './lib/qpid/version.rb'
-
-desc 'Default: run all tests.'
-task :default => :'test:all'
-
-#---------------
-# Testing tasks.
-#---------------
-
-desc 'Run all tests (alias for test:all).'
-task :test => :'test:all'
-
-namespace :test do
- desc "Run all tests (default)."
- task :all => [:units, :integrations]
-
- desc "Run unit tests."
- Rake::TestTask.new(:units) do |t|
- t.libs << '.'
- t.pattern = 'test/test*.rb'
- t.verbose = true
- end
-
- desc "Run integration tests."
- Rake::TestTask.new(:integrations) do |t|
- t.libs << '.'
- t.pattern = 'test/integration/*.rb'
- t.verbose = true
- end
-
-end
-
-#---------------------
-# Documentation tasks.
-#---------------------
-
-Rake::RDocTask.new(
- :rdoc => 'rdoc',
- :clobber_rdoc => 'rdoc:clean',
- :rerdoc => 'rdoc:force'
- ) do |rd|
- rd.main = 'README.rdoc'
- rd.options << '--all'
- rd.rdoc_files.include('README.rdoc', 'lib/**/*.rb')
-end
diff --git a/qpid/cpp/bindings/qpid/ruby/lib/qpid.rb b/qpid/cpp/bindings/qpid/ruby/lib/qpid.rb
deleted file mode 100644
index 1f00c136c1..0000000000
--- a/qpid/cpp/bindings/qpid/ruby/lib/qpid.rb
+++ /dev/null
@@ -1,29 +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.
-#
-
-require 'qpid/errors'
-require 'qpid/duration'
-require 'qpid/address'
-require 'qpid/encoding'
-require 'qpid/message'
-require 'qpid/sender'
-require 'qpid/receiver'
-require 'qpid/session'
-require 'qpid/connection'
-
diff --git a/qpid/cpp/bindings/qpid/ruby/lib/qpid/address.rb b/qpid/cpp/bindings/qpid/ruby/lib/qpid/address.rb
deleted file mode 100644
index 73b61bb1c7..0000000000
--- a/qpid/cpp/bindings/qpid/ruby/lib/qpid/address.rb
+++ /dev/null
@@ -1,125 +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.
-#
-
-require 'cqpid'
-
-module Qpid
-
- module Messaging
-
- # Address represents an address to which messages can be sent or from
- # which they can be received.
- #
- # An Address can be described using the following pattern:
- #
- # <address> [ / <subject> ] ; [ { <key> : <value> , ... } ]
- #
- # where *address* is a simple name and *subject* is a subject or subject
- # pattern.
- #
- # The options, enclosed in curly braces, are key:value pairs delimited by
- # a comma. The values can be nested maps also enclosed in curly braces.
- # Or they can be lists of values, where they are contained within square
- # brackets but still comma delimited, such as:
- #
- # [value1,value2,value3]
- #
- # The following are the list of supported options:
- #
- # create:: Indicates if the address should be created; values are *always*,
- # *never*, *sender* or *reciever*.
- #
- # assert:: Indicates whether or not to assert any specified node properties;
- # values are *always*, *never*, *sender* or *receiver*.
- #
- # delete:: Indicates whether or not to delete the addressed node when a
- # sender or receiver is cancelled; values are *always*, *never*,
- # *sender* or *receiver*.
- #
- # node:: A nested map describing properties for the addressed node.
- # Properties are *type* (*topic* or *queue*), *durable* (a boolean),
- # *x-declare* (a nested map of amqp 0.10-specific options) and
- # *x-bindings*. (nested list which specifies a queue, exchange or
- # a binding key and arguments.
- #
- # link:: A nested map through which properties of the link can be specified;
- # properties are *durable*, *reliability*, *x-declare*, *x-subscribe*
- # and *x-bindings*.
- #
- # mode:: (*For receivers only*) indicates whether the receiver should consume
- # or browse messages; values are *consume* (the default) and *browse*.
- class Address
-
- def initialize(name, subject, options = {}, _type = "", address_impl = nil)
- @address_impl = address_impl || Cqpid::Address.new(name, subject, convert_options(options), _type)
- end
-
- def address_impl # :nodoc:
- @address_impl
- end
-
- # Returns the name.
- def name; @address_impl.getName; end
-
- # Sets the name.
- def name=(name); @address_impl.setName name; end
-
- # Returns the subject.
- def subject; @address_impl.getSubject; end
-
- # Sets the subject.
- def subject=(subject); @address_impl.setSubject(subject); end
-
- # Returns the type.
- #---
- # We cannot use "type" since that clashes with the Ruby object.type
- # identifier.
- def _type; @address_impl.getType; end
-
- # Sets the type.
- #
- # The type of the address determines how Sender and Receiver objects
- # are constructed for it. If no type is specified then it will be
- # determined by querying the broker.
- def _type=(_type); @address_impl.setType(_type); end
-
- # Returns the options.
- def options; @address_impl.getOptions; end
-
- # Sets the options for the address.
- # Any symbols are converted to strings.
- def options=(options); @address_impl.setOptions(convert_options(options)); end
-
- def to_s; @address_impl.str; end
-
- private
-
- def convert_options(options)
- result = {}
- options.each_pair {|key, value| result[key.to_s] = value.to_s}
-
- return result
- end
-
- end
-
- end
-
-end
-
diff --git a/qpid/cpp/bindings/qpid/ruby/lib/qpid/connection.rb b/qpid/cpp/bindings/qpid/ruby/lib/qpid/connection.rb
deleted file mode 100644
index 5c56c1f5d0..0000000000
--- a/qpid/cpp/bindings/qpid/ruby/lib/qpid/connection.rb
+++ /dev/null
@@ -1,134 +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.
-#
-
-require 'cqpid'
-
-module Qpid
-
- module Messaging
-
- # Connection allows for establishing connections to a remote endpoint.
- class Connection
-
- # The following general options are supported (as strings or symbols):
- #
- # username::
- # password::
- # heartbeat::
- # tcp_nodelay::
- # sasl_mechanism::
- # sasl_service::
- # sasl_min_ssf::
- # sasl_max_ssf::
- # transport::
- #
- # The following options specifically control reconnection behavior:
- #
- # reconnect:: *true* or *false*; indicates whether to attempt reconnections
- # reconnect_timeout:: the number of seconds to attempt reconnecting
- # reconnect_limit:: the number of retries before reporting failure
- # reconnect_interval_min:: initial delay, in seconds, before attempting a reconnecting
- # reconnect_interval_max:: number of seconds to wait before additional reconnect attempts
- # reconnect_interval:: shorthand for setting box min and max values
- # reconnect_urls:: a list of alternate URLs to use for reconnection attempts
- def initialize(url, options = {}, connection_impl = nil)
- @url = url
- @connection_impl = connection_impl
- @options = options
- end
-
- def connection_impl # :nodoc:
- @connection_impl
- end
-
- # Opens the connection.
- def open
- @connection_impl = Cqpid::Connection.new(@url, convert_options)
- @connection_impl.open
- end
-
- # Reports whether the connection is open.
- def open?; false || (@connection_impl.isOpen if @connection_impl); end
-
- # Closes the connection.
- def close; @connection_impl.close if open?; end
-
- # Creates a new session.
- #
- # If :transactional => true then a transactional session is created.
- # Otherwise a standard session is created.
- def create_session(args = {})
- name = args[:name] || ""
- if open?
- if args[:transactional]
- session = @connection_impl.createTransactionalSession name
- else
- session = @connection_impl.createSession name
- end
- return Session.new(session)
- else
- raise RuntimeError.new "No connection available."
- end
- end
-
- # Returns a session for the specified session name.
- def session name
- session_impl = @connection_impl.getSession name
- Qpid::Messaging::Session.new session_impl if session_impl
- end
-
- # Returns the username used to authenticate with the connection.
- def authenticated_username; @connection_impl.getAuthenticatedUsername if open?; end
-
- # inherited from Handle
-
- # Returns whether the underlying handle is valid; i.e., not null.
- def valid?
- @connection_impl.isValid
- end
-
- # Returns whether the underlying handle is null.
- def null?
- @connection_impl.isNull
- end
-
- # Swaps the underlying connection handle.
- def swap connection
- @connection_impl.swap connection.connection_impl
- end
-
- private
-
- def convert_options
- result = {}
- # map only those options defined in the C++ layer
- # TODO when new options are added, this needs to be updated.
- unless @options.nil? || @options.empty?
- @options.each_pair {|key, value| result[key.to_s] = value.to_s}
- end
-
- return result
- end
-
- end
-
- end
-
-end
-
diff --git a/qpid/cpp/bindings/qpid/ruby/lib/qpid/duration.rb b/qpid/cpp/bindings/qpid/ruby/lib/qpid/duration.rb
deleted file mode 100644
index c1f44e9281..0000000000
--- a/qpid/cpp/bindings/qpid/ruby/lib/qpid/duration.rb
+++ /dev/null
@@ -1,63 +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.
-#
-
-require 'cqpid'
-
-module Qpid
-
- module Messaging
-
- # A Duration represents a period of time in milliseconds
- #
- # It defines the following named values as symbols:
- #
- # :FOREVER :: the maximum integer value for the platform
- # :IMMEDIATE :: an alias for 0
- # :SECOND :: 1,000ms
- # :MINUTE :: 60,000ms
- class Duration
-
- def initialize duration # :nodoc:
- @duration_impl = Cqpid::Duration.new duration
- end
-
- def duration_impl # :nodoc:
- @duration_impl
- end
-
- def self.add_item(key, value) # :nodoc:
- @hash ||= {}
- @hash[key] = Duration.new value
- end
-
- def self.const_missing(key) # :nodoc:
- @hash[key]
- end
-
- self.add_item :FOREVER, Cqpid::Duration.FOREVER.getMilliseconds
- self.add_item :IMMEDIATE, Cqpid::Duration.IMMEDIATE.getMilliseconds
- self.add_item :SECOND, Cqpid::Duration.SECOND.getMilliseconds
- self.add_item :MINUTE, Cqpid::Duration.MINUTE.getMilliseconds
-
- end
-
- end
-
-end
-
diff --git a/qpid/cpp/bindings/qpid/ruby/lib/qpid/encoding.rb b/qpid/cpp/bindings/qpid/ruby/lib/qpid/encoding.rb
deleted file mode 100644
index c8b843b597..0000000000
--- a/qpid/cpp/bindings/qpid/ruby/lib/qpid/encoding.rb
+++ /dev/null
@@ -1,56 +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.
-#
-
-require 'cqpid'
-
-module Qpid
-
- module Messaging
-
- # Encodes the supplied content into the given message.
- def self.encode content, message, encoding = nil
- prepared = content
- case content
- when Hash
- prepared = {}
- content.each_pair do |key,value|
- prepared[key.to_s] = value.to_s
- end
- Cqpid::encode prepared, message.message_impl
- when Array
- prepared = []
- content.each {|value| prepared << value.to_s}
- Cqpid::encode prepared, message.message_impl
- end
- end
-
- # Decodes and returns the message's content.
- def self.decode(message, content_type = nil)
- content_type = message.content_type unless content_type
-
- case content_type
- when "amqp/map": Cqpid.decodeMap message.message_impl
- when "amqp/list": Cqpid.decodeList message.message_impl
- end
- end
-
- end
-
-end
-
diff --git a/qpid/cpp/bindings/qpid/ruby/lib/qpid/errors.rb b/qpid/cpp/bindings/qpid/ruby/lib/qpid/errors.rb
deleted file mode 100644
index 7a16d08d84..0000000000
--- a/qpid/cpp/bindings/qpid/ruby/lib/qpid/errors.rb
+++ /dev/null
@@ -1,30 +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.
-#
-
-module Qpid
-
- module Messaging
-
- class KeyError < RuntimeError
- end
-
- end
-
-end
-
diff --git a/qpid/cpp/bindings/qpid/ruby/lib/qpid/message.rb b/qpid/cpp/bindings/qpid/ruby/lib/qpid/message.rb
deleted file mode 100644
index 652b9fe564..0000000000
--- a/qpid/cpp/bindings/qpid/ruby/lib/qpid/message.rb
+++ /dev/null
@@ -1,129 +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.
-#
-
-require 'cqpid'
-
-module Qpid
-
- module Messaging
-
- # Message represents a message.
- class Message
-
- def initialize(args = {}, message_impl = nil)
- @message_impl = message_impl
- @message_impl = Cqpid::Message.new if @message_impl.nil?
- @message_impl.setContent args[:content].to_s if args[:content]
- end
-
- def message_impl # :nodoc:
- @message_impl
- end
-
- # Assigns the reply to address.
- # The address must be an instance of Address.
- def reply_to=(address); @message_impl.setReplyTo address.address_impl; end
-
- # Returns the reply to address for the message as an instance of +Address+.
- def reply_to
- address_impl = @message_impl.getReplyTo
- # only return an address if a reply to was specified
- Qpid::Messaging::Address.new(nil, nil, nil, nil, address_impl) if address_impl
- end
-
- # Sets the subject.
- def subject=(subject); @message_impl.setSubject subject; end
-
- # Returns the subject.
- def subject; @message_impl.getSubject; end
-
- # Sets the content type.
- def content_type=(content_type); @message_impl.setContentType content_type; end
-
- # Returns the content type.
- def content_type; @message_impl.getContentType; end
-
- # Sets the message id.
- def message_id=(message_id); @message_impl.setMessageId message_id.to_s; end
-
- # Returns the message id.
- def message_id; @message_impl.getMessageId; end
-
- # Sets the user id.
- def user_id=(user_id); @message_impl.setUserId user_id; end
-
- # Returns the user id.
- def user_id; @message_impl.getUserId; end
-
- # Sets the correlation id.
- def correlation_id=(correlation_id); @message_impl.setCorrelationId correlation_id; end
-
- # Returns the correlation id.
- def correlation_id; @message_impl.getCorrelationId; end
-
- # Sets the priority.
- def priority=(priority); @message_impl.setPriority priority; end
-
- # Returns the priority.
- def priority; @message_impl.getPriority; end
-
- # Sets the time-to-live in milliseconds.
- def ttl=(duration); @message_impl.setTtl duration; end
-
- # Returns the time-to-live in milliseconds.
- def ttl; @message_impl.getTtl; end
-
- # Sets the durability.
- def durable=(durable); @message_impl.setDurable durable; end
-
- # Returns the durability.
- def durable; @message_impl.getDurable; end
-
- # Allows marking the message as redelivered.
- def redelivered=(redelivered); @message_impl.setRedelivered redelivered; end
-
- # Returns if the message was redelivered.
- def redelivered; @message_impl.getRedelivered; end
-
- # Returns all named properties.
- # *NOTE:* It is recommended to use the +foo[key]+ method for
- # retrieving properties.
- def properties; @message_impl.getProperties; end
-
- # Returns the value for the named property.
- def [](key); self.properties[key.to_s]; end
-
- # Assigns a value to the named property.
- def []=(key, value); @message_impl.setProperty(key.to_s, value.to_s); end
-
- # Sets the content.
- def content=(content); @message_impl.setContent content.to_s; end
-
- # Returns the content.
- def content; @message_impl.getContent; end
-
- # Returns the content's size.
- def content_size; @message_impl.getContentSize; end
-
- end
-
- end
-
-end
-
diff --git a/qpid/cpp/bindings/qpid/ruby/lib/qpid/receiver.rb b/qpid/cpp/bindings/qpid/ruby/lib/qpid/receiver.rb
deleted file mode 100644
index d498aa922b..0000000000
--- a/qpid/cpp/bindings/qpid/ruby/lib/qpid/receiver.rb
+++ /dev/null
@@ -1,102 +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.
-#
-
-require 'cqpid'
-
-require 'qpid/duration'
-
-module Qpid
-
- module Messaging
-
- # Receiver defines a type for receiving messages.
- class Receiver
-
- def initialize(receiver_impl) # :nodoc:
- @receiver_impl = receiver_impl
- end
-
- def receiver_impl # :nodoc:
- @receiver_impl
- end
-
- # Retrieves a message from the receiver's local queue, or waits
- # for up to the duration specified for one to become available.
- def get(duration = Qpid::Messaging::Duration::FOREVER)
- message_impl = @receiver_impl.get duration.duration_impl
- create_message_wrapper message_impl unless message_impl.nil?
- end
-
- # Retrieves a message from the receiver's subscription, or waits
- # for up to the duration specified for one to become available.
- def fetch(duration = Qpid::Messaging::Duration::FOREVER)
- message_impl = @receiver_impl.fetch duration.duration_impl
- create_message_wrapper message_impl unless message_impl.nil?
- end
-
- # Sets the capacity.
- #
- # The capacity for a receiver determines the number of messages that
- # can be held in the receiver before being fetched.
- def capacity=(capacity); @receiver_impl.setCapacity capacity; end
-
- # Returns the capacity.
- def capacity; @receiver_impl.getCapacity; end
-
- # Returns the number of available messages waiting to be fetched.
- def available; @receiver_impl.getAvailable; end
-
- # Returns the number of messages that have been received and acknowledged
- # but whose acknowledgements have not been confirmed by the sender.
- def unsettled; @receiver_impl.getUnsettled; end
-
- # Cancels the reciever.
- def close; @receiver_impl.close; end
-
- # Returns whether the receiver is closed.
- def closed?; @receiver_impl.isClosed; end
-
- # Returns the name of the receiver
- def name; @receiver_impl.getName; end
-
- # Returns the Session for this receiver.
- def session; Qpid::Messaging::Session.new(@receiver_impl.getSession); end
-
- # Returns whether the underlying handle is valid.
- def valid?; @receiver_impl.isValid; end
-
- # Returns whether the underlying handle is null.
- def null?; @receiver_impl.isNull; end
-
- def swap receiver
- @receiver_impl.swap receiver.receiver_impl
- end
-
- private
-
- def create_message_wrapper message_impl
- Qpid::Messaging::Message.new({}, message_impl)
- end
-
- end
-
- end
-
-end
-
diff --git a/qpid/cpp/bindings/qpid/ruby/lib/qpid/sender.rb b/qpid/cpp/bindings/qpid/ruby/lib/qpid/sender.rb
deleted file mode 100644
index 5d59c20d7e..0000000000
--- a/qpid/cpp/bindings/qpid/ruby/lib/qpid/sender.rb
+++ /dev/null
@@ -1,82 +0,0 @@
-#
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License. You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied. See the License for the
-# specific language governing permissions and limitations
-# under the License.
-#
-
-module Qpid
-
- module Messaging
-
- # Sender defines a type for sending messages.
- class Sender
-
- def initialize(sender_impl) # :nodoc:
- @sender_impl = sender_impl
- end
-
- def sender_impl # :nodoc:
- @sender_impl
- end
-
- # Sends a message.
- def send(message, args = {})
- block = args[:block] || false
- @sender_impl.send message.message_impl, block
- end
-
- # Closes the sender.
- def close; @sender_impl.close; end
-
- # Returns the name for the sender.
- def name; @sender_impl.getName; end
-
- # Sets the capacity for the sender, which is the number of outgoing
- # messages that can be held pending confirmation or receipt by
- # the broker.
- def capacity=(capacity); @sender_impl.setCapacity capacity; end
-
- # Returns the capacity.
- def capacity; @sender_impl.getCapacity; end
-
- # Returns the number of messages sent that are pending receipt
- # confirmation by the broker.
- def unsettled; @sender_impl.getUnsettled; end
-
- # Returns the available capacity for sending messages.
- def available
- @sender_impl.getAvailable
- end
-
- # Returns the Session for this sender.
- def session; Qpid::Messaging::Session.new @sender_impl.getSession; end
-
- # Returns if the underlying sender is valid.
- def valid?; @sender_impl.isValid; end
-
- # Returns if the underlying sender is null.
- def null?; @sender_impl.isNull; end
-
- def swap sender
- @sender_impl.swap sender.sender_impl
- end
-
- end
-
- end
-
-end
-
diff --git a/qpid/cpp/bindings/qpid/ruby/lib/qpid/session.rb b/qpid/cpp/bindings/qpid/ruby/lib/qpid/session.rb
deleted file mode 100644
index 543c26cc70..0000000000
--- a/qpid/cpp/bindings/qpid/ruby/lib/qpid/session.rb
+++ /dev/null
@@ -1,186 +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.
-#
-
-require 'cqpid'
-
-require 'qpid/errors'
-
-module Qpid
-
- module Messaging
-
- # A Session represents a distinct conversation between end points.
- class Session
-
- def initialize(session) # :nodoc:
- @session_impl = session
- end
-
- def session_impl # :nodoc:
- @session_impl
- end
-
- # Returns the +Connection+ for the +Session+.
- def connection
- connection_impl = @session_impl.getConnection
- Qpid::Messaging::Connection.new "", {}, connection_impl
- end
-
- # Creates a new endpoint for sending messages.
- def create_sender(address)
- _address = address
-
- if address.class == Qpid::Messaging::Address
- _address = address.address_impl
- end
-
- Qpid::Messaging::Sender.new(@session_impl.createSender(_address))
- end
-
- # Retrieves the +Sender+ with the specified name.
- def sender(name)
- result = nil
-
- begin
- sender_impl = @session_impl.getSender name
- result = Sender.for_impl sender_impl
- rescue
- # treat any error as a key error
- end
-
- raise Qpid::Messaging::KeyError, "No such sender: #{name}" if result.nil?
- result
- end
-
- # Retrieves the +Receiver+ with the specified name.
- def receiver(name)
- result = nil
-
- begin
- receiver_impl = @session_impl.getReceiver name
- result = Receiver.for_impl receiver_impl
- rescue
- # treat any error as a key error
- end
-
- raise Qpid::Messaging::KeyError, "No such receiver: #{name}" if result.nil?
- result
- end
-
- # Creates a new endpoint for receiving messages.
- def create_receiver(address)
- result = nil
-
- if address.class == Qpid::Messaging::Address
- address_impl = address.address_impl
- result = Qpid::Messaging::Receiver.new(@session_impl.createReceiver(address_impl))
- else
- result = Qpid::Messaging::Receiver.new(@session_impl.createReceiver(address))
- end
-
- return result
- end
-
- # Closes the Session and all associated Senders and Receivers.
- # All Sessions are closed when the associated Connection is closed.
- def close; @session_impl.close; end
-
- # Commits any pending transactions for a transactional session.
- def commit; @session_impl.commit; end
-
- # Rolls back any uncommitted transactions on a transactional session.
- def rollback; @session_impl.rollback; end
-
- # Acknowledges one or more outstanding messages that have been received
- # on this session.
- #
- # If a message is submitted (:message => something_message) then only
- # that message is acknowledged. Otherwise all messsages are acknowledged.
- #
- # If :sync => true then the call will block until the server completes
- # processing the acknowledgements.
- # If :sync => true then the call will block until processed by the server (def. false)
- def acknowledge(args = {})
- sync = args[:sync] || false
- message = args[:message] if args[:message]
-
- unless message.nil?
- @session_impl.acknowledge message.message_impl, sync
- else
- @session_impl.acknowledge sync
- end
- end
-
- # Rejects the specified message. A rejected message will not be redelivered.
- #
- # NOTE: A message cannot be rejected once it has been acknowledged.
- def reject(message); @session_impl.reject message.message_impl; end
-
- # Releases the message, which allows the broker to attempt to
- # redeliver it.
- #
- # NOTE: A message connot be released once it has been acknowled.
- def release(message); @session_impl.release message.message_impl; end
-
- # Requests synchronization with the server.
- #
- # If :block => true then the call will block until the server acknowledges.
- #
- # If :block => false (default) then the call will complete and the server
- # will send notification on completion.
- def sync(args = {})
- block = args[:block] || false
- @session_impl.sync block
- end
-
- # Returns the total number of receivable messages, and messages already received,
- # by Receivers associated with this session.
- def receivable; @session_impl.getReceivable; end
-
- # Returns the number of messages that have been acknowledged by this session
- # whose acknowledgements have not been confirmed as processed by the server.
- def unsettled_acks; @session_impl.getUnsettledAcks; end
-
- # Fetches the receiver for the next message.
- def next_receiver(timeout = Qpid::Messaging::Duration::FOREVER)
- receiver_impl = @session_impl.nextReceiver(timeout.duration_impl)
- Qpid::Messaging::Receiver.new receiver_impl
- end
-
- # Returns whether there are errors on this session.
- def error?; @session_impl.hasError; end
-
- def check_error; @session_impl.checkError; end
-
- # Returns if the underlying session is valid.
- def valid?; @session_impl.isValid; end
-
- # Returns if the underlying session is null.
- def null?; @session_impl.isNull; end
-
- def swap session
- @session_impl.swap session.session_impl
- end
-
- end
-
- end
-
-end
-
diff --git a/qpid/cpp/bindings/qpid/ruby/lib/qpid/version.rb b/qpid/cpp/bindings/qpid/ruby/lib/qpid/version.rb
deleted file mode 100644
index a791b1638c..0000000000
--- a/qpid/cpp/bindings/qpid/ruby/lib/qpid/version.rb
+++ /dev/null
@@ -1,31 +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.
-#
-
-module Qpid
-
- module Version
-
- NUMBERS = [MAJOR = 0,
- MINOR = 10,
- BUILD = 0]
- end
-
- VERSION = Version::NUMBERS.join('.')
-
-end
diff --git a/qpid/cpp/bindings/qpid/ruby/test/test_address.rb b/qpid/cpp/bindings/qpid/ruby/test/test_address.rb
deleted file mode 100644
index f54e93aa3d..0000000000
--- a/qpid/cpp/bindings/qpid/ruby/test/test_address.rb
+++ /dev/null
@@ -1,39 +0,0 @@
-#
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License. You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied. See the License for the
-# specific language governing permissions and limitations
-# under the License.
-#
-
-$:.unshift File.join(File.dirname(__FILE__), "..", "lib")
-
-require 'test/unit'
-require 'flexmock/test_unit'
-
-require 'cqpid'
-require 'qpid/address'
-
-class TestAddress < Test::Unit::TestCase
-
- def test_constructor
- result = Qpid::Messaging::Address.new "name", "subject", {:foo => :bar}, "type"
-
- assert_equal "name", result.name
- assert_equal "subject", result.subject
- assert_equal "type", result._type
- end
-
-end
-
diff --git a/qpid/cpp/bindings/qpid/ruby/test/test_connection.rb b/qpid/cpp/bindings/qpid/ruby/test/test_connection.rb
deleted file mode 100644
index 648fb0588a..0000000000
--- a/qpid/cpp/bindings/qpid/ruby/test/test_connection.rb
+++ /dev/null
@@ -1,257 +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.
-#
-
-$:.unshift File.join(File.dirname(__FILE__), "..", "lib")
-
-require 'test/unit'
-require 'flexmock/test_unit'
-
-require 'cqpid'
-require 'qpid/connection'
-
-class TestConnection < Test::Unit::TestCase
-
- def setup
- @connection_impl = flexmock("connection_impl")
- @other_connection = flexmock("other_connection")
- @other_connection_impl = flexmock("other_connection_impl")
- @cqpid_connection = flexmock(Cqpid::Connection)
-
- @session = flexmock("session")
- @session_name = "test-session"
-
- @url = "localhost"
- @options = {}
-
- @connection = Qpid::Messaging::Connection.new(@url, @options, @connection_impl)
- end
-
- def test_create_with_username_and_password
- @cqpid_connection.
- should_receive(:new).
- once.with("localhost",
- {"username" => "username",
- "password" => "password"}).
- and_return(@connection_impl)
- @connection_impl.
- should_receive(:open).
- once
-
- result = Qpid::Messaging::Connection.new("localhost",
- :username => "username",
- :password => "password")
- result.open
-
- assert_same @connection_impl, result.connection_impl
- end
-
- def test_create_with_hostname
- result = Qpid::Messaging::Connection.new("localhost")
-
- assert_not_nil result
- end
-
- def test_open
- @cqpid_connection.
- should_receive(:new).
- once.
- with(@url, {}).
- and_return(@connection_impl)
- @connection_impl.
- should_receive(:open).
- once
-
- @connection.open
-
- assert_same @connection_impl, @connection.connection_impl
- end
-
- def test_check_open_when_open
- @connection_impl.
- should_receive(:isOpen).
- once.
- and_return(true)
-
- assert @connection.open?
- end
-
- def test_check_open_before_connection
- result = Qpid::Messaging::Connection.new("hostname")
-
- assert !result.open?
- end
-
- def test_check_open_when_closed
- @connection_impl.
- should_receive(:isOpen).
- once.
- and_return(false)
-
- assert !@connection.open?
- end
-
- def test_close_an_unopened_session
- @connection_impl.
- should_receive(:isOpen).
- once.
- and_return(false)
-
- @connection.close
- end
-
- def test_close
- @connection_impl.
- should_receive(:isOpen).
- once.
- and_return(true).
- should_receive(:close).
- once
-
- @connection.close
- end
-
- def test_create_session_without_name
- @connection_impl.
- should_receive(:isOpen).
- once.
- and_return(true).
- should_receive(:createSession).
- once.
- with("").
- and_return(@session)
-
- result = @connection.create_session
-
- assert_not_nil result
- assert_same @session, result.session_impl
- end
-
- def test_create_session
- @connection_impl.
- should_receive(:isOpen).
- once.
- and_return(true).
- should_receive(:createSession).
- once.
- with(@session_name).
- and_return(@session)
-
- result = @connection.create_session :name => @session_name
-
- assert_not_nil result
- assert_same @session, result.session_impl
- end
-
- def test_create_session_raises_exception_when_closed
- @connection_impl.
- should_receive(:isOpen).
- once.
- and_return(false)
-
- assert_raise(RuntimeError) {@connection.create_session @session_name}
- end
-
- def test_create_transactional_session
- @connection_impl.
- should_receive(:isOpen).
- once.
- and_return(true).
- should_receive(:createTransactionalSession).
- once.
- with("").
- and_return(@session)
-
- result = @connection.create_session :transactional => true
-
- assert_not_nil result
- assert_same @session, result.session_impl
- end
-
- def test_authenticated_username_when_not_connected
- @connection_impl.
- should_receive(:isOpen).
- once.
- and_return(false)
-
- result = @connection.authenticated_username
-
- assert_nil result
- end
-
- def test_authenticated_username
- @connection_impl.
- should_receive(:isOpen).
- once.
- and_return(true).
- should_receive(:getAuthenticatedUsername).
- once.
- and_return("farkle")
-
- result = @connection.authenticated_username
-
- assert_equal "farkle", result
- end
-
- def test_get_session_with_invalid_name
- @connection_impl.
- should_receive(:getSession).
- once.
- with(@session_name).
- and_return(nil)
-
- result = @connection.session @session_name
-
- assert_nil result
- end
-
- # APIs inherited from Handle
-
- def test_is_valid
- @connection_impl.
- should_receive(:isValid).
- once.
- and_return(true)
-
- assert @connection.valid?
- end
-
- def test_is_null
- @connection_impl.
- should_receive(:isNull).
- once.
- and_return(false)
-
- assert !@connection.null?
- end
-
- def test_swap
- @other_connection.
- should_receive(:connection_impl).
- once.
- and_return(@other_connection_impl)
- @connection_impl.
- should_receive(:swap).
- once.
- with(@other_connection_impl)
-
- @connection.swap @other_connection
- end
-
-end
-
diff --git a/qpid/cpp/bindings/qpid/ruby/test/test_encoding.rb b/qpid/cpp/bindings/qpid/ruby/test/test_encoding.rb
deleted file mode 100644
index 060975a1d5..0000000000
--- a/qpid/cpp/bindings/qpid/ruby/test/test_encoding.rb
+++ /dev/null
@@ -1,146 +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.
-#
-
-$:.unshift File.join(File.dirname(__FILE__), "..", "lib")
-
-require 'test/unit'
-require 'flexmock/test_unit'
-
-require 'cqpid'
-require 'qpid/encoding'
-
-class TestEncoding < Test::Unit::TestCase
-
- def setup
- @cqpid = flexmock(Cqpid)
-
- @message = flexmock("message")
- @message_impl = flexmock("message_impl")
-
- @encoded = {"foo" => "bar"}
- end
-
- def test_encode_map_with_symbols
- @message.
- should_receive(:message_impl).
- once.
- and_return(@message_impl)
- @cqpid.
- should_receive(:encode).
- once.
- with({"foo" => "bar"}, @message_impl).
- and_return(@encoded)
-
- result = Qpid::Messaging.encode({:foo => :bar}, @message)
-
- assert_same @encoded, result
- end
-
- def test_encode_list_with_symbols
- @message.
- should_receive(:message_impl).
- once.
- and_return(@message_impl)
- @cqpid.
- should_receive(:encode).
- once.
- with(["foo", "bar"], @message_impl).
- and_return(@encoded)
-
- result = Qpid::Messaging.encode([:foo, :bar], @message)
-
- assert_same @encoded, result
- end
-
- def test_encode_with_content_type
- @message.
- should_receive(:message_impl).
- once.
- and_return(@message_impl)
- @cqpid.
- should_receive(:encode).
- once.
- with({"foo" => "bar"}, @message_impl).
- and_return(@encoded)
-
- result = Qpid::Messaging.encode({:foo => :bar}, @message)
-
- assert_same @encoded, result
- end
-
- def test_encode
- @message.
- should_receive(:message_impl).
- once.
- and_return(@message_impl)
- @cqpid.
- should_receive(:encode).
- once.
- with({"foo" => "bar"}, @message_impl).
- and_return(@encoded)
-
- result = Qpid::Messaging.encode({"foo" => "bar"}, @message)
-
- assert_same @encoded, result
- end
-
- def test_decode_for_map
- decoded = {"foo" => "bar"}
- @message.
- should_receive(:content_type).
- once.
- and_return("amqp/map")
- @message.
- should_receive(:message_impl).
- once.
- and_return(@message_impl)
- @cqpid.
- should_receive(:decodeMap).
- once.
- with(@message_impl).
- and_return(decoded)
-
- result = Qpid::Messaging.decode(@message)
-
- assert_same decoded, result
- end
-
- def test_decode_for_list
- decoded = ["foo", "bar"]
- @message.
- should_receive(:content_type).
- once.
- and_return("amqp/list")
- @message.
- should_receive(:message_impl).
- once.
- and_return(@message_impl)
- @cqpid.
- should_receive(:decodeList).
- once.
- with(@message_impl).
- and_return(decoded)
-
- result = Qpid::Messaging.decode(@message)
-
- assert_same decoded, result
- end
-
-end
-
diff --git a/qpid/cpp/bindings/qpid/ruby/test/test_message.rb b/qpid/cpp/bindings/qpid/ruby/test/test_message.rb
deleted file mode 100644
index 0d71d42360..0000000000
--- a/qpid/cpp/bindings/qpid/ruby/test/test_message.rb
+++ /dev/null
@@ -1,307 +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.
-#
-
-$:.unshift File.join(File.dirname(__FILE__), "..", "lib")
-
-require 'test/unit'
-require 'flexmock/test_unit'
-
-require 'qpid/encoding'
-require 'qpid/message'
-
-class TestMessage < Test::Unit::TestCase
-
- def setup
- @address = flexmock("address")
- @address_impl = flexmock("address_impl")
-
- @message_impl = flexmock("message")
- @message = Qpid::Messaging::Message.new({}, @message_impl)
- end
-
- def test_message_impl
- assert_same @message_impl, @message.message_impl
- end
-
- def test_set_reply_to
- @address.
- should_receive(:address_impl).
- once.
- and_return(@address_impl)
- @message_impl.
- should_receive(:setReplyTo).
- once.
- with(@address_impl)
-
- @message.reply_to = @address
- end
-
- def test_get_reply_to
- @message_impl.
- should_receive(:getReplyTo).
- once.
- and_return(@address_impl)
-
- result = @message.reply_to
-
- assert_not_nil result
- assert_same @address_impl, result.address_impl
- end
-
- def test_set_subject
- @message_impl.
- should_receive(:setSubject).
- once.
- with("New Subject")
-
- @message.subject = "New Subject"
- end
-
- def test_get_subject
- @message_impl.
- should_receive(:getSubject).
- once.
- and_return("Old Subject")
-
- assert_equal "Old Subject", @message.subject
- end
-
- def test_set_content_type
- @message_impl.
- should_receive(:setContentType).
- once.
- and_return("amqp/map")
-
- @message.content_type = "amqp/map"
- end
-
- def test_get_content_type
- @message_impl.
- should_receive(:getContentType).
- once.
- and_return("amqp/list")
-
- assert_equal "amqp/list", @message.content_type
- end
-
- def test_set_message_id
- @message_impl.
- should_receive(:setMessageId).
- once.
- with("717")
-
- @message.message_id = "717"
- end
-
- def test_get_message_id
- @message_impl.
- should_receive(:getMessageId).
- once.
- and_return("1965")
-
- assert_equal "1965", @message.message_id
- end
-
- def test_set_user_id
- @message_impl.
- should_receive(:setUserId).
- once.
- with("129")
-
- @message.user_id = "129"
- end
-
- def test_get_user_id
- @message_impl.
- should_receive(:getUserId).
- once.
- and_return("1971")
-
- assert_equal "1971", @message.user_id
- end
-
- def test_set_correlation_id
- @message_impl.
- should_receive(:setCorrelationId).
- once.
- with("320")
-
- @message.correlation_id = "320"
- end
-
- def test_get_correlation_id
- @message_impl.
- should_receive(:getCorrelationId).
- once.
- and_return("1996")
-
- assert_equal "1996", @message.correlation_id
- end
-
- def test_set_priority
- @message_impl.
- should_receive(:setPriority).
- once.
- with(9)
-
- @message.priority = 9
- end
-
- def test_get_priority
- @message_impl.
- should_receive(:getPriority).
- once.
- and_return(21)
-
- assert_equal 21, @message.priority
- end
-
- def test_set_ttl
- @message_impl.
- should_receive(:setTtl).
- once.
- with(Qpid::Messaging::Duration::FOREVER)
-
- @message.ttl = Qpid::Messaging::Duration::FOREVER
- end
-
- def test_get_ttl
- @message_impl.
- should_receive(:getTtl).
- once.
- and_return(Qpid::Messaging::Duration::SECOND)
-
- assert_equal Qpid::Messaging::Duration::SECOND, @message.ttl
- end
-
- def test_set_durable
- @message_impl.
- should_receive(:setDurable).
- once.
- with(true)
-
- @message.durable = true
- end
-
- def test_set_not_durable
- @message_impl.
- should_receive(:setDurable).
- once.
- with(false)
-
- @message.durable = false
- end
-
- def test_get_durable
- @message_impl.
- should_receive(:getDurable).
- once.
- and_return(true)
-
- assert @message.durable
- end
-
- def test_set_redelivered
- @message_impl.
- should_receive(:setRedelivered).
- once.
- with(true)
-
- @message.redelivered = true
- end
-
- def test_set_not_redelivered
- @message_impl.
- should_receive(:setRedelivered).
- once.
- with(false)
-
- @message.redelivered = false
- end
-
- def test_get_redelivered
- @message_impl.
- should_receive(:getRedelivered).
- once.
- and_return(false)
-
- assert !@message.redelivered
- end
-
- def test_get_properties
- properties = {"foo" => "bar"}
- @message_impl.
- should_receive(:getProperties).
- once.
- and_return(properties)
-
- result = @message.properties
-
- assert_equal properties, result
- end
-
- def test_get_property
- @message_impl.
- should_receive(:getProperties).
- once.
- and_return({"foo" => "bar"})
-
- result = @message["foo"]
-
- assert_equal "bar", result
- end
-
- def test_set_property
- @message_impl.
- should_receive(:setProperty).
- once.
- with("foo", "bar")
-
- @message["foo"] = "bar"
- end
-
- def test_set_content
- @message_impl.
- should_receive(:setContent).
- once.
- with("foo")
-
- @message.content = "foo"
- end
-
- def test_get_content
- @message_impl.
- should_receive(:getContent).
- once.
- and_return("foo")
-
- assert_equal "foo", @message.content
- end
-
- def test_get_content_size
- @message_impl.
- should_receive(:getContentSize).
- once.
- and_return(68)
-
- assert_equal 68, @message.content_size
- end
-
-end
-
diff --git a/qpid/cpp/bindings/qpid/ruby/test/test_receiver.rb b/qpid/cpp/bindings/qpid/ruby/test/test_receiver.rb
deleted file mode 100644
index 61a4db17f2..0000000000
--- a/qpid/cpp/bindings/qpid/ruby/test/test_receiver.rb
+++ /dev/null
@@ -1,238 +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.
-#
-
-$:.unshift File.join(File.dirname(__FILE__), "..", "lib")
-
-require 'test/unit'
-require 'flexmock/test_unit'
-
-require 'qpid/receiver'
-
-class TestReceiver < Test::Unit::TestCase
-
- def setup
- @session_impl = flexmock("session")
-
- @Message_class = flexmock(Qpid::Messaging::Message)
- @Messaging_module = flexmock(Qpid::Messaging)
- @message_impl = flexmock("message_impl")
- @message = flexmock("message")
-
- @receiver_impl = flexmock("receiver")
- @other_receiver = flexmock("other_receiver")
- @other_receiver_impl = flexmock("other_receiver_impl")
- @receiver = Qpid::Messaging::Receiver.new @receiver_impl
- end
-
- def test_receiver_impl
- assert_same @receiver_impl, @receiver.receiver_impl
- end
-
- def test_get
- @receiver_impl.
- should_receive(:get).
- once.
- with_any_args.
- and_return(@message_impl)
-
- result = @receiver.get
-
- assert_not_nil result
- assert_same @message_impl, result.message_impl
- end
-
- def test_get_with_duration
- @receiver_impl.
- should_receive(:get).
- once.
- with_any_args.
- and_return(@message_impl)
-
- result = @receiver.get Qpid::Messaging::Duration::MINUTE
-
- assert_not_nil result
- assert_same @message_impl, result.message_impl
- end
-
- def test_get_with_no_message_received
- @receiver_impl.
- should_receive(:get).
- once.
- with_any_args.
- and_return(nil)
-
- result = @receiver.get Qpid::Messaging::Duration::SECOND
-
- assert_nil result
- end
-
- def test_fetch
- @receiver_impl.
- should_receive(:fetch).
- once.
- with_any_args.
- and_return(@message_impl)
-
- result = @receiver.fetch
-
- assert_not_nil result
- assert_same @message_impl, result.message_impl
- end
-
- def test_fetch_with_duration
- @receiver_impl.
- should_receive(:fetch).
- once.
- with_any_args.
- and_return(@message_impl)
-
- result = @receiver.fetch Qpid::Messaging::Duration::MINUTE
-
- assert_not_nil result
- assert_same @message_impl, result.message_impl
- end
-
- def test_fetch_with_no_message_received
- @receiver_impl.
- should_receive(:fetch).
- once.
- with_any_args.
- and_return(nil)
-
- result = @receiver.fetch Qpid::Messaging::Duration::SECOND
-
- assert_nil result
- end
-
- def test_set_capacity
- @receiver_impl.
- should_receive(:setCapacity).
- once.
- with(15)
-
- @receiver.capacity = 15
- end
-
- def test_get_capacity
- @receiver_impl.
- should_receive(:getCapacity).
- once.
- and_return(17)
-
- assert_equal 17, @receiver.capacity
- end
-
- def test_get_available
- @receiver_impl.
- should_receive(:getAvailable).
- once.
- and_return(2)
-
- assert_equal 2, @receiver.available
- end
-
- def test_get_unsettled
- @receiver_impl.
- should_receive(:getUnsettled).
- once.
- and_return(12)
-
- assert_equal 12, @receiver.unsettled
- end
-
- def test_close
- @receiver_impl.
- should_receive(:close).
- once
-
- @receiver.close
- end
-
- def test_closed_when_open
- @receiver_impl.
- should_receive(:isClosed).
- once.
- and_return(false)
-
- assert !@receiver.closed?
- end
-
- def test_closed
- @receiver_impl.
- should_receive(:isClosed).
- once.
- and_return(true)
-
- assert @receiver.closed?
- end
-
- def test_get_name
- @receiver_impl.
- should_receive(:getName).
- once.
- and_return("my-queue")
-
- assert_equal "my-queue", @receiver.name
- end
-
- def test_get_session
- @receiver_impl.
- should_receive(:getSession).
- once.
- and_return(@session_impl)
-
- result = @receiver.session
-
- assert_not_nil result
- assert_same @session_impl, result.session_impl
- end
-
- def test_is_valid
- @receiver_impl.
- should_receive(:isValid).
- once.
- and_return(false)
-
- assert !@receiver.valid?
- end
-
- def test_is_null
- @receiver_impl.
- should_receive(:isNull).
- once.
- and_return(true)
-
- assert @receiver.null?
- end
-
- def test_swap
- @other_receiver.
- should_receive(:receiver_impl).
- once.
- and_return(@other_receiver_impl)
- @receiver_impl.
- should_receive(:swap).
- once.
- with(@other_receiver_impl)
-
- @receiver.swap @other_receiver
- end
-
-end
-
diff --git a/qpid/cpp/bindings/qpid/ruby/test/test_sender.rb b/qpid/cpp/bindings/qpid/ruby/test/test_sender.rb
deleted file mode 100644
index 64348b9f72..0000000000
--- a/qpid/cpp/bindings/qpid/ruby/test/test_sender.rb
+++ /dev/null
@@ -1,183 +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.
-#
-
-$:.unshift File.join(File.dirname(__FILE__), "..", "lib")
-
-require 'test/unit'
-require 'flexmock/test_unit'
-
-require 'qpid/sender'
-
-class TestSender < Test::Unit::TestCase
-
- def setup
- @messaging = flexmock(Qpid::Messaging)
- @message = flexmock("message")
-
- @session_impl = flexmock("session_impl")
-
- @sender_impl = flexmock("sender_impl")
- @other_sender_impl = flexmock("other_sender_impl")
- @sender = Qpid::Messaging::Sender.new @sender_impl
- @other_sender = flexmock("other_sender")
- end
-
- def test_send
- message_impl = "message_impl"
- content = {:foo => :bar}
- @message.
- should_receive(:message_impl).
- once.
- and_return(message_impl)
- @sender_impl.
- should_receive(:send).
- once.
- with(message_impl, false)
-
- @sender.send @message
- end
-
- def test_send_and_dont_block
- message_impl = "message_impl"
- content = {:foo => :bar}
- @message.
- should_receive(:message_impl).
- once.
- and_return(message_impl)
- @sender_impl.
- should_receive(:send).
- once.
- with(message_impl, false)
-
- @sender.send @message, :block => false
- end
-
- def test_send_and_block
- message_impl = "message_impl"
- content = {:foo => :bar}
- @message.
- should_receive(:message_impl).
- once.
- and_return(message_impl)
- @sender_impl.
- should_receive(:send).
- once.
- with(message_impl, true)
-
- @sender.send @message, :block => true
- end
-
- def test_close
- @sender_impl.
- should_receive(:close).
- once
-
- @sender.close
- end
-
- def test_set_capacity
- @sender_impl.
- should_receive(:setCapacity).
- once.
- with(17)
-
- @sender.capacity = 17
- end
-
- def test_get_capacity
- @sender_impl.
- should_receive(:getCapacity).
- once.
- and_return(12)
-
- assert_equal 12, @sender.capacity
- end
-
- def test_unsettled
- @sender_impl.
- should_receive(:getUnsettled).
- once.
- and_return(5)
-
- assert_equal 5, @sender.unsettled
- end
-
- def test_available
- @sender_impl.
- should_receive(:getAvailable).
- once.
- and_return(15)
-
- assert_equal 15, @sender.available
- end
-
- def test_name
- @sender_impl.
- should_receive(:getName).
- once.
- and_return("myname")
-
- assert_equal "myname", @sender.name
- end
-
- def test_session
- @sender_impl.
- should_receive(:getSession).
- once.
- and_return(@session_impl)
-
- result = @sender.session
-
- assert_not_nil result
- assert_same @session_impl, result.session_impl
- end
-
- def test_is_valid
- @sender_impl.
- should_receive(:isValid).
- once.
- and_return(true)
-
- assert @sender.valid?
- end
-
- def test_is_null
- @sender_impl.
- should_receive(:isNull).
- once.
- and_return(false)
-
- assert !@sender.null?
- end
-
- def test_swap
- @other_sender.
- should_receive(:sender_impl).
- once.
- and_return(@other_sender_impl)
- @sender_impl.
- should_receive(:swap).
- once.
- with(@other_sender_impl)
-
- @sender.swap @other_sender
- end
-
-end
-
diff --git a/qpid/cpp/bindings/qpid/ruby/test/test_session.rb b/qpid/cpp/bindings/qpid/ruby/test/test_session.rb
deleted file mode 100644
index 20f055967b..0000000000
--- a/qpid/cpp/bindings/qpid/ruby/test/test_session.rb
+++ /dev/null
@@ -1,445 +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.
-#
-
-$:.unshift File.join(File.dirname(__FILE__), "..", "lib")
-
-require 'test/unit'
-require 'flexmock/test_unit'
-
-require 'qpid/errors'
-require 'qpid/duration'
-require 'qpid/session'
-
-class TestSession < Test::Unit::TestCase
-
- def setup
- @session_impl = flexmock("session_impl")
- @other_session = flexmock("other_session")
- @other_session_impl = flexmock("other_session_impl")
- @sender = flexmock("sender")
-
- @Connection_class = flexmock(Qpid::Messaging::Connection)
- @connection_impl = flexmock("connection_impl")
- @connection = flexmock("connection")
-
- @Receiver_class = flexmock(Qpid::Messaging::Receiver)
- @receiver = flexmock("receiver")
- @receiver_impl = flexmock("receiver_impl")
-
- @address = flexmock("address")
- @address_impl = flexmock("address_impl")
-
- @Sender_class = flexmock(Qpid::Messaging::Sender)
- @sender = flexmock("sender")
- @sender_impl = flexmock("sender_impl")
-
- @message = flexmock("message")
- @message_impl = flexmock("message_impl")
-
- @duration = flexmock("duration")
- @duration_impl = flexmock("duration_impl")
-
- @session = Qpid::Messaging::Session.new(@session_impl)
- end
-
- def test_create_sender_with_Address
- @address.
- should_receive(:class).
- once.
- and_return(Qpid::Messaging::Address).
- should_receive(:address_impl).
- once.
- and_return(@address_impl)
- @session_impl.
- should_receive(:createSender).
- once.
- with(@address_impl).
- and_return(@sender_impl)
-
- result = @session.create_sender @address
-
- assert_not_nil result
- end
-
- def test_create_sender
- @session_impl.
- should_receive(:createSender).
- once.
- with_any_args.
- and_return(@sender_impl)
-
- result = @session.create_sender("my-queue")
-
- assert_not_nil result
- end
-
- def test_create_sender_with_address_string
- @session_impl.
- should_receive(:createSender).
- once.
- with("my-queue;{create:always}").
- and_return(@sender_impl)
-
- result = @session.create_sender "my-queue;{create:always}"
-
- assert_same @sender_impl, result.sender_impl
- end
-
- def test_create_receiver
- @address.
- should_receive(:class).
- once.
- and_return(Qpid::Messaging::Address).
- should_receive(:address_impl).
- once.
- and_return(@address_impl)
- @session_impl.
- should_receive(:createReceiver).
- once.
- with(@address_impl).
- and_return(@receiver_impl)
-
- result = @session.create_receiver(@address)
-
- assert_equal @receiver_impl, result.receiver_impl
- end
-
- def test_create_receiver_with_address_string
- @session_impl.
- should_receive(:createReceiver).
- once.
- with("my-queue").
- and_return(@receiver_impl)
-
- result = @session.create_receiver("my-queue")
-
- assert_same @receiver_impl, result.receiver_impl
- end
-
- def test_close
- @session_impl.
- should_receive(:close).
- once
-
- @session.close
- end
-
- def test_commit
- @session_impl.
- should_receive(:commit).
- once
-
- @session.commit
- end
-
- def test_rollback
- @session_impl.
- should_receive(:rollback).
- once
-
- @session.rollback
- end
-
- def test_acknowledge_with_no_args
- @session_impl.
- should_receive(:acknowledge).
- once.
- with(false)
-
- @session.acknowledge
- end
-
- def test_acknowledge_and_sync
- @session_impl.
- should_receive(:acknowledge).
- once.
- with(true)
-
- @session.acknowledge :sync => true
- end
-
- def test_acknowledge_and_dont_sync
- @session_impl.
- should_receive(:acknowledge).
- once.
- with(false)
-
- @session.acknowledge :sync => false
- end
-
- def test_acknowledge_message_without_sync
- @message.
- should_receive(:message_impl).
- once.
- and_return(@message_impl)
- @session_impl.
- should_receive(:acknowledge).
- once.
- with(@message_impl, false)
-
- @session.acknowledge :message => @message
- end
-
- def test_acknowledge_message_and_sync
- @message.
- should_receive(:message_impl).
- once.
- and_return(@message_impl)
- @session_impl.
- should_receive(:acknowledge).
- once.
- with(@message_impl, true)
-
- @session.acknowledge :message => @message, :sync => true
- end
-
- def test_acknowledge_message_and_dont_sync
- @message.
- should_receive(:message_impl).
- once.
- and_return(@message_impl)
- @session_impl.
- should_receive(:acknowledge).
- once.
- with(@message_impl, false)
-
- @session.acknowledge :message => @message, :sync => false
- end
-
- def test_reject_message
- @message.
- should_receive(:message_impl).
- once.
- and_return(@message_impl)
- @session_impl.
- should_receive(:reject).
- once.
- with(@message_impl)
-
- @session.reject @message
- end
-
- def test_release_message
- @message.
- should_receive(:message_impl).
- once.
- and_return(@message_impl)
- @session_impl.
- should_receive(:release).
- once.
- with(@message_impl)
-
- @session.release @message
- end
-
- def test_sync_without_block
- @session_impl.
- should_receive(:sync).
- once
-
- @session.sync
- end
-
- def test_sync_and_block
- @session_impl.
- should_receive(:sync).
- once.
- with(true)
-
- @session.sync :block => true
- end
-
- def test_sync_and_dont_block
- @session_impl.
- should_receive(:sync).
- once.
- with(false)
-
- @session.sync :block => false
- end
-
- def test_receivable
- @session_impl.
- should_receive(:getReceivable).
- once.
- and_return(5)
-
- assert_equal 5, @session.receivable
- end
-
- def test_unsettled_acks
- @session_impl.
- should_receive(:getUnsettledAcks).
- once.
- and_return(17)
-
- assert_equal 17, @session.unsettled_acks
- end
-
- def test_next_receiver_with_no_duration
- @session_impl.
- should_receive(:nextReceiver).
- once.
- with(Qpid::Messaging::Duration::FOREVER.duration_impl).
- and_return(@receiver_impl)
-
- result = @session.next_receiver
-
- assert_same @receiver_impl, result.receiver_impl
- end
-
- def test_next_receiver_with_duration
- @duration.
- should_receive(:duration_impl).
- once.
- and_return(@duration_impl)
- @session_impl.
- should_receive(:nextReceiver).
- once.
- with(@duration_impl).
- and_return(@receiver_impl)
-
- result = @session.next_receiver @duration
-
- assert_same @receiver_impl, result.receiver_impl
- end
-
- def test_sender
- @session_impl.
- should_receive(:getSender).
- once.
- with("farkle").
- and_return(@sender_impl)
- @Sender_class.
- should_receive(:for_impl).
- once.
- with(@sender_impl).
- and_return(@sender)
-
- result = @session.sender "farkle"
-
- assert_same @sender, result
- end
-
- def test_sender_with_invalid_name
- @session_impl.
- should_receive(:getSender).
- once.
- with("farkle").
- and_throw(RuntimeError)
-
- assert_raise(Qpid::Messaging::KeyError) {@session.sender "farkle"}
- end
-
- def test_receiver
- @session_impl.
- should_receive(:getReceiver).
- once.
- with("farkle").
- and_return(@receiver_impl)
- @Receiver_class.
- should_receive(:for_impl).
- once.
- with(@receiver_impl).
- and_return(@receiver)
-
- result = @session.receiver "farkle"
-
- assert_same @receiver, result
- end
-
- def test_receiver_with_invalid_name
- @session_impl.
- should_receive(:getReceiver).
- once.
- with("farkle").
- and_throw(RuntimeError)
-
- assert_raise(Qpid::Messaging::KeyError) {@session.receiver "farkle"}
- end
-
- def test_connection
- @session_impl.
- should_receive(:getConnection).
- once.
- and_return(@connection_impl)
-
- result = @session.connection
-
- assert_same @connection_impl, result.connection_impl
- end
-
- def test_error_with_none
- @session_impl.
- should_receive(:hasError).
- once.
- and_return(false)
-
- assert !@session.error?
- end
-
- def test_error
- @session_impl.
- should_receive(:hasError).
- once.
- and_return(true)
-
- assert @session.error?
- end
-
- def test_check_error
- @session_impl.
- should_receive(:checkError).
- once
-
- @session.check_error
- end
-
- def test_is_valid
- @session_impl.
- should_receive(:isValid).
- once.
- and_return(false)
-
- assert !@session.valid?
- end
-
- def test_is_null
- @session_impl.
- should_receive(:isNull).
- once.
- and_return(false)
-
- assert !@session.null?
- end
-
- def test_swap
- @other_session.
- should_receive(:session_impl).
- once.
- and_return(@other_session_impl)
- @session_impl.
- should_receive(:swap).
- once.
- with(@other_session_impl)
-
- @session.swap @other_session
- end
-
-end
diff --git a/qpid/cpp/bindings/qpid/ruby/test/ts_bindings.rb b/qpid/cpp/bindings/qpid/ruby/test/ts_bindings.rb
deleted file mode 100644
index 7aa410c8f8..0000000000
--- a/qpid/cpp/bindings/qpid/ruby/test/ts_bindings.rb
+++ /dev/null
@@ -1,30 +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.
-#
-
-$:.unshift File.join(File.dirname(__FILE__), "..", "lib")
-
-require 'test/unit'
-require 'test_encoding'
-require 'test_address'
-require 'test_message'
-require 'test_sender'
-require 'test_receiver'
-require 'test_session'
-require 'test_connection'
-
diff --git a/qpid/cpp/bindings/swig_ruby_typemaps.i b/qpid/cpp/bindings/swig_ruby_typemaps.i
index 326d607c8d..79e679663d 100644
--- a/qpid/cpp/bindings/swig_ruby_typemaps.i
+++ b/qpid/cpp/bindings/swig_ruby_typemaps.i
@@ -49,7 +49,7 @@
}
VALUE VariantToRb(const qpid::types::Variant* v) {
- VALUE result = Qnil;
+ VALUE result;
try {
switch (v->getType()) {
case qpid::types::VAR_VOID: {
diff --git a/qpid/cpp/bld-winsdk.ps1 b/qpid/cpp/bld-winsdk.ps1
index bea46da28f..8f0a5886dc 100644
--- a/qpid/cpp/bld-winsdk.ps1
+++ b/qpid/cpp/bld-winsdk.ps1
@@ -186,6 +186,9 @@ function BuildAPlatform
'examples/qmf-console',
'examples/request-response',
'examples/tradedemo',
+ 'examples/old-examples.sln',
+ 'examples/README.*',
+ 'examples/verify*',
'include',
'plugins')
diff --git a/qpid/cpp/configure.ac b/qpid/cpp/configure.ac
index 092694d56b..ea1a1b49ea 100644
--- a/qpid/cpp/configure.ac
+++ b/qpid/cpp/configure.ac
@@ -68,10 +68,8 @@ if test x$GXX = xyes; then
# The following warnings are deliberately omitted, they warn on valid code.
# -Wunreachable-code -Wpadded -Winline
# -Wshadow - warns about boost headers.
- # Can't test for -Werror as whether it fails or not depends on what's in
- # CFLAGS/CXXFLAGS. In any case it's been in gcc for a long time (since 2.95 at least)
if test "${enableval}" = yes; then
- COMPILER_FLAGS="-Werror"
+ gl_COMPILER_FLAGS(-Werror)
gl_COMPILER_FLAGS(-pedantic)
gl_COMPILER_FLAGS(-Wall)
gl_COMPILER_FLAGS(-Wextra)
@@ -523,19 +521,18 @@ AM_PATH_PYTHON()
builddir_lib_suffix="/.libs"
AC_SUBST([builddir_lib_suffix])
-# Files to generate
+# Files to generate
AC_CONFIG_FILES([
Makefile
examples/Makefile
- examples/old_api/Makefile
- examples/old_api/direct/Makefile
- examples/old_api/fanout/Makefile
- examples/old_api/pub-sub/Makefile
- examples/old_api/request-response/Makefile
- examples/old_api/failover/Makefile
- examples/old_api/xml-exchange/Makefile
+ examples/direct/Makefile
+ examples/fanout/Makefile
+ examples/pub-sub/Makefile
+ examples/request-response/Makefile
+ examples/failover/Makefile
+ examples/xml-exchange/Makefile
examples/qmf-console/Makefile
- examples/old_api/tradedemo/Makefile
+ examples/tradedemo/Makefile
examples/messaging/Makefile
bindings/qpid/Makefile
bindings/qpid/ruby/Makefile
diff --git a/qpid/cpp/docs/api/developer.doxygen.in b/qpid/cpp/docs/api/developer.doxygen.in
index 1e1fddab80..fd3a9ac621 100644
--- a/qpid/cpp/docs/api/developer.doxygen.in
+++ b/qpid/cpp/docs/api/developer.doxygen.in
@@ -1029,7 +1029,7 @@ INCLUDE_FILE_PATTERNS =
# undefined via #undef or recursively expanded use the := operator
# instead of the = operator.
-PREDEFINED = QPID_CLIENT_EXTERN= QPID_COMMON_EXTERN= QPID_CONSOLE_EXTERN= QPID_BROKER_EXTERN= QPID_MESSAGING_EXTERN= QMF_EXTERN= QMFE_EXTERN=
+PREDEFINED = QPID_CLIENT_EXTERN= QPID_COMMON_EXTERN= QPID_CONSOLE_EXTERN= QPID_BROKER_EXTERN= QPID_MESSAGING_EXTERN= QMF_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/footer.html b/qpid/cpp/docs/api/footer.html
index 5a31e81821..883410ce25 100644
--- a/qpid/cpp/docs/api/footer.html
+++ b/qpid/cpp/docs/api/footer.html
@@ -25,7 +25,7 @@ Qpid C++ API Reference</small></address>
<address style="text-align: right;">
<small>
-Generated on $date for $projectname by&nbsp;<a href="http://www.doxygen.org/index.html"><img src="doxygen.png" alt="doxygen" align="middle" border="0"></a> $doxygenversion</small>
+Generated on $datetime for $projectname by&nbsp;<a href="http://www.doxygen.org/index.html"><img src="doxygen.png" alt="doxygen" align="middle" border="0"></a> $doxygenversion</small>
</address>
</body>
</html>
diff --git a/qpid/cpp/docs/api/user.doxygen.in b/qpid/cpp/docs/api/user.doxygen.in
index ec0fd1361c..2728df47e4 100644
--- a/qpid/cpp/docs/api/user.doxygen.in
+++ b/qpid/cpp/docs/api/user.doxygen.in
@@ -1021,7 +1021,7 @@ INCLUDE_FILE_PATTERNS =
# undefined via #undef or recursively expanded use the := operator
# instead of the = operator.
-PREDEFINED = QPID_CLIENT_EXTERN= QPID_COMMON_EXTERN= QPID_CONSOLE_EXTERN= QPID_BROKER_EXTERN= QPID_MESSAGING_EXTERN= QMF_EXTERN= QMFE_EXTERN=
+PREDEFINED = QPID_CLIENT_EXTERN= QPID_COMMON_EXTERN= QPID_CONSOLE_EXTERN= QPID_BROKER_EXTERN= QPID_MESSAGING_EXTERN= QMF_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/man/Makefile.am b/qpid/cpp/docs/man/Makefile.am
index b821568f81..14295f73bf 100644
--- a/qpid/cpp/docs/man/Makefile.am
+++ b/qpid/cpp/docs/man/Makefile.am
@@ -16,29 +16,10 @@
# specific language governing permissions and limitations
# under the License.
#
-
-# Generate makefile from qpidd --help
-#
-# Note: qiddd.1 is normally a _checked in_ pre-generated file, so that
-# make dist does not have to build the entire source just for the man page.
-#
-# To update the checked-in file (e.g. for a new release) do the following:
-#
-# - start with a completely clean checkout.
-# - make sure there are no modules installed in your configured prefix,
-# we don't want to pick up configuration from optional modules
-# - do bootstrap; configure
-# - in build-dir: cd src; make # build the broker
-# - in source-dir: cd docs/man; rm qpidd.1 # remove checked-in man page.
-# - in build-dir: cd docs/man; make # make new man page
-# - edit qpidd.1 to remove all default values referring to file/directory locations.
-# these values will differ between builds depending on configuration.
-# - if source-dir != build-dir: copy qpidd.1 from build-dir/docs/man to source-dir/docs/man
-
dist_man_MANS = qpidd.1
-man_aux = $(dist_man_MANS:.1=.x)
-EXTRA_DIST = $(man_aux) generate_manpage groffify_options.sed groffify_template.sed
+man_aux = $(dist_man_MANS:.1=.x)
+EXTRA_DIST = $(man_aux) generate_manpage groffify_options.sed groffify_template.sed
DISTCLEANFILES = $(dist_man_MANS)
CLEANFILES=qpidd.1
diff --git a/qpid/cpp/docs/man/qpidd.1 b/qpid/cpp/docs/man/qpidd.1
deleted file mode 100644
index d2cff454cf..0000000000
--- a/qpid/cpp/docs/man/qpidd.1
+++ /dev/null
@@ -1,247 +0,0 @@
-.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.38.2.
-.TH QPIDD "1" "March 2011" "qpidd (qpidc) version 0.11" "User Commands"
-.SH NAME
-
-qpidd \- the Qpid AMQP Message Broker Daemon
-.SH SYNOPSIS
-
-qpidd [-p port] [--config config_file] [--data-dir directory]
-.SH DESCRIPTION
-
-An AMQP message broker daemon that stores, routes and forwards
-messages using the Advanced Message Queueing Protocol (AMQP).
-.SH OPTIONS
-
-The options below are built-in to qpidd. Installing add-on modules provides additional options. To see the full set of options available type "qpidd --help"
-
-Options may be specified via command line, environment variable or configuration file. See FILES and ENVIRONMENT below for details.
-.PP
-
-.TP
-\fB\-h\fR [ \fB\-\-help\fR ]
-Displays the help message
-.TP
-\fB\-v\fR [ \fB\-\-version\fR ]
-Displays version information
-.TP
-\fB\-\-config\fR FILE
-Reads configuration from FILE
-.SS "Module options:"
-.TP
-\fB\-\-module\-dir\fR DIR
-Load all shareable modules in this
-directory
-.TP
-\fB\-\-load\-module\fR FILE
-Specifies additional module(s) to be
-loaded
-.TP
-\fB\-\-no\-module\-dir\fR
-Don't load modules from module
-directory
-.SS "Broker Options:"
-.TP
-\fB\-\-data\-dir\fR DIR
-Directory to contain persistent data
-generated by the broker
-.TP
-\fB\-\-no\-data\-dir\fR
-Don't use a data directory. No
-persistent configuration will be loaded
-or stored
-.TP
-\fB\-p\fR [ \fB\-\-port\fR ] PORT (5672)
-Tells the broker to listen on PORT
-.TP
-\fB\-\-worker\-threads\fR N (3)
-Sets the broker thread pool size
-.TP
-\fB\-\-max\-connections\fR N (500)
-Sets the maximum allowed connections
-.TP
-\fB\-\-connection\-backlog\fR N (10)
-Sets the connection backlog limit for
-the server socket
-.TP
-\fB\-m\fR [ \fB\-\-mgmt\-enable\fR ] yes|no (1)
-Enable Management
-.TP
-\fB\-\-mgmt\-qmf2\fR yes|no (1)
-Enable broadcast of management
-information over QMF v2
-.TP
-\fB\-\-mgmt\-qmf1\fR yes|no (1)
-Enable broadcast of management
-information over QMF v1
-.TP
-\fB\-\-mgmt\-pub\-interval\fR SECONDS (10)
-Management Publish Interval
-.TP
-\fB\-\-queue\-purge\-interval\fR SECONDS (600)
-Interval between attempts to purge any
-expired messages from queues
-.TP
-\fB\-\-auth\fR yes|no (1)
-Enable authentication, if disabled all
-incoming connections will be trusted
-.TP
-\fB\-\-realm\fR REALM (QPID)
-Use the given realm when performing
-authentication
-.TP
-\fB\-\-default\-queue\-limit\fR BYTES (104857600)
-Default maximum size for queues (in
-bytes)
-.TP
-\fB\-\-tcp\-nodelay\fR
-Set TCP_NODELAY on TCP connections
-.TP
-\fB\-\-require\-encryption\fR
-Only accept connections that are
-encrypted
-.TP
-\fB\-\-known\-hosts\-url\fR URL or 'none'
-URL to send as 'known\-hosts' to clients
-('none' implies empty list)
-.TP
-\fB\-\-sasl\-config\fR DIR
-gets sasl config info from nonstandard
-location
-.TP
-\fB\-\-max\-session\-rate\fR MESSAGES/S (0)
-Sets the maximum message rate per
-session (0=unlimited)
-.TP
-\fB\-\-async\-queue\-events\fR yes|no (0)
-Set Queue Events async, used for
-services like replication
-.TP
-\fB\-\-default\-flow\-stop\-threshold\fR PERCENT (80)
-Percent of queue's maximum capacity at
-which flow control is activated.
-.TP
-\fB\-\-default\-flow\-resume\-threshold\fR PERCENT (70)
-Percent of queue's maximum capacity at
-which flow control is de\-activated.
-.TP
-\fB\-\-default\-event\-threshold\-ratio\fR %age of limit (80)
-The ratio of any specified queue limit
-at which an event will be raised
-.SS "Logging options:"
-.TP
-\fB\-t\fR [ \fB\-\-trace\fR ]
-Enables all logging
-.TP
-\fB\-\-log\-enable\fR RULE (notice+)
-Enables logging for selected levels and
-components. RULE is in the form
-\&'LEVEL[+][:PATTERN]' Levels are one of:
-.IP
-trace debug info notice warning error
-.IP
-critical
-For example:
-\&'\-\-log\-enable warning+' logs all
-warning, error and critical messages.
-\&'\-\-log\-enable debug:framing' logs debug
-messages from the framing namespace.
-This option can be used multiple times
-.TP
-\fB\-\-log\-time\fR yes|no (1)
-Include time in log messages
-.TP
-\fB\-\-log\-level\fR yes|no (1)
-Include severity level in log messages
-.TP
-\fB\-\-log\-source\fR yes|no (0)
-Include source file:line in log
-messages
-.TP
-\fB\-\-log\-thread\fR yes|no (0)
-Include thread ID in log messages
-.TP
-\fB\-\-log\-function\fR yes|no (0)
-Include function signature in log
-messages
-.TP
-\fB\-\-log\-prefix\fR STRING
-Prefix to append to all log messages
-.SS "Logging sink options:"
-.TP
-\fB\-\-log\-to\-stderr\fR yes|no (1)
-Send logging output to stderr
-.TP
-\fB\-\-log\-to\-stdout\fR yes|no (0)
-Send logging output to stdout
-.TP
-\fB\-\-log\-to\-file\fR FILE
-Send log output to FILE.
-.TP
-\fB\-\-log\-to\-syslog\fR yes|no (0)
-Send logging output to syslog;
-customize using \fB\-\-syslog\-name\fR and
-\fB\-\-syslog\-facility\fR
-.TP
-\fB\-\-syslog\-name\fR NAME (lt\-qpidd)
-Name to use in syslog messages
-.TP
-\fB\-\-syslog\-facility\fR LOG_XXX (LOG_DAEMON)
-Facility to use in syslog messages
-.SS "Daemon options:"
-.TP
-\fB\-d\fR [ \fB\-\-daemon\fR ]
-Run as a daemon. Logs to syslog by
-default in this mode.
-.TP
-\fB\-\-transport\fR TRANSPORT (tcp)
-The transport for which to return the
-port
-.TP
-\fB\-\-pid\-dir\fR DIR
-Directory where port\-specific PID file
-is stored
-.TP
-\fB\-w\fR [ \fB\-\-wait\fR ] SECONDS (600)
-Sets the maximum wait time to
-initialize the daemon. If the daemon
-fails to initialize, prints an error
-and returns 1
-.TP
-\fB\-c\fR [ \fB\-\-check\fR ]
-Prints the daemon's process ID to
-stdout and returns 0 if the daemon is
-running, otherwise returns 1
-.TP
-\fB\-q\fR [ \fB\-\-quit\fR ]
-Tells the daemon to shut down
-.SH ENVIRONMENT
-.I QPID_<option>
-.RS
-There is an environment variable for each option.
-.RE
-
-The environment variable is the option name in uppercase, prefixed with QPID_ and '.' or '-' are replaced with '_'. Environment settings are over-ridden by command line settings. For example:
-
- export QPID_PORT=6000
- export QPID_MAX_CONNECTIONS=10
- export QPID_LOG_TO_FILE=/tmp/qpidd.log
-.SH FILES
-.I /etc/qpidd.conf
-.RS
-Default configuration file.
-.RE
-
-Configuration file settings are over-ridden by command line or environment variable settings. '--config <file>' or 'export QPID_CONFIG=<file>' specifies an alternate file.
-
-Each line is a name=value pair. Blank lines and lines beginning with # are ignored. For example:
-
- # My qpidd configuration file.
- port=6000
- max-connections=10
- log-to-file=/tmp/qpidd.log
-.SH AUTHOR
-
-The Apache Qpid Project, dev@qpid.apache.org
-.SH "REPORTING BUGS"
-
-Please report bugs to users@qpid.apache.org
diff --git a/qpid/cpp/docs/man/qpidd.x b/qpid/cpp/docs/man/qpidd.x
index 0ccf3b562a..af5d9628ee 100644
--- a/qpid/cpp/docs/man/qpidd.x
+++ b/qpid/cpp/docs/man/qpidd.x
@@ -13,8 +13,6 @@ messages using the Advanced Message Queueing Protocol (AMQP).
[OPTIONS]
-The options below are built-in to qpidd. Installing add-on modules provides additional options. To see the full set of options available type "qpidd --help"
-
Options may be specified via command line, environment variable or configuration file. See FILES and ENVIRONMENT below for details.
[FILES]
diff --git a/qpid/cpp/etc/Makefile.am b/qpid/cpp/etc/Makefile.am
index 1e4db561a7..c91dbcbbad 100644
--- a/qpid/cpp/etc/Makefile.am
+++ b/qpid/cpp/etc/Makefile.am
@@ -30,7 +30,30 @@ nobase_sysconf_DATA = \
qpidd.conf
if HAVE_SASL
+SASL_DB = qpidd.sasldb
+
nobase_sysconf_DATA += \
$(SASL_CONF)
+sasldbdir = $(localstatedir)/lib/qpidd
+sasldb_DATA = $(SASL_DB)
+
+# Setup the default sasldb file with a single user, guest, with an
+# obvious password. This user and password are the default for many
+# clients.
+#
+# The realm specified by -u is very important, and QPID is the default
+# for the broker so we use it here. The realm is important because it
+# defaults to the local hostname of the machine running the
+# broker. This may not seem to bad at first glance, but it means that
+# the sasldb has to be tailored to each machine that would be running
+# a broker, and if the machine ever changed its name the
+# authentication would stop working until the sasldb was updated. For
+# these reasons we always want the broker to specify a realm where its
+# users live, and we want the users to exist in that realm as well.
+$(SASL_DB):
+ echo guest | $(SASL_PASSWD) -c -p -f $(SASL_DB) -u QPID guest
+
+CLEANFILES=$(SASL_DB)
+
endif
diff --git a/qpid/cpp/etc/qpidd.conf b/qpid/cpp/etc/qpidd.conf
index bfe4e38bbd..8082660f6f 100644
--- a/qpid/cpp/etc/qpidd.conf
+++ b/qpid/cpp/etc/qpidd.conf
@@ -21,4 +21,4 @@
#
# (Note: no spaces on either side of '='). Using default settings:
# "qpidd --help" or "man qpidd" for more details.
-cluster-mechanism=DIGEST-MD5 ANONYMOUS
+cluster-mechanism=ANONYMOUS
diff --git a/qpid/cpp/etc/sasl2/qpidd.conf b/qpid/cpp/etc/sasl2/qpidd.conf
index d766cb8ef8..3197d7792a 100644
--- a/qpid/cpp/etc/sasl2/qpidd.conf
+++ b/qpid/cpp/etc/sasl2/qpidd.conf
@@ -17,8 +17,8 @@
# under the License.
#
#
-# This configuation allows for either SASL ANONYMOUS or DIGEST-MD5
-# authentication. The DIGEST-MD5 authentication is done on a
+# This configuation allows for either SASL PLAIN or ANONYMOUS
+# authentication. The PLAIN authentication is done on a
# username+password, which is stored in the sasldb_path
# file. Usernames and passwords can be added to the file using the
# command:
@@ -39,7 +39,6 @@
pwcheck_method: auxprop
auxprop_plugin: sasldb
sasldb_path: /var/lib/qpidd/qpidd.sasldb
-mech_list: DIGEST-MD5 ANONYMOUS
#following line stops spurious 'sql_select option missing' errors when
#cyrus-sql-sasl plugin is installed
diff --git a/qpid/cpp/examples/CMakeLists.txt b/qpid/cpp/examples/CMakeLists.txt
index 1b28cfd031..da8e39e944 100644
--- a/qpid/cpp/examples/CMakeLists.txt
+++ b/qpid/cpp/examples/CMakeLists.txt
@@ -77,14 +77,25 @@ macro(add_example subdir example)
endmacro(add_example)
install (FILES ${CMAKE_CURRENT_SOURCE_DIR}/README.txt
+ ${CMAKE_CURRENT_SOURCE_DIR}/README.verify
+ ${CMAKE_CURRENT_SOURCE_DIR}/verify
+ ${CMAKE_CURRENT_SOURCE_DIR}/verify_all
DESTINATION ${QPID_INSTALL_EXAMPLESDIR}
COMPONENT ${QPID_COMPONENT_EXAMPLES})
if (MSVC)
install (FILES ${CMAKE_CURRENT_SOURCE_DIR}/examples.sln
+ ${CMAKE_CURRENT_SOURCE_DIR}/old-examples.sln
DESTINATION ${QPID_INSTALL_EXAMPLESDIR}
COMPONENT ${QPID_COMPONENT_EXAMPLES})
endif (MSVC)
+add_subdirectory(direct)
+add_subdirectory(failover)
+add_subdirectory(fanout)
+add_subdirectory(pub-sub)
+#add_subdirectory(qmf-agent)
add_subdirectory(qmf-console)
+add_subdirectory(request-response)
+add_subdirectory(tradedemo)
+add_subdirectory(xml-exchange)
add_subdirectory(messaging)
-add_subdirectory(old_api)
diff --git a/qpid/cpp/examples/Makefile.am b/qpid/cpp/examples/Makefile.am
index 6b2bb73587..c6cc308d98 100644
--- a/qpid/cpp/examples/Makefile.am
+++ b/qpid/cpp/examples/Makefile.am
@@ -16,7 +16,15 @@
# specific language governing permissions and limitations
# under the License.
#
-SUBDIRS = qmf-console messaging old_api
+SUBDIRS = direct fanout pub-sub request-response failover qmf-console tradedemo messaging
+if HAVE_XML
+ SUBDIRS += xml-exchange
+ broker_args = "--no-module-dir --data-dir \"\" --auth no --load-module $(top_builddir)/src/.libs/xml.so"
+endif
+if !HAVE_XML
+ exclude_examples_regexp="xml" # Exclude XML examples.
+ broker_args = "--no-module-dir --data-dir \"\" --auth no"
+endif
MAKEDIST=.libs/Makefile
@@ -29,9 +37,13 @@ $(MAKEDIST): Makefile
examplesdir=$(pkgdatadir)/examples
dist_examples_DATA = README.txt $(MAKEDIST)
-EXTRA_DIST = examples.sln CMakeLists.txt
+EXTRA_DIST = README.verify verify verify_all examples.sln CMakeLists.txt
# For older versions of automake
abs_top_srcdir = @abs_top_srcdir@
abs_top_builddir = @abs_top_builddir@
+# Verify the examples in the buid tree.
+check-local:
+ $(srcdir)/verify_all $(abs_top_srcdir)/.. $(abs_top_builddir) $(broker_args) $(exclude_examples_regexp)
+
diff --git a/qpid/cpp/examples/old_api/README.verify b/qpid/cpp/examples/README.verify
index e1370764c9..e1370764c9 100644
--- a/qpid/cpp/examples/old_api/README.verify
+++ b/qpid/cpp/examples/README.verify
diff --git a/qpid/cpp/examples/old_api/direct/CMakeLists.txt b/qpid/cpp/examples/direct/CMakeLists.txt
index 2ec1b2b813..2ec1b2b813 100644
--- a/qpid/cpp/examples/old_api/direct/CMakeLists.txt
+++ b/qpid/cpp/examples/direct/CMakeLists.txt
diff --git a/qpid/cpp/examples/direct/Makefile.am b/qpid/cpp/examples/direct/Makefile.am
new file mode 100644
index 0000000000..b07db2cfd6
--- /dev/null
+++ b/qpid/cpp/examples/direct/Makefile.am
@@ -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.
+#
+examplesdir=$(pkgdatadir)/examples/direct
+
+MAKELDFLAGS=$(CLIENTFLAGS)
+include $(top_srcdir)/examples/makedist.mk
+
+noinst_PROGRAMS=direct_producer listener declare_queues
+direct_producer_SOURCES=direct_producer.cpp
+direct_producer_LDADD=$(CLIENT_LIB)
+
+listener_SOURCES=listener.cpp
+listener_LDADD=$(CLIENT_LIB)
+
+declare_queues_SOURCES=declare_queues.cpp
+declare_queues_LDADD=$(CLIENT_LIB)
+
+examples_DATA= \
+ direct_producer.cpp \
+ listener.cpp \
+ declare_queues.cpp \
+ $(MAKEDIST)
+
+EXTRA_DIST= \
+ $(examples_DATA) \
+ CMakeLists.txt \
+ verify \
+ verify.in \
+ direct_declare_queues.vcproj \
+ direct_direct_producer.vcproj \
+ direct_listener.vcproj
diff --git a/qpid/cpp/examples/old_api/direct/declare_queues.cpp b/qpid/cpp/examples/direct/declare_queues.cpp
index 9a51d1982b..9a51d1982b 100644
--- a/qpid/cpp/examples/old_api/direct/declare_queues.cpp
+++ b/qpid/cpp/examples/direct/declare_queues.cpp
diff --git a/qpid/cpp/examples/old_api/direct/direct_declare_queues.vcproj b/qpid/cpp/examples/direct/direct_declare_queues.vcproj
index 083474b9ef..083474b9ef 100644
--- a/qpid/cpp/examples/old_api/direct/direct_declare_queues.vcproj
+++ b/qpid/cpp/examples/direct/direct_declare_queues.vcproj
diff --git a/qpid/cpp/examples/old_api/direct/direct_direct_producer.vcproj b/qpid/cpp/examples/direct/direct_direct_producer.vcproj
index f091fbf291..f091fbf291 100644
--- a/qpid/cpp/examples/old_api/direct/direct_direct_producer.vcproj
+++ b/qpid/cpp/examples/direct/direct_direct_producer.vcproj
diff --git a/qpid/cpp/examples/old_api/direct/direct_listener.vcproj b/qpid/cpp/examples/direct/direct_listener.vcproj
index dce1d3ec28..dce1d3ec28 100644
--- a/qpid/cpp/examples/old_api/direct/direct_listener.vcproj
+++ b/qpid/cpp/examples/direct/direct_listener.vcproj
diff --git a/qpid/cpp/examples/old_api/direct/direct_producer.cpp b/qpid/cpp/examples/direct/direct_producer.cpp
index ecc9675189..ecc9675189 100644
--- a/qpid/cpp/examples/old_api/direct/direct_producer.cpp
+++ b/qpid/cpp/examples/direct/direct_producer.cpp
diff --git a/qpid/cpp/examples/old_api/direct/listener.cpp b/qpid/cpp/examples/direct/listener.cpp
index 38bf24ec41..38bf24ec41 100644
--- a/qpid/cpp/examples/old_api/direct/listener.cpp
+++ b/qpid/cpp/examples/direct/listener.cpp
diff --git a/qpid/cpp/examples/old_api/direct/verify b/qpid/cpp/examples/direct/verify
index f598bacc1f..f598bacc1f 100644
--- a/qpid/cpp/examples/old_api/direct/verify
+++ b/qpid/cpp/examples/direct/verify
diff --git a/qpid/cpp/examples/old_api/direct/verify.in b/qpid/cpp/examples/direct/verify.in
index d1e95f1151..d1e95f1151 100644
--- a/qpid/cpp/examples/old_api/direct/verify.in
+++ b/qpid/cpp/examples/direct/verify.in
diff --git a/qpid/cpp/examples/examples.sln b/qpid/cpp/examples/examples.sln
index 6f96105d97..8511fe3cce 100644
--- a/qpid/cpp/examples/examples.sln
+++ b/qpid/cpp/examples/examples.sln
@@ -32,14 +32,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "messaging_drain", "messagin
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "messaging_spout", "messaging\messaging_spout.vcproj", "{D3115AC9-91C4-4D79-BCAC-DE837C70F1EA}"
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", "{C1FFDE95-3442-49AE-9985-7EEE3D45B4A3}"
-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
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
@@ -96,22 +88,6 @@ Global
{D3115AC9-91C4-4D79-BCAC-DE837C70F1EA}.Release|Win32.Build.0 = Release|Win32
{D3115AC9-91C4-4D79-BCAC-DE837C70F1EA}.Release|x64.ActiveCfg = Release|x64
{D3115AC9-91C4-4D79-BCAC-DE837C70F1EA}.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}.Release|Win32.ActiveCfg = Release|Win32
- {490473E1-FECA-1BAD-2E13-3FFA2B8669C3}.Release|Win32.Build.0 = Release|Win32
- {C1FFDE95-3442-49AE-9985-7EEE3D45B4A3}.Debug|Win32.ActiveCfg = Debug|Win32
- {C1FFDE95-3442-49AE-9985-7EEE3D45B4A3}.Debug|Win32.Build.0 = Debug|Win32
- {C1FFDE95-3442-49AE-9985-7EEE3D45B4A3}.Release|Win32.ActiveCfg = Release|Win32
- {C1FFDE95-3442-49AE-9985-7EEE3D45B4A3}.Release|Win32.Build.0 = Release|Win32
- {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}.Release|Win32.ActiveCfg = Release|Win32
- {72C74624-FECA-1BAD-2E13-3FFA2B8669C3}.Release|Win32.Build.0 = Release|Win32
- {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}.Release|Win32.ActiveCfg = Release|Win32
- {B21825EA-FECA-1BAD-2E13-3FFA2B8669C3}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/qpid/cpp/examples/old_api/failover/CMakeLists.txt b/qpid/cpp/examples/failover/CMakeLists.txt
index 05db8fad51..05db8fad51 100644
--- a/qpid/cpp/examples/old_api/failover/CMakeLists.txt
+++ b/qpid/cpp/examples/failover/CMakeLists.txt
diff --git a/qpid/cpp/examples/failover/Makefile.am b/qpid/cpp/examples/failover/Makefile.am
new file mode 100644
index 0000000000..48846fdf79
--- /dev/null
+++ b/qpid/cpp/examples/failover/Makefile.am
@@ -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.
+#
+examplesdir=$(pkgdatadir)/examples/failover
+
+MAKELDFLAGS=$(CLIENTFLAGS)
+include $(top_srcdir)/examples/makedist.mk
+
+noinst_PROGRAMS=declare_queues resuming_receiver replaying_sender
+
+declare_queues_SOURCES=declare_queues.cpp
+declare_queues_LDADD=$(CLIENT_LIB)
+
+resuming_receiver_SOURCES=resuming_receiver.cpp
+resuming_receiver_LDADD=$(CLIENT_LIB)
+
+replaying_sender_SOURCES=replaying_sender.cpp
+replaying_sender_LDADD=$(CLIENT_LIB)
+
+examples_DATA= \
+ declare_queues.cpp \
+ resuming_receiver.cpp \
+ replaying_sender.cpp \
+ $(MAKEDIST)
+
+# FIXME aconway 2008-10-10: add verify scripts.
+
+EXTRA_DIST= \
+ CMakeLists.txt \
+ failover_declare_queues.vcproj \
+ failover_replaying_sender.vcproj \
+ failover_resuming_receiver.vcproj
diff --git a/qpid/cpp/examples/old_api/failover/declare_queues.cpp b/qpid/cpp/examples/failover/declare_queues.cpp
index a677870c53..a677870c53 100644
--- a/qpid/cpp/examples/old_api/failover/declare_queues.cpp
+++ b/qpid/cpp/examples/failover/declare_queues.cpp
diff --git a/qpid/cpp/examples/old_api/failover/failover_declare_queues.vcproj b/qpid/cpp/examples/failover/failover_declare_queues.vcproj
index c87c72affd..c87c72affd 100644
--- a/qpid/cpp/examples/old_api/failover/failover_declare_queues.vcproj
+++ b/qpid/cpp/examples/failover/failover_declare_queues.vcproj
diff --git a/qpid/cpp/examples/old_api/failover/failover_replaying_sender.vcproj b/qpid/cpp/examples/failover/failover_replaying_sender.vcproj
index 6d22fa6770..6d22fa6770 100644
--- a/qpid/cpp/examples/old_api/failover/failover_replaying_sender.vcproj
+++ b/qpid/cpp/examples/failover/failover_replaying_sender.vcproj
diff --git a/qpid/cpp/examples/old_api/failover/failover_resuming_receiver.vcproj b/qpid/cpp/examples/failover/failover_resuming_receiver.vcproj
index ba5061e248..ba5061e248 100644
--- a/qpid/cpp/examples/old_api/failover/failover_resuming_receiver.vcproj
+++ b/qpid/cpp/examples/failover/failover_resuming_receiver.vcproj
diff --git a/qpid/cpp/examples/old_api/failover/replaying_sender.cpp b/qpid/cpp/examples/failover/replaying_sender.cpp
index 22a7e1ebd3..22a7e1ebd3 100644
--- a/qpid/cpp/examples/old_api/failover/replaying_sender.cpp
+++ b/qpid/cpp/examples/failover/replaying_sender.cpp
diff --git a/qpid/cpp/examples/old_api/failover/resuming_receiver.cpp b/qpid/cpp/examples/failover/resuming_receiver.cpp
index d1886ce861..d1886ce861 100644
--- a/qpid/cpp/examples/old_api/failover/resuming_receiver.cpp
+++ b/qpid/cpp/examples/failover/resuming_receiver.cpp
diff --git a/qpid/cpp/examples/old_api/fanout/CMakeLists.txt b/qpid/cpp/examples/fanout/CMakeLists.txt
index 3f89d67650..3f89d67650 100644
--- a/qpid/cpp/examples/old_api/fanout/CMakeLists.txt
+++ b/qpid/cpp/examples/fanout/CMakeLists.txt
diff --git a/qpid/cpp/examples/fanout/Makefile.am b/qpid/cpp/examples/fanout/Makefile.am
new file mode 100644
index 0000000000..6e2e821eae
--- /dev/null
+++ b/qpid/cpp/examples/fanout/Makefile.am
@@ -0,0 +1,42 @@
+#
+# 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.
+#
+examplesdir=$(pkgdatadir)/examples/fanout
+
+MAKELDFLAGS=$(CLIENTFLAGS)
+include $(top_srcdir)/examples/makedist.mk
+
+noinst_PROGRAMS=fanout_producer listener
+fanout_producer_SOURCES=fanout_producer.cpp
+fanout_producer_LDADD=$(CLIENT_LIB)
+
+listener_SOURCES=listener.cpp
+listener_LDADD=$(CLIENT_LIB)
+
+examples_DATA= \
+ fanout_producer.cpp \
+ listener.cpp \
+ $(MAKEDIST)
+
+EXTRA_DIST= \
+ $(examples_DATA) \
+ CMakeLists.txt \
+ verify \
+ verify.in \
+ fanout_fanout_producer.vcproj \
+ fanout_listener.vcproj
diff --git a/qpid/cpp/examples/old_api/fanout/fanout_fanout_producer.vcproj b/qpid/cpp/examples/fanout/fanout_fanout_producer.vcproj
index daff5f3cf0..daff5f3cf0 100644
--- a/qpid/cpp/examples/old_api/fanout/fanout_fanout_producer.vcproj
+++ b/qpid/cpp/examples/fanout/fanout_fanout_producer.vcproj
diff --git a/qpid/cpp/examples/old_api/fanout/fanout_listener.vcproj b/qpid/cpp/examples/fanout/fanout_listener.vcproj
index f0e91b7dc6..f0e91b7dc6 100644
--- a/qpid/cpp/examples/old_api/fanout/fanout_listener.vcproj
+++ b/qpid/cpp/examples/fanout/fanout_listener.vcproj
diff --git a/qpid/cpp/examples/old_api/fanout/fanout_producer.cpp b/qpid/cpp/examples/fanout/fanout_producer.cpp
index decd4d314d..decd4d314d 100644
--- a/qpid/cpp/examples/old_api/fanout/fanout_producer.cpp
+++ b/qpid/cpp/examples/fanout/fanout_producer.cpp
diff --git a/qpid/cpp/examples/old_api/fanout/listener.cpp b/qpid/cpp/examples/fanout/listener.cpp
index cd3071c29a..cd3071c29a 100644
--- a/qpid/cpp/examples/old_api/fanout/listener.cpp
+++ b/qpid/cpp/examples/fanout/listener.cpp
diff --git a/qpid/cpp/examples/old_api/fanout/verify b/qpid/cpp/examples/fanout/verify
index 2eaadff56b..2eaadff56b 100644
--- a/qpid/cpp/examples/old_api/fanout/verify
+++ b/qpid/cpp/examples/fanout/verify
diff --git a/qpid/cpp/examples/old_api/fanout/verify.in b/qpid/cpp/examples/fanout/verify.in
index 8f8612ce67..8f8612ce67 100644
--- a/qpid/cpp/examples/old_api/fanout/verify.in
+++ b/qpid/cpp/examples/fanout/verify.in
diff --git a/qpid/cpp/examples/messaging/drain.cpp b/qpid/cpp/examples/messaging/drain.cpp
index 7700244fa8..5c938e9742 100644
--- a/qpid/cpp/examples/messaging/drain.cpp
+++ b/qpid/cpp/examples/messaging/drain.cpp
@@ -50,7 +50,7 @@ struct Options : OptionParser
add("broker,b", url, "url of broker to connect to");
add("timeout,t", timeout, "timeout in seconds to wait before exiting");
add("forever,f", forever, "ignore timeout and wait forever");
- add("connection-options", connectionOptions, "connection options string in the form {name1:value1, name2:value2}");
+ add("connection-options", connectionOptions, "connection options string in the form {name1=value1, name2=value2}");
add("count,c", count, "number of messages to read before exiting");
}
diff --git a/qpid/cpp/examples/messaging/server.cpp b/qpid/cpp/examples/messaging/server.cpp
index aa271d91f9..ab72694c61 100644
--- a/qpid/cpp/examples/messaging/server.cpp
+++ b/qpid/cpp/examples/messaging/server.cpp
@@ -39,8 +39,8 @@ using std::string;
int main(int argc, char** argv) {
const char* url = argc>1 ? argv[1] : "amqp:tcp:127.0.0.1:5672";
- std::string connectionOptions = argc > 2 ? argv[2] : "";
-
+ std::string connectionOptions = argc > 3 ? argv[3] : "";
+
Connection connection(url, connectionOptions);
try {
connection.open();
diff --git a/qpid/cpp/examples/messaging/spout.cpp b/qpid/cpp/examples/messaging/spout.cpp
index cd11a7ad81..57b955c1de 100644
--- a/qpid/cpp/examples/messaging/spout.cpp
+++ b/qpid/cpp/examples/messaging/spout.cpp
@@ -65,7 +65,7 @@ struct Options : OptionParser
add("property,P", properties, "specify message property");
add("map,M", entries, "specify entry for map content");
add("content", content, "specify textual content");
- add("connection-options", connectionOptions, "connection options string in the form {name1:value1, name2:value2}");
+ add("connection-options", connectionOptions, "connection options string in the form {name1=value1, name2=value2}");
}
static bool nameval(const std::string& in, std::string& name, std::string& value)
diff --git a/qpid/cpp/examples/old-examples.sln b/qpid/cpp/examples/old-examples.sln
new file mode 100644
index 0000000000..7f2fa3e8b0
--- /dev/null
+++ b/qpid/cpp/examples/old-examples.sln
@@ -0,0 +1,147 @@
+Microsoft Visual Studio Solution File, Format Version 10.00
+# Visual Studio 2008
+#
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License
+#
+#
+Project("{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", "{C1FFDE95-3442-49AE-9985-7EEE3D45B4A3}"
+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
+ Release|Win32 = Release|Win32
+ 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}.Release|Win32.ActiveCfg = Release|Win32
+ {18165D4D-FECA-1BAD-4346-8C4DF2536AA5}.Release|Win32.Build.0 = Release|Win32
+ {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}.Release|Win32.ActiveCfg = Release|Win32
+ {9701E0BD-FECA-1BAD-4346-8C4DF2536AA5}.Release|Win32.Build.0 = Release|Win32
+ {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}.Release|Win32.ActiveCfg = Release|Win32
+ {95CE1459-FECA-1BAD-4346-8C4DF2536AA5}.Release|Win32.Build.0 = Release|Win32
+ {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}.Release|Win32.ActiveCfg = Release|Win32
+ {7817898E-FECA-1BAD-8026-8D997AD361D0}.Release|Win32.Build.0 = Release|Win32
+ {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}.Release|Win32.ActiveCfg = Release|Win32
+ {085D6A66-FECA-1BAD-8026-8D997AD361D0}.Release|Win32.Build.0 = Release|Win32
+ {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}.Release|Win32.ActiveCfg = Release|Win32
+ {B0DAF702-FECA-1BAD-8026-8D997AD361D0}.Release|Win32.Build.0 = Release|Win32
+ {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}.Release|Win32.ActiveCfg = Release|Win32
+ {972AB76B-FECA-1BAD-8826-8C64F27AA1C5}.Release|Win32.Build.0 = Release|Win32
+ {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}.Release|Win32.ActiveCfg = Release|Win32
+ {95E7DF39-FECA-1BAD-8826-8C64F27AA1C5}.Release|Win32.Build.0 = Release|Win32
+ {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}.Release|Win32.ActiveCfg = Release|Win32
+ {A415E66A-FECA-1BAD-A430-FD5330E23A2D}.Release|Win32.Build.0 = Release|Win32
+ {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}.Release|Win32.ActiveCfg = Release|Win32
+ {05158653-FECA-1BAD-A430-FD5330E23A2D}.Release|Win32.Build.0 = Release|Win32
+ {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}.Release|Win32.ActiveCfg = Release|Win32
+ {490473E1-FECA-1BAD-2E13-3FFA2B8669C3}.Release|Win32.Build.0 = Release|Win32
+ {C1FFDE95-3442-49AE-9985-7EEE3D45B4A3}.Debug|Win32.ActiveCfg = Debug|Win32
+ {C1FFDE95-3442-49AE-9985-7EEE3D45B4A3}.Debug|Win32.Build.0 = Debug|Win32
+ {C1FFDE95-3442-49AE-9985-7EEE3D45B4A3}.Release|Win32.ActiveCfg = Release|Win32
+ {C1FFDE95-3442-49AE-9985-7EEE3D45B4A3}.Release|Win32.Build.0 = Release|Win32
+ {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}.Release|Win32.ActiveCfg = Release|Win32
+ {72C74624-FECA-1BAD-2E13-3FFA2B8669C3}.Release|Win32.Build.0 = Release|Win32
+ {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}.Release|Win32.ActiveCfg = Release|Win32
+ {B21825EA-FECA-1BAD-2E13-3FFA2B8669C3}.Release|Win32.Build.0 = Release|Win32
+ {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}.Release|Win32.ActiveCfg = Release|Win32
+ {2691FE1E-FECA-1BAD-BD3A-8A467D0C5CCC}.Release|Win32.Build.0 = Release|Win32
+ {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}.Release|Win32.ActiveCfg = Release|Win32
+ {46817425-FECA-1BAD-BD3A-8A467D0C5CCC}.Release|Win32.Build.0 = Release|Win32
+ {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}.Release|Win32.ActiveCfg = Release|Win32
+ {9057502D-FECA-1BAD-23CE-CD4095BD3C8B}.Release|Win32.Build.0 = Release|Win32
+ {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}.Release|Win32.ActiveCfg = Release|Win32
+ {5A25F2CD-FECA-1BAD-23CE-CD4095BD3C8B}.Release|Win32.Build.0 = Release|Win32
+ {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}.Release|Win32.ActiveCfg = Release|Win32
+ {E614CC2C-FECA-1BAD-23CE-CD4095BD3C8B}.Release|Win32.Build.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/qpid/cpp/examples/old_api/CMakeLists.txt b/qpid/cpp/examples/old_api/CMakeLists.txt
deleted file mode 100644
index 701f9be860..0000000000
--- a/qpid/cpp/examples/old_api/CMakeLists.txt
+++ /dev/null
@@ -1,25 +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.
-#
-add_subdirectory(direct)
-add_subdirectory(failover)
-add_subdirectory(fanout)
-add_subdirectory(pub-sub)
-add_subdirectory(request-response)
-add_subdirectory(tradedemo)
-add_subdirectory(xml-exchange)
diff --git a/qpid/cpp/examples/old_api/Makefile.am b/qpid/cpp/examples/old_api/Makefile.am
deleted file mode 100644
index 04216ffa97..0000000000
--- a/qpid/cpp/examples/old_api/Makefile.am
+++ /dev/null
@@ -1,48 +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.
-#
-SUBDIRS = direct pub-sub fanout request-response failover tradedemo
-if HAVE_XML
- SUBDIRS += xml-exchange
- broker_args = "--no-module-dir --data-dir \"\" --auth no --load-module $(top_builddir)/src/.libs/xml.so"
-endif
-if !HAVE_XML
- exclude_examples_regexp="xml" # Exclude XML examples.
- broker_args = "--no-module-dir --data-dir \"\" --auth no"
-endif
-
-MAKEDIST=.libs/Makefile
-
-$(MAKEDIST): Makefile
- mkdir -p .libs
- @(echo 'all clean:' ; \
- echo ' for d in $(SUBDIRS) ; do $$(MAKE) -C $$$$d $$@ ; done' ; \
- ) > $(MAKEDIST)
-
-examplesdir=$(pkgdatadir)/examples/old_api
-dist_examples_DATA = $(MAKEDIST)
-EXTRA_DIST = README.verify verify verify_all CMakeLists.txt
-
-# For older versions of automake
-abs_top_srcdir = @abs_top_srcdir@
-abs_top_builddir = @abs_top_builddir@
-
-# Verify the examples in the buid tree.
-check-local:
- $(srcdir)/verify_all $(abs_top_srcdir)/.. $(abs_top_builddir) $(broker_args) $(exclude_examples_regexp)
-
diff --git a/qpid/cpp/examples/old_api/direct/Makefile.am b/qpid/cpp/examples/old_api/direct/Makefile.am
deleted file mode 100644
index 24f783fcc7..0000000000
--- a/qpid/cpp/examples/old_api/direct/Makefile.am
+++ /dev/null
@@ -1,47 +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.
-#
-examplesdir=$(pkgdatadir)/examples/old_api/direct
-
-MAKELDFLAGS=$(CLIENTFLAGS)
-include $(top_srcdir)/examples/makedist.mk
-
-noinst_PROGRAMS=direct_producer listener declare_queues
-direct_producer_SOURCES=direct_producer.cpp
-direct_producer_LDADD=$(CLIENT_LIB)
-
-listener_SOURCES=listener.cpp
-listener_LDADD=$(CLIENT_LIB)
-
-declare_queues_SOURCES=declare_queues.cpp
-declare_queues_LDADD=$(CLIENT_LIB)
-
-examples_DATA= \
- direct_producer.cpp \
- listener.cpp \
- declare_queues.cpp \
- $(MAKEDIST)
-
-EXTRA_DIST= \
- $(examples_DATA) \
- CMakeLists.txt \
- verify \
- verify.in \
- direct_declare_queues.vcproj \
- direct_direct_producer.vcproj \
- direct_listener.vcproj
diff --git a/qpid/cpp/examples/old_api/failover/Makefile.am b/qpid/cpp/examples/old_api/failover/Makefile.am
deleted file mode 100644
index 8b1da80f2c..0000000000
--- a/qpid/cpp/examples/old_api/failover/Makefile.am
+++ /dev/null
@@ -1,47 +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.
-#
-examplesdir=$(pkgdatadir)/examples/old_api/failover
-
-MAKELDFLAGS=$(CLIENTFLAGS)
-include $(top_srcdir)/examples/makedist.mk
-
-noinst_PROGRAMS=declare_queues resuming_receiver replaying_sender
-
-declare_queues_SOURCES=declare_queues.cpp
-declare_queues_LDADD=$(CLIENT_LIB)
-
-resuming_receiver_SOURCES=resuming_receiver.cpp
-resuming_receiver_LDADD=$(CLIENT_LIB)
-
-replaying_sender_SOURCES=replaying_sender.cpp
-replaying_sender_LDADD=$(CLIENT_LIB)
-
-examples_DATA= \
- declare_queues.cpp \
- resuming_receiver.cpp \
- replaying_sender.cpp \
- $(MAKEDIST)
-
-# FIXME aconway 2008-10-10: add verify scripts.
-
-EXTRA_DIST= \
- CMakeLists.txt \
- failover_declare_queues.vcproj \
- failover_replaying_sender.vcproj \
- failover_resuming_receiver.vcproj
diff --git a/qpid/cpp/examples/old_api/fanout/Makefile.am b/qpid/cpp/examples/old_api/fanout/Makefile.am
deleted file mode 100644
index 3ab43b0279..0000000000
--- a/qpid/cpp/examples/old_api/fanout/Makefile.am
+++ /dev/null
@@ -1,42 +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.
-#
-examplesdir=$(pkgdatadir)/examples/old_api/fanout
-
-MAKELDFLAGS=$(CLIENTFLAGS)
-include $(top_srcdir)/examples/makedist.mk
-
-noinst_PROGRAMS=fanout_producer listener
-fanout_producer_SOURCES=fanout_producer.cpp
-fanout_producer_LDADD=$(CLIENT_LIB)
-
-listener_SOURCES=listener.cpp
-listener_LDADD=$(CLIENT_LIB)
-
-examples_DATA= \
- fanout_producer.cpp \
- listener.cpp \
- $(MAKEDIST)
-
-EXTRA_DIST= \
- $(examples_DATA) \
- CMakeLists.txt \
- verify \
- verify.in \
- fanout_fanout_producer.vcproj \
- fanout_listener.vcproj
diff --git a/qpid/cpp/examples/old_api/old-examples.sln b/qpid/cpp/examples/old_api/old-examples.sln
deleted file mode 100644
index e6ec9a0d66..0000000000
--- a/qpid/cpp/examples/old_api/old-examples.sln
+++ /dev/null
@@ -1,123 +0,0 @@
-Microsoft Visual Studio Solution File, Format Version 10.00
-# Visual Studio 2008
-#
-#
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License. You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied. See the License for the
-# specific language governing permissions and limitations
-# under the License
-#
-#
-Project("{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}") = "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
- Release|Win32 = Release|Win32
- 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}.Release|Win32.ActiveCfg = Release|Win32
- {18165D4D-FECA-1BAD-4346-8C4DF2536AA5}.Release|Win32.Build.0 = Release|Win32
- {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}.Release|Win32.ActiveCfg = Release|Win32
- {9701E0BD-FECA-1BAD-4346-8C4DF2536AA5}.Release|Win32.Build.0 = Release|Win32
- {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}.Release|Win32.ActiveCfg = Release|Win32
- {95CE1459-FECA-1BAD-4346-8C4DF2536AA5}.Release|Win32.Build.0 = Release|Win32
- {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}.Release|Win32.ActiveCfg = Release|Win32
- {7817898E-FECA-1BAD-8026-8D997AD361D0}.Release|Win32.Build.0 = Release|Win32
- {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}.Release|Win32.ActiveCfg = Release|Win32
- {085D6A66-FECA-1BAD-8026-8D997AD361D0}.Release|Win32.Build.0 = Release|Win32
- {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}.Release|Win32.ActiveCfg = Release|Win32
- {B0DAF702-FECA-1BAD-8026-8D997AD361D0}.Release|Win32.Build.0 = Release|Win32
- {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}.Release|Win32.ActiveCfg = Release|Win32
- {972AB76B-FECA-1BAD-8826-8C64F27AA1C5}.Release|Win32.Build.0 = Release|Win32
- {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}.Release|Win32.ActiveCfg = Release|Win32
- {95E7DF39-FECA-1BAD-8826-8C64F27AA1C5}.Release|Win32.Build.0 = Release|Win32
- {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}.Release|Win32.ActiveCfg = Release|Win32
- {A415E66A-FECA-1BAD-A430-FD5330E23A2D}.Release|Win32.Build.0 = Release|Win32
- {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}.Release|Win32.ActiveCfg = Release|Win32
- {05158653-FECA-1BAD-A430-FD5330E23A2D}.Release|Win32.Build.0 = Release|Win32
- {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}.Release|Win32.ActiveCfg = Release|Win32
- {2691FE1E-FECA-1BAD-BD3A-8A467D0C5CCC}.Release|Win32.Build.0 = Release|Win32
- {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}.Release|Win32.ActiveCfg = Release|Win32
- {46817425-FECA-1BAD-BD3A-8A467D0C5CCC}.Release|Win32.Build.0 = Release|Win32
- {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}.Release|Win32.ActiveCfg = Release|Win32
- {9057502D-FECA-1BAD-23CE-CD4095BD3C8B}.Release|Win32.Build.0 = Release|Win32
- {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}.Release|Win32.ActiveCfg = Release|Win32
- {5A25F2CD-FECA-1BAD-23CE-CD4095BD3C8B}.Release|Win32.Build.0 = Release|Win32
- {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}.Release|Win32.ActiveCfg = Release|Win32
- {E614CC2C-FECA-1BAD-23CE-CD4095BD3C8B}.Release|Win32.Build.0 = Release|Win32
- EndGlobalSection
- GlobalSection(SolutionProperties) = preSolution
- HideSolutionNode = FALSE
- EndGlobalSection
-EndGlobal
diff --git a/qpid/cpp/examples/old_api/pub-sub/Makefile.am b/qpid/cpp/examples/old_api/pub-sub/Makefile.am
deleted file mode 100644
index 8f42ee0211..0000000000
--- a/qpid/cpp/examples/old_api/pub-sub/Makefile.am
+++ /dev/null
@@ -1,43 +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.
-#
-examplesdir=$(pkgdatadir)/examples/old_api/pub-sub
-
-MAKELDFLAGS=$(CLIENTFLAGS)
-include $(top_srcdir)/examples/makedist.mk
-
-noinst_PROGRAMS=topic_listener topic_publisher
-
-topic_listener_SOURCES=topic_listener.cpp
-topic_listener_LDADD=$(CLIENT_LIB)
-
-topic_publisher_SOURCES=topic_publisher.cpp
-topic_publisher_LDADD=$(CLIENT_LIB)
-
-examples_DATA= \
- topic_listener.cpp \
- topic_publisher.cpp \
- $(MAKEDIST)
-
-EXTRA_DIST= \
- $(examples_DATA) \
- CMakeLists.txt \
- verify \
- verify.in \
- pub-sub_topic_listener.vcproj \
- pub-sub_topic_publisher.vcproj
diff --git a/qpid/cpp/examples/old_api/request-response/Makefile.am b/qpid/cpp/examples/old_api/request-response/Makefile.am
deleted file mode 100644
index f48762da51..0000000000
--- a/qpid/cpp/examples/old_api/request-response/Makefile.am
+++ /dev/null
@@ -1,43 +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.
-#
-examplesdir=$(pkgdatadir)/examples/old_api/request-response
-
-MAKELDFLAGS=$(CLIENTFLAGS)
-include $(top_srcdir)/examples/makedist.mk
-
-noinst_PROGRAMS=client server
-
-client_SOURCES=client.cpp
-client_LDADD=$(CLIENT_LIB)
-
-server_SOURCES=server.cpp
-server_LDADD=$(CLIENT_LIB)
-
-examples_DATA= \
- server.cpp \
- client.cpp \
- $(MAKEDIST)
-
-EXTRA_DIST= \
- $(examples_DATA) \
- CMakeLists.txt \
- verify \
- verify.in \
- request-response_client.vcproj \
- request-response_server.vcproj
diff --git a/qpid/cpp/examples/old_api/tradedemo/Makefile.am b/qpid/cpp/examples/old_api/tradedemo/Makefile.am
deleted file mode 100644
index 445b15b367..0000000000
--- a/qpid/cpp/examples/old_api/tradedemo/Makefile.am
+++ /dev/null
@@ -1,46 +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.
-#
-examplesdir=$(pkgdatadir)/examples/old_api/tradedemo
-
-MAKELDFLAGS=$(CLIENTFLAGS)
-include $(top_srcdir)/examples/makedist.mk
-
-noinst_PROGRAMS=topic_listener topic_publisher declare_queues
-
-topic_listener_SOURCES=topic_listener.cpp
-topic_listener_LDADD=$(CLIENT_LIB)
-
-topic_publisher_SOURCES=topic_publisher.cpp
-topic_publisher_LDADD=$(CLIENT_LIB)
-
-declare_queues_SOURCES=declare_queues.cpp
-declare_queues_LDADD=$(CLIENT_LIB)
-
-
-examples_DATA= \
- topic_listener.cpp \
- topic_publisher.cpp \
- declare_queues.cpp \
- $(MAKEDIST)
-
-EXTRA_DIST= \
- CMakeLists.txt \
- tradedemo_declare_queues.vcproj \
- tradedemo_topic_listener.vcproj \
- tradedemo_topic_publisher.vcproj
diff --git a/qpid/cpp/examples/old_api/verify_all b/qpid/cpp/examples/old_api/verify_all
deleted file mode 100755
index fbe51377b6..0000000000
--- a/qpid/cpp/examples/old_api/verify_all
+++ /dev/null
@@ -1,46 +0,0 @@
-#!/bin/sh
-
-#
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License. You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied. See the License for the
-# specific language governing permissions and limitations
-# under the License.
-#
-
-# Verify all examples
-
-verify=`dirname $0`/verify
-topsrcdir=$1
-topbuilddir=$2
-qpidd=$topbuilddir/src/qpidd
-broker_args=$3
-exclude_regexp=$4
-
-trap "$qpidd -q" exit
-QPID_PORT=`$qpidd -dp0 $broker_args` || { echo "Can't run qpidd" ; exit 1; }
-export QPID_PORT
-
-find="find $topsrcdir/cpp/examples/old_api"
-find="$find -mindepth 2 -name verify"
-all_examples=`$find`
-
-if test -z "$exclude_regexp"; then
- run_examples=$all_examples
-else
- for f in $all_examples; do
- { echo $f | grep $exclude_regexp > /dev/null ; } || run_examples="$run_examples $f"
- done
-fi
-$verify $topsrcdir $topbuilddir $run_examples
diff --git a/qpid/cpp/examples/old_api/xml-exchange/Makefile.am b/qpid/cpp/examples/old_api/xml-exchange/Makefile.am
deleted file mode 100644
index 3e1082cdb2..0000000000
--- a/qpid/cpp/examples/old_api/xml-exchange/Makefile.am
+++ /dev/null
@@ -1,49 +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.
-#
-examplesdir=$(pkgdatadir)/examples/old_api/xml-exchange
-
-MAKELDFLAGS=$(CLIENTFLAGS)
-include $(top_srcdir)/examples/makedist.mk
-
-noinst_PROGRAMS=declare_queues xml_producer listener
-
-declare_queues_SOURCES=declare_queues.cpp
-declare_queues_LDADD=$(CLIENT_LIB)
-
-xml_producer_SOURCES=xml_producer.cpp
-xml_producer_LDADD=$(CLIENT_LIB)
-
-listener_SOURCES=listener.cpp
-listener_LDADD=$(CLIENT_LIB)
-
-EXTRA_DIST= \
- README.txt \
- CMakeLists.txt
-
-examples_DATA= \
- $(EXTRA_DIST) \
- declare_queues.cpp \
- listener.cpp \
- xml_producer.cpp \
- $(MAKEDIST)
-
-
-
-
-
diff --git a/qpid/cpp/examples/old_api/pub-sub/CMakeLists.txt b/qpid/cpp/examples/pub-sub/CMakeLists.txt
index 961de06d5a..961de06d5a 100644
--- a/qpid/cpp/examples/old_api/pub-sub/CMakeLists.txt
+++ b/qpid/cpp/examples/pub-sub/CMakeLists.txt
diff --git a/qpid/cpp/examples/pub-sub/Makefile.am b/qpid/cpp/examples/pub-sub/Makefile.am
new file mode 100644
index 0000000000..62658ebe94
--- /dev/null
+++ b/qpid/cpp/examples/pub-sub/Makefile.am
@@ -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.
+#
+examplesdir=$(pkgdatadir)/examples/pub-sub
+
+MAKELDFLAGS=$(CLIENTFLAGS)
+include $(top_srcdir)/examples/makedist.mk
+
+noinst_PROGRAMS=topic_listener topic_publisher
+
+topic_listener_SOURCES=topic_listener.cpp
+topic_listener_LDADD=$(CLIENT_LIB)
+
+topic_publisher_SOURCES=topic_publisher.cpp
+topic_publisher_LDADD=$(CLIENT_LIB)
+
+examples_DATA= \
+ topic_listener.cpp \
+ topic_publisher.cpp \
+ $(MAKEDIST)
+
+EXTRA_DIST= \
+ $(examples_DATA) \
+ CMakeLists.txt \
+ verify \
+ verify.in \
+ pub-sub_topic_listener.vcproj \
+ pub-sub_topic_publisher.vcproj
diff --git a/qpid/cpp/examples/old_api/pub-sub/pub-sub_topic_listener.vcproj b/qpid/cpp/examples/pub-sub/pub-sub_topic_listener.vcproj
index aa0b3bcaa3..aa0b3bcaa3 100644
--- a/qpid/cpp/examples/old_api/pub-sub/pub-sub_topic_listener.vcproj
+++ b/qpid/cpp/examples/pub-sub/pub-sub_topic_listener.vcproj
diff --git a/qpid/cpp/examples/old_api/pub-sub/pub-sub_topic_publisher.vcproj b/qpid/cpp/examples/pub-sub/pub-sub_topic_publisher.vcproj
index 76e51df4df..76e51df4df 100644
--- a/qpid/cpp/examples/old_api/pub-sub/pub-sub_topic_publisher.vcproj
+++ b/qpid/cpp/examples/pub-sub/pub-sub_topic_publisher.vcproj
diff --git a/qpid/cpp/examples/old_api/pub-sub/topic_listener.cpp b/qpid/cpp/examples/pub-sub/topic_listener.cpp
index d38a806303..d38a806303 100644
--- a/qpid/cpp/examples/old_api/pub-sub/topic_listener.cpp
+++ b/qpid/cpp/examples/pub-sub/topic_listener.cpp
diff --git a/qpid/cpp/examples/old_api/pub-sub/topic_publisher.cpp b/qpid/cpp/examples/pub-sub/topic_publisher.cpp
index aed5f8f033..aed5f8f033 100644
--- a/qpid/cpp/examples/old_api/pub-sub/topic_publisher.cpp
+++ b/qpid/cpp/examples/pub-sub/topic_publisher.cpp
diff --git a/qpid/cpp/examples/old_api/pub-sub/verify b/qpid/cpp/examples/pub-sub/verify
index 528d2f401e..528d2f401e 100644
--- a/qpid/cpp/examples/old_api/pub-sub/verify
+++ b/qpid/cpp/examples/pub-sub/verify
diff --git a/qpid/cpp/examples/old_api/pub-sub/verify.in b/qpid/cpp/examples/pub-sub/verify.in
index 6413c5c788..6413c5c788 100644
--- a/qpid/cpp/examples/old_api/pub-sub/verify.in
+++ b/qpid/cpp/examples/pub-sub/verify.in
diff --git a/qpid/cpp/examples/qmf-console/ping.cpp b/qpid/cpp/examples/qmf-console/ping.cpp
index e6d6d138d5..fe537d48d2 100644
--- a/qpid/cpp/examples/qmf-console/ping.cpp
+++ b/qpid/cpp/examples/qmf-console/ping.cpp
@@ -31,7 +31,9 @@ using namespace qpid::console;
int main_int(int /*argc*/, char** /*argv*/)
{
//
- // Declare connection settings for the messaging broker.
+ // Declare connection settings for the messaging broker. The settings default to
+ // localhost:5672 with user guest (password guest). Refer to the header file
+ // <qpid/client/ConnectionSettings.h> for full details.
//
qpid::client::ConnectionSettings connSettings;
diff --git a/qpid/cpp/examples/qmf-console/printevents.cpp b/qpid/cpp/examples/qmf-console/printevents.cpp
index ac3e449a2c..3a0a2ab68b 100644
--- a/qpid/cpp/examples/qmf-console/printevents.cpp
+++ b/qpid/cpp/examples/qmf-console/printevents.cpp
@@ -64,7 +64,9 @@ struct Main {
Listener listener;
//
- // Declare connection settings for the messaging broker.
+ // Declare connection settings for the messaging broker. The settings default to
+ // localhost:5672 with user guest (password guest). Refer to the header file
+ // <qpid/client/ConnectionSettings.h> for full details.
//
qpid::client::ConnectionSettings connSettings;
diff --git a/qpid/cpp/examples/old_api/request-response/CMakeLists.txt b/qpid/cpp/examples/request-response/CMakeLists.txt
index 873a0cfa86..873a0cfa86 100644
--- a/qpid/cpp/examples/old_api/request-response/CMakeLists.txt
+++ b/qpid/cpp/examples/request-response/CMakeLists.txt
diff --git a/qpid/cpp/examples/request-response/Makefile.am b/qpid/cpp/examples/request-response/Makefile.am
new file mode 100644
index 0000000000..48b3d989f0
--- /dev/null
+++ b/qpid/cpp/examples/request-response/Makefile.am
@@ -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.
+#
+examplesdir=$(pkgdatadir)/examples/request-response
+
+MAKELDFLAGS=$(CLIENTFLAGS)
+include $(top_srcdir)/examples/makedist.mk
+
+noinst_PROGRAMS=client server
+
+client_SOURCES=client.cpp
+client_LDADD=$(CLIENT_LIB)
+
+server_SOURCES=server.cpp
+server_LDADD=$(CLIENT_LIB)
+
+examples_DATA= \
+ server.cpp \
+ client.cpp \
+ $(MAKEDIST)
+
+EXTRA_DIST= \
+ $(examples_DATA) \
+ CMakeLists.txt \
+ verify \
+ verify.in \
+ request-response_client.vcproj \
+ request-response_server.vcproj
diff --git a/qpid/cpp/examples/old_api/request-response/client.cpp b/qpid/cpp/examples/request-response/client.cpp
index 679d1c5fc2..679d1c5fc2 100644
--- a/qpid/cpp/examples/old_api/request-response/client.cpp
+++ b/qpid/cpp/examples/request-response/client.cpp
diff --git a/qpid/cpp/examples/old_api/request-response/request-response_client.vcproj b/qpid/cpp/examples/request-response/request-response_client.vcproj
index 5f9eadde36..5f9eadde36 100644
--- a/qpid/cpp/examples/old_api/request-response/request-response_client.vcproj
+++ b/qpid/cpp/examples/request-response/request-response_client.vcproj
diff --git a/qpid/cpp/examples/old_api/request-response/request-response_server.vcproj b/qpid/cpp/examples/request-response/request-response_server.vcproj
index 54352b9f46..54352b9f46 100644
--- a/qpid/cpp/examples/old_api/request-response/request-response_server.vcproj
+++ b/qpid/cpp/examples/request-response/request-response_server.vcproj
diff --git a/qpid/cpp/examples/old_api/request-response/server.cpp b/qpid/cpp/examples/request-response/server.cpp
index 65a4717b35..65a4717b35 100644
--- a/qpid/cpp/examples/old_api/request-response/server.cpp
+++ b/qpid/cpp/examples/request-response/server.cpp
diff --git a/qpid/cpp/examples/old_api/request-response/verify b/qpid/cpp/examples/request-response/verify
index dee82413e7..dee82413e7 100644
--- a/qpid/cpp/examples/old_api/request-response/verify
+++ b/qpid/cpp/examples/request-response/verify
diff --git a/qpid/cpp/examples/old_api/request-response/verify.in b/qpid/cpp/examples/request-response/verify.in
index 7925dc5671..7925dc5671 100644
--- a/qpid/cpp/examples/old_api/request-response/verify.in
+++ b/qpid/cpp/examples/request-response/verify.in
diff --git a/qpid/cpp/examples/old_api/tradedemo/CMakeLists.txt b/qpid/cpp/examples/tradedemo/CMakeLists.txt
index e61fc1467d..e61fc1467d 100644
--- a/qpid/cpp/examples/old_api/tradedemo/CMakeLists.txt
+++ b/qpid/cpp/examples/tradedemo/CMakeLists.txt
diff --git a/qpid/cpp/examples/tradedemo/Makefile.am b/qpid/cpp/examples/tradedemo/Makefile.am
new file mode 100644
index 0000000000..f4d8686d05
--- /dev/null
+++ b/qpid/cpp/examples/tradedemo/Makefile.am
@@ -0,0 +1,46 @@
+#
+# 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.
+#
+examplesdir=$(pkgdatadir)/examples/tradedemo
+
+MAKELDFLAGS=$(CLIENTFLAGS)
+include $(top_srcdir)/examples/makedist.mk
+
+noinst_PROGRAMS=topic_listener topic_publisher declare_queues
+
+topic_listener_SOURCES=topic_listener.cpp
+topic_listener_LDADD=$(CLIENT_LIB)
+
+topic_publisher_SOURCES=topic_publisher.cpp
+topic_publisher_LDADD=$(CLIENT_LIB)
+
+declare_queues_SOURCES=declare_queues.cpp
+declare_queues_LDADD=$(CLIENT_LIB)
+
+
+examples_DATA= \
+ topic_listener.cpp \
+ topic_publisher.cpp \
+ declare_queues.cpp \
+ $(MAKEDIST)
+
+EXTRA_DIST= \
+ CMakeLists.txt \
+ tradedemo_declare_queues.vcproj \
+ tradedemo_topic_listener.vcproj \
+ tradedemo_topic_publisher.vcproj
diff --git a/qpid/cpp/examples/old_api/tradedemo/declare_queues.cpp b/qpid/cpp/examples/tradedemo/declare_queues.cpp
index b1f2cc3510..b1f2cc3510 100644
--- a/qpid/cpp/examples/old_api/tradedemo/declare_queues.cpp
+++ b/qpid/cpp/examples/tradedemo/declare_queues.cpp
diff --git a/qpid/cpp/examples/old_api/tradedemo/topic_listener.cpp b/qpid/cpp/examples/tradedemo/topic_listener.cpp
index c488e7fb69..c488e7fb69 100644
--- a/qpid/cpp/examples/old_api/tradedemo/topic_listener.cpp
+++ b/qpid/cpp/examples/tradedemo/topic_listener.cpp
diff --git a/qpid/cpp/examples/old_api/tradedemo/topic_publisher.cpp b/qpid/cpp/examples/tradedemo/topic_publisher.cpp
index e22c185bc7..e22c185bc7 100644
--- a/qpid/cpp/examples/old_api/tradedemo/topic_publisher.cpp
+++ b/qpid/cpp/examples/tradedemo/topic_publisher.cpp
diff --git a/qpid/cpp/examples/old_api/tradedemo/tradedemo_declare_queues.vcproj b/qpid/cpp/examples/tradedemo/tradedemo_declare_queues.vcproj
index 34b5cb3b2b..34b5cb3b2b 100644
--- a/qpid/cpp/examples/old_api/tradedemo/tradedemo_declare_queues.vcproj
+++ b/qpid/cpp/examples/tradedemo/tradedemo_declare_queues.vcproj
diff --git a/qpid/cpp/examples/old_api/tradedemo/tradedemo_topic_listener.vcproj b/qpid/cpp/examples/tradedemo/tradedemo_topic_listener.vcproj
index 965be2e88b..965be2e88b 100644
--- a/qpid/cpp/examples/old_api/tradedemo/tradedemo_topic_listener.vcproj
+++ b/qpid/cpp/examples/tradedemo/tradedemo_topic_listener.vcproj
diff --git a/qpid/cpp/examples/old_api/tradedemo/tradedemo_topic_publisher.vcproj b/qpid/cpp/examples/tradedemo/tradedemo_topic_publisher.vcproj
index 77fd511e15..77fd511e15 100644
--- a/qpid/cpp/examples/old_api/tradedemo/tradedemo_topic_publisher.vcproj
+++ b/qpid/cpp/examples/tradedemo/tradedemo_topic_publisher.vcproj
diff --git a/qpid/cpp/examples/old_api/verify b/qpid/cpp/examples/verify
index 9a1ed078d6..9a1ed078d6 100755
--- a/qpid/cpp/examples/old_api/verify
+++ b/qpid/cpp/examples/verify
diff --git a/qpid/cpp/examples/verify_all b/qpid/cpp/examples/verify_all
new file mode 100755
index 0000000000..cb4c5283fa
--- /dev/null
+++ b/qpid/cpp/examples/verify_all
@@ -0,0 +1,46 @@
+#!/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.
+#
+
+# Verify all examples
+
+verify=`dirname $0`/verify
+topsrcdir=$1
+topbuilddir=$2
+qpidd=$topbuilddir/src/qpidd
+broker_args=$3
+exclude_regexp=$4
+
+trap "$qpidd -q" exit
+QPID_PORT=`$qpidd -dp0 $broker_args` || { echo "Can't run qpidd" ; exit 1; }
+export QPID_PORT
+
+find="find $topsrcdir/cpp/examples"
+find="$find -mindepth 2 -name verify"
+all_examples=`$find`
+
+if test -z "$exclude_regexp"; then
+ run_examples=$all_examples
+else
+ for f in $all_examples; do
+ { echo $f | grep $exclude_regexp > /dev/null ; } || run_examples="$run_examples $f"
+ done
+fi
+$verify $topsrcdir $topbuilddir $run_examples
diff --git a/qpid/cpp/examples/old_api/xml-exchange/CMakeLists.txt b/qpid/cpp/examples/xml-exchange/CMakeLists.txt
index 3fea47a208..3fea47a208 100644
--- a/qpid/cpp/examples/old_api/xml-exchange/CMakeLists.txt
+++ b/qpid/cpp/examples/xml-exchange/CMakeLists.txt
diff --git a/qpid/cpp/examples/xml-exchange/Makefile.am b/qpid/cpp/examples/xml-exchange/Makefile.am
new file mode 100644
index 0000000000..9001e3fa61
--- /dev/null
+++ b/qpid/cpp/examples/xml-exchange/Makefile.am
@@ -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.
+#
+examplesdir=$(pkgdatadir)/examples/xml-exchange
+
+MAKELDFLAGS=$(CLIENTFLAGS)
+include $(top_srcdir)/examples/makedist.mk
+
+noinst_PROGRAMS=declare_queues xml_producer listener
+
+declare_queues_SOURCES=declare_queues.cpp
+declare_queues_LDADD=$(CLIENT_LIB)
+
+xml_producer_SOURCES=xml_producer.cpp
+xml_producer_LDADD=$(CLIENT_LIB)
+
+listener_SOURCES=listener.cpp
+listener_LDADD=$(CLIENT_LIB)
+
+EXTRA_DIST= \
+ README.txt \
+ CMakeLists.txt
+
+examples_DATA= \
+ $(EXTRA_DIST) \
+ declare_queues.cpp \
+ listener.cpp \
+ xml_producer.cpp \
+ $(MAKEDIST)
+
+
+
+
+
diff --git a/qpid/cpp/examples/old_api/xml-exchange/README.txt b/qpid/cpp/examples/xml-exchange/README.txt
index 85caebe352..85caebe352 100644
--- a/qpid/cpp/examples/old_api/xml-exchange/README.txt
+++ b/qpid/cpp/examples/xml-exchange/README.txt
diff --git a/qpid/cpp/examples/old_api/xml-exchange/declare_queues.cpp b/qpid/cpp/examples/xml-exchange/declare_queues.cpp
index ad08642019..ad08642019 100644
--- a/qpid/cpp/examples/old_api/xml-exchange/declare_queues.cpp
+++ b/qpid/cpp/examples/xml-exchange/declare_queues.cpp
diff --git a/qpid/cpp/examples/old_api/xml-exchange/listener.cpp b/qpid/cpp/examples/xml-exchange/listener.cpp
index 11bcb9f669..11bcb9f669 100644
--- a/qpid/cpp/examples/old_api/xml-exchange/listener.cpp
+++ b/qpid/cpp/examples/xml-exchange/listener.cpp
diff --git a/qpid/cpp/examples/old_api/xml-exchange/xml_producer.cpp b/qpid/cpp/examples/xml-exchange/xml_producer.cpp
index af1a7e60c7..af1a7e60c7 100644
--- a/qpid/cpp/examples/old_api/xml-exchange/xml_producer.cpp
+++ b/qpid/cpp/examples/xml-exchange/xml_producer.cpp
diff --git a/qpid/cpp/include/qmf/Agent.h b/qpid/cpp/include/qmf/Agent.h
index 94083be4f3..8c0f48b8b1 100644
--- a/qpid/cpp/include/qmf/Agent.h
+++ b/qpid/cpp/include/qmf/Agent.h
@@ -42,7 +42,7 @@ namespace qmf {
class SchemaId;
class Schema;
- class QMF_CLASS_EXTERN Agent : public qmf::Handle<AgentImpl> {
+ class Agent : public qmf::Handle<AgentImpl> {
public:
QMF_EXTERN Agent(AgentImpl* impl = 0);
QMF_EXTERN Agent(const Agent&);
diff --git a/qpid/cpp/include/qmf/AgentEvent.h b/qpid/cpp/include/qmf/AgentEvent.h
index 0f93a9bb0a..59a41c3267 100644
--- a/qpid/cpp/include/qmf/AgentEvent.h
+++ b/qpid/cpp/include/qmf/AgentEvent.h
@@ -46,7 +46,7 @@ namespace qmf {
AGENT_THREAD_FAILED = 8
};
- class QMF_CLASS_EXTERN AgentEvent : public qmf::Handle<AgentEventImpl> {
+ class AgentEvent : public qmf::Handle<AgentEventImpl> {
public:
QMF_EXTERN AgentEvent(AgentEventImpl* impl = 0);
QMF_EXTERN AgentEvent(const AgentEvent&);
diff --git a/qpid/cpp/include/qmf/AgentSession.h b/qpid/cpp/include/qmf/AgentSession.h
index 1eeb252143..9e29d6b54b 100644
--- a/qpid/cpp/include/qmf/AgentSession.h
+++ b/qpid/cpp/include/qmf/AgentSession.h
@@ -40,7 +40,7 @@ namespace qmf {
class Data;
class DataAddr;
- class QMF_CLASS_EXTERN AgentSession : public qmf::Handle<AgentSessionImpl> {
+ class AgentSession : public qmf::Handle<AgentSessionImpl> {
public:
QMF_EXTERN AgentSession(AgentSessionImpl* impl = 0);
QMF_EXTERN AgentSession(const AgentSession&);
@@ -72,14 +72,14 @@ namespace qmf {
* strict-security:{True,False} - If True: Cooperate with the broker to enforce strict access control to the network
* - If False: Operate more flexibly with regard to use of messaging facilities [default]
*/
- QMF_EXTERN AgentSession(qpid::messaging::Connection& conn, const std::string& options="");
+ QMF_EXTERN AgentSession(qpid::messaging::Connection&, const std::string& options="");
/**
* setDomain - Change the QMF domain that this agent will operate in. If this is not called,
* the domain will be "default". Agents in a domain can be seen only by consoles in the same domain.
* This must be called prior to opening the agent session.
*/
- QMF_EXTERN void setDomain(const std::string& domain);
+ QMF_EXTERN void setDomain(const std::string&);
/**
* Set identifying attributes of this agent.
@@ -88,16 +88,16 @@ namespace qmf {
* setInstance - Set the unique instance name (if not set, a UUID will be assigned)
* These must be called prior to opening the agent session.
*/
- QMF_EXTERN void setVendor(const std::string& vendor);
- QMF_EXTERN void setProduct(const std::string& product);
- QMF_EXTERN void setInstance(const std::string& instance);
+ QMF_EXTERN void setVendor(const std::string&);
+ QMF_EXTERN void setProduct(const std::string&);
+ QMF_EXTERN void setInstance(const std::string&);
/**
* setAttribute - Set an arbitrary attribute for this agent. The attributes are not used
* to uniquely identify the agent but can be used as a search criteria when looking for agents.
* This must be called prior to opening the agent session.
*/
- QMF_EXTERN void setAttribute(const std::string& key, const qpid::types::Variant& value);
+ QMF_EXTERN void setAttribute(const std::string&, const qpid::types::Variant&);
/**
* Get the identifying name of the agent.
@@ -119,19 +119,13 @@ namespace qmf {
* Get the next event from the agent session. Events represent actions that must be acted upon by the
* agent application. This method blocks for up to the timeout if there are no events to be handled.
* This method will typically be the focus of the agent application's main execution loop.
- * If the timeout is set to Duration::IMMEDIATE, the call will not block.
*/
- QMF_EXTERN bool nextEvent(AgentEvent& outEvent, qpid::messaging::Duration timeout=qpid::messaging::Duration::FOREVER);
-
- /**
- * Return the number of events pending for nextEvent. This method will never block.
- */
- QMF_EXTERN int pendingEvents() const;
+ QMF_EXTERN bool nextEvent(AgentEvent&, qpid::messaging::Duration timeout=qpid::messaging::Duration::FOREVER);
/**
* Register a schema to be exposed by this agent.
*/
- QMF_EXTERN void registerSchema(Schema& schema);
+ QMF_EXTERN void registerSchema(Schema&);
/**
* Add data to be managed internally by the agent. If the option external:True is selected, this call
@@ -144,12 +138,12 @@ namespace qmf {
* across different sessions. If persistent, it is the agent application's
* responsibility to ensure the name is the same each time it is added.
*/
- QMF_EXTERN DataAddr addData(Data& data, const std::string& name="", bool persistent=false);
+ QMF_EXTERN DataAddr addData(Data&, const std::string& name="", bool persistent=false);
/**
* Delete data from internal agent management.
*/
- QMF_EXTERN void delData(const DataAddr& dataAddr);
+ QMF_EXTERN void delData(const DataAddr&);
/**
* The following methods are used to respond to events received in nextEvent.
@@ -161,13 +155,13 @@ namespace qmf {
* complete - Indicate that the response to a query is complete (external:True only)
* methodSuccess - Indicate the successful completion of a method call.
*/
- QMF_EXTERN void authAccept(AgentEvent& event);
- QMF_EXTERN void authReject(AgentEvent& event, const std::string& diag="");
- QMF_EXTERN void raiseException(AgentEvent& event, const std::string& errorText);
- QMF_EXTERN void raiseException(AgentEvent& event, const Data& errorData);
- QMF_EXTERN void response(AgentEvent& event, const Data& responseData);
- QMF_EXTERN void complete(AgentEvent& event);
- QMF_EXTERN void methodSuccess(AgentEvent& event);
+ QMF_EXTERN void authAccept(AgentEvent&);
+ QMF_EXTERN void authReject(AgentEvent&, const std::string& diag="");
+ QMF_EXTERN void raiseException(AgentEvent&, const std::string&);
+ QMF_EXTERN void raiseException(AgentEvent&, const Data&);
+ QMF_EXTERN void response(AgentEvent&, const Data&);
+ QMF_EXTERN void complete(AgentEvent&);
+ QMF_EXTERN void methodSuccess(AgentEvent&);
/**
* Raise an event to be sent into the QMF network.
diff --git a/qpid/cpp/include/qmf/ConsoleEvent.h b/qpid/cpp/include/qmf/ConsoleEvent.h
index 94600f9357..b836b629af 100644
--- a/qpid/cpp/include/qmf/ConsoleEvent.h
+++ b/qpid/cpp/include/qmf/ConsoleEvent.h
@@ -57,7 +57,7 @@ namespace qmf {
AGENT_DEL_FILTER = 2
};
- class QMF_CLASS_EXTERN ConsoleEvent : public qmf::Handle<ConsoleEventImpl> {
+ class ConsoleEvent : public qmf::Handle<ConsoleEventImpl> {
public:
QMF_EXTERN ConsoleEvent(ConsoleEventImpl* impl = 0);
QMF_EXTERN ConsoleEvent(const ConsoleEvent&);
diff --git a/qpid/cpp/include/qmf/ConsoleSession.h b/qpid/cpp/include/qmf/ConsoleSession.h
index 6008036eec..0c73e7a6db 100644
--- a/qpid/cpp/include/qmf/ConsoleSession.h
+++ b/qpid/cpp/include/qmf/ConsoleSession.h
@@ -38,7 +38,7 @@ namespace qmf {
class ConsoleSessionImpl;
class ConsoleEvent;
- class QMF_CLASS_EXTERN ConsoleSession : public qmf::Handle<ConsoleSessionImpl> {
+ class ConsoleSession : public qmf::Handle<ConsoleSessionImpl> {
public:
QMF_EXTERN ConsoleSession(ConsoleSessionImpl* impl = 0);
QMF_EXTERN ConsoleSession(const ConsoleSession&);
@@ -62,48 +62,14 @@ namespace qmf {
* strict-security:{True,False} - If True: Cooperate with the broker to enforce strict access control to the network
* - If False: Operate more flexibly with regard to use of messaging facilities [default]
*/
- QMF_EXTERN ConsoleSession(qpid::messaging::Connection& conn, const std::string& options="");
-
- /**
- * setDomain - Change the QMF domain that this console will operate in. If this is not called,
- * the domain will be "default". Agents in a domain can be seen only by consoles in the same domain.
- * This must be called prior to opening the console session.
- */
- QMF_EXTERN void setDomain(const std::string& domain);
- QMF_EXTERN void setAgentFilter(const std::string& filter);
-
- /**
- * Open the console session. After opening the session, the domain cannot be changed.
- */
+ QMF_EXTERN ConsoleSession(qpid::messaging::Connection&, const std::string& options="");
+ QMF_EXTERN void setDomain(const std::string&);
+ QMF_EXTERN void setAgentFilter(const std::string&);
QMF_EXTERN void open();
-
- /**
- * Close the session. Once closed, the session no longer communicates on the messaging network.
- */
QMF_EXTERN void close();
-
- /**
- * Get the next event from the console session. Events represent actions that must be acted upon by the
- * console application. This method blocks for up to the timeout if there are no events to be handled.
- * This method will typically be the focus of the console application's main execution loop.
- * If the timeout is set to Duration::IMMEDIATE, the call will not block.
- */
- QMF_EXTERN bool nextEvent(ConsoleEvent& outEvent, qpid::messaging::Duration timeout=qpid::messaging::Duration::FOREVER);
-
- /**
- * Return the number of events pending for nextEvent. This method will never block.
- */
- QMF_EXTERN int pendingEvents() const;
-
- /**
- * getAgentCount, getAgent - Retrieve the set of agents that match the console session's agent filter.
- */
+ QMF_EXTERN bool nextEvent(ConsoleEvent&, qpid::messaging::Duration timeout=qpid::messaging::Duration::FOREVER);
QMF_EXTERN uint32_t getAgentCount() const;
- QMF_EXTERN Agent getAgent(uint32_t agentIndex) const;
-
- /**
- * Get the agent for the connected broker (i.e. the agent embedded in the broker to which we have a connection).
- */
+ QMF_EXTERN Agent getAgent(uint32_t) const;
QMF_EXTERN Agent getConnectedBrokerAgent() const;
/**
@@ -113,8 +79,8 @@ namespace qmf {
* will involve all known agents. If agentFilter is non-empty, it will be applied only to the set of known
* agents. A subscription cannot be created that involves an agent not known by the session.
*/
- QMF_EXTERN Subscription subscribe(const Query& query, const std::string& agentFilter = "", const std::string& options = "");
- QMF_EXTERN Subscription subscribe(const std::string& query, const std::string& agentFilter = "", const std::string& options = "");
+ QMF_EXTERN Subscription subscribe(const Query&, const std::string& agentFilter = "", const std::string& options = "");
+ QMF_EXTERN Subscription subscribe(const std::string&, const std::string& agentFilter = "", const std::string& options = "");
#ifndef SWIG
private:
diff --git a/qpid/cpp/include/qmf/Data.h b/qpid/cpp/include/qmf/Data.h
index 487a02fe95..82f1569a0b 100644
--- a/qpid/cpp/include/qmf/Data.h
+++ b/qpid/cpp/include/qmf/Data.h
@@ -39,7 +39,7 @@ namespace qmf {
class DataAddr;
class Agent;
- class QMF_CLASS_EXTERN Data : public qmf::Handle<DataImpl> {
+ class Data : public qmf::Handle<DataImpl> {
public:
QMF_EXTERN Data(DataImpl* impl = 0);
QMF_EXTERN Data(const Data&);
diff --git a/qpid/cpp/include/qmf/DataAddr.h b/qpid/cpp/include/qmf/DataAddr.h
index 20c469081e..72de0c986a 100644
--- a/qpid/cpp/include/qmf/DataAddr.h
+++ b/qpid/cpp/include/qmf/DataAddr.h
@@ -34,7 +34,7 @@ namespace qmf {
class DataAddrImpl;
- class QMF_CLASS_EXTERN DataAddr : public qmf::Handle<DataAddrImpl> {
+ class DataAddr : public qmf::Handle<DataAddrImpl> {
public:
QMF_EXTERN DataAddr(DataAddrImpl* impl = 0);
QMF_EXTERN DataAddr(const DataAddr&);
@@ -51,9 +51,6 @@ namespace qmf {
QMF_EXTERN uint32_t getAgentEpoch() const;
QMF_EXTERN qpid::types::Variant::Map asMap() const;
- QMF_EXTERN bool operator==(const DataAddr&) const;
- QMF_EXTERN bool operator<(const DataAddr&) const;
-
#ifndef SWIG
private:
friend class qmf::PrivateImplRef<DataAddr>;
diff --git a/qpid/cpp/include/qmf/Handle.h b/qpid/cpp/include/qmf/Handle.h
index 50971ea626..510e2993aa 100644
--- a/qpid/cpp/include/qmf/Handle.h
+++ b/qpid/cpp/include/qmf/Handle.h
@@ -39,22 +39,22 @@ template <class T> class Handle {
public:
/**@return true if handle is valid, i.e. not null. */
- QMF_INLINE_EXTERN bool isValid() const { return impl; }
+ QMF_EXTERN bool isValid() const { return impl; }
/**@return true if handle is null. It is an error to call any function on a null handle. */
- QMF_INLINE_EXTERN bool isNull() const { return !impl; }
+ QMF_EXTERN bool isNull() const { return !impl; }
/** Conversion to bool supports idiom if (handle) { handle->... } */
- QMF_INLINE_EXTERN operator bool() const { return impl; }
+ QMF_EXTERN operator bool() const { return impl; }
/** Operator ! supports idiom if (!handle) { do_if_handle_is_null(); } */
- QMF_INLINE_EXTERN bool operator !() const { return !impl; }
+ QMF_EXTERN bool operator !() const { return !impl; }
void swap(Handle<T>& h) { T* t = h.impl; h.impl = impl; impl = t; }
protected:
typedef T Impl;
- QMF_INLINE_EXTERN Handle() :impl() {}
+ QMF_EXTERN Handle() :impl() {}
// Not implemented,subclasses must implement.
QMF_EXTERN Handle(const Handle&);
diff --git a/qpid/cpp/include/qmf/ImportExport.h b/qpid/cpp/include/qmf/ImportExport.h
index 7405c15259..f5e1d9127c 100644
--- a/qpid/cpp/include/qmf/ImportExport.h
+++ b/qpid/cpp/include/qmf/ImportExport.h
@@ -20,16 +20,14 @@
* under the License.
*/
-#include "qpid/ImportExport.h"
-
-#if defined(QMF_EXPORT) || defined (qmf2_EXPORTS)
-# define QMF_EXTERN QPID_EXPORT
-# define QMF_CLASS_EXTERN QPID_CLASS_EXPORT
-# define QMF_INLINE_EXTERN QPID_INLINE_EXPORT
+#if defined(WIN32) && !defined(QPID_DECLARE_STATIC)
+# if defined(QMF_EXPORT) || defined (qmfcommon_EXPORTS)
+# define QMF_EXTERN __declspec(dllexport)
+# else
+# define QMF_EXTERN __declspec(dllimport)
+# endif
#else
-# define QMF_EXTERN QPID_IMPORT
-# define QMF_CLASS_EXTERN QPID_CLASS_IMPORT
-# define QMF_INLINE_EXTERN QPID_INLINE_IMPORT
+# define QMF_EXTERN
#endif
#endif
diff --git a/qpid/cpp/include/qmf/Query.h b/qpid/cpp/include/qmf/Query.h
index c1264f8901..fec4660bd7 100644
--- a/qpid/cpp/include/qmf/Query.h
+++ b/qpid/cpp/include/qmf/Query.h
@@ -43,7 +43,7 @@ namespace qmf {
QUERY_SCHEMA_ID = 4
};
- class QMF_CLASS_EXTERN Query : public qmf::Handle<QueryImpl> {
+ class Query : public qmf::Handle<QueryImpl> {
public:
QMF_EXTERN Query(QueryImpl* impl = 0);
QMF_EXTERN Query(const Query&);
@@ -65,7 +65,7 @@ namespace qmf {
#ifndef SWIG
private:
friend class qmf::PrivateImplRef<Query>;
- friend struct QueryImplAccess;
+ friend class QueryImplAccess;
#endif
};
diff --git a/qpid/cpp/include/qmf/Schema.h b/qpid/cpp/include/qmf/Schema.h
index 6cfd2e2a56..cf316138c1 100644
--- a/qpid/cpp/include/qmf/Schema.h
+++ b/qpid/cpp/include/qmf/Schema.h
@@ -38,7 +38,7 @@ namespace qmf {
class SchemaProperty;
class SchemaMethod;
- class QMF_CLASS_EXTERN Schema : public qmf::Handle<SchemaImpl> {
+ class Schema : public qmf::Handle<SchemaImpl> {
public:
QMF_EXTERN Schema(SchemaImpl* impl = 0);
QMF_EXTERN Schema(const Schema&);
diff --git a/qpid/cpp/include/qmf/SchemaId.h b/qpid/cpp/include/qmf/SchemaId.h
index 2dafc1c091..13fb1cb902 100644
--- a/qpid/cpp/include/qmf/SchemaId.h
+++ b/qpid/cpp/include/qmf/SchemaId.h
@@ -35,7 +35,7 @@ namespace qmf {
class SchemaIdImpl;
- class QMF_CLASS_EXTERN SchemaId : public qmf::Handle<SchemaIdImpl> {
+ class SchemaId : public qmf::Handle<SchemaIdImpl> {
public:
QMF_EXTERN SchemaId(SchemaIdImpl* impl = 0);
QMF_EXTERN SchemaId(const SchemaId&);
diff --git a/qpid/cpp/include/qmf/SchemaMethod.h b/qpid/cpp/include/qmf/SchemaMethod.h
index b5944dc29e..47302b62b9 100644
--- a/qpid/cpp/include/qmf/SchemaMethod.h
+++ b/qpid/cpp/include/qmf/SchemaMethod.h
@@ -36,7 +36,7 @@ namespace qmf {
class SchemaMethodImpl;
class SchemaProperty;
- class QMF_CLASS_EXTERN SchemaMethod : public qmf::Handle<SchemaMethodImpl> {
+ class SchemaMethod : public qmf::Handle<SchemaMethodImpl> {
public:
QMF_EXTERN SchemaMethod(SchemaMethodImpl* impl = 0);
QMF_EXTERN SchemaMethod(const SchemaMethod&);
diff --git a/qpid/cpp/include/qmf/SchemaProperty.h b/qpid/cpp/include/qmf/SchemaProperty.h
index bbb603fa50..a3a328b60b 100644
--- a/qpid/cpp/include/qmf/SchemaProperty.h
+++ b/qpid/cpp/include/qmf/SchemaProperty.h
@@ -36,7 +36,7 @@ namespace qmf {
class SchemaPropertyImpl;
- class QMF_CLASS_EXTERN SchemaProperty : public Handle<SchemaPropertyImpl> {
+ class SchemaProperty : public Handle<SchemaPropertyImpl> {
public:
QMF_EXTERN SchemaProperty(SchemaPropertyImpl* impl = 0);
QMF_EXTERN SchemaProperty(const SchemaProperty&);
diff --git a/qpid/cpp/include/qmf/Subscription.h b/qpid/cpp/include/qmf/Subscription.h
index 398a45b922..4e60eb984e 100644
--- a/qpid/cpp/include/qmf/Subscription.h
+++ b/qpid/cpp/include/qmf/Subscription.h
@@ -35,7 +35,7 @@ namespace qmf {
class SubscriptionImpl;
class Data;
- class QMF_CLASS_EXTERN Subscription : public qmf::Handle<SubscriptionImpl> {
+ class Subscription : public qmf::Handle<SubscriptionImpl> {
public:
QMF_EXTERN Subscription(SubscriptionImpl* impl = 0);
QMF_EXTERN Subscription(const Subscription&);
@@ -73,7 +73,7 @@ namespace qmf {
#ifndef SWIG
private:
friend class qmf::PrivateImplRef<Subscription>;
- friend struct SubscriptionImplAccess;
+ friend class SubscriptionImplAccess;
#endif
};
diff --git a/qpid/cpp/include/qmf/engine/QmfEngineImportExport.h b/qpid/cpp/include/qmf/engine/QmfEngineImportExport.h
index cf8fffdb17..373617e046 100644
--- a/qpid/cpp/include/qmf/engine/QmfEngineImportExport.h
+++ b/qpid/cpp/include/qmf/engine/QmfEngineImportExport.h
@@ -26,17 +26,8 @@
# else
# define QMFE_EXTERN __declspec(dllimport)
# endif
-# ifdef _MSC_VER
-# define QMFE_CLASS_EXTERN
-# define QMFE_INLINE_EXTERN QMFE_EXTERN
-# else
-# define QMFE_CLASS_EXTERN QMFE_EXTERN
-# define QMFE_INLINE_EXTERN
-# endif
#else
# define QMFE_EXTERN
-# define QMFE_CLASS_EXTERN
-# define QMFE_INLINE_EXTERN
#endif
#endif
diff --git a/qpid/cpp/include/qmf/exceptions.h b/qpid/cpp/include/qmf/exceptions.h
index c7ffa68ce2..7959499d63 100644
--- a/qpid/cpp/include/qmf/exceptions.h
+++ b/qpid/cpp/include/qmf/exceptions.h
@@ -31,24 +31,24 @@ namespace qmf {
/** \ingroup qmf
*/
- struct QMF_CLASS_EXTERN QmfException : public qpid::types::Exception {
+ struct QmfException : public qpid::types::Exception {
QMF_EXTERN QmfException(const std::string& msg);
QMF_EXTERN virtual ~QmfException() throw();
qpid::types::Variant::Map detail;
};
- struct QMF_CLASS_EXTERN KeyNotFound : public QmfException {
+ struct KeyNotFound : public QmfException {
QMF_EXTERN KeyNotFound(const std::string& msg);
QMF_EXTERN virtual ~KeyNotFound() throw();
};
- struct QMF_CLASS_EXTERN IndexOutOfRange : public QmfException {
+ struct IndexOutOfRange : public QmfException {
QMF_EXTERN IndexOutOfRange();
QMF_EXTERN virtual ~IndexOutOfRange() throw();
};
- struct QMF_CLASS_EXTERN OperationTimedOut : public QmfException {
+ struct OperationTimedOut : public QmfException {
QMF_EXTERN OperationTimedOut();
QMF_EXTERN virtual ~OperationTimedOut() throw();
};
diff --git a/qpid/cpp/include/qpid/Address.h b/qpid/cpp/include/qpid/Address.h
index f5b19d0532..57c9139f87 100755
--- a/qpid/cpp/include/qpid/Address.h
+++ b/qpid/cpp/include/qpid/Address.h
@@ -36,7 +36,7 @@ public:
static const std::string TCP; // Default TCP protocol tag.
static const uint16_t AMQP_PORT=5672; // Default AMQP port.
- QPID_COMMON_INLINE_EXTERN explicit Address(
+ QPID_COMMON_EXTERN explicit Address(
const std::string& protocol_=std::string(),
const std::string& host_=std::string(),
uint16_t port_=0
diff --git a/qpid/cpp/include/qpid/CommonImportExport.h b/qpid/cpp/include/qpid/CommonImportExport.h
index dd2b900b73..02c06ed7af 100644
--- a/qpid/cpp/include/qpid/CommonImportExport.h
+++ b/qpid/cpp/include/qpid/CommonImportExport.h
@@ -20,16 +20,14 @@
* under the License.
*/
-#include "qpid/ImportExport.h"
-
+#if defined(WIN32) && !defined(QPID_DECLARE_STATIC)
#if defined(COMMON_EXPORT) || defined (qpidcommon_EXPORTS)
-# define QPID_COMMON_EXTERN QPID_EXPORT
-# define QPID_COMMON_CLASS_EXTERN QPID_CLASS_EXPORT
-# define QPID_COMMON_INLINE_EXTERN QPID_INLINE_EXPORT
+#define QPID_COMMON_EXTERN __declspec(dllexport)
+#else
+#define QPID_COMMON_EXTERN __declspec(dllimport)
+#endif
#else
-# define QPID_COMMON_EXTERN QPID_IMPORT
-# define QPID_COMMON_CLASS_EXTERN QPID_CLASS_IMPORT
-# define QPID_COMMON_INLINE_EXTERN QPID_INLINE_IMPORT
+#define QPID_COMMON_EXTERN
#endif
#endif
diff --git a/qpid/cpp/include/qpid/Exception.h b/qpid/cpp/include/qpid/Exception.h
index cbd175214d..fa7111160c 100644
--- a/qpid/cpp/include/qpid/Exception.h
+++ b/qpid/cpp/include/qpid/Exception.h
@@ -36,7 +36,7 @@ namespace qpid
/**
* Base class for Qpid runtime exceptions.
*/
-class QPID_COMMON_CLASS_EXTERN Exception : public std::exception
+class Exception : public std::exception
{
public:
QPID_COMMON_EXTERN explicit Exception(const std::string& message=std::string()) throw();
@@ -51,30 +51,30 @@ class QPID_COMMON_CLASS_EXTERN Exception : public std::exception
};
/** Exception that includes an errno message. */
-struct QPID_COMMON_CLASS_EXTERN ErrnoException : public Exception {
+struct ErrnoException : public Exception {
ErrnoException(const std::string& msg, int err) : Exception(msg+": "+qpid::sys::strError(err)) {}
ErrnoException(const std::string& msg) : Exception(msg+": "+qpid::sys::strError(errno)) {}
};
-struct QPID_COMMON_CLASS_EXTERN SessionException : public Exception {
+struct SessionException : public Exception {
const framing::execution::ErrorCode code;
SessionException(framing::execution::ErrorCode code_, const std::string& message)
: Exception(message), code(code_) {}
};
-struct QPID_COMMON_CLASS_EXTERN ChannelException : public Exception {
+struct ChannelException : public Exception {
const framing::session::DetachCode code;
ChannelException(framing::session::DetachCode _code, const std::string& message)
: Exception(message), code(_code) {}
};
-struct QPID_COMMON_CLASS_EXTERN ConnectionException : public Exception {
+struct ConnectionException : public Exception {
const framing::connection::CloseCode code;
ConnectionException(framing::connection::CloseCode _code, const std::string& message)
: Exception(message), code(_code) {}
};
-struct QPID_COMMON_CLASS_EXTERN ClosedException : public Exception {
+struct ClosedException : public Exception {
QPID_COMMON_EXTERN ClosedException(const std::string& msg=std::string());
QPID_COMMON_EXTERN std::string getPrefix() const;
};
diff --git a/qpid/cpp/include/qpid/ImportExport.h b/qpid/cpp/include/qpid/ImportExport.h
deleted file mode 100644
index e62399faf7..0000000000
--- a/qpid/cpp/include/qpid/ImportExport.h
+++ /dev/null
@@ -1,71 +0,0 @@
-#ifndef QPID_IMPORTEXPORT_H
-#define QPID_IMPORTEXPORT_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.
- */
-
-//
-// This header file defines the following macros for the control of library/DLL
-// import and export:
-//
-// QPID_EXPORT - Export declaration for Methods
-// QPID_CLASS_EXPORT - Export declaration for Classes
-// QPID_INLINE_EXPORT - Export declaration for Inline methods
-//
-// QPID_IMPORT - Import declaration for Methods
-// QPID_CLASS_IMPORT - Import declaration for Classes
-// QPID_INLINE_IMPORT - Import declaration for Inline methods
-//
-
-#if defined(WIN32) && !defined(QPID_DECLARE_STATIC)
- //
- // Import and Export definitions for Windows:
- //
-# define QPID_EXPORT __declspec(dllexport)
-# define QPID_IMPORT __declspec(dllimport)
-# ifdef _MSC_VER
- //
- // Specific to the Microsoft compiler:
- //
-# define QPID_CLASS_EXPORT
-# define QPID_CLASS_IMPORT
-# define QPID_INLINE_EXPORT QPID_EXPORT
-# define QPID_INLINE_IMPORT QPID_IMPORT
-# else
- //
- // Specific to non-Microsoft compilers (mingw32):
- //
-# define QPID_CLASS_EXPORT QPID_EXPORT
-# define QPID_CLASS_IMPORT QPID_IMPORT
-# define QPID_INLINE_EXPORT
-# define QPID_INLINE_IMPORT
-# endif
-#else
- //
- // Non-Windows (Linux, etc.) definitions:
- //
-# define QPID_EXPORT
-# define QPID_IMPORT
-# define QPID_CLASS_EXPORT
-# define QPID_CLASS_IMPORT
-# define QPID_INLINE_EXPORT
-# define QPID_INLINE_IMPORT
-#endif
-
-#endif /*!QPID_IMPORTEXPORT_H*/
diff --git a/qpid/cpp/include/qpid/Options.h b/qpid/cpp/include/qpid/Options.h
index 63d91c2d72..078a6b4d95 100644
--- a/qpid/cpp/include/qpid/Options.h
+++ b/qpid/cpp/include/qpid/Options.h
@@ -133,6 +133,77 @@ inline po::value_semantic* optValue(bool& value) { return po::bool_switch(&value
+/*
+ * ---------------------------------------------
+ * Explanation for Boost 103200 conditional code
+ * ---------------------------------------------
+ *
+ * This boost version has an implementation of the program_options library
+ * that has no provision for allowing unregistered options to pass by.
+ *
+ * But that means that, if you have a program that loads optional modules
+ * after start-up, and those modules each have their own set of options,
+ * then if you parse the command line too soon, you will get spurious
+ * reports of unrecognized options -- and the program will exit!
+ *
+ * And we must process the command-line before module-loading, because we
+ * need to look at the "bootstrap" options.
+ *
+ * This conditional code:
+ *
+ * 1. implements it's own functor class, derived from the Boost
+ * "options_description_easy_init" class. This functor is used
+ * to process added options and do the functor chaining, so that
+ * I can snoop on the arguments before doing an explicit call
+ * to its parent.
+ *
+ * 2. It implements two static vectors, one to hold long names, and
+ * one for short names, so that options declared by modules are
+ * not forgotten when their options_description goes out of scope.
+ *
+ * I will be thrilled to personally delete this code if we ever decide
+ * that qpid doesn't really need to support this antique version of Boost.
+ *
+ */
+
+#if ( BOOST_VERSION == 103200 )
+struct Options;
+
+
+struct
+options_description_less_easy_init
+ : public po::options_description_easy_init
+{
+ options_description_less_easy_init ( Options * my_owner,
+ po::options_description * my_parents_owner
+ )
+ : po::options_description_easy_init(my_parents_owner)
+ {
+ owner = my_owner;
+ }
+
+
+ options_description_less_easy_init&
+ operator()(char const * name,
+ char const * description);
+
+
+ options_description_less_easy_init&
+ operator()(char const * name,
+ const po::value_semantic* s);
+
+
+ options_description_less_easy_init&
+ operator()(const char* name,
+ const po::value_semantic* s,
+ const char* description);
+
+
+ Options * owner;
+};
+#endif
+
+
struct Options : public po::options_description {
struct Exception : public qpid::Exception {
@@ -151,9 +222,26 @@ struct Options : public po::options_description {
bool allowUnknown = false);
+ #if ( BOOST_VERSION == 103200 )
+ options_description_less_easy_init m_less_easy;
+
+ options_description_less_easy_init addOptions() {
+ return m_less_easy;
+ }
+
+ bool
+ is_registered_option ( std::string s );
+
+ void
+ register_names ( std::string s );
+
+ static std::vector<std::string> long_names;
+ static std::vector<std::string> short_names;
+ #else
boost::program_options::options_description_easy_init addOptions() {
return add_options();
}
+ #endif
};
diff --git a/qpid/cpp/include/qpid/Url.h b/qpid/cpp/include/qpid/Url.h
index 915b08ac5f..353e9d5599 100644
--- a/qpid/cpp/include/qpid/Url.h
+++ b/qpid/cpp/include/qpid/Url.h
@@ -66,7 +66,7 @@ struct Url : public std::vector<Address> {
*@exception Invalid if the url is invalid.
*/
QPID_COMMON_EXTERN void parse(const char* url);
- QPID_COMMON_INLINE_EXTERN void parse(const std::string& url) { parse(url.c_str()); }
+ QPID_COMMON_EXTERN void parse(const std::string& url) { parse(url.c_str()); }
/** Replace contesnts with parsed URL. Replace with empty URL if invalid. */
QPID_COMMON_EXTERN void parseNoThrow(const char* url);
diff --git a/qpid/cpp/include/qpid/agent/ManagementAgent.h b/qpid/cpp/include/qpid/agent/ManagementAgent.h
index 10bc6527a9..e2451244c1 100644
--- a/qpid/cpp/include/qpid/agent/ManagementAgent.h
+++ b/qpid/cpp/include/qpid/agent/ManagementAgent.h
@@ -110,8 +110,8 @@ class ManagementAgent
uint16_t intervalSeconds = 10,
bool useExternalThread = false,
const std::string& storeFile = "",
- const std::string& uid = "",
- const std::string& pwd = "",
+ const std::string& uid = "guest",
+ const std::string& pwd = "guest",
const std::string& mech = "PLAIN",
const std::string& proto = "tcp") = 0;
diff --git a/qpid/cpp/include/qpid/agent/QmfAgentImportExport.h b/qpid/cpp/include/qpid/agent/QmfAgentImportExport.h
index 3f923ac4b2..e41425a7ba 100644
--- a/qpid/cpp/include/qpid/agent/QmfAgentImportExport.h
+++ b/qpid/cpp/include/qpid/agent/QmfAgentImportExport.h
@@ -20,16 +20,14 @@
* under the License.
*/
-#include "qpid/ImportExport.h"
-
-#if defined(QMF_EXPORT) || defined (qmf_EXPORTS)
-# define QMF_AGENT_EXTERN QPID_EXPORT
-# define QMF_AGENT_CLASS_EXTERN QPID_CLASS_EXPORT
-# define QMF_AGENT_INLINE_EXTERN QPID_INLINE_EXPORT
+#if defined(WIN32) && !defined(QPID_DECLARE_STATIC)
+#if defined (qmf_EXPORTS)
+#define QMF_AGENT_EXTERN __declspec(dllexport)
+#else
+#define QMF_AGENT_EXTERN __declspec(dllimport)
+#endif
#else
-# define QMF_AGENT_EXTERN QPID_IMPORT
-# define QMF_AGENT_CLASS_EXTERN QPID_CLASS_IMPORT
-# define QMF_AGENT_INLINE_EXTERN QPID_INLINE_IMPORT
+#define QMF_AGENT_EXTERN
#endif
#endif
diff --git a/qpid/cpp/include/qpid/client/ClientImportExport.h b/qpid/cpp/include/qpid/client/ClientImportExport.h
index 2a3a5a52e9..42b02e33c3 100644
--- a/qpid/cpp/include/qpid/client/ClientImportExport.h
+++ b/qpid/cpp/include/qpid/client/ClientImportExport.h
@@ -20,16 +20,14 @@
* under the License.
*/
-#include "qpid/ImportExport.h"
-
+#if defined(WIN32) && !defined(QPID_DECLARE_STATIC)
#if defined(CLIENT_EXPORT) || defined (qpidclient_EXPORTS)
-# define QPID_CLIENT_EXTERN QPID_EXPORT
-# define QPID_CLIENT_CLASS_EXTERN QPID_CLASS_EXPORT
-# define QPID_CLIENT_INLINE_EXTERN QPID_INLINE_EXPORT
+#define QPID_CLIENT_EXTERN __declspec(dllexport)
+#else
+#define QPID_CLIENT_EXTERN __declspec(dllimport)
+#endif
#else
-# define QPID_CLIENT_EXTERN QPID_IMPORT
-# define QPID_CLIENT_CLASS_EXTERN QPID_CLASS_IMPORT
-# define QPID_CLIENT_INLINE_EXTERN QPID_INLINE_IMPORT
+#define QPID_CLIENT_EXTERN
#endif
#endif
diff --git a/qpid/cpp/include/qpid/client/Completion.h b/qpid/cpp/include/qpid/client/Completion.h
index 9546db9258..99d940f031 100644
--- a/qpid/cpp/include/qpid/client/Completion.h
+++ b/qpid/cpp/include/qpid/client/Completion.h
@@ -41,7 +41,7 @@ template <class T> class PrivateImplRef;
*
*\ingroup clientapi
*/
-class QPID_CLIENT_CLASS_EXTERN Completion : public Handle<CompletionImpl>
+class Completion : public Handle<CompletionImpl>
{
public:
QPID_CLIENT_EXTERN Completion(CompletionImpl* = 0);
diff --git a/qpid/cpp/include/qpid/client/Connection.h b/qpid/cpp/include/qpid/client/Connection.h
index c0db0f301d..6ed0d98bc0 100644
--- a/qpid/cpp/include/qpid/client/Connection.h
+++ b/qpid/cpp/include/qpid/client/Connection.h
@@ -60,7 +60,7 @@ class ConnectionImpl;
*
*/
-class QPID_CLIENT_CLASS_EXTERN Connection
+class Connection
{
framing::ProtocolVersion version;
@@ -102,8 +102,8 @@ class QPID_CLIENT_CLASS_EXTERN Connection
* within a single broker).
*/
QPID_CLIENT_EXTERN void open(const std::string& host, int port = 5672,
- const std::string& uid = "",
- const std::string& pwd = "",
+ const std::string& uid = "guest",
+ const std::string& pwd = "guest",
const std::string& virtualhost = "/", uint16_t maxFrameSize=65535);
/**
@@ -124,8 +124,8 @@ class QPID_CLIENT_CLASS_EXTERN Connection
* within a single broker).
*/
QPID_CLIENT_EXTERN void open(const Url& url,
- const std::string& uid = "",
- const std::string& pwd = "",
+ const std::string& uid = "guest",
+ const std::string& pwd = "guest",
const std::string& virtualhost = "/", uint16_t maxFrameSize=65535);
/**
diff --git a/qpid/cpp/include/qpid/client/ConnectionSettings.h b/qpid/cpp/include/qpid/client/ConnectionSettings.h
index 2b6b86f891..1c2ee28b1b 100644
--- a/qpid/cpp/include/qpid/client/ConnectionSettings.h
+++ b/qpid/cpp/include/qpid/client/ConnectionSettings.h
@@ -37,7 +37,7 @@ namespace client {
/**
* Settings for a Connection.
*/
-struct QPID_CLIENT_CLASS_EXTERN ConnectionSettings {
+struct ConnectionSettings {
QPID_CLIENT_EXTERN ConnectionSettings();
QPID_CLIENT_EXTERN virtual ~ConnectionSettings();
diff --git a/qpid/cpp/include/qpid/client/FailoverListener.h b/qpid/cpp/include/qpid/client/FailoverListener.h
index 53c7c26211..59108eb7cb 100644
--- a/qpid/cpp/include/qpid/client/FailoverListener.h
+++ b/qpid/cpp/include/qpid/client/FailoverListener.h
@@ -48,7 +48,7 @@ namespace client {
* FailoverListener::decode to extract a list of broker URLs from a
* failover exchange message.
*/
-class QPID_CLIENT_CLASS_EXTERN FailoverListener : private MessageListener, private qpid::sys::Runnable
+class FailoverListener : private MessageListener, private qpid::sys::Runnable
{
public:
/** The name of the standard failover exchange amq.failover */
diff --git a/qpid/cpp/include/qpid/client/FailoverManager.h b/qpid/cpp/include/qpid/client/FailoverManager.h
index d3a0dbc976..0d30e2ed60 100644
--- a/qpid/cpp/include/qpid/client/FailoverManager.h
+++ b/qpid/cpp/include/qpid/client/FailoverManager.h
@@ -42,7 +42,7 @@ struct CannotConnectException : qpid::Exception
/**
* Utility to manage failover.
*/
-class QPID_CLIENT_CLASS_EXTERN FailoverManager
+class FailoverManager
{
public:
/**
diff --git a/qpid/cpp/include/qpid/client/Future.h b/qpid/cpp/include/qpid/client/Future.h
index 630a7e03c0..09088e68f6 100644
--- a/qpid/cpp/include/qpid/client/Future.h
+++ b/qpid/cpp/include/qpid/client/Future.h
@@ -34,7 +34,7 @@ namespace qpid {
namespace client {
/**@internal */
-class QPID_CLIENT_CLASS_EXTERN Future
+class Future
{
framing::SequenceNumber command;
boost::shared_ptr<FutureResult> result;
diff --git a/qpid/cpp/include/qpid/client/FutureResult.h b/qpid/cpp/include/qpid/client/FutureResult.h
index ead4929571..b2b663daa1 100644
--- a/qpid/cpp/include/qpid/client/FutureResult.h
+++ b/qpid/cpp/include/qpid/client/FutureResult.h
@@ -34,7 +34,7 @@ namespace client {
class SessionImpl;
///@internal
-class QPID_CLIENT_CLASS_EXTERN FutureResult : public FutureCompletion
+class FutureResult : public FutureCompletion
{
std::string result;
public:
diff --git a/qpid/cpp/include/qpid/client/Handle.h b/qpid/cpp/include/qpid/client/Handle.h
index b8315481a9..088e836fcf 100644
--- a/qpid/cpp/include/qpid/client/Handle.h
+++ b/qpid/cpp/include/qpid/client/Handle.h
@@ -40,22 +40,22 @@ template <class T> class Handle {
public:
/**@return true if handle is valid, i.e. not null. */
- QPID_CLIENT_INLINE_EXTERN 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. */
- QPID_CLIENT_INLINE_EXTERN bool isNull() const { return !impl; }
+ QPID_CLIENT_EXTERN bool isNull() const { return !impl; }
/** Conversion to bool supports idiom if (handle) { handle->... } */
- QPID_CLIENT_INLINE_EXTERN operator bool() const { return impl; }
+ QPID_CLIENT_EXTERN operator bool() const { return impl; }
/** Operator ! supports idiom if (!handle) { do_if_handle_is_null(); } */
- QPID_CLIENT_INLINE_EXTERN bool operator !() const { return !impl; }
+ QPID_CLIENT_EXTERN bool operator !() const { return !impl; }
void swap(Handle<T>& h) { T* t = h.impl; h.impl = impl; impl = t; }
protected:
typedef T Impl;
- QPID_CLIENT_INLINE_EXTERN Handle() :impl() {}
+ QPID_CLIENT_EXTERN Handle() :impl() {}
// Not implemented,subclasses must implement.
QPID_CLIENT_EXTERN Handle(const Handle&);
diff --git a/qpid/cpp/include/qpid/client/LocalQueue.h b/qpid/cpp/include/qpid/client/LocalQueue.h
index 1a19a8499d..70e4cebcf1 100644
--- a/qpid/cpp/include/qpid/client/LocalQueue.h
+++ b/qpid/cpp/include/qpid/client/LocalQueue.h
@@ -71,7 +71,7 @@ template <class T> class PrivateImplRef;
* </ul>
*/
-class QPID_CLIENT_CLASS_EXTERN LocalQueue : public Handle<LocalQueueImpl> {
+class LocalQueue : public Handle<LocalQueueImpl> {
public:
/** Create a local queue. Subscribe the local queue to a remote broker
* queue with a SubscriptionManager.
diff --git a/qpid/cpp/include/qpid/client/Message.h b/qpid/cpp/include/qpid/client/Message.h
index ba50dda9ba..2401cbdc92 100644
--- a/qpid/cpp/include/qpid/client/Message.h
+++ b/qpid/cpp/include/qpid/client/Message.h
@@ -112,7 +112,7 @@ class MessageImpl;
*
*
*/
-class QPID_CLIENT_CLASS_EXTERN Message
+class Message
{
public:
/** Create a Message.
diff --git a/qpid/cpp/include/qpid/client/MessageListener.h b/qpid/cpp/include/qpid/client/MessageListener.h
index 3ca2fa964a..d200f8cf21 100644
--- a/qpid/cpp/include/qpid/client/MessageListener.h
+++ b/qpid/cpp/include/qpid/client/MessageListener.h
@@ -84,7 +84,7 @@ namespace client {
*
*/
- class QPID_CLIENT_CLASS_EXTERN MessageListener{
+ class MessageListener{
public:
QPID_CLIENT_EXTERN virtual ~MessageListener();
diff --git a/qpid/cpp/include/qpid/client/MessageReplayTracker.h b/qpid/cpp/include/qpid/client/MessageReplayTracker.h
index 06a3f29c7d..6f5a0f4ac3 100644
--- a/qpid/cpp/include/qpid/client/MessageReplayTracker.h
+++ b/qpid/cpp/include/qpid/client/MessageReplayTracker.h
@@ -34,7 +34,7 @@ namespace client {
* Utility to track messages sent asynchronously, allowing those that
* are indoubt to be replayed over a new session.
*/
-class QPID_CLIENT_CLASS_EXTERN MessageReplayTracker
+class MessageReplayTracker
{
public:
QPID_CLIENT_EXTERN MessageReplayTracker(uint flushInterval);
diff --git a/qpid/cpp/include/qpid/client/QueueOptions.h b/qpid/cpp/include/qpid/client/QueueOptions.h
index 3984b63fdd..f8a4963f06 100644
--- a/qpid/cpp/include/qpid/client/QueueOptions.h
+++ b/qpid/cpp/include/qpid/client/QueueOptions.h
@@ -35,7 +35,7 @@ enum QueueOrderingPolicy {FIFO, LVQ, LVQ_NO_BROWSE};
* A help class to set options on the Queue. Create a configured args while
* still allowing any custom configuration via the FieldTable base class
*/
-class QPID_CLIENT_CLASS_EXTERN QueueOptions: public framing::FieldTable
+class QueueOptions: public framing::FieldTable
{
public:
QPID_CLIENT_EXTERN QueueOptions();
diff --git a/qpid/cpp/include/qpid/client/SessionBase_0_10.h b/qpid/cpp/include/qpid/client/SessionBase_0_10.h
index ea50ab32f7..3b5c84e74b 100644
--- a/qpid/cpp/include/qpid/client/SessionBase_0_10.h
+++ b/qpid/cpp/include/qpid/client/SessionBase_0_10.h
@@ -54,7 +54,7 @@ enum CreditUnit { MESSAGE_CREDIT=0, BYTE_CREDIT=1, UNLIMITED_CREDIT=0xFFFFFFFF }
* Subclasses provide the AMQP commands for a given
* version of the protocol.
*/
-class QPID_CLIENT_CLASS_EXTERN SessionBase_0_10 {
+class SessionBase_0_10 {
public:
///@internal
diff --git a/qpid/cpp/include/qpid/client/Subscription.h b/qpid/cpp/include/qpid/client/Subscription.h
index bb9b98e8ff..425b6b92e2 100644
--- a/qpid/cpp/include/qpid/client/Subscription.h
+++ b/qpid/cpp/include/qpid/client/Subscription.h
@@ -39,7 +39,7 @@ class SubscriptionManager;
* A handle to an active subscription. Provides methods to query the subscription status
* and control acknowledgement (acquire and accept) of messages.
*/
-class QPID_CLIENT_CLASS_EXTERN Subscription : public Handle<SubscriptionImpl> {
+class Subscription : public Handle<SubscriptionImpl> {
public:
QPID_CLIENT_EXTERN Subscription(SubscriptionImpl* = 0);
QPID_CLIENT_EXTERN Subscription(const Subscription&);
@@ -91,13 +91,13 @@ class QPID_CLIENT_CLASS_EXTERN Subscription : public Handle<SubscriptionImpl> {
QPID_CLIENT_EXTERN void release(const SequenceSet& messageIds);
/* Acquire a single message */
- QPID_CLIENT_INLINE_EXTERN 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 */
- QPID_CLIENT_INLINE_EXTERN 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 */
- QPID_CLIENT_INLINE_EXTERN 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 */
QPID_CLIENT_EXTERN Session getSession() const;
diff --git a/qpid/cpp/include/qpid/client/SubscriptionManager.h b/qpid/cpp/include/qpid/client/SubscriptionManager.h
index b69819a8ff..e70e05f73a 100644
--- a/qpid/cpp/include/qpid/client/SubscriptionManager.h
+++ b/qpid/cpp/include/qpid/client/SubscriptionManager.h
@@ -94,7 +94,7 @@ class SubscriptionManagerImpl;
* </ul>
*
*/
-class QPID_CLIENT_CLASS_EXTERN SubscriptionManager : public sys::Runnable, public Handle<SubscriptionManagerImpl>
+class SubscriptionManager : public sys::Runnable, public Handle<SubscriptionManagerImpl>
{
public:
/** Create a new SubscriptionManager associated with a session */
diff --git a/qpid/cpp/include/qpid/console/Agent.h b/qpid/cpp/include/qpid/console/Agent.h
index 629dd71dee..97d75da250 100644
--- a/qpid/cpp/include/qpid/console/Agent.h
+++ b/qpid/cpp/include/qpid/console/Agent.h
@@ -31,17 +31,17 @@ namespace console {
*
* \ingroup qmfconsoleapi
*/
- class QPID_CONSOLE_CLASS_EXTERN Agent {
+ class QPID_CONSOLE_EXTERN Agent {
public:
typedef std::vector<Agent*> Vector;
- QPID_CONSOLE_INLINE_EXTERN Agent(Broker* _broker, uint32_t _bank, const std::string& _label) :
+ Agent(Broker* _broker, uint32_t _bank, const std::string& _label) :
broker(_broker), brokerBank(broker->getBrokerBank()),
agentBank(_bank), label(_label) {}
- QPID_CONSOLE_INLINE_EXTERN Broker* getBroker() const { return broker; }
- QPID_CONSOLE_INLINE_EXTERN uint32_t getBrokerBank() const { return brokerBank; }
- QPID_CONSOLE_INLINE_EXTERN uint32_t getAgentBank() const { return agentBank; }
- QPID_CONSOLE_INLINE_EXTERN const std::string& getLabel() const { return label; }
+ Broker* getBroker() const { return broker; }
+ uint32_t getBrokerBank() const { return brokerBank; }
+ uint32_t getAgentBank() const { return agentBank; }
+ const std::string& getLabel() const { return label; }
private:
Broker* broker;
@@ -50,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/include/qpid/console/Broker.h b/qpid/cpp/include/qpid/console/Broker.h
index c2ba8ac81f..0b2d1bcb61 100644
--- a/qpid/cpp/include/qpid/console/Broker.h
+++ b/qpid/cpp/include/qpid/console/Broker.h
@@ -55,12 +55,12 @@ namespace console {
client::ConnectionSettings& settings);
QPID_CONSOLE_EXTERN ~Broker();
- QPID_CONSOLE_INLINE_EXTERN bool isConnected() const { return connected; }
- QPID_CONSOLE_INLINE_EXTERN const std::string& getError() const { return error; }
- QPID_CONSOLE_INLINE_EXTERN const std::string& getSessionId() const { return amqpSessionId; }
- QPID_CONSOLE_INLINE_EXTERN const framing::Uuid& getBrokerId() const { return brokerId; }
- QPID_CONSOLE_INLINE_EXTERN uint32_t getBrokerBank() const { return 1; }
- QPID_CONSOLE_INLINE_EXTERN void addBinding(const std::string& key) {
+ QPID_CONSOLE_EXTERN bool isConnected() const { return connected; }
+ QPID_CONSOLE_EXTERN const std::string& getError() const { return error; }
+ QPID_CONSOLE_EXTERN const std::string& getSessionId() const { return amqpSessionId; }
+ QPID_CONSOLE_EXTERN const framing::Uuid& getBrokerId() const { return brokerId; }
+ QPID_CONSOLE_EXTERN uint32_t getBrokerBank() const { return 1; }
+ QPID_CONSOLE_EXTERN void addBinding(const std::string& key) {
connThreadBody.bindExchange("qpid.management", key);
}
QPID_CONSOLE_EXTERN std::string getUrl() const;
@@ -123,10 +123,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/include/qpid/console/ConsoleImportExport.h b/qpid/cpp/include/qpid/console/ConsoleImportExport.h
index aac30858f7..c2d7cb3a14 100644
--- a/qpid/cpp/include/qpid/console/ConsoleImportExport.h
+++ b/qpid/cpp/include/qpid/console/ConsoleImportExport.h
@@ -20,16 +20,14 @@
* under the License.
*/
-#include "qpid/ImportExport.h"
-
+#if defined(WIN32) && !defined(QPID_DECLARE_STATIC)
#if defined(CONSOLE_EXPORT) || defined (qmfconsole_EXPORTS)
-# define QPID_CONSOLE_EXTERN QPID_EXPORT
-# define QPID_CONSOLE_CLASS_EXTERN QPID_CLASS_EXPORT
-# define QPID_CONSOLE_INLINE_EXTERN QPID_INLINE_EXPORT
+#define QPID_CONSOLE_EXTERN __declspec(dllexport)
+#else
+#define QPID_CONSOLE_EXTERN __declspec(dllimport)
+#endif
#else
-# define QPID_CONSOLE_EXTERN QPID_IMPORT
-# define QPID_CONSOLE_CLASS_EXTERN QPID_CLASS_IMPORT
-# define QPID_CONSOLE_INLINE_EXTERN QPID_INLINE_IMPORT
+#define QPID_CONSOLE_EXTERN
#endif
#endif
diff --git a/qpid/cpp/include/qpid/framing/Array.h b/qpid/cpp/include/qpid/framing/Array.h
index 1e97be3bb4..d3bdd36aa6 100644
--- a/qpid/cpp/include/qpid/framing/Array.h
+++ b/qpid/cpp/include/qpid/framing/Array.h
@@ -34,7 +34,7 @@ namespace framing {
class Buffer;
-class QPID_COMMON_CLASS_EXTERN Array
+class Array
{
public:
typedef boost::shared_ptr<FieldValue> ValuePtr;
@@ -55,25 +55,25 @@ class QPID_COMMON_CLASS_EXTERN Array
//creates a longstr array
QPID_COMMON_EXTERN Array(const std::vector<std::string>& in);
- QPID_COMMON_INLINE_EXTERN TypeCode getType() const { return type; }
+ QPID_COMMON_EXTERN TypeCode getType() const { return type; }
// std collection interface.
- QPID_COMMON_INLINE_EXTERN const_iterator begin() const { return values.begin(); }
- QPID_COMMON_INLINE_EXTERN const_iterator end() const { return values.end(); }
- QPID_COMMON_INLINE_EXTERN iterator begin() { return values.begin(); }
- QPID_COMMON_INLINE_EXTERN iterator end(){ return values.end(); }
+ 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_INLINE_EXTERN ValuePtr front() const { return values.front(); }
- QPID_COMMON_INLINE_EXTERN ValuePtr back() const { return values.back(); }
- QPID_COMMON_INLINE_EXTERN size_t size() const { return values.size(); }
+ 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_INLINE_EXTERN void erase(iterator i) { values.erase(i); }
- QPID_COMMON_INLINE_EXTERN void push_back(ValuePtr value) { values.insert(end(), value); }
- QPID_COMMON_INLINE_EXTERN void pop_back() { values.pop_back(); }
+ 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
- QPID_COMMON_INLINE_EXTERN 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
diff --git a/qpid/cpp/include/qpid/framing/Buffer.h b/qpid/cpp/include/qpid/framing/Buffer.h
index 8b08e60762..04583433c5 100644
--- a/qpid/cpp/include/qpid/framing/Buffer.h
+++ b/qpid/cpp/include/qpid/framing/Buffer.h
@@ -29,14 +29,14 @@
namespace qpid {
namespace framing {
-struct QPID_COMMON_CLASS_EXTERN OutOfBounds : qpid::Exception {
+struct OutOfBounds : qpid::Exception {
OutOfBounds() : qpid::Exception(std::string("Out of Bounds")) {}
};
class Content;
class FieldTable;
-class QPID_COMMON_CLASS_EXTERN Buffer
+class Buffer
{
uint32_t size;
char* data;
@@ -72,12 +72,12 @@ class QPID_COMMON_CLASS_EXTERN Buffer
QPID_COMMON_EXTERN void restore(bool reRecord = false);
QPID_COMMON_EXTERN void reset();
- QPID_COMMON_INLINE_EXTERN uint32_t available() { return size - position; }
- QPID_COMMON_INLINE_EXTERN uint32_t getSize() { return size; }
- QPID_COMMON_INLINE_EXTERN uint32_t getPosition() { return position; }
- QPID_COMMON_INLINE_EXTERN void setPosition(uint32_t p) { position = p; }
- QPID_COMMON_INLINE_EXTERN Iterator getIterator() { return Iterator(*this); }
- QPID_COMMON_INLINE_EXTERN 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 void setPosition(uint32_t p) { position = p; }
+ QPID_COMMON_EXTERN Iterator getIterator() { return Iterator(*this); }
+ QPID_COMMON_EXTERN char* getPointer() { return data; }
QPID_COMMON_EXTERN void putOctet(uint8_t i);
QPID_COMMON_EXTERN void putShort(uint16_t i);
diff --git a/qpid/cpp/include/qpid/framing/FieldTable.h b/qpid/cpp/include/qpid/framing/FieldTable.h
index bdcef6d7fd..fdb1a28b9d 100644
--- a/qpid/cpp/include/qpid/framing/FieldTable.h
+++ b/qpid/cpp/include/qpid/framing/FieldTable.h
@@ -56,7 +56,7 @@ class FieldTable
typedef ValueMap::reference reference;
typedef ValueMap::value_type value_type;
- QPID_COMMON_INLINE_EXTERN FieldTable() {};
+ QPID_COMMON_EXTERN FieldTable() {};
QPID_COMMON_EXTERN FieldTable(const FieldTable& ft);
QPID_COMMON_EXTERN ~FieldTable();
QPID_COMMON_EXTERN FieldTable& operator=(const FieldTable& ft);
@@ -65,11 +65,9 @@ class FieldTable
QPID_COMMON_EXTERN void decode(Buffer& buffer);
QPID_COMMON_EXTERN int count() const;
- QPID_COMMON_INLINE_EXTERN size_t size() const { return values.size(); }
- QPID_COMMON_INLINE_EXTERN bool empty() { return size() == 0; }
QPID_COMMON_EXTERN void set(const std::string& name, const ValuePtr& value);
QPID_COMMON_EXTERN ValuePtr get(const std::string& name) const;
- QPID_COMMON_INLINE_EXTERN bool isSet(const std::string& name) const { return get(name).get() != 0; }
+ 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);
diff --git a/qpid/cpp/include/qpid/framing/FieldValue.h b/qpid/cpp/include/qpid/framing/FieldValue.h
index 458de62fdf..19220e74d5 100644
--- a/qpid/cpp/include/qpid/framing/FieldValue.h
+++ b/qpid/cpp/include/qpid/framing/FieldValue.h
@@ -41,14 +41,14 @@ namespace framing {
*
* \ingroup clientapi
*/
-class QPID_COMMON_CLASS_EXTERN FieldValueException : public qpid::Exception {};
+class FieldValueException : public qpid::Exception {};
/**
* Exception thrown when we can't perform requested conversion
*
* \ingroup clientapi
*/
-struct QPID_COMMON_CLASS_EXTERN InvalidConversionException : public FieldValueException {
+struct InvalidConversionException : public FieldValueException {
InvalidConversionException() {}
};
@@ -59,7 +59,7 @@ class List;
*
* \ingroup clientapi
*/
-class QPID_COMMON_CLASS_EXTERN FieldValue {
+class FieldValue {
public:
/*
* Abstract type for content of different types
@@ -90,7 +90,7 @@ class QPID_COMMON_CLASS_EXTERN FieldValue {
void encode(Buffer& buffer);
void decode(Buffer& buffer);
QPID_COMMON_EXTERN bool operator==(const FieldValue&) const;
- QPID_COMMON_INLINE_EXTERN bool operator!=(const FieldValue& v) const { return !(*this == v); }
+ QPID_COMMON_EXTERN bool operator!=(const FieldValue& v) const { return !(*this == v); }
QPID_COMMON_EXTERN void print(std::ostream& out) const;
@@ -98,7 +98,6 @@ class QPID_COMMON_CLASS_EXTERN FieldValue {
template <typename T> T get() const { throw InvalidConversionException(); }
template <class T, int W> T getIntegerValue() const;
- template <class T> T getIntegerValue() const;
template <class T, int W> T getFloatingPointValue() const;
template <int W> void getFixedWidthValue(unsigned char*) const;
template <class T> bool get(T&) const;
@@ -197,18 +196,6 @@ inline T FieldValue::getIntegerValue() const
}
}
-template <class T>
-inline T FieldValue::getIntegerValue() const
-{
- FixedWidthValue<1>* const fwv = dynamic_cast< FixedWidthValue<1>* const>(data.get());
- if (fwv) {
- uint8_t* octets = fwv->rawOctets();
- return octets[0];
- } else {
- throw InvalidConversionException();
- }
-}
-
template <class T, int W>
inline T FieldValue::getFloatingPointValue() const {
FixedWidthValue<W>* const fwv = dynamic_cast< FixedWidthValue<W>* const>(data.get());
diff --git a/qpid/cpp/include/qpid/framing/List.h b/qpid/cpp/include/qpid/framing/List.h
index 681445947c..0f17c7884c 100644
--- a/qpid/cpp/include/qpid/framing/List.h
+++ b/qpid/cpp/include/qpid/framing/List.h
@@ -36,11 +36,10 @@ class FieldValue;
/**
* Representation of an AMQP 0-10 list
*/
-class QPID_COMMON_CLASS_EXTERN List
+class List
{
public:
typedef boost::shared_ptr<FieldValue> ValuePtr;
- typedef ValuePtr value_type;
typedef std::list<ValuePtr> Values;
typedef Values::const_iterator const_iterator;
typedef Values::iterator iterator;
@@ -54,19 +53,19 @@ class QPID_COMMON_CLASS_EXTERN List
QPID_COMMON_EXTERN bool operator==(const List& other) const;
// std collection interface.
- QPID_COMMON_INLINE_EXTERN const_iterator begin() const { return values.begin(); }
- QPID_COMMON_INLINE_EXTERN const_iterator end() const { return values.end(); }
- QPID_COMMON_INLINE_EXTERN iterator begin() { return values.begin(); }
- QPID_COMMON_INLINE_EXTERN iterator end(){ return values.end(); }
+ 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_INLINE_EXTERN ValuePtr front() const { return values.front(); }
- QPID_COMMON_INLINE_EXTERN ValuePtr back() const { return values.back(); }
- QPID_COMMON_INLINE_EXTERN size_t size() const { return values.size(); }
+ 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_INLINE_EXTERN iterator insert(iterator i, ValuePtr value) { return values.insert(i, value); }
- QPID_COMMON_INLINE_EXTERN void erase(iterator i) { values.erase(i); }
- QPID_COMMON_INLINE_EXTERN void push_back(ValuePtr value) { values.insert(end(), value); }
- QPID_COMMON_INLINE_EXTERN void pop_back() { values.pop_back(); }
+ QPID_COMMON_EXTERN iterator insert(iterator i, ValuePtr value) { return values.insert(i, 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(); }
private:
Values values;
diff --git a/qpid/cpp/include/qpid/framing/ProtocolVersion.h b/qpid/cpp/include/qpid/framing/ProtocolVersion.h
index 30094c165d..e7e75d75f6 100644
--- a/qpid/cpp/include/qpid/framing/ProtocolVersion.h
+++ b/qpid/cpp/include/qpid/framing/ProtocolVersion.h
@@ -29,7 +29,7 @@ namespace qpid
namespace framing
{
-class QPID_COMMON_CLASS_EXTERN ProtocolVersion
+class ProtocolVersion
{
private:
uint8_t major_;
@@ -39,16 +39,16 @@ public:
explicit ProtocolVersion(uint8_t _major=0, uint8_t _minor=0)
: major_(_major), minor_(_minor) {}
- QPID_COMMON_INLINE_EXTERN uint8_t getMajor() const { return major_; }
- QPID_COMMON_INLINE_EXTERN void setMajor(uint8_t major) { major_ = major; }
- QPID_COMMON_INLINE_EXTERN uint8_t getMinor() const { return minor_; }
- QPID_COMMON_INLINE_EXTERN void setMinor(uint8_t minor) { minor_ = minor; }
+ 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;
QPID_COMMON_EXTERN ProtocolVersion& operator=(ProtocolVersion p);
QPID_COMMON_EXTERN bool operator==(ProtocolVersion p) const;
- QPID_COMMON_INLINE_EXTERN bool operator!=(ProtocolVersion p) const { return ! (*this == p); }
+ QPID_COMMON_EXTERN bool operator!=(ProtocolVersion p) const { return ! (*this == p); }
};
} // namespace framing
diff --git a/qpid/cpp/include/qpid/framing/SequenceNumber.h b/qpid/cpp/include/qpid/framing/SequenceNumber.h
index eed15a4b75..1e53058df8 100644
--- a/qpid/cpp/include/qpid/framing/SequenceNumber.h
+++ b/qpid/cpp/include/qpid/framing/SequenceNumber.h
@@ -34,7 +34,7 @@ class Buffer;
/**
* 4-byte sequence number that 'wraps around'.
*/
-class QPID_COMMON_CLASS_EXTERN SequenceNumber : public
+class SequenceNumber : public
boost::equality_comparable<
SequenceNumber, boost::less_than_comparable<
SequenceNumber, boost::incrementable<
diff --git a/qpid/cpp/include/qpid/framing/SequenceSet.h b/qpid/cpp/include/qpid/framing/SequenceSet.h
index 0a78e418ba..39395e9ad7 100644
--- a/qpid/cpp/include/qpid/framing/SequenceSet.h
+++ b/qpid/cpp/include/qpid/framing/SequenceSet.h
@@ -29,7 +29,7 @@ namespace qpid {
namespace framing {
class Buffer;
-class QPID_COMMON_CLASS_EXTERN SequenceSet : public RangeSet<SequenceNumber> {
+class SequenceSet : public RangeSet<SequenceNumber> {
public:
SequenceSet() {}
SequenceSet(const RangeSet<SequenceNumber>& r)
diff --git a/qpid/cpp/include/qpid/framing/StructHelper.h b/qpid/cpp/include/qpid/framing/StructHelper.h
index 21f9b91fa9..fc9a7909cc 100644
--- a/qpid/cpp/include/qpid/framing/StructHelper.h
+++ b/qpid/cpp/include/qpid/framing/StructHelper.h
@@ -30,7 +30,7 @@
namespace qpid {
namespace framing {
-class QPID_COMMON_CLASS_EXTERN StructHelper
+class StructHelper
{
public:
diff --git a/qpid/cpp/include/qpid/framing/Uuid.h b/qpid/cpp/include/qpid/framing/Uuid.h
index ccfd7e9534..d0a8d02411 100644
--- a/qpid/cpp/include/qpid/framing/Uuid.h
+++ b/qpid/cpp/include/qpid/framing/Uuid.h
@@ -52,22 +52,22 @@ struct Uuid : public boost::array<uint8_t, 16> {
// boost::array gives us ==, < etc.
/** Copy from 16 bytes of data. */
- QPID_COMMON_EXTERN void assign(const uint8_t* data);
+ void assign(const uint8_t* data);
/** Set to a new unique identifier. */
QPID_COMMON_EXTERN void generate();
/** Set to all zeros. */
- QPID_COMMON_EXTERN void clear();
+ void clear();
/** Test for null (all zeros). */
QPID_COMMON_EXTERN bool isNull() const;
- QPID_COMMON_INLINE_EXTERN operator bool() const { return !isNull(); }
- QPID_COMMON_INLINE_EXTERN bool operator!() const { return isNull(); }
+ operator bool() const { return !isNull(); }
+ bool operator!() const { return isNull(); }
QPID_COMMON_EXTERN void encode(framing::Buffer& buf) const;
QPID_COMMON_EXTERN void decode(framing::Buffer& buf);
- QPID_COMMON_INLINE_EXTERN uint32_t encodedSize() const
+ QPID_COMMON_EXTERN uint32_t encodedSize() const
{ return static_cast<uint32_t>(size()); }
/** String value in format 1b4e28ba-2fa1-11d2-883f-b9a761bde3fb. */
diff --git a/qpid/cpp/include/qpid/log/Logger.h b/qpid/cpp/include/qpid/log/Logger.h
index d255b7e150..783ab7bdb9 100644
--- a/qpid/cpp/include/qpid/log/Logger.h
+++ b/qpid/cpp/include/qpid/log/Logger.h
@@ -33,10 +33,10 @@ namespace log {
* is handled by Logger::Output-derived classes instantiated by the
* platform's sink-related options.
*/
-class QPID_COMMON_CLASS_EXTERN Logger : private boost::noncopyable {
+class Logger : private boost::noncopyable {
public:
/** Flags indicating what to include in the log output */
- enum FormatFlag { FILE=1, LINE=2, FUNCTION=4, LEVEL=8, TIME=16, THREAD=32, HIRES=64};
+ enum FormatFlag { FILE=1, LINE=2, FUNCTION=4, LEVEL=8, TIME=16, THREAD=32};
/**
* Logging output sink.
@@ -93,7 +93,7 @@ class QPID_COMMON_CLASS_EXTERN Logger : private boost::noncopyable {
QPID_COMMON_EXTERN void clear();
/** Get the options used to configure the logger. */
- QPID_COMMON_INLINE_EXTERN const Options& getOptions() const { return options; }
+ QPID_COMMON_EXTERN const Options& getOptions() const { return options; }
private:
diff --git a/qpid/cpp/include/qpid/log/Options.h b/qpid/cpp/include/qpid/log/Options.h
index 17cbfde9bc..bbc47b47d3 100644
--- a/qpid/cpp/include/qpid/log/Options.h
+++ b/qpid/cpp/include/qpid/log/Options.h
@@ -39,7 +39,7 @@ struct Options : public qpid::Options {
std::string argv0;
std::string name;
std::vector<std::string> selectors;
- bool time, level, thread, source, function, hiresTs;
+ bool time, level, thread, source, function;
bool trace;
std::string prefix;
std::auto_ptr<SinkOptions> sinkOptions;
diff --git a/qpid/cpp/include/qpid/management/ManagementObject.h b/qpid/cpp/include/qpid/management/ManagementObject.h
index 16bf21038c..747edda150 100644
--- a/qpid/cpp/include/qpid/management/ManagementObject.h
+++ b/qpid/cpp/include/qpid/management/ManagementObject.h
@@ -58,14 +58,14 @@ protected:
std::string agentName;
void fromString(const std::string&);
public:
- QPID_COMMON_INLINE_EXTERN ObjectId() : agent(0), first(0), second(0), agentEpoch(0) {}
- QPID_COMMON_INLINE_EXTERN ObjectId(const types::Variant& map) :
+ QPID_COMMON_EXTERN ObjectId() : agent(0), first(0), second(0), agentEpoch(0) {}
+ QPID_COMMON_EXTERN ObjectId(const types::Variant& map) :
agent(0), first(0), second(0), agentEpoch(0) { mapDecode(map.asMap()); }
QPID_COMMON_EXTERN ObjectId(uint8_t flags, uint16_t seq, uint32_t broker);
QPID_COMMON_EXTERN ObjectId(AgentAttachment* _agent, uint8_t flags, uint16_t seq);
QPID_COMMON_EXTERN ObjectId(std::istream&);
QPID_COMMON_EXTERN ObjectId(const std::string&);
- QPID_COMMON_INLINE_EXTERN ObjectId(const std::string& agentAddress, const std::string& key,
+ QPID_COMMON_EXTERN ObjectId(const std::string& agentAddress, const std::string& key,
uint64_t epoch=0) : agent(0), first(0), second(0),
agentEpoch(epoch), v2Key(key), agentName(agentAddress) {}
@@ -76,15 +76,15 @@ public:
QPID_COMMON_EXTERN void mapEncode(types::Variant::Map& map) const;
QPID_COMMON_EXTERN void mapDecode(const types::Variant::Map& map);
QPID_COMMON_EXTERN operator types::Variant::Map() const;
- QPID_COMMON_INLINE_EXTERN uint32_t encodedSize() const { return 16; };
+ QPID_COMMON_EXTERN uint32_t encodedSize() const { return 16; };
QPID_COMMON_EXTERN void encode(std::string& buffer) const;
QPID_COMMON_EXTERN void decode(const std::string& buffer);
QPID_COMMON_EXTERN bool equalV1(const ObjectId &other) const;
- QPID_COMMON_INLINE_EXTERN void setV2Key(const std::string& _key) { v2Key = _key; }
+ QPID_COMMON_EXTERN void setV2Key(const std::string& _key) { v2Key = _key; }
QPID_COMMON_EXTERN void setV2Key(const ManagementObject& object);
- QPID_COMMON_INLINE_EXTERN void setAgentName(const std::string& _name) { agentName = _name; }
- QPID_COMMON_INLINE_EXTERN const std::string& getAgentName() const { return agentName; }
- QPID_COMMON_INLINE_EXTERN const std::string& getV2Key() const { return v2Key; }
+ QPID_COMMON_EXTERN void setAgentName(const std::string& _name) { agentName = _name; }
+ QPID_COMMON_EXTERN const std::string& getAgentName() const { return agentName; }
+ QPID_COMMON_EXTERN const std::string& getV2Key() const { return v2Key; }
friend QPID_COMMON_EXTERN std::ostream& operator<<(std::ostream&, const ObjectId&);
};
@@ -131,7 +131,7 @@ public:
virtual ~ManagementItem() {}
};
-class QPID_COMMON_CLASS_EXTERN ManagementObject : public ManagementItem
+class ManagementObject : public ManagementItem
{
protected:
diff --git a/qpid/cpp/include/qpid/messaging/Address.h b/qpid/cpp/include/qpid/messaging/Address.h
index 63dce0c49d..bebbfc72f6 100644
--- a/qpid/cpp/include/qpid/messaging/Address.h
+++ b/qpid/cpp/include/qpid/messaging/Address.h
@@ -119,7 +119,7 @@ class AddressImpl;
*
* An address has value semantics.
*/
-class QPID_MESSAGING_CLASS_EXTERN Address
+class Address
{
public:
QPID_MESSAGING_EXTERN Address();
diff --git a/qpid/cpp/include/qpid/messaging/Connection.h b/qpid/cpp/include/qpid/messaging/Connection.h
index 165573e2ef..1ad7a7242f 100644
--- a/qpid/cpp/include/qpid/messaging/Connection.h
+++ b/qpid/cpp/include/qpid/messaging/Connection.h
@@ -42,7 +42,7 @@ class Session;
* A connection represents a network connection to a remote endpoint.
*/
-class QPID_MESSAGING_CLASS_EXTERN Connection : public qpid::messaging::Handle<ConnectionImpl>
+class Connection : public qpid::messaging::Handle<ConnectionImpl>
{
public:
QPID_MESSAGING_EXTERN Connection(ConnectionImpl* impl);
@@ -54,27 +54,27 @@ class QPID_MESSAGING_CLASS_EXTERN Connection : public qpid::messaging::Handle<Co
* username
* password
* heartbeat
- * tcp_nodelay
- * sasl_mechanisms
- * sasl_service
- * sasl_min_ssf
- * sasl_max_ssf
+ * tcp-nodelay
+ * sasl-mechanism
+ * sasl-service
+ * sasl-min-ssf
+ * sasl-max-ssf
* transport
*
* Reconnect behaviour can be controlled through the following options:
*
* reconnect: true/false (enables/disables reconnect entirely)
- * reconnect_timeout: number of seconds (give up and report failure after specified time)
- * reconnect_limit: n (give up and report failure after specified number of attempts)
- * reconnect_interval_min: number of seconds (initial delay between failed reconnection attempts)
- * reconnect_interval_max: number of seconds (maximum delay between failed reconnection attempts)
- * reconnect_interval: shorthand for setting the same reconnect_interval_min/max
- * reconnect_urls: list of alternate urls to try when connecting
+ * reconnect-timeout: number of seconds (give up and report failure after specified time)
+ * reconnect-limit: n (give up and report failure after specified number of attempts)
+ * reconnect-interval-min: number of seconds (initial delay between failed reconnection attempts)
+ * reconnect-interval-max: number of seconds (maximum delay between failed reconnection attempts)
+ * reconnect-interval: shorthand for setting the same reconnect_interval_min/max
+ * reconnect-urls: list of alternate urls to try when connecting
*
- * The reconnect_interval is the time that the client waits
+ * The reconnect-interval is the time that the client waits
* for after a failed attempt to reconnect before retrying. It
- * starts at the value of the min_retry_interval and is
- * doubled every failure until the value of max_retry_interval
+ * starts at the value of the min-retry-interval and is
+ * doubled every failure until the value of max-retry-interval
* is reached.
*/
QPID_MESSAGING_EXTERN Connection(const std::string& url, const qpid::types::Variant::Map& options = qpid::types::Variant::Map());
diff --git a/qpid/cpp/include/qpid/messaging/Duration.h b/qpid/cpp/include/qpid/messaging/Duration.h
index 6b8f05c7c6..abcf169090 100644
--- a/qpid/cpp/include/qpid/messaging/Duration.h
+++ b/qpid/cpp/include/qpid/messaging/Duration.h
@@ -32,7 +32,7 @@ namespace messaging {
/** \ingroup messaging
* A duration is a time in milliseconds.
*/
-class QPID_MESSAGING_CLASS_EXTERN Duration
+class Duration
{
public:
QPID_MESSAGING_EXTERN explicit Duration(uint64_t milliseconds);
@@ -46,11 +46,9 @@ class QPID_MESSAGING_CLASS_EXTERN Duration
};
QPID_MESSAGING_EXTERN Duration operator*(const Duration& duration,
- uint64_t multiplier);
+ uint64_t multiplier);
QPID_MESSAGING_EXTERN Duration operator*(uint64_t multiplier,
- const Duration& duration);
-QPID_MESSAGING_EXTERN bool operator==(const Duration& a, const Duration& b);
-QPID_MESSAGING_EXTERN bool operator!=(const Duration& a, const Duration& b);
+ const Duration& duration);
}} // namespace qpid::messaging
diff --git a/qpid/cpp/include/qpid/messaging/FailoverUpdates.h b/qpid/cpp/include/qpid/messaging/FailoverUpdates.h
index 6d7314620a..14a1a31b63 100644
--- a/qpid/cpp/include/qpid/messaging/FailoverUpdates.h
+++ b/qpid/cpp/include/qpid/messaging/FailoverUpdates.h
@@ -32,7 +32,7 @@ struct FailoverUpdatesImpl;
* A utility to listen for updates on cluster membership and update
* the list of known urls for a connection accordingly.
*/
-class QPID_MESSAGING_CLASS_EXTERN FailoverUpdates
+class FailoverUpdates
{
public:
QPID_MESSAGING_EXTERN FailoverUpdates(Connection& connection);
diff --git a/qpid/cpp/include/qpid/messaging/Handle.h b/qpid/cpp/include/qpid/messaging/Handle.h
index 97a8f00b54..1e634ef888 100644
--- a/qpid/cpp/include/qpid/messaging/Handle.h
+++ b/qpid/cpp/include/qpid/messaging/Handle.h
@@ -40,22 +40,22 @@ template <class T> class Handle {
public:
/**@return true if handle is valid, i.e. not null. */
- QPID_MESSAGING_INLINE_EXTERN bool isValid() const { return impl; }
+ QPID_MESSAGING_EXTERN bool isValid() const { return impl; }
/**@return true if handle is null. It is an error to call any function on a null handle. */
- QPID_MESSAGING_INLINE_EXTERN bool isNull() const { return !impl; }
+ QPID_MESSAGING_EXTERN bool isNull() const { return !impl; }
/** Conversion to bool supports idiom if (handle) { handle->... } */
- QPID_MESSAGING_INLINE_EXTERN operator bool() const { return impl; }
+ QPID_MESSAGING_EXTERN operator bool() const { return impl; }
/** Operator ! supports idiom if (!handle) { do_if_handle_is_null(); } */
- QPID_MESSAGING_INLINE_EXTERN bool operator !() const { return !impl; }
+ QPID_MESSAGING_EXTERN bool operator !() const { return !impl; }
void swap(Handle<T>& h) { T* t = h.impl; h.impl = impl; impl = t; }
protected:
typedef T Impl;
- QPID_MESSAGING_INLINE_EXTERN Handle() :impl() {}
+ QPID_MESSAGING_EXTERN Handle() :impl() {}
// Not implemented,subclasses must implement.
QPID_MESSAGING_EXTERN Handle(const Handle&);
diff --git a/qpid/cpp/include/qpid/messaging/ImportExport.h b/qpid/cpp/include/qpid/messaging/ImportExport.h
index ab5f21f618..52f3eb8568 100644
--- a/qpid/cpp/include/qpid/messaging/ImportExport.h
+++ b/qpid/cpp/include/qpid/messaging/ImportExport.h
@@ -20,16 +20,14 @@
* under the License.
*/
-#include "qpid/ImportExport.h"
-
+#if defined(WIN32) && !defined(QPID_DECLARE_STATIC)
#if defined(CLIENT_EXPORT) || defined (qpidmessaging_EXPORTS)
-# define QPID_MESSAGING_EXTERN QPID_EXPORT
-# define QPID_MESSAGING_CLASS_EXTERN QPID_CLASS_EXPORT
-# define QPID_MESSAGING_INLINE_EXTERN QPID_INLINE_EXPORT
+#define QPID_MESSAGING_EXTERN __declspec(dllexport)
+#else
+#define QPID_MESSAGING_EXTERN __declspec(dllimport)
+#endif
#else
-# define QPID_MESSAGING_EXTERN QPID_IMPORT
-# define QPID_MESSAGING_CLASS_EXTERN QPID_CLASS_IMPORT
-# define QPID_MESSAGING_INLINE_EXTERN QPID_INLINE_IMPORT
+#define QPID_MESSAGING_EXTERN
#endif
#endif /*!QPID_MESSAGING_IMPORTEXPORT_H*/
diff --git a/qpid/cpp/include/qpid/messaging/Message.h b/qpid/cpp/include/qpid/messaging/Message.h
index e89a6ce02f..d48af35cc0 100644
--- a/qpid/cpp/include/qpid/messaging/Message.h
+++ b/qpid/cpp/include/qpid/messaging/Message.h
@@ -39,7 +39,7 @@ struct MessageImpl;
/** \ingroup messaging
* Representation of a message.
*/
-class QPID_MESSAGING_CLASS_EXTERN Message
+class Message
{
public:
QPID_MESSAGING_EXTERN Message(const std::string& bytes = std::string());
@@ -55,58 +55,23 @@ class QPID_MESSAGING_CLASS_EXTERN Message
QPID_MESSAGING_EXTERN void setSubject(const std::string&);
QPID_MESSAGING_EXTERN const std::string& getSubject() const;
- /**
- * Set the content type (i.e. the MIME type) for the message. This
- * should be set by the sending application and indicates to
- * recipients of message how to interpret or decode the content.
- */
QPID_MESSAGING_EXTERN void setContentType(const std::string&);
- /**
- * Returns the content type (i.e. the MIME type) for the
- * message. This can be used to determine how to decode the
- * message content.
- */
QPID_MESSAGING_EXTERN const std::string& getContentType() const;
- /**
- * Set an application defined identifier for the message. At
- * present this must be a stringfied UUID (support for less
- * restrictive IDs is anticipated however).
- */
QPID_MESSAGING_EXTERN void setMessageId(const std::string&);
QPID_MESSAGING_EXTERN const std::string& getMessageId() const;
- /**
- * Sets the user id of the message. This should in general be the
- * user-id as which the sending connection authenticated itself as
- * the messaging infrastructure will verify this. See
- * Connection::getAuthenticatedUsername()
- */
QPID_MESSAGING_EXTERN void setUserId(const std::string&);
QPID_MESSAGING_EXTERN const std::string& getUserId() const;
- /**
- * Can be used to set application specific correlation identifiers
- * as part of a protocol for message exchange patterns. E.g. a
- * request-reponse pattern might require the correlation-id of the
- * request and response to match, or might use the message-id of
- * the request as the correlation-id on the response etc.
- */
QPID_MESSAGING_EXTERN void setCorrelationId(const std::string&);
QPID_MESSAGING_EXTERN const std::string& getCorrelationId() const;
- /**
- * Sets a priority level on the message. This may be used by the
- * messaging infrastructure to prioritise delivery of higher
- * priority messages.
- */
QPID_MESSAGING_EXTERN void setPriority(uint8_t);
QPID_MESSAGING_EXTERN uint8_t getPriority() const;
/**
- * Set the time to live for this message in milliseconds. This can
- * be used by the messaging infrastructure to discard messages
- * that are no longer of relevance.
+ * Set the time to live for this message in milliseconds.
*/
QPID_MESSAGING_EXTERN void setTtl(Duration ttl);
/**
@@ -114,62 +79,24 @@ class QPID_MESSAGING_CLASS_EXTERN Message
*/
QPID_MESSAGING_EXTERN Duration getTtl() const;
- /**
- * Mark the message as durable. This is a hint to the messaging
- * infrastructure that the message should be persisted or
- * otherwise stored such that failoures or shutdown do not cause
- * it to be lost.
- */
QPID_MESSAGING_EXTERN void setDurable(bool durable);
QPID_MESSAGING_EXTERN bool getDurable() const;
- /**
- * The redelivered flag if set implies that the message *may* have
- * been previously delivered and thus is a hint to the application
- * or messaging infrastructure that if de-duplication is required
- * this message should be examined to determine if it is a
- * duplicate.
- */
QPID_MESSAGING_EXTERN bool getRedelivered() const;
- /**
- * Can be used to provide a hint to the application or messaging
- * infrastructure that if de-duplication is required this message
- * should be examined to determine if it is a duplicate.
- */
QPID_MESSAGING_EXTERN void setRedelivered(bool);
- /**
- * In addition to a payload (i.e. the content), messages can
- * include annotations describing aspectf of the message. In
- * addition to the standard annotations such as TTL and content
- * type, application- or context- specific properties can also be
- * defined. Each message has a map of name values for such custom
- * properties. The value is specified as a Variant.
- */
QPID_MESSAGING_EXTERN const qpid::types::Variant::Map& getProperties() const;
QPID_MESSAGING_EXTERN qpid::types::Variant::Map& getProperties();
- /**
- * Set the content to the data held in the string parameter. Note:
- * this is treated as raw bytes and need not be text. Consider
- * setting the content-type to indicate how the data should be
- * interpreted by recipients.
- */
QPID_MESSAGING_EXTERN void setContent(const std::string&);
/**
- * Copy count bytes from the region pointed to by chars as the
- * message content.
+ * Note that chars are copied.
*/
QPID_MESSAGING_EXTERN void setContent(const char* chars, size_t count);
/** Get the content as a std::string */
QPID_MESSAGING_EXTERN std::string getContent() const;
- /**
- * Get a const pointer to the start of the content data. The
- * memory pointed to is owned by the message. The getContentSize()
- * method indicates how much data there is (i.e. the extent of the
- * memory region pointed to by the return value of this method).
- */
+ /** Get a const pointer to the start of the content data. */
QPID_MESSAGING_EXTERN const char* getContentPtr() const;
/** Get the size of content in bytes. */
QPID_MESSAGING_EXTERN size_t getContentSize() const;
@@ -180,9 +107,9 @@ class QPID_MESSAGING_CLASS_EXTERN Message
friend struct MessageImplAccess;
};
-struct QPID_MESSAGING_CLASS_EXTERN EncodingException : qpid::types::Exception
+struct EncodingException : qpid::types::Exception
{
- QPID_MESSAGING_EXTERN EncodingException(const std::string& msg);
+ EncodingException(const std::string& msg);
};
/**
@@ -195,8 +122,8 @@ struct QPID_MESSAGING_CLASS_EXTERN EncodingException : qpid::types::Exception
* @exception EncodingException
*/
QPID_MESSAGING_EXTERN void decode(const Message& message,
- qpid::types::Variant::Map& map,
- const std::string& encoding = std::string());
+ qpid::types::Variant::Map& map,
+ const std::string& encoding = std::string());
/**
* Decodes message content into a Variant::List.
*
@@ -207,8 +134,8 @@ QPID_MESSAGING_EXTERN void decode(const Message& message,
* @exception EncodingException
*/
QPID_MESSAGING_EXTERN void decode(const Message& message,
- qpid::types::Variant::List& list,
- const std::string& encoding = std::string());
+ qpid::types::Variant::List& list,
+ const std::string& encoding = std::string());
/**
* Encodes a Variant::Map into a message.
*
@@ -219,8 +146,8 @@ QPID_MESSAGING_EXTERN void decode(const Message& message,
* @exception EncodingException
*/
QPID_MESSAGING_EXTERN void encode(const qpid::types::Variant::Map& map,
- Message& message,
- const std::string& encoding = std::string());
+ Message& message,
+ const std::string& encoding = std::string());
/**
* Encodes a Variant::List into a message.
*
@@ -231,8 +158,8 @@ QPID_MESSAGING_EXTERN void encode(const qpid::types::Variant::Map& map,
* @exception EncodingException
*/
QPID_MESSAGING_EXTERN void encode(const qpid::types::Variant::List& list,
- Message& message,
- const std::string& encoding = std::string());
+ Message& message,
+ const std::string& encoding = std::string());
}} // namespace qpid::messaging
diff --git a/qpid/cpp/include/qpid/messaging/Receiver.h b/qpid/cpp/include/qpid/messaging/Receiver.h
index 13317dfcbd..6f3ae961db 100644
--- a/qpid/cpp/include/qpid/messaging/Receiver.h
+++ b/qpid/cpp/include/qpid/messaging/Receiver.h
@@ -41,7 +41,7 @@ class Session;
/** \ingroup messaging
* Interface through which messages are received.
*/
-class QPID_MESSAGING_CLASS_EXTERN Receiver : public qpid::messaging::Handle<ReceiverImpl>
+class Receiver : public qpid::messaging::Handle<ReceiverImpl>
{
public:
QPID_MESSAGING_EXTERN Receiver(ReceiverImpl* impl = 0);
diff --git a/qpid/cpp/include/qpid/messaging/Sender.h b/qpid/cpp/include/qpid/messaging/Sender.h
index 8e1c5846e9..85658f37cc 100644
--- a/qpid/cpp/include/qpid/messaging/Sender.h
+++ b/qpid/cpp/include/qpid/messaging/Sender.h
@@ -40,7 +40,7 @@ class Session;
/** \ingroup messaging
* Interface through which messages are sent.
*/
-class QPID_MESSAGING_CLASS_EXTERN Sender : public qpid::messaging::Handle<SenderImpl>
+class Sender : public qpid::messaging::Handle<SenderImpl>
{
public:
QPID_MESSAGING_EXTERN Sender(SenderImpl* impl = 0);
diff --git a/qpid/cpp/include/qpid/messaging/Session.h b/qpid/cpp/include/qpid/messaging/Session.h
index 428f8aa491..6c023629e0 100644
--- a/qpid/cpp/include/qpid/messaging/Session.h
+++ b/qpid/cpp/include/qpid/messaging/Session.h
@@ -46,7 +46,7 @@ class SessionImpl;
* A session represents a distinct 'conversation' which can involve
* sending and receiving messages to and from different addresses.
*/
-class QPID_MESSAGING_CLASS_EXTERN Session : public qpid::messaging::Handle<SessionImpl>
+class Session : public qpid::messaging::Handle<SessionImpl>
{
public:
QPID_MESSAGING_EXTERN Session(SessionImpl* impl = 0);
@@ -78,10 +78,6 @@ class QPID_MESSAGING_CLASS_EXTERN Session : public qpid::messaging::Handle<Sessi
*/
QPID_MESSAGING_EXTERN void acknowledge(Message&, bool sync=false);
/**
- * Acknowledges all message up to the specified message.
- */
- QPID_MESSAGING_EXTERN void acknowledgeUpTo(Message&, bool sync=false);
- /**
* Rejects the specified message. The broker does not redeliver a
* message that has been rejected. Once a message has been
* acknowledged, it can no longer be rejected.
diff --git a/qpid/cpp/include/qpid/messaging/exceptions.h b/qpid/cpp/include/qpid/messaging/exceptions.h
index 07d1dc414b..0ff608b343 100644
--- a/qpid/cpp/include/qpid/messaging/exceptions.h
+++ b/qpid/cpp/include/qpid/messaging/exceptions.h
@@ -32,7 +32,7 @@ namespace messaging {
/** \ingroup messaging
*/
-struct QPID_MESSAGING_CLASS_EXTERN MessagingException : public qpid::types::Exception
+struct MessagingException : public qpid::types::Exception
{
QPID_MESSAGING_EXTERN MessagingException(const std::string& msg);
QPID_MESSAGING_EXTERN virtual ~MessagingException() throw();
@@ -41,22 +41,22 @@ struct QPID_MESSAGING_CLASS_EXTERN MessagingException : public qpid::types::Exce
//TODO: override what() to include detail if present
};
-struct QPID_MESSAGING_CLASS_EXTERN InvalidOptionString : public MessagingException
+struct InvalidOptionString : public MessagingException
{
QPID_MESSAGING_EXTERN InvalidOptionString(const std::string& msg);
};
-struct QPID_MESSAGING_CLASS_EXTERN KeyError : public MessagingException
+struct KeyError : public MessagingException
{
QPID_MESSAGING_EXTERN KeyError(const std::string&);
};
-struct QPID_MESSAGING_CLASS_EXTERN LinkError : public MessagingException
+struct LinkError : public MessagingException
{
QPID_MESSAGING_EXTERN LinkError(const std::string&);
};
-struct QPID_MESSAGING_CLASS_EXTERN AddressError : public LinkError
+struct AddressError : public LinkError
{
QPID_MESSAGING_EXTERN AddressError(const std::string&);
};
@@ -65,17 +65,17 @@ struct QPID_MESSAGING_CLASS_EXTERN AddressError : public LinkError
* Thrown when a syntactically correct address cannot be resolved or
* used.
*/
-struct QPID_MESSAGING_CLASS_EXTERN ResolutionError : public AddressError
+struct ResolutionError : public AddressError
{
QPID_MESSAGING_EXTERN ResolutionError(const std::string& msg);
};
-struct QPID_MESSAGING_CLASS_EXTERN AssertionFailed : public ResolutionError
+struct AssertionFailed : public ResolutionError
{
QPID_MESSAGING_EXTERN AssertionFailed(const std::string& msg);
};
-struct QPID_MESSAGING_CLASS_EXTERN NotFound : public ResolutionError
+struct NotFound : public ResolutionError
{
QPID_MESSAGING_EXTERN NotFound(const std::string& msg);
};
@@ -83,67 +83,67 @@ struct QPID_MESSAGING_CLASS_EXTERN NotFound : public ResolutionError
/**
* Thrown when an address string with inalid sytanx is used.
*/
-struct QPID_MESSAGING_CLASS_EXTERN MalformedAddress : public AddressError
+struct MalformedAddress : public AddressError
{
QPID_MESSAGING_EXTERN MalformedAddress(const std::string& msg);
};
-struct QPID_MESSAGING_CLASS_EXTERN ReceiverError : public LinkError
+struct ReceiverError : public LinkError
{
QPID_MESSAGING_EXTERN ReceiverError(const std::string&);
};
-struct QPID_MESSAGING_CLASS_EXTERN FetchError : public ReceiverError
+struct FetchError : public ReceiverError
{
QPID_MESSAGING_EXTERN FetchError(const std::string&);
};
-struct QPID_MESSAGING_CLASS_EXTERN NoMessageAvailable : public FetchError
+struct NoMessageAvailable : public FetchError
{
QPID_MESSAGING_EXTERN NoMessageAvailable();
};
-struct QPID_MESSAGING_CLASS_EXTERN SenderError : public LinkError
+struct SenderError : public LinkError
{
QPID_MESSAGING_EXTERN SenderError(const std::string&);
};
-struct QPID_MESSAGING_CLASS_EXTERN SendError : public SenderError
+struct SendError : public SenderError
{
QPID_MESSAGING_EXTERN SendError(const std::string&);
};
-struct QPID_MESSAGING_CLASS_EXTERN TargetCapacityExceeded : public SendError
+struct TargetCapacityExceeded : public SendError
{
QPID_MESSAGING_EXTERN TargetCapacityExceeded(const std::string&);
};
-struct QPID_MESSAGING_CLASS_EXTERN SessionError : public MessagingException
+struct SessionError : public MessagingException
{
QPID_MESSAGING_EXTERN SessionError(const std::string&);
};
-struct QPID_MESSAGING_CLASS_EXTERN TransactionError : public SessionError
+struct TransactionError : public SessionError
{
QPID_MESSAGING_EXTERN TransactionError(const std::string&);
};
-struct QPID_MESSAGING_CLASS_EXTERN TransactionAborted : public TransactionError
+struct TransactionAborted : public TransactionError
{
QPID_MESSAGING_EXTERN TransactionAborted(const std::string&);
};
-struct QPID_MESSAGING_CLASS_EXTERN UnauthorizedAccess : public SessionError
+struct UnauthorizedAccess : public SessionError
{
QPID_MESSAGING_EXTERN UnauthorizedAccess(const std::string&);
};
-struct QPID_MESSAGING_CLASS_EXTERN ConnectionError : public MessagingException
+struct ConnectionError : public MessagingException
{
QPID_MESSAGING_EXTERN ConnectionError(const std::string&);
};
-struct QPID_MESSAGING_CLASS_EXTERN TransportFailure : public MessagingException
+struct TransportFailure : public MessagingException
{
QPID_MESSAGING_EXTERN TransportFailure(const std::string&);
};
diff --git a/qpid/cpp/include/qpid/sys/ExceptionHolder.h b/qpid/cpp/include/qpid/sys/ExceptionHolder.h
index 4bc934cf75..9eff1d64c7 100644
--- a/qpid/cpp/include/qpid/sys/ExceptionHolder.h
+++ b/qpid/cpp/include/qpid/sys/ExceptionHolder.h
@@ -10,9 +10,9 @@
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
@@ -42,11 +42,14 @@ class ExceptionHolder : public Raisable {
public:
ExceptionHolder() {}
// Use default copy & assign.
-
+
/** Take ownership of ex */
template <class Ex> ExceptionHolder(Ex* ex) { wrap(ex); }
- template <class Ex> ExceptionHolder& operator=(Ex* ex) { wrap(ex); return *this; }
+ template <class Ex> ExceptionHolder(const boost::shared_ptr<Ex>& ex) { wrap(ex.release()); }
+ template <class Ex> ExceptionHolder& operator=(Ex* ex) { wrap(ex); return *this; }
+ template <class Ex> ExceptionHolder& operator=(boost::shared_ptr<Ex> ex) { wrap(ex.release()); return *this; }
+
void raise() const { if (wrapper.get()) wrapper->raise() ; }
std::string what() const { return wrapper.get() ? wrapper->what() : std::string(); }
bool empty() const { return !wrapper.get(); }
@@ -63,7 +66,7 @@ class ExceptionHolder : public Raisable {
template <class Ex> void wrap(Ex* ex) { wrapper.reset(new Wrapper<Ex>(ex)); }
boost::shared_ptr<Raisable> wrapper;
};
-
+
}} // namespace qpid::sys
diff --git a/qpid/cpp/include/qpid/sys/IntegerTypes.h b/qpid/cpp/include/qpid/sys/IntegerTypes.h
index 75fa921de0..89635f033e 100755
--- a/qpid/cpp/include/qpid/sys/IntegerTypes.h
+++ b/qpid/cpp/include/qpid/sys/IntegerTypes.h
@@ -21,7 +21,7 @@
*
*/
-#if (defined(_WINDOWS) || defined (WIN32))
+#if (defined(_WINDOWS) || defined (WIN32)) && defined(_MSC_VER)
#include "qpid/sys/windows/IntegerTypes.h"
#endif
#if !defined _WINDOWS && !defined WIN32
diff --git a/qpid/cpp/include/qpid/sys/Runnable.h b/qpid/cpp/include/qpid/sys/Runnable.h
index fed7663cb6..0f1243a277 100644
--- a/qpid/cpp/include/qpid/sys/Runnable.h
+++ b/qpid/cpp/include/qpid/sys/Runnable.h
@@ -30,7 +30,7 @@ namespace sys {
/**
* Interface for objects that can be run, e.g. in a thread.
*/
-class QPID_COMMON_CLASS_EXTERN Runnable
+class Runnable
{
public:
/** Type to represent a runnable as a Functor */
diff --git a/qpid/cpp/include/qpid/sys/Thread.h b/qpid/cpp/include/qpid/sys/Thread.h
index f556612908..45a39e796f 100644
--- a/qpid/cpp/include/qpid/sys/Thread.h
+++ b/qpid/cpp/include/qpid/sys/Thread.h
@@ -25,11 +25,7 @@
#include "qpid/CommonImportExport.h"
#ifdef _WIN32
-# ifdef _MSC_VER
-# define QPID_TSS __declspec(thread)
-# else
-# define QPID_TSS __thread
-# endif
+# define QPID_TSS __declspec(thread)
#elif defined (__GNUC__)
# define QPID_TSS __thread
#elif defined (__SUNPRO_CC)
diff --git a/qpid/cpp/include/qpid/sys/Time.h b/qpid/cpp/include/qpid/sys/Time.h
index 9c5ac66e9a..d3ab832229 100644
--- a/qpid/cpp/include/qpid/sys/Time.h
+++ b/qpid/cpp/include/qpid/sys/Time.h
@@ -119,7 +119,7 @@ class Duration {
friend class AbsTime;
public:
- QPID_COMMON_INLINE_EXTERN inline Duration(int64_t time0 = 0);
+ QPID_COMMON_EXTERN inline Duration(int64_t time0 = 0);
QPID_COMMON_EXTERN explicit Duration(const AbsTime& start, const AbsTime& finish);
inline operator int64_t() const;
};
@@ -167,9 +167,6 @@ QPID_COMMON_EXTERN void usleep(uint64_t usecs);
/** Output formatted date/time for now*/
void outputFormattedNow(std::ostream&);
-/** Output unformatted nanosecond-resolution time for now */
-void outputHiresNow(std::ostream&);
-
}}
#endif /*!_sys_Time_h*/
diff --git a/qpid/cpp/include/qpid/sys/windows/IntegerTypes.h b/qpid/cpp/include/qpid/sys/windows/IntegerTypes.h
index 28b82da1a0..ece1a618e9 100755
--- a/qpid/cpp/include/qpid/sys/windows/IntegerTypes.h
+++ b/qpid/cpp/include/qpid/sys/windows/IntegerTypes.h
@@ -22,17 +22,13 @@
*/
typedef unsigned char uint8_t;
+typedef char int8_t;
typedef unsigned short uint16_t;
typedef short int16_t;
typedef unsigned int uint32_t;
typedef int int32_t;
-#if defined(_MSC_VER)
-typedef signed char int8_t;
typedef unsigned __int64 uint64_t;
typedef __int64 int64_t;
-#else
-#include <stdint.h>
-#endif
// Visual Studio doesn't define other common types, so set them up here too.
typedef unsigned int uint;
diff --git a/qpid/cpp/include/qpid/types/Exception.h b/qpid/cpp/include/qpid/types/Exception.h
index 483d104cc8..d061a7df0e 100644
--- a/qpid/cpp/include/qpid/types/Exception.h
+++ b/qpid/cpp/include/qpid/types/Exception.h
@@ -28,7 +28,7 @@
namespace qpid {
namespace types {
-class QPID_TYPES_CLASS_EXTERN Exception : public std::exception
+class Exception : public std::exception
{
public:
QPID_TYPES_EXTERN explicit Exception(const std::string& message=std::string()) throw();
diff --git a/qpid/cpp/include/qpid/types/ImportExport.h b/qpid/cpp/include/qpid/types/ImportExport.h
index 8fa41884fb..bb10575fcd 100644
--- a/qpid/cpp/include/qpid/types/ImportExport.h
+++ b/qpid/cpp/include/qpid/types/ImportExport.h
@@ -20,16 +20,14 @@
* under the License.
*/
-#include "qpid/ImportExport.h"
-
+#if defined(WIN32) && !defined(QPID_DECLARE_STATIC)
#if defined(TYPES_EXPORT) || defined (qpidtypes_EXPORTS)
-# define QPID_TYPES_EXTERN QPID_EXPORT
-# define QPID_TYPES_CLASS_EXTERN QPID_CLASS_EXPORT
-# define QPID_TYPES_INLINE_EXTERN QPID_INLINE_EXPORT
+#define QPID_TYPES_EXTERN __declspec(dllexport)
+#else
+#define QPID_TYPES_EXTERN __declspec(dllimport)
+#endif
#else
-# define QPID_TYPES_EXTERN QPID_IMPORT
-# define QPID_TYPES_CLASS_EXTERN QPID_CLASS_IMPORT
-# define QPID_TYPES_INLINE_EXTERN QPID_INLINE_IMPORT
+#define QPID_TYPES_EXTERN
#endif
#endif /*!QPID_TYPES_IMPORTEXPORT_H*/
diff --git a/qpid/cpp/include/qpid/types/Uuid.h b/qpid/cpp/include/qpid/types/Uuid.h
index 02af4c7e7f..467a895184 100644
--- a/qpid/cpp/include/qpid/types/Uuid.h
+++ b/qpid/cpp/include/qpid/types/Uuid.h
@@ -29,7 +29,7 @@
namespace qpid {
namespace types {
-class QPID_TYPES_CLASS_EXTERN Uuid
+class Uuid
{
public:
static const size_t SIZE;
diff --git a/qpid/cpp/include/qpid/types/Variant.h b/qpid/cpp/include/qpid/types/Variant.h
index 4459fc4123..9ae672b7c2 100644
--- a/qpid/cpp/include/qpid/types/Variant.h
+++ b/qpid/cpp/include/qpid/types/Variant.h
@@ -36,7 +36,7 @@ namespace types {
/**
* Thrown when an illegal conversion of a variant is attempted.
*/
-struct QPID_TYPES_CLASS_EXTERN InvalidConversion : public Exception
+struct InvalidConversion : public Exception
{
InvalidConversion(const std::string& msg);
};
@@ -60,14 +60,12 @@ enum VariantType {
VAR_UUID
};
-std::string getTypeName(VariantType type);
-
class VariantImpl;
/**
* Represents a value of variable type.
*/
-class QPID_TYPES_CLASS_EXTERN Variant
+class Variant
{
public:
typedef std::map<std::string, Variant> Map;
diff --git a/qpid/cpp/managementgen/Makefile.am b/qpid/cpp/managementgen/Makefile.am
index 4fc5edcad4..6c2024ccaa 100644
--- a/qpid/cpp/managementgen/Makefile.am
+++ b/qpid/cpp/managementgen/Makefile.am
@@ -19,26 +19,20 @@
qmfpythondir = $(pythondir)
dist_bin_SCRIPTS = \
qmf-gen
-
-pkgpyexec_qmfgendir = $(pyexecdir)/qmfgen
-pkgpyexec_qmfgen_PYTHON = \
+nobase_qmfpython_DATA = \
qmfgen/__init__.py \
qmfgen/generate.py \
qmfgen/schema.py \
- qmfgen/management-types.xml
-
-pkgpyexec_qmfgentmpldir = $(pyexecdir)/qmfgen/templates
-pkgpyexec_qmfgentmpl_PYTHON = \
qmfgen/templates/Args.h \
qmfgen/templates/Class.cpp \
qmfgen/templates/Class.h \
- qmfgen/templates/CMakeLists.cmake \
qmfgen/templates/Event.cpp \
qmfgen/templates/Event.h \
qmfgen/templates/Makefile.mk \
qmfgen/templates/Package.cpp \
qmfgen/templates/Package.h \
qmfgen/templates/V2Package.cpp \
- qmfgen/templates/V2Package.h
+ qmfgen/templates/V2Package.h \
+ qmfgen/management-types.xml
EXTRA_DIST = $(nobase_qmfpython_DATA) CMakeLists.txt
diff --git a/qpid/cpp/managementgen/qmfgen/schema.py b/qpid/cpp/managementgen/qmfgen/schema.py
index 59e951fb6e..afdfe42639 100755
--- a/qpid/cpp/managementgen/qmfgen/schema.py
+++ b/qpid/cpp/managementgen/qmfgen/schema.py
@@ -1731,9 +1731,9 @@ class SchemaPackage:
stream.write(" qmf::SchemaProperty arg(\"%s\", %s);\n" % (arg.name, typeName))
if subType:
stream.write(" arg.setSubtype(\"%s\");\n" % subType)
- if arg.unit:
+ if stat.unit:
stream.write(" arg.setUnit(\"%s\");\n" % arg.unit)
- if arg.desc:
+ if stat.desc:
stream.write(" arg.setDesc(\"%s\");\n" % arg.desc)
stream.write(" arg.setDirection(%s);\n" % self.qmfv2Dir(arg.dir))
stream.write(" method.addArgument(arg);\n")
diff --git a/qpid/cpp/rubygen/0-10/specification.rb b/qpid/cpp/rubygen/0-10/specification.rb
index ef193f5fd0..7366599eba 100755
--- a/qpid/cpp/rubygen/0-10/specification.rb
+++ b/qpid/cpp/rubygen/0-10/specification.rb
@@ -252,7 +252,7 @@ class Specification < CppGen
include "#{@dir}/specification"
namespace(@ns) {
genl "template <class F, class R=typename F::result_type>"
- cpp_extern_class("QPID_COMMON_CLASS_EXTERN", "ProxyTemplate") {
+ cpp_class("ProxyTemplate") {
public
genl "ProxyTemplate(F f=F()) : functor(f) {}"
@amqp.classes.each { |c|
diff --git a/qpid/cpp/rubygen/MethodBodyDefaultVisitor.rb b/qpid/cpp/rubygen/MethodBodyDefaultVisitor.rb
index 11dbcb8f83..4f9b369117 100755
--- a/qpid/cpp/rubygen/MethodBodyDefaultVisitor.rb
+++ b/qpid/cpp/rubygen/MethodBodyDefaultVisitor.rb
@@ -33,7 +33,7 @@ class MethodBodyDefaultVisitorGen < CppGen
include "qpid/framing/MethodBodyConstVisitor"
namespace(@namespace) {
genl
- cpp_extern_class("QPID_COMMON_CLASS_EXTERN", @classname, "public MethodBodyConstVisitor") {
+ cpp_class(@classname, "public MethodBodyConstVisitor") {
genl "public:"
genl "virtual void defaultVisit() = 0;"
@amqp.methods_.each { |m|
diff --git a/qpid/cpp/rubygen/amqpgen.rb b/qpid/cpp/rubygen/amqpgen.rb
index 20aac35194..69e65a4056 100755
--- a/qpid/cpp/rubygen/amqpgen.rb
+++ b/qpid/cpp/rubygen/amqpgen.rb
@@ -61,8 +61,7 @@ end
class Module
# Add trailing _ to avoid conflict with Object methods.
def mangle(sym)
- sym = (sym.to_s+"_").to_sym if (Object.method_defined?(sym) or sym == :type)
- sym
+ (Object.method_defined? sym) ? (sym.to_s+"_").intern : sym
end
# Add attribute reader for XML attribute.
diff --git a/qpid/cpp/rubygen/cppgen.rb b/qpid/cpp/rubygen/cppgen.rb
index 7dc21fe1bc..f0995105f1 100755
--- a/qpid/cpp/rubygen/cppgen.rb
+++ b/qpid/cpp/rubygen/cppgen.rb
@@ -377,9 +377,6 @@ class CppGen < Generator
def cpp_class(name, *bases, &block)
struct_class("class", name, bases, &block);
end
- def cpp_extern_class(scope, name, *bases, &block)
- struct_class("class "+scope, name, bases, &block);
- end
def typedef(type, name) genl "typedef #{type} #{name};\n"; end
diff --git a/qpid/cpp/rubygen/framing.0-10/MethodBodyDefaultVisitor.rb b/qpid/cpp/rubygen/framing.0-10/MethodBodyDefaultVisitor.rb
index 4c58ff2bbb..00962de4f9 100755
--- a/qpid/cpp/rubygen/framing.0-10/MethodBodyDefaultVisitor.rb
+++ b/qpid/cpp/rubygen/framing.0-10/MethodBodyDefaultVisitor.rb
@@ -33,7 +33,7 @@ class MethodBodyDefaultVisitorGen < CppGen
include "qpid/CommonImportExport.h"
namespace(@namespace) {
genl "class AMQMethodBody;"
- cpp_extern_class("QPID_COMMON_CLASS_EXTERN", @classname, "public MethodBodyConstVisitor") {
+ cpp_class(@classname, "public MethodBodyConstVisitor") {
genl "public:"
genl "virtual void defaultVisit(const AMQMethodBody&) = 0;"
@amqp.methods_.each { |m|
diff --git a/qpid/cpp/rubygen/framing.0-10/OperationsInvoker.rb b/qpid/cpp/rubygen/framing.0-10/OperationsInvoker.rb
index f9b5ce58d8..f9b6cac76b 100755
--- a/qpid/cpp/rubygen/framing.0-10/OperationsInvoker.rb
+++ b/qpid/cpp/rubygen/framing.0-10/OperationsInvoker.rb
@@ -69,7 +69,7 @@ class OperationsInvokerGen < CppGen
def invoker_h(invoker, target, methods)
return if methods.empty?
genl
- cpp_extern_class("QPID_COMMON_CLASS_EXTERN", invoker, "public qpid::framing::Invoker") {
+ cpp_class(invoker, "public qpid::framing::Invoker") {
genl "#{target}& target;"
public
genl("Invoker(#{target}& target_) : target(target_) {}")
diff --git a/qpid/cpp/rubygen/framing.0-10/Proxy.rb b/qpid/cpp/rubygen/framing.0-10/Proxy.rb
index 3325616754..6e3cb4fd4d 100755
--- a/qpid/cpp/rubygen/framing.0-10/Proxy.rb
+++ b/qpid/cpp/rubygen/framing.0-10/Proxy.rb
@@ -37,7 +37,7 @@ class ProxyGen < CppGen
def inner_class_decl(c)
cname=c.name.caps
- cpp_extern_class("QPID_COMMON_CLASS_EXTERN", cname, "public Proxy") {
+ cpp_class(cname, "public Proxy") {
gen <<EOS
public:
#{cname}(FrameHandler& f) : Proxy(f) {}
@@ -69,7 +69,7 @@ EOS
include "qpid/CommonImportExport.h"
namespace("qpid::framing") {
- cpp_extern_class("QPID_COMMON_CLASS_EXTERN", @classname, "public Proxy") {
+ cpp_class(@classname, "public Proxy") {
public
genl "QPID_COMMON_EXTERN #{@classname}(FrameHandler& out);"
genl
diff --git a/qpid/cpp/rubygen/framing.0-10/Session.rb b/qpid/cpp/rubygen/framing.0-10/Session.rb
index e800df9b2e..61f0e03a8b 100755
--- a/qpid/cpp/rubygen/framing.0-10/Session.rb
+++ b/qpid/cpp/rubygen/framing.0-10/Session.rb
@@ -56,8 +56,8 @@ module SyncAsync
def decl_ctor_opeq()
genl
genl "QPID_CLIENT_EXTERN #{@classname}();"
- genl "QPID_CLIENT_INLINE_EXTERN #{@classname}(const #{@version_base}& other);"
- genl "QPID_CLIENT_INLINE_EXTERN #{@classname}& operator=(const #{@version_base}& other);"
+ 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="")
diff --git a/qpid/cpp/rubygen/framing.0-10/structs.rb b/qpid/cpp/rubygen/framing.0-10/structs.rb
index 62b33ce773..c3684aea66 100755
--- a/qpid/cpp/rubygen/framing.0-10/structs.rb
+++ b/qpid/cpp/rubygen/framing.0-10/structs.rb
@@ -406,7 +406,7 @@ EOS
namespace qpid {
namespace framing {
-class QPID_COMMON_CLASS_EXTERN #{classname} #{inheritance} {
+class #{classname} #{inheritance} {
EOS
if (is_packed(s))
indent { s.fields.each { |f| genl "#{f.cpptype.name} #{f.cppname};" unless f.type_ == "bit"} }
diff --git a/qpid/cpp/src/CMakeLists.txt b/qpid/cpp/src/CMakeLists.txt
index b0ea19709b..d0ca2d9c2b 100644
--- a/qpid/cpp/src/CMakeLists.txt
+++ b/qpid/cpp/src/CMakeLists.txt
@@ -96,7 +96,7 @@ MACRO (add_msvc_version_full verProject verProjectType verProjectFileExt verFN1
inherit_value ("winver_${verProject}_InternalName" "${verProject}")
inherit_value ("winver_${verProject}_OriginalFilename" "${verProject}.${verProjectFileExt}")
inherit_value ("winver_${verProject}_ProductName" "${winver_DESCRIPTION_SUMMARY}")
-
+
# Create strings to be substituted into the template file
set ("winverFileVersionBinary" "${winver_${verProject}_FileVersionBinary}")
set ("winverProductVersionBinary" "${winver_${verProject}_ProductVersionBinary}")
@@ -126,7 +126,7 @@ ENDMACRO (add_msvc_version_full)
#
MACRO (add_msvc_version verProject verProjectType verProjectFileExt)
if (MSVC)
- add_msvc_version_full (${verProject}
+ add_msvc_version_full (${verProject}
${verProjectType}
${verProjectFileExt}
${winver_FILE_VERSION_N1}
@@ -580,15 +580,6 @@ include (ssl.cmake)
check_symbol_exists (LOG_AUTHPRIV "sys/syslog.h" HAVE_LOG_AUTHPRIV)
check_symbol_exists (LOG_FTP "sys/syslog.h" HAVE_LOG_FTP)
-# Allow MSVC user to select 'WinXP-SP3/Windows Server 2003' as build target version
-set (win32_winnt_default OFF)
-if (CMAKE_SYSTEM_NAME STREQUAL Windows)
- if (MSVC)
- set (win32_winnt_default ON)
- endif (MSVC)
-endif (CMAKE_SYSTEM_NAME STREQUAL Windows)
-option(SET_WIN32_WINNT "In Windows-MSVC build: define _WIN32_WINNT=0x0502 to select target version: Windows XP with SP3" ${win32_winnt_default})
-
if (CMAKE_SYSTEM_NAME STREQUAL Windows)
if (MSVC)
add_definitions(
@@ -599,9 +590,9 @@ if (CMAKE_SYSTEM_NAME STREQUAL Windows)
/wd4800
/wd4355
)
- if (SET_WIN32_WINNT)
- add_definitions(/D "_WIN32_WINNT=0x0502")
- endif (SET_WIN32_WINNT)
+ if (MSVC80)
+ add_definitions(/D "_WIN32_WINNT=0x0501")
+ endif (MSVC80)
# set the RelWithDebInfo compile/link switches to equal Release
set (CMAKE_CXX_FLAGS_RELWITHDEBINFO "/MD /O2 /Ob2 /D NDEBUG")
@@ -645,7 +636,8 @@ if (CMAKE_SYSTEM_NAME STREQUAL Windows)
)
set (qpidcommon_platform_LIBS
- ${Boost_THREAD_LIBRARY} ${windows_ssl_libs} ${Boost_PROGRAM_OPTIONS_LIBRARY} ${Boost_DATE_TIME_LIBRARY} ${Boost_FILESYSTEM_LIBRARY} ${Boost_SYSTEM_LIBRARY} ws2_32 )
+ ${windows_ssl_libs} ws2_32
+ )
set (qpidbroker_platform_SOURCES
qpid/broker/windows/BrokerDefaults.cpp
qpid/broker/windows/SaslAuthenticator.cpp
@@ -665,7 +657,7 @@ if (CMAKE_SYSTEM_NAME STREQUAL Windows)
set (qpidd_platform_SOURCES
windows/QpiddBroker.cpp
)
-
+
set (qpidmessaging_platform_SOURCES
qpid/messaging/HandleInstantiator.cpp
)
@@ -946,7 +938,7 @@ if (NOT QPID_GENERATED_HEADERS_IN_SOURCE)
endif (NOT QPID_GENERATED_HEADERS_IN_SOURCE)
-if (MSVC)
+if (WIN32)
# Install the DtcPlugin project and call it qpidxarm.
set(AMQP_WCF_DIR ${qpid-cpp_SOURCE_DIR}/../wcf)
set(qpidxarm_SOURCES ${AMQP_WCF_DIR}/src/Apache/Qpid/DtcPlugin/DtcPlugin.cpp)
@@ -959,7 +951,7 @@ if (MSVC)
COMPONENT ${QPID_COMPONENT_CLIENT})
install_pdb (qpidxarm ${QPID_COMPONENT_CLIENT})
endif (EXISTS ${qpidxarm_SOURCES})
-endif (MSVC)
+endif (WIN32)
set (qpidbroker_SOURCES
${mgen_broker_cpp}
@@ -1006,6 +998,7 @@ set (qpidbroker_SOURCES
qpid/broker/QueuePolicy.cpp
qpid/broker/QueueRegistry.cpp
qpid/broker/QueueFlowLimit.cpp
+ qpid/broker/RateTracker.cpp
qpid/broker/RecoveryManagerImpl.cpp
qpid/broker/RecoveredEnqueue.cpp
qpid/broker/RecoveredDequeue.cpp
diff --git a/qpid/cpp/src/CMakeWinVersions.cmake b/qpid/cpp/src/CMakeWinVersions.cmake
index 0bac7cab47..9bffd2ba0e 100644
--- a/qpid/cpp/src/CMakeWinVersions.cmake
+++ b/qpid/cpp/src/CMakeWinVersions.cmake
@@ -34,11 +34,11 @@
# set ("winver_PACKAGE_NAME" "qpid-cpp")
# set ("winver_DESCRIPTION_SUMMARY" "Apache Qpid C++")
# set ("winver_FILE_VERSION_N1" "0")
-# set ("winver_FILE_VERSION_N2" "11")
+# set ("winver_FILE_VERSION_N2" "9")
# set ("winver_FILE_VERSION_N3" "0")
# set ("winver_FILE_VERSION_N4" "0")
# set ("winver_PRODUCT_VERSION_N1" "0")
-# set ("winver_PRODUCT_VERSION_N2" "11")
+# set ("winver_PRODUCT_VERSION_N2" "9")
# set ("winver_PRODUCT_VERSION_N3" "0")
# set ("winver_PRODUCT_VERSION_N4" "0")
# set ("winver_LEGAL_COPYRIGHT" "")
@@ -46,10 +46,10 @@
#
# Specification of per-project settings:
#
-# set ("winver_${projectName}_FileVersionBinary" "0,11,0,0")
-# set ("winver_${projectName}_ProductVersionBinary" "0,11,0,0")
-# set ("winver_${projectName}_FileVersionString" "0, 11, 0, 0")
-# set ("winver_${projectName}_ProductVersionString" "0, 11, 0, 0")
+# set ("winver_${projectName}_FileVersionBinary" "0,9,0,0")
+# set ("winver_${projectName}_ProductVersionBinary" "0,9,0,0")
+# set ("winver_${projectName}_FileVersionString" "0, 9, 0, 0")
+# set ("winver_${projectName}_ProductVersionString" "0, 9, 0, 0")
# set ("winver_${projectName}_FileDescription" "qpid-cpp-qpidcommon Library")
# set ("winver_${projectName}_LegalCopyright" "")
# set ("winver_${projectName}_InternalName" "qpidcommon")
diff --git a/qpid/cpp/src/Makefile.am b/qpid/cpp/src/Makefile.am
index 4e13e9ad9c..dfb2547613 100644
--- a/qpid/cpp/src/Makefile.am
+++ b/qpid/cpp/src/Makefile.am
@@ -37,7 +37,6 @@ windows_dist = \
qpid/sys/windows/IOHandle.cpp \
qpid/sys/windows/IoHandlePrivate.h \
qpid/sys/windows/LockFile.cpp \
- qpid/sys/windows/mingw32_compat.h \
qpid/sys/windows/PollableCondition.cpp \
qpid/sys/windows/PipeHandle.cpp \
../include/qpid/sys/windows/Mutex.h \
@@ -128,14 +127,14 @@ qpidexec_SCRIPTS =
qpidtestdir = $(qpidexecdir)/tests
qpidtest_PROGRAMS =
qpidtest_SCRIPTS =
-tmoduleexecdir = $(libdir)/qpid/tests
-tmoduleexec_LTLIBRARIES=
+tmoduledir = $(libdir)/qpid/tests
+tmodule_LTLIBRARIES=
AM_CXXFLAGS += -DBOOST_FILESYSTEM_VERSION=2
## Automake macros to build libraries and executables.
-qpidd_CXXFLAGS = $(AM_CXXFLAGS) -DQPIDD_MODULE_DIR=\"$(dmoduleexecdir)\" -DQPIDD_CONF_FILE=\"$(sysconfdir)/qpidd.conf\"
-libqpidclient_la_CXXFLAGS = $(AM_CXXFLAGS) -DQPIDC_MODULE_DIR=\"$(cmoduleexecdir)\" -DQPIDC_CONF_FILE=\"$(confdir)/qpidc.conf\"
+qpidd_CXXFLAGS = $(AM_CXXFLAGS) -DQPIDD_MODULE_DIR=\"$(dmoduledir)\" -DQPIDD_CONF_FILE=\"$(sysconfdir)/qpidd.conf\"
+libqpidclient_la_CXXFLAGS = $(AM_CXXFLAGS) -DQPIDC_MODULE_DIR=\"$(cmoduledir)\" -DQPIDC_CONF_FILE=\"$(confdir)/qpidc.conf\"
qpidd_LDADD = \
libqpidbroker.la \
@@ -177,7 +176,7 @@ nobase_include_HEADERS += \
../include/qpid/sys/posix/Time.h \
../include/qpid/sys/posix/check.h
-if HAVE_EPOLL
+if HAVE_EPOLL
poller = qpid/sys/epoll/EpollPoller.cpp
endif
@@ -196,15 +195,15 @@ libqpidcommon_la_SOURCES += $(poller) $(systeminfo)
posix_broker_src = \
qpid/broker/posix/BrokerDefaults.cpp
-lib_LTLIBRARIES = libqpidtypes.la libqpidcommon.la libqpidbroker.la libqpidclient.la libqpidmessaging.la
+lib_LTLIBRARIES = libqpidtypes.la libqpidcommon.la libqpidbroker.la libqpidclient.la libqpidmessaging.la
# Definitions for client and daemon plugins
PLUGINLDFLAGS=-no-undefined -module -avoid-version
confdir=$(sysconfdir)/qpid
-dmoduleexecdir=$(libdir)/qpid/daemon
-cmoduleexecdir=$(libdir)/qpid/client
-dmoduleexec_LTLIBRARIES =
-cmoduleexec_LTLIBRARIES =
+dmoduledir=$(libdir)/qpid/daemon
+cmoduledir=$(libdir)/qpid/client
+dmodule_LTLIBRARIES =
+cmodule_LTLIBRARIES =
include cluster.mk
include acl.mk
@@ -246,7 +245,7 @@ rdma_la_LIBADD = \
rdma_la_LDFLAGS = $(PLUGINLDFLAGS)
rdma_la_CXXFLAGS = \
$(AM_CXXFLAGS) -Wno-missing-field-initializers
-dmoduleexec_LTLIBRARIES += \
+dmodule_LTLIBRARIES += \
rdma.la
rdmaconnector_la_SOURCES = \
@@ -258,7 +257,7 @@ rdmaconnector_la_LIBADD = \
rdmaconnector_la_LDFLAGS = $(PLUGINLDFLAGS)
rdmaconnector_la_CXXFLAGS = \
$(AM_CXXFLAGS) -Wno-missing-field-initializers
-cmoduleexec_LTLIBRARIES += \
+cmodule_LTLIBRARIES += \
rdmaconnector.la
# RDMA test/sample programs
@@ -333,7 +332,6 @@ libqpidcommon_la_SOURCES += \
qpid/Address.cpp \
qpid/DataDir.cpp \
qpid/DataDir.h \
- qpid/DisableExceptionLogging.h \
qpid/Exception.cpp \
qpid/Modules.cpp \
qpid/Modules.h \
@@ -343,7 +341,6 @@ libqpidcommon_la_SOURCES += \
qpid/RefCounted.h \
qpid/RefCountedBuffer.cpp \
qpid/RefCountedBuffer.h \
- qpid/BufferRef.h \
qpid/Sasl.h \
qpid/SaslFactory.cpp \
qpid/SaslFactory.h \
@@ -617,6 +614,8 @@ libqpidbroker_la_SOURCES = \
qpid/broker/QueueFlowLimit.h \
qpid/broker/QueueFlowLimit.cpp \
qpid/broker/RateFlowcontrol.h \
+ qpid/broker/RateTracker.cpp \
+ qpid/broker/RateTracker.h \
qpid/broker/RecoverableConfig.h \
qpid/broker/RecoverableExchange.h \
qpid/broker/RecoverableMessage.h \
@@ -653,7 +652,6 @@ libqpidbroker_la_SOURCES = \
qpid/broker/SessionState.h \
qpid/broker/SignalHandler.cpp \
qpid/broker/SignalHandler.h \
- qpid/broker/StatefulQueueObserver.h \
qpid/broker/System.cpp \
qpid/broker/System.h \
qpid/broker/ThresholdAlerts.cpp \
@@ -742,7 +740,7 @@ libqpidclient_la_SOURCES = \
QPIDCLIENT_VERSION_INFO = 2:0:0
libqpidclient_la_LDFLAGS = -version-info $(QPIDCLIENT_VERSION_INFO)
-libqpidtypes_la_LIBADD= -luuid
+libqpidtypes_la_libadd=-luuid
libqpidtypes_la_SOURCES= \
qpid/types/Exception.cpp \
qpid/types/Uuid.cpp \
@@ -804,7 +802,6 @@ nobase_include_HEADERS += \
../include/qpid/Address.h \
../include/qpid/CommonImportExport.h \
../include/qpid/Exception.h \
- ../include/qpid/ImportExport.h \
../include/qpid/InlineAllocator.h \
../include/qpid/InlineVector.h \
../include/qpid/Msg.h \
@@ -887,10 +884,14 @@ nobase_include_HEADERS += \
../include/qpid/types/Variant.h \
../include/qpid/types/ImportExport.h
+# Force build of qpidd during dist phase so help2man will work.
+dist-hook: $(BUILT_SOURCES)
+ $(MAKE) qpidd
+
# Create the default data directory
install-data-local:
$(mkinstalldirs) $(DESTDIR)/$(localstatedir)/lib/qpidd
-# Support for pkg-config
+# Support for pkg-config
pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = qpid.pc
diff --git a/qpid/cpp/src/acl.mk b/qpid/cpp/src/acl.mk
index b8e2ff0e13..bcd1d88335 100644
--- a/qpid/cpp/src/acl.mk
+++ b/qpid/cpp/src/acl.mk
@@ -18,8 +18,8 @@
#
#
# acl library makefile fragment, to be included in Makefile.am
-#
-dmoduleexec_LTLIBRARIES += acl.la
+#
+dmodule_LTLIBRARIES += acl.la
acl_la_SOURCES = \
qpid/acl/Acl.cpp \
diff --git a/qpid/cpp/src/cluster.mk b/qpid/cpp/src/cluster.mk
index 3ce4ce25b3..a791b2d41a 100644
--- a/qpid/cpp/src/cluster.mk
+++ b/qpid/cpp/src/cluster.mk
@@ -18,7 +18,7 @@
#
#
# Cluster library makefile fragment, to be included in Makefile.am
-#
+#
# Optional CMAN support
@@ -34,7 +34,7 @@ endif
if HAVE_LIBCPG
-dmoduleexec_LTLIBRARIES += cluster.la
+dmodule_LTLIBRARIES += cluster.la
cluster_la_SOURCES = \
$(CMAN_SOURCES) \
@@ -102,7 +102,7 @@ cluster_la_CXXFLAGS = $(AM_CXXFLAGS) -fno-strict-aliasing
cluster_la_LDFLAGS = $(PLUGINLDFLAGS)
# The watchdog plugin and helper executable
-dmoduleexec_LTLIBRARIES += watchdog.la
+dmodule_LTLIBRARIES += watchdog.la
watchdog_la_SOURCES = qpid/cluster/WatchDogPlugin.cpp
watchdog_la_LIBADD = libqpidbroker.la
watchdog_la_LDFLAGS = $(PLUGINLDFLAGS)
diff --git a/qpid/cpp/src/posix/QpiddBroker.cpp b/qpid/cpp/src/posix/QpiddBroker.cpp
index 1270b57252..879935462e 100644
--- a/qpid/cpp/src/posix/QpiddBroker.cpp
+++ b/qpid/cpp/src/posix/QpiddBroker.cpp
@@ -138,9 +138,6 @@ struct QpiddDaemon : public Daemon {
brokerPtr->accept();
uint16_t port=brokerPtr->getPort(options->daemon.transport);
ready(port); // Notify parent.
- if (options->parent->broker.enableMgmt && (options->parent->broker.port == 0 || options->daemon.transport != TCP)) {
- dynamic_cast<qmf::org::apache::qpid::broker::Broker*>(brokerPtr->GetManagementObject())->set_port(port);
- }
brokerPtr->run();
}
};
@@ -185,13 +182,8 @@ int QpiddBroker::execute (QpiddOptions *options) {
boost::intrusive_ptr<Broker> brokerPtr(new Broker(options->broker));
ScopedSetBroker ssb(brokerPtr);
brokerPtr->accept();
- if (options->broker.port == 0 || myOptions->daemon.transport != TCP) {
- uint16_t port = brokerPtr->getPort(myOptions->daemon.transport);
- cout << port << endl;
- if (options->broker.enableMgmt) {
- dynamic_cast<qmf::org::apache::qpid::broker::Broker*>(brokerPtr->GetManagementObject())->set_port(port);
- }
- }
+ if (options->broker.port == 0 || myOptions->daemon.transport != TCP)
+ cout << uint16_t(brokerPtr->getPort(myOptions->daemon.transport)) << endl;
brokerPtr->run();
}
return 0;
diff --git a/qpid/cpp/src/qmf/Agent.cpp b/qpid/cpp/src/qmf/Agent.cpp
index 684f8e4fba..915f2a1c88 100644
--- a/qpid/cpp/src/qmf/Agent.cpp
+++ b/qpid/cpp/src/qmf/Agent.cpp
@@ -72,7 +72,7 @@ Schema Agent::getSchema(const SchemaId& s, Duration t) { return impl->getSchema(
AgentImpl::AgentImpl(const std::string& n, uint32_t e, ConsoleSessionImpl& s) :
name(n), directSubject(n), epoch(e), session(s), touched(true), untouchedCount(0), capability(0),
- sender(session.directSender), schemaCache(s.schemaCache)
+ sender(session.directSender), nextCorrelator(1), schemaCache(s.schemaCache)
{
}
@@ -102,11 +102,12 @@ const Variant& AgentImpl::getAttribute(const string& k) const
ConsoleEvent AgentImpl::query(const Query& query, Duration timeout)
{
boost::shared_ptr<SyncContext> context(new SyncContext());
- uint32_t correlator(session.correlator());
+ uint32_t correlator;
ConsoleEvent result;
{
qpid::sys::Mutex::ScopedLock l(lock);
+ correlator = nextCorrelator++;
contextMap[correlator] = context;
}
try {
@@ -150,7 +151,12 @@ ConsoleEvent AgentImpl::query(const string& text, Duration timeout)
uint32_t AgentImpl::queryAsync(const Query& query)
{
- uint32_t correlator(session.correlator());
+ uint32_t correlator;
+
+ {
+ qpid::sys::Mutex::ScopedLock l(lock);
+ correlator = nextCorrelator++;
+ }
sendQuery(query, correlator);
return correlator;
@@ -166,11 +172,12 @@ uint32_t AgentImpl::queryAsync(const string& text)
ConsoleEvent AgentImpl::callMethod(const string& method, const Variant::Map& args, const DataAddr& addr, Duration timeout)
{
boost::shared_ptr<SyncContext> context(new SyncContext());
- uint32_t correlator(session.correlator());
+ uint32_t correlator;
ConsoleEvent result;
{
qpid::sys::Mutex::ScopedLock l(lock);
+ correlator = nextCorrelator++;
contextMap[correlator] = context;
}
try {
@@ -206,7 +213,12 @@ ConsoleEvent AgentImpl::callMethod(const string& method, const Variant::Map& arg
uint32_t AgentImpl::callMethodAsync(const string& method, const Variant::Map& args, const DataAddr& addr)
{
- uint32_t correlator(session.correlator());
+ uint32_t correlator;
+
+ {
+ qpid::sys::Mutex::ScopedLock l(lock);
+ correlator = nextCorrelator++;
+ }
sendMethod(method, args, addr, correlator);
return correlator;
@@ -584,7 +596,12 @@ void AgentImpl::sendMethod(const string& method, const Variant::Map& args, const
void AgentImpl::sendSchemaRequest(const SchemaId& id)
{
- uint32_t correlator(session.correlator());
+ uint32_t correlator;
+
+ {
+ qpid::sys::Mutex::ScopedLock l(lock);
+ correlator = nextCorrelator++;
+ }
if (capability >= AGENT_CAPABILITY_V2_SCHEMA) {
Query query(QUERY_SCHEMA, id);
diff --git a/qpid/cpp/src/qmf/AgentImpl.h b/qpid/cpp/src/qmf/AgentImpl.h
index 09754a3a7e..7fa4f4373a 100644
--- a/qpid/cpp/src/qmf/AgentImpl.h
+++ b/qpid/cpp/src/qmf/AgentImpl.h
@@ -99,6 +99,7 @@ namespace qmf {
uint32_t capability;
qpid::messaging::Sender sender;
qpid::types::Variant::Map attributes;
+ uint32_t nextCorrelator;
std::map<uint32_t, boost::shared_ptr<SyncContext> > contextMap;
boost::shared_ptr<SchemaCache> schemaCache;
mutable std::set<std::string> packageSet;
diff --git a/qpid/cpp/src/qmf/AgentSession.cpp b/qpid/cpp/src/qmf/AgentSession.cpp
index 71d369325f..4c5a72a467 100644
--- a/qpid/cpp/src/qmf/AgentSession.cpp
+++ b/qpid/cpp/src/qmf/AgentSession.cpp
@@ -72,7 +72,6 @@ namespace qmf {
void open();
void close();
bool nextEvent(AgentEvent& e, Duration t);
- int pendingEvents() const;
void registerSchema(Schema& s);
DataAddr addData(Data& d, const string& n, bool persist);
@@ -162,7 +161,6 @@ const string& AgentSession::getName() const { return impl->getName(); }
void AgentSession::open() { impl->open(); }
void AgentSession::close() { impl->close(); }
bool AgentSession::nextEvent(AgentEvent& e, Duration t) { return impl->nextEvent(e, t); }
-int AgentSession::pendingEvents() const { return impl->pendingEvents(); }
void AgentSession::registerSchema(Schema& s) { impl->registerSchema(s); }
DataAddr AgentSession::addData(Data& d, const string& n, bool p) { return impl->addData(d, n, p); }
void AgentSession::delData(const DataAddr& a) { impl->delData(a); }
@@ -320,7 +318,7 @@ bool AgentSessionImpl::nextEvent(AgentEvent& event, Duration timeout)
uint64_t milliseconds = timeout.getMilliseconds();
qpid::sys::Mutex::ScopedLock l(lock);
- if (eventQueue.empty() && milliseconds > 0)
+ if (eventQueue.empty())
cond.wait(lock, qpid::sys::AbsTime(qpid::sys::now(),
qpid::sys::Duration(milliseconds * qpid::sys::TIME_MSEC)));
@@ -334,13 +332,6 @@ bool AgentSessionImpl::nextEvent(AgentEvent& event, Duration timeout)
}
-int AgentSessionImpl::pendingEvents() const
-{
- qpid::sys::Mutex::ScopedLock l(lock);
- return eventQueue.size();
-}
-
-
void AgentSessionImpl::registerSchema(Schema& schema)
{
if (!schema.isFinalized())
diff --git a/qpid/cpp/src/qmf/ConsoleSession.cpp b/qpid/cpp/src/qmf/ConsoleSession.cpp
index 7b51d80032..e12c1152f6 100644
--- a/qpid/cpp/src/qmf/ConsoleSession.cpp
+++ b/qpid/cpp/src/qmf/ConsoleSession.cpp
@@ -54,7 +54,6 @@ void ConsoleSession::setAgentFilter(const string& f) { impl->setAgentFilter(f);
void ConsoleSession::open() { impl->open(); }
void ConsoleSession::close() { impl->close(); }
bool ConsoleSession::nextEvent(ConsoleEvent& e, Duration t) { return impl->nextEvent(e, t); }
-int ConsoleSession::pendingEvents() const { return impl->pendingEvents(); }
uint32_t ConsoleSession::getAgentCount() const { return impl->getAgentCount(); }
Agent ConsoleSession::getAgent(uint32_t i) const { return impl->getAgent(i); }
Agent ConsoleSession::getConnectedBrokerAgent() const { return impl->getConnectedBrokerAgent(); }
@@ -66,9 +65,9 @@ Subscription ConsoleSession::subscribe(const string& q, const string& f, const s
//========================================================================================
ConsoleSessionImpl::ConsoleSessionImpl(Connection& c, const string& options) :
- connection(c), domain("default"), maxAgentAgeMinutes(5), listenOnDirect(true), strictSecurity(false),
+ connection(c), domain("default"), maxAgentAgeMinutes(5),
opened(false), thread(0), threadCanceled(false), lastVisit(0), lastAgePass(0),
- connectedBrokerInAgentList(false), schemaCache(new SchemaCache()), nextCorrelator(1)
+ connectedBrokerInAgentList(false), schemaCache(new SchemaCache())
{
if (!options.empty()) {
qpid::messaging::AddressParser parser(options);
@@ -214,7 +213,7 @@ bool ConsoleSessionImpl::nextEvent(ConsoleEvent& event, Duration timeout)
uint64_t milliseconds = timeout.getMilliseconds();
qpid::sys::Mutex::ScopedLock l(lock);
- if (eventQueue.empty() && milliseconds > 0)
+ if (eventQueue.empty())
cond.wait(lock, qpid::sys::AbsTime(qpid::sys::now(),
qpid::sys::Duration(milliseconds * qpid::sys::TIME_MSEC)));
@@ -228,13 +227,6 @@ bool ConsoleSessionImpl::nextEvent(ConsoleEvent& event, Duration timeout)
}
-int ConsoleSessionImpl::pendingEvents() const
-{
- qpid::sys::Mutex::ScopedLock l(lock);
- return eventQueue.size();
-}
-
-
uint32_t ConsoleSessionImpl::getAgentCount() const
{
qpid::sys::Mutex::ScopedLock l(lock);
@@ -429,23 +421,7 @@ void ConsoleSessionImpl::handleAgentUpdate(const string& agentName, const Varian
iter = content.find("_values");
if (iter == content.end())
return;
- const Variant::Map& in_attrs(iter->second.asMap());
- Variant::Map attrs;
-
- //
- // Copy the map from the message to "attrs". Translate any old-style
- // keys to their new key values in the process.
- //
- for (iter = in_attrs.begin(); iter != in_attrs.end(); iter++) {
- if (iter->first == "epoch")
- attrs[protocol::AGENT_ATTR_EPOCH] = iter->second;
- else if (iter->first == "timestamp")
- attrs[protocol::AGENT_ATTR_TIMESTAMP] = iter->second;
- else if (iter->first == "heartbeat_interval")
- attrs[protocol::AGENT_ATTR_HEARTBEAT_INTERVAL] = iter->second;
- else
- attrs[iter->first] = iter->second;
- }
+ Variant::Map attrs(iter->second.asMap());
iter = attrs.find(protocol::AGENT_ATTR_EPOCH);
if (iter != attrs.end())
diff --git a/qpid/cpp/src/qmf/ConsoleSessionImpl.h b/qpid/cpp/src/qmf/ConsoleSessionImpl.h
index 429dfc4881..675c8bcfb5 100644
--- a/qpid/cpp/src/qmf/ConsoleSessionImpl.h
+++ b/qpid/cpp/src/qmf/ConsoleSessionImpl.h
@@ -58,7 +58,6 @@ namespace qmf {
void open();
void close();
bool nextEvent(ConsoleEvent& e, qpid::messaging::Duration t);
- int pendingEvents() const;
uint32_t getAgentCount() const;
Agent getAgent(uint32_t i) const;
Agent getConnectedBrokerAgent() const { return connectedBrokerAgent; }
@@ -90,8 +89,6 @@ namespace qmf {
std::string directBase;
std::string topicBase;
boost::shared_ptr<SchemaCache> schemaCache;
- qpid::sys::Mutex corrlock;
- uint32_t nextCorrelator;
void enqueueEvent(const ConsoleEvent&);
void enqueueEventLH(const ConsoleEvent&);
@@ -102,7 +99,6 @@ namespace qmf {
void handleV1SchemaResponse(qpid::management::Buffer&, uint32_t, const qpid::messaging::Message&);
void periodicProcessing(uint64_t);
void run();
- uint32_t correlator() { qpid::sys::Mutex::ScopedLock l(corrlock); return nextCorrelator++; }
friend class AgentImpl;
};
diff --git a/qpid/cpp/src/qmf/DataAddr.cpp b/qpid/cpp/src/qmf/DataAddr.cpp
index d16e12062e..fb51d5787f 100644
--- a/qpid/cpp/src/qmf/DataAddr.cpp
+++ b/qpid/cpp/src/qmf/DataAddr.cpp
@@ -36,9 +36,7 @@ DataAddr::~DataAddr() { PI::dtor(*this); }
DataAddr& DataAddr::operator=(const DataAddr& s) { return PI::assign(*this, s); }
bool DataAddr::operator==(const DataAddr& o) { return *impl == *o.impl; }
-bool DataAddr::operator==(const DataAddr& o) const { return *impl == *o.impl; }
bool DataAddr::operator<(const DataAddr& o) { return *impl < *o.impl; }
-bool DataAddr::operator<(const DataAddr& o) const { return *impl < *o.impl; }
DataAddr::DataAddr(const qpid::types::Variant::Map& m) { PI::ctor(*this, new DataAddrImpl(m)); }
DataAddr::DataAddr(const string& n, const string& a, uint32_t e) { PI::ctor(*this, new DataAddrImpl(n, a, e)); }
@@ -47,7 +45,7 @@ const string& DataAddr::getAgentName() const { return impl->getAgentName(); }
uint32_t DataAddr::getAgentEpoch() const { return impl->getAgentEpoch(); }
Variant::Map DataAddr::asMap() const { return impl->asMap(); }
-bool DataAddrImpl::operator==(const DataAddrImpl& other) const
+bool DataAddrImpl::operator==(const DataAddrImpl& other)
{
return
agentName == other.agentName &&
@@ -56,7 +54,7 @@ bool DataAddrImpl::operator==(const DataAddrImpl& other) const
}
-bool DataAddrImpl::operator<(const DataAddrImpl& other) const
+bool DataAddrImpl::operator<(const DataAddrImpl& other)
{
if (agentName < other.agentName) return true;
if (agentName > other.agentName) return false;
diff --git a/qpid/cpp/src/qmf/DataAddrImpl.h b/qpid/cpp/src/qmf/DataAddrImpl.h
index 11d512f0c4..3f9cae9453 100644
--- a/qpid/cpp/src/qmf/DataAddrImpl.h
+++ b/qpid/cpp/src/qmf/DataAddrImpl.h
@@ -38,8 +38,8 @@ namespace qmf {
//
// Methods from API handle
//
- bool operator==(const DataAddrImpl&) const;
- bool operator<(const DataAddrImpl&) const;
+ bool operator==(const DataAddrImpl&);
+ bool operator<(const DataAddrImpl&);
DataAddrImpl(const qpid::types::Variant::Map&);
DataAddrImpl(const std::string& _name, const std::string& _agentName, uint32_t _agentEpoch=0) :
agentName(_agentName), name(_name), agentEpoch(_agentEpoch) {}
diff --git a/qpid/cpp/src/qmf/PrivateImplRef.h b/qpid/cpp/src/qmf/PrivateImplRef.h
index 960cbb2e09..8b698c4199 100644
--- a/qpid/cpp/src/qmf/PrivateImplRef.h
+++ b/qpid/cpp/src/qmf/PrivateImplRef.h
@@ -23,8 +23,8 @@
*/
#include "qmf/ImportExport.h"
-#include "qpid/RefCounted.h"
#include <boost/intrusive_ptr.hpp>
+#include "qpid/RefCounted.h"
namespace qmf {
diff --git a/qpid/cpp/src/qmf/engine/ResilientConnection.cpp b/qpid/cpp/src/qmf/engine/ResilientConnection.cpp
index 41dd9ff00c..ab65b8d768 100644
--- a/qpid/cpp/src/qmf/engine/ResilientConnection.cpp
+++ b/qpid/cpp/src/qmf/engine/ResilientConnection.cpp
@@ -334,7 +334,8 @@ void ResilientConnectionImpl::notify()
{
if (notifyFd != -1)
{
- (void) ::write(notifyFd, ".", 1);
+ int unused_ret; //Suppress warnings about ignoring return value.
+ unused_ret = ::write(notifyFd, ".", 1);
}
}
@@ -431,7 +432,8 @@ void ResilientConnectionImpl::EnqueueEvent(ResilientConnectionEvent::EventKind k
if (notifyFd != -1)
{
- (void) ::write(notifyFd, ".", 1);
+ int unused_ret; //Suppress warnings about ignoring return value.
+ unused_ret = ::write(notifyFd, ".", 1);
}
}
diff --git a/qpid/cpp/src/qmf/engine/SchemaImpl.cpp b/qpid/cpp/src/qmf/engine/SchemaImpl.cpp
index f75663e131..e0948a9911 100644
--- a/qpid/cpp/src/qmf/engine/SchemaImpl.cpp
+++ b/qpid/cpp/src/qmf/engine/SchemaImpl.cpp
@@ -55,12 +55,9 @@ void SchemaHash::update(uint8_t data)
void SchemaHash::update(const char* data, uint32_t len)
{
- union h {
- uint8_t b[16];
- uint64_t q[2];
- }* h = reinterpret_cast<union h*>(&hash[0]);
- uint64_t* first = &h->q[0];
- uint64_t* second = &h->q[1];
+ uint64_t* first = (uint64_t*) hash;
+ uint64_t* second = (uint64_t*) hash + 1;
+
for (uint32_t idx = 0; idx < len; idx++) {
*first = *first ^ (uint64_t) data[idx];
*second = *second << 1;
diff --git a/qpid/cpp/src/qpid/BufferRef.h b/qpid/cpp/src/qpid/BufferRef.h
deleted file mode 100644
index bfe1f9ebaa..0000000000
--- a/qpid/cpp/src/qpid/BufferRef.h
+++ /dev/null
@@ -1,70 +0,0 @@
-#ifndef QPID_BUFFERREF_H
-#define QPID_BUFFERREF_H
-
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
- */
-
-#include "qpid/RefCounted.h"
-#include <boost/intrusive_ptr.hpp>
-
-namespace qpid {
-
-/** Template for mutable or const buffer references */
-template <class T> class BufferRefT {
- public:
- BufferRefT() : begin_(0), end_(0) {}
-
- BufferRefT(boost::intrusive_ptr<RefCounted> c, T* begin, T* end) :
- counter(c), begin_(begin), end_(end) {}
-
- template <class U> BufferRefT(const BufferRefT<U>& other) :
- counter(other.counter), begin_(other.begin_), end_(other.end_) {}
-
- T* begin() const { return begin_; }
- T* end() const { return end_; }
-
- /** Return a sub-buffer of the current buffer */
- BufferRefT sub_buffer(T* begin, T* end) {
- assert(begin_ <= begin && begin <= end_);
- assert(begin_ <= end && end <= end_);
- assert(begin <= end);
- return BufferRefT(counter, begin, end);
- }
-
- private:
- boost::intrusive_ptr<RefCounted> counter;
- T* begin_;
- T* end_;
-};
-
-/**
- * Reference to a mutable ref-counted buffer.
- */
-typedef BufferRefT<char> BufferRef;
-
-/**
- * Reference to a const ref-counted buffer.
- */
-typedef BufferRefT<const char> ConstBufferRef;
-
-} // namespace qpid
-
-#endif /*!QPID_BUFFERREF_H*/
diff --git a/qpid/cpp/src/qpid/DisableExceptionLogging.h b/qpid/cpp/src/qpid/DisableExceptionLogging.h
deleted file mode 100644
index 04a9240513..0000000000
--- a/qpid/cpp/src/qpid/DisableExceptionLogging.h
+++ /dev/null
@@ -1,39 +0,0 @@
-#ifndef QPID_DISABLEEXCEPTIONLOGGING_H
-#define QPID_DISABLEEXCEPTIONLOGGING_H
-
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
- */
-#include "qpid/CommonImportExport.h"
-
-namespace qpid {
-
-/**
- * Temporarily disable logging in qpid::Exception constructor.
- * Used by log::Logger to avoid logging exceptions during Logger construction.
- */
-struct DisableExceptionLogging
-{
- QPID_COMMON_EXTERN DisableExceptionLogging();
- QPID_COMMON_EXTERN ~DisableExceptionLogging();
-};
-} // namespace qpid
-
-#endif /*!QPID_DISABLEEXCEPTIONLOGGING_H*/
diff --git a/qpid/cpp/src/qpid/Exception.cpp b/qpid/cpp/src/qpid/Exception.cpp
index a6696f06e1..16a3a13d17 100644
--- a/qpid/cpp/src/qpid/Exception.cpp
+++ b/qpid/cpp/src/qpid/Exception.cpp
@@ -7,9 +7,9 @@
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
@@ -21,25 +21,13 @@
#include "qpid/log/Statement.h"
#include "qpid/Exception.h"
-#include "qpid/DisableExceptionLogging.h"
#include <typeinfo>
#include <assert.h>
#include <string.h>
namespace qpid {
-// Note on static initialization order: if an exception is constructed
-// in a static constructor before disableExceptionLogging has been
-// initialized, the worst that can happen is we lose an exception log
-// message. Since we shouldn't be throwing a lot of exceptions during
-// static construction this seems safe.
-static bool disableExceptionLogging = false;
-
-DisableExceptionLogging::DisableExceptionLogging() { disableExceptionLogging = true; }
-DisableExceptionLogging::~DisableExceptionLogging() { disableExceptionLogging = false; }
-
Exception::Exception(const std::string& msg) throw() : message(msg) {
- if (disableExceptionLogging) return;
QPID_LOG_IF(debug, !msg.empty(), "Exception constructed: " << message);
}
diff --git a/qpid/cpp/src/qpid/Modules.cpp b/qpid/cpp/src/qpid/Modules.cpp
index 727e05d212..8f58df6ed1 100644
--- a/qpid/cpp/src/qpid/Modules.cpp
+++ b/qpid/cpp/src/qpid/Modules.cpp
@@ -64,6 +64,7 @@ void tryShlib(const char* libname_, bool noThrow) {
if (!isShlibName(libname)) libname += suffix();
try {
sys::Shlib shlib(libname);
+ QPID_LOG (info, "Loaded Module: " << libname);
}
catch (const std::exception& /*e*/) {
if (!noThrow)
@@ -81,7 +82,7 @@ void loadModuleDir (std::string dirname, bool isDefault)
return;
throw Exception ("Directory not found: " + dirname);
}
- if (!fs::is_directory(dirPath))
+ if (!fs::is_directory(dirPath))
{
throw Exception ("Invalid value for module-dir: " + dirname + " is not a directory");
}
diff --git a/qpid/cpp/src/qpid/Options.cpp b/qpid/cpp/src/qpid/Options.cpp
index 4b13e349f5..499fb71bc3 100644
--- a/qpid/cpp/src/qpid/Options.cpp
+++ b/qpid/cpp/src/qpid/Options.cpp
@@ -30,6 +30,23 @@ namespace qpid {
using namespace std;
+/*
+ * ---------------------------------------------
+ * Explanation for Boost 103200 conditional code
+ * ---------------------------------------------
+ *
+ * Please see large comment in Options.h .
+ *
+ */
+
+#if ( BOOST_VERSION == 103200 )
+std::vector<std::string> Options::long_names;
+std::vector<std::string> Options::short_names;
+#endif
+
+
+
+
namespace {
struct EnvOptMapper {
@@ -52,11 +69,49 @@ struct EnvOptMapper {
static const std::string prefix("QPID_");
if (envVar.substr(0, prefix.size()) == prefix) {
string env = envVar.substr(prefix.size());
+#if (BOOST_VERSION >= 103300)
typedef const std::vector< boost::shared_ptr<po::option_description> > OptDescs;
OptDescs::const_iterator i =
find_if(opts.options().begin(), opts.options().end(), boost::bind(matchStr, env, _1));
if (i != opts.options().end())
return (*i)->long_name();
+#else
+ /*
+ * For Boost version 103200 and below.
+ *
+ * In Boost version 103200, the options_description::options member,
+ * used above, is private. So what I will do here is use the
+ * count() funtion, which returns a 1 or 0 indicating presence or
+ * absence of the environment variable.
+ *
+ * If it is present, I will return its name. Env vars do not have
+ * short and long forms, so the name is synonymous with the long
+ * name. (This would not work for command line args.)
+ * And if it's absent -- an empty string.
+ */
+
+
+ /*
+ * The env vars come in unaltered, i.e. QPID_FOO, but the
+ * options are stored normalized as "qpid-foo". Change the
+ * local variable "env" so it can be found by "opts".
+ */
+ for (std::string::iterator i = env.begin(); i != env.end(); ++i)
+ {
+ *i = (*i == '_')
+ ? '-'
+ : ::tolower(*i);
+ }
+
+ if ( opts.count(env.c_str()) > 0 )
+ {
+ return env.c_str();
+ }
+ else
+ {
+ return string();
+ }
+#endif
}
return string();
}
@@ -111,6 +166,10 @@ std::string prettyArg(const std::string& name, const std::string& value) {
Options::Options(const string& name) :
po::options_description(name)
+
+#if ( BOOST_VERSION == 103200 )
+ , m_less_easy(this, this)
+#endif
{
}
@@ -127,6 +186,7 @@ void Options::parse(int argc, char const* const* argv, const std::string& config
parsing="command line options";
if (argc > 0 && argv != 0) {
if (allowUnknown) {
+#if (BOOST_VERSION >= 103300)
// This hideous workaround is required because boost 1.33 has a bug
// that causes 'allow_unregistered' to not work.
po::command_line_parser clp = po::command_line_parser(argc, const_cast<char**>(argv)).
@@ -140,6 +200,113 @@ void Options::parse(int argc, char const* const* argv, const std::string& config
filtopts.options.push_back (*i);
po::store(filtopts, vm);
+#elif ( BOOST_VERSION == 103200 )
+
+ /*
+ * "Tokenize" the argv to get rid of equals signs.
+ */
+ vector<string> tokenized_argv;
+ vector<string>::iterator iter;
+
+ for ( int i = 0; i < argc; ++ i )
+ {
+ string s = argv[i];
+ size_t equals_pos = s.find_first_of ( '=' );
+
+ if ( string::npos == equals_pos ) // There's no equals sign. This is a token.
+ {
+ tokenized_argv.push_back(s);
+ }
+ else
+ {
+ // Two tokens -- before and after the equals position.
+ tokenized_argv.push_back ( s.substr(0, equals_pos) );
+ tokenized_argv.push_back ( s.substr(equals_pos+1) );
+ }
+ }
+
+
+ /*
+ * Now "filter" the tokenized argv, to get rid of all
+ * unrecognized options. Because Boost 103200 has no
+ * facility for dealing gracefully with "unregistered"
+ * options.
+ */
+ vector<string> filtered_argv;
+ vector<string>::iterator the_end = tokenized_argv.end();
+
+ // The program-name gets in for free...
+ iter = tokenized_argv.begin();
+ filtered_argv.push_back ( * iter );
+ ++ iter;
+
+ // ...but all other args get checked.
+ while ( iter < the_end )
+ {
+ /*
+ * If this is an argument that is registered,
+ * copy it to filtered_argv and also copy all
+ * of its arguments.
+ */
+ if ( is_registered_option ( * iter ) )
+ {
+ // Store this recognized arg.
+ filtered_argv.push_back ( * iter );
+ ++ iter;
+
+ // Copy all values for the above arg.
+ // Args are tokens that do not start with a minus.
+ while ( (iter < the_end) && ((* iter)[0] != '-') )
+ {
+ filtered_argv.push_back ( * iter );
+ ++ iter;
+ }
+ }
+ else
+ {
+ // Skip this unrecognized arg.
+ ++ iter;
+
+ // Copy all values for the above arg.
+ // Values are tokens that do not start with a minus.
+ while ( (iter < the_end) && ( '-' != (*iter)[0] ) )
+ {
+ ++ iter;
+ }
+ }
+ }
+
+ // Make an array of temporary C strings, because
+ // the interface I can use wants it that way.
+ int new_argc = filtered_argv.size();
+ char ** new_argv = new char * [ new_argc ];
+ int i = 0;
+
+ // cout << "NEW ARGV: |";
+ for ( iter = filtered_argv.begin();
+ iter < filtered_argv.end();
+ ++ iter, ++ i
+ )
+ {
+ new_argv[i] = strdup( (* iter).c_str() );
+ // cout << " " << new_argv[i] ;
+ }
+ // cout << "|\n";
+
+
+ // Use the array of C strings.
+ po::basic_parsed_options<char> bpo = po::parse_command_line(new_argc, const_cast<char**>(new_argv), *this);
+ po::store(bpo, vm);
+
+
+ // Now free the temporary C strings.
+ for ( i = 0; i < new_argc; ++ i )
+ {
+ free ( new_argv[i] );
+ }
+ delete[] new_argv;
+
+#endif
}
else
po::store(po::parse_command_line(argc, const_cast<char**>(argv), *this), vm);
@@ -196,5 +363,107 @@ CommonOptions::CommonOptions(const string& name, const string& configfile)
}
+
+
+#if ( BOOST_VERSION == 103200 )
+options_description_less_easy_init&
+options_description_less_easy_init::operator()(char const * name,
+ char const * description)
+{
+ // Snoop on the arguments....
+ owner->register_names ( name );
+ // ... then call parent function explicitly.
+ po::options_description_easy_init::operator() ( name, description );
+ return * this;
+}
+
+
+options_description_less_easy_init&
+options_description_less_easy_init::operator()(char const * name,
+ const po::value_semantic* s)
+{
+ // Snoop on the arguments....
+ owner->register_names ( name );
+ // ... then call parent function explicitly.
+ po::options_description_easy_init::operator() ( name, s );
+ return * this;
+}
+
+
+options_description_less_easy_init&
+options_description_less_easy_init::operator()(const char* name,
+ const po::value_semantic* s,
+ const char* description)
+{
+ // Snoop on the arguments....
+ owner->register_names ( name );
+ // ... then call parent function explicitly.
+ po::options_description_easy_init::operator() ( name, s, description );
+ return * this;
+}
+
+
+
+
+
+void
+Options::register_names ( std::string s )
+{
+
+ std::string::size_type comma_pos = s.find_first_of ( ',' );
+
+ if ( std::string::npos == comma_pos )
+ {
+ // There is no short-name.
+ long_names.push_back ( s );
+ }
+ else
+ {
+ std::string long_name = s.substr(0, comma_pos),
+ short_name = s.substr(comma_pos+1);
+ long_names .push_back ( long_name );
+ short_names.push_back ( short_name );
+ }
+
+ /*
+ * There is no way to tell when the adding of new options is finished,
+ * so I re-sort after each one.
+ */
+ std::sort ( long_names .begin(), long_names .end() );
+ std::sort ( short_names.begin(), short_names.end() );
+}
+
+
+
+
+
+bool
+Options::is_registered_option ( std::string s )
+{
+ std::string without_dashes = s.substr ( s.find_first_not_of ( '-' ) );
+ std::vector<std::string>::iterator i;
+
+ // Look among the long names.
+ i = std::find ( long_names.begin(),
+ long_names.end(),
+ without_dashes
+ );
+ if ( i != long_names.end() )
+ return true;
+
+ // Look among the short names.
+ i = std::find ( short_names.begin(),
+ short_names.end(),
+ without_dashes
+ );
+ if ( i != short_names.end() )
+ return true;
+
+
+ return false;
+}
+#endif
+
+
} // namespace qpid
diff --git a/qpid/cpp/src/qpid/RefCounted.h b/qpid/cpp/src/qpid/RefCounted.h
index f9e0107103..e7a9bf31c1 100644
--- a/qpid/cpp/src/qpid/RefCounted.h
+++ b/qpid/cpp/src/qpid/RefCounted.h
@@ -53,10 +53,8 @@ protected:
// intrusive_ptr support.
namespace boost {
-template <typename T>
-inline void intrusive_ptr_add_ref(const T* p) { p->qpid::RefCounted::addRef(); }
-template <typename T>
-inline void intrusive_ptr_release(const T* p) { p->qpid::RefCounted::release(); }
+inline void intrusive_ptr_add_ref(const qpid::RefCounted* p) { p->addRef(); }
+inline void intrusive_ptr_release(const qpid::RefCounted* p) { p->release(); }
}
diff --git a/qpid/cpp/src/qpid/RefCountedBuffer.cpp b/qpid/cpp/src/qpid/RefCountedBuffer.cpp
index 40d620f7ad..9b8f1ebd5e 100644
--- a/qpid/cpp/src/qpid/RefCountedBuffer.cpp
+++ b/qpid/cpp/src/qpid/RefCountedBuffer.cpp
@@ -24,20 +24,30 @@
namespace qpid {
-void RefCountedBuffer::released() const {
+RefCountedBuffer::RefCountedBuffer() : count(0) {}
+
+void RefCountedBuffer::destroy() const {
this->~RefCountedBuffer();
::delete[] reinterpret_cast<const char*>(this);
}
-BufferRef RefCountedBuffer::create(size_t n) {
+char* RefCountedBuffer::addr() const {
+ return const_cast<char*>(reinterpret_cast<const char*>(this)+sizeof(RefCountedBuffer));
+}
+
+RefCountedBuffer::pointer RefCountedBuffer::create(size_t n) {
char* store=::new char[n+sizeof(RefCountedBuffer)];
new(store) RefCountedBuffer;
- char* start = store+sizeof(RefCountedBuffer);
- return BufferRef(
- boost::intrusive_ptr<RefCounted>(reinterpret_cast<RefCountedBuffer*>(store)),
- start, start+n);
+ return pointer(reinterpret_cast<RefCountedBuffer*>(store));
}
+RefCountedBuffer::pointer::pointer() {}
+RefCountedBuffer::pointer::pointer(RefCountedBuffer* x) : p(x) {}
+RefCountedBuffer::pointer::pointer(const pointer& x) : p(x.p) {}
+RefCountedBuffer::pointer::~pointer() {}
+RefCountedBuffer::pointer& RefCountedBuffer::pointer::operator=(const RefCountedBuffer::pointer& x) { p = x.p; return *this; }
+
+char* RefCountedBuffer::pointer::cp() const { return p ? p->get() : 0; }
} // namespace qpid
diff --git a/qpid/cpp/src/qpid/RefCountedBuffer.h b/qpid/cpp/src/qpid/RefCountedBuffer.h
index f0ea86130b..75a23862be 100644
--- a/qpid/cpp/src/qpid/RefCountedBuffer.h
+++ b/qpid/cpp/src/qpid/RefCountedBuffer.h
@@ -22,23 +22,68 @@
*
*/
-#include <qpid/RefCounted.h>
-#include <qpid/BufferRef.h>
+#include <boost/utility.hpp>
+#include <boost/detail/atomic_count.hpp>
+#include <boost/intrusive_ptr.hpp>
namespace qpid {
/**
- * Reference-counted byte buffer. No alignment guarantees.
+ * Reference-counted byte buffer.
+ * No alignment guarantees.
*/
-class RefCountedBuffer : public RefCounted {
- public:
+class RefCountedBuffer : boost::noncopyable {
+ mutable boost::detail::atomic_count count;
+ RefCountedBuffer();
+ void destroy() const;
+ char* addr() const;
+
+public:
+ /** Smart char pointer to a reference counted buffer */
+ class pointer {
+ boost::intrusive_ptr<RefCountedBuffer> p;
+ char* cp() const;
+ pointer(RefCountedBuffer* x);
+ friend class RefCountedBuffer;
+
+ public:
+ pointer();
+ pointer(const pointer&);
+ ~pointer();
+ pointer& operator=(const pointer&);
+
+ char* get() { return cp(); }
+ operator char*() { return cp(); }
+ char& operator*() { return *cp(); }
+ char& operator[](size_t i) { return cp()[i]; }
+
+ const char* get() const { return cp(); }
+ operator const char*() const { return cp(); }
+ const char& operator*() const { return *cp(); }
+ const char& operator[](size_t i) const { return cp()[i]; }
+ };
+
/** Create a reference counted buffer of size n */
- static BufferRef create(size_t n);
+ static pointer create(size_t n);
+
+ /** Get a pointer to the start of the buffer. */
+ char* get() { return addr(); }
+ const char* get() const { return addr(); }
+ char& operator[](size_t i) { return get()[i]; }
+ const char& operator[](size_t i) const { return get()[i]; }
- protected:
- void released() const;
+ void addRef() const { ++count; }
+ void release() const { if (--count==0) destroy(); }
+ long refCount() { return count; }
};
} // namespace qpid
+// intrusive_ptr support.
+namespace boost {
+inline void intrusive_ptr_add_ref(const qpid::RefCountedBuffer* p) { p->addRef(); }
+inline void intrusive_ptr_release(const qpid::RefCountedBuffer* p) { p->release(); }
+}
+
+
#endif /*!QPID_REFCOUNTEDBUFFER_H*/
diff --git a/qpid/cpp/src/qpid/SaslFactory.cpp b/qpid/cpp/src/qpid/SaslFactory.cpp
index f117404028..055883abee 100644
--- a/qpid/cpp/src/qpid/SaslFactory.cpp
+++ b/qpid/cpp/src/qpid/SaslFactory.cpp
@@ -182,17 +182,16 @@ CyrusSasl::CyrusSasl(const std::string & username, const std::string & password,
callbacks[i].id = SASL_CB_AUTHNAME;
callbacks[i].proc = (CallbackProc*) &getUserFromSettings;
callbacks[i++].context = &settings;
-
- callbacks[i].id = SASL_CB_PASS;
- if (settings.password.empty()) {
- callbacks[i].proc = 0;
- callbacks[i++].context = 0;
- } else {
- callbacks[i].proc = (CallbackProc*) &getPasswordFromSettings;
- callbacks[i++].context = &settings;
- }
}
+ callbacks[i].id = SASL_CB_PASS;
+ if (settings.password.empty()) {
+ callbacks[i].proc = 0;
+ callbacks[i++].context = 0;
+ } else {
+ callbacks[i].proc = (CallbackProc*) &getPasswordFromSettings;
+ callbacks[i++].context = &settings;
+ }
callbacks[i].id = SASL_CB_LIST_END;
callbacks[i].proc = 0;
diff --git a/qpid/cpp/src/qpid/acl/Acl.cpp b/qpid/cpp/src/qpid/acl/Acl.cpp
index 4b3dda7962..67603015d7 100644
--- a/qpid/cpp/src/qpid/acl/Acl.cpp
+++ b/qpid/cpp/src/qpid/acl/Acl.cpp
@@ -180,10 +180,7 @@ Acl::Acl (AclValues& av, Broker& b): aclValues(av), broker(&b), transferAcl(fals
{
case _qmf::Acl::METHOD_RELOADACLFILE :
readAclFile(text);
- if (text.empty())
- status = Manageable::STATUS_OK;
- else
- status = Manageable::STATUS_USER;
+ status = Manageable::STATUS_USER;
break;
}
diff --git a/qpid/cpp/src/qpid/agent/ManagementAgentImpl.cpp b/qpid/cpp/src/qpid/agent/ManagementAgentImpl.cpp
index 633401ef5b..593d403a11 100644
--- a/qpid/cpp/src/qpid/agent/ManagementAgentImpl.cpp
+++ b/qpid/cpp/src/qpid/agent/ManagementAgentImpl.cpp
@@ -305,47 +305,43 @@ void ManagementAgentImpl::raiseEvent(const ManagementEvent& event, severity_t se
"emerg", "alert", "crit", "error", "warn",
"note", "info", "debug"
};
- string content;
+ sys::Mutex::ScopedLock lock(agentLock);
+ Buffer outBuffer(eventBuffer, MA_BUFFER_SIZE);
+ uint8_t sev = (severity == SEV_DEFAULT) ? event.getSeverity() : (uint8_t) severity;
stringstream key;
- Variant::Map headers;
- {
- sys::Mutex::ScopedLock lock(agentLock);
- Buffer outBuffer(eventBuffer, MA_BUFFER_SIZE);
- uint8_t sev = (severity == SEV_DEFAULT) ? event.getSeverity() : (uint8_t) severity;
-
- // key << "console.event." << assignedBrokerBank << "." << assignedAgentBank << "." <<
- // event.getPackageName() << "." << event.getEventName();
- key << "agent.ind.event." << keyifyNameStr(event.getPackageName())
- << "." << keyifyNameStr(event.getEventName())
- << "." << severityStr[sev]
- << "." << vendorNameKey
- << "." << productNameKey
- << "." << instanceNameKey;
-
- Variant::Map map_;
- Variant::Map schemaId;
- Variant::Map values;
-
- map_["_schema_id"] = mapEncodeSchemaId(event.getPackageName(),
- event.getEventName(),
- event.getMd5Sum(),
- ManagementItem::CLASS_KIND_EVENT);
- event.mapEncode(values);
- map_["_values"] = values;
- map_["_timestamp"] = uint64_t(Duration(EPOCH, now()));
- map_["_severity"] = sev;
+ // key << "console.event." << assignedBrokerBank << "." << assignedAgentBank << "." <<
+ // event.getPackageName() << "." << event.getEventName();
+ key << "agent.ind.event." << keyifyNameStr(event.getPackageName())
+ << "." << keyifyNameStr(event.getEventName())
+ << "." << severityStr[sev]
+ << "." << vendorNameKey
+ << "." << productNameKey
+ << "." << instanceNameKey;
- headers["method"] = "indication";
- headers["qmf.opcode"] = "_data_indication";
- headers["qmf.content"] = "_event";
- headers["qmf.agent"] = name_address;
+ Variant::Map map_;
+ Variant::Map schemaId;
+ Variant::Map values;
+ Variant::Map headers;
+ string content;
- Variant::List list;
- list.push_back(map_);
- ListCodec::encode(list, content);
- }
+ map_["_schema_id"] = mapEncodeSchemaId(event.getPackageName(),
+ event.getEventName(),
+ event.getMd5Sum(),
+ ManagementItem::CLASS_KIND_EVENT);
+ event.mapEncode(values);
+ map_["_values"] = values;
+ map_["_timestamp"] = uint64_t(Duration(EPOCH, now()));
+ map_["_severity"] = sev;
+ headers["method"] = "indication";
+ headers["qmf.opcode"] = "_data_indication";
+ headers["qmf.content"] = "_event";
+ headers["qmf.agent"] = name_address;
+
+ Variant::List list;
+ list.push_back(map_);
+ ListCodec::encode(list, content);
connThreadBody.sendBuffer(content, "", headers, topicExchange, key.str(), "amqp/list");
}
@@ -525,12 +521,9 @@ void ManagementAgentImpl::sendException(const string& rte, const string& rtk, co
void ManagementAgentImpl::handleSchemaRequest(Buffer& inBuffer, uint32_t sequence, const string& rte, const string& rtk)
{
+ sys::Mutex::ScopedLock lock(agentLock);
string packageName;
SchemaClassKey key;
- uint32_t outLen(0);
- char localBuffer[MA_BUFFER_SIZE];
- Buffer outBuffer(localBuffer, MA_BUFFER_SIZE);
- bool found(false);
inBuffer.getShortString(packageName);
inBuffer.getShortString(key.name);
@@ -538,30 +531,26 @@ void ManagementAgentImpl::handleSchemaRequest(Buffer& inBuffer, uint32_t sequenc
QPID_LOG(trace, "RCVD SchemaRequest: package=" << packageName << " class=" << key.name);
- {
- sys::Mutex::ScopedLock lock(agentLock);
- PackageMap::iterator pIter = packages.find(packageName);
- if (pIter != packages.end()) {
- ClassMap& cMap = pIter->second;
- ClassMap::iterator cIter = cMap.find(key);
- if (cIter != cMap.end()) {
- SchemaClass& schema = cIter->second;
- string body;
-
- encodeHeader(outBuffer, 's', sequence);
- schema.writeSchemaCall(body);
- outBuffer.putRawData(body);
- outLen = MA_BUFFER_SIZE - outBuffer.available();
- outBuffer.reset();
- found = true;
- }
+ PackageMap::iterator pIter = packages.find(packageName);
+ if (pIter != packages.end()) {
+ ClassMap& cMap = pIter->second;
+ ClassMap::iterator cIter = cMap.find(key);
+ if (cIter != cMap.end()) {
+ SchemaClass& schema = cIter->second;
+ Buffer outBuffer(outputBuffer, MA_BUFFER_SIZE);
+ uint32_t outLen;
+ string body;
+
+ encodeHeader(outBuffer, 's', sequence);
+ schema.writeSchemaCall(body);
+ outBuffer.putRawData(body);
+ outLen = MA_BUFFER_SIZE - outBuffer.available();
+ outBuffer.reset();
+ connThreadBody.sendBuffer(outBuffer, outLen, rte, rtk);
+
+ QPID_LOG(trace, "SENT SchemaInd: package=" << packageName << " class=" << key.name);
}
}
-
- if (found) {
- connThreadBody.sendBuffer(outBuffer, outLen, rte, rtk);
- QPID_LOG(trace, "SENT SchemaInd: package=" << packageName << " class=" << key.name);
- }
}
void ManagementAgentImpl::handleConsoleAddedIndication()
@@ -980,6 +969,18 @@ ManagementAgentImpl::PackageMap::iterator ManagementAgentImpl::findOrAddPackage(
pair<PackageMap::iterator, bool> result =
packages.insert(pair<string, ClassMap>(name, ClassMap()));
+ if (connected) {
+ // Publish a package-indication message
+ Buffer outBuffer(outputBuffer, MA_BUFFER_SIZE);
+ uint32_t outLen;
+
+ encodeHeader(outBuffer, 'p');
+ encodePackageIndication(outBuffer, result.first);
+ outLen = MA_BUFFER_SIZE - outBuffer.available();
+ outBuffer.reset();
+ connThreadBody.sendBuffer(outBuffer, outLen, "qpid.management", "schema.package");
+ }
+
return result.first;
}
@@ -1037,146 +1038,131 @@ void ManagementAgentImpl::encodeClassIndication(Buffer& buf,
QPID_LOG(trace, "SENT ClassInd: package=" << (*pIter).first << " class=" << key.name);
}
-struct MessageItem {
- string content;
- Variant::Map headers;
- string key;
- MessageItem(const Variant::Map& h, const string& k) : headers(h), key(k) {}
-};
-
void ManagementAgentImpl::periodicProcessing()
{
string addr_key_base = "agent.ind.data.";
+ sys::Mutex::ScopedLock lock(agentLock);
list<ObjectId> deleteList;
- list<boost::shared_ptr<MessageItem> > message_list;
+
+ if (!connected)
+ return;
sendHeartbeat();
- {
- sys::Mutex::ScopedLock lock(agentLock);
+ moveNewObjectsLH();
- if (!connected)
- return;
+ //
+ // Clear the been-here flag on all objects in the map.
+ //
+ for (ObjectMap::iterator iter = managementObjects.begin();
+ iter != managementObjects.end();
+ iter++) {
+ ManagementObject* object = iter->second.get();
+ object->setFlags(0);
+ if (publishAllData) {
+ object->setForcePublish(true);
+ }
+ }
- moveNewObjectsLH();
+ publishAllData = false;
+
+ //
+ // Process the entire object map.
+ //
+ uint32_t v2Objs = 0;
+
+ for (ObjectMap::iterator baseIter = managementObjects.begin();
+ baseIter != managementObjects.end();
+ baseIter++) {
+ ManagementObject* baseObject = baseIter->second.get();
//
- // Clear the been-here flag on all objects in the map.
+ // Skip until we find a base object requiring a sent message.
//
- for (ObjectMap::iterator iter = managementObjects.begin();
+ if (baseObject->getFlags() == 1 ||
+ (!baseObject->getConfigChanged() &&
+ !baseObject->getInstChanged() &&
+ !baseObject->getForcePublish() &&
+ !baseObject->isDeleted()))
+ continue;
+
+ std::string packageName = baseObject->getPackageName();
+ std::string className = baseObject->getClassName();
+
+ Variant::List list_;
+ string content;
+ std::stringstream addr_key;
+ Variant::Map headers;
+
+ addr_key << addr_key_base;
+ addr_key << keyifyNameStr(packageName)
+ << "." << keyifyNameStr(className)
+ << "." << vendorNameKey
+ << "." << productNameKey
+ << "." << instanceNameKey;
+
+ headers["method"] = "indication";
+ headers["qmf.opcode"] = "_data_indication";
+ headers["qmf.content"] = "_data";
+ headers["qmf.agent"] = name_address;
+
+ for (ObjectMap::iterator iter = baseIter;
iter != managementObjects.end();
iter++) {
ManagementObject* object = iter->second.get();
- object->setFlags(0);
- if (publishAllData) {
- object->setForcePublish(true);
- }
- }
-
- publishAllData = false;
-
- //
- // Process the entire object map.
- //
- uint32_t v2Objs = 0;
-
- for (ObjectMap::iterator baseIter = managementObjects.begin();
- baseIter != managementObjects.end();
- baseIter++) {
- ManagementObject* baseObject = baseIter->second.get();
-
- //
- // Skip until we find a base object requiring a sent message.
- //
- if (baseObject->getFlags() == 1 ||
- (!baseObject->getConfigChanged() &&
- !baseObject->getInstChanged() &&
- !baseObject->getForcePublish() &&
- !baseObject->isDeleted()))
- continue;
-
- std::string packageName = baseObject->getPackageName();
- std::string className = baseObject->getClassName();
-
- Variant::List list_;
- std::stringstream addr_key;
- Variant::Map headers;
-
- addr_key << addr_key_base;
- addr_key << keyifyNameStr(packageName)
- << "." << keyifyNameStr(className)
- << "." << vendorNameKey
- << "." << productNameKey
- << "." << instanceNameKey;
-
- headers["method"] = "indication";
- headers["qmf.opcode"] = "_data_indication";
- headers["qmf.content"] = "_data";
- headers["qmf.agent"] = name_address;
-
- for (ObjectMap::iterator iter = baseIter;
- iter != managementObjects.end();
- iter++) {
- ManagementObject* object = iter->second.get();
- bool send_stats, send_props;
- if (baseObject->isSameClass(*object) && object->getFlags() == 0) {
- object->setFlags(1);
- if (object->getConfigChanged() || object->getInstChanged())
- object->setUpdateTime();
-
- send_props = (object->getConfigChanged() || object->getForcePublish() || object->isDeleted());
- send_stats = (object->hasInst() && (object->getInstChanged() || object->getForcePublish()));
-
- if (send_stats || send_props) {
- Variant::Map map_;
- Variant::Map values;
- Variant::Map oid;
-
- object->getObjectId().mapEncode(oid);
- map_["_object_id"] = oid;
- map_["_schema_id"] = mapEncodeSchemaId(object->getPackageName(),
- object->getClassName(),
- object->getMd5Sum());
- object->writeTimestamps(map_);
- object->mapEncodeValues(values, send_props, send_stats);
- map_["_values"] = values;
- list_.push_back(map_);
+ bool send_stats, send_props;
+ if (baseObject->isSameClass(*object) && object->getFlags() == 0) {
+ object->setFlags(1);
+ if (object->getConfigChanged() || object->getInstChanged())
+ object->setUpdateTime();
- if (++v2Objs >= maxV2ReplyObjs) {
- v2Objs = 0;
- boost::shared_ptr<MessageItem> item(new MessageItem(headers, addr_key.str()));
- ListCodec::encode(list_, item->content);
- message_list.push_back(item);
- list_.clear();
- }
+ send_props = (object->getConfigChanged() || object->getForcePublish() || object->isDeleted());
+ send_stats = (object->hasInst() && (object->getInstChanged() || object->getForcePublish()));
+
+ if (send_stats || send_props) {
+ Variant::Map map_;
+ Variant::Map values;
+ Variant::Map oid;
+
+ object->getObjectId().mapEncode(oid);
+ map_["_object_id"] = oid;
+ map_["_schema_id"] = mapEncodeSchemaId(object->getPackageName(),
+ object->getClassName(),
+ object->getMd5Sum());
+ object->writeTimestamps(map_);
+ object->mapEncodeValues(values, send_props, send_stats);
+ map_["_values"] = values;
+ list_.push_back(map_);
+
+ if (++v2Objs >= maxV2ReplyObjs) {
+ v2Objs = 0;
+ ListCodec::encode(list_, content);
+
+ connThreadBody.sendBuffer(content, "", headers, topicExchange, addr_key.str(), "amqp/list");
+ list_.clear();
+ content.clear();
+ QPID_LOG(trace, "SENT DataIndication");
}
-
- if (object->isDeleted())
- deleteList.push_back(iter->first);
- object->setForcePublish(false);
}
- }
- if (!list_.empty()) {
- boost::shared_ptr<MessageItem> item(new MessageItem(headers, addr_key.str()));
- ListCodec::encode(list_, item->content);
- message_list.push_back(item);
+ if (object->isDeleted())
+ deleteList.push_back(iter->first);
+ object->setForcePublish(false);
}
}
- // Delete flagged objects
- for (list<ObjectId>::reverse_iterator iter = deleteList.rbegin();
- iter != deleteList.rend();
- iter++)
- managementObjects.erase(*iter);
+ if (!list_.empty()) {
+ ListCodec::encode(list_, content);
+ connThreadBody.sendBuffer(content, "", headers, topicExchange, addr_key.str(), "amqp/list");
+ QPID_LOG(trace, "SENT DataIndication");
+ }
}
- while (!message_list.empty()) {
- boost::shared_ptr<MessageItem> item(message_list.front());
- message_list.pop_front();
- connThreadBody.sendBuffer(item->content, "", item->headers, topicExchange, item->key, "amqp/list");
- QPID_LOG(trace, "SENT DataIndication");
- }
+ // Delete flagged objects
+ for (list<ObjectId>::reverse_iterator iter = deleteList.rbegin();
+ iter != deleteList.rend();
+ iter++)
+ managementObjects.erase(*iter);
}
diff --git a/qpid/cpp/src/qpid/agent/ManagementAgentImpl.h b/qpid/cpp/src/qpid/agent/ManagementAgentImpl.h
index 53f3c13a91..bf340777d1 100644
--- a/qpid/cpp/src/qpid/agent/ManagementAgentImpl.h
+++ b/qpid/cpp/src/qpid/agent/ManagementAgentImpl.h
@@ -62,8 +62,8 @@ class ManagementAgentImpl : public ManagementAgent, public client::MessageListen
uint16_t intervalSeconds = 10,
bool useExternalThread = false,
const std::string& storeFile = "",
- const std::string& uid = "",
- const std::string& pwd = "",
+ const std::string& uid = "guest",
+ const std::string& pwd = "guest",
const std::string& mech = "PLAIN",
const std::string& proto = "tcp");
void init(const management::ConnectionSettings& settings,
diff --git a/qpid/cpp/src/qpid/amqp_0_10/Codecs.cpp b/qpid/cpp/src/qpid/amqp_0_10/Codecs.cpp
index b976a5d09b..0fbe2a60b9 100644
--- a/qpid/cpp/src/qpid/amqp_0_10/Codecs.cpp
+++ b/qpid/cpp/src/qpid/amqp_0_10/Codecs.cpp
@@ -127,10 +127,10 @@ Variant toVariant(boost::shared_ptr<FieldValue> in)
switch (in->getType()) {
//Fixed Width types:
case 0x01: out.setEncoding(amqp0_10_binary);
- case 0x02: out = in->getIntegerValue<int8_t>(); break;
- case 0x03: out = in->getIntegerValue<uint8_t>(); break;
+ case 0x02: out = in->getIntegerValue<int8_t, 1>(); break;
+ case 0x03: out = in->getIntegerValue<uint8_t, 1>(); break;
case 0x04: break; //TODO: iso-8859-15 char
- case 0x08: out = static_cast<bool>(in->getIntegerValue<uint8_t>()); break;
+ case 0x08: out = static_cast<bool>(in->getIntegerValue<uint8_t, 1>()); break;
case 0x10: out.setEncoding(amqp0_10_binary);
case 0x11: out = in->getIntegerValue<int16_t, 2>(); break;
case 0x12: out = in->getIntegerValue<uint16_t, 2>(); break;
diff --git a/qpid/cpp/src/qpid/amqp_0_10/SessionHandler.cpp b/qpid/cpp/src/qpid/amqp_0_10/SessionHandler.cpp
index 578598a146..b113d49a73 100644
--- a/qpid/cpp/src/qpid/amqp_0_10/SessionHandler.cpp
+++ b/qpid/cpp/src/qpid/amqp_0_10/SessionHandler.cpp
@@ -130,6 +130,9 @@ void SessionHandler::handleException(const qpid::SessionException& e)
}
namespace {
+bool isControl(const AMQFrame& f) {
+ return f.getMethod() && f.getMethod()->type() == framing::SEGMENT_TYPE_CONTROL;
+}
bool isCommand(const AMQFrame& f) {
return f.getMethod() && f.getMethod()->type() == framing::SEGMENT_TYPE_COMMAND;
}
@@ -188,10 +191,9 @@ void SessionHandler::detach(const std::string& name) {
void SessionHandler::detached(const std::string& name, uint8_t code) {
CHECK_NAME(name, "session.detached");
awaitingDetached = false;
- if (code != session::DETACH_CODE_NORMAL) {
- sendReady = receiveReady = false;
+ if (code != session::DETACH_CODE_NORMAL)
channelException(convert(code), "session.detached from peer.");
- } else {
+ else {
handleDetach();
}
}
diff --git a/qpid/cpp/src/qpid/amqp_0_10/SessionHandler.h b/qpid/cpp/src/qpid/amqp_0_10/SessionHandler.h
index 8b072fa05c..a87a1a155f 100644
--- a/qpid/cpp/src/qpid/amqp_0_10/SessionHandler.h
+++ b/qpid/cpp/src/qpid/amqp_0_10/SessionHandler.h
@@ -41,8 +41,8 @@ namespace amqp_0_10 {
* to a session state.
*/
-class QPID_COMMON_CLASS_EXTERN SessionHandler : public framing::AMQP_AllOperations::SessionHandler,
- public framing::FrameHandler::InOutHandler
+class SessionHandler : public framing::AMQP_AllOperations::SessionHandler,
+ public framing::FrameHandler::InOutHandler
{
public:
QPID_COMMON_EXTERN SessionHandler(framing::FrameHandler* out=0, uint16_t channel=0);
@@ -66,7 +66,7 @@ class QPID_COMMON_CLASS_EXTERN SessionHandler : public framing::AMQP_AllOperatio
QPID_COMMON_EXTERN void handleException(const qpid::SessionException& e);
/** True if the handler is ready to send and receive */
- QPID_COMMON_EXTERN bool ready() const;
+ bool ready() const;
// Protocol methods
QPID_COMMON_EXTERN void attach(const std::string& name, bool force);
diff --git a/qpid/cpp/src/qpid/broker/AsyncCompletion.h b/qpid/cpp/src/qpid/broker/AsyncCompletion.h
index fef994438f..1f3d11e0ee 100644
--- a/qpid/cpp/src/qpid/broker/AsyncCompletion.h
+++ b/qpid/cpp/src/qpid/broker/AsyncCompletion.h
@@ -22,8 +22,6 @@
*
*/
-#include <boost/intrusive_ptr.hpp>
-
#include "qpid/broker/BrokerImportExport.h"
#include "qpid/sys/AtomicValue.h"
#include "qpid/sys/Mutex.h"
@@ -79,22 +77,6 @@ namespace broker {
class AsyncCompletion
{
- public:
-
- /** Supplied by the Initiator to the end() method, allows for a callback
- * when all outstanding completers are done. If the callback cannot be
- * made during the end() call, the clone() method must supply a copy of
- * this callback object that persists after end() returns. The cloned
- * callback object will be used by the last completer thread, and
- * released when the callback returns.
- */
- class Callback : public RefCounted
- {
- public:
- virtual void completed(bool) = 0;
- virtual boost::intrusive_ptr<Callback> clone() = 0;
- };
-
private:
mutable qpid::sys::AtomicValue<uint32_t> completionsNeeded;
mutable qpid::sys::Monitor callbackLock;
@@ -103,17 +85,14 @@ class AsyncCompletion
void invokeCallback(bool sync) {
qpid::sys::Mutex::ScopedLock l(callbackLock);
if (active) {
- if (callback.get()) {
- inCallback = true;
- {
- qpid::sys::Mutex::ScopedUnlock ul(callbackLock);
- callback->completed(sync);
- }
- inCallback = false;
- callback = boost::intrusive_ptr<Callback>();
- callbackLock.notifyAll();
+ inCallback = true;
+ {
+ qpid::sys::Mutex::ScopedUnlock ul(callbackLock);
+ completed(sync);
}
+ inCallback = false;
active = false;
+ callbackLock.notifyAll();
}
}
@@ -121,17 +100,17 @@ class AsyncCompletion
/** Invoked when all completers have signalled that they have completed
* (via calls to finishCompleter()). bool == true if called via end()
*/
- boost::intrusive_ptr<Callback> callback;
+ virtual void completed(bool) = 0;
public:
AsyncCompletion() : completionsNeeded(0), inCallback(false), active(true) {};
virtual ~AsyncCompletion() { cancel(); }
-
/** True when all outstanding operations have compeleted
*/
bool isDone()
{
+ qpid::sys::Mutex::ScopedLock l(callbackLock);
return !active;
}
@@ -156,32 +135,17 @@ class AsyncCompletion
*/
void begin()
{
+ qpid::sys::Mutex::ScopedLock l(callbackLock);
++completionsNeeded;
}
/** called by initiator after all potential completers have called
* startCompleter().
*/
- void end(Callback& cb)
+ void end()
{
assert(completionsNeeded.get() > 0); // ensure begin() has been called!
- // the following only "decrements" the count if it is 1. This means
- // there are no more outstanding completers and we are done.
- if (completionsNeeded.boolCompareAndSwap(1, 0)) {
- // done! Complete immediately
- cb.completed(true);
- return;
- }
-
- // the compare-and-swap did not succeed. This means there are
- // outstanding completers pending (count > 1). Get a persistent
- // Callback object to use when the last completer is done.
- // Decrement after setting up the callback ensures that pending
- // completers cannot touch the callback until it is ready.
- callback = cb.clone();
if (--completionsNeeded == 0) {
- // note that a completer may have completed during the
- // callback setup or decrement:
invokeCallback(true);
}
}
@@ -192,9 +156,14 @@ class AsyncCompletion
virtual void cancel() {
qpid::sys::Mutex::ScopedLock l(callbackLock);
while (inCallback) callbackLock.wait();
- callback = boost::intrusive_ptr<Callback>();
active = false;
}
+
+ /** may be called by Initiator after all completers have been added but
+ * prior to calling end(). Allows initiator to determine if it _really_
+ * needs to wait for pending Completers (e.g. count > 1).
+ */
+ //uint32_t getPendingCompleters() { return completionsNeeded.get(); }
};
}} // qpid::broker::
diff --git a/qpid/cpp/src/qpid/broker/Bridge.cpp b/qpid/cpp/src/qpid/broker/Bridge.cpp
index c709606c17..7fbbf4e2c4 100644
--- a/qpid/cpp/src/qpid/broker/Bridge.cpp
+++ b/qpid/cpp/src/qpid/broker/Bridge.cpp
@@ -164,12 +164,6 @@ void Bridge::destroy()
listener(this);
}
-bool Bridge::isSessionReady() const
-{
- SessionHandler& sessionHandler = conn->getChannel(id);
- return sessionHandler.ready();
-}
-
void Bridge::setPersistenceId(uint64_t pId) const
{
persistenceId = pId;
diff --git a/qpid/cpp/src/qpid/broker/Bridge.h b/qpid/cpp/src/qpid/broker/Bridge.h
index 8b4559a871..a846254c57 100644
--- a/qpid/cpp/src/qpid/broker/Bridge.h
+++ b/qpid/cpp/src/qpid/broker/Bridge.h
@@ -59,8 +59,6 @@ public:
void destroy();
bool isDurable() { return args.i_durable; }
- bool isSessionReady() const;
-
management::ManagementObject* GetManagementObject() const;
management::Manageable::status_t ManagementMethod(uint32_t methodId,
management::Args& args,
diff --git a/qpid/cpp/src/qpid/broker/Broker.cpp b/qpid/cpp/src/qpid/broker/Broker.cpp
index 6eaf16b052..c5662d763a 100644
--- a/qpid/cpp/src/qpid/broker/Broker.cpp
+++ b/qpid/cpp/src/qpid/broker/Broker.cpp
@@ -121,8 +121,7 @@ Broker::Options::Options(const std::string& name) :
qmf2Support(true),
qmf1Support(true),
queueFlowStopRatio(80),
- queueFlowResumeRatio(70),
- queueThresholdEventRatio(80)
+ queueFlowResumeRatio(70)
{
int c = sys::SystemInfo::concurrency();
workerThreads=c+1;
@@ -153,12 +152,11 @@ Broker::Options::Options(const std::string& name) :
("tcp-nodelay", optValue(tcpNoDelay), "Set TCP_NODELAY on TCP connections")
("require-encryption", optValue(requireEncrypted), "Only accept connections that are encrypted")
("known-hosts-url", optValue(knownHosts, "URL or 'none'"), "URL to send as 'known-hosts' to clients ('none' implies empty list)")
- ("sasl-config", optValue(saslConfigPath, "DIR"), "gets sasl config info from nonstandard location")
+ ("sasl-config", optValue(saslConfigPath, "FILE"), "gets sasl config from nonstandard location")
("max-session-rate", optValue(maxSessionRate, "MESSAGES/S"), "Sets the maximum message rate per session (0=unlimited)")
("async-queue-events", optValue(asyncQueueEvents, "yes|no"), "Set Queue Events async, used for services like replication")
- ("default-flow-stop-threshold", optValue(queueFlowStopRatio, "PERCENT"), "Percent of queue's maximum capacity at which flow control is activated.")
- ("default-flow-resume-threshold", optValue(queueFlowResumeRatio, "PERCENT"), "Percent of queue's maximum capacity at which flow control is de-activated.")
- ("default-event-threshold-ratio", optValue(queueThresholdEventRatio, "%age of limit"), "The ratio of any specified queue limit at which an event will be raised");
+ ("default-flow-stop-threshold", optValue(queueFlowStopRatio, "%MESSAGES"), "Queue capacity level at which flow control is activated.")
+ ("default-flow-resume-threshold", optValue(queueFlowResumeRatio, "%MESSAGES"), "Queue capacity level at which flow control is de-activated.");
}
const std::string empty;
@@ -188,7 +186,7 @@ Broker::Broker(const Broker::Options& conf) :
conf.replayFlushLimit*1024, // convert kb to bytes.
conf.replayHardLimit*1024),
*this),
- queueCleaner(queues, &timer),
+ queueCleaner(queues, timer),
queueEvents(poller,!conf.asyncQueueEvents),
recovery(true),
inCluster(false),
@@ -248,7 +246,13 @@ Broker::Broker(const Broker::Options& conf) :
// Early-Initialize plugins
Plugin::earlyInitAll(*this);
- QueueFlowLimit::setDefaults(conf.queueLimit, conf.queueFlowStopRatio, conf.queueFlowResumeRatio);
+ /** todo KAG - remove once cluster support for flow control done */
+ if (isInCluster()) {
+ QPID_LOG(info, "Producer Flow Control TBD for clustered brokers - queue flow control disabled by default.");
+ QueueFlowLimit::setDefaults(0, 0, 0);
+ } else {
+ QueueFlowLimit::setDefaults(conf.queueLimit, conf.queueFlowStopRatio, conf.queueFlowResumeRatio);
+ }
// If no plugin store module registered itself, set up the null store.
if (NullMessageStore::isNullStore(store.get()))
@@ -434,9 +438,8 @@ Manageable::status_t Broker::ManagementMethod (uint32_t methodId,
_qmf::ArgsBrokerConnect& hp=
dynamic_cast<_qmf::ArgsBrokerConnect&>(args);
+ QPID_LOG (debug, "Broker::connect()");
string transport = hp.i_transport.empty() ? TCP_TRANSPORT : hp.i_transport;
- QPID_LOG (debug, "Broker::connect() " << hp.i_host << ":" << hp.i_port << "; transport=" << transport <<
- "; durable=" << (hp.i_durable?"T":"F") << "; authMech=\"" << hp.i_authMechanism << "\"");
if (!getProtocolFactory(transport)) {
QPID_LOG(error, "Transport '" << transport << "' not supported");
return Manageable::STATUS_NOT_IMPLEMENTED;
@@ -453,9 +456,9 @@ Manageable::status_t Broker::ManagementMethod (uint32_t methodId,
_qmf::ArgsBrokerQueueMoveMessages& moveArgs=
dynamic_cast<_qmf::ArgsBrokerQueueMoveMessages&>(args);
QPID_LOG (debug, "Broker::queueMoveMessages()");
- if (queueMoveMessages(moveArgs.i_srcQueue, moveArgs.i_destQueue, moveArgs.i_qty))
+ if (queueMoveMessages(moveArgs.i_srcQueue, moveArgs.i_destQueue, moveArgs.i_qty))
status = Manageable::STATUS_OK;
- else
+ else
return Manageable::STATUS_PARAMETER_INVALID;
break;
}
@@ -590,7 +593,7 @@ void Broker::createObject(const std::string& type, const std::string& name,
}
} else if (type == TYPE_EXCHANGE || type == TYPE_TOPIC) {
bool durable(false);
- std::string exchangeType("topic");
+ std::string exchangeType;
std::string alternateExchange;
Variant::Map extensions;
for (Variant::Map::const_iterator i = properties.begin(); i != properties.end(); ++i) {
@@ -702,7 +705,7 @@ void Broker::accept() {
}
void Broker::connect(
- const std::string& host, const std::string& port, const std::string& transport,
+ const std::string& host, uint16_t port, const std::string& transport,
boost::function2<void, int, std::string> failed,
sys::ConnectionCodec::Factory* f)
{
@@ -718,7 +721,7 @@ void Broker::connect(
{
url.throwIfEmpty();
const Address& addr=url[0];
- connect(addr.host, boost::lexical_cast<std::string>(addr.port), addr.protocol, failed, f);
+ connect(addr.host, addr.port, addr.protocol, failed, f);
}
uint32_t Broker::queueMoveMessages(
@@ -751,7 +754,6 @@ bool Broker::deferDeliveryImpl(const std::string& ,
void Broker::setClusterTimer(std::auto_ptr<sys::Timer> t) {
clusterTimer = t;
- queueCleaner.setTimer(clusterTimer.get());
}
const std::string Broker::TCP_TRANSPORT("tcp");
@@ -785,11 +787,18 @@ std::pair<boost::shared_ptr<Queue>, bool> Broker::createQueue(
Exchange::shared_ptr alternate;
if (!alternateExchange.empty()) {
alternate = exchanges.get(alternateExchange);
- if (!alternate) throw framing::NotFoundException(QPID_MSG("Alternate exchange does not exist: " << alternateExchange));
+ if (!alternate) framing::NotFoundException(QPID_MSG("Alternate exchange does not exist: " << alternateExchange));
}
- std::pair<Queue::shared_ptr, bool> result = queues.declare(name, durable, autodelete, owner, alternate, arguments);
+ std::pair<Queue::shared_ptr, bool> result = queues.declare(name, durable, autodelete, owner);
if (result.second) {
+ if (alternate) {
+ result.first->setAlternateExchange(alternate);
+ alternate->incAlternateUsers();
+ }
+
+ //apply settings & create persistent record if required
+ result.first->create(arguments);
//add default binding:
result.first->bind(exchanges.getDefault(), name);
@@ -850,7 +859,7 @@ std::pair<Exchange::shared_ptr, bool> Broker::createExchange(
Exchange::shared_ptr alternate;
if (!alternateExchange.empty()) {
alternate = exchanges.get(alternateExchange);
- if (!alternate) throw framing::NotFoundException(QPID_MSG("Alternate exchange does not exist: " << alternateExchange));
+ if (!alternate) framing::NotFoundException(QPID_MSG("Alternate exchange does not exist: " << alternateExchange));
}
std::pair<Exchange::shared_ptr, bool> result;
diff --git a/qpid/cpp/src/qpid/broker/Broker.h b/qpid/cpp/src/qpid/broker/Broker.h
index 40f7b6273f..d85927c43c 100644
--- a/qpid/cpp/src/qpid/broker/Broker.h
+++ b/qpid/cpp/src/qpid/broker/Broker.h
@@ -120,7 +120,6 @@ public:
bool qmf1Support;
uint queueFlowStopRatio; // producer flow control: on
uint queueFlowResumeRatio; // producer flow control: off
- uint16_t queueThresholdEventRatio;
private:
std::string getHome();
@@ -154,7 +153,7 @@ public:
void setLogLevel(const std::string& level);
std::string getLogLevel();
void createObject(const std::string& type, const std::string& name,
- const qpid::types::Variant::Map& properties, bool strict, const ConnectionState* context);
+ const qpid::types::Variant::Map& properties, bool lenient, const ConnectionState* context);
void deleteObject(const std::string& type, const std::string& name,
const qpid::types::Variant::Map& options, const ConnectionState* context);
@@ -244,7 +243,7 @@ public:
QPID_BROKER_EXTERN void accept();
/** Create a connection to another broker. */
- void connect(const std::string& host, const std::string& port,
+ void connect(const std::string& host, uint16_t port,
const std::string& transport,
boost::function2<void, int, std::string> failed,
sys::ConnectionCodec::Factory* =0);
diff --git a/qpid/cpp/src/qpid/broker/BrokerImportExport.h b/qpid/cpp/src/qpid/broker/BrokerImportExport.h
index ee05788063..4edf8c9844 100644
--- a/qpid/cpp/src/qpid/broker/BrokerImportExport.h
+++ b/qpid/cpp/src/qpid/broker/BrokerImportExport.h
@@ -20,23 +20,14 @@
* under the License.
*/
-#if defined(WIN32) && !defined(QPID_DECLARE_STATIC)
-# if defined(BROKER_EXPORT) || defined (qpidbroker_EXPORTS)
-# define QPID_BROKER_EXTERN __declspec(dllexport)
-# else
-# define QPID_BROKER_EXTERN __declspec(dllimport)
-# endif
-# ifdef _MSC_VER
-# define QPID_BROKER_CLASS_EXTERN
-# define QPID_BROKER_INLINE_EXTERN QPID_BROKER_EXTERN
-# else
-# define QPID_BROKER_CLASS_EXTERN QPID_BROKER_EXTERN
-# define QPID_BROKER_INLINE_EXTERN
-# endif
+#if defined(WIN32) && !defined(QPID_BROKER_STATIC)
+#if defined(BROKER_EXPORT) || defined (qpidbroker_EXPORTS)
+#define QPID_BROKER_EXTERN __declspec(dllexport)
#else
-# define QPID_BROKER_EXTERN
-# define QPID_BROKER_CLASS_EXTERN
-# define QPID_BROKER_INLINE_EXTERN
+#define QPID_BROKER_EXTERN __declspec(dllimport)
+#endif
+#else
+#define QPID_BROKER_EXTERN
#endif
#endif
diff --git a/qpid/cpp/src/qpid/broker/Connection.cpp b/qpid/cpp/src/qpid/broker/Connection.cpp
index 8362a9782c..67713a6eb7 100644
--- a/qpid/cpp/src/qpid/broker/Connection.cpp
+++ b/qpid/cpp/src/qpid/broker/Connection.cpp
@@ -288,11 +288,11 @@ void Connection::raiseConnectEvent() {
}
}
-void Connection::setUserProxyAuth(bool b)
+void Connection::setFederationLink(bool b)
{
- ConnectionState::setUserProxyAuth(b);
+ ConnectionState::setFederationLink(b);
if (mgmtObject != 0)
- mgmtObject->set_userProxyAuth(b);
+ mgmtObject->set_federationLink(b);
}
void Connection::close(connection::CloseCode code, const string& text)
@@ -331,30 +331,31 @@ void Connection::closed(){ // Physically closed, suspend open sessions.
try {
while (!channels.empty())
ptr_map_ptr(channels.begin())->handleDetach();
+ while (!exclusiveQueues.empty()) {
+ boost::shared_ptr<Queue> q(exclusiveQueues.front());
+ q->releaseExclusiveOwnership();
+ if (q->canAutoDelete()) {
+ Queue::tryAutoDelete(broker, q);
+ }
+ exclusiveQueues.erase(exclusiveQueues.begin());
+ }
} catch(std::exception& e) {
QPID_LOG(error, QPID_MSG("While closing connection: " << e.what()));
assert(0);
}
}
-void Connection::doIoCallbacks() {
- {
- ScopedLock<Mutex> l(ioCallbackLock);
- // Although IO callbacks execute in the connection thread context, they are
- // not cluster safe because they are queued for execution in non-IO threads.
- ClusterUnsafeScope cus;
- while (!ioCallbacks.empty()) {
- boost::function0<void> cb = ioCallbacks.front();
- ioCallbacks.pop();
- ScopedUnlock<Mutex> ul(ioCallbackLock);
- cb(); // Lend the IO thread for management processing
- }
- }
-}
-
bool Connection::doOutput() {
try {
- doIoCallbacks();
+ {
+ ScopedLock<Mutex> l(ioCallbackLock);
+ while (!ioCallbacks.empty()) {
+ boost::function0<void> cb = ioCallbacks.front();
+ ioCallbacks.pop();
+ ScopedUnlock<Mutex> ul(ioCallbackLock);
+ cb(); // Lend the IO thread for management processing
+ }
+ }
if (mgmtClosing) {
closed();
close(connection::CLOSE_CODE_CONNECTION_FORCED, "Closed by Management Request");
@@ -474,8 +475,8 @@ void Connection::OutboundFrameTracker::abort() { next->abort(); }
void Connection::OutboundFrameTracker::activateOutput() { next->activateOutput(); }
void Connection::OutboundFrameTracker::giveReadCredit(int32_t credit) { next->giveReadCredit(credit); }
void Connection::OutboundFrameTracker::send(framing::AMQFrame& f)
-{
- next->send(f);
+{
+ next->send(f);
con.sent(f);
}
void Connection::OutboundFrameTracker::wrap(sys::ConnectionOutputHandlerPtr& p)
diff --git a/qpid/cpp/src/qpid/broker/Connection.h b/qpid/cpp/src/qpid/broker/Connection.h
index 3522d70b35..b751848d73 100644
--- a/qpid/cpp/src/qpid/broker/Connection.h
+++ b/qpid/cpp/src/qpid/broker/Connection.h
@@ -125,7 +125,7 @@ class Connection : public sys::ConnectionInputHandler,
const std::string& getUserId() const { return ConnectionState::getUserId(); }
const std::string& getMgmtId() const { return mgmtId; }
management::ManagementAgent* getAgent() const { return agent; }
- void setUserProxyAuth(bool b);
+ void setFederationLink(bool b);
/** Connection does not delete the listener. 0 resets. */
void setErrorListener(ErrorListener* l) { errorListener=l; }
ErrorListener* getErrorListener() { return errorListener; }
@@ -153,16 +153,13 @@ class Connection : public sys::ConnectionInputHandler,
void addManagementObject();
const qpid::sys::SecuritySettings& getExternalSecuritySettings() const
- {
+ {
return securitySettings;
}
/** @return true if the initial connection negotiation is complete. */
bool isOpen();
- // Used by cluster during catch-up, see cluster::OutputInterceptor
- void doIoCallbacks();
-
private:
typedef boost::ptr_map<framing::ChannelId, SessionHandler> ChannelMap;
typedef std::vector<boost::shared_ptr<Queue> >::iterator queue_iterator;
@@ -204,7 +201,7 @@ class Connection : public sys::ConnectionInputHandler,
sys::ConnectionOutputHandler* next;
};
OutboundFrameTracker outboundTracker;
-
+
void sent(const framing::AMQFrame& f);
public:
diff --git a/qpid/cpp/src/qpid/broker/ConnectionHandler.cpp b/qpid/cpp/src/qpid/broker/ConnectionHandler.cpp
index 270711705e..3f97e5b9de 100644
--- a/qpid/cpp/src/qpid/broker/ConnectionHandler.cpp
+++ b/qpid/cpp/src/qpid/broker/ConnectionHandler.cpp
@@ -137,9 +137,7 @@ void ConnectionHandler::Handler::startOk(const framing::FieldTable& clientProper
throw;
}
connection.setFederationLink(clientProperties.get(QPID_FED_LINK));
- if (clientProperties.isSet(QPID_FED_TAG)) {
- connection.setFederationPeerTag(clientProperties.getAsString(QPID_FED_TAG));
- }
+ connection.setFederationPeerTag(clientProperties.getAsString(QPID_FED_TAG));
if (connection.isFederationLink()) {
if (acl && !acl->authorise(connection.getUserId(),acl::ACT_CREATE,acl::OBJ_LINK,"")){
proxy.close(framing::connection::CLOSE_CODE_CONNECTION_FORCED,"ACL denied creating a federation link");
@@ -258,6 +256,7 @@ void ConnectionHandler::Handler::start(const FieldTable& serverProperties,
false ); // disallow interaction
}
std::string supportedMechanismsList;
+ bool requestedMechanismIsSupported = false;
Array::const_iterator i;
/*
@@ -270,9 +269,11 @@ void ConnectionHandler::Handler::start(const FieldTable& serverProperties,
if (i != supportedMechanisms.begin())
supportedMechanismsList += SPACE;
supportedMechanismsList += (*i)->get<std::string>();
+ requestedMechanismIsSupported = true;
}
}
else {
+ requestedMechanismIsSupported = false;
/*
The caller has requested a mechanism. If it's available,
make sure it ends up at the head of the list.
@@ -281,6 +282,7 @@ void ConnectionHandler::Handler::start(const FieldTable& serverProperties,
string currentMechanism = (*i)->get<std::string>();
if ( requestedMechanism == currentMechanism ) {
+ requestedMechanismIsSupported = true;
supportedMechanismsList = currentMechanism + SPACE + supportedMechanismsList;
} else {
if (i != supportedMechanisms.begin())
@@ -290,9 +292,7 @@ void ConnectionHandler::Handler::start(const FieldTable& serverProperties,
}
}
- if (serverProperties.isSet(QPID_FED_TAG)) {
- connection.setFederationPeerTag(serverProperties.getAsString(QPID_FED_TAG));
- }
+ connection.setFederationPeerTag(serverProperties.getAsString(QPID_FED_TAG));
FieldTable ft;
ft.setInt(QPID_FED_LINK,1);
diff --git a/qpid/cpp/src/qpid/broker/ConnectionState.h b/qpid/cpp/src/qpid/broker/ConnectionState.h
index fdd3c4ddc0..774c37408d 100644
--- a/qpid/cpp/src/qpid/broker/ConnectionState.h
+++ b/qpid/cpp/src/qpid/broker/ConnectionState.h
@@ -46,7 +46,6 @@ class ConnectionState : public ConnectionToken, public management::Manageable
framemax(65535),
heartbeat(0),
heartbeatmax(120),
- userProxyAuth(false), // Can proxy msgs with non-matching auth ids when true (used by federation links & clustering)
federationLink(true),
clientSupportsThrottling(false),
clusterOrderOut(0)
@@ -68,10 +67,8 @@ class ConnectionState : public ConnectionToken, public management::Manageable
void setUrl(const std::string& _url) { url = _url; }
const std::string& getUrl() const { return url; }
- void setUserProxyAuth(const bool b) { userProxyAuth = b; }
- bool isUserProxyAuth() const { return userProxyAuth || federationPeerTag.size() > 0; } // links can proxy msgs with non-matching auth ids
- void setFederationLink(bool b) { federationLink = b; } // deprecated - use setFederationPeerTag() instead
- bool isFederationLink() const { return federationPeerTag.size() > 0; }
+ void setFederationLink(bool b) { federationLink = b; }
+ bool isFederationLink() const { return federationLink; }
void setFederationPeerTag(const std::string& tag) { federationPeerTag = std::string(tag); }
const std::string& getFederationPeerTag() const { return federationPeerTag; }
std::vector<Url>& getKnownHosts() { return knownHosts; }
@@ -82,6 +79,7 @@ class ConnectionState : public ConnectionToken, public management::Manageable
Broker& getBroker() { return broker; }
Broker& broker;
+ std::vector<boost::shared_ptr<Queue> > exclusiveQueues;
//contained output tasks
sys::AggregateOutput outputTasks;
@@ -108,7 +106,6 @@ class ConnectionState : public ConnectionToken, public management::Manageable
uint16_t heartbeatmax;
std::string userId;
std::string url;
- bool userProxyAuth;
bool federationLink;
std::string federationPeerTag;
std::vector<Url> knownHosts;
diff --git a/qpid/cpp/src/qpid/broker/Consumer.h b/qpid/cpp/src/qpid/broker/Consumer.h
index 317338a8ad..b96443fa7c 100644
--- a/qpid/cpp/src/qpid/broker/Consumer.h
+++ b/qpid/cpp/src/qpid/broker/Consumer.h
@@ -29,19 +29,15 @@ namespace qpid {
namespace broker {
class Queue;
-class QueueListeners;
class Consumer {
const bool acquires;
- // inListeners allows QueueListeners to efficiently track if this instance is registered
- // for notifications without having to search its containers
- bool inListeners;
public:
typedef boost::shared_ptr<Consumer> shared_ptr;
framing::SequenceNumber position;
- Consumer(bool preAcquires = true) : acquires(preAcquires), inListeners(false) {}
+ Consumer(bool preAcquires = true) : acquires(preAcquires) {}
bool preAcquires() const { return acquires; }
virtual bool deliver(QueuedMessage& msg) = 0;
virtual void notify() = 0;
@@ -49,7 +45,6 @@ class Consumer {
virtual bool accept(boost::intrusive_ptr<Message>) { return true; }
virtual OwnershipToken* getSession() = 0;
virtual ~Consumer(){}
- friend class QueueListeners;
};
}}
diff --git a/qpid/cpp/src/qpid/broker/Daemon.cpp b/qpid/cpp/src/qpid/broker/Daemon.cpp
index c36538beb7..b30e5f18cb 100644
--- a/qpid/cpp/src/qpid/broker/Daemon.cpp
+++ b/qpid/cpp/src/qpid/broker/Daemon.cpp
@@ -93,10 +93,11 @@ void Daemon::fork()
catch (const exception& e) {
QPID_LOG(critical, "Unexpected error: " << e.what());
uint16_t port = 0;
- (void) write(pipeFds[1], &port, sizeof(uint16_t));
+ int unused_ret; //Supress warning about ignoring return value.
+ unused_ret = write(pipeFds[1], &port, sizeof(uint16_t));
std::string pipeFailureMessage = e.what();
- (void) write ( pipeFds[1],
+ unused_ret = write ( pipeFds[1],
pipeFailureMessage.c_str(),
strlen(pipeFailureMessage.c_str())
);
diff --git a/qpid/cpp/src/qpid/broker/DeliverableMessage.h b/qpid/cpp/src/qpid/broker/DeliverableMessage.h
index c8d21001eb..ce613e7b6e 100644
--- a/qpid/cpp/src/qpid/broker/DeliverableMessage.h
+++ b/qpid/cpp/src/qpid/broker/DeliverableMessage.h
@@ -29,7 +29,7 @@
namespace qpid {
namespace broker {
- class QPID_BROKER_CLASS_EXTERN DeliverableMessage : public Deliverable{
+ class DeliverableMessage : public Deliverable{
boost::intrusive_ptr<Message> msg;
public:
QPID_BROKER_EXTERN DeliverableMessage(const boost::intrusive_ptr<Message>& msg);
diff --git a/qpid/cpp/src/qpid/broker/DeliveryRecord.cpp b/qpid/cpp/src/qpid/broker/DeliveryRecord.cpp
index 11970db394..64760bea36 100644
--- a/qpid/cpp/src/qpid/broker/DeliveryRecord.cpp
+++ b/qpid/cpp/src/qpid/broker/DeliveryRecord.cpp
@@ -75,7 +75,7 @@ void DeliveryRecord::deliver(framing::FrameHandler& h, DeliveryId deliveryId, ui
{
id = deliveryId;
if (msg.payload->getRedelivered()){
- msg.payload->setRedelivered();
+ msg.payload->getProperties<framing::DeliveryProperties>()->setRedelivered(true);
}
msg.payload->adjustTtl();
@@ -135,7 +135,7 @@ void DeliveryRecord::reject()
Exchange::shared_ptr alternate = queue->getAlternateExchange();
if (alternate) {
DeliverableMessage delivery(msg.payload);
- alternate->routeWithAlternate(delivery);
+ alternate->route(delivery, msg.payload->getRoutingKey(), msg.payload->getApplicationHeaders());
QPID_LOG(info, "Routed rejected message from " << queue->getName() << " to "
<< alternate->getName());
} else {
diff --git a/qpid/cpp/src/qpid/broker/DirectExchange.cpp b/qpid/cpp/src/qpid/broker/DirectExchange.cpp
index 060f80f60d..5b8104c77c 100644
--- a/qpid/cpp/src/qpid/broker/DirectExchange.cpp
+++ b/qpid/cpp/src/qpid/broker/DirectExchange.cpp
@@ -94,7 +94,7 @@ bool DirectExchange::bind(Queue::shared_ptr queue, const string& routingKey, con
propagate = bk.fedBinding.delOrigin(queue->getName(), fedOrigin);
if (bk.fedBinding.countFedBindings(queue->getName()) == 0)
- unbind(queue, routingKey, args);
+ unbind(queue, routingKey, 0);
} else if (fedOp == fedOpReorigin) {
/** gather up all the keys that need rebinding in a local vector
@@ -124,18 +124,17 @@ bool DirectExchange::bind(Queue::shared_ptr queue, const string& routingKey, con
return true;
}
-bool DirectExchange::unbind(Queue::shared_ptr queue, const string& routingKey, const FieldTable* args)
+bool DirectExchange::unbind(Queue::shared_ptr queue, const string& routingKey, const FieldTable* /*args*/)
{
- string fedOrigin(args ? args->getAsString(qpidFedOrigin) : "");
bool propagate = false;
- QPID_LOG(debug, "Unbinding key [" << routingKey << "] from queue " << queue->getName()
- << " on exchange " << getName() << " origin=" << fedOrigin << ")" );
+ QPID_LOG(debug, "Unbind key [" << routingKey << "] from queue " << queue->getName());
+
{
Mutex::ScopedLock l(lock);
BoundKey& bk = bindings[routingKey];
if (bk.queues.remove_if(MatchQueue(queue))) {
- propagate = bk.fedBinding.delOrigin(queue->getName(), fedOrigin);
+ propagate = bk.fedBinding.delOrigin();
if (mgmtExchange != 0) {
mgmtExchange->dec_bindingCount();
}
diff --git a/qpid/cpp/src/qpid/broker/Exchange.cpp b/qpid/cpp/src/qpid/broker/Exchange.cpp
index d68845062d..d143471559 100644
--- a/qpid/cpp/src/qpid/broker/Exchange.cpp
+++ b/qpid/cpp/src/qpid/broker/Exchange.cpp
@@ -19,18 +19,16 @@
*
*/
-#include "qpid/broker/Broker.h"
-#include "qpid/broker/DeliverableMessage.h"
#include "qpid/broker/Exchange.h"
#include "qpid/broker/ExchangeRegistry.h"
#include "qpid/broker/FedOps.h"
+#include "qpid/broker/Broker.h"
+#include "qpid/management/ManagementAgent.h"
#include "qpid/broker/Queue.h"
+#include "qpid/log/Statement.h"
#include "qpid/framing/MessageProperties.h"
#include "qpid/framing/reply_exceptions.h"
-#include "qpid/log/Statement.h"
-#include "qpid/management/ManagementAgent.h"
-#include "qpid/sys/ExceptionHolder.h"
-#include <stdexcept>
+#include "qpid/broker/DeliverableMessage.h"
using namespace qpid::broker;
using namespace qpid::framing;
@@ -58,7 +56,7 @@ Exchange::PreRoute::PreRoute(Deliverable& msg, Exchange* _p):parent(_p) {
if (parent->sequence){
parent->sequenceNo++;
- msg.getMessage().insertCustomProperty(qpidMsgSequence,parent->sequenceNo);
+ msg.getMessage().getProperties<MessageProperties>()->getApplicationHeaders().setInt64(qpidMsgSequence,parent->sequenceNo);
}
if (parent->ive) {
parent->lastMsg = &( msg.getMessage());
@@ -72,36 +70,6 @@ Exchange::PreRoute::~PreRoute(){
}
}
-namespace {
-/** Store information about an exception to be thrown later.
- * If multiple exceptions are stored, save the first of the "most severe"
- * exceptions, SESSION is les sever than CONNECTION etc.
- */
-class ExInfo {
- public:
- enum Type { NONE, SESSION, CONNECTION, OTHER };
-
- ExInfo(string exchange) : type(NONE), exchange(exchange) {}
- void store(Type type_, const qpid::sys::ExceptionHolder& exception_, const boost::shared_ptr<Queue>& queue) {
- QPID_LOG(warning, "Exchange " << exchange << " cannot deliver to queue "
- << queue->getName() << ": " << exception_.what());
- if (type < type_) { // Replace less severe exception
- type = type_;
- exception = exception_;
- }
- }
-
- void raise() {
- exception.raise();
- }
-
- private:
- Type type;
- string exchange;
- qpid::sys::ExceptionHolder exception;
-};
-}
-
void Exchange::doRoute(Deliverable& msg, ConstBindingList b)
{
int count = 0;
@@ -112,25 +80,11 @@ void Exchange::doRoute(Deliverable& msg, ConstBindingList b)
msg.getMessage().blockContentRelease();
}
-
- ExInfo error(getName()); // Save exception to throw at the end.
for(std::vector<Binding::shared_ptr>::const_iterator i = b->begin(); i != b->end(); i++, count++) {
- try {
- msg.deliverTo((*i)->queue);
- if ((*i)->mgmtBinding != 0)
- (*i)->mgmtBinding->inc_msgMatched();
- }
- catch (const SessionException& e) {
- error.store(ExInfo::SESSION, framing::createSessionException(e.code, e.what()),(*i)->queue);
- }
- catch (const ConnectionException& e) {
- error.store(ExInfo::CONNECTION, framing::createConnectionException(e.code, e.what()), (*i)->queue);
- }
- catch (const std::exception& e) {
- error.store(ExInfo::OTHER, qpid::sys::ExceptionHolder(new Exception(e.what())), (*i)->queue);
- }
+ msg.deliverTo((*i)->queue);
+ if ((*i)->mgmtBinding != 0)
+ (*i)->mgmtBinding->inc_msgMatched();
}
- error.raise();
}
if (mgmtExchange != 0)
@@ -161,7 +115,7 @@ void Exchange::routeIVE(){
Exchange::Exchange (const string& _name, Manageable* parent, Broker* b) :
name(_name), durable(false), persistenceId(0), sequence(false),
- sequenceNo(0), ive(false), mgmtExchange(0), broker(b), destroyed(false)
+ sequenceNo(0), ive(false), mgmtExchange(0), broker(b)
{
if (parent != 0 && broker != 0)
{
@@ -179,7 +133,7 @@ Exchange::Exchange (const string& _name, Manageable* parent, Broker* b) :
Exchange::Exchange(const string& _name, bool _durable, const qpid::framing::FieldTable& _args,
Manageable* parent, Broker* b)
: name(_name), durable(_durable), alternateUsers(0), persistenceId(0),
- args(_args), sequence(false), sequenceNo(0), ive(false), mgmtExchange(0), broker(b), destroyed(false)
+ args(_args), sequence(false), sequenceNo(0), ive(false), mgmtExchange(0), broker(b)
{
if (parent != 0 && broker != 0)
{
@@ -201,11 +155,7 @@ Exchange::Exchange(const string& _name, bool _durable, const qpid::framing::Fiel
}
ive = _args.get(qpidIVE);
- if (ive) {
- if (broker && broker->isInCluster())
- throw framing::NotImplementedException("Cannot use Initial Value Exchanges in a cluster");
- QPID_LOG(debug, "Configured exchange " << _name << " with Initial Value");
- }
+ if (ive) QPID_LOG(debug, "Configured exchange " << _name << " with Initial Value");
}
Exchange::~Exchange ()
@@ -390,14 +340,5 @@ bool Exchange::MatchQueue::operator()(Exchange::Binding::shared_ptr b)
}
void Exchange::setProperties(const boost::intrusive_ptr<Message>& msg) {
- msg->setExchange(getName());
-}
-
-bool Exchange::routeWithAlternate(Deliverable& msg)
-{
- route(msg, msg.getMessage().getRoutingKey(), msg.getMessage().getApplicationHeaders());
- if (!msg.delivered && alternate) {
- alternate->route(msg, msg.getMessage().getRoutingKey(), msg.getMessage().getApplicationHeaders());
- }
- return msg.delivered;
+ msg->getProperties<DeliveryProperties>()->setExchange(getName());
}
diff --git a/qpid/cpp/src/qpid/broker/Exchange.h b/qpid/cpp/src/qpid/broker/Exchange.h
index b12af9a1dd..3c8b5ca2cd 100644
--- a/qpid/cpp/src/qpid/broker/Exchange.h
+++ b/qpid/cpp/src/qpid/broker/Exchange.h
@@ -10,9 +10,9 @@
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
@@ -39,7 +39,7 @@ namespace broker {
class Broker;
class ExchangeRegistry;
-class QPID_BROKER_CLASS_EXTERN Exchange : public PersistableExchange, public management::Manageable {
+class Exchange : public PersistableExchange, public management::Manageable {
public:
struct Binding : public management::Manageable {
typedef boost::shared_ptr<Binding> shared_ptr;
@@ -82,15 +82,15 @@ protected:
private:
Exchange* parent;
};
-
+
typedef boost::shared_ptr<const std::vector<boost::shared_ptr<qpid::broker::Exchange::Binding> > > ConstBindingList;
typedef boost::shared_ptr< std::vector<boost::shared_ptr<qpid::broker::Exchange::Binding> > > BindingList;
void doRoute(Deliverable& msg, ConstBindingList b);
void routeIVE();
-
+
struct MatchQueue {
- const boost::shared_ptr<Queue> queue;
+ const boost::shared_ptr<Queue> queue;
MatchQueue(boost::shared_ptr<Queue> q);
bool operator()(Exchange::Binding::shared_ptr b);
};
@@ -133,15 +133,15 @@ protected:
/** Returns true if propagation is needed. */
bool delOrigin(const std::string& queueName, const std::string& origin){
- if (origin.empty()) { // no remote == local binding
- if (localBindings > 0)
- localBindings--;
- return localBindings == 0;
- }
- size_t match = fedBindings[queueName].erase(origin);
- if (fedBindings[queueName].empty())
- fedBindings.erase(queueName);
- return match != 0;
+ fedBindings[queueName].erase(origin);
+ return true;
+ }
+
+ /** Returns true if propagation is needed. */
+ bool delOrigin() {
+ if (localBindings > 0)
+ localBindings--;
+ return localBindings == 0;
}
uint32_t count() {
@@ -149,11 +149,7 @@ protected:
}
uint32_t countFedBindings(const std::string& queueName) {
- // don't use '[]' - it may increase size of fedBindings!
- std::map<std::string, originSet>::iterator i;
- if ((i = fedBindings.find(queueName)) != fedBindings.end())
- return i->second.size();
- return 0;
+ return fedBindings[queueName].size();
}
};
@@ -166,7 +162,7 @@ public:
Broker* broker = 0);
QPID_BROKER_EXTERN Exchange(const std::string& _name, bool _durable, const qpid::framing::FieldTable& _args,
management::Manageable* parent = 0, Broker* broker = 0);
- QPID_BROKER_INLINE_EXTERN virtual ~Exchange();
+ QPID_BROKER_EXTERN virtual ~Exchange();
const std::string& getName() const { return name; }
bool isDurable() { return durable; }
@@ -195,7 +191,7 @@ public:
virtual bool isBound(boost::shared_ptr<Queue> queue, const std::string* const routingKey, const qpid::framing::FieldTable* const args) = 0;
QPID_BROKER_EXTERN virtual void setProperties(const boost::intrusive_ptr<Message>&);
virtual void route(Deliverable& msg, const std::string& routingKey, const qpid::framing::FieldTable* args) = 0;
-
+
//PersistableExchange:
QPID_BROKER_EXTERN void setPersistenceId(uint64_t id) const;
uint64_t getPersistenceId() const { return persistenceId; }
@@ -226,20 +222,14 @@ public:
*/
void recoveryComplete(ExchangeRegistry& exchanges);
- bool routeWithAlternate(Deliverable& message);
-
- void destroy() { destroyed = true; }
- bool isDestroyed() const { return destroyed; }
-
protected:
qpid::sys::Mutex bridgeLock;
std::vector<DynamicBridge*> bridgeVector;
Broker* broker;
- bool destroyed;
QPID_BROKER_EXTERN virtual void handleHelloRequest();
void propagateFedOp(const std::string& routingKey, const std::string& tags,
- const std::string& op, const std::string& origin,
+ const std::string& op, const std::string& origin,
qpid::framing::FieldTable* extra_args=0);
};
diff --git a/qpid/cpp/src/qpid/broker/ExchangeRegistry.cpp b/qpid/cpp/src/qpid/broker/ExchangeRegistry.cpp
index 1c8d26c4f7..99b121cbce 100644
--- a/qpid/cpp/src/qpid/broker/ExchangeRegistry.cpp
+++ b/qpid/cpp/src/qpid/broker/ExchangeRegistry.cpp
@@ -7,9 +7,9 @@
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
@@ -39,7 +39,7 @@ pair<Exchange::shared_ptr, bool> ExchangeRegistry::declare(const string& name, c
return declare(name, type, false, FieldTable());
}
-pair<Exchange::shared_ptr, bool> ExchangeRegistry::declare(const string& name, const string& type,
+pair<Exchange::shared_ptr, bool> ExchangeRegistry::declare(const string& name, const string& type,
bool durable, const FieldTable& args){
RWlock::ScopedWlock locker(lock);
ExchangeMap::iterator i = exchanges.find(name);
@@ -61,7 +61,7 @@ pair<Exchange::shared_ptr, bool> ExchangeRegistry::declare(const string& name, c
}else{
FunctionMap::iterator i = factory.find(type);
if (i == factory.end()) {
- throw UnknownExchangeTypeException();
+ throw UnknownExchangeTypeException();
} else {
exchange = i->second(name, durable, args, parent, broker);
}
@@ -82,7 +82,6 @@ void ExchangeRegistry::destroy(const string& name){
RWlock::ScopedWlock locker(lock);
ExchangeMap::iterator i = exchanges.find(name);
if (i != exchanges.end()) {
- i->second->destroy();
exchanges.erase(i);
}
}
@@ -105,7 +104,7 @@ void ExchangeRegistry::registerType(const std::string& type, FactoryFunction f)
}
-namespace
+namespace
{
const std::string empty;
}
diff --git a/qpid/cpp/src/qpid/broker/ExpiryPolicy.cpp b/qpid/cpp/src/qpid/broker/ExpiryPolicy.cpp
index 62cb3fc116..64a12d918a 100644
--- a/qpid/cpp/src/qpid/broker/ExpiryPolicy.cpp
+++ b/qpid/cpp/src/qpid/broker/ExpiryPolicy.cpp
@@ -7,9 +7,9 @@
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
@@ -27,12 +27,12 @@ namespace broker {
ExpiryPolicy::~ExpiryPolicy() {}
+void ExpiryPolicy::willExpire(Message&) {}
+
bool ExpiryPolicy::hasExpired(Message& m) {
return m.getExpiration() < sys::AbsTime::now();
}
-sys::AbsTime ExpiryPolicy::getCurrentTime() {
- return sys::AbsTime::now();
-}
+void ExpiryPolicy::forget(Message&) {}
}} // namespace qpid::broker
diff --git a/qpid/cpp/src/qpid/broker/ExpiryPolicy.h b/qpid/cpp/src/qpid/broker/ExpiryPolicy.h
index 2caf00ce00..40e793bf2c 100644
--- a/qpid/cpp/src/qpid/broker/ExpiryPolicy.h
+++ b/qpid/cpp/src/qpid/broker/ExpiryPolicy.h
@@ -10,9 +10,9 @@
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
@@ -26,11 +26,6 @@
#include "qpid/broker/BrokerImportExport.h"
namespace qpid {
-
-namespace sys {
-class AbsTime;
-}
-
namespace broker {
class Message;
@@ -38,12 +33,13 @@ class Message;
/**
* Default expiry policy.
*/
-class QPID_BROKER_CLASS_EXTERN ExpiryPolicy : public RefCounted
+class ExpiryPolicy : public RefCounted
{
public:
QPID_BROKER_EXTERN virtual ~ExpiryPolicy();
+ QPID_BROKER_EXTERN virtual void willExpire(Message&);
QPID_BROKER_EXTERN virtual bool hasExpired(Message&);
- QPID_BROKER_EXTERN virtual qpid::sys::AbsTime getCurrentTime();
+ QPID_BROKER_EXTERN virtual void forget(Message&);
};
}} // namespace qpid::broker
diff --git a/qpid/cpp/src/qpid/broker/Fairshare.cpp b/qpid/cpp/src/qpid/broker/Fairshare.cpp
index 17270ffd8d..e6bbf86691 100644
--- a/qpid/cpp/src/qpid/broker/Fairshare.cpp
+++ b/qpid/cpp/src/qpid/broker/Fairshare.cpp
@@ -24,7 +24,6 @@
#include "qpid/log/Statement.h"
#include <boost/format.hpp>
#include <boost/lexical_cast.hpp>
-#include <boost/assign/list_of.hpp>
namespace qpid {
namespace broker {
@@ -105,80 +104,51 @@ bool Fairshare::setState(Messages& m, uint priority, uint count)
return fairshare && fairshare->setState(priority, count);
}
-int getIntegerSetting(const qpid::framing::FieldTable& settings, const std::vector<std::string>& keys)
+int getIntegerSetting(const qpid::framing::FieldTable& settings, const std::string& key)
{
- qpid::framing::FieldTable::ValuePtr v;
- std::vector<std::string>::const_iterator i = keys.begin();
- while (!v && i != keys.end()) {
- v = settings.get(*i++);
- }
-
+ qpid::framing::FieldTable::ValuePtr v = settings.get(key);
if (!v) {
return 0;
} else if (v->convertsTo<int>()) {
return v->get<int>();
} else if (v->convertsTo<std::string>()){
std::string s = v->get<std::string>();
- try {
- return boost::lexical_cast<int>(s);
+ try {
+ return boost::lexical_cast<int>(s);
} catch(const boost::bad_lexical_cast&) {
- QPID_LOG(warning, "Ignoring invalid integer value for " << *i << ": " << s);
+ QPID_LOG(warning, "Ignoring invalid integer value for " << key << ": " << s);
return 0;
}
} else {
- QPID_LOG(warning, "Ignoring invalid integer value for " << *i << ": " << *v);
+ QPID_LOG(warning, "Ignoring invalid integer value for " << key << ": " << *v);
return 0;
}
}
-int getIntegerSettingForKey(const qpid::framing::FieldTable& settings, const std::string& key)
-{
- return getIntegerSetting(settings, boost::assign::list_of<std::string>(key));
-}
-
-int getSetting(const qpid::framing::FieldTable& settings, const std::vector<std::string>& keys, int minvalue, int maxvalue)
-{
- return std::max(minvalue,std::min(getIntegerSetting(settings, keys), maxvalue));
-}
-
-std::auto_ptr<Fairshare> getFairshareForKey(const qpid::framing::FieldTable& settings, uint levels, const std::string& key)
-{
- uint defaultLimit = getIntegerSettingForKey(settings, key);
- std::auto_ptr<Fairshare> fairshare(new Fairshare(levels, defaultLimit));
- for (uint i = 0; i < levels; i++) {
- std::string levelKey = (boost::format("%1%-%2%") % key % i).str();
- if(settings.isSet(levelKey)) {
- fairshare->setLimit(i, getIntegerSettingForKey(settings, levelKey));
- }
- }
- if (!fairshare->isNull()) {
- return fairshare;
- } else {
- return std::auto_ptr<Fairshare>();
- }
-}
-
-std::auto_ptr<Fairshare> getFairshare(const qpid::framing::FieldTable& settings,
- uint levels,
- const std::vector<std::string>& keys)
+int getSetting(const qpid::framing::FieldTable& settings, const std::string& key, int minvalue, int maxvalue)
{
- std::auto_ptr<Fairshare> fairshare;
- for (std::vector<std::string>::const_iterator i = keys.begin(); i != keys.end() && !fairshare.get(); ++i) {
- fairshare = getFairshareForKey(settings, levels, *i);
- }
- return fairshare;
+ return std::max(minvalue,std::min(getIntegerSetting(settings, key), maxvalue));
}
std::auto_ptr<Messages> Fairshare::create(const qpid::framing::FieldTable& settings)
{
- using boost::assign::list_of;
std::auto_ptr<Messages> result;
- size_t levels = getSetting(settings, list_of<std::string>("qpid.priorities")("x-qpid-priorities"), 1, 100);
+ size_t levels = getSetting(settings, "x-qpid-priorities", 1, 100);
if (levels) {
- std::auto_ptr<Fairshare> fairshare =
- getFairshare(settings, levels, list_of<std::string>("qpid.fairshare")("x-qpid-fairshare"));
- if (fairshare.get()) result = fairshare;
- else result = std::auto_ptr<Messages>(new PriorityQueue(levels));
+ uint defaultLimit = getIntegerSetting(settings, "x-qpid-fairshare");
+ std::auto_ptr<Fairshare> fairshare(new Fairshare(levels, defaultLimit));
+ for (uint i = 0; i < levels; i++) {
+ std::string key = (boost::format("x-qpid-fairshare-%1%") % i).str();
+ if(settings.isSet(key)) {
+ fairshare->setLimit(i, getIntegerSetting(settings, key));
+ }
+ }
+
+ if (fairshare->isNull()) {
+ result = std::auto_ptr<Messages>(new PriorityQueue(levels));
+ } else {
+ result = fairshare;
+ }
}
return result;
}
diff --git a/qpid/cpp/src/qpid/broker/Fairshare.h b/qpid/cpp/src/qpid/broker/Fairshare.h
index 1b25721e0c..6c4b87f857 100644
--- a/qpid/cpp/src/qpid/broker/Fairshare.h
+++ b/qpid/cpp/src/qpid/broker/Fairshare.h
@@ -41,18 +41,18 @@ class Fairshare : public PriorityQueue
bool getState(uint& priority, uint& count) const;
bool setState(uint priority, uint count);
void setLimit(size_t level, uint limit);
- bool isNull();
static std::auto_ptr<Messages> create(const qpid::framing::FieldTable& settings);
static bool getState(const Messages&, uint& priority, uint& count);
static bool setState(Messages&, uint priority, uint count);
private:
std::vector<uint> limits;
-
+
uint priority;
uint count;
-
+
uint currentLevel();
uint nextLevel();
+ bool isNull();
bool limitReached();
bool findFrontLevel(uint& p, PriorityLevels&);
};
diff --git a/qpid/cpp/src/qpid/broker/FanOutExchange.cpp b/qpid/cpp/src/qpid/broker/FanOutExchange.cpp
index 5879fa0892..ac2c914a97 100644
--- a/qpid/cpp/src/qpid/broker/FanOutExchange.cpp
+++ b/qpid/cpp/src/qpid/broker/FanOutExchange.cpp
@@ -18,7 +18,6 @@
* under the License.
*
*/
-#include "qpid/log/Statement.h"
#include "qpid/broker/FanOutExchange.h"
#include "qpid/broker/FedOps.h"
#include <algorithm>
@@ -66,7 +65,7 @@ bool FanOutExchange::bind(Queue::shared_ptr queue, const string& /*key*/, const
} else if (fedOp == fedOpUnbind) {
propagate = fedBinding.delOrigin(queue->getName(), fedOrigin);
if (fedBinding.countFedBindings(queue->getName()) == 0)
- unbind(queue, "", args);
+ unbind(queue, "", 0);
} else if (fedOp == fedOpReorigin) {
if (fedBinding.hasLocal()) {
propagateFedOp(string(), string(), fedOpBind, string());
@@ -79,16 +78,12 @@ bool FanOutExchange::bind(Queue::shared_ptr queue, const string& /*key*/, const
return true;
}
-bool FanOutExchange::unbind(Queue::shared_ptr queue, const string& /*key*/, const FieldTable* args)
+bool FanOutExchange::unbind(Queue::shared_ptr queue, const string& /*key*/, const FieldTable* /*args*/)
{
- string fedOrigin(args ? args->getAsString(qpidFedOrigin) : "");
bool propagate = false;
- QPID_LOG(debug, "Unbinding queue " << queue->getName()
- << " from exchange " << getName() << " origin=" << fedOrigin << ")" );
-
if (bindings.remove_if(MatchQueue(queue))) {
- propagate = fedBinding.delOrigin(queue->getName(), fedOrigin);
+ propagate = fedBinding.delOrigin();
if (mgmtExchange != 0) {
mgmtExchange->dec_bindingCount();
}
diff --git a/qpid/cpp/src/qpid/broker/HeadersExchange.cpp b/qpid/cpp/src/qpid/broker/HeadersExchange.cpp
index 4bda70d313..82ac5911ee 100644
--- a/qpid/cpp/src/qpid/broker/HeadersExchange.cpp
+++ b/qpid/cpp/src/qpid/broker/HeadersExchange.cpp
@@ -112,14 +112,9 @@ bool HeadersExchange::bind(Queue::shared_ptr queue, const string& bindingKey, co
{
Mutex::ScopedLock l(lock);
- //NOTE: do not include the fed op/tags/origin in the
- //arguments as when x-match is 'all' these would prevent
- //matching (they are internally added properties
- //controlling binding propagation but not relevant to
- //actual routing)
- Binding::shared_ptr binding (new Binding (bindingKey, queue, this, extra_args));
+ Binding::shared_ptr binding (new Binding (bindingKey, queue, this, *args));
BoundKey bk(binding);
- if (bindings.add_unless(bk, MatchArgs(queue, &extra_args))) {
+ if (bindings.add_unless(bk, MatchArgs(queue, args))) {
binding->startManagement();
propagate = bk.fedBinding.addOrigin(queue->getName(), fedOrigin);
if (mgmtExchange != 0) {
@@ -163,13 +158,12 @@ bool HeadersExchange::bind(Queue::shared_ptr queue, const string& bindingKey, co
return true;
}
-bool HeadersExchange::unbind(Queue::shared_ptr queue, const string& bindingKey, const FieldTable *args){
+bool HeadersExchange::unbind(Queue::shared_ptr queue, const string& bindingKey, const FieldTable*){
bool propagate = false;
- string fedOrigin(args ? args->getAsString(qpidFedOrigin) : "");
{
Mutex::ScopedLock l(lock);
- FedUnbindModifier modifier(queue->getName(), fedOrigin);
+ FedUnbindModifier modifier;
MatchKey match_key(queue, bindingKey);
bindings.modify_if(match_key, modifier);
propagate = modifier.shouldPropagate;
@@ -336,7 +330,11 @@ HeadersExchange::FedUnbindModifier::FedUnbindModifier() : shouldUnbind(false), s
bool HeadersExchange::FedUnbindModifier::operator()(BoundKey & bk)
{
- shouldPropagate = bk.fedBinding.delOrigin(queueName, fedOrigin);
+ if ("" == fedOrigin) {
+ shouldPropagate = bk.fedBinding.delOrigin();
+ } else {
+ shouldPropagate = bk.fedBinding.delOrigin(queueName, fedOrigin);
+ }
if (bk.fedBinding.countFedBindings(queueName) == 0)
{
shouldUnbind = true;
diff --git a/qpid/cpp/src/qpid/broker/LegacyLVQ.cpp b/qpid/cpp/src/qpid/broker/LegacyLVQ.cpp
index 3262e343a3..a811a86492 100644
--- a/qpid/cpp/src/qpid/broker/LegacyLVQ.cpp
+++ b/qpid/cpp/src/qpid/broker/LegacyLVQ.cpp
@@ -93,7 +93,11 @@ void LegacyLVQ::removeIf(Predicate p)
//purging of an LVQ is not enabled if the broker is clustered
//(expired messages will be removed on delivery and consolidated
//by key as part of normal LVQ operation).
- if (!broker || !broker->isInCluster())
+
+ //TODO: Is there a neater way to check whether broker is
+ //clustered? Here we assume that if the clustered timer is the
+ //same as the regular timer, we are not clustered:
+ if (!broker || &(broker->getClusterTimer()) == &(broker->getTimer()))
MessageMap::removeIf(p);
}
diff --git a/qpid/cpp/src/qpid/broker/Link.cpp b/qpid/cpp/src/qpid/broker/Link.cpp
index 8010bf43e7..f3acf7c660 100644
--- a/qpid/cpp/src/qpid/broker/Link.cpp
+++ b/qpid/cpp/src/qpid/broker/Link.cpp
@@ -7,9 +7,9 @@
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
@@ -30,6 +30,7 @@
#include "qpid/framing/enum.h"
#include "qpid/framing/reply_exceptions.h"
#include "qpid/broker/AclModule.h"
+#include "qpid/sys/ClusterSafe.h"
using namespace qpid::broker;
using qpid::framing::Buffer;
@@ -56,8 +57,8 @@ Link::Link(LinkRegistry* _links,
string& _password,
Broker* _broker,
Manageable* parent)
- : links(_links), store(_store), host(_host), port(_port),
- transport(_transport),
+ : links(_links), store(_store), host(_host), port(_port),
+ transport(_transport),
durable(_durable),
authMechanism(_authMechanism), username(_username), password(_password),
persistenceId(0), mgmtObject(0), broker(_broker), state(0),
@@ -96,8 +97,7 @@ void Link::setStateLH (int newState)
return;
state = newState;
-
- if (hideManagement())
+ if (mgmtObject == 0)
return;
switch (state)
@@ -117,12 +117,12 @@ void Link::startConnectionLH ()
// Set the state before calling connect. It is possible that connect
// will fail synchronously and call Link::closed before returning.
setStateLH(STATE_CONNECTING);
- broker->connect (host, boost::lexical_cast<std::string>(port), transport,
+ broker->connect (host, port, transport,
boost::bind (&Link::closed, this, _1, _2));
QPID_LOG (debug, "Inter-broker link connecting to " << host << ":" << port);
} catch(std::exception& e) {
setStateLH(STATE_WAITING);
- if (!hideManagement())
+ if (mgmtObject != 0)
mgmtObject->set_lastError (e.what());
}
}
@@ -133,7 +133,8 @@ void Link::established ()
addr << host << ":" << port;
QPID_LOG (info, "Inter-broker link established to " << addr.str());
- if (!hideManagement() && agent)
+ // Don't raise the management event in a cluster, other members wont't get this call.
+ if (broker && !broker->isInCluster())
agent->raiseEvent(_qmf::EventBrokerLinkUp(addr.str()));
{
@@ -153,11 +154,12 @@ void Link::closed (int, std::string text)
connection = 0;
+ // Don't raise the management event in a cluster, other members wont't get this call.
if (state == STATE_OPERATIONAL) {
stringstream addr;
addr << host << ":" << port;
QPID_LOG (warning, "Inter-broker link disconnected from " << addr.str());
- if (!hideManagement() && agent)
+ if (broker && !broker->isInCluster())
agent->raiseEvent(_qmf::EventBrokerLinkDown(addr.str()));
}
@@ -170,7 +172,7 @@ void Link::closed (int, std::string text)
if (state != STATE_FAILED)
{
setStateLH(STATE_WAITING);
- if (!hideManagement())
+ if (mgmtObject != 0)
mgmtObject->set_lastError (text);
}
@@ -219,7 +221,7 @@ 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);
@@ -248,19 +250,6 @@ void Link::ioThreadProcessing()
return;
QPID_LOG(debug, "Link::ioThreadProcessing()");
- // check for bridge session errors and recover
- if (!active.empty()) {
- Bridges::iterator removed = std::remove_if(
- active.begin(), active.end(), !boost::bind(&Bridge::isSessionReady, _1));
- for (Bridges::iterator i = removed; i != active.end(); ++i) {
- Bridge::shared_ptr bridge = *i;
- bridge->closed();
- bridge->cancel(*connection);
- created.push_back(bridge);
- }
- active.erase(removed, active.end());
- }
-
//process any pending creates and/or cancellations
if (!created.empty()) {
for (Bridges::iterator i = created.begin(); i != created.end(); ++i) {
@@ -288,9 +277,9 @@ void Link::maintenanceVisit ()
{
Mutex::ScopedLock mutex(lock);
- if (connection && updateUrls) {
+ if (connection && updateUrls) {
urls.reset(connection->getKnownHosts());
- QPID_LOG(debug, "Known hosts for peer of inter-broker link: " << urls);
+ QPID_LOG(debug, "Known hosts for peer of inter-broker link: " << urls);
updateUrls = false;
}
@@ -309,7 +298,7 @@ void Link::maintenanceVisit ()
}
}
}
- else if (state == STATE_OPERATIONAL && (!active.empty() || !created.empty() || !cancellations.empty()) && connection != 0)
+ else if (state == STATE_OPERATIONAL && (!created.empty() || !cancellations.empty()) && connection != 0)
connection->requestIOProcessing (boost::bind(&Link::ioThreadProcessing, this));
}
@@ -320,7 +309,7 @@ void Link::reconnect(const qpid::Address& a)
port = a.port;
transport = a.protocol;
startConnectionLH();
- if (!hideManagement()) {
+ if (mgmtObject != 0) {
stringstream errorString;
errorString << "Failed over to " << a;
mgmtObject->set_lastError(errorString.str());
@@ -330,7 +319,7 @@ void Link::reconnect(const qpid::Address& a)
bool Link::tryFailover()
{
Address next;
- if (urls.next(next) &&
+ if (urls.next(next) &&
(next.host != host || next.port != port || next.protocol != transport)) {
links->changeAddress(Address(transport, host, port), next);
QPID_LOG(debug, "Link failing over to " << host << ":" << port);
@@ -340,12 +329,6 @@ bool Link::tryFailover()
}
}
-// Management updates for a linke are inconsistent in a cluster, so they are
-// suppressed.
-bool Link::hideManagement() const {
- return !mgmtObject || ( broker && broker->isInCluster());
-}
-
uint Link::nextChannel()
{
Mutex::ScopedLock mutex(lock);
@@ -358,7 +341,7 @@ void Link::notifyConnectionForced(const string text)
Mutex::ScopedLock mutex(lock);
setStateLH(STATE_FAILED);
- if (!hideManagement())
+ if (mgmtObject != 0)
mgmtObject->set_lastError(text);
}
@@ -380,7 +363,7 @@ Link::shared_ptr Link::decode(LinkRegistry& links, Buffer& buffer)
string authMechanism;
string username;
string password;
-
+
buffer.getShortString(host);
port = buffer.getShort();
buffer.getShortString(transport);
@@ -392,7 +375,7 @@ Link::shared_ptr Link::decode(LinkRegistry& links, Buffer& buffer)
return links.declare(host, port, transport, durable, authMechanism, username, password).first;
}
-void Link::encode(Buffer& buffer) const
+void Link::encode(Buffer& buffer) const
{
buffer.putShortString(string("link"));
buffer.putShortString(host);
@@ -404,8 +387,8 @@ void Link::encode(Buffer& buffer) const
buffer.putShortString(password);
}
-uint32_t Link::encodedSize() const
-{
+uint32_t Link::encodedSize() const
+{
return host.size() + 1 // short-string (host)
+ 5 // short-string ("link")
+ 2 // port
diff --git a/qpid/cpp/src/qpid/broker/Link.h b/qpid/cpp/src/qpid/broker/Link.h
index 4badd8b3a1..75a680ff5d 100644
--- a/qpid/cpp/src/qpid/broker/Link.h
+++ b/qpid/cpp/src/qpid/broker/Link.h
@@ -10,9 +10,9 @@
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
@@ -85,7 +85,6 @@ namespace qpid {
void destroy(); // Called when mgmt deletes this link
void ioThreadProcessing(); // Called on connection's IO thread by request
bool tryFailover(); // Called during maintenance visit
- bool hideManagement() const;
public:
typedef boost::shared_ptr<Link> shared_ptr;
@@ -123,12 +122,12 @@ namespace qpid {
void notifyConnectionForced(const std::string text);
void setPassive(bool p);
-
+
// PersistableConfig:
void setPersistenceId(uint64_t id) const;
uint64_t getPersistenceId() const { return persistenceId; }
uint32_t encodedSize() const;
- void encode(framing::Buffer& buffer) const;
+ void encode(framing::Buffer& buffer) const;
const std::string& getName() const;
static Link::shared_ptr decode(LinkRegistry& links, framing::Buffer& buffer);
@@ -136,7 +135,6 @@ namespace qpid {
// Manageable entry points
management::ManagementObject* GetManagementObject(void) const;
management::Manageable::status_t ManagementMethod(uint32_t, management::Args&, std::string&);
-
};
}
}
diff --git a/qpid/cpp/src/qpid/broker/LinkRegistry.cpp b/qpid/cpp/src/qpid/broker/LinkRegistry.cpp
index e9885f5462..7b1c75db74 100644
--- a/qpid/cpp/src/qpid/broker/LinkRegistry.cpp
+++ b/qpid/cpp/src/qpid/broker/LinkRegistry.cpp
@@ -7,9 +7,9 @@
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
@@ -381,7 +381,7 @@ std::string LinkRegistry::createKey(const std::string& host, uint16_t port) {
return keystream.str();
}
-void LinkRegistry::setPassive(bool p)
+void LinkRegistry::setPassive(bool p)
{
Mutex::ScopedLock locker(lock);
passiveChanged = p != passive;
diff --git a/qpid/cpp/src/qpid/broker/Message.cpp b/qpid/cpp/src/qpid/broker/Message.cpp
index 992a94f92e..122c5b9c1a 100644
--- a/qpid/cpp/src/qpid/broker/Message.cpp
+++ b/qpid/cpp/src/qpid/broker/Message.cpp
@@ -7,9 +7,9 @@
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
@@ -30,7 +30,6 @@
#include "qpid/framing/SendContent.h"
#include "qpid/framing/SequenceNumber.h"
#include "qpid/framing/TypeFilter.h"
-#include "qpid/framing/reply_exceptions.h"
#include "qpid/log/Statement.h"
#include <time.h>
@@ -50,12 +49,25 @@ TransferAdapter Message::TRANSFER;
Message::Message(const framing::SequenceNumber& id) :
frames(id), persistenceId(0), redelivered(false), loaded(false),
- staged(false), forcePersistentPolicy(false), publisher(0), adapter(0),
+ staged(false), forcePersistentPolicy(false), publisher(0), adapter(0),
expiration(FAR_FUTURE), dequeueCallback(0),
- inCallback(false), requiredCredit(0), isManagementMessage(false), copyHeaderOnWrite(false)
+ inCallback(false), requiredCredit(0)
{}
-Message::~Message() {}
+Message::Message(const Message& original) :
+ PersistableMessage(), frames(original.frames), persistenceId(0), redelivered(false), loaded(false),
+ staged(false), forcePersistentPolicy(false), publisher(0), adapter(0),
+ expiration(original.expiration), dequeueCallback(0),
+ inCallback(false), requiredCredit(0)
+{
+ setExpiryPolicy(original.expiryPolicy);
+}
+
+Message::~Message()
+{
+ if (expiryPolicy)
+ expiryPolicy->forget(*this);
+}
void Message::forcePersistent()
{
@@ -75,7 +87,7 @@ std::string Message::getRoutingKey() const
return getAdapter().getRoutingKey(frames);
}
-std::string Message::getExchangeName() const
+std::string Message::getExchangeName() const
{
return getAdapter().getExchange(frames);
}
@@ -84,7 +96,7 @@ const boost::shared_ptr<Exchange> Message::getExchange(ExchangeRegistry& registr
{
if (!exchange) {
exchange = registry.get(getExchangeName());
- }
+ }
return exchange;
}
@@ -184,7 +196,7 @@ void Message::decodeContent(framing::Buffer& buffer)
} else {
//adjust header flags
MarkLastSegment f;
- frames.map_if(f, TypeFilter<HEADER_BODY>());
+ frames.map_if(f, TypeFilter<HEADER_BODY>());
}
//mark content loaded
loaded = true;
@@ -236,7 +248,7 @@ void Message::destroy()
bool Message::getContentFrame(const Queue& queue, AMQFrame& frame, uint16_t maxContentSize, uint64_t offset) const
{
intrusive_ptr<const PersistableMessage> pmsg(this);
-
+
bool done = false;
string& data = frame.castBody<AMQContentBody>()->getData();
store->loadContent(queue, pmsg, data, offset, maxContentSize);
@@ -261,7 +273,7 @@ void Message::sendContent(const Queue& queue, framing::FrameHandler& out, uint16
uint16_t maxContentSize = maxFrameSize - AMQFrame::frameOverhead();
bool morecontent = true;
for (uint64_t offset = 0; morecontent; offset += maxContentSize)
- {
+ {
AMQFrame frame((AMQContentBody()));
morecontent = getContentFrame(queue, frame, maxContentSize, offset);
out.handle(frame);
@@ -279,10 +291,7 @@ void Message::sendHeader(framing::FrameHandler& out, uint16_t /*maxFrameSize*/)
{
sys::Mutex::ScopedLock l(lock);
Relay f(out);
- frames.map_if(f, TypeFilter<HEADER_BODY>());
- //as frame (and pointer to body) has now been passed to handler,
- //subsequent modifications should use a copy
- copyHeaderOnWrite = true;
+ frames.map_if(f, TypeFilter<HEADER_BODY>());
}
// TODO aconway 2007-11-09: Obsolete, remove. Was used to cover over
@@ -312,7 +321,7 @@ bool Message::isContentLoaded() const
}
-namespace
+namespace
{
const std::string X_QPID_TRACE("x-qpid.trace");
}
@@ -337,30 +346,11 @@ bool Message::isExcluded(const std::vector<std::string>& excludes) const
return false;
}
-class CloneHeaderBody
-{
-public:
- void operator()(AMQFrame& f)
- {
- f.cloneBody();
- }
-};
-
-AMQHeaderBody* Message::getHeaderBody()
-{
- if (copyHeaderOnWrite) {
- CloneHeaderBody f;
- frames.map_if(f, TypeFilter<HEADER_BODY>());
- copyHeaderOnWrite = false;
- }
- return frames.getHeaders();
-}
-
void Message::addTraceId(const std::string& id)
{
sys::Mutex::ScopedLock l(lock);
if (isA<MessageTransferBody>()) {
- FieldTable& headers = getModifiableProperties<MessageProperties>()->getApplicationHeaders();
+ FieldTable& headers = getProperties<MessageProperties>()->getApplicationHeaders();
std::string trace = headers.getAsString(X_QPID_TRACE);
if (trace.empty()) {
headers.setString(X_QPID_TRACE, id);
@@ -368,14 +358,13 @@ void Message::addTraceId(const std::string& id)
trace += ",";
trace += id;
headers.setString(X_QPID_TRACE, trace);
- }
+ }
}
}
-void Message::setTimestamp(const boost::intrusive_ptr<ExpiryPolicy>& e)
+void Message::setTimestamp(const boost::intrusive_ptr<ExpiryPolicy>& e)
{
- sys::Mutex::ScopedLock l(lock);
- DeliveryProperties* props = getModifiableProperties<DeliveryProperties>();
+ DeliveryProperties* props = getProperties<DeliveryProperties>();
if (props->getTtl()) {
// AMQP requires setting the expiration property to be posix
// time_t in seconds. TTL is in milliseconds
@@ -384,70 +373,26 @@ void Message::setTimestamp(const boost::intrusive_ptr<ExpiryPolicy>& e)
time_t now = ::time(0);
props->setExpiration(now + (props->getTtl()/1000));
}
- if (e) {
- // Use higher resolution time for the internal expiry calculation.
- // Prevent overflow as a signed int64_t
- Duration ttl(std::min(props->getTtl() * TIME_MSEC,
- (uint64_t) std::numeric_limits<int64_t>::max()));
- expiration = AbsTime(e->getCurrentTime(), ttl);
- setExpiryPolicy(e);
- }
+ // Use higher resolution time for the internal expiry calculation.
+ expiration = AbsTime(AbsTime::now(), Duration(props->getTtl() * TIME_MSEC));
+ setExpiryPolicy(e);
}
}
void Message::adjustTtl()
{
- sys::Mutex::ScopedLock l(lock);
- DeliveryProperties* props = getModifiableProperties<DeliveryProperties>();
+ DeliveryProperties* props = getProperties<DeliveryProperties>();
if (props->getTtl()) {
- if (expiration < FAR_FUTURE) {
- sys::AbsTime current(
- expiryPolicy ? expiryPolicy->getCurrentTime() : sys::AbsTime::now());
- sys::Duration ttl(current, getExpiration());
- // convert from ns to ms; set to 1 if expired
- props->setTtl(int64_t(ttl) >= 1000000 ? int64_t(ttl)/1000000 : 1);
- }
+ sys::Mutex::ScopedLock l(lock);
+ sys::Duration d(sys::AbsTime::now(), getExpiration());
+ props->setTtl(int64_t(d) > 0 ? int64_t(d)/1000000 : 1); // convert from ns to ms; set to 1 if expired
}
}
-void Message::setRedelivered()
-{
- sys::Mutex::ScopedLock l(lock);
- getModifiableProperties<framing::DeliveryProperties>()->setRedelivered(true);
-}
-
-void Message::insertCustomProperty(const std::string& key, int64_t value)
-{
- sys::Mutex::ScopedLock l(lock);
- getModifiableProperties<MessageProperties>()->getApplicationHeaders().setInt64(key,value);
-}
-
-void Message::insertCustomProperty(const std::string& key, const std::string& value)
-{
- sys::Mutex::ScopedLock l(lock);
- getModifiableProperties<MessageProperties>()->getApplicationHeaders().setString(key,value);
-}
-
-void Message::removeCustomProperty(const std::string& key)
-{
- sys::Mutex::ScopedLock l(lock);
- getModifiableProperties<MessageProperties>()->getApplicationHeaders().erase(key);
-}
-
-void Message::setExchange(const std::string& exchange)
-{
- sys::Mutex::ScopedLock l(lock);
- getModifiableProperties<DeliveryProperties>()->setExchange(exchange);
-}
-
-void Message::clearApplicationHeadersFlag()
-{
- sys::Mutex::ScopedLock l(lock);
- getModifiableProperties<MessageProperties>()->clearApplicationHeadersFlag();
-}
-
void Message::setExpiryPolicy(const boost::intrusive_ptr<ExpiryPolicy>& e) {
expiryPolicy = e;
+ if (expiryPolicy)
+ expiryPolicy->willExpire(*this);
}
bool Message::hasExpired()
@@ -493,7 +438,9 @@ uint8_t Message::getPriority() const {
return getAdapter().getPriority(frames);
}
-bool Message::getIsManagementMessage() const { return isManagementMessage; }
-void Message::setIsManagementMessage(bool b) { isManagementMessage = b; }
+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 2a23a25d06..2d0de27823 100644
--- a/qpid/cpp/src/qpid/broker/Message.h
+++ b/qpid/cpp/src/qpid/broker/Message.h
@@ -10,9 +10,9 @@
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
@@ -29,21 +29,17 @@
#include "qpid/sys/Monitor.h"
#include "qpid/sys/Time.h"
#include <boost/function.hpp>
-#include <boost/intrusive_ptr.hpp>
#include <boost/shared_ptr.hpp>
-#include <memory>
#include <string>
#include <vector>
namespace qpid {
-
+
namespace framing {
-class AMQBody;
-class AMQHeaderBody;
class FieldTable;
class SequenceNumber;
}
-
+
namespace broker {
class ConnectionToken;
class Exchange;
@@ -55,10 +51,11 @@ class ExpiryPolicy;
class Message : public PersistableMessage {
public:
typedef boost::function<void (const boost::intrusive_ptr<Message>&)> MessageCallback;
-
+
QPID_BROKER_EXTERN Message(const framing::SequenceNumber& id = framing::SequenceNumber());
+ QPID_BROKER_EXTERN Message(const Message&);
QPID_BROKER_EXTERN ~Message();
-
+
uint64_t getPersistenceId() const { return persistenceId; }
void setPersistenceId(uint64_t _persistenceId) const { persistenceId = _persistenceId; }
@@ -78,6 +75,7 @@ public:
bool isImmediate() const;
QPID_BROKER_EXTERN const framing::FieldTable* getApplicationHeaders() const;
QPID_BROKER_EXTERN std::string getAppId() const;
+ framing::FieldTable& getOrInsertHeaders();
QPID_BROKER_EXTERN bool isPersistent() const;
bool requiresAccept();
@@ -85,21 +83,19 @@ public:
void setExpiryPolicy(const boost::intrusive_ptr<ExpiryPolicy>& e);
bool hasExpired();
sys::AbsTime getExpiration() const { return expiration; }
- void setExpiration(sys::AbsTime exp) { expiration = exp; }
void adjustTtl();
- void setRedelivered();
- QPID_BROKER_EXTERN void insertCustomProperty(const std::string& key, int64_t value);
- QPID_BROKER_EXTERN void insertCustomProperty(const std::string& key, const std::string& value);
- QPID_BROKER_EXTERN void removeCustomProperty(const std::string& key);
- void setExchange(const std::string&);
- void clearApplicationHeadersFlag();
- framing::FrameSet& getFrames() { return frames; }
- const framing::FrameSet& getFrames() const { return frames; }
+ framing::FrameSet& getFrames() { return frames; }
+ const framing::FrameSet& getFrames() const { return frames; }
+
+ template <class T> T* getProperties() {
+ qpid::framing::AMQHeaderBody* p = frames.getHeaders();
+ return p->get<T>(true);
+ }
template <class T> const T* getProperties() const {
- const qpid::framing::AMQHeaderBody* p = frames.getHeaders();
- return p->get<T>();
+ qpid::framing::AMQHeaderBody* p = frames.getHeaders();
+ return p->get<T>(true);
}
template <class T> const T* hasProperties() const {
@@ -107,11 +103,6 @@ public:
return p->get<T>();
}
- template <class T> void eraseProperties() {
- qpid::framing::AMQHeaderBody* p = frames.getHeaders();
- p->erase<T>();
- }
-
template <class T> const T* getMethod() const {
return frames.as<T>();
}
@@ -144,7 +135,7 @@ public:
QPID_BROKER_EXTERN void decodeHeader(framing::Buffer& buffer);
QPID_BROKER_EXTERN void decodeContent(framing::Buffer& buffer);
-
+
void QPID_BROKER_EXTERN tryReleaseContent();
void releaseContent();
void releaseContent(MessageStore* s);//deprecated, use 'setStore(store); releaseContent();' instead
@@ -158,17 +149,17 @@ public:
bool isExcluded(const std::vector<std::string>& excludes) const;
void addTraceId(const std::string& id);
-
- void forcePersistent();
- bool isForcedPersistent();
+
+ void forcePersistent();
+ bool isForcedPersistent();
+
/** Call cb when dequeue is complete, may call immediately. Holds cb by reference. */
void setDequeueCompleteCallback(MessageCallback& cb);
void resetDequeueCompleteCallback();
uint8_t getPriority() const;
- bool getIsManagementMessage() const;
- void setIsManagementMessage(bool b);
+
private:
MessageAdapter& getAdapter() const;
void allDequeuesComplete();
@@ -180,7 +171,7 @@ public:
bool redelivered;
bool loaded;
bool staged;
- bool forcePersistentPolicy; // used to force message as durable, via a broker policy
+ bool forcePersistentPolicy; // used to force message as durable, via a broker policy
ConnectionToken* publisher;
mutable MessageAdapter* adapter;
qpid::sys::AbsTime expiration;
@@ -195,16 +186,6 @@ public:
bool inCallback;
uint32_t requiredCredit;
- bool isManagementMessage;
- mutable bool copyHeaderOnWrite;
-
- /**
- * Expects lock to be held
- */
- template <class T> T* getModifiableProperties() {
- return getHeaderBody()->get<T>(true);
- }
- qpid::framing::AMQHeaderBody* getHeaderBody();
};
}}
diff --git a/qpid/cpp/src/qpid/broker/MessageBuilder.h b/qpid/cpp/src/qpid/broker/MessageBuilder.h
index b99b8efee6..75dfd6781d 100644
--- a/qpid/cpp/src/qpid/broker/MessageBuilder.h
+++ b/qpid/cpp/src/qpid/broker/MessageBuilder.h
@@ -33,7 +33,7 @@ namespace qpid {
class Message;
class MessageStore;
- class QPID_BROKER_CLASS_EXTERN MessageBuilder : public framing::FrameHandler{
+ class MessageBuilder : public framing::FrameHandler{
public:
QPID_BROKER_EXTERN MessageBuilder(MessageStore* const store);
QPID_BROKER_EXTERN void handle(framing::AMQFrame& frame);
diff --git a/qpid/cpp/src/qpid/broker/Messages.h b/qpid/cpp/src/qpid/broker/Messages.h
index c535fd1936..0d75417640 100644
--- a/qpid/cpp/src/qpid/broker/Messages.h
+++ b/qpid/cpp/src/qpid/broker/Messages.h
@@ -32,8 +32,7 @@ struct QueuedMessage;
/**
* This interface abstracts out the access to the messages held for
- * delivery by a Queue instance. Note the the assumption at present is
- * that all locking is done in the Queue itself.
+ * delivery by a Queue instance.
*/
class Messages
{
diff --git a/qpid/cpp/src/qpid/broker/NullMessageStore.cpp b/qpid/cpp/src/qpid/broker/NullMessageStore.cpp
index 43f600eaf1..dc8615d58b 100644
--- a/qpid/cpp/src/qpid/broker/NullMessageStore.cpp
+++ b/qpid/cpp/src/qpid/broker/NullMessageStore.cpp
@@ -126,25 +126,21 @@ std::auto_ptr<TPCTransactionContext> NullMessageStore::begin(const std::string&
void NullMessageStore::prepare(TPCTransactionContext& ctxt)
{
- qpid::sys::ScopedLock<qpid::sys::Mutex> l(lock);
prepared.insert(DummyCtxt::getXid(ctxt));
}
void NullMessageStore::commit(TransactionContext& ctxt)
{
- qpid::sys::ScopedLock<qpid::sys::Mutex> l(lock);
prepared.erase(DummyCtxt::getXid(ctxt));
}
void NullMessageStore::abort(TransactionContext& ctxt)
{
- qpid::sys::ScopedLock<qpid::sys::Mutex> l(lock);
prepared.erase(DummyCtxt::getXid(ctxt));
}
void NullMessageStore::collectPreparedXids(std::set<std::string>& out)
{
- qpid::sys::ScopedLock<qpid::sys::Mutex> l(lock);
out.insert(prepared.begin(), prepared.end());
}
diff --git a/qpid/cpp/src/qpid/broker/NullMessageStore.h b/qpid/cpp/src/qpid/broker/NullMessageStore.h
index c6f402662e..e148ec4d51 100644
--- a/qpid/cpp/src/qpid/broker/NullMessageStore.h
+++ b/qpid/cpp/src/qpid/broker/NullMessageStore.h
@@ -25,7 +25,6 @@
#include "qpid/broker/BrokerImportExport.h"
#include "qpid/broker/MessageStore.h"
#include "qpid/broker/Queue.h"
-#include "qpid/sys/Mutex.h"
#include <boost/intrusive_ptr.hpp>
@@ -35,11 +34,10 @@ namespace broker {
/**
* A null implementation of the MessageStore interface
*/
-class QPID_BROKER_CLASS_EXTERN NullMessageStore : public MessageStore
+class NullMessageStore : public MessageStore
{
std::set<std::string> prepared;
uint64_t nextPersistenceId;
- qpid::sys::Mutex lock;
public:
QPID_BROKER_EXTERN NullMessageStore();
diff --git a/qpid/cpp/src/qpid/broker/PersistableMessage.h b/qpid/cpp/src/qpid/broker/PersistableMessage.h
index d29c2c45b4..a84aa45d76 100644
--- a/qpid/cpp/src/qpid/broker/PersistableMessage.h
+++ b/qpid/cpp/src/qpid/broker/PersistableMessage.h
@@ -56,7 +56,7 @@ class PersistableMessage : public Persistable
* operations have completed, the transfer of this message from the client
* may be considered complete.
*/
- AsyncCompletion ingressCompletion;
+ boost::shared_ptr<AsyncCompletion> ingressCompletion;
/**
* Tracks the number of outstanding asynchronous dequeue
@@ -115,11 +115,12 @@ class PersistableMessage : public Persistable
virtual QPID_BROKER_EXTERN bool isPersistent() const = 0;
/** track the progress of a message received by the broker - see ingressCompletion above */
- QPID_BROKER_INLINE_EXTERN bool isIngressComplete() { return ingressCompletion.isDone(); }
- QPID_BROKER_INLINE_EXTERN AsyncCompletion& getIngressCompletion() { return ingressCompletion; }
+ QPID_BROKER_EXTERN bool isIngressComplete() { return !ingressCompletion || ingressCompletion->isDone(); }
+ QPID_BROKER_EXTERN boost::shared_ptr<AsyncCompletion>& getIngressCompletion() { return ingressCompletion; }
+ QPID_BROKER_EXTERN void setIngressCompletion(boost::shared_ptr<AsyncCompletion>& ic) { ingressCompletion = ic; }
- QPID_BROKER_INLINE_EXTERN void enqueueStart() { ingressCompletion.startCompleter(); }
- QPID_BROKER_INLINE_EXTERN void enqueueComplete() { ingressCompletion.finishCompleter(); }
+ QPID_BROKER_EXTERN void enqueueStart() { if (ingressCompletion) ingressCompletion->startCompleter(); }
+ QPID_BROKER_EXTERN void enqueueComplete() { if (ingressCompletion) ingressCompletion->finishCompleter(); }
QPID_BROKER_EXTERN void enqueueAsync(PersistableQueue::shared_ptr queue,
MessageStore* _store);
diff --git a/qpid/cpp/src/qpid/broker/Queue.cpp b/qpid/cpp/src/qpid/broker/Queue.cpp
index dd3f982699..d18b0fcda3 100644
--- a/qpid/cpp/src/qpid/broker/Queue.cpp
+++ b/qpid/cpp/src/qpid/broker/Queue.cpp
@@ -7,9 +7,9 @@
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
@@ -65,7 +65,7 @@ using std::mem_fun;
namespace _qmf = qmf::org::apache::qpid::broker;
-namespace
+namespace
{
const std::string qpidMaxSize("qpid.max_size");
const std::string qpidMaxCount("qpid.max_count");
@@ -87,16 +87,16 @@ const int ENQUEUE_ONLY=1;
const int ENQUEUE_AND_DEQUEUE=2;
}
-Queue::Queue(const string& _name, bool _autodelete,
+Queue::Queue(const string& _name, bool _autodelete,
MessageStore* const _store,
const OwnershipToken* const _owner,
Manageable* parent,
Broker* b) :
- name(_name),
+ name(_name),
autodelete(_autodelete),
store(_store),
- owner(_owner),
+ owner(_owner),
consumerCount(0),
exclusive(0),
noLocal(false),
@@ -179,10 +179,11 @@ void Queue::recover(boost::intrusive_ptr<Message>& msg){
if (policy.get()) policy->recoverEnqueued(msg);
push(msg, true);
- if (store){
+ if (store){
// setup synclist for recovered messages, so they don't get re-stored on lastNodeFailure
- msg->addToSyncList(shared_from_this(), store);
+ msg->addToSyncList(shared_from_this(), store);
}
+ msg->enqueueComplete(); // mark the message as enqueued
if (store && (!msg->isContentLoaded() || msg->checkContentReleasable())) {
//content has not been loaded, need to ensure that lazy loading mode is set:
@@ -206,13 +207,14 @@ void Queue::process(boost::intrusive_ptr<Message>& msg){
void Queue::requeue(const QueuedMessage& msg){
assertClusterSafe();
QueueListeners::NotificationSet copy;
- {
+ {
Mutex::ScopedLock locker(messageLock);
if (!isEnqueued(msg)) return;
+ msg.payload->enqueueComplete(); // mark the message as enqueued
messages->reinsert(msg);
listeners.populate(copy);
- // for persistLastNode - don't force a message twice to disk, but force it if no force before
+ // for persistLastNode - don't force a message twice to disk, but force it if no force before
if(inLastNodeFailure && persistLastNode && !msg.payload->isStoredOnQueue(shared_from_this())) {
msg.payload->forcePersistent();
if (msg.payload->isForcedPersistent() ){
@@ -224,7 +226,7 @@ void Queue::requeue(const QueuedMessage& msg){
copy.notify();
}
-bool Queue::acquireMessageAt(const SequenceNumber& position, QueuedMessage& message)
+bool Queue::acquireMessageAt(const SequenceNumber& position, QueuedMessage& message)
{
Mutex::ScopedLock locker(messageLock);
assertClusterSafe();
@@ -268,7 +270,7 @@ bool Queue::getNextMessage(QueuedMessage& m, Consumer::shared_ptr c)
case NO_MESSAGES:
default:
return false;
- }
+ }
} else {
return browseNextMessage(m, c);
}
@@ -278,7 +280,7 @@ Queue::ConsumeCode Queue::consumeNextMessage(QueuedMessage& m, Consumer::shared_
{
while (true) {
Mutex::ScopedLock locker(messageLock);
- if (messages->empty()) {
+ if (messages->empty()) {
QPID_LOG(debug, "No messages to dispatch on queue '" << name << "'");
listeners.addListener(c);
return NO_MESSAGES;
@@ -291,7 +293,7 @@ Queue::ConsumeCode Queue::consumeNextMessage(QueuedMessage& m, Consumer::shared_
}
if (c->filter(msg.payload)) {
- if (c->accept(msg.payload)) {
+ if (c->accept(msg.payload)) {
m = msg;
pop();
return CONSUMED;
@@ -304,7 +306,7 @@ Queue::ConsumeCode Queue::consumeNextMessage(QueuedMessage& m, Consumer::shared_
//consumer will never want this message
QPID_LOG(debug, "Consumer doesn't want message from '" << name << "'");
return CANT_CONSUME;
- }
+ }
}
}
}
@@ -358,7 +360,7 @@ bool Queue::dispatch(Consumer::shared_ptr c)
}
}
-// Find the next message
+// Find the next message
bool Queue::seek(QueuedMessage& msg, Consumer::shared_ptr c) {
Mutex::ScopedLock locker(messageLock);
if (messages->next(c->position, msg)) {
@@ -426,25 +428,19 @@ bool collect_if_expired(std::deque<QueuedMessage>& expired, QueuedMessage& messa
}
}
-/**
- *@param lapse: time since the last purgeExpired
- */
-void Queue::purgeExpired(qpid::sys::Duration lapse)
+void Queue::purgeExpired()
{
//As expired messages are discarded during dequeue also, only
//bother explicitly expiring if the rate of dequeues since last
- //attempt is less than one per second.
- int count = dequeueSincePurge.get();
- dequeueSincePurge -= count;
- int seconds = int64_t(lapse)/qpid::sys::TIME_SEC;
- if (seconds == 0 || count / seconds < 1) {
+ //attempt is less than one per second.
+
+ if (dequeueTracker.sampleRatePerSecond() < 1) {
std::deque<QueuedMessage> expired;
{
Mutex::ScopedLock locker(messageLock);
- messages->removeIf(boost::bind(&collect_if_expired, boost::ref(expired), _1));
+ messages->removeIf(boost::bind(&collect_if_expired, expired, _1));
}
- for_each(expired.begin(), expired.end(),
- boost::bind(&Queue::dequeue, this, (TransactionContext*) 0, _1));
+ for_each(expired.begin(), expired.end(), boost::bind(&Queue::dequeue, this, (TransactionContext*) 0, _1));
}
}
@@ -463,7 +459,7 @@ void Queue::purgeExpired(qpid::sys::Duration lapse)
uint32_t Queue::purge(const uint32_t purge_request, boost::shared_ptr<Exchange> dest)
{
Mutex::ScopedLock locker(messageLock);
- uint32_t purge_count = purge_request; // only comes into play if >0
+ uint32_t purge_count = purge_request; // only comes into play if >0
std::deque<DeliverableMessage> rerouteQueue;
uint32_t count = 0;
@@ -488,7 +484,8 @@ uint32_t Queue::purge(const uint32_t purge_request, boost::shared_ptr<Exchange>
while (!rerouteQueue.empty()) {
DeliverableMessage msg(rerouteQueue.front());
rerouteQueue.pop_front();
- dest->routeWithAlternate(msg);
+ dest->route(msg, msg.getMessage().getRoutingKey(),
+ msg.getMessage().getApplicationHeaders());
}
return count;
@@ -496,7 +493,7 @@ uint32_t Queue::purge(const uint32_t purge_request, boost::shared_ptr<Exchange>
uint32_t Queue::move(const Queue::shared_ptr destq, uint32_t qty) {
Mutex::ScopedLock locker(messageLock);
- uint32_t move_count = qty; // only comes into play if qty >0
+ uint32_t move_count = qty; // only comes into play if qty >0
uint32_t count = 0; // count how many were moved for returning
while((!qty || move_count--) && !messages->empty()) {
@@ -514,7 +511,7 @@ void Queue::pop()
{
assertClusterSafe();
messages->pop();
- ++dequeueSincePurge;
+ ++dequeueTracker;
}
void Queue::push(boost::intrusive_ptr<Message>& msg, bool isRecovery){
@@ -523,10 +520,10 @@ void Queue::push(boost::intrusive_ptr<Message>& msg, bool isRecovery){
QueuedMessage removed;
bool dequeueRequired = false;
{
- Mutex::ScopedLock locker(messageLock);
+ Mutex::ScopedLock locker(messageLock);
QueuedMessage qm(this, msg, ++sequence);
- if (insertSeqNo) msg->insertCustomProperty(seqNoKey, sequence);
-
+ if (insertSeqNo) msg->getOrInsertHeaders().setInt64(seqNoKey, sequence);
+
dequeueRequired = messages->push(qm, removed);
listeners.populate(copy);
enqueued(qm);
@@ -605,7 +602,7 @@ void Queue::setLastNodeFailure()
}
-// return true if store exists,
+// return true if store exists,
bool Queue::enqueue(TransactionContext* ctxt, boost::intrusive_ptr<Message>& msg, bool suppressPolicyCheck)
{
ScopedUse u(barrier);
@@ -619,21 +616,24 @@ bool Queue::enqueue(TransactionContext* ctxt, boost::intrusive_ptr<Message>& msg
policy->getPendingDequeues(dequeues);
}
//depending on policy, may have some dequeues that need to performed without holding the lock
- for_each(dequeues.begin(), dequeues.end(), boost::bind(&Queue::dequeue, this, (TransactionContext*) 0, _1));
+ for_each(dequeues.begin(), dequeues.end(), boost::bind(&Queue::dequeue, this, (TransactionContext*) 0, _1));
}
if (inLastNodeFailure && persistLastNode){
msg->forcePersistent();
}
-
+
if (traceId.size()) {
+ //copy on write: take deep copy of message before modifying it
+ //as the frames may already be available for delivery on other
+ //threads
+ boost::intrusive_ptr<Message> copy(new Message(*msg));
+ msg = copy;
msg->addTraceId(traceId);
}
if ((msg->isPersistent() || msg->checkContentReleasable()) && store) {
- // mark the message as being enqueued - the store MUST CALL msg->enqueueComplete()
- // when it considers the message stored.
- msg->enqueueAsync(shared_from_this(), 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);
return true;
@@ -650,10 +650,10 @@ bool Queue::enqueue(TransactionContext* ctxt, boost::intrusive_ptr<Message>& msg
void Queue::enqueueAborted(boost::intrusive_ptr<Message> msg)
{
Mutex::ScopedLock locker(messageLock);
- if (policy.get()) policy->enqueueAborted(msg);
+ if (policy.get()) policy->enqueueAborted(msg);
}
-// return true if store exists,
+// return true if store exists,
bool Queue::dequeue(TransactionContext* ctxt, const QueuedMessage& msg)
{
ScopedUse u(barrier);
@@ -662,7 +662,7 @@ bool Queue::dequeue(TransactionContext* ctxt, const QueuedMessage& msg)
{
Mutex::ScopedLock locker(messageLock);
if (!isEnqueued(msg)) return false;
- if (!ctxt) {
+ if (!ctxt) {
dequeued(msg);
}
}
@@ -683,7 +683,7 @@ bool Queue::dequeue(TransactionContext* ctxt, const QueuedMessage& msg)
void Queue::dequeueCommitted(const QueuedMessage& msg)
{
Mutex::ScopedLock locker(messageLock);
- dequeued(msg);
+ dequeued(msg);
if (mgmtObject != 0) {
mgmtObject->inc_msgTxnDequeues();
mgmtObject->inc_byteTxnDequeues(msg.payload->contentSize());
@@ -725,7 +725,7 @@ void Queue::create(const FieldTable& _settings)
if (store) {
store->create(*this, _settings);
}
- configureImpl(_settings);
+ configure(_settings);
}
@@ -738,8 +738,8 @@ int getIntegerSetting(const qpid::framing::FieldTable& settings, const std::stri
return v->get<int>();
} else if (v->convertsTo<std::string>()){
std::string s = v->get<std::string>();
- try {
- return boost::lexical_cast<int>(s);
+ try {
+ return boost::lexical_cast<int>(s);
} catch(const boost::bad_lexical_cast&) {
QPID_LOG(warning, "Ignoring invalid integer value for " << key << ": " << s);
return 0;
@@ -750,20 +750,15 @@ int getIntegerSetting(const qpid::framing::FieldTable& settings, const std::stri
}
}
-void Queue::configure(const FieldTable& _settings)
+void Queue::configure(const FieldTable& _settings, bool recovering)
{
- settings = _settings;
- configureImpl(settings);
-}
-void Queue::configureImpl(const FieldTable& _settings)
-{
eventMode = _settings.getAsInt(qpidQueueEventGeneration);
if (eventMode && broker) {
broker->getQueueEvents().observe(*this, eventMode == ENQUEUE_ONLY);
}
- if (QueuePolicy::getType(_settings) == QueuePolicy::FLOW_TO_DISK &&
+ if (QueuePolicy::getType(_settings) == QueuePolicy::FLOW_TO_DISK &&
(!store || NullMessageStore::isNullStore(store) || (broker && !(broker->getQueueEvents().isSync())) )) {
if ( NullMessageStore::isNullStore(store)) {
QPID_LOG(warning, "Flow to disk not valid for non-persisted queue:" << getName());
@@ -777,7 +772,7 @@ void Queue::configureImpl(const FieldTable& _settings)
setPolicy(QueuePolicy::createQueuePolicy(getName(), _settings));
}
if (broker && broker->getManagementAgent()) {
- ThresholdAlerts::observe(*this, *(broker->getManagementAgent()), _settings, broker->getOptions().queueThresholdEventRatio);
+ ThresholdAlerts::observe(*this, *(broker->getManagementAgent()), _settings);
}
//set this regardless of owner to allow use of no-local with exclusive consumers also
@@ -801,7 +796,7 @@ void Queue::configureImpl(const FieldTable& _settings)
QPID_LOG(debug, "Configured queue " << getName() << " as priority queue.");
}
}
-
+
persistLastNode= _settings.get(qpidPersistLastNode);
if (persistLastNode) QPID_LOG(debug, "Configured queue to Persist data if cluster fails to one node for: " << getName());
@@ -810,20 +805,23 @@ void Queue::configureImpl(const FieldTable& _settings)
if (excludeList.size()) {
split(traceExclude, excludeList, ", ");
}
- QPID_LOG(debug, "Configured queue " << getName() << " with qpid.trace.id='" << traceId
+ QPID_LOG(debug, "Configured queue " << getName() << " with qpid.trace.id='" << traceId
<< "' and qpid.trace.exclude='"<< excludeList << "' i.e. " << traceExclude.size() << " elements");
FieldTable::ValuePtr p =_settings.get(qpidInsertSequenceNumbers);
if (p && p->convertsTo<std::string>()) insertSequenceNumbers(p->get<std::string>());
autoDeleteTimeout = getIntegerSetting(_settings, qpidAutoDeleteTimeout);
- if (autoDeleteTimeout)
- QPID_LOG(debug, "Configured queue " << getName() << " with qpid.auto_delete_timeout=" << autoDeleteTimeout);
+ if (autoDeleteTimeout)
+ QPID_LOG(debug, "Configured queue " << getName() << " with qpid.auto_delete_timeout=" << autoDeleteTimeout);
if (mgmtObject != 0) {
mgmtObject->set_arguments(ManagementAgent::toMap(_settings));
}
+ if ( isDurable() && ! getPersistenceId() && ! recovering )
+ store->create(*this, _settings);
+
QueueFlowLimit::observe(*this, _settings);
}
@@ -834,7 +832,8 @@ void Queue::destroyed()
Mutex::ScopedLock locker(messageLock);
while(!messages->empty()){
DeliverableMessage msg(messages->front().payload);
- alternateExchange->routeWithAlternate(msg);
+ alternateExchange->route(msg, msg.getMessage().getRoutingKey(),
+ msg.getMessage().getApplicationHeaders());
popAndDequeue();
}
alternateExchange->decAlternateUsers();
@@ -882,9 +881,9 @@ const QueuePolicy* Queue::getPolicy()
return policy.get();
}
-uint64_t Queue::getPersistenceId() const
-{
- return persistenceId;
+uint64_t Queue::getPersistenceId() const
+{
+ return persistenceId;
}
void Queue::setPersistenceId(uint64_t _persistenceId) const
@@ -898,11 +897,11 @@ void Queue::setPersistenceId(uint64_t _persistenceId) const
persistenceId = _persistenceId;
}
-void Queue::encode(Buffer& buffer) const
+void Queue::encode(Buffer& buffer) const
{
buffer.putShortString(name);
buffer.put(settings);
- if (policy.get()) {
+ if (policy.get()) {
buffer.put(*policy);
}
buffer.putShortString(alternateExchange.get() ? alternateExchange->getName() : std::string(""));
@@ -916,14 +915,13 @@ uint32_t Queue::encodedSize() const
+ (policy.get() ? (*policy).encodedSize() : 0);
}
-Queue::shared_ptr Queue::restore( QueueRegistry& queues, Buffer& buffer )
+Queue::shared_ptr Queue::decode ( QueueRegistry& queues, Buffer& buffer, bool recovering )
{
string name;
buffer.getShortString(name);
- FieldTable settings;
- buffer.get(settings);
- boost::shared_ptr<Exchange> alternate;
- std::pair<Queue::shared_ptr, bool> result = queues.declare(name, true, false, 0, alternate, settings, true);
+ std::pair<Queue::shared_ptr, bool> result = queues.declare(name, true);
+ buffer.get(result.first->settings);
+ result.first->configure(result.first->settings, recovering );
if (result.first->policy.get() && buffer.available() >= result.first->policy->encodedSize()) {
buffer.get ( *(result.first->policy) );
}
@@ -955,7 +953,7 @@ boost::shared_ptr<Exchange> Queue::getAlternateExchange()
void tryAutoDeleteImpl(Broker& broker, Queue::shared_ptr queue)
{
- if (broker.getQueues().destroyIf(queue->getName(),
+ if (broker.getQueues().destroyIf(queue->getName(),
boost::bind(boost::mem_fn(&Queue::canAutoDelete), queue))) {
QPID_LOG(debug, "Auto-deleting " << queue->getName());
queue->destroyed();
@@ -967,7 +965,7 @@ struct AutoDeleteTask : qpid::sys::TimerTask
Broker& broker;
Queue::shared_ptr queue;
- AutoDeleteTask(Broker& b, Queue::shared_ptr q, AbsTime fireTime)
+ AutoDeleteTask(Broker& b, Queue::shared_ptr q, AbsTime fireTime)
: qpid::sys::TimerTask(fireTime, "DelayedAutoDeletion"), broker(b), queue(q) {}
void fire()
@@ -985,27 +983,27 @@ void Queue::tryAutoDelete(Broker& broker, Queue::shared_ptr queue)
if (queue->autoDeleteTimeout && queue->canAutoDelete()) {
AbsTime time(now(), Duration(queue->autoDeleteTimeout * TIME_SEC));
queue->autoDeleteTask = boost::intrusive_ptr<qpid::sys::TimerTask>(new AutoDeleteTask(broker, queue, time));
- broker.getClusterTimer().add(queue->autoDeleteTask);
+ broker.getClusterTimer().add(queue->autoDeleteTask);
QPID_LOG(debug, "Timed auto-delete for " << queue->getName() << " initiated");
} else {
tryAutoDeleteImpl(broker, queue);
}
}
-bool Queue::isExclusiveOwner(const OwnershipToken* const o) const
-{
+bool Queue::isExclusiveOwner(const OwnershipToken* const o) const
+{
Mutex::ScopedLock locker(ownershipLock);
- return o == owner;
+ return o == owner;
}
-void Queue::releaseExclusiveOwnership()
-{
+void Queue::releaseExclusiveOwnership()
+{
Mutex::ScopedLock locker(ownershipLock);
- owner = 0;
+ owner = 0;
}
-bool Queue::setExclusiveOwner(const OwnershipToken* const o)
-{
+bool Queue::setExclusiveOwner(const OwnershipToken* const o)
+{
//reset auto deletion timer if necessary
if (autoDeleteTimeout && autoDeleteTask) {
autoDeleteTask->cancel();
@@ -1014,25 +1012,25 @@ bool Queue::setExclusiveOwner(const OwnershipToken* const o)
if (owner) {
return false;
} else {
- owner = o;
+ owner = o;
return true;
}
}
-bool Queue::hasExclusiveOwner() const
-{
+bool Queue::hasExclusiveOwner() const
+{
Mutex::ScopedLock locker(ownershipLock);
- return owner != 0;
+ return owner != 0;
}
-bool Queue::hasExclusiveConsumer() const
-{
- return exclusive;
+bool Queue::hasExclusiveConsumer() const
+{
+ return exclusive;
}
void Queue::setExternalQueueStore(ExternalQueueStore* inst) {
- if (externalQueueStore!=inst && externalQueueStore)
- delete externalQueueStore;
+ if (externalQueueStore!=inst && externalQueueStore)
+ delete externalQueueStore;
externalQueueStore = inst;
if (inst) {
@@ -1198,10 +1196,6 @@ const Broker* Queue::getBroker()
return broker;
}
-void Queue::setDequeueSincePurge(uint32_t value) {
- dequeueSincePurge = value;
-}
-
Queue::UsageBarrier::UsageBarrier(Queue& q) : parent(q), count(0) {}
diff --git a/qpid/cpp/src/qpid/broker/Queue.h b/qpid/cpp/src/qpid/broker/Queue.h
index 8435e75cab..331c9eaa4e 100644
--- a/qpid/cpp/src/qpid/broker/Queue.h
+++ b/qpid/cpp/src/qpid/broker/Queue.h
@@ -10,9 +10,9 @@
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
@@ -32,9 +32,9 @@
#include "qpid/broker/QueueBindings.h"
#include "qpid/broker/QueueListeners.h"
#include "qpid/broker/QueueObserver.h"
+#include "qpid/broker/RateTracker.h"
#include "qpid/framing/FieldTable.h"
-#include "qpid/sys/AtomicValue.h"
#include "qpid/sys/Monitor.h"
#include "qpid/sys/Timer.h"
#include "qpid/management/Manageable.h"
@@ -74,13 +74,13 @@ class Queue : public boost::enable_shared_from_this<Queue>,
{
Queue& parent;
uint count;
-
+
UsageBarrier(Queue&);
bool acquire();
void release();
void destroy();
};
-
+
struct ScopedUse
{
UsageBarrier& barrier;
@@ -88,7 +88,7 @@ class Queue : public boost::enable_shared_from_this<Queue>,
ScopedUse(UsageBarrier& b) : barrier(b), acquired(barrier.acquire()) {}
~ScopedUse() { if (acquired) barrier.release(); }
};
-
+
typedef std::set< boost::shared_ptr<QueueObserver> > Observers;
enum ConsumeCode {NO_MESSAGES=0, CANT_CONSUME=1, CONSUMED=2};
@@ -119,7 +119,7 @@ class Queue : public boost::enable_shared_from_this<Queue>,
boost::shared_ptr<Exchange> alternateExchange;
framing::SequenceNumber sequence;
qmf::org::apache::qpid::broker::Queue* mgmtObject;
- sys::AtomicValue<uint32_t> dequeueSincePurge; // Count dequeues since last purge.
+ RateTracker dequeueTracker;
int eventMode;
Observers observers;
bool insertSeqNo;
@@ -146,10 +146,9 @@ class Queue : public boost::enable_shared_from_this<Queue>,
void dequeued(const QueuedMessage& msg);
void pop();
void popAndDequeue();
-
+ QueuedMessage getFront();
void forcePersistent(QueuedMessage& msg);
int getEventMode();
- void configureImpl(const qpid::framing::FieldTable& settings);
inline void mgntEnqStats(const boost::intrusive_ptr<Message>& msg)
{
@@ -184,8 +183,8 @@ class Queue : public boost::enable_shared_from_this<Queue>,
typedef std::vector<shared_ptr> vector;
QPID_BROKER_EXTERN Queue(const std::string& name,
- bool autodelete = false,
- MessageStore* const store = 0,
+ bool autodelete = false,
+ MessageStore* const store = 0,
const OwnershipToken* const owner = 0,
management::Manageable* parent = 0,
Broker* broker = 0);
@@ -193,17 +192,11 @@ class Queue : public boost::enable_shared_from_this<Queue>,
QPID_BROKER_EXTERN bool dispatch(Consumer::shared_ptr);
- /**
- * Used to configure a new queue and create a persistent record
- * for it in store if required.
- */
- QPID_BROKER_EXTERN void create(const qpid::framing::FieldTable& settings);
+ void create(const qpid::framing::FieldTable& settings);
- /**
- * Used to reconfigure a recovered queue (does not create
- * persistent record in store).
- */
- QPID_BROKER_EXTERN void configure(const qpid::framing::FieldTable& settings);
+ // "recovering" means we are doing a MessageStore recovery.
+ QPID_BROKER_EXTERN void configure(const qpid::framing::FieldTable& settings,
+ bool recovering = false);
void destroyed();
QPID_BROKER_EXTERN void bound(const std::string& exchange,
const std::string& key,
@@ -245,11 +238,11 @@ class Queue : public boost::enable_shared_from_this<Queue>,
bool exclusive = false);
QPID_BROKER_EXTERN void cancel(Consumer::shared_ptr c);
- uint32_t purge(const uint32_t purge_request=0, boost::shared_ptr<Exchange> dest=boost::shared_ptr<Exchange>()); //defaults to all messages
- QPID_BROKER_EXTERN void purgeExpired(sys::Duration);
+ uint32_t purge(const uint32_t purge_request=0, boost::shared_ptr<Exchange> dest=boost::shared_ptr<Exchange>()); //defaults to all messages
+ QPID_BROKER_EXTERN void purgeExpired();
//move qty # of messages to destination Queue destq
- uint32_t move(const Queue::shared_ptr destq, uint32_t qty);
+ uint32_t move(const Queue::shared_ptr destq, uint32_t qty);
QPID_BROKER_EXTERN uint32_t getMessageCount() const;
QPID_BROKER_EXTERN uint32_t getEnqueueCompleteMessageCount() const;
@@ -288,8 +281,8 @@ class Queue : public boost::enable_shared_from_this<Queue>,
* Inform queue of messages that were enqueued, have since
* been acquired but not yet accepted or released (and
* thus are still logically on the queue) - used in
- * clustered broker.
- */
+ * clustered broker.
+ */
void updateEnqueued(const QueuedMessage& msg);
/**
@@ -300,9 +293,9 @@ class Queue : public boost::enable_shared_from_this<Queue>,
* accepted it).
*/
bool isEnqueued(const QueuedMessage& msg);
-
+
/**
- * Gets the next available message
+ * Gets the next available message
*/
QPID_BROKER_EXTERN QueuedMessage get();
@@ -321,13 +314,8 @@ class Queue : public boost::enable_shared_from_this<Queue>,
void encode(framing::Buffer& buffer) const;
uint32_t encodedSize() const;
- /**
- * Restores a queue from encoded data (used in recovery)
- *
- * Note: restored queue will be neither auto-deleted or have an
- * exclusive owner
- */
- static Queue::shared_ptr restore(QueueRegistry& queues, framing::Buffer& buffer);
+ // "recovering" means we are doing a MessageStore recovery.
+ static Queue::shared_ptr decode(QueueRegistry& queues, framing::Buffer& buffer, bool recovering = false );
static void tryAutoDelete(Broker& broker, Queue::shared_ptr);
virtual void setExternalQueueStore(ExternalQueueStore* inst);
@@ -348,11 +336,6 @@ class Queue : public boost::enable_shared_from_this<Queue>,
bindings.eachBinding(f);
}
- /** Apply f to each Observer on the queue */
- template <class F> void eachObserver(F f) {
- std::for_each<Observers::iterator, F>(observers.begin(), observers.end(), f);
- }
-
/** Set the position sequence number for the next message on the queue.
* Must be >= the current sequence number.
* Used by cluster to replicate queues.
@@ -382,9 +365,6 @@ class Queue : public boost::enable_shared_from_this<Queue>,
void flush();
const Broker* getBroker();
-
- uint32_t getDequeueSincePurge() { return dequeueSincePurge.get(); }
- void setDequeueSincePurge(uint32_t value);
};
}
}
diff --git a/qpid/cpp/src/qpid/broker/QueueCleaner.cpp b/qpid/cpp/src/qpid/broker/QueueCleaner.cpp
index 838bc28be8..3499ea8a4d 100644
--- a/qpid/cpp/src/qpid/broker/QueueCleaner.cpp
+++ b/qpid/cpp/src/qpid/broker/QueueCleaner.cpp
@@ -7,9 +7,9 @@
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
@@ -27,7 +27,7 @@
namespace qpid {
namespace broker {
-QueueCleaner::QueueCleaner(QueueRegistry& q, sys::Timer* t) : queues(q), timer(t) {}
+QueueCleaner::QueueCleaner(QueueRegistry& q, sys::Timer& t) : queues(q), timer(t) {}
QueueCleaner::~QueueCleaner()
{
@@ -36,16 +36,10 @@ QueueCleaner::~QueueCleaner()
void QueueCleaner::start(qpid::sys::Duration p)
{
- period = p;
task = new Task(*this, p);
- timer->add(task);
+ timer.add(task);
}
-void QueueCleaner::setTimer(qpid::sys::Timer* timer) {
- this->timer = timer;
-}
-
-
QueueCleaner::Task::Task(QueueCleaner& p, qpid::sys::Duration d) : sys::TimerTask(d,"QueueCleaner"), parent(p) {}
void QueueCleaner::Task::fire()
@@ -71,9 +65,9 @@ void QueueCleaner::fired()
std::vector<Queue::shared_ptr> copy;
CollectQueues collect(&copy);
queues.eachQueue(collect);
- std::for_each(copy.begin(), copy.end(), boost::bind(&Queue::purgeExpired, _1, period));
+ std::for_each(copy.begin(), copy.end(), boost::bind(&Queue::purgeExpired, _1));
task->setupNextFire();
- timer->add(task);
+ timer.add(task);
}
diff --git a/qpid/cpp/src/qpid/broker/QueueCleaner.h b/qpid/cpp/src/qpid/broker/QueueCleaner.h
index ffebfe3e1b..11c2d180ac 100644
--- a/qpid/cpp/src/qpid/broker/QueueCleaner.h
+++ b/qpid/cpp/src/qpid/broker/QueueCleaner.h
@@ -10,9 +10,9 @@
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
@@ -35,15 +35,14 @@ class QueueRegistry;
class QueueCleaner
{
public:
- QPID_BROKER_EXTERN QueueCleaner(QueueRegistry& queues, sys::Timer* timer);
+ QPID_BROKER_EXTERN QueueCleaner(QueueRegistry& queues, sys::Timer& timer);
QPID_BROKER_EXTERN ~QueueCleaner();
- QPID_BROKER_EXTERN void start(sys::Duration period);
- QPID_BROKER_EXTERN void setTimer(sys::Timer* timer);
+ QPID_BROKER_EXTERN void start(qpid::sys::Duration period);
private:
class Task : public sys::TimerTask
{
public:
- Task(QueueCleaner& parent, sys::Duration duration);
+ Task(QueueCleaner& parent, qpid::sys::Duration duration);
void fire();
private:
QueueCleaner& parent;
@@ -51,8 +50,7 @@ class QueueCleaner
boost::intrusive_ptr<sys::TimerTask> task;
QueueRegistry& queues;
- sys::Timer* timer;
- sys::Duration period;
+ sys::Timer& timer;
void fired();
};
diff --git a/qpid/cpp/src/qpid/broker/QueueFlowLimit.cpp b/qpid/cpp/src/qpid/broker/QueueFlowLimit.cpp
index fcf8d089f9..a99c9de7df 100644
--- a/qpid/cpp/src/qpid/broker/QueueFlowLimit.cpp
+++ b/qpid/cpp/src/qpid/broker/QueueFlowLimit.cpp
@@ -92,7 +92,7 @@ namespace {
QueueFlowLimit::QueueFlowLimit(Queue *_queue,
uint32_t _flowStopCount, uint32_t _flowResumeCount,
uint64_t _flowStopSize, uint64_t _flowResumeSize)
- : StatefulQueueObserver(std::string("QueueFlowLimit")), queue(_queue), queueName("<unknown>"),
+ : queue(_queue), queueName("<unknown>"),
flowStopCount(_flowStopCount), flowResumeCount(_flowResumeCount),
flowStopSize(_flowStopSize), flowResumeSize(_flowResumeSize),
flowStopped(false), count(0), size(0), queueMgmtObj(0), broker(0)
@@ -120,24 +120,11 @@ QueueFlowLimit::QueueFlowLimit(Queue *_queue,
}
-QueueFlowLimit::~QueueFlowLimit()
-{
- sys::Mutex::ScopedLock l(indexLock);
- if (!index.empty()) {
- // we're gone - release all pending msgs
- for (std::map<framing::SequenceNumber, boost::intrusive_ptr<Message> >::iterator itr = index.begin();
- itr != index.end(); ++itr)
- if (itr->second)
- try {
- itr->second->getIngressCompletion().finishCompleter();
- } catch (...) {} // ignore - not safe for a destructor to throw.
- index.clear();
- }
-}
-
void QueueFlowLimit::enqueued(const QueuedMessage& msg)
{
+ if (!msg.payload) return;
+
sys::Mutex::ScopedLock l(indexLock);
++count;
@@ -151,10 +138,13 @@ void QueueFlowLimit::enqueued(const QueuedMessage& msg)
flowStopped = true;
QPID_LOG(info, "Queue \"" << queueName << "\": has reached " << flowStopSize << " enqueued bytes. Producer flow control activated." );
}
- if (flowStopped && queueMgmtObj) {
+ if (flowStopped && queueMgmtObj)
queueMgmtObj->set_flowStopped(true);
- queueMgmtObj->inc_flowStoppedCount();
- }
+ }
+
+ /** @todo KAG: - REMOVE ONCE STABLE */
+ if (index.find(msg.payload) != index.end()) {
+ QPID_LOG(error, "Queue \"" << queueName << "\": has enqueued a msg twice: " << msg.position);
}
if (flowStopped || !index.empty()) {
@@ -164,11 +154,8 @@ void QueueFlowLimit::enqueued(const QueuedMessage& msg)
return;
}
QPID_LOG(trace, "Queue \"" << queueName << "\": setting flow control for msg pos=" << msg.position);
- msg.payload->getIngressCompletion().startCompleter(); // don't complete until flow resumes
- bool unique;
- unique = index.insert(std::pair<framing::SequenceNumber, boost::intrusive_ptr<Message> >(msg.position, msg.payload)).second;
- // Like this to avoid tripping up unused variable warning when NDEBUG set
- if (!unique) assert(unique);
+ msg.payload->getIngressCompletion()->startCompleter(); // don't complete until flow resumes
+ index.insert(msg.payload);
}
}
@@ -176,6 +163,8 @@ void QueueFlowLimit::enqueued(const QueuedMessage& msg)
void QueueFlowLimit::dequeued(const QueuedMessage& msg)
{
+ if (!msg.payload) return;
+
sys::Mutex::ScopedLock l(indexLock);
if (count > 0) {
@@ -203,16 +192,16 @@ void QueueFlowLimit::dequeued(const QueuedMessage& msg)
if (!index.empty()) {
if (!flowStopped) {
// flow enabled - release all pending msgs
- for (std::map<framing::SequenceNumber, boost::intrusive_ptr<Message> >::iterator itr = index.begin();
- itr != index.end(); ++itr)
- if (itr->second)
- itr->second->getIngressCompletion().finishCompleter();
- index.clear();
+ while (!index.empty()) {
+ std::set< boost::intrusive_ptr<Message> >::iterator itr = index.begin();
+ (*itr)->getIngressCompletion()->finishCompleter();
+ index.erase(itr);
+ }
} else {
// even if flow controlled, we must release this msg as it is being dequeued
- std::map<framing::SequenceNumber, boost::intrusive_ptr<Message> >::iterator itr = index.find(msg.position);
+ std::set< boost::intrusive_ptr<Message> >::iterator itr = index.find(msg.payload);
if (itr != index.end()) { // this msg is flow controlled, release it:
- msg.payload->getIngressCompletion().finishCompleter();
+ (*itr)->getIngressCompletion()->finishCompleter();
index.erase(itr);
}
}
@@ -220,6 +209,34 @@ void QueueFlowLimit::dequeued(const QueuedMessage& msg)
}
+/** used by clustering: is the given message's completion blocked due to flow
+ * control? True if message is blocked. (for the clustering updater: done
+ * after msgs have been replicated to the updatee).
+ */
+bool QueueFlowLimit::getState(const QueuedMessage& msg) const
+{
+ sys::Mutex::ScopedLock l(indexLock);
+ return (index.find(msg.payload) != index.end());
+}
+
+
+/** artificially force the flow control state of a given message
+ * (for the clustering updatee: done after msgs have been replicated to
+ * the updatee's queue)
+ */
+void QueueFlowLimit::setState(const QueuedMessage& msg, bool blocked)
+{
+ if (blocked && msg.payload) {
+
+ sys::Mutex::ScopedLock l(indexLock);
+ assert(index.find(msg.payload) == index.end());
+
+ QPID_LOG(debug, "Queue \"" << queue->getName() << "\": forcing flow control for msg pos=" << msg.position << " for CLUSTER SYNC");
+ index.insert(msg.payload);
+ }
+}
+
+
void QueueFlowLimit::encode(Buffer& buffer) const
{
buffer.putLong(flowStopCount);
@@ -267,7 +284,7 @@ void QueueFlowLimit::setDefaults(uint64_t maxQueueSize, uint flowStopRatio, uint
defaultFlowStopRatio = flowStopRatio;
defaultFlowResumeRatio = flowResumeRatio;
- /** @todo KAG: Verify valid range on Broker::Options instead of here */
+ /** @todo Verify valid range on Broker::Options instead of here */
if (flowStopRatio > 100 || flowResumeRatio > 100)
throw InvalidArgumentException(QPID_MSG("Default queue flow ratios must be between 0 and 100, inclusive:"
<< " flowStopRatio=" << flowStopRatio
@@ -298,9 +315,7 @@ QueueFlowLimit *QueueFlowLimit::createLimit(Queue *queue, const qpid::framing::F
return 0;
}
- if (settings.get(flowStopCountKey) || settings.get(flowStopSizeKey) ||
- settings.get(flowResumeCountKey) || settings.get(flowResumeSizeKey)) {
- // user provided (some) flow settings manually...
+ if (settings.get(flowStopCountKey) || settings.get(flowStopSizeKey)) {
uint32_t flowStopCount = getCapacity(settings, flowStopCountKey, 0);
uint32_t flowResumeCount = getCapacity(settings, flowResumeCountKey, 0);
uint64_t flowStopSize = getCapacity(settings, flowStopSizeKey, 0);
@@ -308,89 +323,32 @@ QueueFlowLimit *QueueFlowLimit::createLimit(Queue *queue, const qpid::framing::F
if (flowStopCount == 0 && flowStopSize == 0) { // disable flow control
return 0;
}
+ /** @todo KAG - remove once cluster support for flow control done. */
+ // TODO aconway 2011-02-16: is queue==0 only in tests?
+ // TODO kgiusti 2011-02-19: yes! The unit tests test this class in isolation */
+ if (queue && queue->getBroker() && queue->getBroker()->isInCluster()) {
+ QPID_LOG(warning, "Producer Flow Control TBD for clustered brokers - queue flow control disabled for queue "
+ << queue->getName());
+ return 0;
+ }
return new QueueFlowLimit(queue, flowStopCount, flowResumeCount, flowStopSize, flowResumeSize);
}
- if (defaultFlowStopRatio) { // broker has a default ratio setup...
+ if (defaultFlowStopRatio) {
uint64_t maxByteCount = getCapacity(settings, QueuePolicy::maxSizeKey, defaultMaxSize);
uint64_t flowStopSize = (uint64_t)(maxByteCount * (defaultFlowStopRatio/100.0) + 0.5);
uint64_t flowResumeSize = (uint64_t)(maxByteCount * (defaultFlowResumeRatio/100.0));
- uint32_t maxMsgCount = getCapacity(settings, QueuePolicy::maxCountKey, 0); // no size by default
- uint32_t flowStopCount = (uint32_t)(maxMsgCount * (defaultFlowStopRatio/100.0) + 0.5);
- uint32_t flowResumeCount = (uint32_t)(maxMsgCount * (defaultFlowResumeRatio/100.0));
-
- return new QueueFlowLimit(queue, flowStopCount, flowResumeCount, flowStopSize, flowResumeSize);
- }
- return 0;
-}
-
-/* Cluster replication */
-namespace {
- /** pack a set of sequence number ranges into a framing::Array */
- void buildSeqRangeArray(qpid::framing::Array *seqs,
- const qpid::framing::SequenceNumber& first,
- const qpid::framing::SequenceNumber& last)
- {
- seqs->push_back(qpid::framing::Array::ValuePtr(new Unsigned32Value(first)));
- seqs->push_back(qpid::framing::Array::ValuePtr(new Unsigned32Value(last)));
- }
-}
-
-/** Runs on UPDATER to snapshot current state */
-void QueueFlowLimit::getState(qpid::framing::FieldTable& state ) const
-{
- sys::Mutex::ScopedLock l(indexLock);
- state.clear();
-
- framing::SequenceSet ss;
- if (!index.empty()) {
- /* replicate the set of messages pending flow control */
- for (std::map<framing::SequenceNumber, boost::intrusive_ptr<Message> >::const_iterator itr = index.begin();
- itr != index.end(); ++itr) {
- ss.add(itr->first);
- }
- framing::Array seqs(TYPE_CODE_UINT32);
- typedef boost::function<void(framing::SequenceNumber, framing::SequenceNumber)> arrayBuilder;
- ss.for_each((arrayBuilder)boost::bind(&buildSeqRangeArray, &seqs, _1, _2));
- state.setArray("pendingMsgSeqs", seqs);
- }
- QPID_LOG(debug, "Queue \"" << queueName << "\": flow limit replicating pending msgs, range=" << ss);
-}
-
-
-/** called on UPDATEE to set state from snapshot */
-void QueueFlowLimit::setState(const qpid::framing::FieldTable& state)
-{
- sys::Mutex::ScopedLock l(indexLock);
- index.clear();
-
- framing::SequenceSet fcmsg;
- framing::Array seqArray(TYPE_CODE_UINT32);
- if (state.getArray("pendingMsgSeqs", seqArray)) {
- assert((seqArray.count() & 0x01) == 0); // must be even since they are sequence ranges
- framing::Array::const_iterator i = seqArray.begin();
- while (i != seqArray.end()) {
- framing::SequenceNumber first((*i)->getIntegerValue<uint32_t, 4>());
- ++i;
- framing::SequenceNumber last((*i)->getIntegerValue<uint32_t, 4>());
- ++i;
- fcmsg.add(first, last);
- for (SequenceNumber seq = first; seq <= last; ++seq) {
- QueuedMessage msg(queue->find(seq)); // fyi: msg.payload may be null if msg is delivered & unacked
- bool unique;
- unique = index.insert(std::pair<framing::SequenceNumber, boost::intrusive_ptr<Message> >(seq, msg.payload)).second;
- // Like this to avoid tripping up unused variable warning when NDEBUG set
- if (!unique) assert(unique);
- }
+ /** todo KAG - remove once cluster support for flow control done. */
+ if (queue && queue->getBroker() && queue->getBroker()->isInCluster()) {
+ QPID_LOG(warning, "Producer Flow Control TBD for clustered brokers - queue flow control disabled for queue "
+ << queue->getName());
+ return 0;
}
- }
- flowStopped = index.size() != 0;
- if (queueMgmtObj) {
- queueMgmtObj->set_flowStopped(isFlowControlActive());
+ return new QueueFlowLimit(queue, 0, 0, flowStopSize, flowResumeSize);
}
- QPID_LOG(debug, "Queue \"" << queueName << "\": flow limit replicated the pending msgs, range=" << fcmsg)
+ return 0;
}
diff --git a/qpid/cpp/src/qpid/broker/QueueFlowLimit.h b/qpid/cpp/src/qpid/broker/QueueFlowLimit.h
index c02e479976..69d91df45a 100644
--- a/qpid/cpp/src/qpid/broker/QueueFlowLimit.h
+++ b/qpid/cpp/src/qpid/broker/QueueFlowLimit.h
@@ -27,7 +27,7 @@
#include <memory>
#include "qpid/broker/BrokerImportExport.h"
#include "qpid/broker/QueuedMessage.h"
-#include "qpid/broker/StatefulQueueObserver.h"
+#include "qpid/broker/QueueObserver.h"
#include "qpid/framing/FieldTable.h"
#include "qpid/sys/AtomicValue.h"
#include "qpid/sys/Mutex.h"
@@ -53,7 +53,7 @@ class Broker;
* passing _either_ level may turn flow control ON, but _both_ must be
* below level before flow control will be turned OFF.
*/
- class QueueFlowLimit : public StatefulQueueObserver
+ class QueueFlowLimit : public QueueObserver
{
static uint64_t defaultMaxSize;
static uint defaultFlowStopRatio;
@@ -78,7 +78,7 @@ class Broker;
static QPID_BROKER_EXTERN const std::string flowStopSizeKey;
static QPID_BROKER_EXTERN const std::string flowResumeSizeKey;
- QPID_BROKER_EXTERN virtual ~QueueFlowLimit();
+ virtual ~QueueFlowLimit() {}
/** the queue has added QueuedMessage. Returns true if flow state changes */
QPID_BROKER_EXTERN void enqueued(const QueuedMessage&);
@@ -86,8 +86,9 @@ class Broker;
QPID_BROKER_EXTERN void dequeued(const QueuedMessage&);
/** for clustering: */
- QPID_BROKER_EXTERN void getState(qpid::framing::FieldTable&) const;
- QPID_BROKER_EXTERN void setState(const qpid::framing::FieldTable&);
+ /** true if the given message is flow controlled, and cannot be completed. */
+ bool getState(const QueuedMessage&) const;
+ void setState(const QueuedMessage&, bool blocked);
uint32_t getFlowStopCount() const { return flowStopCount; }
uint32_t getFlowResumeCount() const { return flowResumeCount; }
@@ -110,7 +111,7 @@ class Broker;
protected:
// msgs waiting for flow to become available.
- std::map<framing::SequenceNumber, boost::intrusive_ptr<Message> > index;
+ std::set< boost::intrusive_ptr<Message> > index;
mutable qpid::sys::Mutex indexLock;
_qmfBroker::Queue *queueMgmtObj;
diff --git a/qpid/cpp/src/qpid/broker/QueueListeners.cpp b/qpid/cpp/src/qpid/broker/QueueListeners.cpp
index 591f4443bb..4d2c57d6b4 100644
--- a/qpid/cpp/src/qpid/broker/QueueListeners.cpp
+++ b/qpid/cpp/src/qpid/broker/QueueListeners.cpp
@@ -26,25 +26,19 @@ namespace broker {
void QueueListeners::addListener(Consumer::shared_ptr c)
{
- if (!c->inListeners) {
- if (c->acquires) {
- add(consumers, c);
- } else {
- add(browsers, c);
- }
- c->inListeners = true;
+ if (c->preAcquires()) {
+ add(consumers, c);
+ } else {
+ add(browsers, c);
}
}
void QueueListeners::removeListener(Consumer::shared_ptr c)
{
- if (c->inListeners) {
- if (c->acquires) {
- remove(consumers, c);
- } else {
- remove(browsers, c);
- }
- c->inListeners = false;
+ if (c->preAcquires()) {
+ remove(consumers, c);
+ } else {
+ remove(browsers, c);
}
}
@@ -52,20 +46,18 @@ void QueueListeners::populate(NotificationSet& set)
{
if (consumers.size()) {
set.consumer = consumers.front();
- consumers.pop_front();
- set.consumer->inListeners = false;
+ consumers.erase(consumers.begin());
} else {
- // Don't swap the deques, hang on to the memory allocated.
+ // Don't swap the vectors, hang on to the memory allocated.
set.browsers = browsers;
browsers.clear();
- for (Listeners::iterator i = set.browsers.begin(); i != set.browsers.end(); i++)
- (*i)->inListeners = false;
}
}
void QueueListeners::add(Listeners& listeners, Consumer::shared_ptr c)
{
- listeners.push_back(c);
+ Listeners::iterator i = std::find(listeners.begin(), listeners.end(), c);
+ if (i == listeners.end()) listeners.push_back(c);
}
void QueueListeners::remove(Listeners& listeners, Consumer::shared_ptr c)
@@ -81,7 +73,9 @@ void QueueListeners::NotificationSet::notify()
}
bool QueueListeners::contains(Consumer::shared_ptr c) const {
- return c->inListeners;
+ return
+ std::find(browsers.begin(), browsers.end(), c) != browsers.end() ||
+ std::find(consumers.begin(), consumers.end(), c) != consumers.end();
}
void QueueListeners::ListenerSet::notifyAll()
diff --git a/qpid/cpp/src/qpid/broker/QueueListeners.h b/qpid/cpp/src/qpid/broker/QueueListeners.h
index 0659499253..59d1c84ca4 100644
--- a/qpid/cpp/src/qpid/broker/QueueListeners.h
+++ b/qpid/cpp/src/qpid/broker/QueueListeners.h
@@ -22,7 +22,7 @@
*
*/
#include "qpid/broker/Consumer.h"
-#include <deque>
+#include <vector>
namespace qpid {
namespace broker {
@@ -40,7 +40,7 @@ namespace broker {
class QueueListeners
{
public:
- typedef std::deque<Consumer::shared_ptr> Listeners;
+ typedef std::vector<Consumer::shared_ptr> Listeners;
class NotificationSet
{
diff --git a/qpid/cpp/src/qpid/broker/QueuePolicy.cpp b/qpid/cpp/src/qpid/broker/QueuePolicy.cpp
index 6ae0d53b1a..4168221ad0 100644
--- a/qpid/cpp/src/qpid/broker/QueuePolicy.cpp
+++ b/qpid/cpp/src/qpid/broker/QueuePolicy.cpp
@@ -117,30 +117,30 @@ void QueuePolicy::update(FieldTable& settings)
settings.setString(typeKey, type);
}
-template <typename T>
-T getCapacity(const FieldTable& settings, const std::string& key, T defaultValue)
+uint32_t QueuePolicy::getCapacity(const FieldTable& settings, const std::string& key, uint32_t defaultValue)
{
FieldTable::ValuePtr v = settings.get(key);
- T result = 0;
+ int32_t result = 0;
if (!v) return defaultValue;
if (v->getType() == 0x23) {
QPID_LOG(debug, "Value for " << key << " specified as float: " << v->get<float>());
} else if (v->getType() == 0x33) {
QPID_LOG(debug, "Value for " << key << " specified as double: " << v->get<double>());
- } else if (v->convertsTo<T>()) {
- result = v->get<T>();
+ } else if (v->convertsTo<int>()) {
+ result = v->get<int>();
QPID_LOG(debug, "Got integer value for " << key << ": " << result);
if (result >= 0) return result;
} else if (v->convertsTo<string>()) {
string s(v->get<string>());
QPID_LOG(debug, "Got string value for " << key << ": " << s);
std::istringstream convert(s);
- if (convert >> result && result >= 0 && convert.eof()) return result;
+ if (convert >> result && result >= 0) return result;
}
- throw IllegalArgumentException(QPID_MSG("Cannot convert " << key << " to unsigned integer: " << *v));
+ QPID_LOG(warning, "Cannot convert " << key << " to unsigned integer, using default (" << defaultValue << ")");
+ return defaultValue;
}
std::string QueuePolicy::getType(const FieldTable& settings)
@@ -247,7 +247,7 @@ bool RingQueuePolicy::checkLimit(boost::intrusive_ptr<Message> m)
{
// If the message is bigger than the queue size, give up
- if (getMaxSize() && m->contentSize() > getMaxSize()) {
+ if (m->contentSize() > getMaxSize()) {
QPID_LOG(debug, "Message too large for ring queue " << name
<< " [" << *this << "] "
<< ": message size = " << m->contentSize() << " bytes"
@@ -320,8 +320,8 @@ std::auto_ptr<QueuePolicy> QueuePolicy::createQueuePolicy(const qpid::framing::F
std::auto_ptr<QueuePolicy> QueuePolicy::createQueuePolicy(const std::string& name, const qpid::framing::FieldTable& settings)
{
- uint32_t maxCount = getCapacity<int32_t>(settings, maxCountKey, 0);
- uint64_t maxSize = getCapacity<int64_t>(settings, maxSizeKey, defaultMaxSize);
+ uint32_t maxCount = getCapacity(settings, maxCountKey, 0);
+ uint32_t maxSize = getCapacity(settings, maxSizeKey, defaultMaxSize);
if (maxCount || maxSize) {
return createQueuePolicy(name, maxCount, maxSize, getType(settings));
} else {
diff --git a/qpid/cpp/src/qpid/broker/QueuePolicy.h b/qpid/cpp/src/qpid/broker/QueuePolicy.h
index ec7f846704..3cdd63784d 100644
--- a/qpid/cpp/src/qpid/broker/QueuePolicy.h
+++ b/qpid/cpp/src/qpid/broker/QueuePolicy.h
@@ -43,7 +43,8 @@ class QueuePolicy
uint32_t count;
uint64_t size;
bool policyExceeded;
-
+
+ static uint32_t getCapacity(const qpid::framing::FieldTable& settings, const std::string& key, uint32_t defaultValue);
protected:
uint64_t getCurrentQueueSize() const { return size; }
diff --git a/qpid/cpp/src/qpid/broker/QueueRegistry.cpp b/qpid/cpp/src/qpid/broker/QueueRegistry.cpp
index 135a3543d9..ea2531dae7 100644
--- a/qpid/cpp/src/qpid/broker/QueueRegistry.cpp
+++ b/qpid/cpp/src/qpid/broker/QueueRegistry.cpp
@@ -21,7 +21,6 @@
#include "qpid/broker/Queue.h"
#include "qpid/broker/QueueRegistry.h"
#include "qpid/broker/QueueEvents.h"
-#include "qpid/broker/Exchange.h"
#include "qpid/log/Statement.h"
#include <sstream>
#include <assert.h>
@@ -37,13 +36,7 @@ QueueRegistry::~QueueRegistry(){}
std::pair<Queue::shared_ptr, bool>
QueueRegistry::declare(const string& declareName, bool durable,
- bool autoDelete, const OwnershipToken* owner,
- boost::shared_ptr<Exchange> alternate,
- const qpid::framing::FieldTable& arguments,
- bool recovering/*true if this declare is a
- result of recovering queue
- definition from persistente
- record*/)
+ bool autoDelete, const OwnershipToken* owner)
{
RWlock::ScopedWlock locker(lock);
string name = declareName.empty() ? generateName() : declareName;
@@ -52,17 +45,6 @@ QueueRegistry::declare(const string& declareName, bool durable,
if (i == queues.end()) {
Queue::shared_ptr queue(new Queue(name, autoDelete, durable ? store : 0, owner, parent, broker));
- if (alternate) {
- queue->setAlternateExchange(alternate);//need to do this *before* create
- alternate->incAlternateUsers();
- }
- if (!recovering) {
- //apply settings & create persistent record if required
- queue->create(arguments);
- } else {
- //i.e. recovering a queue for which we already have a persistent record
- queue->configure(arguments);
- }
queues[name] = queue;
if (lastNode) queue->setLastNodeFailure();
diff --git a/qpid/cpp/src/qpid/broker/QueueRegistry.h b/qpid/cpp/src/qpid/broker/QueueRegistry.h
index 8a32a64f05..57859fe639 100644
--- a/qpid/cpp/src/qpid/broker/QueueRegistry.h
+++ b/qpid/cpp/src/qpid/broker/QueueRegistry.h
@@ -24,7 +24,6 @@
#include "qpid/broker/BrokerImportExport.h"
#include "qpid/sys/Mutex.h"
#include "qpid/management/Manageable.h"
-#include "qpid/framing/FieldTable.h"
#include <boost/bind.hpp>
#include <boost/shared_ptr.hpp>
#include <algorithm>
@@ -35,7 +34,6 @@ namespace broker {
class Queue;
class QueueEvents;
-class Exchange;
class OwnershipToken;
class Broker;
class MessageStore;
@@ -62,10 +60,7 @@ class QueueRegistry {
const std::string& name,
bool durable = false,
bool autodelete = false,
- const OwnershipToken* owner = 0,
- boost::shared_ptr<Exchange> alternateExchange = boost::shared_ptr<Exchange>(),
- const qpid::framing::FieldTable& args = framing::FieldTable(),
- bool recovering = false);
+ const OwnershipToken* owner = 0);
/**
* Destroy the named queue.
diff --git a/qpid/cpp/src/qpid/broker/RateTracker.cpp b/qpid/cpp/src/qpid/broker/RateTracker.cpp
new file mode 100644
index 0000000000..048349b658
--- /dev/null
+++ b/qpid/cpp/src/qpid/broker/RateTracker.cpp
@@ -0,0 +1,51 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+#include "qpid/broker/RateTracker.h"
+
+using qpid::sys::AbsTime;
+using qpid::sys::Duration;
+using qpid::sys::TIME_SEC;
+
+namespace qpid {
+namespace broker {
+
+RateTracker::RateTracker() : currentCount(0), lastCount(0), lastTime(AbsTime::now()) {}
+
+RateTracker& RateTracker::operator++()
+{
+ ++currentCount;
+ return *this;
+}
+
+double RateTracker::sampleRatePerSecond()
+{
+ int32_t increment = currentCount - lastCount;
+ AbsTime now = AbsTime::now();
+ Duration interval(lastTime, now);
+ lastCount = currentCount;
+ lastTime = now;
+ //if sampling at higher frequency than supported, will just return the number of increments
+ if (interval < TIME_SEC) return increment;
+ else if (increment == 0) return 0;
+ else return increment / (interval / TIME_SEC);
+}
+
+}} // namespace qpid::broker
diff --git a/qpid/cpp/src/qpid/broker/RateTracker.h b/qpid/cpp/src/qpid/broker/RateTracker.h
new file mode 100644
index 0000000000..0c20b37312
--- /dev/null
+++ b/qpid/cpp/src/qpid/broker/RateTracker.h
@@ -0,0 +1,57 @@
+#ifndef QPID_BROKER_RATETRACKER_H
+#define QPID_BROKER_RATETRACKER_H
+
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+#include "qpid/sys/Time.h"
+
+namespace qpid {
+namespace broker {
+
+/**
+ * Simple rate tracker: represents some value that can be incremented,
+ * then can periodcially sample the rate of increments.
+ */
+class RateTracker
+{
+ public:
+ RateTracker();
+ /**
+ * Increments the count being tracked. Can be called concurrently
+ * with other calls to this operator as well as with calls to
+ * sampleRatePerSecond().
+ */
+ RateTracker& operator++();
+ /**
+ * Returns the rate of increments per second since last
+ * called. Calls to this method should be serialised, but can be
+ * called concurrently with the increment operator
+ */
+ double sampleRatePerSecond();
+ private:
+ volatile int32_t currentCount;
+ int32_t lastCount;
+ qpid::sys::AbsTime lastTime;
+};
+}} // namespace qpid::broker
+
+#endif /*!QPID_BROKER_RATETRACKER_H*/
diff --git a/qpid/cpp/src/qpid/broker/RecoveredDequeue.cpp b/qpid/cpp/src/qpid/broker/RecoveredDequeue.cpp
index cd6735328f..38cb8043c9 100644
--- a/qpid/cpp/src/qpid/broker/RecoveredDequeue.cpp
+++ b/qpid/cpp/src/qpid/broker/RecoveredDequeue.cpp
@@ -43,6 +43,7 @@ void RecoveredDequeue::commit() throw()
void RecoveredDequeue::rollback() throw()
{
+ msg->enqueueComplete();
queue->process(msg);
}
diff --git a/qpid/cpp/src/qpid/broker/RecoveredEnqueue.cpp b/qpid/cpp/src/qpid/broker/RecoveredEnqueue.cpp
index 6d2eaee6c4..6263c63e3d 100644
--- a/qpid/cpp/src/qpid/broker/RecoveredEnqueue.cpp
+++ b/qpid/cpp/src/qpid/broker/RecoveredEnqueue.cpp
@@ -36,6 +36,7 @@ bool RecoveredEnqueue::prepare(TransactionContext*) throw(){
}
void RecoveredEnqueue::commit() throw(){
+ msg->enqueueComplete();
queue->process(msg);
}
diff --git a/qpid/cpp/src/qpid/broker/RecoveryManagerImpl.cpp b/qpid/cpp/src/qpid/broker/RecoveryManagerImpl.cpp
index d08409695e..2f04943581 100644
--- a/qpid/cpp/src/qpid/broker/RecoveryManagerImpl.cpp
+++ b/qpid/cpp/src/qpid/broker/RecoveryManagerImpl.cpp
@@ -113,7 +113,7 @@ RecoverableExchange::shared_ptr RecoveryManagerImpl::recoverExchange(framing::Bu
RecoverableQueue::shared_ptr RecoveryManagerImpl::recoverQueue(framing::Buffer& buffer)
{
- Queue::shared_ptr queue = Queue::restore(queues, buffer);
+ Queue::shared_ptr queue = Queue::decode(queues, buffer, true);
try {
Exchange::shared_ptr exchange = exchanges.getDefault();
if (exchange) {
@@ -252,6 +252,7 @@ void RecoverableMessageImpl::dequeue(DtxBuffer::shared_ptr buffer, Queue::shared
void RecoverableMessageImpl::enqueue(DtxBuffer::shared_ptr buffer, Queue::shared_ptr queue)
{
+ msg->enqueueComplete(); // recoved nmessage to enqueued in store already
buffer->enlist(TxOp::shared_ptr(new RecoveredEnqueue(queue, msg)));
}
diff --git a/qpid/cpp/src/qpid/broker/SaslAuthenticator.cpp b/qpid/cpp/src/qpid/broker/SaslAuthenticator.cpp
index 07d5045852..acdb4934d4 100644
--- a/qpid/cpp/src/qpid/broker/SaslAuthenticator.cpp
+++ b/qpid/cpp/src/qpid/broker/SaslAuthenticator.cpp
@@ -384,7 +384,7 @@ void CyrusAuthenticator::start(const string& mechanism, const string& response)
QPID_LOG(debug, "SASL: Starting authentication with mechanism: " << mechanism);
int code = sasl_server_start(sasl_conn,
mechanism.c_str(),
- response.size() ? response.c_str() : 0, response.length(),
+ response.c_str(), response.length(),
&challenge, &challenge_len);
processAuthenticationStep(code, challenge, challenge_len);
@@ -424,12 +424,10 @@ void CyrusAuthenticator::processAuthenticationStep(int code, const char *challen
client.secure(challenge_str);
} else {
std::string uid;
- //save error detail before trying to retrieve username as error in doing so will overwrite it
- std::string errordetail = sasl_errdetail(sasl_conn);
if (!getUsername(uid)) {
- QPID_LOG(info, "SASL: Authentication failed (no username available yet):" << errordetail);
+ QPID_LOG(info, "SASL: Authentication failed (no username available):" << sasl_errdetail(sasl_conn));
} else {
- QPID_LOG(info, "SASL: Authentication failed for " << uid << ":" << errordetail);
+ QPID_LOG(info, "SASL: Authentication failed for " << uid << ":" << sasl_errdetail(sasl_conn));
}
// TODO: Change to more specific exceptions, when they are
diff --git a/qpid/cpp/src/qpid/broker/SemanticState.cpp b/qpid/cpp/src/qpid/broker/SemanticState.cpp
index 73a0a5cf7b..cfc379f47c 100644
--- a/qpid/cpp/src/qpid/broker/SemanticState.cpp
+++ b/qpid/cpp/src/qpid/broker/SemanticState.cpp
@@ -70,7 +70,7 @@ SemanticState::SemanticState(DeliveryAdapter& da, SessionContext& ss)
deliveryAdapter(da),
tagGenerator("sgen"),
dtxSelected(false),
- authMsg(getSession().getBroker().getOptions().auth && !getSession().getConnection().isUserProxyAuth()),
+ authMsg(getSession().getBroker().getOptions().auth && !getSession().getConnection().isFederationLink()),
userID(getSession().getConnection().getUserId()),
userName(getSession().getConnection().getUserId().substr(0,getSession().getConnection().getUserId().find('@'))),
isDefaultRealm(userID.find('@') != std::string::npos && getSession().getBroker().getOptions().realm == userID.substr(userID.find('@')+1,userID.size())),
@@ -88,7 +88,7 @@ void SemanticState::closed() {
//prevent requeued messages being redelivered to consumers
for (ConsumerImplMap::iterator i = consumers.begin(); i != consumers.end(); i++) {
disable(i->second);
- }
+ }
if (dtxBuffer.get()) {
dtxBuffer->fail();
}
@@ -107,7 +107,7 @@ bool SemanticState::exists(const string& consumerTag){
return consumers.find(consumerTag) != consumers.end();
}
-void SemanticState::consume(const string& tag,
+void SemanticState::consume(const string& tag,
Queue::shared_ptr queue, bool ackRequired, bool acquire,
bool exclusive, const string& resumeId, uint64_t resumeTtl, const FieldTable& arguments)
{
@@ -116,8 +116,7 @@ void SemanticState::consume(const string& tag,
consumers[tag] = c;
}
-bool SemanticState::cancel(const string& tag)
-{
+void SemanticState::cancel(const string& tag){
ConsumerImplMap::iterator i = consumers.find(tag);
if (i != consumers.end()) {
cancel(i->second);
@@ -125,9 +124,7 @@ bool SemanticState::cancel(const string& tag)
//should cancel all unacked messages for this consumer so that
//they are not redelivered on recovery
for_each(unacked.begin(), unacked.end(), boost::bind(&DeliveryRecord::cancel, _1, tag));
- return true;
- } else {
- return false;
+
}
}
@@ -197,7 +194,7 @@ void SemanticState::endDtx(const std::string& xid, bool fail)
dtxBuffer->fail();
} else {
dtxBuffer->markEnded();
- }
+ }
dtxBuffer.reset();
}
@@ -257,9 +254,9 @@ void SemanticState::record(const DeliveryRecord& delivery)
const std::string QPID_SYNC_FREQUENCY("qpid.sync_frequency");
-SemanticState::ConsumerImpl::ConsumerImpl(SemanticState* _parent,
- const string& _name,
- Queue::shared_ptr _queue,
+SemanticState::ConsumerImpl::ConsumerImpl(SemanticState* _parent,
+ const string& _name,
+ Queue::shared_ptr _queue,
bool ack,
bool _acquire,
bool _exclusive,
@@ -268,20 +265,20 @@ SemanticState::ConsumerImpl::ConsumerImpl(SemanticState* _parent,
const framing::FieldTable& _arguments
-) :
+) :
Consumer(_acquire),
- parent(_parent),
- name(_name),
- queue(_queue),
- ackExpected(ack),
+ parent(_parent),
+ name(_name),
+ queue(_queue),
+ ackExpected(ack),
acquire(_acquire),
- blocked(true),
+ blocked(true),
windowing(true),
exclusive(_exclusive),
resumeId(_resumeId),
resumeTtl(_resumeTtl),
arguments(_arguments),
- msgCredit(0),
+ msgCredit(0),
byteCredit(0),
notifyEnabled(true),
syncFrequency(_arguments.getAsInt(QPID_SYNC_FREQUENCY)),
@@ -292,7 +289,7 @@ SemanticState::ConsumerImpl::ConsumerImpl(SemanticState* _parent,
{
ManagementAgent* agent = parent->session.getBroker().getManagementAgent();
qpid::management::Manageable* ms = dynamic_cast<qpid::management::Manageable*> (&(parent->session));
-
+
if (agent != 0)
{
mgmtObject = new _qmf::Subscription(agent, this, ms , queue->GetManagementObject()->getObjectId() ,name,
@@ -334,7 +331,7 @@ bool SemanticState::ConsumerImpl::deliver(QueuedMessage& msg)
if (!ackExpected && acquire) record.setEnded();//allows message to be released now its been delivered
if (windowing || ackExpected || !acquire) {
parent->record(record);
- }
+ }
if (acquire && !ackExpected) {
queue->dequeue(0, msg);
}
@@ -354,7 +351,7 @@ bool SemanticState::ConsumerImpl::accept(intrusive_ptr<Message> msg)
// checkCredit fails because the message is to big, we should
// remain on queue's listener list for possible smaller messages
// in future.
- //
+ //
blocked = !(filter(msg) && checkCredit(msg));
return !blocked;
}
@@ -375,7 +372,7 @@ void SemanticState::ConsumerImpl::allocateCredit(intrusive_ptr<Message>& msg)
{
assertClusterSafe();
uint32_t originalMsgCredit = msgCredit;
- uint32_t originalByteCredit = byteCredit;
+ uint32_t originalByteCredit = byteCredit;
if (msgCredit != 0xFFFFFFFF) {
msgCredit--;
}
@@ -385,7 +382,7 @@ void SemanticState::ConsumerImpl::allocateCredit(intrusive_ptr<Message>& msg)
QPID_LOG(debug, "Credit allocated for " << ConsumerName(*this)
<< ", was " << " bytes: " << originalByteCredit << " msgs: " << originalMsgCredit
<< " now bytes: " << byteCredit << " msgs: " << msgCredit);
-
+
}
bool SemanticState::ConsumerImpl::checkCredit(intrusive_ptr<Message>& msg)
@@ -399,7 +396,7 @@ bool SemanticState::ConsumerImpl::checkCredit(intrusive_ptr<Message>& msg)
return enoughCredit;
}
-SemanticState::ConsumerImpl::~ConsumerImpl()
+SemanticState::ConsumerImpl::~ConsumerImpl()
{
if (mgmtObject != 0)
mgmtObject->resourceDestroy ();
@@ -417,7 +414,7 @@ void SemanticState::unsubscribe(ConsumerImpl::shared_ptr c)
Queue::shared_ptr queue = c->getQueue();
if(queue) {
queue->cancel(c);
- if (queue->canAutoDelete() && !queue->hasExclusiveOwner()) {
+ if (queue->canAutoDelete() && !queue->hasExclusiveOwner()) {
Queue::tryAutoDelete(session.getBroker(), queue);
}
}
@@ -460,15 +457,16 @@ const std::string nullstring;
void SemanticState::route(intrusive_ptr<Message> msg, Deliverable& strategy) {
msg->setTimestamp(getSession().getBroker().getExpiryPolicy());
-
+
std::string exchangeName = msg->getExchangeName();
- if (!cacheExchange || cacheExchange->getName() != exchangeName || cacheExchange->isDestroyed())
+ if (!cacheExchange || cacheExchange->getName() != exchangeName)
cacheExchange = session.getBroker().getExchanges().get(exchangeName);
cacheExchange->setProperties(msg);
/* verify the userid if specified: */
std::string id =
msg->hasProperties<MessageProperties>() ? msg->getProperties<MessageProperties>()->getUserId() : nullstring;
+
if (authMsg && !id.empty() && !(id == userID || (isDefaultRealm && id == userName)))
{
QPID_LOG(debug, "authorised user id : " << userID << " but user id in message declared as " << id);
@@ -486,7 +484,7 @@ void SemanticState::route(intrusive_ptr<Message> msg, Deliverable& strategy) {
if (!strategy.delivered) {
//TODO:if discard-unroutable, just drop it
- //TODO:else if accept-mode is explicit, reject it
+ //TODO:else if accept-mode is explicit, reject it
//else route it to alternate exchange
if (cacheExchange->getAlternate()) {
cacheExchange->getAlternate()->route(strategy, msg->getRoutingKey(), msg->getApplicationHeaders());
@@ -515,7 +513,7 @@ void SemanticState::ConsumerImpl::requestDispatch()
}
bool SemanticState::complete(DeliveryRecord& delivery)
-{
+{
ConsumerImplMap::iterator i = consumers.find(delivery.getTag());
if (i != consumers.end()) {
i->second->complete(delivery);
@@ -543,7 +541,7 @@ void SemanticState::recover(bool requeue)
unacked.clear();
for_each(copy.rbegin(), copy.rend(), mem_fun_ref(&DeliveryRecord::requeue));
}else{
- for_each(unacked.begin(), unacked.end(), boost::bind(&DeliveryRecord::redeliver, _1, this));
+ for_each(unacked.begin(), unacked.end(), boost::bind(&DeliveryRecord::redeliver, _1, this));
//unconfirmed messages re redelivered and therefore have their
//id adjusted, confirmed messages are not and so the ordering
//w.r.t id is lost
@@ -675,7 +673,7 @@ Queue::shared_ptr SemanticState::getQueue(const string& name) const {
}
AckRange SemanticState::findRange(DeliveryId first, DeliveryId last)
-{
+{
return DeliveryRecord::findRange(unacked, first, last);
}
@@ -766,13 +764,13 @@ void SemanticState::accepted(const SequenceSet& commands) {
//in transactional mode, don't dequeue or remove, just
//maintain set of acknowledged messages:
accumulatedAck.add(commands);
-
+
if (dtxBuffer.get()) {
//if enlisted in a dtx, copy the relevant slice from
//unacked and record it against that transaction
TxOp::shared_ptr txAck(new DtxAck(accumulatedAck, unacked));
accumulatedAck.clear();
- dtxBuffer->enlist(txAck);
+ dtxBuffer->enlist(txAck);
//mark the relevant messages as 'ended' in unacked
//if the messages are already completed, they can be
@@ -794,6 +792,7 @@ void SemanticState::accepted(const SequenceSet& commands) {
}
void SemanticState::completed(const SequenceSet& commands) {
+ assertClusterSafe();
DeliveryRecords::iterator removed =
remove_if(unacked.begin(), unacked.end(),
isInSequenceSetAnd(commands,
@@ -804,6 +803,7 @@ void SemanticState::completed(const SequenceSet& commands) {
void SemanticState::attached()
{
+ assertClusterSafe();
for (ConsumerImplMap::iterator i = consumers.begin(); i != consumers.end(); i++) {
i->second->enableNotify();
session.getConnection().outputTasks.addOutputTask(i->second.get());
@@ -813,6 +813,7 @@ void SemanticState::attached()
void SemanticState::detached()
{
+ assertClusterSafe();
for (ConsumerImplMap::iterator i = consumers.begin(); i != consumers.end(); i++) {
i->second->disableNotify();
session.getConnection().outputTasks.removeOutputTask(i->second.get());
diff --git a/qpid/cpp/src/qpid/broker/SemanticState.h b/qpid/cpp/src/qpid/broker/SemanticState.h
index 8c69d6b89b..b2e648410a 100644
--- a/qpid/cpp/src/qpid/broker/SemanticState.h
+++ b/qpid/cpp/src/qpid/broker/SemanticState.h
@@ -205,7 +205,7 @@ class SemanticState : private boost::noncopyable {
const std::string& resumeId=std::string(), uint64_t resumeTtl=0,
const framing::FieldTable& = framing::FieldTable());
- bool cancel(const std::string& tag);
+ void cancel(const std::string& tag);
void setWindowMode(const std::string& destination);
void setCreditMode(const std::string& destination);
diff --git a/qpid/cpp/src/qpid/broker/SessionAdapter.cpp b/qpid/cpp/src/qpid/broker/SessionAdapter.cpp
index 63c4b660b2..9e4516679e 100644
--- a/qpid/cpp/src/qpid/broker/SessionAdapter.cpp
+++ b/qpid/cpp/src/qpid/broker/SessionAdapter.cpp
@@ -114,7 +114,7 @@ void SessionAdapter::ExchangeHandlerImpl::declare(const string& exchange, const
"existing"));
}
}catch(UnknownExchangeTypeException& /*e*/){
- throw NotFoundException(QPID_MSG("Exchange type not implemented: " << type));
+ throw CommandInvalidException(QPID_MSG("Exchange type not implemented: " << type));
}
}
}
@@ -353,12 +353,12 @@ void SessionAdapter::QueueHandlerImpl::checkDelete(Queue::shared_ptr queue, bool
} else if(ifUnused && queue->getConsumerCount() > 0) {
throw PreconditionFailedException(QPID_MSG("Cannot delete queue "
<< queue->getName() << "; queue in use"));
- } else if (queue->isExclusiveOwner(&session)) {
+ } else if (queue->isExclusiveOwner(&getConnection())) {
//remove the queue from the list of exclusive queues if necessary
- QueueVector::iterator i = std::find(exclusiveQueues.begin(),
- exclusiveQueues.end(),
+ QueueVector::iterator i = std::find(getConnection().exclusiveQueues.begin(),
+ getConnection().exclusiveQueues.end(),
queue);
- if (i < exclusiveQueues.end()) exclusiveQueues.erase(i);
+ if (i < getConnection().exclusiveQueues.end()) getConnection().exclusiveQueues.erase(i);
}
}
@@ -431,9 +431,7 @@ SessionAdapter::MessageHandlerImpl::subscribe(const string& queueName,
void
SessionAdapter::MessageHandlerImpl::cancel(const string& destination )
{
- if (!state.cancel(destination)) {
- throw NotFoundException(QPID_MSG("No such subscription: " << destination));
- }
+ state.cancel(destination);
ManagementAgent* agent = getBroker().getManagementAgent();
if (agent)
diff --git a/qpid/cpp/src/qpid/broker/SessionHandler.cpp b/qpid/cpp/src/qpid/broker/SessionHandler.cpp
index 752fa55535..69b364ad7b 100644
--- a/qpid/cpp/src/qpid/broker/SessionHandler.cpp
+++ b/qpid/cpp/src/qpid/broker/SessionHandler.cpp
@@ -40,6 +40,11 @@ SessionHandler::SessionHandler(Connection& c, ChannelId ch)
SessionHandler::~SessionHandler() {}
+namespace {
+ClassId classId(AMQMethodBody* m) { return m ? m->amqpMethodId() : 0; }
+MethodId methodId(AMQMethodBody* m) { return m ? m->amqpClassId() : 0; }
+} // namespace
+
void SessionHandler::connectionException(framing::connection::CloseCode code, const std::string& msg) {
// NOTE: must tell the error listener _before_ calling connection.close()
if (connection.getErrorListener()) connection.getErrorListener()->connectionError(msg);
diff --git a/qpid/cpp/src/qpid/broker/SessionState.cpp b/qpid/cpp/src/qpid/broker/SessionState.cpp
index 742dbe9be8..11f3e84b70 100644
--- a/qpid/cpp/src/qpid/broker/SessionState.cpp
+++ b/qpid/cpp/src/qpid/broker/SessionState.cpp
@@ -25,7 +25,6 @@
#include "qpid/broker/SessionManager.h"
#include "qpid/broker/SessionHandler.h"
#include "qpid/broker/RateFlowcontrol.h"
-#include "qpid/sys/ClusterSafe.h"
#include "qpid/sys/Timer.h"
#include "qpid/framing/AMQContentBody.h"
#include "qpid/framing/AMQHeaderBody.h"
@@ -63,7 +62,7 @@ SessionState::SessionState(
msgBuilder(&broker.getStore()),
mgmtObject(0),
rateFlowcontrol(0),
- asyncCommandCompleter(new AsyncCommandCompleter(this))
+ scheduledCompleterContext(new ScheduledCompleterContext(this))
{
uint32_t maxRate = broker.getOptions().maxSessionRate;
if (maxRate) {
@@ -96,13 +95,32 @@ void SessionState::addManagementObject() {
}
SessionState::~SessionState() {
- asyncCommandCompleter->cancel();
semanticState.closed();
if (mgmtObject != 0)
mgmtObject->resourceDestroy ();
if (flowControlTimer)
flowControlTimer->cancel();
+
+ // clean up any outstanding incomplete commands
+ {
+ qpid::sys::ScopedLock<Mutex> l(incompleteCmdsLock);
+ std::map<SequenceNumber, boost::shared_ptr<IncompleteCommandContext> > copy(incompleteCmds);
+ incompleteCmds.clear();
+ while (!copy.empty()) {
+ boost::shared_ptr<IncompleteCommandContext> ref(copy.begin()->second);
+ copy.erase(copy.begin());
+ {
+ // note: need to drop lock, as callback may attempt to take it.
+ qpid::sys::ScopedUnlock<Mutex> ul(incompleteCmdsLock);
+ ref->cancel();
+ }
+ }
+ }
+
+ // At this point, we are guaranteed no further completion callbacks will be
+ // made. Cancel any outstanding scheduledCompleter calls...
+ scheduledCompleterContext->cancel();
}
AMQP_ClientProxy& SessionState::getProxy() {
@@ -127,7 +145,6 @@ bool SessionState::isLocal(const ConnectionToken* t) const
void SessionState::detach() {
QPID_LOG(debug, getId() << ": detached on broker.");
- asyncCommandCompleter->detached();
disableOutput();
handler = 0;
if (mgmtObject != 0)
@@ -148,7 +165,6 @@ void SessionState::attach(SessionHandler& h) {
mgmtObject->set_connectionRef (h.getConnection().GetManagementObject()->getObjectId());
mgmtObject->set_channelId (h.getChannel());
}
- asyncCommandCompleter->attached();
}
void SessionState::abort() {
@@ -260,11 +276,13 @@ void SessionState::handleContent(AMQFrame& frame, const SequenceNumber& id)
msg->getFrames().append(header);
}
msg->setPublisher(&getConnection());
- msg->getIngressCompletion().begin();
+
+ boost::shared_ptr<AsyncCompletion> ac(boost::dynamic_pointer_cast<AsyncCompletion>(createIngressMsgXferContext(msg)));
+ msg->setIngressCompletion( ac );
+ ac->begin();
semanticState.handle(msg);
msgBuilder.end();
- IncompleteIngressMsgXfer xfer(this, msg);
- msg->getIngressCompletion().end(xfer); // allows msg to complete xfer
+ ac->end(); // allows msg to complete xfer
}
// Handle producer session flow control
@@ -323,11 +341,6 @@ void SessionState::completeRcvMsg(SequenceNumber id,
bool requiresAccept,
bool requiresSync)
{
- // Mark this as a cluster-unsafe scope since it can be called in
- // journal threads or connection threads as part of asynchronous
- // command completion.
- sys::ClusterUnsafeScope cus;
-
bool callSendCompletion = false;
receiverCompleted(id);
if (requiresAccept)
@@ -433,166 +446,116 @@ void SessionState::addPendingExecutionSync()
if (receiverGetIncomplete().front() < syncCommandId) {
currentCommandComplete = false;
pendingExecutionSyncs.push(syncCommandId);
- asyncCommandCompleter->flushPendingMessages();
QPID_LOG(debug, getId() << ": delaying completion of execution.sync " << syncCommandId);
}
}
-/** factory for creating a reference-counted IncompleteIngressMsgXfer object
- * which will be attached to a message that will be completed asynchronously.
+/** factory for creating IncompleteIngressMsgXfer objects which
+ * can be references from Messages as ingress AsyncCompletion objects.
*/
-boost::intrusive_ptr<AsyncCompletion::Callback>
-SessionState::IncompleteIngressMsgXfer::clone()
+boost::shared_ptr<SessionState::IncompleteIngressMsgXfer>
+SessionState::createIngressMsgXferContext(boost::intrusive_ptr<Message> msg)
{
- // Optimization: this routine is *only* invoked when the message needs to be asynchronously completed.
- // If the client is pending the message.transfer completion, flush now to force immediate write to journal.
- if (requiresSync)
- msg->flush();
- else {
- // otherwise, we need to track this message in order to flush it if an execution.sync arrives
- // before it has been completed (see flushPendingMessages())
- pending = true;
- completerContext->addPendingMessage(msg);
- }
-
- return boost::intrusive_ptr<SessionState::IncompleteIngressMsgXfer>(new SessionState::IncompleteIngressMsgXfer(*this));
+ SequenceNumber id = msg->getCommandId();
+ boost::shared_ptr<SessionState::IncompleteIngressMsgXfer> cmd(new SessionState::IncompleteIngressMsgXfer(this, id, msg));
+ qpid::sys::ScopedLock<Mutex> l(incompleteCmdsLock);
+ incompleteCmds[id] = cmd;
+ return cmd;
}
-/** Invoked by the asynchronous completer associated with a received
- * msg that is pending Completion. May be invoked by the IO thread
- * (sync == true), or some external thread (!sync).
+/** Invoked by the asynchronous completer associated with
+ * a received msg that is pending Completion. May be invoked
+ * by the SessionState directly (sync == true), or some external
+ * entity (!sync).
*/
void SessionState::IncompleteIngressMsgXfer::completed(bool sync)
{
- if (pending) completerContext->deletePendingMessage(id);
if (!sync) {
/** note well: this path may execute in any thread. It is safe to access
- * the scheduledCompleterContext, since *this has a shared pointer to it.
- * but not session!
+ * the session, as the SessionState destructor will cancel all outstanding
+ * callbacks before getting destroyed (so we'll never get here).
*/
- session = 0;
QPID_LOG(debug, ": async completion callback scheduled for msg seq=" << id);
- completerContext->scheduleMsgCompletion(id, requiresAccept, requiresSync);
- } else {
- // this path runs directly from the ac->end() call in handleContent() above,
- // so *session is definately valid.
- if (session->isAttached()) {
- QPID_LOG(debug, ": receive completed for msg seq=" << id);
- session->completeRcvMsg(id, requiresAccept, requiresSync);
+ if (session->scheduledCompleterContext->scheduleCompletion(id))
+ session->getConnection().requestIOProcessing(boost::bind(&scheduledCompleter,
+ session->scheduledCompleterContext));
+ } else { // command is being completed in IO thread.
+ // this path runs only on the IO thread.
+ qpid::sys::ScopedLock<Mutex> l(session->incompleteCmdsLock);
+ std::map<SequenceNumber, boost::shared_ptr<IncompleteCommandContext> >::iterator cmd;
+ cmd = session->incompleteCmds.find(id);
+ if (cmd != session->incompleteCmds.end()) {
+ boost::shared_ptr<IncompleteCommandContext> tmp(cmd->second);
+ session->incompleteCmds.erase(cmd);
+
+ if (session->isAttached()) {
+ QPID_LOG(debug, ": receive completed for msg seq=" << id);
+ qpid::sys::ScopedUnlock<Mutex> ul(session->incompleteCmdsLock);
+ session->completeRcvMsg(id, requiresAccept, requiresSync);
+ return;
+ }
}
}
- completerContext = boost::intrusive_ptr<AsyncCommandCompleter>();
}
-/** Scheduled from an asynchronous command's completed callback to run on
- * the IO thread.
+/** Scheduled from incomplete command's completed callback, safely completes all
+ * completed commands in the IO Thread. Guaranteed not to be running at the same
+ * time as the message receive code.
*/
-void SessionState::AsyncCommandCompleter::schedule(boost::intrusive_ptr<AsyncCommandCompleter> ctxt)
+void SessionState::scheduledCompleter(boost::shared_ptr<SessionState::ScheduledCompleterContext> ctxt)
{
ctxt->completeCommands();
}
-/** Track an ingress message that is pending completion */
-void SessionState::AsyncCommandCompleter::addPendingMessage(boost::intrusive_ptr<Message> msg)
-{
- qpid::sys::ScopedLock<qpid::sys::Mutex> l(completerLock);
- std::pair<SequenceNumber, boost::intrusive_ptr<Message> > item(msg->getCommandId(), msg);
- bool unique = pendingMsgs.insert(item).second;
- if (!unique) {
- assert(false);
- }
-}
-
-
-/** pending message has completed */
-void SessionState::AsyncCommandCompleter::deletePendingMessage(SequenceNumber id)
-{
- qpid::sys::ScopedLock<qpid::sys::Mutex> l(completerLock);
- pendingMsgs.erase(id);
-}
-
-
-/** done when an execution.sync arrives */
-void SessionState::AsyncCommandCompleter::flushPendingMessages()
-{
- std::map<SequenceNumber, boost::intrusive_ptr<Message> > copy;
- {
- qpid::sys::ScopedLock<qpid::sys::Mutex> l(completerLock);
- pendingMsgs.swap(copy); // we've only tracked these in case a flush is needed, so nuke 'em now.
- }
- // drop lock, so it is safe to call "flush()"
- for (std::map<SequenceNumber, boost::intrusive_ptr<Message> >::iterator i = copy.begin();
- i != copy.end(); ++i) {
- i->second->flush();
- }
-}
-
-
-/** mark an ingress Message.Transfer command as completed.
- * This method must be thread safe - it may run on any thread.
+/** mark a command (sequence) as completed, return True if caller should
+ * schedule a call to completeCommands()
*/
-void SessionState::AsyncCommandCompleter::scheduleMsgCompletion(SequenceNumber cmd,
- bool requiresAccept,
- bool requiresSync)
+bool SessionState::ScheduledCompleterContext::scheduleCompletion(SequenceNumber cmd)
{
- qpid::sys::ScopedLock<qpid::sys::Mutex> l(completerLock);
-
- if (session && isAttached) {
- MessageInfo msg(cmd, requiresAccept, requiresSync);
- completedMsgs.push_back(msg);
- if (completedMsgs.size() == 1) {
- session->getConnection().requestIOProcessing(boost::bind(&schedule,
- session->asyncCommandCompleter));
- }
- }
+ qpid::sys::ScopedLock<qpid::sys::Mutex> l(completedCmdsLock);
+
+ completedCmds.push_back(cmd);
+ return (completedCmds.size() == 1);
}
-/** Cause the session to complete all completed commands.
- * Executes on the IO thread.
- */
-void SessionState::AsyncCommandCompleter::completeCommands()
+/** Cause the session to complete all completed commands */
+void SessionState::ScheduledCompleterContext::completeCommands()
{
- qpid::sys::ScopedLock<qpid::sys::Mutex> l(completerLock);
+ qpid::sys::ScopedLock<qpid::sys::Mutex> l(completedCmdsLock);
// when session is destroyed, it clears the session pointer via cancel().
- if (session && session->isAttached()) {
- for (std::vector<MessageInfo>::iterator msg = completedMsgs.begin();
- msg != completedMsgs.end(); ++msg) {
- session->completeRcvMsg(msg->cmd, msg->requiresAccept, msg->requiresSync);
+ if (!session) return;
+
+ while (!completedCmds.empty()) {
+ SequenceNumber id = completedCmds.front();
+ completedCmds.pop_front();
+ std::map<SequenceNumber, boost::shared_ptr<IncompleteCommandContext> >::iterator cmd;
+ {
+ qpid::sys::ScopedLock<qpid::sys::Mutex> l(session->incompleteCmdsLock);
+
+ cmd = session->incompleteCmds.find(id);
+ if (cmd !=session->incompleteCmds.end()) {
+ boost::shared_ptr<IncompleteCommandContext> tmp(cmd->second);
+ {
+ qpid::sys::ScopedUnlock<qpid::sys::Mutex> ul(session->incompleteCmdsLock);
+ tmp->do_completion(); // retakes incompleteCmdslock
+ }
+ }
}
}
- completedMsgs.clear();
}
/** cancel any pending calls to scheduleComplete */
-void SessionState::AsyncCommandCompleter::cancel()
+void SessionState::ScheduledCompleterContext::cancel()
{
- qpid::sys::ScopedLock<qpid::sys::Mutex> l(completerLock);
+ qpid::sys::ScopedLock<qpid::sys::Mutex> l(completedCmdsLock);
session = 0;
}
-
-/** inform the completer that the session has attached,
- * allows command completion scheduling from any thread */
-void SessionState::AsyncCommandCompleter::attached()
-{
- qpid::sys::ScopedLock<qpid::sys::Mutex> l(completerLock);
- isAttached = true;
-}
-
-
-/** inform the completer that the session has detached,
- * disables command completion scheduling from any thread */
-void SessionState::AsyncCommandCompleter::detached()
-{
- qpid::sys::ScopedLock<qpid::sys::Mutex> l(completerLock);
- isAttached = false;
-}
-
}} // namespace qpid::broker
diff --git a/qpid/cpp/src/qpid/broker/SessionState.h b/qpid/cpp/src/qpid/broker/SessionState.h
index 506af85c47..5e162e6475 100644
--- a/qpid/cpp/src/qpid/broker/SessionState.h
+++ b/qpid/cpp/src/qpid/broker/SessionState.h
@@ -38,7 +38,6 @@
#include <boost/noncopyable.hpp>
#include <boost/scoped_ptr.hpp>
-#include <boost/intrusive_ptr.hpp>
#include <set>
#include <vector>
@@ -177,105 +176,79 @@ class SessionState : public qpid::SessionState,
std::queue<SequenceNumber> pendingExecutionSyncs;
bool currentCommandComplete;
- /** This class provides a context for completing asynchronous commands in a thread
- * safe manner. Asynchronous commands save their completion state in this class.
- * This class then schedules the completeCommands() method in the IO thread.
- * While running in the IO thread, completeCommands() may safely complete all
- * saved commands without the risk of colliding with other operations on this
- * SessionState.
+ /** Abstract class that represents a command that is pending
+ * completion.
*/
- class AsyncCommandCompleter : public RefCounted {
- private:
- SessionState *session;
- bool isAttached;
- qpid::sys::Mutex completerLock;
-
- // special-case message.transfer commands for optimization
- struct MessageInfo {
- SequenceNumber cmd; // message.transfer command id
- bool requiresAccept;
- bool requiresSync;
- MessageInfo(SequenceNumber c, bool a, bool s)
- : cmd(c), requiresAccept(a), requiresSync(s) {}
- };
- std::vector<MessageInfo> completedMsgs;
- // If an ingress message does not require a Sync, we need to
- // hold a reference to it in case an Execution.Sync command is received and we
- // have to manually flush the message.
- std::map<SequenceNumber, boost::intrusive_ptr<Message> > pendingMsgs;
-
- /** complete all pending commands, runs in IO thread */
- void completeCommands();
-
- /** for scheduling a run of "completeCommands()" on the IO thread */
- static void schedule(boost::intrusive_ptr<AsyncCommandCompleter>);
-
- public:
- AsyncCommandCompleter(SessionState *s) : session(s), isAttached(s->isAttached()) {};
- ~AsyncCommandCompleter() {};
-
- /** track a message pending ingress completion */
- void addPendingMessage(boost::intrusive_ptr<Message> m);
- void deletePendingMessage(SequenceNumber id);
- void flushPendingMessages();
- /** schedule the processing of a completed ingress message.transfer command */
- void scheduleMsgCompletion(SequenceNumber cmd,
- bool requiresAccept,
- bool requiresSync);
- void cancel(); // called by SessionState destructor.
- void attached(); // called by SessionState on attach()
- void detached(); // called by SessionState on detach()
- };
- boost::intrusive_ptr<AsyncCommandCompleter> asyncCommandCompleter;
-
- /** Abstract class that represents a single asynchronous command that is
- * pending completion.
- */
- class AsyncCommandContext : public AsyncCompletion::Callback
+ class IncompleteCommandContext : public AsyncCompletion
{
public:
- AsyncCommandContext( SessionState *ss, SequenceNumber _id )
- : id(_id), completerContext(ss->asyncCommandCompleter) {}
- virtual ~AsyncCommandContext() {}
+ IncompleteCommandContext( SessionState *ss, SequenceNumber _id )
+ : id(_id), session(ss) {}
+ virtual ~IncompleteCommandContext() {}
+
+ /* allows manual invokation of completion, used by IO thread to
+ * complete a command that was originally finished on a different
+ * thread.
+ */
+ void do_completion() { completed(true); }
protected:
SequenceNumber id;
- boost::intrusive_ptr<AsyncCommandCompleter> completerContext;
+ SessionState *session;
};
/** incomplete Message.transfer commands - inbound to broker from client
*/
- class IncompleteIngressMsgXfer : public SessionState::AsyncCommandContext
+ class IncompleteIngressMsgXfer : public SessionState::IncompleteCommandContext
{
public:
IncompleteIngressMsgXfer( SessionState *ss,
- boost::intrusive_ptr<Message> m )
- : AsyncCommandContext(ss, m->getCommandId()),
- session(ss),
- msg(m),
- requiresAccept(m->requiresAccept()),
- requiresSync(m->getFrames().getMethod()->isSync()),
- pending(false) {}
- IncompleteIngressMsgXfer( const IncompleteIngressMsgXfer& x )
- : AsyncCommandContext(x.session, x.msg->getCommandId()),
- session(x.session),
- msg(x.msg),
- requiresAccept(x.requiresAccept),
- requiresSync(x.requiresSync),
- pending(x.pending) {}
-
- virtual ~IncompleteIngressMsgXfer() {};
+ SequenceNumber _id,
+ boost::intrusive_ptr<Message> msg )
+ : IncompleteCommandContext(ss, _id),
+ requiresAccept(msg->requiresAccept()),
+ requiresSync(msg->getFrames().getMethod()->isSync()) {};
+ virtual ~IncompleteIngressMsgXfer() {};
+ protected:
virtual void completed(bool);
- virtual boost::intrusive_ptr<AsyncCompletion::Callback> clone();
private:
- SessionState *session; // only valid if sync flag in callback is true
- boost::intrusive_ptr<Message> msg;
+ /** meta-info required to complete the message */
bool requiresAccept;
- bool requiresSync;
- bool pending; // true if msg saved on pending list...
+ bool requiresSync; // method's isSync() flag
};
+ /** creates a command context suitable for use as an AsyncCompletion in a message */
+ boost::shared_ptr<SessionState::IncompleteIngressMsgXfer> createIngressMsgXferContext( boost::intrusive_ptr<Message> msg);
+
+ /* A list of commands that are pending completion. These commands are
+ * awaiting some set of asynchronous operations to finish (eg: store,
+ * flow-control, etc). before the command can be completed to the client
+ */
+ std::map<SequenceNumber, boost::shared_ptr<IncompleteCommandContext> > incompleteCmds;
+ qpid::sys::Mutex incompleteCmdsLock; // locks above container
+
+ /** This context is shared between the SessionState and scheduledCompleter,
+ * holds the sequence numbers of all commands that have completed asynchronously.
+ */
+ class ScheduledCompleterContext {
+ private:
+ std::list<SequenceNumber> completedCmds;
+ // ordering: take this lock first, then incompleteCmdsLock
+ qpid::sys::Mutex completedCmdsLock;
+ SessionState *session;
+ public:
+ ScheduledCompleterContext(SessionState *s) : session(s) {};
+ bool scheduleCompletion(SequenceNumber cmd);
+ void completeCommands();
+ void cancel();
+ };
+ boost::shared_ptr<ScheduledCompleterContext> scheduledCompleterContext;
+
+ /** The following method runs the in IO thread and completes commands that
+ * where finished asynchronously.
+ */
+ static void scheduledCompleter(boost::shared_ptr<ScheduledCompleterContext>);
friend class SessionManager;
};
diff --git a/qpid/cpp/src/qpid/broker/StatefulQueueObserver.h b/qpid/cpp/src/qpid/broker/StatefulQueueObserver.h
deleted file mode 100644
index c682d460b7..0000000000
--- a/qpid/cpp/src/qpid/broker/StatefulQueueObserver.h
+++ /dev/null
@@ -1,63 +0,0 @@
-#ifndef QPID_BROKER_STATEFULQUEUEOBSERVER_H
-#define QPID_BROKER_STATEFULQUEUEOBSERVER_H
-
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
- */
-#include "qpid/broker/QueueObserver.h"
-#include "qpid/framing/FieldTable.h"
-
-namespace qpid {
-namespace broker {
-
-/**
- * Specialized type of QueueObserver that maintains internal state that has to
- * be replicated across clustered brokers.
- */
-class StatefulQueueObserver : public QueueObserver
-{
- public:
- StatefulQueueObserver(std::string _id) : id(_id) {}
- virtual ~StatefulQueueObserver() {}
-
- /** This identifier must uniquely identify this particular observer amoung
- * all observers on a queue. For cluster replication, this id will be used
- * to identify the peer queue observer for synchronization across
- * brokers.
- */
- const std::string& getId() const { return id; }
-
- /** This method should return the observer's internal state as an opaque
- * map.
- */
- virtual void getState(qpid::framing::FieldTable& state ) const = 0;
-
- /** The input map represents the internal state of the peer observer that
- * this observer should synchonize to.
- */
- virtual void setState(const qpid::framing::FieldTable&) = 0;
-
-
- private:
- std::string id;
-};
-}} // namespace qpid::broker
-
-#endif /*!QPID_BROKER_STATEFULQUEUEOBSERVER_H*/
diff --git a/qpid/cpp/src/qpid/broker/ThresholdAlerts.cpp b/qpid/cpp/src/qpid/broker/ThresholdAlerts.cpp
index 3c9e210d4d..4f35884af8 100644
--- a/qpid/cpp/src/qpid/broker/ThresholdAlerts.cpp
+++ b/qpid/cpp/src/qpid/broker/ThresholdAlerts.cpp
@@ -28,52 +28,6 @@
namespace qpid {
namespace broker {
-namespace {
-const qmf::org::apache::qpid::broker::EventQueueThresholdExceeded EVENT("dummy", 0, 0);
-bool isQMFv2(const boost::intrusive_ptr<Message> message)
-{
- const qpid::framing::MessageProperties* props = message->getProperties<qpid::framing::MessageProperties>();
- return props && props->getAppId() == "qmf2";
-}
-
-bool isThresholdEvent(const boost::intrusive_ptr<Message> message)
-{
- if (message->getIsManagementMessage()) {
- //is this a qmf event? if so is it a threshold event?
- if (isQMFv2(message)) {
- const qpid::framing::FieldTable* headers = message->getApplicationHeaders();
- if (headers && headers->getAsString("qmf.content") == "_event") {
- //decode as list
- std::string content = message->getFrames().getContent();
- qpid::types::Variant::List list;
- qpid::amqp_0_10::ListCodec::decode(content, list);
- if (list.empty() || list.front().getType() != qpid::types::VAR_MAP) return false;
- qpid::types::Variant::Map map = list.front().asMap();
- try {
- std::string eventName = map["_schema_id"].asMap()["_class_name"].asString();
- return eventName == EVENT.getEventName();
- } catch (const std::exception& e) {
- QPID_LOG(error, "Error checking for recursive threshold alert: " << e.what());
- }
- }
- } else {
- std::string content = message->getFrames().getContent();
- qpid::framing::Buffer buffer(const_cast<char*>(content.data()), content.size());
- if (buffer.getOctet() == 'A' && buffer.getOctet() == 'M' && buffer.getOctet() == '2' && buffer.getOctet() == 'e') {
- buffer.getLong();//sequence
- std::string packageName;
- buffer.getShortString(packageName);
- if (packageName != EVENT.getPackageName()) return false;
- std::string eventName;
- buffer.getShortString(eventName);
- return eventName == EVENT.getEventName();
- }
- }
- }
- return false;
-}
-}
-
ThresholdAlerts::ThresholdAlerts(const std::string& n,
qpid::management::ManagementAgent& a,
const uint32_t ct,
@@ -90,14 +44,8 @@ void ThresholdAlerts::enqueued(const QueuedMessage& m)
if ((countThreshold && count >= countThreshold) || (sizeThreshold && size >= sizeThreshold)) {
if ((repeatInterval == 0 && lastAlert == qpid::sys::EPOCH)
|| qpid::sys::Duration(lastAlert, qpid::sys::now()) > repeatInterval) {
- //Note: Raising an event may result in messages being
- //enqueued on queues; it may even be that this event
- //causes a message to be enqueued on the queue we are
- //tracking, and so we need to avoid recursing
- if (isThresholdEvent(m.payload)) return;
- lastAlert = qpid::sys::now();
agent.raiseEvent(qmf::org::apache::qpid::broker::EventQueueThresholdExceeded(name, count, size));
- QPID_LOG(info, "Threshold event triggered for " << name << ", count=" << count << ", size=" << size);
+ lastAlert = qpid::sys::now();
}
}
}
@@ -127,12 +75,12 @@ void ThresholdAlerts::observe(Queue& queue, qpid::management::ManagementAgent& a
}
void ThresholdAlerts::observe(Queue& queue, qpid::management::ManagementAgent& agent,
- const qpid::framing::FieldTable& settings, uint16_t limitRatio)
+ const qpid::framing::FieldTable& settings)
{
qpid::types::Variant::Map map;
qpid::amqp_0_10::translate(settings, map);
- observe(queue, agent, map, limitRatio);
+ observe(queue, agent, map);
}
template <class T>
@@ -170,19 +118,19 @@ class Option
};
void ThresholdAlerts::observe(Queue& queue, qpid::management::ManagementAgent& agent,
- const qpid::types::Variant::Map& settings, uint16_t limitRatio)
+ const qpid::types::Variant::Map& settings)
{
//Note: aliases are keys defined by java broker
Option<int64_t> repeatInterval("qpid.alert_repeat_gap", 60);
repeatInterval.addAlias("x-qpid-minimum-alert-repeat-gap");
- //If no explicit threshold settings were given use specified
- //percentage of any limit from the policy.
+ //If no explicit threshold settings were given use 80% of any
+ //limit from the policy.
const QueuePolicy* policy = queue.getPolicy();
- Option<uint32_t> countThreshold("qpid.alert_count", (uint32_t) (policy && limitRatio ? (policy->getMaxCount()*limitRatio/100) : 0));
+ Option<uint32_t> countThreshold("qpid.alert_count", (uint32_t) (policy ? policy->getMaxCount()*0.8 : 0));
countThreshold.addAlias("x-qpid-maximum-message-count");
- Option<uint64_t> sizeThreshold("qpid.alert_size", (uint64_t) (policy && limitRatio ? (policy->getMaxSize()*limitRatio/100) : 0));
+ Option<uint64_t> sizeThreshold("qpid.alert_size", (uint64_t) (policy ? policy->getMaxSize()*0.8 : 0));
sizeThreshold.addAlias("x-qpid-maximum-message-size");
observe(queue, agent, countThreshold.get(settings), sizeThreshold.get(settings), repeatInterval.get(settings));
diff --git a/qpid/cpp/src/qpid/broker/ThresholdAlerts.h b/qpid/cpp/src/qpid/broker/ThresholdAlerts.h
index c77722e700..e1f59252c4 100644
--- a/qpid/cpp/src/qpid/broker/ThresholdAlerts.h
+++ b/qpid/cpp/src/qpid/broker/ThresholdAlerts.h
@@ -55,9 +55,9 @@ class ThresholdAlerts : public QueueObserver
const uint64_t sizeThreshold,
const long repeatInterval);
static void observe(Queue& queue, qpid::management::ManagementAgent& agent,
- const qpid::framing::FieldTable& settings, uint16_t limitRatio);
+ const qpid::framing::FieldTable& settings);
static void observe(Queue& queue, qpid::management::ManagementAgent& agent,
- const qpid::types::Variant::Map& settings, uint16_t limitRatio);
+ const qpid::types::Variant::Map& settings);
private:
const std::string name;
qpid::management::ManagementAgent& agent;
diff --git a/qpid/cpp/src/qpid/broker/TopicExchange.cpp b/qpid/cpp/src/qpid/broker/TopicExchange.cpp
index 644a3d628e..1b0fe71bcf 100644
--- a/qpid/cpp/src/qpid/broker/TopicExchange.cpp
+++ b/qpid/cpp/src/qpid/broker/TopicExchange.cpp
@@ -221,7 +221,6 @@ TopicExchange::TopicExchange(const std::string& _name, bool _durable,
bool TopicExchange::bind(Queue::shared_ptr queue, const string& routingKey, const FieldTable* args)
{
- ClearCache cc(&cacheLock,&bindingCache); // clear the cache on function exit.
string fedOp(args ? args->getAsString(qpidFedOp) : fedOpBind);
string fedTags(args ? args->getAsString(qpidFedTags) : "");
string fedOrigin(args ? args->getAsString(qpidFedOrigin) : "");
@@ -250,21 +249,21 @@ bool TopicExchange::bind(Queue::shared_ptr queue, const string& routingKey, cons
if (mgmtExchange != 0) {
mgmtExchange->inc_bindingCount();
}
- QPID_LOG(debug, "Binding key [" << routingPattern << "] to queue " << queue->getName()
- << " on exchange " << getName() << " (origin=" << fedOrigin << ")");
+ QPID_LOG(debug, "Bound key [" << routingPattern << "] to queue " << queue->getName()
+ << " (origin=" << fedOrigin << ")");
}
} else if (fedOp == fedOpUnbind) {
- RWlock::ScopedWlock l(lock);
- BindingKey* bk = getQueueBinding(queue, routingPattern);
- if (bk) {
- QPID_LOG(debug, "FedOpUnbind [" << routingPattern << "] from exchange " << getName()
- << " on queue=" << queue->getName() << " origin=" << fedOrigin);
- propagate = bk->fedBinding.delOrigin(queue->getName(), fedOrigin);
- // if this was the last binding for the queue, delete the binding
- if (bk->fedBinding.countFedBindings(queue->getName()) == 0) {
- deleteBinding(queue, routingPattern, bk);
+ bool reallyUnbind = false;
+ {
+ RWlock::ScopedWlock l(lock);
+ BindingKey* bk = bindingTree.getBindingKey(routingPattern);
+ if (bk) {
+ propagate = bk->fedBinding.delOrigin(queue->getName(), fedOrigin);
+ reallyUnbind = bk->fedBinding.countFedBindings(queue->getName()) == 0;
}
}
+ if (reallyUnbind)
+ unbind(queue, routingPattern, 0);
} else if (fedOp == fedOpReorigin) {
/** gather up all the keys that need rebinding in a local vector
* while holding the lock. Then propagate once the lock is
@@ -282,38 +281,20 @@ bool TopicExchange::bind(Queue::shared_ptr queue, const string& routingKey, cons
}
}
- cc.clearCache(); // clear the cache before we IVE route.
routeIVE();
if (propagate)
propagateFedOp(routingKey, fedTags, fedOp, fedOrigin);
return true;
}
-bool TopicExchange::unbind(Queue::shared_ptr queue, const string& constRoutingKey, const FieldTable* args)
-{
- string fedOrigin(args ? args->getAsString(qpidFedOrigin) : "");
- QPID_LOG(debug, "Unbinding key [" << constRoutingKey << "] from queue " << queue->getName()
- << " on exchange " << getName() << " origin=" << fedOrigin << ")" );
-
- ClearCache cc(&cacheLock,&bindingCache); // clear the cache on function exit.
+bool TopicExchange::unbind(Queue::shared_ptr queue, const string& constRoutingKey, const FieldTable* /*args*/){
RWlock::ScopedWlock l(lock);
string routingKey = normalize(constRoutingKey);
- BindingKey* bk = getQueueBinding(queue, routingKey);
+ BindingKey* bk = bindingTree.getBindingKey(routingKey);
if (!bk) return false;
- bool propagate = bk->fedBinding.delOrigin(queue->getName(), fedOrigin);
- deleteBinding(queue, routingKey, bk);
- if (propagate)
- propagateFedOp(routingKey, string(), fedOpUnbind, string());
- return true;
-}
-
-
-bool TopicExchange::deleteBinding(Queue::shared_ptr queue,
- const std::string& routingKey,
- BindingKey *bk)
-{
- // Note well: write lock held by caller
Binding::vector& qv(bk->bindingVector);
+ bool propagate = false;
+
Binding::vector::iterator q;
for (q = qv.begin(); q != qv.end(); q++)
if ((*q)->queue == queue)
@@ -322,55 +303,42 @@ bool TopicExchange::deleteBinding(Queue::shared_ptr queue,
qv.erase(q);
assert(nBindings > 0);
nBindings--;
-
+ propagate = bk->fedBinding.delOrigin();
if(qv.empty()) {
bindingTree.removeBindingKey(routingKey);
}
if (mgmtExchange != 0) {
mgmtExchange->dec_bindingCount();
}
- QPID_LOG(debug, "Unbound key [" << routingKey << "] from queue " << queue->getName()
- << " on exchange " << getName());
+ QPID_LOG(debug, "Unbound [" << routingKey << "] from queue " << queue->getName());
+
+ if (propagate)
+ propagateFedOp(routingKey, string(), fedOpUnbind, string());
return true;
}
-/** returns a pointer to the BindingKey if the given queue is bound to this
- * exchange using the routing pattern. 0 if queue binding does not exist.
- */
-TopicExchange::BindingKey *TopicExchange::getQueueBinding(Queue::shared_ptr queue, const string& pattern)
+bool TopicExchange::isBound(Queue::shared_ptr queue, const string& pattern)
{
// Note well: lock held by caller....
BindingKey *bk = bindingTree.getBindingKey(pattern); // Exact match against binding pattern
- if (!bk) return 0;
+ if (!bk) return false;
Binding::vector& qv(bk->bindingVector);
Binding::vector::iterator q;
for (q = qv.begin(); q != qv.end(); q++)
if ((*q)->queue == queue)
break;
- return (q != qv.end()) ? bk : 0;
+ return q != qv.end();
}
void TopicExchange::route(Deliverable& msg, const string& routingKey, const FieldTable* /*args*/)
{
// Note: PERFORMANCE CRITICAL!!!
- BindingList b;
- std::map<std::string, BindingList>::iterator it;
- { // only lock the cache for read
- RWlock::ScopedRlock cl(cacheLock);
- it = bindingCache.find(routingKey);
- if (it != bindingCache.end()) {
- b = it->second;
- }
- }
+ BindingList b(new std::vector<boost::shared_ptr<qpid::broker::Exchange::Binding> >);
PreRoute pr(msg, this);
- if (!b.get()) // no cache hit
+ BindingsFinderIter bindingsFinder(b);
{
RWlock::ScopedRlock l(lock);
- b = BindingList(new std::vector<boost::shared_ptr<qpid::broker::Exchange::Binding> >);
- BindingsFinderIter bindingsFinder(b);
bindingTree.iterateMatch(routingKey, bindingsFinder);
- RWlock::ScopedWlock cwl(cacheLock);
- bindingCache[routingKey] = b; // update cache
}
doRoute(msg, b);
}
@@ -380,7 +348,7 @@ bool TopicExchange::isBound(Queue::shared_ptr queue, const string* const routing
RWlock::ScopedRlock l(lock);
if (routingKey && queue) {
string key(normalize(*routingKey));
- return getQueueBinding(queue, key) != 0;
+ return isBound(queue, key);
} else if (!routingKey && !queue) {
return nBindings > 0;
} else if (routingKey) {
diff --git a/qpid/cpp/src/qpid/broker/TopicExchange.h b/qpid/cpp/src/qpid/broker/TopicExchange.h
index 636918f8a1..a6c457dcb3 100644
--- a/qpid/cpp/src/qpid/broker/TopicExchange.h
+++ b/qpid/cpp/src/qpid/broker/TopicExchange.h
@@ -56,7 +56,7 @@ class TopicExchange : public virtual Exchange {
// | +-->d-->...
// +-->x-->y-->...
//
- class QPID_BROKER_CLASS_EXTERN BindingNode {
+ class BindingNode {
public:
typedef boost::shared_ptr<BindingNode> shared_ptr;
@@ -135,31 +135,8 @@ class TopicExchange : public virtual Exchange {
BindingNode bindingTree;
unsigned long nBindings;
qpid::sys::RWlock lock; // protects bindingTree and nBindings
- qpid::sys::RWlock cacheLock; // protects cache
- std::map<std::string, BindingList> bindingCache; // cache of matched routes.
- class ClearCache {
- private:
- qpid::sys::RWlock* cacheLock;
- std::map<std::string, BindingList>* bindingCache;
- bool cleared;
- public:
- ClearCache(qpid::sys::RWlock* l, std::map<std::string, BindingList>* bc): cacheLock(l),
- bindingCache(bc),cleared(false) {};
- void clearCache() {
- qpid::sys::RWlock::ScopedWlock l(*cacheLock);
- if (!cleared) {
- bindingCache->clear();
- cleared =true;
- }
- };
- ~ClearCache(){
- clearCache();
- };
- };
- BindingKey *getQueueBinding(Queue::shared_ptr queue, const std::string& pattern);
- bool deleteBinding(Queue::shared_ptr queue,
- const std::string& routingKey,
- BindingKey *bk);
+
+ bool isBound(Queue::shared_ptr queue, const std::string& pattern);
class ReOriginIter;
class BindingsFinderIter;
diff --git a/qpid/cpp/src/qpid/broker/TxPublish.cpp b/qpid/cpp/src/qpid/broker/TxPublish.cpp
index 9c2cf4a467..36a451e62c 100644
--- a/qpid/cpp/src/qpid/broker/TxPublish.cpp
+++ b/qpid/cpp/src/qpid/broker/TxPublish.cpp
@@ -90,7 +90,14 @@ void TxPublish::deliverTo(const boost::shared_ptr<Queue>& queue){
void TxPublish::prepare(TransactionContext* ctxt, const boost::shared_ptr<Queue> queue)
{
- queue->enqueue(ctxt, msg);
+ if (!queue->enqueue(ctxt, msg)){
+ /**
+ * if not store then mark message for ack and deleivery once
+ * commit happens, as async IO will never set it when no store
+ * exists
+ */
+ msg->enqueueComplete();
+ }
}
TxPublish::Commit::Commit(intrusive_ptr<Message>& _msg) : msg(_msg){}
diff --git a/qpid/cpp/src/qpid/broker/TxPublish.h b/qpid/cpp/src/qpid/broker/TxPublish.h
index f0b9c0a302..effa585676 100644
--- a/qpid/cpp/src/qpid/broker/TxPublish.h
+++ b/qpid/cpp/src/qpid/broker/TxPublish.h
@@ -45,7 +45,7 @@ namespace qpid {
* commit() the messages will be passed to the queue for
* dispatch or to be added to the in-memory queue.
*/
- class QPID_BROKER_CLASS_EXTERN TxPublish : public TxOp, public Deliverable{
+ class TxPublish : public TxOp, public Deliverable{
class Commit{
boost::intrusive_ptr<Message>& msg;
diff --git a/qpid/cpp/src/qpid/broker/windows/BrokerDefaults.cpp b/qpid/cpp/src/qpid/broker/windows/BrokerDefaults.cpp
index b65440b5ad..b6862f0418 100644
--- a/qpid/cpp/src/qpid/broker/windows/BrokerDefaults.cpp
+++ b/qpid/cpp/src/qpid/broker/windows/BrokerDefaults.cpp
@@ -31,16 +31,10 @@ const std::string Broker::Options::DEFAULT_DATA_DIR_NAME("\\QPIDD.DATA");
std::string
Broker::Options::getHome() {
std::string home;
-#ifdef _MSC_VER
char home_c[MAX_PATH+1];
size_t unused;
if (0 == getenv_s (&unused, home_c, sizeof(home_c), "HOME"))
home += home_c;
-#else
- char *home_c = getenv("HOME");
- if (home_c)
- home += home_c;
-#endif
return home;
}
diff --git a/qpid/cpp/src/qpid/broker/windows/SaslAuthenticator.cpp b/qpid/cpp/src/qpid/broker/windows/SaslAuthenticator.cpp
index d26b370632..608a8f7dae 100644
--- a/qpid/cpp/src/qpid/broker/windows/SaslAuthenticator.cpp
+++ b/qpid/cpp/src/qpid/broker/windows/SaslAuthenticator.cpp
@@ -93,7 +93,6 @@ 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")));
}
void NullAuthenticator::start(const string& mechanism, const string& response)
@@ -160,11 +159,8 @@ void SspiAuthenticator::start(const string& mechanism, const string& response)
string::size_type j = response.find((char)0, i+1);
string uid = response.substr(i+1, j-1);
string pwd = response.substr(j+1);
- string dot(".");
int error = 0;
- if (!LogonUser(const_cast<char*>(uid.c_str()),
- const_cast<char*>(dot.c_str()),
- const_cast<char*>(pwd.c_str()),
+ if (!LogonUser(uid.c_str(), ".", pwd.c_str(),
LOGON32_LOGON_NETWORK,
LOGON32_PROVIDER_DEFAULT,
&userToken))
@@ -180,7 +176,7 @@ void SspiAuthenticator::start(const string& mechanism, const string& response)
client.tune(framing::CHANNEL_MAX, connection.getFrameMax(), 0, 0);
}
-void SspiAuthenticator::step(const string& /*response*/)
+void SspiAuthenticator::step(const string& response)
{
QPID_LOG(info, "SASL: Need another step!!!");
}
diff --git a/qpid/cpp/src/qpid/broker/windows/SslProtocolFactory.cpp b/qpid/cpp/src/qpid/broker/windows/SslProtocolFactory.cpp
index 676074a590..fd0e537192 100644
--- a/qpid/cpp/src/qpid/broker/windows/SslProtocolFactory.cpp
+++ b/qpid/cpp/src/qpid/broker/windows/SslProtocolFactory.cpp
@@ -81,11 +81,12 @@ class SslProtocolFactory : public qpid::sys::ProtocolFactory {
SslProtocolFactory(const SslServerOptions&, int backlog, bool nodelay);
~SslProtocolFactory();
void accept(sys::Poller::shared_ptr, sys::ConnectionCodec::Factory*);
- void connect(sys::Poller::shared_ptr, const std::string& host, const std::string& port,
+ void connect(sys::Poller::shared_ptr, const std::string& host, int16_t port,
sys::ConnectionCodec::Factory*,
ConnectFailedCallback failed);
uint16_t getPort() const;
+ std::string getHost() const;
bool supports(const std::string& capability);
private:
@@ -129,7 +130,7 @@ SslProtocolFactory::SslProtocolFactory(const SslServerOptions& options,
int backlog,
bool nodelay)
: tcpNoDelay(nodelay),
- listeningPort(listener.listen("", boost::lexical_cast<std::string>(options.port), backlog)),
+ listeningPort(listener.listen(options.port, backlog)),
clientAuthSelected(options.clientAuth) {
SecInvalidateHandle(&credHandle);
@@ -236,6 +237,10 @@ uint16_t SslProtocolFactory::getPort() const {
return listeningPort; // Immutable no need for lock.
}
+std::string SslProtocolFactory::getHost() const {
+ return listener.getSockname();
+}
+
void SslProtocolFactory::accept(sys::Poller::shared_ptr poller,
sys::ConnectionCodec::Factory* fact) {
acceptor.reset(
@@ -246,7 +251,7 @@ void SslProtocolFactory::accept(sys::Poller::shared_ptr poller,
void SslProtocolFactory::connect(sys::Poller::shared_ptr poller,
const std::string& host,
- const std::string& port,
+ int16_t port,
sys::ConnectionCodec::Factory* fact,
ConnectFailedCallback failed)
{
diff --git a/qpid/cpp/src/qpid/client/ConnectionHandler.cpp b/qpid/cpp/src/qpid/client/ConnectionHandler.cpp
index 801fe38051..8dc1e8338a 100644
--- a/qpid/cpp/src/qpid/client/ConnectionHandler.cpp
+++ b/qpid/cpp/src/qpid/client/ConnectionHandler.cpp
@@ -22,7 +22,6 @@
#include "qpid/client/ConnectionHandler.h"
#include "qpid/SaslFactory.h"
-#include "qpid/StringUtils.h"
#include "qpid/client/Bounds.h"
#include "qpid/framing/amqp_framing.h"
#include "qpid/framing/all_method_bodies.h"
@@ -143,9 +142,7 @@ void ConnectionHandler::outgoing(AMQFrame& frame)
void ConnectionHandler::waitForOpen()
{
waitFor(ESTABLISHED);
- if (getState() == FAILED) {
- throw TransportFailure(errorText);
- } else if (getState() == CLOSED) {
+ if (getState() == FAILED || getState() == CLOSED) {
throw ConnectionException(errorCode, errorText);
}
}
@@ -205,24 +202,6 @@ void ConnectionHandler::fail(const std::string& message)
namespace {
std::string SPACE(" ");
-
-std::string join(const std::vector<std::string>& in)
-{
- std::string result;
- for (std::vector<std::string>::const_iterator i = in.begin(); i != in.end(); ++i) {
- if (result.size()) result += SPACE;
- result += *i;
- }
- return result;
-}
-
-void intersection(const std::vector<std::string>& a, const std::vector<std::string>& b, std::vector<std::string>& results)
-{
- for (std::vector<std::string>::const_iterator i = a.begin(); i != a.end(); ++i) {
- if (std::find(b.begin(), b.end(), *i) != b.end()) results.push_back(*i);
- }
-}
-
}
void ConnectionHandler::start(const FieldTable& /*serverProps*/, const Array& mechanisms, const Array& /*locales*/)
@@ -237,24 +216,25 @@ void ConnectionHandler::start(const FieldTable& /*serverProps*/, const Array& me
maxSsf
);
- std::vector<std::string> mechlist;
- if (mechanism.empty()) {
- //mechlist is simply what the server offers
- mechanisms.collect(mechlist);
- } else {
- //mechlist is the intersection of those indicated by user and
- //those supported by server, in the order listed by user
- std::vector<std::string> allowed = split(mechanism, " ");
- std::vector<std::string> supported;
- mechanisms.collect(supported);
- intersection(allowed, supported, mechlist);
- if (mechlist.empty()) {
- throw Exception(QPID_MSG("Desired mechanism(s) not valid: " << mechanism << " (supported: " << join(supported) << ")"));
+ std::string mechlist;
+ bool chosenMechanismSupported = mechanism.empty();
+ for (Array::const_iterator i = mechanisms.begin(); i != mechanisms.end(); ++i) {
+ if (!mechanism.empty() && mechanism == (*i)->get<std::string>()) {
+ chosenMechanismSupported = true;
+ mechlist = (*i)->get<std::string>() + SPACE + mechlist;
+ } else {
+ if (i != mechanisms.begin()) mechlist += SPACE;
+ mechlist += (*i)->get<std::string>();
}
}
+ if (!chosenMechanismSupported) {
+ fail("Selected mechanism not supported: " + mechanism);
+ }
+
if (sasl.get()) {
- string response = sasl->start(join(mechlist), getSecuritySettings ? getSecuritySettings() : 0);
+ string response = sasl->start(mechanism.empty() ? mechlist : mechanism,
+ getSecuritySettings ? getSecuritySettings() : 0);
proxy.startOk(properties, sasl->getMechanism(), response, locale);
} else {
//TODO: verify that desired mechanism and locale are supported
diff --git a/qpid/cpp/src/qpid/client/ConnectionImpl.cpp b/qpid/cpp/src/qpid/client/ConnectionImpl.cpp
index db97f1e0f4..40c004f166 100644
--- a/qpid/cpp/src/qpid/client/ConnectionImpl.cpp
+++ b/qpid/cpp/src/qpid/client/ConnectionImpl.cpp
@@ -36,7 +36,6 @@
#include <boost/bind.hpp>
#include <boost/format.hpp>
-#include <boost/lexical_cast.hpp>
#include <boost/shared_ptr.hpp>
#include <limits>
@@ -259,16 +258,16 @@ void ConnectionImpl::open()
connector->setInputHandler(&handler);
connector->setShutdownHandler(this);
try {
- std::string p = boost::lexical_cast<std::string>(port);
- connector->connect(host, p);
-
+ connector->connect(host, port);
+
} catch (const std::exception& e) {
QPID_LOG(debug, "Failed to connect to " << protocol << ":" << host << ":" << port << " " << e.what());
connector.reset();
- throw TransportFailure(e.what());
+ throw;
}
connector->init();
-
+ QPID_LOG(info, *this << " connected to " << protocol << ":" << host << ":" << port);
+
// Enable heartbeat if requested
uint16_t heartbeat = static_cast<ConnectionSettings&>(handler).heartbeat;
if (heartbeat) {
@@ -282,7 +281,6 @@ void ConnectionImpl::open()
// - in that case in connector.reset() above;
// - or when we are deleted
handler.waitForOpen();
- QPID_LOG(info, *this << " connected to " << protocol << ":" << host << ":" << port);
// If the SASL layer has provided an "operational" userId for the connection,
// put it in the negotiated settings.
diff --git a/qpid/cpp/src/qpid/client/Connector.h b/qpid/cpp/src/qpid/client/Connector.h
index bc611ffe0d..586012f9d6 100644
--- a/qpid/cpp/src/qpid/client/Connector.h
+++ b/qpid/cpp/src/qpid/client/Connector.h
@@ -61,7 +61,7 @@ class Connector : public framing::OutputHandler
static void registerFactory(const std::string& proto, Factory* connectorFactory);
virtual ~Connector() {};
- virtual void connect(const std::string& host, const std::string& port) = 0;
+ virtual void connect(const std::string& host, int port) = 0;
virtual void init() {};
virtual void close() = 0;
virtual void send(framing::AMQFrame& frame) = 0;
diff --git a/qpid/cpp/src/qpid/client/RdmaConnector.cpp b/qpid/cpp/src/qpid/client/RdmaConnector.cpp
index 664640f5e7..6af607198c 100644
--- a/qpid/cpp/src/qpid/client/RdmaConnector.cpp
+++ b/qpid/cpp/src/qpid/client/RdmaConnector.cpp
@@ -95,7 +95,7 @@ class RdmaConnector : public Connector, public sys::Codec
std::string identifier;
- void connect(const std::string& host, const std::string& port);
+ void connect(const std::string& host, int port);
void close();
void send(framing::AMQFrame& frame);
void abort() {} // TODO: need to fix this for heartbeat timeouts to work
@@ -173,7 +173,7 @@ RdmaConnector::~RdmaConnector() {
}
}
-void RdmaConnector::connect(const std::string& host, const std::string& port){
+void RdmaConnector::connect(const std::string& host, int port){
Mutex::ScopedLock l(dataConnectedLock);
assert(!dataConnected);
@@ -184,7 +184,7 @@ void RdmaConnector::connect(const std::string& host, const std::string& port){
boost::bind(&RdmaConnector::disconnected, this),
boost::bind(&RdmaConnector::rejected, this, poller, _1, _2));
- SocketAddress sa(host, port);
+ SocketAddress sa(host, boost::lexical_cast<std::string>(port));
acon->start(poller, sa);
}
diff --git a/qpid/cpp/src/qpid/client/SessionImpl.cpp b/qpid/cpp/src/qpid/client/SessionImpl.cpp
index 7cf4ef648e..b507625b11 100644
--- a/qpid/cpp/src/qpid/client/SessionImpl.cpp
+++ b/qpid/cpp/src/qpid/client/SessionImpl.cpp
@@ -170,7 +170,6 @@ Demux& SessionImpl::getDemux()
void SessionImpl::waitForCompletion(const SequenceNumber& id)
{
Lock l(state);
- sys::Waitable::ScopedWait w(state);
waitForCompletionImpl(id);
}
diff --git a/qpid/cpp/src/qpid/client/SslConnector.cpp b/qpid/cpp/src/qpid/client/SslConnector.cpp
index 26c2335eda..35c7e6bdf6 100644
--- a/qpid/cpp/src/qpid/client/SslConnector.cpp
+++ b/qpid/cpp/src/qpid/client/SslConnector.cpp
@@ -114,7 +114,7 @@ class SslConnector : public Connector
std::string identifier;
- void connect(const std::string& host, const std::string& port);
+ void connect(const std::string& host, int port);
void init();
void close();
void send(framing::AMQFrame& frame);
@@ -190,14 +190,14 @@ SslConnector::~SslConnector() {
close();
}
-void SslConnector::connect(const std::string& host, const std::string& port){
+void SslConnector::connect(const std::string& host, int port){
Mutex::ScopedLock l(closedLock);
assert(closed);
try {
socket.connect(host, port);
} catch (const std::exception& e) {
socket.close();
- throw TransportFailure(e.what());
+ throw ConnectionException(framing::connection::CLOSE_CODE_FRAMING_ERROR, e.what());
}
identifier = str(format("[%1% %2%]") % socket.getLocalPort() % socket.getPeerAddress());
diff --git a/qpid/cpp/src/qpid/client/TCPConnector.cpp b/qpid/cpp/src/qpid/client/TCPConnector.cpp
index 0070b24ec0..e284d57bec 100644
--- a/qpid/cpp/src/qpid/client/TCPConnector.cpp
+++ b/qpid/cpp/src/qpid/client/TCPConnector.cpp
@@ -88,7 +88,7 @@ TCPConnector::~TCPConnector() {
close();
}
-void TCPConnector::connect(const std::string& host, const std::string& port) {
+void TCPConnector::connect(const std::string& host, int port) {
Mutex::ScopedLock l(lock);
assert(closed);
connector = AsynchConnector::create(
@@ -117,11 +117,11 @@ void TCPConnector::connected(const Socket&) {
void TCPConnector::start(sys::AsynchIO* aio_) {
aio = aio_;
- for (int i = 0; i < 4; i++) {
+ for (int i = 0; i < 32; i++) {
aio->queueReadBuffer(new Buff(maxFrameSize));
}
- identifier = str(format("[%1%]") % socket.getFullAddress());
+ identifier = str(format("[%1% %2%]") % socket.getLocalPort() % socket.getPeerAddress());
}
void TCPConnector::initAmqp() {
diff --git a/qpid/cpp/src/qpid/client/TCPConnector.h b/qpid/cpp/src/qpid/client/TCPConnector.h
index eb3f696013..c756469182 100644
--- a/qpid/cpp/src/qpid/client/TCPConnector.h
+++ b/qpid/cpp/src/qpid/client/TCPConnector.h
@@ -98,7 +98,7 @@ class TCPConnector : public Connector, public sys::Codec
protected:
virtual ~TCPConnector();
- void connect(const std::string& host, const std::string& port);
+ void connect(const std::string& host, int port);
void start(sys::AsynchIO* aio_);
void initAmqp();
virtual void connectFailed(const std::string& msg);
diff --git a/qpid/cpp/src/qpid/client/amqp0_10/AcceptTracker.cpp b/qpid/cpp/src/qpid/client/amqp0_10/AcceptTracker.cpp
index d2accddcd0..bfb20118b5 100644
--- a/qpid/cpp/src/qpid/client/amqp0_10/AcceptTracker.cpp
+++ b/qpid/cpp/src/qpid/client/amqp0_10/AcceptTracker.cpp
@@ -30,23 +30,12 @@ void AcceptTracker::State::accept()
unaccepted.clear();
}
-SequenceSet AcceptTracker::State::accept(qpid::framing::SequenceNumber id, bool cumulative)
+void AcceptTracker::State::accept(qpid::framing::SequenceNumber id)
{
- SequenceSet accepting;
- if (cumulative) {
- for (SequenceSet::iterator i = unaccepted.begin(); i != unaccepted.end() && *i <= id; ++i) {
- accepting.add(*i);
- }
- unconfirmed.add(accepting);
- unaccepted.remove(accepting);
- } else {
- if (unaccepted.contains(id)) {
- unaccepted.remove(id);
- unconfirmed.add(id);
- accepting.add(id);
- }
+ if (unaccepted.contains(id)) {
+ unaccepted.remove(id);
+ unconfirmed.add(id);
}
- return accepting;
}
void AcceptTracker::State::release()
@@ -70,18 +59,6 @@ void AcceptTracker::delivered(const std::string& destination, const qpid::framin
destinationState[destination].unaccepted.add(id);
}
-namespace
-{
-const size_t FLUSH_FREQUENCY = 1024;
-}
-
-void AcceptTracker::addToPending(qpid::client::AsyncSession& session, const Record& record)
-{
- pending.push_back(record);
- if (pending.size() % FLUSH_FREQUENCY == 0) session.flush();
-}
-
-
void AcceptTracker::accept(qpid::client::AsyncSession& session)
{
for (StateMap::iterator i = destinationState.begin(); i != destinationState.end(); ++i) {
@@ -90,19 +67,20 @@ void AcceptTracker::accept(qpid::client::AsyncSession& session)
Record record;
record.status = session.messageAccept(aggregateState.unaccepted);
record.accepted = aggregateState.unaccepted;
- addToPending(session, record);
+ pending.push_back(record);
aggregateState.accept();
}
-void AcceptTracker::accept(qpid::framing::SequenceNumber id, qpid::client::AsyncSession& session, bool cumulative)
+void AcceptTracker::accept(qpid::framing::SequenceNumber id, qpid::client::AsyncSession& session)
{
for (StateMap::iterator i = destinationState.begin(); i != destinationState.end(); ++i) {
- i->second.accept(id, cumulative);
+ i->second.accept(id);
}
Record record;
- record.accepted = aggregateState.accept(id, cumulative);
+ record.accepted.add(id);
record.status = session.messageAccept(record.accepted);
- addToPending(session, record);
+ pending.push_back(record);
+ aggregateState.accept(id);
}
void AcceptTracker::release(qpid::client::AsyncSession& session)
diff --git a/qpid/cpp/src/qpid/client/amqp0_10/AcceptTracker.h b/qpid/cpp/src/qpid/client/amqp0_10/AcceptTracker.h
index 85209c3b87..87890e41cc 100644
--- a/qpid/cpp/src/qpid/client/amqp0_10/AcceptTracker.h
+++ b/qpid/cpp/src/qpid/client/amqp0_10/AcceptTracker.h
@@ -42,7 +42,7 @@ class AcceptTracker
public:
void delivered(const std::string& destination, const qpid::framing::SequenceNumber& id);
void accept(qpid::client::AsyncSession&);
- void accept(qpid::framing::SequenceNumber, qpid::client::AsyncSession&, bool cumulative);
+ void accept(qpid::framing::SequenceNumber, qpid::client::AsyncSession&);
void release(qpid::client::AsyncSession&);
uint32_t acceptsPending();
uint32_t acceptsPending(const std::string& destination);
@@ -62,7 +62,7 @@ class AcceptTracker
qpid::framing::SequenceSet unconfirmed;
void accept();
- qpid::framing::SequenceSet accept(qpid::framing::SequenceNumber, bool cumulative);
+ void accept(qpid::framing::SequenceNumber);
void release();
uint32_t acceptsPending();
void completed(qpid::framing::SequenceSet&);
@@ -79,7 +79,6 @@ class AcceptTracker
StateMap destinationState;
Records pending;
- void addToPending(qpid::client::AsyncSession&, const Record&);
void checkPending();
void completed(qpid::framing::SequenceSet&);
};
diff --git a/qpid/cpp/src/qpid/client/amqp0_10/AddressResolution.cpp b/qpid/cpp/src/qpid/client/amqp0_10/AddressResolution.cpp
index cea7eb0b51..f1295a3b66 100644
--- a/qpid/cpp/src/qpid/client/amqp0_10/AddressResolution.cpp
+++ b/qpid/cpp/src/qpid/client/amqp0_10/AddressResolution.cpp
@@ -233,8 +233,6 @@ class Subscription : public Exchange, public MessageSource
const bool reliable;
const bool durable;
const std::string actualType;
- const bool exclusiveQueue;
- const bool exclusiveSubscription;
FieldTable queueOptions;
FieldTable subscriptionOptions;
Bindings bindings;
@@ -309,7 +307,6 @@ struct Opt
Opt& operator/(const std::string& name);
operator bool() const;
std::string str() const;
- bool asBool(bool defaultValue) const;
const Variant::List& asList() const;
void collect(qpid::framing::FieldTable& args) const;
@@ -341,12 +338,6 @@ Opt::operator bool() const
return value && !value->isVoid() && value->asBool();
}
-bool Opt::asBool(bool defaultValue) const
-{
- if (value) return value->asBool();
- else return defaultValue;
-}
-
std::string Opt::str() const
{
if (value) return value->asString();
@@ -499,9 +490,7 @@ Subscription::Subscription(const Address& address, const std::string& type)
queue(getSubscriptionName(name, (Opt(address)/LINK/NAME).str())),
reliable(AddressResolution::is_reliable(address)),
durable(Opt(address)/LINK/DURABLE),
- actualType(type.empty() ? (specifiedType.empty() ? TOPIC_EXCHANGE : specifiedType) : type),
- exclusiveQueue((Opt(address)/LINK/X_DECLARE/EXCLUSIVE).asBool(true)),
- exclusiveSubscription((Opt(address)/LINK/X_SUBSCRIBE/EXCLUSIVE).asBool(exclusiveQueue))
+ actualType(type.empty() ? (specifiedType.empty() ? TOPIC_EXCHANGE : specifiedType) : type)
{
(Opt(address)/LINK/X_DECLARE/ARGUMENTS).collect(queueOptions);
(Opt(address)/LINK/X_SUBSCRIBE/ARGUMENTS).collect(subscriptionOptions);
@@ -561,7 +550,7 @@ void Subscription::subscribe(qpid::client::AsyncSession& session, const std::str
checkAssert(session, FOR_RECEIVER);
//create subscription queue:
- session.queueDeclare(arg::queue=queue, arg::exclusive=exclusiveQueue,
+ session.queueDeclare(arg::queue=queue, arg::exclusive=true,
arg::autoDelete=!reliable, arg::durable=durable, arg::arguments=queueOptions);
//'default' binding:
bindings.bind(session);
@@ -570,15 +559,15 @@ void Subscription::subscribe(qpid::client::AsyncSession& session, const std::str
linkBindings.bind(session);
//subscribe to subscription queue:
AcceptMode accept = reliable ? ACCEPT_MODE_EXPLICIT : ACCEPT_MODE_NONE;
- session.messageSubscribe(arg::queue=queue, arg::destination=destination,
- arg::exclusive=exclusiveSubscription, arg::acceptMode=accept, arg::arguments=subscriptionOptions);
+ session.messageSubscribe(arg::queue=queue, arg::destination=destination,
+ arg::exclusive=true, arg::acceptMode=accept, arg::arguments=subscriptionOptions);
}
void Subscription::cancel(qpid::client::AsyncSession& session, const std::string& destination)
{
linkBindings.unbind(session);
session.messageCancel(destination);
- if (reliable) session.queueDelete(arg::queue=queue, arg::ifUnused=true);
+ session.queueDelete(arg::queue=queue);
checkDelete(session, FOR_RECEIVER);
}
@@ -833,7 +822,7 @@ void Exchange::checkAssert(qpid::client::AsyncSession& session, CheckMode mode)
FieldTable::ValuePtr v = result.getArguments().get(i->first);
if (!v) {
throw AssertionFailed((boost::format("Option %1% not set for %2%") % i->first % name).str());
- } else if (*i->second != *v) {
+ } else if (i->second != v) {
throw AssertionFailed((boost::format("Option %1% does not match for %2%, expected %3%, got %4%")
% i->first % name % *(i->second) % *v).str());
}
diff --git a/qpid/cpp/src/qpid/client/amqp0_10/ConnectionImpl.cpp b/qpid/cpp/src/qpid/client/amqp0_10/ConnectionImpl.cpp
index 3492938156..5a545c1f6a 100644
--- a/qpid/cpp/src/qpid/client/amqp0_10/ConnectionImpl.cpp
+++ b/qpid/cpp/src/qpid/client/amqp0_10/ConnectionImpl.cpp
@@ -39,18 +39,26 @@ using qpid::types::Variant;
using qpid::types::VAR_LIST;
using qpid::framing::Uuid;
-namespace {
-void merge(const std::string& value, std::vector<std::string>& list) {
- if (std::find(list.begin(), list.end(), value) == list.end())
- list.push_back(value);
+void convert(const Variant::List& from, std::vector<std::string>& to)
+{
+ for (Variant::List::const_iterator i = from.begin(); i != from.end(); ++i) {
+ to.push_back(i->asString());
+ }
}
-void merge(const Variant::List& from, std::vector<std::string>& to)
+template <class T> bool setIfFound(const Variant::Map& map, const std::string& key, T& value)
{
- for (Variant::List::const_iterator i = from.begin(); i != from.end(); ++i)
- merge(i->asString(), to);
+ Variant::Map::const_iterator i = map.find(key);
+ if (i != map.end()) {
+ value = (T) i->second;
+ QPID_LOG(debug, "option " << key << " specified as " << i->second);
+ return true;
+ } else {
+ return false;
+ }
}
+namespace {
std::string asString(const std::vector<std::string>& v) {
std::stringstream os;
os << "[";
@@ -63,8 +71,49 @@ std::string asString(const std::vector<std::string>& v) {
}
}
+template <> bool setIfFound< std::vector<std::string> >(const Variant::Map& map,
+ const std::string& key,
+ std::vector<std::string>& value)
+{
+ Variant::Map::const_iterator i = map.find(key);
+ if (i != map.end()) {
+ value.clear();
+ if (i->second.getType() == VAR_LIST) {
+ convert(i->second.asList(), value);
+ } else {
+ value.push_back(i->second.asString());
+ }
+ QPID_LOG(debug, "option " << key << " specified as " << asString(value));
+ return true;
+ } else {
+ return false;
+ }
+}
+
+void convert(const Variant::Map& from, ConnectionSettings& to)
+{
+ setIfFound(from, "username", to.username);
+ setIfFound(from, "password", to.password);
+ setIfFound(from, "sasl-mechanism", to.mechanism);
+ setIfFound(from, "sasl-service", to.service);
+ setIfFound(from, "sasl-min-ssf", to.minSsf);
+ setIfFound(from, "sasl-max-ssf", to.maxSsf);
+
+ setIfFound(from, "heartbeat", to.heartbeat);
+ setIfFound(from, "tcp-nodelay", to.tcpNoDelay);
+
+ setIfFound(from, "locale", to.locale);
+ setIfFound(from, "max-channels", to.maxChannels);
+ setIfFound(from, "max-frame-size", to.maxFrameSize);
+ setIfFound(from, "bounds", to.bounds);
+
+ setIfFound(from, "transport", to.protocol);
+
+ setIfFound(from, "ssl-cert-name", to.sslCertName);
+}
+
ConnectionImpl::ConnectionImpl(const std::string& url, const Variant::Map& options) :
- replaceUrls(false), reconnect(false), timeout(-1), limit(-1),
+ reconnect(false), timeout(-1), limit(-1),
minReconnectInterval(3), maxReconnectInterval(60),
retries(0), reconnectOnLimitExceeded(true)
{
@@ -75,67 +124,27 @@ ConnectionImpl::ConnectionImpl(const std::string& url, const Variant::Map& optio
void ConnectionImpl::setOptions(const Variant::Map& options)
{
- for (Variant::Map::const_iterator i = options.begin(); i != options.end(); ++i) {
- setOption(i->first, i->second);
+ sys::Mutex::ScopedLock l(lock);
+ convert(options, settings);
+ setIfFound(options, "reconnect", reconnect);
+ setIfFound(options, "reconnect-timeout", timeout);
+ setIfFound(options, "reconnect-limit", limit);
+ int64_t reconnectInterval;
+ if (setIfFound(options, "reconnect-interval", reconnectInterval)) {
+ minReconnectInterval = maxReconnectInterval = reconnectInterval;
+ } else {
+ setIfFound(options, "reconnect-interval-min", minReconnectInterval);
+ setIfFound(options, "reconnect-interval-max", maxReconnectInterval);
}
+ setIfFound(options, "reconnect-urls", urls);
+ setIfFound(options, "x-reconnect-on-limit-exceeded", reconnectOnLimitExceeded);
}
void ConnectionImpl::setOption(const std::string& name, const Variant& value)
{
- sys::Mutex::ScopedLock l(lock);
- if (name == "reconnect") {
- reconnect = value;
- } else if (name == "reconnect-timeout" || name == "reconnect_timeout") {
- timeout = value;
- } else if (name == "reconnect-limit" || name == "reconnect_limit") {
- limit = value;
- } else if (name == "reconnect-interval" || name == "reconnect_interval") {
- maxReconnectInterval = minReconnectInterval = value;
- } else if (name == "reconnect-interval-min" || name == "reconnect_interval_min") {
- minReconnectInterval = value;
- } else if (name == "reconnect-interval-max" || name == "reconnect_interval_max") {
- maxReconnectInterval = value;
- } else if (name == "reconnect-urls-replace" || name == "reconnect_urls_replace") {
- replaceUrls = value.asBool();
- } else if (name == "reconnect-urls" || name == "reconnect_urls") {
- if (replaceUrls) urls.clear();
- if (value.getType() == VAR_LIST) {
- merge(value.asList(), urls);
- } else {
- merge(value.asString(), urls);
- }
- } else if (name == "username") {
- settings.username = value.asString();
- } else if (name == "password") {
- settings.password = value.asString();
- } else if (name == "sasl-mechanism" || name == "sasl_mechanism" ||
- name == "sasl-mechanisms" || name == "sasl_mechanisms") {
- settings.mechanism = value.asString();
- } else if (name == "sasl-service" || name == "sasl_service") {
- settings.service = value.asString();
- } else if (name == "sasl-min-ssf" || name == "sasl_min_ssf") {
- settings.minSsf = value;
- } else if (name == "sasl-max-ssf" || name == "sasl_max_ssf") {
- settings.maxSsf = value;
- } else if (name == "heartbeat") {
- settings.heartbeat = value;
- } else if (name == "tcp-nodelay" || name == "tcp_nodelay") {
- settings.tcpNoDelay = value;
- } else if (name == "locale") {
- settings.locale = value.asString();
- } else if (name == "max-channels" || name == "max_channels") {
- settings.maxChannels = value;
- } else if (name == "max-frame-size" || name == "max_frame_size") {
- settings.maxFrameSize = value;
- } else if (name == "bounds") {
- settings.bounds = value;
- } else if (name == "transport") {
- settings.protocol = value.asString();
- } else if (name == "ssl-cert-name" || name == "ssl_cert_name") {
- settings.sslCertName = value.asString();
- } else {
- throw qpid::messaging::MessagingException(QPID_MSG("Invalid option: " << name << " not recognised"));
- }
+ Variant::Map options;
+ options[name] = value;
+ setOptions(options);
}
@@ -205,7 +214,7 @@ qpid::messaging::Session ConnectionImpl::newSession(bool transactional, const st
sessions[name] = impl;
break;
} catch (const qpid::TransportFailure&) {
- reopen();
+ open();
} catch (const qpid::SessionException& e) {
throw qpid::messaging::SessionError(e.what());
} catch (const std::exception& e) {
@@ -226,15 +235,6 @@ void ConnectionImpl::open()
catch (const qpid::Exception& e) { throw messaging::ConnectionError(e.what()); }
}
-void ConnectionImpl::reopen()
-{
- if (!reconnect) {
- throw qpid::messaging::TransportFailure("Failed to connect (reconnect disabled)");
- }
- open();
-}
-
-
bool expired(const qpid::sys::AbsTime& start, int64_t timeout)
{
if (timeout == 0) return true;
@@ -262,9 +262,14 @@ void ConnectionImpl::connect(const qpid::sys::AbsTime& started)
}
void ConnectionImpl::mergeUrls(const std::vector<Url>& more, const sys::Mutex::ScopedLock&) {
- for (std::vector<Url>::const_iterator i = more.begin(); i != more.end(); ++i)
- merge(i->str(), urls);
- QPID_LOG(debug, "Added known-hosts, reconnect-urls=" << asString(urls));
+ if (more.size()) {
+ for (size_t i = 0; i < more.size(); ++i) {
+ if (std::find(urls.begin(), urls.end(), more[i].str()) == urls.end()) {
+ urls.push_back(more[i].str());
+ }
+ }
+ QPID_LOG(debug, "Added known-hosts, reconnect-urls=" << asString(urls));
+ }
}
bool ConnectionImpl::tryConnect()
@@ -284,7 +289,10 @@ bool ConnectionImpl::tryConnect()
QPID_LOG(info, "Connected to " << *i);
mergeUrls(connection.getInitialBrokers(), l);
return resetSessions(l);
- } catch (const qpid::TransportFailure& e) {
+ } catch (const qpid::ConnectionException& e) {
+ //TODO: need to fix timeout on
+ //qpid::client::Connection::open() so that it throws
+ //TransportFailure rather than a ConnectionException
QPID_LOG(info, "Failed to connect to " << *i << ": " << e.what());
}
}
diff --git a/qpid/cpp/src/qpid/client/amqp0_10/ConnectionImpl.h b/qpid/cpp/src/qpid/client/amqp0_10/ConnectionImpl.h
index 1b58cbbe3e..09f2038312 100644
--- a/qpid/cpp/src/qpid/client/amqp0_10/ConnectionImpl.h
+++ b/qpid/cpp/src/qpid/client/amqp0_10/ConnectionImpl.h
@@ -43,7 +43,6 @@ class ConnectionImpl : public qpid::messaging::ConnectionImpl
public:
ConnectionImpl(const std::string& url, const qpid::types::Variant::Map& options);
void open();
- void reopen();
bool isOpen() const;
void close();
qpid::messaging::Session newSession(bool transactional, const std::string& name);
@@ -60,7 +59,6 @@ class ConnectionImpl : public qpid::messaging::ConnectionImpl
qpid::sys::Semaphore semaphore;//used to coordinate reconnection
Sessions sessions;
qpid::client::Connection connection;
- bool replaceUrls; // Replace rather than merging with reconnect-urls
std::vector<std::string> urls;
qpid::client::ConnectionSettings settings;
bool reconnect;
diff --git a/qpid/cpp/src/qpid/client/amqp0_10/IncomingMessages.cpp b/qpid/cpp/src/qpid/client/amqp0_10/IncomingMessages.cpp
index 5cf20c92eb..71e89bdba1 100644
--- a/qpid/cpp/src/qpid/client/amqp0_10/IncomingMessages.cpp
+++ b/qpid/cpp/src/qpid/client/amqp0_10/IncomingMessages.cpp
@@ -144,10 +144,10 @@ void IncomingMessages::accept()
acceptTracker.accept(session);
}
-void IncomingMessages::accept(qpid::framing::SequenceNumber id, bool cumulative)
+void IncomingMessages::accept(qpid::framing::SequenceNumber id)
{
sys::Mutex::ScopedLock l(lock);
- acceptTracker.accept(id, session, cumulative);
+ acceptTracker.accept(id, session);
}
diff --git a/qpid/cpp/src/qpid/client/amqp0_10/IncomingMessages.h b/qpid/cpp/src/qpid/client/amqp0_10/IncomingMessages.h
index 9053b70312..f6a291bc68 100644
--- a/qpid/cpp/src/qpid/client/amqp0_10/IncomingMessages.h
+++ b/qpid/cpp/src/qpid/client/amqp0_10/IncomingMessages.h
@@ -72,7 +72,7 @@ class IncomingMessages
bool get(Handler& handler, qpid::sys::Duration timeout);
bool getNextDestination(std::string& destination, qpid::sys::Duration timeout);
void accept();
- void accept(qpid::framing::SequenceNumber id, bool cumulative);
+ void accept(qpid::framing::SequenceNumber id);
void releaseAll();
void releasePending(const std::string& destination);
diff --git a/qpid/cpp/src/qpid/client/amqp0_10/OutgoingMessage.cpp b/qpid/cpp/src/qpid/client/amqp0_10/OutgoingMessage.cpp
index d93416da75..82358961c8 100644
--- a/qpid/cpp/src/qpid/client/amqp0_10/OutgoingMessage.cpp
+++ b/qpid/cpp/src/qpid/client/amqp0_10/OutgoingMessage.cpp
@@ -59,9 +59,7 @@ void OutgoingMessage::convert(const qpid::messaging::Message& from)
message.getMessageProperties().setReplyTo(AddressResolution::convert(address));
}
translate(from.getProperties(), message.getMessageProperties().getApplicationHeaders());
- if (from.getTtl().getMilliseconds()) {
- message.getDeliveryProperties().setTtl(from.getTtl().getMilliseconds());
- }
+ message.getDeliveryProperties().setTtl(from.getTtl().getMilliseconds());
if (from.getDurable()) {
message.getDeliveryProperties().setDeliveryMode(DELIVERY_MODE_PERSISTENT);
}
diff --git a/qpid/cpp/src/qpid/client/amqp0_10/SenderImpl.cpp b/qpid/cpp/src/qpid/client/amqp0_10/SenderImpl.cpp
index f2f0f1a9e5..e1b75ec0cf 100644
--- a/qpid/cpp/src/qpid/client/amqp0_10/SenderImpl.cpp
+++ b/qpid/cpp/src/qpid/client/amqp0_10/SenderImpl.cpp
@@ -135,7 +135,6 @@ void SenderImpl::sendUnreliable(const qpid::messaging::Message& m)
void SenderImpl::replay(const sys::Mutex::ScopedLock&)
{
for (OutgoingMessages::iterator i = outgoing.begin(); i != outgoing.end(); ++i) {
- i->message.setRedelivered(true);
sink->send(session, name, *i);
}
}
@@ -148,7 +147,7 @@ uint32_t SenderImpl::checkPendingSends(bool flush) {
uint32_t SenderImpl::checkPendingSends(bool flush, const sys::Mutex::ScopedLock&)
{
if (flush) {
- session.flush();
+ session.flush();
flushed = true;
} else {
flushed = false;
diff --git a/qpid/cpp/src/qpid/client/amqp0_10/SessionImpl.cpp b/qpid/cpp/src/qpid/client/amqp0_10/SessionImpl.cpp
index e6255dcd6f..75a71997fd 100644
--- a/qpid/cpp/src/qpid/client/amqp0_10/SessionImpl.cpp
+++ b/qpid/cpp/src/qpid/client/amqp0_10/SessionImpl.cpp
@@ -112,14 +112,13 @@ void SessionImpl::release(qpid::messaging::Message& m)
execute1<Release>(m);
}
-void SessionImpl::acknowledge(qpid::messaging::Message& m, bool cumulative)
+void SessionImpl::acknowledge(qpid::messaging::Message& m)
{
//Should probably throw an exception on failure here, or indicate
//it through a return type at least. Failure means that the
//message may be redelivered; i.e. the application cannot delete
//any state necessary for preventing reprocessing of the message
- Acknowledge2 ack(*this, m, cumulative);
- execute(ack);
+ execute1<Acknowledge1>(m);
}
void SessionImpl::close()
@@ -432,11 +431,8 @@ uint32_t SessionImpl::getUnsettledAcksImpl(const std::string* destination)
void SessionImpl::syncImpl(bool block)
{
- {
- ScopedLock l(lock);
- if (block) session.sync();
- else session.flush();
- }
+ if (block) session.sync();
+ else session.flush();
//cleanup unconfirmed accept records:
incoming.pendingAccept();
}
@@ -471,10 +467,10 @@ void SessionImpl::acknowledgeImpl()
if (!transactional) incoming.accept();
}
-void SessionImpl::acknowledgeImpl(qpid::messaging::Message& m, bool cumulative)
+void SessionImpl::acknowledgeImpl(qpid::messaging::Message& m)
{
ScopedLock l(lock);
- if (!transactional) incoming.accept(MessageImplAccess::get(m).getInternalId(), cumulative);
+ if (!transactional) incoming.accept(MessageImplAccess::get(m).getInternalId());
}
void SessionImpl::rejectImpl(qpid::messaging::Message& m)
@@ -513,7 +509,7 @@ void SessionImpl::senderCancelled(const std::string& name)
void SessionImpl::reconnect()
{
- connection->reopen();
+ connection->open();
}
bool SessionImpl::backoff()
diff --git a/qpid/cpp/src/qpid/client/amqp0_10/SessionImpl.h b/qpid/cpp/src/qpid/client/amqp0_10/SessionImpl.h
index c7dea77d18..2a2aa47df6 100644
--- a/qpid/cpp/src/qpid/client/amqp0_10/SessionImpl.h
+++ b/qpid/cpp/src/qpid/client/amqp0_10/SessionImpl.h
@@ -63,7 +63,7 @@ class SessionImpl : public qpid::messaging::SessionImpl
void acknowledge(bool sync);
void reject(qpid::messaging::Message&);
void release(qpid::messaging::Message&);
- void acknowledge(qpid::messaging::Message& msg, bool cumulative);
+ void acknowledge(qpid::messaging::Message& msg);
void close();
void sync(bool block);
qpid::messaging::Sender createSender(const qpid::messaging::Address& address);
@@ -139,7 +139,7 @@ class SessionImpl : public qpid::messaging::SessionImpl
void commitImpl();
void rollbackImpl();
void acknowledgeImpl();
- void acknowledgeImpl(qpid::messaging::Message&, bool cumulative);
+ void acknowledgeImpl(qpid::messaging::Message&);
void rejectImpl(qpid::messaging::Message&);
void releaseImpl(qpid::messaging::Message&);
void closeImpl();
@@ -204,13 +204,12 @@ class SessionImpl : public qpid::messaging::SessionImpl
void operator()() { impl.releaseImpl(message); }
};
- struct Acknowledge2 : Command
+ struct Acknowledge1 : Command
{
qpid::messaging::Message& message;
- bool cumulative;
- Acknowledge2(SessionImpl& i, qpid::messaging::Message& m, bool c) : Command(i), message(m), cumulative(c) {}
- void operator()() { impl.acknowledgeImpl(message, cumulative); }
+ Acknowledge1(SessionImpl& i, qpid::messaging::Message& m) : Command(i), message(m) {}
+ void operator()() { impl.acknowledgeImpl(message); }
};
struct CreateSender;
diff --git a/qpid/cpp/src/qpid/client/windows/SaslFactory.cpp b/qpid/cpp/src/qpid/client/windows/SaslFactory.cpp
index d1ae762f1b..63c7fa3d1f 100644
--- a/qpid/cpp/src/qpid/client/windows/SaslFactory.cpp
+++ b/qpid/cpp/src/qpid/client/windows/SaslFactory.cpp
@@ -153,7 +153,7 @@ std::string WindowsSasl::start(const std::string& mechanisms,
return resp;
}
-std::string WindowsSasl::step(const std::string& /*challenge*/)
+std::string WindowsSasl::step(const std::string& challenge)
{
// Shouldn't get this for PLAIN...
throw InternalErrorException(QPID_MSG("Sasl step error"));
@@ -169,7 +169,7 @@ std::string WindowsSasl::getUserId()
return std::string(); // TODO - when GSSAPI is supported, return userId for connection.
}
-std::auto_ptr<SecurityLayer> WindowsSasl::getSecurityLayer(uint16_t /*maxFrameSize*/)
+std::auto_ptr<SecurityLayer> WindowsSasl::getSecurityLayer(uint16_t maxFrameSize)
{
return std::auto_ptr<SecurityLayer>(0);
}
diff --git a/qpid/cpp/src/qpid/client/windows/SslConnector.cpp b/qpid/cpp/src/qpid/client/windows/SslConnector.cpp
index 785c817928..a33713e1a8 100644
--- a/qpid/cpp/src/qpid/client/windows/SslConnector.cpp
+++ b/qpid/cpp/src/qpid/client/windows/SslConnector.cpp
@@ -77,7 +77,7 @@ public:
framing::ProtocolVersion pVersion,
const ConnectionSettings&,
ConnectionImpl*);
- virtual void connect(const std::string& host, const std::string& port);
+ virtual void connect(const std::string& host, int port);
virtual void connected(const Socket&);
unsigned int getSSF();
};
@@ -153,7 +153,7 @@ SslConnector::~SslConnector()
// Will this get reach via virtual method via boost::bind????
-void SslConnector::connect(const std::string& host, const std::string& port) {
+void SslConnector::connect(const std::string& host, int port) {
brokerHost = host;
TCPConnector::connect(host, port);
}
diff --git a/qpid/cpp/src/qpid/cluster/Cluster.cpp b/qpid/cpp/src/qpid/cluster/Cluster.cpp
index 82ed8bf8c9..fe5a1c806e 100644
--- a/qpid/cpp/src/qpid/cluster/Cluster.cpp
+++ b/qpid/cpp/src/qpid/cluster/Cluster.cpp
@@ -146,7 +146,6 @@
#include "qpid/framing/AMQP_AllOperations.h"
#include "qpid/framing/AllInvoker.h"
#include "qpid/framing/ClusterConfigChangeBody.h"
-#include "qpid/framing/ClusterClockBody.h"
#include "qpid/framing/ClusterConnectionDeliverCloseBody.h"
#include "qpid/framing/ClusterConnectionAbortBody.h"
#include "qpid/framing/ClusterRetractOfferBody.h"
@@ -199,7 +198,7 @@ namespace _qmf = ::qmf::org::apache::qpid::cluster;
* Currently use SVN revision to avoid clashes with versions from
* different branches.
*/
-const uint32_t Cluster::CLUSTER_VERSION = 1128070;
+const uint32_t Cluster::CLUSTER_VERSION = 1058747;
struct ClusterDispatcher : public framing::AMQP_AllOperations::ClusterHandler {
qpid::cluster::Cluster& cluster;
@@ -231,16 +230,16 @@ struct ClusterDispatcher : public framing::AMQP_AllOperations::ClusterHandler {
cluster.updateOffer(member, updatee, l);
}
void retractOffer(uint64_t updatee) { cluster.retractOffer(member, updatee, l); }
+ void messageExpired(uint64_t id) { cluster.messageExpired(member, id, l); }
void errorCheck(uint8_t type, const framing::SequenceNumber& frameSeq) {
cluster.errorCheck(member, type, frameSeq, l);
}
void timerWakeup(const std::string& name) { cluster.timerWakeup(member, name, l); }
- void timerDrop(const std::string& name) { cluster.timerDrop(member, name, l); }
+ void timerDrop(const std::string& name) { cluster.timerWakeup(member, name, l); }
void shutdown(const Uuid& id) { cluster.shutdown(member, id, l); }
void deliverToQueue(const std::string& queue, const std::string& message) {
cluster.deliverToQueue(queue, message, l);
}
- void clock(uint64_t time) { cluster.clock(time, l); }
bool invoke(AMQBody& body) { return framing::invoke(*this, body).wasHandled(); }
};
@@ -254,7 +253,7 @@ Cluster::Cluster(const ClusterSettings& set, broker::Broker& b) :
self(cpg.self()),
clusterId(true),
mAgent(0),
- expiryPolicy(new ExpiryPolicy(*this)),
+ 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),
@@ -366,8 +365,7 @@ void Cluster::addShadowConnection(const boost::intrusive_ptr<Connection>& c) {
assert(discarding);
pair<ConnectionMap::iterator, bool> ib
= connections.insert(ConnectionMap::value_type(c->getId(), c));
- // Like this to avoid tripping up unused variable warning when NDEBUG set
- if (!ib.second) assert(ib.second);
+ assert(ib.second);
}
void Cluster::erase(const ConnectionId& id) {
@@ -539,7 +537,7 @@ void Cluster::processFrame(const EventFrame& e, Lock& l) {
connection->deliveredFrame(e);
}
else
- throw Exception(QPID_MSG("Unknown connection: " << e));
+ QPID_LOG(trace, *this << " DROP (no connection): " << e);
}
else // Drop connection frames while state < CATCHUP
QPID_LOG(trace, *this << " DROP (joining): " << e);
@@ -669,8 +667,6 @@ void Cluster::initMapCompleted(Lock& l) {
else { // I can go ready.
discarding = false;
setReady(l);
- // Must be called *before* memberUpdate so first update will be generated.
- failoverExchange->setReady();
memberUpdate(l);
updateMgmtMembership(l);
mcast.mcastControl(ClusterReadyBody(ProtocolVersion(), myUrl.str()), self);
@@ -723,20 +719,6 @@ void Cluster::configChange(const MemberId&,
updateMgmtMembership(l); // Update on every config change for consistency
}
-struct ClusterClockTask : public sys::TimerTask {
- Cluster& cluster;
- sys::Timer& timer;
-
- ClusterClockTask(Cluster& cluster, sys::Timer& timer, uint16_t clockInterval)
- : TimerTask(Duration(clockInterval * TIME_MSEC),"ClusterClock"), cluster(cluster), timer(timer) {}
-
- void fire() {
- cluster.sendClockUpdate();
- setupNextFire();
- timer.add(this);
- }
-};
-
void Cluster::becomeElder(Lock&) {
if (elder) return; // We were already the elder.
// We are the oldest, reactive links if necessary
@@ -744,8 +726,6 @@ void Cluster::becomeElder(Lock&) {
elder = true;
broker.getLinks().setPassive(false);
timer->becomeElder();
-
- clockTimer.add(new ClusterClockTask(*this, clockTimer, settings.clockInterval));
}
void Cluster::makeOffer(const MemberId& id, Lock& ) {
@@ -866,7 +846,7 @@ void Cluster::updateOffer(const MemberId& updater, uint64_t updateeInt, Lock& l)
if (updatee != self && url) {
QPID_LOG(debug, debugSnapshot());
if (mAgent) mAgent->clusterUpdate();
- // Updatee will call clusterUpdate() via checkUpdateIn() when update completes
+ // Updatee will call clusterUpdate when update completes
}
}
@@ -947,11 +927,10 @@ void Cluster::checkUpdateIn(Lock& l) {
if (!updateClosed) return; // Wait till update connection closes.
if (updatedMap) { // We're up to date
map = *updatedMap;
+ failoverExchange->setUrls(getUrls(l));
mcast.mcastControl(ClusterReadyBody(ProtocolVersion(), myUrl.str()), self);
state = CATCHUP;
memberUpdate(l);
- // Must be called *after* memberUpdate() to avoid sending an extra update.
- failoverExchange->setReady();
// NB: don't updateMgmtMembership() here as we are not in the deliver
// thread. It will be updated on delivery of the "ready" we just mcast.
broker.setClusterUpdatee(false);
@@ -964,10 +943,6 @@ void Cluster::checkUpdateIn(Lock& l) {
mAgent->suppress(false); // Enable management output.
mAgent->clusterUpdate();
}
- // Restore alternate exchange settings on exchanges.
- broker.getExchanges().eachExchange(
- boost::bind(&broker::Exchange::recoveryComplete, _1,
- boost::ref(broker.getExchanges())));
enableClusterSafe(); // Enable cluster-safe assertions
deliverEventQueue.start();
}
@@ -1141,6 +1116,10 @@ void Cluster::setClusterId(const Uuid& uuid, Lock&) {
QPID_LOG(notice, *this << " cluster-uuid = " << clusterId);
}
+void Cluster::messageExpired(const MemberId&, uint64_t id, Lock&) {
+ expiryPolicy->deliverExpire(id);
+}
+
void Cluster::errorCheck(const MemberId& from, uint8_t type, framing::SequenceNumber frameSeq, Lock&) {
// If we see an errorCheck here (rather than in the ErrorCheck
// class) then we have processed succesfully past the point of the
@@ -1178,35 +1157,6 @@ void Cluster::deliverToQueue(const std::string& queue, const std::string& messag
q->deliver(msg);
}
-sys::AbsTime Cluster::getClusterTime() {
- Mutex::ScopedLock l(lock);
- return clusterTime;
-}
-
-// This method is called during update on the updatee to set the initial cluster time.
-void Cluster::clock(const uint64_t time) {
- Mutex::ScopedLock l(lock);
- clock(time, l);
-}
-
-// called when broadcast message received
-void Cluster::clock(const uint64_t time, Lock&) {
- clusterTime = AbsTime(EPOCH, time);
- AbsTime now = AbsTime::now();
-
- if (!elder) {
- clusterTimeOffset = Duration(now, clusterTime);
- }
-}
-
-// called by elder timer to send clock broadcast
-void Cluster::sendClockUpdate() {
- Mutex::ScopedLock l(lock);
- int64_t nanosecondsSinceEpoch = Duration(EPOCH, now());
- nanosecondsSinceEpoch += clusterTimeOffset;
- mcast.mcastControl(ClusterClockBody(ProtocolVersion(), nanosecondsSinceEpoch), self);
-}
-
bool Cluster::deferDeliveryImpl(const std::string& queue,
const boost::intrusive_ptr<broker::Message>& msg)
{
diff --git a/qpid/cpp/src/qpid/cluster/Cluster.h b/qpid/cpp/src/qpid/cluster/Cluster.h
index adb06b2783..8f73c6acca 100644
--- a/qpid/cpp/src/qpid/cluster/Cluster.h
+++ b/qpid/cpp/src/qpid/cluster/Cluster.h
@@ -60,19 +60,13 @@ class Message;
namespace framing {
class AMQBody;
-struct Uuid;
-}
-
-namespace sys {
-class Timer;
-class AbsTime;
-class Duration;
+class Uuid;
}
namespace cluster {
class Connection;
-struct EventFrame;
+class EventFrame;
class ClusterTimer;
class UpdateDataExchange;
@@ -141,9 +135,6 @@ class Cluster : private Cpg::Handler, public management::Manageable {
bool deferDeliveryImpl(const std::string& queue,
const boost::intrusive_ptr<broker::Message>& msg);
- sys::AbsTime getClusterTime();
- void sendClockUpdate();
- void clock(const uint64_t time);
private:
typedef sys::Monitor::ScopedLock Lock;
@@ -189,12 +180,12 @@ class Cluster : private Cpg::Handler, public management::Manageable {
const std::string& left,
const std::string& joined,
Lock& l);
+ void messageExpired(const MemberId&, uint64_t, Lock& l);
void errorCheck(const MemberId&, uint8_t type, SequenceNumber frameSeq, Lock&);
void timerWakeup(const MemberId&, const std::string& name, Lock&);
void timerDrop(const MemberId&, const std::string& name, Lock&);
void shutdown(const MemberId&, const framing::Uuid& shutdownId, Lock&);
void deliverToQueue(const std::string& queue, const std::string& message, Lock&);
- void clock(const uint64_t time, Lock&);
// Helper functions
ConnectionPtr getConnection(const EventFrame&, Lock&);
@@ -305,12 +296,9 @@ class Cluster : private Cpg::Handler, public management::Manageable {
ErrorCheck error;
UpdateReceiver updateReceiver;
ClusterTimer* timer;
- sys::Timer clockTimer;
- sys::AbsTime clusterTime;
- sys::Duration clusterTimeOffset;
friend std::ostream& operator<<(std::ostream&, const Cluster&);
- friend struct ClusterDispatcher;
+ friend class ClusterDispatcher;
};
}} // namespace qpid::cluster
diff --git a/qpid/cpp/src/qpid/cluster/ClusterMap.cpp b/qpid/cpp/src/qpid/cluster/ClusterMap.cpp
index a8389095c9..040e129970 100644
--- a/qpid/cpp/src/qpid/cluster/ClusterMap.cpp
+++ b/qpid/cpp/src/qpid/cluster/ClusterMap.cpp
@@ -50,6 +50,11 @@ void insertFieldTableFromMapValue(FieldTable& ft, const ClusterMap::Map::value_t
ft.setString(vt.first.str(), vt.second.str());
}
+void assignFieldTable(FieldTable& ft, const ClusterMap::Map& map) {
+ ft.clear();
+ for_each(map.begin(), map.end(), bind(&insertFieldTableFromMapValue, ref(ft), _1));
+}
+
}
ClusterMap::ClusterMap() : frameSeq(0) {}
diff --git a/qpid/cpp/src/qpid/cluster/ClusterPlugin.cpp b/qpid/cpp/src/qpid/cluster/ClusterPlugin.cpp
index 69ba095f16..2962daaa07 100644
--- a/qpid/cpp/src/qpid/cluster/ClusterPlugin.cpp
+++ b/qpid/cpp/src/qpid/cluster/ClusterPlugin.cpp
@@ -72,7 +72,6 @@ struct ClusterOptions : public Options {
("cluster-cman", optValue(settings.quorum), "Integrate with Cluster Manager (CMAN) cluster.")
#endif
("cluster-size", optValue(settings.size, "N"), "Wait for N cluster members before allowing clients to connect.")
- ("cluster-clock-interval", optValue(settings.clockInterval,"N"), "How often to broadcast the current time to the cluster nodes, in milliseconds. A value between 5 and 1000 is recommended.")
("cluster-read-max", optValue(settings.readMax,"N"), "Experimental: flow-control limit reads per connection. 0=no limit.")
;
}
diff --git a/qpid/cpp/src/qpid/cluster/ClusterSettings.h b/qpid/cpp/src/qpid/cluster/ClusterSettings.h
index 2f7b5be20a..8e708aa139 100644
--- a/qpid/cpp/src/qpid/cluster/ClusterSettings.h
+++ b/qpid/cpp/src/qpid/cluster/ClusterSettings.h
@@ -35,9 +35,8 @@ struct ClusterSettings {
size_t readMax;
std::string username, password, mechanism;
size_t size;
- uint16_t clockInterval;
- ClusterSettings() : quorum(false), readMax(10), size(1), clockInterval(10)
+ ClusterSettings() : quorum(false), readMax(10), size(1)
{}
Url getUrl(uint16_t port) const {
diff --git a/qpid/cpp/src/qpid/cluster/ClusterTimer.cpp b/qpid/cpp/src/qpid/cluster/ClusterTimer.cpp
index b4f7d00f38..f6e1c7a849 100644
--- a/qpid/cpp/src/qpid/cluster/ClusterTimer.cpp
+++ b/qpid/cpp/src/qpid/cluster/ClusterTimer.cpp
@@ -70,7 +70,6 @@ void ClusterTimer::add(intrusive_ptr<TimerTask> task)
if (i != map.end())
throw Exception(QPID_MSG("Task already exists with name " << task->getName()));
map[task->getName()] = task;
-
// Only the elder actually activates the task with the Timer base class.
if (cluster.isElder()) {
QPID_LOG(trace, "Elder activating cluster timer task " << task->getName());
@@ -113,9 +112,6 @@ void ClusterTimer::deliverWakeup(const std::string& name) {
else {
intrusive_ptr<TimerTask> t = i->second;
map.erase(i);
- // Move the nextFireTime so readyToFire() is true. This is to ensure we
- // don't get an error if the fired task calls setupNextFire()
- t->setFired();
Timer::fire(t);
}
}
diff --git a/qpid/cpp/src/qpid/cluster/Connection.cpp b/qpid/cpp/src/qpid/cluster/Connection.cpp
index 030d6e34c1..e9b718e6de 100644
--- a/qpid/cpp/src/qpid/cluster/Connection.cpp
+++ b/qpid/cpp/src/qpid/cluster/Connection.cpp
@@ -7,9 +7,9 @@
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
@@ -35,7 +35,6 @@
#include "qpid/broker/Fairshare.h"
#include "qpid/broker/Link.h"
#include "qpid/broker/Bridge.h"
-#include "qpid/broker/StatefulQueueObserver.h"
#include "qpid/broker/Queue.h"
#include "qpid/framing/enum.h"
#include "qpid/framing/AMQFrame.h"
@@ -79,7 +78,7 @@ const std::string shadowPrefix("[shadow]");
Connection::Connection(Cluster& c, sys::ConnectionOutputHandler& out,
const std::string& mgmtId,
const ConnectionId& id, const qpid::sys::SecuritySettings& external)
- : cluster(c), self(id), catchUp(false), announced(false), output(*this, out),
+ : cluster(c), self(id), catchUp(false), output(*this, out),
connectionCtor(&output, cluster.getBroker(), mgmtId, external, false, 0, true),
expectProtocolHeader(false),
mcastFrameHandler(cluster.getMulticast(), self),
@@ -91,7 +90,7 @@ Connection::Connection(Cluster& c, sys::ConnectionOutputHandler& out,
Connection::Connection(Cluster& c, sys::ConnectionOutputHandler& out,
const std::string& mgmtId, MemberId member,
bool isCatchUp, bool isLink, const qpid::sys::SecuritySettings& external
-) : cluster(c), self(member, ++idCounter), catchUp(isCatchUp), announced(false), output(*this, out),
+) : cluster(c), self(member, ++idCounter), catchUp(isCatchUp), output(*this, out),
connectionCtor(&output, cluster.getBroker(),
mgmtId,
external,
@@ -144,7 +143,7 @@ void Connection::init() {
// Called when we have consumed a read buffer to give credit to the
// connection layer to continue reading.
void Connection::giveReadCredit(int credit) {
- if (cluster.getSettings().readMax && credit)
+ if (cluster.getSettings().readMax && credit)
output.giveReadCredit(credit);
}
@@ -202,7 +201,7 @@ void Connection::received(framing::AMQFrame& f) {
}
else { // Shadow or updated catch-up connection.
if (f.getMethod() && f.getMethod()->isA<ConnectionCloseBody>()) {
- if (isShadow())
+ if (isShadow())
cluster.addShadowConnection(this);
AMQFrame ok((ConnectionCloseOkBody()));
connection->getOutput().send(ok);
@@ -242,7 +241,7 @@ void Connection::deliverDoOutput(uint32_t limit) {
void Connection::deliveredFrame(const EventFrame& f) {
GiveReadCreditOnExit gc(*this, f.readCredit);
assert(!catchUp);
- currentChannel = f.frame.getChannel();
+ currentChannel = f.frame.getChannel();
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.
@@ -256,7 +255,7 @@ void Connection::deliveredFrame(const EventFrame& f) {
}
}
-// A local connection is closed by the network layer. Called in the connection thread.
+// A local connection is closed by the network layer.
void Connection::closed() {
try {
if (isUpdated()) {
@@ -273,9 +272,8 @@ void Connection::closed() {
// closed and process any outstanding frames from the cluster
// until self-delivery of deliver-close.
output.closeOutput();
- if (announced)
- cluster.getMulticast().mcastControl(
- ClusterConnectionDeliverCloseBody(), self);
+ cluster.getMulticast().mcastControl(
+ ClusterConnectionDeliverCloseBody(), self);
}
}
catch (const std::exception& e) {
@@ -289,7 +287,7 @@ void Connection::deliverClose () {
cluster.erase(self);
}
-// Close the connection
+// Close the connection
void Connection::close() {
if (connection.get()) {
QPID_LOG(debug, cluster << " closed connection " << *this);
@@ -322,10 +320,10 @@ size_t Connection::decode(const char* data, size_t size) {
while (localDecoder.decode(buf))
received(localDecoder.getFrame());
if (!wasOpen && connection->isOpen()) {
- // Connections marked with setUserProxyAuth are allowed to proxy
+ // Connections marked as federation links are allowed to proxy
// messages with user-ID that doesn't match the connection's
// authenticated ID. This is important for updates.
- connection->setUserProxyAuth(isCatchUp());
+ connection->setFederationLink(isCatchUp());
}
}
else { // Multicast local connections.
@@ -334,9 +332,9 @@ size_t Connection::decode(const char* data, size_t size) {
if (!checkProtocolHeader(ptr, size)) // Updates ptr
return 0; // Incomplete header
- if (!connection->isOpen())
+ if (!connection->isOpen())
processInitialFrames(ptr, end-ptr); // Updates ptr
-
+
if (connection->isOpen() && end - ptr > 0) {
// We're multi-casting, we will give read credit on delivery.
grc.credit = 0;
@@ -386,7 +384,6 @@ void Connection::processInitialFrames(const char*& ptr, size_t size) {
connection->getUserId(),
initialFrames),
getId());
- announced = true;
initialFrames.clear();
}
}
@@ -435,7 +432,7 @@ void Connection::sessionState(
unknownCompleted,
receivedIncomplete);
QPID_LOG(debug, cluster << " received session state update for " << sessionState().getId());
- // The output tasks will be added later in the update process.
+ // The output tasks will be added later in the update process.
connection->getOutputTasks().removeAll();
}
@@ -481,7 +478,7 @@ void Connection::retractOffer() {
void Connection::closeUpdated() {
self.second = 0; // Mark this as completed update connection.
- if (connection.get())
+ if (connection.get())
connection->close(connection::CLOSE_CODE_NORMAL, "OK");
}
@@ -532,7 +529,7 @@ void Connection::deliveryRecord(const string& qname,
m = getUpdateMessage();
m.queue = queue.get();
m.position = position;
- if (enqueued) queue->updateEnqueued(m); //inform queue of the message
+ if (enqueued) queue->updateEnqueued(m); //inform queue of the message
} else { // Message at original position in original queue
m = queue->find(position);
}
@@ -559,46 +556,8 @@ void Connection::queueFairshareState(const std::string& qname, const uint8_t pri
}
}
-
-namespace {
- // find a StatefulQueueObserver that matches a given identifier
- class ObserverFinder {
- const std::string id;
- boost::shared_ptr<broker::QueueObserver> target;
- ObserverFinder(const ObserverFinder&) {}
- public:
- ObserverFinder(const std::string& _id) : id(_id) {}
- broker::StatefulQueueObserver *getObserver()
- {
- if (target)
- return dynamic_cast<broker::StatefulQueueObserver *>(target.get());
- return 0;
- }
- void operator() (boost::shared_ptr<broker::QueueObserver> o)
- {
- if (!target) {
- broker::StatefulQueueObserver *p = dynamic_cast<broker::StatefulQueueObserver *>(o.get());
- if (p && p->getId() == id) {
- target = o;
- }
- }
- }
- };
-}
-
-
-void Connection::queueObserverState(const std::string& qname, const std::string& observerId, const FieldTable& state)
-{
- boost::shared_ptr<broker::Queue> queue(findQueue(qname));
- ObserverFinder finder(observerId); // find this observer
- queue->eachObserver<ObserverFinder &>(finder);
- broker::StatefulQueueObserver *so = finder.getObserver();
- if (so) {
- so->setState( state );
- QPID_LOG(debug, "updated queue observer " << observerId << "'s state on queue " << qname << "; ...");
- return;
- }
- QPID_LOG(error, "Failed to find observer " << observerId << " state on queue " << qname << "; this will result in inconsistencies.");
+void Connection::expiryId(uint64_t id) {
+ cluster.getExpiryPolicy().setId(id);
}
std::ostream& operator<<(std::ostream& o, const Connection& c) {
@@ -632,7 +591,7 @@ void Connection::txEnqueue(const std::string& queue) {
void Connection::txPublish(const framing::Array& queues, bool delivered) {
boost::shared_ptr<broker::TxPublish> txPub(new broker::TxPublish(getUpdateMessage().payload));
- for (framing::Array::const_iterator i = queues.begin(); i != queues.end(); ++i)
+ for (framing::Array::const_iterator i = queues.begin(); i != queues.end(); ++i)
txPub->deliverTo(findQueue((*i)->get<std::string>()));
txPub->delivered = delivered;
txBuffer->enlist(txPub);
@@ -655,6 +614,12 @@ void Connection::exchange(const std::string& encoded) {
QPID_LOG(debug, cluster << " updated exchange " << ex->getName());
}
+void Connection::queue(const std::string& encoded) {
+ Buffer buf(const_cast<char*>(encoded.data()), encoded.size());
+ broker::Queue::shared_ptr q = broker::Queue::decode(cluster.getBroker().getQueues(), buf);
+ QPID_LOG(debug, cluster << " updated queue " << q->getName());
+}
+
void Connection::sessionError(uint16_t , const std::string& msg) {
// Ignore errors before isOpen(), we're not multicasting yet.
if (connection->isOpen())
@@ -713,23 +678,6 @@ void Connection::config(const std::string& encoded) {
else throw Exception(QPID_MSG("Update failed, invalid kind of config: " << kind));
}
-void Connection::doCatchupIoCallbacks() {
- // We need to process IO callbacks during the catch-up phase in
- // order to service asynchronous completions for messages
- // transferred during catch-up.
-
- if (catchUp) getBrokerConnection()->doIoCallbacks();
-}
-
-void Connection::clock(uint64_t time) {
- QPID_LOG(debug, "Cluster connection received time update");
- cluster.clock(time);
-}
-
-void Connection::queueDequeueSincePurgeState(const std::string& qname, uint32_t dequeueSincePurge) {
- boost::shared_ptr<broker::Queue> queue(findQueue(qname));
- queue->setDequeueSincePurge(dequeueSincePurge);
-}
}} // Namespace qpid::cluster
diff --git a/qpid/cpp/src/qpid/cluster/Connection.h b/qpid/cpp/src/qpid/cluster/Connection.h
index a9740f97f8..7ee85bf1aa 100644
--- a/qpid/cpp/src/qpid/cluster/Connection.h
+++ b/qpid/cpp/src/qpid/cluster/Connection.h
@@ -10,9 +10,9 @@
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
@@ -24,10 +24,10 @@
#include "types.h"
#include "OutputInterceptor.h"
+#include "EventFrame.h"
#include "McastFrameHandler.h"
#include "UpdateReceiver.h"
-#include "qpid/RefCounted.h"
#include "qpid/broker/Connection.h"
#include "qpid/broker/SecureConnection.h"
#include "qpid/broker/SemanticState.h"
@@ -47,7 +47,7 @@ namespace framing { class AMQFrame; }
namespace broker {
class SemanticState;
-struct QueuedMessage;
+class QueuedMessage;
class TxBuffer;
class TxAccept;
}
@@ -55,7 +55,6 @@ class TxAccept;
namespace cluster {
class Cluster;
class Event;
-struct EventFrame;
/** Intercept broker::Connection calls for shadow and local cluster connections. */
class Connection :
@@ -63,7 +62,7 @@ class Connection :
public sys::ConnectionInputHandler,
public framing::AMQP_AllOperations::ClusterConnectionHandler,
private broker::Connection::ErrorListener
-
+
{
public:
@@ -74,7 +73,7 @@ class Connection :
Connection(Cluster&, sys::ConnectionOutputHandler& out, const std::string& mgmtId, const ConnectionId& id,
const qpid::sys::SecuritySettings& external);
~Connection();
-
+
ConnectionId getId() const { return self; }
broker::Connection* getBrokerConnection() { return connection.get(); }
const broker::Connection* getBrokerConnection() const { return connection.get(); }
@@ -109,9 +108,9 @@ class Connection :
void deliveredFrame(const EventFrame&);
void consumerState(const std::string& name, bool blocked, bool notifyEnabled, const qpid::framing::SequenceNumber& position);
-
+
// ==== Used in catch-up mode to build initial state.
- //
+ //
// State update methods.
void shadowPrepare(const std::string&);
@@ -124,9 +123,9 @@ class Connection :
const framing::SequenceNumber& received,
const framing::SequenceSet& unknownCompleted,
const SequenceSet& receivedIncomplete);
-
+
void outputTask(uint16_t channel, const std::string& name);
-
+
void shadowReady(uint64_t memberId,
uint64_t connectionId,
const std::string& managementId,
@@ -154,7 +153,7 @@ class Connection :
void queuePosition(const std::string&, const framing::SequenceNumber&);
void queueFairshareState(const std::string&, const uint8_t priority, const uint8_t count);
- void queueObserverState(const std::string&, const std::string&, const framing::FieldTable&);
+ void expiryId(uint64_t);
void txStart();
void txAccept(const framing::SequenceSet&);
@@ -164,7 +163,8 @@ class Connection :
void txEnd();
void accumulatedAck(const framing::SequenceSet&);
- // Encoded exchange replication.
+ // Encoded queue/exchange replication.
+ void queue(const std::string& encoded);
void exchange(const std::string& encoded);
void giveReadCredit(int credit);
@@ -189,12 +189,6 @@ class Connection :
void setSecureConnection ( broker::SecureConnection * sc );
- void doCatchupIoCallbacks();
-
- void clock(uint64_t time);
-
- void queueDequeueSincePurgeState(const std::string&, uint32_t);
-
private:
struct NullFrameHandler : public framing::FrameHandler {
void handle(framing::AMQFrame&) {}
@@ -239,7 +233,7 @@ class Connection :
// Error listener functions
void connectionError(const std::string&);
void sessionError(uint16_t channel, const std::string&);
-
+
void init();
bool checkUnsupported(const framing::AMQBody& body);
void deliverDoOutput(uint32_t limit);
@@ -255,7 +249,6 @@ class Connection :
Cluster& cluster;
ConnectionId self;
bool catchUp;
- bool announced;
OutputInterceptor output;
framing::FrameDecoder localDecoder;
ConnectionCtor connectionCtor;
diff --git a/qpid/cpp/src/qpid/cluster/Decoder.h b/qpid/cpp/src/qpid/cluster/Decoder.h
index 3b5ada4a81..2e2af2868f 100644
--- a/qpid/cpp/src/qpid/cluster/Decoder.h
+++ b/qpid/cpp/src/qpid/cluster/Decoder.h
@@ -31,7 +31,7 @@
namespace qpid {
namespace cluster {
-struct EventFrame;
+class EventFrame;
class EventHeader;
/**
diff --git a/qpid/cpp/src/qpid/cluster/ErrorCheck.h b/qpid/cpp/src/qpid/cluster/ErrorCheck.h
index a417b2ec25..de8cedafb3 100644
--- a/qpid/cpp/src/qpid/cluster/ErrorCheck.h
+++ b/qpid/cpp/src/qpid/cluster/ErrorCheck.h
@@ -33,7 +33,7 @@
namespace qpid {
namespace cluster {
-struct EventFrame;
+class EventFrame;
class Cluster;
class Multicaster;
class Connection;
diff --git a/qpid/cpp/src/qpid/cluster/Event.cpp b/qpid/cpp/src/qpid/cluster/Event.cpp
index da2bc89d8c..cd775ce2f1 100644
--- a/qpid/cpp/src/qpid/cluster/Event.cpp
+++ b/qpid/cpp/src/qpid/cluster/Event.cpp
@@ -7,9 +7,9 @@
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
@@ -23,7 +23,6 @@
#include "qpid/cluster/Cpg.h"
#include "qpid/framing/Buffer.h"
#include "qpid/framing/AMQFrame.h"
-#include "qpid/RefCountedBuffer.h"
#include "qpid/assert.h"
#include <ostream>
#include <iterator>
diff --git a/qpid/cpp/src/qpid/cluster/Event.h b/qpid/cpp/src/qpid/cluster/Event.h
index 13283edff7..c2dca073d1 100644
--- a/qpid/cpp/src/qpid/cluster/Event.h
+++ b/qpid/cpp/src/qpid/cluster/Event.h
@@ -23,7 +23,7 @@
*/
#include "qpid/cluster/types.h"
-#include "qpid/BufferRef.h"
+#include "qpid/RefCountedBuffer.h"
#include "qpid/framing/AMQFrame.h"
#include <sys/uio.h> // For iovec
#include <iosfwd>
@@ -88,12 +88,12 @@ class Event : public EventHeader {
static Event control(const framing::AMQFrame&, const ConnectionId&);
// Data excluding header.
- char* getData() { return store.begin() + HEADER_SIZE; }
- const char* getData() const { return store.begin() + HEADER_SIZE; }
+ char* getData() { return store + HEADER_SIZE; }
+ const char* getData() const { return store + HEADER_SIZE; }
// Store including header
- char* getStore() { return store.begin(); }
- const char* getStore() const { return store.begin(); }
+ char* getStore() { return store; }
+ const char* getStore() const { return store; }
const framing::AMQFrame& getFrame() const;
@@ -104,7 +104,7 @@ class Event : public EventHeader {
private:
void encodeHeader() const;
- BufferRef store;
+ RefCountedBuffer::pointer store;
mutable framing::AMQFrame frame;
};
diff --git a/qpid/cpp/src/qpid/cluster/ExpiryPolicy.cpp b/qpid/cpp/src/qpid/cluster/ExpiryPolicy.cpp
index 0ef5c2a35d..d9a7b0122a 100644
--- a/qpid/cpp/src/qpid/cluster/ExpiryPolicy.cpp
+++ b/qpid/cpp/src/qpid/cluster/ExpiryPolicy.cpp
@@ -21,21 +21,106 @@
#include "qpid/broker/Message.h"
#include "qpid/cluster/ExpiryPolicy.h"
-#include "qpid/cluster/Cluster.h"
+#include "qpid/cluster/Multicaster.h"
+#include "qpid/framing/ClusterMessageExpiredBody.h"
#include "qpid/sys/Time.h"
+#include "qpid/sys/Timer.h"
#include "qpid/log/Statement.h"
namespace qpid {
namespace cluster {
-ExpiryPolicy::ExpiryPolicy(Cluster& cluster) : cluster(cluster) {}
+ExpiryPolicy::ExpiryPolicy(Multicaster& m, const MemberId& id, sys::Timer& t)
+ : expiryId(1), expiredPolicy(new Expired), mcast(m), memberId(id), timer(t) {}
+struct ExpiryTask : public sys::TimerTask {
+ ExpiryTask(const boost::intrusive_ptr<ExpiryPolicy>& policy, uint64_t id, sys::AbsTime when)
+ : TimerTask(when,"ExpiryPolicy"), expiryPolicy(policy), expiryId(id) {}
+ void fire() { expiryPolicy->sendExpire(expiryId); }
+ boost::intrusive_ptr<ExpiryPolicy> expiryPolicy;
+ const uint64_t expiryId;
+};
+
+// Called while receiving an update
+void ExpiryPolicy::setId(uint64_t id) {
+ sys::Mutex::ScopedLock l(lock);
+ expiryId = id;
+}
+
+// Called while giving an update
+uint64_t ExpiryPolicy::getId() const {
+ sys::Mutex::ScopedLock l(lock);
+ return expiryId;
+}
+
+// Called in enqueuing connection thread
+void ExpiryPolicy::willExpire(broker::Message& m) {
+ uint64_t id;
+ {
+ // When messages are fanned out to multiple queues, update sends
+ // them as independenty messages so we can have multiple messages
+ // with the same expiry ID.
+ //
+ sys::Mutex::ScopedLock l(lock);
+ id = expiryId++;
+ if (!id) { // This is an update of an already-expired message.
+ m.setExpiryPolicy(expiredPolicy);
+ }
+ else {
+ assert(unexpiredByMessage.find(&m) == unexpiredByMessage.end());
+ // If this is an update, the id may already exist
+ unexpiredById.insert(IdMessageMap::value_type(id, &m));
+ unexpiredByMessage[&m] = id;
+ }
+ }
+ timer.add(new ExpiryTask(this, id, m.getExpiration()));
+}
+
+// Called in dequeueing connection thread
+void ExpiryPolicy::forget(broker::Message& m) {
+ sys::Mutex::ScopedLock l(lock);
+ MessageIdMap::iterator i = unexpiredByMessage.find(&m);
+ assert(i != unexpiredByMessage.end());
+ unexpiredById.erase(i->second);
+ unexpiredByMessage.erase(i);
+}
+
+// Called in dequeueing connection or cleanup thread.
bool ExpiryPolicy::hasExpired(broker::Message& m) {
- return m.getExpiration() < cluster.getClusterTime();
+ sys::Mutex::ScopedLock l(lock);
+ return unexpiredByMessage.find(&m) == unexpiredByMessage.end();
+}
+
+// Called in timer thread
+void ExpiryPolicy::sendExpire(uint64_t id) {
+ {
+ sys::Mutex::ScopedLock l(lock);
+ // Don't multicast an expiry notice if message is already forgotten.
+ if (unexpiredById.find(id) == unexpiredById.end()) return;
+ }
+ mcast.mcastControl(framing::ClusterMessageExpiredBody(framing::ProtocolVersion(), id), memberId);
}
-sys::AbsTime ExpiryPolicy::getCurrentTime() {
- return cluster.getClusterTime();
+// Called in CPG deliver thread.
+void ExpiryPolicy::deliverExpire(uint64_t id) {
+ sys::Mutex::ScopedLock l(lock);
+ std::pair<IdMessageMap::iterator, IdMessageMap::iterator> expired = unexpiredById.equal_range(id);
+ IdMessageMap::iterator i = expired.first;
+ while (i != expired.second) {
+ i->second->setExpiryPolicy(expiredPolicy); // hasExpired() == true;
+ unexpiredByMessage.erase(i->second);
+ unexpiredById.erase(i++);
+ }
}
+// Called in update thread on the updater.
+boost::optional<uint64_t> ExpiryPolicy::getId(broker::Message& m) {
+ sys::Mutex::ScopedLock l(lock);
+ MessageIdMap::iterator i = unexpiredByMessage.find(&m);
+ return i == unexpiredByMessage.end() ? boost::optional<uint64_t>() : i->second;
+}
+
+bool ExpiryPolicy::Expired::hasExpired(broker::Message&) { return true; }
+void ExpiryPolicy::Expired::willExpire(broker::Message&) { }
+
}} // namespace qpid::cluster
diff --git a/qpid/cpp/src/qpid/cluster/ExpiryPolicy.h b/qpid/cpp/src/qpid/cluster/ExpiryPolicy.h
index d8ddbca8b3..77a656aa68 100644
--- a/qpid/cpp/src/qpid/cluster/ExpiryPolicy.h
+++ b/qpid/cpp/src/qpid/cluster/ExpiryPolicy.h
@@ -36,8 +36,12 @@ namespace broker {
class Message;
}
+namespace sys {
+class Timer;
+}
+
namespace cluster {
-class Cluster;
+class Multicaster;
/**
* Cluster expiry policy
@@ -45,13 +49,43 @@ class Cluster;
class ExpiryPolicy : public broker::ExpiryPolicy
{
public:
- ExpiryPolicy(Cluster& cluster);
+ ExpiryPolicy(Multicaster&, const MemberId&, sys::Timer&);
+ void willExpire(broker::Message&);
bool hasExpired(broker::Message&);
- qpid::sys::AbsTime getCurrentTime();
+ void forget(broker::Message&);
+
+ // Send expiration notice to cluster.
+ void sendExpire(uint64_t);
+ // Cluster delivers expiry notice.
+ void deliverExpire(uint64_t);
+
+ void setId(uint64_t id);
+ uint64_t getId() const;
+
+ boost::optional<uint64_t> getId(broker::Message&);
+
private:
- Cluster& cluster;
+ typedef std::map<broker::Message*, uint64_t> MessageIdMap;
+ // When messages are fanned out to multiple queues, update sends
+ // them as independenty messages so we can have multiple messages
+ // with the same expiry ID.
+ typedef std::multimap<uint64_t, broker::Message*> IdMessageMap;
+
+ struct Expired : public broker::ExpiryPolicy {
+ bool hasExpired(broker::Message&);
+ void willExpire(broker::Message&);
+ };
+
+ mutable sys::Mutex lock;
+ MessageIdMap unexpiredByMessage;
+ IdMessageMap unexpiredById;
+ uint64_t expiryId;
+ boost::intrusive_ptr<Expired> expiredPolicy;
+ Multicaster& mcast;
+ MemberId memberId;
+ sys::Timer& timer;
};
}} // namespace qpid::cluster
diff --git a/qpid/cpp/src/qpid/cluster/FailoverExchange.cpp b/qpid/cpp/src/qpid/cluster/FailoverExchange.cpp
index cfbe34a460..84232dac1b 100644
--- a/qpid/cpp/src/qpid/cluster/FailoverExchange.cpp
+++ b/qpid/cpp/src/qpid/cluster/FailoverExchange.cpp
@@ -7,9 +7,9 @@
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
@@ -39,10 +39,8 @@ using namespace broker;
using namespace framing;
const string FailoverExchange::typeName("amq.failover");
-
-FailoverExchange::FailoverExchange(management::Manageable* parent, Broker* b)
- : Exchange(typeName, parent, b ), ready(false)
-{
+
+FailoverExchange::FailoverExchange(management::Manageable* parent, Broker* b) : Exchange(typeName, parent, b ) {
if (mgmtExchange != 0)
mgmtExchange->set_type(typeName);
}
@@ -55,17 +53,16 @@ void FailoverExchange::setUrls(const vector<Url>& u) {
void FailoverExchange::updateUrls(const vector<Url>& u) {
Lock l(lock);
urls=u;
- if (ready && !urls.empty()) {
- std::for_each(queues.begin(), queues.end(),
- boost::bind(&FailoverExchange::sendUpdate, this, _1));
- }
+ if (urls.empty()) return;
+ std::for_each(queues.begin(), queues.end(),
+ boost::bind(&FailoverExchange::sendUpdate, this, _1));
}
string FailoverExchange::getType() const { return typeName; }
bool FailoverExchange::bind(Queue::shared_ptr queue, const string&, const framing::FieldTable*) {
Lock l(lock);
- if (ready) sendUpdate(queue);
+ sendUpdate(queue);
return queues.insert(queue).second;
}
@@ -87,7 +84,7 @@ void FailoverExchange::sendUpdate(const Queue::shared_ptr& queue) {
// Called with lock held.
if (urls.empty()) return;
framing::Array array(0x95);
- for (Urls::const_iterator i = urls.begin(); i != urls.end(); ++i)
+ for (Urls::const_iterator i = urls.begin(); i != urls.end(); ++i)
array.add(boost::shared_ptr<Str16Value>(new Str16Value(i->str())));
const ProtocolVersion v;
boost::intrusive_ptr<Message> msg(new Message);
@@ -99,12 +96,9 @@ void FailoverExchange::sendUpdate(const Queue::shared_ptr& queue) {
header.get<MessageProperties>(true)->getApplicationHeaders().setArray(typeName, array);
AMQFrame headerFrame(header);
headerFrame.setFirstSegment(false);
- msg->getFrames().append(headerFrame);
+ msg->getFrames().append(headerFrame);
DeliverableMessage(msg).deliverTo(queue);
}
-void FailoverExchange::setReady() {
- ready = true;
-}
}} // namespace cluster
diff --git a/qpid/cpp/src/qpid/cluster/FailoverExchange.h b/qpid/cpp/src/qpid/cluster/FailoverExchange.h
index c3e50c6929..2e1edfc0ae 100644
--- a/qpid/cpp/src/qpid/cluster/FailoverExchange.h
+++ b/qpid/cpp/src/qpid/cluster/FailoverExchange.h
@@ -10,9 +10,9 @@
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
@@ -46,8 +46,6 @@ class FailoverExchange : public broker::Exchange
void setUrls(const std::vector<Url>&);
/** Set the URLs and send an update.*/
void updateUrls(const std::vector<Url>&);
- /** Flag the failover exchange as ready to generate updates (caught up) */
- void setReady();
// Exchange overrides
std::string getType() const;
@@ -58,7 +56,7 @@ class FailoverExchange : public broker::Exchange
private:
void sendUpdate(const boost::shared_ptr<broker::Queue>&);
-
+
typedef sys::Mutex::ScopedLock Lock;
typedef std::vector<Url> Urls;
typedef std::set<boost::shared_ptr<broker::Queue> > Queues;
@@ -66,7 +64,7 @@ class FailoverExchange : public broker::Exchange
sys::Mutex lock;
Urls urls;
Queues queues;
- bool ready;
+
};
}} // namespace qpid::cluster
diff --git a/qpid/cpp/src/qpid/cluster/OutputInterceptor.cpp b/qpid/cpp/src/qpid/cluster/OutputInterceptor.cpp
index 4bf03eefa2..1354dab17b 100644
--- a/qpid/cpp/src/qpid/cluster/OutputInterceptor.cpp
+++ b/qpid/cpp/src/qpid/cluster/OutputInterceptor.cpp
@@ -7,9 +7,9 @@
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
@@ -45,11 +45,12 @@ void OutputInterceptor::send(framing::AMQFrame& f) {
}
void OutputInterceptor::activateOutput() {
- sys::Mutex::ScopedLock l(lock);
- if (parent.isCatchUp())
+ if (parent.isCatchUp()) {
+ sys::Mutex::ScopedLock l(lock);
next->activateOutput();
+ }
else
- sendDoOutput(sendMax, l);
+ sendDoOutput(sendMax);
}
void OutputInterceptor::abort() {
@@ -65,38 +66,29 @@ void OutputInterceptor::giveReadCredit(int32_t credit) {
}
// Called in write thread when the IO layer has no more data to write.
-// We only process IO callbacks in the write thread during catch-up.
-// Normally we run doOutput only on delivery of doOutput requests.
-bool OutputInterceptor::doOutput() {
- parent.doCatchupIoCallbacks();
- return false;
-}
+// We do nothing in the write thread, we run doOutput only on delivery
+// of doOutput requests.
+bool OutputInterceptor::doOutput() { return false; }
-// Send output up to limit, calculate new limit.
+// Send output up to limit, calculate new limit.
void OutputInterceptor::deliverDoOutput(uint32_t limit) {
- sys::Mutex::ScopedLock l(lock);
sentDoOutput = false;
sendMax = limit;
size_t newLimit = limit;
if (parent.isLocal()) {
- size_t buffered = next->getBuffered();
+ size_t buffered = getBuffered();
if (buffered == 0 && sent == sendMax) // Could have sent more, increase the limit.
- newLimit = sendMax*2;
+ newLimit = sendMax*2;
else if (buffered > 0 && sent > 1) // Data left unsent, reduce the limit.
newLimit = (sendMax + sent) / 2;
}
sent = 0;
- while (sent < limit) {
- {
- sys::Mutex::ScopedUnlock u(lock);
- if (!parent.getBrokerConnection()->doOutput()) break;
- }
+ while (sent < limit && parent.getBrokerConnection()->doOutput())
++sent;
- }
- if (sent == limit) sendDoOutput(newLimit, l);
+ if (sent == limit) sendDoOutput(newLimit);
}
-void OutputInterceptor::sendDoOutput(size_t newLimit, const sys::Mutex::ScopedLock&) {
+void OutputInterceptor::sendDoOutput(size_t newLimit) {
if (parent.isLocal() && !sentDoOutput && !closing) {
sentDoOutput = true;
parent.getCluster().getMulticast().mcastControl(
@@ -105,7 +97,6 @@ void OutputInterceptor::sendDoOutput(size_t newLimit, const sys::Mutex::ScopedLo
}
}
-// Called in connection thread when local connection closes.
void OutputInterceptor::closeOutput() {
sys::Mutex::ScopedLock l(lock);
closing = true;
diff --git a/qpid/cpp/src/qpid/cluster/OutputInterceptor.h b/qpid/cpp/src/qpid/cluster/OutputInterceptor.h
index 3abf5273a0..65bd82a4fc 100644
--- a/qpid/cpp/src/qpid/cluster/OutputInterceptor.h
+++ b/qpid/cpp/src/qpid/cluster/OutputInterceptor.h
@@ -10,9 +10,9 @@
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
@@ -58,13 +58,13 @@ class OutputInterceptor : public sys::ConnectionOutputHandler {
uint32_t getSendMax() const { return sendMax; }
void setSendMax(uint32_t sendMax_) { sendMax=sendMax_; }
-
+
cluster::Connection& parent;
-
+
private:
typedef sys::Mutex::ScopedLock Locker;
- void sendDoOutput(size_t newLimit, const sys::Mutex::ScopedLock&);
+ void sendDoOutput(size_t newLimit);
mutable sys::Mutex lock;
bool closing;
diff --git a/qpid/cpp/src/qpid/cluster/UpdateClient.cpp b/qpid/cpp/src/qpid/cluster/UpdateClient.cpp
index f306517d37..8f751add9b 100644
--- a/qpid/cpp/src/qpid/cluster/UpdateClient.cpp
+++ b/qpid/cpp/src/qpid/cluster/UpdateClient.cpp
@@ -7,9 +7,9 @@
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
@@ -26,9 +26,9 @@
#include "qpid/cluster/Decoder.h"
#include "qpid/cluster/ExpiryPolicy.h"
#include "qpid/cluster/UpdateDataExchange.h"
-#include "qpid/client/SessionBase_0_10Access.h"
-#include "qpid/client/ConnectionAccess.h"
-#include "qpid/client/SessionImpl.h"
+#include "qpid/client/SessionBase_0_10Access.h"
+#include "qpid/client/ConnectionAccess.h"
+#include "qpid/client/SessionImpl.h"
#include "qpid/client/ConnectionImpl.h"
#include "qpid/client/Future.h"
#include "qpid/broker/Broker.h"
@@ -49,7 +49,6 @@
#include "qpid/broker/TxPublish.h"
#include "qpid/broker/RecoveredDequeue.h"
#include "qpid/broker/RecoveredEnqueue.h"
-#include "qpid/broker/StatefulQueueObserver.h"
#include "qpid/framing/MessageTransferBody.h"
#include "qpid/framing/ClusterConnectionMembershipBody.h"
#include "qpid/framing/ClusterConnectionShadowReadyBody.h"
@@ -83,20 +82,11 @@ using namespace framing;
namespace arg=client::arg;
using client::SessionBase_0_10Access;
-// Reserved exchange/queue name for catch-up, avoid clashes with user queues/exchanges.
-const std::string UpdateClient::UPDATE("x-qpid.cluster-update");
-// Name for header used to carry expiration information.
-const std::string UpdateClient::X_QPID_EXPIRATION = "x-qpid.expiration";
-// Headers used to flag headers/properties added by the UpdateClient so they can be
-// removed on the other side.
-const std::string UpdateClient::X_QPID_NO_MESSAGE_PROPS = "x-qpid.no-message-props";
-const std::string UpdateClient::X_QPID_NO_HEADERS = "x-qpid.no-headers";
-
std::ostream& operator<<(std::ostream& o, const UpdateClient& c) {
return o << "cluster(" << c.updaterId << " UPDATER)";
}
-struct ClusterConnectionProxy : public AMQP_AllProxy::ClusterConnection, public framing::FrameHandler
+struct ClusterConnectionProxy : public AMQP_AllProxy::ClusterConnection, public framing::FrameHandler
{
boost::shared_ptr<qpid::client::ConnectionImpl> connection;
@@ -130,7 +120,7 @@ void send(client::AsyncSession& s, const AMQBody& body) {
// TODO aconway 2008-09-24: optimization: update connections/sessions in parallel.
UpdateClient::UpdateClient(const MemberId& updater, const MemberId& updatee, const Url& url,
- broker::Broker& broker, const ClusterMap& m, ExpiryPolicy& expiry_,
+ broker::Broker& broker, const ClusterMap& m, ExpiryPolicy& expiry_,
const Cluster::ConnectionVector& cons, Decoder& decoder_,
const boost::function<void()>& ok,
const boost::function<void(const std::exception&)>& fail,
@@ -144,6 +134,9 @@ UpdateClient::UpdateClient(const MemberId& updater, const MemberId& updatee, con
UpdateClient::~UpdateClient() {}
+// Reserved exchange/queue name for catch-up, avoid clashes with user queues/exchanges.
+const std::string UpdateClient::UPDATE("qpid.cluster-update");
+
void UpdateClient::run() {
try {
connection.open(updateeUrl, connectionSettings);
@@ -161,13 +154,6 @@ void UpdateClient::update() {
<< " at " << updateeUrl);
Broker& b = updaterBroker;
- if(b.getExpiryPolicy()) {
- QPID_LOG(debug, *this << "Updating updatee with cluster time");
- qpid::sys::AbsTime clusterTime = b.getExpiryPolicy()->getCurrentTime();
- int64_t time = qpid::sys::Duration(qpid::sys::EPOCH, clusterTime);
- ClusterConnectionProxy(session).clock(time);
- }
-
updateManagementSetupState();
b.getExchanges().eachExchange(boost::bind(&UpdateClient::updateExchange, this, _1));
@@ -181,12 +167,10 @@ void UpdateClient::update() {
boost::bind(&UpdateClient::updateConnection, this, _1));
session.queueDelete(arg::queue=UPDATE);
- // some Queue Observers need session state & msgs synced first, so sync observers now
- b.getQueues().eachQueue(boost::bind(&UpdateClient::updateQueueObservers, this, _1));
-
// Update queue listeners: must come after sessions so consumerNumbering is populated
b.getQueues().eachQueue(boost::bind(&UpdateClient::updateQueueListeners, this, _1));
+ ClusterConnectionProxy(session).expiryId(expiry.getId());
updateLinks();
updateManagementAgent();
@@ -200,7 +184,7 @@ void UpdateClient::update() {
// NOTE: connection will be closed from the other end, don't close
// it here as that causes a race.
-
+
// TODO aconway 2010-03-15: This sleep avoids the race condition
// described in // https://bugzilla.redhat.com/show_bug.cgi?id=568831.
// It allows the connection to fully close before destroying the
@@ -292,7 +276,7 @@ class MessageUpdater {
framing::SequenceNumber lastPos;
client::AsyncSession session;
ExpiryPolicy& expiry;
-
+
public:
MessageUpdater(const string& q, const client::AsyncSession s, ExpiryPolicy& expiry_) : queue(q), haveLastPos(false), session(s), expiry(expiry_) {
@@ -309,6 +293,7 @@ class MessageUpdater {
}
}
+
void updateQueuedMessage(const broker::QueuedMessage& message) {
// Send the queue position if necessary.
if (!haveLastPos || message.position - lastPos != 1) {
@@ -317,23 +302,10 @@ class MessageUpdater {
}
lastPos = message.position;
- // if the ttl > 0, we need to send the calculated expiration time to the updatee
- const DeliveryProperties* dprops =
- message.payload->getProperties<DeliveryProperties>();
- if (dprops && dprops->getTtl() > 0) {
- bool hadMessageProps =
- message.payload->hasProperties<framing::MessageProperties>();
- const framing::MessageProperties* mprops =
- message.payload->getProperties<framing::MessageProperties>();
- bool hadApplicationHeaders = mprops->hasApplicationHeaders();
- message.payload->insertCustomProperty(UpdateClient::X_QPID_EXPIRATION,
- sys::Duration(sys::EPOCH, message.payload->getExpiration()));
- // If message properties or application headers didn't exist
- // prior to us adding data, we want to remove them on the other side.
- if (!hadMessageProps)
- message.payload->insertCustomProperty(UpdateClient::X_QPID_NO_MESSAGE_PROPS, 0);
- else if (!hadApplicationHeaders)
- message.payload->insertCustomProperty(UpdateClient::X_QPID_NO_HEADERS, 0);
+ // Send the expiry ID if necessary.
+ if (message.payload->getProperties<DeliveryProperties>()->getTtl()) {
+ boost::optional<uint64_t> expiryId = expiry.getId(*message.payload);
+ ClusterConnectionProxy(session).expiryId(expiryId?*expiryId:0);
}
// We can't send a broker::Message via the normal client API,
@@ -346,7 +318,7 @@ class MessageUpdater {
framing::MessageTransferBody transfer(
*message.payload->getFrames().as<framing::MessageTransferBody>());
transfer.setDestination(UpdateClient::UPDATE);
-
+
sb.get()->send(transfer, message.payload->getFrames(),
!message.payload->isContentReleased());
if (message.payload->isContentReleased()){
@@ -354,7 +326,7 @@ class MessageUpdater {
uint16_t maxContentSize = maxFrameSize - AMQFrame::frameOverhead();
bool morecontent = true;
for (uint64_t offset = 0; morecontent; offset += maxContentSize)
- {
+ {
AMQFrame frame((AMQContentBody()));
morecontent = message.payload->getContentFrame(*(message.queue), frame, maxContentSize, offset);
sb.get()->sendRawFrame(frame);
@@ -385,8 +357,6 @@ void UpdateClient::updateQueue(client::AsyncSession& s, const boost::shared_ptr<
if (qpid::broker::Fairshare::getState(q->getMessages(), priority, count)) {
ClusterConnectionProxy(s).queueFairshareState(q->getName(), priority, count);
}
-
- ClusterConnectionProxy(s).queueDequeueSincePurgeState(q->getName(), q->getDequeueSincePurge());
}
void UpdateClient::updateExclusiveQueue(const boost::shared_ptr<broker::Queue>& q) {
@@ -419,7 +389,7 @@ void UpdateClient::updateConnection(const boost::intrusive_ptr<Connection>& upda
QPID_LOG(debug, *this << " updating connection " << *updateConnection);
assert(updateConnection->getBrokerConnection());
broker::Connection& bc = *updateConnection->getBrokerConnection();
-
+
// Send the management ID first on the main connection.
std::string mgmtId = updateConnection->getBrokerConnection()->getMgmtId();
ClusterConnectionProxy(session).shadowPrepare(mgmtId);
@@ -456,7 +426,7 @@ void UpdateClient::updateSession(broker::SessionHandler& sh) {
QPID_LOG(debug, *this << " updating session " << ss->getId());
- // Create a client session to update session state.
+ // Create a client session to update session state.
boost::shared_ptr<client::ConnectionImpl> cimpl = client::ConnectionAccess::getImpl(shadowConnection);
boost::shared_ptr<client::SessionImpl> simpl = cimpl->newSession(ss->getId().getName(), ss->getTimeout(), sh.getChannel());
simpl->disableAutoDetach();
@@ -482,12 +452,12 @@ void UpdateClient::updateSession(broker::SessionHandler& sh) {
// Adjust command counter for message in progress, will be sent after state update.
boost::intrusive_ptr<Message> inProgress = ss->getMessageInProgress();
SequenceNumber received = ss->receiverGetReceived().command;
- if (inProgress)
+ if (inProgress)
--received;
// Sync the session to ensure all responses from broker have been processed.
shadowSession.sync();
-
+
// Reset command-sequence state.
proxy.sessionState(
ss->senderGetReplayPoint().command,
@@ -537,7 +507,7 @@ void UpdateClient::updateConsumer(
QPID_LOG(debug, *this << " updated consumer " << ci->getName()
<< " on " << shadowSession.getId());
}
-
+
void UpdateClient::updateUnacked(const broker::DeliveryRecord& dr) {
if (!dr.isEnded() && dr.isAcquired() && dr.getMessage().payload) {
// If the message is acquired then it is no longer on the
@@ -569,7 +539,7 @@ class TxOpUpdater : public broker::TxOpConstVisitor, public MessageUpdater {
void operator()(const broker::DtxAck& ) {
throw InternalErrorException("DTX transactions not currently supported by cluster.");
}
-
+
void operator()(const broker::RecoveredDequeue& rdeq) {
updateMessage(rdeq.getMessage());
proxy.txEnqueue(rdeq.getQueue()->getName());
@@ -589,7 +559,7 @@ class TxOpUpdater : public broker::TxOpConstVisitor, public MessageUpdater {
typedef std::list<Queue::shared_ptr> QueueList;
const QueueList& qlist = txPub.getQueues();
Array qarray(TYPE_CODE_STR8);
- for (QueueList::const_iterator i = qlist.begin(); i != qlist.end(); ++i)
+ for (QueueList::const_iterator i = qlist.begin(); i != qlist.end(); ++i)
qarray.push_back(Array::ValuePtr(new Str8Value((*i)->getName())));
proxy.txPublish(qarray, txPub.delivered);
}
@@ -599,7 +569,7 @@ class TxOpUpdater : public broker::TxOpConstVisitor, public MessageUpdater {
client::AsyncSession session;
ClusterConnectionProxy proxy;
};
-
+
void UpdateClient::updateTxState(broker::SemanticState& s) {
QPID_LOG(debug, *this << " updating TX transaction state.");
ClusterConnectionProxy proxy(shadowSession);
@@ -645,23 +615,4 @@ void UpdateClient::updateBridge(const boost::shared_ptr<broker::Bridge>& bridge)
ClusterConnectionProxy(session).config(encode(*bridge));
}
-void UpdateClient::updateQueueObservers(const boost::shared_ptr<broker::Queue>& q)
-{
- q->eachObserver(boost::bind(&UpdateClient::updateObserver, this, q, _1));
-}
-
-void UpdateClient::updateObserver(const boost::shared_ptr<broker::Queue>& q,
- boost::shared_ptr<broker::QueueObserver> o)
-{
- qpid::framing::FieldTable state;
- broker::StatefulQueueObserver *so = dynamic_cast<broker::StatefulQueueObserver *>(o.get());
- if (so) {
- so->getState( state );
- std::string id(so->getId());
- QPID_LOG(debug, *this << " updating queue " << q->getName() << "'s observer " << id);
- ClusterConnectionProxy(session).queueObserverState( q->getName(), id, state );
- }
-}
-
-
}} // namespace qpid::cluster
diff --git a/qpid/cpp/src/qpid/cluster/UpdateClient.h b/qpid/cpp/src/qpid/cluster/UpdateClient.h
index 21bf6024e0..7520bb82cb 100644
--- a/qpid/cpp/src/qpid/cluster/UpdateClient.h
+++ b/qpid/cpp/src/qpid/cluster/UpdateClient.h
@@ -10,9 +10,9 @@
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
@@ -34,7 +34,7 @@
namespace qpid {
-struct Url;
+class Url;
namespace broker {
@@ -42,8 +42,8 @@ class Broker;
class Queue;
class Exchange;
class QueueBindings;
-struct QueueBinding;
-struct QueuedMessage;
+class QueueBinding;
+class QueuedMessage;
class SessionHandler;
class DeliveryRecord;
class SessionState;
@@ -51,7 +51,6 @@ class SemanticState;
class Decoder;
class Link;
class Bridge;
-class QueueObserver;
} // namespace broker
@@ -69,19 +68,14 @@ class ExpiryPolicy;
class UpdateClient : public sys::Runnable {
public:
static const std::string UPDATE; // Name for special update queue and exchange.
- static const std::string X_QPID_EXPIRATION; // Update message expiration
- // Flag to remove props/headers that were added by the UpdateClient
- static const std::string X_QPID_NO_MESSAGE_PROPS;
- static const std::string X_QPID_NO_HEADERS;
-
static client::Connection catchUpConnection();
-
+
UpdateClient(const MemberId& updater, const MemberId& updatee, const Url&,
broker::Broker& donor, const ClusterMap& map, ExpiryPolicy& expiry,
const std::vector<boost::intrusive_ptr<Connection> >&, Decoder&,
const boost::function<void()>& done,
const boost::function<void(const std::exception&)>& fail,
- const client::ConnectionSettings&
+ const client::ConnectionSettings&
);
~UpdateClient();
@@ -110,8 +104,6 @@ class UpdateClient : public sys::Runnable {
void updateLinks();
void updateLink(const boost::shared_ptr<broker::Link>&);
void updateBridge(const boost::shared_ptr<broker::Bridge>&);
- void updateQueueObservers(const boost::shared_ptr<broker::Queue>&);
- void updateObserver(const boost::shared_ptr<broker::Queue>&, boost::shared_ptr<broker::QueueObserver>);
Numbering<broker::SemanticState::ConsumerImpl*> consumerNumbering;
diff --git a/qpid/cpp/src/qpid/cluster/UpdateDataExchange.cpp b/qpid/cpp/src/qpid/cluster/UpdateDataExchange.cpp
index e5cd82e3d3..2a079b8881 100644
--- a/qpid/cpp/src/qpid/cluster/UpdateDataExchange.cpp
+++ b/qpid/cpp/src/qpid/cluster/UpdateDataExchange.cpp
@@ -36,8 +36,13 @@ const std::string UpdateDataExchange::MANAGEMENT_AGENTS_KEY("management-agents")
const std::string UpdateDataExchange::MANAGEMENT_SCHEMAS_KEY("management-schemas");
const std::string UpdateDataExchange::MANAGEMENT_DELETED_OBJECTS_KEY("management-deleted-objects");
+std::ostream& operator<<(std::ostream& o, const UpdateDataExchange& c) {
+ return o << "cluster(" << c.clusterId << " UPDATER)";
+}
+
UpdateDataExchange::UpdateDataExchange(Cluster& cluster) :
- Exchange(EXCHANGE_NAME, &cluster)
+ Exchange(EXCHANGE_NAME, &cluster),
+ clusterId(cluster.getId())
{}
void UpdateDataExchange::route(broker::Deliverable& msg, const std::string& routingKey,
@@ -57,9 +62,11 @@ void UpdateDataExchange::updateManagementAgent(management::ManagementAgent* agen
framing::Buffer buf1(const_cast<char*>(managementAgents.data()), managementAgents.size());
agent->importAgents(buf1);
+ QPID_LOG(debug, *this << " updated management agents.");
framing::Buffer buf2(const_cast<char*>(managementSchemas.data()), managementSchemas.size());
agent->importSchemas(buf2);
+ QPID_LOG(debug, *this << " updated management schemas.");
using amqp_0_10::ListCodec;
using types::Variant;
@@ -71,6 +78,7 @@ void UpdateDataExchange::updateManagementAgent(management::ManagementAgent* agen
new management::ManagementAgent::DeletedObject(*i)));
}
agent->importDeletedObjects(objects);
+ QPID_LOG(debug, *this << " updated management deleted objects.");
}
diff --git a/qpid/cpp/src/qpid/cluster/UpdateDataExchange.h b/qpid/cpp/src/qpid/cluster/UpdateDataExchange.h
index d2f6c35ad0..8c493e400a 100644
--- a/qpid/cpp/src/qpid/cluster/UpdateDataExchange.h
+++ b/qpid/cpp/src/qpid/cluster/UpdateDataExchange.h
@@ -74,9 +74,11 @@ class UpdateDataExchange : public broker::Exchange
void updateManagementAgent(management::ManagementAgent* agent);
private:
+ MemberId clusterId;
std::string managementAgents;
std::string managementSchemas;
std::string managementDeletedObjects;
+ friend std::ostream& operator<<(std::ostream&, const UpdateDataExchange&);
};
}} // namespace qpid::cluster
diff --git a/qpid/cpp/src/qpid/cluster/UpdateExchange.cpp b/qpid/cpp/src/qpid/cluster/UpdateExchange.cpp
index cb1376004e..11937f296f 100644
--- a/qpid/cpp/src/qpid/cluster/UpdateExchange.cpp
+++ b/qpid/cpp/src/qpid/cluster/UpdateExchange.cpp
@@ -7,9 +7,9 @@
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
@@ -19,7 +19,6 @@
*
*/
#include "qpid/framing/MessageTransferBody.h"
-#include "qpid/framing/FieldTable.h"
#include "qpid/broker/Message.h"
#include "UpdateExchange.h"
@@ -28,8 +27,6 @@ namespace cluster {
using framing::MessageTransferBody;
using framing::DeliveryProperties;
-using framing::MessageProperties;
-using framing::FieldTable;
UpdateExchange::UpdateExchange(management::Manageable* parent)
: broker::Exchange(UpdateClient::UPDATE, parent),
@@ -37,7 +34,6 @@ UpdateExchange::UpdateExchange(management::Manageable* parent)
void UpdateExchange::setProperties(const boost::intrusive_ptr<broker::Message>& msg) {
- // Copy exchange name to destination property.
MessageTransferBody* transfer = msg->getMethod<MessageTransferBody>();
assert(transfer);
const DeliveryProperties* props = msg->getProperties<DeliveryProperties>();
@@ -46,23 +42,6 @@ void UpdateExchange::setProperties(const boost::intrusive_ptr<broker::Message>&
transfer->setDestination(props->getExchange());
else
transfer->clearDestinationFlag();
-
- // Copy expiration from x-property if present.
- if (msg->hasProperties<MessageProperties>()) {
- const MessageProperties* mprops = msg->getProperties<MessageProperties>();
- if (mprops->hasApplicationHeaders()) {
- const FieldTable& headers = mprops->getApplicationHeaders();
- if (headers.isSet(UpdateClient::X_QPID_EXPIRATION)) {
- msg->setExpiration(
- sys::AbsTime(sys::EPOCH, headers.getAsInt64(UpdateClient::X_QPID_EXPIRATION)));
- msg->removeCustomProperty(UpdateClient::X_QPID_EXPIRATION);
- // Erase props/headers that were added by the UpdateClient
- if (headers.isSet(UpdateClient::X_QPID_NO_MESSAGE_PROPS))
- msg->eraseProperties<MessageProperties>();
- else if (headers.isSet(UpdateClient::X_QPID_NO_HEADERS))
- msg->clearApplicationHeadersFlag();
- }
- }
- }
}
+
}} // namespace qpid::cluster
diff --git a/qpid/cpp/src/qpid/cluster/types.h b/qpid/cpp/src/qpid/cluster/types.h
index bfb4fd5b9e..0795e5e77a 100644
--- a/qpid/cpp/src/qpid/cluster/types.h
+++ b/qpid/cpp/src/qpid/cluster/types.h
@@ -24,7 +24,6 @@
#include "config.h"
#include "qpid/Url.h"
-#include "qpid/RefCounted.h"
#include "qpid/sys/IntegerTypes.h"
#include <boost/intrusive_ptr.hpp>
#include <utility>
diff --git a/qpid/cpp/src/qpid/console/SessionManager.cpp b/qpid/cpp/src/qpid/console/SessionManager.cpp
index 910ae22be8..80c5959417 100644
--- a/qpid/cpp/src/qpid/console/SessionManager.cpp
+++ b/qpid/cpp/src/qpid/console/SessionManager.cpp
@@ -362,11 +362,12 @@ void SessionManager::handleCommandComplete(Broker* broker, Buffer& inBuffer, uin
void SessionManager::handleClassInd(Broker* broker, Buffer& inBuffer, uint32_t)
{
+ uint8_t kind;
string packageName;
string className;
uint8_t hash[16];
- /*kind*/ (void) inBuffer.getOctet();
+ kind = inBuffer.getOctet();
inBuffer.getShortString(packageName);
inBuffer.getShortString(className);
inBuffer.getBin128(hash);
diff --git a/qpid/cpp/src/qpid/framing/AMQBody.h b/qpid/cpp/src/qpid/framing/AMQBody.h
index 56d1d250c1..60ac2d3b7e 100644
--- a/qpid/cpp/src/qpid/framing/AMQBody.h
+++ b/qpid/cpp/src/qpid/framing/AMQBody.h
@@ -46,7 +46,7 @@ struct AMQBodyConstVisitor {
virtual void visit(const AMQMethodBody&) = 0;
};
-class QPID_COMMON_CLASS_EXTERN AMQBody : public RefCounted {
+class AMQBody : public RefCounted {
public:
AMQBody() {}
QPID_COMMON_EXTERN virtual ~AMQBody();
diff --git a/qpid/cpp/src/qpid/framing/AMQContentBody.h b/qpid/cpp/src/qpid/framing/AMQContentBody.h
index e25451e354..69813b221c 100644
--- a/qpid/cpp/src/qpid/framing/AMQContentBody.h
+++ b/qpid/cpp/src/qpid/framing/AMQContentBody.h
@@ -29,7 +29,7 @@
namespace qpid {
namespace framing {
-class QPID_COMMON_CLASS_EXTERN AMQContentBody : public AMQBody
+class AMQContentBody : public AMQBody
{
string data;
@@ -37,15 +37,15 @@ public:
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; }
+ 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;
- void accept(AMQBodyConstVisitor& v) const { v.visit(*this); }
- boost::intrusive_ptr<AMQBody> clone() const { return BodyFactory::copy(*this); }
+ 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 5b9673f0d0..cd60cd971f 100644
--- a/qpid/cpp/src/qpid/framing/AMQFrame.cpp
+++ b/qpid/cpp/src/qpid/framing/AMQFrame.cpp
@@ -139,11 +139,6 @@ bool AMQFrame::decode(Buffer& buffer)
return true;
}
-void AMQFrame::cloneBody()
-{
- body = body->clone();
-}
-
std::ostream& operator<<(std::ostream& out, const AMQFrame& f)
{
return
diff --git a/qpid/cpp/src/qpid/framing/AMQFrame.h b/qpid/cpp/src/qpid/framing/AMQFrame.h
index 4f6faf4199..d7b04f0f65 100644
--- a/qpid/cpp/src/qpid/framing/AMQFrame.h
+++ b/qpid/cpp/src/qpid/framing/AMQFrame.h
@@ -33,7 +33,7 @@
namespace qpid {
namespace framing {
-class QPID_COMMON_CLASS_EXTERN AMQFrame : public AMQDataBlock
+class AMQFrame : public AMQDataBlock
{
public:
QPID_COMMON_EXTERN AMQFrame(const boost::intrusive_ptr<AMQBody>& b=0);
@@ -59,11 +59,6 @@ class QPID_COMMON_CLASS_EXTERN AMQFrame : public AMQDataBlock
return boost::polymorphic_downcast<const T*>(getBody());
}
- /**
- * Take a deep copy of the body currently referenced
- */
- QPID_COMMON_EXTERN void cloneBody();
-
QPID_COMMON_EXTERN void encode(Buffer& buffer) const;
QPID_COMMON_EXTERN bool decode(Buffer& buffer);
QPID_COMMON_EXTERN uint32_t encodedSize() const;
diff --git a/qpid/cpp/src/qpid/framing/AMQHeaderBody.h b/qpid/cpp/src/qpid/framing/AMQHeaderBody.h
index 452154eb5c..8d96e35720 100644
--- a/qpid/cpp/src/qpid/framing/AMQHeaderBody.h
+++ b/qpid/cpp/src/qpid/framing/AMQHeaderBody.h
@@ -10,9 +10,9 @@
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
@@ -35,7 +35,7 @@
namespace qpid {
namespace framing {
-class QPID_COMMON_CLASS_EXTERN AMQHeaderBody : public AMQBody
+class AMQHeaderBody : public AMQBody
{
template <class T> struct OptProps { boost::optional<T> props; };
template <class Base, class T>
@@ -58,7 +58,7 @@ class QPID_COMMON_CLASS_EXTERN AMQHeaderBody : public AMQBody
}
else
return Base::decode(buffer, size, type);
- }
+ }
void print(std::ostream& out) const {
const boost::optional<T>& p=this->OptProps<T>::props;
if (p) out << *p;
@@ -77,7 +77,7 @@ class QPID_COMMON_CLASS_EXTERN AMQHeaderBody : public AMQBody
typedef PropSet<PropSet<Empty, DeliveryProperties>, MessageProperties> Properties;
Properties properties;
-
+
public:
inline uint8_t type() const { return HEADER_BODY; }
@@ -99,10 +99,6 @@ public:
return properties.OptProps<T>::props.get_ptr();
}
- template <class T> void erase() {
- properties.OptProps<T>::props.reset();
- }
-
boost::intrusive_ptr<AMQBody> clone() const { return BodyFactory::copy(*this); }
};
diff --git a/qpid/cpp/src/qpid/framing/AMQHeartbeatBody.h b/qpid/cpp/src/qpid/framing/AMQHeartbeatBody.h
index 19ac2be013..9b1fe8a4c1 100644
--- a/qpid/cpp/src/qpid/framing/AMQHeartbeatBody.h
+++ b/qpid/cpp/src/qpid/framing/AMQHeartbeatBody.h
@@ -29,7 +29,7 @@
namespace qpid {
namespace framing {
-class QPID_COMMON_CLASS_EXTERN AMQHeartbeatBody : public AMQBody
+class AMQHeartbeatBody : public AMQBody
{
public:
QPID_COMMON_EXTERN virtual ~AMQHeartbeatBody();
diff --git a/qpid/cpp/src/qpid/framing/FieldTable.cpp b/qpid/cpp/src/qpid/framing/FieldTable.cpp
index 21eaea0f4d..023e4af819 100644
--- a/qpid/cpp/src/qpid/framing/FieldTable.cpp
+++ b/qpid/cpp/src/qpid/framing/FieldTable.cpp
@@ -129,7 +129,7 @@ FieldTable::ValuePtr FieldTable::get(const std::string& name) const
namespace {
template <class T> T default_value() { return T(); }
template <> int default_value<int>() { return 0; }
- //template <> uint64_t default_value<uint64_t>() { return 0; }
+ template <> uint64_t default_value<uint64_t>() { return 0; }
}
template <class T>
diff --git a/qpid/cpp/src/qpid/framing/MethodBodyFactory.h b/qpid/cpp/src/qpid/framing/MethodBodyFactory.h
index 88bc444795..607ec9d959 100644
--- a/qpid/cpp/src/qpid/framing/MethodBodyFactory.h
+++ b/qpid/cpp/src/qpid/framing/MethodBodyFactory.h
@@ -22,7 +22,6 @@
*
*/
#include "qpid/framing/amqp_types.h"
-#include "qpid/framing/AMQBody.h"
#include <boost/intrusive_ptr.hpp>
namespace qpid {
diff --git a/qpid/cpp/src/qpid/framing/SendContent.h b/qpid/cpp/src/qpid/framing/SendContent.h
index 1c464b9c8b..745c948c9e 100644
--- a/qpid/cpp/src/qpid/framing/SendContent.h
+++ b/qpid/cpp/src/qpid/framing/SendContent.h
@@ -37,7 +37,7 @@ namespace framing {
*/
class SendContent
{
- FrameHandler& handler;
+ mutable FrameHandler& handler;
const uint16_t maxFrameSize;
uint expectedFrameCount;
uint frameCount;
diff --git a/qpid/cpp/src/qpid/framing/TransferContent.h b/qpid/cpp/src/qpid/framing/TransferContent.h
index 9a698a1823..5fe1a513a9 100644
--- a/qpid/cpp/src/qpid/framing/TransferContent.h
+++ b/qpid/cpp/src/qpid/framing/TransferContent.h
@@ -32,7 +32,7 @@ namespace qpid {
namespace framing {
/** Message content */
-class QPID_COMMON_CLASS_EXTERN TransferContent : public MethodContent
+class TransferContent : public MethodContent
{
AMQHeaderBody header;
std::string data;
diff --git a/qpid/cpp/src/qpid/log/Logger.cpp b/qpid/cpp/src/qpid/log/Logger.cpp
index 1600822142..2217cdddbd 100644
--- a/qpid/cpp/src/qpid/log/Logger.cpp
+++ b/qpid/cpp/src/qpid/log/Logger.cpp
@@ -22,7 +22,6 @@
#include "qpid/memory.h"
#include "qpid/sys/Thread.h"
#include "qpid/sys/Time.h"
-#include "qpid/DisableExceptionLogging.h"
#include <boost/pool/detail/singleton.hpp>
#include <boost/bind.hpp>
#include <boost/function.hpp>
@@ -49,16 +48,11 @@ Logger& Logger::instance() {
}
Logger::Logger() : flags(0) {
- // Disable automatic logging in Exception constructors to avoid
- // re-entrant use of logger singleton if there is an error in
- // option parsing.
- DisableExceptionLogging del;
-
// Initialize myself from env variables so all programs
// (e.g. tests) can use logging even if they don't parse
// command line args.
Options opts("");
- opts.parse(0, 0);
+ opts.parse(0, 0);
configure(opts);
}
@@ -79,12 +73,8 @@ void Logger::log(const Statement& s, const std::string& msg) {
std::ostringstream os;
if (!prefix.empty())
os << prefix << ": ";
- if (flags&TIME) {
- if (flags&HIRES)
- qpid::sys::outputHiresNow(os);
- else
- qpid::sys::outputFormattedNow(os);
- }
+ if (flags&TIME)
+ qpid::sys::outputFormattedNow(os);
if (flags&LEVEL)
os << LevelTraits::name(s.level) << " ";
if (flags&THREAD)
@@ -133,8 +123,7 @@ int Logger::format(const Options& opts) {
bitIf(opts.time, TIME) |
bitIf(opts.source, (FILE|LINE)) |
bitIf(opts.function, FUNCTION) |
- bitIf(opts.thread, THREAD) |
- bitIf(opts.hiresTs, HIRES);
+ bitIf(opts.thread, THREAD);
format(flags);
return flags;
}
@@ -151,7 +140,7 @@ void Logger::configure(const Options& opts) {
Options o(opts);
if (o.trace)
o.selectors.push_back("trace+");
- format(o);
+ format(o);
select(Selector(o));
setPrefix(opts.prefix);
options.sinkOptions->setup(this);
diff --git a/qpid/cpp/src/qpid/log/Options.cpp b/qpid/cpp/src/qpid/log/Options.cpp
index 0001d00bdf..24ef413cbc 100644
--- a/qpid/cpp/src/qpid/log/Options.cpp
+++ b/qpid/cpp/src/qpid/log/Options.cpp
@@ -38,7 +38,6 @@ Options::Options(const std::string& argv0_, const std::string& name_) :
thread(false),
source(false),
function(false),
- hiresTs(false),
trace(false),
sinkOptions (SinkOptions::create(argv0_))
{
@@ -66,7 +65,6 @@ Options::Options(const std::string& argv0_, const std::string& name_) :
("log-source", optValue(source,"yes|no"), "Include source file:line in log messages")
("log-thread", optValue(thread,"yes|no"), "Include thread ID in log messages")
("log-function", optValue(function,"yes|no"), "Include function signature in log messages")
- ("log-hires-timestamp", optValue(hiresTs,"yes|no"), "Use unformatted hi-res timestamp in log messages")
("log-prefix", optValue(prefix,"STRING"), "Prefix to append to all log messages")
;
add(*sinkOptions);
@@ -82,7 +80,6 @@ Options::Options(const Options &o) :
thread(o.thread),
source(o.source),
function(o.function),
- hiresTs(o.hiresTs),
trace(o.trace),
prefix(o.prefix),
sinkOptions (SinkOptions::create(o.argv0))
@@ -100,7 +97,6 @@ Options& Options::operator=(const Options& x) {
thread = x.thread;
source = x.source;
function = x.function;
- hiresTs = x.hiresTs;
trace = x.trace;
prefix = x.prefix;
*sinkOptions = *x.sinkOptions;
diff --git a/qpid/cpp/src/qpid/log/windows/SinkOptions.cpp b/qpid/cpp/src/qpid/log/windows/SinkOptions.cpp
index 0c74bea64e..28f4b267e0 100644
--- a/qpid/cpp/src/qpid/log/windows/SinkOptions.cpp
+++ b/qpid/cpp/src/qpid/log/windows/SinkOptions.cpp
@@ -53,7 +53,7 @@ static int eventTypes[qpid::log::LevelTraits::COUNT] = {
class EventLogOutput : public qpid::log::Logger::Output {
public:
- EventLogOutput(const std::string& /*sourceName*/) : logHandle(0)
+ EventLogOutput(const std::string& sourceName) : logHandle(0)
{
logHandle = OpenEventLog(0, "Application");
}
@@ -83,7 +83,7 @@ private:
HANDLE logHandle;
};
-SinkOptions::SinkOptions(const std::string& /*argv0*/)
+SinkOptions::SinkOptions(const std::string& argv0)
: qpid::log::SinkOptions(),
logToStderr(true),
logToStdout(false),
diff --git a/qpid/cpp/src/qpid/log/windows/SinkOptions.h b/qpid/cpp/src/qpid/log/windows/SinkOptions.h
index f270c504a2..605822fd46 100644
--- a/qpid/cpp/src/qpid/log/windows/SinkOptions.h
+++ b/qpid/cpp/src/qpid/log/windows/SinkOptions.h
@@ -26,7 +26,7 @@ namespace qpid {
namespace log {
namespace windows {
-struct QPID_COMMON_CLASS_EXTERN SinkOptions : public qpid::log::SinkOptions {
+struct SinkOptions : public qpid::log::SinkOptions {
QPID_COMMON_EXTERN SinkOptions(const std::string& argv0);
virtual ~SinkOptions() {}
diff --git a/qpid/cpp/src/qpid/management/ManagementAgent.cpp b/qpid/cpp/src/qpid/management/ManagementAgent.cpp
index 50fdc82ee0..8b4defaa73 100644
--- a/qpid/cpp/src/qpid/management/ManagementAgent.cpp
+++ b/qpid/cpp/src/qpid/management/ManagementAgent.cpp
@@ -75,18 +75,6 @@ namespace {
}
return n2;
}
-
-struct ScopedManagementContext
-{
- ScopedManagementContext(const qpid::broker::ConnectionState* context)
- {
- setManagementExecutionContext(context);
- }
- ~ScopedManagementContext()
- {
- setManagementExecutionContext(0);
- }
-};
}
@@ -548,7 +536,6 @@ void ManagementAgent::sendBufferLH(Buffer& buf,
dp->setRoutingKey(routingKey);
msg->getFrames().append(content);
- msg->setIsManagementMessage(true);
{
sys::Mutex::ScopedUnlock u(userLock);
@@ -614,7 +601,7 @@ void ManagementAgent::sendBufferLH(const string& data,
props->setAppId("qmf2");
for (i = headers.begin(); i != headers.end(); ++i) {
- msg->insertCustomProperty(i->first, i->second.asString());
+ msg->getOrInsertHeaders().setString(i->first, i->second.asString());
}
DeliveryProperties* dp =
@@ -625,7 +612,6 @@ void ManagementAgent::sendBufferLH(const string& data,
msg->setTimestamp(broker->getExpiryPolicy());
}
msg->getFrames().append(content);
- msg->setIsManagementMessage(true);
{
sys::Mutex::ScopedUnlock u(userLock);
@@ -2252,7 +2238,7 @@ void ManagementAgent::dispatchAgentCommandLH(Message& msg, bool viaLocal)
uint32_t bufferLen = inBuffer.getPosition();
inBuffer.reset();
- ScopedManagementContext context((const qpid::broker::ConnectionState*) msg.getPublisher());
+ setManagementExecutionContext((const qpid::broker::ConnectionState*) msg.getPublisher());
const framing::FieldTable *headers = msg.getApplicationHeaders();
if (headers && msg.getAppId() == "qmf2")
{
@@ -2756,14 +2742,200 @@ void ManagementAgent::debugSnapshot(const char* title) {
title << ": new objects" << dumpVector(newManagementObjects));
}
-
Variant::Map ManagementAgent::toMap(const FieldTable& from)
{
Variant::Map map;
- qpid::amqp_0_10::translate(from, map);
+
+ for (FieldTable::const_iterator iter = from.begin(); iter != from.end(); iter++) {
+ const string& key(iter->first);
+ const FieldTable::ValuePtr& val(iter->second);
+
+ map[key] = toVariant(val);
+ }
+
return map;
}
+Variant::List ManagementAgent::toList(const List& from)
+{
+ Variant::List _list;
+
+ for (List::const_iterator iter = from.begin(); iter != from.end(); iter++) {
+ const List::ValuePtr& val(*iter);
+
+ _list.push_back(toVariant(val));
+ }
+
+ return _list;
+}
+
+qpid::framing::FieldTable ManagementAgent::fromMap(const Variant::Map& from)
+{
+ qpid::framing::FieldTable ft;
+
+ for (Variant::Map::const_iterator iter = from.begin();
+ iter != from.end();
+ iter++) {
+ const string& key(iter->first);
+ const Variant& val(iter->second);
+
+ ft.set(key, toFieldValue(val));
+ }
+
+ return ft;
+}
+
+
+List ManagementAgent::fromList(const Variant::List& from)
+{
+ List fa;
+
+ for (Variant::List::const_iterator iter = from.begin();
+ iter != from.end();
+ iter++) {
+ const Variant& val(*iter);
+
+ fa.push_back(toFieldValue(val));
+ }
+
+ return fa;
+}
+
+
+boost::shared_ptr<FieldValue> ManagementAgent::toFieldValue(const Variant& in)
+{
+
+ switch(in.getType()) {
+
+ case types::VAR_VOID: return boost::shared_ptr<FieldValue>(new VoidValue());
+ case types::VAR_BOOL: return boost::shared_ptr<FieldValue>(new BoolValue(in.asBool()));
+ case types::VAR_UINT8: return boost::shared_ptr<FieldValue>(new Unsigned8Value(in.asUint8()));
+ case types::VAR_UINT16: return boost::shared_ptr<FieldValue>(new Unsigned16Value(in.asUint16()));
+ case types::VAR_UINT32: return boost::shared_ptr<FieldValue>(new Unsigned32Value(in.asUint32()));
+ case types::VAR_UINT64: return boost::shared_ptr<FieldValue>(new Unsigned64Value(in.asUint64()));
+ case types::VAR_INT8: return boost::shared_ptr<FieldValue>(new Integer8Value(in.asInt8()));
+ case types::VAR_INT16: return boost::shared_ptr<FieldValue>(new Integer16Value(in.asInt16()));
+ case types::VAR_INT32: return boost::shared_ptr<FieldValue>(new Integer32Value(in.asInt32()));
+ case types::VAR_INT64: return boost::shared_ptr<FieldValue>(new Integer64Value(in.asInt64()));
+ case types::VAR_FLOAT: return boost::shared_ptr<FieldValue>(new FloatValue(in.asFloat()));
+ case types::VAR_DOUBLE: return boost::shared_ptr<FieldValue>(new DoubleValue(in.asDouble()));
+ case types::VAR_STRING: return boost::shared_ptr<FieldValue>(new Str16Value(in.asString()));
+ case types::VAR_UUID: return boost::shared_ptr<FieldValue>(new UuidValue(in.asUuid().data()));
+ case types::VAR_MAP: return boost::shared_ptr<FieldValue>(new FieldTableValue(ManagementAgent::fromMap(in.asMap())));
+ case types::VAR_LIST: return boost::shared_ptr<FieldValue>(new ListValue(ManagementAgent::fromList(in.asList())));
+ }
+
+ QPID_LOG(error, "Unknown Variant type - not converted: [" << in.getType() << "]");
+ return boost::shared_ptr<FieldValue>(new VoidValue());
+}
+
+// stolen from qpid/client/amqp0_10/Codecs.cpp - TODO: make Codecs public, and remove this dup.
+Variant ManagementAgent::toVariant(const boost::shared_ptr<FieldValue>& in)
+{
+ const string iso885915("iso-8859-15");
+ const string utf8("utf8");
+ const string utf16("utf16");
+ //const string binary("binary");
+ const string amqp0_10_binary("amqp0-10:binary");
+ //const string amqp0_10_bit("amqp0-10:bit");
+ const string amqp0_10_datetime("amqp0-10:datetime");
+ const string amqp0_10_struct("amqp0-10:struct");
+ Variant out;
+
+ //based on AMQP 0-10 typecode, pick most appropriate variant type
+ switch (in->getType()) {
+ //Fixed Width types:
+ case 0x00: //bin8
+ case 0x01: out.setEncoding(amqp0_10_binary); // int8
+ case 0x02: out = in->getIntegerValue<int8_t, 1>(); break; //uint8
+ case 0x03: out = in->getIntegerValue<uint8_t, 1>(); break; //
+ // case 0x04: break; //TODO: iso-8859-15 char // char
+ case 0x08: out = static_cast<bool>(in->getIntegerValue<uint8_t, 1>()); break; // bool int8
+
+ case 0x10: out.setEncoding(amqp0_10_binary); // bin16
+ case 0x11: out = in->getIntegerValue<int16_t, 2>(); break; // int16
+ case 0x12: out = in->getIntegerValue<uint16_t, 2>(); break; //uint16
+
+ case 0x20: out.setEncoding(amqp0_10_binary); // bin32
+ case 0x21: out = in->getIntegerValue<int32_t, 4>(); break; // int32
+ case 0x22: out = in->getIntegerValue<uint32_t, 4>(); break; // uint32
+
+ case 0x23: out = in->get<float>(); break; // float(32)
+
+ // case 0x27: break; //TODO: utf-32 char
+
+ case 0x30: out.setEncoding(amqp0_10_binary); // bin64
+ case 0x31: out = in->getIntegerValue<int64_t, 8>(); break; //int64
+
+ case 0x38: out.setEncoding(amqp0_10_datetime); //treat datetime as uint64_t, but set encoding
+ case 0x32: out = in->getIntegerValue<uint64_t, 8>(); break; //uint64
+ case 0x33: out = in->get<double>(); break; // double
+
+ case 0x48: // uuid
+ {
+ unsigned char data[16];
+ in->getFixedWidthValue<16>(data);
+ out = qpid::types::Uuid(data);
+ } break;
+
+ //TODO: figure out whether and how to map values with codes 0x40-0xd8
+
+ case 0xf0: break;//void, which is the default value for Variant
+ // case 0xf1: out.setEncoding(amqp0_10_bit); break;//treat 'bit' as void, which is the default value for Variant
+
+ //Variable Width types:
+ //strings:
+ case 0x80: // str8
+ case 0x90: // str16
+ case 0xa0: // str32
+ out = in->get<string>();
+ out.setEncoding(amqp0_10_binary);
+ break;
+
+ case 0x84: // str8
+ case 0x94: // str16
+ out = in->get<string>();
+ out.setEncoding(iso885915);
+ break;
+
+ case 0x85: // str8
+ case 0x95: // str16
+ out = in->get<string>();
+ out.setEncoding(utf8);
+ break;
+
+ case 0x86: // str8
+ case 0x96: // str16
+ out = in->get<string>();
+ out.setEncoding(utf16);
+ break;
+
+ case 0xab: // str32
+ out = in->get<string>();
+ out.setEncoding(amqp0_10_struct);
+ break;
+
+ case 0xa8: // map
+ out = ManagementAgent::toMap(in->get<FieldTable>());
+ break;
+
+ case 0xa9: // list of variant types
+ out = ManagementAgent::toList(in->get<List>());
+ break;
+ //case 0xaa: //convert amqp0-10 array (uniform type) into variant list
+ // out = Variant::List();
+ // translate<Array>(in, out.asList(), &toVariant);
+ // break;
+
+ default:
+ //error?
+ QPID_LOG(error, "Unknown FieldValue type - not converted: [" << (unsigned int)(in->getType()) << "]");
+ break;
+ }
+
+ return out;
+}
+
// Build up a list of the current set of deleted objects that are pending their
// next (last) publish-ment.
diff --git a/qpid/cpp/src/qpid/management/ManagementAgent.h b/qpid/cpp/src/qpid/management/ManagementAgent.h
index c21f384433..fb15dc6ed1 100644
--- a/qpid/cpp/src/qpid/management/ManagementAgent.h
+++ b/qpid/cpp/src/qpid/management/ManagementAgent.h
@@ -145,7 +145,13 @@ public:
const framing::Uuid& getUuid() const { return uuid; }
void setUuid(const framing::Uuid& id) { uuid = id; writeData(); }
+ // TODO: remove these when Variant API moved into common library.
static types::Variant::Map toMap(const framing::FieldTable& from);
+ static framing::FieldTable fromMap(const types::Variant::Map& from);
+ static types::Variant::List toList(const framing::List& from);
+ static framing::List fromList(const types::Variant::List& from);
+ static boost::shared_ptr<framing::FieldValue> toFieldValue(const types::Variant& in);
+ static types::Variant toVariant(const boost::shared_ptr<framing::FieldValue>& val);
// For Clustering: management objects that have been marked as
// "deleted", but are waiting for their last published object
diff --git a/qpid/cpp/src/qpid/messaging/AddressParser.cpp b/qpid/cpp/src/qpid/messaging/AddressParser.cpp
index 83aca82be4..4c8f35fbc5 100644
--- a/qpid/cpp/src/qpid/messaging/AddressParser.cpp
+++ b/qpid/cpp/src/qpid/messaging/AddressParser.cpp
@@ -151,7 +151,7 @@ bool AddressParser::readValueIfExists(Variant& value)
bool AddressParser::readString(std::string& value, char delimiter)
{
if (readChar(delimiter)) {
- std::string::size_type start = current;
+ std::string::size_type start = current++;
while (!eos()) {
if (input.at(current) == delimiter) {
if (current > start) {
diff --git a/qpid/cpp/src/qpid/messaging/Duration.cpp b/qpid/cpp/src/qpid/messaging/Duration.cpp
index a23e9f5bcb..a2c443c746 100644
--- a/qpid/cpp/src/qpid/messaging/Duration.cpp
+++ b/qpid/cpp/src/qpid/messaging/Duration.cpp
@@ -37,16 +37,6 @@ Duration operator*(uint64_t multiplier, const Duration& duration)
return Duration(duration.getMilliseconds() * multiplier);
}
-bool operator==(const Duration& a, const Duration& b)
-{
- return a.getMilliseconds() == b.getMilliseconds();
-}
-
-bool operator!=(const Duration& a, const Duration& b)
-{
- return a.getMilliseconds() != b.getMilliseconds();
-}
-
const Duration Duration::FOREVER(std::numeric_limits<uint64_t>::max());
const Duration Duration::IMMEDIATE(0);
const Duration Duration::SECOND(1000);
diff --git a/qpid/cpp/src/qpid/messaging/Session.cpp b/qpid/cpp/src/qpid/messaging/Session.cpp
index cccfd9a873..496953a8e5 100644
--- a/qpid/cpp/src/qpid/messaging/Session.cpp
+++ b/qpid/cpp/src/qpid/messaging/Session.cpp
@@ -39,8 +39,7 @@ Session& Session::operator=(const Session& s) { return PI::assign(*this, s); }
void Session::commit() { impl->commit(); }
void Session::rollback() { impl->rollback(); }
void Session::acknowledge(bool sync) { impl->acknowledge(sync); }
-void Session::acknowledge(Message& m, bool s) { impl->acknowledge(m, false); sync(s); }
-void Session::acknowledgeUpTo(Message& m, bool s) { impl->acknowledge(m, true); sync(s); }
+void Session::acknowledge(Message& m, bool s) { impl->acknowledge(m); sync(s); }
void Session::reject(Message& m) { impl->reject(m); }
void Session::release(Message& m) { impl->release(m); }
void Session::close() { impl->close(); }
diff --git a/qpid/cpp/src/qpid/messaging/SessionImpl.h b/qpid/cpp/src/qpid/messaging/SessionImpl.h
index 60ae615253..02a254e4f2 100644
--- a/qpid/cpp/src/qpid/messaging/SessionImpl.h
+++ b/qpid/cpp/src/qpid/messaging/SessionImpl.h
@@ -41,7 +41,7 @@ class SessionImpl : public virtual qpid::RefCounted
virtual void commit() = 0;
virtual void rollback() = 0;
virtual void acknowledge(bool sync) = 0;
- virtual void acknowledge(Message&, bool cumulative) = 0;
+ virtual void acknowledge(Message&) = 0;
virtual void reject(Message&) = 0;
virtual void release(Message&) = 0;
virtual void close() = 0;
diff --git a/qpid/cpp/src/qpid/replication/ReplicatingEventListener.cpp b/qpid/cpp/src/qpid/replication/ReplicatingEventListener.cpp
index 0ced4d9161..b7d52372f4 100644
--- a/qpid/cpp/src/qpid/replication/ReplicatingEventListener.cpp
+++ b/qpid/cpp/src/qpid/replication/ReplicatingEventListener.cpp
@@ -69,9 +69,10 @@ void ReplicatingEventListener::deliverDequeueMessage(const QueuedMessage& dequeu
void ReplicatingEventListener::deliverEnqueueMessage(const QueuedMessage& enqueued)
{
boost::intrusive_ptr<Message> msg(cloneMessage(*(enqueued.queue), enqueued.payload));
- msg->insertCustomProperty(REPLICATION_TARGET_QUEUE, enqueued.queue->getName());
- msg->insertCustomProperty(REPLICATION_EVENT_TYPE, ENQUEUE);
- msg->insertCustomProperty(QUEUE_MESSAGE_POSITION,enqueued.position);
+ FieldTable& headers = msg->getProperties<MessageProperties>()->getApplicationHeaders();
+ headers.setString(REPLICATION_TARGET_QUEUE, enqueued.queue->getName());
+ headers.setInt(REPLICATION_EVENT_TYPE, ENQUEUE);
+ headers.setInt(QUEUE_MESSAGE_POSITION,enqueued.position);
route(msg);
}
diff --git a/qpid/cpp/src/qpid/replication/ReplicationExchange.cpp b/qpid/cpp/src/qpid/replication/ReplicationExchange.cpp
index 89a2bf516d..4b6d25ac7d 100644
--- a/qpid/cpp/src/qpid/replication/ReplicationExchange.cpp
+++ b/qpid/cpp/src/qpid/replication/ReplicationExchange.cpp
@@ -97,10 +97,11 @@ void ReplicationExchange::handleEnqueueEvent(const FieldTable* args, Deliverable
} else {
queue->setPosition(seqno1);
- msg.getMessage().removeCustomProperty(REPLICATION_TARGET_QUEUE);
- msg.getMessage().removeCustomProperty(REPLICATION_EVENT_SEQNO);
- msg.getMessage().removeCustomProperty(REPLICATION_EVENT_TYPE);
- msg.getMessage().removeCustomProperty(QUEUE_MESSAGE_POSITION);
+ FieldTable& headers = msg.getMessage().getProperties<MessageProperties>()->getApplicationHeaders();
+ headers.erase(REPLICATION_TARGET_QUEUE);
+ headers.erase(REPLICATION_EVENT_SEQNO);
+ headers.erase(REPLICATION_EVENT_TYPE);
+ headers.erase(QUEUE_MESSAGE_POSITION);
msg.deliverTo(queue);
QPID_LOG(debug, "Enqueued replicated message onto " << queueName);
if (mgmtExchange != 0) {
diff --git a/qpid/cpp/src/qpid/store/StorageProvider.h b/qpid/cpp/src/qpid/store/StorageProvider.h
index d162cc58ec..bc8d187517 100644
--- a/qpid/cpp/src/qpid/store/StorageProvider.h
+++ b/qpid/cpp/src/qpid/store/StorageProvider.h
@@ -54,7 +54,7 @@ struct QueueEntry {
QueueEntry(uint64_t id, TplStatus tpl = NONE, const std::string& x = "")
: queueId(id), tplStatus(tpl), xid(x) {}
- bool operator==(const QueueEntry& rhs) const {
+ bool operator==(const QueueEntry& rhs) {
if (queueId != rhs.queueId) return false;
if (tplStatus == NONE && rhs.tplStatus == NONE) return true;
return xid == rhs.xid;
diff --git a/qpid/cpp/src/qpid/sys/AggregateOutput.h b/qpid/cpp/src/qpid/sys/AggregateOutput.h
index d7c0ff29e3..6dad998bb0 100644
--- a/qpid/cpp/src/qpid/sys/AggregateOutput.h
+++ b/qpid/cpp/src/qpid/sys/AggregateOutput.h
@@ -41,7 +41,7 @@ namespace sys {
* doOutput is called in another.
*/
-class QPID_COMMON_CLASS_EXTERN AggregateOutput : public OutputTask, public OutputControl
+class AggregateOutput : public OutputTask, public OutputControl
{
typedef std::deque<OutputTask*> TaskList;
diff --git a/qpid/cpp/src/qpid/sys/AsynchIO.h b/qpid/cpp/src/qpid/sys/AsynchIO.h
index 41f74f7ed0..50da8fa4fc 100644
--- a/qpid/cpp/src/qpid/sys/AsynchIO.h
+++ b/qpid/cpp/src/qpid/sys/AsynchIO.h
@@ -64,8 +64,8 @@ public:
// deletes. To correctly manage heaps when needed, the allocate and
// delete should both be done from the same class/library.
QPID_COMMON_EXTERN static AsynchConnector* create(const Socket& s,
- const std::string& hostname,
- const std::string& port,
+ std::string hostname,
+ uint16_t port,
ConnectedCallback connCb,
FailedCallback failCb);
virtual void start(boost::shared_ptr<Poller> poller) = 0;
diff --git a/qpid/cpp/src/qpid/sys/AsynchIOHandler.h b/qpid/cpp/src/qpid/sys/AsynchIOHandler.h
index b9867606c4..e1885bac79 100644
--- a/qpid/cpp/src/qpid/sys/AsynchIOHandler.h
+++ b/qpid/cpp/src/qpid/sys/AsynchIOHandler.h
@@ -57,7 +57,7 @@ class AsynchIOHandler : public OutputControl {
QPID_COMMON_EXTERN ~AsynchIOHandler();
QPID_COMMON_EXTERN void init(AsynchIO* a, int numBuffs);
- QPID_COMMON_INLINE_EXTERN void setClient() { isClient = true; }
+ QPID_COMMON_EXTERN void setClient() { isClient = true; }
// Output side
QPID_COMMON_EXTERN void abort();
diff --git a/qpid/cpp/src/qpid/sys/AtomicValue.h b/qpid/cpp/src/qpid/sys/AtomicValue.h
index bf995f991e..6e90eafead 100644
--- a/qpid/cpp/src/qpid/sys/AtomicValue.h
+++ b/qpid/cpp/src/qpid/sys/AtomicValue.h
@@ -22,12 +22,7 @@
*
*/
-// Have to check for clang before gcc as clang pretends to be gcc too
-#if defined( __clang__ )
-// Use the clang doesn't support atomic builtins for 64 bit values, so use the slow versions
-#include "qpid/sys/AtomicValue_mutex.h"
-
-#elif defined( __GNUC__ ) && __GNUC__ >= 4 && ( defined( __i686__ ) || defined( __x86_64__ ) )
+#if defined( __GNUC__ ) && __GNUC__ >= 4 && ( defined( __i686__ ) || defined( __x86_64__ ) )
// Use the Gnu C built-in atomic operations if compiling with gcc on a suitable platform.
#include "qpid/sys/AtomicValue_gcc.h"
diff --git a/qpid/cpp/src/qpid/sys/AtomicValue_gcc.h b/qpid/cpp/src/qpid/sys/AtomicValue_gcc.h
index 724bae422e..d022b07c1d 100644
--- a/qpid/cpp/src/qpid/sys/AtomicValue_gcc.h
+++ b/qpid/cpp/src/qpid/sys/AtomicValue_gcc.h
@@ -10,9 +10,9 @@
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
@@ -39,9 +39,6 @@ class AtomicValue
public:
AtomicValue(T init=0) : value(init) {}
- // Not atomic. Don't call concurrently with atomic ops.
- AtomicValue<T>& operator=(T newValue) { value = newValue; return *this; }
-
// Update and return new value.
inline T operator+=(T n) { return __sync_add_and_fetch(&value, n); }
inline T operator-=(T n) { return __sync_sub_and_fetch(&value, n); }
@@ -57,11 +54,11 @@ class AtomicValue
/** If current value == testval then set to newval. Returns the old value. */
T valueCompareAndSwap(T testval, T newval) { return __sync_val_compare_and_swap(&value, testval, newval); }
- /** If current value == testval then set to newval. Returns true if the swap was performed. */
+ /** If current value == testval then set to newval. Returns true if the swap was performed. */
bool boolCompareAndSwap(T testval, T newval) { return __sync_bool_compare_and_swap(&value, testval, newval); }
T get() const { return const_cast<AtomicValue<T>*>(this)->fetchAndAdd(static_cast<T>(0)); }
-
+
private:
T value;
};
diff --git a/qpid/cpp/src/qpid/sys/ClusterSafe.cpp b/qpid/cpp/src/qpid/sys/ClusterSafe.cpp
index dd37615145..b67b04c267 100644
--- a/qpid/cpp/src/qpid/sys/ClusterSafe.cpp
+++ b/qpid/cpp/src/qpid/sys/ClusterSafe.cpp
@@ -51,16 +51,6 @@ ClusterSafeScope::~ClusterSafeScope() {
inContext = save;
}
-ClusterUnsafeScope::ClusterUnsafeScope() {
- save = inContext;
- inContext = false;
-}
-
-ClusterUnsafeScope::~ClusterUnsafeScope() {
- assert(!inContext);
- inContext = save;
-}
-
void enableClusterSafe() { inCluster = true; }
}} // namespace qpid::sys
diff --git a/qpid/cpp/src/qpid/sys/ClusterSafe.h b/qpid/cpp/src/qpid/sys/ClusterSafe.h
index 27e4eb46a5..42e290f4c8 100644
--- a/qpid/cpp/src/qpid/sys/ClusterSafe.h
+++ b/qpid/cpp/src/qpid/sys/ClusterSafe.h
@@ -53,8 +53,10 @@ QPID_COMMON_EXTERN void assertClusterSafe();
QPID_COMMON_EXTERN bool isClusterSafe();
/**
- * Mark a scope as cluster safe. Sets isClusterSafe in constructor and resets
- * to previous value in destructor.
+ * Base class for classes that encapsulate state which is replicated
+ * to all members of a cluster. Acts as a marker for clustered state
+ * and provides functions to assist detecting bugs in cluster
+ * behavior.
*/
class ClusterSafeScope {
public:
@@ -65,18 +67,6 @@ class ClusterSafeScope {
};
/**
- * Mark a scope as cluster unsafe. Clears isClusterSafe in constructor and resets
- * to previous value in destructor.
- */
-class ClusterUnsafeScope {
- public:
- QPID_COMMON_EXTERN ClusterUnsafeScope();
- QPID_COMMON_EXTERN ~ClusterUnsafeScope();
- private:
- bool save;
-};
-
-/**
* Enable cluster-safe assertions. By default they are no-ops.
* Called by cluster code.
*/
diff --git a/qpid/cpp/src/qpid/sys/PollableQueue.h b/qpid/cpp/src/qpid/sys/PollableQueue.h
index 03b9d0084d..81c2301c1e 100644
--- a/qpid/cpp/src/qpid/sys/PollableQueue.h
+++ b/qpid/cpp/src/qpid/sys/PollableQueue.h
@@ -10,9 +10,9 @@
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
@@ -28,8 +28,7 @@
#include <boost/function.hpp>
#include <boost/bind.hpp>
#include <algorithm>
-#include <deque>
-#include "qpid/log/Statement.h" // FIXME aconway 2011-08-05:
+#include <vector>
namespace qpid {
namespace sys {
@@ -45,7 +44,7 @@ class Poller;
template <class T>
class PollableQueue {
public:
- typedef std::deque<T> Batch;
+ typedef std::vector<T> Batch;
typedef T value_type;
/**
@@ -69,11 +68,11 @@ class PollableQueue {
const boost::shared_ptr<sys::Poller>& poller);
~PollableQueue();
-
+
/** Push a value onto the queue. Thread safe */
void push(const T& t);
- /** Start polling. */
+ /** Start polling. */
void start();
/** Stop polling and wait for the current callback, if any, to complete. */
@@ -91,14 +90,14 @@ class PollableQueue {
* ensure clean shutdown with no events left on the queue.
*/
void shutdown();
-
+
private:
typedef sys::Monitor::ScopedLock ScopedLock;
typedef sys::Monitor::ScopedUnlock ScopedUnlock;
void dispatch(PollableCondition& cond);
void process();
-
+
mutable sys::Monitor lock;
Callback callback;
PollableCondition condition;
@@ -108,7 +107,7 @@ class PollableQueue {
};
template <class T> PollableQueue<T>::PollableQueue(
- const Callback& cb, const boost::shared_ptr<sys::Poller>& p)
+ const Callback& cb, const boost::shared_ptr<sys::Poller>& p)
: callback(cb),
condition(boost::bind(&PollableQueue<T>::dispatch, this, _1), p),
stopped(true)
@@ -152,7 +151,7 @@ template <class T> void PollableQueue<T>::process() {
putBack = callback(batch);
}
// put back unprocessed items.
- queue.insert(queue.begin(), putBack, typename Batch::const_iterator(batch.end()));
+ queue.insert(queue.begin(), putBack, typename Batch::const_iterator(batch.end()));
batch.clear();
}
}
diff --git a/qpid/cpp/src/qpid/sys/Poller.h b/qpid/cpp/src/qpid/sys/Poller.h
index 01ee139ee6..ec53b79bad 100644
--- a/qpid/cpp/src/qpid/sys/Poller.h
+++ b/qpid/cpp/src/qpid/sys/Poller.h
@@ -120,7 +120,7 @@ class PollerHandle {
friend struct Poller::Event;
PollerHandlePrivate* const impl;
- QPID_COMMON_INLINE_EXTERN virtual void processEvent(Poller::EventType) {};
+ QPID_COMMON_EXTERN virtual void processEvent(Poller::EventType) {};
public:
QPID_COMMON_EXTERN PollerHandle(const IOHandle& h);
diff --git a/qpid/cpp/src/qpid/sys/ProtocolFactory.h b/qpid/cpp/src/qpid/sys/ProtocolFactory.h
index 4d198a92da..b233b2da1a 100644
--- a/qpid/cpp/src/qpid/sys/ProtocolFactory.h
+++ b/qpid/cpp/src/qpid/sys/ProtocolFactory.h
@@ -39,10 +39,11 @@ class ProtocolFactory : public qpid::SharedObject<ProtocolFactory>
virtual ~ProtocolFactory() = 0;
virtual uint16_t getPort() const = 0;
+ virtual std::string getHost() const = 0;
virtual void accept(boost::shared_ptr<Poller>, ConnectionCodec::Factory*) = 0;
virtual void connect(
boost::shared_ptr<Poller>,
- const std::string& host, const std::string& port,
+ const std::string& host, int16_t port,
ConnectionCodec::Factory* codec,
ConnectFailedCallback failed) = 0;
virtual bool supports(const std::string& /*capability*/) { return false; }
diff --git a/qpid/cpp/src/qpid/sys/RdmaIOPlugin.cpp b/qpid/cpp/src/qpid/sys/RdmaIOPlugin.cpp
index 6769e5383c..d53db20598 100644
--- a/qpid/cpp/src/qpid/sys/RdmaIOPlugin.cpp
+++ b/qpid/cpp/src/qpid/sys/RdmaIOPlugin.cpp
@@ -31,6 +31,7 @@
#include "qpid/sys/SecuritySettings.h"
#include <boost/bind.hpp>
+#include <boost/lexical_cast.hpp>
#include <memory>
#include <netdb.h>
@@ -211,9 +212,10 @@ void RdmaIOHandler::readbuff(Rdma::AsynchIO&, Rdma::Buffer* buff) {
if (readError) {
return;
}
+ size_t decoded = 0;
try {
if (codec) {
- (void) codec->decode(buff->bytes(), buff->dataCount());
+ decoded = codec->decode(buff->bytes(), buff->dataCount());
}else{
// Need to start protocol processing
initProtocolIn(buff);
@@ -228,7 +230,9 @@ void RdmaIOHandler::readbuff(Rdma::AsynchIO&, Rdma::Buffer* buff) {
void RdmaIOHandler::initProtocolIn(Rdma::Buffer* buff) {
framing::Buffer in(buff->bytes(), buff->dataCount());
framing::ProtocolInitiation protocolInit;
+ size_t decoded = 0;
if (protocolInit.decode(in)) {
+ decoded = in.getPosition();
QPID_LOG(debug, "Rdma: RECV [" << identifier << "] INIT(" << protocolInit << ")");
codec = factory->create(protocolInit.getVersion(), *this, identifier, SecuritySettings());
@@ -250,9 +254,10 @@ class RdmaIOProtocolFactory : public ProtocolFactory {
public:
RdmaIOProtocolFactory(int16_t port, int backlog);
void accept(Poller::shared_ptr, ConnectionCodec::Factory*);
- void connect(Poller::shared_ptr, const string& host, const std::string& port, ConnectionCodec::Factory*, ConnectFailedCallback);
+ void connect(Poller::shared_ptr, const string& host, int16_t port, ConnectionCodec::Factory*, ConnectFailedCallback);
uint16_t getPort() const;
+ string getHost() const;
private:
bool request(Rdma::Connection::intrusive_ptr, const Rdma::ConnectionParams&, ConnectionCodec::Factory*);
@@ -342,7 +347,18 @@ uint16_t RdmaIOProtocolFactory::getPort() const {
return listeningPort; // Immutable no need for lock.
}
+string RdmaIOProtocolFactory::getHost() const {
+ //return listener.getSockname();
+ return "";
+}
+
void RdmaIOProtocolFactory::accept(Poller::shared_ptr poller, ConnectionCodec::Factory* fact) {
+ ::sockaddr_in sin;
+
+ sin.sin_family = AF_INET;
+ sin.sin_port = htons(listeningPort);
+ sin.sin_addr.s_addr = INADDR_ANY;
+
listener.reset(
new Rdma::Listener(
Rdma::ConnectionParams(65536, Rdma::DEFAULT_WR_ENTRIES),
@@ -371,7 +387,7 @@ void RdmaIOProtocolFactory::connected(Poller::shared_ptr poller, Rdma::Connectio
void RdmaIOProtocolFactory::connect(
Poller::shared_ptr poller,
- const std::string& host, const std::string& port,
+ const std::string& host, int16_t port,
ConnectionCodec::Factory* f,
ConnectFailedCallback failed)
{
@@ -383,7 +399,7 @@ void RdmaIOProtocolFactory::connect(
boost::bind(&RdmaIOProtocolFactory::disconnected, this, _1),
boost::bind(&RdmaIOProtocolFactory::rejected, this, _1, _2, failed));
- SocketAddress sa(host, port);
+ SocketAddress sa(host, boost::lexical_cast<std::string>(port));
c->start(poller, sa);
}
diff --git a/qpid/cpp/src/qpid/sys/Socket.h b/qpid/cpp/src/qpid/sys/Socket.h
index 9f62f3be1c..7d50afc59f 100644
--- a/qpid/cpp/src/qpid/sys/Socket.h
+++ b/qpid/cpp/src/qpid/sys/Socket.h
@@ -33,18 +33,21 @@ namespace sys {
class Duration;
class SocketAddress;
-class QPID_COMMON_CLASS_EXTERN Socket : public IOHandle
+class Socket : public IOHandle
{
public:
/** Create a socket wrapper for descriptor. */
QPID_COMMON_EXTERN Socket();
+ /** Set timeout for read and write */
+ void setTimeout(const Duration& interval) const;
+
/** Set socket non blocking */
void setNonblocking() const;
QPID_COMMON_EXTERN void setTcpNoDelay() const;
- QPID_COMMON_EXTERN void connect(const std::string& host, const std::string& port) const;
+ QPID_COMMON_EXTERN void connect(const std::string& host, uint16_t port) const;
QPID_COMMON_EXTERN void connect(const SocketAddress&) const;
QPID_COMMON_EXTERN void close() const;
@@ -54,9 +57,19 @@ public:
*@param backlog maximum number of pending connections.
*@return The bound port.
*/
- QPID_COMMON_EXTERN int listen(const std::string& host = "", const std::string& port = "0", int backlog = 10) const;
+ QPID_COMMON_EXTERN int listen(uint16_t port = 0, int backlog = 10) const;
QPID_COMMON_EXTERN int listen(const SocketAddress&, int backlog = 10) const;
+ /** Returns the "socket name" ie the address bound to
+ * the near end of the socket
+ */
+ QPID_COMMON_EXTERN std::string getSockname() const;
+
+ /** Returns the "peer name" ie the address bound to
+ * the remote end of the socket
+ */
+ std::string getPeername() const;
+
/**
* Returns an address (host and port) for the remote end of the
* socket
@@ -71,7 +84,10 @@ public:
/**
* Returns the full address of the connection: local and remote host and port.
*/
- QPID_COMMON_INLINE_EXTERN std::string getFullAddress() const { return getLocalAddress()+"-"+getPeerAddress(); }
+ QPID_COMMON_EXTERN std::string getFullAddress() const { return getLocalAddress()+"-"+getPeerAddress(); }
+
+ QPID_COMMON_EXTERN uint16_t getLocalPort() const;
+ uint16_t getRemotePort() const;
/**
* Returns the error code stored in the socket. This may be used
@@ -93,8 +109,7 @@ private:
void createSocket(const SocketAddress&) const;
Socket(IOHandlePrivate*);
- mutable std::string localname;
- mutable std::string peername;
+ mutable std::string connectname;
mutable bool nonblocking;
mutable bool nodelay;
};
diff --git a/qpid/cpp/src/qpid/sys/SocketAddress.h b/qpid/cpp/src/qpid/sys/SocketAddress.h
index c2120338cf..27b9642f2c 100644
--- a/qpid/cpp/src/qpid/sys/SocketAddress.h
+++ b/qpid/cpp/src/qpid/sys/SocketAddress.h
@@ -41,7 +41,7 @@ public:
QPID_COMMON_EXTERN SocketAddress& operator=(const SocketAddress&);
QPID_COMMON_EXTERN ~SocketAddress();
- std::string asString(bool numeric=true) const;
+ std::string asString() const;
private:
std::string host;
diff --git a/qpid/cpp/src/qpid/sys/SslPlugin.cpp b/qpid/cpp/src/qpid/sys/SslPlugin.cpp
index 471a0cef60..b0e791d60b 100644
--- a/qpid/cpp/src/qpid/sys/SslPlugin.cpp
+++ b/qpid/cpp/src/qpid/sys/SslPlugin.cpp
@@ -66,11 +66,12 @@ class SslProtocolFactory : public ProtocolFactory {
public:
SslProtocolFactory(const SslServerOptions&, int backlog, bool nodelay);
void accept(Poller::shared_ptr, ConnectionCodec::Factory*);
- void connect(Poller::shared_ptr, const std::string& host, const std::string& port,
+ void connect(Poller::shared_ptr, const std::string& host, int16_t port,
ConnectionCodec::Factory*,
boost::function2<void, int, std::string> failed);
uint16_t getPort() const;
+ std::string getHost() const;
bool supports(const std::string& capability);
private:
@@ -94,7 +95,7 @@ static struct SslPlugin : public Plugin {
// Only provide to a Broker
if (broker) {
if (options.certDbPath.empty()) {
- QPID_LOG(notice, "SSL plugin not enabled, you must set --ssl-cert-db to enable it.");
+ QPID_LOG(info, "SSL plugin not enabled, you must set --ssl-cert-db to enable it.");
} else {
try {
ssl::initNSS(options, true);
@@ -145,6 +146,10 @@ uint16_t SslProtocolFactory::getPort() const {
return listeningPort; // Immutable no need for lock.
}
+std::string SslProtocolFactory::getHost() const {
+ return listener.getSockname();
+}
+
void SslProtocolFactory::accept(Poller::shared_ptr poller,
ConnectionCodec::Factory* fact) {
acceptor.reset(
@@ -155,7 +160,7 @@ void SslProtocolFactory::accept(Poller::shared_ptr poller,
void SslProtocolFactory::connect(
Poller::shared_ptr poller,
- const std::string& host, const std::string& port,
+ const std::string& host, int16_t port,
ConnectionCodec::Factory* fact,
ConnectFailedCallback failed)
{
diff --git a/qpid/cpp/src/qpid/sys/StateMonitor.h b/qpid/cpp/src/qpid/sys/StateMonitor.h
index eac37a8543..5a92756f3a 100644
--- a/qpid/cpp/src/qpid/sys/StateMonitor.h
+++ b/qpid/cpp/src/qpid/sys/StateMonitor.h
@@ -41,9 +41,9 @@ class StateMonitor : public Waitable
struct Set : public std::bitset<MaxEnum + 1> {
Set() {}
Set(Enum s) { set(s); }
- Set(Enum s, Enum t) { std::bitset<MaxEnum + 1>::set(s).set(t); }
- Set(Enum s, Enum t, Enum u) { std::bitset<MaxEnum + 1>::set(s).set(t).set(u); }
- Set(Enum s, Enum t, Enum u, Enum v) { std::bitset<MaxEnum + 1>::set(s).set(t).set(u).set(v); }
+ Set(Enum s, Enum t) { set(s).set(t); }
+ Set(Enum s, Enum t, Enum u) { set(s).set(t).set(u); }
+ Set(Enum s, Enum t, Enum u, Enum v) { set(s).set(t).set(u).set(v); }
};
@@ -60,13 +60,13 @@ class StateMonitor : public Waitable
operator Enum() const { return state; }
/** @pre Caller holds a ScopedLock */
- void waitFor(Enum s) { ScopedWait w(*this); while (s != state) wait(); }
+ void waitFor(Enum s) { ScopedWait(*this); while (s != state) wait(); }
/** @pre Caller holds a ScopedLock */
- void waitFor(Set s) { ScopedWait w(*this); while (!s.test(state)) wait(); }
+ void waitFor(Set s) { ScopedWait(*this); while (!s.test(state)) wait(); }
/** @pre Caller holds a ScopedLock */
- void waitNot(Enum s) { ScopedWait w(*this); while (s == state) wait(); }
+ void waitNot(Enum s) { ScopedWait(*this); while (s == state) wait(); }
/** @pre Caller holds a ScopedLock */
- void waitNot(Set s) { ScopedWait w(*this); while (s.test(state)) wait(); }
+ void waitNot(Set s) { ScopedWait(*this); while (s.test(state)) wait(); }
private:
Enum state;
diff --git a/qpid/cpp/src/qpid/sys/TCPIOPlugin.cpp b/qpid/cpp/src/qpid/sys/TCPIOPlugin.cpp
index 34338ce434..a6528f9ad9 100644
--- a/qpid/cpp/src/qpid/sys/TCPIOPlugin.cpp
+++ b/qpid/cpp/src/qpid/sys/TCPIOPlugin.cpp
@@ -42,13 +42,14 @@ class AsynchIOProtocolFactory : public ProtocolFactory {
std::auto_ptr<AsynchAcceptor> acceptor;
public:
- AsynchIOProtocolFactory(const std::string& host, const std::string& port, int backlog, bool nodelay);
+ AsynchIOProtocolFactory(int16_t port, int backlog, bool nodelay);
void accept(Poller::shared_ptr, ConnectionCodec::Factory*);
- void connect(Poller::shared_ptr, const std::string& host, const std::string& port,
+ void connect(Poller::shared_ptr, const std::string& host, int16_t port,
ConnectionCodec::Factory*,
ConnectFailedCallback);
uint16_t getPort() const;
+ std::string getHost() const;
private:
void established(Poller::shared_ptr, const Socket&, ConnectionCodec::Factory*,
@@ -60,25 +61,22 @@ class AsynchIOProtocolFactory : public ProtocolFactory {
static class TCPIOPlugin : public Plugin {
void earlyInitialize(Target&) {
}
-
+
void initialize(Target& target) {
broker::Broker* broker = dynamic_cast<broker::Broker*>(&target);
// Only provide to a Broker
if (broker) {
const broker::Broker::Options& opts = broker->getOptions();
- ProtocolFactory::shared_ptr protocolt(
- new AsynchIOProtocolFactory(
- "", boost::lexical_cast<std::string>(opts.port),
- opts.connectionBacklog,
- opts.tcpNoDelay));
- QPID_LOG(notice, "Listening on TCP port " << protocolt->getPort());
- broker->registerProtocolFactory("tcp", protocolt);
+ ProtocolFactory::shared_ptr protocol(new AsynchIOProtocolFactory(opts.port, opts.connectionBacklog,
+ opts.tcpNoDelay));
+ QPID_LOG(notice, "Listening on TCP port " << protocol->getPort());
+ broker->registerProtocolFactory("tcp", protocol);
}
}
} tcpPlugin;
-AsynchIOProtocolFactory::AsynchIOProtocolFactory(const std::string& host, const std::string& port, int backlog, bool nodelay) :
- tcpNoDelay(nodelay), listeningPort(listener.listen(host, port, backlog))
+AsynchIOProtocolFactory::AsynchIOProtocolFactory(int16_t port, int backlog, bool nodelay) :
+ tcpNoDelay(nodelay), listeningPort(listener.listen(port, backlog))
{}
void AsynchIOProtocolFactory::established(Poller::shared_ptr poller, const Socket& s,
@@ -109,6 +107,10 @@ uint16_t AsynchIOProtocolFactory::getPort() const {
return listeningPort; // Immutable no need for lock.
}
+std::string AsynchIOProtocolFactory::getHost() const {
+ return listener.getSockname();
+}
+
void AsynchIOProtocolFactory::accept(Poller::shared_ptr poller,
ConnectionCodec::Factory* fact) {
acceptor.reset(
@@ -128,7 +130,7 @@ void AsynchIOProtocolFactory::connectFailed(
void AsynchIOProtocolFactory::connect(
Poller::shared_ptr poller,
- const std::string& host, const std::string& port,
+ const std::string& host, int16_t port,
ConnectionCodec::Factory* fact,
ConnectFailedCallback failed)
{
@@ -137,6 +139,7 @@ void AsynchIOProtocolFactory::connect(
// upon connection failure or by the AsynchIO upon connection
// shutdown. The allocated AsynchConnector frees itself when it
// is no longer needed.
+
Socket* socket = new Socket();
AsynchConnector* c = AsynchConnector::create(
*socket,
diff --git a/qpid/cpp/src/qpid/sys/Timer.cpp b/qpid/cpp/src/qpid/sys/Timer.cpp
index 47752e4584..a97ccd1bd1 100644
--- a/qpid/cpp/src/qpid/sys/Timer.cpp
+++ b/qpid/cpp/src/qpid/sys/Timer.cpp
@@ -75,12 +75,6 @@ void TimerTask::cancel() {
cancelled = true;
}
-void TimerTask::setFired() {
- // Set nextFireTime to just before now, making readyToFire() true.
- nextFireTime = AbsTime(sys::now(), Duration(-1));
-}
-
-
Timer::Timer() :
active(false),
late(50 * TIME_MSEC),
@@ -137,14 +131,12 @@ void Timer::run()
bool warningsEnabled;
QPID_LOG_TEST(warning, warningsEnabled);
if (warningsEnabled) {
- if (overrun > overran) {
- if (delay > overran) // if delay is significant to an overrun.
- warn.lateAndOverran(t->name, delay, overrun, Duration(start, end));
- else
- warn.overran(t->name, overrun, Duration(start, end));
- }
+ if (delay > late && overrun > overran)
+ warn.lateAndOverran(t->name, delay, overrun, Duration(start, end));
else if (delay > late)
warn.late(t->name, delay);
+ else if (overrun > overran)
+ warn.overran(t->name, overrun, Duration(start, end));
}
continue;
} else {
@@ -191,11 +183,7 @@ void Timer::stop()
// Allow subclasses to override behavior when firing a task.
void Timer::fire(boost::intrusive_ptr<TimerTask> t) {
- try {
- t->fireTask();
- } catch (const std::exception& e) {
- QPID_LOG(error, "Exception thrown by timer task " << t->getName() << ": " << e.what());
- }
+ t->fireTask();
}
// Provided for subclasses: called when a task is droped.
diff --git a/qpid/cpp/src/qpid/sys/Timer.h b/qpid/cpp/src/qpid/sys/Timer.h
index fccb17dbc2..98ba39ce38 100644
--- a/qpid/cpp/src/qpid/sys/Timer.h
+++ b/qpid/cpp/src/qpid/sys/Timer.h
@@ -7,9 +7,9 @@
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
@@ -64,10 +64,6 @@ class TimerTask : public RefCounted {
std::string getName() const { return name; }
- // Move the nextFireTime so readyToFire is true.
- // Used by the cluster, where tasks are fired on cluster events, not on local time.
- QPID_COMMON_EXTERN void setFired();
-
protected:
// Must be overridden with callback
virtual void fire() = 0;
diff --git a/qpid/cpp/src/qpid/sys/TimerWarnings.cpp b/qpid/cpp/src/qpid/sys/TimerWarnings.cpp
index 87c3169456..48a56eb472 100644
--- a/qpid/cpp/src/qpid/sys/TimerWarnings.cpp
+++ b/qpid/cpp/src/qpid/sys/TimerWarnings.cpp
@@ -59,19 +59,17 @@ void TimerWarnings::log() {
QPID_LOG(warning, task << " task late "
<< stats.lateDelay.count << " times by "
<< stats.lateDelay.average()/TIME_MSEC << "ms on average.");
-
if (stats.overranOverrun.count)
QPID_LOG(warning, task << " task overran "
<< stats.overranOverrun.count << " times by "
<< stats.overranOverrun.average()/TIME_MSEC << "ms (taking "
<< stats.overranTime.average() << "ns) on average.");
- if (stats.lateAndOverranOverrun.count)
- QPID_LOG(warning, task << " task late and overran "
- << stats.lateAndOverranOverrun.count << " times: late "
- << stats.lateAndOverranDelay.average()/TIME_MSEC << "ms, overran "
- << stats.lateAndOverranOverrun.average()/TIME_MSEC << "ms (taking "
- << stats.lateAndOverranTime.average() << "ns) on average.");
+ if (stats.lateAndOverranDelay.count)
+ QPID_LOG(warning, task << " task overran "
+ << stats.overranOverrun.count << " times by "
+ << stats.overranOverrun.average()/TIME_MSEC << "ms (taking "
+ << stats.overranTime.average() << "ns) on average.");
}
nextReport = AbsTime(now(), interval);
diff --git a/qpid/cpp/src/qpid/sys/alloca.h b/qpid/cpp/src/qpid/sys/alloca.h
index 0f58920908..e989670e4f 100644
--- a/qpid/cpp/src/qpid/sys/alloca.h
+++ b/qpid/cpp/src/qpid/sys/alloca.h
@@ -21,22 +21,19 @@
*
*/
-#if (defined(_WINDOWS) || defined (WIN32))
-# include <malloc.h>
-
-# if defined(_MSC_VER)
-# 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
+#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/cyrus/CyrusSecurityLayer.cpp b/qpid/cpp/src/qpid/sys/cyrus/CyrusSecurityLayer.cpp
index 3d868da64b..454ce62495 100644
--- a/qpid/cpp/src/qpid/sys/cyrus/CyrusSecurityLayer.cpp
+++ b/qpid/cpp/src/qpid/sys/cyrus/CyrusSecurityLayer.cpp
@@ -106,7 +106,7 @@ size_t CyrusSecurityLayer::encode(const char* buffer, size_t size)
bool CyrusSecurityLayer::canEncode()
{
- return codec && (encrypted || codec->canEncode());
+ return encrypted || codec->canEncode();
}
void CyrusSecurityLayer::init(qpid::sys::Codec* c)
diff --git a/qpid/cpp/src/qpid/sys/posix/AsynchIO.cpp b/qpid/cpp/src/qpid/sys/posix/AsynchIO.cpp
index b5a0b0bf32..119a6aa8a4 100644
--- a/qpid/cpp/src/qpid/sys/posix/AsynchIO.cpp
+++ b/qpid/cpp/src/qpid/sys/posix/AsynchIO.cpp
@@ -152,8 +152,8 @@ private:
public:
AsynchConnector(const Socket& socket,
- const std::string& hostname,
- const std::string& port,
+ std::string hostname,
+ uint16_t port,
ConnectedCallback connCb,
FailedCallback failCb);
void start(Poller::shared_ptr poller);
@@ -161,8 +161,8 @@ public:
};
AsynchConnector::AsynchConnector(const Socket& s,
- const std::string& hostname,
- const std::string& port,
+ std::string hostname,
+ uint16_t port,
ConnectedCallback connCb,
FailedCallback failCb) :
DispatchHandle(s,
@@ -174,7 +174,7 @@ AsynchConnector::AsynchConnector(const Socket& s,
socket(s)
{
socket.setNonblocking();
- SocketAddress sa(hostname, port);
+ SocketAddress sa(hostname, boost::lexical_cast<std::string>(port));
// Note, not catching any exceptions here, also has effect of destructing
socket.connect(sa);
}
@@ -589,8 +589,8 @@ AsynchAcceptor* AsynchAcceptor::create(const Socket& s,
}
AsynchConnector* AsynchConnector::create(const Socket& s,
- const std::string& hostname,
- const std::string& port,
+ std::string hostname,
+ uint16_t port,
ConnectedCallback connCb,
FailedCallback failCb)
{
diff --git a/qpid/cpp/src/qpid/sys/posix/LockFile.cpp b/qpid/cpp/src/qpid/sys/posix/LockFile.cpp
index f5a6c292cb..1862ff6ac9 100755
--- a/qpid/cpp/src/qpid/sys/posix/LockFile.cpp
+++ b/qpid/cpp/src/qpid/sys/posix/LockFile.cpp
@@ -58,7 +58,8 @@ LockFile::~LockFile() {
if (impl) {
int f = impl->fd;
if (f >= 0) {
- (void) ::lockf(f, F_ULOCK, 0); // Suppress warnings about ignoring return value.
+ int unused_ret;
+ unused_ret = ::lockf(f, F_ULOCK, 0); // Suppress warnings about ignoring return value.
::close(f);
impl->fd = -1;
}
diff --git a/qpid/cpp/src/qpid/sys/posix/Socket.cpp b/qpid/cpp/src/qpid/sys/posix/Socket.cpp
index aa25f8062d..7b906f33e8 100644
--- a/qpid/cpp/src/qpid/sys/posix/Socket.cpp
+++ b/qpid/cpp/src/qpid/sys/posix/Socket.cpp
@@ -7,9 +7,9 @@
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
@@ -37,31 +37,62 @@
#include <iostream>
#include <boost/format.hpp>
+#include <boost/lexical_cast.hpp>
namespace qpid {
namespace sys {
namespace {
-std::string getName(int fd, bool local)
+std::string getName(int fd, bool local, bool includeService = false)
{
- ::sockaddr_storage name; // big enough for any socket address
+ ::sockaddr_storage name; // big enough for any socket address
::socklen_t namelen = sizeof(name);
-
+
int result = -1;
if (local) {
result = ::getsockname(fd, (::sockaddr*)&name, &namelen);
} else {
result = ::getpeername(fd, (::sockaddr*)&name, &namelen);
}
+
QPID_POSIX_CHECK(result);
char servName[NI_MAXSERV];
char dispName[NI_MAXHOST];
- if (int rc=::getnameinfo((::sockaddr*)&name, namelen, dispName, sizeof(dispName),
- servName, sizeof(servName),
- NI_NUMERICHOST | NI_NUMERICSERV) != 0)
+ if (includeService) {
+ if (int rc=::getnameinfo((::sockaddr*)&name, namelen, dispName, sizeof(dispName),
+ servName, sizeof(servName),
+ NI_NUMERICHOST | NI_NUMERICSERV) != 0)
+ throw QPID_POSIX_ERROR(rc);
+ return std::string(dispName) + ":" + std::string(servName);
+
+ } else {
+ if (int rc=::getnameinfo((::sockaddr*)&name, namelen, dispName, sizeof(dispName), 0, 0, NI_NUMERICHOST) != 0)
+ throw QPID_POSIX_ERROR(rc);
+ return dispName;
+ }
+}
+
+std::string getService(int fd, bool local)
+{
+ ::sockaddr_storage name; // big enough for any socket address
+ ::socklen_t namelen = sizeof(name);
+
+ int result = -1;
+ if (local) {
+ result = ::getsockname(fd, (::sockaddr*)&name, &namelen);
+ } else {
+ result = ::getpeername(fd, (::sockaddr*)&name, &namelen);
+ }
+
+ QPID_POSIX_CHECK(result);
+
+ char servName[NI_MAXSERV];
+ if (int rc=::getnameinfo((::sockaddr*)&name, namelen, 0, 0,
+ servName, sizeof(servName),
+ NI_NUMERICHOST | NI_NUMERICSERV) != 0)
throw QPID_POSIX_ERROR(rc);
- return std::string(dispName) + ":" + std::string(servName);
+ return servName;
}
}
@@ -95,6 +126,15 @@ void Socket::createSocket(const SocketAddress& sa) const
}
}
+void Socket::setTimeout(const Duration& interval) const
+{
+ const int& socket = impl->fd;
+ struct timeval tv;
+ toTimeval(tv, interval);
+ setsockopt(socket, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv));
+ setsockopt(socket, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
+}
+
void Socket::setNonblocking() const {
int& socket = impl->fd;
nonblocking = true;
@@ -114,22 +154,15 @@ void Socket::setTcpNoDelay() const
}
}
-void Socket::connect(const std::string& host, const std::string& port) const
+void Socket::connect(const std::string& host, uint16_t port) const
{
- SocketAddress sa(host, port);
+ SocketAddress sa(host, boost::lexical_cast<std::string>(port));
connect(sa);
}
void Socket::connect(const SocketAddress& addr) const
{
- // The display name for an outbound connection needs to be the name that was specified
- // for the address rather than a resolved IP address as we don't know which of
- // the IP addresses is actually the one that will be connected to.
- peername = addr.asString(false);
-
- // However the string we compare with the local port must be numeric or it might not
- // match when it should as getLocalAddress() will always be numeric
- std::string connectname = addr.asString();
+ connectname = addr.asString();
createSocket(addr);
@@ -137,24 +170,7 @@ void Socket::connect(const SocketAddress& addr) const
// TODO the correct thing to do here is loop on failure until you've used all the returned addresses
if ((::connect(socket, getAddrInfo(addr).ai_addr, getAddrInfo(addr).ai_addrlen) < 0) &&
(errno != EINPROGRESS)) {
- throw Exception(QPID_MSG(strError(errno) << ": " << peername));
- }
- // When connecting to a port on the same host which no longer has
- // a process associated with it, the OS occasionally chooses the
- // remote port (which is unoccupied) as the port to bind the local
- // end of the socket, resulting in a "circular" connection.
- //
- // This seems like something the OS should prevent but I have
- // confirmed that sporadic hangs in
- // cluster_tests.LongTests.test_failover on RHEL5 are caused by
- // such a circular connection.
- //
- // Raise an error if we see such a connection, since we know there is
- // no listener on the peer address.
- //
- if (getLocalAddress() == connectname) {
- close();
- throw Exception(QPID_MSG("Connection refused: " << peername));
+ throw Exception(QPID_MSG(strError(errno) << ": " << connectname));
}
}
@@ -167,9 +183,9 @@ Socket::close() const
socket = -1;
}
-int Socket::listen(const std::string& host, const std::string& port, int backlog) const
+int Socket::listen(uint16_t port, int backlog) const
{
- SocketAddress sa(host, port);
+ SocketAddress sa("", boost::lexical_cast<std::string>(port));
return listen(sa, backlog);
}
@@ -197,11 +213,8 @@ int Socket::listen(const SocketAddress& sa, int backlog) const
Socket* Socket::accept() const
{
int afd = ::accept(impl->fd, 0, 0);
- if ( afd >= 0) {
- Socket* s = new Socket(new IOHandlePrivate(afd));
- s->localname = localname;
- return s;
- }
+ if ( afd >= 0)
+ return new Socket(new IOHandlePrivate(afd));
else if (errno == EAGAIN)
return 0;
else throw QPID_POSIX_ERROR(errno);
@@ -217,20 +230,37 @@ int Socket::write(const void *buf, size_t count) const
return ::write(impl->fd, buf, count);
}
+std::string Socket::getSockname() const
+{
+ return getName(impl->fd, true);
+}
+
+std::string Socket::getPeername() const
+{
+ return getName(impl->fd, false);
+}
+
std::string Socket::getPeerAddress() const
{
- if (peername.empty()) {
- peername = getName(impl->fd, false);
+ if (connectname.empty()) {
+ connectname = getName(impl->fd, false, true);
}
- return peername;
+ return connectname;
}
std::string Socket::getLocalAddress() const
{
- if (localname.empty()) {
- localname = getName(impl->fd, true);
- }
- return localname;
+ return getName(impl->fd, true, true);
+}
+
+uint16_t Socket::getLocalPort() const
+{
+ return std::atoi(getService(impl->fd, true).c_str());
+}
+
+uint16_t Socket::getRemotePort() const
+{
+ return std::atoi(getService(impl->fd, true).c_str());
}
int Socket::getError() const
diff --git a/qpid/cpp/src/qpid/sys/posix/SocketAddress.cpp b/qpid/cpp/src/qpid/sys/posix/SocketAddress.cpp
index 10f1c8a563..8f5f29d793 100644
--- a/qpid/cpp/src/qpid/sys/posix/SocketAddress.cpp
+++ b/qpid/cpp/src/qpid/sys/posix/SocketAddress.cpp
@@ -27,8 +27,6 @@
#include <string.h>
#include <netdb.h>
-#include <algorithm>
-
namespace qpid {
namespace sys {
@@ -48,9 +46,15 @@ SocketAddress::SocketAddress(const SocketAddress& sa) :
SocketAddress& SocketAddress::operator=(const SocketAddress& sa)
{
- SocketAddress temp(sa);
+ if (&sa != this) {
+ host = sa.host;
+ port = sa.port;
- std::swap(temp, *this);
+ if (addrInfo) {
+ ::freeaddrinfo(addrInfo);
+ addrInfo = 0;
+ }
+ }
return *this;
}
@@ -61,23 +65,9 @@ SocketAddress::~SocketAddress()
}
}
-std::string SocketAddress::asString(bool numeric) const
+std::string SocketAddress::asString() const
{
- if (!numeric)
- return host + ":" + port;
- // Canonicalise into numeric id
- const ::addrinfo& ai = getAddrInfo(*this);
- char servName[NI_MAXSERV];
- char dispName[NI_MAXHOST];
- if (int rc=::getnameinfo(ai.ai_addr, ai.ai_addrlen,
- dispName, sizeof(dispName),
- servName, sizeof(servName),
- NI_NUMERICHOST | NI_NUMERICSERV) != 0)
- throw QPID_POSIX_ERROR(rc);
- std::string s(dispName);
- s += ":";
- s += servName;
- return s;
+ return host + ":" + port;
}
const ::addrinfo& getAddrInfo(const SocketAddress& sa)
@@ -98,7 +88,7 @@ const ::addrinfo& getAddrInfo(const SocketAddress& sa)
int n = ::getaddrinfo(node, service, &hints, &sa.addrInfo);
if (n != 0)
- throw Exception(QPID_MSG("Cannot resolve " << sa.asString(false) << ": " << ::gai_strerror(n)));
+ throw Exception(QPID_MSG("Cannot resolve " << sa.host << ": " << ::gai_strerror(n)));
}
return *sa.addrInfo;
diff --git a/qpid/cpp/src/qpid/sys/posix/Thread.cpp b/qpid/cpp/src/qpid/sys/posix/Thread.cpp
index a1d6396763..b466733260 100644
--- a/qpid/cpp/src/qpid/sys/posix/Thread.cpp
+++ b/qpid/cpp/src/qpid/sys/posix/Thread.cpp
@@ -37,8 +37,7 @@ void* runRunnable(void* p)
}
}
-class ThreadPrivate {
-public:
+struct ThreadPrivate {
pthread_t thread;
ThreadPrivate(Runnable* runnable) {
diff --git a/qpid/cpp/src/qpid/sys/posix/Time.cpp b/qpid/cpp/src/qpid/sys/posix/Time.cpp
index 9661f0c5e8..b3858279b4 100644
--- a/qpid/cpp/src/qpid/sys/posix/Time.cpp
+++ b/qpid/cpp/src/qpid/sys/posix/Time.cpp
@@ -27,7 +27,6 @@
#include <stdio.h>
#include <sys/time.h>
#include <unistd.h>
-#include <iomanip>
namespace {
int64_t max_abstime() { return std::numeric_limits<int64_t>::max(); }
@@ -104,12 +103,6 @@ void outputFormattedNow(std::ostream& o) {
o << " ";
}
-void outputHiresNow(std::ostream& o) {
- ::timespec time;
- ::clock_gettime(CLOCK_REALTIME, &time);
- o << time.tv_sec << "." << std::setw(9) << std::setfill('0') << time.tv_nsec << "s ";
-}
-
void sleep(int secs) {
::sleep(secs);
}
diff --git a/qpid/cpp/src/qpid/sys/rdma/RdmaIO.cpp b/qpid/cpp/src/qpid/sys/rdma/RdmaIO.cpp
index 78bcdec68e..c80c94cba6 100644
--- a/qpid/cpp/src/qpid/sys/rdma/RdmaIO.cpp
+++ b/qpid/cpp/src/qpid/sys/rdma/RdmaIO.cpp
@@ -140,8 +140,8 @@ namespace Rdma {
// Prepost recv buffers before we go any further
qp->allocateRecvBuffers(recvBufferCount, bufferSize+FrameHeaderSize);
- // Create xmit buffers, reserve space for frame header.
- qp->createSendBuffers(xmitBufferCount, bufferSize, FrameHeaderSize);
+ // Create xmit buffers
+ qp->createSendBuffers(xmitBufferCount, bufferSize+FrameHeaderSize);
}
AsynchIO::~AsynchIO() {
@@ -210,14 +210,12 @@ namespace Rdma {
}
break;
case 1:
- if (!buff)
- buff = getSendBuffer();
+ Buffer* ob = buff ? buff : getSendBuffer();
// Add FrameHeader after frame data
FrameHeader header(credit);
- assert(buff->dataCount() <= buff->byteCount()); // ensure app data doesn't impinge on reserved space.
- ::memcpy(buff->bytes()+buff->dataCount(), &header, FrameHeaderSize);
- buff->dataCount(buff->dataCount()+FrameHeaderSize);
- qp->postSend(buff);
+ ::memcpy(ob->bytes()+ob->dataCount(), &header, FrameHeaderSize);
+ ob->dataCount(ob->dataCount()+FrameHeaderSize);
+ qp->postSend(ob);
break;
}
}
diff --git a/qpid/cpp/src/qpid/sys/rdma/rdma_wrap.cpp b/qpid/cpp/src/qpid/sys/rdma/rdma_wrap.cpp
index efe454c5be..6d38c42502 100644
--- a/qpid/cpp/src/qpid/sys/rdma/rdma_wrap.cpp
+++ b/qpid/cpp/src/qpid/sys/rdma/rdma_wrap.cpp
@@ -50,9 +50,8 @@ namespace Rdma {
return count;
}
- Buffer::Buffer(uint32_t lkey, char* bytes, const int32_t byteCount,
- const int32_t reserve) :
- bufferSize(byteCount + reserve), reserved(reserve)
+ Buffer::Buffer(uint32_t lkey, char* bytes, const int32_t byteCount) :
+ bufferSize(byteCount)
{
sge.addr = (uintptr_t) bytes;
sge.length = 0;
@@ -164,21 +163,21 @@ namespace Rdma {
}
// Create buffers to use for writing
- void QueuePair::createSendBuffers(int sendBufferCount, int bufferSize, int reserved)
+ void QueuePair::createSendBuffers(int sendBufferCount, int bufferSize)
{
assert(!smr);
// Round up buffersize to cacheline (64 bytes)
- int dataLength = (bufferSize+reserved+63) & (~63);
+ bufferSize = (bufferSize+63) & (~63);
// Allocate memory block for all receive buffers
- char* mem = new char [sendBufferCount * dataLength];
- smr = regMr(pd.get(), mem, sendBufferCount * dataLength, ::IBV_ACCESS_LOCAL_WRITE);
+ char* mem = new char [sendBufferCount * bufferSize];
+ smr = regMr(pd.get(), mem, sendBufferCount * bufferSize, ::IBV_ACCESS_LOCAL_WRITE);
sendBuffers.reserve(sendBufferCount);
freeBuffers.reserve(sendBufferCount);
for (int i = 0; i<sendBufferCount; ++i) {
// Allocate xmit buffer
- sendBuffers.push_back(Buffer(smr->lkey, &mem[i*dataLength], bufferSize, reserved));
+ sendBuffers.push_back(Buffer(smr->lkey, &mem[i*bufferSize], bufferSize));
freeBuffers.push_back(i);
}
}
diff --git a/qpid/cpp/src/qpid/sys/rdma/rdma_wrap.h b/qpid/cpp/src/qpid/sys/rdma/rdma_wrap.h
index 8e3429027b..28bddd2165 100644
--- a/qpid/cpp/src/qpid/sys/rdma/rdma_wrap.h
+++ b/qpid/cpp/src/qpid/sys/rdma/rdma_wrap.h
@@ -57,9 +57,8 @@ namespace Rdma {
void dataCount(int32_t);
private:
- Buffer(uint32_t lkey, char* bytes, const int32_t byteCount, const int32_t reserve=0);
+ Buffer(uint32_t lkey, char* bytes, const int32_t byteCount);
int32_t bufferSize;
- int32_t reserved; // for framing header
::ibv_sge sge;
};
@@ -67,9 +66,8 @@ namespace Rdma {
return (char*) sge.addr;
}
- /** return the number of bytes available for application data */
inline int32_t Buffer::byteCount() const {
- return bufferSize - reserved;
+ return bufferSize;
}
inline int32_t Buffer::dataCount() const {
@@ -77,8 +75,6 @@ namespace Rdma {
}
inline void Buffer::dataCount(int32_t s) {
- // catch any attempt to overflow a buffer
- assert(s <= bufferSize + reserved);
sge.length = s;
}
@@ -140,7 +136,7 @@ namespace Rdma {
typedef boost::intrusive_ptr<QueuePair> intrusive_ptr;
// Create a buffers to use for writing
- void createSendBuffers(int sendBufferCount, int dataSize, int headerSize);
+ void createSendBuffers(int sendBufferCount, int bufferSize);
// Get a send buffer
Buffer* getSendBuffer();
diff --git a/qpid/cpp/src/qpid/sys/ssl/SslHandler.h b/qpid/cpp/src/qpid/sys/ssl/SslHandler.h
index 400fa317fd..a340109966 100644
--- a/qpid/cpp/src/qpid/sys/ssl/SslHandler.h
+++ b/qpid/cpp/src/qpid/sys/ssl/SslHandler.h
@@ -35,7 +35,7 @@ namespace sys {
namespace ssl {
class SslIO;
-struct SslIOBufferBase;
+class SslIOBufferBase;
class SslSocket;
class SslHandler : public OutputControl {
diff --git a/qpid/cpp/src/qpid/sys/ssl/SslIo.cpp b/qpid/cpp/src/qpid/sys/ssl/SslIo.cpp
index 734ebb483a..a58a137473 100644
--- a/qpid/cpp/src/qpid/sys/ssl/SslIo.cpp
+++ b/qpid/cpp/src/qpid/sys/ssl/SslIo.cpp
@@ -117,7 +117,7 @@ void SslAcceptor::readable(DispatchHandle& h) {
SslConnector::SslConnector(const SslSocket& s,
Poller::shared_ptr poller,
std::string hostname,
- std::string port,
+ uint16_t port,
ConnectedCallback connCb,
FailedCallback failCb) :
DispatchHandle(s,
diff --git a/qpid/cpp/src/qpid/sys/ssl/SslIo.h b/qpid/cpp/src/qpid/sys/ssl/SslIo.h
index 8785852c24..53ac69d8d6 100644
--- a/qpid/cpp/src/qpid/sys/ssl/SslIo.h
+++ b/qpid/cpp/src/qpid/sys/ssl/SslIo.h
@@ -73,7 +73,7 @@ public:
SslConnector(const SslSocket& socket,
Poller::shared_ptr poller,
std::string hostname,
- std::string port,
+ uint16_t port,
ConnectedCallback connCb,
FailedCallback failCb = 0);
diff --git a/qpid/cpp/src/qpid/sys/ssl/SslSocket.cpp b/qpid/cpp/src/qpid/sys/ssl/SslSocket.cpp
index f7483a220c..01e2658877 100644
--- a/qpid/cpp/src/qpid/sys/ssl/SslSocket.cpp
+++ b/qpid/cpp/src/qpid/sys/ssl/SslSocket.cpp
@@ -158,7 +158,7 @@ void SslSocket::setNonblocking() const
PR_SetSocketOption(socket, &option);
}
-void SslSocket::connect(const std::string& host, const std::string& port) const
+void SslSocket::connect(const std::string& host, uint16_t port) const
{
std::stringstream namestream;
namestream << host << ":" << port;
@@ -180,7 +180,7 @@ void SslSocket::connect(const std::string& host, const std::string& port) const
PRHostEnt hostEntry;
PR_CHECK(PR_GetHostByName(host.data(), hostBuffer, PR_NETDB_BUF_SIZE, &hostEntry));
PRNetAddr address;
- int value = PR_EnumerateHostEnt(0, &hostEntry, boost::lexical_cast<PRUint16>(port), &address);
+ int value = PR_EnumerateHostEnt(0, &hostEntry, port, &address);
if (value < 0) {
throw Exception(QPID_MSG("Error getting address for host: " << ErrorString()));
} else if (value == 0) {
diff --git a/qpid/cpp/src/qpid/sys/ssl/SslSocket.h b/qpid/cpp/src/qpid/sys/ssl/SslSocket.h
index 993859495b..25712c98d5 100644
--- a/qpid/cpp/src/qpid/sys/ssl/SslSocket.h
+++ b/qpid/cpp/src/qpid/sys/ssl/SslSocket.h
@@ -53,7 +53,7 @@ public:
* NSSInit().*/
void setCertName(const std::string& certName);
- void connect(const std::string& host, const std::string& port) const;
+ void connect(const std::string& host, uint16_t port) const;
void close() const;
diff --git a/qpid/cpp/src/qpid/sys/windows/AsynchIO.cpp b/qpid/cpp/src/qpid/sys/windows/AsynchIO.cpp
index 8d84fdb7b2..38d8842521 100644
--- a/qpid/cpp/src/qpid/sys/windows/AsynchIO.cpp
+++ b/qpid/cpp/src/qpid/sys/windows/AsynchIO.cpp
@@ -30,7 +30,6 @@
#include "qpid/log/Statement.h"
#include "qpid/sys/windows/check.h"
-#include "qpid/sys/windows/mingw32_compat.h"
#include <boost/thread/once.hpp>
@@ -115,8 +114,7 @@ AsynchAcceptor::~AsynchAcceptor()
}
void AsynchAcceptor::start(Poller::shared_ptr poller) {
- PollerHandle ph = PollerHandle(socket);
- poller->monitorHandle(ph, Poller::INPUT);
+ poller->monitorHandle(PollerHandle(socket), Poller::INPUT);
restart ();
}
@@ -156,7 +154,7 @@ void AsynchAcceptResult::success(size_t /*bytesTransferred*/) {
delete this;
}
-void AsynchAcceptResult::failure(int /*status*/) {
+void AsynchAcceptResult::failure(int status) {
//if (status != WSA_OPERATION_ABORTED)
// Can there be anything else? ;
delete this;
@@ -175,20 +173,20 @@ private:
FailedCallback failCallback;
const Socket& socket;
const std::string hostname;
- const std::string port;
+ const uint16_t port;
public:
AsynchConnector(const Socket& socket,
- const std::string& hostname,
- const std::string& port,
+ std::string hostname,
+ uint16_t port,
ConnectedCallback connCb,
FailedCallback failCb = 0);
void start(Poller::shared_ptr poller);
};
AsynchConnector::AsynchConnector(const Socket& sock,
- const std::string& hname,
- const std::string& p,
+ std::string hname,
+ uint16_t p,
ConnectedCallback connCb,
FailedCallback failCb) :
connCallback(connCb), failCallback(failCb), socket(sock),
@@ -218,8 +216,8 @@ AsynchAcceptor* AsynchAcceptor::create(const Socket& s,
}
AsynchConnector* qpid::sys::AsynchConnector::create(const Socket& s,
- const std::string& hostname,
- const std::string& port,
+ std::string hostname,
+ uint16_t port,
ConnectedCallback connCb,
FailedCallback failCb)
{
@@ -412,9 +410,8 @@ void AsynchIO::queueForDeletion() {
}
void AsynchIO::start(Poller::shared_ptr poller0) {
- PollerHandle ph = PollerHandle(socket);
poller = poller0;
- poller->monitorHandle(ph, Poller::INPUT);
+ poller->monitorHandle(PollerHandle(socket), Poller::INPUT);
if (writeQueue.size() > 0) // Already have data queued for write
notifyPendingWrite();
startReading();
@@ -587,6 +584,7 @@ void AsynchIO::notifyIdle(void) {
void AsynchIO::startWrite(AsynchIO::BufferBase* buff) {
writeInProgress = true;
InterlockedIncrement(&opsInProgress);
+ int writeCount = buff->byteCount-buff->dataCount;
AsynchWriteResult *result =
new AsynchWriteResult(boost::bind(&AsynchIO::completion, this, _1),
buff,
diff --git a/qpid/cpp/src/qpid/sys/windows/AsynchIoResult.h b/qpid/cpp/src/qpid/sys/windows/AsynchIoResult.h
index b11324918b..66c89efc11 100755
--- a/qpid/cpp/src/qpid/sys/windows/AsynchIoResult.h
+++ b/qpid/cpp/src/qpid/sys/windows/AsynchIoResult.h
@@ -98,7 +98,7 @@ private:
// AcceptEx needs a place to write the local and remote addresses
// when accepting the connection. Place those here; get enough for
// IPv6 addresses, even if the socket is IPv4.
- enum { SOCKADDRMAXLEN = sizeof(sockaddr_in6) + 16,
+ enum { SOCKADDRMAXLEN = sizeof sockaddr_in6 + 16,
SOCKADDRBUFLEN = 2 * SOCKADDRMAXLEN };
char addressBuffer[SOCKADDRBUFLEN];
};
diff --git a/qpid/cpp/src/qpid/sys/windows/IocpPoller.cpp b/qpid/cpp/src/qpid/sys/windows/IocpPoller.cpp
index 1805dd2cd8..d326ab02ac 100755
--- a/qpid/cpp/src/qpid/sys/windows/IocpPoller.cpp
+++ b/qpid/cpp/src/qpid/sys/windows/IocpPoller.cpp
@@ -152,9 +152,9 @@ void Poller::monitorHandle(PollerHandle& handle, Direction dir) {
}
// All no-ops...
-void Poller::unmonitorHandle(PollerHandle& /*handle*/, Direction /*dir*/) {}
-void Poller::registerHandle(PollerHandle& /*handle*/) {}
-void Poller::unregisterHandle(PollerHandle& /*handle*/) {}
+void Poller::unmonitorHandle(PollerHandle& handle, Direction dir) {}
+void Poller::registerHandle(PollerHandle& handle) {}
+void Poller::unregisterHandle(PollerHandle& handle) {}
Poller::Event Poller::wait(Duration timeout) {
DWORD timeoutMs = 0;
diff --git a/qpid/cpp/src/qpid/sys/windows/Shlib.cpp b/qpid/cpp/src/qpid/sys/windows/Shlib.cpp
index ba18747eb4..38027de93f 100644
--- a/qpid/cpp/src/qpid/sys/windows/Shlib.cpp
+++ b/qpid/cpp/src/qpid/sys/windows/Shlib.cpp
@@ -44,8 +44,7 @@ void Shlib::unload() {
}
void* Shlib::getSymbol(const char* name) {
- // Double cast avoids warning about casting function pointer to object
- void *sym = reinterpret_cast<void*>(reinterpret_cast<intptr_t>(GetProcAddress(static_cast<HMODULE>(handle), name)));
+ void* sym = GetProcAddress(static_cast<HMODULE>(handle), name);
if (sym == NULL)
throw QPID_WINDOWS_ERROR(GetLastError());
return sym;
diff --git a/qpid/cpp/src/qpid/sys/windows/Socket.cpp b/qpid/cpp/src/qpid/sys/windows/Socket.cpp
index baa80f04e0..11fb8b4133 100755
--- a/qpid/cpp/src/qpid/sys/windows/Socket.cpp
+++ b/qpid/cpp/src/qpid/sys/windows/Socket.cpp
@@ -19,11 +19,6 @@
*
*/
-// Ensure we get all of winsock2.h
-#ifndef _WIN32_WINNT
-#define _WIN32_WINNT 0x0501
-#endif
-
#include "qpid/sys/Socket.h"
#include "qpid/sys/SocketAddress.h"
#include "qpid/sys/windows/IoHandlePrivate.h"
@@ -89,7 +84,7 @@ namespace sys {
namespace {
-std::string getName(SOCKET fd, bool local)
+std::string getName(SOCKET fd, bool local, bool includeService = false)
{
sockaddr_in name; // big enough for any socket address
socklen_t namelen = sizeof(name);
@@ -101,12 +96,41 @@ std::string getName(SOCKET fd, bool local)
char servName[NI_MAXSERV];
char dispName[NI_MAXHOST];
+ if (includeService) {
+ if (int rc = ::getnameinfo((sockaddr*)&name, namelen,
+ dispName, sizeof(dispName),
+ servName, sizeof(servName),
+ NI_NUMERICHOST | NI_NUMERICSERV) != 0)
+ throw qpid::Exception(QPID_MSG(gai_strerror(rc)));
+ return std::string(dispName) + ":" + std::string(servName);
+ } else {
+ if (int rc = ::getnameinfo((sockaddr*)&name, namelen,
+ dispName, sizeof(dispName),
+ 0, 0,
+ NI_NUMERICHOST) != 0)
+ throw qpid::Exception(QPID_MSG(gai_strerror(rc)));
+ return dispName;
+ }
+}
+
+std::string getService(SOCKET fd, bool local)
+{
+ sockaddr_in name; // big enough for any socket address
+ socklen_t namelen = sizeof(name);
+
+ if (local) {
+ QPID_WINSOCK_CHECK(::getsockname(fd, (sockaddr*)&name, &namelen));
+ } else {
+ QPID_WINSOCK_CHECK(::getpeername(fd, (sockaddr*)&name, &namelen));
+ }
+
+ char servName[NI_MAXSERV];
if (int rc = ::getnameinfo((sockaddr*)&name, namelen,
- dispName, sizeof(dispName),
+ 0, 0,
servName, sizeof(servName),
NI_NUMERICHOST | NI_NUMERICSERV) != 0)
throw qpid::Exception(QPID_MSG(gai_strerror(rc)));
- return std::string(dispName) + ":" + std::string(servName);
+ return servName;
}
} // namespace
@@ -150,22 +174,34 @@ Socket::createSocket(const SocketAddress& sa) const
}
}
+void Socket::setTimeout(const Duration& interval) const
+{
+ const SOCKET& socket = impl->fd;
+ int64_t nanosecs = interval;
+ nanosecs /= (1000 * 1000); // nsecs -> usec -> msec
+ int msec = 0;
+ if (nanosecs > std::numeric_limits<int>::max())
+ msec = std::numeric_limits<int>::max();
+ else
+ msec = static_cast<int>(nanosecs);
+ setsockopt(socket, SOL_SOCKET, SO_SNDTIMEO, (char *)&msec, sizeof(msec));
+ setsockopt(socket, SOL_SOCKET, SO_RCVTIMEO, (char *)&msec, sizeof(msec));
+}
+
void Socket::setNonblocking() const {
u_long nonblock = 1;
QPID_WINSOCK_CHECK(ioctlsocket(impl->fd, FIONBIO, &nonblock));
}
-void Socket::connect(const std::string& host, const std::string& port) const
+void Socket::connect(const std::string& host, uint16_t port) const
{
- SocketAddress sa(host, port);
+ SocketAddress sa(host, boost::lexical_cast<std::string>(port));
connect(sa);
}
void
Socket::connect(const SocketAddress& addr) const
{
- peername = addr.asString(false);
-
const SOCKET& socket = impl->fd;
const addrinfo *addrs = &(getAddrInfo(addr));
int error = 0;
@@ -180,7 +216,7 @@ Socket::connect(const SocketAddress& addr) const
addrs = addrs->ai_next;
}
if (error)
- throw qpid::Exception(QPID_MSG(strError(error) << ": " << peername));
+ throw qpid::Exception(QPID_MSG(strError(error) << ": " << connectname));
}
void
@@ -211,7 +247,7 @@ int Socket::read(void *buf, size_t count) const
return received;
}
-int Socket::listen(const std::string&, const std::string& port, int backlog) const
+int Socket::listen(uint16_t port, int backlog) const
{
const SOCKET& socket = impl->fd;
BOOL yes=1;
@@ -219,7 +255,7 @@ int Socket::listen(const std::string&, const std::string& port, int backlog) con
struct sockaddr_in name;
memset(&name, 0, sizeof(name));
name.sin_family = AF_INET;
- name.sin_port = htons(boost::lexical_cast<uint16_t>(port));
+ name.sin_port = htons(port);
name.sin_addr.s_addr = 0;
if (::bind(socket, (struct sockaddr*)&name, sizeof(name)) == SOCKET_ERROR)
throw Exception(QPID_MSG("Can't bind to port " << port << ": " << strError(WSAGetLastError())));
@@ -241,18 +277,36 @@ Socket* Socket::accept() const
else throw QPID_WINDOWS_ERROR(WSAGetLastError());
}
+std::string Socket::getSockname() const
+{
+ return getName(impl->fd, true);
+}
+
+std::string Socket::getPeername() const
+{
+ return getName(impl->fd, false);
+}
+
std::string Socket::getPeerAddress() const
{
- if (peername.empty())
- peername = getName(impl->fd, false);
- return peername;
+ if (!connectname.empty())
+ return std::string (connectname);
+ return getName(impl->fd, false, true);
}
std::string Socket::getLocalAddress() const
{
- if (localname.empty())
- localname = getName(impl->fd, true);
- return localname;
+ return getName(impl->fd, true, true);
+}
+
+uint16_t Socket::getLocalPort() const
+{
+ return atoi(getService(impl->fd, true).c_str());
+}
+
+uint16_t Socket::getRemotePort() const
+{
+ return atoi(getService(impl->fd, true).c_str());
}
int Socket::getError() const
diff --git a/qpid/cpp/src/qpid/sys/windows/SocketAddress.cpp b/qpid/cpp/src/qpid/sys/windows/SocketAddress.cpp
index ac43cd2d23..501cff1297 100644
--- a/qpid/cpp/src/qpid/sys/windows/SocketAddress.cpp
+++ b/qpid/cpp/src/qpid/sys/windows/SocketAddress.cpp
@@ -19,11 +19,6 @@
*
*/
-// Ensure we get all of winsock2.h
-#ifndef _WIN32_WINNT
-#define _WIN32_WINNT 0x0501
-#endif
-
#include "qpid/sys/SocketAddress.h"
#include "qpid/sys/windows/check.h"
@@ -63,7 +58,7 @@ SocketAddress::~SocketAddress()
::freeaddrinfo(addrInfo);
}
-std::string SocketAddress::asString(bool) const
+std::string SocketAddress::asString() const
{
return host + ":" + port;
}
diff --git a/qpid/cpp/src/qpid/sys/windows/StrError.cpp b/qpid/cpp/src/qpid/sys/windows/StrError.cpp
index 546d399d16..9c1bfcd79c 100755
--- a/qpid/cpp/src/qpid/sys/windows/StrError.cpp
+++ b/qpid/cpp/src/qpid/sys/windows/StrError.cpp
@@ -30,7 +30,6 @@ namespace sys {
std::string strError(int err) {
const size_t bufsize = 512;
char buf[bufsize];
- buf[0] = 0;
if (0 == FormatMessage (FORMAT_MESSAGE_MAX_WIDTH_MASK
| FORMAT_MESSAGE_FROM_SYSTEM,
0,
@@ -40,11 +39,7 @@ std::string strError(int err) {
bufsize,
0))
{
-#ifdef _MSC_VER
- strerror_s(buf, bufsize, err);
-#else
- return std::string(strerror(err));
-#endif
+ strerror_s (buf, bufsize, err);
}
return std::string(buf);
}
diff --git a/qpid/cpp/src/qpid/sys/windows/Thread.cpp b/qpid/cpp/src/qpid/sys/windows/Thread.cpp
index 23b0033be4..583a9613a3 100755
--- a/qpid/cpp/src/qpid/sys/windows/Thread.cpp
+++ b/qpid/cpp/src/qpid/sys/windows/Thread.cpp
@@ -19,11 +19,6 @@
*
*/
-// Ensure definition of OpenThread in mingw
-#ifndef _WIN32_WINNT
-#define _WIN32_WINNT 0x0501
-#endif
-
#include "qpid/sys/Thread.h"
#include "qpid/sys/Runnable.h"
#include "qpid/sys/windows/check.h"
@@ -31,204 +26,50 @@
#include <process.h>
#include <windows.h>
-/*
- * This implementation distinguishes between two types of thread: Qpid
- * threads (based on qpid::sys::Runnable) and the rest. It provides a
- * join() that will not deadlock against the Windows loader lock for
- * Qpid threads.
- *
- * System thread identifiers are unique per Windows thread; thread
- * handles are not. Thread identifiers can be recycled, but keeping a
- * handle open against the thread prevents recycling as long as
- * shared_ptr references to a ThreadPrivate structure remain.
- *
- * There is a 1-1 relationship between Qpid threads and their
- * ThreadPrivate structure. Non-Qpid threads do not need to find the
- * qpidThreadDone handle, so there may be a 1-many relationship for
- * them.
- *
- * TLS storage is used for a lockless solution for static library
- * builds. The special case of LoadLibrary/FreeLibrary requires
- * additional synchronization variables and resource cleanup in
- * DllMain. _DLL marks the dynamic case.
- */
+namespace {
+unsigned __stdcall runRunnable(void* p)
+{
+ static_cast<qpid::sys::Runnable*>(p)->run();
+ _endthreadex(0);
+ return 0;
+}
+}
namespace qpid {
namespace sys {
class ThreadPrivate {
-public:
friend class Thread;
- friend unsigned __stdcall runThreadPrivate(void*);
- typedef boost::shared_ptr<ThreadPrivate> shared_ptr;
- ~ThreadPrivate();
-private:
- unsigned threadId;
HANDLE threadHandle;
- HANDLE initCompleted;
- HANDLE qpidThreadDone;
- Runnable* runnable;
- shared_ptr keepAlive;
-
- ThreadPrivate() : threadId(GetCurrentThreadId()), initCompleted(NULL),
- qpidThreadDone(NULL), runnable(NULL) {
- threadHandle = OpenThread (SYNCHRONIZE, FALSE, threadId);
- QPID_WINDOWS_CHECK_CRT_NZ(threadHandle);
- }
-
- ThreadPrivate(Runnable* r) : threadHandle(NULL), initCompleted(NULL),
- qpidThreadDone(NULL), runnable(r) {}
-
- void start(shared_ptr& p);
- static shared_ptr createThread(Runnable* r);
-};
-
-}} // namespace qpid::sys
-
-
-namespace {
-using namespace qpid::sys;
-
-#ifdef _DLL
-class ScopedCriticalSection
-{
- public:
- ScopedCriticalSection(CRITICAL_SECTION& cs) : criticalSection(cs) { EnterCriticalSection(&criticalSection); }
- ~ScopedCriticalSection() { LeaveCriticalSection(&criticalSection); }
- private:
- CRITICAL_SECTION& criticalSection;
-};
-
-CRITICAL_SECTION threadLock;
-long runningThreads = 0;
-HANDLE threadsDone;
-bool terminating = false;
-#endif
-
-
-DWORD volatile tlsIndex = TLS_OUT_OF_INDEXES;
-
-DWORD getTlsIndex() {
- if (tlsIndex != TLS_OUT_OF_INDEXES)
- return tlsIndex; // already set
-
- DWORD trialIndex = TlsAlloc();
- QPID_WINDOWS_CHECK_NOT(trialIndex, TLS_OUT_OF_INDEXES); // No OS resource
+ unsigned threadId;
- // only one thread gets to set the value
- DWORD actualIndex = (DWORD) InterlockedCompareExchange((LONG volatile *) &tlsIndex, (LONG) trialIndex, (LONG) TLS_OUT_OF_INDEXES);
- if (actualIndex == TLS_OUT_OF_INDEXES)
- return trialIndex; // we won the race
- else {
- TlsFree(trialIndex);
- return actualIndex;
+ ThreadPrivate(Runnable* runnable) {
+ uintptr_t h = _beginthreadex(0,
+ 0,
+ runRunnable,
+ runnable,
+ 0,
+ &threadId);
+ QPID_WINDOWS_CHECK_CRT_NZ(h);
+ threadHandle = reinterpret_cast<HANDLE>(h);
}
-}
-
-} // namespace
-
-namespace qpid {
-namespace sys {
-
-unsigned __stdcall runThreadPrivate(void* p)
-{
- ThreadPrivate* threadPrivate = static_cast<ThreadPrivate*>(p);
- TlsSetValue(getTlsIndex(), threadPrivate);
-
- WaitForSingleObject (threadPrivate->initCompleted, INFINITE);
- CloseHandle (threadPrivate->initCompleted);
- threadPrivate->initCompleted = NULL;
-
- try {
- threadPrivate->runnable->run();
- } catch (...) {
- // not our concern
- }
-
- SetEvent (threadPrivate->qpidThreadDone); // allow join()
- threadPrivate->keepAlive.reset(); // may run ThreadPrivate destructor
-
-#ifdef _DLL
- {
- ScopedCriticalSection l(threadLock);
- if (--runningThreads == 0)
- SetEvent(threadsDone);
- }
-#endif
- return 0;
-}
-
-
-ThreadPrivate::shared_ptr ThreadPrivate::createThread(Runnable* runnable) {
- ThreadPrivate::shared_ptr tp(new ThreadPrivate(runnable));
- tp->start(tp);
- return tp;
-}
-
-void ThreadPrivate::start(ThreadPrivate::shared_ptr& tp) {
- getTlsIndex(); // fail here if OS problem, not in new thread
-
- initCompleted = CreateEvent (NULL, TRUE, FALSE, NULL);
- QPID_WINDOWS_CHECK_CRT_NZ(initCompleted);
- qpidThreadDone = CreateEvent (NULL, TRUE, FALSE, NULL);
- QPID_WINDOWS_CHECK_CRT_NZ(qpidThreadDone);
-
-#ifdef _DLL
- {
- ScopedCriticalSection l(threadLock);
- if (terminating)
- throw qpid::Exception(QPID_MSG("creating thread after exit/FreeLibrary"));
- runningThreads++;
- }
-#endif
-
- uintptr_t h = _beginthreadex(0,
- 0,
- runThreadPrivate,
- (void *)this,
- 0,
- &threadId);
-
-#ifdef _DLL
- if (h == NULL) {
- ScopedCriticalSection l(threadLock);
- if (--runningThreads == 0)
- SetEvent(threadsDone);
- }
-#endif
-
- QPID_WINDOWS_CHECK_CRT_NZ(h);
-
- // Success
- keepAlive = tp;
- threadHandle = reinterpret_cast<HANDLE>(h);
- SetEvent (initCompleted);
-}
-
-ThreadPrivate::~ThreadPrivate() {
- if (threadHandle)
- CloseHandle (threadHandle);
- if (initCompleted)
- CloseHandle (initCompleted);
- if (qpidThreadDone)
- CloseHandle (qpidThreadDone);
-}
-
+
+ ThreadPrivate()
+ : threadHandle(GetCurrentThread()), threadId(GetCurrentThreadId()) {}
+};
Thread::Thread() {}
-Thread::Thread(Runnable* runnable) : impl(ThreadPrivate::createThread(runnable)) {}
+Thread::Thread(Runnable* runnable) : impl(new ThreadPrivate(runnable)) {}
-Thread::Thread(Runnable& runnable) : impl(ThreadPrivate::createThread(&runnable)) {}
+Thread::Thread(Runnable& runnable) : impl(new ThreadPrivate(&runnable)) {}
Thread::operator bool() {
return impl;
}
bool Thread::operator==(const Thread& t) const {
- if (!impl || !t.impl)
- return false;
return impl->threadId == t.impl->threadId;
}
@@ -238,17 +79,10 @@ bool Thread::operator!=(const Thread& t) const {
void Thread::join() {
if (impl) {
- DWORD status;
- if (impl->runnable) {
- HANDLE handles[2] = {impl->qpidThreadDone, impl->threadHandle};
- // wait for either. threadHandle not signalled if loader
- // lock held (FreeLibrary). qpidThreadDone not signalled
- // if thread terminated by exit().
- status = WaitForMultipleObjects (2, handles, false, INFINITE);
- }
- else
- status = WaitForSingleObject (impl->threadHandle, INFINITE);
+ DWORD status = WaitForSingleObject (impl->threadHandle, INFINITE);
QPID_WINDOWS_CHECK_NOT(status, WAIT_FAILED);
+ CloseHandle (impl->threadHandle);
+ impl->threadHandle = 0;
}
}
@@ -258,70 +92,9 @@ unsigned long Thread::logId() {
/* static */
Thread Thread::current() {
- ThreadPrivate* tlsValue = (ThreadPrivate *) TlsGetValue(getTlsIndex());
Thread t;
- if (tlsValue != NULL) {
- // called from within Runnable->run(), so keepAlive has positive use count
- t.impl = tlsValue->keepAlive;
- }
- else
- t.impl.reset(new ThreadPrivate());
+ t.impl.reset(new ThreadPrivate());
return t;
}
-}} // namespace qpid::sys
-
-
-#ifdef _DLL
-
-// DllMain: called possibly many times in a process lifetime if dll
-// loaded and freed repeatedly . Be mindful of Windows loader lock
-// and other DllMain restrictions.
-
-BOOL APIENTRY DllMain(HMODULE hm, DWORD reason, LPVOID reserved) {
- switch (reason) {
- case DLL_PROCESS_ATTACH:
- InitializeCriticalSection(&threadLock);
- threadsDone = CreateEvent(NULL, TRUE, FALSE, NULL);
- break;
-
- case DLL_PROCESS_DETACH:
- terminating = true;
- if (reserved != NULL) {
- // process exit(): threads are stopped arbitrarily and
- // possibly in an inconsistent state. Not even threadLock
- // can be trusted. All static destructors have been
- // called at this point and any resources this unit knows
- // about will be released as part of process tear down by
- // the OS. Accordingly, do nothing.
- return TRUE;
- }
- else {
- // FreeLibrary(): threads are still running and we are
- // encouraged to clean up to avoid leaks. Mostly we just
- // want any straggler threads to finish and notify
- // threadsDone as the last thing they do.
- while (1) {
- {
- ScopedCriticalSection l(threadLock);
- if (runningThreads == 0)
- break;
- ResetEvent(threadsDone);
- }
- WaitForSingleObject(threadsDone, INFINITE);
- }
- if (tlsIndex != TLS_OUT_OF_INDEXES)
- TlsFree(getTlsIndex());
- CloseHandle(threadsDone);
- DeleteCriticalSection(&threadLock);
- }
- break;
-
- case DLL_THREAD_ATTACH:
- case DLL_THREAD_DETACH:
- break;
- }
- return TRUE;
-}
-
-#endif
+}} /* qpid::sys */
diff --git a/qpid/cpp/src/qpid/sys/windows/Time.cpp b/qpid/cpp/src/qpid/sys/windows/Time.cpp
index 25c50819cd..16d09fcdc0 100644
--- a/qpid/cpp/src/qpid/sys/windows/Time.cpp
+++ b/qpid/cpp/src/qpid/sys/windows/Time.cpp
@@ -27,17 +27,6 @@
using namespace boost::posix_time;
-namespace {
-
-// High-res timing support. This will display times since program start,
-// more or less. Keep track of the start value and the conversion factor to
-// seconds.
-bool timeInitialized = false;
-LARGE_INTEGER start;
-double freq = 1.0;
-
-}
-
namespace qpid {
namespace sys {
@@ -102,35 +91,10 @@ void outputFormattedNow(std::ostream& o) {
char time_string[100];
::time( &rawtime );
-#ifdef _MSC_VER
::localtime_s(&timeinfo, &rawtime);
-#else
- timeinfo = *(::localtime(&rawtime));
-#endif
::strftime(time_string, 100,
"%Y-%m-%d %H:%M:%S",
&timeinfo);
o << time_string << " ";
}
-
-void outputHiresNow(std::ostream& o) {
- if (!timeInitialized) {
- start.QuadPart = 0;
- LARGE_INTEGER iFreq;
- iFreq.QuadPart = 1;
- QueryPerformanceCounter(&start);
- QueryPerformanceFrequency(&iFreq);
- freq = static_cast<double>(iFreq.QuadPart);
- timeInitialized = true;
- }
- LARGE_INTEGER iNow;
- iNow.QuadPart = 0;
- QueryPerformanceCounter(&iNow);
- iNow.QuadPart -= start.QuadPart;
- if (iNow.QuadPart < 0)
- iNow.QuadPart = 0;
- double now = static_cast<double>(iNow.QuadPart);
- now /= freq; // now is seconds after this
- o << std::fixed << std::setprecision(8) << std::setw(16) << std::setfill('0') << now << "s ";
-}
}}
diff --git a/qpid/cpp/src/qpid/sys/windows/mingw32_compat.h b/qpid/cpp/src/qpid/sys/windows/mingw32_compat.h
deleted file mode 100644
index 51f613cc25..0000000000
--- a/qpid/cpp/src/qpid/sys/windows/mingw32_compat.h
+++ /dev/null
@@ -1,39 +0,0 @@
-#ifndef _sys_windows_mingw32_compat
-#define _sys_windows_mingw32_compat
-/*
- *
- * 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.
- *
- */
-
-#ifdef WIN32
-#ifndef _MSC_VER
-
-//
-// The following definitions for extension function GUIDs and signatures are taken from
-// MswSock.h in the Windows32 SDK. These rightfully belong in the mingw32 version of
-// mswsock.h, but are not included presently.
-//
-
-#define WSAID_ACCEPTEX {0xb5367df1,0xcbac,0x11cf,{0x95,0xca,0x00,0x80,0x5f,0x48,0xa1,0x92}}
-typedef BOOL (PASCAL *LPFN_ACCEPTEX)(SOCKET,SOCKET,PVOID,DWORD,DWORD,DWORD,LPDWORD,LPOVERLAPPED);
-
-#endif
-#endif
-
-#endif
diff --git a/qpid/cpp/src/qpid/sys/windows/uuid.cpp b/qpid/cpp/src/qpid/sys/windows/uuid.cpp
index 3316ecbc00..b5360622dc 100644
--- a/qpid/cpp/src/qpid/sys/windows/uuid.cpp
+++ b/qpid/cpp/src/qpid/sys/windows/uuid.cpp
@@ -19,7 +19,7 @@
*
*/
-#include <rpc.h>
+#include <Rpc.h>
#ifdef uuid_t /* Done in rpcdce.h */
# undef uuid_t
#endif
@@ -52,11 +52,7 @@ int uuid_parse (const char *in, uuid_t uu) {
void uuid_unparse (const uuid_t uu, char *out) {
unsigned char *formatted;
if (UuidToString((UUID*)uu, &formatted) == RPC_S_OK) {
-#ifdef _MSC_VER
strncpy_s (out, 36+1, (char*)formatted, _TRUNCATE);
-#else
- strncpy (out, (char*)formatted, 36+1);
-#endif
RpcStringFree(&formatted);
}
}
diff --git a/qpid/cpp/src/qpid/types/Variant.cpp b/qpid/cpp/src/qpid/types/Variant.cpp
index 0b28234025..5d8878bdac 100644
--- a/qpid/cpp/src/qpid/types/Variant.cpp
+++ b/qpid/cpp/src/qpid/types/Variant.cpp
@@ -108,27 +108,15 @@ class VariantImpl
} value;
std::string encoding;//optional encoding for variable length data
+ std::string getTypeName(VariantType type) const;
template<class T> T convertFromString() const
{
std::string* s = reinterpret_cast<std::string*>(value.v);
- if (std::numeric_limits<T>::is_signed || s->find('-') != 0) {
- //lexical_cast won't fail if string is a negative number and T is unsigned
- try {
- return boost::lexical_cast<T>(*s);
- } catch(const boost::bad_lexical_cast&) {
- //don't return, throw exception below
- }
- } else {
- //T is unsigned and number starts with '-'
- try {
- //handle special case of negative zero
- if (boost::lexical_cast<int>(*s) == 0) return 0;
- //else its a non-zero negative number so throw exception at end of function
- } catch(const boost::bad_lexical_cast&) {
- //wasn't a valid int, therefore not a valid uint
- }
+ try {
+ return boost::lexical_cast<T>(*s);
+ } catch(const boost::bad_lexical_cast&) {
+ throw InvalidConversion(QPID_MSG("Cannot convert " << *s));
}
- throw InvalidConversion(QPID_MSG("Cannot convert " << *s));
}
};
@@ -382,11 +370,11 @@ int8_t VariantImpl::asInt8() const
return int8_t(value.ui16);
break;
case VAR_UINT32:
- if (value.ui32 <= (uint32_t) std::numeric_limits<int8_t>::max())
+ if (value.ui32 <= (uint) std::numeric_limits<int8_t>::max())
return int8_t(value.ui32);
break;
case VAR_UINT64:
- if (value.ui64 <= (uint64_t) std::numeric_limits<int8_t>::max())
+ if (value.ui64 <= (uint) std::numeric_limits<int8_t>::max())
return int8_t(value.ui64);
break;
case VAR_STRING: return convertFromString<int8_t>();
@@ -413,11 +401,11 @@ int16_t VariantImpl::asInt16() const
return int16_t(value.ui16);
break;
case VAR_UINT32:
- if (value.ui32 <= (uint32_t) std::numeric_limits<int16_t>::max())
+ if (value.ui32 <= (uint) std::numeric_limits<int16_t>::max())
return int16_t(value.ui32);
break;
case VAR_UINT64:
- if (value.ui64 <= (uint64_t) std::numeric_limits<int16_t>::max())
+ if (value.ui64 <= (uint) std::numeric_limits<int16_t>::max())
return int16_t(value.ui64);
break;
case VAR_STRING: return convertFromString<int16_t>();
@@ -442,7 +430,7 @@ int32_t VariantImpl::asInt32() const
return int32_t(value.ui32);
break;
case VAR_UINT64:
- if (value.ui64 <= (uint64_t) std::numeric_limits<int32_t>::max())
+ if (value.ui64 <= (uint32_t) std::numeric_limits<int32_t>::max())
return int32_t(value.ui64);
break;
case VAR_STRING: return convertFromString<int32_t>();
@@ -594,7 +582,7 @@ const std::string& VariantImpl::getString() const
void VariantImpl::setEncoding(const std::string& s) { encoding = s; }
const std::string& VariantImpl::getEncoding() const { return encoding; }
-std::string getTypeName(VariantType type)
+std::string VariantImpl::getTypeName(VariantType type) const
{
switch (type) {
case VAR_VOID: return "void";
diff --git a/qpid/cpp/src/replication.mk b/qpid/cpp/src/replication.mk
index e5da32f88b..dbe071f405 100644
--- a/qpid/cpp/src/replication.mk
+++ b/qpid/cpp/src/replication.mk
@@ -19,14 +19,14 @@
# Make file for building two plugins for asynchronously replicating
# queues.
-dmoduleexec_LTLIBRARIES += replicating_listener.la replication_exchange.la
+dmodule_LTLIBRARIES += replicating_listener.la replication_exchange.la
# a queue event listener plugin that creates messages on a replication
# queue corresponding to enqueue and dequeue events:
replicating_listener_la_SOURCES = \
qpid/replication/constants.h \
qpid/replication/ReplicatingEventListener.cpp \
- qpid/replication/ReplicatingEventListener.h
+ qpid/replication/ReplicatingEventListener.h
replicating_listener_la_LIBADD = libqpidbroker.la
if SUNOS
@@ -41,7 +41,7 @@ replicating_listener_la_LDFLAGS = $(PLUGINLDFLAGS)
replication_exchange_la_SOURCES = \
qpid/replication/constants.h \
qpid/replication/ReplicationExchange.cpp \
- qpid/replication/ReplicationExchange.h
+ qpid/replication/ReplicationExchange.h
replication_exchange_la_LIBADD = libqpidbroker.la
diff --git a/qpid/cpp/src/ssl.mk b/qpid/cpp/src/ssl.mk
index 4dba9bb61c..5fbdd55438 100644
--- a/qpid/cpp/src/ssl.mk
+++ b/qpid/cpp/src/ssl.mk
@@ -18,7 +18,7 @@
#
#
# Makefile fragment, conditionally included in Makefile.am
-#
+#
libsslcommon_la_SOURCES = \
qpid/sys/ssl/check.h \
qpid/sys/ssl/check.cpp \
@@ -47,7 +47,7 @@ ssl_la_CXXFLAGS=$(AM_CXXFLAGS) $(SSL_CFLAGS)
ssl_la_LDFLAGS = $(PLUGINLDFLAGS)
-dmoduleexec_LTLIBRARIES += ssl.la
+dmodule_LTLIBRARIES += ssl.la
sslconnector_la_SOURCES = \
qpid/client/SslConnector.cpp
@@ -60,5 +60,5 @@ sslconnector_la_CXXFLAGS = $(AM_CXXFLAGS) -DQPIDC_CONF_FILE=\"$(confdir)/qpidc.c
sslconnector_la_LDFLAGS = $(PLUGINLDFLAGS)
-cmoduleexec_LTLIBRARIES += \
+cmodule_LTLIBRARIES += \
sslconnector.la
diff --git a/qpid/cpp/src/tests/.valgrind.supp b/qpid/cpp/src/tests/.valgrind.supp
index 2c6a1509ff..0e3e045437 100644
--- a/qpid/cpp/src/tests/.valgrind.supp
+++ b/qpid/cpp/src/tests/.valgrind.supp
@@ -73,6 +73,61 @@
}
{
+ boost 103200 -- we think Boost is responsible for these leaks.
+ Memcheck:Leak
+ fun:_Znwm
+ fun:_ZN5boost15program_options??options_description*
+}
+
+{
+ boost 103200 -- we think Boost is responsible for these leaks.
+ Memcheck:Leak
+ fun:_Znwm
+ fun:_ZN5boost9unit_test9test_case*
+}
+
+{
+ boost 103200 -- we think Boost is responsible for these leaks.
+ Memcheck:Leak
+ fun:calloc
+ fun:_dlerror_run
+ fun:dlopen@@GLIBC_2.2.5
+ fun:_ZN4qpid3sys5Shlib4loadEPKc
+ fun:_Z9testShlibv
+ fun:_ZN5boost9unit_test9ut_detail17unit_test_monitor8functionEv
+ obj:/usr/lib64/libboost_unit_test_framework.so.1.32.0
+ fun:_ZN5boost17execution_monitor7executeEbi
+ fun:_ZN5boost9unit_test9ut_detail17unit_test_monitor21execute_and_translateEPNS0_9test_caseEMS3_FvvEi
+ fun:_ZN5boost9unit_test9test_case3runEv
+ fun:_ZN5boost9unit_test10test_suite6do_runEv
+ fun:_ZN5boost9unit_test9test_case3runEv
+ fun:main
+}
+
+{
+ boost 103200 -- we think Boost is responsible for these leaks.
+ Memcheck:Leak
+ fun:calloc
+ fun:_dl_allocate_tls
+ fun:pthread_create@@GLIBC_2.2.5
+ fun:_ZN4qpid6broker5Timer5startEv
+ fun:_ZN4qpid6broker5TimerC1Ev
+ fun:_ZN4qpid6broker10DtxManagerC1Ev
+ fun:_ZN4qpid6broker6BrokerC1ERKNS1_7OptionsE
+ fun:_ZN4qpid6broker6Broker6createERKNS1_7OptionsE
+ fun:_ZN15SessionFixtureTI15ProxyConnectionEC2Ev
+ fun:_Z14testQueueQueryv
+ fun:_ZN5boost9unit_test9ut_detail17unit_test_monitor8functionEv
+ obj:/usr/lib64/libboost_unit_test_framework.so.1.32.0
+ fun:_ZN5boost17execution_monitor7executeEbi
+ fun:_ZN5boost9unit_test9ut_detail17unit_test_monitor21execute_and_translateEPNS0_9test_caseEMS3_FvvEi
+ fun:_ZN5boost9unit_test9test_case3runEv
+ fun:_ZN5boost9unit_test10test_suite6do_runEv
+ fun:_ZN5boost9unit_test9test_case3runEv
+ fun:main
+}
+
+{
INVESTIGATE
Memcheck:Leak
fun:calloc
@@ -100,6 +155,25 @@
}
{
+ boost 103200 -- mgoulish -- fix this, sometime
+ Memcheck:Leak
+ fun:*
+ fun:*
+ obj:*
+ fun:*
+ fun:_ZN4qpid34options_description_less_easy_initclEPKcPKN5boost15program_options14value_semanticES2_
+}
+
+{
+ boost 103200 -- mgoulish -- fix this, sometime
+ Memcheck:Leak
+ fun:*
+ fun:*
+ fun:*
+ fun:_ZN4qpid34options_description_less_easy_initclEPKcPKN5boost15program_options14value_semanticES2_
+}
+
+{
INVESTIGATE
Memcheck:Param
socketcall.sendto(msg)
diff --git a/qpid/cpp/src/tests/Address.cpp b/qpid/cpp/src/tests/Address.cpp
index 0fd3585958..f41f27b6df 100644
--- a/qpid/cpp/src/tests/Address.cpp
+++ b/qpid/cpp/src/tests/Address.cpp
@@ -119,17 +119,6 @@ QPID_AUTO_TEST_CASE(testParseQuotedNameAndSubject)
BOOST_CHECK_EQUAL(std::string("my subject with ; in it"), address.getSubject());
}
-QPID_AUTO_TEST_CASE(testParseOptionsWithEmptyStringAsValue)
-{
- Address address("my-topic; {a:'', x:101}");
- BOOST_CHECK_EQUAL(std::string("my-topic"), address.getName());
- Variant a = address.getOptions()["a"];
- BOOST_CHECK_EQUAL(VAR_STRING, a.getType());
- std::string aVal = a;
- BOOST_CHECK(aVal.size() == 0);
- BOOST_CHECK_EQUAL((uint16_t) 101, address.getOptions()["x"].asInt64());
-}
-
QPID_AUTO_TEST_SUITE_END()
}}
diff --git a/qpid/cpp/src/tests/BrokerMgmtAgent.cpp b/qpid/cpp/src/tests/BrokerMgmtAgent.cpp
index 1d5289dc90..d0c6668b72 100644
--- a/qpid/cpp/src/tests/BrokerMgmtAgent.cpp
+++ b/qpid/cpp/src/tests/BrokerMgmtAgent.cpp
@@ -599,12 +599,13 @@ namespace qpid {
// populate the agent with multiple test objects
const size_t objCount = 50;
std::vector<TestManageable *> tmv;
+ uint32_t objLen;
for (size_t i = 0; i < objCount; i++) {
std::stringstream key;
key << "testobj-" << i;
TestManageable *tm = new TestManageable(agent, key.str());
- (void) tm->GetManagementObject()->writePropertiesSize();
+ objLen = tm->GetManagementObject()->writePropertiesSize();
agent->addObject(tm->GetManagementObject(), key.str());
tmv.push_back(tm);
}
diff --git a/qpid/cpp/src/tests/CMakeLists.txt b/qpid/cpp/src/tests/CMakeLists.txt
index 401b137dc7..405718f12b 100644
--- a/qpid/cpp/src/tests/CMakeLists.txt
+++ b/qpid/cpp/src/tests/CMakeLists.txt
@@ -278,7 +278,7 @@ set(test_wrap ${shell} ${CMAKE_CURRENT_SOURCE_DIR}/run_test${test_script_suffix}
add_test (unit_test ${test_wrap} ${unit_test_LOCATION})
add_test (start_broker ${shell} ${CMAKE_CURRENT_SOURCE_DIR}/start_broker${test_script_suffix})
-add_test (qpid-client-test ${test_wrap} ${qpid-client-test_LOCATION})
+add_test (qpid-client-test ${test_wrap} ${qpid-client_test_LOCATION})
add_test (quick_perftest ${test_wrap} ${qpid-perftest_LOCATION} --summary --count 100)
add_test (quick_topictest ${test_wrap} ${CMAKE_CURRENT_SOURCE_DIR}/quick_topictest${test_script_suffix})
add_test (quick_txtest ${test_wrap} ${qpid-txtest_LOCATION} --queues 4 --tx-count 10 --quiet)
diff --git a/qpid/cpp/src/tests/ClientSessionTest.cpp b/qpid/cpp/src/tests/ClientSessionTest.cpp
index 3c0cff7350..939f8f2b88 100644
--- a/qpid/cpp/src/tests/ClientSessionTest.cpp
+++ b/qpid/cpp/src/tests/ClientSessionTest.cpp
@@ -271,12 +271,8 @@ QPID_AUTO_TEST_CASE(testOpenFailure) {
QPID_AUTO_TEST_CASE(testPeriodicExpiration) {
Broker::Options opts;
opts.queueCleanInterval = 1;
- opts.queueFlowStopRatio = 0;
- opts.queueFlowResumeRatio = 0;
ClientSessionFixture fix(opts);
- FieldTable args;
- args.setInt("qpid.max_count",10);
- fix.session.queueDeclare(arg::queue="my-queue", arg::exclusive=true, arg::autoDelete=true, arg::arguments=args);
+ fix.session.queueDeclare(arg::queue="my-queue", arg::exclusive=true, arg::autoDelete=true);
for (uint i = 0; i < 10; i++) {
Message m((boost::format("Message_%1%") % (i+1)).str(), "my-queue");
@@ -287,7 +283,6 @@ QPID_AUTO_TEST_CASE(testPeriodicExpiration) {
BOOST_CHECK_EQUAL(fix.session.queueQuery(string("my-queue")).getMessageCount(), 10u);
qpid::sys::sleep(2);
BOOST_CHECK_EQUAL(fix.session.queueQuery(string("my-queue")).getMessageCount(), 5u);
- fix.session.messageTransfer(arg::content=Message("Message_11", "my-queue"));//ensure policy is also updated
}
QPID_AUTO_TEST_CASE(testExpirationOnPop) {
diff --git a/qpid/cpp/src/tests/ExchangeTest.cpp b/qpid/cpp/src/tests/ExchangeTest.cpp
index fe72f42a46..88a1cd99c2 100644
--- a/qpid/cpp/src/tests/ExchangeTest.cpp
+++ b/qpid/cpp/src/tests/ExchangeTest.cpp
@@ -253,7 +253,7 @@ QPID_AUTO_TEST_CASE(testIVEOption)
TopicExchange topic ("topic1", false, args);
intrusive_ptr<Message> msg1 = cmessage("direct1", "abc");
- msg1->insertCustomProperty("a", "abc");
+ msg1->getProperties<MessageProperties>()->getApplicationHeaders().setString("a", "abc");
DeliverableMessage dmsg1(msg1);
FieldTable args2;
diff --git a/qpid/cpp/src/tests/ForkedBroker.cpp b/qpid/cpp/src/tests/ForkedBroker.cpp
index 10674b5175..53eaa7e1ce 100644
--- a/qpid/cpp/src/tests/ForkedBroker.cpp
+++ b/qpid/cpp/src/tests/ForkedBroker.cpp
@@ -68,7 +68,8 @@ ForkedBroker::~ForkedBroker() {
}
if (!dataDir.empty())
{
- (void) ::system(("rm -rf "+dataDir).c_str());
+ int unused_ret; // Suppress warnings about ignoring return value.
+ unused_ret = ::system(("rm -rf "+dataDir).c_str());
}
}
diff --git a/qpid/cpp/src/tests/Makefile.am b/qpid/cpp/src/tests/Makefile.am
index 1a6e56dbfd..9a1c9e51f6 100644
--- a/qpid/cpp/src/tests/Makefile.am
+++ b/qpid/cpp/src/tests/Makefile.am
@@ -286,6 +286,18 @@ check_PROGRAMS+=datagen
datagen_SOURCES=datagen.cpp
datagen_LDADD=$(lib_common) $(lib_client)
+check_PROGRAMS+=qrsh_server
+qrsh_server_SOURCES=qrsh_server.cpp
+qrsh_server_LDADD=$(lib_client)
+
+check_PROGRAMS+=qrsh_run
+qrsh_run_SOURCES=qrsh_run.cpp
+qrsh_run_LDADD=$(lib_client)
+
+check_PROGRAMS+=qrsh
+qrsh_SOURCES=qrsh.cpp
+qrsh_LDADD=$(lib_client)
+
check_PROGRAMS+=qpid-stream
qpid_stream_INCLUDES=$(PUBLIC_INCLUDES)
qpid_stream_SOURCES=qpid-stream.cpp
@@ -298,7 +310,7 @@ TESTS_ENVIRONMENT = \
$(srcdir)/run_test
system_tests = qpid-client-test quick_perftest quick_topictest run_header_test quick_txtest
-TESTS += start_broker $(system_tests) python_tests stop_broker run_federation_tests run_federation_sys_tests \
+TESTS += start_broker $(system_tests) python_tests stop_broker run_federation_tests \
run_acl_tests run_cli_tests replication_test dynamic_log_level_test \
run_queue_flow_limit_tests
@@ -315,8 +327,6 @@ EXTRA_DIST += \
config.null \
ais_check \
run_federation_tests \
- run_federation_sys_tests \
- run_long_federation_sys_tests \
run_cli_tests \
run_acl_tests \
.valgrind.supp \
@@ -354,7 +364,6 @@ CLEANFILES+=valgrind.out *.log *.vglog* dummy_test qpidd.port $(unit_wrappers)
# Not run under valgrind, too slow
LONG_TESTS+=start_broker fanout_perftest shared_perftest multiq_perftest topic_perftest run_ring_queue_test stop_broker \
- run_long_federation_sys_tests \
run_failover_soak reliable_replication_test \
federated_cluster_test_with_node_failure
diff --git a/qpid/cpp/src/tests/MessageUtils.h b/qpid/cpp/src/tests/MessageUtils.h
index a1b140d484..baca14cf4e 100644
--- a/qpid/cpp/src/tests/MessageUtils.h
+++ b/qpid/cpp/src/tests/MessageUtils.h
@@ -20,6 +20,7 @@
*/
#include "qpid/broker/Message.h"
+#include "qpid/broker/AsyncCompletion.h"
#include "qpid/framing/AMQFrame.h"
#include "qpid/framing/MessageTransferBody.h"
#include "qpid/framing/Uuid.h"
@@ -28,6 +29,17 @@ using namespace qpid;
using namespace broker;
using namespace framing;
+namespace {
+ class DummyCompletion : public AsyncCompletion
+ {
+ public:
+ DummyCompletion() {}
+ virtual ~DummyCompletion() {}
+ protected:
+ void completed(bool) {}
+ };
+}
+
namespace qpid {
namespace tests {
@@ -50,6 +62,8 @@ struct MessageUtils
msg->getFrames().getHeaders()->get<DeliveryProperties>(true)->setRoutingKey(routingKey);
if (durable)
msg->getFrames().getHeaders()->get<DeliveryProperties>(true)->setDeliveryMode(2);
+ boost::shared_ptr<AsyncCompletion>dc(new DummyCompletion());
+ msg->setIngressCompletion(dc);
return msg;
}
diff --git a/qpid/cpp/src/tests/MessagingSessionTests.cpp b/qpid/cpp/src/tests/MessagingSessionTests.cpp
index 161b55b909..20ed16dece 100644
--- a/qpid/cpp/src/tests/MessagingSessionTests.cpp
+++ b/qpid/cpp/src/tests/MessagingSessionTests.cpp
@@ -611,28 +611,6 @@ QPID_AUTO_TEST_CASE(testAssertPolicyQueue)
fix.admin.deleteQueue("q");
}
-QPID_AUTO_TEST_CASE(testAssertExchangeOption)
-{
- MessagingFixture fix;
- std::string a1 = "e; {create:always, assert:always, node:{type:topic, x-declare:{type:direct, arguments:{qpid.msg_sequence:True}}}}";
- Sender s1 = fix.session.createSender(a1);
- s1.close();
- Receiver r1 = fix.session.createReceiver(a1);
- r1.close();
-
- std::string a2 = "e; {assert:receiver, node:{type:topic, x-declare:{type:fanout, arguments:{qpid.msg_sequence:True}}}}";
- Sender s2 = fix.session.createSender(a2);
- s2.close();
- BOOST_CHECK_THROW(fix.session.createReceiver(a2), qpid::messaging::AssertionFailed);
-
- std::string a3 = "e; {assert:sender, node:{x-declare:{arguments:{qpid.msg_sequence:False}}}}";
- BOOST_CHECK_THROW(fix.session.createSender(a3), qpid::messaging::AssertionFailed);
- Receiver r3 = fix.session.createReceiver(a3);
- r3.close();
-
- fix.admin.deleteExchange("e");
-}
-
QPID_AUTO_TEST_CASE(testGetSender)
{
QueueFixture fix;
@@ -1000,92 +978,6 @@ QPID_AUTO_TEST_CASE(testRejectAndCredit)
sender.close();
}
-QPID_AUTO_TEST_CASE(testTtlForever)
-{
- QueueFixture fix;
- Sender sender = fix.session.createSender(fix.queue);
- Message out("I want to live forever!");
- out.setTtl(Duration::FOREVER);
- sender.send(out, true);
- Receiver receiver = fix.session.createReceiver(fix.queue);
- Message in = receiver.fetch(Duration::IMMEDIATE);
- fix.session.acknowledge();
- BOOST_CHECK_EQUAL(in.getContent(), out.getContent());
- BOOST_CHECK(in.getTtl() == Duration::FOREVER);
-}
-
-QPID_AUTO_TEST_CASE(testExclusiveTopicSubscriber)
-{
- TopicFixture fix;
- std::string address = (boost::format("%1%; { link: { name: 'my-subscription', x-declare: { auto-delete: true, exclusive: true }}}") % fix.topic).str();
- Sender sender = fix.session.createSender(fix.topic);
- Receiver receiver1 = fix.session.createReceiver(address);
- {
- ScopedSuppressLogging sl;
- try {
- fix.session.createReceiver(address);
- fix.session.sync();
- BOOST_FAIL("Expected exception.");
- } catch (const MessagingException& /*e*/) {}
- }
-}
-
-QPID_AUTO_TEST_CASE(testNonExclusiveSubscriber)
-{
- TopicFixture fix;
- std::string address = (boost::format("%1%; {node:{type:topic}, link:{name:'my-subscription', x-declare:{auto-delete:true, exclusive:false}}}") % fix.topic).str();
- Receiver receiver1 = fix.session.createReceiver(address);
- Receiver receiver2 = fix.session.createReceiver(address);
- Sender sender = fix.session.createSender(fix.topic);
- sender.send(Message("one"), true);
- Message in = receiver1.fetch(Duration::IMMEDIATE);
- BOOST_CHECK_EQUAL(in.getContent(), std::string("one"));
- sender.send(Message("two"), true);
- in = receiver2.fetch(Duration::IMMEDIATE);
- BOOST_CHECK_EQUAL(in.getContent(), std::string("two"));
- fix.session.acknowledge();
-}
-
-QPID_AUTO_TEST_CASE(testAcknowledgeUpTo)
-{
- QueueFixture fix;
- Sender sender = fix.session.createSender(fix.queue);
- const uint count(20);
- for (uint i = 0; i < count; ++i) {
- sender.send(Message((boost::format("Message_%1%") % (i+1)).str()));
- }
-
- Session other = fix.connection.createSession();
- Receiver receiver = other.createReceiver(fix.queue);
- std::vector<Message> messages;
- for (uint i = 0; i < count; ++i) {
- Message msg = receiver.fetch();
- BOOST_CHECK_EQUAL(msg.getContent(), (boost::format("Message_%1%") % (i+1)).str());
- messages.push_back(msg);
- }
- const uint batch = 10;
- other.acknowledgeUpTo(messages[batch-1]);//acknowledge first 10 messages only
-
- messages.clear();
- other.sync();
- other.close();
-
- other = fix.connection.createSession();
- receiver = other.createReceiver(fix.queue);
- Message msg;
- for (uint i = 0; i < (count-batch); ++i) {
- msg = receiver.fetch();
- BOOST_CHECK_EQUAL(msg.getContent(), (boost::format("Message_%1%") % (i+1+batch)).str());
- }
- other.acknowledgeUpTo(msg);
- other.sync();
- other.close();
-
- Message m;
- //check queue is empty
- BOOST_CHECK(!fix.session.createReceiver(fix.queue).fetch(m, Duration::IMMEDIATE));
-}
-
QPID_AUTO_TEST_SUITE_END()
}} // namespace qpid::tests
diff --git a/qpid/cpp/src/tests/QueueFlowLimitTest.cpp b/qpid/cpp/src/tests/QueueFlowLimitTest.cpp
index 8a6923fb09..70184095cd 100644
--- a/qpid/cpp/src/tests/QueueFlowLimitTest.cpp
+++ b/qpid/cpp/src/tests/QueueFlowLimitTest.cpp
@@ -75,10 +75,8 @@ public:
QueuedMessage createMessage(uint32_t size)
{
- static uint32_t seqNum;
QueuedMessage msg;
msg.payload = MessageUtils::createMessage();
- msg.position = ++seqNum;
MessageUtils::addContent(msg.payload, std::string (size, 'x'));
return msg;
}
diff --git a/qpid/cpp/src/tests/QueuePolicyTest.cpp b/qpid/cpp/src/tests/QueuePolicyTest.cpp
index 5455105078..f9c058c771 100644
--- a/qpid/cpp/src/tests/QueuePolicyTest.cpp
+++ b/qpid/cpp/src/tests/QueuePolicyTest.cpp
@@ -386,7 +386,6 @@ QPID_AUTO_TEST_CASE(testCapacityConversion)
{
FieldTable args;
args.setString("qpid.max_count", "5");
- args.setString("qpid.flow_stop_count", "0");
ProxySessionFixture f;
std::string q("q");
diff --git a/qpid/cpp/src/tests/QueueTest.cpp b/qpid/cpp/src/tests/QueueTest.cpp
index d94a5cab7f..e4e9897195 100644
--- a/qpid/cpp/src/tests/QueueTest.cpp
+++ b/qpid/cpp/src/tests/QueueTest.cpp
@@ -81,14 +81,15 @@ public:
Message& getMessage() { return *(msg.get()); }
};
-intrusive_ptr<Message> create_message(std::string exchange, std::string routingKey, uint64_t ttl = 0) {
+intrusive_ptr<Message> create_message(std::string exchange, std::string routingKey) {
intrusive_ptr<Message> msg(new Message());
AMQFrame method((MessageTransferBody(ProtocolVersion(), exchange, 0, 0)));
AMQFrame header((AMQHeaderBody()));
msg->getFrames().append(method);
msg->getFrames().append(header);
msg->getFrames().getHeaders()->get<DeliveryProperties>(true)->setRoutingKey(routingKey);
- if (ttl) msg->getFrames().getHeaders()->get<DeliveryProperties>(true)->setTtl(ttl);
+ boost::shared_ptr<AsyncCompletion>dc(new DummyCompletion());
+ msg->setIngressCompletion(dc);
return msg;
}
@@ -304,11 +305,11 @@ QPID_AUTO_TEST_CASE(testSeek){
QueuedMessage qm;
queue->dispatch(consumer);
-
+
BOOST_CHECK_EQUAL(msg3.get(), consumer->last.get());
queue->dispatch(consumer);
queue->dispatch(consumer); // make sure over-run is safe
-
+
}
QPID_AUTO_TEST_CASE(testSearch){
@@ -326,15 +327,15 @@ QPID_AUTO_TEST_CASE(testSearch){
SequenceNumber seq(2);
QueuedMessage qm = queue->find(seq);
-
+
BOOST_CHECK_EQUAL(seq.getValue(), qm.position.getValue());
-
+
queue->acquire(qm);
BOOST_CHECK_EQUAL(queue->getMessageCount(), 2u);
SequenceNumber seq1(3);
QueuedMessage qm1 = queue->find(seq1);
BOOST_CHECK_EQUAL(seq1.getValue(), qm1.position.getValue());
-
+
}
const std::string nullxid = "";
@@ -438,10 +439,10 @@ QPID_AUTO_TEST_CASE(testLVQOrdering){
BOOST_CHECK_EQUAL(key, "qpid.LVQ_key");
- msg1->insertCustomProperty(key,"a");
- msg2->insertCustomProperty(key,"b");
- msg3->insertCustomProperty(key,"c");
- msg4->insertCustomProperty(key,"a");
+ msg1->getProperties<MessageProperties>()->getApplicationHeaders().setString(key,"a");
+ msg2->getProperties<MessageProperties>()->getApplicationHeaders().setString(key,"b");
+ msg3->getProperties<MessageProperties>()->getApplicationHeaders().setString(key,"c");
+ msg4->getProperties<MessageProperties>()->getApplicationHeaders().setString(key,"a");
//enqueue 4 message
queue->deliver(msg1);
@@ -463,9 +464,9 @@ QPID_AUTO_TEST_CASE(testLVQOrdering){
intrusive_ptr<Message> msg5 = create_message("e", "A");
intrusive_ptr<Message> msg6 = create_message("e", "B");
intrusive_ptr<Message> msg7 = create_message("e", "C");
- msg5->insertCustomProperty(key,"a");
- msg6->insertCustomProperty(key,"b");
- msg7->insertCustomProperty(key,"c");
+ msg5->getProperties<MessageProperties>()->getApplicationHeaders().setString(key,"a");
+ msg6->getProperties<MessageProperties>()->getApplicationHeaders().setString(key,"b");
+ msg7->getProperties<MessageProperties>()->getApplicationHeaders().setString(key,"c");
queue->deliver(msg5);
queue->deliver(msg6);
queue->deliver(msg7);
@@ -500,7 +501,7 @@ QPID_AUTO_TEST_CASE(testLVQEmptyKey){
BOOST_CHECK_EQUAL(key, "qpid.LVQ_key");
- msg1->insertCustomProperty(key,"a");
+ msg1->getProperties<MessageProperties>()->getApplicationHeaders().setString(key,"a");
queue->deliver(msg1);
queue->deliver(msg2);
BOOST_CHECK_EQUAL(queue->getMessageCount(), 2u);
@@ -532,12 +533,12 @@ QPID_AUTO_TEST_CASE(testLVQAcquire){
BOOST_CHECK_EQUAL(key, "qpid.LVQ_key");
- msg1->insertCustomProperty(key,"a");
- msg2->insertCustomProperty(key,"b");
- msg3->insertCustomProperty(key,"c");
- msg4->insertCustomProperty(key,"a");
- msg5->insertCustomProperty(key,"b");
- msg6->insertCustomProperty(key,"c");
+ msg1->getProperties<MessageProperties>()->getApplicationHeaders().setString(key,"a");
+ msg2->getProperties<MessageProperties>()->getApplicationHeaders().setString(key,"b");
+ msg3->getProperties<MessageProperties>()->getApplicationHeaders().setString(key,"c");
+ msg4->getProperties<MessageProperties>()->getApplicationHeaders().setString(key,"a");
+ msg5->getProperties<MessageProperties>()->getApplicationHeaders().setString(key,"b");
+ msg6->getProperties<MessageProperties>()->getApplicationHeaders().setString(key,"c");
//enqueue 4 message
queue->deliver(msg1);
@@ -601,8 +602,8 @@ QPID_AUTO_TEST_CASE(testLVQMultiQueue){
args.getLVQKey(key);
BOOST_CHECK_EQUAL(key, "qpid.LVQ_key");
- msg1->insertCustomProperty(key,"a");
- msg2->insertCustomProperty(key,"a");
+ msg1->getProperties<MessageProperties>()->getApplicationHeaders().setString(key,"a");
+ msg2->getProperties<MessageProperties>()->getApplicationHeaders().setString(key,"a");
queue1->deliver(msg1);
queue2->deliver(msg1);
@@ -636,7 +637,7 @@ QPID_AUTO_TEST_CASE(testLVQRecover){
Queue::shared_ptr queue1(new Queue("my-queue", true, &testStore));
intrusive_ptr<Message> received;
- queue1->create(args);
+ queue1->configure(args);
intrusive_ptr<Message> msg1 = create_message("e", "A");
intrusive_ptr<Message> msg2 = create_message("e", "A");
@@ -645,8 +646,8 @@ QPID_AUTO_TEST_CASE(testLVQRecover){
args.getLVQKey(key);
BOOST_CHECK_EQUAL(key, "qpid.LVQ_key");
- msg1->insertCustomProperty(key,"a");
- msg2->insertCustomProperty(key,"a");
+ msg1->getProperties<MessageProperties>()->getApplicationHeaders().setString(key,"a");
+ msg2->getProperties<MessageProperties>()->getApplicationHeaders().setString(key,"a");
// 3
queue1->deliver(msg1);
// 4
@@ -666,7 +667,12 @@ QPID_AUTO_TEST_CASE(testLVQRecover){
void addMessagesToQueue(uint count, Queue& queue, uint oddTtl = 200, uint evenTtl = 0)
{
for (uint i = 0; i < count; i++) {
- intrusive_ptr<Message> m = create_message("exchange", "key", i % 2 ? oddTtl : evenTtl);
+ intrusive_ptr<Message> m = create_message("exchange", "key");
+ if (i % 2) {
+ if (oddTtl) m->getProperties<DeliveryProperties>()->setTtl(oddTtl);
+ } else {
+ if (evenTtl) m->getProperties<DeliveryProperties>()->setTtl(evenTtl);
+ }
m->setTimestamp(new broker::ExpiryPolicy);
queue.deliver(m);
}
@@ -677,7 +683,7 @@ QPID_AUTO_TEST_CASE(testPurgeExpired) {
addMessagesToQueue(10, queue);
BOOST_CHECK_EQUAL(queue.getMessageCount(), 10u);
::usleep(300*1000);
- queue.purgeExpired(0);
+ queue.purgeExpired();
BOOST_CHECK_EQUAL(queue.getMessageCount(), 5u);
}
@@ -688,7 +694,7 @@ QPID_AUTO_TEST_CASE(testQueueCleaner) {
addMessagesToQueue(10, *queue, 200, 400);
BOOST_CHECK_EQUAL(queue->getMessageCount(), 10u);
- QueueCleaner cleaner(queues, &timer);
+ QueueCleaner cleaner(queues, timer);
cleaner.start(100 * qpid::sys::TIME_MSEC);
::usleep(300*1000);
BOOST_CHECK_EQUAL(queue->getMessageCount(), 5u);
@@ -703,9 +709,9 @@ QPID_AUTO_TEST_CASE(testMultiQueueLastNode){
args.setPersistLastNode();
Queue::shared_ptr queue1(new Queue("queue1", true, &testStore ));
- queue1->create(args);
+ queue1->configure(args);
Queue::shared_ptr queue2(new Queue("queue2", true, &testStore ));
- queue2->create(args);
+ queue2->configure(args);
intrusive_ptr<Message> msg1 = create_message("e", "A");
@@ -791,7 +797,7 @@ not requeued to the store.
Queue::shared_ptr queue1(new Queue("my-queue", true, &testStore));
intrusive_ptr<Message> received;
- queue1->create(args);
+ queue1->configure(args);
// check requeue 1
intrusive_ptr<Message> msg1 = create_message("e", "C");
@@ -871,40 +877,28 @@ QPID_AUTO_TEST_CASE(testFlowToDiskBlocking){
intrusive_ptr<Message> msg02 = mkMsg(testStore, std::string(5, 'X')); // transient w/ content
DeliverableMessage dmsg02(msg02);
- {
- ScopedSuppressLogging sl; // suppress expected error messages.
- BOOST_CHECK_THROW(sbtFanout1.route(dmsg02, "", 0), ResourceLimitExceededException);
- }
+ BOOST_CHECK_THROW(sbtFanout1.route(dmsg02, "", 0), ResourceLimitExceededException);
msg02->tryReleaseContent();
BOOST_CHECK_EQUAL(msg02->isContentReleased(), false);
BOOST_CHECK_EQUAL(1u, tq1->getMessageCount());
intrusive_ptr<Message> msg03 = mkMsg(testStore, std::string(5, 'X'), true); // durable w/ content
DeliverableMessage dmsg03(msg03);
- {
- ScopedSuppressLogging sl; // suppress expected error messages.
- BOOST_CHECK_THROW(sbtFanout1.route(dmsg03, "", 0), ResourceLimitExceededException);
- }
+ BOOST_CHECK_THROW(sbtFanout1.route(dmsg03, "", 0), ResourceLimitExceededException);
msg03->tryReleaseContent();
BOOST_CHECK_EQUAL(msg03->isContentReleased(), false);
BOOST_CHECK_EQUAL(1u, tq1->getMessageCount());
intrusive_ptr<Message> msg04 = mkMsg(testStore); // transient no content
DeliverableMessage dmsg04(msg04);
- {
- ScopedSuppressLogging sl; // suppress expected error messages.
- BOOST_CHECK_THROW(sbtFanout1.route(dmsg04, "", 0), ResourceLimitExceededException);
- }
+ BOOST_CHECK_THROW(sbtFanout1.route(dmsg04, "", 0), ResourceLimitExceededException);
msg04->tryReleaseContent();
BOOST_CHECK_EQUAL(msg04->isContentReleased(), false);
BOOST_CHECK_EQUAL(1u, tq1->getMessageCount());
intrusive_ptr<Message> msg05 = mkMsg(testStore, "", true); // durable no content
DeliverableMessage dmsg05(msg05);
- {
- ScopedSuppressLogging sl; // suppress expected error messages.
- BOOST_CHECK_THROW(sbtFanout1.route(dmsg05, "", 0), ResourceLimitExceededException);
- }
+ BOOST_CHECK_THROW(sbtFanout1.route(dmsg05, "", 0), ResourceLimitExceededException);
msg05->tryReleaseContent();
BOOST_CHECK_EQUAL(msg05->isContentReleased(), false);
BOOST_CHECK_EQUAL(1u, tq1->getMessageCount());
diff --git a/qpid/cpp/src/tests/SessionState.cpp b/qpid/cpp/src/tests/SessionState.cpp
index 3be9bb0cbc..157cabfb63 100644
--- a/qpid/cpp/src/tests/SessionState.cpp
+++ b/qpid/cpp/src/tests/SessionState.cpp
@@ -43,7 +43,7 @@ using namespace qpid::framing;
// Apply f to [begin, end) and accumulate the result
template <class Iter, class T, class F>
T applyAccumulate(Iter begin, Iter end, T seed, const F& f) {
- return std::accumulate(begin, end, seed, boost::bind(std::plus<T>(), _1, boost::bind(f, _2)));
+ return std::accumulate(begin, end, seed, bind(std::plus<T>(), _1, bind(f, _2)));
}
// Create a frame with a one-char string.
@@ -105,8 +105,8 @@ size_t transferN(qpid::SessionState& s, string content) {
char last = content[content.size()-1];
content.resize(content.size()-1);
size += applyAccumulate(content.begin(), content.end(), 0,
- boost::bind(&send, boost::ref(s),
- boost::bind(contentFrameChar, _1, false)));
+ bind(&send, ref(s),
+ bind(contentFrameChar, _1, false)));
size += send(s, contentFrameChar(last, true));
}
return size;
@@ -115,7 +115,7 @@ size_t transferN(qpid::SessionState& s, string content) {
// Send multiple transfers with single-byte content.
size_t transfers(qpid::SessionState& s, string content) {
return applyAccumulate(content.begin(), content.end(), 0,
- boost::bind(transfer1Char, boost::ref(s), _1));
+ bind(transfer1Char, ref(s), _1));
}
size_t contentFrameSize(size_t n=1) { return AMQFrame(( AMQContentBody())).encodedSize() + n; }
diff --git a/qpid/cpp/src/tests/SocketProxy.h b/qpid/cpp/src/tests/SocketProxy.h
index d195f11aa9..0c6f39d62e 100644
--- a/qpid/cpp/src/tests/SocketProxy.h
+++ b/qpid/cpp/src/tests/SocketProxy.h
@@ -35,8 +35,6 @@
#include "qpid/sys/Mutex.h"
#include "qpid/log/Statement.h"
-#include <boost/lexical_cast.hpp>
-
namespace qpid {
namespace tests {
@@ -64,7 +62,7 @@ class SocketProxy : private qpid::sys::Runnable
: closed(false), joined(true),
port(listener.listen()), dropClient(), dropServer()
{
- client.connect(host, boost::lexical_cast<std::string>(connectPort));
+ client.connect(host, connectPort);
joined = false;
thread = qpid::sys::Thread(static_cast<qpid::sys::Runnable*>(this));
}
diff --git a/qpid/cpp/src/tests/TimerTest.cpp b/qpid/cpp/src/tests/TimerTest.cpp
index 6a0a196f4e..7df94164e0 100644
--- a/qpid/cpp/src/tests/TimerTest.cpp
+++ b/qpid/cpp/src/tests/TimerTest.cpp
@@ -77,10 +77,8 @@ class TestTask : public TimerTask
BOOST_CHECK(fired);
BOOST_CHECK_EQUAL(expected_position, position);
Duration actual(start, end);
-#ifdef _MSC_VER
+#ifdef _WIN32
uint64_t difference = _abs64(expected - actual);
-#elif defined(_WIN32)
- uint64_t difference = labs(expected - actual);
#else
uint64_t difference = abs(expected - actual);
#endif
diff --git a/qpid/cpp/src/tests/TxPublishTest.cpp b/qpid/cpp/src/tests/TxPublishTest.cpp
index 152581e4ba..210abf0a5b 100644
--- a/qpid/cpp/src/tests/TxPublishTest.cpp
+++ b/qpid/cpp/src/tests/TxPublishTest.cpp
@@ -50,9 +50,10 @@ struct TxPublishTest
TxPublishTest() :
queue1(new Queue("queue1", false, &store, 0)),
queue2(new Queue("queue2", false, &store, 0)),
- msg(MessageUtils::createMessage("exchange", "routing_key", true)),
+ msg(MessageUtils::createMessage("exchange", "routing_key", false, "id")),
op(msg)
{
+ msg->getProperties<DeliveryProperties>()->setDeliveryMode(PERSISTENT);
op.deliverTo(queue1);
op.deliverTo(queue2);
}
diff --git a/qpid/cpp/src/tests/Variant.cpp b/qpid/cpp/src/tests/Variant.cpp
index 40f1c0cf75..b4188f524b 100644
--- a/qpid/cpp/src/tests/Variant.cpp
+++ b/qpid/cpp/src/tests/Variant.cpp
@@ -86,64 +86,6 @@ QPID_AUTO_TEST_CASE(testConversions)
BOOST_CHECK_THROW(value.asBool(), InvalidConversion);
}
-QPID_AUTO_TEST_CASE(testConversionsFromString)
-{
- Variant value;
- value = "5";
- BOOST_CHECK_EQUAL(5, value.asInt16());
- BOOST_CHECK_EQUAL(5u, value.asUint16());
-
- value = "-5";
- BOOST_CHECK_EQUAL(-5, value.asInt16());
- BOOST_CHECK_THROW(value.asUint16(), InvalidConversion);
-
- value = "18446744073709551615";
- BOOST_CHECK_EQUAL(18446744073709551615ull, value.asUint64());
- BOOST_CHECK_THROW(value.asInt64(), InvalidConversion);
-
- value = "9223372036854775808";
- BOOST_CHECK_EQUAL(9223372036854775808ull, value.asUint64());
- BOOST_CHECK_THROW(value.asInt64(), InvalidConversion);
-
- value = "-9223372036854775809";
- BOOST_CHECK_THROW(value.asUint64(), InvalidConversion);
- BOOST_CHECK_THROW(value.asInt64(), InvalidConversion);
-
- value = "2147483648";
- BOOST_CHECK_EQUAL(2147483648ul, value.asUint32());
- BOOST_CHECK_THROW(value.asInt32(), InvalidConversion);
-
- value = "-2147483649";
- BOOST_CHECK_THROW(value.asUint32(), InvalidConversion);
- BOOST_CHECK_THROW(value.asInt32(), InvalidConversion);
-
- value = "32768";
- BOOST_CHECK_EQUAL(32768u, value.asUint16());
- BOOST_CHECK_THROW(value.asInt16(), InvalidConversion);
-
- value = "-32769";
- BOOST_CHECK_THROW(value.asUint16(), InvalidConversion);
- BOOST_CHECK_THROW(value.asInt16(), InvalidConversion);
-
- value = "-2.5";
- BOOST_CHECK_EQUAL(-2.5, value.asFloat());
-
- value = "-0.875432e10";
- BOOST_CHECK_EQUAL(-0.875432e10, value.asDouble());
-
- value = "-0";
- BOOST_CHECK_EQUAL(0, value.asInt16());
- BOOST_CHECK_EQUAL(0u, value.asUint16());
-
- value = "-000";
- BOOST_CHECK_EQUAL(0, value.asInt16());
- BOOST_CHECK_EQUAL(0u, value.asUint16());
-
- value = "-0010";
- BOOST_CHECK_EQUAL(-10, value.asInt16());
- BOOST_CHECK_THROW(value.asUint16(), InvalidConversion);
-}
-
QPID_AUTO_TEST_CASE(testSizeConversionsUint)
{
Variant value;
diff --git a/qpid/cpp/src/tests/acl.py b/qpid/cpp/src/tests/acl.py
index 5e9a150d8f..2d6a5b489d 100755
--- a/qpid/cpp/src/tests/acl.py
+++ b/qpid/cpp/src/tests/acl.py
@@ -26,11 +26,10 @@ from qpid.datatypes import uuid4
from qpid.testlib import TestBase010
from qmf.console import Session
from qpid.datatypes import Message
-import qpid.messaging
class ACLFile:
- def __init__(self, policy='data_dir/policy.acl'):
- self.f = open(policy,'w')
+ def __init__(self):
+ self.f = open('data_dir/policy.acl','w');
def write(self,line):
self.f.write(line)
@@ -51,24 +50,14 @@ class ACLTests(TestBase010):
acl = self.qmf.getObjects(_class="acl")[0]
return acl.reloadACLFile()
- def get_acl_file(self):
- return ACLFile(self.config.defines.get("policy-file", "data_dir/policy.acl"))
-
def setUp(self):
- aclf = self.get_acl_file()
+ aclf = ACLFile()
aclf.write('acl allow all all\n')
aclf.close()
TestBase010.setUp(self)
self.startQmf()
self.reload_acl()
-
- def tearDown(self):
- aclf = self.get_acl_file()
- aclf.write('acl allow all all\n')
- aclf.close()
- self.reload_acl()
- TestBase010.tearDown(self)
-
+
#=====================================
# ACL general tests
#=====================================
@@ -77,7 +66,7 @@ class ACLTests(TestBase010):
"""
Test the deny all mode
"""
- aclf = self.get_acl_file()
+ aclf = ACLFile()
aclf.write('acl allow anonymous all all\n')
aclf.write('acl allow bob@QPID create queue\n')
aclf.write('acl deny all all')
@@ -105,7 +94,7 @@ class ACLTests(TestBase010):
"""
Test the allow all mode
"""
- aclf = self.get_acl_file()
+ aclf = ACLFile()
aclf.write('acl deny bob@QPID bind exchange\n')
aclf.write('acl allow all all')
aclf.close()
@@ -137,7 +126,7 @@ class ACLTests(TestBase010):
"""
Test empty groups
"""
- aclf = self.get_acl_file()
+ aclf = ACLFile()
aclf.write('acl group\n')
aclf.write('acl group admins bob@QPID joe@QPID\n')
aclf.write('acl allow all all')
@@ -151,7 +140,7 @@ class ACLTests(TestBase010):
"""
Test illegal acl formats
"""
- aclf = self.get_acl_file()
+ aclf = ACLFile()
aclf.write('acl group admins bob@QPID joe@QPID\n')
aclf.write('acl allow all all')
aclf.close()
@@ -165,7 +154,7 @@ class ACLTests(TestBase010):
Test illegal extension lines
"""
- aclf = self.get_acl_file()
+ aclf = ACLFile()
aclf.write('group admins bob@QPID \n')
aclf.write(' \ \n')
aclf.write('joe@QPID \n')
@@ -183,7 +172,7 @@ class ACLTests(TestBase010):
"""
Test proper extention lines
"""
- aclf = self.get_acl_file()
+ aclf = ACLFile()
aclf.write('group test1 joe@EXAMPLE.com \\ \n') # should be allowed
aclf.write(' jack@EXAMPLE.com \\ \n') # should be allowed
aclf.write('jill@TEST.COM \\ \n') # should be allowed
@@ -200,7 +189,7 @@ class ACLTests(TestBase010):
Test a user defined without a realm
Ex. group admin rajith
"""
- aclf = self.get_acl_file()
+ aclf = ACLFile()
aclf.write('group admin bob\n') # shouldn't be allowed
aclf.write('acl deny admin bind exchange\n')
aclf.write('acl allow all all')
@@ -215,7 +204,7 @@ class ACLTests(TestBase010):
Test a user defined without a realm
Ex. group admin rajith
"""
- aclf = self.get_acl_file()
+ aclf = ACLFile()
aclf.write('group test1 joe@EXAMPLE.com\n') # should be allowed
aclf.write('group test2 jack_123-jill@EXAMPLE.com\n') # should be allowed
aclf.write('group test4 host/somemachine.example.com@EXAMPLE.COM\n') # should be allowed
@@ -226,7 +215,7 @@ class ACLTests(TestBase010):
if (result.text.find("ACL format error",0,len(result.text)) != -1):
self.fail(result)
- aclf = self.get_acl_file()
+ aclf = ACLFile()
aclf.write('group test1 joe$H@EXAMPLE.com\n') # shouldn't be allowed
aclf.write('acl allow all all')
aclf.close()
@@ -244,7 +233,7 @@ class ACLTests(TestBase010):
Test illegal queue policy
"""
- aclf = self.get_acl_file()
+ aclf = ACLFile()
aclf.write('acl deny bob@QPID create queue name=q2 exclusive=true policytype=ding\n')
aclf.write('acl allow all all')
aclf.close()
@@ -260,7 +249,7 @@ class ACLTests(TestBase010):
Test illegal queue policy
"""
- aclf = self.get_acl_file()
+ aclf = ACLFile()
aclf.write('acl deny bob@QPID create queue name=q2 maxqueuesize=-1\n')
aclf.write('acl allow all all')
aclf.close()
@@ -271,7 +260,7 @@ class ACLTests(TestBase010):
if (result.text != expected):
self.fail(result)
- aclf = self.get_acl_file()
+ aclf = ACLFile()
aclf.write('acl deny bob@QPID create queue name=q2 maxqueuesize=9223372036854775808\n')
aclf.write('acl allow all all')
aclf.close()
@@ -288,7 +277,7 @@ class ACLTests(TestBase010):
Test illegal queue policy
"""
- aclf = self.get_acl_file()
+ aclf = ACLFile()
aclf.write('acl deny bob@QPID create queue name=q2 maxqueuecount=-1\n')
aclf.write('acl allow all all')
aclf.close()
@@ -299,7 +288,7 @@ class ACLTests(TestBase010):
if (result.text != expected):
self.fail(result)
- aclf = self.get_acl_file()
+ aclf = ACLFile()
aclf.write('acl deny bob@QPID create queue name=q2 maxqueuecount=9223372036854775808\n')
aclf.write('acl allow all all')
aclf.close()
@@ -319,7 +308,7 @@ class ACLTests(TestBase010):
"""
Test cases for queue acl in allow mode
"""
- aclf = self.get_acl_file()
+ aclf = ACLFile()
aclf.write('acl deny bob@QPID create queue name=q1 durable=true passive=true\n')
aclf.write('acl deny bob@QPID create queue name=q2 exclusive=true policytype=ring\n')
aclf.write('acl deny bob@QPID access queue name=q3\n')
@@ -422,7 +411,7 @@ class ACLTests(TestBase010):
"""
Test cases for queue acl in deny mode
"""
- aclf = self.get_acl_file()
+ aclf = ACLFile()
aclf.write('acl allow bob@QPID create queue name=q1 durable=true passive=true\n')
aclf.write('acl allow bob@QPID create queue name=q2 exclusive=true policytype=ring\n')
aclf.write('acl allow bob@QPID access queue name=q3\n')
@@ -545,7 +534,7 @@ class ACLTests(TestBase010):
"""
Test cases for exchange acl in allow mode
"""
- aclf = self.get_acl_file()
+ aclf = ACLFile()
aclf.write('acl deny bob@QPID create exchange name=testEx durable=true passive=true\n')
aclf.write('acl deny bob@QPID create exchange name=ex1 type=direct\n')
aclf.write('acl deny bob@QPID access exchange name=myEx queuename=q1 routingkey=rk1.*\n')
@@ -676,7 +665,7 @@ class ACLTests(TestBase010):
"""
Test cases for exchange acl in deny mode
"""
- aclf = self.get_acl_file()
+ aclf = ACLFile()
aclf.write('acl allow bob@QPID create exchange name=myEx durable=true passive=false\n')
aclf.write('acl allow bob@QPID bind exchange name=amq.topic queuename=bar routingkey=foo.*\n')
aclf.write('acl allow bob@QPID unbind exchange name=amq.topic queuename=bar routingkey=foo.*\n')
@@ -783,52 +772,6 @@ class ACLTests(TestBase010):
if (403 == e.args[0].error_code):
self.fail("ACL should allow exchange delete request for myEx");
- def test_create_and_delete_exchange_via_qmf(self):
- """
- Test acl is enforced when creating/deleting via QMF
- methods. Note that in order to be able to send the QMF methods
- and receive the responses a significant amount of permissions
- need to be enabled (TODO: can the set below be narrowed down
- at all?)
- """
- aclf = self.get_acl_file()
- aclf.write('acl allow bob@QPID create exchange\n')
- aclf.write('acl allow admin@QPID delete exchange\n')
- aclf.write('acl allow all access exchange\n')
- aclf.write('acl allow all bind exchange\n')
- aclf.write('acl allow all create queue\n')
- aclf.write('acl allow all access queue\n')
- aclf.write('acl allow all delete queue\n')
- aclf.write('acl allow all consume queue\n')
- aclf.write('acl allow all access method\n')
- aclf.write('acl deny all all')
- aclf.close()
-
- result = self.reload_acl()
- if (result.text.find("format error",0,len(result.text)) != -1):
- self.fail(result)
-
- bob = BrokerAdmin(self.config.broker, "bob", "bob")
- bob.create_exchange("my-exchange") #should pass
- #cleanup by deleting exchange
- try:
- bob.delete_exchange("my-exchange") #should fail
- self.fail("ACL should deny exchange delete request for my-exchange");
- except Exception, e:
- self.assertEqual(7,e.args[0]["error_code"])
- assert e.args[0]["error_text"].find("unauthorized-access") == 0
- admin = BrokerAdmin(self.config.broker, "admin", "admin")
- admin.delete_exchange("my-exchange") #should pass
-
- anonymous = BrokerAdmin(self.config.broker)
- try:
- anonymous.create_exchange("another-exchange") #should fail
- self.fail("ACL should deny exchange create request for another-exchange");
- except Exception, e:
- self.assertEqual(7,e.args[0]["error_code"])
- assert e.args[0]["error_text"].find("unauthorized-access") == 0
-
-
#=====================================
# ACL consume tests
#=====================================
@@ -837,7 +780,7 @@ class ACLTests(TestBase010):
"""
Test cases for consume in allow mode
"""
- aclf = self.get_acl_file()
+ aclf = ACLFile()
aclf.write('acl deny bob@QPID consume queue name=q1\n')
aclf.write('acl deny bob@QPID consume queue name=q2\n')
aclf.write('acl allow all all')
@@ -883,7 +826,7 @@ class ACLTests(TestBase010):
"""
Test cases for consume in allow mode
"""
- aclf = self.get_acl_file()
+ aclf = ACLFile()
aclf.write('acl allow bob@QPID consume queue name=q1\n')
aclf.write('acl allow bob@QPID consume queue name=q2\n')
aclf.write('acl allow bob@QPID create queue\n')
@@ -929,7 +872,7 @@ class ACLTests(TestBase010):
"""
Test various publish acl
"""
- aclf = self.get_acl_file()
+ aclf = ACLFile()
aclf.write('acl deny bob@QPID publish exchange name=amq.direct routingkey=rk1\n')
aclf.write('acl deny bob@QPID publish exchange name=amq.topic\n')
aclf.write('acl deny bob@QPID publish exchange name=myEx routingkey=rk2\n')
@@ -978,7 +921,7 @@ class ACLTests(TestBase010):
"""
Test various publish acl
"""
- aclf = self.get_acl_file()
+ aclf = ACLFile()
aclf.write('acl allow bob@QPID publish exchange name=amq.direct routingkey=rk1\n')
aclf.write('acl allow bob@QPID publish exchange name=amq.topic\n')
aclf.write('acl allow bob@QPID publish exchange name=myEx routingkey=rk2\n')
@@ -1029,49 +972,3 @@ class ACLTests(TestBase010):
except qpid.session.SessionException, e:
if (403 == e.args[0].error_code):
self.fail("ACL should allow message transfer to exchange amq.direct with routing key rk1");
-
-class BrokerAdmin:
- def __init__(self, broker, username=None, password=None):
- self.connection = qpid.messaging.Connection(broker)
- if username:
- self.connection.username = username
- self.connection.password = password
- self.connection.sasl_mechanisms = "PLAIN"
- self.connection.open()
- self.session = self.connection.session()
- self.sender = self.session.sender("qmf.default.direct/broker")
- self.reply_to = "responses-#; {create:always}"
- self.receiver = self.session.receiver(self.reply_to)
-
- def invoke(self, method, arguments):
- content = {
- "_object_id": {"_object_name": "org.apache.qpid.broker:broker:amqp-broker"},
- "_method_name": method,
- "_arguments": arguments
- }
- request = qpid.messaging.Message(reply_to=self.reply_to, content=content)
- request.properties["x-amqp-0-10.app-id"] = "qmf2"
- request.properties["qmf.opcode"] = "_method_request"
- self.sender.send(request)
- response = self.receiver.fetch()
- self.session.acknowledge()
- if response.properties['x-amqp-0-10.app-id'] == 'qmf2':
- if response.properties['qmf.opcode'] == '_method_response':
- return response.content['_arguments']
- elif response.properties['qmf.opcode'] == '_exception':
- raise Exception(response.content['_values'])
- else: raise Exception("Invalid response received, unexpected opcode: %s" % response.properties['qmf.opcode'])
- else: raise Exception("Invalid response received, not a qmfv2 method: %s" % response.properties['x-amqp-0-10.app-id'])
- def create_exchange(self, name, exchange_type=None, options={}):
- properties = options
- if exchange_type: properties["exchange_type"] = exchange_type
- self.invoke("create", {"type": "exchange", "name":name, "properties":properties})
-
- def create_queue(self, name, properties={}):
- self.invoke("create", {"type": "queue", "name":name, "properties":properties})
-
- def delete_exchange(self, name):
- self.invoke("delete", {"type": "exchange", "name":name})
-
- def delete_queue(self, name):
- self.invoke("delete", {"type": "queue", "name":name})
diff --git a/qpid/cpp/src/tests/allhosts b/qpid/cpp/src/tests/allhosts
index 4b4b943156..e43571aed4 100755
--- a/qpid/cpp/src/tests/allhosts
+++ b/qpid/cpp/src/tests/allhosts
@@ -29,12 +29,11 @@ Options:
-s SECONDS sleep between starting commands.
-q don't print banner lines for each host.
-o SUFFIX log output of each command to <host>.SUFFIX
- -X passed to ssh - forward X connection.
"
exit 1
}
-while getopts "tl:bs:dqo:X" opt; do
+while getopts "tl:bs:dqo:" opt; do
case $opt in
l) SSHOPTS="-l$OPTARG $SSHOPTS" ;;
t) SSHOPTS="-t $SSHOPTS" ;;
@@ -43,7 +42,6 @@ while getopts "tl:bs:dqo:X" opt; do
s) SLEEP="sleep $OPTARG" ;;
q) NOBANNER=1 ;;
o) SUFFIX=$OPTARG ;;
- X) SSHOPTS="-X $SSHOPTS" ;;
*) usage;;
esac
done
diff --git a/qpid/cpp/src/tests/brokertest.py b/qpid/cpp/src/tests/brokertest.py
index fd972b4394..6e771bf5d6 100644
--- a/qpid/cpp/src/tests/brokertest.py
+++ b/qpid/cpp/src/tests/brokertest.py
@@ -62,6 +62,24 @@ def is_running(pid):
class BadProcessStatus(Exception):
pass
+class ExceptionWrapper:
+ """Proxy object that adds a message to exceptions raised"""
+ def __init__(self, obj, msg):
+ self.obj = obj
+ self.msg = msg
+
+ def __getattr__(self, name):
+ func = getattr(self.obj, name)
+ if type(func) != callable:
+ return func
+ return lambda *args, **kwargs: self._wrap(func, args, kwargs)
+
+ def _wrap(self, func, args, kwargs):
+ try:
+ return func(*args, **kwargs)
+ except Exception, e:
+ raise Exception("%s: %s" %(self.msg, str(e)))
+
def error_line(filename, n=1):
"""Get the last n line(s) of filename for error messages"""
result = []
@@ -71,8 +89,7 @@ def error_line(filename, n=1):
for l in f:
if len(result) == n: result.pop(0)
result.append(" "+l)
- finally:
- f.close()
+ finally: f.close()
except: return ""
return ":\n" + "".join(result)
@@ -80,90 +97,111 @@ def retry(function, timeout=10, delay=.01):
"""Call function until it returns True or timeout expires.
Double the delay for each retry. Return True if function
returns true, False if timeout expires."""
- deadline = time.time() + timeout
while not function():
- remaining = deadline - time.time()
- if remaining <= 0: return False
- delay = min(delay, remaining)
+ if delay > timeout: delay = timeout
time.sleep(delay)
+ timeout -= delay
+ if timeout <= 0: return False
delay *= 2
return True
-class AtomicCounter:
- def __init__(self):
- self.count = 0
- self.lock = Lock()
-
- def next(self):
- self.lock.acquire();
- ret = self.count
- self.count += 1
- self.lock.release();
- return ret
-
-_popen_id = AtomicCounter() # Popen identifier for use in output file names.
-
-# Constants for file descriptor arguments to Popen
-FILE = "FILE" # Write to file named after process
-PIPE = subprocess.PIPE
-
class Popen(subprocess.Popen):
"""
Can set and verify expectation of process status at end of test.
Dumps command line, stdout, stderr to data dir for debugging.
"""
- def __init__(self, cmd, expect=EXPECT_EXIT_OK, stdin=None, stdout=FILE, stderr=FILE):
- """Run cmd (should be a list of program and arguments)
+ class DrainThread(Thread):
+ """Thread to drain a file object and write the data to a file."""
+ def __init__(self, infile, outname):
+ Thread.__init__(self)
+ self.infile, self.outname = infile, outname
+ self.outfile = None
+
+ def run(self):
+ try:
+ for line in self.infile:
+ if self.outfile is None:
+ self.outfile = open(self.outname, "w")
+ self.outfile.write(line)
+ finally:
+ self.infile.close()
+ if self.outfile is not None: self.outfile.close()
+
+ class OutStream(ExceptionWrapper):
+ """Wrapper for output streams, handles exceptions & draining output"""
+ def __init__(self, infile, outfile, msg):
+ ExceptionWrapper.__init__(self, infile, msg)
+ self.infile, self.outfile = infile, outfile
+ self.thread = None
+
+ def drain(self):
+ if self.thread is None:
+ self.thread = Popen.DrainThread(self.infile, self.outfile)
+ self.thread.start()
+
+ def outfile(self, ext): return "%s.%s" % (self.pname, ext)
+
+ def __init__(self, cmd, expect=EXPECT_EXIT_OK, drain=True):
+ """Run cmd (should be a list of arguments)
expect - if set verify expectation at end of test.
- stdout, stderr - can have the same values as for subprocess.Popen as well as
- FILE (the default) which means write to a file named after the process.
- stdin - like subprocess.Popen but defauts to PIPE
+ drain - if true (default) drain stdout/stderr to files.
"""
self._clean = False
self._clean_lock = Lock()
assert find_exe(cmd[0]), "executable not found: "+cmd[0]
if type(cmd) is type(""): cmd = [cmd] # Make it a list.
self.cmd = [ str(x) for x in cmd ]
+ self.returncode = None
self.expect = expect
- self.id = _popen_id.next()
- self.pname = "%s-%d" % (os.path.split(self.cmd[0])[1], self.id)
- if stdout == FILE: stdout = open(self.outfile("out"), "w")
- if stderr == FILE: stderr = open(self.outfile("err"), "w")
try:
- subprocess.Popen.__init__(self, self.cmd, bufsize=0, executable=None,
- stdin=stdin, stdout=stdout, stderr=stderr,
- close_fds=True)
- except ValueError: # Windows can't do close_fds
- subprocess.Popen.__init__(self, self.cmd, bufsize=0, executable=None,
- stdin=stdin, stdout=stdout, stderr=stderr)
-
+ subprocess.Popen.__init__(self, self.cmd, 0, None, subprocess.PIPE, subprocess.PIPE, subprocess.PIPE, close_fds=True)
+ except ValueError: # Windows can't do close_fds
+ subprocess.Popen.__init__(self, self.cmd, 0, None, subprocess.PIPE, subprocess.PIPE, subprocess.PIPE)
+ self.pname = "%s-%d" % (os.path.split(self.cmd[0])[1], self.pid)
+ msg = "Process %s" % self.pname
+ self.stdin = ExceptionWrapper(self.stdin, msg)
+ self.stdout = Popen.OutStream(self.stdout, self.outfile("out"), msg)
+ self.stderr = Popen.OutStream(self.stderr, self.outfile("err"), msg)
f = open(self.outfile("cmd"), "w")
- try: f.write("%s\n%d"%(self.cmd_str(), self.pid))
+ try: f.write(self.cmd_str())
finally: f.close()
log.debug("Started process %s: %s" % (self.pname, " ".join(self.cmd)))
+ if drain: self.drain()
- def __str__(self): return "Popen<%s>"%(self.pname)
+ def __str__(self): return "Popen<%s>"%(self.pname)
- def outfile(self, ext): return "%s.%s" % (self.pname, ext)
+ def drain(self):
+ """Start threads to drain stdout/err"""
+ self.stdout.drain()
+ self.stderr.drain()
+
+ def _cleanup(self):
+ """Close pipes to sub-process"""
+ self._clean_lock.acquire()
+ try:
+ if self._clean: return
+ self._clean = True
+ self.stdin.close()
+ self.drain() # Drain output pipes.
+ self.stdout.thread.join() # Drain thread closes pipe.
+ self.stderr.thread.join()
+ finally: self._clean_lock.release()
def unexpected(self,msg):
err = error_line(self.outfile("err")) or error_line(self.outfile("out"))
raise BadProcessStatus("%s %s%s" % (self.pname, msg, err))
-
+
def stop(self): # Clean up at end of test.
try:
if self.expect == EXPECT_UNKNOWN:
try: self.kill() # Just make sure its dead
except: pass
elif self.expect == EXPECT_RUNNING:
- if self.poll() != None:
- self.unexpected("expected running, exit code %d" % self.returncode)
- else:
- try:
- self.kill()
- except Exception,e:
- self.unexpected("exception from kill: %s" % str(e))
+ try:
+ self.kill()
+ except:
+ self.unexpected("expected running, exit code %d" % self.wait())
else:
retry(lambda: self.poll() is not None)
if self.returncode is None: # Still haven't stopped
@@ -175,21 +213,40 @@ class Popen(subprocess.Popen):
self.unexpected("expected error")
finally:
self.wait() # Clean up the process.
-
+
def communicate(self, input=None):
- ret = subprocess.Popen.communicate(self, input)
- self.cleanup()
- return ret
+ if input:
+ self.stdin.write(input)
+ self.stdin.close()
+ outerr = (self.stdout.read(), self.stderr.read())
+ self.wait()
+ return outerr
- def is_running(self): return self.poll() is None
+ def is_running(self):
+ return self.poll() is None
def assert_running(self):
if not self.is_running(): self.unexpected("Exit code %d" % self.returncode)
+ def poll(self, _deadstate=None): # _deadstate required by base class in python 2.4
+ if self.returncode is None:
+ # Pass _deadstate only if it has been set, there is no _deadstate
+ # parameter in Python 2.6
+ if _deadstate is None: ret = subprocess.Popen.poll(self)
+ else: ret = subprocess.Popen.poll(self, _deadstate)
+
+ if (ret != -1):
+ self.returncode = ret
+ self._cleanup()
+ return self.returncode
+
def wait(self):
- ret = subprocess.Popen.wait(self)
- self._cleanup()
- return ret
+ if self.returncode is None:
+ self.drain()
+ try: self.returncode = subprocess.Popen.wait(self)
+ except OSError,e: raise OSError("Wait failed %s: %s"%(self.pname, e))
+ self._cleanup()
+ return self.returncode
def terminate(self):
try: subprocess.Popen.terminate(self)
@@ -198,8 +255,7 @@ class Popen(subprocess.Popen):
os.kill( self.pid , signal.SIGTERM)
except AttributeError: # no os.kill, using taskkill.. (Windows only)
os.popen('TASKKILL /PID ' +str(self.pid) + ' /F')
- self._cleanup()
-
+
def kill(self):
try: subprocess.Popen.kill(self)
except AttributeError: # No terminate method
@@ -207,20 +263,6 @@ class Popen(subprocess.Popen):
os.kill( self.pid , signal.SIGKILL)
except AttributeError: # no os.kill, using taskkill.. (Windows only)
os.popen('TASKKILL /PID ' +str(self.pid) + ' /F')
- self._cleanup()
-
- def _cleanup(self):
- """Clean up after a dead process"""
- self._clean_lock.acquire()
- if not self._clean:
- self._clean = True
- try: self.stdin.close()
- except: pass
- try: self.stdout.close()
- except: pass
- try: self.stderr.close()
- except: pass
- self._clean_lock.release()
def cmd_str(self): return " ".join([str(s) for s in self.cmd])
@@ -247,11 +289,11 @@ class Broker(Popen):
while (os.path.exists(self.log)):
self.log = "%s-%d.log" % (self.name, i)
i += 1
-
+
def get_log(self):
return os.path.abspath(self.log)
- def __init__(self, test, args=[], name=None, expect=EXPECT_RUNNING, port=0, log_level=None, wait=None, show_cmd=False):
+ def __init__(self, test, args=[], name=None, expect=EXPECT_RUNNING, port=0, log_level=None, wait=None):
"""Start a broker daemon. name determines the data-dir and log
file names."""
@@ -277,11 +319,10 @@ class Broker(Popen):
cmd += ["--log-to-file", self.log]
cmd += ["--log-to-stderr=no"]
if log_level != None:
- cmd += ["--log-enable=%s" % log_level]
+ cmd += ["--log-enable=%s" % log_level]
self.datadir = self.name
cmd += ["--data-dir", self.datadir]
- if show_cmd: print cmd
- Popen.__init__(self, cmd, expect, stdout=PIPE)
+ Popen.__init__(self, cmd, expect, drain=False)
test.cleanup_stop(self)
self._host = "127.0.0.1"
log.debug("Started broker %s (%s, %s)" % (self.name, self.pname, self.log))
@@ -321,7 +362,7 @@ class Broker(Popen):
s = c.session(str(qpid.datatypes.uuid4()))
s.queue_declare(queue=queue)
c.close()
-
+
def _prep_sender(self, queue, durable, xprops):
s = queue + "; {create:always, node:{durable:" + str(durable)
if xprops != None: s += ", x-declare:{" + xprops + "}"
@@ -365,14 +406,13 @@ class Broker(Popen):
def log_ready(self):
"""Return true if the log file exists and contains a broker ready message"""
- if not self._log_ready:
- self._log_ready = find_in_file("notice Broker running", self.log)
- return self._log_ready
+ if self._log_ready: return True
+ self._log_ready = find_in_file("notice Broker running", self.log)
def ready(self, **kwargs):
"""Wait till broker is ready to serve clients"""
# First make sure the broker is listening by checking the log.
- if not retry(self.log_ready, timeout=60):
+ if not retry(self.log_ready, timeout=30):
raise Exception(
"Timed out waiting for broker %s%s"%(self.name, error_line(self.log,5)))
# Create a connection and a session. For a cluster broker this will
@@ -381,27 +421,23 @@ class Broker(Popen):
c = self.connect(**kwargs)
try: c.session()
finally: c.close()
- except Exception,e: raise RethrownException(
- "Broker %s not responding: (%s)%s"%(self.name,e,error_line(self.log, 5)))
+ except: raise RethrownException(
+ "Broker %s failed ready test%s"%(self.name,error_line(self.log, 5)))
def store_state(self):
- f = open(os.path.join(self.datadir, "cluster", "store.status"))
- try: uuids = f.readlines()
- finally: f.close()
+ uuids = open(os.path.join(self.datadir, "cluster", "store.status")).readlines()
null_uuid="00000000-0000-0000-0000-000000000000\n"
if len(uuids) < 2: return "unknown" # we looked while the file was being updated.
if uuids[0] == null_uuid: return "empty"
if uuids[1] == null_uuid: return "dirty"
return "clean"
-
+
class Cluster:
"""A cluster of brokers in a test."""
- # Client connection options for use in failover tests.
- CONNECTION_OPTIONS = "reconnect:true,reconnect-timeout:10,reconnect-urls-replace:true"
_cluster_count = 0
- def __init__(self, test, count=0, args=[], expect=EXPECT_RUNNING, wait=True, show_cmd=False):
+ def __init__(self, test, count=0, args=[], expect=EXPECT_RUNNING, wait=True):
self.test = test
self._brokers=[]
self.name = "cluster%d" % Cluster._cluster_count
@@ -412,16 +448,16 @@ class Cluster:
self.args += [ "--log-enable=info+", "--log-enable=debug+:cluster"]
assert BrokerTest.cluster_lib, "Cannot locate cluster plug-in"
self.args += [ "--load-module", BrokerTest.cluster_lib ]
- self.start_n(count, expect=expect, wait=wait, show_cmd=show_cmd)
+ self.start_n(count, expect=expect, wait=wait)
- def start(self, name=None, expect=EXPECT_RUNNING, wait=True, args=[], port=0, show_cmd=False):
+ def start(self, name=None, expect=EXPECT_RUNNING, wait=True, args=[], port=0):
"""Add a broker to the cluster. Returns the index of the new broker."""
if not name: name="%s-%d" % (self.name, len(self._brokers))
- self._brokers.append(self.test.broker(self.args+args, name, expect, wait, port=port, show_cmd=show_cmd))
+ self._brokers.append(self.test.broker(self.args+args, name, expect, wait, port=port))
return self._brokers[-1]
- def start_n(self, count, expect=EXPECT_RUNNING, wait=True, args=[], show_cmd=False):
- for i in range(count): self.start(expect=expect, wait=wait, args=args, show_cmd=show_cmd)
+ def start_n(self, count, expect=EXPECT_RUNNING, wait=True, args=[]):
+ for i in range(count): self.start(expect=expect, wait=wait, args=args)
# Behave like a list of brokers.
def __len__(self): return len(self._brokers)
@@ -450,7 +486,7 @@ class BrokerTest(TestCase):
rootdir = os.getcwd()
def configure(self, config): self.config=config
-
+
def setUp(self):
outdir = self.config.defines.get("OUTDIR") or "brokertest.tmp"
self.dir = os.path.join(self.rootdir, outdir, self.id())
@@ -471,51 +507,41 @@ class BrokerTest(TestCase):
"""Call thing.stop at end of test"""
self.stopem.append(stopable)
- def popen(self, cmd, expect=EXPECT_EXIT_OK, stdin=None, stdout=FILE, stderr=FILE):
+ def popen(self, cmd, expect=EXPECT_EXIT_OK, drain=True):
"""Start a process that will be killed at end of test, in the test dir."""
os.chdir(self.dir)
- p = Popen(cmd, expect, stdin=stdin, stdout=stdout, stderr=stderr)
+ p = Popen(cmd, expect, drain)
self.cleanup_stop(p)
return p
- def broker(self, args=[], name=None, expect=EXPECT_RUNNING, wait=True, port=0, log_level=None, show_cmd=False):
+ def broker(self, args=[], name=None, expect=EXPECT_RUNNING, wait=True, port=0, log_level=None):
"""Create and return a broker ready for use"""
- b = Broker(self, args=args, name=name, expect=expect, port=port, log_level=log_level, show_cmd=show_cmd)
+ b = Broker(self, args=args, name=name, expect=expect, port=port, log_level=log_level)
if (wait):
try: b.ready()
except Exception, e:
raise RethrownException("Failed to start broker %s(%s): %s" % (b.name, b.log, e))
return b
- def cluster(self, count=0, args=[], expect=EXPECT_RUNNING, wait=True, show_cmd=False):
+ def cluster(self, count=0, args=[], expect=EXPECT_RUNNING, wait=True):
"""Create and return a cluster ready for use"""
- cluster = Cluster(self, count, args, expect=expect, wait=wait, show_cmd=show_cmd)
+ cluster = Cluster(self, count, args, expect=expect, wait=wait)
return cluster
- def browse(self, session, queue, timeout=0):
+ def assert_browse(self, session, queue, expect_contents, timeout=0):
"""Assert that the contents of messages on queue (as retrieved
using session and timeout) exactly match the strings in
expect_contents"""
+
r = session.receiver("%s;{mode:browse}"%(queue))
+ actual_contents = []
try:
- contents = []
- try:
- while True: contents.append(r.fetch(timeout=timeout).content)
- except messaging.Empty: pass
- finally: pass #FIXME aconway 2011-04-14: r.close()
- return contents
-
- def assert_browse(self, session, queue, expect_contents, timeout=0):
- """Assert that the contents of messages on queue (as retrieved
- using session and timeout) exactly match the strings in
- expect_contents"""
- actual_contents = self.browse(session, queue, timeout)
+ for c in expect_contents: actual_contents.append(r.fetch(timeout=timeout).content)
+ while True: actual_contents.append(r.fetch(timeout=0).content) # Check for extra messages.
+ except messaging.Empty: pass
+ r.close()
self.assertEqual(expect_contents, actual_contents)
-def join(thread, timeout=10):
- thread.join(timeout)
- if thread.isAlive(): raise Exception("Timed out joining thread %s"%thread)
-
class RethrownException(Exception):
"""Captures the stack trace of the current exception to be thrown later"""
def __init__(self, msg=""):
@@ -533,16 +559,15 @@ class StoppableThread(Thread):
def stop(self):
self.stopped = True
- join(self)
+ self.join()
if self.error: raise self.error
-
+
class NumberedSender(Thread):
"""
Thread to run a sender client and send numbered messages until stopped.
"""
- def __init__(self, broker, max_depth=None, queue="test-queue",
- connection_options=Cluster.CONNECTION_OPTIONS):
+ def __init__(self, broker, max_depth=None, queue="test-queue"):
"""
max_depth: enable flow control, ensure sent - received <= max_depth.
Requires self.notify_received(n) to be called each time messages are received.
@@ -553,11 +578,9 @@ class NumberedSender(Thread):
"--broker", "localhost:%s"%broker.port(),
"--address", "%s;{create:always}"%queue,
"--failover-updates",
- "--connection-options", "{%s}"%(connection_options),
"--content-stdin"
],
- expect=EXPECT_RUNNING,
- stdin=PIPE)
+ expect=EXPECT_RUNNING)
self.condition = Condition()
self.max = max_depth
self.received = 0
@@ -572,7 +595,6 @@ class NumberedSender(Thread):
try:
self.sent = 0
while not self.stopped:
- self.sender.assert_running()
if self.max:
self.condition.acquire()
while not self.stopped and self.sent - self.received > self.max:
@@ -595,17 +617,16 @@ class NumberedSender(Thread):
self.stopped = True
self.condition.notify()
finally: self.condition.release()
- join(self)
+ self.join()
self.write_message(-1) # end-of-messages marker.
if self.error: raise self.error
-
+
class NumberedReceiver(Thread):
"""
Thread to run a receiver client and verify it receives
sequentially numbered messages.
"""
- def __init__(self, broker, sender = None, queue="test-queue",
- connection_options=Cluster.CONNECTION_OPTIONS):
+ def __init__(self, broker, sender = None, queue="test-queue"):
"""
sender: enable flow control. Call sender.received(n) for each message received.
"""
@@ -616,24 +637,22 @@ class NumberedReceiver(Thread):
"--broker", "localhost:%s"%broker.port(),
"--address", "%s;{create:always}"%queue,
"--failover-updates",
- "--connection-options", "{%s}"%(connection_options),
"--forever"
],
expect=EXPECT_RUNNING,
- stdout=PIPE)
+ drain=False)
self.lock = Lock()
self.error = None
self.sender = sender
- self.received = 0
def read_message(self):
return int(self.receiver.stdout.readline())
-
+
def run(self):
try:
+ self.received = 0
m = self.read_message()
while m != -1:
- self.receiver.assert_running()
assert(m <= self.received) # Check for missing messages
if (m == self.received): # Ignore duplicates
self.received += 1
@@ -645,7 +664,7 @@ class NumberedReceiver(Thread):
def stop(self):
"""Returns when termination message is received"""
- join(self)
+ self.join()
if self.error: raise self.error
class ErrorGenerator(StoppableThread):
@@ -660,7 +679,7 @@ class ErrorGenerator(StoppableThread):
self.broker=broker
broker.test.cleanup_stop(self)
self.start()
-
+
def run(self):
c = self.broker.connect_old()
try:
diff --git a/qpid/cpp/src/tests/cli_tests.py b/qpid/cpp/src/tests/cli_tests.py
index 6c75927461..deef03279d 100755
--- a/qpid/cpp/src/tests/cli_tests.py
+++ b/qpid/cpp/src/tests/cli_tests.py
@@ -365,26 +365,6 @@ class CliTests(TestBase010):
self.assertEqual(queue._altExchange_.name, altName)
self.assertEqual(found, True)
- def test_qpid_config_list_queues_arguments(self):
- """
- Test to verify that when the type of a policy limit is
- actually a string (though still a valid value), it does not
- upset qpid-config
- """
- self.startQmf();
- qmf = self.qmf
-
- names = ["queue_capacity%s" % (i) for i in range(1, 6)]
- for name in names:
- self.session.queue_declare(queue=name, exclusive=True,
- arguments={'qpid.max_count' : str(i), 'qpid.max_size': '100'})
-
- output = os.popen(self.qpid_config_command(" queues")).readlines()
- queues = [line.split()[0] for line in output[2:len(output)]] #ignore first two lines (header)
-
- for name in names:
- assert name in queues, "%s not in %s" % (name, queues)
-
def test_qpid_route(self):
self.startQmf();
qmf = self.qmf
@@ -425,7 +405,7 @@ class CliTests(TestBase010):
qmf = self.qmf
ret = self.qpid_route_api("dynamic add "
- + " --client-sasl-mechanism PLAIN "
+ + " --sasl-mechanism PLAIN "
+ "guest/guest@localhost:"+str(self.broker.port) + " "
+ str(self.remote_host())+":"+str(self.remote_port()) + " "
+"amq.direct")
@@ -444,7 +424,7 @@ class CliTests(TestBase010):
qmf = self.qmf
ret = self.qpid_route_api("dynamic add "
- + " --client-sasl-mechanism PLAIN "
+ + " --sasl-mechanism PLAIN "
+ "localhost:"+str(self.broker.port) + " "
+ str(self.remote_host())+":"+str(self.remote_port()) + " "
+"amq.direct")
diff --git a/qpid/cpp/src/tests/cluster_test_logs.py b/qpid/cpp/src/tests/cluster_test_logs.py
index a0ce8fb9c3..1fa9014d11 100755
--- a/qpid/cpp/src/tests/cluster_test_logs.py
+++ b/qpid/cpp/src/tests/cluster_test_logs.py
@@ -54,17 +54,15 @@ def filter_log(log):
'caught up',
'active for links|Passivating links|Activating links',
'info Connection.* connected to', # UpdateClient connection
- 'warning Connection \\[[-0-9.: ]+\\] closed', # UpdateClient connection
+ 'warning Connection [\d+ [0-9.:]+] closed', # UpdateClient connection
'warning Broker closed connection: 200, OK',
'task late',
'task overran',
'warning CLOSING .* unsent data',
'Inter-broker link ',
- 'Running in a cluster, marking store',
- 'debug Sending keepalive signal to watchdog', # Watchdog timer thread
- 'last broker standing joined by 1 replicas, updating queue policies.',
- 'Connection .* timed out: closing' # heartbeat connection close
+ 'Running in a cluster, marking store'
])
+ skip_re = re.compile(skip)
# Regex to match a UUID
uuid='\w\w\w\w\w\w\w\w-\w\w\w\w-\w\w\w\w-\w\w\w\w-\w\w\w\w\w\w\w\w\w\w\w\w'
# Substitutions to remove expected differences
@@ -82,13 +80,6 @@ def filter_log(log):
(r' map={.*_object_name:([^,}]*)[,}].*', r' \1'), # V2 map - just keep name
(r'\d+-\d+-\d+--\d+', 'X-X-X--X'), # V1 Object IDs
]
- # Substitutions to mask known issue: durable test shows inconsistent "changed stats for com.redhat.rhm.store:journal" messages.
- skip += '|Changed V[12] statistics com.redhat.rhm.store:journal'
- subs += [(r'to=console.obj.1.0.com.redhat.rhm.store.journal props=\d+ stats=\d+',
- 'to=console.obj.1.0.com.redhat.rhm.store.journal props=NN stats=NN')]
-
- skip_re = re.compile(skip)
- subs = [(re.compile(pattern), subst) for pattern, subst in subs]
for l in open(log):
if skip_re.search(l): continue
for pattern,subst in subs: l = re.sub(pattern,subst,l)
diff --git a/qpid/cpp/src/tests/cluster_tests.py b/qpid/cpp/src/tests/cluster_tests.py
index 807e9508c3..3e13a3ce8a 100755
--- a/qpid/cpp/src/tests/cluster_tests.py
+++ b/qpid/cpp/src/tests/cluster_tests.py
@@ -18,12 +18,11 @@
# under the License.
#
-import os, signal, sys, time, imp, re, subprocess, glob, random, logging
-import cluster_test_logs
+import os, signal, sys, time, imp, re, subprocess, glob, cluster_test_logs
from qpid import datatypes, messaging
from brokertest import *
from qpid.harness import Skipped
-from qpid.messaging import Message, Empty, Disposition, REJECTED, util
+from qpid.messaging import Message, Empty
from threading import Thread, Lock, Condition
from logging import getLogger
from itertools import chain
@@ -97,15 +96,9 @@ class ShortTests(BrokerTest):
destination="amq.direct",
message=qpid.datatypes.Message(props, "content"))
- # Try message with TTL and differnet headers/properties
- cluster[0].send_message("q", Message(durable=True, ttl=100000))
- cluster[0].send_message("q", Message(durable=True, properties={}, ttl=100000))
- cluster[0].send_message("q", Message(durable=True, properties={"x":10}, ttl=100000))
-
# Now update a new member and compare their dumps.
cluster.start(args=["--test-store-dump", "updatee.dump"])
assert readfile("direct.dump") == readfile("updatee.dump")
-
os.remove("direct.dump")
os.remove("updatee.dump")
@@ -253,6 +246,25 @@ acl allow all all
session1 = cluster[1].connect().session()
for q in queues: self.assert_browse(session1, "q1", ["foo"])
+ def test_dr_no_message(self):
+ """Regression test for https://bugzilla.redhat.com/show_bug.cgi?id=655141
+ Joining broker crashes with 'error deliveryRecord no update message'
+ """
+
+ cluster = self.cluster(1)
+ session0 = cluster[0].connect().session()
+ s = session0.sender("q1;{create:always}")
+ s.send(Message("a", ttl=0.05), sync=False)
+ s.send(Message("b", ttl=0.05), sync=False)
+ r1 = session0.receiver("q1")
+ self.assertEqual("a", r1.fetch(timeout=0).content)
+ r2 = session0.receiver("q1;{mode:browse}")
+ self.assertEqual("b", r2.fetch(timeout=0).content)
+ # Leave messages un-acknowledged, let the expire, then start new broker.
+ time.sleep(.1)
+ cluster.start()
+ self.assertRaises(Empty, cluster[1].connect().session().receiver("q1").fetch,0)
+
def test_route_update(self):
"""Regression test for https://issues.apache.org/jira/browse/QPID-2982
Links and bridges associated with routes were not replicated on update.
@@ -260,7 +272,6 @@ acl allow all all
client was attached.
"""
args=["--mgmt-pub-interval=1","--log-enable=trace+:management"]
- # First broker will be killed.
cluster0 = self.cluster(1, args=args)
cluster1 = self.cluster(1, args=args)
assert 0 == subprocess.call(
@@ -290,47 +301,9 @@ acl allow all all
qpid_tool.wait()
scanner.join()
assert scanner.found
- # Regression test for https://issues.apache.org/jira/browse/QPID-3235
- # Inconsistent stats when changing elder.
-
- # Force a change of elder
- cluster0.start()
- cluster0[0].expect=EXPECT_EXIT_FAIL # About to die.
- cluster0[0].kill()
- time.sleep(2) # Allow a management interval to pass.
# Verify logs are consistent
cluster_test_logs.verify_logs()
- def test_redelivered(self):
- """Verify that redelivered flag is set correctly on replayed messages"""
- cluster = self.cluster(2, expect=EXPECT_EXIT_FAIL)
- url = "amqp:tcp:%s,tcp:%s" % (cluster[0].host_port(), cluster[1].host_port())
- queue = "my-queue"
- cluster[0].declare_queue(queue)
- self.sender = self.popen(
- ["qpid-send",
- "--broker", url,
- "--address", queue,
- "--sequence=true",
- "--send-eos=1",
- "--messages=100000",
- "--connection-options={%s}"%(Cluster.CONNECTION_OPTIONS)
- ])
- self.receiver = self.popen(
- ["qpid-receive",
- "--broker", url,
- "--address", queue,
- "--ignore-duplicates",
- "--check-redelivered",
- "--connection-options={%s}"%(Cluster.CONNECTION_OPTIONS),
- "--forever"
- ])
- time.sleep(1)#give sender enough time to have some messages to replay
- cluster[0].kill()
- self.sender.wait()
- self.receiver.wait()
- cluster[1].kill()
-
class BlockedSend(Thread):
"""Send a message, send is expected to block.
Verify that it does block (for a given timeout), then allow
@@ -343,7 +316,7 @@ acl allow all all
Thread.__init__(self)
def run(self):
try:
- self.sender.send(self.msg, sync=True)
+ self.sender.send(self.msg)
self.condition.acquire()
try:
self.blocked = False
@@ -375,12 +348,11 @@ acl allow all all
ssn0 = brokers.first().connect().session()
s0 = ssn0.sender("flq; {create:always, node:{type:queue, x-declare:{arguments:{'qpid.flow_stop_count':5, 'qpid.flow_resume_count':3}}}}")
brokers.first().startQmf()
- q1 = [q for q in brokers.first().qmf_session.getObjects(_class="queue") if q.name == "flq"][0]
- oid = q1.getObjectId()
- self.assertEqual(q1.name, "flq")
- self.assertEqual(q1.arguments, {u'qpid.flow_stop_count': 5L, u'qpid.flow_resume_count': 3L})
- assert not q1.flowStopped
- self.assertEqual(q1.flowStoppedCount, 0)
+ q = [q for q in brokers.first().qmf_session.getObjects(_class="queue") if q.name == "flq"][0]
+ oid = q.getObjectId()
+ self.assertEqual(q.name, "flq")
+ self.assertEqual(q.arguments, {u'qpid.flow_stop_count': 5L, u'qpid.flow_resume_count': 3L})
+ assert not q.flowStopped
# fill the queue on one broker until flow control is active
for x in range(5): s0.send(Message(str(x)))
@@ -388,20 +360,18 @@ acl allow all all
sender.start() # Tests that sender does block
# Verify the broker queue goes into a flowStopped state
deadline = time.time() + 1
- while not q1.flowStopped and time.time() < deadline: q1.update()
- assert q1.flowStopped
- self.assertEqual(q1.flowStoppedCount, 1)
+ while not q.flowStopped and time.time() < deadline: q.update()
+ assert q.flowStopped
sender.assert_blocked() # Still blocked
# Now verify the both brokers in cluster have same configuration
brokers.second().startQmf()
qs = brokers.second().qmf_session.getObjects(_objectId=oid)
self.assertEqual(len(qs), 1)
- q2 = qs[0]
- self.assertEqual(q2.name, "flq")
- self.assertEqual(q2.arguments, {u'qpid.flow_stop_count': 5L, u'qpid.flow_resume_count': 3L})
- assert q2.flowStopped
- self.assertEqual(q2.flowStoppedCount, 1)
+ q = qs[0]
+ self.assertEqual(q.name, "flq")
+ self.assertEqual(q.arguments, {u'qpid.flow_stop_count': 5L, u'qpid.flow_resume_count': 3L})
+ assert q.flowStopped
# now drain the queue using a session to the other broker
ssn1 = brokers.second().connect().session()
@@ -411,12 +381,6 @@ acl allow all all
ssn1.acknowledge()
sender.wait() # Verify no longer blocked.
- # and re-verify state of queue on both brokers
- q1.update()
- assert not q1.flowStopped
- q2.update()
- assert not q2.flowStopped
-
ssn0.connection.close()
ssn1.connection.close()
cluster_test_logs.verify_logs()
@@ -430,6 +394,7 @@ acl allow all all
self.queue_flowlimit_test(Brokers())
def test_queue_flowlimit_cluster(self):
+ return # TODO aconway 2011-02-18: disabled till fixed, QPID-2935
cluster = self.cluster(2)
class Brokers:
def first(self): return cluster[0]
@@ -437,6 +402,7 @@ acl allow all all
self.queue_flowlimit_test(Brokers())
def test_queue_flowlimit_cluster_join(self):
+ return # TODO aconway 2011-02-18: disabled till fixed, QPID-2935
cluster = self.cluster(1)
class Brokers:
def first(self): return cluster[0]
@@ -445,274 +411,6 @@ acl allow all all
return cluster[1]
self.queue_flowlimit_test(Brokers())
- def test_queue_flowlimit_replicate(self):
- """ Verify that a queue which is in flow control BUT has drained BELOW
- the flow control 'stop' threshold, is correctly replicated when a new
- broker is added to the cluster.
- """
-
- class AsyncSender(Thread):
- """Send a fixed number of msgs from a sender in a separate thread
- so it may block without blocking the test.
- """
- def __init__(self, broker, address, count=1, size=4):
- Thread.__init__(self)
- self.daemon = True
- self.broker = broker
- self.queue = address
- self.count = count
- self.size = size
- self.done = False
-
- def run(self):
- self.sender = subprocess.Popen(["qpid-send",
- "--capacity=1",
- "--content-size=%s" % self.size,
- "--messages=%s" % self.count,
- "--failover-updates",
- "--connection-options={%s}"%(Cluster.CONNECTION_OPTIONS),
- "--address=%s" % self.queue,
- "--broker=%s" % self.broker.host_port()])
- self.sender.wait()
- self.done = True
-
- cluster = self.cluster(2)
- # create a queue with rather draconian flow control settings
- ssn0 = cluster[0].connect().session()
- s0 = ssn0.sender("flq; {create:always, node:{type:queue, x-declare:{arguments:{'qpid.flow_stop_count':100, 'qpid.flow_resume_count':20}}}}")
-
- # fire off the sending thread to broker[0], and wait until the queue
- # hits flow control on broker[1]
- sender = AsyncSender(cluster[0], "flq", count=110);
- sender.start();
-
- cluster[1].startQmf()
- q_obj = [q for q in cluster[1].qmf_session.getObjects(_class="queue") if q.name == "flq"][0]
- deadline = time.time() + 10
- while not q_obj.flowStopped and time.time() < deadline:
- q_obj.update()
- assert q_obj.flowStopped
- assert not sender.done
- assert q_obj.msgDepth < 110
-
- # Now drain enough messages on broker[1] to drop below the flow stop
- # threshold, but not relieve flow control...
- receiver = subprocess.Popen(["qpid-receive",
- "--messages=15",
- "--timeout=1",
- "--print-content=no",
- "--failover-updates",
- "--connection-options={%s}"%(Cluster.CONNECTION_OPTIONS),
- "--ack-frequency=1",
- "--address=flq",
- "--broker=%s" % cluster[1].host_port()])
- receiver.wait()
- q_obj.update()
- assert q_obj.flowStopped
- assert not sender.done
- current_depth = q_obj.msgDepth
-
- # add a new broker to the cluster, and verify that the queue is in flow
- # control on that broker
- cluster.start()
- cluster[2].startQmf()
- q_obj = [q for q in cluster[2].qmf_session.getObjects(_class="queue") if q.name == "flq"][0]
- assert q_obj.flowStopped
- assert q_obj.msgDepth == current_depth
-
- # now drain the queue on broker[2], and verify that the sender becomes
- # unblocked
- receiver = subprocess.Popen(["qpid-receive",
- "--messages=95",
- "--timeout=1",
- "--print-content=no",
- "--failover-updates",
- "--connection-options={%s}"%(Cluster.CONNECTION_OPTIONS),
- "--ack-frequency=1",
- "--address=flq",
- "--broker=%s" % cluster[2].host_port()])
- receiver.wait()
- q_obj.update()
- assert not q_obj.flowStopped
- self.assertEqual(q_obj.msgDepth, 0)
-
- # verify that the sender has become unblocked
- sender.join(timeout=5)
- assert not sender.isAlive()
- assert sender.done
-
- def test_blocked_queue_delete(self):
- """Verify that producers which are blocked on a queue due to flow
- control are unblocked when that queue is deleted.
- """
-
- cluster = self.cluster(2)
- cluster[0].startQmf()
- cluster[1].startQmf()
-
- # configure a queue with a specific flow limit on first broker
- ssn0 = cluster[0].connect().session()
- s0 = ssn0.sender("flq; {create:always, node:{type:queue, x-declare:{arguments:{'qpid.flow_stop_count':5, 'qpid.flow_resume_count':3}}}}")
- q1 = [q for q in cluster[0].qmf_session.getObjects(_class="queue") if q.name == "flq"][0]
- oid = q1.getObjectId()
- self.assertEqual(q1.name, "flq")
- self.assertEqual(q1.arguments, {u'qpid.flow_stop_count': 5L, u'qpid.flow_resume_count': 3L})
- assert not q1.flowStopped
- self.assertEqual(q1.flowStoppedCount, 0)
-
- # fill the queue on one broker until flow control is active
- for x in range(5): s0.send(Message(str(x)))
- sender = ShortTests.BlockedSend(s0, Message(str(6)))
- sender.start() # Tests that sender does block
- # Verify the broker queue goes into a flowStopped state
- deadline = time.time() + 1
- while not q1.flowStopped and time.time() < deadline: q1.update()
- assert q1.flowStopped
- self.assertEqual(q1.flowStoppedCount, 1)
- sender.assert_blocked() # Still blocked
-
- # Now verify the both brokers in cluster have same configuration
- qs = cluster[1].qmf_session.getObjects(_objectId=oid)
- self.assertEqual(len(qs), 1)
- q2 = qs[0]
- self.assertEqual(q2.name, "flq")
- self.assertEqual(q2.arguments, {u'qpid.flow_stop_count': 5L, u'qpid.flow_resume_count': 3L})
- assert q2.flowStopped
- self.assertEqual(q2.flowStoppedCount, 1)
-
- # now delete the blocked queue from other broker
- ssn1 = cluster[1].connect().session()
- self.evaluate_address(ssn1, "flq;{delete:always}")
- sender.wait() # Verify no longer blocked.
-
- ssn0.connection.close()
- ssn1.connection.close()
- cluster_test_logs.verify_logs()
-
-
- def test_alternate_exchange_update(self):
- """Verify that alternate-exchange on exchanges and queues is propagated to new members of a cluster. """
- cluster = self.cluster(1)
- s0 = cluster[0].connect().session()
- # create alt queue bound to amq.fanout exchange, will be destination for alternate exchanges
- self.evaluate_address(s0, "alt;{create:always,node:{x-bindings:[{exchange:'amq.fanout',queue:alt}]}}")
- # create direct exchange ex with alternate-exchange amq.fanout and no queues bound
- self.evaluate_address(s0, "ex;{create:always,node:{type:topic, x-declare:{type:'direct', alternate-exchange:'amq.fanout'}}}")
- # create queue q with alternate-exchange amq.fanout
- self.evaluate_address(s0, "q;{create:always,node:{type:queue, x-declare:{alternate-exchange:'amq.fanout'}}}")
-
- def verify(broker):
- s = broker.connect().session()
- # Verify unmatched message goes to ex's alternate.
- s.sender("ex").send("foo")
- self.assertEqual("foo", s.receiver("alt").fetch(timeout=0).content)
- # Verify rejected message goes to q's alternate.
- s.sender("q").send("bar")
- msg = s.receiver("q").fetch(timeout=0)
- self.assertEqual("bar", msg.content)
- s.acknowledge(msg, Disposition(REJECTED)) # Reject the message
- self.assertEqual("bar", s.receiver("alt").fetch(timeout=0).content)
-
- verify(cluster[0])
- cluster.start()
- verify(cluster[1])
-
- def test_binding_order(self):
- """Regression test for binding order inconsistency in cluster"""
- cluster = self.cluster(1)
- c0 = cluster[0].connect()
- s0 = c0.session()
- # Declare multiple queues bound to same key on amq.topic
- def declare(q,max=0):
- if max: declare = 'x-declare:{arguments:{"qpid.max_count":%d, "qpid.flow_stop_count":0}}'%max
- else: declare = 'x-declare:{}'
- bind='x-bindings:[{queue:%s,key:key,exchange:"amq.topic"}]'%(q)
- s0.sender("%s;{create:always,node:{%s,%s}}" % (q,declare,bind))
- declare('d',max=4) # Only one with a limit
- for q in ['c', 'b','a']: declare(q)
- # Add a cluster member, send enough messages to exceed the max count
- cluster.start()
- try:
- s = s0.sender('amq.topic/key')
- for m in xrange(1,6): s.send(Message(str(m)))
- self.fail("Expected capacity exceeded exception")
- except messaging.exceptions.TargetCapacityExceeded: pass
- c1 = cluster[1].connect()
- s1 = c1.session()
- s0 = c0.session() # Old session s0 is broken by exception.
- # Verify queue contents are consistent.
- for q in ['a','b','c','d']:
- self.assertEqual(self.browse(s0, q), self.browse(s1, q))
- # Verify queue contents are "best effort"
- for q in ['a','b','c']: self.assert_browse(s1,q,[str(n) for n in xrange(1,6)])
- self.assert_browse(s1,'d',[str(n) for n in xrange(1,5)])
-
- def test_deleted_exchange(self):
- """QPID-3215: cached exchange reference can cause cluster inconsistencies
- if exchange is deleted/recreated
- Verify stand-alone case
- """
- cluster = self.cluster()
- # Verify we do not route message via an exchange that has been destroyed.
- cluster.start()
- s0 = cluster[0].connect().session()
- self.evaluate_address(s0, "ex;{create:always,node:{type:topic}}")
- self.evaluate_address(s0, "q;{create:always,node:{x-bindings:[{exchange:'ex',queue:q,key:foo}]}}")
- send0 = s0.sender("ex/foo")
- send0.send("foo")
- self.assert_browse(s0, "q", ["foo"])
- self.evaluate_address(s0, "ex;{delete:always}")
- try:
- send0.send("bar") # Should fail, exchange is deleted.
- self.fail("Expected not-found exception")
- except qpid.messaging.NotFound: pass
- self.assert_browse(cluster[0].connect().session(), "q", ["foo"])
-
- def test_deleted_exchange_inconsistent(self):
- """QPID-3215: cached exchange reference can cause cluster inconsistencies
- if exchange is deleted/recreated
-
- Verify cluster inconsistency.
- """
- cluster = self.cluster()
- cluster.start()
- s0 = cluster[0].connect().session()
- self.evaluate_address(s0, "ex;{create:always,node:{type:topic}}")
- self.evaluate_address(s0, "q;{create:always,node:{x-bindings:[{exchange:'ex',queue:q,key:foo}]}}")
- send0 = s0.sender("ex/foo")
- send0.send("foo")
- self.assert_browse(s0, "q", ["foo"])
-
- cluster.start()
- s1 = cluster[1].connect().session()
- self.evaluate_address(s0, "ex;{delete:always}")
- try:
- send0.send("bar")
- self.fail("Expected not-found exception")
- except qpid.messaging.NotFound: pass
-
- self.assert_browse(s1, "q", ["foo"])
-
-
- def test_ttl_consistent(self):
- """Ensure we don't get inconsistent errors with message that have TTL very close together"""
- messages = [ Message(str(i), ttl=i/1000.0) for i in xrange(0,1000)]
- messages.append(Message("x"))
- cluster = self.cluster(2)
- sender = cluster[0].connect().session().sender("q;{create:always}")
-
- def fetch(b):
- receiver = b.connect().session().receiver("q;{create:always}")
- while receiver.fetch().content != "x": pass
-
- for m in messages: sender.send(m, sync=False)
- for m in messages: sender.send(m, sync=False)
- fetch(cluster[0])
- fetch(cluster[1])
- for m in messages: sender.send(m, sync=False)
- cluster.start()
- fetch(cluster[2])
-
class LongTests(BrokerTest):
"""Tests that can run for a long time if -DDURATION=<minutes> is set"""
def duration(self):
@@ -725,28 +423,22 @@ class LongTests(BrokerTest):
# Original cluster will all be killed so expect exit with failure
cluster = self.cluster(3, expect=EXPECT_EXIT_FAIL)
- for b in cluster: b.ready() # Wait for brokers to be ready
for b in cluster: ErrorGenerator(b)
# Start sender and receiver threads
cluster[0].declare_queue("test-queue")
- sender = NumberedSender(cluster[0], 1000) # Max queue depth
- receiver = NumberedReceiver(cluster[0], sender)
+ sender = NumberedSender(cluster[1], 1000) # Max queue depth
+ receiver = NumberedReceiver(cluster[2], sender)
receiver.start()
sender.start()
- # Wait for sender & receiver to get up and running
- retry(lambda: receiver.received > 0)
# Kill original brokers, start new ones for the duration.
endtime = time.time() + self.duration()
i = 0
while time.time() < endtime:
- sender.sender.assert_running()
- receiver.receiver.assert_running()
cluster[i].kill()
i += 1
b = cluster.start(expect=EXPECT_EXIT_FAIL)
- for b in cluster[i:]: b.ready()
ErrorGenerator(b)
time.sleep(5)
sender.stop()
@@ -777,24 +469,24 @@ class LongTests(BrokerTest):
if self.stopped: break
self.process = self.broker.test.popen(
self.cmd, expect=EXPECT_UNKNOWN)
- finally:
- self.lock.release()
- try:
- exit = self.process.wait()
+ finally: self.lock.release()
+ try: exit = self.process.wait()
except OSError, e:
- # Process may already have been killed by self.stop()
- break
+ # Seems to be a race in wait(), it throws
+ # "no such process" during test shutdown.
+ # Doesn't indicate a test error, ignore.
+ return
except Exception, e:
self.process.unexpected(
"client of %s: %s"%(self.broker.name, e))
self.lock.acquire()
try:
+ # Quit and ignore errors if stopped or expecting failure.
if self.stopped: break
if exit != 0:
self.process.unexpected(
"client of %s exit code %s"%(self.broker.name, exit))
- finally:
- self.lock.release()
+ finally: self.lock.release()
except Exception, e:
self.error = RethrownException("Error in ClientLoop.run")
@@ -816,7 +508,7 @@ class LongTests(BrokerTest):
args += ["--log-enable=trace+:management"]
# Use store if present.
if BrokerTest.store_lib: args +=["--load-module", BrokerTest.store_lib]
- cluster = self.cluster(3, args, expect=EXPECT_EXIT_FAIL) # brokers will be killed
+ cluster = self.cluster(3, args)
clients = [] # Per-broker list of clients that only connect to one broker.
mclients = [] # Management clients that connect to every broker in the cluster.
@@ -825,12 +517,10 @@ class LongTests(BrokerTest):
"""Start ordinary clients for a broker."""
cmds=[
["qpid-tool", "localhost:%s"%(broker.port())],
- ["qpid-perftest", "--count=5000", "--durable=yes",
+ ["qpid-perftest", "--count", 50000,
"--base-name", str(qpid.datatypes.uuid4()), "--port", broker.port()],
- ["qpid-txtest", "--queue-base-name", "tx-%s"%str(qpid.datatypes.uuid4()),
- "--port", broker.port()],
- ["qpid-queue-stats", "-a", "localhost:%s" %(broker.port())]
- ]
+ ["qpid-queue-stats", "-a", "localhost:%s" %(broker.port())],
+ ["testagent", "localhost", str(broker.port())] ]
clients.append([ClientLoop(broker, cmd) for cmd in cmds])
def start_mclients(broker):
@@ -839,8 +529,7 @@ class LongTests(BrokerTest):
mclients.append(ClientLoop(broker, cmd))
endtime = time.time() + self.duration()
- # For long duration, first run is a quarter of the duration.
- runtime = min(5.0, self.duration() / 3.0)
+ runtime = self.duration() / 4 # First run is longer, use quarter of duration.
alive = 0 # First live cluster member
for i in range(len(cluster)): start_clients(cluster[i])
start_mclients(cluster[alive])
@@ -851,7 +540,7 @@ class LongTests(BrokerTest):
for b in cluster[alive:]: b.ready() # Check if a broker crashed.
# Kill the first broker, expect the clients to fail.
b = cluster[alive]
- b.ready()
+ b.expect = EXPECT_EXIT_FAIL
b.kill()
# Stop the brokers clients and all the mclients.
for c in clients[alive] + mclients:
@@ -861,179 +550,26 @@ class LongTests(BrokerTest):
mclients = []
# Start another broker and clients
alive += 1
- cluster.start(expect=EXPECT_EXIT_FAIL)
- cluster[-1].ready() # Wait till its ready
+ cluster.start()
start_clients(cluster[-1])
start_mclients(cluster[alive])
for c in chain(mclients, *clients):
c.stop()
- for b in cluster[alive:]:
- b.ready() # Verify still alive
- b.kill()
+
# Verify that logs are consistent
cluster_test_logs.verify_logs()
def test_management_qmf2(self):
self.test_management(args=["--mgmt-qmf2=yes"])
- def test_connect_consistent(self):
+ def test_connect_consistent(self): # FIXME aconway 2011-01-18:
args=["--mgmt-pub-interval=1","--log-enable=trace+:management"]
cluster = self.cluster(2, args=args)
end = time.time() + self.duration()
while (time.time() < end): # Get a management interval
for i in xrange(1000): cluster[0].connect().close()
- cluster_test_logs.verify_logs()
-
- def test_flowlimit_failover(self):
- """Test fail-over during continuous send-receive with flow control
- active.
- """
-
- # Original cluster will all be killed so expect exit with failure
- cluster = self.cluster(3, expect=EXPECT_EXIT_FAIL)
- for b in cluster: b.ready() # Wait for brokers to be ready
-
- # create a queue with rather draconian flow control settings
- ssn0 = cluster[0].connect().session()
- s0 = ssn0.sender("test-queue; {create:always, node:{type:queue, x-declare:{arguments:{'qpid.flow_stop_count':2000, 'qpid.flow_resume_count':100}}}}")
-
- receiver = NumberedReceiver(cluster[0])
- receiver.start()
- senders = [NumberedSender(cluster[0]) for i in range(1,3)]
- for s in senders:
- s.start()
- # Wait for senders & receiver to get up and running
- retry(lambda: receiver.received > 2*senders)
-
- # Kill original brokers, start new ones for the duration.
- endtime = time.time() + self.duration();
- i = 0
- while time.time() < endtime:
- for s in senders: s.sender.assert_running()
- receiver.receiver.assert_running()
- for b in cluster[i:]: b.ready() # Check if any broker crashed.
- cluster[i].kill()
- i += 1
- b = cluster.start(expect=EXPECT_EXIT_FAIL)
- time.sleep(5)
- for s in senders:
- s.stop()
- receiver.stop()
- for i in range(i, len(cluster)): cluster[i].kill()
-
- def test_ttl_failover(self):
- """Test that messages with TTL don't cause problems in a cluster with failover"""
-
- class Client(StoppableThread):
-
- def __init__(self, broker):
- StoppableThread.__init__(self)
- self.connection = broker.connect(reconnect=True)
- self.auto_fetch_reconnect_urls(self.connection)
- self.session = self.connection.session()
-
- def auto_fetch_reconnect_urls(self, conn):
- """Replacment for qpid.messaging.util version which is noisy"""
- ssn = conn.session("auto-fetch-reconnect-urls")
- rcv = ssn.receiver("amq.failover")
- rcv.capacity = 10
-
- def main():
- while True:
- try:
- msg = rcv.fetch()
- qpid.messaging.util.set_reconnect_urls(conn, msg)
- ssn.acknowledge(msg, sync=False)
- except messaging.exceptions.LinkClosed: return
- except messaging.exceptions.ConnectionError: return
-
- thread = Thread(name="auto-fetch-reconnect-urls", target=main)
- thread.setDaemon(True)
- thread.start()
-
- def stop(self):
- StoppableThread.stop(self)
- self.connection.detach()
-
- class Sender(Client):
- def __init__(self, broker, address):
- Client.__init__(self, broker)
- self.sent = 0 # Number of messages _reliably_ sent.
- self.sender = self.session.sender(address, capacity=1000)
-
- def send_counted(self, ttl):
- self.sender.send(Message(str(self.sent), ttl=ttl))
- self.sent += 1
-
- def run(self):
- while not self.stopped:
- choice = random.randint(0,4)
- if choice == 0: self.send_counted(None) # No ttl
- elif choice == 1: self.send_counted(100000) # Large ttl
- else: # Small ttl, might expire
- self.sender.send(Message("", ttl=random.random()/10))
- self.sender.send(Message("z"), sync=True) # Chaser.
-
- class Receiver(Client):
-
- def __init__(self, broker, address):
- Client.__init__(self, broker)
- self.received = 0 # Number of non-empty (reliable) messages received.
- self.receiver = self.session.receiver(address, capacity=1000)
- def run(self):
- try:
- while True:
- m = self.receiver.fetch(1)
- if m.content == "z": break
- if m.content: # Ignore unreliable messages
- # Ignore duplicates
- if int(m.content) == self.received: self.received += 1
- except Exception,e: self.error = e
-
- # def test_ttl_failover
-
- # Original cluster will all be killed so expect exit with failure
- # Set small purge interval.
- cluster = self.cluster(3, expect=EXPECT_EXIT_FAIL, args=["--queue-purge-interval=1"])
- for b in cluster: b.ready() # Wait for brokers to be ready
-
- # Python client failover produces noisy WARN logs, disable temporarily
- logger = logging.getLogger()
- log_level = logger.getEffectiveLevel()
- logger.setLevel(logging.ERROR)
- try:
- # Start sender and receiver threads
- receiver = Receiver(cluster[0], "q;{create:always}")
- receiver.start()
- sender = Sender(cluster[0], "q;{create:always}")
- sender.start()
- # Wait for sender & receiver to get up and running
- retry(lambda: receiver.received > 0)
-
- # Kill brokers in a cycle.
- endtime = time.time() + self.duration()
- runtime = min(5.0, self.duration() / 4.0)
- i = 0
- while time.time() < endtime:
- for b in cluster[i:]: b.ready() # Check if any broker crashed.
- cluster[i].kill()
- i += 1
- b = cluster.start(expect=EXPECT_EXIT_FAIL)
- b.ready()
- time.sleep(runtime)
- sender.stop()
- receiver.stop()
- for b in cluster[i:]:
- b.ready() # Check it didn't crash
- b.kill()
- self.assertEqual(sender.sent, receiver.received)
cluster_test_logs.verify_logs()
- finally:
- # Detach to avoid slow reconnect attempts during shut-down if test fails.
- sender.connection.detach()
- receiver.connection.detach()
- logger.setLevel(log_level)
class StoreTests(BrokerTest):
"""
diff --git a/qpid/cpp/src/tests/federation.py b/qpid/cpp/src/tests/federation.py
index 0665712db3..973a1d366c 100755
--- a/qpid/cpp/src/tests/federation.py
+++ b/qpid/cpp/src/tests/federation.py
@@ -23,7 +23,7 @@ from qpid.testlib import TestBase010
from qpid.datatypes import Message
from qpid.queue import Empty
from qpid.util import URL
-from time import sleep, time
+from time import sleep
class _FedBroker(object):
@@ -268,63 +268,6 @@ class FederationTests(TestBase010):
self.verify_cleanup()
- def test_pull_from_queue_recovery(self):
- session = self.session
-
- #setup queue on remote broker and add some messages
- r_conn = self.connect(host=self.remote_host(), port=self.remote_port())
- r_session = r_conn.session("test_pull_from_queue_recovery")
- r_session.queue_declare(queue="my-bridge-queue", auto_delete=True)
- for i in range(1, 6):
- dp = r_session.delivery_properties(routing_key="my-bridge-queue")
- r_session.message_transfer(message=Message(dp, "Message %d" % i))
-
- #setup queue to receive messages from local broker
- session.queue_declare(queue="fed1", exclusive=True, auto_delete=True)
- session.exchange_bind(queue="fed1", exchange="amq.fanout")
- self.subscribe(queue="fed1", destination="f1")
- queue = session.incoming("f1")
-
- self.startQmf()
- qmf = self.qmf
- broker = qmf.getObjects(_class="broker")[0]
- result = broker.connect(self.remote_host(), self.remote_port(), False, "PLAIN", "guest", "guest", "tcp")
- self.assertEqual(result.status, 0)
-
- link = qmf.getObjects(_class="link")[0]
- result = link.bridge(False, "my-bridge-queue", "amq.fanout", "my-key", "", "", True, False, False, 1)
- self.assertEqual(result.status, 0)
-
- bridge = qmf.getObjects(_class="bridge")[0]
- sleep(5)
-
- #recreate the remote bridge queue to invalidate the bridge session
- r_session.queue_delete (queue="my-bridge-queue", if_empty=False, if_unused=False)
- r_session.queue_declare(queue="my-bridge-queue", auto_delete=True)
-
- #add some more messages (i.e. after bridge was created)
- for i in range(6, 11):
- dp = r_session.delivery_properties(routing_key="my-bridge-queue")
- r_session.message_transfer(message=Message(dp, "Message %d" % i))
-
- for i in range(1, 11):
- try:
- msg = queue.get(timeout=5)
- self.assertEqual("Message %d" % i, msg.body)
- except Empty:
- self.fail("Failed to find expected message containing 'Message %d'" % i)
- try:
- extra = queue.get(timeout=1)
- self.fail("Got unexpected message in queue: " + extra.body)
- except Empty: None
-
- result = bridge.close()
- self.assertEqual(result.status, 0)
- result = link.close()
- self.assertEqual(result.status, 0)
-
- self.verify_cleanup()
-
def test_tracing_automatic(self):
remoteUrl = "%s:%d" % (self.remote_host(), self.remote_port())
self.startQmf()
@@ -706,17 +649,10 @@ class FederationTests(TestBase010):
self.verify_cleanup()
- def test_dynamic_headers_any(self):
- self.do_test_dynamic_headers('any')
-
- def test_dynamic_headers_all(self):
- self.do_test_dynamic_headers('all')
-
-
- def do_test_dynamic_headers(self, match_mode):
+ def test_dynamic_headers(self):
session = self.session
r_conn = self.connect(host=self.remote_host(), port=self.remote_port())
- r_session = r_conn.session("test_dynamic_headers_%s" % match_mode)
+ r_session = r_conn.session("test_dynamic_headers")
session.exchange_declare(exchange="fed.headers", type="headers")
r_session.exchange_declare(exchange="fed.headers", type="headers")
@@ -735,7 +671,7 @@ class FederationTests(TestBase010):
sleep(5)
session.queue_declare(queue="fed1", exclusive=True, auto_delete=True)
- session.exchange_bind(queue="fed1", exchange="fed.headers", binding_key="key1", arguments={'x-match':match_mode, 'class':'first'})
+ session.exchange_bind(queue="fed1", exchange="fed.headers", binding_key="key1", arguments={'x-match':'any', 'class':'first'})
self.subscribe(queue="fed1", destination="f1")
queue = session.incoming("f1")
@@ -1855,301 +1791,3 @@ class FederationTests(TestBase010):
if headers:
return headers[name]
return None
-
- def test_dynamic_topic_bounce(self):
- """ Bounce the connection between federated Topic Exchanges.
- """
- class Params:
- def exchange_type(self): return "topic"
- def bind_queue(self, ssn, qname, ename):
- ssn.exchange_bind(queue=qname, exchange=ename,
- binding_key="spud.*")
- def unbind_queue(self, ssn, qname, ename):
- ssn.exchange_unbind(queue=qname, exchange=ename, binding_key="spud.*")
- def delivery_properties(self, ssn):
- return ssn.delivery_properties(routing_key="spud.boy")
-
- self.generic_dynamic_bounce_test(Params())
-
- def test_dynamic_direct_bounce(self):
- """ Bounce the connection between federated Direct Exchanges.
- """
- class Params:
- def exchange_type(self): return "direct"
- def bind_queue(self, ssn, qname, ename):
- ssn.exchange_bind(queue=qname, exchange=ename, binding_key="spud")
- def unbind_queue(self, ssn, qname, ename):
- ssn.exchange_unbind(queue=qname, exchange=ename, binding_key="spud")
- def delivery_properties(self, ssn):
- return ssn.delivery_properties(routing_key="spud")
- self.generic_dynamic_bounce_test(Params())
-
- def test_dynamic_fanout_bounce(self):
- """ Bounce the connection between federated Fanout Exchanges.
- """
- class Params:
- def exchange_type(self): return "fanout"
- def bind_queue(self, ssn, qname, ename):
- ssn.exchange_bind(queue=qname, exchange=ename)
- def unbind_queue(self, ssn, qname, ename):
- ssn.exchange_unbind(queue=qname, exchange=ename)
- def delivery_properties(self, ssn):
- return ssn.delivery_properties(routing_key="spud")
- self.generic_dynamic_bounce_test(Params())
-
- def test_dynamic_headers_bounce(self):
- """ Bounce the connection between federated Headers Exchanges.
- """
- class Params:
- def exchange_type(self): return "headers"
- def bind_queue(self, ssn, qname, ename):
- ssn.exchange_bind(queue=qname, exchange=ename,
- binding_key="spud", arguments={'x-match':'any', 'class':'first'})
- def unbind_queue(self, ssn, qname, ename):
- ssn.exchange_unbind(queue=qname, exchange=ename, binding_key="spud")
- def delivery_properties(self, ssn):
- return ssn.message_properties(application_headers={'class':'first'})
- ## @todo KAG - re-enable once federation bugs with headers exchanges
- ## are fixed.
- #self.generic_dynamic_bounce_test(Params())
- return
-
-
- def generic_dynamic_bounce_test(self, params):
- """ Verify that a federated broker can maintain a binding to a local
- queue using the same key as a remote binding. Destroy and reconnect
- the federation link, and verify routes are restored correctly.
- See QPID-3170.
- Topology:
-
- Queue1 <---"Key"---B0<==[Federated Exchange]==>B1---"Key"--->Queue2
- """
- session = self.session
-
- # create the federation
-
- self.startQmf()
- qmf = self.qmf
-
- self._setup_brokers()
-
- # create exchange on each broker, and retrieve the corresponding
- # management object for that exchange
-
- exchanges=[]
- for _b in self._brokers[0:2]:
- _b.client_session.exchange_declare(exchange="fedX", type=params.exchange_type())
- self.assertEqual(_b.client_session.exchange_query(name="fedX").type,
- params.exchange_type(), "exchange_declare failed!")
- # pull the exchange out of qmf...
- retries = 0
- my_exchange = None
- timeout = time() + 10
- while my_exchange is None and time() <= timeout:
- objs = qmf.getObjects(_broker=_b.qmf_broker, _class="exchange")
- for ooo in objs:
- if ooo.name == "fedX":
- my_exchange = ooo
- break
- if my_exchange is None:
- self.fail("QMF failed to find new exchange!")
- exchanges.append(my_exchange)
-
- #
- # on each broker, create a local queue bound to the exchange with the
- # same key value.
- #
-
- self._brokers[0].client_session.queue_declare(queue="fedX1", exclusive=True, auto_delete=True)
- params.bind_queue(self._brokers[0].client_session, "fedX1", "fedX")
- self.subscribe(self._brokers[0].client_session, queue="fedX1", destination="f1")
- queue_0 = self._brokers[0].client_session.incoming("f1")
-
- self._brokers[1].client_session.queue_declare(queue="fedX1", exclusive=True, auto_delete=True)
- params.bind_queue(self._brokers[1].client_session, "fedX1", "fedX")
- self.subscribe(self._brokers[1].client_session, queue="fedX1", destination="f1")
- queue_1 = self._brokers[1].client_session.incoming("f1")
-
- # now federate the two brokers
-
- # connect B0 --> B1
- result = self._brokers[1].qmf_object.connect(self._brokers[0].host,
- self._brokers[0].port,
- False, "PLAIN", "guest", "guest", "tcp")
- self.assertEqual(result.status, 0)
-
- # connect B1 --> B0
- result = self._brokers[0].qmf_object.connect(self._brokers[1].host,
- self._brokers[1].port,
- False, "PLAIN", "guest", "guest", "tcp")
- self.assertEqual(result.status, 0)
-
- # for each link, bridge the "fedX" exchanges:
-
- for _l in qmf.getObjects(_class="link"):
- # print("Link=%s:%s %s" % (_l.host, _l.port, str(_l.getBroker())))
- result = _l.bridge(False, # durable
- "fedX", # src
- "fedX", # dst
- "", # key
- "", # tag
- "", # excludes
- False, # srcIsQueue
- False, # srcIsLocal
- True, # dynamic
- 0) # sync
- self.assertEqual(result.status, 0)
-
- # wait for all the inter-broker links to become operational
- operational = False
- timeout = time() + 10
- while not operational and time() <= timeout:
- operational = True
- for _l in qmf.getObjects(_class="link"):
- #print("Link=%s:%s %s" % (_l.host, _l.port, str(_l.state)))
- if _l.state != "Operational":
- operational = False
- self.failUnless(operational, "inter-broker links failed to become operational.")
-
- # @todo - There is no way to determine when the bridge objects become
- # active.
-
- # wait until the binding key has propagated to each broker - each
- # broker should see 2 bindings (1 local, 1 remote)
-
- binding_counts = [2, 2]
- self.assertEqual(len(binding_counts), len(exchanges), "Update Test!")
- for i in range(2):
- exchanges[i].update()
- timeout = time() + 10
- while exchanges[i].bindingCount < binding_counts[i] and time() <= timeout:
- exchanges[i].update()
- self.failUnless(exchanges[i].bindingCount == binding_counts[i])
-
- # send 10 msgs to B0
- for i in range(1, 11):
- # dp = self._brokers[0].client_session.delivery_properties(routing_key=params.routing_key())
- dp = params.delivery_properties(self._brokers[0].client_session)
- self._brokers[0].client_session.message_transfer(destination="fedX", message=Message(dp, "Message_trp %d" % i))
-
- # get exactly 10 msgs on B0's local queue and B1's queue
- for i in range(1, 11):
- try:
- msg = queue_0.get(timeout=5)
- self.assertEqual("Message_trp %d" % i, msg.body)
- msg = queue_1.get(timeout=5)
- self.assertEqual("Message_trp %d" % i, msg.body)
- except Empty:
- self.fail("Only got %d msgs - expected 10" % i)
- try:
- extra = queue_0.get(timeout=1)
- self.fail("Got unexpected message in queue_0: " + extra.body)
- except Empty: None
-
- try:
- extra = queue_1.get(timeout=1)
- self.fail("Got unexpected message in queue_1: " + extra.body)
- except Empty: None
-
- #
- # Tear down the bridges between the two exchanges, then wait
- # for the bindings to be cleaned up
- #
-
- for _b in qmf.getObjects(_class="bridge"):
- result = _b.close()
- self.assertEqual(result.status, 0)
-
- binding_counts = [1, 1]
- self.assertEqual(len(binding_counts), len(exchanges), "Update Test!")
- for i in range(2):
- exchanges[i].update()
- timeout = time() + 10
- while exchanges[i].bindingCount != binding_counts[i] and time() <= timeout:
- exchanges[i].update()
- self.failUnless(exchanges[i].bindingCount == binding_counts[i])
-
- #
- # restore the bridges between the two exchanges, and wait for the
- # bindings to propagate.
- #
-
- for _l in qmf.getObjects(_class="link"):
- # print("Link=%s:%s %s" % (_l.host, _l.port, str(_l.getBroker())))
- result = _l.bridge(False, # durable
- "fedX", # src
- "fedX", # dst
- "", # key
- "", # tag
- "", # excludes
- False, # srcIsQueue
- False, # srcIsLocal
- True, # dynamic
- 0) # sync
- self.assertEqual(result.status, 0)
-
- binding_counts = [2, 2]
- self.assertEqual(len(binding_counts), len(exchanges), "Update Test!")
- for i in range(2):
- exchanges[i].update()
- timeout = time() + 10
- while exchanges[i].bindingCount != binding_counts[i] and time() <= timeout:
- exchanges[i].update()
- self.failUnless(exchanges[i].bindingCount == binding_counts[i])
-
- #
- # verify traffic flows correctly
- #
-
- for i in range(1, 11):
- #dp = self._brokers[1].client_session.delivery_properties(routing_key=params.routing_key())
- dp = params.delivery_properties(self._brokers[1].client_session)
- self._brokers[1].client_session.message_transfer(destination="fedX", message=Message(dp, "Message_trp %d" % i))
-
- # get exactly 10 msgs on B0's queue and B1's queue
- for i in range(1, 11):
- try:
- msg = queue_0.get(timeout=5)
- self.assertEqual("Message_trp %d" % i, msg.body)
- msg = queue_1.get(timeout=5)
- self.assertEqual("Message_trp %d" % i, msg.body)
- except Empty:
- self.fail("Only got %d msgs - expected 10" % i)
- try:
- extra = queue_0.get(timeout=1)
- self.fail("Got unexpected message in queue_0: " + extra.body)
- except Empty: None
-
- try:
- extra = queue_1.get(timeout=1)
- self.fail("Got unexpected message in queue_1: " + extra.body)
- except Empty: None
-
-
- #
- # cleanup
- #
- params.unbind_queue(self._brokers[0].client_session, "fedX1", "fedX")
- self._brokers[0].client_session.message_cancel(destination="f1")
- self._brokers[0].client_session.queue_delete(queue="fedX1")
-
- params.unbind_queue(self._brokers[1].client_session, "fedX1", "fedX")
- self._brokers[1].client_session.message_cancel(destination="f1")
- self._brokers[1].client_session.queue_delete(queue="fedX1")
-
- for _b in qmf.getObjects(_class="bridge"):
- result = _b.close()
- self.assertEqual(result.status, 0)
-
- for _l in qmf.getObjects(_class="link"):
- result = _l.close()
- self.assertEqual(result.status, 0)
-
- for _b in self._brokers[0:2]:
- _b.client_session.exchange_delete(exchange="fedX")
-
- self._teardown_brokers()
-
- self.verify_cleanup()
-
-
diff --git a/qpid/cpp/src/tests/federation_sys.py b/qpid/cpp/src/tests/federation_sys.py
deleted file mode 100755
index 4e28156a29..0000000000
--- a/qpid/cpp/src/tests/federation_sys.py
+++ /dev/null
@@ -1,2180 +0,0 @@
-#!/usr/bin/env python
-#
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License. You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied. See the License for the
-# specific language governing permissions and limitations
-# under the License.
-#
-
-from inspect import stack
-from qpid import messaging
-from qpid.messaging import Message
-from qpid.messaging.exceptions import Empty
-from qpid.testlib import TestBase010
-from random import randint
-from sys import stdout
-from time import sleep
-
-
-class Enum(object):
- def __init__(self, **entries):
- self.__dict__.update(entries)
- def __repr__(self):
- args = ['%s=%s' % (k, repr(v)) for (k,v) in vars(self).items()]
- return 'Enum(%s)' % ', '.join(args)
-
-
-class QmfTestBase010(TestBase010):
-
- _brokers = []
- _links = []
- _bridges = []
- _alt_exch_ops = Enum(none=0, create=1, delete=2)
-
- class _Broker(object):
- """
- This broker proxy object holds the Qmf proxy to a broker of known address as well as the QMF broker
- object, connection and sessions to the broker.
- """
- def __init__(self, url):
- self.url = url # format: "host:port"
- url_parts = url.split(':')
- self.host = url_parts[0]
- self.port = int(url_parts[1])
- self.qmf_broker = None
- self.connection = messaging.Connection.establish(self.url)
- self.sessions = []
- def __str__(self):
- return "_Broker %s:%s (%d open sessions)" % (self.host, self.port, len(self.sessions))
- def destroy(self, qmf = None):
- if qmf is not None:
- qmf.delBroker(self.qmf_broker.getBroker())
- for session in self.sessions:
- try: # Session may have been closed by broker error
- session.close()
- except Exception, e: print "WARNING: %s: Unable to close session %s (%s): %s %s" % (self, session, hex(id(session)), type(e), e)
- try: # Connection may have been closed by broker error
- self.connection.close()
- except Exception, e: print "WARNING: %s: Unable to close connection %s (%s): %s %s" % (self, self.connection, hex(id(self.connection)), type(e), e)
- def session(self, name, transactional_flag = False):
- session = self.connection.session(name, transactional_flag)
- self.sessions.append(session)
- return session
-
- def setUp(self):
- """
- Called one before each test starts
- """
- TestBase010.setUp(self)
- self.startQmf();
-
- def tearDown(self):
- """
- Called once after each test competes. Close all Qmf objects (bridges, links and brokers)
- """
- while len(self._bridges):
- self._bridges.pop().close()
- while len(self._links):
- self._links.pop().close()
- while len(self._brokers):
- b = self._brokers.pop()
- if len(self._brokers) <= 1:
- b.destroy(None)
- else:
- b.destroy(self.qmf)
- TestBase010.tearDown(self)
- self.qmf.close()
-
- #--- General test utility functions
-
- def _get_name(self):
- """
- Return the name of method which called this method stripped of "test_" prefix. Used for naming
- queues and exchanges on a per-test basis.
- """
- return stack()[1][3][5:]
-
- def _get_broker_port(self, key):
- """
- Get the port of a broker defined in the environment using -D<key>=portno
- """
- return int(self.defines[key])
-
- def _get_cluster_ports(self, key):
- """
- Get the cluster ports from the parameters of the test which place it in the environment using
- -D<key>="port0 port1 ... portN" (space-separated)
- """
- ports = []
- ports_str = self.defines[key]
- if ports_str:
- for p in ports_str.split():
- ports.append(int(p))
- return ports
-
- def _get_send_address(self, exch_name, queue_name):
- """
- Get an address to which to send messages based on the exchange name and queue name, but taking into account
- that the exchange name may be "" (the default exchange), in whcih case the format changes slightly.
- """
- if len(exch_name) == 0: # Default exchange
- return queue_name
- return "%s/%s" % (exch_name, queue_name)
-
- def _get_broker(self, cluster_flag, broker_port_key, cluster_ports_key):
- """
- Read the port numbers for pre-started brokers from the environment using keys, then find or create and return
- the Qmf broker proxy for the appropriate broker
- """
- if cluster_flag:
- port = self._get_cluster_ports(cluster_ports_key)[0] # Always use the first node in the cluster
- else:
- port = self._get_broker_port(broker_port_key)
- return self._find_create_broker("localhost:%s" % port)
-
- def _get_msg_subject(self, topic_key):
- """
- Return an appropriate subject for sending a message to a known topic. Return None if there is no topic.
- """
- if len(topic_key) == 0: return None
- if "*" in topic_key: return topic_key.replace("*", "test")
- if "#" in topic_key: return topic_key.replace("#", "multipart.test")
- return topic_key
-
- def _send_msgs(self, session_name, broker, addr, msg_count, msg_content = "Message_%03d", topic_key = "",
- msg_durable_flag = False, enq_txn_size = 0):
- """
- Send messages to a broker using address addr
- """
- send_session = broker.session(session_name, transactional_flag = enq_txn_size > 0)
- sender = send_session.sender(addr)
- txn_cnt = 0
- for i in range(0, msg_count):
- sender.send(Message(msg_content % (i + 1), subject = self._get_msg_subject(topic_key), durable = msg_durable_flag))
- if enq_txn_size > 0:
- txn_cnt += 1
- if txn_cnt >= enq_txn_size:
- send_session.commit()
- txn_cnt = 0
- if enq_txn_size > 0 and txn_cnt > 0:
- send_session.commit()
- sender.close()
- send_session.close()
-
- def _receive_msgs(self, session_name, broker, addr, msg_count, msg_content = "Message_%03d", deq_txn_size = 0,
- timeout = 0):
- """
- Receive messages from a broker
- """
- receive_session = broker.session(session_name, transactional_flag = deq_txn_size > 0)
- receiver = receive_session.receiver(addr)
- txn_cnt = 0
- for i in range(0, msg_count):
- try:
- msg = receiver.fetch(timeout = timeout)
- if deq_txn_size > 0:
- txn_cnt += 1
- if txn_cnt >= deq_txn_size:
- receive_session.commit()
- txn_cnt = 0
- receive_session.acknowledge()
- except Empty:
- if deq_txn_size > 0: receive_session.rollback()
- receiver.close()
- receive_session.close()
- if i == 0:
- self.fail("Broker %s queue \"%s\" is empty" % (broker.qmf_broker.getBroker().getUrl(), addr))
- else:
- self.fail("Unable to receive message %d from broker %s queue \"%s\"" % (i, broker.qmf_broker.getBroker().getUrl(), addr))
- if msg.content != msg_content % (i + 1):
- receiver.close()
- receive_session.close()
- self.fail("Unexpected message \"%s\", was expecting \"%s\"." % (msg.content, msg_content % (i + 1)))
- try:
- msg = receiver.fetch(timeout = 0)
- if deq_txn_size > 0: receive_session.rollback()
- receiver.close()
- receive_session.close()
- self.fail("Extra message \"%s\" found on broker %s address \"%s\"" % (msg.content, broker.qmf_broker.getBroker().getUrl(), addr))
- except Empty:
- pass
- if deq_txn_size > 0 and txn_cnt > 0:
- receive_session.commit()
- receiver.close()
- receive_session.close()
-
- #--- QMF-specific utility functions
-
- def _get_qmf_property(self, props, key):
- """
- Get the value of a named property key kj from a property list [(k0, v0), (k1, v1), ... (kn, vn)].
- """
- for k,v in props:
- if k.name == key:
- return v
- return None
-
- def _check_qmf_return(self, method_result):
- """
- Check the result of a Qmf-defined method call
- """
- self.assertTrue(method_result.status == 0, method_result.text)
-
- def _check_optional_qmf_property(self, qmf_broker, type, qmf_object, key, expected_val, obj_ref_flag):
- """
- Optional Qmf properties don't show up in the properties list when they are not specified. Checks for
- these property types involve searching the properties list and making sure it is present or not as
- expected.
- """
- val = self._get_qmf_property(qmf_object.getProperties(), key)
- if val is None:
- if len(expected_val) > 0:
- self.fail("%s %s exists, but has does not have %s property. Expected value: \"%s\"" %
- (type, qmf_object.name, key, expected_val))
- else:
- if len(expected_val) > 0:
- if obj_ref_flag:
- obj = self.qmf.getObjects(_objectId = val, _broker = qmf_broker.getBroker())
- self.assertEqual(len(obj), 1, "More than one object with the same objectId: %s" % obj)
- val = obj[0].name
- self.assertEqual(val, expected_val, "%s %s exists, but has incorrect %s property. Found \"%s\", expected \"%s\"" %
- (type, qmf_object.name, key, val, expected_val))
- else:
- self.fail("%s %s exists, but has an unexpected %s property \"%s\" set." % (type, qmf_object.name, key, val))
-
- #--- Find/create Qmf broker objects
-
- def _find_qmf_broker(self, url):
- """
- Find the Qmf broker object for the given broker URL. The broker must have been previously added to Qmf through
- addBroker()
- """
- for b in self.qmf.getObjects(_class="broker"):
- if b.getBroker().getUrl() == url:
- return b
- return None
-
- def _find_create_broker(self, url):
- """
- Find a running broker through Qmf. If it does not exist, add it (assuming the broker is already running).
- """
- broker = self._Broker(url)
- self._brokers.append(broker)
- if self.qmf is not None:
- qmf_broker = self._find_qmf_broker(broker.url)
- if qmf_broker is None:
- self.qmf.addBroker(broker.url)
- broker.qmf_broker = self._find_qmf_broker(broker.url)
- else:
- broker.qmf_broker = qmf_broker
- return broker
-
- #--- Find/create/delete exchanges
-
- def _find_qmf_exchange(self, qmf_broker, name, type, alternate, durable, auto_delete):
- """
- Find Qmf exchange object
- """
- for e in self.qmf.getObjects(_class="exchange", _broker = qmf_broker.getBroker()):
- if e.name == name:
- if len(name) == 0 or (len(name) >= 4 and name[:4] == "amq."): return e # skip checks for special exchanges
- self.assertEqual(e.type, type,
- "Exchange \"%s\" exists, but is of unexpected type %s; expected type %s." %
- (name, e.type, type))
- self._check_optional_qmf_property(qmf_broker, "Exchange", e, "altExchange", alternate, True)
- self.assertEqual(e.durable, durable,
- "Exchange \"%s\" exists, but has incorrect durability. Found durable=%s, expected durable=%s" %
- (name, e.durable, durable))
- self.assertEqual(e.autoDelete, auto_delete,
- "Exchange \"%s\" exists, but has incorrect auto-delete property. Found %s, expected %s" %
- (name, e.autoDelete, auto_delete))
- return e
- return None
-
- def _find_create_qmf_exchange(self, qmf_broker, name, type, alternate, durable, auto_delete, args):
- """
- Find Qmf exchange object if exchange exists, create exchange and return its Qmf object if not
- """
- e = self._find_qmf_exchange(qmf_broker, name, type, alternate, durable, auto_delete)
- if e is not None: return e
- # Does not exist, so create it
- props = dict({"exchange-type": type, "type": type, "durable": durable, "auto-delete": auto_delete, "alternate-exchange": alternate}, **args)
- self._check_qmf_return(qmf_broker.create(type="exchange", name=name, properties=props, strict=True))
- e = self._find_qmf_exchange(qmf_broker, name, type, alternate, durable, auto_delete)
- self.assertNotEqual(e, None, "Creation of exchange %s on broker %s failed" % (name, qmf_broker.getBroker().getUrl()))
- return e
-
- def _find_delete_qmf_exchange(self, qmf_broker, name, type, alternate, durable, auto_delete):
- """
- Find and delete Qmf exchange object if it exists
- """
- e = self._find_qmf_exchange(qmf_broker, name, type, alternate, durable, auto_delete)
- if e is not None and not auto_delete:
- self._check_qmf_return(qmf_broker.delete(type="exchange", name=name, options={}))
-
- #--- Find/create/delete queues
-
- def _find_qmf_queue(self, qmf_broker, name, alternate_exchange, durable, exclusive, auto_delete):
- """
- Find a Qmf queue object
- """
- for q in self.qmf.getObjects(_class="queue", _broker = qmf_broker.getBroker()):
- if q.name == name:
- self._check_optional_qmf_property(qmf_broker, "Queue", q, "altExchange", alternate_exchange, True)
- self.assertEqual(q.durable, durable,
- "Queue \"%s\" exists, but has incorrect durable property. Found %s, expected %s" %
- (name, q.durable, durable))
- self.assertEqual(q.exclusive, exclusive,
- "Queue \"%s\" exists, but has incorrect exclusive property. Found %s, expected %s" %
- (name, q.exclusive, exclusive))
- self.assertEqual(q.autoDelete, auto_delete,
- "Queue \"%s\" exists, but has incorrect auto-delete property. Found %s, expected %s" %
- (name, q.autoDelete, auto_delete))
- return q
- return None
-
- def _find_create_qmf_queue(self, qmf_broker, name, alternate_exchange, durable, exclusive, auto_delete, args):
- """
- Find Qmf queue object if queue exists, create queue and return its Qmf object if not
- """
- q = self._find_qmf_queue(qmf_broker, name, alternate_exchange, durable, exclusive, auto_delete)
- if q is not None: return q
- # Queue does not exist, so create it
- props = dict({"durable": durable, "auto-delete": auto_delete, "exclusive": exclusive, "alternate-exchange": alternate_exchange}, **args)
- self._check_qmf_return(qmf_broker.create(type="queue", name=name, properties=props, strict=True))
- q = self._find_qmf_queue(qmf_broker, name, alternate_exchange, durable, exclusive, auto_delete)
- self.assertNotEqual(q, None, "Creation of queue %s on broker %s failed" % (name, qmf_broker.getBroker().getUrl()))
- return q
-
- def _find_delete_qmf_queue(self, qmf_broker, name, alternate_exchange, durable, exclusive, auto_delete, args):
- """
- Find and delete Qmf queue object if it exists
- """
- q = self._find_qmf_queue(qmf_broker, name, alternate_exchange, durable, exclusive, auto_delete)
- if q is not None and not auto_delete:
- self._check_qmf_return(qmf_broker.delete(type="queue", name=name, options={}))
-
- #--- Find/create/delete bindings (between an exchange and a queue)
-
- def _find_qmf_binding(self, qmf_broker, qmf_exchange, qmf_queue, binding_key, binding_args):
- """
- Find a Qmf binding object
- """
- for b in self.qmf.getObjects(_class="binding", _broker = qmf_broker.getBroker()):
- if b.exchangeRef == qmf_exchange.getObjectId() and b.queueRef == qmf_queue.getObjectId():
- if qmf_exchange.type != "fanout": # Fanout ignores the binding key, and always returns "" as the key
- self.assertEqual(b.bindingKey, binding_key,
- "Binding between exchange %s and queue %s exists, but has mismatching binding key: Found %s, expected %s." %
- (qmf_exchange.name, qmf_queue.name, b.bindingKey, binding_key))
- self.assertEqual(b.arguments, binding_args,
- "Binding between exchange %s and queue %s exists, but has mismatching arguments: Found %s, expected %s" %
- (qmf_exchange.name, qmf_queue.name, b.arguments, binding_args))
- return b
- return None
-
- def _find_create_qmf_binding(self, qmf_broker, qmf_exchange, qmf_queue, binding_key, binding_args):
- """
- Find Qmf binding object if it exists, create binding and return its Qmf object if not
- """
- b = self._find_qmf_binding(qmf_broker, qmf_exchange, qmf_queue, binding_key, binding_args)
- if b is not None: return b
- # Does not exist, so create it
- self._check_qmf_return(qmf_broker.create(type="binding", name="%s/%s/%s" % (qmf_exchange.name, qmf_queue.name, binding_key), properties=binding_args, strict=True))
- b = self._find_qmf_binding(qmf_broker, qmf_exchange, qmf_queue, binding_key, binding_args)
- self.assertNotEqual(b, None, "Creation of binding between exchange %s and queue %s with key %s failed" %
- (qmf_exchange.name, qmf_queue.name, binding_key))
- return b
-
- def _find_delete_qmf_binding(self, qmf_broker, qmf_exchange, qmf_queue, binding_key, binding_args):
- """
- Find and delete Qmf binding object if it exists
- """
- b = self._find_qmf_binding(qmf_broker, qmf_exchange, qmf_queue, binding_key, binding_args)
- if b is not None:
- if len(qmf_exchange.name) > 0: # not default exchange
- self._check_qmf_return(qmf_broker.delete(type="binding", name="%s/%s/%s" % (qmf_exchange.name, qmf_queue.name, binding_key), options={}))
-
- #--- Find/create a link
-
- def _find_qmf_link(self, qmf_from_broker_proxy, host, port):
- """
- Find a Qmf link object
- """
- for l in self.qmf.getObjects(_class="link", _broker=qmf_from_broker_proxy):
- if l.host == host and l.port == port:
- return l
- return None
-
- def _find_create_qmf_link(self, qmf_from_broker, qmf_to_broker_proxy, link_durable_flag, auth_mechanism, user_id,
- password, transport, pause_interval, link_ready_timeout):
- """
- Find a Qmf link object if it exists, create it and return its Qmf link object if not
- """
- to_broker_host = qmf_to_broker_proxy.host
- to_broker_port = qmf_to_broker_proxy.port
- l = self._find_qmf_link(qmf_from_broker.getBroker(), to_broker_host, to_broker_port)
- if l is not None: return l
- # Does not exist, so create it
- self._check_qmf_return(qmf_from_broker.connect(to_broker_host, to_broker_port, link_durable_flag, auth_mechanism, user_id, password, transport))
- l = self._find_qmf_link(qmf_from_broker.getBroker(), to_broker_host, to_broker_port)
- self.assertNotEqual(l, None, "Creation of link from broker %s to broker %s failed" %
- (qmf_from_broker.getBroker().getUrl(), qmf_to_broker_proxy.getUrl()))
- self._wait_for_link(l, pause_interval, link_ready_timeout)
- return l
-
- def _wait_for_link(self, link, pause_interval, link_ready_timeout):
- """
- Wait for link to become active (state=Operational)
- """
- tot_time = 0
- link.update()
- if link.state == "":
- # Link mgmt updates for the c++ link object are disabled when in a cluster because of inconsistent state:
- # one is "Operational", the other "Passive". In this case, wait a bit and hope for the best...
- sleep(2*pause_interval)
- else:
- while link.state != "Operational" and tot_time < link_ready_timeout:
- sleep(pause_interval)
- tot_time += pause_interval
- link.update()
- self.assertEqual(link.state, "Operational", "Timeout: Link not operational, state=%s" % link.state)
-
- #--- Find/create a bridge
-
- def _find_qmf_bridge(self, qmf_broker_proxy, qmf_link, source, destination, key):
- """
- Find a Qmf link object
- """
- for b in self.qmf.getObjects(_class="bridge", _broker=qmf_broker_proxy):
- if b.linkRef == qmf_link.getObjectId() and b.src == source and b.dest == destination and b.key == key:
- return b
- return None
-
- def _find_create_qmf_bridge(self, qmf_broker_proxy, qmf_link, queue_name, exch_name, topic_key,
- queue_route_type_flag, bridge_durable_flag):
- """
- Find a Qmf bridge object if it exists, create it and return its Qmf object if not
- """
- if queue_route_type_flag:
- src = queue_name
- dest = exch_name
- key = ""
- else:
- src = exch_name
- dest = exch_name
- if len(topic_key) > 0:
- key = topic_key
- else:
- key = queue_name
- b = self._find_qmf_bridge(qmf_broker_proxy, qmf_link, src, dest, key)
- if b is not None:
- return b
- # Does not exist, so create it
- self._check_qmf_return(qmf_link.bridge(bridge_durable_flag, src, dest, key, "", "", queue_route_type_flag, False, False, 1))
- b = self._find_qmf_bridge(qmf_broker_proxy, qmf_link, src, dest, key)
- self.assertNotEqual(b, None, "Bridge creation failed: src=%s dest=%s key=%s" % (src, dest, key))
- return b
-
- def _wait_for_bridge(self, bridge, src_broker, dest_broker, exch_name, queue_name, topic_key, pause_interval,
- bridge_ready_timeout):
- """
- Wait for bridge to become active by sending messages over the bridge at 1 sec intervals until they are
- observed at the destination.
- """
- tot_time = 0
- active = False
- send_session = src_broker.session("tx")
- sender = send_session.sender(self._get_send_address(exch_name, queue_name))
- src_receive_session = src_broker.session("src_rx")
- src_receiver = src_receive_session.receiver(queue_name)
- dest_receive_session = dest_broker.session("dest_rx")
- dest_receiver = dest_receive_session.receiver(queue_name)
- while not active and tot_time < bridge_ready_timeout:
- sender.send(Message("xyz123", subject = self._get_msg_subject(topic_key)))
- try:
- src_receiver.fetch(timeout = 0)
- src_receive_session.acknowledge()
- # Keep receiving msgs, as several may have accumulated
- while True:
- dest_receiver.fetch(timeout = 0)
- dest_receive_session.acknowledge()
- sleep(1)
- active = True
- except Empty:
- sleep(pause_interval)
- tot_time += pause_interval
- dest_receiver.close()
- dest_receive_session.close()
- src_receiver.close()
- src_receive_session.close()
- sender.close()
- send_session.close()
- self.assertTrue(active, "Bridge failed to become active after %ds: %s" % (bridge_ready_timeout, bridge))
-
- #--- Find/create/delete utility functions
-
- def _create_and_bind(self, qmf_broker, exchange_args, queue_args, binding_args):
- """
- Create a binding between a named exchange and queue on a broker
- """
- e = self._find_create_qmf_exchange(qmf_broker, **exchange_args)
- q = self._find_create_qmf_queue(qmf_broker, **queue_args)
- return self._find_create_qmf_binding(qmf_broker, e, q, **binding_args)
-
- def _check_alt_exchange(self, qmf_broker, alt_exch_name, alt_exch_type, alt_exch_op):
- """
- Check for existence of alternate exchange. Return the Qmf exchange proxy object for the alternate exchange
- """
- if len(alt_exch_name) == 0: return None
- if alt_exch_op == _alt_exch_ops.create:
- return self._find_create_qmf_exchange(qmf_broker=qmf_broker, name=alt_exch_name, type=alt_exch_type,
- alternate="", durable=False, auto_delete=False, args={})
- if alt_exch_op == _alt_exch_ops.delete:
- return self._find_delete_qmf_exchange(qmf_broker=qmf_broker, name=alt_exch_name, type=alt_exch_type,
- alternate="", durable=False, auto_delete=False)
- return self._find_qmf_exchange(qmf_broker=qmf_broker, name=alt_exchange_name, type=alt_exchange_type,
- alternate="", durable=False, auto_delete=False)
-
- def _delete_queue_binding(self, qmf_broker, exchange_args, queue_args, binding_args):
- """
- Delete a queue and the binding between it and the exchange
- """
- e = self._find_qmf_exchange(qmf_broker, exchange_args["name"], exchange_args["type"], exchange_args["alternate"], exchange_args["durable"], exchange_args["auto_delete"])
- q = self._find_qmf_queue(qmf_broker, queue_args["name"], queue_args["alternate_exchange"], queue_args["durable"], queue_args["exclusive"], queue_args["auto_delete"])
- self._find_delete_qmf_binding(qmf_broker, e, q, **binding_args)
- self._find_delete_qmf_queue(qmf_broker, **queue_args)
-
- def _create_route(self, queue_route_type_flag, src_broker, dest_broker, exch_name, queue_name, topic_key,
- link_durable_flag, bridge_durable_flag, auth_mechanism, user_id, password, transport,
- pause_interval = 1, link_ready_timeout = 20, bridge_ready_timeout = 20):
- """
- Create a route from a source broker to a destination broker
- """
- l = self._find_create_qmf_link(dest_broker.qmf_broker, src_broker.qmf_broker.getBroker(), link_durable_flag,
- auth_mechanism, user_id, password, transport, pause_interval, link_ready_timeout)
- self._links.append(l)
- b = self._find_create_qmf_bridge(dest_broker.qmf_broker.getBroker(), l, queue_name, exch_name, topic_key,
- queue_route_type_flag, bridge_durable_flag)
- self._bridges.append(b)
- self._wait_for_bridge(b, src_broker, dest_broker, exch_name, queue_name, topic_key, pause_interval, bridge_ready_timeout)
-
- # Parameterized test - entry point for tests
-
- def _do_test(self,
- test_name, # Name of test
- exch_name = "", # Remote exchange name
- exch_type = "direct", # Remote exchange type
- exch_alt_exch = "", # Remote exchange alternate exchange
- exch_alt_exch_type = "direct", # Remote exchange alternate exchange type
- exch_durable_flag = False, # Remote exchange durability
- exch_auto_delete_flag = False, # Remote exchange auto-delete property
- exch_x_args = {}, # Remote exchange args
- queue_alt_exch = "", # Remote queue alternate exchange
- queue_alt_exch_type = "direct", # Remote queue alternate exchange type
- queue_durable_flag = False, # Remote queue durability
- queue_exclusive_flag = False, # Remote queue exclusive property
- queue_auto_delete_flag = False, # Remote queue auto-delete property
- queue_x_args = {}, # Remote queue args
- binding_durable_flag = False, # Remote binding durability
- binding_x_args = {}, # Remote binding args
- topic_key = "", # Binding key For remote topic exchanges only
- msg_count = 10, # Number of messages to send
- msg_durable_flag = False, # Message durability
- link_durable_flag = False, # Route link durability
- bridge_durable_flag = False, # Route bridge durability
- queue_route_type_flag = False, # Route type: false = bridge route, true = queue route
- enq_txn_size = 0, # Enqueue transaction size, 0 = no transactions
- deq_txn_size = 0, # Dequeue transaction size, 0 = no transactions
- local_cluster_flag = False, # Use a node from the local cluster, otherwise use single local broker
- remote_cluster_flag = False, # Use a node from the remote cluster, otherwise use single remote broker
- alt_exch_op = _alt_exch_ops.create,# Op on alt exch [create (ensure present), delete (ensure not present), none (neither create nor delete)]
- auth_mechanism = "", # Authorization mechanism for linked broker
- user_id = "", # User ID for authorization on linked broker
- password = "", # Password for authorization on linked broker
- transport = "tcp" # Transport for route to linked broker
- ):
- """
- Parameterized federation test. Sets up a federated link between a source broker and a destination broker and
- checks that messages correctly pass over the link to the destination. Where appropriate (non-queue-routes), also
- checks for the presence of messages on the source broker.
-
- In these tests, the concept is to create a LOCAL broker, then create a link to a REMOTE broker using federation.
- In other words, the messages sent to the LOCAL broker will be replicated on the REMOTE broker, and tests are
- performed on the REMOTE broker to check that the required messages are present. In the case of regular routes,
- the LOCAL broker will also retain the messages, and a similar test is performed on this broker.
-
- TODO: There are several items to improve here:
- 1. _do_test() is rather general. Rather create a version for each exchange type and test the exchange/queue
- interaction in more detail based on the exchange type
- 2. Add a headers and an xml exchange type
- 3. Restructure the tests to start and stop brokers and clusters directly rather than relying on previously
- started brokers. Then persistence can be checked by stopping and restarting the brokers/clusters. In particular,
- test the persistence of links and bridges, both of which take a persistence flag.
- 4. Test the behavior of the alternate exchanges when messages are sourced through a link. Also check behavior
- when the alternate exchange is not present or is deleted after the reference is made.
- 5. Test special queue types (eg LVQ)
- """
- local_broker = self._get_broker(local_cluster_flag, "local-port", "local-cluster-ports")
- remote_broker = self._get_broker(remote_cluster_flag, "remote-port", "remote-cluster-ports")
-
- # Check alternate exchanges exist (and create them if not) on both local and remote brokers
- self._check_alt_exchange(local_broker.qmf_broker, exch_alt_exch, exch_alt_exch_type, alt_exch_op)
- self._check_alt_exchange(local_broker.qmf_broker, queue_alt_exch, queue_alt_exch_type, alt_exch_op)
- self._check_alt_exchange(remote_broker.qmf_broker, exch_alt_exch, exch_alt_exch_type, alt_exch_op)
- self._check_alt_exchange(remote_broker.qmf_broker, queue_alt_exch, queue_alt_exch_type, alt_exch_op)
-
- queue_name = "queue_%s" % test_name
- exchange_args = {"name": exch_name, "type": exch_type, "alternate": exch_alt_exch,
- "durable": exch_durable_flag, "auto_delete": exch_auto_delete_flag, "args": exch_x_args}
- queue_args = {"name": queue_name, "alternate_exchange": queue_alt_exch, "durable": queue_durable_flag,
- "exclusive": queue_exclusive_flag, "auto_delete": queue_auto_delete_flag, "args": queue_x_args}
- binding_args = {"binding_args": binding_x_args}
- if exch_type == "topic":
- self.assertTrue(len(topic_key) > 0, "Topic exchange selected, but no topic key was set.")
- binding_args["binding_key"] = topic_key
- elif exch_type == "direct":
- binding_args["binding_key"] = queue_name
- else:
- binding_args["binding_key"] = ""
- self._create_and_bind(qmf_broker=local_broker.qmf_broker, exchange_args=exchange_args, queue_args=queue_args, binding_args=binding_args)
- self._create_and_bind(qmf_broker=remote_broker.qmf_broker, exchange_args=exchange_args, queue_args=queue_args, binding_args=binding_args)
- self._create_route(queue_route_type_flag, local_broker, remote_broker, exch_name, queue_name, topic_key,
- link_durable_flag, bridge_durable_flag, auth_mechanism, user_id, password, transport)
-
- self._send_msgs("send_session", local_broker, addr = self._get_send_address(exch_name, queue_name),
- msg_count = msg_count, topic_key = topic_key, msg_durable_flag = msg_durable_flag, enq_txn_size = enq_txn_size)
- if not queue_route_type_flag:
- self._receive_msgs("local_receive_session", local_broker, addr = queue_name, msg_count = msg_count, deq_txn_size = deq_txn_size)
- self._receive_msgs("remote_receive_session", remote_broker, addr = queue_name, msg_count = msg_count, deq_txn_size = deq_txn_size, timeout = 5)
-
- # Clean up
- self._delete_queue_binding(qmf_broker=local_broker.qmf_broker, exchange_args=exchange_args, queue_args=queue_args, binding_args=binding_args)
- self._delete_queue_binding(qmf_broker=remote_broker.qmf_broker, exchange_args=exchange_args, queue_args=queue_args, binding_args=binding_args)
-
-class A_ShortTests(QmfTestBase010):
-
- def test_route_defaultExch(self):
- self._do_test(self._get_name())
-
- def test_queueRoute_defaultExch(self):
- self._do_test(self._get_name(), queue_route_type_flag=True)
-
-
-class A_LongTests(QmfTestBase010):
-
- def test_route_amqDirectExch(self):
- self._do_test(self._get_name(), exch_name="amq.direct")
-
- def test_queueRoute_amqDirectExch(self):
- self._do_test(self._get_name(), exch_name="amq.direct", queue_route_type_flag=True)
-
-
- def test_route_directExch(self):
- self._do_test(self._get_name(), exch_name="testDirectExchange")
-
- def test_queueRoute_directExch(self):
- self._do_test(self._get_name(), exch_name="testDirectExchange", queue_route_type_flag=True)
-
-
- def test_route_fanoutExch(self):
- self._do_test(self._get_name(), exch_name="testFanoutExchange", exch_type="fanout")
-
- def test_queueRoute_fanoutExch(self):
- self._do_test(self._get_name(), exch_name="testFanoutExchange", exch_type="fanout", queue_route_type_flag=True)
-
-
- def test_route_topicExch(self):
- self._do_test(self._get_name(), exch_name="testTopicExchange", exch_type="topic", topic_key=self._get_name()+".#")
-
- def test_queueRoute_topicExch(self):
- self._do_test(self._get_name(), exch_name="testTopicExchange", exch_type="topic", topic_key=self._get_name()+".#", queue_route_type_flag=True)
-
-
-class B_ShortTransactionTests(QmfTestBase010):
-
- def test_txEnq01_route_defaultExch(self):
- self._do_test(self._get_name(), enq_txn_size=1)
-
- def test_txEnq01_queueRoute_defaultExch(self):
- self._do_test(self._get_name(), queue_route_type_flag=True, enq_txn_size=1)
-
- def test_txEnq01_txDeq01_route_defaultExch(self):
- self._do_test(self._get_name(), enq_txn_size=1, deq_txn_size=1)
-
- def test_txEnq01_txDeq01_queueRoute_defaultExch(self):
- self._do_test(self._get_name(), queue_route_type_flag=True, enq_txn_size=1, deq_txn_size=1)
-
-
-class B_LongTransactionTests(QmfTestBase010):
-
- def test_txEnq10_route_defaultExch(self):
- self._do_test(self._get_name(), enq_txn_size=10, msg_count = 103)
-
- def test_txEnq10_queueRoute_defaultExch(self):
- self._do_test(self._get_name(), queue_route_type_flag=True, enq_txn_size=10, msg_count = 103)
-
-
- def test_txEnq01_route_amqDirectExch(self):
- self._do_test(self._get_name(), exch_name="amq.direct", enq_txn_size=1)
-
- def test_txEnq01_queueRoute_amqDirectExch(self):
- self._do_test(self._get_name(), exch_name="amq.direct", queue_route_type_flag=True, enq_txn_size=1)
-
- def test_txEnq10_route_amqDirectExch(self):
- self._do_test(self._get_name(), exch_name="amq.direct", enq_txn_size=10, msg_count = 103)
-
- def test_txEnq10_queueRoute_amqDirectExch(self):
- self._do_test(self._get_name(), exch_name="amq.direct", queue_route_type_flag=True, enq_txn_size=10, msg_count = 103)
-
- def test_txEnq01_txDeq01_route_amqDirectExch(self):
- self._do_test(self._get_name(), exch_name="amq.direct", enq_txn_size=1, deq_txn_size=1)
-
- def test_txEnq01_txDeq01_queueRoute_amqDirectExch(self):
- self._do_test(self._get_name(), exch_name="amq.direct", queue_route_type_flag=True, enq_txn_size=1, deq_txn_size=1)
-
-
- def test_txEnq01_route_directExch(self):
- self._do_test(self._get_name(), exch_name="testDirectExchange", enq_txn_size=1)
-
- def test_txEnq01_queueRoute_directExch(self):
- self._do_test(self._get_name(), exch_name="testDirectExchange", queue_route_type_flag=True, enq_txn_size=1)
-
- def test_txEnq10_route_directExch(self):
- self._do_test(self._get_name(), exch_name="testDirectExchange", enq_txn_size=10, msg_count = 103)
-
- def test_txEnq10_queueRoute_directExch(self):
- self._do_test(self._get_name(), exch_name="testDirectExchange", queue_route_type_flag=True, enq_txn_size=10, msg_count = 103)
-
- def test_txEnq01_txDeq01_route_directExch(self):
- self._do_test(self._get_name(), exch_name="testDirectExchange", enq_txn_size=1, deq_txn_size=1)
-
- def test_txEnq01_txDeq01_queueRoute_directExch(self):
- self._do_test(self._get_name(), exch_name="testDirectExchange", queue_route_type_flag=True, enq_txn_size=1, deq_txn_size=1)
-
-
- def test_txEnq01_route_fanoutExch(self):
- self._do_test(self._get_name(), exch_name="testFanoutExchange", exch_type="fanout", enq_txn_size=1)
-
- def test_txEnq01_queueRoute_fanoutExch(self):
- self._do_test(self._get_name(), exch_name="testFanoutExchange", exch_type="fanout", queue_route_type_flag=True, enq_txn_size=1)
-
- def test_txEnq10_route_fanoutExch(self):
- self._do_test(self._get_name(), exch_name="testFanoutExchange", exch_type="fanout", enq_txn_size=10, msg_count = 103)
-
- def test_txEnq10_queueRoute_fanoutExch(self):
- self._do_test(self._get_name(), exch_name="testFanoutExchange", exch_type="fanout", queue_route_type_flag=True, enq_txn_size=10, msg_count = 103)
-
- def test_txEnq01_txDeq01_route_fanoutExch(self):
- self._do_test(self._get_name(), exch_name="testFanoutExchange", exch_type="fanout", enq_txn_size=1, deq_txn_size=1)
-
- def test_txEnq01_txDeq01_queueRoute_fanoutExch(self):
- self._do_test(self._get_name(), exch_name="testFanoutExchange", exch_type="fanout", queue_route_type_flag=True, enq_txn_size=1, deq_txn_size=1)
-
-
- def test_txEnq01_route_topicExch(self):
- self._do_test(self._get_name(), exch_name="testTopicExchange", exch_type="topic", topic_key=self._get_name()+".#", enq_txn_size=1)
-
- def test_txEnq01_queueRoute_topicExch(self):
- self._do_test(self._get_name(), exch_name="testTopicExchange", exch_type="topic", topic_key=self._get_name()+".#", queue_route_type_flag=True, enq_txn_size=1)
-
- def test_txEnq10_route_topicExch(self):
- self._do_test(self._get_name(), exch_name="testTopicExchange", exch_type="topic", topic_key=self._get_name()+".#", enq_txn_size=10, msg_count = 103)
-
- def test_txEnq10_queueRoute_topicExch(self):
- self._do_test(self._get_name(), exch_name="testTopicExchange", exch_type="topic", topic_key=self._get_name()+".#", queue_route_type_flag=True, enq_txn_size=10, msg_count = 103)
-
- def test_txEnq01_txDeq01_route_topicExch(self):
- self._do_test(self._get_name(), exch_name="testTopicExchange", exch_type="topic", topic_key=self._get_name()+".#", enq_txn_size=1, deq_txn_size=1)
-
- def test_txEnq01_txDeq01_queueRoute_topicExch(self):
- self._do_test(self._get_name(), exch_name="testTopicExchange", exch_type="topic", topic_key=self._get_name()+".#", queue_route_type_flag=True, enq_txn_size=1, deq_txn_size=1)
-
-
-class C_ShortClusterTests(QmfTestBase010):
-
- def test_locCluster_route_defaultExch(self):
- self._do_test(self._get_name(), local_cluster_flag=True)
-
- def test_locCluster_queueRoute_defaultExch(self):
- self._do_test(self._get_name(), queue_route_type_flag=True, local_cluster_flag=True)
-
- def test_remCluster_route_defaultExch(self):
- self._do_test(self._get_name(), remote_cluster_flag=True)
-
- def test_remCluster_queueRoute_defaultExch(self):
- self._do_test(self._get_name(), queue_route_type_flag=True, remote_cluster_flag=True)
-
- def test_locCluster_remCluster_route_defaultExch(self):
- self._do_test(self._get_name(), local_cluster_flag=True, remote_cluster_flag=True)
-
- def test_locCluster_remCluster_queueRoute_defaultExch(self):
- self._do_test(self._get_name(), queue_route_type_flag=True, local_cluster_flag=True, remote_cluster_flag=True)
-
-
-class C_LongClusterTests(QmfTestBase010):
-
- def test_locCluster_route_amqDirectExch(self):
- self._do_test(self._get_name(), exch_name="amq.direct", local_cluster_flag=True)
-
- def test_locCluster_queueRoute_amqDirectExch(self):
- self._do_test(self._get_name(), exch_name="amq.direct", queue_route_type_flag=True, local_cluster_flag=True)
-
- def test_remCluster_route_amqDirectExch(self):
- self._do_test(self._get_name(), exch_name="amq.direct", remote_cluster_flag=True)
-
- def test_remCluster_queueRoute_amqDirectExch(self):
- self._do_test(self._get_name(), exch_name="amq.direct", queue_route_type_flag=True, remote_cluster_flag=True)
-
- def test_locCluster_remCluster_route_amqDirectExch(self):
- self._do_test(self._get_name(), exch_name="amq.direct", local_cluster_flag=True, remote_cluster_flag=True)
-
- def test_locCluster_remCluster_queueRoute_amqDirectExch(self):
- self._do_test(self._get_name(), exch_name="amq.direct", queue_route_type_flag=True, local_cluster_flag=True, remote_cluster_flag=True)
-
-
- def test_locCluster_route_directExch(self):
- self._do_test(self._get_name(), exch_name="testDirectExchange", local_cluster_flag=True)
-
- def test_locCluster_queueRoute_directExch(self):
- self._do_test(self._get_name(), exch_name="testDirectExchange", queue_route_type_flag=True, local_cluster_flag=True)
-
- def test_remCluster_route_directExch(self):
- self._do_test(self._get_name(), exch_name="testDirectExchange", remote_cluster_flag=True)
-
- def test_remCluster_queueRoute_directExch(self):
- self._do_test(self._get_name(), exch_name="testDirectExchange", queue_route_type_flag=True, remote_cluster_flag=True)
-
- def test_locCluster_remCluster_route_directExch(self):
- self._do_test(self._get_name(), exch_name="testDirectExchange", local_cluster_flag=True, remote_cluster_flag=True)
-
- def test_locCluster_remCluster_queueRoute_directExch(self):
- self._do_test(self._get_name(), exch_name="testDirectExchange", queue_route_type_flag=True, local_cluster_flag=True, remote_cluster_flag=True)
-
-
- def test_locCluster_route_fanoutExch(self):
- self._do_test(self._get_name(), exch_name="testFanoutExchange", exch_type="fanout", local_cluster_flag=True)
-
- def test_locCluster_queueRoute_fanoutExch(self):
- self._do_test(self._get_name(), exch_name="testFanoutExchange", exch_type="fanout", queue_route_type_flag=True, local_cluster_flag=True)
-
- def test_remCluster_route_fanoutExch(self):
- self._do_test(self._get_name(), exch_name="testFanoutExchange", exch_type="fanout", remote_cluster_flag=True)
-
- def test_remCluster_queueRoute_fanoutExch(self):
- self._do_test(self._get_name(), exch_name="testFanoutExchange", exch_type="fanout", queue_route_type_flag=True, remote_cluster_flag=True)
-
- def test_locCluster_remCluster_route_fanoutExch(self):
- self._do_test(self._get_name(), exch_name="testFanoutExchange", exch_type="fanout", local_cluster_flag=True, remote_cluster_flag=True)
-
- def test_locCluster_remCluster_queueRoute_fanoutExch(self):
- self._do_test(self._get_name(), exch_name="testFanoutExchange", exch_type="fanout", queue_route_type_flag=True, local_cluster_flag=True, remote_cluster_flag=True)
-
-
- def test_locCluster_route_topicExch(self):
- self._do_test(self._get_name(), exch_name="testTopicExchange", exch_type="topic", topic_key=self._get_name()+".#", local_cluster_flag=True)
-
- def test_locCluster_queueRoute_topicExch(self):
- self._do_test(self._get_name(), exch_name="testTopicExchange", exch_type="topic", topic_key=self._get_name()+".#", queue_route_type_flag=True, local_cluster_flag=True)
-
- def test_remCluster_route_topicExch(self):
- self._do_test(self._get_name(), exch_name="testTopicExchange", exch_type="topic", topic_key=self._get_name()+".#", remote_cluster_flag=True)
-
- def test_remCluster_queueRoute_topicExch(self):
- self._do_test(self._get_name(), exch_name="testTopicExchange", exch_type="topic", topic_key=self._get_name()+".#", queue_route_type_flag=True, remote_cluster_flag=True)
-
- def test_locCluster_remCluster_route_topicExch(self):
- self._do_test(self._get_name(), exch_name="testTopicExchange", exch_type="topic", topic_key=self._get_name()+".#", local_cluster_flag=True, remote_cluster_flag=True)
-
- def test_locCluster_remCluster_queueRoute_topicExch(self):
- self._do_test(self._get_name(), exch_name="testTopicExchange", exch_type="topic", topic_key=self._get_name()+".#", queue_route_type_flag=True, local_cluster_flag=True, remote_cluster_flag=True)
-
-
-class D_ShortClusterTransactionTests(QmfTestBase010):
-
- def test_txEnq01_locCluster_route_defaultExch(self):
- self._do_test(self._get_name(), enq_txn_size=1, local_cluster_flag=True)
-
- def test_txEnq01_locCluster_queueRoute_defaultExch(self):
- self._do_test(self._get_name(), queue_route_type_flag=True, enq_txn_size=1, local_cluster_flag=True)
-
- def test_txEnq01_txDeq01_locCluster_route_defaultExch(self):
- self._do_test(self._get_name(), enq_txn_size=1, deq_txn_size=1, local_cluster_flag=True)
-
- def test_txEnq01_txDeq01_locCluster_queueRoute_defaultExch(self):
- self._do_test(self._get_name(), queue_route_type_flag=True, enq_txn_size=1, deq_txn_size=1, local_cluster_flag=True)
-
- def test_txEnq01_remCluster_route_defaultExch(self):
- self._do_test(self._get_name(), enq_txn_size=1, remote_cluster_flag=True)
-
- def test_txEnq01_remCluster_queueRoute_defaultExch(self):
- self._do_test(self._get_name(), queue_route_type_flag=True, enq_txn_size=1, remote_cluster_flag=True)
-
- def test_txEnq01_txDeq01_remCluster_route_defaultExch(self):
- self._do_test(self._get_name(), enq_txn_size=1, deq_txn_size=1, remote_cluster_flag=True)
-
- def test_txEnq01_txDeq01_remCluster_queueRoute_defaultExch(self):
- self._do_test(self._get_name(), queue_route_type_flag=True, enq_txn_size=1, deq_txn_size=1, remote_cluster_flag=True)
-
- def test_txEnq01_locCluster_remCluster_route_defaultExch(self):
- self._do_test(self._get_name(), enq_txn_size=1, local_cluster_flag=True, remote_cluster_flag=True)
-
- def test_txEnq01_locCluster_remCluster_queueRoute_defaultExch(self):
- self._do_test(self._get_name(), queue_route_type_flag=True, enq_txn_size=1, local_cluster_flag=True, remote_cluster_flag=True)
-
- def test_txEnq01_txDeq01_locCluster_remCluster_route_defaultExch(self):
- self._do_test(self._get_name(), enq_txn_size=1, deq_txn_size=1, local_cluster_flag=True, remote_cluster_flag=True)
-
- def test_txEnq01_txDeq01_locCluster_remCluster_queueRoute_defaultExch(self):
- self._do_test(self._get_name(), queue_route_type_flag=True, enq_txn_size=1, deq_txn_size=1, local_cluster_flag=True, remote_cluster_flag=True)
-
-
-class D_LongClusterTransactionTests(QmfTestBase010):
-
- def test_txEnq10_locCluster_route_defaultExch(self):
- self._do_test(self._get_name(), enq_txn_size=10, msg_count = 103, local_cluster_flag=True)
-
- def test_txEnq10_locCluster_queueRoute_defaultExch(self):
- self._do_test(self._get_name(), queue_route_type_flag=True, enq_txn_size=10, msg_count = 103, local_cluster_flag=True)
-
- def test_txEnq10_remCluster_route_defaultExch(self):
- self._do_test(self._get_name(), enq_txn_size=10, msg_count = 103, remote_cluster_flag=True)
-
- def test_txEnq10_remCluster_queueRoute_defaultExch(self):
- self._do_test(self._get_name(), queue_route_type_flag=True, enq_txn_size=10, msg_count = 103, remote_cluster_flag=True)
-
- def test_txEnq10_locCluster_remCluster_route_defaultExch(self):
- self._do_test(self._get_name(), enq_txn_size=10, msg_count = 103, local_cluster_flag=True, remote_cluster_flag=True)
-
- def test_txEnq10_locCluster_remCluster_queueRoute_defaultExch(self):
- self._do_test(self._get_name(), queue_route_type_flag=True, enq_txn_size=10, msg_count = 103, local_cluster_flag=True, remote_cluster_flag=True)
-
-
- def test_txEnq01_locCluster_route_amqDirectExch(self):
- self._do_test(self._get_name(), exch_name="amq.direct", enq_txn_size=1, local_cluster_flag=True)
-
- def test_txEnq01_locCluster_queueRoute_amqDirectExch(self):
- self._do_test(self._get_name(), exch_name="amq.direct", queue_route_type_flag=True, enq_txn_size=1, local_cluster_flag=True)
-
- def test_txEnq10_locCluster_route_amqDirectExch(self):
- self._do_test(self._get_name(), exch_name="amq.direct", enq_txn_size=10, msg_count = 103, local_cluster_flag=True)
-
- def test_txEnq10_locCluster_queueRoute_amqDirectExch(self):
- self._do_test(self._get_name(), exch_name="amq.direct", queue_route_type_flag=True, enq_txn_size=10, msg_count = 103, local_cluster_flag=True)
-
- def test_txEnq01_txDeq01_locCluster_route_amqDirectExch(self):
- self._do_test(self._get_name(), exch_name="amq.direct", enq_txn_size=1, deq_txn_size=1, local_cluster_flag=True)
-
- def test_txEnq01_txDeq01_locCluster_queueRoute_amqDirectExch(self):
- self._do_test(self._get_name(), exch_name="amq.direct", queue_route_type_flag=True, enq_txn_size=1, deq_txn_size=1, local_cluster_flag=True)
-
- def test_txEnq01_remCluster_route_amqDirectExch(self):
- self._do_test(self._get_name(), exch_name="amq.direct", enq_txn_size=1, remote_cluster_flag=True)
-
- def test_txEnq01_remCluster_queueRoute_amqDirectExch(self):
- self._do_test(self._get_name(), exch_name="amq.direct", queue_route_type_flag=True, enq_txn_size=1, remote_cluster_flag=True)
-
- def test_txEnq10_remCluster_route_amqDirectExch(self):
- self._do_test(self._get_name(), exch_name="amq.direct", enq_txn_size=10, msg_count = 103, remote_cluster_flag=True)
-
- def test_txEnq10_remCluster_queueRoute_amqDirectExch(self):
- self._do_test(self._get_name(), exch_name="amq.direct", queue_route_type_flag=True, enq_txn_size=10, msg_count = 103, remote_cluster_flag=True)
-
- def test_txEnq01_txDeq01_remCluster_route_amqDirectExch(self):
- self._do_test(self._get_name(), exch_name="amq.direct", enq_txn_size=1, deq_txn_size=1, remote_cluster_flag=True)
-
- def test_txEnq01_txDeq01_remCluster_queueRoute_amqDirectExch(self):
- self._do_test(self._get_name(), exch_name="amq.direct", queue_route_type_flag=True, enq_txn_size=1, deq_txn_size=1, remote_cluster_flag=True)
-
- def test_txEnq01_locCluster_remCluster_route_amqDirectExch(self):
- self._do_test(self._get_name(), exch_name="amq.direct", enq_txn_size=1, local_cluster_flag=True, remote_cluster_flag=True)
-
- def test_txEnq01_locCluster_remCluster_queueRoute_amqDirectExch(self):
- self._do_test(self._get_name(), exch_name="amq.direct", queue_route_type_flag=True, enq_txn_size=1, local_cluster_flag=True, remote_cluster_flag=True)
-
- def test_txEnq10_locCluster_remCluster_route_amqDirectExch(self):
- self._do_test(self._get_name(), exch_name="amq.direct", enq_txn_size=10, msg_count = 103, local_cluster_flag=True, remote_cluster_flag=True)
-
- def test_txEnq10_locCluster_remCluster_queueRoute_amqDirectExch(self):
- self._do_test(self._get_name(), exch_name="amq.direct", queue_route_type_flag=True, enq_txn_size=10, msg_count = 103, local_cluster_flag=True, remote_cluster_flag=True)
-
- def test_txEnq01_txDeq01_locCluster_remCluster_route_amqDirectExch(self):
- self._do_test(self._get_name(), exch_name="amq.direct", enq_txn_size=1, deq_txn_size=1, local_cluster_flag=True, remote_cluster_flag=True)
-
- def test_txEnq01_txDeq01_locCluster_remCluster_queueRoute_amqDirectExch(self):
- self._do_test(self._get_name(), exch_name="amq.direct", queue_route_type_flag=True, enq_txn_size=1, deq_txn_size=1, local_cluster_flag=True, remote_cluster_flag=True)
-
-
- def test_txEnq01_locCluster_route_directExch(self):
- self._do_test(self._get_name(), exch_name="testDirectExchange", enq_txn_size=1, local_cluster_flag=True)
-
- def test_txEnq01_locCluster_queueRoute_directExch(self):
- self._do_test(self._get_name(), exch_name="testDirectExchange", queue_route_type_flag=True, enq_txn_size=1, local_cluster_flag=True)
-
- def test_txEnq10_locCluster_route_directExch(self):
- self._do_test(self._get_name(), exch_name="testDirectExchange", enq_txn_size=10, msg_count = 103, local_cluster_flag=True)
-
- def test_txEnq10_locCluster_queueRoute_directExch(self):
- self._do_test(self._get_name(), exch_name="testDirectExchange", queue_route_type_flag=True, enq_txn_size=10, msg_count = 103, local_cluster_flag=True)
-
- def test_txEnq01_txDeq01_locCluster_route_directExch(self):
- self._do_test(self._get_name(), exch_name="testDirectExchange", enq_txn_size=1, deq_txn_size=1, local_cluster_flag=True)
-
- def test_txEnq01_txDeq01_locCluster_queueRoute_directExch(self):
- self._do_test(self._get_name(), exch_name="testDirectExchange", queue_route_type_flag=True, enq_txn_size=1, deq_txn_size=1, local_cluster_flag=True)
-
- def test_txEnq01_remCluster_route_directExch(self):
- self._do_test(self._get_name(), exch_name="testDirectExchange", enq_txn_size=1, remote_cluster_flag=True)
-
- def test_txEnq01_remCluster_queueRoute_directExch(self):
- self._do_test(self._get_name(), exch_name="testDirectExchange", queue_route_type_flag=True, enq_txn_size=1, remote_cluster_flag=True)
-
- def test_txEnq10_remCluster_route_directExch(self):
- self._do_test(self._get_name(), exch_name="testDirectExchange", enq_txn_size=10, msg_count = 103, remote_cluster_flag=True)
-
- def test_txEnq10_remCluster_queueRoute_directExch(self):
- self._do_test(self._get_name(), exch_name="testDirectExchange", queue_route_type_flag=True, enq_txn_size=10, msg_count = 103, remote_cluster_flag=True)
-
- def test_txEnq01_txDeq01_remCluster_route_directExch(self):
- self._do_test(self._get_name(), exch_name="testDirectExchange", enq_txn_size=1, deq_txn_size=1, remote_cluster_flag=True)
-
- def test_txEnq01_txDeq01_remCluster_queueRoute_directExch(self):
- self._do_test(self._get_name(), exch_name="testDirectExchange", queue_route_type_flag=True, enq_txn_size=1, deq_txn_size=1, remote_cluster_flag=True)
-
- def test_txEnq01_locCluster_remCluster_route_directExch(self):
- self._do_test(self._get_name(), exch_name="testDirectExchange", enq_txn_size=1, local_cluster_flag=True, remote_cluster_flag=True)
-
- def test_txEnq01_locCluster_remCluster_queueRoute_directExch(self):
- self._do_test(self._get_name(), exch_name="testDirectExchange", queue_route_type_flag=True, enq_txn_size=1, local_cluster_flag=True, remote_cluster_flag=True)
-
- def test_txEnq10_locCluster_remCluster_route_directExch(self):
- self._do_test(self._get_name(), exch_name="testDirectExchange", enq_txn_size=10, msg_count = 103, local_cluster_flag=True, remote_cluster_flag=True)
-
- def test_txEnq10_locCluster_remCluster_queueRoute_directExch(self):
- self._do_test(self._get_name(), exch_name="testDirectExchange", queue_route_type_flag=True, enq_txn_size=10, msg_count = 103, local_cluster_flag=True, remote_cluster_flag=True)
-
- def test_txEnq01_txDeq01_locCluster_remCluster_route_directExch(self):
- self._do_test(self._get_name(), exch_name="testDirectExchange", enq_txn_size=1, deq_txn_size=1, local_cluster_flag=True, remote_cluster_flag=True)
-
- def test_txEnq01_txDeq01_locCluster_remCluster_queueRoute_directExch(self):
- self._do_test(self._get_name(), exch_name="testDirectExchange", queue_route_type_flag=True, enq_txn_size=1, deq_txn_size=1, local_cluster_flag=True, remote_cluster_flag=True)
-
-
- def test_txEnq01_locCluster_route_fanoutExch(self):
- self._do_test(self._get_name(), exch_name="testFanoutExchange", exch_type="fanout", enq_txn_size=1, local_cluster_flag=True)
-
- def test_txEnq01_locCluster_queueRoute_fanoutExch(self):
- self._do_test(self._get_name(), exch_name="testFanoutExchange", exch_type="fanout", queue_route_type_flag=True, enq_txn_size=1, local_cluster_flag=True)
-
- def test_txEnq10_locCluster_route_fanoutExch(self):
- self._do_test(self._get_name(), exch_name="testFanoutExchange", exch_type="fanout", enq_txn_size=10, msg_count = 103, local_cluster_flag=True)
-
- def test_txEnq10_locCluster_queueRoute_fanoutExch(self):
- self._do_test(self._get_name(), exch_name="testFanoutExchange", exch_type="fanout", queue_route_type_flag=True, enq_txn_size=10, msg_count = 103, local_cluster_flag=True)
-
- def test_txEnq01_txDeq01_locCluster_route_fanoutExch(self):
- self._do_test(self._get_name(), exch_name="testFanoutExchange", exch_type="fanout", enq_txn_size=1, deq_txn_size=1, local_cluster_flag=True)
-
- def test_txEnq01_txDeq01_locCluster_queueRoute_fanoutExch(self):
- self._do_test(self._get_name(), exch_name="testFanoutExchange", exch_type="fanout", queue_route_type_flag=True, enq_txn_size=1, deq_txn_size=1, local_cluster_flag=True)
-
- def test_txEnq01_remCluster_route_fanoutExch(self):
- self._do_test(self._get_name(), exch_name="testFanoutExchange", exch_type="fanout", enq_txn_size=1, remote_cluster_flag=True)
-
- def test_txEnq01_remCluster_queueRoute_fanoutExch(self):
- self._do_test(self._get_name(), exch_name="testFanoutExchange", exch_type="fanout", queue_route_type_flag=True, enq_txn_size=1, remote_cluster_flag=True)
-
- def test_txEnq10_remCluster_route_fanoutExch(self):
- self._do_test(self._get_name(), exch_name="testFanoutExchange", exch_type="fanout", enq_txn_size=10, msg_count = 103, remote_cluster_flag=True)
-
- def test_txEnq10_remCluster_queueRoute_fanoutExch(self):
- self._do_test(self._get_name(), exch_name="testFanoutExchange", exch_type="fanout", queue_route_type_flag=True, enq_txn_size=10, msg_count = 103, remote_cluster_flag=True)
-
- def test_txEnq01_txDeq01_remCluster_route_fanoutExch(self):
- self._do_test(self._get_name(), exch_name="testFanoutExchange", exch_type="fanout", enq_txn_size=1, deq_txn_size=1, remote_cluster_flag=True)
-
- def test_txEnq01_txDeq01_remCluster_queueRoute_fanoutExch(self):
- self._do_test(self._get_name(), exch_name="testFanoutExchange", exch_type="fanout", queue_route_type_flag=True, enq_txn_size=1, deq_txn_size=1, remote_cluster_flag=True)
-
- def test_txEnq01_locCluster_remCluster_route_fanoutExch(self):
- self._do_test(self._get_name(), exch_name="testFanoutExchange", exch_type="fanout", enq_txn_size=1, local_cluster_flag=True, remote_cluster_flag=True)
-
- def test_txEnq01_locCluster_remCluster_queueRoute_fanoutExch(self):
- self._do_test(self._get_name(), exch_name="testFanoutExchange", exch_type="fanout", queue_route_type_flag=True, enq_txn_size=1, local_cluster_flag=True, remote_cluster_flag=True)
-
- def test_txEnq10_locCluster_remCluster_route_fanoutExch(self):
- self._do_test(self._get_name(), exch_name="testFanoutExchange", exch_type="fanout", enq_txn_size=10, msg_count = 103, local_cluster_flag=True, remote_cluster_flag=True)
-
- def test_txEnq10_locCluster_remCluster_queueRoute_fanoutExch(self):
- self._do_test(self._get_name(), exch_name="testFanoutExchange", exch_type="fanout", queue_route_type_flag=True, enq_txn_size=10, msg_count = 103, local_cluster_flag=True, remote_cluster_flag=True)
-
- def test_txEnq01_txDeq01_locCluster_remCluster_route_fanoutExch(self):
- self._do_test(self._get_name(), exch_name="testFanoutExchange", exch_type="fanout", enq_txn_size=1, deq_txn_size=1, local_cluster_flag=True, remote_cluster_flag=True)
-
- def test_txEnq01_txDeq01_locCluster_remCluster_queueRoute_fanoutExch(self):
- self._do_test(self._get_name(), exch_name="testFanoutExchange", exch_type="fanout", queue_route_type_flag=True, enq_txn_size=1, deq_txn_size=1, local_cluster_flag=True, remote_cluster_flag=True)
-
-
- def test_txEnq01_locCluster_route_topicExch(self):
- self._do_test(self._get_name(), exch_name="testTopicExchange", exch_type="topic", topic_key=self._get_name()+".#", enq_txn_size=1, local_cluster_flag=True)
-
- def test_txEnq01_locCluster_queueRoute_topicExch(self):
- self._do_test(self._get_name(), exch_name="testTopicExchange", exch_type="topic", topic_key=self._get_name()+".#", queue_route_type_flag=True, enq_txn_size=1, local_cluster_flag=True)
-
- def test_txEnq10_locCluster_route_topicExch(self):
- self._do_test(self._get_name(), exch_name="testTopicExchange", exch_type="topic", topic_key=self._get_name()+".#", enq_txn_size=10, msg_count = 103, local_cluster_flag=True)
-
- def test_txEnq10_locCluster_queueRoute_topicExch(self):
- self._do_test(self._get_name(), exch_name="testTopicExchange", exch_type="topic", topic_key=self._get_name()+".#", queue_route_type_flag=True, enq_txn_size=10, msg_count = 103, local_cluster_flag=True)
-
- def test_txEnq01_txDeq01_locCluster_route_topicExch(self):
- self._do_test(self._get_name(), exch_name="testTopicExchange", exch_type="topic", topic_key=self._get_name()+".#", enq_txn_size=1, deq_txn_size=1, local_cluster_flag=True)
-
- def test_txEnq01_txDeq01_locCluster_queueRoute_topicExch(self):
- self._do_test(self._get_name(), exch_name="testTopicExchange", exch_type="topic", topic_key=self._get_name()+".#", queue_route_type_flag=True, enq_txn_size=1, deq_txn_size=1, local_cluster_flag=True)
-
- def test_txEnq01_remCluster_route_topicExch(self):
- self._do_test(self._get_name(), exch_name="testTopicExchange", exch_type="topic", topic_key=self._get_name()+".#", enq_txn_size=1, remote_cluster_flag=True)
-
- def test_txEnq01_remCluster_queueRoute_topicExch(self):
- self._do_test(self._get_name(), exch_name="testTopicExchange", exch_type="topic", topic_key=self._get_name()+".#", queue_route_type_flag=True, enq_txn_size=1, remote_cluster_flag=True)
-
- def test_txEnq10_remCluster_route_topicExch(self):
- self._do_test(self._get_name(), exch_name="testTopicExchange", exch_type="topic", topic_key=self._get_name()+".#", enq_txn_size=10, msg_count = 103, remote_cluster_flag=True)
-
- def test_txEnq10_remCluster_queueRoute_topicExch(self):
- self._do_test(self._get_name(), exch_name="testTopicExchange", exch_type="topic", topic_key=self._get_name()+".#", queue_route_type_flag=True, enq_txn_size=10, msg_count = 103, remote_cluster_flag=True)
-
- def test_txEnq01_txDeq01_remCluster_route_topicExch(self):
- self._do_test(self._get_name(), exch_name="testTopicExchange", exch_type="topic", topic_key=self._get_name()+".#", enq_txn_size=1, deq_txn_size=1, remote_cluster_flag=True)
-
- def test_txEnq01_txDeq01_remCluster_queueRoute_topicExch(self):
- self._do_test(self._get_name(), exch_name="testTopicExchange", exch_type="topic", topic_key=self._get_name()+".#", queue_route_type_flag=True, enq_txn_size=1, deq_txn_size=1, remote_cluster_flag=True)
-
- def test_txEnq01_locCluster_remCluster_route_topicExch(self):
- self._do_test(self._get_name(), exch_name="testTopicExchange", exch_type="topic", topic_key=self._get_name()+".#", enq_txn_size=1, local_cluster_flag=True, remote_cluster_flag=True)
-
- def test_txEnq01_locCluster_remCluster_queueRoute_topicExch(self):
- self._do_test(self._get_name(), exch_name="testTopicExchange", exch_type="topic", topic_key=self._get_name()+".#", queue_route_type_flag=True, enq_txn_size=1, local_cluster_flag=True, remote_cluster_flag=True)
-
- def test_txEnq10_locCluster_remCluster_route_topicExch(self):
- self._do_test(self._get_name(), exch_name="testTopicExchange", exch_type="topic", topic_key=self._get_name()+".#", enq_txn_size=10, msg_count = 103, local_cluster_flag=True, remote_cluster_flag=True)
-
- def test_txEnq10_locCluster_remCluster_queueRoute_topicExch(self):
- self._do_test(self._get_name(), exch_name="testTopicExchange", exch_type="topic", topic_key=self._get_name()+".#", queue_route_type_flag=True, enq_txn_size=10, msg_count = 103, local_cluster_flag=True, remote_cluster_flag=True)
-
- def test_txEnq01_txDeq01_locCluster_remCluster_route_topicExch(self):
- self._do_test(self._get_name(), exch_name="testTopicExchange", exch_type="topic", topic_key=self._get_name()+".#", enq_txn_size=1, deq_txn_size=1, local_cluster_flag=True, remote_cluster_flag=True)
-
- def test_txEnq01_txDeq01_locCluster_remCluster_queueRoute_topicExch(self):
- self._do_test(self._get_name(), exch_name="testTopicExchange", exch_type="topic", topic_key=self._get_name()+".#", queue_route_type_flag=True, enq_txn_size=1, deq_txn_size=1, local_cluster_flag=True, remote_cluster_flag=True)
-
-
-class E_ShortPersistenceTests(QmfTestBase010):
-
- def test_route_durQueue_defaultExch(self):
- self._do_test(self._get_name(), queue_durable_flag=True)
-
- def test_route_durMsg_durQueue_defaultExch(self):
- self._do_test(self._get_name(), msg_durable_flag=True, queue_durable_flag=True)
-
- def test_queueRoute_durQueue_defaultExch(self):
- self._do_test(self._get_name(), queue_durable_flag=True, queue_route_type_flag=True)
-
- def test_queueRoute_durMsg_durQueue_defaultExch(self):
- self._do_test(self._get_name(), msg_durable_flag=True, queue_durable_flag=True, queue_route_type_flag=True)
-
-
-class E_LongPersistenceTests(QmfTestBase010):
-
- def test_route_durQueue_amqDirectExch(self):
- self._do_test(self._get_name(), exch_name="amq.direct", queue_durable_flag=True)
-
- def test_route_durMsg_durQueue_amqDirectExch(self):
- self._do_test(self._get_name(), exch_name="amq.direct", msg_durable_flag=True, queue_durable_flag=True)
-
- def test_queueRoute_durQueue_amqDirectExch(self):
- self._do_test(self._get_name(), exch_name="amq.direct", queue_durable_flag=True, queue_route_type_flag=True)
-
- def test_queueRoute_durMsg_durQueue_amqDirectExch(self):
- self._do_test(self._get_name(), exch_name="amq.direct", msg_durable_flag=True, queue_durable_flag=True, queue_route_type_flag=True)
-
-
- def test_route_durQueue_directExch(self):
- self._do_test(self._get_name(), exch_name="testDirectExchange", queue_durable_flag=True)
-
- def test_route_durMsg_durQueue_directExch(self):
- self._do_test(self._get_name(), exch_name="testDirectExchange", msg_durable_flag=True, queue_durable_flag=True)
-
- def test_queueRoute_durQueue_directExch(self):
- self._do_test(self._get_name(), exch_name="testDirectExchange", queue_durable_flag=True, queue_route_type_flag=True)
-
- def test_queueRoute_durMsg_durQueue_directExch(self):
- self._do_test(self._get_name(), exch_name="testDirectExchange", msg_durable_flag=True, queue_durable_flag=True, queue_route_type_flag=True)
-
-
- def test_route_durQueue_fanoutExch(self):
- self._do_test(self._get_name(), exch_name="testFanoutExchange", exch_type="fanout", queue_durable_flag=True)
-
- def test_route_durMsg_durQueue_fanoutExch(self):
- self._do_test(self._get_name(), exch_name="testFanoutExchange", exch_type="fanout", msg_durable_flag=True, queue_durable_flag=True)
-
- def test_queueRoute_durQueue_fanoutExch(self):
- self._do_test(self._get_name(), exch_name="testFanoutExchange", exch_type="fanout", queue_durable_flag=True, queue_route_type_flag=True)
-
- def test_queueRoute_durMsg_durQueue_fanoutExch(self):
- self._do_test(self._get_name(), exch_name="testFanoutExchange", exch_type="fanout", msg_durable_flag=True, queue_durable_flag=True, queue_route_type_flag=True)
-
-
- def test_route_durQueue_topicExch(self):
- self._do_test(self._get_name(), exch_name="testTopicExchange", exch_type="topic", topic_key=self._get_name()+".#", queue_durable_flag=True)
-
- def test_route_durMsg_durQueue_topicExch(self):
- self._do_test(self._get_name(), exch_name="testTopicExchange", exch_type="topic", topic_key=self._get_name()+".#", msg_durable_flag=True, queue_durable_flag=True)
-
- def test_queueRoute_durQueue_topicExch(self):
- self._do_test(self._get_name(), exch_name="testTopicExchange", exch_type="topic", topic_key=self._get_name()+".#", queue_durable_flag=True, queue_route_type_flag=True)
-
- def test_queueRoute_durMsg_durQueue_topicExch(self):
- self._do_test(self._get_name(), exch_name="testTopicExchange", exch_type="topic", topic_key=self._get_name()+".#", msg_durable_flag=True, queue_durable_flag=True, queue_route_type_flag=True)
-
-
-class F_ShortPersistenceTransactionTests(QmfTestBase010):
-
- def test_txEnq01_route_durQueue_defaultExch(self):
- self._do_test(self._get_name(), queue_durable_flag=True, enq_txn_size=1)
-
- def test_txEnq01_route_durMsg_durQueue_defaultExch(self):
- self._do_test(self._get_name(), msg_durable_flag=True, queue_durable_flag=True, enq_txn_size=1)
-
- def test_txEnq01_queueRoute_durQueue_defaultExch(self):
- self._do_test(self._get_name(), queue_durable_flag=True, queue_route_type_flag=True, enq_txn_size=1)
-
- def test_txEnq01_queueRoute_durMsg_durQueue_defaultExch(self):
- self._do_test(self._get_name(), msg_durable_flag=True, queue_durable_flag=True, queue_route_type_flag=True, enq_txn_size=1)
-
- def test_txEnq01_txDeq01_route_durQueue_defaultExch(self):
- self._do_test(self._get_name(), queue_durable_flag=True, enq_txn_size=1, deq_txn_size=1)
-
- def test_txEnq01_txDeq01_route_durMsg_durQueue_defaultExch(self):
- self._do_test(self._get_name(), msg_durable_flag=True, queue_durable_flag=True, enq_txn_size=1, deq_txn_size=1)
-
- def test_txEnq01_txDeq01_queueRoute_durQueue_defaultExch(self):
- self._do_test(self._get_name(), queue_durable_flag=True, queue_route_type_flag=True, enq_txn_size=1, deq_txn_size=1)
-
- def test_txEnq01_txDeq01_queueRoute_durMsg_durQueue_defaultExch(self):
- self._do_test(self._get_name(), msg_durable_flag=True, queue_durable_flag=True, queue_route_type_flag=True, enq_txn_size=1, deq_txn_size=1)
-
-
-class F_LongPersistenceTransactionTests(QmfTestBase010):
-
- def test_txEnq10_route_durQueue_defaultExch(self):
- self._do_test(self._get_name(), queue_durable_flag=True, enq_txn_size=10, msg_count = 103)
-
- def test_txEnq10_route_durMsg_durQueue_defaultExch(self):
- self._do_test(self._get_name(), msg_durable_flag=True, queue_durable_flag=True, enq_txn_size=10, msg_count = 103)
-
- def test_txEnq10_queueRoute_durQueue_defaultExch(self):
- self._do_test(self._get_name(), queue_durable_flag=True, queue_route_type_flag=True, enq_txn_size=10, msg_count = 103)
-
- def test_txEnq10_queueRoute_durMsg_durQueue_defaultExch(self):
- self._do_test(self._get_name(), msg_durable_flag=True, queue_durable_flag=True, queue_route_type_flag=True, enq_txn_size=10, msg_count = 103)
-
-
- def test_txEnq01_route_durQueue_amqDirectExch(self):
- self._do_test(self._get_name(), exch_name="amq.direct", queue_durable_flag=True, enq_txn_size=1)
-
- def test_txEnq01_route_durMsg_durQueue_amqDirectExch(self):
- self._do_test(self._get_name(), exch_name="amq.direct", msg_durable_flag=True, queue_durable_flag=True, enq_txn_size=1)
-
- def test_txEnq01_queueRoute_durQueue_amqDirectExch(self):
- self._do_test(self._get_name(), exch_name="amq.direct", queue_durable_flag=True, queue_route_type_flag=True, enq_txn_size=1)
-
- def test_txEnq01_queueRoute_durMsg_durQueue_amqDirectExch(self):
- self._do_test(self._get_name(), exch_name="amq.direct", msg_durable_flag=True, queue_durable_flag=True, queue_route_type_flag=True, enq_txn_size=1)
-
- def test_txEnq10_route_durQueue_amqDirectExch(self):
- self._do_test(self._get_name(), exch_name="amq.direct", queue_durable_flag=True, enq_txn_size=10, msg_count = 103)
-
- def test_txEnq10_route_durMsg_durQueue_amqDirectExch(self):
- self._do_test(self._get_name(), exch_name="amq.direct", msg_durable_flag=True, queue_durable_flag=True, enq_txn_size=10, msg_count = 103)
-
- def test_txEnq10_queueRoute_durQueue_amqDirectExch(self):
- self._do_test(self._get_name(), exch_name="amq.direct", queue_durable_flag=True, queue_route_type_flag=True, enq_txn_size=10, msg_count = 103)
-
- def test_txEnq10_queueRoute_durMsg_durQueue_amqDirectExch(self):
- self._do_test(self._get_name(), exch_name="amq.direct", msg_durable_flag=True, queue_durable_flag=True, queue_route_type_flag=True, enq_txn_size=10, msg_count = 103)
-
- def test_txEnq01_txDeq01_route_durQueue_amqDirectExch(self):
- self._do_test(self._get_name(), exch_name="amq.direct", queue_durable_flag=True, enq_txn_size=1, deq_txn_size=1)
-
- def test_txEnq01_txDeq01_route_durMsg_durQueue_amqDirectExch(self):
- self._do_test(self._get_name(), exch_name="amq.direct", msg_durable_flag=True, queue_durable_flag=True, enq_txn_size=1, deq_txn_size=1)
-
- def test_txEnq01_txDeq01_queueRoute_durQueue_amqDirectExch(self):
- self._do_test(self._get_name(), exch_name="amq.direct", queue_durable_flag=True, queue_route_type_flag=True, enq_txn_size=1, deq_txn_size=1)
-
- def test_txEnq01_txDeq01_queueRoute_durMsg_durQueue_amqDirectExch(self):
- self._do_test(self._get_name(), exch_name="amq.direct", msg_durable_flag=True, queue_durable_flag=True, queue_route_type_flag=True, enq_txn_size=1, deq_txn_size=1)
-
-
- def test_txEnq01_route_durQueue_directExch(self):
- self._do_test(self._get_name(), exch_name="testDirectExchange", queue_durable_flag=True, enq_txn_size=1)
-
- def test_txEnq01_route_durMsg_durQueue_directExch(self):
- self._do_test(self._get_name(), exch_name="testDirectExchange", msg_durable_flag=True, queue_durable_flag=True, enq_txn_size=1)
-
- def test_txEnq01_queueRoute_durQueue_directExch(self):
- self._do_test(self._get_name(), exch_name="testDirectExchange", queue_durable_flag=True, queue_route_type_flag=True, enq_txn_size=1)
-
- def test_txEnq01_queueRoute_durMsg_durQueue_directExch(self):
- self._do_test(self._get_name(), exch_name="testDirectExchange", msg_durable_flag=True, queue_durable_flag=True, queue_route_type_flag=True, enq_txn_size=1)
-
- def test_txEnq10_route_durQueue_directExch(self):
- self._do_test(self._get_name(), exch_name="testDirectExchange", queue_durable_flag=True, enq_txn_size=10, msg_count = 103)
-
- def test_txEnq10_route_durMsg_durQueue_directExch(self):
- self._do_test(self._get_name(), exch_name="testDirectExchange", msg_durable_flag=True, queue_durable_flag=True, enq_txn_size=10, msg_count = 103)
-
- def test_txEnq10_queueRoute_durQueue_directExch(self):
- self._do_test(self._get_name(), exch_name="testDirectExchange", queue_durable_flag=True, queue_route_type_flag=True, enq_txn_size=10, msg_count = 103)
-
- def test_txEnq10_queueRoute_durMsg_durQueue_directExch(self):
- self._do_test(self._get_name(), exch_name="testDirectExchange", msg_durable_flag=True, queue_durable_flag=True, queue_route_type_flag=True, enq_txn_size=10, msg_count = 103)
-
- def test_txEnq01_txDeq01_route_durQueue_directExch(self):
- self._do_test(self._get_name(), exch_name="testDirectExchange", queue_durable_flag=True, enq_txn_size=1, deq_txn_size=1)
-
- def test_txEnq01_txDeq01_route_durMsg_durQueue_directExch(self):
- self._do_test(self._get_name(), exch_name="testDirectExchange", msg_durable_flag=True, queue_durable_flag=True, enq_txn_size=1, deq_txn_size=1)
-
- def test_txEnq01_txDeq01_queueRoute_durQueue_directExch(self):
- self._do_test(self._get_name(), exch_name="testDirectExchange", queue_durable_flag=True, queue_route_type_flag=True, enq_txn_size=1, deq_txn_size=1)
-
- def test_txEnq01_txDeq01_queueRoute_durMsg_durQueue_directExch(self):
- self._do_test(self._get_name(), exch_name="testDirectExchange", msg_durable_flag=True, queue_durable_flag=True, queue_route_type_flag=True, enq_txn_size=1, deq_txn_size=1)
-
-
- def test_txEnq01_route_durQueue_fanoutExch(self):
- self._do_test(self._get_name(), exch_name="testFanoutExchange", exch_type="fanout", queue_durable_flag=True, enq_txn_size=1)
-
- def test_txEnq01_route_durMsg_durQueue_fanoutExch(self):
- self._do_test(self._get_name(), exch_name="testFanoutExchange", exch_type="fanout", msg_durable_flag=True, queue_durable_flag=True, enq_txn_size=1)
-
- def test_txEnq01_queueRoute_durQueue_fanoutExch(self):
- self._do_test(self._get_name(), exch_name="testFanoutExchange", exch_type="fanout", queue_durable_flag=True, queue_route_type_flag=True, enq_txn_size=1)
-
- def test_txEnq01_queueRoute_durMsg_durQueue_fanoutExch(self):
- self._do_test(self._get_name(), exch_name="testFanoutExchange", exch_type="fanout", msg_durable_flag=True, queue_durable_flag=True, queue_route_type_flag=True, enq_txn_size=1)
-
- def test_txEnq10_route_durQueue_fanoutExch(self):
- self._do_test(self._get_name(), exch_name="testFanoutExchange", exch_type="fanout", queue_durable_flag=True, enq_txn_size=10, msg_count = 103)
-
- def test_txEnq10_route_durMsg_durQueue_fanoutExch(self):
- self._do_test(self._get_name(), exch_name="testFanoutExchange", exch_type="fanout", msg_durable_flag=True, queue_durable_flag=True, enq_txn_size=10, msg_count = 103)
-
- def test_txEnq10_queueRoute_durQueue_fanoutExch(self):
- self._do_test(self._get_name(), exch_name="testFanoutExchange", exch_type="fanout", queue_durable_flag=True, queue_route_type_flag=True, enq_txn_size=10, msg_count = 103)
-
- def test_txEnq10_queueRoute_durMsg_durQueue_fanoutExch(self):
- self._do_test(self._get_name(), exch_name="testFanoutExchange", exch_type="fanout", msg_durable_flag=True, queue_durable_flag=True, queue_route_type_flag=True, enq_txn_size=10, msg_count = 103)
-
- def test_txEnq01_txDeq01_route_durQueue_fanoutExch(self):
- self._do_test(self._get_name(), exch_name="testFanoutExchange", exch_type="fanout", queue_durable_flag=True, enq_txn_size=1, deq_txn_size=1)
-
- def test_txEnq01_txDeq01_route_durMsg_durQueue_fanoutExch(self):
- self._do_test(self._get_name(), exch_name="testFanoutExchange", exch_type="fanout", msg_durable_flag=True, queue_durable_flag=True, enq_txn_size=1, deq_txn_size=1)
-
- def test_txEnq01_txDeq01_queueRoute_durQueue_fanoutExch(self):
- self._do_test(self._get_name(), exch_name="testFanoutExchange", exch_type="fanout", queue_durable_flag=True, queue_route_type_flag=True, enq_txn_size=1, deq_txn_size=1)
-
- def test_txEnq01_txDeq01_queueRoute_durMsg_durQueue_fanoutExch(self):
- self._do_test(self._get_name(), exch_name="testFanoutExchange", exch_type="fanout", msg_durable_flag=True, queue_durable_flag=True, queue_route_type_flag=True, enq_txn_size=1, deq_txn_size=1)
-
-
- def test_txEnq01_route_durQueue_topicExch(self):
- self._do_test(self._get_name(), exch_name="testTopicExchange", exch_type="topic", topic_key=self._get_name()+".#", queue_durable_flag=True, enq_txn_size=1)
-
- def test_txEnq01_route_durMsg_durQueue_topicExch(self):
- self._do_test(self._get_name(), exch_name="testTopicExchange", exch_type="topic", topic_key=self._get_name()+".#", msg_durable_flag=True, queue_durable_flag=True, enq_txn_size=1)
-
- def test_txEnq01_queueRoute_durQueue_topicExch(self):
- self._do_test(self._get_name(), exch_name="testTopicExchange", exch_type="topic", topic_key=self._get_name()+".#", queue_durable_flag=True, queue_route_type_flag=True, enq_txn_size=1)
-
- def test_txEnq01_queueRoute_durMsg_durQueue_topicExch(self):
- self._do_test(self._get_name(), exch_name="testTopicExchange", exch_type="topic", topic_key=self._get_name()+".#", msg_durable_flag=True, queue_durable_flag=True, queue_route_type_flag=True, enq_txn_size=1)
-
- def test_txEnq10_route_durQueue_topicExch(self):
- self._do_test(self._get_name(), exch_name="testTopicExchange", exch_type="topic", topic_key=self._get_name()+".#", queue_durable_flag=True, enq_txn_size=10, msg_count = 103)
-
- def test_txEnq10_route_durMsg_durQueue_topicExch(self):
- self._do_test(self._get_name(), exch_name="testTopicExchange", exch_type="topic", topic_key=self._get_name()+".#", msg_durable_flag=True, queue_durable_flag=True, enq_txn_size=10, msg_count = 103)
-
- def test_txEnq10_queueRoute_durQueue_topicExch(self):
- self._do_test(self._get_name(), exch_name="testTopicExchange", exch_type="topic", topic_key=self._get_name()+".#", queue_durable_flag=True, queue_route_type_flag=True, enq_txn_size=10, msg_count = 103)
-
- def test_txEnq10_queueRoute_durMsg_durQueue_topicExch(self):
- self._do_test(self._get_name(), exch_name="testTopicExchange", exch_type="topic", topic_key=self._get_name()+".#", msg_durable_flag=True, queue_durable_flag=True, queue_route_type_flag=True, enq_txn_size=10, msg_count = 103)
-
- def test_txEnq01_txDeq01_route_durQueue_topicExch(self):
- self._do_test(self._get_name(), exch_name="testTopicExchange", exch_type="topic", topic_key=self._get_name()+".#", queue_durable_flag=True, enq_txn_size=1, deq_txn_size=1)
-
- def test_txEnq01_txDeq01_route_durMsg_durQueue_topicExch(self):
- self._do_test(self._get_name(), exch_name="testTopicExchange", exch_type="topic", topic_key=self._get_name()+".#", msg_durable_flag=True, queue_durable_flag=True, enq_txn_size=1, deq_txn_size=1)
-
- def test_txEnq01_txDeq01_queueRoute_durQueue_topicExch(self):
- self._do_test(self._get_name(), exch_name="testTopicExchange", exch_type="topic", topic_key=self._get_name()+".#", queue_durable_flag=True, queue_route_type_flag=True, enq_txn_size=1, deq_txn_size=1)
-
- def test_txEnq01_txDeq01_queueRoute_durMsg_durQueue_topicExch(self):
- self._do_test(self._get_name(), exch_name="testTopicExchange", exch_type="topic", topic_key=self._get_name()+".#", msg_durable_flag=True, queue_durable_flag=True, queue_route_type_flag=True, enq_txn_size=1, deq_txn_size=1)
-
-
-class G_ShortPersistenceClusterTests(QmfTestBase010):
-
- def test_locCluster_route_durQueue_defaultExch(self):
- self._do_test(self._get_name(), queue_durable_flag=True, local_cluster_flag=True)
-
- def test_locCluster_route_durMsg_durQueue_defaultExch(self):
- self._do_test(self._get_name(), msg_durable_flag=True, queue_durable_flag=True, local_cluster_flag=True)
-
- def test_locCluster_queueRoute_durQueue_defaultExch(self):
- self._do_test(self._get_name(), queue_durable_flag=True, queue_route_type_flag=True, local_cluster_flag=True)
-
- def test_locCluster_queueRoute_durMsg_durQueue_defaultExch(self):
- self._do_test(self._get_name(), msg_durable_flag=True, queue_durable_flag=True, queue_route_type_flag=True, local_cluster_flag=True)
-
- def test_remCluster_route_durQueue_defaultExch(self):
- self._do_test(self._get_name(), queue_durable_flag=True, remote_cluster_flag=True)
-
- def test_remCluster_route_durMsg_durQueue_defaultExch(self):
- self._do_test(self._get_name(), msg_durable_flag=True, queue_durable_flag=True, remote_cluster_flag=True)
-
- def test_remCluster_queueRoute_durQueue_defaultExch(self):
- self._do_test(self._get_name(), queue_durable_flag=True, queue_route_type_flag=True, remote_cluster_flag=True)
-
- def test_remCluster_queueRoute_durMsg_durQueue_defaultExch(self):
- self._do_test(self._get_name(), msg_durable_flag=True, queue_durable_flag=True, queue_route_type_flag=True, remote_cluster_flag=True)
-
- def test_locCluster_remCluster_route_durQueue_defaultExch(self):
- self._do_test(self._get_name(), queue_durable_flag=True, local_cluster_flag=True, remote_cluster_flag=True)
-
- def test_locCluster_remCluster_route_durMsg_durQueue_defaultExch(self):
- self._do_test(self._get_name(), msg_durable_flag=True, queue_durable_flag=True, local_cluster_flag=True, remote_cluster_flag=True)
-
- def test_locCluster_remCluster_queueRoute_durQueue_defaultExch(self):
- self._do_test(self._get_name(), queue_durable_flag=True, queue_route_type_flag=True, local_cluster_flag=True, remote_cluster_flag=True)
-
- def test_locCluster_remCluster_queueRoute_durMsg_durQueue_defaultExch(self):
- self._do_test(self._get_name(), msg_durable_flag=True, queue_durable_flag=True, queue_route_type_flag=True, local_cluster_flag=True, remote_cluster_flag=True)
-
-
-class G_LongPersistenceClusterTests(QmfTestBase010):
-
- def test_locCluster_route_durQueue_amqDirectExch(self):
- self._do_test(self._get_name(), exch_name="amq.direct", queue_durable_flag=True, local_cluster_flag=True)
-
- def test_locCluster_route_durMsg_durQueue_amqDirectExch(self):
- self._do_test(self._get_name(), exch_name="amq.direct", msg_durable_flag=True, queue_durable_flag=True, local_cluster_flag=True)
-
- def test_locCluster_queueRoute_durQueue_amqDirectExch(self):
- self._do_test(self._get_name(), exch_name="amq.direct", queue_durable_flag=True, queue_route_type_flag=True, local_cluster_flag=True)
-
- def test_locCluster_queueRoute_durMsg_durQueue_amqDirectExch(self):
- self._do_test(self._get_name(), exch_name="amq.direct", msg_durable_flag=True, queue_durable_flag=True, queue_route_type_flag=True, local_cluster_flag=True)
-
- def test_remCluster_route_durQueue_amqDirectExch(self):
- self._do_test(self._get_name(), exch_name="amq.direct", queue_durable_flag=True, remote_cluster_flag=True)
-
- def test_remCluster_route_durMsg_durQueue_amqDirectExch(self):
- self._do_test(self._get_name(), exch_name="amq.direct", msg_durable_flag=True, queue_durable_flag=True, remote_cluster_flag=True)
-
- def test_remCluster_queueRoute_durQueue_amqDirectExch(self):
- self._do_test(self._get_name(), exch_name="amq.direct", queue_durable_flag=True, queue_route_type_flag=True, remote_cluster_flag=True)
-
- def test_remCluster_queueRoute_durMsg_durQueue_amqDirectExch(self):
- self._do_test(self._get_name(), exch_name="amq.direct", msg_durable_flag=True, queue_durable_flag=True, queue_route_type_flag=True, remote_cluster_flag=True)
-
- def test_locCluster_remCluster_route_durQueue_amqDirectExch(self):
- self._do_test(self._get_name(), exch_name="amq.direct", queue_durable_flag=True, local_cluster_flag=True, remote_cluster_flag=True)
-
- def test_locCluster_remCluster_route_durMsg_durQueue_amqDirectExch(self):
- self._do_test(self._get_name(), exch_name="amq.direct", msg_durable_flag=True, queue_durable_flag=True, local_cluster_flag=True, remote_cluster_flag=True)
-
- def test_locCluster_remCluster_queueRoute_durQueue_amqDirectExch(self):
- self._do_test(self._get_name(), exch_name="amq.direct", queue_durable_flag=True, queue_route_type_flag=True, local_cluster_flag=True, remote_cluster_flag=True)
-
- def test_locCluster_remCluster_queueRoute_durMsg_durQueue_amqDirectExch(self):
- self._do_test(self._get_name(), exch_name="amq.direct", msg_durable_flag=True, queue_durable_flag=True, queue_route_type_flag=True, local_cluster_flag=True, remote_cluster_flag=True)
-
-
- def test_locCluster_route_durQueue_directExch(self):
- self._do_test(self._get_name(), exch_name="testDirectExchange", queue_durable_flag=True, local_cluster_flag=True)
-
- def test_locCluster_route_durMsg_durQueue_directExch(self):
- self._do_test(self._get_name(), exch_name="testDirectExchange", msg_durable_flag=True, queue_durable_flag=True, local_cluster_flag=True)
-
- def test_locCluster_queueRoute_durQueue_directExch(self):
- self._do_test(self._get_name(), exch_name="testDirectExchange", queue_durable_flag=True, queue_route_type_flag=True, local_cluster_flag=True)
-
- def test_locCluster_queueRoute_durMsg_durQueue_directExch(self):
- self._do_test(self._get_name(), exch_name="testDirectExchange", msg_durable_flag=True, queue_durable_flag=True, queue_route_type_flag=True, local_cluster_flag=True)
-
- def test_remCluster_route_durQueue_directExch(self):
- self._do_test(self._get_name(), exch_name="testDirectExchange", queue_durable_flag=True, remote_cluster_flag=True)
-
- def test_remCluster_route_durMsg_durQueue_directExch(self):
- self._do_test(self._get_name(), exch_name="testDirectExchange", msg_durable_flag=True, queue_durable_flag=True, remote_cluster_flag=True)
-
- def test_remCluster_queueRoute_durQueue_directExch(self):
- self._do_test(self._get_name(), exch_name="testDirectExchange", queue_durable_flag=True, queue_route_type_flag=True, remote_cluster_flag=True)
-
- def test_remCluster_queueRoute_durMsg_durQueue_directExch(self):
- self._do_test(self._get_name(), exch_name="testDirectExchange", msg_durable_flag=True, queue_durable_flag=True, queue_route_type_flag=True, remote_cluster_flag=True)
-
- def test_locCluster_remCluster_route_durQueue_directExch(self):
- self._do_test(self._get_name(), exch_name="testDirectExchange", queue_durable_flag=True, local_cluster_flag=True, remote_cluster_flag=True)
-
- def test_locCluster_remCluster_route_durMsg_durQueue_directExch(self):
- self._do_test(self._get_name(), exch_name="testDirectExchange", msg_durable_flag=True, queue_durable_flag=True, local_cluster_flag=True, remote_cluster_flag=True)
-
- def test_locCluster_remCluster_queueRoute_durQueue_directExch(self):
- self._do_test(self._get_name(), exch_name="testDirectExchange", queue_durable_flag=True, queue_route_type_flag=True, local_cluster_flag=True, remote_cluster_flag=True)
-
- def test_locCluster_remCluster_queueRoute_durMsg_durQueue_directExch(self):
- self._do_test(self._get_name(), exch_name="testDirectExchange", msg_durable_flag=True, queue_durable_flag=True, queue_route_type_flag=True, local_cluster_flag=True, remote_cluster_flag=True)
-
-
- def test_locCluster_route_durQueue_fanoutExch(self):
- self._do_test(self._get_name(), exch_name="testFanoutExchange", exch_type="fanout", queue_durable_flag=True, local_cluster_flag=True)
-
- def test_locCluster_route_durMsg_durQueue_fanoutExch(self):
- self._do_test(self._get_name(), exch_name="testFanoutExchange", exch_type="fanout", msg_durable_flag=True, queue_durable_flag=True, local_cluster_flag=True)
-
- def test_locCluster_queueRoute_durQueue_fanoutExch(self):
- self._do_test(self._get_name(), exch_name="testFanoutExchange", exch_type="fanout", queue_durable_flag=True, queue_route_type_flag=True, local_cluster_flag=True)
-
- def test_locCluster_queueRoute_durMsg_durQueue_fanoutExch(self):
- self._do_test(self._get_name(), exch_name="testFanoutExchange", exch_type="fanout", msg_durable_flag=True, queue_durable_flag=True, queue_route_type_flag=True, local_cluster_flag=True)
-
- def test_remCluster_route_durQueue_fanoutExch(self):
- self._do_test(self._get_name(), exch_name="testFanoutExchange", exch_type="fanout", queue_durable_flag=True, remote_cluster_flag=True)
-
- def test_remCluster_route_durMsg_durQueue_fanoutExch(self):
- self._do_test(self._get_name(), exch_name="testFanoutExchange", exch_type="fanout", msg_durable_flag=True, queue_durable_flag=True, remote_cluster_flag=True)
-
- def test_remCluster_queueRoute_durQueue_fanoutExch(self):
- self._do_test(self._get_name(), exch_name="testFanoutExchange", exch_type="fanout", queue_durable_flag=True, queue_route_type_flag=True, remote_cluster_flag=True)
-
- def test_remCluster_queueRoute_durMsg_durQueue_fanoutExch(self):
- self._do_test(self._get_name(), exch_name="testFanoutExchange", exch_type="fanout", msg_durable_flag=True, queue_durable_flag=True, queue_route_type_flag=True, remote_cluster_flag=True)
-
- def test_locCluster_remCluster_route_durQueue_fanoutExch(self):
- self._do_test(self._get_name(), exch_name="testFanoutExchange", exch_type="fanout", queue_durable_flag=True, local_cluster_flag=True, remote_cluster_flag=True)
-
- def test_locCluster_remCluster_route_durMsg_durQueue_fanoutExch(self):
- self._do_test(self._get_name(), exch_name="testFanoutExchange", exch_type="fanout", msg_durable_flag=True, queue_durable_flag=True, local_cluster_flag=True, remote_cluster_flag=True)
-
- def test_locCluster_remCluster_queueRoute_durQueue_fanoutExch(self):
- self._do_test(self._get_name(), exch_name="testFanoutExchange", exch_type="fanout", queue_durable_flag=True, queue_route_type_flag=True, local_cluster_flag=True, remote_cluster_flag=True)
-
- def test_locCluster_remCluster_queueRoute_durMsg_durQueue_fanoutExch(self):
- self._do_test(self._get_name(), exch_name="testFanoutExchange", exch_type="fanout", msg_durable_flag=True, queue_durable_flag=True, queue_route_type_flag=True, local_cluster_flag=True, remote_cluster_flag=True)
-
-
- def test_locCluster_route_durQueue_topicExch(self):
- self._do_test(self._get_name(), exch_name="testTopicExchange", exch_type="topic", topic_key=self._get_name()+".#", queue_durable_flag=True, local_cluster_flag=True)
-
- def test_locCluster_route_durMsg_durQueue_topicExch(self):
- self._do_test(self._get_name(), exch_name="testTopicExchange", exch_type="topic", topic_key=self._get_name()+".#", msg_durable_flag=True, queue_durable_flag=True, local_cluster_flag=True)
-
- def test_locCluster_queueRoute_durQueue_topicExch(self):
- self._do_test(self._get_name(), exch_name="testTopicExchange", exch_type="topic", topic_key=self._get_name()+".#", queue_durable_flag=True, queue_route_type_flag=True, local_cluster_flag=True)
-
- def test_locCluster_queueRoute_durMsg_durQueue_topicExch(self):
- self._do_test(self._get_name(), exch_name="testTopicExchange", exch_type="topic", topic_key=self._get_name()+".#", msg_durable_flag=True, queue_durable_flag=True, queue_route_type_flag=True, local_cluster_flag=True)
-
- def test_remCluster_route_durQueue_topicExch(self):
- self._do_test(self._get_name(), exch_name="testTopicExchange", exch_type="topic", topic_key=self._get_name()+".#", queue_durable_flag=True, remote_cluster_flag=True)
-
- def test_remCluster_route_durMsg_durQueue_topicExch(self):
- self._do_test(self._get_name(), exch_name="testTopicExchange", exch_type="topic", topic_key=self._get_name()+".#", msg_durable_flag=True, queue_durable_flag=True, remote_cluster_flag=True)
-
- def test_remCluster_queueRoute_durQueue_topicExch(self):
- self._do_test(self._get_name(), exch_name="testTopicExchange", exch_type="topic", topic_key=self._get_name()+".#", queue_durable_flag=True, queue_route_type_flag=True, remote_cluster_flag=True)
-
- def test_remCluster_queueRoute_durMsg_durQueue_topicExch(self):
- self._do_test(self._get_name(), exch_name="testTopicExchange", exch_type="topic", topic_key=self._get_name()+".#", msg_durable_flag=True, queue_durable_flag=True, queue_route_type_flag=True, remote_cluster_flag=True)
-
- def test_locCluster_remCluster_route_durQueue_topicExch(self):
- self._do_test(self._get_name(), exch_name="testTopicExchange", exch_type="topic", topic_key=self._get_name()+".#", queue_durable_flag=True, local_cluster_flag=True, remote_cluster_flag=True)
-
- def test_locCluster_remCluster_route_durMsg_durQueue_topicExch(self):
- self._do_test(self._get_name(), exch_name="testTopicExchange", exch_type="topic", topic_key=self._get_name()+".#", msg_durable_flag=True, queue_durable_flag=True, local_cluster_flag=True, remote_cluster_flag=True)
-
- def test_locCluster_remCluster_queueRoute_durQueue_topicExch(self):
- self._do_test(self._get_name(), exch_name="testTopicExchange", exch_type="topic", topic_key=self._get_name()+".#", queue_durable_flag=True, queue_route_type_flag=True, local_cluster_flag=True, remote_cluster_flag=True)
-
- def test_locCluster_remCluster_queueRoute_durMsg_durQueue_topicExch(self):
- self._do_test(self._get_name(), exch_name="testTopicExchange", exch_type="topic", topic_key=self._get_name()+".#", msg_durable_flag=True, queue_durable_flag=True, queue_route_type_flag=True, local_cluster_flag=True, remote_cluster_flag=True)
-
-
-class H_ShortPersistenceClusterTransactionTests(QmfTestBase010):
-
- def test_txEnq01_locCluster_route_durQueue_defaultExch(self):
- self._do_test(self._get_name(), queue_durable_flag=True, enq_txn_size=1, local_cluster_flag=True)
-
- def test_txEnq01_locCluster_route_durMsg_durQueue_defaultExch(self):
- self._do_test(self._get_name(), msg_durable_flag=True, queue_durable_flag=True, enq_txn_size=1, local_cluster_flag=True)
-
- def test_txEnq01_locCluster_queueRoute_durQueue_defaultExch(self):
- self._do_test(self._get_name(), queue_durable_flag=True, queue_route_type_flag=True, enq_txn_size=1, local_cluster_flag=True)
-
- def test_txEnq01_locCluster_queueRoute_durMsg_durQueue_defaultExch(self):
- self._do_test(self._get_name(), msg_durable_flag=True, queue_durable_flag=True, queue_route_type_flag=True, enq_txn_size=1, local_cluster_flag=True)
-
- def test_txEnq01_txDeq01_locCluster_route_durQueue_defaultExch(self):
- self._do_test(self._get_name(), queue_durable_flag=True, enq_txn_size=1, deq_txn_size=1, local_cluster_flag=True)
-
- def test_txEnq01_txDeq01_locCluster_route_durMsg_durQueue_defaultExch(self):
- self._do_test(self._get_name(), msg_durable_flag=True, queue_durable_flag=True, enq_txn_size=1, deq_txn_size=1, local_cluster_flag=True)
-
- def test_txEnq01_txDeq01_locCluster_queueRoute_durQueue_defaultExch(self):
- self._do_test(self._get_name(), queue_durable_flag=True, queue_route_type_flag=True, enq_txn_size=1, deq_txn_size=1, local_cluster_flag=True)
-
- def test_txEnq01_txDeq01_locCluster_queueRoute_durMsg_durQueue_defaultExch(self):
- self._do_test(self._get_name(), msg_durable_flag=True, queue_durable_flag=True, queue_route_type_flag=True, enq_txn_size=1, deq_txn_size=1, local_cluster_flag=True)
-
- def test_txEnq01_remCluster_route_durQueue_defaultExch(self):
- self._do_test(self._get_name(), queue_durable_flag=True, enq_txn_size=1, remote_cluster_flag=True)
-
- def test_txEnq01_remCluster_route_durMsg_durQueue_defaultExch(self):
- self._do_test(self._get_name(), msg_durable_flag=True, queue_durable_flag=True, enq_txn_size=1, remote_cluster_flag=True)
-
- def test_txEnq01_remCluster_queueRoute_durQueue_defaultExch(self):
- self._do_test(self._get_name(), queue_durable_flag=True, queue_route_type_flag=True, enq_txn_size=1, remote_cluster_flag=True)
-
- def test_txEnq01_remCluster_queueRoute_durMsg_durQueue_defaultExch(self):
- self._do_test(self._get_name(), msg_durable_flag=True, queue_durable_flag=True, queue_route_type_flag=True, enq_txn_size=1, remote_cluster_flag=True)
-
- def test_txEnq01_txDeq01_remCluster_route_durQueue_defaultExch(self):
- self._do_test(self._get_name(), queue_durable_flag=True, enq_txn_size=1, deq_txn_size=1, remote_cluster_flag=True)
-
- def test_txEnq01_txDeq01_remCluster_route_durMsg_durQueue_defaultExch(self):
- self._do_test(self._get_name(), msg_durable_flag=True, queue_durable_flag=True, enq_txn_size=1, deq_txn_size=1, remote_cluster_flag=True)
-
- def test_txEnq01_txDeq01_remCluster_queueRoute_durQueue_defaultExch(self):
- self._do_test(self._get_name(), queue_durable_flag=True, queue_route_type_flag=True, enq_txn_size=1, deq_txn_size=1, remote_cluster_flag=True)
-
- def test_txEnq01_txDeq01_remCluster_queueRoute_durMsg_durQueue_defaultExch(self):
- self._do_test(self._get_name(), msg_durable_flag=True, queue_durable_flag=True, queue_route_type_flag=True, enq_txn_size=1, deq_txn_size=1, remote_cluster_flag=True)
-
- def test_txEnq01_locCluster_remCluster_route_durQueue_defaultExch(self):
- self._do_test(self._get_name(), queue_durable_flag=True, enq_txn_size=1, local_cluster_flag=True, remote_cluster_flag=True)
-
- def test_txEnq01_locCluster_remCluster_route_durMsg_durQueue_defaultExch(self):
- self._do_test(self._get_name(), msg_durable_flag=True, queue_durable_flag=True, enq_txn_size=1, local_cluster_flag=True, remote_cluster_flag=True)
-
- def test_txEnq01_locCluster_remCluster_queueRoute_durQueue_defaultExch(self):
- self._do_test(self._get_name(), queue_durable_flag=True, queue_route_type_flag=True, enq_txn_size=1, local_cluster_flag=True, remote_cluster_flag=True)
-
- def test_txEnq01_locCluster_remCluster_queueRoute_durMsg_durQueue_defaultExch(self):
- self._do_test(self._get_name(), msg_durable_flag=True, queue_durable_flag=True, queue_route_type_flag=True, enq_txn_size=1, local_cluster_flag=True, remote_cluster_flag=True)
-
- def test_txEnq01_txDeq01_locCluster_remCluster_route_durQueue_defaultExch(self):
- self._do_test(self._get_name(), queue_durable_flag=True, enq_txn_size=1, deq_txn_size=1, local_cluster_flag=True, remote_cluster_flag=True)
-
- def test_txEnq01_txDeq01_locCluster_remCluster_route_durMsg_durQueue_defaultExch(self):
- self._do_test(self._get_name(), msg_durable_flag=True, queue_durable_flag=True, enq_txn_size=1, deq_txn_size=1, local_cluster_flag=True, remote_cluster_flag=True)
-
- def test_txEnq01_txDeq01_locCluster_remCluster_queueRoute_durQueue_defaultExch(self):
- self._do_test(self._get_name(), queue_durable_flag=True, queue_route_type_flag=True, enq_txn_size=1, deq_txn_size=1, local_cluster_flag=True, remote_cluster_flag=True)
-
- def test_txEnq01_txDeq01_locCluster_remCluster_queueRoute_durMsg_durQueue_defaultExch(self):
- self._do_test(self._get_name(), msg_durable_flag=True, queue_durable_flag=True, queue_route_type_flag=True, enq_txn_size=1, deq_txn_size=1, local_cluster_flag=True, remote_cluster_flag=True)
-
-
-class H_LongPersistenceClusterTransactionTests(QmfTestBase010):
-
- def test_txEnq10_locCluster_route_durQueue_defaultExch(self):
- self._do_test(self._get_name(), queue_durable_flag=True, enq_txn_size=10, msg_count = 103, local_cluster_flag=True)
-
- def test_txEnq10_locCluster_route_durMsg_durQueue_defaultExch(self):
- self._do_test(self._get_name(), msg_durable_flag=True, queue_durable_flag=True, enq_txn_size=10, msg_count = 103, local_cluster_flag=True)
-
- def test_txEnq10_locCluster_queueRoute_durQueue_defaultExch(self):
- self._do_test(self._get_name(), queue_durable_flag=True, queue_route_type_flag=True, enq_txn_size=10, msg_count = 103, local_cluster_flag=True)
-
- def test_txEnq10_locCluster_queueRoute_durMsg_durQueue_defaultExch(self):
- self._do_test(self._get_name(), msg_durable_flag=True, queue_durable_flag=True, queue_route_type_flag=True, enq_txn_size=10, msg_count = 103, local_cluster_flag=True)
-
- def test_txEnq10_remCluster_route_durQueue_defaultExch(self):
- self._do_test(self._get_name(), queue_durable_flag=True, enq_txn_size=10, msg_count = 103, remote_cluster_flag=True)
-
- def test_txEnq10_remCluster_route_durMsg_durQueue_defaultExch(self):
- self._do_test(self._get_name(), msg_durable_flag=True, queue_durable_flag=True, enq_txn_size=10, msg_count = 103, remote_cluster_flag=True)
-
- def test_txEnq10_remCluster_queueRoute_durQueue_defaultExch(self):
- self._do_test(self._get_name(), queue_durable_flag=True, queue_route_type_flag=True, enq_txn_size=10, msg_count = 103, remote_cluster_flag=True)
-
- def test_txEnq10_remCluster_queueRoute_durMsg_durQueue_defaultExch(self):
- self._do_test(self._get_name(), msg_durable_flag=True, queue_durable_flag=True, queue_route_type_flag=True, enq_txn_size=10, msg_count = 103, remote_cluster_flag=True)
-
- def test_txEnq10_locCluster_remCluster_route_durQueue_defaultExch(self):
- self._do_test(self._get_name(), queue_durable_flag=True, enq_txn_size=10, msg_count = 103, local_cluster_flag=True, remote_cluster_flag=True)
-
- def test_txEnq10_locCluster_remCluster_route_durMsg_durQueue_defaultExch(self):
- self._do_test(self._get_name(), msg_durable_flag=True, queue_durable_flag=True, enq_txn_size=10, msg_count = 103, local_cluster_flag=True, remote_cluster_flag=True)
-
- def test_txEnq10_locCluster_remCluster_queueRoute_durQueue_defaultExch(self):
- self._do_test(self._get_name(), queue_durable_flag=True, queue_route_type_flag=True, enq_txn_size=10, msg_count = 103, local_cluster_flag=True, remote_cluster_flag=True)
-
- def test_txEnq10_locCluster_remCluster_queueRoute_durMsg_durQueue_defaultExch(self):
- self._do_test(self._get_name(), msg_durable_flag=True, queue_durable_flag=True, queue_route_type_flag=True, enq_txn_size=10, msg_count = 103, local_cluster_flag=True, remote_cluster_flag=True)
-
-
- def test_txEnq01_locCluster_route_durQueue_amqDirectExch(self):
- self._do_test(self._get_name(), exch_name="amq.direct", queue_durable_flag=True, enq_txn_size=1, local_cluster_flag=True)
-
- def test_txEnq01_locCluster_route_durMsg_durQueue_amqDirectExch(self):
- self._do_test(self._get_name(), exch_name="amq.direct", msg_durable_flag=True, queue_durable_flag=True, enq_txn_size=1, local_cluster_flag=True)
-
- def test_txEnq01_locCluster_queueRoute_durQueue_amqDirectExch(self):
- self._do_test(self._get_name(), exch_name="amq.direct", queue_durable_flag=True, queue_route_type_flag=True, enq_txn_size=1, local_cluster_flag=True)
-
- def test_txEnq01_locCluster_queueRoute_durMsg_durQueue_amqDirectExch(self):
- self._do_test(self._get_name(), exch_name="amq.direct", msg_durable_flag=True, queue_durable_flag=True, queue_route_type_flag=True, enq_txn_size=1, local_cluster_flag=True)
-
- def test_txEnq10_locCluster_route_durQueue_amqDirectExch(self):
- self._do_test(self._get_name(), exch_name="amq.direct", queue_durable_flag=True, enq_txn_size=10, msg_count = 103, local_cluster_flag=True)
-
- def test_txEnq10_locCluster_route_durMsg_durQueue_amqDirectExch(self):
- self._do_test(self._get_name(), exch_name="amq.direct", msg_durable_flag=True, queue_durable_flag=True, enq_txn_size=10, msg_count = 103, local_cluster_flag=True)
-
- def test_txEnq10_locCluster_queueRoute_durQueue_amqDirectExch(self):
- self._do_test(self._get_name(), exch_name="amq.direct", queue_durable_flag=True, queue_route_type_flag=True, enq_txn_size=10, msg_count = 103, local_cluster_flag=True)
-
- def test_txEnq10_locCluster_queueRoute_durMsg_durQueue_amqDirectExch(self):
- self._do_test(self._get_name(), exch_name="amq.direct", msg_durable_flag=True, queue_durable_flag=True, queue_route_type_flag=True, enq_txn_size=10, msg_count = 103, local_cluster_flag=True)
-
- def test_txEnq01_txDeq01_locCluster_route_durQueue_amqDirectExch(self):
- self._do_test(self._get_name(), exch_name="amq.direct", queue_durable_flag=True, enq_txn_size=1, deq_txn_size=1, local_cluster_flag=True)
-
- def test_txEnq01_txDeq01_locCluster_route_durMsg_durQueue_amqDirectExch(self):
- self._do_test(self._get_name(), exch_name="amq.direct", msg_durable_flag=True, queue_durable_flag=True, enq_txn_size=1, deq_txn_size=1, local_cluster_flag=True)
-
- def test_txEnq01_txDeq01_locCluster_queueRoute_durQueue_amqDirectExch(self):
- self._do_test(self._get_name(), exch_name="amq.direct", queue_durable_flag=True, queue_route_type_flag=True, enq_txn_size=1, deq_txn_size=1, local_cluster_flag=True)
-
- def test_txEnq01_txDeq01_locCluster_queueRoute_durMsg_durQueue_amqDirectExch(self):
- self._do_test(self._get_name(), exch_name="amq.direct", msg_durable_flag=True, queue_durable_flag=True, queue_route_type_flag=True, enq_txn_size=1, deq_txn_size=1, local_cluster_flag=True)
-
- def test_txEnq01_remCluster_route_durQueue_amqDirectExch(self):
- self._do_test(self._get_name(), exch_name="amq.direct", queue_durable_flag=True, enq_txn_size=1, remote_cluster_flag=True)
-
- def test_txEnq01_remCluster_route_durMsg_durQueue_amqDirectExch(self):
- self._do_test(self._get_name(), exch_name="amq.direct", msg_durable_flag=True, queue_durable_flag=True, enq_txn_size=1, remote_cluster_flag=True)
-
- def test_txEnq01_remCluster_queueRoute_durQueue_amqDirectExch(self):
- self._do_test(self._get_name(), exch_name="amq.direct", queue_durable_flag=True, queue_route_type_flag=True, enq_txn_size=1, remote_cluster_flag=True)
-
- def test_txEnq01_remCluster_queueRoute_durMsg_durQueue_amqDirectExch(self):
- self._do_test(self._get_name(), exch_name="amq.direct", msg_durable_flag=True, queue_durable_flag=True, queue_route_type_flag=True, enq_txn_size=1, remote_cluster_flag=True)
-
- def test_txEnq10_remCluster_route_durQueue_amqDirectExch(self):
- self._do_test(self._get_name(), exch_name="amq.direct", queue_durable_flag=True, enq_txn_size=10, msg_count = 103, remote_cluster_flag=True)
-
- def test_txEnq10_remCluster_route_durMsg_durQueue_amqDirectExch(self):
- self._do_test(self._get_name(), exch_name="amq.direct", msg_durable_flag=True, queue_durable_flag=True, enq_txn_size=10, msg_count = 103, remote_cluster_flag=True)
-
- def test_txEnq10_remCluster_queueRoute_durQueue_amqDirectExch(self):
- self._do_test(self._get_name(), exch_name="amq.direct", queue_durable_flag=True, queue_route_type_flag=True, enq_txn_size=10, msg_count = 103, remote_cluster_flag=True)
-
- def test_txEnq10_remCluster_queueRoute_durMsg_durQueue_amqDirectExch(self):
- self._do_test(self._get_name(), exch_name="amq.direct", msg_durable_flag=True, queue_durable_flag=True, queue_route_type_flag=True, enq_txn_size=10, msg_count = 103, remote_cluster_flag=True)
-
- def test_txEnq01_txDeq01_remCluster_route_durQueue_amqDirectExch(self):
- self._do_test(self._get_name(), exch_name="amq.direct", queue_durable_flag=True, enq_txn_size=1, deq_txn_size=1, remote_cluster_flag=True)
-
- def test_txEnq01_txDeq01_remCluster_route_durMsg_durQueue_amqDirectExch(self):
- self._do_test(self._get_name(), exch_name="amq.direct", msg_durable_flag=True, queue_durable_flag=True, enq_txn_size=1, deq_txn_size=1, remote_cluster_flag=True)
-
- def test_txEnq01_txDeq01_remCluster_queueRoute_durQueue_amqDirectExch(self):
- self._do_test(self._get_name(), exch_name="amq.direct", queue_durable_flag=True, queue_route_type_flag=True, enq_txn_size=1, deq_txn_size=1, remote_cluster_flag=True)
-
- def test_txEnq01_txDeq01_remCluster_queueRoute_durMsg_durQueue_amqDirectExch(self):
- self._do_test(self._get_name(), exch_name="amq.direct", msg_durable_flag=True, queue_durable_flag=True, queue_route_type_flag=True, enq_txn_size=1, deq_txn_size=1, remote_cluster_flag=True)
-
- def test_txEnq01_locCluster_remCluster_route_durQueue_amqDirectExch(self):
- self._do_test(self._get_name(), exch_name="amq.direct", queue_durable_flag=True, enq_txn_size=1, local_cluster_flag=True, remote_cluster_flag=True)
-
- def test_txEnq01_locCluster_remCluster_route_durMsg_durQueue_amqDirectExch(self):
- self._do_test(self._get_name(), exch_name="amq.direct", msg_durable_flag=True, queue_durable_flag=True, enq_txn_size=1, local_cluster_flag=True, remote_cluster_flag=True)
-
- def test_txEnq01_locCluster_remCluster_queueRoute_durQueue_amqDirectExch(self):
- self._do_test(self._get_name(), exch_name="amq.direct", queue_durable_flag=True, queue_route_type_flag=True, enq_txn_size=1, local_cluster_flag=True, remote_cluster_flag=True)
-
- def test_txEnq01_locCluster_remCluster_queueRoute_durMsg_durQueue_amqDirectExch(self):
- self._do_test(self._get_name(), exch_name="amq.direct", msg_durable_flag=True, queue_durable_flag=True, queue_route_type_flag=True, enq_txn_size=1, local_cluster_flag=True, remote_cluster_flag=True)
-
- def test_txEnq10_locCluster_remCluster_route_durQueue_amqDirectExch(self):
- self._do_test(self._get_name(), exch_name="amq.direct", queue_durable_flag=True, enq_txn_size=10, msg_count = 103, local_cluster_flag=True, remote_cluster_flag=True)
-
- def test_txEnq10_locCluster_remCluster_route_durMsg_durQueue_amqDirectExch(self):
- self._do_test(self._get_name(), exch_name="amq.direct", msg_durable_flag=True, queue_durable_flag=True, enq_txn_size=10, msg_count = 103, local_cluster_flag=True, remote_cluster_flag=True)
-
- def test_txEnq10_locCluster_remCluster_queueRoute_durQueue_amqDirectExch(self):
- self._do_test(self._get_name(), exch_name="amq.direct", queue_durable_flag=True, queue_route_type_flag=True, enq_txn_size=10, msg_count = 103, local_cluster_flag=True, remote_cluster_flag=True)
-
- def test_txEnq10_locCluster_remCluster_queueRoute_durMsg_durQueue_amqDirectExch(self):
- self._do_test(self._get_name(), exch_name="amq.direct", msg_durable_flag=True, queue_durable_flag=True, queue_route_type_flag=True, enq_txn_size=10, msg_count = 103, local_cluster_flag=True, remote_cluster_flag=True)
-
- def test_txEnq01_txDeq01_locCluster_remCluster_route_durQueue_amqDirectExch(self):
- self._do_test(self._get_name(), exch_name="amq.direct", queue_durable_flag=True, enq_txn_size=1, deq_txn_size=1, local_cluster_flag=True, remote_cluster_flag=True)
-
- def test_txEnq01_txDeq01_locCluster_remCluster_route_durMsg_durQueue_amqDirectExch(self):
- self._do_test(self._get_name(), exch_name="amq.direct", msg_durable_flag=True, queue_durable_flag=True, enq_txn_size=1, deq_txn_size=1, local_cluster_flag=True, remote_cluster_flag=True)
-
- def test_txEnq01_txDeq01_locCluster_remCluster_queueRoute_durQueue_amqDirectExch(self):
- self._do_test(self._get_name(), exch_name="amq.direct", queue_durable_flag=True, queue_route_type_flag=True, enq_txn_size=1, deq_txn_size=1, local_cluster_flag=True, remote_cluster_flag=True)
-
- def test_txEnq01_txDeq01_locCluster_remCluster_queueRoute_durMsg_durQueue_amqDirectExch(self):
- self._do_test(self._get_name(), exch_name="amq.direct", msg_durable_flag=True, queue_durable_flag=True, queue_route_type_flag=True, enq_txn_size=1, deq_txn_size=1, local_cluster_flag=True, remote_cluster_flag=True)
-
-
- def test_txEnq01_locCluster_route_durQueue_directExch(self):
- self._do_test(self._get_name(), exch_name="testDirectExchange", queue_durable_flag=True, enq_txn_size=1, local_cluster_flag=True)
-
- def test_txEnq01_locCluster_route_durMsg_durQueue_directExch(self):
- self._do_test(self._get_name(), exch_name="testDirectExchange", msg_durable_flag=True, queue_durable_flag=True, enq_txn_size=1, local_cluster_flag=True)
-
- def test_txEnq01_locCluster_queueRoute_durQueue_directExch(self):
- self._do_test(self._get_name(), exch_name="testDirectExchange", queue_durable_flag=True, queue_route_type_flag=True, enq_txn_size=1, local_cluster_flag=True)
-
- def test_txEnq01_locCluster_queueRoute_durMsg_durQueue_directExch(self):
- self._do_test(self._get_name(), exch_name="testDirectExchange", msg_durable_flag=True, queue_durable_flag=True, queue_route_type_flag=True, enq_txn_size=1, local_cluster_flag=True)
-
- def test_txEnq10_locCluster_route_durQueue_directExch(self):
- self._do_test(self._get_name(), exch_name="testDirectExchange", queue_durable_flag=True, enq_txn_size=10, msg_count = 103, local_cluster_flag=True)
-
- def test_txEnq10_locCluster_route_durMsg_durQueue_directExch(self):
- self._do_test(self._get_name(), exch_name="testDirectExchange", msg_durable_flag=True, queue_durable_flag=True, enq_txn_size=10, msg_count = 103, local_cluster_flag=True)
-
- def test_txEnq10_locCluster_queueRoute_durQueue_directExch(self):
- self._do_test(self._get_name(), exch_name="testDirectExchange", queue_durable_flag=True, queue_route_type_flag=True, enq_txn_size=10, msg_count = 103, local_cluster_flag=True)
-
- def test_txEnq10_locCluster_queueRoute_durMsg_durQueue_directExch(self):
- self._do_test(self._get_name(), exch_name="testDirectExchange", msg_durable_flag=True, queue_durable_flag=True, queue_route_type_flag=True, enq_txn_size=10, msg_count = 103, local_cluster_flag=True)
-
- def test_txEnq01_txDeq01_locCluster_route_durQueue_directExch(self):
- self._do_test(self._get_name(), exch_name="testDirectExchange", queue_durable_flag=True, enq_txn_size=1, deq_txn_size=1, local_cluster_flag=True)
-
- def test_txEnq01_txDeq01_locCluster_route_durMsg_durQueue_directExch(self):
- self._do_test(self._get_name(), exch_name="testDirectExchange", msg_durable_flag=True, queue_durable_flag=True, enq_txn_size=1, deq_txn_size=1, local_cluster_flag=True)
-
- def test_txEnq01_txDeq01_locCluster_queueRoute_durQueue_directExch(self):
- self._do_test(self._get_name(), exch_name="testDirectExchange", queue_durable_flag=True, queue_route_type_flag=True, enq_txn_size=1, deq_txn_size=1, local_cluster_flag=True)
-
- def test_txEnq01_txDeq01_locCluster_queueRoute_durMsg_durQueue_directExch(self):
- self._do_test(self._get_name(), exch_name="testDirectExchange", msg_durable_flag=True, queue_durable_flag=True, queue_route_type_flag=True, enq_txn_size=1, deq_txn_size=1, local_cluster_flag=True)
-
- def test_txEnq01_remCluster_route_durQueue_directExch(self):
- self._do_test(self._get_name(), exch_name="testDirectExchange", queue_durable_flag=True, enq_txn_size=1, remote_cluster_flag=True)
-
- def test_txEnq01_remCluster_route_durMsg_durQueue_directExch(self):
- self._do_test(self._get_name(), exch_name="testDirectExchange", msg_durable_flag=True, queue_durable_flag=True, enq_txn_size=1, remote_cluster_flag=True)
-
- def test_txEnq01_remCluster_queueRoute_durQueue_directExch(self):
- self._do_test(self._get_name(), exch_name="testDirectExchange", queue_durable_flag=True, queue_route_type_flag=True, enq_txn_size=1, remote_cluster_flag=True)
-
- def test_txEnq01_remCluster_queueRoute_durMsg_durQueue_directExch(self):
- self._do_test(self._get_name(), exch_name="testDirectExchange", msg_durable_flag=True, queue_durable_flag=True, queue_route_type_flag=True, enq_txn_size=1, remote_cluster_flag=True)
-
- def test_txEnq10_remCluster_route_durQueue_directExch(self):
- self._do_test(self._get_name(), exch_name="testDirectExchange", queue_durable_flag=True, enq_txn_size=10, msg_count = 103, remote_cluster_flag=True)
-
- def test_txEnq10_remCluster_route_durMsg_durQueue_directExch(self):
- self._do_test(self._get_name(), exch_name="testDirectExchange", msg_durable_flag=True, queue_durable_flag=True, enq_txn_size=10, msg_count = 103, remote_cluster_flag=True)
-
- def test_txEnq10_remCluster_queueRoute_durQueue_directExch(self):
- self._do_test(self._get_name(), exch_name="testDirectExchange", queue_durable_flag=True, queue_route_type_flag=True, enq_txn_size=10, msg_count = 103, remote_cluster_flag=True)
-
- def test_txEnq10_remCluster_queueRoute_durMsg_durQueue_directExch(self):
- self._do_test(self._get_name(), exch_name="testDirectExchange", msg_durable_flag=True, queue_durable_flag=True, queue_route_type_flag=True, enq_txn_size=10, msg_count = 103, remote_cluster_flag=True)
-
- def test_txEnq01_txDeq01_remCluster_route_durQueue_directExch(self):
- self._do_test(self._get_name(), exch_name="testDirectExchange", queue_durable_flag=True, enq_txn_size=1, deq_txn_size=1, remote_cluster_flag=True)
-
- def test_txEnq01_txDeq01_remCluster_route_durMsg_durQueue_directExch(self):
- self._do_test(self._get_name(), exch_name="testDirectExchange", msg_durable_flag=True, queue_durable_flag=True, enq_txn_size=1, deq_txn_size=1, remote_cluster_flag=True)
-
- def test_txEnq01_txDeq01_remCluster_queueRoute_durQueue_directExch(self):
- self._do_test(self._get_name(), exch_name="testDirectExchange", queue_durable_flag=True, queue_route_type_flag=True, enq_txn_size=1, deq_txn_size=1, remote_cluster_flag=True)
-
- def test_txEnq01_txDeq01_remCluster_queueRoute_durMsg_durQueue_directExch(self):
- self._do_test(self._get_name(), exch_name="testDirectExchange", msg_durable_flag=True, queue_durable_flag=True, queue_route_type_flag=True, enq_txn_size=1, deq_txn_size=1, remote_cluster_flag=True)
-
- def test_txEnq01_locCluster_remCluster_route_durQueue_directExch(self):
- self._do_test(self._get_name(), exch_name="testDirectExchange", queue_durable_flag=True, enq_txn_size=1, local_cluster_flag=True, remote_cluster_flag=True)
-
- def test_txEnq01_locCluster_remCluster_route_durMsg_durQueue_directExch(self):
- self._do_test(self._get_name(), exch_name="testDirectExchange", msg_durable_flag=True, queue_durable_flag=True, enq_txn_size=1, local_cluster_flag=True, remote_cluster_flag=True)
-
- def test_txEnq01_locCluster_remCluster_queueRoute_durQueue_directExch(self):
- self._do_test(self._get_name(), exch_name="testDirectExchange", queue_durable_flag=True, queue_route_type_flag=True, enq_txn_size=1, local_cluster_flag=True, remote_cluster_flag=True)
-
- def test_txEnq01_locCluster_remCluster_queueRoute_durMsg_durQueue_directExch(self):
- self._do_test(self._get_name(), exch_name="testDirectExchange", msg_durable_flag=True, queue_durable_flag=True, queue_route_type_flag=True, enq_txn_size=1, local_cluster_flag=True, remote_cluster_flag=True)
-
- def test_txEnq10_locCluster_remCluster_route_durQueue_directExch(self):
- self._do_test(self._get_name(), exch_name="testDirectExchange", queue_durable_flag=True, enq_txn_size=10, msg_count = 103, local_cluster_flag=True, remote_cluster_flag=True)
-
- def test_txEnq10_locCluster_remCluster_route_durMsg_durQueue_directExch(self):
- self._do_test(self._get_name(), exch_name="testDirectExchange", msg_durable_flag=True, queue_durable_flag=True, enq_txn_size=10, msg_count = 103, local_cluster_flag=True, remote_cluster_flag=True)
-
- def test_txEnq10_locCluster_remCluster_queueRoute_durQueue_directExch(self):
- self._do_test(self._get_name(), exch_name="testDirectExchange", queue_durable_flag=True, queue_route_type_flag=True, enq_txn_size=10, msg_count = 103, local_cluster_flag=True, remote_cluster_flag=True)
-
- def test_txEnq10_locCluster_remCluster_queueRoute_durMsg_durQueue_directExch(self):
- self._do_test(self._get_name(), exch_name="testDirectExchange", msg_durable_flag=True, queue_durable_flag=True, queue_route_type_flag=True, enq_txn_size=10, msg_count = 103, local_cluster_flag=True, remote_cluster_flag=True)
-
- def test_txEnq01_txDeq01_locCluster_remCluster_route_durQueue_directExch(self):
- self._do_test(self._get_name(), exch_name="testDirectExchange", queue_durable_flag=True, enq_txn_size=1, deq_txn_size=1, local_cluster_flag=True, remote_cluster_flag=True)
-
- def test_txEnq01_txDeq01_locCluster_remCluster_route_durMsg_durQueue_directExch(self):
- self._do_test(self._get_name(), exch_name="testDirectExchange", msg_durable_flag=True, queue_durable_flag=True, enq_txn_size=1, deq_txn_size=1, local_cluster_flag=True, remote_cluster_flag=True)
-
- def test_txEnq01_txDeq01_locCluster_remCluster_queueRoute_durQueue_directExch(self):
- self._do_test(self._get_name(), exch_name="testDirectExchange", queue_durable_flag=True, queue_route_type_flag=True, enq_txn_size=1, deq_txn_size=1, local_cluster_flag=True, remote_cluster_flag=True)
-
- def test_txEnq01_txDeq01_locCluster_remCluster_queueRoute_durMsg_durQueue_directExch(self):
- self._do_test(self._get_name(), exch_name="testDirectExchange", msg_durable_flag=True, queue_durable_flag=True, queue_route_type_flag=True, enq_txn_size=1, deq_txn_size=1, local_cluster_flag=True, remote_cluster_flag=True)
-
-
- def test_txEnq01_locCluster_route_durQueue_fanoutExch(self):
- self._do_test(self._get_name(), exch_name="testFanoutExchange", exch_type="fanout", queue_durable_flag=True, enq_txn_size=1, local_cluster_flag=True)
-
- def test_txEnq01_locCluster_route_durMsg_durQueue_fanoutExch(self):
- self._do_test(self._get_name(), exch_name="testFanoutExchange", exch_type="fanout", msg_durable_flag=True, queue_durable_flag=True, enq_txn_size=1, local_cluster_flag=True)
-
- def test_txEnq01_locCluster_queueRoute_durQueue_fanoutExch(self):
- self._do_test(self._get_name(), exch_name="testFanoutExchange", exch_type="fanout", queue_durable_flag=True, queue_route_type_flag=True, enq_txn_size=1, local_cluster_flag=True)
-
- def test_txEnq01_locCluster_queueRoute_durMsg_durQueue_fanoutExch(self):
- self._do_test(self._get_name(), exch_name="testFanoutExchange", exch_type="fanout", msg_durable_flag=True, queue_durable_flag=True, queue_route_type_flag=True, enq_txn_size=1, local_cluster_flag=True)
-
- def test_txEnq10_locCluster_route_durQueue_fanoutExch(self):
- self._do_test(self._get_name(), exch_name="testFanoutExchange", exch_type="fanout", queue_durable_flag=True, enq_txn_size=10, msg_count = 103, local_cluster_flag=True)
-
- def test_txEnq10_locCluster_route_durMsg_durQueue_fanoutExch(self):
- self._do_test(self._get_name(), exch_name="testFanoutExchange", exch_type="fanout", msg_durable_flag=True, queue_durable_flag=True, enq_txn_size=10, msg_count = 103, local_cluster_flag=True)
-
- def test_txEnq10_locCluster_queueRoute_durQueue_fanoutExch(self):
- self._do_test(self._get_name(), exch_name="testFanoutExchange", exch_type="fanout", queue_durable_flag=True, queue_route_type_flag=True, enq_txn_size=10, msg_count = 103, local_cluster_flag=True)
-
- def test_txEnq10_locCluster_queueRoute_durMsg_durQueue_fanoutExch(self):
- self._do_test(self._get_name(), exch_name="testFanoutExchange", exch_type="fanout", msg_durable_flag=True, queue_durable_flag=True, queue_route_type_flag=True, enq_txn_size=10, msg_count = 103, local_cluster_flag=True)
-
- def test_txEnq01_txDeq01_locCluster_route_durQueue_fanoutExch(self):
- self._do_test(self._get_name(), exch_name="testFanoutExchange", exch_type="fanout", queue_durable_flag=True, enq_txn_size=1, deq_txn_size=1, local_cluster_flag=True)
-
- def test_txEnq01_txDeq01_locCluster_route_durMsg_durQueue_fanoutExch(self):
- self._do_test(self._get_name(), exch_name="testFanoutExchange", exch_type="fanout", msg_durable_flag=True, queue_durable_flag=True, enq_txn_size=1, deq_txn_size=1, local_cluster_flag=True)
-
- def test_txEnq01_txDeq01_locCluster_queueRoute_durQueue_fanoutExch(self):
- self._do_test(self._get_name(), exch_name="testFanoutExchange", exch_type="fanout", queue_durable_flag=True, queue_route_type_flag=True, enq_txn_size=1, deq_txn_size=1, local_cluster_flag=True)
-
- def test_txEnq01_txDeq01_locCluster_queueRoute_durMsg_durQueue_fanoutExch(self):
- self._do_test(self._get_name(), exch_name="testFanoutExchange", exch_type="fanout", msg_durable_flag=True, queue_durable_flag=True, queue_route_type_flag=True, enq_txn_size=1, deq_txn_size=1, local_cluster_flag=True)
-
- def test_txEnq01_remCluster_route_durQueue_fanoutExch(self):
- self._do_test(self._get_name(), exch_name="testFanoutExchange", exch_type="fanout", queue_durable_flag=True, enq_txn_size=1, remote_cluster_flag=True)
-
- def test_txEnq01_remCluster_route_durMsg_durQueue_fanoutExch(self):
- self._do_test(self._get_name(), exch_name="testFanoutExchange", exch_type="fanout", msg_durable_flag=True, queue_durable_flag=True, enq_txn_size=1, remote_cluster_flag=True)
-
- def test_txEnq01_remCluster_queueRoute_durQueue_fanoutExch(self):
- self._do_test(self._get_name(), exch_name="testFanoutExchange", exch_type="fanout", queue_durable_flag=True, queue_route_type_flag=True, enq_txn_size=1, remote_cluster_flag=True)
-
- def test_txEnq01_remCluster_queueRoute_durMsg_durQueue_fanoutExch(self):
- self._do_test(self._get_name(), exch_name="testFanoutExchange", exch_type="fanout", msg_durable_flag=True, queue_durable_flag=True, queue_route_type_flag=True, enq_txn_size=1, remote_cluster_flag=True)
-
- def test_txEnq10_remCluster_route_durQueue_fanoutExch(self):
- self._do_test(self._get_name(), exch_name="testFanoutExchange", exch_type="fanout", queue_durable_flag=True, enq_txn_size=10, msg_count = 103, remote_cluster_flag=True)
-
- def test_txEnq10_remCluster_route_durMsg_durQueue_fanoutExch(self):
- self._do_test(self._get_name(), exch_name="testFanoutExchange", exch_type="fanout", msg_durable_flag=True, queue_durable_flag=True, enq_txn_size=10, msg_count = 103, remote_cluster_flag=True)
-
- def test_txEnq10_remCluster_queueRoute_durQueue_fanoutExch(self):
- self._do_test(self._get_name(), exch_name="testFanoutExchange", exch_type="fanout", queue_durable_flag=True, queue_route_type_flag=True, enq_txn_size=10, msg_count = 103, remote_cluster_flag=True)
-
- def test_txEnq10_remCluster_queueRoute_durMsg_durQueue_fanoutExch(self):
- self._do_test(self._get_name(), exch_name="testFanoutExchange", exch_type="fanout", msg_durable_flag=True, queue_durable_flag=True, queue_route_type_flag=True, enq_txn_size=10, msg_count = 103, remote_cluster_flag=True)
-
- def test_txEnq01_txDeq01_remCluster_route_durQueue_fanoutExch(self):
- self._do_test(self._get_name(), exch_name="testFanoutExchange", exch_type="fanout", queue_durable_flag=True, enq_txn_size=1, deq_txn_size=1, remote_cluster_flag=True)
-
- def test_txEnq01_txDeq01_remCluster_route_durMsg_durQueue_fanoutExch(self):
- self._do_test(self._get_name(), exch_name="testFanoutExchange", exch_type="fanout", msg_durable_flag=True, queue_durable_flag=True, enq_txn_size=1, deq_txn_size=1, remote_cluster_flag=True)
-
- def test_txEnq01_txDeq01_remCluster_queueRoute_durQueue_fanoutExch(self):
- self._do_test(self._get_name(), exch_name="testFanoutExchange", exch_type="fanout", queue_durable_flag=True, queue_route_type_flag=True, enq_txn_size=1, deq_txn_size=1, remote_cluster_flag=True)
-
- def test_txEnq01_txDeq01_remCluster_queueRoute_durMsg_durQueue_fanoutExch(self):
- self._do_test(self._get_name(), exch_name="testFanoutExchange", exch_type="fanout", msg_durable_flag=True, queue_durable_flag=True, queue_route_type_flag=True, enq_txn_size=1, deq_txn_size=1, remote_cluster_flag=True)
-
- def test_txEnq01_locCluster_remCluster_route_durQueue_fanoutExch(self):
- self._do_test(self._get_name(), exch_name="testFanoutExchange", exch_type="fanout", queue_durable_flag=True, enq_txn_size=1, local_cluster_flag=True, remote_cluster_flag=True)
-
- def test_txEnq01_locCluster_remCluster_route_durMsg_durQueue_fanoutExch(self):
- self._do_test(self._get_name(), exch_name="testFanoutExchange", exch_type="fanout", msg_durable_flag=True, queue_durable_flag=True, enq_txn_size=1, local_cluster_flag=True, remote_cluster_flag=True)
-
- def test_txEnq01_locCluster_remCluster_queueRoute_durQueue_fanoutExch(self):
- self._do_test(self._get_name(), exch_name="testFanoutExchange", exch_type="fanout", queue_durable_flag=True, queue_route_type_flag=True, enq_txn_size=1, local_cluster_flag=True, remote_cluster_flag=True)
-
- def test_txEnq01_locCluster_remCluster_queueRoute_durMsg_durQueue_fanoutExch(self):
- self._do_test(self._get_name(), exch_name="testFanoutExchange", exch_type="fanout", msg_durable_flag=True, queue_durable_flag=True, queue_route_type_flag=True, enq_txn_size=1, local_cluster_flag=True, remote_cluster_flag=True)
-
- def test_txEnq10_locCluster_remCluster_route_durQueue_fanoutExch(self):
- self._do_test(self._get_name(), exch_name="testFanoutExchange", exch_type="fanout", queue_durable_flag=True, enq_txn_size=10, msg_count = 103, local_cluster_flag=True, remote_cluster_flag=True)
-
- def test_txEnq10_locCluster_remCluster_route_durMsg_durQueue_fanoutExch(self):
- self._do_test(self._get_name(), exch_name="testFanoutExchange", exch_type="fanout", msg_durable_flag=True, queue_durable_flag=True, enq_txn_size=10, msg_count = 103, local_cluster_flag=True, remote_cluster_flag=True)
-
- def test_txEnq10_locCluster_remCluster_queueRoute_durQueue_fanoutExch(self):
- self._do_test(self._get_name(), exch_name="testFanoutExchange", exch_type="fanout", queue_durable_flag=True, queue_route_type_flag=True, enq_txn_size=10, msg_count = 103, local_cluster_flag=True, remote_cluster_flag=True)
-
- def test_txEnq10_locCluster_remCluster_queueRoute_durMsg_durQueue_fanoutExch(self):
- self._do_test(self._get_name(), exch_name="testFanoutExchange", exch_type="fanout", msg_durable_flag=True, queue_durable_flag=True, queue_route_type_flag=True, enq_txn_size=10, msg_count = 103, local_cluster_flag=True, remote_cluster_flag=True)
-
- def test_txEnq01_txDeq01_locCluster_remCluster_route_durQueue_fanoutExch(self):
- self._do_test(self._get_name(), exch_name="testFanoutExchange", exch_type="fanout", queue_durable_flag=True, enq_txn_size=1, deq_txn_size=1, local_cluster_flag=True, remote_cluster_flag=True)
-
- def test_txEnq01_txDeq01_locCluster_remCluster_route_durMsg_durQueue_fanoutExch(self):
- self._do_test(self._get_name(), exch_name="testFanoutExchange", exch_type="fanout", msg_durable_flag=True, queue_durable_flag=True, enq_txn_size=1, deq_txn_size=1, local_cluster_flag=True, remote_cluster_flag=True)
-
- def test_txEnq01_txDeq01_locCluster_remCluster_queueRoute_durQueue_fanoutExch(self):
- self._do_test(self._get_name(), exch_name="testFanoutExchange", exch_type="fanout", queue_durable_flag=True, queue_route_type_flag=True, enq_txn_size=1, deq_txn_size=1, local_cluster_flag=True, remote_cluster_flag=True)
-
- def test_txEnq01_txDeq01_locCluster_remCluster_queueRoute_durMsg_durQueue_fanoutExch(self):
- self._do_test(self._get_name(), exch_name="testFanoutExchange", exch_type="fanout", msg_durable_flag=True, queue_durable_flag=True, queue_route_type_flag=True, enq_txn_size=1, deq_txn_size=1, local_cluster_flag=True, remote_cluster_flag=True)
-
-
- def test_txEnq01_locCluster_route_durQueue_topicExch(self):
- self._do_test(self._get_name(), exch_name="testTopicExchange", exch_type="topic", topic_key=self._get_name()+".#", queue_durable_flag=True, enq_txn_size=1, local_cluster_flag=True)
-
- def test_txEnq01_locCluster_route_durMsg_durQueue_topicExch(self):
- self._do_test(self._get_name(), exch_name="testTopicExchange", exch_type="topic", topic_key=self._get_name()+".#", msg_durable_flag=True, queue_durable_flag=True, enq_txn_size=1, local_cluster_flag=True)
-
- def test_txEnq01_locCluster_queueRoute_durQueue_topicExch(self):
- self._do_test(self._get_name(), exch_name="testTopicExchange", exch_type="topic", topic_key=self._get_name()+".#", queue_durable_flag=True, queue_route_type_flag=True, enq_txn_size=1, local_cluster_flag=True)
-
- def test_txEnq01_locCluster_queueRoute_durMsg_durQueue_topicExch(self):
- self._do_test(self._get_name(), exch_name="testTopicExchange", exch_type="topic", topic_key=self._get_name()+".#", msg_durable_flag=True, queue_durable_flag=True, queue_route_type_flag=True, enq_txn_size=1, local_cluster_flag=True)
-
- def test_txEnq10_locCluster_route_durQueue_topicExch(self):
- self._do_test(self._get_name(), exch_name="testTopicExchange", exch_type="topic", topic_key=self._get_name()+".#", queue_durable_flag=True, enq_txn_size=10, msg_count = 103, local_cluster_flag=True)
-
- def test_txEnq10_locCluster_route_durMsg_durQueue_topicExch(self):
- self._do_test(self._get_name(), exch_name="testTopicExchange", exch_type="topic", topic_key=self._get_name()+".#", msg_durable_flag=True, queue_durable_flag=True, enq_txn_size=10, msg_count = 103, local_cluster_flag=True)
-
- def test_txEnq10_locCluster_queueRoute_durQueue_topicExch(self):
- self._do_test(self._get_name(), exch_name="testTopicExchange", exch_type="topic", topic_key=self._get_name()+".#", queue_durable_flag=True, queue_route_type_flag=True, enq_txn_size=10, msg_count = 103, local_cluster_flag=True)
-
- def test_txEnq10_locCluster_queueRoute_durMsg_durQueue_topicExch(self):
- self._do_test(self._get_name(), exch_name="testTopicExchange", exch_type="topic", topic_key=self._get_name()+".#", msg_durable_flag=True, queue_durable_flag=True, queue_route_type_flag=True, enq_txn_size=10, msg_count = 103, local_cluster_flag=True)
-
- def test_txEnq01_txDeq01_locCluster_route_durQueue_topicExch(self):
- self._do_test(self._get_name(), exch_name="testTopicExchange", exch_type="topic", topic_key=self._get_name()+".#", queue_durable_flag=True, enq_txn_size=1, deq_txn_size=1, local_cluster_flag=True)
-
- def test_txEnq01_txDeq01_locCluster_route_durMsg_durQueue_topicExch(self):
- self._do_test(self._get_name(), exch_name="testTopicExchange", exch_type="topic", topic_key=self._get_name()+".#", msg_durable_flag=True, queue_durable_flag=True, enq_txn_size=1, deq_txn_size=1, local_cluster_flag=True)
-
- def test_txEnq01_txDeq01_locCluster_queueRoute_durQueue_topicExch(self):
- self._do_test(self._get_name(), exch_name="testTopicExchange", exch_type="topic", topic_key=self._get_name()+".#", queue_durable_flag=True, queue_route_type_flag=True, enq_txn_size=1, deq_txn_size=1, local_cluster_flag=True)
-
- def test_txEnq01_txDeq01_locCluster_queueRoute_durMsg_durQueue_topicExch(self):
- self._do_test(self._get_name(), exch_name="testTopicExchange", exch_type="topic", topic_key=self._get_name()+".#", msg_durable_flag=True, queue_durable_flag=True, queue_route_type_flag=True, enq_txn_size=1, deq_txn_size=1, local_cluster_flag=True)
-
- def test_txEnq01_remCluster_route_durQueue_topicExch(self):
- self._do_test(self._get_name(), exch_name="testTopicExchange", exch_type="topic", topic_key=self._get_name()+".#", queue_durable_flag=True, enq_txn_size=1, remote_cluster_flag=True)
-
- def test_txEnq01_remCluster_route_durMsg_durQueue_topicExch(self):
- self._do_test(self._get_name(), exch_name="testTopicExchange", exch_type="topic", topic_key=self._get_name()+".#", msg_durable_flag=True, queue_durable_flag=True, enq_txn_size=1, remote_cluster_flag=True)
-
- def test_txEnq01_remCluster_queueRoute_durQueue_topicExch(self):
- self._do_test(self._get_name(), exch_name="testTopicExchange", exch_type="topic", topic_key=self._get_name()+".#", queue_durable_flag=True, queue_route_type_flag=True, enq_txn_size=1, remote_cluster_flag=True)
-
- def test_txEnq01_remCluster_queueRoute_durMsg_durQueue_topicExch(self):
- self._do_test(self._get_name(), exch_name="testTopicExchange", exch_type="topic", topic_key=self._get_name()+".#", msg_durable_flag=True, queue_durable_flag=True, queue_route_type_flag=True, enq_txn_size=1, remote_cluster_flag=True)
-
- def test_txEnq10_remCluster_route_durQueue_topicExch(self):
- self._do_test(self._get_name(), exch_name="testTopicExchange", exch_type="topic", topic_key=self._get_name()+".#", queue_durable_flag=True, enq_txn_size=10, msg_count = 103, remote_cluster_flag=True)
-
- def test_txEnq10_remCluster_route_durMsg_durQueue_topicExch(self):
- self._do_test(self._get_name(), exch_name="testTopicExchange", exch_type="topic", topic_key=self._get_name()+".#", msg_durable_flag=True, queue_durable_flag=True, enq_txn_size=10, msg_count = 103, remote_cluster_flag=True)
-
- def test_txEnq10_remCluster_queueRoute_durQueue_topicExch(self):
- self._do_test(self._get_name(), exch_name="testTopicExchange", exch_type="topic", topic_key=self._get_name()+".#", queue_durable_flag=True, queue_route_type_flag=True, enq_txn_size=10, msg_count = 103, remote_cluster_flag=True)
-
- def test_txEnq10_remCluster_queueRoute_durMsg_durQueue_topicExch(self):
- self._do_test(self._get_name(), exch_name="testTopicExchange", exch_type="topic", topic_key=self._get_name()+".#", msg_durable_flag=True, queue_durable_flag=True, queue_route_type_flag=True, enq_txn_size=10, msg_count = 103, remote_cluster_flag=True)
-
- def test_txEnq01_txDeq01_remCluster_route_durQueue_topicExch(self):
- self._do_test(self._get_name(), exch_name="testTopicExchange", exch_type="topic", topic_key=self._get_name()+".#", queue_durable_flag=True, enq_txn_size=1, deq_txn_size=1, remote_cluster_flag=True)
-
- def test_txEnq01_txDeq01_remCluster_route_durMsg_durQueue_topicExch(self):
- self._do_test(self._get_name(), exch_name="testTopicExchange", exch_type="topic", topic_key=self._get_name()+".#", msg_durable_flag=True, queue_durable_flag=True, enq_txn_size=1, deq_txn_size=1, remote_cluster_flag=True)
-
- def test_txEnq01_txDeq01_remCluster_queueRoute_durQueue_topicExch(self):
- self._do_test(self._get_name(), exch_name="testTopicExchange", exch_type="topic", topic_key=self._get_name()+".#", queue_durable_flag=True, queue_route_type_flag=True, enq_txn_size=1, deq_txn_size=1, remote_cluster_flag=True)
-
- def test_txEnq01_txDeq01_remCluster_queueRoute_durMsg_durQueue_topicExch(self):
- self._do_test(self._get_name(), exch_name="testTopicExchange", exch_type="topic", topic_key=self._get_name()+".#", msg_durable_flag=True, queue_durable_flag=True, queue_route_type_flag=True, enq_txn_size=1, deq_txn_size=1, remote_cluster_flag=True)
-
- def test_txEnq01_locCluster_remCluster_route_durQueue_topicExch(self):
- self._do_test(self._get_name(), exch_name="testTopicExchange", exch_type="topic", topic_key=self._get_name()+".#", queue_durable_flag=True, enq_txn_size=1, local_cluster_flag=True, remote_cluster_flag=True)
-
- def test_txEnq01_locCluster_remCluster_route_durMsg_durQueue_topicExch(self):
- self._do_test(self._get_name(), exch_name="testTopicExchange", exch_type="topic", topic_key=self._get_name()+".#", msg_durable_flag=True, queue_durable_flag=True, enq_txn_size=1, local_cluster_flag=True, remote_cluster_flag=True)
-
- def test_txEnq01_locCluster_remCluster_queueRoute_durQueue_topicExch(self):
- self._do_test(self._get_name(), exch_name="testTopicExchange", exch_type="topic", topic_key=self._get_name()+".#", queue_durable_flag=True, queue_route_type_flag=True, enq_txn_size=1, local_cluster_flag=True, remote_cluster_flag=True)
-
- def test_txEnq01_locCluster_remCluster_queueRoute_durMsg_durQueue_topicExch(self):
- self._do_test(self._get_name(), exch_name="testTopicExchange", exch_type="topic", topic_key=self._get_name()+".#", msg_durable_flag=True, queue_durable_flag=True, queue_route_type_flag=True, enq_txn_size=1, local_cluster_flag=True, remote_cluster_flag=True)
-
- def test_txEnq10_locCluster_remCluster_route_durQueue_topicExch(self):
- self._do_test(self._get_name(), exch_name="testTopicExchange", exch_type="topic", topic_key=self._get_name()+".#", queue_durable_flag=True, enq_txn_size=10, msg_count = 103, local_cluster_flag=True, remote_cluster_flag=True)
-
- def test_txEnq10_locCluster_remCluster_route_durMsg_durQueue_topicExch(self):
- self._do_test(self._get_name(), exch_name="testTopicExchange", exch_type="topic", topic_key=self._get_name()+".#", msg_durable_flag=True, queue_durable_flag=True, enq_txn_size=10, msg_count = 103, local_cluster_flag=True, remote_cluster_flag=True)
-
- def test_txEnq10_locCluster_remCluster_queueRoute_durQueue_topicExch(self):
- self._do_test(self._get_name(), exch_name="testTopicExchange", exch_type="topic", topic_key=self._get_name()+".#", queue_durable_flag=True, queue_route_type_flag=True, enq_txn_size=10, msg_count = 103, local_cluster_flag=True, remote_cluster_flag=True)
-
- def test_txEnq10_locCluster_remCluster_queueRoute_durMsg_durQueue_topicExch(self):
- self._do_test(self._get_name(), exch_name="testTopicExchange", exch_type="topic", topic_key=self._get_name()+".#", msg_durable_flag=True, queue_durable_flag=True, queue_route_type_flag=True, enq_txn_size=10, msg_count = 103, local_cluster_flag=True, remote_cluster_flag=True)
-
- def test_txEnq01_txDeq01_locCluster_remCluster_route_durQueue_topicExch(self):
- self._do_test(self._get_name(), exch_name="testTopicExchange", exch_type="topic", topic_key=self._get_name()+".#", queue_durable_flag=True, enq_txn_size=1, deq_txn_size=1, local_cluster_flag=True, remote_cluster_flag=True)
-
- def test_txEnq01_txDeq01_locCluster_remCluster_route_durMsg_durQueue_topicExch(self):
- self._do_test(self._get_name(), exch_name="testTopicExchange", exch_type="topic", topic_key=self._get_name()+".#", msg_durable_flag=True, queue_durable_flag=True, enq_txn_size=1, deq_txn_size=1, local_cluster_flag=True, remote_cluster_flag=True)
-
- def test_txEnq01_txDeq01_locCluster_remCluster_queueRoute_durQueue_topicExch(self):
- self._do_test(self._get_name(), exch_name="testTopicExchange", exch_type="topic", topic_key=self._get_name()+".#", queue_durable_flag=True, queue_route_type_flag=True, enq_txn_size=1, deq_txn_size=1, local_cluster_flag=True, remote_cluster_flag=True)
-
- def test_txEnq01_txDeq01_locCluster_remCluster_queueRoute_durMsg_durQueue_topicExch(self):
- self._do_test(self._get_name(), exch_name="testTopicExchange", exch_type="topic", topic_key=self._get_name()+".#", msg_durable_flag=True, queue_durable_flag=True, queue_route_type_flag=True, enq_txn_size=1, deq_txn_size=1, local_cluster_flag=True, remote_cluster_flag=True)
-
diff --git a/qpid/cpp/src/tests/python_tests b/qpid/cpp/src/tests/python_tests
index 0216b5ca7b..e367004a71 100755
--- a/qpid/cpp/src/tests/python_tests
+++ b/qpid/cpp/src/tests/python_tests
@@ -1,4 +1,4 @@
-#!/bin/bash
+#!/bin/sh
#
# Licensed to the Apache Software Foundation (ASF) under one
diff --git a/qpid/cpp/src/tests/qpid-cluster-benchmark b/qpid/cpp/src/tests/qpid-cluster-benchmark
index ff787a46dd..4408e63866 100755
--- a/qpid/cpp/src/tests/qpid-cluster-benchmark
+++ b/qpid/cpp/src/tests/qpid-cluster-benchmark
@@ -7,9 +7,9 @@
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
@@ -19,40 +19,21 @@
#
# Benchmark script for comparing cluster performance.
+#PORT=":5555"
+BROKER=`echo $HOSTS | awk '{print $1}'` # Single broker
+BROKERS=`echo $HOSTS | sed "s/\>/$PORT/g;s/ /,/g"` # Broker URL list
+COUNT=100000
+RATE=20000 # Rate to throttle senders for latency results
+run_test() { echo $*; "$@"; echo; echo; echo; }
-# Default values
-PORT="5672"
-COUNT=10000
-FLOW=100 # Flow control limit on queue depth for latency.
-REPEAT=10
-QUEUES=4
-CLIENTS=3
-
-while getopts "p:c:f:r:t:b:q:c" opt; do
- case $opt in
- p) PORT=$OPTARG;;
- c) COUNT=$OPTARG;;
- f) FLOW=$OPTARG;;
- r) REPEAT=$OPTARG;;
- s) SCALE=$OPTARG;;
- b) BROKERS=$OPTARG;;
- q) QUEUES=$OPTARG;;
- c) CLIENTS=$OPTARG;;
- *) echo "Unknown option"; exit 1;;
- esac
-done
-
-BROKERS=${BROKERS:-$(echo $HOSTS | sed "s/\>/:$PORT/g;s/ /,/g")} # Broker URL list
-BROKER=`echo $BROKERS | awk -F, '{print $1}'` # First broker
+# Thruput, unshared queue
+run_test qpid-cpp-benchmark --repeat 10 -b $BROKER --no-timestamp -m $COUNT
-run_test() { echo $*; shift; "$@"; echo; echo; echo; }
+# Latency
+run_test qpid-cpp-benchmark --repeat 10 -b $BROKER --connection-options '{tcp-nodelay:true}' -m `expr $COUNT / 2` --send-rate $RATE
# Multiple pubs/subs connect via multiple brokers (active-active)
-run_test "multi-host-thruput" qpid-cpp-benchmark --repeat $REPEAT -b $BROKERS --no-timestamp --summarize -q$QUEUES -s$CLIENTS -r$CLIENTS -m $COUNT
+run_test qpid-cpp-benchmark --repeat 10 -b $BROKERS --no-timestamp --summarize -s10 -r10 -m `expr $COUNT / 10`
# Multiple pubs/subs connect via single broker (active-passive)
-run_test "single-host-thruput" qpid-cpp-benchmark --repeat $REPEAT -b $BROKER --no-timestamp --summarize -q$QUEUES -s$CLIENTS -r$CLIENTS -m $COUNT
-
-# Latency
-run_test "latency" qpid-cpp-benchmark --repeat $REPEAT -b $BROKER --connection-options '{tcp-nodelay:true}' -m $COUNT --flow-control $FLOW
-
+run_test qpid-cpp-benchmark --repeat 10 -b $BROKER --no-timestamp --summarize -s10 -r10 -m `expr $COUNT / 10`
diff --git a/qpid/cpp/src/tests/qpid-cpp-benchmark b/qpid/cpp/src/tests/qpid-cpp-benchmark
index 300d34774f..1f77226b4d 100755
--- a/qpid/cpp/src/tests/qpid-cpp-benchmark
+++ b/qpid/cpp/src/tests/qpid-cpp-benchmark
@@ -77,20 +77,6 @@ def ssh_command(host, command):
"""Convert command into an ssh command on host with quoting"""
return ["ssh", host] + [posix_quote(arg) for arg in command]
-class Clients:
- def __init__(self): self.clients=[]
-
- def add(self, client):
- self.clients.append(client)
- return client
-
- def kill(self):
- for c in self.clients:
- try: c.kill()
- except: pass
-
-clients = Clients()
-
def start_receive(queue, index, opts, ready_queue, broker, host):
address_opts=["create:receiver"] + opts.receive_option
if opts.durable: address_opts += ["node:{durable:true}"]
@@ -115,7 +101,7 @@ def start_receive(queue, index, opts, ready_queue, broker, host):
if opts.connection_options:
command += ["--connection-options",opts.connection_options]
if host: command = ssh_command(host, command)
- return clients.add(Popen(command, stdout=PIPE))
+ return Popen(command, stdout=PIPE)
def start_send(queue, opts, broker, host):
address="%s;{%s}"%(queue,",".join(opts.send_option))
@@ -136,7 +122,7 @@ def start_send(queue, opts, broker, host):
if opts.connection_options:
command += ["--connection-options",opts.connection_options]
if host: command = ssh_command(host, command)
- return clients.add(Popen(command, stdout=PIPE))
+ return Popen(command, stdout=PIPE)
def first_line(p):
out,err=p.communicate()
@@ -147,11 +133,7 @@ def delete_queues(queues, broker):
c = qpid.messaging.Connection(broker)
c.open()
for q in queues:
- try:
- s = c.session()
- snd = s.sender("%s;{delete:always}"%(q))
- snd.close()
- s.sync()
+ try: s = c.session().sender("%s;{delete:always}"%(q))
except qpid.messaging.exceptions.NotFound: pass # Ignore "no such queue"
c.close()
@@ -163,6 +145,7 @@ def print_header(timestamp):
def parse(parser, lines): # Parse sender/receiver output
for l in lines:
fn_val = zip(parser, l)
+
return [map(lambda p: p[0](p[1]), zip(parser,line.split())) for line in lines]
def parse_senders(senders):
@@ -173,12 +156,11 @@ def parse_receivers(receivers):
def print_data(send_stats, recv_stats):
for send,recv in map(None, send_stats, recv_stats):
- line=""
- if send: line += "%d"%send[0]
+ if send: print send[0],
if recv:
- line += "\t\t%d"%recv[0]
- if len(recv) == 4: line += "\t%.2f\t%.2f\t%.2f"%tuple(recv[1:])
- print line
+ print "\t\t%d"%recv[0],
+ if len(recv) == 4: print "\t%.2f\t%.2f\t%.2f"%tuple(recv[1:]),
+ print
def print_summary(send_stats, recv_stats):
def avg(s): sum(s) / len(s)
@@ -202,11 +184,11 @@ class ReadyReceiver:
self.receiver = self.connection.session().receiver(
"%s;{create:receiver,delete:receiver,node:{durable:false}}"%(queue))
self.receiver.session.sync()
- self.timeout=10
+ self.timeout=2
def wait(self, receivers):
try:
- for i in receivers: self.receiver.fetch(self.timeout)
+ for i in xrange(len(receivers)): self.receiver.fetch(self.timeout)
self.connection.close()
except qpid.messaging.Empty:
for r in receivers:
@@ -215,8 +197,7 @@ class ReadyReceiver:
raise Exception("Receiver error: %s"%(out))
raise Exception("Timed out waiting for receivers to be ready")
-def flatten(l):
- return sum(map(lambda s: re.split(re.compile("\s*,\s*|\s+"), s), l), [])
+def flatten(l): return sum(map(lambda s: s.split(","), l),[])
class RoundRobin:
def __init__(self,items):
@@ -240,22 +221,20 @@ def main():
receive_out = ""
ready_queue="%s-ready"%(opts.queue_name)
queues = ["%s-%s"%(opts.queue_name, i) for i in xrange(opts.queues)]
- try:
- for i in xrange(opts.repeat):
- delete_queues(queues, opts.broker[0])
- ready_receiver = ReadyReceiver(ready_queue, opts.broker[0])
- receivers = [start_receive(q, j, opts, ready_queue, brokers.next(), client_hosts.next())
- for q in queues for j in xrange(opts.receivers)]
- ready_receiver.wait(filter(None, receivers)) # Wait for receivers to be ready.
- senders = [start_send(q, opts,brokers.next(), client_hosts.next())
- for q in queues for j in xrange(opts.senders)]
- if opts.report_header and i == 0: print_header(opts.timestamp)
- send_stats=parse_senders(senders)
- recv_stats=parse_receivers(receivers)
- if opts.summarize: print_summary(send_stats, recv_stats)
- else: print_data(send_stats, recv_stats)
- delete_queues(queues, opts.broker[0])
- finally: clients.kill() # No strays
+ for i in xrange(opts.repeat):
+ delete_queues(queues, opts.broker[0])
+ ready_receiver = ReadyReceiver(ready_queue, opts.broker[0])
+ receivers = [start_receive(q, j, opts, ready_queue, brokers.next(), client_hosts.next())
+ for q in queues for j in xrange(opts.receivers)]
+ ready_receiver.wait(filter(None, receivers)) # Wait for receivers to be ready.
+ senders = [start_send(q, opts,brokers.next(), client_hosts.next())
+ for q in queues for j in xrange(opts.senders)]
+ if opts.report_header and i == 0: print_header(opts.timestamp)
+ send_stats=parse_senders(senders)
+ recv_stats=parse_receivers(receivers)
+ if opts.summarize: print_summary(send_stats, recv_stats)
+ else: print_data(send_stats, recv_stats)
+ delete_queues(queues, opts.broker[0])
if __name__ == "__main__": main()
diff --git a/qpid/cpp/src/tests/qpid-perftest.cpp b/qpid/cpp/src/tests/qpid-perftest.cpp
index 3aff742c62..4d7b563c8c 100644
--- a/qpid/cpp/src/tests/qpid-perftest.cpp
+++ b/qpid/cpp/src/tests/qpid-perftest.cpp
@@ -396,7 +396,7 @@ struct Controller : public Client {
void run() { // Controller
try {
// Wait for subscribers to be ready.
- process(opts.totalSubs, fqn("sub_ready"), boost::bind(expect, _1, "ready"));
+ process(opts.totalSubs, fqn("sub_ready"), bind(expect, _1, "ready"));
LocalQueue pubDone;
LocalQueue subDone;
@@ -423,10 +423,8 @@ struct Controller : public Client {
process(opts.totalSubs, subDone, fqn("sub_done"), boost::ref(subRates));
AbsTime end=now();
+
double time=secs(start, end);
- if (time <= 0.0) {
- throw Exception("ERROR: Test completed in zero seconds. Try again with a larger message count.");
- }
double txrate=opts.transfers/time;
double mbytes=(txrate*opts.size)/(1024*1024);
@@ -510,11 +508,10 @@ struct PublishThread : public Client {
}
SubscriptionManager subs(session);
LocalQueue lq;
- subs.setFlowControl(0, SubscriptionManager::UNLIMITED, false);
- Subscription cs = subs.subscribe(lq, fqn("pub_start"));
+ subs.setFlowControl(1, SubscriptionManager::UNLIMITED, true);
+ subs.subscribe(lq, fqn("pub_start"));
for (size_t j = 0; j < opts.iterations; ++j) {
- cs.grantMessageCredit(1);
expect(lq.pop().getData(), "start");
AbsTime start=now();
for (size_t i=0; i<opts.count; i++) {
@@ -546,9 +543,6 @@ struct PublishThread : public Client {
if (opts.confirm) session.sync();
AbsTime end=now();
double time=secs(start,end);
- if (time <= 0.0) {
- throw Exception("ERROR: Test completed in zero seconds. Try again with a larger message count.");
- }
// Send result to controller.
Message report(lexical_cast<string>(opts.count/time), fqn("pub_done"));
diff --git a/qpid/cpp/src/tests/qpid-receive.cpp b/qpid/cpp/src/tests/qpid-receive.cpp
index 9c713e872a..3189a13c6e 100644
--- a/qpid/cpp/src/tests/qpid-receive.cpp
+++ b/qpid/cpp/src/tests/qpid-receive.cpp
@@ -53,7 +53,6 @@ struct Options : public qpid::Options
bool forever;
uint messages;
bool ignoreDuplicates;
- bool checkRedelivered;
uint capacity;
uint ackFrequency;
uint tx;
@@ -76,7 +75,6 @@ struct Options : public qpid::Options
forever(false),
messages(0),
ignoreDuplicates(false),
- checkRedelivered(false),
capacity(1000),
ackFrequency(100),
tx(0),
@@ -98,7 +96,6 @@ struct Options : public qpid::Options
("forever,f", qpid::optValue(forever), "ignore timeout and wait forever")
("messages,m", 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)")
- ("check-redelivered", qpid::optValue(checkRedelivered), "Fails with exception if a duplicate is not marked as redelivered (only relevant when ignore-duplicates is selected)")
("capacity", qpid::optValue(capacity, "N"), "Pre-fetch window (0 implies no pre-fetch)")
("ack-frequency", qpid::optValue(ackFrequency, "N"), "Ack frequency (0 implies none of the messages will get accepted)")
("tx", qpid::optValue(tx, "N"), "batch size for transactions (0 implies transaction are not used)")
@@ -219,8 +216,6 @@ int main(int argc, char ** argv)
std::cout << msg.getContent() << std::endl;//TODO: handle map or list messages
if (opts.messages && count >= opts.messages) done = true;
}
- } else if (opts.checkRedelivered && !msg.getRedelivered()) {
- throw qpid::Exception("duplicate sequence number received, message not marked as redelivered!");
}
if (opts.tx && (count % opts.tx == 0)) {
if (opts.rollbackFrequency && (++txCount % opts.rollbackFrequency == 0)) {
@@ -262,7 +257,7 @@ int main(int argc, char ** argv)
return 0;
}
} catch(const std::exception& error) {
- std::cerr << "qpid-receive: " << error.what() << std::endl;
+ std::cerr << "Failure: " << error.what() << std::endl;
connection.close();
return 1;
}
diff --git a/qpid/cpp/src/tests/qpid-send.cpp b/qpid/cpp/src/tests/qpid-send.cpp
index ef5e98e2a0..15fa284c48 100644
--- a/qpid/cpp/src/tests/qpid-send.cpp
+++ b/qpid/cpp/src/tests/qpid-send.cpp
@@ -368,7 +368,7 @@ int main(int argc, char ** argv)
return 0;
}
} catch(const std::exception& error) {
- std::cerr << "qpid-send: " << error.what() << std::endl;
+ std::cout << "Failed: " << error.what() << std::endl;
connection.close();
return 1;
}
diff --git a/qpid/cpp/src/tests/qrsh.cpp b/qpid/cpp/src/tests/qrsh.cpp
new file mode 100644
index 0000000000..0cb52b6b05
--- /dev/null
+++ b/qpid/cpp/src/tests/qrsh.cpp
@@ -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.
+ *
+ */
+
+#include <qpid/client/Connection.h>
+#include <qpid/client/Session.h>
+#include <qpid/client/AsyncSession.h>
+#include <qpid/client/Message.h>
+#include <qpid/client/MessageListener.h>
+#include <qpid/client/SubscriptionManager.h>
+
+#include <stdio.h>
+#include <cstdlib>
+#include <iostream>
+
+#include <sstream>
+
+using namespace qpid::client;
+using namespace qpid::framing;
+
+using namespace std;
+
+namespace qpid {
+namespace tests {
+
+class ResponseListener : public MessageListener
+{
+ public :
+
+ int exitCode;
+
+ ResponseListener ( SubscriptionManager & subscriptions )
+ : exitCode(-1),
+ subscriptions ( subscriptions )
+ {
+ }
+
+ virtual void
+ received ( Message & message )
+ {
+ char first_word[1000];
+ sscanf ( message.getData().c_str(), "%s", first_word );
+
+ if ( ! strcmp ( first_word, "wait_response" ) )
+ {
+ // If we receive a message here, parse out the exit code.
+ sscanf ( message.getData().c_str(), "%*s%d", & exitCode );
+ subscriptions.cancel(message.getDestination());
+ }
+ else
+ if ( ! strcmp ( first_word, "get_response" ) )
+ {
+ // The remainder of the message is the file we requested.
+ fprintf ( stdout,
+ "%s",
+ message.getData().c_str() + strlen("get_response" )
+ );
+ subscriptions.cancel(message.getDestination());
+ }
+ }
+
+
+ private :
+
+ SubscriptionManager & subscriptions;
+};
+
+}} // namespace qpid::tests
+
+using namespace qpid::tests;
+
+/*
+ * argv[1] host
+ * argv[2] port
+ * argv[3] server name
+ * argv[4] command name
+ * argv[5..N] args to the command
+ */
+int
+main ( int argc, char ** argv )
+{
+ const char* host = argv[1];
+ int port = atoi(argv[2]);
+
+
+ Connection connection;
+
+ try
+ {
+ connection.open ( host, port );
+ Session session = connection.newSession ( );
+
+ // Make a queue and bind it to fanout.
+ string myQueue = session.getId().getName();
+
+ session.queueDeclare ( arg::queue=myQueue,
+ arg::exclusive=true,
+ arg::autoDelete=true
+ );
+
+ session.exchangeBind ( arg::exchange="amq.fanout",
+ arg::queue=myQueue,
+ arg::bindingKey="my-key"
+ );
+
+ // Get ready to listen for the wait-response.
+ // or maybe a get-response.
+ // ( Although this may not be one of those types
+ // of command, get ready anyway.
+ SubscriptionManager subscriptions ( session );
+ ResponseListener responseListener ( subscriptions );
+ subscriptions.subscribe ( responseListener, myQueue );
+
+ bool response_command = false;
+ if(! strcmp("exec_wait", argv[4] ))
+ response_command = true;
+ else
+ if(! strcmp("exited", argv[4] ))
+ response_command = true;
+ else
+ if(! strcmp("get", argv[4] ))
+ response_command = true;
+
+ // Send the payload message.
+ // Skip "qrsh host_name port"
+ Message message;
+ stringstream ss;
+ for ( int i = 3; i < argc; ++ i )
+ ss << argv[i] << ' ';
+
+ message.setData ( ss.str() );
+
+ session.messageTransfer(arg::content=message,
+ arg::destination="amq.fanout");
+
+ if ( response_command )
+ subscriptions.run();
+
+ session.close();
+ connection.close();
+ return responseListener.exitCode;
+ }
+ catch ( exception const & e)
+ {
+ cerr << e.what() << endl;
+ }
+
+ return 1;
+}
+
+
+
diff --git a/qpid/cpp/src/tests/qrsh_run.cpp b/qpid/cpp/src/tests/qrsh_run.cpp
new file mode 100644
index 0000000000..cfdd0cef80
--- /dev/null
+++ b/qpid/cpp/src/tests/qrsh_run.cpp
@@ -0,0 +1,321 @@
+/*
+ *
+ * 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 <iostream>
+#include <sstream>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <fcntl.h>
+#include <errno.h>
+
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+
+
+using namespace std;
+
+
+
+int
+main ( int argc, char ** argv )
+{
+ int exit_code = -1;
+ int fd[2];
+ int my_pid = getpid();
+ int child_pid;
+
+ pipe(fd);
+
+ char const * root_dir = argv[1]; // This arg is prepended by qrsh_server.
+ char const * child_name = argv[2]; // This arg comes from qrsh.
+ char const * child_path = argv[3]; // This arg comes from qrsh.
+
+ // This is the problem..
+ fprintf ( stderr, "MDEBUG qrsh_run: root_dir: |%s|\n", root_dir );
+ fprintf ( stderr, "MDEBUG qrsh_run: child_name: |%s|\n", child_name );
+ fprintf ( stderr, "MDEBUG qrsh_run: child_path: |%s|\n", child_path );
+
+ /*
+ * A named child is one for whom we will create a directory and
+ * store information. There are some magic names that are not
+ * real symbolic names -- but are instead the names of actions.
+ */
+
+ bool named_child = true;
+
+ if ( ! strcmp ( child_name, "exec" ) )
+ named_child = false;
+ else
+ if ( ! strcmp ( child_name, "exec_wait" ) )
+ named_child = false;
+ else
+ if ( ! strcmp ( child_name, "exited" ) )
+ named_child = false;
+ else
+ named_child = true;
+
+ stringstream child_dir_name;
+
+ if ( named_child )
+ {
+ child_dir_name << root_dir
+ << '/'
+ << child_name;
+
+ /*
+ * Make the child directory before forking, or there is
+ * a race in which the child might be trying to make its
+ * stdout and stderr files while we are tring to make
+ * the directory.
+ */
+ if ( -1 == mkdir ( child_dir_name.str().c_str(), 0777 ) )
+ {
+ fprintf ( stderr,
+ "qrsh_run error: Can't mkdir |%s|\n",
+ child_dir_name.str().c_str()
+ );
+ exit ( 1 );
+ }
+
+ }
+ else
+ /*
+ * If this is an 'exited' command that means we are
+ * waiting for a pre-existing child.
+ */
+ if ( ! strcmp ( child_name, "exited" ) )
+ {
+ int wait_pid = atoi(child_path);
+
+ // Find the child's symbolic name.
+ stringstream pid_to_name_file_name;
+ pid_to_name_file_name << root_dir
+ << '/'
+ << wait_pid;
+ FILE * fp = fopen ( pid_to_name_file_name.str().c_str(), "r" );
+ if (! fp)
+ {
+ fprintf ( stderr,
+ "qrsh_run %d error: Can't open pid2name file |%s|.\n",
+ my_pid,
+ pid_to_name_file_name.str().c_str()
+ );
+ exit(1);
+ }
+ char symbolic_name[1000];
+ strcpy ( symbolic_name, "qrsh_no_name" );
+ fscanf ( fp, "%s", symbolic_name );
+ fclose ( fp );
+
+ // Make the name of the child's exit code file.
+ stringstream exit_code_file_name;
+ exit_code_file_name << root_dir
+ << '/'
+ << symbolic_name
+ << "/exit_code";
+
+ struct stat stat_buf;
+ int file_does_not_exist = stat ( exit_code_file_name.str().c_str(), & stat_buf );
+
+ /*
+ * If the result of stat is zero, the file exists, which means that
+ * the command has exited. The question we are being asked here is
+ * "has it exited yet?"
+ */
+ if ( ! file_does_not_exist )
+ return 1;
+ else
+ if ( errno == ENOENT )
+ return 0;
+ else
+ return 2 ;
+ }
+
+
+ // We are not waiting on a pre-wxiting child: we have a
+ // new child to create.
+
+ child_pid = fork();
+
+ if ( child_pid == 0 )
+ {
+ // This code is executed in the child process.
+
+ // If it's a *named* child, then redirect its stdout and stderr.
+ if ( named_child )
+ {
+ stringstream stdout_path,
+ stderr_path;
+
+ // Redirect the child's stdout. -----------------
+ stdout_path << root_dir
+ << '/'
+ << child_name
+ << '/'
+ << "stdout";
+
+ int redirected_stdout = open ( stdout_path.str().c_str(),
+ O_WRONLY|O_CREAT|O_TRUNC,
+ S_IRWXU|S_IRWXG|S_IRWXO
+ );
+ if ( redirected_stdout < 0 )
+ {
+ perror ( "qrsh_run: error opening redirected_stdout: " );
+ fprintf ( stderr, "stdout path: |%s|\n", stdout_path.str().c_str() );
+ exit ( 1 );
+ }
+ if ( -1 == dup2 ( redirected_stdout, 1 ) )
+ {
+ perror ( "qrsh_run: dup2 (stdout) error: " );
+ exit(1);
+ }
+
+ // Redirect the child's stderr. -----------------
+ stderr_path << root_dir
+ << '/'
+ << child_name
+ << '/'
+ << "stderr";
+
+ int redirected_stderr = open ( stderr_path.str().c_str(),
+ O_WRONLY|O_CREAT|O_TRUNC,
+ S_IRWXU|S_IRWXG|S_IRWXO
+ );
+ if ( redirected_stderr < 0 )
+ {
+ perror ( "qrsh_run: error opening redirected_stderr: " );
+ fprintf ( stderr, "stderr path: |%s|\n", stderr_path.str().c_str() );
+ exit ( 1 );
+ }
+ if(-1 == dup2 ( redirected_stderr, 2 ) )
+ {
+ perror ( "qrsh_run: dup2 (stderr) error: " );
+ exit(1);
+ }
+ }
+
+ fprintf ( stderr, "MDEBUG ------------- qrsh_run argv -------------\n" );
+ for ( int i = 0; i < argc; ++ i )
+ fprintf ( stderr, "MDEBUG argv[%d] : |%s|\n", i, argv[i] );
+
+ execv ( child_path, argv + 2 );
+ perror ( "qrsh_run: execv error: " );
+ fprintf ( stderr, "on path |%s|\n", child_path );
+ exit ( 1 );
+ }
+ else
+ {
+ // This code is executed in the parent process.
+
+ if ( named_child )
+ {
+ // Write the name-to-pid mapping.
+ stringstream pid_file_name;
+ pid_file_name << child_dir_name.str()
+ << "/pid";
+
+ FILE * fp;
+ if ( ! (fp = fopen ( pid_file_name.str().c_str(), "w") ) )
+ {
+ fprintf ( stderr,
+ "qrsh_run %d error: Can't open file |%s|\n",
+ my_pid,
+ pid_file_name.str().c_str()
+ );
+ exit(1);
+ }
+ fprintf ( fp, "%d\n", child_pid );
+ fclose ( fp );
+
+
+ // Write the pid-to-name mapping.
+ stringstream name_to_pid_file_name;
+ name_to_pid_file_name << root_dir
+ << '/'
+ << child_pid;
+ if(! (fp = fopen ( name_to_pid_file_name.str().c_str(), "w")))
+ {
+ fprintf ( stderr,
+ "qrsh_run %d error: Can't open file |%s|\n",
+ my_pid,
+ name_to_pid_file_name.str().c_str()
+ );
+ exit(1);
+ }
+ fprintf ( fp, "%s\n", child_name );
+ fclose(fp);
+ }
+
+ pid_t awaited_pid;
+ while ( 0 == (awaited_pid = waitpid ( child_pid, & exit_code, WNOHANG)) )
+ {
+ fprintf ( stderr,
+ "qrsh_run %d info: parent: waiting for child %d...\n",
+ my_pid,
+ child_pid
+ );
+ sleep(1);
+ }
+
+ if ( -1 == awaited_pid )
+ {
+ fprintf ( stderr, "qrsh_run error awaiting child!\n" );
+ exit ( 1 );
+ }
+
+ /*
+ * Write the exit code.
+ */
+ exit_code >>= 8;
+
+ if ( named_child )
+ {
+ if ( child_pid == awaited_pid )
+ {
+ stringstream exit_code_file_name;
+ exit_code_file_name << child_dir_name.str()
+ << "/exit_code";
+
+ FILE * fp;
+ if ( ! (fp = fopen ( exit_code_file_name.str().c_str(), "w") ) )
+ {
+ fprintf ( stderr,
+ "qrsh_run error: Can't open file |%s|\n",
+ exit_code_file_name.str().c_str()
+ );
+ exit(1);
+ }
+ fprintf ( fp, "%d\n", exit_code );
+ fclose ( fp );
+ }
+ }
+ }
+
+ fprintf ( stderr, "MDEBUG qrsh_run returning exit code %d\n", exit_code );
+ return exit_code;
+}
+
+
+
+
diff --git a/qpid/cpp/src/tests/qrsh_server.cpp b/qpid/cpp/src/tests/qrsh_server.cpp
new file mode 100644
index 0000000000..782f1e6c7c
--- /dev/null
+++ b/qpid/cpp/src/tests/qrsh_server.cpp
@@ -0,0 +1,1068 @@
+/*
+ *
+ * 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 <stdio.h>
+#include <set>
+#include <string>
+#include <sstream>
+#include <unistd.h>
+#include <cstdlib>
+#include <iostream>
+#include <map>
+#include <dirent.h>
+
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+
+#include <qpid/client/Connection.h>
+#include <qpid/client/Session.h>
+#include <qpid/client/AsyncSession.h>
+#include <qpid/client/Message.h>
+#include <qpid/client/MessageListener.h>
+#include <qpid/client/SubscriptionManager.h>
+
+
+using namespace qpid::client;
+using namespace qpid::framing;
+using namespace std;
+
+
+namespace qpid {
+namespace tests {
+
+int
+mrand ( int max_desired_val )
+{
+ double zero_to_one = (double) rand() / (double) RAND_MAX;
+ return (int) (zero_to_one * (double) max_desired_val);
+}
+
+
+
+char *
+file2str ( char const * file_name )
+{
+ FILE * fp = fopen ( file_name, "r" );
+ if(! fp)
+ {
+ fprintf ( stderr, "file2str error: can't open file |%s|.\n", file_name );
+ return 0;
+ }
+
+ fseek ( fp, 0, SEEK_END );
+ size_t file_len = (size_t) ftell ( fp );
+ rewind ( fp );
+ char * content = (char *) malloc ( file_len + 1 );
+
+ if ( ! content )
+ {
+ fprintf ( stderr,
+ "file2str error: can't malloc %d bytes.\n",
+ (int)file_len
+ );
+ return 0;
+ }
+
+ size_t items_read = fread ( content, file_len, 1, fp );
+
+ if ( 1 != items_read )
+ {
+ fprintf ( stderr, "file2str error: read failed.\n" );
+ free ( content );
+ return 0;
+ }
+
+ fclose ( fp );
+ content[file_len] = 0;
+
+ return content;
+}
+
+
+
+
+
+class QrshServer : public MessageListener
+{
+ public:
+
+ QrshServer ( SubscriptionManager & subscriptions,
+ char const * name,
+ char const * qrsh_run_path,
+ char const * host,
+ int port
+ );
+
+ virtual void received ( Message & message);
+
+
+ private:
+
+ set<string> all_server_names;
+
+ stringstream data_dir;
+
+ SubscriptionManager & subscriptions;
+
+ // Is this message addressed to me?
+ bool myMessage ( Message const & message );
+
+ /* ----------------------------------------------
+ * Special Commands
+ * These are commands that the qrsh_server executes
+ * directly, rather than through a child process
+ * instance of qrsh_run.
+ */
+ void runCommand ( Message const & message );
+ void execute ( Message const & message );
+ void wait ( Message const & message );
+ void exited ( Message const & message );
+ void get ( Message const & message );
+ void rememberIntroduction ( Message const & message );
+ void getStraw ( Message const & message );
+ void addAlias ( Message const & message );
+
+ void start ( );
+ void sayHello ( );
+ void sayName ( );
+ // end Special Commands ------------------------
+
+
+ void saveCommand ( Message const & message );
+
+ void send ( string const & content );
+
+ void drawStraws ( );
+ void getNames ( );
+ void runSavedCommand ( );
+
+ char ** getArgs ( char const * s );
+ bool isProcessName ( char const * s );
+ int string_countWords ( char const * s );
+ char const * skipWord ( char const * s );
+
+
+ void string_replaceAll ( string & str,
+ string & target,
+ string & replacement
+ );
+
+
+ string name,
+ qrsh_run_path,
+ host;
+
+ vector<string *> aliases;
+
+ int port;
+
+ map < char *, int > abstract_name_map;
+
+ set < string > myFellowBrokers;
+
+ bool saidHello;
+
+ Message savedCommand;
+
+ vector < int > straws;
+ int myStraw;
+
+};
+
+
+
+QrshServer::QrshServer ( SubscriptionManager & subs,
+ char const * name,
+ char const * qrsh_run_path,
+ char const * host,
+ int port
+ )
+ : subscriptions ( subs ),
+ name ( name ),
+ qrsh_run_path ( qrsh_run_path ),
+ host ( host ),
+ port ( port ),
+ saidHello ( false ),
+ myStraw ( 0 )
+{
+ data_dir << "/tmp/qrsh_"
+ << getpid();
+
+ if(mkdir ( data_dir.str().c_str(), 0777 ) )
+ {
+ fprintf ( stderr,
+ "QrshServer::QrshServer error: can't mkdir |%s|\n",
+ data_dir.str().c_str()
+ );
+ exit ( 1 );
+ }
+}
+
+
+
+void
+QrshServer::saveCommand ( Message const & message )
+{
+ savedCommand = message;
+}
+
+
+
+void
+QrshServer::runSavedCommand ( )
+{
+ runCommand ( savedCommand );
+}
+
+
+
+void
+QrshServer::start ( )
+{
+ stringstream announcement_data;
+ announcement_data << "hello_my_name_is "
+ << name;
+
+ send ( announcement_data.str() );
+
+ saidHello = true;
+}
+
+
+
+
+void
+QrshServer::send ( string const & content )
+{
+ try
+ {
+ Message message;
+ message.setData ( content );
+
+ Connection connection;
+ connection.open ( host, port );
+ Session session = connection.newSession ( );
+ session.messageTransfer ( arg::content = message,
+ arg::destination = "amq.fanout"
+ );
+ session.close();
+ connection.close();
+ }
+ catch ( exception const & e )
+ {
+ fprintf ( stderr, "QrshServer::send error: |%s|\n", e.what() );
+ }
+}
+
+
+
+
+void
+QrshServer::sayHello ( )
+{
+ if ( saidHello )
+ return;
+
+ stringstream ss;
+
+ ss << "hello_my_name_is "
+ << name;
+
+ send ( ss.str() );
+ saidHello = true;
+}
+
+
+
+void
+QrshServer::sayName ( )
+{
+ fprintf ( stderr, "My name is: |%s|\n", name.c_str() );
+}
+
+
+
+
+void
+QrshServer::drawStraws ( )
+{
+ myStraw = mrand ( 1000000000 );
+ stringstream ss;
+ ss << "straw "
+ << name
+ << ' '
+ << myStraw;
+ send ( ss.str() );
+}
+
+
+
+void
+QrshServer::getStraw ( Message const & message )
+{
+ int straw;
+
+ char brokerName[1000];
+ sscanf ( message.getData().c_str(), "%*s%s", brokerName );
+
+ if ( ! strcmp ( brokerName, name.c_str() ) )
+ return;
+
+ sscanf ( message.getData().c_str(), "%*s%*s%d", & straw );
+ straws.push_back ( straw );
+
+ bool i_win = true;
+ int ties = 0;
+
+ if ( straws.size() >= myFellowBrokers.size() )
+ {
+ // All votes are in! Let's see if I win!
+ for ( unsigned int i = 0; i < straws.size(); ++ i )
+ {
+ if ( straws[i] == myStraw )
+ ++ ties;
+ else
+ if ( straws[i] > myStraw )
+ {
+ i_win = false;
+ break;
+ }
+ }
+
+ if ( i_win && (ties <= 0) )
+ {
+ myStraw = 0;
+ straws.clear();
+ runSavedCommand ( );
+ }
+ else
+ if ( i_win && (ties > 0) )
+ {
+ fprintf ( stderr, "MDEBUG oh no! drawStraws error: server %s tied with straw %d!\n", name.c_str(), straw );
+ }
+ }
+}
+
+
+
+
+/*
+ * "APB" command (all-points-bullitens (commands that are not addressed
+ * specifically to any server)) are handled directly, here.
+ * Because if I return simply "true", the normal command processing code
+ * will misinterpret the command.
+ */
+bool
+QrshServer::myMessage ( Message const & message )
+{
+ int const maxlen = 100;
+ char head[maxlen];
+ char first_word [ maxlen + 1 ];
+ strncpy ( head, message.getData().c_str(), maxlen );
+ sscanf ( head, "%s", first_word );
+
+ if ( ! strcmp ( name.c_str(), first_word ) )
+ {
+ return true;
+ }
+ else
+ {
+ // Is the given name one of my aliases?
+ char possibleAlias[1000];
+ if(1 == sscanf ( message.getData().c_str(), "%s", possibleAlias ))
+ {
+ for ( unsigned int i = 0; i < aliases.size(); ++ i )
+ {
+
+ if ( ! strcmp ( possibleAlias, aliases[i]->c_str() ))
+ {
+ return true;
+ }
+ }
+ }
+ }
+
+ if ( ! strcmp ( first_word, "hello_my_name_is" ) )
+ {
+ rememberIntroduction ( message );
+ sayHello ( );
+ return false;
+ }
+ else
+ if ( ! strcmp ( first_word, "straw" ) )
+ {
+ getStraw ( message );
+ return false;
+ }
+ else
+ if ( ! strcmp ( first_word, "all" ) )
+ {
+ return true;
+ }
+ else
+ if ( ! strcmp ( first_word, "any" ) )
+ {
+ straws.clear();
+ usleep ( 200000 );
+ saveCommand ( message );
+ drawStraws ( );
+ return false;
+ }
+ else
+ return false;
+}
+
+
+
+
+void
+QrshServer::rememberIntroduction ( Message const & message )
+{
+ char brokerName [ 1000 ];
+ sscanf ( message.getData().c_str(), "%*s%s", brokerName );
+
+ if ( strcmp ( brokerName, name.c_str() ) )
+ myFellowBrokers.insert ( string ( brokerName ) );
+}
+
+
+
+
+void
+QrshServer::addAlias ( Message const & message )
+{
+ char alias[1000];
+ sscanf ( message.getData().c_str(), "%*s%*s%s", alias );
+ aliases.push_back ( new string(alias) );
+}
+
+
+
+
+void
+QrshServer::getNames ( )
+{
+ abstract_name_map.clear();
+
+ DIR * dir = opendir ( data_dir.str().c_str() );
+
+ if ( ! dir )
+ {
+ fprintf ( stderr,
+ "QrshServer::getNames error: could not open dir |%s|.\n",
+ data_dir.str().c_str()
+ );
+ return;
+ }
+
+ struct dirent * file;
+ while ( (file = readdir ( dir ) ) )
+ {
+ if ( '.' != file->d_name[0] )
+ {
+ stringstream pid_file_name;
+ pid_file_name << data_dir.str()
+ << '/'
+ << file->d_name
+ << "/pid";
+
+ int pid = 0;
+ FILE * fp;
+ if ( (fp = fopen ( pid_file_name.str().c_str(), "r" ) ) )
+ {
+ fscanf ( fp, "%d", & pid );
+ fclose ( fp );
+ abstract_name_map.insert(pair<char*, int>(strdup(file->d_name), pid));
+ }
+ else
+ {
+ /*
+ * Fail silently. The non-existence of this file
+ * is not necessarily an error.
+ */
+ }
+ }
+ }
+ closedir ( dir );
+}
+
+
+
+void
+QrshServer::string_replaceAll ( string & str,
+ string & target,
+ string & replacement
+ )
+{
+ int target_size = target.size();
+ int found_pos = 0;
+
+ while ( 0 <= (found_pos = str.find ( target ) ) )
+ str.replace ( found_pos, target_size, replacement );
+}
+
+
+
+
+bool
+QrshServer::isProcessName ( char const * str )
+{
+ getNames();
+ map<char *, int>::iterator it;
+ for ( it = abstract_name_map.begin(); it != abstract_name_map.end(); ++ it )
+ {
+ if ( ! strcmp ( str, it->first ) )
+ return true;
+ }
+
+ return false;
+}
+
+
+
+
+
+int
+QrshServer::string_countWords ( char const * s1 )
+{
+ int count = 0;
+ char const * s2 = s1 + 1;
+
+ if ( ! isspace(* s1) )
+ {
+ ++ count;
+ }
+
+ for ( ; * s2; ++ s1, ++ s2 )
+ {
+ // count space-to-word transitions.
+ if ( isspace(*s1) && (! isspace(*s2)) )
+ ++ count;
+ }
+
+ return count;
+}
+
+
+
+
+void
+QrshServer::execute ( Message const & message )
+{
+ // First, gather all the symbolic names we know.
+ getNames();
+
+ // Now make a copy of the command, that I can alter.
+ string command ( message.getData() );
+
+
+ // Replace each occurrence of every abstract name with its pid.
+ char pid_str[100];
+ map<char *, int>::iterator it;
+ for ( it = abstract_name_map.begin(); it != abstract_name_map.end(); ++ it )
+ {
+ sprintf ( pid_str, "%d", it->second );
+ string target ( it->first ),
+ replacement ( pid_str );
+ string_replaceAll ( command, target, replacement );
+ }
+
+
+ char const * truncated_command = skipWord(skipWord(command.c_str()));
+
+ if ( truncated_command )
+ system ( truncated_command );
+}
+
+
+
+
+
+void
+QrshServer::get ( Message const & request_message )
+{
+ char * file_content;
+
+ /*
+ * Get the contents of the requested file.
+ */
+ char file_or_process_name[1000];
+ sscanf ( request_message.getData().c_str(), "%*s%*s%s", file_or_process_name );
+
+ if ( isProcessName ( file_or_process_name ) )
+ {
+ stringstream desired_file_name;
+ desired_file_name << data_dir.str()
+ << '/'
+ << file_or_process_name
+ << '/';
+ char requested_output_stream[1000];
+ if(1 != sscanf ( request_message.getData().c_str(),
+ "%*s%*s%*s%s",
+ requested_output_stream
+ )
+ )
+ {
+ fprintf ( stderr,
+ "QrshServer::get error: Can't read requested data file name from this message: |%s|\n",
+ request_message.getData().c_str()
+ );
+ return;
+ }
+ desired_file_name << requested_output_stream;
+ file_content = file2str ( desired_file_name.str().c_str() );
+ }
+ else
+ {
+ file_content = file2str ( file_or_process_name );
+ }
+
+ stringstream reply_data ;
+ reply_data << "get_response "
+ << file_content;
+ /*
+ * Send a response-message to the server who is waiting.
+ */
+ send ( reply_data.str() );
+}
+
+
+
+
+
+
+void
+QrshServer::exited ( Message const & message )
+{
+ int exit_code = -1;
+
+ // First, gather all the symbolic names we know.
+ getNames();
+
+ // Now make a copy of the command, that I can alter.
+ string edited_command ( message.getData() );
+
+ // Replace each occurrence of every abstract name with its pid.
+ char pid_str[100];
+ map<char *, int>::iterator it;
+ for ( it = abstract_name_map.begin(); it != abstract_name_map.end(); ++ it )
+ {
+ sprintf ( pid_str, "%d", it->second );
+ string target ( it->first ),
+ replacement ( pid_str );
+ string_replaceAll ( edited_command, target, replacement );
+ }
+
+ // Skip the service name. That is not used by the child.
+ char const * truncated_command = skipWord(edited_command.c_str());
+
+ if ( truncated_command )
+ {
+ stringstream ss;
+ ss << qrsh_run_path
+ << ' '
+ << data_dir.str()
+ << ' '
+ << truncated_command;
+
+ int child_pid;
+ if ( ! (child_pid = fork() ) )
+ {
+ // This is the child.
+
+ char ** argv = getArgs ( ss.str().c_str() );
+ execv ( qrsh_run_path.c_str(), argv );
+
+ perror ( "qrsh_server: execv error: " );
+ exit ( 1 );
+ }
+ else
+ {
+ // This is the parent.
+ pid_t awaited_pid;
+ while ( 0 == (awaited_pid = waitpid ( child_pid, & exit_code, WNOHANG)) )
+ {
+ fprintf ( stderr, "qrsh_server info: parent: waiting for child...\n" );
+ sleep(1);
+ }
+
+ if ( -1 == awaited_pid )
+ {
+ fprintf ( stderr, "qrsh_server error awaiting child!\n" );
+ exit ( 1 );
+ }
+
+ exit_code >>= 8;
+
+ stringstream data;
+ data << "wait_response "
+ << exit_code;
+
+ send ( data.str() );
+ }
+ }
+}
+
+
+
+
+void
+QrshServer::wait ( Message const & message )
+{
+ bool pre_existing = false;
+ if ( 3 == string_countWords ( message.getData().c_str() ) )
+ {
+ // The first word is the name of this service.
+ // The second word is "exec_wait".
+ // The third word is the symbolic name of the command to wait for.
+ // The fact that there are exactly three words means that this
+ // must be a command that has already been named and started --
+ // we just need to find its pid and wait on it.
+ pre_existing = true;
+ }
+
+
+ int exit_code = -1;
+
+ // First, gather all the symbolic names we know.
+ getNames();
+
+ // Now make a copy of the command, that I can alter.
+ string edited_command ( message.getData() );
+
+ // Replace each occurrence of every abstract name with its pid.
+ char pid_str[100];
+ map<char *, int>::iterator it;
+ for ( it = abstract_name_map.begin(); it != abstract_name_map.end(); ++ it )
+ {
+ sprintf ( pid_str, "%d", it->second );
+ string target ( it->first ),
+ replacement ( pid_str );
+ string_replaceAll ( edited_command, target, replacement );
+ }
+
+ // Skip the service name. That is not used by the child.
+ char const * truncated_command = skipWord(edited_command.c_str());
+
+ if ( truncated_command )
+ {
+ stringstream ss;
+ ss << qrsh_run_path
+ << ' '
+ << data_dir.str()
+ << ' '
+ << truncated_command;
+
+ int child_pid;
+ if ( ! (child_pid = fork() ) )
+ {
+ // This is the child.
+
+ char ** argv = getArgs ( ss.str().c_str() );
+ execv ( qrsh_run_path.c_str(), argv );
+
+ perror ( "qrsh_server: execv error: " );
+ exit ( 1 );
+ }
+ else
+ {
+ // This is the parent.
+ pid_t awaited_pid;
+ while ( 0 == (awaited_pid = waitpid ( child_pid, & exit_code, WNOHANG)) )
+ {
+ fprintf ( stderr, "qrsh_server info: parent: waiting for child...\n" );
+ sleep(1);
+ }
+
+ if ( -1 == awaited_pid )
+ {
+ fprintf ( stderr, "qrsh_server error awaiting child!\n" );
+ exit ( 1 );
+ }
+ }
+
+ exit_code >>= 8;
+
+ stringstream data;
+ data << "wait_response "
+ << exit_code;
+
+ send ( data.str() );
+ }
+}
+
+
+
+
+
+char const *
+QrshServer::skipWord ( char const * s )
+{
+ if(! (s && *s) )
+ return 0;
+
+ // skip past initial white space
+ while ( isspace(*s) )
+ {
+ ++ s;
+ if(! *s)
+ return 0;
+ }
+
+ // skip past first word
+ while ( ! isspace(*s) )
+ {
+ ++ s;
+ if(! *s)
+ return 0;
+ }
+
+ return s;
+}
+
+
+
+
+
+char **
+QrshServer::getArgs ( char const * str )
+{
+ char const * s = str;
+
+ char ** argv = 0;
+ vector<int> start_positions,
+ lengths;
+
+ int pos = 0;
+ int arg_len = 0;
+
+ int n_args = 0;
+ while ( 1 )
+ {
+ // advance over whitespace.
+ while ( isspace ( *s ) )
+ {
+ ++ s; ++ pos;
+ if(! *s)
+ {
+ goto done;
+ }
+ }
+
+ ++ n_args;
+ start_positions.push_back ( pos );
+ arg_len = 0;
+
+ // advance over non-whitespace.
+ while ( ! isspace ( *s ) )
+ {
+ ++ s; ++ pos; ++ arg_len;
+ if(! *s)
+ {
+ lengths.push_back ( arg_len );
+ arg_len = 0;
+ goto done;
+ }
+ }
+
+ lengths.push_back ( arg_len );
+ arg_len = 0;
+ }
+
+ done:
+
+ if ( arg_len > 0 )
+ lengths.push_back ( arg_len );
+
+ // Alloc the array.
+ argv = (char **) malloc ( sizeof(char *) * ( n_args + 1 ) );
+ argv[n_args] = 0; // mull-term the array.
+
+ for ( int i = 0; i < n_args; ++ i )
+ {
+ argv[i] = ( char *) malloc ( lengths[i] + 1 );
+ strncpy ( argv[i],
+ str + start_positions[i],
+ lengths[i]
+ );
+ argv[i][lengths[i]] = 0;
+ }
+
+ return argv;
+}
+
+
+
+void
+QrshServer::runCommand ( Message const & message )
+{
+ char const * s = message.getData().c_str();
+
+ /*
+ * Skip the first word, which is this server's name.
+ */
+ while ( isspace(*s) ) // go to start of first word.
+ ++ s;
+
+ while ( ! isspace(*s) ) // go to end of first word.
+ ++ s;
+
+ while ( isspace(*s) ) // go to start of second word.
+ ++ s;
+
+ char command_name[1000];
+ sscanf ( s, "%s", command_name );
+
+ if ( ! strcmp ( "get", command_name ) )
+ {
+ get ( message );
+ }
+ else
+ if ( ! strcmp ( "exited", command_name ) )
+ {
+ exited ( message );
+ }
+ else
+ if ( ! strcmp ( "exec_wait", command_name ) )
+ {
+ wait ( message );
+ }
+ else
+ if ( ! strcmp ( "exec", command_name ) )
+ {
+ execute ( message );
+ }
+ else
+ if ( ! strcmp ( "start", command_name ) )
+ {
+ start ( );
+ }
+ else
+ if ( ! strcmp ( "alias", command_name ) )
+ {
+ addAlias ( message );
+ }
+ else
+ if ( ! strcmp ( "sayName", command_name ) )
+ {
+ sayName ( );
+ }
+ else
+ {
+ /*
+ * If the command is not any of the "special" commands
+ * above, then it's a "normal" command.
+ * That means we run it with a child process instance of
+ * qrsh_run, which will save all its data in the qrsh dir.
+ */
+ stringstream ss;
+ ss << qrsh_run_path
+ << ' '
+ << data_dir.str()
+ << ' '
+ << s;
+
+ if ( ! fork() )
+ {
+ char ** argv = getArgs ( ss.str().c_str() );
+ execv ( qrsh_run_path.c_str(), argv );
+ perror ( "qrsh_server: execv error: " );
+ }
+ }
+}
+
+
+
+void
+QrshServer::received ( Message & message )
+{
+ if ( myMessage ( message ) )
+ runCommand ( message );
+}
+
+
+
+}} // namespace qpid::tests
+
+using namespace qpid::tests;
+
+/*
+ * fixme mick Mon Aug 3 10:29:26 EDT 2009
+ * argv[1] server name
+ * argv[2] qrsh exe path
+ * argv[3] host
+ * argv[4] port
+ */
+int
+main ( int /*argc*/, char** argv )
+{
+ const char* host = argv[3];
+ int port = atoi(argv[4]);
+ Connection connection;
+ Message msg;
+
+ srand ( getpid() );
+
+ try
+ {
+ connection.open ( host, port );
+ Session session = connection.newSession();
+
+
+ // Declare queues.
+ string myQueue = session.getId().getName();
+ session.queueDeclare ( arg::queue=myQueue,
+ arg::exclusive=true,
+ arg::autoDelete=true);
+
+ session.exchangeBind ( arg::exchange="amq.fanout",
+ arg::queue=myQueue,
+ arg::bindingKey="my-key");
+
+ // Create a server and subscribe it to my queue.
+ SubscriptionManager subscriptions ( session );
+ QrshServer server ( subscriptions,
+ argv[1], // server name
+ argv[2], // qrsh exe path
+ host,
+ port
+ );
+ subscriptions.subscribe ( server, myQueue );
+
+ // Receive messages until the subscription is cancelled
+ // by QrshServer::received()
+ subscriptions.run();
+
+ connection.close();
+ }
+ catch(const exception& error)
+ {
+ cout << error.what() << endl;
+ return 1;
+ }
+
+ return 0;
+}
+
+
+
+
diff --git a/qpid/cpp/src/tests/qrsh_utils/10_all b/qpid/cpp/src/tests/qrsh_utils/10_all
new file mode 100755
index 0000000000..7b486ea672
--- /dev/null
+++ b/qpid/cpp/src/tests/qrsh_utils/10_all
@@ -0,0 +1,30 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+#! /bin/bash
+
+echo "Asking all servers to say their names... "
+qrsh 127.0.0.1 5813 \
+ all sayName
+
+
+
+
diff --git a/qpid/cpp/src/tests/qrsh_utils/1_remote_run b/qpid/cpp/src/tests/qrsh_utils/1_remote_run
new file mode 100755
index 0000000000..5b9b307bba
--- /dev/null
+++ b/qpid/cpp/src/tests/qrsh_utils/1_remote_run
@@ -0,0 +1,26 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+#! /bin/bash
+
+
+./qrsh 127.0.0.1 5813 \
+ mrg23 command_1 /home/mick/redhat/qrsh/qrsh_run/my_command foo bar baz
diff --git a/qpid/cpp/src/tests/qrsh_utils/2_forever b/qpid/cpp/src/tests/qrsh_utils/2_forever
new file mode 100755
index 0000000000..5528b0e4d8
--- /dev/null
+++ b/qpid/cpp/src/tests/qrsh_utils/2_forever
@@ -0,0 +1,26 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+#! /bin/bash
+
+
+./qrsh 127.0.0.1 5813 \
+ mrg23 command_2 /home/mick/redhat/qrsh/qrsh_run/forever foo bar baz
diff --git a/qpid/cpp/src/tests/qrsh_utils/3_kill_it b/qpid/cpp/src/tests/qrsh_utils/3_kill_it
new file mode 100755
index 0000000000..afc7a03c9d
--- /dev/null
+++ b/qpid/cpp/src/tests/qrsh_utils/3_kill_it
@@ -0,0 +1,27 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+#! /bin/bash
+
+echo "Killing command 2... "
+./qrsh 127.0.0.1 5813 \
+ mrg23 exec kill -9 command_2
+
diff --git a/qpid/cpp/src/tests/qrsh_utils/4_wait_for_it b/qpid/cpp/src/tests/qrsh_utils/4_wait_for_it
new file mode 100755
index 0000000000..a4dc0da1ce
--- /dev/null
+++ b/qpid/cpp/src/tests/qrsh_utils/4_wait_for_it
@@ -0,0 +1,26 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+#! /bin/bash
+
+./qrsh 127.0.0.1 5813 \
+ mrg23 exec_wait /home/mick/redhat/qrsh/qrsh_run/my_command foo bar baz
+echo "my_command returned an exit code of $?"
diff --git a/qpid/cpp/src/tests/qrsh_utils/5_exited b/qpid/cpp/src/tests/qrsh_utils/5_exited
new file mode 100755
index 0000000000..4fec1dcc79
--- /dev/null
+++ b/qpid/cpp/src/tests/qrsh_utils/5_exited
@@ -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.
+ *
+ */
+
+#! /bin/bash
+
+path=/home/mick/redhat/qrsh/qrsh_run
+
+echo "Running command_3 ..."
+./qrsh 127.0.0.1 5813 \
+ mrg23 command_3 $path/my_command foo bar baz
+
+echo "Now I do some other stuff..."
+sleep 1
+echo "And then some more stuff..."
+sleep 1
+echo "and so on..."
+sleep 1
+
+echo "Now I'm waiting for command_3 ..."
+./qrsh 127.0.0.1 5813 \
+ mrg23 exited command_3
+echo "has command_3 exited: $? ."
+sleep 5
+
+./qrsh 127.0.0.1 5813 \
+ mrg23 exited command_3
+echo "has command_3 exited: $? ."
+sleep 5
+
+./qrsh 127.0.0.1 5813 \
+ mrg23 exited command_3
+echo "has command_3 exited: $? ."
+sleep 5
+
+./qrsh 127.0.0.1 5813 \
+ mrg23 exited command_3
+echo "has command_3 exited: $? ."
+sleep 5
+
+./qrsh 127.0.0.1 5813 \
+ mrg23 exited command_3
+echo "has command_3 exited: $? ."
+sleep 5
+
+
+
diff --git a/qpid/cpp/src/tests/qrsh_utils/6_get b/qpid/cpp/src/tests/qrsh_utils/6_get
new file mode 100755
index 0000000000..4b35ca98e6
--- /dev/null
+++ b/qpid/cpp/src/tests/qrsh_utils/6_get
@@ -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.
+ *
+ */
+
+#! /bin/bash
+
+echo "getting /tmp/foo ..."
+./qrsh 127.0.0.1 5813 \
+ mrg23 get /tmp/foo
+
+
+
diff --git a/qpid/cpp/src/tests/qrsh_utils/7_get_output b/qpid/cpp/src/tests/qrsh_utils/7_get_output
new file mode 100755
index 0000000000..59911089ec
--- /dev/null
+++ b/qpid/cpp/src/tests/qrsh_utils/7_get_output
@@ -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.
+ *
+ */
+
+#! /bin/bash
+
+echo "Run a command..."
+./qrsh 127.0.0.1 5813 \
+ mrg23 command_4 /home/mick/redhat/qrsh/qrsh_run/my_command foo bar baz
+
+echo "Wait for a while..."
+sleep 20
+
+echo "Get stderr output:"
+echo "------------- begin stderr ---------------"
+./qrsh 127.0.0.1 5813 \
+ mrg23 get command_4 stderr
+echo "------------- end stderr ---------------"
+echo " "
+echo " "
+echo " "
+echo "Get stdout output:"
+echo "------------- begin stdout ---------------"
+./qrsh 127.0.0.1 5813 \
+ mrg23 get command_4 stdout
+echo "------------- end stdout ---------------"
+
diff --git a/qpid/cpp/src/tests/qrsh_utils/8_any b/qpid/cpp/src/tests/qrsh_utils/8_any
new file mode 100755
index 0000000000..2a922ea0e0
--- /dev/null
+++ b/qpid/cpp/src/tests/qrsh_utils/8_any
@@ -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.
+ *
+ */
+
+#! /bin/bash
+
+echo "asking any server to say his name ..."
+./qrsh 127.0.0.1 5813 \
+ any sayName
+sleep 1
+echo "asking any server to say his name ..."
+./qrsh 127.0.0.1 5813 \
+ any sayName
+sleep 1
+echo "asking any server to say his name ..."
+./qrsh 127.0.0.1 5813 \
+ any sayName
+sleep 1
+echo "asking any server to say his name ..."
+./qrsh 127.0.0.1 5813 \
+ any sayName
+sleep 1
+
+
+
+
diff --git a/qpid/cpp/src/tests/qrsh_utils/9_alias b/qpid/cpp/src/tests/qrsh_utils/9_alias
new file mode 100755
index 0000000000..a4cfdfdf9a
--- /dev/null
+++ b/qpid/cpp/src/tests/qrsh_utils/9_alias
@@ -0,0 +1,38 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+#! /bin/bash
+
+# Make a group of two of the servers, using "alias",
+# and send the group a command.
+
+qrsh 127.0.0.1 5813 \
+ mrg22 alias group_1
+qrsh 127.0.0.1 5813 \
+ mrg23 alias group_1
+
+echo "Asking group_1 to say their names... "
+qrsh 127.0.0.1 5813 \
+ group_1 sayName
+
+
+
+
diff --git a/qpid/cpp/src/tests/qrsh_utils/qrsh_example_command.cpp b/qpid/cpp/src/tests/qrsh_utils/qrsh_example_command.cpp
new file mode 100644
index 0000000000..386e2f73f0
--- /dev/null
+++ b/qpid/cpp/src/tests/qrsh_utils/qrsh_example_command.cpp
@@ -0,0 +1,52 @@
+/*
+ *
+ * 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 <stdio.h>
+#include <unistd.h>
+
+
+
+main ( int argc, char ** argv )
+{
+ fprintf ( stderr, "Hello, I am the Example Child!\n");
+ fprintf ( stderr, "my arguments %d are:\n", argc - 1 );
+ fprintf ( stdout, "And hello to stdout, too!\n");
+
+ int i;
+ for ( i = 1; i < argc; ++ i )
+ {
+ fprintf ( stderr, "arg %d: |%s|\n", i, argv[i] );
+ }
+
+ for ( i = 0; i < 15; ++ i )
+ {
+ fprintf ( stderr, "child sleeping...\n" );
+ sleep ( 1 );
+ }
+
+ fprintf ( stderr, "child exiting with code 13.\n" );
+
+ return 13;
+}
+
+
+
+
diff --git a/qpid/cpp/src/tests/qrsh_utils/qrsh_forever.cpp b/qpid/cpp/src/tests/qrsh_utils/qrsh_forever.cpp
new file mode 100644
index 0000000000..191a9bca11
--- /dev/null
+++ b/qpid/cpp/src/tests/qrsh_utils/qrsh_forever.cpp
@@ -0,0 +1,50 @@
+/*
+ *
+ * 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 <stdio.h>
+#include <unistd.h>
+
+
+
+main ( int argc, char ** argv )
+{
+ fprintf ( stderr, "Hello, I am the Forever Example Child!\n");
+ fprintf ( stderr, "my %d arguments are:\n", argc - 1 );
+
+ int i;
+ for ( i = 1; i < argc; ++ i )
+ fprintf ( stderr, "arg %d: |%s|\n", i, argv[i] );
+
+ for ( i = 0; i >= 0; ++ i )
+ {
+ fprintf ( stderr, "child sleeping forever %d ...\n" , i);
+ sleep ( 1 );
+ }
+
+ fprintf ( stderr, "child exiting with code 12.\n" );
+
+ return 12;
+}
+
+
+
+
diff --git a/qpid/cpp/src/tests/qrsh_utils/qsh_doc.txt b/qpid/cpp/src/tests/qrsh_utils/qsh_doc.txt
new file mode 100644
index 0000000000..ad5990b38b
--- /dev/null
+++ b/qpid/cpp/src/tests/qrsh_utils/qsh_doc.txt
@@ -0,0 +1,309 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+##############################################
+ qrsh: a Qpid-based remote shell utility
+
+ Last updated: 3 Aug 09 Mick Goulish
+##############################################
+
+
+
+=============================
+Overview
+=============================
+
+ You're writing a multi-box test, and you want to write a
+ shell script in which you start processes on other boxes
+ and kill them (or send arbitrary signals to them).
+
+ But ssh doesn't let you signal them, and bash isn't the
+ greatest language in the world for creating data structures
+ (like you need to associate the PIDs with box names and
+ executable names.)
+
+ Qsh is a utility implemented on Qpid that you can use from
+ within your bash script, or any other scripting language.
+ With it, you can:
+
+ 1. run any executable on any box in your cluster.
+
+ 2. don't worry about PIDs and box-names. You associate
+ your own abstract names with the executable instances,
+ and then use those names in the rest of your script.
+ I.e. "broker_1" "sender_3" etc.
+
+ 3. Launch the executable and wait until it returns, and
+ get its exit code.
+
+ 4. Launch your executable and do other stuff, then come
+ back later and see if it has exited.
+
+ 5. Get whatever it sent to stdout or stderr.
+
+ 6. Get the contents of any other file.
+
+ 7. send a command to all your boxes at once
+
+ 8. send a command to a randomly selected box.
+
+ 9. define groups of boxes, and send a command simultaneously
+ to all boxes in a given group.
+
+
+
+
+=============================
+Using It
+=============================
+
+ 1. You need to run a Qpid broker.
+
+ 2. You start a Qpid client ( which is called a qrsh_server )
+ on all the boxes you care about. And you give them all
+ names like "mrg13", "mrg14" etc. The names can be anything
+ you want, but I've always used one qrsh_server per box,
+ and given it the box name. ( However, you can run two on
+ one box, they won't collide. )
+
+ 3. After you start all servers, send a "start" command to any
+ one of them:
+
+ 4. The qrsh_servers use the fanout exchange to talk to each
+ other.
+
+ 5. In your script, you run an executable called "qrsh". It knows
+ how to talk to the servers, do what you want, and retrieve
+ the data you want.
+
+
+ example start script: (this does 4 servers on the same box)
+ -------------------------------------------------------------
+
+ echo "Starting server mrg22 ..."
+ ./qrsh_server mrg22 ./qrsh_run 127.0.0.1 5813 &
+
+ echo "Starting server mrg23 ..."
+ ./qrsh_server mrg23 ./qrsh_run 127.0.0.1 5813 &
+
+ echo "Starting server mrg24 ..."
+ ./qrsh_server mrg24 ./qrsh_run 127.0.0.1 5813 &
+
+ echo "Starting server mrg25 ..."
+ ./qrsh_server mrg25 ./qrsh_run 127.0.0.1 5813 &
+
+ echo "Issuing start command..."
+ sleep 2
+ ./qrsh 127.0.0.1 5813 mrg22 start
+ sleep 1
+
+ echo "Ready."
+
+ # end of script.
+
+
+
+
+
+
+=============================
+Qrsh Syntax
+=============================
+
+ qrsh host port server_name command_name arg*
+
+
+ "host" and "port" specify the Qpid server to connect to.
+
+ "server_name" can be anything you want. I always use the name
+ of the box that the server is running on.
+
+ "command_name" is the name that you choose to assign to
+ the process you are running. Each process that you decide
+ to name must have a unique name within this script.
+
+ Or it could be a reserved command name, that Qsh
+ interprets in a special way.
+
+ Reserved command names are:
+
+ exec
+ exec_wait
+ exited
+ get
+
+ "exec" means "interpret the rest of the command line as a
+ command to be executed by the designated server.
+
+ "exec_wait" means same as "exec", but wait for the command
+ to terminate, and return its exit code.
+
+ "exited" -- you provide 1 arg, which is an abstract
+ process name. qrsh returns 1 if that process has exited,
+ else 0.
+
+ "get" -- you provide one arg which is a path. qrsh returns
+ (by printing to stdout) the contents of that file.
+
+ "arg*" is zero or more arguments. They are interpreted
+ differently depending on whether you are using one of
+ the above reserved command names, or making up your own
+ abstract name for a command.
+
+
+
+
+=============================
+Examples
+=============================
+
+ 1. Run a process on a remote box.
+
+ qrsh mrg23 command_1 /usr/sbin/whatever foo bar baz
+
+ Returns immediately.
+
+
+
+ 2. Kill a process that you started earlier:
+
+ qrsh mrg23 exec kill -9 command_1
+
+ After the word "exec" put any command line you want.
+ The server you're sending this to will replace all abstract
+ names in the command with process IDs. ( In this example,
+ just the word "command_1" will be replaced. ) Then it will
+ execute the command.
+
+
+
+ 3. Execute a command, and wait for it to finish
+
+ qrsh mrg23 exec_wait command_name args
+
+
+
+ 4. Check on whether a command you issude earlier has exited.
+
+ ./qrsh mrg23 exited command_3
+
+ Returns 1 if it has exited, else 0.
+
+
+
+ 5. Get the contents of a file from the remote system:
+
+ ./qrsh mrg23 get /tmp/foo
+
+ Prints the contents to stdout.
+
+
+
+ 6. Send a command to all servers at once:
+
+ # This example causes them all to print thir names to stderr.
+ ./qrsh all sayName
+
+
+ 7. Define a group of servers and send a command to that group.
+
+ #! /bin/bash
+
+ # Make a group of two of the servers, using "alias",
+ # and send the group a command.
+
+ qrsh 127.0.0.1 5813 \
+ mrg22 alias group_1
+
+ qrsh 127.0.0.1 5813 \
+ mrg23 alias group_1
+
+ echo "Asking group_1 to say their names... "
+ qrsh 127.0.0.1 5813 \
+ group_1 sayName
+
+ # end of script.
+
+
+
+
+ 8. Execute a command and get its stdout and stderr contents.
+
+ #! /bin/bash
+
+ echo "Run a command..."
+ ./qrsh 127.0.0.1 5813 \
+ mrg23 command_4 my_command foo bar baz
+
+ echo "Wait for a while..."
+ sleep 10
+
+ echo "Get stderr output:"
+ echo "------------- begin stderr ---------------"
+ ./qrsh 127.0.0.1 5813 \
+ mrg23 get command_4 stderr
+ echo "------------- end stderr ---------------"
+ echo " "
+
+ echo " "
+ echo "Get stdout output:"
+ echo "------------- begin stdout ---------------"
+ ./qrsh 127.0.0.1 5813 \
+ mrg23 get command_4 stdout
+ echo "------------- end stdout ---------------"
+
+ # end of script.
+
+
+
+
+ 9. Send a command to one of your servers, selected
+ at random.
+
+ #! /bin/bash
+
+ # I do it multiple times here, so I can see
+ # that it really is selecting randomly.
+
+ echo "asking any server to say his name ..."
+ ./qrsh 127.0.0.1 5813 \
+ any sayName
+ sleep 1
+
+ echo "asking any server to say his name ..."
+ ./qrsh 127.0.0.1 5813 \
+ any sayName
+ sleep 1
+
+ echo "asking any server to say his name ..."
+ ./qrsh 127.0.0.1 5813 \
+ any sayName
+ sleep 1
+
+ echo "asking any server to say his name ..."
+ ./qrsh 127.0.0.1 5813 \
+ any sayName
+
+ # end of script.
+
+
+
+
diff --git a/qpid/cpp/src/tests/queue_flow_limit_tests.py b/qpid/cpp/src/tests/queue_flow_limit_tests.py
index dec7cfb3af..ac62dcdd1e 100644
--- a/qpid/cpp/src/tests/queue_flow_limit_tests.py
+++ b/qpid/cpp/src/tests/queue_flow_limit_tests.py
@@ -24,7 +24,7 @@ from qpid import datatypes, messaging
from qpid.messaging import Message, Empty
from threading import Thread, Lock
from logging import getLogger
-from time import sleep, time
+from time import sleep
from os import environ, popen
class QueueFlowLimitTests(TestBase010):
@@ -37,8 +37,7 @@ class QueueFlowLimitTests(TestBase010):
def _create_queue(self, name,
stop_count=None, resume_count=None,
- stop_size=None, resume_size=None,
- max_size=None, max_count=None):
+ stop_size=None, resume_size=None):
""" Create a queue with the given flow settings via the queue.declare
command.
"""
@@ -51,11 +50,6 @@ class QueueFlowLimitTests(TestBase010):
args["qpid.flow_stop_size"] = stop_size;
if (resume_size is not None):
args["qpid.flow_resume_size"] = resume_size;
- if (max_size is not None):
- args["qpid.max_size"] = max_size;
- if (max_count is not None):
- args["qpid.max_count"] = max_count;
-
self.session.queue_declare(queue=name, arguments=args)
@@ -71,10 +65,6 @@ class QueueFlowLimitTests(TestBase010):
self.assertEqual(i.arguments.get("qpid.flow_stop_size"), stop_size)
if (resume_size is not None):
self.assertEqual(i.arguments.get("qpid.flow_resume_size"), resume_size)
- if (max_size is not None):
- self.assertEqual(i.arguments.get("qpid.max_size"), max_size)
- if (max_count is not None):
- self.assertEqual(i.arguments.get("qpid.max_count"), max_count)
self.failIf(i.flowStopped)
return i.getObjectId()
self.fail("Unable to create queue '%s'" % name)
@@ -87,7 +77,7 @@ class QueueFlowLimitTests(TestBase010):
self.session.queue_delete(queue=name)
- def _start_qpid_send(self, queue, count, content="X", capacity=100):
+ def _start_qpid_send(self, queue, count, content="X", capacity=10):
""" Use the qpid-send client to generate traffic to a queue.
"""
command = "qpid-send" + \
@@ -147,18 +137,19 @@ class QueueFlowLimitTests(TestBase010):
"""
self.startQmf();
oid = self._create_queue("test-q", stop_count=373, resume_count=229)
- self.assertEqual(self.qmf.getObjects(_objectId=oid)[0].flowStoppedCount, 0)
sndr1 = self._start_qpid_send("test-q", count=1213, content="XXX", capacity=50);
sndr2 = self._start_qpid_send("test-q", count=797, content="Y", capacity=13);
sndr3 = self._start_qpid_send("test-q", count=331, content="ZZZZZ", capacity=149);
totalMsgs = 1213 + 797 + 331
+
# wait until flow control is active
- deadline = time() + 10
- while (not self.qmf.getObjects(_objectId=oid)[0].flowStopped) and \
- time() < deadline:
- pass
+ count = 0
+ while self.qmf.getObjects(_objectId=oid)[0].flowStopped == False and \
+ count < 10:
+ sleep(1);
+ count += 1;
self.failUnless(self.qmf.getObjects(_objectId=oid)[0].flowStopped)
depth = self.qmf.getObjects(_objectId=oid)[0].msgDepth
self.assertGreater(depth, 373)
@@ -189,7 +180,6 @@ class QueueFlowLimitTests(TestBase010):
self.assertEqual(count, totalMsgs)
self.failIf(self.qmf.getObjects(_objectId=oid)[0].flowStopped)
- self.failUnless(self.qmf.getObjects(_objectId=oid)[0].flowStoppedCount)
self._delete_queue("test-q")
@@ -206,12 +196,14 @@ class QueueFlowLimitTests(TestBase010):
sndr2 = self._start_qpid_send("test-q", count=1129, content="Y"*631, capacity=13);
sndr3 = self._start_qpid_send("test-q", count=881, content="Z"*823, capacity=149);
totalMsgs = 1699 + 1129 + 881
+ totalBytes = 439 + 631 + 823
# wait until flow control is active
- deadline = time() + 10
- while (not self.qmf.getObjects(_objectId=oid)[0].flowStopped) and \
- time() < deadline:
- pass
+ count = 0
+ while self.qmf.getObjects(_objectId=oid)[0].flowStopped == False and \
+ count < 10:
+ sleep(1);
+ count += 1;
self.failUnless(self.qmf.getObjects(_objectId=oid)[0].flowStopped)
self.assertGreater(self.qmf.getObjects(_objectId=oid)[0].byteDepth, 351133)
@@ -246,126 +238,5 @@ class QueueFlowLimitTests(TestBase010):
self._delete_queue("test-q")
- def verify_limit(self, testq):
- """ run a limit check against the testq object
- """
-
- testq.mgmt = self.qmf.getObjects(_objectId=testq.oid)[0]
-
- # fill up the queue, waiting until flow control is active
- sndr1 = self._start_qpid_send(testq.mgmt.name, count=testq.sendCount, content=testq.content)
- deadline = time() + 10
- while (not testq.mgmt.flowStopped) and time() < deadline:
- testq.mgmt.update()
-
- self.failUnless(testq.verifyStopped())
-
- # now consume enough messages to drop below the flow resume point, and
- # verify flow control is released.
- rcvr = self._start_qpid_receive(testq.mgmt.name, count=testq.consumeCount)
- rcvr.readlines() # prints a line for each received msg
- rcvr.close();
-
- # we should now be below the resume threshold
- self.failUnless(testq.verifyResumed())
-
- self._delete_queue(testq.mgmt.name)
- sndr1.close();
-
-
- def test_default_flow_count(self):
- """ Create a queue with count-based size limit, and verify the computed
- thresholds using the broker's default ratios.
- """
- class TestQ:
- def __init__(self, oid):
- # Use the broker-wide default flow thresholds of 80%/70% (see
- # run_queue_flow_limit_tests) to base the thresholds off the
- # queue's max_count configuration parameter
- # max_count == 1000 -> stop == 800, resume == 700
- self.oid = oid
- self.sendCount = 1000
- self.consumeCount = 301 # (send - resume) + 1 to reenable flow
- self.content = "X"
- def verifyStopped(self):
- self.mgmt.update()
- return self.mgmt.flowStopped and (self.mgmt.msgDepth > 800)
- def verifyResumed(self):
- self.mgmt.update()
- return (not self.mgmt.flowStopped) and (self.mgmt.msgDepth < 700)
-
- self.startQmf();
- oid = self._create_queue("test-X", max_count=1000)
- self.verify_limit(TestQ(oid))
-
-
- def test_default_flow_size(self):
- """ Create a queue with byte-based size limit, and verify the computed
- thresholds using the broker's default ratios.
- """
- class TestQ:
- def __init__(self, oid):
- # Use the broker-wide default flow thresholds of 80%/70% (see
- # run_queue_flow_limit_tests) to base the thresholds off the
- # queue's max_count configuration parameter
- # max_size == 10000 -> stop == 8000 bytes, resume == 7000 bytes
- self.oid = oid
- self.sendCount = 2000
- self.consumeCount = 601 # (send - resume) + 1 to reenable flow
- self.content = "XXXXX" # 5 bytes per message sent.
- def verifyStopped(self):
- self.mgmt.update()
- return self.mgmt.flowStopped and (self.mgmt.byteDepth > 8000)
- def verifyResumed(self):
- self.mgmt.update()
- return (not self.mgmt.flowStopped) and (self.mgmt.byteDepth < 7000)
-
- self.startQmf();
- oid = self._create_queue("test-Y", max_size=10000)
- self.verify_limit(TestQ(oid))
-
-
- def test_blocked_queue_delete(self):
- """ Verify that blocked senders are unblocked when a queue that is flow
- controlled is deleted.
- """
-
- class BlockedSender(Thread):
- def __init__(self, tester, queue, count, capacity=10):
- self.tester = tester
- self.queue = queue
- self.count = count
- self.capacity = capacity
- Thread.__init__(self)
- self.done = False
- self.start()
- def run(self):
- # spawn qpid-send
- p = self.tester._start_qpid_send(self.queue,
- self.count,
- self.capacity)
- p.close() # waits for qpid-send to complete
- self.done = True
-
- self.startQmf();
- oid = self._create_queue("kill-q", stop_size=10, resume_size=2)
- q = self.qmf.getObjects(_objectId=oid)[0]
- self.failIf(q.flowStopped)
-
- sender = BlockedSender(self, "kill-q", count=100)
- # wait for flow control
- deadline = time() + 10
- while (not q.flowStopped) and time() < deadline:
- q.update()
-
- self.failUnless(q.flowStopped)
- self.failIf(sender.done) # sender blocked
-
- self._delete_queue("kill-q")
- sender.join(5)
- self.failIf(sender.isAlive())
- self.failUnless(sender.done)
-
-
diff --git a/qpid/cpp/src/tests/replication_test b/qpid/cpp/src/tests/replication_test
index 8c37568875..691fd20b0c 100755
--- a/qpid/cpp/src/tests/replication_test
+++ b/qpid/cpp/src/tests/replication_test
@@ -1,4 +1,4 @@
-#!/bin/bash
+#!/bin/sh
#
# Licensed to the Apache Software Foundation (ASF) under one
diff --git a/qpid/cpp/src/tests/run_acl_tests b/qpid/cpp/src/tests/run_acl_tests
index 41f41e20e1..aff13408ed 100755
--- a/qpid/cpp/src/tests/run_acl_tests
+++ b/qpid/cpp/src/tests/run_acl_tests
@@ -1,4 +1,4 @@
-#!/bin/bash
+#!/bin/sh
#
# Licensed to the Apache Software Foundation (ASF) under one
diff --git a/qpid/cpp/src/tests/run_cli_tests b/qpid/cpp/src/tests/run_cli_tests
index ec5c71b646..3f1388b9f5 100755
--- a/qpid/cpp/src/tests/run_cli_tests
+++ b/qpid/cpp/src/tests/run_cli_tests
@@ -1,4 +1,4 @@
-#!/bin/bash
+#!/bin/sh
#
# Licensed to the Apache Software Foundation (ASF) under one
@@ -70,8 +70,7 @@ stop_brokers() {
if test -d ${PYTHON_DIR} ; then
start_brokers
echo "Running CLI tests using brokers on ports $LOCAL_PORT $REMOTE_PORT"
- PYTHON_TESTS=${PYTHON_TESTS:-$*}
- $QPID_PYTHON_TEST -m cli_tests -b localhost:$LOCAL_PORT -Dremote-port=$REMOTE_PORT -Dcli-dir=$CLI_DIR $targs $PYTHON_TESTS $@
+ $QPID_PYTHON_TEST -m cli_tests -b localhost:$LOCAL_PORT -Dremote-port=$REMOTE_PORT -Dcli-dir=$CLI_DIR $targs $@
RETCODE=$?
stop_brokers
if test x$RETCODE != x0; then
diff --git a/qpid/cpp/src/tests/run_federation_sys_tests b/qpid/cpp/src/tests/run_federation_sys_tests
deleted file mode 100755
index f5f772d72e..0000000000
--- a/qpid/cpp/src/tests/run_federation_sys_tests
+++ /dev/null
@@ -1,97 +0,0 @@
-#!/bin/bash
-
-#
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License. You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied. See the License for the
-# specific language governing permissions and limitations
-# under the License.
-#
-
-# Run the federation system tests.
-
-source ./test_env.sh
-
-MODULENAME=federation_sys
-
-# Test for clustering
-ps -u root | grep 'aisexec\|corosync' > /dev/null
-if (( $? == 0 )); then
- CLUSTERING_ENABLED=1
-else
- echo "WARNING: No clustering detected; tests using it will be ignored."
-fi
-
-# Test for long test
-if [[ "$1" == "LONG_TEST" ]]; then
- USE_LONG_TEST=1
- shift # get rid of this param so it is not treated as a test name
-fi
-
-trap stop_brokers INT TERM QUIT
-
-SKIPTESTS="-i federation_sys.E_* -i federation_sys.F_* -i federation_sys.G_* -i federation_sys.H_*"
-if [ -z ${USE_LONG_TEST} ]; then
- SKIPTESTS="-i federation_sys.A_Long* -i federation_sys.B_Long* ${SKIPTESTS}"
-fi
-echo "WARNING: Tests using persistence will be ignored."
-if [ -z ${CLUSTERING_ENABLED} ]; then
- SKIPTESTS="${SKIPTESTS} -i federation_sys.C_* -i federation_sys.D_*"
-elif [ -z ${USE_LONG_TEST} ]; then
- SKIPTESTS="${SKIPTESTS} -i federation_sys.C_Long* -i federation_sys.D_Long*"
-fi
-
-start_brokers() {
- start_broker() {
- ${QPIDD_EXEC} --daemon --port 0 --auth no --no-data-dir $1 > qpidd.port
- PORT=`cat qpidd.port`
- eval "$2=${PORT}"
- }
- start_broker "" LOCAL_PORT
- start_broker "" REMOTE_PORT
- if [ -n "${CLUSTERING_ENABLED}" ]; then
- start_broker "--load-module ${CLUSTER_LIB} --cluster-name test-cluster-1" CLUSTER_C1_1
- start_broker "--load-module ${CLUSTER_LIB} --cluster-name test-cluster-1" CLUSTER_C1_2
- start_broker "--load-module ${CLUSTER_LIB} --cluster-name test-cluster-2" CLUSTER_C2_1
- start_broker "--load-module ${CLUSTER_LIB} --cluster-name test-cluster-2" CLUSTER_C2_2
- fi
- rm qpidd.port
-}
-
-stop_brokers() {
- ${QPIDD_EXEC} -q --port ${LOCAL_PORT}
- ${QPIDD_EXEC} -q --port ${REMOTE_PORT}
- if [ -n "${CLUSTERING_ENABLED}" ]; then
- ${QPID_CLUSTER_EXEC} --all-stop --force localhost:${CLUSTER_C1_1}
- ${QPID_CLUSTER_EXEC} --all-stop --force localhost:${CLUSTER_C2_1}
- fi
-}
-
-if test -d ${PYTHON_DIR} ; then
- start_brokers
- if [ -z ${CLUSTERING_ENABLED} ]; then
- echo "Running federation tests using brokers on local port ${LOCAL_PORT}, remote port ${REMOTE_PORT} (NOTE: clustering is DISABLED)"
- else
- echo "Running federation tests using brokers on local port ${LOCAL_PORT}, remote port ${REMOTE_PORT}, local cluster nodes ${CLUSTER_C1_1} ${CLUSTER_C1_2}, remote cluster nodes ${CLUSTER_C2_1} ${CLUSTER_C2_2}"
- fi
- if [ -z ${USE_LONG_TEST} ]; then
- echo "NOTE: To run a full set of federation system tests, use \"make check-long\". To test with persistence, run the store version of this script."
- fi
- ${QPID_PYTHON_TEST} -m ${MODULENAME} ${SKIPTESTS} -b localhost:${REMOTE_PORT} -Dlocal-port=${LOCAL_PORT} -Dremote-port=${REMOTE_PORT} -Dlocal-cluster-ports="${CLUSTER_C1_1} ${CLUSTER_C1_2}" -Dremote-cluster-ports="${CLUSTER_C2_1} ${CLUSTER_C2_2}" $@
- RETCODE=$?
- stop_brokers
- if test x${RETCODE} != x0; then
- echo "FAIL federation tests"; exit 1;
- fi
-fi
diff --git a/qpid/cpp/src/tests/run_federation_tests b/qpid/cpp/src/tests/run_federation_tests
index 14af4807ba..4be27a2e85 100755
--- a/qpid/cpp/src/tests/run_federation_tests
+++ b/qpid/cpp/src/tests/run_federation_tests
@@ -1,4 +1,4 @@
-#!/bin/bash
+#!/bin/sh
#
# Licensed to the Apache Software Foundation (ASF) under one
@@ -55,7 +55,7 @@ stop_brokers() {
if test -d ${PYTHON_DIR} ; then
start_brokers
echo "Running federation tests using brokers on ports $LOCAL_PORT $REMOTE_PORT $REMOTE_B1 $REMOTE_B2"
- $QPID_PYTHON_TEST -m federation "$SKIPTESTS" -b localhost:$LOCAL_PORT -Dremote-port=$REMOTE_PORT -Dextra-brokers="$REMOTE_B1 $REMOTE_B2" $@
+ $QPID_PYTHON_TEST -m federation $SKIPTESTS -b localhost:$LOCAL_PORT -Dremote-port=$REMOTE_PORT -Dextra-brokers="$REMOTE_B1 $REMOTE_B2" $@
RETCODE=$?
stop_brokers
if test x$RETCODE != x0; then
diff --git a/qpid/cpp/src/tests/run_header_test b/qpid/cpp/src/tests/run_header_test
index 34008132cc..07658343e7 100755
--- a/qpid/cpp/src/tests/run_header_test
+++ b/qpid/cpp/src/tests/run_header_test
@@ -1,4 +1,4 @@
-#!/bin/bash
+#!/bin/sh
#
# Licensed to the Apache Software Foundation (ASF) under one
diff --git a/qpid/cpp/src/tests/run_long_federation_sys_tests b/qpid/cpp/src/tests/run_long_federation_sys_tests
deleted file mode 100644
index 69dc08d11c..0000000000
--- a/qpid/cpp/src/tests/run_long_federation_sys_tests
+++ /dev/null
@@ -1,24 +0,0 @@
-#! /bin/bash
-
-#
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License. You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied. See the License for the
-# specific language governing permissions and limitations
-# under the License.
-#
-
-# Run the federation system tests (long version).
-
-./run_federation_sys_tests LONG_TEST $@
diff --git a/qpid/cpp/src/tests/run_queue_flow_limit_tests b/qpid/cpp/src/tests/run_queue_flow_limit_tests
index f921cf5e7e..9f2f093353 100755
--- a/qpid/cpp/src/tests/run_queue_flow_limit_tests
+++ b/qpid/cpp/src/tests/run_queue_flow_limit_tests
@@ -35,10 +35,8 @@ error() {
}
start_broker() {
- # Note: if you change the DEFAULT_THRESHOLDS, you will need to update queue_flow_limit_tests.py
- DEFAULT_THRESHOLDS="--default-flow-stop-threshold=80 --default-flow-resume-threshold=70"
rm -rf $LOG_FILE
- PORT=$($QPIDD_EXEC $DEFAULT_THRESHOLDS --auth=no --no-module-dir --daemon --port=0 -t --log-to-file $LOG_FILE) || error "Could not start broker"
+ PORT=$($QPIDD_EXEC --auth=no --no-module-dir --daemon --port=0 -t --log-to-file $LOG_FILE) || error "Could not start broker"
}
stop_broker() {
diff --git a/qpid/cpp/src/tests/run_test b/qpid/cpp/src/tests/run_test
index 6ec1fd892b..4b227621bc 100755
--- a/qpid/cpp/src/tests/run_test
+++ b/qpid/cpp/src/tests/run_test
@@ -1,4 +1,4 @@
-#!/bin/bash
+#!/bin/sh
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
diff --git a/qpid/cpp/src/tests/sasl.mk b/qpid/cpp/src/tests/sasl.mk
index 20eaa7c7a5..5b8419f604 100644
--- a/qpid/cpp/src/tests/sasl.mk
+++ b/qpid/cpp/src/tests/sasl.mk
@@ -30,20 +30,9 @@ check_PROGRAMS+=sasl_version
sasl_version_SOURCES=sasl_version.cpp
sasl_version_LDADD=$(lib_client)
-TESTS += run_cluster_authentication_test sasl_fed sasl_fed_ex_dynamic sasl_fed_ex_link sasl_fed_ex_queue sasl_fed_ex_route sasl_fed_ex_route_cluster sasl_fed_ex_link_cluster sasl_fed_ex_queue_cluster sasl_fed_ex_dynamic_cluster
+TESTS += run_cluster_authentication_test sasl_fed sasl_fed_ex
LONG_TESTS += run_cluster_authentication_soak
-EXTRA_DIST += run_cluster_authentication_test \
- sasl_fed \
- sasl_fed_ex \
- run_cluster_authentication_soak \
- sasl_fed_ex_dynamic \
- sasl_fed_ex_link \
- sasl_fed_ex_queue \
- sasl_fed_ex_route \
- sasl_fed_ex_dynamic_cluster \
- sasl_fed_ex_link_cluster \
- sasl_fed_ex_queue_cluster \
- sasl_fed_ex_route_cluster
+EXTRA_DIST += run_cluster_authentication_test sasl_fed sasl_fed_ex run_cluster_authentication_soak
endif # HAVE_SASL
diff --git a/qpid/cpp/src/tests/sasl_fed b/qpid/cpp/src/tests/sasl_fed
index 884c44177c..9845a20838 100755
--- a/qpid/cpp/src/tests/sasl_fed
+++ b/qpid/cpp/src/tests/sasl_fed
@@ -123,7 +123,7 @@ n_messages=100
#--------------------------------------------------
#echo " Sending 100 messages to $broker_1_port "
#--------------------------------------------------
-$builddir/datagen --count $n_messages | $SENDER_EXEC --mechanism DIGEST-MD5 --username zag --password zag --exchange $EXCHANGE_NAME --routing-key $ROUTING_KEY --port $broker_1_port
+$builddir/datagen --count $n_messages | $SENDER_EXEC --username zag --password zag --exchange $EXCHANGE_NAME --routing-key $ROUTING_KEY --port $broker_1_port
sleep 5
diff --git a/qpid/cpp/src/tests/sasl_fed_ex b/qpid/cpp/src/tests/sasl_fed_ex
index 716a806874..0740650d6c 100755
--- a/qpid/cpp/src/tests/sasl_fed_ex
+++ b/qpid/cpp/src/tests/sasl_fed_ex
@@ -19,52 +19,22 @@
# under the License.
#
+
#===============================================================================
-# These tests create federated links between two brokers using SASL security.
+# This test creates a federated link between two brokers using SASL security.
# The SASL mechanism used is EXTERNAL, which is satisfied by SSL
# transport-layer security.
#===============================================================================
source ./test_env.sh
-script_name=`basename $0`
-
-if [ $# -lt 1 ] || [ $# -gt 2 ]
-then
- echo
- # These are the four different ways of creating links ( or routes+links )
- # that the qpid-route command provides.
- echo "Usage: ${script_name} dynamic|link|queue|route [cluster]"
- echo
- exit 1
-fi
-
-# Has the user told us to do clustering ? -----------
-clustering_flag=
-if [ $# -eq "2" ] && [ "$2" == "cluster" ]; then
- clustering_flag=true
-fi
-
-qpid_route_method=$1
-
-# Debugging print. --------------------------
-debug=
-function print {
- if [ "$debug" ]; then
- echo "${script_name}: $1"
- fi
-}
-
-print "=========== start sasl_fed_ex $* ============"
-
-
# This minimum value corresponds to sasl version 2.1.22
minimum_sasl_version=131350
sasl_version=`$QPID_TEST_EXEC_DIR/sasl_version`
-# This test is necessary because this sasl version is the first one that permits
+# This test is necessary becasue this sasl version is the first one that permits
# redirection of the sasl config file path.
if [ "$sasl_version" -lt "$minimum_sasl_version" ]; then
echo "sasl_fed: must have sasl version 2.1.22 or greater. ( Integer value: $minimum_sasl_version ) Version is: $sasl_version"
@@ -90,7 +60,6 @@ create_certs() {
delete_certs() {
if [[ -e ${CERT_DIR} ]] ; then
- print "removing cert dir ${CERT_DIR}"
rm -rf ${CERT_DIR}
fi
}
@@ -103,40 +72,22 @@ if [[ !(-x $CERTUTIL) ]] ; then
fi
delete_certs
-create_certs 2> /dev/null
-if [ ! $? ]; then
- error "Could not create test certificate"
- exit 1
-fi
+create_certs || error "Could not create test certificate"
-sasl_config_dir=$builddir/sasl_config
-tmp_root=${builddir}/sasl_fed_ex_temp
-print "results dir is ${tmp_root}"
-rm -rf ${tmp_root}
+sasl_config_file=$builddir/sasl_config
+
+my_random_number=$RANDOM
+tmp_root=/tmp/sasl_fed_$my_random_number
mkdir -p $tmp_root
SRC_SSL_PORT=6667
DST_SSL_PORT=6666
-SRC_SSL_PORT_2=6668
-DST_SSL_PORT_2=6669
-
SRC_TCP_PORT=5801
DST_TCP_PORT=5807
-SRC_TCP_PORT_2=5802
-DST_TCP_PORT_2=5803
-
-CLUSTER_NAME_SUFFIX=`hostname | tr '.' ' ' | awk '{print $1}'`
-CLUSTER_1_NAME=sasl_fed_ex_cluster_1_${CLUSTER_NAME_SUFFIX}
-CLUSTER_2_NAME=sasl_fed_ex_cluster_2_${CLUSTER_NAME_SUFFIX}
-
-print "CLUSTER_1_NAME == ${CLUSTER_1_NAME}"
-print "CLUSTER_2_NAME == ${CLUSTER_2_NAME}"
-
-SSL_LIB=${moduledir}/ssl.so
-CLUSTER_LIB=${moduledir}/cluster.so
+SSL_LIB=../.libs/ssl.so
export QPID_SSL_CERT_NAME=${TEST_HOSTNAME}
@@ -165,112 +116,52 @@ export QPID_SSL_CERT_NAME=${TEST_HOSTNAME}
# 5. DST pulls messages off the temp queue on SRC to itself.
#
-COMMON_BROKER_OPTIONS=" \
- --ssl-sasl-no-dict \
- --sasl-config=$sasl_config_dir \
- --ssl-require-client-authentication \
- --auth yes \
- --ssl-cert-db $CERT_DIR \
- --ssl-cert-password-file $CERT_PW_FILE \
- --ssl-cert-name $TEST_HOSTNAME \
- --no-data-dir \
- --no-module-dir \
- --load-module ${SSL_LIB} \
- --mgmt-enable=yes \
- --log-enable info+ \
- --log-source yes \
- --daemon "
-
-
-function start_brokers {
- if [ $1 ]; then
- # clustered ----------------------------------------
- print "Starting SRC cluster"
-
- print " src broker 1"
- $QPIDD_EXEC \
- --port=${SRC_TCP_PORT} \
- --ssl-port ${SRC_SSL_PORT} \
- ${COMMON_BROKER_OPTIONS} \
- --load-module ${CLUSTER_LIB} \
- --cluster-name ${CLUSTER_1_NAME} \
- --log-to-file $tmp_root/qpidd_src.log 2> /dev/null
-
- broker_ports[0]=${SRC_TCP_PORT}
-
- print " src broker 2"
- $QPIDD_EXEC \
- --port=${SRC_TCP_PORT_2} \
- --ssl-port ${SRC_SSL_PORT_2} \
- ${COMMON_BROKER_OPTIONS} \
- --load-module ${CLUSTER_LIB} \
- --cluster-name ${CLUSTER_1_NAME} \
- --log-to-file $tmp_root/qpidd_src_2.log 2> /dev/null
-
- broker_ports[1]=${SRC_TCP_PORT_2}
-
-
- print "Starting DST cluster"
-
- print " dst broker 1"
- $QPIDD_EXEC \
- --port=${DST_TCP_PORT} \
- --ssl-port ${DST_SSL_PORT} \
- ${COMMON_BROKER_OPTIONS} \
- --load-module ${CLUSTER_LIB} \
- --cluster-name ${CLUSTER_2_NAME} \
- --log-to-file $tmp_root/qpidd_dst.log 2> /dev/null
-
- broker_ports[2]=${DST_TCP_PORT}
-
- print " dst broker 2"
- $QPIDD_EXEC \
- --port=${DST_TCP_PORT_2} \
- --ssl-port ${DST_SSL_PORT_2} \
- ${COMMON_BROKER_OPTIONS} \
- --load-module ${CLUSTER_LIB} \
- --cluster-name ${CLUSTER_2_NAME} \
- --log-to-file $tmp_root/qpidd_dst_2.log 2> /dev/null
-
- broker_ports[3]=${DST_TCP_PORT_2}
-
- else
- # vanilla brokers --------------------------------
- print "Starting SRC broker"
- $QPIDD_EXEC \
- --port=${SRC_TCP_PORT} \
- --ssl-port ${SRC_SSL_PORT} \
- ${COMMON_BROKER_OPTIONS} \
- --log-to-file $tmp_root/qpidd_src.log 2> /dev/null
-
- broker_ports[0]=${SRC_TCP_PORT}
-
- print "Starting DST broker"
- $QPIDD_EXEC \
- --port=${DST_TCP_PORT} \
- --ssl-port ${DST_SSL_PORT} \
- ${COMMON_BROKER_OPTIONS} \
- --log-to-file $tmp_root/qpidd_dst.log 2> /dev/null
-
- broker_ports[1]=${DST_TCP_PORT}
- fi
-}
-
-function halt_brokers {
- n_brokers=${#broker_ports[@]}
- print "Halting ${n_brokers} brokers."
- for i in $(seq 0 $((${n_brokers} - 1)))
- do
- halt_port=${broker_ports[$i]}
- print "Halting broker $i on port ${halt_port}"
- $QPIDD_EXEC --port ${halt_port} --quit
- done
-
-}
-
-start_brokers $clustering_flag
+#echo "-----------------------"
+#echo "Starting SRC broker"
+#echo "-----------------------"
+$QPIDD_EXEC \
+ --port=${SRC_TCP_PORT} \
+ --ssl-port ${SRC_SSL_PORT} \
+ --ssl-sasl-no-dict \
+ --sasl-config=$sasl_config_file \
+ --ssl-require-client-authentication \
+ --auth yes \
+ --ssl-cert-db $CERT_DIR \
+ --ssl-cert-password-file $CERT_PW_FILE \
+ --ssl-cert-name $TEST_HOSTNAME \
+ --no-data-dir \
+ --no-module-dir \
+ --load-module ${SSL_LIB} \
+ --mgmt-enable=yes \
+ --log-enable info+ \
+ --log-source yes \
+ --daemon \
+ --log-to-file $tmp_root/qpidd_src.log 2> /dev/null
+
+
+#echo "-----------------------"
+#echo "Starting DST broker"
+#echo "-----------------------"
+$QPIDD_EXEC \
+ --port=${DST_TCP_PORT} \
+ --ssl-port ${DST_SSL_PORT} \
+ --ssl-cert-db $CERT_DIR \
+ --ssl-cert-password-file $CERT_PW_FILE \
+ --ssl-cert-name $TEST_HOSTNAME \
+ --ssl-sasl-no-dict \
+ --ssl-require-client-authentication \
+ --sasl-config=$sasl_config_file \
+ --no-data-dir \
+ --no-module-dir \
+ --load-module ${SSL_LIB} \
+ --mgmt-enable=yes \
+ --log-enable info+ \
+ --log-source yes \
+ --daemon \
+ $COMMON_BROKER_OPTIONS \
+ --log-to-file $tmp_root/qpidd_dst.log 2> /dev/null
# I am not randomizing these names, because this test creates its own brokers.
@@ -279,83 +170,76 @@ ROUTING_KEY=sasl_fed_queue
EXCHANGE_NAME=sasl_fedex
-print "add exchanges"
+#echo "-----------------------"
+#echo "add exchanges"
+#echo "-----------------------"
$QPID_CONFIG_EXEC -a localhost:${SRC_TCP_PORT} add exchange direct $EXCHANGE_NAME
$QPID_CONFIG_EXEC -a localhost:${DST_TCP_PORT} add exchange direct $EXCHANGE_NAME
-print "add queues"
+#echo "-----------------------"
+#echo "add queues"
+#echo "-----------------------"
$QPID_CONFIG_EXEC -a localhost:${SRC_TCP_PORT} add queue $QUEUE_NAME
$QPID_CONFIG_EXEC -a localhost:${DST_TCP_PORT} add queue $QUEUE_NAME
-print "create bindings"
+#echo "-----------------------"
+#echo "create bindings"
+#echo "-----------------------"
$QPID_CONFIG_EXEC -a localhost:${SRC_TCP_PORT} bind $EXCHANGE_NAME $QUEUE_NAME $ROUTING_KEY
$QPID_CONFIG_EXEC -a localhost:${DST_TCP_PORT} bind $EXCHANGE_NAME $QUEUE_NAME $ROUTING_KEY
-#
+#echo "-----------------------"
+#echo "qpid-route route add"
+#echo "-----------------------"
# NOTE: The SRC broker *must* be referred to as $TEST_HOSTNAME, and not as "localhost".
# It must be referred to by the exact string given as the Common Name (CN) in the cert,
# which was created in the function create_certs, above.
+$QPID_ROUTE_EXEC route add localhost:${DST_TCP_PORT} $TEST_HOSTNAME:${SRC_SSL_PORT} -t ssl $EXCHANGE_NAME $ROUTING_KEY "" "" EXTERNAL
+#echo "-----------------------"
+#echo "view the route :"
+#echo "-----------------------"
+#$PYTHON_COMMANDS/qpid-route route list localhost:${DST_TCP_PORT}
+# I don't know how to avoid this sleep yet. It has to come after route-creation.
+sleep 5
-#----------------------------------------------------------------
-# Use qpid-route to create the link, or the link+route, depending
-# on which of its several methods was requested.
-#----------------------------------------------------------------
-if [ ${qpid_route_method} == "dynamic" ]; then
- print "dynamic add"
- $QPID_ROUTE_EXEC -t ssl dynamic add localhost:${DST_TCP_PORT} $TEST_HOSTNAME:${SRC_SSL_PORT} $EXCHANGE_NAME "" "" EXTERNAL
-elif [ ${qpid_route_method} == "link" ]; then
- print "link add"
- $QPID_ROUTE_EXEC -t ssl link add localhost:${DST_TCP_PORT} $TEST_HOSTNAME:${SRC_SSL_PORT} EXTERNAL
-elif [ ${qpid_route_method} == "queue" ]; then
- print "queue add"
- $QPID_ROUTE_EXEC -t ssl queue add localhost:${DST_TCP_PORT} $TEST_HOSTNAME:${SRC_SSL_PORT} $EXCHANGE_NAME $ROUTING_KEY EXTERNAL
-elif [ ${qpid_route_method} == "route" ]; then
- print "route add"
- $QPID_ROUTE_EXEC -t ssl route add localhost:${DST_TCP_PORT} $TEST_HOSTNAME:${SRC_SSL_PORT} $EXCHANGE_NAME $ROUTING_KEY "" "" EXTERNAL
-else
- echo "unknown method: |${qpid_route_method}|"
- echo " choices are: dynamic|link|queue|route "
- halt_brokers
- exit 1
-fi
+n_messages=100
+./datagen --count ${n_messages} | ./sender --broker localhost --port ${SRC_TCP_PORT} --exchange ${EXCHANGE_NAME} --routing-key ${ROUTING_KEY} --mechanism ANONYMOUS
-# I don't know how to avoid this sleep yet. It has to come after route-creation
-# to avoid false negatives.
-sleep 5
-# This should work the same whether or not we are running a clustered test.
-# In the case of clustered tests, the status is not printed by qpid_route.
-# So in either case, I will look only at the transport field, which should be "ssl".
-print "check the link"
-link_status=$($QPID_ROUTE_EXEC link list localhost:${DST_TCP_PORT} | tail -1 | awk '{print $3}')
+#echo "-----------------------"
+#echo "Examine DST Broker"
+#echo "-----------------------"
+dst_message_count=`qpid-stat -q localhost:${DST_TCP_PORT} | grep sasl_fed_queue | awk '{print $2}'`
-halt_brokers
-sleep 1
+#echo "-----------------------"
+#echo "Asking brokers to quit."
+#echo "-----------------------"
+$QPIDD_EXEC --port ${SRC_TCP_PORT} --quit
+$QPIDD_EXEC --port ${DST_TCP_PORT} --quit
-if [ ! ${link_status} ]; then
- print "link_status is empty"
- print "result: fail"
- exit 2
-fi
-if [ ${link_status} == "ssl" ]; then
- print "result: good"
- # Only remove the tmp_root on success, to permit debugging.
- print "Removing temporary directory $tmp_root"
- rm -rf $tmp_root
+#echo "-----------------------"
+#echo "Removing temporary directory $tmp_root"
+#echo "-----------------------"
+rm -rf $tmp_root
+
+if [ "$dst_message_count" -eq "$n_messages" ]; then
+ #echo "good: |$dst_message_count| == |$n_messages|"
exit 0
+else
+ #echo "not ideal: |$dst_message_count| != |$n_messages|"
+ exit 1
fi
-print "link_status has a bad value: ${link_status}"
-print "result: fail"
-exit 3
+
+
diff --git a/qpid/cpp/src/tests/sasl_fed_ex_dynamic b/qpid/cpp/src/tests/sasl_fed_ex_dynamic
deleted file mode 100755
index c20b8d69a0..0000000000
--- a/qpid/cpp/src/tests/sasl_fed_ex_dynamic
+++ /dev/null
@@ -1,27 +0,0 @@
-#! /bin/bash
-
-#
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License. You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied. See the License for the
-# specific language governing permissions and limitations
-# under the License.
-#
-
-
-source ./test_env.sh
-
-${srcdir}/sasl_fed_ex dynamic
-
-
diff --git a/qpid/cpp/src/tests/sasl_fed_ex_dynamic_cluster b/qpid/cpp/src/tests/sasl_fed_ex_dynamic_cluster
deleted file mode 100755
index b0cceccecb..0000000000
--- a/qpid/cpp/src/tests/sasl_fed_ex_dynamic_cluster
+++ /dev/null
@@ -1,28 +0,0 @@
-#! /bin/bash
-
-#
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License. You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied. See the License for the
-# specific language governing permissions and limitations
-# under the License.
-#
-
-
-source ./test_env.sh
-source $srcdir/ais_check
-
-with_ais_group ${srcdir}/sasl_fed_ex dynamic cluster
-
-
diff --git a/qpid/cpp/src/tests/sasl_fed_ex_link b/qpid/cpp/src/tests/sasl_fed_ex_link
deleted file mode 100755
index 7b232d4874..0000000000
--- a/qpid/cpp/src/tests/sasl_fed_ex_link
+++ /dev/null
@@ -1,27 +0,0 @@
-#! /bin/bash
-
-#
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License. You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied. See the License for the
-# specific language governing permissions and limitations
-# under the License.
-#
-
-
-source ./test_env.sh
-
-${srcdir}/sasl_fed_ex link
-
-
diff --git a/qpid/cpp/src/tests/sasl_fed_ex_link_cluster b/qpid/cpp/src/tests/sasl_fed_ex_link_cluster
deleted file mode 100755
index 4139300b12..0000000000
--- a/qpid/cpp/src/tests/sasl_fed_ex_link_cluster
+++ /dev/null
@@ -1,28 +0,0 @@
-#! /bin/bash
-
-#
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License. You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied. See the License for the
-# specific language governing permissions and limitations
-# under the License.
-#
-
-
-source ./test_env.sh
-source $srcdir/ais_check
-
-with_ais_group ${srcdir}/sasl_fed_ex link cluster
-
-
diff --git a/qpid/cpp/src/tests/sasl_fed_ex_queue b/qpid/cpp/src/tests/sasl_fed_ex_queue
deleted file mode 100755
index be0c10cf63..0000000000
--- a/qpid/cpp/src/tests/sasl_fed_ex_queue
+++ /dev/null
@@ -1,27 +0,0 @@
-#! /bin/bash
-
-#
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License. You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied. See the License for the
-# specific language governing permissions and limitations
-# under the License.
-#
-
-
-source ./test_env.sh
-
-${srcdir}/sasl_fed_ex queue
-
-
diff --git a/qpid/cpp/src/tests/sasl_fed_ex_queue_cluster b/qpid/cpp/src/tests/sasl_fed_ex_queue_cluster
deleted file mode 100755
index f251420e08..0000000000
--- a/qpid/cpp/src/tests/sasl_fed_ex_queue_cluster
+++ /dev/null
@@ -1,28 +0,0 @@
-#! /bin/bash
-
-#
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License. You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied. See the License for the
-# specific language governing permissions and limitations
-# under the License.
-#
-
-
-source ./test_env.sh
-source ${srcdir}/ais_check
-
-with_ais_group ${srcdir}/sasl_fed_ex queue cluster
-
-
diff --git a/qpid/cpp/src/tests/sasl_fed_ex_route b/qpid/cpp/src/tests/sasl_fed_ex_route
deleted file mode 100755
index dd5c4f3cac..0000000000
--- a/qpid/cpp/src/tests/sasl_fed_ex_route
+++ /dev/null
@@ -1,27 +0,0 @@
-#! /bin/bash
-
-#
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License. You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied. See the License for the
-# specific language governing permissions and limitations
-# under the License.
-#
-
-
-source ./test_env.sh
-
-${srcdir}/sasl_fed_ex route
-
-
diff --git a/qpid/cpp/src/tests/sasl_fed_ex_route_cluster b/qpid/cpp/src/tests/sasl_fed_ex_route_cluster
deleted file mode 100755
index a5d1542def..0000000000
--- a/qpid/cpp/src/tests/sasl_fed_ex_route_cluster
+++ /dev/null
@@ -1,28 +0,0 @@
-#! /bin/bash
-
-#
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License. You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied. See the License for the
-# specific language governing permissions and limitations
-# under the License.
-#
-
-
-source ./test_env.sh
-source ${srcdir}/ais_check
-
-with_ais_group ${srcdir}/sasl_fed_ex route cluster
-
-
diff --git a/qpid/cpp/src/tests/ssl_test b/qpid/cpp/src/tests/ssl_test
index cbf75eb237..04584f169d 100755
--- a/qpid/cpp/src/tests/ssl_test
+++ b/qpid/cpp/src/tests/ssl_test
@@ -1,4 +1,4 @@
-#!/bin/bash
+#!/bin/sh
#
# Licensed to the Apache Software Foundation (ASF) under one
diff --git a/qpid/cpp/src/tests/windows/DisableWin32ErrorWindows.cpp b/qpid/cpp/src/tests/windows/DisableWin32ErrorWindows.cpp
index 024f20b147..a0b665db73 100644
--- a/qpid/cpp/src/tests/windows/DisableWin32ErrorWindows.cpp
+++ b/qpid/cpp/src/tests/windows/DisableWin32ErrorWindows.cpp
@@ -26,9 +26,7 @@
// include this file with the executable being built. If the default
// behaviors are desired, don't include this file in the build.
-#if defined(_MSC_VER)
#include <crtdbg.h>
-#endif
#include <windows.h>
#include <iostream>
@@ -55,14 +53,12 @@ static redirect_errors_to_stderr block;
redirect_errors_to_stderr::redirect_errors_to_stderr()
{
-#if defined(_MSC_VER)
_CrtSetReportMode (_CRT_WARN, _CRTDBG_MODE_FILE);
_CrtSetReportFile (_CRT_WARN, _CRTDBG_FILE_STDERR);
_CrtSetReportMode (_CRT_ERROR, _CRTDBG_MODE_FILE);
_CrtSetReportFile (_CRT_ERROR, _CRTDBG_FILE_STDERR);
_CrtSetReportMode (_CRT_ASSERT, _CRTDBG_MODE_FILE);
_CrtSetReportFile (_CRT_ASSERT, _CRTDBG_FILE_STDERR);
-#endif
// Prevent the system from displaying the critical-error-handler
// and can't-open-file message boxes.
diff --git a/qpid/cpp/src/windows/QpiddBroker.cpp b/qpid/cpp/src/windows/QpiddBroker.cpp
index 50bb45979c..e221551575 100644
--- a/qpid/cpp/src/windows/QpiddBroker.cpp
+++ b/qpid/cpp/src/windows/QpiddBroker.cpp
@@ -155,7 +155,7 @@ NamedSharedMemory<T>::NamedSharedMemory(const std::string& n) :
name(n),
memory(NULL),
data(0)
-{}
+{};
template <typename T>
NamedSharedMemory<T>::~NamedSharedMemory() {
@@ -163,7 +163,7 @@ NamedSharedMemory<T>::~NamedSharedMemory() {
::UnmapViewOfFile(data);
if (memory != NULL)
::CloseHandle(memory);
-}
+};
template <typename T>
T& NamedSharedMemory<T>::create() {
diff --git a/qpid/cpp/src/xml.mk b/qpid/cpp/src/xml.mk
index baf3803647..0d700fcc03 100644
--- a/qpid/cpp/src/xml.mk
+++ b/qpid/cpp/src/xml.mk
@@ -16,7 +16,7 @@
# specific language governing permissions and limitations
# under the License.
#
-dmoduleexec_LTLIBRARIES += xml.la
+dmodule_LTLIBRARIES += xml.la
xml_la_SOURCES = \
qpid/xml/XmlExchange.cpp \
diff --git a/qpid/cpp/xml/cluster.xml b/qpid/cpp/xml/cluster.xml
index c33f2e4852..be1c1f868c 100644
--- a/qpid/cpp/xml/cluster.xml
+++ b/qpid/cpp/xml/cluster.xml
@@ -8,9 +8,9 @@
- to you under the Apache License, Version 2.0 (the
- "License"); you may not use this file except in compliance
- with the License. You may obtain a copy of the License at
--
+-
- http://www.apache.org/licenses/LICENSE-2.0
--
+-
- Unless required by applicable law or agreed to in writing,
- software distributed under the License is distributed on an
- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
@@ -78,6 +78,10 @@
<field name="left" type="vbin16"/> <!-- packed member-id array -->
</control>
+ <control name="message-expired" code="0x12">
+ <field name="id" type="uint64"/>
+ </control>
+
<domain name="error-type" type="uint8" label="Types of error">
<enum>
<choice name="none" value="0"/>
@@ -85,7 +89,7 @@
<choice name="connection" value="2"/>
</enum>
</domain>
-
+
<!-- Check for error consistency across the cluster -->
<control name="error-check" code="0x14">
<field name="type" type="error-type"/>
@@ -112,11 +116,6 @@
<field name="message" type="vbin32"/>
</control>
- <!-- Update the cluster time -->
- <control name="clock" code="0x22">
- <field name="time" type="uint64"/>
- </control>
-
</class>
<!-- Controls associated with a specific connection. -->
@@ -150,7 +149,7 @@
<!-- Abort a connection that is sending invalid data. -->
<control name="abort" code="0x4"/>
-
+
<!-- Update controls. Sent to a new broker in joining mode.
A connection is updated as followed:
- send the shadow's management ID in shadow-perpare on the update connection
@@ -184,7 +183,7 @@
<field name="position" type="sequence-no"/>
<field name="tag" type="str8"/>
<field name="id" type="sequence-no"/>
- <field name="acquired" type="bit"/> <!--If not set, message is on update queue. -->
+ <field name="acquired" type="bit"/> <!--If not set, message follows. -->
<field name="accepted" type="bit"/>
<field name="cancelled" type="bit"/>
<field name="completed" type="bit"/>
@@ -193,9 +192,9 @@
<field name="enqueued" type="bit"/>
<field name="credit" type="uint32"/>
</control>
-
+
<!-- Tx transaction state. -->
- <control name="tx-start" code="0x12"/>
+ <control name="tx-start" code="0x12"/>
<control name="tx-accept" code="0x13"> <field name="commands" type="sequence-set"/> </control>
<control name="tx-dequeue" code="0x14"> <field name="queue" type="str8"/> </control>
<control name="tx-enqueue" code="0x15"> <field name="queue" type="str8"/> </control>
@@ -205,7 +204,7 @@
</control>
<control name="tx-end" code="0x17"/>
<control name="accumulated-ack" code="0x18"> <field name="commands" type="sequence-set"/> </control>
-
+
<!-- Consumers in the connection's output task -->
<control name="output-task" code="0x19">
<field name="channel" type="uint16"/>
@@ -253,6 +252,10 @@
<!-- 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>
<!-- Add a listener to a queue -->
<control name="add-queue-listener" code="0x34">
@@ -279,26 +282,6 @@
<field name="position" type="uint8"/>
<field name="count" type="uint8"/>
</control>
-
- <!-- Replicate a QueueObserver for a given queue. -->
- <control name="queue-observer-state" code="0x39">
- <field name="queue" type="str8"/>
- <field name="observer-id" type="str8"/>
- <field name="state" type="map"/> <!-- "name"=value -->
- </control>
-
- <!-- Update the cluster time -->
- <control name="clock" code="0x40">
- <field name="time" type="uint64"/>
- </control>
-
- <!-- Update a queue's dequeue rate -->
- <control name="queue-dequeue-since-purge-state" code="0x41">
- <field name="queue" type="str8"/>
- <field name="dequeueSincePurge" type="uint32"/>
- </control>
-
-
</class>
</amqp>
diff --git a/qpid/doc/book/build-book.sh b/qpid/doc/book/build-book.sh
index 46192907e6..74a2ec963d 100755
--- a/qpid/doc/book/build-book.sh
+++ b/qpid/doc/book/build-book.sh
@@ -29,12 +29,6 @@
#
########################################################################
-# DOCBOOK XSL STYLESHEET LOCATION
-# Fedora, RHEL:
-DOCBOOK_XSL=/usr/share/sgml/docbook/xsl-stylesheets
-# Ubuntu:
-# DOCBOOK_XSL=/usr/share/sgml/docbook/stylesheet/xsl/nwalsh
-
rm -rf build/$1
mkdir -p build/$1
mkdir -p build/$1/html-single
@@ -44,16 +38,16 @@ cp -r src/images build/$1/html-single
cp -r src/images build/$1/html
# Create single-page .html
-xsltproc --xinclude --stringparam section.autolabel 1 --stringparam callout.graphics 0 --stringparam callout.unicode 0 --stringparam section.label.includes.component.label 1 ${DOCBOOK_XSL}/html/docbook.xsl src/$1.xml >build/$1/html-single/$1.html
+xsltproc --xinclude --stringparam section.autolabel 1 --stringparam callout.graphics 0 --stringparam callout.unicode 0 --stringparam section.label.includes.component.label 1 /usr/share/sgml/docbook/xsl-stylesheets/html/docbook.xsl src/$1.xml >build/$1/html-single/$1.html
# Create chunked .html
INFILE=$(readlink -f src/$1.xml)
pushd build/$1/html
-xsltproc --xinclude --stringparam chunk.section.depth 1 --stringparam section.autolabel 1 --stringparam callout.graphics 0 --stringparam callout.unicode 0 --stringparam section.label.includes.component.label 1 ${DOCBOOK_XSL}/html/chunk.xsl $INFILE
+xsltproc --xinclude --stringparam chunk.section.depth 1 --stringparam section.autolabel 1 --stringparam callout.graphics 0 --stringparam callout.unicode 0 --stringparam section.label.includes.component.label 1 /usr/share/sgml/docbook/xsl-stylesheets/html/chunk.xsl $INFILE
popd
# Create the .fo
-xsltproc --xinclude --stringparam section.autolabel 1 --stringparam callout.graphics 0 --stringparam callout.unicode 0 --stringparam section.label.includes.component.label 1 ${DOCBOOK_XSL}/fo/docbook.xsl src/$1.xml >build/$1/pdf/$1.fo
+xsltproc --xinclude --stringparam section.autolabel 1 --stringparam callout.graphics 0 --stringparam callout.unicode 0 --stringparam section.label.includes.component.label 1 /usr/share/sgml/docbook/xsl-stylesheets/fo/docbook.xsl src/$1.xml >build/$1/pdf/$1.fo
# Use Apache FOP to create the PDF
fop build/$1/pdf/$1.fo build/$1/pdf/$1.pdf
diff --git a/qpid/doc/book/src/AMQP-Messaging-Broker-CPP-Book.xml b/qpid/doc/book/src/AMQP-Messaging-Broker-CPP-Book.xml
index 6c27d7c668..309492262d 100644
--- a/qpid/doc/book/src/AMQP-Messaging-Broker-CPP-Book.xml
+++ b/qpid/doc/book/src/AMQP-Messaging-Broker-CPP-Book.xml
@@ -56,7 +56,6 @@
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="LVQ.xml"/>
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="queue-state-replication.xml"/>
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="Starting-a-cluster.xml"/>
- <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="producer-flow-control.xml"/>
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="AMQP-Compatibility.xml"/>
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="Qpid-Interoperability-Documentation.xml"/>
diff --git a/qpid/doc/book/src/AMQP-Messaging-Broker-CPP.xml b/qpid/doc/book/src/AMQP-Messaging-Broker-CPP.xml
index 15f5660455..b9c513e511 100644
--- a/qpid/doc/book/src/AMQP-Messaging-Broker-CPP.xml
+++ b/qpid/doc/book/src/AMQP-Messaging-Broker-CPP.xml
@@ -50,8 +50,7 @@
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="LVQ.xml"/>
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="queue-state-replication.xml"/>
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="Starting-a-cluster.xml"/>
- <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="ACL.xml"/>
- <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="producer-flow-control.xml"/>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="ACL.xml"/>
</chapter>
diff --git a/qpid/doc/book/src/Cheat-Sheet-for-configuring-Queue-Options.xml b/qpid/doc/book/src/Cheat-Sheet-for-configuring-Queue-Options.xml
index d50948e0cc..60f1a4103d 100644
--- a/qpid/doc/book/src/Cheat-Sheet-for-configuring-Queue-Options.xml
+++ b/qpid/doc/book/src/Cheat-Sheet-for-configuring-Queue-Options.xml
@@ -65,16 +65,6 @@
</itemizedlist>
</para></listitem>
</itemizedlist>
-
- <para>
- The 0.10 C++ Broker supports the following additional Queue configuration options:
- </para>
- <itemizedlist>
- <listitem><para>
- <xref linkend="producer-flow-control"/>
- </para></listitem>
- </itemizedlist>
-
<section role="h3" id="CheatSheetforconfiguringQueueOptions-ApplyingQueueSizingConstraints"><title>
Applying Queue Sizing Constraints
</title>
diff --git a/qpid/doc/book/src/Programming-In-Apache-Qpid.xml b/qpid/doc/book/src/Programming-In-Apache-Qpid.xml
index 6fae2f0bc7..3950b375da 100644
--- a/qpid/doc/book/src/Programming-In-Apache-Qpid.xml
+++ b/qpid/doc/book/src/Programming-In-Apache-Qpid.xml
@@ -1722,7 +1722,7 @@ try {
<row>
<entry>
- <literal>username</literal>
+ username
</entry>
<entry>
string
@@ -1733,7 +1733,7 @@ try {
</row>
<row>
<entry>
- <literal>password</literal>
+ password
</entry>
<entry>
string
@@ -1744,22 +1744,35 @@ try {
</row>
<row>
<entry>
- <literal>sasl_mechanisms</literal>
+ sasl-mechanism
</entry>
<entry>
string
</entry>
<entry>
- The specific SASL mechanisms to use with the python
+ The specific SASL mechanism to use with the c++
+ client when authenticating to the broker. Only a
+ single value can be specified at present. [C++ only].
+ </entry>
+ </row>
+ <row>
+ <entry>
+ sasl_mechanisms
+ </entry>
+ <entry>
+ string
+ </entry>
+ <entry>
+ The specific SASL mechanism to use with the python
client when authenticating to the broker. The value
- is a space separated list.
+ is a space separated list in order of preference. [Python only].
</entry>
</row>
<row>
<entry>
- <literal>reconnect</literal>
+ reconnect
</entry>
<entry>
boolean
@@ -1770,7 +1783,7 @@ try {
</row>
<row>
<entry>
- <literal>reconnect_timeout</literal>
+ <literal>reconnect_timeout&nbsp;[Python]</literal> <literal>reconnect-timeout&nbsp;[C++]</literal>
</entry>
<entry>
integer
@@ -1781,7 +1794,7 @@ try {
</row>
<row>
<entry>
- <literal>reconnect_limit</literal>
+ <literal>reconnect_limit&nbsp;[Python]</literal> <literal>reconnect-limit&nbsp;[C++]</literal>
</entry>
<entry>
integer
@@ -1792,7 +1805,7 @@ try {
</row>
<row>
<entry>
- <literal>reconnect_interval_min</literal>
+ <literal>reconnect_interval_min&nbsp;[Python]</literal> <literal>reconnect-interval-min&nbsp;[C++]</literal>
</entry>
<entry>
integer representing time in seconds
@@ -1803,7 +1816,7 @@ try {
</row>
<row>
<entry>
- <literal>reconnect_interval_max</literal>
+ <literal>reconnect_interval_max&nbsp;[Python]</literal> <literal>reconnect-interval-max&nbsp;[C++]</literal>
</entry>
<entry>
integer representing time in seconds
@@ -1814,7 +1827,7 @@ try {
</row>
<row>
<entry>
- <literal>reconnect_interval</literal>
+ <literal>reconnect_interval&nbsp;[Python]</literal> <literal>reconnect-interval&nbsp;[C++]</literal>
</entry>
<entry>
integer representing time in seconds
@@ -1826,7 +1839,7 @@ try {
<row>
<entry>
- <literal>heartbeat</literal>
+ heartbeat
</entry>
<entry>
integer representing time in seconds
@@ -1839,7 +1852,7 @@ try {
</row>
<row>
<entry>
- <literal>protocol</literal>
+ protocol
</entry>
<entry>
string
@@ -1850,7 +1863,7 @@ try {
</row>
<row>
<entry>
- <literal>tcp-nodelay</literal>
+ tcp-nodelay
</entry>
<entry>
boolean
diff --git a/qpid/doc/book/src/Security.xml b/qpid/doc/book/src/Security.xml
index 49abfbebca..77d10abf8c 100644
--- a/qpid/doc/book/src/Security.xml
+++ b/qpid/doc/book/src/Security.xml
@@ -1,25 +1,5 @@
<?xml version='1.0' encoding='utf-8' ?>
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
-<!--
-
- Licensed to the Apache Software Foundation (ASF) under one
- or more contributor license agreements. See the NOTICE file
- distributed with this work for additional information
- regarding copyright ownership. The ASF licenses this file
- to you under the Apache License, Version 2.0 (the
- "License"); you may not use this file except in compliance
- with the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing,
- software distributed under the License is distributed on an
- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- KIND, either express or implied. See the License for the
- specific language governing permissions and limitations
- under the License.
-
--->
<section id="chap-Messaging_User_Guide-Security">
<title>Security</title>
<para>
diff --git a/qpid/doc/book/src/producer-flow-control.xml b/qpid/doc/book/src/producer-flow-control.xml
deleted file mode 100644
index fd44f51e81..0000000000
--- a/qpid/doc/book/src/producer-flow-control.xml
+++ /dev/null
@@ -1,351 +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.
-
--->
-
-<section id="producer-flow-control">
- <title>
- Producer Flow Control
- </title>
-
- <section role="h2" id="producerflowcontrol-Overview">
- <title>
- Overview
- </title>
- <para>
- As of release 0.10, the C++ broker supports the use of flow control to
- throttle back message producers that are at risk of overflowing a
- destination queue.
- </para>
-
- <para>
- Each queue in the C++ broker has two threshold values associated with it:
- </para>
-
- <para>
- Flow Stop Threshold: this is the level of queue resource
- utilization above which flow control will be enabled. Once this
- threshold is crossed, the queue is considered in danger of overflow.
- </para>
-
- <para>
- Flow Resume Threshold - this is the level of queue resource utilization
- below which flow control will be disabled. Once this threshold is
- crossed, the queue is no longer considered in danger of overflow.
- </para>
-
- <para>
- In the above description, queue resource utilization may be
- defined as the total count of messages currently enqueued, or the total
- sum of all message content in bytes.
- </para>
-
- <para>
- The value for a queue's Flow Stop Threshold must be greater than or
- equal to the value of the queue's Flow Resume Threshold.
- </para>
-
- <section role="h3" id="producerflowcontrol-QueueThresholdsExample">
- <title>
- Example
- </title>
-
- <para>
- Let's consider a queue with a maximum limit set on the total number of
- messages that may be enqueued to that queue. Assume this maximum
- message limit is 1000 messages. Assume also that the user configures a
- Flow Stop Threshold of 900 messages, and a Flow Resume Threshold of 500
- messages. Then the following holds:
- </para>
-
- <para>
- The queue's initial flow control state is "OFF".
- </para>
-
- <para>
- While the total number of enqueued messages is less than or equal to
- 900, the queue's flow control state remains "OFF".
- </para>
-
- <para>
- When the total number of enqueued messages is greater than 900, the
- queue's flow control state transitions to "ON".
- </para>
-
- <para>
- When the queue's flow control state is "ON", it remains "ON" until the
- total number of enqueued messages is less than 500. At that point, the queue's
- flow control state transitions to "OFF".
- </para>
-
- <para>
- A similar example using total enqueued content bytes as the threshold
- units are permitted.
- </para>
- </section>
-
- <para>
- Thresholds may be set using both total message counts and total byte
- counts. In this case, the following rules apply:
- </para>
-
- <para>
- 1) Flow control is "ON" when either stop threshold value is crossed.
- </para>
- <para>
- 2) Flow control remains "ON" until both resume thresholds are satisfied.
- </para>
-
- <section role="h3" id="producerflowcontro-MultiThresholdExample">
- <title>
- Example
- </title>
-
- <para>
- Let's consider a queue with a maximum size limit of 10K bytes, and 5000
- messages. A user may assign a Flow Stop Threshold based on a total
- message count of 4000 messages. They may also assigne a Flow Stop
- Threshold of 8K bytes. The queue's flow control state transitions to
- "ON" if either threshold is crossed: (total-msgs greater-than 4000 OR total-bytes
- greater-than 8K).
- </para>
-
- <para>
- Assume the user has assigned Flow Resume threshold's of 3000 messages and
- 6K bytes. Then the queue's flow control will remain active until both
- thresholds are satified: (total-msg less-than 3000 AND total-bytes less-than 6K).
- </para>
- </section>
-
- <para>
- The Broker enforces flow control by delaying the completion of the
- Message.Transfer command that causes a message to be delivered to a queue
- with active flow control. The completion of the Message.Transfer command
- is held off until flow control state transitions to "OFF" for all queues
- that are a destination for that command.
- </para>
-
- <para>
- A message producing client is permitted to have a finite number of
- commands pending completion. When the total number of these outstanding
- commands reaches the limit, the client must not issue further commands
- until one or more of the outstanding commands have completed. This
- window of outstanding commands is considered the sender's "capacity".
- This allows any given producer to have a "capacity's" worth of messages
- blocked due to flow control before the sender must stop sending further
- messages.
- </para>
-
- <para>
- This capacity window must be considered when determining a suitable
- flow stop threshold for a given queue, as a producer may send its
- capacity worth of messages _after_ a queue has reached the flow stop
- threshold. Therefore, a flow stop threshould should be set such that
- the queue can accomodate more messages without overflowing.
- </para>
-
- <para>
- For example, assume two clients, C1 and C2, are producing messages to
- one particular destination queue. Assume client C1 has a configured
- capacity of 50 messages, and client C2's capacity is 15 messages. In
- this example, assume C1 and C2 are the only clients queuing messages to
- a given queue. If this queue has a Flow Stop Threshold of 100
- messages, then, worst-case, the queue may receive up to 165 messages
- before clients C1 and C2 are blocked from sending further messages.
- This is due to the fact that the queue will enable flow control on
- receipt of its 101'st message - preventing the completion of the
- Message.Transfer command that carried the 101'st message. However, C1
- and C2 are allowed to have a total of 65 (50 for C1 and 15 for C2)
- messages pending completion of Message.Transfer before they will stop
- producing messages. Thus, up to 65 messages may be enqueued beyond the
- flow stop threshold before the producers will be blocked.
- </para>
- </section>
-
- <section role="h2" id="producerflowcontrol-UserInterface">
- <title>
- User Interface
- </title>
-
- <para>
- By default, the C++ broker assigns a queue's flow stop and flow resume
- thresholds when the queue is created. The C++ broker also allows the
- user to manually specify the flow control thresholds on a per queue
- basis.
- </para>
-
- <para>
- However, queues that have been configured with a Limit Policy of type
- RING or RING-STRICT do NOT have queue flow thresholds enabled by
- default. The nature of a RING queue defines its behavior when its
- capacity is reach: replace the oldest message.
- </para>
-
- <para>
- The flow control state of a queue can be determined by the "flowState"
- boolean in the queue's QMF management object. The queue's management
- object also contains a counter that increments each time flow control
- becomes active for the queue.
- </para>
-
- <para>
- The broker applies a threshold ratio to compute a queue's default flow
- control configuration. These thresholds are expressed as a percentage
- of a queue's maximum capacity. There is one value for determining the
- stop threshold, and another for determining the resume threshold. The
- user may configure these percentages using the following broker
- configuration options:
- </para>
-
- <programlisting>
- --default-flow-stop-threshold ("Queue capacity level at which flow control is activated.")
- --default-flow-resume-threshold ("Queue capacity level at which flow control is de-activated.")
- </programlisting>
-
- <para>
- For example:
- </para>
-
- <programlisting>
- qpidd --default-flow-stop-threshold=90 --default-flow-resume-threshold=75
- </programlisting>
-
- <para>
- Sets the default flow stop threshold to 90% of a queue's maximum
- capacity and the flow resume threshold to 75% of the maximum capacity.
- If a queue is created with a default-queue-limit of 10000 bytes, then
- the default flow stop threshold would be 90% of 10000 = 9000 bytes and
- the flow resume threshold would be 75% of 10000 = 7500. The same
- computation is performed should a queue be created with a maximum size
- expressed as a message count instead of a byte count.
- </para>
-
- <para>
- If not overridden by the user, the value of the
- default-flow-stop-threshold is 80% and the value of the
- default-flow-resume-threshold is 70%.
- </para>
-
- <para>
- The user may disable default queue flow control broker-wide by
- specifying the value 0 for both of these configuration options. Note
- that flow control may still be applied manually on a per-queue basis in
- this case.
- </para>
-
- <para>
- The user may manually set the flow thresholds when creating a queue.
- The following options may be provided when adding a queue using the
- <command>qpid-config</command> command line tool:
- </para>
-
- <programlisting>
- --flow-stop-size=<replaceable>N</replaceable> Sets the queue's flow stop threshold to <replaceable>N</replaceable> total bytes.
- --flow-resume-size=<replaceable>N</replaceable> Sets the queue's flow resume threshold to <replaceable>N</replaceable> total bytes.
- --flow-stop-count=<replaceable>N</replaceable> Sets the queue's flow stop threshold to <replaceable>N</replaceable> total messages.
- --flow-resume-count=<replaceable>N</replaceable> Sets the queue's flow resume threshold to <replaceable>N</replaceable> total messages.
- </programlisting>
-
- <para>
- Flow thresholds may also be specified in the
- <command>queue.declare</command> method, via the
- <command>arguments</command> parameter map. The following keys can be
- provided in the arguments map for setting flow thresholds:
- </para>
-
- <table>
- <title>Queue Declare Method Flow Control Arguments</title>
- <tgroup cols="2">
- <thead>
- <row>
- <entry>Key</entry>
- <entry>Value</entry>
- </row>
- </thead>
- <tbody>
- <row>
- <entry>qpid.flow_stop_size</entry>
- <entry>integer - queue's flow stop threshold value in bytes</entry>
- </row>
- <row>
- <entry>qpid.flow_resume_size</entry>
- <entry>integer - queue's flow resume threshold value in bytes</entry>
- </row>
- <row>
- <entry>qpid.flow_stop_count</entry>
- <entry>integer - queue's flow stop threshold value as a message count</entry>
- </row>
- <row>
- <entry>qpid.flow_resume_count</entry>
- <entry>integer - queue's flow resume threshold value as a message count</entry>
- </row>
- </tbody>
- </tgroup>
- </table>
-
- <para>
- The user may disable flow control on a per queue basis by setting
- the flow-stop-size and flow-stop-count to zero for the queue.
- </para>
-
- <para>
- The current state of flow control for a given queue can be
- determined by the "flowStopped" statistic. This statistic is
- available in the queue's QMF management object. The value of
- flowStopped is True when the queue's capacity has exceeded the
- flow stop threshold. The value of flowStopped is False when the
- queue is no longer blocking due to flow control.
- </para>
-
- <para>
- A queue will also track the number of times flow control has been
- activated. The "flowStoppedCount" statistic is incremented each time
- the queue's capacity exceeds a flow stop threshold. This statistic can
- be used to monitor the activity of flow control for any given queue
- over time.
- </para>
-
- <table>
- <title>Flow Control Statistics available in Queue's QMF Class</title>
- <tgroup cols="3">
- <thead>
- <row>
- <entry>Statistic Name</entry>
- <entry>Type</entry>
- <entry>Description</entry>
- </row>
- </thead>
- <tbody>
- <row>
- <entry>flowStopped</entry>
- <entry>Boolean</entry>
- <entry>If true, producers are blocked by flow control.</entry>
- </row>
- <row>
- <entry>flowStoppedCount</entry>
- <entry>count32</entry>
- <entry>Number of times flow control was activated for this queue</entry>
- </row>
- </tbody>
- </tgroup>
- </table>
- </section>
- <!--h2-->
- </section>
diff --git a/qpid/doc/dev-readme/QPID-Component-README.odg b/qpid/doc/dev-readme/QPID-Component-README.odg
index 217a6d68d8..40f2972d88 100644
--- a/qpid/doc/dev-readme/QPID-Component-README.odg
+++ b/qpid/doc/dev-readme/QPID-Component-README.odg
Binary files differ
diff --git a/qpid/doc/dev-readme/QPID-Component-README.pdf b/qpid/doc/dev-readme/QPID-Component-README.pdf
index 3012372889..8863883df9 100644
--- a/qpid/doc/dev-readme/QPID-Component-README.pdf
+++ b/qpid/doc/dev-readme/QPID-Component-README.pdf
Binary files differ
diff --git a/qpid/doc/website/README.txt b/qpid/doc/website/README.txt
index dcb3b423e5..6a0c2876ab 100644
--- a/qpid/doc/website/README.txt
+++ b/qpid/doc/website/README.txt
@@ -1,10 +1,26 @@
-To edit the website, check out the /site repo area:
+This is the source directory for creating web pages for the Qpid web
+site.
- svn co https://svn.apache.org/repos/asf/qpid/site
+The template used for all pages (template.html), stylesheet
+(style.css), and images are in the ./template directory.
-The HTML files for the site reside in the docs directory, where a README
-can be found to describe the process of adding new content.
+The tools directory contains a very simple Python script (wrap) that
+combines a template and content to create static html pages. Content
+should be written in XHTML, with one <div/> element at the root - see
+./content/home.html for an example.
-It is no longer necessary to generate the main website pages, the live files
-are now edited directly, and are deployed to the web server after check in.
+Use wrap like this:
+$ tools/wrap template/template.html content/<filename> build/<filename>
+
+Content for the main pages should be check into the content
+directory. Content for documentation is created in the ../book
+directory.
+
+To publish generated content, check out the website repo:
+
+$ svn co https://svn.apache.org/repos/asf/qpid/site/docs
+
+Copy generated content (NOT the source!) into the website repo, add it
+using $ svn add, and commit it. When it is committed, it appears on
+the website.
diff --git a/qpid/doc/website/build.sh b/qpid/doc/website/build.sh
new file mode 100755
index 0000000000..25162b4de0
--- /dev/null
+++ b/qpid/doc/website/build.sh
@@ -0,0 +1,53 @@
+#!/bin/bash
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+TEMPLATE_DIR=template
+TEMPLATE=template.html
+CONTENT_DIR=content
+BUILD_DIR=build
+WRAP="tools/wrap"
+
+# Gather the *.html filenames to wrap
+pushd $CONTENT_DIR >/dev/null
+HTML_FILES=`ls *.html`
+popd >/dev/null
+
+# Clear the existing artefacts, or create the build dir
+if [ -d $BUILD_DIR ];
+then
+ rm -rf $BUILD_DIR/*;
+else
+ mkdir $BUILD_DIR
+fi
+
+# Wrap the html files
+for FILE in $HTML_FILES;
+do
+ ./$WRAP "$TEMPLATE_DIR/$TEMPLATE" "$CONTENT_DIR/$FILE" "$BUILD_DIR/$FILE"
+done
+
+# Copy the .htaccess, style.css, images, and any specifically required non-html content
+cp $CONTENT_DIR/.htaccess $BUILD_DIR/
+cp $TEMPLATE_DIR/style.css $BUILD_DIR/
+cp -R $TEMPLATE_DIR/images $BUILD_DIR/
+cp -R $CONTENT_DIR/images $BUILD_DIR/
+cp $CONTENT_DIR/download.cgi $BUILD_DIR/
+
+
diff --git a/qpid/doc/website/content/.htaccess b/qpid/doc/website/content/.htaccess
new file mode 100644
index 0000000000..a6ab32531b
--- /dev/null
+++ b/qpid/doc/website/content/.htaccess
@@ -0,0 +1,20 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+Redirect /download.html http://qpid.apache.org/download.cgi
+Redirect /licence.html http://www.apache.org/licenses/
diff --git a/qpid/doc/website/content/acknowledgements.html b/qpid/doc/website/content/acknowledgements.html
new file mode 100644
index 0000000000..daeb21c172
--- /dev/null
+++ b/qpid/doc/website/content/acknowledgements.html
@@ -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.
+ -
+-->
+<div class="main_text_area_body">
+ <h1>Acknowledgements</h1>
+ <div>
+ <table>
+ <tbody>
+ <tr>
+ <td><a href="http://www.ej-technologies.com/products/jprofiler/overview.html">
+ <img src="images/jprofiler.png" /></a>
+ </td>
+ <td><p>We acknowledge <a href="http://www.ej-technologies.com">ej-technologies</a> for giving us a free team license for profiling Qpid Java code.</p></td>
+
+ </tr>
+ <tr>
+ <td><a href="http://www.headwaysoftware.com/products/structure101"><img src="images/structure101.jpg"/></a> </td>
+ <td><p>We acknowledge <a href="http://www.headwaysoftware.com">Headway Software</a> for giving us free licenses of Structure101 for analyzing and managing the architecture of Qpid Java code.</p></td>
+ </tr>
+ </tbody></table>
+ </div>
+</div>
diff --git a/qpid/doc/website/content/amqp.html b/qpid/doc/website/content/amqp.html
new file mode 100644
index 0000000000..a251164d07
--- /dev/null
+++ b/qpid/doc/website/content/amqp.html
@@ -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.
+ -
+-->
+<div class="main_text_area_body">
+ <h1>What is AMQP?</h1>
+
+ <p>AMQP <a href="http://www.amqp.org">Advanced Message Queuing Protocol</a> is an open standard designed to support reliable, high-performance messaging over the Internet. AMQP can be used for any distributed or business application, and supports common messaging paradigms like point-to-point, fanout, publish-subscribe, and request-response.</p>
+
+ <p>Apache Qpid implements AMQP, including transaction management, queuing, clustering, federation, security, management and multi-platform support.</p>
+
+
+ <p>Apache Qpid implements the latest AMQP specification, providing transaction management, queuing, distribution, security, management, clustering, federation and heterogeneous multi-platform support and a lot more. </p>
+
+ <p>Apache Qpid is highly optimized, and <a href="compatibility.html" title="AMQP compatibility">aims to be 100% AMQP Compliant</a>.</p>
+
+ <h2><a name="AMQP%28AdvancedMessageQueueingProtocol%29-DownloadtheAMQPSpecifications"></a>Download the AMQP Specifications</h2>
+
+ <h3><a name="AMQP%28AdvancedMessageQueueingProtocol%29-AMQPversion010"></a>AMQP version 0-10</h3>
+
+
+ <ul>
+ <li><a href="https://jira.amqp.org/confluence/download/attachments/720900/amqp.0-10.pdf?version=1">AMQP 0-10 Specification (PDF) </a></li>
+ <li><a href="https://jira.amqp.org/confluence/download/attachments/720900/amqp.0-10.xml?version=1">AMQP 0-10 Protocol Definition XML </a></li>
+ <li><a href="https://jira.amqp.org/confluence/download/attachments/720900/amqp.0-10.dfd?version=1">AMQP 0-10 Protocol Definition DTD </a></li>
+
+ </ul>
+
+
+ <h3><a name="AMQP%28AdvancedMessageQueueingProtocol%29-AMQPversion091"></a>AMQP version 0-9-1</h3>
+
+ <ul>
+ <li><a href="https://jira.amqp.org/confluence/download/attachments/720900/amqp0-9-1.pdf?version=1">AMQP 0-9-1 Specification (PDF) </a></li>
+ <li><a href="https://jira.amqp.org/confluence/download/attachments/720900/amqp0-9-1.xml?version=1">AMQP 0-9-1 Protocol Documentation (PDF) </a></li>
+ <li><a href="https://jira.amqp.org/confluence/download/attachments/720900/amqp0-9-1.dtd?version=1">AMQP 0-9-1 Protocol Definitions (XML) </a></li>
+ </ul>
+
+
+ <h3><a name="AMQP%28AdvancedMessageQueueingProtocol%29-AMQPversion09"></a>AMQP version 0-9</h3>
+
+ <ul>
+ <li><a href="https://jira.amqp.org/confluence/download/attachments/720900/amqp0-9.pdf?version=1">AMQP 0-9 Specification (PDF) </a></li>
+ <li><a href="https://jira.amqp.org/confluence/download/attachments/720900/amqp0-9.xml?version=1">AMQP 0-9 Protocol Documentation (PDF) </a></li>
+ <li><a href="https://jira.amqp.org/confluence/download/attachments/720900/amqp0-9.dtd?version=1">AMQP 0-9 Protocol Definitions (XML) </a></li>
+ </ul>
+
+ <h3><a name="AMQP%28AdvancedMessageQueueingProtocol%29-AMQPversion08"></a>AMQP version 0-8</h3>
+
+ <ul>
+ <li><a href="https://jira.amqp.org/confluence/download/attachments/720900/amqp0-8.pdf?version=1">AMQP 0-8 Specification (PDF) </a></li>
+ <li><a href="https://jira.amqp.org/confluence/download/attachments/720900/amqp0-8.dtd?version=1">AMQP 0-8 Protocol Documentation (PDF) </a></li>
+ <li><a href="https://jira.amqp.org/confluence/download/attachments/720900/amqp0-8.xml?version=1">AMQP 0-8 Protocol Definitions (XML) </a></li>
+ </ul>
+</div>
+
diff --git a/qpid/doc/website/content/compatibility.html b/qpid/doc/website/content/compatibility.html
new file mode 100644
index 0000000000..af99670da9
--- /dev/null
+++ b/qpid/doc/website/content/compatibility.html
@@ -0,0 +1,386 @@
+<!--
+ -
+ - Licensed to the Apache Software Foundation (ASF) under one
+ - or more contributor license agreements. See the NOTICE file
+ - distributed with this work for additional information
+ - regarding copyright ownership. The ASF licenses this file
+ - to you under the Apache License, Version 2.0 (the
+ - "License"); you may not use this file except in compliance
+ - with the License. You may obtain a copy of the License at
+ -
+ - http://www.apache.org/licenses/LICENSE-2.0
+ -
+ - Unless required by applicable law or agreed to in writing,
+ - software distributed under the License is distributed on an
+ - "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ - KIND, either express or implied. See the License for the
+ - specific language governing permissions and limitations
+ - under the License.
+ -
+-->
+<div class="main_text_area_body">
+ <p><b>Qpid provides the most complete and compatible implementation of AMQP. And is the most aggressive in implementing the latest version of the specification. Qpid can be</b> <b><a href="./download.cgi" title="Download"><b>downloaded here</b></a></b></p>
+
+ <p>There are two brokers:</p>
+
+ <p>C+&#43; with support for AMQP 0-10<br/>
+ Java with support for AMQP 0-8, 0-9, and 0-10.</p>
+
+ <p>There are client libraries for C++, Java (JMS), .Net (written in C#), python and ruby.</p>
+
+ <ul>
+ <li>All clients support 0-10 and interoperate with both brokers as of 0.6.</li>
+ </ul>
+
+
+ <ul>
+ <li>The JMS client supports 0-8, 0-9 and 0-10 and interoperates with both brokers.</li>
+ </ul>
+
+
+ <ul>
+ <li>The python and ruby clients will also support all versions, but the API is dynamically driven by the specification used and so differs between versions. To work with the C+&#43; broker you must use 0-10. To work with the Java broker you can use any version as of 0.6, or prior to 0.6 you can use 0-8 or 0-9.</li>
+
+ </ul>
+
+
+ <ul>
+ <li>There are two separate C# clients, one for 0-8 that interoperates only with the Java broker, and one for 0-10.</li>
+ </ul>
+
+
+ <ul>
+ <li>There is also a WCF channel, which wraps the 0-10 native C++ client library.</li>
+ </ul>
+
+
+ <p>QMF Management is supported in Ruby, Python, C++, and can be translated to Java JMX &amp; WS-DM via the QMan management tool.</p>
+
+ <h3><a name="AMQPcompatibility-AMQPCompatibilityofQpidreleases%3A"></a>AMQP Compatibility of Qpid releases:</h3>
+
+ <p>Qpid implements the AMQP Specification, and as the specification has progressed Qpid is keeping up with the updates. This means that different Qpid versions support different versions of AMQP. Here is a simple guide on what use.</p>
+
+ <p>Here is a matrix that describes the different versions supported by each release<br/>
+ Y = supported<br/>
+ N = unsupported<br/>
+
+ IP = in progress<br/>
+ P = planned</p>
+ <div >
+ <table ><tbody>
+ <tr>
+ <th > Component </th>
+ <th > Spec </th>
+ <th >&nbsp;</th>
+ <th >&nbsp;</th>
+ <th >&nbsp;</th>
+ <th >&nbsp;</th>
+ <th >&nbsp;</th>
+ <th >&nbsp;</th>
+ </tr>
+ <tr>
+ <td >&nbsp;</td>
+ <td >&nbsp;</td>
+ <th > M2.1 </th>
+ <th > M3 </th>
+ <th > M4 </th>
+ <th > 0.5 </th>
+ <th > 0.6 </th>
+ <th > 0.8 </th>
+ </tr>
+ <tr>
+ <th > Java client </th>
+ <td > 0-10 </td>
+ <td >&nbsp;</td>
+ <td > Y </td>
+ <td > Y </td>
+ <td > Y </td>
+ <td > Y </td>
+ <td > Y </td>
+ </tr>
+ <tr>
+ <td >&nbsp;</td>
+ <td > 0-9 </td>
+ <td > Y </td>
+ <td > Y </td>
+ <td > Y </td>
+ <td > Y </td>
+ <td > Y </td>
+ <td > Y </td>
+ </tr>
+ <tr>
+ <td >&nbsp;</td>
+ <td > 0-8 </td>
+ <td > Y </td>
+ <td > Y </td>
+ <td > Y </td>
+ <td > Y </td>
+ <td > Y </td>
+ <td > Y </td>
+ </tr>
+ <tr>
+ <th > Java broker </th>
+ <td > 0-10 </td>
+ <td >&nbsp;</td>
+ <td >&nbsp;</td>
+ <td >&nbsp;</td>
+ <td >&nbsp;</td>
+ <td > Y </td>
+ <td > Y </td>
+ </tr>
+ <tr>
+ <td >&nbsp;</td>
+ <td > 0-9 </td>
+ <td > Y </td>
+ <td > Y </td>
+ <td > Y </td>
+ <td > Y </td>
+ <td > Y </td>
+ <td > Y </td>
+ </tr>
+ <tr>
+ <td >&nbsp;</td>
+ <td > 0-8 </td>
+ <td > Y </td>
+ <td > Y </td>
+ <td > Y </td>
+ <td > Y </td>
+ <td > Y </td>
+ <td > Y </td>
+ </tr>
+ <tr>
+
+ <th > C+&#43; client/broker </th>
+ <td > 0-10 </td>
+ <td >&nbsp;</td>
+ <td > Y </td>
+ <td > Y </td>
+ <td > Y </td>
+ <td > Y </td>
+ <td > Y </td>
+ </tr>
+ <tr>
+ <td >&nbsp;</td>
+ <td > 0-9 </td>
+ <td > Y </td>
+ <td >&nbsp;</td>
+ <td >&nbsp;</td>
+ <td >&nbsp;</td>
+ <td >&nbsp;</td>
+ <td >&nbsp;</td>
+ </tr>
+
+ <tr>
+ <th > Python client </th>
+ <td > 0-10 </td>
+ <td >&nbsp;</td>
+ <td > Y </td>
+ <td > Y </td>
+ <td > Y </td>
+ <td > Y </td>
+ <td > Y </td>
+ </tr>
+ <tr>
+ <td >&nbsp;</td>
+ <td > 0-9 </td>
+ <td > Y </td>
+ <td > Y </td>
+ <td > Y </td>
+ <td > Y </td>
+ <td > Y </td>
+ <td > Y </td>
+ </tr>
+ <tr>
+ <td >&nbsp;</td>
+ <td > 0-8 </td>
+ <td > Y </td>
+ <td > Y </td>
+ <td > Y </td>
+ <td > Y </td>
+ <td > Y </td>
+ <td > Y </td>
+ </tr>
+ <tr>
+ <th > Ruby client </th>
+ <td > 0-10 </td>
+ <td >&nbsp;</td>
+ <td >&nbsp;</td>
+ <td > Y </td>
+ <td > Y </td>
+ <td > Y </td>
+ <td > Y </td>
+ </tr>
+ <tr>
+ <td >&nbsp;</td>
+ <td > 0-8 </td>
+ <td > Y </td>
+ <td > Y </td>
+ <td > Y </td>
+ <td > Y </td>
+ <td > Y </td>
+ <td > Y </td>
+ </tr>
+ <tr>
+
+ <th > C# client </th>
+ <td > 0-10 </td>
+ <td >&nbsp;</td>
+ <td >&nbsp;</td>
+ <td > Y </td>
+ <td > Y </td>
+ <td > Y </td>
+ <td > Y </td>
+ </tr>
+ <tr>
+ <td >&nbsp;</td>
+ <td > 0-8 </td>
+ <td > Y </td>
+ <td > Y </td>
+ <td > Y </td>
+ <td > Y </td>
+ <td > Y </td>
+ <td > Y </td>
+ </tr>
+ <tr>
+ <th > WCF channel </th>
+ <td > 0-10 </td>
+ <td >&nbsp;</td>
+ <td >&nbsp;</td>
+ <td >&nbsp;</td>
+ <td >&nbsp;</td>
+ <td > Y </td>
+ <td > Y </td>
+ </tr>
+ </tbody></table>
+ </div>
+
+
+ <h3><a name="AMQPcompatibility-InteroptablebyAMQPspecificationversion"></a>Interop table by AMQP specification version</h3>
+
+ <p>Above table represented in another format.</p>
+ <div >
+ <table ><tbody>
+ <tr>
+ <th >Component</th>
+ <th >Release </th>
+
+ <th > 0-8 </th>
+ <th > 0-9 </th>
+ <th > 0-10 </th>
+ </tr>
+ <tr>
+ <td > Java client </td>
+ <td > M3, M4, 0.5, 0.6, 0.8</td>
+
+ <td > Y </td>
+ <td > Y </td>
+ <td > Y </td>
+ </tr>
+ <tr>
+ <td > Java client </td>
+ <td > M2.1 </td>
+
+ <td > Y </td>
+ <td > Y </td>
+ <td > N </td>
+ </tr>
+ <tr>
+ <td > Java broker </td>
+ <td > 0.6, 0.8</td>
+
+ <td > Y </td>
+ <td > Y </td>
+ <td > Y </td>
+ </tr>
+ <tr>
+ <td > Java broker </td>
+ <td > M3, M4, 0.5 </td>
+
+ <td > Y </td>
+ <td > Y </td>
+ <td > N </td>
+ </tr>
+ <tr>
+ <td > Java broker </td>
+ <td > M2.1 </td>
+
+ <td > Y </td>
+ <td > Y </td>
+ <td > N </td>
+ </tr>
+ <tr>
+ <td > C+&#43; client/broker </td>
+ <td > M3, M4, 0.5, 0.6, 0.8</td>
+
+ <td > N </td>
+ <td > N </td>
+ <td > Y </td>
+ </tr>
+ <tr>
+ <td > C+&#43; client/broker </td>
+ <td > M2.1 </td>
+
+ <td > N </td>
+ <td > Y </td>
+ <td > N </td>
+ </tr>
+ <tr>
+ <td > Python client </td>
+ <td > M3, M4, 0.5, 0.6, 0.8</td>
+
+ <td > Y </td>
+ <td > Y </td>
+ <td > Y </td>
+ </tr>
+ <tr>
+ <td > Python client </td>
+ <td > M2.1 </td>
+
+ <td > Y </td>
+ <td > Y </td>
+ <td > N </td>
+ </tr>
+ <tr>
+ <td > Ruby client </td>
+ <td > M4, 0.5, 0.6, 0.8</td>
+
+ <td > Y </td>
+ <td > Y </td>
+ <td > Y </td>
+ </tr>
+ <tr>
+ <td > Ruby client </td>
+ <td > M3 </td>
+
+ <td > Y </td>
+ <td > Y </td>
+ <td > N </td>
+ </tr>
+ <tr>
+ <td > C# client 0-10 </td>
+ <td > M4, 0.5, 0.6, 0.8</td>
+
+ <td > N </td>
+ <td > N </td>
+ <td > Y</td>
+ </tr>
+ <tr>
+ <td > C# client 0-8 </td>
+ <td > M3, M4, 0.5, 0.6, 0.8</td>
+
+ <td > Y </td>
+ <td > N </td>
+ <td > N </td>
+ </tr>
+ <tr>
+ <td > WCF channel </td>
+ <td > 0.6, 0.8</td>
+
+ <td > N </td>
+ <td > N </td>
+ <td > Y </td>
+ </tr>
+ </tbody></table>
+ </div>
+</div>
+
diff --git a/qpid/doc/website/content/documentation.html b/qpid/doc/website/content/documentation.html
new file mode 100644
index 0000000000..0a49a7c50b
--- /dev/null
+++ b/qpid/doc/website/content/documentation.html
@@ -0,0 +1,92 @@
+<!--
+ -
+ - Licensed to the Apache Software Foundation (ASF) under one
+ - or more contributor license agreements. See the NOTICE file
+ - distributed with this work for additional information
+ - regarding copyright ownership. The ASF licenses this file
+ - to you under the Apache License, Version 2.0 (the
+ - "License"); you may not use this file except in compliance
+ - with the License. You may obtain a copy of the License at
+ -
+ - http://www.apache.org/licenses/LICENSE-2.0
+ -
+ - Unless required by applicable law or agreed to in writing,
+ - software distributed under the License is distributed on an
+ - "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ - KIND, either express or implied. See the License for the
+ - specific language governing permissions and limitations
+ - under the License.
+ -
+-->
+<div class="main_text_area_body">
+ <h1>Qpid Documentation</h1>
+
+ <h2 id="doc-release">Documentation for Qpid 0.8 release</h2>
+
+ <p>This documentation was converted from the Wiki and organized into
+ book form. <a href="#doc-archives">The archives</a> contain the
+ original content of the Wiki.</p>
+
+ <ul>
+ <li><a href="getting_started.html">Getting Started</a></li>
+ <li><p>AMQP Messaging Broker (C++ implementation for Linux, Windows, Solaris)</p>
+ <p>
+ <a href="books/0.8/AMQP-Messaging-Broker-CPP-Book/pdf/AMQP-Messaging-Broker-CPP-Book.pdf"
+ name="AMQP Messaging Broker (C++ implemementation)">PDF</a> |
+ <a href="books/0.8/AMQP-Messaging-Broker-CPP-Book/html/index.html">HTML</a></p></li>
+ <li><p>AMQP Messaging Broker (Java implemementation)</p>
+ <p><a href="books/0.8/AMQP-Messaging-Broker-Java-Book/pdf/AMQP-Messaging-Broker-Java-Book.pdf"
+ name="AMQP Messaging Broker (Java implemementation)">PDF</a> |
+ <a href="books/0.8/AMQP-Messaging-Broker-Java-Book/html/index.html">HTML</a></p></li>
+ <li><p>Programming in Apache Qpid: Cross-Platform AMQP Messaging in Java JMS, .NET, C++, and Python</p>
+ <p>
+ <a href="books/0.8/Programming-In-Apache-Qpid/pdf/Programming-In-Apache-Qpid.pdf"
+ name="Cross-Platform AMQP Messaging in Java JMS, .NET, C++, and Python">PDF</a> |
+ <a href="books/0.8/Programming-In-Apache-Qpid/html/index.html"
+ name="Cross-Platform AMQP Messaging in Java JMS, .NET, C++, and Python">HTML</a></p></li>
+ <li><p>For programming examples and documentation for Qpid,
+ see the <a href="getting_started.html">Getting Started</a>
+ page.</p></li>
+ <li><p>API Reference Documentation</p>
+ <p>C++: <a href="apis/0.8/cpp/html/index.html">HTML</a> | <a href="apis/0.8/cpp/qpid-cpp-doxygen-0.8.html.tar.gz">qpid-cpp-doxygen-0.8.html.tar.gz</a></p>
+ <p>Python: <a href="apis/0.8/python/html/index.html">HTML</a> | <a href="apis/0.8/python/qpid-python-epydoc-0.8.html.tar.gz">qpid-python-epydoc-0.8.html.tar.gz</a></p></li>
+ </ul>
+
+
+ <h2 id="doc-trunk">Documentation for Qpid development trunk</h2>
+ <ul>
+ <li><a href="getting_started.html">Getting Started</a></li>
+ <li><p>AMQP Messaging Broker (C++ implementation for Linux, Windows, Solaris)</p>
+ <p>
+ <a href="books/trunk/AMQP-Messaging-Broker-CPP-Book/pdf/AMQP-Messaging-Broker-CPP-Book.pdf"
+ name="AMQP Messaging Broker (C++ implemementation)">PDF</a> |
+ <a href="books/trunk/AMQP-Messaging-Broker-CPP-Book/html/index.html">HTML</a></p></li>
+ <li><p>AMQP Messaging Broker (Java implemementation)</p>
+ <p><a href="books/trunk/AMQP-Messaging-Broker-Java-Book/pdf/AMQP-Messaging-Broker-Java-Book.pdf"
+ name="AMQP Messaging Broker (Java implemementation)">PDF</a> |
+ <a href="books/trunk/AMQP-Messaging-Broker-Java-Book/html/index.html">HTML</a></p></li>
+ <li><p>Programming in Apache Qpid: Cross-Platform AMQP Messaging in Java JMS, .NET, C++, and Python</p>
+ <p>
+ <a href="books/trunk/Programming-In-Apache-Qpid/pdf/Programming-In-Apache-Qpid.pdf"
+ name="Cross-Platform AMQP Messaging in Java JMS, .NET, C++, and Python">PDF</a> |
+ <a href="books/trunk/Programming-In-Apache-Qpid/html/index.html"
+ name="Cross-Platform AMQP Messaging in Java JMS, .NET, C++, and Python">HTML</a></p></li>
+ </ul>
+
+
+
+ <h2 id="doc-archives">Documentation Archives</h2>
+
+ <ul>
+ <li><p>Qpid Wiki converted to PDF format on 26 May 2010</p>
+ <a href="archives/qpid-2010-05-26.html.zip">HTML</a> |
+ <a href="archives/qpid-2010-05-26.pdf">PDF</a></li>
+ </ul>
+
+ <h2 id="qpid-wiki">Qpid Wiki</h2>
+
+ <ul>
+ <li><p><a href="https://cwiki.apache.org/qpid/">Qpid Wiki</a></p></li>
+ </ul>
+
+</div>
diff --git a/qpid/doc/website/content/download.cgi b/qpid/doc/website/content/download.cgi
new file mode 100644
index 0000000000..c4e25082c8
--- /dev/null
+++ b/qpid/doc/website/content/download.cgi
@@ -0,0 +1,26 @@
+#!/bin/sh
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+# Wrapper script around mirrors.cgi script
+# (we must change to that directory in order for python to pick up the
+# python includes correctly)
+cd /www/www.apache.org/dyn/mirrors
+/www/www.apache.org/dyn/mirrors/mirrors.cgi $*
+
diff --git a/qpid/doc/website/content/download.html b/qpid/doc/website/content/download.html
new file mode 100644
index 0000000000..b8d1013cfc
--- /dev/null
+++ b/qpid/doc/website/content/download.html
@@ -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.
+ -
+-->
+<div class="main_text_area_body">
+ <h1>Downloads</h1>
+
+ <h2>Production Releases</h2>
+
+ <p>These releases are well tested and appropriate for production use, use the links below to download them from one of our mirrors. Older versions can be found in the <a href="http://archive.apache.org/dist/qpid/">archive</a></p>
+
+ <p>Qpid supports the latest version of AMQP 0-10, and some components also the earlier AMQP 0-8 and 0-9 versions. The Java Broker and Client provide protocol negotiation. For details on cross component compatibility among releases, see: <a href="./compatibility.html">AMQP Release Compatibility for Qpid</a></p>
+
+ <p>If you have any questions about these releases, please email the <a href="mailto:users@qpid.apache.org">user list</a></p>
+
+ <h2>Mirrors</h2>
+
+ <p>[if-any logo]
+<a href="[link]"><img align="right" src="[logo]" border="0" /></a>[end]
+The currently selected mirror is <b>[preferred]</b>. If you encounter a problem with this mirror, please select another. If all mirrors are failing, there are <i>backup</i> mirrors (at the end of the list) that should be available, or you may also consult the <a href="http://www.apache.org/mirrors/">complete list</a> of mirrors.</p>
+
+<form action="[location]" method="get" id="SelectMirror">
+<p>
+Other mirrors: <select name="Preferred">
+[if-any http]
+ [for http]<option value="[http]">[http]</option>[end]
+[end]
+[if-any ftp]
+ [for ftp]<option value="[ftp]">[ftp]</option>[end]
+[end]
+[if-any backup]
+ [for backup]<option value="[backup]">[backup] (backup)</option>[end]
+[end]
+</select>
+<input type="submit" value="Change" />
+</p>
+</form>
+
+ <p> It is good practice to <a href="#Download-Verify">verify</a> the integrity of the downloaded files using signatures downloaded from our <a href="http://www.apache.org/dist/qpid/">main distribution directory</a>.</p>
+
+
+ <h2>Latest Release: 0.8</h2>
+
+ <p>Individual PGP signatures are provided below, and the sha1sum output for each artefact is listed here: <a href="http://www.apache.org/dist/qpid/0.8/SHA1SUM">SHA1SUM</a>.</p>
+
+ <h3>Multiple Component Packages</h3>
+
+ <div>
+ <table class="download_table"><tbody>
+ <tr>
+ <th class="download_table_col_1"> Component </th>
+
+ <th> Download </th>
+ <th class="download_table_amqp_col"> AMQP<br />0-10 </th>
+ <th class="download_table_amqp_col"> AMQP<br />0-8/0-9 </th>
+ </tr>
+ <tr>
+ <td class="download_table_col_1"> Full source release</td>
+ <td> <a href="[preferred]/qpid/0.8/qpid-0.8.tar.gz">qpid-0.8.tar.gz</a> [<a href="http://www.apache.org/dist/qpid/0.8/qpid-0.8.tar.gz.asc">PGP</a>] </td>
+
+ <td class="download_table_amqp_col"> Y </td>
+ <td class="download_table_amqp_col"> Y </td>
+ </tr>
+ <tr>
+ <td class="download_table_col_1"> C+&#43; broker &amp; client </td>
+ <td> <a href="[preferred]/qpid/0.8/qpid-cpp-0.8.tar.gz">qpid-cpp-0.8.tar.gz</a> [<a href="http://www.apache.org/dist/qpid/0.8/qpid-cpp-0.8.tar.gz.asc">PGP</a>] </td>
+
+ <td class="download_table_amqp_col"> Y </td>
+ <td class="download_table_amqp_col">&nbsp;</td>
+ </tr>
+ <tr>
+ <td class="download_table_col_1"> Java broker, client &amp; tools </td>
+ <td> <a href="[preferred]/qpid/0.8/qpid-java-0.8.tar.gz">qpid-java-0.8.tar.gz</a> [<a href="http://www.apache.org/dist/qpid/0.8/qpid-java-0.8.tar.gz.asc">PGP</a>] </td>
+ <td class="download_table_amqp_col"> Y </td>
+
+ <td class="download_table_amqp_col"> Y </td>
+ </tr>
+ <tr>
+ <td class="download_table_col_1"> All released artefacts</td>
+ <td> <a href="[preferred]/qpid/0.8/">/qpid/0.8/</a> </td>
+
+ <td class="download_table_amqp_col"> Y </td>
+ <td class="download_table_amqp_col"> Y </td>
+ </tr>
+ </tbody></table>
+ </div>
+
+
+ <h3><a name="Download-SingleComponentPackage"></a>Single Component Packages</h3>
+
+ <p><b>Broker</b></p>
+ <div>
+ <table class="download_table"><tbody>
+ <tr>
+ <th class="download_table_col_1"> Language </th>
+
+ <th> Download </th>
+ <th class="download_table_amqp_col"> AMQP<br />0-10 </th>
+ <th class="download_table_amqp_col"> AMQP<br />0-8/0-9 </th>
+ </tr>
+ <tr>
+ <td class="download_table_col_1"> Java </td>
+ <td> <a href="[preferred]/qpid/0.8/qpid-java-broker-0.8.tar.gz">qpid-java-broker-0.8.tar.gz</a> [<a href="http://www.apache.org/dist/qpid/0.8/qpid-java-broker-0.8.tar.gz.asc">PGP</a>] </td>
+
+ <td class="download_table_amqp_col"> Y </td>
+ <td class="download_table_amqp_col"> Y </td>
+ </tr>
+ </tbody></table>
+ </div>
+
+
+ <p><b>Client</b></p>
+ <div>
+ <table class="download_table"><tbody>
+ <tr>
+ <th class="download_table_col_1"> Language </th>
+
+ <th> Download </th>
+ <th class="download_table_amqp_col"> AMQP<br />0-10 </th>
+ <th class="download_table_amqp_col"> AMQP<br />0-8/0-9 </th>
+ </tr>
+ <tr>
+ <td class="download_table_col_1"> C# (.NET, WCF) WCF channel (C+&#43; Broker Compatible) </td>
+ <td> <a href="[preferred]/qpid/0.8/qpid-wcf-0.8.zip">qpid-wcf-0.8.zip</a> [<a href="http://www.apache.org/dist/qpid/0.8/qpid-wcf-0.8.zip.asc">PGP</a>] </td>
+
+ <td class="download_table_amqp_col"> Y </td>
+ <td class="download_table_amqp_col">&nbsp;</td>
+ </tr>
+ <tr>
+ <td class="download_table_col_1"> C# (.NET, WCF, Excel) 0-10 client (C+&#43; Broker Compatible) </td>
+ <td> <a href="[preferred]/qpid/0.8/qpid-dotnet-0-10-0.8.zip">qpid-dotnet-0-10-0.8.zip</a> [<a href="http://www.apache.org/dist/qpid/0.8/qpid-dotnet-0-10-0.8.zip.asc">PGP</a>] </td>
+ <td class="download_table_amqp_col"> Y </td>
+
+ <td class="download_table_amqp_col">&nbsp;</td>
+ </tr>
+ <tr>
+ <td class="download_table_col_1"> C# (.NET) 0-8 client (Java Broker Compatible) </td>
+ <td> <a href="[preferred]/qpid/0.8/qpid-dotnet-0-8-0.8.zip">qpid-dotnet-0-8-0.8.zip</a> [<a href="http://www.apache.org/dist/qpid/0.8/qpid-dotnet-0-8-0.8.zip.asc">PGP</a>] </td>
+ <td class="download_table_amqp_col">&nbsp;</td>
+ <td class="download_table_amqp_col"> Y </td>
+ </tr>
+ <tr>
+ <td class="download_table_col_1"> Java </td>
+
+ <td> <a href="[preferred]/qpid/0.8/qpid-java-client-0.8.tar.gz">qpid-java-client-0.8.tar.gz</a> [<a href="http://www.apache.org/dist/qpid/0.8/qpid-java-client-0.8.tar.gz.asc">PGP</a>] </td>
+ <td class="download_table_amqp_col"> Y </td>
+ <td class="download_table_amqp_col"> Y </td>
+ </tr>
+ <tr>
+ <td class="download_table_col_1"> Python </td>
+ <td> <a href="[preferred]/qpid/0.8/qpid-python-0.8.tar.gz">qpid-python-0.8.tar.gz</a> [<a href="http://www.apache.org/dist/qpid/0.8/qpid-python-0.8.tar.gz.asc">PGP</a>] </td>
+
+ <td class="download_table_amqp_col"> Y </td>
+ <td class="download_table_amqp_col"> Y </td>
+ </tr>
+ <tr>
+ <td class="download_table_col_1"> Ruby </td>
+ <td> <a href="[preferred]/qpid/0.8/qpid-ruby-0.8.tar.gz">qpid-ruby-0.8.tar.gz</a> [<a href="http://www.apache.org/dist/qpid/0.8/qpid-ruby-0.8.tar.gz.asc">PGP</a>] </td>
+ <td class="download_table_amqp_col"> Y </td>
+
+ <td class="download_table_amqp_col"> Y </td>
+ </tr>
+ </tbody></table>
+ </div>
+
+
+ <p><b>Management tools</b></p>
+
+ <p>C+&#43; broker management</p>
+ <div>
+ <table class="download_table"><tbody>
+
+ <tr>
+ <th class="download_table_col_1"> Component </th>
+ <th> Download </th>
+ <th class="download_table_amqp_col"> AMQP<br />0-10 </th>
+ <th class="download_table_amqp_col"> AMQP<br />0-8/0-9 </th>
+ </tr>
+ <tr>
+ <td class="download_table_col_1"> Cmd line tools <br /> (packaged in full-release)</td>
+ <td> <a href="[preferred]/qpid/0.8/qpid-0.8.tar.gz">qpid-0.8.tar.gz</a> [<a href="http://www.apache.org/dist/qpid/0.8/qpid-0.8.tar.gz.asc">PGP</a>] </td>
+
+ <td class="download_table_amqp_col"> Y </td>
+ <td class="download_table_amqp_col">&nbsp;</td>
+ </tr>
+ </tbody></table>
+
+ </div>
+
+
+ <p>Java broker management</p>
+ <div>
+ <table class="download_table"><tbody>
+ <tr>
+ <th class="download_table_col_1"> Component </th>
+ <th> Download </th>
+ </tr>
+ <tr>
+ <td class="download_table_col_1"> JMX Management Console <br /> </td>
+
+ <td> <a href="[preferred]/qpid/0.8/qpid-jmx-management-console-0.8-linux-gtk-x86.tar.gz">Linux x86</a> [<a href="http://www.apache.org/dist/qpid/0.8/qpid-jmx-management-console-0.8-linux-gtk-x86.tar.gz.asc">PGP</a>] | <a href="[preferred]/qpid/0.8/qpid-jmx-management-console-0.8-linux-gtk-x86_64.tar.gz">Linux x86_64</a> [<a href="http://www.apache.org/dist/qpid/0.8/qpid-jmx-management-console-0.8-linux-gtk-x86_64.tar.gz.asc">PGP</a>] | <a href="[preferred]/qpid/0.8/qpid-jmx-management-console-0.8-macosx.zip">Mac OS X</a> [<a href="http://www.apache.org/dist/qpid/0.8/qpid-jmx-management-console-0.8-macosx.zip.asc">PGP</a>] | <a href="[preferred]/qpid/0.8/qpid-jmx-management-console-0.8-solaris-gtk-sparc.tar.gz">Solaris 10 Sparc</a> [<a href="http://www.apache.org/dist/qpid/0.8/qpid-jmx-management-console-0.8-solaris-gtk-sparc.tar.gz.asc">PGP</a>] | <a href="[preferred]/qpid/0.8/qpid-jmx-management-console-0.8-win32-win32-x86.zip">Windows x86</a> [<a href="http://www.apache.org/dist/qpid/0.8/qpid-jmx-management-console-0.8-win32-win32-x86.zip.asc">PGP</a>] </td>
+ </tr>
+ </tbody></table>
+ </div>
+
+
+
+ <h2><a name="Download-PreviousRelease"></a>Previous Release: 0.6</h2>
+
+ <p>Individual PGP signatures are provided below, and the sha1sum output for each artefact is listed here: <a href="http://www.apache.org/dist/qpid/0.6/SHA1SUM">SHA1SUM</a>.</p>
+
+ <h3>Multiple Component Packages</h3>
+
+ <div>
+ <table class="download_table"><tbody>
+ <tr>
+ <th class="download_table_col_1"> Component </th>
+
+ <th> Download </th>
+ <th class="download_table_amqp_col"> AMQP<br />0-10 </th>
+ <th class="download_table_amqp_col"> AMQP<br />0-8/0-9 </th>
+ </tr>
+ <tr>
+ <td class="download_table_col_1"> All released artefacts</td>
+ <td> <a href="[preferred]/qpid/0.6/">/qpid/0.6/</a> </td>
+
+ <td class="download_table_amqp_col"> Y </td>
+ <td class="download_table_amqp_col"> Y </td>
+ </tr>
+ <tr>
+ <td class="download_table_col_1"> C+&#43; broker &amp; client </td>
+ <td> <a href="[preferred]/qpid/0.6/qpid-cpp-0.6.tar.gz">qpid-cpp-0.6.tar.gz</a> [<a href="http://www.apache.org/dist/qpid/0.6/qpid-cpp-0.6.tar.gz.asc">PGP</a>] </td>
+
+ <td class="download_table_amqp_col"> Y </td>
+ <td class="download_table_amqp_col">&nbsp;</td>
+ </tr>
+ <tr>
+ <td class="download_table_col_1"> Java broker, client &amp; tools </td>
+ <td> <a href="[preferred]/qpid/0.6/qpid-java-0.6.tar.gz">qpid-java-0.6.tar.gz</a> [<a href="http://www.apache.org/dist/qpid/0.6/qpid-java-0.6.tar.gz.asc">PGP</a>] </td>
+ <td class="download_table_amqp_col"> Y </td>
+
+ <td class="download_table_amqp_col"> Y </td>
+ </tr>
+ </tbody></table>
+ </div>
+
+
+ <h3><a name="Download-SingleComponentPackage"></a>Single Component Packages</h3>
+
+ <p><b>Broker</b></p>
+ <div>
+ <table class="download_table"><tbody>
+ <tr>
+ <th class="download_table_col_1"> Language </th>
+
+ <th> Download </th>
+ <th class="download_table_amqp_col"> AMQP<br />0-10 </th>
+ <th class="download_table_amqp_col"> AMQP<br />0-8/0-9 </th>
+ </tr>
+ <tr>
+ <td class="download_table_col_1"> Java </td>
+ <td> <a href="[preferred]/qpid/0.6/qpid-java-broker-0.6.tar.gz">qpid-java-broker-0.6.tar.gz</a> [<a href="http://www.apache.org/dist/qpid/0.6/qpid-java-broker-0.6.tar.gz.asc">PGP</a>] </td>
+
+ <td class="download_table_amqp_col"> Y </td>
+ <td class="download_table_amqp_col"> Y </td>
+ </tr>
+ </tbody></table>
+ </div>
+
+
+ <p><b>Client</b></p>
+ <div>
+ <table class="download_table"><tbody>
+ <tr>
+ <th class="download_table_col_1"> Language </th>
+
+ <th> Download </th>
+ <th class="download_table_amqp_col"> AMQP<br />0-10 </th>
+ <th class="download_table_amqp_col"> AMQP<br />0-8/0-9 </th>
+ </tr>
+ <tr>
+ <td class="download_table_col_1"> C# (.NET, WCF) WCF channel (C+&#43; Broker Compatible) </td>
+ <td> <a href="[preferred]/qpid/0.6/qpid-wcf-0.6.zip">qpid-wcf-0.6.zip</a> [<a href="http://www.apache.org/dist/qpid/0.6/qpid-wcf-0.6.zip.asc">PGP</a>] </td>
+
+ <td class="download_table_amqp_col"> Y </td>
+ <td class="download_table_amqp_col">&nbsp;</td>
+ </tr>
+ <tr>
+ <td class="download_table_col_1"> C# (.NET, WCF, Excel) 0-10 client (C+&#43; Broker Compatible) </td>
+ <td> <a href="[preferred]/qpid/0.6/qpid-dotnet-0-10-0.6.zip">qpid-dotnet-0-10-0.6.zip</a> [<a href="http://www.apache.org/dist/qpid/0.6/qpid-dotnet-0-10-0.6.zip.asc">PGP</a>] </td>
+ <td class="download_table_amqp_col"> Y </td>
+
+ <td class="download_table_amqp_col">&nbsp;</td>
+ </tr>
+ <tr>
+ <td class="download_table_col_1"> C# (.NET) 0-8 client (Java Broker Compatible) </td>
+ <td> <a href="[preferred]/qpid/0.6/qpid-dotnet-0-8-0.6.zip">qpid-dotnet-0-8-0.6.zip</a> [<a href="http://www.apache.org/dist/qpid/0.6/qpid-dotnet-0-8-0.6.zip.asc">PGP</a>] </td>
+ <td class="download_table_amqp_col">&nbsp;</td>
+ <td class="download_table_amqp_col"> Y </td>
+ </tr>
+ <tr>
+ <td class="download_table_col_1"> Java </td>
+
+ <td> <a href="[preferred]/qpid/0.6/qpid-java-client-0.6.tar.gz">qpid-java-client-0.6.tar.gz</a> [<a href="http://www.apache.org/dist/qpid/0.6/qpid-java-client-0.6.tar.gz.asc">PGP</a>] </td>
+ <td class="download_table_amqp_col"> Y </td>
+ <td class="download_table_amqp_col"> Y </td>
+ </tr>
+ <tr>
+ <td class="download_table_col_1"> Python </td>
+ <td> <a href="[preferred]/qpid/0.6/qpid-python-0.6.tar.gz">qpid-python-0.6.tar.gz</a> [<a href="http://www.apache.org/dist/qpid/0.6/qpid-python-0.6.tar.gz.asc">PGP</a>] </td>
+
+ <td class="download_table_amqp_col"> Y </td>
+ <td class="download_table_amqp_col"> Y </td>
+ </tr>
+ <tr>
+ <td class="download_table_col_1"> Ruby </td>
+ <td> <a href="[preferred]/qpid/0.6/qpid-ruby-0.6.tar.gz">qpid-ruby-0.6.tar.gz</a> [<a href="http://www.apache.org/dist/qpid/0.6/qpid-ruby-0.6.tar.gz.asc">PGP</a>] </td>
+ <td class="download_table_amqp_col"> Y </td>
+
+ <td class="download_table_amqp_col"> Y </td>
+ </tr>
+ </tbody></table>
+ </div>
+
+
+ <p><b>Management tools</b></p>
+
+ <p>C+&#43; broker management</p>
+ <div>
+ <table class="download_table"><tbody>
+
+ <tr>
+ <th class="download_table_col_1"> Component </th>
+ <th> Download </th>
+ <th class="download_table_amqp_col"> AMQP<br />0-10 </th>
+ <th class="download_table_amqp_col"> AMQP<br />0-8/0-9 </th>
+ </tr>
+ <tr>
+ <td class="download_table_col_1"> cmd line (packaged with python) </td>
+ <td> <a href="[preferred]/qpid/0.6/qpid-python-0.6.tar.gz">qpid-python-0.6.tar.gz</a> [<a href="http://www.apache.org/dist/qpid/0.6/qpid-python-0.6.tar.gz.asc">PGP</a>] </td>
+
+ <td class="download_table_amqp_col"> Y </td>
+ <td class="download_table_amqp_col">&nbsp;</td>
+ </tr>
+ <tr>
+ <td class="download_table_col_1"> QMan JMX bridge, WS-DM </td>
+ <td> <a href="[preferred]/qpid/0.6/qpid-management-client-0.6.tar.gz">qpid-management-client-0.6.tar.gz</a> [<a href="http://www.apache.org/dist/qpid/0.6/qpid-management-client-0.6.tar.gz.asc">PGP</a>] </td>
+ <td class="download_table_amqp_col"> Y </td>
+ <td class="download_table_amqp_col">&nbsp;</td>
+ </tr>
+ </tbody></table>
+
+ </div>
+
+
+ <p>Java broker management</p>
+ <div>
+ <table class="download_table"><tbody>
+ <tr>
+ <th class="download_table_col_1"> Component </th>
+ <th> Download </th>
+ </tr>
+ <tr>
+ <td class="download_table_col_1"> JMX Management Console <br /> </td>
+
+ <td> <a href="[preferred]/qpid/0.6/qpid-jmx-management-console-0.6-linux-gtk-x86.tar.gz">Linux x86</a> [<a href="http://www.apache.org/dist/qpid/0.6/qpid-jmx-management-console-0.6-linux-gtk-x86.tar.gz.asc">PGP</a>] | <a href="[preferred]/qpid/0.6/qpid-jmx-management-console-0.6-linux-gtk-x86_64.tar.gz">Linux x86_64</a> [<a href="http://www.apache.org/dist/qpid/0.6/qpid-jmx-management-console-0.6-linux-gtk-x86_64.tar.gz.asc">PGP</a>] | <a href="[preferred]/qpid/0.6/qpid-jmx-management-console-0.6-macosx.zip">Mac OS X</a> [<a href="http://www.apache.org/dist/qpid/0.6/qpid-jmx-management-console-0.6-macosx.zip.asc">PGP</a>] | <a href="[preferred]/qpid/0.6/qpid-jmx-management-console-0.6-solaris-gtk-sparc.tar.gz">Solaris 10 Sparc</a> [<a href="http://www.apache.org/dist/qpid/0.6/qpid-jmx-management-console-0.6-solaris-gtk-sparc.tar.gz.asc">PGP</a>] | <a href="[preferred]/qpid/0.6/qpid-jmx-management-console-0.6-win32-win32-x86.zip">Windows x86</a> [<a href="http://www.apache.org/dist/qpid/0.6/qpid-jmx-management-console-0.6-win32-win32-x86.zip.asc">PGP</a>] </td>
+ </tr>
+ </tbody></table>
+ </div>
+
+
+ <h2><a name="Download-QpidComponents.org"></a>QpidComponents.org </h2>
+
+ <p><a href="http://QpidComponents.org">QpidComponents.org</a> provides further components for Apache Qpid, including both persistence and management tools. These components are open source, but are not developed as part of the Apache Qpid project due to licensing or other restrictions.</p>
+
+ <h2><a name="Download-ContributedC%5CPackages"></a>Contributed C+&#43; Packages</h2>
+
+ <h3><a name="Download-WindowsInstaller"></a>Windows Installer</h3>
+
+ <p>The Windows installer is available from <a href="http://www.riverace.com/qpid/downloads.htm">http://www.riverace.com/qpid/downloads.htm</a>. It is built from the C+&#43; broker &amp; client and C# WCF Channel source distributions listed above. It has been tested for Windows XP SP3 and above.</p>
+
+ <h3><a name="Download-PrebuiltLinuxPackages"></a>Pre-built Linux Packages</h3>
+
+ <h4><a name="Download-Fedora"></a>Fedora </h4>
+
+ <p>On Fedora, Qpid can be installed using yum. Because Java RPMs are not yet available in Fedora repos, the Java client is not in these distributions.</p>
+
+ <p>To install the server:</p>
+ <div><div>
+ <pre>
+# yum install qpidd
+ </pre>
+ </div></div>
+
+ <p>To install C+&#43; and Python clients:</p>
+ <div><div>
+ <pre>
+# yum install qpidc-devel
+ </pre>
+ </div></div>
+ <div><div>
+ <pre>
+# yum install amqp python-qpid
+ </pre>
+ </div></div>
+ <p>To install documentation:</p>
+ <div><div>
+
+ <pre>
+# yum install rhm-docs
+ </pre>
+ </div></div>
+ <p>To install persistence using an external store module:</p>
+ <div><div>
+ <pre>
+# yum install rhm
+ </pre>
+ </div></div>
+
+ <h2><a name="Download-SourceCodeRepository"></a>Source Code Repository</h2>
+
+ <p>The latest version of the code is always available in the <a href="source_repository.html" title="Source Repository">Source Repository</a>.</p>
+
+
+ <h2><a name="Download-Verify"></a>Verify the integrity of the files</h2>
+
+ <p>It is essential that you verify the integrity of the downloaded files using the PGP signatures or SHA1 checksums.</p>
+
+ <p>The PGP signatures can be verified using PGP or GPG. First download the <a href="http://www.apache.org/dist/qpid/KEYS">KEYS</a> file as well as the <code>.asc</code> PGP signature file for the relevant artefact. Make sure you get these files from the relevant subdirectory of the <a href="http://www.apache.org/dist/qpid/">main distribution directory</a>, rather than from a mirror. Then verify the signatures using:</p>
+
+ <p>
+ <code>
+% pgpk -a KEYS<br />
+% pgpv qpid-0.8.tar.gz.asc<br />
+ </code>
+ <em>or</em><br />
+ <code>
+% pgp -ka KEYS<br />
+% pgp qpid-0.8.tar.gz.asc<br />
+ </code>
+ <em>or</em><br />
+ <code>
+% gpg --import KEYS<br />
+% gpg --verify qpid-0.8.tar.gz.asc
+ </code>
+ </p>
+
+<p>Alternatively, you can verify the SHA1 checksum of the files. A unix program called <code>sha1</code> or <code>sha1sum</code> is included in many unix distributions. It is also available as part of <a href="http://www.gnu.org/software/textutils/textutils.html">GNU Textutils</a>. For windows users, <a href="http://www.slavasoft.com/fsum/">fsum</a> supports SHA1. Ensure your generated checksum string matches the string published in the SHA1SUM file included with each release. Again, make sure you get this file from the relevant subdirectory of the <a href="http://www.apache.org/dist/qpid/">main distribution directory</a>, rather than from a mirror</p>
+
+</div>
diff --git a/qpid/doc/website/content/getting_involved.html b/qpid/doc/website/content/getting_involved.html
new file mode 100644
index 0000000000..033abdc443
--- /dev/null
+++ b/qpid/doc/website/content/getting_involved.html
@@ -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.
+ -
+-->
+<div class="main_text_area_body">
+
+<h1>Getting Involved</h1>
+
+<h2><a name="GettingInvolved-TherearemanywaysyoucangetinvolvedinQpid%3A"></a>Join in</h2>
+
+<ol>
+ <li>Participate on the <a href="mailing_lists.html" title="Mailing Lists">Mailing Lists</a>.</li>
+ <li>Contibute via <a href="http://issues.apache.org/jira/browse/qpid">JIRA issues</a>. Remember that all patches must be attached to a JIRA with the ASL usage granted or we can't use it!</li>
+ <li>Review the current code.</li>
+ <li>Help write user documentation.</li>
+ <li>Help write user examples.</li>
+ <li>Most definitely add more tests.</li>
+</ol>
+
+<p>Please be sure to take a look at the coding guidelines for the section of the project that you contribute to:</p>
+
+<ul>
+ <li><a href="https://cwiki.apache.org/qpid/java-coding-standards.html">Java Coding Standards</a></li>
+ <li><a href="https://cwiki.apache.org/qpid/cppstyleguide.html">C++ Coding Standards</a></li>
+
+ <li><a href="https://cwiki.apache.org/qpid/cpptips.html">C++ Tips</a></li>
+ <li><a href="https://cwiki.apache.org/qpid/osvc.html">OS version considerations</a></li>
+</ul>
+
+<h2><a name="GettingInvolved-ProjectEtiquette"></a>Project Etiquette</h2>
+
+<p>Please read and digest our <a href="qpid_project_etiquette_guide.html" title="Qpid Project Etiquette Guide">Qpid Project Etiquette Guide</a>. This is a key guide for new contributers and required reading.</p>
+
+<h2><a name="GettingInvolved-Becomingacommitter%3A"></a>Becoming a Committer</h2>
+
+<p>Qpid uses the following guidelines for voting in new committers. First off we would like new committers to have provided meaningful contribution to the project. By contributions we include development (tests, features, examples) or documentation through patches and interactions with the project through lists and JIRA. It should be noted that as we send our JIRA to the dev list, thus some people filter the JIRA's to limit traffic. It is thus good to cross post something to the dev list every now and again, if the discussion is being held primarily on JIRA.</p>
+
+<p>The key question is what does the Qpid project consider to be a meaningful contribution to be come a committer. As this bar is set for all new commiters Qpid will be conservative in general with adding new committers.</p>
+
+<p>The Qpid project will look to see if someone consistently provides quality contributions and interactions with the project over a period of several weeks. Based on that the PMC will vote the new committers onto the project. </p>
+
+<p>If you have any question please mail <a href="mailto:dev@qpid.apache.org">dev@qpid.apache.org</a> or <a href="mailto:private@qpid.apache.org">private@qpid.apache.org</a> </p>
+
+<p>Many thanks for you interest,<br />
+
+The Qpid Team.</p>
+
+<h2><a name="GettingInvolved-JoiningthePMC"></a>Joining the PMC</h2>
+
+<p>Nominations for Qpid PMC membership will be voted on by the Qpid PMC.</p>
+
+</div>
+
diff --git a/qpid/doc/website/content/getting_started.html b/qpid/doc/website/content/getting_started.html
new file mode 100644
index 0000000000..5a3a8cb602
--- /dev/null
+++ b/qpid/doc/website/content/getting_started.html
@@ -0,0 +1,85 @@
+<!--
+ -
+ - Licensed to the Apache Software Foundation (ASF) under one
+ - or more contributor license agreements. See the NOTICE file
+ - distributed with this work for additional information
+ - regarding copyright ownership. The ASF licenses this file
+ - to you under the Apache License, Version 2.0 (the
+ - "License"); you may not use this file except in compliance
+ - with the License. You may obtain a copy of the License at
+ -
+ - http://www.apache.org/licenses/LICENSE-2.0
+ -
+ - Unless required by applicable law or agreed to in writing,
+ - software distributed under the License is distributed on an
+ - "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ - KIND, either express or implied. See the License for the
+ - specific language governing permissions and limitations
+ - under the License.
+ -
+-->
+<div class="main_text_area_body" >
+ <h1>Getting Started with Apache Qpid</h1>
+ <p>To get started with Apache Qpid, follow the steps below.</p>
+
+ <ol>
+ <li>Download the software <a href="download.cgi" title="Download">Download</a></li>
+ <li>Start a broker.
+ <ul>
+ <li>Instructions for <a href="https://cwiki.apache.org/qpid/getting-started-guide.html" title="Getting Started Guide">running a Qpid Java broker (AMQP 0-8, 0-9) </a></li>
+ <li>Instructions for <a href="http://qpid.apache.org/books/trunk/AMQP-Messaging-Broker-CPP-Book/html/ch01.html#section-Running-a-Qpid-CPP-Broker" title="RASC">running a Qpid C++ broker (AMQP 0-10) </a></li>
+
+ <li><a href="https://cwiki.apache.org/qpid/mgmtc.html" title="MgmtC++">Management tools </a> (AMQP 0-10, works with the Qpid C++ broker)</li>
+ </ul>
+ </li>
+ <li>Run an example program from the downloaded software, or from the following URLs (these are svn URLs, which you can use to browse the examples or check them out):
+ <ul>
+ <li>C++ (AMQP 0-10):
+ <ul>
+ <li>Examples: <a href="https://svn.apache.org/repos/asf/qpid/trunk/qpid/cpp/examples/">https://svn.apache.org/repos/asf/qpid/trunk/qpid/cpp/examples/ </a></li>
+
+ <li><a href="https://svn.apache.org/repos/asf/qpid/trunk/qpid/cpp/examples/README.txt">Running the C++ Examples </a></li>
+ </ul>
+ </li>
+ <li>Java JMS (AMQP 0-10):
+ <ul>
+ <li>Examples: <a href="https://svn.apache.org/repos/asf/qpid/trunk/qpid/java/client/example/">https://svn.apache.org/repos/asf/qpid/trunk/qpid/java/client/example/ </a></li>
+ <li><a href="https://svn.apache.org/repos/asf/qpid/trunk/qpid/java/client/example/src/main/java/runSample.sh">Script for Running the Java JMS Examples </a></li>
+
+ </ul>
+ </li>
+ <li>Python (AMQP 0-10):
+ <ul>
+ <li>Examples: <a href="https://svn.apache.org/repos/asf/qpid/trunk/qpid/python/examples/">https://svn.apache.org/repos/asf/qpid/trunk/qpid/python/examples/ </a></li>
+ <li><a href="https://svn.apache.org/repos/asf/qpid/trunk/qpid/python/examples/README">Running the Python Examples </a></li>
+ </ul>
+ </li>
+
+ <li>Ruby (AMQP 0-10):
+ <ul>
+ <li>Examples: <a href="https://svn.apache.org/repos/asf/qpid/trunk/qpid/ruby/examples/">https://svn.apache.org/repos/asf/qpid/trunk/qpid/ruby/examples/ </a></li>
+ </ul>
+ </li>
+ <li>.NET (AMQP 0-10):
+ <ul>
+ <li>Examples: <a href="http://svn.apache.org/viewvc/qpid/trunk/qpid/dotnet/client-010/examples/">http://svn.apache.org/viewvc/qpid/trunk/qpid/dotnet/client-010/examples/ </a></li>
+
+ <li><a href="https://cwiki.apache.org/qpid/net-user-guide.html">.NET Tutorial </a></li>
+ </ul>
+ </li>
+ </ul>
+ </li>
+ <li>Read the API Guides and Documentation
+ <ul>
+ <li><p><a href="documentation.html">API Guides and Documentation</a></li>
+ </ul>
+ </li>
+ <li>Get your Questions Answered
+ <ul>
+ <li>Read the <a href="https://cwiki.apache.org/qpid/faq.html" title="FAQ">FAQ</a></li>
+
+ <li>Ask a question on the user list <a href="mailto:users-subscribe@qpid.apache.org">users-subscribe@qpid.apache.org</a></li>
+ </ul>
+ </li>
+ </ol>
+</div>
diff --git a/qpid/doc/website/content/images/README.txt b/qpid/doc/website/content/images/README.txt
new file mode 100644
index 0000000000..c53909bfd2
--- /dev/null
+++ b/qpid/doc/website/content/images/README.txt
@@ -0,0 +1 @@
+This directory is for images associated with content, not the images used in page templates.
diff --git a/qpid/doc/website/content/images/jprofiler.png b/qpid/doc/website/content/images/jprofiler.png
new file mode 100644
index 0000000000..7c5da2cf94
--- /dev/null
+++ b/qpid/doc/website/content/images/jprofiler.png
Binary files differ
diff --git a/qpid/doc/website/content/images/structure101.jpg b/qpid/doc/website/content/images/structure101.jpg
new file mode 100644
index 0000000000..9242ea9176
--- /dev/null
+++ b/qpid/doc/website/content/images/structure101.jpg
Binary files differ
diff --git a/qpid/doc/website/content/index.html b/qpid/doc/website/content/index.html
new file mode 100644
index 0000000000..16e96ebc7a
--- /dev/null
+++ b/qpid/doc/website/content/index.html
@@ -0,0 +1,91 @@
+<!--
+ -
+ - Licensed to the Apache Software Foundation (ASF) under one
+ - or more contributor license agreements. See the NOTICE file
+ - distributed with this work for additional information
+ - regarding copyright ownership. The ASF licenses this file
+ - to you under the Apache License, Version 2.0 (the
+ - "License"); you may not use this file except in compliance
+ - with the License. You may obtain a copy of the License at
+ -
+ - http://www.apache.org/licenses/LICENSE-2.0
+ -
+ - Unless required by applicable law or agreed to in writing,
+ - software distributed under the License is distributed on an
+ - "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ - KIND, either express or implied. See the License for the
+ - specific language governing permissions and limitations
+ - under the License.
+ -
+-->
+<div class="main_text_area_body">
+ <h1>Introduction</h1>
+
+ <p>Apache Qpid&#8482; is a cross-platform Enterprise
+ Messaging system which implements the Advanced Message Queuing Protocol
+ (AMQP), providing message brokers written in C++ and
+ Java, along with clients for C++, Java JMS, .Net, Python, and Ruby.</p>
+
+ <p>Enterprise Messaging systems let programs communicate by
+ exchanging messages, much as people communicate by
+ exchanging email. Unlike email, enterprise messaging systems
+ provide guaranteed delivery, speed, security, and freedom
+ from spam. Until recently, there was no open standard for
+ Enterprise Messaging systems, so programmers either wrote
+ their own, or used expensive proprietary systems.</p>
+
+ <p><a href="http://www.amqp.org/">AMQP</a> is the first open standard for
+ Enterprise Messaging. It is designed to support messaging
+ for just about any distributed or business
+ application. Routing can be configured flexibly, easily
+ supporting common messaging paradigms like point-to-point,
+ fanout, publish-subscribe, and request-response.</p>
+
+ <p>Apache Qpid implements the latest AMQP specification, providing
+ transaction management, queuing, distribution, security,
+ management, clustering, federation and heterogeneous
+ multi-platform support and a lot more. And Apache Qpid is
+ extremely fast. Apache Qpid <a href="compatibility.html"
+ title="AMQP compatibility">aims to be 100% AMQP Compliant</a>.</p>
+
+ <p>This is a project of the <a href="http://www.apache.org/">Apache Software Foundation.</a></p>
+
+ <div class="feature_box">
+ <div class="feature_box_column1">
+ <h3>AMQP Brokers</h3>
+ <ul>
+ <li><p>Java Implementation</p>
+ </li>
+ <li><p>C++ Implementation</p>
+ </li>
+ </ul>
+ <br/>
+ <br/>
+ </div> <!-- end of feature_box_column -->
+
+ <div class="feature_box_column2">
+ <h3>AMQP Client APIs</h3>
+ <ul>
+ <li>Java (JMS 1.1 compliant)</li>
+ <li>C++ (Linux/Windows)</li>
+ <li>C# .NET</li>
+ <li>WCF Adapter (Windows Only)</li>
+ <li>Python</li>
+ <li>Ruby</li>
+ </ul>
+ </div> <!-- end of feature_box_column -->
+
+ <div class="feature_box_column3">
+ <h3>Qpid Management</h3>
+ <ul>
+ <li>QMF Python API</li>
+ <li>QMF C++ API </li>
+ <li>Python tools</li>
+ <li>JMX</li>
+ </ul>
+ </div> <!-- end of feature_box_column -->
+
+ </div> <!-- end of feature_box -->
+
+</div> <!-- end of main_text_area_body -->
+
diff --git a/qpid/doc/website/content/mailing_lists.html b/qpid/doc/website/content/mailing_lists.html
new file mode 100644
index 0000000000..b1c5266e40
--- /dev/null
+++ b/qpid/doc/website/content/mailing_lists.html
@@ -0,0 +1,82 @@
+<!--
+ -
+ - Licensed to the Apache Software Foundation (ASF) under one
+ - or more contributor license agreements. See the NOTICE file
+ - distributed with this work for additional information
+ - regarding copyright ownership. The ASF licenses this file
+ - to you under the Apache License, Version 2.0 (the
+ - "License"); you may not use this file except in compliance
+ - with the License. You may obtain a copy of the License at
+ -
+ - http://www.apache.org/licenses/LICENSE-2.0
+ -
+ - Unless required by applicable law or agreed to in writing,
+ - software distributed under the License is distributed on an
+ - "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ - KIND, either express or implied. See the License for the
+ - specific language governing permissions and limitations
+ - under the License.
+ -
+-->
+<div class="main_text_area_body">
+ <h1>Qpid Mailing lists</h1>
+
+ <p>There are a number of lists listed below. Note when sening subscription emails it is best to have a value in the subjsct and body even if it is only 'subscribe'. This will help the ensure the email get past the spam filters.</p>
+
+ <h2>Qpid User List</h2>
+
+ <p>The user's list is for discussions that relate to use or questions
+ on Qpid. If you have questions about how a feature works, suggestions
+ on additional requirements, or general questions about Qpid please use
+ this list.</p>
+
+ <ul>
+ <li>To subscribe to the user's list send an e-mail with subject 'subscribe' to:<br />
+ <a href="mailto:users-subscribe@qpid.apache.org">users-subscribe@qpid.apache.org</a></li>
+
+ <li>To remove yourself from the user's list send an e-mail with subject 'unsubscribe' to:<br />
+ <a href="mailto:users-unsubscribe@qpid.apache.org">users-unsubscribe@qpid.apache.org</a></li>
+ <li>The user's mailing list is archived. You can view the archive at:
+ <ul>
+ <li>Apache archive: <a href="http://mail-archives.apache.org/mod_mbox/qpid-users/">http://mail-archives.apache.org/mod_mbox/qpid-users/</a><br/></li>
+ <li>Nabble archive: <a href="http://n2.nabble.com/Apache-Qpid-users-f2158936.html">http://n2.nabble.com/Apache-Qpid-users-f2158936.html</a></li>
+ </ul>
+ </li>
+ </ul>
+
+
+ <h2><a name="MailingLists-QpidDeveloperList"></a>Qpid Developer List</h2>
+
+ <p>The developer's list is for discussions that relate to the on going development of Qpid. If you have questions about how a feature is being developed, suggestions on how to implement a new feature, or requests for a new feature this is the list to use.</p>
+
+ <ul>
+ <li>To subscribe to the developer's list send an e-mail with subject 'subscribe' to:<br />
+ <a href="mailto:dev-subscribe@qpid.apache.org">dev-subscribe@qpid.apache.org</a></li>
+ <li>To remove yourself from the developer's list send an e-mail with subject 'unsubscribe' to:
+ <a href="mailto:dev-unsubscribe@qpid.apache.org">dev-unsubscribe@qpid.apache.org</a></li>
+ <li>The developer's mailing list is archived. You can view the archive at:
+ <ul>
+ <li>Apache archive: <a href="http://mail-archives.apache.org/mod_mbox/qpid-dev/">http://mail-archives.apache.org/mod_mbox/qpid-dev/</a></li>
+ <li>Nabble archive: <a href="http://www.nabble.com/Qpid-Developers-f16694.html">http://www.nabble.com/Qpid-Developers-f16694.html</a><br/>
+ and <a href="http://n2.nabble.com/Apache-Qpid-developers-f2158895.html">http://n2.nabble.com/Apache-Qpid-developers-f2158895.html</a></li>
+ </ul>
+ </li>
+ </ul>
+
+
+ <h2><a name="MailingLists-QpidCommitsList"></a>Qpid Commits List</h2>
+
+ <p>The commits list is for recieving notifications about code being committed to the Qpid repository. The trafic on this list is automatically generated by Subversion. You should not post messages to this list.</p>
+
+ <ul>
+ <li>To subscribe to the commits list send an e-mail with subject 'subscribe' to:<br />
+ <a href="mailto:commits-subscribe@qpid.apache.org">commits-subscribe@qpid.apache.org</a></li>
+ <li>To remove yourself from the commits list send an e-mail with subject 'unsubscribe' to:<br />
+ <a href="mailto:commits-unsubscribe@qpid.apache.org">commits-unsubscribe@qpid.apache.org</a></li>
+ <li>The commits mailing list is archived. You can view the archive at:
+ <ul>
+ <li>Apache archive: <a href="http://mail-archives.apache.org/mod_mbox/qpid-commits/">http://mail-archives.apache.org/mod_mbox/qpid-commits/</a></li>
+ </ul>
+ </li>
+ </ul>
+</div>
diff --git a/qpid/doc/website/content/people.html b/qpid/doc/website/content/people.html
new file mode 100644
index 0000000000..4b78a0a255
--- /dev/null
+++ b/qpid/doc/website/content/people.html
@@ -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.
+ -
+-->
+<div class="main_text_area_body">
+ <h1>People</h1>
+
+ <p>This page lists some of the people who have contributed to Qpid.</p>
+
+ <h2>Committers</h2>
+ <p>The people listed below have made significant contributions to
+ Qpid by working long and hard to make quality software for the rest
+ of the world to use.</p>
+
+ <p>In addition to providing us contribuions, or being commmitters
+ some of the following people are also members of the Project
+ Management Committee (PMC). Refer to the How the ASF works for
+ details on meritocracy.</p>
+
+ <p>If you would like to contribute to Qpid please look at the Get
+ Involved page to see how you can contribute.</p>
+
+ <ul>
+ <li>Aidan Skinner</li>
+ <li>Alan Conway</li>
+ <li>Andrea Gazzarini</li>
+ <li>Andrew Kennedy</li>
+ <li>Andrew Stitcher</li>
+ <li>Arnaud Simon</li>
+ <li>Carl Trieloff</li>
+ <li>Chuck Rolke</li>
+ <li>Cliff Jansen</li>
+ <li>Gordon Sim</li>
+ <li>Jim Meyering</li>
+ <li>John O'Hara</li>
+ <li>Jonathan Robie</li>
+ <li>Ken Giusti</li>
+ <li>Kim van der Riet</li>
+ <li>Lahiru Gunathilake</li>
+ <li>Manuel Teira</li>
+ <li>Marnie McCormack</li>
+ <li>Martin Ritchie</li>
+ <li>Michael Goulish</li>
+ <li>Nuno Santos</li>
+ <li>Paul Fremantle</li>
+ <li>Rafael Schloming</li>
+ <li>Rajith Attapattu</li>
+ <li>Robbie Gemmell</li>
+ <li>Robert Godfrey</li>
+ <li>Robert Greig</li>
+ <li>Rupert Smith</li>
+ <li>Steve Huston</li>
+ <li>Ted Ross</li>
+ <li>Yoav Shapira</li>
+ </ul>
+
+ <h2>Contributors</h2>
+
+
+ <p>Many thanks to the following people for providing contributions:</p>
+
+ <ul>
+ <li>Colin Crist</li>
+ <li>Bhupendra Bhardwaj</li>
+ <li>Kevin Smith</li>
+ <li>Steve Vinoski</li>
+ <li>Steven Shaw</li>
+ <li>Tomas Restrepo</li>
+ </ul>
+
+ <h2>Mentors</h2>
+
+ <p>And many thanks to our project's mentors:</p>
+
+ <ul>
+ <li>Cliff Schmidt</li>
+ <li>Craig Russell</li>
+ <li>Paul Fremantle</li>
+ <li>Yoav Shapira</li>
+ <li>Scott Deboy</li>
+ </ul>
+</div>
diff --git a/qpid/doc/website/content/qpid_integrated_with.html b/qpid/doc/website/content/qpid_integrated_with.html
new file mode 100644
index 0000000000..a2b53209c7
--- /dev/null
+++ b/qpid/doc/website/content/qpid_integrated_with.html
@@ -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.
+ -
+-->
+<div class="main_text_area_body">
+
+ <h1><a name="QpidIntegrations-AMQPintegrations"></a>AMQP integrations </h1>
+
+ <ul>
+ <li><a href="http://qpid.apache.org/archives/wiki/hermesjms.html" title="HermesJMS">HermesJMS</a> - The integration of Hermes JMS with Qpid</li>
+ <li>Twisted AMQP - <a href="https://launchpad.net/txamqp" class="external-link" rel="nofollow">https://launchpad.net/txamqp</a></li>
+ <li>Apache Camel - <a href="http://activemq.apache.org/camel/amqp.html" class="external-link" rel="nofollow">http://activemq.apache.org/camel/amqp.html</a></li>
+ <li>Apache Axis2 Java - <a href="http://wso2.org/library/3663" class="external-link" rel="nofollow">http://wso2.org/library/3663</a></li>
+
+ <li>Apache Axis2 C - <a href="http://ws.apache.org/axis2/c/docs/axis2c_manual.html#amqptrans" class="external-link" rel="nofollow">http://ws.apache.org/axis2/c/docs/axis2c_manual.html#amqptrans</a></li>
+ <li>Apache Synapse</li>
+ <li>libvirt - <a href="http://libvirt.org/" class="external-link" rel="nofollow">http://libvirt.org/</a> Provides QMF access to visualization</li>
+ <li>Ovirt - <a href="http://ovirt.org/" class="external-link" rel="nofollow">http://ovirt.org/</a> QMFC - used to build management tools</li>
+
+ <li>Python web plugin - Plug-in for AMQP support from web browser</li>
+ <li>Red Hat MRG - <a href="http://redhat.com/mrg" class="external-link" rel="nofollow">http://redhat.com/mrg</a> Distro of Qpid with added management console and persistence</li>
+ <li>Condor - <a href="http://www.cs.wisc.edu/condor/" class="external-link" rel="nofollow">http://www.cs.wisc.edu/condor/</a> QMF Agents and AMQP job routing</li>
+ </ul>
+</div>
diff --git a/qpid/doc/website/content/qpid_project_etiquette_guide.html b/qpid/doc/website/content/qpid_project_etiquette_guide.html
new file mode 100644
index 0000000000..7ce69c327a
--- /dev/null
+++ b/qpid/doc/website/content/qpid_project_etiquette_guide.html
@@ -0,0 +1,104 @@
+<!--
+ -
+ - Licensed to the Apache Software Foundation (ASF) under one
+ - or more contributor license agreements. See the NOTICE file
+ - distributed with this work for additional information
+ - regarding copyright ownership. The ASF licenses this file
+ - to you under the Apache License, Version 2.0 (the
+ - "License"); you may not use this file except in compliance
+ - with the License. You may obtain a copy of the License at
+ -
+ - http://www.apache.org/licenses/LICENSE-2.0
+ -
+ - Unless required by applicable law or agreed to in writing,
+ - software distributed under the License is distributed on an
+ - "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ - KIND, either express or implied. See the License for the
+ - specific language governing permissions and limitations
+ - under the License.
+ -
+-->
+<div class="main_text_area_body">
+
+<h1>Qpid Project Etiquette Guide</h1>
+
+<h2><a name="QpidProjectEtiquetteGuide-Purpose"></a>Purpose</h2>
+
+<p>This guide, written by Rafael Schloming, gives both Qpid committers and submitters a useful introduction to project etiquette, shedding light on how we do things &amp; why. Following this etiquette makes the path to righteousness less long and winding !</p>
+
+<h2><a name="QpidProjectEtiquetteGuide-Maintainers"></a>Maintainers</h2>
+
+<p>The Qpid project consists of a number of major components spread across almost as many different languages. Thus it is rare for qpid committers to be experts in every single area of the project.</p>
+
+<p>As such it is expected that qpid committers make some effort to reach out to their teammates before directly modifying components that are outside their chosen areas. </p>
+
+<p>You should use the dev list to reach out to Qpid developers and comment on any JIRAs you're progressing.</p>
+
+<h2><a name="QpidProjectEtiquetteGuide-PatchSubmission"></a>Patch Submission</h2>
+
+<p>As a committer it can be difficult to decide whether/how to provide feedback when someone submits a patch. Often it is tempting to just fix up the patch and avoid the slower and sometimes awkward process of telling someone that they got some part of it wrong. </p>
+
+<p>However, it is necessary to ensure that those who submit patches get to learn what they need to know in order to become a valued qpid committer.</p>
+
+<p>In that spirit, here are a few guidelines for contributing patch submissions and how we handle them:</p>
+
+<ul>
+ <li>Submitters should produce the final patch(s) as applied to the tree. Producing a patch that needs little or no rework is a key skill for a qpid committer.</li>
+
+ <li>Maintainers may make requests for 'trivial' updates to the patch. Such requests are vital to ensuring that contributers get familiar with subtle yet important aspects of the code, stylistic conventions, etc.</li>
+
+ <li>Make sure the submitter is familiar with project etiquette so they understand why we make seemingly trivial requests. We'll ask new contributers to read this etiquette info for that reason !</li>
+
+ <li>A one-time patch from someone passing through may need nothing more than a polite thank you regardless of the content. If a submitter does aim for committership, best to make it plain you're planning to stay around on the project.</li>
+
+ <li>Break up unrelated changes. It wouldn't be considered correct for a committer to glom together too many unrelated changes within a single commit, and so we won't commit this kind of patch from submitters.</li>
+
+ <li>You need a JIRA for any patch to be attached to, which should accurately describe the change.</li>
+</ul>
+
+
+<h2><a name="QpidProjectEtiquetteGuide-BigIdeas"></a>Big Ideas</h2>
+
+<p>Every so often someone has a Big Idea that they get excited about and want to go do. They generally mail the list about it to give people the opportunity to comment, and then when nobody says anything they go off and do it.</p>
+
+<p>Fast forward six months later they commit/merge/enable/publish the result of their Big Idea, and suddenly everyone understands the full implications, and not everyone is happy. </p>
+
+<h3><a name="QpidProjectEtiquetteGuide-Guidelines"></a>Guidelines</h3>
+
+<p>So, here are a few guidelines for making sure this doesn't happen, starting with how to write a good proposal for a Big Idea:</p>
+
+<ul>
+ <li>Make sure your proposal is recognizable as a proposal. An easy way to avoid ambiguity is to start a new thread for your proposal and stick &quot;proposal&quot; somewhere in the subject.</li>
+
+ <li>Understand who and what your proposal effects, and make this clear. If you think X's implementation of Y doesn't deserve to live and you're going to rewrite the whole thing from scratch then make this very clear so X can object sooner rather than later.</li>
+
+ <li>Make sure you call out loudly that you intend to kill feature A, even if you think no-one on earth should care.</li>
+
+ <li>Even if you're going to write an Atari emulator, and you're 100% sure that it won't overlap with anything in the rest of the project, make sure you understand how and why it relates to the rest of the project in general, and make that clear.</li>
+
+ <li>Be concrete. Often a proposal of the form &quot;hey, I did a little of this, here is a proof-of-concept, I'd like to do it for real now&quot; is far more effective than a proposal of the form &quot;hey, I have this vague idea about this, I'm going to vaguely suggest it would be good if someone did it&quot;.</li>
+
+ <li>Talk about the long term implications of your proposal. If it's code then someone needs to maintain it, and committers will expect this to be you. Make clear your intentions.</li>
+
+ <li>Never assume silence implies complicity, more likely it means people didn't understand the implications of your proposal, or didn't have time to figure out why they didn't like it. Ask again !</li>
+
+ <li>The bigger your idea is, the more time and effort you should spend on the proposal, and ensuring that you get positive responses and deal with the comments and feedback provided in your actual implementation.</li>
+</ul>
+
+
+<h3><a name="QpidProjectEtiquetteGuide-Talkearly%2Ctalkoften"></a>Talk early, talk often</h3>
+
+<p>No matter how incredibly excellent your proposal is, there is going to need to be some discussion before the result of your Big Idea is blessed. Here are some things you can do to help that discussion go smoothly:</p>
+
+<ul>
+ <li>Make frequent progress reports. Every hour/day/week/month you spend working without telling people what you're doing is an hour/day/week/month of your time that you risk wasting.</li>
+
+ <li>Define milestones and make them visible to the rest of the project. Just like a concrete proof-of-concept can help a proposal, it helps to give people a concrete look at what you're doing while it's in progress. This can go a long way towards avoiding surprises.</li>
+</ul>
+
+<h3><a name="QpidProjectEtiquetteGuide-Andfinally....."></a>And finally .....</h3>
+
+<p>When the time does come to commit/merge/enable/publish your Big Idea, it really shouldn't be a surprise to anyone if you've followed the steps up until now, but make sure you let people know in advance by making note in your final few progress reports of when you expect to be finished, and sending a note to the dev list a day or so before you flip the big switch.</p>
+
+</div>
+
diff --git a/qpid/doc/website/content/release_notes_0.8.html b/qpid/doc/website/content/release_notes_0.8.html
new file mode 100644
index 0000000000..2e0bb1fd7a
--- /dev/null
+++ b/qpid/doc/website/content/release_notes_0.8.html
@@ -0,0 +1,437 @@
+<!--
+ -
+ - Licensed to the Apache Software Foundation (ASF) under one
+ - or more contributor license agreements. See the NOTICE file
+ - distributed with this work for additional information
+ - regarding copyright ownership. The ASF licenses this file
+ - to you under the Apache License, Version 2.0 (the
+ - "License"); you may not use this file except in compliance
+ - with the License. You may obtain a copy of the License at
+ -
+ - http://www.apache.org/licenses/LICENSE-2.0
+ -
+ - Unless required by applicable law or agreed to in writing,
+ - software distributed under the License is distributed on an
+ - "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ - KIND, either express or implied. See the License for the
+ - specific language governing permissions and limitations
+ - under the License.
+ -
+-->
+<div class="main_text_area_body">
+ <h1>0.8 Release Notes</h1>
+
+<p>The full list of changes in the Qpid 0.8 release incorporates both the issues worked on during the 0.7 development stream and any final touches made during the 0.8 release process. A list of these JIRA issues can be found below.</p>
+
+<h3>JIRA Issues</h3>
+
+<h4>New Feature</h4>
+<ul>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-664'>QPID-664</a>] - High-level C++ client API.</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-1403'>QPID-1403</a>] - Add SSL support for C++ Windows broker/client</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-1940'>QPID-1940</a>] - QMF Feature Request - Structured exceptions for method failure</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2321'>QPID-2321</a>] - [Java Broker] Add "conflation queue" to Java Broker</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2363'>QPID-2363</a>] - JMS Map Message Should Support AMQP 0-10 Encoded Map As Message Body</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2365'>QPID-2365</a>] - Reroute messages on a queue - remove messages from a queue and send them to an exchange</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2412'>QPID-2412</a>] - Support for SASL EXTERNAL when using SSL</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2500'>QPID-2500</a>] - Transport security for the WCF channel</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2555'>QPID-2555</a>] - Qpid Info OSGI plugin</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2581'>QPID-2581</a>] - Create a ConfigurationManager to allow plugins to provide configuration handling classes</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2589'>QPID-2589</a>] - Add a .NET binding to QPID Messaging API</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2614'>QPID-2614</a>] - QueueConfiguration requires to configurations to be provided on construction</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2646'>QPID-2646</a>] - Qpid Messaging address support for WCF Channel</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2700'>QPID-2700</a>] - Ability to remove queue binding in QPID</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2807'>QPID-2807</a>] - More flexible acknowledgement</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2867'>QPID-2867</a>] - enable the JMX management console to remove bindings from direct/topic exchanges</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2909'>QPID-2909</a>] - Hybrid SQL-CLFS persistence store for C++ broker on Windows</li>
+</ul>
+
+<h4>Bug</h4>
+<ul>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-1662'>QPID-1662</a>] - TimeToLiveTest.testPassive occasionally receives more messages.</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-1879'>QPID-1879</a>] - The client library uses a new thread for every connection</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-1904'>QPID-1904</a>] - Timestamps are incorrect</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2137'>QPID-2137</a>] - StringIndexOutOfBounds when formating Connection Message during failed systest run.</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2165'>QPID-2165</a>] - MINANetworkDriverTest fails to socket already in use</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2173'>QPID-2173</a>] - Java client should set the process ID in the client properties during Connection open</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2174'>QPID-2174</a>] - When kerberos auth is used, Java client should use the kerberos userid &amp; domain when setting the userid in messages</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2186'>QPID-2186</a>] - Windows - "vector iterator not dereferencable"</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2262'>QPID-2262</a>] - Random test failures in SimpleACLTest</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2265'>QPID-2265</a>] - Ruby Rakfile References an old file</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2297'>QPID-2297</a>] - ACL policy won't allow "." in the realm for users added to a group</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2298'>QPID-2298</a>] - CMake-based install based on released sources tries to include generated headers from build tree</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2299'>QPID-2299</a>] - C++ Messaging drain and spout examples need vcproj files</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2300'>QPID-2300</a>] - C++ packaging directory not included in release</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2301'>QPID-2301</a>] - C++ examples changed at r880718; obsolete vcproj files not removed</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2302'>QPID-2302</a>] - Missing header.html, footer.html in C++ docs/api distribution</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2306'>QPID-2306</a>] - C++ uninstaller does not uninstall some header files.</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2318'>QPID-2318</a>] - qpid-tool does not seem to issue session acknowledgements </li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2320'>QPID-2320</a>] - Failed acquire on LVQ causes broker crash</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2323'>QPID-2323</a>] - Add uuid to variant</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2325'>QPID-2325</a>] - [Java Broker] SASL PLAIN authentication does not work when both an authentication and authorization id are supplied</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2328'>QPID-2328</a>] - Querying for 500 objects causes C++ based ruby console to hang</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2336'>QPID-2336</a>] - Cannot disable heatbeats in JMS client</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2338'>QPID-2338</a>] - [C++ Broker] Ring queue does not properly implement byte size limits</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2339'>QPID-2339</a>] - JMS (0-10 client) does not verify if it supports the SASL mechanisms sent by the broker.</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2340'>QPID-2340</a>] - [Java] ProducerFlowControlTest failing due to race condition in test</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2344'>QPID-2344</a>] - qpid/messaging/uuid.h r899657 breaks Windows build...</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2347'>QPID-2347</a>] - Subscribers are never notified if queue is deleted from under them</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2355'>QPID-2355</a>] - QMF bindings build conflicts with installed qmf headers</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2360'>QPID-2360</a>] - declaring virtualhost level firewall configuration in virtualhosts.xml leads to NPE on startup</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2361'>QPID-2361</a>] - exchange configuration attributes are ignored when configuration is placed in virtualhosts.xml</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2366'>QPID-2366</a>] - Windows C++ broker port written to stdout at startup is wrong</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2370'>QPID-2370</a>] - TTR-Qpid-07-NA failed due to channel error 504 during tear down</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2372'>QPID-2372</a>] - PeriodicTimerImpl addition broker Windows build</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2374'>QPID-2374</a>] - qpidd: --require-encryption with "--auth no" will reject SSL connections as being "un-encrypted" </li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2376'>QPID-2376</a>] - C++ broker build broken at 20:00 Thurs Jan 28, 2010</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2378'>QPID-2378</a>] - WCF/C++ Client subtree lacks Apache licensing files</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2387'>QPID-2387</a>] - qpidd does not replicate management agent lists, causes brokers to exit. </li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2388'>QPID-2388</a>] - user-defined signals can cause process terminate</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2392'>QPID-2392</a>] - Powershell scripts not included in release source kits</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2395'>QPID-2395</a>] - fd leak in Connection</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2398'>QPID-2398</a>] - C++ examples' Visual Studio projects need BOOST_ALL_DYN_LINK to build against installed kit</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2406'>QPID-2406</a>] - Consistent approach to durations in qpid::messaging api</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2407'>QPID-2407</a>] - C++ SSL session can get bad buffer management</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2413'>QPID-2413</a>] - ACL - error handling/bounds checking</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2418'>QPID-2418</a>] - Existing durable subscription with selector is not unsubscribed during change to new subscription</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2420'>QPID-2420</a>] - Windows SQL-based persistence loses prepared two-phase transactions on broker restart</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2422'>QPID-2422</a>] - DerbyStore does not persist queue exclusivity or arguments</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2426'>QPID-2426</a>] - Better error message and logging when receving/sending from/to empty address</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2427'>QPID-2427</a>] - Modify browse option in-line with path chosen for python client</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2428'>QPID-2428</a>] - qpid.subject should be set on outgoing messages if the address specifies a suject</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2429'>QPID-2429</a>] - headers exchange does not match correctly on a map entry with a null value</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2430'>QPID-2430</a>] - Java broker emits NPE following qpid-tool being connected</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2431'>QPID-2431</a>] - .NET csproj files missing Apache license text</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2433'>QPID-2433</a>] - qpid-server.bat fails if the path contains a space character</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2434'>QPID-2434</a>] - make clean in qpid/cpp/src/tests/testagent breaks build</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2435'>QPID-2435</a>] - Deadlock can occur during the registration of a qmf agent</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2437'>QPID-2437</a>] - Define exceptions for messaging API</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2438'>QPID-2438</a>] - Performance tests do not correctly populate the message with the given MessageSize</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2439'>QPID-2439</a>] - CMake builds broken 08-Mar-2010</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2441'>QPID-2441</a>] - make check fails because of wrong sorting</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2444'>QPID-2444</a>] - JMS client does not verify that the hostname connected to matches that specified in the servers certificate</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2445'>QPID-2445</a>] - JMS Client needs to extract the user ID from the external auth mechanism when SASL EXTERNAL is used</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2452'>QPID-2452</a>] - Inconsistent handling on strings between C++ and Python messaging APIs</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2463'>QPID-2463</a>] - C++ install step puts api docs in wrong place on Windows</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2465'>QPID-2465</a>] - Ant 1.8.x javac task prints warning message during builds</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2467'>QPID-2467</a>] - Windows install doesn't include qpidxarm.dll or broker plugins</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2468'>QPID-2468</a>] - WCF client samples can't resolve the DLLs when installed</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2471'>QPID-2471</a>] - Java client releases messages in an unpredictable order on recover</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2472'>QPID-2472</a>] - QpidCompositeRollingAppender log4j configuration is misleading</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2474'>QPID-2474</a>] - ACL file reader can trip vector iter validity checking</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2475'>QPID-2475</a>] - qpid/messaging/Session.h r928855 breaks Windows build - macro conflict</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2481'>QPID-2481</a>] - Deadlock in Qpid 0.6</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2482'>QPID-2482</a>] - Topic Exchange can duplicate messages.</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2484'>QPID-2484</a>] - Interoperability tests fail due to attempts to print out contents of JMS Message objects, and do not parse command line properies</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2487'>QPID-2487</a>] - Tearing down one dynamic route may delete other independent routes in the federation.</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2488'>QPID-2488</a>] - ACL - error handling/bounds checking</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2493'>QPID-2493</a>] - AMQPEncodedMapMessage does not support nested maps and lists</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2497'>QPID-2497</a>] - messaging api silently ignores unrecognised/invalid address options</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2502'>QPID-2502</a>] - securityTracker open() call is made on exchangeTracker instance instead</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2503'>QPID-2503</a>] - CommandLineParser does not print '-' when showing options</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2506'>QPID-2506</a>] - QMF: fix encoding/decoding of map and list method call arguments</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2507'>QPID-2507</a>] - C++ broker can deadlock when processing a bind.</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2511'>QPID-2511</a>] - ConnectionImpl instance may be deleted before IO threads are finished with the underllying DispatchHandle</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2515'>QPID-2515</a>] - Need to be able to set flow control in Java on a per destination level</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2520'>QPID-2520</a>] - Broken POM generation on Windows</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2521'>QPID-2521</a>] - ACL module core dumps if management is disabled</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2523'>QPID-2523</a>] - When reloading a large acl file while acl lookup is in progress, the broker core dumps</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2526'>QPID-2526</a>] - Ant build fails if the path contains a space character</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2553'>QPID-2553</a>] - CMakeLists wrong file name </li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2558'>QPID-2558</a>] - client connection.open to a non-broker on qpid 0.6 windows segfaults with: access violation</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2561'>QPID-2561</a>] - Download page does not follow ASF standards</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2562'>QPID-2562</a>] - website does not have any links to the Issue tracker</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2563'>QPID-2563</a>] - Website does not have required ASF elements</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2564'>QPID-2564</a>] - Wcf functional test source file is absent</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2570'>QPID-2570</a>] - Broker uses NotAllowedException for ACL violations, should use UnauthorisedAccessException</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2587'>QPID-2587</a>] - PollableCondition test fails on Windows</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2600'>QPID-2600</a>] - ACL policy doesn't permit certain characters in usernames added to groups</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2605'>QPID-2605</a>] - Recovered messages larger than 65523 bytes result in framing violation ()</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2607'>QPID-2607</a>] - Package name typo for CRAMMD5HexInitialiserTest.java</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2608'>QPID-2608</a>] - AMQPException messages contain duplicate AMQConstant text</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2609'>QPID-2609</a>] - MockAMQQueue does not implement getName</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2610'>QPID-2610</a>] - AMQConstant Map usage is not correct</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2611'>QPID-2611</a>] - AMQConnectionFailureException does not record reason for underlying cause if it is an AMQPException</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2612'>QPID-2612</a>] - Recent DLL qpidtypes breaks the build on Windows</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2613'>QPID-2613</a>] - message data is not commited to the persistent store on 0-8/0-9 codepath</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2615'>QPID-2615</a>] - JMX Management Console fails to connect to 0.5 and below brokers if run in a Java5 VM</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2626'>QPID-2626</a>] - Typo in ServerConnectionDelegate</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2631'>QPID-2631</a>] - Race in qpid::client::Bounds causes (rare) deadlock</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2634'>QPID-2634</a>] - CRLF line endings in the shell scripts</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2635'>QPID-2635</a>] - Ant tests fail with OutOfMemoryError due to PermGen space exhaustion</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2636'>QPID-2636</a>] - disconnect() callback on broker results in leaked connections</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2637'>QPID-2637</a>] - connection.start() hangs if the connection is not accepted</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2640'>QPID-2640</a>] - options string for connection does not work for some types</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2641'>QPID-2641</a>] - The bitwise AND operator used instead of logical AND in QpidLog4JConfigurator.java</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2642'>QPID-2642</a>] - The bitwise AND operator used instead of logical AND in QpidLog4JConfigurator.java</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2644'>QPID-2644</a>] - Console examples sometimes fail due to not waiting for the broker connection to complete</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2647'>QPID-2647</a>] - Typo in str8-latin type definition for 0-10</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2649'>QPID-2649</a>] - Segfault on shutting down qpidd</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2650'>QPID-2650</a>] - DerbyStore only ever uses auto-commit connections</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2653'>QPID-2653</a>] - Double checked locking in org.apache.qpid.server.transport.ThreadPoolFilter</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2654'>QPID-2654</a>] - Access control plugin should use Actor logging</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2657'>QPID-2657</a>] - Verify/correct error handling on client 0-10 codepath</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2658'>QPID-2658</a>] - Update Java 0-10 profile excludes</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2661'>QPID-2661</a>] - The 0-8 BasicGetMethodHandler should return NOT_IMPLEMENTED for 0-10 messages</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2662'>QPID-2662</a>] - The FirewallPlugin should accept a ServerSocket, not the string representation</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2665'>QPID-2665</a>] - Remove BROKER from object types for plugins</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2668'>QPID-2668</a>] - PlainPasswordPrincipalDatabase - code improvement </li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2670'>QPID-2670</a>] - Concurrent tagging of message with trace id while message is delivered from another queue causes segfault</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2673'>QPID-2673</a>] - retained 0-10 ImplicitAcceptDispositionChangeListener objects can lead to connection closure timeout and broker OOM</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2674'>QPID-2674</a>] - heartbeats can cause seg faults under tcp on linux</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2677'>QPID-2677</a>] - QMF: console.py sends agent locate request before it has enabled receiving data indications.</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2686'>QPID-2686</a>] - Update Ant doc task with better configuration</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2687'>QPID-2687</a>] - The PluginManager does not auto-deploy bundles properly</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2688'>QPID-2688</a>] - Exclusive queues deleted before unacked messages are requeued; unacked messages not routed to alternate-exchange as a result.</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2691'>QPID-2691</a>] - ttl is lost for federation routes where trace id is added</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2694'>QPID-2694</a>] - Memory leak in 0-8/0-9 AMQSessions on channel close</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2695'>QPID-2695</a>] - VirtualHostConfigRecoveryHandler can NPE or bind to the wrong exchange on binding recovery</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2696'>QPID-2696</a>] - Addressing strings in the jndi properties file is interpreted as binding urls</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2697'>QPID-2697</a>] - AMQConnectionURL options do not appear in the toString representation</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2698'>QPID-2698</a>] - Certain amqp 0-10 message properties are not exposed through messaging apis message class</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2702'>QPID-2702</a>] - --max-connections not work when using cluster</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2704'>QPID-2704</a>] - Provide scavenge() for SimpleQueueEntryList - TRUNK MERGE</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2706'>QPID-2706</a>] - Visual Basic example includes a directory whose name contains a space</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2707'>QPID-2707</a>] - Cmake build doesn't output all needed settings to build a valid shared library name for loading</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2716'>QPID-2716</a>] - QMF: c++ agent does not set the agent name attribute in an object id during addObject() call.</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2718'>QPID-2718</a>] - Update the common.bnd to match client.bnd, release version</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2719'>QPID-2719</a>] - Some SSL errors do not get reported up the stack or in the log file.</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2722'>QPID-2722</a>] - The JMS 0-10 client does not make use of the subject specified via "qpid.subject" in the application properties.</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2723'>QPID-2723</a>] - NullPointerException thrown when you pass an address based destination to the setJMSReplyTo() in a Message.</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2724'>QPID-2724</a>] - Docbook generation is fixed on xsl-stylesheets-1.75.2 </li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2727'>QPID-2727</a>] - ./src/qpidd --load-module ./src/.libs/cluster.so --cluster-name blah --known-hosts-url amqpx:blah segfaults</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2728'>QPID-2728</a>] - Windows icon/version additions broke nightly builds</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2734'>QPID-2734</a>] - testAuthenticatedUsername fails on cmake builds</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2735'>QPID-2735</a>] - If no subject is specified and if the exchange type is topic, "#" should be used as the default. </li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2741'>QPID-2741</a>] - DerbyMessageStore is not shut down when told to close</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2742'>QPID-2742</a>] - DerbyMessageStore createExchange() method does not function</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2744'>QPID-2744</a>] - FieldTable throws a NullPointerException in setObjectProperty rather than expected AMQPInvalidClassException</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2749'>QPID-2749</a>] - [Java Broker] Add -XX:+ExplicitGCInvokesConcurrent to qpid-server[.bat]</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2752'>QPID-2752</a>] - Cannot create LVQ's using the JMS client.</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2754'>QPID-2754</a>] - C++ broker crashes due to management object database corruption</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2755'>QPID-2755</a>] - Windows SDK has no README</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2757'>QPID-2757</a>] - Remove double-checked-locking in ThreadPoolFilter</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2758'>QPID-2758</a>] - Remove call to Thread.run() in FirewallPlugin</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2760'>QPID-2760</a>] - Only client 0-10 session sync should throw any exceptions</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2764'>QPID-2764</a>] - WinSdk cpp examples do not compile</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2766'>QPID-2766</a>] - string to double conversion results in questionable precision</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2769'>QPID-2769</a>] - UnexpectedMethodException is serializable but does not implement serialVersionUID</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2774'>QPID-2774</a>] - Incorrect logic when querying for existance of an exchange while parsing an address string.</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2781'>QPID-2781</a>] - QPBRKR process name tag should be declared in qpid-server script, not qpid-run</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2785'>QPID-2785</a>] - QpidTypes.pdb is not installed</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2786'>QPID-2786</a>] - Cannot create a durable subscription using a destination created with an addressing string</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2788'>QPID-2788</a>] - jmx management console can throw ConcurrentModificationException whilst connected to (older) brokers with MBeans actively (un)registering</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2791'>QPID-2791</a>] - QMF: c++ agent publishes all data object updates in a single message.</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2797'>QPID-2797</a>] - Add an extra boolean to 0-10 session to indicate closing</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2798'>QPID-2798</a>] - C++ Messaging Client .NET binding fails to clone managed objects correctly</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2799'>QPID-2799</a>] - Temporary queue names should be more meaningful</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2805'>QPID-2805</a>] - The windows resource version for qmfengine dll is hard coded to an unusable value</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2806'>QPID-2806</a>] - QMF: python console will incorrectly delete agents if the session is configured with rcvHeartbeats=False</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2810'>QPID-2810</a>] - QMF: python console does not properly shutdown broker thread in some error cases.</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2817'>QPID-2817</a>] - Connection::close() may hang if broker is suspended</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2828'>QPID-2828</a>] - jmx management console can NPE when adding a queue to the navigation tree after its MBean has just been unregistered but before the view is refreshed</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2842'>QPID-2842</a>] - references to other objects in qpid-tool use id that doesn't match anything else</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2844'>QPID-2844</a>] - JMS client should use the exchange given in the address if the exchange name is not explicitly given in x-bindings </li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2845'>QPID-2845</a>] - JMS client should allow arbitary arguments map in the x-bindings section</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2846'>QPID-2846</a>] - QMF: python console crashes on race condition when deleting an agent.</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2851'>QPID-2851</a>] - Programming with Apache Qpid doc confusing over confirmations</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2854'>QPID-2854</a>] - [Java Broker] 0-10 Queue Exclusive behaviour not correctly implemented</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2855'>QPID-2855</a>] - [Java Broker] 0-10 Transport should not block on awaiting for close confirmation from client</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2856'>QPID-2856</a>] - [Java Broker] Should send 530 not-allowed exception onattempt to delete a defautl exchange (e.g. amq.direct, amq.topic)</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2857'>QPID-2857</a>] - [Java] Running FindBugs against Java codebase reveals room for improvement</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2860'>QPID-2860</a>] - C++ hello_xml example receives all message content, not just what's wanted</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2861'>QPID-2861</a>] - JMS client needs to handle duplicate commands replayed after failover</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2868'>QPID-2868</a>] - throw exception users when attempt is made to move/copy messages to a non-existent queue</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2869'>QPID-2869</a>] - prevent specifying the souce queue as destination when moving/copying messages</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2870'>QPID-2870</a>] - an unauthorised attempt to delete a queue will prevent all further deletion attempts</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2872'>QPID-2872</a>] - Java broker incorrectly indicates it supports sending 0-10 heartbeats when it currently does not</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2875'>QPID-2875</a>] - Federation route propagation tests fail occassionally.</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2876'>QPID-2876</a>] - Design issues in Java client failover</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2877'>QPID-2877</a>] - QPID_JAVA_MEM usage in windows qpid-server.bat fails and prevents startup</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2879'>QPID-2879</a>] - The 0-10 Java Client is sending null arguments on messageSubscribe</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2880'>QPID-2880</a>] - QMF: C++ agent does not accept method calls with map/list arguments that contain booleans</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2883'>QPID-2883</a>] - QMF: python console does not pass V2-style events to the console callback</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2885'>QPID-2885</a>] - C++ qmf console shows memory leaks under valgrind.</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2886'>QPID-2886</a>] - Address the issues outlined by findbugs on 0.5.x-dev branch</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2888'>QPID-2888</a>] - QMF: C++ agent does not re-publish all management data on reconnect to the broker.</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2892'>QPID-2892</a>] - IBM JVM throws different exception when signal handler fails, stopping broker execution</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2896'>QPID-2896</a>] - Incorrect detection of data types in address parameters - C++ client</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2898'>QPID-2898</a>] - broker is unable to evaulate "JMSMessageID IS NULL" correctly when using 0-10</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2910'>QPID-2910</a>] - Small fix for python timeout tests</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2914'>QPID-2914</a>] - address parser doesn't recognize None</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2915'>QPID-2915</a>] - Qpid Cpp Messaging .NET Binding does not properly handle Qpid type VAR_VOID</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2916'>QPID-2916</a>] - C++ broker &amp; Python client will silently truncate strings whose length is greater than the max length supported by the type.</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2918'>QPID-2918</a>] - Assembly mis-named in csharp.example.declare_queues</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2919'>QPID-2919</a>] - hello_world, hello_xml examples left out of CMakeLists.txt</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2922'>QPID-2922</a>] - Qpid Cpp Messaging .NET Binding does not implement FailoverUpdate class</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2923'>QPID-2923</a>] - Qpid Messaging .NET Binding fails to translate exceptions from C++ to .NET</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2925'>QPID-2925</a>] - MSSQL-based message store throws uncaught exception if db recovery throws an error</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2926'>QPID-2926</a>] - Simple example code does not link under Windows</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2927'>QPID-2927</a>] - JMX Shutdown plugin throws InstanceNotFoundException during broker shutdown</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2928'>QPID-2928</a>] - Java client always create exclusive lock for the queue when use with the new addressing scheme</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2929'>QPID-2929</a>] - the broker-plugins jars are not incorporated into the broker release binary when using 'ant release-bin'</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2931'>QPID-2931</a>] - nulling the MessageReference handle on the Message during QueueEntry disposal can result in NPE</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2940'>QPID-2940</a>] - message-accept records are not cleaned up unless getUnsettledAcks() is called</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2941'>QPID-2941</a>] - CLFS store recovery can encounter invalid C++ iterator</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2948'>QPID-2948</a>] - Generated API docs have extraneous macro names in method signatures</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2950'>QPID-2950</a>] - DerbyMessageStore incorrectly logs an error for an expected exception indicating successfull database shutdown</li>
+</ul>
+
+<h4>Improvement</h4>
+<ul>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-1308'>QPID-1308</a>] - JMS Temprory Queue naming</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-1447'>QPID-1447</a>] - Broker does not handle with slow consumers effectively</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-1825'>QPID-1825</a>] - Improve TimeToLiveTest.testActive to prevent spurious failures</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-1831'>QPID-1831</a>] - Improve JMS Destination abstraction to better support AMQP and Qpid specific features</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2213'>QPID-2213</a>] - qpid/framing/BodyHolder.* still needed?</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2251'>QPID-2251</a>] - Provide portable signal mechanism for the C++ QMF agent API</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2283'>QPID-2283</a>] - java Testkit scripts should have sensible defaults when setting up the environment</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2313'>QPID-2313</a>] - Release notes for the WCF/C++ client </li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2322'>QPID-2322</a>] - remove redundant "version" key property from the ObjectName of the JMX MBeans</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2327'>QPID-2327</a>] - Enhance qpid-config to deal with xml and headers brokers</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2348'>QPID-2348</a>] - [C++] The HeadersExchange does not support federation</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2351'>QPID-2351</a>] - Allow the following config properties to be set in the ConnectionURL</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2371'>QPID-2371</a>] - Missing includes for MSVC 2005 compiler</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2380'>QPID-2380</a>] - define and implement reliability options for senders and receivers</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2415'>QPID-2415</a>] - Update doc for new SSL support in Windows broker and client</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2421'>QPID-2421</a>] - Augment performance tests to allow pre-filling broker, fill and consume only runs.</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2423'>QPID-2423</a>] - Add Constructors to set initial value of content for MapContent and ListContent</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2424'>QPID-2424</a>] - Augment CPU/GC processing scripts to provide additional stats.</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2425'>QPID-2425</a>] - Augment TKTestRunner to provide latency data for throughput tests.</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2446'>QPID-2446</a>] - JMS Client should allow a trust/key store per connection rather than one per JVM</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2447'>QPID-2447</a>] - JMS Client should allow multiple connections, each with it's own SSL certificate from the same JVM</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2466'>QPID-2466</a>] - Replace WeakReference use with SoftReference for enhanced message caching</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2477'>QPID-2477</a>] - std::cout in agent not used anymore</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2479'>QPID-2479</a>] - Log in debug aevery time the housekeeping thread runs</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2483'>QPID-2483</a>] - Can't build samples from Windows installer</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2489'>QPID-2489</a>] - Remove references to boost:: and qpid::framing:: from QMF-generated cpp files</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2492'>QPID-2492</a>] - Changes to brokertest.py to better manage Windows brokers</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2496'>QPID-2496</a>] - The following changes needs to be done for JMS Client to support the changes made in addressing</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2501'>QPID-2501</a>] - WCF Binding Configuration parameters</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2508'>QPID-2508</a>] - Replace org.apache.qpid.util.concurrent.Condition with a CountDownLatch</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2512'>QPID-2512</a>] - Change Default Destination Syntax to ADDR (addressing)</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2513'>QPID-2513</a>] - Expose the ServerConfiguration as an OSGI service for use in plugins</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2516'>QPID-2516</a>] - New sample to show how to specify WCF bindings in config files</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2522'>QPID-2522</a>] - Remove the dependency on Commons Lang for the Java client</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2525'>QPID-2525</a>] - Update QueueInformation</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2529'>QPID-2529</a>] - Update the Felix OSGI framework to a recent release</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2530'>QPID-2530</a>] - Refactor the broker-plugins directory setup to allow adding new modules </li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2533'>QPID-2533</a>] - Modify config.xml to have ${QPID_HOME}/lib/plugins as the standard OSGI plugin directory</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2534'>QPID-2534</a>] - Add org.apache.qpid.protocol and org.apache.junit.extensions.util to the packages exported by the PluginManager </li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2547'>QPID-2547</a>] - Improve PluginTest.java in order to test new OSGI plugins</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2557'>QPID-2557</a>] - Hello World example</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2569'>QPID-2569</a>] - Implement the SimpleXML as an OSGI plugin</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2573'>QPID-2573</a>] - Implement the Firewall functionality as an OSGI plugin</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2575'>QPID-2575</a>] - Create a Connection and Session model to abstract protocol versions</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2579'>QPID-2579</a>] - InternalBrokerBaseCase can fail to test tearDown</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2580'>QPID-2580</a>] - Update build path to allow plugins to use systests</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2582'>QPID-2582</a>] - Update QTC to print stack traces from AppRegistry during InVM startup</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2585'>QPID-2585</a>] - Upgrade Felix to 2.0.5</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2590'>QPID-2590</a>] - Update install notes for transactions</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2594'>QPID-2594</a>] - Exception chaining for JMSExceptions</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2595'>QPID-2595</a>] - WCF programming guide documentation</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2599'>QPID-2599</a>] - Allow Qpid users to configure the Java client logging using an sl4j binding of their choice, instead of Qpid shipping a defualt binding.</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2618'>QPID-2618</a>] - Add org.apache.common to the PluginManager exported packages</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2619'>QPID-2619</a>] - Capture the PID for the qpid broker on unix platforms</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2628'>QPID-2628</a>] - c++ messaging API dotnet binding needs received message callback</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2629'>QPID-2629</a>] - Remove Java client dependency on commons-collection.jar</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2651'>QPID-2651</a>] - replace the deprecated Derby 10.3.2.1 (data corruption bug) with a newer version</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2663'>QPID-2663</a>] - QMF: Improvement the behavior of the python console implementation based on scale testing. </li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2667'>QPID-2667</a>] - Cpp INSTALL-WINDOWS build instructions are out of date</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2669'>QPID-2669</a>] - Base64MD5PasswordFilePrincipalDatabase - code improvement</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2671'>QPID-2671</a>] - Doc Book Programming-In-Apache-Qpid needs update for Messaging .NET binding</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2678'>QPID-2678</a>] - Qpid Shutdown OSGI plugin</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2689'>QPID-2689</a>] - Cpp build on Windows does not produce debug symbol PDB file</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2710'>QPID-2710</a>] - C++ Messaging Client .NET binding is not compiled in SDK</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2711'>QPID-2711</a>] - Add version and icon resources to Windows C++ exe/dll files</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2717'>QPID-2717</a>] - Update the bnd tool to version 0.0.384</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2731'>QPID-2731</a>] - enable getting/setting queue exclusivity property via the JMX management interface</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2736'>QPID-2736</a>] - Allow session.createQueue and session.createTopic methods to accept an address string</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2737'>QPID-2737</a>] - Add support in the JMS client for x-subscribe props defined in the new addressing format</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2738'>QPID-2738</a>] - Add support in the JMS client for "mode" option defined in the new addressing format</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2761'>QPID-2761</a>] - Add tests 4 and 5 to the .NET client (0.8)</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2765'>QPID-2765</a>] - WinSdk does not .NET Binding examples</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2771'>QPID-2771</a>] - Use plugins rather than plugin in package naming</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2772'>QPID-2772</a>] - Add fully qualified path to Regex class on default.build</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2775'>QPID-2775</a>] - use JMX to reload the security configuration for FirewallConfigTest</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2780'>QPID-2780</a>] - Improve the operational logging for 0-10 code path</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2782'>QPID-2782</a>] - QMF: improve the console api for selective filtering of unsolicited V2 indications.</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2783'>QPID-2783</a>] - Eliminate the UnknownMessageTypeException from o.a.q.server.protocol package</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2801'>QPID-2801</a>] - Implement LogSubject Interface in 0-10 Subscription/ServerConnection/ServerSession Objects</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2802'>QPID-2802</a>] - Implement selective operational logging via log4j.xml configuration</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2803'>QPID-2803</a>] - Abbreviate the log messages and optimize the log string operations for speed and size</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2809'>QPID-2809</a>] - Once an AMQDestination object resolves an address, it should not try to resolve it again when used in subsequent operations. </li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2820'>QPID-2820</a>] - Remove the ManagedChannel interface from broker code</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2822'>QPID-2822</a>] - Move the documentation from o.a.q.server.logging.messages.*_logmessages.properties into qpid docbook documentation</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2824'>QPID-2824</a>] - Use toLogString rather than toString on LogSubject(s)</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2825'>QPID-2825</a>] - The class o.a.q.transport.Sink is not used and can be safely removed</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2826'>QPID-2826</a>] - The class o.a.q.transport.Result is not used and can be safely removed</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2827'>QPID-2827</a>] - QPID Cpp WinSDK does not contain 64-bit libraries</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2829'>QPID-2829</a>] - The o.a.q.transport.Echo class is not used and can be safely removed</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2831'>QPID-2831</a>] - Use slf4j as the logging mechanism across all code paths</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2832'>QPID-2832</a>] - Collate all the LogSubject formatting strings in a static class</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2833'>QPID-2833</a>] - Add a Generic Actor for 0-10 Logging</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2834'>QPID-2834</a>] - Implement subscriptions (SUB) operational logging on 0-10 </li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2835'>QPID-2835</a>] - Implement connections (CON) operational logging on 0-10</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2837'>QPID-2837</a>] - The o.a.q.server.transport.ThreadPoolFilter class is not used and can be safely removed</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2838'>QPID-2838</a>] - reduce code duplication in logging tests</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2839'>QPID-2839</a>] - Implement Channel (CHN) operational logging on 0-10 protocol </li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2840'>QPID-2840</a>] - Use a configurable message prefix on the AbstractActor class</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2841'>QPID-2841</a>] - QMF: set TTL on agent heartbeat messages</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2843'>QPID-2843</a>] - remove redundant/duplicated logging</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2853'>QPID-2853</a>] - ReadMe for WinSDK is unclear about Visual Studio version support.</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2858'>QPID-2858</a>] - Implement FilterManager for 0-10 subscriptions</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2859'>QPID-2859</a>] - QMF: C++ agent should store its configured name in the config file if available.</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2862'>QPID-2862</a>] - QMF: python console should abort any pending transactions when the broker is deleted.</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2863'>QPID-2863</a>] - Propagate WinSDK Build Version numbers to the Messaging .NET Binding</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2865'>QPID-2865</a>] - Cpp messaging examples compile problems for x64</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2866'>QPID-2866</a>] - Remove unneeded build files and directory</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2884'>QPID-2884</a>] - Add the method arguments to Subscription_0_10 </li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2887'>QPID-2887</a>] - Remove the System.out.println statements from SlowConsumerDetectionConfiguration</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2897'>QPID-2897</a>] - C++ broker: improve scale and speed of route matching algorithm for topic exchanges.</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2906'>QPID-2906</a>] - Qpid WinSDK .NET Binding does not support Release configuration</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2907'>QPID-2907</a>] - Developing Qpid Cpp Messaging .NET Binding requires setup help</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2911'>QPID-2911</a>] - Remove the class printing from the log4j layout as the (%F:%L) provides sufficient debug information</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2913'>QPID-2913</a>] - QPID Cpp Messaging Libraries for WinSDK Are Not Signed</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2924'>QPID-2924</a>] - Refactor WinSDK to create separate debug and release /bin directories</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2942'>QPID-2942</a>] - enable the Java broker convenience binary release package to be run out-of-the-box</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2943'>QPID-2943</a>] - add the examples to the Java client binary convenience release package</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2947'>QPID-2947</a>] - use a newer sl4j-api release to allow the Java client binary convenience package to be used out-of-the-box</li>
+</ul>
+
+<h4>Test</h4>
+<ul>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2359'>QPID-2359</a>] - Need functional tests for the transactional AMQP WCF channel</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2419'>QPID-2419</a>] - DurableSubscriptionTest is not thorough enough</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2510'>QPID-2510</a>] - Python messaging SetupTests.testConnectError false fail on Windows</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2532'>QPID-2532</a>] - stale lock file</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2787'>QPID-2787</a>] - enhance the MessageStoreTest</li>
+</ul>
+
+<h4>Sub-task</h4>
+<ul>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-1811'>QPID-1811</a>] - Unable to compile qpid on FreeBSD</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2284'>QPID-2284</a>] - Add new qpidxarm dll to the Windows installer build</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2539'>QPID-2539</a>] - Update ACL file syntax to be clearer and add extra operations</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2540'>QPID-2540</a>] - Create parser and implementation of C++ style ACL files for Java broker</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2542'>QPID-2542</a>] - Implement ACL checking as OSGi plugin</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2659'>QPID-2659</a>] - Change message stores to throw exceptions with internal error code 541</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2660'>QPID-2660</a>] - FieldTable does not throw AMQFrameDecodingException</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2675'>QPID-2675</a>] - Remove obsolete QpidException</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2679'>QPID-2679</a>] - Cache Queues during bind and remove from cache on queue.close()</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2680'>QPID-2680</a>] - Provide user documentation for configuring SCD</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2681'>QPID-2681</a>] - Process topic configuration section</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2682'>QPID-2682</a>] - Move SCD Plugin to part of the Core Broker</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2715'>QPID-2715</a>] - Document new SecurityPlugin design and implementation</li>
+</ul>
+
+<h4>Task</h4>
+<ul>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2315'>QPID-2315</a>] - remove unused client package jar dependencies</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2417'>QPID-2417</a>] - Enhance topic test coverage</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2527'>QPID-2527</a>] - Remove Thread::id() dependency</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2709'>QPID-2709</a>] - Replace the remaining references to the incubator</li>
+<li>[<a href='https://issues.apache.org/jira/browse/QPID-2946'>QPID-2946</a>] - remove QMan binary convenience package from the 0.8 release</li>
+</ul>
+
+</div>
diff --git a/qpid/doc/website/content/source_repository.html b/qpid/doc/website/content/source_repository.html
new file mode 100644
index 0000000000..147669991e
--- /dev/null
+++ b/qpid/doc/website/content/source_repository.html
@@ -0,0 +1,74 @@
+<!--
+ -
+ - Licensed to the Apache Software Foundation (ASF) under one
+ - or more contributor license agreements. See the NOTICE file
+ - distributed with this work for additional information
+ - regarding copyright ownership. The ASF licenses this file
+ - to you under the Apache License, Version 2.0 (the
+ - "License"); you may not use this file except in compliance
+ - with the License. You may obtain a copy of the License at
+ -
+ - http://www.apache.org/licenses/LICENSE-2.0
+ -
+ - Unless required by applicable law or agreed to in writing,
+ - software distributed under the License is distributed on an
+ - "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ - KIND, either express or implied. See the License for the
+ - specific language governing permissions and limitations
+ - under the License.
+ -
+-->
+<div class="main_text_area_body">
+ <h1>Source Code Repositories</h1>
+ <h2>Web Browsing of SVN</h2>
+
+ <p>To browse via the web use the ViewVC interface:</p>
+
+ <p><a href="http://svn.apache.org/viewvc/qpid/trunk/qpid">http://svn.apache.org/viewvc/qpid/trunk/qpid</a></p>
+
+ <p>Or to browse the source tree directly:</p>
+
+ <p><a href="https://svn.apache.org/repos/asf/qpid/trunk/qpid">https://svn.apache.org/repos/asf/qpid/trunk/qpid</a></p>
+
+ <h2>Checking out from SVN</h2>
+
+ <p>The source code can be checked out anonymous over HTTP:</p>
+
+ <pre>
+svn co http://svn.apache.org/repos/asf/qpid/trunk
+ </pre>
+
+
+ <p>Committers can check out the code using HTTPS:</p>
+
+ <pre>
+svn co https://svn.apache.org/repos/asf/qpid/trunk
+ </pre>
+
+ <h2>Read only GIT repo</h2>
+
+ <p>A read only GIT repo is available:</p>
+
+ <p>It can be cloned with</p>
+ <pre>
+git clone git://git.apache.org/qpid.git qpid
+ </pre>
+
+ <p>or</p>
+
+<pre>
+git clone http://git.apache.org/qpid.git qpid
+</pre>
+
+ <p>and then git pull will fetch updates.</p>
+
+ <p>If you have commit access it is also possible to commit back with git svn dcommit by following the instructions on the <a href="http://wiki.apache.org/general/GitAtApache">GitAtApache</a> page.</p>
+
+ <h2>Setting up your subversion client</h2>
+
+ <p>When adding files to subversion, it's important that your subversion client is properly setup to the appropriate subversion properties are set. The client can do it automatically by modifying the auto-props section of the subversion config file. Use the contents of:</p>
+
+<pre>
+http://svn.apache.org/repos/asf/qpid/trunk/etc/svn-auto-props
+</pre>
+</div>
diff --git a/qpid/doc/website/example/images/asf-logo.png b/qpid/doc/website/example/images/asf-logo.png
new file mode 100644
index 0000000000..d824fab768
--- /dev/null
+++ b/qpid/doc/website/example/images/asf-logo.png
Binary files differ
diff --git a/qpid/doc/website/example/images/asf_logo.gif b/qpid/doc/website/example/images/asf_logo.gif
new file mode 100644
index 0000000000..22eb9d7358
--- /dev/null
+++ b/qpid/doc/website/example/images/asf_logo.gif
Binary files differ
diff --git a/qpid/doc/website/example/images/header.png b/qpid/doc/website/example/images/header.png
new file mode 100644
index 0000000000..9cd149fb29
--- /dev/null
+++ b/qpid/doc/website/example/images/header.png
Binary files differ
diff --git a/qpid/doc/website/example/images/main_body.png b/qpid/doc/website/example/images/main_body.png
new file mode 100644
index 0000000000..a29bdeecd6
--- /dev/null
+++ b/qpid/doc/website/example/images/main_body.png
Binary files differ
diff --git a/qpid/doc/website/example/images/main_bottom.png b/qpid/doc/website/example/images/main_bottom.png
new file mode 100644
index 0000000000..319288a717
--- /dev/null
+++ b/qpid/doc/website/example/images/main_bottom.png
Binary files differ
diff --git a/qpid/doc/website/example/images/main_top.png b/qpid/doc/website/example/images/main_top.png
new file mode 100644
index 0000000000..ffefe05a8d
--- /dev/null
+++ b/qpid/doc/website/example/images/main_top.png
Binary files differ
diff --git a/qpid/doc/website/example/images/menu_body.png b/qpid/doc/website/example/images/menu_body.png
new file mode 100644
index 0000000000..39b2e22205
--- /dev/null
+++ b/qpid/doc/website/example/images/menu_body.png
Binary files differ
diff --git a/qpid/doc/website/example/images/menu_bottom.png b/qpid/doc/website/example/images/menu_bottom.png
new file mode 100644
index 0000000000..21bd16aeba
--- /dev/null
+++ b/qpid/doc/website/example/images/menu_bottom.png
Binary files differ
diff --git a/qpid/doc/website/example/images/menu_top.png b/qpid/doc/website/example/images/menu_top.png
new file mode 100644
index 0000000000..dea7164ef0
--- /dev/null
+++ b/qpid/doc/website/example/images/menu_top.png
Binary files differ
diff --git a/qpid/doc/website/example/images/qpid-logo-900x480.png b/qpid/doc/website/example/images/qpid-logo-900x480.png
new file mode 100644
index 0000000000..3e12816142
--- /dev/null
+++ b/qpid/doc/website/example/images/qpid-logo-900x480.png
Binary files differ
diff --git a/qpid/doc/website/example/images/qpid-logo.png b/qpid/doc/website/example/images/qpid-logo.png
new file mode 100644
index 0000000000..f6d4bfdbad
--- /dev/null
+++ b/qpid/doc/website/example/images/qpid-logo.png
Binary files differ
diff --git a/qpid/doc/website/example/index.html b/qpid/doc/website/example/index.html
new file mode 100644
index 0000000000..308ac94765
--- /dev/null
+++ b/qpid/doc/website/example/index.html
@@ -0,0 +1,185 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<!--
+ -
+ - Licensed to the Apache Software Foundation (ASF) under one
+ - or more contributor license agreements. See the NOTICE file
+ - distributed with this work for additional information
+ - regarding copyright ownership. The ASF licenses this file
+ - to you under the Apache License, Version 2.0 (the
+ - "License"); you may not use this file except in compliance
+ - with the License. You may obtain a copy of the License at
+ -
+ - http://www.apache.org/licenses/LICENSE-2.0
+ -
+ - Unless required by applicable law or agreed to in writing,
+ - software distributed under the License is distributed on an
+ - "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ - KIND, either express or implied. See the License for the
+ - specific language governing permissions and limitations
+ - under the License.
+ -
+-->
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+ <title>Apache Qpid: Open Source AMQP Messaging</title>
+ <link href="style.css" rel="stylesheet" type="text/css"/>
+ </head>
+
+ <body>
+ <div id="container">
+ <div id="header">
+ <div id="logo">
+ <h1>Apache Qpid</h1>
+ <h2>Open Source AMQP Messaging</h2>
+ </div>
+ </div> <!-- end of header -->
+
+ <div id="menu_box">
+ <div id="menu_box_top"></div>
+ <div id="menu_box_body">
+ <h3>Apache Qpid</h3>
+ <ul>
+ <li><a href="#">Home</a></li>
+ <li><a href="#">Download</a></li>
+ <li><a href="#">Getting Started</a></li>
+ <li><a href="#">Roadmap</a></li>
+ <li><a href="#">License</a></li>
+ <li><a href="#">FAQ</a></li>
+ </ul>
+ </div> <!-- end of menu_box_body -->
+ <div id="menu_box_bottom"></div>
+
+ <div id="menu_box_top"></div>
+ <div id="menu_box_body">
+ <h3>Documentation</h3>
+ <ul>
+ <li><a href="#">Version 0.6</a></li>
+ <li><a href="#">Version 0.5</a></li>
+ <li><a href="#">Archive</a></li>
+ </ul>
+ </div> <!-- end of menu_box_body -->
+ <div id="menu_box_bottom"></div>
+
+ <div id="menu_box_top"></div>
+ <div id="menu_box_body">
+ <h3>Community</h3>
+ <ul>
+ <li><a href="#">Getting Involved</a></li>
+ <li><a href="#">Source Repository</a></li>
+ <li><a href="#">Mailing Lists</a></li>
+ <li><a href="#">Wiki</a></li>
+ <li><a href="#">Issue Reporting</a></li>
+ <li><a href="#">People</a></li>
+ <li><a href="#">Project Status</a></li>
+ <li><a href="#">Acknowledgements</a></li>
+ </ul>
+ </div> <!-- end of menu_box_body -->
+ <div id="menu_box_bottom"></div>
+
+ <div id="menu_box_top"></div>
+ <div id="menu_box_body">
+ <h3>Developers</h3>
+ <ul>
+ <li><a href="#">Building Qpid</a></li>
+ <li><a href="#">Developer Pages</a></li>
+ </ul>
+ </div> <!-- end of menu_box_body -->
+ <div id="menu_box_bottom"></div>
+
+ <div id="menu_box_top"></div>
+ <div id="menu_box_body">
+ <h3>About AMQP</h3>
+ <ul>
+ <li><a href="#">What is AMQP?</a></li>
+ <li><a href="#">Specification</a></li>
+ </ul>
+ </div> <!-- end of menu_box_body -->
+ <div id="menu_box_bottom"></div>
+
+ </div> <!-- end of menu_box -->
+
+ <div id="main_text_area">
+ <div id="main_text_area_top"></div>
+
+<div id="main_text_area_body" xmlns="http://www.w3.org/1999/xhtml">
+ <h1>Introduction</h1>
+ <p>Enterprise Messaging systems let programs communicate by
+ exchanging messages, much as people communicate by
+ exchanging email. Unlike email, enterprise messaging systems
+ provide guaranteed delivery, speed, security, and freedom
+ from spam. Until recently, there was no open standard for
+ Enterprise Messaging systems, so programmers either wrote
+ their own, or used expensive proprietary systems.</p>
+
+ <p>AMQP <a href="http://www.amqp.org/">Advanced Message
+ Queuing Protocol</a> is the first open standard for
+ Enterprise Messaging. It is designed to support messaging
+ for just about any distributed or business
+ application. Routing can be configured flexibly, easily
+ supporting common messaging paradigms like point-to-point,
+ fanout, publish-subscribe, and request-response.</p>
+
+ <p>Apache Qpid implements the latest AMQP specification, providing
+ transaction management, queuing, distribution, security,
+ management, clustering, federation and heterogeneous
+ multi-platform support and a lot more. And Apache Qpid is
+ extremely fast. Apache Qpid <a href="amqp-compatibility.html"
+ title="AMQP compatibility">aims to be 100% AMQP Compliant</a>.</p>
+
+ <div id="feature_box">
+ <div id="feature_box_column1">
+ <h3>AMQP Brokers</h3>
+ <ul>
+ <li><a href="#">Java Broker</a>
+ <ul>
+ <li><a href="#">Feature Guide</a></li>
+ </ul>
+ </li>
+ <li><a href="#">C++ Broker (Linux/Windows)</a>
+ <ul>
+ <li><a href="#">Feature Guide</a></li>
+ </ul>
+ </li>
+ </ul>
+ <br/>
+ <br/>
+ </div> <!-- end of feature_box_column -->
+
+ <div id="feature_box_column2">
+ <h3>AMQP Client APIs</h3>
+ <ul>
+ <li><a href="#">Java (JMS 1.1 compliant)</a></li>
+ <li><a href="#">C++ (Linux/Windows)</a></li>
+ <li><a href="#">C# .NET</a></li>
+ <li><a href="#">WCF Adapter (Windows Only)</a></li>
+ <li><a href="#">Python</a></li>
+ <li><a href="#">Ruby</a></li>
+ </ul>
+ </div> <!-- end of feature_box_column -->
+
+ <div id="feature_box_column3">
+ <h3>Qpid Management</h3>
+ <ul>
+ <li><a href="#">QMF Python API</a></li>
+ <li><a href="#">QMF C++ API</a> </li>
+ <li><a href="#">Python tools</a></li>
+ <li><a href="#">QMan (QMF&lt;=>JMX)</a></li>
+ </ul>
+ </div> <!-- end of feature_box_column -->
+
+ </div> <!-- end of feature_box -->
+
+</div> <!-- end of main_text_area_body -->
+
+
+ <div id="main_text_area_bottom"></div>
+ </div> <!-- end of main_text_area -->
+
+ <div id="footer">
+ Apache Qpid, Enterprise AMQP Messaging &#xA9; 2004-2010 The Apache Software Foundation.
+ </div>
+
+ </div>
+ </body>
+</html>
diff --git a/qpid/doc/website/example/style.css b/qpid/doc/website/example/style.css
new file mode 100644
index 0000000000..1e05052a03
--- /dev/null
+++ b/qpid/doc/website/example/style.css
@@ -0,0 +1,263 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+ul {
+ list-style-type:square;
+}
+
+th {
+ text-align: left;
+ font-weight: bold;
+}
+
+
+#body {
+ margin:0;
+ background:#FFFFFF;
+ font-family:"Verdana", sans-serif;
+}
+
+#container {
+ width:950px;
+ margin:0 auto;
+}
+
+#header {
+ height:100px;
+ width:950px;
+ background:url(images/header.png)
+}
+
+#logo {
+ text-align:center;
+ font-weight:600;
+ padding:0 0 0 0;
+ font-size:14px;
+ font-family:"Verdana", cursive;
+}
+
+#logo a {
+ color:#000000;
+ text-decoration:none;
+}
+
+#main_text_area {
+ margin-left:200px;
+}
+
+#main_text_area_top {
+ height:14px;
+ font-size:1px;
+}
+
+#main_text_area_bottom {
+ height:14px;
+ font-size:1px;
+ margin-bottom:4px;
+}
+
+#main_text_area_body {
+ padding:5px 24px;
+}
+
+#main_text_area_body p {
+ text-align:justify;
+}
+
+#main_text_area br {
+ line-height:10px;
+}
+
+#main_text_area h1 {
+ font-size:28px;
+ font-weight:600;
+ margin:0 0 24px 0;
+ color:#0c3b82;
+ font-family:"Verdana", Times, serif;
+}
+
+#main_text_area h2 {
+ font-size:24px;
+ font-weight:600;
+ margin:24px 0 8px 0;
+ color:#0c3b82;
+ font-family:"Verdana",Times, serif;
+}
+
+#main_text_area ol, #main_text_area ul {
+ padding:0;
+ margin:10px 0;
+ margin-left:20px;
+}
+
+#main_text_area li {
+/* margin-left:40px; */
+}
+
+#main_text_area, #menu_box {
+ font-size:13px;
+ line-height:17px;
+ color:#000000;
+}
+
+#main_text_area {
+ font-size:15px;
+}
+
+#main_text_area a {
+ color:#000000;
+}
+
+#main_text_area a:hover {
+ color:#000000;
+}
+
+#menu_box {
+ width:196px;
+ float:left;
+ margin-left:4px;
+}
+
+#menu_box_top {
+ background:url(images/menu_top.png) no-repeat;
+ height:14px;
+ font-size:1px;
+}
+
+#menu_box_body {
+ background:url(images/menu_body.png) repeat-y;
+ padding:5px 24px 5px 24px;
+}
+
+#menu_box_bottom {
+ background:url(images/menu_bottom.png) no-repeat;
+ height:14px;
+ font-size:1px;
+ margin-bottom:1px;
+}
+
+#menu_box h3 {
+ font-size:20px;
+ font-weight:500;
+ margin:0 0 8px 0;
+ color:#0c3b82;
+ font-family:"Verdana",Times, serif;
+}
+
+#menu_box ul {
+ margin:12px;
+ padding:0px;
+}
+
+#menu_box li {
+ list-style:square;
+}
+
+#menu_box a {
+ color:#000000;
+ text-decoration:none;
+}
+
+#menu_box a:hover {
+ color:#000000;
+ text-decoration:underline;
+}
+
+#feature_box {
+ width:698px;
+ overflow:hidden;
+}
+
+#feature_box h3 {
+ font-size:18px;
+ font-weight:600;
+ margin:0 0 8px 0;
+ color:#0c3b82;
+ font-family:"Verdana", Times, serif;
+}
+
+#feature_box_column1 {
+ width:196px;
+ float:left;
+ padding:10px 15px 10px 15px;
+ margin-left:0px;
+}
+
+#feature_box_column2 {
+ width:196px;
+ float:left;
+ padding:10px 15px 10px 15px;
+ margin-left:0px;
+}
+
+#feature_box_column3 {
+ width:196px;
+ float:left;
+ padding:10px 15px 10px 15px;
+ margin-left:0px;
+}
+
+#feature_box ul {
+ margin:.8em .4em;
+ padding-left:1.2em;
+ padding:0;
+ list-style-type: square;
+}
+
+#feature_box ul li {
+ font-family:"Verdana",sans-serif;
+ font-size:14px;
+ color:#000;
+ margin:.4em 0;
+}
+
+#feature_box ul li ul {
+ padding-left:1.2em;
+ margin-left:2em;
+}
+
+#feature_box a {
+ color:#000000;
+ text-decoration:none;
+}
+
+#feature_box a:hover {
+ color:#000000;
+ text-decoration:underline;
+}
+
+#footer {
+ color:#000000;
+ clear:both;
+ text-align:center;
+ font-size:11px;
+ line-height:17px;
+ height:45px;
+ padding-top:18px;
+}
+
+#footer a {
+ color:#000000;
+}
+
+#footer a:hover {
+ color:#000000;
+}
+
diff --git a/qpid/doc/website/template/images/asf-logo.png b/qpid/doc/website/template/images/asf-logo.png
new file mode 100644
index 0000000000..d824fab768
--- /dev/null
+++ b/qpid/doc/website/template/images/asf-logo.png
Binary files differ
diff --git a/qpid/doc/website/template/images/asf_logo.gif b/qpid/doc/website/template/images/asf_logo.gif
new file mode 100644
index 0000000000..22eb9d7358
--- /dev/null
+++ b/qpid/doc/website/template/images/asf_logo.gif
Binary files differ
diff --git a/qpid/doc/website/template/images/header.png b/qpid/doc/website/template/images/header.png
new file mode 100644
index 0000000000..66e35d7e37
--- /dev/null
+++ b/qpid/doc/website/template/images/header.png
Binary files differ
diff --git a/qpid/doc/website/template/images/main_body.png b/qpid/doc/website/template/images/main_body.png
new file mode 100644
index 0000000000..a29bdeecd6
--- /dev/null
+++ b/qpid/doc/website/template/images/main_body.png
Binary files differ
diff --git a/qpid/doc/website/template/images/main_bottom.png b/qpid/doc/website/template/images/main_bottom.png
new file mode 100644
index 0000000000..319288a717
--- /dev/null
+++ b/qpid/doc/website/template/images/main_bottom.png
Binary files differ
diff --git a/qpid/doc/website/template/images/main_top.png b/qpid/doc/website/template/images/main_top.png
new file mode 100644
index 0000000000..ffefe05a8d
--- /dev/null
+++ b/qpid/doc/website/template/images/main_top.png
Binary files differ
diff --git a/qpid/doc/website/template/images/menu_body.png b/qpid/doc/website/template/images/menu_body.png
new file mode 100644
index 0000000000..39b2e22205
--- /dev/null
+++ b/qpid/doc/website/template/images/menu_body.png
Binary files differ
diff --git a/qpid/doc/website/template/images/menu_bottom.png b/qpid/doc/website/template/images/menu_bottom.png
new file mode 100644
index 0000000000..21bd16aeba
--- /dev/null
+++ b/qpid/doc/website/template/images/menu_bottom.png
Binary files differ
diff --git a/qpid/doc/website/template/images/menu_top.png b/qpid/doc/website/template/images/menu_top.png
new file mode 100644
index 0000000000..dea7164ef0
--- /dev/null
+++ b/qpid/doc/website/template/images/menu_top.png
Binary files differ
diff --git a/qpid/doc/website/template/images/qpid-logo-900x480.png b/qpid/doc/website/template/images/qpid-logo-900x480.png
new file mode 100644
index 0000000000..3e12816142
--- /dev/null
+++ b/qpid/doc/website/template/images/qpid-logo-900x480.png
Binary files differ
diff --git a/qpid/doc/website/template/images/qpid-logo.png b/qpid/doc/website/template/images/qpid-logo.png
new file mode 100644
index 0000000000..95d49ea469
--- /dev/null
+++ b/qpid/doc/website/template/images/qpid-logo.png
Binary files differ
diff --git a/qpid/doc/website/template/style.css b/qpid/doc/website/template/style.css
new file mode 100644
index 0000000000..57dc571425
--- /dev/null
+++ b/qpid/doc/website/template/style.css
@@ -0,0 +1,276 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+ul {
+ list-style-type:square;
+}
+
+th {
+ text-align: left;
+ font-weight: bold;
+}
+
+body {
+ margin:0;
+ background:#FFFFFF;
+ font-family:"Verdana", sans-serif;
+}
+
+.container {
+ width:950px;
+ margin:0 auto;
+}
+
+.header {
+ height:100px;
+ width:950px;
+ background:url(images/header.png)
+}
+
+.logo {
+ text-align:center;
+ font-weight:600;
+ padding:0 0 0 0;
+ font-size:14px;
+ font-family:"Verdana", cursive;
+}
+
+.logo a {
+ color:#000000;
+ text-decoration:none;
+}
+
+.main_text_area {
+ margin-left:200px;
+}
+
+.main_text_area_top {
+ height:14px;
+ font-size:1px;
+}
+
+.main_text_area_bottom {
+ height:14px;
+ font-size:1px;
+ margin-bottom:4px;
+}
+
+.main_text_area_body {
+ padding:5px 24px;
+}
+
+.main_text_area_body p {
+ text-align:justify;
+}
+
+.main_text_area br {
+ line-height:10px;
+}
+
+.main_text_area h1 {
+ font-size:28px;
+ font-weight:600;
+ margin:0 0 24px 0;
+ color:#0c3b82;
+ font-family:"Verdana", Times, serif;
+}
+
+.main_text_area h2 {
+ font-size:24px;
+ font-weight:600;
+ margin:24px 0 8px 0;
+ color:#0c3b82;
+ font-family:"Verdana",Times, serif;
+}
+
+.main_text_area ol, .main_text_area ul {
+ padding:0;
+ margin:10px 0;
+ margin-left:20px;
+}
+
+.main_text_area li {
+/* margin-left:40px; */
+}
+
+.main_text_area, .menu_box {
+ font-size:13px;
+ line-height:17px;
+ color:#000000;
+}
+
+.main_text_area {
+ font-size:15px;
+}
+
+.main_text_area a {
+ color:#000000;
+}
+
+.main_text_area a:hover {
+ color:#000000;
+}
+
+.menu_box {
+ width:196px;
+ float:left;
+ margin-left:4px;
+}
+
+.menu_box_top {
+ background:url(images/menu_top.png) no-repeat;
+ height:14px;
+ font-size:1px;
+}
+
+.menu_box_body {
+ background:url(images/menu_body.png) repeat-y;
+ padding:5px 24px 5px 24px;
+}
+
+.menu_box_bottom {
+ background:url(images/menu_bottom.png) no-repeat;
+ height:14px;
+ font-size:1px;
+ margin-bottom:1px;
+}
+
+.menu_box h3 {
+ font-size:20px;
+ font-weight:500;
+ margin:0 0 8px 0;
+ color:#0c3b82;
+ font-family:"Verdana",Times, serif;
+}
+
+.menu_box ul {
+ margin:12px;
+ padding:0px;
+}
+
+.menu_box li {
+ list-style:square;
+}
+
+.menu_box a {
+ color:#000000;
+ text-decoration:none;
+}
+
+.menu_box a:hover {
+ color:#000000;
+ text-decoration:underline;
+}
+
+.feature_box {
+ width:698px;
+ overflow:hidden;
+}
+
+.feature_box h3 {
+ font-size:18px;
+ font-weight:600;
+ margin:0 0 8px 0;
+ color:#0c3b82;
+ font-family:"Verdana", Times, serif;
+}
+
+.feature_box_column1 {
+ width:196px;
+ float:left;
+ padding:10px 15px 10px 15px;
+ margin-left:0px;
+}
+
+.feature_box_column2 {
+ width:196px;
+ float:left;
+ padding:10px 15px 10px 15px;
+ margin-left:0px;
+}
+
+.feature_box_column3 {
+ width:196px;
+ float:left;
+ padding:10px 15px 10px 15px;
+ margin-left:0px;
+}
+
+
+.feature_box ul {
+ margin:.8em .4em;
+ padding-left:1.2em;
+ padding:0;
+ list-style-type: square;
+}
+
+.feature_box ul li {
+ font-family:"Verdana",sans-serif;
+ font-size:14px;
+ color:#000;
+ margin:.4em 0;
+}
+
+.feature_box ul li ul {
+ padding-left:1.2em;
+ margin-left:2em;
+}
+
+.feature_box a {
+ color:#000000;
+ text-decoration:none;
+}
+
+.feature_box a:hover {
+ color:#000000;
+ text-decoration:underline;
+}
+
+.footer {
+ color:#000000;
+ clear:both;
+ text-align:center;
+ font-size:11px;
+ line-height:17px;
+ height:45px;
+ padding-top:18px;
+}
+
+.footer a {
+ color:#000000;
+}
+
+.footer a:hover {
+ color:#000000;
+}
+
+.download_table {
+ width:100%;
+}
+
+.download_table_col_1 {
+ width:240px;
+}
+
+.download_table_amqp_col {
+ text-align:center;
+ width:80px;
+}
+
diff --git a/qpid/doc/website/template/template.html b/qpid/doc/website/template/template.html
new file mode 100644
index 0000000000..2738085e00
--- /dev/null
+++ b/qpid/doc/website/template/template.html
@@ -0,0 +1,126 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<!--
+ -
+ - Licensed to the Apache Software Foundation (ASF) under one
+ - or more contributor license agreements. See the NOTICE file
+ - distributed with this work for additional information
+ - regarding copyright ownership. The ASF licenses this file
+ - to you under the Apache License, Version 2.0 (the
+ - "License"); you may not use this file except in compliance
+ - with the License. You may obtain a copy of the License at
+ -
+ - http://www.apache.org/licenses/LICENSE-2.0
+ -
+ - Unless required by applicable law or agreed to in writing,
+ - software distributed under the License is distributed on an
+ - "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ - KIND, either express or implied. See the License for the
+ - specific language governing permissions and limitations
+ - under the License.
+ -
+-->
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+ <title>Apache Qpid&#8482;: Open Source AMQP Messaging</title>
+ <link href="style.css" rel="stylesheet" type="text/css"/>
+ </head>
+
+ <body>
+ <div class="container">
+ <div class="header">
+ <div class="logo">
+ <h1>Apache Qpid&#8482;</h1>
+ <h2>Open Source AMQP Messaging</h2>
+ </div>
+ </div> <!-- end of header -->
+
+ <div class="menu_box">
+ <div class="menu_box_top"></div>
+ <div class="menu_box_body">
+ <h3>Apache Qpid</h3>
+ <ul>
+ <li><a href="index.html">Home</a></li>
+ <li><a href="download.cgi">Download</a></li>
+ <li><a href="getting_started.html">Getting Started</a></li>
+ <li><a href="http://www.apache.org/licenses/">License</a></li>
+ <li><a href="https://cwiki.apache.org/qpid/faq.html">FAQ</a></li>
+ </ul>
+ </div> <!-- end of menu_box_body -->
+ <div class="menu_box_bottom"></div>
+
+ <div class="menu_box_top"></div>
+ <div class="menu_box_body">
+ <h3>Documentation</h3>
+ <ul>
+ <li><a href="documentation.html#doc-release">0.8 Release</a></li>
+ <li><a href="documentation.html#doc-trunk">Trunk</a></li>
+ <li><a href="documentation.html#doc-archives">Archive</a></li>
+ </ul>
+ </div> <!-- end of menu_box_body -->
+ <div class="menu_box_bottom"></div>
+
+ <div class="menu_box_top"></div>
+ <div class="menu_box_body">
+ <h3>Community</h3>
+ <ul>
+ <li><a href="getting_involved.html">Getting Involved</a></li>
+ <li><a href="source_repository.html">Source Repository</a></li>
+ <li><a href="mailing_lists.html">Mailing Lists</a></li>
+ <li><a href="https://cwiki.apache.org/qpid/">Wiki</a></li>
+ <li><a href="https://issues.apache.org/jira/browse/qpid">Issue Reporting</a></li>
+ <li><a href="people.html">People</a></li>
+ <li><a href="acknowledgements.html">Acknowledgements</a></li>
+ </ul>
+ </div> <!-- end of menu_box_body -->
+ <div class="menu_box_bottom"></div>
+
+ <div class="menu_box_top"></div>
+ <div class="menu_box_body">
+ <h3>Developers</h3>
+ <ul>
+ <li><a href="https://cwiki.apache.org/qpid/building.html">Building Qpid</a></li>
+ <li><a href="https://cwiki.apache.org/qpid/developer-pages.html">Developer Pages</a></li>
+ </ul>
+ </div> <!-- end of menu_box_body -->
+ <div class="menu_box_bottom"></div>
+
+ <div class="menu_box_top"></div>
+ <div class="menu_box_body">
+ <h3>About AMQP</h3>
+ <ul>
+ <li><a href="amqp.html">What is AMQP?</a></li>
+ </ul>
+ </div> <!-- end of menu_box_body -->
+ <div class="menu_box_bottom"></div>
+
+ <div class="menu_box_top"></div>
+ <div class="menu_box_body">
+ <h3>About Apache</h3>
+ <ul>
+ <li><a href="http://www.apache.org">Home</a></li>
+ <li><a href="http://www.apache.org/foundation/sponsorship.html">Sponsorship</a></li>
+ <li><a href="http://www.apache.org/foundation/thanks.html">Thanks</a></li>
+ <li><a href="http://www.apache.org/security/">Security</a></li>
+ </ul>
+ </div> <!-- end of menu_box_body -->
+ <div class="menu_box_bottom"></div>
+ </div> <!-- end of menu_box -->
+
+ <div class="main_text_area">
+ <div class="main_text_area_top"></div>
+{.}
+ </div>
+
+ <div class="footer">
+ <p>
+ &#xA9; 2004-2010 The Apache Software Foundation.<br />
+ Apache Qpid, Qpid, Apache, the Apache feather logo, and the Apache Qpid project logo are trademarks of The Apache Software Foundation.<br />
+ All other marks mentioned may be trademarks or registered trademarks of their respective owners.
+ </p>
+ </div>
+
+ </div>
+ </body>
+</html>
diff --git a/qpid/doc/website/tools/generate b/qpid/doc/website/tools/generate
new file mode 100755
index 0000000000..a45e803793
--- /dev/null
+++ b/qpid/doc/website/tools/generate
@@ -0,0 +1,56 @@
+#!/usr/bin/env python
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+import os
+import sys
+
+if len(sys.argv) != 4:
+ print "Usage: $ generate template/template.html contentDir outputDir"
+ exit()
+
+else:
+ try:
+ srcDir = os.path.abspath(sys.argv[2])
+ srcFiles = os.listdir(srcDir)
+ targetDir = os.path.abspath(sys.argv[3])
+ template = open(sys.argv[1], "r")
+
+ for srcFile in srcFiles:
+ if os.path.splitext(srcFile)[1] == ".html":
+ content = open(os.path.join(srcDir,srcFile), "r")
+ output = open(os.path.join(targetDir,srcFile),"w")
+
+ template.seek(0)
+
+ for t in template:
+ if t.rstrip() == "{.}":
+ for c in content:
+ output.write( c )
+ else:
+ output.write( t )
+
+ output.close()
+ content.close()
+
+ except:
+ print "Ooops!"
+ exit()
+
+template.close()
diff --git a/qpid/doc/website/tools/wrap b/qpid/doc/website/tools/wrap
new file mode 100755
index 0000000000..d756da7335
--- /dev/null
+++ b/qpid/doc/website/tools/wrap
@@ -0,0 +1,44 @@
+#!/usr/bin/env python
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+import sys
+
+if len(sys.argv) != 4:
+ print "Usage: $ wrap template.html content.html output.html"
+ exit()
+
+try:
+ template = open(sys.argv[1], "r")
+ content = open(sys.argv[2], "r")
+ output = open(sys.argv[3], "w")
+
+ for t in template:
+ if t.rstrip() == "{.}":
+ for c in content:
+ output.write( c )
+ else:
+ output.write( t )
+except:
+ print "Ooops!"
+ exit()
+
+template.close()
+content.close()
+output.close()
diff --git a/qpid/dotnet/LICENSE.txt b/qpid/dotnet/LICENSE.txt
new file mode 100644
index 0000000000..981d2f83c3
--- /dev/null
+++ b/qpid/dotnet/LICENSE.txt
@@ -0,0 +1,757 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+
+=========================================================================
+== Saxon XSLT License ==
+=========================================================================
+
+Mozilla Public License Version 1.0
+
+1. Definitions.
+
+ 1.1. "Contributor" means each entity that creates or contributes
+ to the creation of Modifications.
+
+ 1.2. "Contributor Version" means the combination of the
+ Original Code, prior Modifications used by a Contributor, and the
+ Modifications made by that particular Contributor.
+
+ 1.3. "Covered Code" means the Original Code or Modifications
+ or the combination of the Original Code and Modifications, in each case
+ including portions thereof.
+
+ 1.4. "Electronic Distribution Mechanism" means a mechanism
+ generally accepted in the software development community for the
+ electronic transfer of data.
+
+ 1.5. "Executable" means Covered Code in any form other than
+ Source Code.
+
+ 1.6. "Initial Developer" means the individual or entity
+ identified as the Initial Developer in the Source Code notice required by
+ Exhibit A.
+
+ 1.7. "Larger Work" means a work which combines Covered Code
+ or portions thereof with code not governed by the terms of this License.
+
+ 1.8. "License" means this document.
+
+ 1.9. "Modifications" means any addition to or deletion from
+ the substance or structure of either the Original Code or any previous
+ Modifications. When Covered Code is released as a series of files, a
+ Modification is:
+
+ A. Any addition to or deletion from the contents of a file
+ containing Original Code or previous Modifications.
+
+ B. Any new file that contains any part of the Original
+ Code or previous Modifications.
+
+ 1.10. "Original Code" means Source Code of computer software
+ code which is described in the Source Code notice required by Exhibit
+ A as Original Code, and which, at the time of its release under this
+ License is not already Covered Code governed by this License.
+
+ 1.11. "Source Code" means the preferred form of the Covered
+ Code for making modifications to it, including all modules it contains,
+ plus any associated interface definition files, scripts used to control
+ compilation and installation of an Executable, or a list of source code
+ differential comparisons against either the Original Code or another well
+ known, available Covered Code of the Contributor's choice. The Source
+ Code can be in a compressed or archival form, provided the appropriate
+ decompression or de-archiving software is widely available for no charge.
+
+ 1.12. "You" means an individual or a legal entity exercising
+ rights under, and complying with all of the terms of, this License or a
+ future version of this License issued under Section 6.1. For legal
+ entities, "You" includes any entity which controls, is controlled by,
+ or is under common control with You. For purposes of this definition,
+ "control" means (a) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or otherwise,
+ or (b) ownership of fifty percent (50%) or more of the outstanding shares
+ or beneficial ownership of such entity.
+
+2. Source Code License.
+
+ 2.1. The Initial Developer Grant.
+
+
+ The Initial Developer hereby grants You a world-wide, royalty-free,
+ non-exclusive license, subject to third party intellectual property
+ claims:
+
+ (a) to use, reproduce, modify, display, perform, sublicense
+ and distribute the Original Code (or portions thereof) with or
+ without Modifications, or as part of a Larger Work; and
+
+ (b) under patents now or hereafter owned or controlled by
+ Initial Developer, to make, have made, use and sell ("Utilize") the
+ Original Code (or portions thereof), but solely to the extent that
+ any such patent is reasonably necessary to enable You to Utilize the
+ Original Code (or portions thereof) and not to any greater extent
+ that may be necessary to Utilize further Modifications or
+ combinations.
+
+ 2.2. Contributor Grant.
+
+
+ Each Contributor hereby grants You a world-wide, royalty-free,
+ non-exclusive license, subject to third party intellectual property
+ claims:
+
+ (a) to use, reproduce, modify, display, perform, sublicense and
+ distribute the Modifications created by such Contributor (or portions
+ thereof) either on an unmodified basis, with other Modifications, as
+ Covered Code or as part of a Larger Work; and
+
+ (b) under patents now or hereafter owned or controlled by
+ Contributor, to Utilize the Contributor Version (or portions thereof),
+ but solely to the extent that any such patent is reasonably necessary to
+ enable You to Utilize the Contributor Version (or portions thereof), and
+ not to any greater extent that may be necessary to Utilize further
+ Modifications or combinations.
+
+3. Distribution Obligations.
+
+ 3.1. Application of License.
+
+
+ The Modifications which You create or to which You contribute are
+ governed by the terms of this License, including without limitation
+ Section 2.2. The Source Code version of Covered Code may be
+ distributed only under the terms of this License or a future version of
+ this License released under Section 6.1, and You must include a
+ copy of this License with every copy of the Source Code You
+ distribute. You may not offer or impose any terms on any Source Code
+ version that alters or restricts the applicable version of this License
+ or the recipients' rights hereunder. However, You may include an
+ additional document offering the additional rights described in Section
+ 3.5.
+
+ 3.2. Availability of Source Code.
+
+
+ Any Modification which You create or to which You contribute must be
+ made available in Source Code form under the terms of this License either
+ on the same media as an Executable version or via an accepted Electronic
+ Distribution Mechanism to anyone to whom you made an Executable version
+ available; and if made available via Electronic Distribution Mechanism,
+ must remain available for at least twelve (12) months after the date it
+ initially became available, or at least six (6) months after a subsequent
+ version of that particular Modification has been made available to such
+ recipients. You are responsible for ensuring that the Source Code version
+ remains available even if the Electronic Distribution Mechanism is
+ maintained by a third party.
+
+ 3.3. Description of Modifications.
+
+
+ You must cause all Covered Code to which you contribute to contain a
+ file documenting the changes You made to create that Covered Code and the
+ date of any change. You must include a prominent statement that the
+ Modification is derived, directly or indirectly, from Original Code
+ provided by the Initial Developer and including the name of the Initial
+ Developer in (a) the Source Code, and (b) in any notice in an Executable
+ version or related documentation in which You describe the origin or
+ ownership of the Covered Code.
+
+ 3.4. Intellectual Property Matters
+
+ (a) Third Party Claims.
+
+
+ If You have knowledge that a party claims an intellectual
+ property right in particular functionality or code (or its
+ utilization under this License), you must include a text file with
+ the source code distribution titled "LEGAL" which describes the
+ claim and the party making the claim in sufficient detail that a
+ recipient will know whom to contact. If you obtain such knowledge
+ after You make Your Modification available as described in Section
+ 3.2, You shall promptly modify the LEGAL file in all copies
+ You make available thereafter and shall take other steps (such as
+ notifying appropriate mailing lists or newsgroups) reasonably
+ calculated to inform those who received the Covered Code that new
+ knowledge has been obtained.
+
+ (b) Contributor APIs.
+
+
+ If Your Modification is an application programming interface and
+ You own or control patents which are reasonably necessary to
+ implement that API, you must also include this information in the
+ LEGAL file.
+
+ 3.5. Required Notices.
+
+
+ You must duplicate the notice in Exhibit A in each file of the
+ Source Code, and this License in any documentation for the Source Code,
+ where You describe recipients' rights relating to Covered Code. If You
+ created one or more Modification(s), You may add your name as a
+ Contributor to the notice described in Exhibit A. If it is not
+ possible to put such notice in a particular Source Code file due to its
+ structure, then you must include such notice in a location (such as a
+ relevant directory file) where a user would be likely to look for such a
+ notice. You may choose to offer, and to charge a fee for, warranty,
+ support, indemnity or liability obligations to one or more recipients of
+ Covered Code. However, You may do so only on Your own behalf, and not on
+ behalf of the Initial Developer or any Contributor. You must make it
+ absolutely clear than any such warranty, support, indemnity or liability
+ obligation is offered by You alone, and You hereby agree to indemnify the
+ Initial Developer and every Contributor for any liability incurred by the
+ Initial Developer or such Contributor as a result of warranty, support,
+ indemnity or liability terms You offer.
+
+ 3.6. Distribution of Executable Versions.
+
+
+ You may distribute Covered Code in Executable form only if the
+ requirements of Section 3.1-3.5 have been met for that Covered
+ Code, and if You include a notice stating that the Source Code version of
+ the Covered Code is available under the terms of this License, including
+ a description of how and where You have fulfilled the obligations of
+ Section 3.2. The notice must be conspicuously included in any
+ notice in an Executable version, related documentation or collateral in
+ which You describe recipients' rights relating to the Covered Code. You
+ may distribute the Executable version of Covered Code under a license of
+ Your choice, which may contain terms different from this License,
+ provided that You are in compliance with the terms of this License and
+ that the license for the Executable version does not attempt to limit or
+ alter the recipient's rights in the Source Code version from the rights
+ set forth in this License. If You distribute the Executable version under
+ a different license You must make it absolutely clear that any terms
+ which differ from this License are offered by You alone, not by the
+ Initial Developer or any Contributor. You hereby agree to indemnify the
+ Initial Developer and every Contributor for any liability incurred by the
+ Initial Developer or such Contributor as a result of any such terms You
+ offer.
+
+ 3.7. Larger Works.
+
+
+ You may create a Larger Work by combining Covered Code with other
+ code not governed by the terms of this License and distribute the Larger
+ Work as a single product. In such a case, You must make sure the
+ requirements of this License are fulfilled for the Covered Code.
+
+4. Inability to Comply Due to Statute or Regulation.
+
+ If it is impossible for You to comply with any of the terms of this
+ License with respect to some or all of the Covered Code due to statute or
+ regulation then You must: (a) comply with the terms of this License to
+ the maximum extent possible; and (b) describe the limitations and the
+ code they affect. Such description must be included in the LEGAL file
+ described in Section 3.4 and must be included with all
+ distributions of the Source Code. Except to the extent prohibited by
+ statute or regulation, such description must be sufficiently detailed for
+ a recipient of ordinary skill
+ to be able to understand it.
+
+5. Application of this License.
+
+ This License applies to code to which the Initial Developer has attached
+ the notice in Exhibit A, and to related Covered Code.
+
+6. Versions of the License.
+
+ 6.1. New Versions.
+
+
+ Netscape Communications Corporation ("Netscape") may publish
+ revised and/or new versions of the License from time to time. Each
+ version will be given a distinguishing version number.
+
+ 6.2. Effect of New Versions.
+
+
+ Once Covered Code has been published under a particular version of
+ the License, You may always continue to use it under the terms of that
+ version. You may also choose to use such Covered Code under the terms of
+ any subsequent version of the License published by Netscape. No one other
+ than Netscape has the right to modify the terms applicable to Covered
+ Code created under this License.
+
+ 6.3. Derivative Works.
+
+
+ If you create or use a modified version of this License (which you
+ may only do in order to apply it to code which is not already Covered
+ Code governed by this License), you must (a) rename Your license so that
+ the phrases "Mozilla", "MOZILLAPL", "MOZPL", "Netscape", "NPL"
+ or any confusingly similar phrase do not appear anywhere in your license
+ and (b) otherwise make it clear that your version of the license contains
+ terms which differ from the Mozilla Public License and Netscape Public
+ License. (Filling in the name of the Initial Developer, Original Code or
+ Contributor in the notice described in Exhibit A shall not of
+ themselves be deemed to be modifications of this License.)
+
+7. DISCLAIMER OF WARRANTY.
+
+ COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ WITHOUT LIMITATION, WARRANTIES THAT THE COVERED CODE IS FREE OF DEFECTS,
+ MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE OR NON-INFRINGING. THE ENTIRE
+ RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED CODE IS WITH
+ YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT THE
+ INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY
+ NECESSARY SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY
+ CONSTITUTES AN ESSENTIAL PART OF THIS LICENSE. NO USE OF ANY COVERED CODE
+ IS AUTHORIZED HEREUNDER EXCEPT UNDER THIS DISCLAIMER.
+
+8. TERMINATION.
+
+ This License and the rights granted hereunder will terminate
+ automatically if You fail to comply with terms herein and fail to cure
+ such breach within 30 days of becoming aware of the breach. All
+ sublicenses to the Covered Code which are properly granted shall survive
+ any termination of this License. Provisions which, by their nature, must
+ remain in effect beyond the termination of this License shall survive.
+
+9. LIMITATION OF LIABILITY.
+
+ UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, WHETHER TORT (INCLUDING
+ NEGLIGENCE), CONTRACT, OR OTHERWISE, SHALL THE INITIAL DEVELOPER, ANY
+ OTHER CONTRIBUTOR, OR ANY DISTRIBUTOR OF COVERED CODE, OR ANY SUPPLIER OF
+ ANY OF SUCH PARTIES, BE LIABLE TO YOU OR ANY OTHER PERSON FOR ANY
+ INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY CHARACTER
+ INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF GOODWILL, WORK
+ STOPPAGE, COMPUTER FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER
+ COMMERCIAL DAMAGES OR LOSSES, EVEN IF SUCH PARTY SHALL HAVE BEEN INFORMED
+ OF THE POSSIBILITY OF SUCH DAMAGES. THIS LIMITATION OF LIABILITY SHALL
+ NOT APPLY TO LIABILITY FOR DEATH OR PERSONAL INJURY RESULTING FROM SUCH
+ PARTY'S NEGLIGENCE TO THE EXTENT APPLICABLE LAW PROHIBITS SUCH
+ LIMITATION. SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION OR LIMITATION
+ OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO THAT EXCLUSION AND LIMITATION
+ MAY NOT APPLY TO YOU.
+
+10. U.S. GOVERNMENT END USERS.
+
+ The Covered Code is a "commercial item," as that term is defined in 48
+ C.F.R. 2.101 (Oct. 1995), consisting of "commercial computer software"
+ and "commercial computer software documentation," as such terms are
+ used in 48 C.F.R. 12.212 (Sept. 1995). Consistent with 48 C.F.R. 12.212
+ and 48 C.F.R. 227.7202-1 through 227.7202-4 (June 1995), all
+ U.S. Government End Users acquire Covered Code with only those rights set
+ forth herein.
+
+11. MISCELLANEOUS.
+
+ This License represents the complete agreement concerning subject matter
+ hereof. If any provision of this License is held to be unenforceable,
+ such provision shall be reformed only to the extent necessary to make it
+ enforceable. This License shall be governed by California law provisions
+ (except to the extent applicable law, if any, provides otherwise),
+ excluding its conflict-of-law provisions. With respect to disputes in
+ which at least one party is a citizen of, or an entity chartered or
+ registered to do business in, the United States of America: (a) unless
+ otherwise agreed in writing, all disputes relating to this License
+ (excepting any dispute relating to intellectual property rights) shall be
+ subject to final and binding arbitration, with the losing party paying
+ all costs of arbitration; (b) any arbitration relating to this Agreement
+ shall be held in Santa Clara County, California, under the auspices of
+ JAMS/EndDispute; and (c) any litigation relating to this Agreement shall
+ be subject to the jurisdiction of the Federal Courts of the Northern
+ District of California, with venue lying in Santa Clara County,
+ California, with the losing party responsible for costs, including
+ without limitation, court costs and reasonable attorneys fees and
+ expenses. The application of the United Nations Convention on Contracts
+ for the International Sale of Goods is expressly excluded. Any law or
+ regulation which provides that the language of a contract shall be
+ construed against the drafter shall not apply to this License.
+
+12. RESPONSIBILITY FOR CLAIMS.
+
+ Except in cases where another Contributor has failed to comply with
+ Section 3.4, You are responsible for damages arising, directly or
+ indirectly, out of Your utilization of rights under this License, based
+ on the number of copies of Covered Code you made available, the revenues
+ you received from utilizing such rights, and other relevant factors. You
+ agree to work with affected parties to distribute responsibility on an
+ equitable basis.
+
+EXHIBIT A.
+
+ "The contents of this file are subject to the Mozilla Public License
+ Version 1.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.mozilla.org/MPL/
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
+ License for the specific language governing rights and limitations under
+ the License.
+
+ The Original Code is ______________________________________.
+
+ The Initial Developer of the Original Code is
+ ________________________. Portions created by ______________________ are
+ Copyright (C) ______ _______________________. All Rights Reserved.
+
+ Contributor(s): ______________________________________."
+
+
+=========================================================================
+== Nunit License ==
+=========================================================================
+Copyright (c) 2002 James W. Newkirk, Michael C. Two, Alexei A. Vorontsov
+Copyright (c) 2000-2002 Philip A. Craig
+
+This software is provided 'as-is', without any express or implied
+warranty. In no event will the authors be held liable for any damages
+arising from the use of this software.
+
+Permission is granted to anyone to use this software for any purpose,
+including commercial applications, and to alter it and redistribute it
+freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+
+ 3. This notice may not be removed or altered from any source
+ distribution.
+
+=========================================================================
+== Mentalis Security LibraryLicense ==
+=========================================================================
+
+Source Code License
+
+Copyright © 2002-2007, The Mentalis.org Team
+All rights reserved.
+http://www.mentalis.org/
+
+Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+
+- Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
+
+- Neither the name of the Mentalis.org Team, nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+=========================================================================
+== AMQP License ==
+=========================================================================
+
+ Copyright Notice
+ ================
+ (c) Copyright JPMorgan Chase Bank & Co., Cisco Systems, Inc., Envoy Technologies Inc.,
+ iMatix Corporation, IONA\ufffd Technologies, Red Hat, Inc.,
+ TWIST Process Innovations, and 29West Inc. 2006. All rights reserved.
+
+ License
+ =======
+ JPMorgan Chase Bank & Co., Cisco Systems, Inc., Envoy Technologies Inc., iMatix
+ Corporation, IONA\ufffd Technologies, Red Hat, Inc., TWIST Process Innovations, and
+ 29West Inc. (collectively, the "Authors") each hereby grants to you a worldwide,
+ perpetual, royalty-free, nontransferable, nonexclusive license to
+ (i) copy, display, and implement the Advanced Messaging Queue Protocol
+ ("AMQP") Specification and (ii) the Licensed Claims that are held by
+ the Authors, all for the purpose of implementing the Advanced Messaging
+ Queue Protocol Specification. Your license and any rights under this
+ Agreement will terminate immediately without notice from
+ any Author if you bring any claim, suit, demand, or action related to
+ the Advanced Messaging Queue Protocol Specification against any Author.
+ Upon termination, you shall destroy all copies of the Advanced Messaging
+ Queue Protocol Specification in your possession or control.
+
+ As used hereunder, "Licensed Claims" means those claims of a patent or
+ patent application, throughout the world, excluding design patents and
+ design registrations, owned or controlled, or that can be sublicensed
+ without fee and in compliance with the requirements of this
+ Agreement, by an Author or its affiliates now or at any
+ future time and which would necessarily be infringed by implementation
+ of the Advanced Messaging Queue Protocol Specification. A claim is
+ necessarily infringed hereunder only when it is not possible to avoid
+ infringing it because there is no plausible non-infringing alternative
+ for implementing the required portions of the Advanced Messaging Queue
+ Protocol Specification. Notwithstanding the foregoing, Licensed Claims
+ shall not include any claims other than as set forth above even if
+ contained in the same patent as Licensed Claims; or that read solely
+ on any implementations of any portion of the Advanced Messaging Queue
+ Protocol Specification that are not required by the Advanced Messaging
+ Queue Protocol Specification, or that, if licensed, would require a
+ payment of royalties by the licensor to unaffiliated third parties.
+ Moreover, Licensed Claims shall not include (i) any enabling technologies
+ that may be necessary to make or use any Licensed Product but are not
+ themselves expressly set forth in the Advanced Messaging Queue Protocol
+ Specification (e.g., semiconductor manufacturing technology, compiler
+ technology, object oriented technology, networking technology, operating
+ system technology, and the like); or (ii) the implementation of other
+ published standards developed elsewhere and merely referred to in the
+ body of the Advanced Messaging Queue Protocol Specification, or
+ (iii) any Licensed Product and any combinations thereof the purpose or
+ function of which is not required for compliance with the Advanced
+ Messaging Queue Protocol Specification. For purposes of this definition,
+ the Advanced Messaging Queue Protocol Specification shall be deemed to
+ include both architectural and interconnection requirements essential
+ for interoperability and may also include supporting source code artifacts
+ where such architectural, interconnection requirements and source code
+ artifacts are expressly identified as being required or documentation to
+ achieve compliance with the Advanced Messaging Queue Protocol Specification.
+
+ As used hereunder, "Licensed Products" means only those specific portions
+ of products (hardware, software or combinations thereof) that implement
+ and are compliant with all relevant portions of the Advanced Messaging
+ Queue Protocol Specification.
+
+ The following disclaimers, which you hereby also acknowledge as to any
+ use you may make of the Advanced Messaging Queue Protocol Specification:
+
+ THE ADVANCED MESSAGING QUEUE PROTOCOL SPECIFICATION IS PROVIDED "AS IS,"
+ AND THE AUTHORS MAKE NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR
+ IMPLIED, INCLUDING, BUT NOT LIMITED TO, WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, OR TITLE; THAT THE
+ CONTENTS OF THE ADVANCED MESSAGING QUEUE PROTOCOL SPECIFICATION ARE
+ SUITABLE FOR ANY PURPOSE; NOR THAT THE IMPLEMENTATION OF THE ADVANCED
+ MESSAGING QUEUE PROTOCOL SPECIFICATION WILL NOT INFRINGE ANY THIRD PARTY
+ PATENTS, COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS.
+
+ THE AUTHORS WILL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL,
+ INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF OR RELATING TO ANY
+ USE, IMPLEMENTATION OR DISTRIBUTION OF THE ADVANCED MESSAGING QUEUE
+ PROTOCOL SPECIFICATION.
+
+ The name and trademarks of the Authors may NOT be used in any manner,
+ including advertising or publicity pertaining to the Advanced Messaging
+ Queue Protocol Specification or its contents without specific, written
+ prior permission. Title to copyright in the Advanced Messaging Queue
+ Protocol Specification will at all times remain with the Authors.
+
+ No other rights are granted by implication, estoppel or otherwise.
+
+ Upon termination of your license or rights under this Agreement, you
+ shall destroy all copies of the Advanced Messaging Queue Protocol
+ Specification in your possession or control.
+
+ Trademarks
+ ==========
+ "JPMorgan", "JPMorgan Chase", "Chase", the JPMorgan Chase logo and the
+ Octagon Symbol are trademarks of JPMorgan Chase & Co.
+
+ IMATIX and the iMatix logo are trademarks of iMatix Corporation sprl.
+
+ IONA, IONA Technologies, and the IONA logos are trademarks of IONA
+ Technologies PLC and/or its subsidiaries.
+
+ LINUX is a trademark of Linus Torvalds. RED HAT and JBOSS are registered
+ trademarks of Red Hat, Inc. in the US and other countries.
+
+ Java, all Java-based trademarks and OpenOffice.org are trademarks of
+ Sun Microsystems, Inc. in the United States, other countries, or both.
+
+ Other company, product, or service names may be trademarks or service
+ marks of others.
+
+ Links to full AMQP specification:
+ =================================
+ http://www.envoytech.org/spec/amq/
+ http://www.iona.com/opensource/amqp/
+ http://www.redhat.com/solutions/specifications/amqp/
+ http://www.twiststandards.org/tiki-index.php?page=AMQ
+ http://www.imatix.com/amqp
diff --git a/qpid/dotnet/NOTICE.txt b/qpid/dotnet/NOTICE.txt
new file mode 100644
index 0000000000..0b22ed3ab2
--- /dev/null
+++ b/qpid/dotnet/NOTICE.txt
@@ -0,0 +1,32 @@
+=========================================================================
+== NOTICE file corresponding to the section 4 d of ==
+== the Apache License, Version 2.0, ==
+== in this case for the Apache Ant distribution. ==
+=========================================================================
+
+Apache Qpid.NET
+Copyright 2006 The Apache Software Foundation
+
+This product includes software developed by
+The Apache Software Foundation (http://www.apache.org/).
+
+This product also includes software developed by:
+
+ - The SAXON XSLT Processor from Michael Kay distributed under the Mozilla
+ Public License v1.0, which is available for download at
+ http://saxon.sourceforge.net/
+
+ - The nunit library, Copyright © 2002 James W. Newkirk, Michael C. Two,
+ Alexei A. Vorontsov or Copyright © 2000-2002 Philip A. Craig. Available
+ under terms based on the zlib/libpng licence. Available from
+ http://www.nunit.org/
+
+ - The Mentalis Security Library, Copyright © 2002-2006, , The Mentalis.org Team
+ under tterms based on the BSD license (http://www.mentalis.org/site/license.qpx).
+ Available from http://www.mentalis.org/soft/projects/seclib/
+
+This product includes software, Apache Log4Net
+(http://logging.apache.org/log4net)
+License: Apache 2.0 License (http://www.apache.org/licenses/LICENSE-2.0)
+
+
diff --git a/qpid/dotnet/Qpid.Buffer.Tests/Properties/AssemblyInfo.cs b/qpid/dotnet/Qpid.Buffer.Tests/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000000..2f49033c2d
--- /dev/null
+++ b/qpid/dotnet/Qpid.Buffer.Tests/Properties/AssemblyInfo.cs
@@ -0,0 +1,56 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+ using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("Apache.Qpid.Buffer.Tests")]
+[assembly: AssemblyDescription("Built from svn revision number: ")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Apache Software Foundation")]
+[assembly: AssemblyProduct("Apache.Qpid.Buffer.Tests")]
+[assembly: AssemblyCopyright("Apache Software Foundation")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("9d967d0b-9454-4f00-8f53-fa86fd62b696")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Revision and Build Numbers
+// by using the '*' as shown below:
+[assembly: AssemblyVersion("0.5.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/qpid/dotnet/Qpid.Buffer.Tests/Qpid.Buffer.Tests.csproj b/qpid/dotnet/Qpid.Buffer.Tests/Qpid.Buffer.Tests.csproj
new file mode 100644
index 0000000000..72d3ccc82f
--- /dev/null
+++ b/qpid/dotnet/Qpid.Buffer.Tests/Qpid.Buffer.Tests.csproj
@@ -0,0 +1,83 @@
+<!--
+
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+
+-->
+
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProductVersion>8.0.50727</ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{74640962-99D0-4D06-B57A-9CD66517CF52}</ProjectGuid>
+ <OutputType>Library</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>Apache.Qpid.Buffer.Tests</RootNamespace>
+ <AssemblyName>Apache.Qpid.Buffer.Tests</AssemblyName>
+ <FileUpgradeFlags>
+ </FileUpgradeFlags>
+ <OldToolsVersion>2.0</OldToolsVersion>
+ <UpgradeBackupLocation>
+ </UpgradeBackupLocation>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>..\bin\net-2.0\debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ <UseVSHostingProcess>true</UseVSHostingProcess>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>..\bin\net-2.0\release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="nunit.framework, Version=2.2.8.0, Culture=neutral, PublicKeyToken=96d09a1eb7f44a77">
+ <SpecificVersion>False</SpecificVersion>
+ <HintPath>..\Qpid.Client.Tests\lib\nunit\nunit.framework.dll</HintPath>
+ </Reference>
+ <Reference Include="System" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="**\*.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\Qpid.Buffer\Qpid.Buffer.csproj">
+ <Project>{44384DF2-B0A4-4580-BDBC-EE4BAA87D995}</Project>
+ <Name>Qpid.Buffer</Name>
+ </ProjectReference>
+ </ItemGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+ <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
+ Other similar extension points exist, see Microsoft.Common.targets.
+ <Target Name="BeforeBuild">
+ </Target>
+ <Target Name="AfterBuild">
+ </Target>
+ -->
+</Project>
diff --git a/qpid/dotnet/Qpid.Buffer.Tests/SimpleByteBufferTests.cs b/qpid/dotnet/Qpid.Buffer.Tests/SimpleByteBufferTests.cs
new file mode 100644
index 0000000000..b028bdb1ee
--- /dev/null
+++ b/qpid/dotnet/Qpid.Buffer.Tests/SimpleByteBufferTests.cs
@@ -0,0 +1,333 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+using NUnit.Framework;
+using Apache.Qpid.Buffer;
+
+namespace Apache.Qpid.Buffer.Tests
+{
+ /// <summary>
+ /// Tests for the SimpleByteBuffer class
+ /// </summary>
+ [TestFixture]
+ public class SimpleByteBufferTests
+ {
+ [Test]
+ public void CanCreateNewBuffer()
+ {
+ const int size = 10;
+ ByteBuffer buffer = ByteBuffer.Allocate(size);
+ Assert.AreEqual(size, buffer.Capacity);
+ Assert.AreEqual(0, buffer.Position);
+ Assert.AreEqual(size, buffer.Remaining);
+ Assert.AreEqual(true, buffer.HasRemaining);
+ }
+
+ [Test]
+ public void CanWrapArray()
+ {
+ byte[] array = new byte[10];
+ for ( int i=0; i < array.Length; i++ )
+ {
+ array[i] = (byte) i;
+ }
+ ByteBuffer buffer = ByteBuffer.Wrap(array);
+ // the buffer should be the same size,
+ // and positioned at the end
+ Assert.AreEqual(array.Length, buffer.Capacity);
+ Assert.AreEqual(array.Length, buffer.Position);
+ Assert.AreEqual(array.Length, buffer.Limit);
+ }
+
+ #region Base Read/Write tests
+ //
+ // Base Read/Write tests
+ //
+ [Test]
+ public void CanReadWriteBytes()
+ {
+ ByteBuffer buffer = ByteBuffer.Allocate(10);
+ buffer.Put((byte)0x01).Put((byte)0x02).Put((byte)0x03);
+ buffer.Rewind();
+ Assert.AreEqual(0x01, buffer.GetByte());
+ Assert.AreEqual(0x02, buffer.GetByte());
+ Assert.AreEqual(0x03, buffer.GetByte());
+ }
+
+ [Test]
+ [ExpectedException(typeof(BufferUnderflowException))]
+ public void ThrowOnReadByteWithNoSpace()
+ {
+ ByteBuffer buffer = ByteBuffer.Allocate(1);
+ buffer.Put((byte)0x01);
+ buffer.GetByte();
+ }
+
+ [Test]
+ [ExpectedException(typeof(BufferOverflowException))]
+ public void ThrowOnWriteByteWithNoSpace()
+ {
+ ByteBuffer buffer = ByteBuffer.Allocate(1);
+ buffer.Put((byte)0x01).Put((byte)0x02);
+ }
+
+ #endregion Base Read/Write tests
+
+ #region Other Buffer Operations
+ //
+ // Other Buffer Operations
+ //
+
+ [Test]
+ public void CanFlipBuffer()
+ {
+ ByteBuffer buffer = ByteBuffer.Allocate(10);
+ buffer.Put((byte)0x01).Put((byte)0x02).Put((byte)0x03);
+ buffer.Flip();
+ Assert.AreEqual(10, buffer.Capacity);
+ Assert.AreEqual(3, buffer.Limit);
+ Assert.AreEqual(0, buffer.Position);
+ Assert.AreEqual(3, buffer.Remaining);
+ }
+
+ [Test]
+ public void CanCompactBuffer()
+ {
+ ByteBuffer buffer = ByteBuffer.Allocate(10);
+ buffer.Put((byte)0x01).Put((byte)0x02).Put((byte)0x03);
+ buffer.Flip();
+ buffer.Position = 1;
+ buffer.Compact();
+ Assert.AreEqual(10, buffer.Capacity);
+ Assert.AreEqual(10, buffer.Limit);
+ Assert.AreEqual(2, buffer.Position);
+ Assert.AreEqual(8, buffer.Remaining);
+ buffer.Rewind();
+ Assert.AreEqual((byte)0x02, buffer.GetByte());
+ Assert.AreEqual((byte)0x03, buffer.GetByte());
+ }
+
+ [Test]
+ public void CanClearBuffer()
+ {
+ ByteBuffer buffer = ByteBuffer.Allocate(10);
+ buffer.Put((byte)0x01).Put((byte)0x02).Put((byte)0x03);
+ buffer.Flip();
+ buffer.Position = 2;
+ buffer.Clear();
+ Assert.AreEqual(10, buffer.Capacity);
+ Assert.AreEqual(10, buffer.Limit);
+ Assert.AreEqual(0, buffer.Position);
+ Assert.AreEqual(10, buffer.Remaining);
+ }
+
+ [Test]
+ public void CanExpandBuffer()
+ {
+ ByteBuffer buffer = ByteBuffer.Allocate(10);
+ buffer.Put((byte)0x01).Put((byte)0x02).Put((byte)0x03);
+ buffer.Flip();
+ buffer.Position = 2;
+ int pos = buffer.Position;
+ buffer.Expand(20);
+
+ Assert.AreEqual(pos, buffer.Position);
+ Assert.IsTrue(buffer.Remaining >= 20);
+ buffer.Rewind();
+ Assert.AreEqual(0x01, buffer.GetByte());
+ }
+
+ [Test]
+ public void CanAutoExpand()
+ {
+ ByteBuffer buffer = ByteBuffer.Allocate(2);
+ buffer.IsAutoExpand = true;
+ // should cause autoexpand
+ buffer.Put((byte)0x01).Put((byte)0x02).Put((byte)0x03);
+ Assert.IsTrue(buffer.Capacity > 2);
+ }
+
+ [Test]
+ public void CanGetArray()
+ {
+ ByteBuffer buffer = ByteBuffer.Allocate(10);
+ buffer.Put((byte)0x01).Put((byte)0x02).Put((byte)0x03);
+ buffer.Flip();
+
+ byte[] array = buffer.Array;
+ for ( int i=0; i < buffer.Limit; i++ )
+ {
+ Assert.AreEqual(buffer.GetByte(), array[i]);
+ }
+ }
+
+ [Test]
+ public void CanSkip()
+ {
+ ByteBuffer buffer = ByteBuffer.Allocate(10);
+ buffer.Skip(4);
+ Assert.AreEqual(4, buffer.Position);
+ }
+
+ #endregion // Base Read/Write tests
+
+ #region Typed Accessors
+ //
+ // Typed Accessors
+ //
+ [Test]
+ public void CanReadWriteSByte()
+ {
+ ByteBuffer buffer = ByteBuffer.Allocate(10);
+ sbyte value = -12;
+ buffer.Put(value);
+ buffer.Flip();
+ Assert.AreEqual(value, buffer.GetSByte());
+ }
+ [Test]
+ public void CanReadWriteUInt16()
+ {
+ ByteBuffer buffer = ByteBuffer.Allocate(10);
+ ushort value = 41233;
+ buffer.Put(value);
+ buffer.Flip();
+ Assert.AreEqual(value, buffer.GetUInt16());
+ }
+ [Test]
+ public void CanReadWriteInt16()
+ {
+ ByteBuffer buffer = ByteBuffer.Allocate(10);
+ short value = -21233;
+ buffer.Put(value);
+ buffer.Flip();
+ Assert.AreEqual(value, buffer.GetInt16());
+ }
+ [Test]
+ public void CanReadWriteUInt32()
+ {
+ ByteBuffer buffer = ByteBuffer.Allocate(10);
+ uint value = 41233211;
+ buffer.Put(value);
+ buffer.Flip();
+ Assert.AreEqual(value, buffer.GetUInt32());
+ }
+ [Test]
+ public void CanReadWriteInt32()
+ {
+ ByteBuffer buffer = ByteBuffer.Allocate(10);
+ int value = -22221233;
+ buffer.Put(value);
+ buffer.Flip();
+ Assert.AreEqual(value, buffer.GetInt32());
+ }
+ [Test]
+ public void CanReadWriteUInt64()
+ {
+ ByteBuffer buffer = ByteBuffer.Allocate(10);
+ ulong value = 41233218871;
+ buffer.Put(value);
+ buffer.Flip();
+ Assert.AreEqual(value, buffer.GetUInt64());
+ }
+ [Test]
+ public void CanReadWriteInt64()
+ {
+ ByteBuffer buffer = ByteBuffer.Allocate(10);
+ long value = -9887335411;
+ buffer.Put(value);
+ buffer.Flip();
+ Assert.AreEqual(value, buffer.GetInt64());
+ }
+ [Test]
+ public void CanReadWriteFloat()
+ {
+ ByteBuffer buffer = ByteBuffer.Allocate(10);
+ float value = -1.2331f;
+ buffer.Put(value);
+ buffer.Flip();
+ Assert.AreEqual(value, buffer.GetFloat());
+ }
+
+ [Test]
+ public void CanReadWriteDouble()
+ {
+ ByteBuffer buffer = ByteBuffer.Allocate(10);
+ double value = -1.2331E12;
+ buffer.Put(value);
+ buffer.Flip();
+ Assert.AreEqual(value, buffer.GetDouble());
+ }
+
+ [Test]
+ public void CanReadWriteChar()
+ {
+ ByteBuffer buffer = ByteBuffer.Allocate(10);
+ char value = 'H';
+ buffer.Put(value);
+ buffer.Flip();
+ Assert.AreEqual(value, buffer.GetChar());
+ }
+
+ [Test]
+ public void CanReadWriteByteArray()
+ {
+ ByteBuffer buffer = ByteBuffer.Allocate(10);
+ buffer.Put(new byte[] { 0x01, 0x02, 0x03});
+ buffer.Flip();
+ byte[] data = new byte[3];
+ buffer.GetBytes(data);
+ Assert.AreEqual(0x01, data[0]);
+ Assert.AreEqual(0x02, data[1]);
+ Assert.AreEqual(0x03, data[2]);
+ }
+
+ [Test]
+ public void CanReadWriteByteArrayWithOffset()
+ {
+ ByteBuffer buffer = ByteBuffer.Allocate(10);
+ buffer.Put(new byte[] { 0x01, 0x02, 0x03, 0x04, 0x05 }, 1, 4);
+ buffer.Flip();
+ byte[] data = new byte[3];
+ buffer.GetBytes(data, 2, 1);
+ Assert.AreEqual(0x00, data[0]);
+ Assert.AreEqual(0x00, data[1]);
+ Assert.AreEqual(0x02, data[2]);
+ }
+
+ [Test]
+ public void CanWriteByteBuffer()
+ {
+ ByteBuffer buffer1 = ByteBuffer.Allocate(10);
+ buffer1.Put((byte)0x01).Put((byte)0x02).Put((byte)0x03);
+ buffer1.Flip();
+
+ ByteBuffer buffer2 = ByteBuffer.Allocate(10);
+ buffer2.Put(buffer1);
+ buffer2.Flip();
+ Assert.AreEqual(buffer1.Limit, buffer2.Limit);
+ Assert.AreEqual(0x01, buffer2.GetByte());
+ }
+ #endregion // Typed Accessors
+
+ } // class SimpleByteBufferTests
+}
+
+
diff --git a/qpid/dotnet/Qpid.Buffer.Tests/SlicedByteBufferTests.cs b/qpid/dotnet/Qpid.Buffer.Tests/SlicedByteBufferTests.cs
new file mode 100644
index 0000000000..7dec7c390f
--- /dev/null
+++ b/qpid/dotnet/Qpid.Buffer.Tests/SlicedByteBufferTests.cs
@@ -0,0 +1,133 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+using System;
+using NUnit.Framework;
+using Apache.Qpid.Buffer;
+
+namespace Apache.Qpid.Buffer.Tests
+{
+ /// <summary>
+ /// Tests for the SlicedByteBuffer class
+ /// </summary>
+ [TestFixture]
+ public class SlicedByteBufferTests
+ {
+ private ByteBuffer _baseBuffer;
+
+ [SetUp]
+ public void Setup()
+ {
+ const int size = 50;
+ _baseBuffer = ByteBuffer.Allocate(size);
+ for ( byte b = 0; b < 10; b++ )
+ {
+ _baseBuffer.Put(b);
+ }
+ _baseBuffer.Flip();
+ }
+
+ [Test]
+ public void CanSliceBuffer()
+ {
+ _baseBuffer.Position = 5;
+
+ ByteBuffer slice = _baseBuffer.Slice();
+ Assert.AreEqual(5, slice.Capacity);
+ Assert.AreEqual(0, slice.Position);
+ Assert.AreEqual(5, slice.Remaining);
+ Assert.AreEqual(5, slice.Limit);
+ }
+
+ [Test]
+ public void CanReadWriteSlice()
+ {
+ _baseBuffer.Position = 5;
+
+ ByteBuffer slice = _baseBuffer.Slice();
+ slice.Put((byte) 0xFF).Put((byte) 0xF0).Put((byte) 0xA0);
+ slice.Flip();
+
+ Assert.AreEqual(3, slice.Limit);
+ Assert.AreEqual(0xFF, slice.GetByte());
+ Assert.AreEqual(0xF0, slice.GetByte());
+ Assert.AreEqual(0xA0, slice.GetByte());
+ }
+
+ [Test]
+ public void WriteModifiesBaseBufferOnCorrectPosition()
+ {
+ _baseBuffer.Position = 5;
+
+ ByteBuffer slice = _baseBuffer.Slice();
+ slice.Put((byte) 0xFF);
+ slice.Flip();
+ // reading the _baseBuffer at position 5 should yield 0xFF
+ _baseBuffer.Position = 5;
+ Assert.AreEqual(0xFF, _baseBuffer.GetByte());
+
+ }
+
+ [Test]
+ public void CanReadWriteByteArray()
+ {
+ _baseBuffer.Position = 5;
+
+ ByteBuffer slice = _baseBuffer.Slice();
+ byte[] data = {0xFF, 0xF0, 0xF2, 0xEE, 0x23};
+ slice.Put(data, 2, 2);
+ slice.Flip();
+
+ Assert.AreEqual(2, slice.Limit);
+ Assert.AreEqual(0xF2, slice.GetByte());
+ Assert.AreEqual(0xEE, slice.GetByte());
+ }
+
+ [Test]
+ [ExpectedException(typeof(BufferOverflowException))]
+ public void ThrowWhenWritePastLimit()
+ {
+ _baseBuffer.Position = 5;
+
+ ByteBuffer slice = _baseBuffer.Slice();
+ slice.Put(0x01).Put(0x02);
+ }
+
+
+ [Test]
+ [ExpectedException(typeof(NotSupportedException))]
+ public void ThrowOnCompact()
+ {
+ // we don't support compacting
+ ByteBuffer slice = _baseBuffer.Slice();
+ slice.Compact();
+ }
+
+ [Test]
+ [ExpectedException(typeof(NotSupportedException))]
+ public void ThrowOnResize()
+ {
+ // we don't support resizing
+ ByteBuffer slice = _baseBuffer.Slice();
+ slice.Expand(50);
+ }
+ } // class SlicedByteBufferTests
+}
diff --git a/qpid/dotnet/Qpid.Buffer.Tests/default.build b/qpid/dotnet/Qpid.Buffer.Tests/default.build
new file mode 100644
index 0000000000..77e95fb9d9
--- /dev/null
+++ b/qpid/dotnet/Qpid.Buffer.Tests/default.build
@@ -0,0 +1,48 @@
+<?xml version="1.0"?>
+<!--
+
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+
+-->
+
+<project name="Apache.Qpid.Buffer" default="test">
+
+ <target name="build">
+ <csc target="library"
+ define="${build.defines}"
+ warnaserror="true" debug="${build.debug}"
+ output="${build.dir}/${project::get-name()}.Tests.dll">
+
+ <sources>
+ <include name="**/*.cs" />
+ </sources>
+ <references>
+ <include name="${build.dir}/nunit.framework.dll" />
+ <include name="${build.dir}/${project::get-name()}.dll" />
+ </references>
+
+ </csc>
+ </target>
+ <target name="test" depends="build">
+ <nunit2>
+ <formatter type="${nant.formatter}" usefile="false" />
+ <test assemblyname="${build.dir}/${project::get-name()}.Tests.dll" />
+ </nunit2>
+ </target>
+</project>
+
diff --git a/qpid/dotnet/Qpid.Buffer/BufferOverflowException.cs b/qpid/dotnet/Qpid.Buffer/BufferOverflowException.cs
new file mode 100644
index 0000000000..5a2fff74a7
--- /dev/null
+++ b/qpid/dotnet/Qpid.Buffer/BufferOverflowException.cs
@@ -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.
+ *
+ */
+using System;
+using System.Runtime.Serialization;
+
+namespace Apache.Qpid.Buffer
+{
+ [Serializable]
+ public class BufferOverflowException : Exception
+ {
+ public BufferOverflowException(string message) : base(message)
+ {
+ }
+
+ protected BufferOverflowException(SerializationInfo info, StreamingContext ctxt)
+ : base(info, ctxt)
+ {
+ }
+ }
+}
+
+
+
diff --git a/qpid/dotnet/Qpid.Buffer/BufferUnderflowException.cs b/qpid/dotnet/Qpid.Buffer/BufferUnderflowException.cs
new file mode 100644
index 0000000000..13939b77a8
--- /dev/null
+++ b/qpid/dotnet/Qpid.Buffer/BufferUnderflowException.cs
@@ -0,0 +1,42 @@
+/*
+ *
+ * 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.
+ *
+ */
+using System;
+using System.Runtime.Serialization;
+
+namespace Apache.Qpid.Buffer
+{
+ [Serializable]
+ public class BufferUnderflowException : Exception
+ {
+ public BufferUnderflowException(string message)
+ : base(message)
+ {
+ }
+
+ protected BufferUnderflowException(SerializationInfo info, StreamingContext ctxt)
+ : base(info, ctxt)
+ {
+ }
+ }
+}
+
+
+
diff --git a/qpid/dotnet/Qpid.Buffer/ByteBuffer.cs b/qpid/dotnet/Qpid.Buffer/ByteBuffer.cs
new file mode 100644
index 0000000000..67f0edd440
--- /dev/null
+++ b/qpid/dotnet/Qpid.Buffer/ByteBuffer.cs
@@ -0,0 +1,982 @@
+/*
+ *
+ * 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.
+ *
+ */
+using System;
+
+namespace Apache.Qpid.Buffer
+{
+ /// <summary>
+ /// Abstract class implementing a byte buffer
+ /// </summary>
+ public abstract class ByteBuffer
+ {
+ private int _position;
+ private int _limit;
+ private bool _isAutoExpand;
+ private static IByteBufferAllocator _allocator =
+ new SimpleByteBufferAllocator();
+
+ #region Properties
+ //
+ // Properties
+ //
+
+ /// <summary>
+ /// The maximum number of bytes the buffer can hold
+ /// </summary>
+ public abstract int Capacity
+ {
+ get;
+ }
+
+ /// <summary>
+ /// Return the backing array of this buffer
+ /// </summary>
+ public abstract byte[] Array
+ {
+ get;
+ }
+
+ /// <summary>
+ /// The current position inside this buffer
+ /// </summary>
+ public int Position
+ {
+ get { return _position; }
+ set { Seek(value); }
+ }
+
+ /// <summary>
+ /// Index of the first element that should not be read or written.
+ /// A buffer's limit is never negative and is never greater than the its capacity.
+ /// </summary>
+ public int Limit
+ {
+ get { return _limit; }
+ set { SetLimit(value); }
+ }
+
+ /// <summary>
+ /// Number of bytes remaining in the buffer from the current position
+ /// </summary>
+ public int Remaining
+ {
+ get { return Limit - Position; }
+ }
+
+ /// <summary>
+ /// True if there are bytes remaining in the buffer
+ /// </summary>
+ public bool HasRemaining
+ {
+ get { return Remaining > 0; }
+ }
+
+ /// <summary>
+ /// If true, the buffer will be resized as necessary
+ /// to allow space for writing. By default is false.
+ /// </summary>
+ public bool IsAutoExpand
+ {
+ get { return _isAutoExpand; }
+ set { _isAutoExpand = value; }
+ }
+
+ #endregion // Properties
+
+ #region Buffer Manipulation
+ //
+ // Buffer Manipulation
+ //
+
+ /// <summary>
+ /// Move the buffer to Position 0
+ /// </summary>
+ /// <returns>This instance</returns>
+ public ByteBuffer Rewind()
+ {
+ Seek(0);
+ return this;
+ }
+
+ /// <summary>
+ /// Prepare the buffer to read back what's been written
+ /// </summary>
+ /// <returns>This instance</returns>
+ public ByteBuffer Flip()
+ {
+ Limit = Position;
+ Position = 0;
+ return this;
+ }
+
+ /// <summary>
+ /// Compact this buffer.
+ /// </summary>
+ /// <returns>This instance</returns>
+ /// <remarks>
+ /// The bytes between the buffer's current position and its limit, if any,
+ /// are copied to the beginning of the buffer.
+ /// </remarks>
+ public ByteBuffer Compact()
+ {
+ DoCompact();
+ return this;
+ }
+
+ /// <summary>
+ /// Clears this buffer. The position is set to zero, the limit is set to the capacity
+ /// </summary>
+ /// <returns>This instance</returns>
+ public ByteBuffer Clear()
+ {
+ Limit = Capacity;
+ Position = 0;
+ return this;
+ }
+
+ /// <summary>
+ /// Expands this buffer's capacity so that
+ /// Remaining == expectedRemaining
+ /// </summary>
+ /// <param name="expectedRemaining">Number of bytes that should be accessable after resizing</param>
+ /// <returns>This instance</returns>
+ public ByteBuffer Expand(int expectedRemaining)
+ {
+ return Expand(Position, expectedRemaining);
+ }
+
+ /// <summary>
+ /// Expands this buffer's capacity so that
+ /// Remaining == expectedRemaining
+ /// </summary>
+ /// <param name="position">Position from which to start the resize</param>
+ /// <param name="expectedRemaining">Number of bytes that should be accessable after resizing</param>
+ /// <returns>This instance</returns>
+ public ByteBuffer Expand(int position, int expectedRemaining)
+ {
+ if ( expectedRemaining <= 0 )
+ throw new ArgumentException("expectedRemaining must be greater than 0");
+
+ int end = position + expectedRemaining;
+ if ( end > Capacity )
+ {
+ DoResize(end);
+ }
+ if ( end > Limit )
+ Limit = end;
+ return this;
+ }
+
+ /// <summary>
+ /// Creates a new byte buffer whose content is a shared
+ /// subsequence of this buffer's content.
+ /// </summary>
+ /// <remarks>
+ /// The content of the new buffer will start at this buffer's current position.
+ /// Changes to this buffer's content will be visible in the new buffer,
+ /// and vice versa; the two buffers' position and limit values will be independent.
+ /// <para>
+ /// The new buffer's position will be zero, its capacity and its limit will
+ /// be the number of bytes remaining in this buffer.
+ /// </para>
+ /// </remarks>
+ /// <returns>A view on top of this instance</returns>
+ public ByteBuffer Slice()
+ {
+ return new SlicedByteBuffer(this);
+ }
+
+ /// <summary>
+ /// Skip the specified number of bytes
+ /// </summary>
+ /// <param name="numBytes">Number of bytes to move forward by</param>
+ /// <returns>This instance</returns>
+ public ByteBuffer Skip(int numBytes)
+ {
+ Position += numBytes;
+ return this;
+ }
+
+ /// <summary>
+ /// Acquire this buffer to keep it alive.
+ /// </summary>
+ public virtual void Acquire()
+ {
+ // override in subclass if supported
+ }
+
+ /// <summary>
+ /// Release this buffer instance
+ /// </summary>
+ public virtual void Release()
+ {
+ // override in subclass if supported
+ }
+
+ /// <summary>
+ /// Return a string with a Hex Dump of this buffer's contents
+ /// </summary>
+ /// <returns>The hex dump</returns>
+ public string GetHexDump()
+ {
+ return ByteBufferHexDumper.GetHexDump(this);
+ }
+
+ public override string ToString()
+ {
+ return GetHexDump();
+ }
+ #endregion // Buffer Manipulation
+
+ #region Static Operations
+ //
+ // Static Operations
+ //
+ /// <summary>
+ /// Replaces the default allocator with your own implementation
+ /// </summary>
+ /// <param name="allocator">New allocator</param>
+ public static void SetAllocator(IByteBufferAllocator allocator)
+ {
+ if ( allocator == null )
+ throw new ArgumentNullException("allocator");
+ _allocator = allocator;
+ }
+
+ /// <summary>
+ /// Allocate a new buffer with the specified capacity
+ /// using the default allocator
+ /// </summary>
+ /// <param name="capacity">Desired capacity</param>
+ /// <returns>The new buffer</returns>
+ public static ByteBuffer Allocate(int capacity)
+ {
+ return _allocator.Allocate(capacity);
+ }
+
+ /// <summary>
+ /// Wraps the specified arrat into a new buffer
+ /// </summary>
+ /// <param name="buffer"></param>
+ /// <returns></returns>
+ public static ByteBuffer Wrap(byte[] buffer)
+ {
+ return _allocator.Wrap(buffer);
+ }
+ #endregion // Static Operations
+
+ #region Data Accessors
+ //
+ // Data Accessors
+ //
+
+ // Byte Stuff
+
+ /// <summary>
+ /// Read the next byte in the buffer
+ /// </summary>
+ /// <returns>The next byte available</returns>
+ public byte GetByte()
+ {
+ byte value = GetByte(Position);
+ Position += 1;
+ return value;
+ }
+ /// <summary>
+ /// Read the byte at the specified position
+ /// </summary>
+ /// <param name="position">Position to read from</param>
+ /// <returns>The value at the position</returns>
+ public byte GetByte(int position)
+ {
+ CheckSpaceForReading(position, 1);
+ return ReadByte(position);
+ }
+ /// <summary>
+ /// Write a byte at the current position
+ /// </summary>
+ /// <param name="value">Value to write</param>
+ /// <returns>This instance</returns>
+ public ByteBuffer Put(byte value)
+ {
+ Put(Position, value);
+ Position++;
+ return this;
+ }
+ /// <summary>
+ /// Write a byte at the specified position
+ /// </summary>
+ /// <param name="position">Position to write to</param>
+ /// <param name="value">Value to write</param>
+ /// <returns>This instance</returns>
+ public ByteBuffer Put(int position, byte value)
+ {
+ CheckSpaceForWriting(position, 1);
+ Write(position, value);
+ return this;
+ }
+
+ // SByte Stuff
+
+ /// <summary>
+ /// Read the next signed byte in the buffer
+ /// </summary>
+ /// <returns>The next signed byte available</returns>
+ public sbyte GetSByte()
+ {
+ sbyte value = GetSByte(Position);
+ Position += 1;
+ return value;
+ }
+ /// <summary>
+ /// Read the signed byte at the specified position
+ /// </summary>
+ /// <param name="position">Position to read from</param>
+ /// <returns>The value at the position</returns>
+ public sbyte GetSByte(int position)
+ {
+ CheckSpaceForReading(position, 1);
+ return (sbyte)ReadByte(position);
+ }
+
+ /// <summary>
+ /// Write a signed byte at the current position
+ /// </summary>
+ /// <param name="value">Value to write</param>
+ /// <returns>This instance</returns>
+ public ByteBuffer Put(sbyte value)
+ {
+ Put(Position, value);
+ Position += 1;
+ return this;
+ }
+
+ /// <summary>
+ /// Write a signed byte at the specified position
+ /// </summary>
+ /// <param name="position">Position to write to</param>
+ /// <param name="value">Value to write</param>
+ /// <returns>This instance</returns>
+ public ByteBuffer Put(int position, sbyte value)
+ {
+ CheckSpaceForWriting(position, 1);
+ Write(position, (byte)value);
+ return this;
+ }
+
+ // UInt16 Stuff
+
+ /// <summary>
+ /// Read the next uint16 in the buffer
+ /// </summary>
+ /// <returns>The next uint16 available</returns>
+ public ushort GetUInt16()
+ {
+ ushort value = GetUInt16(Position);
+ Position += 2;
+ return value;
+ }
+ /// <summary>
+ /// Read the uint16 at the specified position
+ /// </summary>
+ /// <param name="position">Position to read from</param>
+ /// <returns>The value at the position</returns>
+ public ushort GetUInt16(int position)
+ {
+ CheckSpaceForReading(position, 2);
+ byte upper = ReadByte(position);
+ byte lower = ReadByte(position+1);
+ return (ushort)(((ushort)upper << 8) + lower);
+ }
+
+ /// <summary>
+ /// Write a uint16 at the current position
+ /// </summary>
+ /// <param name="value">Value to write</param>
+ /// <returns>This instance</returns>
+ public ByteBuffer Put(ushort value)
+ {
+ Put(Position, value);
+ Position += 2;
+ return this;
+ }
+
+ /// <summary>
+ /// Write a uint16 at the specified position
+ /// </summary>
+ /// <param name="position">Position to write to</param>
+ /// <param name="value">Value to write</param>
+ /// <returns>This instance</returns>
+ public ByteBuffer Put(int position, ushort value)
+ {
+ CheckSpaceForWriting(position, 2);
+ Write(position, (byte)(value >> 8));
+ Write(position+1, (byte)(value));
+ return this;
+ }
+
+ // Int16 Stuff
+
+ /// <summary>
+ /// Read the next int16 in the buffer
+ /// </summary>
+ /// <returns>The next int16 available</returns>
+ public short GetInt16()
+ {
+ return (short) GetUInt16();
+ }
+ /// <summary>
+ /// Read the int16 at the specified position
+ /// </summary>
+ /// <param name="position">Position to read from</param>
+ /// <returns>The value at the position</returns>
+ public short GetInt16(int position)
+ {
+ return (short)GetUInt16(position);
+ }
+
+ /// <summary>
+ /// Write a int16 at the current position
+ /// </summary>
+ /// <param name="value">Value to write</param>
+ /// <returns>This instance</returns>
+ public ByteBuffer Put(short value)
+ {
+ return Put((ushort) value);
+ }
+
+ /// <summary>
+ /// Write a int16 at the specified position
+ /// </summary>
+ /// <param name="position">Position to write to</param>
+ /// <param name="value">Value to write</param>
+ /// <returns>This instance</returns>
+ public ByteBuffer Put(int position, short value)
+ {
+ return Put(position, (ushort)value);
+ }
+
+
+ // UInt32 Stuff
+
+ /// <summary>
+ /// Read the next uint32 in the buffer
+ /// </summary>
+ /// <returns>The next uint32 available</returns>
+ public uint GetUInt32()
+ {
+ uint value = GetUInt32(Position);
+ Position += 4;
+ return value;
+ }
+ /// <summary>
+ /// Read the uint32 at the specified position
+ /// </summary>
+ /// <param name="position">Position to read from</param>
+ /// <returns>The value at the position</returns>
+ public uint GetUInt32(int position)
+ {
+ CheckSpaceForReading(position, 4);
+ byte b1 = ReadByte(position);
+ byte b2 = ReadByte(position + 1);
+ byte b3 = ReadByte(position + 2);
+ byte b4 = ReadByte(position + 3);
+ return (uint)((b1 << 24) + (b2 << 16) + (b3 << 8) + b4);
+ }
+
+ /// <summary>
+ /// Write a uint32 at the current position
+ /// </summary>
+ /// <param name="value">Value to write</param>
+ /// <returns>This instance</returns>
+ public ByteBuffer Put(uint value)
+ {
+ Put(Position, value);
+ Position += 4;
+ return this;
+ }
+
+ /// <summary>
+ /// Write a uint32 at the specified position
+ /// </summary>
+ /// <param name="position">Position to write to</param>
+ /// <param name="value">Value to write</param>
+ /// <returns>This instance</returns>
+ public ByteBuffer Put(int position, uint value)
+ {
+ CheckSpaceForWriting(position, 4);
+ Write(position, (byte)(value >> 24));
+ Write(position + 1, (byte)(value >> 16));
+ Write(position + 2, (byte)(value >> 8));
+ Write(position + 3, (byte)(value));
+ return this;
+ }
+
+ // Int32 Stuff
+
+ /// <summary>
+ /// Read the next int32 in the buffer
+ /// </summary>
+ /// <returns>The next int32 available</returns>
+ public int GetInt32()
+ {
+ return (int)GetUInt32();
+ }
+ /// <summary>
+ /// Read the int32 at the specified position
+ /// </summary>
+ /// <param name="position">Position to read from</param>
+ /// <returns>The value at the position</returns>
+ public int GetInt32(int position)
+ {
+ return (int)GetUInt32(position);
+ }
+
+ /// <summary>
+ /// Write a int32 at the current position
+ /// </summary>
+ /// <param name="value">Value to write</param>
+ /// <returns>This instance</returns>
+ public ByteBuffer Put(int value)
+ {
+ return Put((uint)value);
+ }
+
+ /// <summary>
+ /// Write a int32 at the specified position
+ /// </summary>
+ /// <param name="position">Position to write to</param>
+ /// <param name="value">Value to write</param>
+ /// <returns>This instance</returns>
+ public ByteBuffer Put(int position, int value)
+ {
+ return Put(position, (uint)value);
+ }
+
+ // UInt64 Stuff
+
+ /// <summary>
+ /// Read the next uint64 in the buffer
+ /// </summary>
+ /// <returns>The next uint64 available</returns>
+ public ulong GetUInt64()
+ {
+ ulong value = GetUInt64(Position);
+ Position += 8;
+ return value;
+ }
+ /// <summary>
+ /// Read the uint64 at the specified position
+ /// </summary>
+ /// <param name="position">Position to read from</param>
+ /// <returns>The value at the position</returns>
+ public ulong GetUInt64(int position)
+ {
+ CheckSpaceForReading(position, 8);
+ byte b1 = ReadByte(position);
+ byte b2 = ReadByte(position + 1);
+ byte b3 = ReadByte(position + 2);
+ byte b4 = ReadByte(position + 3);
+ byte b5 = ReadByte(position + 4);
+ byte b6 = ReadByte(position + 5);
+ byte b7 = ReadByte(position + 6);
+ byte b8 = ReadByte(position + 7);
+ // all the casts necessary because otherwise each subexpression
+ // only gets promoted to uint and cause incorrect results
+ return (((ulong)b1 << 56) + ((ulong)b2 << 48) + ((ulong)b3 << 40) +
+ ((ulong)b4 << 32) + ((ulong)b5 << 24) +
+ ((ulong)b6 << 16) + ((ulong)b7 << 8) + b8);
+ }
+
+ /// <summary>
+ /// Write a uint64 at the current position
+ /// </summary>
+ /// <param name="value">Value to write</param>
+ /// <returns>This instance</returns>
+ public ByteBuffer Put(ulong value)
+ {
+ Put(Position, value);
+ Position += 8;
+ return this;
+ }
+
+ /// <summary>
+ /// Write a uint64 at the specified position
+ /// </summary>
+ /// <param name="position">Position to write to</param>
+ /// <param name="value">Value to write</param>
+ /// <returns>This instance</returns>
+ public ByteBuffer Put(int position, ulong value)
+ {
+ CheckSpaceForWriting(position, 8);
+ Write(position, (byte)(value >> 56));
+ Write(position + 1, (byte)(value >> 48));
+ Write(position + 2, (byte)(value >> 40));
+ Write(position + 3, (byte)(value >> 32));
+ Write(position + 4, (byte)(value >> 24));
+ Write(position + 5, (byte)(value >> 16));
+ Write(position + 6, (byte)(value >> 8));
+ Write(position + 7, (byte)(value));
+ return this;
+ }
+
+ // Int64 Stuff
+
+ /// <summary>
+ /// Read the next int64 in the buffer
+ /// </summary>
+ /// <returns>The next int64 available</returns>
+ public long GetInt64()
+ {
+ return (long)GetUInt64();
+ }
+ /// <summary>
+ /// Read the int64 at the specified position
+ /// </summary>
+ /// <param name="position">Position to read from</param>
+ /// <returns>The value at the position</returns>
+ public long GetInt64(int position)
+ {
+ return (long)GetUInt64(position);
+ }
+
+ /// <summary>
+ /// Write a int64 at the current position
+ /// </summary>
+ /// <param name="value">Value to write</param>
+ /// <returns>This instance</returns>
+ public ByteBuffer Put(long value)
+ {
+ return Put((ulong)value);
+ }
+
+ /// <summary>
+ /// Write a int64 at the specified position
+ /// </summary>
+ /// <param name="position">Position to write to</param>
+ /// <param name="value">Value to write</param>
+ /// <returns>This instance</returns>
+ public ByteBuffer Put(int position, long value)
+ {
+ return Put(position, (ulong)value);
+ }
+
+
+ // Float Stuff
+
+ /// <summary>
+ /// Read the next float in the buffer
+ /// </summary>
+ /// <returns>The next float available</returns>
+ public float GetFloat()
+ {
+ unsafe
+ {
+ uint val = GetUInt32();
+ return *((float*)&val);
+ }
+ }
+ /// <summary>
+ /// Read the float at the specified position
+ /// </summary>
+ /// <param name="position">Position to read from</param>
+ /// <returns>The value at the position</returns>
+ public float GetFloat(int position)
+ {
+ unsafe
+ {
+ uint val = GetUInt32(position);
+ return *((float*)&val);
+ }
+ }
+
+ /// <summary>
+ /// Write a float at the current position
+ /// </summary>
+ /// <param name="value">Value to write</param>
+ /// <returns>This instance</returns>
+ public ByteBuffer Put(float value)
+ {
+ unsafe
+ {
+ uint val = *((uint*)&value);
+ return Put(val);
+ }
+ }
+
+ /// <summary>
+ /// Write a float at the specified position
+ /// </summary>
+ /// <param name="position">Position to write to</param>
+ /// <param name="value">Value to write</param>
+ /// <returns>This instance</returns>
+ public ByteBuffer Put(int position, float value)
+ {
+ unsafe
+ {
+ uint val = *((uint*)&value);
+ return Put(position, val);
+ }
+ }
+
+ // Double Stuff
+
+ /// <summary>
+ /// Read the next double in the buffer
+ /// </summary>
+ /// <returns>The next double available</returns>
+ public double GetDouble()
+ {
+ unsafe
+ {
+ ulong val = GetUInt64();
+ return *((double*)&val);
+ }
+ }
+ /// <summary>
+ /// Read the double at the specified position
+ /// </summary>
+ /// <param name="position">Position to read from</param>
+ /// <returns>The value at the position</returns>
+ public double GetDouble(int position)
+ {
+ unsafe
+ {
+ ulong val = GetUInt64(position);
+ return *((double*)&val);
+ }
+ }
+
+ /// <summary>
+ /// Write a double at the current position
+ /// </summary>
+ /// <param name="value">Value to write</param>
+ /// <returns>This instance</returns>
+ public ByteBuffer Put(double value)
+ {
+ unsafe
+ {
+ ulong val = *((ulong*)&value);
+ return Put(val);
+ }
+ }
+
+ /// <summary>
+ /// Write a double at the specified position
+ /// </summary>
+ /// <param name="position">Position to write to</param>
+ /// <param name="value">Value to write</param>
+ /// <returns>This instance</returns>
+ public ByteBuffer Put(int position, double value)
+ {
+ unsafe
+ {
+ ulong val = *((ulong*)&value);
+ return Put(position, val);
+ }
+ }
+
+ // Char Stuff
+
+ /// <summary>
+ /// Read the next char in the buffer
+ /// </summary>
+ /// <returns>The next char available</returns>
+ public char GetChar()
+ {
+ return (char)GetUInt16();
+ }
+ /// <summary>
+ /// Read the char at the specified position
+ /// </summary>
+ /// <param name="position">Position to read from</param>
+ /// <returns>The value at the position</returns>
+ public char GetChar(int position)
+ {
+ return (char)GetUInt16(position);
+ }
+
+ /// <summary>
+ /// Write a char at the current position
+ /// </summary>
+ /// <param name="value">Value to write</param>
+ /// <returns>This instance</returns>
+ public ByteBuffer Put(char value)
+ {
+ return Put((ushort) value);
+ }
+
+ /// <summary>
+ /// Write a char at the specified position
+ /// </summary>
+ /// <param name="position">Position to write to</param>
+ /// <param name="value">Value to write</param>
+ /// <returns>This instance</returns>
+ public ByteBuffer Put(int position, char value)
+ {
+ return Put(position, (ushort)value);
+ }
+
+ // Byte[] stuff
+
+ public void GetBytes(byte[] buffer)
+ {
+ GetBytes(buffer, 0, buffer.Length);
+ }
+
+ public void GetBytes(byte[] buffer, int offset, int length)
+ {
+ GetBytes(Position, buffer, offset, length);
+ Position += length;
+ }
+ public void GetBytes(int position, byte[] buffer, int offset, int length)
+ {
+ CheckSpaceForReading(position, length);
+ if ( offset + length > buffer.Length )
+ throw new ArgumentException("Invalid offset + length");
+ ReadBytes(position, buffer, offset, length);
+ }
+
+ public ByteBuffer Put(byte[] buffer)
+ {
+ return Put(buffer, 0, buffer.Length);
+ }
+
+ public ByteBuffer Put(byte[] buffer, int offset, int length)
+ {
+ Put(Position, buffer, offset, length);
+ Position += length;
+ return this;
+ }
+
+ public ByteBuffer Put(int position, byte[] buffer, int offset, int length)
+ {
+ CheckSpaceForWriting(position, length);
+ if ( offset + length > buffer.Length )
+ throw new ArgumentException("Invalid offset + length");
+
+ Write(position, buffer, offset, length);
+ return this;
+ }
+
+ public ByteBuffer Put(ByteBuffer data)
+ {
+ Put(Position, data);
+ Position += data.Remaining;
+ return this;
+ }
+
+ public ByteBuffer Put(int position, ByteBuffer data)
+ {
+ CheckSpaceForWriting(position, data.Remaining);
+ Write(position, data.Array, data.Position, data.Remaining);
+ return this;
+ }
+
+ #endregion // Data Accessors
+
+ #region Core Overrides
+ //
+ // Core Overrides
+ //
+
+ protected abstract void DoWrite(int position, byte value);
+ protected abstract void DoWrite(int position, byte[] src, int offset, int length);
+ protected abstract byte DoReadByte(int position);
+ protected abstract void DoReadBytes(int position, byte[] dest, int offset, int length);
+ protected abstract void DoCompact();
+ protected abstract void DoResize(int newSize);
+
+ #endregion // Core Overrides
+
+ #region Private Methods
+ //
+ // Private Methods
+ //
+
+ private void Seek(int offset)
+ {
+ if ( offset > Capacity )
+ throw new ArgumentException("Cannot position beyond end of buffer");
+ _position = offset;
+ AdjustLimit();
+ }
+
+ private void SetLimit(int newLimit)
+ {
+ if ( newLimit < 0 )
+ throw new ArgumentOutOfRangeException("The new limit must be a positive value");
+ if ( newLimit > Capacity )
+ throw new ArgumentOutOfRangeException("The new limit must not be greater than the capacity");
+ _limit = newLimit;
+ if ( _position > newLimit )
+ _position = newLimit;
+ }
+
+ private void AdjustLimit()
+ {
+ if ( _limit < _position )
+ _limit = _position;
+ }
+
+ private void CheckSpaceForReading(int position, int length)
+ {
+ if ( position + length > Limit )
+ {
+ throw new BufferUnderflowException("Attempt to read " + length + " byte(s) to buffer where position is " + position +
+ " and limit is " + Limit);
+ }
+ }
+
+ private void CheckSpaceForWriting(int position, int length)
+ {
+ if ( IsAutoExpand )
+ {
+ Expand(position, length);
+ }
+ if ( position + length > Limit )
+ {
+ throw new BufferOverflowException("Attempt to write " + length + " byte(s) to buffer where position is " + position +
+ " and limit is " + Limit);
+ }
+ }
+
+ private void Write(int position, byte value)
+ {
+ DoWrite(position, value);
+ }
+ private void Write(int position, byte[] src, int offset, int length)
+ {
+ DoWrite(position, src, offset, length);
+ }
+ private byte ReadByte(int position)
+ {
+ return DoReadByte(position);
+ }
+ private void ReadBytes(int position, byte[] dest, int offset, int length)
+ {
+ DoReadBytes(position, dest, offset, length);
+ }
+
+ #endregion // Private Methods
+
+ } // class ByteBuffer
+}
diff --git a/qpid/dotnet/Qpid.Buffer/ByteBufferHexDumper.cs b/qpid/dotnet/Qpid.Buffer/ByteBufferHexDumper.cs
new file mode 100644
index 0000000000..4c2856c333
--- /dev/null
+++ b/qpid/dotnet/Qpid.Buffer/ByteBufferHexDumper.cs
@@ -0,0 +1,79 @@
+/*
+ *
+ * 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.
+ *
+ */
+using System.Text;
+
+namespace Apache.Qpid.Buffer
+{
+ public class ByteBufferHexDumper
+ {
+ private static byte[] highDigits;
+
+ private static byte[] lowDigits;
+
+ static ByteBufferHexDumper()
+ {
+ byte[] digits = { (byte)'0', (byte)'1', (byte)'2', (byte)'3', (byte)'4', (byte)'5', (byte)'6',
+ (byte)'7', (byte)'8', (byte)'9', (byte)'A', (byte)'B', (byte)'C', (byte)'D',
+ (byte)'E', (byte)'F' };
+ int i;
+ byte[] high = new byte[256];
+ byte[] low = new byte[256];
+
+ for (i = 0; i < 256; i++)
+ {
+ high[i] = digits[i >> 4];
+ low[i] = digits[i & 0x0F];
+ }
+
+ highDigits = high;
+ lowDigits = low;
+ }
+
+ public static string GetHexDump(ByteBuffer input)
+ {
+ int size = input.Remaining;
+ if (size == 0)
+ {
+ return "empty";
+ }
+
+ StringBuilder output = new StringBuilder(size * 3 - 1);
+
+ byte[] data = input.Array;
+ int byteValue = data[0] & 0xFF;
+ output.Append((char) highDigits[byteValue]);
+ output.Append((char) lowDigits[byteValue]);
+
+ for (int i = 1 ; i < size; i++)
+ {
+ output.Append(' ');
+ byteValue = data[i] & 0xFF;
+ output.Append((char) highDigits[byteValue]);
+ output.Append((char) lowDigits[byteValue]);
+ }
+
+ return output.ToString();
+ }
+ }
+}
+
+
+
diff --git a/qpid/dotnet/Qpid.Buffer/IByteBufferAllocator.cs b/qpid/dotnet/Qpid.Buffer/IByteBufferAllocator.cs
new file mode 100644
index 0000000000..74944f7e69
--- /dev/null
+++ b/qpid/dotnet/Qpid.Buffer/IByteBufferAllocator.cs
@@ -0,0 +1,50 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+using System;
+
+namespace Apache.Qpid.Buffer
+{
+ /// <summary>
+ /// Allocates <see cref="ByteBuffer"/>'s and manages them. Please
+ /// implement this interface if you need more advanced memory management scheme
+ /// </summary>
+ public interface IByteBufferAllocator : IDisposable
+ {
+ /// <summary>
+ /// Returns the buffer which is capable of the specified size.
+ /// </summary>
+ /// <param name="capacity">The capacity of the buffer</param>
+ /// <returns>A new buffer</returns>
+ ByteBuffer Allocate(int capacity);
+
+ /// <summary>
+ /// Wrap the specified byte array in a new buffer
+ /// </summary>
+ /// <param name="src">Source array</param>
+ /// <returns>A new buffer</returns>
+ ByteBuffer Wrap(byte[] src);
+
+ } // interface IByteBufferAllocator
+}
+
+
+
diff --git a/qpid/dotnet/Qpid.Buffer/Properties/AssemblyInfo.cs b/qpid/dotnet/Qpid.Buffer/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000000..b692af7ce5
--- /dev/null
+++ b/qpid/dotnet/Qpid.Buffer/Properties/AssemblyInfo.cs
@@ -0,0 +1,53 @@
+/*
+ *
+ * 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.
+ *
+ */
+using System.Reflection;
+using System.Runtime.InteropServices;
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("Apache.Qpid.ByteBuffer")]
+[assembly: AssemblyDescription("Built from svn revision number: ")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Apache Software Foundation")]
+[assembly: AssemblyProduct("Apache.Qpid.ByteBuffer")]
+[assembly: AssemblyCopyright("Apache Software Foundation")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("2b3333e5-03b5-4f00-9215-66009f8a5c47")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Revision and Build Numbers
+// by using the '*' as shown below:
+[assembly: AssemblyVersion("0.5.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/qpid/dotnet/Qpid.Buffer/Qpid.Buffer.csproj b/qpid/dotnet/Qpid.Buffer/Qpid.Buffer.csproj
new file mode 100644
index 0000000000..d13f399196
--- /dev/null
+++ b/qpid/dotnet/Qpid.Buffer/Qpid.Buffer.csproj
@@ -0,0 +1,77 @@
+<!--
+
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+
+-->
+
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProductVersion>8.0.50727</ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{44384DF2-B0A4-4580-BDBC-EE4BAA87D995}</ProjectGuid>
+ <OutputType>Library</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>Apache.Qpid.Buffer</RootNamespace>
+ <AssemblyName>Apache.Qpid.Buffer</AssemblyName>
+ <SignAssembly>true</SignAssembly>
+ <AssemblyOriginatorKeyFile>
+ </AssemblyOriginatorKeyFile>
+ <FileUpgradeFlags>
+ </FileUpgradeFlags>
+ <OldToolsVersion>2.0</OldToolsVersion>
+ <UpgradeBackupLocation>
+ </UpgradeBackupLocation>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>..\bin\net-2.0\debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>..\bin\net-2.0\release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="System" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="**\*.cs" />
+ </ItemGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+ <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
+ Other similar extension points exist, see Microsoft.Common.targets.
+ <Target Name="BeforeBuild">
+ </Target>
+ <Target Name="AfterBuild">
+ </Target>
+ -->
+</Project>
diff --git a/qpid/dotnet/Qpid.Buffer/SimpleByteBuffer.cs b/qpid/dotnet/Qpid.Buffer/SimpleByteBuffer.cs
new file mode 100644
index 0000000000..956c59aa45
--- /dev/null
+++ b/qpid/dotnet/Qpid.Buffer/SimpleByteBuffer.cs
@@ -0,0 +1,120 @@
+/*
+ *
+ * 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.
+ *
+ */
+using System;
+
+namespace Apache.Qpid.Buffer
+{
+ internal sealed class SimpleByteBuffer : ByteBuffer
+ {
+ private byte[] _buffer;
+
+ public override int Capacity
+ {
+ get { return _buffer.Length; }
+ }
+
+ public override byte[] Array
+ {
+ get { return _buffer; }
+ }
+
+ /// <summary>
+ /// Initialize a new instance with the desired size
+ /// </summary>
+ /// <param name="desiredSize">Initial Length of the array</param>
+ internal SimpleByteBuffer(int desiredSize)
+ {
+ _buffer = new byte[desiredSize];
+ Position = 0;
+ Limit = Capacity;
+ }
+
+ /// <summary>
+ /// Initialize a new instance with the data from
+ /// an underlying array
+ /// </summary>
+ /// <param name="buffer">Initial data</param>
+ /// <remarks>The original array is copied during construction and is not modified</remarks>
+ internal SimpleByteBuffer(byte[] buffer)
+ {
+ _buffer = (byte[])buffer.Clone();
+ // position at end
+ Position = Limit = Capacity;
+ }
+
+ protected override void DoWrite(int position, byte value)
+ {
+ // available space is already handled by base class
+ _buffer[position] = value;
+ }
+
+ protected override void DoWrite(int position, byte[] src, int offset, int length)
+ {
+ // available space is already handled by base class
+ for ( int i = 0; i < length; i++ )
+ {
+ _buffer[position+i] = src[offset+i];
+ }
+ }
+
+ protected override byte DoReadByte(int position)
+ {
+ return _buffer[position];
+ }
+
+ protected override void DoReadBytes(int position, byte[] dest, int offset, int length)
+ {
+ System.Array.Copy(_buffer, position, dest, offset, length);
+ }
+
+ protected override void DoCompact()
+ {
+ if ( Remaining > 0 )
+ {
+ if ( Position > 0 )
+ {
+ System.Array.Copy(_buffer, Position, _buffer, 0, Remaining);
+ }
+ Position = Remaining;
+ } else
+ {
+ Position = 0;
+ }
+ Limit = Capacity;
+ }
+
+ protected override void DoResize(int newSize)
+ {
+ if ( newSize < Capacity )
+ throw new NotSupportedException("Cannot resize a buffer to make it smaller");
+
+ int newCapacity = 1;
+ while ( newCapacity < newSize )
+ {
+ newCapacity <<= 1;
+ }
+
+ byte[] newBuffer = new byte[newCapacity];
+ System.Array.Copy(_buffer, newBuffer, _buffer.Length);
+ _buffer = newBuffer;
+ }
+ } // class SimpleByteBuffer
+}
diff --git a/qpid/dotnet/Qpid.Buffer/SimpleByteBufferAllocator.cs b/qpid/dotnet/Qpid.Buffer/SimpleByteBufferAllocator.cs
new file mode 100644
index 0000000000..e772e59ae3
--- /dev/null
+++ b/qpid/dotnet/Qpid.Buffer/SimpleByteBufferAllocator.cs
@@ -0,0 +1,58 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+namespace Apache.Qpid.Buffer
+{
+ /// <summary>
+ /// Allocates <see cref="ByteBuffer"/>'s and manages them.
+ /// This is a simple implementation that just returns buffers
+ /// as they are. Buffers are not reused or refcounted
+ /// </summary>
+ public class SimpleByteBufferAllocator : IByteBufferAllocator
+ {
+ #region IByteBufferAllocator Members
+
+ public ByteBuffer Allocate(int capacity)
+ {
+ return new SimpleByteBuffer(capacity);
+ }
+
+ public ByteBuffer Wrap(byte[] src)
+ {
+ return new SimpleByteBuffer(src);
+ }
+
+ #endregion
+
+ #region IDisposable Members
+
+ public void Dispose()
+ {
+ // no need to do anaything
+ }
+
+ #endregion
+
+ } // class SimpleByteBufferAllocator
+}
+
+
+
diff --git a/qpid/dotnet/Qpid.Buffer/SlicedByteBuffer.cs b/qpid/dotnet/Qpid.Buffer/SlicedByteBuffer.cs
new file mode 100644
index 0000000000..890e2a3c7a
--- /dev/null
+++ b/qpid/dotnet/Qpid.Buffer/SlicedByteBuffer.cs
@@ -0,0 +1,86 @@
+/*
+ *
+ * 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.
+ *
+ */
+using System;
+
+namespace Apache.Qpid.Buffer
+{
+ internal sealed class SlicedByteBuffer : ByteBuffer
+ {
+ private ByteBuffer _buffer;
+ private int _capacity;
+ private int _startPos;
+
+ public override int Capacity
+ {
+ get { return _capacity; }
+ }
+
+ public override byte[] Array
+ {
+ get { return _buffer.Array; }
+ }
+
+ /// <summary>
+ /// Initialize a new instance
+ /// </summary>
+ /// <param name="buffer">Underlying byte buffer</param>
+ internal SlicedByteBuffer(ByteBuffer buffer)
+ {
+ _buffer = buffer;
+ _startPos = buffer.Position;
+ Position = 0;
+ _capacity = buffer.Remaining;
+ Limit = Capacity;
+ // cannot autoexpand
+ IsAutoExpand = false;
+ }
+
+ protected override void DoWrite(int position, byte value)
+ {
+ _buffer.Put(_startPos + position, value);
+ }
+
+ protected override void DoWrite(int position, byte[] src, int offset, int length)
+ {
+ _buffer.Put(_startPos + position, src, offset, length);
+ }
+
+ protected override byte DoReadByte(int position)
+ {
+ return _buffer.GetByte(_startPos + position);
+ }
+
+ protected override void DoReadBytes(int position, byte[] dest, int offset, int length)
+ {
+ _buffer.GetBytes(_startPos + position, dest, offset, length);
+ }
+
+ protected override void DoCompact()
+ {
+ throw new NotSupportedException();
+ }
+
+ protected override void DoResize(int newSize)
+ {
+ throw new NotSupportedException();
+ }
+ } // class SlicedByteBuffer
+}
diff --git a/qpid/dotnet/Qpid.Buffer/default.build b/qpid/dotnet/Qpid.Buffer/default.build
new file mode 100644
index 0000000000..efb5a8fc89
--- /dev/null
+++ b/qpid/dotnet/Qpid.Buffer/default.build
@@ -0,0 +1,46 @@
+<?xml version="1.0"?>
+<!--
+
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+
+-->
+
+<project name="Apache.Qpid.Buffer" default="build">
+ <!--
+ Properties that come from master build file
+ - build.dir: root directory for build
+ - build.debug: true if building debug release
+ - build.defines: variables to define during build
+ -->
+
+ <target name="build">
+ <csc target="library"
+ define="${build.defines}"
+ debug="${build.debug}"
+ unsafe="true"
+ output="${build.dir}/${project::get-name()}.dll">
+
+ <sources>
+ <include name="**/*.cs" />
+ </sources>
+ <references>
+ </references>
+ </csc>
+ </target>
+</project>
+
diff --git a/qpid/dotnet/Qpid.Client.Tests/App.config b/qpid/dotnet/Qpid.Client.Tests/App.config
new file mode 100644
index 0000000000..e71a468a3a
--- /dev/null
+++ b/qpid/dotnet/Qpid.Client.Tests/App.config
@@ -0,0 +1,34 @@
+<?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.
+
+-->
+
+<configuration>
+ <configSections>
+ <sectionGroup name="qpid.client">
+ <section name="authentication" type="Apache.Qpid.Client.Configuration.AuthenticationConfigurationSectionHandler, Apache.Qpid.Client"/>
+ </sectionGroup>
+ </configSections>
+ <qpid.client>
+ <authentication>
+ <add key="TEST" value="Apache.Qpid.Client.Tests.Security.TestCallbackHandler, Apache.Qpid.Client.Tests"/>
+ </authentication>
+ </qpid.client>
+</configuration>
diff --git a/qpid/dotnet/Qpid.Client.Tests/BrokerDetails/BrokerDetailsTest.cs b/qpid/dotnet/Qpid.Client.Tests/BrokerDetails/BrokerDetailsTest.cs
new file mode 100644
index 0000000000..56269c0f9d
--- /dev/null
+++ b/qpid/dotnet/Qpid.Client.Tests/BrokerDetails/BrokerDetailsTest.cs
@@ -0,0 +1,65 @@
+/*
+ *
+ * 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.
+ *
+ */
+using System;
+using System.Net;
+using NUnit.Framework;
+using Apache.Qpid.Client.Qms;
+
+namespace Apache.Qpid.Client.Tests.BrokerDetails
+{
+ [TestFixture]
+ public class BrokerDetailsTest
+ {
+
+ [Test]
+ public void ValidateBrokerInfoEqualsMethod()
+ {
+ AmqBrokerInfo broker = new AmqBrokerInfo("amqp", "localhost", 5672, true);
+ AmqBrokerInfo broker1 = new AmqBrokerInfo("Amqp", "localhost", 5672, true);
+
+ Assert.IsTrue(broker.Equals(broker1),"The two AmqBrokerInfo objects are not equals");
+ Console.WriteLine(string.Format("The object broker: {0} and broker1: {1} are equals", broker, broker1));
+ }
+
+ [Test]
+ public void ValidateBrokerInfoWithDifferentSSL()
+ {
+ AmqBrokerInfo broker = new AmqBrokerInfo("amqp", "localhost", 5672, true);
+ AmqBrokerInfo broker1 = new AmqBrokerInfo("amqp", "localhost", 5672, false);
+
+ Assert.IsFalse(broker.Equals(broker1), "The two AmqBrokerInfo objects are equals");
+ Console.WriteLine(string.Format("The object broker: {0} and broker1: {1} are not equals", broker, broker1));
+ }
+
+ [Test]
+ public void ValidateBrokerInfoFromToString()
+ {
+ String url = "tcp://localhost:5672?timeout='200',immediatedelivery='true'";
+
+ AmqBrokerInfo broker = new AmqBrokerInfo(url);
+ AmqBrokerInfo broker1 = new AmqBrokerInfo(broker.ToString());
+
+ Assert.AreEqual(broker.GetOption("timeout"), broker1.GetOption("timeout"));
+ Assert.AreEqual(broker.GetOption("immediatedelivery"), broker1.GetOption("immediatedelivery"));
+ }
+
+ }
+}
diff --git a/qpid/dotnet/Qpid.Client.Tests/Channel/ChannelMessageCreationTests.cs b/qpid/dotnet/Qpid.Client.Tests/Channel/ChannelMessageCreationTests.cs
new file mode 100644
index 0000000000..f4f217c2a0
--- /dev/null
+++ b/qpid/dotnet/Qpid.Client.Tests/Channel/ChannelMessageCreationTests.cs
@@ -0,0 +1,79 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+using System;
+
+using log4net;
+using NUnit.Framework;
+using Apache.Qpid.Client;
+using Apache.Qpid.Client.Message;
+using Apache.Qpid.Messaging;
+
+namespace Apache.Qpid.Client.Tests.Channel
+{
+ /// <summary>
+ /// Test that channels can create messages correctly
+ /// </summary>
+ [TestFixture]
+ public class ChannelMessageCreationTests
+ {
+ [Test]
+ public void CanCreateTextMessage()
+ {
+ IChannel channel = AmqChannel.CreateDisconnectedChannel();
+ ITextMessage msg = channel.CreateTextMessage();
+ Assert.IsNotNull(msg);
+ }
+ [Test]
+ public void CanCreateTextMessageWithContent()
+ {
+ IChannel channel = AmqChannel.CreateDisconnectedChannel();
+ const string CONTENT = "1234567890";
+ ITextMessage msg = channel.CreateTextMessage(CONTENT);
+ Assert.IsNotNull(msg);
+ Assert.AreEqual(CONTENT, msg.Text);
+ }
+ [Test]
+ public void CanCreateBytesMessage()
+ {
+ IChannel channel = AmqChannel.CreateDisconnectedChannel();
+ IBytesMessage msg = channel.CreateBytesMessage();
+ Assert.IsNotNull(msg);
+ }
+ [Test]
+ public void CanCreateMessage()
+ {
+ IChannel channel = AmqChannel.CreateDisconnectedChannel();
+ IMessage msg = channel.CreateMessage();
+ Assert.IsNotNull(msg);
+ }
+ [Test]
+ public void CanCreateMessageFromMimeType()
+ {
+ IChannel channel = AmqChannel.CreateDisconnectedChannel();
+ IMessage msg = channel.CreateMessage("text/xml");
+ Assert.IsNotNull(msg);
+ Assert.IsInstanceOfType(typeof(ITextMessage), msg);
+ }
+ }
+} // namespace Apache.Qpid.Client.Tests.Channel
+
+
diff --git a/qpid/dotnet/Qpid.Client.Tests/Messages/MessageFactoryRegistryTests.cs b/qpid/dotnet/Qpid.Client.Tests/Messages/MessageFactoryRegistryTests.cs
new file mode 100644
index 0000000000..4db3c91cb5
--- /dev/null
+++ b/qpid/dotnet/Qpid.Client.Tests/Messages/MessageFactoryRegistryTests.cs
@@ -0,0 +1,114 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+using System;
+
+using log4net;
+using NUnit.Framework;
+using Apache.Qpid.Messaging;
+using Apache.Qpid.Client.Message;
+
+namespace Apache.Qpid.Client.Tests.Messages
+{
+ /// <summary>
+ /// Ensure a factory creates messages correctly
+ /// </summary>
+ [TestFixture]
+ public class MessageFactoryRegistryTests
+ {
+ const string TEXT_PLAIN = "text/plain";
+ const string TEXT_XML = "text/xml";
+ const string OCTET_STREAM = "application/octet-stream";
+
+ /// <summary>
+ /// Check default registry can create text/plain messages
+ /// </summary>
+ [Test]
+ public void CanCreateTextPlain()
+ {
+ MessageFactoryRegistry registry =
+ MessageFactoryRegistry.NewDefaultRegistry();
+
+ IMessage message = registry.CreateMessage(TEXT_PLAIN);
+ Assert.IsNotNull(message);
+ Assert.AreEqual(TEXT_PLAIN, message.ContentType);
+ Assert.IsInstanceOfType(typeof(QpidTextMessage), message);
+ }
+ /// <summary>
+ /// Check default registry can create text/xml messages
+ /// </summary>
+ [Test]
+ public void CanCreateTextXml()
+ {
+ MessageFactoryRegistry registry =
+ MessageFactoryRegistry.NewDefaultRegistry();
+
+ IMessage message = registry.CreateMessage(TEXT_XML);
+ Assert.IsNotNull(message);
+ Assert.AreEqual(TEXT_XML, message.ContentType);
+ Assert.IsInstanceOfType(typeof(QpidTextMessage), message);
+ }
+ /// <summary>
+ /// Check default registry can create application/octet-stream messages
+ /// </summary>
+ [Test]
+ public void CanCreateBinary()
+ {
+ MessageFactoryRegistry registry =
+ MessageFactoryRegistry.NewDefaultRegistry();
+
+ IMessage message = registry.CreateMessage(OCTET_STREAM);
+ Assert.IsNotNull(message);
+ Assert.AreEqual(OCTET_STREAM, message.ContentType);
+ Assert.IsInstanceOfType(typeof(QpidBytesMessage), message);
+ }
+ /// <summary>
+ /// Check default registry can create messages for unknown types
+ /// </summary>
+ [Test]
+ public void CanCreateUnknownType()
+ {
+ MessageFactoryRegistry registry =
+ MessageFactoryRegistry.NewDefaultRegistry();
+
+ const string OTHER = "application/unknown";
+ IMessage message = registry.CreateMessage(OTHER);
+ Assert.IsNotNull(message);
+ Assert.AreEqual(OTHER, message.ContentType);
+ Assert.IsInstanceOfType(typeof(QpidBytesMessage), message);
+ }
+ /// <summary>
+ /// Check that text messages default to UTF-8 encoding
+ /// </summary>
+ [Test]
+ public void TextMessagesDefaultToUTF8Encoding()
+ {
+ MessageFactoryRegistry registry =
+ MessageFactoryRegistry.NewDefaultRegistry();
+
+ IMessage message = registry.CreateMessage(TEXT_PLAIN);
+ Assert.AreEqual("utf-8", message.ContentEncoding.ToLower());
+ }
+
+ }
+} // namespace Apache.Qpid.Client.Tests.Messages
+
+
diff --git a/qpid/dotnet/Qpid.Client.Tests/Properties/AssemblyInfo.cs b/qpid/dotnet/Qpid.Client.Tests/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000000..c710818053
--- /dev/null
+++ b/qpid/dotnet/Qpid.Client.Tests/Properties/AssemblyInfo.cs
@@ -0,0 +1,53 @@
+/*
+ *
+ * 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.
+ *
+ */
+using System.Reflection;
+using System.Runtime.InteropServices;
+using log4net.Config;
+[assembly: XmlConfigurator(ConfigFile="log4net.config")]
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("Apache.Qpid.Client.Tests")]
+[assembly: AssemblyDescription("Built from svn revision number: ")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Apache Software Foundation")]
+[assembly: AssemblyProduct("Apache.Qpid.Client.Tests")]
+[assembly: AssemblyCopyright("Apache Software Foundation")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("7ebdea21-1352-4673-b66e-fdc0beff461f")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+[assembly: AssemblyVersion("0.5.0.0")]
diff --git a/qpid/dotnet/Qpid.Client.Tests/Qpid.Client.Tests.csproj b/qpid/dotnet/Qpid.Client.Tests/Qpid.Client.Tests.csproj
new file mode 100644
index 0000000000..73eabfa1f8
--- /dev/null
+++ b/qpid/dotnet/Qpid.Client.Tests/Qpid.Client.Tests.csproj
@@ -0,0 +1,158 @@
+<!--
+
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+
+-->
+
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProductVersion>9.0.30729</ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{BA1B0032-4CE6-40DD-A2DC-119F0FFA0A1D}</ProjectGuid>
+ <OutputType>Library</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>Apache.Qpid.Client.Tests</RootNamespace>
+ <AssemblyName>Apache.Qpid.Client.Tests</AssemblyName>
+ <StartupObject>
+ </StartupObject>
+ <FileUpgradeFlags>
+ </FileUpgradeFlags>
+ <OldToolsVersion>2.0</OldToolsVersion>
+ <UpgradeBackupLocation>
+ </UpgradeBackupLocation>
+ <PublishUrl>http://localhost/Apache.Qpid.Client.Tests/</PublishUrl>
+ <Install>true</Install>
+ <InstallFrom>Web</InstallFrom>
+ <UpdateEnabled>true</UpdateEnabled>
+ <UpdateMode>Foreground</UpdateMode>
+ <UpdateInterval>7</UpdateInterval>
+ <UpdateIntervalUnits>Days</UpdateIntervalUnits>
+ <UpdatePeriodically>false</UpdatePeriodically>
+ <UpdateRequired>false</UpdateRequired>
+ <MapFileExtensions>true</MapFileExtensions>
+ <ApplicationRevision>0</ApplicationRevision>
+ <ApplicationVersion>1.0.0.%2a</ApplicationVersion>
+ <IsWebBootstrapper>true</IsWebBootstrapper>
+ <UseApplicationTrust>false</UseApplicationTrust>
+ <BootstrapperEnabled>true</BootstrapperEnabled>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>..\bin\net-2.0\debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ <UseVSHostingProcess>true</UseVSHostingProcess>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>..\bin\net-2.0\release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="log4net, Version=1.2.9.0, Culture=neutral, PublicKeyToken=b32731d11ce58905">
+ <SpecificVersion>False</SpecificVersion>
+ <HintPath>..\Qpid.Common\lib\log4net\log4net.dll</HintPath>
+ </Reference>
+ <Reference Include="nunit.framework, Version=2.2.6.0, Culture=neutral, PublicKeyToken=96d09a1eb7f44a77">
+ <SpecificVersion>False</SpecificVersion>
+ <HintPath>lib\nunit\nunit.framework.dll</HintPath>
+ </Reference>
+ <Reference Include="System" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="**\*.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\Qpid.Buffer\Qpid.Buffer.csproj">
+ <Project>{44384DF2-B0A4-4580-BDBC-EE4BAA87D995}</Project>
+ <Name>Qpid.Buffer</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\Qpid.Messaging\Qpid.Messaging.csproj">
+ <Project>{6688F826-C58E-4C1B-AA1F-22AFAB4B7D07}</Project>
+ <Name>Qpid.Messaging</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\Qpid.Client\Qpid.Client.csproj">
+ <Project>{68987C05-3768-452C-A6FC-6BA1D372852F}</Project>
+ <Name>Qpid.Client</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\Qpid.Common\Qpid.Common.csproj">
+ <Project>{77064C42-24D2-4CEB-9EA2-0EF481A43205}</Project>
+ <Name>Qpid.Common</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\Qpid.Sasl\Qpid.Sasl.csproj">
+ <Project>{1465B0EE-6452-42A6-AB73-B2F9EABEEE75}</Project>
+ <Name>Qpid.Sasl</Name>
+ </ProjectReference>
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="log4net.config">
+ <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+ </None>
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="App.config" />
+ </ItemGroup>
+ <ItemGroup>
+ <BootstrapperPackage Include="Microsoft.Net.Client.3.5">
+ <Visible>False</Visible>
+ <ProductName>.NET Framework Client Profile</ProductName>
+ <Install>false</Install>
+ </BootstrapperPackage>
+ <BootstrapperPackage Include="Microsoft.Net.Framework.2.0">
+ <Visible>False</Visible>
+ <ProductName>.NET Framework 2.0 %28x86%29</ProductName>
+ <Install>true</Install>
+ </BootstrapperPackage>
+ <BootstrapperPackage Include="Microsoft.Net.Framework.3.0">
+ <Visible>False</Visible>
+ <ProductName>.NET Framework 3.0 %28x86%29</ProductName>
+ <Install>false</Install>
+ </BootstrapperPackage>
+ <BootstrapperPackage Include="Microsoft.Net.Framework.3.5">
+ <Visible>False</Visible>
+ <ProductName>.NET Framework 3.5</ProductName>
+ <Install>false</Install>
+ </BootstrapperPackage>
+ <BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
+ <Visible>False</Visible>
+ <ProductName>.NET Framework 3.5 SP1</ProductName>
+ <Install>false</Install>
+ </BootstrapperPackage>
+ </ItemGroup>
+ <ItemGroup>
+ <Folder Include="interop\TestCases\" />
+ </ItemGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+ <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
+ Other similar extension points exist, see Microsoft.Common.targets.
+ <Target Name="BeforeBuild">
+ </Target>
+ <Target Name="AfterBuild">
+ </Target>
+ -->
+</Project>
diff --git a/qpid/dotnet/Qpid.Client.Tests/Security/CallbackHandlerRegistryTests.cs b/qpid/dotnet/Qpid.Client.Tests/Security/CallbackHandlerRegistryTests.cs
new file mode 100644
index 0000000000..f1446a9aa6
--- /dev/null
+++ b/qpid/dotnet/Qpid.Client.Tests/Security/CallbackHandlerRegistryTests.cs
@@ -0,0 +1,66 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+using System;
+using NUnit.Framework;
+using Apache.Qpid.Client.Security;
+
+
+namespace Apache.Qpid.Client.Tests.Security
+{
+ [TestFixture]
+ public class CallbackRegistryHandlerTests
+ {
+ [Test]
+ public void ParsesConfiguration()
+ {
+ CallbackHandlerRegistry registry = CallbackHandlerRegistry.Instance;
+ Assert.AreEqual(4, registry.Mechanisms.Length);
+ Assert.Contains("TEST", registry.Mechanisms);
+
+ Type handlerType = registry.GetCallbackHandler("TEST");
+ Assert.IsNotNull(handlerType);
+ Assert.AreEqual(typeof(TestCallbackHandler), handlerType);
+ }
+
+ [Test]
+ public void MechanimsInOrder()
+ {
+ CallbackHandlerRegistry registry = CallbackHandlerRegistry.Instance;
+ Assert.AreEqual(4, registry.Mechanisms.Length);
+ Assert.AreEqual("TEST", registry.Mechanisms[0]);
+ Assert.AreEqual("EXTERNAL", registry.Mechanisms[1]);
+ Assert.AreEqual("CRAM-MD5", registry.Mechanisms[2]);
+ Assert.AreEqual("PLAIN", registry.Mechanisms[3]);
+ }
+ } // class CallbackRegistryHandlerTests
+
+ public class TestCallbackHandler : IAMQCallbackHandler
+ {
+ public void Initialize(Qpid.Client.Protocol.AMQProtocolSession session)
+ {
+ }
+ public void Handle(Qpid.Sasl.ISaslCallback[] callbacks)
+ {
+ }
+
+ } // class TestCallbackHandler
+
+} // namespace Apache.Qpid.Client.Tests.Connection
diff --git a/qpid/dotnet/Qpid.Client.Tests/default.build b/qpid/dotnet/Qpid.Client.Tests/default.build
new file mode 100644
index 0000000000..5116e651e1
--- /dev/null
+++ b/qpid/dotnet/Qpid.Client.Tests/default.build
@@ -0,0 +1,64 @@
+<?xml version="1.0"?>
+<!--
+
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+
+-->
+
+<project name="Apache.Qpid.Client" default="test">
+
+ <target name="build">
+ <csc target="library"
+ define="${build.defines}"
+ warnaserror="false" debug="${build.debug}"
+ output="${build.dir}/${project::get-name()}.Tests.dll">
+
+ <sources>
+ <include name="**/*.cs" />
+ </sources>
+ <references>
+ <include name="${build.dir}/log4net.dll" />
+ <include name="${build.dir}/nunit.framework.dll" />
+ <include name="${build.dir}/${project::get-name()}.dll" />
+ <include name="${build.dir}/Apache.Qpid.Common.dll" />
+ <include name="${build.dir}/Apache.Qpid.Messaging.dll" />
+ <include name="${build.dir}/Apache.Qpid.Sasl.dll" />
+ </references>
+ </csc>
+ <copy tofile="${build.dir}/${project::get-name()}.Tests.dll.config" file="App.config" />
+ <copy todir="${build.dir}" file="log4net.config"/>
+ </target>
+
+ <target name="test" depends="build">
+ <nunit2 verbose="true">
+ <formatter type="${nant.formatter}" usefile="false" />
+ <test>
+ <assemblies>
+ <include name="${build.dir}/${project::get-name()}.tests.dll"/>
+ </assemblies>
+ <categories>
+ <!-- The fail-over tests are interactive so should not be run as part of the build. -->
+ <exclude name="Integration"/>
+ <exclude name="SSL" if="${framework::get-target-framework() == 'mono-2.0'}"/>
+ </categories>
+ </test>
+ </nunit2>
+ </target>
+
+</project>
+
diff --git a/qpid/dotnet/Qpid.Client.Tests/interop/TopicListener.cs b/qpid/dotnet/Qpid.Client.Tests/interop/TopicListener.cs
new file mode 100644
index 0000000000..b355abb28d
--- /dev/null
+++ b/qpid/dotnet/Qpid.Client.Tests/interop/TopicListener.cs
@@ -0,0 +1,211 @@
+/*
+ *
+ * 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.
+ *
+ */
+using System;
+using log4net;
+using Apache.Qpid.Messaging;
+using Apache.Qpid.Client.Qms;
+
+namespace Apache.Qpid.Client.Tests.interop
+{
+ public class TopicListener
+ {
+ private static ILog log = LogManager.GetLogger(typeof(TopicListener));
+
+ /// <summary> The default AMQ connection URL to use for tests. </summary>
+ const string DEFAULT_URI = "amqp://guest:guest@default/test?brokerlist='tcp://localhost:5672'";
+
+ /// <summary> Holds the routing key for the topic to receive test messages on. </summary>
+ public static string CONTROL_ROUTING_KEY = "topic_control";
+
+ /// <summary> Holds the routing key for the queue to send reports to. </summary>
+ public static string RESPONSE_ROUTING_KEY = "response";
+
+ /// <summary> Holds the connection to listen on. </summary>
+ private IConnection connection;
+
+ /// <summary> Holds the channel for all test messages.</summary>
+ private IChannel channel;
+
+ /// <summary> Holds the producer to send report messages on. </summary>
+ private IMessagePublisher publisher;
+
+ /// <summary> Holds a flag to indicate that a timer has begun on the first message. Reset when report is sent. </summary> */
+ private bool init;
+
+ /// <summary> Holds the count of messages received by this listener. </summary> */
+ private int count;
+
+ /// <summary> Creates a topic listener using the specified broker URL. </summary>
+ ///
+ /// <param name="connectionUri">The broker URL to listen on.</param>
+ TopicListener(string connectionUri)
+ {
+ log.Debug("TopicListener(string connectionUri = " + connectionUri + "): called");
+
+ // Create a connection to the broker.
+ IConnectionInfo connectionInfo = QpidConnectionInfo.FromUrl(connectionUri);
+ connection = new AMQConnection(connectionInfo);
+
+ // Establish a session on the broker.
+ channel = connection.CreateChannel(false, AcknowledgeMode.AutoAcknowledge, 1);
+
+ // Set up a queue to listen for test messages on.
+ string topicQueueName = channel.GenerateUniqueName();
+ channel.DeclareQueue(topicQueueName, false, true, true);
+
+ // Set this listener up to listen for incoming messages on the test topic queue.
+ channel.Bind(topicQueueName, ExchangeNameDefaults.TOPIC, CONTROL_ROUTING_KEY);
+ IMessageConsumer consumer = channel.CreateConsumerBuilder(topicQueueName)
+ .Create();
+ consumer.OnMessage += new MessageReceivedDelegate(OnMessage);
+
+ // Set up this listener with a producer to send the reports on.
+ publisher = channel.CreatePublisherBuilder()
+ .WithExchangeName(ExchangeNameDefaults.DIRECT)
+ .WithRoutingKey(RESPONSE_ROUTING_KEY)
+ .Create();
+
+ connection.Start();
+ Console.WriteLine("Waiting for messages...");
+ }
+
+ public static void Main(String[] argv)
+ {
+ // Create an instance of this listener with the command line parameters.
+ new TopicListener(DEFAULT_URI);
+ }
+
+ /// <summary>
+ /// Handles all message received by this listener. Test messages are counted, report messages result in a report being sent and
+ /// shutdown messages result in this listener being terminated.
+ /// </summary>
+ ///
+ /// <param name="message">The received message.</param>
+ public void OnMessage(IMessage message)
+ {
+ log.Debug("public void onMessage(Message message = " + message + "): called");
+
+ // Take the start time of the first message if this is the first message.
+ if (!init)
+ {
+ count = 0;
+ init = true;
+ }
+
+ // Check if the message is a control message telling this listener to shut down.
+ if (IsShutdown(message))
+ {
+ log.Debug("Got a shutdown message.");
+ Shutdown();
+ }
+ // Check if the message is a report request message asking this listener to respond with the message count.
+ else if (IsReport(message))
+ {
+ log.Debug("Got a report request message.");
+
+ // Send the message count report.
+ SendReport();
+
+ // Reset the initialization flag so that the next message is considered to be the first.
+ init = false;
+ }
+ // Otherwise it is an ordinary test message, so increment the message count.
+ else
+ {
+ count++;
+ }
+ }
+
+ /// <summary> Checks a message to see if it is a shutdown control message. </summary>
+ ///
+ /// <param name="m">The message to check.</param>
+ ///
+ /// <returns><tt>true</tt> if it is a shutdown control message, <tt>false</tt> otherwise.</returns>
+ private bool IsShutdown(IMessage m)
+ {
+ bool result = CheckTextField(m, "TYPE", "TERMINATION_REQUEST");
+
+ //log.Debug("isShutdown = " + result);
+
+ return result;
+ }
+
+ /// <summary> Checks a message to see if it is a report request control message. </summary>
+ ///
+ /// <param name="m">The message to check.</param>
+ ///
+ /// <returns><tt>true</tt> if it is a report request control message, <tt>false</tt> otherwise.</returns>
+ private bool IsReport(IMessage m)
+ {
+ bool result = CheckTextField(m, "TYPE", "REPORT_REQUEST");
+
+ //log.Debug("isReport = " + result);
+
+ return result;
+ }
+
+ /// <summary> Checks whether or not a text field on a message has the specified value. </summary>
+ ///
+ /// <param name="e">The message to check.</param>
+ /// <param name="e">The name of the field to check.</param>
+ /// <param name="e">The expected value of the field to compare with.</param>
+ ///
+ /// <returns> <tt>true</tt>If the specified field has the specified value, <tt>fals</tt> otherwise. </returns>
+ private static bool CheckTextField(IMessage m, string fieldName, string value)
+ {
+ /*log.Debug("private static boolean checkTextField(Message m = " + m + ", String fieldName = " + fieldName
+ + ", String value = " + value + "): called");*/
+
+ string comp = m.Headers.GetString(fieldName);
+
+ return (comp != null) && comp == value;
+ }
+
+ /// <summary> Stops the message consumer and closes the connection. </summary>
+ private void Shutdown()
+ {
+ connection.Stop();
+ channel.Dispose();
+ connection.Dispose();
+ }
+
+ /// <summary> Sends the report message to the response location. </summary>
+ private void SendReport()
+ {
+ string report = "Received " + count + ".";
+
+ IMessage reportMessage = channel.CreateTextMessage(report);
+
+ reportMessage.Headers.SetBoolean("BOOLEAN", false);
+ //reportMessage.Headers.SetByte("BYTE", 5);
+ reportMessage.Headers.SetDouble("DOUBLE", 3.141);
+ reportMessage.Headers.SetFloat("FLOAT", 1.0f);
+ reportMessage.Headers.SetInt("INT", 1);
+ reportMessage.Headers.SetLong("LONG", 1);
+ reportMessage.Headers.SetString("STRING", "hello");
+ reportMessage.Headers.SetShort("SHORT", 2);
+
+ publisher.Send(reportMessage);
+
+ Console.WriteLine("Sent report: " + report);
+ }
+ }
+}
diff --git a/qpid/dotnet/Qpid.Client.Tests/interop/TopicPublisher.cs b/qpid/dotnet/Qpid.Client.Tests/interop/TopicPublisher.cs
new file mode 100644
index 0000000000..4fd0419e9c
--- /dev/null
+++ b/qpid/dotnet/Qpid.Client.Tests/interop/TopicPublisher.cs
@@ -0,0 +1,208 @@
+/*
+ *
+ * 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.
+ *
+ */
+using System;
+using System.Threading;
+using log4net;
+using Apache.Qpid.Messaging;
+using Apache.Qpid.Client.Qms;
+
+namespace Apache.Qpid.Client.Tests.interop
+{
+ public class TopicPublisher
+ {
+ private static ILog log = LogManager.GetLogger(typeof(TopicPublisher));
+
+ /// <summary> The default AMQ connection URL to use for tests. </summary>
+ const string DEFAULT_URI = "amqp://guest:guest@default/test?brokerlist='tcp://localhost:5672'";
+
+ /// <summary> Holds the default test timeout for broker communications before tests give up. </summary>
+ const int TIMEOUT = 10000;
+
+ /// <summary> Holds the routing key for the topic to receive test messages on. </summary>
+ const string CONTROL_ROUTING_KEY = "topic_control";
+
+ /// <summary> Holds the routing key for the queue to send reports to. </summary>
+ const string RESPONSE_ROUTING_KEY = "response";
+
+ /// <summary> Holds the number of messages to send in each test run. </summary>
+ private int numMessages;
+
+ /// <summary> Holds the number of subscribers listening to the messsages. </summary>
+ private int numSubscribers;
+
+ /// <summary> A monitor used to wait for all reports to arrive back from consumers on. </summary>
+ private AutoResetEvent allReportsReceivedEvt = new AutoResetEvent(false);
+
+ /// <summary> Holds the connection to listen on. </summary>
+ private IConnection connection;
+
+ /// <summary> Holds the channel for all test messages.</summary>
+ private IChannel channel;
+
+ /// <summary> Holds the producer to send test messages on. </summary>
+ private IMessagePublisher publisher;
+
+ /// <summary>
+ /// Creates a topic publisher that will send the specifed number of messages and expect the specifed number of report back from test
+ /// subscribers.
+ /// </summary>
+ ///
+ /// <param name="connectionUri">The broker URL.</param>
+ /// <param name="numMessages">The number of messages to send in each test.</param>
+ /// <param name="numSubscribers">The number of subscribes that are expected to reply with a report.</param>
+ TopicPublisher(string connectionUri, int numMessages, int numSubscribers)
+ {
+ log.Debug("TopicPublisher(string connectionUri = " + connectionUri + ", int numMessages = "+ numMessages +
+ ", int numSubscribers = " + numSubscribers + "): called");
+
+ // Create a connection to the broker.
+ IConnectionInfo connectionInfo = QpidConnectionInfo.FromUrl(connectionUri);
+ connection = new AMQConnection(connectionInfo);
+
+ // Establish a session on the broker.
+ channel = connection.CreateChannel(false, AcknowledgeMode.AutoAcknowledge, 1);
+
+ // Set up a queue to listen for reports on.
+ string responseQueueName = channel.GenerateUniqueName();
+ channel.DeclareQueue(responseQueueName, false, true, true);
+
+ // Set this listener up to listen for reports on the response queue.
+ channel.Bind(responseQueueName, ExchangeNameDefaults.DIRECT, RESPONSE_ROUTING_KEY);
+ //channel.Bind(responseQueueName, "<<default>>", RESPONSE_ROUTING_KEY);
+ IMessageConsumer consumer = channel.CreateConsumerBuilder(responseQueueName)
+ .Create();
+ consumer.OnMessage += new MessageReceivedDelegate(OnMessage);
+
+ // Set up this listener with a producer to send the test messages and report requests on.
+ publisher = channel.CreatePublisherBuilder()
+ .WithExchangeName(ExchangeNameDefaults.TOPIC)
+ .WithRoutingKey(CONTROL_ROUTING_KEY)
+ .Create();
+
+ // Keep the test parameters.
+ this.numMessages = numMessages;
+ this.numSubscribers = numSubscribers;
+
+ connection.Start();
+ Console.WriteLine("Sending messages and waiting for reports...");
+ }
+
+ /// <summary>
+ /// Start a test subscriber. The broker URL must be specified as the first command line argument.
+ /// </summary>
+ ///
+ /// <param name="argv">The command line arguments, broker URL first.</param>
+ public static void Main(String[] argv)
+ {
+ // Create an instance of this publisher with the command line parameters.
+ TopicPublisher publisher = new TopicPublisher(DEFAULT_URI, 1, 1);
+
+ // Publish the test messages.
+ publisher.DoTest();
+ }
+
+ /// <summary>
+ /// Sends the test messages and waits for all subscribers to reply with a report.
+ /// </summary>
+ public void DoTest()
+ {
+ log.Debug("public void DoTest(): called");
+
+ // Create a test message to send.
+ IMessage testMessage = channel.CreateTextMessage("test");
+
+ // Send the desired number of test messages.
+ for (int i = 0; i < numMessages; i++)
+ {
+ publisher.Send(testMessage);
+ }
+
+ log.Debug("Sent " + numMessages + " test messages.");
+
+ // Send the report request.
+ IMessage reportRequestMessage = channel.CreateTextMessage("Report request message.");
+ reportRequestMessage.Headers["TYPE"] = "REPORT_REQUEST";
+
+ reportRequestMessage.Headers.SetBoolean("BOOLEAN", false);
+ //reportRequestMessage.Headers.SetByte("BYTE", 5);
+ reportRequestMessage.Headers.SetDouble("DOUBLE", 3.141);
+ reportRequestMessage.Headers.SetFloat("FLOAT", 1.0f);
+ reportRequestMessage.Headers.SetInt("INT", 1);
+ reportRequestMessage.Headers.SetLong("LONG", 1);
+ reportRequestMessage.Headers.SetString("STRING", "hello");
+ reportRequestMessage.Headers.SetShort("SHORT", 2);
+
+ publisher.Send(reportRequestMessage);
+
+ log.Debug("Sent the report request message, waiting for all replies...");
+
+ // Wait until all the reports come in.
+ allReportsReceivedEvt.WaitOne(TIMEOUT, true);
+
+ // Check if all reports were really received or if the timeout occurred.
+ if (numSubscribers == 0)
+ {
+ log.Debug("Got all reports.");
+ }
+ else
+ {
+ log.Debug("Waiting for reports timed out, still waiting for " + numSubscribers + ".");
+ }
+
+ // Send the termination request.
+ IMessage terminationRequestMessage = channel.CreateTextMessage("Termination request message.");
+ terminationRequestMessage.Headers["TYPE"] = "TERMINATION_REQUEST";
+ publisher.Send(terminationRequestMessage);
+
+ log.Debug("Sent the termination request message.");
+
+ // Close all message producers and consumers and the connection to the broker.
+ Shutdown();
+ }
+
+ /// <summary>
+ /// Handles all report messages from subscribers. This decrements the count of subscribers that are still to reply, until this becomes
+ /// zero, at which time waiting threads are notified of this event.
+ /// </summary>
+ ///
+ /// <param name="message">The received report message.</param>
+ public void OnMessage(IMessage message)
+ {
+ log.Debug("public void OnMessage(IMessage message = " + message + "): called");
+
+ // Decrement the count of expected messages and release the wait monitor when this becomes zero.
+ if (--numSubscribers == 0)
+ {
+ log.Debug("Got reports from all subscribers.");
+ allReportsReceivedEvt.Set();
+ }
+ }
+
+ /// <summary> Stops the message consumers and closes the connection. </summary>
+ private void Shutdown()
+ {
+ connection.Stop();
+ publisher.Dispose();
+ channel.Dispose();
+ connection.Dispose();
+ }
+ }
+}
diff --git a/qpid/dotnet/Qpid.Client.Tests/lib/nunit/nunit-licence.txt b/qpid/dotnet/Qpid.Client.Tests/lib/nunit/nunit-licence.txt
new file mode 100644
index 0000000000..b2316295d3
--- /dev/null
+++ b/qpid/dotnet/Qpid.Client.Tests/lib/nunit/nunit-licence.txt
@@ -0,0 +1,23 @@
+Copyright © 2002-2004 James W. Newkirk, Michael C. Two, Alexei A. Vorontsov,
+ Charlie Poole
+Copyright © 2000-2004 Philip A. Craig
+
+This software is provided 'as-is', without any express or implied warranty. In
+no event will the authors be held liable for any damages arising from the use
+of this software.
+
+Permission is granted to anyone to use this software for any purpose, including
+commercial applications, and to alter it and redistribute it freely, subject to
+the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must not claim
+ that you wrote the original software. If you use this software in a product, an
+ acknowledgment (see the following) in the product documentation is required.
+
+ Portions Copyright © 2002 James W. Newkirk, Michael C. Two, Alexei A. Vorontsov
+ or Copyright © 2000-2002 Philip A. Craig
+
+2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+
+3. This notice may not be removed or altered from any source distribution.
diff --git a/qpid/dotnet/Qpid.Client.Tests/lib/nunit/nunit.framework.dll b/qpid/dotnet/Qpid.Client.Tests/lib/nunit/nunit.framework.dll
new file mode 100644
index 0000000000..53666e74c9
--- /dev/null
+++ b/qpid/dotnet/Qpid.Client.Tests/lib/nunit/nunit.framework.dll
Binary files differ
diff --git a/qpid/dotnet/Qpid.Client.Tests/log4net.config b/qpid/dotnet/Qpid.Client.Tests/log4net.config
new file mode 100644
index 0000000000..0ad25c4185
--- /dev/null
+++ b/qpid/dotnet/Qpid.Client.Tests/log4net.config
@@ -0,0 +1,68 @@
+<!--
+
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+
+-->
+<log4net>
+
+ <!-- ============================== -->
+ <!-- Append messages to the console -->
+ <!-- ============================== -->
+
+ <appender name="console" type="log4net.Appender.ConsoleAppender" >
+ <layout type="log4net.Layout.PatternLayout">
+ <conversionPattern value="%m%n"/>
+ </layout>
+ <threshold value="info"/>
+ </appender>
+
+ <!-- ====================================== -->
+ <!-- Append messages to the socket appender -->
+ <!-- ====================================== -->
+
+ <appender name="UdpAppender" type="log4net.Appender.UdpAppender">
+ <remoteAddress value="127.0.0.1"/>
+ <remotePort value="4445"/>
+ <layout type="log4net.Layout.XmlLayoutSchemaLog4j">
+ <locationInfo value="true"/>
+ </layout>
+ <threshold value="debug"/>
+ </appender>
+
+ <!-- ================ -->
+ <!-- Limit categories -->
+ <!-- ================ -->
+
+ <logger name="Qpid">
+ <level value="debug"/>
+ </logger>
+
+ <logger name="CONSOLE">
+ <level value="info"/>
+ <appender-ref ref="console"/>
+ </logger>
+
+ <!-- ======================= -->
+ <!-- Setup the Root category -->
+ <!-- ======================= -->
+
+ <root>
+ <appender-ref ref="UdpAppender"/>
+ </root>
+
+</log4net>
diff --git a/qpid/dotnet/Qpid.Client.Tests/url/ConnectionUrlTest.cs b/qpid/dotnet/Qpid.Client.Tests/url/ConnectionUrlTest.cs
new file mode 100644
index 0000000000..3c9f8dd4e2
--- /dev/null
+++ b/qpid/dotnet/Qpid.Client.Tests/url/ConnectionUrlTest.cs
@@ -0,0 +1,446 @@
+/*
+ *
+ * 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.
+ *
+ */
+using System;
+using System.Net;
+using NUnit.Framework;
+using Apache.Qpid.Client.Qms;
+
+namespace Apache.Qpid.Client.Tests.url
+{
+ [TestFixture]
+ public class connectionUrlTests
+ {
+ [Test]
+ public void FailoverURL()
+ {
+ //String url = "amqp://ritchiem:bob@/temp?brokerlist='tcp://localhost:5672;tcp://fancyserver:3000/',failover='roundrobin'";
+ String url = "amqp://ritchiem:bob@default/temp?brokerlist='tcp://localhost:5672;tcp://fancyserver:3000/',failover='roundrobin'";
+
+ IConnectionInfo connectionurl = QpidConnectionInfo.FromUrl(url);
+
+ Assert.AreEqual("roundrobin", connectionurl.FailoverMethod);
+ Assert.IsTrue(connectionurl.Username.Equals("ritchiem"));
+ Assert.IsTrue(connectionurl.Password.Equals("bob"));
+ Assert.IsTrue(connectionurl.VirtualHost.Equals("/temp"));
+
+ Assert.IsTrue(connectionurl.BrokerCount == 2);
+
+ IBrokerInfo service = connectionurl.GetBrokerInfo(0);
+
+ Assert.IsTrue(service.Transport.Equals("tcp"));
+ Assert.IsTrue(service.Host.Equals("localhost"));
+ Assert.IsTrue(service.Port == 5672);
+
+ service = connectionurl.GetBrokerInfo(1);
+
+ Assert.IsTrue(service.Transport.Equals("tcp"));
+ Assert.IsTrue(service.Host.Equals("fancyserver"));
+ Assert.IsTrue(service.Port == 3000);
+
+ }
+
+ [Test]
+ public void SingleTransportUsernamePasswordURL()
+ {
+ String url = "amqp://ritchiem:bob@default/temp?brokerlist='tcp://localhost:5672'";
+
+ IConnectionInfo connectionurl = QpidConnectionInfo.FromUrl(url);
+
+ Assert.IsTrue(connectionurl.FailoverMethod == null);
+ Assert.IsTrue(connectionurl.Username.Equals("ritchiem"));
+ Assert.IsTrue(connectionurl.Password.Equals("bob"));
+ Assert.IsTrue(connectionurl.VirtualHost.Equals("/temp"));
+
+ Assert.IsTrue(connectionurl.BrokerCount == 1);
+
+ IBrokerInfo service = connectionurl.GetBrokerInfo(0);
+
+ Assert.IsTrue(service.Transport.Equals("tcp"));
+ Assert.IsTrue(service.Host.Equals("localhost"));
+ Assert.IsTrue(service.Port == 5672);
+ }
+
+ [Test]
+ public void SingleTransportUsernameBlankPasswordURL()
+ {
+ String url = "amqp://ritchiem:@default/temp?brokerlist='tcp://localhost:5672'";
+
+ IConnectionInfo connectionurl = QpidConnectionInfo.FromUrl(url);
+
+ Assert.IsTrue(connectionurl.FailoverMethod == null);
+ Assert.IsTrue(connectionurl.Username.Equals("ritchiem"));
+ Assert.IsTrue(connectionurl.Password.Equals(""));
+ Assert.IsTrue(connectionurl.VirtualHost.Equals("/temp"));
+
+ Assert.IsTrue(connectionurl.BrokerCount == 1);
+
+ IBrokerInfo service = connectionurl.GetBrokerInfo(0);
+
+ Assert.IsTrue(service.Transport.Equals("tcp"));
+ Assert.IsTrue(service.Host.Equals("localhost"));
+ Assert.IsTrue(service.Port == 5672);
+ }
+
+ [Test]
+ public void FailedURLNullPassword()
+ {
+ String url = "amqp://ritchiem@default/temp?brokerlist='tcp://localhost:5672'";
+
+ try
+ {
+ QpidConnectionInfo.FromUrl(url);
+ Assert.Fail("URL has null password");
+ }
+ catch (UrlSyntaxException e)
+ {
+ Assert.AreEqual("Null password in user information not allowed.", e.Message);
+ Assert.IsTrue(e.GetIndex() == 7);
+ }
+ }
+
+ [Test]
+ public void SingleTransportURL()
+ {
+ String url = "amqp://guest:guest@default/test?brokerlist='tcp://localhost:5672'";
+
+ IConnectionInfo connectionurl = QpidConnectionInfo.FromUrl(url);
+
+
+ Assert.IsTrue(connectionurl.FailoverMethod == null);
+ Assert.IsTrue(connectionurl.Username.Equals("guest"));
+ Assert.IsTrue(connectionurl.Password.Equals("guest"));
+ Assert.IsTrue(connectionurl.VirtualHost.Equals("/test"));
+
+
+ Assert.IsTrue(connectionurl.BrokerCount == 1);
+
+
+ IBrokerInfo service = connectionurl.GetBrokerInfo(0);
+
+ Assert.IsTrue(service.Transport.Equals("tcp"));
+ Assert.IsTrue(service.Host.Equals("localhost"));
+ Assert.IsTrue(service.Port == 5672);
+ }
+
+ [Test]
+ public void SingleTransportWithClientURLURL()
+ {
+ String url = "amqp://guest:guest@clientname/temp?brokerlist='tcp://localhost:5672'";
+
+ IConnectionInfo connectionurl = QpidConnectionInfo.FromUrl(url);
+
+
+ Assert.IsTrue(connectionurl.FailoverMethod == null);
+ Assert.IsTrue(connectionurl.Username.Equals("guest"));
+ Assert.IsTrue(connectionurl.Password.Equals("guest"));
+ Assert.IsTrue(connectionurl.VirtualHost.Equals("/temp"));
+ Assert.IsTrue(connectionurl.ClientName.Equals("clientname"));
+
+
+ Assert.IsTrue(connectionurl.BrokerCount == 1);
+
+
+ IBrokerInfo service = connectionurl.GetBrokerInfo(0);
+
+ Assert.IsTrue(service.Transport.Equals("tcp"));
+ Assert.IsTrue(service.Host.Equals("localhost"));
+ Assert.IsTrue(service.Port == 5672);
+ }
+
+ [Test]
+ public void SingleTransport1OptionURL()
+ {
+ String url = "amqp://guest:guest@default/temp?brokerlist='tcp://localhost:5672',routingkey='jim'";
+
+ IConnectionInfo connectionurl = QpidConnectionInfo.FromUrl(url);
+
+ Assert.IsTrue(connectionurl.FailoverMethod == null);
+ Assert.IsTrue(connectionurl.Username.Equals("guest"));
+ Assert.IsTrue(connectionurl.Password.Equals("guest"));
+ Assert.IsTrue(connectionurl.VirtualHost.Equals("/temp"));
+
+
+ Assert.IsTrue(connectionurl.BrokerCount == 1);
+
+ IBrokerInfo service = connectionurl.GetBrokerInfo(0);
+
+ Assert.IsTrue(service.Transport.Equals("tcp"));
+
+ Assert.IsTrue(service.Host.Equals("localhost"));
+ Assert.IsTrue(service.Port == 5672);
+ Assert.IsTrue(connectionurl.GetOption("routingkey").Equals("jim"));
+ }
+
+ [Test]
+ public void SingleTransportDefaultedBroker()
+ {
+ String url = "amqp://guest:guest@default/temp?brokerlist='localhost:'";
+
+ IConnectionInfo connectionurl = QpidConnectionInfo.FromUrl(url);
+
+ Assert.IsTrue(connectionurl.FailoverMethod == null);
+ Assert.IsTrue(connectionurl.Username.Equals("guest"));
+ Assert.IsTrue(connectionurl.Password.Equals("guest"));
+ Assert.IsTrue(connectionurl.VirtualHost.Equals("/temp"));
+
+
+ Assert.IsTrue(connectionurl.BrokerCount == 1);
+
+ IBrokerInfo service = connectionurl.GetBrokerInfo(0);
+
+ Assert.IsTrue(service.Transport.Equals("tcp"));
+
+ Assert.IsTrue(service.Host.Equals("localhost"));
+ Assert.IsTrue(service.Port == 5672);
+ }
+
+ [Test]
+ public void SingleTransportMultiOptionURL()
+ {
+ String url = "amqp://guest:guest@default/temp?brokerlist='tcp://localhost:5672',routingkey='jim',timeout='200',immediatedelivery='true'";
+
+ IConnectionInfo connectionurl = QpidConnectionInfo.FromUrl(url);
+
+ Assert.IsTrue(connectionurl.FailoverMethod == null);
+ Assert.IsTrue(connectionurl.Username.Equals("guest"));
+ Assert.IsTrue(connectionurl.Password.Equals("guest"));
+ Assert.IsTrue(connectionurl.VirtualHost.Equals("/temp"));
+
+ Assert.IsTrue(connectionurl.BrokerCount == 1);
+
+ IBrokerInfo service = connectionurl.GetBrokerInfo(0);
+
+ Assert.IsTrue(service.Transport.Equals("tcp"));
+
+ Assert.IsTrue(service.Host.Equals("localhost"));
+ Assert.IsTrue(service.Port == 5672);
+
+ Assert.IsTrue(connectionurl.GetOption("routingkey").Equals("jim"));
+ Assert.IsTrue(connectionurl.GetOption("timeout").Equals("200"));
+ Assert.IsTrue(connectionurl.GetOption("immediatedelivery").Equals("true"));
+ }
+
+ [Test]
+ public void SinglevmURL()
+ {
+ String url = "amqp://guest:guest@default/messages?brokerlist='vm://default:2'";
+
+ IConnectionInfo connectionurl = QpidConnectionInfo.FromUrl(url);
+
+ Assert.IsTrue(connectionurl.FailoverMethod == null);
+ Assert.IsTrue(connectionurl.Username.Equals("guest"));
+ Assert.IsTrue(connectionurl.Password.Equals("guest"));
+ Assert.IsTrue(connectionurl.VirtualHost.Equals("/messages"));
+
+ Assert.IsTrue(connectionurl.BrokerCount == 1);
+
+ IBrokerInfo service = connectionurl.GetBrokerInfo(0);
+
+ Assert.IsTrue(service.Transport.Equals("vm"));
+ Assert.AreEqual("localhost", service.Host);
+ Assert.AreEqual(2, service.Port);
+ }
+
+ [Test]
+ public void FailoverVMURL()
+ {
+ String url = "amqp://ritchiem:bob@default/temp?brokerlist='vm://default:2;vm://default:3',failover='roundrobin'";
+
+ IConnectionInfo connectionurl = QpidConnectionInfo.FromUrl(url);
+
+ Assert.IsTrue(connectionurl.FailoverMethod.Equals("roundrobin"));
+ Assert.IsTrue(connectionurl.Username.Equals("ritchiem"));
+ Assert.IsTrue(connectionurl.Password.Equals("bob"));
+ Assert.IsTrue(connectionurl.VirtualHost.Equals("/temp"));
+
+ Assert.AreEqual(2, connectionurl.BrokerCount);
+
+ IBrokerInfo service = connectionurl.GetBrokerInfo(0);
+
+ Assert.IsTrue(service.Transport.Equals("vm"));
+ Assert.AreEqual("localhost", service.Host);
+ Assert.IsTrue(service.Port == 2);
+
+ service = connectionurl.GetBrokerInfo(1);
+ Assert.IsTrue(service.Transport.Equals("vm"));
+ Assert.AreEqual("localhost", service.Host);
+ Assert.IsTrue(service.Port == 3);
+ }
+
+ [Test]
+ public void NoVirtualHostURL()
+ {
+ String url = "amqp://user@default?brokerlist='tcp://localhost:5672'";
+
+ try
+ {
+ QpidConnectionInfo.FromUrl(url);
+ Assert.Fail("URL has no virtual host should not parse");
+ }
+ catch (UrlSyntaxException)
+ {
+ // This should occur.
+ }
+ }
+
+ [Test]
+ public void NoClientID()
+ {
+ String url = "amqp://user:@default/test?brokerlist='tcp://localhost:5672'";
+
+ IConnectionInfo connectionurl = QpidConnectionInfo.FromUrl(url);
+
+ Assert.IsTrue(connectionurl.Username.Equals("user"));
+ Assert.IsTrue(connectionurl.Password.Equals(""));
+ Assert.IsTrue(connectionurl.VirtualHost.Equals("/test"));
+ Assert.IsTrue(connectionurl.ClientName.StartsWith(Dns.GetHostName()));
+
+ Assert.IsTrue(connectionurl.BrokerCount == 1);
+ }
+
+ [Test]
+ public void WrongOptionSeparatorInOptions()
+ {
+ String url = "amqp://guest:guest@default/test?brokerlist='tcp://localhost:5672;tcp://localhost:5673'+failover='roundrobin'";
+ try
+ {
+ QpidConnectionInfo.FromUrl(url);
+ Assert.Fail("URL Should not parse");
+ }
+ catch (UrlSyntaxException urise)
+ {
+ Assert.IsTrue(urise.Message.Equals("Unterminated option. Possible illegal option separator:'+'"));
+ }
+
+ }
+
+ [Test]
+ public void NoUserDetailsProvidedWithClientID()
+
+ {
+ String url = "amqp://clientID/test?brokerlist='tcp://localhost:5672;tcp://localhost:5673'";
+ try
+ {
+ QpidConnectionInfo.FromUrl(url);
+ Assert.Fail("URL Should not parse");
+ }
+ catch (UrlSyntaxException urise)
+ {
+ Assert.IsTrue(urise.Message.StartsWith("User information not found on url"));
+ }
+
+ }
+
+ [Test]
+ public void NoUserDetailsProvidedNOClientID()
+
+ {
+ String url = "amqp:///test@default?brokerlist='tcp://localhost:5672;tcp://localhost:5673'";
+ try
+ {
+ QpidConnectionInfo.FromUrl(url);
+ Assert.Fail("URL Should not parse");
+ }
+ catch (UrlSyntaxException urise)
+ {
+
+ Assert.IsTrue(urise.Message.StartsWith("User information not found on url"));
+ }
+
+ }
+
+ [Test]
+ public void CheckVirtualHostFormat()
+ {
+ String url = "amqp://guest:guest@default/t.-_+!=:?brokerlist='tcp://localhost:5672'";
+
+ IConnectionInfo connection = QpidConnectionInfo.FromUrl(url);
+ Assert.IsTrue(connection.VirtualHost.Equals("/t.-_+!=:"));
+ }
+
+ [Test]
+ public void CheckDefaultPort()
+ {
+ String url = "amqp://guest:guest@default/test=:?brokerlist='tcp://localhost'";
+
+ IConnectionInfo connection = QpidConnectionInfo.FromUrl(url);
+
+ IBrokerInfo broker = connection.GetBrokerInfo(0);
+ Assert.IsTrue(broker.Port == BrokerInfoConstants.DEFAULT_PORT);
+
+ }
+
+ [Test]
+ public void CheckMissingFinalQuote()
+ {
+ String url = "amqp://guest:guest@id/test" + "?brokerlist='tcp://localhost:5672";
+
+ try
+ {
+ QpidConnectionInfo.FromUrl(url);
+ }
+ catch (UrlSyntaxException e)
+ {
+// Assert.AreEqual("Unterminated option at index 32: brokerlist='tcp://localhost:5672",
+// e.Message);
+ Assert.AreEqual("Unterminated option", e.Message);
+ }
+ }
+
+ [Test]
+ public void ValidateQpidConnectionInfoFromToString()
+ {
+ String url = "amqp://ritchiem:bob@default/temp?brokerlist='tcp://localhost:5672;tcp://fancyserver:3000/',failover='roundrobin'";
+
+ IConnectionInfo connectionInfo = QpidConnectionInfo.FromUrl(url);
+ IConnectionInfo connectionInfo1 = QpidConnectionInfo.FromUrl(connectionInfo.ToString());
+
+ Console.WriteLine(connectionInfo.ToString());
+ Console.WriteLine(connectionInfo1.ToString());
+
+ Assert.AreEqual(connectionInfo.Username, connectionInfo1.Username);
+ Assert.AreEqual(connectionInfo.Password, connectionInfo1.Password);
+ Assert.AreEqual(connectionInfo.VirtualHost, connectionInfo1.VirtualHost);
+
+ Assert.IsTrue((connectionInfo1.GetAllBrokerInfos().Count == 2));
+ Assert.IsTrue(connectionInfo.GetBrokerInfo(0).Equals(connectionInfo1.GetBrokerInfo(0)));
+ Assert.IsTrue(connectionInfo.GetBrokerInfo(1).Equals(connectionInfo1.GetBrokerInfo(1)));
+
+ }
+
+ [Test]
+ public void EnsureVirtualHostStartsWithSlash()
+ {
+ IConnectionInfo connection = new QpidConnectionInfo();
+ connection.VirtualHost = "test";
+ Assert.AreEqual("/test", connection.VirtualHost);
+
+ connection.VirtualHost = "/mytest";
+ Assert.AreEqual("/mytest", connection.VirtualHost);
+
+ connection.VirtualHost = "";
+ Assert.AreEqual("/", connection.VirtualHost);
+
+ connection.VirtualHost = null;
+ Assert.AreEqual("/", connection.VirtualHost);
+ }
+ }
+}
diff --git a/qpid/dotnet/Qpid.Client.Transport.Socket.Blocking/BlockingSocketProcessor.cs b/qpid/dotnet/Qpid.Client.Transport.Socket.Blocking/BlockingSocketProcessor.cs
new file mode 100644
index 0000000000..b62b11a3db
--- /dev/null
+++ b/qpid/dotnet/Qpid.Client.Transport.Socket.Blocking/BlockingSocketProcessor.cs
@@ -0,0 +1,135 @@
+/*
+ *
+ * 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.
+ *
+ */
+using System;
+using System.Net;
+using System.Net.Sockets;
+using log4net;
+using Apache.Qpid.Buffer;
+using Apache.Qpid.Client.Protocol;
+
+namespace Apache.Qpid.Client.Transport.Socket.Blocking
+{
+ class BlockingSocketProcessor : IConnectionCloser
+ {
+ private static readonly ILog _log = LogManager.GetLogger(typeof(BlockingSocketProcessor));
+
+ string _host;
+ int _port;
+ System.Net.Sockets.Socket _socket;
+ private NetworkStream _networkStream;
+ IByteChannel _byteChannel;
+ IProtocolListener _protocolListener;
+
+ public BlockingSocketProcessor(string host, int port, IProtocolListener protocolListener)
+ {
+ _host = host;
+ _port = port;
+ _protocolListener = protocolListener;
+ _byteChannel = new ByteChannel(this);
+ }
+
+ /// <summary>
+ /// Synchronous blocking connect.
+ /// </summary>
+ public void Connect()
+ {
+ _socket = new System.Net.Sockets.Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
+
+ /// For future note TCP Set NoDelay options may help, though with the blocking io not sure
+ /// The Don't linger may help with detecting disconnect but that hasn't been the case in testing.
+ /// _socket.SetSocketOption (SocketOptionLevel.Socket, SocketOptionName.NoDelay, 0);
+ /// _socket.SetSocketOption (SocketOptionLevel.Socket, SocketOptionName.DontLinger, 0);
+
+ IPHostEntry ipHostInfo = Dns.Resolve(_host); // Note: don't fix this warning. We do this for .NET 1.1 compatibility.
+ IPAddress ipAddress = ipHostInfo.AddressList[0];
+
+ IPEndPoint ipe = new IPEndPoint(ipAddress, _port);
+
+ _socket.Connect(ipe);
+ _networkStream = new NetworkStream(_socket, true);
+ }
+
+ public string getLocalEndPoint()
+ {
+ return _socket.LocalEndPoint.ToString();
+ }
+
+ public void Write(ByteBuffer byteBuffer)
+ {
+ try
+ {
+ _networkStream.Write(byteBuffer.array(), byteBuffer.position(), byteBuffer.limit()); // FIXME
+ }
+ catch (Exception e)
+ {
+ _log.Error("Write caused exception", e);
+ _protocolListener.OnException(e);
+ // We should provide the error synchronously as we are doing blocking io.
+ throw e;
+ }
+ }
+
+ public ByteBuffer Read()
+ {
+ const int bufferSize = 4 * 1024; // TODO: Prevent constant allocation of buffers.
+ byte[] bytes = new byte[bufferSize];
+
+ int numOctets = _networkStream.Read(bytes, 0, bytes.Length);
+
+ /// Read only returns 0 if the socket has been gracefully shutdown.
+ /// http://msdn2.microsoft.com/en-us/library/system.net.sockets.networkstream.read(VS.71).aspx
+ /// We can use this to block Send so the next Read will force an exception forcing failover.
+ /// Otherwise we need to wait ~20 seconds for the NetworkStream/Socket code to realise that
+ /// the socket has been closed.
+ if (numOctets == 0)
+ {
+ _socket.Shutdown(SocketShutdown.Send);
+ _socket.Close();
+ }
+
+ ByteBuffer byteBuffer = ByteBuffer.wrap(bytes);
+ byteBuffer.limit(numOctets);
+
+ byteBuffer.flip();
+
+ return byteBuffer;
+ }
+
+ public void Disconnect()
+ {
+ _networkStream.Flush();
+ _networkStream.Close();
+ _socket.Close();
+ }
+
+ public void Close()
+ {
+ Disconnect();
+ }
+
+ public IByteChannel ByteChannel
+ {
+ get { return _byteChannel; }
+ }
+ }
+}
+
+
diff --git a/qpid/dotnet/Qpid.Client.Transport.Socket.Blocking/BlockingSocketTransport.cs b/qpid/dotnet/Qpid.Client.Transport.Socket.Blocking/BlockingSocketTransport.cs
new file mode 100644
index 0000000000..17f911fb6d
--- /dev/null
+++ b/qpid/dotnet/Qpid.Client.Transport.Socket.Blocking/BlockingSocketTransport.cs
@@ -0,0 +1,121 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+using System;
+using System.Collections;
+using System.Threading;
+using log4net;
+using Apache.Qpid.Client.Protocol;
+using Apache.Qpid.Framing;
+
+namespace Qpid.Client.Transport.Socket.Blocking
+{
+ public class BlockingSocketTransport : ITransport
+ {
+// static readonly ILog _log = LogManager.GetLogger(typeof(BlockingSocketTransport));
+
+ // Configuration variables.
+ string _host;
+ int _port;
+ IProtocolListener _protocolListener;
+
+ // Runtime variables.
+ private BlockingSocketProcessor _socketProcessor;
+ private AmqpChannel _amqpChannel;
+
+ private ReaderRunner _readerRunner;
+ private Thread _readerThread;
+
+ public BlockingSocketTransport(string host, int port, AMQConnection connection)
+ {
+ _host = host;
+ _port = port;
+ _protocolListener = connection.ProtocolListener;
+ }
+
+ public void Open()
+ {
+ _socketProcessor = new BlockingSocketProcessor(_host, _port, _protocolListener);
+ _socketProcessor.Connect();
+ _amqpChannel = new AmqpChannel(_socketProcessor.ByteChannel);
+ _readerRunner = new ReaderRunner(this);
+ _readerThread = new Thread(new ThreadStart(_readerRunner.Run));
+ _readerThread.Start();
+ }
+
+ public string getLocalEndPoint()
+ {
+ return _socketProcessor.getLocalEndPoint();
+ }
+
+ public void Close()
+ {
+ StopReaderThread();
+ _socketProcessor.Disconnect();
+ }
+
+ public IProtocolChannel ProtocolChannel { get { return _amqpChannel; } }
+ public IProtocolWriter ProtocolWriter { get { return _amqpChannel; } }
+
+ public void StopReaderThread()
+ {
+ _readerRunner.Stop();
+ }
+
+ class ReaderRunner
+ {
+ BlockingSocketTransport _transport;
+ bool _running = true;
+
+ public ReaderRunner(BlockingSocketTransport transport)
+ {
+ _transport = transport;
+ }
+
+ public void Run()
+ {
+ try
+ {
+ while (_running)
+ {
+ Queue frames = _transport.ProtocolChannel.Read();
+
+ foreach (IDataBlock dataBlock in frames)
+ {
+ _transport._protocolListener.OnMessage(dataBlock);
+ }
+ }
+ }
+ catch (Exception e)
+ {
+ _transport._protocolListener.OnException(e);
+ }
+ }
+
+ public void Stop()
+ {
+ // TODO: Check if this is thread safe. running is not volitile....
+ _running = false;
+ }
+ }
+ }
+}
+
+
diff --git a/qpid/dotnet/Qpid.Client.Transport.Socket.Blocking/ByteChannel.cs b/qpid/dotnet/Qpid.Client.Transport.Socket.Blocking/ByteChannel.cs
new file mode 100644
index 0000000000..5f67e99838
--- /dev/null
+++ b/qpid/dotnet/Qpid.Client.Transport.Socket.Blocking/ByteChannel.cs
@@ -0,0 +1,63 @@
+/*
+ *
+ * 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.
+ *
+ */
+using System;
+using log4net;
+using Apache.Qpid.Buffer;
+
+namespace Apache.Qpid.Client.Transport.Socket.Blocking
+{
+ class ByteChannel : IByteChannel
+ {
+ // Warning: don't use this log for regular logging.
+ private static readonly ILog _ioTraceLog = LogManager.GetLogger("TRACE.Qpid.Client.ByteChannel");
+
+ BlockingSocketProcessor processor;
+
+ public ByteChannel(BlockingSocketProcessor processor)
+ {
+ this.processor = processor;
+ }
+
+ public ByteBuffer Read()
+ {
+ ByteBuffer result = processor.Read();
+
+ // TODO: Move into decorator.
+ if (_ioTraceLog.IsDebugEnabled)
+ {
+ _ioTraceLog.Debug(String.Format("READ {0}", result));
+ }
+
+ return result;
+ }
+
+ public void Write(ByteBuffer buffer)
+ {
+ // TODO: Move into decorator.
+ if (_ioTraceLog.IsDebugEnabled)
+ {
+ _ioTraceLog.Debug(String.Format("WRITE {0}", buffer));
+ }
+
+ processor.Write(buffer);
+ }
+ }
+}
diff --git a/qpid/dotnet/Qpid.Client.Transport.Socket.Blocking/Properties/AssemblyInfo.cs b/qpid/dotnet/Qpid.Client.Transport.Socket.Blocking/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000000..19599b0833
--- /dev/null
+++ b/qpid/dotnet/Qpid.Client.Transport.Socket.Blocking/Properties/AssemblyInfo.cs
@@ -0,0 +1,53 @@
+/*
+ *
+ * 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.
+ *
+ */
+using System.Reflection;
+using System.Runtime.InteropServices;
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("Apache.Qpid.Transport.Blocking")]
+[assembly: AssemblyDescription("Built from svn revision number: ")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Apache Software Foundation")]
+[assembly: AssemblyProduct("Apache.Qpid.Transport.Blocking")]
+[assembly: AssemblyCopyright("Apache Software Foundation")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("ca23e89c-f5b9-4f7a-929a-4fae00ef055b")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Revision and Build Numbers
+// by using the '*' as shown below:
+[assembly: AssemblyVersion("0.5.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/qpid/dotnet/Qpid.Client.Transport.Socket.Blocking/Qpid.Client.Transport.Socket.Blocking.csproj b/qpid/dotnet/Qpid.Client.Transport.Socket.Blocking/Qpid.Client.Transport.Socket.Blocking.csproj
new file mode 100644
index 0000000000..6a0b1cd8e6
--- /dev/null
+++ b/qpid/dotnet/Qpid.Client.Transport.Socket.Blocking/Qpid.Client.Transport.Socket.Blocking.csproj
@@ -0,0 +1,92 @@
+<!--
+
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+
+-->
+
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProductVersion>8.0.50727</ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{52AC4940-2077-4104-A753-29A9C8C16957}</ProjectGuid>
+ <OutputType>Library</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>Apache.Qpid.Client.Transport.Socket.Blocking</RootNamespace>
+ <AssemblyName>Apache.Qpid.Client.Transport.Socket.Blocking</AssemblyName>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="log4net, Version=1.2.0.30714, Culture=neutral, PublicKeyToken=500ffcafb14f92df">
+ <SpecificVersion>False</SpecificVersion>
+ <HintPath>..\Qpid.Common\lib\log4net\log4net.dll</HintPath>
+ </Reference>
+ <Reference Include="System" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="BlockingSocketProcessor.cs" />
+ <Compile Include="BlockingSocketTransport.cs" />
+ <Compile Include="ByteChannel.cs" />
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\Qpid.Buffer\Qpid.Buffer.csproj">
+ <Project>{44384DF2-B0A4-4580-BDBC-EE4BAA87D995}</Project>
+ <Name>Qpid.Buffer</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\Qpid.Client\Qpid.Client.csproj">
+ <Project>{68987C05-3768-452C-A6FC-6BA1D372852F}</Project>
+ <Name>Qpid.Client</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\Qpid.Common\Qpid.Common.csproj">
+ <Project>{77064C42-24D2-4CEB-9EA2-0EF481A43205}</Project>
+ <Name>Qpid.Common</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\Qpid.Messaging\Qpid.Messaging.csproj">
+ <Project>{6688F826-C58E-4C1B-AA1F-22AFAB4B7D07}</Project>
+ <Name>Qpid.Messaging</Name>
+ </ProjectReference>
+ </ItemGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+ <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
+ Other similar extension points exist, see Microsoft.Common.targets.
+ <Target Name="BeforeBuild">
+ </Target>
+ <Target Name="AfterBuild">
+ </Target>
+ -->
+</Project>
diff --git a/qpid/dotnet/Qpid.Client.Transport.Socket.Blocking/Qpid.Client.Transport.Socket.Blocking.mdp b/qpid/dotnet/Qpid.Client.Transport.Socket.Blocking/Qpid.Client.Transport.Socket.Blocking.mdp
new file mode 100644
index 0000000000..54c3be76e5
--- /dev/null
+++ b/qpid/dotnet/Qpid.Client.Transport.Socket.Blocking/Qpid.Client.Transport.Socket.Blocking.mdp
@@ -0,0 +1,50 @@
+<!--
+ -
+ - Licensed to the Apache Software Foundation (ASF) under one
+ - or more contributor license agreements. See the NOTICE file
+ - distributed with this work for additional information
+ - regarding copyright ownership. The ASF licenses this file
+ - to you under the Apache License, Version 2.0 (the
+ - "License"); you may not use this file except in compliance
+ - with the License. You may obtain a copy of the License at
+ -
+ - http://www.apache.org/licenses/LICENSE-2.0
+ -
+ - Unless required by applicable law or agreed to in writing,
+ - software distributed under the License is distributed on an
+ - "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ - KIND, either express or implied. See the License for the
+ - specific language governing permissions and limitations
+ - under the License.
+ -
+ -->
+<Project name="Qpid.Client.Transport.Socket.Blocking" fileversion="2.0" language="C#" clr-version="Net_1_1" ctype="DotNetProject">
+ <Configurations active="Debug">
+ <Configuration name="Debug" ctype="DotNetProjectConfiguration">
+ <Output directory="./bin/Debug" assembly="Qpid.Client.Transport.Socket.Blocking" />
+ <Build debugmode="True" target="Library" />
+ <Execution runwithwarnings="True" consolepause="False" runtime="MsNet" clr-version="Net_1_1" />
+ <CodeGeneration compiler="Csc" warninglevel="4" optimize="True" unsafecodeallowed="False" generateoverflowchecks="True" generatexmldocumentation="False" ctype="CSharpCompilerParameters" />
+ </Configuration>
+ <Configuration name="Release" ctype="DotNetProjectConfiguration">
+ <Output directory="./bin/Release" assembly="Qpid.Client.Transport.Socket.Blocking" />
+ <Build debugmode="False" target="Library" />
+ <Execution runwithwarnings="True" consolepause="False" runtime="MsNet" clr-version="Net_1_1" />
+ <CodeGeneration compiler="Csc" warninglevel="4" optimize="True" unsafecodeallowed="False" generateoverflowchecks="True" generatexmldocumentation="False" ctype="CSharpCompilerParameters" />
+ </Configuration>
+ </Configurations>
+ <DeployTargets />
+ <Contents>
+ <File name="./Properties/AssemblyInfo.cs" subtype="Code" buildaction="Compile" />
+ <File name="./BlockingSocketProcessor.cs" subtype="Code" buildaction="Compile" />
+ <File name="./BlockingSocketTransport.cs" subtype="Code" buildaction="Compile" />
+ <File name="./ByteChannel.cs" subtype="Code" buildaction="Compile" />
+ </Contents>
+ <References>
+ <ProjectReference type="Gac" localcopy="True" refto="System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
+ <ProjectReference type="Assembly" localcopy="True" refto="../Qpid.Common/lib/log4net/log4net.dll" />
+ <ProjectReference type="Project" localcopy="True" refto="Qpid.Buffer" />
+ <ProjectReference type="Project" localcopy="True" refto="Qpid.Client" />
+ <ProjectReference type="Project" localcopy="True" refto="Qpid.Common" />
+ </References>
+</Project> \ No newline at end of file
diff --git a/qpid/dotnet/Qpid.Client/Client/AMQAuthenticationException.cs b/qpid/dotnet/Qpid.Client/Client/AMQAuthenticationException.cs
new file mode 100644
index 0000000000..7bb64e3fff
--- /dev/null
+++ b/qpid/dotnet/Qpid.Client/Client/AMQAuthenticationException.cs
@@ -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.
+ *
+ */
+using System;
+using System.Runtime.Serialization;
+
+namespace Apache.Qpid.Client
+{
+ [Serializable]
+ public class AMQAuthenticationException : AMQException
+ {
+ public AMQAuthenticationException(int error, String message)
+ : base(error, message)
+ {
+ }
+
+ protected AMQAuthenticationException(SerializationInfo info, StreamingContext ctxt)
+ : base(info, ctxt)
+ {
+ }
+ }
+}
diff --git a/qpid/dotnet/Qpid.Client/Client/AMQConnection.cs b/qpid/dotnet/Qpid.Client/Client/AMQConnection.cs
new file mode 100644
index 0000000000..41d4e089b6
--- /dev/null
+++ b/qpid/dotnet/Qpid.Client/Client/AMQConnection.cs
@@ -0,0 +1,873 @@
+/*
+ *
+ * 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.
+ *
+ */
+using System;
+using System.Collections;
+using System.IO;
+using System.Reflection;
+using System.Threading;
+using log4net;
+using Apache.Qpid.Client.Failover;
+using Apache.Qpid.Client.Protocol;
+using Apache.Qpid.Client.Qms;
+using Apache.Qpid.Client.State;
+using Apache.Qpid.Client.Transport;
+using Apache.Qpid.Client.Transport.Socket.Blocking;
+using Apache.Qpid.Collections;
+using Apache.Qpid.Framing;
+using Apache.Qpid.Messaging;
+
+namespace Apache.Qpid.Client
+{
+ public class AMQConnection : Closeable, IConnection
+ {
+ private static readonly ILog _log = LogManager.GetLogger(typeof(AMQConnection));
+
+ IConnectionInfo _connectionInfo;
+ private int _nextChannelId = 0;
+
+ // _Connected should be refactored with a suitable wait object.
+ private bool _connected;
+
+ Thread _heartBeatThread;
+ HeartBeatThread _heartBeatRunner;
+
+ // The last error code that occured on the connection. Used to return the correct exception to the client
+ private AMQException _lastAMQException = null;
+
+ /**
+ * This is the "root" mutex that must be held when doing anything that could be impacted by failover.
+ * This must be held by any child objects of this connection such as the session, producers and consumers.
+ */
+ private readonly Object _failoverMutex = new Object();
+ public object FailoverMutex
+ {
+ get { return _failoverMutex; }
+ }
+
+ /**
+ * Policy dictating how to failover
+ */
+ private FailoverPolicy _failoverPolicy;
+
+ internal bool IsFailoverAllowed
+ {
+ get { if(!_connected) return false; else return _failoverPolicy.FailoverAllowed(); }
+ }
+
+ /// <summary>
+ /// A channel is roughly analogous to a session. The server can negotiate the maximum number of channels
+ /// per session and we must prevent the client from opening too many. Zero means unlimited.
+ /// </summary>
+ private ushort _maximumChannelCount;
+
+ /// <summary>
+ /// The maximum size of frame supported by the server
+ /// </summary>
+ private uint _maximumFrameSize;
+
+ private AMQStateManager _stateManager;
+
+ private AMQProtocolSession _protocolSession;
+ public AMQProtocolSession ProtocolSession { get { return _protocolSession; } }
+
+ /// <summary>
+ /// Maps from session id (Integer) to AmqChannel instance
+ /// </summary>
+ private readonly IDictionary _sessions = new LinkedHashtable();
+
+ private ExceptionListenerDelegate _exceptionListener;
+
+ private IConnectionListener _connectionListener;
+
+ private ITransport _transport;
+ public ITransport Transport { get { return _transport; } }
+
+ /// <summary>
+ /// Whether this connection is started, i.e. whether messages are flowing to consumers. It has no meaning for
+ /// message publication.
+ /// </summary>
+ private bool _started;
+
+ private AMQProtocolListener _protocolListener;
+ public AMQProtocolListener ProtocolListener { get { return _protocolListener; } }
+
+ public IProtocolWriter ProtocolWriter
+ {
+ get { return _transport.ProtocolWriter; }
+ }
+
+ ProtocolWriter _protocolWriter;
+
+ public ProtocolWriter ConvenientProtocolWriter
+ {
+ get { return _protocolWriter; }
+ }
+
+ public AMQConnection(IConnectionInfo connectionInfo)
+ {
+ if (connectionInfo == null)
+ {
+ throw new ArgumentException("ConnectionInfo must be specified");
+ }
+ _log.Debug("ConnectionInfo: " + connectionInfo);
+ _connectionInfo = connectionInfo;
+ _log.Debug("password = " + _connectionInfo.Password);
+ _failoverPolicy = new FailoverPolicy(connectionInfo);
+
+ // We are not currently connected.
+ _connected = false;
+
+ Exception lastException = null;
+ do
+ {
+ try
+ {
+ IBrokerInfo brokerInfo = _failoverPolicy.GetNextBrokerInfo();
+ _log.Debug("Connecting to " + brokerInfo);
+ MakeBrokerConnection(brokerInfo);
+ break;
+ }
+ catch (Exception e)
+ {
+ lastException = e;
+ _log.Error("Unable to connect to broker " + _failoverPolicy.GetCurrentBrokerInfo(), e);
+ // XXX: Should perhaps break out of the do/while here if not a SocketException...
+ }
+ } while (!_connected && _failoverPolicy.FailoverAllowed());
+
+ _log.Debug("Are we connected:" + _connected);
+
+ if (!_connected)
+ {
+ if ( lastException is AMQException )
+ {
+ throw lastException;
+ }
+ else
+ {
+ throw new AMQConnectionException("Unable to connect", lastException);
+ }
+ }
+
+ }
+
+ /*private ITransport LoadTransportFromAssembly(string host, int port, String assemblyName, String transportType)
+ {
+ //Assembly assembly = Assembly.LoadFrom(assemblyName);
+ Assembly assembly = Assembly.Load(assemblyName);
+
+ foreach (Type type in assembly.GetTypes())
+ {
+ _log.Debug(String.Format("type = {0}", type));
+ }
+
+ Type transport = assembly.GetType(transportType);
+
+ if (transport == null)
+ {
+ throw new ArgumentException(
+ String.Format("Type is not found in assembly. Type={0} Assembly={1}", transportType, assemblyName));
+
+ }
+
+ _log.Debug("transport = " + transport);
+ _log.Debug("ctors = " + transport.GetConstructors());
+
+ ConstructorInfo info = transport.GetConstructors()[0];
+ ITransport result = (ITransport)info.Invoke(new object[] { host, port, this });
+
+ _log.Debug("transport = " + result);
+
+ return result;
+ }*/
+
+ public void Disconnect()
+ {
+ _transport.Close();
+ }
+
+ #region IConnection Members
+
+ public string ClientID
+ {
+ get
+ {
+ CheckNotClosed();
+ return _connectionInfo.ClientName;
+ }
+ set
+ {
+ CheckNotClosed();
+ _connectionInfo.ClientName = value;
+ }
+ }
+
+ public override void Close()
+ {
+ lock (FailoverMutex)
+ {
+ // atomically set to closed and check the _previous value was NOT CLOSED
+ if (Interlocked.Exchange(ref _closed, CLOSED) == NOT_CLOSED)
+ {
+ try
+ {
+ CloseAllSessions(null);
+ CloseConnection();
+ }
+ catch (AMQException e)
+ {
+ throw new QpidException("Error closing connection: " + e);
+ }
+ }
+ }
+ }
+
+ private void CloseConnection()
+ {
+ _stateManager.ChangeState(AMQState.CONNECTION_CLOSING);
+
+ AMQFrame frame = ConnectionCloseBody.CreateAMQFrame(
+ 0, 200, "Qpid.NET client is closing the connection.", 0, 0);
+
+ ProtocolWriter.Write(frame);
+
+ _log.Debug("Blocking for connection close ok frame");
+
+ Disconnect();
+ }
+
+ class CreateChannelFailoverSupport : FailoverSupport
+ {
+ private static readonly ILog _log = LogManager.GetLogger(typeof(CreateChannelFailoverSupport));
+
+ private bool _transacted;
+ private AcknowledgeMode _acknowledgeMode;
+ int _prefetchHigh;
+ int _prefetchLow;
+ AMQConnection _connection;
+
+ public CreateChannelFailoverSupport(AMQConnection connection, bool transacted, AcknowledgeMode acknowledgeMode, int prefetchHigh, int prefetchLow)
+ {
+ _connection = connection;
+ _transacted = transacted;
+ _acknowledgeMode = acknowledgeMode;
+ _prefetchHigh = prefetchHigh;
+ _prefetchLow = prefetchLow;
+ }
+
+ protected override object operation()
+ {
+ ushort channelId = _connection.NextChannelId();
+
+ if (_log.IsDebugEnabled)
+ {
+ _log.Debug("Write channel open frame for channel id " + channelId);
+ }
+
+ // We must create the channel and register it before actually sending the frame to the server to
+ // open it, so that there is no window where we could receive data on the channel and not be set
+ // up to handle it appropriately.
+ AmqChannel channel = new AmqChannel(_connection,
+ channelId, _transacted, _acknowledgeMode, _prefetchHigh, _prefetchLow);
+ _connection.ProtocolSession.AddSessionByChannel(channelId, channel);
+ _connection.RegisterSession(channelId, channel);
+
+ bool success = false;
+ try
+ {
+ _connection.CreateChannelOverWire(channelId, _prefetchHigh, _prefetchLow, _transacted);
+ success = true;
+ }
+ catch (AMQException e)
+ {
+ throw new QpidException("Error creating channel: " + e, e);
+ }
+ finally
+ {
+ if (!success) {
+ _connection.ProtocolSession.RemoveSessionByChannel(channelId);
+ _connection.DeregisterSession(channelId);
+ }
+ }
+
+ if (_connection._started)
+ {
+ channel.Start();
+ }
+ return channel;
+ }
+ }
+
+ internal ushort NextChannelId()
+ {
+ return (ushort) Interlocked.Increment(ref _nextChannelId);
+ }
+
+ public IChannel CreateChannel(bool transacted, AcknowledgeMode acknowledgeMode)
+ {
+ return CreateChannel(transacted, acknowledgeMode, AmqChannel.DEFAULT_PREFETCH_HIGH_MARK);
+ }
+
+ public IChannel CreateChannel(bool transacted, AcknowledgeMode acknowledgeMode, int prefetch)
+ {
+ return CreateChannel(transacted, acknowledgeMode, prefetch, prefetch);
+ }
+
+ public IChannel CreateChannel(bool transacted, AcknowledgeMode acknowledgeMode, int prefetchHigh, int prefetchLow)
+ {
+ CheckNotClosed();
+ if (ChannelLimitReached())
+ {
+ throw new ChannelLimitReachedException(_maximumChannelCount);
+ }
+ else
+ {
+ CreateChannelFailoverSupport operation =
+ new CreateChannelFailoverSupport(this, transacted, acknowledgeMode, prefetchHigh, prefetchLow);
+ return (IChannel)operation.execute(this);
+ }
+ }
+
+ public void CloseSession(AmqChannel channel)
+ {
+ // FIXME: Don't we need FailoverSupport here (as we have SyncWrite).
+ _protocolSession.CloseSession(channel);
+
+ AMQFrame frame = ChannelCloseBody.CreateAMQFrame(
+ channel.ChannelId, 200, "JMS client closing channel", 0, 0);
+
+ _log.Debug("Blocking for channel close frame for channel " + channel.ChannelId);
+ _protocolWriter.SyncWrite(frame, typeof(ChannelCloseOkBody));
+ _log.Debug("Received channel close frame");
+ // When control resumes at this point, a reply will have been received that
+ // indicates the broker has closed the channel successfully
+ }
+
+ public ExceptionListenerDelegate ExceptionListener
+ {
+ get
+ {
+ CheckNotClosed();
+ return _exceptionListener;
+ }
+ set
+ {
+ CheckNotClosed();
+ _exceptionListener = value;
+ }
+ }
+
+ /// <summary>
+ /// Start the connection, i.e. start flowing messages. Note that this method must be called only from a single thread
+ /// and is not thread safe (which is legal according to the JMS specification).
+ /// @throws JMSException
+ /// </summary>
+ public void Start()
+ {
+ CheckNotClosed();
+
+ if (!_started)
+ {
+ foreach (DictionaryEntry lde in _sessions)
+ {
+ AmqChannel s = (AmqChannel)lde.Value;
+ s.Start();
+ }
+ _started = true;
+ }
+ }
+
+ public void Stop()
+ {
+ CheckNotClosed();
+
+ if (_started)
+ {
+ foreach (DictionaryEntry lde in _sessions)
+ {
+ AmqChannel s = (AmqChannel) lde.Value;
+ s.Stop();
+ }
+ _started = false;
+ }
+ }
+
+ public IConnectionListener ConnectionListener
+ {
+ get { return _connectionListener; }
+ set { _connectionListener = value; }
+ }
+
+ #endregion
+
+ #region IDisposable Members
+
+ public void Dispose()
+ {
+ Close();
+ }
+
+ #endregion
+
+ private bool ChannelLimitReached()
+ {
+ return _maximumChannelCount != 0 && _sessions.Count == _maximumChannelCount;
+ }
+
+ /// <summary>
+ /// Close all the sessions, either due to normal connection closure or due to an error occurring.
+ /// @param cause if not null, the error that is causing this shutdown
+ /// </summary>
+ private void CloseAllSessions(Exception cause)
+ {
+ _log.Debug("Closing all session in connection " + this);
+ ICollection sessions = new ArrayList(_sessions.Values);
+ foreach (AmqChannel channel in sessions)
+ {
+ _log.Debug("Closing channel " + channel);
+ if (cause != null)
+ {
+ channel.ClosedWithException(cause);
+ }
+ else
+ {
+ try
+ {
+ channel.Close();
+ }
+ catch (QpidException e)
+ {
+ _log.Error("Error closing channel: " + e);
+ }
+ }
+ }
+ _log.Debug("Done closing all sessions in connection " + this);
+ }
+
+ public int MaximumChannelCount
+ {
+ get
+ {
+ CheckNotClosed();
+ return _maximumChannelCount;
+ }
+ }
+
+ internal void SetMaximumChannelCount(ushort maximumChannelCount)
+ {
+ CheckNotClosed();
+ _maximumChannelCount = maximumChannelCount;
+ }
+
+ public uint MaximumFrameSize
+ {
+ get
+ {
+ return _maximumFrameSize;
+ }
+
+ set
+ {
+ _maximumFrameSize = value;
+ }
+ }
+
+ public IDictionary Sessions
+ {
+ get
+ {
+ return _sessions;
+ }
+ }
+
+ public string Host
+ {
+ get
+ {
+ return _failoverPolicy.GetCurrentBrokerInfo().Host;
+ }
+ }
+
+ public int Port
+ {
+ get
+ {
+ return _failoverPolicy.GetCurrentBrokerInfo().Port;
+ }
+ }
+
+ public string Username
+ {
+ get
+ {
+ return _connectionInfo.Username;
+ }
+ }
+
+ public string Password
+ {
+ get
+ {
+ return _connectionInfo.Password;
+ }
+ }
+
+ public string VirtualHost
+ {
+ get
+ {
+ return _connectionInfo.VirtualHost;
+ }
+ }
+
+ /// <summary>
+ /// Invoked by the AMQProtocolSession when a protocol session exception has occurred.
+ /// This method sends the exception to a JMS exception listener, if configured, and
+ /// propagates the exception to sessions, which in turn will propagate to consumers.
+ /// This allows synchronous consumers to have exceptions thrown to them.
+ /// </summary>
+ /// <param name="cause">the exception</param>
+ public void ExceptionReceived(Exception cause)
+ {
+ if (_exceptionListener != null)
+ {
+ // Listener expects one of these...
+ QpidException xe;
+
+ if (cause is QpidException)
+ {
+ xe = (QpidException) cause;
+ }
+ else
+ {
+ xe = new QpidException("Exception thrown against " + ToString() + ": " + cause, cause);
+ }
+ // in the case of an IOException, MINA has closed the protocol session so we set _closed to true
+ // so that any generic client code that tries to close the connection will not mess up this error
+ // handling sequence
+ if (cause is IOException)
+ {
+ Interlocked.Exchange(ref _closed, CLOSED);
+ }
+#if __MonoCS__
+ _exceptionListener(xe);
+#else
+ _exceptionListener.Invoke(xe);
+#endif
+ }
+ else
+ {
+ _log.Error("Connection exception: " + cause);
+ }
+
+ // An undelivered is not fatal to the connections usability.
+ if (!(cause is AMQUndeliveredException))
+ {
+ Interlocked.Exchange(ref _closed, CLOSED);
+ CloseAllSessions(cause);
+ }
+ else
+ {
+ ;
+ }
+ }
+
+ internal void RegisterSession(int channelId, AmqChannel channel)
+ {
+ _sessions[channelId] = channel;
+ }
+
+ internal void DeregisterSession(int channelId)
+ {
+ _sessions.Remove(channelId);
+ }
+
+ /**
+ * Fire the preFailover event to the registered connection listener (if any)
+ *
+ * @param redirect true if this is the result of a redirect request rather than a connection error
+ * @return true if no listener or listener does not veto change
+ */
+ public bool FirePreFailover(bool redirect)
+ {
+ bool proceed = true;
+ if (_connectionListener != null)
+ {
+ proceed = _connectionListener.PreFailover(redirect);
+ }
+ return proceed;
+ }
+
+ /**
+ * Fire the preResubscribe event to the registered connection listener (if any). If the listener
+ * vetoes resubscription then all the sessions are closed.
+ *
+ * @return true if no listener or listener does not veto resubscription.
+ * @throws JMSException
+ */
+ public bool FirePreResubscribe()
+ {
+ if (_connectionListener != null)
+ {
+ bool resubscribe = _connectionListener.PreResubscribe();
+ if (!resubscribe)
+ {
+ MarkAllSessionsClosed();
+ }
+ return resubscribe;
+ }
+ else
+ {
+ return true;
+ }
+ }
+
+ /**
+ * Marks all sessions and their children as closed without sending any protocol messages. Useful when
+ * you need to mark objects "visible" in userland as closed after failover or other significant event that
+ * impacts the connection.
+ * <p/>
+ * The caller must hold the failover mutex before calling this method.
+ */
+ private void MarkAllSessionsClosed()
+ {
+ //LinkedList sessionCopy = new LinkedList(_sessions.values());
+ ArrayList sessionCopy = new ArrayList(_sessions.Values);
+ foreach (AmqChannel session in sessionCopy)
+ {
+ session.MarkClosed();
+ }
+ _sessions.Clear();
+ }
+
+ /**
+ * Fires a failover complete event to the registered connection listener (if any).
+ */
+ public void FireFailoverComplete()
+ {
+ if (_connectionListener != null)
+ {
+ _connectionListener.FailoverComplete();
+ }
+ }
+
+ public bool AttemptReconnection(String host, int port, SslOptions sslConfig)
+ {
+ IBrokerInfo bd = new AmqBrokerInfo("amqp", host, port, sslConfig);
+
+ _failoverPolicy.setBroker(bd);
+
+ try
+ {
+ MakeBrokerConnection(bd);
+ return true;
+ }
+ catch (Exception e)
+ {
+ _log.Debug("Unable to connect to broker at " + bd, e);
+ AttemptReconnection();
+ }
+ return false;
+ }
+
+ private void MakeBrokerConnection(IBrokerInfo brokerDetail)
+ {
+ try
+ {
+ _stateManager = new AMQStateManager();
+ _protocolListener = new AMQProtocolListener(this, _stateManager);
+ _protocolListener.AddFrameListener(_stateManager);
+
+ /*
+ // Currently there is only one transport option - BlockingSocket.
+ String assemblyName = "Apache.Qpid.Client.Transport.Socket.Blocking.dll";
+ String transportType = "Apache.Qpid.Client.Transport.Socket.Blocking.BlockingSocketTransport";
+
+ // Load the transport assembly dynamically.
+ _transport = LoadTransportFromAssembly(brokerDetail.getHost(), brokerDetail.getPort(), assemblyName, transportType);
+ */
+
+ _transport = new BlockingSocketTransport();
+
+ // Connect.
+ _transport.Connect(brokerDetail, this);
+ _protocolWriter = new ProtocolWriter(_transport.ProtocolWriter, _protocolListener);
+ _protocolSession = new AMQProtocolSession(_transport.ProtocolWriter, _transport, this);
+ _protocolListener.ProtocolSession = _protocolSession;
+
+ // Now start the connection "handshake".
+ _transport.ProtocolWriter.Write(new ProtocolInitiation());
+
+ // Blocks until the connection has been opened.
+ _stateManager.AttainState(AMQState.CONNECTION_OPEN);
+
+ _failoverPolicy.attainedConnection();
+
+ // XXX: Again this should be changed to a suitable notify.
+ _connected = true;
+ }
+ catch (AMQException e)
+ {
+ _lastAMQException = e;
+ throw; // rethrow
+ }
+ }
+
+ public bool AttemptReconnection()
+ {
+ while (_failoverPolicy.FailoverAllowed())
+ {
+ try
+ {
+ MakeBrokerConnection(_failoverPolicy.GetNextBrokerInfo());
+ return true;
+ }
+ catch (Exception e)
+ {
+ if (!(e is AMQException))
+ {
+ _log.Debug("Unable to connect to broker at " + _failoverPolicy.GetCurrentBrokerInfo(), e);
+ }
+ else
+ {
+ _log.Debug(e.Message + ":Unable to connect to broker at " + _failoverPolicy.GetCurrentBrokerInfo());
+ }
+ }
+ }
+
+ // Connection unsuccessful.
+ return false;
+ }
+
+ /**
+ * For all channels, and for all consumers in those sessions, resubscribe. This is called during failover handling.
+ * The caller must hold the failover mutex before calling this method.
+ */
+ public void ResubscribeChannels()
+ {
+ ArrayList channels = new ArrayList(_sessions.Values);
+ _log.Debug(String.Format("Resubscribing sessions = {0} sessions.size={1}", channels, channels.Count));
+ foreach (AmqChannel channel in channels)
+ {
+ _protocolSession.AddSessionByChannel(channel.ChannelId, channel);
+ ReopenChannel(
+ channel.ChannelId,
+ channel.DefaultPrefetchHigh,
+ channel.DefaultPrefetchLow,
+ channel.Transacted
+ );
+ channel.ReplayOnFailOver();
+ }
+ }
+
+ private void ReopenChannel(ushort channelId, int prefetchHigh, int prefetchLow, bool transacted)
+ {
+ _log.Debug(string.Format("Reopening channel id={0} prefetchHigh={1} prefetchLow={2} transacted={3}",
+ channelId, prefetchHigh, prefetchLow, transacted));
+ try
+ {
+ CreateChannelOverWire(channelId, prefetchHigh, prefetchLow, transacted);
+ }
+ catch (AMQException e)
+ {
+ _protocolSession.RemoveSessionByChannel(channelId);
+ DeregisterSession(channelId);
+ throw new AMQException("Error reopening channel " + channelId + " after failover: " + e);
+ }
+ }
+
+ void CreateChannelOverWire(ushort channelId, int prefetchHigh, int prefetchLow, bool transacted)
+ {
+ _protocolWriter.SyncWrite(ChannelOpenBody.CreateAMQFrame(channelId, null), typeof (ChannelOpenOkBody));
+
+ // Don't use the BasicQos frame if connecting to OpenAMQ (at it is not support). We
+ // know this when we connection using AMQP 0.7
+ if (ProtocolInitiation.CURRENT_PROTOCOL_VERSION_MAJOR != 7)
+ {
+ // Basic.Qos frame appears to not be supported by OpenAMQ 1.0d.
+ _protocolWriter.SyncWrite(BasicQosBody.CreateAMQFrame(channelId, 0, (ushort)prefetchHigh, false), typeof (BasicQosOkBody));
+ }
+
+ if (transacted)
+ {
+ if (_log.IsDebugEnabled)
+ {
+ _log.Debug("Issuing TxSelect for " + channelId);
+ }
+ _protocolWriter.SyncWrite(TxSelectBody.CreateAMQFrame(channelId), typeof(TxSelectOkBody));
+ }
+ }
+
+ public String toURL()
+ {
+ return _connectionInfo.AsUrl();
+ }
+
+ class HeartBeatThread
+ {
+ int _heartbeatMillis;
+ IProtocolWriter _protocolWriter;
+ bool _run = true;
+
+ public HeartBeatThread(IProtocolWriter protocolWriter, int heartbeatMillis)
+ {
+ _protocolWriter = protocolWriter;
+ _heartbeatMillis = heartbeatMillis;
+ }
+
+ public void Run()
+ {
+ while (_run)
+ {
+ Thread.Sleep(_heartbeatMillis);
+ if (!_run) break;
+ _log.Debug("Sending heartbeat");
+ // TODO: Can we optimise this so that heartbeats are only written when we haven't sent anything recently to the broker?
+ _protocolWriter.Write(HeartbeatBody.FRAME);
+ }
+ _log.Debug("Heatbeat thread stopped");
+ }
+
+ public void Stop()
+ {
+ _run = false;
+ }
+ }
+
+ public void StartHeartBeatThread(int heartbeatSeconds)
+ {
+ _log.Debug("Starting new heartbeat thread");
+ _heartBeatRunner = new HeartBeatThread(ProtocolWriter, heartbeatSeconds * 1000);
+ _heartBeatThread = new Thread(new ThreadStart(_heartBeatRunner.Run));
+ _heartBeatThread.Name = "HeartBeat";
+ _heartBeatThread.Start();
+ }
+
+ public void StopHeartBeatThread()
+ {
+ if (_heartBeatRunner != null)
+ {
+ _log.Debug("Stopping old heartbeat thread");
+ _heartBeatRunner.Stop();
+ }
+ }
+ }
+}
diff --git a/qpid/dotnet/Qpid.Client/Client/AMQConnectionException.cs b/qpid/dotnet/Qpid.Client/Client/AMQConnectionException.cs
new file mode 100644
index 0000000000..c8a48814bb
--- /dev/null
+++ b/qpid/dotnet/Qpid.Client/Client/AMQConnectionException.cs
@@ -0,0 +1,38 @@
+/*
+ *
+ * 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.
+ *
+ */
+using System;
+using System.Runtime.Serialization;
+
+namespace Apache.Qpid.Client
+{
+ [Serializable]
+ public class AMQConnectionException : AMQException
+ {
+ public AMQConnectionException(String message, Exception e) : base(message, e)
+ {
+ }
+
+ protected AMQConnectionException(SerializationInfo info, StreamingContext ctxt)
+ : base(info, ctxt)
+ {
+ }
+ }
+}
diff --git a/qpid/dotnet/Qpid.Client/Client/AMQDestination.cs b/qpid/dotnet/Qpid.Client/Client/AMQDestination.cs
new file mode 100644
index 0000000000..07ce3c2354
--- /dev/null
+++ b/qpid/dotnet/Qpid.Client/Client/AMQDestination.cs
@@ -0,0 +1,234 @@
+/*
+ *
+ * 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.
+ *
+ */
+using System;
+
+namespace Apache.Qpid.Client
+{
+ public abstract class AMQDestination
+ {
+ protected readonly string _exchangeName;
+ protected readonly string _exchangeClass;
+ protected readonly string _destinationName;
+ protected readonly bool _isExclusive;
+ protected readonly bool _isAutoDelete;
+ protected bool _isDurable;
+
+ public bool IsDurable
+ {
+
+ get { return _isDurable; }
+ }
+
+ protected string _queueName;
+
+ protected AMQDestination(String exchangeName, String exchangeClass, String destinationName, bool isExclusive,
+ bool isAutoDelete, String queueName)
+ {
+ // XXX: This is ugly - OnlyRequired because of ReplyToDestination.
+// if (destinationName == null)
+// {
+// throw new ArgumentNullException("destinationName");
+// }
+
+ // XXX: This is ugly - OnlyRequired because of SendingDestinationAdapter.
+// if (exchangeName == null)
+// {
+// throw new ArgumentNullException("exchangeName");
+// }
+
+ // XXX: This is ugly - OnlyRequired because of SendingDestinationAdapter.
+// if (exchangeClass == null)
+// {
+// throw new ArgumentNullException("exchangeClass");
+// }
+
+ _exchangeName = exchangeName;
+ _exchangeClass = exchangeClass;
+ _destinationName = destinationName;
+ _isExclusive = isExclusive;
+ _isAutoDelete = isAutoDelete;
+ _queueName = queueName;
+ }
+
+ public string Name
+ {
+ get
+ {
+ return _destinationName;
+ }
+ }
+
+ public abstract string RoutingKey
+ {
+ get;
+ }
+
+ public abstract string EncodedName
+ {
+ get;
+ }
+
+ public bool AutoDelete
+ {
+ get
+ {
+ return _isAutoDelete;
+ }
+ }
+
+ public string QueueName
+ {
+ get
+ {
+ return _queueName;
+ }
+ set
+ {
+ _queueName = value;
+ }
+ }
+
+ public string ExchangeName
+ {
+ get
+ {
+ return _exchangeName;
+ }
+ }
+
+ public string ExchangeClass
+ {
+ get
+ {
+ return _exchangeClass;
+ }
+ }
+
+ public bool IsExclusive
+ {
+ get
+ {
+ return _isExclusive;
+ }
+ }
+
+ public bool IsAutoDelete
+ {
+ get
+ {
+ return _isAutoDelete;
+ }
+ }
+
+ public override string ToString()
+ {
+ return "Destination: " + _destinationName + ", " +
+ "Queue Name: " + _queueName + ", Exchange: " + _exchangeName +
+ ", Exchange class: " + _exchangeClass + ", Exclusive: " + _isExclusive +
+ ", AutoDelete: " + _isAutoDelete; // +", Routing Key: " + RoutingKey;
+ }
+
+ public override bool Equals(object o)
+ {
+ if (this == o)
+ {
+ return true;
+ }
+ if (o == null || GetType() != o.GetType())
+ {
+ return false;
+ }
+
+ AMQDestination that = (AMQDestination) o;
+
+ if (!StringsNotEqualNullSafe(_destinationName, that._destinationName))
+ {
+ return false;
+ }
+ if (!StringsNotEqualNullSafe(_exchangeClass, that._exchangeClass))
+ {
+ return false;
+ }
+ if (!StringsNotEqualNullSafe(_exchangeName, that._exchangeName))
+ {
+ return false;
+ }
+ if (!StringsNotEqualNullSafe(_queueName, that._queueName))
+ {
+ return false;
+ }
+ if (_isExclusive != that._isExclusive)
+ {
+ return false;
+ }
+ if (_isAutoDelete != that._isAutoDelete)
+ {
+ return false;
+ }
+ return true;
+ }
+
+ private bool StringsNotEqualNullSafe(string one, string two)
+ {
+ if ((one == null && two != null) ||
+ (one != null && !one.Equals(two)))
+ {
+ return false;
+ }
+ else
+ {
+ return true;
+ }
+ }
+
+ public override int GetHashCode()
+ {
+ int result;
+ if (_exchangeName == null)
+ {
+ result = "".GetHashCode();
+ }
+ else
+ {
+ result = _exchangeName.GetHashCode();
+ }
+ if (_exchangeClass != null)
+ {
+ result = 29 * result + _exchangeClass.GetHashCode();
+ }
+ if (_destinationName != null)
+ {
+ result = 29 * result + _destinationName.GetHashCode();
+ }
+ if (_queueName != null)
+ {
+ result = 29 * result + _queueName.GetHashCode();
+ }
+ result = result * (_isExclusive ? 13 : 7);
+ result = result * (_isAutoDelete ? 13 : 7);
+
+ Console.WriteLine("FIXME HashCode for " + this + " = " + result);
+ return result;
+ }
+
+ public abstract bool IsNameRequired { get; }
+ }
+}
diff --git a/qpid/dotnet/Qpid.Client/Client/AMQNoConsumersException.cs b/qpid/dotnet/Qpid.Client/Client/AMQNoConsumersException.cs
new file mode 100644
index 0000000000..5c9dd86c53
--- /dev/null
+++ b/qpid/dotnet/Qpid.Client/Client/AMQNoConsumersException.cs
@@ -0,0 +1,45 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+using System;
+using System.Runtime.Serialization;
+using Apache.Qpid.Common;
+using Apache.Qpid.Protocol;
+
+namespace Apache.Qpid.Client
+{
+ [Serializable]
+ public class AMQNoConsumersException : AMQUndeliveredException
+ {
+ public AMQNoConsumersException(string message)
+ : this(message, null)
+ {
+ }
+
+ public AMQNoConsumersException(string message, object bounced)
+ : base(AMQConstant.NO_CONSUMERS.Code, message, bounced)
+ {
+ }
+ protected AMQNoConsumersException(SerializationInfo info, StreamingContext ctxt)
+ : base(info, ctxt)
+ {
+ }
+ }
+}
diff --git a/qpid/dotnet/Qpid.Client/Client/AMQNoRouteException.cs b/qpid/dotnet/Qpid.Client/Client/AMQNoRouteException.cs
new file mode 100644
index 0000000000..5868d78f32
--- /dev/null
+++ b/qpid/dotnet/Qpid.Client/Client/AMQNoRouteException.cs
@@ -0,0 +1,46 @@
+/*
+ *
+ * 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.
+ *
+ */
+using System;
+using System.Runtime.Serialization;
+using Apache.Qpid.Common;
+using Apache.Qpid.Protocol;
+
+namespace Apache.Qpid.Client
+{
+ [Serializable]
+ public class AMQNoRouteException : AMQUndeliveredException
+ {
+ public AMQNoRouteException(string message)
+ : this(message, null)
+ {
+ }
+
+ public AMQNoRouteException(string message, object bounced)
+ : base(AMQConstant.NO_ROUTE.Code, message, bounced)
+ {
+ }
+
+ protected AMQNoRouteException(SerializationInfo info, StreamingContext ctxt)
+ : base(info, ctxt)
+ {
+ }
+ }
+}
diff --git a/qpid/dotnet/Qpid.Client/Client/AmqBrokerInfo.cs b/qpid/dotnet/Qpid.Client/Client/AmqBrokerInfo.cs
new file mode 100644
index 0000000000..591c5b941f
--- /dev/null
+++ b/qpid/dotnet/Qpid.Client/Client/AmqBrokerInfo.cs
@@ -0,0 +1,322 @@
+/*
+ *
+ * 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.
+ *
+ */
+using System;
+using System.Collections;
+using System.Text;
+using Apache.Qpid.Client.Qms;
+
+namespace Apache.Qpid.Client
+{
+ public class AmqBrokerInfo : IBrokerInfo
+ {
+ public readonly string URL_FORMAT_EXAMPLE =
+ "<transport>://<hostname>[:<port Default=\""+BrokerInfoConstants.DEFAULT_PORT+"\">][?<option>='<value>'[,<option>='<value>']]";
+
+ public const long DEFAULT_CONNECT_TIMEOUT = 30000L;
+
+ private string _host = "localhost";
+ private int _port = 5672;
+ private string _transport = "amqp";
+ private Hashtable _options = new Hashtable();
+ private SslOptions _sslOptions;
+
+ public AmqBrokerInfo()
+ {
+ }
+
+ public AmqBrokerInfo(string url)
+ {
+ // URL should be of format tcp://host:port?option='value',option='value'
+ try
+ {
+ Uri connection = new Uri(url);
+
+ String transport = connection.Scheme;
+
+ // Handles some defaults to minimise changes to existing broker URLS e.g. localhost
+ if (transport != null)
+ {
+ transport = transport.ToLower();
+ //todo this list of valid transports should be enumerated somewhere
+ if ((!(transport.Equals("vm") || transport.Equals("tcp"))))
+ {
+ if (transport.Equals("localhost"))
+ {
+ connection = new Uri(BrokerInfoConstants.DEFAULT_TRANSPORT + "://" + url);
+ transport = connection.Scheme;
+ }
+ else
+ {
+ if (url[transport.Length] == ':' && url[transport.Length + 1] != '/')
+ {
+ //Then most likely we have a host:port value
+ connection = new Uri(BrokerInfoConstants.DEFAULT_TRANSPORT + "://" + url);
+ transport = connection.Scheme;
+ }
+ else
+ {
+ URLHelper.parseError(0, transport.Length, "Unknown transport", url);
+ }
+ }
+ }
+ }
+ else
+ {
+ //Default the transport
+ connection = new Uri(BrokerInfoConstants.DEFAULT_TRANSPORT + "://" + url);
+ transport = connection.Scheme;
+ }
+
+ if (transport == null)
+ {
+ URLHelper.parseError(-1, "Unknown transport:'" + transport + "'" +
+ " In broker URL:'" + url + "' Format: " + URL_FORMAT_EXAMPLE, "");
+ }
+
+ Transport = transport;
+
+ String host = connection.Host;
+ if (!host.Equals("default")) Host = host;
+
+ int port = connection.Port;
+
+ if (port == -1)
+ {
+ // Fix for when there is port data but it is not automatically parseable by getPort().
+ String auth = connection.Authority;
+
+ if (auth != null && auth.IndexOf(':') != -1)
+ {
+ int start = auth.IndexOf(":") + 1;
+ int end = start;
+ bool looking = true;
+ bool found = false;
+ //Walk the authority looking for a port value.
+ while (looking)
+ {
+ try
+ {
+ end++;
+ int.Parse(auth.Substring(start, end-start+1));
+
+ if (end >= auth.Length)
+ {
+ looking = false;
+ found = true;
+ }
+ }
+ catch (FormatException)
+ {
+ looking = false;
+ }
+
+ }
+ if (found)
+ {
+ Port = int.Parse(auth.Substring(start, end-start+1));
+ }
+ else
+ {
+ URLHelper.parseError(connection.ToString().IndexOf(connection.Authority) + end - 1,
+ "Illegal character in port number", connection.ToString());
+ }
+ }
+ else
+ {
+ Port = BrokerInfoConstants.DEFAULT_PORT;
+ }
+ }
+ else
+ {
+ Port = port;
+ }
+
+ String queryString = connection.Query;
+ if (queryString.Length > 0 && queryString[0] == '?')
+ {
+ queryString = queryString.Substring(1);
+ }
+
+ URLHelper.parseOptions(_options, queryString);
+
+ //Fragment is #string (not used)
+ }
+ catch (UriFormatException uris)
+ {
+ throw uris;
+// if (uris is UrlSyntaxException)
+// {
+// throw uris;
+// }
+//
+// URLHelper.parseError(uris.getIndex(), uris.getReason(), uris.getInput());
+ }
+ }
+
+ public AmqBrokerInfo(string transport, string host, int port, bool useSSL) : this()
+ {
+ _transport = transport;
+ _host = host;
+ _port = port;
+
+ if (useSSL)
+ {
+ SetOption(BrokerInfoConstants.OPTIONS_SSL, "true");
+ }
+ }
+
+ public AmqBrokerInfo(string transport, string host, int port, SslOptions sslConfig)
+ : this()
+ {
+ _transport = transport;
+ _host = host;
+ _port = port;
+
+ if ( sslConfig != null )
+ {
+ SetOption(BrokerInfoConstants.OPTIONS_SSL, "true");
+ _sslOptions = sslConfig;
+ }
+ }
+
+
+ public string Host
+ {
+ get { return _host; }
+ set { _host = value; }
+ }
+
+ public int Port
+ {
+ get { return _port; }
+ set { _port = value; }
+ }
+
+ public string Transport
+ {
+ get { return _transport; }
+ set { _transport = value; }
+ }
+
+ public SslOptions SslOptions
+ {
+ get { return _sslOptions; }
+ }
+
+ public string GetOption(string key)
+ {
+ return (string)_options[key];
+ }
+
+ public void SetOption(string key, string value)
+ {
+ _options[key] = value;
+ }
+
+ public long Timeout
+ {
+ get
+ {
+ if ( _options.ContainsKey(BrokerInfoConstants.OPTIONS_CONNECT_TIMEOUT) )
+ {
+ try
+ {
+ return long.Parse(GetOption(BrokerInfoConstants.OPTIONS_CONNECT_TIMEOUT));
+ } catch ( FormatException )
+ {
+ //Do nothing as we will use the default below.
+ }
+ }
+ return BrokerInfoConstants.DEFAULT_CONNECT_TIMEOUT;
+ }
+ set
+ {
+ SetOption(BrokerInfoConstants.OPTIONS_CONNECT_TIMEOUT, value.ToString());
+ }
+ }
+
+ public override string ToString()
+ {
+ StringBuilder sb = new StringBuilder();
+
+ sb.Append(_transport);
+ sb.Append("://");
+
+ if (!(StringEqualsIgnoreCase(_transport, "vm")))
+ {
+ sb.Append(_host);
+ }
+
+ sb.Append(':');
+ sb.Append(_port);
+
+ sb.Append(URLHelper.printOptions(_options));
+
+ return sb.ToString();
+ }
+
+ public override bool Equals(object obj)
+ {
+ if (!(obj is IBrokerInfo))
+ {
+ return false;
+ }
+
+ IBrokerInfo bd = (IBrokerInfo) obj;
+ return StringEqualsIgnoreCase(_host, bd.Host) &&
+ _port == bd.Port &&
+ StringEqualsIgnoreCase(_transport, bd.Transport) &&
+ UseSSL == bd.UseSSL;
+ }
+
+ public override int GetHashCode()
+ {
+ return _host.ToLower().GetHashCode() ^ _port.GetHashCode();
+ }
+
+ // TODO: move to util class.
+ private bool StringEqualsIgnoreCase(string one, string two)
+ {
+ return one.ToLower().Equals(two.ToLower());
+ }
+
+ public bool UseSSL
+ {
+ get
+ {
+ // To be friendly to users we should be case insensitive.
+ // or simply force users to conform to OPTIONS_SSL
+ // todo make case insensitive by trying ssl Ssl sSl ssL SSl SsL sSL SSL
+
+ if ( _options.ContainsKey(BrokerInfoConstants.OPTIONS_SSL) )
+ {
+ return StringEqualsIgnoreCase(GetOption(BrokerInfoConstants.OPTIONS_SSL), "true");
+ }
+
+ return false;
+ }
+ set
+ {
+ SetOption(BrokerInfoConstants.OPTIONS_SSL, value.ToString());
+ }
+ }
+ }
+}
diff --git a/qpid/dotnet/Qpid.Client/Client/AmqChannel.cs b/qpid/dotnet/Qpid.Client/Client/AmqChannel.cs
new file mode 100644
index 0000000000..84c7c06fe1
--- /dev/null
+++ b/qpid/dotnet/Qpid.Client/Client/AmqChannel.cs
@@ -0,0 +1,1241 @@
+/*
+ *
+ * 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.
+ *
+ */
+using System;
+using System.Collections;
+using System.Text.RegularExpressions;
+using System.Threading;
+using log4net;
+using Apache.Qpid.Buffer;
+using Apache.Qpid.Client.Message;
+using Apache.Qpid.Client.Util;
+using Apache.Qpid.Collections;
+using Apache.Qpid.Framing;
+using Apache.Qpid.Messaging;
+using Apache.Qpid.Protocol;
+
+namespace Apache.Qpid.Client
+{
+ /// <summary>
+ /// <p/><table id="crc"><caption>CRC Card</caption>
+ /// <tr><th> Responsibilities <th> Collaborations
+ /// <tr><td> Declare queues.
+ /// <tr><td> Declare exchanges.
+ /// <tr><td> Bind queues to exchanges.
+ /// <tr><td> Create messages.
+ /// <tr><td> Set up message consumers on the channel.
+ /// <tr><td> Set up message producers on the channel.
+ /// <tr><td> Commit the current transaction.
+ /// <tr><td> Roll-back the current transaction.
+ /// <tr><td> Close the channel.
+ /// </table>
+ /// </summary>
+ public class AmqChannel : Closeable, IChannel
+ {
+ private static readonly ILog _logger = LogManager.GetLogger(typeof(AmqChannel));
+
+ internal const int BASIC_CONTENT_TYPE = 60;
+
+ public const int DEFAULT_PREFETCH_HIGH_MARK = 5000;
+
+ public const int DEFAULT_PREFETCH_LOW_MARK = 2500;
+
+ private static int _nextSessionNumber = 0;
+
+ private AMQConnection _connection;
+
+ private int _sessionNumber;
+
+ private bool _suspended;
+
+ private object _suspensionLock = new object();
+
+ // Used in the consume method. We generate the consume tag on the client so that we can use the nowait feature.
+ private int _nextConsumerNumber = 1;
+
+ private bool _transacted;
+
+ private AcknowledgeMode _acknowledgeMode;
+
+ private ushort _channelId;
+
+ private int _defaultPrefetchHighMark = DEFAULT_PREFETCH_HIGH_MARK;
+
+ private int _defaultPrefetchLowMark = DEFAULT_PREFETCH_LOW_MARK;
+
+ private FlowControlQueue _queue;
+
+ private Dispatcher _dispatcher;
+
+ private MessageFactoryRegistry _messageFactoryRegistry;
+
+ /// <summary> Holds all of the producers created by this channel. </summary>
+ private Hashtable _producers = Hashtable.Synchronized(new Hashtable());
+
+ /// <summary> Holds all of the consumers created by this channel. </summary>
+ private Hashtable _consumers = Hashtable.Synchronized(new Hashtable());
+
+ private ArrayList _replayFrames = new ArrayList();
+
+ /// <summary>
+ /// The counter of the _next producer id. This id is generated by the session and used only to allow the
+ /// producer to identify itself to the session when deregistering itself.
+ ///
+ /// Access to this id does not require to be synchronized since according to the JMS specification only one
+ /// thread of control is allowed to create producers for any given session instance.
+ /// </summary>
+ private long _nextProducerId;
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="AmqChannel"/> class.
+ /// </summary>
+ /// <param name="con">The connection.</param>
+ /// <param name="channelId">The channel id.</param>
+ /// <param name="transacted">if set to <c>true</c> [transacted].</param>
+ /// <param name="acknowledgeMode">The acknowledge mode.</param>
+ /// <param name="defaultPrefetchHigh">Default prefetch high value</param>
+ /// <param name="defaultPrefetchLow">Default prefetch low value</param>
+ internal AmqChannel(AMQConnection con, ushort channelId, bool transacted, AcknowledgeMode acknowledgeMode,
+ int defaultPrefetchHigh, int defaultPrefetchLow)
+ : this()
+ {
+ _sessionNumber = Interlocked.Increment(ref _nextSessionNumber);
+ _connection = con;
+ _transacted = transacted;
+
+ if ( transacted )
+ {
+ _acknowledgeMode = AcknowledgeMode.SessionTransacted;
+ }
+ else
+ {
+ _acknowledgeMode = acknowledgeMode;
+ }
+
+ _channelId = channelId;
+ _defaultPrefetchHighMark = defaultPrefetchHigh;
+ _defaultPrefetchLowMark = defaultPrefetchLow;
+
+ if ( _acknowledgeMode == AcknowledgeMode.NoAcknowledge )
+ {
+ _queue = new FlowControlQueue(_defaultPrefetchLowMark, _defaultPrefetchHighMark,
+ new ThresholdMethod(OnPrefetchLowMark),
+ new ThresholdMethod(OnPrefetchHighMark));
+ }
+ else
+ {
+ // low and upper are the same
+ _queue = new FlowControlQueue(_defaultPrefetchHighMark, _defaultPrefetchHighMark,
+ null, null);
+ }
+ }
+
+ private AmqChannel()
+ {
+ _messageFactoryRegistry = MessageFactoryRegistry.NewDefaultRegistry();
+ }
+
+ /// <summary>
+ /// Acknowledge mode for messages received.
+ /// </summary>
+ public AcknowledgeMode AcknowledgeMode
+ {
+ get
+ {
+ CheckNotClosed();
+ return _acknowledgeMode;
+ }
+ }
+
+ /// <summary>
+ /// True if the channel should use transactions.
+ /// </summary>
+ public bool Transacted
+ {
+ get
+ {
+ CheckNotClosed();
+ return _transacted;
+ }
+ }
+
+ /// <summary>
+ /// Prefetch value to be used as the default for
+ /// consumers created on this channel.
+ /// </summary>
+ public int DefaultPrefetch
+ {
+ get { return DefaultPrefetchHigh; }
+ }
+
+ /// <summary>
+ /// Prefetch low value to be used as the default for
+ /// consumers created on this channel.
+ /// </summary>
+ public int DefaultPrefetchLow
+ {
+ get { return _defaultPrefetchLowMark; }
+ }
+
+ /// <summary>
+ /// Prefetch high value to be used as the default for
+ /// consumers created on this channel.
+ /// </summary>
+ public int DefaultPrefetchHigh
+ {
+ get { return _defaultPrefetchHighMark; }
+ }
+
+ /// <summary> Indicates whether or not this channel is currently suspended. </summary>
+ public bool IsSuspended
+ {
+ get { return _suspended; }
+ }
+
+ /// <summary> Provides the channels number within the the connection. </summary>
+ public ushort ChannelId
+ {
+ get { return _channelId; }
+ }
+
+ /// <summary> Provides the connection that this channel runs over. </summary>
+ public AMQConnection Connection
+ {
+ get { return _connection; }
+ }
+
+ /// <summary>
+ /// Declare a new exchange.
+ /// </summary>
+ /// <param name="exchangeName">Name of the exchange</param>
+ /// <param name="exchangeClass">Class of the exchange, from <see cref="ExchangeClassConstants"/></param>
+ public void DeclareExchange(String exchangeName, String exchangeClass)
+ {
+ _logger.Debug(string.Format("DeclareExchange vame={0} exchangeClass={1}", exchangeName, exchangeClass));
+
+ DeclareExchange(_channelId, 0, exchangeName, exchangeClass, false, false, false, false, true, null);
+ }
+
+ /// <summary>
+ /// Declare a new exchange using the default exchange class.
+ /// </summary>
+ /// <param name="exchangeName">Name of the exchange</param>
+ public void DeleteExchange(string exchangeName)
+ {
+ throw new NotImplementedException();
+ }
+
+ /// <summary>
+ /// Declare a new queue with the specified set of arguments.
+ /// </summary>
+ /// <param name="queueName">Name of the queue</param>
+ /// <param name="isDurable">True if the queue should be durable</param>
+ /// <param name="isExclusive">True if the queue should be exclusive to this channel</param>
+ /// <param name="isAutoDelete">True if the queue should be deleted when the channel closes</param>
+ public void DeclareQueue(string queueName, bool isDurable, bool isExclusive, bool isAutoDelete)
+ {
+ DoQueueDeclare(queueName, isDurable, isExclusive, isAutoDelete, null);
+ }
+
+ /// <summary>
+ /// Declare a new queue with the specified set of arguments.
+ /// </summary>
+ /// <param name="queueName">Name of the queue</param>
+ /// <param name="isDurable">True if the queue should be durable</param>
+ /// <param name="isExclusive">True if the queue should be exclusive to this channel</param>
+ /// <param name="isAutoDelete">True if the queue should be deleted when the channel closes</param>
+ /// <param name="args">Optional arguments to Queue.Declare</param>
+ public void DeclareQueue(string queueName, bool isDurable, bool isExclusive, bool isAutoDelete, IFieldTable args)
+ {
+ DoQueueDeclare(queueName, isDurable, isExclusive, isAutoDelete, args);
+ }
+
+ /// <summary>
+ /// Delete a queue with the specifies arguments.
+ /// </summary>
+ /// <param name="queueName">Name of the queue to delete</param>
+ /// <param name="ifUnused">If true, the queue will not deleted if it has no consumers</param>
+ /// <param name="ifEmpty">If true, the queue will not deleted if it has no messages</param>
+ /// <param name="noWait">If true, the server will not respond to the method</param>
+ public void DeleteQueue(string queueName, bool ifUnused, bool ifEmpty, bool noWait)
+ {
+ DoDeleteQueue(queueName, ifUnused, ifEmpty, noWait);
+ }
+
+ /// <summary>
+ /// Generate a new Unique name to use for a queue.
+ /// </summary>
+ /// <returns>A unique name to this channel</returns>
+ public string GenerateUniqueName()
+ {
+ string result = _connection.ProtocolSession.GenerateQueueName();
+ return Regex.Replace(result, "[^a-z0-9_]", "_");
+ }
+
+ /// <summary>
+ /// Removes all messages from a queue.
+ /// </summary>
+ /// <param name="queueName">Name of the queue to delete</param>
+ /// <param name="noWait">If true, the server will not respond to the method</param>
+ public void PurgeQueue(string queueName, bool noWait)
+ {
+ DoPurgeQueue(queueName, noWait);
+ }
+
+ /// <summary>
+ /// Bind a queue to the specified exchange.
+ /// </summary>
+ /// <param name="queueName">Name of queue to bind</param>
+ /// <param name="exchangeName">Name of exchange to bind to</param>
+ /// <param name="routingKey">Routing key</param>
+ public void Bind(string queueName, string exchangeName, string routingKey)
+ {
+ DoBind(queueName, exchangeName, routingKey, new FieldTable());
+ }
+
+ /// <summary>
+ /// Bind a queue to the specified exchange.
+ /// </summary>
+ /// <param name="queueName">Name of queue to bind</param>
+ /// <param name="exchangeName">Name of exchange to bind to</param>
+ /// <param name="routingKey">Routing key</param>
+ /// <param name="args">Table of arguments for the binding. Used to bind with a Headers Exchange</param>
+ public void Bind(string queueName, string exchangeName, string routingKey, IFieldTable args)
+ {
+ DoBind(queueName, exchangeName, routingKey, (FieldTable)args);
+ }
+
+ /// <summary>
+ /// Create a new empty message with no body.
+ /// </summary>
+ /// <returns>The new message</returns>
+ public IMessage CreateMessage()
+ {
+ return (IBytesMessage)_messageFactoryRegistry.CreateMessage("application/octet-stream");
+ }
+
+ /// <summary>
+ /// Create a new message of the specified MIME type.
+ /// </summary>
+ /// <param name="mimeType">The mime type to create</param>
+ /// <returns>The new message</returns>
+ public IMessage CreateMessage(string mimeType)
+ {
+ return _messageFactoryRegistry.CreateMessage(mimeType);
+ }
+
+ /// <summary>
+ /// Creates a new message for bytes (application/octet-stream).
+ /// </summary>
+ /// <returns>The new message</returns>
+ public IBytesMessage CreateBytesMessage()
+ {
+ return (IBytesMessage)_messageFactoryRegistry.CreateMessage("application/octet-stream");
+ }
+
+ /// <summary>
+ /// Creates a new text message (text/plain) with empty content.
+ /// </summary>
+ /// <returns>The new message</returns>
+ public ITextMessage CreateTextMessage()
+ {
+ return CreateTextMessage(String.Empty);
+ }
+
+ /// <summary>
+ /// Creates a new text message (text/plain) with a body.
+ /// </summary>
+ /// <param name="text">Initial body of the message</param>
+ /// <returns>The new message</returns>
+ public ITextMessage CreateTextMessage(string text)
+ {
+ ITextMessage msg = (ITextMessage)_messageFactoryRegistry.CreateMessage("text/plain");
+ msg.Text = text;
+ return msg;
+ }
+
+ /// <summary>
+ /// Creates a new Consumer using the builder pattern.
+ /// </summary>
+ /// <param name="queueName">Name of queue to receive messages from</param>
+ /// <returns>The builder object</returns>
+ public MessageConsumerBuilder CreateConsumerBuilder(string queueName)
+ {
+ return new MessageConsumerBuilder(this, queueName);
+ }
+
+ /// <summary>
+ /// Creates a new consumer.
+ /// </summary>
+ /// <param name="queueName">Name of queue to receive messages from</param>
+ /// <param name="prefetchLow">Low prefetch value</param>
+ /// <param name="prefetchHigh">High prefetch value</param>
+ /// <param name="noLocal">If true, messages sent on this channel will not be received by this consumer</param>
+ /// <param name="exclusive">If true, the consumer opens the queue in exclusive mode</param>
+ /// <returns>The new consumer</returns>
+ public IMessageConsumer CreateConsumer(string queueName,
+ int prefetchLow,
+ int prefetchHigh,
+ bool noLocal,
+ bool exclusive)
+ {
+ _logger.Debug(String.Format("CreateConsumer queueName={0} prefetchLow={1} prefetchHigh={2} noLocal={3} exclusive={4} ",
+ queueName, prefetchLow, prefetchHigh, noLocal, exclusive));
+
+ return CreateConsumerImpl(queueName, prefetchLow, prefetchHigh, noLocal, exclusive, false);
+ }
+
+ /// <summary>
+ /// Creates a new consumer.
+ /// </summary>
+ /// <param name="queueName">Name of queue to receive messages from</param>
+ /// <param name="prefetchLow">Low prefetch value</param>
+ /// <param name="prefetchHigh">High prefetch value</param>
+ /// <param name="noLocal">If true, messages sent on this channel will not be received by this consumer</param>
+ /// <param name="exclusive">If true, the consumer opens the queue in exclusive mode</param>
+ /// <param name="browse">If true, the consumer only browses and does not consume messages</param>
+ /// <returns>The new consumer</returns>
+ public IMessageConsumer CreateConsumer(string queueName,
+ int prefetchLow,
+ int prefetchHigh,
+ bool noLocal,
+ bool exclusive,
+ bool browse)
+ {
+ _logger.Debug(String.Format("CreateConsumer queueName={0} prefetchLow={1} prefetchHigh={2} noLocal={3} exclusive={4} browse={5}",
+ queueName, prefetchLow, prefetchHigh, noLocal, exclusive, browse));
+
+ return CreateConsumerImpl(queueName, prefetchLow, prefetchHigh, noLocal, exclusive, browse);
+ }
+
+
+ /// <summary>
+ /// Unsubscribe from a queue.
+ /// </summary>
+ /// <param name="subscriptionName">Subscription name</param>
+ public void Unsubscribe(String name)
+ {
+ throw new NotImplementedException();
+ }
+
+ /// <summary>
+ /// Create a new message publisher using the builder pattern.
+ /// </summary>
+ /// <returns>The builder object</returns>
+ public MessagePublisherBuilder CreatePublisherBuilder()
+ {
+ return new MessagePublisherBuilder(this);
+ }
+
+ /// <summary>
+ /// Create a new message publisher.
+ /// </summary>
+ /// <param name="exchangeName">Name of exchange to publish to</param>
+ /// <param name="routingKey">Routing key</param>
+ /// <param name="deliveryMode">Default delivery mode</param>
+ /// <param name="timeToLive">Default TTL time of messages</param>
+ /// <param name="immediate">If true, sent immediately</param>
+ /// <param name="mandatory">If true, the broker will return an error
+ /// (as a connection exception) if the message cannot be delivered</param>
+ /// <param name="priority">Default message priority</param>
+ /// <returns>The new message publisher</returns>
+ public IMessagePublisher CreatePublisher(string exchangeName, string routingKey, DeliveryMode deliveryMode,
+ long timeToLive, bool immediate, bool mandatory, int priority)
+ {
+ _logger.Debug(string.Format("Using new CreatePublisher exchangeName={0}, exchangeClass={1} routingKey={2}",
+ exchangeName, "none", routingKey));
+
+ return CreateProducerImpl(exchangeName, routingKey, deliveryMode,
+ timeToLive, immediate, mandatory, priority);
+ }
+
+ /// <summary>
+ /// Recover after transaction failure.
+ /// </summary>
+ /// <remarks>The 0-8 protocol does not support this, not implemented exception will always be thrown.</remarks>
+ public void Recover()
+ {
+ CheckNotClosed();
+ CheckNotTransacted();
+
+ throw new NotImplementedException();
+ }
+
+ /// <summary>
+ /// Commit the transaction.
+ /// </summary>
+ public void Commit()
+ {
+ // FIXME: Fail over safety. Needs FailoverSupport?
+ CheckNotClosed();
+ CheckTransacted(); // throws IllegalOperationException if not a transacted session
+
+ try
+ {
+ // Acknowledge up to message last delivered (if any) for each consumer.
+ // Need to send ack for messages delivered to consumers so far.
+ foreach (BasicMessageConsumer consumer in _consumers.Values)
+ {
+ // Sends acknowledgement to server.
+ consumer.AcknowledgeDelivered();
+ }
+
+ // Commits outstanding messages sent and outstanding acknowledgements.
+ _connection.ConvenientProtocolWriter.SyncWrite(TxCommitBody.CreateAMQFrame(_channelId), typeof(TxCommitOkBody));
+ }
+ catch (AMQException e)
+ {
+ throw new QpidException("Failed to commit", e);
+ }
+ }
+
+ /// <summary>
+ /// Rollback the transaction.
+ /// </summary>
+ public void Rollback()
+ {
+ lock (_suspensionLock)
+ {
+ CheckTransacted(); // throws IllegalOperationException if not a transacted session
+
+ try
+ {
+ bool suspended = IsSuspended;
+ if (!suspended)
+ {
+ Suspend(true);
+ }
+
+ // Reject up to message last delivered (if any) for each consumer.
+ // Need to send reject for messages delivered to consumers so far.
+ foreach (BasicMessageConsumer consumer in _consumers.Values)
+ {
+ // Sends acknowledgement to server.
+ consumer.RejectUnacked();
+ }
+
+ _connection.ConvenientProtocolWriter.SyncWrite(TxRollbackBody.CreateAMQFrame(_channelId), typeof(TxRollbackOkBody));
+
+ if ( !suspended )
+ {
+ Suspend(false);
+ }
+ }
+ catch (AMQException e)
+ {
+ throw new QpidException("Failed to rollback", e);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Create a disconnected channel that will fault
+ /// for most things, but is useful for testing
+ /// </summary>
+ /// <returns>A new disconnected channel</returns>
+ public static IChannel CreateDisconnectedChannel()
+ {
+ return new AmqChannel();
+ }
+
+ public override void Close()
+ {
+ lock (_connection.FailoverMutex)
+ {
+ // We must close down all producers and consumers in an orderly fashion. This is the only method
+ // that can be called from a different thread of control from the one controlling the session
+
+ lock (_closingLock)
+ {
+ SetClosed();
+
+ // we pass null since this is not an error case
+ CloseProducersAndConsumers(null);
+
+ try
+ {
+ _connection.CloseSession(this);
+ }
+ catch (AMQException e)
+ {
+ throw new QpidException("Error closing session: " + e);
+ }
+ finally
+ {
+ _connection.DeregisterSession(_channelId);
+ }
+ }
+ }
+ }
+
+ /**
+ * Called when the server initiates the closure of the session
+ * unilaterally.
+ * @param e the exception that caused this session to be closed. Null causes the
+ */
+ public void ClosedWithException(Exception e)
+ {
+ lock (_connection.FailoverMutex)
+ {
+ // An AMQException has an error code and message already and will be passed in when closure occurs as a
+ // result of a channel close request
+ SetClosed();
+ AMQException amqe;
+
+ if (e is AMQException)
+ {
+ amqe = (AMQException) e;
+ }
+ else
+ {
+ amqe = new AMQException("Closing session forcibly", e);
+ }
+
+ _connection.DeregisterSession(_channelId);
+ CloseProducersAndConsumers(amqe);
+ }
+ }
+
+ public void MessageReceived(UnprocessedMessage message)
+ {
+ if (_logger.IsDebugEnabled)
+ {
+ _logger.Debug("Message received in session with channel id " + _channelId);
+ }
+
+ if ( message.DeliverBody == null )
+ {
+ ReturnBouncedMessage(message);
+ }
+ else
+ {
+ _queue.Enqueue(message);
+ }
+ }
+
+ public void Dispose()
+ {
+ Close();
+ }
+
+ private void SetClosed()
+ {
+ Interlocked.Exchange(ref _closed, CLOSED);
+ }
+
+ /// <summary>
+ /// Close all producers or consumers. This is called either in the error case or when closing the session normally.
+ /// <param name="amqe">the exception, may be null to indicate no error has occurred</param>
+ ///
+ private void CloseProducersAndConsumers(AMQException amqe)
+ {
+ try
+ {
+ CloseProducers();
+ }
+ catch (QpidException e)
+ {
+ _logger.Error("Error closing session: " + e, e);
+ }
+ try
+ {
+ CloseConsumers(amqe);
+ }
+ catch (QpidException e)
+ {
+ _logger.Error("Error closing session: " + e, e);
+ }
+ }
+
+ /// <summary>
+ /// Called to close message producers cleanly. This may or may <b>not</b> be as a result of an error. There is
+ /// currently no way of propagating errors to message producers (this is a JMS limitation).
+ /// </summary>
+ private void CloseProducers()
+ {
+ _logger.Debug("Closing producers on session " + this);
+
+ // we need to clone the list of producers since the close() method updates the _producers collection
+ // which would result in a concurrent modification exception
+ ArrayList clonedProducers = new ArrayList(_producers.Values);
+
+ foreach (BasicMessageProducer prod in clonedProducers)
+ {
+ _logger.Debug("Closing producer " + prod);
+ prod.Close();
+ }
+
+ // at this point the _producers map is empty
+ }
+
+ /// <summary>
+ /// Called to close message consumers cleanly. This may or may <b>not</b> be as a result of an error.
+ /// <param name="error">not null if this is a result of an error occurring at the connection level</param>
+ private void CloseConsumers(Exception error)
+ {
+ if (_dispatcher != null)
+ {
+ _dispatcher.StopDispatcher();
+ }
+
+ // we need to clone the list of consumers since the close() method updates the _consumers collection
+ // which would result in a concurrent modification exception
+ ArrayList clonedConsumers = new ArrayList(_consumers.Values);
+
+ foreach (BasicMessageConsumer con in clonedConsumers)
+ {
+ if (error != null)
+ {
+ con.NotifyError(error);
+ }
+ else
+ {
+ con.Close();
+ }
+ }
+
+ // at this point the _consumers map will be empty
+ }
+
+ private IMessagePublisher CreateProducerImpl(string exchangeName, string routingKey,
+ DeliveryMode deliveryMode,
+ long timeToLive, bool immediate, bool mandatory, int priority)
+ {
+ lock (_closingLock)
+ {
+ CheckNotClosed();
+
+ try
+ {
+ return new BasicMessageProducer(exchangeName, routingKey, _transacted, _channelId,
+ this, GetNextProducerId(),
+ deliveryMode, timeToLive, immediate, mandatory, priority);
+ }
+ catch (AMQException e)
+ {
+ _logger.Error("Error creating message producer: " + e, e);
+ throw new QpidException("Error creating message producer", e);
+ }
+ }
+ }
+
+ /// <summary> Creates a message consumer on this channel.</summary>
+ ///
+ /// <param name="queueName">The name of the queue to attach the consumer to.</param>
+ /// <param name="prefetchLow">The pre-fetch buffer low-water mark.</param>
+ /// <param name="prefetchHigh">The pre-fetch buffer high-water mark.</param>
+ /// <param name="noLocal">The no-local flag, <tt>true</tt> means that the consumer does not receive messages sent on this channel.</param>
+ /// <param name="exclusive">The exclusive flag, <tt>true</tt> gives this consumer exclusive receive access to the queue.</param>
+ ///
+ /// <return>The message consumer.</return>
+ private IMessageConsumer CreateConsumerImpl(string queueName,
+ int prefetchLow,
+ int prefetchHigh,
+ bool noLocal,
+ bool exclusive,
+ bool browse)
+ {
+ lock (_closingLock)
+ {
+ CheckNotClosed();
+
+ BasicMessageConsumer consumer = new BasicMessageConsumer(_channelId, queueName, noLocal,
+ _messageFactoryRegistry, this,
+ prefetchHigh, prefetchLow, exclusive,
+ browse);
+ try
+ {
+ RegisterConsumer(consumer);
+ }
+ catch (AMQException e)
+ {
+ throw new QpidException("Error registering consumer: " + e, e);
+ }
+
+ return consumer;
+ }
+ }
+
+ private void CheckTransacted()
+ {
+ if (!Transacted)
+ {
+ throw new InvalidOperationException("Channel is not transacted");
+ }
+ }
+
+ private void CheckNotTransacted()
+ {
+ if (Transacted)
+ {
+ throw new InvalidOperationException("Channel is transacted");
+ }
+ }
+
+ internal void Start()
+ {
+ _dispatcher = new Dispatcher(this);
+ Thread dispatcherThread = new Thread(new ThreadStart(_dispatcher.RunDispatcher));
+ dispatcherThread.IsBackground = true;
+ dispatcherThread.Start();
+ }
+
+ internal void Stop()
+ {
+ Suspend(true);
+ if (_dispatcher != null)
+ {
+ _dispatcher.StopDispatcher();
+ }
+ }
+
+ internal void RegisterConsumer(string consumerTag, IMessageConsumer consumer)
+ {
+ _consumers[consumerTag] = consumer;
+ }
+
+ /// <summary>
+ /// Called by the MessageConsumer when closing, to deregister the consumer from the
+ /// map from consumerTag to consumer instance.
+ /// </summary>
+ /// <param name="consumerTag">the consumer tag, that was broker-generated</param>
+ internal void DeregisterConsumer(string consumerTag)
+ {
+ _consumers.Remove(consumerTag);
+ }
+
+ internal void RegisterProducer(long producerId, IMessagePublisher publisher)
+ {
+ _producers[producerId] = publisher;
+ }
+
+ internal void DeregisterProducer(long producerId)
+ {
+ _producers.Remove(producerId);
+ }
+
+ private long GetNextProducerId()
+ {
+ return ++_nextProducerId;
+ }
+
+ /**
+ * Called to mark the session as being closed. Useful when the session needs to be made invalid, e.g. after
+ * failover when the client has veoted resubscription.
+ *
+ * The caller of this method must already hold the failover mutex.
+ */
+ internal void MarkClosed()
+ {
+ SetClosed();
+ _connection.DeregisterSession(_channelId);
+ MarkClosedProducersAndConsumers();
+ }
+
+ private void MarkClosedProducersAndConsumers()
+ {
+ try
+ {
+ // no need for a markClosed* method in this case since there is no protocol traffic closing a producer
+ CloseProducers();
+ }
+ catch (QpidException e)
+ {
+ _logger.Error("Error closing session: " + e, e);
+ }
+ try
+ {
+ MarkClosedConsumers();
+ }
+ catch (QpidException e)
+ {
+ _logger.Error("Error closing session: " + e, e);
+ }
+ }
+
+ private void MarkClosedConsumers()
+ {
+ if (_dispatcher != null)
+ {
+ _dispatcher.StopDispatcher();
+ }
+ // we need to clone the list of consumers since the close() method updates the _consumers collection
+ // which would result in a concurrent modification exception
+ ArrayList clonedConsumers = new ArrayList(_consumers.Values);
+
+ foreach (BasicMessageConsumer consumer in clonedConsumers)
+ {
+ consumer.MarkClosed();
+ }
+ // at this point the _consumers map will be empty
+ }
+
+ private void DoPurgeQueue(string queueName, bool noWait)
+ {
+ try
+ {
+ _logger.DebugFormat("PurgeQueue {0}", queueName);
+
+ AMQFrame purgeQueue = QueuePurgeBody.CreateAMQFrame(_channelId, 0, queueName, noWait);
+
+ if (noWait)
+ _connection.ProtocolWriter.Write(purgeQueue);
+ else
+ _connection.ConvenientProtocolWriter.SyncWrite(purgeQueue, typeof(QueuePurgeOkBody));
+ }
+ catch (AMQException)
+ {
+ throw;
+ }
+ }
+
+ /**
+ * Replays frame on fail over.
+ *
+ * @throws AMQException
+ */
+ internal void ReplayOnFailOver()
+ {
+ _logger.Debug(string.Format("Replaying frames for channel {0}", _channelId));
+ foreach (AMQFrame frame in _replayFrames)
+ {
+ _logger.Debug(string.Format("Replaying frame=[{0}]", frame));
+ _connection.ProtocolWriter.Write(frame);
+ }
+ }
+
+ /// <summary>
+ /// Callers must hold the failover mutex before calling this method.
+ /// </summary>
+ /// <param name="consumer"></param>
+ private void RegisterConsumer(BasicMessageConsumer consumer)
+ {
+ // Need to generate a consumer tag on the client so we can exploit the nowait flag.
+ String tag = string.Format("{0}-{1}", _sessionNumber, _nextConsumerNumber++);
+ consumer.ConsumerTag = tag;
+ _consumers.Add(tag, consumer);
+
+ String consumerTag = ConsumeFromQueue(consumer.QueueName, consumer.NoLocal,
+ consumer.Exclusive, consumer.AcknowledgeMode, tag, consumer.Browse);
+
+ }
+
+ internal void DoBind(string queueName, string exchangeName, string routingKey, FieldTable args)
+ {
+
+ _logger.Debug(string.Format("QueueBind queueName={0} exchangeName={1} routingKey={2}, arg={3}",
+ queueName, exchangeName, routingKey, args));
+
+ AMQFrame queueBind = QueueBindBody.CreateAMQFrame(_channelId, 0,
+ queueName, exchangeName,
+ routingKey, false, args);
+
+
+ lock (_connection.FailoverMutex)
+ {
+ _connection.ConvenientProtocolWriter.SyncWrite(queueBind, typeof(QueueBindOkBody));
+ }
+ // AS FIXME: wasnae me
+ _replayFrames.Add(QueueBindBody.CreateAMQFrame(_channelId, 0,
+ queueName, exchangeName,
+ routingKey, true, args));
+ }
+
+ private String ConsumeFromQueue(String queueName, bool noLocal, bool exclusive, AcknowledgeMode acknowledgeMode, String tag, bool browse)
+ {
+ FieldTable args = new FieldTable();
+ if(browse)
+ {
+ args["x-filter-no-consume"] = true;
+ }
+ AMQFrame basicConsume = BasicConsumeBody.CreateAMQFrame(_channelId, 0,
+ queueName, tag, noLocal,
+ acknowledgeMode == AcknowledgeMode.NoAcknowledge,
+ exclusive, true, args);
+
+ _replayFrames.Add(basicConsume);
+
+ _connection.ProtocolWriter.Write(basicConsume);
+ return tag;
+ }
+
+ private void DoDeleteQueue(string queueName, bool ifUnused, bool ifEmpty, bool noWait)
+ {
+ try
+ {
+ _logger.Debug(string.Format("DeleteQueue name={0}", queueName));
+
+ AMQFrame queueDelete = QueueDeleteBody.CreateAMQFrame(_channelId, 0, queueName, ifUnused, ifEmpty, noWait);
+
+ if (noWait)
+ {
+ _connection.ProtocolWriter.Write(queueDelete);
+ }
+ else
+ {
+ _connection.ConvenientProtocolWriter.SyncWrite(queueDelete, typeof(QueueDeleteOkBody));
+ }
+ // AS FIXME: wasnae me
+ _replayFrames.Add(QueueDeleteBody.CreateAMQFrame(_channelId, 0, queueName, ifUnused, ifEmpty, true));
+ }
+ catch (AMQException)
+ {
+ throw;
+ }
+ }
+
+ private void DoQueueDeclare(string queueName, bool isDurable, bool isExclusive, bool isAutoDelete, IFieldTable args)
+ {
+ _logger.Debug(string.Format("DeclareQueue name={0} durable={1} exclusive={2}, auto-delete={3}",
+ queueName, isDurable, isExclusive, isAutoDelete));
+
+ AMQFrame queueDeclare = QueueDeclareBody.CreateAMQFrame(_channelId, 0, queueName, false, isDurable, isExclusive,
+ isAutoDelete, false, (FieldTable) args);
+
+
+ lock (_connection.FailoverMutex)
+ {
+ _connection.ConvenientProtocolWriter.SyncWrite(queueDeclare, typeof(QueueDeclareOkBody));
+ }
+ // AS FIXME: wasnae me
+ _replayFrames.Add(QueueDeclareBody.CreateAMQFrame(_channelId, 0, queueName, false, isDurable, isExclusive,
+ isAutoDelete, true, null));
+ }
+
+ // AMQP-level method.
+ private void DeclareExchange(ushort channelId, ushort ticket, string exchangeName,
+ string exchangeClass, bool passive, bool durable,
+ bool autoDelete, bool xinternal, bool noWait, FieldTable args)
+ {
+ _logger.Debug(String.Format("DeclareExchange channelId={0} exchangeName={1} exchangeClass={2}",
+ _channelId, exchangeName, exchangeClass));
+
+ AMQFrame declareExchange = ExchangeDeclareBody.CreateAMQFrame(channelId, ticket, exchangeName, exchangeClass, passive,
+ durable, autoDelete, xinternal, noWait, args);
+
+ if (noWait)
+ {
+ lock (_connection.FailoverMutex)
+ {
+ _connection.ProtocolWriter.Write(declareExchange);
+ }
+ // AS FIXME: wasnae me
+ _replayFrames.Add(declareExchange);
+ }
+ else
+ {
+ throw new NotImplementedException("Don't use nowait=false with DeclareExchange");
+ //_connection.ConvenientProtocolWriter.SyncWrite(declareExchange, typeof (ExchangeDeclareOkBody));
+ }
+ }
+
+ /**
+ * Acknowledge a message or several messages. This method can be called via AbstractJMSMessage or from
+ * a BasicConsumer. The former where the mode is CLIENT_ACK and the latter where the mode is
+ * AUTO_ACK or similar.
+ *
+ * @param deliveryTag the tag of the last message to be acknowledged
+ * @param multiple if true will acknowledge all messages up to and including the one specified by the
+ * delivery tag
+ */
+ internal void AcknowledgeMessage(ulong deliveryTag, bool multiple)
+ {
+ AMQFrame ackFrame = BasicAckBody.CreateAMQFrame(_channelId, deliveryTag, multiple);
+ if (_logger.IsDebugEnabled)
+ {
+ _logger.Debug("Sending ack for delivery tag " + deliveryTag + " on channel " + _channelId);
+ }
+ // FIXME: lock FailoverMutex here?
+ _connection.ProtocolWriter.Write(ackFrame);
+ }
+
+ public void RejectMessage(ulong deliveryTag, bool requeue)
+ {
+ if ((_acknowledgeMode == AcknowledgeMode.ClientAcknowledge) || (_acknowledgeMode == AcknowledgeMode.SessionTransacted))
+ {
+ AMQFrame rejectFrame = BasicRejectBody.CreateAMQFrame(_channelId, deliveryTag, requeue);
+ _connection.ProtocolWriter.Write(rejectFrame);
+ }
+ }
+
+ /// <summary>
+ /// Handle a message that bounced from the server, creating
+ /// the corresponding exception and notifying the connection about it
+ /// </summary>
+ /// <param name="message">Unprocessed message</param>
+ private void ReturnBouncedMessage(UnprocessedMessage message)
+ {
+ try
+ {
+ AbstractQmsMessage bouncedMessage =
+ _messageFactoryRegistry.CreateMessage(0, false, message.ContentHeader, message.Bodies);
+
+ int errorCode = message.BounceBody.ReplyCode;
+ string reason = message.BounceBody.ReplyText;
+ _logger.Debug("Message returned with error code " + errorCode + " (" + reason + ")");
+ AMQException exception;
+
+ if (errorCode == AMQConstant.NO_CONSUMERS.Code)
+ {
+ exception = new AMQNoConsumersException(reason, bouncedMessage);
+ }
+ else if (errorCode == AMQConstant.NO_ROUTE.Code)
+ {
+ exception = new AMQNoRouteException(reason, bouncedMessage);
+ }
+ else
+ {
+ exception = new AMQUndeliveredException(errorCode, reason, bouncedMessage);
+ }
+
+ _connection.ExceptionReceived(exception);
+ }
+ catch (Exception ex)
+ {
+ _logger.Error("Caught exception trying to raise undelivered message exception (dump follows) - ignoring...", ex);
+ }
+ }
+
+ private void OnPrefetchLowMark(int count)
+ {
+ if (_acknowledgeMode == AcknowledgeMode.NoAcknowledge)
+ {
+ _logger.Warn("Below threshold(" + _defaultPrefetchLowMark + ") so unsuspending channel. Current value is " + count);
+ Suspend(false);
+ }
+ }
+
+ private void OnPrefetchHighMark(int count)
+ {
+ if (_acknowledgeMode == AcknowledgeMode.NoAcknowledge)
+ {
+ _logger.Warn("Above threshold(" + _defaultPrefetchHighMark + ") so suspending channel. Current value is " + count);
+ Suspend(true);
+ }
+ }
+
+ private void Suspend(bool suspend)
+ {
+ lock (_suspensionLock)
+ {
+ if (_logger.IsDebugEnabled)
+ {
+ _logger.Debug("Setting channel flow : " + (suspend ? "suspended" : "unsuspended"));
+ }
+
+ _suspended = suspend;
+ AMQFrame frame = ChannelFlowBody.CreateAMQFrame(_channelId, !suspend);
+
+ Connection.ConvenientProtocolWriter.SyncWrite(frame, typeof(ChannelFlowOkBody));
+ }
+ }
+
+ /// <summary>A Dispatcher turns the consumption of incoming messages from an arrival queue, into event notifications on consumers.
+ /// The arrival queue is typically a blocking queue, on which a dispatcher waits for messages to consume. Upon receipt of a message
+ /// the dispatcher finds the consumer that is listening to the queue to which the message has been send and notifies it of the new
+ /// message.
+ ///
+ /// <p/>The Dispatcher also contains logic to recognize bounced messages. Bounced messages returned from the broker can be
+ /// told apart from regular deliveries because they do not have a delivery queue set on them. When the dispatcher receives a
+ /// bounced message it creates an exception and notifies the connection, to which its containing channel belongs, of the condition.
+ ///
+ /// <p/><table id="crc"><caption>CRC Card</caption>
+ /// <tr><th> Responsibilities <th> Collaborations
+ /// <tr><td> Notify consumers of message arrivals on their queues. <td> <see cref="BasicMessageConsumer"/>
+ /// <tr><td> Notify the containing connection of bounced message arrivals. <td> <see cref="AMQConnection"/>
+ /// </table>
+ /// </summary>
+ ///
+ /// <remarks>Stop mechanism seems wrong, as queue consume is evaluated after stop flag, so could consume and notify one more message.
+ /// Placing stop check after consume may also be wrong as it may cause a message to be thrown away. Seems more correct to use interupt on
+ /// the block thread to cause it to prematurely return from its wait, whereupon it can be made to re-check the stop flag.</remarks>
+ ///
+ /// <remarks>Exception swallowed, if there is an exception whilst notifying the connection on bounced messages. Unhandled excetpion should
+ /// fall through and terminate the loop, as it is a bug if it occurrs.</remarks>
+ private class Dispatcher
+ {
+ /// <summary> Flag used to indicate when this dispatcher is to be stopped (0=go, 1=stop). </summary>
+ private int _stopped = 0;
+
+ /// <summary> The channel for which this is a dispatcher. </summary>
+ private AmqChannel _containingChannel;
+
+ /// <summary> Creates a dispatcher on the specified channel. </summary>
+ ///
+ /// <param name="containingChannel"> The channel on which this is a dispatcher. </param>
+ public Dispatcher(AmqChannel containingChannel)
+ {
+ _containingChannel = containingChannel;
+ }
+
+ /// <summary>The message dispatch loop. Consumes messages from the channels queue, notifying consumers of regular deliveries, and
+ /// the connection of bounced messages.</summary>
+ public void RunDispatcher()
+ {
+ UnprocessedMessage message;
+
+ while (_stopped == 0 && (message = (UnprocessedMessage)_containingChannel._queue.Dequeue()) != null)
+ {
+ if (message.DeliverBody != null)
+ {
+ BasicMessageConsumer consumer = (BasicMessageConsumer) _containingChannel._consumers[message.DeliverBody.ConsumerTag];
+
+ if (consumer == null)
+ {
+ _logger.Warn("Received a message from queue " + message.DeliverBody.ConsumerTag + " without a f - ignoring...");
+ }
+ else
+ {
+ consumer.NotifyMessage(message, _containingChannel.ChannelId);
+ }
+ }
+ else
+ {
+ try
+ {
+ // Bounced message is processed here, away from the transport thread
+ AbstractQmsMessage bouncedMessage = _containingChannel._messageFactoryRegistry.
+ CreateMessage(0, false, message.ContentHeader, message.Bodies);
+
+ int errorCode = message.BounceBody.ReplyCode;
+ string reason = message.BounceBody.ReplyText;
+
+ _logger.Debug("Message returned with error code " + errorCode + " (" + reason + ")");
+
+ _containingChannel._connection.ExceptionReceived(new AMQUndeliveredException(errorCode, "Error: " + reason, bouncedMessage));
+ }
+ catch (Exception e)
+ {
+ _logger.Error("Caught exception trying to raise undelivered message exception (dump follows) - ignoring...", e);
+ }
+ }
+ }
+
+ _logger.Debug("Dispatcher thread terminating for channel: " + _containingChannel._channelId + ".");
+ }
+
+ /// <summary> Sets a stop flag on this dispatcher, which causes its dispatch loop to exit at the next available opportunity. </summary>
+ public void StopDispatcher()
+ {
+ Interlocked.Exchange(ref _stopped, 1);
+ }
+ }
+ }
+}
diff --git a/qpid/dotnet/Qpid.Client/Client/BasicMessageConsumer.cs b/qpid/dotnet/Qpid.Client/Client/BasicMessageConsumer.cs
new file mode 100644
index 0000000000..fdac5e75f2
--- /dev/null
+++ b/qpid/dotnet/Qpid.Client/Client/BasicMessageConsumer.cs
@@ -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.
+ *
+ */
+using System;
+using System.Threading;
+using System.Collections;
+using System.Collections.Generic;
+using log4net;
+using Apache.Qpid.Client.Message;
+using Apache.Qpid.Collections;
+using Apache.Qpid.Framing;
+using Apache.Qpid.Messaging;
+
+namespace Apache.Qpid.Client
+{
+ public class BasicMessageConsumer : Closeable, IMessageConsumer
+ {
+ private static readonly ILog _logger = LogManager.GetLogger(typeof(BasicMessageConsumer));
+
+ private bool _noLocal;
+
+ /** Holds the exclusive status flag for the consumers access to its queue. */
+ private bool _exclusive;
+
+ public bool Exclusive
+ {
+ get { return _exclusive; }
+ }
+
+ private bool _browse;
+
+ public bool Browse
+ {
+ get { return _browse; }
+ }
+
+ public bool NoLocal
+ {
+ get { return _noLocal; }
+ set { _noLocal = value; }
+ }
+
+ private AcknowledgeMode _acknowledgeMode;
+
+ public AcknowledgeMode AcknowledgeMode
+ {
+ get { return _acknowledgeMode; }
+ }
+
+ private MessageReceivedDelegate _messageListener;
+
+ private bool IsMessageListenerSet
+ {
+ get { return _messageListener != null; }
+ }
+
+ /// <summary>
+ /// The consumer tag allows us to close the consumer by sending a jmsCancel method to the
+ /// broker
+ /// </summary>
+ private string _consumerTag;
+
+ /// <summary>
+ /// We need to know the channel id when constructing frames
+ /// </summary>
+ private ushort _channelId;
+
+ private readonly string _queueName;
+
+ /// <summary>
+ /// Protects the setting of a messageListener
+ /// </summary>
+ private readonly object _syncLock = new object();
+
+ /// <summary>
+ /// We store the high water prefetch field in order to be able to reuse it when resubscribing in the event of failover
+ /// </summary>
+ private int _prefetchHigh;
+
+ /// <summary>
+ /// We store the low water prefetch field in order to be able to reuse it when resubscribing in the event of failover
+ /// </summary>
+ private int _prefetchLow;
+
+ /// <summary>
+ /// When true indicates that either a message listener is set or that
+ /// a blocking receive call is in progress
+ /// </summary>
+ private bool _receiving;
+
+ /// <summary>
+ /// Used in the blocking receive methods to receive a message from
+ /// the Channel thread.
+ /// </summary>
+ private readonly ConsumerProducerQueue _messageQueue = new ConsumerProducerQueue();
+
+ private MessageFactoryRegistry _messageFactory;
+
+ private AmqChannel _channel;
+
+ // <summary>
+ // Tag of last message delievered, whoch should be acknowledged on commit in transaction mode.
+ // </summary>
+ //private long _lastDeliveryTag;
+
+ /// <summary>
+ /// Explicit list of all received but un-acked messages in a transaction. Used to ensure acking is completed when transaction is committed.
+ /// </summary>
+ private LinkedList<long> _receivedDeliveryTags;
+
+ /// <summary>
+ /// Number of messages unacknowledged in DUPS_OK_ACKNOWLEDGE mode
+ /// </summary>
+ private int _outstanding;
+
+ /// <summary>
+ /// Switch to enable sending of acknowledgements when using DUPS_OK_ACKNOWLEDGE mode.
+ /// Enabled when _outstannding number of msgs >= _prefetchHigh and disabled at < _prefetchLow
+ /// </summary>
+ private bool _dups_ok_acknowledge_send;
+
+ internal BasicMessageConsumer(ushort channelId, string queueName, bool noLocal,
+ MessageFactoryRegistry messageFactory, AmqChannel channel,
+ int prefetchHigh, int prefetchLow, bool exclusive, bool browse)
+ {
+ _channelId = channelId;
+ _queueName = queueName;
+ _noLocal = noLocal;
+ _messageFactory = messageFactory;
+ _channel = channel;
+ _acknowledgeMode = _channel.AcknowledgeMode;
+ _prefetchHigh = prefetchHigh;
+ _prefetchLow = prefetchLow;
+ _exclusive = exclusive;
+ _browse = browse;
+
+ if (_acknowledgeMode == AcknowledgeMode.SessionTransacted)
+ {
+ _receivedDeliveryTags = new LinkedList<long>();
+ }
+ }
+
+ #region IMessageConsumer Members
+
+ public MessageReceivedDelegate OnMessage
+ {
+ get
+ {
+ return _messageListener;
+ }
+ set
+ {
+ CheckNotClosed();
+
+ lock (_syncLock)
+ {
+ // If someone is already receiving
+ if (_messageListener != null && _receiving)
+ {
+ throw new InvalidOperationException("Another thread is already receiving...");
+ }
+
+ _messageListener = value;
+
+ _receiving = (_messageListener != null);
+
+ if (_receiving)
+ {
+ _logger.Debug("Message listener set for queue with name " + _queueName);
+ }
+ }
+ }
+ }
+
+ public IMessage Receive(long delay)
+ {
+ CheckNotClosed();
+
+ lock (_syncLock)
+ {
+ // If someone is already receiving
+ if (_receiving)
+ {
+ throw new InvalidOperationException("Another thread is already receiving (possibly asynchronously)...");
+ }
+
+ _receiving = true;
+ }
+
+ try
+ {
+ object o = _messageQueue.Dequeue(delay);
+
+ return ReturnMessageOrThrowAndPostDeliver(o);
+ }
+ finally
+ {
+ lock (_syncLock)
+ {
+ _receiving = false;
+ }
+ }
+ }
+
+ private IMessage ReturnMessageOrThrowAndPostDeliver(object o)
+ {
+ IMessage m = ReturnMessageOrThrow(o);
+ if (m != null)
+ {
+ PostDeliver(m);
+ }
+ return m;
+ }
+
+ public IMessage Receive()
+ {
+ return Receive(Timeout.Infinite);
+ }
+
+ public IMessage ReceiveNoWait()
+ {
+ return Receive(0);
+ }
+
+ #endregion
+
+ /// <summary>
+ /// We can get back either a Message or an exception from the queue. This method examines the argument and deals
+ /// with it by throwing it (if an exception) or returning it (in any other case).
+ /// </summary>
+ /// <param name="o">the object off the queue</param>
+ /// <returns> a message only if o is a Message</returns>
+ /// <exception>JMSException if the argument is a throwable. If it is a QpidMessagingException it is rethrown as is, but if not
+ /// a QpidMessagingException is created with the linked exception set appropriately</exception>
+ private IMessage ReturnMessageOrThrow(object o)
+ {
+ // errors are passed via the queue too since there is no way of interrupting the poll() via the API.
+ if (o is Exception)
+ {
+ Exception e = (Exception) o;
+ throw new QpidException("Message consumer forcibly closed due to error: " + e, e);
+ }
+ else
+ {
+ return (IMessage) o;
+ }
+ }
+
+ #region IDisposable Members
+
+ public void Dispose()
+ {
+ Close();
+ }
+
+ #endregion
+
+ public override void Close()
+ {
+ if (_closed == CLOSED)
+ {
+ return;
+ }
+ // FIXME: Don't we need FailoverSupport here (as we have SyncWrite). i.e. rather than just locking FailOverMutex
+ lock (_channel.Connection.FailoverMutex)
+ {
+ lock (_closingLock)
+ {
+ Interlocked.Exchange(ref _closed, CLOSED);
+
+ AMQFrame cancelFrame = BasicCancelBody.CreateAMQFrame(_channelId, _consumerTag, false);
+
+ try
+ {
+ _channel.Connection.ConvenientProtocolWriter.SyncWrite(
+ cancelFrame, typeof(BasicCancelOkBody));
+ }
+ catch (AMQException e)
+ {
+ _logger.Error("Error closing consumer: " + e, e);
+ throw new QpidException("Error closing consumer: " + e);
+ }
+ finally
+ {
+ DeregisterConsumer();
+ }
+ }
+ }
+ }
+
+ /**
+ * Called from the AMQSession when a message has arrived for this consumer. This methods handles both the case
+ * of a message listener or a synchronous receive() caller.
+ *
+ * @param messageFrame the raw unprocessed mesage
+ * @param channelId channel on which this message was sent
+ */
+ internal void NotifyMessage(UnprocessedMessage messageFrame, int channelId)
+ {
+ if (_logger.IsDebugEnabled)
+ {
+ _logger.Debug("notifyMessage called with message number " + messageFrame.DeliverBody.DeliveryTag);
+ }
+ try
+ {
+ AbstractQmsMessage jmsMessage = _messageFactory.CreateMessage((long)messageFrame.DeliverBody.DeliveryTag,
+ messageFrame.DeliverBody.Redelivered,
+ messageFrame.ContentHeader,
+ messageFrame.Bodies);
+
+ _logger.Debug("Message is of type: " + jmsMessage.GetType().Name);
+
+ PreDeliver(jmsMessage);
+
+ if (IsMessageListenerSet)
+ {
+ // We do not need a lock around the test above, and the dispatch below as it is invalid
+ // for an application to alter an installed listener while the session is started.
+#if __MonoCS__
+ _messageListener(jmsMessage);
+#else
+ _messageListener.Invoke(jmsMessage);
+#endif
+ PostDeliver(jmsMessage);
+ }
+ else
+ {
+ _messageQueue.Enqueue(jmsMessage);
+ }
+ }
+ catch (Exception e)
+ {
+ _logger.Error("Caught exception (dump follows) - ignoring...", e); // FIXME
+ }
+ }
+
+
+ internal void NotifyError(Exception cause)
+ {
+ lock (_syncLock)
+ {
+ SetClosed();
+
+ // we have no way of propagating the exception to a message listener - a JMS limitation - so we
+ // deal with the case where we have a synchronous receive() waiting for a message to arrive
+ if (_messageListener == null)
+ {
+ // offer only succeeds if there is a thread waiting for an item from the queue
+ _messageQueue.Enqueue(cause);
+ _logger.Debug("Passed exception to synchronous queue for propagation to receive()");
+ }
+ DeregisterConsumer();
+ }
+ }
+
+ private void SetClosed()
+ {
+ Interlocked.Exchange(ref _closed, CLOSED);
+ }
+
+ /// <summary>
+ /// Perform cleanup to deregister this consumer. This occurs when closing the consumer in both the clean
+ /// case and in the case of an error occurring.
+ /// </summary>
+ internal void DeregisterConsumer()
+ {
+ _channel.DeregisterConsumer(_consumerTag);
+ }
+
+ public string ConsumerTag
+ {
+ get
+ {
+ return _consumerTag;
+ }
+ set
+ {
+ _consumerTag = value;
+ }
+ }
+
+ /**
+ * Called when you need to invalidate a consumer. Used for example when failover has occurred and the
+ * client has vetoed automatic resubscription.
+ * The caller must hold the failover mutex.
+ */
+ internal void MarkClosed()
+ {
+ SetClosed();
+ DeregisterConsumer();
+ }
+
+ public string QueueName
+ {
+ get { return _queueName; }
+ }
+
+ /// <summary>
+ /// Acknowledge up to last message delivered (if any). Used when commiting.
+ /// </summary>
+ internal void AcknowledgeDelivered()
+ {
+ foreach (long tag in _receivedDeliveryTags)
+ {
+ _channel.AcknowledgeMessage((ulong)tag, false);
+ }
+
+ _receivedDeliveryTags.Clear();
+ }
+
+ internal void RejectUnacked()
+ {
+ foreach (long tag in _receivedDeliveryTags)
+ {
+ _channel.RejectMessage((ulong)tag, true);
+ }
+
+ _receivedDeliveryTags.Clear();
+ }
+
+ private void PreDeliver(AbstractQmsMessage msg)
+ {
+ switch (AcknowledgeMode)
+ {
+ case AcknowledgeMode.PreAcknowledge:
+ _channel.AcknowledgeMessage((ulong)msg.DeliveryTag, false);
+ break;
+
+ case AcknowledgeMode.ClientAcknowledge:
+ // We set the session so that when the user calls acknowledge() it can call the method on session
+ // to send out the appropriate frame.
+ //msg.setAMQSession(_session);
+ msg.Channel = _channel;
+ break;
+ }
+ }
+
+ private void PostDeliver(IMessage m)
+ {
+ AbstractQmsMessage msg = (AbstractQmsMessage) m;
+ switch (AcknowledgeMode)
+ {
+ case AcknowledgeMode.DupsOkAcknowledge:
+ if (++_outstanding >= _prefetchHigh)
+ {
+ _dups_ok_acknowledge_send = true;
+ }
+ if (_outstanding <= _prefetchLow)
+ {
+ _dups_ok_acknowledge_send = false;
+ }
+ if (_dups_ok_acknowledge_send)
+ {
+ _channel.AcknowledgeMessage((ulong)msg.DeliveryTag, true);
+ }
+ break;
+
+ case AcknowledgeMode.AutoAcknowledge:
+ _channel.AcknowledgeMessage((ulong)msg.DeliveryTag, true);
+ break;
+
+ case AcknowledgeMode.SessionTransacted:
+ _receivedDeliveryTags.AddLast(msg.DeliveryTag);
+ break;
+ }
+ }
+ }
+}
diff --git a/qpid/dotnet/Qpid.Client/Client/BasicMessageProducer.cs b/qpid/dotnet/Qpid.Client/Client/BasicMessageProducer.cs
new file mode 100644
index 0000000000..f33afc452e
--- /dev/null
+++ b/qpid/dotnet/Qpid.Client/Client/BasicMessageProducer.cs
@@ -0,0 +1,405 @@
+/*
+ *
+ * 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.
+ *
+ */
+using System;
+using System.Threading;
+using log4net;
+using Apache.Qpid.Buffer;
+using Apache.Qpid.Client.Message;
+using Apache.Qpid.Messaging;
+using Apache.Qpid.Framing;
+
+namespace Apache.Qpid.Client
+{
+ public class BasicMessageProducer : Closeable, IMessagePublisher
+ {
+ protected readonly ILog _logger = LogManager.GetLogger(typeof(BasicMessageProducer));
+
+ /// <summary>
+ /// If true, messages will not get a timestamp.
+ /// </summary>
+ private bool _disableTimestamps;
+
+ /// <summary>
+ /// Priority of messages created by this producer.
+ /// </summary>
+ private int _messagePriority;
+
+ /// <summary>
+ /// Time to live of messages. Specified in milliseconds but AMQ has 1 second resolution.
+ /// </summary>
+ private long _timeToLive;
+
+ /// <summary>
+ /// Delivery mode used for this producer.
+ /// </summary>
+ private DeliveryMode _deliveryMode;
+
+ private bool _immediate;
+ private bool _mandatory;
+
+ string _exchangeName;
+ string _routingKey;
+
+ /// <summary>
+ /// Default encoding used for messages produced by this producer.
+ /// </summary>
+ private string _encoding;
+
+ /// <summary>
+ /// Default encoding used for message produced by this producer.
+ /// </summary>
+ private string _mimeType;
+
+ /// <summary>
+ /// True if this producer was created from a transacted session
+ /// </summary>
+ private bool _transacted;
+
+ private ushort _channelId;
+
+ /// <summary>
+ /// This is an id generated by the session and is used to tie individual producers to the session. This means we
+ /// can deregister a producer with the session when the producer is closed. We need to be able to tie producers
+ /// to the session so that when an error is propagated to the session it can close the producer (meaning that
+ /// a client that happens to hold onto a producer reference will get an error if he tries to use it subsequently).
+ /// </summary>
+ private long _producerId;
+
+ /// <summary>
+ /// The session used to create this producer
+ /// </summary>
+ private AmqChannel _channel;
+
+ public BasicMessageProducer(string exchangeName, string routingKey,
+ bool transacted,
+ ushort channelId,
+ AmqChannel channel,
+ long producerId,
+ DeliveryMode deliveryMode,
+ long timeToLive,
+ bool immediate,
+ bool mandatory,
+ int priority)
+ {
+ _exchangeName = exchangeName;
+ _routingKey = routingKey;
+ _transacted = transacted;
+ _channelId = channelId;
+ _channel = channel;
+ _producerId = producerId;
+ _deliveryMode = deliveryMode;
+ _timeToLive = timeToLive;
+ _immediate = immediate;
+ _mandatory = mandatory;
+ _messagePriority = priority;
+
+ _channel.RegisterProducer(producerId, this);
+ }
+
+
+ #region IMessagePublisher Members
+
+ public DeliveryMode DeliveryMode
+ {
+ get
+ {
+ CheckNotClosed();
+ return _deliveryMode;
+ }
+ set
+ {
+ CheckNotClosed();
+ _deliveryMode = value;
+ }
+ }
+
+ public string ExchangeName
+ {
+ get { return _exchangeName; }
+ }
+
+ public string RoutingKey
+ {
+ get { return _routingKey; }
+ }
+
+ public bool DisableMessageID
+ {
+ get
+ {
+ throw new Exception("The method or operation is not implemented.");
+ }
+ set
+ {
+ throw new Exception("The method or operation is not implemented.");
+ }
+ }
+
+ public bool DisableMessageTimestamp
+ {
+ get
+ {
+ CheckNotClosed();
+ return _disableTimestamps;
+ }
+ set
+ {
+ CheckNotClosed();
+ _disableTimestamps = value;
+ }
+ }
+
+ public int Priority
+ {
+ get
+ {
+ CheckNotClosed();
+ return _messagePriority;
+ }
+ set
+ {
+ CheckNotClosed();
+ if ( value < 0 || value > 9 )
+ {
+ throw new ArgumentOutOfRangeException("Priority of " + value + " is illegal. Value must be in range 0 to 9");
+ }
+ _messagePriority = value;
+ }
+ }
+
+ public override void Close()
+ {
+ _logger.Debug("Closing producer " + this);
+ Interlocked.Exchange(ref _closed, CLOSED);
+ _channel.DeregisterProducer(_producerId);
+ }
+
+ public void Send(IMessage msg, DeliveryMode deliveryMode, int priority, long timeToLive)
+ {
+ CheckNotClosed();
+ SendImpl(
+ _exchangeName,
+ _routingKey,
+ (AbstractQmsMessage)msg,
+ deliveryMode,
+ priority,
+ (uint)timeToLive,
+ _mandatory,
+ _immediate
+ );
+ }
+
+ public void Send(IMessage msg)
+ {
+ CheckNotClosed();
+ SendImpl(
+ _exchangeName,
+ _routingKey,
+ (AbstractQmsMessage)msg,
+ _deliveryMode,
+ _messagePriority,
+ (uint)_timeToLive,
+ _mandatory,
+ _immediate
+ );
+ }
+
+ // This is a short-term hack (knowing that this code will be re-vamped sometime soon)
+ // to facilitate publishing messages to potentially non-existent recipients.
+ public void Send(IMessage msg, bool mandatory)
+ {
+ CheckNotClosed();
+ SendImpl(
+ _exchangeName,
+ _routingKey,
+ (AbstractQmsMessage)msg,
+ _deliveryMode,
+ _messagePriority,
+ (uint)_timeToLive,
+ mandatory,
+ _immediate
+ );
+ }
+
+ public long TimeToLive
+ {
+ get
+ {
+ CheckNotClosed();
+ return _timeToLive;
+ }
+ set
+ {
+ CheckNotClosed();
+ if ( value < 0 )
+ {
+ throw new ArgumentOutOfRangeException("Time to live must be non-negative - supplied value was " + value);
+ }
+ _timeToLive = value;
+ }
+ }
+
+ #endregion
+
+ public string MimeType
+ {
+ get
+ {
+ CheckNotClosed();
+ return _mimeType;
+ }
+ set
+ {
+ CheckNotClosed();
+ _mimeType = value;
+ }
+ }
+
+ public string Encoding
+ {
+ get
+ {
+ CheckNotClosed();
+ return _encoding;
+ }
+ set
+ {
+ CheckNotClosed();
+ _encoding = value;
+ }
+ }
+
+ public void Dispose()
+ {
+ Close();
+ }
+
+ #region Message Publishing
+
+ private void SendImpl(string exchangeName, string routingKey, AbstractQmsMessage message, DeliveryMode deliveryMode, int priority, uint timeToLive, bool mandatory, bool immediate)
+ {
+ // todo: handle session access ticket
+ AMQFrame publishFrame = BasicPublishBody.CreateAMQFrame(
+ _channel.ChannelId, 0, exchangeName,
+ routingKey, mandatory, immediate
+ );
+
+ // fix message properties
+ if ( !_disableTimestamps )
+ {
+ message.Timestamp = DateTime.UtcNow.Ticks;
+ if (timeToLive != 0)
+ {
+ message.Expiration = message.Timestamp + timeToLive;
+ }
+ } else
+ {
+ message.Expiration = 0;
+ }
+ message.DeliveryMode = deliveryMode;
+ message.Priority = (byte)priority;
+
+ ByteBuffer payload = message.Data;
+ int payloadLength = payload.Limit;
+
+ ContentBody[] contentBodies = CreateContentBodies(payload);
+ AMQFrame[] frames = new AMQFrame[2 + contentBodies.Length];
+ for ( int i = 0; i < contentBodies.Length; i++ )
+ {
+ frames[2 + i] = ContentBody.CreateAMQFrame(_channelId, contentBodies[i]);
+ }
+ if ( contentBodies.Length > 0 && _logger.IsDebugEnabled )
+ {
+ _logger.Debug(string.Format("Sending content body frames to {{exchangeName={0} routingKey={1}}}", exchangeName, routingKey));
+ }
+
+ // weight argument of zero indicates no child content headers, just bodies
+ AMQFrame contentHeaderFrame = ContentHeaderBody.CreateAMQFrame(
+ _channelId, AmqChannel.BASIC_CONTENT_TYPE, 0,
+ message.ContentHeaderProperties, (uint)payloadLength
+ );
+ if ( _logger.IsDebugEnabled )
+ {
+ _logger.Debug(string.Format("Sending content header frame to {{exchangeName={0} routingKey={1}}}", exchangeName, routingKey));
+ }
+
+ frames[0] = publishFrame;
+ frames[1] = contentHeaderFrame;
+ CompositeAMQDataBlock compositeFrame = new CompositeAMQDataBlock(frames);
+
+ lock ( _channel.Connection.FailoverMutex )
+ {
+ _channel.Connection.ProtocolWriter.Write(compositeFrame);
+ }
+ }
+
+
+ /// <summary>
+ /// Create content bodies. This will split a large message into numerous bodies depending on the negotiated
+ /// maximum frame size.
+ /// </summary>
+ /// <param name="payload"></param>
+ /// <returns>return the array of content bodies</returns>
+ private ContentBody[] CreateContentBodies(ByteBuffer payload)
+ {
+ if ( payload == null )
+ {
+ return null;
+ } else if ( payload.Remaining == 0 )
+ {
+ return new ContentBody[0];
+ }
+ // we substract one from the total frame maximum size to account for the end of frame marker in a body frame
+ // (0xCE byte).
+ int framePayloadMax = (int)(_channel.Connection.MaximumFrameSize - 1);
+ int frameCount = CalculateContentBodyFrames(payload);
+ ContentBody[] bodies = new ContentBody[frameCount];
+ for ( int i = 0; i < frameCount; i++ )
+ {
+ int length = (payload.Remaining >= framePayloadMax)
+ ? framePayloadMax : payload.Remaining;
+ bodies[i] = new ContentBody(payload, (uint)length);
+ }
+ return bodies;
+ }
+
+ private int CalculateContentBodyFrames(ByteBuffer payload)
+ {
+ // we substract one from the total frame maximum size to account
+ // for the end of frame marker in a body frame
+ // (0xCE byte).
+ int frameCount;
+ if ( (payload == null) || (payload.Remaining == 0) )
+ {
+ frameCount = 0;
+ } else
+ {
+ int dataLength = payload.Remaining;
+ int framePayloadMax = (int)_channel.Connection.MaximumFrameSize - 1;
+ int lastFrame = ((dataLength % framePayloadMax) > 0) ? 1 : 0;
+ frameCount = (int)(dataLength / framePayloadMax) + lastFrame;
+ }
+
+ return frameCount;
+ }
+ #endregion // Message Publishing
+ }
+}
diff --git a/qpid/dotnet/Qpid.Client/Client/Closeable.cs b/qpid/dotnet/Qpid.Client/Client/Closeable.cs
new file mode 100644
index 0000000000..b9664ccea3
--- /dev/null
+++ b/qpid/dotnet/Qpid.Client/Client/Closeable.cs
@@ -0,0 +1,83 @@
+/*
+ *
+ * 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.
+ *
+ */
+using System;
+using Apache.Qpid.Messaging;
+
+namespace Apache.Qpid.Client
+{
+ /// <summary>Closeable provides monitoring of the state of a closeable resource; whether it is open or closed. It also provides a lock on which
+ /// attempts to close the resource from multiple threads can be coordinated.
+ ///
+ /// <p/><table id="crc"><caption>CRC Card</caption>
+ /// <tr><th> Responsibilities <th> Collaborations
+ /// <tr><td> Close (and clean-up) a resource.
+ /// <tr><td> Monitor the state of a closeable resource.
+ /// <tr><td> Synchronous attempts to close resource from concurrent threads.
+ /// </table>
+ /// </summary>
+ ///
+ /// <remarks>Poor encapsulation of the close lock. Better to completely hide the implementation, such that there is a method, e.g., DoSingleClose,
+ /// that sub-classes implement. Guaranteed to only be called by one thread at once, and iff the object is not already closed. That is, multiple
+ /// simultaneous closes will result in a single call to the real close method. Put the wait and condition checking loop in this base class.
+ /// </remarks>
+ public abstract class Closeable : ICloseable
+ {
+ /// <summary> Constant representing the closed state. </summary>
+ protected const int CLOSED = 1;
+
+ /// <summary> Constant representing the open state. </summary>
+ protected const int NOT_CLOSED = 2;
+
+ /// <summary> Used to ensure orderly closing of the object. </summary>
+ protected readonly object _closingLock = new object();
+
+ /// <summary> Indicates the state of this resource; open or closed. </summary>
+ protected int _closed = NOT_CLOSED;
+
+ /// <summary>
+ /// Checks the not closed.
+ /// </summary>
+ ///
+ /// <remarks>Don't like check methods that throw exceptions. a) it can come as a surprise without checked exceptions, b) it limits the
+ /// callers choice, if the caller would prefer a boolean, c) it is not side-effect free programming, where such could be used. Get rid
+ /// of this and replace with boolean.</remarks>
+ protected void CheckNotClosed()
+ {
+ if (_closed == CLOSED)
+ {
+ throw new InvalidOperationException("Object " + ToString() + " has been closed");
+ }
+ }
+
+ /// <summary>Indicates whether this resource is closed.</summary>
+ /// <value><c>true</c> if closed; otherwise, <c>false</c>.</value>
+ public bool Closed
+ {
+ get
+ {
+ return _closed == CLOSED;
+ }
+ }
+
+ /// <summary> Close this resource. </summary>
+ public abstract void Close();
+ }
+}
diff --git a/qpid/dotnet/Qpid.Client/Client/Configuration/AuthenticationConfigurationSectionHandler.cs b/qpid/dotnet/Qpid.Client/Client/Configuration/AuthenticationConfigurationSectionHandler.cs
new file mode 100644
index 0000000000..8d289fa956
--- /dev/null
+++ b/qpid/dotnet/Qpid.Client/Client/Configuration/AuthenticationConfigurationSectionHandler.cs
@@ -0,0 +1,84 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+using System;
+using System.Collections;
+using System.Collections.Specialized;
+using System.Configuration;
+using System.Text;
+
+using Apache.Qpid.Client.Security;
+using Apache.Qpid.Sasl.Mechanisms;
+
+namespace Apache.Qpid.Client.Configuration
+{
+ public class AuthenticationConfigurationSectionHandler
+ : IConfigurationSectionHandler
+ {
+
+ public object Create(object parent, object configContext, System.Xml.XmlNode section)
+ {
+ NameValueSectionHandler handler = new NameValueSectionHandler();
+ OrderedHashTable schemes = new OrderedHashTable();
+
+ NameValueCollection options = (NameValueCollection)
+ handler.Create(parent, configContext, section);
+
+ if ( options != null )
+ {
+ foreach ( string key in options.Keys )
+ {
+ Type type = Type.GetType(options[key]);
+ if ( type == null )
+ throw new ConfigurationException(string.Format("Type '{0}' not found", key));
+ if ( !typeof(IAMQCallbackHandler).IsAssignableFrom(type) )
+ throw new ConfigurationException(string.Format("Type '{0}' does not implement IAMQCallbackHandler", key));
+
+ schemes.Add(key, type);
+ }
+ }
+
+ return schemes;
+ }
+
+ } // class AuthenticationConfigurationSectionHandler
+
+ public class OrderedHashTable : Hashtable
+ {
+ private ArrayList _keys = new ArrayList();
+
+ public IList OrderedKeys
+ {
+ get { return _keys; }
+ }
+
+ public override void Add(object key, object value)
+ {
+ base.Add(key, value);
+ _keys.Add(key);
+ }
+ public override void Remove(object key)
+ {
+ base.Remove(key);
+ _keys.Remove(key);
+ }
+ }
+} // namespace Apache.Qpid.Client.Configuration
diff --git a/qpid/dotnet/Qpid.Client/Client/ConnectionTuneParameters.cs b/qpid/dotnet/Qpid.Client/Client/ConnectionTuneParameters.cs
new file mode 100644
index 0000000000..b21486bfa8
--- /dev/null
+++ b/qpid/dotnet/Qpid.Client/Client/ConnectionTuneParameters.cs
@@ -0,0 +1,83 @@
+/*
+ *
+ * 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.
+ *
+ */
+namespace Apache.Qpid.Client
+{
+ public class ConnectionTuneParameters
+ {
+ private uint _frameMax;
+
+ private ushort _channelMax;
+
+ private uint _hearbeat;
+
+ private uint _txnLimit;
+
+ public uint FrameMax
+ {
+ get
+ {
+ return _frameMax;
+ }
+ set
+ {
+ _frameMax = value;
+ }
+ }
+
+ public ushort ChannelMax
+ {
+ get
+ {
+ return _channelMax;
+ }
+ set
+ {
+ _channelMax = value;
+ }
+ }
+
+ public uint Heartbeat
+ {
+ get
+ {
+ return _hearbeat;
+ }
+ set
+ {
+ _hearbeat = value;
+ }
+ }
+
+ public uint TxnLimit
+ {
+ get
+ {
+ return _txnLimit;
+ }
+ set
+ {
+ _txnLimit = value;
+ }
+ }
+ }
+}
+
+
diff --git a/qpid/dotnet/Qpid.Client/Client/Failover/FailoverException.cs b/qpid/dotnet/Qpid.Client/Client/Failover/FailoverException.cs
new file mode 100644
index 0000000000..7013746414
--- /dev/null
+++ b/qpid/dotnet/Qpid.Client/Client/Failover/FailoverException.cs
@@ -0,0 +1,42 @@
+/*
+ *
+ * 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.
+ *
+ */
+using System;
+using System.Runtime.Serialization;
+
+namespace Apache.Qpid.Client.Failover
+{
+ /// <summary>
+ /// This exception is thrown when failover is taking place and we need to let other
+ /// parts of the client know about this.
+ /// </summary>
+ [Serializable]
+ class FailoverException : Exception
+ {
+ public FailoverException(String message) : base(message)
+ {
+ }
+
+ protected FailoverException(SerializationInfo info, StreamingContext ctxt)
+ : base(info, ctxt)
+ {
+ }
+ }
+}
diff --git a/qpid/dotnet/Qpid.Client/Client/Failover/FailoverHandler.cs b/qpid/dotnet/Qpid.Client/Client/Failover/FailoverHandler.cs
new file mode 100644
index 0000000000..83c69b7d25
--- /dev/null
+++ b/qpid/dotnet/Qpid.Client/Client/Failover/FailoverHandler.cs
@@ -0,0 +1,175 @@
+/*
+ *
+ * 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.
+ *
+ */
+using System;
+using System.Threading;
+using log4net;
+using Apache.Qpid.Client.Protocol;
+using Apache.Qpid.Client.State;
+
+namespace Apache.Qpid.Client.Failover
+{
+ public class FailoverHandler
+ {
+ private static readonly ILog _log = LogManager.GetLogger(typeof(FailoverHandler));
+
+ private AMQConnection _connection;
+
+ /**
+ * Used where forcing the failover host
+ */
+ private String _host;
+
+ /**
+ * Used where forcing the failover port
+ */
+ private int _port;
+
+ public FailoverHandler(AMQConnection connection)
+ {
+ _connection = connection;
+ }
+
+ public void Run()
+ {
+ if (Thread.CurrentThread.IsBackground)
+ {
+ throw new InvalidOperationException("FailoverHandler must Run on a non-background thread.");
+ }
+
+ AMQProtocolListener pl = _connection.ProtocolListener;
+ pl.FailoverLatch = new ManualResetEvent(false);
+
+ // We wake up listeners. If they can handle failover, they will extend the
+ // FailoverSupport class and will in turn block on the latch until failover
+ // has completed before retrying the operation
+ _connection.ProtocolListener.PropagateExceptionToWaiters(new FailoverException("Failing over about to start"));
+
+ // Since failover impacts several structures we protect them all with a single mutex. These structures
+ // are also in child objects of the connection. This allows us to manipulate them without affecting
+ // client code which runs in a separate thread.
+ lock (_connection.FailoverMutex)
+ {
+ _log.Info("Starting failover process");
+
+ // We switch in a new state manager temporarily so that the interaction to get to the "connection open"
+ // state works, without us having to terminate any existing "state waiters". We could theoretically
+ // have a state waiter waiting until the connection is closed for some reason. Or in future we may have
+ // a slightly more complex state model therefore I felt it was worthwhile doing this.
+ AMQStateManager existingStateManager = _connection.ProtocolListener.StateManager;
+ _connection.ProtocolListener.StateManager = new AMQStateManager();
+ if (!_connection.FirePreFailover(_host != null))
+ {
+ _connection.ProtocolListener.StateManager = existingStateManager;
+ if (_host != null)
+ {
+ _connection.ExceptionReceived(new AMQDisconnectedException("Redirect was vetoed by client"));
+ }
+ else
+ {
+ _connection.ExceptionReceived(new AMQDisconnectedException("Failover was vetoed by client"));
+ }
+ pl.FailoverLatch.Set();
+ pl.FailoverLatch = null;
+ return;
+ }
+ bool failoverSucceeded;
+ // when host is non null we have a specified failover host otherwise we all the client to cycle through
+ // all specified hosts
+
+ // if _host has value then we are performing a redirect.
+ if (_host != null)
+ {
+ // todo: fix SSL support!
+ failoverSucceeded = _connection.AttemptReconnection(_host, _port, null);
+ }
+ else
+ {
+ failoverSucceeded = _connection.AttemptReconnection();
+ }
+
+ // XXX: at this point it appears that we are going to set StateManager to existingStateManager in
+ // XXX: both paths of control.
+ if (!failoverSucceeded)
+ {
+ _connection.ProtocolListener.StateManager = existingStateManager;
+ _connection.ExceptionReceived(
+ new AMQDisconnectedException("Server closed connection and no failover " +
+ "was successful"));
+ }
+ else
+ {
+ _connection.ProtocolListener.StateManager = existingStateManager;
+ try
+ {
+ if (_connection.FirePreResubscribe())
+ {
+ _log.Info("Resubscribing on new connection");
+ _connection.ResubscribeChannels();
+ }
+ else
+ {
+ _log.Info("Client vetoed automatic resubscription");
+ }
+ _connection.FireFailoverComplete();
+ _connection.ProtocolListener.FailoverState = FailoverState.NOT_STARTED;
+ _log.Info("Connection failover completed successfully");
+ }
+ catch (Exception e)
+ {
+ _log.Info("Failover process failed - exception being propagated by protocol handler");
+ _connection.ProtocolListener.FailoverState = FailoverState.FAILED;
+ try
+ {
+ _connection.ProtocolListener.OnException(e);
+ }
+ catch (Exception ex)
+ {
+ _log.Error("Error notifying protocol session of error: " + ex, ex);
+ }
+ }
+ }
+ }
+ pl.FailoverLatch.Set();
+ }
+
+ public String getHost()
+ {
+ return _host;
+ }
+
+ public void setHost(String host)
+ {
+ _host = host;
+ }
+
+ public int getPort()
+ {
+ return _port;
+ }
+
+ public void setPort(int port)
+ {
+ _port = port;
+ }
+ }
+}
+
+
diff --git a/qpid/dotnet/Qpid.Client/Client/Failover/FailoverState.cs b/qpid/dotnet/Qpid.Client/Client/Failover/FailoverState.cs
new file mode 100644
index 0000000000..3058cdcd69
--- /dev/null
+++ b/qpid/dotnet/Qpid.Client/Client/Failover/FailoverState.cs
@@ -0,0 +1,31 @@
+/*
+ *
+ * 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.
+ *
+ */
+namespace Apache.Qpid.Client.Failover
+{
+ /// <summary>
+ /// Enumeration of failover states. Used to handle failover from within AMQProtocolHandler where MINA events need to be
+ /// dealt with and can happen during failover.
+ /// </summary>
+ enum FailoverState
+ {
+ NOT_STARTED, IN_PROGRESS, FAILED
+ }
+}
diff --git a/qpid/dotnet/Qpid.Client/Client/Failover/FailoverSupport.cs b/qpid/dotnet/Qpid.Client/Client/Failover/FailoverSupport.cs
new file mode 100644
index 0000000000..afa5301f39
--- /dev/null
+++ b/qpid/dotnet/Qpid.Client/Client/Failover/FailoverSupport.cs
@@ -0,0 +1,55 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+using log4net;
+
+namespace Apache.Qpid.Client.Failover
+{
+ public abstract class FailoverSupport
+ {
+ private static readonly ILog _log = LogManager.GetLogger(typeof(FailoverSupport));
+
+ public object execute(AMQConnection con)
+ {
+ // We wait until we are not in the middle of failover before acquiring the mutex and then proceeding.
+ // Any method that can potentially block for any reason should use this class so that deadlock will not
+ // occur. The FailoverException is propagated by the AMQProtocolHandler to any listeners (e.g. frame listeners)
+ // that might be causing a block. When that happens, the exception is caught here and the mutex is released
+ // before waiting for the failover to complete (either successfully or unsuccessfully).
+ while (true)
+ {
+ con.ProtocolListener.BlockUntilNotFailingOver();
+ lock (con.FailoverMutex)
+ {
+ try
+ {
+ return operation();
+ }
+ catch (FailoverException e)
+ {
+ _log.Info("Failover exception caught during operation", e);
+ }
+ }
+ }
+ }
+
+ protected abstract object operation();
+ }
+}
diff --git a/qpid/dotnet/Qpid.Client/Client/Handler/BasicDeliverMethodHandler.cs b/qpid/dotnet/Qpid.Client/Client/Handler/BasicDeliverMethodHandler.cs
new file mode 100644
index 0000000000..def1e78e8c
--- /dev/null
+++ b/qpid/dotnet/Qpid.Client/Client/Handler/BasicDeliverMethodHandler.cs
@@ -0,0 +1,42 @@
+/*
+ *
+ * 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.
+ *
+ */
+using log4net;
+using Apache.Qpid.Client.Message;
+using Apache.Qpid.Client.Protocol;
+using Apache.Qpid.Client.State;
+using Apache.Qpid.Framing;
+
+namespace Apache.Qpid.Client.Handler
+{
+ public class BasicDeliverMethodHandler : IStateAwareMethodListener
+ {
+ private static readonly ILog _logger = LogManager.GetLogger(typeof(BasicDeliverMethodHandler));
+
+ public void MethodReceived(AMQStateManager stateManager, AMQMethodEvent evt)
+ {
+ UnprocessedMessage msg = new UnprocessedMessage();
+ msg.DeliverBody = (BasicDeliverBody) evt.Method;
+ msg.ChannelId = evt.ChannelId;
+ _logger.Debug("New JmsDeliver method received");
+ evt.ProtocolSession.UnprocessedMessageReceived(msg);
+ }
+ }
+}
diff --git a/qpid/dotnet/Qpid.Client/Client/Handler/BasicReturnMethodHandler.cs b/qpid/dotnet/Qpid.Client/Client/Handler/BasicReturnMethodHandler.cs
new file mode 100644
index 0000000000..f413dfc9c6
--- /dev/null
+++ b/qpid/dotnet/Qpid.Client/Client/Handler/BasicReturnMethodHandler.cs
@@ -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.
+ *
+ */
+using log4net;
+using Apache.Qpid.Client.Message;
+using Apache.Qpid.Client.Protocol;
+using Apache.Qpid.Client.State;
+using Apache.Qpid.Framing;
+
+namespace Apache.Qpid.Client.Handler
+{
+ public class BasicReturnMethodHandler : IStateAwareMethodListener
+ {
+ private static readonly ILog _logger = LogManager.GetLogger(typeof(BasicReturnMethodHandler));
+
+ public void MethodReceived(AMQStateManager stateManager, AMQMethodEvent evt)
+ {
+ _logger.Debug("New Basic.Return method received");
+ UnprocessedMessage msg = new UnprocessedMessage();
+ msg.DeliverBody = null;
+ msg.BounceBody = (BasicReturnBody) evt.Method;
+ msg.ChannelId = evt.ChannelId;
+
+ evt.ProtocolSession.UnprocessedMessageReceived(msg);
+ }
+ }
+}
diff --git a/qpid/dotnet/Qpid.Client/Client/Handler/ChannelCloseMethodHandler.cs b/qpid/dotnet/Qpid.Client/Client/Handler/ChannelCloseMethodHandler.cs
new file mode 100644
index 0000000000..9ed09a0d01
--- /dev/null
+++ b/qpid/dotnet/Qpid.Client/Client/Handler/ChannelCloseMethodHandler.cs
@@ -0,0 +1,68 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+using log4net;
+using Apache.Qpid.Client.Protocol;
+using Apache.Qpid.Client.State;
+using Apache.Qpid.Protocol;
+using Apache.Qpid.Framing;
+
+namespace Apache.Qpid.Client.Handler
+{
+ public class ChannelCloseMethodHandler : IStateAwareMethodListener
+ {
+ private static readonly ILog _logger = LogManager.GetLogger(typeof(ChannelCloseMethodHandler));
+
+ public void MethodReceived(AMQStateManager stateManager, AMQMethodEvent evt)
+ {
+ _logger.Debug("ChannelClose method received");
+ ChannelCloseBody method = (ChannelCloseBody) evt.Method;
+
+ int errorCode = method.ReplyCode;
+ string reason = method.ReplyText;
+ if (_logger.IsDebugEnabled)
+ {
+ _logger.Debug("Channel close reply code: " + errorCode + ", reason: " + reason);
+ }
+
+ AMQFrame frame = ChannelCloseOkBody.CreateAMQFrame(evt.ChannelId);
+ evt.ProtocolSession.WriteFrame(frame);
+
+ if ( errorCode != AMQConstant.REPLY_SUCCESS.Code )
+ {
+ _logger.Debug("Channel close received with errorCode " + errorCode + ", throwing exception");
+ if ( errorCode == AMQConstant.NO_CONSUMERS.Code )
+ throw new AMQNoConsumersException(reason);
+ if ( errorCode == AMQConstant.NO_ROUTE.Code )
+ throw new AMQNoRouteException(reason);
+ if ( errorCode == AMQConstant.INVALID_ARGUMENT.Code )
+ throw new AMQInvalidArgumentException(reason);
+ if ( errorCode == AMQConstant.INVALID_ROUTING_KEY.Code )
+ throw new AMQInvalidRoutingKeyException(reason);
+ // any other
+ throw new AMQChannelClosedException(errorCode, "Error: " + reason);
+ }
+ evt.ProtocolSession.ChannelClosed(evt.ChannelId, errorCode, reason);
+ }
+ }
+}
+
+
+
diff --git a/qpid/dotnet/Qpid.Client/Client/Handler/ConnectionCloseMethodHandler.cs b/qpid/dotnet/Qpid.Client/Client/Handler/ConnectionCloseMethodHandler.cs
new file mode 100644
index 0000000000..66cff3bc65
--- /dev/null
+++ b/qpid/dotnet/Qpid.Client/Client/Handler/ConnectionCloseMethodHandler.cs
@@ -0,0 +1,68 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+using System;
+using System.Threading;
+using log4net;
+using Apache.Qpid.Client.Protocol;
+using Apache.Qpid.Client.State;
+using Apache.Qpid.Framing;
+using Apache.Qpid.Protocol;
+
+namespace Apache.Qpid.Client.Handler
+{
+ public class ConnectionCloseMethodHandler : IStateAwareMethodListener
+ {
+ private static readonly ILog _logger = LogManager.GetLogger(typeof(ConnectionCloseMethodHandler));
+
+ public void MethodReceived(AMQStateManager stateManager, AMQMethodEvent evt)
+ {
+ _logger.Debug("ConnectionClose frame received");
+ ConnectionCloseBody method = (ConnectionCloseBody) evt.Method;
+
+ int errorCode = method.ReplyCode;
+ String reason = method.ReplyText;
+
+ // send CloseOK
+ evt.ProtocolSession.WriteFrame(ConnectionCloseOkBody.CreateAMQFrame(evt.ChannelId));
+
+ if ( errorCode != AMQConstant.REPLY_SUCCESS.Code )
+ {
+ if ( errorCode == AMQConstant.NOT_ALLOWED.Code )
+ {
+ _logger.Info("Authentication Error: " + Thread.CurrentThread.Name);
+ evt.ProtocolSession.CloseProtocolSession();
+
+ //todo this is a bit of a fudge (could be conssidered such as each new connection needs a new state manager or at least a fresh state.
+ stateManager.ChangeState(AMQState.CONNECTION_NOT_STARTED);
+
+ throw new AMQAuthenticationException(errorCode, reason);
+ } else
+ {
+ _logger.Info("Connection close received with error code " + errorCode);
+ throw new AMQConnectionClosedException(errorCode, "Error: " + reason);
+ }
+ }
+ // this actually closes the connection in the case where it is not an error.
+ evt.ProtocolSession.CloseProtocolSession();
+ stateManager.ChangeState(AMQState.CONNECTION_CLOSED);
+ }
+ }
+}
diff --git a/qpid/dotnet/Qpid.Client/Client/Handler/ConnectionCloseOkHandler.cs b/qpid/dotnet/Qpid.Client/Client/Handler/ConnectionCloseOkHandler.cs
new file mode 100644
index 0000000000..038da15731
--- /dev/null
+++ b/qpid/dotnet/Qpid.Client/Client/Handler/ConnectionCloseOkHandler.cs
@@ -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.
+ *
+ */
+using log4net;
+using Apache.Qpid.Client.Protocol;
+using Apache.Qpid.Client.State;
+using Apache.Qpid.Framing;
+
+namespace Apache.Qpid.Client.Handler
+{
+ public class ConnectionCloseOkHandler : IStateAwareMethodListener
+ {
+ private static readonly ILog _logger = LogManager.GetLogger(typeof(ConnectionCloseOkHandler));
+
+ public void MethodReceived(AMQStateManager stateManager, AMQMethodEvent evt)
+ {
+ _logger.Debug("ConnectionCloseOk frame received");
+// ConnectionCloseOkBody method = (ConnectionCloseOkBody)evt.Method;
+ stateManager.ChangeState(AMQState.CONNECTION_CLOSED);
+ }
+ }
+}
+
+
diff --git a/qpid/dotnet/Qpid.Client/Client/Handler/ConnectionOpenOkMethodHandler.cs b/qpid/dotnet/Qpid.Client/Client/Handler/ConnectionOpenOkMethodHandler.cs
new file mode 100644
index 0000000000..a12e4ead60
--- /dev/null
+++ b/qpid/dotnet/Qpid.Client/Client/Handler/ConnectionOpenOkMethodHandler.cs
@@ -0,0 +1,35 @@
+/*
+ *
+ * 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.
+ *
+ */
+using Apache.Qpid.Client.Protocol;
+using Apache.Qpid.Client.State;
+
+namespace Apache.Qpid.Client.Handler
+{
+ public class ConnectionOpenOkMethodHandler : IStateAwareMethodListener
+ {
+ public void MethodReceived(AMQStateManager stateManager, AMQMethodEvent evt)
+ {
+ stateManager.ChangeState(AMQState.CONNECTION_OPEN);
+ }
+ }
+}
+
+
diff --git a/qpid/dotnet/Qpid.Client/Client/Handler/ConnectionRedirectMethodHandler.cs b/qpid/dotnet/Qpid.Client/Client/Handler/ConnectionRedirectMethodHandler.cs
new file mode 100644
index 0000000000..08cc580b17
--- /dev/null
+++ b/qpid/dotnet/Qpid.Client/Client/Handler/ConnectionRedirectMethodHandler.cs
@@ -0,0 +1,68 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+using log4net;
+using Apache.Qpid.Client.Protocol;
+using Apache.Qpid.Client.State;
+
+namespace Apache.Qpid.Client.Handler
+{
+ public class ConnectionRedirectMethodHandler : IStateAwareMethodListener
+ {
+// private static readonly ILog _logger = LogManager.GetLogger(typeof(ConnectionRedirectMethodHandler));
+
+ private const int DEFAULT_REDIRECT_PORT = 5672;
+
+ private static ConnectionRedirectMethodHandler _handler = new ConnectionRedirectMethodHandler();
+
+ public static ConnectionRedirectMethodHandler GetInstance()
+ {
+ return _handler;
+ }
+
+ private ConnectionRedirectMethodHandler()
+ {
+ }
+
+ public void MethodReceived(AMQStateManager stateManager, AMQMethodEvent evt)
+ {
+ /*_logger.Info("ConnectionRedirect frame received");
+ ConnectionRedirectBody method = (ConnectionRedirectBody) evt.Method;
+
+ // the host is in the form hostname:port with the port being optional
+ int portIndex = method.Host.IndexOf(':');
+ String host;
+ int port;
+ if (portIndex == -1)
+ {
+ host = method.Host;
+ port = DEFAULT_REDIRECT_PORT;
+ }
+ else
+ {
+ host = method.Host.Substring(0, portIndex);
+ port = Int32.Parse(method.Host.Substring(portIndex + 1));
+ }
+ evt.ProtocolSession.Failover(host, port);*/
+ }
+ }
+}
+
+
diff --git a/qpid/dotnet/Qpid.Client/Client/Handler/ConnectionSecureMethodHandler.cs b/qpid/dotnet/Qpid.Client/Client/Handler/ConnectionSecureMethodHandler.cs
new file mode 100644
index 0000000000..9333d4d0a6
--- /dev/null
+++ b/qpid/dotnet/Qpid.Client/Client/Handler/ConnectionSecureMethodHandler.cs
@@ -0,0 +1,60 @@
+/*
+ *
+ * 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.
+ *
+ */
+using Apache.Qpid.Client.Protocol;
+using Apache.Qpid.Client.State;
+using Apache.Qpid.Framing;
+using Apache.Qpid.Sasl;
+
+namespace Apache.Qpid.Client.Handler
+{
+ public class ConnectionSecureMethodHandler : IStateAwareMethodListener
+ {
+ public void MethodReceived(AMQStateManager stateManager, AMQMethodEvent evt)
+ {
+ ISaslClient saslClient = evt.ProtocolSession.SaslClient;
+ if ( saslClient == null )
+ {
+ throw new AMQException("No SASL client set up - cannot proceed with authentication");
+ }
+
+
+ ConnectionSecureBody body = (ConnectionSecureBody)evt.Method;
+
+ try
+ {
+ // Evaluate server challenge
+ byte[] response = saslClient.EvaluateChallenge(body.Challenge);
+ // AMQP version change: Hardwire the version to 0-8 (major=8, minor=0)
+ // TODO: Connect this to the session version obtained from ProtocolInitiation for this session.
+ // Be aware of possible changes to parameter order as versions change.
+ AMQFrame responseFrame = ConnectionSecureOkBody.CreateAMQFrame(
+ evt.ChannelId, response);
+ evt.ProtocolSession.WriteFrame(responseFrame);
+ } catch ( SaslException e )
+ {
+ throw new AMQException("Error processing SASL challenge: " + e, e);
+ }
+ }
+ }
+}
+
+
+
diff --git a/qpid/dotnet/Qpid.Client/Client/Handler/ConnectionStartMethodHandler.cs b/qpid/dotnet/Qpid.Client/Client/Handler/ConnectionStartMethodHandler.cs
new file mode 100644
index 0000000000..c54662286b
--- /dev/null
+++ b/qpid/dotnet/Qpid.Client/Client/Handler/ConnectionStartMethodHandler.cs
@@ -0,0 +1,144 @@
+/*
+ *
+ * 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.
+ *
+ */
+using System;
+using System.Collections;
+using System.Text;
+using log4net;
+using Apache.Qpid.Client.Protocol;
+using Apache.Qpid.Client.Security;
+using Apache.Qpid.Client.State;
+using Apache.Qpid.Framing;
+using Apache.Qpid.Sasl;
+
+
+namespace Apache.Qpid.Client.Handler
+{
+ public class ConnectionStartMethodHandler : IStateAwareMethodListener
+ {
+ private static readonly ILog _log = LogManager.GetLogger(typeof(ConnectionStartMethodHandler));
+
+ public void MethodReceived(AMQStateManager stateManager, AMQMethodEvent evt)
+ {
+ ConnectionStartBody body = (ConnectionStartBody) evt.Method;
+ AMQProtocolSession ps = evt.ProtocolSession;
+
+ try
+ {
+ if ( body.Mechanisms == null )
+ {
+ throw new AMQException("mechanism not specified in ConnectionStart method frame");
+ }
+ string mechanisms = Encoding.UTF8.GetString(body.Mechanisms);
+ string selectedMechanism = ChooseMechanism(mechanisms);
+ if ( selectedMechanism == null )
+ {
+ throw new AMQException("No supported security mechanism found, passed: " + mechanisms);
+ }
+
+ byte[] saslResponse = DoAuthentication(selectedMechanism, ps);
+
+ if (body.Locales == null)
+ {
+ throw new AMQException("Locales is not defined in Connection Start method");
+ }
+ string allLocales = Encoding.ASCII.GetString(body.Locales);
+ string[] locales = allLocales.Split(' ');
+ string selectedLocale;
+ if (locales != null && locales.Length > 0)
+ {
+ selectedLocale = locales[0];
+ }
+ else
+ {
+ throw new AMQException("No locales sent from server, passed: " + locales);
+ }
+
+ stateManager.ChangeState(AMQState.CONNECTION_NOT_TUNED);
+ FieldTable clientProperties = new FieldTable();
+ clientProperties["product"] = "Apache.Qpid.NET";
+ clientProperties["version"] = "1.0";
+ clientProperties["platform"] = GetFullSystemInfo();
+ clientProperties["instance"] = ps.ClientID;
+ AMQFrame frame = ConnectionStartOkBody.CreateAMQFrame(
+ evt.ChannelId, clientProperties, selectedMechanism,
+ saslResponse, selectedLocale);
+ ps.WriteFrame(frame);
+ }
+ catch (Exception e)
+ {
+ throw new AMQException(_log, "Unable to decode data: " + e, e);
+ }
+ }
+
+ private string GetFullSystemInfo()
+ {
+ StringBuilder sysInfo = new StringBuilder();
+ // check if we're running on mono or .net
+ Type monoRuntime = Type.GetType("Mono.Runtime");
+ if ( monoRuntime != null )
+ sysInfo.Append("Mono");
+ else
+ sysInfo.Append(".NET");
+ sysInfo.Append(" ").Append(Environment.Version);
+ sysInfo.Append(", ").Append(Environment.OSVersion);
+ return sysInfo.ToString();
+ }
+
+ private string ChooseMechanism(string mechanisms)
+ {
+ return CallbackHandlerRegistry.Instance.ChooseMechanism(mechanisms);
+ }
+
+ private byte[] DoAuthentication(string selectedMechanism, AMQProtocolSession ps)
+ {
+ ISaslClient saslClient = Sasl.Sasl.CreateClient(
+ new string[] { selectedMechanism }, null, "AMQP", "localhost",
+ new Hashtable(), CreateCallbackHandler(selectedMechanism, ps)
+ );
+ if ( saslClient == null )
+ {
+ throw new AMQException("Client SASL configuration error: no SaslClient could be created for mechanism " +
+ selectedMechanism);
+ }
+ ps.SaslClient = saslClient;
+ try
+ {
+ return saslClient.HasInitialResponse ?
+ saslClient.EvaluateChallenge(new byte[0]) : null;
+ } catch ( Exception ex )
+ {
+ ps.SaslClient = null;
+ throw new AMQException("Unable to create SASL client", ex);
+ }
+ }
+
+ private IAMQCallbackHandler CreateCallbackHandler(string mechanism, AMQProtocolSession session)
+ {
+ Type type = CallbackHandlerRegistry.Instance.GetCallbackHandler(mechanism);
+ IAMQCallbackHandler handler =
+ (IAMQCallbackHandler)Activator.CreateInstance(type);
+ if ( handler == null )
+ throw new AMQException("Unable to create callback handler: " + mechanism);
+ handler.Initialize(session);
+ return handler;
+ }
+ }
+}
diff --git a/qpid/dotnet/Qpid.Client/Client/Handler/ConnectionTuneMethodHandler.cs b/qpid/dotnet/Qpid.Client/Client/Handler/ConnectionTuneMethodHandler.cs
new file mode 100644
index 0000000000..15a1d908b7
--- /dev/null
+++ b/qpid/dotnet/Qpid.Client/Client/Handler/ConnectionTuneMethodHandler.cs
@@ -0,0 +1,63 @@
+/*
+ *
+ * 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.
+ *
+ */
+using System;
+using log4net;
+using Apache.Qpid.Client.Protocol;
+using Apache.Qpid.Client.State;
+using Apache.Qpid.Framing;
+
+namespace Apache.Qpid.Client.Handler
+{
+ public class ConnectionTuneMethodHandler : IStateAwareMethodListener
+ {
+ private static readonly ILog _logger = LogManager.GetLogger(typeof(ConnectionTuneMethodHandler));
+
+ public void MethodReceived(AMQStateManager stateManager, AMQMethodEvent evt)
+ {
+ _logger.Debug("ConnectionTune frame received");
+ ConnectionTuneBody frame = (ConnectionTuneBody) evt.Method;
+ AMQProtocolSession session = evt.ProtocolSession;
+
+ ConnectionTuneParameters parameters = session.ConnectionTuneParameters;
+ if (parameters == null)
+ {
+ parameters = new ConnectionTuneParameters();
+ }
+
+ _logger.Debug(String.Format("ConnectionTune.heartbeat = {0}.", frame.Heartbeat));
+
+ parameters.FrameMax = frame.FrameMax;
+ parameters.Heartbeat = frame.Heartbeat;
+ session.ConnectionTuneParameters = parameters;
+
+ stateManager.ChangeState(AMQState.CONNECTION_NOT_OPENED);
+ session.WriteFrame(ConnectionTuneOkBody.CreateAMQFrame(
+ evt.ChannelId, frame.ChannelMax, frame.FrameMax, frame.Heartbeat));
+ session.WriteFrame(ConnectionOpenBody.CreateAMQFrame(
+ evt.ChannelId, session.AMQConnection.VirtualHost, null, true));
+
+ if (frame.Heartbeat > 0)
+ {
+ evt.ProtocolSession.AMQConnection.StartHeartBeatThread(frame.Heartbeat);
+ }
+ }
+ }
+}
diff --git a/qpid/dotnet/Qpid.Client/Client/Handler/QueueDeleteOkMethodHandler.cs b/qpid/dotnet/Qpid.Client/Client/Handler/QueueDeleteOkMethodHandler.cs
new file mode 100644
index 0000000000..70aa3e1078
--- /dev/null
+++ b/qpid/dotnet/Qpid.Client/Client/Handler/QueueDeleteOkMethodHandler.cs
@@ -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.
+ *
+ */
+using log4net;
+using Apache.Qpid.Client.Message;
+using Apache.Qpid.Client.Protocol;
+using Apache.Qpid.Client.State;
+using Apache.Qpid.Framing;
+
+namespace Apache.Qpid.Client.Handler
+{
+ public class QueueDeleteOkMethodHandler : IStateAwareMethodListener
+ {
+
+ private static readonly ILog _logger = LogManager.GetLogger(typeof(QueueDeleteOkMethodHandler));
+
+ public void MethodReceived(AMQStateManager stateManager, AMQMethodEvent evt)
+ {
+ QueueDeleteOkBody body = (QueueDeleteOkBody)evt.Method;
+ if (body != null)
+ {
+ _logger.InfoFormat("Received Queue.Delete-Ok message, message count {0}", body.MessageCount);
+ }
+ }
+
+ }
+}
diff --git a/qpid/dotnet/Qpid.Client/Client/Handler/QueuePurgeOkMethodHandler.cs b/qpid/dotnet/Qpid.Client/Client/Handler/QueuePurgeOkMethodHandler.cs
new file mode 100644
index 0000000000..22db70575d
--- /dev/null
+++ b/qpid/dotnet/Qpid.Client/Client/Handler/QueuePurgeOkMethodHandler.cs
@@ -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.
+ *
+ */
+using log4net;
+using Apache.Qpid.Client.Message;
+using Apache.Qpid.Client.Protocol;
+using Apache.Qpid.Client.State;
+using Apache.Qpid.Framing;
+
+namespace Apache.Qpid.Client.Handler
+{
+ public class QueuePurgeOkMethodHandler : IStateAwareMethodListener
+ {
+
+ private static readonly ILog _logger = LogManager.GetLogger(typeof(QueuePurgeOkMethodHandler));
+
+ public void MethodReceived(AMQStateManager stateManager, AMQMethodEvent evt)
+ {
+ QueuePurgeOkBody body = (QueuePurgeOkBody)evt.Method;
+ if (body != null)
+ {
+ _logger.InfoFormat("Received Queue.Purge-Ok message, message count {0}", body.MessageCount);
+ }
+ }
+
+ }
+}
diff --git a/qpid/dotnet/Qpid.Client/Client/Message/AMQMessage.cs b/qpid/dotnet/Qpid.Client/Client/Message/AMQMessage.cs
new file mode 100644
index 0000000000..e58de2ab96
--- /dev/null
+++ b/qpid/dotnet/Qpid.Client/Client/Message/AMQMessage.cs
@@ -0,0 +1,58 @@
+/*
+ *
+ * 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.
+ *
+ */
+using Apache.Qpid.Framing;
+
+namespace Apache.Qpid.Client.Message
+{
+ public class AMQMessage
+ {
+ protected IContentHeaderProperties _contentHeaderProperties;
+
+ /// <summary>
+ /// If the acknowledge mode is CLIENT_ACKNOWLEDGE the session is required
+ /// </summary>
+ protected AmqChannel _channel;
+
+ private long _deliveryTag;
+
+ public AMQMessage(IContentHeaderProperties properties, long deliveryTag)
+ {
+ _contentHeaderProperties = properties;
+ _deliveryTag = deliveryTag;
+ }
+
+ public AMQMessage(IContentHeaderProperties properties)
+ : this(properties, -1)
+ {
+ }
+
+ public long DeliveryTag
+ {
+ get { return _deliveryTag; }
+ }
+
+ public AmqChannel Channel
+ {
+ get { return _channel; }
+ set { _channel = value; }
+ }
+ }
+}
diff --git a/qpid/dotnet/Qpid.Client/Client/Message/AMQMessageFactory.cs b/qpid/dotnet/Qpid.Client/Client/Message/AMQMessageFactory.cs
new file mode 100644
index 0000000000..f352d62c11
--- /dev/null
+++ b/qpid/dotnet/Qpid.Client/Client/Message/AMQMessageFactory.cs
@@ -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.
+ *
+ */
+using System.Collections;
+using Apache.Qpid.Framing;
+using log4net;
+using Apache.Qpid.Buffer;
+
+namespace Apache.Qpid.Client.Message
+{
+ public abstract class AbstractQmsMessageFactory : IMessageFactory
+ {
+ public abstract AbstractQmsMessage CreateMessage(string mimeType);
+
+ private static readonly ILog _logger = LogManager.GetLogger(typeof (AbstractQmsMessageFactory));
+
+ protected abstract AbstractQmsMessage CreateMessage(long messageNbr, ByteBuffer data, ContentHeaderBody contentHeader);
+
+ protected AbstractQmsMessage CreateMessageWithBody(long messageNbr,
+ ContentHeaderBody contentHeader,
+ IList bodies)
+ {
+ ByteBuffer data;
+
+ // we optimise the non-fragmented case to avoid copying
+ if (bodies != null && bodies.Count == 1)
+ {
+ _logger.Debug("Non-fragmented message body (bodySize=" + contentHeader.BodySize +")");
+ data = ((ContentBody)bodies[0]).Payload;
+ }
+ else
+ {
+ _logger.Debug("Fragmented message body (" + bodies.Count + " frames, bodySize=" + contentHeader.BodySize + ")");
+ data = ByteBuffer.Allocate((int)contentHeader.BodySize); // XXX: Is cast a problem?
+ foreach (ContentBody body in bodies) {
+ data.Put(body.Payload);
+ //body.Payload.Release();
+ }
+
+ data.Flip();
+ }
+ _logger.Debug("Creating message from buffer with position=" + data.Position + " and remaining=" + data.Remaining);
+
+ return CreateMessage(messageNbr, data, contentHeader);
+ }
+
+ public AbstractQmsMessage CreateMessage(long messageNbr, bool redelivered,
+ ContentHeaderBody contentHeader,
+ IList bodies)
+ {
+ AbstractQmsMessage msg = CreateMessageWithBody(messageNbr, contentHeader, bodies);
+ msg.Redelivered = redelivered;
+ return msg;
+ }
+ }
+}
diff --git a/qpid/dotnet/Qpid.Client/Client/Message/AbstractQmsMessage.cs b/qpid/dotnet/Qpid.Client/Client/Message/AbstractQmsMessage.cs
new file mode 100644
index 0000000000..34b47137e5
--- /dev/null
+++ b/qpid/dotnet/Qpid.Client/Client/Message/AbstractQmsMessage.cs
@@ -0,0 +1,694 @@
+/*
+ *
+ * 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.
+ *
+ */
+using System;
+using System.Collections;
+using System.Text;
+using log4net;
+using Apache.Qpid.Framing;
+using Apache.Qpid.Messaging;
+using Apache.Qpid.Buffer;
+
+namespace Apache.Qpid.Client.Message
+{
+ public abstract class AbstractQmsMessage : AMQMessage, IMessage
+ {
+ private static ILog log = LogManager.GetLogger(typeof(AbstractQmsMessage));
+
+ protected bool _redelivered;
+
+ protected ByteBuffer _data;
+ protected bool _readableMessage = false;
+ private QpidHeaders _headers;
+
+ protected AbstractQmsMessage(ByteBuffer data)
+ : base(new BasicContentHeaderProperties())
+ {
+ Init(data);
+ }
+
+ protected AbstractQmsMessage(long deliveryTag, BasicContentHeaderProperties contentHeader, ByteBuffer data)
+ : this(contentHeader, deliveryTag)
+ {
+ Init(data);
+ }
+
+ protected AbstractQmsMessage(BasicContentHeaderProperties contentHeader, long deliveryTag) : base(contentHeader, deliveryTag)
+ {
+ Init(null);
+ }
+
+ private void Init(ByteBuffer data)
+ {
+ _data = data;
+ if ( _data != null )
+ {
+ _data.Acquire();
+ }
+ _readableMessage = (data != null);
+ if ( ContentHeaderProperties.Headers == null )
+ ContentHeaderProperties.Headers = new FieldTable();
+ _headers = new QpidHeaders(ContentHeaderProperties.Headers);
+ }
+
+ //
+ // Properties
+ //
+
+ /// <summary>
+ /// The application message identifier
+ /// </summary>
+ public string MessageId
+ {
+ get
+ {
+ if (ContentHeaderProperties.MessageId == null)
+ {
+ ContentHeaderProperties.MessageId = "ID:" + DeliveryTag;
+ }
+ return ContentHeaderProperties.MessageId;
+ }
+ set { ContentHeaderProperties.MessageId = value; }
+ }
+
+ /// <summary>
+ /// The message timestamp
+ /// </summary>
+ public long Timestamp
+ {
+ get
+ {
+ // TODO: look at ulong/long choice
+ return (long) ContentHeaderProperties.Timestamp;
+ }
+ set
+ {
+ ContentHeaderProperties.Timestamp = (ulong) value;
+ }
+ }
+
+ /// <summary>
+ /// The <see cref="CorrelationId"/> as a byte array.
+ /// </summary>
+ public byte[] CorrelationIdAsBytes
+ {
+ get { return Encoding.Default.GetBytes(ContentHeaderProperties.CorrelationId); }
+ set { ContentHeaderProperties.CorrelationId = Encoding.Default.GetString(value); }
+ }
+
+ /// <summary>
+ /// The application correlation identifier
+ /// </summary>
+ public string CorrelationId
+ {
+ get { return ContentHeaderProperties.CorrelationId; }
+ set { ContentHeaderProperties.CorrelationId = value; }
+ }
+
+ struct Dest
+ {
+ public string ExchangeName;
+ public string RoutingKey;
+
+ public Dest(string exchangeName, string routingKey)
+ {
+ ExchangeName = exchangeName;
+ RoutingKey = routingKey;
+ }
+ }
+
+ /// <summary>
+ /// Exchange name of the reply-to address
+ /// </summary>
+ public string ReplyToExchangeName
+ {
+ get
+ {
+ return ReadReplyToHeader().ExchangeName;
+ }
+ set
+ {
+ BindingURL dest = ReadReplyToHeader();
+ dest.ExchangeName = value;
+ WriteReplyToHeader(dest);
+ }
+ }
+
+ /// <summary>
+ /// Routing key of the reply-to address
+ /// </summary>
+ public string ReplyToRoutingKey
+ {
+ get
+ {
+ return ReadReplyToHeader().RoutingKey;
+ }
+ set
+ {
+ BindingURL dest = ReadReplyToHeader();
+ dest.RoutingKey = value;
+ WriteReplyToHeader(dest);
+ }
+ }
+
+ /// <summary>
+ /// Non-persistent (1) or persistent (2)
+ /// </summary>
+ public DeliveryMode DeliveryMode
+ {
+ get
+ {
+ byte b = ContentHeaderProperties.DeliveryMode;
+ switch (b)
+ {
+ case 1:
+ return DeliveryMode.NonPersistent;
+ case 2:
+ return DeliveryMode.Persistent;
+ default:
+ throw new QpidException("Illegal value for delivery mode in content header properties");
+ }
+ }
+ set
+ {
+ ContentHeaderProperties.DeliveryMode = (byte)(value==DeliveryMode.NonPersistent?1:2);
+ }
+ }
+
+ /// <summary>
+ /// True, if this is a redelivered message
+ /// </summary>
+ public bool Redelivered
+ {
+ get { return _redelivered; }
+ set { _redelivered = value; }
+ }
+
+ /// <summary>
+ /// The message type name
+ /// </summary>
+ public string Type
+ {
+ get { return ContentHeaderProperties.Type; }
+ set { ContentHeaderProperties.Type = value; }
+ }
+
+ /// <summary>
+ /// Message expiration specification
+ /// </summary>
+ public long Expiration
+ {
+ get { return ContentHeaderProperties.Expiration; }
+ set { ContentHeaderProperties.Expiration = value; }
+ }
+
+ /// <summary>
+ /// The message priority, 0 to 9
+ /// </summary>
+ public byte Priority
+ {
+ get { return ContentHeaderProperties.Priority; }
+ set { ContentHeaderProperties.Priority = (byte) value; }
+ }
+
+ /// <summary>
+ /// The MIME Content Type
+ /// </summary>
+ public string ContentType
+ {
+ get { return ContentHeaderProperties.ContentType; }
+ set { ContentHeaderProperties.ContentType = value; }
+ }
+
+ /// <summary>
+ /// The MIME Content Encoding
+ /// </summary>
+ public string ContentEncoding
+ {
+ get { return ContentHeaderProperties.Encoding; }
+ set { ContentHeaderProperties.Encoding = value; }
+ }
+
+ /// <summary>
+ /// Headers of this message
+ /// </summary>
+ public IHeaders Headers
+ {
+ get { return _headers; }
+ }
+
+ /// <summary>
+ /// The creating user id
+ /// </summary>
+ public string UserId
+ {
+ get { return ContentHeaderProperties.UserId; }
+ set { ContentHeaderProperties.UserId = value; }
+ }
+
+ /// <summary>
+ /// The creating application id
+ /// </summary>
+ public string AppId
+ {
+ get { return ContentHeaderProperties.AppId; }
+ set { ContentHeaderProperties.AppId = value; }
+ }
+
+ /// <summary>
+ /// Intra-cluster routing identifier
+ /// </summary>
+ public string ClusterId
+ {
+ get { return ContentHeaderProperties.ClusterId; }
+ set { ContentHeaderProperties.ClusterId = value; }
+ }
+
+ /// <summary>
+ /// Return the raw byte array that is used to populate the frame when sending
+ /// the message.
+ /// </summary>
+ /// <value>a byte array of message data</value>
+ public ByteBuffer Data
+ {
+ get
+ {
+ if (_data != null)
+ {
+ if (!_readableMessage)
+ {
+ _data.Flip();
+ }
+ else
+ {
+ // Make sure we rewind the data just in case any method has moved the
+ // position beyond the start.
+ _data.Rewind();
+ }
+ }
+ return _data;
+ }
+
+ set
+ {
+ _data = value;
+ }
+ }
+
+ public void Acknowledge()
+ {
+ // the JMS 1.1 spec says in section 3.6 that calls to acknowledge are ignored when client acknowledge
+ // is not specified. In our case, we only set the session field where client acknowledge mode is specified.
+ if (_channel != null)
+ {
+ // we set multiple to true here since acknowledgement implies acknowledge of all count messages
+ // received on the session
+ _channel.AcknowledgeMessage((ulong)DeliveryTag, true);
+ }
+
+ }
+
+ public abstract void ClearBodyImpl();
+
+ public void ClearBody()
+ {
+ ClearBodyImpl();
+ _readableMessage = false;
+ }
+
+ /// <summary>
+ /// Get a String representation of the body of the message. Used in the
+ /// toString() method which outputs this before message properties.
+ /// </summary>
+ /// <exception cref="QpidException"></exception>
+ public abstract string ToBodyString();
+
+ public override string ToString()
+ {
+ try
+ {
+ StringBuilder buf = new StringBuilder("Body:\n");
+ buf.Append(ToBodyString());
+ buf.Append("\nQmsTimestamp: ").Append(Timestamp);
+ buf.Append("\nQmsExpiration: ").Append(Expiration);
+ buf.Append("\nQmsPriority: ").Append(Priority);
+ buf.Append("\nQmsDeliveryMode: ").Append(DeliveryMode);
+ buf.Append("\nReplyToExchangeName: ").Append(ReplyToExchangeName);
+ buf.Append("\nReplyToRoutingKey: ").Append(ReplyToRoutingKey);
+ buf.Append("\nAMQ message number: ").Append(DeliveryTag);
+ buf.Append("\nProperties:");
+ if (ContentHeaderProperties.Headers == null)
+ {
+ buf.Append("<NONE>");
+ }
+ else
+ {
+ buf.Append(Headers.ToString());
+ }
+ return buf.ToString();
+ }
+ catch (Exception e)
+ {
+ return e.ToString();
+ }
+ }
+
+ public FieldTable PopulateHeadersFromMessageProperties()
+ {
+ if (ContentHeaderProperties.Headers == null)
+ {
+ return null;
+ }
+ else
+ {
+ //
+ // We need to convert every property into a String representation
+ // Note that type information is preserved in the property name
+ //
+ FieldTable table = new FieldTable();
+ foreach (DictionaryEntry entry in ContentHeaderProperties.Headers)
+ {
+ string propertyName = (string) entry.Key;
+ if (propertyName == null)
+ {
+ continue;
+ }
+ else
+ {
+ table[propertyName] = entry.Value.ToString();
+ }
+ }
+ return table;
+ }
+ }
+
+ public BasicContentHeaderProperties ContentHeaderProperties
+ {
+ get
+ {
+ return (BasicContentHeaderProperties) _contentHeaderProperties;
+ }
+ }
+
+ protected virtual void Reset()
+ {
+ _readableMessage = true;
+ }
+
+ public bool IsReadable
+ {
+ get { return _readableMessage; }
+ }
+
+ public bool isWritable
+ {
+ get { return !_readableMessage; }
+ }
+
+ protected void CheckReadable()
+ {
+ if ( !_readableMessage )
+ {
+ throw new MessageNotReadableException("You need to call reset() to make the message readable");
+ }
+ }
+
+ /// <summary>
+ /// Decodes the replyto field if one is set.
+ ///
+ /// Splits a replyto field containing an exchange name followed by a ':', followed by a routing key into the exchange name and
+ /// routing key seperately. The exchange name may be empty in which case the empty string is returned. If the exchange name is
+ /// empty the replyto field is expected to being with ':'.
+ ///
+ /// Anyhting other than a two part replyto field sperated with a ':' will result in an exception.
+ /// </summary>
+ ///
+ /// <returns>A destination initialized to the replyto location if a replyto field was set, or an empty destination otherwise.</returns>
+ private BindingURL ReadReplyToHeader()
+ {
+ string replyToEncoding = ContentHeaderProperties.ReplyTo;
+ //log.Debug("replyToEncoding = " + replyToEncoding);
+
+ BindingURL bindingUrl = new BindingURL(replyToEncoding);
+ //log.Debug("bindingUrl = " + bindingUrl.ToString());
+
+ return bindingUrl;
+
+ //log.Info("replyToEncoding = " + replyToEncoding);
+
+// if ( replyToEncoding == null )
+// {
+// return new Dest();
+// } else
+// {
+// // Split the replyto field on a ':'
+// string[] split = replyToEncoding.Split(':');
+
+// // Ensure that the replyto field argument only consisted of two parts.
+// if ( split.Length != 2 )
+// {
+// throw new QpidException("Illegal value in ReplyTo property: " + replyToEncoding);
+// }
+
+// // Extract the exchange name and routing key from the split replyto field.
+// string exchangeName = split[0];
+
+// string[] split2 = split[1].Split('/');
+// string routingKey = split2[3];
+
+// return new Dest(exchangeName, routingKey);
+// }
+ }
+
+ private void WriteReplyToHeader(BindingURL dest)
+ {
+ string encodedDestination = string.Format("{0}:{1}", dest.ExchangeName, dest.RoutingKey);
+ ContentHeaderProperties.ReplyTo = encodedDestination;
+ }
+ }
+
+ public class BindingURL
+ {
+ public readonly static string OPTION_EXCLUSIVE = "exclusive";
+ public readonly static string OPTION_AUTODELETE = "autodelete";
+ public readonly static string OPTION_DURABLE = "durable";
+ public readonly static string OPTION_CLIENTID = "clientid";
+ public readonly static string OPTION_SUBSCRIPTION = "subscription";
+ public readonly static string OPTION_ROUTING_KEY = "routingkey";
+
+ /// <summary> Holds the undecoded URL </summary>
+ string url;
+
+ /// <summary> Holds the decoded options. </summary>
+ IDictionary options = new Hashtable();
+
+ /// <summary> Holds the decoded exchange class. </summary>
+ string exchangeClass;
+
+ /// <summary> Holds the decoded exchange name. </summary>
+ string exchangeName;
+
+ /// <summary> Holds the destination name. </summary>
+ string destination;
+
+ /// <summary> Holds the decoded queue name. </summary>
+ string queueName;
+
+ /// <summary>
+ /// The binding URL has the format:
+ /// <exch_class>://<exch_name>/[<destination>]/[<queue>]?<option>='<value>'[,<option>='<value>']*
+ /// </summary>
+ public BindingURL(string url)
+ {
+ this.url = url;
+ Parse();
+ }
+
+ public string Url { get { return url; } }
+
+ public string ExchangeClass
+ {
+ get { return exchangeClass; }
+ set { exchangeClass = value; }
+ }
+
+ public string ExchangeName
+ {
+ get { return exchangeName; }
+ set { exchangeName = value; }
+ }
+
+ public string QueueName
+ {
+ get { return queueName; }
+ set { queueName = value; }
+ }
+
+ public string DestinationName
+ {
+ get { return destination; }
+ set { destination = value; }
+ }
+
+ public string RoutingKey {
+ get { return (string)options[OPTION_ROUTING_KEY]; }
+ set { options[OPTION_ROUTING_KEY] = value; }
+ }
+
+ public bool ContainsOption(string key) { return options.Contains(key); }
+
+ public string ToString()
+ {
+ return "BindingURL: [ ExchangeClass = " + ExchangeClass + ", ExchangeName = " + ExchangeName + ", QueueName = " + QueueName +
+ ", DestinationName = " + DestinationName + ", RoutingKey = " + RoutingKey + " ] ";
+ }
+
+ private void Parse()
+ {
+ Uri binding = new Uri(url);
+
+ // Extract the URI scheme, this contains the exchange class. It is defaulted to the direct exchange if not specified.
+ string exchangeClass = binding.Scheme;
+
+ if (exchangeClass == null)
+ {
+ url = ExchangeNameDefaults.DIRECT_EXCHANGE_CLASS + "://" + ExchangeNameDefaults.DIRECT + "//" + url;
+ Parse();
+
+ return;
+ }
+ else
+ {
+ this.exchangeClass = exchangeClass;
+ }
+
+ // Extract the host name, this contains the exchange name. It is defaulted to the default direct exchange if not specified.
+ string exchangeName = binding.Host;
+
+ if (exchangeName == null)
+ {
+ if (exchangeClass.Equals(ExchangeNameDefaults.DIRECT_EXCHANGE_CLASS))
+ {
+ this.exchangeName = "";
+ }
+ }
+ else
+ {
+ this.exchangeName = exchangeName;
+ }
+
+ // Extract the destination and queue name.
+ if ((binding.AbsolutePath == null) || binding.AbsolutePath.Equals(""))
+ {
+ throw new UriFormatException("Destination or Queue required");
+ }
+ else
+ {
+ int slashOffset = binding.AbsolutePath.IndexOf("/", 1);
+ if (slashOffset == -1)
+ {
+ throw new UriFormatException("Destination required");
+ }
+ else
+ {
+ String path = binding.AbsolutePath;
+
+ this.destination = path.Substring(1, slashOffset - 1);
+ this.queueName = path.Substring(slashOffset + 1);
+ }
+ }
+
+ ParseOptions(options, binding.Query);
+
+ // If the routing key is not set as an option, set it to the destination name.
+ if (!ContainsOption(OPTION_ROUTING_KEY))
+ {
+ options[OPTION_ROUTING_KEY] = destination;
+ }
+ }
+
+ /// <summary>
+ /// options looks like this
+ /// brokerlist='tcp://host:port?option='value',option='value';vm://:3/virtualpath?option='value'',failover='method?option='value',option='value'
+ /// </summary>
+ public static void ParseOptions(IDictionary optionMap, string options)
+ {
+ // Check that there really are some options to parse.
+ if ((options == null) || (options.IndexOf('=') == -1))
+ {
+ return;
+ }
+
+ int optionIndex = options.IndexOf('=');
+ string option = options.Substring(0, optionIndex);
+ int length = options.Length;
+ int nestedQuotes = 0;
+
+ // Holds the index of the final "'".
+ int valueIndex = optionIndex;
+
+ // Loop over all the options.Dest
+ while ((nestedQuotes > 0) || (valueIndex < length))
+ {
+ valueIndex++;
+
+ if (valueIndex >= length)
+ {
+ break;
+ }
+
+ if (options[valueIndex] == '\'')
+ {
+ if ((valueIndex + 1) < options.Length)
+ {
+ if ((options[valueIndex + 1] == '&') ||
+ (options[valueIndex + 1] == ',') ||
+ (options[valueIndex + 1] == ';') ||
+ (options[valueIndex + 1] == '\''))
+ {
+ nestedQuotes--;
+
+ if (nestedQuotes == 0)
+ {
+ // We've found the value of an option
+ break;
+ }
+ }
+ else
+ {
+ nestedQuotes++;
+ }
+ }
+ else
+ {
+ // We are at the end of the string
+ // Check to see if we are corectly closing quotes
+ if (options[valueIndex] == '\'')
+ {
+ nestedQuotes--;
+ }
+
+ break;
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/qpid/dotnet/Qpid.Client/Client/Message/IMessageFactory.cs b/qpid/dotnet/Qpid.Client/Client/Message/IMessageFactory.cs
new file mode 100644
index 0000000000..bed379290f
--- /dev/null
+++ b/qpid/dotnet/Qpid.Client/Client/Message/IMessageFactory.cs
@@ -0,0 +1,52 @@
+/*
+ *
+ * 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.
+ *
+ */
+using System.Collections;
+using Apache.Qpid.Framing;
+
+namespace Apache.Qpid.Client.Message
+{
+ public interface IMessageFactory
+ {
+ /// <summary>
+ /// Create a message
+ /// </summary>
+ /// <param name="deliverTag">Delivery Tag</param>
+ /// <param name="messageNbr">Message Sequence Number</param>
+ /// <param name="redelivered">True if this is a redelivered message</param>
+ /// <param name="contentHeader">Content headers</param>
+ /// <param name="bodies">Message bodies</param>
+ /// <returns>The new message</returns>
+ /// <exception cref="QpidMessagingException">if the message cannot be created</exception>
+ AbstractQmsMessage CreateMessage(long deliverTag, bool redelivered,
+ ContentHeaderBody contentHeader,
+ IList bodies);
+
+ /// <summary>
+ /// Creates the message.
+ /// </summary>
+ /// <param name="mimeType">Mime type to associate the new message with</param>
+ /// <returns>The new message</returns>
+ /// <exception cref="QpidMessagingException">if the message cannot be created</exception>
+ AbstractQmsMessage CreateMessage(string mimeType);
+ }
+}
+
+
diff --git a/qpid/dotnet/Qpid.Client/Client/Message/MessageFactoryRegistry.cs b/qpid/dotnet/Qpid.Client/Client/Message/MessageFactoryRegistry.cs
new file mode 100644
index 0000000000..fdb5e14aa6
--- /dev/null
+++ b/qpid/dotnet/Qpid.Client/Client/Message/MessageFactoryRegistry.cs
@@ -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.
+ *
+ */
+using System;
+using System.Collections;
+using Apache.Qpid.Framing;
+using Apache.Qpid.Messaging;
+
+namespace Apache.Qpid.Client.Message
+{
+ public class MessageFactoryRegistry
+ {
+ private readonly Hashtable _mimeToFactoryMap = new Hashtable();
+ private IMessageFactory _defaultFactory;
+
+ /// <summary>
+ /// Default factory to use for unknown message types
+ /// </summary>
+ public IMessageFactory DefaultFactory
+ {
+ get { return _defaultFactory; }
+ set { _defaultFactory = value; }
+ }
+
+ /// <summary>
+ /// Register a new message factory for a MIME type
+ /// </summary>
+ /// <param name="mimeType">Mime type to register</param>
+ /// <param name="mf"></param>
+ public void RegisterFactory(string mimeType, IMessageFactory mf)
+ {
+ if ( mf == null )
+ throw new ArgumentNullException("mf");
+ if ( mimeType == null || mimeType.Length == 0 )
+ throw new ArgumentNullException("mimeType");
+
+ _mimeToFactoryMap[mimeType] = mf;
+ }
+
+ /// <summary>
+ /// Remove a message factory
+ /// </summary>
+ /// <param name="mimeType">MIME type to unregister</param>
+ public void DeregisterFactory(string mimeType)
+ {
+ _mimeToFactoryMap.Remove(mimeType);
+ }
+
+ /// <summary>
+ /// Create a message. This looks up the MIME type from the content header and instantiates the appropriate
+ /// concrete message type.
+ /// </summary>
+ /// <param name="messageNbr">the AMQ message id</param>
+ /// <param name="redelivered">true if redelivered</param>
+ /// <param name="contentHeader">the content header that was received</param>
+ /// <param name="bodies">a list of ContentBody instances</param>
+ /// <returns>the message.</returns>
+ /// <exception cref="AMQException"/>
+ /// <exception cref="QpidException"/>
+ public AbstractQmsMessage CreateMessage(long messageNbr, bool redelivered,
+ ContentHeaderBody contentHeader,
+ IList bodies)
+ {
+ BasicContentHeaderProperties properties = (BasicContentHeaderProperties)contentHeader.Properties;
+
+ if ( properties.ContentType == null )
+ {
+ properties.ContentType = "";
+ }
+
+ IMessageFactory mf = GetFactory(properties.ContentType);
+ return mf.CreateMessage(messageNbr, redelivered, contentHeader, bodies);
+ }
+
+ /// <summary>
+ /// Create a new message of the specified type
+ /// </summary>
+ /// <param name="mimeType">The Mime type</param>
+ /// <returns>The new message</returns>
+ public AbstractQmsMessage CreateMessage(string mimeType)
+ {
+ if ( mimeType == null || mimeType.Length == 0 )
+ throw new ArgumentNullException("mimeType");
+
+ IMessageFactory mf = GetFactory(mimeType);
+ return mf.CreateMessage(mimeType);
+ }
+
+ /// <summary>
+ /// Construct a new registry with the default message factories registered
+ /// </summary>
+ /// <returns>a message factory registry</returns>
+ public static MessageFactoryRegistry NewDefaultRegistry()
+ {
+ MessageFactoryRegistry mf = new MessageFactoryRegistry();
+ mf.RegisterFactory("text/plain", new QpidTextMessageFactory());
+ mf.RegisterFactory("text/xml", new QpidTextMessageFactory());
+ mf.RegisterFactory("application/octet-stream", new QpidBytesMessageFactory());
+
+ mf.DefaultFactory = new QpidBytesMessageFactory();
+ return mf;
+ }
+
+ private IMessageFactory GetFactory(string mimeType)
+ {
+ IMessageFactory mf = (IMessageFactory)_mimeToFactoryMap[mimeType];
+ return mf != null ? mf : _defaultFactory;
+ }
+ }
+}
+
+
diff --git a/qpid/dotnet/Qpid.Client/Client/Message/QpidBytesMessage.cs b/qpid/dotnet/Qpid.Client/Client/Message/QpidBytesMessage.cs
new file mode 100644
index 0000000000..fb3efb1b0f
--- /dev/null
+++ b/qpid/dotnet/Qpid.Client/Client/Message/QpidBytesMessage.cs
@@ -0,0 +1,353 @@
+/*
+ *
+ * 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.
+ *
+ */
+using System;
+using System.IO;
+using System.Runtime.Serialization;
+using System.Text;
+using Apache.Qpid.Framing;
+using Apache.Qpid.Messaging;
+using Apache.Qpid.Buffer;
+
+namespace Apache.Qpid.Client.Message
+{
+ [Serializable]
+ class MessageEOFException : QpidException
+ {
+ public MessageEOFException(string message) : base(message)
+ {
+ }
+
+ protected MessageEOFException(SerializationInfo info, StreamingContext ctxt)
+ : base(info, ctxt)
+ {
+ }
+ }
+
+ public class QpidBytesMessage : AbstractQmsMessage, IBytesMessage
+ {
+ private const int DEFAULT_BUFFER_INITIAL_SIZE = 1024;
+
+ public QpidBytesMessage() : this(null)
+ {
+ }
+
+ /// <summary>
+ /// Construct a bytes message with existing data.
+ /// </summary>
+ /// <param name="data">if data is not null, the message is immediately in read only mode. if data is null, it is in
+ /// write-only mode</param>
+ QpidBytesMessage(ByteBuffer data) : base(data)
+ {
+ // superclass constructor has instantiated a content header at this point
+ if (data == null)
+ {
+ _data = ByteBuffer.Allocate(DEFAULT_BUFFER_INITIAL_SIZE);
+ _data.IsAutoExpand = true;
+ }
+ }
+
+ internal QpidBytesMessage(long messageNbr, ContentHeaderBody contentHeader, ByteBuffer data)
+ // TODO: this casting is ugly. Need to review whole ContentHeaderBody idea
+ : base(messageNbr, (BasicContentHeaderProperties)contentHeader.Properties, data)
+ {
+ }
+
+ public override void ClearBodyImpl()
+ {
+ _data.Clear();
+ }
+
+ public override string ToBodyString()
+ {
+ CheckReadable();
+ try
+ {
+ return GetText();
+ }
+ catch (IOException e)
+ {
+ throw new QpidException(e.ToString());
+ }
+ }
+
+ private String GetText()
+ {
+ // 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
+ {
+ byte[] data = new byte[_data.Remaining];
+ _data.GetBytes(data);
+ return Encoding.UTF8.GetString(data);
+ }
+ }
+
+ public long BodyLength
+ {
+ get
+ {
+ CheckReadable();
+ return _data.Limit;
+ }
+ }
+
+ private void CheckWritable()
+ {
+ if (_readableMessage)
+ {
+ throw new MessageNotWriteableException("You need to call clearBody() to make the message writable");
+ }
+ }
+
+ public bool ReadBoolean()
+ {
+ CheckReadable();
+ CheckAvailable(1);
+ return _data.GetByte() != 0;
+ }
+
+ public byte ReadByte()
+ {
+ CheckReadable();
+ CheckAvailable(1);
+ return _data.GetByte();
+ }
+
+ public short ReadSignedByte()
+ {
+ CheckReadable();
+ CheckAvailable(1);
+ return _data.GetSByte();
+ }
+
+ public short ReadShort()
+ {
+ CheckReadable();
+ CheckAvailable(2);
+ return _data.GetInt16();
+ }
+
+ public char ReadChar()
+ {
+ CheckReadable();
+ CheckAvailable(2);
+ return _data.GetChar();
+ }
+
+ public int ReadInt()
+ {
+ CheckReadable();
+ CheckAvailable(4);
+ return _data.GetInt32();
+ }
+
+ public long ReadLong()
+ {
+ CheckReadable();
+ CheckAvailable(8);
+ return _data.GetInt64();
+ }
+
+ public float ReadFloat()
+ {
+ CheckReadable();
+ CheckAvailable(4);
+ return _data.GetFloat();
+ }
+
+ public double ReadDouble()
+ {
+ CheckReadable();
+ CheckAvailable(8);
+ return _data.GetDouble();
+ }
+
+ public string ReadUTF()
+ {
+ CheckReadable();
+ // we check only for one byte since theoretically the string could be only a
+ // single byte when using UTF-8 encoding
+ CheckAvailable(1);
+ try
+ {
+ byte[] data = new byte[_data.Remaining];
+ _data.GetBytes(data);
+ return Encoding.UTF8.GetString(data);
+ }
+ catch (IOException e)
+ {
+ throw new QpidException(e.ToString(), e);
+ }
+ }
+
+ public int ReadBytes(byte[] bytes)
+ {
+ if (bytes == null)
+ {
+ throw new ArgumentNullException("bytes");
+ }
+ CheckReadable();
+ int count = (_data.Remaining >= bytes.Length ? bytes.Length : _data.Remaining);
+ if (count == 0)
+ {
+ return -1;
+ }
+ else
+ {
+ _data.GetBytes(bytes, 0, count);
+ return count;
+ }
+ }
+
+ public int ReadBytes(byte[] bytes, int maxLength)
+ {
+ if (bytes == null)
+ {
+ throw new ArgumentNullException("bytes");
+ }
+ if (maxLength > bytes.Length)
+ {
+ throw new ArgumentOutOfRangeException("maxLength must be >= 0");
+ }
+ CheckReadable();
+ int count = (_data.Remaining >= maxLength ? maxLength : _data.Remaining);
+ if (count == 0)
+ {
+ return -1;
+ }
+ else
+ {
+ _data.GetBytes(bytes, 0, count);
+ return count;
+ }
+ }
+
+ public void WriteBoolean(bool b)
+ {
+ CheckWritable();
+ _data.Put(b ? (byte)1 : (byte)0);
+ }
+
+ public void WriteByte(byte b)
+ {
+ CheckWritable();
+ _data.Put(b);
+ }
+
+ public void WriteShort(short i)
+ {
+ CheckWritable();
+ _data.Put(i);
+ }
+
+ public void WriteChar(char c)
+ {
+ CheckWritable();
+ _data.Put(c);
+ }
+
+ public void WriteSignedByte(short value)
+ {
+ CheckWritable();
+ _data.Put(value);
+ }
+
+ public void WriteDouble(double value)
+ {
+ CheckWritable();
+ _data.Put(value);
+ }
+
+ public void WriteFloat(float value)
+ {
+ CheckWritable();
+ _data.Put(value);
+ }
+
+ public void WriteInt(int value)
+ {
+ CheckWritable();
+ _data.Put(value);
+ }
+
+ public void WriteLong(long value)
+ {
+ CheckWritable();
+ _data.Put(value);
+ }
+
+ public void WriteUTF(string value)
+ {
+ CheckWritable();
+ byte[] encodedData = Encoding.UTF8.GetBytes(value);
+ _data.Put(encodedData);
+ }
+
+ public void WriteBytes(byte[] bytes)
+ {
+ CheckWritable();
+ _data.Put(bytes);
+ }
+
+ public void WriteBytes(byte[] bytes, int offset, int length)
+ {
+ CheckWritable();
+ _data.Put(bytes, offset, length);
+ }
+
+ protected override void Reset()
+ {
+ base.Reset();
+ _data.Flip();
+ }
+
+ void IBytesMessage.Reset()
+ {
+ Reset();
+ }
+
+ /**
+ * Check that there is at least a certain number of bytes available to read
+ *
+ * @param len the number of bytes
+ * @throws MessageEOFException if there are less than len bytes available to read
+ */
+ private void CheckAvailable(int len)
+ {
+ if (_data.Remaining < len)
+ {
+ throw new MessageEOFException("Unable to read " + len + " bytes");
+ }
+ }
+ }
+}
diff --git a/qpid/dotnet/Qpid.Client/Client/Message/QpidBytesMessageFactory.cs b/qpid/dotnet/Qpid.Client/Client/Message/QpidBytesMessageFactory.cs
new file mode 100644
index 0000000000..3cc96cbddc
--- /dev/null
+++ b/qpid/dotnet/Qpid.Client/Client/Message/QpidBytesMessageFactory.cs
@@ -0,0 +1,75 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+using System;
+using System.Collections;
+using Apache.Qpid.Framing;
+using Apache.Qpid.Buffer;
+
+namespace Apache.Qpid.Client.Message
+{
+ public class QpidBytesMessageFactory : AbstractQmsMessageFactory
+ {
+ //protected override AbstractQmsMessage CreateMessageWithBody(long messageNbr,
+ // ContentHeaderBody contentHeader,
+ // IList bodies)
+ //{
+ // byte[] data;
+
+ // // we optimise the non-fragmented case to avoid copying
+ // if (bodies != null && bodies.Count == 1)
+ // {
+ // data = ((ContentBody)bodies[0]).Payload;
+ // }
+ // else
+ // {
+ // data = new byte[(long)contentHeader.BodySize];
+ // int currentPosition = 0;
+ // foreach (ContentBody cb in bodies)
+ // {
+ // Array.Copy(cb.Payload, 0, data, currentPosition, cb.Payload.Length);
+ // currentPosition += cb.Payload.Length;
+ // }
+ // }
+
+ // return new QpidBytesMessage(messageNbr, data, contentHeader);
+ //}
+
+ //public override AbstractQmsMessage CreateMessage()
+ //{
+ // return new QpidBytesMessage();
+ //}
+
+ protected override AbstractQmsMessage CreateMessage(long deliveryTag, ByteBuffer data, ContentHeaderBody contentHeader)
+ {
+ return new QpidBytesMessage(deliveryTag, contentHeader, data);
+ }
+
+ public override AbstractQmsMessage CreateMessage(string mimeType)
+ {
+ QpidBytesMessage msg = new QpidBytesMessage();
+ msg.ContentType = mimeType;
+ return msg;
+ }
+
+ }
+}
+
+
diff --git a/qpid/dotnet/Qpid.Client/Client/Message/QpidHeaders.cs b/qpid/dotnet/Qpid.Client/Client/Message/QpidHeaders.cs
new file mode 100644
index 0000000000..9ad1c26867
--- /dev/null
+++ b/qpid/dotnet/Qpid.Client/Client/Message/QpidHeaders.cs
@@ -0,0 +1,233 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+using System;
+using System.Collections;
+using System.Text;
+using Apache.Qpid.Framing;
+using Apache.Qpid.Messaging;
+
+namespace Apache.Qpid.Client.Message
+{
+ internal class QpidHeaders : IHeaders
+ {
+ private FieldTable _headers;
+
+ public QpidHeaders(FieldTable headers)
+ {
+ if ( headers == null )
+ throw new ArgumentNullException("headers");
+ _headers = headers;
+ }
+
+ public bool Contains(string name)
+ {
+ CheckPropertyName(name);
+ return _headers.Contains(name);
+ }
+
+ public void Clear()
+ {
+ _headers.Clear();
+ }
+
+ public object this[string name]
+ {
+ get { return GetObject(name); }
+ set { SetObject(name, value); }
+ }
+
+ public bool GetBoolean(string name)
+ {
+ CheckPropertyName(name);
+ if ( Contains(name) )
+ return _headers.GetBoolean(name);
+ return false;
+ }
+
+ public void SetBoolean(string name, bool b)
+ {
+ CheckPropertyName(name);
+ _headers.SetBoolean(name, b);
+ }
+
+ public byte GetByte(string propertyName)
+ {
+ CheckPropertyName(propertyName);
+ if ( Contains(propertyName) )
+ return _headers.GetByte(propertyName);
+ return 0;
+ }
+
+ public void SetByte(string propertyName, byte b)
+ {
+ CheckPropertyName(propertyName);
+ _headers.SetByte(propertyName, b);
+ }
+
+ // we have sbyte overloads to interoperate with java
+ // because the Java client/server uses signed bytes
+ // by default, while C#'s is unsigned
+ public sbyte GetSByte(string propertyName)
+ {
+ CheckPropertyName(propertyName);
+ if ( Contains(propertyName) )
+ return _headers.GetSByte(propertyName);
+ return 0;
+ }
+
+ public void SetSByte(string propertyName, sbyte b)
+ {
+ CheckPropertyName(propertyName);
+ _headers.SetSByte(propertyName, b);
+ }
+
+ public short GetShort(string propertyName)
+ {
+ CheckPropertyName(propertyName);
+ if ( Contains(propertyName) )
+ return _headers.GetInt16(propertyName);
+ return 0;
+ }
+
+ public void SetShort(string propertyName, short i)
+ {
+ CheckPropertyName(propertyName);
+ _headers.SetInt16(propertyName, i);
+ }
+
+ public int GetInt(string propertyName)
+ {
+ CheckPropertyName(propertyName);
+ if ( Contains(propertyName) )
+ return _headers.GetInt32(propertyName);
+ return 0;
+ }
+
+ public void SetInt(string propertyName, int i)
+ {
+ CheckPropertyName(propertyName);
+ _headers.SetInt32(propertyName, i);
+ }
+
+ public long GetLong(string propertyName)
+ {
+ CheckPropertyName(propertyName);
+ if ( Contains(propertyName) )
+ return _headers.GetInt64(propertyName);
+ return 0;
+ }
+
+ public void SetLong(string propertyName, long l)
+ {
+ CheckPropertyName(propertyName);
+ _headers.SetInt64(propertyName, l);
+ }
+
+ public float GetFloat(String propertyName)
+ {
+ CheckPropertyName(propertyName);
+ if ( Contains(propertyName) )
+ return _headers.GetFloat(propertyName);
+ return 0f;
+ }
+
+ public void SetFloat(string propertyName, float f)
+ {
+ CheckPropertyName(propertyName);
+ _headers.SetFloat(propertyName, f);
+ }
+
+ public double GetDouble(string propertyName)
+ {
+ CheckPropertyName(propertyName);
+ if ( Contains(propertyName) )
+ return _headers.GetDouble(propertyName);
+ return 0;
+ }
+
+ public void SetDouble(string propertyName, double v)
+ {
+ CheckPropertyName(propertyName);
+ _headers.SetDouble(propertyName, v);
+ }
+
+ public string GetString(string propertyName)
+ {
+ CheckPropertyName(propertyName);
+ return _headers.GetString(propertyName);
+ }
+
+ public void SetString(string propertyName, string value)
+ {
+ CheckPropertyName(propertyName);
+ _headers.SetString(propertyName, value);
+ }
+
+ public object GetObject(string propertyName)
+ {
+ CheckPropertyName(propertyName);
+ return _headers[propertyName];
+ }
+
+ public void SetObject(string propertyName, object value)
+ {
+ CheckPropertyName(propertyName);
+ _headers[propertyName] = value;
+ }
+
+ private static void CheckPropertyName(string propertyName)
+ {
+ if ( propertyName == null )
+ {
+ throw new ArgumentException("Property name must not be null");
+ } else if ( "".Equals(propertyName) )
+ {
+ throw new ArgumentException("Property name must not be the empty string");
+ }
+ }
+
+ public override string ToString()
+ {
+ StringBuilder buf = new StringBuilder("{");
+ int i = 0;
+ foreach ( DictionaryEntry entry in _headers )
+ {
+ ++i;
+ if ( i > 1 )
+ {
+ buf.Append(", ");
+ }
+ string propertyName = (string)entry.Key;
+ if ( propertyName == null )
+ {
+ buf.Append("\nInternal error: Property with NULL key defined");
+ } else
+ {
+ buf.Append(propertyName);
+ buf.Append(" = ").Append(entry.Value);
+ }
+ }
+ buf.Append("}");
+ return buf.ToString();
+ }
+
+ }
+}
diff --git a/qpid/dotnet/Qpid.Client/Client/Message/QpidTextMessage.cs b/qpid/dotnet/Qpid.Client/Client/Message/QpidTextMessage.cs
new file mode 100644
index 0000000000..24aef92aa5
--- /dev/null
+++ b/qpid/dotnet/Qpid.Client/Client/Message/QpidTextMessage.cs
@@ -0,0 +1,115 @@
+/*
+ *
+ * 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.
+ *
+ */
+using System;
+using System.Text;
+using Apache.Qpid.Framing;
+using Apache.Qpid.Messaging;
+using Apache.Qpid.Buffer;
+
+namespace Apache.Qpid.Client.Message
+{
+ public class QpidTextMessage : AbstractQmsMessage, ITextMessage
+ {
+ private string _decodedValue = null;
+ private static Encoding DEFAULT_ENCODING = Encoding.UTF8;
+
+ internal QpidTextMessage() : this(null, null)
+ {
+ ContentEncoding = DEFAULT_ENCODING.BodyName;
+ }
+
+ internal QpidTextMessage(ByteBuffer data, String encoding) : base(data)
+ {
+ ContentEncoding = encoding;
+ }
+
+ internal QpidTextMessage(long deliveryTag, BasicContentHeaderProperties contentHeader, ByteBuffer data)
+ :base(deliveryTag, contentHeader, data)
+ {
+ }
+
+ public override void ClearBodyImpl()
+ {
+ if (_data != null)
+ {
+ _data.Release();
+ }
+ _data = null;
+ _decodedValue = null;
+ }
+
+ public override string ToBodyString()
+ {
+ return Text;
+ }
+
+ public string Text
+ {
+ get
+ {
+ if (_data == null && _decodedValue == null)
+ {
+ return null;
+ }
+ else if (_decodedValue != null)
+ {
+ return _decodedValue;
+ }
+ else
+ {
+ _data.Rewind();
+
+ // Read remaining bytes.
+ byte[] bytes = new byte[_data.Remaining];
+ _data.GetBytes(bytes);
+
+ // Convert to string based on encoding.
+ if (ContentHeaderProperties.Encoding != null)
+ {
+ // throw ArgumentException if the encoding is not supported
+ _decodedValue = Encoding.GetEncoding(ContentHeaderProperties.Encoding).GetString(bytes);
+ }
+ else
+ {
+ _decodedValue = DEFAULT_ENCODING.GetString(bytes);
+ }
+ return _decodedValue;
+ }
+ }
+
+ set
+ {
+ byte[] bytes;
+ if (ContentHeaderProperties.Encoding == null)
+ {
+ bytes = Encoding.Default.GetBytes(value);
+ }
+ else
+ {
+ // throw ArgumentException if the encoding is not supported
+ bytes = Encoding.GetEncoding(ContentHeaderProperties.Encoding).GetBytes(value);
+ }
+ _data = ByteBuffer.Wrap(bytes);
+ _decodedValue = value;
+ }
+ }
+ }
+}
diff --git a/qpid/dotnet/Qpid.Client/Client/Message/QpidTextMessageFactory.cs b/qpid/dotnet/Qpid.Client/Client/Message/QpidTextMessageFactory.cs
new file mode 100644
index 0000000000..79871e85ca
--- /dev/null
+++ b/qpid/dotnet/Qpid.Client/Client/Message/QpidTextMessageFactory.cs
@@ -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.
+ *
+ */
+using Apache.Qpid.Buffer;
+using Apache.Qpid.Framing;
+
+namespace Apache.Qpid.Client.Message
+{
+ public class QpidTextMessageFactory : AbstractQmsMessageFactory
+ {
+ public override AbstractQmsMessage CreateMessage(string mimeType)
+ {
+ QpidTextMessage msg = new QpidTextMessage();
+ msg.ContentType = mimeType;
+ return msg;
+ }
+
+ protected override AbstractQmsMessage CreateMessage(long deliveryTag, ByteBuffer data, ContentHeaderBody contentHeader)
+ {
+ return new QpidTextMessage(deliveryTag, (BasicContentHeaderProperties) contentHeader.Properties, data);
+ }
+ }
+}
diff --git a/qpid/dotnet/Qpid.Client/Client/Message/UnexpectedBodyReceivedException.cs b/qpid/dotnet/Qpid.Client/Client/Message/UnexpectedBodyReceivedException.cs
new file mode 100644
index 0000000000..4317ef3474
--- /dev/null
+++ b/qpid/dotnet/Qpid.Client/Client/Message/UnexpectedBodyReceivedException.cs
@@ -0,0 +1,57 @@
+/*
+ *
+ * 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.
+ *
+ */
+using System;
+using System.Runtime.Serialization;
+using log4net;
+
+namespace Apache.Qpid.Client.Message
+{
+ /// <summary>
+ /// Raised when a message body is received unexpectedly by the client. This typically occurs when the
+ /// length of bodies received does not match with the declared length in the content header.
+ /// </summary>
+ [Serializable]
+ public class UnexpectedBodyReceivedException : AMQException
+ {
+ public UnexpectedBodyReceivedException(ILog logger, string msg, Exception t)
+ : base(logger, msg, t)
+ {
+ }
+
+ public UnexpectedBodyReceivedException(ILog logger, string msg)
+ : base(logger, msg)
+ {
+ }
+
+ public UnexpectedBodyReceivedException(ILog logger, int errorCode, string msg)
+ : base(logger, errorCode, msg)
+ {
+ }
+
+ protected UnexpectedBodyReceivedException(SerializationInfo info, StreamingContext ctxt)
+ : base(info, ctxt)
+ {
+ }
+ }
+}
+
+
+
diff --git a/qpid/dotnet/Qpid.Client/Client/Message/UnprocessedMessage.cs b/qpid/dotnet/Qpid.Client/Client/Message/UnprocessedMessage.cs
new file mode 100644
index 0000000000..d329712334
--- /dev/null
+++ b/qpid/dotnet/Qpid.Client/Client/Message/UnprocessedMessage.cs
@@ -0,0 +1,57 @@
+/*
+ *
+ * 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.
+ *
+ */
+using System.Collections;
+using Apache.Qpid.Framing;
+
+namespace Apache.Qpid.Client.Message
+{
+ public class UnprocessedMessage
+ {
+ private ulong _bytesReceived = 0;
+
+ public BasicDeliverBody DeliverBody;
+ public BasicReturnBody BounceBody;
+ public ushort ChannelId;
+ public ContentHeaderBody ContentHeader;
+
+ /// <summary>
+ /// List of ContentBody instances. Due to fragmentation you don't know how big this will be in general
+ /// </summary>
+ /// TODO: write and use linked list class
+ public IList Bodies = new ArrayList();
+
+ public void ReceiveBody(ContentBody body)
+ {
+ Bodies.Add(body);
+ if (body.Payload != null)
+ {
+ _bytesReceived += (uint)body.Payload.Remaining;
+ }
+ }
+
+ public bool IsAllBodyDataReceived()
+ {
+ return _bytesReceived == ContentHeader.BodySize;
+ }
+ }
+}
+
+
diff --git a/qpid/dotnet/Qpid.Client/Client/Protocol/AMQMethodEvent.cs b/qpid/dotnet/Qpid.Client/Client/Protocol/AMQMethodEvent.cs
new file mode 100644
index 0000000000..a7ce808862
--- /dev/null
+++ b/qpid/dotnet/Qpid.Client/Client/Protocol/AMQMethodEvent.cs
@@ -0,0 +1,76 @@
+/*
+ *
+ * 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.
+ *
+ */
+using System;
+using System.Text;
+using Apache.Qpid.Framing;
+
+namespace Apache.Qpid.Client.Protocol
+{
+ public class AMQMethodEvent
+ {
+ private AMQMethodBody _method;
+
+ private ushort _channelId;
+
+ private AMQProtocolSession _protocolSession;
+
+ public AMQMethodEvent(ushort channelId, AMQMethodBody method, AMQProtocolSession protocolSession)
+ {
+ _channelId = channelId;
+ _method = method;
+ _protocolSession = protocolSession;
+ }
+
+ public AMQMethodBody Method
+ {
+ get
+ {
+ return _method;
+ }
+ }
+
+ public ushort ChannelId
+ {
+ get
+ {
+ return _channelId;
+ }
+ }
+
+ public AMQProtocolSession ProtocolSession
+ {
+ get
+ {
+ return _protocolSession;
+ }
+ }
+
+ public override String ToString()
+ {
+ StringBuilder buf = new StringBuilder("Method event: ");
+ buf.Append("\nChannel id: ").Append(_channelId);
+ buf.Append("\nMethod: ").Append(_method);
+ return buf.ToString();
+ }
+ }
+}
+
+
diff --git a/qpid/dotnet/Qpid.Client/Client/Protocol/AMQProtocolListener.cs b/qpid/dotnet/Qpid.Client/Client/Protocol/AMQProtocolListener.cs
new file mode 100644
index 0000000000..c51538b70e
--- /dev/null
+++ b/qpid/dotnet/Qpid.Client/Client/Protocol/AMQProtocolListener.cs
@@ -0,0 +1,318 @@
+/*
+ *
+ * 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.
+ *
+ */
+using System;
+using System.Collections;
+using System.Threading;
+using log4net;
+using Apache.Qpid.Client.Failover;
+using Apache.Qpid.Client.Protocol.Listener;
+using Apache.Qpid.Client.State;
+using Apache.Qpid.Framing;
+
+namespace Apache.Qpid.Client.Protocol
+{
+ /// <summary>
+ /// AMQProtocolListener
+ ///
+ /// <p/>Fail-over state transition rules...
+ ///
+ /// <p/>The failover handler is created when the session is created since it needs a reference to the IoSession in order
+ /// to be able to send errors during failover back to the client application. The session won't be available in the case
+ /// when failing over due to a Connection.Redirect message from the broker.
+ ///
+ /// <p><table id="crc"><caption>CRC Card</caption>
+ /// <tr><th> Responsibilities <th> Collaborations
+ /// <tr><td> Track fail over state of a connection.
+ /// <tr><td> Manage method listeners. <td> IAMQMethodListener
+ /// <tr><td> Receive notification of all IO errors on a connection. <td> IoHandler
+ /// <tr><td> Inform method listeners of all method events on a connection. <td> IAMQMethodListener
+ /// <tr><td> Inform method listeners of all error events on a connection. <td> IAMQMethodListener
+ /// </table>
+ ///
+ /// <b>Todo:</b> The broker will close the connection with no warning if authentication fails. This may result in the fail-over process being
+ /// triggered, when it should not be.
+ ///
+ /// </summary>
+ public class AMQProtocolListener : IProtocolListener
+ {
+ /// <summary>Used for debugging.</summary>
+ private static readonly ILog _log = LogManager.GetLogger(typeof(AMQProtocolListener));
+
+ /// <summary>
+ /// Holds the failover handler for the connection. When a failure is detected, and the current failover state allows it,
+ /// the failover process is handed off to this handler.
+ /// </summary>
+ private FailoverHandler _failoverHandler;
+
+ /// <summary>Tracks the current fail-over state.</summary>
+ internal FailoverState _failoverState = FailoverState.NOT_STARTED;
+
+ internal FailoverState FailoverState
+ {
+ get { return _failoverState; }
+ set { _failoverState = value; }
+ }
+
+ internal ManualResetEvent FailoverLatch;
+
+ AMQConnection _connection;
+ AMQStateManager _stateManager;
+
+ public AMQStateManager StateManager
+ {
+ get { return _stateManager; }
+ set { _stateManager = value; }
+ }
+
+ private readonly ArrayList _frameListeners = ArrayList.Synchronized(new ArrayList());
+
+ AMQProtocolSession _protocolSession = null;
+
+ private readonly Object _lock = new Object();
+
+ public AMQProtocolSession ProtocolSession { set { _protocolSession = value; } }
+
+ public AMQProtocolListener(AMQConnection connection, AMQStateManager stateManager)
+ {
+ _connection = connection;
+ _stateManager = stateManager;
+ _failoverHandler = new FailoverHandler(connection);
+ }
+
+ public void OnMessage(IDataBlock message)
+ {
+ // Handle incorrect protocol version.
+ if (message is ProtocolInitiation)
+ {
+ string error = String.Format("Protocol mismatch - {0}", message.ToString());
+ AMQException e = new AMQProtocolHeaderException(error);
+ _log.Error("Closing connection because of protocol mismatch", e);
+ //_protocolSession.CloseProtocolSession();
+ _stateManager.Error(e);
+ return;
+ }
+
+ AMQFrame frame = (AMQFrame)message;
+
+ if (frame.BodyFrame is AMQMethodBody)
+ {
+ if (_log.IsDebugEnabled)
+ {
+ _log.Debug("Method frame received: " + frame);
+ }
+ AMQMethodEvent evt = new AMQMethodEvent(frame.Channel, (AMQMethodBody)frame.BodyFrame, _protocolSession);
+ try
+ {
+ bool wasAnyoneInterested = false;
+ lock (_frameListeners.SyncRoot)
+ {
+ foreach (IAMQMethodListener listener in _frameListeners)
+ {
+ wasAnyoneInterested = listener.MethodReceived(evt) || wasAnyoneInterested;
+ }
+ }
+ if (!wasAnyoneInterested)
+ {
+ throw new AMQException("AMQMethodEvent " + evt + " was not processed by any listener.");
+ }
+ }
+ catch (Exception e)
+ {
+ foreach (IAMQMethodListener listener in _frameListeners)
+ {
+ listener.Error(e);
+ }
+ }
+ }
+ else if (frame.BodyFrame is ContentHeaderBody)
+ {
+ _protocolSession.MessageContentHeaderReceived(frame.Channel,
+ (ContentHeaderBody)frame.BodyFrame);
+ }
+ else if (frame.BodyFrame is ContentBody)
+ {
+ _protocolSession.MessageContentBodyReceived(frame.Channel,
+ (ContentBody)frame.BodyFrame);
+ }
+ else if (frame.BodyFrame is HeartbeatBody)
+ {
+ _log.Debug("HeartBeat received");
+ }
+ }
+
+ /// <summary>
+ /// Receives notification of any IO exceptions on the connection.
+ ///
+ /// <p/>Upon receipt of a connection closed exception or any IOException, the fail-over process is attempted. If the fail-over fails, then
+ /// all method listeners and the application connection object are notified of the connection failure exception.
+ ///
+ /// <p/>All other exception types are propagated to all method listeners.
+ /// </summary>
+ public void OnException(Exception cause)
+ {
+ _log.Warn("public void OnException(Exception cause = " + cause + "): called");
+
+ // Ensure that the method listener set cannot be changed whilst this exception is propagated to all listeners. This also
+ // ensures that this exception is fully propagated to all listeners, before another one can be processed.
+ lock (_lock)
+ {
+ if (cause is AMQConnectionClosedException || cause is System.IO.IOException)
+ {
+ // Try a fail-over because the connection has failed.
+ FailoverState failoverState = AttemptFailover();
+
+ // Check if the fail-over has failed, in which case notify all method listeners of the exception.
+ // The application connection object is also notified of the failure of the connection with the exception.
+ if (failoverState == FailoverState.FAILED)
+ {
+ _log.Debug("Fail-over has failed. Notifying all method listeners of the exception.");
+
+ AMQException amqe = new AMQException("Protocol handler error: " + cause, cause);
+ PropagateExceptionToWaiters(amqe);
+ _connection.ExceptionReceived(cause);
+ }
+ }
+ // Notify all method listeners of the exception.
+ else
+ {
+ PropagateExceptionToWaiters(cause);
+ _connection.ExceptionReceived(cause);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Tries to fail-over the connection, if the connection policy will permit it, and the fail-over process has not yet been
+ /// started. If the connection does not allow fail-over then an exception will be raised. If a fail-over is already in progress
+ /// this method allows it to continue to run and will do nothing.
+ ///
+ /// <p/>This method should only be called when the connection has been remotely closed.
+ /// </summary>
+ ///
+ /// <returns>The fail-over state at the end of this attempt.</returns>
+ private FailoverState AttemptFailover()
+ {
+ _log.Debug("private void AttemptFailover(): called");
+ _log.Debug("_failoverState = " + _failoverState);
+
+ // Ensure that the connection stops sending heart beats, if it still is.
+ _connection.StopHeartBeatThread();
+
+ // Check that the connection policy allows fail-over to be attempted.
+ if (!_connection.IsFailoverAllowed)
+ {
+ _log.Debug("Connection does not allowed to failover");
+ _connection.ExceptionReceived(
+ new AMQDisconnectedException("Broker closed connection and reconnection is not permitted."));
+ }
+
+ // Check if connection was closed deliberately by the application, in which case no fail-over is attempted.
+ if (_connection.Closed)
+ {
+ return _failoverState;
+ }
+
+ // If the connection allows fail-over and fail-over has not yet been started, then it is started and the fail-over state is
+ // advanced to 'in progress'
+ if (_failoverState == FailoverState.NOT_STARTED && _connection.IsFailoverAllowed)
+ {
+ _log.Info("Starting the fail-over process.");
+
+ _failoverState = FailoverState.IN_PROGRESS;
+ StartFailoverThread();
+ }
+
+ return _failoverState;
+ }
+
+ /// <summary>
+ /// There are two cases where we have other threads potentially blocking for events to be handled by this
+ /// class. These are for the state manager (waiting for a state change) or a frame listener (waiting for a
+ /// particular type of frame to arrive). When an error occurs we need to notify these waiters so that they can
+ /// react appropriately.
+ ///
+ /// <param name="e">the exception to propagate</param>
+ /// </summary>
+ public void PropagateExceptionToWaiters(Exception e)
+ {
+ // FIXME: not sure if required as StateManager is in _frameListeners. Probably something to do with fail-over.
+ _stateManager.Error(e);
+ lock ( _lock )
+ {
+ foreach ( IAMQMethodListener listener in _frameListeners )
+ {
+ listener.Error(e);
+ }
+ }
+ }
+
+ public void AddFrameListener(IAMQMethodListener listener)
+ {
+ lock ( _lock )
+ {
+ _frameListeners.Add(listener);
+ }
+ }
+
+ public void RemoveFrameListener(IAMQMethodListener listener)
+ {
+ if (_log.IsDebugEnabled)
+ {
+ _log.Debug("Removing frame listener: " + listener.ToString());
+ }
+ lock ( _lock )
+ {
+ _frameListeners.Remove(listener);
+ }
+ }
+
+ public void BlockUntilNotFailingOver()
+ {
+ if (FailoverLatch != null)
+ {
+ FailoverLatch.WaitOne();
+ }
+ }
+
+ /// <summary>
+ /// "Failover" for redirection.
+ /// </summary>
+ /// <param name="host"></param>
+ /// <param name="port"></param>
+ public void Failover(string host, int port)
+ {
+ _failoverHandler.setHost(host);
+ _failoverHandler.setPort(port);
+ // see javadoc for FailoverHandler to see rationale for separate thread
+ StartFailoverThread();
+ }
+
+ private void StartFailoverThread()
+ {
+ Thread failoverThread = new Thread(new ThreadStart(_failoverHandler.Run));
+ failoverThread.Name = "Failover";
+ // Do not inherit daemon-ness from current thread as this can be a daemon
+ // thread such as a AnonymousIoService thread.
+ failoverThread.IsBackground = false;
+ failoverThread.Start();
+ }
+ }
+}
diff --git a/qpid/dotnet/Qpid.Client/Client/Protocol/AMQProtocolSession.cs b/qpid/dotnet/Qpid.Client/Client/Protocol/AMQProtocolSession.cs
new file mode 100644
index 0000000000..1fb3d407eb
--- /dev/null
+++ b/qpid/dotnet/Qpid.Client/Client/Protocol/AMQProtocolSession.cs
@@ -0,0 +1,267 @@
+/*
+ *
+ * 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.
+ *
+ */
+using System;
+using System.Collections;
+using log4net;
+using Apache.Qpid.Client.Message;
+using Apache.Qpid.Client.Transport;
+using Apache.Qpid.Framing;
+using Apache.Qpid.Sasl;
+
+namespace Apache.Qpid.Client.Protocol
+{
+ public class AMQProtocolSession
+ {
+ private static readonly ILog _logger = LogManager.GetLogger(typeof(AMQProtocolSession));
+
+ private readonly IProtocolWriter _protocolWriter;
+ private readonly IConnectionCloser _connectionCloser;
+
+ /// <summary>
+ /// Maps from the channel id to the AmqChannel that it represents.
+ /// </summary>
+ //private ConcurrentMap _channelId2SessionMap = new ConcurrentHashMap();
+ private Hashtable _channelId2SessionMap = Hashtable.Synchronized(new Hashtable());
+
+ //private ConcurrentMap _closingChannels = new ConcurrentHashMap();
+ private Hashtable _closingChannels = Hashtable.Synchronized(new Hashtable());
+
+ /// <summary>
+ /// Maps from a channel id to an unprocessed message. This is used to tie together the
+ /// JmsDeliverBody (which arrives first) with the subsequent content header and content bodies.
+ /// </summary>
+ //private ConcurrentMap _channelId2UnprocessedMsgMap = new ConcurrentHashMap();
+ private Hashtable _channelId2UnprocessedMsgMap = Hashtable.Synchronized(new Hashtable());
+
+ private AMQConnection _connection;
+
+ public string ClientID { get { return _connection.ClientID; } }
+
+ public AMQProtocolSession(IProtocolWriter protocolWriter, IConnectionCloser connectionCloser, AMQConnection connection)
+ {
+ _protocolWriter = protocolWriter;
+ _connectionCloser = connectionCloser;
+ _connection = connection;
+ }
+
+ public void Init()
+ {
+ // start the process of setting up the connection. This is the first place that
+ // data is written to the server.
+ _protocolWriter.Write(new ProtocolInitiation());
+ }
+
+ public string Username
+ {
+ get
+ {
+ return AMQConnection.Username;
+ }
+ }
+
+ public string Password
+ {
+ get
+ {
+ return AMQConnection.Password;
+ }
+ }
+
+ ConnectionTuneParameters _connectionTuneParameters; // TODO: should be able to have this in the Java too.
+
+ public ConnectionTuneParameters ConnectionTuneParameters
+ {
+ get
+ {
+ return _connectionTuneParameters;
+ }
+ set
+ {
+ _connectionTuneParameters = value;
+ AMQConnection con = AMQConnection;
+ con.SetMaximumChannelCount(value.ChannelMax);
+ con.MaximumFrameSize = value.FrameMax;
+ }
+ }
+
+ private ISaslClient _saslClient;
+ public ISaslClient SaslClient
+ {
+ get { return _saslClient; }
+ set { _saslClient = value; }
+ }
+
+ /// <summary>
+ /// Callback invoked from the BasicDeliverMethodHandler when a message has been received.
+ /// This is invoked on the MINA dispatcher thread.
+ /// </summary>
+ /// <param name="message">the unprocessed message</param>
+ /// <exception cname="AMQException">if this was not expected</exception>
+ public void UnprocessedMessageReceived(UnprocessedMessage message)
+ {
+ _channelId2UnprocessedMsgMap[message.ChannelId] = message;
+ }
+
+ public void MessageContentHeaderReceived(ushort channelId, ContentHeaderBody contentHeader)
+ {
+ UnprocessedMessage msg = (UnprocessedMessage) _channelId2UnprocessedMsgMap[channelId];
+ if (msg == null)
+ {
+ throw new AMQException("Error: received content header without having received a JMSDeliver frame first");
+ }
+ if (msg.ContentHeader != null)
+ {
+ throw new AMQException("Error: received duplicate content header or did not receive correct number of content body frames");
+ }
+ msg.ContentHeader = contentHeader;
+ if (contentHeader.BodySize == 0)
+ {
+ DeliverMessageToAMQSession(channelId, msg);
+ }
+ }
+
+ public void MessageContentBodyReceived(ushort channelId, ContentBody contentBody)
+ {
+ UnprocessedMessage msg = (UnprocessedMessage) _channelId2UnprocessedMsgMap[channelId];
+ if (msg == null)
+ {
+ throw new AMQException("Error: received content body without having received a BasicDeliver frame first");
+ }
+ if (msg.ContentHeader == null)
+ {
+ _channelId2UnprocessedMsgMap.Remove(channelId);
+ throw new AMQException("Error: received content body without having received a ContentHeader frame first");
+ }
+ try
+ {
+ msg.ReceiveBody(contentBody);
+ }
+ catch (UnexpectedBodyReceivedException e)
+ {
+ _channelId2UnprocessedMsgMap.Remove(channelId);
+ throw e;
+ }
+ if (msg.IsAllBodyDataReceived())
+ {
+ DeliverMessageToAMQSession(channelId, msg);
+ }
+ }
+
+ /// <summary>
+ /// Deliver a message to the appropriate session, removing the unprocessed message
+ /// from our map
+ /// <param name="channelId">the channel id the message should be delivered to</param>
+ /// <param name="msg"> the message</param>
+ private void DeliverMessageToAMQSession(ushort channelId, UnprocessedMessage msg)
+ {
+ AmqChannel channel = (AmqChannel) _channelId2SessionMap[channelId];
+ channel.MessageReceived(msg);
+ _channelId2UnprocessedMsgMap.Remove(channelId);
+ }
+
+ /// <summary>
+ /// Convenience method that writes a frame to the protocol session. Equivalent
+ /// to calling getProtocolSession().write().
+ /// </summary>
+ /// <param name="frame">the frame to write</param>
+ public void WriteFrame(IDataBlock frame)
+ {
+ _protocolWriter.Write(frame);
+ }
+
+ public void AddSessionByChannel(ushort channelId, AmqChannel channel)
+ {
+ if (channel == null)
+ {
+ throw new ArgumentNullException("Attempt to register a null channel");
+ }
+ _logger.Debug("Add channel with channel id " + channelId);
+ _channelId2SessionMap[channelId] = channel;
+ }
+
+ public void RemoveSessionByChannel(ushort channelId)
+ {
+ _logger.Debug("Removing session with channelId " + channelId);
+ _channelId2SessionMap.Remove(channelId);
+ }
+
+ /// <summary>
+ /// Starts the process of closing a channel
+ /// </summary>
+ /// <param name="channel" the AmqChannel being closed</param>
+ public void CloseSession(AmqChannel channel)
+ {
+ _logger.Debug("closeSession called on protocol channel for channel " + channel.ChannelId);
+ ushort channelId = channel.ChannelId;
+
+ // we need to know when a channel is closing so that we can respond
+ // with a channel.close frame when we receive any other type of frame
+ // on that channel
+ _closingChannels[channelId] = channel;
+
+ }
+
+ /// <summary>
+ /// Called from the ChannelClose handler when a channel close frame is received.
+ /// This method decides whether this is a response or an initiation. The latter
+ /// case causes the AmqChannel to be closed and an exception to be thrown if
+ /// appropriate.
+ /// </summary>
+ /// <param name="channelId">the id of the channel (session)</param>
+ /// <returns>true if the client must respond to the server, i.e. if the server
+ /// initiated the channel close, false if the channel close is just the server
+ /// responding to the client's earlier request to close the channel.</returns>
+ public bool ChannelClosed(ushort channelId, int code, string text)
+ {
+ // if this is not a response to an earlier request to close the channel
+ if (!_closingChannels.ContainsKey(channelId))
+ {
+ _closingChannels.Remove(channelId);
+ AmqChannel channel = (AmqChannel) _channelId2SessionMap[channelId];
+ channel.ClosedWithException(new AMQException(_logger, code, text));
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ public AMQConnection AMQConnection
+ {
+ get
+ {
+ return _connection;
+ }
+ }
+
+ public void CloseProtocolSession()
+ {
+ _logger.Debug("Closing protocol session");
+ _connectionCloser.Close();
+ }
+
+ internal string GenerateQueueName()
+ {
+ return "ntmp_" + System.Guid.NewGuid();
+ }
+ }
+}
diff --git a/qpid/dotnet/Qpid.Client/Client/Protocol/DefaultTimeouts.cs b/qpid/dotnet/Qpid.Client/Client/Protocol/DefaultTimeouts.cs
new file mode 100644
index 0000000000..2f23a1571d
--- /dev/null
+++ b/qpid/dotnet/Qpid.Client/Client/Protocol/DefaultTimeouts.cs
@@ -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.
+ *
+ */
+
+using System;
+using System.Text;
+
+namespace Apache.Qpid.Client.Protocol
+{
+ /// <summary>
+ /// Default timeout values for the protocol
+ /// </summary>
+ sealed class DefaultTimeouts
+ {
+ /// <summary>
+ /// Maximum number of milliseconds to wait for a state change
+ /// in the protocol's state machine
+ /// </summary>
+ public const int MaxWaitForState = 30* 1000;
+ /// <summary>
+ /// Maximum number of milliseconds to wait for a reply
+ /// frame when doing synchronous writer to the broker
+ /// </summary>
+ public const int MaxWaitForSyncWriter = 30 * 1000;
+
+ private DefaultTimeouts()
+ {
+ }
+ }
+}
diff --git a/qpid/dotnet/Qpid.Client/Client/Protocol/IConnectionCloser.cs b/qpid/dotnet/Qpid.Client/Client/Protocol/IConnectionCloser.cs
new file mode 100644
index 0000000000..e3298200c4
--- /dev/null
+++ b/qpid/dotnet/Qpid.Client/Client/Protocol/IConnectionCloser.cs
@@ -0,0 +1,27 @@
+/*
+ *
+ * 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.
+ *
+ */
+namespace Apache.Qpid.Client.Protocol
+{
+ public interface IConnectionCloser
+ {
+ void Close();
+ }
+}
diff --git a/qpid/dotnet/Qpid.Client/Client/Protocol/IProtocolListener.cs b/qpid/dotnet/Qpid.Client/Client/Protocol/IProtocolListener.cs
new file mode 100644
index 0000000000..3b53f015f8
--- /dev/null
+++ b/qpid/dotnet/Qpid.Client/Client/Protocol/IProtocolListener.cs
@@ -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.
+ *
+ */
+using System;
+using Apache.Qpid.Client.Protocol.Listener;
+using Apache.Qpid.Framing;
+
+namespace Apache.Qpid.Client.Protocol
+{
+ public interface IProtocolListener
+ {
+ void OnMessage(IDataBlock message);
+ void OnException(Exception e);
+
+ // XXX: .NET way of doing listeners?
+ void AddFrameListener(IAMQMethodListener listener);
+ void RemoveFrameListener(IAMQMethodListener listener);
+ }
+}
diff --git a/qpid/dotnet/Qpid.Client/Client/Protocol/Listener/BlockingMethodFrameListener.cs b/qpid/dotnet/Qpid.Client/Client/Protocol/Listener/BlockingMethodFrameListener.cs
new file mode 100644
index 0000000000..9cc9f8cee5
--- /dev/null
+++ b/qpid/dotnet/Qpid.Client/Client/Protocol/Listener/BlockingMethodFrameListener.cs
@@ -0,0 +1,110 @@
+/*
+ *
+ * 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.
+ *
+ */
+using System;
+using System.Threading;
+using Apache.Qpid.Framing;
+
+namespace Apache.Qpid.Client.Protocol.Listener
+{
+ public abstract class BlockingMethodFrameListener : IAMQMethodListener
+ {
+ private ManualResetEvent _resetEvent;
+
+ public abstract bool ProcessMethod(ushort channelId, AMQMethodBody frame);
+
+ /// <summary>
+ /// This is set if there is an exception thrown from processCommandFrame and the
+ /// exception is rethrown to the caller of blockForFrame()
+ /// </summary>
+ private volatile Exception _error;
+
+ protected ushort _channelId;
+
+ protected AMQMethodEvent _doneEvt = null;
+
+ public BlockingMethodFrameListener(ushort channelId)
+ {
+ _channelId = channelId;
+ _resetEvent = new ManualResetEvent(false);
+ }
+
+ /// <summary>
+ /// This method is called by the MINA dispatching thread. Note that it could
+ /// be called before BlockForFrame() has been called.
+ /// </summary>
+ /// <param name="evt">the frame event</param>
+ /// <returns>true if the listener has dealt with this frame</returns>
+ /// <exception cref="AMQException"></exception>
+ public bool MethodReceived(AMQMethodEvent evt)
+ {
+ AMQMethodBody method = evt.Method;
+
+ try
+ {
+ bool ready = (evt.ChannelId == _channelId) && ProcessMethod(evt.ChannelId, method);
+ if (ready)
+ {
+ _doneEvt = evt;
+ _resetEvent.Set();
+ }
+
+ return ready;
+ }
+ catch (AMQException e)
+ {
+ Error(e);
+ // we rethrow the error here, and the code in the frame dispatcher will go round
+ // each listener informing them that an exception has been thrown
+ throw e;
+ }
+ }
+
+ /// <summary>
+ /// This method is called by the thread that wants to wait for a frame.
+ /// </summary>
+ /// <param name="timeout">Set the number of milliseconds to wait</param>
+ public AMQMethodEvent BlockForFrame(int timeout)
+ {
+ _resetEvent.WaitOne(timeout, true);
+ //at this point the event will have been signalled. The error field might or might not be set
+ // depending on whether an error occurred
+ if (_error != null)
+ {
+ throw _error;
+ }
+
+ return _doneEvt;
+ }
+
+ /// <summary>
+ /// This is a callback, called by the MINA dispatcher thread only. It is also called from within this
+ /// class to avoid code repetition but again is only called by the MINA dispatcher thread.
+ /// </summary>
+ /// <param name="e">the exception that caused the error</param>
+ public void Error(Exception e)
+ {
+ // set the error so that the thread that is blocking (in BlockForFrame())
+ // can pick up the exception and rethrow to the caller
+ _error = e;
+ _resetEvent.Set();
+ }
+ }
+}
diff --git a/qpid/dotnet/Qpid.Client/Client/Protocol/Listener/IAMQMethodListener.cs b/qpid/dotnet/Qpid.Client/Client/Protocol/Listener/IAMQMethodListener.cs
new file mode 100644
index 0000000000..b5450d00f7
--- /dev/null
+++ b/qpid/dotnet/Qpid.Client/Client/Protocol/Listener/IAMQMethodListener.cs
@@ -0,0 +1,46 @@
+/*
+ *
+ * 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.
+ *
+ */
+using System;
+
+namespace Apache.Qpid.Client.Protocol.Listener
+{
+ public interface IAMQMethodListener
+ {
+ /// <summary>
+ /// Invoked when a method frame has been received
+ /// <param name="evt">the event</param>
+ /// <returns>true if the handler has processed the method frame, false otherwise. Note
+ /// that this does not prohibit the method event being delivered to subsequent listeners
+ /// but can be used to determine if nobody has dealt with an incoming method frame.</param>
+ /// <exception cname="AMQException">if an error has occurred. This exception will be delivered
+ /// to all registered listeners using the error() method (see below) allowing them to
+ /// perform cleanup if necessary.</exception>
+ bool MethodReceived(AMQMethodEvent evt);
+
+ /// <summary>
+ /// Callback when an error has occurred. Allows listeners to clean up.
+ /// </summary>
+ /// <param name="e">the exception</param>
+ void Error(Exception e);
+ }
+}
+
+
diff --git a/qpid/dotnet/Qpid.Client/Client/Protocol/Listener/SpecificMethodFrameListener.cs b/qpid/dotnet/Qpid.Client/Client/Protocol/Listener/SpecificMethodFrameListener.cs
new file mode 100644
index 0000000000..8cdc1dbba9
--- /dev/null
+++ b/qpid/dotnet/Qpid.Client/Client/Protocol/Listener/SpecificMethodFrameListener.cs
@@ -0,0 +1,42 @@
+/*
+ *
+ * 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.
+ *
+ */
+using System;
+using Apache.Qpid.Framing;
+
+namespace Apache.Qpid.Client.Protocol.Listener
+{
+ public class SpecificMethodFrameListener : BlockingMethodFrameListener
+ {
+ private readonly Type _expectedClass;
+
+ public SpecificMethodFrameListener(ushort channelId, Type expectedClass) : base(channelId)
+ {
+ _expectedClass = expectedClass;
+ }
+
+ public override bool ProcessMethod(ushort channelId, AMQMethodBody frame)
+ {
+ return _expectedClass.IsInstanceOfType(frame);
+ }
+ }
+}
+
+
diff --git a/qpid/dotnet/Qpid.Client/Client/Protocol/ProtocolWriter.cs b/qpid/dotnet/Qpid.Client/Client/Protocol/ProtocolWriter.cs
new file mode 100644
index 0000000000..11918f1ea2
--- /dev/null
+++ b/qpid/dotnet/Qpid.Client/Client/Protocol/ProtocolWriter.cs
@@ -0,0 +1,107 @@
+/*
+ *
+ * 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.
+ *
+ */
+using System;
+using Apache.Qpid.Client.Protocol.Listener;
+using Apache.Qpid.Client.Transport;
+using Apache.Qpid.Framing;
+
+using log4net;
+
+namespace Apache.Qpid.Client.Protocol
+{
+ /// <summary>
+ /// A convenient interface to writing protocol frames.
+ /// </summary>
+ public class ProtocolWriter
+ {
+
+ private ILog _logger = LogManager.GetLogger(typeof(ProtocolWriter));
+
+ IProtocolWriter _protocolWriter;
+ IProtocolListener _protocolListener;
+
+ public ProtocolWriter(IProtocolWriter protocolWriter, IProtocolListener protocolListener)
+ {
+ _protocolWriter = protocolWriter;
+ _protocolListener = protocolListener;
+ }
+
+ public void WriteFrame(IDataBlock frame)
+ {
+ _protocolWriter.Write(frame);
+ }
+
+ /// <summary>
+ /// Convenience method that writes a frame to the protocol session and waits for
+ /// a particular response. Equivalent to calling getProtocolSession().write() then
+ /// waiting for the response.
+ /// </summary>
+ /// <param name="frame">the frame</param>
+ /// <param name="listener">the blocking listener. Note the calling thread will block.</param>
+ /// <param name="timeout">set the number of milliseconds to wait</param>
+ private AMQMethodEvent SyncWrite(AMQFrame frame, BlockingMethodFrameListener listener, int timeout)
+ {
+ try
+ {
+ _protocolListener.AddFrameListener(listener);
+ _protocolWriter.Write(frame);
+
+ return listener.BlockForFrame(timeout);
+ }
+ finally
+ {
+ _protocolListener.RemoveFrameListener(listener);
+ }
+ // When control resumes before this line, a reply will have been received
+ // that matches the criteria defined in the blocking listener
+ }
+
+ /// <summary>
+ /// Convenience method that writes a frame to the protocol session and waits for
+ /// a particular response. Equivalent to calling getProtocolSession().write() then
+ /// waiting for the response.
+ /// </summary>
+ /// <param name="frame">the frame</param>
+ /// <param name="responseType">the type of method response</param>
+ public AMQMethodEvent SyncWrite(AMQFrame frame, Type responseType)
+ {
+ // TODO: If each frame knew it's response type, then the responseType argument would
+ // TODO: not be neccesary.
+ return SyncWrite(frame, responseType, DefaultTimeouts.MaxWaitForSyncWriter);
+ }
+
+ /// <summary>
+ /// Convenience method that writes a frame to the protocol session and waits for
+ /// a particular response. Equivalent to calling getProtocolSession().write() then
+ /// waiting for the response.
+ /// </summary>
+ /// <param name="frame">the frame</param>
+ /// <param name="responseType">the type of method response</param>
+ /// <param name="timeout">set the number of milliseconds to wait</param>
+ /// <returns>set the number of milliseconds to wait</returns>
+ public AMQMethodEvent SyncWrite(AMQFrame frame, Type responseType, int timeout)
+ {
+ return SyncWrite(frame, new SpecificMethodFrameListener(frame.Channel, responseType), timeout);
+ }
+ }
+}
+
+
diff --git a/qpid/dotnet/Qpid.Client/Client/QpidConnectionInfo.cs b/qpid/dotnet/Qpid.Client/Client/QpidConnectionInfo.cs
new file mode 100644
index 0000000000..ede8966f37
--- /dev/null
+++ b/qpid/dotnet/Qpid.Client/Client/QpidConnectionInfo.cs
@@ -0,0 +1,504 @@
+/*
+ *
+ * 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.
+ *
+ */
+using System;
+using System.Collections;
+using System.Net;
+using System.Text;
+using System.Text.RegularExpressions;
+using log4net;
+using Apache.Qpid.Client.Qms;
+
+namespace Apache.Qpid.Client
+{
+
+ public class URLHelper
+ {
+ public static char DEFAULT_OPTION_SEPERATOR = '&';
+ public static char ALTERNATIVE_OPTION_SEPARATOR = ',';
+ public static char BROKER_SEPARATOR = ';';
+
+ /// <summary>
+ ///
+ /// </summary>
+ /// <param name="optionMap"></param>
+ /// <param name="options"></param>
+ public static void parseOptions(IDictionary optionMap, string options)
+ {
+ //options looks like this
+ //brokerlist='tcp://host:port?option='value',option='value';vm://:3/virtualpath?option='value'',failover='method?option='value',option='value''
+
+ if (options == null || options.IndexOf('=') == -1)
+ {
+ return;
+ }
+
+ int optionIndex = options.IndexOf('=');
+
+ String option = options.Substring(0, optionIndex);
+
+ int length = options.Length;
+
+ int nestedQuotes = 0;
+
+ // to store index of final "'"
+ int valueIndex = optionIndex;
+
+ //Walk remainder of url.
+ while (nestedQuotes > 0 || valueIndex < length)
+ {
+ valueIndex++;
+
+ if (valueIndex >= length)
+ {
+ break;
+ }
+
+ if (options[valueIndex] == '\'')
+ {
+ if (valueIndex + 1 < options.Length)
+ {
+ if (options[valueIndex + 1] == DEFAULT_OPTION_SEPERATOR ||
+ options[valueIndex + 1] == ALTERNATIVE_OPTION_SEPARATOR ||
+ options[valueIndex + 1] == BROKER_SEPARATOR ||
+ options[valueIndex + 1] == '\'')
+ {
+ nestedQuotes--;
+ // System.out.println(
+ // options + "\n" + "-" + nestedQuotes + ":" + getPositionString(valueIndex - 2, 1));
+ if (nestedQuotes == 0)
+ {
+ //We've found the value of an option
+ break;
+ }
+ }
+ else
+ {
+ nestedQuotes++;
+ // System.out.println(
+ // options + "\n" + "+" + nestedQuotes + ":" + getPositionString(valueIndex - 2, 1));
+ }
+ }
+ else
+ {
+ // We are at the end of the string
+ // Check to see if we are corectly closing quotes
+ if (options[valueIndex] == '\'')
+ {
+ nestedQuotes--;
+ }
+
+ break;
+ }
+ }
+ }
+
+ if (nestedQuotes != 0 || valueIndex < (optionIndex + 2))
+ {
+ int sepIndex = 0;
+
+ //Try and identify illegal separator character
+ if (nestedQuotes > 1)
+ {
+ for (int i = 0; i < nestedQuotes; i++)
+ {
+ sepIndex = options.IndexOf('\'', sepIndex);
+ sepIndex++;
+ }
+ }
+
+ if (sepIndex >= options.Length || sepIndex == 0)
+ {
+ parseError(valueIndex, "Unterminated option", options);
+ }
+ else
+ {
+ parseError(sepIndex, "Unterminated option. Possible illegal option separator:'" +
+ options[sepIndex] + "'", options);
+ }
+ }
+
+ // optionIndex +2 to skip "='"
+ int sublen = valueIndex - (optionIndex + 2);
+ String value = options.Substring(optionIndex + 2, sublen);
+
+ optionMap.Add(option, value);
+
+ if (valueIndex < (options.Length - 1))
+ {
+ //Recurse to get remaining options
+ parseOptions(optionMap, options.Substring(valueIndex + 2));
+ }
+ }
+
+
+ public static void parseError(int index, String error, String url)
+ {
+ parseError(index, 1, error, url);
+ }
+
+ public static void parseError(int index, int length, String error, String url)
+ {
+ throw new UrlSyntaxException(url, error, index, length);
+ }
+
+ public static String printOptions(Hashtable options)
+ {
+ if (options.Count == 0)
+ {
+ return "";
+ }
+ else
+ {
+ StringBuilder sb = new StringBuilder();
+ sb.Append('?');
+ foreach (String key in options.Keys)
+ {
+ sb.AppendFormat("{0}='{1}'{2}", key, options[key], DEFAULT_OPTION_SEPERATOR);
+ }
+
+ sb.Remove(sb.Length - 1, 1);
+ return sb.ToString();
+ }
+ }
+
+ }
+
+ public class QpidConnectionUrl
+ {
+ internal static IConnectionInfo FromUrl(string fullURL)
+ {
+ //_url = fullURL;
+ IConnectionInfo connectionInfo = new QpidConnectionInfo();
+
+
+ // _options = new HashMap<String, String>();
+ // _brokers = new LinkedList();
+ // _failoverOptions = new HashMap<String, String>();
+
+ // Connection URL format
+ //amqp://[user:pass@][clientid]/virtualhost?brokerlist='tcp://host:port?option=\'value\',option=\'value\';vm://:3/virtualpath?option=\'value\'',failover='method?option=\'value\',option='value''"
+ // Options are of course optional except for requiring a single broker in the broker list.
+ try
+ {
+ Uri connection = new Uri(fullURL);
+
+ if (connection.Scheme == null || !(connection.Scheme.Equals(ConnectionUrlConstants.AMQ_PROTOCOL)))
+ {
+ throw new UrlSyntaxException(fullURL, "Not an AMQP URL");
+ }
+
+ if (connection.Host != null && connection.Host.Length > 0 && !connection.Host.Equals("default"))
+ {
+ connectionInfo.ClientName = connection.Host;
+ }
+
+ String userInfo = connection.UserInfo;
+ if (userInfo == null || userInfo.Length == 0)
+ {
+ URLHelper.parseError(ConnectionUrlConstants.AMQ_PROTOCOL.Length + 3,
+ "User information not found on url", fullURL);
+ }
+ else
+ {
+ parseUserInfo(userInfo, fullURL, connectionInfo);
+ }
+ String virtualHost = connection.AbsolutePath; // XXX: is AbsolutePath corrrect?
+
+ if (virtualHost != null && virtualHost.Length > 0)
+ {
+ connectionInfo.VirtualHost = virtualHost;
+ }
+ else
+ {
+ int authLength = connection.Authority.Length;
+ int start = ConnectionUrlConstants.AMQ_PROTOCOL.Length + 3;
+ int testIndex = start + authLength;
+ if (testIndex < fullURL.Length && fullURL[testIndex] == '?')
+ {
+ URLHelper.parseError(start, testIndex - start, "Virtual host found", fullURL);
+ }
+ else
+ {
+ URLHelper.parseError(-1, "Virtual host not specified", fullURL);
+ }
+
+ }
+
+ QpidConnectionInfo qci = (QpidConnectionInfo)connectionInfo;
+ string query = connection.Query;
+ if (query[0] == '?') query = query.Substring(1);
+ URLHelper.parseOptions(qci.GetOptions(), query);
+
+ processOptions(connectionInfo);
+
+ //Fragment is #string (not used)
+ //System.out.println(connection.getFragment());
+ return connectionInfo;
+ }
+ catch (UriFormatException uris)
+ {
+ throw uris;
+ // if (uris is UrlSyntaxException)
+ // {
+ // throw uris;
+ // }
+ //
+ // int slash = fullURL.IndexOf("\\");
+ //
+ // if (slash == -1)
+ // {
+ // URLHelper.parseError(uris.GetIndex(), uris.getReason(), uris.getInput());
+ // }
+ // else
+ // {
+ // if (slash != 0 && fullURL.charAt(slash - 1) == ':')
+ // {
+ // URLHelper.parseError(slash - 2, fullURL.indexOf('?') - slash + 2, "Virtual host looks like a windows path, forward slash not allowed in URL", fullURL);
+ // }
+ // else
+ // {
+ // URLHelper.parseError(slash, "Forward slash not allowed in URL", fullURL);
+ // }
+ // }
+ }
+ }
+
+ private static void parseUserInfo(String userinfo, string fullUrl, IConnectionInfo connectionInfo)
+ {
+ //user info = user:pass
+
+ int colonIndex = userinfo.IndexOf(':');
+
+ if (colonIndex == -1)
+ {
+ URLHelper.parseError(ConnectionUrlConstants.AMQ_PROTOCOL.Length + 3,
+ userinfo.Length, "Null password in user information not allowed.", fullUrl);
+ }
+ else
+ {
+ connectionInfo.Username = userinfo.Substring(0, colonIndex);
+ connectionInfo.Password = userinfo.Substring(colonIndex + 1);
+ }
+ }
+
+ private static void processOptions(IConnectionInfo connectionInfo)
+ {
+ string brokerlist = connectionInfo.GetOption(ConnectionUrlConstants.OPTIONS_BROKERLIST);
+ if (brokerlist != null)
+ {
+ //brokerlist tcp://host:port?option='value',option='value';vm://:3/virtualpath?option='value'
+ Regex splitter = new Regex("" + URLHelper.BROKER_SEPARATOR);
+
+ foreach (string broker in splitter.Split(brokerlist))
+ {
+ connectionInfo.AddBrokerInfo(new AmqBrokerInfo(broker));
+ }
+
+ connectionInfo.SetOption(ConnectionUrlConstants.OPTIONS_BROKERLIST, null);
+ // _options.remove(OPTIONS_BROKERLIST);
+ }
+
+ string failover = connectionInfo.GetOption(ConnectionUrlConstants.OPTIONS_FAILOVER);
+ if (failover != null)
+ {
+ // failover='method?option='value',option='value''
+
+ int methodIndex = failover.IndexOf('?');
+
+ if (methodIndex > -1)
+ {
+ connectionInfo.FailoverMethod = failover.Substring(0, methodIndex);
+ QpidConnectionInfo qpidConnectionInfo = (QpidConnectionInfo)connectionInfo;
+ URLHelper.parseOptions(qpidConnectionInfo.GetFailoverOptions(),
+ failover.Substring(methodIndex + 1));
+ }
+ else
+ {
+ connectionInfo.FailoverMethod = failover;
+ }
+
+ connectionInfo.SetOption(ConnectionUrlConstants.OPTIONS_FAILOVER, null);
+ // _options.remove(OPTIONS_FAILOVER);
+ }
+ }
+
+ internal static IConnectionInfo FromUri(Uri uri)
+ {
+ return null; // FIXME
+
+ }
+ }
+
+ public class QpidConnectionInfo : IConnectionInfo
+ {
+ const string DEFAULT_VHOST = "/";
+ string _username = "guest";
+ string _password = "guest";
+ string _virtualHost = DEFAULT_VHOST;
+
+ string _failoverMethod = null;
+ IDictionary _failoverOptions = new Hashtable();
+ IDictionary _options = new Hashtable();
+ IList _brokerInfos = new ArrayList(); // List<BrokerInfo>
+ string _clientName = String.Format("{0}{1:G}", Dns.GetHostName(), DateTime.Now.Ticks);
+
+ public IDictionary GetFailoverOptions()
+ {
+ return _failoverOptions;
+ }
+
+ public IDictionary GetOptions()
+ {
+ return _options;
+ }
+
+ public static IConnectionInfo FromUrl(String url)
+ {
+ return QpidConnectionUrl.FromUrl(url);
+ }
+
+ public string AsUrl()
+ {
+ StringBuilder sb = new StringBuilder();
+ sb.AppendFormat("{0}://", ConnectionUrlConstants.AMQ_PROTOCOL);
+
+ if (_username != null)
+ {
+ sb.Append(_username);
+ if (_password != null)
+ {
+ sb.AppendFormat(":{0}", _password);
+ }
+ sb.Append("@");
+ }
+
+ sb.Append(_clientName);
+ sb.Append(_virtualHost);
+ sb.Append(OptionsToString());
+
+ return sb.ToString();
+ }
+
+ private String OptionsToString()
+ {
+ StringBuilder sb = new StringBuilder();
+ sb.AppendFormat("?{0}='", ConnectionUrlConstants.OPTIONS_BROKERLIST);
+
+ foreach (IBrokerInfo broker in _brokerInfos)
+ {
+ sb.AppendFormat("{0};", broker);
+ }
+
+ sb.Remove(sb.Length - 1, 1);
+ sb.Append("'");
+
+ if (_failoverMethod != null)
+ {
+ sb.AppendFormat("{0}{1}='{2}{3}'", URLHelper.DEFAULT_OPTION_SEPERATOR,
+ ConnectionUrlConstants.OPTIONS_FAILOVER,
+ _failoverMethod,
+ URLHelper.printOptions((Hashtable)_failoverOptions));
+ }
+
+ return sb.ToString();
+ }
+
+
+ public string FailoverMethod
+ {
+ get { return _failoverMethod; }
+ set { _failoverMethod = value; }
+ }
+
+ public string GetFailoverOption(string key)
+ {
+ return (string)_failoverOptions[key];
+ }
+
+ public int BrokerCount
+ {
+ get { return _brokerInfos.Count; }
+ }
+
+ public IBrokerInfo GetBrokerInfo(int index)
+ {
+ return (IBrokerInfo)_brokerInfos[index];
+ }
+
+ public void AddBrokerInfo(IBrokerInfo brokerInfo)
+ {
+ if (!_brokerInfos.Contains(brokerInfo))
+ {
+ _brokerInfos.Add(brokerInfo);
+ }
+ }
+
+ public IList GetAllBrokerInfos()
+ {
+ return _brokerInfos;
+ }
+
+ public string ClientName
+ {
+ get { return _clientName; }
+ set { _clientName = value; }
+ }
+
+ public string Username
+ {
+ get { return _username; }
+ set { _username = value; }
+ }
+
+ public string Password
+ {
+ get { return _password; }
+ set { _password = value; }
+ }
+
+ public string VirtualHost
+ {
+ get { return _virtualHost; }
+ set {
+ _virtualHost = value;
+ if ( _virtualHost == null || _virtualHost.Length == 0 )
+ _virtualHost = DEFAULT_VHOST;
+ if ( _virtualHost[0] != '/' )
+ _virtualHost = '/' + _virtualHost;
+ }
+ }
+
+ public string GetOption(string key)
+ {
+ return (string)_options[key];
+ }
+
+ public void SetOption(string key, string value)
+ {
+ _options[key] = value;
+ }
+
+ public override string ToString()
+ {
+ return AsUrl();
+ }
+ }
+}
diff --git a/qpid/dotnet/Qpid.Client/Client/Security/CallbackHandlerRegistry.cs b/qpid/dotnet/Qpid.Client/Client/Security/CallbackHandlerRegistry.cs
new file mode 100644
index 0000000000..9ac0381850
--- /dev/null
+++ b/qpid/dotnet/Qpid.Client/Client/Security/CallbackHandlerRegistry.cs
@@ -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.
+ *
+ */
+
+using System;
+using System.Collections;
+using System.Configuration;
+using System.Text;
+using Apache.Qpid.Sasl;
+using Apache.Qpid.Sasl.Mechanisms;
+
+using Apache.Qpid.Client.Configuration;
+
+namespace Apache.Qpid.Client.Security
+{
+
+ /// <summary>
+ /// Helper class to map SASL mechanisms to our
+ /// internal ISaslCallbackHandler implementations.
+ /// </summary>
+ /// <remarks>
+ /// The set of configured callback handlers and their order
+ /// controls the selection of the SASL mechanism used for authentication.
+ /// <para>
+ /// You can either replace the default handler for CRAM-MD5 and PLAIN
+ /// authentication (the two default options) using the application
+ /// configuration file. Configuration is done by especifying the SASL
+ /// mechanism name (e.g PLAIN) and the type implementing the callback handler
+ /// used to provide any data required by the mechanism like username and password.
+ /// </para>
+ /// <para>
+ /// Callback handler types should implement the IAMQCallbackHandler interface.
+ /// </para>
+ /// <para>
+ /// New callbacks or authentication mechanisms can be configured like this:
+ /// </para>
+ /// <example><![CDATA[
+ /// <configuration>
+ /// <configSections>
+ /// <sectionGroup name="qpid.client">
+ /// <section name="authentication" type="Apache.Qpid.Client.Configuration.AuthenticationConfigurationSectionHandler, Apache.Qpid.Client"/>
+ /// </sectionGroup>
+ /// </configSections>
+ /// <qpid.client>
+ /// <authentication>
+ /// <add key="TEST" value="Apache.Qpid.Client.Tests.Security.TestCallbackHandler, Apache.Qpid.Client.Tests"/>
+ /// </authentication>
+ /// </qpid.client>
+ /// </configuration>
+ /// ]]></example>
+ /// </remarks>
+ public sealed class CallbackHandlerRegistry
+ {
+ private static CallbackHandlerRegistry _instance =
+ new CallbackHandlerRegistry();
+ private OrderedHashTable _mechanism2HandlerMap;
+ private string[] _mechanisms;
+
+ public static CallbackHandlerRegistry Instance
+ {
+ get { return _instance; }
+ }
+
+ public string[] Mechanisms
+ {
+ get { return _mechanisms; }
+ }
+
+ private CallbackHandlerRegistry()
+ {
+ _mechanism2HandlerMap = (OrderedHashTable)
+ ConfigurationSettings.GetConfig("qpid.client/authentication");
+
+ // configure default options if not available
+ if ( _mechanism2HandlerMap == null )
+ _mechanism2HandlerMap = new OrderedHashTable();
+
+ if ( !_mechanism2HandlerMap.Contains(ExternalSaslClient.Mechanism) )
+ _mechanism2HandlerMap.Add(ExternalSaslClient.Mechanism, typeof(UsernamePasswordCallbackHandler));
+ if ( !_mechanism2HandlerMap.Contains(CramMD5SaslClient.Mechanism) )
+ _mechanism2HandlerMap.Add(CramMD5SaslClient.Mechanism, typeof(UsernamePasswordCallbackHandler));
+ if ( !_mechanism2HandlerMap.Contains(CramMD5HexSaslClient.Mechanism) )
+ _mechanism2HandlerMap.Add(CramMD5HexSaslClient.Mechanism, typeof(UsernamePasswordCallbackHandler));
+ if ( !_mechanism2HandlerMap.Contains(PlainSaslClient.Mechanism) )
+ _mechanism2HandlerMap.Add(PlainSaslClient.Mechanism, typeof(UsernamePasswordCallbackHandler));
+
+ _mechanisms = new string[_mechanism2HandlerMap.Count];
+ _mechanism2HandlerMap.OrderedKeys.CopyTo(_mechanisms, 0);
+ }
+
+ public bool IsSupportedMechanism(string mechanism)
+ {
+ return _mechanism2HandlerMap.Contains(mechanism);
+ }
+
+ public string ChooseMechanism(string mechanisms)
+ {
+ IList mechs = mechanisms.Split(' ');
+ foreach ( string supportedMech in _mechanisms )
+ {
+ if ( mechs.Contains(supportedMech) )
+ return supportedMech;
+ }
+ return null;
+ }
+
+ public Type GetCallbackHandler(string mechanism)
+ {
+ return (Type)_mechanism2HandlerMap[mechanism];
+ }
+ }
+}
diff --git a/qpid/dotnet/Qpid.Client/Client/Security/IAMQCallbackHandler.cs b/qpid/dotnet/Qpid.Client/Client/Security/IAMQCallbackHandler.cs
new file mode 100644
index 0000000000..6ff45be04a
--- /dev/null
+++ b/qpid/dotnet/Qpid.Client/Client/Security/IAMQCallbackHandler.cs
@@ -0,0 +1,35 @@
+/*
+ *
+ * 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.
+ *
+ */
+using System;
+using System.Text;
+using Apache.Qpid.Client.Protocol;
+using Apache.Qpid.Sasl;
+
+namespace Apache.Qpid.Client.Security
+{
+ public interface IAMQCallbackHandler : ISaslCallbackHandler
+ {
+ void Initialize(AMQProtocolSession session);
+ }
+
+}
+
+
diff --git a/qpid/dotnet/Qpid.Client/Client/Security/UsernamePasswordCallbackHandler.cs b/qpid/dotnet/Qpid.Client/Client/Security/UsernamePasswordCallbackHandler.cs
new file mode 100644
index 0000000000..743ade77c9
--- /dev/null
+++ b/qpid/dotnet/Qpid.Client/Client/Security/UsernamePasswordCallbackHandler.cs
@@ -0,0 +1,56 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+using System;
+using System.Collections;
+using System.Text;
+using Apache.Qpid.Client.Protocol;
+using Apache.Qpid.Sasl;
+
+namespace Apache.Qpid.Client.Security
+{
+ internal class UsernamePasswordCallbackHandler : IAMQCallbackHandler
+ {
+ private AMQProtocolSession _session;
+
+ public void Initialize(AMQProtocolSession session)
+ {
+ if ( session == null )
+ throw new ArgumentNullException("session");
+
+ _session = session;
+ }
+
+ public void Handle(ISaslCallback[] callbacks)
+ {
+ foreach ( ISaslCallback cb in callbacks )
+ {
+ if ( cb is NameCallback )
+ {
+ ((NameCallback)cb).Text = _session.Username;
+ } else if ( cb is PasswordCallback )
+ {
+ ((PasswordCallback)cb).Text = _session.Password;
+ }
+ }
+ }
+ }
+}
diff --git a/qpid/dotnet/Qpid.Client/Client/SslOptions.cs b/qpid/dotnet/Qpid.Client/Client/SslOptions.cs
new file mode 100644
index 0000000000..4630121828
--- /dev/null
+++ b/qpid/dotnet/Qpid.Client/Client/SslOptions.cs
@@ -0,0 +1,81 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+using System;
+using System.Security.Cryptography.X509Certificates;
+
+namespace Apache.Qpid.Client
+{
+ /// <summary>
+ /// Configures SSL-related options to connect to an AMQP broker.
+ /// </summary>
+ /// <remarks>
+ /// If the server certificate is not trusted by the client,
+ /// connection will fail. However, you can set the
+ /// <see cref="IgnoreValidationErrors"/> property to true
+ /// to ignore any certificate verification errors for debugging purposes.
+ /// </remarks>
+ public class SslOptions
+ {
+ private X509Certificate _clientCertificate;
+ private bool _ignoreValidationErrors;
+
+ /// <summary>
+ /// Certificate to present to the broker to authenticate
+ /// this client connection
+ /// </summary>
+ public X509Certificate ClientCertificate
+ {
+ get { return _clientCertificate; }
+ }
+
+ /// <summary>
+ /// If true, the validity of the broker certificate
+ /// will not be verified on connection
+ /// </summary>
+ public bool IgnoreValidationErrors
+ {
+ get { return _ignoreValidationErrors; }
+ }
+
+ /// <summary>
+ /// Initialize a new instance with default values
+ /// (No client certificate, don't ignore validation errors)
+ /// </summary>
+ public SslOptions()
+ {
+ }
+
+ /// <summary>
+ /// Initialize a new instance
+ /// </summary>
+ /// <param name="clientCertificate">
+ /// Certificate to use to authenticate the client to the broker
+ /// </param>
+ /// <param name="ignoreValidationErrors">
+ /// If true, ignore any validation errors when validating the server certificate
+ /// </param>
+ public SslOptions(X509Certificate clientCertificate, bool ignoreValidationErrors)
+ {
+ _clientCertificate = clientCertificate;
+ _ignoreValidationErrors = ignoreValidationErrors;
+ }
+ }
+}
diff --git a/qpid/dotnet/Qpid.Client/Client/State/AMQState.cs b/qpid/dotnet/Qpid.Client/Client/State/AMQState.cs
new file mode 100644
index 0000000000..67f8427fb2
--- /dev/null
+++ b/qpid/dotnet/Qpid.Client/Client/State/AMQState.cs
@@ -0,0 +1,35 @@
+/*
+ *
+ * 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.
+ *
+ */
+namespace Apache.Qpid.Client.State
+{
+ public enum AMQState
+ {
+ CONNECTION_NOT_STARTED,
+ CONNECTION_NOT_TUNED,
+ CONNECTION_NOT_OPENED,
+ CONNECTION_OPEN,
+ CONNECTION_CLOSING,
+ CONNECTION_CLOSED,
+ ALL // all is a special state used in the state manager. It is not valid to be "in" the state "all".
+ }
+}
+
+
diff --git a/qpid/dotnet/Qpid.Client/Client/State/AMQStateChangedEvent.cs b/qpid/dotnet/Qpid.Client/Client/State/AMQStateChangedEvent.cs
new file mode 100644
index 0000000000..a464bbb6f5
--- /dev/null
+++ b/qpid/dotnet/Qpid.Client/Client/State/AMQStateChangedEvent.cs
@@ -0,0 +1,52 @@
+/*
+ *
+ * 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.
+ *
+ */
+namespace Apache.Qpid.Client.State
+{
+ public class AMQStateChangedEvent
+ {
+ private readonly AMQState _oldState;
+
+ private readonly AMQState _newState;
+
+ public AMQStateChangedEvent(AMQState oldState, AMQState newState)
+ {
+ _oldState = oldState;
+ _newState = newState;
+ }
+
+ public AMQState OldState
+ {
+ get
+ {
+ return _oldState;
+ }
+ }
+
+ public AMQState NewState
+ {
+ get
+ {
+ return _newState;
+ }
+ }
+
+ }
+}
diff --git a/qpid/dotnet/Qpid.Client/Client/State/AMQStateManager.cs b/qpid/dotnet/Qpid.Client/Client/State/AMQStateManager.cs
new file mode 100644
index 0000000000..881e01e697
--- /dev/null
+++ b/qpid/dotnet/Qpid.Client/Client/State/AMQStateManager.cs
@@ -0,0 +1,251 @@
+/*
+ *
+ * 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.
+ *
+ */
+using System;
+using System.Collections;
+using log4net;
+using Apache.Qpid.Client.Handler;
+using Apache.Qpid.Client.Protocol;
+using Apache.Qpid.Client.Protocol.Listener;
+using Apache.Qpid.Framing;
+
+namespace Apache.Qpid.Client.State
+{
+ public class AMQStateManager : IAMQMethodListener
+ {
+ private static readonly ILog _logger = LogManager.GetLogger(typeof(AMQStateManager));
+
+ const bool InfoLoggingHack = true;
+
+ /// <summary>
+ /// The current state
+ /// </summary>
+ private AMQState _currentState;
+
+ /// <summary>
+ /// Maps from an AMQState instance to a Map from Class to StateTransitionHandler.
+ /// The class must be a subclass of AMQFrame.
+ /// </summary>
+ private readonly IDictionary _state2HandlersMap;
+ private ArrayList _stateListeners;
+ private object _syncLock;
+
+ public AMQStateManager()
+ {
+ _syncLock = new object();
+ _state2HandlersMap = new Hashtable();
+ _stateListeners = ArrayList.Synchronized(new ArrayList(5));
+ _currentState = AMQState.CONNECTION_NOT_STARTED;
+ RegisterListeners();
+ }
+
+ private void RegisterListeners()
+ {
+ IStateAwareMethodListener connectionStart = new ConnectionStartMethodHandler();
+ IStateAwareMethodListener connectionClose = new ConnectionCloseMethodHandler();
+ IStateAwareMethodListener connectionCloseOk = new ConnectionCloseOkHandler();
+ IStateAwareMethodListener connectionTune = new ConnectionTuneMethodHandler();
+ IStateAwareMethodListener connectionSecure = new ConnectionSecureMethodHandler();
+ IStateAwareMethodListener connectionOpenOk = new ConnectionOpenOkMethodHandler();
+ IStateAwareMethodListener channelClose = new ChannelCloseMethodHandler();
+ IStateAwareMethodListener basicDeliver = new BasicDeliverMethodHandler();
+ IStateAwareMethodListener basicReturn = new BasicReturnMethodHandler();
+ IStateAwareMethodListener queueDeleteOk = new QueueDeleteOkMethodHandler();
+ IStateAwareMethodListener queuePurgeOk = new QueuePurgeOkMethodHandler();
+
+ // We need to register a map for the null (i.e. all state) handlers otherwise you get
+ // a stack overflow in the handler searching code when you present it with a frame for which
+ // no handlers are registered.
+ _state2HandlersMap[AMQState.ALL] = new Hashtable();
+
+ {
+ Hashtable notStarted = new Hashtable();
+ notStarted[typeof(ConnectionStartBody)] = connectionStart;
+ notStarted[typeof(ConnectionCloseBody)] = connectionClose;
+ _state2HandlersMap[AMQState.CONNECTION_NOT_STARTED] = notStarted;
+ }
+ {
+ Hashtable notTuned = new Hashtable();
+ notTuned[typeof(ConnectionTuneBody)] = connectionTune;
+ notTuned[typeof(ConnectionSecureBody)] = connectionSecure;
+ notTuned[typeof(ConnectionCloseBody)] = connectionClose;
+ _state2HandlersMap[AMQState.CONNECTION_NOT_TUNED] = notTuned;
+ }
+ {
+ Hashtable notOpened = new Hashtable();
+ notOpened[typeof(ConnectionOpenOkBody)] = connectionOpenOk;
+ notOpened[typeof(ConnectionCloseBody)] = connectionClose;
+ _state2HandlersMap[AMQState.CONNECTION_NOT_OPENED] = notOpened;
+ }
+ {
+ Hashtable open = new Hashtable();
+ open[typeof(ChannelCloseBody)] = channelClose;
+ open[typeof(ConnectionCloseBody)] = connectionClose;
+ open[typeof(BasicDeliverBody)] = basicDeliver;
+ open[typeof(BasicReturnBody)] = basicReturn;
+ open[typeof(QueueDeleteOkBody)] = queueDeleteOk;
+ open[typeof(QueuePurgeOkBody)] = queuePurgeOk;
+ _state2HandlersMap[AMQState.CONNECTION_OPEN] = open;
+ }
+ {
+ Hashtable closing = new Hashtable();
+ closing[typeof(ConnectionCloseOkBody)] = connectionCloseOk;
+ _state2HandlersMap[AMQState.CONNECTION_CLOSING] = closing;
+ }
+ }
+
+ public AMQState CurrentState
+ {
+ get
+ {
+ return _currentState;
+ }
+ }
+
+ /// <summary>
+ /// Changes the state.
+ /// </summary>
+ /// <param name="newState">The new state.</param>
+ /// <exception cref="AMQException">if there is an error changing state</exception>
+ public void ChangeState(AMQState newState)
+ {
+ if (InfoLoggingHack)
+ {
+ _logger.Debug("State changing to " + newState + " from old state " + _currentState);
+ }
+ _logger.Debug("State changing to " + newState + " from old state " + _currentState);
+ AMQState oldState = _currentState;
+ _currentState = newState;
+
+ lock ( _syncLock )
+ {
+ foreach ( IStateListener l in _stateListeners )
+ {
+ l.StateChanged(oldState, newState);
+ }
+ }
+ }
+
+ public void Error(Exception e)
+ {
+ _logger.Debug("State manager receive error notification: " + e);
+ lock ( _syncLock )
+ {
+ foreach ( IStateListener l in _stateListeners )
+ {
+ l.Error(e);
+ }
+ }
+ }
+
+ public bool MethodReceived(AMQMethodEvent evt)
+ {
+ _logger.Debug(String.Format("Finding method handler. currentState={0} type={1}", _currentState, evt.Method.GetType()));
+ IStateAwareMethodListener handler = FindStateTransitionHandler(_currentState, evt.Method);
+ if (handler != null)
+ {
+ handler.MethodReceived(this, evt);
+ return true;
+ }
+ return false;
+ }
+
+ /// <summary>
+ /// Finds the state transition handler.
+ /// </summary>
+ /// <param name="currentState">State of the current.</param>
+ /// <param name="frame">The frame.</param>
+ /// <returns></returns>
+ /// <exception cref="IllegalStateTransitionException">if the state transition if not allowed</exception>
+ private IStateAwareMethodListener FindStateTransitionHandler(AMQState currentState,
+ AMQMethodBody frame)
+ {
+ Type clazz = frame.GetType();
+ if (_logger.IsDebugEnabled)
+ {
+ _logger.Debug("Looking for state transition handler for frame " + clazz);
+ }
+ IDictionary classToHandlerMap = (IDictionary) _state2HandlersMap[currentState];
+
+ if (classToHandlerMap == null)
+ {
+ // if no specialised per state handler is registered look for a
+ // handler registered for "all" states
+ return FindStateTransitionHandler(AMQState.ALL, frame);
+ }
+ IStateAwareMethodListener handler = (IStateAwareMethodListener) classToHandlerMap[clazz];
+ if (handler == null)
+ {
+ if (currentState == AMQState.ALL)
+ {
+ _logger.Debug("No state transition handler defined for receiving frame " + frame);
+ return null;
+ }
+ else
+ {
+ // if no specialised per state handler is registered look for a
+ // handler registered for "all" states
+ return FindStateTransitionHandler(AMQState.ALL, frame);
+ }
+ }
+ else
+ {
+ return handler;
+ }
+ }
+
+ public void AddStateListener(IStateListener listener)
+ {
+ _logger.Debug("Adding state listener");
+ lock ( _syncLock )
+ {
+ _stateListeners.Add(listener);
+ }
+ }
+
+ public void RemoveStateListener(IStateListener listener)
+ {
+ lock ( _syncLock )
+ {
+ _stateListeners.Remove(listener);
+ }
+ }
+
+ public void AttainState(AMQState s)
+ {
+ if (_currentState != s)
+ {
+ StateWaiter sw = null;
+ try
+ {
+ _logger.Debug("Adding state wait to reach state " + s);
+ sw = new StateWaiter(s);
+ AddStateListener(sw);
+ sw.WaituntilStateHasChanged();
+ // at this point the state will have changed.
+ }
+ finally
+ {
+ RemoveStateListener(sw);
+ }
+ }
+ }
+ }
+}
diff --git a/qpid/dotnet/Qpid.Client/Client/State/IAMQStateListener.cs b/qpid/dotnet/Qpid.Client/Client/State/IAMQStateListener.cs
new file mode 100644
index 0000000000..31e4b5046d
--- /dev/null
+++ b/qpid/dotnet/Qpid.Client/Client/State/IAMQStateListener.cs
@@ -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.
+ *
+ */
+namespace Apache.Qpid.Client.State
+{
+ public interface IAMQStateListener
+ {
+ void StateChanged(AMQStateChangedEvent evt);
+ }
+}
+
+
diff --git a/qpid/dotnet/Qpid.Client/Client/State/IStateAwareMethodListener.cs b/qpid/dotnet/Qpid.Client/Client/State/IStateAwareMethodListener.cs
new file mode 100644
index 0000000000..0874f39665
--- /dev/null
+++ b/qpid/dotnet/Qpid.Client/Client/State/IStateAwareMethodListener.cs
@@ -0,0 +1,31 @@
+/*
+ *
+ * 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.
+ *
+ */
+using Apache.Qpid.Client.Protocol;
+
+namespace Apache.Qpid.Client.State
+{
+ public interface IStateAwareMethodListener
+ {
+ void MethodReceived(AMQStateManager stateManager, AMQMethodEvent evt);
+ }
+}
+
+
diff --git a/qpid/dotnet/Qpid.Client/Client/State/IStateListener.cs b/qpid/dotnet/Qpid.Client/Client/State/IStateListener.cs
new file mode 100644
index 0000000000..edd7382f93
--- /dev/null
+++ b/qpid/dotnet/Qpid.Client/Client/State/IStateListener.cs
@@ -0,0 +1,33 @@
+/*
+ *
+ * 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.
+ *
+ */
+using System;
+
+namespace Apache.Qpid.Client.State
+{
+ public interface IStateListener
+ {
+ void StateChanged(AMQState oldState, AMQState newState);
+
+ void Error(Exception e);
+ }
+}
+
+
diff --git a/qpid/dotnet/Qpid.Client/Client/State/IllegalStateTransitionException.cs b/qpid/dotnet/Qpid.Client/Client/State/IllegalStateTransitionException.cs
new file mode 100644
index 0000000000..81de622617
--- /dev/null
+++ b/qpid/dotnet/Qpid.Client/Client/State/IllegalStateTransitionException.cs
@@ -0,0 +1,74 @@
+/*
+ *
+ * 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.
+ *
+ */
+using System;
+using System.Runtime.Serialization;
+
+namespace Apache.Qpid.Client.State
+{
+ [Serializable]
+ public class IllegalStateTransitionException : AMQException
+ {
+ private AMQState _originalState;
+
+ private Type _frame;
+
+ public IllegalStateTransitionException(AMQState originalState, Type frame)
+ : base("No valid state transition defined for receiving frame " + frame +
+ " from state " + originalState)
+ {
+ _originalState = originalState;
+ _frame = frame;
+ }
+
+ protected IllegalStateTransitionException(SerializationInfo info, StreamingContext ctxt)
+ : base(info, ctxt)
+ {
+ _originalState = (AMQState)info.GetValue("OriginalState", typeof(AMQState));
+ _frame = (Type)info.GetValue("FrameType", typeof(Type));
+ }
+
+ public AMQState OriginalState
+ {
+ get
+ {
+ return _originalState;
+ }
+ }
+
+ public Type FrameType
+ {
+ get
+ {
+ return _frame;
+ }
+ }
+
+ public override void GetObjectData(SerializationInfo info, StreamingContext context)
+ {
+ base.GetObjectData(info, context);
+ info.AddValue("OriginalState", OriginalState);
+ info.AddValue("FrameType", FrameType);
+ }
+ }
+}
+
+
+
diff --git a/qpid/dotnet/Qpid.Client/Client/State/StateWaiter.cs b/qpid/dotnet/Qpid.Client/Client/State/StateWaiter.cs
new file mode 100644
index 0000000000..e739d0cb44
--- /dev/null
+++ b/qpid/dotnet/Qpid.Client/Client/State/StateWaiter.cs
@@ -0,0 +1,121 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+using System;
+using System.Threading;
+using Apache.Qpid.Client.Protocol;
+using log4net;
+
+namespace Apache.Qpid.Client.State
+{
+ public class StateWaiter : IStateListener
+ {
+ private static readonly ILog _logger = LogManager.GetLogger(typeof(StateWaiter));
+
+ private readonly AMQState _state;
+ private AMQState _newState;
+
+ private volatile bool _newStateAchieved;
+
+ private volatile Exception _exception;
+
+ private ManualResetEvent _resetEvent = new ManualResetEvent(false);
+
+ public StateWaiter(AMQState state)
+ {
+ _state = state;
+ }
+
+ public void StateChanged(AMQState oldState, AMQState newState)
+ {
+ _newState = newState;
+ if (_logger.IsDebugEnabled)
+ {
+ _logger.Debug("stateChanged called");
+ }
+ if (_state == newState)
+ {
+ _newStateAchieved = true;
+
+ if (_logger.IsDebugEnabled)
+ {
+ _logger.Debug("New state reached so notifying monitor");
+ }
+ _resetEvent.Set();
+ }
+ }
+
+ public void Error(Exception e)
+ {
+ if (_logger.IsDebugEnabled)
+ {
+ _logger.Debug("exceptionThrown called");
+ }
+
+ _exception = e;
+ _resetEvent.Set();
+ }
+
+ public void WaituntilStateHasChanged()
+ {
+ //
+ // The guard is required in case we are woken up by a spurious
+ // notify().
+ //
+
+ TimeSpan waitTime = TimeSpan.FromMilliseconds(DefaultTimeouts.MaxWaitForState);
+ DateTime waitUntilTime = DateTime.Now + waitTime;
+
+ while ( !_newStateAchieved
+ && _exception == null
+ && waitTime.TotalMilliseconds > 0 )
+ {
+ _logger.Debug("State not achieved so waiting...");
+ try
+ {
+ _resetEvent.WaitOne(waitTime, true);
+ }
+ finally
+ {
+ if (!_newStateAchieved)
+ {
+ waitTime = waitUntilTime - DateTime.Now;
+ }
+ }
+ }
+
+ if (_exception != null)
+ {
+ _logger.Debug("Throwable reached state waiter: " + _exception);
+ if (_exception is AMQException)
+ throw _exception;
+ else
+ throw new AMQException("Error: " + _exception, _exception);
+ }
+
+ if (!_newStateAchieved)
+ {
+ string error = string.Format("State not achieved within permitted time. Current state: {0}, desired state: {1}", _state, _newState);
+ _logger.Warn(error);
+ throw new AMQException(error);
+ }
+ }
+ }
+}
diff --git a/qpid/dotnet/Qpid.Client/Client/Transport/AMQProtocolProvider.cs b/qpid/dotnet/Qpid.Client/Client/Transport/AMQProtocolProvider.cs
new file mode 100644
index 0000000000..dd0bb404cb
--- /dev/null
+++ b/qpid/dotnet/Qpid.Client/Client/Transport/AMQProtocolProvider.cs
@@ -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.
+ *
+ */
+using Apache.Qpid.Codec;
+using Apache.Qpid.Codec.Demux;
+using Apache.Qpid.Framing;
+
+namespace Apache.Qpid.Client.Transport
+{
+ public class AMQProtocolProvider
+ {
+ private DemuxingProtocolCodecFactory _factory;
+
+ public AMQProtocolProvider()
+ {
+ _factory = new DemuxingProtocolCodecFactory();
+ _factory.Register(new AMQDataBlockEncoder());
+ _factory.Register(new AMQDataBlockDecoder());
+ _factory.Register(new ProtocolInitiation.Decoder());
+ }
+
+ public IProtocolCodecFactory CodecFactory
+ {
+ get
+ {
+ return _factory;
+ }
+ }
+ }
+}
diff --git a/qpid/dotnet/Qpid.Client/Client/Transport/AmqpChannel.cs b/qpid/dotnet/Qpid.Client/Client/Transport/AmqpChannel.cs
new file mode 100644
index 0000000000..1e217e755b
--- /dev/null
+++ b/qpid/dotnet/Qpid.Client/Client/Transport/AmqpChannel.cs
@@ -0,0 +1,111 @@
+/*
+ *
+ * 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.
+ *
+ */
+using System;
+using System.Collections;
+using log4net;
+using Apache.Qpid.Buffer;
+using Apache.Qpid.Codec;
+using Apache.Qpid.Codec.Support;
+using Apache.Qpid.Framing;
+
+namespace Apache.Qpid.Client.Transport
+{
+ public class AmqpChannel : IProtocolChannel
+ {
+ // Warning: don't use this log for regular logging.
+ static readonly ILog _protocolTraceLog = LogManager.GetLogger("TRACE.Qpid.Client.ProtocolChannel");
+
+ IByteChannel _byteChannel;
+ IProtocolEncoder _encoder;
+ IProtocolDecoder _decoder;
+ IProtocolDecoderOutput _decoderOutput;
+ private object _syncLock;
+
+ public AmqpChannel(IByteChannel byteChannel, IProtocolDecoderOutput decoderOutput)
+ {
+ _byteChannel = byteChannel;
+ _decoderOutput = decoderOutput;
+ _syncLock = new object();
+
+ AMQProtocolProvider protocolProvider = new AMQProtocolProvider();
+ IProtocolCodecFactory factory = protocolProvider.CodecFactory;
+ _encoder = factory.Encoder;
+ _decoder = factory.Decoder;
+ }
+
+ public void Read()
+ {
+ ByteBuffer buffer = _byteChannel.Read();
+ Decode(buffer);
+ }
+
+ public IAsyncResult BeginRead(AsyncCallback callback, object state)
+ {
+ return _byteChannel.BeginRead(callback, state);
+ }
+
+ public void EndRead(IAsyncResult result)
+ {
+ ByteBuffer buffer = _byteChannel.EndRead(result);
+ Decode(buffer);
+ }
+
+ public void Write(IDataBlock o)
+ {
+ // TODO: Refactor to decorator.
+ if (_protocolTraceLog.IsDebugEnabled)
+ {
+ _protocolTraceLog.Debug(String.Format("WRITE {0}", o));
+ }
+ // we should be doing an async write, but apparently
+ // the mentalis library doesn't queue async read/writes
+ // correctly and throws random IOException's. Stay sync for a while
+ //_byteChannel.BeginWrite(Encode(o), OnAsyncWriteDone, null);
+ _byteChannel.Write(Encode(o));
+ }
+
+ // not used for now
+ //private void OnAsyncWriteDone(IAsyncResult result)
+ //{
+ // _byteChannel.EndWrite(result);
+ //}
+
+ private void Decode(ByteBuffer buffer)
+ {
+ // make sure we don't try to decode more than
+ // one buffer at the same time
+ lock ( _syncLock )
+ {
+ _decoder.Decode(buffer, _decoderOutput);
+ }
+ }
+
+ private ByteBuffer Encode(object o)
+ {
+ SingleProtocolEncoderOutput output = new SingleProtocolEncoderOutput();
+ _encoder.Encode(o, output);
+ return output.buffer;
+ }
+
+ }
+}
+
+
diff --git a/qpid/dotnet/Qpid.Client/Client/Transport/IByteChannel.cs b/qpid/dotnet/Qpid.Client/Client/Transport/IByteChannel.cs
new file mode 100644
index 0000000000..35806f2a6e
--- /dev/null
+++ b/qpid/dotnet/Qpid.Client/Client/Transport/IByteChannel.cs
@@ -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.
+ *
+ */
+using System;
+using Apache.Qpid.Buffer;
+
+namespace Apache.Qpid.Client.Transport
+{
+ /// <summary>
+ /// Represents input/output channels that read
+ /// and write <see cref="ByteBuffer"/> instances
+ /// </summary>
+ public interface IByteChannel
+ {
+ /// <summary>
+ /// Read a <see cref="ByteBuffer"/> from the underlying
+ /// network stream and any configured filters
+ /// </summary>
+ /// <returns>A ByteBuffer, if available</returns>
+ ByteBuffer Read();
+ /// <summary>
+ /// Begin an asynchronous read operation
+ /// </summary>
+ /// <param name="callback">Callback method to call when read operation completes</param>
+ /// <param name="state">State object</param>
+ /// <returns>An <see cref="System.IAsyncResult"/> object</returns>
+ IAsyncResult BeginRead(AsyncCallback callback, object state);
+ /// <summary>
+ /// End an asynchronous read operation
+ /// </summary>
+ /// <param name="result">The <see cref="System.IAsyncResult"/> object returned from <see cref="BeginRead"/></param>
+ /// <returns>The <see cref="ByteBuffer"/> read</returns>
+ ByteBuffer EndRead(IAsyncResult result);
+ /// <summary>
+ /// Write a <see cref="ByteBuffer"/> to the underlying network
+ /// stream, going through any configured filters
+ /// </summary>
+ /// <param name="buffer"></param>
+ void Write(ByteBuffer buffer);
+ /// <summary>
+ /// Begin an asynchronous write operation
+ /// </summary>
+ /// <param name="buffer">Buffer to write</param>
+ /// <param name="callback">A callback to call when the operation completes</param>
+ /// <param name="state">State object</param>
+ /// <returns>An <see cref="System.IAsyncResult"/> object</returns>
+ IAsyncResult BeginWrite(ByteBuffer buffer, AsyncCallback callback, object state);
+ /// <summary>
+ /// End an asynchronous write operation
+ /// </summary>
+ /// <param name="result">The <see cref="System.IAsyncResult"/> object returned by <see cref="BeginWrite"/></param>
+ void EndWrite(IAsyncResult result);
+ }
+}
diff --git a/qpid/dotnet/Qpid.Client/Client/Transport/IProtocolChannel.cs b/qpid/dotnet/Qpid.Client/Client/Transport/IProtocolChannel.cs
new file mode 100644
index 0000000000..0b59ee8799
--- /dev/null
+++ b/qpid/dotnet/Qpid.Client/Client/Transport/IProtocolChannel.cs
@@ -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.
+ *
+ */
+using System;
+using System.Collections;
+
+namespace Apache.Qpid.Client.Transport
+{
+ public interface IProtocolChannel : IProtocolWriter
+ {
+ void Read();
+ IAsyncResult BeginRead(AsyncCallback callback, object state);
+ void EndRead(IAsyncResult result);
+ }
+}
diff --git a/qpid/dotnet/Qpid.Client/Client/Transport/IProtocolWriter.cs b/qpid/dotnet/Qpid.Client/Client/Transport/IProtocolWriter.cs
new file mode 100644
index 0000000000..592dff3a19
--- /dev/null
+++ b/qpid/dotnet/Qpid.Client/Client/Transport/IProtocolWriter.cs
@@ -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.
+ *
+ */
+using Apache.Qpid.Framing;
+
+namespace Apache.Qpid.Client.Transport
+{
+ public interface IProtocolWriter
+ {
+ void Write(IDataBlock o);
+ }
+}
diff --git a/qpid/dotnet/Qpid.Client/Client/Transport/IStreamFilter.cs b/qpid/dotnet/Qpid.Client/Client/Transport/IStreamFilter.cs
new file mode 100644
index 0000000000..e0e890fc5a
--- /dev/null
+++ b/qpid/dotnet/Qpid.Client/Client/Transport/IStreamFilter.cs
@@ -0,0 +1,38 @@
+/*
+ *
+ * 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.
+ *
+ */
+using System.IO;
+
+namespace Apache.Qpid.Client.Transport
+{
+ /// <summary>
+ /// Defines a way to introduce an arbitrary filtering
+ /// stream into the stream chain managed by <see cref="IoHandler"/>
+ /// </summary>
+ public interface IStreamFilter
+ {
+ /// <summary>
+ /// Creates a new filtering stream on top of another
+ /// </summary>
+ /// <param name="lowerStream">Next stream on the stack</param>
+ /// <returns>A new filtering stream</returns>
+ Stream CreateFilterStream(Stream lowerStream);
+ }
+}
diff --git a/qpid/dotnet/Qpid.Client/Client/Transport/ITransport.cs b/qpid/dotnet/Qpid.Client/Client/Transport/ITransport.cs
new file mode 100644
index 0000000000..693a9a9534
--- /dev/null
+++ b/qpid/dotnet/Qpid.Client/Client/Transport/ITransport.cs
@@ -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.
+ *
+ */
+using Apache.Qpid.Client.Qms;
+using Apache.Qpid.Client.Protocol;
+
+namespace Apache.Qpid.Client.Transport
+{
+ public interface ITransport : IConnectionCloser
+ {
+ void Connect(IBrokerInfo broker, AMQConnection connection);
+ string LocalEndpoint { get; }
+ IProtocolWriter ProtocolWriter { get; }
+ }
+}
diff --git a/qpid/dotnet/Qpid.Client/Client/Transport/IoHandler.cs b/qpid/dotnet/Qpid.Client/Client/Transport/IoHandler.cs
new file mode 100644
index 0000000000..0475236d92
--- /dev/null
+++ b/qpid/dotnet/Qpid.Client/Client/Transport/IoHandler.cs
@@ -0,0 +1,322 @@
+/*
+ *
+ * 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.
+ *
+ */
+using System;
+using System.IO;
+using System.Threading;
+using log4net;
+using Apache.Qpid.Buffer;
+using Apache.Qpid.Client.Protocol;
+
+namespace Apache.Qpid.Client.Transport
+{
+ /// <summary>
+ /// Responsible for reading and writing
+ /// ByteBuffers from/to network streams, and handling
+ /// the stream filters
+ /// </summary>
+ public class IoHandler : IByteChannel, IDisposable
+ {
+ private static readonly ILog _log = LogManager.GetLogger(typeof(IoHandler));
+ private const int DEFAULT_BUFFER_SIZE = 32 * 1024;
+
+ private Stream _topStream;
+ private IProtocolListener _protocolListener;
+ private int _readBufferSize;
+
+ public int ReadBufferSize
+ {
+ get { return _readBufferSize; }
+ set { _readBufferSize = value; }
+ }
+
+ /// <summary>
+ /// Initialize a new instance
+ /// </summary>
+ /// <param name="stream">Underlying network stream</param>
+ /// <param name="protocolListener">Protocol listener to report exceptions to</param>
+ public IoHandler(Stream stream, IProtocolListener protocolListener)
+ {
+ if ( stream == null )
+ throw new ArgumentNullException("stream");
+ if ( protocolListener == null )
+ throw new ArgumentNullException("protocolListener");
+
+ // initially, the stream at the top of the filter
+ // chain is the underlying network stream
+ _topStream = stream;
+ _protocolListener = protocolListener;
+ _readBufferSize = DEFAULT_BUFFER_SIZE;
+ }
+
+ /// <summary>
+ /// Adds a new filter on the top of the chain
+ /// </summary>
+ /// <param name="filter">Stream filter to put on top of the chain</param>
+ /// <remarks>
+ /// This should *only* be called during initialization. We don't
+ /// support changing the filter change after the first read/write
+ /// has been done and it's not thread-safe to boot!
+ /// </remarks>
+ public void AddFilter(IStreamFilter filter)
+ {
+ _topStream = filter.CreateFilterStream(_topStream);
+ }
+
+ #region IByteChannel Implementation
+ //
+ // IByteChannel Implementation
+ //
+
+ /// <summary>
+ /// Read a <see cref="ByteBuffer"/> from the underlying
+ /// network stream and any configured filters
+ /// </summary>
+ /// <returns>A ByteBuffer, if available</returns>
+ public ByteBuffer Read()
+ {
+ byte[] bytes = AllocateBuffer();
+
+ int numOctets = _topStream.Read(bytes, 0, bytes.Length);
+
+ return WrapByteArray(bytes, numOctets);
+ }
+
+ /// <summary>
+ /// Begin an asynchronous read operation
+ /// </summary>
+ /// <param name="callback">Callback method to call when read operation completes</param>
+ /// <param name="state">State object</param>
+ /// <returns>An <see cref="System.IAsyncResult"/> object</returns>
+ public IAsyncResult BeginRead(AsyncCallback callback, object state)
+ {
+ byte[] bytes = AllocateBuffer();
+ ReadData rd = new ReadData(callback, state, bytes);
+
+ // only put a callback if the caller wants one.
+ AsyncCallback myCallback = null;
+ if ( callback != null )
+ myCallback = new AsyncCallback(OnAsyncReadDone);
+
+ IAsyncResult result = _topStream.BeginRead(
+ bytes, 0, bytes.Length, myCallback,rd
+ );
+ return new WrappedAsyncResult(result, bytes);
+ }
+
+ /// <summary>
+ /// End an asynchronous read operation
+ /// </summary>
+ /// <param name="result">The <see cref="System.IAsyncResult"/> object returned from <see cref="BeginRead"/></param>
+ /// <returns>The <see cref="ByteBuffer"/> read</returns>
+ public ByteBuffer EndRead(IAsyncResult result)
+ {
+ WrappedAsyncResult theResult = (WrappedAsyncResult)result;
+ int bytesRead = _topStream.EndRead(theResult.InnerResult);
+ return WrapByteArray(theResult.Buffer, bytesRead);
+ }
+
+ /// <summary>
+ /// Write a <see cref="ByteBuffer"/> to the underlying network
+ /// stream, going through any configured filters
+ /// </summary>
+ /// <param name="buffer"></param>
+ public void Write(ByteBuffer buffer)
+ {
+ try
+ {
+ _topStream.Write(buffer.Array, buffer.Position, buffer.Limit); // FIXME
+ }
+ catch (Exception e)
+ {
+ _log.Warn("Write caused exception", e);
+ _protocolListener.OnException(e);
+ }
+ }
+
+ /// <summary>
+ /// Begin an asynchronous write operation
+ /// </summary>
+ /// <param name="buffer">Buffer to write</param>
+ /// <param name="callback">A callback to call when the operation completes</param>
+ /// <param name="state">State object</param>
+ /// <returns>An <see cref="System.IAsyncResult"/> object</returns>
+ public IAsyncResult BeginWrite(ByteBuffer buffer, AsyncCallback callback, object state)
+ {
+ try
+ {
+ return _topStream.BeginWrite(
+ buffer.Array, buffer.Position, buffer.Limit,
+ callback, state
+ );
+ } catch ( Exception e )
+ {
+ _log.Error("BeginWrite caused exception", e);
+ // not clear if an exception here should be propagated? we still
+ // need to propagate it upwards anyway!
+ _protocolListener.OnException(e);
+ throw;
+ }
+ }
+
+ /// <summary>
+ /// End an asynchronous write operation
+ /// </summary>
+ /// <param name="result">The <see cref="System.IAsyncResult"/> object returned by <see cref="BeginWrite"/></param>
+ public void EndWrite(IAsyncResult result)
+ {
+ try
+ {
+ _topStream.EndWrite(result);
+ } catch ( Exception e )
+ {
+ _log.Error("EndWrite caused exception", e);
+ // not clear if an exception here should be propagated?
+ _protocolListener.OnException(e);
+ //throw;
+ }
+ }
+ #endregion // IByteChannel Implementation
+
+ #region IDisposable Implementation
+ //
+ // IDisposable Implementation
+ //
+
+ public void Dispose()
+ {
+ if ( _topStream != null )
+ {
+ _topStream.Close();
+ }
+ }
+
+ #endregion // IDisposable Implementation
+
+ #region Private and Helper Classes/Methods
+ //
+ // Private and Helper Classes/Methods
+ //
+
+ private byte[] AllocateBuffer()
+ {
+ return new byte[ReadBufferSize];
+ }
+
+ private static ByteBuffer WrapByteArray(byte[] bytes, int size)
+ {
+ ByteBuffer byteBuffer = ByteBuffer.Wrap(bytes);
+ byteBuffer.Limit = size;
+ byteBuffer.Flip();
+
+ return byteBuffer;
+ }
+
+
+ private static void OnAsyncReadDone(IAsyncResult result)
+ {
+ ReadData rd = (ReadData) result.AsyncState;
+ IAsyncResult wrapped = new WrappedAsyncResult(result, rd.Buffer);
+ rd.Callback(wrapped);
+ }
+
+ class ReadData
+ {
+ private object _state;
+ private AsyncCallback _callback;
+ private byte[] _buffer;
+
+ public object State
+ {
+ get { return _state; }
+ }
+
+ public AsyncCallback Callback
+ {
+ get { return _callback; }
+ }
+
+ public byte[] Buffer
+ {
+ get { return _buffer; }
+ }
+
+ public ReadData(AsyncCallback callback, object state, byte[] buffer)
+ {
+ _callback = callback;
+ _state = state;
+ _buffer = buffer;
+ }
+ }
+
+ class WrappedAsyncResult : IAsyncResult
+ {
+ private IAsyncResult _innerResult;
+ private byte[] _buffer;
+
+ #region IAsyncResult Properties
+ //
+ // IAsyncResult Properties
+ //
+ public bool IsCompleted
+ {
+ get { return _innerResult.IsCompleted; }
+ }
+
+ public WaitHandle AsyncWaitHandle
+ {
+ get { return _innerResult.AsyncWaitHandle; }
+ }
+
+ public object AsyncState
+ {
+ get { return _innerResult.AsyncState; }
+ }
+
+ public bool CompletedSynchronously
+ {
+ get { return _innerResult.CompletedSynchronously; }
+ }
+ #endregion // IAsyncResult Properties
+
+ public IAsyncResult InnerResult
+ {
+ get { return _innerResult; }
+ }
+ public byte[] Buffer
+ {
+ get { return _buffer; }
+ }
+
+ public WrappedAsyncResult(IAsyncResult result, byte[] buffer)
+ {
+ if ( result == null )
+ throw new ArgumentNullException("result");
+ if ( buffer == null )
+ throw new ArgumentNullException("buffer");
+
+ _innerResult = result;
+ _buffer = buffer;
+ }
+ }
+
+ #endregion // Private and Helper Classes/Methods
+ }
+}
diff --git a/qpid/dotnet/Qpid.Client/Client/Transport/ProtocolDecoderOutput.cs b/qpid/dotnet/Qpid.Client/Client/Transport/ProtocolDecoderOutput.cs
new file mode 100644
index 0000000000..9fa313152f
--- /dev/null
+++ b/qpid/dotnet/Qpid.Client/Client/Transport/ProtocolDecoderOutput.cs
@@ -0,0 +1,60 @@
+/*
+ *
+ * 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.
+ *
+ */
+using System;
+using System.Threading;
+using Apache.Qpid.Client.Protocol;
+using Apache.Qpid.Codec;
+using Apache.Qpid.Framing;
+using log4net;
+
+namespace Apache.Qpid.Client.Transport
+{
+ /// <summary>
+ /// <see cref="IProtocolDecoderOutput"/> implementation that forwards
+ /// each <see cref="IDataBlock"/> as it is decoded to the
+ /// protocol listener
+ /// </summary>
+ internal class ProtocolDecoderOutput : IProtocolDecoderOutput
+ {
+ private IProtocolListener _protocolListener;
+ static readonly ILog _protocolTraceLog = LogManager.GetLogger("TRACE.Qpid.Client.ProtocolChannel");
+
+ public ProtocolDecoderOutput(IProtocolListener protocolListener)
+ {
+ if ( protocolListener == null )
+ throw new ArgumentNullException("protocolListener");
+
+ _protocolListener = protocolListener;
+ }
+
+ public void Write(object message)
+ {
+ IDataBlock block = message as IDataBlock;
+ if ( block != null )
+ {
+ _protocolTraceLog.Debug(String.Format("READ {0}", block));
+ _protocolListener.OnMessage(block);
+ }
+ }
+ }
+} // namespace Apache.Qpid.Client.Transport
+
+
diff --git a/qpid/dotnet/Qpid.Client/Client/Transport/SingleProtocolEncoderOutput.cs b/qpid/dotnet/Qpid.Client/Client/Transport/SingleProtocolEncoderOutput.cs
new file mode 100644
index 0000000000..a1aa889ba0
--- /dev/null
+++ b/qpid/dotnet/Qpid.Client/Client/Transport/SingleProtocolEncoderOutput.cs
@@ -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.
+ *
+ */
+using System;
+using Apache.Qpid.Buffer;
+using Apache.Qpid.Codec;
+
+namespace Apache.Qpid.Client.Transport
+{
+ public class SingleProtocolEncoderOutput : IProtocolEncoderOutput
+ {
+ public ByteBuffer buffer;
+
+ public void Write(ByteBuffer buf)
+ {
+ if (buffer != null)
+ {
+ throw new InvalidOperationException("{0} does not allow the writing of more than one buffer");
+ }
+ buffer = buf;
+ }
+ }
+}
diff --git a/qpid/dotnet/Qpid.Client/Client/Transport/Socket/Blocking/BlockingSocketTransport.cs b/qpid/dotnet/Qpid.Client/Client/Transport/Socket/Blocking/BlockingSocketTransport.cs
new file mode 100644
index 0000000000..f336d8a80a
--- /dev/null
+++ b/qpid/dotnet/Qpid.Client/Client/Transport/Socket/Blocking/BlockingSocketTransport.cs
@@ -0,0 +1,150 @@
+/*
+ *
+ * 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.
+ *
+ */
+using System;
+using System.Collections;
+using System.IO;
+using System.Threading;
+using Apache.Qpid.Client.Qms;
+using Apache.Qpid.Client.Protocol;
+using Apache.Qpid.Codec;
+using Apache.Qpid.Framing;
+
+namespace Apache.Qpid.Client.Transport.Socket.Blocking
+{
+ /// <summary>
+ /// TCP Socket transport supporting both
+ /// SSL and non-SSL connections.
+ /// </summary>
+ public class BlockingSocketTransport : ITransport
+ {
+ // Configuration variables.
+ IProtocolListener _protocolListener;
+
+ // Runtime variables.
+ private ISocketConnector _connector;
+ private IoHandler _ioHandler;
+ private AmqpChannel _amqpChannel;
+ private ManualResetEvent _stopEvent;
+
+ public IProtocolWriter ProtocolWriter
+ {
+ get { return _amqpChannel; }
+ }
+ public string LocalEndpoint
+ {
+ get { return _connector.LocalEndpoint; }
+ }
+
+
+ /// <summary>
+ /// Connect to the specified broker
+ /// </summary>
+ /// <param name="broker">The broker to connect to</param>
+ /// <param name="connection">The AMQ connection</param>
+ public void Connect(IBrokerInfo broker, AMQConnection connection)
+ {
+ _stopEvent = new ManualResetEvent(false);
+ _protocolListener = connection.ProtocolListener;
+
+ _ioHandler = MakeBrokerConnection(broker, connection);
+ // todo: get default read size from config!
+
+ IProtocolDecoderOutput decoderOutput =
+ new ProtocolDecoderOutput(_protocolListener);
+ _amqpChannel =
+ new AmqpChannel(new ByteChannel(_ioHandler), decoderOutput);
+
+ // post an initial async read
+ _amqpChannel.BeginRead(new AsyncCallback(OnAsyncReadDone), this);
+ }
+
+ /// <summary>
+ /// Close the broker connection
+ /// </summary>
+ public void Close()
+ {
+ StopReading();
+ CloseBrokerConnection();
+ }
+
+ private void StopReading()
+ {
+ _stopEvent.Set();
+ }
+
+ private void CloseBrokerConnection()
+ {
+ if ( _ioHandler != null )
+ {
+ _ioHandler.Dispose();
+ _ioHandler = null;
+ }
+ if ( _connector != null )
+ {
+ _connector.Dispose();
+ _connector = null;
+ }
+ }
+
+ private IoHandler MakeBrokerConnection(IBrokerInfo broker, AMQConnection connection)
+ {
+ if ( broker.UseSSL )
+ {
+ _connector = new SslSocketConnector();
+ } else
+ {
+ _connector = new SocketConnector();
+ }
+
+ Stream stream = _connector.Connect(broker);
+ return new IoHandler(stream, connection.ProtocolListener);
+ }
+
+ private void OnAsyncReadDone(IAsyncResult result)
+ {
+ try
+ {
+ _amqpChannel.EndRead(result);
+
+ bool stopping = _stopEvent.WaitOne(0, false);
+ if ( !stopping )
+ _amqpChannel.BeginRead(new AsyncCallback(OnAsyncReadDone), null);
+ } catch ( Exception e )
+ {
+ // ignore any errors during closing
+ bool stopping = _stopEvent.WaitOne(0, false);
+ if ( !stopping )
+ _protocolListener.OnException(e);
+ }
+ }
+
+ #region IProtocolDecoderOutput Members
+
+ public void Write(object message)
+ {
+ _protocolListener.OnMessage((IDataBlock)message);
+ }
+
+ #endregion
+ }
+}
+
+
diff --git a/qpid/dotnet/Qpid.Client/Client/Transport/Socket/Blocking/ByteChannel.cs b/qpid/dotnet/Qpid.Client/Client/Transport/Socket/Blocking/ByteChannel.cs
new file mode 100644
index 0000000000..4540f01f4e
--- /dev/null
+++ b/qpid/dotnet/Qpid.Client/Client/Transport/Socket/Blocking/ByteChannel.cs
@@ -0,0 +1,92 @@
+/*
+ *
+ * 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.
+ *
+ */
+using System;
+using log4net;
+using Apache.Qpid.Buffer;
+
+namespace Apache.Qpid.Client.Transport.Socket.Blocking
+{
+ class ByteChannel : IByteChannel
+ {
+ // Warning: don't use this log for regular logging.
+ private static readonly ILog _ioTraceLog = LogManager.GetLogger("TRACE.Qpid.Client.ByteChannel");
+
+ private IByteChannel _lowerChannel;
+
+ public ByteChannel(IByteChannel lowerChannel)
+ {
+ _lowerChannel = lowerChannel;
+ }
+
+ public ByteBuffer Read()
+ {
+ ByteBuffer result = _lowerChannel.Read();
+
+ // TODO: Move into decorator.
+ if (_ioTraceLog.IsDebugEnabled)
+ {
+ _ioTraceLog.Debug(String.Format("READ {0}", result));
+ }
+
+ return result;
+ }
+
+ public IAsyncResult BeginRead(AsyncCallback callback, object state)
+ {
+ return _lowerChannel.BeginRead(callback, state);
+ }
+
+ public ByteBuffer EndRead(IAsyncResult result)
+ {
+ ByteBuffer buffer = _lowerChannel.EndRead(result);
+ if ( _ioTraceLog.IsDebugEnabled )
+ {
+ _ioTraceLog.Debug(String.Format("READ {0}", buffer));
+ }
+ return buffer;
+ }
+
+ public void Write(ByteBuffer buffer)
+ {
+ // TODO: Move into decorator.
+ if (_ioTraceLog.IsDebugEnabled)
+ {
+ _ioTraceLog.Debug(String.Format("WRITE {0}", buffer));
+ }
+
+ _lowerChannel.Write(buffer);
+ }
+
+ public IAsyncResult BeginWrite(ByteBuffer buffer, AsyncCallback callback, object state)
+ {
+ if ( _ioTraceLog.IsDebugEnabled )
+ {
+ _ioTraceLog.Debug(String.Format("WRITE {0}", buffer));
+ }
+ return _lowerChannel.BeginWrite(buffer, callback, state);
+ }
+
+ public void EndWrite(IAsyncResult result)
+ {
+ _lowerChannel.EndWrite(result);
+ }
+ }
+}
diff --git a/qpid/dotnet/Qpid.Client/Client/Transport/Socket/Blocking/ISocketConnector.cs b/qpid/dotnet/Qpid.Client/Client/Transport/Socket/Blocking/ISocketConnector.cs
new file mode 100644
index 0000000000..137fa19c0d
--- /dev/null
+++ b/qpid/dotnet/Qpid.Client/Client/Transport/Socket/Blocking/ISocketConnector.cs
@@ -0,0 +1,34 @@
+/*
+ *
+ * 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.
+ *
+ */
+using System;
+using System.IO;
+using Apache.Qpid.Client.Qms;
+
+namespace Apache.Qpid.Client.Transport.Socket.Blocking
+{
+ interface ISocketConnector : IDisposable
+ {
+ string LocalEndpoint { get; }
+ Stream Connect(IBrokerInfo broker);
+ }
+}
+
+
diff --git a/qpid/dotnet/Qpid.Client/Client/Transport/Socket/Blocking/SocketConnector.cs b/qpid/dotnet/Qpid.Client/Client/Transport/Socket/Blocking/SocketConnector.cs
new file mode 100644
index 0000000000..b6dd8c3be1
--- /dev/null
+++ b/qpid/dotnet/Qpid.Client/Client/Transport/Socket/Blocking/SocketConnector.cs
@@ -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.
+ *
+ */
+using System.IO;
+using System.Net;
+using System.Net.Sockets;
+using Apache.Qpid.Client.Qms;
+
+namespace Apache.Qpid.Client.Transport.Socket.Blocking
+{
+ /// <summary>
+ /// Implements a TCP connection over regular sockets.
+ /// </summary>
+ class SocketConnector : ISocketConnector
+ {
+ private MyTcpClient _tcpClient;
+
+ public string LocalEndpoint
+ {
+ get { return _tcpClient.LocalEndpoint.ToString(); }
+ }
+
+ public Stream Connect(IBrokerInfo broker)
+ {
+ _tcpClient = new MyTcpClient(broker.Host, broker.Port);
+ return _tcpClient.GetStream();
+ }
+
+ public void Dispose()
+ {
+ if ( _tcpClient != null )
+ {
+ _tcpClient.Close();
+ _tcpClient = null;
+ }
+ }
+
+ class MyTcpClient : TcpClient
+ {
+ public MyTcpClient(string host, int port)
+ : base(host, port)
+ {
+ }
+
+ public EndPoint LocalEndpoint
+ {
+ get { return Client.LocalEndPoint; }
+ }
+ }
+
+ }
+}
+
+
diff --git a/qpid/dotnet/Qpid.Client/Client/Transport/Socket/Blocking/SslSocketConnector.cs b/qpid/dotnet/Qpid.Client/Client/Transport/Socket/Blocking/SslSocketConnector.cs
new file mode 100644
index 0000000000..8436e6fc4f
--- /dev/null
+++ b/qpid/dotnet/Qpid.Client/Client/Transport/Socket/Blocking/SslSocketConnector.cs
@@ -0,0 +1,107 @@
+/*
+ *
+ * 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.
+ *
+ */
+using System.IO;
+using System.Net;
+using log4net;
+using Apache.Qpid.Client.Qms;
+using Org.Mentalis.Security.Ssl;
+using MCertificate = Org.Mentalis.Security.Certificates.Certificate;
+using MCertificateChain = Org.Mentalis.Security.Certificates.CertificateChain;
+
+namespace Apache.Qpid.Client.Transport.Socket.Blocking
+{
+ /// <summary>
+ /// Implements a TLS v1.0 connection using the Mentalis.org library
+ /// </summary>
+ /// <remarks>
+ /// It would've been easier to implement this at the StreamFilter
+ /// level, but unfortunately the Mentalis library doesn't support
+ /// a passthrough SSL stream class and is tied directly
+ /// to socket-like classes.
+ /// </remarks>
+ class SslSocketConnector : ISocketConnector
+ {
+ private static ILog _logger = LogManager.GetLogger(typeof(SslSocketConnector));
+ private MyTcpClient _tcpClient;
+
+ public string LocalEndpoint
+ {
+ get { return _tcpClient.LocalEndpoint.ToString(); }
+ }
+
+ public Stream Connect(IBrokerInfo broker)
+ {
+ MCertificate cert = GetClientCert(broker);
+ SecurityOptions options = new SecurityOptions(
+ SecureProtocol.Tls1, cert, ConnectionEnd.Client
+ );
+ if ( broker.SslOptions != null
+ && broker.SslOptions.IgnoreValidationErrors )
+ {
+ _logger.Warn("Ignoring any certificate validation errors during SSL handshake...");
+ options.VerificationType = CredentialVerification.None;
+ }
+
+ _tcpClient = new MyTcpClient(broker.Host, broker.Port, options);
+ return _tcpClient.GetStream();
+ }
+
+ public void Dispose()
+ {
+ if ( _tcpClient != null )
+ {
+ _tcpClient.Close();
+ _tcpClient = null;
+ }
+ }
+
+ private static MCertificate GetClientCert(IBrokerInfo broker)
+ {
+ // if a client certificate is configured,
+ // use that to enable mutual authentication
+ MCertificate cert = null;
+ if ( broker.SslOptions != null
+ && broker.SslOptions.ClientCertificate != null )
+ {
+ cert = MCertificate.CreateFromX509Certificate(
+ broker.SslOptions.ClientCertificate
+ );
+ _logger.DebugFormat("Using Client Certificate for SSL '{0}'", cert.ToString(true));
+ }
+ return cert;
+ }
+
+ class MyTcpClient : SecureTcpClient
+ {
+ public MyTcpClient(string host, int port, SecurityOptions options)
+ : base(host, port, options)
+ {
+ }
+
+ public EndPoint LocalEndpoint
+ {
+ get { return Client.LocalEndPoint; }
+ }
+
+ }
+
+ }
+}
diff --git a/qpid/dotnet/Qpid.Client/Client/Util/FlowControlQueue.cs b/qpid/dotnet/Qpid.Client/Client/Util/FlowControlQueue.cs
new file mode 100644
index 0000000000..a06de9eac8
--- /dev/null
+++ b/qpid/dotnet/Qpid.Client/Client/Util/FlowControlQueue.cs
@@ -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.
+ *
+ */
+using System;
+using System.Collections;
+using System.Text;
+using System.Threading;
+using Apache.Qpid.Collections;
+using Apache.Qpid.Common;
+
+namespace Apache.Qpid.Client.Util
+{
+ internal delegate void ThresholdMethod(int currentCount);
+
+ /// <summary>
+ /// Basic bounded queue used to implement prefetching.
+ /// Notice we do the callbacks here asynchronously to
+ /// avoid adding more complexity to the channel impl.
+ /// </summary>
+ internal class FlowControlQueue
+ {
+ private BlockingQueue _queue = new LinkedBlockingQueue();
+ private int _itemCount;
+ private int _lowerBound;
+ private int _upperBound;
+ private ThresholdMethod _underThreshold;
+ private ThresholdMethod _overThreshold;
+
+ public FlowControlQueue(
+ int lowerBound,
+ int upperBound,
+ ThresholdMethod underThreshold,
+ ThresholdMethod overThreshold
+ )
+ {
+ _lowerBound = lowerBound;
+ _upperBound = upperBound;
+ _underThreshold = underThreshold;
+ _overThreshold = overThreshold;
+ }
+
+ public void Enqueue(object item)
+ {
+ _queue.EnqueueBlocking(item);
+ int count = Interlocked.Increment(ref _itemCount);
+ if ( _overThreshold != null )
+ {
+ if ( count == _upperBound )
+ {
+ _overThreshold.BeginInvoke(
+ count, new AsyncCallback(OnAsyncCallEnd),
+ _overThreshold
+ );
+ }
+ }
+ }
+
+ public object Dequeue()
+ {
+ object item = _queue.DequeueBlocking();
+ int count = Interlocked.Decrement(ref _itemCount);
+ if ( _underThreshold != null )
+ {
+ if ( count == _lowerBound )
+ {
+ _underThreshold.BeginInvoke(
+ count, new AsyncCallback(OnAsyncCallEnd),
+ _underThreshold
+ );
+ }
+ }
+ return item;
+ }
+
+ private void OnAsyncCallEnd(IAsyncResult res)
+ {
+ ThresholdMethod method = (ThresholdMethod)res.AsyncState;
+ method.EndInvoke(res);
+ }
+ }
+}
diff --git a/qpid/dotnet/Qpid.Client/Properties/AssemblyInfo.cs b/qpid/dotnet/Qpid.Client/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000000..670a4f90b2
--- /dev/null
+++ b/qpid/dotnet/Qpid.Client/Properties/AssemblyInfo.cs
@@ -0,0 +1,52 @@
+/*
+ *
+ * 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.
+ *
+ */
+using System.Reflection;
+using System.Runtime.InteropServices;
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("Apache.Qpid.Client")]
+[assembly: AssemblyDescription("Built from svn revision number: ")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Apache Software Foundation")]
+[assembly: AssemblyProduct("Apache.Qpid.Client")]
+[assembly: AssemblyCopyright("Apache Software Foundation")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("380cb124-07a8-40c2-b67d-69a0d94cb620")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Revision and Build Numbers
+// by using the '*' as shown below:
+[assembly: AssemblyVersion("0.5.0.0")]
diff --git a/qpid/dotnet/Qpid.Client/Qpid.Client.csproj b/qpid/dotnet/Qpid.Client/Qpid.Client.csproj
new file mode 100644
index 0000000000..303f885149
--- /dev/null
+++ b/qpid/dotnet/Qpid.Client/Qpid.Client.csproj
@@ -0,0 +1,102 @@
+<!--
+
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+
+-->
+
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProductVersion>8.0.50727</ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{68987C05-3768-452C-A6FC-6BA1D372852F}</ProjectGuid>
+ <OutputType>Library</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>Apache.Qpid.Client</RootNamespace>
+ <AssemblyName>Apache.Qpid.Client</AssemblyName>
+ <FileUpgradeFlags>
+ </FileUpgradeFlags>
+ <OldToolsVersion>2.0</OldToolsVersion>
+ <UpgradeBackupLocation>
+ </UpgradeBackupLocation>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>..\bin\net-2.0\debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>..\bin\net-2.0\release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="log4net, Version=1.2.0.30714, Culture=neutral, PublicKeyToken=500ffcafb14f92df">
+ <SpecificVersion>False</SpecificVersion>
+ <HintPath>..\Qpid.Common\lib\log4net\log4net.dll</HintPath>
+ </Reference>
+ <Reference Include="Org.Mentalis.Security, Version=1.0.13.716, Culture=neutral, PublicKeyToken=085a8f6006888436">
+ <SpecificVersion>False</SpecificVersion>
+ <HintPath>..\Qpid.Common\lib\seclib-1.0.0\Org.Mentalis.Security.dll</HintPath>
+ </Reference>
+ <Reference Include="System" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="**\*.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\Qpid.Buffer\Qpid.Buffer.csproj">
+ <Project>{44384DF2-B0A4-4580-BDBC-EE4BAA87D995}</Project>
+ <Name>Qpid.Buffer</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\Qpid.Codec\Qpid.Codec.csproj">
+ <Project>{22D0D0C2-77AF-4DE3-B456-7FF3893F9F88}</Project>
+ <Name>Qpid.Codec</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\Qpid.Messaging\Qpid.Messaging.csproj">
+ <Project>{6688F826-C58E-4C1B-AA1F-22AFAB4B7D07}</Project>
+ <Name>Qpid.Messaging</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\Qpid.Common\Qpid.Common.csproj">
+ <Project>{77064C42-24D2-4CEB-9EA2-0EF481A43205}</Project>
+ <Name>Qpid.Common</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\Qpid.Sasl\Qpid.Sasl.csproj">
+ <Project>{1465B0EE-6452-42A6-AB73-B2F9EABEEE75}</Project>
+ <Name>Qpid.Sasl</Name>
+ </ProjectReference>
+ </ItemGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+ <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
+ Other similar extension points exist, see Microsoft.Common.targets.
+ <Target Name="BeforeBuild">
+ </Target>
+ <Target Name="AfterBuild">
+ </Target>
+ -->
+</Project>
diff --git a/qpid/dotnet/Qpid.Client/default.build b/qpid/dotnet/Qpid.Client/default.build
new file mode 100644
index 0000000000..9a0ec2ea6d
--- /dev/null
+++ b/qpid/dotnet/Qpid.Client/default.build
@@ -0,0 +1,52 @@
+<?xml version="1.0"?>
+<!--
+
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+
+-->
+
+<project name="Apache.Qpid.Client" default="build">
+ <!--
+ Properties that come from master build file
+ - build.dir: root directory for build
+ - build.debug: true if building debug release
+ - build.defines: variables to define during build
+ -->
+
+ <target name="build">
+ <csc target="library"
+ define="${build.defines}"
+ debug="${build.debug}"
+ output="${build.dir}/${project::get-name()}.dll">
+
+ <sources>
+ <include name="**/*.cs" />
+ </sources>
+ <references>
+ <include name="${build.dir}/log4net.dll" />
+ <include name="${build.dir}/Apache.Qpid.Buffer.dll" />
+ <include name="${build.dir}/Apache.Qpid.Sasl.dll" />
+ <include name="${build.dir}/Apache.Qpid.Codec.dll" />
+ <include name="${build.dir}/Apache.Qpid.Common.dll" />
+ <include name="${build.dir}/Apache.Qpid.Messaging.dll" />
+ <include name="${build.dir}/Org.Mentalis.Security.dll" />
+ </references>
+ </csc>
+ </target>
+</project>
+
diff --git a/qpid/dotnet/Qpid.Client/qms/BrokerInfo.cs b/qpid/dotnet/Qpid.Client/qms/BrokerInfo.cs
new file mode 100644
index 0000000000..93c00af6e0
--- /dev/null
+++ b/qpid/dotnet/Qpid.Client/qms/BrokerInfo.cs
@@ -0,0 +1,55 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+using System;
+
+namespace Apache.Qpid.Client.Qms
+{
+ /// <summary>
+ /// Know URL option names.
+ /// <seealso cref="IConnectionInfo"/>
+ /// </summary>
+ public class BrokerInfoConstants
+ {
+ public const String OPTIONS_RETRY = "retries";
+ public const String OPTIONS_SSL = ConnectionUrlConstants.OPTIONS_SSL;
+ public const String OPTIONS_CONNECT_TIMEOUT = "connecttimeout";
+ public const int DEFAULT_PORT = 5672;
+ public const String DEFAULT_TRANSPORT = "tcp";
+
+ public readonly string URL_FORMAT_EXAMPLE =
+ "<transport>://<hostname>[:<port Default=\"" + DEFAULT_PORT + "\">][?<option>='<value>'[,<option>='<value>']]";
+
+ public const long DEFAULT_CONNECT_TIMEOUT = 30000L;
+ }
+
+ public interface IBrokerInfo
+ {
+ string Host { get; set; }
+ int Port { get; set; }
+ string Transport { get; set; }
+ bool UseSSL { get; set; }
+ long Timeout { get; set; }
+ SslOptions SslOptions { get; }
+
+ String GetOption(string key);
+ void SetOption(string key, string value);
+ }
+}
diff --git a/qpid/dotnet/Qpid.Client/qms/ConnectionInfo.cs b/qpid/dotnet/Qpid.Client/qms/ConnectionInfo.cs
new file mode 100644
index 0000000000..4d3f7698b5
--- /dev/null
+++ b/qpid/dotnet/Qpid.Client/qms/ConnectionInfo.cs
@@ -0,0 +1,63 @@
+/*
+ *
+ * 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.
+ *
+ */
+using System.Collections;
+
+namespace Apache.Qpid.Client.Qms
+{
+ class ConnectionUrlConstants
+ {
+ public const string AMQ_PROTOCOL = "amqp";
+ public const string OPTIONS_BROKERLIST = "brokerlist";
+ public const string OPTIONS_FAILOVER = "failover";
+ public const string OPTIONS_FAILOVER_CYCLE = "cyclecount";
+ public const string OPTIONS_SSL = "ssl";
+ }
+
+ /// <summary>
+ /// Connection URL format
+ /// amqp://[user:pass@][clientid]/virtualhost?brokerlist='tcp://host:port?option=\'value\'&amp;option=\'value\';vm://:3/virtualpath?option=\'value\''&amp;failover='method?option=\'value\'&amp;option='value''"
+ /// Options are of course optional except for requiring a single broker in the broker list.
+ /// The option seperator is defined to be either '&amp;' or ','
+ /// </summary>
+ public interface IConnectionInfo
+ {
+ string AsUrl();
+
+ string FailoverMethod { get; set; }
+ string ClientName { get; set; }
+ string Username { get; set; }
+ string Password { get; set; }
+ string VirtualHost { get; set; }
+ string GetFailoverOption(string key);
+
+ int BrokerCount { get; }
+
+ IBrokerInfo GetBrokerInfo(int index);
+
+ void AddBrokerInfo(IBrokerInfo broker);
+
+ IList GetAllBrokerInfos();
+
+ string GetOption(string key);
+
+ void SetOption(string key, string value);
+ }
+}
diff --git a/qpid/dotnet/Qpid.Client/qms/FailoverPolicy.cs b/qpid/dotnet/Qpid.Client/qms/FailoverPolicy.cs
new file mode 100644
index 0000000000..179a695bf9
--- /dev/null
+++ b/qpid/dotnet/Qpid.Client/qms/FailoverPolicy.cs
@@ -0,0 +1,315 @@
+/*
+ *
+ * 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.
+ *
+ */
+using System;
+using System.Text;
+using log4net;
+using Apache.Qpid.Client.Qms.Failover;
+
+namespace Apache.Qpid.Client.Qms
+{
+ public class FailoverPolicy
+ {
+ private static readonly ILog _logger = LogManager.GetLogger(typeof(FailoverPolicy));
+
+ private const long MINUTE = 60000L;
+
+ private const long DEFAULT_METHOD_TIMEOUT = 1 * MINUTE;
+ private const long DEFAULT_FAILOVER_TIMEOUT = 4 * MINUTE;
+
+ private IFailoverMethod[] _methods = new IFailoverMethod[1];
+
+ private int _currentMethod;
+
+ private int _methodsRetries;
+
+ private int _currentRetry;
+
+ private bool _timing;
+
+ private long _lastMethodTime;
+ private long _lastFailTime;
+
+ public FailoverPolicy(IConnectionInfo connectionInfo)
+ {
+ IFailoverMethod method;
+
+ //todo This should be integrated in to the connection url when it supports
+ // multiple strategies.
+
+ _methodsRetries = 0;
+
+ if (connectionInfo.FailoverMethod == null)
+ {
+ if (connectionInfo.BrokerCount > 1)
+ {
+ method = new FailoverRoundRobin(connectionInfo);
+ }
+ else
+ {
+ method = new FailoverSingleServer(connectionInfo);
+ }
+ }
+ else
+ {
+ string failoverMethod = connectionInfo.FailoverMethod;
+
+ /*
+ if (failoverMethod.equals(FailoverMethod.RANDOM))
+ {
+ //todo write a random connection Failover
+ }
+ */
+ if (failoverMethod.Equals(FailoverMethodConstants.ROUND_ROBIN))
+ {
+ method = new FailoverRoundRobin(connectionInfo);
+ }
+ else
+ {
+ throw new NotImplementedException("Dynamic loading of FailoverMethods not yet implemented.");
+// try
+// {
+// Type[] constructorSpec = {ConnectionInfo.class};
+// Object [] params = {connectionInfo};
+//
+// method = (FailoverMethod) ClassLoader.getSystemClassLoader().
+// loadClass(failoverMethod).
+// getConstructor(constructorSpec).newInstance(params);
+// }
+// catch (Exception cnfe)
+// {
+// throw new IllegalArgumentException("Unknown failover method:" + failoverMethod);
+// }
+ }
+ }
+
+ if (method == null)
+ {
+ throw new ArgumentException("Unknown failover method specified.");
+ }
+
+ reset();
+
+ _methods[_currentMethod] = method;
+ }
+
+ public FailoverPolicy(IFailoverMethod method) : this(method, 0)
+ {
+ }
+
+ public FailoverPolicy(IFailoverMethod method, int retries)
+ {
+ _methodsRetries = retries;
+
+ reset();
+
+ _methods[_currentMethod] = method;
+ }
+
+ private void reset()
+ {
+ _currentMethod = 0;
+ _currentRetry = 0;
+ _timing = false;
+
+ }
+
+ public bool FailoverAllowed()
+ {
+ bool failoverAllowed;
+
+ if (_timing)
+ {
+ long now = CurrentTimeMilliseconds();
+
+ if ((now - _lastMethodTime) >= DEFAULT_METHOD_TIMEOUT)
+ {
+ _logger.Info("Failover method timeout");
+ _lastMethodTime = now;
+
+ if (!nextMethod())
+ {
+ return false;
+ }
+
+
+ }
+ else if ((now - _lastFailTime) >= DEFAULT_FAILOVER_TIMEOUT)
+ {
+ _logger.Info("Failover timeout");
+ return false;
+ }
+ else
+ {
+ _lastMethodTime = now;
+ }
+ }
+ else
+ {
+ _timing = true;
+ _lastMethodTime = CurrentTimeMilliseconds();
+ _lastFailTime = _lastMethodTime;
+ }
+
+
+ if (_methods[_currentMethod].FailoverAllowed())
+ {
+ failoverAllowed = true;
+ }
+ else
+ {
+ if (_currentMethod < (_methods.Length - 1))
+ {
+ nextMethod();
+ _logger.Info("Changing method to " + _methods[_currentMethod].MethodName);
+ return FailoverAllowed();
+ }
+ else
+ {
+ return cycleMethods();
+ }
+ }
+
+ return failoverAllowed;
+ }
+
+ private static long CurrentTimeMilliseconds()
+ {
+ return DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond;
+ }
+
+ private bool nextMethod()
+ {
+ if (_currentMethod < (_methods.Length - 1))
+ {
+ _currentMethod++;
+ _methods[_currentMethod].Reset();
+ return true;
+ }
+ else
+ {
+ return cycleMethods();
+ }
+ }
+
+ private bool cycleMethods()
+ {
+ if (_currentRetry < _methodsRetries)
+ {
+ _currentRetry++;
+
+ _currentMethod = 0;
+
+ _logger.Info("Retrying methods starting with " + _methods[_currentMethod].MethodName);
+ _methods[_currentMethod].Reset();
+ return FailoverAllowed();
+ }
+ else
+ {
+ _logger.Debug("All failover methods exhausted");
+ return false;
+ }
+ }
+
+ /**
+ * Notification that connection was successful.
+ */
+ public void attainedConnection()
+ {
+ _currentRetry = 0;
+
+ _methods[_currentMethod].AttainedConnection();
+
+ _timing = false;
+ }
+
+ public IBrokerInfo GetCurrentBrokerInfo()
+ {
+ return _methods[_currentMethod].GetCurrentBrokerInfo();
+ }
+
+ public IBrokerInfo GetNextBrokerInfo()
+ {
+ return _methods[_currentMethod].GetNextBrokerDetails();
+ }
+
+ public void setBroker(IBrokerInfo broker)
+ {
+ _methods[_currentMethod].SetBroker(broker);
+ }
+
+ public void addMethod(IFailoverMethod method)
+ {
+ int len = _methods.Length + 1;
+ IFailoverMethod[] newMethods = new IFailoverMethod[len];
+ _methods.CopyTo(newMethods, 0);
+// System.arraycopy(_methods, 0, newMethods, 0, _methods.length);
+ int index = len - 1;
+ newMethods[index] = method;
+ _methods = newMethods;
+ }
+
+ public void setMethodRetries(int retries)
+ {
+ _methodsRetries = retries;
+ }
+
+ public IFailoverMethod getCurrentMethod()
+ {
+ if (_currentMethod >= 0 && _currentMethod < (_methods.Length - 1))
+ {
+ return _methods[_currentMethod];
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ public String toString()
+ {
+ StringBuilder sb = new StringBuilder();
+
+ sb.Append("Failover Policy:\n");
+
+ if (FailoverAllowed())
+ {
+ sb.Append("Failover allowed\n");
+ }
+ else
+ {
+ sb.Append("Failover not allowed\n");
+ }
+
+ sb.Append("Failover policy methods\n");
+ for (int i = 0; i < _methods.Length; i++)
+ {
+
+ if (i == _currentMethod)
+ {
+ sb.Append(">");
+ }
+ sb.Append(_methods[i].ToString());
+ }
+
+ return sb.ToString();
+ }
+ }
+}
diff --git a/qpid/dotnet/Qpid.Client/qms/UrlSyntaxException.cs b/qpid/dotnet/Qpid.Client/qms/UrlSyntaxException.cs
new file mode 100644
index 0000000000..ab3de325d4
--- /dev/null
+++ b/qpid/dotnet/Qpid.Client/qms/UrlSyntaxException.cs
@@ -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.
+ *
+ */
+using System;
+using System.Runtime.Serialization;
+using System.Text;
+
+namespace Apache.Qpid.Client.Qms
+{
+ [Serializable]
+ public class UrlSyntaxException : UriFormatException
+ {
+ private string _url;
+ private int _index;
+ private int _length;
+
+ public int GetIndex()
+ {
+ return _index;
+ }
+
+ public UrlSyntaxException(String input, String reason)
+ : this(input, reason, -1)
+ {
+ }
+
+ private UrlSyntaxException(string input, string reason, int index)
+ :
+ this(input, reason, index, input.Length)
+ {
+ }
+
+ public UrlSyntaxException(String url, String error, int index, int length)
+ : base(error)
+ {
+ _url = url;
+ _index = index;
+ _length = length;
+ }
+
+ protected UrlSyntaxException(SerializationInfo info, StreamingContext ctxt)
+ : base(info, ctxt)
+ {
+ _url = info.GetString("Url");
+ _index = info.GetInt32("Index");
+ _length = info.GetInt32("Length");
+ }
+
+ public override void GetObjectData(SerializationInfo info, StreamingContext context)
+ {
+ base.GetObjectData(info, context);
+ info.AddValue("Url", _url);
+ info.AddValue("Index", _index);
+ info.AddValue("Length", _length);
+ }
+
+ private static String getPositionString(int index, int length)
+ {
+ StringBuilder sb = new StringBuilder(index + 1);
+
+ for (int i = 0; i < index; i++)
+ {
+ sb.Append(" ");
+ }
+
+ if (length > -1)
+ {
+ for (int i = 0; i < length; i++)
+ {
+ sb.Append('^');
+ }
+ }
+
+ return sb.ToString();
+ }
+
+
+ public String toString()
+ {
+ StringBuilder sb = new StringBuilder();
+
+// sb.Append(getReason());
+
+ if (_index > -1)
+ {
+ if (_length != -1)
+ {
+ sb.Append(" between indicies ");
+ sb.Append(_index);
+ sb.Append(" and ");
+ sb.Append(_length);
+ }
+ else
+ {
+ sb.Append(" at index ");
+ sb.Append(_index);
+ }
+ }
+
+ sb.Append(" ");
+ if (_index != -1)
+ {
+ sb.Append("\n");
+ }
+
+ sb.Append(_url);
+
+ if (_index != -1)
+ {
+ sb.Append("\n");
+ sb.Append(getPositionString(_index, _length));
+ }
+
+ return sb.ToString();
+ }
+ }
+}
diff --git a/qpid/dotnet/Qpid.Client/qms/failover/FailoverMethod.cs b/qpid/dotnet/Qpid.Client/qms/failover/FailoverMethod.cs
new file mode 100644
index 0000000000..f32b275e84
--- /dev/null
+++ b/qpid/dotnet/Qpid.Client/qms/failover/FailoverMethod.cs
@@ -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.
+ *
+ */
+using System;
+
+namespace Apache.Qpid.Client.Qms.Failover
+{
+ public class FailoverMethodConstants
+ {
+ public const String ROUND_ROBIN = "roundrobin";
+ public const String RANDOM = "random";
+ }
+
+ public interface IFailoverMethod
+ {
+ /// <summary>
+ /// The name of this method for display purposes.
+ /// </summary>
+ String MethodName { get; }
+
+ /// <summary>
+ /// Reset the Failover to initial conditions
+ /// </summary>
+ void Reset();
+
+ /// <summary>
+ /// Check if failover is possible for this method
+ /// </summary>
+ /// <returns>true if failover is allowed</returns>
+ bool FailoverAllowed();
+
+ /// <summary>
+ /// Notification to the Failover method that a connection has been attained.
+ /// </summary>
+ void AttainedConnection();
+
+ /// <summary>
+ /// If there is no current BrokerInfo the null will be returned.
+ /// </summary>
+ /// <returns>The current BrokerDetail value to use</returns>
+ IBrokerInfo GetCurrentBrokerInfo();
+
+ /// <summary>
+ /// Move to the next BrokerInfo if one is available.
+ /// </summary>
+ /// <returns>the next BrokerDetail or null if there is none.</returns>
+ IBrokerInfo GetNextBrokerDetails();
+
+ /// <summary>
+ /// Set the currently active broker to be the new value.
+ /// </summary>
+ /// <param name="broker">The new BrokerDetail value</param>
+ void SetBroker(IBrokerInfo broker);
+
+ /// <summary>
+ /// Set the retries for this method
+ /// </summary>
+ /// <param name="maxRetries">the maximum number of time to retry this Method</param>
+ void SetRetries(int maxRetries);
+ }
+}
diff --git a/qpid/dotnet/Qpid.Client/qms/failover/FailoverRoundRobin.cs b/qpid/dotnet/Qpid.Client/qms/failover/FailoverRoundRobin.cs
new file mode 100644
index 0000000000..8103940fb4
--- /dev/null
+++ b/qpid/dotnet/Qpid.Client/qms/failover/FailoverRoundRobin.cs
@@ -0,0 +1,255 @@
+/*
+ *
+ * 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.
+ *
+ */
+using System;
+using System.Text;
+using log4net;
+
+namespace Apache.Qpid.Client.Qms.Failover
+{
+ public class FailoverRoundRobin : IFailoverMethod
+ {
+ private static readonly ILog _logger = LogManager.GetLogger(typeof(FailoverRoundRobin));
+
+ /** The default number of times to cycle through all servers */
+ public const int DEFAULT_CYCLE_RETRIES = 0;
+ /** The default number of times to retry each server */
+ public const int DEFAULT_SERVER_RETRIES = 0;
+
+ /**
+ * The index into the hostDetails array of the broker to which we are connected
+ */
+ private int _currentBrokerIndex = -1;
+
+ /**
+ * The number of times to retry connecting for each server
+ */
+ private int _serverRetries;
+
+ /**
+ * The current number of retry attempts made
+ */
+ private int _currentServerRetry;
+
+ /**
+ * The number of times to cycle through the servers
+ */
+ private int _cycleRetries;
+
+ /**
+ * The current number of cycles performed.
+ */
+ private int _currentCycleRetries;
+
+ /**
+ * Array of BrokerDetail used to make connections.
+ */
+ private IConnectionInfo _connectionDetails;
+
+ public FailoverRoundRobin(IConnectionInfo connectionDetails)
+ {
+ if (!(connectionDetails.BrokerCount > 0))
+ {
+ throw new ArgumentException("At least one broker details must be specified.");
+ }
+
+ _connectionDetails = connectionDetails;
+
+ //There is no current broker at startup so set it to -1.
+ _currentBrokerIndex = -1;
+
+ String cycleRetries = _connectionDetails.GetFailoverOption(ConnectionUrlConstants.OPTIONS_FAILOVER_CYCLE);
+
+ if (cycleRetries != null)
+ {
+ try
+ {
+ _cycleRetries = int.Parse(cycleRetries);
+ }
+ catch (FormatException)
+ {
+ _cycleRetries = DEFAULT_CYCLE_RETRIES;
+ }
+ }
+
+ _currentCycleRetries = 0;
+
+ _serverRetries = 0;
+ _currentServerRetry = -1;
+ }
+
+ public void Reset()
+ {
+ _currentBrokerIndex = 0;
+ _currentCycleRetries = 0;
+ _currentServerRetry = -1;
+ }
+
+ public bool FailoverAllowed()
+ {
+ return ((_currentCycleRetries < _cycleRetries)
+ || (_currentServerRetry < _serverRetries)
+ || (_currentBrokerIndex < (_connectionDetails.BrokerCount - 1)));
+ }
+
+ public void AttainedConnection()
+ {
+ _currentCycleRetries = 0;
+ _currentServerRetry = -1;
+ }
+
+ public IBrokerInfo GetCurrentBrokerInfo()
+ {
+ if (_currentBrokerIndex == -1)
+ {
+ return null;
+ }
+
+ return _connectionDetails.GetBrokerInfo(_currentBrokerIndex);
+ }
+
+ public IBrokerInfo GetNextBrokerDetails()
+ {
+ if (_currentBrokerIndex == (_connectionDetails.BrokerCount - 1))
+ {
+ if (_currentServerRetry < _serverRetries)
+ {
+ if (_currentBrokerIndex == -1)
+ {
+ _currentBrokerIndex = 0;
+
+ SetBroker(_connectionDetails.GetBrokerInfo(_currentBrokerIndex ));
+
+ _logger.Info("First Run using " + _connectionDetails.GetBrokerInfo(_currentBrokerIndex));
+ }
+ else
+ {
+ _logger.Info("Retrying " + _connectionDetails.GetBrokerInfo(_currentBrokerIndex));
+ }
+
+ _currentServerRetry++;
+ }
+ else
+ {
+ _currentCycleRetries++;
+ //failed to connect to first broker
+ _currentBrokerIndex = 0;
+
+ SetBroker(_connectionDetails.GetBrokerInfo(_currentBrokerIndex ));
+
+ // This is zero rather than -1 as we are already retrieving the details.
+ _currentServerRetry = 0;
+ }
+ //else - should force client to stop as max retries has been reached.
+ }
+ else
+ {
+ if (_currentServerRetry < _serverRetries)
+ {
+ if (_currentBrokerIndex == -1)
+ {
+ _currentBrokerIndex = 0;
+
+ SetBroker(_connectionDetails.GetBrokerInfo(_currentBrokerIndex ));
+
+ _logger.Info("First Run using " + _connectionDetails.GetBrokerInfo(_currentBrokerIndex));
+ }
+ else
+ {
+ _logger.Info("Retrying " + _connectionDetails.GetBrokerInfo(_currentBrokerIndex));
+ }
+ _currentServerRetry++;
+ }
+ else
+ {
+ _currentBrokerIndex++;
+
+ SetBroker(_connectionDetails.GetBrokerInfo(_currentBrokerIndex ));
+ // This is zero rather than -1 as we are already retrieving the details.
+ _currentServerRetry = 0;
+ }
+ }
+
+ return _connectionDetails.GetBrokerInfo(_currentBrokerIndex);
+ }
+
+ public void SetBroker(IBrokerInfo broker)
+ {
+ _connectionDetails.AddBrokerInfo(broker);
+
+ int index = _connectionDetails.GetAllBrokerInfos().IndexOf(broker);
+
+ String serverRetries = broker.GetOption(BrokerInfoConstants.OPTIONS_RETRY);
+
+ if (serverRetries != null)
+ {
+ try
+ {
+ _serverRetries = int.Parse(serverRetries);
+ }
+ catch (FormatException)
+ {
+ _serverRetries = DEFAULT_SERVER_RETRIES;
+ }
+ }
+
+ _currentServerRetry = -1;
+ _currentBrokerIndex = index;
+ }
+
+ public void SetRetries(int maxRetries)
+ {
+ _cycleRetries = maxRetries;
+ }
+
+ public String MethodName
+ {
+ get { return "Cycle Servers"; }
+ }
+
+ public override string ToString()
+ {
+ StringBuilder sb = new StringBuilder();
+
+ sb.Append(GetType().Name).Append("\n");
+
+ sb.Append("Broker count: ").Append(_connectionDetails.BrokerCount);
+ sb.Append("\ncurrent broker index: ").Append(_currentBrokerIndex);
+
+ sb.Append("\nCycle Retries: ").Append(_cycleRetries);
+ sb.Append("\nCurrent Cycle:").Append(_currentCycleRetries);
+ sb.Append("\nServer Retries:").Append(_serverRetries);
+ sb.Append("\nCurrent Retry:").Append(_currentServerRetry);
+ sb.Append("\n");
+
+ for(int i=0; i < _connectionDetails.BrokerCount ; i++)
+ {
+ if (i == _currentBrokerIndex)
+ {
+ sb.Append(">");
+ }
+ sb.Append(_connectionDetails.GetBrokerInfo(i));
+ sb.Append("\n");
+ }
+
+ return sb.ToString();
+ }
+ }
+}
diff --git a/qpid/dotnet/Qpid.Client/qms/failover/FailoverSingleServer.cs b/qpid/dotnet/Qpid.Client/qms/failover/FailoverSingleServer.cs
new file mode 100644
index 0000000000..5e502b897e
--- /dev/null
+++ b/qpid/dotnet/Qpid.Client/qms/failover/FailoverSingleServer.cs
@@ -0,0 +1,147 @@
+/*
+ *
+ * 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.
+ *
+ */
+using System;
+
+namespace Apache.Qpid.Client.Qms.Failover
+{
+ public class FailoverSingleServer : IFailoverMethod
+ {
+ /** The default number of times to rety a conection to this server */
+ public const int DEFAULT_SERVER_RETRIES = 1;
+
+ /**
+ * The details of the Single Server
+ */
+ private IBrokerInfo _brokerDetail;
+
+ /**
+ * The number of times to retry connecting to the sever
+ */
+ private int _retries;
+
+ /**
+ * The current number of attempts made to the server
+ */
+ private int _currentRetries;
+
+
+ public FailoverSingleServer(IConnectionInfo connectionDetails)
+ {
+ if (connectionDetails.BrokerCount > 0)
+ {
+ SetBroker(connectionDetails.GetBrokerInfo(0));
+ }
+ else
+ {
+ throw new ArgumentException("BrokerInfo details required for connection.");
+ }
+ }
+
+ public FailoverSingleServer(IBrokerInfo brokerDetail)
+ {
+ SetBroker(brokerDetail);
+ }
+
+ public void Reset()
+ {
+ _currentRetries = -1;
+ }
+
+ public bool FailoverAllowed()
+ {
+ return _currentRetries < _retries;
+ }
+
+ public void AttainedConnection()
+ {
+ Reset();
+ }
+
+ public IBrokerInfo GetCurrentBrokerInfo()
+ {
+ return _brokerDetail;
+ }
+
+ public IBrokerInfo GetNextBrokerDetails()
+ {
+ if (_currentRetries == _retries)
+ {
+ return null;
+ }
+ else
+ {
+ if (_currentRetries < _retries)
+ {
+ _currentRetries ++;
+ }
+
+ return _brokerDetail;
+ }
+ }
+
+ public void SetBroker(IBrokerInfo broker)
+ {
+ if (broker == null)
+ {
+ throw new ArgumentException("BrokerInfo details cannot be null");
+ }
+ _brokerDetail = broker;
+
+ String retries = broker.GetOption(BrokerInfoConstants.OPTIONS_RETRY);
+ if (retries != null)
+ {
+ try
+ {
+ _retries = int.Parse(retries);
+ }
+ catch (FormatException)
+ {
+ _retries = DEFAULT_SERVER_RETRIES;
+ }
+ }
+ else
+ {
+ _retries = DEFAULT_SERVER_RETRIES;
+ }
+
+ Reset();
+ }
+
+ public void SetRetries(int retries)
+ {
+ _retries = retries;
+ }
+
+ public String MethodName
+ {
+ get { return "Single Server"; }
+ }
+
+ public String toString()
+ {
+ return "SingleServer:\n"+
+ "Max Retries:"+_retries+
+ "\nCurrent Retry:"+_currentRetries+
+ "\n"+_brokerDetail+"\n";
+ }
+
+ }
+}
diff --git a/qpid/dotnet/Qpid.Codec/CumulativeProtocolDecoder.cs b/qpid/dotnet/Qpid.Codec/CumulativeProtocolDecoder.cs
new file mode 100644
index 0000000000..6cfd75c851
--- /dev/null
+++ b/qpid/dotnet/Qpid.Codec/CumulativeProtocolDecoder.cs
@@ -0,0 +1,152 @@
+/*
+ *
+ * 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.
+ *
+ */
+using System;
+using log4net;
+using Apache.Qpid.Buffer;
+
+namespace Apache.Qpid.Codec
+{
+ public abstract class CumulativeProtocolDecoder : IProtocolDecoder
+ {
+ static ILog _logger = LogManager.GetLogger(typeof(CumulativeProtocolDecoder));
+
+ ByteBuffer _remaining;
+
+ /// <summary>
+ /// Creates a new instance with the 4096 bytes initial capacity of
+ /// cumulative buffer.
+ /// </summary>
+ protected CumulativeProtocolDecoder()
+ {
+ _remaining = AllocateBuffer();
+ }
+
+ /// <summary>
+ /// Cumulates content of <tt>in</tt> into internal buffer and forwards
+ /// decoding request to {@link #doDecode(IoSession, ByteBuffer, ProtocolDecoderOutput)}.
+ /// <tt>doDecode()</tt> is invoked repeatedly until it returns <tt>false</tt>
+ /// and the cumulative buffer is compacted after decoding ends.
+ /// </summary>
+ /// <exception cref="Exception">
+ /// if your <tt>doDecode()</tt> returned <tt>true</tt> not consuming the cumulative buffer.
+ /// </exception>
+ public void Decode(ByteBuffer input, IProtocolDecoderOutput output)
+ {
+ if ( _remaining.Position != 0 ) // If there were remaining undecoded bytes
+ {
+ DecodeRemainingAndInput(input, output);
+ } else
+ {
+ DecodeInput(input, output);
+ }
+ }
+
+ private void DecodeInput(ByteBuffer input, IProtocolDecoderOutput output)
+ {
+ _logger.Debug(string.Format("DecodeInput: input {0}", input.Remaining));
+ // Just decode the input buffer and remember any remaining undecoded bytes.
+ try
+ {
+ DecodeAll(input, output);
+ } finally
+ {
+ if ( input.HasRemaining )
+ {
+ _remaining.Put(input);
+ }
+ }
+ }
+
+ private void DecodeRemainingAndInput(ByteBuffer input, IProtocolDecoderOutput output)
+ {
+ _logger.Debug(string.Format("DecodeRemainingAndInput: input {0}, remaining {1}", input.Remaining, _remaining.Position));
+ // replace the _remainder buffer, so that we can leave the
+ // original one alone. Necessary because some consumer splice
+ // the buffer and only consume it until later, causing
+ // a race condition if we compact it too soon.
+ ByteBuffer newRemainding = AllocateBuffer();
+ ByteBuffer temp = _remaining;
+ _remaining = newRemainding;
+ temp.Put(input);
+ temp.Flip();
+ try
+ {
+ DecodeAll(temp, output);
+ } finally
+ {
+ if ( temp.Remaining > 0 )
+ _remaining.Put(temp);
+ }
+ }
+
+ private void DecodeAll(ByteBuffer buf, IProtocolDecoderOutput output)
+ {
+ for ( ; ; )
+ {
+ int oldPos = buf.Position;
+ bool decoded = DoDecode(buf, output);
+ if ( decoded )
+ {
+ if ( buf.Position == oldPos )
+ {
+ throw new Exception(
+ "doDecode() can't return true when buffer is not consumed.");
+ }
+
+ if ( !buf.HasRemaining )
+ {
+ break;
+ }
+ } else
+ {
+ break;
+ }
+ }
+ }
+
+ /// <summary>
+ /// Implement this method to consume the specified cumulative buffer and
+ /// decode its content into message(s).
+ /// </summary>
+ /// <param name="input">the cumulative buffer</param>
+ /// <param name="output">decoder output</param>
+ /// <returns>
+ /// <tt>true</tt> if and only if there's more to decode in the buffer
+ /// and you want to have <tt>doDecode</tt> method invoked again.
+ /// Return <tt>false</tt> if remaining data is not enough to decode,
+ /// then this method will be invoked again when more data is cumulated.
+ /// </returns>
+ /// <exception cref="Exception">If cannot decode</exception>
+ protected abstract bool DoDecode(ByteBuffer input, IProtocolDecoderOutput output);
+
+ public void Dispose()
+ {
+ _remaining = null;
+ }
+
+ private ByteBuffer AllocateBuffer()
+ {
+ ByteBuffer buffer = ByteBuffer.Allocate(4096);
+ buffer.IsAutoExpand = true;
+ return buffer;
+ }
+ }
+}
diff --git a/qpid/dotnet/Qpid.Codec/Demux/DemuxingProtocolCodecFactory.cs b/qpid/dotnet/Qpid.Codec/Demux/DemuxingProtocolCodecFactory.cs
new file mode 100644
index 0000000000..78276202d6
--- /dev/null
+++ b/qpid/dotnet/Qpid.Codec/Demux/DemuxingProtocolCodecFactory.cs
@@ -0,0 +1,387 @@
+/*
+ *
+ * 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.
+ *
+ */
+using System;
+using System.Collections;
+using Apache.Qpid.Buffer;
+
+namespace Apache.Qpid.Codec.Demux
+{
+ public class DemuxingProtocolCodecFactory : IProtocolCodecFactory
+ {
+ private ArrayList _decoderFactories = new ArrayList();
+ private ArrayList _encoderFactories = new ArrayList();
+
+ public void Register(Type encoderOrDecoderClass)
+ {
+ if (encoderOrDecoderClass == null)
+ {
+ throw new ArgumentNullException("encoderOrDecoderClass");
+ }
+
+ bool registered = false;
+ if (typeof(IMessageEncoder).IsAssignableFrom(encoderOrDecoderClass))
+ {
+ Register(new DefaultConstructorMessageEncoderFactory(encoderOrDecoderClass));
+ registered = true;
+ }
+
+ if (typeof(IMessageDecoder).IsAssignableFrom(encoderOrDecoderClass))
+ {
+ Register(new DefaultConstructorMessageDecoderFactory(encoderOrDecoderClass));
+ registered = true;
+ }
+
+ if (!registered)
+ {
+ throw new ArgumentException("Unregisterable type: " + encoderOrDecoderClass);
+ }
+ }
+
+ public void Register(IMessageEncoder encoder)
+ {
+ Register(new SingletonMessageEncoderFactory(encoder));
+ }
+
+ public void Register(IMessageEncoderFactory factory)
+ {
+ if (factory == null)
+ {
+ throw new ArgumentNullException("factory");
+ }
+
+ _encoderFactories.Add(factory);
+ }
+
+ public void Register(IMessageDecoder decoder)
+ {
+ Register(new SingletonMessageDecoderFactory(decoder));
+ }
+
+ public void Register(IMessageDecoderFactory factory)
+ {
+ if (factory == null)
+ {
+ throw new ArgumentNullException("factory");
+ }
+ _decoderFactories.Add(factory);
+ }
+
+ public IProtocolEncoder Encoder
+ {
+ get
+ {
+ return new ProtocolEncoderImpl(this);
+ }
+ }
+
+ public IProtocolDecoder Decoder
+ {
+ get
+ {
+ return new ProtocolDecoderImpl(this);
+ }
+ }
+
+ protected void DisposeCodecResources()
+ {
+ // Do nothing by default
+ }
+
+ private class ProtocolEncoderImpl : IProtocolEncoder
+ {
+ private readonly Hashtable _encoders = new Hashtable();
+
+ private DemuxingProtocolCodecFactory _enclosing;
+
+ public ProtocolEncoderImpl(DemuxingProtocolCodecFactory enclosing)
+ {
+ _enclosing = enclosing;
+ ArrayList encoderFactories = enclosing._encoderFactories;
+ for (int i = encoderFactories.Count - 1; i >= 0; i--)
+ {
+ IMessageEncoder encoder = ((IMessageEncoderFactory)encoderFactories[i]).NewEncoder();
+ foreach (Type type in encoder.MessageTypes.Keys)
+ {
+ _encoders[type] = encoder;
+ }
+ }
+ }
+
+ public void Encode(object message, IProtocolEncoderOutput output)
+ {
+ Type type = message.GetType();
+ IMessageEncoder encoder = FindEncoder(type);
+ if (encoder == null)
+ {
+ throw new ProtocolEncoderException("Unexpected message type: " + type);
+ }
+
+ encoder.Encode(message, output);
+ }
+
+ private IMessageEncoder FindEncoder(Type type)
+ {
+ IMessageEncoder encoder = (IMessageEncoder)_encoders[type];
+ if (encoder == null)
+ {
+ encoder = FindEncoder(type, new Hashtable());
+ }
+
+ return encoder;
+ }
+
+ private IMessageEncoder FindEncoder(Type type, Hashtable triedClasses)
+ {
+ IMessageEncoder encoder;
+
+ if (triedClasses.Contains(type))
+ {
+ return null;
+ }
+ triedClasses[type] = 1;
+
+ encoder = (IMessageEncoder)_encoders[type];
+ if (encoder == null)
+ {
+ encoder = FindEncoder(type, triedClasses);
+ if (encoder != null)
+ {
+ return encoder;
+ }
+
+ Type[] interfaces = type.GetInterfaces();
+ for (int i = 0; i < interfaces.Length; i++)
+ {
+ encoder = FindEncoder(interfaces[i], triedClasses);
+ if (encoder != null)
+ {
+ return encoder;
+ }
+ }
+
+ return null;
+ }
+ else
+ return encoder;
+ }
+
+ public void Dispose()
+ {
+ _enclosing.DisposeCodecResources();
+ }
+ }
+
+ private class ProtocolDecoderImpl : CumulativeProtocolDecoder
+ {
+ private readonly IMessageDecoder[] _decoders;
+ private IMessageDecoder _currentDecoder;
+ private DemuxingProtocolCodecFactory _enclosing;
+
+ public ProtocolDecoderImpl(DemuxingProtocolCodecFactory enclosing)
+ {
+ _enclosing = enclosing;
+ ArrayList decoderFactories = _enclosing._decoderFactories;
+ _decoders = new IMessageDecoder[decoderFactories.Count];
+ for (int i = decoderFactories.Count - 1; i >= 0; i--)
+ {
+ _decoders[i] = ((IMessageDecoderFactory) decoderFactories[i]).NewDecoder();
+ }
+ }
+
+ protected override bool DoDecode(ByteBuffer input, IProtocolDecoderOutput output)
+ {
+ MessageDecoderResult result;
+ if (_currentDecoder == null)
+ {
+ IMessageDecoder[] decoders = _decoders;
+ int undecodables = 0;
+
+ for (int i = decoders.Length - 1; i >= 0; i --)
+ {
+ IMessageDecoder decoder = decoders[i];
+ int limit = input.Limit;
+ int pos = input.Position;
+
+ try
+ {
+ result = decoder.Decodable(input);
+ }
+ finally
+ {
+ input.Position = pos;
+ input.Limit = limit;
+ }
+
+ if (result == MessageDecoderResult.OK)
+ {
+ _currentDecoder = decoder;
+ break;
+ }
+ else if(result == MessageDecoderResult.NOT_OK)
+ {
+ undecodables ++;
+ }
+ else if (result != MessageDecoderResult.NEED_DATA)
+ {
+ throw new Exception("Unexpected decode result (see your decodable()): " + result);
+ }
+ }
+
+ if (undecodables == _decoders.Length)
+ {
+ // Throw an exception if all decoders cannot decode data.
+ input.Position = input.Limit; // Skip data
+ throw new ProtocolDecoderException(
+ "No appropriate message decoder: " + input.GetHexDump());
+ }
+
+ if (_currentDecoder == null)
+ {
+ // Decoder is not determined yet (i.e. we need more data)
+ return false;
+ }
+ }
+
+ result = _currentDecoder.Decode(input, output);
+ if (result == MessageDecoderResult.OK)
+ {
+ _currentDecoder = null;
+ return true;
+ }
+ else if (result == MessageDecoderResult.NEED_DATA)
+ {
+ return false;
+ }
+ else if (result == MessageDecoderResult.NOT_OK)
+ {
+ throw new ProtocolDecoderException("Message decoder returned NOT_OK.");
+ }
+ else
+ {
+ throw new Exception("Unexpected decode result (see your decode()): " + result);
+ }
+ }
+ }
+
+ private class SingletonMessageEncoderFactory : IMessageEncoderFactory
+ {
+ private readonly IMessageEncoder _encoder;
+
+ public SingletonMessageEncoderFactory(IMessageEncoder encoder)
+ {
+ if (encoder == null)
+ {
+ throw new ArgumentNullException("encoder");
+ }
+ _encoder = encoder;
+ }
+
+ public IMessageEncoder NewEncoder()
+ {
+ return _encoder;
+ }
+ }
+
+ private class SingletonMessageDecoderFactory : IMessageDecoderFactory
+ {
+ private readonly IMessageDecoder _decoder;
+
+ public SingletonMessageDecoderFactory(IMessageDecoder decoder)
+ {
+ if (decoder == null)
+ {
+ throw new ArgumentNullException("decoder");
+ }
+ _decoder = decoder;
+ }
+
+ public IMessageDecoder NewDecoder()
+ {
+ return _decoder;
+ }
+ }
+
+ private class DefaultConstructorMessageEncoderFactory : IMessageEncoderFactory
+ {
+ private readonly Type _encoderClass;
+
+ public DefaultConstructorMessageEncoderFactory(Type encoderClass)
+ {
+ if (encoderClass == null)
+ {
+ throw new ArgumentNullException("encoderClass");
+ }
+
+ if(!typeof(IMessageEncoder).IsAssignableFrom(encoderClass))
+ {
+ throw new ArgumentException("encoderClass is not assignable to MessageEncoder");
+ }
+ _encoderClass = encoderClass;
+ }
+
+ public IMessageEncoder NewEncoder()
+ {
+ try
+ {
+ return (IMessageEncoder) Activator.CreateInstance(_encoderClass);
+ }
+ catch (Exception e)
+ {
+ throw new Exception( "Failed to create a new instance of " + _encoderClass, e);
+ }
+ }
+ }
+
+ private class DefaultConstructorMessageDecoderFactory : IMessageDecoderFactory
+ {
+ private readonly Type _decoderClass;
+
+ public DefaultConstructorMessageDecoderFactory(Type decoderClass)
+ {
+ if (decoderClass == null)
+ {
+ throw new ArgumentNullException("decoderClass");
+ }
+
+ if(!typeof(IMessageDecoder).IsAssignableFrom(decoderClass))
+ {
+ throw new ArgumentException("decoderClass is not assignable to MessageDecoder");
+ }
+ _decoderClass = decoderClass;
+ }
+
+ public IMessageDecoder NewDecoder()
+ {
+ try
+ {
+ return (IMessageDecoder) Activator.CreateInstance(_decoderClass);
+ }
+ catch (Exception e)
+ {
+ throw new Exception("Failed to create a new instance of " + _decoderClass, e);
+ }
+ }
+ }
+ }
+}
+
+
+
diff --git a/qpid/dotnet/Qpid.Codec/Demux/IMessageDecoder.cs b/qpid/dotnet/Qpid.Codec/Demux/IMessageDecoder.cs
new file mode 100644
index 0000000000..5892673440
--- /dev/null
+++ b/qpid/dotnet/Qpid.Codec/Demux/IMessageDecoder.cs
@@ -0,0 +1,56 @@
+/*
+ *
+ * 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.
+ *
+ */
+using System;
+using Apache.Qpid.Buffer;
+
+namespace Apache.Qpid.Codec.Demux
+{
+ public interface IMessageDecoder
+ {
+ /// <summary>
+ /// Checks the specified buffer is decodable by this decoder.
+ /// </summary>
+ /// <param name="buffer">The buffer to read data from.</param>
+ /// <returns>
+ /// OK if this decoder can decode the specified buffer.
+ /// NOT_OK if this decoder cannot decode the specified buffer.
+ /// if more data is required to determine if the
+ /// specified buffer is decodable ({@link #OK}) or not decodable
+ /// {@link #NOT_OK}.</returns>
+ MessageDecoderResult Decodable(ByteBuffer buffer);
+
+ /// <summary>
+ /// Decodes binary or protocol-specific content into higher-level message objects.
+ /// MINA invokes {@link #decode(IoSession, ByteBuffer, ProtocolDecoderOutput)}
+ /// method with read data, and then the decoder implementation puts decoded
+ /// messages into {@link ProtocolDecoderOutput}.
+ /// </summary>
+ /// <returns>
+ /// {@link #OK} if you finished decoding messages successfully.
+ /// {@link #NEED_DATA} if you need more data to finish decoding current message.
+ /// {@link #NOT_OK} if you cannot decode current message due to protocol specification violation.
+ /// </returns>
+ /// <exception cref="Exception">if the read data violated protocol specification </exception>
+ MessageDecoderResult Decode(ByteBuffer buffer, IProtocolDecoderOutput output);
+ }
+}
+
+
diff --git a/qpid/dotnet/Qpid.Codec/Demux/IMessageDecoderFactory.cs b/qpid/dotnet/Qpid.Codec/Demux/IMessageDecoderFactory.cs
new file mode 100644
index 0000000000..9e333d670f
--- /dev/null
+++ b/qpid/dotnet/Qpid.Codec/Demux/IMessageDecoderFactory.cs
@@ -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.
+ *
+ */
+namespace Apache.Qpid.Codec.Demux
+{
+ public interface IMessageDecoderFactory
+ {
+ /// <summary>
+ /// Creates a new message decoder.
+ /// </summary>
+ IMessageDecoder NewDecoder();
+ }
+}
+
+
diff --git a/qpid/dotnet/Qpid.Codec/Demux/IMessageEncoder.cs b/qpid/dotnet/Qpid.Codec/Demux/IMessageEncoder.cs
new file mode 100644
index 0000000000..75ae23592b
--- /dev/null
+++ b/qpid/dotnet/Qpid.Codec/Demux/IMessageEncoder.cs
@@ -0,0 +1,48 @@
+/*
+ *
+ * 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.
+ *
+ */
+using System;
+using System.Collections;
+
+namespace Apache.Qpid.Codec.Demux
+{
+ public interface IMessageEncoder
+ {
+ /// <summary>
+ /// Returns the set of message classes this encoder can encode.
+ /// </summary>
+ Hashtable MessageTypes
+ {
+ get;
+ }
+
+ /// <summary>
+ /// Encodes higher-level message objects into binary or protocol-specific data.
+ /// MINA invokes {@link #encode(IoSession, Object, ProtocolEncoderOutput)}
+ /// method with message which is popped from the session write queue, and then
+ /// the encoder implementation puts encoded {@link ByteBuffer}s into
+ /// {@link ProtocolEncoderOutput}.
+ /// </summary>
+ /// <exception cref="Exception">if the message violated protocol specification</exception>
+ void Encode(Object message, IProtocolEncoderOutput output);
+ }
+}
+
+
diff --git a/qpid/dotnet/Qpid.Codec/Demux/IMessageEncoderFactory.cs b/qpid/dotnet/Qpid.Codec/Demux/IMessageEncoderFactory.cs
new file mode 100644
index 0000000000..3001d1a963
--- /dev/null
+++ b/qpid/dotnet/Qpid.Codec/Demux/IMessageEncoderFactory.cs
@@ -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.
+ *
+ */
+namespace Apache.Qpid.Codec.Demux
+{
+ public interface IMessageEncoderFactory
+ {
+ /// <summary>
+ /// Creates a new message encoder.
+ /// </summary>
+ IMessageEncoder NewEncoder();
+ }
+}
+
+
diff --git a/qpid/dotnet/Qpid.Codec/Demux/MessageDecoderResult.cs b/qpid/dotnet/Qpid.Codec/Demux/MessageDecoderResult.cs
new file mode 100644
index 0000000000..ab01864bc0
--- /dev/null
+++ b/qpid/dotnet/Qpid.Codec/Demux/MessageDecoderResult.cs
@@ -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.
+ *
+ */
+namespace Apache.Qpid.Codec.Demux
+{
+ public enum MessageDecoderResult
+ {
+ OK, NOT_OK, NEED_DATA
+ }
+}
+
+
diff --git a/qpid/dotnet/Qpid.Codec/IProtocolCodecFactory.cs b/qpid/dotnet/Qpid.Codec/IProtocolCodecFactory.cs
new file mode 100644
index 0000000000..a26b91b16c
--- /dev/null
+++ b/qpid/dotnet/Qpid.Codec/IProtocolCodecFactory.cs
@@ -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.
+ *
+ */
+namespace Apache.Qpid.Codec
+{
+ public interface IProtocolCodecFactory
+ {
+ IProtocolEncoder Encoder
+ {
+ get;
+ }
+
+ IProtocolDecoder Decoder
+ {
+ get;
+ }
+ }
+}
+
+
diff --git a/qpid/dotnet/Qpid.Codec/IProtocolDecoder.cs b/qpid/dotnet/Qpid.Codec/IProtocolDecoder.cs
new file mode 100644
index 0000000000..3cccb0f7da
--- /dev/null
+++ b/qpid/dotnet/Qpid.Codec/IProtocolDecoder.cs
@@ -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.
+ *
+ */
+using System;
+using Apache.Qpid.Buffer;
+
+namespace Apache.Qpid.Codec
+{
+ public interface IProtocolDecoder : IDisposable
+ {
+ /// <summary>
+ /// Decodes binary or protocol-specific content into higher-level message objects.
+ /// MINA invokes {@link #decode(IoSession, ByteBuffer, ProtocolDecoderOutput)}
+ /// method with read data, and then the decoder implementation puts decoded
+ /// messages into {@link ProtocolDecoderOutput}.
+ /// </summary>
+ /// <param name="input"></param>
+ /// <param name="output"></param>
+ /// <exception cref="Exception">if the read data violated protocol specification</exception>
+ void Decode(ByteBuffer input, IProtocolDecoderOutput output);
+ }
+}
+
+
diff --git a/qpid/dotnet/Qpid.Codec/IProtocolDecoderOutput.cs b/qpid/dotnet/Qpid.Codec/IProtocolDecoderOutput.cs
new file mode 100644
index 0000000000..77a1aea9db
--- /dev/null
+++ b/qpid/dotnet/Qpid.Codec/IProtocolDecoderOutput.cs
@@ -0,0 +1,35 @@
+/*
+ *
+ * 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.
+ *
+ */
+namespace Apache.Qpid.Codec
+{
+ public interface IProtocolDecoderOutput
+ {
+ /// <summary>
+ /// Callback for {@link ProtocolDecoder} to generate decoded messages.
+ /// {@link ProtocolDecoder} must call {@link #write(Object)} for each
+ /// decoded messages.
+ /// </summary>
+ /// <param name="message">the decoded message</param>
+ void Write(object message);
+ }
+}
+
+
diff --git a/qpid/dotnet/Qpid.Codec/IProtocolEncoder.cs b/qpid/dotnet/Qpid.Codec/IProtocolEncoder.cs
new file mode 100644
index 0000000000..a16f2ad9d6
--- /dev/null
+++ b/qpid/dotnet/Qpid.Codec/IProtocolEncoder.cs
@@ -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.
+ *
+ */
+using System;
+
+namespace Apache.Qpid.Codec
+{
+ public interface IProtocolEncoder : IDisposable
+ {
+ /// <summary>
+ /// Encodes higher-level message objects into binary or protocol-specific data.
+ /// MINA invokes {@link #encode(IoSession, Object, ProtocolEncoderOutput)}
+ /// method with message which is popped from the session write queue, and then
+ /// the encoder implementation puts encoded {@link ByteBuffer}s into
+ /// {@link ProtocolEncoderOutput}.
+ /// </summary>
+ /// <param name="message"></param>
+ /// <param name="output"></param>
+ /// <exception cref="Exception">if the message violated protocol specification</exception>
+ void Encode(Object message, IProtocolEncoderOutput output);
+ }
+}
+
+
diff --git a/qpid/dotnet/Qpid.Codec/IProtocolEncoderOutput.cs b/qpid/dotnet/Qpid.Codec/IProtocolEncoderOutput.cs
new file mode 100644
index 0000000000..70f9be38dc
--- /dev/null
+++ b/qpid/dotnet/Qpid.Codec/IProtocolEncoderOutput.cs
@@ -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.
+ *
+ */
+using Apache.Qpid.Buffer;
+
+namespace Apache.Qpid.Codec
+{
+ public interface IProtocolEncoderOutput
+ {
+ /// <summary>
+ /// Callback for {@link ProtocolEncoder} to generate encoded
+ /// {@link ByteBuffer}s. {@link ProtocolEncoder} must call
+ /// {@link #write(ByteBuffer)} for each decoded messages.
+ /// </summary>
+ /// <param name="buf">the buffer which contains encoded data</param>
+ void Write(ByteBuffer buf);
+ }
+}
+
+
diff --git a/qpid/dotnet/Qpid.Codec/Properties/AssemblyInfo.cs b/qpid/dotnet/Qpid.Codec/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000000..5261a62ec5
--- /dev/null
+++ b/qpid/dotnet/Qpid.Codec/Properties/AssemblyInfo.cs
@@ -0,0 +1,53 @@
+/*
+ *
+ * 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.
+ *
+ */
+using System.Reflection;
+using System.Runtime.InteropServices;
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("Apache.Qpid.Codec")]
+[assembly: AssemblyDescription("Built from svn revision number: ")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Apache Software Foundation")]
+[assembly: AssemblyProduct("Apache.Qpid.Codec")]
+[assembly: AssemblyCopyright("Apache Software Foundation")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("8bfe84f8-cd88-48f7-b0d2-0010411a14e5")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Revision and Build Numbers
+// by using the '*' as shown below:
+[assembly: AssemblyVersion("0.5.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/qpid/dotnet/Qpid.Codec/ProtocolCodecException.cs b/qpid/dotnet/Qpid.Codec/ProtocolCodecException.cs
new file mode 100644
index 0000000000..49678d2c11
--- /dev/null
+++ b/qpid/dotnet/Qpid.Codec/ProtocolCodecException.cs
@@ -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.
+ *
+ */
+using System;
+using System.Runtime.Serialization;
+
+namespace Apache.Qpid.Codec
+{
+ [Serializable]
+ public class ProtocolCodecException : Exception
+ {
+ public ProtocolCodecException() : base()
+ {
+ }
+
+ public ProtocolCodecException(string message) : base(message)
+ {
+ }
+
+ public ProtocolCodecException(Exception cause) : base("Codec Exception", cause)
+ {
+ }
+
+ protected ProtocolCodecException(SerializationInfo info, StreamingContext ctxt)
+ : base(info, ctxt)
+ {
+ }
+ }
+}
+
+
+
diff --git a/qpid/dotnet/Qpid.Codec/ProtocolDecoderException.cs b/qpid/dotnet/Qpid.Codec/ProtocolDecoderException.cs
new file mode 100644
index 0000000000..8e7e6da145
--- /dev/null
+++ b/qpid/dotnet/Qpid.Codec/ProtocolDecoderException.cs
@@ -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.
+ *
+ */
+using System;
+using System.Runtime.Serialization;
+
+namespace Apache.Qpid.Codec
+{
+ [Serializable]
+ public class ProtocolDecoderException : ProtocolCodecException
+ {
+ private string _hexdump;
+
+ public ProtocolDecoderException() : base()
+ {
+ }
+
+ public ProtocolDecoderException(string message) : base(message)
+ {
+ }
+
+ public ProtocolDecoderException(Exception cause) : base(cause)
+ {
+ }
+
+ protected ProtocolDecoderException(SerializationInfo info, StreamingContext ctxt)
+ : base(info, ctxt)
+ {
+ _hexdump = info.GetString("HexDump");
+ }
+
+ public string HexDump
+ {
+ get
+ {
+ return _hexdump;
+ }
+ set
+ {
+ _hexdump = value;
+ }
+ }
+
+ public override void GetObjectData(SerializationInfo info, StreamingContext context)
+ {
+ base.GetObjectData(info, context);
+ info.AddValue("HexDump", _hexdump);
+ }
+ }
+}
+
+
+
diff --git a/qpid/dotnet/Qpid.Codec/ProtocolEncoderException.cs b/qpid/dotnet/Qpid.Codec/ProtocolEncoderException.cs
new file mode 100644
index 0000000000..ac565a308b
--- /dev/null
+++ b/qpid/dotnet/Qpid.Codec/ProtocolEncoderException.cs
@@ -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.
+ *
+ */
+using System;
+using System.Runtime.Serialization;
+
+namespace Apache.Qpid.Codec
+{
+ [Serializable]
+ public class ProtocolEncoderException : ProtocolCodecException
+ {
+ public ProtocolEncoderException() : base()
+ {
+ }
+
+ public ProtocolEncoderException(string message) : base(message)
+ {
+ }
+
+ public ProtocolEncoderException(Exception cause) : base(cause)
+ {
+ }
+
+ protected ProtocolEncoderException(SerializationInfo info, StreamingContext ctxt)
+ : base(info, ctxt)
+ {
+ }
+ }
+}
+
+
+
diff --git a/qpid/dotnet/Qpid.Codec/Qpid.Codec.csproj b/qpid/dotnet/Qpid.Codec/Qpid.Codec.csproj
new file mode 100644
index 0000000000..a0217cffa3
--- /dev/null
+++ b/qpid/dotnet/Qpid.Codec/Qpid.Codec.csproj
@@ -0,0 +1,82 @@
+<!--
+
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+
+-->
+
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProductVersion>8.0.50727</ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{22D0D0C2-77AF-4DE3-B456-7FF3893F9F88}</ProjectGuid>
+ <OutputType>Library</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>Apache.Qpid.Codec</RootNamespace>
+ <AssemblyName>Apache.Qpid.Codec</AssemblyName>
+ <FileUpgradeFlags>
+ </FileUpgradeFlags>
+ <OldToolsVersion>2.0</OldToolsVersion>
+ <UpgradeBackupLocation>
+ </UpgradeBackupLocation>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>..\bin\net-2.0\debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>..\bin\net-2.0\release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="log4net, Version=1.2.0.30714, Culture=neutral, PublicKeyToken=500ffcafb14f92df">
+ <SpecificVersion>False</SpecificVersion>
+ <HintPath>..\Qpid.Common\lib\log4net\log4net.dll</HintPath>
+ </Reference>
+ <Reference Include="System" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="**\*.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\Qpid.Buffer\Qpid.Buffer.csproj">
+ <Project>{44384DF2-B0A4-4580-BDBC-EE4BAA87D995}</Project>
+ <Name>Qpid.Buffer</Name>
+ </ProjectReference>
+ </ItemGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+ <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
+ Other similar extension points exist, see Microsoft.Common.targets.
+ <Target Name="BeforeBuild">
+ </Target>
+ <Target Name="AfterBuild">
+ </Target>
+ -->
+</Project>
diff --git a/qpid/dotnet/Qpid.Codec/Support/SimpleProtocolDecoderOutput.cs b/qpid/dotnet/Qpid.Codec/Support/SimpleProtocolDecoderOutput.cs
new file mode 100644
index 0000000000..0a4ff10ff0
--- /dev/null
+++ b/qpid/dotnet/Qpid.Codec/Support/SimpleProtocolDecoderOutput.cs
@@ -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.
+ *
+ */
+using System.Collections;
+
+namespace Apache.Qpid.Codec.Support
+{
+ public class SimpleProtocolDecoderOutput : IProtocolDecoderOutput
+ {
+ private readonly Queue _messageQueue = new Queue();
+
+ public Queue MessageQueue
+ {
+ get
+ {
+ return _messageQueue;
+ }
+ }
+
+ public void Write(object message)
+ {
+ _messageQueue.Enqueue(message);
+ }
+ }
+}
+
+
diff --git a/qpid/dotnet/Qpid.Codec/Support/SimpleProtocolEncoderOutput.cs b/qpid/dotnet/Qpid.Codec/Support/SimpleProtocolEncoderOutput.cs
new file mode 100644
index 0000000000..2e4224ef98
--- /dev/null
+++ b/qpid/dotnet/Qpid.Codec/Support/SimpleProtocolEncoderOutput.cs
@@ -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.
+ *
+ */
+using System.Collections;
+using Apache.Qpid.Buffer;
+
+namespace Apache.Qpid.Codec.Support
+{
+ public abstract class SimpleProtocolEncoderOutput : IProtocolEncoderOutput
+ {
+ private readonly Queue _bufferQueue = new Queue();
+
+ public Queue BufferQueue
+ {
+ get
+ {
+ return _bufferQueue;
+ }
+ }
+
+ public void Write(ByteBuffer buf)
+ {
+ _bufferQueue.Enqueue(buf);
+ }
+ }
+}
diff --git a/qpid/dotnet/Qpid.Codec/default.build b/qpid/dotnet/Qpid.Codec/default.build
new file mode 100644
index 0000000000..dd59df7d6a
--- /dev/null
+++ b/qpid/dotnet/Qpid.Codec/default.build
@@ -0,0 +1,47 @@
+<?xml version="1.0"?>
+<!--
+
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+
+-->
+
+<project name="Apache.Qpid.Codec" default="build">
+ <!--
+ Properties that come from master build file
+ - build.dir: root directory for build
+ - build.debug: true if building debug release
+ - build.defines: variables to define during build
+ -->
+
+ <target name="build">
+ <csc target="library"
+ define="${build.defines}"
+ debug="${build.debug}"
+ output="${build.dir}/${project::get-name()}.dll">
+
+ <sources>
+ <include name="**/*.cs" />
+ </sources>
+ <references>
+ <include name="${build.dir}/log4net.dll" />
+ <include name="${build.dir}/Apache.Qpid.Buffer.dll" />
+ </references>
+ </csc>
+ </target>
+</project>
+
diff --git a/qpid/dotnet/Qpid.Common.Tests/Properties/AssemblyInfo.cs b/qpid/dotnet/Qpid.Common.Tests/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000000..2516a73035
--- /dev/null
+++ b/qpid/dotnet/Qpid.Common.Tests/Properties/AssemblyInfo.cs
@@ -0,0 +1,54 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+using System.Reflection;
+using System.Runtime.InteropServices;
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("Apache.Qpid.Common.Tests")]
+[assembly: AssemblyDescription("Built from svn revision number: ")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Apache Software Foundation")]
+[assembly: AssemblyProduct("Apache.Qpid.Common.Tests")]
+[assembly: AssemblyCopyright("Apache Software Foundation")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("2c0d906c-375d-4b04-8ad0-a22fcb4e7337")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Revision and Build Numbers
+// by using the '*' as shown below:
+[assembly: AssemblyVersion("0.5.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/qpid/dotnet/Qpid.Common.Tests/Qpid.Common.Tests.csproj b/qpid/dotnet/Qpid.Common.Tests/Qpid.Common.Tests.csproj
new file mode 100644
index 0000000000..c99217cc51
--- /dev/null
+++ b/qpid/dotnet/Qpid.Common.Tests/Qpid.Common.Tests.csproj
@@ -0,0 +1,87 @@
+<!--
+
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+
+-->
+
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProductVersion>8.0.50727</ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{F83624B0-762B-4D82-900D-FF4C1B36E36E}</ProjectGuid>
+ <OutputType>Library</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>Apache.Qpid.Tests</RootNamespace>
+ <AssemblyName>Apache.Qpid.Common.Tests</AssemblyName>
+ <FileUpgradeFlags>
+ </FileUpgradeFlags>
+ <OldToolsVersion>2.0</OldToolsVersion>
+ <UpgradeBackupLocation>
+ </UpgradeBackupLocation>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>..\bin\net-2.0\debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ <UseVSHostingProcess>true</UseVSHostingProcess>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>..\bin\net-2.0\release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="nunit.framework, Version=2.2.6.0, Culture=neutral, PublicKeyToken=96d09a1eb7f44a77">
+ <SpecificVersion>False</SpecificVersion>
+ <HintPath>..\Qpid.Client.Tests\lib\nunit\nunit.framework.dll</HintPath>
+ </Reference>
+ <Reference Include="System" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="**\*.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\Qpid.Buffer\Qpid.Buffer.csproj">
+ <Project>{44384DF2-B0A4-4580-BDBC-EE4BAA87D995}</Project>
+ <Name>Qpid.Buffer</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\Qpid.Common\Qpid.Common.csproj">
+ <Project>{77064C42-24D2-4CEB-9EA2-0EF481A43205}</Project>
+ <Name>Qpid.Common</Name>
+ </ProjectReference>
+ </ItemGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+ <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
+ Other similar extension points exist, see Microsoft.Common.targets.
+ <Target Name="BeforeBuild">
+ </Target>
+ <Target Name="AfterBuild">
+ </Target>
+ -->
+</Project>
diff --git a/qpid/dotnet/Qpid.Common.Tests/Qpid/Collections/TestConsumerProducerQueue.cs b/qpid/dotnet/Qpid.Common.Tests/Qpid/Collections/TestConsumerProducerQueue.cs
new file mode 100644
index 0000000000..3e19508bac
--- /dev/null
+++ b/qpid/dotnet/Qpid.Common.Tests/Qpid/Collections/TestConsumerProducerQueue.cs
@@ -0,0 +1,85 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+using System;
+using System.Collections;
+using System.Text;
+using System.Threading;
+using NUnit.Framework;
+using Apache.Qpid.Collections;
+
+namespace Apache.Qpid.Collections.Tests
+{
+ [TestFixture]
+ public class TestConsumerProducerQueue
+ {
+ private ConsumerProducerQueue _queue;
+
+ [SetUp]
+ public void SetUp()
+ {
+ _queue = new ConsumerProducerQueue();
+ }
+
+ [Test]
+ public void CanDequeueWithInifiniteWait()
+ {
+ Thread producer = new Thread(new ThreadStart(ProduceFive));
+ producer.Start();
+ for ( int i = 0; i < 5; i++ )
+ {
+ object item = _queue.Dequeue();
+ Assert.IsNotNull(item);
+ }
+ }
+
+ [Test]
+ public void ReturnsNullOnDequeueTimeout()
+ {
+ // queue is empty
+ Assert.IsNull(_queue.Dequeue(500));
+ }
+
+ [Test]
+ public void DequeueTillEmpty()
+ {
+ _queue.Enqueue(1);
+ _queue.Enqueue(2);
+ _queue.Enqueue(3);
+ Assert.AreEqual(1, _queue.Dequeue());
+ Assert.AreEqual(2, _queue.Dequeue());
+ Assert.AreEqual(3, _queue.Dequeue());
+ // no messages in queue, will timeout
+ Assert.IsNull(_queue.Dequeue(500));
+ }
+
+
+ private void ProduceFive()
+ {
+ Thread.Sleep(1000);
+ _queue.Enqueue("test item 1");
+ _queue.Enqueue("test item 2");
+ _queue.Enqueue("test item 3");
+ Thread.Sleep(0);
+ _queue.Enqueue("test item 4");
+ _queue.Enqueue("test item 5");
+ }
+ }
+}
diff --git a/qpid/dotnet/Qpid.Common.Tests/Qpid/Collections/TestLinkedHashtable.cs b/qpid/dotnet/Qpid.Common.Tests/Qpid/Collections/TestLinkedHashtable.cs
new file mode 100644
index 0000000000..dbbc98a2e6
--- /dev/null
+++ b/qpid/dotnet/Qpid.Common.Tests/Qpid/Collections/TestLinkedHashtable.cs
@@ -0,0 +1,83 @@
+/*
+ *
+ * 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.
+ *
+ */
+using System;
+using System.Collections;
+using System.Text;
+using NUnit.Framework;
+
+namespace Apache.Qpid.Collections
+{
+ [TestFixture]
+ public class TestLinkedHashtable
+ {
+ [Test]
+ public void Test1()
+ {
+ LinkedHashtable table = new LinkedHashtable();
+ table["Super"] = "Ayr";
+ table["Ayr"] = "United";
+ table["Fred"] = "Wilma";
+ table["Dumbarton"] = "Gubbed";
+ dumpDictionary(table);
+
+ Console.WriteLine("\nRemoving XXX (non-existant)");
+ table.Remove("XXX");
+ dumpDictionary(table);
+
+ Console.WriteLine("\nRemoving Fred");
+ table.Remove("Fred");
+ dumpDictionary(table);
+
+ Console.WriteLine("\nMoving Dumbarton to head");
+ table.MoveToHead("Dumbarton");
+ dumpDictionary(table);
+ }
+
+ private static void dumpDictionary(LinkedHashtable table)
+ {
+ foreach (DictionaryEntry o in table)
+ {
+ Console.WriteLine(string.Format("Item: key={0} value={1}", o.Key, o.Value));
+ }
+
+ Console.WriteLine("keys are " + InspectCollection(table.Keys));
+ Console.WriteLine("values are " + InspectCollection(table.Values));
+ }
+
+ static string InspectCollection(ICollection collection)
+ {
+ StringBuilder sb = null;
+ foreach (object o in collection)
+ {
+ if (sb == null)
+ {
+ sb = new StringBuilder(o.ToString());
+ }
+ else
+ {
+ sb.Append(", ");
+ sb.Append(o.ToString());
+ }
+ }
+ return sb.ToString();
+ }
+ }
+}
diff --git a/qpid/dotnet/Qpid.Common.Tests/Qpid/Framing/TestAMQType.cs b/qpid/dotnet/Qpid.Common.Tests/Qpid/Framing/TestAMQType.cs
new file mode 100644
index 0000000000..23cb71c9f8
--- /dev/null
+++ b/qpid/dotnet/Qpid.Common.Tests/Qpid/Framing/TestAMQType.cs
@@ -0,0 +1,270 @@
+/*
+ *
+ * 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.
+ *
+ */
+using System;
+using NUnit.Framework;
+using Apache.Qpid.Buffer;
+using Apache.Qpid.Framing;
+
+namespace Apache.Qpid.Framing.Tests
+{
+ [TestFixture]
+ public class TestAMQType
+ {
+
+ #region LONG_STRING tests
+ [Test]
+ public void LONG_STRING_ReadWrite()
+ {
+ AMQType type = AMQType.LONG_STRING;
+ ByteBuffer buffer = ByteBuffer.Allocate(0x1000);
+ const string VALUE = "simple string 1";
+
+ type.WriteToBuffer(VALUE, buffer);
+ buffer.Flip();
+ buffer.Rewind();
+ AMQTypedValue value = AMQTypedValue.ReadFromBuffer(buffer);
+ Assert.AreEqual(VALUE, value.Value);
+ }
+ #endregion // LONG_STRING tests
+
+ #region UINT32 tests
+ [Test]
+ public void UINT32_CanGetEncodingSize()
+ {
+ AMQType type = AMQType.UINT32;
+ Assert.AreEqual(4, type.GetEncodingSize(1234443));
+ }
+
+ [Test]
+ public void UINT32_ToNativeValue()
+ {
+ AMQType type = AMQType.UINT32;
+ Assert.AreEqual(1, type.ToNativeValue(1));
+ Assert.AreEqual(1, type.ToNativeValue((short)1));
+ Assert.AreEqual(1, type.ToNativeValue((byte)1));
+ Assert.AreEqual(1, type.ToNativeValue("1"));
+
+ try
+ {
+ Assert.AreEqual(1, type.ToNativeValue("adasdads"));
+ Assert.Fail("Invalid format allowed");
+ } catch ( FormatException )
+ {
+ }
+ }
+
+ [Test]
+ public void UINT32_ReadWrite()
+ {
+ AMQType type = AMQType.UINT32;
+ ByteBuffer buffer = ByteBuffer.Allocate(0x1000);
+ const uint VALUE = 0xFFEEDDCC;
+
+ type.WriteToBuffer(VALUE, buffer);
+ buffer.Flip();
+ buffer.Rewind();
+ AMQTypedValue value = AMQTypedValue.ReadFromBuffer(buffer);
+ Assert.AreEqual(VALUE, value.Value);
+ }
+ #endregion // UINT32 Tests
+
+ #region VOID Tests
+ [Test]
+ public void VOID_CanGetEncodingSize()
+ {
+ AMQType type = AMQType.VOID;
+ Assert.AreEqual(0, type.GetEncodingSize(null));
+ }
+
+ [Test]
+ public void VOID_ToNativeValue()
+ {
+ AMQType type = AMQType.VOID;
+ Assert.IsNull(type.ToNativeValue(null));
+
+ try
+ {
+ type.ToNativeValue("asdasd");
+ Assert.Fail("converted invalid value");
+ } catch (FormatException)
+ {
+ }
+ }
+
+ [Test]
+ public void VOID_ReadWrite()
+ {
+ AMQType type = AMQType.VOID;
+ ByteBuffer buffer = ByteBuffer.Allocate(0x1000);
+
+ type.WriteToBuffer(null, buffer);
+ buffer.Flip();
+ buffer.Rewind();
+ AMQTypedValue value = AMQTypedValue.ReadFromBuffer(buffer);
+ Assert.AreEqual(null, value.Value);
+ }
+
+ #endregion // VOID Tests
+
+ #region BOOLEAN Tests
+ [Test]
+ public void BOOLEAN_CanGetEncodingSize()
+ {
+ AMQType type = AMQType.BOOLEAN;
+ Assert.AreEqual(1, type.GetEncodingSize(true));
+ }
+
+ [Test]
+ public void BOOLEAN_ToNativeValue()
+ {
+ AMQType type = AMQType.BOOLEAN;
+ Assert.AreEqual(true, type.ToNativeValue(true));
+ Assert.AreEqual(false, type.ToNativeValue("false"));
+
+ try
+ {
+ type.ToNativeValue("asdasd");
+ Assert.Fail("converted invalid value");
+ } catch ( FormatException )
+ {
+ }
+ }
+
+ [Test]
+ public void BOOLEAN_ReadWrite()
+ {
+ AMQType type = AMQType.BOOLEAN;
+ ByteBuffer buffer = ByteBuffer.Allocate(0x1000);
+
+ type.WriteToBuffer(true, buffer);
+ buffer.Flip();
+ buffer.Rewind();
+ AMQTypedValue value = AMQTypedValue.ReadFromBuffer(buffer);
+ Assert.AreEqual(true, value.Value);
+ }
+ #endregion // BOOLEAN Tests
+
+ #region INT16 tests
+ [Test]
+ public void INT16_ReadWrite()
+ {
+ AMQType type = AMQType.INT16;
+ ByteBuffer buffer = ByteBuffer.Allocate(0x1000);
+ const short VALUE = -32765;
+
+ type.WriteToBuffer(VALUE, buffer);
+ buffer.Flip();
+ buffer.Rewind();
+ AMQTypedValue value = AMQTypedValue.ReadFromBuffer(buffer);
+ Assert.AreEqual(VALUE, value.Value);
+ }
+ //public void UINT16_ReadWrite()
+ //{
+ // AMQType type = AMQType.UINT16;
+ // ByteBuffer buffer = ByteBuffer.Allocate(0x1000);
+ // const ushort VALUE = 64321;
+
+ // type.WriteToBuffer(VALUE, buffer);
+ // buffer.Flip();
+ // buffer.Rewind();
+ // AMQTypedValue value = AMQTypedValue.ReadFromBuffer(buffer);
+ // Assert.AreEqual(VALUE, value.Value);
+ //}
+ #endregion // INT16 Tests
+
+ #region INT32 tests
+ [Test]
+ public void INT32_ReadWrite()
+ {
+ AMQType type = AMQType.INT32;
+ ByteBuffer buffer = ByteBuffer.Allocate(0x1000);
+ const int VALUE = -39273563;
+
+ type.WriteToBuffer(VALUE, buffer);
+ buffer.Flip();
+ buffer.Rewind();
+ AMQTypedValue value = AMQTypedValue.ReadFromBuffer(buffer);
+ Assert.AreEqual(VALUE, value.Value);
+ }
+ #endregion // INT32 Tests
+
+ #region INT64 tests
+ [Test]
+ public void INT64_ReadWrite()
+ {
+ AMQType type = AMQType.INT64;
+ ByteBuffer buffer = ByteBuffer.Allocate(0x1000);
+ const long VALUE = -(2^43+1233123);
+
+ type.WriteToBuffer(VALUE, buffer);
+ buffer.Flip();
+ buffer.Rewind();
+ AMQTypedValue value = AMQTypedValue.ReadFromBuffer(buffer);
+ Assert.AreEqual(VALUE, value.Value);
+ }
+ [Test]
+ public void UINT64_ReadWrite()
+ {
+ AMQType type = AMQType.UINT64;
+ ByteBuffer buffer = ByteBuffer.Allocate(0x1000);
+ const ulong VALUE = (2 ^ 61 + 1233123);
+
+ type.WriteToBuffer(VALUE, buffer);
+ buffer.Flip();
+ buffer.Rewind();
+ AMQTypedValue value = AMQTypedValue.ReadFromBuffer(buffer);
+ Assert.AreEqual(VALUE, value.Value);
+ }
+ #endregion // INT64 Tests
+
+ #region FLOAT tests
+ [Test]
+ public void FLOAT_ReadWrite()
+ {
+ AMQType type = AMQType.FLOAT;
+ ByteBuffer buffer = ByteBuffer.Allocate(0x1000);
+ const float VALUE = 1.2345000E-035f;
+
+ type.WriteToBuffer(VALUE, buffer);
+ buffer.Flip();
+ buffer.Rewind();
+ AMQTypedValue value = AMQTypedValue.ReadFromBuffer(buffer);
+ Assert.AreEqual(VALUE, value.Value);
+ }
+ #endregion // FLOAT Tests
+
+ #region DOUBLE tests
+ [Test]
+ public void DOUBLE_ReadWrite()
+ {
+ AMQType type = AMQType.DOUBLE;
+ ByteBuffer buffer = ByteBuffer.Allocate(0x1000);
+ const double VALUE = 1.2345000E-045;
+
+ type.WriteToBuffer(VALUE, buffer);
+ buffer.Flip();
+ buffer.Rewind();
+ AMQTypedValue value = AMQTypedValue.ReadFromBuffer(buffer);
+ Assert.AreEqual(VALUE, value.Value);
+ }
+ #endregion // FLOAT Tests
+ }
+}
diff --git a/qpid/dotnet/Qpid.Common.Tests/Qpid/Framing/TestEncodingUtils.cs b/qpid/dotnet/Qpid.Common.Tests/Qpid/Framing/TestEncodingUtils.cs
new file mode 100644
index 0000000000..a8202dc70d
--- /dev/null
+++ b/qpid/dotnet/Qpid.Common.Tests/Qpid/Framing/TestEncodingUtils.cs
@@ -0,0 +1,60 @@
+/*
+ *
+ * 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.
+ *
+ */
+using System;
+using NUnit.Framework;
+using Apache.Qpid.Buffer;
+using Apache.Qpid.Framing;
+
+namespace Apache.Qpid.Framing.Tests
+{
+ [TestFixture]
+ public class TestEncodingUtils
+ {
+ [Test]
+ public void CanReadLongAsShortString()
+ {
+ ByteBuffer buffer = ByteBuffer.Allocate(0x1000);
+ EncodingUtils.WriteShortStringBytes(buffer, "98878122");
+ buffer.Flip();
+ long value = EncodingUtils.ReadLongAsShortString(buffer);
+ Assert.AreEqual(98878122, value);
+ }
+ [Test]
+ public void CanReadLongAsShortStringNegative()
+ {
+ ByteBuffer buffer = ByteBuffer.Allocate(0x1000);
+ EncodingUtils.WriteShortStringBytes(buffer, "-98878122");
+ buffer.Flip();
+ long value = EncodingUtils.ReadLongAsShortString(buffer);
+ Assert.AreEqual(-98878122, value);
+ }
+ [Test]
+ public void CanReadLongAsShortStringEmpty()
+ {
+ ByteBuffer buffer = ByteBuffer.Allocate(0x1000);
+ EncodingUtils.WriteShortStringBytes(buffer, "");
+ buffer.Flip();
+ long value = EncodingUtils.ReadLongAsShortString(buffer);
+ Assert.AreEqual(0, value);
+ }
+
+ }
+}
diff --git a/qpid/dotnet/Qpid.Common.Tests/default.build b/qpid/dotnet/Qpid.Common.Tests/default.build
new file mode 100644
index 0000000000..a97c0282c2
--- /dev/null
+++ b/qpid/dotnet/Qpid.Common.Tests/default.build
@@ -0,0 +1,52 @@
+<?xml version="1.0"?>
+<!--
+
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+
+-->
+
+<project name="Apache.Qpid.Common" default="test">
+
+ <target name="build">
+ <csc target="library"
+ define="${build.defines}"
+ warnaserror="true" debug="${build.debug}"
+ output="${build.dir}/${project::get-name()}.Tests.dll">
+
+ <sources>
+ <include name="**/*.cs" />
+ </sources>
+ <references>
+ <include name="${build.dir}/log4net.dll" />
+ <include name="${build.dir}/nunit.framework.dll" />
+ <include name="${build.dir}/${project::get-name()}.dll" />
+ <include name="${build.dir}/Apache.Qpid.Codec.dll" />
+ <include name="${build.dir}/Apache.Qpid.Messaging.dll" />
+ <include name="${build.dir}/Apache.Qpid.Buffer.dll" />
+ </references>
+
+ </csc>
+ </target>
+ <target name="test" depends="build">
+ <nunit2>
+ <formatter type="${nant.formatter}" usefile="false" />
+ <test assemblyname="${build.dir}/${project::get-name()}.Tests.dll" />
+ </nunit2>
+ </target>
+</project>
+
diff --git a/qpid/dotnet/Qpid.Common/AMQChannelClosedException.cs b/qpid/dotnet/Qpid.Common/AMQChannelClosedException.cs
new file mode 100644
index 0000000000..98c6966cd1
--- /dev/null
+++ b/qpid/dotnet/Qpid.Common/AMQChannelClosedException.cs
@@ -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.
+ *
+ */
+
+using System;
+using System.Runtime.Serialization;
+
+namespace Apache.Qpid
+{
+ [Serializable]
+ public class AMQChannelClosedException : AMQException
+ {
+ public AMQChannelClosedException(int errorCode, string message)
+ : base(errorCode, message)
+ {
+ }
+
+ protected AMQChannelClosedException(SerializationInfo info, StreamingContext ctxt)
+ : base(info, ctxt)
+ {
+ }
+ }
+}
diff --git a/qpid/dotnet/Qpid.Common/AMQConnectionClosedException.cs b/qpid/dotnet/Qpid.Common/AMQConnectionClosedException.cs
new file mode 100644
index 0000000000..136131144b
--- /dev/null
+++ b/qpid/dotnet/Qpid.Common/AMQConnectionClosedException.cs
@@ -0,0 +1,51 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+using System;
+using System.Runtime.Serialization;
+
+namespace Apache.Qpid
+{
+ /// <summary>
+ /// AMQConnectionClosedException indicates that a connection has been closed.
+ ///
+ /// <p/>This exception is really used as an event, in order that the method handler that raises it creates an event
+ /// which is propagated to the io handler, in order to notify it of the connection closure.
+ ///
+ /// <p/><table id="crc"><caption>CRC Card</caption>
+ /// <tr><th> Responsibilities <th> Collaborations
+ /// <tr><td> Represents a the closure of a connection.
+ /// </table>
+ /// </summary>
+ [Serializable]
+ public class AMQConnectionClosedException : AMQException
+ {
+ public AMQConnectionClosedException(int errorCode, string message)
+ : base(errorCode, message)
+ {
+ }
+
+ protected AMQConnectionClosedException(SerializationInfo info, StreamingContext ctxt)
+ : base(info, ctxt)
+ {
+ }
+ }
+}
diff --git a/qpid/dotnet/Qpid.Common/AMQDisconnectedException.cs b/qpid/dotnet/Qpid.Common/AMQDisconnectedException.cs
new file mode 100644
index 0000000000..b5c4d544cd
--- /dev/null
+++ b/qpid/dotnet/Qpid.Common/AMQDisconnectedException.cs
@@ -0,0 +1,45 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+using System;
+using System.Runtime.Serialization;
+
+namespace Apache.Qpid
+{
+ [Serializable]
+ public class AMQDisconnectedException : AMQException
+ {
+ public AMQDisconnectedException(int errorCode, string message)
+ : base(errorCode, message)
+ {
+ }
+
+ public AMQDisconnectedException(string message)
+ : base(message)
+ {
+ }
+
+ protected AMQDisconnectedException(SerializationInfo info, StreamingContext ctxt)
+ : base(info, ctxt)
+ {
+ }
+ }
+}
diff --git a/qpid/dotnet/Qpid.Common/AMQException.cs b/qpid/dotnet/Qpid.Common/AMQException.cs
new file mode 100644
index 0000000000..f9f7158a26
--- /dev/null
+++ b/qpid/dotnet/Qpid.Common/AMQException.cs
@@ -0,0 +1,149 @@
+/*
+ *
+ * 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.
+ *
+ */
+using System;
+using System.Runtime.Serialization;
+using log4net;
+
+namespace Apache.Qpid
+{
+ /// <summary>
+ /// The generic AMQ exception.
+ /// </summary>
+ [Serializable]
+ public class AMQException : Exception
+ {
+ private int _errorCode;
+
+ public AMQException(string message)
+ : base(message)
+ {
+ }
+
+ public AMQException(string message, Exception innerException)
+ : base(message, innerException)
+ {
+ }
+
+ public AMQException(int errorCode, string message)
+ : base(message)
+ {
+ _errorCode = errorCode;
+ }
+
+ public AMQException(int errorCode, string message, Exception innerException)
+ : base(message, innerException)
+ {
+ _errorCode = errorCode;
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="T:AMQException"/> class, with a logger that will
+ /// be used to output log information upon construction. This saves having to log separately.
+ /// </summary>
+ /// <param name="logger">The logger.</param>
+ /// <param name="message">The message.</param>
+ public AMQException(ILog logger, string message)
+ : base(message)
+ {
+ logger.Error(message);
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="T:AMQException"/> class, with a logger that will
+ /// be used to output log information upon construction. This saves having to log separately.
+ /// </summary>
+ /// <param name="logger">The logger.</param>
+ /// <param name="message">The message.</param>
+ /// <param name="innerException">The root cause</param>
+ public AMQException(ILog logger, string message, Exception innerException)
+ : base(message, innerException)
+ {
+ logger.Error(message, innerException);
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="T:AMQException"/> class, with a logger that will
+ /// be used to output log information upon construction. This saves having to log separately.
+ /// </summary>
+ /// <param name="logger">The logger.</param>
+ /// <param name="message">The message.</param>
+ /// <param name="errorCode">The AMQ error code. See RFC 006 for details of error codes</param>
+ public AMQException(ILog logger, int errorCode, string message)
+ : this(errorCode, message)
+ {
+ logger.Error(message);
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="T:AMQException"/> class, with a logger that will
+ /// be used to output log information upon construction. This saves having to log separately.
+ /// </summary>
+ /// <param name="logger">The logger.</param>
+ /// <param name="message">The message.</param>
+ /// <param name="errorCode">The AMQ error code. See RFC 006 for details of error codes</param>
+ /// <param name="innerException">The root cause</param>
+ public AMQException(ILog logger, int errorCode, string message, Exception innerException)
+ : this(errorCode, message, innerException)
+ {
+ logger.Error(message, innerException);
+ }
+
+ /// <summary>
+ /// Serialization Constructor
+ /// </summary>
+ /// <param name="info">SerializationInfo object</param>
+ /// <param name="ctxt">StreamingContext object</param>
+ protected AMQException(SerializationInfo info, StreamingContext ctxt)
+ : base(info, ctxt)
+ {
+ _errorCode = info.GetInt32("ErrorCode");
+ }
+
+ /// <summary>
+ /// ISerializable implementation of GetObjectData()
+ /// </summary>
+ /// <param name="info">SerializationInfo object</param>
+ /// <param name="ctxt">StreamingContext object</param>
+ public override void GetObjectData(SerializationInfo info, StreamingContext context)
+ {
+ base.GetObjectData(info, context);
+ info.AddValue("ErrorCode", _errorCode);
+ }
+
+
+ /// <summary>
+ /// Gets or sets the error code. See RFC 006 for details of error codes.
+ /// </summary>
+ /// <value>The error code.</value>
+ public int ErrorCode
+ {
+ get
+ {
+ return _errorCode;
+ }
+ set
+ {
+ _errorCode = value;
+ }
+ }
+
+ }
+}
diff --git a/qpid/dotnet/Qpid.Common/AMQInvalidArgumentException.cs b/qpid/dotnet/Qpid.Common/AMQInvalidArgumentException.cs
new file mode 100644
index 0000000000..831f7bab0e
--- /dev/null
+++ b/qpid/dotnet/Qpid.Common/AMQInvalidArgumentException.cs
@@ -0,0 +1,46 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+using System;
+using System.Runtime.Serialization;
+
+using Apache.Qpid.Protocol;
+
+namespace Apache.Qpid
+{
+ /// <summary>
+ /// Thrown when an invalid argument was supplied to the broker
+ /// </summary>
+ [Serializable]
+ public class AMQInvalidArgumentException : AMQException
+ {
+ public AMQInvalidArgumentException(string message)
+ : base(AMQConstant.INVALID_ARGUMENT.Code, message, null)
+ {
+ }
+
+ protected AMQInvalidArgumentException(SerializationInfo info, StreamingContext ctxt)
+ : base(info, ctxt)
+ {
+ }
+
+ }
+}
diff --git a/qpid/dotnet/Qpid.Common/AMQInvalidRoutingKeyException.cs b/qpid/dotnet/Qpid.Common/AMQInvalidRoutingKeyException.cs
new file mode 100644
index 0000000000..a3ce813d1b
--- /dev/null
+++ b/qpid/dotnet/Qpid.Common/AMQInvalidRoutingKeyException.cs
@@ -0,0 +1,46 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+using System;
+using System.Runtime.Serialization;
+
+using Apache.Qpid.Protocol;
+
+namespace Apache.Qpid
+{
+ /// <summary>
+ /// Thrown when an invalid routing key was sent to the broker
+ /// </summary>
+ [Serializable]
+ public class AMQInvalidRoutingKeyException : AMQException
+ {
+ public AMQInvalidRoutingKeyException(string message)
+ : base(AMQConstant.INVALID_ROUTING_KEY.Code, message, null)
+ {
+ }
+
+ protected AMQInvalidRoutingKeyException(SerializationInfo info, StreamingContext ctxt)
+ : base(info, ctxt)
+ {
+ }
+
+ }
+}
diff --git a/qpid/dotnet/Qpid.Common/AMQUndeliveredException.cs b/qpid/dotnet/Qpid.Common/AMQUndeliveredException.cs
new file mode 100644
index 0000000000..70ad86c8a3
--- /dev/null
+++ b/qpid/dotnet/Qpid.Common/AMQUndeliveredException.cs
@@ -0,0 +1,59 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+using System;
+using System.Runtime.Serialization;
+
+namespace Apache.Qpid
+{
+ /// <summary>
+ /// Thrown when a message has been bounced by the broker, indicating it could not be delivered.
+ /// </summary>
+ [Serializable]
+ public class AMQUndeliveredException : AMQException
+ {
+ // TODO: Warning, no guarantee that the value stored here is serializable!
+ private object _bounced;
+
+ public AMQUndeliveredException(int errorCode, string message, object bounced)
+ : base(errorCode, message)
+ {
+ _bounced = bounced;
+ }
+
+ protected AMQUndeliveredException(SerializationInfo info, StreamingContext ctxt)
+ : base(info, ctxt)
+ {
+ _bounced = info.GetValue("bounced", typeof(object));
+ }
+
+ public override void GetObjectData(SerializationInfo info, StreamingContext context)
+ {
+ base.GetObjectData(info, context);
+ info.AddValue("bounced", _bounced);
+ }
+
+ public object GetUndeliveredMessage()
+ {
+ return _bounced;
+ }
+ }
+}
diff --git a/qpid/dotnet/Qpid.Common/AssemblySettings.cs b/qpid/dotnet/Qpid.Common/AssemblySettings.cs
new file mode 100644
index 0000000000..888de692e8
--- /dev/null
+++ b/qpid/dotnet/Qpid.Common/AssemblySettings.cs
@@ -0,0 +1,160 @@
+/*
+ *
+ * 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.
+ *
+ */
+using System;
+using System.Collections;
+using System.Configuration;
+using System.IO;
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Xml;
+using log4net;
+
+namespace Apache.Qpid.Common
+{
+ /// <summary>
+ ///
+ /// Mike Woodring
+ /// Bear Canyon Consulting LLC
+ /// http://www.bearcanyon.com
+ ///
+ /// AssemblySettings usage:
+ ///
+ /// If you know the keys you're after, the following is probably
+ /// the most convenient:
+ ///
+ /// AssemblySettings settings = new AssemblySettings();
+ /// string someSetting1 = settings["someKey1"];
+ /// string someSetting2 = settings["someKey2"];
+ ///
+ /// If you want to enumerate over the settings (or just as an
+ /// alternative approach), you can do this too:
+ ///
+ /// IDictionary settings = AssemblySettings.GetConfig();
+ ///
+ /// foreach( DictionaryEntry entry in settings )
+ /// {
+ /// // Use entry.Key or entry.Value as desired...
+ /// }
+ ///
+ /// In either of the above two scenarios, the calling assembly
+ /// (the one that called the constructor or GetConfig) is used
+ /// to determine what file to parse and what the name of the
+ /// settings collection element is. For example, if the calling
+ /// assembly is c:\foo\bar\TestLib.dll, then the configuration file
+ /// that's parsed is c:\foo\bar\TestLib.dll.config, and the
+ /// configuration section that's parsed must be named <assemblySettings>.
+ ///
+ /// To retrieve the configuration information for an arbitrary assembly,
+ /// use the overloaded constructor or GetConfig method that takes an
+ /// Assembly reference as input.
+ ///
+ /// If your assembly is being automatically downloaded from a web
+ /// site by an "href-exe" (an application that's run directly from a link
+ /// on a web page), then the enclosed web.config shows the mechanism
+ /// for allowing the AssemblySettings library to download the
+ /// configuration files you're using for your assemblies (while not
+ /// allowing web.config itself to be downloaded).
+ ///
+ /// If the assembly you are trying to use this with is installed in, and loaded
+ /// from, the GAC then you'll need to place the config file in the GAC directory where
+ /// the assembly is installed. On the first release of the CLR, this directory is
+ /// <windir>\assembly\gac\libName\verNum__pubKeyToken]]>. For example,
+ /// the assembly "SomeLib, Version=1.2.3.4, Culture=neutral, PublicKeyToken=abcd1234"
+ /// would be installed to the c:\winnt\assembly\gac\SomeLib\1.2.3.4__abcd1234 diretory
+ /// (assuming the OS is installed in c:\winnt). For future versions of the CLR, this
+ /// directory scheme may change, so you'll need to check the <code>CodeBase</code> property
+ /// of a GAC-loaded assembly in the debugger to determine the correct directory location.
+ ///
+ /// </summary>
+ public class AssemblySettings
+ {
+ private static readonly ILog _log = LogManager.GetLogger(typeof(AssemblySettings));
+
+ private IDictionary settings;
+
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ public AssemblySettings()
+ : this(Assembly.GetCallingAssembly())
+ {
+ }
+
+ public AssemblySettings(Assembly asm)
+ {
+ settings = GetConfig(asm);
+ }
+
+ public string this[string key]
+ {
+ get
+ {
+ string settingValue = null;
+
+ if (settings != null)
+ {
+ settingValue = settings[key] as string;
+ }
+
+ return (settingValue == null ? "" : settingValue);
+ }
+ }
+
+ public static IDictionary GetConfig()
+ {
+ return GetConfig(Assembly.GetCallingAssembly());
+ }
+
+ public static IDictionary GetConfig(Assembly asm)
+ {
+ // Open and parse configuration file for specified
+ // assembly, returning collection to caller for future
+ // use outside of this class.
+ string cfgFile = asm.CodeBase + ".config";
+ try
+ {
+ const string nodeName = "assemblySettings";
+
+ XmlDocument doc = new XmlDocument();
+ doc.Load(new XmlTextReader(cfgFile));
+
+ XmlNodeList nodes = doc.GetElementsByTagName(nodeName);
+
+ foreach (XmlNode node in nodes)
+ {
+ if (node.LocalName == nodeName)
+ {
+ DictionarySectionHandler handler = new DictionarySectionHandler();
+ return (IDictionary)handler.Create(null, null, node);
+ }
+ }
+ }
+ catch (FileNotFoundException)
+ {
+ _log.Warn("Assembly configuration file not found: " + cfgFile);
+ }
+ catch (Exception e)
+ {
+ _log.Warn("Failed to load .config file: " + cfgFile, e);
+ }
+
+ return null;
+ }
+ }
+}
diff --git a/qpid/dotnet/Qpid.Common/Collections/BlockingQueue.cs b/qpid/dotnet/Qpid.Common/Collections/BlockingQueue.cs
new file mode 100644
index 0000000000..dcfacf8474
--- /dev/null
+++ b/qpid/dotnet/Qpid.Common/Collections/BlockingQueue.cs
@@ -0,0 +1,95 @@
+/*
+ *
+ * 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.
+ *
+ */
+using System;
+using System.Collections;
+
+namespace Apache.Qpid.Collections
+{
+ public abstract class BlockingQueue : Queue
+ {
+ /**
+ * Inserts the specified element into this queue if it is possible to do
+ * so immediately without violating capacity restrictions, returning
+ * <tt>true</tt> upon success and <tt>false</tt> if no space is currently
+ * available. When using a capacity-restricted queue, this method is
+ * generally preferable to {@link #add}, which can fail to insert an
+ * element only by throwing an exception.
+ *
+ * @param e the element to add
+ * @return <tt>true</tt> if the element was added to this queue, else
+ * <tt>false</tt>
+ * @throws ClassCastException if the class of the specified element
+ * prevents it from being added to this queue
+ * @throws NullPointerException if the specified element is null
+ * @throws IllegalArgumentException if some property of the specified
+ * element prevents it from being added to this queue
+ */
+ public abstract bool EnqueueNoThrow(Object e);
+
+ /**
+ * Inserts the specified element into this queue, waiting if necessary
+ * for space to become available.
+ *
+ * @param e the element to add
+ * @throws InterruptedException if interrupted while waiting
+ * @throws ClassCastException if the class of the specified element
+ * prevents it from being added to this queue
+ * @throws NullPointerException if the specified element is null
+ * @throws IllegalArgumentException if some property of the specified
+ * element prevents it from being added to this queue
+ */
+ public abstract void EnqueueBlocking(object e);
+
+ /**
+ * Retrieves and removes the head of this queue, waiting up to the
+ * specified wait time if necessary for an element to become available.
+ *
+ * @param timeout how long to wait before giving up, in units of
+ * <tt>unit</tt>
+ * @param unit a <tt>TimeUnit</tt> determining how to interpret the
+ * <tt>timeout</tt> parameter
+ * @return the head of this queue, or <tt>null</tt> if the
+ * specified waiting time elapses before an element is available
+ * @throws InterruptedException if interrupted while waiting
+ */
+ public abstract object DequeueBlocking();
+
+ /**
+ * Returns the number of additional elements that this queue can ideally
+ * (in the absence of memory or resource constraints) accept without
+ * blocking, or <tt>Integer.MAX_VALUE</tt> if there is no intrinsic
+ * limit.
+ *
+ * <p>Note that you <em>cannot</em> always tell if an attempt to insert
+ * an element will succeed by inspecting <tt>remainingCapacity</tt>
+ * because it may be the case that another thread is about to
+ * insert or remove an element.
+ *
+ * @return the remaining capacity
+ */
+ public abstract int RemainingCapacity
+ {
+ get;
+ }
+ }
+}
+
+
diff --git a/qpid/dotnet/Qpid.Common/Collections/ConsumerProducerQueue.cs b/qpid/dotnet/Qpid.Common/Collections/ConsumerProducerQueue.cs
new file mode 100644
index 0000000000..131f316da6
--- /dev/null
+++ b/qpid/dotnet/Qpid.Common/Collections/ConsumerProducerQueue.cs
@@ -0,0 +1,113 @@
+/*
+ *
+ * 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.
+ *
+ */
+using System;
+using System.Collections;
+using System.Threading;
+
+
+namespace Apache.Qpid.Collections
+{
+ /// <summary>
+ /// Simple FIFO queue to support multi-threaded consumer
+ /// and producers. It supports timeouts in dequeue operations.
+ /// </summary>
+ public sealed class ConsumerProducerQueue
+ {
+ private Queue _queue = new Queue();
+ private WaitSemaphore _semaphore = new WaitSemaphore();
+
+ /// <summary>
+ /// Put an item into the tail of the queue
+ /// </summary>
+ /// <param name="item"></param>
+ public void Enqueue(object item)
+ {
+ lock ( _queue.SyncRoot )
+ {
+ _queue.Enqueue(item);
+ _semaphore.Increment();
+ }
+ }
+
+ /// <summary>
+ /// Wait indefinitely for an item to be available
+ /// on the queue.
+ /// </summary>
+ /// <returns>The object at the head of the queue</returns>
+ public object Dequeue()
+ {
+ return Dequeue(Timeout.Infinite);
+ }
+
+ /// <summary>
+ /// Wait up to the number of milliseconds specified
+ /// for an item to be available on the queue
+ /// </summary>
+ /// <param name="timeout">Number of milliseconds to wait</param>
+ /// <returns>The object at the head of the queue, or null
+ /// if the timeout expires</returns>
+ public object Dequeue(long timeout)
+ {
+ if ( _semaphore.Decrement(timeout) )
+ {
+ lock ( _queue.SyncRoot )
+ {
+ return _queue.Dequeue();
+ }
+ }
+ return null;
+ }
+
+ #region Simple Semaphore
+ //
+ // Simple Semaphore
+ //
+
+ class WaitSemaphore
+ {
+ private int _count;
+ private AutoResetEvent _event = new AutoResetEvent(false);
+
+ public void Increment()
+ {
+ Interlocked.Increment(ref _count);
+ _event.Set();
+ }
+
+ public bool Decrement(long timeout)
+ {
+ if ( timeout > int.MaxValue )
+ throw new ArgumentOutOfRangeException("timeout", timeout, "Must be <= Int32.MaxValue");
+
+ int millis = (int) (timeout & 0x7FFFFFFF);
+ if ( Interlocked.Decrement(ref _count) > 0 )
+ {
+ // there are messages in queue, so no need to wait
+ return true;
+ } else
+ {
+ return _event.WaitOne(millis, false);
+ }
+ }
+ }
+ #endregion // Simple Semaphore
+ }
+}
diff --git a/qpid/dotnet/Qpid.Common/Collections/LinkedBlockingQueue.cs b/qpid/dotnet/Qpid.Common/Collections/LinkedBlockingQueue.cs
new file mode 100644
index 0000000000..be92576951
--- /dev/null
+++ b/qpid/dotnet/Qpid.Common/Collections/LinkedBlockingQueue.cs
@@ -0,0 +1,384 @@
+/*
+ *
+ * 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.
+ *
+ */
+using System;
+using System.Threading;
+
+namespace Apache.Qpid.Collections
+{
+ public class LinkedBlockingQueue : BlockingQueue
+ {
+
+ /*
+ * A variant of the "two lock queue" algorithm. The putLock gates
+ * entry to put (and offer), and has an associated condition for
+ * waiting puts. Similarly for the takeLock. The "count" field
+ * that they both rely on is maintained as an atomic to avoid
+ * needing to get both locks in most cases. Also, to minimize need
+ * for puts to get takeLock and vice-versa, cascading notifies are
+ * used. When a put notices that it has enabled at least one take,
+ * it signals taker. That taker in turn signals others if more
+ * items have been entered since the signal. And symmetrically for
+ * takes signalling puts. Operations such as remove(Object) and
+ * iterators acquire both locks.
+ */
+
+ /**
+ * Linked list node class
+ */
+ internal class Node
+ {
+ /** The item, volatile to ensure barrier separating write and read */
+ internal volatile Object item;
+ internal Node next;
+ internal Node(Object x) { item = x; }
+ }
+
+ /** The capacity bound, or Integer.MAX_VALUE if none */
+ private readonly int capacity;
+
+ /** Current number of elements */
+ private volatile int count = 0;
+
+ /** Head of linked list */
+ private Node head;
+
+ /** Tail of linked list */
+ private Node last;
+
+ /** Lock held by take, poll, etc */
+ private readonly object takeLock = new Object(); //new SerializableLock();
+
+ /** Lock held by put, offer, etc */
+ private readonly object putLock = new Object();//new SerializableLock();
+
+ /**
+ * Signals a waiting take. Called only from put/offer (which do not
+ * otherwise ordinarily lock takeLock.)
+ */
+ private void SignalNotEmpty()
+ {
+ lock (takeLock)
+ {
+ Monitor.Pulse(takeLock);
+ }
+ }
+
+ /**
+ * Signals a waiting put. Called only from take/poll.
+ */
+ private void SignalNotFull()
+ {
+ lock (putLock)
+ {
+ Monitor.Pulse(putLock);
+ }
+ }
+
+ /**
+ * Creates a node and links it at end of queue.
+ * @param x the item
+ */
+ private void Insert(Object x)
+ {
+ last = last.next = new Node(x);
+ }
+
+ /**
+ * Removes a node from head of queue,
+ * @return the node
+ */
+ private Object Extract()
+ {
+ Node first = head.next;
+ head = first;
+ Object x = first.item;
+ first.item = null;
+ return x;
+ }
+
+
+ /**
+ * Creates a <tt>LinkedBlockingQueue</tt> with a capacity of
+ * {@link Integer#MAX_VALUE}.
+ */
+ public LinkedBlockingQueue() : this(Int32.MaxValue)
+ {
+ }
+
+ /**
+ * Creates a <tt>LinkedBlockingQueue</tt> with the given (fixed) capacity.
+ *
+ * @param capacity the capacity of this queue
+ * @throws IllegalArgumentException if <tt>capacity</tt> is not greater
+ * than zero
+ */
+ public LinkedBlockingQueue(int capacity)
+ {
+ if (capacity <= 0) throw new ArgumentException("Capacity must be positive, was passed " + capacity);
+ this.capacity = capacity;
+ last = head = new Node(null);
+ }
+
+ // this doc comment is overridden to remove the reference to collections
+ // greater in size than Integer.MAX_VALUE
+ /**
+ * Returns the number of elements in this queue.
+ *
+ * @return the number of elements in this queue
+ */
+ public int Size
+ {
+ get
+ {
+ return count;
+ }
+ }
+
+ // this doc comment is a modified copy of the inherited doc comment,
+ // without the reference to unlimited queues.
+ /**
+ * Returns the number of additional elements that this queue can ideally
+ * (in the absence of memory or resource constraints) accept without
+ * blocking. This is always equal to the initial capacity of this queue
+ * less the current <tt>size</tt> of this queue.
+ *
+ * <p>Note that you <em>cannot</em> always tell if an attempt to insert
+ * an element will succeed by inspecting <tt>remainingCapacity</tt>
+ * because it may be the case that another thread is about to
+ * insert or remove an element.
+ */
+ public override int RemainingCapacity
+ {
+ get
+ {
+ return capacity - count;
+ }
+ }
+
+ /**
+ * Inserts the specified element at the tail of this queue, waiting if
+ * necessary for space to become available.
+ *
+ * @throws InterruptedException {@inheritDoc}
+ * @throws NullPointerException {@inheritDoc}
+ */
+ public override void EnqueueBlocking(Object e)
+ {
+ if (e == null) throw new ArgumentNullException("Object must not be null");
+ // Note: convention in all put/take/etc is to preset
+ // local var holding count negative to indicate failure unless set.
+ int c = -1;
+ lock (putLock)
+ {
+ /*
+ * Note that count is used in wait guard even though it is
+ * not protected by lock. This works because count can
+ * only decrease at this point (all other puts are shut
+ * out by lock), and we (or some other waiting put) are
+ * signalled if it ever changes from
+ * capacity. Similarly for all other uses of count in
+ * other wait guards.
+ */
+ while (count == capacity)
+ {
+ Monitor.Wait(putLock);
+ }
+
+ Insert(e);
+ lock(this)
+ {
+ c = count++;
+ }
+ if (c + 1 < capacity)
+ {
+ Monitor.Pulse(putLock);
+ }
+ }
+
+ if (c == 0)
+ {
+ SignalNotEmpty();
+ }
+ }
+
+ /**
+ * Inserts the specified element at the tail of this queue if it is
+ * possible to do so immediately without exceeding the queue's capacity,
+ * returning <tt>true</tt> upon success and <tt>false</tt> if this queue
+ * is full.
+ * When using a capacity-restricted queue, this method is generally
+ * preferable to method {@link BlockingQueue#add add}, which can fail to
+ * insert an element only by throwing an exception.
+ *
+ * @throws NullPointerException if the specified element is null
+ */
+ public override bool EnqueueNoThrow(Object e)
+ {
+ if (e == null) throw new ArgumentNullException("e must not be null");
+ if (count == capacity)
+ {
+ return false;
+ }
+ int c = -1;
+ lock (putLock)
+ {
+ if (count < capacity)
+ {
+ Insert(e);
+ lock (this)
+ {
+ c = count++;
+ }
+ if (c + 1 < capacity)
+ {
+ Monitor.Pulse(putLock);
+ }
+ }
+ }
+ if (c == 0)
+ {
+ SignalNotEmpty();
+ }
+ return c >= 0;
+ }
+
+ /**
+ * Retrieves and removes the head of this queue, waiting if necessary
+ * until an element becomes available.
+ *
+ * @return the head of this queue
+ * @throws InterruptedException if interrupted while waiting
+ */
+ public override Object DequeueBlocking()
+ {
+ Object x;
+ int c = -1;
+ lock (takeLock)
+ {
+
+ while (count == 0)
+ {
+ Monitor.Wait(takeLock);
+ }
+
+
+ x = Extract();
+ lock (this) { c = count--; }
+ if (c > 1)
+ {
+ Monitor.Pulse(takeLock);
+ }
+ }
+ if (c == capacity)
+ {
+ SignalNotFull();
+ }
+ return x;
+ }
+
+ public Object Poll()
+ {
+ if (count == 0)
+ {
+ return null;
+ }
+ Object x = null;
+ int c = -1;
+ lock (takeLock)
+ {
+ if (count > 0)
+ {
+ x = Extract();
+ lock (this) { c = count--; }
+ if (c > 1)
+ {
+ Monitor.Pulse(takeLock);
+ }
+ }
+ }
+ if (c == capacity)
+ {
+ SignalNotFull();
+ }
+ return x;
+ }
+
+
+ public override Object Peek()
+ {
+ if (count == 0)
+ {
+ return null;
+ }
+ lock (takeLock)
+ {
+ Node first = head.next;
+ if (first == null)
+ {
+ return null;
+ }
+ else
+ {
+ return first.item;
+ }
+ }
+ }
+
+ public override String ToString()
+ {
+ lock (putLock)
+ {
+ lock (takeLock)
+ {
+ return base.ToString();
+ }
+ }
+ }
+
+ /**
+ * Atomically removes all of the elements from this queue.
+ * The queue will be empty after this call returns.
+ */
+ public override void Clear()
+ {
+ lock (putLock)
+ {
+ lock (takeLock)
+ {
+ head.next = null;
+ last = head;
+ int c;
+ lock (this)
+ {
+ c = count;
+ count = 0;
+ }
+ if (c == capacity)
+ {
+ Monitor.PulseAll(putLock);
+ }
+ }
+ }
+ }
+ }
+}
+
+
diff --git a/qpid/dotnet/Qpid.Common/Collections/LinkedHashtable.cs b/qpid/dotnet/Qpid.Common/Collections/LinkedHashtable.cs
new file mode 100644
index 0000000000..10ab5c674d
--- /dev/null
+++ b/qpid/dotnet/Qpid.Common/Collections/LinkedHashtable.cs
@@ -0,0 +1,327 @@
+/*
+ *
+ * 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.
+ *
+ */
+using System;
+using System.Collections;
+
+namespace Apache.Qpid.Collections
+{
+ public class LinkedHashtable : IDictionary
+ {
+ /// <summary>
+ /// Maps from key to LinkedDictionaryEntry
+ /// </summary>
+ private Hashtable _indexedValues = new Hashtable();
+
+ private LinkedDictionaryEntry _head;
+
+ private LinkedDictionaryEntry _tail;
+
+ private class LinkedDictionaryEntry
+ {
+ public LinkedDictionaryEntry _previous;
+ public LinkedDictionaryEntry _next;
+ internal DictionaryEntry _entry;
+
+ public LinkedDictionaryEntry(object key, object value)
+ {
+ _entry = new DictionaryEntry(key, value);
+ }
+ }
+
+ public object this[object key]
+ {
+ get
+ {
+ LinkedDictionaryEntry entry = (LinkedDictionaryEntry)_indexedValues[key];
+ if (entry == null)
+ {
+ return null; // key not found
+ }
+ else
+ {
+ return entry._entry.Value;
+ }
+ }
+
+ set
+ {
+ LinkedDictionaryEntry entry = (LinkedDictionaryEntry)_indexedValues[key];
+ if (entry == null)
+ {
+ Add(key, value);
+ }
+ else
+ {
+ entry._entry.Value = value;
+ }
+ }
+ }
+
+ /// <summary>
+ /// Collect keys in linked order.
+ /// </summary>
+ public ICollection Keys
+ {
+ get
+ {
+ IList result = new ArrayList();
+ foreach (DictionaryEntry entry in this)
+ {
+ result.Add(entry.Key);
+ }
+ return result;
+ }
+ }
+
+ /// <summary>
+ /// Collect values in linked order.
+ /// </summary>
+ public ICollection Values
+ {
+ get
+ {
+ IList result = new ArrayList();
+ foreach (DictionaryEntry entry in this)
+ {
+ result.Add(entry.Value);
+ }
+ return result;
+ }
+ }
+
+ public bool IsReadOnly
+ {
+ get { return _indexedValues.IsReadOnly; }
+ }
+
+ public bool IsFixedSize
+ {
+ get { return _indexedValues.IsFixedSize; }
+ }
+
+ public bool Contains(object key)
+ {
+ return _indexedValues.Contains(key);
+ }
+
+ public void Add(object key, object value)
+ {
+ if (key == null) throw new ArgumentNullException("key");
+
+ if (Contains(key))
+ {
+ throw new ArgumentException("LinkedHashtable already contains key. key=" + key);
+ }
+
+ LinkedDictionaryEntry de = new LinkedDictionaryEntry(key, value);
+ if (_head == null)
+ {
+ _head = de;
+ _tail = de;
+ }
+ else
+ {
+ _tail._next = de;
+ de._previous = _tail;
+ _tail = de;
+ }
+ _indexedValues[key] = de;
+ }
+
+ public void Clear()
+ {
+ _indexedValues.Clear();
+ }
+
+ IDictionaryEnumerator IDictionary.GetEnumerator()
+ {
+ return new LHTEnumerator(this);
+ }
+
+ public void Remove(object key)
+ {
+ if (key == null) throw new ArgumentNullException("key");
+
+ LinkedDictionaryEntry de = (LinkedDictionaryEntry)_indexedValues[key];
+ if (de == null) return; // key not found.
+ LinkedDictionaryEntry prev = de._previous;
+ if (prev == null)
+ {
+ _head = de._next;
+ }
+ else
+ {
+ prev._next = de._next;
+ }
+
+ LinkedDictionaryEntry next = de._next;
+ if (next == null)
+ {
+ _tail = de;
+ }
+ else
+ {
+ next._previous = de._previous;
+ }
+ }
+
+ private LinkedDictionaryEntry Head
+ {
+ get
+ {
+ return _head;
+ }
+ }
+
+// private LinkedDictionaryEntry Tail
+// {
+// get
+// {
+// return _tail;
+// }
+// }
+
+ private class LHTEnumerator : IDictionaryEnumerator
+ {
+ private LinkedHashtable _container;
+
+ private LinkedDictionaryEntry _current;
+
+ /// <summary>
+ /// Set once we have navigated off the end of the collection
+ /// </summary>
+ private bool _needsReset = false;
+
+ public LHTEnumerator(LinkedHashtable container)
+ {
+ _container = container;
+ }
+
+ public object Current
+ {
+ get
+ {
+ if (_current == null)
+ {
+ throw new Exception("Iterator before first element");
+ }
+ else
+ {
+ return _current._entry;
+ }
+ }
+ }
+
+ public object Key
+ {
+ get { return _current._entry.Key; }
+ }
+
+ public object Value
+ {
+ get { return _current._entry.Value; }
+ }
+
+ public DictionaryEntry Entry
+ {
+ get
+ {
+ return _current._entry;
+ }
+ }
+
+ public bool MoveNext()
+ {
+ if (_needsReset)
+ {
+ return false;
+ }
+ else if (_current == null)
+ {
+ _current = _container.Head;
+ }
+ else
+ {
+ _current = _current._next;
+ }
+ _needsReset = (_current == null);
+ return !_needsReset;
+ }
+
+ public void Reset()
+ {
+ _current = null;
+ _needsReset = false;
+ }
+ }
+
+ public void MoveToHead(object key)
+ {
+ LinkedDictionaryEntry de = (LinkedDictionaryEntry)_indexedValues[key];
+ if (de == null)
+ {
+ throw new ArgumentException("Key " + key + " not found");
+ }
+ // if the head is the element then there is nothing to do
+ if (_head == de)
+ {
+ return;
+ }
+ de._previous._next = de._next;
+ if (de._next != null)
+ {
+ de._next._previous = de._previous;
+ }
+ else
+ {
+ _tail = de._previous;
+ }
+ de._next = _head;
+ _head = de;
+ de._previous = null;
+ }
+
+ public void CopyTo(Array array, int index)
+ {
+ _indexedValues.CopyTo(array, index);
+ }
+
+ public int Count
+ {
+ get { return _indexedValues.Count; }
+ }
+
+ public object SyncRoot
+ {
+ get { return _indexedValues.SyncRoot; }
+ }
+
+ public bool IsSynchronized
+ {
+ get { return _indexedValues.IsSynchronized; }
+ }
+
+ public IEnumerator GetEnumerator()
+ {
+ return new LHTEnumerator(this);
+ }
+ }
+}
diff --git a/qpid/dotnet/Qpid.Common/Collections/SynchronousQueue.cs b/qpid/dotnet/Qpid.Common/Collections/SynchronousQueue.cs
new file mode 100644
index 0000000000..3c12df6067
--- /dev/null
+++ b/qpid/dotnet/Qpid.Common/Collections/SynchronousQueue.cs
@@ -0,0 +1,375 @@
+/*
+ *
+ * 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.
+ *
+ */
+using System;
+using System.Threading;
+
+namespace Apache.Qpid.Collections
+{
+ public class SynchronousQueue : BlockingQueue
+ {
+ /// <summary>
+ /// Lock protecting both wait queues
+ /// </summary>
+// private readonly object _qlock = new object();
+
+ /// <summary>
+ /// Queue holding waiting puts
+ /// </summary>
+// private readonly WaitQueue _waitingProducers;
+
+ /// <summary>
+ /// Queue holding waiting takes
+ /// </summary>
+// private readonly WaitQueue _waitingConsumers;
+
+ /**
+ * Queue to hold waiting puts/takes; specialized to Fifo/Lifo below.
+ * These queues have all transient fields, but are serializable
+ * in order to recover fairness settings when deserialized.
+ */
+ internal abstract class WaitQueue
+ {
+ /** Creates, adds, and returns node for x. */
+ internal abstract Node Enq(Object x);
+ /** Removes and returns node, or null if empty. */
+ internal abstract Node Deq();
+ /** Removes a cancelled node to avoid garbage retention. */
+ internal abstract void Unlink(Node node);
+ /** Returns true if a cancelled node might be on queue. */
+ internal abstract bool ShouldUnlink(Node node);
+ }
+
+ /**
+ * FIFO queue to hold waiting puts/takes.
+ */
+ sealed class FifoWaitQueue : WaitQueue
+ {
+ private Node head;
+ private Node last;
+
+ internal override Node Enq(Object x)
+ {
+ Node p = new Node(x);
+ if (last == null)
+ {
+ last = head = p;
+ }
+ else
+ {
+ last = last.next = p;
+ }
+ return p;
+ }
+
+ internal override Node Deq()
+ {
+ Node p = head;
+ if (p != null)
+ {
+ if ((head = p.next) == null)
+ {
+ last = null;
+ }
+ p.next = null;
+ }
+ return p;
+ }
+
+ internal override bool ShouldUnlink(Node node)
+ {
+ return (node == last || node.next != null);
+ }
+
+ internal override void Unlink(Node node)
+ {
+ Node p = head;
+ Node trail = null;
+ while (p != null)
+ {
+ if (p == node)
+ {
+ Node next = p.next;
+ if (trail == null)
+ {
+ head = next;
+ }
+ else
+ {
+ trail.next = next;
+ }
+ if (last == node)
+ {
+ last = trail;
+ }
+ break;
+ }
+ trail = p;
+ p = p.next;
+ }
+ }
+ }
+
+ /**
+ * LIFO queue to hold waiting puts/takes.
+ */
+ sealed class LifoWaitQueue : WaitQueue
+ {
+ private Node head;
+
+ internal override Node Enq(Object x)
+ {
+ return head = new Node(x, head);
+ }
+
+ internal override Node Deq()
+ {
+ Node p = head;
+ if (p != null)
+ {
+ head = p.next;
+ p.next = null;
+ }
+ return p;
+ }
+
+ internal override bool ShouldUnlink(Node node)
+ {
+ // Return false if already dequeued or is bottom node (in which
+ // case we might retain at most one garbage node)
+ return (node == head || node.next != null);
+ }
+
+ internal override void Unlink(Node node)
+ {
+ Node p = head;
+ Node trail = null;
+ while (p != null)
+ {
+ if (p == node)
+ {
+ Node next = p.next;
+ if (trail == null)
+ head = next;
+ else
+ trail.next = next;
+ break;
+ }
+ trail = p;
+ p = p.next;
+ }
+ }
+ }
+
+ /**
+ * Nodes each maintain an item and handle waits and signals for
+ * getting and setting it. The class extends
+ * AbstractQueuedSynchronizer to manage blocking, using AQS state
+ * 0 for waiting, 1 for ack, -1 for cancelled.
+ */
+ sealed internal class Node
+ {
+
+ /** Synchronization state value representing that node acked */
+ private const int ACK = 1;
+ /** Synchronization state value representing that node cancelled */
+ private const int CANCEL = -1;
+
+ internal int state = 0;
+
+ /** The item being transferred */
+ internal Object item;
+ /** Next node in wait queue */
+ internal Node next;
+
+ /** Creates a node with initial item */
+ internal Node(Object x)
+ {
+ item = x;
+ }
+
+ /** Creates a node with initial item and next */
+ internal Node(Object x, Node n)
+ {
+ item = x;
+ next = n;
+ }
+
+ /**
+ * Takes item and nulls out field (for sake of GC)
+ *
+ * PRE: lock owned
+ */
+ private Object Extract()
+ {
+ Object x = item;
+ item = null;
+ return x;
+ }
+
+ /**
+ * Tries to cancel on interrupt; if so rethrowing,
+ * else setting interrupt state
+ *
+ * PRE: lock owned
+ */
+ /*private void checkCancellationOnInterrupt(InterruptedException ie)
+ throws InterruptedException
+ {
+ if (state == 0) {
+ state = CANCEL;
+ notify();
+ throw ie;
+ }
+ Thread.currentThread().interrupt();
+ }*/
+
+ /**
+ * Fills in the slot created by the consumer and signal consumer to
+ * continue.
+ */
+ internal bool SetItem(Object x)
+ {
+ lock (this)
+ {
+ if (state != 0) return false;
+ item = x;
+ state = ACK;
+ Monitor.Pulse(this);
+ return true;
+ }
+ }
+
+ /**
+ * Removes item from slot created by producer and signal producer
+ * to continue.
+ */
+ internal Object GetItem()
+ {
+ if (state != 0) return null;
+ state = ACK;
+ Monitor.Pulse(this);
+ return Extract();
+ }
+
+ /**
+ * Waits for a consumer to take item placed by producer.
+ */
+ internal void WaitForTake() //throws InterruptedException {
+ {
+ while (state == 0)
+ {
+ Monitor.Wait(this);
+ }
+ }
+
+ /**
+ * Waits for a producer to put item placed by consumer.
+ */
+ internal object WaitForPut()
+ {
+ lock (this)
+ {
+ while (state == 0) Monitor.Wait(this);
+ }
+ return Extract();
+ }
+
+ private bool Attempt(long nanos)
+ {
+ if (state != 0) return true;
+ if (nanos <= 0) {
+ state = CANCEL;
+ Monitor.Pulse(this);
+ return false;
+ }
+
+ while (true)
+ {
+ Monitor.Wait(nanos);
+ //TimeUnit.NANOSECONDS.timedWait(this, nanos);
+ if (state != 0)
+ {
+ return true;
+ }
+ //nanos = deadline - Utils.nanoTime();
+ //if (nanos <= 0)
+ else
+ {
+ state = CANCEL;
+ Monitor.Pulse(this);
+ return false;
+ }
+ }
+ }
+
+ /**
+ * Waits for a consumer to take item placed by producer or time out.
+ */
+ internal bool WaitForTake(long nanos)
+ {
+ return Attempt(nanos);
+ }
+
+ /**
+ * Waits for a producer to put item placed by consumer, or time out.
+ */
+ internal object WaitForPut(long nanos)
+ {
+ if (!Attempt(nanos))
+ {
+ return null;
+ }
+ else
+ {
+ return Extract();
+ }
+ }
+ }
+
+ public SynchronousQueue(bool strict)
+ {
+ // TODO !!!!
+ }
+
+ public override bool EnqueueNoThrow(object e)
+ {
+ throw new NotImplementedException();
+ }
+
+ public override void EnqueueBlocking(object e)
+ {
+ throw new NotImplementedException();
+ }
+
+ public override object DequeueBlocking()
+ {
+ throw new NotImplementedException();
+ }
+
+ public override int RemainingCapacity
+ {
+ get
+ {
+ throw new NotImplementedException();
+ }
+ }
+ }
+}
diff --git a/qpid/dotnet/Qpid.Common/Framing/AMQDataBlockDecoder.cs b/qpid/dotnet/Qpid.Common/Framing/AMQDataBlockDecoder.cs
new file mode 100644
index 0000000000..7867650e50
--- /dev/null
+++ b/qpid/dotnet/Qpid.Common/Framing/AMQDataBlockDecoder.cs
@@ -0,0 +1,155 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+using System;
+using System.Collections;
+using log4net;
+using Apache.Qpid.Buffer;
+using Apache.Qpid.Codec;
+using Apache.Qpid.Codec.Demux;
+
+namespace Apache.Qpid.Framing
+{
+ public class AMQDataBlockDecoder : IMessageDecoder
+ {
+ private static ILog _logger = LogManager.GetLogger(typeof(AMQDataBlockDecoder));
+
+ private Hashtable _supportedBodies = new Hashtable();
+
+ private bool _disabled = false;
+
+ public AMQDataBlockDecoder()
+ {
+ _supportedBodies[AMQMethodBody.TYPE] = AMQMethodBodyFactory.GetInstance();
+ _supportedBodies[ContentHeaderBody.TYPE] = ContentHeaderBodyFactory.GetInstance();
+ _supportedBodies[ContentBody.TYPE] = ContentBodyFactory.GetInstance();
+ _supportedBodies[HeartbeatBody.TYPE] = new HeartbeatBodyFactory();
+ }
+
+ public MessageDecoderResult Decodable(ByteBuffer input)
+ {
+ if (_disabled)
+ {
+ return MessageDecoderResult.NOT_OK;
+ }
+ // final +1 represents the command end which we know we must require even
+ // if there is an empty body
+ if (input.Remaining < 1)
+ {
+ return MessageDecoderResult.NEED_DATA;
+ }
+ byte type = input.GetByte();
+
+ // we have to check this isn't a protocol initiation frame here - we can't tell later on and we end up
+ // waiting for more data. This could be improved if MINA supported some kind of state awareness when decoding
+ if ((char)type == 'A')
+ {
+ _logger.Error("Received what appears to be a protocol initiation frame");
+ return MessageDecoderResult.NOT_OK;
+ }
+ // zero, channel, body size and end byte
+ if (input.Remaining < (1 + 2 + 4 + 1))
+ {
+ return MessageDecoderResult.NEED_DATA;
+ }
+
+ int channel = input.GetUInt16();
+ long bodySize = input.GetUInt32();
+
+ // bodySize can be zero
+ if (type <= 0 || channel < 0 || bodySize < 0)
+ {
+ _logger.Error(String.Format("Error decoding frame: Type={0}, Channel={1}, BodySize={2}", type, channel, bodySize));
+ return MessageDecoderResult.NOT_OK;
+ }
+
+ if (input.Remaining < (bodySize + 1))
+ {
+ return MessageDecoderResult.NEED_DATA;
+ }
+
+ if (IsSupportedFrameType(type))
+ {
+ if (_logger.IsDebugEnabled)
+ {
+ // we have read 7 bytes so far, so output 7 + bodysize + 1 (for end byte) to get complete data block size
+ // this logging statement is useful when looking at exactly what size of data is coming in/out
+ // the broker
+ _logger.Debug("Able to decode data block of size " + (bodySize + 8));
+ }
+ return MessageDecoderResult.OK;
+ }
+ else
+ {
+ return MessageDecoderResult.NOT_OK;
+ }
+ }
+
+ private bool IsSupportedFrameType(byte frameType)
+ {
+ bool result = _supportedBodies.ContainsKey(frameType);
+
+ if (!result)
+ {
+ _logger.Warn("AMQDataBlockDecoder does not handle frame type " + frameType);
+ }
+
+ return result;
+ }
+
+ protected Object CreateAndPopulateFrame(ByteBuffer input)
+ {
+ byte type = input.GetByte();
+ ushort channel = input.GetUInt16();
+ uint bodySize = input.GetUInt32();
+
+ IBodyFactory bodyFactory = (IBodyFactory)_supportedBodies[type];
+ if (bodyFactory == null)
+ {
+ throw new AMQFrameDecodingException("Unsupported body type: " + type);
+ }
+ AMQFrame frame = new AMQFrame();
+
+ frame.PopulateFromBuffer(input, channel, bodySize, bodyFactory);
+
+ byte marker = input.GetByte();
+ if (marker != 0xCE) {
+ throw new FormatException("marker is not 0xCE");
+ }
+ return frame;
+ }
+
+ public MessageDecoderResult Decode(ByteBuffer input, IProtocolDecoderOutput output)
+ {
+
+ output.Write(CreateAndPopulateFrame(input));
+
+ return MessageDecoderResult.OK;
+ }
+
+ public bool Disabled
+ {
+ set
+ {
+ _disabled = value;
+ }
+ }
+ }
+}
diff --git a/qpid/dotnet/Qpid.Common/Framing/AMQDataBlockEncoder.cs b/qpid/dotnet/Qpid.Common/Framing/AMQDataBlockEncoder.cs
new file mode 100644
index 0000000000..e2645c630e
--- /dev/null
+++ b/qpid/dotnet/Qpid.Common/Framing/AMQDataBlockEncoder.cs
@@ -0,0 +1,65 @@
+/*
+ *
+ * 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.
+ *
+ */
+using System.Collections;
+using log4net;
+using Apache.Qpid.Buffer;
+using Apache.Qpid.Codec;
+using Apache.Qpid.Codec.Demux;
+
+namespace Apache.Qpid.Framing
+{
+ public class AMQDataBlockEncoder : IMessageEncoder
+ {
+ private static ILog _logger = LogManager.GetLogger(typeof(AMQDataBlockEncoder));
+
+ private Hashtable _messageTypes;
+
+ public AMQDataBlockEncoder()
+ {
+ _messageTypes = new Hashtable();
+ _messageTypes[typeof (IEncodableAMQDataBlock)] = 1;
+ }
+
+
+ public Hashtable MessageTypes
+ {
+ get
+ {
+ return _messageTypes;
+ }
+ }
+
+ public void Encode(object message, IProtocolEncoderOutput output)
+ {
+ IDataBlock frame = (IDataBlock) message;
+ int frameSize = (int)frame.Size; // TODO: sort out signed/unsigned
+ ByteBuffer buffer = ByteBuffer.Allocate(frameSize);
+ frame.WritePayload(buffer);
+
+ if (_logger.IsDebugEnabled)
+ {
+ _logger.Debug("Encoded frame byte-buffer is '" + ByteBufferHexDumper.GetHexDump(buffer) + "'");
+ }
+ buffer.Flip();
+ output.Write(buffer);
+ }
+ }
+}
diff --git a/qpid/dotnet/Qpid.Common/Framing/AMQFrame.cs b/qpid/dotnet/Qpid.Common/Framing/AMQFrame.cs
new file mode 100644
index 0000000000..912be72d30
--- /dev/null
+++ b/qpid/dotnet/Qpid.Common/Framing/AMQFrame.cs
@@ -0,0 +1,107 @@
+/*
+ *
+ * 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.
+ *
+ */
+using Apache.Qpid.Buffer;
+
+namespace Apache.Qpid.Framing
+{
+ public class AMQFrame : IDataBlock
+ {
+ private ushort _channel;
+
+ private IBody _bodyFrame;
+
+ public AMQFrame()
+ {
+ }
+
+ public AMQFrame(ushort channel, IBody bodyFrame)
+ {
+ _channel = channel;
+ _bodyFrame = bodyFrame;
+ }
+
+ public ushort Channel
+ {
+ get
+ {
+ return _channel;
+ }
+ set
+ {
+ _channel = value;
+ }
+ }
+
+ public IBody BodyFrame
+ {
+ get
+ {
+ return _bodyFrame;
+ }
+ set
+ {
+ _bodyFrame = value;
+ }
+ }
+
+ #region IDataBlock Members
+
+ public uint Size
+ {
+ get
+ {
+ return (uint) (1 + 2 + 4 + _bodyFrame.Size + 1);
+ }
+ }
+
+ public void WritePayload(ByteBuffer buffer)
+ {
+ buffer.Put(_bodyFrame.BodyType);
+ // TODO: how does channel get populated
+ buffer.Put(_channel);
+ buffer.Put(_bodyFrame.Size);
+ _bodyFrame.WritePayload(buffer);
+ buffer.Put((byte) 0xCE);
+ }
+
+ #endregion
+
+ /// <summary>
+ /// Populates the frame instance data from the supplied buffer.
+ /// </summary>
+ /// <param name="buffer">The buffer.</param>
+ /// <param name="channel">The channel.</param>
+ /// <param name="bodySize">Size of the body in bytes</param>
+ /// <param name="bodyFactory">The body factory.</param>
+ /// <exception cref="AMQFrameDecodingException">Thrown if the buffer cannot be decoded</exception>
+ public void PopulateFromBuffer(ByteBuffer buffer, ushort channel, uint bodySize, IBodyFactory bodyFactory)
+ {
+ _channel = channel;
+ _bodyFrame = bodyFactory.CreateBody(buffer);
+ _bodyFrame.PopulateFromBuffer(buffer, bodySize);
+ }
+
+ public override string ToString()
+ {
+ return "Frame channelId: " + _channel + ", bodyFrame: " + _bodyFrame.ToString();
+ }
+ }
+}
diff --git a/qpid/dotnet/Qpid.Common/Framing/AMQFrameDecodingException.cs b/qpid/dotnet/Qpid.Common/Framing/AMQFrameDecodingException.cs
new file mode 100644
index 0000000000..cda8c84ecf
--- /dev/null
+++ b/qpid/dotnet/Qpid.Common/Framing/AMQFrameDecodingException.cs
@@ -0,0 +1,59 @@
+/*
+ *
+ * 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.
+ *
+ */
+using System;
+using System.Runtime.Serialization;
+using log4net;
+
+namespace Apache.Qpid.Framing
+{
+ /// <summary>
+ /// Thrown when a frame cannot be decoded. This generally indicates a mismatch between the broker and the
+ /// client.
+ /// </summary>
+ [Serializable]
+ public class AMQFrameDecodingException : AMQException
+ {
+ public AMQFrameDecodingException(string message)
+ : base(message)
+ {
+ }
+
+ public AMQFrameDecodingException(string message, Exception innerException)
+ : base(message, innerException)
+ {
+ }
+
+ public AMQFrameDecodingException(ILog logger, string message)
+ : base(logger, message)
+ {
+ }
+
+ public AMQFrameDecodingException(ILog logger, string message, Exception innerException)
+ : base(logger, message, innerException)
+ {
+ }
+
+ protected AMQFrameDecodingException(SerializationInfo info, StreamingContext ctxt)
+ : base(info, ctxt)
+ {
+ }
+ }
+}
diff --git a/qpid/dotnet/Qpid.Common/Framing/AMQMethodBody.cs b/qpid/dotnet/Qpid.Common/Framing/AMQMethodBody.cs
new file mode 100644
index 0000000000..a3c4337147
--- /dev/null
+++ b/qpid/dotnet/Qpid.Common/Framing/AMQMethodBody.cs
@@ -0,0 +1,93 @@
+/*
+ *
+ * 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.
+ *
+ */
+using System;
+using Apache.Qpid.Buffer;
+
+namespace Apache.Qpid.Framing
+{
+ public abstract class AMQMethodBody : IBody
+ {
+ public const byte TYPE = 1;
+
+ protected abstract uint BodySize
+ {
+ get;
+ }
+
+ protected abstract ushort Clazz
+ {
+ get;
+ }
+
+ protected abstract ushort Method
+ {
+ get;
+ }
+
+ protected abstract void WriteMethodPayload(ByteBuffer buffer);
+
+ public byte BodyType
+ {
+ get
+ {
+ return TYPE;
+ }
+ }
+
+ public uint Size
+ {
+ get
+ {
+ return (uint) (2 + 2 + BodySize);
+ }
+ }
+
+ public void WritePayload(ByteBuffer buffer)
+ {
+ buffer.Put(Clazz);
+ buffer.Put(Method);
+ WriteMethodPayload(buffer);
+ }
+
+ /// <summary>
+ /// Populates the method body by decoding the specified buffer
+ /// </summary>
+ /// <param name="buffer">The buffer to decode.</param>
+ /// <exception cref="AMQFrameDecodingException">If the buffer cannot be decoded</exception>
+ protected abstract void PopulateMethodBodyFromBuffer(ByteBuffer buffer);
+
+ /// <summary>
+ /// Populates this instance from a buffer of data.
+ /// </summary>
+ /// <param name="buffer">The buffer.</param>
+ /// <param name="size">The size.</param>
+ /// <exception cref="AMQFrameDecodingException">If the buffer contains data that cannot be decoded</exception>
+ public void PopulateFromBuffer(ByteBuffer buffer, uint size)
+ {
+ PopulateMethodBodyFromBuffer(buffer);
+ }
+
+ public override string ToString()
+ {
+ return String.Format("{0}{{ Class: {1} Method: {2} }}", GetType().Name, Clazz, Method);
+ }
+ }
+}
diff --git a/qpid/dotnet/Qpid.Common/Framing/AMQMethodBodyFactory.cs b/qpid/dotnet/Qpid.Common/Framing/AMQMethodBodyFactory.cs
new file mode 100644
index 0000000000..c1fd3f887a
--- /dev/null
+++ b/qpid/dotnet/Qpid.Common/Framing/AMQMethodBodyFactory.cs
@@ -0,0 +1,45 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+using Apache.Qpid.Buffer;
+
+namespace Apache.Qpid.Framing
+{
+ public class AMQMethodBodyFactory : IBodyFactory
+ {
+ private static readonly AMQMethodBodyFactory _instance = new AMQMethodBodyFactory();
+
+ public static AMQMethodBodyFactory GetInstance()
+ {
+ return _instance;
+ }
+
+ /// <summary>
+ /// Creates the body.
+ /// </summary>
+ /// <param name="inbuf">The ByteBuffer containing data from the network</param>
+ /// <returns></returns>
+ /// <exception>AMQFrameDecodingException</exception>
+ public IBody CreateBody(ByteBuffer inbuf)
+ {
+ return MethodBodyDecoderRegistry.Get(inbuf.GetUInt16(), inbuf.GetUInt16());
+ }
+ }
+}
diff --git a/qpid/dotnet/Qpid.Common/Framing/AMQProtocolHeaderException.cs b/qpid/dotnet/Qpid.Common/Framing/AMQProtocolHeaderException.cs
new file mode 100644
index 0000000000..379e5d00ba
--- /dev/null
+++ b/qpid/dotnet/Qpid.Common/Framing/AMQProtocolHeaderException.cs
@@ -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.
+ *
+ */
+
+using System;
+using System.Runtime.Serialization;
+
+namespace Apache.Qpid.Framing
+{
+ [Serializable]
+ public class AMQProtocolHeaderException : AMQException
+ {
+ public AMQProtocolHeaderException(string message) : base(message)
+ {
+ }
+
+ protected AMQProtocolHeaderException(SerializationInfo info, StreamingContext ctxt)
+ : base(info, ctxt)
+ {
+ }
+ }
+}
diff --git a/qpid/dotnet/Qpid.Common/Framing/AMQType.cs b/qpid/dotnet/Qpid.Common/Framing/AMQType.cs
new file mode 100644
index 0000000000..95da72b907
--- /dev/null
+++ b/qpid/dotnet/Qpid.Common/Framing/AMQType.cs
@@ -0,0 +1,700 @@
+/*
+ *
+ * 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.
+ *
+ */
+using System;
+using System.Text;
+using Apache.Qpid.Buffer;
+
+namespace Apache.Qpid.Framing
+{
+ /// <summary>
+ /// Base class for the Field Table Type system.
+ /// Ported over from the Java AMQType enumeration
+ /// </summary>
+ public abstract class AMQType
+ {
+ private byte _identifier;
+
+ /// <summary>
+ /// Type code identifier for this type
+ /// </summary>
+ public byte Identifier
+ {
+ get { return _identifier; }
+ }
+
+ protected AMQType(char identifier)
+ {
+ _identifier = (byte)identifier;
+ }
+
+ /// <summary>
+ /// Create a new <see cref="AMQTypedValue"/> instance
+ /// </summary>
+ /// <param name="value">Value to initialize with</param>
+ /// <returns>A new typed value instance</returns>
+ public AMQTypedValue AsTypedValue(object value)
+ {
+ return new AMQTypedValue(this, ToNativeValue(value));
+ }
+
+ /// <summary>
+ /// Write the specified value to the buffer using the encoding
+ /// specified for this type
+ /// </summary>
+ /// <param name="value">Value to write</param>
+ /// <param name="buffer">Buffer to write to</param>
+ public void WriteToBuffer(object value, ByteBuffer buffer)
+ {
+ buffer.Put(Identifier);
+ WriteValueImpl(value, buffer);
+ }
+
+ public override string ToString()
+ {
+ return ((Char) Identifier).ToString();
+ }
+
+ /// <summary>
+ /// Get the encoding size for the specified value in this type format
+ /// </summary>
+ /// <param name="value">Value to find encoded size for</param>
+ /// <returns>The encoded size</returns>
+ public abstract uint GetEncodingSize(object value);
+ /// <summary>
+ /// Convert the specified value to this type
+ /// </summary>
+ /// <param name="value">Value to convert</param>
+ /// <returns>The converted value</returns>
+ public abstract object ToNativeValue(object value);
+
+ /// <summary>
+ /// Read a value from the specified buffer using the encoding for
+ /// this type
+ /// </summary>
+ /// <param name="buffer">Buffer to read from</param>
+ /// <returns>The value read</returns>
+ public abstract object ReadValueFromBuffer(ByteBuffer buffer);
+
+ protected abstract void WriteValueImpl(Object value, ByteBuffer buffer);
+
+
+ #region Known Types
+ //
+ // Known Types
+ //
+
+ // long string is not defined in the proposed specification,
+ // and the 'S' discriminator is left for unsigned short (16-bit) values
+ public static readonly AMQType LONG_STRING = new AMQLongStringType();
+ public static readonly AMQType UINT32 = new AMQUInt32Type();
+ public static readonly AMQType DECIMAL = new AMQDecimalType();
+ public static readonly AMQType TIMESTAMP = new AMQTimeStampType();
+ public static readonly AMQType FIELD_TABLE = new AMQFieldTableType();
+ public static readonly AMQType VOID = new AMQVoidType();
+ public static readonly AMQType BINARY = new AMQBinaryType();
+ public static readonly AMQType ASCII_STRING = new AMQAsciiStringType();
+ public static readonly AMQType WIDE_STRING = new AMQWideStringType();
+ public static readonly AMQType BOOLEAN = new AMQBooleanType();
+ public static readonly AMQType ASCII_CHARACTER = new AMQAsciiCharType();
+ public static readonly AMQType BYTE = new AMQByteType();
+ public static readonly AMQType SBYTE = new AMQSByteType();
+ public static readonly AMQType INT16 = new AMQInt16Type();
+ public static readonly AMQType UINT16 = new AMQUInt16Type();
+ public static readonly AMQType INT32 = new AMQInt32Type();
+ public static readonly AMQType INT64 = new AMQInt64Type();
+ public static readonly AMQType UINT64 = new AMQUInt64Type();
+ public static readonly AMQType FLOAT = new AMQFloatType();
+ public static readonly AMQType DOUBLE = new AMQDoubleType();
+
+ #endregion // Known Types
+
+ #region Type Implementation
+ //
+ // Type Implementation
+ //
+
+ sealed class AMQLongStringType : AMQType
+ {
+ public AMQLongStringType() : base('S')
+ {
+ }
+
+ public override uint GetEncodingSize(object value)
+ {
+ return EncodingUtils.EncodedLongStringLength((string) value);
+ }
+
+ public override object ToNativeValue(object value)
+ {
+ if ( value == null )
+ throw new ArgumentNullException("value");
+ return value.ToString();
+ }
+
+ public override object ReadValueFromBuffer(ByteBuffer buffer)
+ {
+ return EncodingUtils.ReadLongString(buffer);
+ }
+
+ protected override void WriteValueImpl(object value, ByteBuffer buffer)
+ {
+ EncodingUtils.WriteLongStringBytes(buffer, (string) value);
+ }
+
+ }
+
+ sealed class AMQUInt32Type : AMQType
+ {
+ public AMQUInt32Type() : base('i')
+ {
+ }
+
+ public override uint GetEncodingSize(object value)
+ {
+ return EncodingUtils.UnsignedIntegerLength();
+ }
+
+ public override object ToNativeValue(object value)
+ {
+ return Convert.ToUInt32(value);
+ }
+
+ public override object ReadValueFromBuffer(ByteBuffer buffer)
+ {
+ return EncodingUtils.ReadUnsignedInteger(buffer);
+ }
+
+ protected override void WriteValueImpl(object value, ByteBuffer buffer)
+ {
+ EncodingUtils.WriteUnsignedInteger(buffer, (uint) value);
+ }
+
+ }
+
+ sealed class AMQDecimalType : AMQType
+ {
+ public AMQDecimalType() : base('D')
+ {
+ }
+
+ public override uint GetEncodingSize(object value)
+ {
+ throw new NotImplementedException();
+ }
+
+ public override object ToNativeValue(object value)
+ {
+ throw new NotImplementedException();
+ }
+
+ public override object ReadValueFromBuffer(ByteBuffer buffer)
+ {
+ throw new NotImplementedException();
+ }
+
+ protected override void WriteValueImpl(object value, ByteBuffer buffer)
+ {
+ throw new NotImplementedException();
+ }
+ }
+
+ sealed class AMQTimeStampType : AMQType
+ {
+ public AMQTimeStampType() : base('T')
+ {
+ }
+
+ public override uint GetEncodingSize(object value)
+ {
+ throw new NotImplementedException();
+ }
+
+ public override object ToNativeValue(object value)
+ {
+ throw new NotImplementedException();
+ }
+
+ public override object ReadValueFromBuffer(ByteBuffer buffer)
+ {
+ throw new NotImplementedException();
+ }
+
+ protected override void WriteValueImpl(object value, ByteBuffer buffer)
+ {
+ throw new NotImplementedException();
+ }
+ }
+
+ sealed class AMQFieldTableType : AMQType
+ {
+ public AMQFieldTableType() : base('F')
+ {
+ }
+
+ public override uint GetEncodingSize(object value)
+ {
+ throw new NotImplementedException();
+ }
+
+ public override object ToNativeValue(object value)
+ {
+ throw new NotImplementedException();
+ }
+
+ public override object ReadValueFromBuffer(ByteBuffer buffer)
+ {
+ throw new NotImplementedException();
+ }
+
+ protected override void WriteValueImpl(object value, ByteBuffer buffer)
+ {
+ throw new NotImplementedException();
+ }
+ }
+
+ sealed class AMQVoidType : AMQType
+ {
+ public AMQVoidType() : base('V')
+ {
+ }
+
+ public override uint GetEncodingSize(object value)
+ {
+ return 0;
+ }
+
+ public override object ToNativeValue(object value)
+ {
+ if ( value != null )
+ throw new FormatException(string.Format("Cannot convert {0} to VOID type", value));
+ return null;
+ }
+
+ public override object ReadValueFromBuffer(ByteBuffer buffer)
+ {
+ return null;
+ }
+
+ protected override void WriteValueImpl(object value, ByteBuffer buffer)
+ {
+ }
+ }
+
+ // Extended Types
+
+ sealed class AMQBinaryType : AMQType
+ {
+ public AMQBinaryType() : base('x')
+ {
+ }
+
+ public override uint GetEncodingSize(object value)
+ {
+ return EncodingUtils.EncodedLongstrLength((byte[]) value);
+ }
+
+ public override object ToNativeValue(object value)
+ {
+ if ( value is byte[] || value == null )
+ {
+ return value;
+ }
+ throw new ArgumentException("Value cannot be converted to byte[]");
+ }
+
+ public override object ReadValueFromBuffer(ByteBuffer buffer)
+ {
+ return EncodingUtils.ReadLongstr(buffer);
+ }
+
+ protected override void WriteValueImpl(object value, ByteBuffer buffer)
+ {
+ EncodingUtils.WriteLongstr(buffer, (byte[])value);
+ }
+ }
+
+ sealed class AMQAsciiStringType : AMQType
+ {
+ public AMQAsciiStringType() : base('c')
+ {
+ }
+
+ public override uint GetEncodingSize(object value)
+ {
+ return EncodingUtils.EncodedAsciiStringLength((string)value);
+ }
+
+ public override object ToNativeValue(object value)
+ {
+ if ( value == null )
+ throw new ArgumentNullException("value");
+ return value.ToString();
+ }
+
+ public override object ReadValueFromBuffer(ByteBuffer buffer)
+ {
+ return EncodingUtils.ReadAsciiString(buffer);
+ }
+
+ protected override void WriteValueImpl(object value, ByteBuffer buffer)
+ {
+ EncodingUtils.WriteAsciiString(buffer, (string)value);
+ }
+ }
+
+ sealed class AMQWideStringType : AMQType
+ {
+ // todo: Change encoding to UTF16 (java code still uses default
+ // ascii encoding for wide strings
+ private static readonly Encoding ENCODING = Encoding.ASCII;
+
+ public AMQWideStringType()
+ : base('C')
+ {
+ }
+
+ public override uint GetEncodingSize(object value)
+ {
+ return EncodingUtils.EncodedLongStringLength((string)value, ENCODING);
+ }
+
+ public override object ToNativeValue(object value)
+ {
+ if ( value == null )
+ throw new ArgumentNullException("value");
+ return value.ToString();
+ }
+
+ public override object ReadValueFromBuffer(ByteBuffer buffer)
+ {
+ return EncodingUtils.ReadLongString(buffer, ENCODING);
+ }
+
+ protected override void WriteValueImpl(object value, ByteBuffer buffer)
+ {
+ EncodingUtils.WriteLongStringBytes(buffer, (string)value, ENCODING);
+ }
+ }
+
+ sealed class AMQBooleanType : AMQType
+ {
+ public AMQBooleanType() : base('t')
+ {
+ }
+
+ public override uint GetEncodingSize(object value)
+ {
+ return EncodingUtils.EncodedBooleanLength();
+ }
+
+ public override object ToNativeValue(object value)
+ {
+ return Convert.ToBoolean(value);
+ }
+
+ public override object ReadValueFromBuffer(ByteBuffer buffer)
+ {
+ return EncodingUtils.ReadBoolean(buffer);
+ }
+
+ protected override void WriteValueImpl(object value, ByteBuffer buffer)
+ {
+ EncodingUtils.WriteBoolean(buffer, (bool)value);
+ }
+ }
+
+ sealed class AMQAsciiCharType : AMQType
+ {
+ public AMQAsciiCharType() : base('k')
+ {
+ }
+
+ public override uint GetEncodingSize(object value)
+ {
+ return EncodingUtils.EncodedCharLength();
+ }
+
+ public override object ToNativeValue(object value)
+ {
+ return Convert.ToChar(value);
+ }
+
+ public override object ReadValueFromBuffer(ByteBuffer buffer)
+ {
+ return EncodingUtils.ReadChar(buffer);
+ }
+
+ protected override void WriteValueImpl(object value, ByteBuffer buffer)
+ {
+ EncodingUtils.WriteChar(buffer, (char)value);
+ }
+ }
+
+ sealed class AMQByteType : AMQType
+ {
+ public AMQByteType() : base('B')
+ {
+ }
+
+ public override uint GetEncodingSize(object value)
+ {
+ return EncodingUtils.EncodedByteLength();
+ }
+
+ public override object ToNativeValue(object value)
+ {
+ return Convert.ToByte(value);
+ }
+
+ public override object ReadValueFromBuffer(ByteBuffer buffer)
+ {
+ return EncodingUtils.ReadByte(buffer);
+ }
+
+ protected override void WriteValueImpl(object value, ByteBuffer buffer)
+ {
+ EncodingUtils.WriteByte(buffer, (byte)value);
+ }
+ }
+
+ sealed class AMQSByteType : AMQType
+ {
+ public AMQSByteType()
+ : base('b')
+ {
+ }
+
+ public override uint GetEncodingSize(object value)
+ {
+ return EncodingUtils.EncodedSByteLength();
+ }
+
+ public override object ToNativeValue(object value)
+ {
+ return Convert.ToSByte(value);
+ }
+
+ public override object ReadValueFromBuffer(ByteBuffer buffer)
+ {
+ return EncodingUtils.ReadSByte(buffer);
+ }
+
+ protected override void WriteValueImpl(object value, ByteBuffer buffer)
+ {
+ EncodingUtils.WriteSByte(buffer, (sbyte)value);
+ }
+ }
+
+ sealed class AMQInt16Type : AMQType
+ {
+ public AMQInt16Type() : base('s')
+ {
+ }
+
+ public override uint GetEncodingSize(object value)
+ {
+ return EncodingUtils.EncodedShortLength();
+ }
+
+ public override object ToNativeValue(object value)
+ {
+ return Convert.ToInt16(value);
+ }
+
+ public override object ReadValueFromBuffer(ByteBuffer buffer)
+ {
+ return EncodingUtils.ReadShort(buffer);
+ }
+
+ protected override void WriteValueImpl(object value, ByteBuffer buffer)
+ {
+ EncodingUtils.WriteShort(buffer, (short)value);
+ }
+ }
+
+ sealed class AMQUInt16Type : AMQType
+ {
+ public AMQUInt16Type()
+ : base('S')
+ {
+ }
+
+ public override uint GetEncodingSize(object value)
+ {
+ return EncodingUtils.EncodedUnsignedShortLength();
+ }
+
+ public override object ToNativeValue(object value)
+ {
+ return Convert.ToUInt16(value);
+ }
+
+ public override object ReadValueFromBuffer(ByteBuffer buffer)
+ {
+ return EncodingUtils.ReadUnsignedShort(buffer);
+ }
+
+ protected override void WriteValueImpl(object value, ByteBuffer buffer)
+ {
+ EncodingUtils.WriteUnsignedShort(buffer, (ushort)value);
+ }
+ }
+
+ sealed class AMQInt32Type : AMQType
+ {
+ public AMQInt32Type() : base('I')
+ {
+ }
+
+ public override uint GetEncodingSize(object value)
+ {
+ return EncodingUtils.EncodedIntegerLength();
+ }
+
+ public override object ToNativeValue(object value)
+ {
+ return Convert.ToInt32(value);
+ }
+
+ public override object ReadValueFromBuffer(ByteBuffer buffer)
+ {
+ return EncodingUtils.ReadInteger(buffer);
+ }
+
+ protected override void WriteValueImpl(object value, ByteBuffer buffer)
+ {
+ EncodingUtils.WriteInteger(buffer, (int)value);
+ }
+ }
+
+ sealed class AMQInt64Type : AMQType
+ {
+ public AMQInt64Type() : base('l')
+ {
+ }
+
+ public override uint GetEncodingSize(object value)
+ {
+ return EncodingUtils.EncodedLongLength();
+ }
+
+ public override object ToNativeValue(object value)
+ {
+ return Convert.ToInt64(value);
+ }
+
+ public override object ReadValueFromBuffer(ByteBuffer buffer)
+ {
+ return EncodingUtils.ReadLong(buffer);
+ }
+
+ protected override void WriteValueImpl(object value, ByteBuffer buffer)
+ {
+ EncodingUtils.WriteLong(buffer, (long)value);
+ }
+ }
+
+ sealed class AMQUInt64Type : AMQType
+ {
+ public AMQUInt64Type()
+ : base('L')
+ {
+ }
+
+ public override uint GetEncodingSize(object value)
+ {
+ return EncodingUtils.EncodedUnsignedLongLength();
+ }
+
+ public override object ToNativeValue(object value)
+ {
+ return Convert.ToUInt64(value);
+ }
+
+ public override object ReadValueFromBuffer(ByteBuffer buffer)
+ {
+ return EncodingUtils.ReadUnsignedLong(buffer);
+ }
+
+ protected override void WriteValueImpl(object value, ByteBuffer buffer)
+ {
+ EncodingUtils.WriteUnsignedLong(buffer, (ulong)value);
+ }
+ }
+
+ sealed class AMQFloatType : AMQType
+ {
+ public AMQFloatType() : base('f')
+ {
+ }
+
+ public override uint GetEncodingSize(object value)
+ {
+ return EncodingUtils.EncodedFloatLength();
+ }
+
+ public override object ToNativeValue(object value)
+ {
+ return Convert.ToSingle(value);
+ }
+
+ public override object ReadValueFromBuffer(ByteBuffer buffer)
+ {
+ return EncodingUtils.ReadFloat(buffer);
+ }
+
+ protected override void WriteValueImpl(object value, ByteBuffer buffer)
+ {
+ EncodingUtils.WriteFloat(buffer, (float)value);
+ }
+ }
+
+ sealed class AMQDoubleType : AMQType
+ {
+ public AMQDoubleType() : base('d')
+ {
+ }
+
+ public override uint GetEncodingSize(object value)
+ {
+ return EncodingUtils.EncodedDoubleLength();
+ }
+
+ public override object ToNativeValue(object value)
+ {
+ return Convert.ToDouble(value);
+ }
+
+ public override object ReadValueFromBuffer(ByteBuffer buffer)
+ {
+ return EncodingUtils.ReadDouble(buffer);
+ }
+
+ protected override void WriteValueImpl(object value, ByteBuffer buffer)
+ {
+ EncodingUtils.WriteDouble(buffer, (double)value);
+ }
+ }
+
+ #endregion // Type Implementation
+
+ } // class AMQType
+}
diff --git a/qpid/dotnet/Qpid.Common/Framing/AMQTypeMap.cs b/qpid/dotnet/Qpid.Common/Framing/AMQTypeMap.cs
new file mode 100644
index 0000000000..8497c283f9
--- /dev/null
+++ b/qpid/dotnet/Qpid.Common/Framing/AMQTypeMap.cs
@@ -0,0 +1,75 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+using System;
+using System.Collections;
+
+namespace Apache.Qpid.Framing
+{
+ public sealed class AMQTypeMap
+ {
+ private static Hashtable _reverseTypeMap;
+
+ private AMQTypeMap()
+ {
+ }
+
+ static AMQTypeMap()
+ {
+ _reverseTypeMap = Hashtable.Synchronized(new Hashtable());
+
+ Add(AMQType.LONG_STRING);
+ Add(AMQType.BOOLEAN);
+ Add(AMQType.BYTE);
+ Add(AMQType.SBYTE);
+ Add(AMQType.INT16);
+ // not supported for now as type code conflicts
+ // with LONG_STRING
+ //Add(AMQType.UINT16);
+ Add(AMQType.INT32);
+ Add(AMQType.UINT32);
+ Add(AMQType.INT64);
+ Add(AMQType.UINT64);
+ Add(AMQType.FLOAT);
+ Add(AMQType.DOUBLE);
+ Add(AMQType.DECIMAL);
+ Add(AMQType.BINARY);
+ Add(AMQType.ASCII_STRING);
+ Add(AMQType.WIDE_STRING);
+ Add(AMQType.ASCII_CHARACTER);
+ Add(AMQType.TIMESTAMP);
+ Add(AMQType.FIELD_TABLE);
+ Add(AMQType.VOID);
+ }
+
+ public static AMQType GetType(byte identifier)
+ {
+ AMQType type = (AMQType)_reverseTypeMap[identifier];
+ if ( type == null )
+ throw new ArgumentOutOfRangeException(string.Format("No such type code: {0:x}", identifier));
+ return type;
+ }
+
+ private static void Add(AMQType type)
+ {
+ _reverseTypeMap.Add(type.Identifier, type);
+ }
+ }
+}
diff --git a/qpid/dotnet/Qpid.Common/Framing/AMQTypedValue.cs b/qpid/dotnet/Qpid.Common/Framing/AMQTypedValue.cs
new file mode 100644
index 0000000000..3d2e313fa6
--- /dev/null
+++ b/qpid/dotnet/Qpid.Common/Framing/AMQTypedValue.cs
@@ -0,0 +1,76 @@
+/*
+ *
+ * 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.
+ *
+ */
+using System;
+using Apache.Qpid.Buffer;
+
+namespace Apache.Qpid.Framing
+{
+ public class AMQTypedValue
+ {
+ private readonly AMQType _type;
+ private readonly object _value;
+
+ public AMQType Type
+ {
+ get { return _type; }
+ }
+
+ public object Value
+ {
+ get { return _value; }
+ }
+
+ public uint EncodingLength
+ {
+ get { return _type.GetEncodingSize(_value); }
+ }
+
+ public AMQTypedValue(AMQType type, object value)
+ {
+ if ( type == null )
+ throw new ArgumentNullException("type");
+ _type = type;
+ _value = type.ToNativeValue(value);
+ }
+
+ public AMQTypedValue(AMQType type, ByteBuffer buffer)
+ {
+ _type = type;
+ _value = type.ReadValueFromBuffer(buffer);
+ }
+
+ public void WriteToBuffer(ByteBuffer buffer)
+ {
+ _type.WriteToBuffer(_value, buffer);
+ }
+
+ public static AMQTypedValue ReadFromBuffer(ByteBuffer buffer)
+ {
+ AMQType type = AMQTypeMap.GetType(buffer.GetByte());
+ return new AMQTypedValue(type, buffer);
+ }
+
+ public override string ToString()
+ {
+ return string.Format("{0}: {1}", Type, Value);
+ }
+ }
+}
diff --git a/qpid/dotnet/Qpid.Common/Framing/BasicContentHeaderProperties.cs b/qpid/dotnet/Qpid.Common/Framing/BasicContentHeaderProperties.cs
new file mode 100644
index 0000000000..47db7b0887
--- /dev/null
+++ b/qpid/dotnet/Qpid.Common/Framing/BasicContentHeaderProperties.cs
@@ -0,0 +1,290 @@
+/*
+ *
+ * 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.
+ *
+ */
+using System;
+using log4net;
+using Apache.Qpid.Buffer;
+using Apache.Qpid.Messaging;
+
+namespace Apache.Qpid.Framing
+{
+ public class BasicContentHeaderProperties : IContentHeaderProperties
+ {
+ private static readonly ILog _log = LogManager.GetLogger(typeof(BasicContentHeaderProperties));
+
+ private string _contentType;
+ private string _encoding;
+ private FieldTable _headers;
+ private byte _deliveryMode;
+ private byte _priority;
+ private string _correlationId;
+ private long _expiration;
+ private string _replyTo;
+ private string _messageId;
+ private ulong _timestamp;
+ private string _type;
+ private string _userId;
+ private string _appId;
+ private string _clusterId;
+
+
+ #region Properties
+ //
+ // Properties
+ //
+
+ /// <summary>
+ /// The MIME Content Type
+ /// </summary>
+ public string ContentType
+ {
+ get { return _contentType; }
+ set { _contentType = value; }
+ }
+
+ /// <summary>
+ /// The MIME Content Encoding
+ /// </summary>
+ public string Encoding
+ {
+ get { return _encoding; }
+ set { _encoding = value; }
+ }
+
+ /// <summary>
+ /// Message headers
+ /// </summary>
+ public FieldTable Headers
+ {
+ get { return _headers; }
+ set { _headers = value; }
+ }
+
+ /// <summary>
+ /// Non-persistent (1) or persistent (2)
+ /// </summary>
+ public byte DeliveryMode
+ {
+ get { return _deliveryMode; }
+ set { _deliveryMode = value; }
+ }
+
+ /// <summary>
+ /// The message priority, 0 to 9
+ /// </summary>
+ public byte Priority
+ {
+ get { return _priority; }
+ set { _priority = value; }
+ }
+
+ /// <summary>
+ /// The application correlation identifier
+ /// </summary>
+ public string CorrelationId
+ {
+ get { return _correlationId; }
+ set { _correlationId = value; }
+ }
+
+ /// <summary>
+ /// Message expiration specification
+ /// </summary>
+ // TODO: Should be string according to spec
+ public long Expiration
+ {
+ get { return _expiration; }
+ set { _expiration = value; }
+ }
+
+ /// <summary>
+ /// The destination to reply to
+ /// </summary>
+ public string ReplyTo
+ {
+ get { return _replyTo; }
+ set { _replyTo = value; }
+ }
+
+ /// <summary>
+ /// The application message identifier
+ /// </summary>
+ public string MessageId
+ {
+ get { return _messageId; }
+ set { _messageId = value; }
+ }
+
+ /// <summary>
+ /// The message timestamp
+ /// </summary>
+ public ulong Timestamp
+ {
+ get { return _timestamp; }
+ set { _timestamp = value; }
+ }
+
+ /// <summary>
+ /// The message type name
+ /// </summary>
+ public string Type
+ {
+ get { return _type; }
+ set { _type = value; }
+ }
+
+ /// <summary>
+ /// The creating user id
+ /// </summary>
+ public string UserId
+ {
+ get { return _userId; }
+ set { _userId = value; }
+ }
+
+ /// <summary>
+ /// The creating application id
+ /// </summary>
+ public string AppId
+ {
+ get { return _appId; }
+ set { _appId = value; }
+ }
+
+ /// <summary>
+ /// Intra-cluster routing identifier
+ /// </summary>
+ public string ClusterId
+ {
+ get { return _clusterId; }
+ set { _clusterId = value; }
+ }
+
+ #endregion // Properties
+
+
+ public BasicContentHeaderProperties()
+ {
+ }
+
+ public uint PropertyListSize
+ {
+ get
+ {
+ return (uint)(EncodingUtils.EncodedShortStringLength(ContentType) +
+ EncodingUtils.EncodedShortStringLength(Encoding) +
+ EncodingUtils.EncodedFieldTableLength(Headers) +
+ 1 + 1 +
+ EncodingUtils.EncodedShortStringLength(CorrelationId) +
+ EncodingUtils.EncodedShortStringLength(ReplyTo) +
+ EncodingUtils.EncodedShortStringLength(String.Format("{0:D}", Expiration)) +
+ EncodingUtils.EncodedShortStringLength(MessageId) +
+ 8 +
+ EncodingUtils.EncodedShortStringLength(Type) +
+ EncodingUtils.EncodedShortStringLength(UserId) +
+ EncodingUtils.EncodedShortStringLength(AppId) +
+ EncodingUtils.EncodedShortStringLength(ClusterId));
+
+ }
+ }
+
+ public ushort PropertyFlags
+ {
+ get
+ {
+ int value = 0;
+
+ // for now we just blast in all properties
+ for ( int i = 0; i < 14; i++ )
+ {
+ value += (1 << (15 - i));
+ }
+ return (ushort)value;
+ }
+ }
+
+ public void WritePropertyListPayload(ByteBuffer buffer)
+ {
+ EncodingUtils.WriteShortStringBytes(buffer, ContentType);
+ EncodingUtils.WriteShortStringBytes(buffer, Encoding);
+ EncodingUtils.WriteFieldTableBytes(buffer, Headers);
+ buffer.Put(DeliveryMode);
+ buffer.Put(Priority);
+ EncodingUtils.WriteShortStringBytes(buffer, CorrelationId);
+ EncodingUtils.WriteShortStringBytes(buffer, ReplyTo);
+ EncodingUtils.WriteShortStringBytes(buffer, String.Format("{0:D}", Expiration));
+ EncodingUtils.WriteShortStringBytes(buffer, MessageId);
+ buffer.Put(Timestamp);
+ EncodingUtils.WriteShortStringBytes(buffer, Type);
+ EncodingUtils.WriteShortStringBytes(buffer, UserId);
+ EncodingUtils.WriteShortStringBytes(buffer, AppId);
+ EncodingUtils.WriteShortStringBytes(buffer, ClusterId);
+ }
+
+ public void PopulatePropertiesFromBuffer(ByteBuffer buffer, ushort propertyFlags)
+ {
+ _log.Debug("Property flags: " + propertyFlags);
+ if ( (propertyFlags & (1 << 15)) > 0 )
+ ContentType = EncodingUtils.ReadShortString(buffer);
+ if ( (propertyFlags & (1 << 14)) > 0 )
+ Encoding = EncodingUtils.ReadShortString(buffer);
+ if ( (propertyFlags & (1 << 13)) > 0 )
+ Headers = EncodingUtils.ReadFieldTable(buffer);
+ if ( (propertyFlags & (1 << 12)) > 0 )
+ DeliveryMode = buffer.GetByte();
+ if ( (propertyFlags & (1 << 11)) > 0 )
+ Priority = buffer.GetByte();
+ if ( (propertyFlags & (1 << 10)) > 0 )
+ CorrelationId = EncodingUtils.ReadShortString(buffer);
+ if ( (propertyFlags & (1 << 9)) > 0 )
+ ReplyTo = EncodingUtils.ReadShortString(buffer);
+ if ( (propertyFlags & (1 << 8)) > 0 )
+ Expiration = EncodingUtils.ReadLongAsShortString(buffer);
+ if ( (propertyFlags & (1 << 7)) > 0 )
+ MessageId = EncodingUtils.ReadShortString(buffer);
+ if ( (propertyFlags & (1 << 6)) > 0 )
+ Timestamp = buffer.GetUInt64();
+ if ( (propertyFlags & (1 << 5)) > 0 )
+ Type = EncodingUtils.ReadShortString(buffer);
+ if ( (propertyFlags & (1 << 4)) > 0 )
+ UserId = EncodingUtils.ReadShortString(buffer);
+ if ( (propertyFlags & (1 << 3)) > 0 )
+ AppId = EncodingUtils.ReadShortString(buffer);
+ if ( (propertyFlags & (1 << 2)) > 0 )
+ ClusterId = EncodingUtils.ReadShortString(buffer);
+ }
+
+ public void SetDeliveryMode(DeliveryMode deliveryMode)
+ {
+ if ( deliveryMode == Messaging.DeliveryMode.NonPersistent )
+ {
+ DeliveryMode = 1;
+ } else
+ {
+ DeliveryMode = 2;
+ }
+ }
+
+ public override string ToString()
+ {
+ return "Properties: " + ContentType + " " + Encoding + " " + Timestamp + " " + Type;
+ }
+ }
+}
diff --git a/qpid/dotnet/Qpid.Common/Framing/CompositeAMQDataBlock.cs b/qpid/dotnet/Qpid.Common/Framing/CompositeAMQDataBlock.cs
new file mode 100644
index 0000000000..d2b7f606b2
--- /dev/null
+++ b/qpid/dotnet/Qpid.Common/Framing/CompositeAMQDataBlock.cs
@@ -0,0 +1,85 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+using System.Text;
+using Apache.Qpid.Buffer;
+
+namespace Apache.Qpid.Framing
+{
+ public class CompositeAMQDataBlock : IDataBlock, IEncodableAMQDataBlock
+ {
+ private IDataBlock[] _blocks;
+
+ public CompositeAMQDataBlock(IDataBlock[] blocks)
+ {
+ _blocks = blocks;
+ }
+
+ public IDataBlock[] Blocks
+ {
+ get
+ {
+ return _blocks;
+ }
+ }
+
+ public uint Size
+ {
+ get
+ {
+ uint frameSize = 0;
+ foreach (IDataBlock block in _blocks)
+ {
+ frameSize += block.Size;
+ }
+ return frameSize;
+ }
+ }
+
+ public void WritePayload(ByteBuffer buffer)
+ {
+ foreach (IDataBlock block in _blocks)
+ {
+ block.WritePayload(buffer);
+ }
+ }
+
+ public override string ToString()
+ {
+ if (_blocks == null)
+ {
+ return "No blocks contained in composite frame";
+ }
+ else
+ {
+ StringBuilder buf = new StringBuilder(GetType().Name);
+ buf.Append("{");
+ //buf.Append("encodedBlock=").Append(_encodedBlock);
+ for (int i = 0; i < _blocks.Length; i++)
+ {
+ buf.Append(" ").Append(i).Append("=[").Append(_blocks[i].ToString()).Append("]");
+ }
+ buf.Append("}");
+ return buf.ToString();
+ }
+ }
+
+ }
+}
diff --git a/qpid/dotnet/Qpid.Common/Framing/ContentBody.cs b/qpid/dotnet/Qpid.Common/Framing/ContentBody.cs
new file mode 100644
index 0000000000..7a2142985d
--- /dev/null
+++ b/qpid/dotnet/Qpid.Common/Framing/ContentBody.cs
@@ -0,0 +1,100 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+using Apache.Qpid.Buffer;
+
+namespace Apache.Qpid.Framing
+{
+ public class ContentBody : IBody
+ {
+ public const byte TYPE = 3;
+
+ private ByteBuffer _payload;
+
+ public ByteBuffer Payload
+ {
+ get { return _payload; }
+ }
+
+ public ContentBody()
+ {
+ }
+ public ContentBody(ByteBuffer payload)
+ {
+ PopulateFromBuffer(payload, (uint)payload.Remaining);
+ }
+ public ContentBody(ByteBuffer payload, uint length)
+ {
+ PopulateFromBuffer(payload, length);
+ }
+
+ #region IBody Members
+
+ public byte BodyType
+ {
+ get
+ {
+ return TYPE;
+ }
+ }
+
+ public uint Size
+ {
+ get
+ {
+ return (ushort)(Payload == null ? 0 : Payload.Remaining);
+ }
+ }
+
+ public void WritePayload(ByteBuffer buffer)
+ {
+ if (Payload != null)
+ {
+ buffer.Put(Payload);
+ Payload.Rewind();
+ }
+ }
+
+ public void PopulateFromBuffer(ByteBuffer buffer, uint size)
+ {
+ if (size > 0)
+ {
+ _payload = buffer.Slice();
+ _payload.Limit = (int)size;
+ buffer.Skip((int)size);
+ }
+ }
+
+ #endregion
+
+ public static AMQFrame CreateAMQFrame(ushort channelId, ContentBody body)
+ {
+ AMQFrame frame = new AMQFrame();
+ frame.Channel = channelId;
+ frame.BodyFrame = body;
+ return frame;
+ }
+
+ public override string ToString()
+ {
+ return string.Format("ContentBody [ Size: {0} ]", Size);
+ }
+ }
+}
diff --git a/qpid/dotnet/Qpid.Common/Framing/ContentBodyFactory.cs b/qpid/dotnet/Qpid.Common/Framing/ContentBodyFactory.cs
new file mode 100644
index 0000000000..400b2aec08
--- /dev/null
+++ b/qpid/dotnet/Qpid.Common/Framing/ContentBodyFactory.cs
@@ -0,0 +1,53 @@
+/*
+ *
+ * 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.
+ *
+ */
+using log4net;
+using Apache.Qpid.Buffer;
+
+namespace Apache.Qpid.Framing
+{
+ public class ContentBodyFactory : IBodyFactory
+ {
+ private static readonly ILog _log = LogManager.GetLogger(typeof(ContentBodyFactory));
+
+ private static readonly ContentBodyFactory _instance = new ContentBodyFactory();
+
+ public static ContentBodyFactory GetInstance()
+ {
+ return _instance;
+ }
+
+ private ContentBodyFactory()
+ {
+ _log.Debug("Creating content body factory");
+ }
+
+ /// <summary>
+ /// Creates the body.
+ /// </summary>
+ /// <param name="inbuf">The ByteBuffer containing data from the network</param>
+ /// <returns></returns>
+ /// <exception>AMQFrameDecodingException</exception>
+ public IBody CreateBody(ByteBuffer inbuf)
+ {
+ return new ContentBody();
+ }
+ }
+}
diff --git a/qpid/dotnet/Qpid.Common/Framing/ContentHeaderBody.cs b/qpid/dotnet/Qpid.Common/Framing/ContentHeaderBody.cs
new file mode 100644
index 0000000000..82889c23c8
--- /dev/null
+++ b/qpid/dotnet/Qpid.Common/Framing/ContentHeaderBody.cs
@@ -0,0 +1,118 @@
+/*
+ *
+ * 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.
+ *
+ */
+using System;
+using Apache.Qpid.Buffer;
+
+namespace Apache.Qpid.Framing
+{
+ public class ContentHeaderBody : IBody
+ {
+ public static readonly byte TYPE = 2;
+
+ public ushort ClassId;
+
+ public ushort Weight;
+
+ public ulong BodySize;
+
+ /** must never be null */
+ public IContentHeaderProperties Properties;
+
+ public ContentHeaderBody()
+ {
+ }
+
+ public ContentHeaderBody(IContentHeaderProperties props, ushort classId)
+ {
+ Properties = props;
+ ClassId = classId;
+ }
+
+ public ContentHeaderBody(ushort classId, ushort weight, IContentHeaderProperties props, uint bodySize)
+ : this(props, classId)
+ {
+ Weight = weight;
+ BodySize = bodySize;
+ }
+
+ #region IBody Members
+
+ public byte BodyType
+ {
+ get
+ {
+ return TYPE;
+ }
+ }
+
+ public uint Size
+ {
+ get
+ {
+ return (2 + 2 + 8 + 2 + Properties.PropertyListSize);
+ }
+ }
+
+ public void WritePayload(ByteBuffer buffer)
+ {
+ buffer.Put(ClassId);
+ buffer.Put(Weight);
+ buffer.Put(BodySize);
+ buffer.Put(Properties.PropertyFlags);
+ Properties.WritePropertyListPayload(buffer);
+ }
+
+ public void PopulateFromBuffer(ByteBuffer buffer, uint size)
+ {
+ ClassId = buffer.GetUInt16();
+ Weight = buffer.GetUInt16();
+ BodySize = buffer.GetUInt64();
+ ushort propertyFlags = buffer.GetUInt16();
+ ContentHeaderPropertiesFactory factory = ContentHeaderPropertiesFactory.GetInstance();
+ Properties = factory.CreateContentHeaderProperties(ClassId, propertyFlags, buffer);
+ }
+
+ #endregion
+
+ public static AMQFrame CreateAMQFrame(ushort channelId, ushort classId, ushort weight, BasicContentHeaderProperties properties,
+ uint bodySize)
+ {
+ AMQFrame frame = new AMQFrame();
+ frame.Channel = channelId;
+ frame.BodyFrame = new ContentHeaderBody(classId, weight, properties, bodySize);
+ return frame;
+ }
+
+ public static AMQFrame CreateAMQFrame(ushort channelId, ContentHeaderBody body)
+ {
+ AMQFrame frame = new AMQFrame();
+ frame.Channel = channelId;
+ frame.BodyFrame = body;
+ return frame;
+ }
+
+ public override string ToString()
+ {
+ return String.Format("ContentHeaderBody: ClassId {0}, Weight {1}, BodySize {2}, Properties {3}", ClassId, Weight,
+ BodySize, Properties);
+ }
+ }
+}
diff --git a/qpid/dotnet/Qpid.Common/Framing/ContentHeaderBodyFactory.cs b/qpid/dotnet/Qpid.Common/Framing/ContentHeaderBodyFactory.cs
new file mode 100644
index 0000000000..c95a10871d
--- /dev/null
+++ b/qpid/dotnet/Qpid.Common/Framing/ContentHeaderBodyFactory.cs
@@ -0,0 +1,53 @@
+/*
+ *
+ * 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.
+ *
+ */
+using log4net;
+using Apache.Qpid.Buffer;
+
+namespace Apache.Qpid.Framing
+{
+ public class ContentHeaderBodyFactory : IBodyFactory
+ {
+ private static readonly ILog _log = LogManager.GetLogger(typeof(ContentHeaderBodyFactory));
+
+ private static readonly ContentHeaderBodyFactory _instance = new ContentHeaderBodyFactory();
+
+ public static ContentHeaderBodyFactory GetInstance()
+ {
+ return _instance;
+ }
+
+ private ContentHeaderBodyFactory()
+ {
+ _log.Debug("Creating content header body factory");
+ }
+
+ #region IBodyFactory Members
+
+ public IBody CreateBody(ByteBuffer inbuf)
+ {
+ // all content headers are the same - it is only the properties that differ.
+ // the content header body further delegates construction of properties
+ return new ContentHeaderBody();
+ }
+
+ #endregion
+ }
+}
diff --git a/qpid/dotnet/Qpid.Common/Framing/ContentHeaderPropertiesFactory.cs b/qpid/dotnet/Qpid.Common/Framing/ContentHeaderPropertiesFactory.cs
new file mode 100644
index 0000000000..bac5d10fd4
--- /dev/null
+++ b/qpid/dotnet/Qpid.Common/Framing/ContentHeaderPropertiesFactory.cs
@@ -0,0 +1,63 @@
+/*
+ *
+ * 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.
+ *
+ */
+using Apache.Qpid.Buffer;
+
+namespace Apache.Qpid.Framing
+{
+ public class ContentHeaderPropertiesFactory
+ {
+
+ private static readonly ContentHeaderPropertiesFactory _instance = new ContentHeaderPropertiesFactory();
+
+ public static ContentHeaderPropertiesFactory GetInstance()
+ {
+ return _instance;
+ }
+
+ private ContentHeaderPropertiesFactory()
+ {
+ }
+
+ /// <summary>
+ /// Creates the content header properties from a buffer.
+ /// </summary>
+ /// <param name="classId">The class id.</param>
+ /// <param name="propertyFlags">The property flags.</param>
+ /// <param name="buffer">The buffer.</param>
+ /// <returns>a populated properties structure</returns>
+ /// <exception cref="AMQFrameDecodingException">if the buffer cannot be decoded</exception>
+ public IContentHeaderProperties CreateContentHeaderProperties(ushort classId, ushort propertyFlags,
+ ByteBuffer buffer)
+ {
+ IContentHeaderProperties properties;
+ switch (classId)
+ {
+ case 60:
+ properties = new BasicContentHeaderProperties();
+ break;
+ default:
+ throw new AMQFrameDecodingException("Unsupport content header class id: " + classId);
+ }
+ properties.PopulatePropertiesFromBuffer(buffer, propertyFlags);
+ return properties;
+ }
+ }
+}
diff --git a/qpid/dotnet/Qpid.Common/Framing/EncodingUtils.cs b/qpid/dotnet/Qpid.Common/Framing/EncodingUtils.cs
new file mode 100644
index 0000000000..4d424656f9
--- /dev/null
+++ b/qpid/dotnet/Qpid.Common/Framing/EncodingUtils.cs
@@ -0,0 +1,460 @@
+/*
+ *
+ * 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.
+ *
+ */
+using System;
+using System.Globalization;
+using System.Text;
+using Apache.Qpid.Buffer;
+
+namespace Apache.Qpid.Framing
+{
+ public class EncodingUtils
+ {
+ private static readonly Encoding DEFAULT_ENCODER = Encoding.ASCII;
+
+ // SHORT STRING
+ public static ushort EncodedShortStringLength(string s)
+ {
+ if ( s == null )
+ {
+ return 1;
+ } else
+ {
+ return (ushort)(1 + s.Length);
+ }
+ }
+ public static void WriteShortStringBytes(ByteBuffer buffer, string s)
+ {
+ if ( s != null )
+ {
+ //try
+ //{
+ //final byte[] encodedString = s.getBytes(STRING_ENCODING);
+ byte[] encodedString;
+ lock ( DEFAULT_ENCODER )
+ {
+ encodedString = DEFAULT_ENCODER.GetBytes(s);
+ }
+ // TODO: check length fits in an unsigned byte
+ buffer.Put((byte)encodedString.Length);
+ buffer.Put(encodedString);
+
+ } else
+ {
+ // really writing out unsigned byte
+ buffer.Put((byte)0);
+ }
+ }
+
+ // ASCII STRINGS
+ public static uint EncodedAsciiStringLength(string s)
+ {
+ // TODO: move this to 2-byte length once the proposed encodings
+ // have been approved. Also, validate length!
+ if ( s == null )
+ return 4;
+ else
+ return (uint) (4 + s.Length);
+ }
+ public static string ReadAsciiString(ByteBuffer buffer)
+ {
+ return ReadLongString(buffer, DEFAULT_ENCODER);
+ }
+ public static void WriteAsciiString(ByteBuffer buffer, string s)
+ {
+ WriteLongStringBytes(buffer, s, DEFAULT_ENCODER);
+ }
+
+ // LONG STRING
+ public static uint EncodedLongStringLength(string s)
+ {
+ return EncodedLongStringLength(s, DEFAULT_ENCODER);
+ }
+
+ public static uint EncodedLongStringLength(string s, Encoding encoding)
+ {
+ if ( s == null )
+ {
+ return 4;
+ } else
+ {
+ return (uint)(4 + encoding.GetByteCount(s));
+ }
+ }
+ public static string ReadLongString(ByteBuffer buffer)
+ {
+ return ReadLongString(buffer, DEFAULT_ENCODER);
+ }
+ public static string ReadLongString(ByteBuffer buffer, Encoding encoding)
+ {
+ uint length = buffer.GetUInt32();
+ if ( length == 0 )
+ {
+ return null;
+ } else
+ {
+ byte[] data = new byte[length];
+ buffer.GetBytes(data);
+ lock ( encoding )
+ {
+ return encoding.GetString(data);
+ }
+ }
+ }
+ public static void WriteLongStringBytes(ByteBuffer buffer, string s)
+ {
+ WriteLongStringBytes(buffer, s, DEFAULT_ENCODER);
+ }
+
+ public static void WriteLongStringBytes(ByteBuffer buffer, string s, Encoding encoding)
+ {
+ if ( !(s == null || s.Length <= 0xFFFE) )
+ {
+ throw new ArgumentException("String too long");
+ }
+ if ( s != null )
+ {
+ lock ( encoding )
+ {
+ byte[] encodedString = encoding.GetBytes(s);
+ buffer.Put((uint)encodedString.Length);
+ buffer.Put(encodedString);
+ }
+ } else
+ {
+ buffer.Put((uint)0);
+ }
+ }
+
+ // BINARY
+ public static uint EncodedLongstrLength(byte[] bytes)
+ {
+ if ( bytes == null )
+ {
+ return 4;
+ } else
+ {
+ return (uint)(4 + bytes.Length);
+ }
+ }
+ public static byte[] ReadLongstr(ByteBuffer buffer)
+ {
+ uint length = buffer.GetUInt32();
+ if ( length == 0 )
+ {
+ return null;
+ } else
+ {
+ byte[] result = new byte[length];
+ buffer.GetBytes(result);
+ return result;
+ }
+ }
+ public static void WriteLongstr(ByteBuffer buffer, byte[] data)
+ {
+ if ( data != null )
+ {
+ buffer.Put((uint)data.Length);
+ buffer.Put(data);
+ } else
+ {
+ buffer.Put((uint)0);
+ }
+ }
+
+ // BOOLEANS
+ public static bool[] ReadBooleans(ByteBuffer buffer)
+ {
+ byte packedValue = buffer.GetByte();
+ bool[] result = new bool[8];
+
+ for ( int i = 0; i < 8; i++ )
+ {
+ result[i] = ((packedValue & (1 << i)) != 0);
+ }
+ return result;
+ }
+ public static void WriteBooleans(ByteBuffer buffer, bool[] values)
+ {
+ byte packedValue = 0;
+ for ( int i = 0; i < values.Length; i++ )
+ {
+ if ( values[i] )
+ {
+ packedValue = (byte)(packedValue | (1 << i));
+ }
+ }
+
+ buffer.Put(packedValue);
+ }
+
+ // FIELD TABLES
+ public static uint EncodedFieldTableLength(FieldTable table)
+ {
+ if ( table == null )
+ {
+ // size is encoded as 4 octets
+ return 4;
+ } else
+ {
+ // size of the table plus 4 octets for the size
+ return table.EncodedSize + 4;
+ }
+ }
+ /// <summary>
+ /// Reads the field table using the data in the specified buffer
+ /// </summary>
+ /// <param name="buffer">The buffer to read from.</param>
+ /// <returns>a populated field table</returns>
+ /// <exception cref="AMQFrameDecodingException">if the buffer does not contain a decodable field table</exception>
+ public static FieldTable ReadFieldTable(ByteBuffer buffer)
+ {
+ uint length = buffer.GetUInt32();
+ if ( length == 0 )
+ {
+ return null;
+ } else
+ {
+ return new FieldTable(buffer, length);
+ }
+ }
+ public static void WriteFieldTableBytes(ByteBuffer buffer, FieldTable table)
+ {
+ if ( table != null )
+ {
+ table.WriteToBuffer(buffer);
+ } else
+ {
+ buffer.Put((uint)0);
+ }
+ }
+
+
+ /// <summary>
+ /// Read a short string from the buffer
+ /// </summary>
+ /// <param name="buffer">The buffer to read from.</param>
+ /// <returns>a string</returns>
+ /// <exception cref="AMQFrameDecodingException">if the buffer does not contain a decodable short string</exception>
+ public static string ReadShortString(ByteBuffer buffer)
+ {
+ byte length = buffer.GetByte();
+ if ( length == 0 )
+ {
+ return null;
+ } else
+ {
+ byte[] data = new byte[length];
+ buffer.GetBytes(data);
+
+ lock ( DEFAULT_ENCODER )
+ {
+ return DEFAULT_ENCODER.GetString(data);
+ }
+ }
+ }
+
+
+
+ // BOOLEAN
+ public static uint EncodedBooleanLength()
+ {
+ return 1;
+ }
+ public static bool ReadBoolean(ByteBuffer buffer)
+ {
+ byte packedValue = buffer.GetByte();
+ return (packedValue == 1);
+ }
+ public static void WriteBoolean(ByteBuffer buffer, bool value)
+ {
+ buffer.Put((byte)(value ? 1 : 0));
+ }
+
+
+ // CHAR
+ public static uint EncodedCharLength()
+ {
+ return EncodedByteLength();
+ }
+ public static char ReadChar(ByteBuffer buffer)
+ {
+ return (char)buffer.GetByte();
+ }
+ public static void WriteChar(ByteBuffer buffer, char value)
+ {
+ buffer.Put((byte)value);
+ }
+
+ // BYTE
+ public static uint EncodedByteLength()
+ {
+ return 1;
+ }
+ public static byte ReadByte(ByteBuffer buffer)
+ {
+ return buffer.GetByte();
+ }
+ public static void WriteByte(ByteBuffer buffer, byte value)
+ {
+ buffer.Put(value);
+ }
+
+ // SBYTE
+ public static uint EncodedSByteLength()
+ {
+ return 1;
+ }
+ public static sbyte ReadSByte(ByteBuffer buffer)
+ {
+ return buffer.GetSByte();
+ }
+ public static void WriteSByte(ByteBuffer buffer, sbyte value)
+ {
+ buffer.Put(value);
+ }
+
+ // INT16
+ public static uint EncodedShortLength()
+ {
+ return 2;
+ }
+
+ public static short ReadShort(ByteBuffer buffer)
+ {
+ return buffer.GetInt16();
+ }
+ public static void WriteShort(ByteBuffer buffer, short value)
+ {
+ buffer.Put(value);
+ }
+
+ // UINT16
+ public static uint EncodedUnsignedShortLength()
+ {
+ return 2;
+ }
+
+ public static ushort ReadUnsignedShort(ByteBuffer buffer)
+ {
+ return buffer.GetUInt16();
+ }
+ public static void WriteUnsignedShort(ByteBuffer buffer, ushort value)
+ {
+ buffer.Put(value);
+ }
+
+
+ // INT32
+ public static uint EncodedIntegerLength()
+ {
+ return 4;
+ }
+ public static int ReadInteger(ByteBuffer buffer)
+ {
+ return buffer.GetInt32();
+ }
+ public static void WriteInteger(ByteBuffer buffer, int value)
+ {
+ buffer.Put(value);
+ }
+
+ // UINT32
+ public static uint UnsignedIntegerLength()
+ {
+ return 4;
+ }
+ public static void WriteUnsignedInteger(ByteBuffer buffer, uint value)
+ {
+ buffer.Put(value);
+ }
+ public static uint ReadUnsignedInteger(ByteBuffer buffer)
+ {
+ return buffer.GetUInt32();
+ }
+
+ // INT64
+ public static uint EncodedUnsignedLongLength()
+ {
+ return 8;
+ }
+ public static ulong ReadUnsignedLong(ByteBuffer buffer)
+ {
+ return buffer.GetUInt64();
+ }
+ public static void WriteUnsignedLong(ByteBuffer buffer, ulong value)
+ {
+ buffer.Put(value);
+ }
+
+ // UINT64
+ public static uint EncodedLongLength()
+ {
+ return 8;
+ }
+ public static long ReadLong(ByteBuffer buffer)
+ {
+ return buffer.GetInt64();
+ }
+ public static void WriteLong(ByteBuffer buffer, long value)
+ {
+ buffer.Put(value);
+ }
+
+ // FLOAT
+ public static uint EncodedFloatLength()
+ {
+ return 4;
+ }
+ public static void WriteFloat(ByteBuffer buffer, float value)
+ {
+ buffer.Put(value);
+ }
+ public static float ReadFloat(ByteBuffer buffer)
+ {
+ return buffer.GetFloat();
+ }
+
+ // DOUBLE
+ public static uint EncodedDoubleLength()
+ {
+ return 8;
+ }
+ public static void WriteDouble(ByteBuffer buffer, double value)
+ {
+ buffer.Put(value);
+ }
+ public static double ReadDouble(ByteBuffer buffer)
+ {
+ return buffer.GetDouble();
+ }
+
+ // OTHER
+ public static long ReadLongAsShortString(ByteBuffer buffer)
+ {
+ string value = ReadShortString(buffer);
+ if ( value == null || value.Length == 0 )
+ return 0L;
+ return Convert.ToInt64(value, CultureInfo.InvariantCulture);
+ }
+
+ }
+
+}
diff --git a/qpid/dotnet/Qpid.Common/Framing/FieldTable.cs b/qpid/dotnet/Qpid.Common/Framing/FieldTable.cs
new file mode 100644
index 0000000000..6567bf58ab
--- /dev/null
+++ b/qpid/dotnet/Qpid.Common/Framing/FieldTable.cs
@@ -0,0 +1,633 @@
+/*
+ *
+ * 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.
+ *
+ */
+using System;
+using System.Collections;
+using System.Text;
+using log4net;
+using Apache.Qpid.Buffer;
+using Apache.Qpid.Collections;
+using Apache.Qpid.Messaging;
+
+namespace Apache.Qpid.Framing
+{
+ public class FieldTable : IFieldTable, IEnumerable
+ {
+ private static readonly ILog _log = LogManager.GetLogger(typeof(FieldTable));
+
+ IDictionary _properties;
+ private ByteBuffer _encodedForm;
+ private object _syncLock;
+ private uint _encodedSize;
+
+ public FieldTable()
+ {
+ _syncLock = new object();
+ }
+
+ /// <summary>
+ /// Construct a new field table.
+ /// </summary>
+ /// <param name="buffer">the buffer from which to read data. The length byte must be read already</param>
+ /// <param name="length">the length of the field table. Must be > 0.</param>
+ public FieldTable(ByteBuffer buffer, uint length) : this()
+ {
+ _encodedForm = buffer.Slice();
+ _encodedForm.Limit = (int)length;
+ _encodedSize = length;
+ buffer.Skip((int)length);
+ }
+
+ /// <summary>
+ /// The set of all property names
+ /// </summary>
+ public ICollection Keys
+ {
+ get
+ {
+ InitMapIfNecessary();
+ return _properties.Keys;
+ }
+ }
+
+ /// <summary>
+ /// Calculated size of this field table once encoded
+ /// </summary>
+ public uint EncodedSize
+ {
+ get { return _encodedSize; }
+ }
+
+ /// <summary>
+ /// Number of properties in the field table
+ /// </summary>
+ public int Count
+ {
+ get
+ {
+ InitMapIfNecessary();
+ return _properties.Count;
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets the specified property.
+ /// </summary>
+ /// <param name="key">Property name</param>
+ /// <returns>The specified property value</returns>
+ public object this[string key]
+ {
+ get { return GetObject(key); }
+ set { SetObject(key, value); }
+ }
+
+ #region Typed Setters and Getters
+ //
+ // Typed Setters and Getters
+ //
+ public bool GetBoolean(string key)
+ {
+ return (bool)this[key];
+ }
+ public void SetBoolean(string key, bool value)
+ {
+ CheckPropertyName(key);
+ SetProperty(key, AMQType.BOOLEAN.AsTypedValue(value));
+ }
+ public byte GetByte(string key)
+ {
+ return (byte)this[key];
+ }
+ public void SetByte(string key, byte value)
+ {
+ CheckPropertyName(key);
+ SetProperty(key, AMQType.BYTE.AsTypedValue(value));
+ }
+ public sbyte GetSByte(string key)
+ {
+ return (sbyte)this[key];
+ }
+ public void SetSByte(string key, sbyte value)
+ {
+ CheckPropertyName(key);
+ SetProperty(key, AMQType.SBYTE.AsTypedValue(value));
+ }
+ public short GetInt16(string key)
+ {
+ return (short)this[key];
+ }
+ public void SetInt16(string key, short value)
+ {
+ CheckPropertyName(key);
+ SetProperty(key, AMQType.INT16.AsTypedValue(value));
+ }
+ public int GetInt32(string key)
+ {
+ return (int)this[key];
+ }
+ public void SetInt32(string key, int value)
+ {
+ CheckPropertyName(key);
+ SetProperty(key, AMQType.INT32.AsTypedValue(value));
+ }
+ public long GetInt64(string key)
+ {
+ return (long)this[key];
+ }
+ public void SetInt64(string key, long value)
+ {
+ CheckPropertyName(key);
+ SetProperty(key, AMQType.INT64.AsTypedValue(value));
+ }
+ public char GetChar(string key)
+ {
+ return (char)this[key];
+ }
+ public void SetChar(string key, char value)
+ {
+ CheckPropertyName(key);
+ SetProperty(key, AMQType.ASCII_CHARACTER.AsTypedValue(value));
+ }
+ public float GetFloat(string key)
+ {
+ return (float)this[key];
+ }
+ public void SetFloat(string key, float value)
+ {
+ CheckPropertyName(key);
+ SetProperty(key, AMQType.FLOAT.AsTypedValue(value));
+ }
+ public double GetDouble(string key)
+ {
+ return (double)this[key];
+ }
+ public void SetDouble(string key, double value)
+ {
+ CheckPropertyName(key);
+ SetProperty(key, AMQType.DOUBLE.AsTypedValue(value));
+ }
+ public decimal GetDecimal(string key)
+ {
+ return (decimal)this[key];
+ }
+ public void SetDecimal(string key, decimal value)
+ {
+ CheckPropertyName(key);
+ SetProperty(key, AMQType.DECIMAL.AsTypedValue(value));
+ }
+ public string GetString(string key)
+ {
+ return (string)this[key];
+ }
+ public void SetString(string key, string value)
+ {
+ CheckPropertyName(key);
+ if ( value == null )
+ SetProperty(key, AMQType.VOID.AsTypedValue(null));
+ else
+ SetProperty(key, AMQType.LONG_STRING.AsTypedValue(value));
+ }
+ public byte[] GetBytes(string key)
+ {
+ return (byte[])this[key];
+ }
+ public void SetBytes(string key, byte[] value)
+ {
+ CheckPropertyName(key);
+ SetProperty(key, AMQType.BINARY.AsTypedValue(value));
+ }
+ public ushort GetUInt16(string key)
+ {
+ return (ushort)this[key];
+ }
+ public void SetUInt16(string key, ushort value)
+ {
+ CheckPropertyName(key);
+ SetProperty(key, AMQType.UINT16.AsTypedValue(value));
+ }
+ public uint GetUInt32(string key)
+ {
+ return (uint)this[key];
+ }
+ public void SetUInt32(string key, uint value)
+ {
+ CheckPropertyName(key);
+ SetProperty(key, AMQType.UINT32.AsTypedValue(value));
+ }
+ public ulong GetUInt64(string key)
+ {
+ return (ulong)this[key];
+ }
+ public void SetUInt64(string key, ulong value)
+ {
+ CheckPropertyName(key);
+ SetProperty(key, AMQType.UINT64.AsTypedValue(value));
+ }
+
+ #endregion // Typed Setters and Getters
+
+ #region Public Methods
+ //
+ // Public Methods
+ //
+
+ /// <summary>
+ /// Removes the property with the specified name
+ /// </summary>
+ /// <param name="key">The name of the property to remove</param>
+ /// <returns>The previous value of the property or null</returns>
+ public AMQTypedValue RemoveKey(string key)
+ {
+ InitMapIfNecessary();
+ _encodedForm = null;
+ AMQTypedValue value = (AMQTypedValue)_properties[key];
+ if ( value != null )
+ {
+ _properties.Remove(key);
+ _encodedSize -= EncodingUtils.EncodedShortStringLength(key);
+ _encodedSize--;
+ _encodedSize -= value.EncodingLength;
+
+ }
+ return value;
+ }
+
+
+ /// <summary>
+ /// Remove the property with the specified name
+ /// </summary>
+ /// <param name="key">The name of the property to remove</param>
+ public void Remove(string key)
+ {
+ RemoveKey(key);
+ }
+
+ /// <summary>
+ /// Remove all properties from the table
+ /// </summary>
+ public void Clear()
+ {
+ InitMapIfNecessary();
+ _encodedForm = null;
+ _properties.Clear();
+ _encodedSize = 0;
+ }
+
+ /// <summary>
+ /// Adds all the items from one field table in this one. Will overwrite any items in the current table
+ /// with the same key.
+ /// </summary>
+ /// <param name="ft">the source field table</param>
+ public void AddAll(IFieldTable ft)
+ {
+ foreach ( DictionaryEntry dictionaryEntry in ft )
+ {
+ this[(string)dictionaryEntry.Key] = dictionaryEntry.Value;
+ }
+ }
+
+ /// <summary>
+ /// Get a enumerator over the internal property set.
+ /// Notice the enumerator will DictionaryEntry objects with
+ /// a string as the Key and an <see cref="AMQTypedValue"/> instance as the value
+ /// </summary>
+ /// <returns>The enumerator object</returns>
+ public IEnumerator GetEnumerator()
+ {
+ InitMapIfNecessary();
+ return _properties.GetEnumerator();
+ }
+
+ /// <summary>
+ /// Indicates if a property with the given name exists
+ /// </summary>
+ /// <param name="s">Property name to check</param>
+ /// <returns>True if the property exists</returns>
+ public bool Contains(string s)
+ {
+ InitMapIfNecessary();
+ return _properties.Contains(s);
+ }
+
+ /// <summary>
+ /// Returns a dictionary mapping Property Names to the corresponding
+ /// <see cref="AMQTypedValue"/> value
+ /// </summary>
+ /// <returns>The internal dictionary</returns>
+ public IDictionary AsDictionary()
+ {
+ InitMapIfNecessary();
+ return _properties;
+ }
+
+ /// <summary>
+ /// Returns a string representation of this field table
+ /// </summary>
+ /// <returns>A string</returns>
+ public override string ToString()
+ {
+ StringBuilder sb = new StringBuilder("FieldTable {");
+
+ bool first = true;
+ InitMapIfNecessary();
+ foreach ( DictionaryEntry entry in _properties )
+ {
+ if ( !first )
+ {
+ sb.Append(", ");
+ }
+ first = false;
+ sb.Append(entry.Key).Append(" => ").Append(entry.Value);
+ }
+
+ sb.Append("}");
+ return sb.ToString();
+ }
+
+ /// <summary>
+ /// Serializes this instance to the specified <see cref="ByteBuffer"/>.
+ /// </summary>
+ /// <param name="buffer">The buffer to write to</param>
+ public void WriteToBuffer(ByteBuffer buffer)
+ {
+ if ( _log.IsDebugEnabled )
+ {
+ _log.Debug("FieldTable::writeToBuffer: Writing encoded length of " + EncodedSize + "...");
+ }
+
+ EncodingUtils.WriteUnsignedInteger(buffer, EncodedSize);
+ WritePayload(buffer);
+ }
+
+ /// <summary>
+ /// Returns a byte array with the serialized representation
+ /// of this field table
+ /// </summary>
+ /// <returns>An array of bytes</returns>
+ public byte[] GetDataAsBytes()
+ {
+ ByteBuffer buffer = ByteBuffer.Allocate((int)_encodedSize);
+ WritePayload(buffer);
+ byte[] result = new byte[_encodedSize];
+ buffer.Flip();
+ buffer.GetBytes(result);
+ //buffer.Release();
+ return result;
+ }
+
+ #endregion // Public Methods
+
+ #region Private Methods
+ //
+ // Private Methods
+ //
+
+ private static void CheckPropertyName(string propertyName)
+ {
+ if ( propertyName == null || propertyName.Length == 0 )
+ throw new ArgumentNullException("propertyName");
+ CheckIdentifierFormat(propertyName);
+ }
+
+ private static void CheckIdentifierFormat(string propertyName)
+ {
+ // AMQP Spec: 4.2.5.5 Field Tables
+ // Guidelines for implementers:
+ // * Field names MUST start with a letter, '$' or '#' and may continue with
+ // letters, '$' or '#', digits, or underlines, to a maximum length of 128
+ // characters.
+ // * The server SHOULD validate field names and upon receiving an invalid
+ // field name, it SHOULD signal a connection exception with reply code
+ // 503 (syntax error). Conformance test: amq_wlp_table_01.
+ // * A peer MUST handle duplicate fields by using only the first instance.
+
+
+ // AMQP length limit
+ if ( propertyName.Length > 128 )
+ {
+ throw new ArgumentException("AMQP limits property names to 128 characters");
+ }
+
+ // AMQ start character
+ if ( !(Char.IsLetter(propertyName[0])
+ || propertyName[0] == '$'
+ || propertyName[0] == '#'
+ || propertyName[0] == '_' ) )// Not official AMQP added for JMS.
+ {
+ throw new ArgumentException("Identifier '" + propertyName + "' does not start with a valid AMQP start character");
+ }
+ }
+
+ private object GetObject(string key)
+ {
+ AMQTypedValue value = GetProperty(key);
+ return value != null ? value.Value : null;
+ }
+
+ private void SetObject(string key, object value)
+ {
+ if ( value is bool )
+ {
+ SetBoolean(key, (bool)value);
+ } else if ( value is byte )
+ {
+ SetByte(key, (byte)value);
+ } else if ( value is sbyte )
+ {
+ SetSByte(key, (sbyte)value);
+ } else if ( value is short )
+ {
+ SetInt16(key, (short)value);
+ } else if ( value is ushort )
+ {
+ SetUInt16(key, (ushort)value);
+ } else if ( value is int )
+ {
+ SetInt32(key, (int) value);
+ } else if ( value is uint )
+ {
+ SetUInt32(key, (uint)value);
+ } else if ( value is long )
+ {
+ SetInt64(key, (long) value);
+ } else if ( value is ulong )
+ {
+ SetUInt64(key, (ulong)value);
+ } else if ( value is char )
+ {
+ SetChar(key, (char) value);
+ } else if ( value is float )
+ {
+ SetFloat(key, (float) value);
+ } else if ( value is double )
+ {
+ SetDouble(key, (double) value);
+ } else if ( value is decimal )
+ {
+ SetDecimal(key, (decimal) value);
+ } else if ( value is string )
+ {
+ SetString(key, (string) value);
+ } else if ( value is byte[] )
+ {
+ SetBytes(key, (byte[])value);
+ } else
+ {
+ throw new ArgumentException("Data type not supported yet");
+ }
+ }
+
+ private AMQTypedValue GetProperty(string name)
+ {
+ InitMapIfNecessary();
+ return (AMQTypedValue) _properties[name];
+ }
+
+ private void PopulateFromBuffer()
+ {
+ try
+ {
+ ByteBuffer buffer = _encodedForm;
+ _encodedForm = null;
+ if ( buffer != null )
+ SetFromBuffer(buffer, _encodedSize);
+ } catch ( AMQFrameDecodingException e )
+ {
+ _log.Error("Error decoding FieldTable in deferred decoding mode ", e);
+ throw;
+ }
+ }
+
+ private void SetFromBuffer(ByteBuffer buffer, uint length)
+ {
+ bool trace = _log.IsDebugEnabled;
+ if ( length > 0 )
+ {
+ int expectedRemaining = buffer.Remaining - (int)length;
+ _properties = new LinkedHashtable();
+
+ do
+ {
+ string key = EncodingUtils.ReadShortString(buffer);
+ AMQTypedValue value = AMQTypedValue.ReadFromBuffer(buffer);
+ if ( trace )
+ {
+ _log.Debug(string.Format("FieldTable::PropFieldTable(buffer,{0}): Read type '{1}', key '{2}', value '{3}'", length, value.Type, key, value.Value));
+ }
+ _properties.Add(key, value);
+
+ } while ( buffer.Remaining > expectedRemaining );
+ _encodedSize = length;
+ }
+ if ( trace )
+ {
+ _log.Debug("FieldTable::FieldTable(buffer," + length + "): Done.");
+ }
+ }
+
+ private void InitMapIfNecessary()
+ {
+ lock ( _syncLock )
+ {
+ if ( _properties == null )
+ {
+ if ( _encodedForm == null )
+ {
+ _properties = new LinkedHashtable();
+ } else
+ {
+ PopulateFromBuffer();
+ }
+ }
+ }
+ }
+
+ private AMQTypedValue SetProperty(string key, AMQTypedValue value)
+ {
+ InitMapIfNecessary();
+ _encodedForm = null;
+ if ( value == null )
+ {
+ RemoveKey(key);
+ }
+ AMQTypedValue oldVal = (AMQTypedValue)_properties[key];
+ _properties.Add(key, value);
+ if ( oldVal != null )
+ {
+ _encodedSize -= oldVal.EncodingLength;
+ } else
+ {
+ _encodedSize += EncodingUtils.EncodedShortStringLength(key) + (uint)1;
+ }
+ if ( value != null )
+ {
+ _encodedSize += value.EncodingLength;
+ }
+
+ return oldVal;
+ }
+
+ public void WritePayload(ByteBuffer buffer)
+ {
+ if ( _encodedForm != null )
+ {
+ lock ( _syncLock )
+ {
+ buffer.Put(_encodedForm);
+ _encodedForm.Flip();
+ }
+ } else if ( _properties != null )
+ {
+ foreach ( DictionaryEntry de in _properties )
+ {
+ string key = (string)de.Key;
+ AMQTypedValue value = (AMQTypedValue)de.Value;
+ try
+ {
+ if ( _log.IsDebugEnabled )
+ {
+ _log.Debug("Writing Property:" + key +
+ " Type:" + value.Type +
+ " Value:" + value.Value);
+ _log.Debug("Buffer Position:" + buffer.Position +
+ " Remaining:" + buffer.Remaining);
+ }
+ //Write the actual parameter name
+ EncodingUtils.WriteShortStringBytes(buffer, key);
+ value.WriteToBuffer(buffer);
+ } catch ( Exception ex )
+ {
+ if ( _log.IsDebugEnabled )
+ {
+ _log.Debug("Exception thrown:" + ex);
+ _log.Debug("Writing Property:" + key +
+ " Type:" + value.Type +
+ " Value:" + value.Value);
+ _log.Debug("Buffer Position:" + buffer.Position +
+ " Remaining:" + buffer.Remaining);
+ }
+ throw;
+ }
+ }
+ }
+ }
+ #endregion // Private Methods
+ }
+}
diff --git a/qpid/dotnet/Qpid.Common/Framing/HeartbeatBody.cs b/qpid/dotnet/Qpid.Common/Framing/HeartbeatBody.cs
new file mode 100644
index 0000000000..a8906f5ba8
--- /dev/null
+++ b/qpid/dotnet/Qpid.Common/Framing/HeartbeatBody.cs
@@ -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.
+ *
+ */
+using Apache.Qpid.Buffer;
+
+namespace Apache.Qpid.Framing
+{
+ public class HeartbeatBody : IBody
+{
+ public const byte TYPE = 8;
+ public static AMQFrame FRAME = new HeartbeatBody().ToFrame();
+
+ public byte BodyType
+ {
+ get
+ {
+ return TYPE;
+ }
+ }
+
+ public uint Size
+ {
+ get
+ {
+ return 0;//heartbeats we generate have no payload
+ }
+ }
+
+ public void WritePayload(ByteBuffer buffer)
+ {
+ }
+
+ public void PopulateFromBuffer(ByteBuffer buffer, uint size)
+ {
+ if (size > 0)
+ {
+ //allow other implementations to have a payload, but ignore it:
+ buffer.Skip((int) size);
+ }
+ }
+
+ public AMQFrame ToFrame()
+ {
+ return new AMQFrame(0, this);
+ }
+}
+}
diff --git a/qpid/dotnet/Qpid.Common/Framing/HeartbeatBodyFactory.cs b/qpid/dotnet/Qpid.Common/Framing/HeartbeatBodyFactory.cs
new file mode 100644
index 0000000000..90e5c7768e
--- /dev/null
+++ b/qpid/dotnet/Qpid.Common/Framing/HeartbeatBodyFactory.cs
@@ -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.
+ *
+ */
+using Apache.Qpid.Buffer;
+
+namespace Apache.Qpid.Framing
+{
+ public class HeartbeatBodyFactory : IBodyFactory
+ {
+ public IBody CreateBody(ByteBuffer input)
+ {
+ return new HeartbeatBody();
+ }
+ }
+}
diff --git a/qpid/dotnet/Qpid.Common/Framing/IBody.cs b/qpid/dotnet/Qpid.Common/Framing/IBody.cs
new file mode 100644
index 0000000000..97b4459e5c
--- /dev/null
+++ b/qpid/dotnet/Qpid.Common/Framing/IBody.cs
@@ -0,0 +1,63 @@
+/*
+ *
+ * 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.
+ *
+ */
+using Apache.Qpid.Buffer;
+
+namespace Apache.Qpid.Framing
+{
+ /// <summary>
+ /// An IBody is contained within a top level frame. As such, it is not en/decodable on its own but
+ /// is decoded as a step within a the overall en/decoding process.
+ /// </summary>
+ public interface IBody
+ {
+ /// <summary>
+ /// Gets the type. See RFC 006 for the meaning of "type" in this context.
+ /// </summary>
+ /// <value>The type.</value>
+ byte BodyType
+ {
+ get;
+ }
+
+ /// <summary>
+ /// Get the size of the body
+ /// </summary>
+ /// <value>The size in bytes.</value>
+ uint Size
+ {
+ get;
+ }
+
+ /// <summary>
+ /// Writes this instance to a buffer.
+ /// </summary>
+ /// <param name="buffer">The buffer.</param>
+ void WritePayload(ByteBuffer buffer);
+
+ /// <summary>
+ /// Populates this instance from a buffer of data.
+ /// </summary>
+ /// <param name="buffer">The buffer.</param>
+ /// <param name="size">The size.</param>
+ /// <exception cref="AMQFrameDecodingException">If the buffer contains data that cannot be decoded</exception>
+ void PopulateFromBuffer(ByteBuffer buffer, uint size);
+ }
+}
diff --git a/qpid/dotnet/Qpid.Common/Framing/IBodyFactory.cs b/qpid/dotnet/Qpid.Common/Framing/IBodyFactory.cs
new file mode 100644
index 0000000000..dd7960ddbe
--- /dev/null
+++ b/qpid/dotnet/Qpid.Common/Framing/IBodyFactory.cs
@@ -0,0 +1,38 @@
+/*
+ *
+ * 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.
+ *
+ */
+using Apache.Qpid.Buffer;
+
+namespace Apache.Qpid.Framing
+{
+ /// <summary>
+ /// Any class that is capable of turning a stream of bytes into an AMQ structure must implement this interface.
+ /// </summary>
+ public interface IBodyFactory
+ {
+ /// <summary>
+ /// Creates the body.
+ /// </summary>
+ /// <param name="inbuf">The ByteBuffer containing data from the network</param>
+ /// <returns></returns>
+ /// <exception>AMQFrameDecodingException</exception>
+ IBody CreateBody(ByteBuffer inbuf);
+ }
+}
diff --git a/qpid/dotnet/Qpid.Common/Framing/IContentHeaderProperties.cs b/qpid/dotnet/Qpid.Common/Framing/IContentHeaderProperties.cs
new file mode 100644
index 0000000000..676d0910d4
--- /dev/null
+++ b/qpid/dotnet/Qpid.Common/Framing/IContentHeaderProperties.cs
@@ -0,0 +1,65 @@
+/*
+ *
+ * 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.
+ *
+ */
+using Apache.Qpid.Buffer;
+
+namespace Apache.Qpid.Framing
+{
+ /// <summary>
+ /// There will be an implementation of this interface for each content type. All content types have associated
+ /// header properties and this provides a way to encode and decode them.
+ /// </summary>
+ public interface IContentHeaderProperties
+ {
+ /// <summary>
+ /// Writes the property list to the buffer, in a suitably encoded form.
+ /// </summary>
+ /// <param name="buffer">The buffer to write to</param>
+ void WritePropertyListPayload(ByteBuffer buffer);
+
+ /// <summary>
+ /// Populates the properties from buffer.
+ /// </summary>
+ /// <param name="buffer">The buffer to read from.</param>
+ /// <param name="propertyFlags">The property flags.</param>
+ /// <exception cref="AMQFrameDecodingException">Thrown when the buffer does not contain valid data</exception>
+ void PopulatePropertiesFromBuffer(ByteBuffer buffer, ushort propertyFlags);
+
+ /// <summary>
+ /// Gets the size of the encoded property list in bytes.
+ /// </summary>
+ /// <value>The size of the property list in bytes</value>
+ uint PropertyListSize
+ {
+ get;
+ }
+
+ /// <summary>
+ /// Gets the property flags. Property flags indicate which properties are set in the list. The
+ /// position and meaning of each flag is defined in the protocol specification for the particular
+ /// content type with which these properties are associated.
+ /// </summary>
+ /// <value>the flags as an unsigned integer</value>
+ ushort PropertyFlags
+ {
+ get;
+ }
+ }
+}
diff --git a/qpid/dotnet/Qpid.Common/Framing/IDataBlock.cs b/qpid/dotnet/Qpid.Common/Framing/IDataBlock.cs
new file mode 100644
index 0000000000..c61ed90d10
--- /dev/null
+++ b/qpid/dotnet/Qpid.Common/Framing/IDataBlock.cs
@@ -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.
+ *
+ */
+using Apache.Qpid.Buffer;
+
+namespace Apache.Qpid.Framing
+{
+ /// <summary>
+ /// A data block represents something that has a size in bytes and the ability to write itself to a byte
+ /// buffer (similar to a byte array). It represents "top level" frames in the protocol specification.
+ /// </summary>
+ public interface IDataBlock : IEncodableAMQDataBlock
+ {
+ /// <summary>
+ /// Get the size of buffer needed to store the byte representation of this
+ /// frame.
+ /// </summary>
+ /// <returns>size in bytes</returns>
+ uint Size
+ {
+ get;
+ }
+
+ /// <summary>
+ /// Writes the datablock to the specified buffer.
+ /// </summary>
+ /// <param name="buffer">The buffer to write to. Must be the correct size.</param>
+ void WritePayload(ByteBuffer buffer);
+ }
+}
diff --git a/qpid/dotnet/Qpid.Common/Framing/IEncodableAMQDataBlock.cs b/qpid/dotnet/Qpid.Common/Framing/IEncodableAMQDataBlock.cs
new file mode 100644
index 0000000000..da8bf9fef9
--- /dev/null
+++ b/qpid/dotnet/Qpid.Common/Framing/IEncodableAMQDataBlock.cs
@@ -0,0 +1,31 @@
+/*
+ *
+ * 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.
+ *
+ */
+namespace Apache.Qpid.Framing
+{
+
+ /// <summary>
+ /// Marker interface to indicate to MINA that a data block should be encoded with the
+ /// single encoder/decoder that we have defined.
+ /// </summary>
+ public interface IEncodableAMQDataBlock
+ {
+ }
+}
diff --git a/qpid/dotnet/Qpid.Common/Framing/ProtocolInitiation.cs b/qpid/dotnet/Qpid.Common/Framing/ProtocolInitiation.cs
new file mode 100644
index 0000000000..5407bc08d5
--- /dev/null
+++ b/qpid/dotnet/Qpid.Common/Framing/ProtocolInitiation.cs
@@ -0,0 +1,158 @@
+/*
+ *
+ * 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.
+ *
+ */
+using System;
+using System.Collections;
+using System.Configuration;
+using System.Reflection;
+using System.Xml;
+using log4net;
+using Apache.Qpid.Buffer;
+using Apache.Qpid.Codec;
+using Apache.Qpid.Codec.Demux;
+using Apache.Qpid.Common;
+
+namespace Apache.Qpid.Framing
+{
+ public class ProtocolInitiation : IDataBlock, IEncodableAMQDataBlock
+ {
+ private static readonly ILog _log = LogManager.GetLogger(typeof(ProtocolInitiation));
+
+ public char[] Header = new char[]{'A','M','Q','P'};
+
+ private const byte CURRENT_PROTOCOL_CLASS = 1;
+ private const int CURRENT_PROTOCOL_INSTANCE = 1;
+ // FIXME: Needs to be tweakable from GRM.dll.config file. i.e. Major version 7 or 8 +
+ // FIXME: a configuration item for avoiding Basic.Qos (for OpenAMQ compatibility)
+ public static int CURRENT_PROTOCOL_VERSION_MAJOR = 8; // FIXME: put back to 7 for OpenAMQ!
+ private const int CURRENT_PROTOCOL_VERSION_MINOR = 0;
+
+ public byte ProtocolClass = CURRENT_PROTOCOL_CLASS;
+ public byte ProtocolInstance = CURRENT_PROTOCOL_INSTANCE;
+ public byte ProtocolMajor = (byte)CURRENT_PROTOCOL_VERSION_MAJOR;
+ public byte ProtocolMinor = CURRENT_PROTOCOL_VERSION_MINOR;
+
+ static ProtocolInitiation()
+ {
+ AssemblySettings settings = new AssemblySettings();
+
+ /*
+ string openAMQ = settings["OpenAMQ1d4Compatibility"];
+ if (openAMQ.Equals("true"))
+ {
+ _log.Warn("Starting in OpenAMQ-1.0d4 compatibility mode. ProtocolMajorVersion is 7 and Basic.Qos will not be sent.");
+ CURRENT_PROTOCOL_VERSION_MAJOR = 7;
+ }
+ */
+ }
+
+ public uint Size
+ {
+ get
+ {
+ return 4 + 1 + 1 + 1 + 1;
+ }
+ }
+
+ public void WritePayload(ByteBuffer buffer)
+ {
+ foreach (char c in Header)
+ {
+ buffer.Put((byte) c);
+ }
+ buffer.Put(ProtocolClass);
+ buffer.Put(ProtocolInstance);
+ buffer.Put(ProtocolMajor);
+ buffer.Put(ProtocolMinor);
+ }
+
+ /// <summary>
+ /// Populates from buffer.
+ /// </summary>
+ /// <param name="buffer">The buffer.</param>
+ public void PopulateFromBuffer(ByteBuffer buffer)
+ {
+ throw new AMQException("Method not implemented");
+ }
+
+ public class Decoder : IMessageDecoder
+ {
+ private bool _disabled = false;
+
+ public MessageDecoderResult Decodable(ByteBuffer inbuf)
+ {
+ if (_disabled)
+ {
+ return MessageDecoderResult.NOT_OK;
+ }
+ if (inbuf.Remaining < 8)
+ {
+ return MessageDecoderResult.NEED_DATA;
+ }
+ else
+ {
+ char[] expected = new char[]{'A', 'M', 'Q', 'P'};
+ for (int i = 0; i < 4; i++)
+ {
+ if (((char) inbuf.GetByte()) != expected[i])
+ {
+ return MessageDecoderResult.NOT_OK;
+ }
+ }
+ return MessageDecoderResult.OK;
+ }
+ }
+
+ /// <summary>
+ /// Decodes the specified session.
+ /// </summary>
+ /// <param name="inbuf">The inbuf.</param>
+ /// <param name="output">The protocol output.</param>
+ /// <returns></returns>
+ public MessageDecoderResult Decode(ByteBuffer inbuf, IProtocolDecoderOutput output)
+ {
+ byte[] header = new byte[4];
+ inbuf.GetBytes(header);
+ ProtocolInitiation pi = new ProtocolInitiation();
+ pi.Header = new char[]{'A','M','Q','P'};
+ pi.ProtocolClass = inbuf.GetByte();
+ pi.ProtocolInstance = inbuf.GetByte();
+ pi.ProtocolMajor = inbuf.GetByte();
+ pi.ProtocolMinor = inbuf.GetByte();
+ output.Write(pi);
+ return MessageDecoderResult.OK;
+ }
+
+ public bool Disabled
+ {
+ set
+ {
+ _disabled = value;
+ }
+ }
+ }
+
+ public override string ToString()
+ {
+ return String.Format("{0}{{Class={1} Instance={2} Major={3} Minor={4}}}",
+ GetType().Name, ProtocolClass, ProtocolInstance, ProtocolMajor, ProtocolMinor);
+ }
+ }
+}
diff --git a/qpid/dotnet/Qpid.Common/Properties/AssemblyInfo.cs b/qpid/dotnet/Qpid.Common/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000000..3847429519
--- /dev/null
+++ b/qpid/dotnet/Qpid.Common/Properties/AssemblyInfo.cs
@@ -0,0 +1,52 @@
+/*
+ *
+ * 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.
+ *
+ */
+using System.Reflection;
+using System.Runtime.InteropServices;
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("Apache.Qpid.Common")]
+[assembly: AssemblyDescription("Built from svn revision number: ")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Apache Software Foundation")]
+[assembly: AssemblyProduct("Apache.Qpid.Common")]
+[assembly: AssemblyCopyright("Apache Software Foundation")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("8dea7c69-1383-4bf7-99e9-e172eba639a2")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Revision and Build Numbers
+// by using the '*' as shown below:
+[assembly: AssemblyVersion("0.5.0.0")]
diff --git a/qpid/dotnet/Qpid.Common/Protocol/AMQConstant.cs b/qpid/dotnet/Qpid.Common/Protocol/AMQConstant.cs
new file mode 100644
index 0000000000..9400b1bd80
--- /dev/null
+++ b/qpid/dotnet/Qpid.Common/Protocol/AMQConstant.cs
@@ -0,0 +1,100 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+using System;
+using System.Collections;
+
+namespace Apache.Qpid.Protocol
+{
+ public sealed class AMQConstant
+ {
+ private int _code;
+ private string _name;
+ private static Hashtable _codeMap = new Hashtable();
+
+ public int Code
+ {
+ get { return _code; }
+ }
+
+ public string Name
+ {
+ get { return _name; }
+ }
+
+ private AMQConstant(int code, string name, bool map)
+ {
+ _code = code;
+ _name = name;
+
+ if ( map )
+ {
+ _codeMap.Add(code, this);
+ }
+ }
+
+ public override string ToString()
+ {
+ return string.Format("{0}: {1}", Code, Name);
+ }
+
+ public static AMQConstant GetConstant(int code)
+ {
+ AMQConstant c = (AMQConstant)_codeMap[code];
+ if ( c == null )
+ {
+ c = new AMQConstant(code, "unknown code", false);
+ }
+ return c;
+ }
+
+ #region Constants
+ //
+ // Constants
+ //
+ public static readonly AMQConstant FRAME_MIN_SIZE = new AMQConstant(4096, "frame min size", true);
+ public static readonly AMQConstant FRAME_END = new AMQConstant(206, "frame end", true);
+ public static readonly AMQConstant REPLY_SUCCESS = new AMQConstant(200, "reply success", true);
+ public static readonly AMQConstant NOT_DELIVERED = new AMQConstant(310, "not delivered", true);
+ public static readonly AMQConstant MESSAGE_TOO_LARGE = new AMQConstant(311, "message too large", true);
+ public static readonly AMQConstant NO_ROUTE = new AMQConstant(312, "no route", true);
+ public static readonly AMQConstant NO_CONSUMERS = new AMQConstant(313, "no consumers", true);
+ public static readonly AMQConstant CONTEXT_IN_USE = new AMQConstant(320, "context in use", true);
+ public static readonly AMQConstant INVALID_PATH = new AMQConstant(402, "invalid path", true);
+ public static readonly AMQConstant ACCESS_REFUSED = new AMQConstant(403, "access refused", true);
+ public static readonly AMQConstant NOT_FOUND = new AMQConstant(404, "not found", true);
+ public static readonly AMQConstant ALREADY_EXISTS = new AMQConstant(405, "already exists", true);
+ public static readonly AMQConstant IN_USE = new AMQConstant(406, "in use", true);
+ public static readonly AMQConstant INVALID_ROUTING_KEY = new AMQConstant(407, "routing key invalid", true);
+ public static readonly AMQConstant REQUEST_TIMEOUT = new AMQConstant(408, "request timeout", true);
+ public static readonly AMQConstant INVALID_ARGUMENT = new AMQConstant(409, "argument invalid", true);
+ public static readonly AMQConstant FRAME_ERROR = new AMQConstant(501, "frame error", true);
+ public static readonly AMQConstant SYNTAX_ERROR = new AMQConstant(502, "syntax error", true);
+ public static readonly AMQConstant COMMAND_INVALID = new AMQConstant(503, "command invalid", true);
+ public static readonly AMQConstant CHANNEL_ERROR = new AMQConstant(504, "channel error", true);
+ public static readonly AMQConstant RESOURCE_ERROR = new AMQConstant(506, "resource error", true);
+ public static readonly AMQConstant NOT_ALLOWED = new AMQConstant(530, "not allowed", true);
+ public static readonly AMQConstant NOT_IMPLEMENTED = new AMQConstant(540, "not implemented", true);
+ public static readonly AMQConstant INTERNAL_ERROR = new AMQConstant(541, "internal error", true);
+
+ #endregion // Constants
+
+ }
+}
diff --git a/qpid/dotnet/Qpid.Common/Qpid.Common.csproj b/qpid/dotnet/Qpid.Common/Qpid.Common.csproj
new file mode 100644
index 0000000000..09f0a96ba9
--- /dev/null
+++ b/qpid/dotnet/Qpid.Common/Qpid.Common.csproj
@@ -0,0 +1,104 @@
+<!--
+
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+
+-->
+
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProductVersion>8.0.50727</ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{77064C42-24D2-4CEB-9EA2-0EF481A43205}</ProjectGuid>
+ <OutputType>Library</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>Apache.Qpid</RootNamespace>
+ <AssemblyName>Apache.Qpid.Common</AssemblyName>
+ <SignAssembly>false</SignAssembly>
+ <AssemblyOriginatorKeyFile>
+ </AssemblyOriginatorKeyFile>
+ <FileUpgradeFlags>
+ </FileUpgradeFlags>
+ <OldToolsVersion>2.0</OldToolsVersion>
+ <UpgradeBackupLocation>
+ </UpgradeBackupLocation>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>..\bin\net-2.0\debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>..\bin\net-2.0\release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="log4net, Version=1.2.9.0, Culture=neutral, PublicKeyToken=b32731d11ce58905">
+ <SpecificVersion>False</SpecificVersion>
+ <HintPath>lib\log4net\log4net.dll</HintPath>
+ </Reference>
+ <Reference Include="System" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="**\*.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\Qpid.Buffer\Qpid.Buffer.csproj">
+ <Project>{44384DF2-B0A4-4580-BDBC-EE4BAA87D995}</Project>
+ <Name>Qpid.Buffer</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\Qpid.Codec\Qpid.Codec.csproj">
+ <Project>{22D0D0C2-77AF-4DE3-B456-7FF3893F9F88}</Project>
+ <Name>Qpid.Codec</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\Qpid.Messaging\Qpid.Messaging.csproj">
+ <Project>{6688F826-C58E-4C1B-AA1F-22AFAB4B7D07}</Project>
+ <Name>Qpid.Messaging</Name>
+ </ProjectReference>
+ </ItemGroup>
+ <ItemGroup>
+ <Content Include="stylesheets\csharp.xsl" />
+ <Content Include="stylesheets\framing.xsl" />
+ <Content Include="stylesheets\java.xsl" />
+ <Content Include="stylesheets\prepare1.xsl" />
+ <Content Include="stylesheets\prepare2.xsl" />
+ <Content Include="stylesheets\prepare3.xsl" />
+ <Content Include="stylesheets\readme.txt" />
+ <Content Include="stylesheets\registry.xsl" />
+ <Content Include="stylesheets\utils.xsl" />
+ </ItemGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+ <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
+ Other similar extension points exist, see Microsoft.Common.targets.
+ <Target Name="BeforeBuild">
+ </Target>
+ <Target Name="AfterBuild">
+ </Target>
+ -->
+</Project>
diff --git a/qpid/dotnet/Qpid.Common/amqp.xml b/qpid/dotnet/Qpid.Common/amqp.xml
new file mode 100644
index 0000000000..ddd4b5be4b
--- /dev/null
+++ b/qpid/dotnet/Qpid.Common/amqp.xml
@@ -0,0 +1,3929 @@
+<?xml version="1.0"?>
+<!--
+
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+
+-->
+
+
+<!--
+Copyright Notice
+================
+© Copyright JPMorgan Chase Bank & Co., Cisco Systems, Inc., Envoy Technologies Inc.,
+iMatix Corporation, IONA� Technologies, Red Hat, Inc.,
+TWIST Process Innovations, and 29West Inc. 2006. All rights reserved.
+
+License
+=======
+JPMorgan Chase Bank & Co., Cisco Systems, Inc., Envoy Technologies Inc., iMatix
+Corporation, IONA� Technologies, Red Hat, Inc., TWIST Process Innovations, and
+29West Inc. (collectively, the "Authors") each hereby grants to you a worldwide,
+perpetual, royalty-free, nontransferable, nonexclusive license to
+(i) copy, display, and implement the Advanced Messaging Queue Protocol
+("AMQP") Specification and (ii) the Licensed Claims that are held by
+the Authors, all for the purpose of implementing the Advanced Messaging
+Queue Protocol Specification. Your license and any rights under this
+Agreement will terminate immediately without notice from
+any Author if you bring any claim, suit, demand, or action related to
+the Advanced Messaging Queue Protocol Specification against any Author.
+Upon termination, you shall destroy all copies of the Advanced Messaging
+Queue Protocol Specification in your possession or control.
+
+As used hereunder, "Licensed Claims" means those claims of a patent or
+patent application, throughout the world, excluding design patents and
+design registrations, owned or controlled, or that can be sublicensed
+without fee and in compliance with the requirements of this
+Agreement, by an Author or its affiliates now or at any
+future time and which would necessarily be infringed by implementation
+of the Advanced Messaging Queue Protocol Specification. A claim is
+necessarily infringed hereunder only when it is not possible to avoid
+infringing it because there is no plausible non-infringing alternative
+for implementing the required portions of the Advanced Messaging Queue
+Protocol Specification. Notwithstanding the foregoing, Licensed Claims
+shall not include any claims other than as set forth above even if
+contained in the same patent as Licensed Claims; or that read solely
+on any implementations of any portion of the Advanced Messaging Queue
+Protocol Specification that are not required by the Advanced Messaging
+Queue Protocol Specification, or that, if licensed, would require a
+payment of royalties by the licensor to unaffiliated third parties.
+Moreover, Licensed Claims shall not include (i) any enabling technologies
+that may be necessary to make or use any Licensed Product but are not
+themselves expressly set forth in the Advanced Messaging Queue Protocol
+Specification (e.g., semiconductor manufacturing technology, compiler
+technology, object oriented technology, networking technology, operating
+system technology, and the like); or (ii) the implementation of other
+published standards developed elsewhere and merely referred to in the
+body of the Advanced Messaging Queue Protocol Specification, or
+(iii) any Licensed Product and any combinations thereof the purpose or
+function of which is not required for compliance with the Advanced
+Messaging Queue Protocol Specification. For purposes of this definition,
+the Advanced Messaging Queue Protocol Specification shall be deemed to
+include both architectural and interconnection requirements essential
+for interoperability and may also include supporting source code artifacts
+where such architectural, interconnection requirements and source code
+artifacts are expressly identified as being required or documentation to
+achieve compliance with the Advanced Messaging Queue Protocol Specification.
+
+As used hereunder, "Licensed Products" means only those specific portions
+of products (hardware, software or combinations thereof) that implement
+and are compliant with all relevant portions of the Advanced Messaging
+Queue Protocol Specification.
+
+The following disclaimers, which you hereby also acknowledge as to any
+use you may make of the Advanced Messaging Queue Protocol Specification:
+
+THE ADVANCED MESSAGING QUEUE PROTOCOL SPECIFICATION IS PROVIDED "AS IS,"
+AND THE AUTHORS MAKE NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR
+IMPLIED, INCLUDING, BUT NOT LIMITED TO, WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, OR TITLE; THAT THE
+CONTENTS OF THE ADVANCED MESSAGING QUEUE PROTOCOL SPECIFICATION ARE
+SUITABLE FOR ANY PURPOSE; NOR THAT THE IMPLEMENTATION OF THE ADVANCED
+MESSAGING QUEUE PROTOCOL SPECIFICATION WILL NOT INFRINGE ANY THIRD PARTY
+PATENTS, COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS.
+
+THE AUTHORS WILL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL,
+INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF OR RELATING TO ANY
+USE, IMPLEMENTATION OR DISTRIBUTION OF THE ADVANCED MESSAGING QUEUE
+PROTOCOL SPECIFICATION.
+
+The name and trademarks of the Authors may NOT be used in any manner,
+including advertising or publicity pertaining to the Advanced Messaging
+Queue Protocol Specification or its contents without specific, written
+prior permission. Title to copyright in the Advanced Messaging Queue
+Protocol Specification will at all times remain with the Authors.
+
+No other rights are granted by implication, estoppel or otherwise.
+
+Upon termination of your license or rights under this Agreement, you
+shall destroy all copies of the Advanced Messaging Queue Protocol
+Specification in your possession or control.
+
+Trademarks
+==========
+"JPMorgan", "JPMorgan Chase", "Chase", the JPMorgan Chase logo and the
+Octagon Symbol are trademarks of JPMorgan Chase & Co.
+
+IMATIX and the iMatix logo are trademarks of iMatix Corporation sprl.
+
+IONA, IONA Technologies, and the IONA logos are trademarks of IONA
+Technologies PLC and/or its subsidiaries.
+
+LINUX is a trademark of Linus Torvalds. RED HAT and JBOSS are registered
+trademarks of Red Hat, Inc. in the US and other countries.
+
+Java, all Java-based trademarks and OpenOffice.org are trademarks of
+Sun Microsystems, Inc. in the United States, other countries, or both.
+
+Other company, product, or service names may be trademarks or service
+marks of others.
+
+Links to full AMQP specification:
+=================================
+http://www.envoytech.org/spec/amq/
+http://www.iona.com/opensource/amqp/
+http://www.redhat.com/solutions/specifications/amqp/
+http://www.twiststandards.org/tiki-index.php?page=AMQ
+http://www.imatix.com/amqp
+
+-->
+
+<amqp major="8" minor="0" port="5672" comment="AMQ protocol 0.80">
+ AMQ Protocol 0.80
+<!--
+======================================================
+== CONSTANTS
+======================================================
+-->
+ <constant name="frame method" value="1"/>
+ <constant name="frame header" value="2"/>
+ <constant name="frame body" value="3"/>
+ <constant name="frame oob method" value="4"/>
+ <constant name="frame oob header" value="5"/>
+ <constant name="frame oob body" value="6"/>
+ <constant name="frame trace" value="7"/>
+ <constant name="frame heartbeat" value="8"/>
+ <constant name="frame min size" value="4096"/>
+ <constant name="frame end" value="206"/>
+ <constant name="reply success" value="200">
+ Indicates that the method completed successfully. This reply code is
+ reserved for future use - the current protocol design does not use
+ positive confirmation and reply codes are sent only in case of an
+ error.
+</constant>
+ <constant name="not delivered" value="310" class="soft error">
+ The client asked for a specific message that is no longer available.
+ The message was delivered to another client, or was purged from the
+ queue for some other reason.
+</constant>
+ <constant name="content too large" value="311" class="soft error">
+ The client attempted to transfer content larger than the server
+ could accept at the present time. The client may retry at a later
+ time.
+</constant>
+ <constant name="connection forced" value="320" class="hard error">
+ An operator intervened to close the connection for some reason.
+ The client may retry at some later date.
+</constant>
+ <constant name="invalid path" value="402" class="hard error">
+ The client tried to work with an unknown virtual host or cluster.
+</constant>
+ <constant name="access refused" value="403" class="soft error">
+ The client attempted to work with a server entity to which it has
+ no due to security settings.
+</constant>
+ <constant name="not found" value="404" class="soft error">
+ The client attempted to work with a server entity that does not exist.
+</constant>
+ <constant name="resource locked" value="405" class="soft error">
+ The client attempted to work with a server entity to which it has
+ no access because another client is working with it.
+</constant>
+ <constant name="frame error" value="501" class="hard error">
+ The client sent a malformed frame that the server could not decode.
+ This strongly implies a programming error in the client.
+</constant>
+ <constant name="syntax error" value="502" class="hard error">
+ The client sent a frame that contained illegal values for one or more
+ fields. This strongly implies a programming error in the client.
+</constant>
+ <constant name="command invalid" value="503" class="hard error">
+ The client sent an invalid sequence of frames, attempting to perform
+ an operation that was considered invalid by the server. This usually
+ implies a programming error in the client.
+</constant>
+ <constant name="channel error" value="504" class="hard error">
+ The client attempted to work with a channel that had not been
+ correctly opened. This most likely indicates a fault in the client
+ layer.
+</constant>
+ <constant name="resource error" value="506" class="hard error">
+ The server could not complete the method because it lacked sufficient
+ resources. This may be due to the client creating too many of some
+ type of entity.
+</constant>
+ <constant name="not allowed" value="530" class="hard error">
+ The client tried to work with some entity in a manner that is
+ prohibited by the server, due to security settings or by some other
+ criteria.
+</constant>
+ <constant name="not implemented" value="540" class="hard error">
+ The client tried to use functionality that is not implemented in the
+ server.
+</constant>
+ <constant name="internal error" value="541" class="hard error">
+ The server could not complete the method because of an internal error.
+ The server may require intervention by an operator in order to resume
+ normal operations.
+</constant>
+ <!--
+======================================================
+== DOMAIN TYPES
+======================================================
+-->
+ <domain name="access ticket" type="short">
+ access ticket granted by server
+ <doc>
+ An access ticket granted by the server for a certain set of access
+ rights within a specific realm. Access tickets are valid within the
+ channel where they were created, and expire when the channel closes.
+ </doc>
+ <assert check="ne" value="0"/>
+ </domain>
+ <domain name="class id" type="short"/>
+ <domain name="consumer tag" type="shortstr">
+ consumer tag
+ <doc>
+ Identifier for the consumer, valid within the current connection.
+ </doc>
+ <rule implement="MUST">
+ The consumer tag is valid only within the channel from which the
+ consumer was created. I.e. a client MUST NOT create a consumer in
+ one channel and then use it in another.
+ </rule>
+ </domain>
+ <domain name="delivery tag" type="longlong">
+ server-assigned delivery tag
+ <doc>
+ The server-assigned and channel-specific delivery tag
+ </doc>
+ <rule implement="MUST">
+ The delivery tag is valid only within the channel from which the
+ message was received. I.e. a client MUST NOT receive a message on
+ one channel and then acknowledge it on another.
+ </rule>
+ <rule implement="MUST">
+ The server MUST NOT use a zero value for delivery tags. Zero is
+ reserved for client use, meaning "all messages so far received".
+ </rule>
+ </domain>
+ <domain name="exchange name" type="shortstr">
+ exchange name
+ <doc>
+ The exchange name is a client-selected string that identifies
+ the exchange for publish methods. Exchange names may consist
+ of any mixture of digits, letters, and underscores. Exchange
+ names are scoped by the virtual host.
+ </doc>
+ <assert check="length" value="127"/>
+ </domain>
+ <domain name="known hosts" type="shortstr">
+list of known hosts
+<doc>
+Specifies the list of equivalent or alternative hosts that the server
+knows about, which will normally include the current server itself.
+Clients can cache this information and use it when reconnecting to a
+server after a failure.
+</doc>
+ <rule implement="MAY">
+The server MAY leave this field empty if it knows of no other
+hosts than itself.
+</rule>
+ </domain>
+ <domain name="method id" type="short"/>
+ <domain name="no ack" type="bit">
+ no acknowledgement needed
+ <doc>
+ If this field is set the server does not expect acknowledgments
+ for messages. That is, when a message is delivered to the client
+ the server automatically and silently acknowledges it on behalf
+ of the client. This functionality increases performance but at
+ the cost of reliability. Messages can get lost if a client dies
+ before it can deliver them to the application.
+ </doc>
+ </domain>
+ <domain name="no local" type="bit">
+ do not deliver own messages
+ <doc>
+ If the no-local field is set the server will not send messages to
+ the client that published them.
+ </doc>
+ </domain>
+ <domain name="path" type="shortstr">
+ <doc>
+ Must start with a slash "/" and continue with path names
+ separated by slashes. A path name consists of any combination
+ of at least one of [A-Za-z0-9] plus zero or more of [.-_+!=:].
+</doc>
+ <assert check="notnull"/>
+ <assert check="syntax" rule="path"/>
+ <assert check="length" value="127"/>
+ </domain>
+ <domain name="peer properties" type="table">
+ <doc>
+This string provides a set of peer properties, used for
+identification, debugging, and general information.
+</doc>
+ <rule implement="SHOULD">
+The properties SHOULD contain these fields:
+"product", giving the name of the peer product, "version", giving
+the name of the peer version, "platform", giving the name of the
+operating system, "copyright", if appropriate, and "information",
+giving other general information.
+</rule>
+ </domain>
+ <domain name="queue name" type="shortstr">
+ queue name
+ <doc>
+ The queue name identifies the queue within the vhost. Queue
+ names may consist of any mixture of digits, letters, and
+ underscores.
+ </doc>
+ <assert check="length" value="127"/>
+ </domain>
+ <domain name="redelivered" type="bit">
+ message is being redelivered
+ <doc>
+ This indicates that the message has been previously delivered to
+ this or another client.
+ </doc>
+ <rule implement="SHOULD">
+ The server SHOULD try to signal redelivered messages when it can.
+ When redelivering a message that was not successfully acknowledged,
+ the server SHOULD deliver it to the original client if possible.
+ </rule>
+ <rule implement="MUST">
+ The client MUST NOT rely on the redelivered field but MUST take it
+ as a hint that the message may already have been processed. A
+ fully robust client must be able to track duplicate received messages
+ on non-transacted, and locally-transacted channels.
+ </rule>
+ </domain>
+ <domain name="reply code" type="short">
+reply code from server
+<doc>
+ The reply code. The AMQ reply codes are defined in AMQ RFC 011.
+</doc>
+ <assert check="notnull"/>
+ </domain>
+ <domain name="reply text" type="shortstr">
+localised reply text
+<doc>
+ The localised reply text. This text can be logged as an aid to
+ resolving issues.
+</doc>
+ <assert check="notnull"/>
+ </domain>
+ <class name="connection" handler="connection" index="10">
+ <!--
+======================================================
+== CONNECTION
+======================================================
+-->
+ work with socket connections
+<doc>
+ The connection class provides methods for a client to establish a
+ network connection to a server, and for both peers to operate the
+ connection thereafter.
+</doc>
+ <doc name="grammar">
+ connection = open-connection *use-connection close-connection
+ open-connection = C:protocol-header
+ S:START C:START-OK
+ *challenge
+ S:TUNE C:TUNE-OK
+ C:OPEN S:OPEN-OK | S:REDIRECT
+ challenge = S:SECURE C:SECURE-OK
+ use-connection = *channel
+ close-connection = C:CLOSE S:CLOSE-OK
+ / S:CLOSE C:CLOSE-OK
+</doc>
+ <chassis name="server" implement="MUST"/>
+ <chassis name="client" implement="MUST"/>
+ <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+ <method name="start" synchronous="1" index="10">
+ start connection negotiation
+ <doc>
+ This method starts the connection negotiation process by telling
+ the client the protocol version that the server proposes, along
+ with a list of security mechanisms which the client can use for
+ authentication.
+ </doc>
+ <rule implement="MUST">
+ If the client cannot handle the protocol version suggested by the
+ server it MUST close the socket connection.
+ </rule>
+ <rule implement="MUST">
+ The server MUST provide a protocol version that is lower than or
+ equal to that requested by the client in the protocol header. If
+ the server cannot support the specified protocol it MUST NOT send
+ this method, but MUST close the socket connection.
+ </rule>
+ <chassis name="client" implement="MUST"/>
+ <response name="start-ok"/>
+ <field name="version major" type="octet">
+ protocol major version
+ <doc>
+ The protocol major version that the server agrees to use, which
+ cannot be higher than the client's major version.
+ </doc>
+ </field>
+ <field name="version minor" type="octet">
+ protocol major version
+ <doc>
+ The protocol minor version that the server agrees to use, which
+ cannot be higher than the client's minor version.
+ </doc>
+ </field>
+ <field name="server properties" domain="peer properties">
+ server properties
+ </field>
+ <field name="mechanisms" type="longstr">
+ available security mechanisms
+ <doc>
+ A list of the security mechanisms that the server supports, delimited
+ by spaces. Currently ASL supports these mechanisms: PLAIN.
+ </doc>
+ <see name="security mechanisms"/>
+ <assert check="notnull"/>
+ </field>
+ <field name="locales" type="longstr">
+ available message locales
+ <doc>
+ A list of the message locales that the server supports, delimited
+ by spaces. The locale defines the language in which the server
+ will send reply texts.
+ </doc>
+ <rule implement="MUST">
+ All servers MUST support at least the en_US locale.
+ </rule>
+ <assert check="notnull"/>
+ </field>
+ </method>
+ <method name="start-ok" synchronous="1" index="11">
+ select security mechanism and locale
+ <doc>
+ This method selects a SASL security mechanism. ASL uses SASL
+ (RFC2222) to negotiate authentication and encryption.
+ </doc>
+ <chassis name="server" implement="MUST"/>
+ <field name="client properties" domain="peer properties">
+ client properties
+ </field>
+ <field name="mechanism" type="shortstr">
+ selected security mechanism
+ <doc>
+ A single security mechanisms selected by the client, which must be
+ one of those specified by the server.
+ </doc>
+ <rule implement="SHOULD">
+ The client SHOULD authenticate using the highest-level security
+ profile it can handle from the list provided by the server.
+ </rule>
+ <rule implement="MUST">
+ The mechanism field MUST contain one of the security mechanisms
+ proposed by the server in the Start method. If it doesn't, the
+ server MUST close the socket.
+ </rule>
+ <assert check="notnull"/>
+ </field>
+ <field name="response" type="longstr">
+ security response data
+ <doc>
+ A block of opaque data passed to the security mechanism. The contents
+ of this data are defined by the SASL security mechanism. For the
+ PLAIN security mechanism this is defined as a field table holding
+ two fields, LOGIN and PASSWORD.
+ </doc>
+ <assert check="notnull"/>
+ </field>
+ <field name="locale" type="shortstr">
+ selected message locale
+ <doc>
+ A single message local selected by the client, which must be one
+ of those specified by the server.
+ </doc>
+ <assert check="notnull"/>
+ </field>
+ </method>
+ <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+ <method name="secure" synchronous="1" index="20">
+ security mechanism challenge
+ <doc>
+ The SASL protocol works by exchanging challenges and responses until
+ both peers have received sufficient information to authenticate each
+ other. This method challenges the client to provide more information.
+ </doc>
+ <chassis name="client" implement="MUST"/>
+ <response name="secure-ok"/>
+ <field name="challenge" type="longstr">
+ security challenge data
+ <doc>
+ Challenge information, a block of opaque binary data passed to
+ the security mechanism.
+ </doc>
+ <see name="security mechanisms"/>
+ </field>
+ </method>
+ <method name="secure-ok" synchronous="1" index="21">
+ security mechanism response
+ <doc>
+ This method attempts to authenticate, passing a block of SASL data
+ for the security mechanism at the server side.
+ </doc>
+ <chassis name="server" implement="MUST"/>
+ <field name="response" type="longstr">
+ security response data
+ <doc>
+ A block of opaque data passed to the security mechanism. The contents
+ of this data are defined by the SASL security mechanism.
+ </doc>
+ <assert check="notnull"/>
+ </field>
+ </method>
+ <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+ <method name="tune" synchronous="1" index="30">
+ propose connection tuning parameters
+ <doc>
+ This method proposes a set of connection configuration values
+ to the client. The client can accept and/or adjust these.
+ </doc>
+ <chassis name="client" implement="MUST"/>
+ <response name="tune-ok"/>
+ <field name="channel max" type="short">
+ proposed maximum channels
+ <doc>
+ The maximum total number of channels that the server allows
+ per connection. Zero means that the server does not impose a
+ fixed limit, but the number of allowed channels may be limited
+ by available server resources.
+ </doc>
+ </field>
+ <field name="frame max" type="long">
+ proposed maximum frame size
+ <doc>
+ The largest frame size that the server proposes for the
+ connection. The client can negotiate a lower value. Zero means
+ that the server does not impose any specific limit but may reject
+ very large frames if it cannot allocate resources for them.
+ </doc>
+ <rule implement="MUST">
+ Until the frame-max has been negotiated, both peers MUST accept
+ frames of up to 4096 octets large. The minimum non-zero value for
+ the frame-max field is 4096.
+ </rule>
+ </field>
+ <field name="heartbeat" type="short">
+ desired heartbeat delay
+ <doc>
+ The delay, in seconds, of the connection heartbeat that the server
+ wants. Zero means the server does not want a heartbeat.
+ </doc>
+ </field>
+ </method>
+ <method name="tune-ok" synchronous="1" index="31">
+ negotiate connection tuning parameters
+ <doc>
+ This method sends the client's connection tuning parameters to the
+ server. Certain fields are negotiated, others provide capability
+ information.
+ </doc>
+ <chassis name="server" implement="MUST"/>
+ <field name="channel max" type="short">
+ negotiated maximum channels
+ <doc>
+ The maximum total number of channels that the client will use
+ per connection. May not be higher than the value specified by
+ the server.
+ </doc>
+ <rule implement="MAY">
+ The server MAY ignore the channel-max value or MAY use it for
+ tuning its resource allocation.
+ </rule>
+ <assert check="notnull"/>
+ <assert check="le" method="tune" field="channel max"/>
+ </field>
+ <field name="frame max" type="long">
+ negotiated maximum frame size
+ <doc>
+ The largest frame size that the client and server will use for
+ the connection. Zero means that the client does not impose any
+ specific limit but may reject very large frames if it cannot
+ allocate resources for them. Note that the frame-max limit
+ applies principally to content frames, where large contents
+ can be broken into frames of arbitrary size.
+ </doc>
+ <rule implement="MUST">
+ Until the frame-max has been negotiated, both peers must accept
+ frames of up to 4096 octets large. The minimum non-zero value for
+ the frame-max field is 4096.
+ </rule>
+ </field>
+ <field name="heartbeat" type="short">
+ desired heartbeat delay
+ <doc>
+ The delay, in seconds, of the connection heartbeat that the client
+ wants. Zero means the client does not want a heartbeat.
+ </doc>
+ </field>
+ </method>
+ <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+ <method name="open" synchronous="1" index="40">
+ open connection to virtual host
+ <doc>
+ This method opens a connection to a virtual host, which is a
+ collection of resources, and acts to separate multiple application
+ domains within a server.
+ </doc>
+ <rule implement="MUST">
+ The client MUST open the context before doing any work on the
+ connection.
+ </rule>
+ <chassis name="server" implement="MUST"/>
+ <response name="open-ok"/>
+ <response name="redirect"/>
+ <field name="virtual host" domain="path">
+ virtual host name
+ <assert check="regexp" value="^[a-zA-Z0-9/-_]+$"/>
+ <doc>
+ The name of the virtual host to work with.
+ </doc>
+ <rule implement="MUST">
+ If the server supports multiple virtual hosts, it MUST enforce a
+ full separation of exchanges, queues, and all associated entities
+ per virtual host. An application, connected to a specific virtual
+ host, MUST NOT be able to access resources of another virtual host.
+ </rule>
+ <rule implement="SHOULD">
+ The server SHOULD verify that the client has permission to access
+ the specified virtual host.
+ </rule>
+ <rule implement="MAY">
+ The server MAY configure arbitrary limits per virtual host, such
+ as the number of each type of entity that may be used, per
+ connection and/or in total.
+ </rule>
+ </field>
+ <field name="capabilities" type="shortstr">
+ required capabilities
+ <doc>
+ The client may specify a number of capability names, delimited by
+ spaces. The server can use this string to how to process the
+ client's connection request.
+ </doc>
+ </field>
+ <field name="insist" type="bit">
+ insist on connecting to server
+ <doc>
+ In a configuration with multiple load-sharing servers, the server
+ may respond to a Connection.Open method with a Connection.Redirect.
+ The insist option tells the server that the client is insisting on
+ a connection to the specified server.
+ </doc>
+ <rule implement="SHOULD">
+ When the client uses the insist option, the server SHOULD accept
+ the client connection unless it is technically unable to do so.
+ </rule>
+ </field>
+ </method>
+ <method name="open-ok" synchronous="1" index="41">
+ signal that the connection is ready
+ <doc>
+ This method signals to the client that the connection is ready for
+ use.
+ </doc>
+ <chassis name="client" implement="MUST"/>
+ <field name="known hosts" domain="known hosts"/>
+ </method>
+ <method name="redirect" synchronous="1" index="50">
+ asks the client to use a different server
+ <doc>
+ This method redirects the client to another server, based on the
+ requested virtual host and/or capabilities.
+ </doc>
+ <rule implement="SHOULD">
+ When getting the Connection.Redirect method, the client SHOULD
+ reconnect to the host specified, and if that host is not present,
+ to any of the hosts specified in the known-hosts list.
+ </rule>
+ <chassis name="client" implement="MAY"/>
+ <field name="host" type="shortstr">
+ server to connect to
+ <doc>
+ Specifies the server to connect to. This is an IP address or a
+ DNS name, optionally followed by a colon and a port number. If
+ no port number is specified, the client should use the default
+ port number for the protocol.
+ </doc>
+ <assert check="notnull"/>
+ </field>
+ <field name="known hosts" domain="known hosts"/>
+ </method>
+ <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+ <method name="close" synchronous="1" index="60">
+ request a connection close
+ <doc>
+ This method indicates that the sender wants to close the connection.
+ This may be due to internal conditions (e.g. a forced shut-down) or
+ due to an error handling a specific method, i.e. an exception. When
+ a close is due to an exception, the sender provides the class and
+ method id of the method which caused the exception.
+ </doc>
+ <rule implement="MUST">
+ After sending this method any received method except the Close-OK
+ method MUST be discarded.
+ </rule>
+ <rule implement="MAY">
+ The peer sending this method MAY use a counter or timeout to
+ detect failure of the other peer to respond correctly with
+ the Close-OK method.
+ </rule>
+ <rule implement="MUST">
+ When a server receives the Close method from a client it MUST
+ delete all server-side resources associated with the client's
+ context. A client CANNOT reconnect to a context after sending
+ or receiving a Close method.
+ </rule>
+ <chassis name="client" implement="MUST"/>
+ <chassis name="server" implement="MUST"/>
+ <response name="close-ok"/>
+ <field name="reply code" domain="reply code"/>
+ <field name="reply text" domain="reply text"/>
+ <field name="class id" domain="class id">
+ failing method class
+ <doc>
+ When the close is provoked by a method exception, this is the
+ class of the method.
+ </doc>
+ </field>
+ <field name="method id" domain="class id">
+ failing method ID
+ <doc>
+ When the close is provoked by a method exception, this is the
+ ID of the method.
+ </doc>
+ </field>
+ </method>
+ <method name="close-ok" synchronous="1" index="61">
+ confirm a connection close
+ <doc>
+ This method confirms a Connection.Close method and tells the
+ recipient that it is safe to release resources for the connection
+ and close the socket.
+ </doc>
+ <rule implement="SHOULD">
+ A peer that detects a socket closure without having received a
+ Close-Ok handshake method SHOULD log the error.
+ </rule>
+ <chassis name="client" implement="MUST"/>
+ <chassis name="server" implement="MUST"/>
+ </method>
+ </class>
+ <class name="channel" handler="channel" index="20">
+ <!--
+======================================================
+== CHANNEL
+======================================================
+-->
+ work with channels
+<doc>
+ The channel class provides methods for a client to establish a virtual
+ connection - a channel - to a server and for both peers to operate the
+ virtual connection thereafter.
+</doc>
+ <doc name="grammar">
+ channel = open-channel *use-channel close-channel
+ open-channel = C:OPEN S:OPEN-OK
+ use-channel = C:FLOW S:FLOW-OK
+ / S:FLOW C:FLOW-OK
+ / S:ALERT
+ / functional-class
+ close-channel = C:CLOSE S:CLOSE-OK
+ / S:CLOSE C:CLOSE-OK
+</doc>
+ <chassis name="server" implement="MUST"/>
+ <chassis name="client" implement="MUST"/>
+ <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+ <method name="open" synchronous="1" index="10">
+ open a channel for use
+ <doc>
+ This method opens a virtual connection (a channel).
+ </doc>
+ <rule implement="MUST">
+ This method MUST NOT be called when the channel is already open.
+ </rule>
+ <chassis name="server" implement="MUST"/>
+ <response name="open-ok"/>
+ <field name="out of band" type="shortstr">
+ out-of-band settings
+ <doc>
+ Configures out-of-band transfers on this channel. The syntax and
+ meaning of this field will be formally defined at a later date.
+ </doc>
+ <assert check="null"/>
+ </field>
+ </method>
+ <method name="open-ok" synchronous="1" index="11">
+ signal that the channel is ready
+ <doc>
+ This method signals to the client that the channel is ready for use.
+ </doc>
+ <chassis name="client" implement="MUST"/>
+ </method>
+ <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+ <method name="flow" synchronous="1" index="20">
+ enable/disable flow from peer
+ <doc>
+ This method asks the peer to pause or restart the flow of content
+ data. This is a simple flow-control mechanism that a peer can use
+ to avoid oveflowing its queues or otherwise finding itself receiving
+ more messages than it can process. Note that this method is not
+ intended for window control. The peer that receives a request to
+ stop sending content should finish sending the current content, if
+ any, and then wait until it receives a Flow restart method.
+ </doc>
+ <rule implement="MAY">
+ When a new channel is opened, it is active. Some applications
+ assume that channels are inactive until started. To emulate this
+ behaviour a client MAY open the channel, then pause it.
+ </rule>
+ <rule implement="SHOULD">
+ When sending content data in multiple frames, a peer SHOULD monitor
+ the channel for incoming methods and respond to a Channel.Flow as
+ rapidly as possible.
+ </rule>
+ <rule implement="MAY">
+ A peer MAY use the Channel.Flow method to throttle incoming content
+ data for internal reasons, for example, when exchangeing data over a
+ slower connection.
+ </rule>
+ <rule implement="MAY">
+ The peer that requests a Channel.Flow method MAY disconnect and/or
+ ban a peer that does not respect the request.
+ </rule>
+ <chassis name="server" implement="MUST"/>
+ <chassis name="client" implement="MUST"/>
+ <response name="flow-ok"/>
+ <field name="active" type="bit">
+ start/stop content frames
+ <doc>
+ If 1, the peer starts sending content frames. If 0, the peer
+ stops sending content frames.
+ </doc>
+ </field>
+ </method>
+ <method name="flow-ok" index="21">
+ confirm a flow method
+ <doc>
+ Confirms to the peer that a flow command was received and processed.
+ </doc>
+ <chassis name="server" implement="MUST"/>
+ <chassis name="client" implement="MUST"/>
+ <field name="active" type="bit">
+ current flow setting
+ <doc>
+ Confirms the setting of the processed flow method: 1 means the
+ peer will start sending or continue to send content frames; 0
+ means it will not.
+ </doc>
+ </field>
+ </method>
+ <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+ <method name="alert" index="30">
+ send a non-fatal warning message
+ <doc>
+ This method allows the server to send a non-fatal warning to the
+ client. This is used for methods that are normally asynchronous
+ and thus do not have confirmations, and for which the server may
+ detect errors that need to be reported. Fatal errors are handled
+ as channel or connection exceptions; non-fatal errors are sent
+ through this method.
+ </doc>
+ <chassis name="client" implement="MUST"/>
+ <field name="reply code" domain="reply code"/>
+ <field name="reply text" domain="reply text"/>
+ <field name="details" type="table">
+ detailed information for warning
+ <doc>
+ A set of fields that provide more information about the
+ problem. The meaning of these fields are defined on a
+ per-reply-code basis (TO BE DEFINED).
+ </doc>
+ </field>
+ </method>
+ <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+ <method name="close" synchronous="1" index="40">
+ request a channel close
+ <doc>
+ This method indicates that the sender wants to close the channel.
+ This may be due to internal conditions (e.g. a forced shut-down) or
+ due to an error handling a specific method, i.e. an exception. When
+ a close is due to an exception, the sender provides the class and
+ method id of the method which caused the exception.
+ </doc>
+ <rule implement="MUST">
+ After sending this method any received method except
+ Channel.Close-OK MUST be discarded.
+ </rule>
+ <rule implement="MAY">
+ The peer sending this method MAY use a counter or timeout to detect
+ failure of the other peer to respond correctly with Channel.Close-OK..
+ </rule>
+ <chassis name="client" implement="MUST"/>
+ <chassis name="server" implement="MUST"/>
+ <response name="close-ok"/>
+ <field name="reply code" domain="reply code"/>
+ <field name="reply text" domain="reply text"/>
+ <field name="class id" domain="class id">
+ failing method class
+ <doc>
+ When the close is provoked by a method exception, this is the
+ class of the method.
+ </doc>
+ </field>
+ <field name="method id" domain="method id">
+ failing method ID
+ <doc>
+ When the close is provoked by a method exception, this is the
+ ID of the method.
+ </doc>
+ </field>
+ </method>
+ <method name="close-ok" synchronous="1" index="41">
+ confirm a channel close
+ <doc>
+ This method confirms a Channel.Close method and tells the recipient
+ that it is safe to release resources for the channel and close the
+ socket.
+ </doc>
+ <rule implement="SHOULD">
+ A peer that detects a socket closure without having received a
+ Channel.Close-Ok handshake method SHOULD log the error.
+ </rule>
+ <chassis name="client" implement="MUST"/>
+ <chassis name="server" implement="MUST"/>
+ </method>
+ </class>
+ <class name="access" handler="connection" index="30">
+ <!--
+======================================================
+== ACCESS CONTROL
+======================================================
+-->
+ work with access tickets
+<doc>
+ The protocol control access to server resources using access tickets.
+ A client must explicitly request access tickets before doing work.
+ An access ticket grants a client the right to use a specific set of
+ resources - called a "realm" - in specific ways.
+</doc>
+ <doc name="grammar">
+ access = C:REQUEST S:REQUEST-OK
+</doc>
+ <chassis name="server" implement="MUST"/>
+ <chassis name="client" implement="MUST"/>
+ <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+ <method name="request" synchronous="1" index="10">
+ request an access ticket
+ <doc>
+ This method requests an access ticket for an access realm.
+ The server responds by granting the access ticket. If the
+ client does not have access rights to the requested realm
+ this causes a connection exception. Access tickets are a
+ per-channel resource.
+ </doc>
+ <rule implement="MUST">
+ The realm name MUST start with either "/data" (for application
+ resources) or "/admin" (for server administration resources).
+ If the realm starts with any other path, the server MUST raise
+ a connection exception with reply code 403 (access refused).
+ </rule>
+ <rule implement="MUST">
+ The server MUST implement the /data realm and MAY implement the
+ /admin realm. The mapping of resources to realms is not
+ defined in the protocol - this is a server-side configuration
+ issue.
+ </rule>
+ <chassis name="server" implement="MUST"/>
+ <response name="request-ok"/>
+ <field name="realm" domain="path">
+ name of requested realm
+ <rule implement="MUST">
+ If the specified realm is not known to the server, the server
+ must raise a channel exception with reply code 402 (invalid
+ path).
+ </rule>
+ </field>
+ <field name="exclusive" type="bit">
+ request exclusive access
+ <doc>
+ Request exclusive access to the realm. If the server cannot grant
+ this - because there are other active tickets for the realm - it
+ raises a channel exception.
+ </doc>
+ </field>
+ <field name="passive" type="bit">
+ request passive access
+ <doc>
+ Request message passive access to the specified access realm.
+ Passive access lets a client get information about resources in
+ the realm but not to make any changes to them.
+ </doc>
+ </field>
+ <field name="active" type="bit">
+ request active access
+ <doc>
+ Request message active access to the specified access realm.
+ Acvtive access lets a client get create and delete resources in
+ the realm.
+ </doc>
+ </field>
+ <field name="write" type="bit">
+ request write access
+ <doc>
+ Request write access to the specified access realm. Write access
+ lets a client publish messages to all exchanges in the realm.
+ </doc>
+ </field>
+ <field name="read" type="bit">
+ request read access
+ <doc>
+ Request read access to the specified access realm. Read access
+ lets a client consume messages from queues in the realm.
+ </doc>
+ </field>
+ </method>
+ <method name="request-ok" synchronous="1" index="11">
+ grant access to server resources
+ <doc>
+ This method provides the client with an access ticket. The access
+ ticket is valid within the current channel and for the lifespan of
+ the channel.
+ </doc>
+ <rule implement="MUST">
+ The client MUST NOT use access tickets except within the same
+ channel as originally granted.
+ </rule>
+ <rule implement="MUST">
+ The server MUST isolate access tickets per channel and treat an
+ attempt by a client to mix these as a connection exception.
+ </rule>
+ <chassis name="client" implement="MUST"/>
+ <field name="ticket" domain="access ticket"/>
+ </method>
+ </class>
+ <class name="exchange" handler="channel" index="40">
+ <!--
+======================================================
+== EXCHANGES (or "routers", if you prefer)
+== (Or matchers, plugins, extensions, agents,... Routing is just one of
+== the many fun things an exchange can do.)
+======================================================
+-->
+ work with exchanges
+<doc>
+ Exchanges match and distribute messages across queues. Exchanges can be
+ configured in the server or created at runtime.
+</doc>
+ <doc name="grammar">
+ exchange = C:DECLARE S:DECLARE-OK
+ / C:DELETE S:DELETE-OK
+</doc>
+ <chassis name="server" implement="MUST"/>
+ <chassis name="client" implement="MUST"/>
+ <rule implement="MUST">
+ <test>amq_exchange_19</test>
+ The server MUST implement the direct and fanout exchange types, and
+ predeclare the corresponding exchanges named amq.direct and amq.fanout
+ in each virtual host. The server MUST also predeclare a direct
+ exchange to act as the default exchange for content Publish methods
+ and for default queue bindings.
+</rule>
+ <rule implement="SHOULD">
+ <test>amq_exchange_20</test>
+ The server SHOULD implement the topic exchange type, and predeclare
+ the corresponding exchange named amq.topic in each virtual host.
+</rule>
+ <rule implement="MAY">
+ <test>amq_exchange_21</test>
+ The server MAY implement the system exchange type, and predeclare the
+ corresponding exchanges named amq.system in each virtual host. If the
+ client attempts to bind a queue to the system exchange, the server
+ MUST raise a connection exception with reply code 507 (not allowed).
+</rule>
+ <rule implement="MUST">
+ <test>amq_exchange_22</test>
+ The default exchange MUST be defined as internal, and be inaccessible
+ to the client except by specifying an empty exchange name in a content
+ Publish method. That is, the server MUST NOT let clients make explicit
+ bindings to this exchange.
+</rule>
+ <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+ <method name="declare" synchronous="1" index="10">
+ declare exchange, create if needed
+ <doc>
+ This method creates an exchange if it does not already exist, and if the
+ exchange exists, verifies that it is of the correct and expected class.
+ </doc>
+ <rule implement="SHOULD">
+ <test>amq_exchange_23</test>
+ The server SHOULD support a minimum of 16 exchanges per virtual host
+ and ideally, impose no limit except as defined by available resources.
+ </rule>
+ <chassis name="server" implement="MUST"/>
+ <response name="declare-ok"/>
+ <field name="ticket" domain="access ticket">
+ <doc>
+ When a client defines a new exchange, this belongs to the access realm
+ of the ticket used. All further work done with that exchange must be
+ done with an access ticket for the same realm.
+ </doc>
+ <rule implement="MUST">
+ The client MUST provide a valid access ticket giving "active" access
+ to the realm in which the exchange exists or will be created, or
+ "passive" access if the if-exists flag is set.
+ </rule>
+ </field>
+ <field name="exchange" domain="exchange name">
+ <rule implement="MUST">
+ <test>amq_exchange_15</test>
+ Exchange names starting with "amq." are reserved for predeclared
+ and standardised exchanges. If the client attempts to create an
+ exchange starting with "amq.", the server MUST raise a channel
+ exception with reply code 403 (access refused).
+ </rule>
+ <assert check="regexp" value="^[a-zA-Z0-9-_.:]+$"/>
+ </field>
+ <field name="type" type="shortstr">
+ exchange type
+ <doc>
+ Each exchange belongs to one of a set of exchange types implemented
+ by the server. The exchange types define the functionality of the
+ exchange - i.e. how messages are routed through it. It is not valid
+ or meaningful to attempt to change the type of an existing exchange.
+ </doc>
+ <rule implement="MUST">
+ <test>amq_exchange_16</test>
+ If the exchange already exists with a different type, the server
+ MUST raise a connection exception with a reply code 507 (not allowed).
+ </rule>
+ <rule implement="MUST">
+ <test>amq_exchange_18</test>
+ If the server does not support the requested exchange type it MUST
+ raise a connection exception with a reply code 503 (command invalid).
+ </rule>
+ <assert check="regexp" value="^[a-zA-Z0-9-_.:]+$"/>
+ </field>
+ <field name="passive" type="bit">
+ do not create exchange
+ <doc>
+ If set, the server will not create the exchange. The client can use
+ this to check whether an exchange exists without modifying the server
+ state.
+ </doc>
+ <rule implement="MUST">
+ <test>amq_exchange_05</test>
+ If set, and the exchange does not already exist, the server MUST
+ raise a channel exception with reply code 404 (not found).
+ </rule>
+ </field>
+ <field name="durable" type="bit">
+ request a durable exchange
+ <doc>
+ If set when creating a new exchange, the exchange will be marked as
+ durable. Durable exchanges remain active when a server restarts.
+ Non-durable exchanges (transient exchanges) are purged if/when a
+ server restarts.
+ </doc>
+ <rule implement="MUST">
+ <test>amq_exchange_24</test>
+ The server MUST support both durable and transient exchanges.
+ </rule>
+ <rule implement="MUST">
+ The server MUST ignore the durable field if the exchange already
+ exists.
+ </rule>
+ </field>
+ <field name="auto delete" type="bit">
+ auto-delete when unused
+ <doc>
+ If set, the exchange is deleted when all queues have finished
+ using it.
+ </doc>
+ <rule implement="SHOULD">
+ <test>amq_exchange_02</test>
+ The server SHOULD allow for a reasonable delay between the point
+ when it determines that an exchange is not being used (or no longer
+ used), and the point when it deletes the exchange. At the least it
+ must allow a client to create an exchange and then bind a queue to
+ it, with a small but non-zero delay between these two actions.
+ </rule>
+ <rule implement="MUST">
+ <test>amq_exchange_25</test>
+ The server MUST ignore the auto-delete field if the exchange already
+ exists.
+ </rule>
+ </field>
+ <field name="internal" type="bit">
+ create internal exchange
+ <doc>
+ If set, the exchange may not be used directly by publishers, but
+ only when bound to other exchanges. Internal exchanges are used to
+ construct wiring that is not visible to applications.
+ </doc>
+ </field>
+
+ <field name = "nowait" type = "bit">
+ do not send a reply method
+ <doc>
+ If set, the server will not respond to the method. The client should
+ not wait for a reply method. If the server could not complete the
+ method it will raise a channel or connection exception.
+ </doc>
+ </field>
+
+ <field name="arguments" type="table">
+ arguments for declaration
+ <doc>
+ A set of arguments for the declaration. The syntax and semantics
+ of these arguments depends on the server implementation. This
+ field is ignored if passive is 1.
+ </doc>
+ </field>
+ </method>
+ <method name="declare-ok" synchronous="1" index="11">
+ confirms an exchange declaration
+ <doc>
+ This method confirms a Declare method and confirms the name of the
+ exchange, essential for automatically-named exchanges.
+ </doc>
+ <chassis name="client" implement="MUST"/>
+ </method>
+ <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+ <method name="delete" synchronous="1" index="20">
+ delete an exchange
+ <doc>
+ This method deletes an exchange. When an exchange is deleted all queue
+ bindings on the exchange are cancelled.
+ </doc>
+ <chassis name="server" implement="MUST"/>
+ <response name="delete-ok"/>
+ <field name="ticket" domain="access ticket">
+ <rule implement="MUST">
+ The client MUST provide a valid access ticket giving "active"
+ access rights to the exchange's access realm.
+ </rule>
+ </field>
+ <field name="exchange" domain="exchange name">
+ <rule implement="MUST">
+ <test>amq_exchange_11</test>
+ The exchange MUST exist. Attempting to delete a non-existing exchange
+ causes a channel exception.
+ </rule>
+ <assert check="notnull"/>
+ </field>
+ <field name="if unused" type="bit">
+ delete only if unused
+ <doc>
+ If set, the server will only delete the exchange if it has no queue
+ bindings. If the exchange has queue bindings the server does not
+ delete it but raises a channel exception instead.
+ </doc>
+ <rule implement="SHOULD">
+ <test>amq_exchange_12</test>
+ If set, the server SHOULD delete the exchange but only if it has
+ no queue bindings.
+ </rule>
+ <rule implement="SHOULD">
+ <test>amq_exchange_13</test>
+ If set, the server SHOULD raise a channel exception if the exchange is in
+ use.
+ </rule>
+ </field>
+
+ <field name = "nowait" type = "bit">
+ do not send a reply method
+ <doc>
+ If set, the server will not respond to the method. The client should
+ not wait for a reply method. If the server could not complete the
+ method it will raise a channel or connection exception.
+ </doc>
+ </field>
+
+ </method>
+ <method name="delete-ok" synchronous="1" index="21">
+ confirm deletion of an exchange
+ <doc>
+ This method confirms the deletion of an exchange.
+ </doc>
+ <chassis name="client" implement="MUST"/>
+ </method>
+ </class>
+ <class name="queue" handler="channel" index="50">
+ <!--
+======================================================
+== QUEUES
+======================================================
+-->
+ work with queues
+
+<doc>
+ Queues store and forward messages. Queues can be configured in the server
+ or created at runtime. Queues must be attached to at least one exchange
+ in order to receive messages from publishers.
+</doc>
+ <doc name="grammar">
+ queue = C:DECLARE S:DECLARE-OK
+ / C:BIND S:BIND-OK
+ / C:PURGE S:PURGE-OK
+ / C:DELETE S:DELETE-OK
+</doc>
+ <chassis name="server" implement="MUST"/>
+ <chassis name="client" implement="MUST"/>
+ <rule implement="MUST">
+ <test>amq_queue_33</test>
+ A server MUST allow any content class to be sent to any queue, in any
+ mix, and queue and delivery these content classes independently. Note
+ that all methods that fetch content off queues are specific to a given
+ content class.
+</rule>
+ <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+ <method name="declare" synchronous="1" index="10">
+ declare queue, create if needed
+ <doc>
+ This method creates or checks a queue. When creating a new queue
+ the client can specify various properties that control the durability
+ of the queue and its contents, and the level of sharing for the queue.
+ </doc>
+ <rule implement="MUST">
+ <test>amq_queue_34</test>
+ The server MUST create a default binding for a newly-created queue
+ to the default exchange, which is an exchange of type 'direct'.
+ </rule>
+ <rule implement="SHOULD">
+ <test>amq_queue_35</test>
+ The server SHOULD support a minimum of 256 queues per virtual host
+ and ideally, impose no limit except as defined by available resources.
+ </rule>
+ <chassis name="server" implement="MUST"/>
+ <response name="declare-ok"/>
+ <field name="ticket" domain="access ticket">
+ <doc>
+ When a client defines a new queue, this belongs to the access realm
+ of the ticket used. All further work done with that queue must be
+ done with an access ticket for the same realm.
+ </doc>
+ <doc>
+ The client provides a valid access ticket giving "active" access
+ to the realm in which the queue exists or will be created, or
+ "passive" access if the if-exists flag is set.
+ </doc>
+ </field>
+ <field name="queue" domain="queue name">
+ <rule implement="MAY">
+ <test>amq_queue_10</test>
+ The queue name MAY be empty, in which case the server MUST create
+ a new queue with a unique generated name and return this to the
+ client in the Declare-Ok method.
+ </rule>
+ <rule implement="MUST">
+ <test>amq_queue_32</test>
+ Queue names starting with "amq." are reserved for predeclared and
+ standardised server queues. If the queue name starts with "amq."
+ and the passive option is zero, the server MUST raise a connection
+ exception with reply code 403 (access refused).
+ </rule>
+ <assert check="regexp" value="^[a-zA-Z0-9-_.:]*$"/>
+ </field>
+ <field name="passive" type="bit">
+ do not create queue
+ <doc>
+ If set, the server will not create the queue. The client can use
+ this to check whether a queue exists without modifying the server
+ state.
+ </doc>
+ <rule implement="MUST">
+ <test>amq_queue_05</test>
+ If set, and the queue does not already exist, the server MUST
+ respond with a reply code 404 (not found) and raise a channel
+ exception.
+ </rule>
+ </field>
+ <field name="durable" type="bit">
+ request a durable queue
+ <doc>
+ If set when creating a new queue, the queue will be marked as
+ durable. Durable queues remain active when a server restarts.
+ Non-durable queues (transient queues) are purged if/when a
+ server restarts. Note that durable queues do not necessarily
+ hold persistent messages, although it does not make sense to
+ send persistent messages to a transient queue.
+ </doc>
+ <rule implement="MUST">
+ <test>amq_queue_03</test>
+ The server MUST recreate the durable queue after a restart.
+ </rule>
+ <rule implement="MUST">
+ <test>amq_queue_36</test>
+ The server MUST support both durable and transient queues.
+ </rule>
+ <rule implement="MUST">
+ <test>amq_queue_37</test>
+ The server MUST ignore the durable field if the queue already
+ exists.
+ </rule>
+ </field>
+ <field name="exclusive" type="bit">
+ request an exclusive queue
+ <doc>
+ Exclusive queues may only be consumed from by the current connection.
+ Setting the 'exclusive' flag always implies 'auto-delete'.
+ </doc>
+ <rule implement="MUST">
+ <test>amq_queue_38</test>
+ The server MUST support both exclusive (private) and non-exclusive
+ (shared) queues.
+ </rule>
+ <rule implement="MUST">
+ <test>amq_queue_04</test>
+ The server MUST raise a channel exception if 'exclusive' is specified
+ and the queue already exists and is owned by a different connection.
+ </rule>
+ </field>
+ <field name="auto delete" type="bit">
+ auto-delete queue when unused
+ <doc>
+ If set, the queue is deleted when all consumers have finished
+ using it. Last consumer can be cancelled either explicitly or because
+ its channel is closed. If there was no consumer ever on the queue, it
+ won't be deleted.
+ </doc>
+ <rule implement="SHOULD">
+ <test>amq_queue_02</test>
+ The server SHOULD allow for a reasonable delay between the point
+ when it determines that a queue is not being used (or no longer
+ used), and the point when it deletes the queue. At the least it
+ must allow a client to create a queue and then create a consumer
+ to read from it, with a small but non-zero delay between these
+ two actions. The server should equally allow for clients that may
+ be disconnected prematurely, and wish to re-consume from the same
+ queue without losing messages. We would recommend a configurable
+ timeout, with a suitable default value being one minute.
+ </rule>
+ <rule implement="MUST">
+ <test>amq_queue_31</test>
+ The server MUST ignore the auto-delete field if the queue already
+ exists.
+ </rule>
+ </field>
+ <field name = "nowait" type = "bit">
+ do not send a reply method
+ <doc>
+ If set, the server will not respond to the method. The client should
+ not wait for a reply method. If the server could not complete the
+ method it will raise a channel or connection exception.
+ </doc>
+ </field>
+
+ <field name="arguments" type="table">
+ arguments for declaration
+ <doc>
+ A set of arguments for the declaration. The syntax and semantics
+ of these arguments depends on the server implementation. This
+ field is ignored if passive is 1.
+ </doc>
+ </field>
+ </method>
+ <method name="declare-ok" synchronous="1" index="11">
+ confirms a queue definition
+ <doc>
+ This method confirms a Declare method and confirms the name of the
+ queue, essential for automatically-named queues.
+ </doc>
+ <chassis name="client" implement="MUST"/>
+ <field name="queue" domain="queue name">
+ <doc>
+ Reports the name of the queue. If the server generated a queue
+ name, this field contains that name.
+ </doc>
+ <assert check="notnull"/>
+ </field>
+ <field name="message count" type="long">
+ number of messages in queue
+ <doc>
+ Reports the number of messages in the queue, which will be zero
+ for newly-created queues.
+ </doc>
+ </field>
+ <field name="consumer count" type="long">
+ number of consumers
+ <doc>
+ Reports the number of active consumers for the queue. Note that
+ consumers can suspend activity (Channel.Flow) in which case they
+ do not appear in this count.
+ </doc>
+ </field>
+ </method>
+ <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+ <method name="bind" synchronous="1" index="20">
+ bind queue to an exchange
+ <doc>
+ This method binds a queue to an exchange. Until a queue is
+ bound it will not receive any messages. In a classic messaging
+ model, store-and-forward queues are bound to a dest exchange
+ and subscription queues are bound to a dest_wild exchange.
+ </doc>
+ <rule implement="MUST">
+ <test>amq_queue_25</test>
+ A server MUST allow ignore duplicate bindings - that is, two or
+ more bind methods for a specific queue, with identical arguments
+ - without treating these as an error.
+ </rule>
+ <rule implement="MUST">
+ <test>amq_queue_39</test>
+ If a bind fails, the server MUST raise a connection exception.
+ </rule>
+ <rule implement="MUST">
+ <test>amq_queue_12</test>
+ The server MUST NOT allow a durable queue to bind to a transient
+ exchange. If the client attempts this the server MUST raise a
+ channel exception.
+ </rule>
+ <rule implement="SHOULD">
+ <test>amq_queue_13</test>
+ Bindings for durable queues are automatically durable and the
+ server SHOULD restore such bindings after a server restart.
+ </rule>
+ <rule implement="MUST">
+ <test>amq_queue_17</test>
+ If the client attempts to an exchange that was declared as internal,
+ the server MUST raise a connection exception with reply code 530
+ (not allowed).
+ </rule>
+ <rule implement="SHOULD">
+ <test>amq_queue_40</test>
+ The server SHOULD support at least 4 bindings per queue, and
+ ideally, impose no limit except as defined by available resources.
+ </rule>
+ <chassis name="server" implement="MUST"/>
+ <response name="bind-ok"/>
+ <field name="ticket" domain="access ticket">
+ <doc>
+ The client provides a valid access ticket giving "active"
+ access rights to the queue's access realm.
+ </doc>
+ </field>
+
+ <field name = "queue" domain = "queue name">
+ <doc>
+ Specifies the name of the queue to bind. If the queue name is
+ empty, refers to the current queue for the channel, which is
+ the last declared queue.
+ </doc>
+ <doc name = "rule">
+ If the client did not previously declare a queue, and the queue
+ name in this method is empty, the server MUST raise a connection
+ exception with reply code 530 (not allowed).
+ </doc>
+ <doc name = "rule" test = "amq_queue_26">
+ If the queue does not exist the server MUST raise a channel exception
+ with reply code 404 (not found).
+ </doc>
+ </field>
+
+ <field name="exchange" domain="exchange name">
+ The name of the exchange to bind to.
+ <rule implement="MUST">
+ <test>amq_queue_14</test>
+ If the exchange does not exist the server MUST raise a channel
+ exception with reply code 404 (not found).
+ </rule>
+ </field>
+ <field name="routing key" type="shortstr">
+ message routing key
+ <doc>
+ Specifies the routing key for the binding. The routing key is
+ used for routing messages depending on the exchange configuration.
+ Not all exchanges use a routing key - refer to the specific
+ exchange documentation. If the routing key is empty and the queue
+ name is empty, the routing key will be the current queue for the
+ channel, which is the last declared queue.
+ </doc>
+ </field>
+
+ <field name = "nowait" type = "bit">
+ do not send a reply method
+ <doc>
+ If set, the server will not respond to the method. The client should
+ not wait for a reply method. If the server could not complete the
+ method it will raise a channel or connection exception.
+ </doc>
+ </field>
+
+ <field name="arguments" type="table">
+ arguments for binding
+ <doc>
+ A set of arguments for the binding. The syntax and semantics of
+ these arguments depends on the exchange class.
+ </doc>
+ </field>
+ </method>
+ <method name="bind-ok" synchronous="1" index="21">
+ confirm bind successful
+ <doc>
+ This method confirms that the bind was successful.
+ </doc>
+ <chassis name="client" implement="MUST"/>
+ </method>
+ <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+ <method name="purge" synchronous="1" index="30">
+ purge a queue
+ <doc>
+ This method removes all messages from a queue. It does not cancel
+ consumers. Purged messages are deleted without any formal "undo"
+ mechanism.
+ </doc>
+ <rule implement="MUST">
+ <test>amq_queue_15</test>
+ A call to purge MUST result in an empty queue.
+ </rule>
+ <rule implement="MUST">
+ <test>amq_queue_41</test>
+ On transacted channels the server MUST not purge messages that have
+ already been sent to a client but not yet acknowledged.
+ </rule>
+ <rule implement="MAY">
+ <test>amq_queue_42</test>
+ The server MAY implement a purge queue or log that allows system
+ administrators to recover accidentally-purged messages. The server
+ SHOULD NOT keep purged messages in the same storage spaces as the
+ live messages since the volumes of purged messages may get very
+ large.
+ </rule>
+ <chassis name="server" implement="MUST"/>
+ <response name="purge-ok"/>
+ <field name="ticket" domain="access ticket">
+ <doc>
+ The access ticket must be for the access realm that holds the
+ queue.
+ </doc>
+ <rule implement="MUST">
+ The client MUST provide a valid access ticket giving "read" access
+ rights to the queue's access realm. Note that purging a queue is
+ equivalent to reading all messages and discarding them.
+ </rule>
+ </field>
+ <field name = "queue" domain = "queue name">
+ <doc>
+ Specifies the name of the queue to purge. If the queue name is
+ empty, refers to the current queue for the channel, which is
+ the last declared queue.
+ </doc>
+ <doc name = "rule">
+ If the client did not previously declare a queue, and the queue
+ name in this method is empty, the server MUST raise a connection
+ exception with reply code 530 (not allowed).
+ </doc>
+ <doc name = "rule" test = "amq_queue_16">
+ The queue must exist. Attempting to purge a non-existing queue
+ causes a channel exception.
+ </doc>
+ </field>
+
+ <field name = "nowait" type = "bit">
+ do not send a reply method
+ <doc>
+ If set, the server will not respond to the method. The client should
+ not wait for a reply method. If the server could not complete the
+ method it will raise a channel or connection exception.
+ </doc>
+ </field>
+ </method>
+ <method name="purge-ok" synchronous="1" index="31">
+ confirms a queue purge
+ <doc>
+ This method confirms the purge of a queue.
+ </doc>
+ <chassis name="client" implement="MUST"/>
+ <field name="message count" type="long">
+ number of messages purged
+ <doc>
+ Reports the number of messages purged.
+ </doc>
+ </field>
+ </method>
+ <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+ <method name="delete" synchronous="1" index="40">
+ delete a queue
+ <doc>
+ This method deletes a queue. When a queue is deleted any pending
+ messages are sent to a dead-letter queue if this is defined in the
+ server configuration, and all consumers on the queue are cancelled.
+ </doc>
+ <rule implement="SHOULD">
+ <test>amq_queue_43</test>
+ The server SHOULD use a dead-letter queue to hold messages that
+ were pending on a deleted queue, and MAY provide facilities for
+ a system administrator to move these messages back to an active
+ queue.
+ </rule>
+ <chassis name="server" implement="MUST"/>
+ <response name="delete-ok"/>
+ <field name="ticket" domain="access ticket">
+ <doc>
+ The client provides a valid access ticket giving "active"
+ access rights to the queue's access realm.
+ </doc>
+ </field>
+
+ <field name = "queue" domain = "queue name">
+ <doc>
+ Specifies the name of the queue to delete. If the queue name is
+ empty, refers to the current queue for the channel, which is the
+ last declared queue.
+ </doc>
+ <doc name = "rule">
+ If the client did not previously declare a queue, and the queue
+ name in this method is empty, the server MUST raise a connection
+ exception with reply code 530 (not allowed).
+ </doc>
+ <doc name = "rule" test = "amq_queue_21">
+ The queue must exist. Attempting to delete a non-existing queue
+ causes a channel exception.
+ </doc>
+ </field>
+
+ <field name="if unused" type="bit">
+ delete only if unused
+ <doc>
+ If set, the server will only delete the queue if it has no
+ consumers. If the queue has consumers the server does does not
+ delete it but raises a channel exception instead.
+ </doc>
+ <rule implement="MUST">
+ <test>amq_queue_29</test>
+ <test>amq_queue_30</test>
+ The server MUST respect the if-unused flag when deleting a queue.
+ </rule>
+ </field>
+ <field name="if empty" type="bit">
+ delete only if empty
+ <test>amq_queue_27</test>
+ <doc>
+ If set, the server will only delete the queue if it has no
+ messages. If the queue is not empty the server raises a channel
+ exception.
+ </doc>
+ </field>
+ <field name = "nowait" type = "bit">
+ do not send a reply method
+ <doc>
+ If set, the server will not respond to the method. The client should
+ not wait for a reply method. If the server could not complete the
+ method it will raise a channel or connection exception.
+ </doc>
+ </field>
+ </method>
+
+ <method name="delete-ok" synchronous="1" index="41">
+ confirm deletion of a queue
+ <doc>
+ This method confirms the deletion of a queue.
+ </doc>
+ <chassis name="client" implement="MUST"/>
+ <field name="message count" type="long">
+ number of messages purged
+ <doc>
+ Reports the number of messages purged.
+ </doc>
+ </field>
+ </method>
+ </class>
+ <class name="basic" handler="channel" index="60">
+ <!--
+======================================================
+== BASIC MIDDLEWARE
+======================================================
+-->
+ work with basic content
+<doc>
+ The Basic class provides methods that support an industry-standard
+ messaging model.
+</doc>
+
+<doc name = "grammar">
+ basic = C:QOS S:QOS-OK
+ / C:CONSUME S:CONSUME-OK
+ / C:CANCEL S:CANCEL-OK
+ / C:PUBLISH content
+ / S:RETURN content
+ / S:DELIVER content
+ / C:GET ( S:GET-OK content / S:GET-EMPTY )
+ / C:ACK
+ / C:REJECT
+</doc>
+
+<chassis name = "server" implement = "MUST" />
+<chassis name = "client" implement = "MAY" />
+
+<doc name = "rule" test = "amq_basic_08">
+ The server SHOULD respect the persistent property of basic messages
+ and SHOULD make a best-effort to hold persistent basic messages on a
+ reliable storage mechanism.
+</doc>
+<doc name = "rule" test = "amq_basic_09">
+ The server MUST NOT discard a persistent basic message in case of a
+ queue overflow. The server MAY use the Channel.Flow method to slow
+ or stop a basic message publisher when necessary.
+</doc>
+<doc name = "rule" test = "amq_basic_10">
+ The server MAY overflow non-persistent basic messages to persistent
+ storage and MAY discard or dead-letter non-persistent basic messages
+ on a priority basis if the queue size exceeds some configured limit.
+</doc>
+<doc name = "rule" test = "amq_basic_11">
+ The server MUST implement at least 2 priority levels for basic
+ messages, where priorities 0-4 and 5-9 are treated as two distinct
+ levels. The server MAY implement up to 10 priority levels.
+</doc>
+<doc name = "rule" test = "amq_basic_12">
+ The server MUST deliver messages of the same priority in order
+ irrespective of their individual persistence.
+</doc>
+<doc name = "rule" test = "amq_basic_13">
+ The server MUST support both automatic and explicit acknowledgements
+ on Basic content.
+</doc>
+
+<!-- These are the properties for a Basic content -->
+
+<field name = "content type" type = "shortstr">
+ MIME content type
+</field>
+<field name = "content encoding" type = "shortstr">
+ MIME content encoding
+</field>
+<field name = "headers" type = "table">
+ Message header field table
+</field>
+<field name = "delivery mode" type = "octet">
+ Non-persistent (1) or persistent (2)
+</field>
+<field name = "priority" type = "octet">
+ The message priority, 0 to 9
+</field>
+<field name = "correlation id" type = "shortstr">
+ The application correlation identifier
+</field>
+<field name = "reply to" type = "shortstr">
+ The destination to reply to
+</field>
+<field name = "expiration" type = "shortstr">
+ Message expiration specification
+</field>
+<field name = "message id" type = "shortstr">
+ The application message identifier
+</field>
+<field name = "timestamp" type = "timestamp">
+ The message timestamp
+</field>
+<field name = "type" type = "shortstr">
+ The message type name
+</field>
+<field name = "user id" type = "shortstr">
+ The creating user id
+</field>
+<field name = "app id" type = "shortstr">
+ The creating application id
+</field>
+<field name = "cluster id" type = "shortstr">
+ Intra-cluster routing identifier
+</field>
+
+
+<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+<method name = "qos" synchronous = "1" index = "10">
+ specify quality of service
+ <doc>
+ This method requests a specific quality of service. The QoS can
+ be specified for the current channel or for all channels on the
+ connection. The particular properties and semantics of a qos method
+ always depend on the content class semantics. Though the qos method
+ could in principle apply to both peers, it is currently meaningful
+ only for the server.
+ </doc>
+ <chassis name = "server" implement = "MUST" />
+ <response name = "qos-ok" />
+
+ <field name = "prefetch size" type = "long">
+ prefetch window in octets
+ <doc>
+ The client can request that messages be sent in advance so that
+ when the client finishes processing a message, the following
+ message is already held locally, rather than needing to be sent
+ down the channel. Prefetching gives a performance improvement.
+ This field specifies the prefetch window size in octets. The
+ server will send a message in advance if it is equal to or
+ smaller in size than the available prefetch size (and also falls
+ into other prefetch limits). May be set to zero, meaning "no
+ specific limit", although other prefetch limits may still apply.
+ The prefetch-size is ignored if the no-ack option is set.
+ </doc>
+ <doc name = "rule" test = "amq_basic_17">
+ The server MUST ignore this setting when the client is not
+ processing any messages - i.e. the prefetch size does not limit
+ the transfer of single messages to a client, only the sending in
+ advance of more messages while the client still has one or more
+ unacknowledged messages.
+ </doc>
+ </field>
+
+ <field name = "prefetch count" type = "short">
+ prefetch window in messages
+ <doc>
+ Specifies a prefetch window in terms of whole messages. This
+ field may be used in combination with the prefetch-size field;
+ a message will only be sent in advance if both prefetch windows
+ (and those at the channel and connection level) allow it.
+ The prefetch-count is ignored if the no-ack option is set.
+ </doc>
+ <doc name = "rule" test = "amq_basic_18">
+ The server MAY send less data in advance than allowed by the
+ client's specified prefetch windows but it MUST NOT send more.
+ </doc>
+ </field>
+
+ <field name = "global" type = "bit">
+ apply to entire connection
+ <doc>
+ By default the QoS settings apply to the current channel only. If
+ this field is set, they are applied to the entire connection.
+ </doc>
+ </field>
+</method>
+
+<method name = "qos-ok" synchronous = "1" index = "11">
+ confirm the requested qos
+ <doc>
+ This method tells the client that the requested QoS levels could
+ be handled by the server. The requested QoS applies to all active
+ consumers until a new QoS is defined.
+ </doc>
+ <chassis name = "client" implement = "MUST" />
+</method>
+
+<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+<method name = "consume" synchronous = "1" index = "20">
+ start a queue consumer
+ <doc>
+ This method asks the server to start a "consumer", which is a
+ transient request for messages from a specific queue. Consumers
+ last as long as the channel they were created on, or until the
+ client cancels them.
+ </doc>
+ <doc name = "rule" test = "amq_basic_01">
+ The server SHOULD support at least 16 consumers per queue, unless
+ the queue was declared as private, and ideally, impose no limit
+ except as defined by available resources.
+ </doc>
+ <chassis name = "server" implement = "MUST" />
+ <response name = "consume-ok" />
+
+ <field name = "ticket" domain = "access ticket">
+ <doc name = "rule">
+ The client MUST provide a valid access ticket giving "read" access
+ rights to the realm for the queue.
+ </doc>
+ </field>
+
+ <field name = "queue" domain = "queue name">
+ <doc>
+ Specifies the name of the queue to consume from. If the queue name
+ is null, refers to the current queue for the channel, which is the
+ last declared queue.
+ </doc>
+ <doc name = "rule">
+ If the client did not previously declare a queue, and the queue name
+ in this method is empty, the server MUST raise a connection exception
+ with reply code 530 (not allowed).
+ </doc>
+ </field>
+
+ <field name = "consumer tag" domain = "consumer tag">
+ <doc>
+ Specifies the identifier for the consumer. The consumer tag is
+ local to a connection, so two clients can use the same consumer
+ tags. If this field is empty the server will generate a unique
+ tag.
+ </doc>
+ <doc name = "rule" test = "todo">
+ The tag MUST NOT refer to an existing consumer. If the client
+ attempts to create two consumers with the same non-empty tag
+ the server MUST raise a connection exception with reply code
+ 530 (not allowed).
+ </doc>
+ </field>
+
+ <field name = "no local" domain = "no local" />
+
+ <field name = "no ack" domain = "no ack" />
+
+ <field name = "exclusive" type = "bit">
+ request exclusive access
+ <doc>
+ Request exclusive consumer access, meaning only this consumer can
+ access the queue.
+ </doc>
+ <doc name = "rule" test = "amq_basic_02">
+ If the server cannot grant exclusive access to the queue when asked,
+ - because there are other consumers active - it MUST raise a channel
+ exception with return code 403 (access refused).
+ </doc>
+ </field>
+
+ <field name = "nowait" type = "bit">
+ do not send a reply method
+ <doc>
+ If set, the server will not respond to the method. The client should
+ not wait for a reply method. If the server could not complete the
+ method it will raise a channel or connection exception.
+ </doc>
+ </field>
+</method>
+
+<method name = "consume-ok" synchronous = "1" index = "21">
+ confirm a new consumer
+ <doc>
+ The server provides the client with a consumer tag, which is used
+ by the client for methods called on the consumer at a later stage.
+ </doc>
+ <chassis name = "client" implement = "MUST" />
+
+ <field name = "consumer tag" domain = "consumer tag">
+ <doc>
+ Holds the consumer tag specified by the client or provided by
+ the server.
+ </doc>
+ </field>
+</method>
+
+
+<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+<method name = "cancel" synchronous = "1" index = "30">
+ end a queue consumer
+ <doc test = "amq_basic_04">
+ This method cancels a consumer. This does not affect already
+ delivered messages, but it does mean the server will not send any
+ more messages for that consumer. The client may receive an
+ abitrary number of messages in between sending the cancel method
+ and receiving the cancel-ok reply.
+ </doc>
+ <doc name = "rule" test = "todo">
+ If the queue no longer exists when the client sends a cancel command,
+ or the consumer has been cancelled for other reasons, this command
+ has no effect.
+ </doc>
+ <chassis name = "server" implement = "MUST" />
+ <response name = "cancel-ok" />
+
+ <field name = "consumer tag" domain = "consumer tag" />
+
+ <field name = "nowait" type = "bit">
+ do not send a reply method
+ <doc>
+ If set, the server will not respond to the method. The client should
+ not wait for a reply method. If the server could not complete the
+ method it will raise a channel or connection exception.
+ </doc>
+ </field>
+</method>
+
+<method name = "cancel-ok" synchronous = "1" index = "31">
+ confirm a cancelled consumer
+ <doc>
+ This method confirms that the cancellation was completed.
+ </doc>
+ <chassis name = "client" implement = "MUST" />
+
+ <field name = "consumer tag" domain = "consumer tag" />
+</method>
+
+
+<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+<method name = "publish" content = "1" index = "40">
+ publish a message
+ <doc>
+ This method publishes a message to a specific exchange. The message
+ will be routed to queues as defined by the exchange configuration
+ and distributed to any active consumers when the transaction, if any,
+ is committed.
+ </doc>
+ <chassis name = "server" implement = "MUST" />
+
+ <field name = "ticket" domain = "access ticket">
+ <doc name = "rule">
+ The client MUST provide a valid access ticket giving "write"
+ access rights to the access realm for the exchange.
+ </doc>
+ </field>
+
+ <field name = "exchange" domain = "exchange name">
+ <doc>
+ Specifies the name of the exchange to publish to. The exchange
+ name can be empty, meaning the default exchange. If the exchange
+ name is specified, and that exchange does not exist, the server
+ will raise a channel exception.
+ </doc>
+ <doc name = "rule" test = "amq_basic_06">
+ The server MUST accept a blank exchange name to mean the default
+ exchange.
+ </doc>
+ <doc name = "rule" test = "amq_basic_14">
+ If the exchange was declared as an internal exchange, the server
+ MUST raise a channel exception with a reply code 403 (access
+ refused).
+ </doc>
+ <doc name = "rule" test = "amq_basic_15">
+ The exchange MAY refuse basic content in which case it MUST raise
+ a channel exception with reply code 540 (not implemented).
+ </doc>
+ </field>
+
+ <field name = "routing key" type = "shortstr">
+ Message routing key
+ <doc>
+ Specifies the routing key for the message. The routing key is
+ used for routing messages depending on the exchange configuration.
+ </doc>
+ </field>
+
+ <field name = "mandatory" type = "bit">
+ indicate mandatory routing
+ <doc>
+ This flag tells the server how to react if the message cannot be
+ routed to a queue. If this flag is set, the server will return an
+ unroutable message with a Return method. If this flag is zero, the
+ server silently drops the message.
+ </doc>
+ <doc name = "rule" test = "amq_basic_07">
+ The server SHOULD implement the mandatory flag.
+ </doc>
+ </field>
+
+ <field name = "immediate" type = "bit">
+ request immediate delivery
+ <doc>
+ This flag tells the server how to react if the message cannot be
+ routed to a queue consumer immediately. If this flag is set, the
+ server will return an undeliverable message with a Return method.
+ If this flag is zero, the server will queue the message, but with
+ no guarantee that it will ever be consumed.
+ </doc>
+ <doc name = "rule" test = "amq_basic_16">
+ The server SHOULD implement the immediate flag.
+ </doc>
+ </field>
+</method>
+
+<method name = "return" content = "1" index = "50">
+ return a failed message
+ <doc>
+ This method returns an undeliverable message that was published
+ with the "immediate" flag set, or an unroutable message published
+ with the "mandatory" flag set. The reply code and text provide
+ information about the reason that the message was undeliverable.
+ </doc>
+ <chassis name = "client" implement = "MUST" />
+
+ <field name = "reply code" domain = "reply code" />
+ <field name = "reply text" domain = "reply text" />
+
+ <field name = "exchange" domain = "exchange name">
+ <doc>
+ Specifies the name of the exchange that the message was
+ originally published to.
+ </doc>
+ </field>
+
+ <field name = "routing key" type = "shortstr">
+ Message routing key
+ <doc>
+ Specifies the routing key name specified when the message was
+ published.
+ </doc>
+ </field>
+</method>
+
+
+<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+<method name = "deliver" content = "1" index = "60">
+ notify the client of a consumer message
+ <doc>
+ This method delivers a message to the client, via a consumer. In
+ the asynchronous message delivery model, the client starts a
+ consumer using the Consume method, then the server responds with
+ Deliver methods as and when messages arrive for that consumer.
+ </doc>
+ <doc name = "rule" test = "amq_basic_19">
+ The server SHOULD track the number of times a message has been
+ delivered to clients and when a message is redelivered a certain
+ number of times - e.g. 5 times - without being acknowledged, the
+ server SHOULD consider the message to be unprocessable (possibly
+ causing client applications to abort), and move the message to a
+ dead letter queue.
+ </doc>
+ <chassis name = "client" implement = "MUST" />
+
+ <field name = "consumer tag" domain = "consumer tag" />
+
+ <field name = "delivery tag" domain = "delivery tag" />
+
+ <field name = "redelivered" domain = "redelivered" />
+
+ <field name = "exchange" domain = "exchange name">
+ <doc>
+ Specifies the name of the exchange that the message was
+ originally published to.
+ </doc>
+ </field>
+
+ <field name = "routing key" type = "shortstr">
+ Message routing key
+ <doc>
+ Specifies the routing key name specified when the message was
+ published.
+ </doc>
+ </field>
+</method>
+
+
+<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+<method name = "get" synchronous = "1" index = "70">
+ direct access to a queue
+ <doc>
+ This method provides a direct access to the messages in a queue
+ using a synchronous dialogue that is designed for specific types of
+ application where synchronous functionality is more important than
+ performance.
+ </doc>
+ <response name = "get-ok" />
+ <response name = "get-empty" />
+ <chassis name = "server" implement = "MUST" />
+
+ <field name = "ticket" domain = "access ticket">
+ <doc name = "rule">
+ The client MUST provide a valid access ticket giving "read"
+ access rights to the realm for the queue.
+ </doc>
+ </field>
+
+ <field name = "queue" domain = "queue name">
+ <doc>
+ Specifies the name of the queue to consume from. If the queue name
+ is null, refers to the current queue for the channel, which is the
+ last declared queue.
+ </doc>
+ <doc name = "rule">
+ If the client did not previously declare a queue, and the queue name
+ in this method is empty, the server MUST raise a connection exception
+ with reply code 530 (not allowed).
+ </doc>
+ </field>
+
+ <field name = "no ack" domain = "no ack" />
+</method>
+
+<method name = "get-ok" synchronous = "1" content = "1" index = "71">
+ provide client with a message
+ <doc>
+ This method delivers a message to the client following a get
+ method. A message delivered by 'get-ok' must be acknowledged
+ unless the no-ack option was set in the get method.
+ </doc>
+ <chassis name = "client" implement = "MAY" />
+
+ <field name = "delivery tag" domain = "delivery tag" />
+
+ <field name = "redelivered" domain = "redelivered" />
+
+ <field name = "exchange" domain = "exchange name">
+ <doc>
+ Specifies the name of the exchange that the message was originally
+ published to. If empty, the message was published to the default
+ exchange.
+ </doc>
+ </field>
+
+ <field name = "routing key" type = "shortstr">
+ Message routing key
+ <doc>
+ Specifies the routing key name specified when the message was
+ published.
+ </doc>
+ </field>
+
+ <field name = "message count" type = "long" >
+ number of messages pending
+ <doc>
+ This field reports the number of messages pending on the queue,
+ excluding the message being delivered. Note that this figure is
+ indicative, not reliable, and can change arbitrarily as messages
+ are added to the queue and removed by other clients.
+ </doc>
+ </field>
+</method>
+
+
+<method name = "get-empty" synchronous = "1" index = "72">
+ indicate no messages available
+ <doc>
+ This method tells the client that the queue has no messages
+ available for the client.
+ </doc>
+ <chassis name = "client" implement = "MAY" />
+
+ <field name = "cluster id" type = "shortstr">
+ Cluster id
+ <doc>
+ For use by cluster applications, should not be used by
+ client applications.
+ </doc>
+ </field>
+</method>
+
+<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+<method name = "ack" index = "80">
+ acknowledge one or more messages
+ <doc>
+ This method acknowledges one or more messages delivered via the
+ Deliver or Get-Ok methods. The client can ask to confirm a
+ single message or a set of messages up to and including a specific
+ message.
+ </doc>
+ <chassis name = "server" implement = "MUST" />
+ <field name = "delivery tag" domain = "delivery tag" />
+
+ <field name = "multiple" type = "bit">
+ acknowledge multiple messages
+ <doc>
+ If set to 1, the delivery tag is treated as "up to and including",
+ so that the client can acknowledge multiple messages with a single
+ method. If set to zero, the delivery tag refers to a single
+ message. If the multiple field is 1, and the delivery tag is zero,
+ tells the server to acknowledge all outstanding mesages.
+ </doc>
+ <doc name = "rule" test = "amq_basic_20">
+ The server MUST validate that a non-zero delivery-tag refers to an
+ delivered message, and raise a channel exception if this is not the
+ case.
+ </doc>
+ </field>
+</method>
+
+<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+<method name = "reject" index = "90">
+ reject an incoming message
+ <doc>
+ This method allows a client to reject a message. It can be used to
+ interrupt and cancel large incoming messages, or return untreatable
+ messages to their original queue.
+ </doc>
+ <doc name = "rule" test = "amq_basic_21">
+ The server SHOULD be capable of accepting and process the Reject
+ method while sending message content with a Deliver or Get-Ok
+ method. I.e. the server should read and process incoming methods
+ while sending output frames. To cancel a partially-send content,
+ the server sends a content body frame of size 1 (i.e. with no data
+ except the frame-end octet).
+ </doc>
+ <doc name = "rule" test = "amq_basic_22">
+ The server SHOULD interpret this method as meaning that the client
+ is unable to process the message at this time.
+ </doc>
+ <doc name = "rule">
+ A client MUST NOT use this method as a means of selecting messages
+ to process. A rejected message MAY be discarded or dead-lettered,
+ not necessarily passed to another client.
+ </doc>
+ <chassis name = "server" implement = "MUST" />
+
+ <field name = "delivery tag" domain = "delivery tag" />
+
+ <field name = "requeue" type = "bit">
+ requeue the message
+ <doc>
+ If this field is zero, the message will be discarded. If this bit
+ is 1, the server will attempt to requeue the message.
+ </doc>
+ <doc name = "rule" test = "amq_basic_23">
+ The server MUST NOT deliver the message to the same client within
+ the context of the current channel. The recommended strategy is
+ to attempt to deliver the message to an alternative consumer, and
+ if that is not possible, to move the message to a dead-letter
+ queue. The server MAY use more sophisticated tracking to hold
+ the message on the queue and redeliver it to the same client at
+ a later stage.
+ </doc>
+ </field>
+</method>
+
+<method name = "recover" index = "100">
+ redeliver unacknowledged messages. This method is only allowed on non-transacted channels.
+ <doc>
+ This method asks the broker to redeliver all unacknowledged messages on a
+ specifieid channel. Zero or more messages may be redelivered.
+ </doc>
+ <chassis name = "server" implement = "MUST" />
+
+ <field name = "requeue" type = "bit">
+ requeue the message
+ <doc>
+ If this field is zero, the message will be redelivered to the original recipient. If this bit
+ is 1, the server will attempt to requeue the message, potentially then delivering it to an
+ alternative subscriber.
+ </doc>
+ </field>
+
+ <doc name="rule">
+ The server MUST set the redelivered flag on all messages that are resent.
+ </doc>
+ <doc name="rule">
+ The server MUST raise a channel exception if this is called on a transacted channel.
+ </doc>
+</method>
+
+
+</class>
+
+
+ <class name="file" handler="channel" index="70">
+ <!--
+======================================================
+== FILE TRANSFER
+======================================================
+-->
+ work with file content
+<doc>
+ The file class provides methods that support reliable file transfer.
+ File messages have a specific set of properties that are required for
+ interoperability with file transfer applications. File messages and
+ acknowledgements are subject to channel transactions. Note that the
+ file class does not provide message browsing methods; these are not
+ compatible with the staging model. Applications that need browsable
+ file transfer should use Basic content and the Basic class.
+</doc>
+
+<doc name = "grammar">
+ file = C:QOS S:QOS-OK
+ / C:CONSUME S:CONSUME-OK
+ / C:CANCEL S:CANCEL-OK
+ / C:OPEN S:OPEN-OK C:STAGE content
+ / S:OPEN C:OPEN-OK S:STAGE content
+ / C:PUBLISH
+ / S:DELIVER
+ / S:RETURN
+ / C:ACK
+ / C:REJECT
+</doc>
+
+<chassis name = "server" implement = "MAY" />
+<chassis name = "client" implement = "MAY" />
+
+<doc name = "rule">
+ The server MUST make a best-effort to hold file messages on a
+ reliable storage mechanism.
+</doc>
+<doc name = "rule">
+ The server MUST NOT discard a file message in case of a queue
+ overflow. The server MUST use the Channel.Flow method to slow or stop
+ a file message publisher when necessary.
+</doc>
+<doc name = "rule">
+ The server MUST implement at least 2 priority levels for file
+ messages, where priorities 0-4 and 5-9 are treated as two distinct
+ levels. The server MAY implement up to 10 priority levels.
+</doc>
+<doc name = "rule">
+ The server MUST support both automatic and explicit acknowledgements
+ on file content.
+</doc>
+
+<!-- These are the properties for a File content -->
+
+<field name = "content type" type = "shortstr">
+ MIME content type
+</field>
+<field name = "content encoding" type = "shortstr">
+ MIME content encoding
+</field>
+<field name = "headers" type = "table">
+ Message header field table
+</field>
+<field name = "priority" type = "octet">
+ The message priority, 0 to 9
+</field>
+<field name = "reply to" type = "shortstr">
+ The destination to reply to
+</field>
+<field name = "message id" type = "shortstr">
+ The application message identifier
+</field>
+<field name = "filename" type = "shortstr">
+ The message filename
+</field>
+<field name = "timestamp" type = "timestamp">
+ The message timestamp
+</field>
+<field name = "cluster id" type = "shortstr">
+ Intra-cluster routing identifier
+</field>
+
+
+<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+<method name = "qos" synchronous = "1" index = "10">
+ specify quality of service
+ <doc>
+ This method requests a specific quality of service. The QoS can
+ be specified for the current channel or for all channels on the
+ connection. The particular properties and semantics of a qos method
+ always depend on the content class semantics. Though the qos method
+ could in principle apply to both peers, it is currently meaningful
+ only for the server.
+ </doc>
+ <chassis name = "server" implement = "MUST" />
+ <response name = "qos-ok" />
+
+ <field name = "prefetch size" type = "long">
+ prefetch window in octets
+ <doc>
+ The client can request that messages be sent in advance so that
+ when the client finishes processing a message, the following
+ message is already held locally, rather than needing to be sent
+ down the channel. Prefetching gives a performance improvement.
+ This field specifies the prefetch window size in octets. May be
+ set to zero, meaning "no specific limit". Note that other
+ prefetch limits may still apply. The prefetch-size is ignored
+ if the no-ack option is set.
+ </doc>
+ </field>
+
+ <field name = "prefetch count" type = "short">
+ prefetch window in messages
+ <doc>
+ Specifies a prefetch window in terms of whole messages. This
+ is compatible with some file API implementations. This field
+ may be used in combination with the prefetch-size field; a
+ message will only be sent in advance if both prefetch windows
+ (and those at the channel and connection level) allow it.
+ The prefetch-count is ignored if the no-ack option is set.
+ </doc>
+ <doc name = "rule">
+ The server MAY send less data in advance than allowed by the
+ client's specified prefetch windows but it MUST NOT send more.
+ </doc>
+ </field>
+
+ <field name = "global" type = "bit">
+ apply to entire connection
+ <doc>
+ By default the QoS settings apply to the current channel only. If
+ this field is set, they are applied to the entire connection.
+ </doc>
+ </field>
+</method>
+
+<method name = "qos-ok" synchronous = "1" index = "11">
+ confirm the requested qos
+ <doc>
+ This method tells the client that the requested QoS levels could
+ be handled by the server. The requested QoS applies to all active
+ consumers until a new QoS is defined.
+ </doc>
+ <chassis name = "client" implement = "MUST" />
+</method>
+
+<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+<method name = "consume" synchronous = "1" index = "20">
+ start a queue consumer
+ <doc>
+ This method asks the server to start a "consumer", which is a
+ transient request for messages from a specific queue. Consumers
+ last as long as the channel they were created on, or until the
+ client cancels them.
+ </doc>
+ <doc name = "rule">
+ The server SHOULD support at least 16 consumers per queue, unless
+ the queue was declared as private, and ideally, impose no limit
+ except as defined by available resources.
+ </doc>
+ <chassis name = "server" implement = "MUST" />
+ <response name = "consume-ok" />
+
+ <field name = "ticket" domain = "access ticket">
+ <doc name = "rule">
+ The client MUST provide a valid access ticket giving "read" access
+ rights to the realm for the queue.
+ </doc>
+ </field>
+
+ <field name = "queue" domain = "queue name">
+ <doc>
+ Specifies the name of the queue to consume from. If the queue name
+ is null, refers to the current queue for the channel, which is the
+ last declared queue.
+ </doc>
+ <doc name = "rule">
+ If the client did not previously declare a queue, and the queue name
+ in this method is empty, the server MUST raise a connection exception
+ with reply code 530 (not allowed).
+ </doc>
+ </field>
+
+ <field name = "consumer tag" domain = "consumer tag">
+ <doc>
+ Specifies the identifier for the consumer. The consumer tag is
+ local to a connection, so two clients can use the same consumer
+ tags. If this field is empty the server will generate a unique
+ tag.
+ </doc>
+ <doc name = "rule" test = "todo">
+ The tag MUST NOT refer to an existing consumer. If the client
+ attempts to create two consumers with the same non-empty tag
+ the server MUST raise a connection exception with reply code
+ 530 (not allowed).
+ </doc>
+ </field>
+
+ <field name = "no local" domain = "no local" />
+
+ <field name = "no ack" domain = "no ack" />
+
+ <field name = "exclusive" type = "bit">
+ request exclusive access
+ <doc>
+ Request exclusive consumer access, meaning only this consumer can
+ access the queue.
+ </doc>
+ <doc name = "rule" test = "amq_file_00">
+ If the server cannot grant exclusive access to the queue when asked,
+ - because there are other consumers active - it MUST raise a channel
+ exception with return code 405 (resource locked).
+ </doc>
+ </field>
+
+ <field name = "nowait" type = "bit">
+ do not send a reply method
+ <doc>
+ If set, the server will not respond to the method. The client should
+ not wait for a reply method. If the server could not complete the
+ method it will raise a channel or connection exception.
+ </doc>
+ </field>
+</method>
+
+<method name = "consume-ok" synchronous = "1" index = "21">
+ confirm a new consumer
+ <doc>
+ This method provides the client with a consumer tag which it MUST
+ use in methods that work with the consumer.
+ </doc>
+ <chassis name = "client" implement = "MUST" />
+
+ <field name = "consumer tag" domain = "consumer tag">
+ <doc>
+ Holds the consumer tag specified by the client or provided by
+ the server.
+ </doc>
+ </field>
+</method>
+
+
+<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+<method name = "cancel" synchronous = "1" index = "30">
+ end a queue consumer
+ <doc>
+ This method cancels a consumer. This does not affect already
+ delivered messages, but it does mean the server will not send any
+ more messages for that consumer.
+ </doc>
+ <chassis name = "server" implement = "MUST" />
+ <response name = "cancel-ok" />
+
+ <field name = "consumer tag" domain = "consumer tag" />
+
+ <field name = "nowait" type = "bit">
+ do not send a reply method
+ <doc>
+ If set, the server will not respond to the method. The client should
+ not wait for a reply method. If the server could not complete the
+ method it will raise a channel or connection exception.
+ </doc>
+ </field>
+</method>
+
+<method name = "cancel-ok" synchronous = "1" index = "31">
+ confirm a cancelled consumer
+ <doc>
+ This method confirms that the cancellation was completed.
+ </doc>
+ <chassis name = "client" implement = "MUST" />
+
+ <field name = "consumer tag" domain = "consumer tag" />
+</method>
+
+
+<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+<method name = "open" synchronous = "1" index = "40">
+ request to start staging
+ <doc>
+ This method requests permission to start staging a message. Staging
+ means sending the message into a temporary area at the recipient end
+ and then delivering the message by referring to this temporary area.
+ Staging is how the protocol handles partial file transfers - if a
+ message is partially staged and the connection breaks, the next time
+ the sender starts to stage it, it can restart from where it left off.
+ </doc>
+ <response name = "open-ok" />
+ <chassis name = "server" implement = "MUST" />
+ <chassis name = "client" implement = "MUST" />
+
+ <field name = "identifier" type = "shortstr">
+ staging identifier
+ <doc>
+ This is the staging identifier. This is an arbitrary string chosen
+ by the sender. For staging to work correctly the sender must use
+ the same staging identifier when staging the same message a second
+ time after recovery from a failure. A good choice for the staging
+ identifier would be the SHA1 hash of the message properties data
+ (including the original filename, revised time, etc.).
+ </doc>
+ </field>
+
+ <field name = "content size" type = "longlong">
+ message content size
+ <doc>
+ The size of the content in octets. The recipient may use this
+ information to allocate or check available space in advance, to
+ avoid "disk full" errors during staging of very large messages.
+ </doc>
+ <doc name = "rule">
+ The sender MUST accurately fill the content-size field.
+ Zero-length content is permitted.
+ </doc>
+ </field>
+</method>
+
+<method name = "open-ok" synchronous = "1" index = "41">
+ confirm staging ready
+ <doc>
+ This method confirms that the recipient is ready to accept staged
+ data. If the message was already partially-staged at a previous
+ time the recipient will report the number of octets already staged.
+ </doc>
+ <response name = "stage" />
+ <chassis name = "server" implement = "MUST" />
+ <chassis name = "client" implement = "MUST" />
+
+ <field name = "staged size" type = "longlong">
+ already staged amount
+ <doc>
+ The amount of previously-staged content in octets. For a new
+ message this will be zero.
+ </doc>
+ <doc name = "rule">
+ The sender MUST start sending data from this octet offset in the
+ message, counting from zero.
+ </doc>
+ <doc name = "rule">
+ The recipient MAY decide how long to hold partially-staged content
+ and MAY implement staging by always discarding partially-staged
+ content. However if it uses the file content type it MUST support
+ the staging methods.
+ </doc>
+ </field>
+</method>
+
+<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+<method name = "stage" content = "1" index = "50">
+ stage message content
+ <doc>
+ This method stages the message, sending the message content to the
+ recipient from the octet offset specified in the Open-Ok method.
+ </doc>
+ <chassis name = "server" implement = "MUST" />
+ <chassis name = "client" implement = "MUST" />
+</method>
+
+
+<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+<method name = "publish" index = "60">
+ publish a message
+ <doc>
+ This method publishes a staged file message to a specific exchange.
+ The file message will be routed to queues as defined by the exchange
+ configuration and distributed to any active consumers when the
+ transaction, if any, is committed.
+ </doc>
+ <chassis name = "server" implement = "MUST" />
+
+ <field name = "ticket" domain = "access ticket">
+ <doc name = "rule">
+ The client MUST provide a valid access ticket giving "write"
+ access rights to the access realm for the exchange.
+ </doc>
+ </field>
+
+ <field name = "exchange" domain = "exchange name">
+ <doc>
+ Specifies the name of the exchange to publish to. The exchange
+ name can be empty, meaning the default exchange. If the exchange
+ name is specified, and that exchange does not exist, the server
+ will raise a channel exception.
+ </doc>
+ <doc name = "rule">
+ The server MUST accept a blank exchange name to mean the default
+ exchange.
+ </doc>
+ <doc name = "rule">
+ If the exchange was declared as an internal exchange, the server
+ MUST respond with a reply code 403 (access refused) and raise a
+ channel exception.
+ </doc>
+ <doc name = "rule">
+ The exchange MAY refuse file content in which case it MUST respond
+ with a reply code 540 (not implemented) and raise a channel
+ exception.
+ </doc>
+ </field>
+
+ <field name = "routing key" type = "shortstr">
+ Message routing key
+ <doc>
+ Specifies the routing key for the message. The routing key is
+ used for routing messages depending on the exchange configuration.
+ </doc>
+ </field>
+
+ <field name = "mandatory" type = "bit">
+ indicate mandatory routing
+ <doc>
+ This flag tells the server how to react if the message cannot be
+ routed to a queue. If this flag is set, the server will return an
+ unroutable message with a Return method. If this flag is zero, the
+ server silently drops the message.
+ </doc>
+ <doc name = "rule" test = "amq_file_00">
+ The server SHOULD implement the mandatory flag.
+ </doc>
+ </field>
+
+ <field name = "immediate" type = "bit">
+ request immediate delivery
+ <doc>
+ This flag tells the server how to react if the message cannot be
+ routed to a queue consumer immediately. If this flag is set, the
+ server will return an undeliverable message with a Return method.
+ If this flag is zero, the server will queue the message, but with
+ no guarantee that it will ever be consumed.
+ </doc>
+ <doc name = "rule" test = "amq_file_00">
+ The server SHOULD implement the immediate flag.
+ </doc>
+ </field>
+
+ <field name = "identifier" type = "shortstr">
+ staging identifier
+ <doc>
+ This is the staging identifier of the message to publish. The
+ message must have been staged. Note that a client can send the
+ Publish method asynchronously without waiting for staging to
+ finish.
+ </doc>
+ </field>
+</method>
+
+<method name = "return" content = "1" index = "70">
+ return a failed message
+ <doc>
+ This method returns an undeliverable message that was published
+ with the "immediate" flag set, or an unroutable message published
+ with the "mandatory" flag set. The reply code and text provide
+ information about the reason that the message was undeliverable.
+ </doc>
+ <chassis name = "client" implement = "MUST" />
+
+ <field name = "reply code" domain = "reply code" />
+ <field name = "reply text" domain = "reply text" />
+
+ <field name = "exchange" domain = "exchange name">
+ <doc>
+ Specifies the name of the exchange that the message was
+ originally published to.
+ </doc>
+ </field>
+
+ <field name = "routing key" type = "shortstr">
+ Message routing key
+ <doc>
+ Specifies the routing key name specified when the message was
+ published.
+ </doc>
+ </field>
+</method>
+
+
+<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+<method name = "deliver" index = "80">
+ notify the client of a consumer message
+ <doc>
+ This method delivers a staged file message to the client, via a
+ consumer. In the asynchronous message delivery model, the client
+ starts a consumer using the Consume method, then the server
+ responds with Deliver methods as and when messages arrive for
+ that consumer.
+ </doc>
+ <doc name = "rule">
+ The server SHOULD track the number of times a message has been
+ delivered to clients and when a message is redelivered a certain
+ number of times - e.g. 5 times - without being acknowledged, the
+ server SHOULD consider the message to be unprocessable (possibly
+ causing client applications to abort), and move the message to a
+ dead letter queue.
+ </doc>
+ <chassis name = "client" implement = "MUST" />
+
+ <field name = "consumer tag" domain = "consumer tag" />
+
+ <field name = "delivery tag" domain = "delivery tag" />
+
+ <field name = "redelivered" domain = "redelivered" />
+
+ <field name = "exchange" domain = "exchange name">
+ <doc>
+ Specifies the name of the exchange that the message was originally
+ published to.
+ </doc>
+ </field>
+
+ <field name = "routing key" type = "shortstr">
+ Message routing key
+ <doc>
+ Specifies the routing key name specified when the message was
+ published.
+ </doc>
+ </field>
+
+ <field name = "identifier" type = "shortstr">
+ staging identifier
+ <doc>
+ This is the staging identifier of the message to deliver. The
+ message must have been staged. Note that a server can send the
+ Deliver method asynchronously without waiting for staging to
+ finish.
+ </doc>
+ </field>
+</method>
+
+
+<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+<method name = "ack" index = "90">
+ acknowledge one or more messages
+ <doc>
+ This method acknowledges one or more messages delivered via the
+ Deliver method. The client can ask to confirm a single message or
+ a set of messages up to and including a specific message.
+ </doc>
+ <chassis name = "server" implement = "MUST" />
+ <field name = "delivery tag" domain = "delivery tag" />
+
+ <field name = "multiple" type = "bit">
+ acknowledge multiple messages
+ <doc>
+ If set to 1, the delivery tag is treated as "up to and including",
+ so that the client can acknowledge multiple messages with a single
+ method. If set to zero, the delivery tag refers to a single
+ message. If the multiple field is 1, and the delivery tag is zero,
+ tells the server to acknowledge all outstanding mesages.
+ </doc>
+ <doc name = "rule">
+ The server MUST validate that a non-zero delivery-tag refers to an
+ delivered message, and raise a channel exception if this is not the
+ case.
+ </doc>
+ </field>
+</method>
+
+
+<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+<method name = "reject" index = "100">
+ reject an incoming message
+ <doc>
+ This method allows a client to reject a message. It can be used to
+ return untreatable messages to their original queue. Note that file
+ content is staged before delivery, so the client will not use this
+ method to interrupt delivery of a large message.
+ </doc>
+ <doc name = "rule">
+ The server SHOULD interpret this method as meaning that the client
+ is unable to process the message at this time.
+ </doc>
+ <doc name = "rule">
+ A client MUST NOT use this method as a means of selecting messages
+ to process. A rejected message MAY be discarded or dead-lettered,
+ not necessarily passed to another client.
+ </doc>
+ <chassis name = "server" implement = "MUST" />
+
+ <field name = "delivery tag" domain = "delivery tag" />
+
+ <field name = "requeue" type = "bit">
+ requeue the message
+ <doc>
+ If this field is zero, the message will be discarded. If this bit
+ is 1, the server will attempt to requeue the message.
+ </doc>
+ <doc name = "rule">
+ The server MUST NOT deliver the message to the same client within
+ the context of the current channel. The recommended strategy is
+ to attempt to deliver the message to an alternative consumer, and
+ if that is not possible, to move the message to a dead-letter
+ queue. The server MAY use more sophisticated tracking to hold
+ the message on the queue and redeliver it to the same client at
+ a later stage.
+ </doc>
+ </field>
+</method>
+
+</class>
+
+ <class name="stream" handler="channel" index="80">
+ <!--
+======================================================
+== STREAMING
+======================================================
+-->
+ work with streaming content
+
+<doc>
+ The stream class provides methods that support multimedia streaming.
+ The stream class uses the following semantics: one message is one
+ packet of data; delivery is unacknowleged and unreliable; the consumer
+ can specify quality of service parameters that the server can try to
+ adhere to; lower-priority messages may be discarded in favour of high
+ priority messages.
+</doc>
+
+<doc name = "grammar">
+ stream = C:QOS S:QOS-OK
+ / C:CONSUME S:CONSUME-OK
+ / C:CANCEL S:CANCEL-OK
+ / C:PUBLISH content
+ / S:RETURN
+ / S:DELIVER content
+</doc>
+
+<chassis name = "server" implement = "MAY" />
+<chassis name = "client" implement = "MAY" />
+
+<doc name = "rule">
+ The server SHOULD discard stream messages on a priority basis if
+ the queue size exceeds some configured limit.
+</doc>
+<doc name = "rule">
+ The server MUST implement at least 2 priority levels for stream
+ messages, where priorities 0-4 and 5-9 are treated as two distinct
+ levels. The server MAY implement up to 10 priority levels.
+</doc>
+<doc name = "rule">
+ The server MUST implement automatic acknowledgements on stream
+ content. That is, as soon as a message is delivered to a client
+ via a Deliver method, the server must remove it from the queue.
+</doc>
+
+
+<!-- These are the properties for a Stream content -->
+
+<field name = "content type" type = "shortstr">
+ MIME content type
+</field>
+<field name = "content encoding" type = "shortstr">
+ MIME content encoding
+</field>
+<field name = "headers" type = "table">
+ Message header field table
+</field>
+<field name = "priority" type = "octet">
+ The message priority, 0 to 9
+</field>
+<field name = "timestamp" type = "timestamp">
+ The message timestamp
+</field>
+
+
+<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+<method name = "qos" synchronous = "1" index = "10">
+ specify quality of service
+ <doc>
+ This method requests a specific quality of service. The QoS can
+ be specified for the current channel or for all channels on the
+ connection. The particular properties and semantics of a qos method
+ always depend on the content class semantics. Though the qos method
+ could in principle apply to both peers, it is currently meaningful
+ only for the server.
+ </doc>
+ <chassis name = "server" implement = "MUST" />
+ <response name = "qos-ok" />
+
+ <field name = "prefetch size" type = "long">
+ prefetch window in octets
+ <doc>
+ The client can request that messages be sent in advance so that
+ when the client finishes processing a message, the following
+ message is already held locally, rather than needing to be sent
+ down the channel. Prefetching gives a performance improvement.
+ This field specifies the prefetch window size in octets. May be
+ set to zero, meaning "no specific limit". Note that other
+ prefetch limits may still apply.
+ </doc>
+ </field>
+
+ <field name = "prefetch count" type = "short">
+ prefetch window in messages
+ <doc>
+ Specifies a prefetch window in terms of whole messages. This
+ field may be used in combination with the prefetch-size field;
+ a message will only be sent in advance if both prefetch windows
+ (and those at the channel and connection level) allow it.
+ </doc>
+ </field>
+
+ <field name = "consume rate" type = "long">
+ transfer rate in octets/second
+ <doc>
+ Specifies a desired transfer rate in octets per second. This is
+ usually determined by the application that uses the streaming
+ data. A value of zero means "no limit", i.e. as rapidly as
+ possible.
+ </doc>
+ <doc name = "rule">
+ The server MAY ignore the prefetch values and consume rates,
+ depending on the type of stream and the ability of the server
+ to queue and/or reply it. The server MAY drop low-priority
+ messages in favour of high-priority messages.
+ </doc>
+ </field>
+
+ <field name = "global" type = "bit">
+ apply to entire connection
+ <doc>
+ By default the QoS settings apply to the current channel only. If
+ this field is set, they are applied to the entire connection.
+ </doc>
+ </field>
+</method>
+
+<method name = "qos-ok" synchronous = "1" index = "11">
+ confirm the requested qos
+ <doc>
+ This method tells the client that the requested QoS levels could
+ be handled by the server. The requested QoS applies to all active
+ consumers until a new QoS is defined.
+ </doc>
+ <chassis name = "client" implement = "MUST" />
+</method>
+
+<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+<method name = "consume" synchronous = "1" index = "20">
+ start a queue consumer
+ <doc>
+ This method asks the server to start a "consumer", which is a
+ transient request for messages from a specific queue. Consumers
+ last as long as the channel they were created on, or until the
+ client cancels them.
+ </doc>
+ <doc name = "rule">
+ The server SHOULD support at least 16 consumers per queue, unless
+ the queue was declared as private, and ideally, impose no limit
+ except as defined by available resources.
+ </doc>
+ <doc name = "rule">
+ Streaming applications SHOULD use different channels to select
+ different streaming resolutions. AMQP makes no provision for
+ filtering and/or transforming streams except on the basis of
+ priority-based selective delivery of individual messages.
+ </doc>
+ <chassis name = "server" implement = "MUST" />
+ <response name = "consume-ok" />
+
+ <field name = "ticket" domain = "access ticket">
+ <doc name = "rule">
+ The client MUST provide a valid access ticket giving "read" access
+ rights to the realm for the queue.
+ </doc>
+ </field>
+
+ <field name = "queue" domain = "queue name">
+ <doc>
+ Specifies the name of the queue to consume from. If the queue name
+ is null, refers to the current queue for the channel, which is the
+ last declared queue.
+ </doc>
+ <doc name = "rule">
+ If the client did not previously declare a queue, and the queue name
+ in this method is empty, the server MUST raise a connection exception
+ with reply code 530 (not allowed).
+ </doc>
+ </field>
+
+ <field name = "consumer tag" domain = "consumer tag">
+ <doc>
+ Specifies the identifier for the consumer. The consumer tag is
+ local to a connection, so two clients can use the same consumer
+ tags. If this field is empty the server will generate a unique
+ tag.
+ </doc>
+ <doc name = "rule" test = "todo">
+ The tag MUST NOT refer to an existing consumer. If the client
+ attempts to create two consumers with the same non-empty tag
+ the server MUST raise a connection exception with reply code
+ 530 (not allowed).
+ </doc>
+ </field>
+
+ <field name = "no local" domain = "no local" />
+
+ <field name = "exclusive" type = "bit">
+ request exclusive access
+ <doc>
+ Request exclusive consumer access, meaning only this consumer can
+ access the queue.
+ </doc>
+ <doc name = "rule" test = "amq_file_00">
+ If the server cannot grant exclusive access to the queue when asked,
+ - because there are other consumers active - it MUST raise a channel
+ exception with return code 405 (resource locked).
+ </doc>
+ </field>
+
+ <field name = "nowait" type = "bit">
+ do not send a reply method
+ <doc>
+ If set, the server will not respond to the method. The client should
+ not wait for a reply method. If the server could not complete the
+ method it will raise a channel or connection exception.
+ </doc>
+ </field>
+</method>
+
+
+<method name = "consume-ok" synchronous = "1" index = "21">
+ confirm a new consumer
+ <doc>
+ This method provides the client with a consumer tag which it may
+ use in methods that work with the consumer.
+ </doc>
+ <chassis name = "client" implement = "MUST" />
+
+ <field name = "consumer tag" domain = "consumer tag">
+ <doc>
+ Holds the consumer tag specified by the client or provided by
+ the server.
+ </doc>
+ </field>
+</method>
+
+<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+<method name = "cancel" synchronous = "1" index = "30">
+ end a queue consumer
+ <doc>
+ This method cancels a consumer. Since message delivery is
+ asynchronous the client may continue to receive messages for
+ a short while after canceling a consumer. It may process or
+ discard these as appropriate.
+ </doc>
+ <chassis name = "server" implement = "MUST" />
+ <response name = "cancel-ok" />
+
+ <field name = "consumer tag" domain = "consumer tag" />
+
+ <field name = "nowait" type = "bit">
+ do not send a reply method
+ <doc>
+ If set, the server will not respond to the method. The client should
+ not wait for a reply method. If the server could not complete the
+ method it will raise a channel or connection exception.
+ </doc>
+ </field>
+</method>
+
+<method name = "cancel-ok" synchronous = "1" index = "31">
+ confirm a cancelled consumer
+ <doc>
+ This method confirms that the cancellation was completed.
+ </doc>
+ <chassis name = "client" implement = "MUST" />
+
+ <field name = "consumer tag" domain = "consumer tag" />
+</method>
+
+
+<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+<method name = "publish" content = "1" index = "40">
+ publish a message
+ <doc>
+ This method publishes a message to a specific exchange. The message
+ will be routed to queues as defined by the exchange configuration
+ and distributed to any active consumers as appropriate.
+ </doc>
+ <chassis name = "server" implement = "MUST" />
+
+ <field name = "ticket" domain = "access ticket">
+ <doc name = "rule">
+ The client MUST provide a valid access ticket giving "write"
+ access rights to the access realm for the exchange.
+ </doc>
+ </field>
+
+ <field name = "exchange" domain = "exchange name">
+ <doc>
+ Specifies the name of the exchange to publish to. The exchange
+ name can be empty, meaning the default exchange. If the exchange
+ name is specified, and that exchange does not exist, the server
+ will raise a channel exception.
+ </doc>
+ <doc name = "rule">
+ The server MUST accept a blank exchange name to mean the default
+ exchange.
+ </doc>
+ <doc name = "rule">
+ If the exchange was declared as an internal exchange, the server
+ MUST respond with a reply code 403 (access refused) and raise a
+ channel exception.
+ </doc>
+ <doc name = "rule">
+ The exchange MAY refuse stream content in which case it MUST
+ respond with a reply code 540 (not implemented) and raise a
+ channel exception.
+ </doc>
+ </field>
+
+ <field name = "routing key" type = "shortstr">
+ Message routing key
+ <doc>
+ Specifies the routing key for the message. The routing key is
+ used for routing messages depending on the exchange configuration.
+ </doc>
+ </field>
+
+ <field name = "mandatory" type = "bit">
+ indicate mandatory routing
+ <doc>
+ This flag tells the server how to react if the message cannot be
+ routed to a queue. If this flag is set, the server will return an
+ unroutable message with a Return method. If this flag is zero, the
+ server silently drops the message.
+ </doc>
+ <doc name = "rule" test = "amq_stream_00">
+ The server SHOULD implement the mandatory flag.
+ </doc>
+ </field>
+
+ <field name = "immediate" type = "bit">
+ request immediate delivery
+ <doc>
+ This flag tells the server how to react if the message cannot be
+ routed to a queue consumer immediately. If this flag is set, the
+ server will return an undeliverable message with a Return method.
+ If this flag is zero, the server will queue the message, but with
+ no guarantee that it will ever be consumed.
+ </doc>
+ <doc name = "rule" test = "amq_stream_00">
+ The server SHOULD implement the immediate flag.
+ </doc>
+ </field>
+</method>
+
+<method name = "return" content = "1" index = "50">
+ return a failed message
+ <doc>
+ This method returns an undeliverable message that was published
+ with the "immediate" flag set, or an unroutable message published
+ with the "mandatory" flag set. The reply code and text provide
+ information about the reason that the message was undeliverable.
+ </doc>
+ <chassis name = "client" implement = "MUST" />
+
+ <field name = "reply code" domain = "reply code" />
+ <field name = "reply text" domain = "reply text" />
+
+ <field name = "exchange" domain = "exchange name">
+ <doc>
+ Specifies the name of the exchange that the message was
+ originally published to.
+ </doc>
+ </field>
+
+ <field name = "routing key" type = "shortstr">
+ Message routing key
+ <doc>
+ Specifies the routing key name specified when the message was
+ published.
+ </doc>
+ </field>
+</method>
+
+
+<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+<method name = "deliver" content = "1" index = "60">
+ notify the client of a consumer message
+ <doc>
+ This method delivers a message to the client, via a consumer. In
+ the asynchronous message delivery model, the client starts a
+ consumer using the Consume method, then the server responds with
+ Deliver methods as and when messages arrive for that consumer.
+ </doc>
+ <chassis name = "client" implement = "MUST" />
+
+ <field name = "consumer tag" domain = "consumer tag" />
+
+ <field name = "delivery tag" domain = "delivery tag" />
+
+ <field name = "exchange" domain = "exchange name">
+ <doc>
+ Specifies the name of the exchange that the message was originally
+ published to.
+ </doc>
+ </field>
+
+ <field name = "queue" domain = "queue name">
+ <doc>
+ Specifies the name of the queue that the message came from. Note
+ that a single channel can start many consumers on different
+ queues.
+ </doc>
+ <assert check = "notnull" />
+ </field>
+</method>
+ </class>
+
+ <class name="tx" handler="channel" index="90">
+ <!--
+======================================================
+== TRANSACTIONS
+======================================================
+-->
+ work with standard transactions
+
+<doc>
+ Standard transactions provide so-called "1.5 phase commit". We can
+ ensure that work is never lost, but there is a chance of confirmations
+ being lost, so that messages may be resent. Applications that use
+ standard transactions must be able to detect and ignore duplicate
+ messages.
+</doc>
+ <rule implement="SHOULD">
+ An client using standard transactions SHOULD be able to track all
+ messages received within a reasonable period, and thus detect and
+ reject duplicates of the same message. It SHOULD NOT pass these to
+ the application layer.
+</rule>
+ <doc name="grammar">
+ tx = C:SELECT S:SELECT-OK
+ / C:COMMIT S:COMMIT-OK
+ / C:ROLLBACK S:ROLLBACK-OK
+</doc>
+ <chassis name="server" implement="SHOULD"/>
+ <chassis name="client" implement="MAY"/>
+ <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+ <method name="select" synchronous="1" index="10">
+select standard transaction mode
+ <doc>
+ This method sets the channel to use standard transactions. The
+ client must use this method at least once on a channel before
+ using the Commit or Rollback methods.
+ </doc>
+ <chassis name="server" implement="MUST"/>
+ <response name="select-ok"/>
+ </method>
+ <method name="select-ok" synchronous="1" index="11">
+confirm transaction mode
+ <doc>
+ This method confirms to the client that the channel was successfully
+ set to use standard transactions.
+ </doc>
+ <chassis name="client" implement="MUST"/>
+ </method>
+ <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+ <method name="commit" synchronous="1" index="20">
+commit the current transaction
+ <doc>
+ This method commits all messages published and acknowledged in
+ the current transaction. A new transaction starts immediately
+ after a commit.
+ </doc>
+ <chassis name="server" implement="MUST"/>
+ <response name="commit-ok"/>
+ </method>
+ <method name="commit-ok" synchronous="1" index="21">
+confirm a successful commit
+ <doc>
+ This method confirms to the client that the commit succeeded.
+ Note that if a commit fails, the server raises a channel exception.
+ </doc>
+ <chassis name="client" implement="MUST"/>
+ </method>
+ <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+ <method name="rollback" synchronous="1" index="30">
+abandon the current transaction
+ <doc>
+ This method abandons all messages published and acknowledged in
+ the current transaction. A new transaction starts immediately
+ after a rollback.
+ </doc>
+ <chassis name="server" implement="MUST"/>
+ <response name="rollback-ok"/>
+ </method>
+ <method name="rollback-ok" synchronous="1" index="31">
+confirm a successful rollback
+ <doc>
+ This method confirms to the client that the rollback succeeded.
+ Note that if an rollback fails, the server raises a channel exception.
+ </doc>
+ <chassis name="client" implement="MUST"/>
+ </method>
+ </class>
+ <class name="dtx" handler="channel" index="100">
+ <!--
+======================================================
+== DISTRIBUTED TRANSACTIONS
+======================================================
+-->
+ work with distributed transactions
+
+<doc>
+ Distributed transactions provide so-called "2-phase commit". The
+ AMQP distributed transaction model supports the X-Open XA
+ architecture and other distributed transaction implementations.
+ The Dtx class assumes that the server has a private communications
+ channel (not AMQP) to a distributed transaction coordinator.
+</doc>
+ <doc name="grammar">
+ dtx = C:SELECT S:SELECT-OK
+ C:START S:START-OK
+</doc>
+ <chassis name="server" implement="MAY"/>
+ <chassis name="client" implement="MAY"/>
+ <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+ <method name="select" synchronous="1" index="10">
+select standard transaction mode
+ <doc>
+ This method sets the channel to use distributed transactions. The
+ client must use this method at least once on a channel before
+ using the Start method.
+ </doc>
+ <chassis name="server" implement="MUST"/>
+ <response name="select-ok"/>
+ </method>
+ <method name="select-ok" synchronous="1" index="11">
+confirm transaction mode
+ <doc>
+ This method confirms to the client that the channel was successfully
+ set to use distributed transactions.
+ </doc>
+ <chassis name="client" implement="MUST"/>
+ </method>
+ <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+ <method name="start" synchronous="1" index="20">
+ start a new distributed transaction
+ <doc>
+ This method starts a new distributed transaction. This must be
+ the first method on a new channel that uses the distributed
+ transaction mode, before any methods that publish or consume
+ messages.
+ </doc>
+ <chassis name="server" implement="MAY"/>
+ <response name="start-ok"/>
+ <field name="dtx identifier" type="shortstr">
+ transaction identifier
+ <doc>
+ The distributed transaction key. This identifies the transaction
+ so that the AMQP server can coordinate with the distributed
+ transaction coordinator.
+ </doc>
+ <assert check="notnull"/>
+ </field>
+ </method>
+ <method name="start-ok" synchronous="1" index="21">
+ confirm the start of a new distributed transaction
+ <doc>
+ This method confirms to the client that the transaction started.
+ Note that if a start fails, the server raises a channel exception.
+ </doc>
+ <chassis name="client" implement="MUST"/>
+ </method>
+ </class>
+ <class name="tunnel" handler="tunnel" index="110">
+ <!--
+======================================================
+== TUNNEL
+======================================================
+-->
+ methods for protocol tunneling.
+
+<doc>
+ The tunnel methods are used to send blocks of binary data - which
+ can be serialised AMQP methods or other protocol frames - between
+ AMQP peers.
+</doc>
+ <doc name="grammar">
+ tunnel = C:REQUEST
+ / S:REQUEST
+</doc>
+ <chassis name="server" implement="MAY"/>
+ <chassis name="client" implement="MAY"/>
+ <field name="headers" type="table">
+ Message header field table
+</field>
+ <field name="proxy name" type="shortstr">
+ The identity of the tunnelling proxy
+</field>
+ <field name="data name" type="shortstr">
+ The name or type of the message being tunnelled
+</field>
+ <field name="durable" type="octet">
+ The message durability indicator
+</field>
+ <field name="broadcast" type="octet">
+ The message broadcast mode
+</field>
+ <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+ <method name="request" content="1" index="10">
+ sends a tunnelled method
+ <doc>
+ This method tunnels a block of binary data, which can be an
+ encoded AMQP method or other data. The binary data is sent
+ as the content for the Tunnel.Request method.
+ </doc>
+ <chassis name="server" implement="MUST"/>
+ <field name="meta data" type="table">
+ meta data for the tunnelled block
+ <doc>
+ This field table holds arbitrary meta-data that the sender needs
+ to pass to the recipient.
+ </doc>
+ </field>
+ </method>
+ </class>
+ <class name="test" handler="channel" index="120">
+ <!--
+======================================================
+== TEST - CHECK FUNCTIONAL CAPABILITIES OF AN IMPLEMENTATION
+======================================================
+-->
+ test functional primitives of the implementation
+
+<doc>
+ The test class provides methods for a peer to test the basic
+ operational correctness of another peer. The test methods are
+ intended to ensure that all peers respect at least the basic
+ elements of the protocol, such as frame and content organisation
+ and field types. We assume that a specially-designed peer, a
+ "monitor client" would perform such tests.
+</doc>
+ <doc name="grammar">
+ test = C:INTEGER S:INTEGER-OK
+ / S:INTEGER C:INTEGER-OK
+ / C:STRING S:STRING-OK
+ / S:STRING C:STRING-OK
+ / C:TABLE S:TABLE-OK
+ / S:TABLE C:TABLE-OK
+ / C:CONTENT S:CONTENT-OK
+ / S:CONTENT C:CONTENT-OK
+</doc>
+ <chassis name="server" implement="MUST"/>
+ <chassis name="client" implement="SHOULD"/>
+ <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+ <method name="integer" synchronous="1" index="10">
+ test integer handling
+ <doc>
+ This method tests the peer's capability to correctly marshal integer
+ data.
+ </doc>
+ <chassis name="client" implement="MUST"/>
+ <chassis name="server" implement="MUST"/>
+ <response name="integer-ok"/>
+ <field name="integer 1" type="octet">
+ octet test value
+ <doc>
+ An octet integer test value.
+ </doc>
+ </field>
+ <field name="integer 2" type="short">
+ short test value
+ <doc>
+ A short integer test value.
+ </doc>
+ </field>
+ <field name="integer 3" type="long">
+ long test value
+ <doc>
+ A long integer test value.
+ </doc>
+ </field>
+ <field name="integer 4" type="longlong">
+ long-long test value
+ <doc>
+ A long long integer test value.
+ </doc>
+ </field>
+ <field name="operation" type="octet">
+ operation to test
+ <doc>
+ The client must execute this operation on the provided integer
+ test fields and return the result.
+ </doc>
+ <assert check="enum">
+ <value name="add">return sum of test values</value>
+ <value name="min">return lowest of test values</value>
+ <value name="max">return highest of test values</value>
+ </assert>
+ </field>
+ </method>
+ <method name="integer-ok" synchronous="1" index="11">
+ report integer test result
+ <doc>
+ This method reports the result of an Integer method.
+ </doc>
+ <chassis name="client" implement="MUST"/>
+ <chassis name="server" implement="MUST"/>
+ <field name="result" type="longlong">
+ result value
+ <doc>
+ The result of the tested operation.
+ </doc>
+ </field>
+ </method>
+ <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+ <method name="string" synchronous="1" index="20">
+ test string handling
+ <doc>
+ This method tests the peer's capability to correctly marshal string
+ data.
+ </doc>
+ <chassis name="client" implement="MUST"/>
+ <chassis name="server" implement="MUST"/>
+ <response name="string-ok"/>
+ <field name="string 1" type="shortstr">
+ short string test value
+ <doc>
+ An short string test value.
+ </doc>
+ </field>
+ <field name="string 2" type="longstr">
+ long string test value
+ <doc>
+ A long string test value.
+ </doc>
+ </field>
+ <field name="operation" type="octet">
+ operation to test
+ <doc>
+ The client must execute this operation on the provided string
+ test fields and return the result.
+ </doc>
+ <assert check="enum">
+ <value name="add">return concatentation of test strings</value>
+ <value name="min">return shortest of test strings</value>
+ <value name="max">return longest of test strings</value>
+ </assert>
+ </field>
+ </method>
+ <method name="string-ok" synchronous="1" index="21">
+ report string test result
+ <doc>
+ This method reports the result of a String method.
+ </doc>
+ <chassis name="client" implement="MUST"/>
+ <chassis name="server" implement="MUST"/>
+ <field name="result" type="longstr">
+ result value
+ <doc>
+ The result of the tested operation.
+ </doc>
+ </field>
+ </method>
+ <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+ <method name="table" synchronous="1" index="30">
+ test field table handling
+ <doc>
+ This method tests the peer's capability to correctly marshal field
+ table data.
+ </doc>
+ <chassis name="client" implement="MUST"/>
+ <chassis name="server" implement="MUST"/>
+ <response name="table-ok"/>
+ <field name="table" type="table">
+ field table of test values
+ <doc>
+ A field table of test values.
+ </doc>
+ </field>
+ <field name="integer op" type="octet">
+ operation to test on integers
+ <doc>
+ The client must execute this operation on the provided field
+ table integer values and return the result.
+ </doc>
+ <assert check="enum">
+ <value name="add">return sum of numeric field values</value>
+ <value name="min">return min of numeric field values</value>
+ <value name="max">return max of numeric field values</value>
+ </assert>
+ </field>
+ <field name="string op" type="octet">
+ operation to test on strings
+ <doc>
+ The client must execute this operation on the provided field
+ table string values and return the result.
+ </doc>
+ <assert check="enum">
+ <value name="add">return concatenation of string field values</value>
+ <value name="min">return shortest of string field values</value>
+ <value name="max">return longest of string field values</value>
+ </assert>
+ </field>
+ </method>
+ <method name="table-ok" synchronous="1" index="31">
+ report table test result
+ <doc>
+ This method reports the result of a Table method.
+ </doc>
+ <chassis name="client" implement="MUST"/>
+ <chassis name="server" implement="MUST"/>
+ <field name="integer result" type="longlong">
+ integer result value
+ <doc>
+ The result of the tested integer operation.
+ </doc>
+ </field>
+ <field name="string result" type="longstr">
+ string result value
+ <doc>
+ The result of the tested string operation.
+ </doc>
+ </field>
+ </method>
+ <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+ <method name="content" synchronous="1" content="1" index="40">
+ test content handling
+ <doc>
+ This method tests the peer's capability to correctly marshal content.
+ </doc>
+ <chassis name="client" implement="MUST"/>
+ <chassis name="server" implement="MUST"/>
+ <response name="content-ok"/>
+ </method>
+ <method name="content-ok" synchronous="1" content="1" index="41">
+ report content test result
+ <doc>
+ This method reports the result of a Content method. It contains the
+ content checksum and echoes the original content as provided.
+ </doc>
+ <chassis name="client" implement="MUST"/>
+ <chassis name="server" implement="MUST"/>
+ <field name="content checksum" type="long">
+ content hash
+ <doc>
+ The 32-bit checksum of the content, calculated by adding the
+ content into a 32-bit accumulator.
+ </doc>
+ </field>
+ </method>
+ </class>
+</amqp>
diff --git a/qpid/dotnet/Qpid.Common/build.xml b/qpid/dotnet/Qpid.Common/build.xml
new file mode 100644
index 0000000000..96dd877722
--- /dev/null
+++ b/qpid/dotnet/Qpid.Common/build.xml
@@ -0,0 +1,95 @@
+<!--
+
+ 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.
+
+-->
+
+
+<!--
+ This sole purpose of this build script is to generate the framing layer for the .net client from the AMQ spec.
+ -->
+<project name="AMQ Dot Net Framing Layer" default="generate">
+
+ <property name="amq.home" value="../.."/>
+
+ <property name="stylesheet" value="stylesheets/framing.xsl"/>
+ <property name="registry_stylesheet" value="stylesheets/registry.xsl"/>
+ <property name="registry_template" value="resources/registry.template"/>
+ <property name="saxon.jar" value="lib/saxon/saxon8.jar"/>
+ <property name="generated.src" value="generated"/>
+ <property name="static.src" value="src"/>
+ <property name="resources" value="resources"/>
+ <property name="base.lib" value="lib"/>
+
+ <path id="amq.home.path">
+ <pathelement location="${amq.home}"/>
+ </path>
+
+ <pathconvert targetos="unix" property="amq.home.fixed" refid="amq.home.path"/>
+
+<!-- Some spec changes break the build, reverting to private copy in Qpid.Common temporarily till this is fixed. -->
+ <property name="amq.asl" value="${amq.home.fixed}/specs/amqp.0-8.xml"/>
+
+ <target name="clean" description="Deletes the generated sources.">
+ <delete>
+ <fileset dir="${generated.src}" includes="**/*"/>
+ </delete>
+ </target>
+
+ <!--
+ Checks if the generation step needs to be performed. It will be skipped if the sources are up to date with the spec and provided that the
+ force flag has not been set.
+ -->
+ <target name="check-generate"
+ description="Checks if the generated sources are up-to-date. Use -Dforce=true or the 'forcegen' target to force generation.">
+
+ <condition property="generateNotRequired">
+ <and>
+ <uptodate targetfile="${generated.src}/results.out" srcfile="${amq.asl}"/>
+ <not><isset property="force"/></not>
+ </and>
+ </condition>
+ </target>
+
+ <!-- Applies a transformation to the AMQP spec to generate the framing layer. -->
+ <target name="generate" depends="check-generate" unless="generateNotRequired" description="generates code">
+
+ <mkdir dir="${generated.src}"/>
+
+ <java jar="${saxon.jar}" fork="true">
+ <arg value="-o"/>
+ <arg value="${generated.src}/results.out"/>
+ <arg value="${amq.asl}"/>
+ <arg value="${stylesheet}"/>
+ <arg value="asl_base=${asl.base}"/>
+ <arg value="registry_name=MainRegistry"/>
+ </java>
+
+ <java jar="${saxon.jar}" fork="true">
+ <arg value="-o"/>
+ <arg value="${generated.src}/registry.out"/>
+ <arg value="${registry_template}"/>
+ <arg value="${registry_stylesheet}"/>
+ </java>
+ </target>
+
+ <!-- Does a clean and forces re-generation of the sources. -->
+ <target name="forcegen" depends="clean, generate" description="Forces clean re-generation of the code.">
+ </target>
+
+</project>
diff --git a/qpid/dotnet/Qpid.Common/default.build b/qpid/dotnet/Qpid.Common/default.build
new file mode 100644
index 0000000000..df07397d0b
--- /dev/null
+++ b/qpid/dotnet/Qpid.Common/default.build
@@ -0,0 +1,49 @@
+<?xml version="1.0"?>
+<!--
+
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+
+-->
+
+<project name="Apache.Qpid.Common" default="build">
+ <!--
+ Properties that come from master build file
+ - build.dir: root directory for build
+ - build.debug: true if building debug release
+ - build.defines: variables to define during build
+ -->
+
+ <target name="build">
+ <csc target="library"
+ define="${build.defines}"
+ debug="${build.debug}"
+ output="${build.dir}/${project::get-name()}.dll">
+
+ <sources>
+ <include name="**/*.cs" />
+ </sources>
+ <references>
+ <include name="${build.dir}/log4net.dll" />
+ <include name="${build.dir}/Apache.Qpid.Buffer.dll" />
+ <include name="${build.dir}/Apache.Qpid.Messaging.dll" />
+ <include name="${build.dir}/Apache.Qpid.Codec.dll" />
+ </references>
+ </csc>
+ </target>
+</project>
+
diff --git a/qpid/dotnet/Qpid.Common/lib/log4net/log4net-licence.txt b/qpid/dotnet/Qpid.Common/lib/log4net/log4net-licence.txt
new file mode 100644
index 0000000000..261eeb9e9f
--- /dev/null
+++ b/qpid/dotnet/Qpid.Common/lib/log4net/log4net-licence.txt
@@ -0,0 +1,201 @@
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
diff --git a/qpid/dotnet/Qpid.Common/lib/log4net/log4net.dll b/qpid/dotnet/Qpid.Common/lib/log4net/log4net.dll
new file mode 100644
index 0000000000..995816f27b
--- /dev/null
+++ b/qpid/dotnet/Qpid.Common/lib/log4net/log4net.dll
Binary files differ
diff --git a/qpid/dotnet/Qpid.Common/lib/log4net/log4net.xml b/qpid/dotnet/Qpid.Common/lib/log4net/log4net.xml
new file mode 100644
index 0000000000..5beb669ab0
--- /dev/null
+++ b/qpid/dotnet/Qpid.Common/lib/log4net/log4net.xml
@@ -0,0 +1,28676 @@
+<?xml version="1.0"?>
+<!--
+
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+
+-->
+
+<doc>
+ <assembly>
+ <name>log4net</name>
+ </assembly>
+ <members>
+ <member name="T:log4net.Appender.AdoNetAppender">
+ <summary>
+ Appender that logs to a database.
+ </summary>
+ <remarks>
+ <para>
+ <see cref="T:log4net.Appender.AdoNetAppender"/> appends logging events to a table within a
+ database. The appender can be configured to specify the connection
+ string by setting the <see cref="P:log4net.Appender.AdoNetAppender.ConnectionString"/> property.
+ The connection type (provider) can be specified by setting the <see cref="P:log4net.Appender.AdoNetAppender.ConnectionType"/>
+ property. For more information on database connection strings for
+ your specific database see <a href="http://www.connectionstrings.com/">http://www.connectionstrings.com/</a>.
+ </para>
+ <para>
+ Records are written into the database either using a prepared
+ statement or a stored procedure. The <see cref="P:log4net.Appender.AdoNetAppender.CommandType"/> property
+ is set to <see cref="F:System.Data.CommandType.Text"/> (<c>System.Data.CommandType.Text</c>) to specify a prepared statement
+ or to <see cref="F:System.Data.CommandType.StoredProcedure"/> (<c>System.Data.CommandType.StoredProcedure</c>) to specify a stored
+ procedure.
+ </para>
+ <para>
+ The prepared statement text or the name of the stored procedure
+ must be set in the <see cref="P:log4net.Appender.AdoNetAppender.CommandText"/> property.
+ </para>
+ <para>
+ The prepared statement or stored procedure can take a number
+ of parameters. Parameters are added using the <see cref="M:log4net.Appender.AdoNetAppender.AddParameter(log4net.Appender.AdoNetAppenderParameter)"/>
+ method. This adds a single <see cref="T:log4net.Appender.AdoNetAppenderParameter"/> to the
+ ordered list of parameters. The <see cref="T:log4net.Appender.AdoNetAppenderParameter"/>
+ type may be subclassed if required to provide database specific
+ functionality. The <see cref="T:log4net.Appender.AdoNetAppenderParameter"/> specifies
+ the parameter name, database type, size, and how the value should
+ be generated using a <see cref="T:log4net.Layout.ILayout"/>.
+ </para>
+ </remarks>
+ <example>
+ An example of a SQL Server table that could be logged to:
+ <code lang="SQL">
+ CREATE TABLE [dbo].[Log] (
+ [ID] [int] IDENTITY (1, 1) NOT NULL ,
+ [Date] [datetime] NOT NULL ,
+ [Thread] [varchar] (255) NOT NULL ,
+ [Level] [varchar] (20) NOT NULL ,
+ [Logger] [varchar] (255) NOT NULL ,
+ [Message] [varchar] (4000) NOT NULL
+ ) ON [PRIMARY]
+ </code>
+ </example>
+ <example>
+ An example configuration to log to the above table:
+ <code lang="XML" escaped="true">
+ <appender name="AdoNetAppender_SqlServer" type="log4net.Appender.AdoNetAppender">
+ <connectionType value="System.Data.SqlClient.SqlConnection, System.Data, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>
+ <connectionString value="data source=SQLSVR;initial catalog=test_log4net;integrated security=false;persist security info=True;User ID=sa;Password=sa"/>
+ <commandText value="INSERT INTO Log ([Date],[Thread],[Level],[Logger],[Message]) VALUES (@log_date, @thread, @log_level, @logger, @message)"/>
+ <parameter>
+ <parameterName value="@log_date"/>
+ <dbType value="DateTime"/>
+ <layout type="log4net.Layout.PatternLayout" value="%date{yyyy'-'MM'-'dd HH':'mm':'ss'.'fff}"/>
+ </parameter>
+ <parameter>
+ <parameterName value="@thread"/>
+ <dbType value="String"/>
+ <size value="255"/>
+ <layout type="log4net.Layout.PatternLayout" value="%thread"/>
+ </parameter>
+ <parameter>
+ <parameterName value="@log_level"/>
+ <dbType value="String"/>
+ <size value="50"/>
+ <layout type="log4net.Layout.PatternLayout" value="%level"/>
+ </parameter>
+ <parameter>
+ <parameterName value="@logger"/>
+ <dbType value="String"/>
+ <size value="255"/>
+ <layout type="log4net.Layout.PatternLayout" value="%logger"/>
+ </parameter>
+ <parameter>
+ <parameterName value="@message"/>
+ <dbType value="String"/>
+ <size value="4000"/>
+ <layout type="log4net.Layout.PatternLayout" value="%message"/>
+ </parameter>
+ </appender>
+ </code>
+ </example>
+ <author>Julian Biddle</author>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ <author>Lance Nehring</author>
+ </member>
+ <member name="T:log4net.Appender.BufferingAppenderSkeleton">
+ <summary>
+ Abstract base class implementation of <see cref="T:log4net.Appender.IAppender"/> that
+ buffers events in a fixed size buffer.
+ </summary>
+ <remarks>
+ <para>
+ This base class should be used by appenders that need to buffer a
+ number of events before logging them. For example the <see cref="T:log4net.Appender.AdoNetAppender"/>
+ buffers events and then submits the entire contents of the buffer to
+ the underlying database in one go.
+ </para>
+ <para>
+ Subclasses should override the <see cref="M:log4net.Appender.BufferingAppenderSkeleton.SendBuffer(log4net.Core.LoggingEvent[])"/>
+ method to deliver the buffered events.
+ </para>
+ <para>The BufferingAppenderSkeleton maintains a fixed size cyclic
+ buffer of events. The size of the buffer is set using
+ the <see cref="P:log4net.Appender.BufferingAppenderSkeleton.BufferSize"/> property.
+ </para>
+ <para>A <see cref="T:log4net.Core.ITriggeringEventEvaluator"/> is used to inspect
+ each event as it arrives in the appender. If the <see cref="P:log4net.Appender.BufferingAppenderSkeleton.Evaluator"/>
+ triggers, then the current buffer is sent immediately
+ (see <see cref="M:log4net.Appender.BufferingAppenderSkeleton.SendBuffer(log4net.Core.LoggingEvent[])"/>). Otherwise the event
+ is stored in the buffer. For example, an evaluator can be used to
+ deliver the events immediately when an ERROR event arrives.
+ </para>
+ <para>
+ The buffering appender can be configured in a <see cref="P:log4net.Appender.BufferingAppenderSkeleton.Lossy"/> mode.
+ By default the appender is NOT lossy. When the buffer is full all
+ the buffered events are sent with <see cref="M:log4net.Appender.BufferingAppenderSkeleton.SendBuffer(log4net.Core.LoggingEvent[])"/>.
+ If the <see cref="P:log4net.Appender.BufferingAppenderSkeleton.Lossy"/> property is set to <c>true</c> then the
+ buffer will not be sent when it is full, and new events arriving
+ in the appender will overwrite the oldest event in the buffer.
+ In lossy mode the buffer will only be sent when the <see cref="P:log4net.Appender.BufferingAppenderSkeleton.Evaluator"/>
+ triggers. This can be useful behavior when you need to know about
+ ERROR events but not about events with a lower level, configure an
+ evaluator that will trigger when an ERROR event arrives, the whole
+ buffer will be sent which gives a history of events leading up to
+ the ERROR event.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="T:log4net.Appender.AppenderSkeleton">
+ <summary>
+ Abstract base class implementation of <see cref="T:log4net.Appender.IAppender"/>.
+ </summary>
+ <remarks>
+ <para>
+ This class provides the code for common functionality, such
+ as support for threshold filtering and support for general filters.
+ </para>
+ <para>
+ Appenders can also implement the <see cref="T:log4net.Core.IOptionHandler"/> interface. Therefore
+ they would require that the <see cref="M:log4net.Core.IOptionHandler.ActivateOptions"/> method
+ be called after the appenders properties have been configured.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="T:log4net.Appender.IAppender">
+ <summary>
+ Implement this interface for your own strategies for printing log statements.
+ </summary>
+ <remarks>
+ <para>
+ Implementors should consider extending the <see cref="T:log4net.Appender.AppenderSkeleton"/>
+ class which provides a default implementation of this interface.
+ </para>
+ <para>
+ Appenders can also implement the <see cref="T:log4net.Core.IOptionHandler"/> interface. Therefore
+ they would require that the <see cref="M:log4net.Core.IOptionHandler.ActivateOptions"/> method
+ be called after the appenders properties have been configured.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="M:log4net.Appender.IAppender.Close">
+ <summary>
+ Closes the appender and releases resources.
+ </summary>
+ <remarks>
+ <para>
+ Releases any resources allocated within the appender such as file handles,
+ network connections, etc.
+ </para>
+ <para>
+ It is a programming error to append to a closed appender.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.IAppender.DoAppend(log4net.Core.LoggingEvent)">
+ <summary>
+ Log the logging event in Appender specific way.
+ </summary>
+ <param name="loggingEvent">The event to log</param>
+ <remarks>
+ <para>
+ This method is called to log a message into this appender.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.IAppender.Name">
+ <summary>
+ Gets or sets the name of this appender.
+ </summary>
+ <value>The name of the appender.</value>
+ <remarks>
+ <para>The name uniquely identifies the appender.</para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Appender.IBulkAppender">
+ <summary>
+ Interface for appenders that support bulk logging.
+ </summary>
+ <remarks>
+ <para>
+ This interface extends the <see cref="T:log4net.Appender.IAppender"/> interface to
+ support bulk logging of <see cref="T:log4net.Core.LoggingEvent"/> objects. Appenders
+ should only implement this interface if they can bulk log efficiently.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="M:log4net.Appender.IBulkAppender.DoAppend(log4net.Core.LoggingEvent[])">
+ <summary>
+ Log the array of logging events in Appender specific way.
+ </summary>
+ <param name="loggingEvents">The events to log</param>
+ <remarks>
+ <para>
+ This method is called to log an array of events into this appender.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Core.IOptionHandler">
+ <summary>
+ Interface used to delay activate a configured object.
+ </summary>
+ <remarks>
+ <para>
+ This allows an object to defer activation of its options until all
+ options have been set. This is required for components which have
+ related options that remain ambiguous until all are set.
+ </para>
+ <para>
+ If a component implements this interface then the <see cref="M:log4net.Core.IOptionHandler.ActivateOptions"/> method
+ must be called by the container after its all the configured properties have been set
+ and before the component can be used.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="M:log4net.Core.IOptionHandler.ActivateOptions">
+ <summary>
+ Activate the options that were previously set with calls to properties.
+ </summary>
+ <remarks>
+ <para>
+ This allows an object to defer activation of its options until all
+ options have been set. This is required for components which have
+ related options that remain ambiguous until all are set.
+ </para>
+ <para>
+ If a component implements this interface then this method must be called
+ after its properties have been set before the component can be used.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Appender.AppenderSkeleton.c_renderBufferSize">
+ <summary>
+ Initial buffer size
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.AppenderSkeleton.c_renderBufferMaxCapacity">
+ <summary>
+ Maximum buffer size before it is recycled
+ </summary>
+ </member>
+ <member name="M:log4net.Appender.AppenderSkeleton.#ctor">
+ <summary>
+ Default constructor
+ </summary>
+ <remarks>
+ <para>Empty default constructor</para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.AppenderSkeleton.Finalize">
+ <summary>
+ Finalizes this appender by calling the implementation's
+ <see cref="M:log4net.Appender.AppenderSkeleton.Close"/> method.
+ </summary>
+ <remarks>
+ <para>
+ If this appender has not been closed then the <c>Finalize</c> method
+ will call <see cref="M:log4net.Appender.AppenderSkeleton.Close"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.AppenderSkeleton.ActivateOptions">
+ <summary>
+ Initialize the appender based on the options set
+ </summary>
+ <remarks>
+ <para>
+ This is part of the <see cref="T:log4net.Core.IOptionHandler"/> delayed object
+ activation scheme. The <see cref="M:log4net.Appender.AppenderSkeleton.ActivateOptions"/> method must
+ be called on this object after the configuration properties have
+ been set. Until <see cref="M:log4net.Appender.AppenderSkeleton.ActivateOptions"/> is called this
+ object is in an undefined state and must not be used.
+ </para>
+ <para>
+ If any of the configuration properties are modified then
+ <see cref="M:log4net.Appender.AppenderSkeleton.ActivateOptions"/> must be called again.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.AppenderSkeleton.Close">
+ <summary>
+ Closes the appender and release resources.
+ </summary>
+ <remarks>
+ <para>
+ Release any resources allocated within the appender such as file handles,
+ network connections, etc.
+ </para>
+ <para>
+ It is a programming error to append to a closed appender.
+ </para>
+ <para>
+ This method cannot be overridden by subclasses. This method
+ delegates the closing of the appender to the <see cref="M:log4net.Appender.AppenderSkeleton.OnClose"/>
+ method which must be overridden in the subclass.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.AppenderSkeleton.DoAppend(log4net.Core.LoggingEvent)">
+ <summary>
+ Performs threshold checks and invokes filters before
+ delegating actual logging to the subclasses specific
+ <see cref="M:log4net.Appender.AppenderSkeleton.Append(log4net.Core.LoggingEvent)"/> method.
+ </summary>
+ <param name="loggingEvent">The event to log.</param>
+ <remarks>
+ <para>
+ This method cannot be overridden by derived classes. A
+ derived class should override the <see cref="M:log4net.Appender.AppenderSkeleton.Append(log4net.Core.LoggingEvent)"/> method
+ which is called by this method.
+ </para>
+ <para>
+ The implementation of this method is as follows:
+ </para>
+ <para>
+ <list type="bullet">
+ <item>
+ <description>
+ Checks that the severity of the <paramref name="loggingEvent"/>
+ is greater than or equal to the <see cref="P:log4net.Appender.AppenderSkeleton.Threshold"/> of this
+ appender.</description>
+ </item>
+ <item>
+ <description>
+ Checks that the <see cref="T:log4net.Filter.IFilter"/> chain accepts the
+ <paramref name="loggingEvent"/>.
+ </description>
+ </item>
+ <item>
+ <description>
+ Calls <see cref="M:log4net.Appender.AppenderSkeleton.PreAppendCheck"/> and checks that
+ it returns <c>true</c>.</description>
+ </item>
+ </list>
+ </para>
+ <para>
+ If all of the above steps succeed then the <paramref name="loggingEvent"/>
+ will be passed to the abstract <see cref="M:log4net.Appender.AppenderSkeleton.Append(log4net.Core.LoggingEvent)"/> method.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.AppenderSkeleton.DoAppend(log4net.Core.LoggingEvent[])">
+ <summary>
+ Performs threshold checks and invokes filters before
+ delegating actual logging to the subclasses specific
+ <see cref="M:log4net.Appender.AppenderSkeleton.Append(log4net.Core.LoggingEvent[])"/> method.
+ </summary>
+ <param name="loggingEvents">The array of events to log.</param>
+ <remarks>
+ <para>
+ This method cannot be overridden by derived classes. A
+ derived class should override the <see cref="M:log4net.Appender.AppenderSkeleton.Append(log4net.Core.LoggingEvent[])"/> method
+ which is called by this method.
+ </para>
+ <para>
+ The implementation of this method is as follows:
+ </para>
+ <para>
+ <list type="bullet">
+ <item>
+ <description>
+ Checks that the severity of the <paramref name="loggingEvent"/>
+ is greater than or equal to the <see cref="P:log4net.Appender.AppenderSkeleton.Threshold"/> of this
+ appender.</description>
+ </item>
+ <item>
+ <description>
+ Checks that the <see cref="T:log4net.Filter.IFilter"/> chain accepts the
+ <paramref name="loggingEvent"/>.
+ </description>
+ </item>
+ <item>
+ <description>
+ Calls <see cref="M:log4net.Appender.AppenderSkeleton.PreAppendCheck"/> and checks that
+ it returns <c>true</c>.</description>
+ </item>
+ </list>
+ </para>
+ <para>
+ If all of the above steps succeed then the <paramref name="loggingEvents"/>
+ will be passed to the <see cref="M:log4net.Appender.AppenderSkeleton.Append(log4net.Core.LoggingEvent[])"/> method.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.AppenderSkeleton.FilterEvent(log4net.Core.LoggingEvent)">
+ <summary>
+ Test if the logging event should we output by this appender
+ </summary>
+ <param name="loggingEvent">the event to test</param>
+ <returns><c>true</c> if the event should be output, <c>false</c> if the event should be ignored</returns>
+ <remarks>
+ <para>
+ This method checks the logging event against the threshold level set
+ on this appender and also against the filters specified on this
+ appender.
+ </para>
+ <para>
+ The implementation of this method is as follows:
+ </para>
+ <para>
+ <list type="bullet">
+ <item>
+ <description>
+ Checks that the severity of the <paramref name="loggingEvent"/>
+ is greater than or equal to the <see cref="P:log4net.Appender.AppenderSkeleton.Threshold"/> of this
+ appender.</description>
+ </item>
+ <item>
+ <description>
+ Checks that the <see cref="T:log4net.Filter.IFilter"/> chain accepts the
+ <paramref name="loggingEvent"/>.
+ </description>
+ </item>
+ </list>
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.AppenderSkeleton.AddFilter(log4net.Filter.IFilter)">
+ <summary>
+ Adds a filter to the end of the filter chain.
+ </summary>
+ <param name="filter">the filter to add to this appender</param>
+ <remarks>
+ <para>
+ The Filters are organized in a linked list.
+ </para>
+ <para>
+ Setting this property causes the new filter to be pushed onto the
+ back of the filter chain.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.AppenderSkeleton.ClearFilters">
+ <summary>
+ Clears the filter list for this appender.
+ </summary>
+ <remarks>
+ <para>
+ Clears the filter list for this appender.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.AppenderSkeleton.IsAsSevereAsThreshold(log4net.Core.Level)">
+ <summary>
+ Checks if the message level is below this appender's threshold.
+ </summary>
+ <param name="level"><see cref="T:log4net.Core.Level"/> to test against.</param>
+ <remarks>
+ <para>
+ If there is no threshold set, then the return value is always <c>true</c>.
+ </para>
+ </remarks>
+ <returns>
+ <c>true</c> if the <paramref name="level"/> meets the <see cref="P:log4net.Appender.AppenderSkeleton.Threshold"/>
+ requirements of this appender.
+ </returns>
+ </member>
+ <member name="M:log4net.Appender.AppenderSkeleton.OnClose">
+ <summary>
+ Is called when the appender is closed. Derived classes should override
+ this method if resources need to be released.
+ </summary>
+ <remarks>
+ <para>
+ Releases any resources allocated within the appender such as file handles,
+ network connections, etc.
+ </para>
+ <para>
+ It is a programming error to append to a closed appender.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.AppenderSkeleton.Append(log4net.Core.LoggingEvent)">
+ <summary>
+ Subclasses of <see cref="T:log4net.Appender.AppenderSkeleton"/> should implement this method
+ to perform actual logging.
+ </summary>
+ <param name="loggingEvent">The event to append.</param>
+ <remarks>
+ <para>
+ A subclass must implement this method to perform
+ logging of the <paramref name="loggingEvent"/>.
+ </para>
+ <para>This method will be called by <see cref="M:log4net.Appender.AppenderSkeleton.DoAppend(log4net.Core.LoggingEvent)"/>
+ if all the conditions listed for that method are met.
+ </para>
+ <para>
+ To restrict the logging of events in the appender
+ override the <see cref="M:log4net.Appender.AppenderSkeleton.PreAppendCheck"/> method.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.AppenderSkeleton.Append(log4net.Core.LoggingEvent[])">
+ <summary>
+ Append a bulk array of logging events.
+ </summary>
+ <param name="loggingEvents">the array of logging events</param>
+ <remarks>
+ <para>
+ This base class implementation calls the <see cref="M:log4net.Appender.AppenderSkeleton.Append(log4net.Core.LoggingEvent)"/>
+ method for each element in the bulk array.
+ </para>
+ <para>
+ A sub class that can better process a bulk array of events should
+ override this method in addition to <see cref="M:log4net.Appender.AppenderSkeleton.Append(log4net.Core.LoggingEvent)"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.AppenderSkeleton.PreAppendCheck">
+ <summary>
+ Called before <see cref="M:log4net.Appender.AppenderSkeleton.Append(log4net.Core.LoggingEvent)"/> as a precondition.
+ </summary>
+ <remarks>
+ <para>
+ This method is called by <see cref="M:log4net.Appender.AppenderSkeleton.DoAppend(log4net.Core.LoggingEvent)"/>
+ before the call to the abstract <see cref="M:log4net.Appender.AppenderSkeleton.Append(log4net.Core.LoggingEvent)"/> method.
+ </para>
+ <para>
+ This method can be overridden in a subclass to extend the checks
+ made before the event is passed to the <see cref="M:log4net.Appender.AppenderSkeleton.Append(log4net.Core.LoggingEvent)"/> method.
+ </para>
+ <para>
+ A subclass should ensure that they delegate this call to
+ this base class if it is overridden.
+ </para>
+ </remarks>
+ <returns><c>true</c> if the call to <see cref="M:log4net.Appender.AppenderSkeleton.Append(log4net.Core.LoggingEvent)"/> should proceed.</returns>
+ </member>
+ <member name="M:log4net.Appender.AppenderSkeleton.RenderLoggingEvent(log4net.Core.LoggingEvent)">
+ <summary>
+ Renders the <see cref="T:log4net.Core.LoggingEvent"/> to a string.
+ </summary>
+ <param name="loggingEvent">The event to render.</param>
+ <returns>The event rendered as a string.</returns>
+ <remarks>
+ <para>
+ Helper method to render a <see cref="T:log4net.Core.LoggingEvent"/> to
+ a string. This appender must have a <see cref="P:log4net.Appender.AppenderSkeleton.Layout"/>
+ set to render the <paramref name="loggingEvent"/> to
+ a string.
+ </para>
+ <para>If there is exception data in the logging event and
+ the layout does not process the exception, this method
+ will append the exception text to the rendered string.
+ </para>
+ <para>
+ Where possible use the alternative version of this method
+ <see cref="M:log4net.Appender.AppenderSkeleton.RenderLoggingEvent(System.IO.TextWriter,log4net.Core.LoggingEvent)"/>.
+ That method streams the rendering onto an existing Writer
+ which can give better performance if the caller already has
+ a <see cref="T:System.IO.TextWriter"/> open and ready for writing.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.AppenderSkeleton.RenderLoggingEvent(System.IO.TextWriter,log4net.Core.LoggingEvent)">
+ <summary>
+ Renders the <see cref="T:log4net.Core.LoggingEvent"/> to a string.
+ </summary>
+ <param name="loggingEvent">The event to render.</param>
+ <param name="writer">The TextWriter to write the formatted event to</param>
+ <remarks>
+ <para>
+ Helper method to render a <see cref="T:log4net.Core.LoggingEvent"/> to
+ a string. This appender must have a <see cref="P:log4net.Appender.AppenderSkeleton.Layout"/>
+ set to render the <paramref name="loggingEvent"/> to
+ a string.
+ </para>
+ <para>If there is exception data in the logging event and
+ the layout does not process the exception, this method
+ will append the exception text to the rendered string.
+ </para>
+ <para>
+ Use this method in preference to <see cref="M:log4net.Appender.AppenderSkeleton.RenderLoggingEvent(log4net.Core.LoggingEvent)"/>
+ where possible. If, however, the caller needs to render the event
+ to a string then <see cref="M:log4net.Appender.AppenderSkeleton.RenderLoggingEvent(log4net.Core.LoggingEvent)"/> does
+ provide an efficient mechanism for doing so.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Appender.AppenderSkeleton.m_layout">
+ <summary>
+ The layout of this appender.
+ </summary>
+ <remarks>
+ See <see cref="P:log4net.Appender.AppenderSkeleton.Layout"/> for more information.
+ </remarks>
+ </member>
+ <member name="F:log4net.Appender.AppenderSkeleton.m_name">
+ <summary>
+ The name of this appender.
+ </summary>
+ <remarks>
+ See <see cref="P:log4net.Appender.AppenderSkeleton.Name"/> for more information.
+ </remarks>
+ </member>
+ <member name="F:log4net.Appender.AppenderSkeleton.m_threshold">
+ <summary>
+ The level threshold of this appender.
+ </summary>
+ <remarks>
+ <para>
+ There is no level threshold filtering by default.
+ </para>
+ <para>
+ See <see cref="P:log4net.Appender.AppenderSkeleton.Threshold"/> for more information.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Appender.AppenderSkeleton.m_errorHandler">
+ <summary>
+ It is assumed and enforced that errorHandler is never null.
+ </summary>
+ <remarks>
+ <para>
+ It is assumed and enforced that errorHandler is never null.
+ </para>
+ <para>
+ See <see cref="P:log4net.Appender.AppenderSkeleton.ErrorHandler"/> for more information.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Appender.AppenderSkeleton.m_headFilter">
+ <summary>
+ The first filter in the filter chain.
+ </summary>
+ <remarks>
+ <para>
+ Set to <c>null</c> initially.
+ </para>
+ <para>
+ See <see cref="T:log4net.Filter.IFilter"/> for more information.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Appender.AppenderSkeleton.m_tailFilter">
+ <summary>
+ The last filter in the filter chain.
+ </summary>
+ <remarks>
+ See <see cref="T:log4net.Filter.IFilter"/> for more information.
+ </remarks>
+ </member>
+ <member name="F:log4net.Appender.AppenderSkeleton.m_closed">
+ <summary>
+ Flag indicating if this appender is closed.
+ </summary>
+ <remarks>
+ See <see cref="M:log4net.Appender.AppenderSkeleton.Close"/> for more information.
+ </remarks>
+ </member>
+ <member name="F:log4net.Appender.AppenderSkeleton.m_recursiveGuard">
+ <summary>
+ The guard prevents an appender from repeatedly calling its own DoAppend method
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.AppenderSkeleton.m_renderWriter">
+ <summary>
+ StringWriter used to render events
+ </summary>
+ </member>
+ <member name="P:log4net.Appender.AppenderSkeleton.Threshold">
+ <summary>
+ Gets or sets the threshold <see cref="T:log4net.Core.Level"/> of this appender.
+ </summary>
+ <value>
+ The threshold <see cref="T:log4net.Core.Level"/> of the appender.
+ </value>
+ <remarks>
+ <para>
+ All log events with lower level than the threshold level are ignored
+ by the appender.
+ </para>
+ <para>
+ In configuration files this option is specified by setting the
+ value of the <see cref="P:log4net.Appender.AppenderSkeleton.Threshold"/> option to a level
+ string, such as "DEBUG", "INFO" and so on.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.AppenderSkeleton.ErrorHandler">
+ <summary>
+ Gets or sets the <see cref="T:log4net.Core.IErrorHandler"/> for this appender.
+ </summary>
+ <value>The <see cref="T:log4net.Core.IErrorHandler"/> of the appender</value>
+ <remarks>
+ <para>
+ The <see cref="T:log4net.Appender.AppenderSkeleton"/> provides a default
+ implementation for the <see cref="P:log4net.Appender.AppenderSkeleton.ErrorHandler"/> property.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.AppenderSkeleton.FilterHead">
+ <summary>
+ The filter chain.
+ </summary>
+ <value>The head of the filter chain filter chain.</value>
+ <remarks>
+ <para>
+ Returns the head Filter. The Filters are organized in a linked list
+ and so all Filters on this Appender are available through the result.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.AppenderSkeleton.Layout">
+ <summary>
+ Gets or sets the <see cref="T:log4net.Layout.ILayout"/> for this appender.
+ </summary>
+ <value>The layout of the appender.</value>
+ <remarks>
+ <para>
+ See <see cref="P:log4net.Appender.AppenderSkeleton.RequiresLayout"/> for more information.
+ </para>
+ </remarks>
+ <seealso cref="P:log4net.Appender.AppenderSkeleton.RequiresLayout"/>
+ </member>
+ <member name="P:log4net.Appender.AppenderSkeleton.Name">
+ <summary>
+ Gets or sets the name of this appender.
+ </summary>
+ <value>The name of the appender.</value>
+ <remarks>
+ <para>
+ The name uniquely identifies the appender.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.AppenderSkeleton.RequiresLayout">
+ <summary>
+ Tests if this appender requires a <see cref="P:log4net.Appender.AppenderSkeleton.Layout"/> to be set.
+ </summary>
+ <remarks>
+ <para>
+ In the rather exceptional case, where the appender
+ implementation admits a layout but can also work without it,
+ then the appender should return <c>true</c>.
+ </para>
+ <para>
+ This default implementation always returns <c>true</c>.
+ </para>
+ </remarks>
+ <returns>
+ <c>true</c> if the appender requires a layout object, otherwise <c>false</c>.
+ </returns>
+ </member>
+ <member name="F:log4net.Appender.BufferingAppenderSkeleton.DEFAULT_BUFFER_SIZE">
+ <summary>
+ The default buffer size.
+ </summary>
+ <remarks>
+ The default size of the cyclic buffer used to store events.
+ This is set to 512 by default.
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.BufferingAppenderSkeleton.#ctor">
+ <summary>
+ Initializes a new instance of the <see cref="T:log4net.Appender.BufferingAppenderSkeleton"/> class.
+ </summary>
+ <remarks>
+ <para>
+ Protected default constructor to allow subclassing.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.BufferingAppenderSkeleton.#ctor(System.Boolean)">
+ <summary>
+ Initializes a new instance of the <see cref="T:log4net.Appender.BufferingAppenderSkeleton"/> class.
+ </summary>
+ <param name="eventMustBeFixed">the events passed through this appender must be
+ fixed by the time that they arrive in the derived class' <c>SendBuffer</c> method.</param>
+ <remarks>
+ <para>
+ Protected constructor to allow subclassing.
+ </para>
+ <para>
+ The <paramref name="eventMustBeFixed"/> should be set if the subclass
+ expects the events delivered to be fixed even if the
+ <see cref="P:log4net.Appender.BufferingAppenderSkeleton.BufferSize"/> is set to zero, i.e. when no buffering occurs.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.BufferingAppenderSkeleton.Flush">
+ <summary>
+ Flush the currently buffered events
+ </summary>
+ <remarks>
+ <para>
+ Flushes any events that have been buffered.
+ </para>
+ <para>
+ If the appender is buffering in <see cref="P:log4net.Appender.BufferingAppenderSkeleton.Lossy"/> mode then the contents
+ of the buffer will NOT be flushed to the appender.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.BufferingAppenderSkeleton.Flush(System.Boolean)">
+ <summary>
+ Flush the currently buffered events
+ </summary>
+ <param name="flushLossyBuffer">set to <c>true</c> to flush the buffer of lossy events</param>
+ <remarks>
+ <para>
+ Flushes events that have been buffered. If <paramref name="flushLossyBuffer"/> is
+ <c>false</c> then events will only be flushed if this buffer is non-lossy mode.
+ </para>
+ <para>
+ If the appender is buffering in <see cref="P:log4net.Appender.BufferingAppenderSkeleton.Lossy"/> mode then the contents
+ of the buffer will only be flushed if <paramref name="flushLossyBuffer"/> is <c>true</c>.
+ In this case the contents of the buffer will be tested against the
+ <see cref="P:log4net.Appender.BufferingAppenderSkeleton.LossyEvaluator"/> and if triggering will be output. All other buffered
+ events will be discarded.
+ </para>
+ <para>
+ If <paramref name="flushLossyBuffer"/> is <c>true</c> then the buffer will always
+ be emptied by calling this method.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.BufferingAppenderSkeleton.ActivateOptions">
+ <summary>
+ Initialize the appender based on the options set
+ </summary>
+ <remarks>
+ <para>
+ This is part of the <see cref="T:log4net.Core.IOptionHandler"/> delayed object
+ activation scheme. The <see cref="M:log4net.Appender.BufferingAppenderSkeleton.ActivateOptions"/> method must
+ be called on this object after the configuration properties have
+ been set. Until <see cref="M:log4net.Appender.BufferingAppenderSkeleton.ActivateOptions"/> is called this
+ object is in an undefined state and must not be used.
+ </para>
+ <para>
+ If any of the configuration properties are modified then
+ <see cref="M:log4net.Appender.BufferingAppenderSkeleton.ActivateOptions"/> must be called again.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.BufferingAppenderSkeleton.OnClose">
+ <summary>
+ Close this appender instance.
+ </summary>
+ <remarks>
+ <para>
+ Close this appender instance. If this appender is marked
+ as not <see cref="P:log4net.Appender.BufferingAppenderSkeleton.Lossy"/> then the remaining events in
+ the buffer must be sent when the appender is closed.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.BufferingAppenderSkeleton.Append(log4net.Core.LoggingEvent)">
+ <summary>
+ This method is called by the <see cref="M:log4net.Appender.AppenderSkeleton.DoAppend(log4net.Core.LoggingEvent)"/> method.
+ </summary>
+ <param name="loggingEvent">the event to log</param>
+ <remarks>
+ <para>
+ Stores the <paramref name="loggingEvent"/> in the cyclic buffer.
+ </para>
+ <para>
+ The buffer will be sent (i.e. passed to the <see cref="M:log4net.Appender.BufferingAppenderSkeleton.SendBuffer(log4net.Core.LoggingEvent[])"/>
+ method) if one of the following conditions is met:
+ </para>
+ <list type="bullet">
+ <item>
+ <description>The cyclic buffer is full and this appender is
+ marked as not lossy (see <see cref="P:log4net.Appender.BufferingAppenderSkeleton.Lossy"/>)</description>
+ </item>
+ <item>
+ <description>An <see cref="P:log4net.Appender.BufferingAppenderSkeleton.Evaluator"/> is set and
+ it is triggered for the <paramref name="loggingEvent"/>
+ specified.</description>
+ </item>
+ </list>
+ <para>
+ Before the event is stored in the buffer it is fixed
+ (see <see cref="M:log4net.Core.LoggingEvent.FixVolatileData(log4net.Core.FixFlags)"/>) to ensure that
+ any data referenced by the event will be valid when the buffer
+ is processed.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.BufferingAppenderSkeleton.SendFromBuffer(log4net.Core.LoggingEvent,log4net.Util.CyclicBuffer)">
+ <summary>
+ Sends the contents of the buffer.
+ </summary>
+ <param name="firstLoggingEvent">The first logging event.</param>
+ <param name="buffer">The buffer containing the events that need to be send.</param>
+ <remarks>
+ <para>
+ The subclass must override <see cref="M:log4net.Appender.BufferingAppenderSkeleton.SendBuffer(log4net.Core.LoggingEvent[])"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.BufferingAppenderSkeleton.SendBuffer(log4net.Core.LoggingEvent[])">
+ <summary>
+ Sends the events.
+ </summary>
+ <param name="events">The events that need to be send.</param>
+ <remarks>
+ <para>
+ The subclass must override this method to process the buffered events.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Appender.BufferingAppenderSkeleton.m_bufferSize">
+ <summary>
+ The size of the cyclic buffer used to hold the logging events.
+ </summary>
+ <remarks>
+ Set to <see cref="F:log4net.Appender.BufferingAppenderSkeleton.DEFAULT_BUFFER_SIZE"/> by default.
+ </remarks>
+ </member>
+ <member name="F:log4net.Appender.BufferingAppenderSkeleton.m_cb">
+ <summary>
+ The cyclic buffer used to store the logging events.
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.BufferingAppenderSkeleton.m_evaluator">
+ <summary>
+ The triggering event evaluator that causes the buffer to be sent immediately.
+ </summary>
+ <remarks>
+ The object that is used to determine if an event causes the entire
+ buffer to be sent immediately. This field can be <c>null</c>, which
+ indicates that event triggering is not to be done. The evaluator
+ can be set using the <see cref="P:log4net.Appender.BufferingAppenderSkeleton.Evaluator"/> property. If this appender
+ has the <see cref="F:log4net.Appender.BufferingAppenderSkeleton.m_lossy"/> (<see cref="P:log4net.Appender.BufferingAppenderSkeleton.Lossy"/> property) set to
+ <c>true</c> then an <see cref="P:log4net.Appender.BufferingAppenderSkeleton.Evaluator"/> must be set.
+ </remarks>
+ </member>
+ <member name="F:log4net.Appender.BufferingAppenderSkeleton.m_lossy">
+ <summary>
+ Indicates if the appender should overwrite events in the cyclic buffer
+ when it becomes full, or if the buffer should be flushed when the
+ buffer is full.
+ </summary>
+ <remarks>
+ If this field is set to <c>true</c> then an <see cref="P:log4net.Appender.BufferingAppenderSkeleton.Evaluator"/> must
+ be set.
+ </remarks>
+ </member>
+ <member name="F:log4net.Appender.BufferingAppenderSkeleton.m_lossyEvaluator">
+ <summary>
+ The triggering event evaluator filters discarded events.
+ </summary>
+ <remarks>
+ The object that is used to determine if an event that is discarded should
+ really be discarded or if it should be sent to the appenders.
+ This field can be <c>null</c>, which indicates that all discarded events will
+ be discarded.
+ </remarks>
+ </member>
+ <member name="F:log4net.Appender.BufferingAppenderSkeleton.m_fixFlags">
+ <summary>
+ Value indicating which fields in the event should be fixed
+ </summary>
+ <remarks>
+ By default all fields are fixed
+ </remarks>
+ </member>
+ <member name="F:log4net.Appender.BufferingAppenderSkeleton.m_eventMustBeFixed">
+ <summary>
+ The events delivered to the subclass must be fixed.
+ </summary>
+ </member>
+ <member name="P:log4net.Appender.BufferingAppenderSkeleton.Lossy">
+ <summary>
+ Gets or sets a value that indicates whether the appender is lossy.
+ </summary>
+ <value>
+ <c>true</c> if the appender is lossy, otherwise <c>false</c>. The default is <c>false</c>.
+ </value>
+ <remarks>
+ <para>
+ This appender uses a buffer to store logging events before
+ delivering them. A triggering event causes the whole buffer
+ to be send to the remote sink. If the buffer overruns before
+ a triggering event then logging events could be lost. Set
+ <see cref="P:log4net.Appender.BufferingAppenderSkeleton.Lossy"/> to <c>false</c> to prevent logging events
+ from being lost.
+ </para>
+ <para>If <see cref="P:log4net.Appender.BufferingAppenderSkeleton.Lossy"/> is set to <c>true</c> then an
+ <see cref="P:log4net.Appender.BufferingAppenderSkeleton.Evaluator"/> must be specified.</para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.BufferingAppenderSkeleton.BufferSize">
+ <summary>
+ Gets or sets the size of the cyclic buffer used to hold the
+ logging events.
+ </summary>
+ <value>
+ The size of the cyclic buffer used to hold the logging events.
+ </value>
+ <remarks>
+ <para>
+ The <see cref="P:log4net.Appender.BufferingAppenderSkeleton.BufferSize"/> option takes a positive integer
+ representing the maximum number of logging events to collect in
+ a cyclic buffer. When the <see cref="P:log4net.Appender.BufferingAppenderSkeleton.BufferSize"/> is reached,
+ oldest events are deleted as new events are added to the
+ buffer. By default the size of the cyclic buffer is 512 events.
+ </para>
+ <para>
+ If the <see cref="P:log4net.Appender.BufferingAppenderSkeleton.BufferSize"/> is set to a value less than
+ or equal to 1 then no buffering will occur. The logging event
+ will be delivered synchronously (depending on the <see cref="P:log4net.Appender.BufferingAppenderSkeleton.Lossy"/>
+ and <see cref="P:log4net.Appender.BufferingAppenderSkeleton.Evaluator"/> properties). Otherwise the event will
+ be buffered.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.BufferingAppenderSkeleton.Evaluator">
+ <summary>
+ Gets or sets the <see cref="T:log4net.Core.ITriggeringEventEvaluator"/> that causes the
+ buffer to be sent immediately.
+ </summary>
+ <value>
+ The <see cref="T:log4net.Core.ITriggeringEventEvaluator"/> that causes the buffer to be
+ sent immediately.
+ </value>
+ <remarks>
+ <para>
+ The evaluator will be called for each event that is appended to this
+ appender. If the evaluator triggers then the current buffer will
+ immediately be sent (see <see cref="M:log4net.Appender.BufferingAppenderSkeleton.SendBuffer(log4net.Core.LoggingEvent[])"/>).
+ </para>
+ <para>If <see cref="P:log4net.Appender.BufferingAppenderSkeleton.Lossy"/> is set to <c>true</c> then an
+ <see cref="P:log4net.Appender.BufferingAppenderSkeleton.Evaluator"/> must be specified.</para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.BufferingAppenderSkeleton.LossyEvaluator">
+ <summary>
+ Gets or sets the value of the <see cref="T:log4net.Core.ITriggeringEventEvaluator"/> to use.
+ </summary>
+ <value>
+ The value of the <see cref="T:log4net.Core.ITriggeringEventEvaluator"/> to use.
+ </value>
+ <remarks>
+ <para>
+ The evaluator will be called for each event that is discarded from this
+ appender. If the evaluator triggers then the current buffer will immediately
+ be sent (see <see cref="M:log4net.Appender.BufferingAppenderSkeleton.SendBuffer(log4net.Core.LoggingEvent[])"/>).
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.BufferingAppenderSkeleton.OnlyFixPartialEventData">
+ <summary>
+ Gets or sets a value indicating if only part of the logging event data
+ should be fixed.
+ </summary>
+ <value>
+ <c>true</c> if the appender should only fix part of the logging event
+ data, otherwise <c>false</c>. The default is <c>false</c>.
+ </value>
+ <remarks>
+ <para>
+ Setting this property to <c>true</c> will cause only part of the
+ event data to be fixed and serialized. This will improve performance.
+ </para>
+ <para>
+ See <see cref="M:log4net.Core.LoggingEvent.FixVolatileData(log4net.Core.FixFlags)"/> for more information.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.BufferingAppenderSkeleton.Fix">
+ <summary>
+ Gets or sets a the fields that will be fixed in the event
+ </summary>
+ <value>
+ The event fields that will be fixed before the event is buffered
+ </value>
+ <remarks>
+ <para>
+ The logging event needs to have certain thread specific values
+ captured before it can be buffered. See <see cref="P:log4net.Core.LoggingEvent.Fix"/>
+ for details.
+ </para>
+ </remarks>
+ <seealso cref="P:log4net.Core.LoggingEvent.Fix"/>
+ </member>
+ <member name="M:log4net.Appender.AdoNetAppender.#ctor">
+ <summary>
+ Initializes a new instance of the <see cref="T:log4net.Appender.AdoNetAppender"/> class.
+ </summary>
+ <remarks>
+ Public default constructor to initialize a new instance of this class.
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.AdoNetAppender.ActivateOptions">
+ <summary>
+ Initialize the appender based on the options set
+ </summary>
+ <remarks>
+ <para>
+ This is part of the <see cref="T:log4net.Core.IOptionHandler"/> delayed object
+ activation scheme. The <see cref="M:log4net.Appender.AdoNetAppender.ActivateOptions"/> method must
+ be called on this object after the configuration properties have
+ been set. Until <see cref="M:log4net.Appender.AdoNetAppender.ActivateOptions"/> is called this
+ object is in an undefined state and must not be used.
+ </para>
+ <para>
+ If any of the configuration properties are modified then
+ <see cref="M:log4net.Appender.AdoNetAppender.ActivateOptions"/> must be called again.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.AdoNetAppender.OnClose">
+ <summary>
+ Override the parent method to close the database
+ </summary>
+ <remarks>
+ <para>
+ Closes the database command and database connection.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.AdoNetAppender.SendBuffer(log4net.Core.LoggingEvent[])">
+ <summary>
+ Inserts the events into the database.
+ </summary>
+ <param name="events">The events to insert into the database.</param>
+ <remarks>
+ <para>
+ Insert all the events specified in the <paramref name="events"/>
+ array into the database.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.AdoNetAppender.AddParameter(log4net.Appender.AdoNetAppenderParameter)">
+ <summary>
+ Adds a parameter to the command.
+ </summary>
+ <param name="parameter">The parameter to add to the command.</param>
+ <remarks>
+ <para>
+ Adds a parameter to the ordered list of command parameters.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.AdoNetAppender.SendBuffer(System.Data.IDbTransaction,log4net.Core.LoggingEvent[])">
+ <summary>
+ Writes the events to the database using the transaction specified.
+ </summary>
+ <param name="dbTran">The transaction that the events will be executed under.</param>
+ <param name="events">The array of events to insert into the database.</param>
+ <remarks>
+ <para>
+ The transaction argument can be <c>null</c> if the appender has been
+ configured not to use transactions. See <see cref="P:log4net.Appender.AdoNetAppender.UseTransactions"/>
+ property for more information.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.AdoNetAppender.GetLogStatement(log4net.Core.LoggingEvent)">
+ <summary>
+ Formats the log message into database statement text.
+ </summary>
+ <param name="logEvent">The event being logged.</param>
+ <remarks>
+ This method can be overridden by subclasses to provide
+ more control over the format of the database statement.
+ </remarks>
+ <returns>
+ Text that can be passed to a <see cref="T:System.Data.IDbCommand"/>.
+ </returns>
+ </member>
+ <member name="M:log4net.Appender.AdoNetAppender.InitializeDatabaseConnection">
+ <summary>
+ Connects to the database.
+ </summary>
+ </member>
+ <member name="M:log4net.Appender.AdoNetAppender.ResolveConnectionType">
+ <summary>
+ Retrieves the class type of the ADO.NET provider.
+ </summary>
+ <remarks>
+ <para>
+ Gets the Type of the ADO.NET provider to use to connect to the
+ database. This method resolves the type specified in the
+ <see cref="P:log4net.Appender.AdoNetAppender.ConnectionType"/> property.
+ </para>
+ <para>
+ Subclasses can override this method to return a different type
+ if necessary.
+ </para>
+ </remarks>
+ <returns>The <see cref="T:System.Type"/> of the ADO.NET provider</returns>
+ </member>
+ <member name="M:log4net.Appender.AdoNetAppender.InitializeDatabaseCommand">
+ <summary>
+ Prepares the database command and initialize the parameters.
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.AdoNetAppender.m_usePreparedCommand">
+ <summary>
+ Flag to indicate if we are using a command object
+ </summary>
+ <remarks>
+ <para>
+ Set to <c>true</c> when the appender is to use a prepared
+ statement or stored procedure to insert into the database.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Appender.AdoNetAppender.m_parameters">
+ <summary>
+ The list of <see cref="T:log4net.Appender.AdoNetAppenderParameter"/> objects.
+ </summary>
+ <remarks>
+ <para>
+ The list of <see cref="T:log4net.Appender.AdoNetAppenderParameter"/> objects.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Appender.AdoNetAppender.m_securityContext">
+ <summary>
+ The security context to use for privileged calls
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.AdoNetAppender.m_dbConnection">
+ <summary>
+ The <see cref="T:System.Data.IDbConnection"/> that will be used
+ to insert logging events into a database.
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.AdoNetAppender.m_dbCommand">
+ <summary>
+ The database command.
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.AdoNetAppender.m_connectionString">
+ <summary>
+ Database connection string.
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.AdoNetAppender.m_connectionType">
+ <summary>
+ String type name of the <see cref="T:System.Data.IDbConnection"/> type name.
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.AdoNetAppender.m_commandText">
+ <summary>
+ The text of the command.
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.AdoNetAppender.m_commandType">
+ <summary>
+ The command type.
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.AdoNetAppender.m_useTransactions">
+ <summary>
+ Indicates whether to use transactions when writing to the database.
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.AdoNetAppender.m_reconnectOnError">
+ <summary>
+ Indicates whether to use transactions when writing to the database.
+ </summary>
+ </member>
+ <member name="P:log4net.Appender.AdoNetAppender.ConnectionString">
+ <summary>
+ Gets or sets the database connection string that is used to connect to
+ the database.
+ </summary>
+ <value>
+ The database connection string used to connect to the database.
+ </value>
+ <remarks>
+ <para>
+ The connections string is specific to the connection type.
+ See <see cref="P:log4net.Appender.AdoNetAppender.ConnectionType"/> for more information.
+ </para>
+ </remarks>
+ <example>Connection string for MS Access via ODBC:
+ <code>"DSN=MS Access Database;UID=admin;PWD=;SystemDB=C:\data\System.mdw;SafeTransactions = 0;FIL=MS Access;DriverID = 25;DBQ=C:\data\train33.mdb"</code>
+ </example>
+ <example>Another connection string for MS Access via ODBC:
+ <code>"Driver={Microsoft Access Driver (*.mdb)};DBQ=C:\Work\cvs_root\log4net-1.2\access.mdb;UID=;PWD=;"</code>
+ </example>
+ <example>Connection string for MS Access via OLE DB:
+ <code>"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\Work\cvs_root\log4net-1.2\access.mdb;User Id=;Password=;"</code>
+ </example>
+ </member>
+ <member name="P:log4net.Appender.AdoNetAppender.ConnectionType">
+ <summary>
+ Gets or sets the type name of the <see cref="T:System.Data.IDbConnection"/> connection
+ that should be created.
+ </summary>
+ <value>
+ The type name of the <see cref="T:System.Data.IDbConnection"/> connection.
+ </value>
+ <remarks>
+ <para>
+ The type name of the ADO.NET provider to use.
+ </para>
+ <para>
+ The default is to use the OLE DB provider.
+ </para>
+ </remarks>
+ <example>Use the OLE DB Provider. This is the default value.
+ <code>System.Data.OleDb.OleDbConnection, System.Data, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</code>
+ </example>
+ <example>Use the MS SQL Server Provider.
+ <code>System.Data.SqlClient.SqlConnection, System.Data, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</code>
+ </example>
+ <example>Use the ODBC Provider.
+ <code>Microsoft.Data.Odbc.OdbcConnection,Microsoft.Data.Odbc,version=1.0.3300.0,publicKeyToken=b77a5c561934e089,culture=neutral</code>
+ This is an optional package that you can download from
+ <a href="http://msdn.microsoft.com/downloads">http://msdn.microsoft.com/downloads</a>
+ search for <b>ODBC .NET Data Provider</b>.
+ </example>
+ <example>Use the Oracle Provider.
+ <code>System.Data.OracleClient.OracleConnection, System.Data.OracleClient, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</code>
+ This is an optional package that you can download from
+ <a href="http://msdn.microsoft.com/downloads">http://msdn.microsoft.com/downloads</a>
+ search for <b>.NET Managed Provider for Oracle</b>.
+ </example>
+ </member>
+ <member name="P:log4net.Appender.AdoNetAppender.CommandText">
+ <summary>
+ Gets or sets the command text that is used to insert logging events
+ into the database.
+ </summary>
+ <value>
+ The command text used to insert logging events into the database.
+ </value>
+ <remarks>
+ <para>
+ Either the text of the prepared statement or the
+ name of the stored procedure to execute to write into
+ the database.
+ </para>
+ <para>
+ The <see cref="P:log4net.Appender.AdoNetAppender.CommandType"/> property determines if
+ this text is a prepared statement or a stored procedure.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.AdoNetAppender.CommandType">
+ <summary>
+ Gets or sets the command type to execute.
+ </summary>
+ <value>
+ The command type to execute.
+ </value>
+ <remarks>
+ <para>
+ This value may be either <see cref="F:System.Data.CommandType.Text"/> (<c>System.Data.CommandType.Text</c>) to specify
+ that the <see cref="P:log4net.Appender.AdoNetAppender.CommandText"/> is a prepared statement to execute,
+ or <see cref="F:System.Data.CommandType.StoredProcedure"/> (<c>System.Data.CommandType.StoredProcedure</c>) to specify that the
+ <see cref="P:log4net.Appender.AdoNetAppender.CommandText"/> property is the name of a stored procedure
+ to execute.
+ </para>
+ <para>
+ The default value is <see cref="F:System.Data.CommandType.Text"/> (<c>System.Data.CommandType.Text</c>).
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.AdoNetAppender.UseTransactions">
+ <summary>
+ Should transactions be used to insert logging events in the database.
+ </summary>
+ <value>
+ <c>true</c> if transactions should be used to insert logging events in
+ the database, otherwise <c>false</c>. The default value is <c>true</c>.
+ </value>
+ <remarks>
+ <para>
+ Gets or sets a value that indicates whether transactions should be used
+ to insert logging events in the database.
+ </para>
+ <para>
+ When set a single transaction will be used to insert the buffered events
+ into the database. Otherwise each event will be inserted without using
+ an explicit transaction.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.AdoNetAppender.SecurityContext">
+ <summary>
+ Gets or sets the <see cref="P:log4net.Appender.AdoNetAppender.SecurityContext"/> used to call the NetSend method.
+ </summary>
+ <value>
+ The <see cref="P:log4net.Appender.AdoNetAppender.SecurityContext"/> used to call the NetSend method.
+ </value>
+ <remarks>
+ <para>
+ Unless a <see cref="P:log4net.Appender.AdoNetAppender.SecurityContext"/> specified here for this appender
+ the <see cref="P:log4net.Core.SecurityContextProvider.DefaultProvider"/> is queried for the
+ security context to use. The default behavior is to use the security context
+ of the current thread.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.AdoNetAppender.ReconnectOnError">
+ <summary>
+ Should this appender try to reconnect to the database on error.
+ </summary>
+ <value>
+ <c>true</c> if the appender should try to reconnect to the database after an
+ error has occurred, otherwise <c>false</c>. The default value is <c>false</c>,
+ i.e. not to try to reconnect.
+ </value>
+ <remarks>
+ <para>
+ The default behaviour is for the appender not to try to reconnect to the
+ database if an error occurs. Subsequent logging events are discarded.
+ </para>
+ <para>
+ To force the appender to attempt to reconnect to the database set this
+ property to <c>true</c>.
+ </para>
+ <note>
+ When the appender attempts to connect to the database there may be a
+ delay of up to the connection timeout specified in the connection string.
+ This delay will block the calling application's thread.
+ Until the connection can be reestablished this potential delay may occur multiple times.
+ </note>
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.AdoNetAppender.Connection">
+ <summary>
+ Gets or sets the underlying <see cref="T:System.Data.IDbConnection"/>.
+ </summary>
+ <value>
+ The underlying <see cref="T:System.Data.IDbConnection"/>.
+ </value>
+ <remarks>
+ <see cref="T:log4net.Appender.AdoNetAppender"/> creates a <see cref="T:System.Data.IDbConnection"/> to insert
+ logging events into a database. Classes deriving from <see cref="T:log4net.Appender.AdoNetAppender"/>
+ can use this property to get or set this <see cref="T:System.Data.IDbConnection"/>. Use the
+ underlying <see cref="T:System.Data.IDbConnection"/> returned from <see cref="P:log4net.Appender.AdoNetAppender.Connection"/> if
+ you require access beyond that which <see cref="T:log4net.Appender.AdoNetAppender"/> provides.
+ </remarks>
+ </member>
+ <member name="T:log4net.Appender.AdoNetAppenderParameter">
+ <summary>
+ Parameter type used by the <see cref="T:log4net.Appender.AdoNetAppender"/>.
+ </summary>
+ <remarks>
+ <para>
+ This class provides the basic database parameter properties
+ as defined by the <see cref="T:System.Data.IDbDataParameter"/> interface.
+ </para>
+ <para>This type can be subclassed to provide database specific
+ functionality. The two methods that are called externally are
+ <see cref="M:log4net.Appender.AdoNetAppenderParameter.Prepare(System.Data.IDbCommand)"/> and <see cref="M:log4net.Appender.AdoNetAppenderParameter.FormatValue(System.Data.IDbCommand,log4net.Core.LoggingEvent)"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.AdoNetAppenderParameter.#ctor">
+ <summary>
+ Initializes a new instance of the <see cref="T:log4net.Appender.AdoNetAppenderParameter"/> class.
+ </summary>
+ <remarks>
+ Default constructor for the AdoNetAppenderParameter class.
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.AdoNetAppenderParameter.Prepare(System.Data.IDbCommand)">
+ <summary>
+ Prepare the specified database command object.
+ </summary>
+ <param name="command">The command to prepare.</param>
+ <remarks>
+ <para>
+ Prepares the database command object by adding
+ this parameter to its collection of parameters.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.AdoNetAppenderParameter.FormatValue(System.Data.IDbCommand,log4net.Core.LoggingEvent)">
+ <summary>
+ Renders the logging event and set the parameter value in the command.
+ </summary>
+ <param name="command">The command containing the parameter.</param>
+ <param name="loggingEvent">The event to be rendered.</param>
+ <remarks>
+ <para>
+ Renders the logging event using this parameters layout
+ object. Sets the value of the parameter on the command object.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Appender.AdoNetAppenderParameter.m_parameterName">
+ <summary>
+ The name of this parameter.
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.AdoNetAppenderParameter.m_dbType">
+ <summary>
+ The database type for this parameter.
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.AdoNetAppenderParameter.m_inferType">
+ <summary>
+ Flag to infer type rather than use the DbType
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.AdoNetAppenderParameter.m_precision">
+ <summary>
+ The precision for this parameter.
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.AdoNetAppenderParameter.m_scale">
+ <summary>
+ The scale for this parameter.
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.AdoNetAppenderParameter.m_size">
+ <summary>
+ The size for this parameter.
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.AdoNetAppenderParameter.m_layout">
+ <summary>
+ The <see cref="T:log4net.Layout.IRawLayout"/> to use to render the
+ logging event into an object for this parameter.
+ </summary>
+ </member>
+ <member name="P:log4net.Appender.AdoNetAppenderParameter.ParameterName">
+ <summary>
+ Gets or sets the name of this parameter.
+ </summary>
+ <value>
+ The name of this parameter.
+ </value>
+ <remarks>
+ <para>
+ The name of this parameter. The parameter name
+ must match up to a named parameter to the SQL stored procedure
+ or prepared statement.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.AdoNetAppenderParameter.DbType">
+ <summary>
+ Gets or sets the database type for this parameter.
+ </summary>
+ <value>
+ The database type for this parameter.
+ </value>
+ <remarks>
+ <para>
+ The database type for this parameter. This property should
+ be set to the database type from the <see cref="P:log4net.Appender.AdoNetAppenderParameter.DbType"/>
+ enumeration. See <see cref="P:System.Data.IDataParameter.DbType"/>.
+ </para>
+ <para>
+ This property is optional. If not specified the ADO.NET provider
+ will attempt to infer the type from the value.
+ </para>
+ </remarks>
+ <seealso cref="P:System.Data.IDataParameter.DbType"/>
+ </member>
+ <member name="P:log4net.Appender.AdoNetAppenderParameter.Precision">
+ <summary>
+ Gets or sets the precision for this parameter.
+ </summary>
+ <value>
+ The precision for this parameter.
+ </value>
+ <remarks>
+ <para>
+ The maximum number of digits used to represent the Value.
+ </para>
+ <para>
+ This property is optional. If not specified the ADO.NET provider
+ will attempt to infer the precision from the value.
+ </para>
+ </remarks>
+ <seealso cref="P:System.Data.IDbDataParameter.Precision"/>
+ </member>
+ <member name="P:log4net.Appender.AdoNetAppenderParameter.Scale">
+ <summary>
+ Gets or sets the scale for this parameter.
+ </summary>
+ <value>
+ The scale for this parameter.
+ </value>
+ <remarks>
+ <para>
+ The number of decimal places to which Value is resolved.
+ </para>
+ <para>
+ This property is optional. If not specified the ADO.NET provider
+ will attempt to infer the scale from the value.
+ </para>
+ </remarks>
+ <seealso cref="P:System.Data.IDbDataParameter.Scale"/>
+ </member>
+ <member name="P:log4net.Appender.AdoNetAppenderParameter.Size">
+ <summary>
+ Gets or sets the size for this parameter.
+ </summary>
+ <value>
+ The size for this parameter.
+ </value>
+ <remarks>
+ <para>
+ The maximum size, in bytes, of the data within the column.
+ </para>
+ <para>
+ This property is optional. If not specified the ADO.NET provider
+ will attempt to infer the size from the value.
+ </para>
+ </remarks>
+ <seealso cref="P:System.Data.IDbDataParameter.Size"/>
+ </member>
+ <member name="P:log4net.Appender.AdoNetAppenderParameter.Layout">
+ <summary>
+ Gets or sets the <see cref="T:log4net.Layout.IRawLayout"/> to use to
+ render the logging event into an object for this
+ parameter.
+ </summary>
+ <value>
+ The <see cref="T:log4net.Layout.IRawLayout"/> used to render the
+ logging event into an object for this parameter.
+ </value>
+ <remarks>
+ <para>
+ The <see cref="T:log4net.Layout.IRawLayout"/> that renders the value for this
+ parameter.
+ </para>
+ <para>
+ The <see cref="T:log4net.Layout.RawLayoutConverter"/> can be used to adapt
+ any <see cref="T:log4net.Layout.ILayout"/> into a <see cref="T:log4net.Layout.IRawLayout"/>
+ for use in the property.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Appender.AnsiColorTerminalAppender">
+ <summary>
+ Appends logging events to the terminal using ANSI color escape sequences.
+ </summary>
+ <remarks>
+ <para>
+ AnsiColorTerminalAppender appends log events to the standard output stream
+ or the error output stream using a layout specified by the
+ user. It also allows the color of a specific level of message to be set.
+ </para>
+ <note>
+ This appender expects the terminal to understand the VT100 control set
+ in order to interpret the color codes. If the terminal or console does not
+ understand the control codes the behavior is not defined.
+ </note>
+ <para>
+ By default, all output is written to the console's standard output stream.
+ The <see cref="P:log4net.Appender.AnsiColorTerminalAppender.Target"/> property can be set to direct the output to the
+ error stream.
+ </para>
+ <para>
+ NOTE: This appender writes each message to the <c>System.Console.Out</c> or
+ <c>System.Console.Error</c> that is set at the time the event is appended.
+ Therefore it is possible to programmatically redirect the output of this appender
+ (for example NUnit does this to capture program output). While this is the desired
+ behavior of this appender it may have security implications in your application.
+ </para>
+ <para>
+ When configuring the ANSI colored terminal appender, a mapping should be
+ specified to map a logging level to a color. For example:
+ </para>
+ <code lang="XML" escaped="true">
+ <mapping>
+ <level value="ERROR"/>
+ <foreColor value="White"/>
+ <backColor value="Red"/>
+ <attributes value="Bright,Underscore"/>
+ </mapping>
+ <mapping>
+ <level value="DEBUG"/>
+ <backColor value="Green"/>
+ </mapping>
+ </code>
+ <para>
+ The Level is the standard log4net logging level and ForeColor and BackColor can be any
+ of the following values:
+ <list type="bullet">
+ <item><term>Blue</term><description></description></item>
+ <item><term>Green</term><description></description></item>
+ <item><term>Red</term><description></description></item>
+ <item><term>White</term><description></description></item>
+ <item><term>Yellow</term><description></description></item>
+ <item><term>Purple</term><description></description></item>
+ <item><term>Cyan</term><description></description></item>
+ </list>
+ These color values cannot be combined together to make new colors.
+ </para>
+ <para>
+ The attributes can be any combination of the following:
+ <list type="bullet">
+ <item><term>Bright</term><description>foreground is brighter</description></item>
+ <item><term>Dim</term><description>foreground is dimmer</description></item>
+ <item><term>Underscore</term><description>message is underlined</description></item>
+ <item><term>Blink</term><description>foreground is blinking (does not work on all terminals)</description></item>
+ <item><term>Reverse</term><description>foreground and background are reversed</description></item>
+ <item><term>Hidden</term><description>output is hidden</description></item>
+ <item><term>Strikethrough</term><description>message has a line through it</description></item>
+ </list>
+ While any of these attributes may be combined together not all combinations
+ work well together, for example setting both <i>Bright</i> and <i>Dim</i> attributes makes
+ no sense.
+ </para>
+ </remarks>
+ <author>Patrick Wagstrom</author>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="F:log4net.Appender.AnsiColorTerminalAppender.ConsoleOut">
+ <summary>
+ The <see cref="P:log4net.Appender.AnsiColorTerminalAppender.Target"/> to use when writing to the Console
+ standard output stream.
+ </summary>
+ <remarks>
+ <para>
+ The <see cref="P:log4net.Appender.AnsiColorTerminalAppender.Target"/> to use when writing to the Console
+ standard output stream.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Appender.AnsiColorTerminalAppender.ConsoleError">
+ <summary>
+ The <see cref="P:log4net.Appender.AnsiColorTerminalAppender.Target"/> to use when writing to the Console
+ standard error output stream.
+ </summary>
+ <remarks>
+ <para>
+ The <see cref="P:log4net.Appender.AnsiColorTerminalAppender.Target"/> to use when writing to the Console
+ standard error output stream.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Appender.AnsiColorTerminalAppender.PostEventCodes">
+ <summary>
+ Ansi code to reset terminal
+ </summary>
+ </member>
+ <member name="M:log4net.Appender.AnsiColorTerminalAppender.#ctor">
+ <summary>
+ Initializes a new instance of the <see cref="T:log4net.Appender.AnsiColorTerminalAppender"/> class.
+ </summary>
+ <remarks>
+ The instance of the <see cref="T:log4net.Appender.AnsiColorTerminalAppender"/> class is set up to write
+ to the standard output stream.
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.AnsiColorTerminalAppender.AddMapping(log4net.Appender.AnsiColorTerminalAppender.LevelColors)">
+ <summary>
+ Add a mapping of level to color
+ </summary>
+ <param name="mapping">The mapping to add</param>
+ <remarks>
+ <para>
+ Add a <see cref="T:log4net.Appender.AnsiColorTerminalAppender.LevelColors"/> mapping to this appender.
+ Each mapping defines the foreground and background colours
+ for a level.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.AnsiColorTerminalAppender.Append(log4net.Core.LoggingEvent)">
+ <summary>
+ This method is called by the <see cref="M:log4net.Appender.AppenderSkeleton.DoAppend(log4net.Core.LoggingEvent)"/> method.
+ </summary>
+ <param name="loggingEvent">The event to log.</param>
+ <remarks>
+ <para>
+ Writes the event to the console.
+ </para>
+ <para>
+ The format of the output will depend on the appender's layout.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.AnsiColorTerminalAppender.ActivateOptions">
+ <summary>
+ Initialize the options for this appender
+ </summary>
+ <remarks>
+ <para>
+ Initialize the level to color mappings set on this appender.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Appender.AnsiColorTerminalAppender.m_writeToErrorStream">
+ <summary>
+ Flag to write output to the error stream rather than the standard output stream
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.AnsiColorTerminalAppender.m_levelMapping">
+ <summary>
+ Mapping from level object to color value
+ </summary>
+ </member>
+ <member name="P:log4net.Appender.AnsiColorTerminalAppender.Target">
+ <summary>
+ Target is the value of the console output stream.
+ </summary>
+ <value>
+ Target is the value of the console output stream.
+ This is either <c>"Console.Out"</c> or <c>"Console.Error"</c>.
+ </value>
+ <remarks>
+ <para>
+ Target is the value of the console output stream.
+ This is either <c>"Console.Out"</c> or <c>"Console.Error"</c>.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.AnsiColorTerminalAppender.RequiresLayout">
+ <summary>
+ This appender requires a <see cref="N:log4net.Layout"/> to be set.
+ </summary>
+ <value><c>true</c></value>
+ <remarks>
+ <para>
+ This appender requires a <see cref="N:log4net.Layout"/> to be set.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Appender.AnsiColorTerminalAppender.AnsiAttributes">
+ <summary>
+ The enum of possible display attributes
+ </summary>
+ <remarks>
+ <para>
+ The following flags can be combined together to
+ form the ANSI color attributes.
+ </para>
+ </remarks>
+ <seealso cref="T:log4net.Appender.AnsiColorTerminalAppender"/>
+ </member>
+ <member name="F:log4net.Appender.AnsiColorTerminalAppender.AnsiAttributes.Bright">
+ <summary>
+ text is bright
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.AnsiColorTerminalAppender.AnsiAttributes.Dim">
+ <summary>
+ text is dim
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.AnsiColorTerminalAppender.AnsiAttributes.Underscore">
+ <summary>
+ text is underlined
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.AnsiColorTerminalAppender.AnsiAttributes.Blink">
+ <summary>
+ text is blinking
+ </summary>
+ <remarks>
+ Not all terminals support this attribute
+ </remarks>
+ </member>
+ <member name="F:log4net.Appender.AnsiColorTerminalAppender.AnsiAttributes.Reverse">
+ <summary>
+ text and background colors are reversed
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.AnsiColorTerminalAppender.AnsiAttributes.Hidden">
+ <summary>
+ text is hidden
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.AnsiColorTerminalAppender.AnsiAttributes.Strikethrough">
+ <summary>
+ text is displayed with a strikethrough
+ </summary>
+ </member>
+ <member name="T:log4net.Appender.AnsiColorTerminalAppender.AnsiColor">
+ <summary>
+ The enum of possible foreground or background color values for
+ use with the color mapping method
+ </summary>
+ <remarks>
+ <para>
+ The output can be in one for the following ANSI colors.
+ </para>
+ </remarks>
+ <seealso cref="T:log4net.Appender.AnsiColorTerminalAppender"/>
+ </member>
+ <member name="F:log4net.Appender.AnsiColorTerminalAppender.AnsiColor.Black">
+ <summary>
+ color is black
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.AnsiColorTerminalAppender.AnsiColor.Red">
+ <summary>
+ color is red
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.AnsiColorTerminalAppender.AnsiColor.Green">
+ <summary>
+ color is green
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.AnsiColorTerminalAppender.AnsiColor.Yellow">
+ <summary>
+ color is yellow
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.AnsiColorTerminalAppender.AnsiColor.Blue">
+ <summary>
+ color is blue
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.AnsiColorTerminalAppender.AnsiColor.Magenta">
+ <summary>
+ color is magenta
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.AnsiColorTerminalAppender.AnsiColor.Cyan">
+ <summary>
+ color is cyan
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.AnsiColorTerminalAppender.AnsiColor.White">
+ <summary>
+ color is white
+ </summary>
+ </member>
+ <member name="T:log4net.Appender.AnsiColorTerminalAppender.LevelColors">
+ <summary>
+ A class to act as a mapping between the level that a logging call is made at and
+ the color it should be displayed as.
+ </summary>
+ <remarks>
+ <para>
+ Defines the mapping between a level and the color it should be displayed in.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Util.LevelMappingEntry">
+ <summary>
+ An entry in the <see cref="T:log4net.Util.LevelMapping"/>
+ </summary>
+ <remarks>
+ <para>
+ This is an abstract base class for types that are stored in the
+ <see cref="T:log4net.Util.LevelMapping"/> object.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="M:log4net.Util.LevelMappingEntry.#ctor">
+ <summary>
+ Default protected constructor
+ </summary>
+ <remarks>
+ <para>
+ Default protected constructor
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.LevelMappingEntry.ActivateOptions">
+ <summary>
+ Initialize any options defined on this entry
+ </summary>
+ <remarks>
+ <para>
+ Should be overridden by any classes that need to initialise based on their options
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Util.LevelMappingEntry.Level">
+ <summary>
+ The level that is the key for this mapping
+ </summary>
+ <value>
+ The <see cref="P:log4net.Util.LevelMappingEntry.Level"/> that is the key for this mapping
+ </value>
+ <remarks>
+ <para>
+ Get or set the <see cref="P:log4net.Util.LevelMappingEntry.Level"/> that is the key for this
+ mapping subclass.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.AnsiColorTerminalAppender.LevelColors.ActivateOptions">
+ <summary>
+ Initialize the options for the object
+ </summary>
+ <remarks>
+ <para>
+ Combine the <see cref="P:log4net.Appender.AnsiColorTerminalAppender.LevelColors.ForeColor"/> and <see cref="P:log4net.Appender.AnsiColorTerminalAppender.LevelColors.BackColor"/> together
+ and append the attributes.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.AnsiColorTerminalAppender.LevelColors.ForeColor">
+ <summary>
+ The mapped foreground color for the specified level
+ </summary>
+ <remarks>
+ <para>
+ Required property.
+ The mapped foreground color for the specified level
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.AnsiColorTerminalAppender.LevelColors.BackColor">
+ <summary>
+ The mapped background color for the specified level
+ </summary>
+ <remarks>
+ <para>
+ Required property.
+ The mapped background color for the specified level
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.AnsiColorTerminalAppender.LevelColors.Attributes">
+ <summary>
+ The color attributes for the specified level
+ </summary>
+ <remarks>
+ <para>
+ Required property.
+ The color attributes for the specified level
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.AnsiColorTerminalAppender.LevelColors.CombinedColor">
+ <summary>
+ The combined <see cref="P:log4net.Appender.AnsiColorTerminalAppender.LevelColors.ForeColor"/>, <see cref="P:log4net.Appender.AnsiColorTerminalAppender.LevelColors.BackColor"/> and
+ <see cref="P:log4net.Appender.AnsiColorTerminalAppender.LevelColors.Attributes"/> suitable for setting the ansi terminal color.
+ </summary>
+ </member>
+ <member name="T:log4net.Appender.AppenderCollection">
+ <summary>
+ A strongly-typed collection of <see cref="T:log4net.Appender.IAppender"/> objects.
+ </summary>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="M:log4net.Appender.AppenderCollection.ReadOnly(log4net.Appender.AppenderCollection)">
+ <summary>
+ Creates a read-only wrapper for a <c>AppenderCollection</c> instance.
+ </summary>
+ <param name="list">list to create a readonly wrapper arround</param>
+ <returns>
+ An <c>AppenderCollection</c> wrapper that is read-only.
+ </returns>
+ </member>
+ <member name="F:log4net.Appender.AppenderCollection.EmptyCollection">
+ <summary>
+ An empty readonly static AppenderCollection
+ </summary>
+ </member>
+ <member name="M:log4net.Appender.AppenderCollection.#ctor">
+ <summary>
+ Initializes a new instance of the <c>AppenderCollection</c> class
+ that is empty and has the default initial capacity.
+ </summary>
+ </member>
+ <member name="M:log4net.Appender.AppenderCollection.#ctor(System.Int32)">
+ <summary>
+ Initializes a new instance of the <c>AppenderCollection</c> class
+ that has the specified initial capacity.
+ </summary>
+ <param name="capacity">
+ The number of elements that the new <c>AppenderCollection</c> is initially capable of storing.
+ </param>
+ </member>
+ <member name="M:log4net.Appender.AppenderCollection.#ctor(log4net.Appender.AppenderCollection)">
+ <summary>
+ Initializes a new instance of the <c>AppenderCollection</c> class
+ that contains elements copied from the specified <c>AppenderCollection</c>.
+ </summary>
+ <param name="c">The <c>AppenderCollection</c> whose elements are copied to the new collection.</param>
+ </member>
+ <member name="M:log4net.Appender.AppenderCollection.#ctor(log4net.Appender.IAppender[])">
+ <summary>
+ Initializes a new instance of the <c>AppenderCollection</c> class
+ that contains elements copied from the specified <see cref="T:log4net.Appender.IAppender"/> array.
+ </summary>
+ <param name="a">The <see cref="T:log4net.Appender.IAppender"/> array whose elements are copied to the new list.</param>
+ </member>
+ <member name="M:log4net.Appender.AppenderCollection.#ctor(System.Collections.ICollection)">
+ <summary>
+ Initializes a new instance of the <c>AppenderCollection</c> class
+ that contains elements copied from the specified <see cref="T:log4net.Appender.IAppender"/> collection.
+ </summary>
+ <param name="col">The <see cref="T:log4net.Appender.IAppender"/> collection whose elements are copied to the new list.</param>
+ </member>
+ <member name="M:log4net.Appender.AppenderCollection.#ctor(log4net.Appender.AppenderCollection.Tag)">
+ <summary>
+ Allow subclasses to avoid our default constructors
+ </summary>
+ <param name="tag"></param>
+ <exclude/>
+ </member>
+ <member name="M:log4net.Appender.AppenderCollection.CopyTo(log4net.Appender.IAppender[])">
+ <summary>
+ Copies the entire <c>AppenderCollection</c> to a one-dimensional
+ <see cref="T:log4net.Appender.IAppender"/> array.
+ </summary>
+ <param name="array">The one-dimensional <see cref="T:log4net.Appender.IAppender"/> array to copy to.</param>
+ </member>
+ <member name="M:log4net.Appender.AppenderCollection.CopyTo(log4net.Appender.IAppender[],System.Int32)">
+ <summary>
+ Copies the entire <c>AppenderCollection</c> to a one-dimensional
+ <see cref="T:log4net.Appender.IAppender"/> array, starting at the specified index of the target array.
+ </summary>
+ <param name="array">The one-dimensional <see cref="T:log4net.Appender.IAppender"/> array to copy to.</param>
+ <param name="start">The zero-based index in <paramref name="array"/> at which copying begins.</param>
+ </member>
+ <member name="M:log4net.Appender.AppenderCollection.Add(log4net.Appender.IAppender)">
+ <summary>
+ Adds a <see cref="T:log4net.Appender.IAppender"/> to the end of the <c>AppenderCollection</c>.
+ </summary>
+ <param name="item">The <see cref="T:log4net.Appender.IAppender"/> to be added to the end of the <c>AppenderCollection</c>.</param>
+ <returns>The index at which the value has been added.</returns>
+ </member>
+ <member name="M:log4net.Appender.AppenderCollection.Clear">
+ <summary>
+ Removes all elements from the <c>AppenderCollection</c>.
+ </summary>
+ </member>
+ <member name="M:log4net.Appender.AppenderCollection.Clone">
+ <summary>
+ Creates a shallow copy of the <see cref="T:log4net.Appender.AppenderCollection"/>.
+ </summary>
+ <returns>A new <see cref="T:log4net.Appender.AppenderCollection"/> with a shallow copy of the collection data.</returns>
+ </member>
+ <member name="M:log4net.Appender.AppenderCollection.Contains(log4net.Appender.IAppender)">
+ <summary>
+ Determines whether a given <see cref="T:log4net.Appender.IAppender"/> is in the <c>AppenderCollection</c>.
+ </summary>
+ <param name="item">The <see cref="T:log4net.Appender.IAppender"/> to check for.</param>
+ <returns><c>true</c> if <paramref name="item"/> is found in the <c>AppenderCollection</c>; otherwise, <c>false</c>.</returns>
+ </member>
+ <member name="M:log4net.Appender.AppenderCollection.IndexOf(log4net.Appender.IAppender)">
+ <summary>
+ Returns the zero-based index of the first occurrence of a <see cref="T:log4net.Appender.IAppender"/>
+ in the <c>AppenderCollection</c>.
+ </summary>
+ <param name="item">The <see cref="T:log4net.Appender.IAppender"/> to locate in the <c>AppenderCollection</c>.</param>
+ <returns>
+ The zero-based index of the first occurrence of <paramref name="item"/>
+ in the entire <c>AppenderCollection</c>, if found; otherwise, -1.
+ </returns>
+ </member>
+ <member name="M:log4net.Appender.AppenderCollection.Insert(System.Int32,log4net.Appender.IAppender)">
+ <summary>
+ Inserts an element into the <c>AppenderCollection</c> at the specified index.
+ </summary>
+ <param name="index">The zero-based index at which <paramref name="item"/> should be inserted.</param>
+ <param name="item">The <see cref="T:log4net.Appender.IAppender"/> to insert.</param>
+ <exception cref="T:System.ArgumentOutOfRangeException">
+ <para><paramref name="index"/> is less than zero</para>
+ <para>-or-</para>
+ <para><paramref name="index"/> is equal to or greater than <see cref="P:log4net.Appender.AppenderCollection.Count"/>.</para>
+ </exception>
+ </member>
+ <member name="M:log4net.Appender.AppenderCollection.Remove(log4net.Appender.IAppender)">
+ <summary>
+ Removes the first occurrence of a specific <see cref="T:log4net.Appender.IAppender"/> from the <c>AppenderCollection</c>.
+ </summary>
+ <param name="item">The <see cref="T:log4net.Appender.IAppender"/> to remove from the <c>AppenderCollection</c>.</param>
+ <exception cref="T:System.ArgumentException">
+ The specified <see cref="T:log4net.Appender.IAppender"/> was not found in the <c>AppenderCollection</c>.
+ </exception>
+ </member>
+ <member name="M:log4net.Appender.AppenderCollection.RemoveAt(System.Int32)">
+ <summary>
+ Removes the element at the specified index of the <c>AppenderCollection</c>.
+ </summary>
+ <param name="index">The zero-based index of the element to remove.</param>
+ <exception cref="T:System.ArgumentOutOfRangeException">
+ <para><paramref name="index"/> is less than zero</para>
+ <para>-or-</para>
+ <para><paramref name="index"/> is equal to or greater than <see cref="P:log4net.Appender.AppenderCollection.Count"/>.</para>
+ </exception>
+ </member>
+ <member name="M:log4net.Appender.AppenderCollection.GetEnumerator">
+ <summary>
+ Returns an enumerator that can iterate through the <c>AppenderCollection</c>.
+ </summary>
+ <returns>An <see cref="T:log4net.Appender.AppenderCollection.Enumerator"/> for the entire <c>AppenderCollection</c>.</returns>
+ </member>
+ <member name="M:log4net.Appender.AppenderCollection.AddRange(log4net.Appender.AppenderCollection)">
+ <summary>
+ Adds the elements of another <c>AppenderCollection</c> to the current <c>AppenderCollection</c>.
+ </summary>
+ <param name="x">The <c>AppenderCollection</c> whose elements should be added to the end of the current <c>AppenderCollection</c>.</param>
+ <returns>The new <see cref="P:log4net.Appender.AppenderCollection.Count"/> of the <c>AppenderCollection</c>.</returns>
+ </member>
+ <member name="M:log4net.Appender.AppenderCollection.AddRange(log4net.Appender.IAppender[])">
+ <summary>
+ Adds the elements of a <see cref="T:log4net.Appender.IAppender"/> array to the current <c>AppenderCollection</c>.
+ </summary>
+ <param name="x">The <see cref="T:log4net.Appender.IAppender"/> array whose elements should be added to the end of the <c>AppenderCollection</c>.</param>
+ <returns>The new <see cref="P:log4net.Appender.AppenderCollection.Count"/> of the <c>AppenderCollection</c>.</returns>
+ </member>
+ <member name="M:log4net.Appender.AppenderCollection.AddRange(System.Collections.ICollection)">
+ <summary>
+ Adds the elements of a <see cref="T:log4net.Appender.IAppender"/> collection to the current <c>AppenderCollection</c>.
+ </summary>
+ <param name="col">The <see cref="T:log4net.Appender.IAppender"/> collection whose elements should be added to the end of the <c>AppenderCollection</c>.</param>
+ <returns>The new <see cref="P:log4net.Appender.AppenderCollection.Count"/> of the <c>AppenderCollection</c>.</returns>
+ </member>
+ <member name="M:log4net.Appender.AppenderCollection.TrimToSize">
+ <summary>
+ Sets the capacity to the actual number of elements.
+ </summary>
+ </member>
+ <member name="M:log4net.Appender.AppenderCollection.ToArray">
+ <summary>
+ Return the collection elements as an array
+ </summary>
+ <returns>the array</returns>
+ </member>
+ <member name="M:log4net.Appender.AppenderCollection.ValidateIndex(System.Int32)">
+ <exception cref="T:System.ArgumentOutOfRangeException">
+ <para><paramref name="index"/> is less than zero</para>
+ <para>-or-</para>
+ <para><paramref name="index"/> is equal to or greater than <see cref="P:log4net.Appender.AppenderCollection.Count"/>.</para>
+ </exception>
+ </member>
+ <member name="M:log4net.Appender.AppenderCollection.ValidateIndex(System.Int32,System.Boolean)">
+ <exception cref="T:System.ArgumentOutOfRangeException">
+ <para><paramref name="index"/> is less than zero</para>
+ <para>-or-</para>
+ <para><paramref name="index"/> is equal to or greater than <see cref="P:log4net.Appender.AppenderCollection.Count"/>.</para>
+ </exception>
+ </member>
+ <member name="P:log4net.Appender.AppenderCollection.Count">
+ <summary>
+ Gets the number of elements actually contained in the <c>AppenderCollection</c>.
+ </summary>
+ </member>
+ <member name="P:log4net.Appender.AppenderCollection.IsSynchronized">
+ <summary>
+ Gets a value indicating whether access to the collection is synchronized (thread-safe).
+ </summary>
+ <returns>true if access to the ICollection is synchronized (thread-safe); otherwise, false.</returns>
+ </member>
+ <member name="P:log4net.Appender.AppenderCollection.SyncRoot">
+ <summary>
+ Gets an object that can be used to synchronize access to the collection.
+ </summary>
+ </member>
+ <member name="P:log4net.Appender.AppenderCollection.Item(System.Int32)">
+ <summary>
+ Gets or sets the <see cref="T:log4net.Appender.IAppender"/> at the specified index.
+ </summary>
+ <param name="index">The zero-based index of the element to get or set.</param>
+ <exception cref="T:System.ArgumentOutOfRangeException">
+ <para><paramref name="index"/> is less than zero</para>
+ <para>-or-</para>
+ <para><paramref name="index"/> is equal to or greater than <see cref="P:log4net.Appender.AppenderCollection.Count"/>.</para>
+ </exception>
+ </member>
+ <member name="P:log4net.Appender.AppenderCollection.IsFixedSize">
+ <summary>
+ Gets a value indicating whether the collection has a fixed size.
+ </summary>
+ <value>true if the collection has a fixed size; otherwise, false. The default is false</value>
+ </member>
+ <member name="P:log4net.Appender.AppenderCollection.IsReadOnly">
+ <summary>
+ Gets a value indicating whether the IList is read-only.
+ </summary>
+ <value>true if the collection is read-only; otherwise, false. The default is false</value>
+ </member>
+ <member name="P:log4net.Appender.AppenderCollection.Capacity">
+ <summary>
+ Gets or sets the number of elements the <c>AppenderCollection</c> can contain.
+ </summary>
+ </member>
+ <member name="T:log4net.Appender.AppenderCollection.IAppenderCollectionEnumerator">
+ <summary>
+ Supports type-safe iteration over a <see cref="T:log4net.Appender.AppenderCollection"/>.
+ </summary>
+ <exclude/>
+ </member>
+ <member name="M:log4net.Appender.AppenderCollection.IAppenderCollectionEnumerator.MoveNext">
+ <summary>
+ Advances the enumerator to the next element in the collection.
+ </summary>
+ <returns>
+ <c>true</c> if the enumerator was successfully advanced to the next element;
+ <c>false</c> if the enumerator has passed the end of the collection.
+ </returns>
+ <exception cref="T:System.InvalidOperationException">
+ The collection was modified after the enumerator was created.
+ </exception>
+ </member>
+ <member name="M:log4net.Appender.AppenderCollection.IAppenderCollectionEnumerator.Reset">
+ <summary>
+ Sets the enumerator to its initial position, before the first element in the collection.
+ </summary>
+ </member>
+ <member name="P:log4net.Appender.AppenderCollection.IAppenderCollectionEnumerator.Current">
+ <summary>
+ Gets the current element in the collection.
+ </summary>
+ </member>
+ <member name="T:log4net.Appender.AppenderCollection.Tag">
+ <summary>
+ Type visible only to our subclasses
+ Used to access protected constructor
+ </summary>
+ <exclude/>
+ </member>
+ <member name="F:log4net.Appender.AppenderCollection.Tag.Default">
+ <summary>
+ A value
+ </summary>
+ </member>
+ <member name="T:log4net.Appender.AppenderCollection.Enumerator">
+ <summary>
+ Supports simple iteration over a <see cref="T:log4net.Appender.AppenderCollection"/>.
+ </summary>
+ <exclude/>
+ </member>
+ <member name="M:log4net.Appender.AppenderCollection.Enumerator.#ctor(log4net.Appender.AppenderCollection)">
+ <summary>
+ Initializes a new instance of the <c>Enumerator</c> class.
+ </summary>
+ <param name="tc"></param>
+ </member>
+ <member name="M:log4net.Appender.AppenderCollection.Enumerator.MoveNext">
+ <summary>
+ Advances the enumerator to the next element in the collection.
+ </summary>
+ <returns>
+ <c>true</c> if the enumerator was successfully advanced to the next element;
+ <c>false</c> if the enumerator has passed the end of the collection.
+ </returns>
+ <exception cref="T:System.InvalidOperationException">
+ The collection was modified after the enumerator was created.
+ </exception>
+ </member>
+ <member name="M:log4net.Appender.AppenderCollection.Enumerator.Reset">
+ <summary>
+ Sets the enumerator to its initial position, before the first element in the collection.
+ </summary>
+ </member>
+ <member name="P:log4net.Appender.AppenderCollection.Enumerator.Current">
+ <summary>
+ Gets the current element in the collection.
+ </summary>
+ </member>
+ <member name="T:log4net.Appender.AppenderCollection.ReadOnlyAppenderCollection">
+ <exclude/>
+ </member>
+ <member name="T:log4net.Appender.AspNetTraceAppender">
+ <summary>
+ <para>
+ Appends log events to the ASP.NET <see cref="T:System.Web.TraceContext"/> system.
+ </para>
+ </summary>
+ <remarks>
+ <para>
+ Diagnostic information and tracing messages that you specify are appended to the output
+ of the page that is sent to the requesting browser. Optionally, you can view this information
+ from a separate trace viewer (Trace.axd) that displays trace information for every page in a
+ given application.
+ </para>
+ <para>
+ Trace statements are processed and displayed only when tracing is enabled. You can control
+ whether tracing is displayed to a page, to the trace viewer, or both.
+ </para>
+ <para>
+ The logging event is passed to the <see cref="M:System.Web.TraceContext.Write(System.String)"/> or
+ <see cref="M:System.Web.TraceContext.Warn(System.String)"/> method depending on the level of the logging event.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="M:log4net.Appender.AspNetTraceAppender.#ctor">
+ <summary>
+ Initializes a new instance of the <see cref="T:log4net.Appender.AspNetTraceAppender"/> class.
+ </summary>
+ <remarks>
+ <para>
+ Default constructor.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.AspNetTraceAppender.Append(log4net.Core.LoggingEvent)">
+ <summary>
+ Write the logging event to the ASP.NET trace
+ </summary>
+ <param name="loggingEvent">the event to log</param>
+ <remarks>
+ <para>
+ Write the logging event to the ASP.NET trace
+ <c>HttpContext.Current.Trace</c>
+ (<see cref="T:System.Web.TraceContext"/>).
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.AspNetTraceAppender.RequiresLayout">
+ <summary>
+ This appender requires a <see cref="N:log4net.Layout"/> to be set.
+ </summary>
+ <value><c>true</c></value>
+ <remarks>
+ <para>
+ This appender requires a <see cref="N:log4net.Layout"/> to be set.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Appender.BufferingForwardingAppender">
+ <summary>
+ Buffers events and then forwards them to attached appenders.
+ </summary>
+ <remarks>
+ <para>
+ The events are buffered in this appender until conditions are
+ met to allow the appender to deliver the events to the attached
+ appenders. See <see cref="T:log4net.Appender.BufferingAppenderSkeleton"/> for the
+ conditions that cause the buffer to be sent.
+ </para>
+ <para>The forwarding appender can be used to specify different
+ thresholds and filters for the same appender at different locations
+ within the hierarchy.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="T:log4net.Core.IAppenderAttachable">
+ <summary>
+ Interface for attaching appenders to objects.
+ </summary>
+ <remarks>
+ <para>
+ Interface for attaching, removing and retrieving appenders.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="M:log4net.Core.IAppenderAttachable.AddAppender(log4net.Appender.IAppender)">
+ <summary>
+ Attaches an appender.
+ </summary>
+ <param name="appender">The appender to add.</param>
+ <remarks>
+ <para>
+ Add the specified appender. The implementation may
+ choose to allow or deny duplicate appenders.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.IAppenderAttachable.GetAppender(System.String)">
+ <summary>
+ Gets an attached appender with the specified name.
+ </summary>
+ <param name="name">The name of the appender to get.</param>
+ <returns>
+ The appender with the name specified, or <c>null</c> if no appender with the
+ specified name is found.
+ </returns>
+ <remarks>
+ <para>
+ Returns an attached appender with the <paramref name="name"/> specified.
+ If no appender with the specified name is found <c>null</c> will be
+ returned.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.IAppenderAttachable.RemoveAllAppenders">
+ <summary>
+ Removes all attached appenders.
+ </summary>
+ <remarks>
+ <para>
+ Removes and closes all attached appenders
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.IAppenderAttachable.RemoveAppender(log4net.Appender.IAppender)">
+ <summary>
+ Removes the specified appender from the list of attached appenders.
+ </summary>
+ <param name="appender">The appender to remove.</param>
+ <returns>The appender removed from the list</returns>
+ <remarks>
+ <para>
+ The appender removed is not closed.
+ If you are discarding the appender you must call
+ <see cref="M:log4net.Appender.IAppender.Close"/> on the appender removed.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.IAppenderAttachable.RemoveAppender(System.String)">
+ <summary>
+ Removes the appender with the specified name from the list of appenders.
+ </summary>
+ <param name="name">The name of the appender to remove.</param>
+ <returns>The appender removed from the list</returns>
+ <remarks>
+ <para>
+ The appender removed is not closed.
+ If you are discarding the appender you must call
+ <see cref="M:log4net.Appender.IAppender.Close"/> on the appender removed.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Core.IAppenderAttachable.Appenders">
+ <summary>
+ Gets all attached appenders.
+ </summary>
+ <value>
+ A collection of attached appenders.
+ </value>
+ <remarks>
+ <para>
+ Gets a collection of attached appenders.
+ If there are no attached appenders the
+ implementation should return an empty
+ collection rather than <c>null</c>.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.BufferingForwardingAppender.#ctor">
+ <summary>
+ Initializes a new instance of the <see cref="T:log4net.Appender.BufferingForwardingAppender"/> class.
+ </summary>
+ <remarks>
+ <para>
+ Default constructor.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.BufferingForwardingAppender.OnClose">
+ <summary>
+ Closes the appender and releases resources.
+ </summary>
+ <remarks>
+ <para>
+ Releases any resources allocated within the appender such as file handles,
+ network connections, etc.
+ </para>
+ <para>
+ It is a programming error to append to a closed appender.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.BufferingForwardingAppender.SendBuffer(log4net.Core.LoggingEvent[])">
+ <summary>
+ Send the events.
+ </summary>
+ <param name="events">The events that need to be send.</param>
+ <remarks>
+ <para>
+ Forwards the events to the attached appenders.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.BufferingForwardingAppender.AddAppender(log4net.Appender.IAppender)">
+ <summary>
+ Adds an <see cref="T:log4net.Appender.IAppender"/> to the list of appenders of this
+ instance.
+ </summary>
+ <param name="newAppender">The <see cref="T:log4net.Appender.IAppender"/> to add to this appender.</param>
+ <remarks>
+ <para>
+ If the specified <see cref="T:log4net.Appender.IAppender"/> is already in the list of
+ appenders, then it won't be added again.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.BufferingForwardingAppender.GetAppender(System.String)">
+ <summary>
+ Looks for the appender with the specified name.
+ </summary>
+ <param name="name">The name of the appender to lookup.</param>
+ <returns>
+ The appender with the specified name, or <c>null</c>.
+ </returns>
+ <remarks>
+ <para>
+ Get the named appender attached to this buffering appender.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.BufferingForwardingAppender.RemoveAllAppenders">
+ <summary>
+ Removes all previously added appenders from this appender.
+ </summary>
+ <remarks>
+ <para>
+ This is useful when re-reading configuration information.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.BufferingForwardingAppender.RemoveAppender(log4net.Appender.IAppender)">
+ <summary>
+ Removes the specified appender from the list of appenders.
+ </summary>
+ <param name="appender">The appender to remove.</param>
+ <returns>The appender removed from the list</returns>
+ <remarks>
+ The appender removed is not closed.
+ If you are discarding the appender you must call
+ <see cref="M:log4net.Appender.IAppender.Close"/> on the appender removed.
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.BufferingForwardingAppender.RemoveAppender(System.String)">
+ <summary>
+ Removes the appender with the specified name from the list of appenders.
+ </summary>
+ <param name="name">The name of the appender to remove.</param>
+ <returns>The appender removed from the list</returns>
+ <remarks>
+ The appender removed is not closed.
+ If you are discarding the appender you must call
+ <see cref="M:log4net.Appender.IAppender.Close"/> on the appender removed.
+ </remarks>
+ </member>
+ <member name="F:log4net.Appender.BufferingForwardingAppender.m_appenderAttachedImpl">
+ <summary>
+ Implementation of the <see cref="T:log4net.Core.IAppenderAttachable"/> interface
+ </summary>
+ </member>
+ <member name="P:log4net.Appender.BufferingForwardingAppender.Appenders">
+ <summary>
+ Gets the appenders contained in this appender as an
+ <see cref="T:System.Collections.ICollection"/>.
+ </summary>
+ <remarks>
+ If no appenders can be found, then an <see cref="T:log4net.Util.EmptyCollection"/>
+ is returned.
+ </remarks>
+ <returns>
+ A collection of the appenders in this appender.
+ </returns>
+ </member>
+ <member name="T:log4net.Appender.ColoredConsoleAppender">
+ <summary>
+ Appends logging events to the console.
+ </summary>
+ <remarks>
+ <para>
+ ColoredConsoleAppender appends log events to the standard output stream
+ or the error output stream using a layout specified by the
+ user. It also allows the color of a specific type of message to be set.
+ </para>
+ <para>
+ By default, all output is written to the console's standard output stream.
+ The <see cref="P:log4net.Appender.ColoredConsoleAppender.Target"/> property can be set to direct the output to the
+ error stream.
+ </para>
+ <para>
+ NOTE: This appender writes directly to the application's attached console
+ not to the <c>System.Console.Out</c> or <c>System.Console.Error</c> <c>TextWriter</c>.
+ The <c>System.Console.Out</c> and <c>System.Console.Error</c> streams can be
+ programmatically redirected (for example NUnit does this to capture program output).
+ This appender will ignore these redirections because it needs to use Win32
+ API calls to colorize the output. To respect these redirections the <see cref="T:log4net.Appender.ConsoleAppender"/>
+ must be used.
+ </para>
+ <para>
+ When configuring the colored console appender, mapping should be
+ specified to map a logging level to a color. For example:
+ </para>
+ <code lang="XML" escaped="true">
+ <mapping>
+ <level value="ERROR"/>
+ <foreColor value="White"/>
+ <backColor value="Red, HighIntensity"/>
+ </mapping>
+ <mapping>
+ <level value="DEBUG"/>
+ <backColor value="Green"/>
+ </mapping>
+ </code>
+ <para>
+ The Level is the standard log4net logging level and ForeColor and BackColor can be any
+ combination of the following values:
+ <list type="bullet">
+ <item><term>Blue</term><description></description></item>
+ <item><term>Green</term><description></description></item>
+ <item><term>Red</term><description></description></item>
+ <item><term>White</term><description></description></item>
+ <item><term>Yellow</term><description></description></item>
+ <item><term>Purple</term><description></description></item>
+ <item><term>Cyan</term><description></description></item>
+ <item><term>HighIntensity</term><description></description></item>
+ </list>
+ </para>
+ </remarks>
+ <author>Rick Hobbs</author>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="F:log4net.Appender.ColoredConsoleAppender.ConsoleOut">
+ <summary>
+ The <see cref="P:log4net.Appender.ColoredConsoleAppender.Target"/> to use when writing to the Console
+ standard output stream.
+ </summary>
+ <remarks>
+ <para>
+ The <see cref="P:log4net.Appender.ColoredConsoleAppender.Target"/> to use when writing to the Console
+ standard output stream.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Appender.ColoredConsoleAppender.ConsoleError">
+ <summary>
+ The <see cref="P:log4net.Appender.ColoredConsoleAppender.Target"/> to use when writing to the Console
+ standard error output stream.
+ </summary>
+ <remarks>
+ <para>
+ The <see cref="P:log4net.Appender.ColoredConsoleAppender.Target"/> to use when writing to the Console
+ standard error output stream.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.ColoredConsoleAppender.#ctor">
+ <summary>
+ Initializes a new instance of the <see cref="T:log4net.Appender.ColoredConsoleAppender"/> class.
+ </summary>
+ <remarks>
+ The instance of the <see cref="T:log4net.Appender.ColoredConsoleAppender"/> class is set up to write
+ to the standard output stream.
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.ColoredConsoleAppender.#ctor(log4net.Layout.ILayout)">
+ <summary>
+ Initializes a new instance of the <see cref="T:log4net.Appender.ColoredConsoleAppender"/> class
+ with the specified layout.
+ </summary>
+ <param name="layout">the layout to use for this appender</param>
+ <remarks>
+ The instance of the <see cref="T:log4net.Appender.ColoredConsoleAppender"/> class is set up to write
+ to the standard output stream.
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.ColoredConsoleAppender.#ctor(log4net.Layout.ILayout,System.Boolean)">
+ <summary>
+ Initializes a new instance of the <see cref="T:log4net.Appender.ColoredConsoleAppender"/> class
+ with the specified layout.
+ </summary>
+ <param name="layout">the layout to use for this appender</param>
+ <param name="writeToErrorStream">flag set to <c>true</c> to write to the console error stream</param>
+ <remarks>
+ When <paramref name="writeToErrorStream"/> is set to <c>true</c>, output is written to
+ the standard error output stream. Otherwise, output is written to the standard
+ output stream.
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.ColoredConsoleAppender.AddMapping(log4net.Appender.ColoredConsoleAppender.LevelColors)">
+ <summary>
+ Add a mapping of level to color - done by the config file
+ </summary>
+ <param name="mapping">The mapping to add</param>
+ <remarks>
+ <para>
+ Add a <see cref="T:log4net.Appender.ColoredConsoleAppender.LevelColors"/> mapping to this appender.
+ Each mapping defines the foreground and background colors
+ for a level.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.ColoredConsoleAppender.Append(log4net.Core.LoggingEvent)">
+ <summary>
+ This method is called by the <see cref="M:log4net.Appender.AppenderSkeleton.DoAppend(log4net.Core.LoggingEvent)"/> method.
+ </summary>
+ <param name="loggingEvent">The event to log.</param>
+ <remarks>
+ <para>
+ Writes the event to the console.
+ </para>
+ <para>
+ The format of the output will depend on the appender's layout.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.ColoredConsoleAppender.ActivateOptions">
+ <summary>
+ Initialize the options for this appender
+ </summary>
+ <remarks>
+ <para>
+ Initialize the level to color mappings set on this appender.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Appender.ColoredConsoleAppender.m_writeToErrorStream">
+ <summary>
+ Flag to write output to the error stream rather than the standard output stream
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.ColoredConsoleAppender.m_levelMapping">
+ <summary>
+ Mapping from level object to color value
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.ColoredConsoleAppender.m_consoleOutputWriter">
+ <summary>
+ The console output stream writer to write to
+ </summary>
+ <remarks>
+ <para>
+ This writer is not thread safe.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.ColoredConsoleAppender.Target">
+ <summary>
+ Target is the value of the console output stream.
+ This is either <c>"Console.Out"</c> or <c>"Console.Error"</c>.
+ </summary>
+ <value>
+ Target is the value of the console output stream.
+ This is either <c>"Console.Out"</c> or <c>"Console.Error"</c>.
+ </value>
+ <remarks>
+ <para>
+ Target is the value of the console output stream.
+ This is either <c>"Console.Out"</c> or <c>"Console.Error"</c>.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.ColoredConsoleAppender.RequiresLayout">
+ <summary>
+ This appender requires a <see cref="N:log4net.Layout"/> to be set.
+ </summary>
+ <value><c>true</c></value>
+ <remarks>
+ <para>
+ This appender requires a <see cref="N:log4net.Layout"/> to be set.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Appender.ColoredConsoleAppender.Colors">
+ <summary>
+ The enum of possible color values for use with the color mapping method
+ </summary>
+ <remarks>
+ <para>
+ The following flags can be combined together to
+ form the colors.
+ </para>
+ </remarks>
+ <seealso cref="T:log4net.Appender.ColoredConsoleAppender"/>
+ </member>
+ <member name="F:log4net.Appender.ColoredConsoleAppender.Colors.Blue">
+ <summary>
+ color is blue
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.ColoredConsoleAppender.Colors.Green">
+ <summary>
+ color is green
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.ColoredConsoleAppender.Colors.Red">
+ <summary>
+ color is red
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.ColoredConsoleAppender.Colors.White">
+ <summary>
+ color is white
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.ColoredConsoleAppender.Colors.Yellow">
+ <summary>
+ color is yellow
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.ColoredConsoleAppender.Colors.Purple">
+ <summary>
+ color is purple
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.ColoredConsoleAppender.Colors.Cyan">
+ <summary>
+ color is cyan
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.ColoredConsoleAppender.Colors.HighIntensity">
+ <summary>
+ color is intensified
+ </summary>
+ </member>
+ <member name="T:log4net.Appender.ColoredConsoleAppender.LevelColors">
+ <summary>
+ A class to act as a mapping between the level that a logging call is made at and
+ the color it should be displayed as.
+ </summary>
+ <remarks>
+ <para>
+ Defines the mapping between a level and the color it should be displayed in.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.ColoredConsoleAppender.LevelColors.ActivateOptions">
+ <summary>
+ Initialize the options for the object
+ </summary>
+ <remarks>
+ <para>
+ Combine the <see cref="P:log4net.Appender.ColoredConsoleAppender.LevelColors.ForeColor"/> and <see cref="P:log4net.Appender.ColoredConsoleAppender.LevelColors.BackColor"/> together.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.ColoredConsoleAppender.LevelColors.ForeColor">
+ <summary>
+ The mapped foreground color for the specified level
+ </summary>
+ <remarks>
+ <para>
+ Required property.
+ The mapped foreground color for the specified level.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.ColoredConsoleAppender.LevelColors.BackColor">
+ <summary>
+ The mapped background color for the specified level
+ </summary>
+ <remarks>
+ <para>
+ Required property.
+ The mapped background color for the specified level.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.ColoredConsoleAppender.LevelColors.CombinedColor">
+ <summary>
+ The combined <see cref="P:log4net.Appender.ColoredConsoleAppender.LevelColors.ForeColor"/> and <see cref="P:log4net.Appender.ColoredConsoleAppender.LevelColors.BackColor"/> suitable for
+ setting the console color.
+ </summary>
+ </member>
+ <member name="T:log4net.Appender.ConsoleAppender">
+ <summary>
+ Appends logging events to the console.
+ </summary>
+ <remarks>
+ <para>
+ ConsoleAppender appends log events to the standard output stream
+ or the error output stream using a layout specified by the
+ user.
+ </para>
+ <para>
+ By default, all output is written to the console's standard output stream.
+ The <see cref="P:log4net.Appender.ConsoleAppender.Target"/> property can be set to direct the output to the
+ error stream.
+ </para>
+ <para>
+ NOTE: This appender writes each message to the <c>System.Console.Out</c> or
+ <c>System.Console.Error</c> that is set at the time the event is appended.
+ Therefore it is possible to programmatically redirect the output of this appender
+ (for example NUnit does this to capture program output). While this is the desired
+ behavior of this appender it may have security implications in your application.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="F:log4net.Appender.ConsoleAppender.ConsoleOut">
+ <summary>
+ The <see cref="P:log4net.Appender.ConsoleAppender.Target"/> to use when writing to the Console
+ standard output stream.
+ </summary>
+ <remarks>
+ <para>
+ The <see cref="P:log4net.Appender.ConsoleAppender.Target"/> to use when writing to the Console
+ standard output stream.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Appender.ConsoleAppender.ConsoleError">
+ <summary>
+ The <see cref="P:log4net.Appender.ConsoleAppender.Target"/> to use when writing to the Console
+ standard error output stream.
+ </summary>
+ <remarks>
+ <para>
+ The <see cref="P:log4net.Appender.ConsoleAppender.Target"/> to use when writing to the Console
+ standard error output stream.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.ConsoleAppender.#ctor">
+ <summary>
+ Initializes a new instance of the <see cref="T:log4net.Appender.ConsoleAppender"/> class.
+ </summary>
+ <remarks>
+ The instance of the <see cref="T:log4net.Appender.ConsoleAppender"/> class is set up to write
+ to the standard output stream.
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.ConsoleAppender.#ctor(log4net.Layout.ILayout)">
+ <summary>
+ Initializes a new instance of the <see cref="T:log4net.Appender.ConsoleAppender"/> class
+ with the specified layout.
+ </summary>
+ <param name="layout">the layout to use for this appender</param>
+ <remarks>
+ The instance of the <see cref="T:log4net.Appender.ConsoleAppender"/> class is set up to write
+ to the standard output stream.
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.ConsoleAppender.#ctor(log4net.Layout.ILayout,System.Boolean)">
+ <summary>
+ Initializes a new instance of the <see cref="T:log4net.Appender.ConsoleAppender"/> class
+ with the specified layout.
+ </summary>
+ <param name="layout">the layout to use for this appender</param>
+ <param name="writeToErrorStream">flag set to <c>true</c> to write to the console error stream</param>
+ <remarks>
+ When <paramref name="writeToErrorStream"/> is set to <c>true</c>, output is written to
+ the standard error output stream. Otherwise, output is written to the standard
+ output stream.
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.ConsoleAppender.Append(log4net.Core.LoggingEvent)">
+ <summary>
+ This method is called by the <see cref="M:log4net.Appender.AppenderSkeleton.DoAppend(log4net.Core.LoggingEvent)"/> method.
+ </summary>
+ <param name="loggingEvent">The event to log.</param>
+ <remarks>
+ <para>
+ Writes the event to the console.
+ </para>
+ <para>
+ The format of the output will depend on the appender's layout.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.ConsoleAppender.Target">
+ <summary>
+ Target is the value of the console output stream.
+ This is either <c>"Console.Out"</c> or <c>"Console.Error"</c>.
+ </summary>
+ <value>
+ Target is the value of the console output stream.
+ This is either <c>"Console.Out"</c> or <c>"Console.Error"</c>.
+ </value>
+ <remarks>
+ <para>
+ Target is the value of the console output stream.
+ This is either <c>"Console.Out"</c> or <c>"Console.Error"</c>.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.ConsoleAppender.RequiresLayout">
+ <summary>
+ This appender requires a <see cref="N:log4net.Layout"/> to be set.
+ </summary>
+ <value><c>true</c></value>
+ <remarks>
+ <para>
+ This appender requires a <see cref="N:log4net.Layout"/> to be set.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Appender.DebugAppender">
+ <summary>
+ Appends log events to the <see cref="T:System.Diagnostics.Debug"/> system.
+ </summary>
+ <remarks>
+ <para>
+ The application configuration file can be used to control what listeners
+ are actually used. See the MSDN documentation for the
+ <see cref="T:System.Diagnostics.Debug"/> class for details on configuring the
+ debug system.
+ </para>
+ <para>
+ Events are written using the <see cref="M:System.Diagnostics.Debug.Write(System.String,System.String)"/>
+ method. The event's logger name is passed as the value for the category name to the Write method.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="M:log4net.Appender.DebugAppender.#ctor">
+ <summary>
+ Initializes a new instance of the <see cref="T:log4net.Appender.DebugAppender"/>.
+ </summary>
+ <remarks>
+ <para>
+ Default constructor.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.DebugAppender.#ctor(log4net.Layout.ILayout)">
+ <summary>
+ Initializes a new instance of the <see cref="T:log4net.Appender.DebugAppender"/>
+ with a specified layout.
+ </summary>
+ <param name="layout">The layout to use with this appender.</param>
+ <remarks>
+ <para>
+ Obsolete constructor.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.DebugAppender.Append(log4net.Core.LoggingEvent)">
+ <summary>
+ Writes the logging event to the <see cref="T:System.Diagnostics.Debug"/> system.
+ </summary>
+ <param name="loggingEvent">The event to log.</param>
+ <remarks>
+ <para>
+ Writes the logging event to the <see cref="T:System.Diagnostics.Debug"/> system.
+ If <see cref="P:log4net.Appender.DebugAppender.ImmediateFlush"/> is <c>true</c> then the <see cref="M:System.Diagnostics.Debug.Flush"/>
+ is called.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Appender.DebugAppender.m_immediateFlush">
+ <summary>
+ Immediate flush means that the underlying writer or output stream
+ will be flushed at the end of each append operation.
+ </summary>
+ <remarks>
+ <para>
+ Immediate flush is slower but ensures that each append request is
+ actually written. If <see cref="P:log4net.Appender.DebugAppender.ImmediateFlush"/> is set to
+ <c>false</c>, then there is a good chance that the last few
+ logs events are not actually written to persistent media if and
+ when the application crashes.
+ </para>
+ <para>
+ The default value is <c>true</c>.</para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.DebugAppender.ImmediateFlush">
+ <summary>
+ Gets or sets a value that indicates whether the appender will
+ flush at the end of each write.
+ </summary>
+ <remarks>
+ <para>The default behavior is to flush at the end of each
+ write. If the option is set to<c>false</c>, then the underlying
+ stream can defer writing to physical medium to a later time.
+ </para>
+ <para>
+ Avoiding the flush operation at the end of each append results
+ in a performance gain of 10 to 20 percent. However, there is safety
+ trade-off involved in skipping flushing. Indeed, when flushing is
+ skipped, then it is likely that the last few log events will not
+ be recorded on disk when the application exits. This is a high
+ price to pay even for a 20% performance gain.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.DebugAppender.RequiresLayout">
+ <summary>
+ This appender requires a <see cref="N:log4net.Layout"/> to be set.
+ </summary>
+ <value><c>true</c></value>
+ <remarks>
+ <para>
+ This appender requires a <see cref="N:log4net.Layout"/> to be set.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Appender.EventLogAppender">
+ <summary>
+ Writes events to the system event log.
+ </summary>
+ <remarks>
+ <para>
+ The <c>EventID</c> of the event log entry can be
+ set using the <c>EventLogEventID</c> property (<see cref="P:log4net.Core.LoggingEvent.Properties"/>)
+ on the <see cref="T:log4net.Core.LoggingEvent"/>.
+ </para>
+ <para>
+ There is a limit of 32K characters for an event log message
+ </para>
+ <para>
+ When configuring the EventLogAppender a mapping can be
+ specified to map a logging level to an event log entry type. For example:
+ </para>
+ <code lang="XML">
+ &lt;mapping&gt;
+ &lt;level value="ERROR" /&gt;
+ &lt;eventLogEntryType value="Error" /&gt;
+ &lt;/mapping&gt;
+ &lt;mapping&gt;
+ &lt;level value="DEBUG" /&gt;
+ &lt;eventLogEntryType value="Information" /&gt;
+ &lt;/mapping&gt;
+ </code>
+ <para>
+ The Level is the standard log4net logging level and eventLogEntryType can be any value
+ from the <see cref="T:System.Diagnostics.EventLogEntryType"/> enum, i.e.:
+ <list type="bullet">
+ <item><term>Error</term><description>an error event</description></item>
+ <item><term>Warning</term><description>a warning event</description></item>
+ <item><term>Information</term><description>an informational event</description></item>
+ </list>
+ </para>
+ </remarks>
+ <author>Aspi Havewala</author>
+ <author>Douglas de la Torre</author>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ <author>Thomas Voss</author>
+ </member>
+ <member name="M:log4net.Appender.EventLogAppender.#ctor">
+ <summary>
+ Initializes a new instance of the <see cref="T:log4net.Appender.EventLogAppender"/> class.
+ </summary>
+ <remarks>
+ <para>
+ Default constructor.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.EventLogAppender.#ctor(log4net.Layout.ILayout)">
+ <summary>
+ Initializes a new instance of the <see cref="T:log4net.Appender.EventLogAppender"/> class
+ with the specified <see cref="T:log4net.Layout.ILayout"/>.
+ </summary>
+ <param name="layout">The <see cref="T:log4net.Layout.ILayout"/> to use with this appender.</param>
+ <remarks>
+ <para>
+ Obsolete constructor.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.EventLogAppender.AddMapping(log4net.Appender.EventLogAppender.Level2EventLogEntryType)">
+ <summary>
+ Add a mapping of level to <see cref="T:System.Diagnostics.EventLogEntryType"/> - done by the config file
+ </summary>
+ <param name="mapping">The mapping to add</param>
+ <remarks>
+ <para>
+ Add a <see cref="T:log4net.Appender.EventLogAppender.Level2EventLogEntryType"/> mapping to this appender.
+ Each mapping defines the event log entry type for a level.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.EventLogAppender.ActivateOptions">
+ <summary>
+ Initialize the appender based on the options set
+ </summary>
+ <remarks>
+ <para>
+ This is part of the <see cref="T:log4net.Core.IOptionHandler"/> delayed object
+ activation scheme. The <see cref="M:log4net.Appender.EventLogAppender.ActivateOptions"/> method must
+ be called on this object after the configuration properties have
+ been set. Until <see cref="M:log4net.Appender.EventLogAppender.ActivateOptions"/> is called this
+ object is in an undefined state and must not be used.
+ </para>
+ <para>
+ If any of the configuration properties are modified then
+ <see cref="M:log4net.Appender.EventLogAppender.ActivateOptions"/> must be called again.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.EventLogAppender.CreateEventSource(System.String,System.String,System.String)">
+ <summary>
+ Create an event log source
+ </summary>
+ <remarks>
+ Uses different API calls under NET_2_0
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.EventLogAppender.Append(log4net.Core.LoggingEvent)">
+ <summary>
+ This method is called by the <see cref="M:log4net.Appender.AppenderSkeleton.DoAppend(log4net.Core.LoggingEvent)"/>
+ method.
+ </summary>
+ <param name="loggingEvent">the event to log</param>
+ <remarks>
+ <para>Writes the event to the system event log using the
+ <see cref="P:log4net.Appender.EventLogAppender.ApplicationName"/>.</para>
+
+ <para>If the event has an <c>EventID</c> property (see <see cref="P:log4net.Core.LoggingEvent.Properties"/>)
+ set then this integer will be used as the event log event id.</para>
+
+ <para>
+ There is a limit of 32K characters for an event log message
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.EventLogAppender.GetEntryType(log4net.Core.Level)">
+ <summary>
+ Get the equivalent <see cref="T:System.Diagnostics.EventLogEntryType"/> for a <see cref="T:log4net.Core.Level"/> <paramref name="p"/>
+ </summary>
+ <param name="level">the Level to convert to an EventLogEntryType</param>
+ <returns>The equivalent <see cref="T:System.Diagnostics.EventLogEntryType"/> for a <see cref="T:log4net.Core.Level"/> <paramref name="p"/></returns>
+ <remarks>
+ Because there are fewer applicable <see cref="T:System.Diagnostics.EventLogEntryType"/>
+ values to use in logging levels than there are in the
+ <see cref="T:log4net.Core.Level"/> this is a one way mapping. There is
+ a loss of information during the conversion.
+ </remarks>
+ </member>
+ <member name="F:log4net.Appender.EventLogAppender.m_logName">
+ <summary>
+ The log name is the section in the event logs where the messages
+ are stored.
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.EventLogAppender.m_applicationName">
+ <summary>
+ Name of the application to use when logging. This appears in the
+ application column of the event log named by <see cref="F:log4net.Appender.EventLogAppender.m_logName"/>.
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.EventLogAppender.m_machineName">
+ <summary>
+ The name of the machine which holds the event log. This is
+ currently only allowed to be '.' i.e. the current machine.
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.EventLogAppender.m_levelMapping">
+ <summary>
+ Mapping from level object to EventLogEntryType
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.EventLogAppender.m_securityContext">
+ <summary>
+ The security context to use for privileged calls
+ </summary>
+ </member>
+ <member name="P:log4net.Appender.EventLogAppender.LogName">
+ <summary>
+ The name of the log where messages will be stored.
+ </summary>
+ <value>
+ The string name of the log where messages will be stored.
+ </value>
+ <remarks>
+ <para>This is the name of the log as it appears in the Event Viewer
+ tree. The default value is to log into the <c>Application</c>
+ log, this is where most applications write their events. However
+ if you need a separate log for your application (or applications)
+ then you should set the <see cref="P:log4net.Appender.EventLogAppender.LogName"/> appropriately.</para>
+ <para>This should not be used to distinguish your event log messages
+ from those of other applications, the <see cref="P:log4net.Appender.EventLogAppender.ApplicationName"/>
+ property should be used to distinguish events. This property should be
+ used to group together events into a single log.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.EventLogAppender.ApplicationName">
+ <summary>
+ Property used to set the Application name. This appears in the
+ event logs when logging.
+ </summary>
+ <value>
+ The string used to distinguish events from different sources.
+ </value>
+ <remarks>
+ Sets the event log source property.
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.EventLogAppender.MachineName">
+ <summary>
+ This property is used to return the name of the computer to use
+ when accessing the event logs. Currently, this is the current
+ computer, denoted by a dot "."
+ </summary>
+ <value>
+ The string name of the machine holding the event log that
+ will be logged into.
+ </value>
+ <remarks>
+ This property cannot be changed. It is currently set to '.'
+ i.e. the local machine. This may be changed in future.
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.EventLogAppender.SecurityContext">
+ <summary>
+ Gets or sets the <see cref="P:log4net.Appender.EventLogAppender.SecurityContext"/> used to write to the EventLog.
+ </summary>
+ <value>
+ The <see cref="P:log4net.Appender.EventLogAppender.SecurityContext"/> used to write to the EventLog.
+ </value>
+ <remarks>
+ <para>
+ The system security context used to write to the EventLog.
+ </para>
+ <para>
+ Unless a <see cref="P:log4net.Appender.EventLogAppender.SecurityContext"/> specified here for this appender
+ the <see cref="P:log4net.Core.SecurityContextProvider.DefaultProvider"/> is queried for the
+ security context to use. The default behavior is to use the security context
+ of the current thread.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.EventLogAppender.RequiresLayout">
+ <summary>
+ This appender requires a <see cref="N:log4net.Layout"/> to be set.
+ </summary>
+ <value><c>true</c></value>
+ <remarks>
+ <para>
+ This appender requires a <see cref="N:log4net.Layout"/> to be set.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Appender.EventLogAppender.Level2EventLogEntryType">
+ <summary>
+ A class to act as a mapping between the level that a logging call is made at and
+ the color it should be displayed as.
+ </summary>
+ <remarks>
+ <para>
+ Defines the mapping between a level and its event log entry type.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.EventLogAppender.Level2EventLogEntryType.EventLogEntryType">
+ <summary>
+ The <see cref="P:log4net.Appender.EventLogAppender.Level2EventLogEntryType.EventLogEntryType"/> for this entry
+ </summary>
+ <remarks>
+ <para>
+ Required property.
+ The <see cref="P:log4net.Appender.EventLogAppender.Level2EventLogEntryType.EventLogEntryType"/> for this entry
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Appender.FileAppender">
+ <summary>
+ Appends logging events to a file.
+ </summary>
+ <remarks>
+ <para>
+ Logging events are sent to the file specified by
+ the <see cref="P:log4net.Appender.FileAppender.File"/> property.
+ </para>
+ <para>
+ The file can be opened in either append or overwrite mode
+ by specifying the <see cref="P:log4net.Appender.FileAppender.AppendToFile"/> property.
+ If the file path is relative it is taken as relative from
+ the application base directory. The file encoding can be
+ specified by setting the <see cref="P:log4net.Appender.FileAppender.Encoding"/> property.
+ </para>
+ <para>
+ The layout's <see cref="P:log4net.Layout.ILayout.Header"/> and <see cref="P:log4net.Layout.ILayout.Footer"/>
+ values will be written each time the file is opened and closed
+ respectively. If the <see cref="P:log4net.Appender.FileAppender.AppendToFile"/> property is <see langword="true"/>
+ then the file may contain multiple copies of the header and footer.
+ </para>
+ <para>
+ This appender will first try to open the file for writing when <see cref="M:log4net.Appender.FileAppender.ActivateOptions"/>
+ is called. This will typically be during configuration.
+ If the file cannot be opened for writing the appender will attempt
+ to open the file again each time a message is logged to the appender.
+ If the file cannot be opened for writing when a message is logged then
+ the message will be discarded by this appender.
+ </para>
+ <para>
+ The <see cref="T:log4net.Appender.FileAppender"/> supports pluggable file locking models via
+ the <see cref="P:log4net.Appender.FileAppender.LockingModel"/> property.
+ The default behavior, implemented by <see cref="T:log4net.Appender.FileAppender.ExclusiveLock"/>
+ is to obtain an exclusive write lock on the file until this appender is closed.
+ The alternative model, <see cref="T:log4net.Appender.FileAppender.MinimalLock"/>, only holds a
+ write lock while the appender is writing a logging event.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ <author>Rodrigo B. de Oliveira</author>
+ <author>Douglas de la Torre</author>
+ <author>Niall Daley</author>
+ </member>
+ <member name="T:log4net.Appender.TextWriterAppender">
+ <summary>
+ Sends logging events to a <see cref="T:System.IO.TextWriter"/>.
+ </summary>
+ <remarks>
+ <para>
+ An Appender that writes to a <see cref="T:System.IO.TextWriter"/>.
+ </para>
+ <para>
+ This appender may be used stand alone if initialized with an appropriate
+ writer, however it is typically used as a base class for an appender that
+ can open a <see cref="T:System.IO.TextWriter"/> to write to.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ <author>Douglas de la Torre</author>
+ </member>
+ <member name="M:log4net.Appender.TextWriterAppender.#ctor">
+ <summary>
+ Initializes a new instance of the <see cref="T:log4net.Appender.TextWriterAppender"/> class.
+ </summary>
+ <remarks>
+ <para>
+ Default constructor.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.TextWriterAppender.#ctor(log4net.Layout.ILayout,System.IO.Stream)">
+ <summary>
+ Initializes a new instance of the <see cref="T:log4net.Appender.TextWriterAppender"/> class and
+ sets the output destination to a new <see cref="T:System.IO.StreamWriter"/> initialized
+ with the specified <see cref="T:System.IO.Stream"/>.
+ </summary>
+ <param name="layout">The layout to use with this appender.</param>
+ <param name="os">The <see cref="T:System.IO.Stream"/> to output to.</param>
+ <remarks>
+ <para>
+ Obsolete constructor.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.TextWriterAppender.#ctor(log4net.Layout.ILayout,System.IO.TextWriter)">
+ <summary>
+ Initializes a new instance of the <see cref="T:log4net.Appender.TextWriterAppender"/> class and sets
+ the output destination to the specified <see cref="T:System.IO.StreamWriter"/>.
+ </summary>
+ <param name="layout">The layout to use with this appender</param>
+ <param name="writer">The <see cref="T:System.IO.TextWriter"/> to output to</param>
+ <remarks>
+ The <see cref="T:System.IO.TextWriter"/> must have been previously opened.
+ </remarks>
+ <remarks>
+ <para>
+ Obsolete constructor.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.TextWriterAppender.PreAppendCheck">
+ <summary>
+ This method determines if there is a sense in attempting to append.
+ </summary>
+ <remarks>
+ <para>
+ This method checked if an output target has been set and if a
+ layout has been set.
+ </para>
+ </remarks>
+ <returns><c>false</c> if any of the preconditions fail.</returns>
+ </member>
+ <member name="M:log4net.Appender.TextWriterAppender.Append(log4net.Core.LoggingEvent)">
+ <summary>
+ This method is called by the <see cref="M:log4net.Appender.AppenderSkeleton.DoAppend(log4net.Core.LoggingEvent)"/>
+ method.
+ </summary>
+ <param name="loggingEvent">The event to log.</param>
+ <remarks>
+ <para>
+ Writes a log statement to the output stream if the output stream exists
+ and is writable.
+ </para>
+ <para>
+ The format of the output will depend on the appender's layout.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.TextWriterAppender.Append(log4net.Core.LoggingEvent[])">
+ <summary>
+ This method is called by the <see cref="M:log4net.Appender.AppenderSkeleton.DoAppend(log4net.Core.LoggingEvent[])"/>
+ method.
+ </summary>
+ <param name="loggingEvents">The array of events to log.</param>
+ <remarks>
+ <para>
+ This method writes all the bulk logged events to the output writer
+ before flushing the stream.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.TextWriterAppender.OnClose">
+ <summary>
+ Close this appender instance. The underlying stream or writer is also closed.
+ </summary>
+ <remarks>
+ Closed appenders cannot be reused.
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.TextWriterAppender.WriteFooterAndCloseWriter">
+ <summary>
+ Writes the footer and closes the underlying <see cref="T:System.IO.TextWriter"/>.
+ </summary>
+ <remarks>
+ <para>
+ Writes the footer and closes the underlying <see cref="T:System.IO.TextWriter"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.TextWriterAppender.CloseWriter">
+ <summary>
+ Closes the underlying <see cref="T:System.IO.TextWriter"/>.
+ </summary>
+ <remarks>
+ <para>
+ Closes the underlying <see cref="T:System.IO.TextWriter"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.TextWriterAppender.Reset">
+ <summary>
+ Clears internal references to the underlying <see cref="T:System.IO.TextWriter"/>
+ and other variables.
+ </summary>
+ <remarks>
+ <para>
+ Subclasses can override this method for an alternate closing behavior.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.TextWriterAppender.WriteFooter">
+ <summary>
+ Writes a footer as produced by the embedded layout's <see cref="P:log4net.Layout.ILayout.Footer"/> property.
+ </summary>
+ <remarks>
+ <para>
+ Writes a footer as produced by the embedded layout's <see cref="P:log4net.Layout.ILayout.Footer"/> property.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.TextWriterAppender.WriteHeader">
+ <summary>
+ Writes a header produced by the embedded layout's <see cref="P:log4net.Layout.ILayout.Header"/> property.
+ </summary>
+ <remarks>
+ <para>
+ Writes a header produced by the embedded layout's <see cref="P:log4net.Layout.ILayout.Header"/> property.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.TextWriterAppender.PrepareWriter">
+ <summary>
+ Called to allow a subclass to lazily initialize the writer
+ </summary>
+ <remarks>
+ <para>
+ This method is called when an event is logged and the <see cref="P:log4net.Appender.TextWriterAppender.Writer"/> or
+ <see cref="P:log4net.Appender.TextWriterAppender.QuietWriter"/> have not been set. This allows a subclass to
+ attempt to initialize the writer multiple times.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Appender.TextWriterAppender.m_qtw">
+ <summary>
+ This is the <see cref="T:log4net.Util.QuietTextWriter"/> where logging events
+ will be written to.
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.TextWriterAppender.m_immediateFlush">
+ <summary>
+ Immediate flush means that the underlying <see cref="T:System.IO.TextWriter"/>
+ or output stream will be flushed at the end of each append operation.
+ </summary>
+ <remarks>
+ <para>
+ Immediate flush is slower but ensures that each append request is
+ actually written. If <see cref="P:log4net.Appender.TextWriterAppender.ImmediateFlush"/> is set to
+ <c>false</c>, then there is a good chance that the last few
+ logging events are not actually persisted if and when the application
+ crashes.
+ </para>
+ <para>
+ The default value is <c>true</c>.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.TextWriterAppender.ImmediateFlush">
+ <summary>
+ Gets or set whether the appender will flush at the end
+ of each append operation.
+ </summary>
+ <value>
+ <para>
+ The default behavior is to flush at the end of each
+ append operation.
+ </para>
+ <para>
+ If this option is set to <c>false</c>, then the underlying
+ stream can defer persisting the logging event to a later
+ time.
+ </para>
+ </value>
+ <remarks>
+ Avoiding the flush operation at the end of each append results in
+ a performance gain of 10 to 20 percent. However, there is safety
+ trade-off involved in skipping flushing. Indeed, when flushing is
+ skipped, then it is likely that the last few log events will not
+ be recorded on disk when the application exits. This is a high
+ price to pay even for a 20% performance gain.
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.TextWriterAppender.Writer">
+ <summary>
+ Sets the <see cref="T:System.IO.TextWriter"/> where the log output will go.
+ </summary>
+ <remarks>
+ <para>
+ The specified <see cref="T:System.IO.TextWriter"/> must be open and writable.
+ </para>
+ <para>
+ The <see cref="T:System.IO.TextWriter"/> will be closed when the appender
+ instance is closed.
+ </para>
+ <para>
+ <b>Note:</b> Logging to an unopened <see cref="T:System.IO.TextWriter"/> will fail.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.TextWriterAppender.ErrorHandler">
+ <summary>
+ Gets or set the <see cref="T:log4net.Core.IErrorHandler"/> and the underlying
+ <see cref="T:log4net.Util.QuietTextWriter"/>, if any, for this appender.
+ </summary>
+ <value>
+ The <see cref="T:log4net.Core.IErrorHandler"/> for this appender.
+ </value>
+ </member>
+ <member name="P:log4net.Appender.TextWriterAppender.RequiresLayout">
+ <summary>
+ This appender requires a <see cref="N:log4net.Layout"/> to be set.
+ </summary>
+ <value><c>true</c></value>
+ <remarks>
+ <para>
+ This appender requires a <see cref="N:log4net.Layout"/> to be set.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.TextWriterAppender.QuietWriter">
+ <summary>
+ Gets or sets the <see cref="T:log4net.Util.QuietTextWriter"/> where logging events
+ will be written to.
+ </summary>
+ <value>
+ The <see cref="T:log4net.Util.QuietTextWriter"/> where logging events are written.
+ </value>
+ <remarks>
+ <para>
+ This is the <see cref="T:log4net.Util.QuietTextWriter"/> where logging events
+ will be written to.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.FileAppender.#ctor">
+ <summary>
+ Default constructor
+ </summary>
+ <remarks>
+ <para>
+ Default constructor
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.FileAppender.#ctor(log4net.Layout.ILayout,System.String,System.Boolean)">
+ <summary>
+ Construct a new appender using the layout, file and append mode.
+ </summary>
+ <param name="layout">the layout to use with this appender</param>
+ <param name="filename">the full path to the file to write to</param>
+ <param name="append">flag to indicate if the file should be appended to</param>
+ <remarks>
+ <para>
+ Obsolete constructor.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.FileAppender.#ctor(log4net.Layout.ILayout,System.String)">
+ <summary>
+ Construct a new appender using the layout and file specified.
+ The file will be appended to.
+ </summary>
+ <param name="layout">the layout to use with this appender</param>
+ <param name="filename">the full path to the file to write to</param>
+ <remarks>
+ <para>
+ Obsolete constructor.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.FileAppender.ActivateOptions">
+ <summary>
+ Activate the options on the file appender.
+ </summary>
+ <remarks>
+ <para>
+ This is part of the <see cref="T:log4net.Core.IOptionHandler"/> delayed object
+ activation scheme. The <see cref="M:log4net.Appender.FileAppender.ActivateOptions"/> method must
+ be called on this object after the configuration properties have
+ been set. Until <see cref="M:log4net.Appender.FileAppender.ActivateOptions"/> is called this
+ object is in an undefined state and must not be used.
+ </para>
+ <para>
+ If any of the configuration properties are modified then
+ <see cref="M:log4net.Appender.FileAppender.ActivateOptions"/> must be called again.
+ </para>
+ <para>
+ This will cause the file to be opened.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.FileAppender.Reset">
+ <summary>
+ Closes any previously opened file and calls the parent's <see cref="M:log4net.Appender.TextWriterAppender.Reset"/>.
+ </summary>
+ <remarks>
+ <para>
+ Resets the filename and the file stream.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.FileAppender.PrepareWriter">
+ <summary>
+ Called to initialize the file writer
+ </summary>
+ <remarks>
+ <para>
+ Will be called for each logged message until the file is
+ successfully opened.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.FileAppender.Append(log4net.Core.LoggingEvent)">
+ <summary>
+ This method is called by the <see cref="M:log4net.Appender.AppenderSkeleton.DoAppend(log4net.Core.LoggingEvent)"/>
+ method.
+ </summary>
+ <param name="loggingEvent">The event to log.</param>
+ <remarks>
+ <para>
+ Writes a log statement to the output stream if the output stream exists
+ and is writable.
+ </para>
+ <para>
+ The format of the output will depend on the appender's layout.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.FileAppender.Append(log4net.Core.LoggingEvent[])">
+ <summary>
+ This method is called by the <see cref="M:log4net.Appender.AppenderSkeleton.DoAppend(log4net.Core.LoggingEvent[])"/>
+ method.
+ </summary>
+ <param name="loggingEvents">The array of events to log.</param>
+ <remarks>
+ <para>
+ Acquires the output file locks once before writing all the events to
+ the stream.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.FileAppender.WriteFooter">
+ <summary>
+ Writes a footer as produced by the embedded layout's <see cref="P:log4net.Layout.ILayout.Footer"/> property.
+ </summary>
+ <remarks>
+ <para>
+ Writes a footer as produced by the embedded layout's <see cref="P:log4net.Layout.ILayout.Footer"/> property.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.FileAppender.WriteHeader">
+ <summary>
+ Writes a header produced by the embedded layout's <see cref="P:log4net.Layout.ILayout.Header"/> property.
+ </summary>
+ <remarks>
+ <para>
+ Writes a header produced by the embedded layout's <see cref="P:log4net.Layout.ILayout.Header"/> property.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.FileAppender.CloseWriter">
+ <summary>
+ Closes the underlying <see cref="T:System.IO.TextWriter"/>.
+ </summary>
+ <remarks>
+ <para>
+ Closes the underlying <see cref="T:System.IO.TextWriter"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.FileAppender.CloseFile">
+ <summary>
+ Closes the previously opened file.
+ </summary>
+ <remarks>
+ <para>
+ Writes the <see cref="P:log4net.Layout.ILayout.Footer"/> to the file and then
+ closes the file.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.FileAppender.SafeOpenFile(System.String,System.Boolean)">
+ <summary>
+ Sets and <i>opens</i> the file where the log output will go. The specified file must be writable.
+ </summary>
+ <param name="fileName">The path to the log file. Must be a fully qualified path.</param>
+ <param name="append">If true will append to fileName. Otherwise will truncate fileName</param>
+ <remarks>
+ <para>
+ Calls <see cref="M:log4net.Appender.FileAppender.OpenFile(System.String,System.Boolean)"/> but guarantees not to throw an exception.
+ Errors are passed to the <see cref="P:log4net.Appender.TextWriterAppender.ErrorHandler"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.FileAppender.OpenFile(System.String,System.Boolean)">
+ <summary>
+ Sets and <i>opens</i> the file where the log output will go. The specified file must be writable.
+ </summary>
+ <param name="fileName">The path to the log file. Must be a fully qualified path.</param>
+ <param name="append">If true will append to fileName. Otherwise will truncate fileName</param>
+ <remarks>
+ <para>
+ If there was already an opened file, then the previous file
+ is closed first.
+ </para>
+ <para>
+ This method will ensure that the directory structure
+ for the <paramref name="fileName"/> specified exists.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.FileAppender.SetQWForFiles(System.IO.Stream)">
+ <summary>
+ Sets the quiet writer used for file output
+ </summary>
+ <param name="fileStream">the file stream that has been opened for writing</param>
+ <remarks>
+ <para>
+ This implementation of <see cref="M:log4net.Appender.FileAppender.SetQWForFiles(System.IO.Stream)"/> creates a <see cref="T:System.IO.StreamWriter"/>
+ over the <paramref name="fileStream"/> and passes it to the
+ <see cref="M:log4net.Appender.FileAppender.SetQWForFiles(System.IO.TextWriter)"/> method.
+ </para>
+ <para>
+ This method can be overridden by sub classes that want to wrap the
+ <see cref="T:System.IO.Stream"/> in some way, for example to encrypt the output
+ data using a <c>System.Security.Cryptography.CryptoStream</c>.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.FileAppender.SetQWForFiles(System.IO.TextWriter)">
+ <summary>
+ Sets the quiet writer being used.
+ </summary>
+ <param name="writer">the writer over the file stream that has been opened for writing</param>
+ <remarks>
+ <para>
+ This method can be overridden by sub classes that want to
+ wrap the <see cref="T:System.IO.TextWriter"/> in some way.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.FileAppender.ConvertToFullPath(System.String)">
+ <summary>
+ Convert a path into a fully qualified path.
+ </summary>
+ <param name="path">The path to convert.</param>
+ <returns>The fully qualified path.</returns>
+ <remarks>
+ <para>
+ Converts the path specified to a fully
+ qualified path. If the path is relative it is
+ taken as relative from the application base
+ directory.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Appender.FileAppender.m_appendToFile">
+ <summary>
+ Flag to indicate if we should append to the file
+ or overwrite the file. The default is to append.
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.FileAppender.m_fileName">
+ <summary>
+ The name of the log file.
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.FileAppender.m_encoding">
+ <summary>
+ The encoding to use for the file stream.
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.FileAppender.m_securityContext">
+ <summary>
+ The security context to use for privileged calls
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.FileAppender.m_stream">
+ <summary>
+ The stream to log to. Has added locking semantics
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.FileAppender.m_lockingModel">
+ <summary>
+ The locking model to use
+ </summary>
+ </member>
+ <member name="P:log4net.Appender.FileAppender.File">
+ <summary>
+ Gets or sets the path to the file that logging will be written to.
+ </summary>
+ <value>
+ The path to the file that logging will be written to.
+ </value>
+ <remarks>
+ <para>
+ If the path is relative it is taken as relative from
+ the application base directory.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.FileAppender.AppendToFile">
+ <summary>
+ Gets or sets a flag that indicates whether the file should be
+ appended to or overwritten.
+ </summary>
+ <value>
+ Indicates whether the file should be appended to or overwritten.
+ </value>
+ <remarks>
+ <para>
+ If the value is set to false then the file will be overwritten, if
+ it is set to true then the file will be appended to.
+ </para>
+ The default value is true.
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.FileAppender.Encoding">
+ <summary>
+ Gets or sets <see cref="P:log4net.Appender.FileAppender.Encoding"/> used to write to the file.
+ </summary>
+ <value>
+ The <see cref="P:log4net.Appender.FileAppender.Encoding"/> used to write to the file.
+ </value>
+ <remarks>
+ <para>
+ The default encoding set is <see cref="P:System.Text.Encoding.Default"/>
+ which is the encoding for the system's current ANSI code page.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.FileAppender.SecurityContext">
+ <summary>
+ Gets or sets the <see cref="P:log4net.Appender.FileAppender.SecurityContext"/> used to write to the file.
+ </summary>
+ <value>
+ The <see cref="P:log4net.Appender.FileAppender.SecurityContext"/> used to write to the file.
+ </value>
+ <remarks>
+ <para>
+ Unless a <see cref="P:log4net.Appender.FileAppender.SecurityContext"/> specified here for this appender
+ the <see cref="P:log4net.Core.SecurityContextProvider.DefaultProvider"/> is queried for the
+ security context to use. The default behavior is to use the security context
+ of the current thread.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.FileAppender.LockingModel">
+ <summary>
+ Gets or sets the <see cref="P:log4net.Appender.FileAppender.LockingModel"/> used to handle locking of the file.
+ </summary>
+ <value>
+ The <see cref="P:log4net.Appender.FileAppender.LockingModel"/> used to lock the file.
+ </value>
+ <remarks>
+ <para>
+ Gets or sets the <see cref="P:log4net.Appender.FileAppender.LockingModel"/> used to handle locking of the file.
+ </para>
+ <para>
+ There are two built in locking models, <see cref="T:log4net.Appender.FileAppender.ExclusiveLock"/> and <see cref="T:log4net.Appender.FileAppender.MinimalLock"/>.
+ The former locks the file from the start of logging to the end and the
+ later lock only for the minimal amount of time when logging each message.
+ </para>
+ <para>
+ The default locking model is the <see cref="T:log4net.Appender.FileAppender.ExclusiveLock"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Appender.FileAppender.LockingStream">
+ <summary>
+ Write only <see cref="T:System.IO.Stream"/> that uses the <see cref="T:log4net.Appender.FileAppender.LockingModelBase"/>
+ to manage access to an underlying resource.
+ </summary>
+ </member>
+ <member name="M:log4net.Appender.FileAppender.LockingStream.BeginWrite(System.Byte[],System.Int32,System.Int32,System.AsyncCallback,System.Object)">
+ <summary>
+ True asynchronous writes are not supported, the implementation forces a synchronous write.
+ </summary>
+ </member>
+ <member name="T:log4net.Core.LogException">
+ <summary>
+ Exception base type for log4net.
+ </summary>
+ <remarks>
+ <para>
+ This type extends <see cref="T:System.ApplicationException"/>. It
+ does not add any new functionality but does differentiate the
+ type of exception being thrown.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="M:log4net.Core.LogException.#ctor">
+ <summary>
+ Constructor
+ </summary>
+ <remarks>
+ <para>
+ Initializes a new instance of the <see cref="T:log4net.Core.LogException"/> class.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LogException.#ctor(System.String)">
+ <summary>
+ Constructor
+ </summary>
+ <param name="message">A message to include with the exception.</param>
+ <remarks>
+ <para>
+ Initializes a new instance of the <see cref="T:log4net.Core.LogException"/> class with
+ the specified message.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LogException.#ctor(System.String,System.Exception)">
+ <summary>
+ Constructor
+ </summary>
+ <param name="message">A message to include with the exception.</param>
+ <param name="innerException">A nested exception to include.</param>
+ <remarks>
+ <para>
+ Initializes a new instance of the <see cref="T:log4net.Core.LogException"/> class
+ with the specified message and inner exception.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LogException.#ctor(System.Runtime.Serialization.SerializationInfo,System.Runtime.Serialization.StreamingContext)">
+ <summary>
+ Serialization constructor
+ </summary>
+ <param name="info">The <see cref="T:System.Runtime.Serialization.SerializationInfo"/> that holds the serialized object data about the exception being thrown.</param>
+ <param name="context">The <see cref="T:System.Runtime.Serialization.StreamingContext"/> that contains contextual information about the source or destination.</param>
+ <remarks>
+ <para>
+ Initializes a new instance of the <see cref="T:log4net.Core.LogException"/> class
+ with serialized data.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Appender.FileAppender.LockingModelBase">
+ <summary>
+ Locking model base class
+ </summary>
+ <remarks>
+ <para>
+ Base class for the locking models available to the <see cref="T:log4net.Appender.FileAppender"/> derived loggers.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.FileAppender.LockingModelBase.OpenFile(System.String,System.Boolean,System.Text.Encoding)">
+ <summary>
+ Open the output file
+ </summary>
+ <param name="filename">The filename to use</param>
+ <param name="append">Whether to append to the file, or overwrite</param>
+ <param name="encoding">The encoding to use</param>
+ <remarks>
+ <para>
+ Open the file specified and prepare for logging.
+ No writes will be made until <see cref="M:log4net.Appender.FileAppender.LockingModelBase.AcquireLock"/> is called.
+ Must be called before any calls to <see cref="M:log4net.Appender.FileAppender.LockingModelBase.AcquireLock"/>,
+ <see cref="M:log4net.Appender.FileAppender.LockingModelBase.ReleaseLock"/> and <see cref="M:log4net.Appender.FileAppender.LockingModelBase.CloseFile"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.FileAppender.LockingModelBase.CloseFile">
+ <summary>
+ Close the file
+ </summary>
+ <remarks>
+ <para>
+ Close the file. No further writes will be made.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.FileAppender.LockingModelBase.AcquireLock">
+ <summary>
+ Acquire the lock on the file
+ </summary>
+ <returns>A stream that is ready to be written to.</returns>
+ <remarks>
+ <para>
+ Acquire the lock on the file in preparation for writing to it.
+ Return a stream pointing to the file. <see cref="M:log4net.Appender.FileAppender.LockingModelBase.ReleaseLock"/>
+ must be called to release the lock on the output file.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.FileAppender.LockingModelBase.ReleaseLock">
+ <summary>
+ Release the lock on the file
+ </summary>
+ <remarks>
+ <para>
+ Release the lock on the file. No further writes will be made to the
+ stream until <see cref="M:log4net.Appender.FileAppender.LockingModelBase.AcquireLock"/> is called again.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.FileAppender.LockingModelBase.CurrentAppender">
+ <summary>
+ Gets or sets the <see cref="T:log4net.Appender.FileAppender"/> for this LockingModel
+ </summary>
+ <value>
+ The <see cref="T:log4net.Appender.FileAppender"/> for this LockingModel
+ </value>
+ <remarks>
+ <para>
+ The file appender this locking model is attached to and working on
+ behalf of.
+ </para>
+ <para>
+ The file appender is used to locate the security context and the error handler to use.
+ </para>
+ <para>
+ The value of this property will be set before <see cref="M:log4net.Appender.FileAppender.LockingModelBase.OpenFile(System.String,System.Boolean,System.Text.Encoding)"/> is
+ called.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Appender.FileAppender.ExclusiveLock">
+ <summary>
+ Hold an exclusive lock on the output file
+ </summary>
+ <remarks>
+ <para>
+ Open the file once for writing and hold it open until <see cref="M:log4net.Appender.FileAppender.ExclusiveLock.CloseFile"/> is called.
+ Maintains an exclusive lock on the file during this time.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.FileAppender.ExclusiveLock.OpenFile(System.String,System.Boolean,System.Text.Encoding)">
+ <summary>
+ Open the file specified and prepare for logging.
+ </summary>
+ <param name="filename">The filename to use</param>
+ <param name="append">Whether to append to the file, or overwrite</param>
+ <param name="encoding">The encoding to use</param>
+ <remarks>
+ <para>
+ Open the file specified and prepare for logging.
+ No writes will be made until <see cref="M:log4net.Appender.FileAppender.ExclusiveLock.AcquireLock"/> is called.
+ Must be called before any calls to <see cref="M:log4net.Appender.FileAppender.ExclusiveLock.AcquireLock"/>,
+ <see cref="M:log4net.Appender.FileAppender.ExclusiveLock.ReleaseLock"/> and <see cref="M:log4net.Appender.FileAppender.ExclusiveLock.CloseFile"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.FileAppender.ExclusiveLock.CloseFile">
+ <summary>
+ Close the file
+ </summary>
+ <remarks>
+ <para>
+ Close the file. No further writes will be made.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.FileAppender.ExclusiveLock.AcquireLock">
+ <summary>
+ Acquire the lock on the file
+ </summary>
+ <returns>A stream that is ready to be written to.</returns>
+ <remarks>
+ <para>
+ Does nothing. The lock is already taken
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.FileAppender.ExclusiveLock.ReleaseLock">
+ <summary>
+ Release the lock on the file
+ </summary>
+ <remarks>
+ <para>
+ Does nothing. The lock will be released when the file is closed.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Appender.FileAppender.MinimalLock">
+ <summary>
+ Acquires the file lock for each write
+ </summary>
+ <remarks>
+ <para>
+ Opens the file once for each <see cref="M:log4net.Appender.FileAppender.MinimalLock.AcquireLock"/>/<see cref="M:log4net.Appender.FileAppender.MinimalLock.ReleaseLock"/> cycle,
+ thus holding the lock for the minimal amount of time. This method of locking
+ is considerably slower than <see cref="T:log4net.Appender.FileAppender.ExclusiveLock"/> but allows
+ other processes to move/delete the log file whilst logging continues.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.FileAppender.MinimalLock.OpenFile(System.String,System.Boolean,System.Text.Encoding)">
+ <summary>
+ Prepares to open the file when the first message is logged.
+ </summary>
+ <param name="filename">The filename to use</param>
+ <param name="append">Whether to append to the file, or overwrite</param>
+ <param name="encoding">The encoding to use</param>
+ <remarks>
+ <para>
+ Open the file specified and prepare for logging.
+ No writes will be made until <see cref="M:log4net.Appender.FileAppender.MinimalLock.AcquireLock"/> is called.
+ Must be called before any calls to <see cref="M:log4net.Appender.FileAppender.MinimalLock.AcquireLock"/>,
+ <see cref="M:log4net.Appender.FileAppender.MinimalLock.ReleaseLock"/> and <see cref="M:log4net.Appender.FileAppender.MinimalLock.CloseFile"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.FileAppender.MinimalLock.CloseFile">
+ <summary>
+ Close the file
+ </summary>
+ <remarks>
+ <para>
+ Close the file. No further writes will be made.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.FileAppender.MinimalLock.AcquireLock">
+ <summary>
+ Acquire the lock on the file
+ </summary>
+ <returns>A stream that is ready to be written to.</returns>
+ <remarks>
+ <para>
+ Acquire the lock on the file in preparation for writing to it.
+ Return a stream pointing to the file. <see cref="M:log4net.Appender.FileAppender.MinimalLock.ReleaseLock"/>
+ must be called to release the lock on the output file.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.FileAppender.MinimalLock.ReleaseLock">
+ <summary>
+ Release the lock on the file
+ </summary>
+ <remarks>
+ <para>
+ Release the lock on the file. No further writes will be made to the
+ stream until <see cref="M:log4net.Appender.FileAppender.MinimalLock.AcquireLock"/> is called again.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Appender.ForwardingAppender">
+ <summary>
+ This appender forwards logging events to attached appenders.
+ </summary>
+ <remarks>
+ <para>
+ The forwarding appender can be used to specify different thresholds
+ and filters for the same appender at different locations within the hierarchy.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="M:log4net.Appender.ForwardingAppender.#ctor">
+ <summary>
+ Initializes a new instance of the <see cref="T:log4net.Appender.ForwardingAppender"/> class.
+ </summary>
+ <remarks>
+ <para>
+ Default constructor.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.ForwardingAppender.OnClose">
+ <summary>
+ Closes the appender and releases resources.
+ </summary>
+ <remarks>
+ <para>
+ Releases any resources allocated within the appender such as file handles,
+ network connections, etc.
+ </para>
+ <para>
+ It is a programming error to append to a closed appender.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.ForwardingAppender.Append(log4net.Core.LoggingEvent)">
+ <summary>
+ Forward the logging event to the attached appenders
+ </summary>
+ <param name="loggingEvent">The event to log.</param>
+ <remarks>
+ <para>
+ Delivers the logging event to all the attached appenders.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.ForwardingAppender.Append(log4net.Core.LoggingEvent[])">
+ <summary>
+ Forward the logging events to the attached appenders
+ </summary>
+ <param name="loggingEvents">The array of events to log.</param>
+ <remarks>
+ <para>
+ Delivers the logging events to all the attached appenders.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.ForwardingAppender.AddAppender(log4net.Appender.IAppender)">
+ <summary>
+ Adds an <see cref="T:log4net.Appender.IAppender"/> to the list of appenders of this
+ instance.
+ </summary>
+ <param name="newAppender">The <see cref="T:log4net.Appender.IAppender"/> to add to this appender.</param>
+ <remarks>
+ <para>
+ If the specified <see cref="T:log4net.Appender.IAppender"/> is already in the list of
+ appenders, then it won't be added again.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.ForwardingAppender.GetAppender(System.String)">
+ <summary>
+ Looks for the appender with the specified name.
+ </summary>
+ <param name="name">The name of the appender to lookup.</param>
+ <returns>
+ The appender with the specified name, or <c>null</c>.
+ </returns>
+ <remarks>
+ <para>
+ Get the named appender attached to this appender.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.ForwardingAppender.RemoveAllAppenders">
+ <summary>
+ Removes all previously added appenders from this appender.
+ </summary>
+ <remarks>
+ <para>
+ This is useful when re-reading configuration information.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.ForwardingAppender.RemoveAppender(log4net.Appender.IAppender)">
+ <summary>
+ Removes the specified appender from the list of appenders.
+ </summary>
+ <param name="appender">The appender to remove.</param>
+ <returns>The appender removed from the list</returns>
+ <remarks>
+ The appender removed is not closed.
+ If you are discarding the appender you must call
+ <see cref="M:log4net.Appender.IAppender.Close"/> on the appender removed.
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.ForwardingAppender.RemoveAppender(System.String)">
+ <summary>
+ Removes the appender with the specified name from the list of appenders.
+ </summary>
+ <param name="name">The name of the appender to remove.</param>
+ <returns>The appender removed from the list</returns>
+ <remarks>
+ The appender removed is not closed.
+ If you are discarding the appender you must call
+ <see cref="M:log4net.Appender.IAppender.Close"/> on the appender removed.
+ </remarks>
+ </member>
+ <member name="F:log4net.Appender.ForwardingAppender.m_appenderAttachedImpl">
+ <summary>
+ Implementation of the <see cref="T:log4net.Core.IAppenderAttachable"/> interface
+ </summary>
+ </member>
+ <member name="P:log4net.Appender.ForwardingAppender.Appenders">
+ <summary>
+ Gets the appenders contained in this appender as an
+ <see cref="T:System.Collections.ICollection"/>.
+ </summary>
+ <remarks>
+ If no appenders can be found, then an <see cref="T:log4net.Util.EmptyCollection"/>
+ is returned.
+ </remarks>
+ <returns>
+ A collection of the appenders in this appender.
+ </returns>
+ </member>
+ <member name="T:log4net.Appender.LocalSyslogAppender">
+ <summary>
+ Logs events to a local syslog service.
+ </summary>
+ <remarks>
+ <note>
+ This appender uses the POSIX libc library functions <c>openlog</c>, <c>syslog</c>, and <c>closelog</c>.
+ If these functions are not available on the local system then this appender will not work!
+ </note>
+ <para>
+ The functions <c>openlog</c>, <c>syslog</c>, and <c>closelog</c> are specified in SUSv2 and
+ POSIX 1003.1-2001 standards. These are used to log messages to the local syslog service.
+ </para>
+ <para>
+ This appender talks to a local syslog service. If you need to log to a remote syslog
+ daemon and you cannot configure your local syslog service to do this you may be
+ able to use the <see cref="T:log4net.Appender.RemoteSyslogAppender"/> to log via UDP.
+ </para>
+ <para>
+ Syslog messages must have a facility and and a severity. The severity
+ is derived from the Level of the logging event.
+ The facility must be chosen from the set of defined syslog
+ <see cref="T:log4net.Appender.LocalSyslogAppender.SyslogFacility"/> values. The facilities list is predefined
+ and cannot be extended.
+ </para>
+ <para>
+ An identifier is specified with each log message. This can be specified
+ by setting the <see cref="P:log4net.Appender.LocalSyslogAppender.Identity"/> property. The identity (also know
+ as the tag) must not contain white space. The default value for the
+ identity is the application name (from <see cref="P:log4net.Util.SystemInfo.ApplicationFriendlyName"/>).
+ </para>
+ </remarks>
+ <author>Rob Lyon</author>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="M:log4net.Appender.LocalSyslogAppender.#ctor">
+ <summary>
+ Initializes a new instance of the <see cref="T:log4net.Appender.LocalSyslogAppender"/> class.
+ </summary>
+ <remarks>
+ This instance of the <see cref="T:log4net.Appender.LocalSyslogAppender"/> class is set up to write
+ to a local syslog service.
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.LocalSyslogAppender.AddMapping(log4net.Appender.LocalSyslogAppender.LevelSeverity)">
+ <summary>
+ Add a mapping of level to severity
+ </summary>
+ <param name="mapping">The mapping to add</param>
+ <remarks>
+ <para>
+ Adds a <see cref="T:log4net.Appender.LocalSyslogAppender.LevelSeverity"/> to this appender.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.LocalSyslogAppender.ActivateOptions">
+ <summary>
+ Initialize the appender based on the options set.
+ </summary>
+ <remarks>
+ <para>
+ This is part of the <see cref="T:log4net.Core.IOptionHandler"/> delayed object
+ activation scheme. The <see cref="M:log4net.Appender.LocalSyslogAppender.ActivateOptions"/> method must
+ be called on this object after the configuration properties have
+ been set. Until <see cref="M:log4net.Appender.LocalSyslogAppender.ActivateOptions"/> is called this
+ object is in an undefined state and must not be used.
+ </para>
+ <para>
+ If any of the configuration properties are modified then
+ <see cref="M:log4net.Appender.LocalSyslogAppender.ActivateOptions"/> must be called again.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.LocalSyslogAppender.Append(log4net.Core.LoggingEvent)">
+ <summary>
+ This method is called by the <see cref="M:log4net.Appender.AppenderSkeleton.DoAppend(log4net.Core.LoggingEvent)"/> method.
+ </summary>
+ <param name="loggingEvent">The event to log.</param>
+ <remarks>
+ <para>
+ Writes the event to a remote syslog daemon.
+ </para>
+ <para>
+ The format of the output will depend on the appender's layout.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.LocalSyslogAppender.OnClose">
+ <summary>
+ Close the syslog when the appender is closed
+ </summary>
+ <remarks>
+ <para>
+ Close the syslog when the appender is closed
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.LocalSyslogAppender.GetSeverity(log4net.Core.Level)">
+ <summary>
+ Translates a log4net level to a syslog severity.
+ </summary>
+ <param name="level">A log4net level.</param>
+ <returns>A syslog severity.</returns>
+ <remarks>
+ <para>
+ Translates a log4net level to a syslog severity.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.LocalSyslogAppender.GeneratePriority(log4net.Appender.LocalSyslogAppender.SyslogFacility,log4net.Appender.LocalSyslogAppender.SyslogSeverity)">
+ <summary>
+ Generate a syslog priority.
+ </summary>
+ <param name="facility">The syslog facility.</param>
+ <param name="severity">The syslog severity.</param>
+ <returns>A syslog priority.</returns>
+ </member>
+ <member name="F:log4net.Appender.LocalSyslogAppender.m_facility">
+ <summary>
+ The facility. The default facility is <see cref="F:log4net.Appender.LocalSyslogAppender.SyslogFacility.User"/>.
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.LocalSyslogAppender.m_identity">
+ <summary>
+ The message identity
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.LocalSyslogAppender.m_handleToIdentity">
+ <summary>
+ Marshaled handle to the identity string. We have to hold on to the
+ string as the <c>openlog</c> and <c>syslog</c> APIs just hold the
+ pointer to the ident and dereference it for each log message.
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.LocalSyslogAppender.m_levelMapping">
+ <summary>
+ Mapping from level object to syslog severity
+ </summary>
+ </member>
+ <member name="M:log4net.Appender.LocalSyslogAppender.openlog(System.IntPtr,System.Int32,log4net.Appender.LocalSyslogAppender.SyslogFacility)">
+ <summary>
+ Open connection to system logger.
+ </summary>
+ </member>
+ <member name="M:log4net.Appender.LocalSyslogAppender.syslog(System.Int32,System.String,System.String)">
+ <summary>
+ Generate a log message.
+ </summary>
+ <remarks>
+ <para>
+ The libc syslog method takes a format string and a variable argument list similar
+ to the classic printf function. As this type of vararg list is not supported
+ by C# we need to specify the arguments explicitly. Here we have specified the
+ format string with a single message argument. The caller must set the format
+ string to <c>"%s"</c>.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.LocalSyslogAppender.closelog">
+ <summary>
+ Close descriptor used to write to system logger.
+ </summary>
+ </member>
+ <member name="P:log4net.Appender.LocalSyslogAppender.Identity">
+ <summary>
+ Message identity
+ </summary>
+ <remarks>
+ <para>
+ An identifier is specified with each log message. This can be specified
+ by setting the <see cref="P:log4net.Appender.LocalSyslogAppender.Identity"/> property. The identity (also know
+ as the tag) must not contain white space. The default value for the
+ identity is the application name (from <see cref="P:log4net.Util.SystemInfo.ApplicationFriendlyName"/>).
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.LocalSyslogAppender.Facility">
+ <summary>
+ Syslog facility
+ </summary>
+ <remarks>
+ Set to one of the <see cref="T:log4net.Appender.LocalSyslogAppender.SyslogFacility"/> values. The list of
+ facilities is predefined and cannot be extended. The default value
+ is <see cref="F:log4net.Appender.LocalSyslogAppender.SyslogFacility.User"/>.
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.LocalSyslogAppender.RequiresLayout">
+ <summary>
+ This appender requires a <see cref="P:log4net.Appender.AppenderSkeleton.Layout"/> to be set.
+ </summary>
+ <value><c>true</c></value>
+ <remarks>
+ <para>
+ This appender requires a <see cref="P:log4net.Appender.AppenderSkeleton.Layout"/> to be set.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Appender.LocalSyslogAppender.SyslogSeverity">
+ <summary>
+ syslog severities
+ </summary>
+ <remarks>
+ <para>
+ The log4net Level maps to a syslog severity using the
+ <see cref="M:log4net.Appender.LocalSyslogAppender.AddMapping(log4net.Appender.LocalSyslogAppender.LevelSeverity)"/> method and the <see cref="T:log4net.Appender.LocalSyslogAppender.LevelSeverity"/>
+ class. The severity is set on <see cref="P:log4net.Appender.LocalSyslogAppender.LevelSeverity.Severity"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Appender.LocalSyslogAppender.SyslogSeverity.Emergency">
+ <summary>
+ system is unusable
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.LocalSyslogAppender.SyslogSeverity.Alert">
+ <summary>
+ action must be taken immediately
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.LocalSyslogAppender.SyslogSeverity.Critical">
+ <summary>
+ critical conditions
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.LocalSyslogAppender.SyslogSeverity.Error">
+ <summary>
+ error conditions
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.LocalSyslogAppender.SyslogSeverity.Warning">
+ <summary>
+ warning conditions
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.LocalSyslogAppender.SyslogSeverity.Notice">
+ <summary>
+ normal but significant condition
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.LocalSyslogAppender.SyslogSeverity.Informational">
+ <summary>
+ informational
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.LocalSyslogAppender.SyslogSeverity.Debug">
+ <summary>
+ debug-level messages
+ </summary>
+ </member>
+ <member name="T:log4net.Appender.LocalSyslogAppender.SyslogFacility">
+ <summary>
+ syslog facilities
+ </summary>
+ <remarks>
+ <para>
+ The syslog facility defines which subsystem the logging comes from.
+ This is set on the <see cref="P:log4net.Appender.LocalSyslogAppender.Facility"/> property.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Appender.LocalSyslogAppender.SyslogFacility.Kernel">
+ <summary>
+ kernel messages
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.LocalSyslogAppender.SyslogFacility.User">
+ <summary>
+ random user-level messages
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.LocalSyslogAppender.SyslogFacility.Mail">
+ <summary>
+ mail system
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.LocalSyslogAppender.SyslogFacility.Daemons">
+ <summary>
+ system daemons
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.LocalSyslogAppender.SyslogFacility.Authorization">
+ <summary>
+ security/authorization messages
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.LocalSyslogAppender.SyslogFacility.Syslog">
+ <summary>
+ messages generated internally by syslogd
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.LocalSyslogAppender.SyslogFacility.Printer">
+ <summary>
+ line printer subsystem
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.LocalSyslogAppender.SyslogFacility.News">
+ <summary>
+ network news subsystem
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.LocalSyslogAppender.SyslogFacility.Uucp">
+ <summary>
+ UUCP subsystem
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.LocalSyslogAppender.SyslogFacility.Clock">
+ <summary>
+ clock (cron/at) daemon
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.LocalSyslogAppender.SyslogFacility.Authorization2">
+ <summary>
+ security/authorization messages (private)
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.LocalSyslogAppender.SyslogFacility.Ftp">
+ <summary>
+ ftp daemon
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.LocalSyslogAppender.SyslogFacility.Ntp">
+ <summary>
+ NTP subsystem
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.LocalSyslogAppender.SyslogFacility.Audit">
+ <summary>
+ log audit
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.LocalSyslogAppender.SyslogFacility.Alert">
+ <summary>
+ log alert
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.LocalSyslogAppender.SyslogFacility.Clock2">
+ <summary>
+ clock daemon
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.LocalSyslogAppender.SyslogFacility.Local0">
+ <summary>
+ reserved for local use
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.LocalSyslogAppender.SyslogFacility.Local1">
+ <summary>
+ reserved for local use
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.LocalSyslogAppender.SyslogFacility.Local2">
+ <summary>
+ reserved for local use
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.LocalSyslogAppender.SyslogFacility.Local3">
+ <summary>
+ reserved for local use
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.LocalSyslogAppender.SyslogFacility.Local4">
+ <summary>
+ reserved for local use
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.LocalSyslogAppender.SyslogFacility.Local5">
+ <summary>
+ reserved for local use
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.LocalSyslogAppender.SyslogFacility.Local6">
+ <summary>
+ reserved for local use
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.LocalSyslogAppender.SyslogFacility.Local7">
+ <summary>
+ reserved for local use
+ </summary>
+ </member>
+ <member name="T:log4net.Appender.LocalSyslogAppender.LevelSeverity">
+ <summary>
+ A class to act as a mapping between the level that a logging call is made at and
+ the syslog severity that is should be logged at.
+ </summary>
+ <remarks>
+ <para>
+ A class to act as a mapping between the level that a logging call is made at and
+ the syslog severity that is should be logged at.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.LocalSyslogAppender.LevelSeverity.Severity">
+ <summary>
+ The mapped syslog severity for the specified level
+ </summary>
+ <remarks>
+ <para>
+ Required property.
+ The mapped syslog severity for the specified level
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Appender.MemoryAppender">
+ <summary>
+ Stores logging events in an array.
+ </summary>
+ <remarks>
+ <para>
+ The memory appender stores all the logging events
+ that are appended in an in-memory array.
+ </para>
+ <para>
+ Use the <see cref="M:log4net.Appender.MemoryAppender.GetEvents"/> method to get
+ the current list of events that have been appended.
+ </para>
+ <para>
+ Use the <see cref="M:log4net.Appender.MemoryAppender.Clear"/> method to clear the
+ current list of events.
+ </para>
+ </remarks>
+ <author>Julian Biddle</author>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="M:log4net.Appender.MemoryAppender.#ctor">
+ <summary>
+ Initializes a new instance of the <see cref="T:log4net.Appender.MemoryAppender"/> class.
+ </summary>
+ <remarks>
+ <para>
+ Default constructor.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.MemoryAppender.GetEvents">
+ <summary>
+ Gets the events that have been logged.
+ </summary>
+ <returns>The events that have been logged</returns>
+ <remarks>
+ <para>
+ Gets the events that have been logged.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.MemoryAppender.Append(log4net.Core.LoggingEvent)">
+ <summary>
+ This method is called by the <see cref="M:log4net.Appender.AppenderSkeleton.DoAppend(log4net.Core.LoggingEvent)"/> method.
+ </summary>
+ <param name="loggingEvent">the event to log</param>
+ <remarks>
+ <para>Stores the <paramref name="loggingEvent"/> in the events list.</para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.MemoryAppender.Clear">
+ <summary>
+ Clear the list of events
+ </summary>
+ <remarks>
+ Clear the list of events
+ </remarks>
+ </member>
+ <member name="F:log4net.Appender.MemoryAppender.m_eventsList">
+ <summary>
+ The list of events that have been appended.
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.MemoryAppender.m_fixFlags">
+ <summary>
+ Value indicating which fields in the event should be fixed
+ </summary>
+ <remarks>
+ By default all fields are fixed
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.MemoryAppender.OnlyFixPartialEventData">
+ <summary>
+ Gets or sets a value indicating whether only part of the logging event
+ data should be fixed.
+ </summary>
+ <value>
+ <c>true</c> if the appender should only fix part of the logging event
+ data, otherwise <c>false</c>. The default is <c>false</c>.
+ </value>
+ <remarks>
+ <para>
+ Setting this property to <c>true</c> will cause only part of the event
+ data to be fixed and stored in the appender, hereby improving performance.
+ </para>
+ <para>
+ See <see cref="M:log4net.Core.LoggingEvent.FixVolatileData(System.Boolean)"/> for more information.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.MemoryAppender.Fix">
+ <summary>
+ Gets or sets the fields that will be fixed in the event
+ </summary>
+ <remarks>
+ <para>
+ The logging event needs to have certain thread specific values
+ captured before it can be buffered. See <see cref="P:log4net.Core.LoggingEvent.Fix"/>
+ for details.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Appender.NetSendAppender">
+ <summary>
+ Logs entries by sending network messages using the
+ <see cref="M:log4net.Appender.NetSendAppender.NetMessageBufferSend(System.String,System.String,System.String,System.String,System.Int32)"/> native function.
+ </summary>
+ <remarks>
+ <para>
+ You can send messages only to names that are active
+ on the network. If you send the message to a user name,
+ that user must be logged on and running the Messenger
+ service to receive the message.
+ </para>
+ <para>
+ The receiver will get a top most window displaying the
+ messages one at a time, therefore this appender should
+ not be used to deliver a high volume of messages.
+ </para>
+ <para>
+ The following table lists some possible uses for this appender :
+ </para>
+ <para>
+ <list type="table">
+ <listheader>
+ <term>Action</term>
+ <description>Property Value(s)</description>
+ </listheader>
+ <item>
+ <term>Send a message to a user account on the local machine</term>
+ <description>
+ <para>
+ <paramref name="Server"/> = &lt;name of the local machine&gt;
+ </para>
+ <para>
+ <paramref name="Recipient"/> = &lt;user name&gt;
+ </para>
+ </description>
+ </item>
+ <item>
+ <term>Send a message to a user account on a remote machine</term>
+ <description>
+ <para>
+ <paramref name="Server"/> = &lt;name of the remote machine&gt;
+ </para>
+ <para>
+ <paramref name="Recipient"/> = &lt;user name&gt;
+ </para>
+ </description>
+ </item>
+ <item>
+ <term>Send a message to a domain user account</term>
+ <description>
+ <para>
+ <paramref name="Server"/> = &lt;name of a domain controller | uninitialized&gt;
+ </para>
+ <para>
+ <paramref name="Recipient"/> = &lt;user name&gt;
+ </para>
+ </description>
+ </item>
+ <item>
+ <term>Send a message to all the names in a workgroup or domain</term>
+ <description>
+ <para>
+ <paramref name="Recipient"/> = &lt;workgroup name | domain name&gt;*
+ </para>
+ </description>
+ </item>
+ <item>
+ <term>Send a message from the local machine to a remote machine</term>
+ <description>
+ <para>
+ <paramref name="Server"/> = &lt;name of the local machine | uninitialized&gt;
+ </para>
+ <para>
+ <paramref name="Recipient"/> = &lt;name of the remote machine&gt;
+ </para>
+ </description>
+ </item>
+ </list>
+ </para>
+ <para>
+ <b>Note :</b> security restrictions apply for sending
+ network messages, see <see cref="M:log4net.Appender.NetSendAppender.NetMessageBufferSend(System.String,System.String,System.String,System.String,System.Int32)"/>
+ for more information.
+ </para>
+ </remarks>
+ <example>
+ <para>
+ An example configuration section to log information
+ using this appender from the local machine, named
+ LOCAL_PC, to machine OPERATOR_PC :
+ </para>
+ <code lang="XML" escaped="true">
+ <appender name="NetSendAppender_Operator" type="log4net.Appender.NetSendAppender">
+ <server value="LOCAL_PC"/>
+ <recipient value="OPERATOR_PC"/>
+ <layout type="log4net.Layout.PatternLayout" value="%-5p %c [%x] - %m%n"/>
+ </appender>
+ </code>
+ </example>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="F:log4net.Appender.NetSendAppender.m_server">
+ <summary>
+ The DNS or NetBIOS name of the server on which the function is to execute.
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.NetSendAppender.m_sender">
+ <summary>
+ The sender of the network message.
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.NetSendAppender.m_recipient">
+ <summary>
+ The message alias to which the message should be sent.
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.NetSendAppender.m_securityContext">
+ <summary>
+ The security context to use for privileged calls
+ </summary>
+ </member>
+ <member name="M:log4net.Appender.NetSendAppender.#ctor">
+ <summary>
+ Initializes the appender.
+ </summary>
+ <remarks>
+ The default constructor initializes all fields to their default values.
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.NetSendAppender.ActivateOptions">
+ <summary>
+ Initialize the appender based on the options set.
+ </summary>
+ <remarks>
+ <para>
+ This is part of the <see cref="T:log4net.Core.IOptionHandler"/> delayed object
+ activation scheme. The <see cref="M:log4net.Appender.NetSendAppender.ActivateOptions"/> method must
+ be called on this object after the configuration properties have
+ been set. Until <see cref="M:log4net.Appender.NetSendAppender.ActivateOptions"/> is called this
+ object is in an undefined state and must not be used.
+ </para>
+ <para>
+ If any of the configuration properties are modified then
+ <see cref="M:log4net.Appender.NetSendAppender.ActivateOptions"/> must be called again.
+ </para>
+ <para>
+ The appender will be ignored if no <see cref="P:log4net.Appender.NetSendAppender.Recipient"/> was specified.
+ </para>
+ </remarks>
+ <exception cref="T:System.ArgumentNullException">The required property <see cref="P:log4net.Appender.NetSendAppender.Recipient"/> was not specified.</exception>
+ </member>
+ <member name="M:log4net.Appender.NetSendAppender.Append(log4net.Core.LoggingEvent)">
+ <summary>
+ This method is called by the <see cref="M:log4net.Appender.AppenderSkeleton.DoAppend(log4net.Core.LoggingEvent)"/> method.
+ </summary>
+ <param name="loggingEvent">The event to log.</param>
+ <remarks>
+ <para>
+ Sends the event using a network message.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.NetSendAppender.NetMessageBufferSend(System.String,System.String,System.String,System.String,System.Int32)">
+ <summary>
+ Sends a buffer of information to a registered message alias.
+ </summary>
+ <param name="serverName">The DNS or NetBIOS name of the server on which the function is to execute.</param>
+ <param name="msgName">The message alias to which the message buffer should be sent</param>
+ <param name="fromName">The originator of the message.</param>
+ <param name="buffer">The message text.</param>
+ <param name="bufferSize">The length, in bytes, of the message text.</param>
+ <remarks>
+ <para>
+ The following restrictions apply for sending network messages:
+ </para>
+ <para>
+ <list type="table">
+ <listheader>
+ <term>Platform</term>
+ <description>Requirements</description>
+ </listheader>
+ <item>
+ <term>Windows NT</term>
+ <description>
+ <para>
+ No special group membership is required to send a network message.
+ </para>
+ <para>
+ Admin, Accounts, Print, or Server Operator group membership is required to
+ successfully send a network message on a remote server.
+ </para>
+ </description>
+ </item>
+ <item>
+ <term>Windows 2000 or later</term>
+ <description>
+ <para>
+ If you send a message on a domain controller that is running Active Directory,
+ access is allowed or denied based on the access control list (ACL) for the securable
+ object. The default ACL permits only Domain Admins and Account Operators to send a network message.
+ </para>
+ <para>
+ On a member server or workstation, only Administrators and Server Operators can send a network message.
+ </para>
+ </description>
+ </item>
+ </list>
+ </para>
+ <para>
+ For more information see <a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/netmgmt/netmgmt/security_requirements_for_the_network_management_functions.asp">Security Requirements for the Network Management Functions</a>.
+ </para>
+ </remarks>
+ <returns>
+ <para>
+ If the function succeeds, the return value is zero.
+ </para>
+ </returns>
+ </member>
+ <member name="P:log4net.Appender.NetSendAppender.Sender">
+ <summary>
+ Gets or sets the sender of the message.
+ </summary>
+ <value>
+ The sender of the message.
+ </value>
+ <remarks>
+ If this property is not specified, the message is sent from the local computer.
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.NetSendAppender.Recipient">
+ <summary>
+ Gets or sets the message alias to which the message should be sent.
+ </summary>
+ <value>
+ The recipient of the message.
+ </value>
+ <remarks>
+ This property should always be specified in order to send a message.
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.NetSendAppender.Server">
+ <summary>
+ Gets or sets the DNS or NetBIOS name of the remote server on which the function is to execute.
+ </summary>
+ <value>
+ DNS or NetBIOS name of the remote server on which the function is to execute.
+ </value>
+ <remarks>
+ <para>
+ For Windows NT 4.0 and earlier, the string should begin with \\.
+ </para>
+ <para>
+ If this property is not specified, the local computer is used.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.NetSendAppender.SecurityContext">
+ <summary>
+ Gets or sets the <see cref="P:log4net.Appender.NetSendAppender.SecurityContext"/> used to call the NetSend method.
+ </summary>
+ <value>
+ The <see cref="P:log4net.Appender.NetSendAppender.SecurityContext"/> used to call the NetSend method.
+ </value>
+ <remarks>
+ <para>
+ Unless a <see cref="P:log4net.Appender.NetSendAppender.SecurityContext"/> specified here for this appender
+ the <see cref="P:log4net.Core.SecurityContextProvider.DefaultProvider"/> is queried for the
+ security context to use. The default behavior is to use the security context
+ of the current thread.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.NetSendAppender.RequiresLayout">
+ <summary>
+ This appender requires a <see cref="N:log4net.Layout"/> to be set.
+ </summary>
+ <value><c>true</c></value>
+ <remarks>
+ <para>
+ This appender requires a <see cref="N:log4net.Layout"/> to be set.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Appender.OutputDebugStringAppender">
+ <summary>
+ Appends log events to the OutputDebugString system.
+ </summary>
+ <remarks>
+ <para>
+ OutputDebugStringAppender appends log events to the
+ OutputDebugString system.
+ </para>
+ <para>
+ The string is passed to the native <c>OutputDebugString</c>
+ function.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="M:log4net.Appender.OutputDebugStringAppender.#ctor">
+ <summary>
+ Initializes a new instance of the <see cref="T:log4net.Appender.OutputDebugStringAppender"/> class.
+ </summary>
+ <remarks>
+ <para>
+ Default constructor.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.OutputDebugStringAppender.Append(log4net.Core.LoggingEvent)">
+ <summary>
+ Write the logging event to the output debug string API
+ </summary>
+ <param name="loggingEvent">the event to log</param>
+ <remarks>
+ <para>
+ Write the logging event to the output debug string API
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.OutputDebugStringAppender.OutputDebugString(System.String)">
+ <summary>
+ Stub for OutputDebugString native method
+ </summary>
+ <param name="message">the string to output</param>
+ <remarks>
+ <para>
+ Stub for OutputDebugString native method
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.OutputDebugStringAppender.RequiresLayout">
+ <summary>
+ This appender requires a <see cref="N:log4net.Layout"/> to be set.
+ </summary>
+ <value><c>true</c></value>
+ <remarks>
+ <para>
+ This appender requires a <see cref="N:log4net.Layout"/> to be set.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Appender.RemoteSyslogAppender">
+ <summary>
+ Logs events to a remote syslog daemon.
+ </summary>
+ <remarks>
+ <para>
+ The BSD syslog protocol is used to remotely log to
+ a syslog daemon. The syslogd listens for for messages
+ on UDP port 514.
+ </para>
+ <para>
+ The syslog UDP protocol is not authenticated. Most syslog daemons
+ do not accept remote log messages because of the security implications.
+ You may be able to use the LocalSyslogAppender to talk to a local
+ syslog service.
+ </para>
+ <para>
+ There is an RFC 3164 that claims to document the BSD Syslog Protocol.
+ This RFC can be seen here: http://www.faqs.org/rfcs/rfc3164.html.
+ This appender generates what the RFC calls an "Original Device Message",
+ i.e. does not include the TIMESTAMP or HOSTNAME fields. By observation
+ this format of message will be accepted by all current syslog daemon
+ implementations. The daemon will attach the current time and the source
+ hostname or IP address to any messages received.
+ </para>
+ <para>
+ Syslog messages must have a facility and and a severity. The severity
+ is derived from the Level of the logging event.
+ The facility must be chosen from the set of defined syslog
+ <see cref="T:log4net.Appender.RemoteSyslogAppender.SyslogFacility"/> values. The facilities list is predefined
+ and cannot be extended.
+ </para>
+ <para>
+ An identifier is specified with each log message. This can be specified
+ by setting the <see cref="P:log4net.Appender.RemoteSyslogAppender.Identity"/> property. The identity (also know
+ as the tag) must not contain white space. The default value for the
+ identity is the application name (from <see cref="P:log4net.Core.LoggingEvent.Domain"/>).
+ </para>
+ </remarks>
+ <author>Rob Lyon</author>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="T:log4net.Appender.UdpAppender">
+ <summary>
+ Sends logging events as connectionless UDP datagrams to a remote host or a
+ multicast group using an <see cref="T:System.Net.Sockets.UdpClient"/>.
+ </summary>
+ <remarks>
+ <para>
+ UDP guarantees neither that messages arrive, nor that they arrive in the correct order.
+ </para>
+ <para>
+ To view the logging results, a custom application can be developed that listens for logging
+ events.
+ </para>
+ <para>
+ When decoding events send via this appender remember to use the same encoding
+ to decode the events as was used to send the events. See the <see cref="P:log4net.Appender.UdpAppender.Encoding"/>
+ property to specify the encoding to use.
+ </para>
+ </remarks>
+ <example>
+ This example shows how to log receive logging events that are sent
+ on IP address 244.0.0.1 and port 8080 to the console. The event is
+ encoded in the packet as a unicode string and it is decoded as such.
+ <code lang="C#">
+ IPEndPoint remoteEndPoint = new IPEndPoint(IPAddress.Any, 0);
+ UdpClient udpClient;
+ byte[] buffer;
+ string loggingEvent;
+
+ try
+ {
+ udpClient = new UdpClient(8080);
+
+ while(true)
+ {
+ buffer = udpClient.Receive(ref remoteEndPoint);
+ loggingEvent = System.Text.Encoding.Unicode.GetString(buffer);
+ Console.WriteLine(loggingEvent);
+ }
+ }
+ catch(Exception e)
+ {
+ Console.WriteLine(e.ToString());
+ }
+ </code>
+ <code lang="Visual Basic">
+ Dim remoteEndPoint as IPEndPoint
+ Dim udpClient as UdpClient
+ Dim buffer as Byte()
+ Dim loggingEvent as String
+
+ Try
+ remoteEndPoint = new IPEndPoint(IPAddress.Any, 0)
+ udpClient = new UdpClient(8080)
+
+ While True
+ buffer = udpClient.Receive(ByRef remoteEndPoint)
+ loggingEvent = System.Text.Encoding.Unicode.GetString(buffer)
+ Console.WriteLine(loggingEvent)
+ Wend
+ Catch e As Exception
+ Console.WriteLine(e.ToString())
+ End Try
+ </code>
+ <para>
+ An example configuration section to log information using this appender to the
+ IP 224.0.0.1 on port 8080:
+ </para>
+ <code lang="XML" escaped="true">
+ <appender name="UdpAppender" type="log4net.Appender.UdpAppender">
+ <remoteAddress value="224.0.0.1"/>
+ <remotePort value="8080"/>
+ <layout type="log4net.Layout.PatternLayout" value="%-5level %logger [%ndc] - %message%newline"/>
+ </appender>
+ </code>
+ </example>
+ <author>Gert Driesen</author>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="M:log4net.Appender.UdpAppender.#ctor">
+ <summary>
+ Initializes a new instance of the <see cref="T:log4net.Appender.UdpAppender"/> class.
+ </summary>
+ <remarks>
+ The default constructor initializes all fields to their default values.
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.UdpAppender.ActivateOptions">
+ <summary>
+ Initialize the appender based on the options set.
+ </summary>
+ <remarks>
+ <para>
+ This is part of the <see cref="T:log4net.Core.IOptionHandler"/> delayed object
+ activation scheme. The <see cref="M:log4net.Appender.UdpAppender.ActivateOptions"/> method must
+ be called on this object after the configuration properties have
+ been set. Until <see cref="M:log4net.Appender.UdpAppender.ActivateOptions"/> is called this
+ object is in an undefined state and must not be used.
+ </para>
+ <para>
+ If any of the configuration properties are modified then
+ <see cref="M:log4net.Appender.UdpAppender.ActivateOptions"/> must be called again.
+ </para>
+ <para>
+ The appender will be ignored if no <see cref="P:log4net.Appender.UdpAppender.RemoteAddress"/> was specified or
+ an invalid remote or local TCP port number was specified.
+ </para>
+ </remarks>
+ <exception cref="T:System.ArgumentNullException">The required property <see cref="P:log4net.Appender.UdpAppender.RemoteAddress"/> was not specified.</exception>
+ <exception cref="T:System.ArgumentOutOfRangeException">The TCP port number assigned to <see cref="P:log4net.Appender.UdpAppender.LocalPort"/> or <see cref="P:log4net.Appender.UdpAppender.RemotePort"/> is less than <see cref="F:System.Net.IPEndPoint.MinPort"/> or greater than <see cref="F:System.Net.IPEndPoint.MaxPort"/>.</exception>
+ </member>
+ <member name="M:log4net.Appender.UdpAppender.Append(log4net.Core.LoggingEvent)">
+ <summary>
+ This method is called by the <see cref="M:log4net.Appender.AppenderSkeleton.DoAppend(log4net.Core.LoggingEvent)"/> method.
+ </summary>
+ <param name="loggingEvent">The event to log.</param>
+ <remarks>
+ <para>
+ Sends the event using an UDP datagram.
+ </para>
+ <para>
+ Exceptions are passed to the <see cref="P:log4net.Appender.AppenderSkeleton.ErrorHandler"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.UdpAppender.OnClose">
+ <summary>
+ Closes the UDP connection and releases all resources associated with
+ this <see cref="T:log4net.Appender.UdpAppender"/> instance.
+ </summary>
+ <remarks>
+ <para>
+ Disables the underlying <see cref="T:System.Net.Sockets.UdpClient"/> and releases all managed
+ and unmanaged resources associated with the <see cref="T:log4net.Appender.UdpAppender"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.UdpAppender.InitializeClientConnection">
+ <summary>
+ Initializes the underlying <see cref="T:System.Net.Sockets.UdpClient"/> connection.
+ </summary>
+ <remarks>
+ <para>
+ The underlying <see cref="T:System.Net.Sockets.UdpClient"/> is initialized and binds to the
+ port number from which you intend to communicate.
+ </para>
+ <para>
+ Exceptions are passed to the <see cref="P:log4net.Appender.AppenderSkeleton.ErrorHandler"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Appender.UdpAppender.m_remoteAddress">
+ <summary>
+ The IP address of the remote host or multicast group to which
+ the logging event will be sent.
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.UdpAppender.m_remotePort">
+ <summary>
+ The TCP port number of the remote host or multicast group to
+ which the logging event will be sent.
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.UdpAppender.m_remoteEndPoint">
+ <summary>
+ The cached remote endpoint to which the logging events will be sent.
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.UdpAppender.m_localPort">
+ <summary>
+ The TCP port number from which the <see cref="T:System.Net.Sockets.UdpClient"/> will communicate.
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.UdpAppender.m_client">
+ <summary>
+ The <see cref="T:System.Net.Sockets.UdpClient"/> instance that will be used for sending the
+ logging events.
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.UdpAppender.m_encoding">
+ <summary>
+ The encoding to use for the packet.
+ </summary>
+ </member>
+ <member name="P:log4net.Appender.UdpAppender.RemoteAddress">
+ <summary>
+ Gets or sets the IP address of the remote host or multicast group to which
+ the underlying <see cref="T:System.Net.Sockets.UdpClient"/> should sent the logging event.
+ </summary>
+ <value>
+ The IP address of the remote host or multicast group to which the logging event
+ will be sent.
+ </value>
+ <remarks>
+ <para>
+ Multicast addresses are identified by IP class <b>D</b> addresses (in the range 224.0.0.0 to
+ 239.255.255.255). Multicast packets can pass across different networks through routers, so
+ it is possible to use multicasts in an Internet scenario as long as your network provider
+ supports multicasting.
+ </para>
+ <para>
+ Hosts that want to receive particular multicast messages must register their interest by joining
+ the multicast group. Multicast messages are not sent to networks where no host has joined
+ the multicast group. Class <b>D</b> IP addresses are used for multicast groups, to differentiate
+ them from normal host addresses, allowing nodes to easily detect if a message is of interest.
+ </para>
+ <para>
+ Static multicast addresses that are needed globally are assigned by IANA. A few examples are listed in the table below:
+ </para>
+ <para>
+ <list type="table">
+ <listheader>
+ <term>IP Address</term>
+ <description>Description</description>
+ </listheader>
+ <item>
+ <term>224.0.0.1</term>
+ <description>
+ <para>
+ Sends a message to all system on the subnet.
+ </para>
+ </description>
+ </item>
+ <item>
+ <term>224.0.0.2</term>
+ <description>
+ <para>
+ Sends a message to all routers on the subnet.
+ </para>
+ </description>
+ </item>
+ <item>
+ <term>224.0.0.12</term>
+ <description>
+ <para>
+ The DHCP server answers messages on the IP address 224.0.0.12, but only on a subnet.
+ </para>
+ </description>
+ </item>
+ </list>
+ </para>
+ <para>
+ A complete list of actually reserved multicast addresses and their owners in the ranges
+ defined by RFC 3171 can be found at the <A href="http://www.iana.org/assignments/multicast-addresses">IANA web site</A>.
+ </para>
+ <para>
+ The address range 239.0.0.0 to 239.255.255.255 is reserved for administrative scope-relative
+ addresses. These addresses can be reused with other local groups. Routers are typically
+ configured with filters to prevent multicast traffic in this range from flowing outside
+ of the local network.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.UdpAppender.RemotePort">
+ <summary>
+ Gets or sets the TCP port number of the remote host or multicast group to which
+ the underlying <see cref="T:System.Net.Sockets.UdpClient"/> should sent the logging event.
+ </summary>
+ <value>
+ An integer value in the range <see cref="F:System.Net.IPEndPoint.MinPort"/> to <see cref="F:System.Net.IPEndPoint.MaxPort"/>
+ indicating the TCP port number of the remote host or multicast group to which the logging event
+ will be sent.
+ </value>
+ <remarks>
+ The underlying <see cref="T:System.Net.Sockets.UdpClient"/> will send messages to this TCP port number
+ on the remote host or multicast group.
+ </remarks>
+ <exception cref="T:System.ArgumentOutOfRangeException">The value specified is less than <see cref="F:System.Net.IPEndPoint.MinPort"/> or greater than <see cref="F:System.Net.IPEndPoint.MaxPort"/>.</exception>
+ </member>
+ <member name="P:log4net.Appender.UdpAppender.LocalPort">
+ <summary>
+ Gets or sets the TCP port number from which the underlying <see cref="T:System.Net.Sockets.UdpClient"/> will communicate.
+ </summary>
+ <value>
+ An integer value in the range <see cref="F:System.Net.IPEndPoint.MinPort"/> to <see cref="F:System.Net.IPEndPoint.MaxPort"/>
+ indicating the TCP port number from which the underlying <see cref="T:System.Net.Sockets.UdpClient"/> will communicate.
+ </value>
+ <remarks>
+ <para>
+ The underlying <see cref="T:System.Net.Sockets.UdpClient"/> will bind to this port for sending messages.
+ </para>
+ <para>
+ Setting the value to 0 (the default) will cause the udp client not to bind to
+ a local port.
+ </para>
+ </remarks>
+ <exception cref="T:System.ArgumentOutOfRangeException">The value specified is less than <see cref="F:System.Net.IPEndPoint.MinPort"/> or greater than <see cref="F:System.Net.IPEndPoint.MaxPort"/>.</exception>
+ </member>
+ <member name="P:log4net.Appender.UdpAppender.Encoding">
+ <summary>
+ Gets or sets <see cref="P:log4net.Appender.UdpAppender.Encoding"/> used to write the packets.
+ </summary>
+ <value>
+ The <see cref="P:log4net.Appender.UdpAppender.Encoding"/> used to write the packets.
+ </value>
+ <remarks>
+ <para>
+ The <see cref="P:log4net.Appender.UdpAppender.Encoding"/> used to write the packets.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.UdpAppender.Client">
+ <summary>
+ Gets or sets the underlying <see cref="T:System.Net.Sockets.UdpClient"/>.
+ </summary>
+ <value>
+ The underlying <see cref="T:System.Net.Sockets.UdpClient"/>.
+ </value>
+ <remarks>
+ <see cref="T:log4net.Appender.UdpAppender"/> creates a <see cref="T:System.Net.Sockets.UdpClient"/> to send logging events
+ over a network. Classes deriving from <see cref="T:log4net.Appender.UdpAppender"/> can use this
+ property to get or set this <see cref="T:System.Net.Sockets.UdpClient"/>. Use the underlying <see cref="T:System.Net.Sockets.UdpClient"/>
+ returned from <see cref="P:log4net.Appender.UdpAppender.Client"/> if you require access beyond that which
+ <see cref="T:log4net.Appender.UdpAppender"/> provides.
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.UdpAppender.RemoteEndPoint">
+ <summary>
+ Gets or sets the cached remote endpoint to which the logging events should be sent.
+ </summary>
+ <value>
+ The cached remote endpoint to which the logging events will be sent.
+ </value>
+ <remarks>
+ The <see cref="M:log4net.Appender.UdpAppender.ActivateOptions"/> method will initialize the remote endpoint
+ with the values of the <see cref="P:log4net.Appender.UdpAppender.RemoteAddress"/> and <see cref="P:log4net.Appender.UdpAppender.RemotePort"/>
+ properties.
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.UdpAppender.RequiresLayout">
+ <summary>
+ This appender requires a <see cref="N:log4net.Layout"/> to be set.
+ </summary>
+ <value><c>true</c></value>
+ <remarks>
+ <para>
+ This appender requires a <see cref="N:log4net.Layout"/> to be set.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Appender.RemoteSyslogAppender.DefaultSyslogPort">
+ <summary>
+ Syslog port 514
+ </summary>
+ </member>
+ <member name="M:log4net.Appender.RemoteSyslogAppender.#ctor">
+ <summary>
+ Initializes a new instance of the <see cref="T:log4net.Appender.RemoteSyslogAppender"/> class.
+ </summary>
+ <remarks>
+ This instance of the <see cref="T:log4net.Appender.RemoteSyslogAppender"/> class is set up to write
+ to a remote syslog daemon.
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.RemoteSyslogAppender.AddMapping(log4net.Appender.RemoteSyslogAppender.LevelSeverity)">
+ <summary>
+ Add a mapping of level to severity
+ </summary>
+ <param name="mapping">The mapping to add</param>
+ <remarks>
+ <para>
+ Add a <see cref="T:log4net.Appender.RemoteSyslogAppender.LevelSeverity"/> mapping to this appender.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.RemoteSyslogAppender.Append(log4net.Core.LoggingEvent)">
+ <summary>
+ This method is called by the <see cref="M:log4net.Appender.AppenderSkeleton.DoAppend(log4net.Core.LoggingEvent)"/> method.
+ </summary>
+ <param name="loggingEvent">The event to log.</param>
+ <remarks>
+ <para>
+ Writes the event to a remote syslog daemon.
+ </para>
+ <para>
+ The format of the output will depend on the appender's layout.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.RemoteSyslogAppender.ActivateOptions">
+ <summary>
+ Initialize the options for this appender
+ </summary>
+ <remarks>
+ <para>
+ Initialize the level to syslog severity mappings set on this appender.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.RemoteSyslogAppender.GetSeverity(log4net.Core.Level)">
+ <summary>
+ Translates a log4net level to a syslog severity.
+ </summary>
+ <param name="level">A log4net level.</param>
+ <returns>A syslog severity.</returns>
+ <remarks>
+ <para>
+ Translates a log4net level to a syslog severity.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.RemoteSyslogAppender.GeneratePriority(log4net.Appender.RemoteSyslogAppender.SyslogFacility,log4net.Appender.RemoteSyslogAppender.SyslogSeverity)">
+ <summary>
+ Generate a syslog priority.
+ </summary>
+ <param name="facility">The syslog facility.</param>
+ <param name="severity">The syslog severity.</param>
+ <returns>A syslog priority.</returns>
+ <remarks>
+ <para>
+ Generate a syslog priority.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Appender.RemoteSyslogAppender.m_facility">
+ <summary>
+ The facility. The default facility is <see cref="F:log4net.Appender.RemoteSyslogAppender.SyslogFacility.User"/>.
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.RemoteSyslogAppender.m_identity">
+ <summary>
+ The message identity
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.RemoteSyslogAppender.m_levelMapping">
+ <summary>
+ Mapping from level object to syslog severity
+ </summary>
+ </member>
+ <member name="P:log4net.Appender.RemoteSyslogAppender.Identity">
+ <summary>
+ Message identity
+ </summary>
+ <remarks>
+ <para>
+ An identifier is specified with each log message. This can be specified
+ by setting the <see cref="P:log4net.Appender.RemoteSyslogAppender.Identity"/> property. The identity (also know
+ as the tag) must not contain white space. The default value for the
+ identity is the application name (from <see cref="P:log4net.Core.LoggingEvent.Domain"/>).
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.RemoteSyslogAppender.Facility">
+ <summary>
+ Syslog facility
+ </summary>
+ <remarks>
+ Set to one of the <see cref="T:log4net.Appender.RemoteSyslogAppender.SyslogFacility"/> values. The list of
+ facilities is predefined and cannot be extended. The default value
+ is <see cref="F:log4net.Appender.RemoteSyslogAppender.SyslogFacility.User"/>.
+ </remarks>
+ </member>
+ <member name="T:log4net.Appender.RemoteSyslogAppender.SyslogSeverity">
+ <summary>
+ syslog severities
+ </summary>
+ <remarks>
+ <para>
+ The syslog severities.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Appender.RemoteSyslogAppender.SyslogSeverity.Emergency">
+ <summary>
+ system is unusable
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.RemoteSyslogAppender.SyslogSeverity.Alert">
+ <summary>
+ action must be taken immediately
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.RemoteSyslogAppender.SyslogSeverity.Critical">
+ <summary>
+ critical conditions
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.RemoteSyslogAppender.SyslogSeverity.Error">
+ <summary>
+ error conditions
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.RemoteSyslogAppender.SyslogSeverity.Warning">
+ <summary>
+ warning conditions
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.RemoteSyslogAppender.SyslogSeverity.Notice">
+ <summary>
+ normal but significant condition
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.RemoteSyslogAppender.SyslogSeverity.Informational">
+ <summary>
+ informational
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.RemoteSyslogAppender.SyslogSeverity.Debug">
+ <summary>
+ debug-level messages
+ </summary>
+ </member>
+ <member name="T:log4net.Appender.RemoteSyslogAppender.SyslogFacility">
+ <summary>
+ syslog facilities
+ </summary>
+ <remarks>
+ <para>
+ The syslog facilities
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Appender.RemoteSyslogAppender.SyslogFacility.Kernel">
+ <summary>
+ kernel messages
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.RemoteSyslogAppender.SyslogFacility.User">
+ <summary>
+ random user-level messages
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.RemoteSyslogAppender.SyslogFacility.Mail">
+ <summary>
+ mail system
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.RemoteSyslogAppender.SyslogFacility.Daemons">
+ <summary>
+ system daemons
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.RemoteSyslogAppender.SyslogFacility.Authorization">
+ <summary>
+ security/authorization messages
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.RemoteSyslogAppender.SyslogFacility.Syslog">
+ <summary>
+ messages generated internally by syslogd
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.RemoteSyslogAppender.SyslogFacility.Printer">
+ <summary>
+ line printer subsystem
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.RemoteSyslogAppender.SyslogFacility.News">
+ <summary>
+ network news subsystem
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.RemoteSyslogAppender.SyslogFacility.Uucp">
+ <summary>
+ UUCP subsystem
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.RemoteSyslogAppender.SyslogFacility.Clock">
+ <summary>
+ clock (cron/at) daemon
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.RemoteSyslogAppender.SyslogFacility.Authorization2">
+ <summary>
+ security/authorization messages (private)
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.RemoteSyslogAppender.SyslogFacility.Ftp">
+ <summary>
+ ftp daemon
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.RemoteSyslogAppender.SyslogFacility.Ntp">
+ <summary>
+ NTP subsystem
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.RemoteSyslogAppender.SyslogFacility.Audit">
+ <summary>
+ log audit
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.RemoteSyslogAppender.SyslogFacility.Alert">
+ <summary>
+ log alert
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.RemoteSyslogAppender.SyslogFacility.Clock2">
+ <summary>
+ clock daemon
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.RemoteSyslogAppender.SyslogFacility.Local0">
+ <summary>
+ reserved for local use
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.RemoteSyslogAppender.SyslogFacility.Local1">
+ <summary>
+ reserved for local use
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.RemoteSyslogAppender.SyslogFacility.Local2">
+ <summary>
+ reserved for local use
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.RemoteSyslogAppender.SyslogFacility.Local3">
+ <summary>
+ reserved for local use
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.RemoteSyslogAppender.SyslogFacility.Local4">
+ <summary>
+ reserved for local use
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.RemoteSyslogAppender.SyslogFacility.Local5">
+ <summary>
+ reserved for local use
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.RemoteSyslogAppender.SyslogFacility.Local6">
+ <summary>
+ reserved for local use
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.RemoteSyslogAppender.SyslogFacility.Local7">
+ <summary>
+ reserved for local use
+ </summary>
+ </member>
+ <member name="T:log4net.Appender.RemoteSyslogAppender.LevelSeverity">
+ <summary>
+ A class to act as a mapping between the level that a logging call is made at and
+ the syslog severity that is should be logged at.
+ </summary>
+ <remarks>
+ <para>
+ A class to act as a mapping between the level that a logging call is made at and
+ the syslog severity that is should be logged at.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.RemoteSyslogAppender.LevelSeverity.Severity">
+ <summary>
+ The mapped syslog severity for the specified level
+ </summary>
+ <remarks>
+ <para>
+ Required property.
+ The mapped syslog severity for the specified level
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Appender.RemotingAppender">
+ <summary>
+ Delivers logging events to a remote logging sink.
+ </summary>
+ <remarks>
+ <para>
+ This Appender is designed to deliver events to a remote sink.
+ That is any object that implements the <see cref="T:log4net.Appender.RemotingAppender.IRemoteLoggingSink"/>
+ interface. It delivers the events using .NET remoting. The
+ object to deliver events to is specified by setting the
+ appenders <see cref="P:log4net.Appender.RemotingAppender.Sink"/> property.</para>
+ <para>
+ The RemotingAppender buffers events before sending them. This allows it to
+ make more efficient use of the remoting infrastructure.</para>
+ <para>
+ Once the buffer is full the events are still not sent immediately.
+ They are scheduled to be sent using a pool thread. The effect is that
+ the send occurs asynchronously. This is very important for a
+ number of non obvious reasons. The remoting infrastructure will
+ flow thread local variables (stored in the <see cref="T:System.Runtime.Remoting.Messaging.CallContext"/>),
+ if they are marked as <see cref="T:System.Runtime.Remoting.Messaging.ILogicalThreadAffinative"/>, across the
+ remoting boundary. If the server is not contactable then
+ the remoting infrastructure will clear the <see cref="T:System.Runtime.Remoting.Messaging.ILogicalThreadAffinative"/>
+ objects from the <see cref="T:System.Runtime.Remoting.Messaging.CallContext"/>. To prevent a logging failure from
+ having side effects on the calling application the remoting call must be made
+ from a separate thread to the one used by the application. A <see cref="T:System.Threading.ThreadPool"/>
+ thread is used for this. If no <see cref="T:System.Threading.ThreadPool"/> thread is available then
+ the events will block in the thread pool manager until a thread is available.</para>
+ <para>
+ Because the events are sent asynchronously using pool threads it is possible to close
+ this appender before all the queued events have been sent.
+ When closing the appender attempts to wait until all the queued events have been sent, but
+ this will timeout after 30 seconds regardless.</para>
+ <para>
+ If this appender is being closed because the <see cref="E:System.AppDomain.ProcessExit"/>
+ event has fired it may not be possible to send all the queued events. During process
+ exit the runtime limits the time that a <see cref="E:System.AppDomain.ProcessExit"/>
+ event handler is allowed to run for. If the runtime terminates the threads before
+ the queued events have been sent then they will be lost. To ensure that all events
+ are sent the appender must be closed before the application exits. See
+ <see cref="M:log4net.Core.LoggerManager.Shutdown"/> for details on how to shutdown
+ log4net programmatically.</para>
+ </remarks>
+ <seealso cref="T:log4net.Appender.RemotingAppender.IRemoteLoggingSink"/>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ <author>Daniel Cazzulino</author>
+ </member>
+ <member name="M:log4net.Appender.RemotingAppender.#ctor">
+ <summary>
+ Initializes a new instance of the <see cref="T:log4net.Appender.RemotingAppender"/> class.
+ </summary>
+ <remarks>
+ <para>
+ Default constructor.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.RemotingAppender.ActivateOptions">
+ <summary>
+ Initialize the appender based on the options set
+ </summary>
+ <remarks>
+ <para>
+ This is part of the <see cref="T:log4net.Core.IOptionHandler"/> delayed object
+ activation scheme. The <see cref="M:log4net.Appender.RemotingAppender.ActivateOptions"/> method must
+ be called on this object after the configuration properties have
+ been set. Until <see cref="M:log4net.Appender.RemotingAppender.ActivateOptions"/> is called this
+ object is in an undefined state and must not be used.
+ </para>
+ <para>
+ If any of the configuration properties are modified then
+ <see cref="M:log4net.Appender.RemotingAppender.ActivateOptions"/> must be called again.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.RemotingAppender.SendBuffer(log4net.Core.LoggingEvent[])">
+ <summary>
+ Send the contents of the buffer to the remote sink.
+ </summary>
+ <remarks>
+ The events are not sent immediately. They are scheduled to be sent
+ using a pool thread. The effect is that the send occurs asynchronously.
+ This is very important for a number of non obvious reasons. The remoting
+ infrastructure will flow thread local variables (stored in the <see cref="T:System.Runtime.Remoting.Messaging.CallContext"/>),
+ if they are marked as <see cref="T:System.Runtime.Remoting.Messaging.ILogicalThreadAffinative"/>, across the
+ remoting boundary. If the server is not contactable then
+ the remoting infrastructure will clear the <see cref="T:System.Runtime.Remoting.Messaging.ILogicalThreadAffinative"/>
+ objects from the <see cref="T:System.Runtime.Remoting.Messaging.CallContext"/>. To prevent a logging failure from
+ having side effects on the calling application the remoting call must be made
+ from a separate thread to the one used by the application. A <see cref="T:System.Threading.ThreadPool"/>
+ thread is used for this. If no <see cref="T:System.Threading.ThreadPool"/> thread is available then
+ the events will block in the thread pool manager until a thread is available.
+ </remarks>
+ <param name="events">The events to send.</param>
+ </member>
+ <member name="M:log4net.Appender.RemotingAppender.OnClose">
+ <summary>
+ Override base class close.
+ </summary>
+ <remarks>
+ <para>
+ This method waits while there are queued work items. The events are
+ sent asynchronously using <see cref="T:System.Threading.ThreadPool"/> work items. These items
+ will be sent once a thread pool thread is available to send them, therefore
+ it is possible to close the appender before all the queued events have been
+ sent.</para>
+ <para>
+ This method attempts to wait until all the queued events have been sent, but this
+ method will timeout after 30 seconds regardless.</para>
+ <para>
+ If the appender is being closed because the <see cref="E:System.AppDomain.ProcessExit"/>
+ event has fired it may not be possible to send all the queued events. During process
+ exit the runtime limits the time that a <see cref="E:System.AppDomain.ProcessExit"/>
+ event handler is allowed to run for.</para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.RemotingAppender.BeginAsyncSend">
+ <summary>
+ A work item is being queued into the thread pool
+ </summary>
+ </member>
+ <member name="M:log4net.Appender.RemotingAppender.EndAsyncSend">
+ <summary>
+ A work item from the thread pool has completed
+ </summary>
+ </member>
+ <member name="M:log4net.Appender.RemotingAppender.SendBufferCallback(System.Object)">
+ <summary>
+ Send the contents of the buffer to the remote sink.
+ </summary>
+ <remarks>
+ This method is designed to be used with the <see cref="T:System.Threading.ThreadPool"/>.
+ This method expects to be passed an array of <see cref="T:log4net.Core.LoggingEvent"/>
+ objects in the state param.
+ </remarks>
+ <param name="state">the logging events to send</param>
+ </member>
+ <member name="F:log4net.Appender.RemotingAppender.m_sinkUrl">
+ <summary>
+ The URL of the remote sink.
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.RemotingAppender.m_sinkObj">
+ <summary>
+ The local proxy (.NET remoting) for the remote logging sink.
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.RemotingAppender.m_queuedCallbackCount">
+ <summary>
+ The number of queued callbacks currently waiting or executing
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.RemotingAppender.m_workQueueEmptyEvent">
+ <summary>
+ Event used to signal when there are no queued work items
+ </summary>
+ <remarks>
+ This event is set when there are no queued work items. In this
+ state it is safe to close the appender.
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.RemotingAppender.Sink">
+ <summary>
+ Gets or sets the URL of the well-known object that will accept
+ the logging events.
+ </summary>
+ <value>
+ The well-known URL of the remote sink.
+ </value>
+ <remarks>
+ <para>
+ The URL of the remoting sink that will accept logging events.
+ The sink must implement the <see cref="T:log4net.Appender.RemotingAppender.IRemoteLoggingSink"/>
+ interface.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Appender.RemotingAppender.IRemoteLoggingSink">
+ <summary>
+ Interface used to deliver <see cref="T:log4net.Core.LoggingEvent"/> objects to a remote sink.
+ </summary>
+ <remarks>
+ This interface must be implemented by a remoting sink
+ if the <see cref="T:log4net.Appender.RemotingAppender"/> is to be used
+ to deliver logging events to the sink.
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.RemotingAppender.IRemoteLoggingSink.LogEvents(log4net.Core.LoggingEvent[])">
+ <summary>
+ Delivers logging events to the remote sink
+ </summary>
+ <param name="events">Array of events to log.</param>
+ <remarks>
+ <para>
+ Delivers logging events to the remote sink
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Appender.RollingFileAppender">
+ <summary>
+ Appender that rolls log files based on size or date or both.
+ </summary>
+ <remarks>
+ <para>
+ RollingFileAppender can roll log files based on size or date or both
+ depending on the setting of the <see cref="P:log4net.Appender.RollingFileAppender.RollingStyle"/> property.
+ When set to <see cref="F:log4net.Appender.RollingFileAppender.RollingMode.Size"/> the log file will be rolled
+ once its size exceeds the <see cref="P:log4net.Appender.RollingFileAppender.MaximumFileSize"/>.
+ When set to <see cref="F:log4net.Appender.RollingFileAppender.RollingMode.Date"/> the log file will be rolled
+ once the date boundary specified in the <see cref="P:log4net.Appender.RollingFileAppender.DatePattern"/> property
+ is crossed.
+ When set to <see cref="F:log4net.Appender.RollingFileAppender.RollingMode.Composite"/> the log file will be
+ rolled once the date boundary specified in the <see cref="P:log4net.Appender.RollingFileAppender.DatePattern"/> property
+ is crossed, but within a date boundary the file will also be rolled
+ once its size exceeds the <see cref="P:log4net.Appender.RollingFileAppender.MaximumFileSize"/>.
+ When set to <see cref="F:log4net.Appender.RollingFileAppender.RollingMode.Once"/> the log file will be rolled when
+ the appender is configured. This effectively means that the log file can be
+ rolled once per program execution.
+ </para>
+ <para>
+ A of few additional optional features have been added:
+ <list type="bullet">
+ <item>Attach date pattern for current log file <see cref="P:log4net.Appender.RollingFileAppender.StaticLogFileName"/></item>
+ <item>Backup number increments for newer files <see cref="P:log4net.Appender.RollingFileAppender.CountDirection"/></item>
+ <item>Infinite number of backups by file size <see cref="P:log4net.Appender.RollingFileAppender.MaxSizeRollBackups"/></item>
+ </list>
+ </para>
+
+ <note>
+ <para>
+ For large or infinite numbers of backup files a <see cref="P:log4net.Appender.RollingFileAppender.CountDirection"/>
+ greater than zero is highly recommended, otherwise all the backup files need
+ to be renamed each time a new backup is created.
+ </para>
+ <para>
+ When Date/Time based rolling is used setting <see cref="P:log4net.Appender.RollingFileAppender.StaticLogFileName"/>
+ to <see langword="true"/> will reduce the number of file renamings to few or none.
+ </para>
+ </note>
+
+ <note type="caution">
+ <para>
+ Changing <see cref="P:log4net.Appender.RollingFileAppender.StaticLogFileName"/> or <see cref="P:log4net.Appender.RollingFileAppender.CountDirection"/> without clearing
+ the log file directory of backup files will cause unexpected and unwanted side effects.
+ </para>
+ </note>
+
+ <para>
+ If Date/Time based rolling is enabled this appender will attempt to roll existing files
+ in the directory without a Date/Time tag based on the last write date of the base log file.
+ The appender only rolls the log file when a message is logged. If Date/Time based rolling
+ is enabled then the appender will not roll the log file at the Date/Time boundary but
+ at the point when the next message is logged after the boundary has been crossed.
+ </para>
+
+ <para>
+ The <see cref="T:log4net.Appender.RollingFileAppender"/> extends the <see cref="T:log4net.Appender.FileAppender"/> and
+ has the same behavior when opening the log file.
+ The appender will first try to open the file for writing when <see cref="M:log4net.Appender.RollingFileAppender.ActivateOptions"/>
+ is called. This will typically be during configuration.
+ If the file cannot be opened for writing the appender will attempt
+ to open the file again each time a message is logged to the appender.
+ If the file cannot be opened for writing when a message is logged then
+ the message will be discarded by this appender.
+ </para>
+ <para>
+ When rolling a backup file necessitates deleting an older backup file the
+ file to be deleted is moved to a temporary name before being deleted.
+ </para>
+
+ <note type="caution">
+ <para>
+ A maximum number of backup files when rolling on date/time boundaries is not supported.
+ </para>
+ </note>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ <author>Aspi Havewala</author>
+ <author>Douglas de la Torre</author>
+ <author>Edward Smit</author>
+ </member>
+ <member name="M:log4net.Appender.RollingFileAppender.#ctor">
+ <summary>
+ Initializes a new instance of the <see cref="T:log4net.Appender.RollingFileAppender"/> class.
+ </summary>
+ <remarks>
+ <para>
+ Default constructor.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.RollingFileAppender.SetQWForFiles(System.IO.TextWriter)">
+ <summary>
+ Sets the quiet writer being used.
+ </summary>
+ <remarks>
+ This method can be overridden by sub classes.
+ </remarks>
+ <param name="writer">the writer to set</param>
+ </member>
+ <member name="M:log4net.Appender.RollingFileAppender.Append(log4net.Core.LoggingEvent)">
+ <summary>
+ Write out a logging event.
+ </summary>
+ <param name="loggingEvent">the event to write to file.</param>
+ <remarks>
+ <para>
+ Handles append time behavior for RollingFileAppender. This checks
+ if a roll over either by date (checked first) or time (checked second)
+ is need and then appends to the file last.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.RollingFileAppender.Append(log4net.Core.LoggingEvent[])">
+ <summary>
+ Write out an array of logging events.
+ </summary>
+ <param name="loggingEvents">the events to write to file.</param>
+ <remarks>
+ <para>
+ Handles append time behavior for RollingFileAppender. This checks
+ if a roll over either by date (checked first) or time (checked second)
+ is need and then appends to the file last.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.RollingFileAppender.AdjustFileBeforeAppend">
+ <summary>
+ Performs any required rolling before outputting the next event
+ </summary>
+ <remarks>
+ <para>
+ Handles append time behavior for RollingFileAppender. This checks
+ if a roll over either by date (checked first) or time (checked second)
+ is need and then appends to the file last.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.RollingFileAppender.OpenFile(System.String,System.Boolean)">
+ <summary>
+ Creates and opens the file for logging. If <see cref="P:log4net.Appender.RollingFileAppender.StaticLogFileName"/>
+ is false then the fully qualified name is determined and used.
+ </summary>
+ <param name="fileName">the name of the file to open</param>
+ <param name="append">true to append to existing file</param>
+ <remarks>
+ <para>This method will ensure that the directory structure
+ for the <paramref name="fileName"/> specified exists.</para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.RollingFileAppender.GetNextOutputFileName(System.String)">
+ <summary>
+ Get the current output file name
+ </summary>
+ <param name="fileName">the base file name</param>
+ <returns>the output file name</returns>
+ <remarks>
+ The output file name is based on the base fileName specified.
+ If <see cref="P:log4net.Appender.RollingFileAppender.StaticLogFileName"/> is set then the output
+ file name is the same as the base file passed in. Otherwise
+ the output file depends on the date pattern, on the count
+ direction or both.
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.RollingFileAppender.DetermineCurSizeRollBackups">
+ <summary>
+ Determines curSizeRollBackups (only within the current roll point)
+ </summary>
+ </member>
+ <member name="M:log4net.Appender.RollingFileAppender.GetWildcardPatternForFile(System.String)">
+ <summary>
+ Generates a wildcard pattern that can be used to find all files
+ that are similar to the base file name.
+ </summary>
+ <param name="baseFileName"></param>
+ <returns></returns>
+ </member>
+ <member name="M:log4net.Appender.RollingFileAppender.GetExistingFiles(System.String)">
+ <summary>
+ Builds a list of filenames for all files matching the base filename plus a file
+ pattern.
+ </summary>
+ <param name="baseFilePath"></param>
+ <returns></returns>
+ </member>
+ <member name="M:log4net.Appender.RollingFileAppender.RollOverIfDateBoundaryCrossing">
+ <summary>
+ Initiates a roll over if needed for crossing a date boundary since the last run.
+ </summary>
+ </member>
+ <member name="M:log4net.Appender.RollingFileAppender.ExistingInit">
+ <summary>
+ Initializes based on existing conditions at time of <see cref="M:log4net.Appender.RollingFileAppender.ActivateOptions"/>.
+ </summary>
+ <remarks>
+ <para>
+ Initializes based on existing conditions at time of <see cref="M:log4net.Appender.RollingFileAppender.ActivateOptions"/>.
+ The following is done
+ <list type="bullet">
+ <item>determine curSizeRollBackups (only within the current roll point)</item>
+ <item>initiates a roll over if needed for crossing a date boundary since the last run.</item>
+ </list>
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.RollingFileAppender.InitializeFromOneFile(System.String,System.String)">
+ <summary>
+ Does the work of bumping the 'current' file counter higher
+ to the highest count when an incremental file name is seen.
+ The highest count is either the first file (when count direction
+ is greater than 0) or the last file (when count direction less than 0).
+ In either case, we want to know the highest count that is present.
+ </summary>
+ <param name="baseFile"></param>
+ <param name="curFileName"></param>
+ </member>
+ <member name="M:log4net.Appender.RollingFileAppender.InitializeRollBackups(System.String,System.Collections.ArrayList)">
+ <summary>
+ Takes a list of files and a base file name, and looks for
+ 'incremented' versions of the base file. Bumps the max
+ count up to the highest count seen.
+ </summary>
+ <param name="baseFile"></param>
+ <param name="arrayFiles"></param>
+ </member>
+ <member name="M:log4net.Appender.RollingFileAppender.ComputeCheckPeriod(System.String)">
+ <summary>
+ Calculates the RollPoint for the datePattern supplied.
+ </summary>
+ <param name="datePattern">the date pattern to calculate the check period for</param>
+ <returns>The RollPoint that is most accurate for the date pattern supplied</returns>
+ <remarks>
+ Essentially the date pattern is examined to determine what the
+ most suitable roll point is. The roll point chosen is the roll point
+ with the smallest period that can be detected using the date pattern
+ supplied. i.e. if the date pattern only outputs the year, month, day
+ and hour then the smallest roll point that can be detected would be
+ and hourly roll point as minutes could not be detected.
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.RollingFileAppender.ActivateOptions">
+ <summary>
+ Initialize the appender based on the options set
+ </summary>
+ <remarks>
+ <para>
+ This is part of the <see cref="T:log4net.Core.IOptionHandler"/> delayed object
+ activation scheme. The <see cref="M:log4net.Appender.RollingFileAppender.ActivateOptions"/> method must
+ be called on this object after the configuration properties have
+ been set. Until <see cref="M:log4net.Appender.RollingFileAppender.ActivateOptions"/> is called this
+ object is in an undefined state and must not be used.
+ </para>
+ <para>
+ If any of the configuration properties are modified then
+ <see cref="M:log4net.Appender.RollingFileAppender.ActivateOptions"/> must be called again.
+ </para>
+ <para>
+ Sets initial conditions including date/time roll over information, first check,
+ scheduledFilename, and calls <see cref="M:log4net.Appender.RollingFileAppender.ExistingInit"/> to initialize
+ the current number of backups.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.RollingFileAppender.RollOverTime(System.Boolean)">
+ <summary>
+ Rollover the file(s) to date/time tagged file(s).
+ </summary>
+ <param name="fileIsOpen">set to true if the file to be rolled is currently open</param>
+ <remarks>
+ <para>
+ Rollover the file(s) to date/time tagged file(s).
+ Resets curSizeRollBackups.
+ If fileIsOpen is set then the new file is opened (through SafeOpenFile).
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.RollingFileAppender.RollFile(System.String,System.String)">
+ <summary>
+ Renames file <paramref name="fromFile"/> to file <paramref name="toFile"/>.
+ </summary>
+ <param name="fromFile">Name of existing file to roll.</param>
+ <param name="toFile">New name for file.</param>
+ <remarks>
+ <para>
+ Renames file <paramref name="fromFile"/> to file <paramref name="toFile"/>. It
+ also checks for existence of target file and deletes if it does.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.RollingFileAppender.FileExists(System.String)">
+ <summary>
+ Test if a file exists at a specified path
+ </summary>
+ <param name="path">the path to the file</param>
+ <returns>true if the file exists</returns>
+ <remarks>
+ <para>
+ Test if a file exists at a specified path
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.RollingFileAppender.DeleteFile(System.String)">
+ <summary>
+ Deletes the specified file if it exists.
+ </summary>
+ <param name="fileName">The file to delete.</param>
+ <remarks>
+ <para>
+ Delete a file if is exists.
+ The file is first moved to a new filename then deleted.
+ This allows the file to be removed even when it cannot
+ be deleted, but it still can be moved.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.RollingFileAppender.RollOverSize">
+ <summary>
+ Implements file roll base on file size.
+ </summary>
+ <remarks>
+ <para>
+ If the maximum number of size based backups is reached
+ (<c>curSizeRollBackups == maxSizeRollBackups</c>) then the oldest
+ file is deleted -- its index determined by the sign of countDirection.
+ If <c>countDirection</c> &lt; 0, then files
+ {<c>File.1</c>, ..., <c>File.curSizeRollBackups -1</c>}
+ are renamed to {<c>File.2</c>, ...,
+ <c>File.curSizeRollBackups</c>}. Moreover, <c>File</c> is
+ renamed <c>File.1</c> and closed.
+ </para>
+ <para>
+ A new file is created to receive further log output.
+ </para>
+ <para>
+ If <c>maxSizeRollBackups</c> is equal to zero, then the
+ <c>File</c> is truncated with no backup files created.
+ </para>
+ <para>
+ If <c>maxSizeRollBackups</c> &lt; 0, then <c>File</c> is
+ renamed if needed and no files are deleted.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.RollingFileAppender.RollOverRenameFiles(System.String)">
+ <summary>
+ Implements file roll.
+ </summary>
+ <param name="baseFileName">the base name to rename</param>
+ <remarks>
+ <para>
+ If the maximum number of size based backups is reached
+ (<c>curSizeRollBackups == maxSizeRollBackups</c>) then the oldest
+ file is deleted -- its index determined by the sign of countDirection.
+ If <c>countDirection</c> &lt; 0, then files
+ {<c>File.1</c>, ..., <c>File.curSizeRollBackups -1</c>}
+ are renamed to {<c>File.2</c>, ...,
+ <c>File.curSizeRollBackups</c>}.
+ </para>
+ <para>
+ If <c>maxSizeRollBackups</c> is equal to zero, then the
+ <c>File</c> is truncated with no backup files created.
+ </para>
+ <para>
+ If <c>maxSizeRollBackups</c> &lt; 0, then <c>File</c> is
+ renamed if needed and no files are deleted.
+ </para>
+ <para>
+ This is called by <see cref="M:log4net.Appender.RollingFileAppender.RollOverSize"/> to rename the files.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.RollingFileAppender.NextCheckDate(System.DateTime,log4net.Appender.RollingFileAppender.RollPoint)">
+ <summary>
+ Get the start time of the next window for the current rollpoint
+ </summary>
+ <param name="currentDateTime">the current date</param>
+ <param name="rollPoint">the type of roll point we are working with</param>
+ <returns>the start time for the next roll point an interval after the currentDateTime date</returns>
+ <remarks>
+ <para>
+ Returns the date of the next roll point after the currentDateTime date passed to the method.
+ </para>
+ <para>
+ The basic strategy is to subtract the time parts that are less significant
+ than the rollpoint from the current time. This should roll the time back to
+ the start of the time window for the current rollpoint. Then we add 1 window
+ worth of time and get the start time of the next window for the rollpoint.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Appender.RollingFileAppender.m_dateTime">
+ <summary>
+ This object supplies the current date/time. Allows test code to plug in
+ a method to control this class when testing date/time based rolling.
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.RollingFileAppender.m_datePattern">
+ <summary>
+ The date pattern. By default, the pattern is set to <c>".yyyy-MM-dd"</c>
+ meaning daily rollover.
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.RollingFileAppender.m_scheduledFilename">
+ <summary>
+ The actual formatted filename that is currently being written to
+ or will be the file transferred to on roll over
+ (based on staticLogFileName).
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.RollingFileAppender.m_nextCheck">
+ <summary>
+ The timestamp when we shall next recompute the filename.
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.RollingFileAppender.m_now">
+ <summary>
+ Holds date of last roll over
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.RollingFileAppender.m_rollPoint">
+ <summary>
+ The type of rolling done
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.RollingFileAppender.m_maxFileSize">
+ <summary>
+ The default maximum file size is 10MB
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.RollingFileAppender.m_maxSizeRollBackups">
+ <summary>
+ There is zero backup files by default
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.RollingFileAppender.m_curSizeRollBackups">
+ <summary>
+ How many sized based backups have been made so far
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.RollingFileAppender.m_countDirection">
+ <summary>
+ The rolling file count direction.
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.RollingFileAppender.m_rollingStyle">
+ <summary>
+ The rolling mode used in this appender.
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.RollingFileAppender.m_rollDate">
+ <summary>
+ Cache flag set if we are rolling by date.
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.RollingFileAppender.m_rollSize">
+ <summary>
+ Cache flag set if we are rolling by size.
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.RollingFileAppender.m_staticLogFileName">
+ <summary>
+ Value indicating whether to always log to the same file.
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.RollingFileAppender.m_baseFileName">
+ <summary>
+ FileName provided in configuration. Used for rolling properly
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.RollingFileAppender.s_date1970">
+ <summary>
+ The 1st of January 1970 in UTC
+ </summary>
+ </member>
+ <member name="P:log4net.Appender.RollingFileAppender.DatePattern">
+ <summary>
+ Gets or sets the date pattern to be used for generating file names
+ when rolling over on date.
+ </summary>
+ <value>
+ The date pattern to be used for generating file names when rolling
+ over on date.
+ </value>
+ <remarks>
+ <para>
+ Takes a string in the same format as expected by
+ <see cref="T:log4net.DateFormatter.SimpleDateFormatter"/>.
+ </para>
+ <para>
+ This property determines the rollover schedule when rolling over
+ on date.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.RollingFileAppender.MaxSizeRollBackups">
+ <summary>
+ Gets or sets the maximum number of backup files that are kept before
+ the oldest is erased.
+ </summary>
+ <value>
+ The maximum number of backup files that are kept before the oldest is
+ erased.
+ </value>
+ <remarks>
+ <para>
+ If set to zero, then there will be no backup files and the log file
+ will be truncated when it reaches <see cref="P:log4net.Appender.RollingFileAppender.MaxFileSize"/>.
+ </para>
+ <para>
+ If a negative number is supplied then no deletions will be made. Note
+ that this could result in very slow performance as a large number of
+ files are rolled over unless <see cref="P:log4net.Appender.RollingFileAppender.CountDirection"/> is used.
+ </para>
+ <para>
+ The maximum applies to <b>each</b> time based group of files and
+ <b>not</b> the total.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.RollingFileAppender.MaxFileSize">
+ <summary>
+ Gets or sets the maximum size that the output file is allowed to reach
+ before being rolled over to backup files.
+ </summary>
+ <value>
+ The maximum size in bytes that the output file is allowed to reach before being
+ rolled over to backup files.
+ </value>
+ <remarks>
+ <para>
+ This property is equivalent to <see cref="P:log4net.Appender.RollingFileAppender.MaximumFileSize"/> except
+ that it is required for differentiating the setter taking a
+ <see cref="T:System.Int64"/> argument from the setter taking a <see cref="T:System.String"/>
+ argument.
+ </para>
+ <para>
+ The default maximum file size is 10MB (10*1024*1024).
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.RollingFileAppender.MaximumFileSize">
+ <summary>
+ Gets or sets the maximum size that the output file is allowed to reach
+ before being rolled over to backup files.
+ </summary>
+ <value>
+ The maximum size that the output file is allowed to reach before being
+ rolled over to backup files.
+ </value>
+ <remarks>
+ <para>
+ This property allows you to specify the maximum size with the
+ suffixes "KB", "MB" or "GB" so that the size is interpreted being
+ expressed respectively in kilobytes, megabytes or gigabytes.
+ </para>
+ <para>
+ For example, the value "10KB" will be interpreted as 10240 bytes.
+ </para>
+ <para>
+ The default maximum file size is 10MB.
+ </para>
+ <para>
+ If you have the option to set the maximum file size programmatically
+ consider using the <see cref="P:log4net.Appender.RollingFileAppender.MaxFileSize"/> property instead as this
+ allows you to set the size in bytes as a <see cref="T:System.Int64"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.RollingFileAppender.CountDirection">
+ <summary>
+ Gets or sets the rolling file count direction.
+ </summary>
+ <value>
+ The rolling file count direction.
+ </value>
+ <remarks>
+ <para>
+ Indicates if the current file is the lowest numbered file or the
+ highest numbered file.
+ </para>
+ <para>
+ By default newer files have lower numbers (<see cref="P:log4net.Appender.RollingFileAppender.CountDirection"/> &lt; 0),
+ i.e. log.1 is most recent, log.5 is the 5th backup, etc...
+ </para>
+ <para>
+ <see cref="P:log4net.Appender.RollingFileAppender.CountDirection"/> &gt;= 0 does the opposite i.e.
+ log.1 is the first backup made, log.5 is the 5th backup made, etc.
+ For infinite backups use <see cref="P:log4net.Appender.RollingFileAppender.CountDirection"/> &gt;= 0 to reduce
+ rollover costs.
+ </para>
+ <para>The default file count direction is -1.</para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.RollingFileAppender.RollingStyle">
+ <summary>
+ Gets or sets the rolling style.
+ </summary>
+ <value>The rolling style.</value>
+ <remarks>
+ <para>
+ The default rolling style is <see cref="F:log4net.Appender.RollingFileAppender.RollingMode.Composite"/>.
+ </para>
+ <para>
+ When set to <see cref="F:log4net.Appender.RollingFileAppender.RollingMode.Once"/> this appender's
+ <see cref="P:log4net.Appender.FileAppender.AppendToFile"/> property is set to <c>false</c>, otherwise
+ the appender would append to a single file rather than rolling
+ the file each time it is opened.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.RollingFileAppender.StaticLogFileName">
+ <summary>
+ Gets or sets a value indicating whether to always log to
+ the same file.
+ </summary>
+ <value>
+ <c>true</c> if always should be logged to the same file, otherwise <c>false</c>.
+ </value>
+ <remarks>
+ <para>
+ By default file.log is always the current file. Optionally
+ file.log.yyyy-mm-dd for current formatted datePattern can by the currently
+ logging file (or file.log.curSizeRollBackup or even
+ file.log.yyyy-mm-dd.curSizeRollBackup).
+ </para>
+ <para>
+ This will make time based rollovers with a large number of backups
+ much faster as the appender it won't have to rename all the backups!
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Appender.RollingFileAppender.RollingMode">
+ <summary>
+ Style of rolling to use
+ </summary>
+ <remarks>
+ <para>
+ Style of rolling to use
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Appender.RollingFileAppender.RollingMode.Once">
+ <summary>
+ Roll files once per program execution
+ </summary>
+ <remarks>
+ <para>
+ Roll files once per program execution.
+ Well really once each time this appender is
+ configured.
+ </para>
+ <para>
+ Setting this option also sets <c>AppendToFile</c> to
+ <c>false</c> on the <c>RollingFileAppender</c>, otherwise
+ this appender would just be a normal file appender.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Appender.RollingFileAppender.RollingMode.Size">
+ <summary>
+ Roll files based only on the size of the file
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.RollingFileAppender.RollingMode.Date">
+ <summary>
+ Roll files based only on the date
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.RollingFileAppender.RollingMode.Composite">
+ <summary>
+ Roll files based on both the size and date of the file
+ </summary>
+ </member>
+ <member name="T:log4net.Appender.RollingFileAppender.RollPoint">
+ <summary>
+ The code assumes that the following 'time' constants are in a increasing sequence.
+ </summary>
+ <remarks>
+ <para>
+ The code assumes that the following 'time' constants are in a increasing sequence.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Appender.RollingFileAppender.RollPoint.InvalidRollPoint">
+ <summary>
+ Roll the log not based on the date
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.RollingFileAppender.RollPoint.TopOfMinute">
+ <summary>
+ Roll the log for each minute
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.RollingFileAppender.RollPoint.TopOfHour">
+ <summary>
+ Roll the log for each hour
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.RollingFileAppender.RollPoint.HalfDay">
+ <summary>
+ Roll the log twice a day (midday and midnight)
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.RollingFileAppender.RollPoint.TopOfDay">
+ <summary>
+ Roll the log each day (midnight)
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.RollingFileAppender.RollPoint.TopOfWeek">
+ <summary>
+ Roll the log each week
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.RollingFileAppender.RollPoint.TopOfMonth">
+ <summary>
+ Roll the log each month
+ </summary>
+ </member>
+ <member name="T:log4net.Appender.RollingFileAppender.IDateTime">
+ <summary>
+ This interface is used to supply Date/Time information to the <see cref="T:log4net.Appender.RollingFileAppender"/>.
+ </summary>
+ <remarks>
+ This interface is used to supply Date/Time information to the <see cref="T:log4net.Appender.RollingFileAppender"/>.
+ Used primarily to allow test classes to plug themselves in so they can
+ supply test date/times.
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.RollingFileAppender.IDateTime.Now">
+ <summary>
+ Gets the <i>current</i> time.
+ </summary>
+ <value>The <i>current</i> time.</value>
+ <remarks>
+ <para>
+ Gets the <i>current</i> time.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Appender.RollingFileAppender.DefaultDateTime">
+ <summary>
+ Default implementation of <see cref="T:log4net.Appender.RollingFileAppender.IDateTime"/> that returns the current time.
+ </summary>
+ </member>
+ <member name="P:log4net.Appender.RollingFileAppender.DefaultDateTime.Now">
+ <summary>
+ Gets the <b>current</b> time.
+ </summary>
+ <value>The <b>current</b> time.</value>
+ <remarks>
+ <para>
+ Gets the <b>current</b> time.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Appender.SmtpAppender">
+ <summary>
+ Send an e-mail when a specific logging event occurs, typically on errors
+ or fatal errors.
+ </summary>
+ <remarks>
+ <para>
+ The number of logging events delivered in this e-mail depend on
+ the value of <see cref="P:log4net.Appender.BufferingAppenderSkeleton.BufferSize"/> option. The
+ <see cref="T:log4net.Appender.SmtpAppender"/> keeps only the last
+ <see cref="P:log4net.Appender.BufferingAppenderSkeleton.BufferSize"/> logging events in its
+ cyclic buffer. This keeps memory requirements at a reasonable level while
+ still delivering useful application context.
+ </para>
+ <note type="caution">
+ Authentication and setting the server Port are only available on the MS .NET 1.1 runtime.
+ For these features to be enabled you need to ensure that you are using a version of
+ the log4net assembly that is built against the MS .NET 1.1 framework and that you are
+ running the your application on the MS .NET 1.1 runtime. On all other platforms only sending
+ unauthenticated messages to a server listening on port 25 (the default) is supported.
+ </note>
+ <para>
+ Authentication is supported by setting the <see cref="P:log4net.Appender.SmtpAppender.Authentication"/> property to
+ either <see cref="F:log4net.Appender.SmtpAppender.SmtpAuthentication.Basic"/> or <see cref="F:log4net.Appender.SmtpAppender.SmtpAuthentication.Ntlm"/>.
+ If using <see cref="F:log4net.Appender.SmtpAppender.SmtpAuthentication.Basic"/> authentication then the <see cref="P:log4net.Appender.SmtpAppender.Username"/>
+ and <see cref="P:log4net.Appender.SmtpAppender.Password"/> properties must also be set.
+ </para>
+ <para>
+ To set the SMTP server port use the <see cref="P:log4net.Appender.SmtpAppender.Port"/> property. The default port is 25.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="M:log4net.Appender.SmtpAppender.#ctor">
+ <summary>
+ Default constructor
+ </summary>
+ <remarks>
+ <para>
+ Default constructor
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.SmtpAppender.SendBuffer(log4net.Core.LoggingEvent[])">
+ <summary>
+ Sends the contents of the cyclic buffer as an e-mail message.
+ </summary>
+ <param name="events">The logging events to send.</param>
+ </member>
+ <member name="M:log4net.Appender.SmtpAppender.SendEmail(System.String)">
+ <summary>
+ Send the email message
+ </summary>
+ <param name="messageBody">the body text to include in the mail</param>
+ </member>
+ <member name="P:log4net.Appender.SmtpAppender.To">
+ <summary>
+ Gets or sets a semicolon-delimited list of recipient e-mail addresses.
+ </summary>
+ <value>
+ A semicolon-delimited list of e-mail addresses.
+ </value>
+ <remarks>
+ <para>
+ A semicolon-delimited list of recipient e-mail addresses.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.SmtpAppender.From">
+ <summary>
+ Gets or sets the e-mail address of the sender.
+ </summary>
+ <value>
+ The e-mail address of the sender.
+ </value>
+ <remarks>
+ <para>
+ The e-mail address of the sender.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.SmtpAppender.Subject">
+ <summary>
+ Gets or sets the subject line of the e-mail message.
+ </summary>
+ <value>
+ The subject line of the e-mail message.
+ </value>
+ <remarks>
+ <para>
+ The subject line of the e-mail message.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.SmtpAppender.SmtpHost">
+ <summary>
+ Gets or sets the name of the SMTP relay mail server to use to send
+ the e-mail messages.
+ </summary>
+ <value>
+ The name of the e-mail relay server. If SmtpServer is not set, the
+ name of the local SMTP server is used.
+ </value>
+ <remarks>
+ <para>
+ The name of the e-mail relay server. If SmtpServer is not set, the
+ name of the local SMTP server is used.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.SmtpAppender.LocationInfo">
+ <summary>
+ Obsolete
+ </summary>
+ <remarks>
+ Use the BufferingAppenderSkeleton Fix methods instead
+ </remarks>
+ <remarks>
+ <para>
+ Obsolete property.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.SmtpAppender.Authentication">
+ <summary>
+ The mode to use to authentication with the SMTP server
+ </summary>
+ <remarks>
+ <note type="caution">Authentication is only available on the MS .NET 1.1 runtime.</note>
+ <para>
+ Valid Authentication mode values are: <see cref="F:log4net.Appender.SmtpAppender.SmtpAuthentication.None"/>,
+ <see cref="F:log4net.Appender.SmtpAppender.SmtpAuthentication.Basic"/>, and <see cref="F:log4net.Appender.SmtpAppender.SmtpAuthentication.Ntlm"/>.
+ The default value is <see cref="F:log4net.Appender.SmtpAppender.SmtpAuthentication.None"/>. When using
+ <see cref="F:log4net.Appender.SmtpAppender.SmtpAuthentication.Basic"/> you must specify the <see cref="P:log4net.Appender.SmtpAppender.Username"/>
+ and <see cref="P:log4net.Appender.SmtpAppender.Password"/> to use to authenticate.
+ When using <see cref="F:log4net.Appender.SmtpAppender.SmtpAuthentication.Ntlm"/> the Windows credentials for the current
+ thread, if impersonating, or the process will be used to authenticate.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.SmtpAppender.Username">
+ <summary>
+ The username to use to authenticate with the SMTP server
+ </summary>
+ <remarks>
+ <note type="caution">Authentication is only available on the MS .NET 1.1 runtime.</note>
+ <para>
+ A <see cref="P:log4net.Appender.SmtpAppender.Username"/> and <see cref="P:log4net.Appender.SmtpAppender.Password"/> must be specified when
+ <see cref="P:log4net.Appender.SmtpAppender.Authentication"/> is set to <see cref="F:log4net.Appender.SmtpAppender.SmtpAuthentication.Basic"/>,
+ otherwise the username will be ignored.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.SmtpAppender.Password">
+ <summary>
+ The password to use to authenticate with the SMTP server
+ </summary>
+ <remarks>
+ <note type="caution">Authentication is only available on the MS .NET 1.1 runtime.</note>
+ <para>
+ A <see cref="P:log4net.Appender.SmtpAppender.Username"/> and <see cref="P:log4net.Appender.SmtpAppender.Password"/> must be specified when
+ <see cref="P:log4net.Appender.SmtpAppender.Authentication"/> is set to <see cref="F:log4net.Appender.SmtpAppender.SmtpAuthentication.Basic"/>,
+ otherwise the password will be ignored.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.SmtpAppender.Port">
+ <summary>
+ The port on which the SMTP server is listening
+ </summary>
+ <remarks>
+ <note type="caution">Server Port is only available on the MS .NET 1.1 runtime.</note>
+ <para>
+ The port on which the SMTP server is listening. The default
+ port is <c>25</c>. The Port can only be changed when running on
+ the MS .NET 1.1 runtime.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.SmtpAppender.Priority">
+ <summary>
+ Gets or sets the priority of the e-mail message
+ </summary>
+ <value>
+ One of the <see cref="T:System.Web.Mail.MailPriority"/> values.
+ </value>
+ <remarks>
+ <para>
+ Sets the priority of the e-mails generated by this
+ appender. The default priority is <see cref="F:System.Web.Mail.MailPriority.Normal"/>.
+ </para>
+ <para>
+ If you are using this appender to report errors then
+ you may want to set the priority to <see cref="F:System.Web.Mail.MailPriority.High"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.SmtpAppender.RequiresLayout">
+ <summary>
+ This appender requires a <see cref="N:log4net.Layout"/> to be set.
+ </summary>
+ <value><c>true</c></value>
+ <remarks>
+ <para>
+ This appender requires a <see cref="N:log4net.Layout"/> to be set.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Appender.SmtpAppender.SmtpAuthentication">
+ <summary>
+ Values for the <see cref="P:log4net.Appender.SmtpAppender.Authentication"/> property.
+ </summary>
+ <remarks>
+ <para>
+ SMTP authentication modes.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Appender.SmtpAppender.SmtpAuthentication.None">
+ <summary>
+ No authentication
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.SmtpAppender.SmtpAuthentication.Basic">
+ <summary>
+ Basic authentication.
+ </summary>
+ <remarks>
+ Requires a username and password to be supplied
+ </remarks>
+ </member>
+ <member name="F:log4net.Appender.SmtpAppender.SmtpAuthentication.Ntlm">
+ <summary>
+ Integrated authentication
+ </summary>
+ <remarks>
+ Uses the Windows credentials from the current thread or process to authenticate.
+ </remarks>
+ </member>
+ <member name="T:log4net.Appender.SmtpPickupDirAppender">
+ <summary>
+ Send an email when a specific logging event occurs, typically on errors
+ or fatal errors. Rather than sending via smtp it writes a file into the
+ directory specified by <see cref="P:log4net.Appender.SmtpPickupDirAppender.PickupDir"/>. This allows services such
+ as the IIS SMTP agent to manage sending the messages.
+ </summary>
+ <remarks>
+ <para>
+ The configuration for this appender is identical to that of the <c>SMTPAppender</c>,
+ except that instead of specifying the <c>SMTPAppender.SMTPHost</c> you specify
+ <see cref="P:log4net.Appender.SmtpPickupDirAppender.PickupDir"/>.
+ </para>
+ <para>
+ The number of logging events delivered in this e-mail depend on
+ the value of <see cref="P:log4net.Appender.BufferingAppenderSkeleton.BufferSize"/> option. The
+ <see cref="T:log4net.Appender.SmtpPickupDirAppender"/> keeps only the last
+ <see cref="P:log4net.Appender.BufferingAppenderSkeleton.BufferSize"/> logging events in its
+ cyclic buffer. This keeps memory requirements at a reasonable level while
+ still delivering useful application context.
+ </para>
+ </remarks>
+ <author>Niall Daley</author>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="M:log4net.Appender.SmtpPickupDirAppender.#ctor">
+ <summary>
+ Default constructor
+ </summary>
+ <remarks>
+ <para>
+ Default constructor
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.SmtpPickupDirAppender.SendBuffer(log4net.Core.LoggingEvent[])">
+ <summary>
+ Sends the contents of the cyclic buffer as an e-mail message.
+ </summary>
+ <param name="events">The logging events to send.</param>
+ <remarks>
+ <para>
+ Sends the contents of the cyclic buffer as an e-mail message.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.SmtpPickupDirAppender.ActivateOptions">
+ <summary>
+ Activate the options on this appender.
+ </summary>
+ <remarks>
+ <para>
+ This is part of the <see cref="T:log4net.Core.IOptionHandler"/> delayed object
+ activation scheme. The <see cref="M:log4net.Appender.SmtpPickupDirAppender.ActivateOptions"/> method must
+ be called on this object after the configuration properties have
+ been set. Until <see cref="M:log4net.Appender.SmtpPickupDirAppender.ActivateOptions"/> is called this
+ object is in an undefined state and must not be used.
+ </para>
+ <para>
+ If any of the configuration properties are modified then
+ <see cref="M:log4net.Appender.SmtpPickupDirAppender.ActivateOptions"/> must be called again.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.SmtpPickupDirAppender.ConvertToFullPath(System.String)">
+ <summary>
+ Convert a path into a fully qualified path.
+ </summary>
+ <param name="path">The path to convert.</param>
+ <returns>The fully qualified path.</returns>
+ <remarks>
+ <para>
+ Converts the path specified to a fully
+ qualified path. If the path is relative it is
+ taken as relative from the application base
+ directory.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Appender.SmtpPickupDirAppender.m_securityContext">
+ <summary>
+ The security context to use for privileged calls
+ </summary>
+ </member>
+ <member name="P:log4net.Appender.SmtpPickupDirAppender.To">
+ <summary>
+ Gets or sets a semicolon-delimited list of recipient e-mail addresses.
+ </summary>
+ <value>
+ A semicolon-delimited list of e-mail addresses.
+ </value>
+ <remarks>
+ <para>
+ A semicolon-delimited list of e-mail addresses.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.SmtpPickupDirAppender.From">
+ <summary>
+ Gets or sets the e-mail address of the sender.
+ </summary>
+ <value>
+ The e-mail address of the sender.
+ </value>
+ <remarks>
+ <para>
+ The e-mail address of the sender.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.SmtpPickupDirAppender.Subject">
+ <summary>
+ Gets or sets the subject line of the e-mail message.
+ </summary>
+ <value>
+ The subject line of the e-mail message.
+ </value>
+ <remarks>
+ <para>
+ The subject line of the e-mail message.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.SmtpPickupDirAppender.PickupDir">
+ <summary>
+ Gets or sets the path to write the messages to.
+ </summary>
+ <remarks>
+ <para>
+ Gets or sets the path to write the messages to. This should be the same
+ as that used by the agent sending the messages.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.SmtpPickupDirAppender.SecurityContext">
+ <summary>
+ Gets or sets the <see cref="P:log4net.Appender.SmtpPickupDirAppender.SecurityContext"/> used to write to the pickup directory.
+ </summary>
+ <value>
+ The <see cref="P:log4net.Appender.SmtpPickupDirAppender.SecurityContext"/> used to write to the pickup directory.
+ </value>
+ <remarks>
+ <para>
+ Unless a <see cref="P:log4net.Appender.SmtpPickupDirAppender.SecurityContext"/> specified here for this appender
+ the <see cref="P:log4net.Core.SecurityContextProvider.DefaultProvider"/> is queried for the
+ security context to use. The default behavior is to use the security context
+ of the current thread.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.SmtpPickupDirAppender.RequiresLayout">
+ <summary>
+ This appender requires a <see cref="N:log4net.Layout"/> to be set.
+ </summary>
+ <value><c>true</c></value>
+ <remarks>
+ <para>
+ This appender requires a <see cref="N:log4net.Layout"/> to be set.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Appender.TelnetAppender">
+ <summary>
+ Appender that allows clients to connect via Telnet to receive log messages
+ </summary>
+ <remarks>
+ <para>
+ The TelnetAppender accepts socket connections and streams logging messages
+ back to the client.
+ The output is provided in a telnet-friendly way so that a log can be monitored
+ over a TCP/IP socket.
+ This allows simple remote monitoring of application logging.
+ </para>
+ <para>
+ The default <see cref="P:log4net.Appender.TelnetAppender.Port"/> is 23 (the telnet port).
+ </para>
+ </remarks>
+ <author>Keith Long</author>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="M:log4net.Appender.TelnetAppender.#ctor">
+ <summary>
+ Default constructor
+ </summary>
+ <remarks>
+ <para>
+ Default constructor
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.TelnetAppender.OnClose">
+ <summary>
+ Overrides the parent method to close the socket handler
+ </summary>
+ <remarks>
+ <para>
+ Closes all the outstanding connections.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.TelnetAppender.ActivateOptions">
+ <summary>
+ Initialize the appender based on the options set.
+ </summary>
+ <remarks>
+ <para>
+ This is part of the <see cref="T:log4net.Core.IOptionHandler"/> delayed object
+ activation scheme. The <see cref="M:log4net.Appender.TelnetAppender.ActivateOptions"/> method must
+ be called on this object after the configuration properties have
+ been set. Until <see cref="M:log4net.Appender.TelnetAppender.ActivateOptions"/> is called this
+ object is in an undefined state and must not be used.
+ </para>
+ <para>
+ If any of the configuration properties are modified then
+ <see cref="M:log4net.Appender.TelnetAppender.ActivateOptions"/> must be called again.
+ </para>
+ <para>
+ Create the socket handler and wait for connections
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.TelnetAppender.Append(log4net.Core.LoggingEvent)">
+ <summary>
+ Writes the logging event to each connected client.
+ </summary>
+ <param name="loggingEvent">The event to log.</param>
+ <remarks>
+ <para>
+ Writes the logging event to each connected client.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.TelnetAppender.Port">
+ <summary>
+ Gets or sets the TCP port number on which this <see cref="T:log4net.Appender.TelnetAppender"/> will listen for connections.
+ </summary>
+ <value>
+ An integer value in the range <see cref="F:System.Net.IPEndPoint.MinPort"/> to <see cref="F:System.Net.IPEndPoint.MaxPort"/>
+ indicating the TCP port number on which this <see cref="T:log4net.Appender.TelnetAppender"/> will listen for connections.
+ </value>
+ <remarks>
+ <para>
+ The default value is 23 (the telnet port).
+ </para>
+ </remarks>
+ <exception cref="T:System.ArgumentOutOfRangeException">The value specified is less than <see cref="F:System.Net.IPEndPoint.MinPort"/>
+ or greater than <see cref="F:System.Net.IPEndPoint.MaxPort"/>.</exception>
+ </member>
+ <member name="P:log4net.Appender.TelnetAppender.RequiresLayout">
+ <summary>
+ This appender requires a <see cref="N:log4net.Layout"/> to be set.
+ </summary>
+ <value><c>true</c></value>
+ <remarks>
+ <para>
+ This appender requires a <see cref="N:log4net.Layout"/> to be set.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Appender.TelnetAppender.SocketHandler">
+ <summary>
+ Helper class to manage connected clients
+ </summary>
+ <remarks>
+ <para>
+ The SocketHandler class is used to accept connections from
+ clients. It is threaded so that clients can connect/disconnect
+ asynchronously.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.TelnetAppender.SocketHandler.#ctor(System.Int32)">
+ <summary>
+ Opens a new server port on <paramref ref="port"/>
+ </summary>
+ <param name="port">the local port to listen on for connections</param>
+ <remarks>
+ <para>
+ Creates a socket handler on the specified local server port.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.TelnetAppender.SocketHandler.Send(System.String)">
+ <summary>
+ Sends a string message to each of the connected clients
+ </summary>
+ <param name="message">the text to send</param>
+ <remarks>
+ <para>
+ Sends a string message to each of the connected clients
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.TelnetAppender.SocketHandler.AddClient(log4net.Appender.TelnetAppender.SocketHandler.SocketClient)">
+ <summary>
+ Add a client to the internal clients list
+ </summary>
+ <param name="client">client to add</param>
+ </member>
+ <member name="M:log4net.Appender.TelnetAppender.SocketHandler.RemoveClient(log4net.Appender.TelnetAppender.SocketHandler.SocketClient)">
+ <summary>
+ Remove a client from the internal clients list
+ </summary>
+ <param name="client">client to remove</param>
+ </member>
+ <member name="M:log4net.Appender.TelnetAppender.SocketHandler.OnConnect(System.IAsyncResult)">
+ <summary>
+ Callback used to accept a connection on the server socket
+ </summary>
+ <param name="asyncResult">The result of the asynchronous operation</param>
+ <remarks>
+ <para>
+ On connection adds to the list of connections
+ if there are two many open connections you will be disconnected
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.TelnetAppender.SocketHandler.Dispose">
+ <summary>
+ Close all network connections
+ </summary>
+ <remarks>
+ <para>
+ Make sure we close all network connections
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.TelnetAppender.SocketHandler.HasConnections">
+ <summary>
+ Test if this handler has active connections
+ </summary>
+ <value>
+ <c>true</c> if this handler has active connections
+ </value>
+ <remarks>
+ <para>
+ This property will be <c>true</c> while this handler has
+ active connections, that is at least one connection that
+ the handler will attempt to send a message to.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Appender.TelnetAppender.SocketHandler.SocketClient">
+ <summary>
+ Class that represents a client connected to this handler
+ </summary>
+ <remarks>
+ <para>
+ Class that represents a client connected to this handler
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.TelnetAppender.SocketHandler.SocketClient.#ctor(System.Net.Sockets.Socket)">
+ <summary>
+ Create this <see cref="T:log4net.Appender.TelnetAppender.SocketHandler.SocketClient"/> for the specified <see cref="T:System.Net.Sockets.Socket"/>
+ </summary>
+ <param name="socket">the client's socket</param>
+ <remarks>
+ <para>
+ Opens a stream writer on the socket.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.TelnetAppender.SocketHandler.SocketClient.Send(System.String)">
+ <summary>
+ Write a string to the client
+ </summary>
+ <param name="message">string to send</param>
+ <remarks>
+ <para>
+ Write a string to the client
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.TelnetAppender.SocketHandler.SocketClient.Dispose">
+ <summary>
+ Cleanup the clients connection
+ </summary>
+ <remarks>
+ <para>
+ Close the socket connection.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Appender.TraceAppender">
+ <summary>
+ Appends log events to the <see cref="T:System.Diagnostics.Trace"/> system.
+ </summary>
+ <remarks>
+ <para>
+ The application configuration file can be used to control what listeners
+ are actually used. See the MSDN documentation for the
+ <see cref="T:System.Diagnostics.Trace"/> class for details on configuring the
+ trace system.
+ </para>
+ <para>
+ Events are written using the <c>System.Diagnostics.Trace.Write(string,string)</c>
+ method. The event's logger name is passed as the value for the category name to the Write method.
+ </para>
+ <para>
+ <b>Compact Framework</b><br/>
+ The Compact Framework does not support the <see cref="T:System.Diagnostics.Trace"/>
+ class for any operation except <c>Assert</c>. When using the Compact Framework this
+ appender will write to the <see cref="T:System.Diagnostics.Debug"/> system rather than
+ the Trace system. This appender will therefore behave like the <see cref="T:log4net.Appender.DebugAppender"/>.
+ </para>
+ </remarks>
+ <author>Douglas de la Torre</author>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="M:log4net.Appender.TraceAppender.#ctor">
+ <summary>
+ Initializes a new instance of the <see cref="T:log4net.Appender.TraceAppender"/>.
+ </summary>
+ <remarks>
+ <para>
+ Default constructor.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.TraceAppender.#ctor(log4net.Layout.ILayout)">
+ <summary>
+ Initializes a new instance of the <see cref="T:log4net.Appender.TraceAppender"/>
+ with a specified layout.
+ </summary>
+ <param name="layout">The layout to use with this appender.</param>
+ <remarks>
+ <para>
+ Obsolete constructor.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.TraceAppender.Append(log4net.Core.LoggingEvent)">
+ <summary>
+ Writes the logging event to the <see cref="T:System.Diagnostics.Trace"/> system.
+ </summary>
+ <param name="loggingEvent">The event to log.</param>
+ <remarks>
+ <para>
+ Writes the logging event to the <see cref="T:System.Diagnostics.Trace"/> system.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Appender.TraceAppender.m_immediateFlush">
+ <summary>
+ Immediate flush means that the underlying writer or output stream
+ will be flushed at the end of each append operation.
+ </summary>
+ <remarks>
+ <para>
+ Immediate flush is slower but ensures that each append request is
+ actually written. If <see cref="P:log4net.Appender.TraceAppender.ImmediateFlush"/> is set to
+ <c>false</c>, then there is a good chance that the last few
+ logs events are not actually written to persistent media if and
+ when the application crashes.
+ </para>
+ <para>
+ The default value is <c>true</c>.</para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.TraceAppender.ImmediateFlush">
+ <summary>
+ Gets or sets a value that indicates whether the appender will
+ flush at the end of each write.
+ </summary>
+ <remarks>
+ <para>The default behavior is to flush at the end of each
+ write. If the option is set to<c>false</c>, then the underlying
+ stream can defer writing to physical medium to a later time.
+ </para>
+ <para>
+ Avoiding the flush operation at the end of each append results
+ in a performance gain of 10 to 20 percent. However, there is safety
+ trade-off involved in skipping flushing. Indeed, when flushing is
+ skipped, then it is likely that the last few log events will not
+ be recorded on disk when the application exits. This is a high
+ price to pay even for a 20% performance gain.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.TraceAppender.RequiresLayout">
+ <summary>
+ This appender requires a <see cref="N:log4net.Layout"/> to be set.
+ </summary>
+ <value><c>true</c></value>
+ <remarks>
+ <para>
+ This appender requires a <see cref="N:log4net.Layout"/> to be set.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Config.AliasDomainAttribute">
+ <summary>
+ Assembly level attribute that specifies a domain to alias to this assembly's repository.
+ </summary>
+ <remarks>
+ <para>
+ <b>AliasDomainAttribute is obsolete. Use AliasRepositoryAttribute instead of AliasDomainAttribute.</b>
+ </para>
+ <para>
+ An assembly's logger repository is defined by its <see cref="T:log4net.Config.DomainAttribute"/>,
+ however this can be overridden by an assembly loaded before the target assembly.
+ </para>
+ <para>
+ An assembly can alias another assembly's domain to its repository by
+ specifying this attribute with the name of the target domain.
+ </para>
+ <para>
+ This attribute can only be specified on the assembly and may be used
+ as many times as necessary to alias all the required domains.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="T:log4net.Config.AliasRepositoryAttribute">
+ <summary>
+ Assembly level attribute that specifies a repository to alias to this assembly's repository.
+ </summary>
+ <remarks>
+ <para>
+ An assembly's logger repository is defined by its <see cref="T:log4net.Config.RepositoryAttribute"/>,
+ however this can be overridden by an assembly loaded before the target assembly.
+ </para>
+ <para>
+ An assembly can alias another assembly's repository to its repository by
+ specifying this attribute with the name of the target repository.
+ </para>
+ <para>
+ This attribute can only be specified on the assembly and may be used
+ as many times as necessary to alias all the required repositories.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="M:log4net.Config.AliasRepositoryAttribute.#ctor(System.String)">
+ <summary>
+ Initializes a new instance of the <see cref="T:log4net.Config.AliasRepositoryAttribute"/> class with
+ the specified repository to alias to this assembly's repository.
+ </summary>
+ <param name="name">The repository to alias to this assemby's repository.</param>
+ <remarks>
+ <para>
+ Initializes a new instance of the <see cref="T:log4net.Config.AliasRepositoryAttribute"/> class with
+ the specified repository to alias to this assembly's repository.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Config.AliasRepositoryAttribute.Name">
+ <summary>
+ Gets or sets the repository to alias to this assemby's repository.
+ </summary>
+ <value>
+ The repository to alias to this assemby's repository.
+ </value>
+ <remarks>
+ <para>
+ The name of the repository to alias to this assemby's repository.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Config.AliasDomainAttribute.#ctor(System.String)">
+ <summary>
+ Initializes a new instance of the <see cref="T:log4net.Config.AliasDomainAttribute"/> class with
+ the specified domain to alias to this assembly's repository.
+ </summary>
+ <param name="name">The domain to alias to this assemby's repository.</param>
+ <remarks>
+ <para>
+ Obsolete. Use <see cref="T:log4net.Config.AliasRepositoryAttribute"/> instead of <see cref="T:log4net.Config.AliasDomainAttribute"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Config.BasicConfigurator">
+ <summary>
+ Use this class to quickly configure a <see cref="T:log4net.Repository.Hierarchy.Hierarchy"/>.
+ </summary>
+ <remarks>
+ <para>
+ Allows very simple programmatic configuration of log4net.
+ </para>
+ <para>
+ Only one appender can be configured using this configurator.
+ The appender is set at the root of the hierarchy and all logging
+ events will be delivered to that appender.
+ </para>
+ <para>
+ Appenders can also implement the <see cref="T:log4net.Core.IOptionHandler"/> interface. Therefore
+ they would require that the <see cref="M:log4net.Core.IOptionHandler.ActivateOptions"/> method
+ be called after the appenders properties have been configured.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="M:log4net.Config.BasicConfigurator.#ctor">
+ <summary>
+ Initializes a new instance of the <see cref="T:log4net.Config.BasicConfigurator"/> class.
+ </summary>
+ <remarks>
+ <para>
+ Uses a private access modifier to prevent instantiation of this class.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Config.BasicConfigurator.Configure">
+ <summary>
+ Initializes the log4net system with a default configuration.
+ </summary>
+ <remarks>
+ <para>
+ Initializes the log4net logging system using a <see cref="T:log4net.Appender.ConsoleAppender"/>
+ that will write to <c>Console.Out</c>. The log messages are
+ formatted using the <see cref="T:log4net.Layout.PatternLayout"/> layout object
+ with the <see cref="F:log4net.Layout.PatternLayout.DetailConversionPattern"/>
+ layout style.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Config.BasicConfigurator.Configure(log4net.Appender.IAppender)">
+ <summary>
+ Initializes the log4net system using the specified appender.
+ </summary>
+ <param name="appender">The appender to use to log all logging events.</param>
+ <remarks>
+ <para>
+ Initializes the log4net system using the specified appender.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Config.BasicConfigurator.Configure(log4net.Repository.ILoggerRepository)">
+ <summary>
+ Initializes the <see cref="T:log4net.Repository.ILoggerRepository"/> with a default configuration.
+ </summary>
+ <param name="repository">The repository to configure.</param>
+ <remarks>
+ <para>
+ Initializes the specified repository using a <see cref="T:log4net.Appender.ConsoleAppender"/>
+ that will write to <c>Console.Out</c>. The log messages are
+ formatted using the <see cref="T:log4net.Layout.PatternLayout"/> layout object
+ with the <see cref="F:log4net.Layout.PatternLayout.DetailConversionPattern"/>
+ layout style.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Config.BasicConfigurator.Configure(log4net.Repository.ILoggerRepository,log4net.Appender.IAppender)">
+ <summary>
+ Initializes the <see cref="T:log4net.Repository.ILoggerRepository"/> using the specified appender.
+ </summary>
+ <param name="repository">The repository to configure.</param>
+ <param name="appender">The appender to use to log all logging events.</param>
+ <remarks>
+ <para>
+ Initializes the <see cref="T:log4net.Repository.ILoggerRepository"/> using the specified appender.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Config.ConfiguratorAttribute">
+ <summary>
+ Base class for all log4net configuration attributes.
+ </summary>
+ <remarks>
+ This is an abstract class that must be extended by
+ specific configurators. This attribute allows the
+ configurator to be parameterized by an assembly level
+ attribute.
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="M:log4net.Config.ConfiguratorAttribute.#ctor(System.Int32)">
+ <summary>
+ Constructor used by subclasses.
+ </summary>
+ <param name="priority">the ordering priority for this configurator</param>
+ <remarks>
+ <para>
+ The <paramref name="priority"/> is used to order the configurator
+ attributes before they are invoked. Higher priority configurators are executed
+ before lower priority ones.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Config.ConfiguratorAttribute.Configure(System.Reflection.Assembly,log4net.Repository.ILoggerRepository)">
+ <summary>
+ Configures the <see cref="T:log4net.Repository.ILoggerRepository"/> for the specified assembly.
+ </summary>
+ <param name="sourceAssembly">The assembly that this attribute was defined on.</param>
+ <param name="targetRepository">The repository to configure.</param>
+ <remarks>
+ <para>
+ Abstract method implemented by a subclass. When this method is called
+ the subclass should configure the <paramref name="targetRepository"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Config.ConfiguratorAttribute.CompareTo(System.Object)">
+ <summary>
+ Compare this instance to another ConfiguratorAttribute
+ </summary>
+ <param name="obj">the object to compare to</param>
+ <returns>see <see cref="M:System.IComparable.CompareTo(System.Object)"/></returns>
+ <remarks>
+ <para>
+ Compares the priorities of the two <see cref="T:log4net.Config.ConfiguratorAttribute"/> instances.
+ Sorts by priority in descending order. Objects with the same priority are
+ randomly ordered.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Config.DomainAttribute">
+ <summary>
+ Assembly level attribute that specifies the logging domain for the assembly.
+ </summary>
+ <remarks>
+ <para>
+ <b>DomainAttribute is obsolete. Use RepositoryAttribute instead of DomainAttribute.</b>
+ </para>
+ <para>
+ Assemblies are mapped to logging domains. Each domain has its own
+ logging repository. This attribute specified on the assembly controls
+ the configuration of the domain. The <see cref="P:log4net.Config.RepositoryAttribute.Name"/> property specifies the name
+ of the domain that this assembly is a part of. The <see cref="P:log4net.Config.RepositoryAttribute.RepositoryType"/>
+ specifies the type of the repository objects to create for the domain. If
+ this attribute is not specified and a <see cref="P:log4net.Config.RepositoryAttribute.Name"/> is not specified
+ then the assembly will be part of the default shared logging domain.
+ </para>
+ <para>
+ This attribute can only be specified on the assembly and may only be used
+ once per assembly.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="T:log4net.Config.RepositoryAttribute">
+ <summary>
+ Assembly level attribute that specifies the logging repository for the assembly.
+ </summary>
+ <remarks>
+ <para>
+ Assemblies are mapped to logging repository. This attribute specified
+ on the assembly controls
+ the configuration of the repository. The <see cref="P:log4net.Config.RepositoryAttribute.Name"/> property specifies the name
+ of the repository that this assembly is a part of. The <see cref="P:log4net.Config.RepositoryAttribute.RepositoryType"/>
+ specifies the type of the <see cref="T:log4net.Repository.ILoggerRepository"/> object
+ to create for the assembly. If this attribute is not specified or a <see cref="P:log4net.Config.RepositoryAttribute.Name"/>
+ is not specified then the assembly will be part of the default shared logging repository.
+ </para>
+ <para>
+ This attribute can only be specified on the assembly and may only be used
+ once per assembly.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="M:log4net.Config.RepositoryAttribute.#ctor">
+ <summary>
+ Initializes a new instance of the <see cref="T:log4net.Config.RepositoryAttribute"/> class.
+ </summary>
+ <remarks>
+ <para>
+ Default constructor.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Config.RepositoryAttribute.#ctor(System.String)">
+ <summary>
+ Initialize a new instance of the <see cref="T:log4net.Config.RepositoryAttribute"/> class
+ with the name of the repository.
+ </summary>
+ <param name="name">The name of the repository.</param>
+ <remarks>
+ <para>
+ Initialize the attribute with the name for the assembly's repository.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Config.RepositoryAttribute.Name">
+ <summary>
+ Gets or sets the name of the logging repository.
+ </summary>
+ <value>
+ The string name to use as the name of the repository associated with this
+ assembly.
+ </value>
+ <remarks>
+ <para>
+ This value does not have to be unique. Several assemblies can share the
+ same repository. They will share the logging configuration of the repository.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Config.RepositoryAttribute.RepositoryType">
+ <summary>
+ Gets or sets the type of repository to create for this assembly.
+ </summary>
+ <value>
+ The type of repository to create for this assembly.
+ </value>
+ <remarks>
+ <para>
+ The type of the repository to create for the assembly.
+ The type must implement the <see cref="T:log4net.Repository.ILoggerRepository"/>
+ interface.
+ </para>
+ <para>
+ This will be the type of repository created when
+ the repository is created. If multiple assemblies reference the
+ same repository then the repository is only created once using the
+ <see cref="P:log4net.Config.RepositoryAttribute.RepositoryType"/> of the first assembly to call into the
+ repository.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Config.DomainAttribute.#ctor">
+ <summary>
+ Initializes a new instance of the <see cref="T:log4net.Config.DomainAttribute"/> class.
+ </summary>
+ <remarks>
+ <para>
+ Obsolete. Use RepositoryAttribute instead of DomainAttribute.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Config.DomainAttribute.#ctor(System.String)">
+ <summary>
+ Initialize a new instance of the <see cref="T:log4net.Config.DomainAttribute"/> class
+ with the name of the domain.
+ </summary>
+ <param name="name">The name of the domain.</param>
+ <remarks>
+ <para>
+ Obsolete. Use RepositoryAttribute instead of DomainAttribute.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Config.DOMConfigurator">
+ <summary>
+ Use this class to initialize the log4net environment using an Xml tree.
+ </summary>
+ <remarks>
+ <para>
+ <b>DOMConfigurator is obsolete. Use XmlConfigurator instead of DOMConfigurator.</b>
+ </para>
+ <para>
+ Configures a <see cref="T:log4net.Repository.ILoggerRepository"/> using an Xml tree.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="M:log4net.Config.DOMConfigurator.#ctor">
+ <summary>
+ Private constructor
+ </summary>
+ </member>
+ <member name="M:log4net.Config.DOMConfigurator.Configure">
+ <summary>
+ Automatically configures the log4net system based on the
+ application's configuration settings.
+ </summary>
+ <remarks>
+ <para>
+ <b>DOMConfigurator is obsolete. Use XmlConfigurator instead of DOMConfigurator.</b>
+ </para>
+ Each application has a configuration file. This has the
+ same name as the application with '.config' appended.
+ This file is XML and calling this function prompts the
+ configurator to look in that file for a section called
+ <c>log4net</c> that contains the configuration data.
+ </remarks>
+ </member>
+ <member name="M:log4net.Config.DOMConfigurator.Configure(log4net.Repository.ILoggerRepository)">
+ <summary>
+ Automatically configures the <see cref="T:log4net.Repository.ILoggerRepository"/> using settings
+ stored in the application's configuration file.
+ </summary>
+ <remarks>
+ <para>
+ <b>DOMConfigurator is obsolete. Use XmlConfigurator instead of DOMConfigurator.</b>
+ </para>
+ Each application has a configuration file. This has the
+ same name as the application with '.config' appended.
+ This file is XML and calling this function prompts the
+ configurator to look in that file for a section called
+ <c>log4net</c> that contains the configuration data.
+ </remarks>
+ <param name="repository">The repository to configure.</param>
+ </member>
+ <member name="M:log4net.Config.DOMConfigurator.Configure(System.Xml.XmlElement)">
+ <summary>
+ Configures log4net using a <c>log4net</c> element
+ </summary>
+ <remarks>
+ <para>
+ <b>DOMConfigurator is obsolete. Use XmlConfigurator instead of DOMConfigurator.</b>
+ </para>
+ Loads the log4net configuration from the XML element
+ supplied as <paramref name="element"/>.
+ </remarks>
+ <param name="element">The element to parse.</param>
+ </member>
+ <member name="M:log4net.Config.DOMConfigurator.Configure(log4net.Repository.ILoggerRepository,System.Xml.XmlElement)">
+ <summary>
+ Configures the <see cref="T:log4net.Repository.ILoggerRepository"/> using the specified XML
+ element.
+ </summary>
+ <remarks>
+ <para>
+ <b>DOMConfigurator is obsolete. Use XmlConfigurator instead of DOMConfigurator.</b>
+ </para>
+ Loads the log4net configuration from the XML element
+ supplied as <paramref name="element"/>.
+ </remarks>
+ <param name="repository">The repository to configure.</param>
+ <param name="element">The element to parse.</param>
+ </member>
+ <member name="M:log4net.Config.DOMConfigurator.Configure(System.IO.FileInfo)">
+ <summary>
+ Configures log4net using the specified configuration file.
+ </summary>
+ <param name="configFile">The XML file to load the configuration from.</param>
+ <remarks>
+ <para>
+ <b>DOMConfigurator is obsolete. Use XmlConfigurator instead of DOMConfigurator.</b>
+ </para>
+ <para>
+ The configuration file must be valid XML. It must contain
+ at least one element called <c>log4net</c> that holds
+ the log4net configuration data.
+ </para>
+ <para>
+ The log4net configuration file can possible be specified in the application's
+ configuration file (either <c>MyAppName.exe.config</c> for a
+ normal application on <c>Web.config</c> for an ASP.NET application).
+ </para>
+ <example>
+ The following example configures log4net using a configuration file, of which the
+ location is stored in the application's configuration file :
+ </example>
+ <code lang="C#">
+ using log4net.Config;
+ using System.IO;
+ using System.Configuration;
+
+ ...
+
+ DOMConfigurator.Configure(new FileInfo(ConfigurationSettings.AppSettings["log4net-config-file"]));
+ </code>
+ <para>
+ In the <c>.config</c> file, the path to the log4net can be specified like this :
+ </para>
+ <code lang="XML" escaped="true">
+ <configuration>
+ <appSettings>
+ <add key="log4net-config-file" value="log.config"/>
+ </appSettings>
+ </configuration>
+ </code>
+ </remarks>
+ </member>
+ <member name="M:log4net.Config.DOMConfigurator.Configure(System.IO.Stream)">
+ <summary>
+ Configures log4net using the specified configuration file.
+ </summary>
+ <param name="configStream">A stream to load the XML configuration from.</param>
+ <remarks>
+ <para>
+ <b>DOMConfigurator is obsolete. Use XmlConfigurator instead of DOMConfigurator.</b>
+ </para>
+ <para>
+ The configuration data must be valid XML. It must contain
+ at least one element called <c>log4net</c> that holds
+ the log4net configuration data.
+ </para>
+ <para>
+ Note that this method will NOT close the stream parameter.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Config.DOMConfigurator.Configure(log4net.Repository.ILoggerRepository,System.IO.FileInfo)">
+ <summary>
+ Configures the <see cref="T:log4net.Repository.ILoggerRepository"/> using the specified configuration
+ file.
+ </summary>
+ <param name="repository">The repository to configure.</param>
+ <param name="configFile">The XML file to load the configuration from.</param>
+ <remarks>
+ <para>
+ <b>DOMConfigurator is obsolete. Use XmlConfigurator instead of DOMConfigurator.</b>
+ </para>
+ <para>
+ The configuration file must be valid XML. It must contain
+ at least one element called <c>log4net</c> that holds
+ the configuration data.
+ </para>
+ <para>
+ The log4net configuration file can possible be specified in the application's
+ configuration file (either <c>MyAppName.exe.config</c> for a
+ normal application on <c>Web.config</c> for an ASP.NET application).
+ </para>
+ <example>
+ The following example configures log4net using a configuration file, of which the
+ location is stored in the application's configuration file :
+ </example>
+ <code lang="C#">
+ using log4net.Config;
+ using System.IO;
+ using System.Configuration;
+
+ ...
+
+ DOMConfigurator.Configure(new FileInfo(ConfigurationSettings.AppSettings["log4net-config-file"]));
+ </code>
+ <para>
+ In the <c>.config</c> file, the path to the log4net can be specified like this :
+ </para>
+ <code lang="XML" escaped="true">
+ <configuration>
+ <appSettings>
+ <add key="log4net-config-file" value="log.config"/>
+ </appSettings>
+ </configuration>
+ </code>
+ </remarks>
+ </member>
+ <member name="M:log4net.Config.DOMConfigurator.Configure(log4net.Repository.ILoggerRepository,System.IO.Stream)">
+ <summary>
+ Configures the <see cref="T:log4net.Repository.ILoggerRepository"/> using the specified configuration
+ file.
+ </summary>
+ <param name="repository">The repository to configure.</param>
+ <param name="configStream">The stream to load the XML configuration from.</param>
+ <remarks>
+ <para>
+ <b>DOMConfigurator is obsolete. Use XmlConfigurator instead of DOMConfigurator.</b>
+ </para>
+ <para>
+ The configuration data must be valid XML. It must contain
+ at least one element called <c>log4net</c> that holds
+ the configuration data.
+ </para>
+ <para>
+ Note that this method will NOT close the stream parameter.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Config.DOMConfigurator.ConfigureAndWatch(System.IO.FileInfo)">
+ <summary>
+ Configures log4net using the file specified, monitors the file for changes
+ and reloads the configuration if a change is detected.
+ </summary>
+ <param name="configFile">The XML file to load the configuration from.</param>
+ <remarks>
+ <para>
+ <b>DOMConfigurator is obsolete. Use XmlConfigurator instead of DOMConfigurator.</b>
+ </para>
+ <para>
+ The configuration file must be valid XML. It must contain
+ at least one element called <c>log4net</c> that holds
+ the configuration data.
+ </para>
+ <para>
+ The configuration file will be monitored using a <see cref="T:System.IO.FileSystemWatcher"/>
+ and depends on the behavior of that class.
+ </para>
+ <para>
+ For more information on how to configure log4net using
+ a separate configuration file, see <see cref="M:log4net.Config.DOMConfigurator.Configure(System.IO.FileInfo)"/>.
+ </para>
+ </remarks>
+ <seealso cref="M:log4net.Config.DOMConfigurator.Configure(System.IO.FileInfo)"/>
+ </member>
+ <member name="M:log4net.Config.DOMConfigurator.ConfigureAndWatch(log4net.Repository.ILoggerRepository,System.IO.FileInfo)">
+ <summary>
+ Configures the <see cref="T:log4net.Repository.ILoggerRepository"/> using the file specified,
+ monitors the file for changes and reloads the configuration if a change
+ is detected.
+ </summary>
+ <param name="repository">The repository to configure.</param>
+ <param name="configFile">The XML file to load the configuration from.</param>
+ <remarks>
+ <para>
+ <b>DOMConfigurator is obsolete. Use XmlConfigurator instead of DOMConfigurator.</b>
+ </para>
+ <para>
+ The configuration file must be valid XML. It must contain
+ at least one element called <c>log4net</c> that holds
+ the configuration data.
+ </para>
+ <para>
+ The configuration file will be monitored using a <see cref="T:System.IO.FileSystemWatcher"/>
+ and depends on the behavior of that class.
+ </para>
+ <para>
+ For more information on how to configure log4net using
+ a separate configuration file, see <see cref="M:log4net.Config.DOMConfigurator.Configure(System.IO.FileInfo)"/>.
+ </para>
+ </remarks>
+ <seealso cref="M:log4net.Config.DOMConfigurator.Configure(System.IO.FileInfo)"/>
+ </member>
+ <member name="T:log4net.Config.DOMConfiguratorAttribute">
+ <summary>
+ Assembly level attribute to configure the <see cref="T:log4net.Config.XmlConfigurator"/>.
+ </summary>
+ <remarks>
+ <para>
+ <b>AliasDomainAttribute is obsolete. Use AliasRepositoryAttribute instead of AliasDomainAttribute.</b>
+ </para>
+ <para>
+ This attribute may only be used at the assembly scope and can only
+ be used once per assembly.
+ </para>
+ <para>
+ Use this attribute to configure the <see cref="T:log4net.Config.XmlConfigurator"/>
+ without calling one of the <see cref="M:log4net.Config.XmlConfigurator.Configure"/>
+ methods.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="T:log4net.Config.XmlConfiguratorAttribute">
+ <summary>
+ Assembly level attribute to configure the <see cref="T:log4net.Config.XmlConfigurator"/>.
+ </summary>
+ <remarks>
+ <para>
+ This attribute may only be used at the assembly scope and can only
+ be used once per assembly.
+ </para>
+ <para>
+ Use this attribute to configure the <see cref="T:log4net.Config.XmlConfigurator"/>
+ without calling one of the <see cref="M:log4net.Config.XmlConfigurator.Configure"/>
+ methods.
+ </para>
+ <para>
+ If neither of the <see cref="P:log4net.Config.XmlConfiguratorAttribute.ConfigFile"/> or <see cref="P:log4net.Config.XmlConfiguratorAttribute.ConfigFileExtension"/>
+ properties are set the configuration is loaded from the application's .config file.
+ If set the <see cref="P:log4net.Config.XmlConfiguratorAttribute.ConfigFile"/> property takes priority over the
+ <see cref="P:log4net.Config.XmlConfiguratorAttribute.ConfigFileExtension"/> property. The <see cref="P:log4net.Config.XmlConfiguratorAttribute.ConfigFile"/> property
+ specifies a path to a file to load the config from. The path is relative to the
+ application's base directory; <see cref="P:System.AppDomain.BaseDirectory"/>.
+ The <see cref="P:log4net.Config.XmlConfiguratorAttribute.ConfigFileExtension"/> property is used as a postfix to the assembly file name.
+ The config file must be located in the application's base directory; <see cref="P:System.AppDomain.BaseDirectory"/>.
+ For example in a console application setting the <see cref="P:log4net.Config.XmlConfiguratorAttribute.ConfigFileExtension"/> to
+ <c>config</c> has the same effect as not specifying the <see cref="P:log4net.Config.XmlConfiguratorAttribute.ConfigFile"/> or
+ <see cref="P:log4net.Config.XmlConfiguratorAttribute.ConfigFileExtension"/> properties.
+ </para>
+ <para>
+ The <see cref="P:log4net.Config.XmlConfiguratorAttribute.Watch"/> property can be set to cause the <see cref="T:log4net.Config.XmlConfigurator"/>
+ to watch the configuration file for changes.
+ </para>
+ <note>
+ <para>
+ Log4net will only look for assembly level configuration attributes once.
+ When using the log4net assembly level attributes to control the configuration
+ of log4net you must ensure that the first call to any of the
+ <see cref="T:log4net.Core.LoggerManager"/> methods is made from the assembly with the configuration
+ attributes.
+ </para>
+ <para>
+ If you cannot guarantee the order in which log4net calls will be made from
+ different assemblies you must use programmatic configuration instead, i.e.
+ call the <see cref="M:log4net.Config.XmlConfigurator.Configure"/> method directly.
+ </para>
+ </note>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="M:log4net.Config.XmlConfiguratorAttribute.#ctor">
+ <summary>
+ Default constructor
+ </summary>
+ <remarks>
+ <para>
+ Default constructor
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Config.XmlConfiguratorAttribute.Configure(System.Reflection.Assembly,log4net.Repository.ILoggerRepository)">
+ <summary>
+ Configures the <see cref="T:log4net.Repository.ILoggerRepository"/> for the specified assembly.
+ </summary>
+ <param name="sourceAssembly">The assembly that this attribute was defined on.</param>
+ <param name="targetRepository">The repository to configure.</param>
+ <remarks>
+ <para>
+ Configure the repository using the <see cref="T:log4net.Config.XmlConfigurator"/>.
+ The <paramref name="targetRepository"/> specified must extend the <see cref="T:log4net.Repository.Hierarchy.Hierarchy"/>
+ class otherwise the <see cref="T:log4net.Config.XmlConfigurator"/> will not be able to
+ configure it.
+ </para>
+ </remarks>
+ <exception cref="T:System.ArgumentOutOfRangeException">The <paramref name="repository"/> does not extend <see cref="T:log4net.Repository.Hierarchy.Hierarchy"/>.</exception>
+ </member>
+ <member name="M:log4net.Config.XmlConfiguratorAttribute.ConfigureFromFile(System.Reflection.Assembly,log4net.Repository.ILoggerRepository)">
+ <summary>
+ Attempt to load configuration from the local file system
+ </summary>
+ <param name="sourceAssembly">The assembly that this attribute was defined on.</param>
+ <param name="targetRepository">The repository to configure.</param>
+ </member>
+ <member name="M:log4net.Config.XmlConfiguratorAttribute.ConfigureFromFile(log4net.Repository.ILoggerRepository,System.IO.FileInfo)">
+ <summary>
+ Configure the specified repository using a <see cref="T:System.IO.FileInfo"/>
+ </summary>
+ <param name="targetRepository">The repository to configure.</param>
+ <param name="configFile">the FileInfo pointing to the config file</param>
+ </member>
+ <member name="M:log4net.Config.XmlConfiguratorAttribute.ConfigureFromUri(System.Reflection.Assembly,log4net.Repository.ILoggerRepository)">
+ <summary>
+ Attempt to load configuration from a URI
+ </summary>
+ <param name="sourceAssembly">The assembly that this attribute was defined on.</param>
+ <param name="targetRepository">The repository to configure.</param>
+ </member>
+ <member name="P:log4net.Config.XmlConfiguratorAttribute.ConfigFile">
+ <summary>
+ Gets or sets the filename of the configuration file.
+ </summary>
+ <value>
+ The filename of the configuration file.
+ </value>
+ <remarks>
+ <para>
+ If specified, this is the name of the configuration file to use with
+ the <see cref="T:log4net.Config.XmlConfigurator"/>. This file path is relative to the
+ <b>application base</b> directory (<see cref="P:System.AppDomain.BaseDirectory"/>).
+ </para>
+ <para>
+ The <see cref="P:log4net.Config.XmlConfiguratorAttribute.ConfigFile"/> takes priority over the <see cref="P:log4net.Config.XmlConfiguratorAttribute.ConfigFileExtension"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Config.XmlConfiguratorAttribute.ConfigFileExtension">
+ <summary>
+ Gets or sets the extension of the configuration file.
+ </summary>
+ <value>
+ The extension of the configuration file.
+ </value>
+ <remarks>
+ <para>
+ If specified this is the extension for the configuration file.
+ The path to the config file is built by using the <b>application
+ base</b> directory (<see cref="P:System.AppDomain.BaseDirectory"/>),
+ the <b>assembly file name</b> and the config file extension.
+ </para>
+ <para>
+ If the <see cref="P:log4net.Config.XmlConfiguratorAttribute.ConfigFileExtension"/> is set to <c>MyExt</c> then
+ possible config file names would be: <c>MyConsoleApp.exe.MyExt</c> or
+ <c>MyClassLibrary.dll.MyExt</c>.
+ </para>
+ <para>
+ The <see cref="P:log4net.Config.XmlConfiguratorAttribute.ConfigFile"/> takes priority over the <see cref="P:log4net.Config.XmlConfiguratorAttribute.ConfigFileExtension"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Config.XmlConfiguratorAttribute.Watch">
+ <summary>
+ Gets or sets a value indicating whether to watch the configuration file.
+ </summary>
+ <value>
+ <c>true</c> if the configuration should be watched, <c>false</c> otherwise.
+ </value>
+ <remarks>
+ <para>
+ If this flag is specified and set to <c>true</c> then the framework
+ will watch the configuration file and will reload the config each time
+ the file is modified.
+ </para>
+ <para>
+ The config file can only be watched if it is loaded from local disk.
+ In a No-Touch (Smart Client) deployment where the application is downloaded
+ from a web server the config file may not reside on the local disk
+ and therefore it may not be able to watch it.
+ </para>
+ <note>
+ Watching configuration is not supported on the SSCLI.
+ </note>
+ </remarks>
+ </member>
+ <member name="T:log4net.Config.Log4NetConfigurationSectionHandler">
+ <summary>
+ Class to register for the log4net section of the configuration file
+ </summary>
+ <remarks>
+ The log4net section of the configuration file needs to have a section
+ handler registered. This is the section handler used. It simply returns
+ the XML element that is the root of the section.
+ </remarks>
+ <example>
+ Example of registering the log4net section handler :
+ <code lang="XML" escaped="true">
+ <configuration>
+ <configSections>
+ <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" />
+ </configSections>
+ <log4net>
+ log4net configuration XML goes here
+ </log4net>
+ </configuration>
+ </code>
+ </example>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="M:log4net.Config.Log4NetConfigurationSectionHandler.#ctor">
+ <summary>
+ Initializes a new instance of the <see cref="T:log4net.Config.Log4NetConfigurationSectionHandler"/> class.
+ </summary>
+ <remarks>
+ <para>
+ Default constructor.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Config.Log4NetConfigurationSectionHandler.Create(System.Object,System.Object,System.Xml.XmlNode)">
+ <summary>
+ Parses the configuration section.
+ </summary>
+ <param name="parent">The configuration settings in a corresponding parent configuration section.</param>
+ <param name="configContext">The configuration context when called from the ASP.NET configuration system. Otherwise, this parameter is reserved and is a null reference.</param>
+ <param name="section">The <see cref="T:System.Xml.XmlNode"/> for the log4net section.</param>
+ <returns>The <see cref="T:System.Xml.XmlNode"/> for the log4net section.</returns>
+ <remarks>
+ <para>
+ Returns the <see cref="T:System.Xml.XmlNode"/> containing the configuration data,
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Config.PluginAttribute">
+ <summary>
+ Assembly level attribute that specifies a plugin to attach to
+ the repository.
+ </summary>
+ <remarks>
+ <para>
+ Specifies the type of a plugin to create and attach to the
+ assembly's repository. The plugin type must implement the
+ <see cref="T:log4net.Plugin.IPlugin"/> interface.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="T:log4net.Plugin.IPluginFactory">
+ <summary>
+ Interface used to create plugins.
+ </summary>
+ <remarks>
+ <para>
+ Interface used to create a plugin.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="M:log4net.Plugin.IPluginFactory.CreatePlugin">
+ <summary>
+ Creates the plugin object.
+ </summary>
+ <returns>the new plugin instance</returns>
+ <remarks>
+ <para>
+ Create and return a new plugin instance.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Config.PluginAttribute.#ctor(System.String)">
+ <summary>
+ Initializes a new instance of the <see cref="T:log4net.Config.PluginAttribute"/> class
+ with the specified type.
+ </summary>
+ <param name="typeName">The type name of plugin to create.</param>
+ <remarks>
+ <para>
+ Create the attribute with the plugin type specified.
+ </para>
+ <para>
+ Where possible use the constructor that takes a <see cref="T:System.Type"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Config.PluginAttribute.#ctor(System.Type)">
+ <summary>
+ Initializes a new instance of the <see cref="T:log4net.Config.PluginAttribute"/> class
+ with the specified type.
+ </summary>
+ <param name="type">The type of plugin to create.</param>
+ <remarks>
+ <para>
+ Create the attribute with the plugin type specified.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Config.PluginAttribute.CreatePlugin">
+ <summary>
+ Creates the plugin object defined by this attribute.
+ </summary>
+ <remarks>
+ <para>
+ Creates the instance of the <see cref="T:log4net.Plugin.IPlugin"/> object as
+ specified by this attribute.
+ </para>
+ </remarks>
+ <returns>The plugin object.</returns>
+ </member>
+ <member name="M:log4net.Config.PluginAttribute.ToString">
+ <summary>
+ Returns a representation of the properties of this object.
+ </summary>
+ <remarks>
+ <para>
+ Overrides base class <see cref="M:System.Object.ToString"/> method to
+ return a representation of the properties of this object.
+ </para>
+ </remarks>
+ <returns>A representation of the properties of this object</returns>
+ </member>
+ <member name="P:log4net.Config.PluginAttribute.Type">
+ <summary>
+ Gets or sets the type for the plugin.
+ </summary>
+ <value>
+ The type for the plugin.
+ </value>
+ <remarks>
+ <para>
+ The type for the plugin.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Config.PluginAttribute.TypeName">
+ <summary>
+ Gets or sets the type name for the plugin.
+ </summary>
+ <value>
+ The type name for the plugin.
+ </value>
+ <remarks>
+ <para>
+ The type name for the plugin.
+ </para>
+ <para>
+ Where possible use the <see cref="P:log4net.Config.PluginAttribute.Type"/> property instead.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Config.SecurityContextProviderAttribute">
+ <summary>
+ Assembly level attribute to configure the <see cref="T:log4net.Core.SecurityContextProvider"/>.
+ </summary>
+ <remarks>
+ <para>
+ This attribute may only be used at the assembly scope and can only
+ be used once per assembly.
+ </para>
+ <para>
+ Use this attribute to configure the <see cref="T:log4net.Config.XmlConfigurator"/>
+ without calling one of the <see cref="M:log4net.Config.XmlConfigurator.Configure"/>
+ methods.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="M:log4net.Config.SecurityContextProviderAttribute.#ctor(System.Type)">
+ <summary>
+ Construct provider attribute with type specified
+ </summary>
+ <param name="providerType">the type of the provider to use</param>
+ <remarks>
+ <para>
+ The provider specified must subclass the <see cref="T:log4net.Core.SecurityContextProvider"/>
+ class.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Config.SecurityContextProviderAttribute.Configure(System.Reflection.Assembly,log4net.Repository.ILoggerRepository)">
+ <summary>
+ Configures the SecurityContextProvider
+ </summary>
+ <param name="sourceAssembly">The assembly that this attribute was defined on.</param>
+ <param name="targetRepository">The repository to configure.</param>
+ <remarks>
+ <para>
+ Creates a provider instance from the <see cref="P:log4net.Config.SecurityContextProviderAttribute.ProviderType"/> specified.
+ Sets this as the default security context provider <see cref="P:log4net.Core.SecurityContextProvider.DefaultProvider"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Config.SecurityContextProviderAttribute.ProviderType">
+ <summary>
+ Gets or sets the type of the provider to use.
+ </summary>
+ <value>
+ the type of the provider to use.
+ </value>
+ <remarks>
+ <para>
+ The provider specified must subclass the <see cref="T:log4net.Core.SecurityContextProvider"/>
+ class.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Config.XmlConfigurator">
+ <summary>
+ Use this class to initialize the log4net environment using an Xml tree.
+ </summary>
+ <remarks>
+ <para>
+ Configures a <see cref="T:log4net.Repository.ILoggerRepository"/> using an Xml tree.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="M:log4net.Config.XmlConfigurator.#ctor">
+ <summary>
+ Private constructor
+ </summary>
+ </member>
+ <member name="M:log4net.Config.XmlConfigurator.Configure">
+ <summary>
+ Automatically configures the log4net system based on the
+ application's configuration settings.
+ </summary>
+ <remarks>
+ <para>
+ Each application has a configuration file. This has the
+ same name as the application with '.config' appended.
+ This file is XML and calling this function prompts the
+ configurator to look in that file for a section called
+ <c>log4net</c> that contains the configuration data.
+ </para>
+ <para>
+ To use this method to configure log4net you must specify
+ the <see cref="T:log4net.Config.Log4NetConfigurationSectionHandler"/> section
+ handler for the <c>log4net</c> configuration section. See the
+ <see cref="T:log4net.Config.Log4NetConfigurationSectionHandler"/> for an example.
+ </para>
+ </remarks>
+ <seealso cref="T:log4net.Config.Log4NetConfigurationSectionHandler"/>
+ </member>
+ <member name="M:log4net.Config.XmlConfigurator.Configure(log4net.Repository.ILoggerRepository)">
+ <summary>
+ Automatically configures the <see cref="T:log4net.Repository.ILoggerRepository"/> using settings
+ stored in the application's configuration file.
+ </summary>
+ <remarks>
+ <para>
+ Each application has a configuration file. This has the
+ same name as the application with '.config' appended.
+ This file is XML and calling this function prompts the
+ configurator to look in that file for a section called
+ <c>log4net</c> that contains the configuration data.
+ </para>
+ <para>
+ To use this method to configure log4net you must specify
+ the <see cref="T:log4net.Config.Log4NetConfigurationSectionHandler"/> section
+ handler for the <c>log4net</c> configuration section. See the
+ <see cref="T:log4net.Config.Log4NetConfigurationSectionHandler"/> for an example.
+ </para>
+ </remarks>
+ <param name="repository">The repository to configure.</param>
+ </member>
+ <member name="M:log4net.Config.XmlConfigurator.Configure(System.Xml.XmlElement)">
+ <summary>
+ Configures log4net using a <c>log4net</c> element
+ </summary>
+ <remarks>
+ <para>
+ Loads the log4net configuration from the XML element
+ supplied as <paramref name="element"/>.
+ </para>
+ </remarks>
+ <param name="element">The element to parse.</param>
+ </member>
+ <member name="M:log4net.Config.XmlConfigurator.Configure(log4net.Repository.ILoggerRepository,System.Xml.XmlElement)">
+ <summary>
+ Configures the <see cref="T:log4net.Repository.ILoggerRepository"/> using the specified XML
+ element.
+ </summary>
+ <remarks>
+ Loads the log4net configuration from the XML element
+ supplied as <paramref name="element"/>.
+ </remarks>
+ <param name="repository">The repository to configure.</param>
+ <param name="element">The element to parse.</param>
+ </member>
+ <member name="M:log4net.Config.XmlConfigurator.Configure(System.IO.FileInfo)">
+ <summary>
+ Configures log4net using the specified configuration file.
+ </summary>
+ <param name="configFile">The XML file to load the configuration from.</param>
+ <remarks>
+ <para>
+ The configuration file must be valid XML. It must contain
+ at least one element called <c>log4net</c> that holds
+ the log4net configuration data.
+ </para>
+ <para>
+ The log4net configuration file can possible be specified in the application's
+ configuration file (either <c>MyAppName.exe.config</c> for a
+ normal application on <c>Web.config</c> for an ASP.NET application).
+ </para>
+ <para>
+ The first element matching <c>&lt;configuration&gt;</c> will be read as the
+ configuration. If this file is also a .NET .config file then you must specify
+ a configuration section for the <c>log4net</c> element otherwise .NET will
+ complain. Set the type for the section handler to <see cref="T:System.Configuration.IgnoreSectionHandler"/>, for example:
+ <code lang="XML" escaped="true">
+ <configSections>
+ <section name="log4net" type="System.Configuration.IgnoreSectionHandler"/>
+ </configSections>
+ </code>
+ </para>
+ <example>
+ The following example configures log4net using a configuration file, of which the
+ location is stored in the application's configuration file :
+ </example>
+ <code lang="C#">
+ using log4net.Config;
+ using System.IO;
+ using System.Configuration;
+
+ ...
+
+ XmlConfigurator.Configure(new FileInfo(ConfigurationSettings.AppSettings["log4net-config-file"]));
+ </code>
+ <para>
+ In the <c>.config</c> file, the path to the log4net can be specified like this :
+ </para>
+ <code lang="XML" escaped="true">
+ <configuration>
+ <appSettings>
+ <add key="log4net-config-file" value="log.config"/>
+ </appSettings>
+ </configuration>
+ </code>
+ </remarks>
+ </member>
+ <member name="M:log4net.Config.XmlConfigurator.Configure(System.Uri)">
+ <summary>
+ Configures log4net using the specified configuration URI.
+ </summary>
+ <param name="configUri">A URI to load the XML configuration from.</param>
+ <remarks>
+ <para>
+ The configuration data must be valid XML. It must contain
+ at least one element called <c>log4net</c> that holds
+ the log4net configuration data.
+ </para>
+ <para>
+ The <see cref="T:System.Net.WebRequest"/> must support the URI scheme specified.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Config.XmlConfigurator.Configure(System.IO.Stream)">
+ <summary>
+ Configures log4net using the specified configuration data stream.
+ </summary>
+ <param name="configStream">A stream to load the XML configuration from.</param>
+ <remarks>
+ <para>
+ The configuration data must be valid XML. It must contain
+ at least one element called <c>log4net</c> that holds
+ the log4net configuration data.
+ </para>
+ <para>
+ Note that this method will NOT close the stream parameter.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Config.XmlConfigurator.Configure(log4net.Repository.ILoggerRepository,System.IO.FileInfo)">
+ <summary>
+ Configures the <see cref="T:log4net.Repository.ILoggerRepository"/> using the specified configuration
+ file.
+ </summary>
+ <param name="repository">The repository to configure.</param>
+ <param name="configFile">The XML file to load the configuration from.</param>
+ <remarks>
+ <para>
+ The configuration file must be valid XML. It must contain
+ at least one element called <c>log4net</c> that holds
+ the configuration data.
+ </para>
+ <para>
+ The log4net configuration file can possible be specified in the application's
+ configuration file (either <c>MyAppName.exe.config</c> for a
+ normal application on <c>Web.config</c> for an ASP.NET application).
+ </para>
+ <para>
+ The first element matching <c>&lt;configuration&gt;</c> will be read as the
+ configuration. If this file is also a .NET .config file then you must specify
+ a configuration section for the <c>log4net</c> element otherwise .NET will
+ complain. Set the type for the section handler to <see cref="T:System.Configuration.IgnoreSectionHandler"/>, for example:
+ <code lang="XML" escaped="true">
+ <configSections>
+ <section name="log4net" type="System.Configuration.IgnoreSectionHandler"/>
+ </configSections>
+ </code>
+ </para>
+ <example>
+ The following example configures log4net using a configuration file, of which the
+ location is stored in the application's configuration file :
+ </example>
+ <code lang="C#">
+ using log4net.Config;
+ using System.IO;
+ using System.Configuration;
+
+ ...
+
+ XmlConfigurator.Configure(new FileInfo(ConfigurationSettings.AppSettings["log4net-config-file"]));
+ </code>
+ <para>
+ In the <c>.config</c> file, the path to the log4net can be specified like this :
+ </para>
+ <code lang="XML" escaped="true">
+ <configuration>
+ <appSettings>
+ <add key="log4net-config-file" value="log.config"/>
+ </appSettings>
+ </configuration>
+ </code>
+ </remarks>
+ </member>
+ <member name="M:log4net.Config.XmlConfigurator.Configure(log4net.Repository.ILoggerRepository,System.Uri)">
+ <summary>
+ Configures the <see cref="T:log4net.Repository.ILoggerRepository"/> using the specified configuration
+ URI.
+ </summary>
+ <param name="repository">The repository to configure.</param>
+ <param name="configUri">A URI to load the XML configuration from.</param>
+ <remarks>
+ <para>
+ The configuration data must be valid XML. It must contain
+ at least one element called <c>log4net</c> that holds
+ the configuration data.
+ </para>
+ <para>
+ The <see cref="T:System.Net.WebRequest"/> must support the URI scheme specified.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Config.XmlConfigurator.Configure(log4net.Repository.ILoggerRepository,System.IO.Stream)">
+ <summary>
+ Configures the <see cref="T:log4net.Repository.ILoggerRepository"/> using the specified configuration
+ file.
+ </summary>
+ <param name="repository">The repository to configure.</param>
+ <param name="configStream">The stream to load the XML configuration from.</param>
+ <remarks>
+ <para>
+ The configuration data must be valid XML. It must contain
+ at least one element called <c>log4net</c> that holds
+ the configuration data.
+ </para>
+ <para>
+ Note that this method will NOT close the stream parameter.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Config.XmlConfigurator.ConfigureAndWatch(System.IO.FileInfo)">
+ <summary>
+ Configures log4net using the file specified, monitors the file for changes
+ and reloads the configuration if a change is detected.
+ </summary>
+ <param name="configFile">The XML file to load the configuration from.</param>
+ <remarks>
+ <para>
+ The configuration file must be valid XML. It must contain
+ at least one element called <c>log4net</c> that holds
+ the configuration data.
+ </para>
+ <para>
+ The configuration file will be monitored using a <see cref="T:System.IO.FileSystemWatcher"/>
+ and depends on the behavior of that class.
+ </para>
+ <para>
+ For more information on how to configure log4net using
+ a separate configuration file, see <see cref="M:log4net.Config.XmlConfigurator.Configure(System.IO.FileInfo)"/>.
+ </para>
+ </remarks>
+ <seealso cref="M:log4net.Config.XmlConfigurator.Configure(System.IO.FileInfo)"/>
+ </member>
+ <member name="M:log4net.Config.XmlConfigurator.ConfigureAndWatch(log4net.Repository.ILoggerRepository,System.IO.FileInfo)">
+ <summary>
+ Configures the <see cref="T:log4net.Repository.ILoggerRepository"/> using the file specified,
+ monitors the file for changes and reloads the configuration if a change
+ is detected.
+ </summary>
+ <param name="repository">The repository to configure.</param>
+ <param name="configFile">The XML file to load the configuration from.</param>
+ <remarks>
+ <para>
+ The configuration file must be valid XML. It must contain
+ at least one element called <c>log4net</c> that holds
+ the configuration data.
+ </para>
+ <para>
+ The configuration file will be monitored using a <see cref="T:System.IO.FileSystemWatcher"/>
+ and depends on the behavior of that class.
+ </para>
+ <para>
+ For more information on how to configure log4net using
+ a separate configuration file, see <see cref="M:log4net.Config.XmlConfigurator.Configure(System.IO.FileInfo)"/>.
+ </para>
+ </remarks>
+ <seealso cref="M:log4net.Config.XmlConfigurator.Configure(System.IO.FileInfo)"/>
+ </member>
+ <member name="M:log4net.Config.XmlConfigurator.ConfigureFromXml(log4net.Repository.ILoggerRepository,System.Xml.XmlElement)">
+ <summary>
+ Configures the specified repository using a <c>log4net</c> element.
+ </summary>
+ <param name="repository">The hierarchy to configure.</param>
+ <param name="element">The element to parse.</param>
+ <remarks>
+ <para>
+ Loads the log4net configuration from the XML element
+ supplied as <paramref name="element"/>.
+ </para>
+ <para>
+ This method is ultimately called by one of the Configure methods
+ to load the configuration from an <see cref="T:System.Xml.XmlElement"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Config.XmlConfigurator.ConfigureAndWatchHandler">
+ <summary>
+ Class used to watch config files.
+ </summary>
+ <remarks>
+ <para>
+ Uses the <see cref="T:System.IO.FileSystemWatcher"/> to monitor
+ changes to a specified file. Because multiple change notifications
+ may be raised when the file is modified, a timer is used to
+ compress the notifications into a single event. The timer
+ waits for <see cref="F:log4net.Config.XmlConfigurator.ConfigureAndWatchHandler.TimeoutMillis"/> time before delivering
+ the event notification. If any further <see cref="T:System.IO.FileSystemWatcher"/>
+ change notifications arrive while the timer is waiting it
+ is reset and waits again for <see cref="F:log4net.Config.XmlConfigurator.ConfigureAndWatchHandler.TimeoutMillis"/> to
+ elapse.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Config.XmlConfigurator.ConfigureAndWatchHandler.TimeoutMillis">
+ <summary>
+ The default amount of time to wait after receiving notification
+ before reloading the config file.
+ </summary>
+ </member>
+ <member name="M:log4net.Config.XmlConfigurator.ConfigureAndWatchHandler.StartWatching(log4net.Repository.ILoggerRepository,System.IO.FileInfo)">
+ <summary>
+ Watch a specified config file used to configure a repository
+ </summary>
+ <param name="repository">The repository to configure.</param>
+ <param name="configFile">The configuration file to watch.</param>
+ <remarks>
+ <para>
+ Watch a specified config file used to configure a repository
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Config.XmlConfigurator.ConfigureAndWatchHandler.m_configFile">
+ <summary>
+ Holds the FileInfo used to configure the XmlConfigurator
+ </summary>
+ </member>
+ <member name="F:log4net.Config.XmlConfigurator.ConfigureAndWatchHandler.m_repository">
+ <summary>
+ Holds the repository being configured.
+ </summary>
+ </member>
+ <member name="F:log4net.Config.XmlConfigurator.ConfigureAndWatchHandler.m_timer">
+ <summary>
+ The timer used to compress the notification events.
+ </summary>
+ </member>
+ <member name="M:log4net.Config.XmlConfigurator.ConfigureAndWatchHandler.#ctor(log4net.Repository.ILoggerRepository,System.IO.FileInfo)">
+ <summary>
+ Initializes a new instance of the <see cref="T:log4net.Config.XmlConfigurator.ConfigureAndWatchHandler"/> class.
+ </summary>
+ <param name="repository">The repository to configure.</param>
+ <param name="configFile">The configuration file to watch.</param>
+ <remarks>
+ <para>
+ Initializes a new instance of the <see cref="T:log4net.Config.XmlConfigurator.ConfigureAndWatchHandler"/> class.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Config.XmlConfigurator.ConfigureAndWatchHandler.ConfigureAndWatchHandler_OnChanged(System.Object,System.IO.FileSystemEventArgs)">
+ <summary>
+ Event handler used by <see cref="T:log4net.Config.XmlConfigurator.ConfigureAndWatchHandler"/>.
+ </summary>
+ <param name="source">The <see cref="T:System.IO.FileSystemWatcher"/> firing the event.</param>
+ <param name="e">The argument indicates the file that caused the event to be fired.</param>
+ <remarks>
+ <para>
+ This handler reloads the configuration from the file when the event is fired.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Config.XmlConfigurator.ConfigureAndWatchHandler.ConfigureAndWatchHandler_OnRenamed(System.Object,System.IO.RenamedEventArgs)">
+ <summary>
+ Event handler used by <see cref="T:log4net.Config.XmlConfigurator.ConfigureAndWatchHandler"/>.
+ </summary>
+ <param name="source">The <see cref="T:System.IO.FileSystemWatcher"/> firing the event.</param>
+ <param name="e">The argument indicates the file that caused the event to be fired.</param>
+ <remarks>
+ <para>
+ This handler reloads the configuration from the file when the event is fired.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Config.XmlConfigurator.ConfigureAndWatchHandler.OnWatchedFileChange(System.Object)">
+ <summary>
+ Called by the timer when the configuration has been updated.
+ </summary>
+ <param name="state">null</param>
+ </member>
+ <member name="T:log4net.Core.CompactRepositorySelector">
+ <summary>
+ The implementation of the <see cref="T:log4net.Core.IRepositorySelector"/> interface suitable
+ for use with the compact framework
+ </summary>
+ <remarks>
+ <para>
+ This <see cref="T:log4net.Core.IRepositorySelector"/> implementation is a simple
+ mapping between repository name and <see cref="T:log4net.Repository.ILoggerRepository"/>
+ object.
+ </para>
+ <para>
+ The .NET Compact Framework 1.0 does not support retrieving assembly
+ level attributes therefore unlike the <c>DefaultRepositorySelector</c>
+ this selector does not examine the calling assembly for attributes.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="T:log4net.Core.IRepositorySelector">
+ <summary>
+ Interface used by the <see cref="T:log4net.LogManager"/> to select the <see cref="T:log4net.Repository.ILoggerRepository"/>.
+ </summary>
+ <remarks>
+ <para>
+ The <see cref="T:log4net.LogManager"/> uses a <see cref="T:log4net.Core.IRepositorySelector"/>
+ to specify the policy for selecting the correct <see cref="T:log4net.Repository.ILoggerRepository"/>
+ to return to the caller.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="M:log4net.Core.IRepositorySelector.GetRepository(System.Reflection.Assembly)">
+ <summary>
+ Gets the <see cref="T:log4net.Repository.ILoggerRepository"/> for the specified assembly.
+ </summary>
+ <param name="assembly">The assembly to use to lookup to the <see cref="T:log4net.Repository.ILoggerRepository"/></param>
+ <returns>The <see cref="T:log4net.Repository.ILoggerRepository"/> for the assembly.</returns>
+ <remarks>
+ <para>
+ Gets the <see cref="T:log4net.Repository.ILoggerRepository"/> for the specified assembly.
+ </para>
+ <para>
+ How the association between <see cref="T:System.Reflection.Assembly"/> and <see cref="T:log4net.Repository.ILoggerRepository"/>
+ is made is not defined. The implementation may choose any method for
+ this association. The results of this method must be repeatable, i.e.
+ when called again with the same arguments the result must be the
+ save value.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.IRepositorySelector.GetRepository(System.String)">
+ <summary>
+ Gets the named <see cref="T:log4net.Repository.ILoggerRepository"/>.
+ </summary>
+ <param name="repositoryName">The name to use to lookup to the <see cref="T:log4net.Repository.ILoggerRepository"/>.</param>
+ <returns>The named <see cref="T:log4net.Repository.ILoggerRepository"/></returns>
+ <remarks>
+ Lookup a named <see cref="T:log4net.Repository.ILoggerRepository"/>. This is the repository created by
+ calling <see cref="M:log4net.Core.IRepositorySelector.CreateRepository(System.String,System.Type)"/>.
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.IRepositorySelector.CreateRepository(System.Reflection.Assembly,System.Type)">
+ <summary>
+ Creates a new repository for the assembly specified.
+ </summary>
+ <param name="assembly">The assembly to use to create the domain to associate with the <see cref="T:log4net.Repository.ILoggerRepository"/>.</param>
+ <param name="repositoryType">The type of repository to create, must implement <see cref="T:log4net.Repository.ILoggerRepository"/>.</param>
+ <returns>The repository created.</returns>
+ <remarks>
+ <para>
+ The <see cref="T:log4net.Repository.ILoggerRepository"/> created will be associated with the domain
+ specified such that a call to <see cref="M:log4net.Core.IRepositorySelector.GetRepository(System.Reflection.Assembly)"/> with the
+ same assembly specified will return the same repository instance.
+ </para>
+ <para>
+ How the association between <see cref="T:System.Reflection.Assembly"/> and <see cref="T:log4net.Repository.ILoggerRepository"/>
+ is made is not defined. The implementation may choose any method for
+ this association.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.IRepositorySelector.CreateRepository(System.String,System.Type)">
+ <summary>
+ Creates a new repository with the name specified.
+ </summary>
+ <param name="repositoryName">The name to associate with the <see cref="T:log4net.Repository.ILoggerRepository"/>.</param>
+ <param name="repositoryType">The type of repository to create, must implement <see cref="T:log4net.Repository.ILoggerRepository"/>.</param>
+ <returns>The repository created.</returns>
+ <remarks>
+ <para>
+ The <see cref="T:log4net.Repository.ILoggerRepository"/> created will be associated with the name
+ specified such that a call to <see cref="M:log4net.Core.IRepositorySelector.GetRepository(System.String)"/> with the
+ same name will return the same repository instance.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.IRepositorySelector.ExistsRepository(System.String)">
+ <summary>
+ Test if a named repository exists
+ </summary>
+ <param name="repositoryName">the named repository to check</param>
+ <returns><c>true</c> if the repository exists</returns>
+ <remarks>
+ <para>
+ Test if a named repository exists. Use <see cref="M:log4net.Core.IRepositorySelector.CreateRepository(System.Reflection.Assembly,System.Type)"/>
+ to create a new repository and <see cref="M:log4net.Core.IRepositorySelector.GetRepository(System.Reflection.Assembly)"/> to retrieve
+ a repository.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.IRepositorySelector.GetAllRepositories">
+ <summary>
+ Gets an array of all currently defined repositories.
+ </summary>
+ <returns>
+ An array of the <see cref="T:log4net.Repository.ILoggerRepository"/> instances created by
+ this <see cref="T:log4net.Core.IRepositorySelector"/>.</returns>
+ <remarks>
+ <para>
+ Gets an array of all of the repositories created by this selector.
+ </para>
+ </remarks>
+ </member>
+ <member name="E:log4net.Core.IRepositorySelector.LoggerRepositoryCreatedEvent">
+ <summary>
+ Event to notify that a logger repository has been created.
+ </summary>
+ <value>
+ Event to notify that a logger repository has been created.
+ </value>
+ <remarks>
+ <para>
+ Event raised when a new repository is created.
+ The event source will be this selector. The event args will
+ be a <see cref="T:log4net.Core.LoggerRepositoryCreationEventArgs"/> which
+ holds the newly created <see cref="T:log4net.Repository.ILoggerRepository"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.CompactRepositorySelector.#ctor(System.Type)">
+ <summary>
+ Create a new repository selector
+ </summary>
+ <param name="defaultRepositoryType">the type of the repositories to create, must implement <see cref="T:log4net.Repository.ILoggerRepository"/></param>
+ <remarks>
+ <para>
+ Create an new compact repository selector.
+ The default type for repositories must be specified,
+ an appropriate value would be <see cref="T:log4net.Repository.Hierarchy.Hierarchy"/>.
+ </para>
+ </remarks>
+ <exception cref="T:System.ArgumentNullException">throw if <paramref name="defaultRepositoryType"/> is null</exception>
+ <exception cref="T:System.ArgumentOutOfRangeException">throw if <paramref name="defaultRepositoryType"/> does not implement <see cref="T:log4net.Repository.ILoggerRepository"/></exception>
+ </member>
+ <member name="M:log4net.Core.CompactRepositorySelector.GetRepository(System.Reflection.Assembly)">
+ <summary>
+ Get the <see cref="T:log4net.Repository.ILoggerRepository"/> for the specified assembly
+ </summary>
+ <param name="assembly">not used</param>
+ <returns>The default <see cref="T:log4net.Repository.ILoggerRepository"/></returns>
+ <remarks>
+ <para>
+ The <paramref name="assembly"/> argument is not used. This selector does not create a
+ separate repository for each assembly.
+ </para>
+ <para>
+ As a named repository is not specified the default repository is
+ returned. The default repository is named <c>log4net-default-repository</c>.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.CompactRepositorySelector.GetRepository(System.String)">
+ <summary>
+ Get the named <see cref="T:log4net.Repository.ILoggerRepository"/>
+ </summary>
+ <param name="repositoryName">the name of the repository to lookup</param>
+ <returns>The named <see cref="T:log4net.Repository.ILoggerRepository"/></returns>
+ <remarks>
+ <para>
+ Get the named <see cref="T:log4net.Repository.ILoggerRepository"/>. The default
+ repository is <c>log4net-default-repository</c>. Other repositories
+ must be created using the <see cref="M:log4net.Core.CompactRepositorySelector.CreateRepository(System.String,System.Type)"/>.
+ If the named repository does not exist an exception is thrown.
+ </para>
+ </remarks>
+ <exception cref="T:System.ArgumentNullException">throw if <paramref name="repositoryName"/> is null</exception>
+ <exception cref="T:log4net.Core.LogException">throw if the <paramref name="repositoryName"/> does not exist</exception>
+ </member>
+ <member name="M:log4net.Core.CompactRepositorySelector.CreateRepository(System.Reflection.Assembly,System.Type)">
+ <summary>
+ Create a new repository for the assembly specified
+ </summary>
+ <param name="assembly">not used</param>
+ <param name="repositoryType">the type of repository to create, must implement <see cref="T:log4net.Repository.ILoggerRepository"/></param>
+ <returns>the repository created</returns>
+ <remarks>
+ <para>
+ The <paramref name="assembly"/> argument is not used. This selector does not create a
+ separate repository for each assembly.
+ </para>
+ <para>
+ If the <paramref name="repositoryType"/> is <c>null</c> then the
+ default repository type specified to the constructor is used.
+ </para>
+ <para>
+ As a named repository is not specified the default repository is
+ returned. The default repository is named <c>log4net-default-repository</c>.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.CompactRepositorySelector.CreateRepository(System.String,System.Type)">
+ <summary>
+ Create a new repository for the repository specified
+ </summary>
+ <param name="repositoryName">the repository to associate with the <see cref="T:log4net.Repository.ILoggerRepository"/></param>
+ <param name="repositoryType">the type of repository to create, must implement <see cref="T:log4net.Repository.ILoggerRepository"/>.
+ If this param is null then the default repository type is used.</param>
+ <returns>the repository created</returns>
+ <remarks>
+ <para>
+ The <see cref="T:log4net.Repository.ILoggerRepository"/> created will be associated with the repository
+ specified such that a call to <see cref="M:log4net.Core.CompactRepositorySelector.GetRepository(System.String)"/> with the
+ same repository specified will return the same repository instance.
+ </para>
+ <para>
+ If the named repository already exists an exception will be thrown.
+ </para>
+ <para>
+ If <paramref name="repositoryType"/> is <c>null</c> then the default
+ repository type specified to the constructor is used.
+ </para>
+ </remarks>
+ <exception cref="T:System.ArgumentNullException">throw if <paramref name="repositoryName"/> is null</exception>
+ <exception cref="T:log4net.Core.LogException">throw if the <paramref name="repositoryName"/> already exists</exception>
+ </member>
+ <member name="M:log4net.Core.CompactRepositorySelector.ExistsRepository(System.String)">
+ <summary>
+ Test if a named repository exists
+ </summary>
+ <param name="repositoryName">the named repository to check</param>
+ <returns><c>true</c> if the repository exists</returns>
+ <remarks>
+ <para>
+ Test if a named repository exists. Use <see cref="M:log4net.Core.CompactRepositorySelector.CreateRepository(System.String,System.Type)"/>
+ to create a new repository and <see cref="M:log4net.Core.CompactRepositorySelector.GetRepository(System.String)"/> to retrieve
+ a repository.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.CompactRepositorySelector.GetAllRepositories">
+ <summary>
+ Gets a list of <see cref="T:log4net.Repository.ILoggerRepository"/> objects
+ </summary>
+ <returns>an array of all known <see cref="T:log4net.Repository.ILoggerRepository"/> objects</returns>
+ <remarks>
+ <para>
+ Gets an array of all of the repositories created by this selector.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.CompactRepositorySelector.OnLoggerRepositoryCreatedEvent(log4net.Repository.ILoggerRepository)">
+ <summary>
+ Notify the registered listeners that the repository has been created
+ </summary>
+ <param name="repository">The repository that has been created</param>
+ <remarks>
+ <para>
+ Raises the <event cref="E:log4net.Core.CompactRepositorySelector.LoggerRepositoryCreatedEvent">LoggerRepositoryCreatedEvent</event>
+ event.
+ </para>
+ </remarks>
+ </member>
+ <member name="E:log4net.Core.CompactRepositorySelector.LoggerRepositoryCreatedEvent">
+ <summary>
+ Event to notify that a logger repository has been created.
+ </summary>
+ <value>
+ Event to notify that a logger repository has been created.
+ </value>
+ <remarks>
+ <para>
+ Event raised when a new repository is created.
+ The event source will be this selector. The event args will
+ be a <see cref="T:log4net.Core.LoggerRepositoryCreationEventArgs"/> which
+ holds the newly created <see cref="T:log4net.Repository.ILoggerRepository"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Core.DefaultRepositorySelector">
+ <summary>
+ The default implementation of the <see cref="T:log4net.Core.IRepositorySelector"/> interface.
+ </summary>
+ <remarks>
+ <para>
+ Uses attributes defined on the calling assembly to determine how to
+ configure the hierarchy for the repository.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="M:log4net.Core.DefaultRepositorySelector.#ctor(System.Type)">
+ <summary>
+ Creates a new repository selector.
+ </summary>
+ <param name="defaultRepositoryType">The type of the repositories to create, must implement <see cref="T:log4net.Repository.ILoggerRepository"/></param>
+ <remarks>
+ <para>
+ Create an new repository selector.
+ The default type for repositories must be specified,
+ an appropriate value would be <see cref="T:log4net.Repository.Hierarchy.Hierarchy"/>.
+ </para>
+ </remarks>
+ <exception cref="T:System.ArgumentNullException"><paramref name="defaultRepositoryType"/> is <see langword="null"/>.</exception>
+ <exception cref="T:System.ArgumentOutOfRangeException"><paramref name="defaultRepositoryType"/> does not implement <see cref="T:log4net.Repository.ILoggerRepository"/>.</exception>
+ </member>
+ <member name="M:log4net.Core.DefaultRepositorySelector.GetRepository(System.Reflection.Assembly)">
+ <summary>
+ Gets the <see cref="T:log4net.Repository.ILoggerRepository"/> for the specified assembly.
+ </summary>
+ <param name="repositoryAssembly">The assembly use to lookup the <see cref="T:log4net.Repository.ILoggerRepository"/>.</param>
+ <remarks>
+ <para>
+ The type of the <see cref="T:log4net.Repository.ILoggerRepository"/> created and the repository
+ to create can be overridden by specifying the <see cref="T:log4net.Config.RepositoryAttribute"/>
+ attribute on the <paramref name="repositoryAssembly"/>.
+ </para>
+ <para>
+ The default values are to use the <see cref="T:log4net.Repository.Hierarchy.Hierarchy"/>
+ implementation of the <see cref="T:log4net.Repository.ILoggerRepository"/> interface and to use the
+ <see cref="P:System.Reflection.AssemblyName.Name"/> as the name of the repository.
+ </para>
+ <para>
+ The <see cref="T:log4net.Repository.ILoggerRepository"/> created will be automatically configured using
+ any <see cref="T:log4net.Config.ConfiguratorAttribute"/> attributes defined on
+ the <paramref name="repositoryAssembly"/>.
+ </para>
+ </remarks>
+ <returns>The <see cref="T:log4net.Repository.ILoggerRepository"/> for the assembly</returns>
+ <exception cref="T:System.ArgumentNullException"><paramref name="repositoryAssembly"/> is <see langword="null"/>.</exception>
+ </member>
+ <member name="M:log4net.Core.DefaultRepositorySelector.GetRepository(System.String)">
+ <summary>
+ Gets the <see cref="T:log4net.Repository.ILoggerRepository"/> for the specified repository.
+ </summary>
+ <param name="repositoryName">The repository to use to lookup the <see cref="T:log4net.Repository.ILoggerRepository"/>.</param>
+ <returns>The <see cref="T:log4net.Repository.ILoggerRepository"/> for the specified repository.</returns>
+ <remarks>
+ <para>
+ Returns the named repository. If <paramref name="repositoryName"/> is <c>null</c>
+ a <see cref="T:System.ArgumentNullException"/> is thrown. If the repository
+ does not exist a <see cref="T:log4net.Core.LogException"/> is thrown.
+ </para>
+ <para>
+ Use <see cref="M:log4net.Core.DefaultRepositorySelector.CreateRepository(System.String,System.Type)"/> to create a repository.
+ </para>
+ </remarks>
+ <exception cref="T:System.ArgumentNullException"><paramref name="repositoryName"/> is <see langword="null"/>.</exception>
+ <exception cref="T:log4net.Core.LogException"><paramref name="repositoryName"/> does not exist.</exception>
+ </member>
+ <member name="M:log4net.Core.DefaultRepositorySelector.CreateRepository(System.Reflection.Assembly,System.Type)">
+ <summary>
+ Create a new repository for the assembly specified
+ </summary>
+ <param name="repositoryAssembly">the assembly to use to create the repository to associate with the <see cref="T:log4net.Repository.ILoggerRepository"/>.</param>
+ <param name="repositoryType">The type of repository to create, must implement <see cref="T:log4net.Repository.ILoggerRepository"/>.</param>
+ <returns>The repository created.</returns>
+ <remarks>
+ <para>
+ The <see cref="T:log4net.Repository.ILoggerRepository"/> created will be associated with the repository
+ specified such that a call to <see cref="M:log4net.Core.DefaultRepositorySelector.GetRepository(System.Reflection.Assembly)"/> with the
+ same assembly specified will return the same repository instance.
+ </para>
+ <para>
+ The type of the <see cref="T:log4net.Repository.ILoggerRepository"/> created and
+ the repository to create can be overridden by specifying the
+ <see cref="T:log4net.Config.RepositoryAttribute"/> attribute on the
+ <paramref name="repositoryAssembly"/>. The default values are to use the
+ <paramref name="repositoryType"/> implementation of the
+ <see cref="T:log4net.Repository.ILoggerRepository"/> interface and to use the
+ <see cref="P:System.Reflection.AssemblyName.Name"/> as the name of the repository.
+ </para>
+ <para>
+ The <see cref="T:log4net.Repository.ILoggerRepository"/> created will be automatically
+ configured using any <see cref="T:log4net.Config.ConfiguratorAttribute"/>
+ attributes defined on the <paramref name="repositoryAssembly"/>.
+ </para>
+ <para>
+ If a repository for the <paramref name="repositoryAssembly"/> already exists
+ that repository will be returned. An error will not be raised and that
+ repository may be of a different type to that specified in <paramref name="repositoryType"/>.
+ Also the <see cref="T:log4net.Config.RepositoryAttribute"/> attribute on the
+ assembly may be used to override the repository type specified in
+ <paramref name="repositoryType"/>.
+ </para>
+ </remarks>
+ <exception cref="T:System.ArgumentNullException"><paramref name="repositoryAssembly"/> is <see langword="null"/>.</exception>
+ </member>
+ <member name="M:log4net.Core.DefaultRepositorySelector.CreateRepository(System.Reflection.Assembly,System.Type,System.String,System.Boolean)">
+ <summary>
+ Creates a new repository for the assembly specified.
+ </summary>
+ <param name="repositoryAssembly">the assembly to use to create the repository to associate with the <see cref="T:log4net.Repository.ILoggerRepository"/>.</param>
+ <param name="repositoryType">The type of repository to create, must implement <see cref="T:log4net.Repository.ILoggerRepository"/>.</param>
+ <param name="repositoryName">The name to assign to the created repository</param>
+ <param name="readAssemblyAttributes">Set to <c>true</c> to read and apply the assembly attributes</param>
+ <returns>The repository created.</returns>
+ <remarks>
+ <para>
+ The <see cref="T:log4net.Repository.ILoggerRepository"/> created will be associated with the repository
+ specified such that a call to <see cref="M:log4net.Core.DefaultRepositorySelector.GetRepository(System.Reflection.Assembly)"/> with the
+ same assembly specified will return the same repository instance.
+ </para>
+ <para>
+ The type of the <see cref="T:log4net.Repository.ILoggerRepository"/> created and
+ the repository to create can be overridden by specifying the
+ <see cref="T:log4net.Config.RepositoryAttribute"/> attribute on the
+ <paramref name="repositoryAssembly"/>. The default values are to use the
+ <paramref name="repositoryType"/> implementation of the
+ <see cref="T:log4net.Repository.ILoggerRepository"/> interface and to use the
+ <see cref="P:System.Reflection.AssemblyName.Name"/> as the name of the repository.
+ </para>
+ <para>
+ The <see cref="T:log4net.Repository.ILoggerRepository"/> created will be automatically
+ configured using any <see cref="T:log4net.Config.ConfiguratorAttribute"/>
+ attributes defined on the <paramref name="repositoryAssembly"/>.
+ </para>
+ <para>
+ If a repository for the <paramref name="repositoryAssembly"/> already exists
+ that repository will be returned. An error will not be raised and that
+ repository may be of a different type to that specified in <paramref name="repositoryType"/>.
+ Also the <see cref="T:log4net.Config.RepositoryAttribute"/> attribute on the
+ assembly may be used to override the repository type specified in
+ <paramref name="repositoryType"/>.
+ </para>
+ </remarks>
+ <exception cref="T:System.ArgumentNullException"><paramref name="repositoryAssembly"/> is <see langword="null"/>.</exception>
+ </member>
+ <member name="M:log4net.Core.DefaultRepositorySelector.CreateRepository(System.String,System.Type)">
+ <summary>
+ Creates a new repository for the specified repository.
+ </summary>
+ <param name="repositoryName">The repository to associate with the <see cref="T:log4net.Repository.ILoggerRepository"/>.</param>
+ <param name="repositoryType">The type of repository to create, must implement <see cref="T:log4net.Repository.ILoggerRepository"/>.
+ If this param is <see langword="null"/> then the default repository type is used.</param>
+ <returns>The new repository.</returns>
+ <remarks>
+ <para>
+ The <see cref="T:log4net.Repository.ILoggerRepository"/> created will be associated with the repository
+ specified such that a call to <see cref="M:log4net.Core.DefaultRepositorySelector.GetRepository(System.String)"/> with the
+ same repository specified will return the same repository instance.
+ </para>
+ </remarks>
+ <exception cref="T:System.ArgumentNullException"><paramref name="repositoryName"/> is <see langword="null"/>.</exception>
+ <exception cref="T:log4net.Core.LogException"><paramref name="repositoryName"/> already exists.</exception>
+ </member>
+ <member name="M:log4net.Core.DefaultRepositorySelector.ExistsRepository(System.String)">
+ <summary>
+ Test if a named repository exists
+ </summary>
+ <param name="repositoryName">the named repository to check</param>
+ <returns><c>true</c> if the repository exists</returns>
+ <remarks>
+ <para>
+ Test if a named repository exists. Use <see cref="M:log4net.Core.DefaultRepositorySelector.CreateRepository(System.String,System.Type)"/>
+ to create a new repository and <see cref="M:log4net.Core.DefaultRepositorySelector.GetRepository(System.String)"/> to retrieve
+ a repository.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.DefaultRepositorySelector.GetAllRepositories">
+ <summary>
+ Gets a list of <see cref="T:log4net.Repository.ILoggerRepository"/> objects
+ </summary>
+ <returns>an array of all known <see cref="T:log4net.Repository.ILoggerRepository"/> objects</returns>
+ <remarks>
+ <para>
+ Gets an array of all of the repositories created by this selector.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.DefaultRepositorySelector.AliasRepository(System.String,log4net.Repository.ILoggerRepository)">
+ <summary>
+ Aliases a repository to an existing repository.
+ </summary>
+ <param name="repositoryAlias">The repository to alias.</param>
+ <param name="repositoryTarget">The repository that the repository is aliased to.</param>
+ <remarks>
+ <para>
+ The repository specified will be aliased to the repository when created.
+ The repository must not already exist.
+ </para>
+ <para>
+ When the repository is created it must utilize the same repository type as
+ the repository it is aliased to, otherwise the aliasing will fail.
+ </para>
+ </remarks>
+ <exception cref="T:System.ArgumentNullException">
+ <para><paramref name="repositoryAlias"/> is <see langword="null"/>.</para>
+ <para>-or-</para>
+ <para><paramref name="repositoryTarget"/> is <see langword="null"/>.</para>
+ </exception>
+ </member>
+ <member name="M:log4net.Core.DefaultRepositorySelector.OnLoggerRepositoryCreatedEvent(log4net.Repository.ILoggerRepository)">
+ <summary>
+ Notifies the registered listeners that the repository has been created.
+ </summary>
+ <param name="repository">The repository that has been created.</param>
+ <remarks>
+ <para>
+ Raises the <see cref="E:log4net.Core.DefaultRepositorySelector.LoggerRepositoryCreatedEvent"/> event.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.DefaultRepositorySelector.GetInfoForAssembly(System.Reflection.Assembly,System.String@,System.Type@)">
+ <summary>
+ Gets the repository name and repository type for the specified assembly.
+ </summary>
+ <param name="assembly">The assembly that has a <see cref="T:log4net.Config.RepositoryAttribute"/>.</param>
+ <param name="repositoryName">in/out param to hold the repository name to use for the assembly, caller should set this to the default value before calling.</param>
+ <param name="repositoryType">in/out param to hold the type of the repository to create for the assembly, caller should set this to the default value before calling.</param>
+ <exception cref="T:System.ArgumentNullException"><paramref name="assembly"/> is <see langword="null"/>.</exception>
+ </member>
+ <member name="M:log4net.Core.DefaultRepositorySelector.ConfigureRepository(System.Reflection.Assembly,log4net.Repository.ILoggerRepository)">
+ <summary>
+ Configures the repository using information from the assembly.
+ </summary>
+ <param name="assembly">The assembly containing <see cref="T:log4net.Config.ConfiguratorAttribute"/>
+ attributes which define the configuration for the repository.</param>
+ <param name="repository">The repository to configure.</param>
+ <exception cref="T:System.ArgumentNullException">
+ <para><paramref name="assembly"/> is <see langword="null"/>.</para>
+ <para>-or-</para>
+ <para><paramref name="repository"/> is <see langword="null"/>.</para>
+ </exception>
+ </member>
+ <member name="M:log4net.Core.DefaultRepositorySelector.LoadPlugins(System.Reflection.Assembly,log4net.Repository.ILoggerRepository)">
+ <summary>
+ Loads the attribute defined plugins on the assembly.
+ </summary>
+ <param name="assembly">The assembly that contains the attributes.</param>
+ <param name="repository">The repository to add the plugins to.</param>
+ <exception cref="T:System.ArgumentNullException">
+ <para><paramref name="assembly"/> is <see langword="null"/>.</para>
+ <para>-or-</para>
+ <para><paramref name="repository"/> is <see langword="null"/>.</para>
+ </exception>
+ </member>
+ <member name="M:log4net.Core.DefaultRepositorySelector.LoadAliases(System.Reflection.Assembly,log4net.Repository.ILoggerRepository)">
+ <summary>
+ Loads the attribute defined aliases on the assembly.
+ </summary>
+ <param name="assembly">The assembly that contains the attributes.</param>
+ <param name="repository">The repository to alias to.</param>
+ <exception cref="T:System.ArgumentNullException">
+ <para><paramref name="assembly"/> is <see langword="null"/>.</para>
+ <para>-or-</para>
+ <para><paramref name="repository"/> is <see langword="null"/>.</para>
+ </exception>
+ </member>
+ <member name="E:log4net.Core.DefaultRepositorySelector.LoggerRepositoryCreatedEvent">
+ <summary>
+ Event to notify that a logger repository has been created.
+ </summary>
+ <value>
+ Event to notify that a logger repository has been created.
+ </value>
+ <remarks>
+ <para>
+ Event raised when a new repository is created.
+ The event source will be this selector. The event args will
+ be a <see cref="T:log4net.Core.LoggerRepositoryCreationEventArgs"/> which
+ holds the newly created <see cref="T:log4net.Repository.ILoggerRepository"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Core.ErrorCode">
+ <summary>
+ Defined error codes that can be passed to the <see cref="M:log4net.Core.IErrorHandler.Error(System.String,System.Exception,log4net.Core.ErrorCode)"/> method.
+ </summary>
+ <remarks>
+ <para>
+ Values passed to the <see cref="M:log4net.Core.IErrorHandler.Error(System.String,System.Exception,log4net.Core.ErrorCode)"/> method.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="F:log4net.Core.ErrorCode.GenericFailure">
+ <summary>
+ A general error
+ </summary>
+ </member>
+ <member name="F:log4net.Core.ErrorCode.WriteFailure">
+ <summary>
+ Error while writing output
+ </summary>
+ </member>
+ <member name="F:log4net.Core.ErrorCode.FlushFailure">
+ <summary>
+ Failed to flush file
+ </summary>
+ </member>
+ <member name="F:log4net.Core.ErrorCode.CloseFailure">
+ <summary>
+ Failed to close file
+ </summary>
+ </member>
+ <member name="F:log4net.Core.ErrorCode.FileOpenFailure">
+ <summary>
+ Unable to open output file
+ </summary>
+ </member>
+ <member name="F:log4net.Core.ErrorCode.MissingLayout">
+ <summary>
+ No layout specified
+ </summary>
+ </member>
+ <member name="F:log4net.Core.ErrorCode.AddressParseFailure">
+ <summary>
+ Failed to parse address
+ </summary>
+ </member>
+ <member name="T:log4net.Core.IErrorHandler">
+ <summary>
+ Appenders may delegate their error handling to an <see cref="T:log4net.Core.IErrorHandler"/>.
+ </summary>
+ <remarks>
+ <para>
+ Error handling is a particularly tedious to get right because by
+ definition errors are hard to predict and to reproduce.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="M:log4net.Core.IErrorHandler.Error(System.String,System.Exception,log4net.Core.ErrorCode)">
+ <summary>
+ Handles the error and information about the error condition is passed as
+ a parameter.
+ </summary>
+ <param name="message">The message associated with the error.</param>
+ <param name="e">The <see cref="T:System.Exception"/> that was thrown when the error occurred.</param>
+ <param name="errorCode">The error code associated with the error.</param>
+ <remarks>
+ <para>
+ Handles the error and information about the error condition is passed as
+ a parameter.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.IErrorHandler.Error(System.String,System.Exception)">
+ <summary>
+ Prints the error message passed as a parameter.
+ </summary>
+ <param name="message">The message associated with the error.</param>
+ <param name="e">The <see cref="T:System.Exception"/> that was thrown when the error occurred.</param>
+ <remarks>
+ <para>
+ See <see cref="M:log4net.Core.IErrorHandler.Error(System.String,System.Exception,log4net.Core.ErrorCode)"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.IErrorHandler.Error(System.String)">
+ <summary>
+ Prints the error message passed as a parameter.
+ </summary>
+ <param name="message">The message associated with the error.</param>
+ <remarks>
+ <para>
+ See <see cref="M:log4net.Core.IErrorHandler.Error(System.String,System.Exception,log4net.Core.ErrorCode)"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Core.IFixingRequired">
+ <summary>
+ Interface for objects that require fixing.
+ </summary>
+ <remarks>
+ <para>
+ Interface that indicates that the object requires fixing before it
+ can be taken outside the context of the appender's
+ <see cref="M:log4net.Appender.IAppender.DoAppend(log4net.Core.LoggingEvent)"/> method.
+ </para>
+ <para>
+ When objects that implement this interface are stored
+ in the context properties maps <see cref="T:log4net.GlobalContext"/>
+ <see cref="P:log4net.GlobalContext.Properties"/> and <see cref="T:log4net.ThreadContext"/>
+ <see cref="P:log4net.ThreadContext.Properties"/> are fixed
+ (see <see cref="P:log4net.Core.LoggingEvent.Fix"/>) the <see cref="M:log4net.Core.IFixingRequired.GetFixedObject"/>
+ method will be called.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="M:log4net.Core.IFixingRequired.GetFixedObject">
+ <summary>
+ Get a portable version of this object
+ </summary>
+ <returns>the portable instance of this object</returns>
+ <remarks>
+ <para>
+ Get a portable instance object that represents the current
+ state of this object. The portable object can be stored
+ and logged from any thread with identical results.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Core.ILogger">
+ <summary>
+ Interface that all loggers implement
+ </summary>
+ <remarks>
+ <para>
+ This interface supports logging events and testing if a level
+ is enabled for logging.
+ </para>
+ <para>
+ These methods will not throw exceptions. Note to implementor, ensure
+ that the implementation of these methods cannot allow an exception
+ to be thrown to the caller.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="M:log4net.Core.ILogger.Log(System.Type,log4net.Core.Level,System.Object,System.Exception)">
+ <summary>
+ This generic form is intended to be used by wrappers.
+ </summary>
+ <param name="callerStackBoundaryDeclaringType">The declaring type of the method that is
+ the stack boundary into the logging system for this call.</param>
+ <param name="level">The level of the message to be logged.</param>
+ <param name="message">The message object to log.</param>
+ <param name="exception">the exception to log, including its stack trace. Pass <c>null</c> to not log an exception.</param>
+ <remarks>
+ <para>
+ Generates a logging event for the specified <paramref name="level"/> using
+ the <paramref name="message"/> and <paramref name="exception"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.ILogger.Log(log4net.Core.LoggingEvent)">
+ <summary>
+ This is the most generic printing method that is intended to be used
+ by wrappers.
+ </summary>
+ <param name="logEvent">The event being logged.</param>
+ <remarks>
+ <para>
+ Logs the specified logging event through this logger.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.ILogger.IsEnabledFor(log4net.Core.Level)">
+ <summary>
+ Checks if this logger is enabled for a given <see cref="T:log4net.Core.Level"/> passed as parameter.
+ </summary>
+ <param name="level">The level to check.</param>
+ <returns>
+ <c>true</c> if this logger is enabled for <c>level</c>, otherwise <c>false</c>.
+ </returns>
+ <remarks>
+ <para>
+ Test if this logger is going to log events of the specified <paramref name="level"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Core.ILogger.Name">
+ <summary>
+ Gets the name of the logger.
+ </summary>
+ <value>
+ The name of the logger.
+ </value>
+ <remarks>
+ <para>
+ The name of this logger
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Core.ILogger.Repository">
+ <summary>
+ Gets the <see cref="T:log4net.Repository.ILoggerRepository"/> where this
+ <c>Logger</c> instance is attached to.
+ </summary>
+ <value>
+ The <see cref="T:log4net.Repository.ILoggerRepository"/> that this logger belongs to.
+ </value>
+ <remarks>
+ <para>
+ Gets the <see cref="T:log4net.Repository.ILoggerRepository"/> where this
+ <c>Logger</c> instance is attached to.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Core.ILoggerWrapper">
+ <summary>
+ Base interface for all wrappers
+ </summary>
+ <remarks>
+ <para>
+ Base interface for all wrappers.
+ </para>
+ <para>
+ All wrappers must implement this interface.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="P:log4net.Core.ILoggerWrapper.Logger">
+ <summary>
+ Get the implementation behind this wrapper object.
+ </summary>
+ <value>
+ The <see cref="T:log4net.Core.ILogger"/> object that in implementing this object.
+ </value>
+ <remarks>
+ <para>
+ The <see cref="T:log4net.Core.ILogger"/> object that in implementing this
+ object. The <c>Logger</c> object may not
+ be the same object as this object because of logger decorators.
+ This gets the actual underlying objects that is used to process
+ the log events.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Core.LoggerRepositoryCreationEventHandler">
+ <summary>
+ Delegate used to handle logger repository creation event notifications
+ </summary>
+ <param name="sender">The <see cref="T:log4net.Core.IRepositorySelector"/> which created the repository.</param>
+ <param name="e">The <see cref="T:log4net.Core.LoggerRepositoryCreationEventArgs"/> event args
+ that holds the <see cref="T:log4net.Repository.ILoggerRepository"/> instance that has been created.</param>
+ <remarks>
+ <para>
+ Delegate used to handle logger repository creation event notifications.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Core.LoggerRepositoryCreationEventArgs">
+ <summary>
+ Provides data for the <see cref="E:log4net.Core.IRepositorySelector.LoggerRepositoryCreatedEvent"/> event.
+ </summary>
+ <remarks>
+ <para>
+ A <see cref="E:log4net.Core.IRepositorySelector.LoggerRepositoryCreatedEvent"/>
+ event is raised every time a <see cref="T:log4net.Repository.ILoggerRepository"/> is created.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Core.LoggerRepositoryCreationEventArgs.m_repository">
+ <summary>
+ The <see cref="T:log4net.Repository.ILoggerRepository"/> created
+ </summary>
+ </member>
+ <member name="M:log4net.Core.LoggerRepositoryCreationEventArgs.#ctor(log4net.Repository.ILoggerRepository)">
+ <summary>
+ Construct instance using <see cref="T:log4net.Repository.ILoggerRepository"/> specified
+ </summary>
+ <param name="repository">the <see cref="T:log4net.Repository.ILoggerRepository"/> that has been created</param>
+ <remarks>
+ <para>
+ Construct instance using <see cref="T:log4net.Repository.ILoggerRepository"/> specified
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Core.LoggerRepositoryCreationEventArgs.LoggerRepository">
+ <summary>
+ The <see cref="T:log4net.Repository.ILoggerRepository"/> that has been created
+ </summary>
+ <value>
+ The <see cref="T:log4net.Repository.ILoggerRepository"/> that has been created
+ </value>
+ <remarks>
+ <para>
+ The <see cref="T:log4net.Repository.ILoggerRepository"/> that has been created
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Core.ITriggeringEventEvaluator">
+ <summary>
+ Test if an <see cref="T:log4net.Core.LoggingEvent"/> triggers an action
+ </summary>
+ <remarks>
+ <para>
+ Implementations of this interface allow certain appenders to decide
+ when to perform an appender specific action.
+ </para>
+ <para>
+ The action or behavior triggered is defined by the implementation.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="M:log4net.Core.ITriggeringEventEvaluator.IsTriggeringEvent(log4net.Core.LoggingEvent)">
+ <summary>
+ Test if this event triggers the action
+ </summary>
+ <param name="loggingEvent">The event to check</param>
+ <returns><c>true</c> if this event triggers the action, otherwise <c>false</c></returns>
+ <remarks>
+ <para>
+ Return <c>true</c> if this event triggers the action
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Core.Level">
+ <summary>
+ Defines the default set of levels recognized by the system.
+ </summary>
+ <remarks>
+ <para>
+ Each <see cref="T:log4net.Core.LoggingEvent"/> has an associated <see cref="T:log4net.Core.Level"/>.
+ </para>
+ <para>
+ Levels have a numeric <see cref="P:log4net.Core.Level.Value"/> that defines the relative
+ ordering between levels. Two Levels with the same <see cref="P:log4net.Core.Level.Value"/>
+ are deemed to be equivalent.
+ </para>
+ <para>
+ The levels that are recognized by log4net are set for each <see cref="T:log4net.Repository.ILoggerRepository"/>
+ and each repository can have different levels defined. The levels are stored
+ in the <see cref="P:log4net.Repository.ILoggerRepository.LevelMap"/> on the repository. Levels are
+ looked up by name from the <see cref="P:log4net.Repository.ILoggerRepository.LevelMap"/>.
+ </para>
+ <para>
+ When logging at level INFO the actual level used is not <see cref="F:log4net.Core.Level.Info"/> but
+ the value of <c>LoggerRepository.LevelMap["INFO"]</c>. The default value for this is
+ <see cref="F:log4net.Core.Level.Info"/>, but this can be changed by reconfiguring the level map.
+ </para>
+ <para>
+ Each level has a <see cref="P:log4net.Core.Level.DisplayName"/> in addition to its <see cref="P:log4net.Core.Level.Name"/>. The
+ <see cref="P:log4net.Core.Level.DisplayName"/> is the string that is written into the output log. By default
+ the display name is the same as the level name, but this can be used to alias levels
+ or to localize the log output.
+ </para>
+ <para>
+ Some of the predefined levels recognized by the system are:
+ </para>
+ <list type="bullet">
+ <item>
+ <description><see cref="F:log4net.Core.Level.Off"/>.</description>
+ </item>
+ <item>
+ <description><see cref="F:log4net.Core.Level.Fatal"/>.</description>
+ </item>
+ <item>
+ <description><see cref="F:log4net.Core.Level.Error"/>.</description>
+ </item>
+ <item>
+ <description><see cref="F:log4net.Core.Level.Warn"/>.</description>
+ </item>
+ <item>
+ <description><see cref="F:log4net.Core.Level.Info"/>.</description>
+ </item>
+ <item>
+ <description><see cref="F:log4net.Core.Level.Debug"/>.</description>
+ </item>
+ <item>
+ <description><see cref="F:log4net.Core.Level.All"/>.</description>
+ </item>
+ </list>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="M:log4net.Core.Level.#ctor(System.Int32,System.String,System.String)">
+ <summary>
+ Constructor
+ </summary>
+ <param name="level">Integer value for this level, higher values represent more severe levels.</param>
+ <param name="levelName">The string name of this level.</param>
+ <param name="displayName">The display name for this level. This may be localized or otherwise different from the name</param>
+ <remarks>
+ <para>
+ Initializes a new instance of the <see cref="T:log4net.Core.Level"/> class with
+ the specified level name and value.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.Level.#ctor(System.Int32,System.String)">
+ <summary>
+ Constructor
+ </summary>
+ <param name="level">Integer value for this level, higher values represent more severe levels.</param>
+ <param name="levelName">The string name of this level.</param>
+ <remarks>
+ <para>
+ Initializes a new instance of the <see cref="T:log4net.Core.Level"/> class with
+ the specified level name and value.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.Level.ToString">
+ <summary>
+ Returns the <see cref="T:System.String"/> representation of the current
+ <see cref="T:log4net.Core.Level"/>.
+ </summary>
+ <returns>
+ A <see cref="T:System.String"/> representation of the current <see cref="T:log4net.Core.Level"/>.
+ </returns>
+ <remarks>
+ <para>
+ Returns the level <see cref="P:log4net.Core.Level.Name"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.Level.Equals(System.Object)">
+ <summary>
+ Compares levels.
+ </summary>
+ <param name="o">The object to compare against.</param>
+ <returns><c>true</c> if the objects are equal.</returns>
+ <remarks>
+ <para>
+ Compares the levels of <see cref="T:log4net.Core.Level"/> instances, and
+ defers to base class if the target object is not a <see cref="T:log4net.Core.Level"/>
+ instance.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.Level.GetHashCode">
+ <summary>
+ Returns a hash code
+ </summary>
+ <returns>A hash code for the current <see cref="T:log4net.Core.Level"/>.</returns>
+ <remarks>
+ <para>
+ Returns a hash code suitable for use in hashing algorithms and data
+ structures like a hash table.
+ </para>
+ <para>
+ Returns the hash code of the level <see cref="P:log4net.Core.Level.Value"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.Level.CompareTo(System.Object)">
+ <summary>
+ Compares this instance to a specified object and returns an
+ indication of their relative values.
+ </summary>
+ <param name="r">A <see cref="T:log4net.Core.Level"/> instance or <see langword="null"/> to compare with this instance.</param>
+ <returns>
+ A 32-bit signed integer that indicates the relative order of the
+ values compared. The return value has these meanings:
+ <list type="table">
+ <listheader>
+ <term>Value</term>
+ <description>Meaning</description>
+ </listheader>
+ <item>
+ <term>Less than zero</term>
+ <description>This instance is less than <paramref name="r"/>.</description>
+ </item>
+ <item>
+ <term>Zero</term>
+ <description>This instance is equal to <paramref name="r"/>.</description>
+ </item>
+ <item>
+ <term>Greater than zero</term>
+ <description>
+ <para>This instance is greater than <paramref name="r"/>.</para>
+ <para>-or-</para>
+ <para><paramref name="r"/> is <see langword="null"/>.</para>
+ </description>
+ </item>
+ </list>
+ </returns>
+ <remarks>
+ <para>
+ <paramref name="r"/> must be an instance of <see cref="T:log4net.Core.Level"/>
+ or <see langword="null"/>; otherwise, an exception is thrown.
+ </para>
+ </remarks>
+ <exception cref="T:System.ArgumentException"><paramref name="r"/> is not a <see cref="T:log4net.Core.Level"/>.</exception>
+ </member>
+ <member name="M:log4net.Core.Level.op_GreaterThan(log4net.Core.Level,log4net.Core.Level)">
+ <summary>
+ Returns a value indicating whether a specified <see cref="T:log4net.Core.Level"/>
+ is greater than another specified <see cref="T:log4net.Core.Level"/>.
+ </summary>
+ <param name="l">A <see cref="T:log4net.Core.Level"/></param>
+ <param name="r">A <see cref="T:log4net.Core.Level"/></param>
+ <returns>
+ <c>true</c> if <paramref name="l"/> is greater than
+ <paramref name="r"/>; otherwise, <c>false</c>.
+ </returns>
+ <remarks>
+ <para>
+ Compares two levels.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.Level.op_LessThan(log4net.Core.Level,log4net.Core.Level)">
+ <summary>
+ Returns a value indicating whether a specified <see cref="T:log4net.Core.Level"/>
+ is less than another specified <see cref="T:log4net.Core.Level"/>.
+ </summary>
+ <param name="l">A <see cref="T:log4net.Core.Level"/></param>
+ <param name="r">A <see cref="T:log4net.Core.Level"/></param>
+ <returns>
+ <c>true</c> if <paramref name="l"/> is less than
+ <paramref name="r"/>; otherwise, <c>false</c>.
+ </returns>
+ <remarks>
+ <para>
+ Compares two levels.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.Level.op_GreaterThanOrEqual(log4net.Core.Level,log4net.Core.Level)">
+ <summary>
+ Returns a value indicating whether a specified <see cref="T:log4net.Core.Level"/>
+ is greater than or equal to another specified <see cref="T:log4net.Core.Level"/>.
+ </summary>
+ <param name="l">A <see cref="T:log4net.Core.Level"/></param>
+ <param name="r">A <see cref="T:log4net.Core.Level"/></param>
+ <returns>
+ <c>true</c> if <paramref name="l"/> is greater than or equal to
+ <paramref name="r"/>; otherwise, <c>false</c>.
+ </returns>
+ <remarks>
+ <para>
+ Compares two levels.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.Level.op_LessThanOrEqual(log4net.Core.Level,log4net.Core.Level)">
+ <summary>
+ Returns a value indicating whether a specified <see cref="T:log4net.Core.Level"/>
+ is less than or equal to another specified <see cref="T:log4net.Core.Level"/>.
+ </summary>
+ <param name="l">A <see cref="T:log4net.Core.Level"/></param>
+ <param name="r">A <see cref="T:log4net.Core.Level"/></param>
+ <returns>
+ <c>true</c> if <paramref name="l"/> is less than or equal to
+ <paramref name="r"/>; otherwise, <c>false</c>.
+ </returns>
+ <remarks>
+ <para>
+ Compares two levels.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.Level.op_Equality(log4net.Core.Level,log4net.Core.Level)">
+ <summary>
+ Returns a value indicating whether two specified <see cref="T:log4net.Core.Level"/>
+ objects have the same value.
+ </summary>
+ <param name="l">A <see cref="T:log4net.Core.Level"/> or <see langword="null"/>.</param>
+ <param name="r">A <see cref="T:log4net.Core.Level"/> or <see langword="null"/>.</param>
+ <returns>
+ <c>true</c> if the value of <paramref name="l"/> is the same as the
+ value of <paramref name="r"/>; otherwise, <c>false</c>.
+ </returns>
+ <remarks>
+ <para>
+ Compares two levels.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.Level.op_Inequality(log4net.Core.Level,log4net.Core.Level)">
+ <summary>
+ Returns a value indicating whether two specified <see cref="T:log4net.Core.Level"/>
+ objects have different values.
+ </summary>
+ <param name="l">A <see cref="T:log4net.Core.Level"/> or <see langword="null"/>.</param>
+ <param name="r">A <see cref="T:log4net.Core.Level"/> or <see langword="null"/>.</param>
+ <returns>
+ <c>true</c> if the value of <paramref name="l"/> is different from
+ the value of <paramref name="r"/>; otherwise, <c>false</c>.
+ </returns>
+ <remarks>
+ <para>
+ Compares two levels.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.Level.Compare(log4net.Core.Level,log4net.Core.Level)">
+ <summary>
+ Compares two specified <see cref="T:log4net.Core.Level"/> instances.
+ </summary>
+ <param name="l">The first <see cref="T:log4net.Core.Level"/> to compare.</param>
+ <param name="r">The second <see cref="T:log4net.Core.Level"/> to compare.</param>
+ <returns>
+ A 32-bit signed integer that indicates the relative order of the
+ two values compared. The return value has these meanings:
+ <list type="table">
+ <listheader>
+ <term>Value</term>
+ <description>Meaning</description>
+ </listheader>
+ <item>
+ <term>Less than zero</term>
+ <description><paramref name="l"/> is less than <paramref name="r"/>.</description>
+ </item>
+ <item>
+ <term>Zero</term>
+ <description><paramref name="l"/> is equal to <paramref name="r"/>.</description>
+ </item>
+ <item>
+ <term>Greater than zero</term>
+ <description><paramref name="l"/> is greater than <paramref name="r"/>.</description>
+ </item>
+ </list>
+ </returns>
+ <remarks>
+ <para>
+ Compares two levels.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Core.Level.Off">
+ <summary>
+ The <see cref="F:log4net.Core.Level.Off"/> level designates a higher level than all the rest.
+ </summary>
+ </member>
+ <member name="F:log4net.Core.Level.Emergency">
+ <summary>
+ The <see cref="F:log4net.Core.Level.Emergency"/> level designates very severe error events.
+ System unusable, emergencies.
+ </summary>
+ </member>
+ <member name="F:log4net.Core.Level.Fatal">
+ <summary>
+ The <see cref="F:log4net.Core.Level.Fatal"/> level designates very severe error events
+ that will presumably lead the application to abort.
+ </summary>
+ </member>
+ <member name="F:log4net.Core.Level.Alert">
+ <summary>
+ The <see cref="F:log4net.Core.Level.Alert"/> level designates very severe error events.
+ Take immediate action, alerts.
+ </summary>
+ </member>
+ <member name="F:log4net.Core.Level.Critical">
+ <summary>
+ The <see cref="F:log4net.Core.Level.Critical"/> level designates very severe error events.
+ Critical condition, critical.
+ </summary>
+ </member>
+ <member name="F:log4net.Core.Level.Severe">
+ <summary>
+ The <see cref="F:log4net.Core.Level.Severe"/> level designates very severe error events.
+ </summary>
+ </member>
+ <member name="F:log4net.Core.Level.Error">
+ <summary>
+ The <see cref="F:log4net.Core.Level.Error"/> level designates error events that might
+ still allow the application to continue running.
+ </summary>
+ </member>
+ <member name="F:log4net.Core.Level.Warn">
+ <summary>
+ The <see cref="F:log4net.Core.Level.Warn"/> level designates potentially harmful
+ situations.
+ </summary>
+ </member>
+ <member name="F:log4net.Core.Level.Notice">
+ <summary>
+ The <see cref="F:log4net.Core.Level.Notice"/> level designates informational messages
+ that highlight the progress of the application at the highest level.
+ </summary>
+ </member>
+ <member name="F:log4net.Core.Level.Info">
+ <summary>
+ The <see cref="F:log4net.Core.Level.Info"/> level designates informational messages that
+ highlight the progress of the application at coarse-grained level.
+ </summary>
+ </member>
+ <member name="F:log4net.Core.Level.Debug">
+ <summary>
+ The <see cref="F:log4net.Core.Level.Debug"/> level designates fine-grained informational
+ events that are most useful to debug an application.
+ </summary>
+ </member>
+ <member name="F:log4net.Core.Level.Fine">
+ <summary>
+ The <see cref="F:log4net.Core.Level.Fine"/> level designates fine-grained informational
+ events that are most useful to debug an application.
+ </summary>
+ </member>
+ <member name="F:log4net.Core.Level.Trace">
+ <summary>
+ The <see cref="F:log4net.Core.Level.Trace"/> level designates fine-grained informational
+ events that are most useful to debug an application.
+ </summary>
+ </member>
+ <member name="F:log4net.Core.Level.Finer">
+ <summary>
+ The <see cref="F:log4net.Core.Level.Finer"/> level designates fine-grained informational
+ events that are most useful to debug an application.
+ </summary>
+ </member>
+ <member name="F:log4net.Core.Level.Verbose">
+ <summary>
+ The <see cref="F:log4net.Core.Level.Verbose"/> level designates fine-grained informational
+ events that are most useful to debug an application.
+ </summary>
+ </member>
+ <member name="F:log4net.Core.Level.Finest">
+ <summary>
+ The <see cref="F:log4net.Core.Level.Finest"/> level designates fine-grained informational
+ events that are most useful to debug an application.
+ </summary>
+ </member>
+ <member name="F:log4net.Core.Level.All">
+ <summary>
+ The <see cref="F:log4net.Core.Level.All"/> level designates the lowest level possible.
+ </summary>
+ </member>
+ <member name="P:log4net.Core.Level.Name">
+ <summary>
+ Gets the name of this level.
+ </summary>
+ <value>
+ The name of this level.
+ </value>
+ <remarks>
+ <para>
+ Gets the name of this level.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Core.Level.Value">
+ <summary>
+ Gets the value of this level.
+ </summary>
+ <value>
+ The value of this level.
+ </value>
+ <remarks>
+ <para>
+ Gets the value of this level.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Core.Level.DisplayName">
+ <summary>
+ Gets the display name of this level.
+ </summary>
+ <value>
+ The display name of this level.
+ </value>
+ <remarks>
+ <para>
+ Gets the display name of this level.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Core.LevelCollection">
+ <summary>
+ A strongly-typed collection of <see cref="T:log4net.Core.Level"/> objects.
+ </summary>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="M:log4net.Core.LevelCollection.ReadOnly(log4net.Core.LevelCollection)">
+ <summary>
+ Creates a read-only wrapper for a <c>LevelCollection</c> instance.
+ </summary>
+ <param name="list">list to create a readonly wrapper arround</param>
+ <returns>
+ A <c>LevelCollection</c> wrapper that is read-only.
+ </returns>
+ </member>
+ <member name="M:log4net.Core.LevelCollection.#ctor">
+ <summary>
+ Initializes a new instance of the <c>LevelCollection</c> class
+ that is empty and has the default initial capacity.
+ </summary>
+ </member>
+ <member name="M:log4net.Core.LevelCollection.#ctor(System.Int32)">
+ <summary>
+ Initializes a new instance of the <c>LevelCollection</c> class
+ that has the specified initial capacity.
+ </summary>
+ <param name="capacity">
+ The number of elements that the new <c>LevelCollection</c> is initially capable of storing.
+ </param>
+ </member>
+ <member name="M:log4net.Core.LevelCollection.#ctor(log4net.Core.LevelCollection)">
+ <summary>
+ Initializes a new instance of the <c>LevelCollection</c> class
+ that contains elements copied from the specified <c>LevelCollection</c>.
+ </summary>
+ <param name="c">The <c>LevelCollection</c> whose elements are copied to the new collection.</param>
+ </member>
+ <member name="M:log4net.Core.LevelCollection.#ctor(log4net.Core.Level[])">
+ <summary>
+ Initializes a new instance of the <c>LevelCollection</c> class
+ that contains elements copied from the specified <see cref="T:log4net.Core.Level"/> array.
+ </summary>
+ <param name="a">The <see cref="T:log4net.Core.Level"/> array whose elements are copied to the new list.</param>
+ </member>
+ <member name="M:log4net.Core.LevelCollection.#ctor(System.Collections.ICollection)">
+ <summary>
+ Initializes a new instance of the <c>LevelCollection</c> class
+ that contains elements copied from the specified <see cref="T:log4net.Core.Level"/> collection.
+ </summary>
+ <param name="col">The <see cref="T:log4net.Core.Level"/> collection whose elements are copied to the new list.</param>
+ </member>
+ <member name="M:log4net.Core.LevelCollection.#ctor(log4net.Core.LevelCollection.Tag)">
+ <summary>
+ Allow subclasses to avoid our default constructors
+ </summary>
+ <param name="tag"></param>
+ </member>
+ <member name="M:log4net.Core.LevelCollection.CopyTo(log4net.Core.Level[])">
+ <summary>
+ Copies the entire <c>LevelCollection</c> to a one-dimensional
+ <see cref="T:log4net.Core.Level"/> array.
+ </summary>
+ <param name="array">The one-dimensional <see cref="T:log4net.Core.Level"/> array to copy to.</param>
+ </member>
+ <member name="M:log4net.Core.LevelCollection.CopyTo(log4net.Core.Level[],System.Int32)">
+ <summary>
+ Copies the entire <c>LevelCollection</c> to a one-dimensional
+ <see cref="T:log4net.Core.Level"/> array, starting at the specified index of the target array.
+ </summary>
+ <param name="array">The one-dimensional <see cref="T:log4net.Core.Level"/> array to copy to.</param>
+ <param name="start">The zero-based index in <paramref name="array"/> at which copying begins.</param>
+ </member>
+ <member name="M:log4net.Core.LevelCollection.Add(log4net.Core.Level)">
+ <summary>
+ Adds a <see cref="T:log4net.Core.Level"/> to the end of the <c>LevelCollection</c>.
+ </summary>
+ <param name="item">The <see cref="T:log4net.Core.Level"/> to be added to the end of the <c>LevelCollection</c>.</param>
+ <returns>The index at which the value has been added.</returns>
+ </member>
+ <member name="M:log4net.Core.LevelCollection.Clear">
+ <summary>
+ Removes all elements from the <c>LevelCollection</c>.
+ </summary>
+ </member>
+ <member name="M:log4net.Core.LevelCollection.Clone">
+ <summary>
+ Creates a shallow copy of the <see cref="T:log4net.Core.LevelCollection"/>.
+ </summary>
+ <returns>A new <see cref="T:log4net.Core.LevelCollection"/> with a shallow copy of the collection data.</returns>
+ </member>
+ <member name="M:log4net.Core.LevelCollection.Contains(log4net.Core.Level)">
+ <summary>
+ Determines whether a given <see cref="T:log4net.Core.Level"/> is in the <c>LevelCollection</c>.
+ </summary>
+ <param name="item">The <see cref="T:log4net.Core.Level"/> to check for.</param>
+ <returns><c>true</c> if <paramref name="item"/> is found in the <c>LevelCollection</c>; otherwise, <c>false</c>.</returns>
+ </member>
+ <member name="M:log4net.Core.LevelCollection.IndexOf(log4net.Core.Level)">
+ <summary>
+ Returns the zero-based index of the first occurrence of a <see cref="T:log4net.Core.Level"/>
+ in the <c>LevelCollection</c>.
+ </summary>
+ <param name="item">The <see cref="T:log4net.Core.Level"/> to locate in the <c>LevelCollection</c>.</param>
+ <returns>
+ The zero-based index of the first occurrence of <paramref name="item"/>
+ in the entire <c>LevelCollection</c>, if found; otherwise, -1.
+ </returns>
+ </member>
+ <member name="M:log4net.Core.LevelCollection.Insert(System.Int32,log4net.Core.Level)">
+ <summary>
+ Inserts an element into the <c>LevelCollection</c> at the specified index.
+ </summary>
+ <param name="index">The zero-based index at which <paramref name="item"/> should be inserted.</param>
+ <param name="item">The <see cref="T:log4net.Core.Level"/> to insert.</param>
+ <exception cref="T:System.ArgumentOutOfRangeException">
+ <para><paramref name="index"/> is less than zero</para>
+ <para>-or-</para>
+ <para><paramref name="index"/> is equal to or greater than <see cref="P:log4net.Core.LevelCollection.Count"/>.</para>
+ </exception>
+ </member>
+ <member name="M:log4net.Core.LevelCollection.Remove(log4net.Core.Level)">
+ <summary>
+ Removes the first occurrence of a specific <see cref="T:log4net.Core.Level"/> from the <c>LevelCollection</c>.
+ </summary>
+ <param name="item">The <see cref="T:log4net.Core.Level"/> to remove from the <c>LevelCollection</c>.</param>
+ <exception cref="T:System.ArgumentException">
+ The specified <see cref="T:log4net.Core.Level"/> was not found in the <c>LevelCollection</c>.
+ </exception>
+ </member>
+ <member name="M:log4net.Core.LevelCollection.RemoveAt(System.Int32)">
+ <summary>
+ Removes the element at the specified index of the <c>LevelCollection</c>.
+ </summary>
+ <param name="index">The zero-based index of the element to remove.</param>
+ <exception cref="T:System.ArgumentOutOfRangeException">
+ <para><paramref name="index"/> is less than zero</para>
+ <para>-or-</para>
+ <para><paramref name="index"/> is equal to or greater than <see cref="P:log4net.Core.LevelCollection.Count"/>.</para>
+ </exception>
+ </member>
+ <member name="M:log4net.Core.LevelCollection.GetEnumerator">
+ <summary>
+ Returns an enumerator that can iterate through the <c>LevelCollection</c>.
+ </summary>
+ <returns>An <see cref="T:log4net.Core.LevelCollection.Enumerator"/> for the entire <c>LevelCollection</c>.</returns>
+ </member>
+ <member name="M:log4net.Core.LevelCollection.AddRange(log4net.Core.LevelCollection)">
+ <summary>
+ Adds the elements of another <c>LevelCollection</c> to the current <c>LevelCollection</c>.
+ </summary>
+ <param name="x">The <c>LevelCollection</c> whose elements should be added to the end of the current <c>LevelCollection</c>.</param>
+ <returns>The new <see cref="P:log4net.Core.LevelCollection.Count"/> of the <c>LevelCollection</c>.</returns>
+ </member>
+ <member name="M:log4net.Core.LevelCollection.AddRange(log4net.Core.Level[])">
+ <summary>
+ Adds the elements of a <see cref="T:log4net.Core.Level"/> array to the current <c>LevelCollection</c>.
+ </summary>
+ <param name="x">The <see cref="T:log4net.Core.Level"/> array whose elements should be added to the end of the <c>LevelCollection</c>.</param>
+ <returns>The new <see cref="P:log4net.Core.LevelCollection.Count"/> of the <c>LevelCollection</c>.</returns>
+ </member>
+ <member name="M:log4net.Core.LevelCollection.AddRange(System.Collections.ICollection)">
+ <summary>
+ Adds the elements of a <see cref="T:log4net.Core.Level"/> collection to the current <c>LevelCollection</c>.
+ </summary>
+ <param name="col">The <see cref="T:log4net.Core.Level"/> collection whose elements should be added to the end of the <c>LevelCollection</c>.</param>
+ <returns>The new <see cref="P:log4net.Core.LevelCollection.Count"/> of the <c>LevelCollection</c>.</returns>
+ </member>
+ <member name="M:log4net.Core.LevelCollection.TrimToSize">
+ <summary>
+ Sets the capacity to the actual number of elements.
+ </summary>
+ </member>
+ <member name="M:log4net.Core.LevelCollection.ValidateIndex(System.Int32)">
+ <exception cref="T:System.ArgumentOutOfRangeException">
+ <para><paramref name="index"/> is less than zero</para>
+ <para>-or-</para>
+ <para><paramref name="index"/> is equal to or greater than <see cref="P:log4net.Core.LevelCollection.Count"/>.</para>
+ </exception>
+ </member>
+ <member name="M:log4net.Core.LevelCollection.ValidateIndex(System.Int32,System.Boolean)">
+ <exception cref="T:System.ArgumentOutOfRangeException">
+ <para><paramref name="index"/> is less than zero</para>
+ <para>-or-</para>
+ <para><paramref name="index"/> is equal to or greater than <see cref="P:log4net.Core.LevelCollection.Count"/>.</para>
+ </exception>
+ </member>
+ <member name="P:log4net.Core.LevelCollection.Count">
+ <summary>
+ Gets the number of elements actually contained in the <c>LevelCollection</c>.
+ </summary>
+ </member>
+ <member name="P:log4net.Core.LevelCollection.IsSynchronized">
+ <summary>
+ Gets a value indicating whether access to the collection is synchronized (thread-safe).
+ </summary>
+ <value>true if access to the ICollection is synchronized (thread-safe); otherwise, false.</value>
+ </member>
+ <member name="P:log4net.Core.LevelCollection.SyncRoot">
+ <summary>
+ Gets an object that can be used to synchronize access to the collection.
+ </summary>
+ </member>
+ <member name="P:log4net.Core.LevelCollection.Item(System.Int32)">
+ <summary>
+ Gets or sets the <see cref="T:log4net.Core.Level"/> at the specified index.
+ </summary>
+ <param name="index">The zero-based index of the element to get or set.</param>
+ <exception cref="T:System.ArgumentOutOfRangeException">
+ <para><paramref name="index"/> is less than zero</para>
+ <para>-or-</para>
+ <para><paramref name="index"/> is equal to or greater than <see cref="P:log4net.Core.LevelCollection.Count"/>.</para>
+ </exception>
+ </member>
+ <member name="P:log4net.Core.LevelCollection.IsFixedSize">
+ <summary>
+ Gets a value indicating whether the collection has a fixed size.
+ </summary>
+ <value>true if the collection has a fixed size; otherwise, false. The default is false</value>
+ </member>
+ <member name="P:log4net.Core.LevelCollection.IsReadOnly">
+ <summary>
+ Gets a value indicating whether the IList is read-only.
+ </summary>
+ <value>true if the collection is read-only; otherwise, false. The default is false</value>
+ </member>
+ <member name="P:log4net.Core.LevelCollection.Capacity">
+ <summary>
+ Gets or sets the number of elements the <c>LevelCollection</c> can contain.
+ </summary>
+ </member>
+ <member name="T:log4net.Core.LevelCollection.ILevelCollectionEnumerator">
+ <summary>
+ Supports type-safe iteration over a <see cref="T:log4net.Core.LevelCollection"/>.
+ </summary>
+ </member>
+ <member name="M:log4net.Core.LevelCollection.ILevelCollectionEnumerator.MoveNext">
+ <summary>
+ Advances the enumerator to the next element in the collection.
+ </summary>
+ <returns>
+ <c>true</c> if the enumerator was successfully advanced to the next element;
+ <c>false</c> if the enumerator has passed the end of the collection.
+ </returns>
+ <exception cref="T:System.InvalidOperationException">
+ The collection was modified after the enumerator was created.
+ </exception>
+ </member>
+ <member name="M:log4net.Core.LevelCollection.ILevelCollectionEnumerator.Reset">
+ <summary>
+ Sets the enumerator to its initial position, before the first element in the collection.
+ </summary>
+ </member>
+ <member name="P:log4net.Core.LevelCollection.ILevelCollectionEnumerator.Current">
+ <summary>
+ Gets the current element in the collection.
+ </summary>
+ </member>
+ <member name="T:log4net.Core.LevelCollection.Tag">
+ <summary>
+ Type visible only to our subclasses
+ Used to access protected constructor
+ </summary>
+ </member>
+ <member name="F:log4net.Core.LevelCollection.Tag.Default">
+ <summary>
+ A value
+ </summary>
+ </member>
+ <member name="T:log4net.Core.LevelCollection.Enumerator">
+ <summary>
+ Supports simple iteration over a <see cref="T:log4net.Core.LevelCollection"/>.
+ </summary>
+ </member>
+ <member name="M:log4net.Core.LevelCollection.Enumerator.#ctor(log4net.Core.LevelCollection)">
+ <summary>
+ Initializes a new instance of the <c>Enumerator</c> class.
+ </summary>
+ <param name="tc"></param>
+ </member>
+ <member name="M:log4net.Core.LevelCollection.Enumerator.MoveNext">
+ <summary>
+ Advances the enumerator to the next element in the collection.
+ </summary>
+ <returns>
+ <c>true</c> if the enumerator was successfully advanced to the next element;
+ <c>false</c> if the enumerator has passed the end of the collection.
+ </returns>
+ <exception cref="T:System.InvalidOperationException">
+ The collection was modified after the enumerator was created.
+ </exception>
+ </member>
+ <member name="M:log4net.Core.LevelCollection.Enumerator.Reset">
+ <summary>
+ Sets the enumerator to its initial position, before the first element in the collection.
+ </summary>
+ </member>
+ <member name="P:log4net.Core.LevelCollection.Enumerator.Current">
+ <summary>
+ Gets the current element in the collection.
+ </summary>
+ </member>
+ <member name="T:log4net.Core.LevelEvaluator">
+ <summary>
+ An evaluator that triggers at a threshold level
+ </summary>
+ <remarks>
+ <para>
+ This evaluator will trigger if the level of the event
+ passed to <see cref="M:log4net.Core.LevelEvaluator.IsTriggeringEvent(log4net.Core.LoggingEvent)"/>
+ is equal to or greater than the <see cref="P:log4net.Core.LevelEvaluator.Threshold"/>
+ level.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="F:log4net.Core.LevelEvaluator.m_threshold">
+ <summary>
+ The threshold for triggering
+ </summary>
+ </member>
+ <member name="M:log4net.Core.LevelEvaluator.#ctor">
+ <summary>
+ Create a new evaluator using the <see cref="F:log4net.Core.Level.Off"/> threshold.
+ </summary>
+ <remarks>
+ <para>
+ Create a new evaluator using the <see cref="F:log4net.Core.Level.Off"/> threshold.
+ </para>
+ <para>
+ This evaluator will trigger if the level of the event
+ passed to <see cref="M:log4net.Core.LevelEvaluator.IsTriggeringEvent(log4net.Core.LoggingEvent)"/>
+ is equal to or greater than the <see cref="P:log4net.Core.LevelEvaluator.Threshold"/>
+ level.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LevelEvaluator.#ctor(log4net.Core.Level)">
+ <summary>
+ Create a new evaluator using the specified <see cref="T:log4net.Core.Level"/> threshold.
+ </summary>
+ <param name="threshold">the threshold to trigger at</param>
+ <remarks>
+ <para>
+ Create a new evaluator using the specified <see cref="T:log4net.Core.Level"/> threshold.
+ </para>
+ <para>
+ This evaluator will trigger if the level of the event
+ passed to <see cref="M:log4net.Core.LevelEvaluator.IsTriggeringEvent(log4net.Core.LoggingEvent)"/>
+ is equal to or greater than the <see cref="P:log4net.Core.LevelEvaluator.Threshold"/>
+ level.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LevelEvaluator.IsTriggeringEvent(log4net.Core.LoggingEvent)">
+ <summary>
+ Is this <paramref name="loggingEvent"/> the triggering event?
+ </summary>
+ <param name="loggingEvent">The event to check</param>
+ <returns>This method returns <c>true</c>, if the event level
+ is equal or higher than the <see cref="P:log4net.Core.LevelEvaluator.Threshold"/>.
+ Otherwise it returns <c>false</c></returns>
+ <remarks>
+ <para>
+ This evaluator will trigger if the level of the event
+ passed to <see cref="M:log4net.Core.LevelEvaluator.IsTriggeringEvent(log4net.Core.LoggingEvent)"/>
+ is equal to or greater than the <see cref="P:log4net.Core.LevelEvaluator.Threshold"/>
+ level.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Core.LevelEvaluator.Threshold">
+ <summary>
+ the threshold to trigger at
+ </summary>
+ <value>
+ The <see cref="T:log4net.Core.Level"/> that will cause this evaluator to trigger
+ </value>
+ <remarks>
+ <para>
+ This evaluator will trigger if the level of the event
+ passed to <see cref="M:log4net.Core.LevelEvaluator.IsTriggeringEvent(log4net.Core.LoggingEvent)"/>
+ is equal to or greater than the <see cref="P:log4net.Core.LevelEvaluator.Threshold"/>
+ level.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Core.LevelMap">
+ <summary>
+ Mapping between string name and Level object
+ </summary>
+ <remarks>
+ <para>
+ Mapping between string name and <see cref="T:log4net.Core.Level"/> object.
+ This mapping is held separately for each <see cref="T:log4net.Repository.ILoggerRepository"/>.
+ The level name is case insensitive.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="F:log4net.Core.LevelMap.m_mapName2Level">
+ <summary>
+ Mapping from level name to Level object. The
+ level name is case insensitive
+ </summary>
+ </member>
+ <member name="M:log4net.Core.LevelMap.#ctor">
+ <summary>
+ Construct the level map
+ </summary>
+ <remarks>
+ <para>
+ Construct the level map.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LevelMap.Clear">
+ <summary>
+ Clear the internal maps of all levels
+ </summary>
+ <remarks>
+ <para>
+ Clear the internal maps of all levels
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LevelMap.Add(System.String,System.Int32)">
+ <summary>
+ Create a new Level and add it to the map
+ </summary>
+ <param name="name">the string to display for the Level</param>
+ <param name="value">the level value to give to the Level</param>
+ <remarks>
+ <para>
+ Create a new Level and add it to the map
+ </para>
+ </remarks>
+ <seealso cref="M:log4net.Core.LevelMap.Add(System.String,System.Int32,System.String)"/>
+ </member>
+ <member name="M:log4net.Core.LevelMap.Add(System.String,System.Int32,System.String)">
+ <summary>
+ Create a new Level and add it to the map
+ </summary>
+ <param name="name">the string to display for the Level</param>
+ <param name="value">the level value to give to the Level</param>
+ <param name="displayName">the display name to give to the Level</param>
+ <remarks>
+ <para>
+ Create a new Level and add it to the map
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LevelMap.Add(log4net.Core.Level)">
+ <summary>
+ Add a Level to the map
+ </summary>
+ <param name="level">the Level to add</param>
+ <remarks>
+ <para>
+ Add a Level to the map
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LevelMap.LookupWithDefault(log4net.Core.Level)">
+ <summary>
+ Lookup a named level from the map
+ </summary>
+ <param name="defaultLevel">the name of the level to lookup is taken from this level.
+ If the level is not set on the map then this level is added</param>
+ <returns>the level in the map with the name specified</returns>
+ <remarks>
+ <para>
+ Lookup a named level from the map. The name of the level to lookup is taken
+ from the <see cref="P:log4net.Core.Level.Name"/> property of the <paramref name="defaultLevel"/>
+ argument.
+ </para>
+ <para>
+ If no level with the specified name is found then the
+ <paramref name="defaultLevel"/> argument is added to the level map
+ and returned.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Core.LevelMap.Item(System.String)">
+ <summary>
+ Lookup a <see cref="T:log4net.Core.Level"/> by name
+ </summary>
+ <param name="name">The name of the Level to lookup</param>
+ <returns>a Level from the map with the name specified</returns>
+ <remarks>
+ <para>
+ Returns the <see cref="T:log4net.Core.Level"/> from the
+ map with the name specified. If the no level is
+ found then <c>null</c> is returned.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Core.LevelMap.AllLevels">
+ <summary>
+ Return all possible levels as a list of Level objects.
+ </summary>
+ <returns>all possible levels as a list of Level objects</returns>
+ <remarks>
+ <para>
+ Return all possible levels as a list of Level objects.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Core.LocationInfo">
+ <summary>
+ The internal representation of caller location information.
+ </summary>
+ <remarks>
+ <para>
+ This class uses the <c>System.Diagnostics.StackTrace</c> class to generate
+ a call stack. The caller's information is then extracted from this stack.
+ </para>
+ <para>
+ The <c>System.Diagnostics.StackTrace</c> class is not supported on the
+ .NET Compact Framework 1.0 therefore caller location information is not
+ available on that framework.
+ </para>
+ <para>
+ The <c>System.Diagnostics.StackTrace</c> class has this to say about Release builds:
+ </para>
+ <para>
+ "StackTrace information will be most informative with Debug build configurations.
+ By default, Debug builds include debug symbols, while Release builds do not. The
+ debug symbols contain most of the file, method name, line number, and column
+ information used in constructing StackFrame and StackTrace objects. StackTrace
+ might not report as many method calls as expected, due to code transformations
+ that occur during optimization."
+ </para>
+ <para>
+ This means that in a Release build the caller information may be incomplete or may
+ not exist at all! Therefore caller location information cannot be relied upon in a Release build.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="F:log4net.Core.LocationInfo.NA">
+ <summary>
+ When location information is not available the constant
+ <c>NA</c> is returned. Current value of this string
+ constant is <b>?</b>.
+ </summary>
+ </member>
+ <member name="M:log4net.Core.LocationInfo.#ctor(System.Type)">
+ <summary>
+ Constructor
+ </summary>
+ <param name="callerStackBoundaryDeclaringType">The declaring type of the method that is
+ the stack boundary into the logging system for this call.</param>
+ <remarks>
+ <para>
+ Initializes a new instance of the <see cref="T:log4net.Core.LocationInfo"/>
+ class based on the current thread.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LocationInfo.#ctor(System.String,System.String,System.String,System.String)">
+ <summary>
+ Constructor
+ </summary>
+ <param name="className">The fully qualified class name.</param>
+ <param name="methodName">The method name.</param>
+ <param name="fileName">The file name.</param>
+ <param name="lineNumber">The line number of the method within the file.</param>
+ <remarks>
+ <para>
+ Initializes a new instance of the <see cref="T:log4net.Core.LocationInfo"/>
+ class with the specified data.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Core.LocationInfo.ClassName">
+ <summary>
+ Gets the fully qualified class name of the caller making the logging
+ request.
+ </summary>
+ <value>
+ The fully qualified class name of the caller making the logging
+ request.
+ </value>
+ <remarks>
+ <para>
+ Gets the fully qualified class name of the caller making the logging
+ request.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Core.LocationInfo.FileName">
+ <summary>
+ Gets the file name of the caller.
+ </summary>
+ <value>
+ The file name of the caller.
+ </value>
+ <remarks>
+ <para>
+ Gets the file name of the caller.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Core.LocationInfo.LineNumber">
+ <summary>
+ Gets the line number of the caller.
+ </summary>
+ <value>
+ The line number of the caller.
+ </value>
+ <remarks>
+ <para>
+ Gets the line number of the caller.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Core.LocationInfo.MethodName">
+ <summary>
+ Gets the method name of the caller.
+ </summary>
+ <value>
+ The method name of the caller.
+ </value>
+ <remarks>
+ <para>
+ Gets the method name of the caller.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Core.LocationInfo.FullInfo">
+ <summary>
+ Gets all available caller information
+ </summary>
+ <value>
+ All available caller information, in the format
+ <c>fully.qualified.classname.of.caller.methodName(Filename:line)</c>
+ </value>
+ <remarks>
+ <para>
+ Gets all available caller information, in the format
+ <c>fully.qualified.classname.of.caller.methodName(Filename:line)</c>
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Core.LoggerManager">
+ <summary>
+ Static manager that controls the creation of repositories
+ </summary>
+ <remarks>
+ <para>
+ Static manager that controls the creation of repositories
+ </para>
+ <para>
+ This class is used by the wrapper managers (e.g. <see cref="T:log4net.LogManager"/>)
+ to provide access to the <see cref="T:log4net.Core.ILogger"/> objects.
+ </para>
+ <para>
+ This manager also holds the <see cref="T:log4net.Core.IRepositorySelector"/> that is used to
+ lookup and create repositories. The selector can be set either programmatically using
+ the <see cref="P:log4net.Core.LoggerManager.RepositorySelector"/> property, or by setting the <c>log4net.RepositorySelector</c>
+ AppSetting in the applications config file to the fully qualified type name of the
+ selector to use.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="M:log4net.Core.LoggerManager.#ctor">
+ <summary>
+ Private constructor to prevent instances. Only static methods should be used.
+ </summary>
+ <remarks>
+ <para>
+ Private constructor to prevent instances. Only static methods should be used.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LoggerManager.#cctor">
+ <summary>
+ Hook the shutdown event
+ </summary>
+ <remarks>
+ <para>
+ On the full .NET runtime, the static constructor hooks up the
+ <c>AppDomain.ProcessExit</c> and <c>AppDomain.DomainUnload</c>> events.
+ These are used to shutdown the log4net system as the application exits.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LoggerManager.RegisterAppDomainEvents">
+ <summary>
+ Register for ProcessExit and DomainUnload events on the AppDomain
+ </summary>
+ <remarks>
+ <para>
+ This needs to be in a separate method because the events make
+ a LinkDemand for the ControlAppDomain SecurityPermission. Because
+ this is a LinkDemand it is demanded at JIT time. Therefore we cannot
+ catch the exception in the method itself, we have to catch it in the
+ caller.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LoggerManager.GetLoggerRepository(System.String)">
+ <summary>
+ Return the default <see cref="T:log4net.Repository.ILoggerRepository"/> instance.
+ </summary>
+ <param name="repository">the repository to lookup in</param>
+ <returns>Return the default <see cref="T:log4net.Repository.ILoggerRepository"/> instance</returns>
+ <remarks>
+ <para>
+ Gets the <see cref="T:log4net.Repository.ILoggerRepository"/> for the repository specified
+ by the <paramref name="repository"/> argument.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LoggerManager.GetLoggerRepository(System.Reflection.Assembly)">
+ <summary>
+ Returns the default <see cref="T:log4net.Repository.ILoggerRepository"/> instance.
+ </summary>
+ <param name="repositoryAssembly">The assembly to use to lookup the repository.</param>
+ <returns>The default <see cref="T:log4net.Repository.ILoggerRepository"/> instance.</returns>
+ </member>
+ <member name="M:log4net.Core.LoggerManager.GetRepository(System.String)">
+ <summary>
+ Return the default <see cref="T:log4net.Repository.ILoggerRepository"/> instance.
+ </summary>
+ <param name="repository">the repository to lookup in</param>
+ <returns>Return the default <see cref="T:log4net.Repository.ILoggerRepository"/> instance</returns>
+ <remarks>
+ <para>
+ Gets the <see cref="T:log4net.Repository.ILoggerRepository"/> for the repository specified
+ by the <paramref name="repository"/> argument.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LoggerManager.GetRepository(System.Reflection.Assembly)">
+ <summary>
+ Returns the default <see cref="T:log4net.Repository.ILoggerRepository"/> instance.
+ </summary>
+ <param name="repositoryAssembly">The assembly to use to lookup the repository.</param>
+ <returns>The default <see cref="T:log4net.Repository.ILoggerRepository"/> instance.</returns>
+ <remarks>
+ <para>
+ Returns the default <see cref="T:log4net.Repository.ILoggerRepository"/> instance.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LoggerManager.Exists(System.String,System.String)">
+ <summary>
+ Returns the named logger if it exists.
+ </summary>
+ <param name="repository">The repository to lookup in.</param>
+ <param name="name">The fully qualified logger name to look for.</param>
+ <returns>
+ The logger found, or <c>null</c> if the named logger does not exist in the
+ specified repository.
+ </returns>
+ <remarks>
+ <para>
+ If the named logger exists (in the specified repository) then it
+ returns a reference to the logger, otherwise it returns
+ <c>null</c>.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LoggerManager.Exists(System.Reflection.Assembly,System.String)">
+ <summary>
+ Returns the named logger if it exists.
+ </summary>
+ <param name="repositoryAssembly">The assembly to use to lookup the repository.</param>
+ <param name="name">The fully qualified logger name to look for.</param>
+ <returns>
+ The logger found, or <c>null</c> if the named logger does not exist in the
+ specified assembly's repository.
+ </returns>
+ <remarks>
+ <para>
+ If the named logger exists (in the specified assembly's repository) then it
+ returns a reference to the logger, otherwise it returns
+ <c>null</c>.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LoggerManager.GetCurrentLoggers(System.String)">
+ <summary>
+ Returns all the currently defined loggers in the specified repository.
+ </summary>
+ <param name="repository">The repository to lookup in.</param>
+ <returns>All the defined loggers.</returns>
+ <remarks>
+ <para>
+ The root logger is <b>not</b> included in the returned array.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LoggerManager.GetCurrentLoggers(System.Reflection.Assembly)">
+ <summary>
+ Returns all the currently defined loggers in the specified assembly's repository.
+ </summary>
+ <param name="repositoryAssembly">The assembly to use to lookup the repository.</param>
+ <returns>All the defined loggers.</returns>
+ <remarks>
+ <para>
+ The root logger is <b>not</b> included in the returned array.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LoggerManager.GetLogger(System.String,System.String)">
+ <summary>
+ Retrieves or creates a named logger.
+ </summary>
+ <param name="repository">The repository to lookup in.</param>
+ <param name="name">The name of the logger to retrieve.</param>
+ <returns>The logger with the name specified.</returns>
+ <remarks>
+ <para>
+ Retrieves a logger named as the <paramref name="name"/>
+ parameter. If the named logger already exists, then the
+ existing instance will be returned. Otherwise, a new instance is
+ created.
+ </para>
+ <para>
+ By default, loggers do not have a set level but inherit
+ it from the hierarchy. This is one of the central features of
+ log4net.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LoggerManager.GetLogger(System.Reflection.Assembly,System.String)">
+ <summary>
+ Retrieves or creates a named logger.
+ </summary>
+ <param name="repositoryAssembly">The assembly to use to lookup the repository.</param>
+ <param name="name">The name of the logger to retrieve.</param>
+ <returns>The logger with the name specified.</returns>
+ <remarks>
+ <para>
+ Retrieves a logger named as the <paramref name="name"/>
+ parameter. If the named logger already exists, then the
+ existing instance will be returned. Otherwise, a new instance is
+ created.
+ </para>
+ <para>
+ By default, loggers do not have a set level but inherit
+ it from the hierarchy. This is one of the central features of
+ log4net.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LoggerManager.GetLogger(System.String,System.Type)">
+ <summary>
+ Shorthand for <see cref="M:log4net.LogManager.GetLogger(System.String)"/>.
+ </summary>
+ <param name="repository">The repository to lookup in.</param>
+ <param name="type">The <paramref name="type"/> of which the fullname will be used as the name of the logger to retrieve.</param>
+ <returns>The logger with the name specified.</returns>
+ <remarks>
+ <para>
+ Gets the logger for the fully qualified name of the type specified.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LoggerManager.GetLogger(System.Reflection.Assembly,System.Type)">
+ <summary>
+ Shorthand for <see cref="M:log4net.LogManager.GetLogger(System.String)"/>.
+ </summary>
+ <param name="repositoryAssembly">the assembly to use to lookup the repository</param>
+ <param name="type">The <paramref name="type"/> of which the fullname will be used as the name of the logger to retrieve.</param>
+ <returns>The logger with the name specified.</returns>
+ <remarks>
+ <para>
+ Gets the logger for the fully qualified name of the type specified.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LoggerManager.Shutdown">
+ <summary>
+ Shuts down the log4net system.
+ </summary>
+ <remarks>
+ <para>
+ Calling this method will <b>safely</b> close and remove all
+ appenders in all the loggers including root contained in all the
+ default repositories.
+ </para>
+ <para>
+ Some appenders need to be closed before the application exists.
+ Otherwise, pending logging events might be lost.
+ </para>
+ <para>
+ The <c>shutdown</c> method is careful to close nested
+ appenders before closing regular appenders. This is allows
+ configurations where a regular appender is attached to a logger
+ and again to a nested appender.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LoggerManager.ShutdownRepository(System.String)">
+ <summary>
+ Shuts down the repository for the repository specified.
+ </summary>
+ <param name="repository">The repository to shutdown.</param>
+ <remarks>
+ <para>
+ Calling this method will <b>safely</b> close and remove all
+ appenders in all the loggers including root contained in the
+ repository for the <paramref name="repository"/> specified.
+ </para>
+ <para>
+ Some appenders need to be closed before the application exists.
+ Otherwise, pending logging events might be lost.
+ </para>
+ <para>
+ The <c>shutdown</c> method is careful to close nested
+ appenders before closing regular appenders. This is allows
+ configurations where a regular appender is attached to a logger
+ and again to a nested appender.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LoggerManager.ShutdownRepository(System.Reflection.Assembly)">
+ <summary>
+ Shuts down the repository for the repository specified.
+ </summary>
+ <param name="repositoryAssembly">The assembly to use to lookup the repository.</param>
+ <remarks>
+ <para>
+ Calling this method will <b>safely</b> close and remove all
+ appenders in all the loggers including root contained in the
+ repository for the repository. The repository is looked up using
+ the <paramref name="repositoryAssembly"/> specified.
+ </para>
+ <para>
+ Some appenders need to be closed before the application exists.
+ Otherwise, pending logging events might be lost.
+ </para>
+ <para>
+ The <c>shutdown</c> method is careful to close nested
+ appenders before closing regular appenders. This is allows
+ configurations where a regular appender is attached to a logger
+ and again to a nested appender.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LoggerManager.ResetConfiguration(System.String)">
+ <summary>
+ Resets all values contained in this repository instance to their defaults.
+ </summary>
+ <param name="repository">The repository to reset.</param>
+ <remarks>
+ <para>
+ Resets all values contained in the repository instance to their
+ defaults. This removes all appenders from all loggers, sets
+ the level of all non-root loggers to <c>null</c>,
+ sets their additivity flag to <c>true</c> and sets the level
+ of the root logger to <see cref="F:log4net.Core.Level.Debug"/>. Moreover,
+ message disabling is set its default "off" value.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LoggerManager.ResetConfiguration(System.Reflection.Assembly)">
+ <summary>
+ Resets all values contained in this repository instance to their defaults.
+ </summary>
+ <param name="repositoryAssembly">The assembly to use to lookup the repository to reset.</param>
+ <remarks>
+ <para>
+ Resets all values contained in the repository instance to their
+ defaults. This removes all appenders from all loggers, sets
+ the level of all non-root loggers to <c>null</c>,
+ sets their additivity flag to <c>true</c> and sets the level
+ of the root logger to <see cref="F:log4net.Core.Level.Debug"/>. Moreover,
+ message disabling is set its default "off" value.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LoggerManager.CreateDomain(System.String)">
+ <summary>
+ Creates a repository with the specified name.
+ </summary>
+ <param name="repository">The name of the repository, this must be unique amongst repositories.</param>
+ <returns>The <see cref="T:log4net.Repository.ILoggerRepository"/> created for the repository.</returns>
+ <remarks>
+ <para>
+ <b>CreateDomain is obsolete. Use CreateRepository instead of CreateDomain.</b>
+ </para>
+ <para>
+ Creates the default type of <see cref="T:log4net.Repository.ILoggerRepository"/> which is a
+ <see cref="T:log4net.Repository.Hierarchy.Hierarchy"/> object.
+ </para>
+ <para>
+ The <paramref name="repository"/> name must be unique. Repositories cannot be redefined.
+ An <see cref="T:System.Exception"/> will be thrown if the repository already exists.
+ </para>
+ </remarks>
+ <exception cref="T:log4net.Core.LogException">The specified repository already exists.</exception>
+ </member>
+ <member name="M:log4net.Core.LoggerManager.CreateRepository(System.String)">
+ <summary>
+ Creates a repository with the specified name.
+ </summary>
+ <param name="repository">The name of the repository, this must be unique amongst repositories.</param>
+ <returns>The <see cref="T:log4net.Repository.ILoggerRepository"/> created for the repository.</returns>
+ <remarks>
+ <para>
+ Creates the default type of <see cref="T:log4net.Repository.ILoggerRepository"/> which is a
+ <see cref="T:log4net.Repository.Hierarchy.Hierarchy"/> object.
+ </para>
+ <para>
+ The <paramref name="repository"/> name must be unique. Repositories cannot be redefined.
+ An <see cref="T:System.Exception"/> will be thrown if the repository already exists.
+ </para>
+ </remarks>
+ <exception cref="T:log4net.Core.LogException">The specified repository already exists.</exception>
+ </member>
+ <member name="M:log4net.Core.LoggerManager.CreateDomain(System.String,System.Type)">
+ <summary>
+ Creates a repository with the specified name and repository type.
+ </summary>
+ <param name="repository">The name of the repository, this must be unique to the repository.</param>
+ <param name="repositoryType">A <see cref="T:System.Type"/> that implements <see cref="T:log4net.Repository.ILoggerRepository"/>
+ and has a no arg constructor. An instance of this type will be created to act
+ as the <see cref="T:log4net.Repository.ILoggerRepository"/> for the repository specified.</param>
+ <returns>The <see cref="T:log4net.Repository.ILoggerRepository"/> created for the repository.</returns>
+ <remarks>
+ <para>
+ <b>CreateDomain is obsolete. Use CreateRepository instead of CreateDomain.</b>
+ </para>
+ <para>
+ The <paramref name="repository"/> name must be unique. Repositories cannot be redefined.
+ An Exception will be thrown if the repository already exists.
+ </para>
+ </remarks>
+ <exception cref="T:log4net.Core.LogException">The specified repository already exists.</exception>
+ </member>
+ <member name="M:log4net.Core.LoggerManager.CreateRepository(System.String,System.Type)">
+ <summary>
+ Creates a repository with the specified name and repository type.
+ </summary>
+ <param name="repository">The name of the repository, this must be unique to the repository.</param>
+ <param name="repositoryType">A <see cref="T:System.Type"/> that implements <see cref="T:log4net.Repository.ILoggerRepository"/>
+ and has a no arg constructor. An instance of this type will be created to act
+ as the <see cref="T:log4net.Repository.ILoggerRepository"/> for the repository specified.</param>
+ <returns>The <see cref="T:log4net.Repository.ILoggerRepository"/> created for the repository.</returns>
+ <remarks>
+ <para>
+ The <paramref name="repository"/> name must be unique. Repositories cannot be redefined.
+ An Exception will be thrown if the repository already exists.
+ </para>
+ </remarks>
+ <exception cref="T:log4net.Core.LogException">The specified repository already exists.</exception>
+ </member>
+ <member name="M:log4net.Core.LoggerManager.CreateDomain(System.Reflection.Assembly,System.Type)">
+ <summary>
+ Creates a repository for the specified assembly and repository type.
+ </summary>
+ <param name="repositoryAssembly">The assembly to use to get the name of the repository.</param>
+ <param name="repositoryType">A <see cref="T:System.Type"/> that implements <see cref="T:log4net.Repository.ILoggerRepository"/>
+ and has a no arg constructor. An instance of this type will be created to act
+ as the <see cref="T:log4net.Repository.ILoggerRepository"/> for the repository specified.</param>
+ <returns>The <see cref="T:log4net.Repository.ILoggerRepository"/> created for the repository.</returns>
+ <remarks>
+ <para>
+ <b>CreateDomain is obsolete. Use CreateRepository instead of CreateDomain.</b>
+ </para>
+ <para>
+ The <see cref="T:log4net.Repository.ILoggerRepository"/> created will be associated with the repository
+ specified such that a call to <see cref="M:log4net.Core.LoggerManager.GetRepository(System.Reflection.Assembly)"/> with the
+ same assembly specified will return the same repository instance.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LoggerManager.CreateRepository(System.Reflection.Assembly,System.Type)">
+ <summary>
+ Creates a repository for the specified assembly and repository type.
+ </summary>
+ <param name="repositoryAssembly">The assembly to use to get the name of the repository.</param>
+ <param name="repositoryType">A <see cref="T:System.Type"/> that implements <see cref="T:log4net.Repository.ILoggerRepository"/>
+ and has a no arg constructor. An instance of this type will be created to act
+ as the <see cref="T:log4net.Repository.ILoggerRepository"/> for the repository specified.</param>
+ <returns>The <see cref="T:log4net.Repository.ILoggerRepository"/> created for the repository.</returns>
+ <remarks>
+ <para>
+ The <see cref="T:log4net.Repository.ILoggerRepository"/> created will be associated with the repository
+ specified such that a call to <see cref="M:log4net.Core.LoggerManager.GetRepository(System.Reflection.Assembly)"/> with the
+ same assembly specified will return the same repository instance.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LoggerManager.GetAllRepositories">
+ <summary>
+ Gets an array of all currently defined repositories.
+ </summary>
+ <returns>An array of all the known <see cref="T:log4net.Repository.ILoggerRepository"/> objects.</returns>
+ <remarks>
+ <para>
+ Gets an array of all currently defined repositories.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LoggerManager.GetVersionInfo">
+ <summary>
+ Internal method to get pertinent version info.
+ </summary>
+ <returns>A string of version info.</returns>
+ </member>
+ <member name="M:log4net.Core.LoggerManager.OnDomainUnload(System.Object,System.EventArgs)">
+ <summary>
+ Called when the <see cref="E:System.AppDomain.DomainUnload"/> event fires
+ </summary>
+ <param name="sender">the <see cref="T:System.AppDomain"/> that is exiting</param>
+ <param name="e">null</param>
+ <remarks>
+ <para>
+ Called when the <see cref="E:System.AppDomain.DomainUnload"/> event fires.
+ </para>
+ <para>
+ When the event is triggered the log4net system is <see cref="M:log4net.Core.LoggerManager.Shutdown"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LoggerManager.OnProcessExit(System.Object,System.EventArgs)">
+ <summary>
+ Called when the <see cref="E:System.AppDomain.ProcessExit"/> event fires
+ </summary>
+ <param name="sender">the <see cref="T:System.AppDomain"/> that is exiting</param>
+ <param name="e">null</param>
+ <remarks>
+ <para>
+ Called when the <see cref="E:System.AppDomain.ProcessExit"/> event fires.
+ </para>
+ <para>
+ When the event is triggered the log4net system is <see cref="M:log4net.Core.LoggerManager.Shutdown"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Core.LoggerManager.s_repositorySelector">
+ <summary>
+ Initialize the default repository selector
+ </summary>
+ </member>
+ <member name="P:log4net.Core.LoggerManager.RepositorySelector">
+ <summary>
+ Gets or sets the repository selector used by the <see cref="T:log4net.LogManager"/>.
+ </summary>
+ <value>
+ The repository selector used by the <see cref="T:log4net.LogManager"/>.
+ </value>
+ <remarks>
+ <para>
+ The repository selector (<see cref="T:log4net.Core.IRepositorySelector"/>) is used by
+ the <see cref="T:log4net.LogManager"/> to create and select repositories
+ (<see cref="T:log4net.Repository.ILoggerRepository"/>).
+ </para>
+ <para>
+ The caller to <see cref="T:log4net.LogManager"/> supplies either a string name
+ or an assembly (if not supplied the assembly is inferred using
+ <see cref="M:System.Reflection.Assembly.GetCallingAssembly"/>).
+ </para>
+ <para>
+ This context is used by the selector to lookup a specific repository.
+ </para>
+ <para>
+ For the full .NET Framework, the default repository is <c>DefaultRepositorySelector</c>;
+ for the .NET Compact Framework <c>CompactRepositorySelector</c> is the default
+ repository.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Core.LoggerWrapperImpl">
+ <summary>
+ Implementation of the <see cref="T:log4net.Core.ILoggerWrapper"/> interface.
+ </summary>
+ <remarks>
+ <para>
+ This class should be used as the base for all wrapper implementations.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="M:log4net.Core.LoggerWrapperImpl.#ctor(log4net.Core.ILogger)">
+ <summary>
+ Constructs a new wrapper for the specified logger.
+ </summary>
+ <param name="logger">The logger to wrap.</param>
+ <remarks>
+ <para>
+ Constructs a new wrapper for the specified logger.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Core.LoggerWrapperImpl.m_logger">
+ <summary>
+ The logger that this object is wrapping
+ </summary>
+ </member>
+ <member name="P:log4net.Core.LoggerWrapperImpl.Logger">
+ <summary>
+ Gets the implementation behind this wrapper object.
+ </summary>
+ <value>
+ The <see cref="T:log4net.Core.ILogger"/> object that this object is implementing.
+ </value>
+ <remarks>
+ <para>
+ The <c>Logger</c> object may not be the same object as this object
+ because of logger decorators.
+ </para>
+ <para>
+ This gets the actual underlying objects that is used to process
+ the log events.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Core.LoggingEventData">
+ <summary>
+ Portable data structure used by <see cref="T:log4net.Core.LoggingEvent"/>
+ </summary>
+ <remarks>
+ <para>
+ Portable data structure used by <see cref="T:log4net.Core.LoggingEvent"/>
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="F:log4net.Core.LoggingEventData.LoggerName">
+ <summary>
+ The logger name.
+ </summary>
+ <remarks>
+ <para>
+ The logger name.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Core.LoggingEventData.Level">
+ <summary>
+ Level of logging event.
+ </summary>
+ <remarks>
+ <para>
+ Level of logging event. Level cannot be Serializable
+ because it is a flyweight. Due to its special serialization it
+ cannot be declared final either.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Core.LoggingEventData.Message">
+ <summary>
+ The application supplied message.
+ </summary>
+ <remarks>
+ <para>
+ The application supplied message of logging event.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Core.LoggingEventData.ThreadName">
+ <summary>
+ The name of thread
+ </summary>
+ <remarks>
+ <para>
+ The name of thread in which this logging event was generated
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Core.LoggingEventData.TimeStamp">
+ <summary>
+ The time the event was logged
+ </summary>
+ <remarks>
+ <para>
+ The TimeStamp is stored in the local time zone for this computer.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Core.LoggingEventData.LocationInfo">
+ <summary>
+ Location information for the caller.
+ </summary>
+ <remarks>
+ <para>
+ Location information for the caller.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Core.LoggingEventData.UserName">
+ <summary>
+ String representation of the user
+ </summary>
+ <remarks>
+ <para>
+ String representation of the user's windows name,
+ like DOMAIN\username
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Core.LoggingEventData.Identity">
+ <summary>
+ String representation of the identity.
+ </summary>
+ <remarks>
+ <para>
+ String representation of the current thread's principal identity.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Core.LoggingEventData.ExceptionString">
+ <summary>
+ The string representation of the exception
+ </summary>
+ <remarks>
+ <para>
+ The string representation of the exception
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Core.LoggingEventData.Domain">
+ <summary>
+ String representation of the AppDomain.
+ </summary>
+ <remarks>
+ <para>
+ String representation of the AppDomain.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Core.LoggingEventData.Properties">
+ <summary>
+ Additional event specific properties
+ </summary>
+ <remarks>
+ <para>
+ A logger or an appender may attach additional
+ properties to specific events. These properties
+ have a string key and an object value.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Core.FixFlags">
+ <summary>
+ Flags passed to the <see cref="P:log4net.Core.LoggingEvent.Fix"/> property
+ </summary>
+ <remarks>
+ <para>
+ Flags passed to the <see cref="P:log4net.Core.LoggingEvent.Fix"/> property
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="F:log4net.Core.FixFlags.Mdc">
+ <summary>
+ Fix the MDC
+ </summary>
+ </member>
+ <member name="F:log4net.Core.FixFlags.Ndc">
+ <summary>
+ Fix the NDC
+ </summary>
+ </member>
+ <member name="F:log4net.Core.FixFlags.Message">
+ <summary>
+ Fix the rendered message
+ </summary>
+ </member>
+ <member name="F:log4net.Core.FixFlags.ThreadName">
+ <summary>
+ Fix the thread name
+ </summary>
+ </member>
+ <member name="F:log4net.Core.FixFlags.LocationInfo">
+ <summary>
+ Fix the callers location information
+ </summary>
+ <remarks>
+ CAUTION: Very slow to generate
+ </remarks>
+ </member>
+ <member name="F:log4net.Core.FixFlags.UserName">
+ <summary>
+ Fix the callers windows user name
+ </summary>
+ <remarks>
+ CAUTION: Slow to generate
+ </remarks>
+ </member>
+ <member name="F:log4net.Core.FixFlags.Domain">
+ <summary>
+ Fix the domain friendly name
+ </summary>
+ </member>
+ <member name="F:log4net.Core.FixFlags.Identity">
+ <summary>
+ Fix the callers principal name
+ </summary>
+ <remarks>
+ CAUTION: May be slow to generate
+ </remarks>
+ </member>
+ <member name="F:log4net.Core.FixFlags.Exception">
+ <summary>
+ Fix the exception text
+ </summary>
+ </member>
+ <member name="F:log4net.Core.FixFlags.Properties">
+ <summary>
+ Fix the event properties
+ </summary>
+ </member>
+ <member name="F:log4net.Core.FixFlags.None">
+ <summary>
+ No fields fixed
+ </summary>
+ </member>
+ <member name="F:log4net.Core.FixFlags.All">
+ <summary>
+ All fields fixed
+ </summary>
+ </member>
+ <member name="F:log4net.Core.FixFlags.Partial">
+ <summary>
+ Partial fields fixed
+ </summary>
+ <remarks>
+ <para>
+ This set of partial fields gives good performance. The following fields are fixed:
+ </para>
+ <list type="bullet">
+ <item><description><see cref="F:log4net.Core.FixFlags.Message"/></description></item>
+ <item><description><see cref="F:log4net.Core.FixFlags.ThreadName"/></description></item>
+ <item><description><see cref="F:log4net.Core.FixFlags.Exception"/></description></item>
+ <item><description><see cref="F:log4net.Core.FixFlags.Domain"/></description></item>
+ <item><description><see cref="F:log4net.Core.FixFlags.Properties"/></description></item>
+ </list>
+ </remarks>
+ </member>
+ <member name="T:log4net.Core.LoggingEvent">
+ <summary>
+ The internal representation of logging events.
+ </summary>
+ <remarks>
+ <para>
+ When an affirmative decision is made to log then a
+ <see cref="T:log4net.Core.LoggingEvent"/> instance is created. This instance
+ is passed around to the different log4net components.
+ </para>
+ <para>
+ This class is of concern to those wishing to extend log4net.
+ </para>
+ <para>
+ Some of the values in instances of <see cref="T:log4net.Core.LoggingEvent"/>
+ are considered volatile, that is the values are correct at the
+ time the event is delivered to appenders, but will not be consistent
+ at any time afterwards. If an event is to be stored and then processed
+ at a later time these volatile values must be fixed by calling
+ <see cref="M:log4net.Core.LoggingEvent.FixVolatileData"/>. There is a performance penalty
+ for incurred by calling <see cref="M:log4net.Core.LoggingEvent.FixVolatileData"/> but it
+ is essential to maintaining data consistency.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ <author>Douglas de la Torre</author>
+ <author>Daniel Cazzulino</author>
+ </member>
+ <member name="F:log4net.Core.LoggingEvent.HostNameProperty">
+ <summary>
+ The key into the Properties map for the host name value.
+ </summary>
+ </member>
+ <member name="F:log4net.Core.LoggingEvent.IdentityProperty">
+ <summary>
+ The key into the Properties map for the thread identity value.
+ </summary>
+ </member>
+ <member name="F:log4net.Core.LoggingEvent.UserNameProperty">
+ <summary>
+ The key into the Properties map for the user name value.
+ </summary>
+ </member>
+ <member name="M:log4net.Core.LoggingEvent.#ctor(System.Type,log4net.Repository.ILoggerRepository,System.String,log4net.Core.Level,System.Object,System.Exception)">
+ <summary>
+ Initializes a new instance of the <see cref="T:log4net.Core.LoggingEvent"/> class
+ from the supplied parameters.
+ </summary>
+ <param name="callerStackBoundaryDeclaringType">The declaring type of the method that is
+ the stack boundary into the logging system for this call.</param>
+ <param name="repository">The repository this event is logged in.</param>
+ <param name="loggerName">The name of the logger of this event.</param>
+ <param name="level">The level of this event.</param>
+ <param name="message">The message of this event.</param>
+ <param name="exception">The exception for this event.</param>
+ <remarks>
+ <para>
+ Except <see cref="P:log4net.Core.LoggingEvent.TimeStamp"/>, <see cref="P:log4net.Core.LoggingEvent.Level"/> and <see cref="P:log4net.Core.LoggingEvent.LoggerName"/>,
+ all fields of <c>LoggingEvent</c> are filled when actually needed. Call
+ <see cref="M:log4net.Core.LoggingEvent.FixVolatileData"/> to cache all data locally
+ to prevent inconsistencies.
+ </para>
+ <para>This method is called by the log4net framework
+ to create a logging event.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LoggingEvent.#ctor(System.Type,log4net.Repository.ILoggerRepository,log4net.Core.LoggingEventData,log4net.Core.FixFlags)">
+ <summary>
+ Initializes a new instance of the <see cref="T:log4net.Core.LoggingEvent"/> class
+ using specific data.
+ </summary>
+ <param name="callerStackBoundaryDeclaringType">The declaring type of the method that is
+ the stack boundary into the logging system for this call.</param>
+ <param name="repository">The repository this event is logged in.</param>
+ <param name="data">Data used to initialize the logging event.</param>
+ <param name="fixedData">The fields in the <paranref name="data"/> struct that have already been fixed.</param>
+ <remarks>
+ <para>
+ This constructor is provided to allow a <see cref="T:log4net.Core.LoggingEvent"/>
+ to be created independently of the log4net framework. This can
+ be useful if you require a custom serialization scheme.
+ </para>
+ <para>
+ Use the <see cref="M:log4net.Core.LoggingEvent.GetLoggingEventData(log4net.Core.FixFlags)"/> method to obtain an
+ instance of the <see cref="T:log4net.Core.LoggingEventData"/> class.
+ </para>
+ <para>
+ The <paramref name="fixedData"/> parameter should be used to specify which fields in the
+ <paramref name="data"/> struct have been preset. Fields not specified in the <paramref name="fixedData"/>
+ will be captured from the environment if requested or fixed.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LoggingEvent.#ctor(System.Type,log4net.Repository.ILoggerRepository,log4net.Core.LoggingEventData)">
+ <summary>
+ Initializes a new instance of the <see cref="T:log4net.Core.LoggingEvent"/> class
+ using specific data.
+ </summary>
+ <param name="callerStackBoundaryDeclaringType">The declaring type of the method that is
+ the stack boundary into the logging system for this call.</param>
+ <param name="repository">The repository this event is logged in.</param>
+ <param name="data">Data used to initialize the logging event.</param>
+ <remarks>
+ <para>
+ This constructor is provided to allow a <see cref="T:log4net.Core.LoggingEvent"/>
+ to be created independently of the log4net framework. This can
+ be useful if you require a custom serialization scheme.
+ </para>
+ <para>
+ Use the <see cref="M:log4net.Core.LoggingEvent.GetLoggingEventData(log4net.Core.FixFlags)"/> method to obtain an
+ instance of the <see cref="T:log4net.Core.LoggingEventData"/> class.
+ </para>
+ <para>
+ This constructor sets this objects <see cref="P:log4net.Core.LoggingEvent.Fix"/> flags to <see cref="F:log4net.Core.FixFlags.All"/>,
+ this assumes that all the data relating to this event is passed in via the <paramref name="data"/>
+ parameter and no other data should be captured from the environment.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LoggingEvent.#ctor(log4net.Core.LoggingEventData)">
+ <summary>
+ Initializes a new instance of the <see cref="T:log4net.Core.LoggingEvent"/> class
+ using specific data.
+ </summary>
+ <param name="data">Data used to initialize the logging event.</param>
+ <remarks>
+ <para>
+ This constructor is provided to allow a <see cref="T:log4net.Core.LoggingEvent"/>
+ to be created independently of the log4net framework. This can
+ be useful if you require a custom serialization scheme.
+ </para>
+ <para>
+ Use the <see cref="M:log4net.Core.LoggingEvent.GetLoggingEventData(log4net.Core.FixFlags)"/> method to obtain an
+ instance of the <see cref="T:log4net.Core.LoggingEventData"/> class.
+ </para>
+ <para>
+ This constructor sets this objects <see cref="P:log4net.Core.LoggingEvent.Fix"/> flags to <see cref="F:log4net.Core.FixFlags.All"/>,
+ this assumes that all the data relating to this event is passed in via the <paramref name="data"/>
+ parameter and no other data should be captured from the environment.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LoggingEvent.#ctor(System.Runtime.Serialization.SerializationInfo,System.Runtime.Serialization.StreamingContext)">
+ <summary>
+ Serialization constructor
+ </summary>
+ <param name="info">The <see cref="T:System.Runtime.Serialization.SerializationInfo"/> that holds the serialized object data.</param>
+ <param name="context">The <see cref="T:System.Runtime.Serialization.StreamingContext"/> that contains contextual information about the source or destination.</param>
+ <remarks>
+ <para>
+ Initializes a new instance of the <see cref="T:log4net.Core.LoggingEvent"/> class
+ with serialized data.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LoggingEvent.EnsureRepository(log4net.Repository.ILoggerRepository)">
+ <summary>
+ Ensure that the repository is set.
+ </summary>
+ <param name="repository">the value for the repository</param>
+ </member>
+ <member name="M:log4net.Core.LoggingEvent.WriteRenderedMessage(System.IO.TextWriter)">
+ <summary>
+ Write the rendered message to a TextWriter
+ </summary>
+ <param name="writer">the writer to write the message to</param>
+ <remarks>
+ <para>
+ Unlike the <see cref="P:log4net.Core.LoggingEvent.RenderedMessage"/> property this method
+ does store the message data in the internal cache. Therefore
+ if called only once this method should be faster than the
+ <see cref="P:log4net.Core.LoggingEvent.RenderedMessage"/> property, however if the message is
+ to be accessed multiple times then the property will be more efficient.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LoggingEvent.GetObjectData(System.Runtime.Serialization.SerializationInfo,System.Runtime.Serialization.StreamingContext)">
+ <summary>
+ Serializes this object into the <see cref="T:System.Runtime.Serialization.SerializationInfo"/> provided.
+ </summary>
+ <param name="info">The <see cref="T:System.Runtime.Serialization.SerializationInfo"/> to populate with data.</param>
+ <param name="context">The destination for this serialization.</param>
+ <remarks>
+ <para>
+ The data in this event must be fixed before it can be serialized.
+ </para>
+ <para>
+ The <see cref="M:log4net.Core.LoggingEvent.FixVolatileData"/> method must be called during the
+ <see cref="M:log4net.Appender.IAppender.DoAppend(log4net.Core.LoggingEvent)"/> method call if this event
+ is to be used outside that method.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LoggingEvent.GetLoggingEventData">
+ <summary>
+ Gets the portable data for this <see cref="T:log4net.Core.LoggingEvent"/>.
+ </summary>
+ <returns>The <see cref="T:log4net.Core.LoggingEventData"/> for this event.</returns>
+ <remarks>
+ <para>
+ A new <see cref="T:log4net.Core.LoggingEvent"/> can be constructed using a
+ <see cref="T:log4net.Core.LoggingEventData"/> instance.
+ </para>
+ <para>
+ Does a <see cref="F:log4net.Core.FixFlags.Partial"/> fix of the data
+ in the logging event before returning the event data.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LoggingEvent.GetLoggingEventData(log4net.Core.FixFlags)">
+ <summary>
+ Gets the portable data for this <see cref="T:log4net.Core.LoggingEvent"/>.
+ </summary>
+ <param name="fixFlags">The set of data to ensure is fixed in the LoggingEventData</param>
+ <returns>The <see cref="T:log4net.Core.LoggingEventData"/> for this event.</returns>
+ <remarks>
+ <para>
+ A new <see cref="T:log4net.Core.LoggingEvent"/> can be constructed using a
+ <see cref="T:log4net.Core.LoggingEventData"/> instance.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LoggingEvent.GetExceptionStrRep">
+ <summary>
+ Returns this event's exception's rendered using the
+ <see cref="P:log4net.Repository.ILoggerRepository.RendererMap"/>.
+ </summary>
+ <returns>
+ This event's exception's rendered using the <see cref="P:log4net.Repository.ILoggerRepository.RendererMap"/>.
+ </returns>
+ <remarks>
+ <para>
+ <b>Obsolete. Use <see cref="M:log4net.Core.LoggingEvent.GetExceptionString"/> instead.</b>
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LoggingEvent.GetExceptionString">
+ <summary>
+ Returns this event's exception's rendered using the
+ <see cref="P:log4net.Repository.ILoggerRepository.RendererMap"/>.
+ </summary>
+ <returns>
+ This event's exception's rendered using the <see cref="P:log4net.Repository.ILoggerRepository.RendererMap"/>.
+ </returns>
+ <remarks>
+ <para>
+ Returns this event's exception's rendered using the
+ <see cref="P:log4net.Repository.ILoggerRepository.RendererMap"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LoggingEvent.FixVolatileData">
+ <summary>
+ Fix instance fields that hold volatile data.
+ </summary>
+ <remarks>
+ <para>
+ Some of the values in instances of <see cref="T:log4net.Core.LoggingEvent"/>
+ are considered volatile, that is the values are correct at the
+ time the event is delivered to appenders, but will not be consistent
+ at any time afterwards. If an event is to be stored and then processed
+ at a later time these volatile values must be fixed by calling
+ <see cref="M:log4net.Core.LoggingEvent.FixVolatileData"/>. There is a performance penalty
+ incurred by calling <see cref="M:log4net.Core.LoggingEvent.FixVolatileData"/> but it
+ is essential to maintaining data consistency.
+ </para>
+ <para>
+ Calling <see cref="M:log4net.Core.LoggingEvent.FixVolatileData"/> is equivalent to
+ calling <see cref="M:log4net.Core.LoggingEvent.FixVolatileData(System.Boolean)"/> passing the parameter
+ <c>false</c>.
+ </para>
+ <para>
+ See <see cref="M:log4net.Core.LoggingEvent.FixVolatileData(System.Boolean)"/> for more
+ information.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LoggingEvent.FixVolatileData(System.Boolean)">
+ <summary>
+ Fixes instance fields that hold volatile data.
+ </summary>
+ <param name="fastButLoose">Set to <c>true</c> to not fix data that takes a long time to fix.</param>
+ <remarks>
+ <para>
+ Some of the values in instances of <see cref="T:log4net.Core.LoggingEvent"/>
+ are considered volatile, that is the values are correct at the
+ time the event is delivered to appenders, but will not be consistent
+ at any time afterwards. If an event is to be stored and then processed
+ at a later time these volatile values must be fixed by calling
+ <see cref="M:log4net.Core.LoggingEvent.FixVolatileData"/>. There is a performance penalty
+ for incurred by calling <see cref="M:log4net.Core.LoggingEvent.FixVolatileData"/> but it
+ is essential to maintaining data consistency.
+ </para>
+ <para>
+ The <paramref name="fastButLoose"/> param controls the data that
+ is fixed. Some of the data that can be fixed takes a long time to
+ generate, therefore if you do not require those settings to be fixed
+ they can be ignored by setting the <paramref name="fastButLoose"/> param
+ to <c>true</c>. This setting will ignore the <see cref="P:log4net.Core.LoggingEvent.LocationInformation"/>
+ and <see cref="P:log4net.Core.LoggingEvent.UserName"/> settings.
+ </para>
+ <para>
+ Set <paramref name="fastButLoose"/> to <c>false</c> to ensure that all
+ settings are fixed.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LoggingEvent.FixVolatileData(log4net.Core.FixFlags)">
+ <summary>
+ Fix the fields specified by the <see cref="T:log4net.Core.FixFlags"/> parameter
+ </summary>
+ <param name="flags">the fields to fix</param>
+ <remarks>
+ <para>
+ Only fields specified in the <paramref name="flags"/> will be fixed.
+ Fields will not be fixed if they have previously been fixed.
+ It is not possible to 'unfix' a field.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LoggingEvent.LookupProperty(System.String)">
+ <summary>
+ Lookup a composite property in this event
+ </summary>
+ <param name="key">the key for the property to lookup</param>
+ <returns>the value for the property</returns>
+ <remarks>
+ <para>
+ This event has composite properties that combine together properties from
+ several different contexts in the following order:
+ <list type="definition">
+ <item>
+ <term>this events properties</term>
+ <description>
+ This event has <see cref="P:log4net.Core.LoggingEvent.Properties"/> that can be set. These
+ properties are specific to this event only.
+ </description>
+ </item>
+ <item>
+ <term>the thread properties</term>
+ <description>
+ The <see cref="P:log4net.ThreadContext.Properties"/> that are set on the current
+ thread. These properties are shared by all events logged on this thread.
+ </description>
+ </item>
+ <item>
+ <term>the global properties</term>
+ <description>
+ The <see cref="P:log4net.GlobalContext.Properties"/> that are set globally. These
+ properties are shared by all the threads in the AppDomain.
+ </description>
+ </item>
+ </list>
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LoggingEvent.GetProperties">
+ <summary>
+ Get all the composite properties in this event
+ </summary>
+ <returns>the <see cref="T:log4net.Util.PropertiesDictionary"/> containing all the properties</returns>
+ <remarks>
+ <para>
+ See <see cref="M:log4net.Core.LoggingEvent.LookupProperty(System.String)"/> for details of the composite properties
+ stored by the event.
+ </para>
+ <para>
+ This method returns a single <see cref="T:log4net.Util.PropertiesDictionary"/> containing all the
+ properties defined for this event.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Core.LoggingEvent.m_data">
+ <summary>
+ The internal logging event data.
+ </summary>
+ </member>
+ <member name="F:log4net.Core.LoggingEvent.m_compositeProperties">
+ <summary>
+ The internal logging event data.
+ </summary>
+ </member>
+ <member name="F:log4net.Core.LoggingEvent.m_eventProperties">
+ <summary>
+ The internal logging event data.
+ </summary>
+ </member>
+ <member name="F:log4net.Core.LoggingEvent.m_callerStackBoundaryDeclaringType">
+ <summary>
+ The fully qualified Type of the calling
+ logger class in the stack frame (i.e. the declaring type of the method).
+ </summary>
+ </member>
+ <member name="F:log4net.Core.LoggingEvent.m_message">
+ <summary>
+ The application supplied message of logging event.
+ </summary>
+ </member>
+ <member name="F:log4net.Core.LoggingEvent.m_thrownException">
+ <summary>
+ The exception that was thrown.
+ </summary>
+ <remarks>
+ This is not serialized. The string representation
+ is serialized instead.
+ </remarks>
+ </member>
+ <member name="F:log4net.Core.LoggingEvent.m_repository">
+ <summary>
+ The repository that generated the logging event
+ </summary>
+ <remarks>
+ This is not serialized.
+ </remarks>
+ </member>
+ <member name="F:log4net.Core.LoggingEvent.m_fixFlags">
+ <summary>
+ The fix state for this event
+ </summary>
+ <remarks>
+ These flags indicate which fields have been fixed.
+ Not serialized.
+ </remarks>
+ </member>
+ <member name="F:log4net.Core.LoggingEvent.m_cacheUpdatable">
+ <summary>
+ Indicated that the internal cache is updateable (ie not fixed)
+ </summary>
+ <remarks>
+ This is a seperate flag to m_fixFlags as it allows incrementel fixing and simpler
+ changes in the caching strategy.
+ </remarks>
+ </member>
+ <member name="P:log4net.Core.LoggingEvent.StartTime">
+ <summary>
+ Gets the time when the current process started.
+ </summary>
+ <value>
+ This is the time when this process started.
+ </value>
+ <remarks>
+ <para>
+ The TimeStamp is stored in the local time zone for this computer.
+ </para>
+ <para>
+ Tries to get the start time for the current process.
+ Failing that it returns the time of the first call to
+ this property.
+ </para>
+ <para>
+ Note that AppDomains may be loaded and unloaded within the
+ same process without the process terminating and therefore
+ without the process start time being reset.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Core.LoggingEvent.Level">
+ <summary>
+ Gets the <see cref="P:log4net.Core.LoggingEvent.Level"/> of the logging event.
+ </summary>
+ <value>
+ The <see cref="P:log4net.Core.LoggingEvent.Level"/> of the logging event.
+ </value>
+ <remarks>
+ <para>
+ Gets the <see cref="P:log4net.Core.LoggingEvent.Level"/> of the logging event.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Core.LoggingEvent.TimeStamp">
+ <summary>
+ Gets the time of the logging event.
+ </summary>
+ <value>
+ The time of the logging event.
+ </value>
+ <remarks>
+ <para>
+ The TimeStamp is stored in the local time zone for this computer.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Core.LoggingEvent.LoggerName">
+ <summary>
+ Gets the name of the logger that logged the event.
+ </summary>
+ <value>
+ The name of the logger that logged the event.
+ </value>
+ <remarks>
+ <para>
+ Gets the name of the logger that logged the event.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Core.LoggingEvent.LocationInformation">
+ <summary>
+ Gets the location information for this logging event.
+ </summary>
+ <value>
+ The location information for this logging event.
+ </value>
+ <remarks>
+ <para>
+ The collected information is cached for future use.
+ </para>
+ <para>
+ See the <see cref="T:log4net.Core.LocationInfo"/> class for more information on
+ supported frameworks and the different behavior in Debug and
+ Release builds.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Core.LoggingEvent.MessageObject">
+ <summary>
+ Gets the message object used to initialize this event.
+ </summary>
+ <value>
+ The message object used to initialize this event.
+ </value>
+ <remarks>
+ <para>
+ Gets the message object used to initialize this event.
+ Note that this event may not have a valid message object.
+ If the event is serialized the message object will not
+ be transferred. To get the text of the message the
+ <see cref="P:log4net.Core.LoggingEvent.RenderedMessage"/> property must be used
+ not this property.
+ </para>
+ <para>
+ If there is no defined message object for this event then
+ null will be returned.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Core.LoggingEvent.ExceptionObject">
+ <summary>
+ Gets the exception object used to initialize this event.
+ </summary>
+ <value>
+ The exception object used to initialize this event.
+ </value>
+ <remarks>
+ <para>
+ Gets the exception object used to initialize this event.
+ Note that this event may not have a valid exception object.
+ If the event is serialized the exception object will not
+ be transferred. To get the text of the exception the
+ <see cref="M:log4net.Core.LoggingEvent.GetExceptionString"/> method must be used
+ not this property.
+ </para>
+ <para>
+ If there is no defined exception object for this event then
+ null will be returned.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Core.LoggingEvent.Repository">
+ <summary>
+ The <see cref="T:log4net.Repository.ILoggerRepository"/> that this event was created in.
+ </summary>
+ <remarks>
+ <para>
+ The <see cref="T:log4net.Repository.ILoggerRepository"/> that this event was created in.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Core.LoggingEvent.RenderedMessage">
+ <summary>
+ Gets the message, rendered through the <see cref="P:log4net.Repository.ILoggerRepository.RendererMap"/>.
+ </summary>
+ <value>
+ The message rendered through the <see cref="P:log4net.Repository.ILoggerRepository.RendererMap"/>.
+ </value>
+ <remarks>
+ <para>
+ The collected information is cached for future use.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Core.LoggingEvent.ThreadName">
+ <summary>
+ Gets the name of the current thread.
+ </summary>
+ <value>
+ The name of the current thread, or the thread ID when
+ the name is not available.
+ </value>
+ <remarks>
+ <para>
+ The collected information is cached for future use.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Core.LoggingEvent.UserName">
+ <summary>
+ Gets the name of the current user.
+ </summary>
+ <value>
+ The name of the current user, or <c>NOT AVAILABLE</c> when the
+ underlying runtime has no support for retrieving the name of the
+ current user.
+ </value>
+ <remarks>
+ <para>
+ Calls <c>WindowsIdentity.GetCurrent().Name</c> to get the name of
+ the current windows user.
+ </para>
+ <para>
+ To improve performance, we could cache the string representation of
+ the name, and reuse that as long as the identity stayed constant.
+ Once the identity changed, we would need to re-assign and re-render
+ the string.
+ </para>
+ <para>
+ However, the <c>WindowsIdentity.GetCurrent()</c> call seems to
+ return different objects every time, so the current implementation
+ doesn't do this type of caching.
+ </para>
+ <para>
+ Timing for these operations:
+ </para>
+ <list type="table">
+ <listheader>
+ <term>Method</term>
+ <description>Results</description>
+ </listheader>
+ <item>
+ <term><c>WindowsIdentity.GetCurrent()</c></term>
+ <description>10000 loops, 00:00:00.2031250 seconds</description>
+ </item>
+ <item>
+ <term><c>WindowsIdentity.GetCurrent().Name</c></term>
+ <description>10000 loops, 00:00:08.0468750 seconds</description>
+ </item>
+ </list>
+ <para>
+ This means we could speed things up almost 40 times by caching the
+ value of the <c>WindowsIdentity.GetCurrent().Name</c> property, since
+ this takes (8.04-0.20) = 7.84375 seconds.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Core.LoggingEvent.Identity">
+ <summary>
+ Gets the identity of the current thread principal.
+ </summary>
+ <value>
+ The string name of the identity of the current thread principal.
+ </value>
+ <remarks>
+ <para>
+ Calls <c>System.Threading.Thread.CurrentPrincipal.Identity.Name</c> to get
+ the name of the current thread principal.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Core.LoggingEvent.Domain">
+ <summary>
+ Gets the AppDomain friendly name.
+ </summary>
+ <value>
+ The AppDomain friendly name.
+ </value>
+ <remarks>
+ <para>
+ Gets the AppDomain friendly name.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Core.LoggingEvent.Properties">
+ <summary>
+ Additional event specific properties.
+ </summary>
+ <value>
+ Additional event specific properties.
+ </value>
+ <remarks>
+ <para>
+ A logger or an appender may attach additional
+ properties to specific events. These properties
+ have a string key and an object value.
+ </para>
+ <para>
+ This property is for events that have been added directly to
+ this event. The aggregate properties (which include these
+ event properties) can be retrieved using <see cref="M:log4net.Core.LoggingEvent.LookupProperty(System.String)"/>
+ and <see cref="M:log4net.Core.LoggingEvent.GetProperties"/>.
+ </para>
+ <para>
+ Once the properties have been fixed <see cref="P:log4net.Core.LoggingEvent.Fix"/> this property
+ returns the combined cached properties. This ensures that updates to
+ this property are always reflected in the underlying storage. When
+ returning the combined properties there may be more keys in the
+ Dictionary than expected.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Core.LoggingEvent.Fix">
+ <summary>
+ The fixed fields in this event
+ </summary>
+ <value>
+ The set of fields that are fixed in this event
+ </value>
+ <remarks>
+ <para>
+ Fields will not be fixed if they have previously been fixed.
+ It is not possible to 'unfix' a field.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Core.LogImpl">
+ <summary>
+ Implementation of <see cref="T:log4net.ILog"/> wrapper interface.
+ </summary>
+ <remarks>
+ <para>
+ This implementation of the <see cref="T:log4net.ILog"/> interface
+ forwards to the <see cref="T:log4net.Core.ILogger"/> held by the base class.
+ </para>
+ <para>
+ This logger has methods to allow the caller to log at the following
+ levels:
+ </para>
+ <list type="definition">
+ <item>
+ <term>DEBUG</term>
+ <description>
+ The <see cref="M:log4net.Core.LogImpl.Debug(System.Object)"/> and <see cref="M:log4net.Core.LogImpl.DebugFormat(System.String,System.Object[])"/> methods log messages
+ at the <c>DEBUG</c> level. That is the level with that name defined in the
+ repositories <see cref="P:log4net.Repository.ILoggerRepository.LevelMap"/>. The default value
+ for this level is <see cref="F:log4net.Core.Level.Debug"/>. The <see cref="P:log4net.Core.LogImpl.IsDebugEnabled"/>
+ property tests if this level is enabled for logging.
+ </description>
+ </item>
+ <item>
+ <term>INFO</term>
+ <description>
+ The <see cref="M:log4net.Core.LogImpl.Info(System.Object)"/> and <see cref="M:log4net.Core.LogImpl.InfoFormat(System.String,System.Object[])"/> methods log messages
+ at the <c>INFO</c> level. That is the level with that name defined in the
+ repositories <see cref="P:log4net.Repository.ILoggerRepository.LevelMap"/>. The default value
+ for this level is <see cref="F:log4net.Core.Level.Info"/>. The <see cref="P:log4net.Core.LogImpl.IsInfoEnabled"/>
+ property tests if this level is enabled for logging.
+ </description>
+ </item>
+ <item>
+ <term>WARN</term>
+ <description>
+ The <see cref="M:log4net.Core.LogImpl.Warn(System.Object)"/> and <see cref="M:log4net.Core.LogImpl.WarnFormat(System.String,System.Object[])"/> methods log messages
+ at the <c>WARN</c> level. That is the level with that name defined in the
+ repositories <see cref="P:log4net.Repository.ILoggerRepository.LevelMap"/>. The default value
+ for this level is <see cref="F:log4net.Core.Level.Warn"/>. The <see cref="P:log4net.Core.LogImpl.IsWarnEnabled"/>
+ property tests if this level is enabled for logging.
+ </description>
+ </item>
+ <item>
+ <term>ERROR</term>
+ <description>
+ The <see cref="M:log4net.Core.LogImpl.Error(System.Object)"/> and <see cref="M:log4net.Core.LogImpl.ErrorFormat(System.String,System.Object[])"/> methods log messages
+ at the <c>ERROR</c> level. That is the level with that name defined in the
+ repositories <see cref="P:log4net.Repository.ILoggerRepository.LevelMap"/>. The default value
+ for this level is <see cref="F:log4net.Core.Level.Error"/>. The <see cref="P:log4net.Core.LogImpl.IsErrorEnabled"/>
+ property tests if this level is enabled for logging.
+ </description>
+ </item>
+ <item>
+ <term>FATAL</term>
+ <description>
+ The <see cref="M:log4net.Core.LogImpl.Fatal(System.Object)"/> and <see cref="M:log4net.Core.LogImpl.FatalFormat(System.String,System.Object[])"/> methods log messages
+ at the <c>FATAL</c> level. That is the level with that name defined in the
+ repositories <see cref="P:log4net.Repository.ILoggerRepository.LevelMap"/>. The default value
+ for this level is <see cref="F:log4net.Core.Level.Fatal"/>. The <see cref="P:log4net.Core.LogImpl.IsFatalEnabled"/>
+ property tests if this level is enabled for logging.
+ </description>
+ </item>
+ </list>
+ <para>
+ The values for these levels and their semantic meanings can be changed by
+ configuring the <see cref="P:log4net.Repository.ILoggerRepository.LevelMap"/> for the repository.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="T:log4net.ILog">
+ <summary>
+ The ILog interface is use by application to log messages into
+ the log4net framework.
+ </summary>
+ <remarks>
+ <para>
+ Use the <see cref="T:log4net.LogManager"/> to obtain logger instances
+ that implement this interface. The <see cref="M:log4net.LogManager.GetLogger(System.Reflection.Assembly,System.Type)"/>
+ static method is used to get logger instances.
+ </para>
+ <para>
+ This class contains methods for logging at different levels and also
+ has properties for determining if those logging levels are
+ enabled in the current configuration.
+ </para>
+ <para>
+ This interface can be implemented in different ways. This documentation
+ specifies reasonable behavior that a caller can expect from the actual
+ implementation, however different implementations reserve the right to
+ do things differently.
+ </para>
+ </remarks>
+ <example>Simple example of logging messages
+ <code lang="C#">
+ ILog log = LogManager.GetLogger("application-log");
+
+ log.Info("Application Start");
+ log.Debug("This is a debug message");
+
+ if (log.IsDebugEnabled)
+ {
+ log.Debug("This is another debug message");
+ }
+ </code>
+ </example>
+ <seealso cref="T:log4net.LogManager"/>
+ <seealso cref="M:log4net.LogManager.GetLogger(System.Reflection.Assembly,System.Type)"/>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="M:log4net.ILog.Debug(System.Object)">
+ <overloads>Log a message object with the <see cref="F:log4net.Core.Level.Debug"/> level.</overloads>
+ <summary>
+ Log a message object with the <see cref="F:log4net.Core.Level.Debug"/> level.
+ </summary>
+ <param name="message">The message object to log.</param>
+ <remarks>
+ <para>
+ This method first checks if this logger is <c>DEBUG</c>
+ enabled by comparing the level of this logger with the
+ <see cref="F:log4net.Core.Level.Debug"/> level. If this logger is
+ <c>DEBUG</c> enabled, then it converts the message object
+ (passed as parameter) to a string by invoking the appropriate
+ <see cref="T:log4net.ObjectRenderer.IObjectRenderer"/>. It then
+ proceeds to call all the registered appenders in this logger
+ and also higher in the hierarchy depending on the value of
+ the additivity flag.
+ </para>
+ <para><b>WARNING</b> Note that passing an <see cref="T:System.Exception"/>
+ to this method will print the name of the <see cref="T:System.Exception"/>
+ but no stack trace. To print a stack trace use the
+ <see cref="M:log4net.ILog.Debug(System.Object,System.Exception)"/> form instead.
+ </para>
+ </remarks>
+ <seealso cref="M:log4net.ILog.Debug(System.Object,System.Exception)"/>
+ <seealso cref="P:log4net.ILog.IsDebugEnabled"/>
+ </member>
+ <member name="M:log4net.ILog.Debug(System.Object,System.Exception)">
+ <summary>
+ Log a message object with the <see cref="F:log4net.Core.Level.Debug"/> level including
+ the stack trace of the <see cref="T:System.Exception"/> passed
+ as a parameter.
+ </summary>
+ <param name="message">The message object to log.</param>
+ <param name="exception">The exception to log, including its stack trace.</param>
+ <remarks>
+ <para>
+ See the <see cref="M:log4net.ILog.Debug(System.Object)"/> form for more detailed information.
+ </para>
+ </remarks>
+ <seealso cref="M:log4net.ILog.Debug(System.Object)"/>
+ <seealso cref="P:log4net.ILog.IsDebugEnabled"/>
+ </member>
+ <member name="M:log4net.ILog.DebugFormat(System.String,System.Object[])">
+ <overloads>Log a formatted string with the <see cref="F:log4net.Core.Level.Debug"/> level.</overloads>
+ <summary>
+ Logs a formatted message string with the <see cref="F:log4net.Core.Level.Debug"/> level.
+ </summary>
+ <param name="format">A String containing zero or more format items</param>
+ <param name="args">An Object array containing zero or more objects to format</param>
+ <remarks>
+ <para>
+ The message is formatted using the <c>String.Format</c> method. See
+ <see cref="M:System.String.Format(System.String,System.Object[])"/> for details of the syntax of the format string and the behavior
+ of the formatting.
+ </para>
+ <para>
+ This method does not take an <see cref="T:System.Exception"/> object to include in the
+ log event. To pass an <see cref="T:System.Exception"/> use one of the <see cref="M:log4net.ILog.Debug(System.Object,System.Exception)"/>
+ methods instead.
+ </para>
+ </remarks>
+ <seealso cref="M:log4net.ILog.Debug(System.Object)"/>
+ <seealso cref="P:log4net.ILog.IsDebugEnabled"/>
+ </member>
+ <member name="M:log4net.ILog.DebugFormat(System.String,System.Object)">
+ <summary>
+ Logs a formatted message string with the <see cref="F:log4net.Core.Level.Debug"/> level.
+ </summary>
+ <param name="format">A String containing zero or more format items</param>
+ <param name="arg0">An Object to format</param>
+ <remarks>
+ <para>
+ The message is formatted using the <c>String.Format</c> method. See
+ <see cref="M:System.String.Format(System.String,System.Object[])"/> for details of the syntax of the format string and the behavior
+ of the formatting.
+ </para>
+ <para>
+ This method does not take an <see cref="T:System.Exception"/> object to include in the
+ log event. To pass an <see cref="T:System.Exception"/> use one of the <see cref="M:log4net.ILog.Debug(System.Object,System.Exception)"/>
+ methods instead.
+ </para>
+ </remarks>
+ <seealso cref="M:log4net.ILog.Debug(System.Object)"/>
+ <seealso cref="P:log4net.ILog.IsDebugEnabled"/>
+ </member>
+ <member name="M:log4net.ILog.DebugFormat(System.String,System.Object,System.Object)">
+ <summary>
+ Logs a formatted message string with the <see cref="F:log4net.Core.Level.Debug"/> level.
+ </summary>
+ <param name="format">A String containing zero or more format items</param>
+ <param name="arg0">An Object to format</param>
+ <param name="arg1">An Object to format</param>
+ <remarks>
+ <para>
+ The message is formatted using the <c>String.Format</c> method. See
+ <see cref="M:System.String.Format(System.String,System.Object[])"/> for details of the syntax of the format string and the behavior
+ of the formatting.
+ </para>
+ <para>
+ This method does not take an <see cref="T:System.Exception"/> object to include in the
+ log event. To pass an <see cref="T:System.Exception"/> use one of the <see cref="M:log4net.ILog.Debug(System.Object,System.Exception)"/>
+ methods instead.
+ </para>
+ </remarks>
+ <seealso cref="M:log4net.ILog.Debug(System.Object)"/>
+ <seealso cref="P:log4net.ILog.IsDebugEnabled"/>
+ </member>
+ <member name="M:log4net.ILog.DebugFormat(System.String,System.Object,System.Object,System.Object)">
+ <summary>
+ Logs a formatted message string with the <see cref="F:log4net.Core.Level.Debug"/> level.
+ </summary>
+ <param name="format">A String containing zero or more format items</param>
+ <param name="arg0">An Object to format</param>
+ <param name="arg1">An Object to format</param>
+ <param name="arg2">An Object to format</param>
+ <remarks>
+ <para>
+ The message is formatted using the <c>String.Format</c> method. See
+ <see cref="M:System.String.Format(System.String,System.Object[])"/> for details of the syntax of the format string and the behavior
+ of the formatting.
+ </para>
+ <para>
+ This method does not take an <see cref="T:System.Exception"/> object to include in the
+ log event. To pass an <see cref="T:System.Exception"/> use one of the <see cref="M:log4net.ILog.Debug(System.Object,System.Exception)"/>
+ methods instead.
+ </para>
+ </remarks>
+ <seealso cref="M:log4net.ILog.Debug(System.Object)"/>
+ <seealso cref="P:log4net.ILog.IsDebugEnabled"/>
+ </member>
+ <member name="M:log4net.ILog.DebugFormat(System.IFormatProvider,System.String,System.Object[])">
+ <summary>
+ Logs a formatted message string with the <see cref="F:log4net.Core.Level.Debug"/> level.
+ </summary>
+ <param name="provider">An <see cref="T:System.IFormatProvider"/> that supplies culture-specific formatting information</param>
+ <param name="format">A String containing zero or more format items</param>
+ <param name="args">An Object array containing zero or more objects to format</param>
+ <remarks>
+ <para>
+ The message is formatted using the <c>String.Format</c> method. See
+ <see cref="M:System.String.Format(System.String,System.Object[])"/> for details of the syntax of the format string and the behavior
+ of the formatting.
+ </para>
+ <para>
+ This method does not take an <see cref="T:System.Exception"/> object to include in the
+ log event. To pass an <see cref="T:System.Exception"/> use one of the <see cref="M:log4net.ILog.Debug(System.Object,System.Exception)"/>
+ methods instead.
+ </para>
+ </remarks>
+ <seealso cref="M:log4net.ILog.Debug(System.Object)"/>
+ <seealso cref="P:log4net.ILog.IsDebugEnabled"/>
+ </member>
+ <member name="M:log4net.ILog.Info(System.Object)">
+ <overloads>Log a message object with the <see cref="F:log4net.Core.Level.Info"/> level.</overloads>
+ <summary>
+ Logs a message object with the <see cref="F:log4net.Core.Level.Info"/> level.
+ </summary>
+ <remarks>
+ <para>
+ This method first checks if this logger is <c>INFO</c>
+ enabled by comparing the level of this logger with the
+ <see cref="F:log4net.Core.Level.Info"/> level. If this logger is
+ <c>INFO</c> enabled, then it converts the message object
+ (passed as parameter) to a string by invoking the appropriate
+ <see cref="T:log4net.ObjectRenderer.IObjectRenderer"/>. It then
+ proceeds to call all the registered appenders in this logger
+ and also higher in the hierarchy depending on the value of the
+ additivity flag.
+ </para>
+ <para><b>WARNING</b> Note that passing an <see cref="T:System.Exception"/>
+ to this method will print the name of the <see cref="T:System.Exception"/>
+ but no stack trace. To print a stack trace use the
+ <see cref="M:log4net.ILog.Info(System.Object,System.Exception)"/> form instead.
+ </para>
+ </remarks>
+ <param name="message">The message object to log.</param>
+ <seealso cref="M:log4net.ILog.Info(System.Object,System.Exception)"/>
+ <seealso cref="P:log4net.ILog.IsInfoEnabled"/>
+ </member>
+ <member name="M:log4net.ILog.Info(System.Object,System.Exception)">
+ <summary>
+ Logs a message object with the <c>INFO</c> level including
+ the stack trace of the <see cref="T:System.Exception"/> passed
+ as a parameter.
+ </summary>
+ <param name="message">The message object to log.</param>
+ <param name="exception">The exception to log, including its stack trace.</param>
+ <remarks>
+ <para>
+ See the <see cref="M:log4net.ILog.Info(System.Object)"/> form for more detailed information.
+ </para>
+ </remarks>
+ <seealso cref="M:log4net.ILog.Info(System.Object)"/>
+ <seealso cref="P:log4net.ILog.IsInfoEnabled"/>
+ </member>
+ <member name="M:log4net.ILog.InfoFormat(System.String,System.Object[])">
+ <overloads>Log a formatted message string with the <see cref="F:log4net.Core.Level.Info"/> level.</overloads>
+ <summary>
+ Logs a formatted message string with the <see cref="F:log4net.Core.Level.Info"/> level.
+ </summary>
+ <param name="format">A String containing zero or more format items</param>
+ <param name="args">An Object array containing zero or more objects to format</param>
+ <remarks>
+ <para>
+ The message is formatted using the <c>String.Format</c> method. See
+ <see cref="M:System.String.Format(System.String,System.Object[])"/> for details of the syntax of the format string and the behavior
+ of the formatting.
+ </para>
+ <para>
+ This method does not take an <see cref="T:System.Exception"/> object to include in the
+ log event. To pass an <see cref="T:System.Exception"/> use one of the <see cref="M:log4net.ILog.Info(System.Object)"/>
+ methods instead.
+ </para>
+ </remarks>
+ <seealso cref="M:log4net.ILog.Info(System.Object,System.Exception)"/>
+ <seealso cref="P:log4net.ILog.IsInfoEnabled"/>
+ </member>
+ <member name="M:log4net.ILog.InfoFormat(System.String,System.Object)">
+ <summary>
+ Logs a formatted message string with the <see cref="F:log4net.Core.Level.Info"/> level.
+ </summary>
+ <param name="format">A String containing zero or more format items</param>
+ <param name="arg0">An Object to format</param>
+ <remarks>
+ <para>
+ The message is formatted using the <c>String.Format</c> method. See
+ <see cref="M:System.String.Format(System.String,System.Object[])"/> for details of the syntax of the format string and the behavior
+ of the formatting.
+ </para>
+ <para>
+ This method does not take an <see cref="T:System.Exception"/> object to include in the
+ log event. To pass an <see cref="T:System.Exception"/> use one of the <see cref="M:log4net.ILog.Info(System.Object,System.Exception)"/>
+ methods instead.
+ </para>
+ </remarks>
+ <seealso cref="M:log4net.ILog.Info(System.Object)"/>
+ <seealso cref="P:log4net.ILog.IsInfoEnabled"/>
+ </member>
+ <member name="M:log4net.ILog.InfoFormat(System.String,System.Object,System.Object)">
+ <summary>
+ Logs a formatted message string with the <see cref="F:log4net.Core.Level.Info"/> level.
+ </summary>
+ <param name="format">A String containing zero or more format items</param>
+ <param name="arg0">An Object to format</param>
+ <param name="arg1">An Object to format</param>
+ <remarks>
+ <para>
+ The message is formatted using the <c>String.Format</c> method. See
+ <see cref="M:System.String.Format(System.String,System.Object[])"/> for details of the syntax of the format string and the behavior
+ of the formatting.
+ </para>
+ <para>
+ This method does not take an <see cref="T:System.Exception"/> object to include in the
+ log event. To pass an <see cref="T:System.Exception"/> use one of the <see cref="M:log4net.ILog.Info(System.Object,System.Exception)"/>
+ methods instead.
+ </para>
+ </remarks>
+ <seealso cref="M:log4net.ILog.Info(System.Object)"/>
+ <seealso cref="P:log4net.ILog.IsInfoEnabled"/>
+ </member>
+ <member name="M:log4net.ILog.InfoFormat(System.String,System.Object,System.Object,System.Object)">
+ <summary>
+ Logs a formatted message string with the <see cref="F:log4net.Core.Level.Info"/> level.
+ </summary>
+ <param name="format">A String containing zero or more format items</param>
+ <param name="arg0">An Object to format</param>
+ <param name="arg1">An Object to format</param>
+ <param name="arg2">An Object to format</param>
+ <remarks>
+ <para>
+ The message is formatted using the <c>String.Format</c> method. See
+ <see cref="M:System.String.Format(System.String,System.Object[])"/> for details of the syntax of the format string and the behavior
+ of the formatting.
+ </para>
+ <para>
+ This method does not take an <see cref="T:System.Exception"/> object to include in the
+ log event. To pass an <see cref="T:System.Exception"/> use one of the <see cref="M:log4net.ILog.Info(System.Object,System.Exception)"/>
+ methods instead.
+ </para>
+ </remarks>
+ <seealso cref="M:log4net.ILog.Info(System.Object)"/>
+ <seealso cref="P:log4net.ILog.IsInfoEnabled"/>
+ </member>
+ <member name="M:log4net.ILog.InfoFormat(System.IFormatProvider,System.String,System.Object[])">
+ <summary>
+ Logs a formatted message string with the <see cref="F:log4net.Core.Level.Info"/> level.
+ </summary>
+ <param name="provider">An <see cref="T:System.IFormatProvider"/> that supplies culture-specific formatting information</param>
+ <param name="format">A String containing zero or more format items</param>
+ <param name="args">An Object array containing zero or more objects to format</param>
+ <remarks>
+ <para>
+ The message is formatted using the <c>String.Format</c> method. See
+ <see cref="M:System.String.Format(System.String,System.Object[])"/> for details of the syntax of the format string and the behavior
+ of the formatting.
+ </para>
+ <para>
+ This method does not take an <see cref="T:System.Exception"/> object to include in the
+ log event. To pass an <see cref="T:System.Exception"/> use one of the <see cref="M:log4net.ILog.Info(System.Object)"/>
+ methods instead.
+ </para>
+ </remarks>
+ <seealso cref="M:log4net.ILog.Info(System.Object,System.Exception)"/>
+ <seealso cref="P:log4net.ILog.IsInfoEnabled"/>
+ </member>
+ <member name="M:log4net.ILog.Warn(System.Object)">
+ <overloads>Log a message object with the <see cref="F:log4net.Core.Level.Warn"/> level.</overloads>
+ <summary>
+ Log a message object with the <see cref="F:log4net.Core.Level.Warn"/> level.
+ </summary>
+ <remarks>
+ <para>
+ This method first checks if this logger is <c>WARN</c>
+ enabled by comparing the level of this logger with the
+ <see cref="F:log4net.Core.Level.Warn"/> level. If this logger is
+ <c>WARN</c> enabled, then it converts the message object
+ (passed as parameter) to a string by invoking the appropriate
+ <see cref="T:log4net.ObjectRenderer.IObjectRenderer"/>. It then
+ proceeds to call all the registered appenders in this logger
+ and also higher in the hierarchy depending on the value of the
+ additivity flag.
+ </para>
+ <para><b>WARNING</b> Note that passing an <see cref="T:System.Exception"/>
+ to this method will print the name of the <see cref="T:System.Exception"/>
+ but no stack trace. To print a stack trace use the
+ <see cref="M:log4net.ILog.Warn(System.Object,System.Exception)"/> form instead.
+ </para>
+ </remarks>
+ <param name="message">The message object to log.</param>
+ <seealso cref="M:log4net.ILog.Warn(System.Object,System.Exception)"/>
+ <seealso cref="P:log4net.ILog.IsWarnEnabled"/>
+ </member>
+ <member name="M:log4net.ILog.Warn(System.Object,System.Exception)">
+ <summary>
+ Log a message object with the <see cref="F:log4net.Core.Level.Warn"/> level including
+ the stack trace of the <see cref="T:System.Exception"/> passed
+ as a parameter.
+ </summary>
+ <param name="message">The message object to log.</param>
+ <param name="exception">The exception to log, including its stack trace.</param>
+ <remarks>
+ <para>
+ See the <see cref="M:log4net.ILog.Warn(System.Object)"/> form for more detailed information.
+ </para>
+ </remarks>
+ <seealso cref="M:log4net.ILog.Warn(System.Object)"/>
+ <seealso cref="P:log4net.ILog.IsWarnEnabled"/>
+ </member>
+ <member name="M:log4net.ILog.WarnFormat(System.String,System.Object[])">
+ <overloads>Log a formatted message string with the <see cref="F:log4net.Core.Level.Warn"/> level.</overloads>
+ <summary>
+ Logs a formatted message string with the <see cref="F:log4net.Core.Level.Warn"/> level.
+ </summary>
+ <param name="format">A String containing zero or more format items</param>
+ <param name="args">An Object array containing zero or more objects to format</param>
+ <remarks>
+ <para>
+ The message is formatted using the <c>String.Format</c> method. See
+ <see cref="M:System.String.Format(System.String,System.Object[])"/> for details of the syntax of the format string and the behavior
+ of the formatting.
+ </para>
+ <para>
+ This method does not take an <see cref="T:System.Exception"/> object to include in the
+ log event. To pass an <see cref="T:System.Exception"/> use one of the <see cref="M:log4net.ILog.Warn(System.Object)"/>
+ methods instead.
+ </para>
+ </remarks>
+ <seealso cref="M:log4net.ILog.Warn(System.Object,System.Exception)"/>
+ <seealso cref="P:log4net.ILog.IsWarnEnabled"/>
+ </member>
+ <member name="M:log4net.ILog.WarnFormat(System.String,System.Object)">
+ <summary>
+ Logs a formatted message string with the <see cref="F:log4net.Core.Level.Warn"/> level.
+ </summary>
+ <param name="format">A String containing zero or more format items</param>
+ <param name="arg0">An Object to format</param>
+ <remarks>
+ <para>
+ The message is formatted using the <c>String.Format</c> method. See
+ <see cref="M:System.String.Format(System.String,System.Object[])"/> for details of the syntax of the format string and the behavior
+ of the formatting.
+ </para>
+ <para>
+ This method does not take an <see cref="T:System.Exception"/> object to include in the
+ log event. To pass an <see cref="T:System.Exception"/> use one of the <see cref="M:log4net.ILog.Warn(System.Object,System.Exception)"/>
+ methods instead.
+ </para>
+ </remarks>
+ <seealso cref="M:log4net.ILog.Warn(System.Object)"/>
+ <seealso cref="P:log4net.ILog.IsWarnEnabled"/>
+ </member>
+ <member name="M:log4net.ILog.WarnFormat(System.String,System.Object,System.Object)">
+ <summary>
+ Logs a formatted message string with the <see cref="F:log4net.Core.Level.Warn"/> level.
+ </summary>
+ <param name="format">A String containing zero or more format items</param>
+ <param name="arg0">An Object to format</param>
+ <param name="arg1">An Object to format</param>
+ <remarks>
+ <para>
+ The message is formatted using the <c>String.Format</c> method. See
+ <see cref="M:System.String.Format(System.String,System.Object[])"/> for details of the syntax of the format string and the behavior
+ of the formatting.
+ </para>
+ <para>
+ This method does not take an <see cref="T:System.Exception"/> object to include in the
+ log event. To pass an <see cref="T:System.Exception"/> use one of the <see cref="M:log4net.ILog.Warn(System.Object,System.Exception)"/>
+ methods instead.
+ </para>
+ </remarks>
+ <seealso cref="M:log4net.ILog.Warn(System.Object)"/>
+ <seealso cref="P:log4net.ILog.IsWarnEnabled"/>
+ </member>
+ <member name="M:log4net.ILog.WarnFormat(System.String,System.Object,System.Object,System.Object)">
+ <summary>
+ Logs a formatted message string with the <see cref="F:log4net.Core.Level.Warn"/> level.
+ </summary>
+ <param name="format">A String containing zero or more format items</param>
+ <param name="arg0">An Object to format</param>
+ <param name="arg1">An Object to format</param>
+ <param name="arg2">An Object to format</param>
+ <remarks>
+ <para>
+ The message is formatted using the <c>String.Format</c> method. See
+ <see cref="M:System.String.Format(System.String,System.Object[])"/> for details of the syntax of the format string and the behavior
+ of the formatting.
+ </para>
+ <para>
+ This method does not take an <see cref="T:System.Exception"/> object to include in the
+ log event. To pass an <see cref="T:System.Exception"/> use one of the <see cref="M:log4net.ILog.Warn(System.Object,System.Exception)"/>
+ methods instead.
+ </para>
+ </remarks>
+ <seealso cref="M:log4net.ILog.Warn(System.Object)"/>
+ <seealso cref="P:log4net.ILog.IsWarnEnabled"/>
+ </member>
+ <member name="M:log4net.ILog.WarnFormat(System.IFormatProvider,System.String,System.Object[])">
+ <summary>
+ Logs a formatted message string with the <see cref="F:log4net.Core.Level.Warn"/> level.
+ </summary>
+ <param name="provider">An <see cref="T:System.IFormatProvider"/> that supplies culture-specific formatting information</param>
+ <param name="format">A String containing zero or more format items</param>
+ <param name="args">An Object array containing zero or more objects to format</param>
+ <remarks>
+ <para>
+ The message is formatted using the <c>String.Format</c> method. See
+ <see cref="M:System.String.Format(System.String,System.Object[])"/> for details of the syntax of the format string and the behavior
+ of the formatting.
+ </para>
+ <para>
+ This method does not take an <see cref="T:System.Exception"/> object to include in the
+ log event. To pass an <see cref="T:System.Exception"/> use one of the <see cref="M:log4net.ILog.Warn(System.Object)"/>
+ methods instead.
+ </para>
+ </remarks>
+ <seealso cref="M:log4net.ILog.Warn(System.Object,System.Exception)"/>
+ <seealso cref="P:log4net.ILog.IsWarnEnabled"/>
+ </member>
+ <member name="M:log4net.ILog.Error(System.Object)">
+ <overloads>Log a message object with the <see cref="F:log4net.Core.Level.Error"/> level.</overloads>
+ <summary>
+ Logs a message object with the <see cref="F:log4net.Core.Level.Error"/> level.
+ </summary>
+ <param name="message">The message object to log.</param>
+ <remarks>
+ <para>
+ This method first checks if this logger is <c>ERROR</c>
+ enabled by comparing the level of this logger with the
+ <see cref="F:log4net.Core.Level.Error"/> level. If this logger is
+ <c>ERROR</c> enabled, then it converts the message object
+ (passed as parameter) to a string by invoking the appropriate
+ <see cref="T:log4net.ObjectRenderer.IObjectRenderer"/>. It then
+ proceeds to call all the registered appenders in this logger
+ and also higher in the hierarchy depending on the value of the
+ additivity flag.
+ </para>
+ <para><b>WARNING</b> Note that passing an <see cref="T:System.Exception"/>
+ to this method will print the name of the <see cref="T:System.Exception"/>
+ but no stack trace. To print a stack trace use the
+ <see cref="M:log4net.ILog.Error(System.Object,System.Exception)"/> form instead.
+ </para>
+ </remarks>
+ <seealso cref="M:log4net.ILog.Error(System.Object,System.Exception)"/>
+ <seealso cref="P:log4net.ILog.IsErrorEnabled"/>
+ </member>
+ <member name="M:log4net.ILog.Error(System.Object,System.Exception)">
+ <summary>
+ Log a message object with the <see cref="F:log4net.Core.Level.Error"/> level including
+ the stack trace of the <see cref="T:System.Exception"/> passed
+ as a parameter.
+ </summary>
+ <param name="message">The message object to log.</param>
+ <param name="exception">The exception to log, including its stack trace.</param>
+ <remarks>
+ <para>
+ See the <see cref="M:log4net.ILog.Error(System.Object)"/> form for more detailed information.
+ </para>
+ </remarks>
+ <seealso cref="M:log4net.ILog.Error(System.Object)"/>
+ <seealso cref="P:log4net.ILog.IsErrorEnabled"/>
+ </member>
+ <member name="M:log4net.ILog.ErrorFormat(System.String,System.Object[])">
+ <overloads>Log a formatted message string with the <see cref="F:log4net.Core.Level.Error"/> level.</overloads>
+ <summary>
+ Logs a formatted message string with the <see cref="F:log4net.Core.Level.Error"/> level.
+ </summary>
+ <param name="format">A String containing zero or more format items</param>
+ <param name="args">An Object array containing zero or more objects to format</param>
+ <remarks>
+ <para>
+ The message is formatted using the <c>String.Format</c> method. See
+ <see cref="M:System.String.Format(System.String,System.Object[])"/> for details of the syntax of the format string and the behavior
+ of the formatting.
+ </para>
+ <para>
+ This method does not take an <see cref="T:System.Exception"/> object to include in the
+ log event. To pass an <see cref="T:System.Exception"/> use one of the <see cref="M:log4net.ILog.Error(System.Object)"/>
+ methods instead.
+ </para>
+ </remarks>
+ <seealso cref="M:log4net.ILog.Error(System.Object,System.Exception)"/>
+ <seealso cref="P:log4net.ILog.IsErrorEnabled"/>
+ </member>
+ <member name="M:log4net.ILog.ErrorFormat(System.String,System.Object)">
+ <summary>
+ Logs a formatted message string with the <see cref="F:log4net.Core.Level.Error"/> level.
+ </summary>
+ <param name="format">A String containing zero or more format items</param>
+ <param name="arg0">An Object to format</param>
+ <remarks>
+ <para>
+ The message is formatted using the <c>String.Format</c> method. See
+ <see cref="M:System.String.Format(System.String,System.Object[])"/> for details of the syntax of the format string and the behavior
+ of the formatting.
+ </para>
+ <para>
+ This method does not take an <see cref="T:System.Exception"/> object to include in the
+ log event. To pass an <see cref="T:System.Exception"/> use one of the <see cref="M:log4net.ILog.Error(System.Object,System.Exception)"/>
+ methods instead.
+ </para>
+ </remarks>
+ <seealso cref="M:log4net.ILog.Error(System.Object)"/>
+ <seealso cref="P:log4net.ILog.IsErrorEnabled"/>
+ </member>
+ <member name="M:log4net.ILog.ErrorFormat(System.String,System.Object,System.Object)">
+ <summary>
+ Logs a formatted message string with the <see cref="F:log4net.Core.Level.Error"/> level.
+ </summary>
+ <param name="format">A String containing zero or more format items</param>
+ <param name="arg0">An Object to format</param>
+ <param name="arg1">An Object to format</param>
+ <remarks>
+ <para>
+ The message is formatted using the <c>String.Format</c> method. See
+ <see cref="M:System.String.Format(System.String,System.Object[])"/> for details of the syntax of the format string and the behavior
+ of the formatting.
+ </para>
+ <para>
+ This method does not take an <see cref="T:System.Exception"/> object to include in the
+ log event. To pass an <see cref="T:System.Exception"/> use one of the <see cref="M:log4net.ILog.Error(System.Object,System.Exception)"/>
+ methods instead.
+ </para>
+ </remarks>
+ <seealso cref="M:log4net.ILog.Error(System.Object)"/>
+ <seealso cref="P:log4net.ILog.IsErrorEnabled"/>
+ </member>
+ <member name="M:log4net.ILog.ErrorFormat(System.String,System.Object,System.Object,System.Object)">
+ <summary>
+ Logs a formatted message string with the <see cref="F:log4net.Core.Level.Error"/> level.
+ </summary>
+ <param name="format">A String containing zero or more format items</param>
+ <param name="arg0">An Object to format</param>
+ <param name="arg1">An Object to format</param>
+ <param name="arg2">An Object to format</param>
+ <remarks>
+ <para>
+ The message is formatted using the <c>String.Format</c> method. See
+ <see cref="M:System.String.Format(System.String,System.Object[])"/> for details of the syntax of the format string and the behavior
+ of the formatting.
+ </para>
+ <para>
+ This method does not take an <see cref="T:System.Exception"/> object to include in the
+ log event. To pass an <see cref="T:System.Exception"/> use one of the <see cref="M:log4net.ILog.Error(System.Object,System.Exception)"/>
+ methods instead.
+ </para>
+ </remarks>
+ <seealso cref="M:log4net.ILog.Error(System.Object)"/>
+ <seealso cref="P:log4net.ILog.IsErrorEnabled"/>
+ </member>
+ <member name="M:log4net.ILog.ErrorFormat(System.IFormatProvider,System.String,System.Object[])">
+ <summary>
+ Logs a formatted message string with the <see cref="F:log4net.Core.Level.Error"/> level.
+ </summary>
+ <param name="provider">An <see cref="T:System.IFormatProvider"/> that supplies culture-specific formatting information</param>
+ <param name="format">A String containing zero or more format items</param>
+ <param name="args">An Object array containing zero or more objects to format</param>
+ <remarks>
+ <para>
+ The message is formatted using the <c>String.Format</c> method. See
+ <see cref="M:System.String.Format(System.String,System.Object[])"/> for details of the syntax of the format string and the behavior
+ of the formatting.
+ </para>
+ <para>
+ This method does not take an <see cref="T:System.Exception"/> object to include in the
+ log event. To pass an <see cref="T:System.Exception"/> use one of the <see cref="M:log4net.ILog.Error(System.Object)"/>
+ methods instead.
+ </para>
+ </remarks>
+ <seealso cref="M:log4net.ILog.Error(System.Object,System.Exception)"/>
+ <seealso cref="P:log4net.ILog.IsErrorEnabled"/>
+ </member>
+ <member name="M:log4net.ILog.Fatal(System.Object)">
+ <overloads>Log a message object with the <see cref="F:log4net.Core.Level.Fatal"/> level.</overloads>
+ <summary>
+ Log a message object with the <see cref="F:log4net.Core.Level.Fatal"/> level.
+ </summary>
+ <remarks>
+ <para>
+ This method first checks if this logger is <c>FATAL</c>
+ enabled by comparing the level of this logger with the
+ <see cref="F:log4net.Core.Level.Fatal"/> level. If this logger is
+ <c>FATAL</c> enabled, then it converts the message object
+ (passed as parameter) to a string by invoking the appropriate
+ <see cref="T:log4net.ObjectRenderer.IObjectRenderer"/>. It then
+ proceeds to call all the registered appenders in this logger
+ and also higher in the hierarchy depending on the value of the
+ additivity flag.
+ </para>
+ <para><b>WARNING</b> Note that passing an <see cref="T:System.Exception"/>
+ to this method will print the name of the <see cref="T:System.Exception"/>
+ but no stack trace. To print a stack trace use the
+ <see cref="M:log4net.ILog.Fatal(System.Object,System.Exception)"/> form instead.
+ </para>
+ </remarks>
+ <param name="message">The message object to log.</param>
+ <seealso cref="M:log4net.ILog.Fatal(System.Object,System.Exception)"/>
+ <seealso cref="P:log4net.ILog.IsFatalEnabled"/>
+ </member>
+ <member name="M:log4net.ILog.Fatal(System.Object,System.Exception)">
+ <summary>
+ Log a message object with the <see cref="F:log4net.Core.Level.Fatal"/> level including
+ the stack trace of the <see cref="T:System.Exception"/> passed
+ as a parameter.
+ </summary>
+ <param name="message">The message object to log.</param>
+ <param name="exception">The exception to log, including its stack trace.</param>
+ <remarks>
+ <para>
+ See the <see cref="M:log4net.ILog.Fatal(System.Object)"/> form for more detailed information.
+ </para>
+ </remarks>
+ <seealso cref="M:log4net.ILog.Fatal(System.Object)"/>
+ <seealso cref="P:log4net.ILog.IsFatalEnabled"/>
+ </member>
+ <member name="M:log4net.ILog.FatalFormat(System.String,System.Object[])">
+ <overloads>Log a formatted message string with the <see cref="F:log4net.Core.Level.Fatal"/> level.</overloads>
+ <summary>
+ Logs a formatted message string with the <see cref="F:log4net.Core.Level.Fatal"/> level.
+ </summary>
+ <param name="format">A String containing zero or more format items</param>
+ <param name="args">An Object array containing zero or more objects to format</param>
+ <remarks>
+ <para>
+ The message is formatted using the <c>String.Format</c> method. See
+ <see cref="M:System.String.Format(System.String,System.Object[])"/> for details of the syntax of the format string and the behavior
+ of the formatting.
+ </para>
+ <para>
+ This method does not take an <see cref="T:System.Exception"/> object to include in the
+ log event. To pass an <see cref="T:System.Exception"/> use one of the <see cref="M:log4net.ILog.Fatal(System.Object)"/>
+ methods instead.
+ </para>
+ </remarks>
+ <seealso cref="M:log4net.ILog.Fatal(System.Object,System.Exception)"/>
+ <seealso cref="P:log4net.ILog.IsFatalEnabled"/>
+ </member>
+ <member name="M:log4net.ILog.FatalFormat(System.String,System.Object)">
+ <summary>
+ Logs a formatted message string with the <see cref="F:log4net.Core.Level.Fatal"/> level.
+ </summary>
+ <param name="format">A String containing zero or more format items</param>
+ <param name="arg0">An Object to format</param>
+ <remarks>
+ <para>
+ The message is formatted using the <c>String.Format</c> method. See
+ <see cref="M:System.String.Format(System.String,System.Object[])"/> for details of the syntax of the format string and the behavior
+ of the formatting.
+ </para>
+ <para>
+ This method does not take an <see cref="T:System.Exception"/> object to include in the
+ log event. To pass an <see cref="T:System.Exception"/> use one of the <see cref="M:log4net.ILog.Fatal(System.Object,System.Exception)"/>
+ methods instead.
+ </para>
+ </remarks>
+ <seealso cref="M:log4net.ILog.Fatal(System.Object)"/>
+ <seealso cref="P:log4net.ILog.IsFatalEnabled"/>
+ </member>
+ <member name="M:log4net.ILog.FatalFormat(System.String,System.Object,System.Object)">
+ <summary>
+ Logs a formatted message string with the <see cref="F:log4net.Core.Level.Fatal"/> level.
+ </summary>
+ <param name="format">A String containing zero or more format items</param>
+ <param name="arg0">An Object to format</param>
+ <param name="arg1">An Object to format</param>
+ <remarks>
+ <para>
+ The message is formatted using the <c>String.Format</c> method. See
+ <see cref="M:System.String.Format(System.String,System.Object[])"/> for details of the syntax of the format string and the behavior
+ of the formatting.
+ </para>
+ <para>
+ This method does not take an <see cref="T:System.Exception"/> object to include in the
+ log event. To pass an <see cref="T:System.Exception"/> use one of the <see cref="M:log4net.ILog.Fatal(System.Object,System.Exception)"/>
+ methods instead.
+ </para>
+ </remarks>
+ <seealso cref="M:log4net.ILog.Fatal(System.Object)"/>
+ <seealso cref="P:log4net.ILog.IsFatalEnabled"/>
+ </member>
+ <member name="M:log4net.ILog.FatalFormat(System.String,System.Object,System.Object,System.Object)">
+ <summary>
+ Logs a formatted message string with the <see cref="F:log4net.Core.Level.Fatal"/> level.
+ </summary>
+ <param name="format">A String containing zero or more format items</param>
+ <param name="arg0">An Object to format</param>
+ <param name="arg1">An Object to format</param>
+ <param name="arg2">An Object to format</param>
+ <remarks>
+ <para>
+ The message is formatted using the <c>String.Format</c> method. See
+ <see cref="M:System.String.Format(System.String,System.Object[])"/> for details of the syntax of the format string and the behavior
+ of the formatting.
+ </para>
+ <para>
+ This method does not take an <see cref="T:System.Exception"/> object to include in the
+ log event. To pass an <see cref="T:System.Exception"/> use one of the <see cref="M:log4net.ILog.Fatal(System.Object,System.Exception)"/>
+ methods instead.
+ </para>
+ </remarks>
+ <seealso cref="M:log4net.ILog.Fatal(System.Object)"/>
+ <seealso cref="P:log4net.ILog.IsFatalEnabled"/>
+ </member>
+ <member name="M:log4net.ILog.FatalFormat(System.IFormatProvider,System.String,System.Object[])">
+ <summary>
+ Logs a formatted message string with the <see cref="F:log4net.Core.Level.Fatal"/> level.
+ </summary>
+ <param name="provider">An <see cref="T:System.IFormatProvider"/> that supplies culture-specific formatting information</param>
+ <param name="format">A String containing zero or more format items</param>
+ <param name="args">An Object array containing zero or more objects to format</param>
+ <remarks>
+ <para>
+ The message is formatted using the <c>String.Format</c> method. See
+ <see cref="M:System.String.Format(System.String,System.Object[])"/> for details of the syntax of the format string and the behavior
+ of the formatting.
+ </para>
+ <para>
+ This method does not take an <see cref="T:System.Exception"/> object to include in the
+ log event. To pass an <see cref="T:System.Exception"/> use one of the <see cref="M:log4net.ILog.Fatal(System.Object)"/>
+ methods instead.
+ </para>
+ </remarks>
+ <seealso cref="M:log4net.ILog.Fatal(System.Object,System.Exception)"/>
+ <seealso cref="P:log4net.ILog.IsFatalEnabled"/>
+ </member>
+ <member name="P:log4net.ILog.IsDebugEnabled">
+ <summary>
+ Checks if this logger is enabled for the <see cref="F:log4net.Core.Level.Debug"/> level.
+ </summary>
+ <value>
+ <c>true</c> if this logger is enabled for <see cref="F:log4net.Core.Level.Debug"/> events, <c>false</c> otherwise.
+ </value>
+ <remarks>
+ <para>
+ This function is intended to lessen the computational cost of
+ disabled log debug statements.
+ </para>
+ <para> For some ILog interface <c>log</c>, when you write:</para>
+ <code lang="C#">
+ log.Debug("This is entry number: " + i );
+ </code>
+ <para>
+ You incur the cost constructing the message, string construction and concatenation in
+ this case, regardless of whether the message is logged or not.
+ </para>
+ <para>
+ If you are worried about speed (who isn't), then you should write:
+ </para>
+ <code lang="C#">
+ if (log.IsDebugEnabled)
+ {
+ log.Debug("This is entry number: " + i );
+ }
+ </code>
+ <para>
+ This way you will not incur the cost of parameter
+ construction if debugging is disabled for <c>log</c>. On
+ the other hand, if the <c>log</c> is debug enabled, you
+ will incur the cost of evaluating whether the logger is debug
+ enabled twice. Once in <see cref="P:log4net.ILog.IsDebugEnabled"/> and once in
+ the <see cref="M:log4net.ILog.Debug(System.Object)"/>. This is an insignificant overhead
+ since evaluating a logger takes about 1% of the time it
+ takes to actually log. This is the preferred style of logging.
+ </para>
+ <para>Alternatively if your logger is available statically then the is debug
+ enabled state can be stored in a static variable like this:
+ </para>
+ <code lang="C#">
+ private static readonly bool isDebugEnabled = log.IsDebugEnabled;
+ </code>
+ <para>
+ Then when you come to log you can write:
+ </para>
+ <code lang="C#">
+ if (isDebugEnabled)
+ {
+ log.Debug("This is entry number: " + i );
+ }
+ </code>
+ <para>
+ This way the debug enabled state is only queried once
+ when the class is loaded. Using a <c>private static readonly</c>
+ variable is the most efficient because it is a run time constant
+ and can be heavily optimized by the JIT compiler.
+ </para>
+ <para>
+ Of course if you use a static readonly variable to
+ hold the enabled state of the logger then you cannot
+ change the enabled state at runtime to vary the logging
+ that is produced. You have to decide if you need absolute
+ speed or runtime flexibility.
+ </para>
+ </remarks>
+ <seealso cref="M:log4net.ILog.Debug(System.Object)"/>
+ <seealso cref="M:log4net.ILog.DebugFormat(System.IFormatProvider,System.String,System.Object[])"/>
+ </member>
+ <member name="P:log4net.ILog.IsInfoEnabled">
+ <summary>
+ Checks if this logger is enabled for the <see cref="F:log4net.Core.Level.Info"/> level.
+ </summary>
+ <value>
+ <c>true</c> if this logger is enabled for <see cref="F:log4net.Core.Level.Info"/> events, <c>false</c> otherwise.
+ </value>
+ <remarks>
+ For more information see <see cref="P:log4net.ILog.IsDebugEnabled"/>.
+ </remarks>
+ <seealso cref="M:log4net.ILog.Info(System.Object)"/>
+ <seealso cref="M:log4net.ILog.InfoFormat(System.IFormatProvider,System.String,System.Object[])"/>
+ <seealso cref="P:log4net.ILog.IsDebugEnabled"/>
+ </member>
+ <member name="P:log4net.ILog.IsWarnEnabled">
+ <summary>
+ Checks if this logger is enabled for the <see cref="F:log4net.Core.Level.Warn"/> level.
+ </summary>
+ <value>
+ <c>true</c> if this logger is enabled for <see cref="F:log4net.Core.Level.Warn"/> events, <c>false</c> otherwise.
+ </value>
+ <remarks>
+ For more information see <see cref="P:log4net.ILog.IsDebugEnabled"/>.
+ </remarks>
+ <seealso cref="M:log4net.ILog.Warn(System.Object)"/>
+ <seealso cref="M:log4net.ILog.WarnFormat(System.IFormatProvider,System.String,System.Object[])"/>
+ <seealso cref="P:log4net.ILog.IsDebugEnabled"/>
+ </member>
+ <member name="P:log4net.ILog.IsErrorEnabled">
+ <summary>
+ Checks if this logger is enabled for the <see cref="F:log4net.Core.Level.Error"/> level.
+ </summary>
+ <value>
+ <c>true</c> if this logger is enabled for <see cref="F:log4net.Core.Level.Error"/> events, <c>false</c> otherwise.
+ </value>
+ <remarks>
+ For more information see <see cref="P:log4net.ILog.IsDebugEnabled"/>.
+ </remarks>
+ <seealso cref="M:log4net.ILog.Error(System.Object)"/>
+ <seealso cref="M:log4net.ILog.ErrorFormat(System.IFormatProvider,System.String,System.Object[])"/>
+ <seealso cref="P:log4net.ILog.IsDebugEnabled"/>
+ </member>
+ <member name="P:log4net.ILog.IsFatalEnabled">
+ <summary>
+ Checks if this logger is enabled for the <see cref="F:log4net.Core.Level.Fatal"/> level.
+ </summary>
+ <value>
+ <c>true</c> if this logger is enabled for <see cref="F:log4net.Core.Level.Fatal"/> events, <c>false</c> otherwise.
+ </value>
+ <remarks>
+ For more information see <see cref="P:log4net.ILog.IsDebugEnabled"/>.
+ </remarks>
+ <seealso cref="M:log4net.ILog.Fatal(System.Object)"/>
+ <seealso cref="M:log4net.ILog.FatalFormat(System.IFormatProvider,System.String,System.Object[])"/>
+ <seealso cref="P:log4net.ILog.IsDebugEnabled"/>
+ </member>
+ <member name="M:log4net.Core.LogImpl.#ctor(log4net.Core.ILogger)">
+ <summary>
+ Construct a new wrapper for the specified logger.
+ </summary>
+ <param name="logger">The logger to wrap.</param>
+ <remarks>
+ <para>
+ Construct a new wrapper for the specified logger.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LogImpl.ReloadLevels(log4net.Repository.ILoggerRepository)">
+ <summary>
+ Virtual method called when the configuration of the repository changes
+ </summary>
+ <param name="repository">the repository holding the levels</param>
+ <remarks>
+ <para>
+ Virtual method called when the configuration of the repository changes
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LogImpl.Debug(System.Object)">
+ <summary>
+ Logs a message object with the <c>DEBUG</c> level.
+ </summary>
+ <param name="message">The message object to log.</param>
+ <remarks>
+ <para>
+ This method first checks if this logger is <c>DEBUG</c>
+ enabled by comparing the level of this logger with the
+ <c>DEBUG</c> level. If this logger is
+ <c>DEBUG</c> enabled, then it converts the message object
+ (passed as parameter) to a string by invoking the appropriate
+ <see cref="T:log4net.ObjectRenderer.IObjectRenderer"/>. It then
+ proceeds to call all the registered appenders in this logger
+ and also higher in the hierarchy depending on the value of the
+ additivity flag.
+ </para>
+ <para>
+ <b>WARNING</b> Note that passing an <see cref="T:System.Exception"/>
+ to this method will print the name of the <see cref="T:System.Exception"/>
+ but no stack trace. To print a stack trace use the
+ <see cref="M:log4net.Core.LogImpl.Debug(System.Object,System.Exception)"/> form instead.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LogImpl.Debug(System.Object,System.Exception)">
+ <summary>
+ Logs a message object with the <c>DEBUG</c> level
+ </summary>
+ <param name="message">The message object to log.</param>
+ <param name="exception">The exception to log, including its stack trace.</param>
+ <remarks>
+ <para>
+ Logs a message object with the <c>DEBUG</c> level including
+ the stack trace of the <see cref="T:System.Exception"/> <paramref name="exception"/> passed
+ as a parameter.
+ </para>
+ <para>
+ See the <see cref="M:log4net.Core.LogImpl.Debug(System.Object)"/> form for more detailed information.
+ </para>
+ </remarks>
+ <seealso cref="M:log4net.Core.LogImpl.Debug(System.Object)"/>
+ </member>
+ <member name="M:log4net.Core.LogImpl.DebugFormat(System.String,System.Object[])">
+ <summary>
+ Logs a formatted message string with the <c>DEBUG</c> level.
+ </summary>
+ <param name="format">A String containing zero or more format items</param>
+ <param name="args">An Object array containing zero or more objects to format</param>
+ <remarks>
+ <para>
+ The message is formatted using the <see cref="M:System.String.Format(System.IFormatProvider,System.String,System.Object[])"/> method. See
+ <c>String.Format</c> for details of the syntax of the format string and the behavior
+ of the formatting.
+ </para>
+ <para>
+ The string is formatted using the <see cref="P:System.Globalization.CultureInfo.InvariantCulture"/>
+ format provider. To specify a localized provider use the
+ <see cref="M:log4net.Core.LogImpl.DebugFormat(System.IFormatProvider,System.String,System.Object[])"/> method.
+ </para>
+ <para>
+ This method does not take an <see cref="T:System.Exception"/> object to include in the
+ log event. To pass an <see cref="T:System.Exception"/> use one of the <see cref="M:log4net.Core.LogImpl.Debug(System.Object)"/>
+ methods instead.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LogImpl.DebugFormat(System.String,System.Object)">
+ <summary>
+ Logs a formatted message string with the <c>DEBUG</c> level.
+ </summary>
+ <param name="format">A String containing zero or more format items</param>
+ <param name="arg0">An Object to format</param>
+ <remarks>
+ <para>
+ The message is formatted using the <see cref="M:System.String.Format(System.IFormatProvider,System.String,System.Object[])"/> method. See
+ <c>String.Format</c> for details of the syntax of the format string and the behavior
+ of the formatting.
+ </para>
+ <para>
+ The string is formatted using the <see cref="P:System.Globalization.CultureInfo.InvariantCulture"/>
+ format provider. To specify a localized provider use the
+ <see cref="M:log4net.Core.LogImpl.DebugFormat(System.IFormatProvider,System.String,System.Object[])"/> method.
+ </para>
+ <para>
+ This method does not take an <see cref="T:System.Exception"/> object to include in the
+ log event. To pass an <see cref="T:System.Exception"/> use one of the <see cref="M:log4net.Core.LogImpl.Debug(System.Object)"/>
+ methods instead.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LogImpl.DebugFormat(System.String,System.Object,System.Object)">
+ <summary>
+ Logs a formatted message string with the <c>DEBUG</c> level.
+ </summary>
+ <param name="format">A String containing zero or more format items</param>
+ <param name="arg0">An Object to format</param>
+ <param name="arg1">An Object to format</param>
+ <remarks>
+ <para>
+ The message is formatted using the <see cref="M:System.String.Format(System.IFormatProvider,System.String,System.Object[])"/> method. See
+ <c>String.Format</c> for details of the syntax of the format string and the behavior
+ of the formatting.
+ </para>
+ <para>
+ The string is formatted using the <see cref="P:System.Globalization.CultureInfo.InvariantCulture"/>
+ format provider. To specify a localized provider use the
+ <see cref="M:log4net.Core.LogImpl.DebugFormat(System.IFormatProvider,System.String,System.Object[])"/> method.
+ </para>
+ <para>
+ This method does not take an <see cref="T:System.Exception"/> object to include in the
+ log event. To pass an <see cref="T:System.Exception"/> use one of the <see cref="M:log4net.Core.LogImpl.Debug(System.Object)"/>
+ methods instead.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LogImpl.DebugFormat(System.String,System.Object,System.Object,System.Object)">
+ <summary>
+ Logs a formatted message string with the <c>DEBUG</c> level.
+ </summary>
+ <param name="format">A String containing zero or more format items</param>
+ <param name="arg0">An Object to format</param>
+ <param name="arg1">An Object to format</param>
+ <param name="arg2">An Object to format</param>
+ <remarks>
+ <para>
+ The message is formatted using the <see cref="M:System.String.Format(System.IFormatProvider,System.String,System.Object[])"/> method. See
+ <c>String.Format</c> for details of the syntax of the format string and the behavior
+ of the formatting.
+ </para>
+ <para>
+ The string is formatted using the <see cref="P:System.Globalization.CultureInfo.InvariantCulture"/>
+ format provider. To specify a localized provider use the
+ <see cref="M:log4net.Core.LogImpl.DebugFormat(System.IFormatProvider,System.String,System.Object[])"/> method.
+ </para>
+ <para>
+ This method does not take an <see cref="T:System.Exception"/> object to include in the
+ log event. To pass an <see cref="T:System.Exception"/> use one of the <see cref="M:log4net.Core.LogImpl.Debug(System.Object)"/>
+ methods instead.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LogImpl.DebugFormat(System.IFormatProvider,System.String,System.Object[])">
+ <summary>
+ Logs a formatted message string with the <c>DEBUG</c> level.
+ </summary>
+ <param name="provider">An <see cref="T:System.IFormatProvider"/> that supplies culture-specific formatting information</param>
+ <param name="format">A String containing zero or more format items</param>
+ <param name="args">An Object array containing zero or more objects to format</param>
+ <remarks>
+ <para>
+ The message is formatted using the <see cref="M:System.String.Format(System.IFormatProvider,System.String,System.Object[])"/> method. See
+ <c>String.Format</c> for details of the syntax of the format string and the behavior
+ of the formatting.
+ </para>
+ <para>
+ This method does not take an <see cref="T:System.Exception"/> object to include in the
+ log event. To pass an <see cref="T:System.Exception"/> use one of the <see cref="M:log4net.Core.LogImpl.Debug(System.Object)"/>
+ methods instead.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LogImpl.Info(System.Object)">
+ <summary>
+ Logs a message object with the <c>INFO</c> level.
+ </summary>
+ <param name="message">The message object to log.</param>
+ <remarks>
+ <para>
+ This method first checks if this logger is <c>INFO</c>
+ enabled by comparing the level of this logger with the
+ <c>INFO</c> level. If this logger is
+ <c>INFO</c> enabled, then it converts the message object
+ (passed as parameter) to a string by invoking the appropriate
+ <see cref="T:log4net.ObjectRenderer.IObjectRenderer"/>. It then
+ proceeds to call all the registered appenders in this logger
+ and also higher in the hierarchy depending on the value of
+ the additivity flag.
+ </para>
+ <para>
+ <b>WARNING</b> Note that passing an <see cref="T:System.Exception"/>
+ to this method will print the name of the <see cref="T:System.Exception"/>
+ but no stack trace. To print a stack trace use the
+ <see cref="M:log4net.Core.LogImpl.Info(System.Object,System.Exception)"/> form instead.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LogImpl.Info(System.Object,System.Exception)">
+ <summary>
+ Logs a message object with the <c>INFO</c> level.
+ </summary>
+ <param name="message">The message object to log.</param>
+ <param name="exception">The exception to log, including its stack trace.</param>
+ <remarks>
+ <para>
+ Logs a message object with the <c>INFO</c> level including
+ the stack trace of the <see cref="T:System.Exception"/> <paramref name="exception"/>
+ passed as a parameter.
+ </para>
+ <para>
+ See the <see cref="M:log4net.Core.LogImpl.Info(System.Object)"/> form for more detailed information.
+ </para>
+ </remarks>
+ <seealso cref="M:log4net.Core.LogImpl.Info(System.Object)"/>
+ </member>
+ <member name="M:log4net.Core.LogImpl.InfoFormat(System.String,System.Object[])">
+ <summary>
+ Logs a formatted message string with the <c>INFO</c> level.
+ </summary>
+ <param name="format">A String containing zero or more format items</param>
+ <param name="args">An Object array containing zero or more objects to format</param>
+ <remarks>
+ <para>
+ The message is formatted using the <see cref="M:System.String.Format(System.IFormatProvider,System.String,System.Object[])"/> method. See
+ <c>String.Format</c> for details of the syntax of the format string and the behavior
+ of the formatting.
+ </para>
+ <para>
+ The string is formatted using the <see cref="P:System.Globalization.CultureInfo.InvariantCulture"/>
+ format provider. To specify a localized provider use the
+ <see cref="M:log4net.Core.LogImpl.InfoFormat(System.IFormatProvider,System.String,System.Object[])"/> method.
+ </para>
+ <para>
+ This method does not take an <see cref="T:System.Exception"/> object to include in the
+ log event. To pass an <see cref="T:System.Exception"/> use one of the <see cref="M:log4net.Core.LogImpl.Info(System.Object)"/>
+ methods instead.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LogImpl.InfoFormat(System.String,System.Object)">
+ <summary>
+ Logs a formatted message string with the <c>INFO</c> level.
+ </summary>
+ <param name="format">A String containing zero or more format items</param>
+ <param name="arg0">An Object to format</param>
+ <remarks>
+ <para>
+ The message is formatted using the <see cref="M:System.String.Format(System.IFormatProvider,System.String,System.Object[])"/> method. See
+ <c>String.Format</c> for details of the syntax of the format string and the behavior
+ of the formatting.
+ </para>
+ <para>
+ The string is formatted using the <see cref="P:System.Globalization.CultureInfo.InvariantCulture"/>
+ format provider. To specify a localized provider use the
+ <see cref="M:log4net.Core.LogImpl.InfoFormat(System.IFormatProvider,System.String,System.Object[])"/> method.
+ </para>
+ <para>
+ This method does not take an <see cref="T:System.Exception"/> object to include in the
+ log event. To pass an <see cref="T:System.Exception"/> use one of the <see cref="M:log4net.Core.LogImpl.Info(System.Object)"/>
+ methods instead.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LogImpl.InfoFormat(System.String,System.Object,System.Object)">
+ <summary>
+ Logs a formatted message string with the <c>INFO</c> level.
+ </summary>
+ <param name="format">A String containing zero or more format items</param>
+ <param name="arg0">An Object to format</param>
+ <param name="arg1">An Object to format</param>
+ <remarks>
+ <para>
+ The message is formatted using the <see cref="M:System.String.Format(System.IFormatProvider,System.String,System.Object[])"/> method. See
+ <c>String.Format</c> for details of the syntax of the format string and the behavior
+ of the formatting.
+ </para>
+ <para>
+ The string is formatted using the <see cref="P:System.Globalization.CultureInfo.InvariantCulture"/>
+ format provider. To specify a localized provider use the
+ <see cref="M:log4net.Core.LogImpl.InfoFormat(System.IFormatProvider,System.String,System.Object[])"/> method.
+ </para>
+ <para>
+ This method does not take an <see cref="T:System.Exception"/> object to include in the
+ log event. To pass an <see cref="T:System.Exception"/> use one of the <see cref="M:log4net.Core.LogImpl.Info(System.Object)"/>
+ methods instead.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LogImpl.InfoFormat(System.String,System.Object,System.Object,System.Object)">
+ <summary>
+ Logs a formatted message string with the <c>INFO</c> level.
+ </summary>
+ <param name="format">A String containing zero or more format items</param>
+ <param name="arg0">An Object to format</param>
+ <param name="arg1">An Object to format</param>
+ <param name="arg2">An Object to format</param>
+ <remarks>
+ <para>
+ The message is formatted using the <see cref="M:System.String.Format(System.IFormatProvider,System.String,System.Object[])"/> method. See
+ <c>String.Format</c> for details of the syntax of the format string and the behavior
+ of the formatting.
+ </para>
+ <para>
+ The string is formatted using the <see cref="P:System.Globalization.CultureInfo.InvariantCulture"/>
+ format provider. To specify a localized provider use the
+ <see cref="M:log4net.Core.LogImpl.InfoFormat(System.IFormatProvider,System.String,System.Object[])"/> method.
+ </para>
+ <para>
+ This method does not take an <see cref="T:System.Exception"/> object to include in the
+ log event. To pass an <see cref="T:System.Exception"/> use one of the <see cref="M:log4net.Core.LogImpl.Info(System.Object)"/>
+ methods instead.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LogImpl.InfoFormat(System.IFormatProvider,System.String,System.Object[])">
+ <summary>
+ Logs a formatted message string with the <c>INFO</c> level.
+ </summary>
+ <param name="provider">An <see cref="T:System.IFormatProvider"/> that supplies culture-specific formatting information</param>
+ <param name="format">A String containing zero or more format items</param>
+ <param name="args">An Object array containing zero or more objects to format</param>
+ <remarks>
+ <para>
+ The message is formatted using the <see cref="M:System.String.Format(System.IFormatProvider,System.String,System.Object[])"/> method. See
+ <c>String.Format</c> for details of the syntax of the format string and the behavior
+ of the formatting.
+ </para>
+ <para>
+ This method does not take an <see cref="T:System.Exception"/> object to include in the
+ log event. To pass an <see cref="T:System.Exception"/> use one of the <see cref="M:log4net.Core.LogImpl.Info(System.Object)"/>
+ methods instead.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LogImpl.Warn(System.Object)">
+ <summary>
+ Logs a message object with the <c>WARN</c> level.
+ </summary>
+ <param name="message">the message object to log</param>
+ <remarks>
+ <para>
+ This method first checks if this logger is <c>WARN</c>
+ enabled by comparing the level of this logger with the
+ <c>WARN</c> level. If this logger is
+ <c>WARN</c> enabled, then it converts the message object
+ (passed as parameter) to a string by invoking the appropriate
+ <see cref="T:log4net.ObjectRenderer.IObjectRenderer"/>. It then
+ proceeds to call all the registered appenders in this logger and
+ also higher in the hierarchy depending on the value of the
+ additivity flag.
+ </para>
+ <para>
+ <b>WARNING</b> Note that passing an <see cref="T:System.Exception"/> to this
+ method will print the name of the <see cref="T:System.Exception"/> but no
+ stack trace. To print a stack trace use the
+ <see cref="M:log4net.Core.LogImpl.Warn(System.Object,System.Exception)"/> form instead.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LogImpl.Warn(System.Object,System.Exception)">
+ <summary>
+ Logs a message object with the <c>WARN</c> level
+ </summary>
+ <param name="message">The message object to log.</param>
+ <param name="exception">The exception to log, including its stack trace.</param>
+ <remarks>
+ <para>
+ Logs a message object with the <c>WARN</c> level including
+ the stack trace of the <see cref="T:System.Exception"/> <paramref name="exception"/>
+ passed as a parameter.
+ </para>
+ <para>
+ See the <see cref="M:log4net.Core.LogImpl.Warn(System.Object)"/> form for more detailed information.
+ </para>
+ </remarks>
+ <seealso cref="M:log4net.Core.LogImpl.Warn(System.Object)"/>
+ </member>
+ <member name="M:log4net.Core.LogImpl.WarnFormat(System.String,System.Object[])">
+ <summary>
+ Logs a formatted message string with the <c>WARN</c> level.
+ </summary>
+ <param name="format">A String containing zero or more format items</param>
+ <param name="args">An Object array containing zero or more objects to format</param>
+ <remarks>
+ <para>
+ The message is formatted using the <see cref="M:System.String.Format(System.IFormatProvider,System.String,System.Object[])"/> method. See
+ <c>String.Format</c> for details of the syntax of the format string and the behavior
+ of the formatting.
+ </para>
+ <para>
+ The string is formatted using the <see cref="P:System.Globalization.CultureInfo.InvariantCulture"/>
+ format provider. To specify a localized provider use the
+ <see cref="M:log4net.Core.LogImpl.WarnFormat(System.IFormatProvider,System.String,System.Object[])"/> method.
+ </para>
+ <para>
+ This method does not take an <see cref="T:System.Exception"/> object to include in the
+ log event. To pass an <see cref="T:System.Exception"/> use one of the <see cref="M:log4net.Core.LogImpl.Warn(System.Object)"/>
+ methods instead.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LogImpl.WarnFormat(System.String,System.Object)">
+ <summary>
+ Logs a formatted message string with the <c>WARN</c> level.
+ </summary>
+ <param name="format">A String containing zero or more format items</param>
+ <param name="arg0">An Object to format</param>
+ <remarks>
+ <para>
+ The message is formatted using the <see cref="M:System.String.Format(System.IFormatProvider,System.String,System.Object[])"/> method. See
+ <c>String.Format</c> for details of the syntax of the format string and the behavior
+ of the formatting.
+ </para>
+ <para>
+ The string is formatted using the <see cref="P:System.Globalization.CultureInfo.InvariantCulture"/>
+ format provider. To specify a localized provider use the
+ <see cref="M:log4net.Core.LogImpl.WarnFormat(System.IFormatProvider,System.String,System.Object[])"/> method.
+ </para>
+ <para>
+ This method does not take an <see cref="T:System.Exception"/> object to include in the
+ log event. To pass an <see cref="T:System.Exception"/> use one of the <see cref="M:log4net.Core.LogImpl.Warn(System.Object)"/>
+ methods instead.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LogImpl.WarnFormat(System.String,System.Object,System.Object)">
+ <summary>
+ Logs a formatted message string with the <c>WARN</c> level.
+ </summary>
+ <param name="format">A String containing zero or more format items</param>
+ <param name="arg0">An Object to format</param>
+ <param name="arg1">An Object to format</param>
+ <remarks>
+ <para>
+ The message is formatted using the <see cref="M:System.String.Format(System.IFormatProvider,System.String,System.Object[])"/> method. See
+ <c>String.Format</c> for details of the syntax of the format string and the behavior
+ of the formatting.
+ </para>
+ <para>
+ The string is formatted using the <see cref="P:System.Globalization.CultureInfo.InvariantCulture"/>
+ format provider. To specify a localized provider use the
+ <see cref="M:log4net.Core.LogImpl.WarnFormat(System.IFormatProvider,System.String,System.Object[])"/> method.
+ </para>
+ <para>
+ This method does not take an <see cref="T:System.Exception"/> object to include in the
+ log event. To pass an <see cref="T:System.Exception"/> use one of the <see cref="M:log4net.Core.LogImpl.Warn(System.Object)"/>
+ methods instead.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LogImpl.WarnFormat(System.String,System.Object,System.Object,System.Object)">
+ <summary>
+ Logs a formatted message string with the <c>WARN</c> level.
+ </summary>
+ <param name="format">A String containing zero or more format items</param>
+ <param name="arg0">An Object to format</param>
+ <param name="arg1">An Object to format</param>
+ <param name="arg2">An Object to format</param>
+ <remarks>
+ <para>
+ The message is formatted using the <see cref="M:System.String.Format(System.IFormatProvider,System.String,System.Object[])"/> method. See
+ <c>String.Format</c> for details of the syntax of the format string and the behavior
+ of the formatting.
+ </para>
+ <para>
+ The string is formatted using the <see cref="P:System.Globalization.CultureInfo.InvariantCulture"/>
+ format provider. To specify a localized provider use the
+ <see cref="M:log4net.Core.LogImpl.WarnFormat(System.IFormatProvider,System.String,System.Object[])"/> method.
+ </para>
+ <para>
+ This method does not take an <see cref="T:System.Exception"/> object to include in the
+ log event. To pass an <see cref="T:System.Exception"/> use one of the <see cref="M:log4net.Core.LogImpl.Warn(System.Object)"/>
+ methods instead.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LogImpl.WarnFormat(System.IFormatProvider,System.String,System.Object[])">
+ <summary>
+ Logs a formatted message string with the <c>WARN</c> level.
+ </summary>
+ <param name="provider">An <see cref="T:System.IFormatProvider"/> that supplies culture-specific formatting information</param>
+ <param name="format">A String containing zero or more format items</param>
+ <param name="args">An Object array containing zero or more objects to format</param>
+ <remarks>
+ <para>
+ The message is formatted using the <see cref="M:System.String.Format(System.IFormatProvider,System.String,System.Object[])"/> method. See
+ <c>String.Format</c> for details of the syntax of the format string and the behavior
+ of the formatting.
+ </para>
+ <para>
+ This method does not take an <see cref="T:System.Exception"/> object to include in the
+ log event. To pass an <see cref="T:System.Exception"/> use one of the <see cref="M:log4net.Core.LogImpl.Warn(System.Object)"/>
+ methods instead.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LogImpl.Error(System.Object)">
+ <summary>
+ Logs a message object with the <c>ERROR</c> level.
+ </summary>
+ <param name="message">The message object to log.</param>
+ <remarks>
+ <para>
+ This method first checks if this logger is <c>ERROR</c>
+ enabled by comparing the level of this logger with the
+ <c>ERROR</c> level. If this logger is
+ <c>ERROR</c> enabled, then it converts the message object
+ (passed as parameter) to a string by invoking the appropriate
+ <see cref="T:log4net.ObjectRenderer.IObjectRenderer"/>. It then
+ proceeds to call all the registered appenders in this logger and
+ also higher in the hierarchy depending on the value of the
+ additivity flag.
+ </para>
+ <para>
+ <b>WARNING</b> Note that passing an <see cref="T:System.Exception"/> to this
+ method will print the name of the <see cref="T:System.Exception"/> but no
+ stack trace. To print a stack trace use the
+ <see cref="M:log4net.Core.LogImpl.Error(System.Object,System.Exception)"/> form instead.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LogImpl.Error(System.Object,System.Exception)">
+ <summary>
+ Logs a message object with the <c>ERROR</c> level
+ </summary>
+ <param name="message">The message object to log.</param>
+ <param name="exception">The exception to log, including its stack trace.</param>
+ <remarks>
+ <para>
+ Logs a message object with the <c>ERROR</c> level including
+ the stack trace of the <see cref="T:System.Exception"/> <paramref name="exception"/>
+ passed as a parameter.
+ </para>
+ <para>
+ See the <see cref="M:log4net.Core.LogImpl.Error(System.Object)"/> form for more detailed information.
+ </para>
+ </remarks>
+ <seealso cref="M:log4net.Core.LogImpl.Error(System.Object)"/>
+ </member>
+ <member name="M:log4net.Core.LogImpl.ErrorFormat(System.String,System.Object[])">
+ <summary>
+ Logs a formatted message string with the <c>ERROR</c> level.
+ </summary>
+ <param name="format">A String containing zero or more format items</param>
+ <param name="args">An Object array containing zero or more objects to format</param>
+ <remarks>
+ <para>
+ The message is formatted using the <see cref="M:System.String.Format(System.IFormatProvider,System.String,System.Object[])"/> method. See
+ <c>String.Format</c> for details of the syntax of the format string and the behavior
+ of the formatting.
+ </para>
+ <para>
+ The string is formatted using the <see cref="P:System.Globalization.CultureInfo.InvariantCulture"/>
+ format provider. To specify a localized provider use the
+ <see cref="M:log4net.Core.LogImpl.ErrorFormat(System.IFormatProvider,System.String,System.Object[])"/> method.
+ </para>
+ <para>
+ This method does not take an <see cref="T:System.Exception"/> object to include in the
+ log event. To pass an <see cref="T:System.Exception"/> use one of the <see cref="M:log4net.Core.LogImpl.Error(System.Object)"/>
+ methods instead.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LogImpl.ErrorFormat(System.String,System.Object)">
+ <summary>
+ Logs a formatted message string with the <c>ERROR</c> level.
+ </summary>
+ <param name="format">A String containing zero or more format items</param>
+ <param name="arg0">An Object to format</param>
+ <remarks>
+ <para>
+ The message is formatted using the <see cref="M:System.String.Format(System.IFormatProvider,System.String,System.Object[])"/> method. See
+ <c>String.Format</c> for details of the syntax of the format string and the behavior
+ of the formatting.
+ </para>
+ <para>
+ The string is formatted using the <see cref="P:System.Globalization.CultureInfo.InvariantCulture"/>
+ format provider. To specify a localized provider use the
+ <see cref="M:log4net.Core.LogImpl.ErrorFormat(System.IFormatProvider,System.String,System.Object[])"/> method.
+ </para>
+ <para>
+ This method does not take an <see cref="T:System.Exception"/> object to include in the
+ log event. To pass an <see cref="T:System.Exception"/> use one of the <see cref="M:log4net.Core.LogImpl.Error(System.Object)"/>
+ methods instead.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LogImpl.ErrorFormat(System.String,System.Object,System.Object)">
+ <summary>
+ Logs a formatted message string with the <c>ERROR</c> level.
+ </summary>
+ <param name="format">A String containing zero or more format items</param>
+ <param name="arg0">An Object to format</param>
+ <param name="arg1">An Object to format</param>
+ <remarks>
+ <para>
+ The message is formatted using the <see cref="M:System.String.Format(System.IFormatProvider,System.String,System.Object[])"/> method. See
+ <c>String.Format</c> for details of the syntax of the format string and the behavior
+ of the formatting.
+ </para>
+ <para>
+ The string is formatted using the <see cref="P:System.Globalization.CultureInfo.InvariantCulture"/>
+ format provider. To specify a localized provider use the
+ <see cref="M:log4net.Core.LogImpl.ErrorFormat(System.IFormatProvider,System.String,System.Object[])"/> method.
+ </para>
+ <para>
+ This method does not take an <see cref="T:System.Exception"/> object to include in the
+ log event. To pass an <see cref="T:System.Exception"/> use one of the <see cref="M:log4net.Core.LogImpl.Error(System.Object)"/>
+ methods instead.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LogImpl.ErrorFormat(System.String,System.Object,System.Object,System.Object)">
+ <summary>
+ Logs a formatted message string with the <c>ERROR</c> level.
+ </summary>
+ <param name="format">A String containing zero or more format items</param>
+ <param name="arg0">An Object to format</param>
+ <param name="arg1">An Object to format</param>
+ <param name="arg2">An Object to format</param>
+ <remarks>
+ <para>
+ The message is formatted using the <see cref="M:System.String.Format(System.IFormatProvider,System.String,System.Object[])"/> method. See
+ <c>String.Format</c> for details of the syntax of the format string and the behavior
+ of the formatting.
+ </para>
+ <para>
+ The string is formatted using the <see cref="P:System.Globalization.CultureInfo.InvariantCulture"/>
+ format provider. To specify a localized provider use the
+ <see cref="M:log4net.Core.LogImpl.ErrorFormat(System.IFormatProvider,System.String,System.Object[])"/> method.
+ </para>
+ <para>
+ This method does not take an <see cref="T:System.Exception"/> object to include in the
+ log event. To pass an <see cref="T:System.Exception"/> use one of the <see cref="M:log4net.Core.LogImpl.Error(System.Object)"/>
+ methods instead.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LogImpl.ErrorFormat(System.IFormatProvider,System.String,System.Object[])">
+ <summary>
+ Logs a formatted message string with the <c>ERROR</c> level.
+ </summary>
+ <param name="provider">An <see cref="T:System.IFormatProvider"/> that supplies culture-specific formatting information</param>
+ <param name="format">A String containing zero or more format items</param>
+ <param name="args">An Object array containing zero or more objects to format</param>
+ <remarks>
+ <para>
+ The message is formatted using the <see cref="M:System.String.Format(System.IFormatProvider,System.String,System.Object[])"/> method. See
+ <c>String.Format</c> for details of the syntax of the format string and the behavior
+ of the formatting.
+ </para>
+ <para>
+ This method does not take an <see cref="T:System.Exception"/> object to include in the
+ log event. To pass an <see cref="T:System.Exception"/> use one of the <see cref="M:log4net.Core.LogImpl.Error(System.Object)"/>
+ methods instead.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LogImpl.Fatal(System.Object)">
+ <summary>
+ Logs a message object with the <c>FATAL</c> level.
+ </summary>
+ <param name="message">The message object to log.</param>
+ <remarks>
+ <para>
+ This method first checks if this logger is <c>FATAL</c>
+ enabled by comparing the level of this logger with the
+ <c>FATAL</c> level. If this logger is
+ <c>FATAL</c> enabled, then it converts the message object
+ (passed as parameter) to a string by invoking the appropriate
+ <see cref="T:log4net.ObjectRenderer.IObjectRenderer"/>. It then
+ proceeds to call all the registered appenders in this logger and
+ also higher in the hierarchy depending on the value of the
+ additivity flag.
+ </para>
+ <para>
+ <b>WARNING</b> Note that passing an <see cref="T:System.Exception"/> to this
+ method will print the name of the <see cref="T:System.Exception"/> but no
+ stack trace. To print a stack trace use the
+ <see cref="M:log4net.Core.LogImpl.Fatal(System.Object,System.Exception)"/> form instead.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LogImpl.Fatal(System.Object,System.Exception)">
+ <summary>
+ Logs a message object with the <c>FATAL</c> level
+ </summary>
+ <param name="message">The message object to log.</param>
+ <param name="exception">The exception to log, including its stack trace.</param>
+ <remarks>
+ <para>
+ Logs a message object with the <c>FATAL</c> level including
+ the stack trace of the <see cref="T:System.Exception"/> <paramref name="exception"/>
+ passed as a parameter.
+ </para>
+ <para>
+ See the <see cref="M:log4net.Core.LogImpl.Fatal(System.Object)"/> form for more detailed information.
+ </para>
+ </remarks>
+ <seealso cref="M:log4net.Core.LogImpl.Fatal(System.Object)"/>
+ </member>
+ <member name="M:log4net.Core.LogImpl.FatalFormat(System.String,System.Object[])">
+ <summary>
+ Logs a formatted message string with the <c>FATAL</c> level.
+ </summary>
+ <param name="format">A String containing zero or more format items</param>
+ <param name="args">An Object array containing zero or more objects to format</param>
+ <remarks>
+ <para>
+ The message is formatted using the <see cref="M:System.String.Format(System.IFormatProvider,System.String,System.Object[])"/> method. See
+ <c>String.Format</c> for details of the syntax of the format string and the behavior
+ of the formatting.
+ </para>
+ <para>
+ The string is formatted using the <see cref="P:System.Globalization.CultureInfo.InvariantCulture"/>
+ format provider. To specify a localized provider use the
+ <see cref="M:log4net.Core.LogImpl.FatalFormat(System.IFormatProvider,System.String,System.Object[])"/> method.
+ </para>
+ <para>
+ This method does not take an <see cref="T:System.Exception"/> object to include in the
+ log event. To pass an <see cref="T:System.Exception"/> use one of the <see cref="M:log4net.Core.LogImpl.Fatal(System.Object)"/>
+ methods instead.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LogImpl.FatalFormat(System.String,System.Object)">
+ <summary>
+ Logs a formatted message string with the <c>FATAL</c> level.
+ </summary>
+ <param name="format">A String containing zero or more format items</param>
+ <param name="arg0">An Object to format</param>
+ <remarks>
+ <para>
+ The message is formatted using the <see cref="M:System.String.Format(System.IFormatProvider,System.String,System.Object[])"/> method. See
+ <c>String.Format</c> for details of the syntax of the format string and the behavior
+ of the formatting.
+ </para>
+ <para>
+ The string is formatted using the <see cref="P:System.Globalization.CultureInfo.InvariantCulture"/>
+ format provider. To specify a localized provider use the
+ <see cref="M:log4net.Core.LogImpl.FatalFormat(System.IFormatProvider,System.String,System.Object[])"/> method.
+ </para>
+ <para>
+ This method does not take an <see cref="T:System.Exception"/> object to include in the
+ log event. To pass an <see cref="T:System.Exception"/> use one of the <see cref="M:log4net.Core.LogImpl.Fatal(System.Object)"/>
+ methods instead.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LogImpl.FatalFormat(System.String,System.Object,System.Object)">
+ <summary>
+ Logs a formatted message string with the <c>FATAL</c> level.
+ </summary>
+ <param name="format">A String containing zero or more format items</param>
+ <param name="arg0">An Object to format</param>
+ <param name="arg1">An Object to format</param>
+ <remarks>
+ <para>
+ The message is formatted using the <see cref="M:System.String.Format(System.IFormatProvider,System.String,System.Object[])"/> method. See
+ <c>String.Format</c> for details of the syntax of the format string and the behavior
+ of the formatting.
+ </para>
+ <para>
+ The string is formatted using the <see cref="P:System.Globalization.CultureInfo.InvariantCulture"/>
+ format provider. To specify a localized provider use the
+ <see cref="M:log4net.Core.LogImpl.FatalFormat(System.IFormatProvider,System.String,System.Object[])"/> method.
+ </para>
+ <para>
+ This method does not take an <see cref="T:System.Exception"/> object to include in the
+ log event. To pass an <see cref="T:System.Exception"/> use one of the <see cref="M:log4net.Core.LogImpl.Fatal(System.Object)"/>
+ methods instead.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LogImpl.FatalFormat(System.String,System.Object,System.Object,System.Object)">
+ <summary>
+ Logs a formatted message string with the <c>FATAL</c> level.
+ </summary>
+ <param name="format">A String containing zero or more format items</param>
+ <param name="arg0">An Object to format</param>
+ <param name="arg1">An Object to format</param>
+ <param name="arg2">An Object to format</param>
+ <remarks>
+ <para>
+ The message is formatted using the <see cref="M:System.String.Format(System.IFormatProvider,System.String,System.Object[])"/> method. See
+ <c>String.Format</c> for details of the syntax of the format string and the behavior
+ of the formatting.
+ </para>
+ <para>
+ The string is formatted using the <see cref="P:System.Globalization.CultureInfo.InvariantCulture"/>
+ format provider. To specify a localized provider use the
+ <see cref="M:log4net.Core.LogImpl.FatalFormat(System.IFormatProvider,System.String,System.Object[])"/> method.
+ </para>
+ <para>
+ This method does not take an <see cref="T:System.Exception"/> object to include in the
+ log event. To pass an <see cref="T:System.Exception"/> use one of the <see cref="M:log4net.Core.LogImpl.Fatal(System.Object)"/>
+ methods instead.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LogImpl.FatalFormat(System.IFormatProvider,System.String,System.Object[])">
+ <summary>
+ Logs a formatted message string with the <c>FATAL</c> level.
+ </summary>
+ <param name="provider">An <see cref="T:System.IFormatProvider"/> that supplies culture-specific formatting information</param>
+ <param name="format">A String containing zero or more format items</param>
+ <param name="args">An Object array containing zero or more objects to format</param>
+ <remarks>
+ <para>
+ The message is formatted using the <see cref="M:System.String.Format(System.IFormatProvider,System.String,System.Object[])"/> method. See
+ <c>String.Format</c> for details of the syntax of the format string and the behavior
+ of the formatting.
+ </para>
+ <para>
+ This method does not take an <see cref="T:System.Exception"/> object to include in the
+ log event. To pass an <see cref="T:System.Exception"/> use one of the <see cref="M:log4net.Core.LogImpl.Fatal(System.Object)"/>
+ methods instead.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LogImpl.LoggerRepositoryConfigurationChanged(System.Object,System.EventArgs)">
+ <summary>
+ Event handler for the <see cref="E:log4net.Repository.ILoggerRepository.ConfigurationChanged"/> event
+ </summary>
+ <param name="sender">the repository</param>
+ <param name="e">Empty</param>
+ </member>
+ <member name="F:log4net.Core.LogImpl.ThisDeclaringType">
+ <summary>
+ The fully qualified name of this declaring type not the type of any subclass.
+ </summary>
+ </member>
+ <member name="P:log4net.Core.LogImpl.IsDebugEnabled">
+ <summary>
+ Checks if this logger is enabled for the <c>DEBUG</c>
+ level.
+ </summary>
+ <value>
+ <c>true</c> if this logger is enabled for <c>DEBUG</c> events,
+ <c>false</c> otherwise.
+ </value>
+ <remarks>
+ <para>
+ This function is intended to lessen the computational cost of
+ disabled log debug statements.
+ </para>
+ <para>
+ For some <c>log</c> Logger object, when you write:
+ </para>
+ <code lang="C#">
+ log.Debug("This is entry number: " + i );
+ </code>
+ <para>
+ You incur the cost constructing the message, concatenation in
+ this case, regardless of whether the message is logged or not.
+ </para>
+ <para>
+ If you are worried about speed, then you should write:
+ </para>
+ <code lang="C#">
+ if (log.IsDebugEnabled())
+ {
+ log.Debug("This is entry number: " + i );
+ }
+ </code>
+ <para>
+ This way you will not incur the cost of parameter
+ construction if debugging is disabled for <c>log</c>. On
+ the other hand, if the <c>log</c> is debug enabled, you
+ will incur the cost of evaluating whether the logger is debug
+ enabled twice. Once in <c>IsDebugEnabled</c> and once in
+ the <c>Debug</c>. This is an insignificant overhead
+ since evaluating a logger takes about 1% of the time it
+ takes to actually log.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Core.LogImpl.IsInfoEnabled">
+ <summary>
+ Checks if this logger is enabled for the <c>INFO</c> level.
+ </summary>
+ <value>
+ <c>true</c> if this logger is enabled for <c>INFO</c> events,
+ <c>false</c> otherwise.
+ </value>
+ <remarks>
+ <para>
+ See <see cref="P:log4net.Core.LogImpl.IsDebugEnabled"/> for more information and examples
+ of using this method.
+ </para>
+ </remarks>
+ <seealso cref="P:log4net.Core.LogImpl.IsDebugEnabled"/>
+ </member>
+ <member name="P:log4net.Core.LogImpl.IsWarnEnabled">
+ <summary>
+ Checks if this logger is enabled for the <c>WARN</c> level.
+ </summary>
+ <value>
+ <c>true</c> if this logger is enabled for <c>WARN</c> events,
+ <c>false</c> otherwise.
+ </value>
+ <remarks>
+ <para>
+ See <see cref="P:log4net.Core.LogImpl.IsDebugEnabled"/> for more information and examples
+ of using this method.
+ </para>
+ </remarks>
+ <seealso cref="P:log4net.ILog.IsDebugEnabled"/>
+ </member>
+ <member name="P:log4net.Core.LogImpl.IsErrorEnabled">
+ <summary>
+ Checks if this logger is enabled for the <c>ERROR</c> level.
+ </summary>
+ <value>
+ <c>true</c> if this logger is enabled for <c>ERROR</c> events,
+ <c>false</c> otherwise.
+ </value>
+ <remarks>
+ <para>
+ See <see cref="P:log4net.Core.LogImpl.IsDebugEnabled"/> for more information and examples of using this method.
+ </para>
+ </remarks>
+ <seealso cref="P:log4net.ILog.IsDebugEnabled"/>
+ </member>
+ <member name="P:log4net.Core.LogImpl.IsFatalEnabled">
+ <summary>
+ Checks if this logger is enabled for the <c>FATAL</c> level.
+ </summary>
+ <value>
+ <c>true</c> if this logger is enabled for <c>FATAL</c> events,
+ <c>false</c> otherwise.
+ </value>
+ <remarks>
+ <para>
+ See <see cref="P:log4net.Core.LogImpl.IsDebugEnabled"/> for more information and examples of using this method.
+ </para>
+ </remarks>
+ <seealso cref="P:log4net.ILog.IsDebugEnabled"/>
+ </member>
+ <member name="T:log4net.Core.SecurityContext">
+ <summary>
+ A SecurityContext used by log4net when interacting with protected resources
+ </summary>
+ <remarks>
+ <para>
+ A SecurityContext used by log4net when interacting with protected resources
+ for example with operating system services. This can be used to impersonate
+ a principal that has been granted privileges on the system resources.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="M:log4net.Core.SecurityContext.Impersonate(System.Object)">
+ <summary>
+ Impersonate this SecurityContext
+ </summary>
+ <param name="state">State supplied by the caller</param>
+ <returns>An <see cref="T:System.IDisposable"/> instance that will
+ revoke the impersonation of this SecurityContext, or <c>null</c></returns>
+ <remarks>
+ <para>
+ Impersonate this security context. Further calls on the current
+ thread should now be made in the security context provided
+ by this object. When the <see cref="T:System.IDisposable"/> result
+ <see cref="M:System.IDisposable.Dispose"/> method is called the security
+ context of the thread should be reverted to the state it was in
+ before <see cref="M:log4net.Core.SecurityContext.Impersonate(System.Object)"/> was called.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Core.SecurityContextProvider">
+ <summary>
+ The <see cref="T:log4net.Core.SecurityContextProvider"/> providers default <see cref="T:log4net.Core.SecurityContext"/> instances.
+ </summary>
+ <remarks>
+ <para>
+ A configured component that interacts with potentially protected system
+ resources uses a <see cref="T:log4net.Core.SecurityContext"/> to provide the elevated
+ privileges required. If the <see cref="T:log4net.Core.SecurityContext"/> object has
+ been not been explicitly provided to the component then the component
+ will request one from this <see cref="T:log4net.Core.SecurityContextProvider"/>.
+ </para>
+ <para>
+ By default the <see cref="P:log4net.Core.SecurityContextProvider.DefaultProvider"/> is
+ an instance of <see cref="T:log4net.Core.SecurityContextProvider"/> which returns only
+ <see cref="T:log4net.Util.NullSecurityContext"/> objects. This is a reasonable default
+ where the privileges required are not know by the system.
+ </para>
+ <para>
+ This default behavior can be overridden by subclassing the <see cref="T:log4net.Core.SecurityContextProvider"/>
+ and overriding the <see cref="M:log4net.Core.SecurityContextProvider.CreateSecurityContext(System.Object)"/> method to return
+ the desired <see cref="T:log4net.Core.SecurityContext"/> objects. The default provider
+ can be replaced by programmatically setting the value of the
+ <see cref="P:log4net.Core.SecurityContextProvider.DefaultProvider"/> property.
+ </para>
+ <para>
+ An alternative is to use the <c>log4net.Config.SecurityContextProviderAttribute</c>
+ This attribute can be applied to an assembly in the same way as the
+ <c>log4net.Config.XmlConfiguratorAttribute"</c>. The attribute takes
+ the type to use as the <see cref="T:log4net.Core.SecurityContextProvider"/> as an argument.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="F:log4net.Core.SecurityContextProvider.s_defaultProvider">
+ <summary>
+ The default provider
+ </summary>
+ </member>
+ <member name="M:log4net.Core.SecurityContextProvider.#ctor">
+ <summary>
+ Protected default constructor to allow subclassing
+ </summary>
+ <remarks>
+ <para>
+ Protected default constructor to allow subclassing
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.SecurityContextProvider.CreateSecurityContext(System.Object)">
+ <summary>
+ Create a SecurityContext for a consumer
+ </summary>
+ <param name="consumer">The consumer requesting the SecurityContext</param>
+ <returns>An impersonation context</returns>
+ <remarks>
+ <para>
+ The default implementation is to return a <see cref="T:log4net.Util.NullSecurityContext"/>.
+ </para>
+ <para>
+ Subclasses should override this method to provide their own
+ behavior.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Core.SecurityContextProvider.DefaultProvider">
+ <summary>
+ Gets or sets the default SecurityContextProvider
+ </summary>
+ <value>
+ The default SecurityContextProvider
+ </value>
+ <remarks>
+ <para>
+ The default provider is used by configured components that
+ require a <see cref="T:log4net.Core.SecurityContext"/> and have not had one
+ given to them.
+ </para>
+ <para>
+ By default this is an instance of <see cref="T:log4net.Core.SecurityContextProvider"/>
+ that returns <see cref="T:log4net.Util.NullSecurityContext"/> objects.
+ </para>
+ <para>
+ The default provider can be set programmatically by setting
+ the value of this property to a sub class of <see cref="T:log4net.Core.SecurityContextProvider"/>
+ that has the desired behavior.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Core.WrapperCreationHandler">
+ <summary>
+ Delegate used to handle creation of new wrappers.
+ </summary>
+ <param name="logger">The logger to wrap in a wrapper.</param>
+ <remarks>
+ <para>
+ Delegate used to handle creation of new wrappers. This delegate
+ is called from the <see cref="M:log4net.Core.WrapperMap.CreateNewWrapperObject(log4net.Core.ILogger)"/>
+ method to construct the wrapper for the specified logger.
+ </para>
+ <para>
+ The delegate to use is supplied to the <see cref="T:log4net.Core.WrapperMap"/>
+ constructor.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Core.WrapperMap">
+ <summary>
+ Maps between logger objects and wrapper objects.
+ </summary>
+ <remarks>
+ <para>
+ This class maintains a mapping between <see cref="T:log4net.Core.ILogger"/> objects and
+ <see cref="T:log4net.Core.ILoggerWrapper"/> objects. Use the <see cref="M:log4net.Core.WrapperMap.GetWrapper(log4net.Core.ILogger)"/> method to
+ lookup the <see cref="T:log4net.Core.ILoggerWrapper"/> for the specified <see cref="T:log4net.Core.ILogger"/>.
+ </para>
+ <para>
+ New wrapper instances are created by the <see cref="M:log4net.Core.WrapperMap.CreateNewWrapperObject(log4net.Core.ILogger)"/>
+ method. The default behavior is for this method to delegate construction
+ of the wrapper to the <see cref="T:log4net.Core.WrapperCreationHandler"/> delegate supplied
+ to the constructor. This allows specialization of the behavior without
+ requiring subclassing of this type.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="M:log4net.Core.WrapperMap.#ctor(log4net.Core.WrapperCreationHandler)">
+ <summary>
+ Initializes a new instance of the <see cref="T:log4net.Core.WrapperMap"/>
+ </summary>
+ <param name="createWrapperHandler">The handler to use to create the wrapper objects.</param>
+ <remarks>
+ <para>
+ Initializes a new instance of the <see cref="T:log4net.Core.WrapperMap"/> class with
+ the specified handler to create the wrapper objects.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.WrapperMap.GetWrapper(log4net.Core.ILogger)">
+ <summary>
+ Gets the wrapper object for the specified logger.
+ </summary>
+ <returns>The wrapper object for the specified logger</returns>
+ <remarks>
+ <para>
+ If the logger is null then the corresponding wrapper is null.
+ </para>
+ <para>
+ Looks up the wrapper it it has previously been requested and
+ returns it. If the wrapper has never been requested before then
+ the <see cref="M:log4net.Core.WrapperMap.CreateNewWrapperObject(log4net.Core.ILogger)"/> virtual method is
+ called.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.WrapperMap.CreateNewWrapperObject(log4net.Core.ILogger)">
+ <summary>
+ Creates the wrapper object for the specified logger.
+ </summary>
+ <param name="logger">The logger to wrap in a wrapper.</param>
+ <returns>The wrapper object for the logger.</returns>
+ <remarks>
+ <para>
+ This implementation uses the <see cref="T:log4net.Core.WrapperCreationHandler"/>
+ passed to the constructor to create the wrapper. This method
+ can be overridden in a subclass.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.WrapperMap.RepositoryShutdown(log4net.Repository.ILoggerRepository)">
+ <summary>
+ Called when a monitored repository shutdown event is received.
+ </summary>
+ <param name="repository">The <see cref="T:log4net.Repository.ILoggerRepository"/> that is shutting down</param>
+ <remarks>
+ <para>
+ This method is called when a <see cref="T:log4net.Repository.ILoggerRepository"/> that this
+ <see cref="T:log4net.Core.WrapperMap"/> is holding loggers for has signaled its shutdown
+ event <see cref="E:log4net.Repository.ILoggerRepository.ShutdownEvent"/>. The default
+ behavior of this method is to release the references to the loggers
+ and their wrappers generated for this repository.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.WrapperMap.ILoggerRepository_Shutdown(System.Object,System.EventArgs)">
+ <summary>
+ Event handler for repository shutdown event.
+ </summary>
+ <param name="sender">The sender of the event.</param>
+ <param name="e">The event args.</param>
+ </member>
+ <member name="F:log4net.Core.WrapperMap.m_repositories">
+ <summary>
+ Map of logger repositories to hashtables of ILogger to ILoggerWrapper mappings
+ </summary>
+ </member>
+ <member name="F:log4net.Core.WrapperMap.m_createWrapperHandler">
+ <summary>
+ The handler to use to create the extension wrapper objects.
+ </summary>
+ </member>
+ <member name="F:log4net.Core.WrapperMap.m_shutdownHandler">
+ <summary>
+ Internal reference to the delegate used to register for repository shutdown events.
+ </summary>
+ </member>
+ <member name="P:log4net.Core.WrapperMap.Repositories">
+ <summary>
+ Gets the map of logger repositories.
+ </summary>
+ <value>
+ Map of logger repositories.
+ </value>
+ <remarks>
+ <para>
+ Gets the hashtable that is keyed on <see cref="T:log4net.Repository.ILoggerRepository"/>. The
+ values are hashtables keyed on <see cref="T:log4net.Core.ILogger"/> with the
+ value being the corresponding <see cref="T:log4net.Core.ILoggerWrapper"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.DateFormatter.AbsoluteTimeDateFormatter">
+ <summary>
+ Formats a <see cref="T:System.DateTime"/> as <c>"HH:mm:ss,fff"</c>.
+ </summary>
+ <remarks>
+ <para>
+ Formats a <see cref="T:System.DateTime"/> in the format <c>"HH:mm:ss,fff"</c> for example, <c>"15:49:37,459"</c>.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="T:log4net.DateFormatter.IDateFormatter">
+ <summary>
+ Render a <see cref="T:System.DateTime"/> as a string.
+ </summary>
+ <remarks>
+ <para>
+ Interface to abstract the rendering of a <see cref="T:System.DateTime"/>
+ instance into a string.
+ </para>
+ <para>
+ The <see cref="M:log4net.DateFormatter.IDateFormatter.FormatDate(System.DateTime,System.IO.TextWriter)"/> method is used to render the
+ date to a text writer.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="M:log4net.DateFormatter.IDateFormatter.FormatDate(System.DateTime,System.IO.TextWriter)">
+ <summary>
+ Formats the specified date as a string.
+ </summary>
+ <param name="dateToFormat">The date to format.</param>
+ <param name="writer">The writer to write to.</param>
+ <remarks>
+ <para>
+ Format the <see cref="T:System.DateTime"/> as a string and write it
+ to the <see cref="T:System.IO.TextWriter"/> provided.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.DateFormatter.AbsoluteTimeDateFormatter.AbsoluteTimeDateFormat">
+ <summary>
+ String constant used to specify AbsoluteTimeDateFormat in layouts. Current value is <b>ABSOLUTE</b>.
+ </summary>
+ </member>
+ <member name="F:log4net.DateFormatter.AbsoluteTimeDateFormatter.DateAndTimeDateFormat">
+ <summary>
+ String constant used to specify DateTimeDateFormat in layouts. Current value is <b>DATE</b>.
+ </summary>
+ </member>
+ <member name="F:log4net.DateFormatter.AbsoluteTimeDateFormatter.Iso8601TimeDateFormat">
+ <summary>
+ String constant used to specify ISO8601DateFormat in layouts. Current value is <b>ISO8601</b>.
+ </summary>
+ </member>
+ <member name="M:log4net.DateFormatter.AbsoluteTimeDateFormatter.FormatDateWithoutMillis(System.DateTime,System.Text.StringBuilder)">
+ <summary>
+ Renders the date into a string. Format is <c>"HH:mm:ss"</c>.
+ </summary>
+ <param name="dateToFormat">The date to render into a string.</param>
+ <param name="buffer">The string builder to write to.</param>
+ <remarks>
+ <para>
+ Subclasses should override this method to render the date
+ into a string using a precision up to the second. This method
+ will be called at most once per second and the result will be
+ reused if it is needed again during the same second.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.DateFormatter.AbsoluteTimeDateFormatter.FormatDate(System.DateTime,System.IO.TextWriter)">
+ <summary>
+ Renders the date into a string. Format is "HH:mm:ss,fff".
+ </summary>
+ <param name="dateToFormat">The date to render into a string.</param>
+ <param name="writer">The writer to write to.</param>
+ <remarks>
+ <para>
+ Uses the <see cref="M:log4net.DateFormatter.AbsoluteTimeDateFormatter.FormatDateWithoutMillis(System.DateTime,System.Text.StringBuilder)"/> method to generate the
+ time string up to the seconds and then appends the current
+ milliseconds. The results from <see cref="M:log4net.DateFormatter.AbsoluteTimeDateFormatter.FormatDateWithoutMillis(System.DateTime,System.Text.StringBuilder)"/> are
+ cached and <see cref="M:log4net.DateFormatter.AbsoluteTimeDateFormatter.FormatDateWithoutMillis(System.DateTime,System.Text.StringBuilder)"/> is called at most once
+ per second.
+ </para>
+ <para>
+ Sub classes should override <see cref="M:log4net.DateFormatter.AbsoluteTimeDateFormatter.FormatDateWithoutMillis(System.DateTime,System.Text.StringBuilder)"/>
+ rather than <see cref="M:log4net.DateFormatter.AbsoluteTimeDateFormatter.FormatDate(System.DateTime,System.IO.TextWriter)"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.DateFormatter.AbsoluteTimeDateFormatter.s_lastTimeToTheSecond">
+ <summary>
+ Last stored time with precision up to the second.
+ </summary>
+ </member>
+ <member name="F:log4net.DateFormatter.AbsoluteTimeDateFormatter.s_lastTimeBuf">
+ <summary>
+ Last stored time with precision up to the second, formatted
+ as a string.
+ </summary>
+ </member>
+ <member name="F:log4net.DateFormatter.AbsoluteTimeDateFormatter.s_lastTimeString">
+ <summary>
+ Last stored time with precision up to the second, formatted
+ as a string.
+ </summary>
+ </member>
+ <member name="T:log4net.DateFormatter.DateTimeDateFormatter">
+ <summary>
+ Formats a <see cref="T:System.DateTime"/> as <c>"dd MMM yyyy HH:mm:ss,fff"</c>
+ </summary>
+ <remarks>
+ <para>
+ Formats a <see cref="T:System.DateTime"/> in the format
+ <c>"dd MMM yyyy HH:mm:ss,fff"</c> for example,
+ <c>"06 Nov 1994 15:49:37,459"</c>.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ <author>Angelika Schnagl</author>
+ </member>
+ <member name="M:log4net.DateFormatter.DateTimeDateFormatter.#ctor">
+ <summary>
+ Default constructor.
+ </summary>
+ <remarks>
+ <para>
+ Initializes a new instance of the <see cref="T:log4net.DateFormatter.DateTimeDateFormatter"/> class.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.DateFormatter.DateTimeDateFormatter.FormatDateWithoutMillis(System.DateTime,System.Text.StringBuilder)">
+ <summary>
+ Formats the date without the milliseconds part
+ </summary>
+ <param name="dateToFormat">The date to format.</param>
+ <param name="buffer">The string builder to write to.</param>
+ <remarks>
+ <para>
+ Formats a DateTime in the format <c>"dd MMM yyyy HH:mm:ss"</c>
+ for example, <c>"06 Nov 1994 15:49:37"</c>.
+ </para>
+ <para>
+ The base class will append the <c>",fff"</c> milliseconds section.
+ This method will only be called at most once per second.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.DateFormatter.DateTimeDateFormatter.m_dateTimeFormatInfo">
+ <summary>
+ The format info for the invariant culture.
+ </summary>
+ </member>
+ <member name="T:log4net.DateFormatter.Iso8601DateFormatter">
+ <summary>
+ Formats the <see cref="T:System.DateTime"/> as <c>"yyyy-MM-dd HH:mm:ss,fff"</c>.
+ </summary>
+ <remarks>
+ <para>
+ Formats the <see cref="T:System.DateTime"/> specified as a string: <c>"yyyy-MM-dd HH:mm:ss,fff"</c>.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="M:log4net.DateFormatter.Iso8601DateFormatter.#ctor">
+ <summary>
+ Default constructor
+ </summary>
+ <remarks>
+ <para>
+ Initializes a new instance of the <see cref="T:log4net.DateFormatter.Iso8601DateFormatter"/> class.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.DateFormatter.Iso8601DateFormatter.FormatDateWithoutMillis(System.DateTime,System.Text.StringBuilder)">
+ <summary>
+ Formats the date without the milliseconds part
+ </summary>
+ <param name="dateToFormat">The date to format.</param>
+ <param name="buffer">The string builder to write to.</param>
+ <remarks>
+ <para>
+ Formats the date specified as a string: <c>"yyyy-MM-dd HH:mm:ss"</c>.
+ </para>
+ <para>
+ The base class will append the <c>",fff"</c> milliseconds section.
+ This method will only be called at most once per second.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.DateFormatter.SimpleDateFormatter">
+ <summary>
+ Formats the <see cref="T:System.DateTime"/> using the <see cref="M:System.DateTime.ToString(System.String,System.IFormatProvider)"/> method.
+ </summary>
+ <remarks>
+ <para>
+ Formats the <see cref="T:System.DateTime"/> using the <see cref="T:System.DateTime"/> <see cref="M:System.DateTime.ToString(System.String,System.IFormatProvider)"/> method.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="M:log4net.DateFormatter.SimpleDateFormatter.#ctor(System.String)">
+ <summary>
+ Constructor
+ </summary>
+ <param name="format">The format string.</param>
+ <remarks>
+ <para>
+ Initializes a new instance of the <see cref="T:log4net.DateFormatter.SimpleDateFormatter"/> class
+ with the specified format string.
+ </para>
+ <para>
+ The format string must be compatible with the options
+ that can be supplied to <see cref="M:System.DateTime.ToString(System.String,System.IFormatProvider)"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.DateFormatter.SimpleDateFormatter.FormatDate(System.DateTime,System.IO.TextWriter)">
+ <summary>
+ Formats the date using <see cref="M:System.DateTime.ToString(System.String,System.IFormatProvider)"/>.
+ </summary>
+ <param name="dateToFormat">The date to convert to a string.</param>
+ <param name="writer">The writer to write to.</param>
+ <remarks>
+ <para>
+ Uses the date format string supplied to the constructor to call
+ the <see cref="M:System.DateTime.ToString(System.String,System.IFormatProvider)"/> method to format the date.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.DateFormatter.SimpleDateFormatter.m_formatString">
+ <summary>
+ The format string used to format the <see cref="T:System.DateTime"/>.
+ </summary>
+ <remarks>
+ <para>
+ The format string must be compatible with the options
+ that can be supplied to <see cref="M:System.DateTime.ToString(System.String,System.IFormatProvider)"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Filter.DenyAllFilter">
+ <summary>
+ This filter drops all <see cref="T:log4net.Core.LoggingEvent"/>.
+ </summary>
+ <remarks>
+ <para>
+ You can add this filter to the end of a filter chain to
+ switch from the default "accept all unless instructed otherwise"
+ filtering behavior to a "deny all unless instructed otherwise"
+ behavior.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="T:log4net.Filter.FilterSkeleton">
+ <summary>
+ Subclass this type to implement customized logging event filtering
+ </summary>
+ <remarks>
+ <para>
+ Users should extend this class to implement customized logging
+ event filtering. Note that <see cref="T:log4net.Repository.Hierarchy.Logger"/> and
+ <see cref="T:log4net.Appender.AppenderSkeleton"/>, the parent class of all standard
+ appenders, have built-in filtering rules. It is suggested that you
+ first use and understand the built-in rules before rushing to write
+ your own custom filters.
+ </para>
+ <para>
+ This abstract class assumes and also imposes that filters be
+ organized in a linear chain. The <see cref="M:log4net.Filter.FilterSkeleton.Decide(log4net.Core.LoggingEvent)"/>
+ method of each filter is called sequentially, in the order of their
+ addition to the chain.
+ </para>
+ <para>
+ The <see cref="M:log4net.Filter.FilterSkeleton.Decide(log4net.Core.LoggingEvent)"/> method must return one
+ of the integer constants <see cref="F:log4net.Filter.FilterDecision.Deny"/>,
+ <see cref="F:log4net.Filter.FilterDecision.Neutral"/> or <see cref="F:log4net.Filter.FilterDecision.Accept"/>.
+ </para>
+ <para>
+ If the value <see cref="F:log4net.Filter.FilterDecision.Deny"/> is returned, then the log event is dropped
+ immediately without consulting with the remaining filters.
+ </para>
+ <para>
+ If the value <see cref="F:log4net.Filter.FilterDecision.Neutral"/> is returned, then the next filter
+ in the chain is consulted. If there are no more filters in the
+ chain, then the log event is logged. Thus, in the presence of no
+ filters, the default behavior is to log all logging events.
+ </para>
+ <para>
+ If the value <see cref="F:log4net.Filter.FilterDecision.Accept"/> is returned, then the log
+ event is logged without consulting the remaining filters.
+ </para>
+ <para>
+ The philosophy of log4net filters is largely inspired from the
+ Linux ipchains.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="T:log4net.Filter.IFilter">
+ <summary>
+ Implement this interface to provide customized logging event filtering
+ </summary>
+ <remarks>
+ <para>
+ Users should implement this interface to implement customized logging
+ event filtering. Note that <see cref="T:log4net.Repository.Hierarchy.Logger"/> and
+ <see cref="T:log4net.Appender.AppenderSkeleton"/>, the parent class of all standard
+ appenders, have built-in filtering rules. It is suggested that you
+ first use and understand the built-in rules before rushing to write
+ your own custom filters.
+ </para>
+ <para>
+ This abstract class assumes and also imposes that filters be
+ organized in a linear chain. The <see cref="M:log4net.Filter.IFilter.Decide(log4net.Core.LoggingEvent)"/>
+ method of each filter is called sequentially, in the order of their
+ addition to the chain.
+ </para>
+ <para>
+ The <see cref="M:log4net.Filter.IFilter.Decide(log4net.Core.LoggingEvent)"/> method must return one
+ of the integer constants <see cref="F:log4net.Filter.FilterDecision.Deny"/>,
+ <see cref="F:log4net.Filter.FilterDecision.Neutral"/> or <see cref="F:log4net.Filter.FilterDecision.Accept"/>.
+ </para>
+ <para>
+ If the value <see cref="F:log4net.Filter.FilterDecision.Deny"/> is returned, then the log event is dropped
+ immediately without consulting with the remaining filters.
+ </para>
+ <para>
+ If the value <see cref="F:log4net.Filter.FilterDecision.Neutral"/> is returned, then the next filter
+ in the chain is consulted. If there are no more filters in the
+ chain, then the log event is logged. Thus, in the presence of no
+ filters, the default behavior is to log all logging events.
+ </para>
+ <para>
+ If the value <see cref="F:log4net.Filter.FilterDecision.Accept"/> is returned, then the log
+ event is logged without consulting the remaining filters.
+ </para>
+ <para>
+ The philosophy of log4net filters is largely inspired from the
+ Linux ipchains.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="M:log4net.Filter.IFilter.Decide(log4net.Core.LoggingEvent)">
+ <summary>
+ Decide if the logging event should be logged through an appender.
+ </summary>
+ <param name="loggingEvent">The LoggingEvent to decide upon</param>
+ <returns>The decision of the filter</returns>
+ <remarks>
+ <para>
+ If the decision is <see cref="F:log4net.Filter.FilterDecision.Deny"/>, then the event will be
+ dropped. If the decision is <see cref="F:log4net.Filter.FilterDecision.Neutral"/>, then the next
+ filter, if any, will be invoked. If the decision is <see cref="F:log4net.Filter.FilterDecision.Accept"/> then
+ the event will be logged without consulting with other filters in
+ the chain.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Filter.IFilter.Next">
+ <summary>
+ Property to get and set the next filter
+ </summary>
+ <value>
+ The next filter in the chain
+ </value>
+ <remarks>
+ <para>
+ Filters are typically composed into chains. This property allows the next filter in
+ the chain to be accessed.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Filter.FilterSkeleton.m_next">
+ <summary>
+ Points to the next filter in the filter chain.
+ </summary>
+ <remarks>
+ <para>
+ See <see cref="P:log4net.Filter.FilterSkeleton.Next"/> for more information.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Filter.FilterSkeleton.ActivateOptions">
+ <summary>
+ Initialize the filter with the options set
+ </summary>
+ <remarks>
+ <para>
+ This is part of the <see cref="T:log4net.Core.IOptionHandler"/> delayed object
+ activation scheme. The <see cref="M:log4net.Filter.FilterSkeleton.ActivateOptions"/> method must
+ be called on this object after the configuration properties have
+ been set. Until <see cref="M:log4net.Filter.FilterSkeleton.ActivateOptions"/> is called this
+ object is in an undefined state and must not be used.
+ </para>
+ <para>
+ If any of the configuration properties are modified then
+ <see cref="M:log4net.Filter.FilterSkeleton.ActivateOptions"/> must be called again.
+ </para>
+ <para>
+ Typically filter's options become active immediately on set,
+ however this method must still be called.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Filter.FilterSkeleton.Decide(log4net.Core.LoggingEvent)">
+ <summary>
+ Decide if the <see cref="T:log4net.Core.LoggingEvent"/> should be logged through an appender.
+ </summary>
+ <param name="loggingEvent">The <see cref="T:log4net.Core.LoggingEvent"/> to decide upon</param>
+ <returns>The decision of the filter</returns>
+ <remarks>
+ <para>
+ If the decision is <see cref="F:log4net.Filter.FilterDecision.Deny"/>, then the event will be
+ dropped. If the decision is <see cref="F:log4net.Filter.FilterDecision.Neutral"/>, then the next
+ filter, if any, will be invoked. If the decision is <see cref="F:log4net.Filter.FilterDecision.Accept"/> then
+ the event will be logged without consulting with other filters in
+ the chain.
+ </para>
+ <para>
+ This method is marked <c>abstract</c> and must be implemented
+ in a subclass.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Filter.FilterSkeleton.Next">
+ <summary>
+ Property to get and set the next filter
+ </summary>
+ <value>
+ The next filter in the chain
+ </value>
+ <remarks>
+ <para>
+ Filters are typically composed into chains. This property allows the next filter in
+ the chain to be accessed.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Filter.DenyAllFilter.#ctor">
+ <summary>
+ Default constructor
+ </summary>
+ </member>
+ <member name="M:log4net.Filter.DenyAllFilter.Decide(log4net.Core.LoggingEvent)">
+ <summary>
+ Always returns the integer constant <see cref="F:log4net.Filter.FilterDecision.Deny"/>
+ </summary>
+ <param name="loggingEvent">the LoggingEvent to filter</param>
+ <returns>Always returns <see cref="F:log4net.Filter.FilterDecision.Deny"/></returns>
+ <remarks>
+ <para>
+ Ignores the event being logged and just returns
+ <see cref="F:log4net.Filter.FilterDecision.Deny"/>. This can be used to change the default filter
+ chain behavior from <see cref="F:log4net.Filter.FilterDecision.Accept"/> to <see cref="F:log4net.Filter.FilterDecision.Deny"/>. This filter
+ should only be used as the last filter in the chain
+ as any further filters will be ignored!
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Filter.FilterDecision">
+ <summary>
+ The return result from <see cref="M:log4net.Filter.IFilter.Decide(log4net.Core.LoggingEvent)"/>
+ </summary>
+ <remarks>
+ <para>
+ The return result from <see cref="M:log4net.Filter.IFilter.Decide(log4net.Core.LoggingEvent)"/>
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Filter.FilterDecision.Deny">
+ <summary>
+ The log event must be dropped immediately without
+ consulting with the remaining filters, if any, in the chain.
+ </summary>
+ </member>
+ <member name="F:log4net.Filter.FilterDecision.Neutral">
+ <summary>
+ This filter is neutral with respect to the log event.
+ The remaining filters, if any, should be consulted for a final decision.
+ </summary>
+ </member>
+ <member name="F:log4net.Filter.FilterDecision.Accept">
+ <summary>
+ The log event must be logged immediately without
+ consulting with the remaining filters, if any, in the chain.
+ </summary>
+ </member>
+ <member name="T:log4net.Filter.LevelMatchFilter">
+ <summary>
+ This is a very simple filter based on <see cref="T:log4net.Core.Level"/> matching.
+ </summary>
+ <remarks>
+ <para>
+ The filter admits two options <see cref="P:log4net.Filter.LevelMatchFilter.LevelToMatch"/> and
+ <see cref="P:log4net.Filter.LevelMatchFilter.AcceptOnMatch"/>. If there is an exact match between the value
+ of the <see cref="P:log4net.Filter.LevelMatchFilter.LevelToMatch"/> option and the <see cref="T:log4net.Core.Level"/> of the
+ <see cref="T:log4net.Core.LoggingEvent"/>, then the <see cref="M:log4net.Filter.LevelMatchFilter.Decide(log4net.Core.LoggingEvent)"/> method returns <see cref="F:log4net.Filter.FilterDecision.Accept"/> in
+ case the <see cref="P:log4net.Filter.LevelMatchFilter.AcceptOnMatch"/> option value is set
+ to <c>true</c>, if it is <c>false</c> then
+ <see cref="F:log4net.Filter.FilterDecision.Deny"/> is returned. If the <see cref="T:log4net.Core.Level"/> does not match then
+ the result will be <see cref="F:log4net.Filter.FilterDecision.Neutral"/>.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="F:log4net.Filter.LevelMatchFilter.m_acceptOnMatch">
+ <summary>
+ flag to indicate if the filter should <see cref="F:log4net.Filter.FilterDecision.Accept"/> on a match
+ </summary>
+ </member>
+ <member name="F:log4net.Filter.LevelMatchFilter.m_levelToMatch">
+ <summary>
+ the <see cref="T:log4net.Core.Level"/> to match against
+ </summary>
+ </member>
+ <member name="M:log4net.Filter.LevelMatchFilter.#ctor">
+ <summary>
+ Default constructor
+ </summary>
+ </member>
+ <member name="M:log4net.Filter.LevelMatchFilter.Decide(log4net.Core.LoggingEvent)">
+ <summary>
+ Tests if the <see cref="T:log4net.Core.Level"/> of the logging event matches that of the filter
+ </summary>
+ <param name="loggingEvent">the event to filter</param>
+ <returns>see remarks</returns>
+ <remarks>
+ <para>
+ If the <see cref="T:log4net.Core.Level"/> of the event matches the level of the
+ filter then the result of the function depends on the
+ value of <see cref="P:log4net.Filter.LevelMatchFilter.AcceptOnMatch"/>. If it is true then
+ the function will return <see cref="F:log4net.Filter.FilterDecision.Accept"/>, it it is false then it
+ will return <see cref="F:log4net.Filter.FilterDecision.Deny"/>. If the <see cref="T:log4net.Core.Level"/> does not match then
+ the result will be <see cref="F:log4net.Filter.FilterDecision.Neutral"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Filter.LevelMatchFilter.AcceptOnMatch">
+ <summary>
+ <see cref="F:log4net.Filter.FilterDecision.Accept"/> when matching <see cref="P:log4net.Filter.LevelMatchFilter.LevelToMatch"/>
+ </summary>
+ <remarks>
+ <para>
+ The <see cref="P:log4net.Filter.LevelMatchFilter.AcceptOnMatch"/> property is a flag that determines
+ the behavior when a matching <see cref="T:log4net.Core.Level"/> is found. If the
+ flag is set to true then the filter will <see cref="F:log4net.Filter.FilterDecision.Accept"/> the
+ logging event, otherwise it will <see cref="F:log4net.Filter.FilterDecision.Deny"/> the event.
+ </para>
+ <para>
+ The default is <c>true</c> i.e. to <see cref="F:log4net.Filter.FilterDecision.Accept"/> the event.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Filter.LevelMatchFilter.LevelToMatch">
+ <summary>
+ The <see cref="T:log4net.Core.Level"/> that the filter will match
+ </summary>
+ <remarks>
+ <para>
+ The level that this filter will attempt to match against the
+ <see cref="T:log4net.Core.LoggingEvent"/> level. If a match is found then
+ the result depends on the value of <see cref="P:log4net.Filter.LevelMatchFilter.AcceptOnMatch"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Filter.LevelRangeFilter">
+ <summary>
+ This is a simple filter based on <see cref="T:log4net.Core.Level"/> matching.
+ </summary>
+ <remarks>
+ <para>
+ The filter admits three options <see cref="P:log4net.Filter.LevelRangeFilter.LevelMin"/> and <see cref="P:log4net.Filter.LevelRangeFilter.LevelMax"/>
+ that determine the range of priorities that are matched, and
+ <see cref="P:log4net.Filter.LevelRangeFilter.AcceptOnMatch"/>. If there is a match between the range
+ of priorities and the <see cref="T:log4net.Core.Level"/> of the <see cref="T:log4net.Core.LoggingEvent"/>, then the
+ <see cref="M:log4net.Filter.LevelRangeFilter.Decide(log4net.Core.LoggingEvent)"/> method returns <see cref="F:log4net.Filter.FilterDecision.Accept"/> in case the <see cref="P:log4net.Filter.LevelRangeFilter.AcceptOnMatch"/>
+ option value is set to <c>true</c>, if it is <c>false</c>
+ then <see cref="F:log4net.Filter.FilterDecision.Deny"/> is returned. If there is no match, <see cref="F:log4net.Filter.FilterDecision.Deny"/> is returned.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="F:log4net.Filter.LevelRangeFilter.m_acceptOnMatch">
+ <summary>
+ Flag to indicate the behavior when matching a <see cref="T:log4net.Core.Level"/>
+ </summary>
+ </member>
+ <member name="F:log4net.Filter.LevelRangeFilter.m_levelMin">
+ <summary>
+ the minimum <see cref="T:log4net.Core.Level"/> value to match
+ </summary>
+ </member>
+ <member name="F:log4net.Filter.LevelRangeFilter.m_levelMax">
+ <summary>
+ the maximum <see cref="T:log4net.Core.Level"/> value to match
+ </summary>
+ </member>
+ <member name="M:log4net.Filter.LevelRangeFilter.#ctor">
+ <summary>
+ Default constructor
+ </summary>
+ </member>
+ <member name="M:log4net.Filter.LevelRangeFilter.Decide(log4net.Core.LoggingEvent)">
+ <summary>
+ Check if the event should be logged.
+ </summary>
+ <param name="loggingEvent">the logging event to check</param>
+ <returns>see remarks</returns>
+ <remarks>
+ <para>
+ If the <see cref="T:log4net.Core.Level"/> of the logging event is outside the range
+ matched by this filter then <see cref="F:log4net.Filter.FilterDecision.Deny"/>
+ is returned. If the <see cref="T:log4net.Core.Level"/> is matched then the value of
+ <see cref="P:log4net.Filter.LevelRangeFilter.AcceptOnMatch"/> is checked. If it is true then
+ <see cref="F:log4net.Filter.FilterDecision.Accept"/> is returned, otherwise
+ <see cref="F:log4net.Filter.FilterDecision.Neutral"/> is returned.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Filter.LevelRangeFilter.AcceptOnMatch">
+ <summary>
+ <see cref="F:log4net.Filter.FilterDecision.Accept"/> when matching <see cref="P:log4net.Filter.LevelRangeFilter.LevelMin"/> and <see cref="P:log4net.Filter.LevelRangeFilter.LevelMax"/>
+ </summary>
+ <remarks>
+ <para>
+ The <see cref="P:log4net.Filter.LevelRangeFilter.AcceptOnMatch"/> property is a flag that determines
+ the behavior when a matching <see cref="T:log4net.Core.Level"/> is found. If the
+ flag is set to true then the filter will <see cref="F:log4net.Filter.FilterDecision.Accept"/> the
+ logging event, otherwise it will <see cref="F:log4net.Filter.FilterDecision.Neutral"/> the event.
+ </para>
+ <para>
+ The default is <c>true</c> i.e. to <see cref="F:log4net.Filter.FilterDecision.Accept"/> the event.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Filter.LevelRangeFilter.LevelMin">
+ <summary>
+ Set the minimum matched <see cref="T:log4net.Core.Level"/>
+ </summary>
+ <remarks>
+ <para>
+ The minimum level that this filter will attempt to match against the
+ <see cref="T:log4net.Core.LoggingEvent"/> level. If a match is found then
+ the result depends on the value of <see cref="P:log4net.Filter.LevelRangeFilter.AcceptOnMatch"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Filter.LevelRangeFilter.LevelMax">
+ <summary>
+ Sets the maximum matched <see cref="T:log4net.Core.Level"/>
+ </summary>
+ <remarks>
+ <para>
+ The maximum level that this filter will attempt to match against the
+ <see cref="T:log4net.Core.LoggingEvent"/> level. If a match is found then
+ the result depends on the value of <see cref="P:log4net.Filter.LevelRangeFilter.AcceptOnMatch"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Filter.LoggerMatchFilter">
+ <summary>
+ Simple filter to match a string in the event's logger name.
+ </summary>
+ <remarks>
+ <para>
+ The works very similar to the <see cref="T:log4net.Filter.LevelMatchFilter"/>. It admits two
+ options <see cref="P:log4net.Filter.LoggerMatchFilter.LoggerToMatch"/> and <see cref="P:log4net.Filter.LoggerMatchFilter.AcceptOnMatch"/>. If the
+ <see cref="P:log4net.Core.LoggingEvent.LoggerName"/> of the <see cref="T:log4net.Core.LoggingEvent"/> starts
+ with the value of the <see cref="P:log4net.Filter.LoggerMatchFilter.LoggerToMatch"/> option, then the
+ <see cref="M:log4net.Filter.LoggerMatchFilter.Decide(log4net.Core.LoggingEvent)"/> method returns <see cref="F:log4net.Filter.FilterDecision.Accept"/> in
+ case the <see cref="P:log4net.Filter.LoggerMatchFilter.AcceptOnMatch"/> option value is set to <c>true</c>,
+ if it is <c>false</c> then <see cref="F:log4net.Filter.FilterDecision.Deny"/> is returned.
+ </para>
+ </remarks>
+ <author>Daniel Cazzulino</author>
+ </member>
+ <member name="F:log4net.Filter.LoggerMatchFilter.m_acceptOnMatch">
+ <summary>
+ Flag to indicate the behavior when we have a match
+ </summary>
+ </member>
+ <member name="F:log4net.Filter.LoggerMatchFilter.m_loggerToMatch">
+ <summary>
+ The logger name string to substring match against the event
+ </summary>
+ </member>
+ <member name="M:log4net.Filter.LoggerMatchFilter.#ctor">
+ <summary>
+ Default constructor
+ </summary>
+ </member>
+ <member name="M:log4net.Filter.LoggerMatchFilter.Decide(log4net.Core.LoggingEvent)">
+ <summary>
+ Check if this filter should allow the event to be logged
+ </summary>
+ <param name="loggingEvent">the event being logged</param>
+ <returns>see remarks</returns>
+ <remarks>
+ <para>
+ The rendered message is matched against the <see cref="P:log4net.Filter.LoggerMatchFilter.LoggerToMatch"/>.
+ If the <see cref="P:log4net.Filter.LoggerMatchFilter.LoggerToMatch"/> equals the beginning of
+ the incoming <see cref="P:log4net.Core.LoggingEvent.LoggerName"/> (<see cref="M:System.String.StartsWith(System.String)"/>)
+ then a match will have occurred. If no match occurs
+ this function will return <see cref="F:log4net.Filter.FilterDecision.Neutral"/>
+ allowing other filters to check the event. If a match occurs then
+ the value of <see cref="P:log4net.Filter.LoggerMatchFilter.AcceptOnMatch"/> is checked. If it is
+ true then <see cref="F:log4net.Filter.FilterDecision.Accept"/> is returned otherwise
+ <see cref="F:log4net.Filter.FilterDecision.Deny"/> is returned.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Filter.LoggerMatchFilter.AcceptOnMatch">
+ <summary>
+ <see cref="F:log4net.Filter.FilterDecision.Accept"/> when matching <see cref="P:log4net.Filter.LoggerMatchFilter.LoggerToMatch"/>
+ </summary>
+ <remarks>
+ <para>
+ The <see cref="P:log4net.Filter.LoggerMatchFilter.AcceptOnMatch"/> property is a flag that determines
+ the behavior when a matching <see cref="T:log4net.Core.Level"/> is found. If the
+ flag is set to true then the filter will <see cref="F:log4net.Filter.FilterDecision.Accept"/> the
+ logging event, otherwise it will <see cref="F:log4net.Filter.FilterDecision.Deny"/> the event.
+ </para>
+ <para>
+ The default is <c>true</c> i.e. to <see cref="F:log4net.Filter.FilterDecision.Accept"/> the event.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Filter.LoggerMatchFilter.LoggerToMatch">
+ <summary>
+ The <see cref="P:log4net.Core.LoggingEvent.LoggerName"/> that the filter will match
+ </summary>
+ <remarks>
+ <para>
+ This filter will attempt to match this value against logger name in
+ the following way. The match will be done against the beginning of the
+ logger name (using <see cref="M:System.String.StartsWith(System.String)"/>). The match is
+ case sensitive. If a match is found then
+ the result depends on the value of <see cref="P:log4net.Filter.LoggerMatchFilter.AcceptOnMatch"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Filter.MdcFilter">
+ <summary>
+ Simple filter to match a keyed string in the <see cref="T:log4net.MDC"/>
+ </summary>
+ <remarks>
+ <para>
+ Simple filter to match a keyed string in the <see cref="T:log4net.MDC"/>
+ </para>
+ <para>
+ As the MDC has been replaced with layered properties the
+ <see cref="T:log4net.Filter.PropertyFilter"/> should be used instead.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="T:log4net.Filter.PropertyFilter">
+ <summary>
+ Simple filter to match a string an event property
+ </summary>
+ <remarks>
+ <para>
+ Simple filter to match a string in the value for a
+ specific event property
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="T:log4net.Filter.StringMatchFilter">
+ <summary>
+ Simple filter to match a string in the rendered message
+ </summary>
+ <remarks>
+ <para>
+ Simple filter to match a string in the rendered message
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="F:log4net.Filter.StringMatchFilter.m_acceptOnMatch">
+ <summary>
+ Flag to indicate the behavior when we have a match
+ </summary>
+ </member>
+ <member name="F:log4net.Filter.StringMatchFilter.m_stringToMatch">
+ <summary>
+ The string to substring match against the message
+ </summary>
+ </member>
+ <member name="F:log4net.Filter.StringMatchFilter.m_stringRegexToMatch">
+ <summary>
+ A string regex to match
+ </summary>
+ </member>
+ <member name="F:log4net.Filter.StringMatchFilter.m_regexToMatch">
+ <summary>
+ A regex object to match (generated from m_stringRegexToMatch)
+ </summary>
+ </member>
+ <member name="M:log4net.Filter.StringMatchFilter.#ctor">
+ <summary>
+ Default constructor
+ </summary>
+ </member>
+ <member name="M:log4net.Filter.StringMatchFilter.ActivateOptions">
+ <summary>
+ Initialize and precompile the Regex if required
+ </summary>
+ <remarks>
+ <para>
+ This is part of the <see cref="T:log4net.Core.IOptionHandler"/> delayed object
+ activation scheme. The <see cref="M:log4net.Filter.StringMatchFilter.ActivateOptions"/> method must
+ be called on this object after the configuration properties have
+ been set. Until <see cref="M:log4net.Filter.StringMatchFilter.ActivateOptions"/> is called this
+ object is in an undefined state and must not be used.
+ </para>
+ <para>
+ If any of the configuration properties are modified then
+ <see cref="M:log4net.Filter.StringMatchFilter.ActivateOptions"/> must be called again.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Filter.StringMatchFilter.Decide(log4net.Core.LoggingEvent)">
+ <summary>
+ Check if this filter should allow the event to be logged
+ </summary>
+ <param name="loggingEvent">the event being logged</param>
+ <returns>see remarks</returns>
+ <remarks>
+ <para>
+ The rendered message is matched against the <see cref="P:log4net.Filter.StringMatchFilter.StringToMatch"/>.
+ If the <see cref="P:log4net.Filter.StringMatchFilter.StringToMatch"/> occurs as a substring within
+ the message then a match will have occurred. If no match occurs
+ this function will return <see cref="F:log4net.Filter.FilterDecision.Neutral"/>
+ allowing other filters to check the event. If a match occurs then
+ the value of <see cref="P:log4net.Filter.StringMatchFilter.AcceptOnMatch"/> is checked. If it is
+ true then <see cref="F:log4net.Filter.FilterDecision.Accept"/> is returned otherwise
+ <see cref="F:log4net.Filter.FilterDecision.Deny"/> is returned.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Filter.StringMatchFilter.AcceptOnMatch">
+ <summary>
+ <see cref="F:log4net.Filter.FilterDecision.Accept"/> when matching <see cref="P:log4net.Filter.StringMatchFilter.StringToMatch"/> or <see cref="P:log4net.Filter.StringMatchFilter.RegexToMatch"/>
+ </summary>
+ <remarks>
+ <para>
+ The <see cref="P:log4net.Filter.StringMatchFilter.AcceptOnMatch"/> property is a flag that determines
+ the behavior when a matching <see cref="T:log4net.Core.Level"/> is found. If the
+ flag is set to true then the filter will <see cref="F:log4net.Filter.FilterDecision.Accept"/> the
+ logging event, otherwise it will <see cref="F:log4net.Filter.FilterDecision.Neutral"/> the event.
+ </para>
+ <para>
+ The default is <c>true</c> i.e. to <see cref="F:log4net.Filter.FilterDecision.Accept"/> the event.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Filter.StringMatchFilter.StringToMatch">
+ <summary>
+ Sets the static string to match
+ </summary>
+ <remarks>
+ <para>
+ The string that will be substring matched against
+ the rendered message. If the message contains this
+ string then the filter will match. If a match is found then
+ the result depends on the value of <see cref="P:log4net.Filter.StringMatchFilter.AcceptOnMatch"/>.
+ </para>
+ <para>
+ One of <see cref="P:log4net.Filter.StringMatchFilter.StringToMatch"/> or <see cref="P:log4net.Filter.StringMatchFilter.RegexToMatch"/>
+ must be specified.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Filter.StringMatchFilter.RegexToMatch">
+ <summary>
+ Sets the regular expression to match
+ </summary>
+ <remarks>
+ <para>
+ The regular expression pattern that will be matched against
+ the rendered message. If the message matches this
+ pattern then the filter will match. If a match is found then
+ the result depends on the value of <see cref="P:log4net.Filter.StringMatchFilter.AcceptOnMatch"/>.
+ </para>
+ <para>
+ One of <see cref="P:log4net.Filter.StringMatchFilter.StringToMatch"/> or <see cref="P:log4net.Filter.StringMatchFilter.RegexToMatch"/>
+ must be specified.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Filter.PropertyFilter.m_key">
+ <summary>
+ The key to use to lookup the string from the event properties
+ </summary>
+ </member>
+ <member name="M:log4net.Filter.PropertyFilter.#ctor">
+ <summary>
+ Default constructor
+ </summary>
+ </member>
+ <member name="M:log4net.Filter.PropertyFilter.Decide(log4net.Core.LoggingEvent)">
+ <summary>
+ Check if this filter should allow the event to be logged
+ </summary>
+ <param name="loggingEvent">the event being logged</param>
+ <returns>see remarks</returns>
+ <remarks>
+ <para>
+ The event property for the <see cref="P:log4net.Filter.PropertyFilter.Key"/> is matched against
+ the <see cref="P:log4net.Filter.StringMatchFilter.StringToMatch"/>.
+ If the <see cref="P:log4net.Filter.StringMatchFilter.StringToMatch"/> occurs as a substring within
+ the property value then a match will have occurred. If no match occurs
+ this function will return <see cref="F:log4net.Filter.FilterDecision.Neutral"/>
+ allowing other filters to check the event. If a match occurs then
+ the value of <see cref="P:log4net.Filter.StringMatchFilter.AcceptOnMatch"/> is checked. If it is
+ true then <see cref="F:log4net.Filter.FilterDecision.Accept"/> is returned otherwise
+ <see cref="F:log4net.Filter.FilterDecision.Deny"/> is returned.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Filter.PropertyFilter.Key">
+ <summary>
+ The key to lookup in the event properties and then match against.
+ </summary>
+ <remarks>
+ <para>
+ The key name to use to lookup in the properties map of the
+ <see cref="T:log4net.Core.LoggingEvent"/>. The match will be performed against
+ the value of this property if it exists.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Filter.NdcFilter">
+ <summary>
+ Simple filter to match a string in the <see cref="T:log4net.NDC"/>
+ </summary>
+ <remarks>
+ <para>
+ Simple filter to match a string in the <see cref="T:log4net.NDC"/>
+ </para>
+ <para>
+ As the MDC has been replaced with named stacks stored in the
+ properties collections the <see cref="T:log4net.Filter.PropertyFilter"/> should
+ be used instead.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="M:log4net.Filter.NdcFilter.#ctor">
+ <summary>
+ Default constructor
+ </summary>
+ <remarks>
+ <para>
+ Sets the <see cref="P:log4net.Filter.PropertyFilter.Key"/> to <c>"NDC"</c>.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Layout.Pattern.AppDomainPatternConverter">
+ <summary>
+ Write the event appdomain name to the output
+ </summary>
+ <remarks>
+ <para>
+ Writes the <see cref="P:log4net.Core.LoggingEvent.Domain"/> to the output writer.
+ </para>
+ </remarks>
+ <author>Daniel Cazzulino</author>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="T:log4net.Layout.Pattern.PatternLayoutConverter">
+ <summary>
+ Abstract class that provides the formatting functionality that
+ derived classes need.
+ </summary>
+ <remarks>
+ Conversion specifiers in a conversion patterns are parsed to
+ individual PatternConverters. Each of which is responsible for
+ converting a logging event in a converter specific manner.
+ </remarks>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="T:log4net.Util.PatternConverter">
+ <summary>
+ Abstract class that provides the formatting functionality that
+ derived classes need.
+ </summary>
+ <remarks>
+ <para>
+ Conversion specifiers in a conversion patterns are parsed to
+ individual PatternConverters. Each of which is responsible for
+ converting a logging event in a converter specific manner.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="F:log4net.Util.PatternConverter.c_renderBufferSize">
+ <summary>
+ Initial buffer size
+ </summary>
+ </member>
+ <member name="F:log4net.Util.PatternConverter.c_renderBufferMaxCapacity">
+ <summary>
+ Maximum buffer size before it is recycled
+ </summary>
+ </member>
+ <member name="M:log4net.Util.PatternConverter.#ctor">
+ <summary>
+ Protected constructor
+ </summary>
+ <remarks>
+ <para>
+ Initializes a new instance of the <see cref="T:log4net.Util.PatternConverter"/> class.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.PatternConverter.Convert(System.IO.TextWriter,System.Object)">
+ <summary>
+ Evaluate this pattern converter and write the output to a writer.
+ </summary>
+ <param name="writer"><see cref="T:System.IO.TextWriter"/> that will receive the formatted result.</param>
+ <param name="state">The state object on which the pattern converter should be executed.</param>
+ <remarks>
+ <para>
+ Derived pattern converters must override this method in order to
+ convert conversion specifiers in the appropriate way.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.PatternConverter.SetNext(log4net.Util.PatternConverter)">
+ <summary>
+ Set the next pattern converter in the chains
+ </summary>
+ <param name="patternConverter">the pattern converter that should follow this converter in the chain</param>
+ <returns>the next converter</returns>
+ <remarks>
+ <para>
+ The PatternConverter can merge with its neighbor during this method (or a sub class).
+ Therefore the return value may or may not be the value of the argument passed in.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.PatternConverter.Format(System.IO.TextWriter,System.Object)">
+ <summary>
+ Write the pattern converter to the writer with appropriate formatting
+ </summary>
+ <param name="writer"><see cref="T:System.IO.TextWriter"/> that will receive the formatted result.</param>
+ <param name="state">The state object on which the pattern converter should be executed.</param>
+ <remarks>
+ <para>
+ This method calls <see cref="M:log4net.Util.PatternConverter.Convert(System.IO.TextWriter,System.Object)"/> to allow the subclass to perform
+ appropriate conversion of the pattern converter. If formatting options have
+ been specified via the <see cref="P:log4net.Util.PatternConverter.FormattingInfo"/> then this method will
+ apply those formattings before writing the output.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.PatternConverter.SpacePad(System.IO.TextWriter,System.Int32)">
+ <summary>
+ Fast space padding method.
+ </summary>
+ <param name="writer"><see cref="T:System.IO.TextWriter"/> to which the spaces will be appended.</param>
+ <param name="length">The number of spaces to be padded.</param>
+ <remarks>
+ <para>
+ Fast space padding method.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Util.PatternConverter.m_option">
+ <summary>
+ The option string to the converter
+ </summary>
+ </member>
+ <member name="M:log4net.Util.PatternConverter.WriteDictionary(System.IO.TextWriter,log4net.Repository.ILoggerRepository,System.Collections.IDictionary)">
+ <summary>
+ Write an dictionary to a <see cref="T:System.IO.TextWriter"/>
+ </summary>
+ <param name="writer">the writer to write to</param>
+ <param name="repository">a <see cref="T:log4net.Repository.ILoggerRepository"/> to use for object conversion</param>
+ <param name="value">the value to write to the writer</param>
+ <remarks>
+ <para>
+ Writes the <see cref="T:System.Collections.IDictionary"/> to a writer in the form:
+ </para>
+ <code>
+ {key1=value1, key2=value2, key3=value3}
+ </code>
+ <para>
+ If the <see cref="T:log4net.Repository.ILoggerRepository"/> specified
+ is not null then it is used to render the key and value to text, otherwise
+ the object's ToString method is called.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.PatternConverter.WriteObject(System.IO.TextWriter,log4net.Repository.ILoggerRepository,System.Object)">
+ <summary>
+ Write an object to a <see cref="T:System.IO.TextWriter"/>
+ </summary>
+ <param name="writer">the writer to write to</param>
+ <param name="repository">a <see cref="T:log4net.Repository.ILoggerRepository"/> to use for object conversion</param>
+ <param name="value">the value to write to the writer</param>
+ <remarks>
+ <para>
+ Writes the Object to a writer. If the <see cref="T:log4net.Repository.ILoggerRepository"/> specified
+ is not null then it is used to render the object to text, otherwise
+ the object's ToString method is called.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Util.PatternConverter.Next">
+ <summary>
+ Get the next pattern converter in the chain
+ </summary>
+ <value>
+ the next pattern converter in the chain
+ </value>
+ <remarks>
+ <para>
+ Get the next pattern converter in the chain
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Util.PatternConverter.FormattingInfo">
+ <summary>
+ Gets or sets the formatting info for this converter
+ </summary>
+ <value>
+ The formatting info for this converter
+ </value>
+ <remarks>
+ <para>
+ Gets or sets the formatting info for this converter
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Util.PatternConverter.Option">
+ <summary>
+ Gets or sets the option value for this converter
+ </summary>
+ <summary>
+ The option for this converter
+ </summary>
+ <remarks>
+ <para>
+ Gets or sets the option value for this converter
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Layout.Pattern.PatternLayoutConverter.#ctor">
+ <summary>
+ Initializes a new instance of the <see cref="T:log4net.Layout.Pattern.PatternLayoutConverter"/> class.
+ </summary>
+ </member>
+ <member name="M:log4net.Layout.Pattern.PatternLayoutConverter.Convert(System.IO.TextWriter,log4net.Core.LoggingEvent)">
+ <summary>
+ Derived pattern converters must override this method in order to
+ convert conversion specifiers in the correct way.
+ </summary>
+ <param name="writer"><see cref="T:System.IO.TextWriter"/> that will receive the formatted result.</param>
+ <param name="loggingEvent">The <see cref="T:log4net.Core.LoggingEvent"/> on which the pattern converter should be executed.</param>
+ </member>
+ <member name="M:log4net.Layout.Pattern.PatternLayoutConverter.Convert(System.IO.TextWriter,System.Object)">
+ <summary>
+ Derived pattern converters must override this method in order to
+ convert conversion specifiers in the correct way.
+ </summary>
+ <param name="writer"><see cref="T:System.IO.TextWriter"/> that will receive the formatted result.</param>
+ <param name="state">The state object on which the pattern converter should be executed.</param>
+ </member>
+ <member name="F:log4net.Layout.Pattern.PatternLayoutConverter.m_ignoresException">
+ <summary>
+ Flag indicating if this converter handles exceptions
+ </summary>
+ <remarks>
+ <c>false</c> if this converter handles exceptions
+ </remarks>
+ </member>
+ <member name="P:log4net.Layout.Pattern.PatternLayoutConverter.IgnoresException">
+ <summary>
+ Flag indicating if this converter handles the logging event exception
+ </summary>
+ <value><c>false</c> if this converter handles the logging event exception</value>
+ <remarks>
+ <para>
+ If this converter handles the exception object contained within
+ <see cref="T:log4net.Core.LoggingEvent"/>, then this property should be set to
+ <c>false</c>. Otherwise, if the layout ignores the exception
+ object, then the property should be set to <c>true</c>.
+ </para>
+ <para>
+ Set this value to override a this default setting. The default
+ value is <c>true</c>, this converter does not handle the exception.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Layout.Pattern.AppDomainPatternConverter.Convert(System.IO.TextWriter,log4net.Core.LoggingEvent)">
+ <summary>
+ Write the event appdomain name to the output
+ </summary>
+ <param name="writer"><see cref="T:System.IO.TextWriter"/> that will receive the formatted result.</param>
+ <param name="loggingEvent">the event being logged</param>
+ <remarks>
+ <para>
+ Writes the <see cref="P:log4net.Core.LoggingEvent.Domain"/> to the output <paramref name="writer"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Layout.Pattern.DatePatternConverter">
+ <summary>
+ Date pattern converter, uses a <see cref="T:log4net.DateFormatter.IDateFormatter"/> to format
+ the date of a <see cref="T:log4net.Core.LoggingEvent"/>.
+ </summary>
+ <remarks>
+ <para>
+ Render the <see cref="P:log4net.Core.LoggingEvent.TimeStamp"/> to the writer as a string.
+ </para>
+ <para>
+ The value of the <see cref="P:log4net.Util.PatternConverter.Option"/> determines
+ the formatting of the date. The following values are allowed:
+ <list type="definition">
+ <listheader>
+ <term>Option value</term>
+ <description>Output</description>
+ </listheader>
+ <item>
+ <term>ISO8601</term>
+ <description>
+ Uses the <see cref="T:log4net.DateFormatter.Iso8601DateFormatter"/> formatter.
+ Formats using the <c>"yyyy-MM-dd HH:mm:ss,fff"</c> pattern.
+ </description>
+ </item>
+ <item>
+ <term>DATE</term>
+ <description>
+ Uses the <see cref="T:log4net.DateFormatter.DateTimeDateFormatter"/> formatter.
+ Formats using the <c>"dd MMM yyyy HH:mm:ss,fff"</c> for example, <c>"06 Nov 1994 15:49:37,459"</c>.
+ </description>
+ </item>
+ <item>
+ <term>ABSOLUTE</term>
+ <description>
+ Uses the <see cref="T:log4net.DateFormatter.AbsoluteTimeDateFormatter"/> formatter.
+ Formats using the <c>"HH:mm:ss,yyyy"</c> for example, <c>"15:49:37,459"</c>.
+ </description>
+ </item>
+ <item>
+ <term>other</term>
+ <description>
+ Any other pattern string uses the <see cref="T:log4net.DateFormatter.SimpleDateFormatter"/> formatter.
+ This formatter passes the pattern string to the <see cref="T:System.DateTime"/>
+ <see cref="M:System.DateTime.ToString(System.String)"/> method.
+ For details on valid patterns see
+ <a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfsystemglobalizationdatetimeformatinfoclasstopic.asp">DateTimeFormatInfo Class</a>.
+ </description>
+ </item>
+ </list>
+ </para>
+ <para>
+ The <see cref="P:log4net.Core.LoggingEvent.TimeStamp"/> is in the local time zone and is rendered in that zone.
+ To output the time in Universal time see <see cref="T:log4net.Layout.Pattern.UtcDatePatternConverter"/>.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="F:log4net.Layout.Pattern.DatePatternConverter.m_dateFormatter">
+ <summary>
+ The <see cref="T:log4net.DateFormatter.IDateFormatter"/> used to render the date to a string
+ </summary>
+ <remarks>
+ <para>
+ The <see cref="T:log4net.DateFormatter.IDateFormatter"/> used to render the date to a string
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Layout.Pattern.DatePatternConverter.ActivateOptions">
+ <summary>
+ Initialize the converter pattern based on the <see cref="P:log4net.Util.PatternConverter.Option"/> property.
+ </summary>
+ <remarks>
+ <para>
+ This is part of the <see cref="T:log4net.Core.IOptionHandler"/> delayed object
+ activation scheme. The <see cref="M:log4net.Layout.Pattern.DatePatternConverter.ActivateOptions"/> method must
+ be called on this object after the configuration properties have
+ been set. Until <see cref="M:log4net.Layout.Pattern.DatePatternConverter.ActivateOptions"/> is called this
+ object is in an undefined state and must not be used.
+ </para>
+ <para>
+ If any of the configuration properties are modified then
+ <see cref="M:log4net.Layout.Pattern.DatePatternConverter.ActivateOptions"/> must be called again.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Layout.Pattern.DatePatternConverter.Convert(System.IO.TextWriter,log4net.Core.LoggingEvent)">
+ <summary>
+ Convert the pattern into the rendered message
+ </summary>
+ <param name="writer"><see cref="T:System.IO.TextWriter"/> that will receive the formatted result.</param>
+ <param name="loggingEvent">the event being logged</param>
+ <remarks>
+ <para>
+ Pass the <see cref="P:log4net.Core.LoggingEvent.TimeStamp"/> to the <see cref="T:log4net.DateFormatter.IDateFormatter"/>
+ for it to render it to the writer.
+ </para>
+ <para>
+ The <see cref="P:log4net.Core.LoggingEvent.TimeStamp"/> passed is in the local time zone.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Layout.Pattern.ExceptionPatternConverter">
+ <summary>
+ Write the exception text to the output
+ </summary>
+ <remarks>
+ <para>
+ If an exception object is stored in the logging event
+ it will be rendered into the pattern output with a
+ trailing newline.
+ </para>
+ <para>
+ If there is no exception then nothing will be output
+ and no trailing newline will be appended.
+ It is typical to put a newline before the exception
+ and to have the exception as the last data in the pattern.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="M:log4net.Layout.Pattern.ExceptionPatternConverter.#ctor">
+ <summary>
+ Default constructor
+ </summary>
+ </member>
+ <member name="M:log4net.Layout.Pattern.ExceptionPatternConverter.Convert(System.IO.TextWriter,log4net.Core.LoggingEvent)">
+ <summary>
+ Write the exception text to the output
+ </summary>
+ <param name="writer"><see cref="T:System.IO.TextWriter"/> that will receive the formatted result.</param>
+ <param name="loggingEvent">the event being logged</param>
+ <remarks>
+ <para>
+ If an exception object is stored in the logging event
+ it will be rendered into the pattern output with a
+ trailing newline.
+ </para>
+ <para>
+ If there is no exception then nothing will be output
+ and no trailing newline will be appended.
+ It is typical to put a newline before the exception
+ and to have the exception as the last data in the pattern.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Layout.Pattern.FileLocationPatternConverter">
+ <summary>
+ Writes the caller location file name to the output
+ </summary>
+ <remarks>
+ <para>
+ Writes the value of the <see cref="P:log4net.Core.LocationInfo.FileName"/> for
+ the event to the output writer.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="M:log4net.Layout.Pattern.FileLocationPatternConverter.Convert(System.IO.TextWriter,log4net.Core.LoggingEvent)">
+ <summary>
+ Write the caller location file name to the output
+ </summary>
+ <param name="writer"><see cref="T:System.IO.TextWriter"/> that will receive the formatted result.</param>
+ <param name="loggingEvent">the event being logged</param>
+ <remarks>
+ <para>
+ Writes the value of the <see cref="P:log4net.Core.LocationInfo.FileName"/> for
+ the <paramref name="loggingEvent"/> to the output <paramref name="writer"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Layout.Pattern.FullLocationPatternConverter">
+ <summary>
+ Write the caller location info to the output
+ </summary>
+ <remarks>
+ <para>
+ Writes the <see cref="P:log4net.Core.LocationInfo.FullInfo"/> to the output writer.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="M:log4net.Layout.Pattern.FullLocationPatternConverter.Convert(System.IO.TextWriter,log4net.Core.LoggingEvent)">
+ <summary>
+ Write the caller location info to the output
+ </summary>
+ <param name="writer"><see cref="T:System.IO.TextWriter"/> that will receive the formatted result.</param>
+ <param name="loggingEvent">the event being logged</param>
+ <remarks>
+ <para>
+ Writes the <see cref="P:log4net.Core.LocationInfo.FullInfo"/> to the output writer.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Layout.Pattern.IdentityPatternConverter">
+ <summary>
+ Writes the event identity to the output
+ </summary>
+ <remarks>
+ <para>
+ Writes the value of the <see cref="P:log4net.Core.LoggingEvent.Identity"/> to
+ the output writer.
+ </para>
+ </remarks>
+ <author>Daniel Cazzulino</author>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="M:log4net.Layout.Pattern.IdentityPatternConverter.Convert(System.IO.TextWriter,log4net.Core.LoggingEvent)">
+ <summary>
+ Writes the event identity to the output
+ </summary>
+ <param name="writer"><see cref="T:System.IO.TextWriter"/> that will receive the formatted result.</param>
+ <param name="loggingEvent">the event being logged</param>
+ <remarks>
+ <para>
+ Writes the value of the <paramref name="loggingEvent"/>
+ <see cref="P:log4net.Core.LoggingEvent.Identity"/> to
+ the output <paramref name="writer"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Layout.Pattern.LevelPatternConverter">
+ <summary>
+ Write the event level to the output
+ </summary>
+ <remarks>
+ <para>
+ Writes the display name of the event <see cref="P:log4net.Core.LoggingEvent.Level"/>
+ to the writer.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="M:log4net.Layout.Pattern.LevelPatternConverter.Convert(System.IO.TextWriter,log4net.Core.LoggingEvent)">
+ <summary>
+ Write the event level to the output
+ </summary>
+ <param name="writer"><see cref="T:System.IO.TextWriter"/> that will receive the formatted result.</param>
+ <param name="loggingEvent">the event being logged</param>
+ <remarks>
+ <para>
+ Writes the <see cref="P:log4net.Core.Level.DisplayName"/> of the <paramref name="loggingEvent"/> <see cref="P:log4net.Core.LoggingEvent.Level"/>
+ to the <paramref name="writer"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Layout.Pattern.LineLocationPatternConverter">
+ <summary>
+ Write the caller location line number to the output
+ </summary>
+ <remarks>
+ <para>
+ Writes the value of the <see cref="P:log4net.Core.LocationInfo.LineNumber"/> for
+ the event to the output writer.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="M:log4net.Layout.Pattern.LineLocationPatternConverter.Convert(System.IO.TextWriter,log4net.Core.LoggingEvent)">
+ <summary>
+ Write the caller location line number to the output
+ </summary>
+ <param name="writer"><see cref="T:System.IO.TextWriter"/> that will receive the formatted result.</param>
+ <param name="loggingEvent">the event being logged</param>
+ <remarks>
+ <para>
+ Writes the value of the <see cref="P:log4net.Core.LocationInfo.LineNumber"/> for
+ the <paramref name="loggingEvent"/> to the output <paramref name="writer"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Layout.Pattern.LoggerPatternConverter">
+ <summary>
+ Converter for logger name
+ </summary>
+ <remarks>
+ <para>
+ Outputs the <see cref="P:log4net.Core.LoggingEvent.LoggerName"/> of the event.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="T:log4net.Layout.Pattern.NamedPatternConverter">
+ <summary>
+ Converter to output and truncate <c>'.'</c> separated strings
+ </summary>
+ <remarks>
+ <para>
+ This abstract class supports truncating a <c>'.'</c> separated string
+ to show a specified number of elements from the right hand side.
+ This is used to truncate class names that are fully qualified.
+ </para>
+ <para>
+ Subclasses should override the <see cref="M:log4net.Layout.Pattern.NamedPatternConverter.GetFullyQualifiedName(log4net.Core.LoggingEvent)"/> method to
+ return the fully qualified string.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="M:log4net.Layout.Pattern.NamedPatternConverter.ActivateOptions">
+ <summary>
+ Initialize the converter
+ </summary>
+ <remarks>
+ <para>
+ This is part of the <see cref="T:log4net.Core.IOptionHandler"/> delayed object
+ activation scheme. The <see cref="M:log4net.Layout.Pattern.NamedPatternConverter.ActivateOptions"/> method must
+ be called on this object after the configuration properties have
+ been set. Until <see cref="M:log4net.Layout.Pattern.NamedPatternConverter.ActivateOptions"/> is called this
+ object is in an undefined state and must not be used.
+ </para>
+ <para>
+ If any of the configuration properties are modified then
+ <see cref="M:log4net.Layout.Pattern.NamedPatternConverter.ActivateOptions"/> must be called again.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Layout.Pattern.NamedPatternConverter.GetFullyQualifiedName(log4net.Core.LoggingEvent)">
+ <summary>
+ Get the fully qualified string data
+ </summary>
+ <param name="loggingEvent">the event being logged</param>
+ <returns>the fully qualified name</returns>
+ <remarks>
+ <para>
+ Overridden by subclasses to get the fully qualified name before the
+ precision is applied to it.
+ </para>
+ <para>
+ Return the fully qualified <c>'.'</c> (dot/period) separated string.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Layout.Pattern.NamedPatternConverter.Convert(System.IO.TextWriter,log4net.Core.LoggingEvent)">
+ <summary>
+ Convert the pattern to the rendered message
+ </summary>
+ <param name="writer"><see cref="T:System.IO.TextWriter"/> that will receive the formatted result.</param>
+ <param name="loggingEvent">the event being logged</param>
+ <remarks>
+ Render the <see cref="M:log4net.Layout.Pattern.NamedPatternConverter.GetFullyQualifiedName(log4net.Core.LoggingEvent)"/> to the precision
+ specified by the <see cref="P:log4net.Util.PatternConverter.Option"/> property.
+ </remarks>
+ </member>
+ <member name="M:log4net.Layout.Pattern.LoggerPatternConverter.GetFullyQualifiedName(log4net.Core.LoggingEvent)">
+ <summary>
+ Gets the fully qualified name of the logger
+ </summary>
+ <param name="loggingEvent">the event being logged</param>
+ <returns>The fully qualified logger name</returns>
+ <remarks>
+ <para>
+ Returns the <see cref="P:log4net.Core.LoggingEvent.LoggerName"/> of the <paramref name="loggingEvent"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Layout.Pattern.MessagePatternConverter">
+ <summary>
+ Writes the event message to the output
+ </summary>
+ <remarks>
+ <para>
+ Uses the <see cref="M:log4net.Core.LoggingEvent.WriteRenderedMessage(System.IO.TextWriter)"/> method
+ to write out the event message.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="M:log4net.Layout.Pattern.MessagePatternConverter.Convert(System.IO.TextWriter,log4net.Core.LoggingEvent)">
+ <summary>
+ Writes the event message to the output
+ </summary>
+ <param name="writer"><see cref="T:System.IO.TextWriter"/> that will receive the formatted result.</param>
+ <param name="loggingEvent">the event being logged</param>
+ <remarks>
+ <para>
+ Uses the <see cref="M:log4net.Core.LoggingEvent.WriteRenderedMessage(System.IO.TextWriter)"/> method
+ to write out the event message.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Layout.Pattern.MethodLocationPatternConverter">
+ <summary>
+ Write the method name to the output
+ </summary>
+ <remarks>
+ <para>
+ Writes the caller location <see cref="P:log4net.Core.LocationInfo.MethodName"/> to
+ the output.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="M:log4net.Layout.Pattern.MethodLocationPatternConverter.Convert(System.IO.TextWriter,log4net.Core.LoggingEvent)">
+ <summary>
+ Write the method name to the output
+ </summary>
+ <param name="writer"><see cref="T:System.IO.TextWriter"/> that will receive the formatted result.</param>
+ <param name="loggingEvent">the event being logged</param>
+ <remarks>
+ <para>
+ Writes the caller location <see cref="P:log4net.Core.LocationInfo.MethodName"/> to
+ the output.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Layout.Pattern.NdcPatternConverter">
+ <summary>
+ Converter to include event NDC
+ </summary>
+ <remarks>
+ <para>
+ Outputs the value of the event property named <c>NDC</c>.
+ </para>
+ <para>
+ The <see cref="T:log4net.Layout.Pattern.PropertyPatternConverter"/> should be used instead.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="M:log4net.Layout.Pattern.NdcPatternConverter.Convert(System.IO.TextWriter,log4net.Core.LoggingEvent)">
+ <summary>
+ Write the event NDC to the output
+ </summary>
+ <param name="writer"><see cref="T:System.IO.TextWriter"/> that will receive the formatted result.</param>
+ <param name="loggingEvent">the event being logged</param>
+ <remarks>
+ <para>
+ As the thread context stacks are now stored in named event properties
+ this converter simply looks up the value of the <c>NDC</c> property.
+ </para>
+ <para>
+ The <see cref="T:log4net.Layout.Pattern.PropertyPatternConverter"/> should be used instead.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Layout.Pattern.PropertyPatternConverter">
+ <summary>
+ Property pattern converter
+ </summary>
+ <remarks>
+ <para>
+ Writes out the value of a named property. The property name
+ should be set in the <see cref="P:log4net.Util.PatternConverter.Option"/>
+ property.
+ </para>
+ <para>
+ If the <see cref="P:log4net.Util.PatternConverter.Option"/> is set to <c>null</c>
+ then all the properties are written as key value pairs.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="M:log4net.Layout.Pattern.PropertyPatternConverter.Convert(System.IO.TextWriter,log4net.Core.LoggingEvent)">
+ <summary>
+ Write the property value to the output
+ </summary>
+ <param name="writer"><see cref="T:System.IO.TextWriter"/> that will receive the formatted result.</param>
+ <param name="loggingEvent">the event being logged</param>
+ <remarks>
+ <para>
+ Writes out the value of a named property. The property name
+ should be set in the <see cref="P:log4net.Util.PatternConverter.Option"/>
+ property.
+ </para>
+ <para>
+ If the <see cref="P:log4net.Util.PatternConverter.Option"/> is set to <c>null</c>
+ then all the properties are written as key value pairs.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Layout.Pattern.RelativeTimePatternConverter">
+ <summary>
+ Converter to output the relative time of the event
+ </summary>
+ <remarks>
+ <para>
+ Converter to output the time of the event relative to the start of the program.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="M:log4net.Layout.Pattern.RelativeTimePatternConverter.Convert(System.IO.TextWriter,log4net.Core.LoggingEvent)">
+ <summary>
+ Write the relative time to the output
+ </summary>
+ <param name="writer"><see cref="T:System.IO.TextWriter"/> that will receive the formatted result.</param>
+ <param name="loggingEvent">the event being logged</param>
+ <remarks>
+ <para>
+ Writes out the relative time of the event in milliseconds.
+ That is the number of milliseconds between the event <see cref="P:log4net.Core.LoggingEvent.TimeStamp"/>
+ and the <see cref="P:log4net.Core.LoggingEvent.StartTime"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Layout.Pattern.RelativeTimePatternConverter.TimeDifferenceInMillis(System.DateTime,System.DateTime)">
+ <summary>
+ Helper method to get the time difference between two DateTime objects
+ </summary>
+ <param name="start">start time (in the current local time zone)</param>
+ <param name="end">end time (in the current local time zone)</param>
+ <returns>the time difference in milliseconds</returns>
+ </member>
+ <member name="T:log4net.Layout.Pattern.ThreadPatternConverter">
+ <summary>
+ Converter to include event thread name
+ </summary>
+ <remarks>
+ <para>
+ Writes the <see cref="P:log4net.Core.LoggingEvent.ThreadName"/> to the output.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="M:log4net.Layout.Pattern.ThreadPatternConverter.Convert(System.IO.TextWriter,log4net.Core.LoggingEvent)">
+ <summary>
+ Write the ThreadName to the output
+ </summary>
+ <param name="writer"><see cref="T:System.IO.TextWriter"/> that will receive the formatted result.</param>
+ <param name="loggingEvent">the event being logged</param>
+ <remarks>
+ <para>
+ Writes the <see cref="P:log4net.Core.LoggingEvent.ThreadName"/> to the <paramref name="writer"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Layout.Pattern.TypeNamePatternConverter">
+ <summary>
+ Pattern converter for the class name
+ </summary>
+ <remarks>
+ <para>
+ Outputs the <see cref="P:log4net.Core.LocationInfo.ClassName"/> of the event.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="M:log4net.Layout.Pattern.TypeNamePatternConverter.GetFullyQualifiedName(log4net.Core.LoggingEvent)">
+ <summary>
+ Gets the fully qualified name of the class
+ </summary>
+ <param name="loggingEvent">the event being logged</param>
+ <returns>The fully qualified type name for the caller location</returns>
+ <remarks>
+ <para>
+ Returns the <see cref="P:log4net.Core.LocationInfo.ClassName"/> of the <paramref name="loggingEvent"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Layout.Pattern.UserNamePatternConverter">
+ <summary>
+ Converter to include event user name
+ </summary>
+ <author>Douglas de la Torre</author>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="M:log4net.Layout.Pattern.UserNamePatternConverter.Convert(System.IO.TextWriter,log4net.Core.LoggingEvent)">
+ <summary>
+ Convert the pattern to the rendered message
+ </summary>
+ <param name="writer"><see cref="T:System.IO.TextWriter"/> that will receive the formatted result.</param>
+ <param name="loggingEvent">the event being logged</param>
+ </member>
+ <member name="T:log4net.Layout.Pattern.UtcDatePatternConverter">
+ <summary>
+ Write the TimeStamp to the output
+ </summary>
+ <remarks>
+ <para>
+ Date pattern converter, uses a <see cref="T:log4net.DateFormatter.IDateFormatter"/> to format
+ the date of a <see cref="T:log4net.Core.LoggingEvent"/>.
+ </para>
+ <para>
+ Uses a <see cref="T:log4net.DateFormatter.IDateFormatter"/> to format the <see cref="P:log4net.Core.LoggingEvent.TimeStamp"/>
+ in Universal time.
+ </para>
+ <para>
+ See the <see cref="T:log4net.Layout.Pattern.DatePatternConverter"/> for details on the date pattern syntax.
+ </para>
+ </remarks>
+ <seealso cref="T:log4net.Layout.Pattern.DatePatternConverter"/>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="M:log4net.Layout.Pattern.UtcDatePatternConverter.Convert(System.IO.TextWriter,log4net.Core.LoggingEvent)">
+ <summary>
+ Write the TimeStamp to the output
+ </summary>
+ <param name="writer"><see cref="T:System.IO.TextWriter"/> that will receive the formatted result.</param>
+ <param name="loggingEvent">the event being logged</param>
+ <remarks>
+ <para>
+ Pass the <see cref="P:log4net.Core.LoggingEvent.TimeStamp"/> to the <see cref="T:log4net.DateFormatter.IDateFormatter"/>
+ for it to render it to the writer.
+ </para>
+ <para>
+ The <see cref="P:log4net.Core.LoggingEvent.TimeStamp"/> passed is in the local time zone, this is converted
+ to Universal time before it is rendered.
+ </para>
+ </remarks>
+ <seealso cref="T:log4net.Layout.Pattern.DatePatternConverter"/>
+ </member>
+ <member name="T:log4net.Layout.ExceptionLayout">
+ <summary>
+ A Layout that renders only the Exception text from the logging event
+ </summary>
+ <remarks>
+ <para>
+ A Layout that renders only the Exception text from the logging event.
+ </para>
+ <para>
+ This Layout should only be used with appenders that utilize multiple
+ layouts (e.g. <see cref="T:log4net.Appender.AdoNetAppender"/>).
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="T:log4net.Layout.LayoutSkeleton">
+ <summary>
+ Extend this abstract class to create your own log layout format.
+ </summary>
+ <remarks>
+ <para>
+ This is the base implementation of the <see cref="T:log4net.Layout.ILayout"/>
+ interface. Most layout objects should extend this class.
+ </para>
+ </remarks>
+ <remarks>
+ <note type="inheritinfo">
+ <para>
+ Subclasses must implement the <see cref="M:log4net.Layout.LayoutSkeleton.Format(System.IO.TextWriter,log4net.Core.LoggingEvent)"/>
+ method.
+ </para>
+ <para>
+ Subclasses should set the <see cref="P:log4net.Layout.LayoutSkeleton.IgnoresException"/> in their default
+ constructor.
+ </para>
+ </note>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="T:log4net.Layout.ILayout">
+ <summary>
+ Interface implemented by layout objects
+ </summary>
+ <remarks>
+ <para>
+ An <see cref="T:log4net.Layout.ILayout"/> object is used to format a <see cref="T:log4net.Core.LoggingEvent"/>
+ as text. The <see cref="M:log4net.Layout.ILayout.Format(System.IO.TextWriter,log4net.Core.LoggingEvent)"/> method is called by an
+ appender to transform the <see cref="T:log4net.Core.LoggingEvent"/> into a string.
+ </para>
+ <para>
+ The layout can also supply <see cref="P:log4net.Layout.ILayout.Header"/> and <see cref="P:log4net.Layout.ILayout.Footer"/>
+ text that is appender before any events and after all the events respectively.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="M:log4net.Layout.ILayout.Format(System.IO.TextWriter,log4net.Core.LoggingEvent)">
+ <summary>
+ Implement this method to create your own layout format.
+ </summary>
+ <param name="writer">The TextWriter to write the formatted event to</param>
+ <param name="loggingEvent">The event to format</param>
+ <remarks>
+ <para>
+ This method is called by an appender to format
+ the <paramref name="loggingEvent"/> as text and output to a writer.
+ </para>
+ <para>
+ If the caller does not have a <see cref="T:System.IO.TextWriter"/> and prefers the
+ event to be formatted as a <see cref="T:System.String"/> then the following
+ code can be used to format the event into a <see cref="T:System.IO.StringWriter"/>.
+ </para>
+ <code lang="C#">
+ StringWriter writer = new StringWriter();
+ Layout.Format(writer, loggingEvent);
+ string formattedEvent = writer.ToString();
+ </code>
+ </remarks>
+ </member>
+ <member name="P:log4net.Layout.ILayout.ContentType">
+ <summary>
+ The content type output by this layout.
+ </summary>
+ <value>The content type</value>
+ <remarks>
+ <para>
+ The content type output by this layout.
+ </para>
+ <para>
+ This is a MIME type e.g. <c>"text/plain"</c>.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Layout.ILayout.Header">
+ <summary>
+ The header for the layout format.
+ </summary>
+ <value>the layout header</value>
+ <remarks>
+ <para>
+ The Header text will be appended before any logging events
+ are formatted and appended.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Layout.ILayout.Footer">
+ <summary>
+ The footer for the layout format.
+ </summary>
+ <value>the layout footer</value>
+ <remarks>
+ <para>
+ The Footer text will be appended after all the logging events
+ have been formatted and appended.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Layout.ILayout.IgnoresException">
+ <summary>
+ Flag indicating if this layout handle exceptions
+ </summary>
+ <value><c>false</c> if this layout handles exceptions</value>
+ <remarks>
+ <para>
+ If this layout handles the exception object contained within
+ <see cref="T:log4net.Core.LoggingEvent"/>, then the layout should return
+ <c>false</c>. Otherwise, if the layout ignores the exception
+ object, then the layout should return <c>true</c>.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Layout.LayoutSkeleton.m_header">
+ <summary>
+ The header text
+ </summary>
+ <remarks>
+ <para>
+ See <see cref="P:log4net.Layout.LayoutSkeleton.Header"/> for more information.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Layout.LayoutSkeleton.m_footer">
+ <summary>
+ The footer text
+ </summary>
+ <remarks>
+ <para>
+ See <see cref="P:log4net.Layout.LayoutSkeleton.Footer"/> for more information.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Layout.LayoutSkeleton.m_ignoresException">
+ <summary>
+ Flag indicating if this layout handles exceptions
+ </summary>
+ <remarks>
+ <para>
+ <c>false</c> if this layout handles exceptions
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Layout.LayoutSkeleton.#ctor">
+ <summary>
+ Empty default constructor
+ </summary>
+ <remarks>
+ <para>
+ Empty default constructor
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Layout.LayoutSkeleton.ActivateOptions">
+ <summary>
+ Activate component options
+ </summary>
+ <remarks>
+ <para>
+ This is part of the <see cref="T:log4net.Core.IOptionHandler"/> delayed object
+ activation scheme. The <see cref="M:log4net.Layout.LayoutSkeleton.ActivateOptions"/> method must
+ be called on this object after the configuration properties have
+ been set. Until <see cref="M:log4net.Layout.LayoutSkeleton.ActivateOptions"/> is called this
+ object is in an undefined state and must not be used.
+ </para>
+ <para>
+ If any of the configuration properties are modified then
+ <see cref="M:log4net.Layout.LayoutSkeleton.ActivateOptions"/> must be called again.
+ </para>
+ <para>
+ This method must be implemented by the subclass.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Layout.LayoutSkeleton.Format(System.IO.TextWriter,log4net.Core.LoggingEvent)">
+ <summary>
+ Implement this method to create your own layout format.
+ </summary>
+ <param name="writer">The TextWriter to write the formatted event to</param>
+ <param name="loggingEvent">The event to format</param>
+ <remarks>
+ <para>
+ This method is called by an appender to format
+ the <paramref name="loggingEvent"/> as text.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Layout.LayoutSkeleton.ContentType">
+ <summary>
+ The content type output by this layout.
+ </summary>
+ <value>The content type is <c>"text/plain"</c></value>
+ <remarks>
+ <para>
+ The content type output by this layout.
+ </para>
+ <para>
+ This base class uses the value <c>"text/plain"</c>.
+ To change this value a subclass must override this
+ property.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Layout.LayoutSkeleton.Header">
+ <summary>
+ The header for the layout format.
+ </summary>
+ <value>the layout header</value>
+ <remarks>
+ <para>
+ The Header text will be appended before any logging events
+ are formatted and appended.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Layout.LayoutSkeleton.Footer">
+ <summary>
+ The footer for the layout format.
+ </summary>
+ <value>the layout footer</value>
+ <remarks>
+ <para>
+ The Footer text will be appended after all the logging events
+ have been formatted and appended.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Layout.LayoutSkeleton.IgnoresException">
+ <summary>
+ Flag indicating if this layout handles exceptions
+ </summary>
+ <value><c>false</c> if this layout handles exceptions</value>
+ <remarks>
+ <para>
+ If this layout handles the exception object contained within
+ <see cref="T:log4net.Core.LoggingEvent"/>, then the layout should return
+ <c>false</c>. Otherwise, if the layout ignores the exception
+ object, then the layout should return <c>true</c>.
+ </para>
+ <para>
+ Set this value to override a this default setting. The default
+ value is <c>true</c>, this layout does not handle the exception.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Layout.ExceptionLayout.#ctor">
+ <summary>
+ Default constructor
+ </summary>
+ <remarks>
+ <para>
+ Constructs a ExceptionLayout
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Layout.ExceptionLayout.ActivateOptions">
+ <summary>
+ Activate component options
+ </summary>
+ <remarks>
+ <para>
+ Part of the <see cref="T:log4net.Core.IOptionHandler"/> component activation
+ framework.
+ </para>
+ <para>
+ This method does nothing as options become effective immediately.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Layout.ExceptionLayout.Format(System.IO.TextWriter,log4net.Core.LoggingEvent)">
+ <summary>
+ Gets the exception text from the logging event
+ </summary>
+ <param name="writer">The TextWriter to write the formatted event to</param>
+ <param name="loggingEvent">the event being logged</param>
+ <remarks>
+ <para>
+ Write the exception string to the <see cref="T:System.IO.TextWriter"/>.
+ The exception string is retrieved from <see cref="M:log4net.Core.LoggingEvent.GetExceptionString"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Layout.IRawLayout">
+ <summary>
+ Interface for raw layout objects
+ </summary>
+ <remarks>
+ <para>
+ Interface used to format a <see cref="T:log4net.Core.LoggingEvent"/>
+ to an object.
+ </para>
+ <para>
+ This interface should not be confused with the
+ <see cref="T:log4net.Layout.ILayout"/> interface. This interface is used in
+ only certain specialized situations where a raw object is
+ required rather than a formatted string. The <see cref="T:log4net.Layout.ILayout"/>
+ is not generally useful than this interface.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="M:log4net.Layout.IRawLayout.Format(log4net.Core.LoggingEvent)">
+ <summary>
+ Implement this method to create your own layout format.
+ </summary>
+ <param name="loggingEvent">The event to format</param>
+ <returns>returns the formatted event</returns>
+ <remarks>
+ <para>
+ Implement this method to create your own layout format.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Layout.Layout2RawLayoutAdapter">
+ <summary>
+ Adapts any <see cref="T:log4net.Layout.ILayout"/> to a <see cref="T:log4net.Layout.IRawLayout"/>
+ </summary>
+ <remarks>
+ <para>
+ Where an <see cref="T:log4net.Layout.IRawLayout"/> is required this adapter
+ allows a <see cref="T:log4net.Layout.ILayout"/> to be specified.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="F:log4net.Layout.Layout2RawLayoutAdapter.m_layout">
+ <summary>
+ The layout to adapt
+ </summary>
+ </member>
+ <member name="M:log4net.Layout.Layout2RawLayoutAdapter.#ctor(log4net.Layout.ILayout)">
+ <summary>
+ Construct a new adapter
+ </summary>
+ <param name="layout">the layout to adapt</param>
+ <remarks>
+ <para>
+ Create the adapter for the specified <paramref name="layout"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Layout.Layout2RawLayoutAdapter.Format(log4net.Core.LoggingEvent)">
+ <summary>
+ Format the logging event as an object.
+ </summary>
+ <param name="loggingEvent">The event to format</param>
+ <returns>returns the formatted event</returns>
+ <remarks>
+ <para>
+ Format the logging event as an object.
+ </para>
+ <para>
+ Uses the <see cref="T:log4net.Layout.ILayout"/> object supplied to
+ the constructor to perform the formatting.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Layout.PatternLayout">
+ <summary>
+ A flexible layout configurable with pattern string.
+ </summary>
+ <remarks>
+ <para>
+ The goal of this class is to <see cref="M:log4net.Layout.PatternLayout.Format(System.IO.TextWriter,log4net.Core.LoggingEvent)"/> a
+ <see cref="T:log4net.Core.LoggingEvent"/> as a string. The results
+ depend on the <i>conversion pattern</i>.
+ </para>
+ <para>
+ The conversion pattern is closely related to the conversion
+ pattern of the printf function in C. A conversion pattern is
+ composed of literal text and format control expressions called
+ <i>conversion specifiers</i>.
+ </para>
+ <para>
+ <i>You are free to insert any literal text within the conversion
+ pattern.</i>
+ </para>
+ <para>
+ Each conversion specifier starts with a percent sign (%) and is
+ followed by optional <i>format modifiers</i> and a <i>conversion
+ pattern name</i>. The conversion pattern name specifies the type of
+ data, e.g. logger, level, date, thread name. The format
+ modifiers control such things as field width, padding, left and
+ right justification. The following is a simple example.
+ </para>
+ <para>
+ Let the conversion pattern be <b>"%-5level [%thread]: %message%newline"</b> and assume
+ that the log4net environment was set to use a PatternLayout. Then the
+ statements
+ </para>
+ <code lang="C#">
+ ILog log = LogManager.GetLogger(typeof(TestApp));
+ log.Debug("Message 1");
+ log.Warn("Message 2");
+ </code>
+ <para>would yield the output</para>
+ <code>
+ DEBUG [main]: Message 1
+ WARN [main]: Message 2
+ </code>
+ <para>
+ Note that there is no explicit separator between text and
+ conversion specifiers. The pattern parser knows when it has reached
+ the end of a conversion specifier when it reads a conversion
+ character. In the example above the conversion specifier
+ <b>%-5level</b> means the level of the logging event should be left
+ justified to a width of five characters.
+ </para>
+ <para>
+ The recognized conversion pattern names are:
+ </para>
+ <list type="table">
+ <listheader>
+ <term>Conversion Pattern Name</term>
+ <description>Effect</description>
+ </listheader>
+ <item>
+ <term>a</term>
+ <description>Equivalent to <b>appdomain</b></description>
+ </item>
+ <item>
+ <term>appdomain</term>
+ <description>
+ Used to output the friendly name of the AppDomain where the
+ logging event was generated.
+ </description>
+ </item>
+ <item>
+ <term>c</term>
+ <description>Equivalent to <b>logger</b></description>
+ </item>
+ <item>
+ <term>C</term>
+ <description>Equivalent to <b>type</b></description>
+ </item>
+ <item>
+ <term>class</term>
+ <description>Equivalent to <b>type</b></description>
+ </item>
+ <item>
+ <term>d</term>
+ <description>Equivalent to <b>date</b></description>
+ </item>
+ <item>
+ <term>date</term>
+ <description>
+ <para>
+ Used to output the date of the logging event in the local time zone.
+ To output the date in universal time use the <c>%utcdate</c> pattern.
+ The date conversion
+ specifier may be followed by a <i>date format specifier</i> enclosed
+ between braces. For example, <b>%date{HH:mm:ss,fff}</b> or
+ <b>%date{dd MMM yyyy HH:mm:ss,fff}</b>. If no date format specifier is
+ given then ISO8601 format is
+ assumed (<see cref="T:log4net.DateFormatter.Iso8601DateFormatter"/>).
+ </para>
+ <para>
+ The date format specifier admits the same syntax as the
+ time pattern string of the <see cref="M:System.DateTime.ToString(System.String)"/>.
+ </para>
+ <para>
+ For better results it is recommended to use the log4net date
+ formatters. These can be specified using one of the strings
+ "ABSOLUTE", "DATE" and "ISO8601" for specifying
+ <see cref="T:log4net.DateFormatter.AbsoluteTimeDateFormatter"/>,
+ <see cref="T:log4net.DateFormatter.DateTimeDateFormatter"/> and respectively
+ <see cref="T:log4net.DateFormatter.Iso8601DateFormatter"/>. For example,
+ <b>%date{ISO8601}</b> or <b>%date{ABSOLUTE}</b>.
+ </para>
+ <para>
+ These dedicated date formatters perform significantly
+ better than <see cref="M:System.DateTime.ToString(System.String)"/>.
+ </para>
+ </description>
+ </item>
+ <item>
+ <term>exception</term>
+ <description>
+ <para>
+ Used to output the exception passed in with the log message.
+ </para>
+ <para>
+ If an exception object is stored in the logging event
+ it will be rendered into the pattern output with a
+ trailing newline.
+ If there is no exception then nothing will be output
+ and no trailing newline will be appended.
+ It is typical to put a newline before the exception
+ and to have the exception as the last data in the pattern.
+ </para>
+ </description>
+ </item>
+ <item>
+ <term>F</term>
+ <description>Equivalent to <b>file</b></description>
+ </item>
+ <item>
+ <term>file</term>
+ <description>
+ <para>
+ Used to output the file name where the logging request was
+ issued.
+ </para>
+ <para>
+ <b>WARNING</b> Generating caller location information is
+ extremely slow. Its use should be avoided unless execution speed
+ is not an issue.
+ </para>
+ <para>
+ See the note below on the availability of caller location information.
+ </para>
+ </description>
+ </item>
+ <item>
+ <term>identity</term>
+ <description>
+ <para>
+ Used to output the user name for the currently active user
+ (Principal.Identity.Name).
+ </para>
+ <para>
+ <b>WARNING</b> Generating caller information is
+ extremely slow. Its use should be avoided unless execution speed
+ is not an issue.
+ </para>
+ </description>
+ </item>
+ <item>
+ <term>l</term>
+ <description>Equivalent to <b>location</b></description>
+ </item>
+ <item>
+ <term>L</term>
+ <description>Equivalent to <b>line</b></description>
+ </item>
+ <item>
+ <term>location</term>
+ <description>
+ <para>
+ Used to output location information of the caller which generated
+ the logging event.
+ </para>
+ <para>
+ The location information depends on the CLI implementation but
+ usually consists of the fully qualified name of the calling
+ method followed by the callers source the file name and line
+ number between parentheses.
+ </para>
+ <para>
+ The location information can be very useful. However, its
+ generation is <b>extremely</b> slow. Its use should be avoided
+ unless execution speed is not an issue.
+ </para>
+ <para>
+ See the note below on the availability of caller location information.
+ </para>
+ </description>
+ </item>
+ <item>
+ <term>level</term>
+ <description>
+ <para>
+ Used to output the level of the logging event.
+ </para>
+ </description>
+ </item>
+ <item>
+ <term>line</term>
+ <description>
+ <para>
+ Used to output the line number from where the logging request
+ was issued.
+ </para>
+ <para>
+ <b>WARNING</b> Generating caller location information is
+ extremely slow. Its use should be avoided unless execution speed
+ is not an issue.
+ </para>
+ <para>
+ See the note below on the availability of caller location information.
+ </para>
+ </description>
+ </item>
+ <item>
+ <term>logger</term>
+ <description>
+ <para>
+ Used to output the logger of the logging event. The
+ logger conversion specifier can be optionally followed by
+ <i>precision specifier</i>, that is a decimal constant in
+ brackets.
+ </para>
+ <para>
+ If a precision specifier is given, then only the corresponding
+ number of right most components of the logger name will be
+ printed. By default the logger name is printed in full.
+ </para>
+ <para>
+ For example, for the logger name "a.b.c" the pattern
+ <b>%logger{2}</b> will output "b.c".
+ </para>
+ </description>
+ </item>
+ <item>
+ <term>m</term>
+ <description>Equivalent to <b>message</b></description>
+ </item>
+ <item>
+ <term>M</term>
+ <description>Equivalent to <b>method</b></description>
+ </item>
+ <item>
+ <term>message</term>
+ <description>
+ <para>
+ Used to output the application supplied message associated with
+ the logging event.
+ </para>
+ </description>
+ </item>
+ <item>
+ <term>mdc</term>
+ <description>
+ <para>
+ The MDC (old name for the ThreadContext.Properties) is now part of the
+ combined event properties. This pattern is supported for compatibility
+ but is equivalent to <b>property</b>.
+ </para>
+ </description>
+ </item>
+ <item>
+ <term>method</term>
+ <description>
+ <para>
+ Used to output the method name where the logging request was
+ issued.
+ </para>
+ <para>
+ <b>WARNING</b> Generating caller location information is
+ extremely slow. Its use should be avoided unless execution speed
+ is not an issue.
+ </para>
+ <para>
+ See the note below on the availability of caller location information.
+ </para>
+ </description>
+ </item>
+ <item>
+ <term>n</term>
+ <description>Equivalent to <b>newline</b></description>
+ </item>
+ <item>
+ <term>newline</term>
+ <description>
+ <para>
+ Outputs the platform dependent line separator character or
+ characters.
+ </para>
+ <para>
+ This conversion pattern offers the same performance as using
+ non-portable line separator strings such as "\n", or "\r\n".
+ Thus, it is the preferred way of specifying a line separator.
+ </para>
+ </description>
+ </item>
+ <item>
+ <term>ndc</term>
+ <description>
+ <para>
+ Used to output the NDC (nested diagnostic context) associated
+ with the thread that generated the logging event.
+ </para>
+ </description>
+ </item>
+ <item>
+ <term>p</term>
+ <description>Equivalent to <b>level</b></description>
+ </item>
+ <item>
+ <term>P</term>
+ <description>Equivalent to <b>property</b></description>
+ </item>
+ <item>
+ <term>properties</term>
+ <description>Equivalent to <b>property</b></description>
+ </item>
+ <item>
+ <term>property</term>
+ <description>
+ <para>
+ Used to output the an event specific property. The key to
+ lookup must be specified within braces and directly following the
+ pattern specifier, e.g. <b>%property{user}</b> would include the value
+ from the property that is keyed by the string 'user'. Each property value
+ that is to be included in the log must be specified separately.
+ Properties are added to events by loggers or appenders. By default
+ the <c>log4net:HostName</c> property is set to the name of machine on
+ which the event was originally logged.
+ </para>
+ <para>
+ If no key is specified, e.g. <b>%property</b> then all the keys and their
+ values are printed in a comma separated list.
+ </para>
+ <para>
+ The properties of an event are combined from a number of different
+ contexts. These are listed below in the order in which they are searched.
+ </para>
+ <list type="definition">
+ <item>
+ <term>the event properties</term>
+ <description>
+ The event has <see cref="P:log4net.Core.LoggingEvent.Properties"/> that can be set. These
+ properties are specific to this event only.
+ </description>
+ </item>
+ <item>
+ <term>the thread properties</term>
+ <description>
+ The <see cref="P:log4net.ThreadContext.Properties"/> that are set on the current
+ thread. These properties are shared by all events logged on this thread.
+ </description>
+ </item>
+ <item>
+ <term>the global properties</term>
+ <description>
+ The <see cref="P:log4net.GlobalContext.Properties"/> that are set globally. These
+ properties are shared by all the threads in the AppDomain.
+ </description>
+ </item>
+ </list>
+
+ </description>
+ </item>
+ <item>
+ <term>r</term>
+ <description>Equivalent to <b>timestamp</b></description>
+ </item>
+ <item>
+ <term>t</term>
+ <description>Equivalent to <b>thread</b></description>
+ </item>
+ <item>
+ <term>timestamp</term>
+ <description>
+ <para>
+ Used to output the number of milliseconds elapsed since the start
+ of the application until the creation of the logging event.
+ </para>
+ </description>
+ </item>
+ <item>
+ <term>thread</term>
+ <description>
+ <para>
+ Used to output the name of the thread that generated the
+ logging event. Uses the thread number if no name is available.
+ </para>
+ </description>
+ </item>
+ <item>
+ <term>type</term>
+ <description>
+ <para>
+ Used to output the fully qualified type name of the caller
+ issuing the logging request. This conversion specifier
+ can be optionally followed by <i>precision specifier</i>, that
+ is a decimal constant in brackets.
+ </para>
+ <para>
+ If a precision specifier is given, then only the corresponding
+ number of right most components of the class name will be
+ printed. By default the class name is output in fully qualified form.
+ </para>
+ <para>
+ For example, for the class name "log4net.Layout.PatternLayout", the
+ pattern <b>%type{1}</b> will output "PatternLayout".
+ </para>
+ <para>
+ <b>WARNING</b> Generating the caller class information is
+ slow. Thus, its use should be avoided unless execution speed is
+ not an issue.
+ </para>
+ <para>
+ See the note below on the availability of caller location information.
+ </para>
+ </description>
+ </item>
+ <item>
+ <term>u</term>
+ <description>Equivalent to <b>identity</b></description>
+ </item>
+ <item>
+ <term>username</term>
+ <description>
+ <para>
+ Used to output the WindowsIdentity for the currently
+ active user.
+ </para>
+ <para>
+ <b>WARNING</b> Generating caller WindowsIdentity information is
+ extremely slow. Its use should be avoided unless execution speed
+ is not an issue.
+ </para>
+ </description>
+ </item>
+ <item>
+ <term>utcdate</term>
+ <description>
+ <para>
+ Used to output the date of the logging event in universal time.
+ The date conversion
+ specifier may be followed by a <i>date format specifier</i> enclosed
+ between braces. For example, <b>%utcdate{HH:mm:ss,fff}</b> or
+ <b>%utcdate{dd MMM yyyy HH:mm:ss,fff}</b>. If no date format specifier is
+ given then ISO8601 format is
+ assumed (<see cref="T:log4net.DateFormatter.Iso8601DateFormatter"/>).
+ </para>
+ <para>
+ The date format specifier admits the same syntax as the
+ time pattern string of the <see cref="M:System.DateTime.ToString(System.String)"/>.
+ </para>
+ <para>
+ For better results it is recommended to use the log4net date
+ formatters. These can be specified using one of the strings
+ "ABSOLUTE", "DATE" and "ISO8601" for specifying
+ <see cref="T:log4net.DateFormatter.AbsoluteTimeDateFormatter"/>,
+ <see cref="T:log4net.DateFormatter.DateTimeDateFormatter"/> and respectively
+ <see cref="T:log4net.DateFormatter.Iso8601DateFormatter"/>. For example,
+ <b>%utcdate{ISO8601}</b> or <b>%utcdate{ABSOLUTE}</b>.
+ </para>
+ <para>
+ These dedicated date formatters perform significantly
+ better than <see cref="M:System.DateTime.ToString(System.String)"/>.
+ </para>
+ </description>
+ </item>
+ <item>
+ <term>w</term>
+ <description>Equivalent to <b>username</b></description>
+ </item>
+ <item>
+ <term>x</term>
+ <description>Equivalent to <b>ndc</b></description>
+ </item>
+ <item>
+ <term>X</term>
+ <description>Equivalent to <b>mdc</b></description>
+ </item>
+ <item>
+ <term>%</term>
+ <description>
+ <para>
+ The sequence %% outputs a single percent sign.
+ </para>
+ </description>
+ </item>
+ </list>
+ <para>
+ The single letter patterns are deprecated in favor of the
+ longer more descriptive pattern names.
+ </para>
+ <para>
+ By default the relevant information is output as is. However,
+ with the aid of format modifiers it is possible to change the
+ minimum field width, the maximum field width and justification.
+ </para>
+ <para>
+ The optional format modifier is placed between the percent sign
+ and the conversion pattern name.
+ </para>
+ <para>
+ The first optional format modifier is the <i>left justification
+ flag</i> which is just the minus (-) character. Then comes the
+ optional <i>minimum field width</i> modifier. This is a decimal
+ constant that represents the minimum number of characters to
+ output. If the data item requires fewer characters, it is padded on
+ either the left or the right until the minimum width is
+ reached. The default is to pad on the left (right justify) but you
+ can specify right padding with the left justification flag. The
+ padding character is space. If the data item is larger than the
+ minimum field width, the field is expanded to accommodate the
+ data. The value is never truncated.
+ </para>
+ <para>
+ This behavior can be changed using the <i>maximum field
+ width</i> modifier which is designated by a period followed by a
+ decimal constant. If the data item is longer than the maximum
+ field, then the extra characters are removed from the
+ <i>beginning</i> of the data item and not from the end. For
+ example, it the maximum field width is eight and the data item is
+ ten characters long, then the first two characters of the data item
+ are dropped. This behavior deviates from the printf function in C
+ where truncation is done from the end.
+ </para>
+ <para>
+ Below are various format modifier examples for the logger
+ conversion specifier.
+ </para>
+ <div class="tablediv">
+ <table class="dtTABLE" cellspacing="0">
+ <tr>
+ <th>Format modifier</th>
+ <th>left justify</th>
+ <th>minimum width</th>
+ <th>maximum width</th>
+ <th>comment</th>
+ </tr>
+ <tr>
+ <td align="center">%20logger</td>
+ <td align="center">false</td>
+ <td align="center">20</td>
+ <td align="center">none</td>
+ <td>
+ <para>
+ Left pad with spaces if the logger name is less than 20
+ characters long.
+ </para>
+ </td>
+ </tr>
+ <tr>
+ <td align="center">%-20logger</td>
+ <td align="center">true</td>
+ <td align="center">20</td>
+ <td align="center">none</td>
+ <td>
+ <para>
+ Right pad with spaces if the logger
+ name is less than 20 characters long.
+ </para>
+ </td>
+ </tr>
+ <tr>
+ <td align="center">%.30logger</td>
+ <td align="center">NA</td>
+ <td align="center">none</td>
+ <td align="center">30</td>
+ <td>
+ <para>
+ Truncate from the beginning if the logger
+ name is longer than 30 characters.
+ </para>
+ </td>
+ </tr>
+ <tr>
+ <td align="center"><nobr>%20.30logger</nobr></td>
+ <td align="center">false</td>
+ <td align="center">20</td>
+ <td align="center">30</td>
+ <td>
+ <para>
+ Left pad with spaces if the logger name is shorter than 20
+ characters. However, if logger name is longer than 30 characters,
+ then truncate from the beginning.
+ </para>
+ </td>
+ </tr>
+ <tr>
+ <td align="center">%-20.30logger</td>
+ <td align="center">true</td>
+ <td align="center">20</td>
+ <td align="center">30</td>
+ <td>
+ <para>
+ Right pad with spaces if the logger name is shorter than 20
+ characters. However, if logger name is longer than 30 characters,
+ then truncate from the beginning.
+ </para>
+ </td>
+ </tr>
+ </table>
+ </div>
+ <para>
+ <b>Note about caller location information.</b><br/>
+ The following patterns <c>%type %file %line %method %location %class %C %F %L %l %M</c>
+ all generate caller location information.
+ Location information uses the <c>System.Diagnostics.StackTrace</c> class to generate
+ a call stack. The caller's information is then extracted from this stack.
+ </para>
+ <note type="caution">
+ <para>
+ The <c>System.Diagnostics.StackTrace</c> class is not supported on the
+ .NET Compact Framework 1.0 therefore caller location information is not
+ available on that framework.
+ </para>
+ </note>
+ <note type="caution">
+ <para>
+ The <c>System.Diagnostics.StackTrace</c> class has this to say about Release builds:
+ </para>
+ <para>
+ "StackTrace information will be most informative with Debug build configurations.
+ By default, Debug builds include debug symbols, while Release builds do not. The
+ debug symbols contain most of the file, method name, line number, and column
+ information used in constructing StackFrame and StackTrace objects. StackTrace
+ might not report as many method calls as expected, due to code transformations
+ that occur during optimization."
+ </para>
+ <para>
+ This means that in a Release build the caller information may be incomplete or may
+ not exist at all! Therefore caller location information cannot be relied upon in a Release build.
+ </para>
+ </note>
+ <para>
+ Additional pattern converters may be registered with a specific <see cref="T:log4net.Layout.PatternLayout"/>
+ instance using the <see cref="M:log4net.Layout.PatternLayout.AddConverter(System.String,System.Type)"/> method.
+ </para>
+ </remarks>
+ <example>
+ This is a more detailed pattern.
+ <code><b>%timestamp [%thread] %level %logger %ndc - %message%newline</b></code>
+ </example>
+ <example>
+ A similar pattern except that the relative time is
+ right padded if less than 6 digits, thread name is right padded if
+ less than 15 characters and truncated if longer and the logger
+ name is left padded if shorter than 30 characters and truncated if
+ longer.
+ <code><b>%-6timestamp [%15.15thread] %-5level %30.30logger %ndc - %message%newline</b></code>
+ </example>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ <author>Douglas de la Torre</author>
+ <author>Daniel Cazzulino</author>
+ </member>
+ <member name="F:log4net.Layout.PatternLayout.DefaultConversionPattern">
+ <summary>
+ Default pattern string for log output.
+ </summary>
+ <remarks>
+ <para>
+ Default pattern string for log output.
+ Currently set to the string <b>"%message%newline"</b>
+ which just prints the application supplied message.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Layout.PatternLayout.DetailConversionPattern">
+ <summary>
+ A detailed conversion pattern
+ </summary>
+ <remarks>
+ <para>
+ A conversion pattern which includes Time, Thread, Logger, and Nested Context.
+ Current value is <b>%timestamp [%thread] %level %logger %ndc - %message%newline</b>.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Layout.PatternLayout.s_globalRulesRegistry">
+ <summary>
+ Internal map of converter identifiers to converter types.
+ </summary>
+ <remarks>
+ <para>
+ This static map is overridden by the m_converterRegistry instance map
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Layout.PatternLayout.m_pattern">
+ <summary>
+ the pattern
+ </summary>
+ </member>
+ <member name="F:log4net.Layout.PatternLayout.m_head">
+ <summary>
+ the head of the pattern converter chain
+ </summary>
+ </member>
+ <member name="F:log4net.Layout.PatternLayout.m_instanceRulesRegistry">
+ <summary>
+ patterns defined on this PatternLayout only
+ </summary>
+ </member>
+ <member name="M:log4net.Layout.PatternLayout.#cctor">
+ <summary>
+ Initialize the global registry
+ </summary>
+ <remarks>
+ <para>
+ Defines the builtin global rules.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Layout.PatternLayout.#ctor">
+ <summary>
+ Constructs a PatternLayout using the DefaultConversionPattern
+ </summary>
+ <remarks>
+ <para>
+ The default pattern just produces the application supplied message.
+ </para>
+ <para>
+ Note to Inheritors: This constructor calls the virtual method
+ <see cref="M:log4net.Layout.PatternLayout.CreatePatternParser(System.String)"/>. If you override this method be
+ aware that it will be called before your is called constructor.
+ </para>
+ <para>
+ As per the <see cref="T:log4net.Core.IOptionHandler"/> contract the <see cref="M:log4net.Layout.PatternLayout.ActivateOptions"/>
+ method must be called after the properties on this object have been
+ configured.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Layout.PatternLayout.#ctor(System.String)">
+ <summary>
+ Constructs a PatternLayout using the supplied conversion pattern
+ </summary>
+ <param name="pattern">the pattern to use</param>
+ <remarks>
+ <para>
+ Note to Inheritors: This constructor calls the virtual method
+ <see cref="M:log4net.Layout.PatternLayout.CreatePatternParser(System.String)"/>. If you override this method be
+ aware that it will be called before your is called constructor.
+ </para>
+ <para>
+ When using this constructor the <see cref="M:log4net.Layout.PatternLayout.ActivateOptions"/> method
+ need not be called. This may not be the case when using a subclass.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Layout.PatternLayout.CreatePatternParser(System.String)">
+ <summary>
+ Create the pattern parser instance
+ </summary>
+ <param name="pattern">the pattern to parse</param>
+ <returns>The <see cref="T:log4net.Util.PatternParser"/> that will format the event</returns>
+ <remarks>
+ <para>
+ Creates the <see cref="T:log4net.Util.PatternParser"/> used to parse the conversion string. Sets the
+ global and instance rules on the <see cref="T:log4net.Util.PatternParser"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Layout.PatternLayout.ActivateOptions">
+ <summary>
+ Initialize layout options
+ </summary>
+ <remarks>
+ <para>
+ This is part of the <see cref="T:log4net.Core.IOptionHandler"/> delayed object
+ activation scheme. The <see cref="M:log4net.Layout.PatternLayout.ActivateOptions"/> method must
+ be called on this object after the configuration properties have
+ been set. Until <see cref="M:log4net.Layout.PatternLayout.ActivateOptions"/> is called this
+ object is in an undefined state and must not be used.
+ </para>
+ <para>
+ If any of the configuration properties are modified then
+ <see cref="M:log4net.Layout.PatternLayout.ActivateOptions"/> must be called again.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Layout.PatternLayout.Format(System.IO.TextWriter,log4net.Core.LoggingEvent)">
+ <summary>
+ Produces a formatted string as specified by the conversion pattern.
+ </summary>
+ <param name="loggingEvent">the event being logged</param>
+ <param name="writer">The TextWriter to write the formatted event to</param>
+ <remarks>
+ <para>
+ Parse the <see cref="T:log4net.Core.LoggingEvent"/> using the patter format
+ specified in the <see cref="P:log4net.Layout.PatternLayout.ConversionPattern"/> property.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Layout.PatternLayout.AddConverter(log4net.Layout.PatternLayout.ConverterInfo)">
+ <summary>
+ Add a converter to this PatternLayout
+ </summary>
+ <param name="converterInfo">the converter info</param>
+ <remarks>
+ <para>
+ This version of the method is used by the configurator.
+ Programmatic users should use the alternative <see cref="M:log4net.Layout.PatternLayout.AddConverter(System.String,System.Type)"/> method.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Layout.PatternLayout.AddConverter(System.String,System.Type)">
+ <summary>
+ Add a converter to this PatternLayout
+ </summary>
+ <param name="name">the name of the conversion pattern for this converter</param>
+ <param name="type">the type of the converter</param>
+ <remarks>
+ <para>
+ Add a named pattern converter to this instance. This
+ converter will be used in the formatting of the event.
+ This method must be called before <see cref="M:log4net.Layout.PatternLayout.ActivateOptions"/>.
+ </para>
+ <para>
+ The <paramref name="type"/> specified must extend the
+ <see cref="T:log4net.Util.PatternConverter"/> type.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Layout.PatternLayout.ConversionPattern">
+ <summary>
+ The pattern formatting string
+ </summary>
+ <remarks>
+ <para>
+ The <b>ConversionPattern</b> option. This is the string which
+ controls formatting and consists of a mix of literal content and
+ conversion specifiers.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Layout.PatternLayout.ConverterInfo">
+ <summary>
+ Wrapper class used to map converter names to converter types
+ </summary>
+ <remarks>
+ <para>
+ Pattern converter info class used during configuration to
+ pass to the <see cref="M:log4net.Layout.PatternLayout.AddConverter(log4net.Layout.PatternLayout.ConverterInfo)"/>
+ method.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Layout.PatternLayout.ConverterInfo.#ctor">
+ <summary>
+ default constructor
+ </summary>
+ </member>
+ <member name="P:log4net.Layout.PatternLayout.ConverterInfo.Name">
+ <summary>
+ Gets or sets the name of the conversion pattern
+ </summary>
+ <remarks>
+ <para>
+ The name of the pattern in the format string
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Layout.PatternLayout.ConverterInfo.Type">
+ <summary>
+ Gets or sets the type of the converter
+ </summary>
+ <remarks>
+ <para>
+ The value specified must extend the
+ <see cref="T:log4net.Util.PatternConverter"/> type.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Layout.RawLayoutConverter">
+ <summary>
+ Type converter for the <see cref="T:log4net.Layout.IRawLayout"/> interface
+ </summary>
+ <remarks>
+ <para>
+ Used to convert objects to the <see cref="T:log4net.Layout.IRawLayout"/> interface.
+ Supports converting from the <see cref="T:log4net.Layout.ILayout"/> interface to
+ the <see cref="T:log4net.Layout.IRawLayout"/> interface using the <see cref="T:log4net.Layout.Layout2RawLayoutAdapter"/>.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="T:log4net.Util.TypeConverters.IConvertFrom">
+ <summary>
+ Interface supported by type converters
+ </summary>
+ <remarks>
+ <para>
+ This interface supports conversion from arbitrary types
+ to a single target type. See <see cref="T:log4net.Util.TypeConverters.TypeConverterAttribute"/>.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="M:log4net.Util.TypeConverters.IConvertFrom.CanConvertFrom(System.Type)">
+ <summary>
+ Can the source type be converted to the type supported by this object
+ </summary>
+ <param name="sourceType">the type to convert</param>
+ <returns>true if the conversion is possible</returns>
+ <remarks>
+ <para>
+ Test if the <paramref name="sourceType"/> can be converted to the
+ type supported by this converter.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.TypeConverters.IConvertFrom.ConvertFrom(System.Object)">
+ <summary>
+ Convert the source object to the type supported by this object
+ </summary>
+ <param name="source">the object to convert</param>
+ <returns>the converted object</returns>
+ <remarks>
+ <para>
+ Converts the <paramref name="source"/> to the type supported
+ by this converter.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Layout.RawLayoutConverter.CanConvertFrom(System.Type)">
+ <summary>
+ Can the sourceType be converted to an <see cref="T:log4net.Layout.IRawLayout"/>
+ </summary>
+ <param name="sourceType">the source to be to be converted</param>
+ <returns><c>true</c> if the source type can be converted to <see cref="T:log4net.Layout.IRawLayout"/></returns>
+ <remarks>
+ <para>
+ Test if the <paramref name="sourceType"/> can be converted to a
+ <see cref="T:log4net.Layout.IRawLayout"/>. Only <see cref="T:log4net.Layout.ILayout"/> is supported
+ as the <paramref name="sourceType"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Layout.RawLayoutConverter.ConvertFrom(System.Object)">
+ <summary>
+ Convert the value to a <see cref="T:log4net.Layout.IRawLayout"/> object
+ </summary>
+ <param name="source">the value to convert</param>
+ <returns>the <see cref="T:log4net.Layout.IRawLayout"/> object</returns>
+ <remarks>
+ <para>
+ Convert the <paramref name="source"/> object to a
+ <see cref="T:log4net.Layout.IRawLayout"/> object. If the <paramref name="source"/> object
+ is a <see cref="T:log4net.Layout.ILayout"/> then the <see cref="T:log4net.Layout.Layout2RawLayoutAdapter"/>
+ is used to adapt between the two interfaces, otherwise an
+ exception is thrown.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Layout.RawPropertyLayout">
+ <summary>
+ Extract the value of a property from the <see cref="T:log4net.Core.LoggingEvent"/>
+ </summary>
+ <remarks>
+ <para>
+ Extract the value of a property from the <see cref="T:log4net.Core.LoggingEvent"/>
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="M:log4net.Layout.RawPropertyLayout.#ctor">
+ <summary>
+ Constructs a RawPropertyLayout
+ </summary>
+ </member>
+ <member name="M:log4net.Layout.RawPropertyLayout.Format(log4net.Core.LoggingEvent)">
+ <summary>
+ Lookup the property for <see cref="P:log4net.Layout.RawPropertyLayout.Key"/>
+ </summary>
+ <param name="loggingEvent">The event to format</param>
+ <returns>returns property value</returns>
+ <remarks>
+ <para>
+ Looks up and returns the object value of the property
+ named <see cref="P:log4net.Layout.RawPropertyLayout.Key"/>. If there is no property defined
+ with than name then <c>null</c> will be returned.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Layout.RawPropertyLayout.Key">
+ <summary>
+ The name of the value to lookup in the LoggingEvent Properties collection.
+ </summary>
+ <value>
+ Value to lookup in the LoggingEvent Properties collection
+ </value>
+ <remarks>
+ <para>
+ String name of the property to lookup in the <see cref="T:log4net.Core.LoggingEvent"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Layout.RawTimeStampLayout">
+ <summary>
+ Extract the date from the <see cref="T:log4net.Core.LoggingEvent"/>
+ </summary>
+ <remarks>
+ <para>
+ Extract the date from the <see cref="T:log4net.Core.LoggingEvent"/>
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="M:log4net.Layout.RawTimeStampLayout.#ctor">
+ <summary>
+ Constructs a RawTimeStampLayout
+ </summary>
+ </member>
+ <member name="M:log4net.Layout.RawTimeStampLayout.Format(log4net.Core.LoggingEvent)">
+ <summary>
+ Gets the <see cref="P:log4net.Core.LoggingEvent.TimeStamp"/> as a <see cref="T:System.DateTime"/>.
+ </summary>
+ <param name="loggingEvent">The event to format</param>
+ <returns>returns the time stamp</returns>
+ <remarks>
+ <para>
+ Gets the <see cref="P:log4net.Core.LoggingEvent.TimeStamp"/> as a <see cref="T:System.DateTime"/>.
+ </para>
+ <para>
+ The time stamp is in local time. To format the time stamp
+ in universal time use <see cref="T:log4net.Layout.RawUtcTimeStampLayout"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Layout.RawUtcTimeStampLayout">
+ <summary>
+ Extract the date from the <see cref="T:log4net.Core.LoggingEvent"/>
+ </summary>
+ <remarks>
+ <para>
+ Extract the date from the <see cref="T:log4net.Core.LoggingEvent"/>
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="M:log4net.Layout.RawUtcTimeStampLayout.#ctor">
+ <summary>
+ Constructs a RawUtcTimeStampLayout
+ </summary>
+ </member>
+ <member name="M:log4net.Layout.RawUtcTimeStampLayout.Format(log4net.Core.LoggingEvent)">
+ <summary>
+ Gets the <see cref="P:log4net.Core.LoggingEvent.TimeStamp"/> as a <see cref="T:System.DateTime"/>.
+ </summary>
+ <param name="loggingEvent">The event to format</param>
+ <returns>returns the time stamp</returns>
+ <remarks>
+ <para>
+ Gets the <see cref="P:log4net.Core.LoggingEvent.TimeStamp"/> as a <see cref="T:System.DateTime"/>.
+ </para>
+ <para>
+ The time stamp is in universal time. To format the time stamp
+ in local time use <see cref="T:log4net.Layout.RawTimeStampLayout"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Layout.SimpleLayout">
+ <summary>
+ A very simple layout
+ </summary>
+ <remarks>
+ <para>
+ SimpleLayout consists of the level of the log statement,
+ followed by " - " and then the log message itself. For example,
+ <code>
+ DEBUG - Hello world
+ </code>
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="M:log4net.Layout.SimpleLayout.#ctor">
+ <summary>
+ Constructs a SimpleLayout
+ </summary>
+ </member>
+ <member name="M:log4net.Layout.SimpleLayout.ActivateOptions">
+ <summary>
+ Initialize layout options
+ </summary>
+ <remarks>
+ <para>
+ This is part of the <see cref="T:log4net.Core.IOptionHandler"/> delayed object
+ activation scheme. The <see cref="M:log4net.Layout.SimpleLayout.ActivateOptions"/> method must
+ be called on this object after the configuration properties have
+ been set. Until <see cref="M:log4net.Layout.SimpleLayout.ActivateOptions"/> is called this
+ object is in an undefined state and must not be used.
+ </para>
+ <para>
+ If any of the configuration properties are modified then
+ <see cref="M:log4net.Layout.SimpleLayout.ActivateOptions"/> must be called again.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Layout.SimpleLayout.Format(System.IO.TextWriter,log4net.Core.LoggingEvent)">
+ <summary>
+ Produces a simple formatted output.
+ </summary>
+ <param name="loggingEvent">the event being logged</param>
+ <param name="writer">The TextWriter to write the formatted event to</param>
+ <remarks>
+ <para>
+ Formats the event as the level of the even,
+ followed by " - " and then the log message itself. The
+ output is terminated by a newline.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Layout.XmlLayout">
+ <summary>
+ Layout that formats the log events as XML elements.
+ </summary>
+ <remarks>
+ <para>
+ The output of the <see cref="T:log4net.Layout.XmlLayout"/> consists of a series of
+ log4net:event elements. It does not output a complete well-formed XML
+ file. The output is designed to be included as an <em>external entity</em>
+ in a separate file to form a correct XML file.
+ </para>
+ <para>
+ For example, if <c>abc</c> is the name of the file where
+ the <see cref="T:log4net.Layout.XmlLayout"/> output goes, then a well-formed XML file would
+ be:
+ </para>
+ <code lang="XML">
+ &lt;?xml version="1.0" ?&gt;
+
+ &lt;!DOCTYPE log4net:events SYSTEM "log4net-events.dtd" [&lt;!ENTITY data SYSTEM "abc"&gt;]&gt;
+
+ &lt;log4net:events version="1.2" xmlns:log4net="http://logging.apache.org/log4net/schemas/log4net-events-1.2&gt;
+ &amp;data;
+ &lt;/log4net:events&gt;
+ </code>
+ <para>
+ This approach enforces the independence of the <see cref="T:log4net.Layout.XmlLayout"/>
+ and the appender where it is embedded.
+ </para>
+ <para>
+ The <c>version</c> attribute helps components to correctly
+ interpret output generated by <see cref="T:log4net.Layout.XmlLayout"/>. The value of
+ this attribute should be "1.2" for release 1.2 and later.
+ </para>
+ <para>
+ Alternatively the <c>Header</c> and <c>Footer</c> properties can be
+ configured to output the correct XML header, open tag and close tag.
+ When setting the <c>Header</c> and <c>Footer</c> properties it is essential
+ that the underlying data store not be appendable otherwise the data
+ will become invalid XML.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="T:log4net.Layout.XmlLayoutBase">
+ <summary>
+ Layout that formats the log events as XML elements.
+ </summary>
+ <remarks>
+ <para>
+ This is an abstract class that must be subclassed by an implementation
+ to conform to a specific schema.
+ </para>
+ <para>
+ Deriving classes must implement the <see cref="M:log4net.Layout.XmlLayoutBase.FormatXml(System.Xml.XmlWriter,log4net.Core.LoggingEvent)"/> method.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="M:log4net.Layout.XmlLayoutBase.#ctor">
+ <summary>
+ Protected constructor to support subclasses
+ </summary>
+ <remarks>
+ <para>
+ Initializes a new instance of the <see cref="T:log4net.Layout.XmlLayoutBase"/> class
+ with no location info.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Layout.XmlLayoutBase.#ctor(System.Boolean)">
+ <summary>
+ Protected constructor to support subclasses
+ </summary>
+ <remarks>
+ <para>
+ The <paramref name="locationInfo" /> parameter determines whether
+ location information will be output by the layout. If
+ <paramref name="locationInfo" /> is set to <c>true</c>, then the
+ file name and line number of the statement at the origin of the log
+ statement will be output.
+ </para>
+ <para>
+ If you are embedding this layout within an SMTPAppender
+ then make sure to set the <b>LocationInfo</b> option of that
+ appender as well.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Layout.XmlLayoutBase.ActivateOptions">
+ <summary>
+ Initialize layout options
+ </summary>
+ <remarks>
+ <para>
+ This is part of the <see cref="T:log4net.Core.IOptionHandler"/> delayed object
+ activation scheme. The <see cref="M:log4net.Layout.XmlLayoutBase.ActivateOptions"/> method must
+ be called on this object after the configuration properties have
+ been set. Until <see cref="M:log4net.Layout.XmlLayoutBase.ActivateOptions"/> is called this
+ object is in an undefined state and must not be used.
+ </para>
+ <para>
+ If any of the configuration properties are modified then
+ <see cref="M:log4net.Layout.XmlLayoutBase.ActivateOptions"/> must be called again.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Layout.XmlLayoutBase.Format(System.IO.TextWriter,log4net.Core.LoggingEvent)">
+ <summary>
+ Produces a formatted string.
+ </summary>
+ <param name="loggingEvent">The event being logged.</param>
+ <param name="writer">The TextWriter to write the formatted event to</param>
+ <remarks>
+ <para>
+ Format the <see cref="T:log4net.Core.LoggingEvent"/> and write it to the <see cref="T:System.IO.TextWriter"/>.
+ </para>
+ <para>
+ This method creates an <see cref="T:System.Xml.XmlTextWriter"/> that writes to the
+ <paramref name="writer"/>. The <see cref="T:System.Xml.XmlTextWriter"/> is passed
+ to the <see cref="M:log4net.Layout.XmlLayoutBase.FormatXml(System.Xml.XmlWriter,log4net.Core.LoggingEvent)"/> method. Subclasses should override the
+ <see cref="M:log4net.Layout.XmlLayoutBase.FormatXml(System.Xml.XmlWriter,log4net.Core.LoggingEvent)"/> method rather than this method.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Layout.XmlLayoutBase.FormatXml(System.Xml.XmlWriter,log4net.Core.LoggingEvent)">
+ <summary>
+ Does the actual writing of the XML.
+ </summary>
+ <param name="writer">The writer to use to output the event to.</param>
+ <param name="loggingEvent">The event to write.</param>
+ <remarks>
+ <para>
+ Subclasses should override this method to format
+ the <see cref="T:log4net.Core.LoggingEvent"/> as XML.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Layout.XmlLayoutBase.m_locationInfo">
+ <summary>
+ Flag to indicate if location information should be included in
+ the XML events.
+ </summary>
+ </member>
+ <member name="F:log4net.Layout.XmlLayoutBase.m_protectCloseTextWriter">
+ <summary>
+ Writer adapter that ignores Close
+ </summary>
+ </member>
+ <member name="F:log4net.Layout.XmlLayoutBase.m_invalidCharReplacement">
+ <summary>
+ The string to replace invalid chars with
+ </summary>
+ </member>
+ <member name="P:log4net.Layout.XmlLayoutBase.LocationInfo">
+ <summary>
+ Gets a value indicating whether to include location information in
+ the XML events.
+ </summary>
+ <value>
+ <c>true</c> if location information should be included in the XML
+ events; otherwise, <c>false</c>.
+ </value>
+ <remarks>
+ <para>
+ If <see cref="P:log4net.Layout.XmlLayoutBase.LocationInfo"/> is set to <c>true</c>, then the file
+ name and line number of the statement at the origin of the log
+ statement will be output.
+ </para>
+ <para>
+ If you are embedding this layout within an <c>SMTPAppender</c>
+ then make sure to set the <b>LocationInfo</b> option of that
+ appender as well.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Layout.XmlLayoutBase.InvalidCharReplacement">
+ <summary>
+ The string to replace characters that can not be expressed in XML with.
+ <remarks>
+ <para>
+ Not all characters may be expressed in XML. This property contains the
+ string to replace those that can not with. This defaults to a ?. Set it
+ to the empty string to simply remove offending characters. For more
+ details on the allowed character ranges see http://www.w3.org/TR/REC-xml/#charsets
+ Character replacement will occur in the log message, the property names
+ and the property values.
+ </para>
+ </remarks>
+ </summary>
+ </member>
+ <member name="P:log4net.Layout.XmlLayoutBase.ContentType">
+ <summary>
+ Gets the content type output by this layout.
+ </summary>
+ <value>
+ As this is the XML layout, the value is always <c>"text/xml"</c>.
+ </value>
+ <remarks>
+ <para>
+ As this is the XML layout, the value is always <c>"text/xml"</c>.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Layout.XmlLayout.#ctor">
+ <summary>
+ Constructs an XmlLayout
+ </summary>
+ </member>
+ <member name="M:log4net.Layout.XmlLayout.#ctor(System.Boolean)">
+ <summary>
+ Constructs an XmlLayout.
+ </summary>
+ <remarks>
+ <para>
+ The <b>LocationInfo</b> option takes a boolean value. By
+ default, it is set to false which means there will be no location
+ information output by this layout. If the the option is set to
+ true, then the file name and line number of the statement
+ at the origin of the log statement will be output.
+ </para>
+ <para>
+ If you are embedding this layout within an SmtpAppender
+ then make sure to set the <b>LocationInfo</b> option of that
+ appender as well.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Layout.XmlLayout.ActivateOptions">
+ <summary>
+ Initialize layout options
+ </summary>
+ <remarks>
+ <para>
+ This is part of the <see cref="T:log4net.Core.IOptionHandler"/> delayed object
+ activation scheme. The <see cref="M:log4net.Layout.XmlLayout.ActivateOptions"/> method must
+ be called on this object after the configuration properties have
+ been set. Until <see cref="M:log4net.Layout.XmlLayout.ActivateOptions"/> is called this
+ object is in an undefined state and must not be used.
+ </para>
+ <para>
+ If any of the configuration properties are modified then
+ <see cref="M:log4net.Layout.XmlLayout.ActivateOptions"/> must be called again.
+ </para>
+ <para>
+ Builds a cache of the element names
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Layout.XmlLayout.FormatXml(System.Xml.XmlWriter,log4net.Core.LoggingEvent)">
+ <summary>
+ Does the actual writing of the XML.
+ </summary>
+ <param name="writer">The writer to use to output the event to.</param>
+ <param name="loggingEvent">The event to write.</param>
+ <remarks>
+ <para>
+ Override the base class <see cref="M:log4net.Layout.XmlLayoutBase.FormatXml(System.Xml.XmlWriter,log4net.Core.LoggingEvent)"/> method
+ to write the <see cref="T:log4net.Core.LoggingEvent"/> to the <see cref="T:System.Xml.XmlWriter"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Layout.XmlLayout.m_prefix">
+ <summary>
+ The prefix to use for all generated element names
+ </summary>
+ </member>
+ <member name="P:log4net.Layout.XmlLayout.Prefix">
+ <summary>
+ The prefix to use for all element names
+ </summary>
+ <remarks>
+ <para>
+ The default prefix is <b>log4net</b>. Set this property
+ to change the prefix. If the prefix is set to an empty string
+ then no prefix will be written.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Layout.XmlLayout.Base64EncodeMessage">
+ <summary>
+ Set whether or not to base64 encode the message.
+ </summary>
+ <remarks>
+ <para>
+ By default the log message will be written as text to the xml
+ output. This can cause problems when the message contains binary
+ data. By setting this to true the contents of the message will be
+ base64 encoded. If this is set then invalid character replacement
+ (see <see cref="P:log4net.Layout.XmlLayoutBase.InvalidCharReplacement"/>) will not be performed
+ on the log message.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Layout.XmlLayout.Base64EncodeProperties">
+ <summary>
+ Set whether or not to base64 encode the property values.
+ </summary>
+ <remarks>
+ <para>
+ By default the properties will be written as text to the xml
+ output. This can cause problems when one or more properties contain
+ binary data. By setting this to true the values of the properties
+ will be base64 encoded. If this is set then invalid character replacement
+ (see <see cref="P:log4net.Layout.XmlLayoutBase.InvalidCharReplacement"/>) will not be performed
+ on the property values.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Layout.XmlLayoutSchemaLog4j">
+ <summary>
+ Layout that formats the log events as XML elements compatible with the log4j schema
+ </summary>
+ <remarks>
+ <para>
+ Formats the log events according to the http://logging.apache.org/log4j schema.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="F:log4net.Layout.XmlLayoutSchemaLog4j.s_date1970">
+ <summary>
+ The 1st of January 1970 in UTC
+ </summary>
+ </member>
+ <member name="M:log4net.Layout.XmlLayoutSchemaLog4j.#ctor">
+ <summary>
+ Constructs an XMLLayoutSchemaLog4j
+ </summary>
+ </member>
+ <member name="M:log4net.Layout.XmlLayoutSchemaLog4j.#ctor(System.Boolean)">
+ <summary>
+ Constructs an XMLLayoutSchemaLog4j.
+ </summary>
+ <remarks>
+ <para>
+ The <b>LocationInfo</b> option takes a boolean value. By
+ default, it is set to false which means there will be no location
+ information output by this layout. If the the option is set to
+ true, then the file name and line number of the statement
+ at the origin of the log statement will be output.
+ </para>
+ <para>
+ If you are embedding this layout within an SMTPAppender
+ then make sure to set the <b>LocationInfo</b> option of that
+ appender as well.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Layout.XmlLayoutSchemaLog4j.FormatXml(System.Xml.XmlWriter,log4net.Core.LoggingEvent)">
+ <summary>
+ Actually do the writing of the xml
+ </summary>
+ <param name="writer">the writer to use</param>
+ <param name="loggingEvent">the event to write</param>
+ <remarks>
+ <para>
+ Generate XML that is compatible with the log4j schema.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Layout.XmlLayoutSchemaLog4j.Version">
+ <summary>
+ The version of the log4j schema to use.
+ </summary>
+ <remarks>
+ <para>
+ Only version 1.2 of the log4j schema is supported.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.ObjectRenderer.DefaultRenderer">
+ <summary>
+ The default object Renderer.
+ </summary>
+ <remarks>
+ <para>
+ The default renderer supports rendering objects and collections to strings.
+ </para>
+ <para>
+ See the <see cref="M:log4net.ObjectRenderer.DefaultRenderer.RenderObject(log4net.ObjectRenderer.RendererMap,System.Object,System.IO.TextWriter)"/> method for details of the output.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="T:log4net.ObjectRenderer.IObjectRenderer">
+ <summary>
+ Implement this interface in order to render objects as strings
+ </summary>
+ <remarks>
+ <para>
+ Certain types require special case conversion to
+ string form. This conversion is done by an object renderer.
+ Object renderers implement the <see cref="T:log4net.ObjectRenderer.IObjectRenderer"/>
+ interface.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="M:log4net.ObjectRenderer.IObjectRenderer.RenderObject(log4net.ObjectRenderer.RendererMap,System.Object,System.IO.TextWriter)">
+ <summary>
+ Render the object <paramref name="obj"/> to a string
+ </summary>
+ <param name="rendererMap">The map used to lookup renderers</param>
+ <param name="obj">The object to render</param>
+ <param name="writer">The writer to render to</param>
+ <remarks>
+ <para>
+ Render the object <paramref name="obj"/> to a
+ string.
+ </para>
+ <para>
+ The <paramref name="rendererMap"/> parameter is
+ provided to lookup and render other objects. This is
+ very useful where <paramref name="obj"/> contains
+ nested objects of unknown type. The <see cref="M:log4net.ObjectRenderer.RendererMap.FindAndRender(System.Object,System.IO.TextWriter)"/>
+ method can be used to render these objects.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.ObjectRenderer.DefaultRenderer.#ctor">
+ <summary>
+ Default constructor
+ </summary>
+ <remarks>
+ <para>
+ Default constructor
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.ObjectRenderer.DefaultRenderer.RenderObject(log4net.ObjectRenderer.RendererMap,System.Object,System.IO.TextWriter)">
+ <summary>
+ Render the object <paramref name="obj"/> to a string
+ </summary>
+ <param name="rendererMap">The map used to lookup renderers</param>
+ <param name="obj">The object to render</param>
+ <param name="writer">The writer to render to</param>
+ <remarks>
+ <para>
+ Render the object <paramref name="obj"/> to a string.
+ </para>
+ <para>
+ The <paramref name="rendererMap"/> parameter is
+ provided to lookup and render other objects. This is
+ very useful where <paramref name="obj"/> contains
+ nested objects of unknown type. The <see cref="M:log4net.ObjectRenderer.RendererMap.FindAndRender(System.Object)"/>
+ method can be used to render these objects.
+ </para>
+ <para>
+ The default renderer supports rendering objects to strings as follows:
+ </para>
+ <list type="table">
+ <listheader>
+ <term>Value</term>
+ <description>Rendered String</description>
+ </listheader>
+ <item>
+ <term><c>null</c></term>
+ <description>
+ <para>"(null)"</para>
+ </description>
+ </item>
+ <item>
+ <term><see cref="T:System.Array"/></term>
+ <description>
+ <para>
+ For a one dimensional array this is the
+ array type name, an open brace, followed by a comma
+ separated list of the elements (using the appropriate
+ renderer), followed by a close brace.
+ </para>
+ <para>
+ For example: <c>int[] {1, 2, 3}</c>.
+ </para>
+ <para>
+ If the array is not one dimensional the
+ <c>Array.ToString()</c> is returned.
+ </para>
+ </description>
+ </item>
+ <item>
+ <term><see cref="T:System.Collections.IEnumerable"/>, <see cref="T:System.Collections.ICollection"/> &amp; <see cref="T:System.Collections.IEnumerator"/></term>
+ <description>
+ <para>
+ Rendered as an open brace, followed by a comma
+ separated list of the elements (using the appropriate
+ renderer), followed by a close brace.
+ </para>
+ <para>
+ For example: <c>{a, b, c}</c>.
+ </para>
+ <para>
+ All collection classes that implement <see cref="T:System.Collections.ICollection"/> its subclasses,
+ or generic equivalents all implement the <see cref="T:System.Collections.IEnumerable"/> interface.
+ </para>
+ </description>
+ </item>
+ <item>
+ <term><see cref="T:System.Collections.DictionaryEntry"/></term>
+ <description>
+ <para>
+ Rendered as the key, an equals sign ('='), and the value (using the appropriate
+ renderer).
+ </para>
+ <para>
+ For example: <c>key=value</c>.
+ </para>
+ </description>
+ </item>
+ <item>
+ <term>other</term>
+ <description>
+ <para><c>Object.ToString()</c></para>
+ </description>
+ </item>
+ </list>
+ </remarks>
+ </member>
+ <member name="M:log4net.ObjectRenderer.DefaultRenderer.RenderArray(log4net.ObjectRenderer.RendererMap,System.Array,System.IO.TextWriter)">
+ <summary>
+ Render the array argument into a string
+ </summary>
+ <param name="rendererMap">The map used to lookup renderers</param>
+ <param name="array">the array to render</param>
+ <param name="writer">The writer to render to</param>
+ <remarks>
+ <para>
+ For a one dimensional array this is the
+ array type name, an open brace, followed by a comma
+ separated list of the elements (using the appropriate
+ renderer), followed by a close brace. For example:
+ <c>int[] {1, 2, 3}</c>.
+ </para>
+ <para>
+ If the array is not one dimensional the
+ <c>Array.ToString()</c> is returned.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.ObjectRenderer.DefaultRenderer.RenderEnumerator(log4net.ObjectRenderer.RendererMap,System.Collections.IEnumerator,System.IO.TextWriter)">
+ <summary>
+ Render the enumerator argument into a string
+ </summary>
+ <param name="rendererMap">The map used to lookup renderers</param>
+ <param name="enumerator">the enumerator to render</param>
+ <param name="writer">The writer to render to</param>
+ <remarks>
+ <para>
+ Rendered as an open brace, followed by a comma
+ separated list of the elements (using the appropriate
+ renderer), followed by a close brace. For example:
+ <c>{a, b, c}</c>.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.ObjectRenderer.DefaultRenderer.RenderDictionaryEntry(log4net.ObjectRenderer.RendererMap,System.Collections.DictionaryEntry,System.IO.TextWriter)">
+ <summary>
+ Render the DictionaryEntry argument into a string
+ </summary>
+ <param name="rendererMap">The map used to lookup renderers</param>
+ <param name="entry">the DictionaryEntry to render</param>
+ <param name="writer">The writer to render to</param>
+ <remarks>
+ <para>
+ Render the key, an equals sign ('='), and the value (using the appropriate
+ renderer). For example: <c>key=value</c>.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.ObjectRenderer.RendererMap">
+ <summary>
+ Map class objects to an <see cref="T:log4net.ObjectRenderer.IObjectRenderer"/>.
+ </summary>
+ <remarks>
+ <para>
+ Maintains a mapping between types that require special
+ rendering and the <see cref="T:log4net.ObjectRenderer.IObjectRenderer"/> that
+ is used to render them.
+ </para>
+ <para>
+ The <see cref="M:log4net.ObjectRenderer.RendererMap.FindAndRender(System.Object)"/> method is used to render an
+ <c>object</c> using the appropriate renderers defined in this map.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="M:log4net.ObjectRenderer.RendererMap.#ctor">
+ <summary>
+ Default Constructor
+ </summary>
+ <remarks>
+ <para>
+ Default constructor.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.ObjectRenderer.RendererMap.FindAndRender(System.Object)">
+ <summary>
+ Render <paramref name="obj"/> using the appropriate renderer.
+ </summary>
+ <param name="obj">the object to render to a string</param>
+ <returns>the object rendered as a string</returns>
+ <remarks>
+ <para>
+ This is a convenience method used to render an object to a string.
+ The alternative method <see cref="M:log4net.ObjectRenderer.RendererMap.FindAndRender(System.Object,System.IO.TextWriter)"/>
+ should be used when streaming output to a <see cref="T:System.IO.TextWriter"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.ObjectRenderer.RendererMap.FindAndRender(System.Object,System.IO.TextWriter)">
+ <summary>
+ Render <paramref name="obj"/> using the appropriate renderer.
+ </summary>
+ <param name="obj">the object to render to a string</param>
+ <param name="writer">The writer to render to</param>
+ <remarks>
+ <para>
+ Find the appropriate renderer for the type of the
+ <paramref name="obj"/> parameter. This is accomplished by calling the
+ <see cref="M:log4net.ObjectRenderer.RendererMap.Get(System.Type)"/> method. Once a renderer is found, it is
+ applied on the object <paramref name="obj"/> and the result is returned
+ as a <see cref="T:System.String"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.ObjectRenderer.RendererMap.Get(System.Object)">
+ <summary>
+ Gets the renderer for the specified object type
+ </summary>
+ <param name="obj">the object to lookup the renderer for</param>
+ <returns>the renderer for <paramref name="obj"/></returns>
+ <remarks>
+ <param>
+ Gets the renderer for the specified object type.
+ </param>
+ <param>
+ Syntactic sugar method that calls <see cref="M:log4net.ObjectRenderer.RendererMap.Get(System.Type)"/>
+ with the type of the object parameter.
+ </param>
+ </remarks>
+ </member>
+ <member name="M:log4net.ObjectRenderer.RendererMap.Get(System.Type)">
+ <summary>
+ Gets the renderer for the specified type
+ </summary>
+ <param name="type">the type to lookup the renderer for</param>
+ <returns>the renderer for the specified type</returns>
+ <remarks>
+ <para>
+ Returns the renderer for the specified type.
+ If no specific renderer has been defined the
+ <see cref="P:log4net.ObjectRenderer.RendererMap.DefaultRenderer"/> will be returned.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.ObjectRenderer.RendererMap.SearchTypeAndInterfaces(System.Type)">
+ <summary>
+ Internal function to recursively search interfaces
+ </summary>
+ <param name="type">the type to lookup the renderer for</param>
+ <returns>the renderer for the specified type</returns>
+ </member>
+ <member name="M:log4net.ObjectRenderer.RendererMap.Clear">
+ <summary>
+ Clear the map of renderers
+ </summary>
+ <remarks>
+ <para>
+ Clear the custom renderers defined by using
+ <see cref="M:log4net.ObjectRenderer.RendererMap.Put(System.Type,log4net.ObjectRenderer.IObjectRenderer)"/>. The <see cref="P:log4net.ObjectRenderer.RendererMap.DefaultRenderer"/>
+ cannot be removed.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.ObjectRenderer.RendererMap.Put(System.Type,log4net.ObjectRenderer.IObjectRenderer)">
+ <summary>
+ Register an <see cref="T:log4net.ObjectRenderer.IObjectRenderer"/> for <paramref name="typeToRender"/>.
+ </summary>
+ <param name="typeToRender">the type that will be rendered by <paramref name="renderer"/></param>
+ <param name="renderer">the renderer for <paramref name="typeToRender"/></param>
+ <remarks>
+ <para>
+ Register an object renderer for a specific source type.
+ This renderer will be returned from a call to <see cref="M:log4net.ObjectRenderer.RendererMap.Get(System.Type)"/>
+ specifying the same <paramref name="typeToRender"/> as an argument.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.ObjectRenderer.RendererMap.DefaultRenderer">
+ <summary>
+ Get the default renderer instance
+ </summary>
+ <value>the default renderer</value>
+ <remarks>
+ <para>
+ Get the default renderer
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Plugin.IPlugin">
+ <summary>
+ Interface implemented by logger repository plugins.
+ </summary>
+ <remarks>
+ <para>
+ Plugins define additional behavior that can be associated
+ with a <see cref="T:log4net.Repository.ILoggerRepository"/>.
+ The <see cref="T:log4net.Plugin.PluginMap"/> held by the <see cref="P:log4net.Repository.ILoggerRepository.PluginMap"/>
+ property is used to store the plugins for a repository.
+ </para>
+ <para>
+ The <c>log4net.Config.PluginAttribute</c> can be used to
+ attach plugins to repositories created using configuration
+ attributes.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="M:log4net.Plugin.IPlugin.Attach(log4net.Repository.ILoggerRepository)">
+ <summary>
+ Attaches the plugin to the specified <see cref="T:log4net.Repository.ILoggerRepository"/>.
+ </summary>
+ <param name="repository">The <see cref="T:log4net.Repository.ILoggerRepository"/> that this plugin should be attached to.</param>
+ <remarks>
+ <para>
+ A plugin may only be attached to a single repository.
+ </para>
+ <para>
+ This method is called when the plugin is attached to the repository.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Plugin.IPlugin.Shutdown">
+ <summary>
+ Is called when the plugin is to shutdown.
+ </summary>
+ <remarks>
+ <para>
+ This method is called to notify the plugin that
+ it should stop operating and should detach from
+ the repository.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Plugin.IPlugin.Name">
+ <summary>
+ Gets the name of the plugin.
+ </summary>
+ <value>
+ The name of the plugin.
+ </value>
+ <remarks>
+ <para>
+ Plugins are stored in the <see cref="T:log4net.Plugin.PluginMap"/>
+ keyed by name. Each plugin instance attached to a
+ repository must be a unique name.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Plugin.PluginCollection">
+ <summary>
+ A strongly-typed collection of <see cref="T:log4net.Plugin.IPlugin"/> objects.
+ </summary>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="M:log4net.Plugin.PluginCollection.ReadOnly(log4net.Plugin.PluginCollection)">
+ <summary>
+ Creates a read-only wrapper for a <c>PluginCollection</c> instance.
+ </summary>
+ <param name="list">list to create a readonly wrapper arround</param>
+ <returns>
+ A <c>PluginCollection</c> wrapper that is read-only.
+ </returns>
+ </member>
+ <member name="M:log4net.Plugin.PluginCollection.#ctor">
+ <summary>
+ Initializes a new instance of the <c>PluginCollection</c> class
+ that is empty and has the default initial capacity.
+ </summary>
+ </member>
+ <member name="M:log4net.Plugin.PluginCollection.#ctor(System.Int32)">
+ <summary>
+ Initializes a new instance of the <c>PluginCollection</c> class
+ that has the specified initial capacity.
+ </summary>
+ <param name="capacity">
+ The number of elements that the new <c>PluginCollection</c> is initially capable of storing.
+ </param>
+ </member>
+ <member name="M:log4net.Plugin.PluginCollection.#ctor(log4net.Plugin.PluginCollection)">
+ <summary>
+ Initializes a new instance of the <c>PluginCollection</c> class
+ that contains elements copied from the specified <c>PluginCollection</c>.
+ </summary>
+ <param name="c">The <c>PluginCollection</c> whose elements are copied to the new collection.</param>
+ </member>
+ <member name="M:log4net.Plugin.PluginCollection.#ctor(log4net.Plugin.IPlugin[])">
+ <summary>
+ Initializes a new instance of the <c>PluginCollection</c> class
+ that contains elements copied from the specified <see cref="T:log4net.Plugin.IPlugin"/> array.
+ </summary>
+ <param name="a">The <see cref="T:log4net.Plugin.IPlugin"/> array whose elements are copied to the new list.</param>
+ </member>
+ <member name="M:log4net.Plugin.PluginCollection.#ctor(System.Collections.ICollection)">
+ <summary>
+ Initializes a new instance of the <c>PluginCollection</c> class
+ that contains elements copied from the specified <see cref="T:log4net.Plugin.IPlugin"/> collection.
+ </summary>
+ <param name="col">The <see cref="T:log4net.Plugin.IPlugin"/> collection whose elements are copied to the new list.</param>
+ </member>
+ <member name="M:log4net.Plugin.PluginCollection.#ctor(log4net.Plugin.PluginCollection.Tag)">
+ <summary>
+ Allow subclasses to avoid our default constructors
+ </summary>
+ <param name="tag"></param>
+ <exclude/>
+ </member>
+ <member name="M:log4net.Plugin.PluginCollection.CopyTo(log4net.Plugin.IPlugin[])">
+ <summary>
+ Copies the entire <c>PluginCollection</c> to a one-dimensional
+ <see cref="T:log4net.Plugin.IPlugin"/> array.
+ </summary>
+ <param name="array">The one-dimensional <see cref="T:log4net.Plugin.IPlugin"/> array to copy to.</param>
+ </member>
+ <member name="M:log4net.Plugin.PluginCollection.CopyTo(log4net.Plugin.IPlugin[],System.Int32)">
+ <summary>
+ Copies the entire <c>PluginCollection</c> to a one-dimensional
+ <see cref="T:log4net.Plugin.IPlugin"/> array, starting at the specified index of the target array.
+ </summary>
+ <param name="array">The one-dimensional <see cref="T:log4net.Plugin.IPlugin"/> array to copy to.</param>
+ <param name="start">The zero-based index in <paramref name="array"/> at which copying begins.</param>
+ </member>
+ <member name="M:log4net.Plugin.PluginCollection.Add(log4net.Plugin.IPlugin)">
+ <summary>
+ Adds a <see cref="T:log4net.Plugin.IPlugin"/> to the end of the <c>PluginCollection</c>.
+ </summary>
+ <param name="item">The <see cref="T:log4net.Plugin.IPlugin"/> to be added to the end of the <c>PluginCollection</c>.</param>
+ <returns>The index at which the value has been added.</returns>
+ </member>
+ <member name="M:log4net.Plugin.PluginCollection.Clear">
+ <summary>
+ Removes all elements from the <c>PluginCollection</c>.
+ </summary>
+ </member>
+ <member name="M:log4net.Plugin.PluginCollection.Clone">
+ <summary>
+ Creates a shallow copy of the <see cref="T:log4net.Plugin.PluginCollection"/>.
+ </summary>
+ <returns>A new <see cref="T:log4net.Plugin.PluginCollection"/> with a shallow copy of the collection data.</returns>
+ </member>
+ <member name="M:log4net.Plugin.PluginCollection.Contains(log4net.Plugin.IPlugin)">
+ <summary>
+ Determines whether a given <see cref="T:log4net.Plugin.IPlugin"/> is in the <c>PluginCollection</c>.
+ </summary>
+ <param name="item">The <see cref="T:log4net.Plugin.IPlugin"/> to check for.</param>
+ <returns><c>true</c> if <paramref name="item"/> is found in the <c>PluginCollection</c>; otherwise, <c>false</c>.</returns>
+ </member>
+ <member name="M:log4net.Plugin.PluginCollection.IndexOf(log4net.Plugin.IPlugin)">
+ <summary>
+ Returns the zero-based index of the first occurrence of a <see cref="T:log4net.Plugin.IPlugin"/>
+ in the <c>PluginCollection</c>.
+ </summary>
+ <param name="item">The <see cref="T:log4net.Plugin.IPlugin"/> to locate in the <c>PluginCollection</c>.</param>
+ <returns>
+ The zero-based index of the first occurrence of <paramref name="item"/>
+ in the entire <c>PluginCollection</c>, if found; otherwise, -1.
+ </returns>
+ </member>
+ <member name="M:log4net.Plugin.PluginCollection.Insert(System.Int32,log4net.Plugin.IPlugin)">
+ <summary>
+ Inserts an element into the <c>PluginCollection</c> at the specified index.
+ </summary>
+ <param name="index">The zero-based index at which <paramref name="item"/> should be inserted.</param>
+ <param name="item">The <see cref="T:log4net.Plugin.IPlugin"/> to insert.</param>
+ <exception cref="T:System.ArgumentOutOfRangeException">
+ <para><paramref name="index"/> is less than zero</para>
+ <para>-or-</para>
+ <para><paramref name="index"/> is equal to or greater than <see cref="P:log4net.Plugin.PluginCollection.Count"/>.</para>
+ </exception>
+ </member>
+ <member name="M:log4net.Plugin.PluginCollection.Remove(log4net.Plugin.IPlugin)">
+ <summary>
+ Removes the first occurrence of a specific <see cref="T:log4net.Plugin.IPlugin"/> from the <c>PluginCollection</c>.
+ </summary>
+ <param name="item">The <see cref="T:log4net.Plugin.IPlugin"/> to remove from the <c>PluginCollection</c>.</param>
+ <exception cref="T:System.ArgumentException">
+ The specified <see cref="T:log4net.Plugin.IPlugin"/> was not found in the <c>PluginCollection</c>.
+ </exception>
+ </member>
+ <member name="M:log4net.Plugin.PluginCollection.RemoveAt(System.Int32)">
+ <summary>
+ Removes the element at the specified index of the <c>PluginCollection</c>.
+ </summary>
+ <param name="index">The zero-based index of the element to remove.</param>
+ <exception cref="T:System.ArgumentOutOfRangeException">
+ <para><paramref name="index"/> is less than zero.</para>
+ <para>-or-</para>
+ <para><paramref name="index"/> is equal to or greater than <see cref="P:log4net.Plugin.PluginCollection.Count"/>.</para>
+ </exception>
+ </member>
+ <member name="M:log4net.Plugin.PluginCollection.GetEnumerator">
+ <summary>
+ Returns an enumerator that can iterate through the <c>PluginCollection</c>.
+ </summary>
+ <returns>An <see cref="T:log4net.Plugin.PluginCollection.Enumerator"/> for the entire <c>PluginCollection</c>.</returns>
+ </member>
+ <member name="M:log4net.Plugin.PluginCollection.AddRange(log4net.Plugin.PluginCollection)">
+ <summary>
+ Adds the elements of another <c>PluginCollection</c> to the current <c>PluginCollection</c>.
+ </summary>
+ <param name="x">The <c>PluginCollection</c> whose elements should be added to the end of the current <c>PluginCollection</c>.</param>
+ <returns>The new <see cref="P:log4net.Plugin.PluginCollection.Count"/> of the <c>PluginCollection</c>.</returns>
+ </member>
+ <member name="M:log4net.Plugin.PluginCollection.AddRange(log4net.Plugin.IPlugin[])">
+ <summary>
+ Adds the elements of a <see cref="T:log4net.Plugin.IPlugin"/> array to the current <c>PluginCollection</c>.
+ </summary>
+ <param name="x">The <see cref="T:log4net.Plugin.IPlugin"/> array whose elements should be added to the end of the <c>PluginCollection</c>.</param>
+ <returns>The new <see cref="P:log4net.Plugin.PluginCollection.Count"/> of the <c>PluginCollection</c>.</returns>
+ </member>
+ <member name="M:log4net.Plugin.PluginCollection.AddRange(System.Collections.ICollection)">
+ <summary>
+ Adds the elements of a <see cref="T:log4net.Plugin.IPlugin"/> collection to the current <c>PluginCollection</c>.
+ </summary>
+ <param name="col">The <see cref="T:log4net.Plugin.IPlugin"/> collection whose elements should be added to the end of the <c>PluginCollection</c>.</param>
+ <returns>The new <see cref="P:log4net.Plugin.PluginCollection.Count"/> of the <c>PluginCollection</c>.</returns>
+ </member>
+ <member name="M:log4net.Plugin.PluginCollection.TrimToSize">
+ <summary>
+ Sets the capacity to the actual number of elements.
+ </summary>
+ </member>
+ <member name="M:log4net.Plugin.PluginCollection.ValidateIndex(System.Int32)">
+ <exception cref="T:System.ArgumentOutOfRangeException">
+ <para><paramref name="index"/> is less than zero.</para>
+ <para>-or-</para>
+ <para><paramref name="index"/> is equal to or greater than <see cref="P:log4net.Plugin.PluginCollection.Count"/>.</para>
+ </exception>
+ </member>
+ <member name="M:log4net.Plugin.PluginCollection.ValidateIndex(System.Int32,System.Boolean)">
+ <exception cref="T:System.ArgumentOutOfRangeException">
+ <para><paramref name="index"/> is less than zero.</para>
+ <para>-or-</para>
+ <para><paramref name="index"/> is equal to or greater than <see cref="P:log4net.Plugin.PluginCollection.Count"/>.</para>
+ </exception>
+ </member>
+ <member name="P:log4net.Plugin.PluginCollection.Count">
+ <summary>
+ Gets the number of elements actually contained in the <c>PluginCollection</c>.
+ </summary>
+ </member>
+ <member name="P:log4net.Plugin.PluginCollection.IsSynchronized">
+ <summary>
+ Gets a value indicating whether access to the collection is synchronized (thread-safe).
+ </summary>
+ <returns>true if access to the ICollection is synchronized (thread-safe); otherwise, false.</returns>
+ </member>
+ <member name="P:log4net.Plugin.PluginCollection.SyncRoot">
+ <summary>
+ Gets an object that can be used to synchronize access to the collection.
+ </summary>
+ <value>
+ An object that can be used to synchronize access to the collection.
+ </value>
+ </member>
+ <member name="P:log4net.Plugin.PluginCollection.Item(System.Int32)">
+ <summary>
+ Gets or sets the <see cref="T:log4net.Plugin.IPlugin"/> at the specified index.
+ </summary>
+ <value>
+ The <see cref="T:log4net.Plugin.IPlugin"/> at the specified index.
+ </value>
+ <param name="index">The zero-based index of the element to get or set.</param>
+ <exception cref="T:System.ArgumentOutOfRangeException">
+ <para><paramref name="index"/> is less than zero.</para>
+ <para>-or-</para>
+ <para><paramref name="index"/> is equal to or greater than <see cref="P:log4net.Plugin.PluginCollection.Count"/>.</para>
+ </exception>
+ </member>
+ <member name="P:log4net.Plugin.PluginCollection.IsFixedSize">
+ <summary>
+ Gets a value indicating whether the collection has a fixed size.
+ </summary>
+ <value><c>true</c> if the collection has a fixed size; otherwise, <c>false</c>. The default is <c>false</c>.</value>
+ </member>
+ <member name="P:log4net.Plugin.PluginCollection.IsReadOnly">
+ <summary>
+ Gets a value indicating whether the IList is read-only.
+ </summary>
+ <value><c>true</c> if the collection is read-only; otherwise, <c>false</c>. The default is <c>false</c>.</value>
+ </member>
+ <member name="P:log4net.Plugin.PluginCollection.Capacity">
+ <summary>
+ Gets or sets the number of elements the <c>PluginCollection</c> can contain.
+ </summary>
+ <value>
+ The number of elements the <c>PluginCollection</c> can contain.
+ </value>
+ </member>
+ <member name="T:log4net.Plugin.PluginCollection.IPluginCollectionEnumerator">
+ <summary>
+ Supports type-safe iteration over a <see cref="T:log4net.Plugin.PluginCollection"/>.
+ </summary>
+ <exclude/>
+ </member>
+ <member name="M:log4net.Plugin.PluginCollection.IPluginCollectionEnumerator.MoveNext">
+ <summary>
+ Advances the enumerator to the next element in the collection.
+ </summary>
+ <returns>
+ <c>true</c> if the enumerator was successfully advanced to the next element;
+ <c>false</c> if the enumerator has passed the end of the collection.
+ </returns>
+ <exception cref="T:System.InvalidOperationException">
+ The collection was modified after the enumerator was created.
+ </exception>
+ </member>
+ <member name="M:log4net.Plugin.PluginCollection.IPluginCollectionEnumerator.Reset">
+ <summary>
+ Sets the enumerator to its initial position, before the first element in the collection.
+ </summary>
+ </member>
+ <member name="P:log4net.Plugin.PluginCollection.IPluginCollectionEnumerator.Current">
+ <summary>
+ Gets the current element in the collection.
+ </summary>
+ </member>
+ <member name="T:log4net.Plugin.PluginCollection.Tag">
+ <summary>
+ Type visible only to our subclasses
+ Used to access protected constructor
+ </summary>
+ <exclude/>
+ </member>
+ <member name="F:log4net.Plugin.PluginCollection.Tag.Default">
+ <summary>
+ A value
+ </summary>
+ </member>
+ <member name="T:log4net.Plugin.PluginCollection.Enumerator">
+ <summary>
+ Supports simple iteration over a <see cref="T:log4net.Plugin.PluginCollection"/>.
+ </summary>
+ <exclude/>
+ </member>
+ <member name="M:log4net.Plugin.PluginCollection.Enumerator.#ctor(log4net.Plugin.PluginCollection)">
+ <summary>
+ Initializes a new instance of the <c>Enumerator</c> class.
+ </summary>
+ <param name="tc"></param>
+ </member>
+ <member name="M:log4net.Plugin.PluginCollection.Enumerator.MoveNext">
+ <summary>
+ Advances the enumerator to the next element in the collection.
+ </summary>
+ <returns>
+ <c>true</c> if the enumerator was successfully advanced to the next element;
+ <c>false</c> if the enumerator has passed the end of the collection.
+ </returns>
+ <exception cref="T:System.InvalidOperationException">
+ The collection was modified after the enumerator was created.
+ </exception>
+ </member>
+ <member name="M:log4net.Plugin.PluginCollection.Enumerator.Reset">
+ <summary>
+ Sets the enumerator to its initial position, before the first element in the collection.
+ </summary>
+ </member>
+ <member name="P:log4net.Plugin.PluginCollection.Enumerator.Current">
+ <summary>
+ Gets the current element in the collection.
+ </summary>
+ <value>
+ The current element in the collection.
+ </value>
+ </member>
+ <member name="T:log4net.Plugin.PluginCollection.ReadOnlyPluginCollection">
+ <exclude/>
+ </member>
+ <member name="T:log4net.Plugin.PluginMap">
+ <summary>
+ Map of repository plugins.
+ </summary>
+ <remarks>
+ <para>
+ This class is a name keyed map of the plugins that are
+ attached to a repository.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="M:log4net.Plugin.PluginMap.#ctor(log4net.Repository.ILoggerRepository)">
+ <summary>
+ Constructor
+ </summary>
+ <param name="repository">The repository that the plugins should be attached to.</param>
+ <remarks>
+ <para>
+ Initialize a new instance of the <see cref="T:log4net.Plugin.PluginMap"/> class with a
+ repository that the plugins should be attached to.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Plugin.PluginMap.Add(log4net.Plugin.IPlugin)">
+ <summary>
+ Adds a <see cref="T:log4net.Plugin.IPlugin"/> to the map.
+ </summary>
+ <param name="plugin">The <see cref="T:log4net.Plugin.IPlugin"/> to add to the map.</param>
+ <remarks>
+ <para>
+ The <see cref="T:log4net.Plugin.IPlugin"/> will be attached to the repository when added.
+ </para>
+ <para>
+ If there already exists a plugin with the same name
+ attached to the repository then the old plugin will
+ be <see cref="M:log4net.Plugin.IPlugin.Shutdown"/> and replaced with
+ the new plugin.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Plugin.PluginMap.Remove(log4net.Plugin.IPlugin)">
+ <summary>
+ Removes a <see cref="T:log4net.Plugin.IPlugin"/> from the map.
+ </summary>
+ <param name="plugin">The <see cref="T:log4net.Plugin.IPlugin"/> to remove from the map.</param>
+ <remarks>
+ <para>
+ Remove a specific plugin from this map.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Plugin.PluginMap.Item(System.String)">
+ <summary>
+ Gets a <see cref="T:log4net.Plugin.IPlugin"/> by name.
+ </summary>
+ <param name="name">The name of the <see cref="T:log4net.Plugin.IPlugin"/> to lookup.</param>
+ <returns>
+ The <see cref="T:log4net.Plugin.IPlugin"/> from the map with the name specified, or
+ <c>null</c> if no plugin is found.
+ </returns>
+ <remarks>
+ <para>
+ Lookup a plugin by name. If the plugin is not found <c>null</c>
+ will be returned.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Plugin.PluginMap.AllPlugins">
+ <summary>
+ Gets all possible plugins as a list of <see cref="T:log4net.Plugin.IPlugin"/> objects.
+ </summary>
+ <value>All possible plugins as a list of <see cref="T:log4net.Plugin.IPlugin"/> objects.</value>
+ <remarks>
+ <para>
+ Get a collection of all the plugins defined in this map.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Plugin.PluginSkeleton">
+ <summary>
+ Base implementation of <see cref="T:log4net.Plugin.IPlugin"/>
+ </summary>
+ <remarks>
+ <para>
+ Default abstract implementation of the <see cref="T:log4net.Plugin.IPlugin"/>
+ interface. This base class can be used by implementors
+ of the <see cref="T:log4net.Plugin.IPlugin"/> interface.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="M:log4net.Plugin.PluginSkeleton.#ctor(System.String)">
+ <summary>
+ Constructor
+ </summary>
+ <param name="name">the name of the plugin</param>
+ <remarks>
+ Initializes a new Plugin with the specified name.
+ </remarks>
+ </member>
+ <member name="M:log4net.Plugin.PluginSkeleton.Attach(log4net.Repository.ILoggerRepository)">
+ <summary>
+ Attaches this plugin to a <see cref="T:log4net.Repository.ILoggerRepository"/>.
+ </summary>
+ <param name="repository">The <see cref="T:log4net.Repository.ILoggerRepository"/> that this plugin should be attached to.</param>
+ <remarks>
+ <para>
+ A plugin may only be attached to a single repository.
+ </para>
+ <para>
+ This method is called when the plugin is attached to the repository.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Plugin.PluginSkeleton.Shutdown">
+ <summary>
+ Is called when the plugin is to shutdown.
+ </summary>
+ <remarks>
+ <para>
+ This method is called to notify the plugin that
+ it should stop operating and should detach from
+ the repository.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Plugin.PluginSkeleton.m_name">
+ <summary>
+ The name of this plugin.
+ </summary>
+ </member>
+ <member name="F:log4net.Plugin.PluginSkeleton.m_repository">
+ <summary>
+ The repository this plugin is attached to.
+ </summary>
+ </member>
+ <member name="P:log4net.Plugin.PluginSkeleton.Name">
+ <summary>
+ Gets or sets the name of the plugin.
+ </summary>
+ <value>
+ The name of the plugin.
+ </value>
+ <remarks>
+ <para>
+ Plugins are stored in the <see cref="T:log4net.Plugin.PluginMap"/>
+ keyed by name. Each plugin instance attached to a
+ repository must be a unique name.
+ </para>
+ <para>
+ The name of the plugin must not change one the
+ plugin has been attached to a repository.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Plugin.PluginSkeleton.LoggerRepository">
+ <summary>
+ The repository for this plugin
+ </summary>
+ <value>
+ The <see cref="T:log4net.Repository.ILoggerRepository"/> that this plugin is attached to.
+ </value>
+ <remarks>
+ <para>
+ Gets or sets the <see cref="T:log4net.Repository.ILoggerRepository"/> that this plugin is
+ attached to.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Plugin.RemoteLoggingServerPlugin">
+ <summary>
+ Plugin that listens for events from the <see cref="T:log4net.Appender.RemotingAppender"/>
+ </summary>
+ <remarks>
+ <para>
+ This plugin publishes an instance of <see cref="T:log4net.Appender.RemotingAppender.IRemoteLoggingSink"/>
+ on a specified <see cref="P:log4net.Plugin.RemoteLoggingServerPlugin.SinkUri"/>. This listens for logging events delivered from
+ a remote <see cref="T:log4net.Appender.RemotingAppender"/>.
+ </para>
+ <para>
+ When an event is received it is relogged within the attached repository
+ as if it had been raised locally.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="M:log4net.Plugin.RemoteLoggingServerPlugin.#ctor">
+ <summary>
+ Default constructor
+ </summary>
+ <remarks>
+ <para>
+ Initializes a new instance of the <see cref="T:log4net.Plugin.RemoteLoggingServerPlugin"/> class.
+ </para>
+ <para>
+ The <see cref="P:log4net.Plugin.RemoteLoggingServerPlugin.SinkUri"/> property must be set.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Plugin.RemoteLoggingServerPlugin.#ctor(System.String)">
+ <summary>
+ Construct with sink Uri.
+ </summary>
+ <param name="sinkUri">The name to publish the sink under in the remoting infrastructure.
+ See <see cref="P:log4net.Plugin.RemoteLoggingServerPlugin.SinkUri"/> for more details.</param>
+ <remarks>
+ <para>
+ Initializes a new instance of the <see cref="T:log4net.Plugin.RemoteLoggingServerPlugin"/> class
+ with specified name.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Plugin.RemoteLoggingServerPlugin.Attach(log4net.Repository.ILoggerRepository)">
+ <summary>
+ Attaches this plugin to a <see cref="T:log4net.Repository.ILoggerRepository"/>.
+ </summary>
+ <param name="repository">The <see cref="T:log4net.Repository.ILoggerRepository"/> that this plugin should be attached to.</param>
+ <remarks>
+ <para>
+ A plugin may only be attached to a single repository.
+ </para>
+ <para>
+ This method is called when the plugin is attached to the repository.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Plugin.RemoteLoggingServerPlugin.Shutdown">
+ <summary>
+ Is called when the plugin is to shutdown.
+ </summary>
+ <remarks>
+ <para>
+ When the plugin is shutdown the remote logging
+ sink is disconnected.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Plugin.RemoteLoggingServerPlugin.SinkUri">
+ <summary>
+ Gets or sets the URI of this sink.
+ </summary>
+ <value>
+ The URI of this sink.
+ </value>
+ <remarks>
+ <para>
+ This is the name under which the object is marshaled.
+ <see cref="M:System.Runtime.Remoting.RemotingServices.Marshal(System.MarshalByRefObject,System.String,System.Type)"/>
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Plugin.RemoteLoggingServerPlugin.RemoteLoggingSinkImpl">
+ <summary>
+ Delivers <see cref="T:log4net.Core.LoggingEvent"/> objects to a remote sink.
+ </summary>
+ <remarks>
+ <para>
+ Internal class used to listen for logging events
+ and deliver them to the local repository.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Plugin.RemoteLoggingServerPlugin.RemoteLoggingSinkImpl.#ctor(log4net.Repository.ILoggerRepository)">
+ <summary>
+ Constructor
+ </summary>
+ <param name="repository">The repository to log to.</param>
+ <remarks>
+ <para>
+ Initializes a new instance of the <see cref="T:log4net.Plugin.RemoteLoggingServerPlugin.RemoteLoggingSinkImpl"/> for the
+ specified <see cref="T:log4net.Repository.ILoggerRepository"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Plugin.RemoteLoggingServerPlugin.RemoteLoggingSinkImpl.LogEvents(log4net.Core.LoggingEvent[])">
+ <summary>
+ Logs the events to the repository.
+ </summary>
+ <param name="events">The events to log.</param>
+ <remarks>
+ <para>
+ The events passed are logged to the <see cref="T:log4net.Repository.ILoggerRepository"/>
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Plugin.RemoteLoggingServerPlugin.RemoteLoggingSinkImpl.InitializeLifetimeService">
+ <summary>
+ Obtains a lifetime service object to control the lifetime
+ policy for this instance.
+ </summary>
+ <returns><c>null</c> to indicate that this instance should live forever.</returns>
+ <remarks>
+ <para>
+ Obtains a lifetime service object to control the lifetime
+ policy for this instance. This object should live forever
+ therefore this implementation returns <c>null</c>.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Plugin.RemoteLoggingServerPlugin.RemoteLoggingSinkImpl.m_repository">
+ <summary>
+ The underlying <see cref="T:log4net.Repository.ILoggerRepository"/> that events should
+ be logged to.
+ </summary>
+ </member>
+ <member name="T:log4net.Repository.Hierarchy.DefaultLoggerFactory">
+ <summary>
+ Default implementation of <see cref="T:log4net.Repository.Hierarchy.ILoggerFactory"/>
+ </summary>
+ <remarks>
+ <para>
+ This default implementation of the <see cref="T:log4net.Repository.Hierarchy.ILoggerFactory"/>
+ interface is used to create the default subclass
+ of the <see cref="T:log4net.Repository.Hierarchy.Logger"/> object.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="T:log4net.Repository.Hierarchy.ILoggerFactory">
+ <summary>
+ Interface abstracts creation of <see cref="T:log4net.Repository.Hierarchy.Logger"/> instances
+ </summary>
+ <remarks>
+ <para>
+ This interface is used by the <see cref="T:log4net.Repository.Hierarchy.Hierarchy"/> to
+ create new <see cref="T:log4net.Repository.Hierarchy.Logger"/> objects.
+ </para>
+ <para>
+ The <see cref="M:log4net.Repository.Hierarchy.ILoggerFactory.CreateLogger(System.String)"/> method is called
+ to create a named <see cref="T:log4net.Repository.Hierarchy.Logger"/>.
+ </para>
+ <para>
+ Implement this interface to create new subclasses of <see cref="T:log4net.Repository.Hierarchy.Logger"/>.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="M:log4net.Repository.Hierarchy.ILoggerFactory.CreateLogger(System.String)">
+ <summary>
+ Create a new <see cref="T:log4net.Repository.Hierarchy.Logger"/> instance
+ </summary>
+ <param name="name">The name of the <see cref="T:log4net.Repository.Hierarchy.Logger"/>.</param>
+ <returns>The <see cref="T:log4net.Repository.Hierarchy.Logger"/> instance for the specified name.</returns>
+ <remarks>
+ <para>
+ Create a new <see cref="T:log4net.Repository.Hierarchy.Logger"/> instance with the
+ specified name.
+ </para>
+ <para>
+ Called by the <see cref="T:log4net.Repository.Hierarchy.Hierarchy"/> to create
+ new named <see cref="T:log4net.Repository.Hierarchy.Logger"/> instances.
+ </para>
+ <para>
+ If the <paramref name="name"/> is <c>null</c> then the root logger
+ must be returned.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Repository.Hierarchy.DefaultLoggerFactory.#ctor">
+ <summary>
+ Default constructor
+ </summary>
+ <remarks>
+ <para>
+ Initializes a new instance of the <see cref="T:log4net.Repository.Hierarchy.DefaultLoggerFactory"/> class.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Repository.Hierarchy.DefaultLoggerFactory.CreateLogger(System.String)">
+ <summary>
+ Create a new <see cref="T:log4net.Repository.Hierarchy.Logger"/> instance
+ </summary>
+ <param name="name">The name of the <see cref="T:log4net.Repository.Hierarchy.Logger"/>.</param>
+ <returns>The <see cref="T:log4net.Repository.Hierarchy.Logger"/> instance for the specified name.</returns>
+ <remarks>
+ <para>
+ Create a new <see cref="T:log4net.Repository.Hierarchy.Logger"/> instance with the
+ specified name.
+ </para>
+ <para>
+ Called by the <see cref="T:log4net.Repository.Hierarchy.Hierarchy"/> to create
+ new named <see cref="T:log4net.Repository.Hierarchy.Logger"/> instances.
+ </para>
+ <para>
+ If the <paramref name="name"/> is <c>null</c> then the root logger
+ must be returned.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Repository.Hierarchy.DefaultLoggerFactory.LoggerImpl">
+ <summary>
+ Default internal subclass of <see cref="T:log4net.Repository.Hierarchy.Logger"/>
+ </summary>
+ <remarks>
+ <para>
+ This subclass has no additional behavior over the
+ <see cref="T:log4net.Repository.Hierarchy.Logger"/> class but does allow instances
+ to be created.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Repository.Hierarchy.Logger">
+ <summary>
+ Implementation of <see cref="T:log4net.Core.ILogger"/> used by <see cref="P:log4net.Repository.Hierarchy.Logger.Hierarchy"/>
+ </summary>
+ <remarks>
+ <para>
+ Internal class used to provide implementation of <see cref="T:log4net.Core.ILogger"/>
+ interface. Applications should use <see cref="T:log4net.LogManager"/> to get
+ logger instances.
+ </para>
+ <para>
+ This is one of the central classes in the log4net implementation. One of the
+ distinctive features of log4net are hierarchical loggers and their
+ evaluation. The <see cref="P:log4net.Repository.Hierarchy.Logger.Hierarchy"/> organizes the <see cref="T:log4net.Repository.Hierarchy.Logger"/>
+ instances into a rooted tree hierarchy.
+ </para>
+ <para>
+ The <see cref="T:log4net.Repository.Hierarchy.Logger"/> class is abstract. Only concrete subclasses of
+ <see cref="T:log4net.Repository.Hierarchy.Logger"/> can be created. The <see cref="T:log4net.Repository.Hierarchy.ILoggerFactory"/>
+ is used to create instances of this type for the <see cref="P:log4net.Repository.Hierarchy.Logger.Hierarchy"/>.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ <author>Aspi Havewala</author>
+ <author>Douglas de la Torre</author>
+ </member>
+ <member name="M:log4net.Repository.Hierarchy.Logger.#ctor(System.String)">
+ <summary>
+ This constructor created a new <see cref="T:log4net.Repository.Hierarchy.Logger"/> instance and
+ sets its name.
+ </summary>
+ <param name="name">The name of the <see cref="T:log4net.Repository.Hierarchy.Logger"/>.</param>
+ <remarks>
+ <para>
+ This constructor is protected and designed to be used by
+ a subclass that is not abstract.
+ </para>
+ <para>
+ Loggers are constructed by <see cref="T:log4net.Repository.Hierarchy.ILoggerFactory"/>
+ objects. See <see cref="T:log4net.Repository.Hierarchy.DefaultLoggerFactory"/> for the default
+ logger creator.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Repository.Hierarchy.Logger.AddAppender(log4net.Appender.IAppender)">
+ <summary>
+ Add <paramref name="newAppender"/> to the list of appenders of this
+ Logger instance.
+ </summary>
+ <param name="newAppender">An appender to add to this logger</param>
+ <remarks>
+ <para>
+ Add <paramref name="newAppender"/> to the list of appenders of this
+ Logger instance.
+ </para>
+ <para>
+ If <paramref name="newAppender"/> is already in the list of
+ appenders, then it won't be added again.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Repository.Hierarchy.Logger.GetAppender(System.String)">
+ <summary>
+ Look for the appender named as <c>name</c>
+ </summary>
+ <param name="name">The name of the appender to lookup</param>
+ <returns>The appender with the name specified, or <c>null</c>.</returns>
+ <remarks>
+ <para>
+ Returns the named appender, or null if the appender is not found.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Repository.Hierarchy.Logger.RemoveAllAppenders">
+ <summary>
+ Remove all previously added appenders from this Logger instance.
+ </summary>
+ <remarks>
+ <para>
+ Remove all previously added appenders from this Logger instance.
+ </para>
+ <para>
+ This is useful when re-reading configuration information.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Repository.Hierarchy.Logger.RemoveAppender(log4net.Appender.IAppender)">
+ <summary>
+ Remove the appender passed as parameter form the list of appenders.
+ </summary>
+ <param name="appender">The appender to remove</param>
+ <returns>The appender removed from the list</returns>
+ <remarks>
+ <para>
+ Remove the appender passed as parameter form the list of appenders.
+ The appender removed is not closed.
+ If you are discarding the appender you must call
+ <see cref="M:log4net.Appender.IAppender.Close"/> on the appender removed.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Repository.Hierarchy.Logger.RemoveAppender(System.String)">
+ <summary>
+ Remove the appender passed as parameter form the list of appenders.
+ </summary>
+ <param name="name">The name of the appender to remove</param>
+ <returns>The appender removed from the list</returns>
+ <remarks>
+ <para>
+ Remove the named appender passed as parameter form the list of appenders.
+ The appender removed is not closed.
+ If you are discarding the appender you must call
+ <see cref="M:log4net.Appender.IAppender.Close"/> on the appender removed.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Repository.Hierarchy.Logger.Log(System.Type,log4net.Core.Level,System.Object,System.Exception)">
+ <summary>
+ This generic form is intended to be used by wrappers.
+ </summary>
+ <param name="callerStackBoundaryDeclaringType">The declaring type of the method that is
+ the stack boundary into the logging system for this call.</param>
+ <param name="level">The level of the message to be logged.</param>
+ <param name="message">The message object to log.</param>
+ <param name="exception">The exception to log, including its stack trace.</param>
+ <remarks>
+ <para>
+ Generate a logging event for the specified <paramref name="level"/> using
+ the <paramref name="message"/> and <paramref name="exception"/>.
+ </para>
+ <para>
+ This method must not throw any exception to the caller.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Repository.Hierarchy.Logger.Log(log4net.Core.LoggingEvent)">
+ <summary>
+ This is the most generic printing method that is intended to be used
+ by wrappers.
+ </summary>
+ <param name="logEvent">The event being logged.</param>
+ <remarks>
+ <para>
+ Logs the specified logging event through this logger.
+ </para>
+ <para>
+ This method must not throw any exception to the caller.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Repository.Hierarchy.Logger.IsEnabledFor(log4net.Core.Level)">
+ <summary>
+ Checks if this logger is enabled for a given <see cref="P:log4net.Repository.Hierarchy.Logger.Level"/> passed as parameter.
+ </summary>
+ <param name="level">The level to check.</param>
+ <returns>
+ <c>true</c> if this logger is enabled for <c>level</c>, otherwise <c>false</c>.
+ </returns>
+ <remarks>
+ <para>
+ Test if this logger is going to log events of the specified <paramref name="level"/>.
+ </para>
+ <para>
+ This method must not throw any exception to the caller.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Repository.Hierarchy.Logger.CallAppenders(log4net.Core.LoggingEvent)">
+ <summary>
+ Deliver the <see cref="T:log4net.Core.LoggingEvent"/> to the attached appenders.
+ </summary>
+ <param name="loggingEvent">The event to log.</param>
+ <remarks>
+ <para>
+ Call the appenders in the hierarchy starting at
+ <c>this</c>. If no appenders could be found, emit a
+ warning.
+ </para>
+ <para>
+ This method calls all the appenders inherited from the
+ hierarchy circumventing any evaluation of whether to log or not
+ to log the particular log request.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Repository.Hierarchy.Logger.CloseNestedAppenders">
+ <summary>
+ Closes all attached appenders implementing the <see cref="T:log4net.Core.IAppenderAttachable"/> interface.
+ </summary>
+ <remarks>
+ <para>
+ Used to ensure that the appenders are correctly shutdown.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Repository.Hierarchy.Logger.Log(log4net.Core.Level,System.Object,System.Exception)">
+ <summary>
+ This is the most generic printing method. This generic form is intended to be used by wrappers
+ </summary>
+ <param name="level">The level of the message to be logged.</param>
+ <param name="message">The message object to log.</param>
+ <param name="exception">The exception to log, including its stack trace.</param>
+ <remarks>
+ <para>
+ Generate a logging event for the specified <paramref name="level"/> using
+ the <paramref name="message"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Repository.Hierarchy.Logger.ForcedLog(System.Type,log4net.Core.Level,System.Object,System.Exception)">
+ <summary>
+ Creates a new logging event and logs the event without further checks.
+ </summary>
+ <param name="callerStackBoundaryDeclaringType">The declaring type of the method that is
+ the stack boundary into the logging system for this call.</param>
+ <param name="level">The level of the message to be logged.</param>
+ <param name="message">The message object to log.</param>
+ <param name="exception">The exception to log, including its stack trace.</param>
+ <remarks>
+ <para>
+ Generates a logging event and delivers it to the attached
+ appenders.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Repository.Hierarchy.Logger.ForcedLog(log4net.Core.LoggingEvent)">
+ <summary>
+ Creates a new logging event and logs the event without further checks.
+ </summary>
+ <param name="logEvent">The event being logged.</param>
+ <remarks>
+ <para>
+ Delivers the logging event to the attached appenders.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Repository.Hierarchy.Logger.ThisDeclaringType">
+ <summary>
+ The fully qualified type of the Logger class.
+ </summary>
+ </member>
+ <member name="F:log4net.Repository.Hierarchy.Logger.m_name">
+ <summary>
+ The name of this logger.
+ </summary>
+ </member>
+ <member name="F:log4net.Repository.Hierarchy.Logger.m_level">
+ <summary>
+ The assigned level of this logger.
+ </summary>
+ <remarks>
+ <para>
+ The <c>level</c> variable need not be
+ assigned a value in which case it is inherited
+ form the hierarchy.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Repository.Hierarchy.Logger.m_parent">
+ <summary>
+ The parent of this logger.
+ </summary>
+ <remarks>
+ <para>
+ The parent of this logger.
+ All loggers have at least one ancestor which is the root logger.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Repository.Hierarchy.Logger.m_hierarchy">
+ <summary>
+ Loggers need to know what Hierarchy they are in.
+ </summary>
+ <remarks>
+ <para>
+ Loggers need to know what Hierarchy they are in.
+ The hierarchy that this logger is a member of is stored
+ here.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Repository.Hierarchy.Logger.m_appenderAttachedImpl">
+ <summary>
+ Helper implementation of the <see cref="T:log4net.Core.IAppenderAttachable"/> interface
+ </summary>
+ </member>
+ <member name="F:log4net.Repository.Hierarchy.Logger.m_additive">
+ <summary>
+ Flag indicating if child loggers inherit their parents appenders
+ </summary>
+ <remarks>
+ <para>
+ Additivity is set to true by default, that is children inherit
+ the appenders of their ancestors by default. If this variable is
+ set to <c>false</c> then the appenders found in the
+ ancestors of this logger are not used. However, the children
+ of this logger will inherit its appenders, unless the children
+ have their additivity flag set to <c>false</c> too. See
+ the user manual for more details.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Repository.Hierarchy.Logger.m_appenderLock">
+ <summary>
+ Lock to protect AppenderAttachedImpl variable m_appenderAttachedImpl
+ </summary>
+ </member>
+ <member name="P:log4net.Repository.Hierarchy.Logger.Parent">
+ <summary>
+ Gets or sets the parent logger in the hierarchy.
+ </summary>
+ <value>
+ The parent logger in the hierarchy.
+ </value>
+ <remarks>
+ <para>
+ Part of the Composite pattern that makes the hierarchy.
+ The hierarchy is parent linked rather than child linked.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Repository.Hierarchy.Logger.Additivity">
+ <summary>
+ Gets or sets a value indicating if child loggers inherit their parent's appenders.
+ </summary>
+ <value>
+ <c>true</c> if child loggers inherit their parent's appenders.
+ </value>
+ <remarks>
+ <para>
+ Additivity is set to <c>true</c> by default, that is children inherit
+ the appenders of their ancestors by default. If this variable is
+ set to <c>false</c> then the appenders found in the
+ ancestors of this logger are not used. However, the children
+ of this logger will inherit its appenders, unless the children
+ have their additivity flag set to <c>false</c> too. See
+ the user manual for more details.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Repository.Hierarchy.Logger.EffectiveLevel">
+ <summary>
+ Gets the effective level for this logger.
+ </summary>
+ <returns>The nearest level in the logger hierarchy.</returns>
+ <remarks>
+ <para>
+ Starting from this logger, searches the logger hierarchy for a
+ non-null level and returns it. Otherwise, returns the level of the
+ root logger.
+ </para>
+ <para>The Logger class is designed so that this method executes as
+ quickly as possible.</para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Repository.Hierarchy.Logger.Hierarchy">
+ <summary>
+ Gets or sets the <see cref="P:log4net.Repository.Hierarchy.Logger.Hierarchy"/> where this
+ <c>Logger</c> instance is attached to.
+ </summary>
+ <value>The hierarchy that this logger belongs to.</value>
+ <remarks>
+ <para>
+ This logger must be attached to a single <see cref="P:log4net.Repository.Hierarchy.Logger.Hierarchy"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Repository.Hierarchy.Logger.Level">
+ <summary>
+ Gets or sets the assigned <see cref="P:log4net.Repository.Hierarchy.Logger.Level"/>, if any, for this Logger.
+ </summary>
+ <value>
+ The <see cref="P:log4net.Repository.Hierarchy.Logger.Level"/> of this logger.
+ </value>
+ <remarks>
+ <para>
+ The assigned <see cref="P:log4net.Repository.Hierarchy.Logger.Level"/> can be <c>null</c>.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Repository.Hierarchy.Logger.Appenders">
+ <summary>
+ Get the appenders contained in this logger as an
+ <see cref="T:System.Collections.ICollection"/>.
+ </summary>
+ <returns>A collection of the appenders in this logger</returns>
+ <remarks>
+ <para>
+ Get the appenders contained in this logger as an
+ <see cref="T:System.Collections.ICollection"/>. If no appenders
+ can be found, then a <see cref="T:log4net.Util.EmptyCollection"/> is returned.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Repository.Hierarchy.Logger.Name">
+ <summary>
+ Gets the logger name.
+ </summary>
+ <value>
+ The name of the logger.
+ </value>
+ <remarks>
+ <para>
+ The name of this logger
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Repository.Hierarchy.Logger.Repository">
+ <summary>
+ Gets the <see cref="T:log4net.Repository.ILoggerRepository"/> where this
+ <c>Logger</c> instance is attached to.
+ </summary>
+ <value>
+ The <see cref="T:log4net.Repository.ILoggerRepository"/> that this logger belongs to.
+ </value>
+ <remarks>
+ <para>
+ Gets the <see cref="T:log4net.Repository.ILoggerRepository"/> where this
+ <c>Logger</c> instance is attached to.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Repository.Hierarchy.DefaultLoggerFactory.LoggerImpl.#ctor(System.String)">
+ <summary>
+ Construct a new Logger
+ </summary>
+ <param name="name">the name of the logger</param>
+ <remarks>
+ <para>
+ Initializes a new instance of the <see cref="T:log4net.Repository.Hierarchy.DefaultLoggerFactory.LoggerImpl"/> class
+ with the specified name.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Repository.Hierarchy.LoggerCreationEventHandler">
+ <summary>
+ Delegate used to handle logger creation event notifications.
+ </summary>
+ <param name="sender">The <see cref="T:log4net.Repository.Hierarchy.Hierarchy"/> in which the <see cref="T:log4net.Repository.Hierarchy.Logger"/> has been created.</param>
+ <param name="e">The <see cref="T:log4net.Repository.Hierarchy.LoggerCreationEventArgs"/> event args that hold the <see cref="T:log4net.Repository.Hierarchy.Logger"/> instance that has been created.</param>
+ <remarks>
+ <para>
+ Delegate used to handle logger creation event notifications.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Repository.Hierarchy.LoggerCreationEventArgs">
+ <summary>
+ Provides data for the <see cref="E:log4net.Repository.Hierarchy.Hierarchy.LoggerCreatedEvent"/> event.
+ </summary>
+ <remarks>
+ <para>
+ A <see cref="E:log4net.Repository.Hierarchy.Hierarchy.LoggerCreatedEvent"/> event is raised every time a
+ <see cref="P:log4net.Repository.Hierarchy.LoggerCreationEventArgs.Logger"/> is created.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Repository.Hierarchy.LoggerCreationEventArgs.m_log">
+ <summary>
+ The <see cref="P:log4net.Repository.Hierarchy.LoggerCreationEventArgs.Logger"/> created
+ </summary>
+ </member>
+ <member name="M:log4net.Repository.Hierarchy.LoggerCreationEventArgs.#ctor(log4net.Repository.Hierarchy.Logger)">
+ <summary>
+ Constructor
+ </summary>
+ <param name="log">The <see cref="P:log4net.Repository.Hierarchy.LoggerCreationEventArgs.Logger"/> that has been created.</param>
+ <remarks>
+ <para>
+ Initializes a new instance of the <see cref="T:log4net.Repository.Hierarchy.LoggerCreationEventArgs"/> event argument
+ class,with the specified <see cref="P:log4net.Repository.Hierarchy.LoggerCreationEventArgs.Logger"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Repository.Hierarchy.LoggerCreationEventArgs.Logger">
+ <summary>
+ Gets the <see cref="P:log4net.Repository.Hierarchy.LoggerCreationEventArgs.Logger"/> that has been created.
+ </summary>
+ <value>
+ The <see cref="P:log4net.Repository.Hierarchy.LoggerCreationEventArgs.Logger"/> that has been created.
+ </value>
+ <remarks>
+ <para>
+ The <see cref="P:log4net.Repository.Hierarchy.LoggerCreationEventArgs.Logger"/> that has been created.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Repository.Hierarchy.Hierarchy">
+ <summary>
+ Hierarchical organization of loggers
+ </summary>
+ <remarks>
+ <para>
+ <i>The casual user should not have to deal with this class
+ directly.</i>
+ </para>
+ <para>
+ This class is specialized in retrieving loggers by name and
+ also maintaining the logger hierarchy. Implements the
+ <see cref="T:log4net.Repository.ILoggerRepository"/> interface.
+ </para>
+ <para>
+ The structure of the logger hierarchy is maintained by the
+ <see cref="M:log4net.Repository.Hierarchy.Hierarchy.GetLogger(System.String)"/> method. The hierarchy is such that children
+ link to their parent but parents do not have any references to their
+ children. Moreover, loggers can be instantiated in any order, in
+ particular descendant before ancestor.
+ </para>
+ <para>
+ In case a descendant is created before a particular ancestor,
+ then it creates a provision node for the ancestor and adds itself
+ to the provision node. Other descendants of the same ancestor add
+ themselves to the previously created provision node.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="T:log4net.Repository.LoggerRepositorySkeleton">
+ <summary>
+ Base implementation of <see cref="T:log4net.Repository.ILoggerRepository"/>
+ </summary>
+ <remarks>
+ <para>
+ Default abstract implementation of the <see cref="T:log4net.Repository.ILoggerRepository"/> interface.
+ </para>
+ <para>
+ Skeleton implementation of the <see cref="T:log4net.Repository.ILoggerRepository"/> interface.
+ All <see cref="T:log4net.Repository.ILoggerRepository"/> types can extend this type.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="T:log4net.Repository.ILoggerRepository">
+ <summary>
+ Interface implemented by logger repositories.
+ </summary>
+ <remarks>
+ <para>
+ This interface is implemented by logger repositories. e.g.
+ <see cref="T:log4net.Repository.Hierarchy.Hierarchy"/>.
+ </para>
+ <para>
+ This interface is used by the <see cref="T:log4net.LogManager"/>
+ to obtain <see cref="T:log4net.ILog"/> interfaces.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="M:log4net.Repository.ILoggerRepository.Exists(System.String)">
+ <summary>
+ Check if the named logger exists in the repository. If so return
+ its reference, otherwise returns <c>null</c>.
+ </summary>
+ <param name="name">The name of the logger to lookup</param>
+ <returns>The Logger object with the name specified</returns>
+ <remarks>
+ <para>
+ If the names logger exists it is returned, otherwise
+ <c>null</c> is returned.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Repository.ILoggerRepository.GetCurrentLoggers">
+ <summary>
+ Returns all the currently defined loggers as an Array.
+ </summary>
+ <returns>All the defined loggers</returns>
+ <remarks>
+ <para>
+ Returns all the currently defined loggers as an Array.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Repository.ILoggerRepository.GetLogger(System.String)">
+ <summary>
+ Returns a named logger instance
+ </summary>
+ <param name="name">The name of the logger to retrieve</param>
+ <returns>The logger object with the name specified</returns>
+ <remarks>
+ <para>
+ Returns a named logger instance.
+ </para>
+ <para>
+ If a logger of that name already exists, then it will be
+ returned. Otherwise, a new logger will be instantiated and
+ then linked with its existing ancestors as well as children.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Repository.ILoggerRepository.Shutdown">
+ <summary>Shutdown the repository</summary>
+ <remarks>
+ <para>
+ Shutting down a repository will <i>safely</i> close and remove
+ all appenders in all loggers including the root logger.
+ </para>
+ <para>
+ Some appenders need to be closed before the
+ application exists. Otherwise, pending logging events might be
+ lost.
+ </para>
+ <para>
+ The <see cref="M:log4net.Repository.ILoggerRepository.Shutdown"/> method is careful to close nested
+ appenders before closing regular appenders. This is allows
+ configurations where a regular appender is attached to a logger
+ and again to a nested appender.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Repository.ILoggerRepository.ResetConfiguration">
+ <summary>
+ Reset the repositories configuration to a default state
+ </summary>
+ <remarks>
+ <para>
+ Reset all values contained in this instance to their
+ default state.
+ </para>
+ <para>
+ Existing loggers are not removed. They are just reset.
+ </para>
+ <para>
+ This method should be used sparingly and with care as it will
+ block all logging until it is completed.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Repository.ILoggerRepository.Log(log4net.Core.LoggingEvent)">
+ <summary>
+ Log the <see cref="T:log4net.Core.LoggingEvent"/> through this repository.
+ </summary>
+ <param name="logEvent">the event to log</param>
+ <remarks>
+ <para>
+ This method should not normally be used to log.
+ The <see cref="T:log4net.ILog"/> interface should be used
+ for routine logging. This interface can be obtained
+ using the <see cref="M:log4net.LogManager.GetLogger(System.String)"/> method.
+ </para>
+ <para>
+ The <c>logEvent</c> is delivered to the appropriate logger and
+ that logger is then responsible for logging the event.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Repository.ILoggerRepository.GetAppenders">
+ <summary>
+ Returns all the Appenders that are configured as an Array.
+ </summary>
+ <returns>All the Appenders</returns>
+ <remarks>
+ <para>
+ Returns all the Appenders that are configured as an Array.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Repository.ILoggerRepository.Name">
+ <summary>
+ The name of the repository
+ </summary>
+ <value>
+ The name of the repository
+ </value>
+ <remarks>
+ <para>
+ The name of the repository.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Repository.ILoggerRepository.RendererMap">
+ <summary>
+ RendererMap accesses the object renderer map for this repository.
+ </summary>
+ <value>
+ RendererMap accesses the object renderer map for this repository.
+ </value>
+ <remarks>
+ <para>
+ RendererMap accesses the object renderer map for this repository.
+ </para>
+ <para>
+ The RendererMap holds a mapping between types and
+ <see cref="T:log4net.ObjectRenderer.IObjectRenderer"/> objects.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Repository.ILoggerRepository.PluginMap">
+ <summary>
+ The plugin map for this repository.
+ </summary>
+ <value>
+ The plugin map for this repository.
+ </value>
+ <remarks>
+ <para>
+ The plugin map holds the <see cref="T:log4net.Plugin.IPlugin"/> instances
+ that have been attached to this repository.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Repository.ILoggerRepository.LevelMap">
+ <summary>
+ Get the level map for the Repository.
+ </summary>
+ <remarks>
+ <para>
+ Get the level map for the Repository.
+ </para>
+ <para>
+ The level map defines the mappings between
+ level names and <see cref="T:log4net.Core.Level"/> objects in
+ this repository.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Repository.ILoggerRepository.Threshold">
+ <summary>
+ The threshold for all events in this repository
+ </summary>
+ <value>
+ The threshold for all events in this repository
+ </value>
+ <remarks>
+ <para>
+ The threshold for all events in this repository.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Repository.ILoggerRepository.Configured">
+ <summary>
+ Flag indicates if this repository has been configured.
+ </summary>
+ <value>
+ Flag indicates if this repository has been configured.
+ </value>
+ <remarks>
+ <para>
+ Flag indicates if this repository has been configured.
+ </para>
+ </remarks>
+ </member>
+ <member name="E:log4net.Repository.ILoggerRepository.ShutdownEvent">
+ <summary>
+ Event to notify that the repository has been shutdown.
+ </summary>
+ <value>
+ Event to notify that the repository has been shutdown.
+ </value>
+ <remarks>
+ <para>
+ Event raised when the repository has been shutdown.
+ </para>
+ </remarks>
+ </member>
+ <member name="E:log4net.Repository.ILoggerRepository.ConfigurationReset">
+ <summary>
+ Event to notify that the repository has had its configuration reset.
+ </summary>
+ <value>
+ Event to notify that the repository has had its configuration reset.
+ </value>
+ <remarks>
+ <para>
+ Event raised when the repository's configuration has been
+ reset to default.
+ </para>
+ </remarks>
+ </member>
+ <member name="E:log4net.Repository.ILoggerRepository.ConfigurationChanged">
+ <summary>
+ Event to notify that the repository has had its configuration changed.
+ </summary>
+ <value>
+ Event to notify that the repository has had its configuration changed.
+ </value>
+ <remarks>
+ <para>
+ Event raised when the repository's configuration has been changed.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Repository.ILoggerRepository.Properties">
+ <summary>
+ Repository specific properties
+ </summary>
+ <value>
+ Repository specific properties
+ </value>
+ <remarks>
+ <para>
+ These properties can be specified on a repository specific basis.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Repository.LoggerRepositorySkeleton.#ctor">
+ <summary>
+ Default Constructor
+ </summary>
+ <remarks>
+ <para>
+ Initializes the repository with default (empty) properties.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Repository.LoggerRepositorySkeleton.#ctor(log4net.Util.PropertiesDictionary)">
+ <summary>
+ Construct the repository using specific properties
+ </summary>
+ <param name="properties">the properties to set for this repository</param>
+ <remarks>
+ <para>
+ Initializes the repository with specified properties.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Repository.LoggerRepositorySkeleton.Exists(System.String)">
+ <summary>
+ Test if logger exists
+ </summary>
+ <param name="name">The name of the logger to lookup</param>
+ <returns>The Logger object with the name specified</returns>
+ <remarks>
+ <para>
+ Check if the named logger exists in the repository. If so return
+ its reference, otherwise returns <c>null</c>.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Repository.LoggerRepositorySkeleton.GetCurrentLoggers">
+ <summary>
+ Returns all the currently defined loggers in the repository
+ </summary>
+ <returns>All the defined loggers</returns>
+ <remarks>
+ <para>
+ Returns all the currently defined loggers in the repository as an Array.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Repository.LoggerRepositorySkeleton.GetLogger(System.String)">
+ <summary>
+ Return a new logger instance
+ </summary>
+ <param name="name">The name of the logger to retrieve</param>
+ <returns>The logger object with the name specified</returns>
+ <remarks>
+ <para>
+ Return a new logger instance.
+ </para>
+ <para>
+ If a logger of that name already exists, then it will be
+ returned. Otherwise, a new logger will be instantiated and
+ then linked with its existing ancestors as well as children.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Repository.LoggerRepositorySkeleton.Shutdown">
+ <summary>
+ Shutdown the repository
+ </summary>
+ <remarks>
+ <para>
+ Shutdown the repository. Can be overridden in a subclass.
+ This base class implementation notifies the <see cref="E:log4net.Repository.LoggerRepositorySkeleton.ShutdownEvent"/>
+ listeners and all attached plugins of the shutdown event.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Repository.LoggerRepositorySkeleton.ResetConfiguration">
+ <summary>
+ Reset the repositories configuration to a default state
+ </summary>
+ <remarks>
+ <para>
+ Reset all values contained in this instance to their
+ default state.
+ </para>
+ <para>
+ Existing loggers are not removed. They are just reset.
+ </para>
+ <para>
+ This method should be used sparingly and with care as it will
+ block all logging until it is completed.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Repository.LoggerRepositorySkeleton.Log(log4net.Core.LoggingEvent)">
+ <summary>
+ Log the logEvent through this repository.
+ </summary>
+ <param name="logEvent">the event to log</param>
+ <remarks>
+ <para>
+ This method should not normally be used to log.
+ The <see cref="T:log4net.ILog"/> interface should be used
+ for routine logging. This interface can be obtained
+ using the <see cref="M:log4net.LogManager.GetLogger(System.String)"/> method.
+ </para>
+ <para>
+ The <c>logEvent</c> is delivered to the appropriate logger and
+ that logger is then responsible for logging the event.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Repository.LoggerRepositorySkeleton.GetAppenders">
+ <summary>
+ Returns all the Appenders that are configured as an Array.
+ </summary>
+ <returns>All the Appenders</returns>
+ <remarks>
+ <para>
+ Returns all the Appenders that are configured as an Array.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Repository.LoggerRepositorySkeleton.AddRenderer(System.Type,log4net.ObjectRenderer.IObjectRenderer)">
+ <summary>
+ Adds an object renderer for a specific class.
+ </summary>
+ <param name="typeToRender">The type that will be rendered by the renderer supplied.</param>
+ <param name="rendererInstance">The object renderer used to render the object.</param>
+ <remarks>
+ <para>
+ Adds an object renderer for a specific class.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Repository.LoggerRepositorySkeleton.OnShutdown(System.EventArgs)">
+ <summary>
+ Notify the registered listeners that the repository is shutting down
+ </summary>
+ <param name="e">Empty EventArgs</param>
+ <remarks>
+ <para>
+ Notify any listeners that this repository is shutting down.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Repository.LoggerRepositorySkeleton.OnConfigurationReset(System.EventArgs)">
+ <summary>
+ Notify the registered listeners that the repository has had its configuration reset
+ </summary>
+ <param name="e">Empty EventArgs</param>
+ <remarks>
+ <para>
+ Notify any listeners that this repository's configuration has been reset.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Repository.LoggerRepositorySkeleton.OnConfigurationChanged(System.EventArgs)">
+ <summary>
+ Notify the registered listeners that the repository has had its configuration changed
+ </summary>
+ <param name="e">Empty EventArgs</param>
+ <remarks>
+ <para>
+ Notify any listeners that this repository's configuration has changed.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Repository.LoggerRepositorySkeleton.RaiseConfigurationChanged(System.EventArgs)">
+ <summary>
+ Raise a configuration changed event on this repository
+ </summary>
+ <param name="e">EventArgs.Empty</param>
+ <remarks>
+ <para>
+ Applications that programmatically change the configuration of the repository should
+ raise this event notification to notify listeners.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Repository.LoggerRepositorySkeleton.Name">
+ <summary>
+ The name of the repository
+ </summary>
+ <value>
+ The string name of the repository
+ </value>
+ <remarks>
+ <para>
+ The name of this repository. The name is
+ used to store and lookup the repositories
+ stored by the <see cref="T:log4net.Core.IRepositorySelector"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Repository.LoggerRepositorySkeleton.Threshold">
+ <summary>
+ The threshold for all events in this repository
+ </summary>
+ <value>
+ The threshold for all events in this repository
+ </value>
+ <remarks>
+ <para>
+ The threshold for all events in this repository
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Repository.LoggerRepositorySkeleton.RendererMap">
+ <summary>
+ RendererMap accesses the object renderer map for this repository.
+ </summary>
+ <value>
+ RendererMap accesses the object renderer map for this repository.
+ </value>
+ <remarks>
+ <para>
+ RendererMap accesses the object renderer map for this repository.
+ </para>
+ <para>
+ The RendererMap holds a mapping between types and
+ <see cref="T:log4net.ObjectRenderer.IObjectRenderer"/> objects.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Repository.LoggerRepositorySkeleton.PluginMap">
+ <summary>
+ The plugin map for this repository.
+ </summary>
+ <value>
+ The plugin map for this repository.
+ </value>
+ <remarks>
+ <para>
+ The plugin map holds the <see cref="T:log4net.Plugin.IPlugin"/> instances
+ that have been attached to this repository.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Repository.LoggerRepositorySkeleton.LevelMap">
+ <summary>
+ Get the level map for the Repository.
+ </summary>
+ <remarks>
+ <para>
+ Get the level map for the Repository.
+ </para>
+ <para>
+ The level map defines the mappings between
+ level names and <see cref="T:log4net.Core.Level"/> objects in
+ this repository.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Repository.LoggerRepositorySkeleton.Configured">
+ <summary>
+ Flag indicates if this repository has been configured.
+ </summary>
+ <value>
+ Flag indicates if this repository has been configured.
+ </value>
+ <remarks>
+ <para>
+ Flag indicates if this repository has been configured.
+ </para>
+ </remarks>
+ </member>
+ <member name="E:log4net.Repository.LoggerRepositorySkeleton.ShutdownEvent">
+ <summary>
+ Event to notify that the repository has been shutdown.
+ </summary>
+ <value>
+ Event to notify that the repository has been shutdown.
+ </value>
+ <remarks>
+ <para>
+ Event raised when the repository has been shutdown.
+ </para>
+ </remarks>
+ </member>
+ <member name="E:log4net.Repository.LoggerRepositorySkeleton.ConfigurationReset">
+ <summary>
+ Event to notify that the repository has had its configuration reset.
+ </summary>
+ <value>
+ Event to notify that the repository has had its configuration reset.
+ </value>
+ <remarks>
+ <para>
+ Event raised when the repository's configuration has been
+ reset to default.
+ </para>
+ </remarks>
+ </member>
+ <member name="E:log4net.Repository.LoggerRepositorySkeleton.ConfigurationChanged">
+ <summary>
+ Event to notify that the repository has had its configuration changed.
+ </summary>
+ <value>
+ Event to notify that the repository has had its configuration changed.
+ </value>
+ <remarks>
+ <para>
+ Event raised when the repository's configuration has been changed.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Repository.LoggerRepositorySkeleton.Properties">
+ <summary>
+ Repository specific properties
+ </summary>
+ <value>
+ Repository specific properties
+ </value>
+ <remarks>
+ These properties can be specified on a repository specific basis
+ </remarks>
+ </member>
+ <member name="T:log4net.Repository.IBasicRepositoryConfigurator">
+ <summary>
+ Basic Configurator interface for repositories
+ </summary>
+ <remarks>
+ <para>
+ Interface used by basic configurator to configure a <see cref="T:log4net.Repository.ILoggerRepository"/>
+ with a default <see cref="T:log4net.Appender.IAppender"/>.
+ </para>
+ <para>
+ A <see cref="T:log4net.Repository.ILoggerRepository"/> should implement this interface to support
+ configuration by the <see cref="T:log4net.Config.BasicConfigurator"/>.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="M:log4net.Repository.IBasicRepositoryConfigurator.Configure(log4net.Appender.IAppender)">
+ <summary>
+ Initialize the repository using the specified appender
+ </summary>
+ <param name="appender">the appender to use to log all logging events</param>
+ <remarks>
+ <para>
+ Configure the repository to route all logging events to the
+ specified appender.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Repository.IXmlRepositoryConfigurator">
+ <summary>
+ Configure repository using XML
+ </summary>
+ <remarks>
+ <para>
+ Interface used by Xml configurator to configure a <see cref="T:log4net.Repository.ILoggerRepository"/>.
+ </para>
+ <para>
+ A <see cref="T:log4net.Repository.ILoggerRepository"/> should implement this interface to support
+ configuration by the <see cref="T:log4net.Config.XmlConfigurator"/>.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="M:log4net.Repository.IXmlRepositoryConfigurator.Configure(System.Xml.XmlElement)">
+ <summary>
+ Initialize the repository using the specified config
+ </summary>
+ <param name="element">the element containing the root of the config</param>
+ <remarks>
+ <para>
+ The schema for the XML configuration data is defined by
+ the implementation.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Repository.Hierarchy.Hierarchy.#ctor">
+ <summary>
+ Default constructor
+ </summary>
+ <remarks>
+ <para>
+ Initializes a new instance of the <see cref="T:log4net.Repository.Hierarchy.Hierarchy"/> class.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Repository.Hierarchy.Hierarchy.#ctor(log4net.Util.PropertiesDictionary)">
+ <summary>
+ Construct with properties
+ </summary>
+ <param name="properties">The properties to pass to this repository.</param>
+ <remarks>
+ <para>
+ Initializes a new instance of the <see cref="T:log4net.Repository.Hierarchy.Hierarchy"/> class.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Repository.Hierarchy.Hierarchy.#ctor(log4net.Repository.Hierarchy.ILoggerFactory)">
+ <summary>
+ Construct with a logger factory
+ </summary>
+ <param name="loggerFactory">The factory to use to create new logger instances.</param>
+ <remarks>
+ <para>
+ Initializes a new instance of the <see cref="T:log4net.Repository.Hierarchy.Hierarchy"/> class with
+ the specified <see cref="T:log4net.Repository.Hierarchy.ILoggerFactory"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Repository.Hierarchy.Hierarchy.#ctor(log4net.Util.PropertiesDictionary,log4net.Repository.Hierarchy.ILoggerFactory)">
+ <summary>
+ Construct with properties and a logger factory
+ </summary>
+ <param name="properties">The properties to pass to this repository.</param>
+ <param name="loggerFactory">The factory to use to create new logger instances.</param>
+ <remarks>
+ <para>
+ Initializes a new instance of the <see cref="T:log4net.Repository.Hierarchy.Hierarchy"/> class with
+ the specified <see cref="T:log4net.Repository.Hierarchy.ILoggerFactory"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Repository.Hierarchy.Hierarchy.Exists(System.String)">
+ <summary>
+ Test if a logger exists
+ </summary>
+ <param name="name">The name of the logger to lookup</param>
+ <returns>The Logger object with the name specified</returns>
+ <remarks>
+ <para>
+ Check if the named logger exists in the hierarchy. If so return
+ its reference, otherwise returns <c>null</c>.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Repository.Hierarchy.Hierarchy.GetCurrentLoggers">
+ <summary>
+ Returns all the currently defined loggers in the hierarchy as an Array
+ </summary>
+ <returns>All the defined loggers</returns>
+ <remarks>
+ <para>
+ Returns all the currently defined loggers in the hierarchy as an Array.
+ The root logger is <b>not</b> included in the returned
+ enumeration.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Repository.Hierarchy.Hierarchy.GetLogger(System.String)">
+ <summary>
+ Return a new logger instance named as the first parameter using
+ the default factory.
+ </summary>
+ <remarks>
+ <para>
+ Return a new logger instance named as the first parameter using
+ the default factory.
+ </para>
+ <para>
+ If a logger of that name already exists, then it will be
+ returned. Otherwise, a new logger will be instantiated and
+ then linked with its existing ancestors as well as children.
+ </para>
+ </remarks>
+ <param name="name">The name of the logger to retrieve</param>
+ <returns>The logger object with the name specified</returns>
+ </member>
+ <member name="M:log4net.Repository.Hierarchy.Hierarchy.Shutdown">
+ <summary>
+ Shutting down a hierarchy will <i>safely</i> close and remove
+ all appenders in all loggers including the root logger.
+ </summary>
+ <remarks>
+ <para>
+ Shutting down a hierarchy will <i>safely</i> close and remove
+ all appenders in all loggers including the root logger.
+ </para>
+ <para>
+ Some appenders need to be closed before the
+ application exists. Otherwise, pending logging events might be
+ lost.
+ </para>
+ <para>
+ The <c>Shutdown</c> method is careful to close nested
+ appenders before closing regular appenders. This is allows
+ configurations where a regular appender is attached to a logger
+ and again to a nested appender.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Repository.Hierarchy.Hierarchy.ResetConfiguration">
+ <summary>
+ Reset all values contained in this hierarchy instance to their default.
+ </summary>
+ <remarks>
+ <para>
+ Reset all values contained in this hierarchy instance to their
+ default. This removes all appenders from all loggers, sets
+ the level of all non-root loggers to <c>null</c>,
+ sets their additivity flag to <c>true</c> and sets the level
+ of the root logger to <see cref="F:log4net.Core.Level.Debug"/>. Moreover,
+ message disabling is set its default "off" value.
+ </para>
+ <para>
+ Existing loggers are not removed. They are just reset.
+ </para>
+ <para>
+ This method should be used sparingly and with care as it will
+ block all logging until it is completed.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Repository.Hierarchy.Hierarchy.Log(log4net.Core.LoggingEvent)">
+ <summary>
+ Log the logEvent through this hierarchy.
+ </summary>
+ <param name="logEvent">the event to log</param>
+ <remarks>
+ <para>
+ This method should not normally be used to log.
+ The <see cref="T:log4net.ILog"/> interface should be used
+ for routine logging. This interface can be obtained
+ using the <see cref="M:log4net.LogManager.GetLogger(System.String)"/> method.
+ </para>
+ <para>
+ The <c>logEvent</c> is delivered to the appropriate logger and
+ that logger is then responsible for logging the event.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Repository.Hierarchy.Hierarchy.GetAppenders">
+ <summary>
+ Returns all the Appenders that are currently configured
+ </summary>
+ <returns>An array containing all the currently configured appenders</returns>
+ <remarks>
+ <para>
+ Returns all the <see cref="T:log4net.Appender.IAppender"/> instances that are currently configured.
+ All the loggers are searched for appenders. The appenders may also be containers
+ for appenders and these are also searched for additional loggers.
+ </para>
+ <para>
+ The list returned is unordered but does not contain duplicates.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Repository.Hierarchy.Hierarchy.CollectAppender(System.Collections.ArrayList,log4net.Appender.IAppender)">
+ <summary>
+ Collect the appenders from an <see cref="T:log4net.Core.IAppenderAttachable"/>.
+ The appender may also be a container.
+ </summary>
+ <param name="appenderList"></param>
+ <param name="appender"></param>
+ </member>
+ <member name="M:log4net.Repository.Hierarchy.Hierarchy.CollectAppenders(System.Collections.ArrayList,log4net.Core.IAppenderAttachable)">
+ <summary>
+ Collect the appenders from an <see cref="T:log4net.Core.IAppenderAttachable"/> container
+ </summary>
+ <param name="appenderList"></param>
+ <param name="container"></param>
+ </member>
+ <member name="M:log4net.Repository.Hierarchy.Hierarchy.log4net#Repository#IBasicRepositoryConfigurator#Configure(log4net.Appender.IAppender)">
+ <summary>
+ Initialize the log4net system using the specified appender
+ </summary>
+ <param name="appender">the appender to use to log all logging events</param>
+ </member>
+ <member name="M:log4net.Repository.Hierarchy.Hierarchy.BasicRepositoryConfigure(log4net.Appender.IAppender)">
+ <summary>
+ Initialize the log4net system using the specified appender
+ </summary>
+ <param name="appender">the appender to use to log all logging events</param>
+ <remarks>
+ <para>
+ This method provides the same functionality as the
+ <see cref="M:log4net.Repository.IBasicRepositoryConfigurator.Configure(log4net.Appender.IAppender)"/> method implemented
+ on this object, but it is protected and therefore can be called by subclasses.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Repository.Hierarchy.Hierarchy.log4net#Repository#IXmlRepositoryConfigurator#Configure(System.Xml.XmlElement)">
+ <summary>
+ Initialize the log4net system using the specified config
+ </summary>
+ <param name="element">the element containing the root of the config</param>
+ </member>
+ <member name="M:log4net.Repository.Hierarchy.Hierarchy.XmlRepositoryConfigure(System.Xml.XmlElement)">
+ <summary>
+ Initialize the log4net system using the specified config
+ </summary>
+ <param name="element">the element containing the root of the config</param>
+ <remarks>
+ <para>
+ This method provides the same functionality as the
+ <see cref="M:log4net.Repository.IBasicRepositoryConfigurator.Configure(log4net.Appender.IAppender)"/> method implemented
+ on this object, but it is protected and therefore can be called by subclasses.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Repository.Hierarchy.Hierarchy.IsDisabled(log4net.Core.Level)">
+ <summary>
+ Test if this hierarchy is disabled for the specified <see cref="T:log4net.Core.Level"/>.
+ </summary>
+ <param name="level">The level to check against.</param>
+ <returns>
+ <c>true</c> if the repository is disabled for the level argument, <c>false</c> otherwise.
+ </returns>
+ <remarks>
+ <para>
+ If this hierarchy has not been configured then this method will
+ always return <c>true</c>.
+ </para>
+ <para>
+ This method will return <c>true</c> if this repository is
+ disabled for <c>level</c> object passed as parameter and
+ <c>false</c> otherwise.
+ </para>
+ <para>
+ See also the <see cref="P:log4net.Repository.ILoggerRepository.Threshold"/> property.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Repository.Hierarchy.Hierarchy.Clear">
+ <summary>
+ Clear all logger definitions from the internal hashtable
+ </summary>
+ <remarks>
+ <para>
+ This call will clear all logger definitions from the internal
+ hashtable. Invoking this method will irrevocably mess up the
+ logger hierarchy.
+ </para>
+ <para>
+ You should <b>really</b> know what you are doing before
+ invoking this method.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Repository.Hierarchy.Hierarchy.GetLogger(System.String,log4net.Repository.Hierarchy.ILoggerFactory)">
+ <summary>
+ Return a new logger instance named as the first parameter using
+ <paramref name="factory"/>.
+ </summary>
+ <param name="name">The name of the logger to retrieve</param>
+ <param name="factory">The factory that will make the new logger instance</param>
+ <returns>The logger object with the name specified</returns>
+ <remarks>
+ <para>
+ If a logger of that name already exists, then it will be
+ returned. Otherwise, a new logger will be instantiated by the
+ <paramref name="factory"/> parameter and linked with its existing
+ ancestors as well as children.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Repository.Hierarchy.Hierarchy.OnLoggerCreationEvent(log4net.Repository.Hierarchy.Logger)">
+ <summary>
+ Sends a logger creation event to all registered listeners
+ </summary>
+ <param name="logger">The newly created logger</param>
+ <remarks>
+ Raises the logger creation event.
+ </remarks>
+ </member>
+ <member name="M:log4net.Repository.Hierarchy.Hierarchy.UpdateParents(log4net.Repository.Hierarchy.Logger)">
+ <summary>
+ Updates all the parents of the specified logger
+ </summary>
+ <param name="log">The logger to update the parents for</param>
+ <remarks>
+ <para>
+ This method loops through all the <i>potential</i> parents of
+ <paramref name="log"/>. There 3 possible cases:
+ </para>
+ <list type="number">
+ <item>
+ <term>No entry for the potential parent of <paramref name="log"/> exists</term>
+ <description>
+ We create a ProvisionNode for this potential
+ parent and insert <paramref name="log"/> in that provision node.
+ </description>
+ </item>
+ <item>
+ <term>The entry is of type Logger for the potential parent.</term>
+ <description>
+ The entry is <paramref name="log"/>'s nearest existing parent. We
+ update <paramref name="log"/>'s parent field with this entry. We also break from
+ he loop because updating our parent's parent is our parent's
+ responsibility.
+ </description>
+ </item>
+ <item>
+ <term>The entry is of type ProvisionNode for this potential parent.</term>
+ <description>
+ We add <paramref name="log"/> to the list of children for this
+ potential parent.
+ </description>
+ </item>
+ </list>
+ </remarks>
+ </member>
+ <member name="M:log4net.Repository.Hierarchy.Hierarchy.UpdateChildren(log4net.Repository.Hierarchy.ProvisionNode,log4net.Repository.Hierarchy.Logger)">
+ <summary>
+ Replace a <see cref="T:log4net.Repository.Hierarchy.ProvisionNode"/> with a <see cref="T:log4net.Repository.Hierarchy.Logger"/> in the hierarchy.
+ </summary>
+ <param name="pn"></param>
+ <param name="log"></param>
+ <remarks>
+ <para>
+ We update the links for all the children that placed themselves
+ in the provision node 'pn'. The second argument 'log' is a
+ reference for the newly created Logger, parent of all the
+ children in 'pn'.
+ </para>
+ <para>
+ We loop on all the children 'c' in 'pn'.
+ </para>
+ <para>
+ If the child 'c' has been already linked to a child of
+ 'log' then there is no need to update 'c'.
+ </para>
+ <para>
+ Otherwise, we set log's parent field to c's parent and set
+ c's parent field to log.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Repository.Hierarchy.Hierarchy.AddLevel(log4net.Repository.Hierarchy.Hierarchy.LevelEntry)">
+ <summary>
+ Define or redefine a Level using the values in the <see cref="T:log4net.Repository.Hierarchy.Hierarchy.LevelEntry"/> argument
+ </summary>
+ <param name="levelEntry">the level values</param>
+ <remarks>
+ <para>
+ Define or redefine a Level using the values in the <see cref="T:log4net.Repository.Hierarchy.Hierarchy.LevelEntry"/> argument
+ </para>
+ <para>
+ Supports setting levels via the configuration file.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Repository.Hierarchy.Hierarchy.AddProperty(log4net.Repository.Hierarchy.Hierarchy.PropertyEntry)">
+ <summary>
+ Set a Property using the values in the <see cref="T:log4net.Repository.Hierarchy.Hierarchy.LevelEntry"/> argument
+ </summary>
+ <param name="propertyEntry">the property value</param>
+ <remarks>
+ <para>
+ Set a Property using the values in the <see cref="T:log4net.Repository.Hierarchy.Hierarchy.LevelEntry"/> argument.
+ </para>
+ <para>
+ Supports setting property values via the configuration file.
+ </para>
+ </remarks>
+ </member>
+ <member name="E:log4net.Repository.Hierarchy.Hierarchy.LoggerCreatedEvent">
+ <summary>
+ Event used to notify that a logger has been created.
+ </summary>
+ <remarks>
+ <para>
+ Event raised when a logger is created.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Repository.Hierarchy.Hierarchy.EmittedNoAppenderWarning">
+ <summary>
+ Has no appender warning been emitted
+ </summary>
+ <remarks>
+ <para>
+ Flag to indicate if we have already issued a warning
+ about not having an appender warning.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Repository.Hierarchy.Hierarchy.Root">
+ <summary>
+ Get the root of this hierarchy
+ </summary>
+ <remarks>
+ <para>
+ Get the root of this hierarchy.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Repository.Hierarchy.Hierarchy.LoggerFactory">
+ <summary>
+ Gets or sets the default <see cref="T:log4net.Repository.Hierarchy.ILoggerFactory"/> instance.
+ </summary>
+ <value>The default <see cref="T:log4net.Repository.Hierarchy.ILoggerFactory"/></value>
+ <remarks>
+ <para>
+ The logger factory is used to create logger instances.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Repository.Hierarchy.Hierarchy.LevelEntry">
+ <summary>
+ A class to hold the value, name and display name for a level
+ </summary>
+ <remarks>
+ <para>
+ A class to hold the value, name and display name for a level
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Repository.Hierarchy.Hierarchy.LevelEntry.ToString">
+ <summary>
+ Override <c>Object.ToString</c> to return sensible debug info
+ </summary>
+ <returns>string info about this object</returns>
+ </member>
+ <member name="P:log4net.Repository.Hierarchy.Hierarchy.LevelEntry.Value">
+ <summary>
+ Value of the level
+ </summary>
+ <remarks>
+ <para>
+ If the value is not set (defaults to -1) the value will be looked
+ up for the current level with the same name.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Repository.Hierarchy.Hierarchy.LevelEntry.Name">
+ <summary>
+ Name of the level
+ </summary>
+ <value>
+ The name of the level
+ </value>
+ <remarks>
+ <para>
+ The name of the level.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Repository.Hierarchy.Hierarchy.LevelEntry.DisplayName">
+ <summary>
+ Display name for the level
+ </summary>
+ <value>
+ The display name of the level
+ </value>
+ <remarks>
+ <para>
+ The display name of the level.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Repository.Hierarchy.Hierarchy.PropertyEntry">
+ <summary>
+ A class to hold the key and data for a property set in the config file
+ </summary>
+ <remarks>
+ <para>
+ A class to hold the key and data for a property set in the config file
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Repository.Hierarchy.Hierarchy.PropertyEntry.ToString">
+ <summary>
+ Override <c>Object.ToString</c> to return sensible debug info
+ </summary>
+ <returns>string info about this object</returns>
+ </member>
+ <member name="P:log4net.Repository.Hierarchy.Hierarchy.PropertyEntry.Key">
+ <summary>
+ Property Key
+ </summary>
+ <value>
+ Property Key
+ </value>
+ <remarks>
+ <para>
+ Property Key.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Repository.Hierarchy.Hierarchy.PropertyEntry.Value">
+ <summary>
+ Property Value
+ </summary>
+ <value>
+ Property Value
+ </value>
+ <remarks>
+ <para>
+ Property Value.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Repository.Hierarchy.LoggerKey">
+ <summary>
+ Used internally to accelerate hash table searches.
+ </summary>
+ <remarks>
+ <para>
+ Internal class used to improve performance of
+ string keyed hashtables.
+ </para>
+ <para>
+ The hashcode of the string is cached for reuse.
+ The string is stored as an interned value.
+ When comparing two <see cref="T:log4net.Repository.Hierarchy.LoggerKey"/> objects for equality
+ the reference equality of the interned strings is compared.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="M:log4net.Repository.Hierarchy.LoggerKey.#ctor(System.String)">
+ <summary>
+ Construct key with string name
+ </summary>
+ <remarks>
+ <para>
+ Initializes a new instance of the <see cref="T:log4net.Repository.Hierarchy.LoggerKey"/> class
+ with the specified name.
+ </para>
+ <para>
+ Stores the hashcode of the string and interns
+ the string key to optimize comparisons.
+ </para>
+ <note>
+ The Compact Framework 1.0 the <see cref="M:System.String.Intern(System.String)"/>
+ method does not work. On the Compact Framework
+ the string keys are not interned nor are they
+ compared by reference.
+ </note>
+ </remarks>
+ <param name="name">The name of the logger.</param>
+ </member>
+ <member name="M:log4net.Repository.Hierarchy.LoggerKey.GetHashCode">
+ <summary>
+ Returns a hash code for the current instance.
+ </summary>
+ <returns>A hash code for the current instance.</returns>
+ <remarks>
+ <para>
+ Returns the cached hashcode.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Repository.Hierarchy.LoggerKey.Equals(System.Object)">
+ <summary>
+ Determines whether two <see cref="T:log4net.Repository.Hierarchy.LoggerKey"/> instances
+ are equal.
+ </summary>
+ <param name="obj">The <see cref="T:System.Object"/> to compare with the current <see cref="T:log4net.Repository.Hierarchy.LoggerKey"/>.</param>
+ <returns>
+ <c>true</c> if the specified <see cref="T:System.Object"/> is equal to the current <see cref="T:log4net.Repository.Hierarchy.LoggerKey"/>; otherwise, <c>false</c>.
+ </returns>
+ <remarks>
+ <para>
+ Compares the references of the interned strings.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Repository.Hierarchy.ProvisionNode">
+ <summary>
+ Provision nodes are used where no logger instance has been specified
+ </summary>
+ <remarks>
+ <para>
+ <see cref="T:log4net.Repository.Hierarchy.ProvisionNode"/> instances are used in the
+ <see cref="T:log4net.Repository.Hierarchy.Hierarchy"/> when there is no specified
+ <see cref="T:log4net.Repository.Hierarchy.Logger"/> for that node.
+ </para>
+ <para>
+ A provision node holds a list of child loggers on behalf of
+ a logger that does not exist.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="M:log4net.Repository.Hierarchy.ProvisionNode.#ctor(log4net.Repository.Hierarchy.Logger)">
+ <summary>
+ Create a new provision node with child node
+ </summary>
+ <param name="log">A child logger to add to this node.</param>
+ <remarks>
+ <para>
+ Initializes a new instance of the <see cref="T:log4net.Repository.Hierarchy.ProvisionNode"/> class
+ with the specified child logger.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Repository.Hierarchy.RootLogger">
+ <summary>
+ The <see cref="T:log4net.Repository.Hierarchy.RootLogger"/> sits at the root of the logger hierarchy tree.
+ </summary>
+ <remarks>
+ <para>
+ The <see cref="T:log4net.Repository.Hierarchy.RootLogger"/> is a regular <see cref="T:log4net.Repository.Hierarchy.Logger"/> except
+ that it provides several guarantees.
+ </para>
+ <para>
+ First, it cannot be assigned a <c>null</c>
+ level. Second, since the root logger cannot have a parent, the
+ <see cref="P:log4net.Repository.Hierarchy.RootLogger.EffectiveLevel"/> property always returns the value of the
+ level field without walking the hierarchy.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="M:log4net.Repository.Hierarchy.RootLogger.#ctor(log4net.Core.Level)">
+ <summary>
+ Construct a <see cref="T:log4net.Repository.Hierarchy.RootLogger"/>
+ </summary>
+ <param name="level">The level to assign to the root logger.</param>
+ <remarks>
+ <para>
+ Initializes a new instance of the <see cref="T:log4net.Repository.Hierarchy.RootLogger"/> class with
+ the specified logging level.
+ </para>
+ <para>
+ The root logger names itself as "root". However, the root
+ logger cannot be retrieved by name.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Repository.Hierarchy.RootLogger.EffectiveLevel">
+ <summary>
+ Gets the assigned level value without walking the logger hierarchy.
+ </summary>
+ <value>The assigned level value without walking the logger hierarchy.</value>
+ <remarks>
+ <para>
+ Because the root logger cannot have a parent and its level
+ must not be <c>null</c> this property just returns the
+ value of <see cref="P:log4net.Repository.Hierarchy.Logger.Level"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Repository.Hierarchy.RootLogger.Level">
+ <summary>
+ Gets or sets the assigned <see cref="P:log4net.Repository.Hierarchy.RootLogger.Level"/> for the root logger.
+ </summary>
+ <value>
+ The <see cref="P:log4net.Repository.Hierarchy.RootLogger.Level"/> of the root logger.
+ </value>
+ <remarks>
+ <para>
+ Setting the level of the root logger to a <c>null</c> reference
+ may have catastrophic results. We prevent this here.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Repository.Hierarchy.XmlHierarchyConfigurator">
+ <summary>
+ Initializes the log4net environment using an XML DOM.
+ </summary>
+ <remarks>
+ <para>
+ Configures a <see cref="T:log4net.Repository.Hierarchy.Hierarchy"/> using an XML DOM.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="M:log4net.Repository.Hierarchy.XmlHierarchyConfigurator.#ctor(log4net.Repository.Hierarchy.Hierarchy)">
+ <summary>
+ Construct the configurator for a hierarchy
+ </summary>
+ <param name="hierarchy">The hierarchy to build.</param>
+ <remarks>
+ <para>
+ Initializes a new instance of the <see cref="T:log4net.Repository.Hierarchy.XmlHierarchyConfigurator"/> class
+ with the specified <see cref="T:log4net.Repository.Hierarchy.Hierarchy"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Repository.Hierarchy.XmlHierarchyConfigurator.Configure(System.Xml.XmlElement)">
+ <summary>
+ Configure the hierarchy by parsing a DOM tree of XML elements.
+ </summary>
+ <param name="element">The root element to parse.</param>
+ <remarks>
+ <para>
+ Configure the hierarchy by parsing a DOM tree of XML elements.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Repository.Hierarchy.XmlHierarchyConfigurator.FindAppenderByReference(System.Xml.XmlElement)">
+ <summary>
+ Parse appenders by IDREF.
+ </summary>
+ <param name="appenderRef">The appender ref element.</param>
+ <returns>The instance of the appender that the ref refers to.</returns>
+ <remarks>
+ <para>
+ Parse an XML element that represents an appender and return
+ the appender.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Repository.Hierarchy.XmlHierarchyConfigurator.ParseAppender(System.Xml.XmlElement)">
+ <summary>
+ Parses an appender element.
+ </summary>
+ <param name="appenderElement">The appender element.</param>
+ <returns>The appender instance or <c>null</c> when parsing failed.</returns>
+ <remarks>
+ <para>
+ Parse an XML element that represents an appender and return
+ the appender instance.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Repository.Hierarchy.XmlHierarchyConfigurator.ParseLogger(System.Xml.XmlElement)">
+ <summary>
+ Parses a logger element.
+ </summary>
+ <param name="loggerElement">The logger element.</param>
+ <remarks>
+ <para>
+ Parse an XML element that represents a logger.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Repository.Hierarchy.XmlHierarchyConfigurator.ParseRoot(System.Xml.XmlElement)">
+ <summary>
+ Parses the root logger element.
+ </summary>
+ <param name="rootElement">The root element.</param>
+ <remarks>
+ <para>
+ Parse an XML element that represents the root logger.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Repository.Hierarchy.XmlHierarchyConfigurator.ParseChildrenOfLoggerElement(System.Xml.XmlElement,log4net.Repository.Hierarchy.Logger,System.Boolean)">
+ <summary>
+ Parses the children of a logger element.
+ </summary>
+ <param name="catElement">The category element.</param>
+ <param name="log">The logger instance.</param>
+ <param name="isRoot">Flag to indicate if the logger is the root logger.</param>
+ <remarks>
+ <para>
+ Parse the child elements of a &lt;logger&gt; element.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Repository.Hierarchy.XmlHierarchyConfigurator.ParseRenderer(System.Xml.XmlElement)">
+ <summary>
+ Parses an object renderer.
+ </summary>
+ <param name="element">The renderer element.</param>
+ <remarks>
+ <para>
+ Parse an XML element that represents a renderer.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Repository.Hierarchy.XmlHierarchyConfigurator.ParseLevel(System.Xml.XmlElement,log4net.Repository.Hierarchy.Logger,System.Boolean)">
+ <summary>
+ Parses a level element.
+ </summary>
+ <param name="element">The level element.</param>
+ <param name="log">The logger object to set the level on.</param>
+ <param name="isRoot">Flag to indicate if the logger is the root logger.</param>
+ <remarks>
+ <para>
+ Parse an XML element that represents a level.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Repository.Hierarchy.XmlHierarchyConfigurator.SetParameter(System.Xml.XmlElement,System.Object)">
+ <summary>
+ Sets a parameter on an object.
+ </summary>
+ <param name="element">The parameter element.</param>
+ <param name="target">The object to set the parameter on.</param>
+ <remarks>
+ The parameter name must correspond to a writable property
+ on the object. The value of the parameter is a string,
+ therefore this function will attempt to set a string
+ property first. If unable to set a string property it
+ will inspect the property and its argument type. It will
+ attempt to call a static method called <c>Parse</c> on the
+ type of the property. This method will take a single
+ string argument and return a value that can be used to
+ set the property.
+ </remarks>
+ </member>
+ <member name="M:log4net.Repository.Hierarchy.XmlHierarchyConfigurator.HasAttributesOrElements(System.Xml.XmlElement)">
+ <summary>
+ Test if an element has no attributes or child elements
+ </summary>
+ <param name="element">the element to inspect</param>
+ <returns><c>true</c> if the element has any attributes or child elements, <c>false</c> otherwise</returns>
+ </member>
+ <member name="M:log4net.Repository.Hierarchy.XmlHierarchyConfigurator.IsTypeConstructible(System.Type)">
+ <summary>
+ Test if a <see cref="T:System.Type"/> is constructible with <c>Activator.CreateInstance</c>.
+ </summary>
+ <param name="type">the type to inspect</param>
+ <returns><c>true</c> if the type is creatable using a default constructor, <c>false</c> otherwise</returns>
+ </member>
+ <member name="M:log4net.Repository.Hierarchy.XmlHierarchyConfigurator.FindMethodInfo(System.Type,System.String)">
+ <summary>
+ Look for a method on the <paramref name="targetType"/> that matches the <paramref name="name"/> supplied
+ </summary>
+ <param name="targetType">the type that has the method</param>
+ <param name="name">the name of the method</param>
+ <returns>the method info found</returns>
+ <remarks>
+ <para>
+ The method must be a public instance method on the <paramref name="targetType"/>.
+ The method must be named <paramref name="name"/> or "Add" followed by <paramref name="name"/>.
+ The method must take a single parameter.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Repository.Hierarchy.XmlHierarchyConfigurator.ConvertStringTo(System.Type,System.String)">
+ <summary>
+ Converts a string value to a target type.
+ </summary>
+ <param name="type">The type of object to convert the string to.</param>
+ <param name="value">The string value to use as the value of the object.</param>
+ <returns>
+ <para>
+ An object of type <paramref name="type"/> with value <paramref name="value"/> or
+ <c>null</c> when the conversion could not be performed.
+ </para>
+ </returns>
+ </member>
+ <member name="M:log4net.Repository.Hierarchy.XmlHierarchyConfigurator.CreateObjectFromXml(System.Xml.XmlElement,System.Type,System.Type)">
+ <summary>
+ Creates an object as specified in XML.
+ </summary>
+ <param name="element">The XML element that contains the definition of the object.</param>
+ <param name="defaultTargetType">The object type to use if not explicitly specified.</param>
+ <param name="typeConstraint">The type that the returned object must be or must inherit from.</param>
+ <returns>The object or <c>null</c></returns>
+ <remarks>
+ <para>
+ Parse an XML element and create an object instance based on the configuration
+ data.
+ </para>
+ <para>
+ The type of the instance may be specified in the XML. If not
+ specified then the <paramref name="defaultTargetType"/> is used
+ as the type. However the type is specified it must support the
+ <paramref name="typeConstraint"/> type.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Repository.Hierarchy.XmlHierarchyConfigurator.m_appenderBag">
+ <summary>
+ key: appenderName, value: appender.
+ </summary>
+ </member>
+ <member name="F:log4net.Repository.Hierarchy.XmlHierarchyConfigurator.m_hierarchy">
+ <summary>
+ The Hierarchy being configured.
+ </summary>
+ </member>
+ <member name="T:log4net.Repository.LoggerRepositoryShutdownEventHandler">
+ <summary>
+ Delegate used to handle logger repository shutdown event notifications
+ </summary>
+ <param name="sender">The <see cref="T:log4net.Repository.ILoggerRepository"/> that is shutting down.</param>
+ <param name="e">Empty event args</param>
+ <remarks>
+ <para>
+ Delegate used to handle logger repository shutdown event notifications.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Repository.LoggerRepositoryConfigurationResetEventHandler">
+ <summary>
+ Delegate used to handle logger repository configuration reset event notifications
+ </summary>
+ <param name="sender">The <see cref="T:log4net.Repository.ILoggerRepository"/> that has had its configuration reset.</param>
+ <param name="e">Empty event args</param>
+ <remarks>
+ <para>
+ Delegate used to handle logger repository configuration reset event notifications.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Repository.LoggerRepositoryConfigurationChangedEventHandler">
+ <summary>
+ Delegate used to handle event notifications for logger repository configuration changes.
+ </summary>
+ <param name="sender">The <see cref="T:log4net.Repository.ILoggerRepository"/> that has had its configuration changed.</param>
+ <param name="e">Empty event arguments.</param>
+ <remarks>
+ <para>
+ Delegate used to handle event notifications for logger repository configuration changes.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Util.PatternStringConverters.AppDomainPatternConverter">
+ <summary>
+ Write the name of the current AppDomain to the output
+ </summary>
+ <remarks>
+ <para>
+ Write the name of the current AppDomain to the output writer
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="M:log4net.Util.PatternStringConverters.AppDomainPatternConverter.Convert(System.IO.TextWriter,System.Object)">
+ <summary>
+ Write the name of the current AppDomain to the output
+ </summary>
+ <param name="writer">the writer to write to</param>
+ <param name="state">null, state is not set</param>
+ <remarks>
+ <para>
+ Writes name of the current AppDomain to the output <paramref name="writer"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Util.PatternStringConverters.DatePatternConverter">
+ <summary>
+ Write the current date to the output
+ </summary>
+ <remarks>
+ <para>
+ Date pattern converter, uses a <see cref="T:log4net.DateFormatter.IDateFormatter"/> to format
+ the current date and time to the writer as a string.
+ </para>
+ <para>
+ The value of the <see cref="P:log4net.Util.PatternConverter.Option"/> determines
+ the formatting of the date. The following values are allowed:
+ <list type="definition">
+ <listheader>
+ <term>Option value</term>
+ <description>Output</description>
+ </listheader>
+ <item>
+ <term>ISO8601</term>
+ <description>
+ Uses the <see cref="T:log4net.DateFormatter.Iso8601DateFormatter"/> formatter.
+ Formats using the <c>"yyyy-MM-dd HH:mm:ss,fff"</c> pattern.
+ </description>
+ </item>
+ <item>
+ <term>DATE</term>
+ <description>
+ Uses the <see cref="T:log4net.DateFormatter.DateTimeDateFormatter"/> formatter.
+ Formats using the <c>"dd MMM yyyy HH:mm:ss,fff"</c> for example, <c>"06 Nov 1994 15:49:37,459"</c>.
+ </description>
+ </item>
+ <item>
+ <term>ABSOLUTE</term>
+ <description>
+ Uses the <see cref="T:log4net.DateFormatter.AbsoluteTimeDateFormatter"/> formatter.
+ Formats using the <c>"HH:mm:ss,fff"</c> for example, <c>"15:49:37,459"</c>.
+ </description>
+ </item>
+ <item>
+ <term>other</term>
+ <description>
+ Any other pattern string uses the <see cref="T:log4net.DateFormatter.SimpleDateFormatter"/> formatter.
+ This formatter passes the pattern string to the <see cref="T:System.DateTime"/>
+ <see cref="M:System.DateTime.ToString(System.String)"/> method.
+ For details on valid patterns see
+ <a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfsystemglobalizationdatetimeformatinfoclasstopic.asp">DateTimeFormatInfo Class</a>.
+ </description>
+ </item>
+ </list>
+ </para>
+ <para>
+ The date and time is in the local time zone and is rendered in that zone.
+ To output the time in Universal time see <see cref="T:log4net.Util.PatternStringConverters.UtcDatePatternConverter"/>.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="F:log4net.Util.PatternStringConverters.DatePatternConverter.m_dateFormatter">
+ <summary>
+ The <see cref="T:log4net.DateFormatter.IDateFormatter"/> used to render the date to a string
+ </summary>
+ <remarks>
+ <para>
+ The <see cref="T:log4net.DateFormatter.IDateFormatter"/> used to render the date to a string
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.PatternStringConverters.DatePatternConverter.ActivateOptions">
+ <summary>
+ Initialize the converter options
+ </summary>
+ <remarks>
+ <para>
+ This is part of the <see cref="T:log4net.Core.IOptionHandler"/> delayed object
+ activation scheme. The <see cref="M:log4net.Util.PatternStringConverters.DatePatternConverter.ActivateOptions"/> method must
+ be called on this object after the configuration properties have
+ been set. Until <see cref="M:log4net.Util.PatternStringConverters.DatePatternConverter.ActivateOptions"/> is called this
+ object is in an undefined state and must not be used.
+ </para>
+ <para>
+ If any of the configuration properties are modified then
+ <see cref="M:log4net.Util.PatternStringConverters.DatePatternConverter.ActivateOptions"/> must be called again.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.PatternStringConverters.DatePatternConverter.Convert(System.IO.TextWriter,System.Object)">
+ <summary>
+ Write the current date to the output
+ </summary>
+ <param name="writer"><see cref="T:System.IO.TextWriter"/> that will receive the formatted result.</param>
+ <param name="state">null, state is not set</param>
+ <remarks>
+ <para>
+ Pass the current date and time to the <see cref="T:log4net.DateFormatter.IDateFormatter"/>
+ for it to render it to the writer.
+ </para>
+ <para>
+ The date and time passed is in the local time zone.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Util.PatternStringConverters.EnvironmentPatternConverter">
+ <summary>
+ Write an environment variable to the output
+ </summary>
+ <remarks>
+ <para>
+ Write an environment variable to the output writer.
+ The value of the <see cref="P:log4net.Util.PatternConverter.Option"/> determines
+ the name of the variable to output.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="M:log4net.Util.PatternStringConverters.EnvironmentPatternConverter.Convert(System.IO.TextWriter,System.Object)">
+ <summary>
+ Write an environment variable to the output
+ </summary>
+ <param name="writer">the writer to write to</param>
+ <param name="state">null, state is not set</param>
+ <remarks>
+ <para>
+ Writes the environment variable to the output <paramref name="writer"/>.
+ The name of the environment variable to output must be set
+ using the <see cref="P:log4net.Util.PatternConverter.Option"/>
+ property.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Util.PatternStringConverters.IdentityPatternConverter">
+ <summary>
+ Write the current thread identity to the output
+ </summary>
+ <remarks>
+ <para>
+ Write the current thread identity to the output writer
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="M:log4net.Util.PatternStringConverters.IdentityPatternConverter.Convert(System.IO.TextWriter,System.Object)">
+ <summary>
+ Write the current thread identity to the output
+ </summary>
+ <param name="writer">the writer to write to</param>
+ <param name="state">null, state is not set</param>
+ <remarks>
+ <para>
+ Writes the current thread identity to the output <paramref name="writer"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Util.PatternStringConverters.LiteralPatternConverter">
+ <summary>
+ Pattern converter for literal string instances in the pattern
+ </summary>
+ <remarks>
+ <para>
+ Writes the literal string value specified in the
+ <see cref="P:log4net.Util.PatternConverter.Option"/> property to
+ the output.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="M:log4net.Util.PatternStringConverters.LiteralPatternConverter.SetNext(log4net.Util.PatternConverter)">
+ <summary>
+ Set the next converter in the chain
+ </summary>
+ <param name="pc">The next pattern converter in the chain</param>
+ <returns>The next pattern converter</returns>
+ <remarks>
+ <para>
+ Special case the building of the pattern converter chain
+ for <see cref="T:log4net.Util.PatternStringConverters.LiteralPatternConverter"/> instances. Two adjacent
+ literals in the pattern can be represented by a single combined
+ pattern converter. This implementation detects when a
+ <see cref="T:log4net.Util.PatternStringConverters.LiteralPatternConverter"/> is added to the chain
+ after this converter and combines its value with this converter's
+ literal value.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.PatternStringConverters.LiteralPatternConverter.Format(System.IO.TextWriter,System.Object)">
+ <summary>
+ Write the literal to the output
+ </summary>
+ <param name="writer">the writer to write to</param>
+ <param name="state">null, not set</param>
+ <remarks>
+ <para>
+ Override the formatting behavior to ignore the FormattingInfo
+ because we have a literal instead.
+ </para>
+ <para>
+ Writes the value of <see cref="P:log4net.Util.PatternConverter.Option"/>
+ to the output <paramref name="writer"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.PatternStringConverters.LiteralPatternConverter.Convert(System.IO.TextWriter,System.Object)">
+ <summary>
+ Convert this pattern into the rendered message
+ </summary>
+ <param name="writer"><see cref="T:System.IO.TextWriter"/> that will receive the formatted result.</param>
+ <param name="state">null, not set</param>
+ <remarks>
+ <para>
+ This method is not used.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Util.PatternStringConverters.NewLinePatternConverter">
+ <summary>
+ Writes a newline to the output
+ </summary>
+ <remarks>
+ <para>
+ Writes the system dependent line terminator to the output.
+ This behavior can be overridden by setting the <see cref="P:log4net.Util.PatternConverter.Option"/>:
+ </para>
+ <list type="definition">
+ <listheader>
+ <term>Option Value</term>
+ <description>Output</description>
+ </listheader>
+ <item>
+ <term>DOS</term>
+ <description>DOS or Windows line terminator <c>"\r\n"</c></description>
+ </item>
+ <item>
+ <term>UNIX</term>
+ <description>UNIX line terminator <c>"\n"</c></description>
+ </item>
+ </list>
+ </remarks>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="M:log4net.Util.PatternStringConverters.NewLinePatternConverter.ActivateOptions">
+ <summary>
+ Initialize the converter
+ </summary>
+ <remarks>
+ <para>
+ This is part of the <see cref="T:log4net.Core.IOptionHandler"/> delayed object
+ activation scheme. The <see cref="M:log4net.Util.PatternStringConverters.NewLinePatternConverter.ActivateOptions"/> method must
+ be called on this object after the configuration properties have
+ been set. Until <see cref="M:log4net.Util.PatternStringConverters.NewLinePatternConverter.ActivateOptions"/> is called this
+ object is in an undefined state and must not be used.
+ </para>
+ <para>
+ If any of the configuration properties are modified then
+ <see cref="M:log4net.Util.PatternStringConverters.NewLinePatternConverter.ActivateOptions"/> must be called again.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Util.PatternStringConverters.ProcessIdPatternConverter">
+ <summary>
+ Write the current process ID to the output
+ </summary>
+ <remarks>
+ <para>
+ Write the current process ID to the output writer
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="M:log4net.Util.PatternStringConverters.ProcessIdPatternConverter.Convert(System.IO.TextWriter,System.Object)">
+ <summary>
+ Write the current process ID to the output
+ </summary>
+ <param name="writer">the writer to write to</param>
+ <param name="state">null, state is not set</param>
+ <remarks>
+ <para>
+ Write the current process ID to the output <paramref name="writer"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Util.PatternStringConverters.PropertyPatternConverter">
+ <summary>
+ Property pattern converter
+ </summary>
+ <remarks>
+ <para>
+ This pattern converter reads the thread and global properties.
+ The thread properties take priority over global properties.
+ See <see cref="P:log4net.ThreadContext.Properties"/> for details of the
+ thread properties. See <see cref="P:log4net.GlobalContext.Properties"/> for
+ details of the global properties.
+ </para>
+ <para>
+ If the <see cref="P:log4net.Util.PatternConverter.Option"/> is specified then that will be used to
+ lookup a single property. If no <see cref="P:log4net.Util.PatternConverter.Option"/> is specified
+ then all properties will be dumped as a list of key value pairs.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="M:log4net.Util.PatternStringConverters.PropertyPatternConverter.Convert(System.IO.TextWriter,System.Object)">
+ <summary>
+ Write the property value to the output
+ </summary>
+ <param name="writer"><see cref="T:System.IO.TextWriter"/> that will receive the formatted result.</param>
+ <param name="state">null, state is not set</param>
+ <remarks>
+ <para>
+ Writes out the value of a named property. The property name
+ should be set in the <see cref="P:log4net.Util.PatternConverter.Option"/>
+ property.
+ </para>
+ <para>
+ If the <see cref="P:log4net.Util.PatternConverter.Option"/> is set to <c>null</c>
+ then all the properties are written as key value pairs.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Util.PatternStringConverters.RandomStringPatternConverter">
+ <summary>
+ A Pattern converter that generates a string of random characters
+ </summary>
+ <remarks>
+ <para>
+ The converter generates a string of random characters. By default
+ the string is length 4. This can be changed by setting the <see cref="P:log4net.Util.PatternConverter.Option"/>
+ to the string value of the length required.
+ </para>
+ <para>
+ The random characters in the string are limited to uppercase letters
+ and numbers only.
+ </para>
+ <para>
+ The random number generator used by this class is not cryptographically secure.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="F:log4net.Util.PatternStringConverters.RandomStringPatternConverter.s_random">
+ <summary>
+ Shared random number generator
+ </summary>
+ </member>
+ <member name="F:log4net.Util.PatternStringConverters.RandomStringPatternConverter.m_length">
+ <summary>
+ Length of random string to generate. Default length 4.
+ </summary>
+ </member>
+ <member name="M:log4net.Util.PatternStringConverters.RandomStringPatternConverter.ActivateOptions">
+ <summary>
+ Initialize the converter options
+ </summary>
+ <remarks>
+ <para>
+ This is part of the <see cref="T:log4net.Core.IOptionHandler"/> delayed object
+ activation scheme. The <see cref="M:log4net.Util.PatternStringConverters.RandomStringPatternConverter.ActivateOptions"/> method must
+ be called on this object after the configuration properties have
+ been set. Until <see cref="M:log4net.Util.PatternStringConverters.RandomStringPatternConverter.ActivateOptions"/> is called this
+ object is in an undefined state and must not be used.
+ </para>
+ <para>
+ If any of the configuration properties are modified then
+ <see cref="M:log4net.Util.PatternStringConverters.RandomStringPatternConverter.ActivateOptions"/> must be called again.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.PatternStringConverters.RandomStringPatternConverter.Convert(System.IO.TextWriter,System.Object)">
+ <summary>
+ Write a randoim string to the output
+ </summary>
+ <param name="writer">the writer to write to</param>
+ <param name="state">null, state is not set</param>
+ <remarks>
+ <para>
+ Write a randoim string to the output <paramref name="writer"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Util.PatternStringConverters.UserNamePatternConverter">
+ <summary>
+ Write the current threads username to the output
+ </summary>
+ <remarks>
+ <para>
+ Write the current threads username to the output writer
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="M:log4net.Util.PatternStringConverters.UserNamePatternConverter.Convert(System.IO.TextWriter,System.Object)">
+ <summary>
+ Write the current threads username to the output
+ </summary>
+ <param name="writer">the writer to write to</param>
+ <param name="state">null, state is not set</param>
+ <remarks>
+ <para>
+ Write the current threads username to the output <paramref name="writer"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Util.PatternStringConverters.UtcDatePatternConverter">
+ <summary>
+ Write the UTC date time to the output
+ </summary>
+ <remarks>
+ <para>
+ Date pattern converter, uses a <see cref="T:log4net.DateFormatter.IDateFormatter"/> to format
+ the current date and time in Universal time.
+ </para>
+ <para>
+ See the <see cref="T:log4net.Util.PatternStringConverters.DatePatternConverter"/> for details on the date pattern syntax.
+ </para>
+ </remarks>
+ <seealso cref="T:log4net.Util.PatternStringConverters.DatePatternConverter"/>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="M:log4net.Util.PatternStringConverters.UtcDatePatternConverter.Convert(System.IO.TextWriter,System.Object)">
+ <summary>
+ Write the current date and time to the output
+ </summary>
+ <param name="writer"><see cref="T:System.IO.TextWriter"/> that will receive the formatted result.</param>
+ <param name="state">null, state is not set</param>
+ <remarks>
+ <para>
+ Pass the current date and time to the <see cref="T:log4net.DateFormatter.IDateFormatter"/>
+ for it to render it to the writer.
+ </para>
+ <para>
+ The date is in Universal time when it is rendered.
+ </para>
+ </remarks>
+ <seealso cref="T:log4net.Util.PatternStringConverters.DatePatternConverter"/>
+ </member>
+ <member name="T:log4net.Util.TypeConverters.BooleanConverter">
+ <summary>
+ Type converter for Boolean.
+ </summary>
+ <remarks>
+ <para>
+ Supports conversion from string to <c>bool</c> type.
+ </para>
+ </remarks>
+ <seealso cref="T:log4net.Util.TypeConverters.ConverterRegistry"/>
+ <seealso cref="T:log4net.Util.TypeConverters.IConvertFrom"/>
+ <seealso cref="T:log4net.Util.TypeConverters.IConvertTo"/>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="M:log4net.Util.TypeConverters.BooleanConverter.CanConvertFrom(System.Type)">
+ <summary>
+ Can the source type be converted to the type supported by this object
+ </summary>
+ <param name="sourceType">the type to convert</param>
+ <returns>true if the conversion is possible</returns>
+ <remarks>
+ <para>
+ Returns <c>true</c> if the <paramref name="sourceType"/> is
+ the <see cref="T:System.String"/> type.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.TypeConverters.BooleanConverter.ConvertFrom(System.Object)">
+ <summary>
+ Convert the source object to the type supported by this object
+ </summary>
+ <param name="source">the object to convert</param>
+ <returns>the converted object</returns>
+ <remarks>
+ <para>
+ Uses the <see cref="M:System.Boolean.Parse(System.String)"/> method to convert the
+ <see cref="T:System.String"/> argument to a <see cref="T:System.Boolean"/>.
+ </para>
+ </remarks>
+ <exception cref="T:log4net.Util.TypeConverters.ConversionNotSupportedException">
+ The <paramref name="source"/> object cannot be converted to the
+ target type. To check for this condition use the <see cref="M:log4net.Util.TypeConverters.BooleanConverter.CanConvertFrom(System.Type)"/>
+ method.
+ </exception>
+ </member>
+ <member name="T:log4net.Util.TypeConverters.ConversionNotSupportedException">
+ <summary>
+ Exception base type for conversion errors.
+ </summary>
+ <remarks>
+ <para>
+ This type extends <see cref="T:System.ApplicationException"/>. It
+ does not add any new functionality but does differentiate the
+ type of exception being thrown.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="M:log4net.Util.TypeConverters.ConversionNotSupportedException.#ctor">
+ <summary>
+ Constructor
+ </summary>
+ <remarks>
+ <para>
+ Initializes a new instance of the <see cref="T:log4net.Util.TypeConverters.ConversionNotSupportedException"/> class.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.TypeConverters.ConversionNotSupportedException.#ctor(System.String)">
+ <summary>
+ Constructor
+ </summary>
+ <param name="message">A message to include with the exception.</param>
+ <remarks>
+ <para>
+ Initializes a new instance of the <see cref="T:log4net.Util.TypeConverters.ConversionNotSupportedException"/> class
+ with the specified message.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.TypeConverters.ConversionNotSupportedException.#ctor(System.String,System.Exception)">
+ <summary>
+ Constructor
+ </summary>
+ <param name="message">A message to include with the exception.</param>
+ <param name="innerException">A nested exception to include.</param>
+ <remarks>
+ <para>
+ Initializes a new instance of the <see cref="T:log4net.Util.TypeConverters.ConversionNotSupportedException"/> class
+ with the specified message and inner exception.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.TypeConverters.ConversionNotSupportedException.#ctor(System.Runtime.Serialization.SerializationInfo,System.Runtime.Serialization.StreamingContext)">
+ <summary>
+ Serialization constructor
+ </summary>
+ <param name="info">The <see cref="T:System.Runtime.Serialization.SerializationInfo"/> that holds the serialized object data about the exception being thrown.</param>
+ <param name="context">The <see cref="T:System.Runtime.Serialization.StreamingContext"/> that contains contextual information about the source or destination.</param>
+ <remarks>
+ <para>
+ Initializes a new instance of the <see cref="T:log4net.Util.TypeConverters.ConversionNotSupportedException"/> class
+ with serialized data.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.TypeConverters.ConversionNotSupportedException.Create(System.Type,System.Object)">
+ <summary>
+ Creates a new instance of the <see cref="T:log4net.Util.TypeConverters.ConversionNotSupportedException"/> class.
+ </summary>
+ <param name="destinationType">The conversion destination type.</param>
+ <param name="sourceValue">The value to convert.</param>
+ <returns>An instance of the <see cref="T:log4net.Util.TypeConverters.ConversionNotSupportedException"/>.</returns>
+ <remarks>
+ <para>
+ Creates a new instance of the <see cref="T:log4net.Util.TypeConverters.ConversionNotSupportedException"/> class.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.TypeConverters.ConversionNotSupportedException.Create(System.Type,System.Object,System.Exception)">
+ <summary>
+ Creates a new instance of the <see cref="T:log4net.Util.TypeConverters.ConversionNotSupportedException"/> class.
+ </summary>
+ <param name="destinationType">The conversion destination type.</param>
+ <param name="sourceValue">The value to convert.</param>
+ <param name="innerException">A nested exception to include.</param>
+ <returns>An instance of the <see cref="T:log4net.Util.TypeConverters.ConversionNotSupportedException"/>.</returns>
+ <remarks>
+ <para>
+ Creates a new instance of the <see cref="T:log4net.Util.TypeConverters.ConversionNotSupportedException"/> class.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Util.TypeConverters.ConverterRegistry">
+ <summary>
+ Register of type converters for specific types.
+ </summary>
+ <remarks>
+ <para>
+ Maintains a registry of type converters used to convert between
+ types.
+ </para>
+ <para>
+ Use the <see cref="M:log4net.Util.TypeConverters.ConverterRegistry.AddConverter(System.Type,System.Object)"/> and
+ <see cref="M:log4net.Util.TypeConverters.ConverterRegistry.AddConverter(System.Type,System.Type)"/> methods to register new converters.
+ The <see cref="M:log4net.Util.TypeConverters.ConverterRegistry.GetConvertTo(System.Type,System.Type)"/> and <see cref="M:log4net.Util.TypeConverters.ConverterRegistry.GetConvertFrom(System.Type)"/> methods
+ lookup appropriate converters to use.
+ </para>
+ </remarks>
+ <seealso cref="T:log4net.Util.TypeConverters.IConvertFrom"/>
+ <seealso cref="T:log4net.Util.TypeConverters.IConvertTo"/>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="M:log4net.Util.TypeConverters.ConverterRegistry.#ctor">
+ <summary>
+ Private constructor
+ </summary>
+ <remarks>
+ Initializes a new instance of the <see cref="T:log4net.Util.TypeConverters.ConverterRegistry"/> class.
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.TypeConverters.ConverterRegistry.#cctor">
+ <summary>
+ Static constructor.
+ </summary>
+ <remarks>
+ <para>
+ This constructor defines the intrinsic type converters.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.TypeConverters.ConverterRegistry.AddConverter(System.Type,System.Object)">
+ <summary>
+ Adds a converter for a specific type.
+ </summary>
+ <param name="destinationType">The type being converted to.</param>
+ <param name="converter">The type converter to use to convert to the destination type.</param>
+ <remarks>
+ <para>
+ Adds a converter instance for a specific type.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.TypeConverters.ConverterRegistry.AddConverter(System.Type,System.Type)">
+ <summary>
+ Adds a converter for a specific type.
+ </summary>
+ <param name="destinationType">The type being converted to.</param>
+ <param name="converterType">The type of the type converter to use to convert to the destination type.</param>
+ <remarks>
+ <para>
+ Adds a converter <see cref="T:System.Type"/> for a specific type.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.TypeConverters.ConverterRegistry.GetConvertTo(System.Type,System.Type)">
+ <summary>
+ Gets the type converter to use to convert values to the destination type.
+ </summary>
+ <param name="sourceType">The type being converted from.</param>
+ <param name="destinationType">The type being converted to.</param>
+ <returns>
+ The type converter instance to use for type conversions or <c>null</c>
+ if no type converter is found.
+ </returns>
+ <remarks>
+ <para>
+ Gets the type converter to use to convert values to the destination type.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.TypeConverters.ConverterRegistry.GetConvertFrom(System.Type)">
+ <summary>
+ Gets the type converter to use to convert values to the destination type.
+ </summary>
+ <param name="destinationType">The type being converted to.</param>
+ <returns>
+ The type converter instance to use for type conversions or <c>null</c>
+ if no type converter is found.
+ </returns>
+ <remarks>
+ <para>
+ Gets the type converter to use to convert values to the destination type.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.TypeConverters.ConverterRegistry.GetConverterFromAttribute(System.Type)">
+ <summary>
+ Lookups the type converter to use as specified by the attributes on the
+ destination type.
+ </summary>
+ <param name="destinationType">The type being converted to.</param>
+ <returns>
+ The type converter instance to use for type conversions or <c>null</c>
+ if no type converter is found.
+ </returns>
+ </member>
+ <member name="M:log4net.Util.TypeConverters.ConverterRegistry.CreateConverterInstance(System.Type)">
+ <summary>
+ Creates the instance of the type converter.
+ </summary>
+ <param name="converterType">The type of the type converter.</param>
+ <returns>
+ The type converter instance to use for type conversions or <c>null</c>
+ if no type converter is found.
+ </returns>
+ <remarks>
+ <para>
+ The type specified for the type converter must implement
+ the <see cref="T:log4net.Util.TypeConverters.IConvertFrom"/> or <see cref="T:log4net.Util.TypeConverters.IConvertTo"/> interfaces
+ and must have a public default (no argument) constructor.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Util.TypeConverters.ConverterRegistry.s_type2converter">
+ <summary>
+ Mapping from <see cref="T:System.Type"/> to type converter.
+ </summary>
+ </member>
+ <member name="T:log4net.Util.TypeConverters.EncodingConverter">
+ <summary>
+ Supports conversion from string to <see cref="T:System.Text.Encoding"/> type.
+ </summary>
+ <remarks>
+ <para>
+ Supports conversion from string to <see cref="T:System.Text.Encoding"/> type.
+ </para>
+ </remarks>
+ <seealso cref="T:log4net.Util.TypeConverters.ConverterRegistry"/>
+ <seealso cref="T:log4net.Util.TypeConverters.IConvertFrom"/>
+ <seealso cref="T:log4net.Util.TypeConverters.IConvertTo"/>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="M:log4net.Util.TypeConverters.EncodingConverter.CanConvertFrom(System.Type)">
+ <summary>
+ Can the source type be converted to the type supported by this object
+ </summary>
+ <param name="sourceType">the type to convert</param>
+ <returns>true if the conversion is possible</returns>
+ <remarks>
+ <para>
+ Returns <c>true</c> if the <paramref name="sourceType"/> is
+ the <see cref="T:System.String"/> type.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.TypeConverters.EncodingConverter.ConvertFrom(System.Object)">
+ <summary>
+ Overrides the ConvertFrom method of IConvertFrom.
+ </summary>
+ <param name="source">the object to convert to an encoding</param>
+ <returns>the encoding</returns>
+ <remarks>
+ <para>
+ Uses the <see cref="M:System.Text.Encoding.GetEncoding(System.String)"/> method to
+ convert the <see cref="T:System.String"/> argument to an <see cref="T:System.Text.Encoding"/>.
+ </para>
+ </remarks>
+ <exception cref="T:log4net.Util.TypeConverters.ConversionNotSupportedException">
+ The <paramref name="source"/> object cannot be converted to the
+ target type. To check for this condition use the <see cref="M:log4net.Util.TypeConverters.EncodingConverter.CanConvertFrom(System.Type)"/>
+ method.
+ </exception>
+ </member>
+ <member name="T:log4net.Util.TypeConverters.IConvertTo">
+ <summary>
+ Interface supported by type converters
+ </summary>
+ <remarks>
+ <para>
+ This interface supports conversion from a single type to arbitrary types.
+ See <see cref="T:log4net.Util.TypeConverters.TypeConverterAttribute"/>.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="M:log4net.Util.TypeConverters.IConvertTo.CanConvertTo(System.Type)">
+ <summary>
+ Returns whether this converter can convert the object to the specified type
+ </summary>
+ <param name="targetType">A Type that represents the type you want to convert to</param>
+ <returns>true if the conversion is possible</returns>
+ <remarks>
+ <para>
+ Test if the type supported by this converter can be converted to the
+ <paramref name="targetType"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.TypeConverters.IConvertTo.ConvertTo(System.Object,System.Type)">
+ <summary>
+ Converts the given value object to the specified type, using the arguments
+ </summary>
+ <param name="source">the object to convert</param>
+ <param name="targetType">The Type to convert the value parameter to</param>
+ <returns>the converted object</returns>
+ <remarks>
+ <para>
+ Converts the <paramref name="source"/> (which must be of the type supported
+ by this converter) to the <paramref name="targetType"/> specified..
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Util.TypeConverters.IPAddressConverter">
+ <summary>
+ Supports conversion from string to <see cref="T:System.Net.IPAddress"/> type.
+ </summary>
+ <remarks>
+ <para>
+ Supports conversion from string to <see cref="T:System.Net.IPAddress"/> type.
+ </para>
+ </remarks>
+ <seealso cref="T:log4net.Util.TypeConverters.ConverterRegistry"/>
+ <seealso cref="T:log4net.Util.TypeConverters.IConvertFrom"/>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="M:log4net.Util.TypeConverters.IPAddressConverter.CanConvertFrom(System.Type)">
+ <summary>
+ Can the source type be converted to the type supported by this object
+ </summary>
+ <param name="sourceType">the type to convert</param>
+ <returns>true if the conversion is possible</returns>
+ <remarks>
+ <para>
+ Returns <c>true</c> if the <paramref name="sourceType"/> is
+ the <see cref="T:System.String"/> type.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.TypeConverters.IPAddressConverter.ConvertFrom(System.Object)">
+ <summary>
+ Overrides the ConvertFrom method of IConvertFrom.
+ </summary>
+ <param name="source">the object to convert to an IPAddress</param>
+ <returns>the IPAddress</returns>
+ <remarks>
+ <para>
+ Uses the <see cref="M:System.Net.IPAddress.Parse(System.String)"/> method to convert the
+ <see cref="T:System.String"/> argument to an <see cref="T:System.Net.IPAddress"/>.
+ If that fails then the string is resolved as a DNS hostname.
+ </para>
+ </remarks>
+ <exception cref="T:log4net.Util.TypeConverters.ConversionNotSupportedException">
+ The <paramref name="source"/> object cannot be converted to the
+ target type. To check for this condition use the <see cref="M:log4net.Util.TypeConverters.IPAddressConverter.CanConvertFrom(System.Type)"/>
+ method.
+ </exception>
+ </member>
+ <member name="F:log4net.Util.TypeConverters.IPAddressConverter.validIpAddressChars">
+ <summary>
+ Valid characters in an IPv4 or IPv6 address string. (Does not support subnets)
+ </summary>
+ </member>
+ <member name="T:log4net.Util.TypeConverters.PatternLayoutConverter">
+ <summary>
+ Supports conversion from string to <see cref="T:log4net.Layout.PatternLayout"/> type.
+ </summary>
+ <remarks>
+ <para>
+ Supports conversion from string to <see cref="T:log4net.Layout.PatternLayout"/> type.
+ </para>
+ <para>
+ The string is used as the <see cref="P:log4net.Layout.PatternLayout.ConversionPattern"/>
+ of the <see cref="T:log4net.Layout.PatternLayout"/>.
+ </para>
+ </remarks>
+ <seealso cref="T:log4net.Util.TypeConverters.ConverterRegistry"/>
+ <seealso cref="T:log4net.Util.TypeConverters.IConvertFrom"/>
+ <seealso cref="T:log4net.Util.TypeConverters.IConvertTo"/>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="M:log4net.Util.TypeConverters.PatternLayoutConverter.CanConvertFrom(System.Type)">
+ <summary>
+ Can the source type be converted to the type supported by this object
+ </summary>
+ <param name="sourceType">the type to convert</param>
+ <returns>true if the conversion is possible</returns>
+ <remarks>
+ <para>
+ Returns <c>true</c> if the <paramref name="sourceType"/> is
+ the <see cref="T:System.String"/> type.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.TypeConverters.PatternLayoutConverter.ConvertFrom(System.Object)">
+ <summary>
+ Overrides the ConvertFrom method of IConvertFrom.
+ </summary>
+ <param name="source">the object to convert to a PatternLayout</param>
+ <returns>the PatternLayout</returns>
+ <remarks>
+ <para>
+ Creates and returns a new <see cref="T:log4net.Layout.PatternLayout"/> using
+ the <paramref name="source"/> <see cref="T:System.String"/> as the
+ <see cref="P:log4net.Layout.PatternLayout.ConversionPattern"/>.
+ </para>
+ </remarks>
+ <exception cref="T:log4net.Util.TypeConverters.ConversionNotSupportedException">
+ The <paramref name="source"/> object cannot be converted to the
+ target type. To check for this condition use the <see cref="M:log4net.Util.TypeConverters.PatternLayoutConverter.CanConvertFrom(System.Type)"/>
+ method.
+ </exception>
+ </member>
+ <member name="T:log4net.Util.TypeConverters.PatternStringConverter">
+ <summary>
+ Convert between string and <see cref="T:log4net.Util.PatternString"/>
+ </summary>
+ <remarks>
+ <para>
+ Supports conversion from string to <see cref="T:log4net.Util.PatternString"/> type,
+ and from a <see cref="T:log4net.Util.PatternString"/> type to a string.
+ </para>
+ <para>
+ The string is used as the <see cref="P:log4net.Util.PatternString.ConversionPattern"/>
+ of the <see cref="T:log4net.Util.PatternString"/>.
+ </para>
+ </remarks>
+ <seealso cref="T:log4net.Util.TypeConverters.ConverterRegistry"/>
+ <seealso cref="T:log4net.Util.TypeConverters.IConvertFrom"/>
+ <seealso cref="T:log4net.Util.TypeConverters.IConvertTo"/>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="M:log4net.Util.TypeConverters.PatternStringConverter.CanConvertTo(System.Type)">
+ <summary>
+ Can the target type be converted to the type supported by this object
+ </summary>
+ <param name="targetType">A <see cref="T:System.Type"/> that represents the type you want to convert to</param>
+ <returns>true if the conversion is possible</returns>
+ <remarks>
+ <para>
+ Returns <c>true</c> if the <paramref name="targetType"/> is
+ assignable from a <see cref="T:System.String"/> type.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.TypeConverters.PatternStringConverter.ConvertTo(System.Object,System.Type)">
+ <summary>
+ Converts the given value object to the specified type, using the arguments
+ </summary>
+ <param name="source">the object to convert</param>
+ <param name="targetType">The Type to convert the value parameter to</param>
+ <returns>the converted object</returns>
+ <remarks>
+ <para>
+ Uses the <see cref="M:log4net.Util.PatternString.Format"/> method to convert the
+ <see cref="T:log4net.Util.PatternString"/> argument to a <see cref="T:System.String"/>.
+ </para>
+ </remarks>
+ <exception cref="T:log4net.Util.TypeConverters.ConversionNotSupportedException">
+ The <paramref name="source"/> object cannot be converted to the
+ <paramref name="targetType"/>. To check for this condition use the
+ <see cref="M:log4net.Util.TypeConverters.PatternStringConverter.CanConvertTo(System.Type)"/> method.
+ </exception>
+ </member>
+ <member name="M:log4net.Util.TypeConverters.PatternStringConverter.CanConvertFrom(System.Type)">
+ <summary>
+ Can the source type be converted to the type supported by this object
+ </summary>
+ <param name="sourceType">the type to convert</param>
+ <returns>true if the conversion is possible</returns>
+ <remarks>
+ <para>
+ Returns <c>true</c> if the <paramref name="sourceType"/> is
+ the <see cref="T:System.String"/> type.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.TypeConverters.PatternStringConverter.ConvertFrom(System.Object)">
+ <summary>
+ Overrides the ConvertFrom method of IConvertFrom.
+ </summary>
+ <param name="source">the object to convert to a PatternString</param>
+ <returns>the PatternString</returns>
+ <remarks>
+ <para>
+ Creates and returns a new <see cref="T:log4net.Util.PatternString"/> using
+ the <paramref name="source"/> <see cref="T:System.String"/> as the
+ <see cref="P:log4net.Util.PatternString.ConversionPattern"/>.
+ </para>
+ </remarks>
+ <exception cref="T:log4net.Util.TypeConverters.ConversionNotSupportedException">
+ The <paramref name="source"/> object cannot be converted to the
+ target type. To check for this condition use the <see cref="M:log4net.Util.TypeConverters.PatternStringConverter.CanConvertFrom(System.Type)"/>
+ method.
+ </exception>
+ </member>
+ <member name="T:log4net.Util.TypeConverters.TypeConverter">
+ <summary>
+ Supports conversion from string to <see cref="T:System.Type"/> type.
+ </summary>
+ <remarks>
+ <para>
+ Supports conversion from string to <see cref="T:System.Type"/> type.
+ </para>
+ </remarks>
+ <seealso cref="T:log4net.Util.TypeConverters.ConverterRegistry"/>
+ <seealso cref="T:log4net.Util.TypeConverters.IConvertFrom"/>
+ <seealso cref="T:log4net.Util.TypeConverters.IConvertTo"/>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="M:log4net.Util.TypeConverters.TypeConverter.CanConvertFrom(System.Type)">
+ <summary>
+ Can the source type be converted to the type supported by this object
+ </summary>
+ <param name="sourceType">the type to convert</param>
+ <returns>true if the conversion is possible</returns>
+ <remarks>
+ <para>
+ Returns <c>true</c> if the <paramref name="sourceType"/> is
+ the <see cref="T:System.String"/> type.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.TypeConverters.TypeConverter.ConvertFrom(System.Object)">
+ <summary>
+ Overrides the ConvertFrom method of IConvertFrom.
+ </summary>
+ <param name="source">the object to convert to a Type</param>
+ <returns>the Type</returns>
+ <remarks>
+ <para>
+ Uses the <see cref="M:System.Type.GetType(System.String,System.Boolean)"/> method to convert the
+ <see cref="T:System.String"/> argument to a <see cref="T:System.Type"/>.
+ Additional effort is made to locate partially specified types
+ by searching the loaded assemblies.
+ </para>
+ </remarks>
+ <exception cref="T:log4net.Util.TypeConverters.ConversionNotSupportedException">
+ The <paramref name="source"/> object cannot be converted to the
+ target type. To check for this condition use the <see cref="M:log4net.Util.TypeConverters.TypeConverter.CanConvertFrom(System.Type)"/>
+ method.
+ </exception>
+ </member>
+ <member name="T:log4net.Util.TypeConverters.TypeConverterAttribute">
+ <summary>
+ Attribute used to associate a type converter
+ </summary>
+ <remarks>
+ <para>
+ Class and Interface level attribute that specifies a type converter
+ to use with the associated type.
+ </para>
+ <para>
+ To associate a type converter with a target type apply a
+ <c>TypeConverterAttribute</c> to the target type. Specify the
+ type of the type converter on the attribute.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="F:log4net.Util.TypeConverters.TypeConverterAttribute.m_typeName">
+ <summary>
+ The string type name of the type converter
+ </summary>
+ </member>
+ <member name="M:log4net.Util.TypeConverters.TypeConverterAttribute.#ctor">
+ <summary>
+ Default constructor
+ </summary>
+ <remarks>
+ <para>
+ Default constructor
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.TypeConverters.TypeConverterAttribute.#ctor(System.String)">
+ <summary>
+ Create a new type converter attribute for the specified type name
+ </summary>
+ <param name="typeName">The string type name of the type converter</param>
+ <remarks>
+ <para>
+ The type specified must implement the <see cref="T:log4net.Util.TypeConverters.IConvertFrom"/>
+ or the <see cref="T:log4net.Util.TypeConverters.IConvertTo"/> interfaces.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.TypeConverters.TypeConverterAttribute.#ctor(System.Type)">
+ <summary>
+ Create a new type converter attribute for the specified type
+ </summary>
+ <param name="converterType">The type of the type converter</param>
+ <remarks>
+ <para>
+ The type specified must implement the <see cref="T:log4net.Util.TypeConverters.IConvertFrom"/>
+ or the <see cref="T:log4net.Util.TypeConverters.IConvertTo"/> interfaces.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Util.TypeConverters.TypeConverterAttribute.ConverterTypeName">
+ <summary>
+ The string type name of the type converter
+ </summary>
+ <value>
+ The string type name of the type converter
+ </value>
+ <remarks>
+ <para>
+ The type specified must implement the <see cref="T:log4net.Util.TypeConverters.IConvertFrom"/>
+ or the <see cref="T:log4net.Util.TypeConverters.IConvertTo"/> interfaces.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Util.AppenderAttachedImpl">
+ <summary>
+ A straightforward implementation of the <see cref="T:log4net.Core.IAppenderAttachable"/> interface.
+ </summary>
+ <remarks>
+ <para>
+ This is the default implementation of the <see cref="T:log4net.Core.IAppenderAttachable"/>
+ interface. Implementors of the <see cref="T:log4net.Core.IAppenderAttachable"/> interface
+ should aggregate an instance of this type.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="M:log4net.Util.AppenderAttachedImpl.#ctor">
+ <summary>
+ Constructor
+ </summary>
+ <remarks>
+ <para>
+ Initializes a new instance of the <see cref="T:log4net.Util.AppenderAttachedImpl"/> class.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.AppenderAttachedImpl.AppendLoopOnAppenders(log4net.Core.LoggingEvent)">
+ <summary>
+ Append on on all attached appenders.
+ </summary>
+ <param name="loggingEvent">The event being logged.</param>
+ <returns>The number of appenders called.</returns>
+ <remarks>
+ <para>
+ Calls the <see cref="M:log4net.Appender.IAppender.DoAppend(log4net.Core.LoggingEvent)"/> method on all
+ attached appenders.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.AppenderAttachedImpl.AppendLoopOnAppenders(log4net.Core.LoggingEvent[])">
+ <summary>
+ Append on on all attached appenders.
+ </summary>
+ <param name="loggingEvents">The array of events being logged.</param>
+ <returns>The number of appenders called.</returns>
+ <remarks>
+ <para>
+ Calls the <see cref="M:log4net.Appender.IAppender.DoAppend(log4net.Core.LoggingEvent)"/> method on all
+ attached appenders.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.AppenderAttachedImpl.CallAppend(log4net.Appender.IAppender,log4net.Core.LoggingEvent[])">
+ <summary>
+ Calls the DoAppende method on the <see cref="T:log4net.Appender.IAppender"/> with
+ the <see cref="T:log4net.Core.LoggingEvent"/> objects supplied.
+ </summary>
+ <param name="appender">The appender</param>
+ <param name="loggingEvents">The events</param>
+ <remarks>
+ <para>
+ If the <paramref name="appender"/> supports the <see cref="T:log4net.Appender.IBulkAppender"/>
+ interface then the <paramref name="loggingEvents"/> will be passed
+ through using that interface. Otherwise the <see cref="T:log4net.Core.LoggingEvent"/>
+ objects in the array will be passed one at a time.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.AppenderAttachedImpl.AddAppender(log4net.Appender.IAppender)">
+ <summary>
+ Attaches an appender.
+ </summary>
+ <param name="newAppender">The appender to add.</param>
+ <remarks>
+ <para>
+ If the appender is already in the list it won't be added again.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.AppenderAttachedImpl.GetAppender(System.String)">
+ <summary>
+ Gets an attached appender with the specified name.
+ </summary>
+ <param name="name">The name of the appender to get.</param>
+ <returns>
+ The appender with the name specified, or <c>null</c> if no appender with the
+ specified name is found.
+ </returns>
+ <remarks>
+ <para>
+ Lookup an attached appender by name.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.AppenderAttachedImpl.RemoveAllAppenders">
+ <summary>
+ Removes all attached appenders.
+ </summary>
+ <remarks>
+ <para>
+ Removes and closes all attached appenders
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.AppenderAttachedImpl.RemoveAppender(log4net.Appender.IAppender)">
+ <summary>
+ Removes the specified appender from the list of attached appenders.
+ </summary>
+ <param name="appender">The appender to remove.</param>
+ <returns>The appender removed from the list</returns>
+ <remarks>
+ <para>
+ The appender removed is not closed.
+ If you are discarding the appender you must call
+ <see cref="M:log4net.Appender.IAppender.Close"/> on the appender removed.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.AppenderAttachedImpl.RemoveAppender(System.String)">
+ <summary>
+ Removes the appender with the specified name from the list of appenders.
+ </summary>
+ <param name="name">The name of the appender to remove.</param>
+ <returns>The appender removed from the list</returns>
+ <remarks>
+ <para>
+ The appender removed is not closed.
+ If you are discarding the appender you must call
+ <see cref="M:log4net.Appender.IAppender.Close"/> on the appender removed.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Util.AppenderAttachedImpl.m_appenderList">
+ <summary>
+ List of appenders
+ </summary>
+ </member>
+ <member name="F:log4net.Util.AppenderAttachedImpl.m_appenderArray">
+ <summary>
+ Array of appenders, used to cache the m_appenderList
+ </summary>
+ </member>
+ <member name="P:log4net.Util.AppenderAttachedImpl.Appenders">
+ <summary>
+ Gets all attached appenders.
+ </summary>
+ <returns>
+ A collection of attached appenders, or <c>null</c> if there
+ are no attached appenders.
+ </returns>
+ <remarks>
+ <para>
+ The read only collection of all currently attached appenders.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Util.CompositeProperties">
+ <summary>
+ This class aggregates several PropertiesDictionary collections together.
+ </summary>
+ <remarks>
+ <para>
+ Provides a dictionary style lookup over an ordered list of
+ <see cref="T:log4net.Util.PropertiesDictionary"/> collections.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="M:log4net.Util.CompositeProperties.#ctor">
+ <summary>
+ Constructor
+ </summary>
+ <remarks>
+ <para>
+ Initializes a new instance of the <see cref="T:log4net.Util.CompositeProperties"/> class.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.CompositeProperties.Add(log4net.Util.ReadOnlyPropertiesDictionary)">
+ <summary>
+ Add a Properties Dictionary to this composite collection
+ </summary>
+ <param name="properties">the properties to add</param>
+ <remarks>
+ <para>
+ Properties dictionaries added first take precedence over dictionaries added
+ later.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.CompositeProperties.Flatten">
+ <summary>
+ Flatten this composite collection into a single properties dictionary
+ </summary>
+ <returns>the flattened dictionary</returns>
+ <remarks>
+ <para>
+ Reduces the collection of ordered dictionaries to a single dictionary
+ containing the resultant values for the keys.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Util.CompositeProperties.Item(System.String)">
+ <summary>
+ Gets the value of a property
+ </summary>
+ <value>
+ The value for the property with the specified key
+ </value>
+ <remarks>
+ <para>
+ Looks up the value for the <paramref name="key"/> specified.
+ The <see cref="T:log4net.Util.PropertiesDictionary"/> collections are searched
+ in the order in which they were added to this collection. The value
+ returned is the value held by the first collection that contains
+ the specified key.
+ </para>
+ <para>
+ If none of the collections contain the specified key then
+ <c>null</c> is returned.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Util.ContextPropertiesBase">
+ <summary>
+ Base class for Context Properties implementations
+ </summary>
+ <remarks>
+ <para>
+ This class defines a basic property get set accessor
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="P:log4net.Util.ContextPropertiesBase.Item(System.String)">
+ <summary>
+ Gets or sets the value of a property
+ </summary>
+ <value>
+ The value for the property with the specified key
+ </value>
+ <remarks>
+ <para>
+ Gets or sets the value of a property
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Util.CountingQuietTextWriter">
+ <summary>
+ Subclass of <see cref="T:log4net.Util.QuietTextWriter"/> that maintains a count of
+ the number of bytes written.
+ </summary>
+ <remarks>
+ <para>
+ This writer counts the number of bytes written.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="T:log4net.Util.QuietTextWriter">
+ <summary>
+ <see cref="T:System.IO.TextWriter"/> that does not leak exceptions
+ </summary>
+ <remarks>
+ <para>
+ <see cref="T:log4net.Util.QuietTextWriter"/> does not throw exceptions when things go wrong.
+ Instead, it delegates error handling to its <see cref="T:log4net.Core.IErrorHandler"/>.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="T:log4net.Util.TextWriterAdapter">
+ <summary>
+ Adapter that extends <see cref="T:System.IO.TextWriter"/> and forwards all
+ messages to an instance of <see cref="T:System.IO.TextWriter"/>.
+ </summary>
+ <remarks>
+ <para>
+ Adapter that extends <see cref="T:System.IO.TextWriter"/> and forwards all
+ messages to an instance of <see cref="T:System.IO.TextWriter"/>.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="F:log4net.Util.TextWriterAdapter.m_writer">
+ <summary>
+ The writer to forward messages to
+ </summary>
+ </member>
+ <member name="M:log4net.Util.TextWriterAdapter.#ctor(System.IO.TextWriter)">
+ <summary>
+ Create an instance of <see cref="T:log4net.Util.TextWriterAdapter"/> that forwards all
+ messages to a <see cref="T:System.IO.TextWriter"/>.
+ </summary>
+ <param name="writer">The <see cref="T:System.IO.TextWriter"/> to forward to</param>
+ <remarks>
+ <para>
+ Create an instance of <see cref="T:log4net.Util.TextWriterAdapter"/> that forwards all
+ messages to a <see cref="T:System.IO.TextWriter"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.TextWriterAdapter.Close">
+ <summary>
+ Closes the writer and releases any system resources associated with the writer
+ </summary>
+ <remarks>
+ <para>
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.TextWriterAdapter.Dispose(System.Boolean)">
+ <summary>
+ Dispose this writer
+ </summary>
+ <param name="disposing">flag indicating if we are being disposed</param>
+ <remarks>
+ <para>
+ Dispose this writer
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.TextWriterAdapter.Flush">
+ <summary>
+ Flushes any buffered output
+ </summary>
+ <remarks>
+ <para>
+ Clears all buffers for the writer and causes any buffered data to be written
+ to the underlying device
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.TextWriterAdapter.Write(System.Char)">
+ <summary>
+ Writes a character to the wrapped TextWriter
+ </summary>
+ <param name="value">the value to write to the TextWriter</param>
+ <remarks>
+ <para>
+ Writes a character to the wrapped TextWriter
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.TextWriterAdapter.Write(System.Char[],System.Int32,System.Int32)">
+ <summary>
+ Writes a character buffer to the wrapped TextWriter
+ </summary>
+ <param name="buffer">the data buffer</param>
+ <param name="index">the start index</param>
+ <param name="count">the number of characters to write</param>
+ <remarks>
+ <para>
+ Writes a character buffer to the wrapped TextWriter
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.TextWriterAdapter.Write(System.String)">
+ <summary>
+ Writes a string to the wrapped TextWriter
+ </summary>
+ <param name="value">the value to write to the TextWriter</param>
+ <remarks>
+ <para>
+ Writes a string to the wrapped TextWriter
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Util.TextWriterAdapter.Writer">
+ <summary>
+ Gets or sets the underlying <see cref="T:System.IO.TextWriter"/>.
+ </summary>
+ <value>
+ The underlying <see cref="T:System.IO.TextWriter"/>.
+ </value>
+ <remarks>
+ <para>
+ Gets or sets the underlying <see cref="T:System.IO.TextWriter"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Util.TextWriterAdapter.Encoding">
+ <summary>
+ The Encoding in which the output is written
+ </summary>
+ <value>
+ The <see cref="P:log4net.Util.TextWriterAdapter.Encoding"/>
+ </value>
+ <remarks>
+ <para>
+ The Encoding in which the output is written
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Util.TextWriterAdapter.FormatProvider">
+ <summary>
+ Gets an object that controls formatting
+ </summary>
+ <value>
+ The format provider
+ </value>
+ <remarks>
+ <para>
+ Gets an object that controls formatting
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Util.TextWriterAdapter.NewLine">
+ <summary>
+ Gets or sets the line terminator string used by the TextWriter
+ </summary>
+ <value>
+ The line terminator to use
+ </value>
+ <remarks>
+ <para>
+ Gets or sets the line terminator string used by the TextWriter
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.QuietTextWriter.#ctor(System.IO.TextWriter,log4net.Core.IErrorHandler)">
+ <summary>
+ Constructor
+ </summary>
+ <param name="writer">the writer to actually write to</param>
+ <param name="errorHandler">the error handler to report error to</param>
+ <remarks>
+ <para>
+ Create a new QuietTextWriter using a writer and error handler
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.QuietTextWriter.Write(System.Char)">
+ <summary>
+ Writes a character to the underlying writer
+ </summary>
+ <param name="value">the char to write</param>
+ <remarks>
+ <para>
+ Writes a character to the underlying writer
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.QuietTextWriter.Write(System.Char[],System.Int32,System.Int32)">
+ <summary>
+ Writes a buffer to the underlying writer
+ </summary>
+ <param name="buffer">the buffer to write</param>
+ <param name="index">the start index to write from</param>
+ <param name="count">the number of characters to write</param>
+ <remarks>
+ <para>
+ Writes a buffer to the underlying writer
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.QuietTextWriter.Write(System.String)">
+ <summary>
+ Writes a string to the output.
+ </summary>
+ <param name="value">The string data to write to the output.</param>
+ <remarks>
+ <para>
+ Writes a string to the output.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.QuietTextWriter.Close">
+ <summary>
+ Closes the underlying output writer.
+ </summary>
+ <remarks>
+ <para>
+ Closes the underlying output writer.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Util.QuietTextWriter.m_errorHandler">
+ <summary>
+ The error handler instance to pass all errors to
+ </summary>
+ </member>
+ <member name="F:log4net.Util.QuietTextWriter.m_closed">
+ <summary>
+ Flag to indicate if this writer is closed
+ </summary>
+ </member>
+ <member name="P:log4net.Util.QuietTextWriter.ErrorHandler">
+ <summary>
+ Gets or sets the error handler that all errors are passed to.
+ </summary>
+ <value>
+ The error handler that all errors are passed to.
+ </value>
+ <remarks>
+ <para>
+ Gets or sets the error handler that all errors are passed to.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Util.QuietTextWriter.Closed">
+ <summary>
+ Gets a value indicating whether this writer is closed.
+ </summary>
+ <value>
+ <c>true</c> if this writer is closed, otherwise <c>false</c>.
+ </value>
+ <remarks>
+ <para>
+ Gets a value indicating whether this writer is closed.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.CountingQuietTextWriter.#ctor(System.IO.TextWriter,log4net.Core.IErrorHandler)">
+ <summary>
+ Constructor
+ </summary>
+ <param name="writer">The <see cref="T:System.IO.TextWriter"/> to actually write to.</param>
+ <param name="errorHandler">The <see cref="T:log4net.Core.IErrorHandler"/> to report errors to.</param>
+ <remarks>
+ <para>
+ Creates a new instance of the <see cref="T:log4net.Util.CountingQuietTextWriter"/> class
+ with the specified <see cref="T:System.IO.TextWriter"/> and <see cref="T:log4net.Core.IErrorHandler"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.CountingQuietTextWriter.Write(System.Char)">
+ <summary>
+ Writes a character to the underlying writer and counts the number of bytes written.
+ </summary>
+ <param name="value">the char to write</param>
+ <remarks>
+ <para>
+ Overrides implementation of <see cref="T:log4net.Util.QuietTextWriter"/>. Counts
+ the number of bytes written.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.CountingQuietTextWriter.Write(System.Char[],System.Int32,System.Int32)">
+ <summary>
+ Writes a buffer to the underlying writer and counts the number of bytes written.
+ </summary>
+ <param name="buffer">the buffer to write</param>
+ <param name="index">the start index to write from</param>
+ <param name="count">the number of characters to write</param>
+ <remarks>
+ <para>
+ Overrides implementation of <see cref="T:log4net.Util.QuietTextWriter"/>. Counts
+ the number of bytes written.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.CountingQuietTextWriter.Write(System.String)">
+ <summary>
+ Writes a string to the output and counts the number of bytes written.
+ </summary>
+ <param name="str">The string data to write to the output.</param>
+ <remarks>
+ <para>
+ Overrides implementation of <see cref="T:log4net.Util.QuietTextWriter"/>. Counts
+ the number of bytes written.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Util.CountingQuietTextWriter.m_countBytes">
+ <summary>
+ Total number of bytes written.
+ </summary>
+ </member>
+ <member name="P:log4net.Util.CountingQuietTextWriter.Count">
+ <summary>
+ Gets or sets the total number of bytes written.
+ </summary>
+ <value>
+ The total number of bytes written.
+ </value>
+ <remarks>
+ <para>
+ Gets or sets the total number of bytes written.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Util.CyclicBuffer">
+ <summary>
+ A fixed size rolling buffer of logging events.
+ </summary>
+ <remarks>
+ <para>
+ An array backed fixed size leaky bucket.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="M:log4net.Util.CyclicBuffer.#ctor(System.Int32)">
+ <summary>
+ Constructor
+ </summary>
+ <param name="maxSize">The maximum number of logging events in the buffer.</param>
+ <remarks>
+ <para>
+ Initializes a new instance of the <see cref="T:log4net.Util.CyclicBuffer"/> class with
+ the specified maximum number of buffered logging events.
+ </para>
+ </remarks>
+ <exception cref="T:System.ArgumentOutOfRangeException">The <paramref name="maxSize"/> argument is not a positive integer.</exception>
+ </member>
+ <member name="M:log4net.Util.CyclicBuffer.Append(log4net.Core.LoggingEvent)">
+ <summary>
+ Appends a <paramref name="loggingEvent"/> to the buffer.
+ </summary>
+ <param name="loggingEvent">The event to append to the buffer.</param>
+ <returns>The event discarded from the buffer, if the buffer is full, otherwise <c>null</c>.</returns>
+ <remarks>
+ <para>
+ Append an event to the buffer. If the buffer still contains free space then
+ <c>null</c> is returned. If the buffer is full then an event will be dropped
+ to make space for the new event, the event dropped is returned.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.CyclicBuffer.PopOldest">
+ <summary>
+ Get and remove the oldest event in the buffer.
+ </summary>
+ <returns>The oldest logging event in the buffer</returns>
+ <remarks>
+ <para>
+ Gets the oldest (first) logging event in the buffer and removes it
+ from the buffer.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.CyclicBuffer.PopAll">
+ <summary>
+ Pops all the logging events from the buffer into an array.
+ </summary>
+ <returns>An array of all the logging events in the buffer.</returns>
+ <remarks>
+ <para>
+ Get all the events in the buffer and clear the buffer.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.CyclicBuffer.Clear">
+ <summary>
+ Clear the buffer
+ </summary>
+ <remarks>
+ <para>
+ Clear the buffer of all events. The events in the buffer are lost.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Util.CyclicBuffer.Item(System.Int32)">
+ <summary>
+ Gets the <paramref name="i"/>th oldest event currently in the buffer.
+ </summary>
+ <value>The <paramref name="i"/>th oldest event currently in the buffer.</value>
+ <remarks>
+ <para>
+ If <paramref name="i"/> is outside the range 0 to the number of events
+ currently in the buffer, then <c>null</c> is returned.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Util.CyclicBuffer.MaxSize">
+ <summary>
+ Gets the maximum size of the buffer.
+ </summary>
+ <value>The maximum size of the buffer.</value>
+ <remarks>
+ <para>
+ Gets the maximum size of the buffer
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Util.CyclicBuffer.Length">
+ <summary>
+ Gets the number of logging events in the buffer.
+ </summary>
+ <value>The number of logging events in the buffer.</value>
+ <remarks>
+ <para>
+ This number is guaranteed to be in the range 0 to <see cref="P:log4net.Util.CyclicBuffer.MaxSize"/>
+ (inclusive).
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Util.EmptyCollection">
+ <summary>
+ An always empty <see cref="T:System.Collections.ICollection"/>.
+ </summary>
+ <remarks>
+ <para>
+ A singleton implementation of the <see cref="T:System.Collections.ICollection"/>
+ interface that always represents an empty collection.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="M:log4net.Util.EmptyCollection.#ctor">
+ <summary>
+ Initializes a new instance of the <see cref="T:log4net.Util.EmptyCollection"/> class.
+ </summary>
+ <remarks>
+ <para>
+ Uses a private access modifier to enforce the singleton pattern.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.EmptyCollection.CopyTo(System.Array,System.Int32)">
+ <summary>
+ Copies the elements of the <see cref="T:System.Collections.ICollection"/> to an
+ <see cref="T:System.Array"/>, starting at a particular Array index.
+ </summary>
+ <param name="array">The one-dimensional <see cref="T:System.Array"/>
+ that is the destination of the elements copied from
+ <see cref="T:System.Collections.ICollection"/>. The Array must have zero-based
+ indexing.</param>
+ <param name="index">The zero-based index in array at which
+ copying begins.</param>
+ <remarks>
+ <para>
+ As the collection is empty no values are copied into the array.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.EmptyCollection.GetEnumerator">
+ <summary>
+ Returns an enumerator that can iterate through a collection.
+ </summary>
+ <returns>
+ An <see cref="T:System.Collections.IEnumerator"/> that can be used to
+ iterate through the collection.
+ </returns>
+ <remarks>
+ <para>
+ As the collection is empty a <see cref="T:log4net.Util.NullEnumerator"/> is returned.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Util.EmptyCollection.s_instance">
+ <summary>
+ The singleton instance of the empty collection.
+ </summary>
+ </member>
+ <member name="P:log4net.Util.EmptyCollection.Instance">
+ <summary>
+ Gets the singleton instance of the empty collection.
+ </summary>
+ <returns>The singleton instance of the empty collection.</returns>
+ <remarks>
+ <para>
+ Gets the singleton instance of the empty collection.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Util.EmptyCollection.IsSynchronized">
+ <summary>
+ Gets a value indicating if access to the <see cref="T:System.Collections.ICollection"/> is synchronized (thread-safe).
+ </summary>
+ <value>
+ <b>true</b> if access to the <see cref="T:System.Collections.ICollection"/> is synchronized (thread-safe); otherwise, <b>false</b>.
+ </value>
+ <remarks>
+ <para>
+ For the <see cref="T:log4net.Util.EmptyCollection"/> this property is always <c>true</c>.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Util.EmptyCollection.Count">
+ <summary>
+ Gets the number of elements contained in the <see cref="T:System.Collections.ICollection"/>.
+ </summary>
+ <value>
+ The number of elements contained in the <see cref="T:System.Collections.ICollection"/>.
+ </value>
+ <remarks>
+ <para>
+ As the collection is empty the <see cref="P:log4net.Util.EmptyCollection.Count"/> is always <c>0</c>.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Util.EmptyCollection.SyncRoot">
+ <summary>
+ Gets an object that can be used to synchronize access to the <see cref="T:System.Collections.ICollection"/>.
+ </summary>
+ <value>
+ An object that can be used to synchronize access to the <see cref="T:System.Collections.ICollection"/>.
+ </value>
+ <remarks>
+ <para>
+ As the collection is empty and thread safe and synchronized this instance is also
+ the <see cref="P:log4net.Util.EmptyCollection.SyncRoot"/> object.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Util.EmptyDictionary">
+ <summary>
+ An always empty <see cref="T:System.Collections.IDictionary"/>.
+ </summary>
+ <remarks>
+ <para>
+ A singleton implementation of the <see cref="T:System.Collections.IDictionary"/>
+ interface that always represents an empty collection.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="M:log4net.Util.EmptyDictionary.#ctor">
+ <summary>
+ Initializes a new instance of the <see cref="T:log4net.Util.EmptyDictionary"/> class.
+ </summary>
+ <remarks>
+ <para>
+ Uses a private access modifier to enforce the singleton pattern.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.EmptyDictionary.CopyTo(System.Array,System.Int32)">
+ <summary>
+ Copies the elements of the <see cref="T:System.Collections.ICollection"/> to an
+ <see cref="T:System.Array"/>, starting at a particular Array index.
+ </summary>
+ <param name="array">The one-dimensional <see cref="T:System.Array"/>
+ that is the destination of the elements copied from
+ <see cref="T:System.Collections.ICollection"/>. The Array must have zero-based
+ indexing.</param>
+ <param name="index">The zero-based index in array at which
+ copying begins.</param>
+ <remarks>
+ <para>
+ As the collection is empty no values are copied into the array.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.EmptyDictionary.System#Collections#IEnumerable#GetEnumerator">
+ <summary>
+ Returns an enumerator that can iterate through a collection.
+ </summary>
+ <returns>
+ An <see cref="T:System.Collections.IEnumerator"/> that can be used to
+ iterate through the collection.
+ </returns>
+ <remarks>
+ <para>
+ As the collection is empty a <see cref="T:log4net.Util.NullEnumerator"/> is returned.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.EmptyDictionary.Add(System.Object,System.Object)">
+ <summary>
+ Adds an element with the provided key and value to the
+ <see cref="T:log4net.Util.EmptyDictionary"/>.
+ </summary>
+ <param name="key">The <see cref="T:System.Object"/> to use as the key of the element to add.</param>
+ <param name="value">The <see cref="T:System.Object"/> to use as the value of the element to add.</param>
+ <remarks>
+ <para>
+ As the collection is empty no new values can be added. A <see cref="T:System.InvalidOperationException"/>
+ is thrown if this method is called.
+ </para>
+ </remarks>
+ <exception cref="T:System.InvalidOperationException">This dictionary is always empty and cannot be modified.</exception>
+ </member>
+ <member name="M:log4net.Util.EmptyDictionary.Clear">
+ <summary>
+ Removes all elements from the <see cref="T:log4net.Util.EmptyDictionary"/>.
+ </summary>
+ <remarks>
+ <para>
+ As the collection is empty no values can be removed. A <see cref="T:System.InvalidOperationException"/>
+ is thrown if this method is called.
+ </para>
+ </remarks>
+ <exception cref="T:System.InvalidOperationException">This dictionary is always empty and cannot be modified.</exception>
+ </member>
+ <member name="M:log4net.Util.EmptyDictionary.Contains(System.Object)">
+ <summary>
+ Determines whether the <see cref="T:log4net.Util.EmptyDictionary"/> contains an element
+ with the specified key.
+ </summary>
+ <param name="key">The key to locate in the <see cref="T:log4net.Util.EmptyDictionary"/>.</param>
+ <returns><c>false</c></returns>
+ <remarks>
+ <para>
+ As the collection is empty the <see cref="M:log4net.Util.EmptyDictionary.Contains(System.Object)"/> method always returns <c>false</c>.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.EmptyDictionary.GetEnumerator">
+ <summary>
+ Returns an enumerator that can iterate through a collection.
+ </summary>
+ <returns>
+ An <see cref="T:System.Collections.IEnumerator"/> that can be used to
+ iterate through the collection.
+ </returns>
+ <remarks>
+ <para>
+ As the collection is empty a <see cref="T:log4net.Util.NullEnumerator"/> is returned.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.EmptyDictionary.Remove(System.Object)">
+ <summary>
+ Removes the element with the specified key from the <see cref="T:log4net.Util.EmptyDictionary"/>.
+ </summary>
+ <param name="key">The key of the element to remove.</param>
+ <remarks>
+ <para>
+ As the collection is empty no values can be removed. A <see cref="T:System.InvalidOperationException"/>
+ is thrown if this method is called.
+ </para>
+ </remarks>
+ <exception cref="T:System.InvalidOperationException">This dictionary is always empty and cannot be modified.</exception>
+ </member>
+ <member name="F:log4net.Util.EmptyDictionary.s_instance">
+ <summary>
+ The singleton instance of the empty dictionary.
+ </summary>
+ </member>
+ <member name="P:log4net.Util.EmptyDictionary.Instance">
+ <summary>
+ Gets the singleton instance of the <see cref="T:log4net.Util.EmptyDictionary"/>.
+ </summary>
+ <returns>The singleton instance of the <see cref="T:log4net.Util.EmptyDictionary"/>.</returns>
+ <remarks>
+ <para>
+ Gets the singleton instance of the <see cref="T:log4net.Util.EmptyDictionary"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Util.EmptyDictionary.IsSynchronized">
+ <summary>
+ Gets a value indicating if access to the <see cref="T:System.Collections.ICollection"/> is synchronized (thread-safe).
+ </summary>
+ <value>
+ <b>true</b> if access to the <see cref="T:System.Collections.ICollection"/> is synchronized (thread-safe); otherwise, <b>false</b>.
+ </value>
+ <remarks>
+ <para>
+ For the <see cref="T:log4net.Util.EmptyCollection"/> this property is always <b>true</b>.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Util.EmptyDictionary.Count">
+ <summary>
+ Gets the number of elements contained in the <see cref="T:System.Collections.ICollection"/>
+ </summary>
+ <value>
+ The number of elements contained in the <see cref="T:System.Collections.ICollection"/>.
+ </value>
+ <remarks>
+ <para>
+ As the collection is empty the <see cref="P:log4net.Util.EmptyDictionary.Count"/> is always <c>0</c>.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Util.EmptyDictionary.SyncRoot">
+ <summary>
+ Gets an object that can be used to synchronize access to the <see cref="T:System.Collections.ICollection"/>.
+ </summary>
+ <value>
+ An object that can be used to synchronize access to the <see cref="T:System.Collections.ICollection"/>.
+ </value>
+ <remarks>
+ <para>
+ As the collection is empty and thread safe and synchronized this instance is also
+ the <see cref="P:log4net.Util.EmptyDictionary.SyncRoot"/> object.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Util.EmptyDictionary.IsFixedSize">
+ <summary>
+ Gets a value indicating whether the <see cref="T:log4net.Util.EmptyDictionary"/> has a fixed size.
+ </summary>
+ <value><c>true</c></value>
+ <remarks>
+ <para>
+ As the collection is empty <see cref="P:log4net.Util.EmptyDictionary.IsFixedSize"/> always returns <c>true</c>.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Util.EmptyDictionary.IsReadOnly">
+ <summary>
+ Gets a value indicating whether the <see cref="T:log4net.Util.EmptyDictionary"/> is read-only.
+ </summary>
+ <value><c>true</c></value>
+ <remarks>
+ <para>
+ As the collection is empty <see cref="P:log4net.Util.EmptyDictionary.IsReadOnly"/> always returns <c>true</c>.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Util.EmptyDictionary.Keys">
+ <summary>
+ Gets an <see cref="T:System.Collections.ICollection"/> containing the keys of the <see cref="T:log4net.Util.EmptyDictionary"/>.
+ </summary>
+ <value>An <see cref="T:System.Collections.ICollection"/> containing the keys of the <see cref="T:log4net.Util.EmptyDictionary"/>.</value>
+ <remarks>
+ <para>
+ As the collection is empty a <see cref="T:log4net.Util.EmptyCollection"/> is returned.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Util.EmptyDictionary.Values">
+ <summary>
+ Gets an <see cref="T:System.Collections.ICollection"/> containing the values of the <see cref="T:log4net.Util.EmptyDictionary"/>.
+ </summary>
+ <value>An <see cref="T:System.Collections.ICollection"/> containing the values of the <see cref="T:log4net.Util.EmptyDictionary"/>.</value>
+ <remarks>
+ <para>
+ As the collection is empty a <see cref="T:log4net.Util.EmptyCollection"/> is returned.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Util.EmptyDictionary.Item(System.Object)">
+ <summary>
+ Gets or sets the element with the specified key.
+ </summary>
+ <param name="key">The key of the element to get or set.</param>
+ <value><c>null</c></value>
+ <remarks>
+ <para>
+ As the collection is empty no values can be looked up or stored.
+ If the index getter is called then <c>null</c> is returned.
+ A <see cref="T:System.InvalidOperationException"/> is thrown if the setter is called.
+ </para>
+ </remarks>
+ <exception cref="T:System.InvalidOperationException">This dictionary is always empty and cannot be modified.</exception>
+ </member>
+ <member name="T:log4net.Util.FormattingInfo">
+ <summary>
+ Contain the information obtained when parsing formatting modifiers
+ in conversion modifiers.
+ </summary>
+ <remarks>
+ <para>
+ Holds the formatting information extracted from the format string by
+ the <see cref="T:log4net.Util.PatternParser"/>. This is used by the <see cref="T:log4net.Util.PatternConverter"/>
+ objects when rendering the output.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="M:log4net.Util.FormattingInfo.#ctor">
+ <summary>
+ Defaut Constructor
+ </summary>
+ <remarks>
+ <para>
+ Initializes a new instance of the <see cref="T:log4net.Util.FormattingInfo"/> class.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.FormattingInfo.#ctor(System.Int32,System.Int32,System.Boolean)">
+ <summary>
+ Constructor
+ </summary>
+ <remarks>
+ <para>
+ Initializes a new instance of the <see cref="T:log4net.Util.FormattingInfo"/> class
+ with the specified parameters.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Util.FormattingInfo.Min">
+ <summary>
+ Gets or sets the minimum value.
+ </summary>
+ <value>
+ The minimum value.
+ </value>
+ <remarks>
+ <para>
+ Gets or sets the minimum value.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Util.FormattingInfo.Max">
+ <summary>
+ Gets or sets the maximum value.
+ </summary>
+ <value>
+ The maximum value.
+ </value>
+ <remarks>
+ <para>
+ Gets or sets the maximum value.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Util.FormattingInfo.LeftAlign">
+ <summary>
+ Gets or sets a flag indicating whether left align is enabled
+ or not.
+ </summary>
+ <value>
+ A flag indicating whether left align is enabled or not.
+ </value>
+ <remarks>
+ <para>
+ Gets or sets a flag indicating whether left align is enabled or not.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Util.GlobalContextProperties">
+ <summary>
+ Implementation of Properties collection for the <see cref="T:log4net.GlobalContext"/>
+ </summary>
+ <remarks>
+ <para>
+ This class implements a properties collection that is thread safe and supports both
+ storing properties and capturing a read only copy of the current propertied.
+ </para>
+ <para>
+ This class is optimized to the scenario where the properties are read frequently
+ and are modified infrequently.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="F:log4net.Util.GlobalContextProperties.m_readOnlyProperties">
+ <summary>
+ The read only copy of the properties.
+ </summary>
+ <remarks>
+ <para>
+ This variable is declared <c>volatile</c> to prevent the compiler and JIT from
+ reordering reads and writes of this thread performed on different threads.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Util.GlobalContextProperties.m_syncRoot">
+ <summary>
+ Lock object used to synchronize updates within this instance
+ </summary>
+ </member>
+ <member name="M:log4net.Util.GlobalContextProperties.#ctor">
+ <summary>
+ Constructor
+ </summary>
+ <remarks>
+ <para>
+ Initializes a new instance of the <see cref="T:log4net.Util.GlobalContextProperties"/> class.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.GlobalContextProperties.Remove(System.String)">
+ <summary>
+ Remove a property from the global context
+ </summary>
+ <param name="key">the key for the entry to remove</param>
+ <remarks>
+ <para>
+ Removing an entry from the global context properties is relatively expensive compared
+ with reading a value.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.GlobalContextProperties.Clear">
+ <summary>
+ Clear the global context properties
+ </summary>
+ </member>
+ <member name="M:log4net.Util.GlobalContextProperties.GetReadOnlyProperties">
+ <summary>
+ Get a readonly immutable copy of the properties
+ </summary>
+ <returns>the current global context properties</returns>
+ <remarks>
+ <para>
+ This implementation is fast because the GlobalContextProperties class
+ stores a readonly copy of the properties.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Util.GlobalContextProperties.Item(System.String)">
+ <summary>
+ Gets or sets the value of a property
+ </summary>
+ <value>
+ The value for the property with the specified key
+ </value>
+ <remarks>
+ <para>
+ Reading the value for a key is faster than setting the value.
+ When the value is written a new read only copy of
+ the properties is created.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Util.LevelMapping">
+ <summary>
+ Manages a mapping from levels to <see cref="T:log4net.Util.LevelMappingEntry"/>
+ </summary>
+ <remarks>
+ <para>
+ Manages an ordered mapping from <see cref="T:log4net.Core.Level"/> instances
+ to <see cref="T:log4net.Util.LevelMappingEntry"/> subclasses.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="M:log4net.Util.LevelMapping.#ctor">
+ <summary>
+ Default constructor
+ </summary>
+ <remarks>
+ <para>
+ Initialise a new instance of <see cref="T:log4net.Util.LevelMapping"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.LevelMapping.Add(log4net.Util.LevelMappingEntry)">
+ <summary>
+ Add a <see cref="T:log4net.Util.LevelMappingEntry"/> to this mapping
+ </summary>
+ <param name="entry">the entry to add</param>
+ <remarks>
+ <para>
+ If a <see cref="T:log4net.Util.LevelMappingEntry"/> has previously been added
+ for the same <see cref="T:log4net.Core.Level"/> then that entry will be
+ overwritten.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.LevelMapping.Lookup(log4net.Core.Level)">
+ <summary>
+ Lookup the mapping for the specified level
+ </summary>
+ <param name="level">the level to lookup</param>
+ <returns>the <see cref="T:log4net.Util.LevelMappingEntry"/> for the level or <c>null</c> if no mapping found</returns>
+ <remarks>
+ <para>
+ Lookup the value for the specified level. Finds the nearest
+ mapping value for the level that is equal to or less than the
+ <paramref name="level"/> specified.
+ </para>
+ <para>
+ If no mapping could be found then <c>null</c> is returned.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.LevelMapping.ActivateOptions">
+ <summary>
+ Initialize options
+ </summary>
+ <remarks>
+ <para>
+ Caches the sorted list of <see cref="T:log4net.Util.LevelMappingEntry"/> in an array
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Util.LogicalThreadContextProperties">
+ <summary>
+ Implementation of Properties collection for the <see cref="T:log4net.LogicalThreadContext"/>
+ </summary>
+ <remarks>
+ <para>
+ Class implements a collection of properties that is specific to each thread.
+ The class is not synchronized as each thread has its own <see cref="T:log4net.Util.PropertiesDictionary"/>.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="M:log4net.Util.LogicalThreadContextProperties.#ctor">
+ <summary>
+ Constructor
+ </summary>
+ <remarks>
+ <para>
+ Initializes a new instance of the <see cref="T:log4net.Util.LogicalThreadContextProperties"/> class.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.LogicalThreadContextProperties.Remove(System.String)">
+ <summary>
+ Remove a property
+ </summary>
+ <param name="key">the key for the entry to remove</param>
+ <remarks>
+ <para>
+ Remove the value for the specified <paramref name="key"/> from the context.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.LogicalThreadContextProperties.Clear">
+ <summary>
+ Clear all the context properties
+ </summary>
+ <remarks>
+ <para>
+ Clear all the context properties
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.LogicalThreadContextProperties.GetProperties(System.Boolean)">
+ <summary>
+ Get the PropertiesDictionary stored in the LocalDataStoreSlot for this thread.
+ </summary>
+ <param name="create">create the dictionary if it does not exist, otherwise return null if is does not exist</param>
+ <returns>the properties for this thread</returns>
+ <remarks>
+ <para>
+ The collection returned is only to be used on the calling thread. If the
+ caller needs to share the collection between different threads then the
+ caller must clone the collection before doings so.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Util.LogicalThreadContextProperties.Item(System.String)">
+ <summary>
+ Gets or sets the value of a property
+ </summary>
+ <value>
+ The value for the property with the specified key
+ </value>
+ <remarks>
+ <para>
+ Get or set the property value for the <paramref name="key"/> specified.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Util.LogLog">
+ <summary>
+ Outputs log statements from within the log4net assembly.
+ </summary>
+ <remarks>
+ <para>
+ Log4net components cannot make log4net logging calls. However, it is
+ sometimes useful for the user to learn about what log4net is
+ doing.
+ </para>
+ <para>
+ All log4net internal debug calls go to the standard output stream
+ whereas internal error messages are sent to the standard error output
+ stream.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="M:log4net.Util.LogLog.#ctor">
+ <summary>
+ Initializes a new instance of the <see cref="T:log4net.Util.LogLog"/> class.
+ </summary>
+ <remarks>
+ <para>
+ Uses a private access modifier to prevent instantiation of this class.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.LogLog.#cctor">
+ <summary>
+ Static constructor that initializes logging by reading
+ settings from the application configuration file.
+ </summary>
+ <remarks>
+ <para>
+ The <c>log4net.Internal.Debug</c> application setting
+ controls internal debugging. This setting should be set
+ to <c>true</c> to enable debugging.
+ </para>
+ <para>
+ The <c>log4net.Internal.Quiet</c> application setting
+ suppresses all internal logging including error messages.
+ This setting should be set to <c>true</c> to enable message
+ suppression.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.LogLog.Debug(System.String)">
+ <summary>
+ Writes log4net internal debug messages to the
+ standard output stream.
+ </summary>
+ <param name="message">The message to log.</param>
+ <remarks>
+ <para>
+ All internal debug messages are prepended with
+ the string "log4net: ".
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.LogLog.Debug(System.String,System.Exception)">
+ <summary>
+ Writes log4net internal debug messages to the
+ standard output stream.
+ </summary>
+ <param name="message">The message to log.</param>
+ <param name="exception">An exception to log.</param>
+ <remarks>
+ <para>
+ All internal debug messages are prepended with
+ the string "log4net: ".
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.LogLog.Warn(System.String)">
+ <summary>
+ Writes log4net internal warning messages to the
+ standard error stream.
+ </summary>
+ <param name="message">The message to log.</param>
+ <remarks>
+ <para>
+ All internal warning messages are prepended with
+ the string "log4net:WARN ".
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.LogLog.Warn(System.String,System.Exception)">
+ <summary>
+ Writes log4net internal warning messages to the
+ standard error stream.
+ </summary>
+ <param name="message">The message to log.</param>
+ <param name="exception">An exception to log.</param>
+ <remarks>
+ <para>
+ All internal warning messages are prepended with
+ the string "log4net:WARN ".
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.LogLog.Error(System.String)">
+ <summary>
+ Writes log4net internal error messages to the
+ standard error stream.
+ </summary>
+ <param name="message">The message to log.</param>
+ <remarks>
+ <para>
+ All internal error messages are prepended with
+ the string "log4net:ERROR ".
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.LogLog.Error(System.String,System.Exception)">
+ <summary>
+ Writes log4net internal error messages to the
+ standard error stream.
+ </summary>
+ <param name="message">The message to log.</param>
+ <param name="exception">An exception to log.</param>
+ <remarks>
+ <para>
+ All internal debug messages are prepended with
+ the string "log4net:ERROR ".
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.LogLog.EmitOutLine(System.String)">
+ <summary>
+ Writes output to the standard output stream.
+ </summary>
+ <param name="message">The message to log.</param>
+ <remarks>
+ <para>
+ Writes to both Console.Out and System.Diagnostics.Trace.
+ Note that the System.Diagnostics.Trace is not supported
+ on the Compact Framework.
+ </para>
+ <para>
+ If the AppDomain is not configured with a config file then
+ the call to System.Diagnostics.Trace may fail. This is only
+ an issue if you are programmatically creating your own AppDomains.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.LogLog.EmitErrorLine(System.String)">
+ <summary>
+ Writes output to the standard error stream.
+ </summary>
+ <param name="message">The message to log.</param>
+ <remarks>
+ <para>
+ Writes to both Console.Error and System.Diagnostics.Trace.
+ Note that the System.Diagnostics.Trace is not supported
+ on the Compact Framework.
+ </para>
+ <para>
+ If the AppDomain is not configured with a config file then
+ the call to System.Diagnostics.Trace may fail. This is only
+ an issue if you are programmatically creating your own AppDomains.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Util.LogLog.s_debugEnabled">
+ <summary>
+ Default debug level
+ </summary>
+ </member>
+ <member name="F:log4net.Util.LogLog.s_quietMode">
+ <summary>
+ In quietMode not even errors generate any output.
+ </summary>
+ </member>
+ <member name="P:log4net.Util.LogLog.InternalDebugging">
+ <summary>
+ Gets or sets a value indicating whether log4net internal logging
+ is enabled or disabled.
+ </summary>
+ <value>
+ <c>true</c> if log4net internal logging is enabled, otherwise
+ <c>false</c>.
+ </value>
+ <remarks>
+ <para>
+ When set to <c>true</c>, internal debug level logging will be
+ displayed.
+ </para>
+ <para>
+ This value can be set by setting the application setting
+ <c>log4net.Internal.Debug</c> in the application configuration
+ file.
+ </para>
+ <para>
+ The default value is <c>false</c>, i.e. debugging is
+ disabled.
+ </para>
+ </remarks>
+ <example>
+ <para>
+ The following example enables internal debugging using the
+ application configuration file :
+ </para>
+ <code lang="XML" escaped="true">
+ <configuration>
+ <appSettings>
+ <add key="log4net.Internal.Debug" value="true" />
+ </appSettings>
+ </configuration>
+ </code>
+ </example>
+ </member>
+ <member name="P:log4net.Util.LogLog.QuietMode">
+ <summary>
+ Gets or sets a value indicating whether log4net should generate no output
+ from internal logging, not even for errors.
+ </summary>
+ <value>
+ <c>true</c> if log4net should generate no output at all from internal
+ logging, otherwise <c>false</c>.
+ </value>
+ <remarks>
+ <para>
+ When set to <c>true</c> will cause internal logging at all levels to be
+ suppressed. This means that no warning or error reports will be logged.
+ This option overrides the <see cref="P:log4net.Util.LogLog.InternalDebugging"/> setting and
+ disables all debug also.
+ </para>
+ <para>This value can be set by setting the application setting
+ <c>log4net.Internal.Quiet</c> in the application configuration file.
+ </para>
+ <para>
+ The default value is <c>false</c>, i.e. internal logging is not
+ disabled.
+ </para>
+ </remarks>
+ <example>
+ The following example disables internal logging using the
+ application configuration file :
+ <code lang="XML" escaped="true">
+ <configuration>
+ <appSettings>
+ <add key="log4net.Internal.Quiet" value="true"/>
+ </appSettings>
+ </configuration>
+ </code>
+ </example>
+ </member>
+ <member name="P:log4net.Util.LogLog.IsDebugEnabled">
+ <summary>
+ Test if LogLog.Debug is enabled for output.
+ </summary>
+ <value>
+ <c>true</c> if Debug is enabled
+ </value>
+ <remarks>
+ <para>
+ Test if LogLog.Debug is enabled for output.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Util.LogLog.IsWarnEnabled">
+ <summary>
+ Test if LogLog.Warn is enabled for output.
+ </summary>
+ <value>
+ <c>true</c> if Warn is enabled
+ </value>
+ <remarks>
+ <para>
+ Test if LogLog.Warn is enabled for output.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Util.LogLog.IsErrorEnabled">
+ <summary>
+ Test if LogLog.Error is enabled for output.
+ </summary>
+ <value>
+ <c>true</c> if Error is enabled
+ </value>
+ <remarks>
+ <para>
+ Test if LogLog.Error is enabled for output.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Util.NativeError">
+ <summary>
+ Represents a native error code and message.
+ </summary>
+ <remarks>
+ <para>
+ Represents a Win32 platform native error.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="M:log4net.Util.NativeError.#ctor(System.Int32,System.String)">
+ <summary>
+ Create an instance of the <see cref="T:log4net.Util.NativeError"/> class with the specified
+ error number and message.
+ </summary>
+ <param name="number">The number of the native error.</param>
+ <param name="message">The message of the native error.</param>
+ <remarks>
+ <para>
+ Create an instance of the <see cref="T:log4net.Util.NativeError"/> class with the specified
+ error number and message.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.NativeError.GetLastError">
+ <summary>
+ Create a new instance of the <see cref="T:log4net.Util.NativeError"/> class for the last Windows error.
+ </summary>
+ <returns>
+ An instance of the <see cref="T:log4net.Util.NativeError"/> class for the last windows error.
+ </returns>
+ <remarks>
+ <para>
+ The message for the <see cref="M:System.Runtime.InteropServices.Marshal.GetLastWin32Error"/> error number is lookup up using the
+ native Win32 <c>FormatMessage</c> function.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.NativeError.GetError(System.Int32)">
+ <summary>
+ Create a new instance of the <see cref="T:log4net.Util.NativeError"/> class.
+ </summary>
+ <param name="number">the error number for the native error</param>
+ <returns>
+ An instance of the <see cref="T:log4net.Util.NativeError"/> class for the specified
+ error number.
+ </returns>
+ <remarks>
+ <para>
+ The message for the specified error number is lookup up using the
+ native Win32 <c>FormatMessage</c> function.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.NativeError.GetErrorMessage(System.Int32)">
+ <summary>
+ Retrieves the message corresponding with a Win32 message identifier.
+ </summary>
+ <param name="messageId">Message identifier for the requested message.</param>
+ <returns>
+ The message corresponding with the specified message identifier.
+ </returns>
+ <remarks>
+ <para>
+ The message will be searched for in system message-table resource(s)
+ using the native <c>FormatMessage</c> function.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.NativeError.ToString">
+ <summary>
+ Return error information string
+ </summary>
+ <returns>error information string</returns>
+ <remarks>
+ <para>
+ Return error information string
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.NativeError.FormatMessage(System.Int32,System.IntPtr@,System.Int32,System.Int32,System.String@,System.Int32,System.IntPtr)">
+ <summary>
+ Formats a message string.
+ </summary>
+ <param name="dwFlags">Formatting options, and how to interpret the <paramref name="lpSource"/> parameter.</param>
+ <param name="lpSource">Location of the message definition.</param>
+ <param name="dwMessageId">Message identifier for the requested message.</param>
+ <param name="dwLanguageId">Language identifier for the requested message.</param>
+ <param name="lpBuffer">If <paramref name="dwFlags"/> includes FORMAT_MESSAGE_ALLOCATE_BUFFER, the function allocates a buffer using the <c>LocalAlloc</c> function, and places the pointer to the buffer at the address specified in <paramref name="lpBuffer"/>.</param>
+ <param name="nSize">If the FORMAT_MESSAGE_ALLOCATE_BUFFER flag is not set, this parameter specifies the maximum number of TCHARs that can be stored in the output buffer. If FORMAT_MESSAGE_ALLOCATE_BUFFER is set, this parameter specifies the minimum number of TCHARs to allocate for an output buffer.</param>
+ <param name="Arguments">Pointer to an array of values that are used as insert values in the formatted message.</param>
+ <remarks>
+ <para>
+ The function requires a message definition as input. The message definition can come from a
+ buffer passed into the function. It can come from a message table resource in an
+ already-loaded module. Or the caller can ask the function to search the system's message
+ table resource(s) for the message definition. The function finds the message definition
+ in a message table resource based on a message identifier and a language identifier.
+ The function copies the formatted message text to an output buffer, processing any embedded
+ insert sequences if requested.
+ </para>
+ <para>
+ To prevent the usage of unsafe code, this stub does not support inserting values in the formatted message.
+ </para>
+ </remarks>
+ <returns>
+ <para>
+ If the function succeeds, the return value is the number of TCHARs stored in the output
+ buffer, excluding the terminating null character.
+ </para>
+ <para>
+ If the function fails, the return value is zero. To get extended error information,
+ call <see cref="M:System.Runtime.InteropServices.Marshal.GetLastWin32Error"/>.
+ </para>
+ </returns>
+ </member>
+ <member name="P:log4net.Util.NativeError.Number">
+ <summary>
+ Gets the number of the native error.
+ </summary>
+ <value>
+ The number of the native error.
+ </value>
+ <remarks>
+ <para>
+ Gets the number of the native error.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Util.NativeError.Message">
+ <summary>
+ Gets the message of the native error.
+ </summary>
+ <value>
+ The message of the native error.
+ </value>
+ <remarks>
+ <para>
+ </para>
+ Gets the message of the native error.
+ </remarks>
+ </member>
+ <member name="T:log4net.Util.NullDictionaryEnumerator">
+ <summary>
+ An always empty <see cref="T:System.Collections.IDictionaryEnumerator"/>.
+ </summary>
+ <remarks>
+ <para>
+ A singleton implementation of the <see cref="T:System.Collections.IDictionaryEnumerator"/> over a collection
+ that is empty and not modifiable.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="M:log4net.Util.NullDictionaryEnumerator.#ctor">
+ <summary>
+ Initializes a new instance of the <see cref="T:log4net.Util.NullDictionaryEnumerator"/> class.
+ </summary>
+ <remarks>
+ <para>
+ Uses a private access modifier to enforce the singleton pattern.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.NullDictionaryEnumerator.MoveNext">
+ <summary>
+ Test if the enumerator can advance, if so advance.
+ </summary>
+ <returns><c>false</c> as the <see cref="T:log4net.Util.NullDictionaryEnumerator"/> cannot advance.</returns>
+ <remarks>
+ <para>
+ As the enumerator is over an empty collection its <see cref="P:log4net.Util.NullDictionaryEnumerator.Current"/>
+ value cannot be moved over a valid position, therefore <see cref="M:log4net.Util.NullDictionaryEnumerator.MoveNext"/>
+ will always return <c>false</c>.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.NullDictionaryEnumerator.Reset">
+ <summary>
+ Resets the enumerator back to the start.
+ </summary>
+ <remarks>
+ <para>
+ As the enumerator is over an empty collection <see cref="M:log4net.Util.NullDictionaryEnumerator.Reset"/> does nothing.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Util.NullDictionaryEnumerator.s_instance">
+ <summary>
+ The singleton instance of the <see cref="T:log4net.Util.NullDictionaryEnumerator"/>.
+ </summary>
+ </member>
+ <member name="P:log4net.Util.NullDictionaryEnumerator.Instance">
+ <summary>
+ Gets the singleton instance of the <see cref="T:log4net.Util.NullDictionaryEnumerator"/>.
+ </summary>
+ <returns>The singleton instance of the <see cref="T:log4net.Util.NullDictionaryEnumerator"/>.</returns>
+ <remarks>
+ <para>
+ Gets the singleton instance of the <see cref="T:log4net.Util.NullDictionaryEnumerator"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Util.NullDictionaryEnumerator.Current">
+ <summary>
+ Gets the current object from the enumerator.
+ </summary>
+ <remarks>
+ Throws an <see cref="T:System.InvalidOperationException"/> because the
+ <see cref="T:log4net.Util.NullDictionaryEnumerator"/> never has a current value.
+ </remarks>
+ <remarks>
+ <para>
+ As the enumerator is over an empty collection its <see cref="P:log4net.Util.NullDictionaryEnumerator.Current"/>
+ value cannot be moved over a valid position, therefore <see cref="P:log4net.Util.NullDictionaryEnumerator.Current"/>
+ will throw an <see cref="T:System.InvalidOperationException"/>.
+ </para>
+ </remarks>
+ <exception cref="T:System.InvalidOperationException">The collection is empty and <see cref="P:log4net.Util.NullDictionaryEnumerator.Current"/>
+ cannot be positioned over a valid location.</exception>
+ </member>
+ <member name="P:log4net.Util.NullDictionaryEnumerator.Key">
+ <summary>
+ Gets the current key from the enumerator.
+ </summary>
+ <remarks>
+ Throws an exception because the <see cref="T:log4net.Util.NullDictionaryEnumerator"/>
+ never has a current value.
+ </remarks>
+ <remarks>
+ <para>
+ As the enumerator is over an empty collection its <see cref="P:log4net.Util.NullDictionaryEnumerator.Current"/>
+ value cannot be moved over a valid position, therefore <see cref="P:log4net.Util.NullDictionaryEnumerator.Key"/>
+ will throw an <see cref="T:System.InvalidOperationException"/>.
+ </para>
+ </remarks>
+ <exception cref="T:System.InvalidOperationException">The collection is empty and <see cref="P:log4net.Util.NullDictionaryEnumerator.Current"/>
+ cannot be positioned over a valid location.</exception>
+ </member>
+ <member name="P:log4net.Util.NullDictionaryEnumerator.Value">
+ <summary>
+ Gets the current value from the enumerator.
+ </summary>
+ <value>The current value from the enumerator.</value>
+ <remarks>
+ Throws an <see cref="T:System.InvalidOperationException"/> because the
+ <see cref="T:log4net.Util.NullDictionaryEnumerator"/> never has a current value.
+ </remarks>
+ <remarks>
+ <para>
+ As the enumerator is over an empty collection its <see cref="P:log4net.Util.NullDictionaryEnumerator.Current"/>
+ value cannot be moved over a valid position, therefore <see cref="P:log4net.Util.NullDictionaryEnumerator.Value"/>
+ will throw an <see cref="T:System.InvalidOperationException"/>.
+ </para>
+ </remarks>
+ <exception cref="T:System.InvalidOperationException">The collection is empty and <see cref="P:log4net.Util.NullDictionaryEnumerator.Current"/>
+ cannot be positioned over a valid location.</exception>
+ </member>
+ <member name="P:log4net.Util.NullDictionaryEnumerator.Entry">
+ <summary>
+ Gets the current entry from the enumerator.
+ </summary>
+ <remarks>
+ Throws an <see cref="T:System.InvalidOperationException"/> because the
+ <see cref="T:log4net.Util.NullDictionaryEnumerator"/> never has a current entry.
+ </remarks>
+ <remarks>
+ <para>
+ As the enumerator is over an empty collection its <see cref="P:log4net.Util.NullDictionaryEnumerator.Current"/>
+ value cannot be moved over a valid position, therefore <see cref="P:log4net.Util.NullDictionaryEnumerator.Entry"/>
+ will throw an <see cref="T:System.InvalidOperationException"/>.
+ </para>
+ </remarks>
+ <exception cref="T:System.InvalidOperationException">The collection is empty and <see cref="P:log4net.Util.NullDictionaryEnumerator.Current"/>
+ cannot be positioned over a valid location.</exception>
+ </member>
+ <member name="T:log4net.Util.NullEnumerator">
+ <summary>
+ An always empty <see cref="T:System.Collections.IEnumerator"/>.
+ </summary>
+ <remarks>
+ <para>
+ A singleton implementation of the <see cref="T:System.Collections.IEnumerator"/> over a collection
+ that is empty and not modifiable.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="M:log4net.Util.NullEnumerator.#ctor">
+ <summary>
+ Initializes a new instance of the <see cref="T:log4net.Util.NullEnumerator"/> class.
+ </summary>
+ <remarks>
+ <para>
+ Uses a private access modifier to enforce the singleton pattern.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.NullEnumerator.MoveNext">
+ <summary>
+ Test if the enumerator can advance, if so advance
+ </summary>
+ <returns><c>false</c> as the <see cref="T:log4net.Util.NullEnumerator"/> cannot advance.</returns>
+ <remarks>
+ <para>
+ As the enumerator is over an empty collection its <see cref="P:log4net.Util.NullEnumerator.Current"/>
+ value cannot be moved over a valid position, therefore <see cref="M:log4net.Util.NullEnumerator.MoveNext"/>
+ will always return <c>false</c>.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.NullEnumerator.Reset">
+ <summary>
+ Resets the enumerator back to the start.
+ </summary>
+ <remarks>
+ <para>
+ As the enumerator is over an empty collection <see cref="M:log4net.Util.NullEnumerator.Reset"/> does nothing.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Util.NullEnumerator.s_instance">
+ <summary>
+ The singleton instance of the <see cref="T:log4net.Util.NullEnumerator"/>.
+ </summary>
+ </member>
+ <member name="P:log4net.Util.NullEnumerator.Instance">
+ <summary>
+ Get the singleton instance of the <see cref="T:log4net.Util.NullEnumerator"/>.
+ </summary>
+ <returns>The singleton instance of the <see cref="T:log4net.Util.NullEnumerator"/>.</returns>
+ <remarks>
+ <para>
+ Gets the singleton instance of the <see cref="T:log4net.Util.NullEnumerator"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Util.NullEnumerator.Current">
+ <summary>
+ Gets the current object from the enumerator.
+ </summary>
+ <remarks>
+ Throws an <see cref="T:System.InvalidOperationException"/> because the
+ <see cref="T:log4net.Util.NullDictionaryEnumerator"/> never has a current value.
+ </remarks>
+ <remarks>
+ <para>
+ As the enumerator is over an empty collection its <see cref="P:log4net.Util.NullEnumerator.Current"/>
+ value cannot be moved over a valid position, therefore <see cref="P:log4net.Util.NullEnumerator.Current"/>
+ will throw an <see cref="T:System.InvalidOperationException"/>.
+ </para>
+ </remarks>
+ <exception cref="T:System.InvalidOperationException">The collection is empty and <see cref="P:log4net.Util.NullEnumerator.Current"/>
+ cannot be positioned over a valid location.</exception>
+ </member>
+ <member name="T:log4net.Util.NullSecurityContext">
+ <summary>
+ A SecurityContext used when a SecurityContext is not required
+ </summary>
+ <remarks>
+ <para>
+ The <see cref="T:log4net.Util.NullSecurityContext"/> is a no-op implementation of the
+ <see cref="T:log4net.Core.SecurityContext"/> base class. It is used where a <see cref="T:log4net.Core.SecurityContext"/>
+ is required but one has not been provided.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="F:log4net.Util.NullSecurityContext.Instance">
+ <summary>
+ Singleton instance of <see cref="T:log4net.Util.NullSecurityContext"/>
+ </summary>
+ <remarks>
+ <para>
+ Singleton instance of <see cref="T:log4net.Util.NullSecurityContext"/>
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.NullSecurityContext.#ctor">
+ <summary>
+ Private constructor
+ </summary>
+ <remarks>
+ <para>
+ Private constructor for singleton pattern.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.NullSecurityContext.Impersonate(System.Object)">
+ <summary>
+ Impersonate this SecurityContext
+ </summary>
+ <param name="state">State supplied by the caller</param>
+ <returns><c>null</c></returns>
+ <remarks>
+ <para>
+ No impersonation is done and <c>null</c> is always returned.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Util.OnlyOnceErrorHandler">
+ <summary>
+ Implements log4net's default error handling policy which consists
+ of emitting a message for the first error in an appender and
+ ignoring all subsequent errors.
+ </summary>
+ <remarks>
+ <para>
+ The error message is printed on the standard error output stream.
+ </para>
+ <para>
+ This policy aims at protecting an otherwise working application
+ from being flooded with error messages when logging fails.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="M:log4net.Util.OnlyOnceErrorHandler.#ctor">
+ <summary>
+ Default Constructor
+ </summary>
+ <remarks>
+ <para>
+ Initializes a new instance of the <see cref="T:log4net.Util.OnlyOnceErrorHandler"/> class.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.OnlyOnceErrorHandler.#ctor(System.String)">
+ <summary>
+ Constructor
+ </summary>
+ <param name="prefix">The prefix to use for each message.</param>
+ <remarks>
+ <para>
+ Initializes a new instance of the <see cref="T:log4net.Util.OnlyOnceErrorHandler"/> class
+ with the specified prefix.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.OnlyOnceErrorHandler.Error(System.String,System.Exception,log4net.Core.ErrorCode)">
+ <summary>
+ Log an Error
+ </summary>
+ <param name="message">The error message.</param>
+ <param name="e">The exception.</param>
+ <param name="errorCode">The internal error code.</param>
+ <remarks>
+ <para>
+ Prints the message and the stack trace of the exception on the standard
+ error output stream.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.OnlyOnceErrorHandler.Error(System.String,System.Exception)">
+ <summary>
+ Log an Error
+ </summary>
+ <param name="message">The error message.</param>
+ <param name="e">The exception.</param>
+ <remarks>
+ <para>
+ Prints the message and the stack trace of the exception on the standard
+ error output stream.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.OnlyOnceErrorHandler.Error(System.String)">
+ <summary>
+ Log an error
+ </summary>
+ <param name="message">The error message.</param>
+ <remarks>
+ <para>
+ Print a the error message passed as parameter on the standard
+ error output stream.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Util.OnlyOnceErrorHandler.m_firstTime">
+ <summary>
+ Flag to indicate if it is the first error
+ </summary>
+ </member>
+ <member name="F:log4net.Util.OnlyOnceErrorHandler.m_prefix">
+ <summary>
+ String to prefix each message with
+ </summary>
+ </member>
+ <member name="P:log4net.Util.OnlyOnceErrorHandler.IsEnabled">
+ <summary>
+ Is error logging enabled
+ </summary>
+ <remarks>
+ <para>
+ Is error logging enabled. Logging is only enabled for the
+ first error delivered to the <see cref="T:log4net.Util.OnlyOnceErrorHandler"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Util.OptionConverter">
+ <summary>
+ A convenience class to convert property values to specific types.
+ </summary>
+ <remarks>
+ <para>
+ Utility functions for converting types and parsing values.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="M:log4net.Util.OptionConverter.#ctor">
+ <summary>
+ Initializes a new instance of the <see cref="T:log4net.Util.OptionConverter"/> class.
+ </summary>
+ <remarks>
+ <para>
+ Uses a private access modifier to prevent instantiation of this class.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.OptionConverter.ToBoolean(System.String,System.Boolean)">
+ <summary>
+ Converts a string to a <see cref="T:System.Boolean"/> value.
+ </summary>
+ <param name="argValue">String to convert.</param>
+ <param name="defaultValue">The default value.</param>
+ <returns>The <see cref="T:System.Boolean"/> value of <paramref name="argValue"/>.</returns>
+ <remarks>
+ <para>
+ If <paramref name="argValue"/> is "true", then <c>true</c> is returned.
+ If <paramref name="argValue"/> is "false", then <c>false</c> is returned.
+ Otherwise, <paramref name="defaultValue"/> is returned.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.OptionConverter.ToFileSize(System.String,System.Int64)">
+ <summary>
+ Parses a file size into a number.
+ </summary>
+ <param name="argValue">String to parse.</param>
+ <param name="defaultValue">The default value.</param>
+ <returns>The <see cref="T:System.Int64"/> value of <paramref name="argValue"/>.</returns>
+ <remarks>
+ <para>
+ Parses a file size of the form: number[KB|MB|GB] into a
+ long value. It is scaled with the appropriate multiplier.
+ </para>
+ <para>
+ <paramref name="defaultValue"/> is returned when <paramref name="argValue"/>
+ cannot be converted to a <see cref="T:System.Int64"/> value.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.OptionConverter.ConvertStringTo(System.Type,System.String)">
+ <summary>
+ Converts a string to an object.
+ </summary>
+ <param name="target">The target type to convert to.</param>
+ <param name="txt">The string to convert to an object.</param>
+ <returns>
+ The object converted from a string or <c>null</c> when the
+ conversion failed.
+ </returns>
+ <remarks>
+ <para>
+ Converts a string to an object. Uses the converter registry to try
+ to convert the string value into the specified target type.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.OptionConverter.CanConvertTypeTo(System.Type,System.Type)">
+ <summary>
+ Checks if there is an appropriate type conversion from the source type to the target type.
+ </summary>
+ <param name="sourceType">The type to convert from.</param>
+ <param name="targetType">The type to convert to.</param>
+ <returns><c>true</c> if there is a conversion from the source type to the target type.</returns>
+ <remarks>
+ Checks if there is an appropriate type conversion from the source type to the target type.
+ <para>
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.OptionConverter.ConvertTypeTo(System.Object,System.Type)">
+ <summary>
+ Converts an object to the target type.
+ </summary>
+ <param name="sourceInstance">The object to convert to the target type.</param>
+ <param name="targetType">The type to convert to.</param>
+ <returns>The converted object.</returns>
+ <remarks>
+ <para>
+ Converts an object to the target type.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.OptionConverter.InstantiateByClassName(System.String,System.Type,System.Object)">
+ <summary>
+ Instantiates an object given a class name.
+ </summary>
+ <param name="className">The fully qualified class name of the object to instantiate.</param>
+ <param name="superClass">The class to which the new object should belong.</param>
+ <param name="defaultValue">The object to return in case of non-fulfillment.</param>
+ <returns>
+ An instance of the <paramref name="className"/> or <paramref name="defaultValue"/>
+ if the object could not be instantiated.
+ </returns>
+ <remarks>
+ <para>
+ Checks that the <paramref name="className"/> is a subclass of
+ <paramref name="superClass"/>. If that test fails or the object could
+ not be instantiated, then <paramref name="defaultValue"/> is returned.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.OptionConverter.SubstituteVariables(System.String,System.Collections.IDictionary)">
+ <summary>
+ Performs variable substitution in string <paramref name="val"/> from the
+ values of keys found in <paramref name="props"/>.
+ </summary>
+ <param name="value">The string on which variable substitution is performed.</param>
+ <param name="props">The dictionary to use to lookup variables.</param>
+ <returns>The result of the substitutions.</returns>
+ <remarks>
+ <para>
+ The variable substitution delimiters are <b>${</b> and <b>}</b>.
+ </para>
+ <para>
+ For example, if props contains <c>key=value</c>, then the call
+ </para>
+ <para>
+ <code lang="C#">
+ string s = OptionConverter.SubstituteVariables("Value of key is ${key}.");
+ </code>
+ </para>
+ <para>
+ will set the variable <c>s</c> to "Value of key is value.".
+ </para>
+ <para>
+ If no value could be found for the specified key, then substitution
+ defaults to an empty string.
+ </para>
+ <para>
+ For example, if system properties contains no value for the key
+ "nonExistentKey", then the call
+ </para>
+ <para>
+ <code lang="C#">
+ string s = OptionConverter.SubstituteVariables("Value of nonExistentKey is [${nonExistentKey}]");
+ </code>
+ </para>
+ <para>
+ will set <s>s</s> to "Value of nonExistentKey is []".
+ </para>
+ <para>
+ An Exception is thrown if <paramref name="value"/> contains a start
+ delimiter "${" which is not balanced by a stop delimiter "}".
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.OptionConverter.ParseEnum(System.Type,System.String,System.Boolean)">
+ <summary>
+ Converts the string representation of the name or numeric value of one or
+ more enumerated constants to an equivalent enumerated object.
+ </summary>
+ <param name="enumType">The type to convert to.</param>
+ <param name="value">The enum string value.</param>
+ <param name="ignoreCase">If <c>true</c>, ignore case; otherwise, regard case.</param>
+ <returns>An object of type <paramref name="enumType" /> whose value is represented by <paramref name="value" />.</returns>
+ </member>
+ <member name="T:log4net.Util.PatternParser">
+ <summary>
+ Most of the work of the <see cref="T:log4net.Layout.PatternLayout"/> class
+ is delegated to the PatternParser class.
+ </summary>
+ <remarks>
+ <para>
+ The <c>PatternParser</c> processes a pattern string and
+ returns a chain of <see cref="T:log4net.Util.PatternConverter"/> objects.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="M:log4net.Util.PatternParser.#ctor(System.String)">
+ <summary>
+ Constructor
+ </summary>
+ <param name="pattern">The pattern to parse.</param>
+ <remarks>
+ <para>
+ Initializes a new instance of the <see cref="T:log4net.Util.PatternParser"/> class
+ with the specified pattern string.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.PatternParser.Parse">
+ <summary>
+ Parses the pattern into a chain of pattern converters.
+ </summary>
+ <returns>The head of a chain of pattern converters.</returns>
+ <remarks>
+ <para>
+ Parses the pattern into a chain of pattern converters.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.PatternParser.BuildCache">
+ <summary>
+ Build the unified cache of converters from the static and instance maps
+ </summary>
+ <returns>the list of all the converter names</returns>
+ <remarks>
+ <para>
+ Build the unified cache of converters from the static and instance maps
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.PatternParser.ParseInternal(System.String,System.String[])">
+ <summary>
+ Internal method to parse the specified pattern to find specified matches
+ </summary>
+ <param name="pattern">the pattern to parse</param>
+ <param name="matches">the converter names to match in the pattern</param>
+ <remarks>
+ <para>
+ The matches param must be sorted such that longer strings come before shorter ones.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.PatternParser.ProcessLiteral(System.String)">
+ <summary>
+ Process a parsed literal
+ </summary>
+ <param name="text">the literal text</param>
+ </member>
+ <member name="M:log4net.Util.PatternParser.ProcessConverter(System.String,System.String,log4net.Util.FormattingInfo)">
+ <summary>
+ Process a parsed converter pattern
+ </summary>
+ <param name="converterName">the name of the converter</param>
+ <param name="option">the optional option for the converter</param>
+ <param name="formattingInfo">the formatting info for the converter</param>
+ </member>
+ <member name="M:log4net.Util.PatternParser.AddConverter(log4net.Util.PatternConverter)">
+ <summary>
+ Resets the internal state of the parser and adds the specified pattern converter
+ to the chain.
+ </summary>
+ <param name="pc">The pattern converter to add.</param>
+ </member>
+ <member name="F:log4net.Util.PatternParser.m_head">
+ <summary>
+ The first pattern converter in the chain
+ </summary>
+ </member>
+ <member name="F:log4net.Util.PatternParser.m_tail">
+ <summary>
+ the last pattern converter in the chain
+ </summary>
+ </member>
+ <member name="F:log4net.Util.PatternParser.m_pattern">
+ <summary>
+ The pattern
+ </summary>
+ </member>
+ <member name="F:log4net.Util.PatternParser.m_patternConverters">
+ <summary>
+ Internal map of converter identifiers to converter types
+ </summary>
+ <remarks>
+ <para>
+ This map overrides the static s_globalRulesRegistry map.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Util.PatternParser.PatternConverters">
+ <summary>
+ Get the converter registry used by this parser
+ </summary>
+ <value>
+ The converter registry used by this parser
+ </value>
+ <remarks>
+ <para>
+ Get the converter registry used by this parser
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Util.PatternParser.StringLengthComparer">
+ <summary>
+ Sort strings by length
+ </summary>
+ <remarks>
+ <para>
+ <see cref="T:System.Collections.IComparer"/> that orders strings by string length.
+ The longest strings are placed first
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Util.PatternString">
+ <summary>
+ This class implements a patterned string.
+ </summary>
+ <remarks>
+ <para>
+ This string has embedded patterns that are resolved and expanded
+ when the string is formatted.
+ </para>
+ <para>
+ This class functions similarly to the <see cref="T:log4net.Layout.PatternLayout"/>
+ in that it accepts a pattern and renders it to a string. Unlike the
+ <see cref="T:log4net.Layout.PatternLayout"/> however the <c>PatternString</c>
+ does not render the properties of a specific <see cref="T:log4net.Core.LoggingEvent"/> but
+ of the process in general.
+ </para>
+ <para>
+ The recognized conversion pattern names are:
+ </para>
+ <list type="table">
+ <listheader>
+ <term>Conversion Pattern Name</term>
+ <description>Effect</description>
+ </listheader>
+ <item>
+ <term>appdomain</term>
+ <description>
+ <para>
+ Used to output the friendly name of the current AppDomain.
+ </para>
+ </description>
+ </item>
+ <item>
+ <term>date</term>
+ <description>
+ <para>
+ Used to output the date of the logging event in the local time zone.
+ To output the date in universal time use the <c>%utcdate</c> pattern.
+ The date conversion
+ specifier may be followed by a <i>date format specifier</i> enclosed
+ between braces. For example, <b>%date{HH:mm:ss,fff}</b> or
+ <b>%date{dd MMM yyyy HH:mm:ss,fff}</b>. If no date format specifier is
+ given then ISO8601 format is
+ assumed (<see cref="T:log4net.DateFormatter.Iso8601DateFormatter"/>).
+ </para>
+ <para>
+ The date format specifier admits the same syntax as the
+ time pattern string of the <see cref="M:System.DateTime.ToString(System.String)"/>.
+ </para>
+ <para>
+ For better results it is recommended to use the log4net date
+ formatters. These can be specified using one of the strings
+ "ABSOLUTE", "DATE" and "ISO8601" for specifying
+ <see cref="T:log4net.DateFormatter.AbsoluteTimeDateFormatter"/>,
+ <see cref="T:log4net.DateFormatter.DateTimeDateFormatter"/> and respectively
+ <see cref="T:log4net.DateFormatter.Iso8601DateFormatter"/>. For example,
+ <b>%date{ISO8601}</b> or <b>%date{ABSOLUTE}</b>.
+ </para>
+ <para>
+ These dedicated date formatters perform significantly
+ better than <see cref="M:System.DateTime.ToString(System.String)"/>.
+ </para>
+ </description>
+ </item>
+ <item>
+ <term>env</term>
+ <description>
+ <para>
+ Used to output the a specific environment variable. The key to
+ lookup must be specified within braces and directly following the
+ pattern specifier, e.g. <b>%env{COMPUTERNAME}</b> would include the value
+ of the <c>COMPUTERNAME</c> environment variable.
+ </para>
+ <para>
+ The <c>env</c> pattern is not supported on the .NET Compact Framework.
+ </para>
+ </description>
+ </item>
+ <item>
+ <term>identity</term>
+ <description>
+ <para>
+ Used to output the user name for the currently active user
+ (Principal.Identity.Name).
+ </para>
+ </description>
+ </item>
+ <item>
+ <term>newline</term>
+ <description>
+ <para>
+ Outputs the platform dependent line separator character or
+ characters.
+ </para>
+ <para>
+ This conversion pattern name offers the same performance as using
+ non-portable line separator strings such as "\n", or "\r\n".
+ Thus, it is the preferred way of specifying a line separator.
+ </para>
+ </description>
+ </item>
+ <item>
+ <term>processid</term>
+ <description>
+ <para>
+ Used to output the system process ID for the current process.
+ </para>
+ </description>
+ </item>
+ <item>
+ <term>property</term>
+ <description>
+ <para>
+ Used to output a specific context property. The key to
+ lookup must be specified within braces and directly following the
+ pattern specifier, e.g. <b>%property{user}</b> would include the value
+ from the property that is keyed by the string 'user'. Each property value
+ that is to be included in the log must be specified separately.
+ Properties are stored in logging contexts. By default
+ the <c>log4net:HostName</c> property is set to the name of machine on
+ which the event was originally logged.
+ </para>
+ <para>
+ If no key is specified, e.g. <b>%property</b> then all the keys and their
+ values are printed in a comma separated list.
+ </para>
+ <para>
+ The properties of an event are combined from a number of different
+ contexts. These are listed below in the order in which they are searched.
+ </para>
+ <list type="definition">
+ <item>
+ <term>the thread properties</term>
+ <description>
+ The <see cref="P:log4net.ThreadContext.Properties"/> that are set on the current
+ thread. These properties are shared by all events logged on this thread.
+ </description>
+ </item>
+ <item>
+ <term>the global properties</term>
+ <description>
+ The <see cref="P:log4net.GlobalContext.Properties"/> that are set globally. These
+ properties are shared by all the threads in the AppDomain.
+ </description>
+ </item>
+ </list>
+ </description>
+ </item>
+ <item>
+ <term>random</term>
+ <description>
+ <para>
+ Used to output a random string of characters. The string is made up of
+ uppercase letters and numbers. By default the string is 4 characters long.
+ The length of the string can be specified within braces directly following the
+ pattern specifier, e.g. <b>%random{8}</b> would output an 8 character string.
+ </para>
+ </description>
+ </item>
+ <item>
+ <term>username</term>
+ <description>
+ <para>
+ Used to output the WindowsIdentity for the currently
+ active user.
+ </para>
+ </description>
+ </item>
+ <item>
+ <term>utcdate</term>
+ <description>
+ <para>
+ Used to output the date of the logging event in universal time.
+ The date conversion
+ specifier may be followed by a <i>date format specifier</i> enclosed
+ between braces. For example, <b>%utcdate{HH:mm:ss,fff}</b> or
+ <b>%utcdate{dd MMM yyyy HH:mm:ss,fff}</b>. If no date format specifier is
+ given then ISO8601 format is
+ assumed (<see cref="T:log4net.DateFormatter.Iso8601DateFormatter"/>).
+ </para>
+ <para>
+ The date format specifier admits the same syntax as the
+ time pattern string of the <see cref="M:System.DateTime.ToString(System.String)"/>.
+ </para>
+ <para>
+ For better results it is recommended to use the log4net date
+ formatters. These can be specified using one of the strings
+ "ABSOLUTE", "DATE" and "ISO8601" for specifying
+ <see cref="T:log4net.DateFormatter.AbsoluteTimeDateFormatter"/>,
+ <see cref="T:log4net.DateFormatter.DateTimeDateFormatter"/> and respectively
+ <see cref="T:log4net.DateFormatter.Iso8601DateFormatter"/>. For example,
+ <b>%utcdate{ISO8601}</b> or <b>%utcdate{ABSOLUTE}</b>.
+ </para>
+ <para>
+ These dedicated date formatters perform significantly
+ better than <see cref="M:System.DateTime.ToString(System.String)"/>.
+ </para>
+ </description>
+ </item>
+ <item>
+ <term>%</term>
+ <description>
+ <para>
+ The sequence %% outputs a single percent sign.
+ </para>
+ </description>
+ </item>
+ </list>
+ <para>
+ Additional pattern converters may be registered with a specific <see cref="T:log4net.Util.PatternString"/>
+ instance using <see cref="M:log4net.Util.PatternString.AddConverter(log4net.Util.PatternString.ConverterInfo)"/> or
+ <see cref="M:log4net.Util.PatternString.AddConverter(System.String,System.Type)"/>.
+ </para>
+ <para>
+ See the <see cref="T:log4net.Layout.PatternLayout"/> for details on the
+ <i>format modifiers</i> supported by the patterns.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="F:log4net.Util.PatternString.s_globalRulesRegistry">
+ <summary>
+ Internal map of converter identifiers to converter types.
+ </summary>
+ </member>
+ <member name="F:log4net.Util.PatternString.m_pattern">
+ <summary>
+ the pattern
+ </summary>
+ </member>
+ <member name="F:log4net.Util.PatternString.m_head">
+ <summary>
+ the head of the pattern converter chain
+ </summary>
+ </member>
+ <member name="F:log4net.Util.PatternString.m_instanceRulesRegistry">
+ <summary>
+ patterns defined on this PatternString only
+ </summary>
+ </member>
+ <member name="M:log4net.Util.PatternString.#cctor">
+ <summary>
+ Initialize the global registry
+ </summary>
+ </member>
+ <member name="M:log4net.Util.PatternString.#ctor">
+ <summary>
+ Default constructor
+ </summary>
+ <remarks>
+ <para>
+ Initialize a new instance of <see cref="T:log4net.Util.PatternString"/>
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.PatternString.#ctor(System.String)">
+ <summary>
+ Constructs a PatternString
+ </summary>
+ <param name="pattern">The pattern to use with this PatternString</param>
+ <remarks>
+ <para>
+ Initialize a new instance of <see cref="T:log4net.Util.PatternString"/> with the pattern specified.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.PatternString.ActivateOptions">
+ <summary>
+ Initialize object options
+ </summary>
+ <remarks>
+ <para>
+ This is part of the <see cref="T:log4net.Core.IOptionHandler"/> delayed object
+ activation scheme. The <see cref="M:log4net.Util.PatternString.ActivateOptions"/> method must
+ be called on this object after the configuration properties have
+ been set. Until <see cref="M:log4net.Util.PatternString.ActivateOptions"/> is called this
+ object is in an undefined state and must not be used.
+ </para>
+ <para>
+ If any of the configuration properties are modified then
+ <see cref="M:log4net.Util.PatternString.ActivateOptions"/> must be called again.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.PatternString.CreatePatternParser(System.String)">
+ <summary>
+ Create the <see cref="T:log4net.Util.PatternParser"/> used to parse the pattern
+ </summary>
+ <param name="pattern">the pattern to parse</param>
+ <returns>The <see cref="T:log4net.Util.PatternParser"/></returns>
+ <remarks>
+ <para>
+ Returns PatternParser used to parse the conversion string. Subclasses
+ may override this to return a subclass of PatternParser which recognize
+ custom conversion pattern name.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.PatternString.Format(System.IO.TextWriter)">
+ <summary>
+ Produces a formatted string as specified by the conversion pattern.
+ </summary>
+ <param name="writer">The TextWriter to write the formatted event to</param>
+ <remarks>
+ <para>
+ Format the pattern to the <paramref name="writer"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.PatternString.Format">
+ <summary>
+ Format the pattern as a string
+ </summary>
+ <returns>the pattern formatted as a string</returns>
+ <remarks>
+ <para>
+ Format the pattern to a string.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.PatternString.AddConverter(log4net.Util.PatternString.ConverterInfo)">
+ <summary>
+ Add a converter to this PatternString
+ </summary>
+ <param name="converterInfo">the converter info</param>
+ <remarks>
+ <para>
+ This version of the method is used by the configurator.
+ Programmatic users should use the alternative <see cref="M:log4net.Util.PatternString.AddConverter(System.String,System.Type)"/> method.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.PatternString.AddConverter(System.String,System.Type)">
+ <summary>
+ Add a converter to this PatternString
+ </summary>
+ <param name="name">the name of the conversion pattern for this converter</param>
+ <param name="type">the type of the converter</param>
+ <remarks>
+ <para>
+ Add a converter to this PatternString
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Util.PatternString.ConversionPattern">
+ <summary>
+ Gets or sets the pattern formatting string
+ </summary>
+ <value>
+ The pattern formatting string
+ </value>
+ <remarks>
+ <para>
+ The <b>ConversionPattern</b> option. This is the string which
+ controls formatting and consists of a mix of literal content and
+ conversion specifiers.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Util.PatternString.ConverterInfo">
+ <summary>
+ Wrapper class used to map converter names to converter types
+ </summary>
+ <remarks>
+ <para>
+ Wrapper class used to map converter names to converter types
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.PatternString.ConverterInfo.#ctor">
+ <summary>
+ default constructor
+ </summary>
+ </member>
+ <member name="P:log4net.Util.PatternString.ConverterInfo.Name">
+ <summary>
+ Gets or sets the name of the conversion pattern
+ </summary>
+ <value>
+ The name of the conversion pattern
+ </value>
+ <remarks>
+ <para>
+ Gets or sets the name of the conversion pattern
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Util.PatternString.ConverterInfo.Type">
+ <summary>
+ Gets or sets the type of the converter
+ </summary>
+ <value>
+ The type of the converter
+ </value>
+ <remarks>
+ <para>
+ Gets or sets the type of the converter
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Util.PropertiesDictionary">
+ <summary>
+ String keyed object map.
+ </summary>
+ <remarks>
+ <para>
+ While this collection is serializable only member
+ objects that are serializable will
+ be serialized along with this collection.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="T:log4net.Util.ReadOnlyPropertiesDictionary">
+ <summary>
+ String keyed object map that is read only.
+ </summary>
+ <remarks>
+ <para>
+ This collection is readonly and cannot be modified.
+ </para>
+ <para>
+ While this collection is serializable only member
+ objects that are serializable will
+ be serialized along with this collection.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="F:log4net.Util.ReadOnlyPropertiesDictionary.m_hashtable">
+ <summary>
+ The Hashtable used to store the properties data
+ </summary>
+ </member>
+ <member name="M:log4net.Util.ReadOnlyPropertiesDictionary.#ctor">
+ <summary>
+ Constructor
+ </summary>
+ <remarks>
+ <para>
+ Initializes a new instance of the <see cref="T:log4net.Util.ReadOnlyPropertiesDictionary"/> class.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.ReadOnlyPropertiesDictionary.#ctor(log4net.Util.ReadOnlyPropertiesDictionary)">
+ <summary>
+ Copy Constructor
+ </summary>
+ <param name="propertiesDictionary">properties to copy</param>
+ <remarks>
+ <para>
+ Initializes a new instance of the <see cref="T:log4net.Util.ReadOnlyPropertiesDictionary"/> class.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.ReadOnlyPropertiesDictionary.#ctor(System.Runtime.Serialization.SerializationInfo,System.Runtime.Serialization.StreamingContext)">
+ <summary>
+ Deserialization constructor
+ </summary>
+ <param name="info">The <see cref="T:System.Runtime.Serialization.SerializationInfo"/> that holds the serialized object data.</param>
+ <param name="context">The <see cref="T:System.Runtime.Serialization.StreamingContext"/> that contains contextual information about the source or destination.</param>
+ <remarks>
+ <para>
+ Initializes a new instance of the <see cref="T:log4net.Util.ReadOnlyPropertiesDictionary"/> class
+ with serialized data.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.ReadOnlyPropertiesDictionary.GetKeys">
+ <summary>
+ Gets the key names.
+ </summary>
+ <returns>An array of all the keys.</returns>
+ <remarks>
+ <para>
+ Gets the key names.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.ReadOnlyPropertiesDictionary.Contains(System.String)">
+ <summary>
+ Test if the dictionary contains a specified key
+ </summary>
+ <param name="key">the key to look for</param>
+ <returns>true if the dictionary contains the specified key</returns>
+ <remarks>
+ <para>
+ Test if the dictionary contains a specified key
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.ReadOnlyPropertiesDictionary.GetObjectData(System.Runtime.Serialization.SerializationInfo,System.Runtime.Serialization.StreamingContext)">
+ <summary>
+ Serializes this object into the <see cref="T:System.Runtime.Serialization.SerializationInfo"/> provided.
+ </summary>
+ <param name="info">The <see cref="T:System.Runtime.Serialization.SerializationInfo"/> to populate with data.</param>
+ <param name="context">The destination for this serialization.</param>
+ <remarks>
+ <para>
+ Serializes this object into the <see cref="T:System.Runtime.Serialization.SerializationInfo"/> provided.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.ReadOnlyPropertiesDictionary.System#Collections#IDictionary#GetEnumerator">
+ <summary>
+ See <see cref="M:System.Collections.IDictionary.GetEnumerator"/>
+ </summary>
+ </member>
+ <member name="M:log4net.Util.ReadOnlyPropertiesDictionary.System#Collections#IDictionary#Remove(System.Object)">
+ <summary>
+ See <see cref="M:System.Collections.IDictionary.Remove(System.Object)"/>
+ </summary>
+ <param name="key"></param>
+ </member>
+ <member name="M:log4net.Util.ReadOnlyPropertiesDictionary.System#Collections#IDictionary#Contains(System.Object)">
+ <summary>
+ See <see cref="M:System.Collections.IDictionary.Contains(System.Object)"/>
+ </summary>
+ <param name="key"></param>
+ <returns></returns>
+ </member>
+ <member name="M:log4net.Util.ReadOnlyPropertiesDictionary.Clear">
+ <summary>
+ Remove all properties from the properties collection
+ </summary>
+ </member>
+ <member name="M:log4net.Util.ReadOnlyPropertiesDictionary.System#Collections#IDictionary#Add(System.Object,System.Object)">
+ <summary>
+ See <see cref="M:System.Collections.IDictionary.Add(System.Object,System.Object)"/>
+ </summary>
+ <param name="key"></param>
+ <param name="value"></param>
+ </member>
+ <member name="M:log4net.Util.ReadOnlyPropertiesDictionary.System#Collections#ICollection#CopyTo(System.Array,System.Int32)">
+ <summary>
+ See <see cref="M:System.Collections.ICollection.CopyTo(System.Array,System.Int32)"/>
+ </summary>
+ <param name="array"></param>
+ <param name="index"></param>
+ </member>
+ <member name="M:log4net.Util.ReadOnlyPropertiesDictionary.System#Collections#IEnumerable#GetEnumerator">
+ <summary>
+ See <see cref="M:System.Collections.IEnumerable.GetEnumerator"/>
+ </summary>
+ </member>
+ <member name="P:log4net.Util.ReadOnlyPropertiesDictionary.Item(System.String)">
+ <summary>
+ Gets or sets the value of the property with the specified key.
+ </summary>
+ <value>
+ The value of the property with the specified key.
+ </value>
+ <param name="key">The key of the property to get or set.</param>
+ <remarks>
+ <para>
+ The property value will only be serialized if it is serializable.
+ If it cannot be serialized it will be silently ignored if
+ a serialization operation is performed.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Util.ReadOnlyPropertiesDictionary.InnerHashtable">
+ <summary>
+ The hashtable used to store the properties
+ </summary>
+ <value>
+ The internal collection used to store the properties
+ </value>
+ <remarks>
+ <para>
+ The hashtable used to store the properties
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Util.ReadOnlyPropertiesDictionary.System#Collections#IDictionary#IsReadOnly">
+ <summary>
+ See <see cref="P:System.Collections.IDictionary.IsReadOnly"/>
+ </summary>
+ </member>
+ <member name="P:log4net.Util.ReadOnlyPropertiesDictionary.System#Collections#IDictionary#Item(System.Object)">
+ <summary>
+ See <see cref="P:System.Collections.IDictionary.Item(System.Object)"/>
+ </summary>
+ </member>
+ <member name="P:log4net.Util.ReadOnlyPropertiesDictionary.System#Collections#IDictionary#Values">
+ <summary>
+ See <see cref="P:System.Collections.IDictionary.Values"/>
+ </summary>
+ </member>
+ <member name="P:log4net.Util.ReadOnlyPropertiesDictionary.System#Collections#IDictionary#Keys">
+ <summary>
+ See <see cref="P:System.Collections.IDictionary.Keys"/>
+ </summary>
+ </member>
+ <member name="P:log4net.Util.ReadOnlyPropertiesDictionary.System#Collections#IDictionary#IsFixedSize">
+ <summary>
+ See <see cref="P:System.Collections.IDictionary.IsFixedSize"/>
+ </summary>
+ </member>
+ <member name="P:log4net.Util.ReadOnlyPropertiesDictionary.System#Collections#ICollection#IsSynchronized">
+ <summary>
+ See <see cref="P:System.Collections.ICollection.IsSynchronized"/>
+ </summary>
+ </member>
+ <member name="P:log4net.Util.ReadOnlyPropertiesDictionary.Count">
+ <summary>
+ The number of properties in this collection
+ </summary>
+ </member>
+ <member name="P:log4net.Util.ReadOnlyPropertiesDictionary.System#Collections#ICollection#SyncRoot">
+ <summary>
+ See <see cref="P:System.Collections.ICollection.SyncRoot"/>
+ </summary>
+ </member>
+ <member name="M:log4net.Util.PropertiesDictionary.#ctor">
+ <summary>
+ Constructor
+ </summary>
+ <remarks>
+ <para>
+ Initializes a new instance of the <see cref="T:log4net.Util.PropertiesDictionary"/> class.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.PropertiesDictionary.#ctor(log4net.Util.ReadOnlyPropertiesDictionary)">
+ <summary>
+ Constructor
+ </summary>
+ <param name="propertiesDictionary">properties to copy</param>
+ <remarks>
+ <para>
+ Initializes a new instance of the <see cref="T:log4net.Util.PropertiesDictionary"/> class.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.PropertiesDictionary.#ctor(System.Runtime.Serialization.SerializationInfo,System.Runtime.Serialization.StreamingContext)">
+ <summary>
+ Initializes a new instance of the <see cref="T:log4net.Util.PropertiesDictionary"/> class
+ with serialized data.
+ </summary>
+ <param name="info">The <see cref="T:System.Runtime.Serialization.SerializationInfo"/> that holds the serialized object data.</param>
+ <param name="context">The <see cref="T:System.Runtime.Serialization.StreamingContext"/> that contains contextual information about the source or destination.</param>
+ <remarks>
+ <para>
+ Because this class is sealed the serialization constructor is private.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.PropertiesDictionary.Remove(System.String)">
+ <summary>
+ Remove the entry with the specified key from this dictionary
+ </summary>
+ <param name="key">the key for the entry to remove</param>
+ <remarks>
+ <para>
+ Remove the entry with the specified key from this dictionary
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.PropertiesDictionary.System#Collections#IDictionary#GetEnumerator">
+ <summary>
+ See <see cref="M:System.Collections.IDictionary.GetEnumerator"/>
+ </summary>
+ <returns>an enumerator</returns>
+ <remarks>
+ <para>
+ Returns a <see cref="T:System.Collections.IDictionaryEnumerator"/> over the contest of this collection.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.PropertiesDictionary.System#Collections#IDictionary#Remove(System.Object)">
+ <summary>
+ See <see cref="M:System.Collections.IDictionary.Remove(System.Object)"/>
+ </summary>
+ <param name="key">the key to remove</param>
+ <remarks>
+ <para>
+ Remove the entry with the specified key from this dictionary
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.PropertiesDictionary.System#Collections#IDictionary#Contains(System.Object)">
+ <summary>
+ See <see cref="M:System.Collections.IDictionary.Contains(System.Object)"/>
+ </summary>
+ <param name="key">the key to lookup in the collection</param>
+ <returns><c>true</c> if the collection contains the specified key</returns>
+ <remarks>
+ <para>
+ Test if this collection contains a specified key.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.PropertiesDictionary.Clear">
+ <summary>
+ Remove all properties from the properties collection
+ </summary>
+ <remarks>
+ <para>
+ Remove all properties from the properties collection
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.PropertiesDictionary.System#Collections#IDictionary#Add(System.Object,System.Object)">
+ <summary>
+ See <see cref="M:System.Collections.IDictionary.Add(System.Object,System.Object)"/>
+ </summary>
+ <param name="key">the key</param>
+ <param name="value">the value to store for the key</param>
+ <remarks>
+ <para>
+ Store a value for the specified <see cref="T:System.String"/> <paramref name="key"/>.
+ </para>
+ </remarks>
+ <exception cref="T:System.ArgumentException">Thrown if the <paramref name="key"/> is not a string</exception>
+ </member>
+ <member name="M:log4net.Util.PropertiesDictionary.System#Collections#ICollection#CopyTo(System.Array,System.Int32)">
+ <summary>
+ See <see cref="M:System.Collections.ICollection.CopyTo(System.Array,System.Int32)"/>
+ </summary>
+ <param name="array"></param>
+ <param name="index"></param>
+ </member>
+ <member name="M:log4net.Util.PropertiesDictionary.System#Collections#IEnumerable#GetEnumerator">
+ <summary>
+ See <see cref="M:System.Collections.IEnumerable.GetEnumerator"/>
+ </summary>
+ </member>
+ <member name="P:log4net.Util.PropertiesDictionary.Item(System.String)">
+ <summary>
+ Gets or sets the value of the property with the specified key.
+ </summary>
+ <value>
+ The value of the property with the specified key.
+ </value>
+ <param name="key">The key of the property to get or set.</param>
+ <remarks>
+ <para>
+ The property value will only be serialized if it is serializable.
+ If it cannot be serialized it will be silently ignored if
+ a serialization operation is performed.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Util.PropertiesDictionary.System#Collections#IDictionary#IsReadOnly">
+ <summary>
+ See <see cref="P:System.Collections.IDictionary.IsReadOnly"/>
+ </summary>
+ <value>
+ <c>false</c>
+ </value>
+ <remarks>
+ <para>
+ This collection is modifiable. This property always
+ returns <c>false</c>.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Util.PropertiesDictionary.System#Collections#IDictionary#Item(System.Object)">
+ <summary>
+ See <see cref="P:System.Collections.IDictionary.Item(System.Object)"/>
+ </summary>
+ <value>
+ The value for the key specified.
+ </value>
+ <remarks>
+ <para>
+ Get or set a value for the specified <see cref="T:System.String"/> <paramref name="key"/>.
+ </para>
+ </remarks>
+ <exception cref="T:System.ArgumentException">Thrown if the <paramref name="key"/> is not a string</exception>
+ </member>
+ <member name="P:log4net.Util.PropertiesDictionary.System#Collections#IDictionary#Values">
+ <summary>
+ See <see cref="P:System.Collections.IDictionary.Values"/>
+ </summary>
+ </member>
+ <member name="P:log4net.Util.PropertiesDictionary.System#Collections#IDictionary#Keys">
+ <summary>
+ See <see cref="P:System.Collections.IDictionary.Keys"/>
+ </summary>
+ </member>
+ <member name="P:log4net.Util.PropertiesDictionary.System#Collections#IDictionary#IsFixedSize">
+ <summary>
+ See <see cref="P:System.Collections.IDictionary.IsFixedSize"/>
+ </summary>
+ </member>
+ <member name="P:log4net.Util.PropertiesDictionary.System#Collections#ICollection#IsSynchronized">
+ <summary>
+ See <see cref="P:System.Collections.ICollection.IsSynchronized"/>
+ </summary>
+ </member>
+ <member name="P:log4net.Util.PropertiesDictionary.System#Collections#ICollection#SyncRoot">
+ <summary>
+ See <see cref="P:System.Collections.ICollection.SyncRoot"/>
+ </summary>
+ </member>
+ <member name="T:log4net.Util.ProtectCloseTextWriter">
+ <summary>
+ A <see cref="T:System.IO.TextWriter"/> that ignores the <see cref="M:log4net.Util.ProtectCloseTextWriter.Close"/> message
+ </summary>
+ <remarks>
+ <para>
+ This writer is used in special cases where it is necessary
+ to protect a writer from being closed by a client.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="M:log4net.Util.ProtectCloseTextWriter.#ctor(System.IO.TextWriter)">
+ <summary>
+ Constructor
+ </summary>
+ <param name="writer">the writer to actually write to</param>
+ <remarks>
+ <para>
+ Create a new ProtectCloseTextWriter using a writer
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.ProtectCloseTextWriter.Attach(System.IO.TextWriter)">
+ <summary>
+ Attach this instance to a different underlying <see cref="T:System.IO.TextWriter"/>
+ </summary>
+ <param name="writer">the writer to attach to</param>
+ <remarks>
+ <para>
+ Attach this instance to a different underlying <see cref="T:System.IO.TextWriter"/>
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.ProtectCloseTextWriter.Close">
+ <summary>
+ Does not close the underlying output writer.
+ </summary>
+ <remarks>
+ <para>
+ Does not close the underlying output writer.
+ This method does nothing.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Util.ReaderWriterLock">
+ <summary>
+ Defines a lock that supports single writers and multiple readers
+ </summary>
+ <remarks>
+ <para>
+ <c>ReaderWriterLock</c> is used to synchronize access to a resource.
+ At any given time, it allows either concurrent read access for
+ multiple threads, or write access for a single thread. In a
+ situation where a resource is changed infrequently, a
+ <c>ReaderWriterLock</c> provides better throughput than a simple
+ one-at-a-time lock, such as <see cref="T:System.Threading.Monitor"/>.
+ </para>
+ <para>
+ If a platform does not support a <c>System.Threading.ReaderWriterLock</c>
+ implementation then all readers and writers are serialized. Therefore
+ the caller must not rely on multiple simultaneous readers.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="M:log4net.Util.ReaderWriterLock.#ctor">
+ <summary>
+ Constructor
+ </summary>
+ <remarks>
+ <para>
+ Initializes a new instance of the <see cref="T:log4net.Util.ReaderWriterLock"/> class.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.ReaderWriterLock.AcquireReaderLock">
+ <summary>
+ Acquires a reader lock
+ </summary>
+ <remarks>
+ <para>
+ <see cref="M:log4net.Util.ReaderWriterLock.AcquireReaderLock"/> blocks if a different thread has the writer
+ lock, or if at least one thread is waiting for the writer lock.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.ReaderWriterLock.ReleaseReaderLock">
+ <summary>
+ Decrements the lock count
+ </summary>
+ <remarks>
+ <para>
+ <see cref="M:log4net.Util.ReaderWriterLock.ReleaseReaderLock"/> decrements the lock count. When the count
+ reaches zero, the lock is released.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.ReaderWriterLock.AcquireWriterLock">
+ <summary>
+ Acquires the writer lock
+ </summary>
+ <remarks>
+ <para>
+ This method blocks if another thread has a reader lock or writer lock.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.ReaderWriterLock.ReleaseWriterLock">
+ <summary>
+ Decrements the lock count on the writer lock
+ </summary>
+ <remarks>
+ <para>
+ ReleaseWriterLock decrements the writer lock count.
+ When the count reaches zero, the writer lock is released.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Util.ReusableStringWriter">
+ <summary>
+ A <see cref="T:System.IO.StringWriter"/> that can be <see cref="M:log4net.Util.ReusableStringWriter.Reset(System.Int32,System.Int32)"/> and reused
+ </summary>
+ <remarks>
+ <para>
+ A <see cref="T:System.IO.StringWriter"/> that can be <see cref="M:log4net.Util.ReusableStringWriter.Reset(System.Int32,System.Int32)"/> and reused.
+ This uses a single buffer for string operations.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="M:log4net.Util.ReusableStringWriter.#ctor(System.IFormatProvider)">
+ <summary>
+ Create an instance of <see cref="T:log4net.Util.ReusableStringWriter"/>
+ </summary>
+ <param name="formatProvider">the format provider to use</param>
+ <remarks>
+ <para>
+ Create an instance of <see cref="T:log4net.Util.ReusableStringWriter"/>
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.ReusableStringWriter.Dispose(System.Boolean)">
+ <summary>
+ Override Dispose to prevent closing of writer
+ </summary>
+ <param name="disposing">flag</param>
+ <remarks>
+ <para>
+ Override Dispose to prevent closing of writer
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.ReusableStringWriter.Reset(System.Int32,System.Int32)">
+ <summary>
+ Reset this string writer so that it can be reused.
+ </summary>
+ <param name="maxCapacity">the maximum buffer capacity before it is trimmed</param>
+ <param name="defaultSize">the default size to make the buffer</param>
+ <remarks>
+ <para>
+ Reset this string writer so that it can be reused.
+ The internal buffers are cleared and reset.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Util.SystemInfo">
+ <summary>
+ Utility class for system specific information.
+ </summary>
+ <remarks>
+ <para>
+ Utility class of static methods for system specific information.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ <author>Alexey Solofnenko</author>
+ </member>
+ <member name="M:log4net.Util.SystemInfo.#ctor">
+ <summary>
+ Private constructor to prevent instances.
+ </summary>
+ <remarks>
+ <para>
+ Only static methods are exposed from this type.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.SystemInfo.#cctor">
+ <summary>
+ Initialize default values for private static fields.
+ </summary>
+ <remarks>
+ <para>
+ Only static methods are exposed from this type.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.SystemInfo.AssemblyLocationInfo(System.Reflection.Assembly)">
+ <summary>
+ Gets the assembly location path for the specified assembly.
+ </summary>
+ <param name="myAssembly">The assembly to get the location for.</param>
+ <returns>The location of the assembly.</returns>
+ <remarks>
+ <para>
+ This method does not guarantee to return the correct path
+ to the assembly. If only tries to give an indication as to
+ where the assembly was loaded from.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.SystemInfo.AssemblyQualifiedName(System.Type)">
+ <summary>
+ Gets the fully qualified name of the <see cref="T:System.Type"/>, including
+ the name of the assembly from which the <see cref="T:System.Type"/> was
+ loaded.
+ </summary>
+ <param name="type">The <see cref="T:System.Type"/> to get the fully qualified name for.</param>
+ <returns>The fully qualified name for the <see cref="T:System.Type"/>.</returns>
+ <remarks>
+ <para>
+ This is equivalent to the <c>Type.AssemblyQualifiedName</c> property,
+ but this method works on the .NET Compact Framework 1.0 as well as
+ the full .NET runtime.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.SystemInfo.AssemblyShortName(System.Reflection.Assembly)">
+ <summary>
+ Gets the short name of the <see cref="T:System.Reflection.Assembly"/>.
+ </summary>
+ <param name="myAssembly">The <see cref="T:System.Reflection.Assembly"/> to get the name for.</param>
+ <returns>The short name of the <see cref="T:System.Reflection.Assembly"/>.</returns>
+ <remarks>
+ <para>
+ The short name of the assembly is the <see cref="P:System.Reflection.Assembly.FullName"/>
+ without the version, culture, or public key. i.e. it is just the
+ assembly's file name without the extension.
+ </para>
+ <para>
+ Use this rather than <c>Assembly.GetName().Name</c> because that
+ is not available on the Compact Framework.
+ </para>
+ <para>
+ Because of a FileIOPermission security demand we cannot do
+ the obvious Assembly.GetName().Name. We are allowed to get
+ the <see cref="P:System.Reflection.Assembly.FullName"/> of the assembly so we
+ start from there and strip out just the assembly name.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.SystemInfo.AssemblyFileName(System.Reflection.Assembly)">
+ <summary>
+ Gets the file name portion of the <see cref="T:System.Reflection.Assembly"/>, including the extension.
+ </summary>
+ <param name="myAssembly">The <see cref="T:System.Reflection.Assembly"/> to get the file name for.</param>
+ <returns>The file name of the assembly.</returns>
+ <remarks>
+ <para>
+ Gets the file name portion of the <see cref="T:System.Reflection.Assembly"/>, including the extension.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.SystemInfo.GetTypeFromString(System.Type,System.String,System.Boolean,System.Boolean)">
+ <summary>
+ Loads the type specified in the type string.
+ </summary>
+ <param name="relativeType">A sibling type to use to load the type.</param>
+ <param name="typeName">The name of the type to load.</param>
+ <param name="throwOnError">Flag set to <c>true</c> to throw an exception if the type cannot be loaded.</param>
+ <param name="ignoreCase"><c>true</c> to ignore the case of the type name; otherwise, <c>false</c></param>
+ <returns>The type loaded or <c>null</c> if it could not be loaded.</returns>
+ <remarks>
+ <para>
+ If the type name is fully qualified, i.e. if contains an assembly name in
+ the type name, the type will be loaded from the system using
+ <see cref="M:System.Type.GetType(System.String,System.Boolean)"/>.
+ </para>
+ <para>
+ If the type name is not fully qualified, it will be loaded from the assembly
+ containing the specified relative type. If the type is not found in the assembly
+ then all the loaded assemblies will be searched for the type.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.SystemInfo.GetTypeFromString(System.String,System.Boolean,System.Boolean)">
+ <summary>
+ Loads the type specified in the type string.
+ </summary>
+ <param name="typeName">The name of the type to load.</param>
+ <param name="throwOnError">Flag set to <c>true</c> to throw an exception if the type cannot be loaded.</param>
+ <param name="ignoreCase"><c>true</c> to ignore the case of the type name; otherwise, <c>false</c></param>
+ <returns>The type loaded or <c>null</c> if it could not be loaded.</returns>
+ <remarks>
+ <para>
+ If the type name is fully qualified, i.e. if contains an assembly name in
+ the type name, the type will be loaded from the system using
+ <see cref="M:System.Type.GetType(System.String,System.Boolean)"/>.
+ </para>
+ <para>
+ If the type name is not fully qualified it will be loaded from the
+ assembly that is directly calling this method. If the type is not found
+ in the assembly then all the loaded assemblies will be searched for the type.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.SystemInfo.GetTypeFromString(System.Reflection.Assembly,System.String,System.Boolean,System.Boolean)">
+ <summary>
+ Loads the type specified in the type string.
+ </summary>
+ <param name="relativeAssembly">An assembly to load the type from.</param>
+ <param name="typeName">The name of the type to load.</param>
+ <param name="throwOnError">Flag set to <c>true</c> to throw an exception if the type cannot be loaded.</param>
+ <param name="ignoreCase"><c>true</c> to ignore the case of the type name; otherwise, <c>false</c></param>
+ <returns>The type loaded or <c>null</c> if it could not be loaded.</returns>
+ <remarks>
+ <para>
+ If the type name is fully qualified, i.e. if contains an assembly name in
+ the type name, the type will be loaded from the system using
+ <see cref="M:System.Type.GetType(System.String,System.Boolean)"/>.
+ </para>
+ <para>
+ If the type name is not fully qualified it will be loaded from the specified
+ assembly. If the type is not found in the assembly then all the loaded assemblies
+ will be searched for the type.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.SystemInfo.NewGuid">
+ <summary>
+ Generate a new guid
+ </summary>
+ <returns>A new Guid</returns>
+ <remarks>
+ <para>
+ Generate a new guid
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.SystemInfo.CreateArgumentOutOfRangeException(System.String,System.Object,System.String)">
+ <summary>
+ Create an <see cref="T:System.ArgumentOutOfRangeException"/>
+ </summary>
+ <param name="parameterName">The name of the parameter that caused the exception</param>
+ <param name="actualValue">The value of the argument that causes this exception</param>
+ <param name="message">The message that describes the error</param>
+ <returns>the ArgumentOutOfRangeException object</returns>
+ <remarks>
+ <para>
+ Create a new instance of the <see cref="T:System.ArgumentOutOfRangeException"/> class
+ with a specified error message, the parameter name, and the value
+ of the argument.
+ </para>
+ <para>
+ The Compact Framework does not support the 3 parameter constructor for the
+ <see cref="T:System.ArgumentOutOfRangeException"/> type. This method provides an
+ implementation that works for all platforms.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.SystemInfo.TryParse(System.String,System.Int32@)">
+ <summary>
+ Parse a string into an <see cref="T:System.Int32"/> value
+ </summary>
+ <param name="s">the string to parse</param>
+ <param name="val">out param where the parsed value is placed</param>
+ <returns><c>true</c> if the string was able to be parsed into an integer</returns>
+ <remarks>
+ <para>
+ Attempts to parse the string into an integer. If the string cannot
+ be parsed then this method returns <c>false</c>. The method does not throw an exception.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.SystemInfo.TryParse(System.String,System.Int64@)">
+ <summary>
+ Parse a string into an <see cref="T:System.Int64"/> value
+ </summary>
+ <param name="s">the string to parse</param>
+ <param name="val">out param where the parsed value is placed</param>
+ <returns><c>true</c> if the string was able to be parsed into an integer</returns>
+ <remarks>
+ <para>
+ Attempts to parse the string into an integer. If the string cannot
+ be parsed then this method returns <c>false</c>. The method does not throw an exception.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.SystemInfo.GetAppSetting(System.String)">
+ <summary>
+ Lookup an application setting
+ </summary>
+ <param name="key">the application settings key to lookup</param>
+ <returns>the value for the key, or <c>null</c></returns>
+ <remarks>
+ <para>
+ Configuration APIs are not supported under the Compact Framework
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.SystemInfo.ConvertToFullPath(System.String)">
+ <summary>
+ Convert a path into a fully qualified local file path.
+ </summary>
+ <param name="path">The path to convert.</param>
+ <returns>The fully qualified path.</returns>
+ <remarks>
+ <para>
+ Converts the path specified to a fully
+ qualified path. If the path is relative it is
+ taken as relative from the application base
+ directory.
+ </para>
+ <para>
+ The path specified must be a local file path, a URI is not supported.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.SystemInfo.CreateCaseInsensitiveHashtable">
+ <summary>
+ Creates a new case-insensitive instance of the <see cref="T:System.Collections.Hashtable"/> class with the default initial capacity.
+ </summary>
+ <returns>A new case-insensitive instance of the <see cref="T:System.Collections.Hashtable"/> class with the default initial capacity</returns>
+ <remarks>
+ <para>
+ The new Hashtable instance uses the default load factor, the CaseInsensitiveHashCodeProvider, and the CaseInsensitiveComparer.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Util.SystemInfo.EmptyTypes">
+ <summary>
+ Gets an empty array of types.
+ </summary>
+ <remarks>
+ <para>
+ The <c>Type.EmptyTypes</c> field is not available on
+ the .NET Compact Framework 1.0.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Util.SystemInfo.s_hostName">
+ <summary>
+ Cache the host name for the current machine
+ </summary>
+ </member>
+ <member name="F:log4net.Util.SystemInfo.s_appFriendlyName">
+ <summary>
+ Cache the application friendly name
+ </summary>
+ </member>
+ <member name="F:log4net.Util.SystemInfo.s_nullText">
+ <summary>
+ Text to output when a <c>null</c> is encountered.
+ </summary>
+ </member>
+ <member name="F:log4net.Util.SystemInfo.s_notAvailableText">
+ <summary>
+ Text to output when an unsupported feature is requested.
+ </summary>
+ </member>
+ <member name="F:log4net.Util.SystemInfo.s_processStartTime">
+ <summary>
+ Start time for the current process.
+ </summary>
+ </member>
+ <member name="P:log4net.Util.SystemInfo.NewLine">
+ <summary>
+ Gets the system dependent line terminator.
+ </summary>
+ <value>
+ The system dependent line terminator.
+ </value>
+ <remarks>
+ <para>
+ Gets the system dependent line terminator.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Util.SystemInfo.ApplicationBaseDirectory">
+ <summary>
+ Gets the base directory for this <see cref="T:System.AppDomain"/>.
+ </summary>
+ <value>The base directory path for the current <see cref="T:System.AppDomain"/>.</value>
+ <remarks>
+ <para>
+ Gets the base directory for this <see cref="T:System.AppDomain"/>.
+ </para>
+ <para>
+ The value returned may be either a local file path or a URI.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Util.SystemInfo.ConfigurationFileLocation">
+ <summary>
+ Gets the path to the configuration file for the current <see cref="T:System.AppDomain"/>.
+ </summary>
+ <value>The path to the configuration file for the current <see cref="T:System.AppDomain"/>.</value>
+ <remarks>
+ <para>
+ The .NET Compact Framework 1.0 does not have a concept of a configuration
+ file. For this runtime, we use the entry assembly location as the root for
+ the configuration file name.
+ </para>
+ <para>
+ The value returned may be either a local file path or a URI.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Util.SystemInfo.EntryAssemblyLocation">
+ <summary>
+ Gets the path to the file that first executed in the current <see cref="T:System.AppDomain"/>.
+ </summary>
+ <value>The path to the entry assembly.</value>
+ <remarks>
+ <para>
+ Gets the path to the file that first executed in the current <see cref="T:System.AppDomain"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Util.SystemInfo.CurrentThreadId">
+ <summary>
+ Gets the ID of the current thread.
+ </summary>
+ <value>The ID of the current thread.</value>
+ <remarks>
+ <para>
+ On the .NET framework, the <c>AppDomain.GetCurrentThreadId</c> method
+ is used to obtain the thread ID for the current thread. This is the
+ operating system ID for the thread.
+ </para>
+ <para>
+ On the .NET Compact Framework 1.0 it is not possible to get the
+ operating system thread ID for the current thread. The native method
+ <c>GetCurrentThreadId</c> is implemented inline in a header file
+ and cannot be called.
+ </para>
+ <para>
+ On the .NET Framework 2.0 the <c>Thread.ManagedThreadId</c> is used as this
+ gives a stable id unrelated to the operating system thread ID which may
+ change if the runtime is using fibers.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Util.SystemInfo.HostName">
+ <summary>
+ Get the host name or machine name for the current machine
+ </summary>
+ <value>
+ The hostname or machine name
+ </value>
+ <remarks>
+ <para>
+ Get the host name or machine name for the current machine
+ </para>
+ <para>
+ The host name (<see cref="M:System.Net.Dns.GetHostName"/>) or
+ the machine name (<c>Environment.MachineName</c>) for
+ the current machine, or if neither of these are available
+ then <c>NOT AVAILABLE</c> is returned.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Util.SystemInfo.ApplicationFriendlyName">
+ <summary>
+ Get this application's friendly name
+ </summary>
+ <value>
+ The friendly name of this application as a string
+ </value>
+ <remarks>
+ <para>
+ If available the name of the application is retrieved from
+ the <c>AppDomain</c> using <c>AppDomain.CurrentDomain.FriendlyName</c>.
+ </para>
+ <para>
+ Otherwise the file name of the entry assembly is used.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Util.SystemInfo.ProcessStartTime">
+ <summary>
+ Get the start time for the current process.
+ </summary>
+ <remarks>
+ <para>
+ This is the time at which the log4net library was loaded into the
+ AppDomain. Due to reports of a hang in the call to <c>System.Diagnostics.Process.StartTime</c>
+ this is not the start time for the current process.
+ </para>
+ <para>
+ The log4net library should be loaded by an application early during its
+ startup, therefore this start time should be a good approximation for
+ the actual start time.
+ </para>
+ <para>
+ Note that AppDomains may be loaded and unloaded within the
+ same process without the process terminating, however this start time
+ will be set per AppDomain.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Util.SystemInfo.NullText">
+ <summary>
+ Text to output when a <c>null</c> is encountered.
+ </summary>
+ <remarks>
+ <para>
+ Use this value to indicate a <c>null</c> has been encountered while
+ outputting a string representation of an item.
+ </para>
+ <para>
+ The default value is <c>(null)</c>. This value can be overridden by specifying
+ a value for the <c>log4net.NullText</c> appSetting in the application's
+ .config file.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Util.SystemInfo.NotAvailableText">
+ <summary>
+ Text to output when an unsupported feature is requested.
+ </summary>
+ <remarks>
+ <para>
+ Use this value when an unsupported feature is requested.
+ </para>
+ <para>
+ The default value is <c>NOT AVAILABLE</c>. This value can be overridden by specifying
+ a value for the <c>log4net.NotAvailableText</c> appSetting in the application's
+ .config file.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Util.SystemStringFormat">
+ <summary>
+ Utility class that represents a format string.
+ </summary>
+ <remarks>
+ <para>
+ Utility class that represents a format string.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="M:log4net.Util.SystemStringFormat.#ctor(System.IFormatProvider,System.String,System.Object[])">
+ <summary>
+ Initialise the <see cref="T:log4net.Util.SystemStringFormat"/>
+ </summary>
+ <param name="provider">An <see cref="T:System.IFormatProvider"/> that supplies culture-specific formatting information.</param>
+ <param name="format">A <see cref="T:System.String"/> containing zero or more format items.</param>
+ <param name="args">An <see cref="T:System.Object"/> array containing zero or more objects to format.</param>
+ </member>
+ <member name="M:log4net.Util.SystemStringFormat.ToString">
+ <summary>
+ Format the string and arguments
+ </summary>
+ <returns>the formatted string</returns>
+ </member>
+ <member name="M:log4net.Util.SystemStringFormat.StringFormat(System.IFormatProvider,System.String,System.Object[])">
+ <summary>
+ Replaces the format item in a specified <see cref="T:System.String"/> with the text equivalent
+ of the value of a corresponding <see cref="T:System.Object"/> instance in a specified array.
+ A specified parameter supplies culture-specific formatting information.
+ </summary>
+ <param name="provider">An <see cref="T:System.IFormatProvider"/> that supplies culture-specific formatting information.</param>
+ <param name="format">A <see cref="T:System.String"/> containing zero or more format items.</param>
+ <param name="args">An <see cref="T:System.Object"/> array containing zero or more objects to format.</param>
+ <returns>
+ A copy of format in which the format items have been replaced by the <see cref="T:System.String"/>
+ equivalent of the corresponding instances of <see cref="T:System.Object"/> in args.
+ </returns>
+ <remarks>
+ <para>
+ This method does not throw exceptions. If an exception thrown while formatting the result the
+ exception and arguments are returned in the result string.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.SystemStringFormat.StringFormatError(System.Exception,System.String,System.Object[])">
+ <summary>
+ Process an error during StringFormat
+ </summary>
+ </member>
+ <member name="M:log4net.Util.SystemStringFormat.RenderArray(System.Array,System.Text.StringBuilder)">
+ <summary>
+ Dump the contents of an array into a string builder
+ </summary>
+ </member>
+ <member name="M:log4net.Util.SystemStringFormat.RenderObject(System.Object,System.Text.StringBuilder)">
+ <summary>
+ Dump an object to a string
+ </summary>
+ </member>
+ <member name="T:log4net.Util.ThreadContextProperties">
+ <summary>
+ Implementation of Properties collection for the <see cref="T:log4net.ThreadContext"/>
+ </summary>
+ <remarks>
+ <para>
+ Class implements a collection of properties that is specific to each thread.
+ The class is not synchronized as each thread has its own <see cref="T:log4net.Util.PropertiesDictionary"/>.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="F:log4net.Util.ThreadContextProperties.s_threadLocalSlot">
+ <summary>
+ The thread local data slot to use to store a PropertiesDictionary.
+ </summary>
+ </member>
+ <member name="M:log4net.Util.ThreadContextProperties.#ctor">
+ <summary>
+ Internal constructor
+ </summary>
+ <remarks>
+ <para>
+ Initializes a new instance of the <see cref="T:log4net.Util.ThreadContextProperties"/> class.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.ThreadContextProperties.Remove(System.String)">
+ <summary>
+ Remove a property
+ </summary>
+ <param name="key">the key for the entry to remove</param>
+ <remarks>
+ <para>
+ Remove a property
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.ThreadContextProperties.Clear">
+ <summary>
+ Clear all properties
+ </summary>
+ <remarks>
+ <para>
+ Clear all properties
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.ThreadContextProperties.GetProperties(System.Boolean)">
+ <summary>
+ Get the <c>PropertiesDictionary</c> for this thread.
+ </summary>
+ <param name="create">create the dictionary if it does not exist, otherwise return null if is does not exist</param>
+ <returns>the properties for this thread</returns>
+ <remarks>
+ <para>
+ The collection returned is only to be used on the calling thread. If the
+ caller needs to share the collection between different threads then the
+ caller must clone the collection before doing so.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Util.ThreadContextProperties.Item(System.String)">
+ <summary>
+ Gets or sets the value of a property
+ </summary>
+ <value>
+ The value for the property with the specified key
+ </value>
+ <remarks>
+ <para>
+ Gets or sets the value of a property
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Util.ThreadContextStack">
+ <summary>
+ Implementation of Stack for the <see cref="T:log4net.ThreadContext"/>
+ </summary>
+ <remarks>
+ <para>
+ Implementation of Stack for the <see cref="T:log4net.ThreadContext"/>
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="F:log4net.Util.ThreadContextStack.m_stack">
+ <summary>
+ The stack store.
+ </summary>
+ </member>
+ <member name="M:log4net.Util.ThreadContextStack.#ctor">
+ <summary>
+ Internal constructor
+ </summary>
+ <remarks>
+ <para>
+ Initializes a new instance of the <see cref="T:log4net.Util.ThreadContextStack"/> class.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.ThreadContextStack.Clear">
+ <summary>
+ Clears all the contextual information held in this stack.
+ </summary>
+ <remarks>
+ <para>
+ Clears all the contextual information held in this stack.
+ Only call this if you think that this tread is being reused after
+ a previous call execution which may not have completed correctly.
+ You do not need to use this method if you always guarantee to call
+ the <see cref="M:System.IDisposable.Dispose"/> method of the <see cref="T:System.IDisposable"/>
+ returned from <see cref="M:log4net.Util.ThreadContextStack.Push(System.String)"/> even in exceptional circumstances,
+ for example by using the <c>using(log4net.ThreadContext.Stacks["NDC"].Push("Stack_Message"))</c>
+ syntax.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.ThreadContextStack.Pop">
+ <summary>
+ Removes the top context from this stack.
+ </summary>
+ <returns>The message in the context that was removed from the top of this stack.</returns>
+ <remarks>
+ <para>
+ Remove the top context from this stack, and return
+ it to the caller. If this stack is empty then an
+ empty string (not <see langword="null"/>) is returned.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.ThreadContextStack.Push(System.String)">
+ <summary>
+ Pushes a new context message into this stack.
+ </summary>
+ <param name="message">The new context message.</param>
+ <returns>
+ An <see cref="T:System.IDisposable"/> that can be used to clean up the context stack.
+ </returns>
+ <remarks>
+ <para>
+ Pushes a new context onto this stack. An <see cref="T:System.IDisposable"/>
+ is returned that can be used to clean up this stack. This
+ can be easily combined with the <c>using</c> keyword to scope the
+ context.
+ </para>
+ </remarks>
+ <example>Simple example of using the <c>Push</c> method with the <c>using</c> keyword.
+ <code lang="C#">
+ using(log4net.ThreadContext.Stacks["NDC"].Push("Stack_Message"))
+ {
+ log.Warn("This should have an ThreadContext Stack message");
+ }
+ </code>
+ </example>
+ </member>
+ <member name="M:log4net.Util.ThreadContextStack.GetFullMessage">
+ <summary>
+ Gets the current context information for this stack.
+ </summary>
+ <returns>The current context information.</returns>
+ </member>
+ <member name="M:log4net.Util.ThreadContextStack.ToString">
+ <summary>
+ Gets the current context information for this stack.
+ </summary>
+ <returns>Gets the current context information</returns>
+ <remarks>
+ <para>
+ Gets the current context information for this stack.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.ThreadContextStack.log4net#Core#IFixingRequired#GetFixedObject">
+ <summary>
+ Get a portable version of this object
+ </summary>
+ <returns>the portable instance of this object</returns>
+ <remarks>
+ <para>
+ Get a cross thread portable version of this object
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Util.ThreadContextStack.Count">
+ <summary>
+ The number of messages in the stack
+ </summary>
+ <value>
+ The current number of messages in the stack
+ </value>
+ <remarks>
+ <para>
+ The current number of messages in the stack. That is
+ the number of times <see cref="M:log4net.Util.ThreadContextStack.Push(System.String)"/> has been called
+ minus the number of times <see cref="M:log4net.Util.ThreadContextStack.Pop"/> has been called.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Util.ThreadContextStack.InternalStack">
+ <summary>
+ Gets and sets the internal stack used by this <see cref="T:log4net.Util.ThreadContextStack"/>
+ </summary>
+ <value>The internal storage stack</value>
+ <remarks>
+ <para>
+ This property is provided only to support backward compatability
+ of the <see cref="T:log4net.NDC"/>. Tytpically the internal stack should not
+ be modified.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Util.ThreadContextStack.StackFrame">
+ <summary>
+ Inner class used to represent a single context frame in the stack.
+ </summary>
+ <remarks>
+ <para>
+ Inner class used to represent a single context frame in the stack.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.ThreadContextStack.StackFrame.#ctor(System.String,log4net.Util.ThreadContextStack.StackFrame)">
+ <summary>
+ Constructor
+ </summary>
+ <param name="message">The message for this context.</param>
+ <param name="parent">The parent context in the chain.</param>
+ <remarks>
+ <para>
+ Initializes a new instance of the <see cref="T:log4net.Util.ThreadContextStack.StackFrame"/> class
+ with the specified message and parent context.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Util.ThreadContextStack.StackFrame.Message">
+ <summary>
+ Get the message.
+ </summary>
+ <value>The message.</value>
+ <remarks>
+ <para>
+ Get the message.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Util.ThreadContextStack.StackFrame.FullMessage">
+ <summary>
+ Gets the full text of the context down to the root level.
+ </summary>
+ <value>
+ The full text of the context down to the root level.
+ </value>
+ <remarks>
+ <para>
+ Gets the full text of the context down to the root level.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Util.ThreadContextStack.AutoPopStackFrame">
+ <summary>
+ Struct returned from the <see cref="M:log4net.Util.ThreadContextStack.Push(System.String)"/> method.
+ </summary>
+ <remarks>
+ <para>
+ This struct implements the <see cref="T:System.IDisposable"/> and is designed to be used
+ with the <see langword="using"/> pattern to remove the stack frame at the end of the scope.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Util.ThreadContextStack.AutoPopStackFrame.m_frameStack">
+ <summary>
+ The ThreadContextStack internal stack
+ </summary>
+ </member>
+ <member name="F:log4net.Util.ThreadContextStack.AutoPopStackFrame.m_frameDepth">
+ <summary>
+ The depth to trim the stack to when this instance is disposed
+ </summary>
+ </member>
+ <member name="M:log4net.Util.ThreadContextStack.AutoPopStackFrame.#ctor(System.Collections.Stack,System.Int32)">
+ <summary>
+ Constructor
+ </summary>
+ <param name="frameStack">The internal stack used by the ThreadContextStack.</param>
+ <param name="frameDepth">The depth to return the stack to when this object is disposed.</param>
+ <remarks>
+ <para>
+ Initializes a new instance of the <see cref="T:log4net.Util.ThreadContextStack.AutoPopStackFrame"/> class with
+ the specified stack and return depth.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.ThreadContextStack.AutoPopStackFrame.Dispose">
+ <summary>
+ Returns the stack to the correct depth.
+ </summary>
+ <remarks>
+ <para>
+ Returns the stack to the correct depth.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Util.ThreadContextStacks">
+ <summary>
+ Implementation of Stacks collection for the <see cref="T:log4net.ThreadContext"/>
+ </summary>
+ <remarks>
+ <para>
+ Implementation of Stacks collection for the <see cref="T:log4net.ThreadContext"/>
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="M:log4net.Util.ThreadContextStacks.#ctor(log4net.Util.ContextPropertiesBase)">
+ <summary>
+ Internal constructor
+ </summary>
+ <remarks>
+ <para>
+ Initializes a new instance of the <see cref="T:log4net.Util.ThreadContextStacks"/> class.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Util.ThreadContextStacks.Item(System.String)">
+ <summary>
+ Gets the named thread context stack
+ </summary>
+ <value>
+ The named stack
+ </value>
+ <remarks>
+ <para>
+ Gets the named thread context stack
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Util.Transform">
+ <summary>
+ Utility class for transforming strings.
+ </summary>
+ <remarks>
+ <para>
+ Utility class for transforming strings.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="M:log4net.Util.Transform.#ctor">
+ <summary>
+ Initializes a new instance of the <see cref="T:log4net.Util.Transform"/> class.
+ </summary>
+ <remarks>
+ <para>
+ Uses a private access modifier to prevent instantiation of this class.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.Transform.WriteEscapedXmlString(System.Xml.XmlWriter,System.String,System.String)">
+ <summary>
+ Write a string to an <see cref="T:System.Xml.XmlWriter"/>
+ </summary>
+ <param name="writer">the writer to write to</param>
+ <param name="textData">the string to write</param>
+ <param name="invalidCharReplacement">The string to replace non XML compliant chars with</param>
+ <remarks>
+ <para>
+ The test is escaped either using XML escape entities
+ or using CDATA sections.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.Transform.MaskXmlInvalidCharacters(System.String,System.String)">
+ <summary>
+ Replace invalid XML characters in text string
+ </summary>
+ <param name="textData">the XML text input string</param>
+ <param name="mask">the string to use in place of invalid characters</param>
+ <returns>A string that does not contain invalid XML characters.</returns>
+ <remarks>
+ <para>
+ Certain Unicode code points are not allowed in the XML InfoSet, for
+ details see: <a href="http://www.w3.org/TR/REC-xml/#charsets">http://www.w3.org/TR/REC-xml/#charsets</a>.
+ </para>
+ <para>
+ This method replaces any illegal characters in the input string
+ with the mask string specified.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.Transform.CountSubstrings(System.String,System.String)">
+ <summary>
+ Count the number of times that the substring occurs in the text
+ </summary>
+ <param name="text">the text to search</param>
+ <param name="substring">the substring to find</param>
+ <returns>the number of times the substring occurs in the text</returns>
+ <remarks>
+ <para>
+ The substring is assumed to be non repeating within itself.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Util.WindowsSecurityContext">
+ <summary>
+ Impersonate a Windows Account
+ </summary>
+ <remarks>
+ <para>
+ This <see cref="T:log4net.Core.SecurityContext"/> impersonates a Windows account.
+ </para>
+ <para>
+ How the impersonation is done depends on the value of <see cref="M:log4net.Util.WindowsSecurityContext.Impersonate(System.Object)"/>.
+ This allows the context to either impersonate a set of user credentials specified
+ using username, domain name and password or to revert to the process credentials.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.WindowsSecurityContext.#ctor">
+ <summary>
+ Default constructor
+ </summary>
+ <remarks>
+ <para>
+ Default constructor
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.WindowsSecurityContext.ActivateOptions">
+ <summary>
+ Initialize the SecurityContext based on the options set.
+ </summary>
+ <remarks>
+ <para>
+ This is part of the <see cref="T:log4net.Core.IOptionHandler"/> delayed object
+ activation scheme. The <see cref="M:log4net.Util.WindowsSecurityContext.ActivateOptions"/> method must
+ be called on this object after the configuration properties have
+ been set. Until <see cref="M:log4net.Util.WindowsSecurityContext.ActivateOptions"/> is called this
+ object is in an undefined state and must not be used.
+ </para>
+ <para>
+ If any of the configuration properties are modified then
+ <see cref="M:log4net.Util.WindowsSecurityContext.ActivateOptions"/> must be called again.
+ </para>
+ <para>
+ The security context will try to Logon the specified user account and
+ capture a primary token for impersonation.
+ </para>
+ </remarks>
+ <exception cref="T:System.ArgumentNullException">The required <see cref="P:log4net.Util.WindowsSecurityContext.UserName"/>,
+ <see cref="P:log4net.Util.WindowsSecurityContext.DomainName"/> or <see cref="P:log4net.Util.WindowsSecurityContext.Password"/> properties were not specified.</exception>
+ </member>
+ <member name="M:log4net.Util.WindowsSecurityContext.Impersonate(System.Object)">
+ <summary>
+ Impersonate the Windows account specified by the <see cref="P:log4net.Util.WindowsSecurityContext.UserName"/> and <see cref="P:log4net.Util.WindowsSecurityContext.DomainName"/> properties.
+ </summary>
+ <param name="state">caller provided state</param>
+ <returns>
+ An <see cref="T:System.IDisposable"/> instance that will revoke the impersonation of this SecurityContext
+ </returns>
+ <remarks>
+ <para>
+ Depending on the <see cref="P:log4net.Util.WindowsSecurityContext.Credentials"/> property either
+ impersonate a user using credentials supplied or revert
+ to the process credentials.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.WindowsSecurityContext.LogonUser(System.String,System.String,System.String)">
+ <summary>
+ Create a <see cref="T:System.Security.Principal.WindowsIdentity"/> given the userName, domainName and password.
+ </summary>
+ <param name="userName">the user name</param>
+ <param name="domainName">the domain name</param>
+ <param name="password">the password</param>
+ <returns>the <see cref="T:System.Security.Principal.WindowsIdentity"/> for the account specified</returns>
+ <remarks>
+ <para>
+ Uses the Windows API call LogonUser to get a principal token for the account. This
+ token is used to initialize the WindowsIdentity.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Util.WindowsSecurityContext.Credentials">
+ <summary>
+ Gets or sets the impersonation mode for this security context
+ </summary>
+ <value>
+ The impersonation mode for this security context
+ </value>
+ <remarks>
+ <para>
+ Impersonate either a user with user credentials or
+ revert this thread to the credentials of the process.
+ The value is one of the <see cref="T:log4net.Util.WindowsSecurityContext.ImpersonationMode"/>
+ enum.
+ </para>
+ <para>
+ The default value is <see cref="F:log4net.Util.WindowsSecurityContext.ImpersonationMode.User"/>
+ </para>
+ <para>
+ When the mode is set to <see cref="F:log4net.Util.WindowsSecurityContext.ImpersonationMode.User"/>
+ the user's credentials are established using the
+ <see cref="P:log4net.Util.WindowsSecurityContext.UserName"/>, <see cref="P:log4net.Util.WindowsSecurityContext.DomainName"/> and <see cref="P:log4net.Util.WindowsSecurityContext.Password"/>
+ values.
+ </para>
+ <para>
+ When the mode is set to <see cref="F:log4net.Util.WindowsSecurityContext.ImpersonationMode.Process"/>
+ no other properties need to be set. If the calling thread is
+ impersonating then it will be reverted back to the process credentials.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Util.WindowsSecurityContext.UserName">
+ <summary>
+ Gets or sets the Windows username for this security context
+ </summary>
+ <value>
+ The Windows username for this security context
+ </value>
+ <remarks>
+ <para>
+ This property must be set if <see cref="P:log4net.Util.WindowsSecurityContext.Credentials"/>
+ is set to <see cref="F:log4net.Util.WindowsSecurityContext.ImpersonationMode.User"/> (the default setting).
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Util.WindowsSecurityContext.DomainName">
+ <summary>
+ Gets or sets the Windows domain name for this security context
+ </summary>
+ <value>
+ The Windows domain name for this security context
+ </value>
+ <remarks>
+ <para>
+ The default value for <see cref="P:log4net.Util.WindowsSecurityContext.DomainName"/> is the local machine name
+ taken from the <see cref="P:System.Environment.MachineName"/> property.
+ </para>
+ <para>
+ This property must be set if <see cref="P:log4net.Util.WindowsSecurityContext.Credentials"/>
+ is set to <see cref="F:log4net.Util.WindowsSecurityContext.ImpersonationMode.User"/> (the default setting).
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Util.WindowsSecurityContext.Password">
+ <summary>
+ Sets the password for the Windows account specified by the <see cref="P:log4net.Util.WindowsSecurityContext.UserName"/> and <see cref="P:log4net.Util.WindowsSecurityContext.DomainName"/> properties.
+ </summary>
+ <value>
+ The password for the Windows account specified by the <see cref="P:log4net.Util.WindowsSecurityContext.UserName"/> and <see cref="P:log4net.Util.WindowsSecurityContext.DomainName"/> properties.
+ </value>
+ <remarks>
+ <para>
+ This property must be set if <see cref="P:log4net.Util.WindowsSecurityContext.Credentials"/>
+ is set to <see cref="F:log4net.Util.WindowsSecurityContext.ImpersonationMode.User"/> (the default setting).
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Util.WindowsSecurityContext.ImpersonationMode">
+ <summary>
+ The impersonation modes for the <see cref="T:log4net.Util.WindowsSecurityContext"/>
+ </summary>
+ <remarks>
+ <para>
+ See the <see cref="P:log4net.Util.WindowsSecurityContext.Credentials"/> property for
+ details.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Util.WindowsSecurityContext.ImpersonationMode.User">
+ <summary>
+ Impersonate a user using the credentials supplied
+ </summary>
+ </member>
+ <member name="F:log4net.Util.WindowsSecurityContext.ImpersonationMode.Process">
+ <summary>
+ Revert this the thread to the credentials of the process
+ </summary>
+ </member>
+ <member name="T:log4net.Util.WindowsSecurityContext.DisposableImpersonationContext">
+ <summary>
+ Adds <see cref="T:System.IDisposable"/> to <see cref="T:System.Security.Principal.WindowsImpersonationContext"/>
+ </summary>
+ <remarks>
+ <para>
+ Helper class to expose the <see cref="T:System.Security.Principal.WindowsImpersonationContext"/>
+ through the <see cref="T:System.IDisposable"/> interface.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.WindowsSecurityContext.DisposableImpersonationContext.#ctor(System.Security.Principal.WindowsImpersonationContext)">
+ <summary>
+ Constructor
+ </summary>
+ <param name="impersonationContext">the impersonation context being wrapped</param>
+ <remarks>
+ <para>
+ Constructor
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.WindowsSecurityContext.DisposableImpersonationContext.Dispose">
+ <summary>
+ Revert the impersonation
+ </summary>
+ <remarks>
+ <para>
+ Revert the impersonation
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.GlobalContext">
+ <summary>
+ The log4net Global Context.
+ </summary>
+ <remarks>
+ <para>
+ The <c>GlobalContext</c> provides a location for global debugging
+ information to be stored.
+ </para>
+ <para>
+ The global context has a properties map and these properties can
+ be included in the output of log messages. The <see cref="T:log4net.Layout.PatternLayout"/>
+ supports selecting and outputing these properties.
+ </para>
+ <para>
+ By default the <c>log4net:HostName</c> property is set to the name of
+ the current machine.
+ </para>
+ </remarks>
+ <example>
+ <code lang="C#">
+ GlobalContext.Properties["hostname"] = Environment.MachineName;
+ </code>
+ </example>
+ <threadsafety static="true" instance="true"/>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="M:log4net.GlobalContext.#ctor">
+ <summary>
+ Private Constructor.
+ </summary>
+ <remarks>
+ Uses a private access modifier to prevent instantiation of this class.
+ </remarks>
+ </member>
+ <member name="F:log4net.GlobalContext.s_properties">
+ <summary>
+ The global context properties instance
+ </summary>
+ </member>
+ <member name="P:log4net.GlobalContext.Properties">
+ <summary>
+ The global properties map.
+ </summary>
+ <value>
+ The global properties map.
+ </value>
+ <remarks>
+ <para>
+ The global properties map.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.LogicalThreadContext">
+ <summary>
+ The log4net Logical Thread Context.
+ </summary>
+ <remarks>
+ <para>
+ The <c>LogicalThreadContext</c> provides a location for <see cref="T:System.Runtime.Remoting.Messaging.CallContext"/> specific debugging
+ information to be stored.
+ The <c>LogicalThreadContext</c> properties override any <see cref="T:log4net.ThreadContext"/> or <see cref="T:log4net.GlobalContext"/>
+ properties with the same name.
+ </para>
+ <para>
+ The Logical Thread Context has a properties map and a stack.
+ The properties and stack can
+ be included in the output of log messages. The <see cref="T:log4net.Layout.PatternLayout"/>
+ supports selecting and outputting these properties.
+ </para>
+ <para>
+ The Logical Thread Context provides a diagnostic context for the current call context.
+ This is an instrument for distinguishing interleaved log
+ output from different sources. Log output is typically interleaved
+ when a server handles multiple clients near-simultaneously.
+ </para>
+ <para>
+ The Logical Thread Context is managed on a per <see cref="T:System.Runtime.Remoting.Messaging.CallContext"/> basis.
+ </para>
+ </remarks>
+ <example>Example of using the thread context properties to store a username.
+ <code lang="C#">
+ LogicalThreadContext.Properties["user"] = userName;
+ log.Info("This log message has a LogicalThreadContext Property called 'user'");
+ </code>
+ </example>
+ <example>Example of how to push a message into the context stack
+ <code lang="C#">
+ using(LogicalThreadContext.Stacks["LDC"].Push("my context message"))
+ {
+ log.Info("This log message has a LogicalThreadContext Stack message that includes 'my context message'");
+
+ } // at the end of the using block the message is automatically popped
+ </code>
+ </example>
+ <threadsafety static="true" instance="true"/>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="M:log4net.LogicalThreadContext.#ctor">
+ <summary>
+ Private Constructor.
+ </summary>
+ <remarks>
+ <para>
+ Uses a private access modifier to prevent instantiation of this class.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.LogicalThreadContext.s_properties">
+ <summary>
+ The thread context properties instance
+ </summary>
+ </member>
+ <member name="F:log4net.LogicalThreadContext.s_stacks">
+ <summary>
+ The thread context stacks instance
+ </summary>
+ </member>
+ <member name="P:log4net.LogicalThreadContext.Properties">
+ <summary>
+ The thread properties map
+ </summary>
+ <value>
+ The thread properties map
+ </value>
+ <remarks>
+ <para>
+ The <c>LogicalThreadContext</c> properties override any <see cref="T:log4net.ThreadContext"/>
+ or <see cref="T:log4net.GlobalContext"/> properties with the same name.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.LogicalThreadContext.Stacks">
+ <summary>
+ The thread stacks
+ </summary>
+ <value>
+ stack map
+ </value>
+ <remarks>
+ <para>
+ The logical thread stacks.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.LogManager">
+ <summary>
+ This class is used by client applications to request logger instances.
+ </summary>
+ <remarks>
+ <para>
+ This class has static methods that are used by a client to request
+ a logger instance. The <see cref="M:log4net.LogManager.GetLogger(System.String)"/> method is
+ used to retrieve a logger.
+ </para>
+ <para>
+ See the <see cref="T:log4net.ILog"/> interface for more details.
+ </para>
+ </remarks>
+ <example>Simple example of logging messages
+ <code lang="C#">
+ ILog log = LogManager.GetLogger("application-log");
+
+ log.Info("Application Start");
+ log.Debug("This is a debug message");
+
+ if (log.IsDebugEnabled)
+ {
+ log.Debug("This is another debug message");
+ }
+ </code>
+ </example>
+ <threadsafety static="true" instance="true"/>
+ <seealso cref="T:log4net.ILog"/>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="M:log4net.LogManager.#ctor">
+ <summary>
+ Initializes a new instance of the <see cref="T:log4net.LogManager"/> class.
+ </summary>
+ <remarks>
+ Uses a private access modifier to prevent instantiation of this class.
+ </remarks>
+ </member>
+ <member name="M:log4net.LogManager.Exists(System.String)">
+ <overloads>Returns the named logger if it exists.</overloads>
+ <summary>
+ Returns the named logger if it exists.
+ </summary>
+ <remarks>
+ <para>
+ If the named logger exists (in the default repository) then it
+ returns a reference to the logger, otherwise it returns <c>null</c>.
+ </para>
+ </remarks>
+ <param name="name">The fully qualified logger name to look for.</param>
+ <returns>The logger found, or <c>null</c> if no logger could be found.</returns>
+ </member>
+ <member name="M:log4net.LogManager.Exists(System.String,System.String)">
+ <summary>
+ Returns the named logger if it exists.
+ </summary>
+ <remarks>
+ <para>
+ If the named logger exists (in the specified repository) then it
+ returns a reference to the logger, otherwise it returns
+ <c>null</c>.
+ </para>
+ </remarks>
+ <param name="repository">The repository to lookup in.</param>
+ <param name="name">The fully qualified logger name to look for.</param>
+ <returns>
+ The logger found, or <c>null</c> if the logger doesn't exist in the specified
+ repository.
+ </returns>
+ </member>
+ <member name="M:log4net.LogManager.Exists(System.Reflection.Assembly,System.String)">
+ <summary>
+ Returns the named logger if it exists.
+ </summary>
+ <remarks>
+ <para>
+ If the named logger exists (in the repository for the specified assembly) then it
+ returns a reference to the logger, otherwise it returns
+ <c>null</c>.
+ </para>
+ </remarks>
+ <param name="repositoryAssembly">The assembly to use to lookup the repository.</param>
+ <param name="name">The fully qualified logger name to look for.</param>
+ <returns>
+ The logger, or <c>null</c> if the logger doesn't exist in the specified
+ assembly's repository.
+ </returns>
+ </member>
+ <member name="M:log4net.LogManager.GetCurrentLoggers">
+ <overloads>Get the currently defined loggers.</overloads>
+ <summary>
+ Returns all the currently defined loggers in the default repository.
+ </summary>
+ <remarks>
+ <para>The root logger is <b>not</b> included in the returned array.</para>
+ </remarks>
+ <returns>All the defined loggers.</returns>
+ </member>
+ <member name="M:log4net.LogManager.GetCurrentLoggers(System.String)">
+ <summary>
+ Returns all the currently defined loggers in the specified repository.
+ </summary>
+ <param name="repository">The repository to lookup in.</param>
+ <remarks>
+ The root logger is <b>not</b> included in the returned array.
+ </remarks>
+ <returns>All the defined loggers.</returns>
+ </member>
+ <member name="M:log4net.LogManager.GetCurrentLoggers(System.Reflection.Assembly)">
+ <summary>
+ Returns all the currently defined loggers in the specified assembly's repository.
+ </summary>
+ <param name="repositoryAssembly">The assembly to use to lookup the repository.</param>
+ <remarks>
+ The root logger is <b>not</b> included in the returned array.
+ </remarks>
+ <returns>All the defined loggers.</returns>
+ </member>
+ <member name="M:log4net.LogManager.GetLogger(System.String)">
+ <overloads>Get or create a logger.</overloads>
+ <summary>
+ Retrieves or creates a named logger.
+ </summary>
+ <remarks>
+ <para>
+ Retrieves a logger named as the <paramref name="name"/>
+ parameter. If the named logger already exists, then the
+ existing instance will be returned. Otherwise, a new instance is
+ created.
+ </para>
+ <para>By default, loggers do not have a set level but inherit
+ it from the hierarchy. This is one of the central features of
+ log4net.
+ </para>
+ </remarks>
+ <param name="name">The name of the logger to retrieve.</param>
+ <returns>The logger with the name specified.</returns>
+ </member>
+ <member name="M:log4net.LogManager.GetLogger(System.String,System.String)">
+ <summary>
+ Retrieves or creates a named logger.
+ </summary>
+ <remarks>
+ <para>
+ Retrieve a logger named as the <paramref name="name"/>
+ parameter. If the named logger already exists, then the
+ existing instance will be returned. Otherwise, a new instance is
+ created.
+ </para>
+ <para>
+ By default, loggers do not have a set level but inherit
+ it from the hierarchy. This is one of the central features of
+ log4net.
+ </para>
+ </remarks>
+ <param name="repository">The repository to lookup in.</param>
+ <param name="name">The name of the logger to retrieve.</param>
+ <returns>The logger with the name specified.</returns>
+ </member>
+ <member name="M:log4net.LogManager.GetLogger(System.Reflection.Assembly,System.String)">
+ <summary>
+ Retrieves or creates a named logger.
+ </summary>
+ <remarks>
+ <para>
+ Retrieve a logger named as the <paramref name="name"/>
+ parameter. If the named logger already exists, then the
+ existing instance will be returned. Otherwise, a new instance is
+ created.
+ </para>
+ <para>
+ By default, loggers do not have a set level but inherit
+ it from the hierarchy. This is one of the central features of
+ log4net.
+ </para>
+ </remarks>
+ <param name="repositoryAssembly">The assembly to use to lookup the repository.</param>
+ <param name="name">The name of the logger to retrieve.</param>
+ <returns>The logger with the name specified.</returns>
+ </member>
+ <member name="M:log4net.LogManager.GetLogger(System.Type)">
+ <summary>
+ Shorthand for <see cref="M:log4net.LogManager.GetLogger(System.String)"/>.
+ </summary>
+ <remarks>
+ Get the logger for the fully qualified name of the type specified.
+ </remarks>
+ <param name="type">The full name of <paramref name="type"/> will be used as the name of the logger to retrieve.</param>
+ <returns>The logger with the name specified.</returns>
+ </member>
+ <member name="M:log4net.LogManager.GetLogger(System.String,System.Type)">
+ <summary>
+ Shorthand for <see cref="M:log4net.LogManager.GetLogger(System.String)"/>.
+ </summary>
+ <remarks>
+ Gets the logger for the fully qualified name of the type specified.
+ </remarks>
+ <param name="repository">The repository to lookup in.</param>
+ <param name="type">The full name of <paramref name="type"/> will be used as the name of the logger to retrieve.</param>
+ <returns>The logger with the name specified.</returns>
+ </member>
+ <member name="M:log4net.LogManager.GetLogger(System.Reflection.Assembly,System.Type)">
+ <summary>
+ Shorthand for <see cref="M:log4net.LogManager.GetLogger(System.String)"/>.
+ </summary>
+ <remarks>
+ Gets the logger for the fully qualified name of the type specified.
+ </remarks>
+ <param name="repositoryAssembly">The assembly to use to lookup the repository.</param>
+ <param name="type">The full name of <paramref name="type"/> will be used as the name of the logger to retrieve.</param>
+ <returns>The logger with the name specified.</returns>
+ </member>
+ <member name="M:log4net.LogManager.Shutdown">
+ <summary>
+ Shuts down the log4net system.
+ </summary>
+ <remarks>
+ <para>
+ Calling this method will <b>safely</b> close and remove all
+ appenders in all the loggers including root contained in all the
+ default repositories.
+ </para>
+ <para>
+ Some appenders need to be closed before the application exists.
+ Otherwise, pending logging events might be lost.
+ </para>
+ <para>The <c>shutdown</c> method is careful to close nested
+ appenders before closing regular appenders. This is allows
+ configurations where a regular appender is attached to a logger
+ and again to a nested appender.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.LogManager.ShutdownRepository">
+ <overloads>Shutdown a logger repository.</overloads>
+ <summary>
+ Shuts down the default repository.
+ </summary>
+ <remarks>
+ <para>
+ Calling this method will <b>safely</b> close and remove all
+ appenders in all the loggers including root contained in the
+ default repository.
+ </para>
+ <para>Some appenders need to be closed before the application exists.
+ Otherwise, pending logging events might be lost.
+ </para>
+ <para>The <c>shutdown</c> method is careful to close nested
+ appenders before closing regular appenders. This is allows
+ configurations where a regular appender is attached to a logger
+ and again to a nested appender.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.LogManager.ShutdownRepository(System.String)">
+ <summary>
+ Shuts down the repository for the repository specified.
+ </summary>
+ <remarks>
+ <para>
+ Calling this method will <b>safely</b> close and remove all
+ appenders in all the loggers including root contained in the
+ <paramref name="repository"/> specified.
+ </para>
+ <para>
+ Some appenders need to be closed before the application exists.
+ Otherwise, pending logging events might be lost.
+ </para>
+ <para>The <c>shutdown</c> method is careful to close nested
+ appenders before closing regular appenders. This is allows
+ configurations where a regular appender is attached to a logger
+ and again to a nested appender.
+ </para>
+ </remarks>
+ <param name="repository">The repository to shutdown.</param>
+ </member>
+ <member name="M:log4net.LogManager.ShutdownRepository(System.Reflection.Assembly)">
+ <summary>
+ Shuts down the repository specified.
+ </summary>
+ <remarks>
+ <para>
+ Calling this method will <b>safely</b> close and remove all
+ appenders in all the loggers including root contained in the
+ repository. The repository is looked up using
+ the <paramref name="repositoryAssembly"/> specified.
+ </para>
+ <para>
+ Some appenders need to be closed before the application exists.
+ Otherwise, pending logging events might be lost.
+ </para>
+ <para>
+ The <c>shutdown</c> method is careful to close nested
+ appenders before closing regular appenders. This is allows
+ configurations where a regular appender is attached to a logger
+ and again to a nested appender.
+ </para>
+ </remarks>
+ <param name="repositoryAssembly">The assembly to use to lookup the repository.</param>
+ </member>
+ <member name="M:log4net.LogManager.ResetConfiguration">
+ <overloads>Reset the configuration of a repository</overloads>
+ <summary>
+ Resets all values contained in this repository instance to their defaults.
+ </summary>
+ <remarks>
+ <para>
+ Resets all values contained in the repository instance to their
+ defaults. This removes all appenders from all loggers, sets
+ the level of all non-root loggers to <c>null</c>,
+ sets their additivity flag to <c>true</c> and sets the level
+ of the root logger to <see cref="F:log4net.Core.Level.Debug"/>. Moreover,
+ message disabling is set to its default "off" value.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.LogManager.ResetConfiguration(System.String)">
+ <summary>
+ Resets all values contained in this repository instance to their defaults.
+ </summary>
+ <remarks>
+ <para>
+ Reset all values contained in the repository instance to their
+ defaults. This removes all appenders from all loggers, sets
+ the level of all non-root loggers to <c>null</c>,
+ sets their additivity flag to <c>true</c> and sets the level
+ of the root logger to <see cref="F:log4net.Core.Level.Debug"/>. Moreover,
+ message disabling is set to its default "off" value.
+ </para>
+ </remarks>
+ <param name="repository">The repository to reset.</param>
+ </member>
+ <member name="M:log4net.LogManager.ResetConfiguration(System.Reflection.Assembly)">
+ <summary>
+ Resets all values contained in this repository instance to their defaults.
+ </summary>
+ <remarks>
+ <para>
+ Reset all values contained in the repository instance to their
+ defaults. This removes all appenders from all loggers, sets
+ the level of all non-root loggers to <c>null</c>,
+ sets their additivity flag to <c>true</c> and sets the level
+ of the root logger to <see cref="F:log4net.Core.Level.Debug"/>. Moreover,
+ message disabling is set to its default "off" value.
+ </para>
+ </remarks>
+ <param name="repositoryAssembly">The assembly to use to lookup the repository to reset.</param>
+ </member>
+ <member name="M:log4net.LogManager.GetLoggerRepository">
+ <overloads>Get the logger repository.</overloads>
+ <summary>
+ Returns the default <see cref="T:log4net.Repository.ILoggerRepository"/> instance.
+ </summary>
+ <remarks>
+ <para>
+ Gets the <see cref="T:log4net.Repository.ILoggerRepository"/> for the repository specified
+ by the callers assembly (<see cref="M:System.Reflection.Assembly.GetCallingAssembly"/>).
+ </para>
+ </remarks>
+ <returns>The <see cref="T:log4net.Repository.ILoggerRepository"/> instance for the default repository.</returns>
+ </member>
+ <member name="M:log4net.LogManager.GetLoggerRepository(System.String)">
+ <summary>
+ Returns the default <see cref="T:log4net.Repository.ILoggerRepository"/> instance.
+ </summary>
+ <returns>The default <see cref="T:log4net.Repository.ILoggerRepository"/> instance.</returns>
+ <remarks>
+ <para>
+ Gets the <see cref="T:log4net.Repository.ILoggerRepository"/> for the repository specified
+ by the <paramref name="repository"/> argument.
+ </para>
+ </remarks>
+ <param name="repository">The repository to lookup in.</param>
+ </member>
+ <member name="M:log4net.LogManager.GetLoggerRepository(System.Reflection.Assembly)">
+ <summary>
+ Returns the default <see cref="T:log4net.Repository.ILoggerRepository"/> instance.
+ </summary>
+ <returns>The default <see cref="T:log4net.Repository.ILoggerRepository"/> instance.</returns>
+ <remarks>
+ <para>
+ Gets the <see cref="T:log4net.Repository.ILoggerRepository"/> for the repository specified
+ by the <paramref name="repositoryAssembly"/> argument.
+ </para>
+ </remarks>
+ <param name="repositoryAssembly">The assembly to use to lookup the repository.</param>
+ </member>
+ <member name="M:log4net.LogManager.GetRepository">
+ <overloads>Get a logger repository.</overloads>
+ <summary>
+ Returns the default <see cref="T:log4net.Repository.ILoggerRepository"/> instance.
+ </summary>
+ <remarks>
+ <para>
+ Gets the <see cref="T:log4net.Repository.ILoggerRepository"/> for the repository specified
+ by the callers assembly (<see cref="M:System.Reflection.Assembly.GetCallingAssembly"/>).
+ </para>
+ </remarks>
+ <returns>The <see cref="T:log4net.Repository.ILoggerRepository"/> instance for the default repository.</returns>
+ </member>
+ <member name="M:log4net.LogManager.GetRepository(System.String)">
+ <summary>
+ Returns the default <see cref="T:log4net.Repository.ILoggerRepository"/> instance.
+ </summary>
+ <returns>The default <see cref="T:log4net.Repository.ILoggerRepository"/> instance.</returns>
+ <remarks>
+ <para>
+ Gets the <see cref="T:log4net.Repository.ILoggerRepository"/> for the repository specified
+ by the <paramref name="repository"/> argument.
+ </para>
+ </remarks>
+ <param name="repository">The repository to lookup in.</param>
+ </member>
+ <member name="M:log4net.LogManager.GetRepository(System.Reflection.Assembly)">
+ <summary>
+ Returns the default <see cref="T:log4net.Repository.ILoggerRepository"/> instance.
+ </summary>
+ <returns>The default <see cref="T:log4net.Repository.ILoggerRepository"/> instance.</returns>
+ <remarks>
+ <para>
+ Gets the <see cref="T:log4net.Repository.ILoggerRepository"/> for the repository specified
+ by the <paramref name="repositoryAssembly"/> argument.
+ </para>
+ </remarks>
+ <param name="repositoryAssembly">The assembly to use to lookup the repository.</param>
+ </member>
+ <member name="M:log4net.LogManager.CreateDomain(System.Type)">
+ <overloads>Create a domain</overloads>
+ <summary>
+ Creates a repository with the specified repository type.
+ </summary>
+ <remarks>
+ <para>
+ <b>CreateDomain is obsolete. Use CreateRepository instead of CreateDomain.</b>
+ </para>
+ <para>
+ The <see cref="T:log4net.Repository.ILoggerRepository"/> created will be associated with the repository
+ specified such that a call to <see cref="M:log4net.LogManager.GetRepository"/> will return
+ the same repository instance.
+ </para>
+ </remarks>
+ <param name="repositoryType">A <see cref="T:System.Type"/> that implements <see cref="T:log4net.Repository.ILoggerRepository"/>
+ and has a no arg constructor. An instance of this type will be created to act
+ as the <see cref="T:log4net.Repository.ILoggerRepository"/> for the repository specified.</param>
+ <returns>The <see cref="T:log4net.Repository.ILoggerRepository"/> created for the repository.</returns>
+ </member>
+ <member name="M:log4net.LogManager.CreateRepository(System.Type)">
+ <overloads>Create a logger repository.</overloads>
+ <summary>
+ Creates a repository with the specified repository type.
+ </summary>
+ <param name="repositoryType">A <see cref="T:System.Type"/> that implements <see cref="T:log4net.Repository.ILoggerRepository"/>
+ and has a no arg constructor. An instance of this type will be created to act
+ as the <see cref="T:log4net.Repository.ILoggerRepository"/> for the repository specified.</param>
+ <returns>The <see cref="T:log4net.Repository.ILoggerRepository"/> created for the repository.</returns>
+ <remarks>
+ <para>
+ The <see cref="T:log4net.Repository.ILoggerRepository"/> created will be associated with the repository
+ specified such that a call to <see cref="M:log4net.LogManager.GetRepository"/> will return
+ the same repository instance.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.LogManager.CreateDomain(System.String)">
+ <summary>
+ Creates a repository with the specified name.
+ </summary>
+ <remarks>
+ <para>
+ <b>CreateDomain is obsolete. Use CreateRepository instead of CreateDomain.</b>
+ </para>
+ <para>
+ Creates the default type of <see cref="T:log4net.Repository.ILoggerRepository"/> which is a
+ <see cref="T:log4net.Repository.Hierarchy.Hierarchy"/> object.
+ </para>
+ <para>
+ The <paramref name="repository"/> name must be unique. Repositories cannot be redefined.
+ An <see cref="T:System.Exception"/> will be thrown if the repository already exists.
+ </para>
+ </remarks>
+ <param name="repository">The name of the repository, this must be unique amongst repositories.</param>
+ <returns>The <see cref="T:log4net.Repository.ILoggerRepository"/> created for the repository.</returns>
+ <exception cref="T:log4net.Core.LogException">The specified repository already exists.</exception>
+ </member>
+ <member name="M:log4net.LogManager.CreateRepository(System.String)">
+ <summary>
+ Creates a repository with the specified name.
+ </summary>
+ <remarks>
+ <para>
+ Creates the default type of <see cref="T:log4net.Repository.ILoggerRepository"/> which is a
+ <see cref="T:log4net.Repository.Hierarchy.Hierarchy"/> object.
+ </para>
+ <para>
+ The <paramref name="repository"/> name must be unique. Repositories cannot be redefined.
+ An <see cref="T:System.Exception"/> will be thrown if the repository already exists.
+ </para>
+ </remarks>
+ <param name="repository">The name of the repository, this must be unique amongst repositories.</param>
+ <returns>The <see cref="T:log4net.Repository.ILoggerRepository"/> created for the repository.</returns>
+ <exception cref="T:log4net.Core.LogException">The specified repository already exists.</exception>
+ </member>
+ <member name="M:log4net.LogManager.CreateDomain(System.String,System.Type)">
+ <summary>
+ Creates a repository with the specified name and repository type.
+ </summary>
+ <remarks>
+ <para>
+ <b>CreateDomain is obsolete. Use CreateRepository instead of CreateDomain.</b>
+ </para>
+ <para>
+ The <paramref name="repository"/> name must be unique. Repositories cannot be redefined.
+ An <see cref="T:System.Exception"/> will be thrown if the repository already exists.
+ </para>
+ </remarks>
+ <param name="repository">The name of the repository, this must be unique to the repository.</param>
+ <param name="repositoryType">A <see cref="T:System.Type"/> that implements <see cref="T:log4net.Repository.ILoggerRepository"/>
+ and has a no arg constructor. An instance of this type will be created to act
+ as the <see cref="T:log4net.Repository.ILoggerRepository"/> for the repository specified.</param>
+ <returns>The <see cref="T:log4net.Repository.ILoggerRepository"/> created for the repository.</returns>
+ <exception cref="T:log4net.Core.LogException">The specified repository already exists.</exception>
+ </member>
+ <member name="M:log4net.LogManager.CreateRepository(System.String,System.Type)">
+ <summary>
+ Creates a repository with the specified name and repository type.
+ </summary>
+ <remarks>
+ <para>
+ The <paramref name="repository"/> name must be unique. Repositories cannot be redefined.
+ An <see cref="T:System.Exception"/> will be thrown if the repository already exists.
+ </para>
+ </remarks>
+ <param name="repository">The name of the repository, this must be unique to the repository.</param>
+ <param name="repositoryType">A <see cref="T:System.Type"/> that implements <see cref="T:log4net.Repository.ILoggerRepository"/>
+ and has a no arg constructor. An instance of this type will be created to act
+ as the <see cref="T:log4net.Repository.ILoggerRepository"/> for the repository specified.</param>
+ <returns>The <see cref="T:log4net.Repository.ILoggerRepository"/> created for the repository.</returns>
+ <exception cref="T:log4net.Core.LogException">The specified repository already exists.</exception>
+ </member>
+ <member name="M:log4net.LogManager.CreateDomain(System.Reflection.Assembly,System.Type)">
+ <summary>
+ Creates a repository for the specified assembly and repository type.
+ </summary>
+ <remarks>
+ <para>
+ <b>CreateDomain is obsolete. Use CreateRepository instead of CreateDomain.</b>
+ </para>
+ <para>
+ The <see cref="T:log4net.Repository.ILoggerRepository"/> created will be associated with the repository
+ specified such that a call to <see cref="M:log4net.LogManager.GetRepository(System.Reflection.Assembly)"/> with the
+ same assembly specified will return the same repository instance.
+ </para>
+ </remarks>
+ <param name="repositoryAssembly">The assembly to use to get the name of the repository.</param>
+ <param name="repositoryType">A <see cref="T:System.Type"/> that implements <see cref="T:log4net.Repository.ILoggerRepository"/>
+ and has a no arg constructor. An instance of this type will be created to act
+ as the <see cref="T:log4net.Repository.ILoggerRepository"/> for the repository specified.</param>
+ <returns>The <see cref="T:log4net.Repository.ILoggerRepository"/> created for the repository.</returns>
+ </member>
+ <member name="M:log4net.LogManager.CreateRepository(System.Reflection.Assembly,System.Type)">
+ <summary>
+ Creates a repository for the specified assembly and repository type.
+ </summary>
+ <remarks>
+ <para>
+ The <see cref="T:log4net.Repository.ILoggerRepository"/> created will be associated with the repository
+ specified such that a call to <see cref="M:log4net.LogManager.GetRepository(System.Reflection.Assembly)"/> with the
+ same assembly specified will return the same repository instance.
+ </para>
+ </remarks>
+ <param name="repositoryAssembly">The assembly to use to get the name of the repository.</param>
+ <param name="repositoryType">A <see cref="T:System.Type"/> that implements <see cref="T:log4net.Repository.ILoggerRepository"/>
+ and has a no arg constructor. An instance of this type will be created to act
+ as the <see cref="T:log4net.Repository.ILoggerRepository"/> for the repository specified.</param>
+ <returns>The <see cref="T:log4net.Repository.ILoggerRepository"/> created for the repository.</returns>
+ </member>
+ <member name="M:log4net.LogManager.GetAllRepositories">
+ <summary>
+ Gets the list of currently defined repositories.
+ </summary>
+ <remarks>
+ <para>
+ Get an array of all the <see cref="T:log4net.Repository.ILoggerRepository"/> objects that have been created.
+ </para>
+ </remarks>
+ <returns>An array of all the known <see cref="T:log4net.Repository.ILoggerRepository"/> objects.</returns>
+ </member>
+ <member name="M:log4net.LogManager.WrapLogger(log4net.Core.ILogger)">
+ <summary>
+ Looks up the wrapper object for the logger specified.
+ </summary>
+ <param name="logger">The logger to get the wrapper for.</param>
+ <returns>The wrapper for the logger specified.</returns>
+ </member>
+ <member name="M:log4net.LogManager.WrapLoggers(log4net.Core.ILogger[])">
+ <summary>
+ Looks up the wrapper objects for the loggers specified.
+ </summary>
+ <param name="loggers">The loggers to get the wrappers for.</param>
+ <returns>The wrapper objects for the loggers specified.</returns>
+ </member>
+ <member name="M:log4net.LogManager.WrapperCreationHandler(log4net.Core.ILogger)">
+ <summary>
+ Create the <see cref="T:log4net.Core.ILoggerWrapper"/> objects used by
+ this manager.
+ </summary>
+ <param name="logger">The logger to wrap.</param>
+ <returns>The wrapper for the logger specified.</returns>
+ </member>
+ <member name="F:log4net.LogManager.s_wrapperMap">
+ <summary>
+ The wrapper map to use to hold the <see cref="T:log4net.Core.LogImpl"/> objects.
+ </summary>
+ </member>
+ <member name="T:log4net.MDC">
+ <summary>
+ Implementation of Mapped Diagnostic Contexts.
+ </summary>
+ <remarks>
+ <note>
+ <para>
+ The MDC is deprecated and has been replaced by the <see cref="P:log4net.ThreadContext.Properties"/>.
+ The current MDC implementation forwards to the <c>ThreadContext.Properties</c>.
+ </para>
+ </note>
+ <para>
+ The MDC class is similar to the <see cref="T:log4net.NDC"/> class except that it is
+ based on a map instead of a stack. It provides <i>mapped
+ diagnostic contexts</i>. A <i>Mapped Diagnostic Context</i>, or
+ MDC in short, is an instrument for distinguishing interleaved log
+ output from different sources. Log output is typically interleaved
+ when a server handles multiple clients near-simultaneously.
+ </para>
+ <para>
+ The MDC is managed on a per thread basis.
+ </para>
+ </remarks>
+ <threadsafety static="true" instance="true"/>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="M:log4net.MDC.#ctor">
+ <summary>
+ Initializes a new instance of the <see cref="T:log4net.MDC"/> class.
+ </summary>
+ <remarks>
+ Uses a private access modifier to prevent instantiation of this class.
+ </remarks>
+ </member>
+ <member name="M:log4net.MDC.Get(System.String)">
+ <summary>
+ Gets the context value identified by the <paramref name="key"/> parameter.
+ </summary>
+ <param name="key">The key to lookup in the MDC.</param>
+ <returns>The string value held for the key, or a <c>null</c> reference if no corresponding value is found.</returns>
+ <remarks>
+ <note>
+ <para>
+ The MDC is deprecated and has been replaced by the <see cref="P:log4net.ThreadContext.Properties"/>.
+ The current MDC implementation forwards to the <c>ThreadContext.Properties</c>.
+ </para>
+ </note>
+ <para>
+ If the <paramref name="key"/> parameter does not look up to a
+ previously defined context then <c>null</c> will be returned.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.MDC.Set(System.String,System.String)">
+ <summary>
+ Add an entry to the MDC
+ </summary>
+ <param name="key">The key to store the value under.</param>
+ <param name="value">The value to store.</param>
+ <remarks>
+ <note>
+ <para>
+ The MDC is deprecated and has been replaced by the <see cref="P:log4net.ThreadContext.Properties"/>.
+ The current MDC implementation forwards to the <c>ThreadContext.Properties</c>.
+ </para>
+ </note>
+ <para>
+ Puts a context value (the <paramref name="val"/> parameter) as identified
+ with the <paramref name="key"/> parameter into the current thread's
+ context map.
+ </para>
+ <para>
+ If a value is already defined for the <paramref name="key"/>
+ specified then the value will be replaced. If the <paramref name="val"/>
+ is specified as <c>null</c> then the key value mapping will be removed.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.MDC.Remove(System.String)">
+ <summary>
+ Removes the key value mapping for the key specified.
+ </summary>
+ <param name="key">The key to remove.</param>
+ <remarks>
+ <note>
+ <para>
+ The MDC is deprecated and has been replaced by the <see cref="P:log4net.ThreadContext.Properties"/>.
+ The current MDC implementation forwards to the <c>ThreadContext.Properties</c>.
+ </para>
+ </note>
+ <para>
+ Remove the specified entry from this thread's MDC
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.MDC.Clear">
+ <summary>
+ Clear all entries in the MDC
+ </summary>
+ <remarks>
+ <note>
+ <para>
+ The MDC is deprecated and has been replaced by the <see cref="P:log4net.ThreadContext.Properties"/>.
+ The current MDC implementation forwards to the <c>ThreadContext.Properties</c>.
+ </para>
+ </note>
+ <para>
+ Remove all the entries from this thread's MDC
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.NDC">
+ <summary>
+ Implementation of Nested Diagnostic Contexts.
+ </summary>
+ <remarks>
+ <note>
+ <para>
+ The NDC is deprecated and has been replaced by the <see cref="P:log4net.ThreadContext.Stacks"/>.
+ The current NDC implementation forwards to the <c>ThreadContext.Stacks["NDC"]</c>.
+ </para>
+ </note>
+ <para>
+ A Nested Diagnostic Context, or NDC in short, is an instrument
+ to distinguish interleaved log output from different sources. Log
+ output is typically interleaved when a server handles multiple
+ clients near-simultaneously.
+ </para>
+ <para>
+ Interleaved log output can still be meaningful if each log entry
+ from different contexts had a distinctive stamp. This is where NDCs
+ come into play.
+ </para>
+ <para>
+ Note that NDCs are managed on a per thread basis. The NDC class
+ is made up of static methods that operate on the context of the
+ calling thread.
+ </para>
+ </remarks>
+ <example>How to push a message into the context
+ <code lang="C#">
+ using(NDC.Push("my context message"))
+ {
+ ... all log calls will have 'my context message' included ...
+
+ } // at the end of the using block the message is automatically removed
+ </code>
+ </example>
+ <threadsafety static="true" instance="true"/>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="M:log4net.NDC.#ctor">
+ <summary>
+ Initializes a new instance of the <see cref="T:log4net.NDC"/> class.
+ </summary>
+ <remarks>
+ Uses a private access modifier to prevent instantiation of this class.
+ </remarks>
+ </member>
+ <member name="M:log4net.NDC.Clear">
+ <summary>
+ Clears all the contextual information held on the current thread.
+ </summary>
+ <remarks>
+ <note>
+ <para>
+ The NDC is deprecated and has been replaced by the <see cref="P:log4net.ThreadContext.Stacks"/>.
+ The current NDC implementation forwards to the <c>ThreadContext.Stacks["NDC"]</c>.
+ </para>
+ </note>
+ <para>
+ Clears the stack of NDC data held on the current thread.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.NDC.CloneStack">
+ <summary>
+ Creates a clone of the stack of context information.
+ </summary>
+ <returns>A clone of the context info for this thread.</returns>
+ <remarks>
+ <note>
+ <para>
+ The NDC is deprecated and has been replaced by the <see cref="P:log4net.ThreadContext.Stacks"/>.
+ The current NDC implementation forwards to the <c>ThreadContext.Stacks["NDC"]</c>.
+ </para>
+ </note>
+ <para>
+ The results of this method can be passed to the <see cref="M:log4net.NDC.Inherit(System.Collections.Stack)"/>
+ method to allow child threads to inherit the context of their
+ parent thread.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.NDC.Inherit(System.Collections.Stack)">
+ <summary>
+ Inherits the contextual information from another thread.
+ </summary>
+ <param name="stack">The context stack to inherit.</param>
+ <remarks>
+ <note>
+ <para>
+ The NDC is deprecated and has been replaced by the <see cref="P:log4net.ThreadContext.Stacks"/>.
+ The current NDC implementation forwards to the <c>ThreadContext.Stacks["NDC"]</c>.
+ </para>
+ </note>
+ <para>
+ This thread will use the context information from the stack
+ supplied. This can be used to initialize child threads with
+ the same contextual information as their parent threads. These
+ contexts will <b>NOT</b> be shared. Any further contexts that
+ are pushed onto the stack will not be visible to the other.
+ Call <see cref="M:log4net.NDC.CloneStack"/> to obtain a stack to pass to
+ this method.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.NDC.Pop">
+ <summary>
+ Removes the top context from the stack.
+ </summary>
+ <returns>
+ The message in the context that was removed from the top
+ of the stack.
+ </returns>
+ <remarks>
+ <note>
+ <para>
+ The NDC is deprecated and has been replaced by the <see cref="P:log4net.ThreadContext.Stacks"/>.
+ The current NDC implementation forwards to the <c>ThreadContext.Stacks["NDC"]</c>.
+ </para>
+ </note>
+ <para>
+ Remove the top context from the stack, and return
+ it to the caller. If the stack is empty then an
+ empty string (not <c>null</c>) is returned.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.NDC.Push(System.String)">
+ <summary>
+ Pushes a new context message.
+ </summary>
+ <param name="message">The new context message.</param>
+ <returns>
+ An <see cref="T:System.IDisposable"/> that can be used to clean up
+ the context stack.
+ </returns>
+ <remarks>
+ <note>
+ <para>
+ The NDC is deprecated and has been replaced by the <see cref="P:log4net.ThreadContext.Stacks"/>.
+ The current NDC implementation forwards to the <c>ThreadContext.Stacks["NDC"]</c>.
+ </para>
+ </note>
+ <para>
+ Pushes a new context onto the context stack. An <see cref="T:System.IDisposable"/>
+ is returned that can be used to clean up the context stack. This
+ can be easily combined with the <c>using</c> keyword to scope the
+ context.
+ </para>
+ </remarks>
+ <example>Simple example of using the <c>Push</c> method with the <c>using</c> keyword.
+ <code lang="C#">
+ using(log4net.NDC.Push("NDC_Message"))
+ {
+ log.Warn("This should have an NDC message");
+ }
+ </code>
+ </example>
+ </member>
+ <member name="M:log4net.NDC.Remove">
+ <summary>
+ Removes the context information for this thread. It is
+ not required to call this method.
+ </summary>
+ <remarks>
+ <note>
+ <para>
+ The NDC is deprecated and has been replaced by the <see cref="P:log4net.ThreadContext.Stacks"/>.
+ The current NDC implementation forwards to the <c>ThreadContext.Stacks["NDC"]</c>.
+ </para>
+ </note>
+ <para>
+ This method is not implemented.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.NDC.SetMaxDepth(System.Int32)">
+ <summary>
+ Forces the stack depth to be at most <paramref name="maxDepth"/>.
+ </summary>
+ <param name="maxDepth">The maximum depth of the stack</param>
+ <remarks>
+ <note>
+ <para>
+ The NDC is deprecated and has been replaced by the <see cref="P:log4net.ThreadContext.Stacks"/>.
+ The current NDC implementation forwards to the <c>ThreadContext.Stacks["NDC"]</c>.
+ </para>
+ </note>
+ <para>
+ Forces the stack depth to be at most <paramref name="maxDepth"/>.
+ This may truncate the head of the stack. This only affects the
+ stack in the current thread. Also it does not prevent it from
+ growing, it only sets the maximum depth at the time of the
+ call. This can be used to return to a known context depth.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.NDC.Depth">
+ <summary>
+ Gets the current context depth.
+ </summary>
+ <value>The current context depth.</value>
+ <remarks>
+ <note>
+ <para>
+ The NDC is deprecated and has been replaced by the <see cref="P:log4net.ThreadContext.Stacks"/>.
+ The current NDC implementation forwards to the <c>ThreadContext.Stacks["NDC"]</c>.
+ </para>
+ </note>
+ <para>
+ The number of context values pushed onto the context stack.
+ </para>
+ <para>
+ Used to record the current depth of the context. This can then
+ be restored using the <see cref="M:log4net.NDC.SetMaxDepth(System.Int32)"/> method.
+ </para>
+ </remarks>
+ <seealso cref="M:log4net.NDC.SetMaxDepth(System.Int32)"/>
+ </member>
+ <member name="T:log4net.ThreadContext">
+ <summary>
+ The log4net Thread Context.
+ </summary>
+ <remarks>
+ <para>
+ The <c>ThreadContext</c> provides a location for thread specific debugging
+ information to be stored.
+ The <c>ThreadContext</c> properties override any <see cref="T:log4net.GlobalContext"/>
+ properties with the same name.
+ </para>
+ <para>
+ The thread context has a properties map and a stack.
+ The properties and stack can
+ be included in the output of log messages. The <see cref="T:log4net.Layout.PatternLayout"/>
+ supports selecting and outputting these properties.
+ </para>
+ <para>
+ The Thread Context provides a diagnostic context for the current thread.
+ This is an instrument for distinguishing interleaved log
+ output from different sources. Log output is typically interleaved
+ when a server handles multiple clients near-simultaneously.
+ </para>
+ <para>
+ The Thread Context is managed on a per thread basis.
+ </para>
+ </remarks>
+ <example>Example of using the thread context properties to store a username.
+ <code lang="C#">
+ ThreadContext.Properties["user"] = userName;
+ log.Info("This log message has a ThreadContext Property called 'user'");
+ </code>
+ </example>
+ <example>Example of how to push a message into the context stack
+ <code lang="C#">
+ using(ThreadContext.Stacks["NDC"].Push("my context message"))
+ {
+ log.Info("This log message has a ThreadContext Stack message that includes 'my context message'");
+
+ } // at the end of the using block the message is automatically popped
+ </code>
+ </example>
+ <threadsafety static="true" instance="true"/>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="M:log4net.ThreadContext.#ctor">
+ <summary>
+ Private Constructor.
+ </summary>
+ <remarks>
+ <para>
+ Uses a private access modifier to prevent instantiation of this class.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.ThreadContext.s_properties">
+ <summary>
+ The thread context properties instance
+ </summary>
+ </member>
+ <member name="F:log4net.ThreadContext.s_stacks">
+ <summary>
+ The thread context stacks instance
+ </summary>
+ </member>
+ <member name="P:log4net.ThreadContext.Properties">
+ <summary>
+ The thread properties map
+ </summary>
+ <value>
+ The thread properties map
+ </value>
+ <remarks>
+ <para>
+ The <c>ThreadContext</c> properties override any <see cref="T:log4net.GlobalContext"/>
+ properties with the same name.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.ThreadContext.Stacks">
+ <summary>
+ The thread stacks
+ </summary>
+ <value>
+ stack map
+ </value>
+ <remarks>
+ <para>
+ The thread local stacks.
+ </para>
+ </remarks>
+ </member>
+ </members>
+</doc>
diff --git a/qpid/dotnet/Qpid.Common/lib/saxon/saxon-licence.txt b/qpid/dotnet/Qpid.Common/lib/saxon/saxon-licence.txt
new file mode 100644
index 0000000000..1bf2b1279d
--- /dev/null
+++ b/qpid/dotnet/Qpid.Common/lib/saxon/saxon-licence.txt
@@ -0,0 +1,471 @@
+ MOZILLA PUBLIC LICENSE
+ Version 1.1
+
+ ---------------
+
+1. Definitions.
+
+ 1.0.1. "Commercial Use" means distribution or otherwise making the
+ Covered Code available to a third party.
+
+ 1.1. "Contributor" means each entity that creates or contributes to
+ the creation of Modifications.
+
+ 1.2. "Contributor Version" means the combination of the Original
+ Code, prior Modifications used by a Contributor, and the Modifications
+ made by that particular Contributor.
+
+ 1.3. "Covered Code" means the Original Code or Modifications or the
+ combination of the Original Code and Modifications, in each case
+ including portions thereof.
+
+ 1.4. "Electronic Distribution Mechanism" means a mechanism generally
+ accepted in the software development community for the electronic
+ transfer of data.
+
+ 1.5. "Executable" means Covered Code in any form other than Source
+ Code.
+
+ 1.6. "Initial Developer" means the individual or entity identified
+ as the Initial Developer in the Source Code notice required by Exhibit
+ A.
+
+ 1.7. "Larger Work" means a work which combines Covered Code or
+ portions thereof with code not governed by the terms of this License.
+
+ 1.8. "License" means this document.
+
+ 1.8.1. "Licensable" means having the right to grant, to the maximum
+ extent possible, whether at the time of the initial grant or
+ subsequently acquired, any and all of the rights conveyed herein.
+
+ 1.9. "Modifications" means any addition to or deletion from the
+ substance or structure of either the Original Code or any previous
+ Modifications. When Covered Code is released as a series of files, a
+ Modification is:
+ A. Any addition to or deletion from the contents of a file
+ containing Original Code or previous Modifications.
+
+ B. Any new file that contains any part of the Original Code or
+ previous Modifications.
+
+ 1.10. "Original Code" means Source Code of computer software code
+ which is described in the Source Code notice required by Exhibit A as
+ Original Code, and which, at the time of its release under this
+ License is not already Covered Code governed by this License.
+
+ 1.10.1. "Patent Claims" means any patent claim(s), now owned or
+ hereafter acquired, including without limitation, method, process,
+ and apparatus claims, in any patent Licensable by grantor.
+
+ 1.11. "Source Code" means the preferred form of the Covered Code for
+ making modifications to it, including all modules it contains, plus
+ any associated interface definition files, scripts used to control
+ compilation and installation of an Executable, or source code
+ differential comparisons against either the Original Code or another
+ well known, available Covered Code of the Contributor's choice. The
+ Source Code can be in a compressed or archival form, provided the
+ appropriate decompression or de-archiving software is widely available
+ for no charge.
+
+ 1.12. "You" (or "Your") means an individual or a legal entity
+ exercising rights under, and complying with all of the terms of, this
+ License or a future version of this License issued under Section 6.1.
+ For legal entities, "You" includes any entity which controls, is
+ controlled by, or is under common control with You. For purposes of
+ this definition, "control" means (a) the power, direct or indirect,
+ to cause the direction or management of such entity, whether by
+ contract or otherwise, or (b) ownership of more than fifty percent
+ (50%) of the outstanding shares or beneficial ownership of such
+ entity.
+
+2. Source Code License.
+
+ 2.1. The Initial Developer Grant.
+ The Initial Developer hereby grants You a world-wide, royalty-free,
+ non-exclusive license, subject to third party intellectual property
+ claims:
+ (a) under intellectual property rights (other than patent or
+ trademark) Licensable by Initial Developer to use, reproduce,
+ modify, display, perform, sublicense and distribute the Original
+ Code (or portions thereof) with or without Modifications, and/or
+ as part of a Larger Work; and
+
+ (b) under Patents Claims infringed by the making, using or
+ selling of Original Code, to make, have made, use, practice,
+ sell, and offer for sale, and/or otherwise dispose of the
+ Original Code (or portions thereof).
+
+ (c) the licenses granted in this Section 2.1(a) and (b) are
+ effective on the date Initial Developer first distributes
+ Original Code under the terms of this License.
+
+ (d) Notwithstanding Section 2.1(b) above, no patent license is
+ granted: 1) for code that You delete from the Original Code; 2)
+ separate from the Original Code; or 3) for infringements caused
+ by: i) the modification of the Original Code or ii) the
+ combination of the Original Code with other software or devices.
+
+ 2.2. Contributor Grant.
+ Subject to third party intellectual property claims, each Contributor
+ hereby grants You a world-wide, royalty-free, non-exclusive license
+
+ (a) under intellectual property rights (other than patent or
+ trademark) Licensable by Contributor, to use, reproduce, modify,
+ display, perform, sublicense and distribute the Modifications
+ created by such Contributor (or portions thereof) either on an
+ unmodified basis, with other Modifications, as Covered Code
+ and/or as part of a Larger Work; and
+
+ (b) under Patent Claims infringed by the making, using, or
+ selling of Modifications made by that Contributor either alone
+ and/or in combination with its Contributor Version (or portions
+ of such combination), to make, use, sell, offer for sale, have
+ made, and/or otherwise dispose of: 1) Modifications made by that
+ Contributor (or portions thereof); and 2) the combination of
+ Modifications made by that Contributor with its Contributor
+ Version (or portions of such combination).
+
+ (c) the licenses granted in Sections 2.2(a) and 2.2(b) are
+ effective on the date Contributor first makes Commercial Use of
+ the Covered Code.
+
+ (d) Notwithstanding Section 2.2(b) above, no patent license is
+ granted: 1) for any code that Contributor has deleted from the
+ Contributor Version; 2) separate from the Contributor Version;
+ 3) for infringements caused by: i) third party modifications of
+ Contributor Version or ii) the combination of Modifications made
+ by that Contributor with other software (except as part of the
+ Contributor Version) or other devices; or 4) under Patent Claims
+ infringed by Covered Code in the absence of Modifications made by
+ that Contributor.
+
+3. Distribution Obligations.
+
+ 3.1. Application of License.
+ The Modifications which You create or to which You contribute are
+ governed by the terms of this License, including without limitation
+ Section 2.2. The Source Code version of Covered Code may be
+ distributed only under the terms of this License or a future version
+ of this License released under Section 6.1, and You must include a
+ copy of this License with every copy of the Source Code You
+ distribute. You may not offer or impose any terms on any Source Code
+ version that alters or restricts the applicable version of this
+ License or the recipients' rights hereunder. However, You may include
+ an additional document offering the additional rights described in
+ Section 3.5.
+
+ 3.2. Availability of Source Code.
+ Any Modification which You create or to which You contribute must be
+ made available in Source Code form under the terms of this License
+ either on the same media as an Executable version or via an accepted
+ Electronic Distribution Mechanism to anyone to whom you made an
+ Executable version available; and if made available via Electronic
+ Distribution Mechanism, must remain available for at least twelve (12)
+ months after the date it initially became available, or at least six
+ (6) months after a subsequent version of that particular Modification
+ has been made available to such recipients. You are responsible for
+ ensuring that the Source Code version remains available even if the
+ Electronic Distribution Mechanism is maintained by a third party.
+
+ 3.3. Description of Modifications.
+ You must cause all Covered Code to which You contribute to contain a
+ file documenting the changes You made to create that Covered Code and
+ the date of any change. You must include a prominent statement that
+ the Modification is derived, directly or indirectly, from Original
+ Code provided by the Initial Developer and including the name of the
+ Initial Developer in (a) the Source Code, and (b) in any notice in an
+ Executable version or related documentation in which You describe the
+ origin or ownership of the Covered Code.
+
+ 3.4. Intellectual Property Matters
+ (a) Third Party Claims.
+ If Contributor has knowledge that a license under a third party's
+ intellectual property rights is required to exercise the rights
+ granted by such Contributor under Sections 2.1 or 2.2,
+ Contributor must include a text file with the Source Code
+ distribution titled "LEGAL" which describes the claim and the
+ party making the claim in sufficient detail that a recipient will
+ know whom to contact. If Contributor obtains such knowledge after
+ the Modification is made available as described in Section 3.2,
+ Contributor shall promptly modify the LEGAL file in all copies
+ Contributor makes available thereafter and shall take other steps
+ (such as notifying appropriate mailing lists or newsgroups)
+ reasonably calculated to inform those who received the Covered
+ Code that new knowledge has been obtained.
+
+ (b) Contributor APIs.
+ If Contributor's Modifications include an application programming
+ interface and Contributor has knowledge of patent licenses which
+ are reasonably necessary to implement that API, Contributor must
+ also include this information in the LEGAL file.
+
+ (c) Representations.
+ Contributor represents that, except as disclosed pursuant to
+ Section 3.4(a) above, Contributor believes that Contributor's
+ Modifications are Contributor's original creation(s) and/or
+ Contributor has sufficient rights to grant the rights conveyed by
+ this License.
+
+ 3.5. Required Notices.
+ You must duplicate the notice in Exhibit A in each file of the Source
+ Code. If it is not possible to put such notice in a particular Source
+ Code file due to its structure, then You must include such notice in a
+ location (such as a relevant directory) where a user would be likely
+ to look for such a notice. If You created one or more Modification(s)
+ You may add your name as a Contributor to the notice described in
+ Exhibit A. You must also duplicate this License in any documentation
+ for the Source Code where You describe recipients' rights or ownership
+ rights relating to Covered Code. You may choose to offer, and to
+ charge a fee for, warranty, support, indemnity or liability
+ obligations to one or more recipients of Covered Code. However, You
+ may do so only on Your own behalf, and not on behalf of the Initial
+ Developer or any Contributor. You must make it absolutely clear than
+ any such warranty, support, indemnity or liability obligation is
+ offered by You alone, and You hereby agree to indemnify the Initial
+ Developer and every Contributor for any liability incurred by the
+ Initial Developer or such Contributor as a result of warranty,
+ support, indemnity or liability terms You offer.
+
+ 3.6. Distribution of Executable Versions.
+ You may distribute Covered Code in Executable form only if the
+ requirements of Section 3.1-3.5 have been met for that Covered Code,
+ and if You include a notice stating that the Source Code version of
+ the Covered Code is available under the terms of this License,
+ including a description of how and where You have fulfilled the
+ obligations of Section 3.2. The notice must be conspicuously included
+ in any notice in an Executable version, related documentation or
+ collateral in which You describe recipients' rights relating to the
+ Covered Code. You may distribute the Executable version of Covered
+ Code or ownership rights under a license of Your choice, which may
+ contain terms different from this License, provided that You are in
+ compliance with the terms of this License and that the license for the
+ Executable version does not attempt to limit or alter the recipient's
+ rights in the Source Code version from the rights set forth in this
+ License. If You distribute the Executable version under a different
+ license You must make it absolutely clear that any terms which differ
+ from this License are offered by You alone, not by the Initial
+ Developer or any Contributor. You hereby agree to indemnify the
+ Initial Developer and every Contributor for any liability incurred by
+ the Initial Developer or such Contributor as a result of any such
+ terms You offer.
+
+ 3.7. Larger Works.
+ You may create a Larger Work by combining Covered Code with other code
+ not governed by the terms of this License and distribute the Larger
+ Work as a single product. In such a case, You must make sure the
+ requirements of this License are fulfilled for the Covered Code.
+
+4. Inability to Comply Due to Statute or Regulation.
+
+ If it is impossible for You to comply with any of the terms of this
+ License with respect to some or all of the Covered Code due to
+ statute, judicial order, or regulation then You must: (a) comply with
+ the terms of this License to the maximum extent possible; and (b)
+ describe the limitations and the code they affect. Such description
+ must be included in the LEGAL file described in Section 3.4 and must
+ be included with all distributions of the Source Code. Except to the
+ extent prohibited by statute or regulation, such description must be
+ sufficiently detailed for a recipient of ordinary skill to be able to
+ understand it.
+
+5. Application of this License.
+
+ This License applies to code to which the Initial Developer has
+ attached the notice in Exhibit A and to related Covered Code.
+
+6. Versions of the License.
+
+ 6.1. New Versions.
+ Netscape Communications Corporation ("Netscape") may publish revised
+ and/or new versions of the License from time to time. Each version
+ will be given a distinguishing version number.
+
+ 6.2. Effect of New Versions.
+ Once Covered Code has been published under a particular version of the
+ License, You may always continue to use it under the terms of that
+ version. You may also choose to use such Covered Code under the terms
+ of any subsequent version of the License published by Netscape. No one
+ other than Netscape has the right to modify the terms applicable to
+ Covered Code created under this License.
+
+ 6.3. Derivative Works.
+ If You create or use a modified version of this License (which you may
+ only do in order to apply it to code which is not already Covered Code
+ governed by this License), You must (a) rename Your license so that
+ the phrases "Mozilla", "MOZILLAPL", "MOZPL", "Netscape",
+ "MPL", "NPL" or any confusingly similar phrase do not appear in your
+ license (except to note that your license differs from this License)
+ and (b) otherwise make it clear that Your version of the license
+ contains terms which differ from the Mozilla Public License and
+ Netscape Public License. (Filling in the name of the Initial
+ Developer, Original Code or Contributor in the notice described in
+ Exhibit A shall not of themselves be deemed to be modifications of
+ this License.)
+
+7. DISCLAIMER OF WARRANTY.
+
+ COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ WITHOUT LIMITATION, WARRANTIES THAT THE COVERED CODE IS FREE OF
+ DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE OR NON-INFRINGING.
+ THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED CODE
+ IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT,
+ YOU (NOT THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE
+ COST OF ANY NECESSARY SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER
+ OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS LICENSE. NO USE OF
+ ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER THIS DISCLAIMER.
+
+8. TERMINATION.
+
+ 8.1. This License and the rights granted hereunder will terminate
+ automatically if You fail to comply with terms herein and fail to cure
+ such breach within 30 days of becoming aware of the breach. All
+ sublicenses to the Covered Code which are properly granted shall
+ survive any termination of this License. Provisions which, by their
+ nature, must remain in effect beyond the termination of this License
+ shall survive.
+
+ 8.2. If You initiate litigation by asserting a patent infringement
+ claim (excluding declatory judgment actions) against Initial Developer
+ or a Contributor (the Initial Developer or Contributor against whom
+ You file such action is referred to as "Participant") alleging that:
+
+ (a) such Participant's Contributor Version directly or indirectly
+ infringes any patent, then any and all rights granted by such
+ Participant to You under Sections 2.1 and/or 2.2 of this License
+ shall, upon 60 days notice from Participant terminate prospectively,
+ unless if within 60 days after receipt of notice You either: (i)
+ agree in writing to pay Participant a mutually agreeable reasonable
+ royalty for Your past and future use of Modifications made by such
+ Participant, or (ii) withdraw Your litigation claim with respect to
+ the Contributor Version against such Participant. If within 60 days
+ of notice, a reasonable royalty and payment arrangement are not
+ mutually agreed upon in writing by the parties or the litigation claim
+ is not withdrawn, the rights granted by Participant to You under
+ Sections 2.1 and/or 2.2 automatically terminate at the expiration of
+ the 60 day notice period specified above.
+
+ (b) any software, hardware, or device, other than such Participant's
+ Contributor Version, directly or indirectly infringes any patent, then
+ any rights granted to You by such Participant under Sections 2.1(b)
+ and 2.2(b) are revoked effective as of the date You first made, used,
+ sold, distributed, or had made, Modifications made by that
+ Participant.
+
+ 8.3. If You assert a patent infringement claim against Participant
+ alleging that such Participant's Contributor Version directly or
+ indirectly infringes any patent where such claim is resolved (such as
+ by license or settlement) prior to the initiation of patent
+ infringement litigation, then the reasonable value of the licenses
+ granted by such Participant under Sections 2.1 or 2.2 shall be taken
+ into account in determining the amount or value of any payment or
+ license.
+
+ 8.4. In the event of termination under Sections 8.1 or 8.2 above,
+ all end user license agreements (excluding distributors and resellers)
+ which have been validly granted by You or any distributor hereunder
+ prior to termination shall survive termination.
+
+9. LIMITATION OF LIABILITY.
+
+ UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, WHETHER TORT
+ (INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE, SHALL YOU, THE INITIAL
+ DEVELOPER, ANY OTHER CONTRIBUTOR, OR ANY DISTRIBUTOR OF COVERED CODE,
+ OR ANY SUPPLIER OF ANY OF SUCH PARTIES, BE LIABLE TO ANY PERSON FOR
+ ANY INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY
+ CHARACTER INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF GOODWILL,
+ WORK STOPPAGE, COMPUTER FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER
+ COMMERCIAL DAMAGES OR LOSSES, EVEN IF SUCH PARTY SHALL HAVE BEEN
+ INFORMED OF THE POSSIBILITY OF SUCH DAMAGES. THIS LIMITATION OF
+ LIABILITY SHALL NOT APPLY TO LIABILITY FOR DEATH OR PERSONAL INJURY
+ RESULTING FROM SUCH PARTY'S NEGLIGENCE TO THE EXTENT APPLICABLE LAW
+ PROHIBITS SUCH LIMITATION. SOME JURISDICTIONS DO NOT ALLOW THE
+ EXCLUSION OR LIMITATION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO
+ THIS EXCLUSION AND LIMITATION MAY NOT APPLY TO YOU.
+
+10. U.S. GOVERNMENT END USERS.
+
+ The Covered Code is a "commercial item," as that term is defined in
+ 48 C.F.R. 2.101 (Oct. 1995), consisting of "commercial computer
+ software" and "commercial computer software documentation," as such
+ terms are used in 48 C.F.R. 12.212 (Sept. 1995). Consistent with 48
+ C.F.R. 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 (June 1995),
+ all U.S. Government End Users acquire Covered Code with only those
+ rights set forth herein.
+
+11. MISCELLANEOUS.
+
+ This License represents the complete agreement concerning subject
+ matter hereof. If any provision of this License is held to be
+ unenforceable, such provision shall be reformed only to the extent
+ necessary to make it enforceable. This License shall be governed by
+ California law provisions (except to the extent applicable law, if
+ any, provides otherwise), excluding its conflict-of-law provisions.
+ With respect to disputes in which at least one party is a citizen of,
+ or an entity chartered or registered to do business in the United
+ States of America, any litigation relating to this License shall be
+ subject to the jurisdiction of the Federal Courts of the Northern
+ District of California, with venue lying in Santa Clara County,
+ California, with the losing party responsible for costs, including
+ without limitation, court costs and reasonable attorneys' fees and
+ expenses. The application of the United Nations Convention on
+ Contracts for the International Sale of Goods is expressly excluded.
+ Any law or regulation which provides that the language of a contract
+ shall be construed against the drafter shall not apply to this
+ License.
+
+12. RESPONSIBILITY FOR CLAIMS.
+
+ As between Initial Developer and the Contributors, each party is
+ responsible for claims and damages arising, directly or indirectly,
+ out of its utilization of rights under this License and You agree to
+ work with Initial Developer and Contributors to distribute such
+ responsibility on an equitable basis. Nothing herein is intended or
+ shall be deemed to constitute any admission of liability.
+
+13. MULTIPLE-LICENSED CODE.
+
+ Initial Developer may designate portions of the Covered Code as
+ "Multiple-Licensed". "Multiple-Licensed" means that the Initial
+ Developer permits you to utilize portions of the Covered Code under
+ Your choice of the NPL or the alternative licenses, if any, specified
+ by the Initial Developer in the file described in Exhibit A.
+
+EXHIBIT A -Mozilla Public License.
+
+ ``The contents of this file are subject to the Mozilla Public License
+ Version 1.1 (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.mozilla.org/MPL/
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
+ License for the specific language governing rights and limitations
+ under the License.
+
+ The Original Code is ______________________________________.
+
+ The Initial Developer of the Original Code is ________________________.
+ Portions created by ______________________ are Copyright (C) ______
+ _______________________. All Rights Reserved.
+
+ Contributor(s): ______________________________________.
+
+ Alternatively, the contents of this file may be used under the terms
+ of the _____ license (the "[___] License"), in which case the
+ provisions of [______] License are applicable instead of those
+ above. If you wish to allow use of your version of this file only
+ under the terms of the [____] License and not to allow others to use
+ your version of this file under the MPL, indicate your decision by
+ deleting the provisions above and replace them with the notice and
+ other provisions required by the [___] License. If you do not delete
+ the provisions above, a recipient may use your version of this file
+ under either the MPL or the [___] License."
+
+ [NOTE: The text of this Exhibit A may differ slightly from the text of
+ the notices in the Source Code files of the Original Code. You should
+ use the text of this Exhibit A rather than the text found in the
+ Original Code Source Code for Your Modifications.]
+
+
diff --git a/qpid/dotnet/Qpid.Common/lib/saxon/saxon8.jar b/qpid/dotnet/Qpid.Common/lib/saxon/saxon8.jar
new file mode 100644
index 0000000000..197ce75c5b
--- /dev/null
+++ b/qpid/dotnet/Qpid.Common/lib/saxon/saxon8.jar
Binary files differ
diff --git a/qpid/dotnet/Qpid.Common/lib/seclib-1.0.0/Org.Mentalis.Security.dll b/qpid/dotnet/Qpid.Common/lib/seclib-1.0.0/Org.Mentalis.Security.dll
new file mode 100644
index 0000000000..c3b95d71ba
--- /dev/null
+++ b/qpid/dotnet/Qpid.Common/lib/seclib-1.0.0/Org.Mentalis.Security.dll
Binary files differ
diff --git a/qpid/dotnet/Qpid.Common/lib/seclib-1.0.0/seclib-license.txt b/qpid/dotnet/Qpid.Common/lib/seclib-1.0.0/seclib-license.txt
new file mode 100644
index 0000000000..e837183135
--- /dev/null
+++ b/qpid/dotnet/Qpid.Common/lib/seclib-1.0.0/seclib-license.txt
@@ -0,0 +1,13 @@
+Source Code License
+
+Copyright © 2002-2006, The Mentalis.org Team
+All rights reserved.
+http://www.mentalis.org/
+
+Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+
+- Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
+
+- Neither the name of the Mentalis.org Team, nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/qpid/dotnet/Qpid.Common/resources/registry.template b/qpid/dotnet/Qpid.Common/resources/registry.template
new file mode 100644
index 0000000000..d870ef3866
--- /dev/null
+++ b/qpid/dotnet/Qpid.Common/resources/registry.template
@@ -0,0 +1,24 @@
+<?xml version="1.0"?>
+<!--
+ -
+ - Licensed to the Apache Software Foundation (ASF) under one
+ - or more contributor license agreements. See the NOTICE file
+ - distributed with this work for additional information
+ - regarding copyright ownership. The ASF licenses this file
+ - to you under the Apache License, Version 2.0 (the
+ - "License"); you may not use this file except in compliance
+ - with the License. You may obtain a copy of the License at
+ -
+ - http://www.apache.org/licenses/LICENSE-2.0
+ -
+ - Unless required by applicable law or agreed to in writing,
+ - software distributed under the License is distributed on an
+ - "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ - KIND, either express or implied. See the License for the
+ - specific language governing permissions and limitations
+ - under the License.
+ -
+ -->
+<registries>
+ <registry name="MainRegistry"/>
+</registries>
diff --git a/qpid/dotnet/Qpid.Common/stylesheets/csharp.xsl b/qpid/dotnet/Qpid.Common/stylesheets/csharp.xsl
new file mode 100644
index 0000000000..ed04a40403
--- /dev/null
+++ b/qpid/dotnet/Qpid.Common/stylesheets/csharp.xsl
@@ -0,0 +1,251 @@
+<?xml version='1.0'?>
+<!--
+
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+
+-->
+
+<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:amq="http://amq.org">
+
+<!-- this class contains the templates for generating C# source code for a given framing model -->
+<xsl:import href="utils.xsl"/>
+<xsl:output method="text" indent="yes" name="textFormat"/>
+
+<xsl:param name="registry_name"/>
+
+<xsl:template match="/">
+ <xsl:apply-templates mode="generate-multi" select="frames"/>
+ <xsl:apply-templates mode="generate-registry" select="frames"/>
+</xsl:template>
+
+<!-- processes all frames outputting the classes in a single stream -->
+<!-- (useful for debugging etc) -->
+<xsl:template match="frame" mode="generate-single">
+ <xsl:call-template name="generate-class">
+ <xsl:with-param name="f" select="."/>
+ </xsl:call-template>
+</xsl:template>
+
+<!-- generates seperate file for each class/frame -->
+<xsl:template match="frame" mode="generate-multi">
+ <xsl:variable name="uri" select="concat(@name, '.cs')"/>
+ wrote <xsl:value-of select="$uri"/>
+ <xsl:result-document href="{$uri}" format="textFormat">
+ <xsl:call-template name="generate-class">
+ <xsl:with-param name="f" select="."/>
+ </xsl:call-template>
+ </xsl:result-document>
+</xsl:template>
+
+<!-- main class generation template -->
+<xsl:template name="generate-class">
+ <xsl:param name="f"/>
+using Apache.Qpid.Buffer;
+using System.Text;
+
+namespace Apache.Qpid.Framing
+{
+ ///
+ /// <summary>This class is autogenerated
+ /// Do not modify.
+ ///</summary>
+ /// @author Code Generator Script by robert.j.greig@jpmorgan.com
+ public class <xsl:value-of select="$f/@name"/> : AMQMethodBody , IEncodableAMQDataBlock
+ {
+ public const int CLASS_ID = <xsl:value-of select="$f/@class-id"/>;
+ public const int METHOD_ID = <xsl:value-of select="$f/@method-id"/>;
+
+ <xsl:for-each select="$f/field">
+ <xsl:text>public </xsl:text><xsl:value-of select="@csharp-type"/>
+ <xsl:text> </xsl:text>
+ <xsl:value-of select="@name"/>;
+ </xsl:for-each>
+
+ protected override ushort Clazz
+ {
+ get
+ {
+ return <xsl:value-of select="$f/@class-id"/>;
+ }
+ }
+
+ protected override ushort Method
+ {
+ get
+ {
+ return <xsl:value-of select="$f/@method-id"/>;
+ }
+ }
+
+ protected override uint BodySize
+ {
+ get
+ {
+ <xsl:choose>
+ <xsl:when test="$f/field">
+ return (uint)
+ <xsl:for-each select="$f/field">
+ <xsl:if test="position() != 1">+
+ </xsl:if>
+ <xsl:value-of select="amq:field-length(.)"/>
+ </xsl:for-each>
+ ;
+ </xsl:when>
+ <xsl:otherwise>return 0;</xsl:otherwise>
+ </xsl:choose>
+ }
+ }
+
+ protected override void WriteMethodPayload(ByteBuffer buffer)
+ {
+ <xsl:for-each select="$f/field">
+ <xsl:if test="@type != 'bit'">
+ <xsl:value-of select="amq:encoder(.)"/>;
+ </xsl:if>
+ <xsl:if test="@type = 'bit' and @boolean-index = 1">
+ <xsl:text>EncodingUtils.WriteBooleans(buffer, new bool[]{</xsl:text>
+ <xsl:value-of select="$f/field[@type='bit']/@name" separator=", "/>});
+ </xsl:if>
+ </xsl:for-each>
+ }
+
+ protected override void PopulateMethodBodyFromBuffer(ByteBuffer buffer)
+ {
+ <xsl:for-each select="$f/field">
+ <xsl:value-of select="amq:decoder(.)"/>;
+ </xsl:for-each>
+ }
+
+ public override string ToString()
+ {
+ StringBuilder buf = new StringBuilder(base.ToString());
+ <xsl:for-each select="$f/field">
+ <xsl:text>buf.Append(" </xsl:text><xsl:value-of select="@name"/>: ").Append(<xsl:value-of select="@name"/>);
+ </xsl:for-each>
+ return buf.ToString();
+ }
+
+ public static AMQFrame CreateAMQFrame(ushort channelId<xsl:if test="$f/field">, </xsl:if><xsl:value-of select="$f/field/concat(@csharp-type, ' ', @name)" separator=", "/>)
+ {
+ <xsl:value-of select="@name"/> body = new <xsl:value-of select="@name"/>();
+ <xsl:for-each select="$f/field">
+ <xsl:value-of select="concat('body.', @name, ' = ', @name)"/>;
+ </xsl:for-each>
+ AMQFrame frame = new AMQFrame();
+ frame.Channel = channelId;
+ frame.BodyFrame = body;
+ return frame;
+ }
+}
+}
+</xsl:template>
+
+<xsl:template match="/" mode="generate-registry">
+ <xsl:text>Matching root for registry mode!</xsl:text>
+ <xsl:value-of select="."/>
+ <xsl:apply-templates select="frames" mode="generate-registry"/>
+</xsl:template>
+
+<xsl:template match="registries" mode="generate-registry">
+Wrote MethodBodyDecoderRegistry.cs
+ <xsl:result-document href="MethodBodyDecoderRegistry.cs" format="textFormat">
+using System;
+using System.Collections;
+using log4net;
+
+namespace Apache.Qpid.Framing
+{
+
+
+ ///
+ /// <summary>This class is autogenerated
+ /// Do not modify.
+ /// </summary>
+ /// @author Code Generator Script by robert.j.greig@jpmorgan.com
+
+ public class MethodBodyDecoderRegistry
+ {
+ private static readonly ILog _log = LogManager.GetLogger(typeof(MethodBodyDecoderRegistry));
+
+ private static readonly Hashtable _classMethodProductToMethodBodyMap = new Hashtable();
+
+ static MethodBodyDecoderRegistry()
+ {
+ <xsl:for-each select="registry">
+ <xsl:value-of select="concat(@name, '.Register(_classMethodProductToMethodBodyMap)')"/>;
+ </xsl:for-each>
+ }
+
+ public static AMQMethodBody Get(int clazz, int method)
+ {
+ Type bodyClass = (Type) _classMethodProductToMethodBodyMap[clazz * 1000 + method];
+ if (bodyClass != null)
+ {
+ try
+ {
+ return (AMQMethodBody) Activator.CreateInstance(bodyClass);
+ }
+ catch (Exception e)
+ {
+ throw new AMQFrameDecodingException(_log, "Unable to instantiate body class for class " + clazz + " and method " + method + ": " + e, e);
+ }
+ }
+ else
+ {
+ throw new AMQFrameDecodingException(_log, "Unable to find a suitable decoder for class " + clazz + " and method " + method);
+ }
+ }
+ }
+ }
+ </xsl:result-document>
+</xsl:template>
+
+<xsl:template match="frames" mode="list-registry">
+ <xsl:if test="$registry_name">
+
+ <xsl:variable name="file" select="concat($registry_name, '.cs')"/>
+ wrote <xsl:value-of select="$file"/>
+ <xsl:result-document href="{$file}" format="textFormat">
+
+using System.Collections;
+namespace Apache.Qpid.Framing
+{
+ /**
+ * This class is autogenerated, do not modify. [From <xsl:value-of select="@protocol"/>]
+ */
+ class <xsl:value-of select="$registry_name"/>
+ {
+ internal static void Register(Hashtable map)
+ {
+ <xsl:for-each select="frame">
+ <xsl:text>map[</xsl:text>
+ <xsl:value-of select="@class-id"/>
+ <xsl:text> * 1000 + </xsl:text>
+ <xsl:value-of select="@method-id"/>
+ <xsl:text>] = typeof(</xsl:text>
+ <xsl:value-of select="@name"/>);
+ </xsl:for-each>
+ }
+}
+}
+ </xsl:result-document>
+
+ </xsl:if>
+</xsl:template>
+
+</xsl:stylesheet>
diff --git a/qpid/dotnet/Qpid.Common/stylesheets/framing.xsl b/qpid/dotnet/Qpid.Common/stylesheets/framing.xsl
new file mode 100644
index 0000000000..119f439599
--- /dev/null
+++ b/qpid/dotnet/Qpid.Common/stylesheets/framing.xsl
@@ -0,0 +1,65 @@
+<?xml version='1.0'?>
+<!--
+
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+
+-->
+
+<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:amq="http://amq.org">
+
+<xsl:import href="prepare1.xsl"/>
+<xsl:import href="prepare2.xsl"/>
+<xsl:import href="prepare3.xsl"/>
+<xsl:import href="csharp.xsl"/>
+
+<xsl:output indent="yes"/>
+<xsl:output method="text" indent="yes" name="textFormat"/>
+
+<xsl:template match="/">
+ <xsl:variable name="prepare1">
+ <xsl:apply-templates mode="prepare1" select="."/>
+ </xsl:variable>
+
+ <xsl:variable name="prepare2">
+ <xsl:apply-templates mode="prepare2" select="$prepare1"/>
+ </xsl:variable>
+
+ <xsl:variable name="model">
+ <xsl:apply-templates mode="prepare3" select="$prepare2"/>
+ </xsl:variable>
+
+ <xsl:apply-templates mode="generate-multi" select="$model"/>
+ <xsl:apply-templates mode="list-registry" select="$model"/>
+
+ <!-- dump out the intermediary files for debugging -->
+ <!--
+ <xsl:result-document href="prepare1.out">
+ <xsl:copy-of select="$prepare1"/>
+ </xsl:result-document>
+
+ <xsl:result-document href="prepare2.out">
+ <xsl:copy-of select="$prepare2"/>
+ </xsl:result-document>
+
+ <xsl:result-document href="model.out">
+ <xsl:copy-of select="$model"/>
+ </xsl:result-document>
+ -->
+</xsl:template>
+
+</xsl:stylesheet>
diff --git a/qpid/dotnet/Qpid.Common/stylesheets/java.xsl b/qpid/dotnet/Qpid.Common/stylesheets/java.xsl
new file mode 100644
index 0000000000..7297c6ae62
--- /dev/null
+++ b/qpid/dotnet/Qpid.Common/stylesheets/java.xsl
@@ -0,0 +1,230 @@
+<?xml version='1.0'?>
+<!--
+
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+
+-->
+
+<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:amq="http://amq.org">
+
+<!-- this class contains the templates for generating java source code for a given framing model -->
+<xsl:import href="utils.xsl"/>
+<xsl:output method="text" indent="yes" name="textFormat"/>
+
+<xsl:param name="registry_name"/>
+
+<xsl:template match="/">
+ <xsl:apply-templates mode="generate-multi" select="frames"/>
+ <xsl:apply-templates mode="generate-registry" select="frames"/>
+</xsl:template>
+
+<!-- processes all frames outputting the classes in a single stream -->
+<!-- (useful for debugging etc) -->
+<xsl:template match="frame" mode="generate-single">
+ <xsl:call-template name="generate-class">
+ <xsl:with-param name="f" select="."/>
+ </xsl:call-template>
+</xsl:template>
+
+<!-- generates seperate file for each class/frame -->
+<xsl:template match="frame" mode="generate-multi">
+ <xsl:variable name="uri" select="concat(@name, '.java')"/>
+ wrote <xsl:value-of select="$uri"/>
+ <xsl:result-document href="{$uri}" format="textFormat">
+ <xsl:call-template name="generate-class">
+ <xsl:with-param name="f" select="."/>
+ </xsl:call-template>
+ </xsl:result-document>
+</xsl:template>
+
+<!-- main class generation template -->
+<xsl:template name="generate-class">
+ <xsl:param name="f"/>
+package org.openamq.framing;
+
+import org.apache.mina.common.ByteBuffer;
+
+/**
+ * This class is autogenerated, do not modify. [From <xsl:value-of select="$f/parent::frames/@protocol"/>]
+ */
+public class <xsl:value-of select="$f/@name"/> extends AMQMethodBody implements EncodableAMQDataBlock
+{
+ public static final int CLASS_ID = <xsl:value-of select="$f/@class-id"/>;
+ public static final int METHOD_ID = <xsl:value-of select="$f/@method-id"/>;
+
+ <xsl:for-each select="$f/field">
+ <xsl:text>public </xsl:text><xsl:value-of select="@java-type"/>
+ <xsl:text> </xsl:text>
+ <xsl:value-of select="@name"/>;
+ </xsl:for-each>
+
+ protected int getClazz()
+ {
+ return <xsl:value-of select="$f/@class-id"/>;
+ }
+
+ protected int getMethod()
+ {
+ return <xsl:value-of select="$f/@method-id"/>;
+ }
+
+ protected int getBodySize()
+ {
+ <xsl:choose>
+ <xsl:when test="$f/field">
+ return
+ <xsl:for-each select="$f/field">
+ <xsl:if test="position() != 1">+
+ </xsl:if>
+ <xsl:value-of select="amq:field-length(.)"/>
+ </xsl:for-each>
+ ;
+ </xsl:when>
+ <xsl:otherwise>return 0;</xsl:otherwise>
+ </xsl:choose>
+ }
+
+ protected void writeMethodPayload(ByteBuffer buffer)
+ {
+ <xsl:for-each select="$f/field">
+ <xsl:if test="@type != 'bit'">
+ <xsl:value-of select="amq:encoder(.)"/>;
+ </xsl:if>
+ <xsl:if test="@type = 'bit' and @boolean-index = 1">
+ <xsl:text>EncodingUtils.writeBooleans(buffer, new boolean[]{</xsl:text>
+ <xsl:value-of select="$f/field[@type='bit']/@name" separator=", "/>});
+ </xsl:if>
+ </xsl:for-each>
+ }
+
+ public void populateMethodBodyFromBuffer(ByteBuffer buffer) throws AMQFrameDecodingException
+ {
+ <xsl:for-each select="$f/field">
+ <xsl:value-of select="amq:decoder(.)"/>;
+ </xsl:for-each>
+ }
+
+ public String toString()
+ {
+ StringBuffer buf = new StringBuffer(super.toString());
+ <xsl:for-each select="$f/field">
+ <xsl:text>buf.append(" </xsl:text><xsl:value-of select="@name"/>: ").append(<xsl:value-of select="@name"/>);
+ </xsl:for-each>
+ return buf.toString();
+ }
+
+ public static AMQFrame createAMQFrame(int channelId<xsl:if test="$f/field">, </xsl:if><xsl:value-of select="$f/field/concat(@java-type, ' ', @name)" separator=", "/>)
+ {
+ <xsl:value-of select="@name"/> body = new <xsl:value-of select="@name"/>();
+ <xsl:for-each select="$f/field">
+ <xsl:value-of select="concat('body.', @name, ' = ', @name)"/>;
+ </xsl:for-each>
+ AMQFrame frame = new AMQFrame();
+ frame.channel = channelId;
+ frame.bodyFrame = body;
+ return frame;
+ }
+}
+</xsl:template>
+
+<xsl:template match="/" mode="generate-registry">
+ <xsl:text>Matching root for registry mode!</xsl:text>
+ <xsl:value-of select="."/>
+ <xsl:apply-templates select="frames" mode="generate-registry"/>
+</xsl:template>
+
+<xsl:template match="registries" mode="generate-registry">
+Wrote MethodBodyDecoderRegistry.java
+ <xsl:result-document href="MethodBodyDecoderRegistry.java" format="textFormat">package org.openamq.framing;
+
+import java.util.Map;
+import java.util.HashMap;
+import org.apache.log4j.Logger;
+import org.openamq.AMQException;
+
+/**
+ * This class is autogenerated, do not modify.
+ */
+public final class MethodBodyDecoderRegistry
+{
+ private static final Logger _log = Logger.getLogger(MethodBodyDecoderRegistry.class);
+
+ private static final Map _classMethodProductToMethodBodyMap = new HashMap();
+
+ static
+ {
+ <xsl:for-each select="registry">
+ <xsl:value-of select="concat(@name, '.register(_classMethodProductToMethodBodyMap)')"/>;
+ </xsl:for-each>
+ }
+
+ public static AMQMethodBody get(int clazz, int method) throws AMQFrameDecodingException
+ {
+ Class bodyClass = (Class) _classMethodProductToMethodBodyMap.get(new Integer(clazz * 1000 + method));
+ if (bodyClass != null)
+ {
+ try
+ {
+ return (AMQMethodBody) bodyClass.newInstance();
+ }
+ catch (Exception e)
+ {
+ throw new AMQFrameDecodingException(_log, "Unable to instantiate body class for class " + clazz + " and method " + method + ": " + e, e);
+ }
+ }
+ else
+ {
+ throw new AMQFrameDecodingException(_log, "Unable to find a suitable decoder for class " + clazz + " and method " + method);
+ }
+ }
+}
+</xsl:result-document>
+</xsl:template>
+
+<xsl:template match="frames" mode="list-registry">
+ <xsl:if test="$registry_name">
+
+ <xsl:variable name="file" select="concat($registry_name, '.java')"/>
+ wrote <xsl:value-of select="$file"/>
+ <xsl:result-document href="{$file}" format="textFormat">package org.openamq.framing;
+
+import java.util.Map;
+
+/**
+ * This class is autogenerated, do not modify. [From <xsl:value-of select="@protocol"/>]
+ */
+class <xsl:value-of select="$registry_name"/>
+{
+ static void register(Map map)
+ {
+ <xsl:for-each select="frame">
+ <xsl:text>map.put(new Integer(</xsl:text>
+ <xsl:value-of select="@class-id"/>
+ <xsl:text> * 1000 + </xsl:text>
+ <xsl:value-of select="@method-id"/>
+ <xsl:text>), </xsl:text>
+ <xsl:value-of select="concat(@name, '.class')"/>);
+ </xsl:for-each>
+ }
+}
+ </xsl:result-document>
+
+ </xsl:if>
+</xsl:template>
+
+</xsl:stylesheet>
diff --git a/qpid/dotnet/Qpid.Common/stylesheets/prepare1.xsl b/qpid/dotnet/Qpid.Common/stylesheets/prepare1.xsl
new file mode 100644
index 0000000000..e266b0a9cc
--- /dev/null
+++ b/qpid/dotnet/Qpid.Common/stylesheets/prepare1.xsl
@@ -0,0 +1,109 @@
+<?xml version='1.0'?>
+<!--
+
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+
+-->
+
+<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:amq="http://amq.org">
+
+<xsl:import href="utils.xsl"/>
+
+<xsl:output indent="yes"/>
+<xsl:param name="asl_base"/>
+
+<!-- pre-process, phase 1 -->
+
+<xsl:template match="/">
+ <xsl:apply-templates select="protocol" mode="prepare1"/>
+</xsl:template>
+
+<xsl:template match="amqp" mode="prepare1">
+ <frames>
+ <xsl:attribute name="protocol">
+ <xsl:value-of select="@comment"/>
+ <xsl:text> (</xsl:text>
+ <xsl:text>major=</xsl:text><xsl:value-of select="option[@name='protocol_major']/@value"/>
+ <xsl:text>, minor=</xsl:text><xsl:value-of select="option[@name='protocol_minor']/@value"/>
+ <xsl:text>)</xsl:text>
+ </xsl:attribute>
+ <xsl:apply-templates mode="prepare1" select="inherit"/>
+ <xsl:apply-templates mode="prepare1" select="include"/>
+ <xsl:apply-templates mode="prepare1" select="domain"/>
+ <xsl:apply-templates mode="prepare1" select="class"/>
+ </frames>
+</xsl:template>
+
+<xsl:template match="include" mode="prepare1">
+ <xsl:if test="@filename != 'asl_constants.asl'">
+ <!-- skip asl_constants.asl, we don't need it and it is not well formed so causes error warnings -->
+ <xsl:apply-templates select="document(@filename)" mode="prepare1"/>
+ </xsl:if>
+</xsl:template>
+
+<xsl:template match="inherit" mode="prepare1">
+ <xsl:variable name="ibase" select="concat('file:///', $asl_base, '/', @name, '.asl')"/>
+ <xsl:choose>
+ <xsl:when test="document($ibase)">
+ <xsl:apply-templates select="document($ibase)" mode="prepare1"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:message>
+ Could not inherit from <xsl:value-of select="$ibase"/>; file not found.
+ </xsl:message>
+ </xsl:otherwise>
+ </xsl:choose>
+</xsl:template>
+
+<xsl:template match="class[@index]" mode="prepare1">
+ <xsl:apply-templates select="method" mode="prepare1"/>
+</xsl:template>
+
+<xsl:template match="method" mode="prepare1">
+ <xsl:if test="parent::class[@index]"><!-- there is a template class that has no index, which we want to skip -->
+ <frame>
+ <xsl:attribute name="name"><xsl:value-of select="amq:class-name(parent::class/@name, @name)"/></xsl:attribute>
+ <xsl:attribute name="class-id"><xsl:value-of select="parent::class/@index"/></xsl:attribute>
+ <xsl:if test="@index">
+ <xsl:attribute name="method-id"><xsl:value-of select="@index"/></xsl:attribute>
+ </xsl:if>
+ <xsl:if test="not(@index)">
+ <xsl:attribute name="method-id"><xsl:number count="method"/></xsl:attribute>
+ </xsl:if>
+
+ <xsl:apply-templates select="field" mode="prepare1"/>
+ </frame>
+ </xsl:if>
+</xsl:template>
+
+<xsl:template match="domain" mode="prepare1">
+ <domain>
+ <name><xsl:value-of select="@name"/></name>
+ <type><xsl:value-of select="@type"/></type>
+ </domain>
+</xsl:template>
+
+<xsl:template match="field" mode="prepare1">
+ <field>
+ <xsl:copy-of select="@name"/>
+ <xsl:copy-of select="@type"/>
+ <xsl:copy-of select="@domain"/>
+ </field>
+</xsl:template>
+
+</xsl:stylesheet>
diff --git a/qpid/dotnet/Qpid.Common/stylesheets/prepare2.xsl b/qpid/dotnet/Qpid.Common/stylesheets/prepare2.xsl
new file mode 100644
index 0000000000..0a64eb6f86
--- /dev/null
+++ b/qpid/dotnet/Qpid.Common/stylesheets/prepare2.xsl
@@ -0,0 +1,68 @@
+<?xml version='1.0'?>
+<!--
+
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+
+-->
+
+<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:amq="http://amq.org">
+
+<xsl:import href="utils.xsl"/>
+
+<xsl:output indent="yes"/>
+
+<!-- pre-process, phase 2 -->
+
+<xsl:key name="domain-lookup" match="domain" use="name"/>
+
+<xsl:template match="/">
+ <xsl:apply-templates mode="prepare2" select="frames"/>
+</xsl:template>
+
+<xsl:template match="field[@domain]" mode="prepare2">
+ <field>
+ <xsl:variable name="t1" select="key('domain-lookup', @domain)/type"/>
+ <xsl:attribute name="name"><xsl:value-of select="amq:field-name(@name)"/></xsl:attribute>
+ <xsl:attribute name="type"><xsl:value-of select="$t1"/></xsl:attribute>
+ </field>
+</xsl:template>
+
+<xsl:template match="field[@type]" mode="prepare2">
+ <field>
+ <xsl:attribute name="name"><xsl:value-of select="amq:field-name(@name)"/></xsl:attribute>
+ <xsl:attribute name="type"><xsl:value-of select="@type"/></xsl:attribute>
+ </field>
+</xsl:template>
+
+<xsl:template match="frames" mode="prepare2">
+ <frames>
+ <xsl:copy-of select="@protocol"/>
+ <xsl:apply-templates mode="prepare2"/>
+ </frames>
+</xsl:template>
+
+<xsl:template match="frame" mode="prepare2">
+ <xsl:element name="{name()}">
+ <xsl:copy-of select="@*"/>
+ <xsl:apply-templates mode="prepare2" select="field"/>
+ </xsl:element>
+</xsl:template>
+
+<xsl:template match="domain" mode="prepare2"></xsl:template>
+
+</xsl:stylesheet>
diff --git a/qpid/dotnet/Qpid.Common/stylesheets/prepare3.xsl b/qpid/dotnet/Qpid.Common/stylesheets/prepare3.xsl
new file mode 100644
index 0000000000..a921160dd0
--- /dev/null
+++ b/qpid/dotnet/Qpid.Common/stylesheets/prepare3.xsl
@@ -0,0 +1,64 @@
+<?xml version='1.0'?>
+<!--
+
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+
+-->
+
+<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:amq="http://amq.org">
+
+<xsl:import href="utils.xsl"/>
+
+<xsl:output indent="yes"/>
+
+<!-- final preparation of the model -->
+
+<xsl:template match="/">
+ <xsl:apply-templates mode="prepare3"/>
+</xsl:template>
+
+<xsl:template match="frames" mode="prepare3">
+ <frames>
+ <xsl:copy-of select="@protocol"/>
+ <xsl:apply-templates mode="prepare3"/>
+ </frames>
+</xsl:template>
+
+<xsl:template match="frame" mode="prepare3">
+ <xsl:element name="frame">
+ <xsl:copy-of select="@*"/>
+ <xsl:if test="field[@type='bit']"><xsl:attribute name="has-bit-field">true</xsl:attribute></xsl:if>
+ <xsl:apply-templates mode="prepare3"/>
+ </xsl:element>
+</xsl:template>
+
+
+<xsl:template match="field" mode="prepare3">
+ <field>
+ <xsl:attribute name="type"><xsl:value-of select="@type"/></xsl:attribute>
+ <!-- ensure the field name is processed to be a valid java name -->
+ <xsl:attribute name="name"><xsl:value-of select="amq:field-name(@name)"/></xsl:attribute>
+ <!-- add some attributes to make code generation easier -->
+ <xsl:attribute name="csharp-type"><xsl:value-of select="amq:csharp-type(@type)"/></xsl:attribute>
+ <xsl:if test="@type='bit'">
+ <xsl:attribute name="boolean-index"><xsl:number count="field[@type='bit']"/></xsl:attribute>
+ </xsl:if>
+ </field>
+</xsl:template>
+
+</xsl:stylesheet>
diff --git a/qpid/dotnet/Qpid.Common/stylesheets/readme.txt b/qpid/dotnet/Qpid.Common/stylesheets/readme.txt
new file mode 100644
index 0000000000..c2f98050a6
--- /dev/null
+++ b/qpid/dotnet/Qpid.Common/stylesheets/readme.txt
@@ -0,0 +1,52 @@
+This directory contains the xsl stylesheets used to generate the code from the
+OpenAMQ protocol specification. They require an XSLT2.0 processor, currently
+Saxon 8 is used.
+
+The generation process is controlled by the framing.xsl stylesheet. This performs
+several phases of transformation, using the other stylesheets. The transformation
+in each phase is defined in a separate file, and these are designed to also allow
+then to be run individually.
+
+The generation takes the amq.asl as input, it also requires that the path to the
+directory where the base asl definitions reside (those definitions that the main
+amq.asl defintion inherits from) be passed in via a paramter called asl_base.
+
+The files involved are as follows:
+
+ framing.xsl The control file for the entire generation process
+
+ prepare1.xsl Resolves the separate files that make up the protocol
+ definition, building a single tree containing all the
+ information as a set of 'frame' elements, each of which
+ has attributes for its name, and ids for the class and
+ method it refers to and contains zero or more field
+ elements.
+
+ A method id is generated based on the order of the
+ method elements within the class elements in the original
+ specification. The class id is taken from the enclosing
+ class element.
+
+ prepare2.xsl Resolves domains into their corresponding types. (This is
+ much easier when all the information is in a single tree,
+ hence the separate frame).
+
+ prepare3.xsl Converts names into valid java names and augments the
+ tree to include information that makes the subsequent
+ generation phase simpler e.g. the index of boolean
+ fields as several boolean flags are combined into a
+ single byte. (This is easier once the domains have been
+ resolved, hence the separate phase).
+
+ java.xsl Generates java classes for each frame, and a registry of
+ all the frames to a 'magic' number generated from their
+ class and method id.
+
+ utils.xsl Contains some utility methods for e.g. producing valid
+ java names.
+
+For debugging the framing.xsl can output the intermediary files. This can be
+enabled by uncommenting the relevant lines (a comment explaining this is
+provided inline).
+
+ \ No newline at end of file
diff --git a/qpid/dotnet/Qpid.Common/stylesheets/registry.xsl b/qpid/dotnet/Qpid.Common/stylesheets/registry.xsl
new file mode 100644
index 0000000000..47a2a29069
--- /dev/null
+++ b/qpid/dotnet/Qpid.Common/stylesheets/registry.xsl
@@ -0,0 +1,33 @@
+<?xml version='1.0'?>
+<!--
+
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+
+-->
+
+<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:amq="http://amq.org">
+
+<xsl:import href="csharp.xsl"/>
+
+<xsl:output method="text" indent="yes" name="textFormat"/>
+
+<xsl:template match="/">
+ <xsl:apply-templates mode="generate-registry" select="registries"/>
+</xsl:template>
+
+</xsl:stylesheet>
diff --git a/qpid/dotnet/Qpid.Common/stylesheets/utils.xsl b/qpid/dotnet/Qpid.Common/stylesheets/utils.xsl
new file mode 100644
index 0000000000..d097bbc4eb
--- /dev/null
+++ b/qpid/dotnet/Qpid.Common/stylesheets/utils.xsl
@@ -0,0 +1,185 @@
+<?xml version='1.0'?>
+<!--
+
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+
+-->
+
+<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:amq="http://amq.org">
+
+<!-- This file contains functions that are used in the generation of the java classes for framing -->
+
+<!-- retrieve the java type of a given amq type -->
+<xsl:function name="amq:csharp-type">
+ <xsl:param name="t"/>
+ <xsl:choose>
+ <xsl:when test="$t='char'">char</xsl:when>
+ <xsl:when test="$t='octet'">byte</xsl:when>
+ <xsl:when test="$t='short'">ushort</xsl:when>
+ <xsl:when test="$t='shortstr'">string</xsl:when>
+ <xsl:when test="$t='longstr'">byte[]</xsl:when>
+ <xsl:when test="$t='bit'">bool</xsl:when>
+ <xsl:when test="$t='long'">uint</xsl:when>
+ <xsl:when test="$t='longlong'">ulong</xsl:when>
+ <xsl:when test="$t='table'">FieldTable</xsl:when>
+ <xsl:otherwise>Object /*WARNING: undefined type*/</xsl:otherwise>
+ </xsl:choose>
+</xsl:function>
+
+<!-- retrieve the code to get the field size of a given amq type -->
+<xsl:function name="amq:field-length">
+ <xsl:param name="f"/>
+ <xsl:choose>
+ <xsl:when test="$f/@type='bit' and $f/@boolean-index=1">
+ <xsl:value-of select="concat('1 /*', $f/@name, '*/')"/>
+ </xsl:when>
+ <xsl:when test="$f/@type='bit' and $f/@boolean-index &gt; 1">
+ <xsl:value-of select="concat('0 /*', $f/@name, '*/')"/>
+ </xsl:when>
+ <xsl:when test="$f/@type='char'">
+ <xsl:value-of select="concat('1 /*', $f/@name, '*/')"/>
+ </xsl:when>
+ <xsl:when test="$f/@type='octet'">
+ <xsl:value-of select="concat('1 /*', $f/@name, '*/')"/>
+ </xsl:when>
+ <xsl:when test="$f/@type='short'">
+ <xsl:value-of select="concat('2 /*', $f/@name, '*/')"/>
+ </xsl:when>
+ <xsl:when test="$f/@type='long'">
+ <xsl:value-of select="concat('4 /*', $f/@name, '*/')"/>
+ </xsl:when>
+ <xsl:when test="$f/@type='longlong'">
+ <xsl:value-of select="concat('8 /*', $f/@name, '*/')"/>
+ </xsl:when>
+ <xsl:when test="$f/@type='shortstr'">
+ <xsl:value-of select="concat('(uint)EncodingUtils.EncodedShortStringLength(', $f/@name, ')')"/>
+ </xsl:when>
+ <xsl:when test="$f/@type='longstr'">
+ <xsl:value-of select="concat('4 + (uint) (', $f/@name, ' == null ? 0 : ', $f/@name, '.Length)')"/>
+ </xsl:when>
+ <xsl:when test="$f/@type='table'">
+ <xsl:value-of select="concat('(uint)EncodingUtils.EncodedFieldTableLength(', $f/@name, ')')"/>
+ </xsl:when>
+ <xsl:otherwise><xsl:text>/* WARNING: COULD NOT DETERMINE FIELD SIZE */</xsl:text></xsl:otherwise>
+ </xsl:choose>
+</xsl:function>
+
+<!-- retrieve the code to encode a field of a given amq type -->
+<!-- Note:
+ This method will not provide an encoder for a bit field.
+ Bit fields should be encoded together separately. -->
+
+<xsl:function name="amq:encoder">
+ <xsl:param name="f"/>
+ <xsl:choose>
+ <xsl:when test="$f/@type='char'">
+ <xsl:value-of select="concat('buffer.Put(', $f/@name, ')')"/>
+ </xsl:when>
+ <xsl:when test="$f/@type='octet'">
+ <xsl:value-of select="concat('buffer.Put(', $f/@name, ')')"/>
+ </xsl:when>
+ <xsl:when test="$f/@type='short'">
+ <xsl:value-of select="concat('buffer.Put(', $f/@name, ')')"/>
+ </xsl:when>
+ <xsl:when test="$f/@type='long'">
+ <xsl:value-of select="concat('buffer.Put(', $f/@name, ')')"/>
+ </xsl:when>
+ <xsl:when test="$f/@type='longlong'">
+ <xsl:value-of select="concat('buffer.Put(', $f/@name, ')')"/>
+ </xsl:when>
+ <xsl:when test="$f/@type='shortstr'">
+ <xsl:value-of select="concat('EncodingUtils.WriteShortStringBytes(buffer, ', $f/@name, ')')"/>
+ </xsl:when>
+ <xsl:when test="$f/@type='longstr'">
+ <xsl:value-of select="concat('EncodingUtils.WriteLongstr(buffer, ', $f/@name, ')')"/>
+ </xsl:when>
+ <xsl:when test="$f/@type='table'">
+ <xsl:value-of select="concat('EncodingUtils.WriteFieldTableBytes(buffer, ', $f/@name, ')')"/>
+ </xsl:when>
+ <xsl:otherwise><xsl:text>/* WARNING: COULD NOT DETERMINE ENCODER */</xsl:text></xsl:otherwise>
+ </xsl:choose>
+</xsl:function>
+
+<!-- retrieve the code to decode a field of a given amq type -->
+<xsl:function name="amq:decoder">
+ <xsl:param name="f"/>
+ <xsl:choose>
+ <xsl:when test="$f/@type='bit'">
+ <xsl:if test="$f/@boolean-index = 1">
+ <xsl:text>bool[] bools = EncodingUtils.ReadBooleans(buffer);</xsl:text>
+ </xsl:if>
+ <xsl:value-of select="concat($f/@name, ' = bools[', $f/@boolean-index - 1 , ']')"/>
+ </xsl:when>
+ <xsl:when test="$f/@type='char'">
+ <xsl:value-of select="concat($f/@name, ' = buffer.GetChar()')"/>
+ </xsl:when>
+ <xsl:when test="$f/@type='octet'">
+ <xsl:value-of select="concat($f/@name, ' = buffer.GetByte()')"/>
+ </xsl:when>
+ <xsl:when test="$f/@type='short'">
+ <xsl:value-of select="concat($f/@name, ' = buffer.GetUInt16()')"/>
+ </xsl:when>
+ <xsl:when test="$f/@type='long'">
+ <xsl:value-of select="concat($f/@name, ' = buffer.GetUInt32()')"/>
+ </xsl:when>
+ <xsl:when test="$f/@type='longlong'">
+ <xsl:value-of select="concat($f/@name, ' = buffer.GetUInt64()')"/>
+ </xsl:when>
+ <xsl:when test="$f/@type='shortstr'">
+ <xsl:value-of select="concat($f/@name, ' = EncodingUtils.ReadShortString(buffer)')"/>
+ </xsl:when>
+ <xsl:when test="$f/@type='longstr'">
+ <xsl:value-of select="concat($f/@name, ' = EncodingUtils.ReadLongstr(buffer)')"/>
+ </xsl:when>
+ <xsl:when test="$f/@type='table'">
+ <xsl:value-of select="concat($f/@name, ' = EncodingUtils.ReadFieldTable(buffer)')"/>
+ </xsl:when>
+ <xsl:otherwise><xsl:text>/* WARNING: COULD NOT DETERMINE DECODER */</xsl:text></xsl:otherwise>
+ </xsl:choose>
+</xsl:function>
+
+<!-- create the class name for a frame, based on class and method (passed in) -->
+<xsl:function name="amq:class-name">
+ <xsl:param name="class"/>
+ <xsl:param name="method"/>
+ <xsl:value-of select="concat(amq:upper-first($class),amq:upper-first(amq:field-name($method)), 'Body')"/>
+</xsl:function>
+
+<!-- get a valid field name, processing spaces and '-'s where appropriate -->
+<xsl:function name="amq:field-name">
+ <xsl:param name="name"/>
+ <xsl:choose>
+ <xsl:when test="contains($name, ' ')">
+ <xsl:value-of select="amq:upper-first(concat(substring-before($name, ' '), amq:upper-first(substring-after($name, ' '))))"/>
+ </xsl:when>
+ <xsl:when test="contains($name, '-')">
+ <xsl:value-of select="amq:upper-first(concat(substring-before($name, '-'), amq:upper-first(substring-after($name, '-'))))"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="amq:upper-first($name)"/>
+ </xsl:otherwise>
+ </xsl:choose>
+</xsl:function>
+
+<!-- convert the first character of the input to upper-case -->
+<xsl:function name="amq:upper-first">
+ <xsl:param name="in"/>
+ <xsl:value-of select="concat(upper-case(substring($in, 1, 1)), substring($in, 2))"/>
+</xsl:function>
+
+</xsl:stylesheet>
diff --git a/qpid/dotnet/Qpid.Integration.Tests/Properties/AssemblyInfo.cs b/qpid/dotnet/Qpid.Integration.Tests/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000000..e19650559f
--- /dev/null
+++ b/qpid/dotnet/Qpid.Integration.Tests/Properties/AssemblyInfo.cs
@@ -0,0 +1,53 @@
+/*
+ *
+ * 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.
+ *
+ */
+using System.Reflection;
+using System.Runtime.InteropServices;
+using log4net.Config;
+[assembly: XmlConfigurator(ConfigFile="log4net.config")]
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("Apache.Qpid.Integration.Tests")]
+[assembly: AssemblyDescription("Built from svn revision number: ")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Apache Software Foundation")]
+[assembly: AssemblyProduct("Apache.Qpid.Integration.Tests")]
+[assembly: AssemblyCopyright("Apache Software Foundation")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("7ebdea21-1352-4673-b66e-fdc0beff461f")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+[assembly: AssemblyVersion("0.5.0.0")]
diff --git a/qpid/dotnet/Qpid.Integration.Tests/Qpid.Integration.Tests.csproj b/qpid/dotnet/Qpid.Integration.Tests/Qpid.Integration.Tests.csproj
new file mode 100755
index 0000000000..e7d6e59cf5
--- /dev/null
+++ b/qpid/dotnet/Qpid.Integration.Tests/Qpid.Integration.Tests.csproj
@@ -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.
+
+-->
+
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">
+ <PropertyGroup>
+ <ProjectGuid>{DE21CEBC-F38C-43EA-B576-38CA9738A00A}</ProjectGuid>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <OutputType>Library</OutputType>
+ <RootNamespace>Qpid.Integration.Tests</RootNamespace>
+ <AssemblyName>Qpid.Integration.Tests</AssemblyName>
+ <FileUpgradeFlags>
+ </FileUpgradeFlags>
+ <OldToolsVersion>2.0</OldToolsVersion>
+ <UpgradeBackupLocation>
+ </UpgradeBackupLocation>
+ <PublishUrl>http://localhost/Qpid.Integration.Tests/</PublishUrl>
+ <Install>true</Install>
+ <InstallFrom>Web</InstallFrom>
+ <UpdateEnabled>true</UpdateEnabled>
+ <UpdateMode>Foreground</UpdateMode>
+ <UpdateInterval>7</UpdateInterval>
+ <UpdateIntervalUnits>Days</UpdateIntervalUnits>
+ <UpdatePeriodically>false</UpdatePeriodically>
+ <UpdateRequired>false</UpdateRequired>
+ <MapFileExtensions>true</MapFileExtensions>
+ <ApplicationRevision>0</ApplicationRevision>
+ <ApplicationVersion>1.0.0.%2a</ApplicationVersion>
+ <IsWebBootstrapper>true</IsWebBootstrapper>
+ <UseApplicationTrust>false</UseApplicationTrust>
+ <BootstrapperEnabled>true</BootstrapperEnabled>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
+ <OutputPath>bin\Debug\</OutputPath>
+ <DebugSymbols>True</DebugSymbols>
+ <DebugType>Full</DebugType>
+ <Optimize>False</Optimize>
+ <CheckForOverflowUnderflow>True</CheckForOverflowUnderflow>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
+ <OutputPath>bin\Release\</OutputPath>
+ <DebugSymbols>False</DebugSymbols>
+ <DebugType>None</DebugType>
+ <Optimize>True</Optimize>
+ <CheckForOverflowUnderflow>False</CheckForOverflowUnderflow>
+ <DefineConstants>TRACE</DefineConstants>
+ </PropertyGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.Targets" />
+ <ItemGroup>
+ <Reference Include="log4net, Version=1.2.10.0, Culture=neutral, PublicKeyToken=1b44e1d426115821">
+ <SpecificVersion>False</SpecificVersion>
+ <HintPath>..\client-010\lib\log4net\log4net.dll</HintPath>
+ </Reference>
+ <Reference Include="nunit.framework, Version=2.2.8.0, Culture=neutral, PublicKeyToken=96d09a1eb7f44a77">
+ <SpecificVersion>False</SpecificVersion>
+ <HintPath>..\client-010\lib\nunit\nunit.framework.dll</HintPath>
+ </Reference>
+ <Reference Include="System" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="**\*.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\Qpid.Client\Qpid.Client.csproj">
+ <Project>{68987C05-3768-452C-A6FC-6BA1D372852F}</Project>
+ <Name>Qpid.Client</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\Qpid.Common\Qpid.Common.csproj">
+ <Project>{77064C42-24D2-4CEB-9EA2-0EF481A43205}</Project>
+ <Name>Qpid.Common</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\Qpid.Messaging\Qpid.Messaging.csproj">
+ <Project>{6688F826-C58E-4C1B-AA1F-22AFAB4B7D07}</Project>
+ <Name>Qpid.Messaging</Name>
+ </ProjectReference>
+ </ItemGroup>
+ <ItemGroup>
+ <BootstrapperPackage Include="Microsoft.Net.Client.3.5">
+ <Visible>False</Visible>
+ <ProductName>.NET Framework Client Profile</ProductName>
+ <Install>false</Install>
+ </BootstrapperPackage>
+ <BootstrapperPackage Include="Microsoft.Net.Framework.2.0">
+ <Visible>False</Visible>
+ <ProductName>.NET Framework 2.0 %28x86%29</ProductName>
+ <Install>true</Install>
+ </BootstrapperPackage>
+ <BootstrapperPackage Include="Microsoft.Net.Framework.3.0">
+ <Visible>False</Visible>
+ <ProductName>.NET Framework 3.0 %28x86%29</ProductName>
+ <Install>false</Install>
+ </BootstrapperPackage>
+ <BootstrapperPackage Include="Microsoft.Net.Framework.3.5">
+ <Visible>False</Visible>
+ <ProductName>.NET Framework 3.5</ProductName>
+ <Install>false</Install>
+ </BootstrapperPackage>
+ <BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
+ <Visible>False</Visible>
+ <ProductName>.NET Framework 3.5 SP1</ProductName>
+ <Install>false</Install>
+ </BootstrapperPackage>
+ </ItemGroup>
+</Project>
diff --git a/qpid/dotnet/Qpid.Integration.Tests/README.txt b/qpid/dotnet/Qpid.Integration.Tests/README.txt
new file mode 100644
index 0000000000..389e3b2c6c
--- /dev/null
+++ b/qpid/dotnet/Qpid.Integration.Tests/README.txt
@@ -0,0 +1,3 @@
+This directory contains NUnit tests, which are 'integration' oriented. These differ
+from 'pure unit' tests which run against the code only. The integration tests require
+a broker to be available to connect to, and apply test cases that interact with it.
diff --git a/qpid/dotnet/Qpid.Integration.Tests/default.build b/qpid/dotnet/Qpid.Integration.Tests/default.build
new file mode 100644
index 0000000000..187aa15894
--- /dev/null
+++ b/qpid/dotnet/Qpid.Integration.Tests/default.build
@@ -0,0 +1,69 @@
+<?xml version="1.0"?>
+<!--
+
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+
+-->
+
+<project name="Apache.Qpid.Integration.Tests" default="test">
+
+ <!-- Creates a .dll for this module. -->
+ <target name="build">
+
+ <csc target="library"
+ define="${build.defines}"
+ warnaserror="false"
+ debug="${build.debug}"
+ output="${build.dir}/${project::get-name()}.dll">
+
+ <sources>
+ <include name="**/*.cs" />
+ </sources>
+
+ <references>
+ <include name="${build.dir}/log4net.dll" />
+ <include name="${build.dir}/nunit.framework.dll" />
+ <include name="${build.dir}/Apache.Qpid.Common.dll" />
+ <include name="${build.dir}/Apache.Qpid.Messaging.dll" />
+ <include name="${build.dir}/Apache.Qpid.Client.dll" />
+ <include name="${build.dir}/Apache.Qpid.Sasl.dll" />
+ </references>
+ </csc>
+
+ <!--<copy tofile="${build.dir}/${project::get-name()}.dll.config" file="App.config" />-->
+ <copy todir="${build.dir}" file="log4net.config"/>
+
+ </target>
+
+ <!-- Runs all of the tests in this module. -->
+ <target name="test" depends="build">
+ <nunit2 verbose="true">
+ <formatter type="${nant.formatter}" usefile="true" outputdir="${build.dir}/testresults/" extension="txt"/>
+ <formatter type="Plain" usefile="false"/>
+ <test>
+ <assemblies>
+ <include name="${build.dir}/${project::get-name()}.dll"/>
+ </assemblies>
+ <categories>
+ <include name="Integration"/>
+ </categories>
+ </test>
+ </nunit2>
+ </target>
+
+</project>
diff --git a/qpid/dotnet/Qpid.Integration.Tests/framework/Assertion.cs b/qpid/dotnet/Qpid.Integration.Tests/framework/Assertion.cs
new file mode 100644
index 0000000000..de12de6522
--- /dev/null
+++ b/qpid/dotnet/Qpid.Integration.Tests/framework/Assertion.cs
@@ -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.
+ *
+ */
+namespace Apache.Qpid.Integration.Tests.framework
+{
+ /// <summary>
+ /// Assertion models an assertion on a test <see cref="Circuit"/>.
+ ///
+ /// <p/><table id="crc"><caption>CRC Card</caption>
+ /// <tr><th> Responsibilities
+ /// <tr><td> Indicate whether or not the assertion passes when applied.
+ /// </table>
+ /// </summary>
+ public interface Assertion
+ {
+ /// <summary>
+ /// Applies the assertion.
+ /// </summary>
+ /// <return> <tt>true</tt> if the assertion passes, <tt>false</tt> if it fails. </return>
+ bool apply();
+ }
+} \ No newline at end of file
diff --git a/qpid/dotnet/Qpid.Integration.Tests/framework/Assertion.csx b/qpid/dotnet/Qpid.Integration.Tests/framework/Assertion.csx
new file mode 100644
index 0000000000..183315fec1
--- /dev/null
+++ b/qpid/dotnet/Qpid.Integration.Tests/framework/Assertion.csx
@@ -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.
+ *
+ */
+namespace Apache.Qpid.Integration.Tests.framework
+{
+ /// <summary>
+ /// Assertion models an assertion on a test <see cref="Circuit"/>.
+ ///
+ /// <p/><table id="crc"><caption>CRC Card</caption>
+ /// <tr><th> Responsibilities
+ /// <tr><td> Indicate whether or not the assertion passes when applied.
+ /// </table>
+ /// </summary>
+ public interface Assertion
+ {
+ /// <summary>
+ /// Applies the assertion.
+ /// </summary>
+ /// <return> <tt>true</tt> if the assertion passes, <tt>false</tt> if it fails. </return>
+ public bool apply();
+ }
+} \ No newline at end of file
diff --git a/qpid/dotnet/Qpid.Integration.Tests/framework/AssertionBase.csx b/qpid/dotnet/Qpid.Integration.Tests/framework/AssertionBase.csx
new file mode 100644
index 0000000000..7de3f6c4a5
--- /dev/null
+++ b/qpid/dotnet/Qpid.Integration.Tests/framework/AssertionBase.csx
@@ -0,0 +1,65 @@
+/*
+ *
+ * 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.
+ *
+ */
+using System.Collections.Generic.LinkedList;
+using System.Collections.Generic.IList;
+
+namespace Apache.Qpid.Integration.Tests.framework
+{
+ /// <summary>
+ /// AssertionBase is a base class for implenmenting assertions. It provides a mechanism to store error messages, and
+ /// report all error messages when its <see cref="#ToString()"/> method is called.
+ ///
+ /// <p/><table id="crc"><caption>CRC Card</caption>
+ /// <tr><th> Responsibilities <th> Collaborations
+ /// <tr><td> Collect error messages.
+ /// </table>
+ /// </summary>
+ public abstract class AssertionBase : Assertion
+ {
+ /// <summary> Holds the error messages. </summary>
+ IList<String> errors = new LinkedList<String>();
+
+ /// <summary>
+ /// Adds an error message to the assertion.
+ /// </summary>
+ /// <param name="error"> An error message to add to the assertion. </param>
+ public void addError(string error)
+ {
+ errors.add(error);
+ }
+
+ /// <summary>
+ /// Prints all of the error messages in the assertion into a string.
+ /// </summary>
+ /// <return> All of the error messages in the assertion as a string. </return>
+ public string ToString()
+ {
+ string result = "";
+
+ for (string error : errors)
+ {
+ result += error;
+ }
+
+ return result;
+ }
+ }
+} \ No newline at end of file
diff --git a/qpid/dotnet/Qpid.Integration.Tests/framework/BrokerLifecycleAware.csx b/qpid/dotnet/Qpid.Integration.Tests/framework/BrokerLifecycleAware.csx
new file mode 100644
index 0000000000..9ef1f54064
--- /dev/null
+++ b/qpid/dotnet/Qpid.Integration.Tests/framework/BrokerLifecycleAware.csx
@@ -0,0 +1,67 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+namespace Apache.Qpid.Integration.Tests.framework
+{
+ /// <summary>
+ /// BrokerLifecycleAware is an awareness interface implemented by test cases that can run control the life-cycle of
+ /// the brokers on which they run. Its purpose is to expose additional instrumentation of brokers during testing, that
+ /// enables tests to use an automated failure mechanism to simulate broker failures, and to re-start failed brokers.
+ ///
+ /// <p/><table id="crc"><caption>CRC Card</caption>
+ /// <tr><th> Responsibilities <th> Collaborations
+ /// <tr><td> Indicate whether or not a test case is using an in-vm broker.
+ /// <tr><td> Track which in-vm broker is currently in use.
+ /// <tr><td> Accept setting of a failure mechanism. <td> <see cref="CauseFailure"/>.
+ /// </table>
+ /// </summary>
+ ///
+ /// <remarks> Need to think about how to present the brokers through this interface. Thinking numbering the available
+ /// brokers from 1 will do. Then can kill 1 and assume failing onto 2. Restart 1 and kill 2 and fail back onto
+ /// 1 again? </remarks>
+ public interface BrokerLifecycleAware
+ {
+ public void setInVmBrokers();
+
+ /// <summary>
+ /// Indicates whether or not a test case is using in-vm brokers.
+ /// </summary>
+ /// <return> <tt>true</tt> if the test is using in-vm brokers, <tt>false</tt> otherwise. </return>
+ public bool usingInVmBroker();
+
+ /// <summary>
+ /// Sets the currently live in-vm broker.
+ /// </summary>
+ /// <param name="i"> The currently live in-vm broker. </param>
+ public void setLiveBroker(int i);
+
+ /// <summary>
+ /// Reports the currently live in-vm broker.
+ /// </summary>
+ /// <return> The currently live in-vm broker. </return>
+ public int getLiveBroker();
+
+ /// <summary>
+ /// Accepts a failure mechanism.
+ /// </summary>
+ /// <param name="failureMechanism"> The failure mechanism. </param>
+ public void setFailureMechanism(CauseFailure failureMechanism);
+ }
+} \ No newline at end of file
diff --git a/qpid/dotnet/Qpid.Integration.Tests/framework/CauseFailure.csx b/qpid/dotnet/Qpid.Integration.Tests/framework/CauseFailure.csx
new file mode 100644
index 0000000000..1fe8918e60
--- /dev/null
+++ b/qpid/dotnet/Qpid.Integration.Tests/framework/CauseFailure.csx
@@ -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.
+ *
+ */
+namespace Apache.Qpid.Integration.Tests.framework
+{
+ /// <summary>
+ /// CauseFailure provides a method to cause a failure in a messaging broker, usually used in conjunction with fail-over
+ /// or other failure mode testing. In some cases failures may be automated, for example by shutting down an in-vm broker,
+ /// or by sending a special control signal to a broker over a network connection. In other cases, it may be preferable
+ /// to ask a user interactively to cause a failure scenario, in which case an implementation may display a prompt or
+ /// dialog box asking for notification once the failure has been caused. The purpose of this interface is to abstract
+ /// the exact cause and nature of a failure out of failure test cases.
+ ///
+ /// <p/><table id="crc"><caption>CRC Card</caption>
+ /// <tr><th> Responsibilities
+ /// <tr><td> Cause messaging broker failure.
+ /// </table>
+ /// </summary>
+ public interface CauseFailure
+ {
+ /// <summary> Causes the active message broker to fail. </summary>
+ void causeFailure();
+ }
+} \ No newline at end of file
diff --git a/qpid/dotnet/Qpid.Integration.Tests/framework/CauseFailureUserPrompt.csx b/qpid/dotnet/Qpid.Integration.Tests/framework/CauseFailureUserPrompt.csx
new file mode 100644
index 0000000000..96f4ec53d0
--- /dev/null
+++ b/qpid/dotnet/Qpid.Integration.Tests/framework/CauseFailureUserPrompt.csx
@@ -0,0 +1,63 @@
+/*
+ *
+ * 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.
+ *
+ */
+using Apache.Qpid.Integration.Tests.framework.CauseFailure;
+
+using java.io.IOException;
+
+namespace Apache.Qpid.Integration.Tests.framework
+{
+ /// <summary>
+ /// Causes a message broker failure by interactively prompting the user to cause it.
+ ///
+ /// <p/><table id="crc"><caption>CRC Card</caption>
+ /// <tr><th> Responsibilities <th> Collaborations
+ /// <tr><td> Cause messaging broker failure.
+ /// </table>
+ /// </summary>
+ public class CauseFailureUserPrompt : CauseFailure
+ {
+ /// <summary> Causes the active message broker to fail.</summary>
+ public void causeFailure()
+ {
+ waitForUser("Cause a broker failure now, then press Return.");
+ }
+
+ /// <summary>
+ /// Outputs a prompt to the console and waits for the user to press return.
+ /// </summary>
+ /// <param name="prompt"> The prompt to display on the console. </param>
+ private void waitForUser(string prompt)
+ {
+ System.out.println(prompt);
+
+ try
+ {
+ System.in.read();
+ }
+ catch (IOException e)
+ {
+ // Ignored.
+ }
+
+ System.out.println("Continuing.");
+ }
+ }
+} \ No newline at end of file
diff --git a/qpid/dotnet/Qpid.Integration.Tests/framework/Circuit.cs b/qpid/dotnet/Qpid.Integration.Tests/framework/Circuit.cs
new file mode 100644
index 0000000000..aae9ca0496
--- /dev/null
+++ b/qpid/dotnet/Qpid.Integration.Tests/framework/Circuit.cs
@@ -0,0 +1,102 @@
+/*
+ *
+ * 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.
+ *
+ */
+using System.Collections.Generic;//.IList;
+
+namespace Apache.Qpid.Integration.Tests.framework
+{
+ /// <summary>
+ /// A Circuit is the basic test unit against which test cases are to be written. A circuit consists of two 'ends', an
+ /// instigating 'publisher' end and a more passive 'receivers' end.
+ ///
+ /// <p/>Once created, the life-cycle of a circuit may be controlled by <see cref="#start()"/>ing it, or <see cref="#close()"/>ing it.
+ /// Once started, the circuit is ready to send messages over. Once closed the circuit can no longer be used.
+ ///
+ /// <p/>The state of the circuit may be taken with the <see cref="#check()"/> method, and asserted against by the
+ /// <see cref="#applyAssertions(System.Collections.Generic.IList)"/> method.
+ ///
+ /// <p/>There is a default test procedure which may be performed against the circuit. The outline of this procedure is:
+ ///
+ /// <p/><pre>
+ /// Start the circuit.
+ /// Send test messages.
+ /// Request a status report.
+ /// Assert conditions on the publishing end of the circuit.
+ /// Assert conditions on the receiving end of the circuit.
+ /// Close the circuit.
+ /// Pass with no failed assertions or fail with a list of failed assertions.
+ /// </pre>
+ ///
+ /// <p/><table id="crc"><caption>CRC Card</caption>
+ /// <tr><th> Responsibilities
+ /// <tr><td> Supply the publishing and receiving ends of a test messaging circuit.
+ /// <tr><td> Start the circuit running.
+ /// <tr><td> Close the circuit down.
+ /// <tr><td> Take a reading of the circuits state.
+ /// <tr><td> Apply assertions against the circuits state.
+ /// <tr><td> Send test messages over the circuit.
+ /// <tr><td> Perform the default test procedue on the circuit.
+ /// </table>
+ /// </summary>
+ public interface Circuit
+ {
+ /// <summary> Gets the interface on the publishing end of the circuit. </summary>
+ ///
+ /// <return> The publishing end of the circuit. </return>
+ Publisher GetPublisher();
+
+ /// <summary> Gets the interface on the receiving end of the circuit. </summary>
+ ///
+ /// <return> The receiving end of the circuit. </return>
+ Receiver GetReceiver();
+
+ /// <summary> Connects and starts the circuit. After this method is called the circuit is ready to send messages. </summary>
+ void Start();
+
+ /// <summary>
+ /// Checks the test circuit. The effect of this is to gather the circuits state, for both ends of the circuit,
+ /// into a report, against which assertions may be checked.
+ /// </summary>
+ void Check();
+
+ /// <summary> Closes the circuit. All associated resources are closed. </summary>
+ void Close();
+
+ /// <summary>
+ /// Applied a list of assertions against the test circuit. The <see cref="#check()"/> method should be called before doing
+ /// this, to ensure that the circuit has gathered its state into a report to assert against.
+ /// </summary>
+ ///
+ /// <param name="assertions"> The list of assertions to apply to the circuit. </param>
+ ///
+ /// <return> Any assertions that failed. </return>
+ IList<Assertion> ApplyAssertions(IList<Assertion> assertions);
+
+ /// <summary>
+ /// Runs the default test procedure against the circuit, and checks that all of the specified assertions hold.
+ /// </summary>
+ ///
+ /// <param name="numMessages"> The number of messages to send using the default test procedure. </param>
+ /// <param name="assertions"> The list of assertions to apply. </param>
+ ///
+ /// <return> Any assertions that failed. </return>
+ IList<Assertion> Test(int numMessages, IList<Assertion> assertions);
+ }
+} \ No newline at end of file
diff --git a/qpid/dotnet/Qpid.Integration.Tests/framework/Circuit.csx b/qpid/dotnet/Qpid.Integration.Tests/framework/Circuit.csx
new file mode 100644
index 0000000000..bf2c623cff
--- /dev/null
+++ b/qpid/dotnet/Qpid.Integration.Tests/framework/Circuit.csx
@@ -0,0 +1,103 @@
+/*
+ *
+ * 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.
+ *
+ */
+using System.Collections.Generic.IList;
+
+namespace Apache.Qpid.Integration.Tests.framework
+{
+ /// <summary>
+ /// A Circuit is the basic test unit against which test cases are to be written. A circuit consists of two 'ends', an
+ /// instigating 'publisher' end and a more passive 'receivers' end.
+ ///
+ /// <p/>Once created, the life-cycle of a circuit may be controlled by <see cref="#start()"/>ing it, or <see cref="#close()"/>ing it.
+ /// Once started, the circuit is ready to send messages over. Once closed the circuit can no longer be used.
+ ///
+ /// <p/>The state of the circuit may be taken with the <see cref="#check()"/> method, and asserted against by the
+ /// <see cref="#applyAssertions(System.Collections.Generic.IList)"/> method.
+ ///
+ /// <p/>There is a default test procedure which may be performed against the circuit. The outline of this procedure is:
+ ///
+ /// <p/><pre>
+ /// Start the circuit.
+ /// Send test messages.
+ /// Request a status report.
+ /// Assert conditions on the publishing end of the circuit.
+ /// Assert conditions on the receiving end of the circuit.
+ /// Close the circuit.
+ /// Pass with no failed assertions or fail with a list of failed assertions.
+ /// </pre>
+ ///
+ /// <p/><table id="crc"><caption>CRC Card</caption>
+ /// <tr><th> Responsibilities
+ /// <tr><td> Supply the publishing and receiving ends of a test messaging circuit.
+ /// <tr><td> Start the circuit running.
+ /// <tr><td> Close the circuit down.
+ /// <tr><td> Take a reading of the circuits state.
+ /// <tr><td> Apply assertions against the circuits state.
+ /// <tr><td> Send test messages over the circuit.
+ /// <tr><td> Perform the default test procedue on the circuit.
+ /// </table>
+ /// </summary>
+ public interface Circuit
+ {
+ /// <summary>
+ /// Gets the interface on the publishing end of the circuit.
+ /// </summary>
+ /// <return> The publishing end of the circuit. </return>
+ public Publisher getPublisher();
+
+ /// <summary>
+ /// Gets the interface on the receiving end of the circuit.
+ /// </summary>
+ /// <return> The receiving end of the circuit. </return>
+ public Receiver getReceiver();
+
+ /// <summary>
+ /// Connects and starts the circuit. After this method is called the circuit is ready to send messages.
+ public void start();
+
+ /// <summary>
+ /// Checks the test circuit. The effect of this is to gather the circuits state, for both ends of the circuit,
+ /// into a report, against which assertions may be checked.
+ public void check();
+
+ /// <summary>
+ /// Closes the circuit. All associated resources are closed.
+ public void close();
+
+ /// <summary>
+ /// Applied a list of assertions against the test circuit. The <see cref="#check()"/> method should be called before doing
+ /// this, to ensure that the circuit has gathered its state into a report to assert against.
+ /// </summary>
+ /// <param name="assertions"> The list of assertions to apply to the circuit. </param>
+ ///
+ /// <return> Any assertions that failed. </return>
+ public IList<Assertion> applyAssertions(List<Assertion> assertions);
+
+ /// <summary>
+ /// Runs the default test procedure against the circuit, and checks that all of the specified assertions hold.
+ /// </summary>
+ /// <param name="numMessages"> The number of messages to send using the default test procedure. </param>
+ /// <param name="assertions"> The list of assertions to apply. </param>
+ ///
+ /// <return> Any assertions that failed. </return>
+ public IList<Assertion> test(int numMessages, List<Assertion> assertions);
+ }
+} \ No newline at end of file
diff --git a/qpid/dotnet/Qpid.Integration.Tests/framework/CircuitEnd.csx b/qpid/dotnet/Qpid.Integration.Tests/framework/CircuitEnd.csx
new file mode 100644
index 0000000000..6edaf428de
--- /dev/null
+++ b/qpid/dotnet/Qpid.Integration.Tests/framework/CircuitEnd.csx
@@ -0,0 +1,86 @@
+/*
+ *
+ * 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.
+ *
+ */
+//using javax.jms.*;
+using Apache.Qpid.Messaging;
+
+namespace Apache.Qpid.Integration.Tests.framework
+{
+ /// <summary>
+ /// A CircuitEnd is a pair consisting of one message producer and one message consumer, that represents one end of a
+ /// test circuit. It is a standard unit of connectivity allowing a full-duplex conversation to be held, provided both
+ /// the consumer and producer are instantiated and configured.
+ ///
+ /// <p/><table id="crc"><caption>CRC Card</caption>
+ /// <tr><th> Responsibilities
+ /// <tr><td> Provide a message producer for sending messages.
+ /// <tr><td> Provide a message consumer for receiving messages.
+ /// </table>
+ /// </summary>
+ ///
+ /// <remarks> Update the <see cref="org.apache.qpid.util.ConversationFactory"/> so that it accepts these as the basic conversation
+ /// connection units.</remarks>
+ public interface CircuitEnd
+ {
+ /// <summary>
+ /// Gets the message producer at this circuit end point.
+ /// </summary>
+ /// <return> The message producer at with this circuit end point. </return>
+ public IMessagePublisher GetProducer();
+
+ /// <summary>
+ /// Gets the message consumer at this circuit end point.
+ /// </summary>
+ /// <return> The message consumer at this circuit end point. </return>
+ public IMessageConsumer GetConsumer();
+
+ /// <summary>
+ /// Send the specified message over the producer at this end point.
+ /// </summary>
+ /// <param name="message"> The message to send. </param>
+ ///
+ /// <exception cref="JMSException"> Any JMS exception occuring during the send is allowed to fall through. </exception>
+ public void Send(IMessage message);
+
+ /// <summary>
+ /// Gets the JMS Session associated with this circuit end point.
+ /// </summary>
+ /// <return> The JMS Session associated with this circuit end point. </return>
+ public IChannel GetSession();
+
+ /// <summary>
+ /// Closes the message producers and consumers and the sessions, associated with this circuit end point.
+ /// </summary>
+ /// <exception cref="JMSException"> Any JMSExceptions occurring during the close are allowed to fall through. </exception>
+ public void Close();
+
+ /// <summary>
+ /// Returns the message monitor for reporting on received messages on this circuit end.
+ /// </summary>
+ /// <return> The message monitor for this circuit end. </return>
+ public MessageMonitor GetMessageMonitor();
+
+ /// <summary>
+ /// Returns the exception monitor for reporting on exceptions received on this circuit end.
+ /// </summary>
+ /// <return> The exception monitor for this circuit end. </return>
+ public ExceptionMonitor GetExceptionMonitor();
+ }
+} \ No newline at end of file
diff --git a/qpid/dotnet/Qpid.Integration.Tests/framework/CircuitEndBase.csx b/qpid/dotnet/Qpid.Integration.Tests/framework/CircuitEndBase.csx
new file mode 100644
index 0000000000..db7fbde6ea
--- /dev/null
+++ b/qpid/dotnet/Qpid.Integration.Tests/framework/CircuitEndBase.csx
@@ -0,0 +1,146 @@
+/*
+ *
+ * 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.
+ *
+ */
+//using javax.jms.*;
+using Apache.Qpid.Messaging;
+
+namespace Apache.Qpid.Integration.Tests.framework
+{
+ /// <summary>
+ /// A CircuitEndBase is a pair consisting of one message producer and one message consumer, that represents one end of a
+ /// test circuit. It is a standard unit of connectivity allowing a full-duplex conversation to be held, provided both
+ /// the consumer and producer are instantiated and configured.
+ ///
+ /// <p/><table id="crc"><caption>CRC Card</caption>
+ /// <tr><th> Responsibilities
+ /// <tr><td> Provide a message producer for sending messages.
+ /// <tr><td> Provide a message consumer for receiving messages.
+ /// </table>
+ /// </summary>
+ public class CircuitEndBase : CircuitEnd
+ {
+ /// <summary> Holds the single message producer. </summary>
+ MessageProducer producer;
+
+ /// <summary> Holds the single message consumer. </summary>
+ MessageConsumer consumer;
+
+ /// <summary> Holds the controlSession for the circuit end. </summary>
+ Session session;
+
+ /// <summary> Holds the message monitor for the circuit end. </summary>
+ MessageMonitor messageMonitor;
+
+ /// <summary> Holds the exception monitor for the circuit end. </summary>
+ ExceptionMonitor exceptionMonitor;
+
+ /// <summary>
+ /// Creates a circuit end point on the specified producer, consumer and controlSession. Monitors are also configured
+ /// for messages and exceptions received by the circuit end.
+ /// </summary>
+ /// <param name="producer"> The message producer for the circuit end point. </param>
+ /// <param name="consumer"> The message consumer for the circuit end point. </param>
+ /// <param name="session"> The controlSession for the circuit end point. </param>
+ /// <param name="messageMonitor"> The monitor to notify of all messages received by the circuit end. </param>
+ /// <param name="exceptionMonitor"> The monitor to notify of all exceptions received by the circuit end. </param>
+ public CircuitEndBase(MessageProducer producer, MessageConsumer consumer, Session session, MessageMonitor messageMonitor,
+ ExceptionMonitor exceptionMonitor)
+ {
+ this.producer = producer;
+ this.consumer = consumer;
+ this.session = session;
+
+ this.messageMonitor = messageMonitor;
+ this.exceptionMonitor = exceptionMonitor;
+ }
+
+ /// <summary>
+ /// Gets the message producer at this circuit end point.
+ /// </summary>
+ /// <return> The message producer at with this circuit end point. </return>
+ public IMessagePublisher GetProducer()
+ {
+ return producer;
+ }
+
+ /// <summary>
+ /// Gets the message consumer at this circuit end point.
+ /// </summary>
+ /// <return> The message consumer at this circuit end point. </return>
+ public IMessageConsumer GetConsumer()
+ {
+ return consumer;
+ }
+
+ /// <summary>
+ /// Send the specified message over the producer at this end point.
+ /// </summary>
+ /// <param name="message"> The message to send. </param>
+ /// <exception cref="javax.jms.JMSException"> Any JMS exception occuring during the send is allowed to fall through. </exception>
+ public void Send(IMessage message)
+ {
+ producer.send(message);
+ }
+
+ /// <summary>
+ /// Gets the JMS Session associated with this circuit end point.
+ /// </summary>
+ /// <return> The JMS Session associated with this circuit end point. </return>
+ public IChannel GetSession()
+ {
+ return session;
+ }
+
+ /// <summary>
+ /// Closes the message producers and consumers and the sessions, associated with this circuit end point.
+ /// </summary>
+ /// <exception cref="javax.jms.JMSException"> Any JMSExceptions occurring during the close are allowed to fall through. </exception>
+ public void Close()
+ {
+ if (producer != null)
+ {
+ producer.Close();
+ }
+
+ if (consumer != null)
+ {
+ consumer.Close();
+ }
+ }
+
+ /// <summary>
+ /// Returns the message monitor for reporting on received messages on this circuit end.
+ /// </summary>
+ /// <return> The message monitor for this circuit end. </return>
+ public MessageMonitor GetMessageMonitor()
+ {
+ return messageMonitor;
+ }
+
+ /// <summary>
+ /// Returns the exception monitor for reporting on exceptions received on this circuit end.
+ /// </summary>
+ /// <return> The exception monitor for this circuit end. </return>
+ public ExceptionMonitor GetExceptionMonitor()
+ {
+ return exceptionMonitor;
+ }
+ }
+} \ No newline at end of file
diff --git a/qpid/dotnet/Qpid.Integration.Tests/framework/ExceptionMonitor.csx b/qpid/dotnet/Qpid.Integration.Tests/framework/ExceptionMonitor.csx
new file mode 100644
index 0000000000..b2a989b940
--- /dev/null
+++ b/qpid/dotnet/Qpid.Integration.Tests/framework/ExceptionMonitor.csx
@@ -0,0 +1,184 @@
+/*
+ *
+ * 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.
+ *
+ */
+using log4net;
+
+using javax.jms.ExceptionListener;
+using javax.jms.JMSException;
+
+using java.io.PrintWriter;
+using java.io.StringWriter;
+using java.util.ArrayList;
+using System.Collections.Generic.IList;
+
+namespace Apache.Qpid.Integration.Tests.framework
+{
+ /// <summary>
+ /// An exception monitor, listens for JMS exception on a connection or consumer. It record all exceptions that it receives
+ /// and provides methods to test the number and type of exceptions received.
+ ///
+ /// <p/><table id="crc"><caption>CRC Card</caption>
+ /// <tr><th> Responsibilities <th> Collaborations
+ /// <tr><td> Record all exceptions received.
+ /// </table>
+ /// </summary>
+ public class ExceptionMonitor : ExceptionListener
+ {
+ /// <summary> Used for debugging. </summary>
+ private static ILog log = LogManager.GetLogger(typeof(ExceptionMonitor));
+
+ /// <summary> Holds the received exceptions. </summary>
+ IList<Exception> exceptions = new ArrayList<Exception>();
+
+ /// <summary>
+ /// Receives incoming exceptions.
+ /// </summary>
+ /// <param name="e"> The exception to record. </param>
+ public synchronized void onException(JMSException e)
+ {
+ log.debug("public void onException(JMSException e): called", e);
+
+ exceptions.add(e);
+ }
+
+ /// <summary>
+ /// Checks that no exceptions have been received.
+ /// </summary>
+ /// <return> <tt>true</tt> if no exceptions have been received, <tt>false</tt> otherwise. </return>
+ public synchronized bool assertNoExceptions()
+ {
+ return exceptions.isEmpty();
+ }
+
+ /// <summary>
+ /// Checks that exactly one exception has been received.
+ /// </summary>
+ /// <return> <tt>true</tt> if exactly one exception been received, <tt>false</tt> otherwise. </return>
+ public synchronized bool assertOneJMSException()
+ {
+ return exceptions.size() == 1;
+ }
+
+ /// <summary>
+ /// Checks that exactly one exception, with a linked cause of the specified type, has been received.
+ /// </summary>
+ /// <param name="aClass"> The type of the linked cause. </param>
+ ///
+ /// <return> <tt>true</tt> if exactly one exception, with a linked cause of the specified type, been received, </return>
+ /// <tt>false</tt> otherwise.
+ public synchronized bool assertOneJMSExceptionWithLinkedCause(Class aClass)
+ {
+ if (exceptions.size() == 1)
+ {
+ Exception e = exceptions.get(0);
+
+ if (e instanceof JMSException)
+ {
+ JMSException jmse = (JMSException) e;
+
+ Exception linkedCause = jmse.getLinkedException();
+
+ if ((linkedCause != null) && aClass.isInstance(linkedCause))
+ {
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
+
+ /// <summary>
+ /// Checks that at least one exception of the the specified type, has been received.
+ /// </summary>
+ /// <param name="exceptionClass"> The type of the exception. </param>
+ ///
+ /// <return> <tt>true</tt> if at least one exception of the specified type has been received, <tt>false</tt> otherwise. </return>
+ public synchronized bool assertExceptionOfType(Class exceptionClass)
+ {
+ // Start by assuming that the exception has no been received.
+ bool passed = false;
+
+ // Scan all the exceptions for a match.
+ for (Exception e : exceptions)
+ {
+ if (exceptionClass.isInstance(e))
+ {
+ passed = true;
+
+ break;
+ }
+ }
+
+ return passed;
+ }
+
+ /// <summary>
+ /// Reports the number of exceptions held by this monitor.
+ /// </summary>
+ /// <return> The number of exceptions held by this monitor. </return>
+ public synchronized int size()
+ {
+ return exceptions.size();
+ }
+
+ /// <summary>
+ /// Clears the record of received exceptions.
+ /// </summary>
+ public synchronized void reset()
+ {
+ exceptions = new ArrayList<Exception>();
+ }
+
+ /// <summary>
+ /// Provides a dump of the stack traces of all exceptions that this exception monitor was notified of. Mainly
+ /// use for debugging/test failure reporting purposes.
+ /// </summary>
+ /// <return> A string containing a dump of the stack traces of all exceptions. </return>
+ public synchronized string ToString()
+ {
+ string result = "ExceptionMonitor: holds " + exceptions.size() + " exceptions.\n\n";
+
+ for (Exception ex : exceptions)
+ {
+ result += getStackTrace(ex) + "\n";
+ }
+
+ return result;
+ }
+
+ /// <summary>
+ /// Prints an exception stack trace into a string.
+ /// </summary>
+ /// <param name="t"> The throwable to get the stack trace from. </param>
+ ///
+ /// <return> A string containing the throwables stack trace. </return>
+ public static string getStackTrace(Throwable t)
+ {
+ StringWriter sw = new StringWriter();
+ PrintWriter pw = new PrintWriter(sw, true);
+ t.printStackTrace(pw);
+ pw.flush();
+ sw.flush();
+
+ return sw.ToString();
+ }
+ }
+} \ No newline at end of file
diff --git a/qpid/dotnet/Qpid.Integration.Tests/framework/FrameworkBaseCase.cs b/qpid/dotnet/Qpid.Integration.Tests/framework/FrameworkBaseCase.cs
new file mode 100644
index 0000000000..77c1cae0ad
--- /dev/null
+++ b/qpid/dotnet/Qpid.Integration.Tests/framework/FrameworkBaseCase.cs
@@ -0,0 +1,282 @@
+/*
+ *
+ * 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.
+ *
+ */
+using log4net;
+using NUnit.Framework;
+//using org.apache.log4j.NDC;
+
+using Apache.Qpid.Integration.Tests.framework.sequencers;//.CircuitFactory;
+
+//using uk.co.thebadgerset.junit.extensions.AsymptoticTestCase;
+//using uk.co.thebadgerset.junit.extensions.SetupTaskAware;
+//using uk.co.thebadgerset.junit.extensions.SetupTaskHandler;
+//using uk.co.thebadgerset.junit.extensions.util.ParsedProperties;
+//using uk.co.thebadgerset.junit.extensions.util.TestContextProperties;
+
+//using java.util.ArrayList;
+using System.Collections.Generic;//.IList;
+
+namespace Apache.Qpid.Integration.Tests.framework
+{
+ /// <summary>
+ /// FrameworkBaseCase provides a starting point for writing test cases against the test framework. Its main purpose is
+ /// to provide some convenience methods for testing.
+ ///
+ /// <p/><table id="crc"><caption>CRC Card</caption>
+ /// <tr><th> Responsibilities <th> Collaborations
+ /// <tr><td> Create and clean up in-vm brokers on every test case.
+ /// <tr><td> Produce lists of assertions from assertion creation calls.
+ /// <tr><td> Produce JUnit failures from assertion failures.
+ /// <tr><td> Convert failed assertions to error messages.
+ /// </table>
+ /// </summary>
+ public class FrameworkBaseCase //extends AsymptoticTestCase : FrameworkTestContext, SetupTaskAware, BrokerLifecycleAware
+ {
+ /// <summary> Used for debugging purposes. </summary>
+ private static ILog log = LogManager.GetLogger(typeof(FrameworkBaseCase));
+
+ /// <summary> Holds the test sequencer to create and run test circuits with. </summary>
+ protected CircuitFactory circuitFactory;// = new LocalCircuitFactory();
+
+ /// <summary> Used to read the tests configurable properties through. </summary>
+ protected TestModel testProps;
+
+ /// <summary> A default setup task processor to delegate setup tasks to. </summary>
+ //protected SetupTaskHandler taskHandler = new SetupTaskHandler();
+
+ /// <summary> Flag used to track whether the test is in-vm or not. </summary>
+ //protected bool isUsingInVM;
+
+ /// <summary> Holds the failure mechanism. </summary>
+ //protected CauseFailure failureMechanism = new CauseFailureUserPrompt();
+
+ /*
+ /// <summary>
+ /// Creates a new test case with the specified name.
+ /// </summary>
+ /// <param name="name"> The test case name. </param>
+ public FrameworkBaseCase(string name) : base(name)
+ {
+ }
+ */
+
+ /// <summary>
+ /// Returns the test case sequencer that provides test circuit, and test sequence implementations. The sequencer
+ /// that this base case returns by default is suitable for running a test circuit with both circuit ends colocated
+ /// on the same JVM.
+ /// </summary>
+ /// <return> The test case sequencer. </return>
+ protected CircuitFactory GetCircuitFactory()
+ {
+ return circuitFactory;
+ }
+
+ /// <summary>
+ /// Overrides the default test circuit factory. Test decorators can use this to supply distributed test sequencers or
+ /// other test circuit factory specializations.
+ /// </summary>
+ /// <param name="circuitFactory"> The new test circuit factory. </param>
+ public void SetCircuitFactory(CircuitFactory circuitFactory)
+ {
+ this.circuitFactory = circuitFactory;
+ }
+
+ /*
+ /// <summary>
+ /// Reports the current test case name.
+ /// </summary>
+ /// <return> The current test case name. </return>
+ public TestCaseVector GetTestCaseVector()
+ {
+ return new TestCaseVector(this.getName(), 0);
+ }
+ */
+
+ /// <summary>
+ /// Reports the current test case parameters.
+ /// </summary>
+ /// <return> The current test case parameters. </return>
+ public TestModel getTestParameters()
+ {
+ return testProps;
+ }
+
+ /// <summary>
+ /// Creates a list of assertions.
+ /// </summary>
+ /// <param name="asserts"> The assertions to compile in a list. </param>
+ ///
+ /// <return> A list of assertions. </return>
+ protected IList<Assertion> AssertionList(params Assertion[] asserts)
+ {
+ IList<Assertion> result = new List<Assertion>();
+
+ foreach (Assertion assertion in asserts)
+ {
+ result.Add(assertion);
+ }
+
+ return result;
+ }
+
+ /// <summary>
+ /// Generates a JUnit assertion exception (failure) if any assertions are passed into this method, also concatenating
+ /// all of the error messages in the assertions together to form an error message to diagnose the test failure with.
+ /// </summary>
+ /// <param name="asserts"> The list of failed assertions. </param>
+ protected static void AssertNoFailures(List<Assertion> asserts)
+ {
+ log.Debug("protected void assertNoFailures(List<Assertion> asserts = " + asserts + "): called");
+
+ // Check if there are no assertion failures, and return without doing anything if so.
+ if ((asserts == null) || (asserts.Count == 0))
+ {
+ return;
+ }
+
+ // Compile all of the assertion failure messages together.
+ string errorMessage = AssertionsToString(asserts);
+
+ // Fail with the error message from all of the assertions.
+ Assert.Fail(errorMessage);
+ }
+
+ /// <summary>
+ /// Converts a list of failed assertions into an error message.
+ /// </summary>
+ /// <param name="asserts"> The failed assertions. </param>
+ ///
+ /// <return> The error message. </return>
+ protected static string AssertionsToString(List<Assertion> asserts)
+ {
+ string errorMessage = "";
+
+ foreach (Assertion assertion in asserts)
+ {
+ errorMessage += assertion.ToString() + "\n";
+ }
+
+ return errorMessage;
+ }
+
+ /// <summary>
+ /// Ensures that the in-vm broker is created and initialized.
+ /// </summary>
+ ///
+ /// <exception cref="Exception"> Any exceptions allowed to fall through and fail the test. </exception>
+ [SetUp]
+ protected void SetUp()
+ {
+ //NDC.Push(Name);
+
+ //testProps = TestContextProperties.getInstance(TestModel.defaults);
+
+ // Process all optional setup tasks. This may include in-vm broker creation, if a decorator has added it.
+ //taskHandler.runSetupTasks();
+ }
+
+ /// <summary> Ensures that the in-vm broker is cleaned up after each test run. </summary>
+ [TearDown]
+ protected void TearDown()
+ {
+ //NDC.Pop();
+
+ // Process all optional tear down tasks. This may include in-vm broker clean up, if a decorator has added it.
+ //taskHandler.runTearDownTasks();
+ }
+
+ /*
+ /// <summary>
+ /// Adds the specified task to the tests setup.
+ /// </summary>
+ /// <param name="task"> The task to add to the tests setup. </param>
+ public void chainSetupTask(Runnable task)
+ {
+ taskHandler.chainSetupTask(task);
+ }
+ */
+
+ /*
+ /// <summary>
+ /// Adds the specified task to the tests tear down.
+ /// </summary>
+ /// <param name="task"> The task to add to the tests tear down. </param>
+ public void chainTearDownTask(Runnable task)
+ {
+ taskHandler.chainTearDownTask(task);
+ }
+ */
+
+ /*
+ /// <summary>
+ /// Should provide a translation from the junit method name of a test to its test case name as known to the test
+ /// clients that will run the test. The purpose of this is to convert the JUnit method name into the correct test
+ /// case name to place into the test invite. For example the method "testP2P" might map onto the interop test case
+ /// name "TC2_BasicP2P".
+ /// </summary>
+ /// <param name="methodName"> The name of the JUnit test method. </param>
+ ///
+ /// <return> The name of the corresponding interop test case. </return>
+ public string getTestCaseNameForTestMethod(string methodName)
+ {
+ return methodName;
+ }
+
+ public void setInVmBrokers()
+ {
+ isUsingInVM = true;
+ }
+
+ /// <summary>
+ /// Indicates whether or not a test case is using in-vm brokers.
+ /// </summary>
+ /// <return> <tt>true</tt> if the test is using in-vm brokers, <tt>false</tt> otherwise. </return>
+ public bool usingInVmBroker()
+ {
+ return isUsingInVM;
+ }
+
+ /// <summary>
+ /// Sets the currently live in-vm broker.
+ /// </summary>
+ /// <param name="i"> The currently live in-vm broker. </param>
+ public void setLiveBroker(int i)
+ { }
+
+ /// <summary>
+ /// Reports the currently live in-vm broker.
+ /// </summary>
+ /// <return> The currently live in-vm broker. </return>
+ public int getLiveBroker()
+ {
+ return 0;
+ }
+
+ /// <summary>
+ /// Accepts a failure mechanism.
+ /// </summary>
+ /// <param name="failureMechanism"> The failure mechanism. </param>
+ public void setFailureMechanism(CauseFailure failureMechanism)
+ {
+ this.failureMechanism = failureMechanism;
+ }
+ */
+ }
+} \ No newline at end of file
diff --git a/qpid/dotnet/Qpid.Integration.Tests/framework/FrameworkBaseCase.csx b/qpid/dotnet/Qpid.Integration.Tests/framework/FrameworkBaseCase.csx
new file mode 100644
index 0000000000..00ed572603
--- /dev/null
+++ b/qpid/dotnet/Qpid.Integration.Tests/framework/FrameworkBaseCase.csx
@@ -0,0 +1,272 @@
+/*
+ *
+ * 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.
+ *
+ */
+using log4net;
+using org.apache.log4j.NDC;
+
+using Apache.Qpid.Integration.Tests.framework.BrokerLifecycleAware;
+using Apache.Qpid.Integration.Tests.framework.sequencers.CircuitFactory;
+
+using uk.co.thebadgerset.junit.extensions.AsymptoticTestCase;
+using uk.co.thebadgerset.junit.extensions.SetupTaskAware;
+using uk.co.thebadgerset.junit.extensions.SetupTaskHandler;
+using uk.co.thebadgerset.junit.extensions.util.ParsedProperties;
+using uk.co.thebadgerset.junit.extensions.util.TestContextProperties;
+
+using java.util.ArrayList;
+using System.Collections.Generic.IList;
+
+namespace Apache.Qpid.Integration.Tests.framework
+{
+ /// <summary>
+ /// FrameworkBaseCase provides a starting point for writing test cases against the test framework. Its main purpose is
+ /// to provide some convenience methods for testing.
+ ///
+ /// <p/><table id="crc"><caption>CRC Card</caption>
+ /// <tr><th> Responsibilities <th> Collaborations
+ /// <tr><td> Create and clean up in-vm brokers on every test case.
+ /// <tr><td> Produce lists of assertions from assertion creation calls.
+ /// <tr><td> Produce JUnit failures from assertion failures.
+ /// <tr><td> Convert failed assertions to error messages.
+ /// </table>
+ /// </summary>
+ public class FrameworkBaseCase extends AsymptoticTestCase : FrameworkTestContext, SetupTaskAware,
+ BrokerLifecycleAware
+ {
+ /// <summary> Used for debugging purposes. </summary>
+ private static ILog log = LogManager.GetLogger(typeof(FrameworkBaseCase));
+
+ /// <summary> Holds the test sequencer to create and run test circuits with. </summary>
+ protected CircuitFactory circuitFactory = new LocalCircuitFactory();
+
+ /// <summary> Used to read the tests configurable properties through. </summary>
+ protected ParsedProperties testProps;
+
+ /// <summary> A default setup task processor to delegate setup tasks to. </summary>
+ protected SetupTaskHandler taskHandler = new SetupTaskHandler();
+
+ /// <summary> Flag used to track whether the test is in-vm or not. </summary>
+ protected bool isUsingInVM;
+
+ /// <summary> Holds the failure mechanism. </summary>
+ protected CauseFailure failureMechanism = new CauseFailureUserPrompt();
+
+ /// <summary>
+ /// Creates a new test case with the specified name.
+ /// </summary>
+ /// <param name="name"> The test case name. </param>
+ public FrameworkBaseCase(string name)
+ {
+ super(name);
+ }
+
+ /// <summary>
+ /// Returns the test case sequencer that provides test circuit, and test sequence implementations. The sequencer
+ /// that this base case returns by default is suitable for running a test circuit with both circuit ends colocated
+ /// on the same JVM.
+ /// </summary>
+ /// <return> The test case sequencer. </return>
+ protected CircuitFactory getCircuitFactory()
+ {
+ return circuitFactory;
+ }
+
+ /// <summary>
+ /// Overrides the default test circuit factory. Test decorators can use this to supply distributed test sequencers or
+ /// other test circuit factory specializations.
+ /// </summary>
+ /// <param name="circuitFactory"> The new test circuit factory. </param>
+ public void setCircuitFactory(CircuitFactory circuitFactory)
+ {
+ this.circuitFactory = circuitFactory;
+ }
+
+ /// <summary>
+ /// Reports the current test case name.
+ /// </summary>
+ /// <return> The current test case name. </return>
+ public TestCaseVector getTestCaseVector()
+ {
+ return new TestCaseVector(this.getName(), 0);
+ }
+
+ /// <summary>
+ /// Reports the current test case parameters.
+ /// </summary>
+ /// <return> The current test case parameters. </return>
+ public MessagingTestConfigProperties getTestParameters()
+ {
+ return new MessagingTestConfigProperties(testProps);
+ }
+
+ /// <summary>
+ /// Creates a list of assertions.
+ /// </summary>
+ /// <param name="asserts"> The assertions to compile in a list. </param>
+ ///
+ /// <return> A list of assertions. </return>
+ protected IList<Assertion> assertionList(Assertion... asserts)
+ {
+ IList<Assertion> result = new ArrayList<Assertion>();
+
+ for (Assertion assertion : asserts)
+ {
+ result.add(assertion);
+ }
+
+ return result;
+ }
+
+ /// <summary>
+ /// Generates a JUnit assertion exception (failure) if any assertions are passed into this method, also concatenating
+ /// all of the error messages in the assertions together to form an error message to diagnose the test failure with.
+ /// </summary>
+ /// <param name="asserts"> The list of failed assertions. </param>
+ protected static void assertNoFailures(List<Assertion> asserts)
+ {
+ log.debug("protected void assertNoFailures(List<Assertion> asserts = " + asserts + "): called");
+
+ // Check if there are no assertion failures, and return without doing anything if so.
+ if ((asserts == null) || asserts.isEmpty())
+ {
+ return;
+ }
+
+ // Compile all of the assertion failure messages together.
+ string errorMessage = assertionsToString(asserts);
+
+ // Fail with the error message from all of the assertions.
+ fail(errorMessage);
+ }
+
+ /// <summary>
+ /// Converts a list of failed assertions into an error message.
+ /// </summary>
+ /// <param name="asserts"> The failed assertions. </param>
+ ///
+ /// <return> The error message. </return>
+ protected static string assertionsToString(List<Assertion> asserts)
+ {
+ string errorMessage = "";
+
+ for (Assertion assertion : asserts)
+ {
+ errorMessage += assertion.ToString() + "\n";
+ }
+
+ return errorMessage;
+ }
+
+ /// <summary>
+ /// Ensures that the in-vm broker is created and initialized.
+ /// </summary>
+ ///
+ /// <exception cref="Exception"> Any exceptions allowed to fall through and fail the test. </exception>
+ protected void setUp() throws Exception
+ {
+ NDC.push(getName());
+
+ testProps = TestContextProperties.getInstance(MessagingTestConfigProperties.defaults);
+
+ // Process all optional setup tasks. This may include in-vm broker creation, if a decorator has added it.
+ taskHandler.runSetupTasks();
+ }
+
+ /// <summary> Ensures that the in-vm broker is cleaned up after each test run. </summary>
+ protected void tearDown()
+ {
+ NDC.pop();
+
+ // Process all optional tear down tasks. This may include in-vm broker clean up, if a decorator has added it.
+ taskHandler.runTearDownTasks();
+ }
+
+ /// <summary>
+ /// Adds the specified task to the tests setup.
+ /// </summary>
+ /// <param name="task"> The task to add to the tests setup. </param>
+ public void chainSetupTask(Runnable task)
+ {
+ taskHandler.chainSetupTask(task);
+ }
+
+ /// <summary>
+ /// Adds the specified task to the tests tear down.
+ /// </summary>
+ /// <param name="task"> The task to add to the tests tear down. </param>
+ public void chainTearDownTask(Runnable task)
+ {
+ taskHandler.chainTearDownTask(task);
+ }
+
+ /// <summary>
+ /// Should provide a translation from the junit method name of a test to its test case name as known to the test
+ /// clients that will run the test. The purpose of this is to convert the JUnit method name into the correct test
+ /// case name to place into the test invite. For example the method "testP2P" might map onto the interop test case
+ /// name "TC2_BasicP2P".
+ /// </summary>
+ /// <param name="methodName"> The name of the JUnit test method. </param>
+ ///
+ /// <return> The name of the corresponding interop test case. </return>
+ public string getTestCaseNameForTestMethod(string methodName)
+ {
+ return methodName;
+ }
+
+ public void setInVmBrokers()
+ {
+ isUsingInVM = true;
+ }
+
+ /// <summary>
+ /// Indicates whether or not a test case is using in-vm brokers.
+ /// </summary>
+ /// <return> <tt>true</tt> if the test is using in-vm brokers, <tt>false</tt> otherwise. </return>
+ public bool usingInVmBroker()
+ {
+ return isUsingInVM;
+ }
+
+ /// <summary>
+ /// Sets the currently live in-vm broker.
+ /// </summary>
+ /// <param name="i"> The currently live in-vm broker. </param>
+ public void setLiveBroker(int i)
+ { }
+
+ /// <summary>
+ /// Reports the currently live in-vm broker.
+ /// </summary>
+ /// <return> The currently live in-vm broker. </return>
+ public int getLiveBroker()
+ {
+ return 0;
+ }
+
+ /// <summary>
+ /// Accepts a failure mechanism.
+ /// </summary>
+ /// <param name="failureMechanism"> The failure mechanism. </param>
+ public void setFailureMechanism(CauseFailure failureMechanism)
+ {
+ this.failureMechanism = failureMechanism;
+ }
+ }
+} \ No newline at end of file
diff --git a/qpid/dotnet/Qpid.Integration.Tests/framework/LocalCircuitFactory.csx b/qpid/dotnet/Qpid.Integration.Tests/framework/LocalCircuitFactory.csx
new file mode 100644
index 0000000000..45ecf26ffe
--- /dev/null
+++ b/qpid/dotnet/Qpid.Integration.Tests/framework/LocalCircuitFactory.csx
@@ -0,0 +1,301 @@
+/*
+ *
+ * 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.
+ *
+ */
+using log4net;
+
+using Apache.Qpid.Integration.Tests.framework.localcircuit;//.LocalCircuitImpl;
+//using Apache.Qpid.Integration.Tests.framework.localcircuit.LocalPublisherImpl;
+//using Apache.Qpid.Integration.Tests.framework.localcircuit.LocalReceiverImpl;
+//using Apache.Qpid.Integration.Tests.framework.sequencers.CircuitFactory;
+//using org.apache.qpid.util.ConversationFactory;
+
+//using uk.co.thebadgerset.junit.extensions.util.ParsedProperties;
+
+//using javax.jms.*;
+
+using System.Collections.Generic;//.IList;
+//using java.util.Properties;
+//using java.util.concurrent.atomic.AtomicLong;
+
+namespace Apache.Qpid.Integration.Tests.framework
+{
+ /// <summary>
+ /// LocalCircuitFactory is a circuit factory that creates test circuits with publishing and receiving ends rooted
+ /// on the same JVM. The ends of the circuit are presented as <see cref="Publisher"/> and <see cref="Receiver"/> interfaces, which
+ /// in turn provide methods to apply assertions to the circuit. The creation of the circuit ends, and the presentation
+ /// of the ends as publisher/receiver interfaces, are designed to be overriden, so that circuits and assertions that
+ /// use messaging features not available in JMS can be written. This provides an extension point for writing tests
+ /// against proprietary features of JMS implementations.
+ ///
+ /// <p/><table id="crc"><caption>CRC Card</caption>
+ /// <tr><th> Responsibilities <th> Collaborations
+ /// <tr><td> Provide a standard test procedure over a test circuit.
+ /// <tr><td> Construct test circuits appropriate to a tests context.
+ /// </table>
+ /// </summary>
+ public class LocalCircuitFactory : CircuitFactory
+ {
+ /// <summary> Used for debugging. </summary>
+ private static ILog log = LogManager.GetLogger(typeof(LocalCircuitFactory));
+
+ /// <summary> Used to create unique destination names for each test. </summary>
+ protected static AtomicLong uniqueDestsId = new AtomicLong();
+
+ /// <summary>
+ /// Holds a test coordinating conversation with the test clients. This should consist of assigning the test roles,
+ /// begining the test and gathering the test reports from the participants.
+ /// </summary>
+ /// <param name="testCircuit"> The test circuit. </param>
+ /// <param name="assertions"> The list of assertions to apply to the test circuit. </param>
+ /// <param name="testProperties"> The test case definition. </param>
+ public void sequenceTest(Circuit testCircuit, IList<Assertion> assertions, Properties testProperties)
+ {
+ FrameworkBaseCase.assertNoFailures(testCircuit.test(1, assertions));
+ }
+
+ /// <summary>
+ /// Creates a test circuit for the test, configered by the test parameters specified.
+ /// </summary>
+ /// <param name="testProperties"> The test parameters. </param>
+ ///
+ /// <return> A test circuit. </return>
+ public Circuit createCircuit(TestModel testProperties)
+ {
+ Circuit result;
+
+ // Create a standard publisher/receivers test client pair on a shared connection, individual sessions.
+ try
+ {
+ // Get a unique offset to append to destination names to make them unique to the connection.
+ long uniqueId = uniqueDestsId.incrementAndGet();
+
+ // Set up the connection.
+ Connection connection = TestUtils.createConnection(testProperties);
+
+ // Add the connection exception listener to assert on exception conditions with.
+ // ExceptionMonitor exceptionMonitor = new ExceptionMonitor();
+ // connection.setExceptionListener(exceptionMonitor);
+
+ // Set up the publisher.
+ CircuitEndBase publisherEnd = createPublisherCircuitEnd(connection, testProps, uniqueId);
+
+ // Set up the receiver.
+ CircuitEndBase receiverEnd = createReceiverCircuitEnd(connection, testProps, uniqueId);
+
+ // Start listening for incoming messages.
+ connection.start();
+
+ // Namespace everything up.
+ LocalPublisherImpl publisher = createPublisherFromCircuitEnd(publisherEnd);
+ LocalReceiverImpl receiver = createReceiverFromCircuitEnd(receiverEnd);
+
+ result = new LocalCircuitImpl(testProperties, publisher, receiver, connection, publisher.getExceptionMonitor());
+ }
+ catch (JMSException e)
+ {
+ throw new RuntimeException("Could not create publisher/receivers pair due to a JMSException.", e);
+ }
+
+ return result;
+ }
+
+ /// <summary>
+ /// Creates a local <see cref="Receiver"/> from a <see cref="CircuitEnd"/>. Sub-classes may override this to provide more
+ /// specialized receivers if necessary.
+ /// </summary>
+ /// <param name="receiverEnd"> The receiving circuit end. </param>
+ ///
+ /// <return> A <see cref="Receiver"/>. </return>
+ protected LocalReceiverImpl createReceiverFromCircuitEnd(CircuitEndBase receiverEnd)
+ {
+ return new LocalReceiverImpl(receiverEnd);
+ }
+
+ /// <summary>
+ /// Creates a local <see cref="Publisher"/> from a <see cref="CircuitEnd"/>. Sub-classes may override this to provide more
+ /// specialized receivers if necessary.
+ /// </summary>
+ /// <param name="publisherEnd"> The publishing circuit end. </param>
+ ///
+ /// <return> A <see cref="Receiver"/>. </return>
+ protected LocalPublisherImpl createPublisherFromCircuitEnd(CircuitEndBase publisherEnd)
+ {
+ return new LocalPublisherImpl(publisherEnd);
+ }
+
+ /// <summary>
+ /// Builds a circuit end suitable for the publishing side of a test circuit, from standard test parameters.
+ /// </summary>
+ /// <param name="connection"> The connection to build the circuit end on. </param>
+ /// <param name="testProps"> The test parameters to configure the circuit end construction. </param>
+ /// <param name="uniqueId"> A unique number to being numbering destinations from, to make this circuit unique. </param>
+ ///
+ /// <return> A circuit end suitable for the publishing side of a test circuit. </return>
+ ///
+ /// <exception cref="JMSException"> Any underlying JMSExceptions are allowed to fall through and fail the creation. </exception>
+ public CircuitEndBase createPublisherCircuitEnd(Connection connection, TestModel testProps, long uniqueId)
+ throws JMSException
+ {
+ log.debug(
+ "public CircuitEndBase createPublisherCircuitEnd(Connection connection, TestModel testProps, long uniqueId = "
+ + uniqueId + "): called");
+
+ // Check that the test properties do not contain AMQP/Qpid specific settings, and fail if they do.
+ if (testProps.getImmediate() || testProps.getMandatory())
+ {
+ throw new RuntimeException(
+ "Cannot create a pure JMS circuit as the test properties require AMQP specific options.");
+ }
+
+ Session session = connection.createSession(testProps.getPublisherTransacted(), testProps.getAckMode());
+
+ Destination destination =
+ testProps.getPubsub() ? session.createTopic(testProps.getSendDestinationNameRoot() + "_" + uniqueId)
+ : session.createQueue(testProps.getSendDestinationNameRoot() + "_" + uniqueId);
+
+ MessageProducer producer = testProps.getPublisherProducerBind() ? session.createProducer(destination) : null;
+
+ MessageConsumer consumer =
+ testProps.getPublisherConsumerBind()
+ ? session.createConsumer(session.createQueue(testProps.getReceiveDestinationNameRoot() + "_" + uniqueId)) : null;
+
+ MessageMonitor messageMonitor = new MessageMonitor();
+
+ if (consumer != null)
+ {
+ consumer.setMessageListener(messageMonitor);
+ }
+
+ ExceptionMonitor exceptionMonitor = new ExceptionMonitor();
+ connection.setExceptionListener(exceptionMonitor);
+
+ if (!testProps.getPublisherConsumerActive() && (consumer != null))
+ {
+ consumer.close();
+ }
+
+ return new CircuitEndBase(producer, consumer, session, messageMonitor, exceptionMonitor);
+ }
+
+ /// <summary>
+ /// Builds a circuit end suitable for the receiving side of a test circuit, from standard test parameters.
+ /// </summary>
+ /// <param name="connection"> The connection to build the circuit end on. </param>
+ /// <param name="testProps"> The test parameters to configure the circuit end construction. </param>
+ /// <param name="uniqueId"> A unique number to being numbering destinations from, to make this circuit unique. </param>
+ ///
+ /// <return> A circuit end suitable for the receiving side of a test circuit. </return>
+ ///
+ /// <exception cref="JMSException"> Any underlying JMSExceptions are allowed to fall through and fail the creation. </exception>
+ public CircuitEndBase createReceiverCircuitEnd(Connection connection, TestModel testProps, long uniqueId)
+ throws JMSException
+ {
+ log.debug(
+ "public CircuitEndBase createReceiverCircuitEnd(Connection connection, TestModel testProps, long uniqueId = "
+ + uniqueId + "): called");
+
+ // Check that the test properties do not contain AMQP/Qpid specific settings, and fail if they do.
+ if (testProps.getImmediate() || testProps.getMandatory())
+ {
+ throw new RuntimeException(
+ "Cannot create a pure JMS circuit as the test properties require AMQP specific options.");
+ }
+
+ Session session = connection.createSession(testProps.getPublisherTransacted(), testProps.getAckMode());
+
+ MessageProducer producer =
+ testProps.getReceiverProducerBind()
+ ? session.createProducer(session.createQueue(testProps.getReceiveDestinationNameRoot() + "_" + uniqueId)) : null;
+
+ Destination destination =
+ testProps.getPubsub() ? session.createTopic(testProps.getSendDestinationNameRoot() + "_" + uniqueId)
+ : session.createQueue(testProps.getSendDestinationNameRoot() + "_" + uniqueId);
+
+ MessageConsumer consumer =
+ testProps.getReceiverConsumerBind()
+ ? ((testProps.getDurableSubscription() && testProps.getPubsub())
+ ? session.createDurableSubscriber((Topic) destination, "testsub") : session.createConsumer(destination))
+ : null;
+
+ MessageMonitor messageMonitor = new MessageMonitor();
+
+ if (consumer != null)
+ {
+ consumer.setMessageListener(messageMonitor);
+ }
+
+ if (!testProps.getReceiverConsumerActive() && (consumer != null))
+ {
+ consumer.close();
+ }
+
+ return new CircuitEndBase(producer, consumer, session, messageMonitor, null);
+ }
+
+ /*
+ /// <summary>
+ /// Sets the sender test client to coordinate the test with.
+ /// </summary>
+ /// <param name="sender"> The contact details of the sending client in the test. </param>
+ public void setSender(TestClientDetails sender)
+ {
+ throw new RuntimeException("Not implemented.");
+ }
+
+ /// <summary>
+ /// Sets the receiving test client to coordinate the test with.
+ /// </summary>
+ /// <param name="receiver"> The contact details of the sending client in the test. </param>
+ public void setReceiver(TestClientDetails receiver)
+ {
+ throw new RuntimeException("Not implemented.");
+ }
+
+ /// <summary>
+ /// Supplies the sending test client.
+ /// </summary>
+ /// <return> The sending test client. </return>
+ public TestClientDetails getSender()
+ {
+ throw new RuntimeException("Not implemented.");
+ }
+
+ /// <summary>
+ /// Supplies the receiving test client.
+ /// </summary>
+ /// <return> The receiving test client. </return>
+ public IList<TestClientDetails> getReceivers()
+ {
+ throw new RuntimeException("Not implemented.");
+ }
+ */
+
+ /*
+ /// <summary>
+ /// Accepts the conversation factory over which to hold the test coordinating conversation.
+ /// </summary>
+ /// <param name="conversationFactory"> The conversation factory to coordinate the test over. </param>
+ public void setConversationFactory(ConversationFactory conversationFactory)
+ {
+ throw new RuntimeException("Not implemented.");
+ }
+ */
+ }
+} \ No newline at end of file
diff --git a/qpid/dotnet/Qpid.Integration.Tests/framework/MessageMonitor.csx b/qpid/dotnet/Qpid.Integration.Tests/framework/MessageMonitor.csx
new file mode 100644
index 0000000000..440d0761e5
--- /dev/null
+++ b/qpid/dotnet/Qpid.Integration.Tests/framework/MessageMonitor.csx
@@ -0,0 +1,102 @@
+/*
+ *
+ * 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.
+ *
+ */
+using log4net;
+using Apache.Qpid.Messaging;
+
+//using javax.jms.Message;
+//using javax.jms.MessageListener;
+
+//using java.util.concurrent.atomic.AtomicInteger;
+
+namespace Apache.Qpid.Integration.Tests.framework
+{
+ /// <summary>
+ /// MessageMonitor is used to record information about messages received. This will provide methods to check various
+ /// properties, such as the type, number and content of messages received in order to verify the correct behaviour of
+ /// tests.
+ ///
+ /// <p/><table id="crc"><caption>CRC Card</caption>
+ /// <tr><th> Responsibilities <th> Collaborations
+ /// <tr><td> Count incoming messages.
+ /// <tr><td> Record time ellapsed since the arrival of the first message.
+ /// <tr><td> Reset all counts and timings.
+ /// </table>
+ /// </summary>
+ public class MessageMonitor : MessageListener
+ {
+ /// <summary> Used for debugging. </summary>
+ private static ILog log = LogManager.GetLogger(typeof(MessageMonitor));
+
+ /// <summary> Holds the count of messages received since the last query. </summary>
+ protected AtomicInteger numMessages = new AtomicInteger();
+
+ /// <summary> Holds the time of arrival of the first message. </summary>
+ protected Long firstMessageTime = null;
+
+ /// <summary>
+ /// Handles received messages. Does Nothing.
+ /// </summary>
+ /// <param name="message"> The message. Ignored. </param>
+ public void onMessage(Message message)
+ {
+ // log.debug("public void onMessage(Message message): called");
+
+ numMessages.getAndIncrement();
+ }
+
+ /// <summary>
+ /// Gets the count of messages.
+ /// </summary>
+ /// <return> The count of messages. </return>
+ public int getNumMessage()
+ {
+ if (firstMessageTime == null)
+ {
+ firstMessageTime = System.nanoTime();
+ }
+
+ return numMessages.get();
+ }
+
+ /// <summary>
+ /// Gets the time elapsed since the first message arrived, in nanos, or zero if no messages have arrived yet.
+ /// </summary>
+ /// <return> The time elapsed since the first message arrived, in nanos, or zero if no messages have arrived yet. </return>
+ public long getTime()
+ {
+ if (firstMessageTime != null)
+ {
+ return System.nanoTime() - firstMessageTime;
+ }
+ else
+ {
+ return 0L;
+ }
+ }
+
+ /// <summary> Resets the message count and timer to zero. </summary>
+ public void reset()
+ {
+ numMessages.set(0);
+ firstMessageTime = null;
+ }
+ }
+} \ No newline at end of file
diff --git a/qpid/dotnet/Qpid.Integration.Tests/framework/MessagingTestConfigProperties.csx b/qpid/dotnet/Qpid.Integration.Tests/framework/MessagingTestConfigProperties.csx
new file mode 100644
index 0000000000..db19b5c2e0
--- /dev/null
+++ b/qpid/dotnet/Qpid.Integration.Tests/framework/MessagingTestConfigProperties.csx
@@ -0,0 +1,652 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+using uk.co.thebadgerset.junit.extensions.util.ParsedProperties;
+
+using javax.jms.Session;
+
+using java.util.Properties;
+
+namespace Apache.Qpid.Integration.Tests.framework
+{
+ /// <summary>
+ /// MessagingTestConfigProperties defines a set of property names and default values for specifying a messaging topology,
+ /// and test parameters for running a messaging test over that topology. A Properties object holding some of these
+ /// properties, superimposed onto the defaults, is used to establish test topologies and control test behaviour.
+ ///
+ /// <p/>A complete list of the parameters, default values and comments on their usage is provided here:
+ ///
+ /// <p/><table><caption>Parameters</caption>
+ /// <tr><th> Parameter <th> Default <th> Comments
+ /// <tr><td> messageSize <td> 0 <td> Message size in bytes. Not including any headers.
+ /// <tr><td> destinationName <td> ping <td> The root name to use to generate destination names to ping.
+ /// <tr><td> persistent <td> false <td> Determines whether peristent delivery is used.
+ /// <tr><td> transacted <td> false <td> Determines whether messages are sent/received in transactions.
+ /// <tr><td> broker <td> tcp://localhost:5672 <td> Determines the broker to connect to.
+ /// <tr><td> virtualHost <td> test <td> Determines the virtual host to send all ping over.
+ /// <tr><td> rate <td> 0 <td> The maximum rate (in hertz) to send messages at. 0 means no limit.
+ /// <tr><td> verbose <td> false <td> The verbose flag for debugging. Prints to console on every message.
+ /// <tr><td> pubsub <td> false <td> Whether to ping topics or queues. Uses p2p by default.
+ /// <tr><td> username <td> guest <td> The username to access the broker with.
+ /// <tr><td> password <td> guest <td> The password to access the broker with.
+ /// <tr><td> selector <td> null <td> Not used. Defines a message selector to filter pings with.
+ /// <tr><td> destinationCount <td> 1 <td> The number of receivers listening to the pings.
+ /// <tr><td> timeout <td> 30000 <td> In milliseconds. The timeout to stop waiting for replies.
+ /// <tr><td> commitBatchSize <td> 1 <td> The number of messages per transaction in transactional mode.
+ /// <tr><td> uniqueDests <td> true <td> Whether each receivers only listens to one ping destination or all.
+ /// <tr><td> durableDests <td> false <td> Whether or not durable destinations are used.
+ /// <tr><td> ackMode <td> AUTO_ACK <td> The message acknowledgement mode. Possible values are:
+ /// 0 - SESSION_TRANSACTED
+ /// 1 - AUTO_ACKNOWLEDGE
+ /// 2 - CLIENT_ACKNOWLEDGE
+ /// 3 - DUPS_OK_ACKNOWLEDGE
+ /// 257 - NO_ACKNOWLEDGE
+ /// 258 - PRE_ACKNOWLEDGE
+ /// <tr><td> maxPending <td> 0 <td> The maximum size in bytes, of messages sent but not yet received.
+ /// Limits the volume of messages currently buffered on the client
+ /// or broker. Can help scale test clients by limiting amount of buffered
+ /// data to avoid out of memory errors.
+ /// </table>
+ ///
+ /// <p><table id="crc"><caption>CRC Card</caption>
+ /// <tr><th> Responsibilities <th> Collaborations
+ /// <tr><td> Provide the names and defaults of all test parameters.
+ /// </table>
+ /// </summary>
+ ///
+ /// <remarks> Put a type-safe wrapper around these properties, but continue to store the parameters as properties. This is
+ /// simply to ensure that it is a simple matter to serialize/deserialize string/string pairs onto messages.</remarks>
+ public class MessagingTestConfigProperties extends ParsedProperties
+ {
+ // ====================== Connection Properties ==================================
+
+ /// <summary> Holds the name of the default connection configuration. </summary>
+ public static final string CONNECTION_NAME = "broker";
+
+ /// <summary> Holds the name of the property to get the initial context factory name from. </summary>
+ public static final string INITIAL_CONTEXT_FACTORY_PROPNAME = "java.naming.factory.initial";
+
+ /// <summary> Defines the class to use as the initial context factory by default. </summary>
+ public static final string INITIAL_CONTEXT_FACTORY_DEFAULT = "org.apache.qpid.jndi.PropertiesFileInitialContextFactory";
+
+ /// <summary> Holds the name of the property to get the test broker url from. </summary>
+ public static final string BROKER_PROPNAME = "qpid.test.broker";
+
+ /// <summary> Holds the default broker url for the test. </summary>
+ public static final string BROKER_DEFAULT = "vm://:1";
+
+ /// <summary> Holds the name of the property to get the test broker virtual path. </summary>
+ public static final string VIRTUAL_HOST_PROPNAME = "virtualHost";
+
+ /// <summary> Holds the default virtual path for the test. </summary>
+ public static final string VIRTUAL_HOST_DEFAULT = "";
+
+ /// <summary> Holds the name of the property to get the broker access username from. </summary>
+ public static final string USERNAME_PROPNAME = "username";
+
+ /// <summary> Holds the default broker log on username. </summary>
+ public static final string USERNAME_DEFAULT = "guest";
+
+ /// <summary> Holds the name of the property to get the broker access password from. </summary>
+ public static final string PASSWORD_PROPNAME = "password";
+
+ /// <summary> Holds the default broker log on password. </summary>
+ public static final string PASSWORD_DEFAULT = "guest";
+
+ // ====================== Messaging Topology Properties ==========================
+
+ /// <summary> Holds the name of the property to get the bind publisher procuder flag from. </summary>
+ public static final string PUBLISHER_PRODUCER_BIND_PROPNAME = "publisherProducerBind";
+
+ /// <summary> Holds the default value of the publisher producer flag. </summary>
+ public static final bool PUBLISHER_PRODUCER_BIND_DEFAULT = true;
+
+ /// <summary> Holds the name of the property to get the bind publisher procuder flag from. </summary>
+ public static final string PUBLISHER_CONSUMER_BIND_PROPNAME = "publisherConsumerBind";
+
+ /// <summary> Holds the default value of the publisher consumer flag. </summary>
+ public static final bool PUBLISHER_CONSUMER_BIND_DEFAULT = false;
+
+ /// <summary> Holds the name of the property to get the bind receivers procuder flag from. </summary>
+ public static final string RECEIVER_PRODUCER_BIND_PROPNAME = "receiverProducerBind";
+
+ /// <summary> Holds the default value of the receivers producer flag. </summary>
+ public static final bool RECEIVER_PRODUCER_BIND_DEFAULT = false;
+
+ /// <summary> Holds the name of the property to get the bind receivers procuder flag from. </summary>
+ public static final string RECEIVER_CONSUMER_BIND_PROPNAME = "receiverConsumerBind";
+
+ /// <summary> Holds the default value of the receivers consumer flag. </summary>
+ public static final bool RECEIVER_CONSUMER_BIND_DEFAULT = true;
+
+ /// <summary> Holds the name of the property to get the publishers consumer active flag from. </summary>
+ public static final string PUBLISHER_CONSUMER_ACTIVE_PROPNAME = "publisherConsumerActive";
+
+ /// <summary> Holds the default value of the publishers consumer active flag. </summary>
+ public static final bool PUBLISHER_CONSUMER_ACTIVE_DEFAULT = true;
+
+ /// <summary> Holds the name of the property to get the receivers consumer active flag from. </summary>
+ public static final string RECEIVER_CONSUMER_ACTIVE_PROPNAME = "receiverConsumerActive";
+
+ /// <summary> Holds the default value of the receivers consumer active flag. </summary>
+ public static final bool RECEIVER_CONSUMER_ACTIVE_DEFAULT = true;
+
+ /// <summary> Holds the name of the property to get the destination name root from. </summary>
+ public static final string SEND_DESTINATION_NAME_ROOT_PROPNAME = "sendDestinationRoot";
+
+ /// <summary> Holds the root of the name of the default destination to send to. </summary>
+ public static final string SEND_DESTINATION_NAME_ROOT_DEFAULT = "sendTo";
+
+ /// <summary> Holds the name of the property to get the destination name root from. </summary>
+ public static final string RECEIVE_DESTINATION_NAME_ROOT_PROPNAME = "receiveDestinationRoot";
+
+ /// <summary> Holds the root of the name of the default destination to send to. </summary>
+ public static final string RECEIVE_DESTINATION_NAME_ROOT_DEFAULT = "receiveFrom";
+
+ /// <summary> Holds the name of the proeprty to get the destination count from. </summary>
+ public static final string DESTINATION_COUNT_PROPNAME = "destinationCount";
+
+ /// <summary> Defines the default number of destinations to ping. </summary>
+ public static final int DESTINATION_COUNT_DEFAULT = 1;
+
+ /// <summary> Holds the name of the property to get the p2p or pub/sub messaging mode from. </summary>
+ public static final string PUBSUB_PROPNAME = "pubsub";
+
+ /// <summary> Holds the pub/sub mode default, true means ping a topic, false means ping a queue. </summary>
+ public static final bool PUBSUB_DEFAULT = false;
+
+ // ====================== JMS Options and Flags =================================
+
+ /// <summary> Holds the name of the property to get the test delivery mode from. </summary>
+ public static final string PERSISTENT_MODE_PROPNAME = "persistent";
+
+ /// <summary> Holds the message delivery mode to use for the test. </summary>
+ public static final bool PERSISTENT_MODE_DEFAULT = false;
+
+ /// <summary> Holds the name of the property to get the test transactional mode from. </summary>
+ public static final string TRANSACTED_PUBLISHER_PROPNAME = "transactedPublisher";
+
+ /// <summary> Holds the transactional mode to use for the test. </summary>
+ public static final bool TRANSACTED_PUBLISHER_DEFAULT = false;
+
+ /// <summary> Holds the name of the property to get the test transactional mode from. </summary>
+ public static final string TRANSACTED_RECEIVER_PROPNAME = "transactedReceiver";
+
+ /// <summary> Holds the transactional mode to use for the test. </summary>
+ public static final bool TRANSACTED_RECEIVER_DEFAULT = false;
+
+ /// <summary> Holds the name of the property to set the no local flag from. </summary>
+ public static final string NO_LOCAL_PROPNAME = "noLocal";
+
+ /// <summary> Defines the default value of the no local flag to use when consuming messages. </summary>
+ public static final bool NO_LOCAL_DEFAULT = false;
+
+ /// <summary> Holds the name of the property to get the message acknowledgement mode from. </summary>
+ public static final string ACK_MODE_PROPNAME = "ackMode";
+
+ /// <summary> Defines the default message acknowledgement mode. </summary>
+ public static final int ACK_MODE_DEFAULT = Session.AUTO_ACKNOWLEDGE;
+
+ /// <summary> Holds the name of the property to get the durable subscriptions flag from, when doing pub/sub messaging. </summary>
+ public static final string DURABLE_SUBSCRIPTION_PROPNAME = "durableSubscription";
+
+ /// <summary> Defines the default value of the durable subscriptions flag. </summary>
+ public static final bool DURABLE_SUBSCRIPTION_DEFAULT = false;
+
+ // ====================== Qpid/AMQP Options and Flags ================================
+
+ /// <summary> Holds the name of the property to set the exclusive flag from. </summary>
+ public static final string EXCLUSIVE_PROPNAME = "exclusive";
+
+ /// <summary> Defines the default value of the exclusive flag to use when consuming messages. </summary>
+ public static final bool EXCLUSIVE_DEFAULT = false;
+
+ /// <summary> Holds the name of the property to set the immediate flag from. </summary>
+ public static final string IMMEDIATE_PROPNAME = "immediate";
+
+ /// <summary> Defines the default value of the immediate flag to use when sending messages. </summary>
+ public static final bool IMMEDIATE_DEFAULT = false;
+
+ /// <summary> Holds the name of the property to set the mandatory flag from. </summary>
+ public static final string MANDATORY_PROPNAME = "mandatory";
+
+ /// <summary> Defines the default value of the mandatory flag to use when sending messages. </summary>
+ public static final bool MANDATORY_DEFAULT = false;
+
+ /// <summary> Holds the name of the property to get the durable destinations flag from. </summary>
+ public static final string DURABLE_DESTS_PROPNAME = "durableDests";
+
+ /// <summary> Default value for the durable destinations flag. </summary>
+ public static final bool DURABLE_DESTS_DEFAULT = false;
+
+ /// <summary> Holds the name of the property to set the prefetch size from. </summary>
+ public static final string PREFETCH_PROPNAME = "prefetch";
+
+ /// <summary> Defines the default prefetch size to use when consuming messages. </summary>
+ public static final int PREFETCH_DEFAULT = 100;
+
+ // ====================== Common Test Parameters ================================
+
+ /// <summary> Holds the name of the property to get the test message size from. </summary>
+ public static final string MESSAGE_SIZE_PROPNAME = "messageSize";
+
+ /// <summary> Used to set up a default message size. </summary>
+ public static final int MESSAGE_SIZE_DEAFULT = 0;
+
+ /// <summary> Holds the name of the property to get the message rate from. </summary>
+ public static final string RATE_PROPNAME = "rate";
+
+ /// <summary> Defines the default rate (in pings per second) to send pings at. 0 means as fast as possible, no restriction. </summary>
+ public static final int RATE_DEFAULT = 0;
+
+ /// <summary> Holds the name of the proeprty to get the. </summary>
+ public static final string SELECTOR_PROPNAME = "selector";
+
+ /// <summary> Holds the default message selector. </summary>
+ public static final string SELECTOR_DEFAULT = "";
+
+ /// <summary> Holds the name of the property to get the waiting timeout for response messages. </summary>
+ public static final string TIMEOUT_PROPNAME = "timeout";
+
+ /// <summary> Default time to wait before assuming that a ping has timed out. </summary>
+ public static final long TIMEOUT_DEFAULT = 30000;
+
+ /// <summary> Holds the name of the property to get the commit batch size from. </summary>
+ public static final string TX_BATCH_SIZE_PROPNAME = "commitBatchSize";
+
+ /// <summary> Defines the default number of pings to send in each transaction when running transactionally. </summary>
+ public static final int TX_BATCH_SIZE_DEFAULT = 1;
+
+ /// <summary> Holds the name of the property to set the maximum amount of pending message data for a producer to hold. </summary>
+ public static final string MAX_PENDING_PROPNAME = "maxPending";
+
+ /// <summary> Defines the default maximum quantity of pending message data to allow producers to hold. </summary>
+ public static final int MAX_PENDING_DEFAULT = 0;
+
+ /// <summary> Holds the name of the property to get the publisher rollback flag from. </summary>
+ public static final string ROLLBACK_PUBLISHER_PROPNAME = "rollbackPublisher";
+
+ /// <summary> Holds the default publisher roll back setting. </summary>
+ public static final bool ROLLBACK_PUBLISHER_DEFAULT = false;
+
+ /// <summary> Holds the name of the property to get the publisher rollback flag from. </summary>
+ public static final string ROLLBACK_RECEIVER_PROPNAME = "rollbackReceiver";
+
+ /// <summary> Holds the default publisher roll back setting. </summary>
+ public static final bool ROLLBACK_RECEIVER_DEFAULT = false;
+
+ // ====================== Options that control the bahviour of the test framework. =========================
+
+ /// <summary> Holds the name of the property to get the behavioural mode of not applicable assertions. </summary>
+ public static final string NOT_APPLICABLE_ASSERTION_PROPNAME = "notApplicableAssertion";
+
+ /// <summary> Holds the default behavioral mode of not applicable assertions, which is logging them as a warning. </summary>
+ public static final string NOT_APPLICABLE_ASSERTION_DEFAULT = "warn";
+
+ /// <summary> Holds the name of the property to get the verbose mode proeprty from. </summary>
+ public static final string VERBOSE_PROPNAME = "verbose";
+
+ /// <summary> Holds the default verbose mode. </summary>
+ public static final bool VERBOSE_DEFAULT = false;
+
+ /// <summary> Holds the default configuration properties. </summary>
+ public static ParsedProperties defaults = new ParsedProperties();
+
+ static
+ {
+ defaults.setPropertyIfNull(INITIAL_CONTEXT_FACTORY_PROPNAME, INITIAL_CONTEXT_FACTORY_DEFAULT);
+ defaults.setPropertyIfNull(BROKER_PROPNAME, BROKER_DEFAULT);
+ defaults.setPropertyIfNull(VIRTUAL_HOST_PROPNAME, VIRTUAL_HOST_DEFAULT);
+ defaults.setPropertyIfNull(USERNAME_PROPNAME, USERNAME_DEFAULT);
+ defaults.setPropertyIfNull(PASSWORD_PROPNAME, PASSWORD_DEFAULT);
+
+ defaults.setPropertyIfNull(PUBLISHER_PRODUCER_BIND_PROPNAME, PUBLISHER_PRODUCER_BIND_DEFAULT);
+ defaults.setPropertyIfNull(PUBLISHER_CONSUMER_BIND_PROPNAME, PUBLISHER_CONSUMER_BIND_DEFAULT);
+ defaults.setPropertyIfNull(RECEIVER_PRODUCER_BIND_PROPNAME, RECEIVER_PRODUCER_BIND_DEFAULT);
+ defaults.setPropertyIfNull(RECEIVER_CONSUMER_BIND_PROPNAME, RECEIVER_CONSUMER_BIND_DEFAULT);
+ defaults.setPropertyIfNull(PUBLISHER_CONSUMER_ACTIVE_PROPNAME, PUBLISHER_CONSUMER_ACTIVE_DEFAULT);
+ defaults.setPropertyIfNull(RECEIVER_CONSUMER_ACTIVE_PROPNAME, RECEIVER_CONSUMER_ACTIVE_DEFAULT);
+ defaults.setPropertyIfNull(SEND_DESTINATION_NAME_ROOT_PROPNAME, SEND_DESTINATION_NAME_ROOT_DEFAULT);
+ defaults.setPropertyIfNull(RECEIVE_DESTINATION_NAME_ROOT_PROPNAME, RECEIVE_DESTINATION_NAME_ROOT_DEFAULT);
+ defaults.setPropertyIfNull(DESTINATION_COUNT_PROPNAME, DESTINATION_COUNT_DEFAULT);
+ defaults.setPropertyIfNull(PUBSUB_PROPNAME, PUBSUB_DEFAULT);
+
+ defaults.setPropertyIfNull(PERSISTENT_MODE_PROPNAME, PERSISTENT_MODE_DEFAULT);
+ defaults.setPropertyIfNull(TRANSACTED_PUBLISHER_PROPNAME, TRANSACTED_PUBLISHER_DEFAULT);
+ defaults.setPropertyIfNull(TRANSACTED_RECEIVER_PROPNAME, TRANSACTED_RECEIVER_DEFAULT);
+ defaults.setPropertyIfNull(NO_LOCAL_PROPNAME, NO_LOCAL_DEFAULT);
+ defaults.setPropertyIfNull(ACK_MODE_PROPNAME, ACK_MODE_DEFAULT);
+ defaults.setPropertyIfNull(DURABLE_SUBSCRIPTION_PROPNAME, DURABLE_SUBSCRIPTION_DEFAULT);
+
+ defaults.setPropertyIfNull(EXCLUSIVE_PROPNAME, EXCLUSIVE_DEFAULT);
+ defaults.setPropertyIfNull(IMMEDIATE_PROPNAME, IMMEDIATE_DEFAULT);
+ defaults.setPropertyIfNull(MANDATORY_PROPNAME, MANDATORY_DEFAULT);
+ defaults.setPropertyIfNull(DURABLE_DESTS_PROPNAME, DURABLE_DESTS_DEFAULT);
+ defaults.setPropertyIfNull(PREFETCH_PROPNAME, PREFETCH_DEFAULT);
+
+ defaults.setPropertyIfNull(MESSAGE_SIZE_PROPNAME, MESSAGE_SIZE_DEAFULT);
+ defaults.setPropertyIfNull(RATE_PROPNAME, RATE_DEFAULT);
+ defaults.setPropertyIfNull(SELECTOR_PROPNAME, SELECTOR_DEFAULT);
+ defaults.setPropertyIfNull(TIMEOUT_PROPNAME, TIMEOUT_DEFAULT);
+ defaults.setPropertyIfNull(TX_BATCH_SIZE_PROPNAME, TX_BATCH_SIZE_DEFAULT);
+ defaults.setPropertyIfNull(MAX_PENDING_PROPNAME, MAX_PENDING_DEFAULT);
+ defaults.setPropertyIfNull(ROLLBACK_PUBLISHER_PROPNAME, ROLLBACK_PUBLISHER_DEFAULT);
+ defaults.setPropertyIfNull(ROLLBACK_RECEIVER_PROPNAME, ROLLBACK_RECEIVER_DEFAULT);
+
+ defaults.setPropertyIfNull(NOT_APPLICABLE_ASSERTION_PROPNAME, NOT_APPLICABLE_ASSERTION_DEFAULT);
+ defaults.setPropertyIfNull(VERBOSE_PROPNAME, VERBOSE_DEFAULT);
+ }
+
+ /// <summary> Creates a test configuration based on the defaults. </summary>
+ public MessagingTestConfigProperties()
+ {
+ super(defaults);
+ }
+
+ /// <summary>
+ /// Creates a test configuration based on the supplied properties.
+ /// </summary>
+ /// <param name="properties"> The test configuration. </param>
+ public MessagingTestConfigProperties(Properties properties)
+ {
+ super(properties);
+ }
+
+ /// <summary>
+ /// The size of test messages to send.
+ /// </summary>
+ /// <return> The size of test messages to send. </return>
+ public int getMessageSize()
+ {
+ return getPropertyAsInteger(MESSAGE_SIZE_PROPNAME);
+ }
+
+ /// <summary>
+ /// Flag to indicate that the publishing producer should be set up to publish to a destination.
+ /// </summary>
+ /// <return> Flag to indicate that the publishing producer should be set up to publish to a destination. </return>
+ public bool getPublisherProducerBind()
+ {
+ return getPropertyAsBoolean(PUBLISHER_PRODUCER_BIND_PROPNAME);
+ }
+
+ /// <summary>
+ /// Flag to indicate that the publishing consumer should be set up to receive from a destination.
+ /// </summary>
+ /// <return> Flag to indicate that the publishing consumer should be set up to receive from a destination. </return>
+ public bool getPublisherConsumerBind()
+ {
+ return getPropertyAsBoolean(PUBLISHER_CONSUMER_BIND_PROPNAME);
+ }
+
+ /// <summary>
+ /// Flag to indicate that the receiving producer should be set up to publish to a destination.
+ /// </summary>
+ /// <return> Flag to indicate that the receiving producer should be set up to publish to a destination. </return>
+ public bool getReceiverProducerBind()
+ {
+ return getPropertyAsBoolean(RECEIVER_PRODUCER_BIND_PROPNAME);
+ }
+
+ /// <summary>
+ /// Flag to indicate that the receiving consumer should be set up to receive from a destination.
+ /// </summary>
+ /// <return> Flag to indicate that the receiving consumer should be set up to receive from a destination. </return>
+ public bool getReceiverConsumerBind()
+ {
+ return getPropertyAsBoolean(RECEIVER_CONSUMER_BIND_PROPNAME);
+ }
+
+ /// <summary>
+ /// Flag to indicate that the publishing consumer should be created and actively listening.
+ /// </summary>
+ /// <return> Flag to indicate that the publishing consumer should be created. </return>
+ public bool getPublisherConsumerActive()
+ {
+ return getPropertyAsBoolean(PUBLISHER_CONSUMER_ACTIVE_PROPNAME);
+ }
+
+ /// <summary>
+ /// Flag to indicate that the receiving consumers should be created and actively listening.
+ /// </summary>
+ /// <return> Flag to indicate that the receiving consumers should be created and actively listening. </return>
+ public bool getReceiverConsumerActive()
+ {
+ return getPropertyAsBoolean(RECEIVER_CONSUMER_ACTIVE_PROPNAME);
+ }
+
+ /// <summary>
+ /// A root to create all test destination names from.
+ /// </summary>
+ /// <return> A root to create all test destination names from. </return>
+ public string getSendDestinationNameRoot()
+ {
+ return getProperty(SEND_DESTINATION_NAME_ROOT_PROPNAME);
+ }
+
+ /// <summary>
+ /// A root to create all receiving destination names from.
+ /// </summary>
+ /// <return> A root to create all receiving destination names from. </return>
+ public string getReceiveDestinationNameRoot()
+ {
+ return getProperty(RECEIVE_DESTINATION_NAME_ROOT_PROPNAME);
+ }
+
+ /// <summary>
+ /// Flag to indicate that persistent messages should be used.
+ /// </summary>
+ /// <return> Flag to indicate that persistent messages should be used. </return>
+ public bool getPersistentMode()
+ {
+ return getPropertyAsBoolean(PERSISTENT_MODE_PROPNAME);
+ }
+
+ /// <summary>
+ /// Flag to indicate that transactional messages should be sent by the publisher.
+ /// </summary>
+ /// <return> Flag to indicate that transactional messages should be sent by the publisher. </return>
+ public bool getPublisherTransacted()
+ {
+ return getPropertyAsBoolean(TRANSACTED_PUBLISHER_PROPNAME);
+ }
+
+ /// <summary>
+ /// Flag to indicate that transactional receives should be used by the receiver.
+ /// </summary>
+ /// <return> Flag to indicate that transactional receives should be used by the receiver. </return>
+ public bool getReceiverTransacted()
+ {
+ return getPropertyAsBoolean(TRANSACTED_PUBLISHER_PROPNAME);
+ }
+
+ /// <summary>
+ /// The name of the virtual host to run all tests over.
+ /// </summary>
+ /// <return> The name of the virtual host to run all tests over. </return>
+ public string getVirtualHost()
+ {
+ return getProperty(VIRTUAL_HOST_PROPNAME);
+ }
+
+ /// <summary>
+ /// Limiting rate for each sender in messages per second, or zero for unlimited.
+ /// </summary>
+ /// <return> Limiting rate for each sender in messages per second, or zero for unlimited. </return>
+ public string getRate()
+ {
+ return getProperty(RATE_PROPNAME);
+ }
+
+ /// <summary>
+ /// Flag to indicate that test messages should be received publish/subscribe style by all receivers.
+ /// </summary>
+ /// <return> Flag to indicate that test messages should be received publish/subscribe style by all receivers. </return>
+ public bool getPubsub()
+ {
+ return getPropertyAsBoolean(PUBSUB_PROPNAME);
+ }
+
+ /// <summary>
+ /// The username credentials to run tests with.
+ /// </summary>
+ /// <return> The username credentials to run tests with. </return>
+ public string getUsername()
+ {
+ return getProperty(USERNAME_PROPNAME);
+ }
+
+ /// <summary>
+ /// The password credentials to run tests with.
+ /// </summary>
+ /// <return> The password credentials to run tests with. </return>
+ public string getPassword()
+ {
+ return getProperty(PASSWORD_PROPNAME);
+ }
+
+ /// <summary>
+ /// The timeout duration to fail tests on, should they receive no messages within it.
+ /// </summary>
+ /// <return> The timeout duration to fail tests on, should they receive no messages within it. </return>
+ public long getTimeout()
+ {
+ return getPropertyAsLong(TIMEOUT_PROPNAME);
+ }
+
+ /// <summary>
+ /// The number of messages to batch into each transaction in transational tests.
+ /// </summary>
+ /// <return> The number of messages to batch into each transaction in transational tests. </return>
+ public int getTxBatchSize()
+ {
+ return getPropertyAsInteger(TX_BATCH_SIZE_PROPNAME);
+ }
+
+ /// <summary>
+ /// Flag to indicate that tests should use durable destinations.
+ /// </summary>
+ /// <return> Flag to indicate that tests should use durable destinations. </return>
+ public bool getDurableDests()
+ {
+ return getPropertyAsBoolean(DURABLE_DESTS_PROPNAME);
+ }
+
+ /// <summary>
+ /// The ack mode for message receivers to use.
+ /// </summary>
+ /// <return> The ack mode for message receivers to use. </return>
+ public int getAckMode()
+ {
+ return getPropertyAsInteger(ACK_MODE_PROPNAME);
+ }
+
+ /// <summary>
+ /// Flag to indicate that tests should use durable subscriptions.
+ /// </summary>
+ /// <return> Flag to indicate that tests should use durable subscriptions. </return>
+ public bool getDurableSubscription()
+ {
+ return getPropertyAsBoolean(DURABLE_SUBSCRIPTION_PROPNAME);
+ }
+
+ /// <summary>
+ /// The maximum amount of in-flight data, in bytes, that tests should send at any time.
+ /// </summary>
+ /// <return> The maximum amount of in-flight data, in bytes, that tests should send at any time. </return>
+ public int getMaxPending()
+ {
+ return getPropertyAsInteger(MAX_PENDING_PROPNAME);
+ }
+
+ /// <summary>
+ /// The size of the prefetch queue to use.
+ /// </summary>
+ /// <return> The size of the prefetch queue to use. </return>
+ public int getPrefetch()
+ {
+ return getPropertyAsInteger(PREFETCH_PROPNAME);
+ }
+
+ /// <summary>
+ /// Flag to indicate that subscriptions should be no-local.
+ /// </summary>
+ /// <return> Flag to indicate that subscriptions should be no-local. </return>
+ public bool getNoLocal()
+ {
+ return getPropertyAsBoolean(NO_LOCAL_PROPNAME);
+ }
+
+ /// <summary>
+ /// Flag to indicate that subscriptions should be exclusive.
+ /// </summary>
+ /// <return> Flag to indicate that subscriptions should be exclusive. </return>
+ public bool getExclusive()
+ {
+ return getPropertyAsBoolean(EXCLUSIVE_PROPNAME);
+ }
+
+ /// <summary>
+ /// Flag to indicate that messages must be delivered immediately.
+ /// </summary>
+ /// <return> Flag to indicate that messages must be delivered immediately. </return>
+ public bool getImmediate()
+ {
+ return getPropertyAsBoolean(IMMEDIATE_PROPNAME);
+ }
+
+ /// <summary>
+ /// Flag to indicate that messages must be routable.
+ /// </summary>
+ /// <return> Flag to indicate that messages must be routable. </return>
+ public bool getMandatory()
+ {
+ return getPropertyAsBoolean(MANDATORY_PROPNAME);
+ }
+
+ /// <summary>
+ /// Gets the value of a flag to indicate that the publisher should rollback all messages sent.
+ /// </summary>
+ /// <return> A flag to indicate that the publisher should rollback all messages sent. </return>
+ public bool getRollbackPublisher()
+ {
+ return getPropertyAsBoolean(ROLLBACK_PUBLISHER_PROPNAME);
+ }
+
+ /// <summary>
+ /// Gets the value of a flag to indicate that the receiver should rollback all messages received, then receive them
+ /// again.
+ /// </summary>
+ /// <return> A flag to indicate that the publisher should rollback all messages received. </return>
+ public bool getRollbackReceiver()
+ {
+ return getPropertyAsBoolean(ROLLBACK_RECEIVER_PROPNAME);
+ }
+
+ /// <summary>
+ /// Gets the behavioural mode of not applicable assertions. Should be one of 'quiet', 'warn' or 'fail'.
+ /// </summary>
+ /// <return> The behavioural mode of not applicable assertions. </return>
+ public string getNotApplicableAssertionMode()
+ {
+ return getProperty(NOT_APPLICABLE_ASSERTION_PROPNAME);
+ }
+ }
+} \ No newline at end of file
diff --git a/qpid/dotnet/Qpid.Integration.Tests/framework/NotApplicableAssertion.csx b/qpid/dotnet/Qpid.Integration.Tests/framework/NotApplicableAssertion.csx
new file mode 100644
index 0000000000..3e3505725f
--- /dev/null
+++ b/qpid/dotnet/Qpid.Integration.Tests/framework/NotApplicableAssertion.csx
@@ -0,0 +1,111 @@
+/*
+ *
+ * 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.
+ *
+ */
+using log4net;
+
+using uk.co.thebadgerset.junit.extensions.util.ParsedProperties;
+
+namespace Apache.Qpid.Integration.Tests.framework
+{
+ /// <summary>
+ /// NotApplicableAssertion is a messaging assertion that can be used when an assertion requested by a test-case is not
+ /// applicable to the testing scenario. For example an assertion may relate to AMQP functionality, but a test case may be
+ /// being run over a non-AMQP JMS implementation, in which case the request to create the assertion may return this
+ /// instead of the proper assertion. The test framework is configurable to quietly drop these assertions, log them
+ /// as warnings to the console, or raise them as test failures.
+ ///
+ /// <p/><table id="crc"><caption>CRC Card</caption>
+ /// <tr><th> Responsibilities <th> Collaborations
+ /// <tr><td> Quitely pass.
+ /// <tr><td> Log a warning.
+ /// <tr><td> Raise a test failure.
+ /// </table>
+ /// </summary>
+ public class NotApplicableAssertion : Assertion
+ {
+ /// <summary> Used for logging to the console. </summary>
+ private static ILog console = LogManager.GetLogger("CONSOLE." + NotApplicableAssertion.class.getName());
+
+ /// <summary> The possible behavioural modes of this assertion. </summary>
+ private enum Mode
+ {
+ /// <summary> Quietly ignore the assertion by passing. </summary>
+ Quiet,
+
+ /// <summary> Ignore the assertion by passing but log a warning about it. </summary>
+ Warn,
+
+ /// <summary> Fail the assertion. </summary>
+ Fail;
+ }
+
+ /// <summary> The behavioural mode of the assertion. </summary>
+ private Mode mode;
+
+ /// <summary>
+ /// Creates an assertion that is driven by the value of the 'notApplicableAssertion' property of the test
+ /// configuration. Its value should match one of 'quiet', 'warn' or 'fail' and if it does not it is automatically
+ /// read as 'fail'.
+ /// </summary>
+ /// <param name="testProperties"> The test configuration properties. </param>
+ public NotApplicableAssertion(ParsedProperties testProperties)
+ {
+ // Cast the test properties into a typed interface for convenience.
+ MessagingTestConfigProperties props = new MessagingTestConfigProperties(testProperties);
+
+ string modeName = props.getNotApplicableAssertionMode();
+
+ if ("quiet".equals(modeName))
+ {
+ mode = Mode.Quiet;
+ }
+ else if ("warn".equals(modeName))
+ {
+ mode = Mode.Warn;
+ }
+ else
+ {
+ mode = Mode.Fail;
+ }
+ }
+
+ /// <summary>
+ /// Applies the assertion.
+ /// </summary>
+ /// <return> <tt>true</tt> if the assertion passes, <tt>false</tt> if it fails. </return>
+ public bool apply()
+ {
+ switch (mode)
+ {
+ case Quiet:
+ return true;
+
+ case Warn:
+ console.warn("Warning: Not applicable assertion being ignored.");
+
+ return true;
+
+ case Fail:
+ default:
+ return false;
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/qpid/dotnet/Qpid.Integration.Tests/framework/Publisher.cs b/qpid/dotnet/Qpid.Integration.Tests/framework/Publisher.cs
new file mode 100644
index 0000000000..5fbdc7a907
--- /dev/null
+++ b/qpid/dotnet/Qpid.Integration.Tests/framework/Publisher.cs
@@ -0,0 +1,65 @@
+/*
+ *
+ * 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.
+ *
+ */
+//using uk.co.thebadgerset.junit.extensions.util.ParsedProperties;
+using System;
+
+namespace Apache.Qpid.Integration.Tests.framework
+{
+ /// <summary>
+ /// A Publisher represents the status of the publishing side of a test circuit. Its main purpose is to provide assertions
+ /// that can be applied to test the behaviour of the publishers.
+ ///
+ /// <p/><table id="crc"><caption>CRC Card</caption>
+ /// <tr><th> Responsibilities
+ /// <tr><td> Provide assertion that the publishers received no exceptions.
+ /// </table>
+ /// </summary>
+ public interface Publisher
+ {
+ /// <summary>
+ /// Provides an assertion that the publisher encountered no exceptions.
+ /// </summary>
+ ///
+ /// <param name="testProps"> The test configuration properties. </param>
+ ///
+ /// <return> An assertion that the publisher encountered no exceptions. </return>
+ Assertion NoExceptionsAssertion(TestModel testProps);
+
+ /// <summary>
+ /// Provides an assertion that the AMQP channel was forcibly closed by an error condition.
+ /// </summary>
+ ///
+ /// <param name="testProps"> The test configuration properties. </param>
+ ///
+ /// <return> An assertion that the AMQP channel was forcibly closed by an error condition. </return>
+ Assertion ChannelClosedAssertion(TestModel testProps);
+
+ /// <summary>
+ /// Provides an assertion that the publisher got a given exception during the test.
+ /// </summary>
+ ///
+ /// <param name="testProps"> The test configuration properties. </param>
+ /// <param name="exceptionClass"> The exception class to check for. </param>
+ ///
+ /// <return> An assertion that the publisher got a given exception during the test. </return>
+ Assertion ExceptionAssertion(TestModel testProps, Type exceptionClass);
+ }
+} \ No newline at end of file
diff --git a/qpid/dotnet/Qpid.Integration.Tests/framework/Publisher.csx b/qpid/dotnet/Qpid.Integration.Tests/framework/Publisher.csx
new file mode 100644
index 0000000000..b23b8c1e59
--- /dev/null
+++ b/qpid/dotnet/Qpid.Integration.Tests/framework/Publisher.csx
@@ -0,0 +1,72 @@
+/*
+ *
+ * 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.
+ *
+ */
+using uk.co.thebadgerset.junit.extensions.util.ParsedProperties;
+
+namespace Apache.Qpid.Integration.Tests.framework
+{
+ /// <summary>
+ /// A Publisher represents the status of the publishing side of a test circuit. Its main purpose is to provide assertions
+ /// that can be applied to test the behaviour of the publishers.
+ ///
+ /// <p/><table id="crc"><caption>CRC Card</caption>
+ /// <tr><th> Responsibilities
+ /// <tr><td> Provide assertion that the publishers received no exceptions.
+ /// </table>
+ /// </summary>
+ ///
+ /// <remarks> There are mixtures of AMQP and JMS assertions in this interface. Either keep them here, but quietly (or with a
+ /// warning or error) drop them from test cases where they are not relevant, or push them down into sub-classes.
+ /// I am tempted to go with the dropping/warning/error approach, that would imply that it makes sense to pull
+ /// the assertions back from AMQPPublisher to here.</remarks>
+ public interface Publisher
+ {
+ // Assertions that are meaningfull to AMQP and to JMS.
+
+ /// <summary>
+ /// Provides an assertion that the publisher encountered no exceptions.
+ /// </summary>
+ /// <param name="testProps"> The test configuration properties. </param>
+ ///
+ /// <return> An assertion that the publisher encountered no exceptions. </return>
+ public Assertion noExceptionsAssertion(ParsedProperties testProps);
+
+ // Assertions that are meaningfull only to AMQP.
+
+ /// <summary>
+ /// Provides an assertion that the AMQP channel was forcibly closed by an error condition.
+ /// </summary>
+ /// <param name="testProps"> The test configuration properties. </param>
+ ///
+ /// <return> An assertion that the AMQP channel was forcibly closed by an error condition. </return>
+ public Assertion channelClosedAssertion(ParsedProperties testProps);
+
+ // Assertions that are meaningfull only to Java/JMS.
+
+ /// <summary>
+ /// Provides an assertion that the publisher got a given exception during the test.
+ /// </summary>
+ /// <param name="testProps"> The test configuration properties. </param>
+ /// <param name="exceptionClass"> The exception class to check for. </param>
+ ///
+ /// <return> An assertion that the publisher got a given exception during the test. </return>
+ public Assertion exceptionAssertion(ParsedProperties testProps, Class<? extends Exception> exceptionClass);
+ }
+} \ No newline at end of file
diff --git a/qpid/dotnet/Qpid.Integration.Tests/framework/README.txt b/qpid/dotnet/Qpid.Integration.Tests/framework/README.txt
new file mode 100644
index 0000000000..927c3415e5
--- /dev/null
+++ b/qpid/dotnet/Qpid.Integration.Tests/framework/README.txt
@@ -0,0 +1,3 @@
+What are all these .csx files?
+
+This code is being ported over from the java. Some of the conversion was automated using search/replace/regex under emacs, but that cannot do all of it. The files were saved as .csx files with the 'x' standing for in-cross-over state. They will gradually be copied into .cs files as the conversion is completed and they are able to compile.
diff --git a/qpid/dotnet/Qpid.Integration.Tests/framework/Receiver.cs b/qpid/dotnet/Qpid.Integration.Tests/framework/Receiver.cs
new file mode 100644
index 0000000000..96820b5980
--- /dev/null
+++ b/qpid/dotnet/Qpid.Integration.Tests/framework/Receiver.cs
@@ -0,0 +1,80 @@
+/*
+ *
+ * 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.
+ *
+ */
+//using uk.co.thebadgerset.junit.extensions.util.ParsedProperties;
+using System;
+
+namespace Apache.Qpid.Integration.Tests.framework
+{
+ /// <summary>
+ /// A Receiver is a <see cref="CircuitEnd"/> that represents the status of the receiving side of a test circuit. Its main
+ /// purpose is to provide assertions that can be applied to check the behaviour of the receivers.
+ ///
+ /// <p/><table id="crc"><caption>CRC Card</caption>
+ /// <tr><th> Responsibilities
+ /// <tr><td> Provide assertion that the receivers received no exceptions.
+ /// <tr><td> Provide assertion that the receivers received all test messages sent to it.
+ /// </table>
+ /// </summary>
+ public interface Receiver
+ {
+ /// <summary>
+ /// Provides an assertion that the receivers encountered no exceptions.
+ /// </summary>
+ ///
+ /// <param name="testProps"> The test configuration properties. </param>
+ ///
+ /// <return> An assertion that the receivers encountered no exceptions. </return>
+ Assertion NoExceptionsAssertion(TestModel testProps);
+
+ /// <summary>
+ /// Provides an assertion that the receivers got all messages that were sent to it.
+ /// </summary>
+ /// <param name="testProps"> The test configuration properties. </param>
+ ///
+ /// <return> An assertion that the receivers got all messages that were sent to it. </return>
+ Assertion AllMessagesReceivedAssertion(TestModel testProps);
+
+ /// <summary>
+ /// Provides an assertion that the receivers got none of the messages that were sent to it.
+ /// </summary>
+ /// <param name="testProps"> The test configuration properties. </param>
+ ///
+ /// <return> An assertion that the receivers got none of the messages that were sent to it. </return>
+ Assertion NoMessagesReceivedAssertion(TestModel testProps);
+
+ /// <summary>
+ /// Provides an assertion that the AMQP channel was forcibly closed by an error condition.
+ /// </summary>
+ /// <param name="testProps"> The test configuration properties. </param>
+ ///
+ /// <return> An assertion that the AMQP channel was forcibly closed by an error condition. </return>
+ Assertion ChannelClosedAssertion(TestModel testProps);
+
+ /// <summary>
+ /// Provides an assertion that the receiver got a given exception during the test.
+ /// </summary>
+ /// <param name="testProps"> The test configuration properties. </param>
+ /// <param name="exceptionClass"> The exception class to check for. </param>
+ ///
+ /// <return> An assertion that the receiver got a given exception during the test. </return>
+ Assertion ExceptionAssertion(TestModel testProps, Type exceptionClass);
+ }
+} \ No newline at end of file
diff --git a/qpid/dotnet/Qpid.Integration.Tests/framework/Receiver.csx b/qpid/dotnet/Qpid.Integration.Tests/framework/Receiver.csx
new file mode 100644
index 0000000000..bafa57b34b
--- /dev/null
+++ b/qpid/dotnet/Qpid.Integration.Tests/framework/Receiver.csx
@@ -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.
+ *
+ */
+using uk.co.thebadgerset.junit.extensions.util.ParsedProperties;
+
+namespace Apache.Qpid.Integration.Tests.framework
+{
+ /// <summary>
+ /// A Receiver is a <see cref="CircuitEnd"/> that represents the status of the receiving side of a test circuit. Its main
+ /// purpose is to provide assertions that can be applied to check the behaviour of the receivers.
+ ///
+ /// <p/><table id="crc"><caption>CRC Card</caption>
+ /// <tr><th> Responsibilities
+ /// <tr><td> Provide assertion that the receivers received no exceptions.
+ /// <tr><td> Provide assertion that the receivers received all test messages sent to it.
+ /// </table>
+ /// </summary>
+ ///
+ /// <remarks> There are mixtures of AMQP and JMS assertions in this interface. Either keep them here, but quietly (or with a
+ /// warning or error) drop them from test cases where they are not relevant, or push them down into sub-classes.
+ /// I am tempted to go with the dropping/warning/error approach.</remarks>
+ public interface Receiver
+ {
+ // Assertions that are meaningfull to AMQP and to JMS.
+
+ /// <summary>
+ /// Provides an assertion that the receivers encountered no exceptions.
+ /// </summary>
+ /// <param name="testProps"> The test configuration properties. </param>
+ ///
+ /// <return> An assertion that the receivers encountered no exceptions. </return>
+ public Assertion noExceptionsAssertion(ParsedProperties testProps);
+
+ /// <summary>
+ /// Provides an assertion that the receivers got all messages that were sent to it.
+ /// </summary>
+ /// <param name="testProps"> The test configuration properties. </param>
+ ///
+ /// <return> An assertion that the receivers got all messages that were sent to it. </return>
+ public Assertion allMessagesReceivedAssertion(ParsedProperties testProps);
+
+ /// <summary>
+ /// Provides an assertion that the receivers got none of the messages that were sent to it.
+ /// </summary>
+ /// <param name="testProps"> The test configuration properties. </param>
+ ///
+ /// <return> An assertion that the receivers got none of the messages that were sent to it. </return>
+ public Assertion noMessagesReceivedAssertion(ParsedProperties testProps);
+
+ // Assertions that are meaningfull only to AMQP.
+
+ /// <summary>
+ /// Provides an assertion that the AMQP channel was forcibly closed by an error condition.
+ /// </summary>
+ /// <param name="testProps"> The test configuration properties. </param>
+ ///
+ /// <return> An assertion that the AMQP channel was forcibly closed by an error condition. </return>
+ public Assertion channelClosedAssertion(ParsedProperties testProps);
+
+ // Assertions that are meaningfull only to Java/JMS.
+
+ /// <summary>
+ /// Provides an assertion that the receiver got a given exception during the test.
+ /// </summary>
+ /// <param name="testProps"> The test configuration properties. </param>
+ /// <param name="exceptionClass"> The exception class to check for. </param>
+ ///
+ /// <return> An assertion that the receiver got a given exception during the test. </return>
+ public Assertion exceptionAssertion(ParsedProperties testProps, Class<? extends Exception> exceptionClass);
+ }
+} \ No newline at end of file
diff --git a/qpid/dotnet/Qpid.Integration.Tests/framework/TestClientDetails.cs b/qpid/dotnet/Qpid.Integration.Tests/framework/TestClientDetails.cs
new file mode 100644
index 0000000000..8be8de3d96
--- /dev/null
+++ b/qpid/dotnet/Qpid.Integration.Tests/framework/TestClientDetails.cs
@@ -0,0 +1,84 @@
+/*
+ *
+ * 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.
+ *
+ */
+using System;
+
+namespace Apache.Qpid.Integration.Tests.framework
+{
+ /// <summary>
+ /// TestClientDetails is used to encapsulate information about an interop test client. It pairs together the unique
+ /// name of the client, and the route on which it listens to its control messages.
+ ///
+ /// <p><table id="crc"><caption>CRC Card</caption>
+ /// <tr><th> Responsibilities <th> Collaborations
+ /// <tr><td> Record test clients control addresses together with their names.
+ /// </table>
+ /// </summary>
+ public class TestClientDetails
+ {
+ /// <summary> The test clients name. </summary>
+ public string clientName;
+
+ /// <summary> The routing key of the test clients control topic. </summary>
+ public string privateControlKey;
+
+ /// <summary>
+ /// Two TestClientDetails are considered to be equal, iff they have the same client name.
+ /// </summary>
+ /// <param name="o"> The object to compare to. </param>
+ ///
+ /// <return> <tt>If the object to compare to is a TestClientDetails equal to this one, <tt>false</tt> otherwise. </return>
+ public override bool Equals(Object o)
+ {
+ if (this == o)
+ {
+ return true;
+ }
+
+ if (!(o is TestClientDetails))
+ {
+ return false;
+ }
+
+ TestClientDetails testClientDetails = (TestClientDetails) o;
+
+ return !((clientName != null) ? (!clientName.Equals(testClientDetails.clientName))
+ : (testClientDetails.clientName != null));
+ }
+
+ /// <summary>
+ /// Computes a hash code compatible with the equals method; based on the client name alone.
+ /// </summary>
+ /// <return> A hash code for this. </return>
+ public override int GetHashCode()
+ {
+ return ((clientName != null) ? clientName.GetHashCode() : 0);
+ }
+
+ /// <summary>
+ /// Outputs the client name and address details. Mostly used for debugging purposes.
+ /// </summary>
+ /// <return> The client name and address. </return>
+ public override string ToString()
+ {
+ return "TestClientDetails: [ clientName = " + clientName + ", privateControlKey = " + privateControlKey + " ]";
+ }
+ }
+}
diff --git a/qpid/dotnet/Qpid.Integration.Tests/framework/TestClientDetails.csx b/qpid/dotnet/Qpid.Integration.Tests/framework/TestClientDetails.csx
new file mode 100644
index 0000000000..877367c762
--- /dev/null
+++ b/qpid/dotnet/Qpid.Integration.Tests/framework/TestClientDetails.csx
@@ -0,0 +1,82 @@
+/*
+ *
+ * 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.
+ *
+ */
+namespace Apache.Qpid.Integration.Tests.framework
+{
+ /// <summary>
+ /// TestClientDetails is used to encapsulate information about an interop test client. It pairs together the unique
+ /// name of the client, and the route on which it listens to its control messages.
+ ///
+ /// <p><table id="crc"><caption>CRC Card</caption>
+ /// <tr><th> Responsibilities <th> Collaborations
+ /// <tr><td> Record test clients control addresses together with their names.
+ /// </table>
+ /// </summary>
+ public class TestClientDetails
+ {
+ /// <summary> The test clients name. </summary>
+ public string clientName;
+
+ /// <summary> The routing key of the test clients control topic. </summary>
+ public string privateControlKey;
+
+ /// <summary>
+ /// Two TestClientDetails are considered to be equal, iff they have the same client name.
+ /// </summary>
+ /// <param name="o"> The object to compare to. </param>
+ ///
+ /// <return> <tt>If the object to compare to is a TestClientDetails equal to this one, <tt>false</tt> otherwise. </return>
+ public bool equals(Object o)
+ {
+ if (this == o)
+ {
+ return true;
+ }
+
+ if (!(o instanceof TestClientDetails))
+ {
+ return false;
+ }
+
+ final TestClientDetails testClientDetails = (TestClientDetails) o;
+
+ return !((clientName != null) ? (!clientName.equals(testClientDetails.clientName))
+ : (testClientDetails.clientName != null));
+ }
+
+ /// <summary>
+ /// Computes a hash code compatible with the equals method; based on the client name alone.
+ /// </summary>
+ /// <return> A hash code for this. </return>
+ public int hashCode()
+ {
+ return ((clientName != null) ? clientName.hashCode() : 0);
+ }
+
+ /// <summary>
+ /// Outputs the client name and address details. Mostly used for debugging purposes.
+ /// </summary>
+ /// <return> The client name and address. </return>
+ public string ToString()
+ {
+ return "TestClientDetails: [ clientName = " + clientName + ", privateControlKey = " + privateControlKey + " ]";
+ }
+ }
+}
diff --git a/qpid/dotnet/Qpid.Integration.Tests/framework/TestModel.cs b/qpid/dotnet/Qpid.Integration.Tests/framework/TestModel.cs
new file mode 100644
index 0000000000..88bea1e5ad
--- /dev/null
+++ b/qpid/dotnet/Qpid.Integration.Tests/framework/TestModel.cs
@@ -0,0 +1,657 @@
+/*
+ *
+ * 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.
+ *
+ */
+//using uk.co.thebadgerset.junit.extensions.util.ParsedProperties;
+
+//using javax.jms.Session;
+
+//using java.util.Properties;
+
+namespace Apache.Qpid.Integration.Tests.framework
+{
+ public class TestModel //extends ParsedProperties
+ {}
+
+ /*
+ /// <summary>
+ /// MessagingTestConfigProperties defines a set of property names and default values for specifying a messaging topology,
+ /// and test parameters for running a messaging test over that topology. A Properties object holding some of these
+ /// properties, superimposed onto the defaults, is used to establish test topologies and control test behaviour.
+ ///
+ /// <p/>A complete list of the parameters, default values and comments on their usage is provided here:
+ ///
+ /// <p/><table><caption>Parameters</caption>
+ /// <tr><th> Parameter <th> Default <th> Comments
+ /// <tr><td> messageSize <td> 0 <td> Message size in bytes. Not including any headers.
+ /// <tr><td> destinationName <td> ping <td> The root name to use to generate destination names to ping.
+ /// <tr><td> persistent <td> false <td> Determines whether peristent delivery is used.
+ /// <tr><td> transacted <td> false <td> Determines whether messages are sent/received in transactions.
+ /// <tr><td> broker <td> tcp://localhost:5672 <td> Determines the broker to connect to.
+ /// <tr><td> virtualHost <td> test <td> Determines the virtual host to send all ping over.
+ /// <tr><td> rate <td> 0 <td> The maximum rate (in hertz) to send messages at. 0 means no limit.
+ /// <tr><td> verbose <td> false <td> The verbose flag for debugging. Prints to console on every message.
+ /// <tr><td> pubsub <td> false <td> Whether to ping topics or queues. Uses p2p by default.
+ /// <tr><td> username <td> guest <td> The username to access the broker with.
+ /// <tr><td> password <td> guest <td> The password to access the broker with.
+ /// <tr><td> selector <td> null <td> Not used. Defines a message selector to filter pings with.
+ /// <tr><td> destinationCount <td> 1 <td> The number of receivers listening to the pings.
+ /// <tr><td> timeout <td> 30000 <td> In milliseconds. The timeout to stop waiting for replies.
+ /// <tr><td> commitBatchSize <td> 1 <td> The number of messages per transaction in transactional mode.
+ /// <tr><td> uniqueDests <td> true <td> Whether each receivers only listens to one ping destination or all.
+ /// <tr><td> durableDests <td> false <td> Whether or not durable destinations are used.
+ /// <tr><td> ackMode <td> AUTO_ACK <td> The message acknowledgement mode. Possible values are:
+ /// 0 - SESSION_TRANSACTED
+ /// 1 - AUTO_ACKNOWLEDGE
+ /// 2 - CLIENT_ACKNOWLEDGE
+ /// 3 - DUPS_OK_ACKNOWLEDGE
+ /// 257 - NO_ACKNOWLEDGE
+ /// 258 - PRE_ACKNOWLEDGE
+ /// <tr><td> maxPending <td> 0 <td> The maximum size in bytes, of messages sent but not yet received.
+ /// Limits the volume of messages currently buffered on the client
+ /// or broker. Can help scale test clients by limiting amount of buffered
+ /// data to avoid out of memory errors.
+ /// </table>
+ ///
+ /// <p><table id="crc"><caption>CRC Card</caption>
+ /// <tr><th> Responsibilities <th> Collaborations
+ /// <tr><td> Provide the names and defaults of all test parameters.
+ /// </table>
+ /// </summary>
+ ///
+ /// <remarks> Put a type-safe wrapper around these properties, but continue to store the parameters as properties. This is
+ /// simply to ensure that it is a simple matter to serialize/deserialize string/string pairs onto messages.</remarks>
+ public class MessagingTestConfigProperties extends ParsedProperties
+ {
+ // ====================== Connection Properties ==================================
+
+ /// <summary> Holds the name of the default connection configuration. </summary>
+ public static final string CONNECTION_NAME = "broker";
+
+ /// <summary> Holds the name of the property to get the initial context factory name from. </summary>
+ public static final string INITIAL_CONTEXT_FACTORY_PROPNAME = "java.naming.factory.initial";
+
+ /// <summary> Defines the class to use as the initial context factory by default. </summary>
+ public static final string INITIAL_CONTEXT_FACTORY_DEFAULT = "org.apache.qpid.jndi.PropertiesFileInitialContextFactory";
+
+ /// <summary> Holds the name of the property to get the test broker url from. </summary>
+ public static final string BROKER_PROPNAME = "qpid.test.broker";
+
+ /// <summary> Holds the default broker url for the test. </summary>
+ public static final string BROKER_DEFAULT = "vm://:1";
+
+ /// <summary> Holds the name of the property to get the test broker virtual path. </summary>
+ public static final string VIRTUAL_HOST_PROPNAME = "virtualHost";
+
+ /// <summary> Holds the default virtual path for the test. </summary>
+ public static final string VIRTUAL_HOST_DEFAULT = "";
+
+ /// <summary> Holds the name of the property to get the broker access username from. </summary>
+ public static final string USERNAME_PROPNAME = "username";
+
+ /// <summary> Holds the default broker log on username. </summary>
+ public static final string USERNAME_DEFAULT = "guest";
+
+ /// <summary> Holds the name of the property to get the broker access password from. </summary>
+ public static final string PASSWORD_PROPNAME = "password";
+
+ /// <summary> Holds the default broker log on password. </summary>
+ public static final string PASSWORD_DEFAULT = "guest";
+
+ // ====================== Messaging Topology Properties ==========================
+
+ /// <summary> Holds the name of the property to get the bind publisher procuder flag from. </summary>
+ public static final string PUBLISHER_PRODUCER_BIND_PROPNAME = "publisherProducerBind";
+
+ /// <summary> Holds the default value of the publisher producer flag. </summary>
+ public static final bool PUBLISHER_PRODUCER_BIND_DEFAULT = true;
+
+ /// <summary> Holds the name of the property to get the bind publisher procuder flag from. </summary>
+ public static final string PUBLISHER_CONSUMER_BIND_PROPNAME = "publisherConsumerBind";
+
+ /// <summary> Holds the default value of the publisher consumer flag. </summary>
+ public static final bool PUBLISHER_CONSUMER_BIND_DEFAULT = false;
+
+ /// <summary> Holds the name of the property to get the bind receivers procuder flag from. </summary>
+ public static final string RECEIVER_PRODUCER_BIND_PROPNAME = "receiverProducerBind";
+
+ /// <summary> Holds the default value of the receivers producer flag. </summary>
+ public static final bool RECEIVER_PRODUCER_BIND_DEFAULT = false;
+
+ /// <summary> Holds the name of the property to get the bind receivers procuder flag from. </summary>
+ public static final string RECEIVER_CONSUMER_BIND_PROPNAME = "receiverConsumerBind";
+
+ /// <summary> Holds the default value of the receivers consumer flag. </summary>
+ public static final bool RECEIVER_CONSUMER_BIND_DEFAULT = true;
+
+ /// <summary> Holds the name of the property to get the publishers consumer active flag from. </summary>
+ public static final string PUBLISHER_CONSUMER_ACTIVE_PROPNAME = "publisherConsumerActive";
+
+ /// <summary> Holds the default value of the publishers consumer active flag. </summary>
+ public static final bool PUBLISHER_CONSUMER_ACTIVE_DEFAULT = true;
+
+ /// <summary> Holds the name of the property to get the receivers consumer active flag from. </summary>
+ public static final string RECEIVER_CONSUMER_ACTIVE_PROPNAME = "receiverConsumerActive";
+
+ /// <summary> Holds the default value of the receivers consumer active flag. </summary>
+ public static final bool RECEIVER_CONSUMER_ACTIVE_DEFAULT = true;
+
+ /// <summary> Holds the name of the property to get the destination name root from. </summary>
+ public static final string SEND_DESTINATION_NAME_ROOT_PROPNAME = "sendDestinationRoot";
+
+ /// <summary> Holds the root of the name of the default destination to send to. </summary>
+ public static final string SEND_DESTINATION_NAME_ROOT_DEFAULT = "sendTo";
+
+ /// <summary> Holds the name of the property to get the destination name root from. </summary>
+ public static final string RECEIVE_DESTINATION_NAME_ROOT_PROPNAME = "receiveDestinationRoot";
+
+ /// <summary> Holds the root of the name of the default destination to send to. </summary>
+ public static final string RECEIVE_DESTINATION_NAME_ROOT_DEFAULT = "receiveFrom";
+
+ /// <summary> Holds the name of the proeprty to get the destination count from. </summary>
+ public static final string DESTINATION_COUNT_PROPNAME = "destinationCount";
+
+ /// <summary> Defines the default number of destinations to ping. </summary>
+ public static final int DESTINATION_COUNT_DEFAULT = 1;
+
+ /// <summary> Holds the name of the property to get the p2p or pub/sub messaging mode from. </summary>
+ public static final string PUBSUB_PROPNAME = "pubsub";
+
+ /// <summary> Holds the pub/sub mode default, true means ping a topic, false means ping a queue. </summary>
+ public static final bool PUBSUB_DEFAULT = false;
+
+ // ====================== JMS Options and Flags =================================
+
+ /// <summary> Holds the name of the property to get the test delivery mode from. </summary>
+ public static final string PERSISTENT_MODE_PROPNAME = "persistent";
+
+ /// <summary> Holds the message delivery mode to use for the test. </summary>
+ public static final bool PERSISTENT_MODE_DEFAULT = false;
+
+ /// <summary> Holds the name of the property to get the test transactional mode from. </summary>
+ public static final string TRANSACTED_PUBLISHER_PROPNAME = "transactedPublisher";
+
+ /// <summary> Holds the transactional mode to use for the test. </summary>
+ public static final bool TRANSACTED_PUBLISHER_DEFAULT = false;
+
+ /// <summary> Holds the name of the property to get the test transactional mode from. </summary>
+ public static final string TRANSACTED_RECEIVER_PROPNAME = "transactedReceiver";
+
+ /// <summary> Holds the transactional mode to use for the test. </summary>
+ public static final bool TRANSACTED_RECEIVER_DEFAULT = false;
+
+ /// <summary> Holds the name of the property to set the no local flag from. </summary>
+ public static final string NO_LOCAL_PROPNAME = "noLocal";
+
+ /// <summary> Defines the default value of the no local flag to use when consuming messages. </summary>
+ public static final bool NO_LOCAL_DEFAULT = false;
+
+ /// <summary> Holds the name of the property to get the message acknowledgement mode from. </summary>
+ public static final string ACK_MODE_PROPNAME = "ackMode";
+
+ /// <summary> Defines the default message acknowledgement mode. </summary>
+ public static final int ACK_MODE_DEFAULT = Session.AUTO_ACKNOWLEDGE;
+
+ /// <summary> Holds the name of the property to get the durable subscriptions flag from, when doing pub/sub messaging. </summary>
+ public static final string DURABLE_SUBSCRIPTION_PROPNAME = "durableSubscription";
+
+ /// <summary> Defines the default value of the durable subscriptions flag. </summary>
+ public static final bool DURABLE_SUBSCRIPTION_DEFAULT = false;
+
+ // ====================== Qpid/AMQP Options and Flags ================================
+
+ /// <summary> Holds the name of the property to set the exclusive flag from. </summary>
+ public static final string EXCLUSIVE_PROPNAME = "exclusive";
+
+ /// <summary> Defines the default value of the exclusive flag to use when consuming messages. </summary>
+ public static final bool EXCLUSIVE_DEFAULT = false;
+
+ /// <summary> Holds the name of the property to set the immediate flag from. </summary>
+ public static final string IMMEDIATE_PROPNAME = "immediate";
+
+ /// <summary> Defines the default value of the immediate flag to use when sending messages. </summary>
+ public static final bool IMMEDIATE_DEFAULT = false;
+
+ /// <summary> Holds the name of the property to set the mandatory flag from. </summary>
+ public static final string MANDATORY_PROPNAME = "mandatory";
+
+ /// <summary> Defines the default value of the mandatory flag to use when sending messages. </summary>
+ public static final bool MANDATORY_DEFAULT = false;
+
+ /// <summary> Holds the name of the property to get the durable destinations flag from. </summary>
+ public static final string DURABLE_DESTS_PROPNAME = "durableDests";
+
+ /// <summary> Default value for the durable destinations flag. </summary>
+ public static final bool DURABLE_DESTS_DEFAULT = false;
+
+ /// <summary> Holds the name of the property to set the prefetch size from. </summary>
+ public static final string PREFETCH_PROPNAME = "prefetch";
+
+ /// <summary> Defines the default prefetch size to use when consuming messages. </summary>
+ public static final int PREFETCH_DEFAULT = 100;
+
+ // ====================== Common Test Parameters ================================
+
+ /// <summary> Holds the name of the property to get the test message size from. </summary>
+ public static final string MESSAGE_SIZE_PROPNAME = "messageSize";
+
+ /// <summary> Used to set up a default message size. </summary>
+ public static final int MESSAGE_SIZE_DEAFULT = 0;
+
+ /// <summary> Holds the name of the property to get the message rate from. </summary>
+ public static final string RATE_PROPNAME = "rate";
+
+ /// <summary> Defines the default rate (in pings per second) to send pings at. 0 means as fast as possible, no restriction. </summary>
+ public static final int RATE_DEFAULT = 0;
+
+ /// <summary> Holds the name of the proeprty to get the. </summary>
+ public static final string SELECTOR_PROPNAME = "selector";
+
+ /// <summary> Holds the default message selector. </summary>
+ public static final string SELECTOR_DEFAULT = "";
+
+ /// <summary> Holds the name of the property to get the waiting timeout for response messages. </summary>
+ public static final string TIMEOUT_PROPNAME = "timeout";
+
+ /// <summary> Default time to wait before assuming that a ping has timed out. </summary>
+ public static final long TIMEOUT_DEFAULT = 30000;
+
+ /// <summary> Holds the name of the property to get the commit batch size from. </summary>
+ public static final string TX_BATCH_SIZE_PROPNAME = "commitBatchSize";
+
+ /// <summary> Defines the default number of pings to send in each transaction when running transactionally. </summary>
+ public static final int TX_BATCH_SIZE_DEFAULT = 1;
+
+ /// <summary> Holds the name of the property to set the maximum amount of pending message data for a producer to hold. </summary>
+ public static final string MAX_PENDING_PROPNAME = "maxPending";
+
+ /// <summary> Defines the default maximum quantity of pending message data to allow producers to hold. </summary>
+ public static final int MAX_PENDING_DEFAULT = 0;
+
+ /// <summary> Holds the name of the property to get the publisher rollback flag from. </summary>
+ public static final string ROLLBACK_PUBLISHER_PROPNAME = "rollbackPublisher";
+
+ /// <summary> Holds the default publisher roll back setting. </summary>
+ public static final bool ROLLBACK_PUBLISHER_DEFAULT = false;
+
+ /// <summary> Holds the name of the property to get the publisher rollback flag from. </summary>
+ public static final string ROLLBACK_RECEIVER_PROPNAME = "rollbackReceiver";
+
+ /// <summary> Holds the default publisher roll back setting. </summary>
+ public static final bool ROLLBACK_RECEIVER_DEFAULT = false;
+
+ // ====================== Options that control the bahviour of the test framework. =========================
+
+ /// <summary> Holds the name of the property to get the behavioural mode of not applicable assertions. </summary>
+ public static final string NOT_APPLICABLE_ASSERTION_PROPNAME = "notApplicableAssertion";
+
+ /// <summary> Holds the default behavioral mode of not applicable assertions, which is logging them as a warning. </summary>
+ public static final string NOT_APPLICABLE_ASSERTION_DEFAULT = "warn";
+
+ /// <summary> Holds the name of the property to get the verbose mode proeprty from. </summary>
+ public static final string VERBOSE_PROPNAME = "verbose";
+
+ /// <summary> Holds the default verbose mode. </summary>
+ public static final bool VERBOSE_DEFAULT = false;
+
+ /// <summary> Holds the default configuration properties. </summary>
+ public static ParsedProperties defaults = new ParsedProperties();
+
+ static
+ {
+ defaults.setPropertyIfNull(INITIAL_CONTEXT_FACTORY_PROPNAME, INITIAL_CONTEXT_FACTORY_DEFAULT);
+ defaults.setPropertyIfNull(BROKER_PROPNAME, BROKER_DEFAULT);
+ defaults.setPropertyIfNull(VIRTUAL_HOST_PROPNAME, VIRTUAL_HOST_DEFAULT);
+ defaults.setPropertyIfNull(USERNAME_PROPNAME, USERNAME_DEFAULT);
+ defaults.setPropertyIfNull(PASSWORD_PROPNAME, PASSWORD_DEFAULT);
+
+ defaults.setPropertyIfNull(PUBLISHER_PRODUCER_BIND_PROPNAME, PUBLISHER_PRODUCER_BIND_DEFAULT);
+ defaults.setPropertyIfNull(PUBLISHER_CONSUMER_BIND_PROPNAME, PUBLISHER_CONSUMER_BIND_DEFAULT);
+ defaults.setPropertyIfNull(RECEIVER_PRODUCER_BIND_PROPNAME, RECEIVER_PRODUCER_BIND_DEFAULT);
+ defaults.setPropertyIfNull(RECEIVER_CONSUMER_BIND_PROPNAME, RECEIVER_CONSUMER_BIND_DEFAULT);
+ defaults.setPropertyIfNull(PUBLISHER_CONSUMER_ACTIVE_PROPNAME, PUBLISHER_CONSUMER_ACTIVE_DEFAULT);
+ defaults.setPropertyIfNull(RECEIVER_CONSUMER_ACTIVE_PROPNAME, RECEIVER_CONSUMER_ACTIVE_DEFAULT);
+ defaults.setPropertyIfNull(SEND_DESTINATION_NAME_ROOT_PROPNAME, SEND_DESTINATION_NAME_ROOT_DEFAULT);
+ defaults.setPropertyIfNull(RECEIVE_DESTINATION_NAME_ROOT_PROPNAME, RECEIVE_DESTINATION_NAME_ROOT_DEFAULT);
+ defaults.setPropertyIfNull(DESTINATION_COUNT_PROPNAME, DESTINATION_COUNT_DEFAULT);
+ defaults.setPropertyIfNull(PUBSUB_PROPNAME, PUBSUB_DEFAULT);
+
+ defaults.setPropertyIfNull(PERSISTENT_MODE_PROPNAME, PERSISTENT_MODE_DEFAULT);
+ defaults.setPropertyIfNull(TRANSACTED_PUBLISHER_PROPNAME, TRANSACTED_PUBLISHER_DEFAULT);
+ defaults.setPropertyIfNull(TRANSACTED_RECEIVER_PROPNAME, TRANSACTED_RECEIVER_DEFAULT);
+ defaults.setPropertyIfNull(NO_LOCAL_PROPNAME, NO_LOCAL_DEFAULT);
+ defaults.setPropertyIfNull(ACK_MODE_PROPNAME, ACK_MODE_DEFAULT);
+ defaults.setPropertyIfNull(DURABLE_SUBSCRIPTION_PROPNAME, DURABLE_SUBSCRIPTION_DEFAULT);
+
+ defaults.setPropertyIfNull(EXCLUSIVE_PROPNAME, EXCLUSIVE_DEFAULT);
+ defaults.setPropertyIfNull(IMMEDIATE_PROPNAME, IMMEDIATE_DEFAULT);
+ defaults.setPropertyIfNull(MANDATORY_PROPNAME, MANDATORY_DEFAULT);
+ defaults.setPropertyIfNull(DURABLE_DESTS_PROPNAME, DURABLE_DESTS_DEFAULT);
+ defaults.setPropertyIfNull(PREFETCH_PROPNAME, PREFETCH_DEFAULT);
+
+ defaults.setPropertyIfNull(MESSAGE_SIZE_PROPNAME, MESSAGE_SIZE_DEAFULT);
+ defaults.setPropertyIfNull(RATE_PROPNAME, RATE_DEFAULT);
+ defaults.setPropertyIfNull(SELECTOR_PROPNAME, SELECTOR_DEFAULT);
+ defaults.setPropertyIfNull(TIMEOUT_PROPNAME, TIMEOUT_DEFAULT);
+ defaults.setPropertyIfNull(TX_BATCH_SIZE_PROPNAME, TX_BATCH_SIZE_DEFAULT);
+ defaults.setPropertyIfNull(MAX_PENDING_PROPNAME, MAX_PENDING_DEFAULT);
+ defaults.setPropertyIfNull(ROLLBACK_PUBLISHER_PROPNAME, ROLLBACK_PUBLISHER_DEFAULT);
+ defaults.setPropertyIfNull(ROLLBACK_RECEIVER_PROPNAME, ROLLBACK_RECEIVER_DEFAULT);
+
+ defaults.setPropertyIfNull(NOT_APPLICABLE_ASSERTION_PROPNAME, NOT_APPLICABLE_ASSERTION_DEFAULT);
+ defaults.setPropertyIfNull(VERBOSE_PROPNAME, VERBOSE_DEFAULT);
+ }
+
+ /// <summary> Creates a test configuration based on the defaults. </summary>
+ public MessagingTestConfigProperties()
+ {
+ super(defaults);
+ }
+
+ /// <summary>
+ /// Creates a test configuration based on the supplied properties.
+ /// </summary>
+ /// <param name="properties"> The test configuration. </param>
+ public MessagingTestConfigProperties(Properties properties)
+ {
+ super(properties);
+ }
+
+ /// <summary>
+ /// The size of test messages to send.
+ /// </summary>
+ /// <return> The size of test messages to send. </return>
+ public int getMessageSize()
+ {
+ return getPropertyAsInteger(MESSAGE_SIZE_PROPNAME);
+ }
+
+ /// <summary>
+ /// Flag to indicate that the publishing producer should be set up to publish to a destination.
+ /// </summary>
+ /// <return> Flag to indicate that the publishing producer should be set up to publish to a destination. </return>
+ public bool getPublisherProducerBind()
+ {
+ return getPropertyAsBoolean(PUBLISHER_PRODUCER_BIND_PROPNAME);
+ }
+
+ /// <summary>
+ /// Flag to indicate that the publishing consumer should be set up to receive from a destination.
+ /// </summary>
+ /// <return> Flag to indicate that the publishing consumer should be set up to receive from a destination. </return>
+ public bool getPublisherConsumerBind()
+ {
+ return getPropertyAsBoolean(PUBLISHER_CONSUMER_BIND_PROPNAME);
+ }
+
+ /// <summary>
+ /// Flag to indicate that the receiving producer should be set up to publish to a destination.
+ /// </summary>
+ /// <return> Flag to indicate that the receiving producer should be set up to publish to a destination. </return>
+ public bool getReceiverProducerBind()
+ {
+ return getPropertyAsBoolean(RECEIVER_PRODUCER_BIND_PROPNAME);
+ }
+
+ /// <summary>
+ /// Flag to indicate that the receiving consumer should be set up to receive from a destination.
+ /// </summary>
+ /// <return> Flag to indicate that the receiving consumer should be set up to receive from a destination. </return>
+ public bool getReceiverConsumerBind()
+ {
+ return getPropertyAsBoolean(RECEIVER_CONSUMER_BIND_PROPNAME);
+ }
+
+ /// <summary>
+ /// Flag to indicate that the publishing consumer should be created and actively listening.
+ /// </summary>
+ /// <return> Flag to indicate that the publishing consumer should be created. </return>
+ public bool getPublisherConsumerActive()
+ {
+ return getPropertyAsBoolean(PUBLISHER_CONSUMER_ACTIVE_PROPNAME);
+ }
+
+ /// <summary>
+ /// Flag to indicate that the receiving consumers should be created and actively listening.
+ /// </summary>
+ /// <return> Flag to indicate that the receiving consumers should be created and actively listening. </return>
+ public bool getReceiverConsumerActive()
+ {
+ return getPropertyAsBoolean(RECEIVER_CONSUMER_ACTIVE_PROPNAME);
+ }
+
+ /// <summary>
+ /// A root to create all test destination names from.
+ /// </summary>
+ /// <return> A root to create all test destination names from. </return>
+ public string getSendDestinationNameRoot()
+ {
+ return getProperty(SEND_DESTINATION_NAME_ROOT_PROPNAME);
+ }
+
+ /// <summary>
+ /// A root to create all receiving destination names from.
+ /// </summary>
+ /// <return> A root to create all receiving destination names from. </return>
+ public string getReceiveDestinationNameRoot()
+ {
+ return getProperty(RECEIVE_DESTINATION_NAME_ROOT_PROPNAME);
+ }
+
+ /// <summary>
+ /// Flag to indicate that persistent messages should be used.
+ /// </summary>
+ /// <return> Flag to indicate that persistent messages should be used. </return>
+ public bool getPersistentMode()
+ {
+ return getPropertyAsBoolean(PERSISTENT_MODE_PROPNAME);
+ }
+
+ /// <summary>
+ /// Flag to indicate that transactional messages should be sent by the publisher.
+ /// </summary>
+ /// <return> Flag to indicate that transactional messages should be sent by the publisher. </return>
+ public bool getPublisherTransacted()
+ {
+ return getPropertyAsBoolean(TRANSACTED_PUBLISHER_PROPNAME);
+ }
+
+ /// <summary>
+ /// Flag to indicate that transactional receives should be used by the receiver.
+ /// </summary>
+ /// <return> Flag to indicate that transactional receives should be used by the receiver. </return>
+ public bool getReceiverTransacted()
+ {
+ return getPropertyAsBoolean(TRANSACTED_PUBLISHER_PROPNAME);
+ }
+
+ /// <summary>
+ /// The name of the virtual host to run all tests over.
+ /// </summary>
+ /// <return> The name of the virtual host to run all tests over. </return>
+ public string getVirtualHost()
+ {
+ return getProperty(VIRTUAL_HOST_PROPNAME);
+ }
+
+ /// <summary>
+ /// Limiting rate for each sender in messages per second, or zero for unlimited.
+ /// </summary>
+ /// <return> Limiting rate for each sender in messages per second, or zero for unlimited. </return>
+ public string getRate()
+ {
+ return getProperty(RATE_PROPNAME);
+ }
+
+ /// <summary>
+ /// Flag to indicate that test messages should be received publish/subscribe style by all receivers.
+ /// </summary>
+ /// <return> Flag to indicate that test messages should be received publish/subscribe style by all receivers. </return>
+ public bool getPubsub()
+ {
+ return getPropertyAsBoolean(PUBSUB_PROPNAME);
+ }
+
+ /// <summary>
+ /// The username credentials to run tests with.
+ /// </summary>
+ /// <return> The username credentials to run tests with. </return>
+ public string getUsername()
+ {
+ return getProperty(USERNAME_PROPNAME);
+ }
+
+ /// <summary>
+ /// The password credentials to run tests with.
+ /// </summary>
+ /// <return> The password credentials to run tests with. </return>
+ public string getPassword()
+ {
+ return getProperty(PASSWORD_PROPNAME);
+ }
+
+ /// <summary>
+ /// The timeout duration to fail tests on, should they receive no messages within it.
+ /// </summary>
+ /// <return> The timeout duration to fail tests on, should they receive no messages within it. </return>
+ public long getTimeout()
+ {
+ return getPropertyAsLong(TIMEOUT_PROPNAME);
+ }
+
+ /// <summary>
+ /// The number of messages to batch into each transaction in transational tests.
+ /// </summary>
+ /// <return> The number of messages to batch into each transaction in transational tests. </return>
+ public int getTxBatchSize()
+ {
+ return getPropertyAsInteger(TX_BATCH_SIZE_PROPNAME);
+ }
+
+ /// <summary>
+ /// Flag to indicate that tests should use durable destinations.
+ /// </summary>
+ /// <return> Flag to indicate that tests should use durable destinations. </return>
+ public bool getDurableDests()
+ {
+ return getPropertyAsBoolean(DURABLE_DESTS_PROPNAME);
+ }
+
+ /// <summary>
+ /// The ack mode for message receivers to use.
+ /// </summary>
+ /// <return> The ack mode for message receivers to use. </return>
+ public int getAckMode()
+ {
+ return getPropertyAsInteger(ACK_MODE_PROPNAME);
+ }
+
+ /// <summary>
+ /// Flag to indicate that tests should use durable subscriptions.
+ /// </summary>
+ /// <return> Flag to indicate that tests should use durable subscriptions. </return>
+ public bool getDurableSubscription()
+ {
+ return getPropertyAsBoolean(DURABLE_SUBSCRIPTION_PROPNAME);
+ }
+
+ /// <summary>
+ /// The maximum amount of in-flight data, in bytes, that tests should send at any time.
+ /// </summary>
+ /// <return> The maximum amount of in-flight data, in bytes, that tests should send at any time. </return>
+ public int getMaxPending()
+ {
+ return getPropertyAsInteger(MAX_PENDING_PROPNAME);
+ }
+
+ /// <summary>
+ /// The size of the prefetch queue to use.
+ /// </summary>
+ /// <return> The size of the prefetch queue to use. </return>
+ public int getPrefetch()
+ {
+ return getPropertyAsInteger(PREFETCH_PROPNAME);
+ }
+
+ /// <summary>
+ /// Flag to indicate that subscriptions should be no-local.
+ /// </summary>
+ /// <return> Flag to indicate that subscriptions should be no-local. </return>
+ public bool getNoLocal()
+ {
+ return getPropertyAsBoolean(NO_LOCAL_PROPNAME);
+ }
+
+ /// <summary>
+ /// Flag to indicate that subscriptions should be exclusive.
+ /// </summary>
+ /// <return> Flag to indicate that subscriptions should be exclusive. </return>
+ public bool getExclusive()
+ {
+ return getPropertyAsBoolean(EXCLUSIVE_PROPNAME);
+ }
+
+ /// <summary>
+ /// Flag to indicate that messages must be delivered immediately.
+ /// </summary>
+ /// <return> Flag to indicate that messages must be delivered immediately. </return>
+ public bool getImmediate()
+ {
+ return getPropertyAsBoolean(IMMEDIATE_PROPNAME);
+ }
+
+ /// <summary>
+ /// Flag to indicate that messages must be routable.
+ /// </summary>
+ /// <return> Flag to indicate that messages must be routable. </return>
+ public bool getMandatory()
+ {
+ return getPropertyAsBoolean(MANDATORY_PROPNAME);
+ }
+
+ /// <summary>
+ /// Gets the value of a flag to indicate that the publisher should rollback all messages sent.
+ /// </summary>
+ /// <return> A flag to indicate that the publisher should rollback all messages sent. </return>
+ public bool getRollbackPublisher()
+ {
+ return getPropertyAsBoolean(ROLLBACK_PUBLISHER_PROPNAME);
+ }
+
+ /// <summary>
+ /// Gets the value of a flag to indicate that the receiver should rollback all messages received, then receive them
+ /// again.
+ /// </summary>
+ /// <return> A flag to indicate that the publisher should rollback all messages received. </return>
+ public bool getRollbackReceiver()
+ {
+ return getPropertyAsBoolean(ROLLBACK_RECEIVER_PROPNAME);
+ }
+
+ /// <summary>
+ /// Gets the behavioural mode of not applicable assertions. Should be one of 'quiet', 'warn' or 'fail'.
+ /// </summary>
+ /// <return> The behavioural mode of not applicable assertions. </return>
+ public string getNotApplicableAssertionMode()
+ {
+ return getProperty(NOT_APPLICABLE_ASSERTION_PROPNAME);
+ }
+ }
+ */
+} \ No newline at end of file
diff --git a/qpid/dotnet/Qpid.Integration.Tests/framework/TestUtils.csx b/qpid/dotnet/Qpid.Integration.Tests/framework/TestUtils.csx
new file mode 100644
index 0000000000..bb00bf2683
--- /dev/null
+++ b/qpid/dotnet/Qpid.Integration.Tests/framework/TestUtils.csx
@@ -0,0 +1,188 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+using log4net;
+
+using static Apache.Qpid.Integration.Tests.framework.MessagingTestConfigProperties.*;
+
+using uk.co.thebadgerset.junit.extensions.util.ParsedProperties;
+
+using javax.jms.*;
+using javax.naming.Context;
+using javax.naming.InitialContext;
+using javax.naming.NamingException;
+
+using System.Collections.Generic.IDictionary;
+
+namespace Apache.Qpid.Integration.Tests.framework
+{
+ /// <summary>
+ /// TestUtils provides static helper methods that are usefull for writing tests against QPid.
+ ///
+ /// <p/><table id="crc"><caption>CRC Card</caption>
+ /// <tr><th> Responsibilities <th> Collaborations
+ /// <tr><td> Create connections from test properties. <td> <see cref="MessagingTestConfigProperties"/>
+ /// <tr><td> Create test messages.
+ /// <tr><td> Inject a short pause in a test.
+ /// <tr><td> Serialize properties into a message.
+ /// </table>
+ /// </summary>
+ public class TestUtils
+ {
+ /// <summary> Used for debugging. </summary>
+ private static ILog log = LogManager.GetLogger(typeof(TestUtils));
+
+ /// <summary> Some dummy data to stuff all test messages with. </summary>
+ private static final byte[] MESSAGE_DATA_BYTES =
+ "Test Message -- Test Message -- Test Message -- Test Message -- Test Message -- Test Message -- Test Message -- "
+ .getBytes();
+
+ /// <summary>
+ /// Establishes a JMS connection using a set of properties and qpids built in JNDI implementation. This is a simple
+ /// convenience method for code that does not anticipate handling connection failures. All exceptions that indicate
+ /// that the connection has failed, are wrapped as rutime exceptions, presumably handled by a top level failure
+ /// handler.
+ ///
+ /// <p/>This utility makes use of the following test parameters from <see cref="MessagingTestConfigProperties"/> to control
+ /// the connection creation:
+ ///
+ /// <p/><table>
+ /// <tr><td> <see cref="MessagingTestConfigProperties#USERNAME_PROPNAME"/> <td> The username.
+ /// <tr><td> <see cref="MessagingTestConfigProperties#PASSWORD_PROPNAME"/> <td> The password.
+ /// <tr><td> <see cref="MessagingTestConfigProperties#VIRTUAL_HOST_PROPNAME"/> <td> The virtual host name.
+ /// <tr><td> <see cref="MessagingTestConfigProperties#BROKER_PROPNAME"/> <td> The broker URL.
+ /// <tr><td> <see cref="MessagingTestConfigProperties#CONNECTION_NAME"/> <td> The broker name in the initial context.
+ /// </summary>
+ /// <param name="messagingProps"> Connection properties as defined in <see cref="MessagingTestConfigProperties"/>. </param>
+ ///
+ /// <return> A JMS conneciton. </return>
+ public static Connection createConnection(ParsedProperties messagingProps)
+ {
+ log.debug("public static Connection createConnection(ParsedProperties messagingProps = " + messagingProps
+ + "): called");
+
+ try
+ {
+ // Extract the configured connection properties from the test configuration.
+ string conUsername = messagingProps.getProperty(USERNAME_PROPNAME);
+ string conPassword = messagingProps.getProperty(PASSWORD_PROPNAME);
+ string virtualHost = messagingProps.getProperty(VIRTUAL_HOST_PROPNAME);
+ string brokerUrl = messagingProps.getProperty(BROKER_PROPNAME);
+
+ // Create the broker connection url.
+ string connectionstring =
+ "amqp://" + conUsername + ":" + conPassword + "@clientid/" + ((virtualHost != null) ? virtualHost : "")
+ + "?brokerlist='" + brokerUrl + "'";
+
+ // Create properties to create the initial context from, and inject the connection factory configuration
+ // for the defined connection name into it.
+ messagingProps.setProperty("connectionfactory." + CONNECTION_NAME, connectionString);
+
+ Context ctx = new InitialContext(messagingProps);
+
+ ConnectionFactory cf = (ConnectionFactory) ctx.lookup(CONNECTION_NAME);
+
+ return cf.createConnection();
+ }
+ catch (NamingException e)
+ {
+ throw new RuntimeException("Got JNDI NamingException whilst looking up the connection factory.", e);
+ }
+ catch (JMSException e)
+ {
+ throw new RuntimeException("Could not establish connection due to JMSException.", e);
+ }
+ }
+
+ /// <summary>
+ /// Creates a test message of the specified size, on the given JMS session.
+ /// </summary>
+ /// <param name="session"> The JMS session. </param>
+ /// <param name="size"> The size of the message in bytes. </param>
+ ///
+ /// <return> A bytes message, of the specified size, filled with dummy data. </return>
+ ///
+ /// <exception cref="JMSException"> Any underlying JMSExceptions are allowed to fall through. </exception>
+ public static Message createTestMessageOfSize(Session session, int size) throws JMSException
+ {
+ BytesMessage message = session.createBytesMessage();
+
+ if (size > 0)
+ {
+ int div = MESSAGE_DATA_BYTES.length / size;
+ int mod = MESSAGE_DATA_BYTES.length % size;
+
+ for (int i = 0; i < div; i++)
+ {
+ message.writeBytes(MESSAGE_DATA_BYTES);
+ }
+
+ if (mod != 0)
+ {
+ message.writeBytes(MESSAGE_DATA_BYTES, 0, mod);
+ }
+ }
+
+ return message;
+ }
+
+ /// <summary>
+ /// Pauses for the specified length of time. In the event of failing to pause for at least that length of time
+ /// due to interuption of the thread, a RutimeException is raised to indicate the failure. The interupted status
+ /// of the thread is restores in that case. This method should only be used when it is expected that the pause
+ /// will be succesfull, for example in test code that relies on inejecting a pause.
+ /// </summary>
+ /// <param name="t"> The minimum time to pause for in milliseconds. </param>
+ public static void pause(long t)
+ {
+ try
+ {
+ Thread.sleep(t);
+ }
+ catch (InterruptedException e)
+ {
+ // Restore the interrupted status
+ Thread.currentThread().interrupt();
+
+ throw new RuntimeException("Failed to generate the requested pause length.", e);
+ }
+ }
+
+ /// <summary>
+ /// Sets properties of different types on a JMS Message.
+ /// </summary>
+ /// <param name="message"> The message to set properties on. </param>
+ /// <param name="properties"> The property name/value pairs to set. </param>
+ ///
+ /// <exception cref="javax.jms.JMSException"> All underlying JMSExceptions are allowed to fall through. </exception>
+ ///
+ /// <remarks> Move this helper method somewhere else. For example, TestUtils.</remarks>
+ public static void setPropertiesOnMessage(Message message, Map<Object, Object> properties) throws JMSException
+ {
+ for (Map.Entry<Object, Object> entry : properties.entrySet())
+ {
+ string name = entry.getKey().ToString();
+ Object value = entry.getValue();
+
+ message.setObjectProperty(name, value);
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/qpid/dotnet/Qpid.Integration.Tests/framework/alljava.csx b/qpid/dotnet/Qpid.Integration.Tests/framework/alljava.csx
new file mode 100644
index 0000000000..23ebd53a5b
--- /dev/null
+++ b/qpid/dotnet/Qpid.Integration.Tests/framework/alljava.csx
@@ -0,0 +1,7851 @@
+/*
+ *
+ * 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.
+ *
+ */
+namespace Apache.Qpid.Integration.Tests.framework
+{
+ /// <summary>
+ /// Assertion models an assertion on a test <see cref="Circuit"/>.
+ ///
+ /// <p/><table id="crc"><caption>CRC Card</caption>
+ /// <tr><th> Responsibilities
+ /// <tr><td> Indicate whether or not the assertion passes when applied.
+ /// </table>
+ /// </summary>
+ public interface Assertion
+ {
+ /// <summary>
+ /// Applies the assertion.
+ /// </summary>
+ /// <return> <tt>true</tt> if the assertion passes, <tt>false</tt> if it fails. </return>
+ public bool apply();
+ }
+}
+/*
+ *
+ * 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.
+ *
+ */
+using System.Collections.Generic.LinkedList;
+using System.Collections.Generic.IList;
+
+namespace Apache.Qpid.Integration.Tests.framework
+{
+ /// <summary>
+ /// AssertionBase is a base class for implenmenting assertions. It provides a mechanism to store error messages, and
+ /// report all error messages when its <see cref="#ToString()"/> method is called.
+ ///
+ /// <p/><table id="crc"><caption>CRC Card</caption>
+ /// <tr><th> Responsibilities <th> Collaborations
+ /// <tr><td> Collect error messages.
+ /// </table>
+ /// </summary>
+ public abstract class AssertionBase : Assertion
+ {
+ /// <summary> Holds the error messages. </summary>
+ IList<String> errors = new LinkedList<String>();
+
+ /// <summary>
+ /// Adds an error message to the assertion.
+ /// </summary>
+ /// <param name="error"> An error message to add to the assertion. </param>
+ public void addError(string error)
+ {
+ errors.add(error);
+ }
+
+ /// <summary>
+ /// Prints all of the error messages in the assertion into a string.
+ /// </summary>
+ /// <return> All of the error messages in the assertion as a string. </return>
+ public string ToString()
+ {
+ string result = "";
+
+ for (string error : errors)
+ {
+ result += error;
+ }
+
+ return result;
+ }
+ }
+}
+/*
+ *
+ * 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.
+ *
+ */
+namespace Apache.Qpid.Integration.Tests.framework
+{
+ /// <summary>
+ /// BrokerLifecycleAware is an awareness interface implemented by test cases that can run control the life-cycle of
+ /// the brokers on which they run. Its purpose is to expose additional instrumentation of brokers during testing, that
+ /// enables tests to use an automated failure mechanism to simulate broker failures, and to re-start failed brokers.
+ ///
+ /// <p/><table id="crc"><caption>CRC Card</caption>
+ /// <tr><th> Responsibilities <th> Collaborations
+ /// <tr><td> Indicate whether or not a test case is using an in-vm broker.
+ /// <tr><td> Track which in-vm broker is currently in use.
+ /// <tr><td> Accept setting of a failure mechanism. <td> <see cref="CauseFailure"/>.
+ /// </table>
+ /// </summary>
+ ///
+ /// <remarks> Need to think about how to present the brokers through this interface. Thinking numbering the available
+ /// brokers from 1 will do. Then can kill 1 and assume failing onto 2. Restart 1 and kill 2 and fail back onto
+ /// 1 again? </remarks>
+ public interface BrokerLifecycleAware
+ {
+ public void setInVmBrokers();
+
+ /// <summary>
+ /// Indicates whether or not a test case is using in-vm brokers.
+ /// </summary>
+ /// <return> <tt>true</tt> if the test is using in-vm brokers, <tt>false</tt> otherwise. </return>
+ public bool usingInVmBroker();
+
+ /// <summary>
+ /// Sets the currently live in-vm broker.
+ /// </summary>
+ /// <param name="i"> The currently live in-vm broker. </param>
+ public void setLiveBroker(int i);
+
+ /// <summary>
+ /// Reports the currently live in-vm broker.
+ /// </summary>
+ /// <return> The currently live in-vm broker. </return>
+ public int getLiveBroker();
+
+ /// <summary>
+ /// Accepts a failure mechanism.
+ /// </summary>
+ /// <param name="failureMechanism"> The failure mechanism. </param>
+ public void setFailureMechanism(CauseFailure failureMechanism);
+ }
+}
+/*
+ *
+ * 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.
+ *
+ */
+namespace Apache.Qpid.Integration.Tests.framework
+{
+ /// <summary>
+ /// CauseFailure provides a method to cause a failure in a messaging broker, usually used in conjunction with fail-over
+ /// or other failure mode testing. In some cases failures may be automated, for example by shutting down an in-vm broker,
+ /// or by sending a special control signal to a broker over a network connection. In other cases, it may be preferable
+ /// to ask a user interactively to cause a failure scenario, in which case an implementation may display a prompt or
+ /// dialog box asking for notification once the failure has been caused. The purpose of this interface is to abstract
+ /// the exact cause and nature of a failure out of failure test cases.
+ ///
+ /// <p/><table id="crc"><caption>CRC Card</caption>
+ /// <tr><th> Responsibilities
+ /// <tr><td> Cause messaging broker failure.
+ /// </table>
+ /// </summary>
+ public interface CauseFailure
+ {
+ /// <summary> Causes the active message broker to fail. </summary>
+ void causeFailure();
+ }
+}
+/*
+ *
+ * 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.
+ *
+ */
+using Apache.Qpid.Integration.Tests.framework.CauseFailure;
+
+using java.io.IOException;
+
+namespace Apache.Qpid.Integration.Tests.framework
+{
+ /// <summary>
+ /// Causes a message broker failure by interactively prompting the user to cause it.
+ ///
+ /// <p/><table id="crc"><caption>CRC Card</caption>
+ /// <tr><th> Responsibilities <th> Collaborations
+ /// <tr><td> Cause messaging broker failure.
+ /// </table>
+ /// </summary>
+ public class CauseFailureUserPrompt : CauseFailure
+ {
+ /// <summary> Causes the active message broker to fail.</summary>
+ public void causeFailure()
+ {
+ waitForUser("Cause a broker failure now, then press Return.");
+ }
+
+ /// <summary>
+ /// Outputs a prompt to the console and waits for the user to press return.
+ /// </summary>
+ /// <param name="prompt"> The prompt to display on the console. </param>
+ private void waitForUser(string prompt)
+ {
+ System.out.println(prompt);
+
+ try
+ {
+ System.in.read();
+ }
+ catch (IOException e)
+ {
+ // Ignored.
+ }
+
+ System.out.println("Continuing.");
+ }
+ }
+}
+/*
+ *
+ * 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.
+ *
+ */
+using System.Collections.Generic.IList;
+
+namespace Apache.Qpid.Integration.Tests.framework
+{
+ /// <summary>
+ /// A Circuit is the basic test unit against which test cases are to be written. A circuit consists of two 'ends', an
+ /// instigating 'publisher' end and a more passive 'receivers' end.
+ ///
+ /// <p/>Once created, the life-cycle of a circuit may be controlled by <see cref="#start()"/>ing it, or <see cref="#close()"/>ing it.
+ /// Once started, the circuit is ready to send messages over. Once closed the circuit can no longer be used.
+ ///
+ /// <p/>The state of the circuit may be taken with the <see cref="#check()"/> method, and asserted against by the
+ /// <see cref="#applyAssertions(System.Collections.Generic.IList)"/> method.
+ ///
+ /// <p/>There is a default test procedure which may be performed against the circuit. The outline of this procedure is:
+ ///
+ /// <p/><pre>
+ /// Start the circuit.
+ /// Send test messages.
+ /// Request a status report.
+ /// Assert conditions on the publishing end of the circuit.
+ /// Assert conditions on the receiving end of the circuit.
+ /// Close the circuit.
+ /// Pass with no failed assertions or fail with a list of failed assertions.
+ /// </pre>
+ ///
+ /// <p/><table id="crc"><caption>CRC Card</caption>
+ /// <tr><th> Responsibilities
+ /// <tr><td> Supply the publishing and receiving ends of a test messaging circuit.
+ /// <tr><td> Start the circuit running.
+ /// <tr><td> Close the circuit down.
+ /// <tr><td> Take a reading of the circuits state.
+ /// <tr><td> Apply assertions against the circuits state.
+ /// <tr><td> Send test messages over the circuit.
+ /// <tr><td> Perform the default test procedue on the circuit.
+ /// </table>
+ /// </summary>
+ public interface Circuit
+ {
+ /// <summary>
+ /// Gets the interface on the publishing end of the circuit.
+ /// </summary>
+ /// <return> The publishing end of the circuit. </return>
+ public Publisher getPublisher();
+
+ /// <summary>
+ /// Gets the interface on the receiving end of the circuit.
+ /// </summary>
+ /// <return> The receiving end of the circuit. </return>
+ public Receiver getReceiver();
+
+ /// <summary>
+ /// Connects and starts the circuit. After this method is called the circuit is ready to send messages.
+ public void start();
+
+ /// <summary>
+ /// Checks the test circuit. The effect of this is to gather the circuits state, for both ends of the circuit,
+ /// into a report, against which assertions may be checked.
+ public void check();
+
+ /// <summary>
+ /// Closes the circuit. All associated resources are closed.
+ public void close();
+
+ /// <summary>
+ /// Applied a list of assertions against the test circuit. The <see cref="#check()"/> method should be called before doing
+ /// this, to ensure that the circuit has gathered its state into a report to assert against.
+ /// </summary>
+ /// <param name="assertions"> The list of assertions to apply to the circuit. </param>
+ ///
+ /// <return> Any assertions that failed. </return>
+ public IList<Assertion> applyAssertions(List<Assertion> assertions);
+
+ /// <summary>
+ /// Runs the default test procedure against the circuit, and checks that all of the specified assertions hold.
+ /// </summary>
+ /// <param name="numMessages"> The number of messages to send using the default test procedure. </param>
+ /// <param name="assertions"> The list of assertions to apply. </param>
+ ///
+ /// <return> Any assertions that failed. </return>
+ public IList<Assertion> test(int numMessages, List<Assertion> assertions);
+ }
+}
+/*
+ *
+ * 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.
+ *
+ */
+using javax.jms.*;
+
+namespace Apache.Qpid.Integration.Tests.framework
+{
+ /// <summary>
+ /// A CircuitEnd is a pair consisting of one message producer and one message consumer, that represents one end of a
+ /// test circuit. It is a standard unit of connectivity allowing a full-duplex conversation to be held, provided both
+ /// the consumer and producer are instantiated and configured.
+ ///
+ /// <p/><table id="crc"><caption>CRC Card</caption>
+ /// <tr><th> Responsibilities
+ /// <tr><td> Provide a message producer for sending messages.
+ /// <tr><td> Provide a message consumer for receiving messages.
+ /// </table>
+ /// </summary>
+ ///
+ /// <remarks> Update the <see cref="org.apache.qpid.util.ConversationFactory"/> so that it accepts these as the basic conversation
+ /// connection units.</remarks>
+ public interface CircuitEnd
+ {
+ /// <summary>
+ /// Gets the message producer at this circuit end point.
+ /// </summary>
+ /// <return> The message producer at with this circuit end point. </return>
+ public MessageProducer getProducer();
+
+ /// <summary>
+ /// Gets the message consumer at this circuit end point.
+ /// </summary>
+ /// <return> The message consumer at this circuit end point. </return>
+ public MessageConsumer getConsumer();
+
+ /// <summary>
+ /// Send the specified message over the producer at this end point.
+ /// </summary>
+ /// <param name="message"> The message to send. </param>
+ ///
+ /// <exception cref="JMSException"> Any JMS exception occuring during the send is allowed to fall through. </exception>
+ public void send(Message message) throws JMSException;
+
+ /// <summary>
+ /// Gets the JMS Session associated with this circuit end point.
+ /// </summary>
+ /// <return> The JMS Session associated with this circuit end point. </return>
+ public Session getSession();
+
+ /// <summary>
+ /// Closes the message producers and consumers and the sessions, associated with this circuit end point.
+ /// </summary>
+ /// <exception cref="JMSException"> Any JMSExceptions occurring during the close are allowed to fall through. </exception>
+ public void close() throws JMSException;
+
+ /// <summary>
+ /// Returns the message monitor for reporting on received messages on this circuit end.
+ /// </summary>
+ /// <return> The message monitor for this circuit end. </return>
+ public MessageMonitor getMessageMonitor();
+
+ /// <summary>
+ /// Returns the exception monitor for reporting on exceptions received on this circuit end.
+ /// </summary>
+ /// <return> The exception monitor for this circuit end. </return>
+ public ExceptionMonitor getExceptionMonitor();
+ }
+}
+/*
+ *
+ * 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.
+ *
+ */
+using javax.jms.*;
+
+namespace Apache.Qpid.Integration.Tests.framework
+{
+ /// <summary>
+ /// A CircuitEndBase is a pair consisting of one message producer and one message consumer, that represents one end of a
+ /// test circuit. It is a standard unit of connectivity allowing a full-duplex conversation to be held, provided both
+ /// the consumer and producer are instantiated and configured.
+ ///
+ /// <p/><table id="crc"><caption>CRC Card</caption>
+ /// <tr><th> Responsibilities
+ /// <tr><td> Provide a message producer for sending messages.
+ /// <tr><td> Provide a message consumer for receiving messages.
+ /// </table>
+ /// </summary>
+ public class CircuitEndBase : CircuitEnd
+ {
+ /// <summary> Holds the single message producer. </summary>
+ MessageProducer producer;
+
+ /// <summary> Holds the single message consumer. </summary>
+ MessageConsumer consumer;
+
+ /// <summary> Holds the controlSession for the circuit end. </summary>
+ Session session;
+
+ /// <summary> Holds the message monitor for the circuit end. </summary>
+ MessageMonitor messageMonitor;
+
+ /// <summary> Holds the exception monitor for the circuit end. </summary>
+ ExceptionMonitor exceptionMonitor;
+
+ /// <summary>
+ /// Creates a circuit end point on the specified producer, consumer and controlSession. Monitors are also configured
+ /// for messages and exceptions received by the circuit end.
+ /// </summary>
+ /// <param name="producer"> The message producer for the circuit end point. </param>
+ /// <param name="consumer"> The message consumer for the circuit end point. </param>
+ /// <param name="session"> The controlSession for the circuit end point. </param>
+ /// <param name="messageMonitor"> The monitor to notify of all messages received by the circuit end. </param>
+ /// <param name="exceptionMonitor"> The monitor to notify of all exceptions received by the circuit end. </param>
+ public CircuitEndBase(MessageProducer producer, MessageConsumer consumer, Session session, MessageMonitor messageMonitor,
+ ExceptionMonitor exceptionMonitor)
+ {
+ this.producer = producer;
+ this.consumer = consumer;
+ this.session = session;
+
+ this.messageMonitor = messageMonitor;
+ this.exceptionMonitor = exceptionMonitor;
+ }
+
+ /// <summary>
+ /// Gets the message producer at this circuit end point.
+ /// </summary>
+ /// <return> The message producer at with this circuit end point. </return>
+ public MessageProducer getProducer()
+ {
+ return producer;
+ }
+
+ /// <summary>
+ /// Gets the message consumer at this circuit end point.
+ /// </summary>
+ /// <return> The message consumer at this circuit end point. </return>
+ public MessageConsumer getConsumer()
+ {
+ return consumer;
+ }
+
+ /// <summary>
+ /// Send the specified message over the producer at this end point.
+ /// </summary>
+ /// <param name="message"> The message to send. </param>
+ /// <exception cref="javax.jms.JMSException"> Any JMS exception occuring during the send is allowed to fall through. </exception>
+ public void send(Message message) throws JMSException
+ {
+ producer.send(message);
+ }
+
+ /// <summary>
+ /// Gets the JMS Session associated with this circuit end point.
+ /// </summary>
+ /// <return> The JMS Session associated with this circuit end point. </return>
+ public Session getSession()
+ {
+ return session;
+ }
+
+ /// <summary>
+ /// Closes the message producers and consumers and the sessions, associated with this circuit end point.
+ /// </summary>
+ /// <exception cref="javax.jms.JMSException"> Any JMSExceptions occurring during the close are allowed to fall through. </exception>
+ public void close() throws JMSException
+ {
+ if (producer != null)
+ {
+ producer.close();
+ }
+
+ if (consumer != null)
+ {
+ consumer.close();
+ }
+ }
+
+ /// <summary>
+ /// Returns the message monitor for reporting on received messages on this circuit end.
+ /// </summary>
+ /// <return> The message monitor for this circuit end. </return>
+ public MessageMonitor getMessageMonitor()
+ {
+ return messageMonitor;
+ }
+
+ /// <summary>
+ /// Returns the exception monitor for reporting on exceptions received on this circuit end.
+ /// </summary>
+ /// <return> The exception monitor for this circuit end. </return>
+ public ExceptionMonitor getExceptionMonitor()
+ {
+ return exceptionMonitor;
+ }
+ }
+}
+/*
+ *
+ * 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.
+ *
+ */
+namespace Apache.Qpid.Integration.Tests.framework.clocksynch
+{
+ /// <summary>
+ /// ClockSynchFailureException represents failure of a <see cref="ClockSynchronizer"/> to achieve synchronization. For example,
+ /// this could be because a reference signal is not available, or because a desired accurracy cannot be attained.
+ ///
+ /// <p/><table id="crc"><caption>CRC Card</caption>
+ /// <tr><th> Responsibilities <th> Collaborations
+ /// <tr><td> Represent failure to achieve synchronization.
+ /// </table>
+ /// </summary>
+ public class ClockSynchFailureException extends Exception
+ {
+ /// <summary>
+ /// Creates a clock synch failure exception.
+ /// </summary>
+ /// <param name="message"> The detail message (which is saved for later retrieval by the <see cref="#getMessage()"/> method). </param>
+ /// <param name="cause"> The cause (which is saved for later retrieval by the <see cref="#getCause()"/> method). (A <tt>null</tt>
+ /// value is permitted, and indicates that the cause is nonexistent or unknown.)</param>
+ public ClockSynchFailureException(string message, Throwable cause)
+ {
+ super(message, cause);
+ }
+ }
+}
+/*
+ *
+ * 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.
+ *
+ */
+namespace Apache.Qpid.Integration.Tests.framework.clocksynch
+{
+ /// <summary>
+ /// ClockSynchronizer provides an interface through which two nodes may synchronize their clocks. It is expected that one
+ /// node will act as the reference clock, to which no delta need be applied, and the other node will act as the slave,
+ /// and which must apply a delta to its local clock to get a clock synchronized with the reference.
+ ///
+ /// <p/>The slave side will initiate the computation of a clock delta by calling the <see cref="#synch"/> method. This method
+ /// will not return until the delta has been computed, at which point there is a method to return its value, as well as
+ /// an estimate of the likely error (usually one standard deviation), in the synchronization. For convenience there is a
+ /// <see cref="#nanoTime"/> method to return the value of System.nanoTime() with the delta added in.
+ ///
+ /// <p/><table id="crc"><caption>CRC Card</caption>
+ /// <tr><th> Responsibilities <th> Collaborations
+ /// <tr><td> Trigger a clock synchronization.
+ /// <tr><td> Compute a clock delta to apply to the local clock.
+ /// <tr><td> Estimate the error in the synchronzation.
+ /// </table>
+ /// </summary>
+ public interface ClockSynchronizer
+ {
+ /// <summary>
+ /// The slave side should call this to copute a clock delta with the reference.
+ /// </summary>
+ /// <exception cref="ClockSynchFailureException"> If synchronization cannot be achieved. </exception>
+ public void synch() throws ClockSynchFailureException;
+
+ /// <summary>
+ /// Gets the clock delta in nano seconds.
+ /// </summary>
+ /// <return> The clock delta in nano seconds. </return>
+ public long getDelta();
+
+ /// <summary>
+ /// Gets an estimate of the clock error in nan seconds.
+ /// </summary>
+ /// <return> An estimate of the clock error in nan seconds. </return>
+ public long getEpsilon();
+
+ /// <summary>
+ /// Gets the local clock time with any computed delta added in.
+ /// </summary>
+ /// <return> The local clock time with any computed delta added in. </return>
+ public long nanoTime();
+ }
+}
+/*
+ *
+ * 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.
+ *
+ */
+using log4net;
+
+using uk.co.thebadgerset.junit.extensions.ShutdownHookable;
+using uk.co.thebadgerset.junit.extensions.Throttle;
+
+namespace Apache.Qpid.Integration.Tests.framework.clocksynch
+{
+ /// <summary>
+ /// ClockSynchThread is a convenient utility for running a thread that periodically synchronizes the clock against
+ /// a reference. Supply it with a <see cref="ClockSynchronizer"/> and a <see cref="Throttle"/> and it will continually keep the
+ /// clock up-to-date at a rate determined by the throttle.
+ ///
+ /// <p/><table id="crc"><caption>CRC Card</caption>
+ /// <tr><th> Responsibilities <th> Collaborations
+ /// <tr><td> Continually sychronize the clock at a throttled rate.
+ /// </table>
+ /// </summary>
+ public class ClockSynchThread extends Thread : ShutdownHookable
+ {
+ /// <summary> Used for debugging. </summary>
+ private static ILog log = LogManager.GetLogger(typeof(ClockSynchThread));
+
+ /// <summary> Holds the clock syncher for the synch thread. </summary>
+ private ClockSynchronizer clockSyncher;
+
+ /// <summary> Holds the throttle to limit the synch rate. </summary>
+ private Throttle throttle;
+
+ /// <summary> Flag to indicate that the periodic clock syncher should keep running. </summary>
+ bool doSynch = true;
+
+ /// <summary>
+ /// Creates a clock synchronizer thread from a clock synchronizer and a throttle.
+ /// </summary>
+ /// <param name="syncher"> The clock synchronizer. </param>
+ /// <param name="throttle"> The throttle. </param>
+ public ClockSynchThread(ClockSynchronizer syncher, Throttle throttle)
+ {
+ this.clockSyncher = syncher;
+ this.throttle = throttle;
+ }
+
+ /// <summary> Terminates the synchronization thread. </summary>
+ public void terminate()
+ {
+ doSynch = false;
+ }
+
+ /// <summary> Continually updates the clock, until <see cref="#terminate()"/> is called. </summary>
+ public void run()
+ {
+ while (doSynch)
+ {
+ // Perform a clock clockSynch.
+ try
+ {
+ // Wait controlled by the throttle before doing the next synch.
+ throttle.throttle();
+
+ clockSyncher.synch();
+ log.debug("Clock synched, delta = " + clockSyncher.getDelta() + ", epsilon = " + clockSyncher.getEpsilon()
+ + ".");
+ }
+ // Terminate the synch thread if the synchronization cannot be achieved.
+ catch (ClockSynchFailureException e)
+ {
+ log.debug("Cannot synchronize the clock (reference service may be down). Terminating the synch thread.");
+ doSynch = false;
+ }
+ }
+ }
+
+ /// <summary>
+ /// Gets the clock synchronizer that is kept continually up to date.
+ /// </summary>
+ /// <return> The clock synchronizer that is kept continually up to date. </return>
+ public ClockSynchronizer getClockSyncher()
+ {
+ return clockSyncher;
+ }
+
+ /// <summary>
+ /// Supplies a shutdown hook, that terminates the synching thread.
+ /// </summary>
+ /// <return> The shut down hook. </return>
+ public Thread getShutdownHook()
+ {
+ return new Thread(new Runnable()
+ {
+ public void run()
+ {
+ doSynch = false;
+ }
+ });
+ }
+ }
+}
+/*
+ *
+ * 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.
+ *
+ */
+namespace Apache.Qpid.Integration.Tests.framework.clocksynch
+{
+
+ /// <summary>
+ /// LocalClockSynchronizer is a fake <see cref="ClockSynchronizer"/> that simply calls System.nanoTime(). It exists so that
+ /// the same tests can be run distributed or locally, taking timings against the ClockSynchronizer interface without
+ /// being aware of how they are being run.
+ ///
+ /// <p/><table id="crc"><caption>CRC Card</caption>
+ /// <tr><th> Responsibilities <th> Collaborations
+ /// <tr><td> Supply the local clock with no delta.
+ /// </table>
+ /// </summary>
+ public class LocalClockSynchronizer : ClockSynchronizer
+ {
+ /// <summary>
+ /// The slave side should call this to copute a clock delta with the reference.
+ /// </summary>
+ /// <exception cref="Apache.Qpid.Integration.Tests.framework.clocksynch.ClockSynchFailureException"> If synchronization cannot be achieved. </exception>
+ public void synch() throws ClockSynchFailureException
+ { }
+
+ /// <summary>
+ /// Gets the clock delta in nano seconds.
+ /// </summary>
+ /// <return> The clock delta in nano seconds. </return>
+ public long getDelta()
+ {
+ return 0L;
+ }
+
+ /// <summary>
+ /// Gets an estimate of the clock error in nan seconds.
+ /// </summary>
+ /// <return> An estimate of the clock error in nan seconds. </return>
+ public long getEpsilon()
+ {
+ return 0L;
+ }
+
+ /// <summary>
+ /// Gets the local clock time with any computed delta added in.
+ /// </summary>
+ /// <return> The local clock time with any computed delta added in. </return>
+ public long nanoTime()
+ {
+ return System.nanoTime();
+ }
+ }
+}
+/*
+ *
+ * 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.
+ *
+ */
+using log4net;
+
+using uk.co.thebadgerset.junit.extensions.ShutdownHookable;
+
+using java.io.IOException;
+using java.net.*;
+using java.nio.ByteBuffer;
+
+namespace Apache.Qpid.Integration.Tests.framework.clocksynch
+{
+ /// <summary>
+ /// UDPClockReference supplies a refernce clock signal (generated from System.nanoTime()).
+ ///
+ /// <p/><table id="crc"><caption>CRC Card</caption>
+ /// <tr><th> Responsibilities <th> Collaborations
+ /// <tr><td> Supply a reference clock signal.
+ /// </table>
+ /// </summary>
+ ///
+ /// <remarks> Port hard coded. Make configurable.</remarks>
+ ///
+ /// <remarks> Errors rethrown as runtimes, or silently terminate the service. Could add better error handling if needed.</remarks>
+ public class UDPClockReference : Runnable, ShutdownHookable
+ {
+ /// <summary> Used for debugging. </summary>
+ // private static ILog log = LogManager.GetLogger(typeof(UDPClockReference));
+
+ /// <summary> Defines the timeout to use when polling the socket for time requests. </summary>
+ private static final int TIMEOUT = 200;
+
+ /// <summary> Defines the port to run the clock reference on. </summary>
+ public static final int REFERENCE_PORT = 4444;
+
+ /// <summary> Holds the socket to receive clock reference requests on. </summary>
+ protected DatagramSocket socket = null;
+
+ /// <summary> Flag used to indicate that the time server should keep running. Set to false to terminate. </summary>
+ protected bool publish = true;
+
+ /// <summary> Creates a clock reference service on the standard port. </summary>
+ public UDPClockReference()
+ {
+ try
+ {
+ socket = new DatagramSocket(REFERENCE_PORT);
+ socket.setSoTimeout(TIMEOUT);
+ }
+ catch (SocketException e)
+ {
+ throw new RuntimeException(e);
+ }
+ }
+
+ /// <summary>
+ /// Implements the run loop for this reference time server. This waits for incoming time requests, and replies to
+ /// any, with a message with the local time stamp in it. Periodically (controlled by <see cref="#TIMEOUT"/>), the run
+ /// loop will check if the <see cref="#publish"/> flag has been cleared, and terminate the reference time service if so.
+ /// </summary>
+ public void run()
+ {
+ byte[] buf = new byte[256];
+ ByteBuffer bbuf = ByteBuffer.wrap(buf);
+
+ while (publish)
+ {
+ try
+ {
+ // Wait for a reference time request.
+ DatagramPacket packet = new DatagramPacket(buf, buf.length);
+ bool timedOut = false;
+
+ try
+ {
+ socket.receive(packet);
+ }
+ catch (SocketTimeoutException e)
+ {
+ timedOut = true;
+ }
+
+ if (!timedOut)
+ {
+ // Work out from the received packet, where to reply to.
+ InetAddress address = packet.getAddress();
+ int port = packet.getPort();
+
+ // Respond to the time request by sending back the local clock as the reference time.
+ bbuf.putLong(System.nanoTime());
+ bbuf.flip();
+ packet = new DatagramPacket(bbuf.array(), bbuf.capacity(), address, port);
+
+ socket.send(packet);
+ }
+ }
+ catch (IOException e)
+ {
+ publish = false;
+ }
+ }
+
+ socket.close();
+ }
+
+ /// <summary>
+ /// Supplies a shutdown hook.
+ /// </summary>
+ /// <return> The shut down hook. </return>
+ public Thread getShutdownHook()
+ {
+ return new Thread(new Runnable()
+ {
+ public void run()
+ {
+ publish = false;
+ }
+ });
+ }
+
+ /// <summary>
+ /// For testing purposes. Runs a reference clock on the default port.
+ /// </summary>
+ /// <param name="args"> None. </param>
+ public static void main(String[] args)
+ {
+ try
+ {
+ // Create the clock reference service.
+ UDPClockReference clock = new UDPClockReference();
+
+ // Set up a shutdown hook for it.
+ Runtime.getRuntime().addShutdownHook(clock.getShutdownHook());
+
+ // Start the service.
+ clock.run();
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ System.exit(1);
+ }
+ }
+ }
+}
+/*
+ *
+ * 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.
+ *
+ */
+using log4net;
+
+using uk.co.thebadgerset.junit.extensions.util.CommandLineParser;
+using uk.co.thebadgerset.junit.extensions.util.ParsedProperties;
+
+using java.io.IOException;
+using java.net.*;
+using java.nio.ByteBuffer;
+using java.util.Arrays;
+
+namespace Apache.Qpid.Integration.Tests.framework.clocksynch
+{
+ /// <summary>
+ /// UDPClockSynchronizer is a <see cref="ClockSynchronizer"/> that sends pings as UDP datagrams, and uses the following simple
+ /// algorithm to perform clock synchronization:
+ ///
+ /// <ol>
+ /// <li>Slave initiates synchronization with a Reference clock.</li>
+ /// <li>Slave stamps current local time on a "time request" message and sends to the Reference.</li>
+ /// <li>Upon receipt by Reference, Reference stamps Reference-time and returns.</li>
+ /// <li>Upon receipt by Slave, Slave subtracts current time from sent time and divides by two to compute latency. It
+ /// subtracts current time from Reference time to determine Slave-Reference time delta and adds in the
+ /// half-latency to get the correct clock delta.</li>
+ /// <li>The first result is immediately used to update the clock since it will get the local clock into at least
+ /// the right ballpark.</li>
+ /// <li>The Slave repeats steps 2 through 4, 15 more times.</li>
+ /// <li>The results of the packet receipts are accumulated and sorted in lowest-latency to highest-latency order. The
+ /// median latency is determined by picking the mid-point sample from this ordered list.</li>
+ /// <li>All samples outside 1 standard-deviation from the median are discarded and the remaining samples
+ /// are averaged using an arithmetic mean.</li>
+ /// </ol>
+ ///
+ /// <p/>The use of UDP datagrams, instead of TCP based communication eliminates the hidden delays that TCP can introduce,
+ /// as it can transparently re-order or re-send packets, or introduce delays as packets are naggled.
+ ///
+ /// <p/><table id="crc"><caption>CRC Card</caption>
+ /// <tr><th> Responsibilities <th> Collaborations
+ /// <tr><td> Trigger a clock synchronziation.
+ /// <tr><td> Compute a clock delta to apply to the local clock.
+ /// <tr><td> Estimate the error in the synchronzation.
+ /// </table>
+ /// </summary>
+ public class UDPClockSynchronizer : ClockSynchronizer
+ {
+ /// <summary> Used for debugging. </summary>
+ // private static ILog log = LogManager.GetLogger(typeof(UDPClockSynchronizer));
+
+ /// <summary> Defines the timeout to use when waiting for responses to time requests. </summary>
+ private static final int TIMEOUT = 50;
+
+ /// <summary> The clock delta. </summary>
+ private long delta = 0L;
+
+ /// <summary> Holds an estimate of the clock error relative to the reference clock. </summary>
+ private long epsilon = 0L;
+
+ /// <summary> Holds the address of the reference clock. </summary>
+ private InetAddress referenceAddress;
+
+ /// <summary> Holds the socket to communicate with the reference service over. </summary>
+ private DatagramSocket socket;
+
+ /// <summary> Used to control the shutdown in the main test loop. </summary>
+ private static bool doSynch = true;
+
+ /// <summary>
+ /// Creates a clock synchronizer against the specified address for the reference.
+ /// </summary>
+ /// <param name="address"> The address of the reference service. </param>
+ public UDPClockSynchronizer(string address)
+ {
+ try
+ {
+ referenceAddress = InetAddress.getByName(address);
+ }
+ catch (UnknownHostException e)
+ {
+ throw new RuntimeException(e);
+ }
+ }
+
+ /// <summary>
+ /// The slave side should call this to compute a clock delta with the reference.
+ /// </summary>
+ /// <exception cref="ClockSynchFailureException"> If synchronization cannot be achieved, due to unavailability of the reference
+ /// time service. </exception>
+ public void synch() throws ClockSynchFailureException
+ {
+ try
+ {
+ socket = new DatagramSocket();
+ socket.setSoTimeout(TIMEOUT);
+
+ // Synchronize on a single ping, to get the clock into the right ball-park.
+ synch(1);
+
+ // Synchronize on 15 pings.
+ synch(15);
+
+ // And again, for greater accuracy, on 31.
+ synch(31);
+
+ socket.close();
+ }
+ catch (SocketException e)
+ {
+ throw new RuntimeException(e);
+ }
+ }
+
+ /// <summary>
+ /// Updates the synchronization delta by performing the specified number of reference clock requests.
+ /// </summary>
+ /// <param name="n"> The number of reference clock request cycles to perform. </param>
+ ///
+ /// <exception cref="ClockSynchFailureException"> If synchronization cannot be achieved, due to unavailability of the reference
+ /// time service. </exception>
+ protected void synch(int n) throws ClockSynchFailureException
+ {
+ // log.debug("protected void synch(int n = " + n + "): called");
+
+ // Create an array of deltas by performing n reference pings.
+ long[] delta = new long[n];
+
+ for (int i = 0; i < n; i++)
+ {
+ delta[i] = ping();
+ }
+
+ // Reject any deltas that are larger than 1 s.d. above the median.
+ long median = median(delta);
+ long sd = standardDeviation(delta);
+
+ // log.debug("median = " + median);
+ // log.debug("sd = " + sd);
+
+ long[] tempDeltas = new long[n];
+ int count = 0;
+
+ for (int i = 0; i < n; i++)
+ {
+ if ((delta[i] <= (median + sd)) && (delta[i] >= (median - sd)))
+ {
+ tempDeltas[count] = delta[i];
+ count++;
+ }
+ else
+ {
+ // log.debug("Rejected: " + delta[i]);
+ }
+ }
+
+ System.arraycopy(tempDeltas, 0, delta, 0, count);
+
+ // Estimate the delta as the mean of the remaining deltas.
+ this.delta += mean(delta);
+
+ // Estimate the error as the standard deviation of the remaining deltas.
+ this.epsilon = standardDeviation(delta);
+
+ // log.debug("this.delta = " + this.delta);
+ // log.debug("this.epsilon = " + this.epsilon);
+ }
+
+ /// <summary>
+ /// Performs a single reference clock request cycle and returns the estimated delta relative to the local clock.
+ /// This is computed as the half-latency of the requst cycle, plus the reference clock, minus the local clock.
+ /// </summary>
+ /// <return> The estimated clock delta. </return>
+ ///
+ /// <exception cref="ClockSynchFailureException"> If the reference service is not responding. </exception>
+ protected long ping() throws ClockSynchFailureException
+ {
+ // log.debug("protected long ping(): called");
+
+ try
+ {
+ byte[] buf = new byte[256];
+
+ bool timedOut = false;
+ long start = 0L;
+ long refTime = 0L;
+ long localTime = 0L;
+ long latency = 0L;
+ int failCount = 0;
+
+ // Keep trying the ping until it gets a response, or 10 tries in a row all time out.
+ do
+ {
+ // Start timing the request latency.
+ start = nanoTime();
+
+ // Get the reference time.
+ DatagramPacket packet =
+ new DatagramPacket(buf, buf.length, referenceAddress, UDPClockReference.REFERENCE_PORT);
+ socket.send(packet);
+ packet = new DatagramPacket(buf, buf.length);
+
+ timedOut = false;
+
+ try
+ {
+ socket.receive(packet);
+ }
+ catch (SocketTimeoutException e)
+ {
+ timedOut = true;
+ failCount++;
+
+ continue;
+ }
+
+ ByteBuffer bbuf = ByteBuffer.wrap(packet.getData());
+ refTime = bbuf.getLong();
+
+ // Stop timing the request latency.
+ localTime = nanoTime();
+ latency = localTime - start;
+
+ // log.debug("refTime = " + refTime);
+ // log.debug("localTime = " + localTime);
+ // log.debug("start = " + start);
+ // log.debug("latency = " + latency);
+ // log.debug("delta = " + ((latency / 2) + (refTime - localTime)));
+
+ }
+ while (timedOut && (failCount < 10));
+
+ // Fail completely if the fail count is too high.
+ if (failCount >= 10)
+ {
+ throw new ClockSynchFailureException("Clock reference not responding.", null);
+ }
+
+ // Estimate delta as (ref clock + half-latency) - local clock.
+ return (latency / 2) + (refTime - localTime);
+ }
+ catch (IOException e)
+ {
+ throw new RuntimeException(e);
+ }
+ }
+
+ /// <summary>
+ /// Gets the clock delta in nano seconds.
+ /// </summary>
+ /// <return> The clock delta in nano seconds. </return>
+ public long getDelta()
+ {
+ return delta;
+ }
+
+ /// <summary>
+ /// Gets an estimate of the clock error in nan seconds.
+ /// </summary>
+ /// <return> An estimate of the clock error in nan seconds. </return>
+ public long getEpsilon()
+ {
+ return epsilon;
+ }
+
+ /// <summary>
+ /// Gets the local clock time with any computed delta added in.
+ /// </summary>
+ /// <return> The local clock time with any computed delta added in. </return>
+ public long nanoTime()
+ {
+ return System.nanoTime() + delta;
+ }
+
+ /// <summary>
+ /// Computes the median of a series of values.
+ /// </summary>
+ /// <param name="values"> The values. </param>
+ ///
+ /// <return> The median. </return>
+ public static long median(long[] values)
+ {
+ // log.debug("public static long median(long[] values = " + Arrays.ToString(values) + "): called");
+
+ long median;
+
+ // Order the list of values.
+ long[] orderedValues = new long[values.length];
+ System.arraycopy(values, 0, orderedValues, 0, values.length);
+ Arrays.sort(orderedValues);
+
+ // Check if the median is computed from a pair of middle value.
+ if ((orderedValues.length % 2) == 0)
+ {
+ int middle = orderedValues.length / 2;
+
+ median = (orderedValues[middle] + orderedValues[middle - 1]) / 2;
+ }
+ // The median is computed from a single middle value.
+ else
+ {
+ median = orderedValues[orderedValues.length / 2];
+ }
+
+ // log.debug("median = " + median);
+
+ return median;
+ }
+
+ /// <summary>
+ /// Computes the mean of a series of values.
+ /// </summary>
+ /// <param name="values"> The values. </param>
+ ///
+ /// <return> The mean. </return>
+ public static long mean(long[] values)
+ {
+ // log.debug("public static long mean(long[] values = " + Arrays.ToString(values) + "): called");
+
+ long total = 0L;
+
+ for (long value : values)
+ {
+ total += value;
+ }
+
+ long mean = total / values.length;
+
+ // log.debug("mean = " + mean);
+
+ return mean;
+ }
+
+ /// <summary>
+ /// Computes the variance of series of values.
+ /// </summary>
+ /// <param name="values"> The values. </param>
+ ///
+ /// <return> The variance of the values. </return>
+ public static long variance(long[] values)
+ {
+ // log.debug("public static long variance(long[] values = " + Arrays.ToString(values) + "): called");
+
+ long mean = mean(values);
+
+ long totalVariance = 0;
+
+ for (long value : values)
+ {
+ long diff = (value - mean);
+ totalVariance += diff/// diff;
+ }
+
+ long variance = totalVariance / values.length;
+
+ // log.debug("variance = " + variance);
+
+ return variance;
+ }
+
+ /// <summary>
+ /// Computes the standard deviation of a series of values.
+ /// </summary>
+ /// <param name="values"> The values. </param>
+ ///
+ /// <return> The standard deviation. </return>
+ public static long standardDeviation(long[] values)
+ {
+ // log.debug("public static long standardDeviation(long[] values = " + Arrays.ToString(values) + "): called");
+
+ long sd = Double.valueOf(Math.sqrt(variance(values))).longValue();
+
+ // log.debug("sd = " + sd);
+
+ return sd;
+ }
+
+ /// <summary>
+ /// For testing purposes. Supply address of reference clock as arg 1.
+ /// </summary>
+ /// <param name="args"> Address of reference clock as arg 1. </param>
+ public static void main(String[] args)
+ {
+ ParsedProperties options =
+ new ParsedProperties(CommandLineParser.processCommandLine(args,
+ new CommandLineParser(
+ new String[][]
+ {
+ { "1", "Address of clock reference service.", "address", "true" }
+ }), System.getProperties()));
+
+ string address = options.getProperty("1");
+
+ // Create a clock synchronizer.
+ UDPClockSynchronizer clockSyncher = new UDPClockSynchronizer(address);
+
+ // Set up a shutdown hook for it.
+ Runtime.getRuntime().addShutdownHook(new Thread(new Runnable()
+ {
+ public void run()
+ {
+ doSynch = false;
+ }
+ }));
+
+ // Repeat the clock synching until the user kills the progam.
+ while (doSynch)
+ {
+ // Perform a clock clockSynch.
+ try
+ {
+ clockSyncher.synch();
+
+ // Print out the clock delta and estimate of the error.
+ System.out.println("Delta = " + clockSyncher.getDelta());
+ System.out.println("Epsilon = " + clockSyncher.getEpsilon());
+
+ try
+ {
+ Thread.sleep(250);
+ }
+ catch (InterruptedException e)
+ {
+ // Restore the interrupted status and terminate the loop.
+ Thread.currentThread().interrupt();
+ doSynch = false;
+ }
+ }
+ // Terminate if the reference time service is unavailable.
+ catch (ClockSynchFailureException e)
+ {
+ doSynch = false;
+ }
+ }
+ }
+ }
+}
+/*
+ *
+ * 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.
+ *
+ */
+using log4net;
+
+using Apache.Qpid.Integration.Tests.framework.*;
+using org.apache.qpid.util.ConversationFactory;
+
+using uk.co.thebadgerset.junit.extensions.TimingController;
+using uk.co.thebadgerset.junit.extensions.TimingControllerAware;
+using uk.co.thebadgerset.junit.extensions.util.ParsedProperties;
+
+using javax.jms.Destination;
+using javax.jms.JMSException;
+using javax.jms.Message;
+using javax.jms.Session;
+
+using System.Collections.Generic.LinkedList;
+using System.Collections.Generic.IList;
+
+namespace Apache.Qpid.Integration.Tests.framework.distributedcircuit
+{
+ /// <summary>
+ /// DistributedCircuitImpl is a distributed implementation of the test <see cref="Circuit"/>. Many publishers and receivers
+ /// accross multiple machines may be combined to form a single test circuit. The test circuit extracts reports from
+ /// all of its publishers and receivers, and applies its assertions to these reports.
+ ///
+ /// <p/><table id="crc"><caption>CRC Card</caption>
+ /// <tr><th> Responsibilities <th> Collaborations
+ /// <tr><td> Supply the publishing and receiving ends of a test messaging circuit.
+ /// <tr><td> Start the circuit running.
+ /// <tr><td> Close the circuit down.
+ /// <tr><td> Take a reading of the circuits state.
+ /// <tr><td> Apply assertions against the circuits state.
+ /// <tr><td> Send test messages over the circuit.
+ /// <tr><td> Perform the default test procedue on the circuit.
+ /// </table>
+ /// </summary>
+ ///
+ /// <remarks> There is a short pause after receiving sender reports before asking for receiver reports, because receivers may
+ /// not have finished receiving all their test messages before the report request arrives. This is going to be a
+ /// problem for taking test timings and needs to be eliminiated. Suggested solution: have receiver send back reports
+ /// asynchronously, on test batch size boundaries, and do so automatically rather than having to have the report
+ /// request sent to them. Number each test run, or otherwise uniquely identify it, when a receiver does not get
+ /// any more messages on a test run for more than a timeout, it can assume the test is complete and send a final
+ /// report. On the coordinator end a future will need to be created to wait for all final reports to come in, and
+ /// to register results and timings for the test. This must work in such a way that a new test cycle can be started
+ /// without waiting for the results of the old one to come in.</remarks>
+ ///
+ /// <remarks> Add in setting of timing controller, from timing aware test cases.</remarks>
+ public class DistributedCircuitImpl : Circuit, TimingControllerAware
+ {
+ /// <summary> Used for debugging purposes. </summary>
+ private static ILog log = LogManager.GetLogger(typeof(DistributedCircuitImpl));
+
+ /// <summary> Holds the conversation factory over which to coordinate the test. </summary>
+ protected ConversationFactory conversationFactory;
+
+ /// <summary> Holds the controlSession over which to hold the control conversation. </summary>
+ protected Session controlSession;
+
+ /// <summary> Holds the sender nodes in the test circuit. </summary>
+ protected IList<TestClientDetails> senders;
+
+ /// <summary> Holds the receiver nodes in the test circuit. </summary>
+ protected IList<TestClientDetails> receivers;
+
+ /// <summary> Holds the sender control conversations. </summary>
+ protected ConversationFactory.Conversation[] senderConversation;
+
+ /// <summary> Holds the receiver control conversations. </summary>
+ protected ConversationFactory.Conversation[] receiverConversation;
+
+ /// <summary> Holds the control topics for the senders in the test circuit. </summary>
+ protected Destination[] senderControlTopic;
+
+ /// <summary> Holds the control topics for the receivers in the test circuit. </summary>
+ protected Destination[] receiverControlTopic;
+
+ /// <summary> Holds the number of messages to send per test run. </summary>
+ protected int numMessages;
+
+ /// <summary>
+ /// Holds the timing controller for the circuit. This is used to log test times asynchronously, when reciever nodes
+ /// return their reports after senders have completed a test case.
+ TimingController timingController;
+
+ /// <summary>
+ /// Creates a distributed test circuit on the specified senders and receivers.
+ /// </summary>
+ /// <param name="session"> The controlSession for all control conversations. </param>
+ /// <param name="senders"> The senders. </param>
+ /// <param name="receivers"> The receivers. </param>
+ /// <param name="senderConversation"> A control conversation with the senders. </param>
+ /// <param name="receiverConversation"> A control conversation with the receivers. </param>
+ /// <param name="senderControlTopic"> The senders control topic. </param>
+ /// <param name="receiverControlTopic"> The receivers control topic. </param>
+ protected DistributedCircuitImpl(Session session, IList<TestClientDetails> senders, List<TestClientDetails> receivers,
+ ConversationFactory.Conversation[] senderConversation, ConversationFactory.Conversation[] receiverConversation,
+ Destination[] senderControlTopic, Destination[] receiverControlTopic)
+ {
+ this.controlSession = session;
+ this.senders = senders;
+ this.receivers = receivers;
+ this.senderConversation = senderConversation;
+ this.receiverConversation = receiverConversation;
+ this.senderControlTopic = senderControlTopic;
+ this.receiverControlTopic = receiverControlTopic;
+ }
+
+ /// <summary>
+ /// Creates a distributed test circuit from the specified test parameters, on the senders and receivers
+ /// given.
+ /// </summary>
+ /// <param name="testProps"> The test parameters. </param>
+ /// <param name="senders"> The sender ends in the test circuit. </param>
+ /// <param name="receivers"> The receiver ends in the test circuit. </param>
+ /// <param name="conversationFactory"> A conversation factory for creating the control conversations with senders and receivers. </param>
+ ///
+ /// <return> A connected and ready to start, test circuit. </return>
+ public static Circuit createCircuit(ParsedProperties testProps, IList<TestClientDetails> senders,
+ IList<TestClientDetails> receivers, ConversationFactory conversationFactory)
+ {
+ log.debug("public static Circuit createCircuit(ParsedProperties testProps, IList<TestClientDetails> senders, "
+ + " IList<TestClientDetails> receivers, ConversationFactory conversationFactory)");
+
+ try
+ {
+ Session session = conversationFactory.getSession();
+
+ // Create control conversations with each of the senders.
+ ConversationFactory.Conversation[] senderConversation = new ConversationFactory.Conversation[senders.size()];
+ Destination[] senderControlTopic = new Destination[senders.size()];
+
+ for (int i = 0; i < senders.size(); i++)
+ {
+ TestClientDetails sender = senders.get(i);
+
+ senderControlTopic[i] = session.createTopic(sender.privateControlKey);
+ senderConversation[i] = conversationFactory.startConversation();
+ }
+
+ log.debug("Sender conversations created.");
+
+ // Create control conversations with each of the receivers.
+ ConversationFactory.Conversation[] receiverConversation = new ConversationFactory.Conversation[receivers.size()];
+ Destination[] receiverControlTopic = new Destination[receivers.size()];
+
+ for (int i = 0; i < receivers.size(); i++)
+ {
+ TestClientDetails receiver = receivers.get(i);
+
+ receiverControlTopic[i] = session.createTopic(receiver.privateControlKey);
+ receiverConversation[i] = conversationFactory.startConversation();
+ }
+
+ log.debug("Receiver conversations created.");
+
+ // Assign the sender role to each of the sending test clients.
+ for (int i = 0; i < senders.size(); i++)
+ {
+ TestClientDetails sender = senders.get(i);
+
+ Message assignSender = conversationFactory.getSession().createMessage();
+ TestUtils.setPropertiesOnMessage(assignSender, testProps);
+ assignSender.setStringProperty("CONTROL_TYPE", "ASSIGN_ROLE");
+ assignSender.setStringProperty("ROLE", "SENDER");
+
+ senderConversation[i].send(senderControlTopic[i], assignSender);
+ }
+
+ log.debug("Sender role assignments sent.");
+
+ // Assign the receivers role to each of the receiving test clients.
+ for (int i = 0; i < receivers.size(); i++)
+ {
+ TestClientDetails receiver = receivers.get(i);
+
+ Message assignReceiver = session.createMessage();
+ TestUtils.setPropertiesOnMessage(assignReceiver, testProps);
+ assignReceiver.setStringProperty("CONTROL_TYPE", "ASSIGN_ROLE");
+ assignReceiver.setStringProperty("ROLE", "RECEIVER");
+
+ receiverConversation[i].send(receiverControlTopic[i], assignReceiver);
+ }
+
+ log.debug("Receiver role assignments sent.");
+
+ // Wait for the senders and receivers to confirm their roles.
+ for (int i = 0; i < senders.size(); i++)
+ {
+ senderConversation[i].receive();
+ }
+
+ log.debug("Got all sender role confirmations");
+
+ for (int i = 0; i < receivers.size(); i++)
+ {
+ receiverConversation[i].receive();
+ }
+
+ log.debug("Got all receiver role confirmations");
+
+ // Package everything up as a circuit.
+ return new DistributedCircuitImpl(session, senders, receivers, senderConversation, receiverConversation,
+ senderControlTopic, receiverControlTopic);
+ }
+ catch (JMSException e)
+ {
+ throw new RuntimeException("JMSException not handled.");
+ }
+ }
+
+ /// <summary>
+ /// Used by tests cases that can supply a <see cref="uk.co.thebadgerset.junit.extensions.TimingController"/> to set the
+ /// controller on an aware test.
+ /// </summary>
+ /// <param name="controller"> The timing controller. </param>
+ public void setTimingController(TimingController controller)
+ {
+ this.timingController = controller;
+ }
+
+ /// <summary>
+ /// Gets the interface on the publishing end of the circuit.
+ /// </summary>
+ /// <return> The publishing end of the circuit. </return>
+ public Publisher getPublisher()
+ {
+ throw new RuntimeException("Not Implemented.");
+ }
+
+ /// <summary>
+ /// Gets the interface on the receiving end of the circuit.
+ /// </summary>
+ /// <return> The receiving end of the circuit. </return>
+ public Receiver getReceiver()
+ {
+ throw new RuntimeException("Not Implemented.");
+ }
+
+ /// <summary>
+ /// Connects and starts the circuit. After this method is called the circuit is ready to send messages.
+ public void start()
+ {
+ log.debug("public void start(): called");
+
+ try
+ {
+ // Start the test on each of the senders.
+ Message start = controlSession.createMessage();
+ start.setStringProperty("CONTROL_TYPE", "START");
+ start.setIntProperty("MESSAGE_COUNT", numMessages);
+
+ for (int i = 0; i < senders.size(); i++)
+ {
+ senderConversation[i].send(senderControlTopic[i], start);
+ }
+
+ log.debug("All senders told to start their tests.");
+ }
+ catch (JMSException e)
+ {
+ throw new RuntimeException("Unhandled JMSException.", e);
+ }
+ }
+
+ /// <summary>
+ /// Checks the test circuit. The effect of this is to gather the circuits state, for both ends of the circuit,
+ /// into a report, against which assertions may be checked.
+ /// </summary>
+ /// <remarks> Replace the asynch receiver report thread with a choice of direct or asynch executor, so that asynch
+ /// or synch logging of test timings is optional. Also need to provide an onMessage method that is capable
+ /// of receiving timing reports that receivers will generate during an ongoing test, on the test sample
+ /// size boundaries. The message timing logging code should be factored out as a common method that can
+ /// be called in response to the final report responses, or the onMessage method. Another alternative is
+ /// to abandon the final report request altogether and just use the onMessage method? I think the two
+ /// differ though, as the final report is used to apply assertions, and the ongoing report is just for
+ /// periodic timing results... In which case, maybe there needs to be a way for the onMessage method
+ /// to process just some of the incoming messages, and forward the rest on to the conversion helper, as
+ /// a sort of pre-conversation helper filter? Make conversation expose its onMessage method (it should
+ /// already) and allow another delivery thread to filter the incoming messages to the conversation.</remarks>
+ public void check()
+ {
+ log.debug("public void check(): called");
+
+ try
+ {
+ // Wait for all the test senders to return their reports.
+ for (int i = 0; i < senders.size(); i++)
+ {
+ Message senderReport = senderConversation[i].receive();
+ log.debug("Sender " + senderReport.getStringProperty("CLIENT_NAME") + " reports message count: "
+ + senderReport.getIntProperty("MESSAGE_COUNT"));
+ log.debug("Sender " + senderReport.getStringProperty("CLIENT_NAME") + " reports message time: "
+ + senderReport.getLongProperty("TEST_TIME"));
+ }
+
+ log.debug("Got all sender test reports.");
+
+ // Apply sender assertions to pass/fail the tests.
+
+ // Inject a short pause to give the receivers time to finish receiving their test messages.
+ TestUtils.pause(500);
+
+ // Ask the receivers for their reports.
+ Message statusRequest = controlSession.createMessage();
+ statusRequest.setStringProperty("CONTROL_TYPE", "STATUS_REQUEST");
+
+ for (int i = 0; i < receivers.size(); i++)
+ {
+ receiverConversation[i].send(receiverControlTopic[i], statusRequest);
+ }
+
+ log.debug("All receiver test reports requested.");
+
+ // Wait for all receiver reports to come in, but do so asynchronously.
+ Runnable gatherAllReceiverReports =
+ new Runnable()
+ {
+ public void run()
+ {
+ try
+ {
+ // Wait for all the receivers to send their reports.
+ for (int i = 0; i < receivers.size(); i++)
+ {
+ Message receiverReport = receiverConversation[i].receive();
+
+ string clientName = receiverReport.getStringProperty("CLIENT_NAME");
+ int messageCount = receiverReport.getIntProperty("MESSAGE_COUNT");
+ long testTime = receiverReport.getLongProperty("TEST_TIME");
+
+ log.debug("Receiver " + clientName + " reports message count: " + messageCount);
+ log.debug("Receiver " + receiverReport.getStringProperty("CLIENT_NAME")
+ + " reports message time: " + testTime);
+
+ // Apply receiver assertions to pass/fail the tests.
+
+ // Log the test timings on the asynchronous test timing controller.
+ /*try
+ {
+ timingController.completeTest(true, messageCount, testTime);
+ }
+ // The timing controll can throw InterruptedException is the current test is to be
+ // interrupted.
+ catch (InterruptedException e)
+ {
+ e.printStackTrace();
+ }*/
+ }
+
+ log.debug("All receiver test reports received.");
+ }
+ catch (JMSException e)
+ {
+ throw new RuntimeException(e);
+ }
+ }
+ };
+
+ Thread receiverReportsThread = new Thread(gatherAllReceiverReports);
+ receiverReportsThread.start();
+
+ // return new Message[] { senderReport, receiverReport };
+
+ }
+ catch (JMSException e)
+ {
+ throw new RuntimeException("Unhandled JMSException.", e);
+ }
+ }
+
+ /// <summary> Closes the circuit. All associated resources are closed. </summary>
+ public void close()
+ {
+ log.debug("public void close(): called");
+
+ // End the current test on all senders and receivers.
+ }
+
+ /// <summary>
+ /// Applies a list of assertions against the test circuit. The <see cref="#check()"/> method should be called before doing
+ /// this, to ensure that the circuit has gathered its state into a report to assert against.
+ /// </summary>
+ /// <param name="assertions"> The list of assertions to apply. </param>
+ ///
+ /// <return> Any assertions that failed. </return>
+ public IList<Assertion> applyAssertions(List<Assertion> assertions)
+ {
+ log.debug("public IList<Assertion> applyAssertions(List<Assertion> assertions = " + assertions + "): called");
+
+ IList<Assertion> failures = new LinkedList<Assertion>();
+
+ for (Assertion assertion : assertions)
+ {
+ if (!assertion.apply())
+ {
+ failures.add(assertion);
+ }
+ }
+
+ return failures;
+ }
+
+ /// <summary>
+ /// Runs the default test procedure against the circuit, and checks that all of the specified assertions hold.
+ /// </summary>
+ /// <param name="numMessages"> The number of messages to send using the default test procedure. </param>
+ /// <param name="assertions"> The list of assertions to apply. </param>
+ ///
+ /// <return> Any assertions that failed. </return>
+ ///
+ /// <remarks> From check onwards needs to be handled as a future. The future must call back onto the test case to
+ /// report results asynchronously.</remarks>
+ public IList<Assertion> test(int numMessages, List<Assertion> assertions)
+ {
+ log.debug("public IList<Assertion> test(int numMessages = " + numMessages + ", List<Assertion> assertions = "
+ + assertions + "): called");
+
+ // Keep the number of messages to send per test run, where the send method can reference it.
+ this.numMessages = numMessages;
+
+ // Start the test running on all sender circuit ends.
+ start();
+
+ // Request status reports to be handed in.
+ check();
+
+ // Assert conditions on the publishing end of the circuit.
+ // Assert conditions on the receiving end of the circuit.
+ IList<Assertion> failures = applyAssertions(assertions);
+
+ // Close the circuit ending the current test case.
+ close();
+
+ // Pass with no failed assertions or fail with a list of failed assertions.
+ return failures;
+ }
+ }
+}
+/*
+ *
+ * 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.
+ *
+ */
+using Apache.Qpid.Integration.Tests.framework.Assertion;
+using Apache.Qpid.Integration.Tests.framework.Publisher;
+
+using uk.co.thebadgerset.junit.extensions.util.ParsedProperties;
+
+namespace Apache.Qpid.Integration.Tests.framework.distributedcircuit
+{
+ /// <summary>
+ /// DistributedPublisherImpl represents the status of the publishing side of a test circuit. Its main purpose is to
+ /// provide assertions that can be applied to verify the behaviour of a non-local publisher.
+ ///
+ /// <p/><table id="crc"><caption>CRC Card</caption>
+ /// <tr><th> Responsibilities <th> Collaborations
+ /// <tr><td> Provide assertion that the publishers received no exceptions.
+ /// <tr><td> Provide assertion that the publishers received a no consumers error code on every message.
+ /// <tr><td> Provide assertion that the publishers received a no route error code on every message.
+ /// </table>
+ /// </summary>
+ public class DistributedPublisherImpl : Publisher
+ {
+ /// <summary>
+ /// Provides an assertion that the publisher encountered no exceptions.
+ /// </summary>
+ /// <param name="testProps"> The test configuration properties. </param>
+ /// <return> An assertion that the publisher encountered no exceptions. </return>
+ public Assertion noExceptionsAssertion(ParsedProperties testProps)
+ {
+ throw new RuntimeException("Not implemented.");
+ }
+
+ /// <summary>
+ /// Provides an assertion that the publisher got a no consumers exception on every message.
+ /// </summary>
+ /// <return> An assertion that the publisher got a no consumers exception on every message. </return>
+ public Assertion noConsumersAssertion()
+ {
+ throw new RuntimeException("Not implemented.");
+ }
+
+ /// <summary>
+ /// Provides an assertion that the publisher got a no rout exception on every message.
+ /// </summary>
+ /// <return> An assertion that the publisher got a no rout exception on every message. </return>
+ public Assertion noRouteAssertion()
+ {
+ throw new RuntimeException("Not implemented.");
+ }
+
+ /// <summary>
+ /// Provides an assertion that the AMQP channel was forcibly closed by an error condition.
+ /// </summary>
+ /// <param name="testProps"> The test configuration properties. </param>
+ /// <return> An assertion that the AMQP channel was forcibly closed by an error condition. </return>
+ public Assertion channelClosedAssertion(ParsedProperties testProps)
+ {
+ throw new RuntimeException("Not implemented.");
+ }
+
+ /// <summary>
+ /// Provides an assertion that the publisher got a given exception during the test.
+ /// </summary>
+ /// <param name="testProps"> The test configuration properties. </param>
+ /// <param name="exceptionClass"> The exception class to check for. </param>
+ /// <return> An assertion that the publisher got a given exception during the test. </return>
+ public Assertion exceptionAssertion(ParsedProperties testProps, Class<? extends Exception> exceptionClass)
+ {
+ throw new RuntimeException("Not implemented.");
+ }
+ }
+}
+/*
+ *
+ * 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.
+ *
+ */
+using Apache.Qpid.Integration.Tests.framework.Assertion;
+using Apache.Qpid.Integration.Tests.framework.Receiver;
+
+using uk.co.thebadgerset.junit.extensions.util.ParsedProperties;
+
+namespace Apache.Qpid.Integration.Tests.framework.distributedcircuit
+{
+ /// <summary>
+ /// DistributedReceiverImpl represents the status of the receiving side of a test circuit. Its main purpose is to
+ /// provide assertions that can be applied to verify the behaviour of a non-local receiver.
+ ///
+ /// <p/><table id="crc"><caption>CRC Card</caption>
+ /// <tr><th> Responsibilities <th> Collaborations
+ /// <tr><td> Provide assertion that the receivers received no exceptions.
+ /// <tr><td> Provide assertion that the receivers received all test messages sent to it.
+ /// </table>
+ /// </summary>
+ public class DistributedReceiverImpl : Receiver
+ {
+ /// <summary>
+ /// Provides an assertion that the receivers encountered no exceptions.
+ /// </summary>
+ /// <param name="testProps"> The test configuration properties. </param>
+ /// <return> An assertion that the receivers encountered no exceptions. </return>
+ public Assertion noExceptionsAssertion(ParsedProperties testProps)
+ {
+ throw new RuntimeException("Not implemented.");
+ }
+
+ /// <summary>
+ /// Provides an assertion that the receivers got all messages that were sent to it.
+ /// </summary>
+ /// <param name="testProps"> The test configuration properties. </param>
+ /// <return> An assertion that the receivers got all messages that were sent to it. </return>
+ public Assertion allMessagesReceivedAssertion(ParsedProperties testProps)
+ {
+ throw new RuntimeException("Not implemented.");
+ }
+
+ /// <summary>
+ /// Provides an assertion that the receivers got none of the messages that were sent to it.
+ /// </summary>
+ /// <param name="testProps"> The test configuration properties. </param>
+ /// <return> An assertion that the receivers got none of the messages that were sent to it. </return>
+ public Assertion noMessagesReceivedAssertion(ParsedProperties testProps)
+ {
+ throw new RuntimeException("Not implemented.");
+ }
+
+ /// <summary>
+ /// Provides an assertion that the AMQP channel was forcibly closed by an error condition.
+ /// </summary>
+ /// <param name="testProps"> The test configuration properties. </param>
+ /// <return> An assertion that the AMQP channel was forcibly closed by an error condition. </return>
+ public Assertion channelClosedAssertion(ParsedProperties testProps)
+ {
+ throw new RuntimeException("Not implemented.");
+ }
+
+ /// <summary>
+ /// Provides an assertion that the receiver got a given exception during the test.
+ ///
+ /// <param name="testProps"> The test configuration properties. </param>
+ /// <param name="exceptionClass"> The exception class to check for. <return> An assertion that the receiver got a given exception during the test. </return> </param>
+ public Assertion exceptionAssertion(ParsedProperties testProps, Class<? extends Exception> exceptionClass)
+ {
+ throw new RuntimeException("Not implemented.");
+ }
+ }
+}
+/*
+ *
+ * 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.
+ *
+ */
+using log4net;
+
+using Apache.Qpid.Integration.Tests.framework.*;
+using Apache.Qpid.Integration.Tests.framework.distributedtesting.TestClientControlledTest;
+
+using uk.co.thebadgerset.junit.extensions.util.ParsedProperties;
+using uk.co.thebadgerset.junit.extensions.util.TestContextProperties;
+
+using javax.jms.*;
+
+namespace Apache.Qpid.Integration.Tests.framework.distributedcircuit
+{
+ /// <summary>
+ /// A TestClientCircuitEnd is a <see cref="CircuitEnd"/> that may be controlled from a
+ /// <see cref="Apache.Qpid.Integration.Tests.framework.distributedtesting.TestClient"/>, and that forms a single publishing or
+ /// receiving end point in a distributed test <see cref="Apache.Qpid.Integration.Tests.framework.Circuit"/>.
+ ///
+ /// <p/>When operating in the SENDER role, this circuit end is capable of acting as part of the default circuit test
+ /// procedure (described in the class comment for <see cref="Apache.Qpid.Integration.Tests.framework.Circuit"/>). That is, it will
+ /// send the number of test messages required, using the test configuration parameters given in the test invite, and
+ /// return a report on its activities to the circuit controller.
+ ///
+ /// <p/>When operation in the RECEIVER role, this circuit end acts as part of the default circuit test procedure. It will
+ /// receive test messages, on the setup specified in the test configuration parameters, and keep count of the messages
+ /// received, and time taken to receive them. When requested by the circuit controller to provide a report, it will
+ /// return this report of its activities.
+ ///
+ /// <p/><table id="crc"><caption>CRC Card</caption>
+ /// <tr><th> Responsibilities <th> Collaborations
+ /// <tr><td> Provide a message producer for sending messages.
+ /// <td> <see cref="CircuitEnd"/>, <see cref="LocalCircuitFactory"/>, <see cref="TestUtils"/>
+ /// <tr><td> Provide a message consumer for receiving messages.
+ /// <td> <see cref="CircuitEnd"/>, <see cref="LocalCircuitFactory"/>, <see cref="TestUtils"/>
+ /// <tr><td> Supply the name of the test case that this implements.
+ /// <tr><td> Accept/Reject invites based on test parameters. <td> <see cref="MessagingTestConfigProperties"/>
+ /// <tr><td> Adapt to assigned roles. <td> <see cref="TestClientControlledTest.Roles"/>
+ /// <tr><td> Perform test case actions. <td> <see cref="MessageMonitor"/>
+ /// <tr><td> Generate test reports. <td> <see cref="MessageMonitor"/>
+ /// </table>
+ /// </summary>
+ public class TestClientCircuitEnd : CircuitEnd, TestClientControlledTest
+ {
+ /// <summary> Used for debugging. </summary>
+ private static ILog log = LogManager.GetLogger(typeof(TestClientCircuitEnd));
+
+ /// <summary> Holds the test parameters. </summary>
+ ParsedProperties testProps;
+
+ /// <summary> The number of test messages to send. </summary>
+ private int numMessages;
+
+ /// <summary> The role to be played by the test. </summary>
+ private Roles role;
+
+ /// <summary> The connection to send the test messages on. </summary>
+ private Connection connection;
+
+ /// <summary> Holds the circuit end for this test. </summary>
+ CircuitEnd circuitEnd;
+
+ /// <summary>
+ /// Holds a message monitor for this circuit end, either the monitor on the consumer when in RECEIVER more, or
+ /// a monitor updated on every message sent, when acting as a SENDER.
+ MessageMonitor messageMonitor;
+
+ /// <summary>
+ /// Should provide the name of the test case that this class implements. The exact names are defined in the
+ /// interop testing spec.
+ /// </summary>
+ /// <return> The name of the test case that this implements. </return>
+ public string getName()
+ {
+ return "DEFAULT_CIRCUIT_TEST";
+ }
+
+ /// <summary>
+ /// Determines whether the test invite that matched this test case is acceptable.
+ /// </summary>
+ /// <param name="inviteMessage"> The invitation to accept or reject. </param>
+ /// <return> <tt>true</tt> to accept the invitation, <tt>false</tt> to reject it. </return>
+ /// </summary>
+ /// <exception cref="JMSException"> Any JMSException resulting from reading the message are allowed to fall through. </exception>
+ public bool acceptInvite(Message inviteMessage) throws JMSException
+ {
+ log.debug("public bool acceptInvite(Message inviteMessage): called");
+
+ // Populate the test parameters from the invitation.
+ testProps = TestContextProperties.getInstance(MessagingTestConfigProperties.defaults);
+
+ for (Object key : testProps.keySet())
+ {
+ string propName = (String) key;
+
+ // If the test parameters is overridden by the invitation, use it instead.
+ string inviteValue = inviteMessage.getStringProperty(propName);
+
+ if (inviteValue != null)
+ {
+ testProps.setProperty(propName, inviteValue);
+ log.debug("Test invite supplied override to " + propName + " of " + inviteValue);
+ }
+
+ }
+
+ // Accept the invitation.
+ return true;
+ }
+
+ /// <summary>
+ /// Assigns the role to be played by this test case. The test parameters are fully specified in the
+ /// assignment message. When this method return the test case will be ready to execute.
+ /// </summary>
+ /// <param name="role"> The role to be played; sender or receivers. </param>
+ /// <param name="assignRoleMessage"> The role assingment message, contains the full test parameters. </param>
+ ///
+ /// <exception cref="JMSException"> Any JMSException resulting from reading the message are allowed to fall through. </exception>
+ public void assignRole(Roles role, Message assignRoleMessage) throws JMSException
+ {
+ log.debug("public void assignRole(Roles role, Message assignRoleMessage): called");
+
+ // Take note of the role to be played.
+ this.role = role;
+
+ // Extract and retain the test parameters.
+ numMessages = 1; // assignRoleMessage.getIntProperty("NUM_MESSAGES");
+
+ // Connect using the test parameters.
+ connection = TestUtils.createConnection(testProps);
+
+ // Create a circuit end that matches the assigned role and test parameters.
+ LocalCircuitFactory circuitFactory = new LocalCircuitFactory();
+
+ switch (role)
+ {
+ // Check if the sender role is being assigned, and set up a message producer if so.
+ case SENDER:
+
+ // Set up the publisher.
+ circuitEnd = circuitFactory.createPublisherCircuitEnd(connection, testProps, 0L);
+
+ // Create a custom message monitor that will be updated on every message sent.
+ messageMonitor = new MessageMonitor();
+
+ break;
+
+ // Otherwise the receivers role is being assigned, so set this up to listen for messages.
+ case RECEIVER:
+
+ // Set up the receiver.
+ circuitEnd = circuitFactory.createReceiverCircuitEnd(connection, testProps, 0L);
+
+ // Use the message monitor from the consumer for stats.
+ messageMonitor = getMessageMonitor();
+
+ break;
+ }
+
+ // Reset all messaging stats for the report.
+ messageMonitor.reset();
+
+ connection.start();
+ }
+
+ /// <summary>
+ /// Performs the test case actions. Returning from here, indicates that the sending role has completed its test.
+ /// </summary>
+ /// <param name="numMessages"> The number of test messages to send. </param>
+ ///
+ /// <exception cref="JMSException"> Any JMSException resulting from reading the message are allowed to fall through. </exception>
+ ///
+ /// <remarks> Add round robin on destinations where multiple destinations being used.</remarks>
+ ///
+ /// <remarks> Add rate limiting when rate limit specified on publishers.</remarks>
+ ///
+ /// <remarks> Add Max pending message size protection. The receiver will have to send back some acks once in a while,
+ /// to notify the publisher that its messages are being consumed. This makes the safety valve harder to
+ /// implement than in the single VM case. For example, if the limit is 1000 messages, might want to get back
+ /// an ack every 500, to notify the publisher that it can keep sending. What about pub/sub tests? Will it be
+ /// necessary to wait for an ack from every receiver? This will have the effect of rate limiting to slow
+ /// consumers too.</remarks>
+ ///
+ /// <remarks> Add commits on every commit batch size boundary.</remarks>
+ public void start(int numMessages) throws JMSException
+ {
+ log.debug("public void start(): called");
+
+ // If in the SENDER role, send the specified number of test messages to the circuit destinations.
+ if (role.equals(Roles.SENDER))
+ {
+ Message testMessage = getSession().createMessage();
+
+ for (int i = 0; i < numMessages; i++)
+ {
+ getProducer().send(testMessage);
+
+ // Increment the message count and timings.
+ messageMonitor.onMessage(testMessage);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Gets a report on the actions performed by the test case in its assigned role.
+ /// </summary>
+ /// <param name="session"> The controlSession to create the report message in. </param>
+ /// <return> The report message. </return>
+ ///
+ /// <exception cref="JMSException"> Any JMSExceptions resulting from creating the report are allowed to fall through. </exception>
+ public Message getReport(Session session) throws JMSException
+ {
+ Message report = session.createMessage();
+ report.setStringProperty("CONTROL_TYPE", "REPORT");
+
+ // Add the count of messages sent/received to the report.
+ report.setIntProperty("MESSAGE_COUNT", messageMonitor.getNumMessage());
+
+ // Add the time to send/receive messages to the report.
+ report.setLongProperty("TEST_TIME", messageMonitor.getTime());
+
+ // Add any exceptions detected to the report.
+
+ return report;
+ }
+
+ /// <summary>
+ /// Gets the message producer at this circuit end point.
+ /// </summary>
+ /// <return> The message producer at with this circuit end point. </return>
+ public MessageProducer getProducer()
+ {
+ return circuitEnd.getProducer();
+ }
+
+ /// <summary>
+ /// Gets the message consumer at this circuit end point.
+ /// </summary>
+ /// <return> The message consumer at this circuit end point. </return>
+ public MessageConsumer getConsumer()
+ {
+ return circuitEnd.getConsumer();
+ }
+
+ /// <summary>
+ /// Send the specified message over the producer at this end point.
+ /// </summary>
+ /// <param name="message"> The message to send. </param>
+ ///
+ /// <exception cref="JMSException"> Any JMS exception occuring during the send is allowed to fall through. </exception>
+ public void send(Message message) throws JMSException
+ {
+ // Send the message on the circuit ends producer.
+ circuitEnd.send(message);
+ }
+
+ /// <summary>
+ /// Gets the JMS Session associated with this circuit end point.
+ /// </summary>
+ /// <return> The JMS Session associated with this circuit end point. </return>
+ public Session getSession()
+ {
+ return circuitEnd.getSession();
+ }
+
+ /// <summary>
+ /// Closes the message producers and consumers and the sessions, associated with this circuit end point.
+ ///
+ /// <exception cref="JMSException"> Any JMSExceptions occurring during the close are allowed to fall through. </exception>
+ public void close() throws JMSException
+ {
+ // Close the producer and consumer.
+ circuitEnd.close();
+ }
+
+ /// <summary>
+ /// Returns the message monitor for reporting on received messages on this circuit end.
+ /// </summary>
+ /// <return> The message monitor for this circuit end. </return>
+ public MessageMonitor getMessageMonitor()
+ {
+ return circuitEnd.getMessageMonitor();
+ }
+
+ /// <summary>
+ /// Returns the exception monitor for reporting on exceptions received on this circuit end.
+ /// </summary>
+ /// <return> The exception monitor for this circuit end. </return>
+ public ExceptionMonitor getExceptionMonitor()
+ {
+ return circuitEnd.getExceptionMonitor();
+ }
+ }
+}
+/*
+ *
+ * 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.
+ *
+ */
+using junit.framework.Test;
+using junit.framework.TestResult;
+using junit.framework.TestSuite;
+
+using log4net;
+using org.apache.log4j.NDC;
+
+using Apache.Qpid.Integration.Tests.framework.FrameworkBaseCase;
+using Apache.Qpid.Integration.Tests.framework.MessagingTestConfigProperties;
+using Apache.Qpid.Integration.Tests.framework.TestClientDetails;
+using Apache.Qpid.Integration.Tests.framework.TestUtils;
+using Apache.Qpid.Integration.Tests.framework.clocksynch.UDPClockReference;
+using org.apache.qpid.util.ConversationFactory;
+
+using uk.co.thebadgerset.junit.extensions.TKTestRunner;
+using uk.co.thebadgerset.junit.extensions.WrappedSuiteTestDecorator;
+using uk.co.thebadgerset.junit.extensions.util.CommandLineParser;
+using uk.co.thebadgerset.junit.extensions.util.MathUtils;
+using uk.co.thebadgerset.junit.extensions.util.ParsedProperties;
+using uk.co.thebadgerset.junit.extensions.util.TestContextProperties;
+
+using javax.jms.*;
+
+using java.net.InetAddress;
+using java.util.*;
+using java.util.concurrent.LinkedBlockingQueue;
+
+namespace Apache.Qpid.Integration.Tests.framework.distributedtesting
+{
+ /// <summary>
+ /// <p/>Implements the coordinator client described in the interop testing specification
+ /// (http://cwiki.apache.org/confluence/display/qpid/Interop+Testing+Specification). This coordinator is built on
+ /// top of the JUnit testing framework.
+ ///
+ /// <p><table id="crc"><caption>CRC Card</caption>
+ /// <tr><th> Responsibilities <th> Collaborations
+ /// <tr><td> Find out what test clients are available. <td> <see cref="ConversationFactory"/>
+ /// <tr><td> Decorate available tests to run on all available clients. <td> <see cref="DistributedTestDecorator"/>
+ /// <tr><td> Attach XML test result logger.
+ /// <tr><td> Terminate the interop testing framework.
+ /// </table>
+ /// </summary>
+ ///
+ /// <remarks> Should accumulate failures over all tests, and return with success or fail code based on all results. May need
+ /// to write a special TestResult to do this properly. At the moment only the last one used will be tested for
+ /// errors, as the start method creates a fresh one for each test case run.</remarks>
+ public class Coordinator extends TKTestRunner
+ {
+ /// <summary> Used for debugging. </summary>
+ private static ILog log = LogManager.GetLogger(typeof(Coordinator));
+
+ /// <summary> Used for reporting to the console. </summary>
+ private static ILog console = LogManager.GetLogger("CONSOLE");
+
+ /// <summary> Defines the possible distributed test engines available to run coordinated test cases with. </summary>
+ public enum TestEngine
+ {
+ /// <summary> Specifies the interop test engine. This tests all available clients in pairs. </summary>
+ INTEROP,
+
+ /// <summary> Specifies the fanout test engine. This sets up one publisher role, and many reciever roles. </summary>
+ FANOUT
+ }
+
+ /// <summary>
+ /// Holds the test context properties that provides the default test parameters, plus command line overrides.
+ /// This is initialized with the default test parameters, to which command line overrides may be applied.
+ protected static ParsedProperties testContextProperties =
+ TestContextProperties.getInstance(MessagingTestConfigProperties.defaults);
+
+ /// <summary> Holds the URL of the broker to coordinate the tests on. </summary>
+ protected string brokerUrl;
+
+ /// <summary> Holds the virtual host to coordinate the tests on. If <tt>null</tt>, then the default virtual host is used. </summary>
+ protected string virtualHost;
+
+ /// <summary> Holds the list of all clients that enlisted, when the compulsory invite was issued. </summary>
+ protected Set<TestClientDetails> enlistedClients = new HashSet<TestClientDetails>();
+
+ /// <summary> Holds the conversation helper for the control conversation. </summary>
+ protected ConversationFactory conversationFactory;
+
+ /// <summary> Holds the connection that the coordinating messages are sent over. </summary>
+ protected Connection connection;
+
+ /// <summary> Holds the path of the directory to output test results too, if one is defined. </summary>
+ protected string reportDir;
+
+ /// <summary> Holds the coordinating test engine type to run the tests through. </summary>
+ protected TestEngine engine;
+
+ /// <summary> Flag that indicates that all test clients should be terminated upon completion of the test cases. </summary>
+ protected bool terminate;
+
+ /// <summary>
+ /// Creates an interop test coordinator on the specified broker and virtual host.
+ /// </summary>
+ /// <param name="repetitions"> The number of times to repeat the test, or test batch size. </param>
+ /// <param name="duration"> The length of time to run the tests for. -1 means no duration has been set. </param>
+ /// <param name="threads"> The concurrency levels to ramp up to. </param>
+ /// <param name="delay"> A delay in milliseconds between test runs. </param>
+ /// <param name="params"> The sets of 'size' parameters to pass to test. </param>
+ /// <param name="testCaseName"> The name of the test case to run. </param>
+ /// <param name="reportDir"> The directory to output the test results to. </param>
+ /// <param name="runName"> The name of the test run; used to name the output file. </param>
+ /// <param name="verbose"> Whether to print comments during test run. </param>
+ /// <param name="brokerUrl"> The URL of the broker to connect to. </param>
+ /// <param name="virtualHost"> The virtual host to run all tests on. Optional, may be <tt>null</tt>. </param>
+ /// <param name="engine"> The distributed test engine type to run the tests with. </param>
+ /// <param name="terminate"> <tt>true</tt> if test client nodes should be terminated at the end of the tests. </param>
+ /// <param name="csv"> <tt>true</tt> if the CSV results listener should be attached. </param>
+ /// <param name="xml"> <tt>true</tt> if the XML results listener should be attached. </param>
+ /// <param name="decoratorFactories"> List of factories for user specified decorators. </param>
+ public Coordinator(Integer repetitions, Long duration, int[] threads, int delay, int[] params, string testCaseName,
+ string reportDir, string runName, bool verbose, string brokerUrl, string virtualHost, TestEngine engine,
+ bool terminate, bool csv, bool xml, IList<TestDecoratorFactory> decoratorFactories)
+ {
+ super(repetitions, duration, threads, delay, params, testCaseName, reportDir, runName, csv, xml, verbose,
+ decoratorFactories);
+
+ log.debug("public Coordinator(Integer repetitions = " + repetitions + " , Long duration = " + duration
+ + ", int[] threads = " + Arrays.ToString(threads) + ", int delay = " + delay + ", int[] params = "
+ + Arrays.ToString(params) + ", string testCaseName = " + testCaseName + ", string reportDir = " + reportDir
+ + ", string runName = " + runName + ", bool verbose = " + verbose + ", string brokerUrl = " + brokerUrl
+ + ", string virtualHost =" + virtualHost + ", TestEngine engine = " + engine + ", bool terminate = "
+ + terminate + ", bool csv = " + csv + ", bool xml = " + xml + "): called");
+
+ // Retain the connection parameters.
+ this.brokerUrl = brokerUrl;
+ this.virtualHost = virtualHost;
+ this.reportDir = reportDir;
+ this.engine = engine;
+ this.terminate = terminate;
+ }
+
+ /// <summary>
+ /// The entry point for the interop test coordinator. This client accepts the following command line arguments:
+ ///
+ /// <p/><table>
+ /// <tr><td> -b <td> The broker URL. <td> Mandatory.
+ /// <tr><td> -h <td> The virtual host. <td> Optional.
+ /// <tr><td> -o <td> The directory to output test results to. <td> Optional.
+ /// <tr><td> -e <td> The type of test distribution engine to use. <td> Optional. One of: interop, fanout.
+ /// <tr><td> ... <td> Free arguments. The distributed test cases to run.
+ /// <td> Mandatory. At least one must be defined.
+ /// <tr><td> name=value <td> Trailing argument define name/value pairs. Added to the test contenxt properties.
+ /// <td> Optional.
+ /// </table>
+ /// </summary>
+ /// <param name="args"> The command line arguments. </param>
+ public static void main(String[] args)
+ {
+ NDC.push("coordinator");
+ log.debug("public static void main(String[] args = " + Arrays.ToString(args) + "): called");
+ console.info("Qpid Distributed Test Coordinator.");
+
+ // Override the default broker url to be localhost:5672.
+ testContextProperties.setProperty(MessagingTestConfigProperties.BROKER_PROPNAME, "tcp://localhost:5672");
+
+ try
+ {
+ // Use the command line parser to evaluate the command line with standard handling behaviour (print errors
+ // and usage then exist if there are errors).
+ // Any options and trailing name=value pairs are also injected into the test context properties object,
+ // to override any defaults that may have been set up.
+ ParsedProperties options =
+ new ParsedProperties(CommandLineParser.processCommandLine(args,
+ new CommandLineParser(
+ new String[][]
+ {
+ { "b", "The broker URL.", "broker", "false" },
+ { "h", "The virtual host to use.", "virtual host", "false" },
+ { "o", "The name of the directory to output test timings to.", "dir", "false" },
+ {
+ "e", "The test execution engine to use. Default is interop.", "engine", "interop",
+ "^interop$|^fanout$", "true"
+ },
+ { "t", "Terminate test clients on completion of tests.", null, "false" },
+ { "-csv", "Output test results in CSV format.", null, "false" },
+ { "-xml", "Output test results in XML format.", null, "false" },
+ {
+ "-trefaddr", "To specify an alternative to hostname for time singal reference.",
+ "address", "false"
+ },
+ {
+ "c", "The number of tests to run concurrently.", "num", "false",
+ MathUtils.SEQUENCE_REGEXP
+ },
+ { "r", "The number of times to repeat each test.", "num", "false" },
+ {
+ "d", "The length of time to run the tests for.", "duration", "false",
+ MathUtils.DURATION_REGEXP
+ },
+ {
+ "f", "The maximum rate to call the tests at.", "frequency", "false",
+ "^([1-9][0-9]*)/([1-9][0-9]*)$"
+ },
+ { "s", "The size parameter to run tests with.", "size", "false", MathUtils.SEQUENCE_REGEXP },
+ { "v", "Verbose mode.", null, "false" },
+ { "n", "A name for this test run, used to name the output file.", "name", "true" },
+ {
+ "X:decorators", "A list of additional test decorators to wrap the tests in.",
+ "\"class.name[:class.name]*\"", "false"
+ }
+ }), testContextProperties));
+
+ // Extract the command line options.
+ string brokerUrl = options.getProperty("b");
+ string virtualHost = options.getProperty("h");
+ string reportDir = options.getProperty("o");
+ reportDir = (reportDir == null) ? "." : reportDir;
+ string testEngine = options.getProperty("e");
+ TestEngine engine = "fanout".equals(testEngine) ? TestEngine.FANOUT : TestEngine.INTEROP;
+ bool terminate = options.getPropertyAsBoolean("t");
+ bool csvResults = options.getPropertyAsBoolean("-csv");
+ bool xmlResults = options.getPropertyAsBoolean("-xml");
+ string threadsstring = options.getProperty("c");
+ Integer repetitions = options.getPropertyAsInteger("r");
+ string durationstring = options.getProperty("d");
+ string paramsstring = options.getProperty("s");
+ bool verbose = options.getPropertyAsBoolean("v");
+ string testRunName = options.getProperty("n");
+ string decorators = options.getProperty("X:decorators");
+
+ int[] threads = (threadsstring == null) ? null : MathUtils.parseSequence(threadsString);
+ int[] params = (paramsstring == null) ? null : MathUtils.parseSequence(paramsString);
+ Long duration = (durationstring == null) ? null : MathUtils.parseDuration(durationString);
+
+ // If broker or virtual host settings were specified as command line options, override the defaults in the
+ // test context properties with them.
+
+ // Collection all of the test cases to be run.
+ Collection<Class<? extends FrameworkBaseCase>> testCaseClasses =
+ new ArrayList<Class<? extends FrameworkBaseCase>>();
+
+ // Create a list of test decorator factories for use specified decorators to be applied.
+ IList<TestDecoratorFactory> decoratorFactories = parseDecorators(decorators);
+
+ // Scan for available test cases using a classpath scanner.
+ // ClasspathScanner.getMatches(DistributedTestCase.class, "^Test.*", true);
+
+ // Hard code the test classes till the classpath scanner is fixed.
+ // Collections.addAll(testCaseClasses, InteropTestCase1DummyRun.class, InteropTestCase2BasicP2P.class,
+ // InteropTestCase3BasicPubSub.class);
+
+ // Parse all of the free arguments as test cases to run.
+ for (int i = 1; true; i++)
+ {
+ string nextFreeArg = options.getProperty(Integer.ToString(i));
+
+ // Terminate the loop once all free arguments have been consumed.
+ if (nextFreeArg == null)
+ {
+ break;
+ }
+
+ try
+ {
+ Class nextClass = Class.forName(nextFreeArg);
+
+ if (FrameworkBaseCase.class.isAssignableFrom(nextClass))
+ {
+ testCaseClasses.add(nextClass);
+ console.info("Found distributed test case: " + nextFreeArg);
+ }
+ }
+ catch (ClassNotFoundException e)
+ {
+ console.info("Unable to instantiate the test case: " + nextFreeArg + ".");
+ }
+ }
+
+ // Check that some test classes were actually found.
+ if (testCaseClasses.isEmpty())
+ {
+ throw new RuntimeException(
+ "No test cases implementing FrameworkBaseCase were specified on the command line.");
+ }
+
+ // Extract the names of all the test classes, to pass to the start method.
+ int i = 0;
+ String[] testClassNames = new String[testCaseClasses.size()];
+
+ for (Class testClass : testCaseClasses)
+ {
+ testClassNames[i++] = testClass.getName();
+ }
+
+ // Create a coordinator and begin its test procedure.
+ Coordinator coordinator =
+ new Coordinator(repetitions, duration, threads, 0, params, null, reportDir, testRunName, verbose, brokerUrl,
+ virtualHost, engine, terminate, csvResults, xmlResults, decoratorFactories);
+
+ TestResult testResult = coordinator.start(testClassNames);
+
+ // Return different error codes, depending on whether or not there were test failures.
+ if (testResult.failureCount() > 0)
+ {
+ System.exit(FAILURE_EXIT);
+ }
+ else
+ {
+ System.exit(SUCCESS_EXIT);
+ }
+ }
+ catch (Exception e)
+ {
+ log.debug("Top level handler caught execption.", e);
+ console.info(e.getMessage());
+ e.printStackTrace();
+ System.exit(EXCEPTION_EXIT);
+ }
+ }
+
+ /// <summary>
+ /// Starts all of the test classes to be run by this coordinator.
+ /// </summary>
+ /// <param name="testClassNames"> An array of all the coordinating test case implementations. </param>
+ ///
+ /// <return> A JUnit TestResult to run the tests with. </return>
+ ///
+ /// <exception cref="Exception"> Any underlying exceptions are allowed to fall through, and fail the test process. </exception>
+ public TestResult start(String[] testClassNames) throws Exception
+ {
+ log.debug("public TestResult start(String[] testClassNames = " + Arrays.ToString(testClassNames) + ": called");
+
+ // Connect to the broker.
+ connection = TestUtils.createConnection(TestContextProperties.getInstance());
+ Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
+
+ Destination controlTopic = session.createTopic("iop.control");
+ Destination responseQueue = session.createQueue("coordinator");
+
+ conversationFactory = new ConversationFactory(connection, responseQueue, LinkedBlockingQueue.class);
+ ConversationFactory.Conversation conversation = conversationFactory.startConversation();
+
+ connection.start();
+
+ // Broadcast the compulsory invitation to find out what clients are available to test.
+ Message invite = session.createMessage();
+ invite.setStringProperty("CONTROL_TYPE", "INVITE");
+ invite.setJMSReplyTo(responseQueue);
+
+ conversation.send(controlTopic, invite);
+
+ // Wait for a short time, to give test clients an opportunity to reply to the invitation.
+ Collection<Message> enlists = conversation.receiveAll(0, 500);
+ enlistedClients = extractEnlists(enlists);
+
+ for (TestClientDetails client : enlistedClients)
+ {
+ log.debug("Got enlisted test client: " + client);
+ console.info("Test node " + client.clientName + " available.");
+ }
+
+ // Start the clock reference service running.
+ UDPClockReference clockReference = new UDPClockReference();
+ Thread clockRefThread = new Thread(clockReference);
+ registerShutdownHook(clockReference);
+ clockRefThread.start();
+
+ // Broadcast to all clients to synchronize their clocks against the coordinators clock reference.
+ Message clockSynchRequest = session.createMessage();
+ clockSynchRequest.setStringProperty("CONTROL_TYPE", "CLOCK_SYNCH");
+
+ string localAddress = InetAddress.getByName(InetAddress.getLocalHost().getHostName()).getHostAddress();
+ clockSynchRequest.setStringProperty("ADDRESS", localAddress);
+
+ conversation.send(controlTopic, clockSynchRequest);
+
+ // Run the test in the suite using JUnit.
+ TestResult result = null;
+
+ for (string testClassName : testClassNames)
+ {
+ // Record the current test class, so that the test results can be output to a file incorporating this name.
+ this.currentTestClassName = testClassName;
+
+ result = super.start(new String[] { testClassName });
+ }
+
+ // At this point in time, all tests have completed. Broadcast the shutdown message, if the termination option
+ // was set on the command line.
+ if (terminate)
+ {
+ Message terminate = session.createMessage();
+ terminate.setStringProperty("CONTROL_TYPE", "TERMINATE");
+
+ conversation.send(controlTopic, terminate);
+ }
+
+ return result;
+ }
+
+ /// <summary>
+ /// For a collection of enlist messages, this method pulls out of the client details for the enlisting clients.
+ /// </summary>
+ /// <param name="enlists"> The enlist messages. </param>
+ ///
+ /// <return> A set of enlisting clients, extracted from the enlist messages. </return>
+ ///
+ /// <exception cref="JMSException"> Any underlying JMSException is allowed to fall through. </exception>
+ public static Set<TestClientDetails> extractEnlists(Collection<Message> enlists) throws JMSException
+ {
+ log.debug("public static Set<TestClientDetails> extractEnlists(Collection<Message> enlists = " + enlists
+ + "): called");
+
+ Set<TestClientDetails> enlistedClients = new HashSet<TestClientDetails>();
+
+ // Retain the list of all available clients.
+ for (Message enlist : enlists)
+ {
+ TestClientDetails clientDetails = new TestClientDetails();
+ clientDetails.clientName = enlist.getStringProperty("CLIENT_NAME");
+ clientDetails.privateControlKey = enlist.getStringProperty("CLIENT_PRIVATE_CONTROL_KEY");
+
+ string replyType = enlist.getStringProperty("CONTROL_TYPE");
+
+ if ("ENLIST".equals(replyType))
+ {
+ enlistedClients.add(clientDetails);
+ }
+ else if ("DECLINE".equals(replyType))
+ {
+ log.debug("Test client " + clientDetails.clientName + " declined the invite.");
+ }
+ else
+ {
+ log.warn("Got an unknown reply type, " + replyType + ", to the invite.");
+ }
+ }
+
+ return enlistedClients;
+ }
+
+ /// <summary>
+ /// Runs a test or suite of tests, using the super class implemenation. This method wraps the test to be run
+ /// in any test decorators needed to add in the coordinators ability to invite test clients to participate in
+ /// tests.
+ /// </summary>
+ /// <param name="test"> The test to run. </param>
+ /// <param name="wait"> Undocumented. Nothing in the JUnit javadocs to say what this is for. </param>
+ ///
+ /// <return> The results of the test run. </return>
+ public TestResult doRun(Test test, bool wait)
+ {
+ log.debug("public TestResult doRun(Test \"" + test + "\", bool " + wait + "): called");
+
+ // Wrap all tests in the test suite with WrappedSuiteTestDecorators. This is quite ugly and a bit baffling,
+ // but the reason it is done is because the JUnit implementation of TestDecorator has some bugs in it.
+ WrappedSuiteTestDecorator targetTest = null;
+
+ if (test instanceof TestSuite)
+ {
+ log.debug("targetTest is a TestSuite");
+
+ TestSuite suite = (TestSuite) test;
+
+ int numTests = suite.countTestCases();
+ log.debug("There are " + numTests + " in the suite.");
+
+ for (int i = 0; i < numTests; i++)
+ {
+ Test nextTest = suite.testAt(i);
+ log.debug("suite.testAt(" + i + ") = " + nextTest);
+
+ if (nextTest instanceof FrameworkBaseCase)
+ {
+ log.debug("nextTest is a FrameworkBaseCase");
+ }
+ }
+
+ targetTest = new WrappedSuiteTestDecorator(suite);
+ log.debug("Wrapped with a WrappedSuiteTestDecorator.");
+ }
+
+ // Apply any optional user specified decorators.
+ targetTest = applyOptionalUserDecorators(targetTest);
+
+ // Wrap the tests in a suitable distributed test decorator, to perform the invite/test cycle.
+ targetTest = newTestDecorator(targetTest, enlistedClients, conversationFactory, connection);
+
+ // TestSuite suite = new TestSuite();
+ // suite.addTest(targetTest);
+
+ // Wrap the tests in a scaled test decorator to them them as a 'batch' in one thread.
+ // targetTest = new ScaledTestDecorator(targetTest, new int[] { 1 });
+
+ return super.doRun(targetTest, wait);
+ }
+
+ /// <summary>
+ /// Creates a wrapped test decorator, that is capable of inviting enlisted clients to participate in a specified
+ /// test. This is the test engine that sets up the roles and sequences a distributed test case.
+ /// </summary>
+ /// <param name="targetTest"> The test decorator to wrap. </param>
+ /// <param name="enlistedClients"> The enlisted clients available to run the test. </param>
+ /// <param name="conversationFactory"> The conversation factory used to build conversation helper over the specified connection. </param>
+ /// <param name="connection"> The connection to talk to the enlisted clients over. </param>
+ ///
+ /// <return> An invititing test decorator, that invites all the enlisted clients to participate in tests, in pairs. </return>
+ protected DistributedTestDecorator newTestDecorator(WrappedSuiteTestDecorator targetTest,
+ Set<TestClientDetails> enlistedClients, ConversationFactory conversationFactory, Connection connection)
+ {
+ switch (engine)
+ {
+ case FANOUT:
+ return new FanOutTestDecorator(targetTest, enlistedClients, conversationFactory, connection);
+ case INTEROP:
+ default:
+ return new InteropTestDecorator(targetTest, enlistedClients, conversationFactory, connection);
+ }
+ }
+ }
+}
+/*
+ *
+ * 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.
+ *
+ */
+using junit.framework.TestResult;
+
+using log4net;
+
+using Apache.Qpid.Integration.Tests.framework.FrameworkBaseCase;
+using Apache.Qpid.Integration.Tests.framework.TestClientDetails;
+using Apache.Qpid.Integration.Tests.framework.sequencers.CircuitFactory;
+using org.apache.qpid.util.ConversationFactory;
+
+using uk.co.thebadgerset.junit.extensions.WrappedSuiteTestDecorator;
+
+using javax.jms.Connection;
+using javax.jms.Destination;
+using javax.jms.JMSException;
+using javax.jms.Message;
+
+using java.util.*;
+
+namespace Apache.Qpid.Integration.Tests.framework.distributedtesting
+{
+ /// <summary>
+ /// DistributedTestDecorator is a base class for writing test decorators that invite test clients to participate in
+ /// distributed test cases. It provides a helper method, <see cref="#signupClients"/>, that broadcasts an invitation and
+ /// returns the set of test clients that are available to particiapte in the test.
+ ///
+ /// <p/>When used to wrap a <see cref="FrameworkBaseCase"/> test, it replaces the default <see cref="CircuitFactory"/> implementations
+ /// with a suitable circuit factory for distributed tests. Concrete implementations can use this to configure the sending
+ /// and receiving roles on the test.
+ ///
+ /// <p><table id="crc"><caption>CRC Card</caption>
+ /// <tr><th> Responsibilities <th> Collaborations
+ /// <tr><td> Broadcast test invitations and collect enlists. <td> <see cref="ConversationFactory"/>.
+ /// </table>
+ /// </summary>
+ public abstract class DistributedTestDecorator extends WrappedSuiteTestDecorator
+ {
+ /// <summary> Used for debugging. </summary>
+ private static ILog log = LogManager.GetLogger(typeof(DistributedTestDecorator));
+
+ /// <summary> Holds the contact information for all test clients that are available and that may take part in the test. </summary>
+ Set<TestClientDetails> allClients;
+
+ /// <summary> Holds the conversation helper for the control level conversation for coordinating the test through. </summary>
+ ConversationFactory conversationFactory;
+
+ /// <summary> Holds the connection that the control conversation is held over. </summary>
+ Connection connection;
+
+ /// <summary> Holds the underlying test suite that this decorator wraps. </summary>
+ WrappedSuiteTestDecorator testSuite;
+
+ /// <summary> Holds the control topic, on which test invitations are broadcast. </summary>
+ protected Destination controlTopic;
+
+ /// <summary>
+ /// Creates a wrapped suite test decorator from another one.
+ /// </summary>
+ /// <param name="suite"> The test suite. </param>
+ /// <param name="availableClients"> The list of all clients that responded to the compulsory invite. </param>
+ /// <param name="controlConversation"> The conversation helper for the control level, test coordination conversation. </param>
+ /// <param name="controlConnection"> The connection that the coordination messages are sent over. </param>
+ public DistributedTestDecorator(WrappedSuiteTestDecorator suite, Set<TestClientDetails> availableClients,
+ ConversationFactory controlConversation, Connection controlConnection)
+ {
+ super(suite);
+
+ log.debug("public DistributedTestDecorator(WrappedSuiteTestDecorator suite, Set<TestClientDetails> allClients = "
+ + availableClients + ", ConversationHelper controlConversation = " + controlConversation + "): called");
+
+ testSuite = suite;
+ allClients = availableClients;
+ conversationFactory = controlConversation;
+ connection = controlConnection;
+
+ // Set up the test control topic.
+ try
+ {
+ controlTopic = conversationFactory.getSession().createTopic("iop.control");
+ }
+ catch (JMSException e)
+ {
+ throw new RuntimeException("Unable to create the coordinating control topic to broadcast test invites on.", e);
+ }
+ }
+
+ /// <summary>
+ /// Should run all of the tests in the wrapped test suite.
+ /// </summary>
+ /// <param name="testResult"> The the results object to monitor the test results with. </param>
+ public abstract void run(TestResult testResult);
+
+ /// <summary>
+ /// Should provide the distributed test sequencer to pass to <see cref="Apache.Qpid.Integration.Tests.framework.FrameworkBaseCase"/>
+ /// tests.
+ /// </summary>
+ /// <return> A distributed test sequencer. </return>
+ public abstract CircuitFactory getTestSequencer();
+
+ /// <summary>
+ /// Broadcasts an invitation to participate in a coordinating test case to find out what clients are available to
+ /// run the test case.
+ /// </summary>
+ /// <param name="coordTest"> The coordinating test case to broadcast an inviate for. </param>
+ ///
+ /// <return> A set of test clients that accepted the invitation. </return>
+ protected Set<TestClientDetails> signupClients(FrameworkBaseCase coordTest)
+ {
+ // Broadcast the invitation to find out what clients are available to test.
+ Set<TestClientDetails> enlists;
+ try
+ {
+ Message invite = conversationFactory.getSession().createMessage();
+
+ ConversationFactory.Conversation conversation = conversationFactory.startConversation();
+
+ invite.setStringProperty("CONTROL_TYPE", "INVITE");
+ invite.setStringProperty("TEST_NAME", coordTest.getTestCaseNameForTestMethod(coordTest.getName()));
+
+ conversation.send(controlTopic, invite);
+
+ // Wait for a short time, to give test clients an opportunity to reply to the invitation.
+ Collection<Message> replies = conversation.receiveAll(allClients.size(), 500);
+ enlists = Coordinator.extractEnlists(replies);
+ }
+ catch (JMSException e)
+ {
+ throw new RuntimeException("There was a JMSException during the invite/enlist conversation.", e);
+ }
+
+ return enlists;
+ }
+
+ /// <summary>
+ /// Prints a string summarizing this test decorator, mainly for debugging purposes.
+ /// </summary>
+ /// <return> string representation for debugging purposes. </return>
+ public string ToString()
+ {
+ return "DistributedTestDecorator: [ testSuite = " + testSuite + " ]";
+ }
+ }
+}
+/*
+ *
+ * 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.
+ *
+ */
+using junit.framework.Test;
+using junit.framework.TestResult;
+
+using log4net;
+
+using Apache.Qpid.Integration.Tests.framework.DropInTest;
+using Apache.Qpid.Integration.Tests.framework.FrameworkBaseCase;
+using Apache.Qpid.Integration.Tests.framework.TestClientDetails;
+using Apache.Qpid.Integration.Tests.framework.sequencers.CircuitFactory;
+using Apache.Qpid.Integration.Tests.framework.sequencers.FanOutCircuitFactory;
+using org.apache.qpid.util.ConversationFactory;
+
+using uk.co.thebadgerset.junit.extensions.WrappedSuiteTestDecorator;
+
+using javax.jms.Connection;
+using javax.jms.JMSException;
+using javax.jms.Message;
+using javax.jms.MessageListener;
+
+using System.Collections.Generic.Collection;
+using java.util.Iterator;
+using java.util.Set;
+
+namespace Apache.Qpid.Integration.Tests.framework.distributedtesting
+{
+ /// <summary>
+ /// FanOutTestDecorator is an <see cref="DistributedTestDecorator"/> that runs one test client in the sender role, and the remainder
+ /// in the receivers role. It also has the capability to listen for new test cases joining the test beyond the initial start
+ /// point. This feature can be usefull when experimenting with adding more load, in the form of more test clients, to assess
+ /// its impact on a running test.
+ ///
+ /// <p><table id="crc"><caption>CRC Card</caption>
+ /// <tr><th> Responsibilities <th> Collaborations
+ /// <tr><td> Execute coordinated test cases. <td> <see cref="FrameworkBaseCase"/>
+ /// <tr><td> Accept test clients joining a running test.
+ /// </table>
+ /// </summary>
+ public class FanOutTestDecorator extends DistributedTestDecorator : MessageListener
+ {
+ /// <summary> Used for debugging. </summary>
+ private static ILog log = LogManager.GetLogger(typeof(FanOutTestDecorator));
+
+ /// <summary> Holds the currently running test case. </summary>
+ FrameworkBaseCase currentTest = null;
+
+ /// <summary>
+ /// Creates a wrapped suite test decorator from another one.
+ /// </summary>
+ /// <param name="suite"> The test suite. </param>
+ /// <param name="availableClients"> The list of all clients that responded to the compulsory invite. </param>
+ /// <param name="controlConversation"> The conversation helper for the control level, test coordination conversation. </param>
+ /// <param name="controlConnection"> The connection that the coordination messages are sent over. </param>
+ public FanOutTestDecorator(WrappedSuiteTestDecorator suite, Set<TestClientDetails> availableClients,
+ ConversationFactory controlConversation, Connection controlConnection)
+ {
+ super(suite, availableClients, controlConversation, controlConnection);
+
+ log.debug("public DistributedTestDecorator(WrappedSuiteTestDecorator suite, Set<TestClientDetails> allClients = "
+ + availableClients + ", ConversationHelper controlConversation = " + controlConversation + "): called");
+
+ testSuite = suite;
+ allClients = availableClients;
+ conversationFactory = controlConversation;
+ connection = controlConnection;
+
+ // Sign available clients up to the test.
+ for (Test test : getAllUnderlyingTests())
+ {
+ FrameworkBaseCase coordTest = (FrameworkBaseCase) test;
+
+ // Get all of the clients able to participate in the test.
+ Set<TestClientDetails> enlists = signupClients(coordTest);
+
+ // Check that there were some clients available.
+ if (enlists.size() == 0)
+ {
+ throw new RuntimeException("No clients to test with");
+ }
+
+ // Create a distributed test circuit factory for the test.
+ CircuitFactory circuitFactory = getTestSequencer();
+
+ // Set up the first client in the sender role, and the remainder in the receivers role.
+ Iterator<TestClientDetails> clients = enlists.iterator();
+ circuitFactory.setSender(clients.next());
+
+ while (clients.hasNext())
+ {
+ // Set the sending and receiving client details on the test case.
+ circuitFactory.setReceiver(clients.next());
+ }
+
+ // Pass down the connection to hold the coordinating conversation over.
+ circuitFactory.setConversationFactory(conversationFactory);
+
+ // If the current test case is a drop-in test, set it up as the currently running test for late joiners to
+ // add in to. Otherwise the current test field is set to null, to indicate that late joiners are not allowed.
+ currentTest = (coordTest instanceof DropInTest) ? coordTest : null;
+
+ // Execute the test case.
+ coordTest.setCircuitFactory(circuitFactory);
+ }
+ }
+
+ /// <summary>
+ /// Broadcasts a test invitation and accepts enlists from participating clients. The wrapped test cases are run
+ /// with one test client in the sender role, and the remaining test clients in the receiving role.
+ ///
+ /// <p/>Any JMSExceptions during the invite/enlist conversation will be allowed to fall through as runtime
+ /// exceptions, resulting in the non-completion of the test run.
+ /// </summary>
+ /// <param name="testResult"> The the results object to monitor the test results with. </param>
+ ///
+ /// <remarks> Better error recovery for failure of the invite/enlist conversation could be added.</remarks>
+ public void run(TestResult testResult)
+ {
+ log.debug("public void run(TestResult testResult): called");
+
+ // Listen for late joiners on the control topic.
+ try
+ {
+ conversationFactory.getSession().createConsumer(controlTopic).setMessageListener(this);
+ }
+ catch (JMSException e)
+ {
+ throw new RuntimeException("Unable to set up the message listener on the control topic.", e);
+ }
+
+ // Run all of the test cases in the test suite.
+ /*for (Test test : getAllUnderlyingTests())
+ {
+ FrameworkBaseCase coordTest = (FrameworkBaseCase) test;
+
+ // Get all of the clients able to participate in the test.
+ Set<TestClientDetails> enlists = signupClients(coordTest);
+
+ // Check that there were some clients available.
+ if (enlists.size() == 0)
+ {
+ throw new RuntimeException("No clients to test with");
+ }
+
+ // Create a distributed test circuit factory for the test.
+ CircuitFactory circuitFactory = getTestSequencer();
+
+ // Set up the first client in the sender role, and the remainder in the receivers role.
+ Iterator<TestClientDetails> clients = enlists.iterator();
+ circuitFactory.setSender(clients.next());
+
+ while (clients.hasNext())
+ {
+ // Set the sending and receiving client details on the test case.
+ circuitFactory.setReceiver(clients.next());
+ }
+
+ // Pass down the connection to hold the coordinating conversation over.
+ circuitFactory.setConversationFactory(conversationFactory);
+
+ // If the current test case is a drop-in test, set it up as the currently running test for late joiners to
+ // add in to. Otherwise the current test field is set to null, to indicate that late joiners are not allowed.
+ currentTest = (coordTest instanceof DropInTest) ? coordTest : null;
+
+ // Execute the test case.
+ coordTest.setCircuitFactory(circuitFactory);
+ }*/
+
+ // Run all of the test cases in the test suite.
+ for (Test test : getAllUnderlyingTests())
+ {
+ FrameworkBaseCase coordTest = (FrameworkBaseCase) test;
+
+ coordTest.run(testResult);
+
+ currentTest = null;
+ }
+ }
+
+ /// <summary>
+ /// Should provide the distributed test sequencer to pass to <see cref="Apache.Qpid.Integration.Tests.framework.FrameworkBaseCase"/>
+ /// tests.
+ /// </summary>
+ /// <return> A distributed test sequencer. </return>
+ public CircuitFactory getTestSequencer()
+ {
+ return new FanOutCircuitFactory();
+ }
+
+ /// <summary>
+ /// Listens to incoming messages on the control topic. If the messages are 'join' messages, signalling a new
+ /// test client wishing to join the current test, then the new client will be added to the current test in the
+ /// receivers role.
+ /// </summary>
+ /// <param name="message"> The incoming control message. </param>
+ public void onMessage(Message message)
+ {
+ try
+ {
+ // Check if the message is from a test client attempting to join a running test, and join it to the current
+ // test case if so.
+ if (message.getStringProperty("CONTROL_TYPE").equals("JOIN") && (currentTest != null))
+ {
+ ((DropInTest) currentTest).lateJoin(message);
+ }
+ }
+ // There is not a lot can be done with this error, so it is deliberately ignored.
+ catch (JMSException e)
+ {
+ log.debug("Unable to process message:" + message);
+ }
+ }
+
+ /// <summary>
+ /// Prints a string summarizing this test decorator, mainly for debugging purposes.
+ /// </summary>
+ /// <return> string representation for debugging purposes. </return>
+ public string ToString()
+ {
+ return "FanOutTestDecorator: [ testSuite = " + testSuite + " ]";
+ }
+ }
+}
+/*
+ *
+ * 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.
+ *
+ */
+using junit.framework.Test;
+using junit.framework.TestResult;
+
+using log4net;
+
+using Apache.Qpid.Integration.Tests.framework.FrameworkBaseCase;
+using Apache.Qpid.Integration.Tests.framework.TestClientDetails;
+using Apache.Qpid.Integration.Tests.framework.sequencers.CircuitFactory;
+using Apache.Qpid.Integration.Tests.framework.sequencers.InteropCircuitFactory;
+using org.apache.qpid.util.ConversationFactory;
+
+using uk.co.thebadgerset.junit.extensions.WrappedSuiteTestDecorator;
+
+using javax.jms.Connection;
+
+using java.util.*;
+
+namespace Apache.Qpid.Integration.Tests.framework.distributedtesting
+{
+ /// <summary>
+ /// DistributedTestDecorator is a test decorator, written to implement the interop test specification. Given a list
+ /// of enlisted test clients, that are available to run interop tests, this decorator invites them to participate
+ /// in each test in the wrapped test suite. Amongst all the clients that respond to the invite, all pairs are formed,
+ /// and each pairing (in both directions, but excluding the reflexive pairings) is split into a sender and receivers
+ /// role and a test case run between them. Any enlisted combinations that do not accept a test invite are automatically
+ /// failed.
+ ///
+ /// <p><table id="crc"><caption>CRC Card</caption>
+ /// <tr><th> Responsibilities <th> Collaborations
+ /// <tr><td> Broadcast test invitations and collect enlists. <td> <see cref="org.apache.qpid.util.ConversationFactory"/>.
+ /// <tr><td> Output test failures for clients unwilling to run the test case. <td> <see cref="Coordinator"/>
+ /// <tr><td> Execute distributed test cases. <td> <see cref="FrameworkBaseCase"/>
+ /// <tr><td> Fail non-participating pairings. <td> <see cref="OptOutTestCase"/>
+ /// </table>
+ /// </summary>
+ public class InteropTestDecorator extends DistributedTestDecorator
+ {
+ /// <summary> Used for debugging. </summary>
+ private static ILog log = LogManager.GetLogger(typeof(InteropTestDecorator));
+
+ /// <summary>
+ /// Creates a wrapped suite test decorator from another one.
+ /// </summary>
+ /// <param name="suite"> The test suite. </param>
+ /// <param name="availableClients"> The list of all clients that responded to the compulsory invite. </param>
+ /// <param name="controlConversation"> The conversation helper for the control level, test coordination conversation. </param>
+ /// <param name="controlConnection"> The connection that the coordination messages are sent over. </param>
+ public InteropTestDecorator(WrappedSuiteTestDecorator suite, Set<TestClientDetails> availableClients,
+ ConversationFactory controlConversation, Connection controlConnection)
+ {
+ super(suite, availableClients, controlConversation, controlConnection);
+ }
+
+ /// <summary>
+ /// Broadcasts a test invitation and accetps enlisting from participating clients. The wrapped test case is
+ /// then repeated for every combination of test clients (provided the wrapped test case extends
+ /// <see cref="FrameworkBaseCase"/>.
+ ///
+ /// <p/>Any JMSExceptions during the invite/enlist conversation will be allowed to fall through as runtime exceptions,
+ /// resulting in the non-completion of the test run.
+ /// </summary>
+ /// <remarks> Better error recovery for failure of the invite/enlist conversation could be added.</remarks>
+ /// <param name="testResult"> The the results object to monitor the test results with. </param>
+ public void run(TestResult testResult)
+ {
+ log.debug("public void run(TestResult testResult): called");
+
+ Collection<Test> tests = testSuite.getAllUnderlyingTests();
+
+ for (Test test : getAllUnderlyingTests())
+ {
+ FrameworkBaseCase coordTest = (FrameworkBaseCase) test;
+
+ // Broadcast the invitation to find out what clients are available to test.
+ Set<TestClientDetails> enlists = signupClients(coordTest);
+
+ // Compare the list of willing clients to the list of all available.
+ Set<TestClientDetails> optOuts = new HashSet<TestClientDetails>(allClients);
+ optOuts.removeAll(enlists);
+
+ // Output test failures for clients that will not particpate in the test.
+ Set<List<TestClientDetails>> failPairs = allPairs(optOuts, allClients);
+
+ for (List<TestClientDetails> failPair : failPairs)
+ {
+ // Create a distributed test circuit factory for the test.
+ CircuitFactory circuitFactory = getTestSequencer();
+
+ // Create an automatic failure test for the opted out test pair.
+ FrameworkBaseCase failTest = new OptOutTestCase("testOptOut");
+ circuitFactory.setSender(failPair.get(0));
+ circuitFactory.setReceiver(failPair.get(1));
+ failTest.setCircuitFactory(circuitFactory);
+
+ failTest.run(testResult);
+ }
+
+ // Loop over all combinations of clients, willing to run the test.
+ Set<List<TestClientDetails>> enlistedPairs = allPairs(enlists, enlists);
+
+ for (List<TestClientDetails> enlistedPair : enlistedPairs)
+ {
+ // Create a distributed test circuit factory for the test.
+ CircuitFactory circuitFactory = getTestSequencer();
+
+ // Set the sending and receiving client details on the test circuitFactory.
+ circuitFactory.setSender(enlistedPair.get(0));
+ circuitFactory.setReceiver(enlistedPair.get(1));
+
+ // Pass down the connection to hold the coordination conversation over.
+ circuitFactory.setConversationFactory(conversationFactory);
+
+ // Execute the test case.
+ coordTest.setCircuitFactory(circuitFactory);
+ coordTest.run(testResult);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Should provide the distributed test sequencer to pass to <see cref="Apache.Qpid.Integration.Tests.framework.FrameworkBaseCase"/>
+ /// tests.
+ /// </summary>
+ /// <return> A distributed test sequencer. </return>
+ public CircuitFactory getTestSequencer()
+ {
+ return new InteropCircuitFactory();
+ }
+
+ /// <summary>
+ /// Produces all pairs of combinations of elements from two sets. The ordering of the elements in the pair is
+ /// important, that is the pair <l, r> is distinct from <r, l>; both pairs are generated. For any element, i, in
+ /// both the left and right sets, the reflexive pair <i, i> is not generated.
+ /// </summary>
+ /// <param name="left"> The left set. </param>
+ /// <param name="right"> The right set. </param>
+ /// @param <E> The type of the content of the pairs.
+ /// </summary>
+ /// <return> All pairs formed from the permutations of all elements of the left and right sets. </return>
+ private <E> Set<List<E>> allPairs(Set<E> left, Set<E> right)
+ {
+ log.debug("private <E> Set<List<E>> allPairs(Set<E> left = " + left + ", Set<E> right = " + right + "): called");
+
+ Set<List<E>> results = new HashSet<List<E>>();
+
+ // Form all pairs from left to right.
+ // Form all pairs from right to left.
+ for (E le : left)
+ {
+ for (E re : right)
+ {
+ if (!le.equals(re))
+ {
+ results.add(new Pair<E>(le, re));
+ results.add(new Pair<E>(re, le));
+ }
+ }
+ }
+
+ log.debug("results = " + results);
+
+ return results;
+ }
+
+ /// <summary> A simple implementation of a pair, using a list. </summary>
+ private class Pair<T> extends ArrayList<T>
+ {
+ /// <summary>
+ /// Creates a new pair of elements.
+ /// </summary>
+ /// <param name="first"> The first element. </param>
+ /// <param name="second"> The second element. </param>
+ public Pair(T first, T second)
+ {
+ super();
+ super.add(first);
+ super.add(second);
+ }
+ }
+ }
+}
+/*
+ *
+ * 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.
+ *
+ */
+using Apache.Qpid.Integration.Tests.framework.sequencers.CircuitFactory;
+using Apache.Qpid.Integration.Tests.framework.FrameworkBaseCase;
+
+namespace Apache.Qpid.Integration.Tests.framework.distributedtesting
+{
+ /// <summary>
+ /// An OptOutTestCase is a test case that automatically fails. It is used when a list of test clients has been generated
+ /// from a compulsory invite, but only some of those clients have responded to a specific test case invite. The clients
+ /// that did not respond, may automatically be given a fail for some tests.
+ ///
+ /// <p><table id="crc"><caption>CRC Card</caption>
+ /// <tr><th> Responsibilities <th> Collaborations
+ /// <tr><td> Fail the test with a suitable reason.
+ /// </table>
+ /// </summary>
+ public class OptOutTestCase extends FrameworkBaseCase
+ {
+ /// <summary>
+ /// Creates a new coordinating test case with the specified name.
+ /// </summary>
+ /// <param name="name"> The test case name. </param>
+ public OptOutTestCase(string name)
+ {
+ super(name);
+ }
+
+ /// <summary> Generates an appropriate test failure assertion. </summary>
+ public void testOptOut()
+ {
+ CircuitFactory circuitFactory = getCircuitFactory();
+
+ fail("One of " + circuitFactory.getSender() + " and " + getCircuitFactory().getReceivers()
+ + " opted out of the test.");
+ }
+
+ /// <summary>
+ /// Should provide a translation from the junit method name of a test to its test case name as defined in the
+ /// interop testing specification. For example the method "testP2P" might map onto the interop test case name
+ /// "TC2_BasicP2P".
+ /// </summary>
+ /// <param name="methodName"> The name of the JUnit test method. </param>
+ /// <return> The name of the corresponding interop test case. </return>
+ public string getTestCaseNameForTestMethod(string methodName)
+ {
+ return "OptOutTest";
+ }
+ }
+}
+/*
+ *
+ * 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.
+ *
+ */
+using log4net;
+using org.apache.log4j.NDC;
+
+using Apache.Qpid.Integration.Tests.framework.MessagingTestConfigProperties;
+using Apache.Qpid.Integration.Tests.framework.TestUtils;
+using Apache.Qpid.Integration.Tests.framework.clocksynch.ClockSynchThread;
+using Apache.Qpid.Integration.Tests.framework.clocksynch.UDPClockSynchronizer;
+using org.apache.qpid.util.ReflectionUtils;
+using org.apache.qpid.util.ReflectionUtilsException;
+
+using uk.co.thebadgerset.junit.extensions.SleepThrottle;
+using uk.co.thebadgerset.junit.extensions.util.ParsedProperties;
+using uk.co.thebadgerset.junit.extensions.util.TestContextProperties;
+
+using javax.jms.*;
+
+using java.util.*;
+
+namespace Apache.Qpid.Integration.Tests.framework.distributedtesting
+{
+ /// <summary>
+ /// Implements a test client as described in the interop testing spec
+ /// (http://cwiki.apache.org/confluence/display/qpid/Interop+Testing+Specification). A test client is an agent that
+ /// reacts to control message sequences send by the test <see cref="Coordinator"/>.
+ ///
+ /// <p/><table><caption>Messages Handled by TestClient</caption>
+ /// <tr><th> Message <th> Action
+ /// <tr><td> Invite(compulsory) <td> Reply with Enlist.
+ /// <tr><td> Invite(test case) <td> Reply with Enlist if test case available.
+ /// <tr><td> AssignRole(test case) <td> Reply with Accept Role if matches an enlisted test. Keep test parameters.
+ /// <tr><td> Start <td> Send test messages defined by test parameters. Send report on messages sent.
+ /// <tr><td> Status Request <td> Send report on messages received.
+ /// <tr><td> Terminate <td> Terminate the test client.
+ /// <tr><td> ClockSynch <td> Synch clock against the supplied UDP address.
+ /// </table>
+ ///
+ /// <p><table id="crc"><caption>CRC Card</caption>
+ /// <tr><th> Responsibilities <th> Collaborations
+ /// <tr><td> Handle all incoming control messages. <td> <see cref="TestClientControlledTest"/>
+ /// <tr><td> Configure and look up test cases by name. <td> <see cref="TestClientControlledTest"/>
+ /// </table>
+ /// </summary>
+ public class TestClient : MessageListener
+ {
+ /// <summary> Used for debugging. </summary>
+ private static ILog log = LogManager.GetLogger(typeof(TestClient));
+
+ /// <summary> Used for reporting to the console. </summary>
+ private static ILog console = LogManager.GetLogger("CONSOLE");
+
+ /// <summary> Holds the default identifying name of the test client. </summary>
+ public static final string CLIENT_NAME = "java";
+
+ /// <summary> Holds the URL of the broker to run the tests on. </summary>
+ public static string brokerUrl;
+
+ /// <summary> Holds the virtual host to run the tests on. If <tt>null</tt>, then the default virtual host is used. </summary>
+ public static string virtualHost;
+
+ /// <summary>
+ /// Holds the test context properties that provides the default test parameters, plus command line overrides.
+ /// This is initialized with the default test parameters, to which command line overrides may be applied.
+ /// </summary>
+ public static ParsedProperties testContextProperties =
+ TestContextProperties.getInstance(MessagingTestConfigProperties.defaults);
+
+ /// <summary> Holds all the test cases loaded from the classpath. </summary>
+ Map<String, TestClientControlledTest> testCases = new HashMap<String, TestClientControlledTest>();
+
+ /// <summary> Holds the test case currently being run by this client. </summary>
+ protected TestClientControlledTest currentTestCase;
+
+ /// <summary> Holds the connection to the broker that the test is being coordinated on. </summary>
+ protected Connection connection;
+
+ /// <summary> Holds the message producer to hold the test coordination over. </summary>
+ protected MessageProducer producer;
+
+ /// <summary> Holds the JMS controlSession for the test coordination. </summary>
+ protected Session session;
+
+ /// <summary> Holds the name of this client, with a default value. </summary>
+ protected string clientName = CLIENT_NAME;
+
+ /// <summary> This flag indicates that the test client should attempt to join the currently running test case on start up. </summary>
+ protected bool join;
+
+ /// <summary> Holds the clock synchronizer for the test node. </summary>
+ ClockSynchThread clockSynchThread;
+
+ /// <summary>
+ /// Creates a new interop test client, listenting to the specified broker and virtual host, with the specified client
+ /// identifying name.
+ /// </summary>
+ /// <param name="pBrokerUrl"> The url of the broker to connect to. </param>
+ /// <param name="pVirtualHost"> The virtual host to conect to. </param>
+ /// <param name="clientName"> The client name to use. </param>
+ /// <param name="join"> Flag to indicate that this client should attempt to join running tests. </param>
+ public TestClient(string pBrokerUrl, string pVirtualHost, string clientName, bool join)
+ {
+ log.debug("public TestClient(string pBrokerUrl = " + pBrokerUrl + ", string pVirtualHost = " + pVirtualHost
+ + ", string clientName = " + clientName + ", bool join = " + join + "): called");
+
+ // Retain the connection parameters.
+ brokerUrl = pBrokerUrl;
+ virtualHost = pVirtualHost;
+ this.clientName = clientName;
+ this.join = join;
+ }
+
+ /// <summary>
+ /// The entry point for the interop test coordinator. This client accepts the following command line arguments:
+ ///
+ /// <p/><table>
+ /// <tr><td> -b <td> The broker URL. <td> Optional.
+ /// <tr><td> -h <td> The virtual host. <td> Optional.
+ /// <tr><td> -n <td> The test client name. <td> Optional.
+ /// <tr><td> name=value <td> Trailing argument define name/value pairs. Added to system properties. <td> Optional.
+ /// </table>
+ /// </summary>
+ /// <param name="args"> The command line arguments. </param>
+ public static void main(String[] args)
+ {
+ log.debug("public static void main(String[] args = " + Arrays.ToString(args) + "): called");
+ console.info("Qpid Distributed Test Client.");
+
+ // Override the default broker url to be localhost:5672.
+ testContextProperties.setProperty(MessagingTestConfigProperties.BROKER_PROPNAME, "tcp://localhost:5672");
+
+ // Use the command line parser to evaluate the command line with standard handling behaviour (print errors
+ // and usage then exist if there are errors).
+ // Any options and trailing name=value pairs are also injected into the test context properties object,
+ // to override any defaults that may have been set up.
+ ParsedProperties options =
+ new ParsedProperties(uk.co.thebadgerset.junit.extensions.util.CommandLineParser.processCommandLine(args,
+ new uk.co.thebadgerset.junit.extensions.util.CommandLineParser(
+ new String[][]
+ {
+ { "b", "The broker URL.", "broker", "false" },
+ { "h", "The virtual host to use.", "virtual host", "false" },
+ { "o", "The name of the directory to output test timings to.", "dir", "false" },
+ { "n", "The name of the test client.", "name", "false" },
+ { "j", "Join this test client to running test.", "false" }
+ }), testContextProperties));
+
+ // Extract the command line options.
+ string brokerUrl = options.getProperty("b");
+ string virtualHost = options.getProperty("h");
+ string clientName = options.getProperty("n");
+ clientName = (clientName == null) ? CLIENT_NAME : clientName;
+ bool join = options.getPropertyAsBoolean("j");
+
+ // To distinguish logging output set up an NDC on the client name.
+ NDC.push(clientName);
+
+ // Create a test client and start it running.
+ TestClient client = new TestClient(brokerUrl, virtualHost, clientName, join);
+
+ // Use a class path scanner to find all the interop test case implementations.
+ // Hard code the test classes till the classpath scanner is fixed.
+ Collection<Class<? extends TestClientControlledTest>> testCaseClasses =
+ new ArrayList<Class<? extends TestClientControlledTest>>();
+ // ClasspathScanner.getMatches(TestClientControlledTest.class, "^TestCase.*", true);
+ testCaseClasses.addAll(loadTestCases("org.apache.qpid.interop.clienttestcases.TestCase1DummyRun",
+ "org.apache.qpid.interop.clienttestcases.TestCase2BasicP2P",
+ "org.apache.qpid.interop.clienttestcases.TestCase3BasicPubSub",
+ "org.apache.qpid.interop.clienttestcases.TestCase4P2PMessageSize",
+ "org.apache.qpid.interop.clienttestcases.TestCase5PubSubMessageSize",
+ "Apache.Qpid.Integration.Tests.framework.distributedcircuit.TestClientCircuitEnd"));
+
+ try
+ {
+ client.start(testCaseClasses);
+ }
+ catch (Exception e)
+ {
+ log.error("The test client was unable to start.", e);
+ console.info(e.getMessage());
+ System.exit(1);
+ }
+ }
+
+ /// <summary>
+ /// Parses a list of class names, and loads them if they are available on the class path.
+ /// </summary>
+ /// <param name="classNames"> The names of the classes to load. </param>
+ ///
+ /// <return> A list of the loaded test case classes. </return>
+ public static IList<Class<? extends TestClientControlledTest>> loadTestCases(String... classNames)
+ {
+ IList<Class<? extends TestClientControlledTest>> testCases =
+ new LinkedList<Class<? extends TestClientControlledTest>>();
+
+ for (string className : classNames)
+ {
+ try
+ {
+ Class<?> cls = ReflectionUtils.forName(className);
+ testCases.add((Class<? extends TestClientControlledTest>) cls);
+ }
+ catch (ReflectionUtilsException e)
+ {
+ // Ignore, class could not be found, so test not available.
+ console.warn("Requested class " + className + " cannot be found, ignoring it.");
+ }
+ catch (ClassCastException e)
+ {
+ // Ignore, class was not of correct type to be a test case.
+ console.warn("Requested class " + className + " is not an instance of TestClientControlledTest.");
+ }
+ }
+
+ return testCases;
+ }
+
+ /// <summary>
+ /// Starts the interop test client running. This causes it to start listening for incoming test invites.
+ /// </summary>
+ /// <param name="testCaseClasses"> The classes of the available test cases. The test case names from these are used to </param>
+ /// matchin incoming test invites against.
+ ///
+ /// <exception cref="JMSException"> Any underlying JMSExceptions are allowed to fall through. </exception>
+ protected void start(Collection<Class<? extends TestClientControlledTest>> testCaseClasses) throws JMSException
+ {
+ log.debug("protected void start(Collection<Class<? extends TestClientControlledTest>> testCaseClasses = "
+ + testCaseClasses + "): called");
+
+ // Create all the test case implementations and index them by the test names.
+ for (Class<? extends TestClientControlledTest> nextClass : testCaseClasses)
+ {
+ try
+ {
+ TestClientControlledTest testCase = nextClass.newInstance();
+ testCases.put(testCase.getName(), testCase);
+ }
+ catch (InstantiationException e)
+ {
+ log.warn("Could not instantiate test case class: " + nextClass.getName(), e);
+ // Ignored.
+ }
+ catch (IllegalAccessException e)
+ {
+ log.warn("Could not instantiate test case class due to illegal access: " + nextClass.getName(), e);
+ // Ignored.
+ }
+ }
+
+ // Open a connection to communicate with the coordinator on.
+ connection = TestUtils.createConnection(testContextProperties);
+ session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
+
+ // Set this up to listen for control messages.
+ Topic privateControlTopic = session.createTopic("iop.control." + clientName);
+ MessageConsumer consumer = session.createConsumer(privateControlTopic);
+ consumer.setMessageListener(this);
+
+ Topic controlTopic = session.createTopic("iop.control");
+ MessageConsumer consumer2 = session.createConsumer(controlTopic);
+ consumer2.setMessageListener(this);
+
+ // Create a producer to send replies with.
+ producer = session.createProducer(null);
+
+ // If the join flag was set, then broadcast a join message to notify the coordinator that a new test client
+ // is available to join the current test case, if it supports it. This message may be ignored, or it may result
+ // in this test client receiving a test invite.
+ if (join)
+ {
+ Message joinMessage = session.createMessage();
+
+ joinMessage.setStringProperty("CONTROL_TYPE", "JOIN");
+ joinMessage.setStringProperty("CLIENT_NAME", clientName);
+ joinMessage.setStringProperty("CLIENT_PRIVATE_CONTROL_KEY", "iop.control." + clientName);
+ producer.send(controlTopic, joinMessage);
+ }
+
+ // Start listening for incoming control messages.
+ connection.start();
+ }
+
+ /// <summary>
+ /// Handles all incoming control messages.
+ /// </summary>
+ /// <param name="message"> The incoming message. </param>
+ public void onMessage(Message message)
+ {
+ NDC.push(clientName);
+ log.debug("public void onMessage(Message message = " + message + "): called");
+
+ try
+ {
+ string controlType = message.getStringProperty("CONTROL_TYPE");
+ string testName = message.getStringProperty("TEST_NAME");
+
+ log.debug("Received control of type '" + controlType + "' for the test '" + testName + "'");
+
+ // Check if the message is a test invite.
+ if ("INVITE".equals(controlType))
+ {
+ // Flag used to indicate that an enlist should be sent. Only enlist to compulsory invites or invites
+ // for which test cases exist.
+ bool enlist = false;
+
+ if (testName != null)
+ {
+ log.debug("Got an invite to test: " + testName);
+
+ // Check if the requested test case is available.
+ TestClientControlledTest testCase = testCases.get(testName);
+
+ if (testCase != null)
+ {
+ log.debug("Found implementing class for test '" + testName + "', enlisting for it.");
+
+ // Check if the test case will accept the invitation.
+ enlist = testCase.acceptInvite(message);
+
+ log.debug("The test case "
+ + (enlist ? " accepted the invite, enlisting for it."
+ : " did not accept the invite, not enlisting."));
+
+ // Make the requested test case the current test case.
+ currentTestCase = testCase;
+ }
+ else
+ {
+ log.debug("Received an invite to the test '" + testName + "' but this test is not known.");
+ }
+ }
+ else
+ {
+ log.debug("Got a compulsory invite, enlisting for it.");
+
+ enlist = true;
+ }
+
+ if (enlist)
+ {
+ // Reply with the client name in an Enlist message.
+ Message enlistMessage = session.createMessage();
+ enlistMessage.setStringProperty("CONTROL_TYPE", "ENLIST");
+ enlistMessage.setStringProperty("CLIENT_NAME", clientName);
+ enlistMessage.setStringProperty("CLIENT_PRIVATE_CONTROL_KEY", "iop.control." + clientName);
+ enlistMessage.setJMSCorrelationID(message.getJMSCorrelationID());
+
+ log.debug("Sending enlist message '" + enlistMessage + "' to " + message.getJMSReplyTo());
+
+ producer.send(message.getJMSReplyTo(), enlistMessage);
+ }
+ else
+ {
+ // Reply with the client name in an Decline message.
+ Message enlistMessage = session.createMessage();
+ enlistMessage.setStringProperty("CONTROL_TYPE", "DECLINE");
+ enlistMessage.setStringProperty("CLIENT_NAME", clientName);
+ enlistMessage.setStringProperty("CLIENT_PRIVATE_CONTROL_KEY", "iop.control." + clientName);
+ enlistMessage.setJMSCorrelationID(message.getJMSCorrelationID());
+
+ log.debug("Sending decline message '" + enlistMessage + "' to " + message.getJMSReplyTo());
+
+ producer.send(message.getJMSReplyTo(), enlistMessage);
+ }
+ }
+ else if ("ASSIGN_ROLE".equals(controlType))
+ {
+ // Assign the role to the current test case.
+ string roleName = message.getStringProperty("ROLE");
+
+ log.debug("Got a role assignment to role: " + roleName);
+
+ TestClientControlledTest.Roles role = Enum.valueOf(TestClientControlledTest.Roles.class, roleName);
+
+ currentTestCase.assignRole(role, message);
+
+ // Reply by accepting the role in an Accept Role message.
+ Message acceptRoleMessage = session.createMessage();
+ acceptRoleMessage.setStringProperty("CLIENT_NAME", clientName);
+ acceptRoleMessage.setStringProperty("CONTROL_TYPE", "ACCEPT_ROLE");
+ acceptRoleMessage.setJMSCorrelationID(message.getJMSCorrelationID());
+
+ log.debug("Sending accept role message '" + acceptRoleMessage + "' to " + message.getJMSReplyTo());
+
+ producer.send(message.getJMSReplyTo(), acceptRoleMessage);
+ }
+ else if ("START".equals(controlType) || "STATUS_REQUEST".equals(controlType))
+ {
+ if ("START".equals(controlType))
+ {
+ log.debug("Got a start notification.");
+
+ // Extract the number of test messages to send from the start notification.
+ int numMessages;
+
+ try
+ {
+ numMessages = message.getIntProperty("MESSAGE_COUNT");
+ }
+ catch (NumberFormatException e)
+ {
+ // If the number of messages is not specified, use the default of one.
+ numMessages = 1;
+ }
+
+ // Start the current test case.
+ currentTestCase.start(numMessages);
+ }
+ else
+ {
+ log.debug("Got a status request.");
+ }
+
+ // Generate the report from the test case and reply with it as a Report message.
+ Message reportMessage = currentTestCase.getReport(session);
+ reportMessage.setStringProperty("CLIENT_NAME", clientName);
+ reportMessage.setStringProperty("CONTROL_TYPE", "REPORT");
+ reportMessage.setJMSCorrelationID(message.getJMSCorrelationID());
+
+ log.debug("Sending report message '" + reportMessage + "' to " + message.getJMSReplyTo());
+
+ producer.send(message.getJMSReplyTo(), reportMessage);
+ }
+ else if ("TERMINATE".equals(controlType))
+ {
+ console.info("Received termination instruction from coordinator.");
+
+ // Is a cleaner shutdown needed?
+ connection.close();
+ System.exit(0);
+ }
+ else if ("CLOCK_SYNCH".equals(controlType))
+ {
+ log.debug("Received clock synch command.");
+ string address = message.getStringProperty("ADDRESS");
+
+ log.debug("address = " + address);
+
+ // Re-create (if necessary) and start the clock synch thread to synch the clock every ten seconds.
+ if (clockSynchThread != null)
+ {
+ clockSynchThread.terminate();
+ }
+
+ SleepThrottle throttle = new SleepThrottle();
+ throttle.setRate(0.1f);
+
+ clockSynchThread = new ClockSynchThread(new UDPClockSynchronizer(address), throttle);
+ clockSynchThread.start();
+ }
+ else
+ {
+ // Log a warning about this but otherwise ignore it.
+ log.warn("Got an unknown control message, controlType = " + controlType + ", message = " + message);
+ }
+ }
+ catch (JMSException e)
+ {
+ // Log a warning about this, but otherwise ignore it.
+ log.warn("Got JMSException whilst handling message: " + message, e);
+ }
+ // Log any runtimes that fall through this message handler. These are fatal errors for the test client.
+ catch (RuntimeException e)
+ {
+ log.error("The test client message handler got an unhandled exception: ", e);
+ console.info("The message handler got an unhandled exception, terminating the test client.");
+ System.exit(1);
+ }
+ finally
+ {
+ NDC.pop();
+ }
+ }
+ }
+}
+/*
+ *
+ * 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.
+ *
+ */
+using javax.jms.JMSException;
+using javax.jms.Message;
+using javax.jms.MessageListener;
+using javax.jms.Session;
+
+namespace Apache.Qpid.Integration.Tests.framework.distributedtesting
+{
+ /// <summary>
+ /// TestClientControlledTest provides an interface that classes implementing test cases to run on a <see cref="TestClient"/>
+ /// node can use. Implementations must be Java beans, that is, to provide a default constructor and to implement the
+ /// <see cref="#getName"/> method.
+ ///
+ /// <p/>The methods specified in this interface are called when the <see cref="TestClient"/> receives control instructions to
+ /// apply to the test. There are control instructions to present the test case with the test invite, so that it may
+ /// choose whether or not to participate in the test, assign the test to play the sender or receiver role, start the
+ /// test and obtain the test status report.
+ ///
+ /// <p><table id="crc"><caption>CRC Card</caption>
+ /// <tr><th> Responsibilities
+ /// <tr><td> Supply the name of the test case that this implements.
+ /// <tr><td> Accept/Reject invites based on test parameters.
+ /// <tr><td> Adapt to assigned roles.
+ /// <tr><td> Perform test case actions.
+ /// <tr><td> Generate test reports.
+ /// </table>
+ /// </summary>
+ public interface TestClientControlledTest
+ {
+ /// <summary> Defines the possible test case roles that an interop test case can take on. </summary>
+ public enum Roles
+ {
+ /// <summary> Specifies the sender role. </summary>
+ SENDER,
+
+ /// <summary> Specifies the receivers role. </summary>
+ RECEIVER
+ }
+
+ /// <summary>
+ /// Should provide the name of the test case that this class implements. The exact names are defined in the
+ /// interop testing spec.
+ /// </summary>
+ /// <return> The name of the test case that this implements. </return>
+ public string getName();
+
+ /// <summary>
+ /// Determines whether the test invite that matched this test case is acceptable.
+ /// </summary>
+ /// <param name="inviteMessage"> The invitation to accept or reject. </param>
+ ///
+ /// <return> <tt>true</tt> to accept the invitation, <tt>false</tt> to reject it. </return>
+ ///
+ /// <exception cref="JMSException"> Any JMSException resulting from reading the message are allowed to fall through. </exception>
+ public bool acceptInvite(Message inviteMessage) throws JMSException;
+
+ /// <summary>
+ /// Assigns the role to be played by this test case. The test parameters are fully specified in the
+ /// assignment message. When this method return the test case will be ready to execute.
+ /// </summary>
+ /// <param name="role"> The role to be played; sender or receivers. </param>
+ /// <param name="assignRoleMessage"> The role assingment message, contains the full test parameters. </param>
+ ///
+ /// <exception cref="JMSException"> Any JMSException resulting from reading the message are allowed to fall through. </exception>
+ public void assignRole(Roles role, Message assignRoleMessage) throws JMSException;
+
+ /// <summary>
+ /// Performs the test case actions. Returning from here, indicates that the sending role has completed its test.
+ /// </summary>
+ /// <param name="numMessages"> The number of test messages to send. </param>
+ ///
+ /// <exception cref="JMSException"> Any JMSException resulting from reading the message are allowed to fall through. </exception>
+ public void start(int numMessages) throws JMSException;
+
+ /// <summary>
+ /// Gets a report on the actions performed by the test case in its assigned role.
+ /// </summary>
+ /// <param name="session"> The controlSession to create the report message in. </param>
+ ///
+ /// <return> The report message. </return>
+ ///
+ /// <exception cref="JMSException"> Any JMSExceptions resulting from creating the report are allowed to fall through. </exception>
+ public Message getReport(Session session) throws JMSException;
+ }
+}
+/*
+ *
+ * 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.
+ *
+ */
+using javax.jms.JMSException;
+using javax.jms.Message;
+
+namespace Apache.Qpid.Integration.Tests.framework
+{
+ /// <summary>
+ /// A DropIn test is a test case that can accept late joining test clients into a running test. This can be usefull,
+ /// for interactive experimentation.
+ ///
+ /// <p/><table id="crc"><caption>CRC Card</caption>
+ /// <tr><th> Responsibilities
+ /// <tr><td> Accept late joining test clients.
+ /// </table>
+ /// </summary>
+ public interface DropInTest
+ {
+ /// <summary>
+ /// Should accept a late joining client into a running test case. The client will be enlisted with a control message
+ /// with the 'CONTROL_TYPE' field set to the value 'LATEJOIN'. It should also provide values for the fields:
+ ///
+ /// <p/><table>
+ /// <tr><td> CLIENT_NAME <td> A unique name for the new client.
+ /// <tr><td> CLIENT_PRIVATE_CONTROL_KEY <td> The key for the route on which the client receives its control messages.
+ /// </table>
+ /// </summary>
+ /// <param name="message"> The late joiners join message. </param>
+ ///
+ /// <exception cref="JMSException"> Any JMS Exception are allowed to fall through, indicating that the join failed. </exception>
+ public void lateJoin(Message message) throws JMSException;
+ }
+}
+/*
+ *
+ * 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.
+ *
+ */
+using log4net;
+
+using javax.jms.ExceptionListener;
+using javax.jms.JMSException;
+
+using java.io.PrintWriter;
+using java.io.StringWriter;
+using java.util.ArrayList;
+using System.Collections.Generic.IList;
+
+namespace Apache.Qpid.Integration.Tests.framework
+{
+ /// <summary>
+ /// An exception monitor, listens for JMS exception on a connection or consumer. It record all exceptions that it receives
+ /// and provides methods to test the number and type of exceptions received.
+ ///
+ /// <p/><table id="crc"><caption>CRC Card</caption>
+ /// <tr><th> Responsibilities <th> Collaborations
+ /// <tr><td> Record all exceptions received.
+ /// </table>
+ /// </summary>
+ public class ExceptionMonitor : ExceptionListener
+ {
+ /// <summary> Used for debugging. </summary>
+ private static ILog log = LogManager.GetLogger(typeof(ExceptionMonitor));
+
+ /// <summary> Holds the received exceptions. </summary>
+ IList<Exception> exceptions = new ArrayList<Exception>();
+
+ /// <summary>
+ /// Receives incoming exceptions.
+ /// </summary>
+ /// <param name="e"> The exception to record. </param>
+ public synchronized void onException(JMSException e)
+ {
+ log.debug("public void onException(JMSException e): called", e);
+
+ exceptions.add(e);
+ }
+
+ /// <summary>
+ /// Checks that no exceptions have been received.
+ /// </summary>
+ /// <return> <tt>true</tt> if no exceptions have been received, <tt>false</tt> otherwise. </return>
+ public synchronized bool assertNoExceptions()
+ {
+ return exceptions.isEmpty();
+ }
+
+ /// <summary>
+ /// Checks that exactly one exception has been received.
+ /// </summary>
+ /// <return> <tt>true</tt> if exactly one exception been received, <tt>false</tt> otherwise. </return>
+ public synchronized bool assertOneJMSException()
+ {
+ return exceptions.size() == 1;
+ }
+
+ /// <summary>
+ /// Checks that exactly one exception, with a linked cause of the specified type, has been received.
+ /// </summary>
+ /// <param name="aClass"> The type of the linked cause. </param>
+ ///
+ /// <return> <tt>true</tt> if exactly one exception, with a linked cause of the specified type, been received, </return>
+ /// <tt>false</tt> otherwise.
+ public synchronized bool assertOneJMSExceptionWithLinkedCause(Class aClass)
+ {
+ if (exceptions.size() == 1)
+ {
+ Exception e = exceptions.get(0);
+
+ if (e instanceof JMSException)
+ {
+ JMSException jmse = (JMSException) e;
+
+ Exception linkedCause = jmse.getLinkedException();
+
+ if ((linkedCause != null) && aClass.isInstance(linkedCause))
+ {
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
+
+ /// <summary>
+ /// Checks that at least one exception of the the specified type, has been received.
+ /// </summary>
+ /// <param name="exceptionClass"> The type of the exception. </param>
+ ///
+ /// <return> <tt>true</tt> if at least one exception of the specified type has been received, <tt>false</tt> otherwise. </return>
+ public synchronized bool assertExceptionOfType(Class exceptionClass)
+ {
+ // Start by assuming that the exception has no been received.
+ bool passed = false;
+
+ // Scan all the exceptions for a match.
+ for (Exception e : exceptions)
+ {
+ if (exceptionClass.isInstance(e))
+ {
+ passed = true;
+
+ break;
+ }
+ }
+
+ return passed;
+ }
+
+ /// <summary>
+ /// Reports the number of exceptions held by this monitor.
+ /// </summary>
+ /// <return> The number of exceptions held by this monitor. </return>
+ public synchronized int size()
+ {
+ return exceptions.size();
+ }
+
+ /// <summary>
+ /// Clears the record of received exceptions.
+ /// </summary>
+ public synchronized void reset()
+ {
+ exceptions = new ArrayList<Exception>();
+ }
+
+ /// <summary>
+ /// Provides a dump of the stack traces of all exceptions that this exception monitor was notified of. Mainly
+ /// use for debugging/test failure reporting purposes.
+ /// </summary>
+ /// <return> A string containing a dump of the stack traces of all exceptions. </return>
+ public synchronized string ToString()
+ {
+ string result = "ExceptionMonitor: holds " + exceptions.size() + " exceptions.\n\n";
+
+ for (Exception ex : exceptions)
+ {
+ result += getStackTrace(ex) + "\n";
+ }
+
+ return result;
+ }
+
+ /// <summary>
+ /// Prints an exception stack trace into a string.
+ /// </summary>
+ /// <param name="t"> The throwable to get the stack trace from. </param>
+ ///
+ /// <return> A string containing the throwables stack trace. </return>
+ public static string getStackTrace(Throwable t)
+ {
+ StringWriter sw = new StringWriter();
+ PrintWriter pw = new PrintWriter(sw, true);
+ t.printStackTrace(pw);
+ pw.flush();
+ sw.flush();
+
+ return sw.ToString();
+ }
+ }
+}
+/*
+ *
+ * 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.
+ *
+ */
+using log4net;
+using org.apache.log4j.NDC;
+
+using Apache.Qpid.Integration.Tests.framework.BrokerLifecycleAware;
+using Apache.Qpid.Integration.Tests.framework.sequencers.CircuitFactory;
+
+using uk.co.thebadgerset.junit.extensions.AsymptoticTestCase;
+using uk.co.thebadgerset.junit.extensions.SetupTaskAware;
+using uk.co.thebadgerset.junit.extensions.SetupTaskHandler;
+using uk.co.thebadgerset.junit.extensions.util.ParsedProperties;
+using uk.co.thebadgerset.junit.extensions.util.TestContextProperties;
+
+using java.util.ArrayList;
+using System.Collections.Generic.IList;
+
+namespace Apache.Qpid.Integration.Tests.framework
+{
+ /// <summary>
+ /// FrameworkBaseCase provides a starting point for writing test cases against the test framework. Its main purpose is
+ /// to provide some convenience methods for testing.
+ ///
+ /// <p/><table id="crc"><caption>CRC Card</caption>
+ /// <tr><th> Responsibilities <th> Collaborations
+ /// <tr><td> Create and clean up in-vm brokers on every test case.
+ /// <tr><td> Produce lists of assertions from assertion creation calls.
+ /// <tr><td> Produce JUnit failures from assertion failures.
+ /// <tr><td> Convert failed assertions to error messages.
+ /// </table>
+ /// </summary>
+ public class FrameworkBaseCase extends AsymptoticTestCase : FrameworkTestContext, SetupTaskAware,
+ BrokerLifecycleAware
+ {
+ /// <summary> Used for debugging purposes. </summary>
+ private static ILog log = LogManager.GetLogger(typeof(FrameworkBaseCase));
+
+ /// <summary> Holds the test sequencer to create and run test circuits with. </summary>
+ protected CircuitFactory circuitFactory = new LocalCircuitFactory();
+
+ /// <summary> Used to read the tests configurable properties through. </summary>
+ protected ParsedProperties testProps;
+
+ /// <summary> A default setup task processor to delegate setup tasks to. </summary>
+ protected SetupTaskHandler taskHandler = new SetupTaskHandler();
+
+ /// <summary> Flag used to track whether the test is in-vm or not. </summary>
+ protected bool isUsingInVM;
+
+ /// <summary> Holds the failure mechanism. </summary>
+ protected CauseFailure failureMechanism = new CauseFailureUserPrompt();
+
+ /// <summary>
+ /// Creates a new test case with the specified name.
+ /// </summary>
+ /// <param name="name"> The test case name. </param>
+ public FrameworkBaseCase(string name)
+ {
+ super(name);
+ }
+
+ /// <summary>
+ /// Returns the test case sequencer that provides test circuit, and test sequence implementations. The sequencer
+ /// that this base case returns by default is suitable for running a test circuit with both circuit ends colocated
+ /// on the same JVM.
+ /// </summary>
+ /// <return> The test case sequencer. </return>
+ protected CircuitFactory getCircuitFactory()
+ {
+ return circuitFactory;
+ }
+
+ /// <summary>
+ /// Overrides the default test circuit factory. Test decorators can use this to supply distributed test sequencers or
+ /// other test circuit factory specializations.
+ /// </summary>
+ /// <param name="circuitFactory"> The new test circuit factory. </param>
+ public void setCircuitFactory(CircuitFactory circuitFactory)
+ {
+ this.circuitFactory = circuitFactory;
+ }
+
+ /// <summary>
+ /// Reports the current test case name.
+ /// </summary>
+ /// <return> The current test case name. </return>
+ public TestCaseVector getTestCaseVector()
+ {
+ return new TestCaseVector(this.getName(), 0);
+ }
+
+ /// <summary>
+ /// Reports the current test case parameters.
+ /// </summary>
+ /// <return> The current test case parameters. </return>
+ public MessagingTestConfigProperties getTestParameters()
+ {
+ return new MessagingTestConfigProperties(testProps);
+ }
+
+ /// <summary>
+ /// Creates a list of assertions.
+ /// </summary>
+ /// <param name="asserts"> The assertions to compile in a list. </param>
+ ///
+ /// <return> A list of assertions. </return>
+ protected IList<Assertion> assertionList(Assertion... asserts)
+ {
+ IList<Assertion> result = new ArrayList<Assertion>();
+
+ for (Assertion assertion : asserts)
+ {
+ result.add(assertion);
+ }
+
+ return result;
+ }
+
+ /// <summary>
+ /// Generates a JUnit assertion exception (failure) if any assertions are passed into this method, also concatenating
+ /// all of the error messages in the assertions together to form an error message to diagnose the test failure with.
+ /// </summary>
+ /// <param name="asserts"> The list of failed assertions. </param>
+ protected static void assertNoFailures(List<Assertion> asserts)
+ {
+ log.debug("protected void assertNoFailures(List<Assertion> asserts = " + asserts + "): called");
+
+ // Check if there are no assertion failures, and return without doing anything if so.
+ if ((asserts == null) || asserts.isEmpty())
+ {
+ return;
+ }
+
+ // Compile all of the assertion failure messages together.
+ string errorMessage = assertionsToString(asserts);
+
+ // Fail with the error message from all of the assertions.
+ fail(errorMessage);
+ }
+
+ /// <summary>
+ /// Converts a list of failed assertions into an error message.
+ /// </summary>
+ /// <param name="asserts"> The failed assertions. </param>
+ ///
+ /// <return> The error message. </return>
+ protected static string assertionsToString(List<Assertion> asserts)
+ {
+ string errorMessage = "";
+
+ for (Assertion assertion : asserts)
+ {
+ errorMessage += assertion.ToString() + "\n";
+ }
+
+ return errorMessage;
+ }
+
+ /// <summary>
+ /// Ensures that the in-vm broker is created and initialized.
+ /// </summary>
+ ///
+ /// <exception cref="Exception"> Any exceptions allowed to fall through and fail the test. </exception>
+ protected void setUp() throws Exception
+ {
+ NDC.push(getName());
+
+ testProps = TestContextProperties.getInstance(MessagingTestConfigProperties.defaults);
+
+ // Process all optional setup tasks. This may include in-vm broker creation, if a decorator has added it.
+ taskHandler.runSetupTasks();
+ }
+
+ /// <summary> Ensures that the in-vm broker is cleaned up after each test run. </summary>
+ protected void tearDown()
+ {
+ NDC.pop();
+
+ // Process all optional tear down tasks. This may include in-vm broker clean up, if a decorator has added it.
+ taskHandler.runTearDownTasks();
+ }
+
+ /// <summary>
+ /// Adds the specified task to the tests setup.
+ /// </summary>
+ /// <param name="task"> The task to add to the tests setup. </param>
+ public void chainSetupTask(Runnable task)
+ {
+ taskHandler.chainSetupTask(task);
+ }
+
+ /// <summary>
+ /// Adds the specified task to the tests tear down.
+ /// </summary>
+ /// <param name="task"> The task to add to the tests tear down. </param>
+ public void chainTearDownTask(Runnable task)
+ {
+ taskHandler.chainTearDownTask(task);
+ }
+
+ /// <summary>
+ /// Should provide a translation from the junit method name of a test to its test case name as known to the test
+ /// clients that will run the test. The purpose of this is to convert the JUnit method name into the correct test
+ /// case name to place into the test invite. For example the method "testP2P" might map onto the interop test case
+ /// name "TC2_BasicP2P".
+ /// </summary>
+ /// <param name="methodName"> The name of the JUnit test method. </param>
+ ///
+ /// <return> The name of the corresponding interop test case. </return>
+ public string getTestCaseNameForTestMethod(string methodName)
+ {
+ return methodName;
+ }
+
+ public void setInVmBrokers()
+ {
+ isUsingInVM = true;
+ }
+
+ /// <summary>
+ /// Indicates whether or not a test case is using in-vm brokers.
+ /// </summary>
+ /// <return> <tt>true</tt> if the test is using in-vm brokers, <tt>false</tt> otherwise. </return>
+ public bool usingInVmBroker()
+ {
+ return isUsingInVM;
+ }
+
+ /// <summary>
+ /// Sets the currently live in-vm broker.
+ /// </summary>
+ /// <param name="i"> The currently live in-vm broker. </param>
+ public void setLiveBroker(int i)
+ { }
+
+ /// <summary>
+ /// Reports the currently live in-vm broker.
+ /// </summary>
+ /// <return> The currently live in-vm broker. </return>
+ public int getLiveBroker()
+ {
+ return 0;
+ }
+
+ /// <summary>
+ /// Accepts a failure mechanism.
+ /// </summary>
+ /// <param name="failureMechanism"> The failure mechanism. </param>
+ public void setFailureMechanism(CauseFailure failureMechanism)
+ {
+ this.failureMechanism = failureMechanism;
+ }
+ }
+}
+/*
+ *
+ * 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.
+ *
+ */
+namespace Apache.Qpid.Integration.Tests.framework
+{
+
+ /// <summary>
+ /// A FrameworkTestContext provides context information to test code about the current test case being run; its name, its
+ /// parameters.
+ ///
+ /// <p/><table id="crc"><caption>CRC Card</caption>
+ /// <tr><th> Responsibilities <th> Collaborations
+ /// <tr><td> Provide the name of the current test case.
+ /// <tr><td> Provide the test parameters.
+ /// </table>
+ /// </summary>
+ public interface FrameworkTestContext
+ {
+ /// <summary>
+ /// Reports the current test case name.
+ /// </summary>
+ /// <return> The current test case name. </return>
+ TestCaseVector getTestCaseVector();
+
+ /// <summary>
+ /// Reports the current test case parameters.
+ /// </summary>
+ /// <return> The current test case parameters. </return>
+ MessagingTestConfigProperties getTestParameters();
+ }
+}
+/*
+ *
+ * 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.
+ *
+ */
+using log4net;
+
+using Apache.Qpid.Integration.Tests.framework.*;
+
+using uk.co.thebadgerset.junit.extensions.util.ParsedProperties;
+
+using javax.jms.*;
+
+using System.Collections.Generic.LinkedList;
+using System.Collections.Generic.IList;
+
+namespace Apache.Qpid.Integration.Tests.framework.localcircuit
+{
+ /// <summary>
+ /// LocalCircuitImpl provides an implementation of the test circuit. This is a local only circuit implementation that
+ /// supports a single producer/consumer on each end of the circuit, with both ends of the circuit on the same JVM.
+ ///
+ /// <p/><table id="crc"><caption>CRC Card</caption>
+ /// <tr><th> Responsibilities <th> Collaborations
+ /// <tr><td> Supply the publishing and receiving ends of a test messaging circuit.
+ /// <td> <see cref="LocalPublisherImpl"/>, <see cref="LocalReceiverImpl"/>
+ /// <tr><td> Start the circuit running.
+ /// <tr><td> Close the circuit down.
+ /// <tr><td> Take a reading of the circuits state.
+ /// <tr><td> Apply assertions against the circuits state. <td> <see cref="Assertion"/>
+ /// <tr><td> Send test messages over the circuit.
+ /// <tr><td> Perform the default test procedure on the circuit.
+ /// <tr><td> Provide access to connection and controlSession exception monitors. <td> <see cref="ExceptionMonitor"/>
+ /// </table>
+ /// </summary>
+ public class LocalCircuitImpl : Circuit
+ {
+ /// <summary> Used for debugging. </summary>
+ private static ILog log = LogManager.GetLogger(typeof(LocalCircuitImpl));
+
+ /// <summary> Holds the test configuration for the circuit. </summary>
+ private ParsedProperties testProps;
+
+ /// <summary> Holds the publishing end of the circuit. </summary>
+ private LocalPublisherImpl publisher;
+
+ /// <summary> Holds the receiving end of the circuit. </summary>
+ private LocalReceiverImpl receiver;
+
+ /// <summary> Holds the connection for the publishing end of the circuit. </summary>
+ private Connection connection;
+
+ /// <summary> Holds the exception listener for the connection on the publishing end of the circuit. </summary>
+ private ExceptionMonitor connectionExceptionMonitor;
+
+ /// <summary> Holds the exception listener for the controlSession on the publishing end of the circuit. </summary>
+ private ExceptionMonitor exceptionMonitor;
+
+ /// <summary>
+ /// Creates a test circuit using the specified test parameters. The publisher, receivers, connection and
+ /// connection monitor must already have been created, to assemble the circuit.
+ /// </summary>
+ /// <param name="testProps"> The test parameters. </param>
+ /// <param name="publisher"> The test publisher. </param>
+ /// <param name="receiver"> The test receivers. </param>
+ /// <param name="connection"> The connection. </param>
+ /// <param name="connectionExceptionMonitor"> The connection exception monitor. </param>
+ public LocalCircuitImpl(ParsedProperties testProps, LocalPublisherImpl publisher, LocalReceiverImpl receiver,
+ Connection connection, ExceptionMonitor connectionExceptionMonitor)
+ {
+ this.testProps = testProps;
+ this.publisher = publisher;
+ this.receiver = receiver;
+ this.connection = connection;
+ this.connectionExceptionMonitor = connectionExceptionMonitor;
+ this.exceptionMonitor = new ExceptionMonitor();
+
+ // Set this as the parent circuit on the publisher and receivers.
+ publisher.setCircuit(this);
+ receiver.setCircuit(this);
+ }
+
+ /// <summary>
+ /// Gets the interface on the publishing end of the circuit.
+ /// </summary>
+ /// <return> The publishing end of the circuit. </return>
+ public Publisher getPublisher()
+ {
+ return publisher;
+ }
+
+ /// <summary>
+ /// Gets the local publishing circuit end, for direct manipulation.
+ /// </summary>
+ /// <return> The local publishing circuit end. </return>
+ public CircuitEnd getLocalPublisherCircuitEnd()
+ {
+ return publisher;
+ }
+
+ /// <summary>
+ /// Gets the interface on the receiving end of the circuit.
+ /// </summary>
+ /// <return> The receiving end of the circuit. </return>
+ public Receiver getReceiver()
+ {
+ return receiver;
+ }
+
+ /// <summary>
+ /// Gets the local receiving circuit end, for direct manipulation.
+ /// </summary>
+ /// <return> The local receiving circuit end. </return>
+ public CircuitEnd getLocalReceiverCircuitEnd()
+ {
+ return receiver;
+ }
+
+ /// <summary>
+ /// Checks the test circuit. The effect of this is to gather the circuits state, for both ends of the circuit,
+ /// into a report, against which assertions may be checked.
+ /// </summary>
+ public void check()
+ { }
+
+ /// <summary>
+ /// Applied a list of assertions against the test circuit. The <see cref="#check()"/> method should be called before doing
+ /// this, to ensure that the circuit has gathered its state into a report to assert against.
+ /// </summary>
+ /// <param name="assertions"> The list of assertions to apply. </param>
+ /// <return> Any assertions that failed. </return>
+ public IList<Assertion> applyAssertions(List<Assertion> assertions)
+ {
+ IList<Assertion> failures = new LinkedList<Assertion>();
+
+ for (Assertion assertion : assertions)
+ {
+ if (!assertion.apply())
+ {
+ failures.add(assertion);
+ }
+ }
+
+ return failures;
+ }
+
+ /// <summary> Connects and starts the circuit. After this method is called the circuit is ready to send messages. </summary>
+ public void start()
+ { }
+
+ /// <summary> Closes the circuit. All associated resources are closed. </summary>
+ public void close()
+ {
+ try
+ {
+ publisher.close();
+ receiver.close();
+ connection.close();
+ }
+ catch (JMSException e)
+ {
+ throw new RuntimeException("Got JMSException during close:" + e.getMessage(), e);
+ }
+ }
+
+ /// <summary> Sends a message on the test circuit. The exact nature of the message sent is controlled by the test parameters. </summary>
+ protected void send()
+ {
+ // Cast the test properties into a typed interface for convenience.
+ MessagingTestConfigProperties props = new MessagingTestConfigProperties(testProps);
+
+ bool transactional = props.getPublisherTransacted();
+ bool rollback = props.getRollbackPublisher();
+
+ // Send a message through the publisher and log any exceptions raised.
+ try
+ {
+ CircuitEnd end = getLocalPublisherCircuitEnd();
+
+ end.send(createTestMessage(end));
+
+ if (rollback)
+ {
+ end.getSession().rollback();
+ }
+ else if (transactional)
+ {
+ end.getSession().commit();
+ }
+ }
+ catch (JMSException e)
+ {
+ exceptionMonitor.onException(e);
+ }
+ }
+
+ /// <summary>
+ /// Runs the default test procedure against the circuit, and checks that all of the specified assertions hold. The
+ /// outline of the default test procedure is:
+ ///
+ /// <p/><pre>
+ /// Start the circuit.
+ /// Send test messages.
+ /// Request a status report.
+ /// Assert conditions on the publishing end of the circuit.
+ /// Assert conditions on the receiving end of the circuit.
+ /// Close the circuit.
+ /// Pass with no failed assertions or fail with a list of failed assertions.
+ /// </pre>
+ /// </summary>
+ /// <param name="numMessages"> The number of messages to send using the default test procedure. </param>
+ /// <param name="assertions"> The list of assertions to apply. </param>
+ /// <return> Any assertions that failed. </return>
+ public IList<Assertion> test(int numMessages, List<Assertion> assertions)
+ {
+ // Start the test circuit.
+ start();
+
+ // Send the requested number of test messages.
+ for (int i = 0; i < numMessages; i++)
+ {
+ send();
+ }
+
+ // Inject a short pause to allow time for exceptions to come back asynchronously.
+ TestUtils.pause(500L);
+
+ // Request a status report.
+ check();
+
+ // Clean up the publisher/receivers/controlSession/connections.
+ close();
+
+ // Apply all of the requested assertions, keeping record of any that fail.
+ IList<Assertion> failures = applyAssertions(assertions);
+
+ // Return any failed assertions to the caller.
+ return failures;
+ }
+
+ /// <summary>
+ /// Creates a message with the properties defined as per the test parameters.
+ /// </summary>
+ /// <param name="client"> The circuit end to create the message on. </param>
+ ///
+ /// <return> The test message. </return>
+ ///
+ /// <exception cref="JMSException"> Any JMSException occurring during creation of the message is allowed to fall through. </exception>
+ private Message createTestMessage(CircuitEnd client) throws JMSException
+ {
+ // Cast the test properties into a typed interface for convenience.
+ MessagingTestConfigProperties props = new MessagingTestConfigProperties(testProps);
+
+ return TestUtils.createTestMessageOfSize(client.getSession(), props.getMessageSize());
+ }
+
+ /// <summary>
+ /// Gets the exception monitor for the publishing ends connection.
+ /// </summary>
+ /// <return> The exception monitor for the publishing ends connection. </return>
+ public ExceptionMonitor getConnectionExceptionMonitor()
+ {
+ return connectionExceptionMonitor;
+ }
+
+ /// <summary>
+ /// Gets the exception monitor for the publishing ends controlSession.
+ /// </summary>
+ /// <return> The exception monitor for the publishing ends controlSession. </return>
+ public ExceptionMonitor getExceptionMonitor()
+ {
+ return exceptionMonitor;
+ }
+ }
+}
+/*
+ *
+ * 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.
+ *
+ */
+using Apache.Qpid.Integration.Tests.framework.*;
+
+using uk.co.thebadgerset.junit.extensions.util.ParsedProperties;
+
+using javax.jms.MessageConsumer;
+using javax.jms.MessageProducer;
+using javax.jms.Session;
+
+namespace Apache.Qpid.Integration.Tests.framework.localcircuit
+{
+ /// <summary>
+ /// Provides an implementation of the <see cref="Publisher"/> interface and wraps a single message producer and consumer on
+ /// a single controlSession, as a <see cref="CircuitEnd"/>. A local publisher also acts as a circuit end, because for a locally
+ /// located circuit the assertions may be applied directly, there does not need to be any inter-process messaging
+ /// between the publisher and its single circuit end, in order to ascertain its status.
+ ///
+ /// <p/><table id="crc"><caption>CRC Card</caption>
+ /// <tr><th> Responsibilities <th> Collaborations
+ /// <tr><td> Provide a message producer for sending messages.
+ /// <tr><td> Provide a message consumer for receiving messages.
+ /// <tr><td> Provide assertion that the publisher received no exceptions.
+ /// <tr><td> Provide assertion that the publisher received a no consumers error code.
+ /// <tr><td> Provide assertion that the publisher received a no route error code.
+ /// </table>
+ /// </summary>
+ public class LocalPublisherImpl extends CircuitEndBase : Publisher
+ {
+ /// <summary> Holds a reference to the containing circuit. </summary>
+ protected LocalCircuitImpl circuit;
+
+ /// <summary>
+ /// Creates a circuit end point on the specified producer, consumer and controlSession. Monitors are also configured
+ /// for messages and exceptions received by the circuit end.
+ /// </summary>
+ /// <param name="producer"> The message producer for the circuit end point. </param>
+ /// <param name="consumer"> The message consumer for the circuit end point. </param>
+ /// <param name="session"> The controlSession for the circuit end point. </param>
+ /// <param name="messageMonitor"> The monitor to notify of all messages received by the circuit end. </param>
+ /// <param name="exceptionMonitor"> The monitor to notify of all exceptions received by the circuit end. </param>
+ public LocalPublisherImpl(MessageProducer producer, MessageConsumer consumer, Session session,
+ MessageMonitor messageMonitor, ExceptionMonitor exceptionMonitor)
+ {
+ super(producer, consumer, session, messageMonitor, exceptionMonitor);
+ }
+
+ /// <summary>
+ /// Creates a circuit end point from the producer, consumer and controlSession in a circuit end base implementation.
+ /// </summary>
+ /// <param name="end"> The circuit end base implementation to take producers and consumers from. </param>
+ public LocalPublisherImpl(CircuitEndBase end)
+ {
+ super(end.getProducer(), end.getConsumer(), end.getSession(), end.getMessageMonitor(), end.getExceptionMonitor());
+ }
+
+ /// <summary> Provides an assertion that the publisher encountered no exceptions. </summary>
+ ///
+ /// <param name="testProps"> The test configuration properties. </param>
+ ///
+ /// <return> An assertion that the publisher encountered no exceptions. </return>
+ public Assertion noExceptionsAssertion(ParsedProperties testProps)
+ {
+ return new AssertionBase()
+ {
+ public bool apply()
+ {
+ bool passed = true;
+ ExceptionMonitor sessionExceptionMonitor = circuit.getExceptionMonitor();
+ ExceptionMonitor connectionExceptionMonitor = circuit.getConnectionExceptionMonitor();
+
+ if (!connectionExceptionMonitor.assertNoExceptions())
+ {
+ passed = false;
+
+ addError("Was expecting no exceptions.\n");
+ addError("Got the following exceptions on the connection, "
+ + circuit.getConnectionExceptionMonitor());
+ }
+
+ if (!sessionExceptionMonitor.assertNoExceptions())
+ {
+ passed = false;
+
+ addError("Was expecting no exceptions.\n");
+ addError("Got the following exceptions on the producer, " + circuit.getExceptionMonitor());
+ }
+
+ return passed;
+ }
+ };
+ }
+
+ /// <summary>
+ /// Provides an assertion that the AMQP channel was forcibly closed by an error condition.
+ /// </summary>
+ /// <param name="testProps"> The test configuration properties. </param>
+ ///
+ /// <return> An assertion that the AMQP channel was forcibly closed by an error condition. </return>
+ public Assertion channelClosedAssertion(ParsedProperties testProps)
+ {
+ return new NotApplicableAssertion(testProps);
+ }
+
+ /// <summary>
+ /// Provides an assertion that the publisher got a given exception during the test.
+ /// </summary>
+ /// <param name="testProps"> The test configuration properties. </param>
+ /// <param name="exceptionClass"> The exception class to check for. </param>
+ ///
+ /// <return> An assertion that the publisher got a given exception during the test. </return>
+ public Assertion exceptionAssertion(ParsedProperties testProps, final Class<? extends Exception> exceptionClass)
+ {
+ return new AssertionBase()
+ {
+ public bool apply()
+ {
+ bool passed = true;
+ ExceptionMonitor connectionExceptionMonitor = circuit.getConnectionExceptionMonitor();
+
+ if (!connectionExceptionMonitor.assertExceptionOfType(exceptionClass))
+ {
+ passed = false;
+
+ addError("Was expecting linked exception type " + exceptionClass.getName()
+ + " on the connection.\n");
+ addError((connectionExceptionMonitor.size() > 0)
+ ? ("Actually got the following exceptions on the connection, " + connectionExceptionMonitor)
+ : "Got no exceptions on the connection.");
+ }
+
+ return passed;
+ }
+ };
+ }
+
+ /// <summary>
+ /// Sets the contianing circuit.
+ /// </summary>
+ /// <param name="circuit"> The containing circuit. </param>
+ public void setCircuit(LocalCircuitImpl circuit)
+ {
+ this.circuit = circuit;
+ }
+ }
+}
+/*
+ *
+ * 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.
+ *
+ */
+using Apache.Qpid.Integration.Tests.framework.*;
+
+using uk.co.thebadgerset.junit.extensions.util.ParsedProperties;
+
+using javax.jms.MessageConsumer;
+using javax.jms.MessageProducer;
+using javax.jms.Session;
+
+namespace Apache.Qpid.Integration.Tests.framework.localcircuit
+{
+ /// <summary>
+ /// Provides an implementation of the <see cref="Receiver"/> interface that wraps a single message producer and consumer on
+ /// a single controlSession, as a <see cref="CircuitEnd"/>. A local receiver also acts as a circuit end, because for a locally
+ /// located circuit the assertions may be applied directly, there does not need to be any inter process messaging
+ /// between the publisher and its single circuit end, in order to ascertain its status.
+ ///
+ /// <p/><table id="crc"><caption>CRC Card</caption>
+ /// <tr><th> Responsibilities <th> Collaborations
+ /// <tr><td> Provide a message producer for sending messages.
+ /// <tr><td> Provide a message consumer for receiving messages.
+ /// <tr><td> Provide assertion that the receivers received no exceptions.
+ /// <tr><td> Provide assertion that the receivers received all test messages sent to it.
+ /// </table>
+ /// </summary>
+ public class LocalReceiverImpl extends CircuitEndBase : Receiver
+ {
+ /// <summary> Holds a reference to the containing circuit. </summary>
+ private LocalCircuitImpl circuit;
+
+ /// <summary>
+ /// Creates a circuit end point on the specified producer, consumer and controlSession. Monitors are also configured
+ /// for messages and exceptions received by the circuit end.
+ /// </summary>
+ /// <param name="producer"> The message producer for the circuit end point. </param>
+ /// <param name="consumer"> The message consumer for the circuit end point. </param>
+ /// <param name="session"> The controlSession for the circuit end point. </param>
+ /// <param name="messageMonitor"> The monitor to notify of all messages received by the circuit end. </param>
+ /// <param name="exceptionMonitor"> The monitor to notify of all exceptions received by the circuit end. </param>
+ public LocalReceiverImpl(MessageProducer producer, MessageConsumer consumer, Session session,
+ MessageMonitor messageMonitor, ExceptionMonitor exceptionMonitor)
+ {
+ super(producer, consumer, session, messageMonitor, exceptionMonitor);
+ }
+
+ /// <summary>
+ /// Creates a circuit end point from the producer, consumer and controlSession in a circuit end base implementation.
+ /// </summary>
+ /// <param name="end"> The circuit end base implementation to take producers and consumers from. </param>
+ public LocalReceiverImpl(CircuitEndBase end)
+ {
+ super(end.getProducer(), end.getConsumer(), end.getSession(), end.getMessageMonitor(), end.getExceptionMonitor());
+ }
+
+ /// <summary>
+ /// Provides an assertion that the receivers encountered no exceptions.
+ /// </summary>
+ /// <param name="testProps"> The test configuration properties. </param>
+ ///
+ /// <return> An assertion that the receivers encountered no exceptions. </return>
+ public Assertion noExceptionsAssertion(ParsedProperties testProps)
+ {
+ return new NotApplicableAssertion(testProps);
+ }
+
+ /// <summary>
+ /// Provides an assertion that the AMQP channel was forcibly closed by an error condition.
+ /// </summary>
+ /// <param name="testProps"> The test configuration properties. </param>
+ ///
+ /// <return> An assertion that the AMQP channel was forcibly closed by an error condition. </return>
+ public Assertion channelClosedAssertion(ParsedProperties testProps)
+ {
+ return new NotApplicableAssertion(testProps);
+ }
+
+ /// <summary>
+ /// Provides an assertion that the receivers got all messages that were sent to it.
+ /// </summary>
+ /// <param name="testProps"> The test configuration properties. </param>
+ ///
+ /// <return> An assertion that the receivers got all messages that were sent to it. </return>
+ public Assertion allMessagesReceivedAssertion(ParsedProperties testProps)
+ {
+ return new NotApplicableAssertion(testProps);
+ }
+
+ /// <summary>
+ /// Provides an assertion that the receivers got none of the messages that were sent to it.
+ /// </summary>
+ /// <param name="testProps"> The test configuration properties. </param>
+ ///
+ /// <return> An assertion that the receivers got none of the messages that were sent to it. </return>
+ public Assertion noMessagesReceivedAssertion(ParsedProperties testProps)
+ {
+ return new NotApplicableAssertion(testProps);
+ }
+
+ /// <summary>
+ /// Provides an assertion that the receiver got a given exception during the test.
+ /// </summary>
+ /// <param name="testProps"> The test configuration properties. </param>
+ /// <param name="exceptionClass"> The exception class to check for. <return> An assertion that the receiver got a given exception during the test. </return> </param>
+ public Assertion exceptionAssertion(ParsedProperties testProps, Class<? extends Exception> exceptionClass)
+ {
+ return new NotApplicableAssertion(testProps);
+ }
+
+ /// <summary>
+ /// Sets the contianing circuit.
+ /// </summary>
+ /// <param name="circuit"> The containing circuit. </param>
+ public void setCircuit(LocalCircuitImpl circuit)
+ {
+ this.circuit = circuit;
+ }
+ }
+}
+/*
+ *
+ * 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.
+ *
+ */
+using log4net;
+
+using Apache.Qpid.Integration.Tests.framework.localcircuit.LocalCircuitImpl;
+using Apache.Qpid.Integration.Tests.framework.localcircuit.LocalPublisherImpl;
+using Apache.Qpid.Integration.Tests.framework.localcircuit.LocalReceiverImpl;
+using Apache.Qpid.Integration.Tests.framework.sequencers.CircuitFactory;
+using org.apache.qpid.util.ConversationFactory;
+
+using uk.co.thebadgerset.junit.extensions.util.ParsedProperties;
+
+using javax.jms.*;
+
+using System.Collections.Generic.IList;
+using java.util.Properties;
+using java.util.concurrent.atomic.AtomicLong;
+
+namespace Apache.Qpid.Integration.Tests.framework
+{
+ /// <summary>
+ /// LocalCircuitFactory is a circuit factory that creates test circuits with publishing and receiving ends rooted
+ /// on the same JVM. The ends of the circuit are presented as <see cref="Publisher"/> and <see cref="Receiver"/> interfaces, which
+ /// in turn provide methods to apply assertions to the circuit. The creation of the circuit ends, and the presentation
+ /// of the ends as publisher/receiver interfaces, are designed to be overriden, so that circuits and assertions that
+ /// use messaging features not available in JMS can be written. This provides an extension point for writing tests
+ /// against proprietary features of JMS implementations.
+ ///
+ /// <p/><table id="crc"><caption>CRC Card</caption>
+ /// <tr><th> Responsibilities <th> Collaborations
+ /// <tr><td> Provide a standard test procedure over a test circuit.
+ /// <tr><td> Construct test circuits appropriate to a tests context.
+ /// </table>
+ /// </summary>
+ public class LocalCircuitFactory : CircuitFactory
+ {
+ /// <summary> Used for debugging. </summary>
+ private static ILog log = LogManager.GetLogger(typeof(LocalCircuitFactory));
+
+ /// <summary> Used to create unique destination names for each test. </summary>
+ protected static AtomicLong uniqueDestsId = new AtomicLong();
+
+ /// <summary>
+ /// Holds a test coordinating conversation with the test clients. This should consist of assigning the test roles,
+ /// begining the test and gathering the test reports from the participants.
+ /// </summary>
+ /// <param name="testCircuit"> The test circuit. </param>
+ /// <param name="assertions"> The list of assertions to apply to the test circuit. </param>
+ /// <param name="testProperties"> The test case definition. </param>
+ public void sequenceTest(Circuit testCircuit, IList<Assertion> assertions, Properties testProperties)
+ {
+ FrameworkBaseCase.assertNoFailures(testCircuit.test(1, assertions));
+ }
+
+ /// <summary>
+ /// Creates a test circuit for the test, configered by the test parameters specified.
+ /// </summary>
+ /// <param name="testProperties"> The test parameters. </param>
+ ///
+ /// <return> A test circuit. </return>
+ public Circuit createCircuit(ParsedProperties testProperties)
+ {
+ Circuit result;
+
+ // Cast the test properties into a typed interface for convenience.
+ MessagingTestConfigProperties props = new MessagingTestConfigProperties(testProperties);
+
+ // Create a standard publisher/receivers test client pair on a shared connection, individual sessions.
+ try
+ {
+ // Get a unique offset to append to destination names to make them unique to the connection.
+ long uniqueId = uniqueDestsId.incrementAndGet();
+
+ // Set up the connection.
+ Connection connection = TestUtils.createConnection(testProperties);
+
+ // Add the connection exception listener to assert on exception conditions with.
+ // ExceptionMonitor exceptionMonitor = new ExceptionMonitor();
+ // connection.setExceptionListener(exceptionMonitor);
+
+ // Set up the publisher.
+ CircuitEndBase publisherEnd = createPublisherCircuitEnd(connection, props, uniqueId);
+
+ // Set up the receiver.
+ CircuitEndBase receiverEnd = createReceiverCircuitEnd(connection, props, uniqueId);
+
+ // Start listening for incoming messages.
+ connection.start();
+
+ // Namespace everything up.
+ LocalPublisherImpl publisher = createPublisherFromCircuitEnd(publisherEnd);
+ LocalReceiverImpl receiver = createReceiverFromCircuitEnd(receiverEnd);
+
+ result = new LocalCircuitImpl(testProperties, publisher, receiver, connection, publisher.getExceptionMonitor());
+ }
+ catch (JMSException e)
+ {
+ throw new RuntimeException("Could not create publisher/receivers pair due to a JMSException.", e);
+ }
+
+ return result;
+ }
+
+ /// <summary>
+ /// Creates a local <see cref="Receiver"/> from a <see cref="CircuitEnd"/>. Sub-classes may override this to provide more
+ /// specialized receivers if necessary.
+ /// </summary>
+ /// <param name="receiverEnd"> The receiving circuit end. </param>
+ ///
+ /// <return> A <see cref="Receiver"/>. </return>
+ protected LocalReceiverImpl createReceiverFromCircuitEnd(CircuitEndBase receiverEnd)
+ {
+ return new LocalReceiverImpl(receiverEnd);
+ }
+
+ /// <summary>
+ /// Creates a local <see cref="Publisher"/> from a <see cref="CircuitEnd"/>. Sub-classes may override this to provide more
+ /// specialized receivers if necessary.
+ /// </summary>
+ /// <param name="publisherEnd"> The publishing circuit end. </param>
+ ///
+ /// <return> A <see cref="Receiver"/>. </return>
+ protected LocalPublisherImpl createPublisherFromCircuitEnd(CircuitEndBase publisherEnd)
+ {
+ return new LocalPublisherImpl(publisherEnd);
+ }
+
+ /// <summary>
+ /// Builds a circuit end suitable for the publishing side of a test circuit, from standard test parameters.
+ /// </summary>
+ /// <param name="connection"> The connection to build the circuit end on. </param>
+ /// <param name="testProps"> The test parameters to configure the circuit end construction. </param>
+ /// <param name="uniqueId"> A unique number to being numbering destinations from, to make this circuit unique. </param>
+ ///
+ /// <return> A circuit end suitable for the publishing side of a test circuit. </return>
+ ///
+ /// <exception cref="JMSException"> Any underlying JMSExceptions are allowed to fall through and fail the creation. </exception>
+ public CircuitEndBase createPublisherCircuitEnd(Connection connection, ParsedProperties testProps, long uniqueId)
+ throws JMSException
+ {
+ log.debug(
+ "public CircuitEndBase createPublisherCircuitEnd(Connection connection, ParsedProperties testProps, long uniqueId = "
+ + uniqueId + "): called");
+
+ // Cast the test properties into a typed interface for convenience.
+ MessagingTestConfigProperties props = new MessagingTestConfigProperties(testProps);
+
+ // Check that the test properties do not contain AMQP/Qpid specific settings, and fail if they do.
+ if (props.getImmediate() || props.getMandatory())
+ {
+ throw new RuntimeException(
+ "Cannot create a pure JMS circuit as the test properties require AMQP specific options.");
+ }
+
+ Session session = connection.createSession(props.getPublisherTransacted(), props.getAckMode());
+
+ Destination destination =
+ props.getPubsub() ? session.createTopic(props.getSendDestinationNameRoot() + "_" + uniqueId)
+ : session.createQueue(props.getSendDestinationNameRoot() + "_" + uniqueId);
+
+ MessageProducer producer = props.getPublisherProducerBind() ? session.createProducer(destination) : null;
+
+ MessageConsumer consumer =
+ props.getPublisherConsumerBind()
+ ? session.createConsumer(session.createQueue(props.getReceiveDestinationNameRoot() + "_" + uniqueId)) : null;
+
+ MessageMonitor messageMonitor = new MessageMonitor();
+
+ if (consumer != null)
+ {
+ consumer.setMessageListener(messageMonitor);
+ }
+
+ ExceptionMonitor exceptionMonitor = new ExceptionMonitor();
+ connection.setExceptionListener(exceptionMonitor);
+
+ if (!props.getPublisherConsumerActive() && (consumer != null))
+ {
+ consumer.close();
+ }
+
+ return new CircuitEndBase(producer, consumer, session, messageMonitor, exceptionMonitor);
+ }
+
+ /// <summary>
+ /// Builds a circuit end suitable for the receiving side of a test circuit, from standard test parameters.
+ /// </summary>
+ /// <param name="connection"> The connection to build the circuit end on. </param>
+ /// <param name="testProps"> The test parameters to configure the circuit end construction. </param>
+ /// <param name="uniqueId"> A unique number to being numbering destinations from, to make this circuit unique. </param>
+ ///
+ /// <return> A circuit end suitable for the receiving side of a test circuit. </return>
+ ///
+ /// <exception cref="JMSException"> Any underlying JMSExceptions are allowed to fall through and fail the creation. </exception>
+ public CircuitEndBase createReceiverCircuitEnd(Connection connection, ParsedProperties testProps, long uniqueId)
+ throws JMSException
+ {
+ log.debug(
+ "public CircuitEndBase createReceiverCircuitEnd(Connection connection, ParsedProperties testProps, long uniqueId = "
+ + uniqueId + "): called");
+
+ // Cast the test properties into a typed interface for convenience.
+ MessagingTestConfigProperties props = new MessagingTestConfigProperties(testProps);
+
+ // Check that the test properties do not contain AMQP/Qpid specific settings, and fail if they do.
+ if (props.getImmediate() || props.getMandatory())
+ {
+ throw new RuntimeException(
+ "Cannot create a pure JMS circuit as the test properties require AMQP specific options.");
+ }
+
+ Session session = connection.createSession(props.getPublisherTransacted(), props.getAckMode());
+
+ MessageProducer producer =
+ props.getReceiverProducerBind()
+ ? session.createProducer(session.createQueue(props.getReceiveDestinationNameRoot() + "_" + uniqueId)) : null;
+
+ Destination destination =
+ props.getPubsub() ? session.createTopic(props.getSendDestinationNameRoot() + "_" + uniqueId)
+ : session.createQueue(props.getSendDestinationNameRoot() + "_" + uniqueId);
+
+ MessageConsumer consumer =
+ props.getReceiverConsumerBind()
+ ? ((props.getDurableSubscription() && props.getPubsub())
+ ? session.createDurableSubscriber((Topic) destination, "testsub") : session.createConsumer(destination))
+ : null;
+
+ MessageMonitor messageMonitor = new MessageMonitor();
+
+ if (consumer != null)
+ {
+ consumer.setMessageListener(messageMonitor);
+ }
+
+ if (!props.getReceiverConsumerActive() && (consumer != null))
+ {
+ consumer.close();
+ }
+
+ return new CircuitEndBase(producer, consumer, session, messageMonitor, null);
+ }
+
+ /// <summary>
+ /// Sets the sender test client to coordinate the test with.
+ /// </summary>
+ /// <param name="sender"> The contact details of the sending client in the test. </param>
+ public void setSender(TestClientDetails sender)
+ {
+ throw new RuntimeException("Not implemented.");
+ }
+
+ /// <summary>
+ /// Sets the receiving test client to coordinate the test with.
+ /// </summary>
+ /// <param name="receiver"> The contact details of the sending client in the test. </param>
+ public void setReceiver(TestClientDetails receiver)
+ {
+ throw new RuntimeException("Not implemented.");
+ }
+
+ /// <summary>
+ /// Supplies the sending test client.
+ /// </summary>
+ /// <return> The sending test client. </return>
+ public TestClientDetails getSender()
+ {
+ throw new RuntimeException("Not implemented.");
+ }
+
+ /// <summary>
+ /// Supplies the receiving test client.
+ /// </summary>
+ /// <return> The receiving test client. </return>
+ public IList<TestClientDetails> getReceivers()
+ {
+ throw new RuntimeException("Not implemented.");
+ }
+
+ /// <summary>
+ /// Accepts the conversation factory over which to hold the test coordinating conversation.
+ /// </summary>
+ /// <param name="conversationFactory"> The conversation factory to coordinate the test over. </param>
+ public void setConversationFactory(ConversationFactory conversationFactory)
+ {
+ throw new RuntimeException("Not implemented.");
+ }
+ }
+}
+/*
+ *
+ * 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.
+ *
+ */
+namespace Apache.Qpid.Integration.Tests.framework
+{
+ /// <summary>
+ /// MessageIdentityVector provides a message identification scheme, that matches individual messages with test cases.
+ /// Test messages are being sent by a number of test clients, sending messages over a set of routes, and being received
+ /// by another set of test clients. Each test is itself, being run within a test cycle, of which there could be many. It
+ /// is the job of the test coordinator to request and receive reports from the available test clients, on what has been
+ /// sent, what has been received, and what errors may have occurred, and to reconcile this information against the
+ /// assertions being applied by the test case. In order to be able to figure out which messages belong to which test,
+ /// there needs to be an identification scheme, that the coordinator can use to correlate messages in senders and
+ /// receiver reports. Every message sent in a test can be associated with this information.
+ ///
+ /// <p/><table id="crc"><caption>CRC Card</caption>
+ /// <tr><th> Responsibilities <th> Collaborations
+ /// <tr><td> Identify a test case, a handling client id, a circuit end within the client, and a test cycle number.
+ /// </table>
+ /// </summary>
+ public class MessageIdentityVector
+ {
+ /// <summary> Holds the test case vector component of the message identity vector. </summary>
+ private TestCaseVector testCaseVector;
+
+ /// <summary> The unique client id. </summary>
+ private string clientId;
+
+ /// <summary> The unique circuit end number within the client id. </summary>
+ private int circuitEndId;
+
+ /// <summary>
+ /// Creates a new identity vector for test messages.
+ /// </summary>
+ /// <param name="testCase"> The name of the test case generating the messages. </param>
+ /// <param name="clientId"> The unique id of the client implementing a circuit end that is handling the messages. </param>
+ /// <param name="circuitEndId"> The unique id number of the circuit end within the client. </param>
+ /// <param name="testCycleNumber"> The cycle iteration number of the test case. </param>
+ public MessageIdentityVector(string testCase, string clientId, int circuitEndId, int testCycleNumber)
+ {
+ this.testCaseVector = new TestCaseVector(testCase, testCycleNumber);
+ this.clientId = clientId;
+ this.circuitEndId = circuitEndId;
+ }
+
+ /// <summary>
+ /// Reports the test case vector component of the message identity vector.
+ /// </summary>
+ /// <return> The test case vector component of the message identity vector. </return>
+ public TestCaseVector getTestCaseVector()
+ {
+ return testCaseVector;
+ }
+
+ /// <summary>
+ /// Reports the name of the test case.
+ /// </summary>
+ /// <return> The name of the test case. </return>
+ public string getTestCase()
+ {
+ return testCaseVector.getTestCase();
+ }
+
+ /// <summary>
+ /// Reports the test iteration cycle number within the test case.
+ /// </summary>
+ /// <return> The test iteration cycle number within the test case. </return>
+ public int getTestCycleNumber()
+ {
+ return testCaseVector.getTestCycleNumber();
+ }
+
+ /// <summary>
+ /// Resports the client id.
+ /// </summary>
+ /// <return> The client id. </return>
+ public string getClientId()
+ {
+ return clientId;
+ }
+
+ /// <summary>
+ /// Reports the circuit end number within the test client.
+ /// </summary>
+ /// <return> The circuit end number within the test client. </return>
+ public int getCircuitEndId()
+ {
+ return circuitEndId;
+ }
+
+ /// <summary>
+ /// Compares this identity vector with another for equality. All fields must match.
+ /// </summary>
+ /// <param name="o"> The identity vector to compare with. </param>
+ ///
+ /// <return> <tt>true</tt> if the identity vector is identical to this one by all fields, <tt>false</tt> otherwise. </return>
+ public bool equals(Object o)
+ {
+ if (this == o)
+ {
+ return true;
+ }
+
+ if ((o == null) || (getClass() != o.getClass()))
+ {
+ return false;
+ }
+
+ MessageIdentityVector that = (MessageIdentityVector) o;
+
+ if (circuitEndId != that.circuitEndId)
+ {
+ return false;
+ }
+
+ if ((clientId != null) ? (!clientId.equals(that.clientId)) : (that.clientId != null))
+ {
+ return false;
+ }
+
+ if ((testCaseVector != null) ? (!testCaseVector.equals(that.testCaseVector)) : (that.testCaseVector != null))
+ {
+ return false;
+ }
+
+ return true;
+ }
+
+ /// <summary>
+ /// Computes a hash code for this identity vector based on all fields.
+ /// </summary>
+ /// <return> A hash code for this identity vector based on all fields. </return>
+ public int hashCode()
+ {
+ int result;
+ result = ((testCaseVector != null) ? testCaseVector.hashCode() : 0);
+ result = (31 * result) + ((clientId != null) ? clientId.hashCode() : 0);
+ result = (31 * result) + circuitEndId;
+
+ return result;
+ }
+ }
+}
+/*
+ *
+ * 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.
+ *
+ */
+using log4net;
+
+using javax.jms.Message;
+using javax.jms.MessageListener;
+
+using java.util.concurrent.atomic.AtomicInteger;
+
+namespace Apache.Qpid.Integration.Tests.framework
+{
+ /// <summary>
+ /// MessageMonitor is used to record information about messages received. This will provide methods to check various
+ /// properties, such as the type, number and content of messages received in order to verify the correct behaviour of
+ /// tests.
+ ///
+ /// <p/><table id="crc"><caption>CRC Card</caption>
+ /// <tr><th> Responsibilities <th> Collaborations
+ /// <tr><td> Count incoming messages.
+ /// <tr><td> Record time ellapsed since the arrival of the first message.
+ /// <tr><td> Reset all counts and timings.
+ /// </table>
+ /// </summary>
+ public class MessageMonitor : MessageListener
+ {
+ /// <summary> Used for debugging. </summary>
+ private static ILog log = LogManager.GetLogger(typeof(MessageMonitor));
+
+ /// <summary> Holds the count of messages received since the last query. </summary>
+ protected AtomicInteger numMessages = new AtomicInteger();
+
+ /// <summary> Holds the time of arrival of the first message. </summary>
+ protected Long firstMessageTime = null;
+
+ /// <summary>
+ /// Handles received messages. Does Nothing.
+ /// </summary>
+ /// <param name="message"> The message. Ignored. </param>
+ public void onMessage(Message message)
+ {
+ // log.debug("public void onMessage(Message message): called");
+
+ numMessages.getAndIncrement();
+ }
+
+ /// <summary>
+ /// Gets the count of messages.
+ /// </summary>
+ /// <return> The count of messages. </return>
+ public int getNumMessage()
+ {
+ if (firstMessageTime == null)
+ {
+ firstMessageTime = System.nanoTime();
+ }
+
+ return numMessages.get();
+ }
+
+ /// <summary>
+ /// Gets the time elapsed since the first message arrived, in nanos, or zero if no messages have arrived yet.
+ /// </summary>
+ /// <return> The time elapsed since the first message arrived, in nanos, or zero if no messages have arrived yet. </return>
+ public long getTime()
+ {
+ if (firstMessageTime != null)
+ {
+ return System.nanoTime() - firstMessageTime;
+ }
+ else
+ {
+ return 0L;
+ }
+ }
+
+ /// <summary> Resets the message count and timer to zero. </summary>
+ public void reset()
+ {
+ numMessages.set(0);
+ firstMessageTime = null;
+ }
+ }
+}
+/*
+ *
+ * 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.
+ *
+ */
+using uk.co.thebadgerset.junit.extensions.util.ParsedProperties;
+
+using javax.jms.Session;
+
+using java.util.Properties;
+
+namespace Apache.Qpid.Integration.Tests.framework
+{
+ /// <summary>
+ /// MessagingTestConfigProperties defines a set of property names and default values for specifying a messaging topology,
+ /// and test parameters for running a messaging test over that topology. A Properties object holding some of these
+ /// properties, superimposed onto the defaults, is used to establish test topologies and control test behaviour.
+ ///
+ /// <p/>A complete list of the parameters, default values and comments on their usage is provided here:
+ ///
+ /// <p/><table><caption>Parameters</caption>
+ /// <tr><th> Parameter <th> Default <th> Comments
+ /// <tr><td> messageSize <td> 0 <td> Message size in bytes. Not including any headers.
+ /// <tr><td> destinationName <td> ping <td> The root name to use to generate destination names to ping.
+ /// <tr><td> persistent <td> false <td> Determines whether peristent delivery is used.
+ /// <tr><td> transacted <td> false <td> Determines whether messages are sent/received in transactions.
+ /// <tr><td> broker <td> tcp://localhost:5672 <td> Determines the broker to connect to.
+ /// <tr><td> virtualHost <td> test <td> Determines the virtual host to send all ping over.
+ /// <tr><td> rate <td> 0 <td> The maximum rate (in hertz) to send messages at. 0 means no limit.
+ /// <tr><td> verbose <td> false <td> The verbose flag for debugging. Prints to console on every message.
+ /// <tr><td> pubsub <td> false <td> Whether to ping topics or queues. Uses p2p by default.
+ /// <tr><td> username <td> guest <td> The username to access the broker with.
+ /// <tr><td> password <td> guest <td> The password to access the broker with.
+ /// <tr><td> selector <td> null <td> Not used. Defines a message selector to filter pings with.
+ /// <tr><td> destinationCount <td> 1 <td> The number of receivers listening to the pings.
+ /// <tr><td> timeout <td> 30000 <td> In milliseconds. The timeout to stop waiting for replies.
+ /// <tr><td> commitBatchSize <td> 1 <td> The number of messages per transaction in transactional mode.
+ /// <tr><td> uniqueDests <td> true <td> Whether each receivers only listens to one ping destination or all.
+ /// <tr><td> durableDests <td> false <td> Whether or not durable destinations are used.
+ /// <tr><td> ackMode <td> AUTO_ACK <td> The message acknowledgement mode. Possible values are:
+ /// 0 - SESSION_TRANSACTED
+ /// 1 - AUTO_ACKNOWLEDGE
+ /// 2 - CLIENT_ACKNOWLEDGE
+ /// 3 - DUPS_OK_ACKNOWLEDGE
+ /// 257 - NO_ACKNOWLEDGE
+ /// 258 - PRE_ACKNOWLEDGE
+ /// <tr><td> maxPending <td> 0 <td> The maximum size in bytes, of messages sent but not yet received.
+ /// Limits the volume of messages currently buffered on the client
+ /// or broker. Can help scale test clients by limiting amount of buffered
+ /// data to avoid out of memory errors.
+ /// </table>
+ ///
+ /// <p><table id="crc"><caption>CRC Card</caption>
+ /// <tr><th> Responsibilities <th> Collaborations
+ /// <tr><td> Provide the names and defaults of all test parameters.
+ /// </table>
+ /// </summary>
+ ///
+ /// <remarks> Put a type-safe wrapper around these properties, but continue to store the parameters as properties. This is
+ /// simply to ensure that it is a simple matter to serialize/deserialize string/string pairs onto messages.</remarks>
+ public class MessagingTestConfigProperties extends ParsedProperties
+ {
+ // ====================== Connection Properties ==================================
+
+ /// <summary> Holds the name of the default connection configuration. </summary>
+ public static final string CONNECTION_NAME = "broker";
+
+ /// <summary> Holds the name of the property to get the initial context factory name from. </summary>
+ public static final string INITIAL_CONTEXT_FACTORY_PROPNAME = "java.naming.factory.initial";
+
+ /// <summary> Defines the class to use as the initial context factory by default. </summary>
+ public static final string INITIAL_CONTEXT_FACTORY_DEFAULT = "org.apache.qpid.jndi.PropertiesFileInitialContextFactory";
+
+ /// <summary> Holds the name of the property to get the test broker url from. </summary>
+ public static final string BROKER_PROPNAME = "qpid.test.broker";
+
+ /// <summary> Holds the default broker url for the test. </summary>
+ public static final string BROKER_DEFAULT = "vm://:1";
+
+ /// <summary> Holds the name of the property to get the test broker virtual path. </summary>
+ public static final string VIRTUAL_HOST_PROPNAME = "virtualHost";
+
+ /// <summary> Holds the default virtual path for the test. </summary>
+ public static final string VIRTUAL_HOST_DEFAULT = "";
+
+ /// <summary> Holds the name of the property to get the broker access username from. </summary>
+ public static final string USERNAME_PROPNAME = "username";
+
+ /// <summary> Holds the default broker log on username. </summary>
+ public static final string USERNAME_DEFAULT = "guest";
+
+ /// <summary> Holds the name of the property to get the broker access password from. </summary>
+ public static final string PASSWORD_PROPNAME = "password";
+
+ /// <summary> Holds the default broker log on password. </summary>
+ public static final string PASSWORD_DEFAULT = "guest";
+
+ // ====================== Messaging Topology Properties ==========================
+
+ /// <summary> Holds the name of the property to get the bind publisher procuder flag from. </summary>
+ public static final string PUBLISHER_PRODUCER_BIND_PROPNAME = "publisherProducerBind";
+
+ /// <summary> Holds the default value of the publisher producer flag. </summary>
+ public static final bool PUBLISHER_PRODUCER_BIND_DEFAULT = true;
+
+ /// <summary> Holds the name of the property to get the bind publisher procuder flag from. </summary>
+ public static final string PUBLISHER_CONSUMER_BIND_PROPNAME = "publisherConsumerBind";
+
+ /// <summary> Holds the default value of the publisher consumer flag. </summary>
+ public static final bool PUBLISHER_CONSUMER_BIND_DEFAULT = false;
+
+ /// <summary> Holds the name of the property to get the bind receivers procuder flag from. </summary>
+ public static final string RECEIVER_PRODUCER_BIND_PROPNAME = "receiverProducerBind";
+
+ /// <summary> Holds the default value of the receivers producer flag. </summary>
+ public static final bool RECEIVER_PRODUCER_BIND_DEFAULT = false;
+
+ /// <summary> Holds the name of the property to get the bind receivers procuder flag from. </summary>
+ public static final string RECEIVER_CONSUMER_BIND_PROPNAME = "receiverConsumerBind";
+
+ /// <summary> Holds the default value of the receivers consumer flag. </summary>
+ public static final bool RECEIVER_CONSUMER_BIND_DEFAULT = true;
+
+ /// <summary> Holds the name of the property to get the publishers consumer active flag from. </summary>
+ public static final string PUBLISHER_CONSUMER_ACTIVE_PROPNAME = "publisherConsumerActive";
+
+ /// <summary> Holds the default value of the publishers consumer active flag. </summary>
+ public static final bool PUBLISHER_CONSUMER_ACTIVE_DEFAULT = true;
+
+ /// <summary> Holds the name of the property to get the receivers consumer active flag from. </summary>
+ public static final string RECEIVER_CONSUMER_ACTIVE_PROPNAME = "receiverConsumerActive";
+
+ /// <summary> Holds the default value of the receivers consumer active flag. </summary>
+ public static final bool RECEIVER_CONSUMER_ACTIVE_DEFAULT = true;
+
+ /// <summary> Holds the name of the property to get the destination name root from. </summary>
+ public static final string SEND_DESTINATION_NAME_ROOT_PROPNAME = "sendDestinationRoot";
+
+ /// <summary> Holds the root of the name of the default destination to send to. </summary>
+ public static final string SEND_DESTINATION_NAME_ROOT_DEFAULT = "sendTo";
+
+ /// <summary> Holds the name of the property to get the destination name root from. </summary>
+ public static final string RECEIVE_DESTINATION_NAME_ROOT_PROPNAME = "receiveDestinationRoot";
+
+ /// <summary> Holds the root of the name of the default destination to send to. </summary>
+ public static final string RECEIVE_DESTINATION_NAME_ROOT_DEFAULT = "receiveFrom";
+
+ /// <summary> Holds the name of the proeprty to get the destination count from. </summary>
+ public static final string DESTINATION_COUNT_PROPNAME = "destinationCount";
+
+ /// <summary> Defines the default number of destinations to ping. </summary>
+ public static final int DESTINATION_COUNT_DEFAULT = 1;
+
+ /// <summary> Holds the name of the property to get the p2p or pub/sub messaging mode from. </summary>
+ public static final string PUBSUB_PROPNAME = "pubsub";
+
+ /// <summary> Holds the pub/sub mode default, true means ping a topic, false means ping a queue. </summary>
+ public static final bool PUBSUB_DEFAULT = false;
+
+ // ====================== JMS Options and Flags =================================
+
+ /// <summary> Holds the name of the property to get the test delivery mode from. </summary>
+ public static final string PERSISTENT_MODE_PROPNAME = "persistent";
+
+ /// <summary> Holds the message delivery mode to use for the test. </summary>
+ public static final bool PERSISTENT_MODE_DEFAULT = false;
+
+ /// <summary> Holds the name of the property to get the test transactional mode from. </summary>
+ public static final string TRANSACTED_PUBLISHER_PROPNAME = "transactedPublisher";
+
+ /// <summary> Holds the transactional mode to use for the test. </summary>
+ public static final bool TRANSACTED_PUBLISHER_DEFAULT = false;
+
+ /// <summary> Holds the name of the property to get the test transactional mode from. </summary>
+ public static final string TRANSACTED_RECEIVER_PROPNAME = "transactedReceiver";
+
+ /// <summary> Holds the transactional mode to use for the test. </summary>
+ public static final bool TRANSACTED_RECEIVER_DEFAULT = false;
+
+ /// <summary> Holds the name of the property to set the no local flag from. </summary>
+ public static final string NO_LOCAL_PROPNAME = "noLocal";
+
+ /// <summary> Defines the default value of the no local flag to use when consuming messages. </summary>
+ public static final bool NO_LOCAL_DEFAULT = false;
+
+ /// <summary> Holds the name of the property to get the message acknowledgement mode from. </summary>
+ public static final string ACK_MODE_PROPNAME = "ackMode";
+
+ /// <summary> Defines the default message acknowledgement mode. </summary>
+ public static final int ACK_MODE_DEFAULT = Session.AUTO_ACKNOWLEDGE;
+
+ /// <summary> Holds the name of the property to get the durable subscriptions flag from, when doing pub/sub messaging. </summary>
+ public static final string DURABLE_SUBSCRIPTION_PROPNAME = "durableSubscription";
+
+ /// <summary> Defines the default value of the durable subscriptions flag. </summary>
+ public static final bool DURABLE_SUBSCRIPTION_DEFAULT = false;
+
+ // ====================== Qpid/AMQP Options and Flags ================================
+
+ /// <summary> Holds the name of the property to set the exclusive flag from. </summary>
+ public static final string EXCLUSIVE_PROPNAME = "exclusive";
+
+ /// <summary> Defines the default value of the exclusive flag to use when consuming messages. </summary>
+ public static final bool EXCLUSIVE_DEFAULT = false;
+
+ /// <summary> Holds the name of the property to set the immediate flag from. </summary>
+ public static final string IMMEDIATE_PROPNAME = "immediate";
+
+ /// <summary> Defines the default value of the immediate flag to use when sending messages. </summary>
+ public static final bool IMMEDIATE_DEFAULT = false;
+
+ /// <summary> Holds the name of the property to set the mandatory flag from. </summary>
+ public static final string MANDATORY_PROPNAME = "mandatory";
+
+ /// <summary> Defines the default value of the mandatory flag to use when sending messages. </summary>
+ public static final bool MANDATORY_DEFAULT = false;
+
+ /// <summary> Holds the name of the property to get the durable destinations flag from. </summary>
+ public static final string DURABLE_DESTS_PROPNAME = "durableDests";
+
+ /// <summary> Default value for the durable destinations flag. </summary>
+ public static final bool DURABLE_DESTS_DEFAULT = false;
+
+ /// <summary> Holds the name of the property to set the prefetch size from. </summary>
+ public static final string PREFETCH_PROPNAME = "prefetch";
+
+ /// <summary> Defines the default prefetch size to use when consuming messages. </summary>
+ public static final int PREFETCH_DEFAULT = 100;
+
+ // ====================== Common Test Parameters ================================
+
+ /// <summary> Holds the name of the property to get the test message size from. </summary>
+ public static final string MESSAGE_SIZE_PROPNAME = "messageSize";
+
+ /// <summary> Used to set up a default message size. </summary>
+ public static final int MESSAGE_SIZE_DEAFULT = 0;
+
+ /// <summary> Holds the name of the property to get the message rate from. </summary>
+ public static final string RATE_PROPNAME = "rate";
+
+ /// <summary> Defines the default rate (in pings per second) to send pings at. 0 means as fast as possible, no restriction. </summary>
+ public static final int RATE_DEFAULT = 0;
+
+ /// <summary> Holds the name of the proeprty to get the. </summary>
+ public static final string SELECTOR_PROPNAME = "selector";
+
+ /// <summary> Holds the default message selector. </summary>
+ public static final string SELECTOR_DEFAULT = "";
+
+ /// <summary> Holds the name of the property to get the waiting timeout for response messages. </summary>
+ public static final string TIMEOUT_PROPNAME = "timeout";
+
+ /// <summary> Default time to wait before assuming that a ping has timed out. </summary>
+ public static final long TIMEOUT_DEFAULT = 30000;
+
+ /// <summary> Holds the name of the property to get the commit batch size from. </summary>
+ public static final string TX_BATCH_SIZE_PROPNAME = "commitBatchSize";
+
+ /// <summary> Defines the default number of pings to send in each transaction when running transactionally. </summary>
+ public static final int TX_BATCH_SIZE_DEFAULT = 1;
+
+ /// <summary> Holds the name of the property to set the maximum amount of pending message data for a producer to hold. </summary>
+ public static final string MAX_PENDING_PROPNAME = "maxPending";
+
+ /// <summary> Defines the default maximum quantity of pending message data to allow producers to hold. </summary>
+ public static final int MAX_PENDING_DEFAULT = 0;
+
+ /// <summary> Holds the name of the property to get the publisher rollback flag from. </summary>
+ public static final string ROLLBACK_PUBLISHER_PROPNAME = "rollbackPublisher";
+
+ /// <summary> Holds the default publisher roll back setting. </summary>
+ public static final bool ROLLBACK_PUBLISHER_DEFAULT = false;
+
+ /// <summary> Holds the name of the property to get the publisher rollback flag from. </summary>
+ public static final string ROLLBACK_RECEIVER_PROPNAME = "rollbackReceiver";
+
+ /// <summary> Holds the default publisher roll back setting. </summary>
+ public static final bool ROLLBACK_RECEIVER_DEFAULT = false;
+
+ // ====================== Options that control the bahviour of the test framework. =========================
+
+ /// <summary> Holds the name of the property to get the behavioural mode of not applicable assertions. </summary>
+ public static final string NOT_APPLICABLE_ASSERTION_PROPNAME = "notApplicableAssertion";
+
+ /// <summary> Holds the default behavioral mode of not applicable assertions, which is logging them as a warning. </summary>
+ public static final string NOT_APPLICABLE_ASSERTION_DEFAULT = "warn";
+
+ /// <summary> Holds the name of the property to get the verbose mode proeprty from. </summary>
+ public static final string VERBOSE_PROPNAME = "verbose";
+
+ /// <summary> Holds the default verbose mode. </summary>
+ public static final bool VERBOSE_DEFAULT = false;
+
+ /// <summary> Holds the default configuration properties. </summary>
+ public static ParsedProperties defaults = new ParsedProperties();
+
+ static
+ {
+ defaults.setPropertyIfNull(INITIAL_CONTEXT_FACTORY_PROPNAME, INITIAL_CONTEXT_FACTORY_DEFAULT);
+ defaults.setPropertyIfNull(BROKER_PROPNAME, BROKER_DEFAULT);
+ defaults.setPropertyIfNull(VIRTUAL_HOST_PROPNAME, VIRTUAL_HOST_DEFAULT);
+ defaults.setPropertyIfNull(USERNAME_PROPNAME, USERNAME_DEFAULT);
+ defaults.setPropertyIfNull(PASSWORD_PROPNAME, PASSWORD_DEFAULT);
+
+ defaults.setPropertyIfNull(PUBLISHER_PRODUCER_BIND_PROPNAME, PUBLISHER_PRODUCER_BIND_DEFAULT);
+ defaults.setPropertyIfNull(PUBLISHER_CONSUMER_BIND_PROPNAME, PUBLISHER_CONSUMER_BIND_DEFAULT);
+ defaults.setPropertyIfNull(RECEIVER_PRODUCER_BIND_PROPNAME, RECEIVER_PRODUCER_BIND_DEFAULT);
+ defaults.setPropertyIfNull(RECEIVER_CONSUMER_BIND_PROPNAME, RECEIVER_CONSUMER_BIND_DEFAULT);
+ defaults.setPropertyIfNull(PUBLISHER_CONSUMER_ACTIVE_PROPNAME, PUBLISHER_CONSUMER_ACTIVE_DEFAULT);
+ defaults.setPropertyIfNull(RECEIVER_CONSUMER_ACTIVE_PROPNAME, RECEIVER_CONSUMER_ACTIVE_DEFAULT);
+ defaults.setPropertyIfNull(SEND_DESTINATION_NAME_ROOT_PROPNAME, SEND_DESTINATION_NAME_ROOT_DEFAULT);
+ defaults.setPropertyIfNull(RECEIVE_DESTINATION_NAME_ROOT_PROPNAME, RECEIVE_DESTINATION_NAME_ROOT_DEFAULT);
+ defaults.setPropertyIfNull(DESTINATION_COUNT_PROPNAME, DESTINATION_COUNT_DEFAULT);
+ defaults.setPropertyIfNull(PUBSUB_PROPNAME, PUBSUB_DEFAULT);
+
+ defaults.setPropertyIfNull(PERSISTENT_MODE_PROPNAME, PERSISTENT_MODE_DEFAULT);
+ defaults.setPropertyIfNull(TRANSACTED_PUBLISHER_PROPNAME, TRANSACTED_PUBLISHER_DEFAULT);
+ defaults.setPropertyIfNull(TRANSACTED_RECEIVER_PROPNAME, TRANSACTED_RECEIVER_DEFAULT);
+ defaults.setPropertyIfNull(NO_LOCAL_PROPNAME, NO_LOCAL_DEFAULT);
+ defaults.setPropertyIfNull(ACK_MODE_PROPNAME, ACK_MODE_DEFAULT);
+ defaults.setPropertyIfNull(DURABLE_SUBSCRIPTION_PROPNAME, DURABLE_SUBSCRIPTION_DEFAULT);
+
+ defaults.setPropertyIfNull(EXCLUSIVE_PROPNAME, EXCLUSIVE_DEFAULT);
+ defaults.setPropertyIfNull(IMMEDIATE_PROPNAME, IMMEDIATE_DEFAULT);
+ defaults.setPropertyIfNull(MANDATORY_PROPNAME, MANDATORY_DEFAULT);
+ defaults.setPropertyIfNull(DURABLE_DESTS_PROPNAME, DURABLE_DESTS_DEFAULT);
+ defaults.setPropertyIfNull(PREFETCH_PROPNAME, PREFETCH_DEFAULT);
+
+ defaults.setPropertyIfNull(MESSAGE_SIZE_PROPNAME, MESSAGE_SIZE_DEAFULT);
+ defaults.setPropertyIfNull(RATE_PROPNAME, RATE_DEFAULT);
+ defaults.setPropertyIfNull(SELECTOR_PROPNAME, SELECTOR_DEFAULT);
+ defaults.setPropertyIfNull(TIMEOUT_PROPNAME, TIMEOUT_DEFAULT);
+ defaults.setPropertyIfNull(TX_BATCH_SIZE_PROPNAME, TX_BATCH_SIZE_DEFAULT);
+ defaults.setPropertyIfNull(MAX_PENDING_PROPNAME, MAX_PENDING_DEFAULT);
+ defaults.setPropertyIfNull(ROLLBACK_PUBLISHER_PROPNAME, ROLLBACK_PUBLISHER_DEFAULT);
+ defaults.setPropertyIfNull(ROLLBACK_RECEIVER_PROPNAME, ROLLBACK_RECEIVER_DEFAULT);
+
+ defaults.setPropertyIfNull(NOT_APPLICABLE_ASSERTION_PROPNAME, NOT_APPLICABLE_ASSERTION_DEFAULT);
+ defaults.setPropertyIfNull(VERBOSE_PROPNAME, VERBOSE_DEFAULT);
+ }
+
+ /// <summary> Creates a test configuration based on the defaults. </summary>
+ public MessagingTestConfigProperties()
+ {
+ super(defaults);
+ }
+
+ /// <summary>
+ /// Creates a test configuration based on the supplied properties.
+ /// </summary>
+ /// <param name="properties"> The test configuration. </param>
+ public MessagingTestConfigProperties(Properties properties)
+ {
+ super(properties);
+ }
+
+ /// <summary>
+ /// The size of test messages to send.
+ /// </summary>
+ /// <return> The size of test messages to send. </return>
+ public int getMessageSize()
+ {
+ return getPropertyAsInteger(MESSAGE_SIZE_PROPNAME);
+ }
+
+ /// <summary>
+ /// Flag to indicate that the publishing producer should be set up to publish to a destination.
+ /// </summary>
+ /// <return> Flag to indicate that the publishing producer should be set up to publish to a destination. </return>
+ public bool getPublisherProducerBind()
+ {
+ return getPropertyAsBoolean(PUBLISHER_PRODUCER_BIND_PROPNAME);
+ }
+
+ /// <summary>
+ /// Flag to indicate that the publishing consumer should be set up to receive from a destination.
+ /// </summary>
+ /// <return> Flag to indicate that the publishing consumer should be set up to receive from a destination. </return>
+ public bool getPublisherConsumerBind()
+ {
+ return getPropertyAsBoolean(PUBLISHER_CONSUMER_BIND_PROPNAME);
+ }
+
+ /// <summary>
+ /// Flag to indicate that the receiving producer should be set up to publish to a destination.
+ /// </summary>
+ /// <return> Flag to indicate that the receiving producer should be set up to publish to a destination. </return>
+ public bool getReceiverProducerBind()
+ {
+ return getPropertyAsBoolean(RECEIVER_PRODUCER_BIND_PROPNAME);
+ }
+
+ /// <summary>
+ /// Flag to indicate that the receiving consumer should be set up to receive from a destination.
+ /// </summary>
+ /// <return> Flag to indicate that the receiving consumer should be set up to receive from a destination. </return>
+ public bool getReceiverConsumerBind()
+ {
+ return getPropertyAsBoolean(RECEIVER_CONSUMER_BIND_PROPNAME);
+ }
+
+ /// <summary>
+ /// Flag to indicate that the publishing consumer should be created and actively listening.
+ /// </summary>
+ /// <return> Flag to indicate that the publishing consumer should be created. </return>
+ public bool getPublisherConsumerActive()
+ {
+ return getPropertyAsBoolean(PUBLISHER_CONSUMER_ACTIVE_PROPNAME);
+ }
+
+ /// <summary>
+ /// Flag to indicate that the receiving consumers should be created and actively listening.
+ /// </summary>
+ /// <return> Flag to indicate that the receiving consumers should be created and actively listening. </return>
+ public bool getReceiverConsumerActive()
+ {
+ return getPropertyAsBoolean(RECEIVER_CONSUMER_ACTIVE_PROPNAME);
+ }
+
+ /// <summary>
+ /// A root to create all test destination names from.
+ /// </summary>
+ /// <return> A root to create all test destination names from. </return>
+ public string getSendDestinationNameRoot()
+ {
+ return getProperty(SEND_DESTINATION_NAME_ROOT_PROPNAME);
+ }
+
+ /// <summary>
+ /// A root to create all receiving destination names from.
+ /// </summary>
+ /// <return> A root to create all receiving destination names from. </return>
+ public string getReceiveDestinationNameRoot()
+ {
+ return getProperty(RECEIVE_DESTINATION_NAME_ROOT_PROPNAME);
+ }
+
+ /// <summary>
+ /// Flag to indicate that persistent messages should be used.
+ /// </summary>
+ /// <return> Flag to indicate that persistent messages should be used. </return>
+ public bool getPersistentMode()
+ {
+ return getPropertyAsBoolean(PERSISTENT_MODE_PROPNAME);
+ }
+
+ /// <summary>
+ /// Flag to indicate that transactional messages should be sent by the publisher.
+ /// </summary>
+ /// <return> Flag to indicate that transactional messages should be sent by the publisher. </return>
+ public bool getPublisherTransacted()
+ {
+ return getPropertyAsBoolean(TRANSACTED_PUBLISHER_PROPNAME);
+ }
+
+ /// <summary>
+ /// Flag to indicate that transactional receives should be used by the receiver.
+ /// </summary>
+ /// <return> Flag to indicate that transactional receives should be used by the receiver. </return>
+ public bool getReceiverTransacted()
+ {
+ return getPropertyAsBoolean(TRANSACTED_PUBLISHER_PROPNAME);
+ }
+
+ /// <summary>
+ /// The name of the virtual host to run all tests over.
+ /// </summary>
+ /// <return> The name of the virtual host to run all tests over. </return>
+ public string getVirtualHost()
+ {
+ return getProperty(VIRTUAL_HOST_PROPNAME);
+ }
+
+ /// <summary>
+ /// Limiting rate for each sender in messages per second, or zero for unlimited.
+ /// </summary>
+ /// <return> Limiting rate for each sender in messages per second, or zero for unlimited. </return>
+ public string getRate()
+ {
+ return getProperty(RATE_PROPNAME);
+ }
+
+ /// <summary>
+ /// Flag to indicate that test messages should be received publish/subscribe style by all receivers.
+ /// </summary>
+ /// <return> Flag to indicate that test messages should be received publish/subscribe style by all receivers. </return>
+ public bool getPubsub()
+ {
+ return getPropertyAsBoolean(PUBSUB_PROPNAME);
+ }
+
+ /// <summary>
+ /// The username credentials to run tests with.
+ /// </summary>
+ /// <return> The username credentials to run tests with. </return>
+ public string getUsername()
+ {
+ return getProperty(USERNAME_PROPNAME);
+ }
+
+ /// <summary>
+ /// The password credentials to run tests with.
+ /// </summary>
+ /// <return> The password credentials to run tests with. </return>
+ public string getPassword()
+ {
+ return getProperty(PASSWORD_PROPNAME);
+ }
+
+ /// <summary>
+ /// The timeout duration to fail tests on, should they receive no messages within it.
+ /// </summary>
+ /// <return> The timeout duration to fail tests on, should they receive no messages within it. </return>
+ public long getTimeout()
+ {
+ return getPropertyAsLong(TIMEOUT_PROPNAME);
+ }
+
+ /// <summary>
+ /// The number of messages to batch into each transaction in transational tests.
+ /// </summary>
+ /// <return> The number of messages to batch into each transaction in transational tests. </return>
+ public int getTxBatchSize()
+ {
+ return getPropertyAsInteger(TX_BATCH_SIZE_PROPNAME);
+ }
+
+ /// <summary>
+ /// Flag to indicate that tests should use durable destinations.
+ /// </summary>
+ /// <return> Flag to indicate that tests should use durable destinations. </return>
+ public bool getDurableDests()
+ {
+ return getPropertyAsBoolean(DURABLE_DESTS_PROPNAME);
+ }
+
+ /// <summary>
+ /// The ack mode for message receivers to use.
+ /// </summary>
+ /// <return> The ack mode for message receivers to use. </return>
+ public int getAckMode()
+ {
+ return getPropertyAsInteger(ACK_MODE_PROPNAME);
+ }
+
+ /// <summary>
+ /// Flag to indicate that tests should use durable subscriptions.
+ /// </summary>
+ /// <return> Flag to indicate that tests should use durable subscriptions. </return>
+ public bool getDurableSubscription()
+ {
+ return getPropertyAsBoolean(DURABLE_SUBSCRIPTION_PROPNAME);
+ }
+
+ /// <summary>
+ /// The maximum amount of in-flight data, in bytes, that tests should send at any time.
+ /// </summary>
+ /// <return> The maximum amount of in-flight data, in bytes, that tests should send at any time. </return>
+ public int getMaxPending()
+ {
+ return getPropertyAsInteger(MAX_PENDING_PROPNAME);
+ }
+
+ /// <summary>
+ /// The size of the prefetch queue to use.
+ /// </summary>
+ /// <return> The size of the prefetch queue to use. </return>
+ public int getPrefetch()
+ {
+ return getPropertyAsInteger(PREFETCH_PROPNAME);
+ }
+
+ /// <summary>
+ /// Flag to indicate that subscriptions should be no-local.
+ /// </summary>
+ /// <return> Flag to indicate that subscriptions should be no-local. </return>
+ public bool getNoLocal()
+ {
+ return getPropertyAsBoolean(NO_LOCAL_PROPNAME);
+ }
+
+ /// <summary>
+ /// Flag to indicate that subscriptions should be exclusive.
+ /// </summary>
+ /// <return> Flag to indicate that subscriptions should be exclusive. </return>
+ public bool getExclusive()
+ {
+ return getPropertyAsBoolean(EXCLUSIVE_PROPNAME);
+ }
+
+ /// <summary>
+ /// Flag to indicate that messages must be delivered immediately.
+ /// </summary>
+ /// <return> Flag to indicate that messages must be delivered immediately. </return>
+ public bool getImmediate()
+ {
+ return getPropertyAsBoolean(IMMEDIATE_PROPNAME);
+ }
+
+ /// <summary>
+ /// Flag to indicate that messages must be routable.
+ /// </summary>
+ /// <return> Flag to indicate that messages must be routable. </return>
+ public bool getMandatory()
+ {
+ return getPropertyAsBoolean(MANDATORY_PROPNAME);
+ }
+
+ /// <summary>
+ /// Gets the value of a flag to indicate that the publisher should rollback all messages sent.
+ /// </summary>
+ /// <return> A flag to indicate that the publisher should rollback all messages sent. </return>
+ public bool getRollbackPublisher()
+ {
+ return getPropertyAsBoolean(ROLLBACK_PUBLISHER_PROPNAME);
+ }
+
+ /// <summary>
+ /// Gets the value of a flag to indicate that the receiver should rollback all messages received, then receive them
+ /// again.
+ /// </summary>
+ /// <return> A flag to indicate that the publisher should rollback all messages received. </return>
+ public bool getRollbackReceiver()
+ {
+ return getPropertyAsBoolean(ROLLBACK_RECEIVER_PROPNAME);
+ }
+
+ /// <summary>
+ /// Gets the behavioural mode of not applicable assertions. Should be one of 'quiet', 'warn' or 'fail'.
+ /// </summary>
+ /// <return> The behavioural mode of not applicable assertions. </return>
+ public string getNotApplicableAssertionMode()
+ {
+ return getProperty(NOT_APPLICABLE_ASSERTION_PROPNAME);
+ }
+ }
+}
+/*
+ *
+ * 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.
+ *
+ */
+using log4net;
+
+using uk.co.thebadgerset.junit.extensions.util.ParsedProperties;
+
+namespace Apache.Qpid.Integration.Tests.framework
+{
+ /// <summary>
+ /// NotApplicableAssertion is a messaging assertion that can be used when an assertion requested by a test-case is not
+ /// applicable to the testing scenario. For example an assertion may relate to AMQP functionality, but a test case may be
+ /// being run over a non-AMQP JMS implementation, in which case the request to create the assertion may return this
+ /// instead of the proper assertion. The test framework is configurable to quietly drop these assertions, log them
+ /// as warnings to the console, or raise them as test failures.
+ ///
+ /// <p/><table id="crc"><caption>CRC Card</caption>
+ /// <tr><th> Responsibilities <th> Collaborations
+ /// <tr><td> Quitely pass.
+ /// <tr><td> Log a warning.
+ /// <tr><td> Raise a test failure.
+ /// </table>
+ /// </summary>
+ public class NotApplicableAssertion : Assertion
+ {
+ /// <summary> Used for logging to the console. </summary>
+ private static ILog console = LogManager.GetLogger("CONSOLE." + NotApplicableAssertion.class.getName());
+
+ /// <summary> The possible behavioural modes of this assertion. </summary>
+ private enum Mode
+ {
+ /// <summary> Quietly ignore the assertion by passing. </summary>
+ Quiet,
+
+ /// <summary> Ignore the assertion by passing but log a warning about it. </summary>
+ Warn,
+
+ /// <summary> Fail the assertion. </summary>
+ Fail;
+ }
+
+ /// <summary> The behavioural mode of the assertion. </summary>
+ private Mode mode;
+
+ /// <summary>
+ /// Creates an assertion that is driven by the value of the 'notApplicableAssertion' property of the test
+ /// configuration. Its value should match one of 'quiet', 'warn' or 'fail' and if it does not it is automatically
+ /// read as 'fail'.
+ /// </summary>
+ /// <param name="testProperties"> The test configuration properties. </param>
+ public NotApplicableAssertion(ParsedProperties testProperties)
+ {
+ // Cast the test properties into a typed interface for convenience.
+ MessagingTestConfigProperties props = new MessagingTestConfigProperties(testProperties);
+
+ string modeName = props.getNotApplicableAssertionMode();
+
+ if ("quiet".equals(modeName))
+ {
+ mode = Mode.Quiet;
+ }
+ else if ("warn".equals(modeName))
+ {
+ mode = Mode.Warn;
+ }
+ else
+ {
+ mode = Mode.Fail;
+ }
+ }
+
+ /// <summary>
+ /// Applies the assertion.
+ /// </summary>
+ /// <return> <tt>true</tt> if the assertion passes, <tt>false</tt> if it fails. </return>
+ public bool apply()
+ {
+ switch (mode)
+ {
+ case Quiet:
+ return true;
+
+ case Warn:
+ console.warn("Warning: Not applicable assertion being ignored.");
+
+ return true;
+
+ case Fail:
+ default:
+ return false;
+ }
+ }
+ }
+}
+/*
+ *
+ * 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.
+ *
+ */
+using uk.co.thebadgerset.junit.extensions.util.ParsedProperties;
+
+namespace Apache.Qpid.Integration.Tests.framework
+{
+ /// <summary>
+ /// A Publisher represents the status of the publishing side of a test circuit. Its main purpose is to provide assertions
+ /// that can be applied to test the behaviour of the publishers.
+ ///
+ /// <p/><table id="crc"><caption>CRC Card</caption>
+ /// <tr><th> Responsibilities
+ /// <tr><td> Provide assertion that the publishers received no exceptions.
+ /// </table>
+ /// </summary>
+ ///
+ /// <remarks> There are mixtures of AMQP and JMS assertions in this interface. Either keep them here, but quietly (or with a
+ /// warning or error) drop them from test cases where they are not relevant, or push them down into sub-classes.
+ /// I am tempted to go with the dropping/warning/error approach, that would imply that it makes sense to pull
+ /// the assertions back from AMQPPublisher to here.</remarks>
+ public interface Publisher
+ {
+ // Assertions that are meaningfull to AMQP and to JMS.
+
+ /// <summary>
+ /// Provides an assertion that the publisher encountered no exceptions.
+ /// </summary>
+ /// <param name="testProps"> The test configuration properties. </param>
+ ///
+ /// <return> An assertion that the publisher encountered no exceptions. </return>
+ public Assertion noExceptionsAssertion(ParsedProperties testProps);
+
+ // Assertions that are meaningfull only to AMQP.
+
+ /// <summary>
+ /// Provides an assertion that the AMQP channel was forcibly closed by an error condition.
+ /// </summary>
+ /// <param name="testProps"> The test configuration properties. </param>
+ ///
+ /// <return> An assertion that the AMQP channel was forcibly closed by an error condition. </return>
+ public Assertion channelClosedAssertion(ParsedProperties testProps);
+
+ // Assertions that are meaningfull only to Java/JMS.
+
+ /// <summary>
+ /// Provides an assertion that the publisher got a given exception during the test.
+ /// </summary>
+ /// <param name="testProps"> The test configuration properties. </param>
+ /// <param name="exceptionClass"> The exception class to check for. </param>
+ ///
+ /// <return> An assertion that the publisher got a given exception during the test. </return>
+ public Assertion exceptionAssertion(ParsedProperties testProps, Class<? extends Exception> exceptionClass);
+ }
+}
+/*
+ *
+ * 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.
+ *
+ */
+using uk.co.thebadgerset.junit.extensions.util.ParsedProperties;
+
+namespace Apache.Qpid.Integration.Tests.framework
+{
+ /// <summary>
+ /// A Receiver is a <see cref="CircuitEnd"/> that represents the status of the receiving side of a test circuit. Its main
+ /// purpose is to provide assertions that can be applied to check the behaviour of the receivers.
+ ///
+ /// <p/><table id="crc"><caption>CRC Card</caption>
+ /// <tr><th> Responsibilities
+ /// <tr><td> Provide assertion that the receivers received no exceptions.
+ /// <tr><td> Provide assertion that the receivers received all test messages sent to it.
+ /// </table>
+ /// </summary>
+ ///
+ /// <remarks> There are mixtures of AMQP and JMS assertions in this interface. Either keep them here, but quietly (or with a
+ /// warning or error) drop them from test cases where they are not relevant, or push them down into sub-classes.
+ /// I am tempted to go with the dropping/warning/error approach.</remarks>
+ public interface Receiver
+ {
+ // Assertions that are meaningfull to AMQP and to JMS.
+
+ /// <summary>
+ /// Provides an assertion that the receivers encountered no exceptions.
+ /// </summary>
+ /// <param name="testProps"> The test configuration properties. </param>
+ ///
+ /// <return> An assertion that the receivers encountered no exceptions. </return>
+ public Assertion noExceptionsAssertion(ParsedProperties testProps);
+
+ /// <summary>
+ /// Provides an assertion that the receivers got all messages that were sent to it.
+ /// </summary>
+ /// <param name="testProps"> The test configuration properties. </param>
+ ///
+ /// <return> An assertion that the receivers got all messages that were sent to it. </return>
+ public Assertion allMessagesReceivedAssertion(ParsedProperties testProps);
+
+ /// <summary>
+ /// Provides an assertion that the receivers got none of the messages that were sent to it.
+ /// </summary>
+ /// <param name="testProps"> The test configuration properties. </param>
+ ///
+ /// <return> An assertion that the receivers got none of the messages that were sent to it. </return>
+ public Assertion noMessagesReceivedAssertion(ParsedProperties testProps);
+
+ // Assertions that are meaningfull only to AMQP.
+
+ /// <summary>
+ /// Provides an assertion that the AMQP channel was forcibly closed by an error condition.
+ /// </summary>
+ /// <param name="testProps"> The test configuration properties. </param>
+ ///
+ /// <return> An assertion that the AMQP channel was forcibly closed by an error condition. </return>
+ public Assertion channelClosedAssertion(ParsedProperties testProps);
+
+ // Assertions that are meaningfull only to Java/JMS.
+
+ /// <summary>
+ /// Provides an assertion that the receiver got a given exception during the test.
+ /// </summary>
+ /// <param name="testProps"> The test configuration properties. </param>
+ /// <param name="exceptionClass"> The exception class to check for. </param>
+ ///
+ /// <return> An assertion that the receiver got a given exception during the test. </return>
+ public Assertion exceptionAssertion(ParsedProperties testProps, Class<? extends Exception> exceptionClass);
+ }
+}
+/*
+ *
+ * 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.
+ *
+ */
+using log4net;
+
+using Apache.Qpid.Integration.Tests.framework.Circuit;
+using Apache.Qpid.Integration.Tests.framework.TestClientDetails;
+using org.apache.qpid.util.ConversationFactory;
+
+using System.Collections.Generic.LinkedList;
+using System.Collections.Generic.IList;
+using java.util.Properties;
+
+namespace Apache.Qpid.Integration.Tests.framework.sequencers
+{
+ /// <summary>
+ /// BaseCircuitFactory provides some functionality common to all <see cref="CircuitFactory"/>s, such as the details of
+ /// all <see cref="Apache.Qpid.Integration.Tests.framework.distributedtesting.TestClient"/>s that make up the end-points of
+ /// the circuits that the factory creates, and an active <see cref="ConversationFactory"/> that can be used to generate
+ /// control conversations with those circuit end-points.
+ ///
+ /// <p/><table id="crc"><caption>CRC Card</caption>
+ /// <tr><th> Responsibilities <th> Collaborations
+ /// <tr><td> Hold the details of the sending and receiving end-points to create circuits from.
+ /// <tr><td> Provide a conversation factory to create control conversations with the end-points.
+ /// </table>
+ /// </summary>
+ public abstract class BaseCircuitFactory : CircuitFactory
+ {
+ /// <summary> Used for debugging. </summary>
+ private static ILog log = LogManager.GetLogger(typeof(BaseCircuitFactory));
+
+ /// <summary> Holds the contact details for the sending test client. </summary>
+ protected TestClientDetails sender;
+
+ /// <summary> Holds the contact details for the receving test client. </summary>
+ protected IList<TestClientDetails> receivers = new LinkedList<TestClientDetails>();
+
+ /// <summary> Holds the conversation factory over which to coordinate the test. </summary>
+ protected ConversationFactory conversationFactory;
+
+ /// <summary>
+ /// Creates a test circuit for the test, configered by the test parameters specified.
+ /// </summary>
+ /// <param name="testProperties"> The test parameters. </param>
+ /// <return> A test circuit. </return>
+ public Circuit createCircuit(Properties testProperties)
+ {
+ throw new RuntimeException("Not implemented.");
+ }
+
+ /// <summary>
+ /// Sets the sender test client to coordinate the test with.
+ /// </summary>
+ /// <param name="sender"> The contact details of the sending client in the test. </param>
+ public void setSender(TestClientDetails sender)
+ {
+ log.debug("public void setSender(TestClientDetails sender = " + sender + "): called");
+
+ this.sender = sender;
+ }
+
+ /// <summary>
+ /// Sets the receiving test client to coordinate the test with.
+ /// </summary>
+ /// <param name="receiver"> The contact details of the sending client in the test. </param>
+ public void setReceiver(TestClientDetails receiver)
+ {
+ log.debug("public void setReceiver(TestClientDetails receivers = " + receiver + "): called");
+
+ this.receivers.add(receiver);
+ }
+
+ /// <summary>
+ /// Supplies the sending test client.
+ /// </summary>
+ /// <return> The sending test client. </return>
+ public TestClientDetails getSender()
+ {
+ return sender;
+ }
+
+ /// <summary>
+ /// Supplies the receiving test client.
+ /// </summary>
+ /// <return> The receiving test client. </return>
+ public IList<TestClientDetails> getReceivers()
+ {
+ return receivers;
+ }
+
+ /// <summary>
+ /// Accepts the conversation factory over which to hold the test coordinating conversation.
+ /// </summary>
+ /// <param name="conversationFactory"> The conversation factory to coordinate the test over. </param>
+ public void setConversationFactory(ConversationFactory conversationFactory)
+ {
+ this.conversationFactory = conversationFactory;
+ }
+
+ /// <summary>
+ /// Provides the conversation factory for providing the distributed test sequencing conversations over the test
+ /// connection.
+ /// </summary>
+ /// <return> The conversation factory to create test sequencing conversations with. </return>
+ public ConversationFactory getConversationFactory()
+ {
+ return conversationFactory;
+ }
+ }
+}
+/*
+ *
+ * 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.
+ *
+ */
+using Apache.Qpid.Integration.Tests.framework.Assertion;
+using Apache.Qpid.Integration.Tests.framework.Circuit;
+using Apache.Qpid.Integration.Tests.framework.TestClientDetails;
+using org.apache.qpid.util.ConversationFactory;
+
+using uk.co.thebadgerset.junit.extensions.util.ParsedProperties;
+
+using javax.jms.JMSException;
+using javax.jms.Message;
+
+using System.Collections.Generic.IList;
+using System.Collections.Generic.IDictionary;
+using java.util.Properties;
+
+namespace Apache.Qpid.Integration.Tests.framework.sequencers
+{
+ /// <summary>
+ /// A CircuitFactory is responsibile for creating test circuits appropriate to the context that a test case is
+ /// running in, and providing an implementation of a standard test procedure over a test circuit.
+ ///
+ /// <p/><table id="crc"><caption>CRC Card</caption>
+ /// <tr><th> Responsibilities
+ /// <tr><td> Provide a standard test procedure over a test circuit.
+ /// <tr><td> Construct test circuits appropriate to a tests context.
+ /// </table>
+ /// </summary>
+ public interface CircuitFactory
+ {
+ /// <summary>
+ /// Holds a test coordinating conversation with the test clients. This should consist of assigning the test roles,
+ /// begining the test, gathering the test reports from the participants, and checking for assertion failures against
+ /// the test reports.
+ /// </summary>
+ /// <param name="testCircuit"> The test circuit. </param>
+ /// <param name="assertions"> The list of assertions to apply to the test circuit. </param>
+ /// <param name="testProperties"> The test case definition. </param>
+ ///
+ /// @deprecated Use test circuits and Circuit.test instead.
+ public void sequenceTest(Circuit testCircuit, IList<Assertion> assertions, Properties testProperties);
+
+ /// <summary>
+ /// Creates a test circuit for the test, configered by the test parameters specified.
+ /// </summary>
+ /// <param name="testProperties"> The test parameters. </param>
+ ///
+ /// <return> A test circuit. </return>
+ public Circuit createCircuit(ParsedProperties testProperties);
+
+ /// <summary>
+ /// Sets the sender test client to coordinate the test with.
+ /// </summary>
+ /// <param name="sender"> The contact details of the sending client in the test. </param>
+ public void setSender(TestClientDetails sender);
+
+ /// <summary>
+ /// Sets the receiving test client to coordinate the test with.
+ /// </summary>
+ /// <param name="receiver"> The contact details of the sending client in the test. </param>
+ public void setReceiver(TestClientDetails receiver);
+
+ /// <summary>
+ /// Supplies the sending test client.
+ /// </summary>
+ /// <return> The sending test client. </return>
+ public TestClientDetails getSender();
+
+ /// <summary>
+ /// Supplies the receiving test client.
+ /// </summary>
+ /// <return> The receiving test client. </return>
+ public IList<TestClientDetails> getReceivers();
+
+ /// <summary>
+ /// Accepts the conversation factory over which to hold the test coordinating conversation.
+ /// </summary>
+ /// <param name="conversationFactory"> The conversation factory to coordinate the test over. </param>
+ public void setConversationFactory(ConversationFactory conversationFactory);
+ }
+}
+/*
+ *
+ * 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.
+ *
+ */
+using log4net;
+
+using Apache.Qpid.Integration.Tests.framework.Assertion;
+using Apache.Qpid.Integration.Tests.framework.Circuit;
+using Apache.Qpid.Integration.Tests.framework.TestClientDetails;
+using Apache.Qpid.Integration.Tests.framework.TestUtils;
+using Apache.Qpid.Integration.Tests.framework.distributedcircuit.DistributedCircuitImpl;
+using org.apache.qpid.util.ConversationFactory;
+
+using uk.co.thebadgerset.junit.extensions.util.ParsedProperties;
+
+using javax.jms.Destination;
+using javax.jms.JMSException;
+using javax.jms.Message;
+using javax.jms.Session;
+
+using System.Collections.Generic.LinkedList;
+using System.Collections.Generic.IList;
+using java.util.Properties;
+
+namespace Apache.Qpid.Integration.Tests.framework.sequencers
+{
+ /// <summary>
+ /// FanOutCircuitFactory is a circuit factory that creates distributed test circuits. Given a set of participating
+ /// test client nodes, it assigns one node to the SENDER role and the remainder to the RECEIVER role.
+ ///
+ /// <p/><table id="crc"><caption>CRC Card</caption>
+ /// <tr><th> Responsibilities <th> Collaborations
+ /// <tr><td> Create distributed circuits from one to many test nodes, for fanout style testing.
+ /// </table>
+ /// </summary>
+ ///
+ /// <remarks> Adapt this to be an n*m topology circuit factory. Need to add circuit topology definitions to the test
+ /// parameters. Place n senders onto the available test clients, and m receivers. Where n or m is larger than
+ /// the available nodes, start stacking multiple test clients on each node. There will also be an option that
+ /// indicates whether nodes can play both roles, and how many nodes out of all available may be assigned to
+ /// each role.</remarks>
+ ///
+ /// <remarks> The createCircuit methods on this and InteropCircuitFactory are going to be identical. This is because the
+ /// partitioning into senders and receivers is already done by the test decorators. Either eliminate these factories
+ /// as unnesesary, or move the partitioning functionality into the factories, in which case the test decorators
+ /// can probably be merged or eliminated. There is confusion over the placement of responsibilities between the
+ /// factories and the test decorators... although the test decorators may well do more than just circuit creation
+ /// in the future. For example, there may have to be a special decorator for test repetition that does one circuit
+ /// creation, but the runs many tests over it, in which case the handling of responsibilities becomes clearer.</remarks>
+ public class FanOutCircuitFactory extends BaseCircuitFactory
+ {
+ /// <summary> Used for debugging. </summary>
+ private static ILog log = LogManager.GetLogger(typeof(FanOutCircuitFactory));
+
+ /// <summary>
+ /// Creates a test circuit for the test, configered by the test parameters specified.
+ /// </summary>
+ /// <param name="testProperties"> The test parameters. </param>
+ /// <return> A test circuit. </return>
+ public Circuit createCircuit(ParsedProperties testProperties)
+ {
+ log.debug("public Circuit createCircuit(ParsedProperties testProperties): called");
+
+ IList<TestClientDetails> senders = new LinkedList<TestClientDetails>();
+ senders.add(getSender());
+ IList<TestClientDetails> receivers = getReceivers();
+ ConversationFactory conversationFactory = getConversationFactory();
+
+ return DistributedCircuitImpl.createCircuit(testProperties, senders, receivers, conversationFactory);
+ }
+
+ /// <summary>
+ /// Holds a test coordinating conversation with the test clients. This should consist of assigning the test roles,
+ /// begining the test, gathering the test reports from the participants, and checking for assertion failures against
+ /// the test reports.
+ /// </summary>
+ /// <param name="testCircuit"> The test circuit. </param>
+ /// <param name="assertions"> The list of assertions to apply to the test circuit. </param>
+ /// <param name="testProperties"> The test case definition. </param>
+ ///
+ /// @deprecated Scheduled for removal once existing tests converted over to use test circuits.
+ public void sequenceTest(Circuit testCircuit, IList<Assertion> assertions, Properties testProperties)
+ {
+ log.debug("protected Message[] sequenceTest(Object... testProperties = " + testProperties + "): called");
+
+ TestClientDetails sender = getSender();
+ IList<TestClientDetails> receivers = getReceivers();
+ ConversationFactory conversationFactory = getConversationFactory();
+
+ try
+ {
+ // Create a conversation on the sender clients private control route.
+ Session session = conversationFactory.getSession();
+ Destination senderControlTopic = session.createTopic(sender.privateControlKey);
+ ConversationFactory.Conversation senderConversation = conversationFactory.startConversation();
+
+ // Assign the sender role to the sending test client.
+ Message assignSender = conversationFactory.getSession().createMessage();
+ TestUtils.setPropertiesOnMessage(assignSender, testProperties);
+ assignSender.setStringProperty("CONTROL_TYPE", "ASSIGN_ROLE");
+ assignSender.setStringProperty("ROLE", "SENDER");
+ assignSender.setStringProperty("CLIENT_NAME", "Sustained_SENDER");
+
+ senderConversation.send(senderControlTopic, assignSender);
+
+ // Wait for the sender to confirm its role.
+ senderConversation.receive();
+
+ // Assign the receivers roles.
+ for (TestClientDetails receiver : receivers)
+ {
+ assignReceiverRole(receiver, testProperties, true);
+ }
+
+ // Start the test on the sender.
+ Message start = session.createMessage();
+ start.setStringProperty("CONTROL_TYPE", "START");
+
+ senderConversation.send(senderControlTopic, start);
+
+ // Wait for the test sender to return its report.
+ Message senderReport = senderConversation.receive();
+ TestUtils.pause(500);
+
+ // Ask the receivers for their reports.
+ Message statusRequest = session.createMessage();
+ statusRequest.setStringProperty("CONTROL_TYPE", "STATUS_REQUEST");
+
+ // Gather the reports from all of the receiving clients.
+
+ // Return all of the test reports, the senders report first.
+ // return new Message[] { senderReport };
+ }
+ catch (JMSException e)
+ {
+ throw new RuntimeException("Unhandled JMSException.");
+ }
+ }
+
+ /// <summary>
+ /// Assigns the receivers role to the specified test client that is to act as a receivers during the test. This method
+ /// does not always wait for the receiving clients to confirm their role assignments. This is because this method
+ /// may be called from an 'onMessage' method, when a client is joining the test at a later point in time, and it
+ /// is not possible to do a synchronous receive during an 'onMessage' method. There is a flag to indicate whether
+ /// or not to wait for role confirmations.
+ /// </summary>
+ /// <param name="receiver"> The test client to assign the receivers role to. </param>
+ /// <param name="testProperties"> The test parameters. </param>
+ /// <param name="confirm"> Indicates whether role confirmation should be waited for. </param>
+ ///
+ /// <exception cref="JMSException"> Any JMSExceptions occurring during the conversation are allowed to fall through. </exception>
+ ///
+ /// @deprecated Scheduled for removal once existing tests converted over to use test circuits.
+ protected void assignReceiverRole(TestClientDetails receiver, Properties testProperties, bool confirm)
+ throws JMSException
+ {
+ log.info("assignReceiverRole(TestClientDetails receivers = " + receiver + ", Map<String, Object> testProperties = "
+ + testProperties + "): called");
+
+ ConversationFactory conversationFactory = getConversationFactory();
+
+ // Create a conversation with the receiving test client.
+ Session session = conversationFactory.getSession();
+ Destination receiverControlTopic = session.createTopic(receiver.privateControlKey);
+ ConversationFactory.Conversation receiverConversation = conversationFactory.startConversation();
+
+ // Assign the receivers role to the receiving client.
+ Message assignReceiver = session.createMessage();
+ TestUtils.setPropertiesOnMessage(assignReceiver, testProperties);
+ assignReceiver.setStringProperty("CONTROL_TYPE", "ASSIGN_ROLE");
+ assignReceiver.setStringProperty("ROLE", "RECEIVER");
+ assignReceiver.setStringProperty("CLIENT_NAME", receiver.clientName);
+
+ receiverConversation.send(receiverControlTopic, assignReceiver);
+
+ // Wait for the role confirmation to come back.
+ if (confirm)
+ {
+ receiverConversation.receive();
+ }
+ }
+ }
+}
+/*
+ *
+ * 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.
+ *
+ */
+using log4net;
+
+using Apache.Qpid.Integration.Tests.framework.Assertion;
+using Apache.Qpid.Integration.Tests.framework.Circuit;
+using Apache.Qpid.Integration.Tests.framework.TestClientDetails;
+using Apache.Qpid.Integration.Tests.framework.TestUtils;
+using Apache.Qpid.Integration.Tests.framework.distributedcircuit.DistributedCircuitImpl;
+using org.apache.qpid.util.ConversationFactory;
+
+using uk.co.thebadgerset.junit.extensions.util.ParsedProperties;
+
+using javax.jms.Destination;
+using javax.jms.JMSException;
+using javax.jms.Message;
+using javax.jms.Session;
+
+using System.Collections.Generic.LinkedList;
+using System.Collections.Generic.IList;
+using java.util.Properties;
+
+namespace Apache.Qpid.Integration.Tests.framework.sequencers
+{
+ /// <summary>
+ /// InteropCircuitFactory is a circuit factory that creates distributed test circuits. Given a set of participating
+ /// test client nodes, it assigns one node to the SENDER role and one the RECEIVER role.
+ ///
+ /// <p/><table id="crc"><caption>CRC Card</caption>
+ /// <tr><th> Responsibilities <th> Collaborations
+ /// <tr><td> Create distributed circuits from pairs of test nodes, for interop style testing.
+ /// </table>
+ /// </summary>
+ ///
+ /// <remarks> The partitioning of a set of nodes into sender and receiver roles is actually done by the interop test
+ /// decorator. See the todo comment in FanOutCircuitFactory about merging the factories with the decorators, or
+ /// more carefully dividing up responsibilities between them.</remarks>
+ ///
+ /// <remarks> The squenceTest code is deprecated, but currently still used by the interop tests. It will be removed once it
+ /// have been fully replaced by the default test procedure.</remarks>
+ public class InteropCircuitFactory extends BaseCircuitFactory
+ {
+ /// <summary> Used for debugging. </summary>
+ private static ILog log = LogManager.GetLogger(typeof(InteropCircuitFactory));
+
+ /// <summary>
+ /// Creates a test circuit for the test, configered by the test parameters specified.
+ /// </summary>
+ /// <param name="testProperties"> The test parameters. </param>
+ /// <return> A test circuit. </return>
+ public Circuit createCircuit(ParsedProperties testProperties)
+ {
+ log.debug("public Circuit createCircuit(ParsedProperties testProperties): called");
+
+ IList<TestClientDetails> senders = new LinkedList<TestClientDetails>();
+ senders.add(getSender());
+ IList<TestClientDetails> receivers = getReceivers();
+ ConversationFactory conversationFactory = getConversationFactory();
+
+ return DistributedCircuitImpl.createCircuit(testProperties, senders, receivers, conversationFactory);
+ }
+
+ /// <summary>
+ /// Holds a test coordinating conversation with the test clients. This should consist of assigning the test roles,
+ /// begining the test, gathering the test reports from the participants, and checking for assertion failures against
+ /// the test reports.
+ /// </summary>
+ /// <param name="testCircuit"> The test circuit. </param>
+ /// <param name="assertions"> The list of assertions to apply to the test circuit. </param>
+ /// <param name="testProperties"> The test case definition. </param>
+ public void sequenceTest(Circuit testCircuit, IList<Assertion> assertions, Properties testProperties)
+ {
+ log.debug("protected Message[] sequenceTest(Object... testProperties = " + testProperties + "): called");
+
+ TestClientDetails sender = getSender();
+ IList<TestClientDetails> receivers = getReceivers();
+ ConversationFactory conversationFactory = getConversationFactory();
+
+ try
+ {
+ Session session = conversationFactory.getSession();
+ Destination senderControlTopic = session.createTopic(sender.privateControlKey);
+ Destination receiverControlTopic = session.createTopic(receivers.get(0).privateControlKey);
+
+ ConversationFactory.Conversation senderConversation = conversationFactory.startConversation();
+ ConversationFactory.Conversation receiverConversation = conversationFactory.startConversation();
+
+ Message assignSender = conversationFactory.getSession().createMessage();
+ TestUtils.setPropertiesOnMessage(assignSender, testProperties);
+ assignSender.setStringProperty("CONTROL_TYPE", "ASSIGN_ROLE");
+ assignSender.setStringProperty("ROLE", "SENDER");
+
+ senderConversation.send(senderControlTopic, assignSender);
+
+ // Assign the receivers role the receiving client.
+ Message assignReceiver = session.createMessage();
+ TestUtils.setPropertiesOnMessage(assignReceiver, testProperties);
+ assignReceiver.setStringProperty("CONTROL_TYPE", "ASSIGN_ROLE");
+ assignReceiver.setStringProperty("ROLE", "RECEIVER");
+
+ receiverConversation.send(receiverControlTopic, assignReceiver);
+
+ // Wait for the senders and receivers to confirm their roles.
+ senderConversation.receive();
+ receiverConversation.receive();
+
+ // Start the test.
+ Message start = session.createMessage();
+ start.setStringProperty("CONTROL_TYPE", "START");
+
+ senderConversation.send(senderControlTopic, start);
+
+ // Wait for the test sender to return its report.
+ Message senderReport = senderConversation.receive();
+ TestUtils.pause(500);
+
+ // Ask the receivers for its report.
+ Message statusRequest = session.createMessage();
+ statusRequest.setStringProperty("CONTROL_TYPE", "STATUS_REQUEST");
+
+ receiverConversation.send(receiverControlTopic, statusRequest);
+
+ // Wait for the receivers to send its report.
+ Message receiverReport = receiverConversation.receive();
+
+ // return new Message[] { senderReport, receiverReport };
+
+ // Apply assertions.
+ }
+ catch (JMSException e)
+ {
+ throw new RuntimeException("JMSException not handled.");
+ }
+ }
+ }
+}
+/*
+ *
+ * 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.
+ *
+ */
+namespace Apache.Qpid.Integration.Tests.framework
+{
+ /// <summary>
+ /// <p/><table id="crc"><caption>CRC Card</caption>
+ /// <tr><th> Responsibilities <th> Collaborations
+ /// <tr><td>
+ /// </table>
+ /// </summary>
+ public class TestCaseVector
+ {
+ /// <summary> The test case name. </summary>
+ private string testCase;
+
+ /// <summary> The test cycle number within the test case. </summary>
+ private int testCycleNumber;
+
+ public TestCaseVector(string testCase, int testCycleNumber)
+ {
+ this.testCase = testCase;
+ this.testCycleNumber = testCycleNumber;
+ }
+
+ public string getTestCase()
+ {
+ return testCase;
+ }
+
+ public int getTestCycleNumber()
+ {
+ return testCycleNumber;
+ }
+
+ public bool equals(Object o)
+ {
+ if (this == o)
+ {
+ return true;
+ }
+
+ if ((o == null) || (getClass() != o.getClass()))
+ {
+ return false;
+ }
+
+ TestCaseVector that = (TestCaseVector) o;
+
+ if (testCycleNumber != that.testCycleNumber)
+ {
+ return false;
+ }
+
+ if ((testCase != null) ? (!testCase.equals(that.testCase)) : (that.testCase != null))
+ {
+ return false;
+ }
+
+ return true;
+ }
+
+ public int hashCode()
+ {
+ int result;
+ result = ((testCase != null) ? testCase.hashCode() : 0);
+ result = (31 * result) + testCycleNumber;
+
+ return result;
+ }
+ }
+}
+/*
+ *
+ * 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.
+ *
+ */
+namespace Apache.Qpid.Integration.Tests.framework
+{
+ /// <summary>
+ /// TestClientDetails is used to encapsulate information about an interop test client. It pairs together the unique
+ /// name of the client, and the route on which it listens to its control messages.
+ ///
+ /// <p><table id="crc"><caption>CRC Card</caption>
+ /// <tr><th> Responsibilities <th> Collaborations
+ /// <tr><td> Record test clients control addresses together with their names.
+ /// </table>
+ /// </summary>
+ public class TestClientDetails
+ {
+ /// <summary> The test clients name. </summary>
+ public string clientName;
+
+ /// <summary> The routing key of the test clients control topic. </summary>
+ public string privateControlKey;
+
+ /// <summary>
+ /// Two TestClientDetails are considered to be equal, iff they have the same client name.
+ /// </summary>
+ /// <param name="o"> The object to compare to. </param>
+ ///
+ /// <return> <tt>If the object to compare to is a TestClientDetails equal to this one, <tt>false</tt> otherwise. </return>
+ public bool equals(Object o)
+ {
+ if (this == o)
+ {
+ return true;
+ }
+
+ if (!(o instanceof TestClientDetails))
+ {
+ return false;
+ }
+
+ final TestClientDetails testClientDetails = (TestClientDetails) o;
+
+ return !((clientName != null) ? (!clientName.equals(testClientDetails.clientName))
+ : (testClientDetails.clientName != null));
+ }
+
+ /// <summary>
+ /// Computes a hash code compatible with the equals method; based on the client name alone.
+ /// </summary>
+ /// <return> A hash code for this. </return>
+ public int hashCode()
+ {
+ return ((clientName != null) ? clientName.hashCode() : 0);
+ }
+
+ /// <summary>
+ /// Outputs the client name and address details. Mostly used for debugging purposes.
+ /// </summary>
+ /// <return> The client name and address. </return>
+ public string ToString()
+ {
+ return "TestClientDetails: [ clientName = " + clientName + ", privateControlKey = " + privateControlKey + " ]";
+ }
+ }
+}
+/*
+ *
+ * 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.
+ *
+ */
+using log4net;
+
+using static Apache.Qpid.Integration.Tests.framework.MessagingTestConfigProperties.*;
+
+using uk.co.thebadgerset.junit.extensions.util.ParsedProperties;
+
+using javax.jms.*;
+using javax.naming.Context;
+using javax.naming.InitialContext;
+using javax.naming.NamingException;
+
+using System.Collections.Generic.IDictionary;
+
+namespace Apache.Qpid.Integration.Tests.framework
+{
+ /// <summary>
+ /// TestUtils provides static helper methods that are usefull for writing tests against QPid.
+ ///
+ /// <p/><table id="crc"><caption>CRC Card</caption>
+ /// <tr><th> Responsibilities <th> Collaborations
+ /// <tr><td> Create connections from test properties. <td> <see cref="MessagingTestConfigProperties"/>
+ /// <tr><td> Create test messages.
+ /// <tr><td> Inject a short pause in a test.
+ /// <tr><td> Serialize properties into a message.
+ /// </table>
+ /// </summary>
+ public class TestUtils
+ {
+ /// <summary> Used for debugging. </summary>
+ private static ILog log = LogManager.GetLogger(typeof(TestUtils));
+
+ /// <summary> Some dummy data to stuff all test messages with. </summary>
+ private static final byte[] MESSAGE_DATA_BYTES =
+ "Test Message -- Test Message -- Test Message -- Test Message -- Test Message -- Test Message -- Test Message -- "
+ .getBytes();
+
+ /// <summary>
+ /// Establishes a JMS connection using a set of properties and qpids built in JNDI implementation. This is a simple
+ /// convenience method for code that does not anticipate handling connection failures. All exceptions that indicate
+ /// that the connection has failed, are wrapped as rutime exceptions, presumably handled by a top level failure
+ /// handler.
+ ///
+ /// <p/>This utility makes use of the following test parameters from <see cref="MessagingTestConfigProperties"/> to control
+ /// the connection creation:
+ ///
+ /// <p/><table>
+ /// <tr><td> <see cref="MessagingTestConfigProperties#USERNAME_PROPNAME"/> <td> The username.
+ /// <tr><td> <see cref="MessagingTestConfigProperties#PASSWORD_PROPNAME"/> <td> The password.
+ /// <tr><td> <see cref="MessagingTestConfigProperties#VIRTUAL_HOST_PROPNAME"/> <td> The virtual host name.
+ /// <tr><td> <see cref="MessagingTestConfigProperties#BROKER_PROPNAME"/> <td> The broker URL.
+ /// <tr><td> <see cref="MessagingTestConfigProperties#CONNECTION_NAME"/> <td> The broker name in the initial context.
+ /// </summary>
+ /// <param name="messagingProps"> Connection properties as defined in <see cref="MessagingTestConfigProperties"/>. </param>
+ ///
+ /// <return> A JMS conneciton. </return>
+ public static Connection createConnection(ParsedProperties messagingProps)
+ {
+ log.debug("public static Connection createConnection(ParsedProperties messagingProps = " + messagingProps
+ + "): called");
+
+ try
+ {
+ // Extract the configured connection properties from the test configuration.
+ string conUsername = messagingProps.getProperty(USERNAME_PROPNAME);
+ string conPassword = messagingProps.getProperty(PASSWORD_PROPNAME);
+ string virtualHost = messagingProps.getProperty(VIRTUAL_HOST_PROPNAME);
+ string brokerUrl = messagingProps.getProperty(BROKER_PROPNAME);
+
+ // Create the broker connection url.
+ string connectionstring =
+ "amqp://" + conUsername + ":" + conPassword + "@clientid/" + ((virtualHost != null) ? virtualHost : "")
+ + "?brokerlist='" + brokerUrl + "'";
+
+ // Create properties to create the initial context from, and inject the connection factory configuration
+ // for the defined connection name into it.
+ messagingProps.setProperty("connectionfactory." + CONNECTION_NAME, connectionString);
+
+ Context ctx = new InitialContext(messagingProps);
+
+ ConnectionFactory cf = (ConnectionFactory) ctx.lookup(CONNECTION_NAME);
+
+ return cf.createConnection();
+ }
+ catch (NamingException e)
+ {
+ throw new RuntimeException("Got JNDI NamingException whilst looking up the connection factory.", e);
+ }
+ catch (JMSException e)
+ {
+ throw new RuntimeException("Could not establish connection due to JMSException.", e);
+ }
+ }
+
+ /// <summary>
+ /// Creates a test message of the specified size, on the given JMS session.
+ /// </summary>
+ /// <param name="session"> The JMS session. </param>
+ /// <param name="size"> The size of the message in bytes. </param>
+ ///
+ /// <return> A bytes message, of the specified size, filled with dummy data. </return>
+ ///
+ /// <exception cref="JMSException"> Any underlying JMSExceptions are allowed to fall through. </exception>
+ public static Message createTestMessageOfSize(Session session, int size) throws JMSException
+ {
+ BytesMessage message = session.createBytesMessage();
+
+ if (size > 0)
+ {
+ int div = MESSAGE_DATA_BYTES.length / size;
+ int mod = MESSAGE_DATA_BYTES.length % size;
+
+ for (int i = 0; i < div; i++)
+ {
+ message.writeBytes(MESSAGE_DATA_BYTES);
+ }
+
+ if (mod != 0)
+ {
+ message.writeBytes(MESSAGE_DATA_BYTES, 0, mod);
+ }
+ }
+
+ return message;
+ }
+
+ /// <summary>
+ /// Pauses for the specified length of time. In the event of failing to pause for at least that length of time
+ /// due to interuption of the thread, a RutimeException is raised to indicate the failure. The interupted status
+ /// of the thread is restores in that case. This method should only be used when it is expected that the pause
+ /// will be succesfull, for example in test code that relies on inejecting a pause.
+ /// </summary>
+ /// <param name="t"> The minimum time to pause for in milliseconds. </param>
+ public static void pause(long t)
+ {
+ try
+ {
+ Thread.sleep(t);
+ }
+ catch (InterruptedException e)
+ {
+ // Restore the interrupted status
+ Thread.currentThread().interrupt();
+
+ throw new RuntimeException("Failed to generate the requested pause length.", e);
+ }
+ }
+
+ /// <summary>
+ /// Sets properties of different types on a JMS Message.
+ /// </summary>
+ /// <param name="message"> The message to set properties on. </param>
+ /// <param name="properties"> The property name/value pairs to set. </param>
+ ///
+ /// <exception cref="javax.jms.JMSException"> All underlying JMSExceptions are allowed to fall through. </exception>
+ ///
+ /// <remarks> Move this helper method somewhere else. For example, TestUtils.</remarks>
+ public static void setPropertiesOnMessage(Message message, Map<Object, Object> properties) throws JMSException
+ {
+ for (Map.Entry<Object, Object> entry : properties.entrySet())
+ {
+ string name = entry.getKey().ToString();
+ Object value = entry.getValue();
+
+ message.setObjectProperty(name, value);
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/qpid/dotnet/Qpid.Integration.Tests/framework/clocksynch/ClockSynchFailureException.csx b/qpid/dotnet/Qpid.Integration.Tests/framework/clocksynch/ClockSynchFailureException.csx
new file mode 100644
index 0000000000..a2bcc49b97
--- /dev/null
+++ b/qpid/dotnet/Qpid.Integration.Tests/framework/clocksynch/ClockSynchFailureException.csx
@@ -0,0 +1,45 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+namespace Apache.Qpid.Integration.Tests.framework.clocksynch
+{
+ /// <summary>
+ /// ClockSynchFailureException represents failure of a <see cref="ClockSynchronizer"/> to achieve synchronization. For example,
+ /// this could be because a reference signal is not available, or because a desired accurracy cannot be attained.
+ ///
+ /// <p/><table id="crc"><caption>CRC Card</caption>
+ /// <tr><th> Responsibilities <th> Collaborations
+ /// <tr><td> Represent failure to achieve synchronization.
+ /// </table>
+ /// </summary>
+ public class ClockSynchFailureException extends Exception
+ {
+ /// <summary>
+ /// Creates a clock synch failure exception.
+ /// </summary>
+ /// <param name="message"> The detail message (which is saved for later retrieval by the <see cref="#getMessage()"/> method). </param>
+ /// <param name="cause"> The cause (which is saved for later retrieval by the <see cref="#getCause()"/> method). (A <tt>null</tt>
+ /// value is permitted, and indicates that the cause is nonexistent or unknown.)</param>
+ public ClockSynchFailureException(string message, Throwable cause)
+ {
+ super(message, cause);
+ }
+ }
+} \ No newline at end of file
diff --git a/qpid/dotnet/Qpid.Integration.Tests/framework/clocksynch/ClockSynchThread.csx b/qpid/dotnet/Qpid.Integration.Tests/framework/clocksynch/ClockSynchThread.csx
new file mode 100644
index 0000000000..7d2fcae058
--- /dev/null
+++ b/qpid/dotnet/Qpid.Integration.Tests/framework/clocksynch/ClockSynchThread.csx
@@ -0,0 +1,117 @@
+/*
+ *
+ * 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.
+ *
+ */
+using log4net;
+
+using uk.co.thebadgerset.junit.extensions.ShutdownHookable;
+using uk.co.thebadgerset.junit.extensions.Throttle;
+
+namespace Apache.Qpid.Integration.Tests.framework.clocksynch
+{
+ /// <summary>
+ /// ClockSynchThread is a convenient utility for running a thread that periodically synchronizes the clock against
+ /// a reference. Supply it with a <see cref="ClockSynchronizer"/> and a <see cref="Throttle"/> and it will continually keep the
+ /// clock up-to-date at a rate determined by the throttle.
+ ///
+ /// <p/><table id="crc"><caption>CRC Card</caption>
+ /// <tr><th> Responsibilities <th> Collaborations
+ /// <tr><td> Continually sychronize the clock at a throttled rate.
+ /// </table>
+ /// </summary>
+ public class ClockSynchThread extends Thread : ShutdownHookable
+ {
+ /// <summary> Used for debugging. </summary>
+ private static ILog log = LogManager.GetLogger(typeof(ClockSynchThread));
+
+ /// <summary> Holds the clock syncher for the synch thread. </summary>
+ private ClockSynchronizer clockSyncher;
+
+ /// <summary> Holds the throttle to limit the synch rate. </summary>
+ private Throttle throttle;
+
+ /// <summary> Flag to indicate that the periodic clock syncher should keep running. </summary>
+ bool doSynch = true;
+
+ /// <summary>
+ /// Creates a clock synchronizer thread from a clock synchronizer and a throttle.
+ /// </summary>
+ /// <param name="syncher"> The clock synchronizer. </param>
+ /// <param name="throttle"> The throttle. </param>
+ public ClockSynchThread(ClockSynchronizer syncher, Throttle throttle)
+ {
+ this.clockSyncher = syncher;
+ this.throttle = throttle;
+ }
+
+ /// <summary> Terminates the synchronization thread. </summary>
+ public void terminate()
+ {
+ doSynch = false;
+ }
+
+ /// <summary> Continually updates the clock, until <see cref="#terminate()"/> is called. </summary>
+ public void run()
+ {
+ while (doSynch)
+ {
+ // Perform a clock clockSynch.
+ try
+ {
+ // Wait controlled by the throttle before doing the next synch.
+ throttle.throttle();
+
+ clockSyncher.synch();
+ log.debug("Clock synched, delta = " + clockSyncher.getDelta() + ", epsilon = " + clockSyncher.getEpsilon()
+ + ".");
+ }
+ // Terminate the synch thread if the synchronization cannot be achieved.
+ catch (ClockSynchFailureException e)
+ {
+ log.debug("Cannot synchronize the clock (reference service may be down). Terminating the synch thread.");
+ doSynch = false;
+ }
+ }
+ }
+
+ /// <summary>
+ /// Gets the clock synchronizer that is kept continually up to date.
+ /// </summary>
+ /// <return> The clock synchronizer that is kept continually up to date. </return>
+ public ClockSynchronizer getClockSyncher()
+ {
+ return clockSyncher;
+ }
+
+ /// <summary>
+ /// Supplies a shutdown hook, that terminates the synching thread.
+ /// </summary>
+ /// <return> The shut down hook. </return>
+ public Thread getShutdownHook()
+ {
+ return new Thread(new Runnable()
+ {
+ public void run()
+ {
+ doSynch = false;
+ }
+ });
+ }
+ }
+} \ No newline at end of file
diff --git a/qpid/dotnet/Qpid.Integration.Tests/framework/clocksynch/ClockSynchronizer.csx b/qpid/dotnet/Qpid.Integration.Tests/framework/clocksynch/ClockSynchronizer.csx
new file mode 100644
index 0000000000..665b804b21
--- /dev/null
+++ b/qpid/dotnet/Qpid.Integration.Tests/framework/clocksynch/ClockSynchronizer.csx
@@ -0,0 +1,66 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+namespace Apache.Qpid.Integration.Tests.framework.clocksynch
+{
+ /// <summary>
+ /// ClockSynchronizer provides an interface through which two nodes may synchronize their clocks. It is expected that one
+ /// node will act as the reference clock, to which no delta need be applied, and the other node will act as the slave,
+ /// and which must apply a delta to its local clock to get a clock synchronized with the reference.
+ ///
+ /// <p/>The slave side will initiate the computation of a clock delta by calling the <see cref="#synch"/> method. This method
+ /// will not return until the delta has been computed, at which point there is a method to return its value, as well as
+ /// an estimate of the likely error (usually one standard deviation), in the synchronization. For convenience there is a
+ /// <see cref="#nanoTime"/> method to return the value of System.nanoTime() with the delta added in.
+ ///
+ /// <p/><table id="crc"><caption>CRC Card</caption>
+ /// <tr><th> Responsibilities <th> Collaborations
+ /// <tr><td> Trigger a clock synchronization.
+ /// <tr><td> Compute a clock delta to apply to the local clock.
+ /// <tr><td> Estimate the error in the synchronzation.
+ /// </table>
+ /// </summary>
+ public interface ClockSynchronizer
+ {
+ /// <summary>
+ /// The slave side should call this to copute a clock delta with the reference.
+ /// </summary>
+ /// <exception cref="ClockSynchFailureException"> If synchronization cannot be achieved. </exception>
+ public void synch() throws ClockSynchFailureException;
+
+ /// <summary>
+ /// Gets the clock delta in nano seconds.
+ /// </summary>
+ /// <return> The clock delta in nano seconds. </return>
+ public long getDelta();
+
+ /// <summary>
+ /// Gets an estimate of the clock error in nan seconds.
+ /// </summary>
+ /// <return> An estimate of the clock error in nan seconds. </return>
+ public long getEpsilon();
+
+ /// <summary>
+ /// Gets the local clock time with any computed delta added in.
+ /// </summary>
+ /// <return> The local clock time with any computed delta added in. </return>
+ public long nanoTime();
+ }
+} \ No newline at end of file
diff --git a/qpid/dotnet/Qpid.Integration.Tests/framework/clocksynch/LocalClockSynchronizer.csx b/qpid/dotnet/Qpid.Integration.Tests/framework/clocksynch/LocalClockSynchronizer.csx
new file mode 100644
index 0000000000..1d19b92d90
--- /dev/null
+++ b/qpid/dotnet/Qpid.Integration.Tests/framework/clocksynch/LocalClockSynchronizer.csx
@@ -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.
+ *
+ */
+namespace Apache.Qpid.Integration.Tests.framework.clocksynch
+{
+
+ /// <summary>
+ /// LocalClockSynchronizer is a fake <see cref="ClockSynchronizer"/> that simply calls System.nanoTime(). It exists so that
+ /// the same tests can be run distributed or locally, taking timings against the ClockSynchronizer interface without
+ /// being aware of how they are being run.
+ ///
+ /// <p/><table id="crc"><caption>CRC Card</caption>
+ /// <tr><th> Responsibilities <th> Collaborations
+ /// <tr><td> Supply the local clock with no delta.
+ /// </table>
+ /// </summary>
+ public class LocalClockSynchronizer : ClockSynchronizer
+ {
+ /// <summary>
+ /// The slave side should call this to copute a clock delta with the reference.
+ /// </summary>
+ /// <exception cref="Apache.Qpid.Integration.Tests.framework.clocksynch.ClockSynchFailureException"> If synchronization cannot be achieved. </exception>
+ public void synch() throws ClockSynchFailureException
+ { }
+
+ /// <summary>
+ /// Gets the clock delta in nano seconds.
+ /// </summary>
+ /// <return> The clock delta in nano seconds. </return>
+ public long getDelta()
+ {
+ return 0L;
+ }
+
+ /// <summary>
+ /// Gets an estimate of the clock error in nan seconds.
+ /// </summary>
+ /// <return> An estimate of the clock error in nan seconds. </return>
+ public long getEpsilon()
+ {
+ return 0L;
+ }
+
+ /// <summary>
+ /// Gets the local clock time with any computed delta added in.
+ /// </summary>
+ /// <return> The local clock time with any computed delta added in. </return>
+ public long nanoTime()
+ {
+ return System.nanoTime();
+ }
+ }
+} \ No newline at end of file
diff --git a/qpid/dotnet/Qpid.Integration.Tests/framework/clocksynch/UDPClockSynchronizer.csx b/qpid/dotnet/Qpid.Integration.Tests/framework/clocksynch/UDPClockSynchronizer.csx
new file mode 100644
index 0000000000..98b02a043b
--- /dev/null
+++ b/qpid/dotnet/Qpid.Integration.Tests/framework/clocksynch/UDPClockSynchronizer.csx
@@ -0,0 +1,453 @@
+/*
+ *
+ * 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.
+ *
+ */
+using log4net;
+
+using uk.co.thebadgerset.junit.extensions.util.CommandLineParser;
+using uk.co.thebadgerset.junit.extensions.util.ParsedProperties;
+
+using java.io.IOException;
+using java.net.*;
+using java.nio.ByteBuffer;
+using java.util.Arrays;
+
+namespace Apache.Qpid.Integration.Tests.framework.clocksynch
+{
+ /// <summary>
+ /// UDPClockSynchronizer is a <see cref="ClockSynchronizer"/> that sends pings as UDP datagrams, and uses the following simple
+ /// algorithm to perform clock synchronization:
+ ///
+ /// <ol>
+ /// <li>Slave initiates synchronization with a Reference clock.</li>
+ /// <li>Slave stamps current local time on a "time request" message and sends to the Reference.</li>
+ /// <li>Upon receipt by Reference, Reference stamps Reference-time and returns.</li>
+ /// <li>Upon receipt by Slave, Slave subtracts current time from sent time and divides by two to compute latency. It
+ /// subtracts current time from Reference time to determine Slave-Reference time delta and adds in the
+ /// half-latency to get the correct clock delta.</li>
+ /// <li>The first result is immediately used to update the clock since it will get the local clock into at least
+ /// the right ballpark.</li>
+ /// <li>The Slave repeats steps 2 through 4, 15 more times.</li>
+ /// <li>The results of the packet receipts are accumulated and sorted in lowest-latency to highest-latency order. The
+ /// median latency is determined by picking the mid-point sample from this ordered list.</li>
+ /// <li>All samples outside 1 standard-deviation from the median are discarded and the remaining samples
+ /// are averaged using an arithmetic mean.</li>
+ /// </ol>
+ ///
+ /// <p/>The use of UDP datagrams, instead of TCP based communication eliminates the hidden delays that TCP can introduce,
+ /// as it can transparently re-order or re-send packets, or introduce delays as packets are naggled.
+ ///
+ /// <p/><table id="crc"><caption>CRC Card</caption>
+ /// <tr><th> Responsibilities <th> Collaborations
+ /// <tr><td> Trigger a clock synchronziation.
+ /// <tr><td> Compute a clock delta to apply to the local clock.
+ /// <tr><td> Estimate the error in the synchronzation.
+ /// </table>
+ /// </summary>
+ public class UDPClockSynchronizer : ClockSynchronizer
+ {
+ /// <summary> Used for debugging. </summary>
+ // private static ILog log = LogManager.GetLogger(typeof(UDPClockSynchronizer));
+
+ /// <summary> Defines the timeout to use when waiting for responses to time requests. </summary>
+ private static final int TIMEOUT = 50;
+
+ /// <summary> The clock delta. </summary>
+ private long delta = 0L;
+
+ /// <summary> Holds an estimate of the clock error relative to the reference clock. </summary>
+ private long epsilon = 0L;
+
+ /// <summary> Holds the address of the reference clock. </summary>
+ private InetAddress referenceAddress;
+
+ /// <summary> Holds the socket to communicate with the reference service over. </summary>
+ private DatagramSocket socket;
+
+ /// <summary> Used to control the shutdown in the main test loop. </summary>
+ private static bool doSynch = true;
+
+ /// <summary>
+ /// Creates a clock synchronizer against the specified address for the reference.
+ /// </summary>
+ /// <param name="address"> The address of the reference service. </param>
+ public UDPClockSynchronizer(string address)
+ {
+ try
+ {
+ referenceAddress = InetAddress.getByName(address);
+ }
+ catch (UnknownHostException e)
+ {
+ throw new RuntimeException(e);
+ }
+ }
+
+ /// <summary>
+ /// The slave side should call this to compute a clock delta with the reference.
+ /// </summary>
+ /// <exception cref="ClockSynchFailureException"> If synchronization cannot be achieved, due to unavailability of the reference
+ /// time service. </exception>
+ public void synch() throws ClockSynchFailureException
+ {
+ try
+ {
+ socket = new DatagramSocket();
+ socket.setSoTimeout(TIMEOUT);
+
+ // Synchronize on a single ping, to get the clock into the right ball-park.
+ synch(1);
+
+ // Synchronize on 15 pings.
+ synch(15);
+
+ // And again, for greater accuracy, on 31.
+ synch(31);
+
+ socket.close();
+ }
+ catch (SocketException e)
+ {
+ throw new RuntimeException(e);
+ }
+ }
+
+ /// <summary>
+ /// Updates the synchronization delta by performing the specified number of reference clock requests.
+ /// </summary>
+ /// <param name="n"> The number of reference clock request cycles to perform. </param>
+ ///
+ /// <exception cref="ClockSynchFailureException"> If synchronization cannot be achieved, due to unavailability of the reference
+ /// time service. </exception>
+ protected void synch(int n) throws ClockSynchFailureException
+ {
+ // log.debug("protected void synch(int n = " + n + "): called");
+
+ // Create an array of deltas by performing n reference pings.
+ long[] delta = new long[n];
+
+ for (int i = 0; i < n; i++)
+ {
+ delta[i] = ping();
+ }
+
+ // Reject any deltas that are larger than 1 s.d. above the median.
+ long median = median(delta);
+ long sd = standardDeviation(delta);
+
+ // log.debug("median = " + median);
+ // log.debug("sd = " + sd);
+
+ long[] tempDeltas = new long[n];
+ int count = 0;
+
+ for (int i = 0; i < n; i++)
+ {
+ if ((delta[i] <= (median + sd)) && (delta[i] >= (median - sd)))
+ {
+ tempDeltas[count] = delta[i];
+ count++;
+ }
+ else
+ {
+ // log.debug("Rejected: " + delta[i]);
+ }
+ }
+
+ System.arraycopy(tempDeltas, 0, delta, 0, count);
+
+ // Estimate the delta as the mean of the remaining deltas.
+ this.delta += mean(delta);
+
+ // Estimate the error as the standard deviation of the remaining deltas.
+ this.epsilon = standardDeviation(delta);
+
+ // log.debug("this.delta = " + this.delta);
+ // log.debug("this.epsilon = " + this.epsilon);
+ }
+
+ /// <summary>
+ /// Performs a single reference clock request cycle and returns the estimated delta relative to the local clock.
+ /// This is computed as the half-latency of the requst cycle, plus the reference clock, minus the local clock.
+ /// </summary>
+ /// <return> The estimated clock delta. </return>
+ ///
+ /// <exception cref="ClockSynchFailureException"> If the reference service is not responding. </exception>
+ protected long ping() throws ClockSynchFailureException
+ {
+ // log.debug("protected long ping(): called");
+
+ try
+ {
+ byte[] buf = new byte[256];
+
+ bool timedOut = false;
+ long start = 0L;
+ long refTime = 0L;
+ long localTime = 0L;
+ long latency = 0L;
+ int failCount = 0;
+
+ // Keep trying the ping until it gets a response, or 10 tries in a row all time out.
+ do
+ {
+ // Start timing the request latency.
+ start = nanoTime();
+
+ // Get the reference time.
+ DatagramPacket packet =
+ new DatagramPacket(buf, buf.length, referenceAddress, UDPClockReference.REFERENCE_PORT);
+ socket.send(packet);
+ packet = new DatagramPacket(buf, buf.length);
+
+ timedOut = false;
+
+ try
+ {
+ socket.receive(packet);
+ }
+ catch (SocketTimeoutException e)
+ {
+ timedOut = true;
+ failCount++;
+
+ continue;
+ }
+
+ ByteBuffer bbuf = ByteBuffer.wrap(packet.getData());
+ refTime = bbuf.getLong();
+
+ // Stop timing the request latency.
+ localTime = nanoTime();
+ latency = localTime - start;
+
+ // log.debug("refTime = " + refTime);
+ // log.debug("localTime = " + localTime);
+ // log.debug("start = " + start);
+ // log.debug("latency = " + latency);
+ // log.debug("delta = " + ((latency / 2) + (refTime - localTime)));
+
+ }
+ while (timedOut && (failCount < 10));
+
+ // Fail completely if the fail count is too high.
+ if (failCount >= 10)
+ {
+ throw new ClockSynchFailureException("Clock reference not responding.", null);
+ }
+
+ // Estimate delta as (ref clock + half-latency) - local clock.
+ return (latency / 2) + (refTime - localTime);
+ }
+ catch (IOException e)
+ {
+ throw new RuntimeException(e);
+ }
+ }
+
+ /// <summary>
+ /// Gets the clock delta in nano seconds.
+ /// </summary>
+ /// <return> The clock delta in nano seconds. </return>
+ public long getDelta()
+ {
+ return delta;
+ }
+
+ /// <summary>
+ /// Gets an estimate of the clock error in nan seconds.
+ /// </summary>
+ /// <return> An estimate of the clock error in nan seconds. </return>
+ public long getEpsilon()
+ {
+ return epsilon;
+ }
+
+ /// <summary>
+ /// Gets the local clock time with any computed delta added in.
+ /// </summary>
+ /// <return> The local clock time with any computed delta added in. </return>
+ public long nanoTime()
+ {
+ return System.nanoTime() + delta;
+ }
+
+ /// <summary>
+ /// Computes the median of a series of values.
+ /// </summary>
+ /// <param name="values"> The values. </param>
+ ///
+ /// <return> The median. </return>
+ public static long median(long[] values)
+ {
+ // log.debug("public static long median(long[] values = " + Arrays.ToString(values) + "): called");
+
+ long median;
+
+ // Order the list of values.
+ long[] orderedValues = new long[values.length];
+ System.arraycopy(values, 0, orderedValues, 0, values.length);
+ Arrays.sort(orderedValues);
+
+ // Check if the median is computed from a pair of middle value.
+ if ((orderedValues.length % 2) == 0)
+ {
+ int middle = orderedValues.length / 2;
+
+ median = (orderedValues[middle] + orderedValues[middle - 1]) / 2;
+ }
+ // The median is computed from a single middle value.
+ else
+ {
+ median = orderedValues[orderedValues.length / 2];
+ }
+
+ // log.debug("median = " + median);
+
+ return median;
+ }
+
+ /// <summary>
+ /// Computes the mean of a series of values.
+ /// </summary>
+ /// <param name="values"> The values. </param>
+ ///
+ /// <return> The mean. </return>
+ public static long mean(long[] values)
+ {
+ // log.debug("public static long mean(long[] values = " + Arrays.ToString(values) + "): called");
+
+ long total = 0L;
+
+ for (long value : values)
+ {
+ total += value;
+ }
+
+ long mean = total / values.length;
+
+ // log.debug("mean = " + mean);
+
+ return mean;
+ }
+
+ /// <summary>
+ /// Computes the variance of series of values.
+ /// </summary>
+ /// <param name="values"> The values. </param>
+ ///
+ /// <return> The variance of the values. </return>
+ public static long variance(long[] values)
+ {
+ // log.debug("public static long variance(long[] values = " + Arrays.ToString(values) + "): called");
+
+ long mean = mean(values);
+
+ long totalVariance = 0;
+
+ for (long value : values)
+ {
+ long diff = (value - mean);
+ totalVariance += diff/// diff;
+ }
+
+ long variance = totalVariance / values.length;
+
+ // log.debug("variance = " + variance);
+
+ return variance;
+ }
+
+ /// <summary>
+ /// Computes the standard deviation of a series of values.
+ /// </summary>
+ /// <param name="values"> The values. </param>
+ ///
+ /// <return> The standard deviation. </return>
+ public static long standardDeviation(long[] values)
+ {
+ // log.debug("public static long standardDeviation(long[] values = " + Arrays.ToString(values) + "): called");
+
+ long sd = Double.valueOf(Math.sqrt(variance(values))).longValue();
+
+ // log.debug("sd = " + sd);
+
+ return sd;
+ }
+
+ /// <summary>
+ /// For testing purposes. Supply address of reference clock as arg 1.
+ /// </summary>
+ /// <param name="args"> Address of reference clock as arg 1. </param>
+ public static void main(String[] args)
+ {
+ ParsedProperties options =
+ new ParsedProperties(CommandLineParser.processCommandLine(args,
+ new CommandLineParser(
+ new String[][]
+ {
+ { "1", "Address of clock reference service.", "address", "true" }
+ }), System.getProperties()));
+
+ string address = options.getProperty("1");
+
+ // Create a clock synchronizer.
+ UDPClockSynchronizer clockSyncher = new UDPClockSynchronizer(address);
+
+ // Set up a shutdown hook for it.
+ Runtime.getRuntime().addShutdownHook(new Thread(new Runnable()
+ {
+ public void run()
+ {
+ doSynch = false;
+ }
+ }));
+
+ // Repeat the clock synching until the user kills the progam.
+ while (doSynch)
+ {
+ // Perform a clock clockSynch.
+ try
+ {
+ clockSyncher.synch();
+
+ // Print out the clock delta and estimate of the error.
+ System.out.println("Delta = " + clockSyncher.getDelta());
+ System.out.println("Epsilon = " + clockSyncher.getEpsilon());
+
+ try
+ {
+ Thread.sleep(250);
+ }
+ catch (InterruptedException e)
+ {
+ // Restore the interrupted status and terminate the loop.
+ Thread.currentThread().interrupt();
+ doSynch = false;
+ }
+ }
+ // Terminate if the reference time service is unavailable.
+ catch (ClockSynchFailureException e)
+ {
+ doSynch = false;
+ }
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/qpid/dotnet/Qpid.Integration.Tests/framework/distributedcircuit/TestClient.csx b/qpid/dotnet/Qpid.Integration.Tests/framework/distributedcircuit/TestClient.csx
new file mode 100644
index 0000000000..1126fec520
--- /dev/null
+++ b/qpid/dotnet/Qpid.Integration.Tests/framework/distributedcircuit/TestClient.csx
@@ -0,0 +1,493 @@
+/*
+ *
+ * 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.
+ *
+ */
+using log4net;
+using org.apache.log4j.NDC;
+
+using Apache.Qpid.Integration.Tests.framework.MessagingTestConfigProperties;
+using Apache.Qpid.Integration.Tests.framework.TestUtils;
+using Apache.Qpid.Integration.Tests.framework.clocksynch.ClockSynchThread;
+using Apache.Qpid.Integration.Tests.framework.clocksynch.UDPClockSynchronizer;
+using org.apache.qpid.util.ReflectionUtils;
+using org.apache.qpid.util.ReflectionUtilsException;
+
+using uk.co.thebadgerset.junit.extensions.SleepThrottle;
+using uk.co.thebadgerset.junit.extensions.util.ParsedProperties;
+using uk.co.thebadgerset.junit.extensions.util.TestContextProperties;
+
+using javax.jms.*;
+
+using java.util.*;
+
+namespace Apache.Qpid.Integration.Tests.framework.distributedtesting
+{
+ /// <summary>
+ /// Implements a test client as described in the interop testing spec
+ /// (http://cwiki.apache.org/confluence/display/qpid/Interop+Testing+Specification). A test client is an agent that
+ /// reacts to control message sequences send by the test <see cref="Coordinator"/>.
+ ///
+ /// <p/><table><caption>Messages Handled by TestClient</caption>
+ /// <tr><th> Message <th> Action
+ /// <tr><td> Invite(compulsory) <td> Reply with Enlist.
+ /// <tr><td> Invite(test case) <td> Reply with Enlist if test case available.
+ /// <tr><td> AssignRole(test case) <td> Reply with Accept Role if matches an enlisted test. Keep test parameters.
+ /// <tr><td> Start <td> Send test messages defined by test parameters. Send report on messages sent.
+ /// <tr><td> Status Request <td> Send report on messages received.
+ /// <tr><td> Terminate <td> Terminate the test client.
+ /// <tr><td> ClockSynch <td> Synch clock against the supplied UDP address.
+ /// </table>
+ ///
+ /// <p><table id="crc"><caption>CRC Card</caption>
+ /// <tr><th> Responsibilities <th> Collaborations
+ /// <tr><td> Handle all incoming control messages. <td> <see cref="TestClientControlledTest"/>
+ /// <tr><td> Configure and look up test cases by name. <td> <see cref="TestClientControlledTest"/>
+ /// </table>
+ /// </summary>
+ public class TestClient : MessageListener
+ {
+ /// <summary> Used for debugging. </summary>
+ private static ILog log = LogManager.GetLogger(typeof(TestClient));
+
+ /// <summary> Used for reporting to the console. </summary>
+ private static ILog console = LogManager.GetLogger("CONSOLE");
+
+ /// <summary> Holds the default identifying name of the test client. </summary>
+ public static final string CLIENT_NAME = "java";
+
+ /// <summary> Holds the URL of the broker to run the tests on. </summary>
+ public static string brokerUrl;
+
+ /// <summary> Holds the virtual host to run the tests on. If <tt>null</tt>, then the default virtual host is used. </summary>
+ public static string virtualHost;
+
+ /// <summary>
+ /// Holds the test context properties that provides the default test parameters, plus command line overrides.
+ /// This is initialized with the default test parameters, to which command line overrides may be applied.
+ /// </summary>
+ public static ParsedProperties testContextProperties =
+ TestContextProperties.getInstance(MessagingTestConfigProperties.defaults);
+
+ /// <summary> Holds all the test cases loaded from the classpath. </summary>
+ Map<String, TestClientControlledTest> testCases = new HashMap<String, TestClientControlledTest>();
+
+ /// <summary> Holds the test case currently being run by this client. </summary>
+ protected TestClientControlledTest currentTestCase;
+
+ /// <summary> Holds the connection to the broker that the test is being coordinated on. </summary>
+ protected Connection connection;
+
+ /// <summary> Holds the message producer to hold the test coordination over. </summary>
+ protected MessageProducer producer;
+
+ /// <summary> Holds the JMS controlSession for the test coordination. </summary>
+ protected Session session;
+
+ /// <summary> Holds the name of this client, with a default value. </summary>
+ protected string clientName = CLIENT_NAME;
+
+ /// <summary> This flag indicates that the test client should attempt to join the currently running test case on start up. </summary>
+ protected bool join;
+
+ /// <summary> Holds the clock synchronizer for the test node. </summary>
+ ClockSynchThread clockSynchThread;
+
+ /// <summary>
+ /// Creates a new interop test client, listenting to the specified broker and virtual host, with the specified client
+ /// identifying name.
+ /// </summary>
+ /// <param name="pBrokerUrl"> The url of the broker to connect to. </param>
+ /// <param name="pVirtualHost"> The virtual host to conect to. </param>
+ /// <param name="clientName"> The client name to use. </param>
+ /// <param name="join"> Flag to indicate that this client should attempt to join running tests. </param>
+ public TestClient(string pBrokerUrl, string pVirtualHost, string clientName, bool join)
+ {
+ log.debug("public TestClient(string pBrokerUrl = " + pBrokerUrl + ", string pVirtualHost = " + pVirtualHost
+ + ", string clientName = " + clientName + ", bool join = " + join + "): called");
+
+ // Retain the connection parameters.
+ brokerUrl = pBrokerUrl;
+ virtualHost = pVirtualHost;
+ this.clientName = clientName;
+ this.join = join;
+ }
+
+ /// <summary>
+ /// The entry point for the interop test coordinator. This client accepts the following command line arguments:
+ ///
+ /// <p/><table>
+ /// <tr><td> -b <td> The broker URL. <td> Optional.
+ /// <tr><td> -h <td> The virtual host. <td> Optional.
+ /// <tr><td> -n <td> The test client name. <td> Optional.
+ /// <tr><td> name=value <td> Trailing argument define name/value pairs. Added to system properties. <td> Optional.
+ /// </table>
+ /// </summary>
+ /// <param name="args"> The command line arguments. </param>
+ public static void main(String[] args)
+ {
+ log.debug("public static void main(String[] args = " + Arrays.ToString(args) + "): called");
+ console.info("Qpid Distributed Test Client.");
+
+ // Override the default broker url to be localhost:5672.
+ testContextProperties.setProperty(MessagingTestConfigProperties.BROKER_PROPNAME, "tcp://localhost:5672");
+
+ // Use the command line parser to evaluate the command line with standard handling behaviour (print errors
+ // and usage then exist if there are errors).
+ // Any options and trailing name=value pairs are also injected into the test context properties object,
+ // to override any defaults that may have been set up.
+ ParsedProperties options =
+ new ParsedProperties(uk.co.thebadgerset.junit.extensions.util.CommandLineParser.processCommandLine(args,
+ new uk.co.thebadgerset.junit.extensions.util.CommandLineParser(
+ new String[][]
+ {
+ { "b", "The broker URL.", "broker", "false" },
+ { "h", "The virtual host to use.", "virtual host", "false" },
+ { "o", "The name of the directory to output test timings to.", "dir", "false" },
+ { "n", "The name of the test client.", "name", "false" },
+ { "j", "Join this test client to running test.", "false" }
+ }), testContextProperties));
+
+ // Extract the command line options.
+ string brokerUrl = options.getProperty("b");
+ string virtualHost = options.getProperty("h");
+ string clientName = options.getProperty("n");
+ clientName = (clientName == null) ? CLIENT_NAME : clientName;
+ bool join = options.getPropertyAsBoolean("j");
+
+ // To distinguish logging output set up an NDC on the client name.
+ NDC.push(clientName);
+
+ // Create a test client and start it running.
+ TestClient client = new TestClient(brokerUrl, virtualHost, clientName, join);
+
+ // Use a class path scanner to find all the interop test case implementations.
+ // Hard code the test classes till the classpath scanner is fixed.
+ Collection<Class<? extends TestClientControlledTest>> testCaseClasses =
+ new ArrayList<Class<? extends TestClientControlledTest>>();
+ // ClasspathScanner.getMatches(TestClientControlledTest.class, "^TestCase.*", true);
+ testCaseClasses.addAll(loadTestCases("org.apache.qpid.interop.clienttestcases.TestCase1DummyRun",
+ "org.apache.qpid.interop.clienttestcases.TestCase2BasicP2P",
+ "org.apache.qpid.interop.clienttestcases.TestCase3BasicPubSub",
+ "org.apache.qpid.interop.clienttestcases.TestCase4P2PMessageSize",
+ "org.apache.qpid.interop.clienttestcases.TestCase5PubSubMessageSize",
+ "Apache.Qpid.Integration.Tests.framework.distributedcircuit.TestClientCircuitEnd"));
+
+ try
+ {
+ client.start(testCaseClasses);
+ }
+ catch (Exception e)
+ {
+ log.error("The test client was unable to start.", e);
+ console.info(e.getMessage());
+ System.exit(1);
+ }
+ }
+
+ /// <summary>
+ /// Parses a list of class names, and loads them if they are available on the class path.
+ /// </summary>
+ /// <param name="classNames"> The names of the classes to load. </param>
+ ///
+ /// <return> A list of the loaded test case classes. </return>
+ public static IList<Class<? extends TestClientControlledTest>> loadTestCases(String... classNames)
+ {
+ IList<Class<? extends TestClientControlledTest>> testCases =
+ new LinkedList<Class<? extends TestClientControlledTest>>();
+
+ for (string className : classNames)
+ {
+ try
+ {
+ Class<?> cls = ReflectionUtils.forName(className);
+ testCases.add((Class<? extends TestClientControlledTest>) cls);
+ }
+ catch (ReflectionUtilsException e)
+ {
+ // Ignore, class could not be found, so test not available.
+ console.warn("Requested class " + className + " cannot be found, ignoring it.");
+ }
+ catch (ClassCastException e)
+ {
+ // Ignore, class was not of correct type to be a test case.
+ console.warn("Requested class " + className + " is not an instance of TestClientControlledTest.");
+ }
+ }
+
+ return testCases;
+ }
+
+ /// <summary>
+ /// Starts the interop test client running. This causes it to start listening for incoming test invites.
+ /// </summary>
+ /// <param name="testCaseClasses"> The classes of the available test cases. The test case names from these are used to </param>
+ /// matchin incoming test invites against.
+ ///
+ /// <exception cref="JMSException"> Any underlying JMSExceptions are allowed to fall through. </exception>
+ protected void start(Collection<Class<? extends TestClientControlledTest>> testCaseClasses) throws JMSException
+ {
+ log.debug("protected void start(Collection<Class<? extends TestClientControlledTest>> testCaseClasses = "
+ + testCaseClasses + "): called");
+
+ // Create all the test case implementations and index them by the test names.
+ for (Class<? extends TestClientControlledTest> nextClass : testCaseClasses)
+ {
+ try
+ {
+ TestClientControlledTest testCase = nextClass.newInstance();
+ testCases.put(testCase.getName(), testCase);
+ }
+ catch (InstantiationException e)
+ {
+ log.warn("Could not instantiate test case class: " + nextClass.getName(), e);
+ // Ignored.
+ }
+ catch (IllegalAccessException e)
+ {
+ log.warn("Could not instantiate test case class due to illegal access: " + nextClass.getName(), e);
+ // Ignored.
+ }
+ }
+
+ // Open a connection to communicate with the coordinator on.
+ connection = TestUtils.createConnection(testContextProperties);
+ session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
+
+ // Set this up to listen for control messages.
+ Topic privateControlTopic = session.createTopic("iop.control." + clientName);
+ MessageConsumer consumer = session.createConsumer(privateControlTopic);
+ consumer.setMessageListener(this);
+
+ Topic controlTopic = session.createTopic("iop.control");
+ MessageConsumer consumer2 = session.createConsumer(controlTopic);
+ consumer2.setMessageListener(this);
+
+ // Create a producer to send replies with.
+ producer = session.createProducer(null);
+
+ // If the join flag was set, then broadcast a join message to notify the coordinator that a new test client
+ // is available to join the current test case, if it supports it. This message may be ignored, or it may result
+ // in this test client receiving a test invite.
+ if (join)
+ {
+ Message joinMessage = session.createMessage();
+
+ joinMessage.setStringProperty("CONTROL_TYPE", "JOIN");
+ joinMessage.setStringProperty("CLIENT_NAME", clientName);
+ joinMessage.setStringProperty("CLIENT_PRIVATE_CONTROL_KEY", "iop.control." + clientName);
+ producer.send(controlTopic, joinMessage);
+ }
+
+ // Start listening for incoming control messages.
+ connection.start();
+ }
+
+ /// <summary>
+ /// Handles all incoming control messages.
+ /// </summary>
+ /// <param name="message"> The incoming message. </param>
+ public void onMessage(Message message)
+ {
+ NDC.push(clientName);
+ log.debug("public void onMessage(Message message = " + message + "): called");
+
+ try
+ {
+ string controlType = message.getStringProperty("CONTROL_TYPE");
+ string testName = message.getStringProperty("TEST_NAME");
+
+ log.debug("Received control of type '" + controlType + "' for the test '" + testName + "'");
+
+ // Check if the message is a test invite.
+ if ("INVITE".equals(controlType))
+ {
+ // Flag used to indicate that an enlist should be sent. Only enlist to compulsory invites or invites
+ // for which test cases exist.
+ bool enlist = false;
+
+ if (testName != null)
+ {
+ log.debug("Got an invite to test: " + testName);
+
+ // Check if the requested test case is available.
+ TestClientControlledTest testCase = testCases.get(testName);
+
+ if (testCase != null)
+ {
+ log.debug("Found implementing class for test '" + testName + "', enlisting for it.");
+
+ // Check if the test case will accept the invitation.
+ enlist = testCase.acceptInvite(message);
+
+ log.debug("The test case "
+ + (enlist ? " accepted the invite, enlisting for it."
+ : " did not accept the invite, not enlisting."));
+
+ // Make the requested test case the current test case.
+ currentTestCase = testCase;
+ }
+ else
+ {
+ log.debug("Received an invite to the test '" + testName + "' but this test is not known.");
+ }
+ }
+ else
+ {
+ log.debug("Got a compulsory invite, enlisting for it.");
+
+ enlist = true;
+ }
+
+ if (enlist)
+ {
+ // Reply with the client name in an Enlist message.
+ Message enlistMessage = session.createMessage();
+ enlistMessage.setStringProperty("CONTROL_TYPE", "ENLIST");
+ enlistMessage.setStringProperty("CLIENT_NAME", clientName);
+ enlistMessage.setStringProperty("CLIENT_PRIVATE_CONTROL_KEY", "iop.control." + clientName);
+ enlistMessage.setJMSCorrelationID(message.getJMSCorrelationID());
+
+ log.debug("Sending enlist message '" + enlistMessage + "' to " + message.getJMSReplyTo());
+
+ producer.send(message.getJMSReplyTo(), enlistMessage);
+ }
+ else
+ {
+ // Reply with the client name in an Decline message.
+ Message enlistMessage = session.createMessage();
+ enlistMessage.setStringProperty("CONTROL_TYPE", "DECLINE");
+ enlistMessage.setStringProperty("CLIENT_NAME", clientName);
+ enlistMessage.setStringProperty("CLIENT_PRIVATE_CONTROL_KEY", "iop.control." + clientName);
+ enlistMessage.setJMSCorrelationID(message.getJMSCorrelationID());
+
+ log.debug("Sending decline message '" + enlistMessage + "' to " + message.getJMSReplyTo());
+
+ producer.send(message.getJMSReplyTo(), enlistMessage);
+ }
+ }
+ else if ("ASSIGN_ROLE".equals(controlType))
+ {
+ // Assign the role to the current test case.
+ string roleName = message.getStringProperty("ROLE");
+
+ log.debug("Got a role assignment to role: " + roleName);
+
+ TestClientControlledTest.Roles role = Enum.valueOf(TestClientControlledTest.Roles.class, roleName);
+
+ currentTestCase.assignRole(role, message);
+
+ // Reply by accepting the role in an Accept Role message.
+ Message acceptRoleMessage = session.createMessage();
+ acceptRoleMessage.setStringProperty("CLIENT_NAME", clientName);
+ acceptRoleMessage.setStringProperty("CONTROL_TYPE", "ACCEPT_ROLE");
+ acceptRoleMessage.setJMSCorrelationID(message.getJMSCorrelationID());
+
+ log.debug("Sending accept role message '" + acceptRoleMessage + "' to " + message.getJMSReplyTo());
+
+ producer.send(message.getJMSReplyTo(), acceptRoleMessage);
+ }
+ else if ("START".equals(controlType) || "STATUS_REQUEST".equals(controlType))
+ {
+ if ("START".equals(controlType))
+ {
+ log.debug("Got a start notification.");
+
+ // Extract the number of test messages to send from the start notification.
+ int numMessages;
+
+ try
+ {
+ numMessages = message.getIntProperty("MESSAGE_COUNT");
+ }
+ catch (NumberFormatException e)
+ {
+ // If the number of messages is not specified, use the default of one.
+ numMessages = 1;
+ }
+
+ // Start the current test case.
+ currentTestCase.start(numMessages);
+ }
+ else
+ {
+ log.debug("Got a status request.");
+ }
+
+ // Generate the report from the test case and reply with it as a Report message.
+ Message reportMessage = currentTestCase.getReport(session);
+ reportMessage.setStringProperty("CLIENT_NAME", clientName);
+ reportMessage.setStringProperty("CONTROL_TYPE", "REPORT");
+ reportMessage.setJMSCorrelationID(message.getJMSCorrelationID());
+
+ log.debug("Sending report message '" + reportMessage + "' to " + message.getJMSReplyTo());
+
+ producer.send(message.getJMSReplyTo(), reportMessage);
+ }
+ else if ("TERMINATE".equals(controlType))
+ {
+ console.info("Received termination instruction from coordinator.");
+
+ // Is a cleaner shutdown needed?
+ connection.close();
+ System.exit(0);
+ }
+ else if ("CLOCK_SYNCH".equals(controlType))
+ {
+ log.debug("Received clock synch command.");
+ string address = message.getStringProperty("ADDRESS");
+
+ log.debug("address = " + address);
+
+ // Re-create (if necessary) and start the clock synch thread to synch the clock every ten seconds.
+ if (clockSynchThread != null)
+ {
+ clockSynchThread.terminate();
+ }
+
+ SleepThrottle throttle = new SleepThrottle();
+ throttle.setRate(0.1f);
+
+ clockSynchThread = new ClockSynchThread(new UDPClockSynchronizer(address), throttle);
+ clockSynchThread.start();
+ }
+ else
+ {
+ // Log a warning about this but otherwise ignore it.
+ log.warn("Got an unknown control message, controlType = " + controlType + ", message = " + message);
+ }
+ }
+ catch (JMSException e)
+ {
+ // Log a warning about this, but otherwise ignore it.
+ log.warn("Got JMSException whilst handling message: " + message, e);
+ }
+ // Log any runtimes that fall through this message handler. These are fatal errors for the test client.
+ catch (RuntimeException e)
+ {
+ log.error("The test client message handler got an unhandled exception: ", e);
+ console.info("The message handler got an unhandled exception, terminating the test client.");
+ System.exit(1);
+ }
+ finally
+ {
+ NDC.pop();
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/qpid/dotnet/Qpid.Integration.Tests/framework/distributedcircuit/TestClientCircuitEnd.csx b/qpid/dotnet/Qpid.Integration.Tests/framework/distributedcircuit/TestClientCircuitEnd.csx
new file mode 100644
index 0000000000..5ac2c4bf5b
--- /dev/null
+++ b/qpid/dotnet/Qpid.Integration.Tests/framework/distributedcircuit/TestClientCircuitEnd.csx
@@ -0,0 +1,312 @@
+/*
+ *
+ * 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.
+ *
+ */
+using log4net;
+
+using Apache.Qpid.Integration.Tests.framework.*;
+using Apache.Qpid.Integration.Tests.framework.distributedtesting.TestClientControlledTest;
+
+using uk.co.thebadgerset.junit.extensions.util.ParsedProperties;
+using uk.co.thebadgerset.junit.extensions.util.TestContextProperties;
+
+using javax.jms.*;
+
+namespace Apache.Qpid.Integration.Tests.framework.distributedcircuit
+{
+ /// <summary>
+ /// A TestClientCircuitEnd is a <see cref="CircuitEnd"/> that may be controlled from a
+ /// <see cref="Apache.Qpid.Integration.Tests.framework.distributedtesting.TestClient"/>, and that forms a single publishing or
+ /// receiving end point in a distributed test <see cref="Apache.Qpid.Integration.Tests.framework.Circuit"/>.
+ ///
+ /// <p/>When operating in the SENDER role, this circuit end is capable of acting as part of the default circuit test
+ /// procedure (described in the class comment for <see cref="Apache.Qpid.Integration.Tests.framework.Circuit"/>). That is, it will
+ /// send the number of test messages required, using the test configuration parameters given in the test invite, and
+ /// return a report on its activities to the circuit controller.
+ ///
+ /// <p/>When operation in the RECEIVER role, this circuit end acts as part of the default circuit test procedure. It will
+ /// receive test messages, on the setup specified in the test configuration parameters, and keep count of the messages
+ /// received, and time taken to receive them. When requested by the circuit controller to provide a report, it will
+ /// return this report of its activities.
+ ///
+ /// <p/><table id="crc"><caption>CRC Card</caption>
+ /// <tr><th> Responsibilities <th> Collaborations
+ /// <tr><td> Provide a message producer for sending messages.
+ /// <td> <see cref="CircuitEnd"/>, <see cref="LocalCircuitFactory"/>, <see cref="TestUtils"/>
+ /// <tr><td> Provide a message consumer for receiving messages.
+ /// <td> <see cref="CircuitEnd"/>, <see cref="LocalCircuitFactory"/>, <see cref="TestUtils"/>
+ /// <tr><td> Supply the name of the test case that this implements.
+ /// <tr><td> Accept/Reject invites based on test parameters. <td> <see cref="MessagingTestConfigProperties"/>
+ /// <tr><td> Adapt to assigned roles. <td> <see cref="TestClientControlledTest.Roles"/>
+ /// <tr><td> Perform test case actions. <td> <see cref="MessageMonitor"/>
+ /// <tr><td> Generate test reports. <td> <see cref="MessageMonitor"/>
+ /// </table>
+ /// </summary>
+ public class TestClientCircuitEnd : CircuitEnd, TestClientControlledTest
+ {
+ /// <summary> Used for debugging. </summary>
+ private static ILog log = LogManager.GetLogger(typeof(TestClientCircuitEnd));
+
+ /// <summary> Holds the test parameters. </summary>
+ ParsedProperties testProps;
+
+ /// <summary> The number of test messages to send. </summary>
+ private int numMessages;
+
+ /// <summary> The role to be played by the test. </summary>
+ private Roles role;
+
+ /// <summary> The connection to send the test messages on. </summary>
+ private Connection connection;
+
+ /// <summary> Holds the circuit end for this test. </summary>
+ CircuitEnd circuitEnd;
+
+ /// <summary>
+ /// Holds a message monitor for this circuit end, either the monitor on the consumer when in RECEIVER more, or
+ /// a monitor updated on every message sent, when acting as a SENDER.
+ MessageMonitor messageMonitor;
+
+ /// <summary>
+ /// Should provide the name of the test case that this class implements. The exact names are defined in the
+ /// interop testing spec.
+ /// </summary>
+ /// <return> The name of the test case that this implements. </return>
+ public string getName()
+ {
+ return "DEFAULT_CIRCUIT_TEST";
+ }
+
+ /// <summary>
+ /// Determines whether the test invite that matched this test case is acceptable.
+ /// </summary>
+ /// <param name="inviteMessage"> The invitation to accept or reject. </param>
+ /// <return> <tt>true</tt> to accept the invitation, <tt>false</tt> to reject it. </return>
+ /// </summary>
+ /// <exception cref="JMSException"> Any JMSException resulting from reading the message are allowed to fall through. </exception>
+ public bool acceptInvite(Message inviteMessage) throws JMSException
+ {
+ log.debug("public bool acceptInvite(Message inviteMessage): called");
+
+ // Populate the test parameters from the invitation.
+ testProps = TestContextProperties.getInstance(MessagingTestConfigProperties.defaults);
+
+ for (Object key : testProps.keySet())
+ {
+ string propName = (String) key;
+
+ // If the test parameters is overridden by the invitation, use it instead.
+ string inviteValue = inviteMessage.getStringProperty(propName);
+
+ if (inviteValue != null)
+ {
+ testProps.setProperty(propName, inviteValue);
+ log.debug("Test invite supplied override to " + propName + " of " + inviteValue);
+ }
+
+ }
+
+ // Accept the invitation.
+ return true;
+ }
+
+ /// <summary>
+ /// Assigns the role to be played by this test case. The test parameters are fully specified in the
+ /// assignment message. When this method return the test case will be ready to execute.
+ /// </summary>
+ /// <param name="role"> The role to be played; sender or receivers. </param>
+ /// <param name="assignRoleMessage"> The role assingment message, contains the full test parameters. </param>
+ ///
+ /// <exception cref="JMSException"> Any JMSException resulting from reading the message are allowed to fall through. </exception>
+ public void assignRole(Roles role, Message assignRoleMessage) throws JMSException
+ {
+ log.debug("public void assignRole(Roles role, Message assignRoleMessage): called");
+
+ // Take note of the role to be played.
+ this.role = role;
+
+ // Extract and retain the test parameters.
+ numMessages = 1; // assignRoleMessage.getIntProperty("NUM_MESSAGES");
+
+ // Connect using the test parameters.
+ connection = TestUtils.createConnection(testProps);
+
+ // Create a circuit end that matches the assigned role and test parameters.
+ LocalCircuitFactory circuitFactory = new LocalCircuitFactory();
+
+ switch (role)
+ {
+ // Check if the sender role is being assigned, and set up a message producer if so.
+ case SENDER:
+
+ // Set up the publisher.
+ circuitEnd = circuitFactory.createPublisherCircuitEnd(connection, testProps, 0L);
+
+ // Create a custom message monitor that will be updated on every message sent.
+ messageMonitor = new MessageMonitor();
+
+ break;
+
+ // Otherwise the receivers role is being assigned, so set this up to listen for messages.
+ case RECEIVER:
+
+ // Set up the receiver.
+ circuitEnd = circuitFactory.createReceiverCircuitEnd(connection, testProps, 0L);
+
+ // Use the message monitor from the consumer for stats.
+ messageMonitor = getMessageMonitor();
+
+ break;
+ }
+
+ // Reset all messaging stats for the report.
+ messageMonitor.reset();
+
+ connection.start();
+ }
+
+ /// <summary>
+ /// Performs the test case actions. Returning from here, indicates that the sending role has completed its test.
+ /// </summary>
+ /// <param name="numMessages"> The number of test messages to send. </param>
+ ///
+ /// <exception cref="JMSException"> Any JMSException resulting from reading the message are allowed to fall through. </exception>
+ ///
+ /// <remarks> Add round robin on destinations where multiple destinations being used.</remarks>
+ ///
+ /// <remarks> Add rate limiting when rate limit specified on publishers.</remarks>
+ ///
+ /// <remarks> Add Max pending message size protection. The receiver will have to send back some acks once in a while,
+ /// to notify the publisher that its messages are being consumed. This makes the safety valve harder to
+ /// implement than in the single VM case. For example, if the limit is 1000 messages, might want to get back
+ /// an ack every 500, to notify the publisher that it can keep sending. What about pub/sub tests? Will it be
+ /// necessary to wait for an ack from every receiver? This will have the effect of rate limiting to slow
+ /// consumers too.</remarks>
+ ///
+ /// <remarks> Add commits on every commit batch size boundary.</remarks>
+ public void start(int numMessages) throws JMSException
+ {
+ log.debug("public void start(): called");
+
+ // If in the SENDER role, send the specified number of test messages to the circuit destinations.
+ if (role.equals(Roles.SENDER))
+ {
+ Message testMessage = getSession().createMessage();
+
+ for (int i = 0; i < numMessages; i++)
+ {
+ getProducer().send(testMessage);
+
+ // Increment the message count and timings.
+ messageMonitor.onMessage(testMessage);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Gets a report on the actions performed by the test case in its assigned role.
+ /// </summary>
+ /// <param name="session"> The controlSession to create the report message in. </param>
+ /// <return> The report message. </return>
+ ///
+ /// <exception cref="JMSException"> Any JMSExceptions resulting from creating the report are allowed to fall through. </exception>
+ public Message getReport(Session session) throws JMSException
+ {
+ Message report = session.createMessage();
+ report.setStringProperty("CONTROL_TYPE", "REPORT");
+
+ // Add the count of messages sent/received to the report.
+ report.setIntProperty("MESSAGE_COUNT", messageMonitor.getNumMessage());
+
+ // Add the time to send/receive messages to the report.
+ report.setLongProperty("TEST_TIME", messageMonitor.getTime());
+
+ // Add any exceptions detected to the report.
+
+ return report;
+ }
+
+ /// <summary>
+ /// Gets the message producer at this circuit end point.
+ /// </summary>
+ /// <return> The message producer at with this circuit end point. </return>
+ public MessageProducer getProducer()
+ {
+ return circuitEnd.getProducer();
+ }
+
+ /// <summary>
+ /// Gets the message consumer at this circuit end point.
+ /// </summary>
+ /// <return> The message consumer at this circuit end point. </return>
+ public MessageConsumer getConsumer()
+ {
+ return circuitEnd.getConsumer();
+ }
+
+ /// <summary>
+ /// Send the specified message over the producer at this end point.
+ /// </summary>
+ /// <param name="message"> The message to send. </param>
+ ///
+ /// <exception cref="JMSException"> Any JMS exception occuring during the send is allowed to fall through. </exception>
+ public void send(Message message) throws JMSException
+ {
+ // Send the message on the circuit ends producer.
+ circuitEnd.send(message);
+ }
+
+ /// <summary>
+ /// Gets the JMS Session associated with this circuit end point.
+ /// </summary>
+ /// <return> The JMS Session associated with this circuit end point. </return>
+ public Session getSession()
+ {
+ return circuitEnd.getSession();
+ }
+
+ /// <summary>
+ /// Closes the message producers and consumers and the sessions, associated with this circuit end point.
+ ///
+ /// <exception cref="JMSException"> Any JMSExceptions occurring during the close are allowed to fall through. </exception>
+ public void close() throws JMSException
+ {
+ // Close the producer and consumer.
+ circuitEnd.close();
+ }
+
+ /// <summary>
+ /// Returns the message monitor for reporting on received messages on this circuit end.
+ /// </summary>
+ /// <return> The message monitor for this circuit end. </return>
+ public MessageMonitor getMessageMonitor()
+ {
+ return circuitEnd.getMessageMonitor();
+ }
+
+ /// <summary>
+ /// Returns the exception monitor for reporting on exceptions received on this circuit end.
+ /// </summary>
+ /// <return> The exception monitor for this circuit end. </return>
+ public ExceptionMonitor getExceptionMonitor()
+ {
+ return circuitEnd.getExceptionMonitor();
+ }
+ }
+} \ No newline at end of file
diff --git a/qpid/dotnet/Qpid.Integration.Tests/framework/distributedcircuit/TestClientControlledTest.csx b/qpid/dotnet/Qpid.Integration.Tests/framework/distributedcircuit/TestClientControlledTest.csx
new file mode 100644
index 0000000000..cfb06aa642
--- /dev/null
+++ b/qpid/dotnet/Qpid.Integration.Tests/framework/distributedcircuit/TestClientControlledTest.csx
@@ -0,0 +1,104 @@
+/*
+ *
+ * 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.
+ *
+ */
+using javax.jms.JMSException;
+using javax.jms.Message;
+using javax.jms.MessageListener;
+using javax.jms.Session;
+
+namespace Apache.Qpid.Integration.Tests.framework.distributedtesting
+{
+ /// <summary>
+ /// TestClientControlledTest provides an interface that classes implementing test cases to run on a <see cref="TestClient"/>
+ /// node can use. Implementations must be Java beans, that is, to provide a default constructor and to implement the
+ /// <see cref="#getName"/> method.
+ ///
+ /// <p/>The methods specified in this interface are called when the <see cref="TestClient"/> receives control instructions to
+ /// apply to the test. There are control instructions to present the test case with the test invite, so that it may
+ /// choose whether or not to participate in the test, assign the test to play the sender or receiver role, start the
+ /// test and obtain the test status report.
+ ///
+ /// <p><table id="crc"><caption>CRC Card</caption>
+ /// <tr><th> Responsibilities
+ /// <tr><td> Supply the name of the test case that this implements.
+ /// <tr><td> Accept/Reject invites based on test parameters.
+ /// <tr><td> Adapt to assigned roles.
+ /// <tr><td> Perform test case actions.
+ /// <tr><td> Generate test reports.
+ /// </table>
+ /// </summary>
+ public interface TestClientControlledTest
+ {
+ /// <summary> Defines the possible test case roles that an interop test case can take on. </summary>
+ public enum Roles
+ {
+ /// <summary> Specifies the sender role. </summary>
+ SENDER,
+
+ /// <summary> Specifies the receivers role. </summary>
+ RECEIVER
+ }
+
+ /// <summary>
+ /// Should provide the name of the test case that this class implements. The exact names are defined in the
+ /// interop testing spec.
+ /// </summary>
+ /// <return> The name of the test case that this implements. </return>
+ public string getName();
+
+ /// <summary>
+ /// Determines whether the test invite that matched this test case is acceptable.
+ /// </summary>
+ /// <param name="inviteMessage"> The invitation to accept or reject. </param>
+ ///
+ /// <return> <tt>true</tt> to accept the invitation, <tt>false</tt> to reject it. </return>
+ ///
+ /// <exception cref="JMSException"> Any JMSException resulting from reading the message are allowed to fall through. </exception>
+ public bool acceptInvite(Message inviteMessage) throws JMSException;
+
+ /// <summary>
+ /// Assigns the role to be played by this test case. The test parameters are fully specified in the
+ /// assignment message. When this method return the test case will be ready to execute.
+ /// </summary>
+ /// <param name="role"> The role to be played; sender or receivers. </param>
+ /// <param name="assignRoleMessage"> The role assingment message, contains the full test parameters. </param>
+ ///
+ /// <exception cref="JMSException"> Any JMSException resulting from reading the message are allowed to fall through. </exception>
+ public void assignRole(Roles role, Message assignRoleMessage) throws JMSException;
+
+ /// <summary>
+ /// Performs the test case actions. Returning from here, indicates that the sending role has completed its test.
+ /// </summary>
+ /// <param name="numMessages"> The number of test messages to send. </param>
+ ///
+ /// <exception cref="JMSException"> Any JMSException resulting from reading the message are allowed to fall through. </exception>
+ public void start(int numMessages) throws JMSException;
+
+ /// <summary>
+ /// Gets a report on the actions performed by the test case in its assigned role.
+ /// </summary>
+ /// <param name="session"> The controlSession to create the report message in. </param>
+ ///
+ /// <return> The report message. </return>
+ ///
+ /// <exception cref="JMSException"> Any JMSExceptions resulting from creating the report are allowed to fall through. </exception>
+ public Message getReport(Session session) throws JMSException;
+ }
+} \ No newline at end of file
diff --git a/qpid/dotnet/Qpid.Integration.Tests/framework/localcircuit/LocalCircuitImpl.csx b/qpid/dotnet/Qpid.Integration.Tests/framework/localcircuit/LocalCircuitImpl.csx
new file mode 100644
index 0000000000..0594e4d781
--- /dev/null
+++ b/qpid/dotnet/Qpid.Integration.Tests/framework/localcircuit/LocalCircuitImpl.csx
@@ -0,0 +1,290 @@
+/*
+ *
+ * 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.
+ *
+ */
+using log4net;
+
+using Apache.Qpid.Integration.Tests.framework.*;
+
+using uk.co.thebadgerset.junit.extensions.util.ParsedProperties;
+
+using javax.jms.*;
+
+using System.Collections.Generic.LinkedList;
+using System.Collections.Generic.IList;
+
+namespace Apache.Qpid.Integration.Tests.framework.localcircuit
+{
+ /// <summary>
+ /// LocalCircuitImpl provides an implementation of the test circuit. This is a local only circuit implementation that
+ /// supports a single producer/consumer on each end of the circuit, with both ends of the circuit on the same JVM.
+ ///
+ /// <p/><table id="crc"><caption>CRC Card</caption>
+ /// <tr><th> Responsibilities <th> Collaborations
+ /// <tr><td> Supply the publishing and receiving ends of a test messaging circuit.
+ /// <td> <see cref="LocalPublisherImpl"/>, <see cref="LocalReceiverImpl"/>
+ /// <tr><td> Start the circuit running.
+ /// <tr><td> Close the circuit down.
+ /// <tr><td> Take a reading of the circuits state.
+ /// <tr><td> Apply assertions against the circuits state. <td> <see cref="Assertion"/>
+ /// <tr><td> Send test messages over the circuit.
+ /// <tr><td> Perform the default test procedure on the circuit.
+ /// <tr><td> Provide access to connection and controlSession exception monitors. <td> <see cref="ExceptionMonitor"/>
+ /// </table>
+ /// </summary>
+ public class LocalCircuitImpl : Circuit
+ {
+ /// <summary> Used for debugging. </summary>
+ private static ILog log = LogManager.GetLogger(typeof(LocalCircuitImpl));
+
+ /// <summary> Holds the test configuration for the circuit. </summary>
+ private ParsedProperties testProps;
+
+ /// <summary> Holds the publishing end of the circuit. </summary>
+ private LocalPublisherImpl publisher;
+
+ /// <summary> Holds the receiving end of the circuit. </summary>
+ private LocalReceiverImpl receiver;
+
+ /// <summary> Holds the connection for the publishing end of the circuit. </summary>
+ private Connection connection;
+
+ /// <summary> Holds the exception listener for the connection on the publishing end of the circuit. </summary>
+ private ExceptionMonitor connectionExceptionMonitor;
+
+ /// <summary> Holds the exception listener for the controlSession on the publishing end of the circuit. </summary>
+ private ExceptionMonitor exceptionMonitor;
+
+ /// <summary>
+ /// Creates a test circuit using the specified test parameters. The publisher, receivers, connection and
+ /// connection monitor must already have been created, to assemble the circuit.
+ /// </summary>
+ /// <param name="testProps"> The test parameters. </param>
+ /// <param name="publisher"> The test publisher. </param>
+ /// <param name="receiver"> The test receivers. </param>
+ /// <param name="connection"> The connection. </param>
+ /// <param name="connectionExceptionMonitor"> The connection exception monitor. </param>
+ public LocalCircuitImpl(ParsedProperties testProps, LocalPublisherImpl publisher, LocalReceiverImpl receiver,
+ Connection connection, ExceptionMonitor connectionExceptionMonitor)
+ {
+ this.testProps = testProps;
+ this.publisher = publisher;
+ this.receiver = receiver;
+ this.connection = connection;
+ this.connectionExceptionMonitor = connectionExceptionMonitor;
+ this.exceptionMonitor = new ExceptionMonitor();
+
+ // Set this as the parent circuit on the publisher and receivers.
+ publisher.setCircuit(this);
+ receiver.setCircuit(this);
+ }
+
+ /// <summary>
+ /// Gets the interface on the publishing end of the circuit.
+ /// </summary>
+ /// <return> The publishing end of the circuit. </return>
+ public Publisher getPublisher()
+ {
+ return publisher;
+ }
+
+ /// <summary>
+ /// Gets the local publishing circuit end, for direct manipulation.
+ /// </summary>
+ /// <return> The local publishing circuit end. </return>
+ public CircuitEnd getLocalPublisherCircuitEnd()
+ {
+ return publisher;
+ }
+
+ /// <summary>
+ /// Gets the interface on the receiving end of the circuit.
+ /// </summary>
+ /// <return> The receiving end of the circuit. </return>
+ public Receiver getReceiver()
+ {
+ return receiver;
+ }
+
+ /// <summary>
+ /// Gets the local receiving circuit end, for direct manipulation.
+ /// </summary>
+ /// <return> The local receiving circuit end. </return>
+ public CircuitEnd getLocalReceiverCircuitEnd()
+ {
+ return receiver;
+ }
+
+ /// <summary>
+ /// Checks the test circuit. The effect of this is to gather the circuits state, for both ends of the circuit,
+ /// into a report, against which assertions may be checked.
+ /// </summary>
+ public void check()
+ { }
+
+ /// <summary>
+ /// Applied a list of assertions against the test circuit. The <see cref="#check()"/> method should be called before doing
+ /// this, to ensure that the circuit has gathered its state into a report to assert against.
+ /// </summary>
+ /// <param name="assertions"> The list of assertions to apply. </param>
+ /// <return> Any assertions that failed. </return>
+ public IList<Assertion> applyAssertions(List<Assertion> assertions)
+ {
+ IList<Assertion> failures = new LinkedList<Assertion>();
+
+ for (Assertion assertion : assertions)
+ {
+ if (!assertion.apply())
+ {
+ failures.add(assertion);
+ }
+ }
+
+ return failures;
+ }
+
+ /// <summary> Connects and starts the circuit. After this method is called the circuit is ready to send messages. </summary>
+ public void start()
+ { }
+
+ /// <summary> Closes the circuit. All associated resources are closed. </summary>
+ public void close()
+ {
+ try
+ {
+ publisher.close();
+ receiver.close();
+ connection.close();
+ }
+ catch (JMSException e)
+ {
+ throw new RuntimeException("Got JMSException during close:" + e.getMessage(), e);
+ }
+ }
+
+ /// <summary> Sends a message on the test circuit. The exact nature of the message sent is controlled by the test parameters. </summary>
+ protected void send()
+ {
+ // Cast the test properties into a typed interface for convenience.
+ MessagingTestConfigProperties props = new MessagingTestConfigProperties(testProps);
+
+ bool transactional = props.getPublisherTransacted();
+ bool rollback = props.getRollbackPublisher();
+
+ // Send a message through the publisher and log any exceptions raised.
+ try
+ {
+ CircuitEnd end = getLocalPublisherCircuitEnd();
+
+ end.send(createTestMessage(end));
+
+ if (rollback)
+ {
+ end.getSession().rollback();
+ }
+ else if (transactional)
+ {
+ end.getSession().commit();
+ }
+ }
+ catch (JMSException e)
+ {
+ exceptionMonitor.onException(e);
+ }
+ }
+
+ /// <summary>
+ /// Runs the default test procedure against the circuit, and checks that all of the specified assertions hold. The
+ /// outline of the default test procedure is:
+ ///
+ /// <p/><pre>
+ /// Start the circuit.
+ /// Send test messages.
+ /// Request a status report.
+ /// Assert conditions on the publishing end of the circuit.
+ /// Assert conditions on the receiving end of the circuit.
+ /// Close the circuit.
+ /// Pass with no failed assertions or fail with a list of failed assertions.
+ /// </pre>
+ /// </summary>
+ /// <param name="numMessages"> The number of messages to send using the default test procedure. </param>
+ /// <param name="assertions"> The list of assertions to apply. </param>
+ /// <return> Any assertions that failed. </return>
+ public IList<Assertion> test(int numMessages, List<Assertion> assertions)
+ {
+ // Start the test circuit.
+ start();
+
+ // Send the requested number of test messages.
+ for (int i = 0; i < numMessages; i++)
+ {
+ send();
+ }
+
+ // Inject a short pause to allow time for exceptions to come back asynchronously.
+ TestUtils.pause(500L);
+
+ // Request a status report.
+ check();
+
+ // Clean up the publisher/receivers/controlSession/connections.
+ close();
+
+ // Apply all of the requested assertions, keeping record of any that fail.
+ IList<Assertion> failures = applyAssertions(assertions);
+
+ // Return any failed assertions to the caller.
+ return failures;
+ }
+
+ /// <summary>
+ /// Creates a message with the properties defined as per the test parameters.
+ /// </summary>
+ /// <param name="client"> The circuit end to create the message on. </param>
+ ///
+ /// <return> The test message. </return>
+ ///
+ /// <exception cref="JMSException"> Any JMSException occurring during creation of the message is allowed to fall through. </exception>
+ private Message createTestMessage(CircuitEnd client) throws JMSException
+ {
+ // Cast the test properties into a typed interface for convenience.
+ MessagingTestConfigProperties props = new MessagingTestConfigProperties(testProps);
+
+ return TestUtils.createTestMessageOfSize(client.getSession(), props.getMessageSize());
+ }
+
+ /// <summary>
+ /// Gets the exception monitor for the publishing ends connection.
+ /// </summary>
+ /// <return> The exception monitor for the publishing ends connection. </return>
+ public ExceptionMonitor getConnectionExceptionMonitor()
+ {
+ return connectionExceptionMonitor;
+ }
+
+ /// <summary>
+ /// Gets the exception monitor for the publishing ends controlSession.
+ /// </summary>
+ /// <return> The exception monitor for the publishing ends controlSession. </return>
+ public ExceptionMonitor getExceptionMonitor()
+ {
+ return exceptionMonitor;
+ }
+ }
+}
diff --git a/qpid/dotnet/Qpid.Integration.Tests/framework/localcircuit/LocalPublisherImpl.csx b/qpid/dotnet/Qpid.Integration.Tests/framework/localcircuit/LocalPublisherImpl.csx
new file mode 100644
index 0000000000..ecc94067ae
--- /dev/null
+++ b/qpid/dotnet/Qpid.Integration.Tests/framework/localcircuit/LocalPublisherImpl.csx
@@ -0,0 +1,164 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+using Apache.Qpid.Integration.Tests.framework.*;
+
+using uk.co.thebadgerset.junit.extensions.util.ParsedProperties;
+
+using javax.jms.MessageConsumer;
+using javax.jms.MessageProducer;
+using javax.jms.Session;
+
+namespace Apache.Qpid.Integration.Tests.framework.localcircuit
+{
+ /// <summary>
+ /// Provides an implementation of the <see cref="Publisher"/> interface and wraps a single message producer and consumer on
+ /// a single controlSession, as a <see cref="CircuitEnd"/>. A local publisher also acts as a circuit end, because for a locally
+ /// located circuit the assertions may be applied directly, there does not need to be any inter-process messaging
+ /// between the publisher and its single circuit end, in order to ascertain its status.
+ ///
+ /// <p/><table id="crc"><caption>CRC Card</caption>
+ /// <tr><th> Responsibilities <th> Collaborations
+ /// <tr><td> Provide a message producer for sending messages.
+ /// <tr><td> Provide a message consumer for receiving messages.
+ /// <tr><td> Provide assertion that the publisher received no exceptions.
+ /// <tr><td> Provide assertion that the publisher received a no consumers error code.
+ /// <tr><td> Provide assertion that the publisher received a no route error code.
+ /// </table>
+ /// </summary>
+ public class LocalPublisherImpl extends CircuitEndBase : Publisher
+ {
+ /// <summary> Holds a reference to the containing circuit. </summary>
+ protected LocalCircuitImpl circuit;
+
+ /// <summary>
+ /// Creates a circuit end point on the specified producer, consumer and controlSession. Monitors are also configured
+ /// for messages and exceptions received by the circuit end.
+ /// </summary>
+ /// <param name="producer"> The message producer for the circuit end point. </param>
+ /// <param name="consumer"> The message consumer for the circuit end point. </param>
+ /// <param name="session"> The controlSession for the circuit end point. </param>
+ /// <param name="messageMonitor"> The monitor to notify of all messages received by the circuit end. </param>
+ /// <param name="exceptionMonitor"> The monitor to notify of all exceptions received by the circuit end. </param>
+ public LocalPublisherImpl(MessageProducer producer, MessageConsumer consumer, Session session,
+ MessageMonitor messageMonitor, ExceptionMonitor exceptionMonitor)
+ {
+ super(producer, consumer, session, messageMonitor, exceptionMonitor);
+ }
+
+ /// <summary>
+ /// Creates a circuit end point from the producer, consumer and controlSession in a circuit end base implementation.
+ /// </summary>
+ /// <param name="end"> The circuit end base implementation to take producers and consumers from. </param>
+ public LocalPublisherImpl(CircuitEndBase end)
+ {
+ super(end.getProducer(), end.getConsumer(), end.getSession(), end.getMessageMonitor(), end.getExceptionMonitor());
+ }
+
+ /// <summary> Provides an assertion that the publisher encountered no exceptions. </summary>
+ ///
+ /// <param name="testProps"> The test configuration properties. </param>
+ ///
+ /// <return> An assertion that the publisher encountered no exceptions. </return>
+ public Assertion noExceptionsAssertion(ParsedProperties testProps)
+ {
+ return new AssertionBase()
+ {
+ public bool apply()
+ {
+ bool passed = true;
+ ExceptionMonitor sessionExceptionMonitor = circuit.getExceptionMonitor();
+ ExceptionMonitor connectionExceptionMonitor = circuit.getConnectionExceptionMonitor();
+
+ if (!connectionExceptionMonitor.assertNoExceptions())
+ {
+ passed = false;
+
+ addError("Was expecting no exceptions.\n");
+ addError("Got the following exceptions on the connection, "
+ + circuit.getConnectionExceptionMonitor());
+ }
+
+ if (!sessionExceptionMonitor.assertNoExceptions())
+ {
+ passed = false;
+
+ addError("Was expecting no exceptions.\n");
+ addError("Got the following exceptions on the producer, " + circuit.getExceptionMonitor());
+ }
+
+ return passed;
+ }
+ };
+ }
+
+ /// <summary>
+ /// Provides an assertion that the AMQP channel was forcibly closed by an error condition.
+ /// </summary>
+ /// <param name="testProps"> The test configuration properties. </param>
+ ///
+ /// <return> An assertion that the AMQP channel was forcibly closed by an error condition. </return>
+ public Assertion channelClosedAssertion(ParsedProperties testProps)
+ {
+ return new NotApplicableAssertion(testProps);
+ }
+
+ /// <summary>
+ /// Provides an assertion that the publisher got a given exception during the test.
+ /// </summary>
+ /// <param name="testProps"> The test configuration properties. </param>
+ /// <param name="exceptionClass"> The exception class to check for. </param>
+ ///
+ /// <return> An assertion that the publisher got a given exception during the test. </return>
+ public Assertion exceptionAssertion(ParsedProperties testProps, final Class<? extends Exception> exceptionClass)
+ {
+ return new AssertionBase()
+ {
+ public bool apply()
+ {
+ bool passed = true;
+ ExceptionMonitor connectionExceptionMonitor = circuit.getConnectionExceptionMonitor();
+
+ if (!connectionExceptionMonitor.assertExceptionOfType(exceptionClass))
+ {
+ passed = false;
+
+ addError("Was expecting linked exception type " + exceptionClass.getName()
+ + " on the connection.\n");
+ addError((connectionExceptionMonitor.size() > 0)
+ ? ("Actually got the following exceptions on the connection, " + connectionExceptionMonitor)
+ : "Got no exceptions on the connection.");
+ }
+
+ return passed;
+ }
+ };
+ }
+
+ /// <summary>
+ /// Sets the contianing circuit.
+ /// </summary>
+ /// <param name="circuit"> The containing circuit. </param>
+ public void setCircuit(LocalCircuitImpl circuit)
+ {
+ this.circuit = circuit;
+ }
+ }
+} \ No newline at end of file
diff --git a/qpid/dotnet/Qpid.Integration.Tests/framework/localcircuit/LocalReceiverImpl.csx b/qpid/dotnet/Qpid.Integration.Tests/framework/localcircuit/LocalReceiverImpl.csx
new file mode 100644
index 0000000000..b174a4c912
--- /dev/null
+++ b/qpid/dotnet/Qpid.Integration.Tests/framework/localcircuit/LocalReceiverImpl.csx
@@ -0,0 +1,137 @@
+/*
+ *
+ * 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.
+ *
+ */
+using Apache.Qpid.Integration.Tests.framework.*;
+
+using uk.co.thebadgerset.junit.extensions.util.ParsedProperties;
+
+using javax.jms.MessageConsumer;
+using javax.jms.MessageProducer;
+using javax.jms.Session;
+
+namespace Apache.Qpid.Integration.Tests.framework.localcircuit
+{
+ /// <summary>
+ /// Provides an implementation of the <see cref="Receiver"/> interface that wraps a single message producer and consumer on
+ /// a single controlSession, as a <see cref="CircuitEnd"/>. A local receiver also acts as a circuit end, because for a locally
+ /// located circuit the assertions may be applied directly, there does not need to be any inter process messaging
+ /// between the publisher and its single circuit end, in order to ascertain its status.
+ ///
+ /// <p/><table id="crc"><caption>CRC Card</caption>
+ /// <tr><th> Responsibilities <th> Collaborations
+ /// <tr><td> Provide a message producer for sending messages.
+ /// <tr><td> Provide a message consumer for receiving messages.
+ /// <tr><td> Provide assertion that the receivers received no exceptions.
+ /// <tr><td> Provide assertion that the receivers received all test messages sent to it.
+ /// </table>
+ /// </summary>
+ public class LocalReceiverImpl extends CircuitEndBase : Receiver
+ {
+ /// <summary> Holds a reference to the containing circuit. </summary>
+ private LocalCircuitImpl circuit;
+
+ /// <summary>
+ /// Creates a circuit end point on the specified producer, consumer and controlSession. Monitors are also configured
+ /// for messages and exceptions received by the circuit end.
+ /// </summary>
+ /// <param name="producer"> The message producer for the circuit end point. </param>
+ /// <param name="consumer"> The message consumer for the circuit end point. </param>
+ /// <param name="session"> The controlSession for the circuit end point. </param>
+ /// <param name="messageMonitor"> The monitor to notify of all messages received by the circuit end. </param>
+ /// <param name="exceptionMonitor"> The monitor to notify of all exceptions received by the circuit end. </param>
+ public LocalReceiverImpl(MessageProducer producer, MessageConsumer consumer, Session session,
+ MessageMonitor messageMonitor, ExceptionMonitor exceptionMonitor)
+ {
+ super(producer, consumer, session, messageMonitor, exceptionMonitor);
+ }
+
+ /// <summary>
+ /// Creates a circuit end point from the producer, consumer and controlSession in a circuit end base implementation.
+ /// </summary>
+ /// <param name="end"> The circuit end base implementation to take producers and consumers from. </param>
+ public LocalReceiverImpl(CircuitEndBase end)
+ {
+ super(end.getProducer(), end.getConsumer(), end.getSession(), end.getMessageMonitor(), end.getExceptionMonitor());
+ }
+
+ /// <summary>
+ /// Provides an assertion that the receivers encountered no exceptions.
+ /// </summary>
+ /// <param name="testProps"> The test configuration properties. </param>
+ ///
+ /// <return> An assertion that the receivers encountered no exceptions. </return>
+ public Assertion noExceptionsAssertion(ParsedProperties testProps)
+ {
+ return new NotApplicableAssertion(testProps);
+ }
+
+ /// <summary>
+ /// Provides an assertion that the AMQP channel was forcibly closed by an error condition.
+ /// </summary>
+ /// <param name="testProps"> The test configuration properties. </param>
+ ///
+ /// <return> An assertion that the AMQP channel was forcibly closed by an error condition. </return>
+ public Assertion channelClosedAssertion(ParsedProperties testProps)
+ {
+ return new NotApplicableAssertion(testProps);
+ }
+
+ /// <summary>
+ /// Provides an assertion that the receivers got all messages that were sent to it.
+ /// </summary>
+ /// <param name="testProps"> The test configuration properties. </param>
+ ///
+ /// <return> An assertion that the receivers got all messages that were sent to it. </return>
+ public Assertion allMessagesReceivedAssertion(ParsedProperties testProps)
+ {
+ return new NotApplicableAssertion(testProps);
+ }
+
+ /// <summary>
+ /// Provides an assertion that the receivers got none of the messages that were sent to it.
+ /// </summary>
+ /// <param name="testProps"> The test configuration properties. </param>
+ ///
+ /// <return> An assertion that the receivers got none of the messages that were sent to it. </return>
+ public Assertion noMessagesReceivedAssertion(ParsedProperties testProps)
+ {
+ return new NotApplicableAssertion(testProps);
+ }
+
+ /// <summary>
+ /// Provides an assertion that the receiver got a given exception during the test.
+ /// </summary>
+ /// <param name="testProps"> The test configuration properties. </param>
+ /// <param name="exceptionClass"> The exception class to check for. <return> An assertion that the receiver got a given exception during the test. </return> </param>
+ public Assertion exceptionAssertion(ParsedProperties testProps, Class<? extends Exception> exceptionClass)
+ {
+ return new NotApplicableAssertion(testProps);
+ }
+
+ /// <summary>
+ /// Sets the contianing circuit.
+ /// </summary>
+ /// <param name="circuit"> The containing circuit. </param>
+ public void setCircuit(LocalCircuitImpl circuit)
+ {
+ this.circuit = circuit;
+ }
+ }
+} \ No newline at end of file
diff --git a/qpid/dotnet/Qpid.Integration.Tests/framework/sequencers/BaseCircuitFactory.csx b/qpid/dotnet/Qpid.Integration.Tests/framework/sequencers/BaseCircuitFactory.csx
new file mode 100644
index 0000000000..79ddfd878f
--- /dev/null
+++ b/qpid/dotnet/Qpid.Integration.Tests/framework/sequencers/BaseCircuitFactory.csx
@@ -0,0 +1,128 @@
+/*
+ *
+ * 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.
+ *
+ */
+using log4net;
+
+using Apache.Qpid.Integration.Tests.framework.Circuit;
+using Apache.Qpid.Integration.Tests.framework.TestClientDetails;
+using org.apache.qpid.util.ConversationFactory;
+
+using System.Collections.Generic.LinkedList;
+using System.Collections.Generic.IList;
+using java.util.Properties;
+
+namespace Apache.Qpid.Integration.Tests.framework.sequencers
+{
+ /// <summary>
+ /// BaseCircuitFactory provides some functionality common to all <see cref="CircuitFactory"/>s, such as the details of
+ /// all <see cref="Apache.Qpid.Integration.Tests.framework.distributedtesting.TestClient"/>s that make up the end-points of
+ /// the circuits that the factory creates, and an active <see cref="ConversationFactory"/> that can be used to generate
+ /// control conversations with those circuit end-points.
+ ///
+ /// <p/><table id="crc"><caption>CRC Card</caption>
+ /// <tr><th> Responsibilities <th> Collaborations
+ /// <tr><td> Hold the details of the sending and receiving end-points to create circuits from.
+ /// <tr><td> Provide a conversation factory to create control conversations with the end-points.
+ /// </table>
+ /// </summary>
+ public abstract class BaseCircuitFactory : CircuitFactory
+ {
+ /// <summary> Used for debugging. </summary>
+ private static ILog log = LogManager.GetLogger(typeof(BaseCircuitFactory));
+
+ /// <summary> Holds the contact details for the sending test client. </summary>
+ protected TestClientDetails sender;
+
+ /// <summary> Holds the contact details for the receving test client. </summary>
+ protected IList<TestClientDetails> receivers = new LinkedList<TestClientDetails>();
+
+ /// <summary> Holds the conversation factory over which to coordinate the test. </summary>
+ protected ConversationFactory conversationFactory;
+
+ /// <summary>
+ /// Creates a test circuit for the test, configered by the test parameters specified.
+ /// </summary>
+ /// <param name="testProperties"> The test parameters. </param>
+ /// <return> A test circuit. </return>
+ public Circuit createCircuit(Properties testProperties)
+ {
+ throw new RuntimeException("Not implemented.");
+ }
+
+ /// <summary>
+ /// Sets the sender test client to coordinate the test with.
+ /// </summary>
+ /// <param name="sender"> The contact details of the sending client in the test. </param>
+ public void setSender(TestClientDetails sender)
+ {
+ log.debug("public void setSender(TestClientDetails sender = " + sender + "): called");
+
+ this.sender = sender;
+ }
+
+ /// <summary>
+ /// Sets the receiving test client to coordinate the test with.
+ /// </summary>
+ /// <param name="receiver"> The contact details of the sending client in the test. </param>
+ public void setReceiver(TestClientDetails receiver)
+ {
+ log.debug("public void setReceiver(TestClientDetails receivers = " + receiver + "): called");
+
+ this.receivers.add(receiver);
+ }
+
+ /// <summary>
+ /// Supplies the sending test client.
+ /// </summary>
+ /// <return> The sending test client. </return>
+ public TestClientDetails getSender()
+ {
+ return sender;
+ }
+
+ /// <summary>
+ /// Supplies the receiving test client.
+ /// </summary>
+ /// <return> The receiving test client. </return>
+ public IList<TestClientDetails> getReceivers()
+ {
+ return receivers;
+ }
+
+ /// <summary>
+ /// Accepts the conversation factory over which to hold the test coordinating conversation.
+ /// </summary>
+ /// <param name="conversationFactory"> The conversation factory to coordinate the test over. </param>
+ public void setConversationFactory(ConversationFactory conversationFactory)
+ {
+ this.conversationFactory = conversationFactory;
+ }
+
+ /// <summary>
+ /// Provides the conversation factory for providing the distributed test sequencing conversations over the test
+ /// connection.
+ /// </summary>
+ /// <return> The conversation factory to create test sequencing conversations with. </return>
+ public ConversationFactory getConversationFactory()
+ {
+ return conversationFactory;
+ }
+ }
+} \ No newline at end of file
diff --git a/qpid/dotnet/Qpid.Integration.Tests/framework/sequencers/CircuitFactory.cs b/qpid/dotnet/Qpid.Integration.Tests/framework/sequencers/CircuitFactory.cs
new file mode 100644
index 0000000000..4be08c3f38
--- /dev/null
+++ b/qpid/dotnet/Qpid.Integration.Tests/framework/sequencers/CircuitFactory.cs
@@ -0,0 +1,85 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+using Apache.Qpid.Integration.Tests.framework;
+//using org.apache.qpid.util.ConversationFactory;
+
+//using uk.co.thebadgerset.junit.extensions.util.ParsedProperties;
+
+//using javax.jms.JMSException;
+//using javax.jms.Message;
+
+using System.Collections.Generic;//.IList;
+//using System.Collections.Generic.IDictionary;
+//using java.util.Properties;
+
+namespace Apache.Qpid.Integration.Tests.framework.sequencers
+{
+ /// <summary>
+ /// A CircuitFactory is responsibile for creating test circuits appropriate to the context that a test case is
+ /// running in, and providing an implementation of a standard test procedure over a test circuit.
+ ///
+ /// <p/><table id="crc"><caption>CRC Card</caption>
+ /// <tr><th> Responsibilities
+ /// <tr><td> Provide a standard test procedure over a test circuit.
+ /// <tr><td> Construct test circuits appropriate to a tests context.
+ /// </table>
+ /// </summary>
+ public interface CircuitFactory
+ {
+ /// <summary>
+ /// Creates a test circuit for the test, configered by the test parameters specified.
+ /// </summary>
+ /// <param name="testProperties"> The test parameters. </param>
+ ///
+ /// <return> A test circuit. </return>
+ Circuit CreateCircuit(TestModel testProperties);
+
+ /// <summary>
+ /// Sets the sender test client to coordinate the test with.
+ /// </summary>
+ /// <param name="sender"> The contact details of the sending client in the test. </param>
+ void SetSender(TestClientDetails sender);
+
+ /// <summary>
+ /// Sets the receiving test client to coordinate the test with.
+ /// </summary>
+ /// <param name="receiver"> The contact details of the sending client in the test. </param>
+ void SetReceiver(TestClientDetails receiver);
+
+ /// <summary>
+ /// Supplies the sending test client.
+ /// </summary>
+ /// <return> The sending test client. </return>
+ TestClientDetails GetSender();
+
+ /// <summary>
+ /// Supplies the receiving test client.
+ /// </summary>
+ /// <return> The receiving test client. </return>
+ IList<TestClientDetails> GetReceivers();
+
+ /// <summary>
+ /// Accepts the conversation factory over which to hold the test coordinating conversation.
+ /// </summary>
+ /// <param name="conversationFactory"> The conversation factory to coordinate the test over. </param>
+ //void setConversationFactory(ConversationFactory conversationFactory);
+ }
+} \ No newline at end of file
diff --git a/qpid/dotnet/Qpid.Integration.Tests/framework/sequencers/CircuitFactory.csx b/qpid/dotnet/Qpid.Integration.Tests/framework/sequencers/CircuitFactory.csx
new file mode 100644
index 0000000000..26632266a4
--- /dev/null
+++ b/qpid/dotnet/Qpid.Integration.Tests/framework/sequencers/CircuitFactory.csx
@@ -0,0 +1,99 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+using Apache.Qpid.Integration.Tests.framework.Assertion;
+using Apache.Qpid.Integration.Tests.framework.Circuit;
+using Apache.Qpid.Integration.Tests.framework.TestClientDetails;
+using org.apache.qpid.util.ConversationFactory;
+
+using uk.co.thebadgerset.junit.extensions.util.ParsedProperties;
+
+using javax.jms.JMSException;
+using javax.jms.Message;
+
+using System.Collections.Generic.IList;
+using System.Collections.Generic.IDictionary;
+using java.util.Properties;
+
+namespace Apache.Qpid.Integration.Tests.framework.sequencers
+{
+ /// <summary>
+ /// A CircuitFactory is responsibile for creating test circuits appropriate to the context that a test case is
+ /// running in, and providing an implementation of a standard test procedure over a test circuit.
+ ///
+ /// <p/><table id="crc"><caption>CRC Card</caption>
+ /// <tr><th> Responsibilities
+ /// <tr><td> Provide a standard test procedure over a test circuit.
+ /// <tr><td> Construct test circuits appropriate to a tests context.
+ /// </table>
+ /// </summary>
+ public interface CircuitFactory
+ {
+ /// <summary>
+ /// Holds a test coordinating conversation with the test clients. This should consist of assigning the test roles,
+ /// begining the test, gathering the test reports from the participants, and checking for assertion failures against
+ /// the test reports.
+ /// </summary>
+ /// <param name="testCircuit"> The test circuit. </param>
+ /// <param name="assertions"> The list of assertions to apply to the test circuit. </param>
+ /// <param name="testProperties"> The test case definition. </param>
+ ///
+ /// @deprecated Use test circuits and Circuit.test instead.
+ public void sequenceTest(Circuit testCircuit, IList<Assertion> assertions, Properties testProperties);
+
+ /// <summary>
+ /// Creates a test circuit for the test, configered by the test parameters specified.
+ /// </summary>
+ /// <param name="testProperties"> The test parameters. </param>
+ ///
+ /// <return> A test circuit. </return>
+ public Circuit createCircuit(ParsedProperties testProperties);
+
+ /// <summary>
+ /// Sets the sender test client to coordinate the test with.
+ /// </summary>
+ /// <param name="sender"> The contact details of the sending client in the test. </param>
+ public void setSender(TestClientDetails sender);
+
+ /// <summary>
+ /// Sets the receiving test client to coordinate the test with.
+ /// </summary>
+ /// <param name="receiver"> The contact details of the sending client in the test. </param>
+ public void setReceiver(TestClientDetails receiver);
+
+ /// <summary>
+ /// Supplies the sending test client.
+ /// </summary>
+ /// <return> The sending test client. </return>
+ public TestClientDetails getSender();
+
+ /// <summary>
+ /// Supplies the receiving test client.
+ /// </summary>
+ /// <return> The receiving test client. </return>
+ public IList<TestClientDetails> getReceivers();
+
+ /// <summary>
+ /// Accepts the conversation factory over which to hold the test coordinating conversation.
+ /// </summary>
+ /// <param name="conversationFactory"> The conversation factory to coordinate the test over. </param>
+ public void setConversationFactory(ConversationFactory conversationFactory);
+ }
+} \ No newline at end of file
diff --git a/qpid/dotnet/Qpid.Integration.Tests/interactive/FailoverTest.cs b/qpid/dotnet/Qpid.Integration.Tests/interactive/FailoverTest.cs
new file mode 100644
index 0000000000..142ac40b27
--- /dev/null
+++ b/qpid/dotnet/Qpid.Integration.Tests/interactive/FailoverTest.cs
@@ -0,0 +1,397 @@
+/*
+ *
+ * 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.
+ *
+ */
+using System;
+using System.Runtime.InteropServices;
+using System.Threading;
+using log4net;
+using NUnit.Framework;
+using Apache.Qpid.Client.Qms;
+using Apache.Qpid.Client;
+using Apache.Qpid.Messaging;
+
+namespace Apache.Qpid.Integration.Tests.interactive
+{
+ [TestFixture, Category("Interactive")]
+ public class FailoverTest : IConnectionListener
+ {
+ private static readonly ILog _log = LogManager.GetLogger(typeof(FailoverTest));
+
+ /// <summary>Specifies the number of times to run the test cycle.</summary>
+ const int NUM_MESSAGES = 10;
+
+ /// <summary>Determines how many messages to send within each commit.</summary>
+ const int COMMIT_BATCH_SIZE = 1;
+
+ /// <summary>Specifies the duration of the pause to place between each message sent in the test.</summary>
+ //const int SLEEP_MILLIS = 1;
+
+ /// <summary>Specified the maximum time in milliseconds to wait for the test to complete.</summary>
+ const int TIMEOUT = 10000;
+
+ /// <summary>Defines the number of test messages to send, before prompting the user to fail a broker.</summary>
+ const int FAIL_POINT = 5;
+
+ /// <summary>Specified the ack mode to use for the test.</summary>
+ AcknowledgeMode _acknowledgeMode = AcknowledgeMode.AutoAcknowledge;
+
+ /// <summary>Determines whether this test runs transactionally or not. </summary>
+ bool transacted = false;
+
+ /// <summary>Holds the connection to run the test over.</summary>
+ AMQConnection _connection;
+
+ /// <summary>Holds the channel for the test message publisher. </summary>
+ IChannel publishingChannel;
+
+ /// <summary>Holds the test message publisher. </summary>
+ IMessagePublisher publisher;
+
+ /// <summary>Used to keep count of the number of messages sent. </summary>
+ int messagesSent;
+
+ /// <summary>Used to keep count of the number of messages received. </summary>
+ int messagesReceived;
+
+ /// <summary>Used to wait for test completion on. </summary>
+ private static object testComplete = new Object();
+
+ /// <summary>Used to wait for failover completion on. </summary>
+ private static object failoverComplete = new Object();
+
+ bool failedOver=false;
+
+ /// <summary>Used to record the extra message count (1) if the message sent right after failover actually made it to the new broker.</summary>
+ int _extraMessage = 0;
+
+ /// <summary>
+ /// Creates the test connection with a fail-over set up, and a producer/consumer pair on that connection.
+ /// </summary>
+ /// [SetUp]
+ public void Init(IConnectionInfo connectionInfo)
+ {
+ //log4net.Config.BasicConfigurator.Configure();
+ // Reset all counts.
+ messagesSent = 0;
+ messagesReceived = 0;
+ failedOver=false;
+ _extraMessage = 0;
+
+ PromptAndWait("Ensure both brokers are running, then press Enter");
+
+ // Create a connection for the test.
+ _connection = new AMQConnection(connectionInfo);
+ _connection.ConnectionListener = this;
+
+ // Create a consumer to receive the test messages.
+ IChannel receivingChannel = _connection.CreateChannel(false, _acknowledgeMode);
+
+ string queueName = receivingChannel.GenerateUniqueName();
+ receivingChannel.DeclareQueue(queueName, false, true, true);
+ receivingChannel.Bind(queueName, "amq.direct", queueName);
+
+ IMessageConsumer consumer = receivingChannel.CreateConsumerBuilder(queueName)
+ .WithPrefetchLow(30)
+ .WithPrefetchHigh(60).Create();
+
+ consumer.OnMessage = new MessageReceivedDelegate(OnMessage);
+ _connection.Start();
+
+ // Create a publisher to send the test messages.
+ publishingChannel = _connection.CreateChannel(transacted, AcknowledgeMode.NoAcknowledge);
+ publisher = publishingChannel.CreatePublisherBuilder()
+ .WithRoutingKey(queueName)
+ .Create();
+
+ _log.Debug("connection = " + _connection);
+ _log.Debug("connectionInfo = " + connectionInfo);
+ _log.Debug("connection.AsUrl = " + _connection.toURL());
+ _log.Debug("AcknowledgeMode is " + _acknowledgeMode);
+ }
+
+ /// <summary>
+ /// Clean up the test connection.
+ /// </summary>
+ [TearDown]
+ public virtual void Shutdown()
+ {
+ if (!failedOver)
+ {
+ Assert.Fail("The failover callback never occured.");
+ }
+
+ Console.WriteLine("Test done shutting down");
+ Thread.Sleep(2000);
+ _connection.Close();
+ }
+
+ /// <summary>
+ /// Runs a failover test, building up the connection information from its component parts. In particular the brokers
+ /// to fail between are seperately added into the connection info.
+ /// </summary>
+ /*[Test]
+ public void TestWithBasicInfo()
+ {
+ _log.Debug("public void TestWithBasicInfo(): called");
+
+ // Manually create the connection parameters.
+ QpidConnectionInfo connectionInfo = new QpidConnectionInfo();
+ connectionInfo.AddBrokerInfo(new AmqBrokerInfo("amqp", "localhost", 5672, false));
+ connectionInfo.AddBrokerInfo(new AmqBrokerInfo("amqp", "localhost", 5673, false));
+
+ Init(connectionInfo);
+ DoFailoverTest();
+ }*/
+
+ /// <summary>
+ /// Runs a failover test, with the failover configuration specified in the Qpid connection URL format.
+ /// </summary>
+ [Test]
+ public void TestWithUrl()
+ {
+ _log.Debug("public void runTestWithUrl(): called");
+
+ // Parse the connection parameters from a URL.
+ String clientId = "failover" + DateTime.Now.Ticks;
+ string defaultUrl = "amqp://guest:guest@" + clientId + "/test" +
+ "?brokerlist='tcp://localhost:9672;tcp://localhost:9673'&failover='roundrobin'";
+ IConnectionInfo connectionInfo = QpidConnectionInfo.FromUrl(defaultUrl);
+
+ Init(connectionInfo);
+ DoFailoverTest(0);
+ }
+
+ /// <summary>
+ /// Send the test messages, prompting at the fail point for the user to cause a broker failure. The test checks that all messages sent
+ /// are received within the test time limit.
+ /// </summary>
+ ///
+ /// <param name="connectionInfo">The connection parameters, specifying the brokers to fail between.</param>
+ void DoFailoverTest(int delay)
+ {
+ _log.Debug("void DoFailoverTest(IConnectionInfo connectionInfo): called");
+
+ // Wait for all of the test messages to be received, checking that this occurs within the test time limit.
+ bool withinTimeout = false;
+
+ for (int i = 1; i <= NUM_MESSAGES; ++i)
+ {
+ SendMessage();
+
+ // Prompt the user to cause a failure if at the fail point.
+ if (i == FAIL_POINT)
+ {
+ for( int min = delay ; min > 0 ; min--)
+ {
+ Console.WriteLine("Waiting for "+min+" minutes to test connection time bug.");
+ Thread.Sleep(60*1000);
+ }
+
+ PromptAndWait("Cause a broker failure now, then press return.");
+ Console.WriteLine("NOTE: ensure that the delay between killing the broker and continuing here is less than 20 second");
+
+ Console.WriteLine("Sending a message to ensure send right after works");
+
+ SendMessage();
+
+ Console.WriteLine("Waiting for fail-over to complete before continuing...");
+
+
+ lock(failoverComplete)
+ {
+ if (!failedOver)
+ {
+ withinTimeout = Monitor.Wait(failoverComplete, TIMEOUT);
+ }
+ else
+ {
+ withinTimeout=true;
+ }
+ }
+
+ if (!withinTimeout)
+ {
+ PromptAndWait("Failover has not yet occured. Press enter to give up waiting.");
+ }
+ }
+ }
+
+ lock(testComplete)
+ {
+ withinTimeout = Monitor.Wait(testComplete, TIMEOUT);
+ }
+
+ if (!withinTimeout)
+ {
+ Assert.Fail("Test timed out, before all messages received.");
+ }
+
+ _log.Debug("void DoFailoverTest(IConnectionInfo connectionInfo): exiting");
+ }
+
+ [Test]
+ public void Test5MinuteWait()
+ {
+ String clientId = "failover" + DateTime.Now.Ticks;
+
+ QpidConnectionInfo connectionInfo = new QpidConnectionInfo();
+ connectionInfo.Username = "guest";
+ connectionInfo.Password = "guest";
+ connectionInfo.ClientName = clientId;
+ connectionInfo.VirtualHost = "/test";
+ connectionInfo.AddBrokerInfo(new AmqBrokerInfo("amqp", "localhost", 9672, false));
+ connectionInfo.AddBrokerInfo(new AmqBrokerInfo("amqp", "localhost", 9673, false));
+
+ Init(connectionInfo);
+ DoFailoverTest(5);
+ }
+
+ void SendMessage()
+ {
+ ITextMessage msg = publishingChannel.CreateTextMessage("message=" + messagesSent);
+
+ publisher.Send(msg);
+ messagesSent++;
+
+ if (transacted)
+ {
+ publishingChannel.Commit();
+ }
+
+ Console.WriteLine("messagesSent = " + messagesSent);
+ }
+
+ /// <summary>
+ /// Receives all of the test messages.
+ /// </summary>
+ ///
+ /// <param name="message">The newly arrived test message.</param>
+ public void OnMessage(IMessage message)
+ {
+ try
+ {
+ if (_acknowledgeMode == AcknowledgeMode.ClientAcknowledge)
+ {
+ message.Acknowledge();
+ }
+
+ messagesReceived++;
+
+ _log.Debug("messagesReceived = " + messagesReceived);
+
+ // Check if all of the messages in the test have been received, in which case notify the message producer that the test has
+ // succesfully completed.
+ if (messagesReceived == NUM_MESSAGES + _extraMessage)
+ {
+ lock (testComplete)
+ {
+ failedOver = true;
+ Monitor.Pulse(testComplete);
+ }
+ }
+ }
+ catch (QpidException e)
+ {
+ _log.Fatal("Exception received. About to stop.", e);
+ Stop();
+ }
+ }
+
+ /// <summary>Prompts the user on stdout and waits for a reply on stdin, using the specified prompt message.</summary>
+ ///
+ /// <param name="message">The message to prompt the user with.</param>
+ private void PromptAndWait(string message)
+ {
+ Console.WriteLine("\n" + message);
+ Console.ReadLine();
+ }
+
+ // <summary>Closes the test connection.</summary>
+ private void Stop()
+ {
+ _log.Debug("Stopping...");
+ try
+ {
+ _connection.Close();
+ }
+ catch (QpidException e)
+ {
+ _log.Debug("Failed to shutdown: ", e);
+ }
+ }
+
+ /// <summary>
+ /// Called when bytes have been transmitted to the server
+ /// </summary>
+ ///
+ /// <param>count the number of bytes sent in total since the connection was opened</param>
+ public void BytesSent(long count) {}
+
+ /// <summary>
+ /// Called when some bytes have been received on a connection
+ /// </summary>
+ ///
+ /// <param>count the number of bytes received in total since the connection was opened</param>
+ public void BytesReceived(long count) {}
+
+ /// <summary>
+ /// Called after the infrastructure has detected that failover is required but before attempting failover.
+ /// </summary>
+ ///
+ /// <param>redirect true if the broker requested redirect. false if failover is occurring due to a connection error.</param>
+ ///
+ /// <return>true to continue failing over, false to veto failover and raise a connection exception</return>
+ public bool PreFailover(bool redirect)
+ {
+ _log.Debug("public bool PreFailover(bool redirect): called");
+ return true;
+ }
+
+ /// <summary>
+ /// Called after connection has been made to another broker after failover has been started but before
+ /// any resubscription has been done.
+ /// </summary>
+ ///
+ /// <return> true to continue with resubscription, false to prevent automatic resubscription. This is useful in
+ /// cases where the application wants to handle resubscription. Note that in the latter case all sessions, producers
+ /// and consumers are invalidated.
+ /// </return>
+ public bool PreResubscribe()
+ {
+ _log.Debug("public bool PreResubscribe(): called");
+ return true;
+ }
+
+ /// <summary>
+ /// Called once failover has completed successfully. This is called irrespective of whether the client has
+ /// vetoed automatic resubscription.
+ /// </summary>
+ public void FailoverComplete()
+ {
+ failedOver = true;
+ _log.Debug("public void FailoverComplete(): called");
+ Console.WriteLine("public void FailoverComplete(): called");
+ lock (failoverComplete)
+ {
+ Monitor.Pulse(failoverComplete);
+ }
+ }
+ }
+}
diff --git a/qpid/dotnet/Qpid.Integration.Tests/interactive/SendReceiveTest.cs b/qpid/dotnet/Qpid.Integration.Tests/interactive/SendReceiveTest.cs
new file mode 100644
index 0000000000..68d7a2ae68
--- /dev/null
+++ b/qpid/dotnet/Qpid.Integration.Tests/interactive/SendReceiveTest.cs
@@ -0,0 +1,181 @@
+/*
+ *
+ * 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.
+ *
+ */
+using System;
+using System.Threading;
+using log4net;
+using NUnit.Framework;
+using Apache.Qpid.Messaging;
+using Apache.Qpid.Client.Qms;
+using Apache.Qpid.Client;
+using Apache.Qpid.Integration.Tests.testcases;
+
+namespace Apache.Qpid.Integration.Tests.interactive
+{
+ /// <summary>
+ /// SendReceiveTest provides a quick interactive send-receive test, where the user is prompted to trigger each send or receive.
+ ///
+ /// <p><table id="crc"><caption>CRC Card</caption>
+ /// <tr><th> Responsibilities <th> Collaborations
+ /// <tr><td> Run an interactive send-receive loop prompting user to trigger each event.
+ /// </table>
+ /// </summary>
+ [TestFixture, Category("Interactive")]
+ public class SendReceiveTest : BaseMessagingTestFixture
+ {
+ /// <summary>Used for debugging purposes.</summary>
+ private static ILog log = LogManager.GetLogger(typeof(SendReceiveTest));
+
+ /// <summary>Defines the name of the test topic to use with the tests.</summary>
+ public const string TEST_ROUTING_KEY = "quicktestkey";
+
+ /// <summary>The number of consumers to test.</summary>
+ private const int CONSUMER_COUNT = 5;
+
+ /// <summary>The number of test messages to send.</summary>
+ private const int MESSAGE_COUNT = 10;
+
+ /// <summary>Monitor used to signal succesfull receipt of all test messages.</summary>
+ AutoResetEvent _finishedEvent;
+
+ /// <summary>Used to count test messages received so far.</summary>
+ private int _messageReceivedCount;
+
+ /// <summary>Used to hold the expected number of messages to receive.</summary>
+ private int expectedMessageCount;
+
+ /// <summary>Flag used to indicate that all messages really were received, and that the test did not just time out. </summary>
+ private bool allReceived;
+
+ /// <summary> Creates one producing end-point and many consuming end-points connected on a topic. </summary>
+ [SetUp]
+ public override void Init()
+ {
+ base.Init();
+
+ // Reset all test counts and flags.
+ _messageReceivedCount = 0;
+ allReceived = false;
+ _finishedEvent = new AutoResetEvent(false);
+ }
+
+ /// <summary> Cleans up all test end-points. </summary>
+ [TearDown]
+ public override void Shutdown()
+ {
+ try
+ {
+ // Close all end points for producer and consumers.
+ // Producer is on 0, and consumers on 1 .. n, so loop is from 0 to n inclusive.
+ for (int i = 0; i <= CONSUMER_COUNT; i++)
+ {
+ CloseEndPoint(i);
+ }
+ }
+ finally
+ {
+ base.Shutdown();
+ }
+ }
+
+ /// <summary> Check that all consumers on a topic each receive all message on it. </summary>
+ [Test]
+ public void AllConsumerReceiveAllMessagesOnTopic()
+ {
+ // Create end-points for all the consumers in the test.
+ for (int i = 1; i <= CONSUMER_COUNT; i++)
+ {
+ SetUpEndPoint(i, false, true, TEST_ROUTING_KEY + testId, AcknowledgeMode.AutoAcknowledge, false, ExchangeNameDefaults.TOPIC,
+ true, false, null);
+ testConsumer[i].OnMessage += new MessageReceivedDelegate(OnMessage);
+ }
+
+ // Create an end-point to publish to the test topic.
+ SetUpEndPoint(0, true, false, TEST_ROUTING_KEY + testId, AcknowledgeMode.AutoAcknowledge, false, ExchangeNameDefaults.TOPIC,
+ true, false, null);
+
+ expectedMessageCount = (MESSAGE_COUNT * CONSUMER_COUNT);
+
+ PromptAndWait("Press to send...");
+
+ for (int i = 0; i < MESSAGE_COUNT; i++)
+ {
+ testProducer[0].Send(testChannel[0].CreateTextMessage("A"));
+ }
+
+ _finishedEvent.WaitOne(new TimeSpan(0, 0, 0, 10), false);
+
+ PromptAndWait("Press to complete test...");
+
+ // Check that all messages really were received.
+ Assert.IsTrue(allReceived, "All messages were not received, only got " + _messageReceivedCount + " but wanted " + expectedMessageCount);
+ }
+
+ /// <summary> Check that consumers on the same queue receive each message once accross all consumers. </summary>
+ //[Test]
+ public void AllConsumerReceiveAllMessagesOnDirect()
+ {
+ // Create end-points for all the consumers in the test.
+ for (int i = 1; i <= CONSUMER_COUNT; i++)
+ {
+ SetUpEndPoint(i, false, true, TEST_ROUTING_KEY + testId, AcknowledgeMode.AutoAcknowledge, false, ExchangeNameDefaults.DIRECT,
+ true, false, null);
+ testConsumer[i].OnMessage += new MessageReceivedDelegate(OnMessage);
+ }
+
+ // Create an end-point to publish to the test topic.
+ SetUpEndPoint(0, true, false, TEST_ROUTING_KEY + testId, AcknowledgeMode.AutoAcknowledge, false, ExchangeNameDefaults.DIRECT,
+ true, false, null);
+
+ expectedMessageCount = MESSAGE_COUNT;
+
+ for (int i = 0; i < MESSAGE_COUNT; i++)
+ {
+ testProducer[0].Send(testChannel[0].CreateTextMessage("A"));
+ }
+
+ _finishedEvent.WaitOne(new TimeSpan(0, 0, 0, 10), false);
+
+ // Check that all messages really were received.
+ Assert.IsTrue(allReceived, "All messages were not received, only got: " + _messageReceivedCount + " but wanted " + expectedMessageCount);
+ }
+
+ /// <summary> Atomically increments the message count on every message, and signals once all messages in the test are received. </summary>
+ public void OnMessage(IMessage m)
+ {
+ int newCount = Interlocked.Increment(ref _messageReceivedCount);
+
+ if (newCount >= expectedMessageCount)
+ {
+ allReceived = true;
+ _finishedEvent.Set();
+ }
+ }
+
+ /// <summary>Prompts the user on stdout and waits for a reply on stdin, using the specified prompt message.</summary>
+ ///
+ /// <param name="message">The message to prompt the user with.</param>
+ private void PromptAndWait(string message)
+ {
+ Console.WriteLine("\n" + message);
+ Console.ReadLine();
+ }
+ }
+} \ No newline at end of file
diff --git a/qpid/dotnet/Qpid.Integration.Tests/interop/InteropClientTestCase.cs b/qpid/dotnet/Qpid.Integration.Tests/interop/InteropClientTestCase.cs
new file mode 100644
index 0000000000..09361b33e8
--- /dev/null
+++ b/qpid/dotnet/Qpid.Integration.Tests/interop/InteropClientTestCase.cs
@@ -0,0 +1,87 @@
+/*
+ *
+ * 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.
+ *
+ */
+using System;
+using System.Text;
+using Apache.Qpid.Messaging;
+
+namespace Apache.Qpid.Integration.Tests.interop
+{
+ /// <summary> Defines the possible test case roles that an interop test case can take on. </summary>
+ public enum Roles { SENDER, RECEIVER };
+
+ /// <summary>
+ /// InteropClientTestCase provides an interface that classes implementing test cases from the interop testing spec
+ /// (http://cwiki.apache.org/confluence/display/qpid/Interop+Testing+Specification) should implement.
+ ///
+ /// <p><table id="crc"><caption>CRC Card</caption>
+ /// <tr><th> Responsibilities
+ /// <tr><td> Supply the name of the test case that this implements.
+ /// <tr><td> Accept/Reject invites based on test parameters.
+ /// <tr><td> Adapt to assigned roles.
+ /// <tr><td> Perform test case actions.
+ /// <tr><td> Generate test reports.
+ /// </table>
+ /// </summary>
+ interface InteropClientTestCase
+ {
+ /// <summary>
+ /// Should provide the name of the test case that this class implements. The exact names are defined in the
+ /// interop testing spec.
+ /// </summary>
+ ///
+ /// <returns> The name of the test case that this implements. </returns>
+ string GetName();
+
+ /// <summary>
+ /// Determines whether the test invite that matched this test case is acceptable.
+ /// </summary>
+ ///
+ /// <param name="inviteMessage"> The invitation to accept or reject. </param>
+ ///
+ /// <returns> <tt>true</tt> to accept the invitation, <tt>false</tt> to reject it. </returns>
+ ///
+ /// @throws JMSException Any JMSException resulting from reading the message are allowed to fall through.
+ bool AcceptInvite(IMessage inviteMessage);
+
+ /// <summary>
+ /// Assigns the role to be played by this test case. The test parameters are fully specified in the
+ /// assignment message. When this method return the test case will be ready to execute.
+ /// </summary>
+ ///
+ /// <param name="role"> The role to be played; sender or receiver. </param>
+ /// <param name="assignRoleMessage"> The role assingment message, contains the full test parameters. </param>
+ void AssignRole(Roles role, IMessage assignRoleMessage);
+
+ /// <summary>
+ /// Performs the test case actions.
+ /// </summary>
+ void Start();
+
+ /// <summary>
+ /// Gets a report on the actions performed by the test case in its assigned role.
+ /// </summary>
+ ///
+ /// <param name="session"> The session to create the report message in. </param>
+ ///
+ /// <returns> The report message. </returns>
+ IMessage GetReport(IChannel channel);
+ }
+}
diff --git a/qpid/dotnet/Qpid.Integration.Tests/interop/TestCases/TestCase1DummyRun.cs b/qpid/dotnet/Qpid.Integration.Tests/interop/TestCases/TestCase1DummyRun.cs
new file mode 100644
index 0000000000..d908b7af0b
--- /dev/null
+++ b/qpid/dotnet/Qpid.Integration.Tests/interop/TestCases/TestCase1DummyRun.cs
@@ -0,0 +1,89 @@
+/*
+ *
+ * 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.
+ *
+ */
+using System;
+using System.Text;
+using log4net;
+using Apache.Qpid.Messaging;
+
+namespace Apache.Qpid.Integration.Tests.interop.TestCases
+{
+ /// <summary>
+ /// Implements tet case 1, dummy run. This test case sends no test messages, it exists to confirm that the test harness
+ /// is interacting with the coordinator correctly.
+ ///
+ /// <p><table id="crc"><caption>CRC Card</caption>
+ /// <tr><th> Responsibilities <th> Collaborations
+ /// <tr><td> Supply the name of the test case that this implements.
+ /// <tr><td> Accept/Reject invites based on test parameters.
+ /// <tr><td> Adapt to assigned roles.
+ /// <tr><td> Perform test case actions.
+ /// <tr><td> Generate test reports.
+ /// </table>
+ /// </summary>
+ public class TestCase1DummyRun : InteropClientTestCase
+ {
+ private static ILog log = LogManager.GetLogger(typeof(TestCase1DummyRun));
+
+ public String GetName()
+ {
+ log.Debug("public String getName(): called");
+
+ return "TC1_DummyRun";
+ }
+
+ public bool AcceptInvite(IMessage inviteMessage)
+ {
+ log.Debug("public boolean acceptInvite(Message inviteMessage): called");
+
+ // Test parameters don't matter, accept all invites.
+ return true;
+ }
+
+ public void AssignRole(Roles role, IMessage assignRoleMessage)
+ {
+ log.Debug("public void assignRole(Roles role, Message assignRoleMessage): called");
+
+ // Do nothing, both roles are the same.
+ }
+
+ public void Start()
+ {
+ log.Debug("public void start(): called");
+
+ // Do nothing.
+ }
+
+ public IMessage GetReport(IChannel channel)
+ {
+ log.Debug("public Message getReport(Session session): called");
+
+ // Generate a dummy report, the coordinator expects a report but doesn't care what it is.
+ return channel.CreateTextMessage("Dummy Run, Ok.");
+ }
+
+ public void OnMessage(IMessage message)
+ {
+ log.Debug("public void onMessage(Message message = " + message + "): called");
+
+ // Ignore any messages.
+ }
+ }
+}
diff --git a/qpid/dotnet/Qpid.Integration.Tests/interop/TestCases/TestCase2BasicP2P.cs b/qpid/dotnet/Qpid.Integration.Tests/interop/TestCases/TestCase2BasicP2P.cs
new file mode 100644
index 0000000000..8993da832e
--- /dev/null
+++ b/qpid/dotnet/Qpid.Integration.Tests/interop/TestCases/TestCase2BasicP2P.cs
@@ -0,0 +1,205 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+using System;
+using System.Text;
+using log4net;
+using Apache.Qpid.Messaging;
+
+namespace Apache.Qpid.Integration.Tests.interop.TestCases
+{
+ /// <summary>
+ /// Implements test case 2, basic P2P. Sends/receives a specified number of messages to a specified route on the
+ /// default direct exchange. Produces reports on the actual number of messages sent/received.
+ ///
+ /// <p><table id="crc"><caption>CRC Card</caption>
+ /// <tr><th> Responsibilities <th> Collaborations
+ /// <tr><td> Supply the name of the test case that this implements.
+ /// <tr><td> Accept/Reject invites based on test parameters.
+ /// <tr><td> Adapt to assigned roles.
+ /// <tr><td> Send required number of test messages.
+ /// <tr><td> Generate test reports.
+ /// </table>
+ /// </summary>
+ public class TestCase2BasicP2P : InteropClientTestCase
+ {
+ /// <summary> Used for debugging. </summary>
+ private static ILog log = LogManager.GetLogger(typeof(TestCase2BasicP2P));
+
+ /// <summary> Holds the count of test messages received. </summary>
+ private int messageCount;
+
+ /// <summary> The role to be played by the test. </summary>
+ private Roles role;
+
+ /// <summary> The number of test messages to send. </summary>
+ private int numMessages;
+
+ /// <summary> The routing key to send them to on the default direct exchange. </summary>
+ private string sendDestination;
+
+ /// <summary> The connection to send the test messages on. </summary>
+ private IConnection connection;
+
+ /// <summary> The session to send the test messages on. </summary>
+ private IChannel channel;
+
+ /// <summary> The producer to send the test messages with. </summary>
+ private IMessagePublisher publisher;
+
+ /// <summary>
+ /// Should provide the name of the test case that this class implements. The exact names are defined in the
+ /// interop testing spec.
+ /// </summary>
+ ///
+ /// <returns> The name of the test case that this implements. </returns>
+ public String GetName()
+ {
+ log.Debug("public String GetName(): called");
+
+ return "TC2_BasicP2P";
+ }
+
+ /// <summary>
+ /// Determines whether the test invite that matched this test case is acceptable.
+ /// </summary>
+ ///
+ /// <param name="inviteMessage"> The invitation to accept or reject. </param>
+ ///
+ /// <returns> <tt>true</tt> to accept the invitation, <tt>false</tt> to reject it. </returns>
+ public bool AcceptInvite(IMessage inviteMessage)
+ {
+ log.Debug("public boolean AcceptInvite(Message inviteMessage = " + inviteMessage + "): called");
+
+ // All invites are acceptable.
+ return true;
+ }
+
+ /// <summary>
+ /// Assigns the role to be played by this test case. The test parameters are fully specified in the
+ /// assignment message. When this method return the test case will be ready to execute.
+ /// </summary>
+ ///
+ /// <param name="role"> The role to be played; sender or receiver. </param>
+ /// <param name="assignRoleMessage"> The role assingment message, contains the full test parameters. </param>
+ public void AssignRole(Roles role, IMessage assignRoleMessage)
+ {
+ log.Debug("public void AssignRole(Roles role = " + role + ", Message assignRoleMessage = " + assignRoleMessage
+ + "): called");
+
+ // Reset the message count for a new test.
+ messageCount = 0;
+
+ // Take note of the role to be played.
+ this.role = role;
+
+ // Create a new connection to pass the test messages on.
+ connection =
+ TestClient.CreateConnection(TestClient.brokerUrl, TestClient.virtualHost);
+ channel = connection.CreateChannel(false, AcknowledgeMode.AutoAcknowledge);
+
+ // Extract and retain the test parameters.
+ numMessages = assignRoleMessage.Headers.GetInt("P2P_NUM_MESSAGES");
+ string queueAndKeyName = assignRoleMessage.Headers.GetString("P2P_QUEUE_AND_KEY_NAME");
+ channel.DeclareQueue(queueAndKeyName, false, true, true);
+ channel.Bind(queueAndKeyName, ExchangeNameDefaults.DIRECT, queueAndKeyName);
+ sendDestination = queueAndKeyName;
+
+ log.Debug("numMessages = " + numMessages);
+ log.Debug("sendDestination = " + sendDestination);
+ log.Debug("role = " + role);
+
+ switch (role)
+ {
+ // Check if the sender role is being assigned, and set up a message producer if so.
+ case Roles.SENDER:
+ publisher = channel.CreatePublisherBuilder()
+ .WithExchangeName(ExchangeNameDefaults.DIRECT)
+ .WithRoutingKey(sendDestination)
+ .Create();
+ break;
+
+ // Otherwise the receiver role is being assigned, so set this up to listen for messages.
+ case Roles.RECEIVER:
+ IMessageConsumer consumer = channel.CreateConsumerBuilder(sendDestination).Create();
+ consumer.OnMessage += new MessageReceivedDelegate(OnMessage);
+
+ break;
+ }
+
+ connection.Start();
+ }
+
+ /// <summary> Performs the test case actions. </summary>
+ public void Start()
+ {
+ log.Debug("public void start(): called");
+
+ // Check that the sender role is being performed.
+ if (role == Roles.SENDER)
+ {
+ IMessage testMessage = channel.CreateTextMessage("test");
+
+ for (int i = 0; i < numMessages; i++)
+ {
+ publisher.Send(testMessage);
+
+ // Increment the message count.
+ messageCount++;
+ }
+ }
+ }
+
+ /// <summary>
+ /// Gets a report on the actions performed by the test case in its assigned role.
+ /// </summary>
+ ///
+ /// <param name="session"> The session to create the report message in. </param>
+ ///
+ /// <returns> The report message. </returns>
+ public IMessage GetReport(IChannel channel)
+ {
+ log.Debug("public Message GetReport(IChannel channel): called");
+
+ // Close the test connection.
+ //connection.Stop();
+
+ // Generate a report message containing the count of the number of messages passed.
+ IMessage report = channel.CreateMessage();
+ //report.Headers.SetString("CONTROL_TYPE", "REPORT");
+ report.Headers.SetInt("MESSAGE_COUNT", messageCount);
+
+ return report;
+ }
+
+ /// <summary>
+ /// Counts incoming test messages.
+ /// </summary>
+ ///
+ /// <param name="message"> The incoming test message. </param>
+ public void OnMessage(IMessage message)
+ {
+ log.Debug("public void OnMessage(IMessage message = " + message + "): called");
+
+ // Increment the message count.
+ messageCount++;
+ }
+ }
+}
diff --git a/qpid/dotnet/Qpid.Integration.Tests/interop/TestCases/TestCase3BasicPubSub.cs b/qpid/dotnet/Qpid.Integration.Tests/interop/TestCases/TestCase3BasicPubSub.cs
new file mode 100644
index 0000000000..79c0322bcd
--- /dev/null
+++ b/qpid/dotnet/Qpid.Integration.Tests/interop/TestCases/TestCase3BasicPubSub.cs
@@ -0,0 +1,244 @@
+/*
+ *
+ * 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.
+ *
+ */
+using System;
+using System.Text;
+using log4net;
+using Apache.Qpid.Messaging;
+
+namespace Apache.Qpid.Integration.Tests.interop.TestCases
+{
+ /// <summary>
+ /// Implements test case 3, basic pub/sub. Sends/received a specified number of messages to a specified route on the
+ /// default topic exchange, using the specified number of receiver connections. Produces reports on the actual number of
+ /// messages sent/received.
+ ///
+ /// <p><table id="crc"><caption>CRC Card</caption>
+ /// <tr><th> Responsibilities <th> Collaborations
+ /// <tr><td> Supply the name of the test case that this implements.
+ /// <tr><td> Accept/Reject invites based on test parameters.
+ /// <tr><td> Adapt to assigned roles.
+ /// <tr><td> Send required number of test messages using pub/sub.
+ /// <tr><td> Generate test reports.
+ /// </table>
+ /// </summary>
+ public class TestCase3BasicPubSub : InteropClientTestCase
+ {
+ /// <summary> Used for debugging. </summary>
+ private static ILog log = LogManager.GetLogger(typeof(TestCase3BasicPubSub));
+
+ /// <summary> Holds the count of test messages received. </summary>
+ private int messageCount;
+
+ /// <summary> The role to be played by the test. </summary>
+ private Roles role;
+
+ /// <summary> The number of test messages to send. </summary>
+ private int numMessages;
+
+ /// <summary> The number of receiver connection to use. </summary>
+ private int numReceivers;
+
+ /// <summary> The routing key to send them to on the default direct exchange. </summary>
+ private string sendDestination;
+
+ /// <summary> The connections to send/receive the test messages on. </summary>
+ private IConnection[] connection;
+
+ /// <summary> The sessions to send/receive the test messages on. </summary>
+ private IChannel[] channel;
+
+ /// <summary> The producer to send the test messages with. </summary>
+ IMessagePublisher publisher;
+
+ /// <summary>
+ /// Should provide the name of the test case that this class implements. The exact names are defined in the
+ /// interop testing spec.
+ /// </summary>
+ ///
+ /// <returns> The name of the test case that this implements. </returns>
+ public String GetName()
+ {
+ log.Debug("public String GetName(): called");
+
+ return "TC3_BasicPubSub";
+ }
+
+ /// <summary>
+ /// Determines whether the test invite that matched this test case is acceptable.
+ /// </summary>
+ ///
+ /// <param name="inviteMessage"> The invitation to accept or reject. </param>
+ ///
+ /// <returns> <tt>true</tt> to accept the invitation, <tt>false</tt> to reject it. </returns>
+ public bool AcceptInvite(IMessage inviteMessage)
+ {
+ log.Debug("public boolean AcceptInvite(IMessage inviteMessage = " + inviteMessage + "): called");
+
+ // All invites are acceptable.
+ return true;
+ }
+
+ /// <summary>
+ /// Assigns the role to be played by this test case. The test parameters are fully specified in the
+ /// assignment message. When this method return the test case will be ready to execute.
+ /// </summary>
+ ///
+ /// <param name="role"> The role to be played; sender or receiver. </param>
+ /// <param name="assignRoleMessage"> The role assingment message, contains the full test parameters. </param>
+ public void AssignRole(Roles role, IMessage assignRoleMessage)
+ {
+ log.Debug("public void assignRole(Roles role = " + role + ", IMessage assignRoleMessage = " + assignRoleMessage
+ + "): called");
+
+ // Reset the message count for a new test.
+ messageCount = 0;
+
+ // Take note of the role to be played.
+ this.role = role;
+
+ // Extract and retain the test parameters.
+ numMessages = assignRoleMessage.Headers.GetInt("PUBSUB_NUM_MESSAGES");
+ numReceivers = assignRoleMessage.Headers.GetInt("PUBSUB_NUM_RECEIVERS");
+ string sendKey = assignRoleMessage.Headers.GetString("PUBSUB_KEY");
+ sendDestination = sendKey;
+
+ log.Debug("numMessages = " + numMessages);
+ log.Debug("numReceivers = " + numReceivers);
+ log.Debug("sendKey = " + sendKey);
+ log.Debug("role = " + role);
+
+ switch (role)
+ {
+ // Check if the sender role is being assigned, and set up a single message producer if so.
+ case Roles.SENDER:
+ // Create a new connection to pass the test messages on.
+ connection = new IConnection[1];
+ channel = new IChannel[1];
+
+ connection[0] =
+ TestClient.CreateConnection(TestClient.brokerUrl, TestClient.virtualHost);
+ channel[0] = connection[0].CreateChannel(false, AcknowledgeMode.AutoAcknowledge);
+
+ // Extract and retain the test parameters.
+ publisher = channel[0].CreatePublisherBuilder()
+ .WithExchangeName(ExchangeNameDefaults.TOPIC)
+ .WithRoutingKey(sendDestination)
+ .WithMandatory(false)
+ .WithImmediate(false)
+ .Create();
+ break;
+
+ // Otherwise the receiver role is being assigned, so set this up to listen for messages on the required number
+ // of receiver connections.
+ case Roles.RECEIVER:
+ // Create the required number of receiver connections.
+ connection = new IConnection[numReceivers];
+ channel = new IChannel[numReceivers];
+
+ for (int i = 0; i < numReceivers; i++)
+ {
+ connection[i] =
+ TestClient.CreateConnection(TestClient.brokerUrl, TestClient.virtualHost);
+ channel[i] = connection[i].CreateChannel(false, AcknowledgeMode.AutoAcknowledge);
+
+ IMessageConsumer consumer = channel[i].CreateConsumerBuilder(sendDestination).Create();
+ consumer.OnMessage += new MessageReceivedDelegate(OnMessage);
+ }
+
+ break;
+ }
+
+ // Start all the connection dispatcher threads running.
+ foreach (IConnection con in connection)
+ {
+ con.Start();
+ }
+ }
+
+ /// <summary>
+ /// Performs the test case actions.
+ /// </summary>
+ public void Start()
+ {
+ log.Debug("public void Start(): called");
+
+ // Check that the sender role is being performed.
+ if (role == Roles.SENDER)
+ {
+ IMessage testMessage = channel[0].CreateTextMessage("test");
+
+ for (int i = 0; i < numMessages; i++)
+ {
+ publisher.Send(testMessage);
+
+ // Increment the message count.
+ messageCount++;
+ }
+ }
+ }
+
+ /// <summary>
+ /// Gets a report on the actions performed by the test case in its assigned role.
+ /// </summary>
+ ///
+ /// <param name="session"> The session to create the report message in. </param>
+ ///
+ /// <returns> The report message. </returns>
+ public IMessage GetReport(IChannel channel)
+ {
+ log.Debug("public IMessage getReport(IChannel channel): called");
+
+ // Close the test connections.
+ /*foreach (IConnection con in connection)
+ {
+ try
+ {
+ con.Stop();
+ }
+ catch (AMQConnectionClosedException e)
+ {
+ // The connection has already died due to an error. Log this as a warning.
+ log.Warn("Connection already closed.");
+ }
+ }*/
+
+ // Generate a report message containing the count of the number of messages passed.
+ IMessage report = channel.CreateMessage();
+ //report.Headers.SetString("CONTROL_TYPE", "REPORT");
+ report.Headers.SetInt("MESSAGE_COUNT", messageCount);
+
+ return report;
+ }
+
+ /// <summary>
+ /// Counts incoming test messages.
+ /// </summary>
+ ///
+ /// <param name="message"> The incoming test message. </param>
+ public void OnMessage(IMessage message)
+ {
+ log.Debug("public void onMessage(IMessage message = " + message + "): called");
+
+ // Increment the message count.
+ messageCount++;
+ }
+ }
+}
diff --git a/qpid/dotnet/Qpid.Integration.Tests/interop/TestCases/TestCase4P2PMessageSize.cs b/qpid/dotnet/Qpid.Integration.Tests/interop/TestCases/TestCase4P2PMessageSize.cs
new file mode 100644
index 0000000000..fd83825a61
--- /dev/null
+++ b/qpid/dotnet/Qpid.Integration.Tests/interop/TestCases/TestCase4P2PMessageSize.cs
@@ -0,0 +1,244 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+using System;
+using System.Text;
+using log4net;
+using Apache.Qpid.Messaging;
+
+namespace Apache.Qpid.Integration.Tests.interop.TestCases
+{
+ ///
+ /// Implements test case 4, from the interop test specification. This test sets up the TC2_P2PMessageSize test for 50
+ /// messages, and a variety of message sizes. It checks that the sender and receivers reports both indicate that all
+ /// the test messages were transmitted successfully.
+ ///
+ /// <p><table id="crc"><caption>CRC Card</caption>
+ /// <tr><th> Responsibilities <th> Collaborations
+ /// <tr><td> Setup p2p test parameters and compare with test output. <td> {@link FrameworkBaseCase}
+ /// </table>
+ ///
+ public class TestCase4P2PMessageSize : InteropClientTestCase
+ {
+ /// Used for debugging.
+ private static ILog log = LogManager.GetLogger(typeof(TestCase4P2PMessageSize));
+
+ /// <summary> The role to be played by the test. </summary>
+ private Roles role;
+
+ /// <summary> Holds the count of test messages received. </summary>
+ private int messageCount;
+
+ ///<summary>The size of the message to be sent </summary>
+ private int messageSize;
+
+ /// <summary> The number of test messages to send. </summary>
+ private int numMessages;
+
+ /// <summary> The number of receiver connection to use. </summary>
+ private int numReceivers;
+
+ /// <summary> The routing key to send them to on the default direct exchange. </summary>
+ private string sendDestination;
+
+ /// <summary> The connections to send/receive the test messages on. </summary>
+ private IConnection[] connection;
+
+ /// <summary> The sessions to send/receive the test messages on. </summary>
+ private IChannel[] channel;
+
+ /// <summary> The producer to send the test messages with. </summary>
+ IMessagePublisher publisher;
+
+ /// <summary>
+ /// Creates a new coordinating test case with the specified name.
+ ///</summary>
+ /// <returns>The test case name.</returns>
+ ///
+ public String GetName()
+ {
+ log.Info("public String GetName(): called");
+ return "TC4_P2PMessageSize";
+ }
+
+ /// <summary>
+ /// Determines whether the test invite that matched this test case is acceptable.
+ /// </summary>
+ ///
+ /// <param name="inviteMessage"> The invitation to accept or reject. </param>
+ ///
+ /// <returns> <tt>true</tt> to accept the invitation, <tt>false</tt> to reject it. </returns>
+ public bool AcceptInvite(IMessage inviteMessage)
+ {
+ log.Info("public boolean AcceptInvite(IMessage inviteMessage = " + inviteMessage + "): called");
+ // All invites are acceptable.
+ return true;
+ }
+
+ public void Start()
+ {
+ log.Info("public void start(): called");
+ // Assuming numMessages = 1
+ Start(1);
+ }
+
+ public void Start(int numMessages)
+ {
+ log.Info("public void start("+numMessages+"): called");
+
+ // Check that the sender role is being performed.
+ if (role == Roles.SENDER)
+ {
+ IMessage testMessage = createMessageOfSize(messageSize);
+
+
+ for (int i = 0; i < numMessages; i++)
+ {
+ publisher.Send(testMessage);
+
+ // Increment the message count.
+ messageCount++;
+ }
+ }
+
+ }
+
+ private IMessage createMessageOfSize(int size)
+ {
+ IBytesMessage message = channel[0].CreateBytesMessage();
+ string messageStr = "Test Message -- Test Message -- Test Message -- Test Message -- Test Message -- Test Message -- Test Message -- ";
+ System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding();
+ byte[] messageBytes = encoding.GetBytes(messageStr);
+
+ if (size > 0)
+ {
+ int div = size / messageBytes.Length;
+ int mod = size % messageBytes.Length;
+
+ for (int i = 0; i < div; i++)
+ {
+ message.WriteBytes(messageBytes);
+ }
+ if (mod != 0)
+ {
+ message.WriteBytes(messageBytes, 0, mod);
+ }
+ }
+ return message;
+ }
+
+ public void AssignRole(Roles role, IMessage assignRoleMessage)
+ {
+ log.Info("public void assignRole(Roles role = " + role + ", IMessage assignRoleMessage = " + assignRoleMessage
+ + "): called");
+
+ // Reset the message count for a new test.
+ messageCount = 0;
+
+ // Take note of the role to be played.
+ this.role = role;
+
+ // Extract and retain the test parameters.
+ numMessages = assignRoleMessage.Headers.GetInt("P2P_NUM_MESSAGES");
+ messageSize = assignRoleMessage.Headers.GetInt("messageSize");
+
+ string sendKey = assignRoleMessage.Headers.GetString("P2P_QUEUE_AND_KEY_NAME");
+ sendDestination = sendKey;
+
+ log.Info("numMessages = " + numMessages);
+ log.Info("messageSize = " + messageSize);
+ log.Info("sendKey = " + sendKey);
+ log.Info("role = " + role);
+
+ switch (role)
+ {
+ // Check if the sender role is being assigned, and set up a single message producer if so.
+ case Roles.SENDER:
+ // Create a new connection to pass the test messages on.
+ connection = new IConnection[1];
+ channel = new IChannel[1];
+
+ connection[0] =
+ TestClient.CreateConnection(TestClient.brokerUrl, TestClient.virtualHost);
+ channel[0] = connection[0].CreateChannel(false, AcknowledgeMode.AutoAcknowledge);
+
+ // Extract and retain the test parameters.
+ publisher = channel[0].CreatePublisherBuilder()
+ .WithExchangeName(ExchangeNameDefaults.TOPIC)
+ .WithRoutingKey(sendDestination)
+ .WithMandatory(false)
+ .WithImmediate(false)
+ .Create();
+ break;
+
+ // Otherwise the receiver role is being assigned, so set this up to listen for messages on the required number
+ // of receiver connections.
+ case Roles.RECEIVER:
+ // Create the required number of receiver connections.
+ connection = new IConnection[1];
+ channel = new IChannel[1];
+ connection[0] = TestClient.CreateConnection(TestClient.brokerUrl, TestClient.virtualHost);
+ channel[0] = connection[0].CreateChannel(false, AcknowledgeMode.AutoAcknowledge);
+ IMessageConsumer consumer = channel[0].CreateConsumerBuilder(sendDestination).Create();
+ consumer.OnMessage += new MessageReceivedDelegate(OnMessage);
+ break;
+ }
+
+ // Start all the connection dispatcher threads running.
+ foreach (IConnection con in connection)
+ {
+ con.Start();
+ }
+
+ }
+
+ public IMessage GetReport(IChannel channel)
+ {
+
+ log.Info("public Message GetReport(IChannel channel): called");
+
+ // Close the test connection.
+ //connection.Stop();
+
+ // Generate a report message containing the count of the number of messages passed.
+ IMessage report = channel.CreateMessage();
+ //report.Headers.SetString("CONTROL_TYPE", "REPORT");
+ report.Headers.SetInt("MESSAGE_COUNT", messageCount);
+
+ return report;
+ }
+
+
+ /// <summary>
+ /// Counts incoming test messages.
+ /// </summary>
+ ///
+ /// <param name="message"> The incoming test message. </param>
+ public void OnMessage(IMessage message)
+ {
+ log.Info("public void onMessage(IMessage message = " + message + "): called");
+
+ // Increment the message count.
+ messageCount++;
+ }
+
+ }
+}
diff --git a/qpid/dotnet/Qpid.Integration.Tests/interop/TestCases/TestCase5PubSubMessageSize.cs b/qpid/dotnet/Qpid.Integration.Tests/interop/TestCases/TestCase5PubSubMessageSize.cs
new file mode 100644
index 0000000000..8fddaeafa2
--- /dev/null
+++ b/qpid/dotnet/Qpid.Integration.Tests/interop/TestCases/TestCase5PubSubMessageSize.cs
@@ -0,0 +1,252 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+using System;
+using System.Text;
+using log4net;
+using Apache.Qpid.Messaging;
+
+namespace Apache.Qpid.Integration.Tests.interop.TestCases
+{
+ ///
+ /// Implements test case 4, from the interop test specification. This test sets up the TC2_P2PMessageSize test for 50
+ /// messages, and a variety of message sizes. It checks that the sender and receivers reports both indicate that all
+ /// the test messages were transmitted successfully.
+ ///
+ /// <p><table id="crc"><caption>CRC Card</caption>
+ /// <tr><th> Responsibilities <th> Collaborations
+ /// <tr><td> Setup p2p test parameters and compare with test output. <td> {@link FrameworkBaseCase}
+ /// </table>
+ ///
+ public class TestCase5PubSubMessageSize : InteropClientTestCase
+ {
+ /// Used for debugging.
+ private static ILog log = LogManager.GetLogger(typeof(TestCase5PubSubMessageSize));
+
+ /// <summary> The role to be played by the test. </summary>
+ private Roles role;
+
+ /// <summary> Holds the count of test messages received. </summary>
+ private int messageCount;
+
+ ///<summary>The size of the message to be sent </summary>
+ private int messageSize;
+
+ /// <summary> The number of test messages to send. </summary>
+ private int numMessages;
+
+ /// <summary> The number of receiver connection to use. </summary>
+ private int numReceivers;
+
+ /// <summary> The routing key to send them to on the default direct exchange. </summary>
+ private string sendDestination;
+
+ /// <summary> The connections to send/receive the test messages on. </summary>
+ private IConnection[] connection;
+
+ /// <summary> The sessions to send/receive the test messages on. </summary>
+ private IChannel[] channel;
+
+ /// <summary> The producer to send the test messages with. </summary>
+ IMessagePublisher publisher;
+
+ /// <summary>
+ /// Creates a new coordinating test case with the specified name.
+ ///</summary>
+ /// <returns>The test case name.</returns>
+ ///
+ public String GetName()
+ {
+ log.Info("public String GetName(): called");
+ return "TC5_PubSubMessageSize";
+ }
+
+ /// <summary>
+ /// Determines whether the test invite that matched this test case is acceptable.
+ /// </summary>
+ ///
+ /// <param name="inviteMessage"> The invitation to accept or reject. </param>
+ ///
+ /// <returns> <tt>true</tt> to accept the invitation, <tt>false</tt> to reject it. </returns>
+ public bool AcceptInvite(IMessage inviteMessage)
+ {
+ log.Info("public boolean AcceptInvite(IMessage inviteMessage = " + inviteMessage + "): called");
+ // All invites are acceptable.
+ return true;
+ }
+
+ public void Start()
+ {
+ log.Info("public void start(): called");
+ // Assuming numMessages = 1
+ Start(1);
+ }
+
+ public void Start(int numMessages)
+ {
+ log.Info("public void start("+numMessages+"): called");
+
+ // Check that the sender role is being performed.
+ if (role == Roles.SENDER)
+ {
+ IMessage testMessage = createMessageOfSize(messageSize);
+
+
+ for (int i = 0; i < numMessages; i++)
+ {
+ publisher.Send(testMessage);
+
+ // Increment the message count.
+ messageCount++;
+ }
+ }
+
+ }
+
+ private IMessage createMessageOfSize(int size)
+ {
+ IBytesMessage message = channel[0].CreateBytesMessage();
+ string messageStr = "Test Message -- Test Message -- Test Message -- Test Message -- Test Message -- Test Message -- Test Message -- ";
+ System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding();
+ byte[] messageBytes = encoding.GetBytes(messageStr);
+
+ if (size > 0)
+ {
+ int div = size / messageBytes.Length;
+ int mod = size % messageBytes.Length;
+
+ for (int i = 0; i < div; i++)
+ {
+ message.WriteBytes(messageBytes);
+ }
+ if (mod != 0)
+ {
+ message.WriteBytes(messageBytes, 0, mod);
+ }
+ }
+ return message;
+ }
+
+ public void AssignRole(Roles role, IMessage assignRoleMessage)
+ {
+ log.Info("public void assignRole(Roles role = " + role + ", IMessage assignRoleMessage = " + assignRoleMessage
+ + "): called");
+
+ // Reset the message count for a new test.
+ messageCount = 0;
+
+ // Take note of the role to be played.
+ this.role = role;
+
+ // Extract and retain the test parameters.
+ numMessages = assignRoleMessage.Headers.GetInt("PUBSUB_NUM_MESSAGES");
+ messageSize = assignRoleMessage.Headers.GetInt("messageSize");
+ numReceivers = assignRoleMessage.Headers.GetInt("PUBSUB_NUM_RECEIVERS");
+
+ string sendKey = assignRoleMessage.Headers.GetString("PUBSUB_KEY");
+ sendDestination = sendKey;
+
+ log.Info("numMessages = " + numMessages);
+ log.Info("messageSize = " + messageSize);
+ log.Info("sendKey = " + sendKey);
+ log.Info("role = " + role);
+
+ switch (role)
+ {
+ // Check if the sender role is being assigned, and set up a single message producer if so.
+ case Roles.SENDER:
+ // Create a new connection to pass the test messages on.
+ connection = new IConnection[1];
+ channel = new IChannel[1];
+
+ connection[0] =
+ TestClient.CreateConnection(TestClient.brokerUrl, TestClient.virtualHost);
+ channel[0] = connection[0].CreateChannel(false, AcknowledgeMode.AutoAcknowledge);
+
+ // Extract and retain the test parameters.
+ publisher = channel[0].CreatePublisherBuilder()
+ .WithExchangeName(ExchangeNameDefaults.TOPIC)
+ .WithRoutingKey(sendDestination)
+ .WithMandatory(false)
+ .WithImmediate(false)
+ .Create();
+ break;
+
+ // Otherwise the receiver role is being assigned, so set this up to listen for messages on the required number
+ // of receiver connections.
+ case Roles.RECEIVER:
+ // Create the required number of receiver connections.
+ connection = new IConnection[numReceivers];
+ channel = new IChannel[numReceivers];
+
+ for (int i = 0; i < numReceivers; i++)
+ {
+ connection[i] =
+ TestClient.CreateConnection(TestClient.brokerUrl, TestClient.virtualHost);
+ channel[i] = connection[i].CreateChannel(false, AcknowledgeMode.AutoAcknowledge);
+
+ IMessageConsumer consumer = channel[i].CreateConsumerBuilder(sendDestination).Create();
+ consumer.OnMessage += new MessageReceivedDelegate(OnMessage);
+ }
+
+ break;
+ }
+
+ // Start all the connection dispatcher threads running.
+ foreach (IConnection con in connection)
+ {
+ con.Start();
+ }
+
+ }
+
+ public IMessage GetReport(IChannel channel)
+ {
+
+ log.Info("public Message GetReport(IChannel channel): called");
+
+ // Close the test connection.
+ //connection.Stop();
+
+ // Generate a report message containing the count of the number of messages passed.
+ IMessage report = channel.CreateMessage();
+ //report.Headers.SetString("CONTROL_TYPE", "REPORT");
+ report.Headers.SetInt("MESSAGE_COUNT", messageCount);
+
+ return report;
+ }
+
+
+ /// <summary>
+ /// Counts incoming test messages.
+ /// </summary>
+ ///
+ /// <param name="message"> The incoming test message. </param>
+ public void OnMessage(IMessage message)
+ {
+ log.Info("public void onMessage(IMessage message = " + message + "): called");
+
+ // Increment the message count.
+ messageCount++;
+ }
+
+ }
+}
diff --git a/qpid/dotnet/Qpid.Integration.Tests/interop/TestClient.cs b/qpid/dotnet/Qpid.Integration.Tests/interop/TestClient.cs
new file mode 100644
index 0000000000..0def89c6da
--- /dev/null
+++ b/qpid/dotnet/Qpid.Integration.Tests/interop/TestClient.cs
@@ -0,0 +1,381 @@
+/*
+ *
+ * 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.
+ *
+ */
+using System;
+using System.Collections;
+using System.Text;
+using System.Threading;
+using Apache.Qpid.Messaging;
+using Apache.Qpid.Client.Qms;
+using Apache.Qpid.Client;
+using log4net;
+using Apache.Qpid.Integration.Tests.interop.TestCases;
+
+namespace Apache.Qpid.Integration.Tests.interop
+{
+ /// <summary>
+ /// Implements a test client as described in the interop testing spec
+ /// (http://cwiki.apache.org/confluence/display/qpid/Interop+Testing+Specification). A test client is an agent that
+ /// reacts to control message sequences send by the test coordinator.
+ ///
+ /// <p/><table><caption>Messages Handled by TestClient</caption>
+ /// <tr><th> Message <th> Action
+ /// <tr><td> Invite(compulsory) <td> Reply with Enlist.
+ /// <tr><td> Invite(test case) <td> Reply with Enlist if test case available.
+ /// <tr><td> AssignRole(test case) <td> Reply with Accept Role if matches an enlisted test. Keep test parameters.
+ /// <tr><td> Start <td> Send test messages defined by test parameters. Send report on messages sent.
+ /// <tr><td> Status Request <td> Send report on messages received.
+ /// </table>
+ ///
+ /// <p><table id="crc"><caption>CRC Card</caption>
+ /// <tr><th> Responsibilities <th> Collaborations
+ /// <tr><td> Handle all incoming control messages. <td> {@link InteropClientTestCase}
+ /// <tr><td> Configure and look up test cases by name. <td> {@link InteropClientTestCase}
+ /// </table>
+ /// </summary>
+ public class TestClient
+ {
+ private static ILog log = LogManager.GetLogger(typeof(TestClient));
+
+ /// <summary> Defines the default broker for the tests, localhost, default port. </summary>
+ public static string DEFAULT_BROKER_URL = "amqp://guest:guest@clientid/?brokerlist='tcp://localhost:5672'";
+
+ /// <summary> Defines the default virtual host to use for the tests, none. </summary>
+ public static string DEFAULT_VIRTUAL_HOST = "";
+
+ /// <summary> Defines the default identifying name of this test client. </summary>
+ public static string DEFAULT_CLIENT_NAME = "dotnet";
+
+ /// <summary> Holds the URL of the broker to run the tests on. </summary>
+ public static string brokerUrl;
+
+ /// <summary> Holds the virtual host to run the tests on. If <tt>null</tt>, then the default virtual host is used. </summary>
+ public static string virtualHost;
+
+ /// <summary> The clients identifying name to print in test results and to distinguish from other clients. </summary>
+ private string clientName;
+
+ /// <summary> Holds all the test cases. </summary>
+ private IDictionary testCases = new Hashtable();
+
+ InteropClientTestCase currentTestCase;
+
+ private MessagePublisherBuilder publisherBuilder;
+
+ private IChannel channel;
+
+ /// <summary> Monitor to wait for termination events on. </summary>
+ private static object terminationMonitor = new Object();
+
+ /// <summary>
+ /// Creates a new interop test client, listenting to the specified broker and virtual host, with the specified
+ /// client identifying name.
+ /// </summary>
+ ///
+ /// <param name="brokerUrl"> The url of the broker to connect to. </param>
+ /// <param name="virtualHost"> The virtual host to conect to. </param>
+ /// <param name="clientName"> The client name to use. </param>
+ public TestClient(string brokerUrl, string virtualHost, string clientName)
+ {
+ log.Info("public TestClient(string brokerUrl = " + brokerUrl + ", string virtualHost = " + virtualHost
+ + ", string clientName = " + clientName + "): called");
+
+ // Retain the connection parameters.
+ TestClient.brokerUrl = brokerUrl;
+ TestClient.virtualHost = virtualHost;
+ this.clientName = clientName;
+ }
+
+
+ /// <summary>
+ /// The entry point for the interop test coordinator. This client accepts the following command line arguments:
+ /// </summary>
+ ///
+ /// <p/><table>
+ /// <tr><td> -b <td> The broker URL. <td> Optional.
+ /// <tr><td> -h <td> The virtual host. <td> Optional.
+ /// <tr><td> -n <td> The test client name. <td> Optional.
+ /// <tr><td> name=value <td> Trailing argument define name/value pairs. Added to system properties. <td> Optional.
+ /// </table>
+ ///
+ /// <param name="args"> The command line arguments. </param>
+ public static void Main(string[] args)
+ {
+ // Extract the command line options (Not exactly Posix but it will do for now...).
+ string brokerUrl = DEFAULT_BROKER_URL;
+ string virtualHost = DEFAULT_VIRTUAL_HOST;
+ string clientName = DEFAULT_CLIENT_NAME;
+
+ foreach (string nextArg in args)
+ {
+ if (nextArg.StartsWith("-b"))
+ {
+ brokerUrl = nextArg.Substring(2);
+ }
+ else if (nextArg.StartsWith("-h"))
+ {
+ virtualHost = nextArg.Substring(2);
+ }
+ else if (nextArg.StartsWith("-n"))
+ {
+ clientName = nextArg.Substring(2);
+ }
+ }
+
+ NDC.Push(clientName);
+
+ // Create a test client and start it running.
+ TestClient client = new TestClient(brokerUrl, virtualHost, clientName);
+
+ try
+ {
+ client.Start();
+ }
+ catch (Exception e)
+ {
+ log.Error("The test client was unable to start.", e);
+ System.Environment.Exit(1);
+ }
+
+ // Wait for a signal on the termination monitor before quitting.
+ lock (terminationMonitor)
+ {
+ Monitor.Wait(terminationMonitor);
+ }
+
+ NDC.Pop();
+ }
+
+ /// <summary>
+ /// Starts the interop test client running. This causes it to start listening for incoming test invites.
+ /// </summary>
+ private void Start()
+ {
+ log.Info("private void Start(): called");
+
+ // Use a class path scanner to find all the interop test case implementations.
+ ArrayList testCaseClasses = new ArrayList();
+
+ // ClasspathScanner.getMatches(InteropClientTestCase.class, "^TestCase.*", true);
+ // Hard code the test classes till the classpath scanner is fixed.
+ testCaseClasses.Add(typeof(TestCase1DummyRun));
+ testCaseClasses.Add(typeof(TestCase2BasicP2P));
+ testCaseClasses.Add(typeof(TestCase3BasicPubSub));
+ testCaseClasses.Add(typeof(TestCase4P2PMessageSize));
+ testCaseClasses.Add(typeof(TestCase5PubSubMessageSize));
+
+ // Create all the test case implementations and index them by the test names.
+ foreach (Type testClass in testCaseClasses)
+ {
+ InteropClientTestCase testCase = (InteropClientTestCase)Activator.CreateInstance(testClass);
+ testCases.Add(testCase.GetName(), testCase);
+
+ log.Info("Found test case: " + testClass);
+ }
+
+ // Open a connection to communicate with the coordinator on.
+ log.Info("brokerUrl = " + brokerUrl);
+ IConnection connection = CreateConnection(brokerUrl, virtualHost);
+
+ channel = connection.CreateChannel(false, AcknowledgeMode.AutoAcknowledge);
+
+ // Set this up to listen for control messages.
+ string responseQueueName = channel.GenerateUniqueName();
+ channel.DeclareQueue(responseQueueName, false, true, true);
+
+ channel.Bind(responseQueueName, ExchangeNameDefaults.TOPIC, "iop.control." + clientName);
+ channel.Bind(responseQueueName, ExchangeNameDefaults.TOPIC, "iop.control");
+
+ IMessageConsumer consumer = channel.CreateConsumerBuilder(responseQueueName)
+ .Create();
+ consumer.OnMessage += new MessageReceivedDelegate(OnMessage);
+
+ // Create a publisher to send replies with.
+ publisherBuilder = channel.CreatePublisherBuilder()
+ .WithExchangeName(ExchangeNameDefaults.DIRECT);
+
+
+ // Start listening for incoming control messages.
+ connection.Start();
+ Console.WriteLine("Test client " + clientName + " ready to receive test control messages...");
+ }
+
+ /// <summary>
+ /// Establishes an AMQ connection. This is a simple convenience method for code that does not anticipate handling connection failures.
+ /// All exceptions that indicate that the connection has failed, are allowed to fall through.
+ /// </summary>
+ ///
+ /// <param name="brokerUrl"> The broker url to connect to, <tt>null</tt> to use the default from the properties. </param>
+ /// <param name="virtualHost"> The virtual host to connectio to, <tt>null</tt> to use the default. </param>
+ ///
+ /// <returns> A JMS conneciton. </returns>
+ public static IConnection CreateConnection(string brokerUrl, string virtualHost)
+ {
+ log.Info("public static Connection createConnection(string brokerUrl = " + brokerUrl + ", string virtualHost = "
+ + virtualHost + "): called");
+
+ // Create a connection to the broker.
+ IConnectionInfo connectionInfo = QpidConnectionInfo.FromUrl(brokerUrl);
+ connectionInfo.VirtualHost = virtualHost;
+ IConnection connection = new AMQConnection(connectionInfo);
+
+ return connection;
+ }
+
+ /// <summary>
+ /// Handles all incoming control messages.
+ /// </summary>
+ ///
+ /// <param name="message"> The incoming message. </param>
+ public void OnMessage(IMessage message)
+ {
+ log.Info("public void OnMessage(IMessage message = " + message + "): called");
+
+ try
+ {
+ string controlType = message.Headers.GetString("CONTROL_TYPE");
+ string testName = message.Headers.GetString("TEST_NAME");
+
+ // Check if the message is a test invite.
+ if ("INVITE" == controlType)
+ {
+ string testCaseName = message.Headers.GetString("TEST_NAME");
+
+ // Flag used to indicate that an enlist should be sent. Only enlist to compulsory invites or invites
+ // for which test cases exist.
+ bool enlist = false;
+
+ if (testCaseName != null)
+ {
+ log.Info("Got an invite to test: " + testCaseName);
+
+ // Check if the requested test case is available.
+ InteropClientTestCase testCase = (InteropClientTestCase)testCases[testCaseName];
+
+ if (testCase != null)
+ {
+ // Make the requested test case the current test case.
+ currentTestCase = testCase;
+ enlist = true;
+ }
+ }
+ else
+ {
+ log.Info("Got a compulsory invite.");
+
+ enlist = true;
+ }
+
+ log.Info("enlist = " + enlist);
+
+ if (enlist)
+ {
+ // Reply with the client name in an Enlist message.
+ IMessage enlistMessage = channel.CreateMessage();
+ enlistMessage.Headers.SetString("CONTROL_TYPE", "ENLIST");
+ enlistMessage.Headers.SetString("CLIENT_NAME", clientName);
+ enlistMessage.Headers.SetString("CLIENT_PRIVATE_CONTROL_KEY", "iop.control." + clientName);
+ enlistMessage.CorrelationId = message.CorrelationId;
+
+ Send(enlistMessage, message.ReplyToRoutingKey);
+ }
+ }
+ else if ("ASSIGN_ROLE" == controlType)
+ {
+ // Assign the role to the current test case.
+ string roleName = message.Headers.GetString("ROLE");
+
+ log.Info("Got a role assignment to role: " + roleName);
+
+ Roles role;
+
+ if (roleName == "SENDER")
+ {
+ role = Roles.SENDER;
+ }
+ else
+ {
+ role = Roles.RECEIVER;
+ }
+
+ currentTestCase.AssignRole(role, message);
+
+ // Reply by accepting the role in an Accept Role message.
+ IMessage acceptRoleMessage = channel.CreateMessage();
+ acceptRoleMessage.Headers.SetString("CONTROL_TYPE", "ACCEPT_ROLE");
+ acceptRoleMessage.CorrelationId = message.CorrelationId;
+
+ Send(acceptRoleMessage, message.ReplyToRoutingKey);
+ }
+ else if ("START" == controlType || "STATUS_REQUEST" == controlType)
+ {
+ if ("START" == controlType)
+ {
+ log.Info("Got a start notification.");
+
+ // Start the current test case.
+ currentTestCase.Start();
+ }
+ else
+ {
+ log.Info("Got a status request.");
+ }
+
+ // Generate the report from the test case and reply with it as a Report message.
+ IMessage reportMessage = currentTestCase.GetReport(channel);
+ reportMessage.Headers.SetString("CONTROL_TYPE", "REPORT");
+ reportMessage.CorrelationId = message.CorrelationId;
+
+ Send(reportMessage, message.ReplyToRoutingKey);
+ }
+ else if ("TERMINATE" == controlType)
+ {
+ Console.WriteLine("Received termination instruction from coordinator.");
+
+ // Is a cleaner shutdown needed?
+ System.Environment.Exit(1);
+ }
+ else
+ {
+ // Log a warning about this but otherwise ignore it.
+ log.Warn("Got an unknown control message, controlType = " + controlType + ", message = " + message);
+ }
+ }
+ catch (QpidException e)
+ {
+ // Log a warning about this, but otherwise ignore it.
+ log.Warn("A QpidException occurred whilst handling a message.");
+ log.Info("Got QpidException whilst handling message: " + message, e);
+ }
+ }
+
+ /// <summary>
+ /// Send the specified message using the specified routing key on the direct exchange.
+ /// </summary>
+ ///
+ /// <param name="message"> The message to send.</param>
+ /// <param name="routingKey"> The routing key to send the message with.</param>
+ public void Send(IMessage message, string routingKey)
+ {
+ IMessagePublisher publisher = publisherBuilder.WithRoutingKey(routingKey).Create();
+ publisher.Send(message);
+ }
+ }
+}
diff --git a/qpid/dotnet/Qpid.Integration.Tests/log4net.config b/qpid/dotnet/Qpid.Integration.Tests/log4net.config
new file mode 100644
index 0000000000..73bfc77a3e
--- /dev/null
+++ b/qpid/dotnet/Qpid.Integration.Tests/log4net.config
@@ -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.
+
+-->
+
+<log4net>
+
+ <!-- ============================== -->
+ <!-- Append messages to the console -->
+ <!-- ============================== -->
+
+ <appender name="console" type="log4net.Appender.ConsoleAppender" >
+ <layout type="log4net.Layout.PatternLayout">
+ <conversionPattern value="%m%n"/>
+ </layout>
+ <threshold value="info"/>
+ </appender>
+
+ <!-- ====================================== -->
+ <!-- Append messages to the socket appender -->
+ <!-- ====================================== -->
+
+ <appender name="UdpAppender" type="log4net.Appender.UdpAppender">
+ <remoteAddress value="127.0.0.1"/>
+ <remotePort value="4445"/>
+ <layout type="log4net.Layout.XmlLayoutSchemaLog4j">
+ <locationInfo value="true"/>
+ </layout>
+ <threshold value="debug"/>
+ </appender>
+
+ <!-- ================ -->
+ <!-- Limit categories -->
+ <!-- ================ -->
+
+ <logger name="Qpid">
+ <level value="debug"/>
+ </logger>
+
+ <logger name="CONSOLE">
+ <level value="info"/>
+ <appender-ref ref="console"/>
+ </logger>
+
+ <!-- ======================= -->
+ <!-- Setup the Root category -->
+ <!-- ======================= -->
+
+ <root>
+ <appender-ref ref="UdpAppender"/>
+ </root>
+
+</log4net>
diff --git a/qpid/dotnet/Qpid.Integration.Tests/old/ServiceProvidingClient.tmp b/qpid/dotnet/Qpid.Integration.Tests/old/ServiceProvidingClient.tmp
new file mode 100644
index 0000000000..b1e7a50aaa
--- /dev/null
+++ b/qpid/dotnet/Qpid.Integration.Tests/old/ServiceProvidingClient.tmp
@@ -0,0 +1,150 @@
+/*
+ *
+ * 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.
+ *
+ */
+using System;
+using System.Threading;
+using log4net;
+using NUnit.Framework;
+using Apache.Qpid.Messaging;
+
+namespace Apache.Qpid.Integration.Tests.testcases
+{
+ [TestFixture, Category("Integration")]
+ public class ServiceProvidingClient : BaseMessagingTestFixture
+ {
+ private static ILog _logger = LogManager.GetLogger(typeof(ServiceProvidingClient));
+
+ private int _messageCount;
+
+ private string _replyToExchangeName;
+ private string _replyToRoutingKey;
+ const int PACK = 100;
+
+ private IMessagePublisher _destinationPublisher;
+ private IMessageConsumer _consumer;
+
+ private string _serviceName = "ServiceQ1";
+
+ private string _selector = null;
+
+ [SetUp]
+ public override void Init()
+ {
+ base.Init();
+
+ _logger.Info("Starting...");
+ _logger.Info("Service (queue) name is '" + _serviceName + "'...");
+
+ _connection.ExceptionListener = new ExceptionListenerDelegate(OnConnectionException);
+
+ _logger.Info("Message selector is <" + _selector + ">...");
+
+ _channel.DeclareQueue(_serviceName, false, false, false);
+
+ _consumer = _channel.CreateConsumerBuilder(_serviceName)
+ .WithPrefetchLow(100)
+ .WithPrefetchHigh(500)
+ .WithNoLocal(true)
+ .Create();
+ _consumer.OnMessage = new MessageReceivedDelegate(OnMessage);
+ }
+
+ public override void Shutdown()
+ {
+ _consumer.Dispose();
+ base.Shutdown();
+ }
+
+ private void OnConnectionException(Exception e)
+ {
+ _logger.Info("Connection exception occurred", e);
+ // XXX: Test still doesn't shutdown when broker terminates. Is there no heartbeat?
+ }
+
+ [Test]
+ public void Test()
+ {
+ _connection.Start();
+ _logger.Info("Waiting...");
+
+ ServiceRequestingClient client = new ServiceRequestingClient();
+ client.Init();
+ client.SendMessages();
+ }
+
+ private void OnMessage(IMessage message)
+ {
+// _logger.Info("Got message '" + message + "'");
+
+ ITextMessage tm = (ITextMessage)message;
+
+ try
+ {
+ string replyToExchangeName = tm.ReplyToExchangeName;
+ string replyToRoutingKey = tm.ReplyToRoutingKey;
+
+ _replyToExchangeName = replyToExchangeName;
+ _replyToRoutingKey = replyToRoutingKey;
+ _logger.Debug("About to create a producer");
+
+// Console.WriteLine("ReplyTo.ExchangeName = " + _replyToExchangeName);
+// Console.WriteLine("ReplyTo.RoutingKey = " + _replyToRoutingKey);
+
+ _destinationPublisher = _channel.CreatePublisherBuilder()
+ .WithExchangeName(_replyToExchangeName)
+ .WithRoutingKey(_replyToRoutingKey)
+ .WithDeliveryMode(DeliveryMode.NonPersistent)
+ .Create();
+ _destinationPublisher.DisableMessageTimestamp = true;
+ _logger.Debug("After create a producer");
+ }
+ catch (QpidException e)
+ {
+ _logger.Error("Error creating destination", e);
+ throw e;
+ }
+ _messageCount++;
+ if (_messageCount % PACK == 0)
+ {
+ _logger.Info("Received message total: " + _messageCount);
+ _logger.Info(string.Format("Sending response to '{0}:{1}'",
+ _replyToExchangeName, _replyToRoutingKey));
+ }
+
+ try
+ {
+ String payload = "This is a response: sing together: 'Mahnah mahnah...'" + tm.Text;
+ ITextMessage msg = _channel.CreateTextMessage(payload);
+ if ( tm.Headers.Contains("timeSent") )
+ {
+ msg.Headers["timeSent"] = tm.Headers["timeSent"];
+ }
+ _destinationPublisher.Send(msg);
+ } catch ( QpidException e )
+ {
+ _logger.Error("Error sending message: " + e, e);
+ throw e;
+ } finally
+ {
+ _destinationPublisher.Dispose();
+ }
+ }
+ }
+}
diff --git a/qpid/dotnet/Qpid.Integration.Tests/old/ServiceRequestingClient.tmp b/qpid/dotnet/Qpid.Integration.Tests/old/ServiceRequestingClient.tmp
new file mode 100644
index 0000000000..da0f764bcd
--- /dev/null
+++ b/qpid/dotnet/Qpid.Integration.Tests/old/ServiceRequestingClient.tmp
@@ -0,0 +1,182 @@
+/*
+ *
+ * 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.
+ *
+ */
+using System;
+using System.Threading;
+using log4net;
+using NUnit.Framework;
+using Apache.Qpid.Messaging;
+
+namespace Apache.Qpid.Integration.Tests.testcases
+{
+ public class ServiceRequestingClient : BaseMessagingTestFixture
+ {
+ private const int MESSAGE_SIZE = 1024;
+ private static string MESSAGE_DATA = new string('x', MESSAGE_SIZE);
+
+ private const int PACK = 100;
+ private const int NUM_MESSAGES = PACK*10; // increase when in standalone
+
+ private static ILog _log = LogManager.GetLogger(typeof(ServiceRequestingClient));
+
+ ManualResetEvent _finishedEvent = new ManualResetEvent(false);
+
+ private int _expectedMessageCount = NUM_MESSAGES;
+
+ private long _startTime = 0;
+
+ private string _commandQueueName = "ServiceQ1";
+
+ private IMessagePublisher _publisher;
+
+ Avergager averager = new Avergager();
+
+ private void InitialiseProducer()
+ {
+ try
+ {
+ _publisher = _channel.CreatePublisherBuilder()
+ .WithRoutingKey(_commandQueueName)
+ .WithDeliveryMode(DeliveryMode.NonPersistent)
+ .Create();
+ _publisher.DisableMessageTimestamp = true; // XXX: need a "with" for this in builder?
+ }
+ catch (QpidException e)
+ {
+ _log.Error("Error: " + e, e);
+ }
+ }
+
+ [Test]
+ public void SendMessages()
+ {
+ InitialiseProducer();
+
+ string replyQueueName = _channel.GenerateUniqueName();
+
+ _channel.DeclareQueue(replyQueueName, false, true, true);
+
+ IMessageConsumer messageConsumer = _channel.CreateConsumerBuilder(replyQueueName)
+ .WithPrefetchLow(100)
+ .WithPrefetchHigh(200)
+ .WithNoLocal(true)
+ .WithExclusive(true).Create();
+
+ _startTime = DateTime.Now.Ticks;
+
+ messageConsumer.OnMessage = new MessageReceivedDelegate(OnMessage);
+ _connection.Start();
+ for (int i = 0; i < _expectedMessageCount; i++)
+ {
+ ITextMessage msg;
+ try
+ {
+ msg = _channel.CreateTextMessage(MESSAGE_DATA + i);
+ }
+ catch (Exception e)
+ {
+ _log.Error("Error creating message: " + e, e);
+ break;
+ }
+ msg.ReplyToRoutingKey = replyQueueName;
+
+ // Added timestamp.
+ long timeNow = DateTime.Now.Ticks;
+ string timeSentString = String.Format("{0:G}", timeNow);
+ msg.Headers.SetLong("timeSent", timeNow);
+
+ _publisher.Send(msg);
+ }
+
+ // Assert that the test finishes within a reasonable amount of time.
+ const int waitSeconds = 40;
+ const int waitMilliseconds = waitSeconds * 1000;
+ _log.Info("Finished sending " + _expectedMessageCount + " messages");
+ _log.Info(String.Format("Waiting {0} seconds to receive last message...", waitSeconds));
+ Assert.IsTrue(_finishedEvent.WaitOne(waitMilliseconds, false),
+ String.Format("Expected to finish in {0} seconds", waitSeconds));
+ }
+
+ public void OnMessage(IMessage m)
+ {
+ if (_log.IsDebugEnabled)
+ {
+ _log.Debug("Message received: " + m);
+ }
+
+ if (!m.Headers.Contains("timeSent"))
+ {
+ throw new Exception("Set timeSent!");
+ }
+
+ long sentAt = m.Headers.GetLong("timeSent");
+ long now = DateTime.Now.Ticks;
+ long latencyTicks = now - sentAt;
+ long latencyMilliseconds = latencyTicks / TimeSpan.TicksPerMillisecond;
+
+ averager.Add(latencyMilliseconds);
+
+ if (averager.Num % PACK == 0)
+ {
+ _log.Info("Ticks per millisecond = " + TimeSpan.TicksPerMillisecond);
+ _log.Info(String.Format("Average latency (ms) = {0}", averager));
+ _log.Info("Received message count: " + averager.Num);
+ }
+
+ if (averager.Num == _expectedMessageCount)
+ {
+ _log.Info(String.Format("Final average latency (ms) = {0}", averager));
+
+ double timeTakenSeconds = (DateTime.Now.Ticks - _startTime) * 1.0 / (TimeSpan.TicksPerMillisecond * 1000);
+ _log.Info("Total time taken to receive " + _expectedMessageCount + " messages was " +
+ timeTakenSeconds + "s, equivalent to " +
+ (_expectedMessageCount/timeTakenSeconds) + " messages per second");
+
+ _finishedEvent.Set(); // Notify main thread to quit.
+ }
+ }
+ }
+
+ class Avergager
+ {
+ long num = 0;
+ long sum = 0;
+
+ long min = long.MaxValue;
+ long max = long.MinValue;
+
+ public void Add(long item)
+ {
+ ++num;
+ sum += item;
+ if (item < min) min = item;
+ if (item > max) max = item;
+ }
+
+ public long Average { get { return sum/num; }}
+
+ public long Num { get { return num; } }
+
+ public override string ToString()
+ {
+ return String.Format("average={0} min={1} max={2}", Average, min, max);
+ }
+ }
+}
diff --git a/qpid/dotnet/Qpid.Integration.Tests/testcases/BaseMessagingTestFixture.cs b/qpid/dotnet/Qpid.Integration.Tests/testcases/BaseMessagingTestFixture.cs
new file mode 100644
index 0000000000..e67d96f188
--- /dev/null
+++ b/qpid/dotnet/Qpid.Integration.Tests/testcases/BaseMessagingTestFixture.cs
@@ -0,0 +1,280 @@
+/*
+ *
+ * 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.
+ *
+ */
+using System;
+using System.Text;
+using log4net;
+using NUnit.Framework;
+using Apache.Qpid.Messaging;
+using Apache.Qpid.Client.Qms;
+using Apache.Qpid.Client;
+
+namespace Apache.Qpid.Integration.Tests.testcases
+{
+ /// <summary>
+ /// Provides a basis for writing Unit tests that communicate with an AMQ protocol broker. By default it creates a connection
+ /// to a message broker running on localhost on the standard AMQ port, 5672, using guest:guest login credentials. It also
+ /// creates a standard auto-ack channel on this connection.
+ /// </summary>
+ public class BaseMessagingTestFixture
+ {
+ private static ILog log = LogManager.GetLogger(typeof(BaseMessagingTestFixture));
+
+ /// <summary> Used to build dummy data to fill test messages with. </summary>
+ private const string MESSAGE_DATA_BYTES = "-- Test Message -- Test Message -- Test Message -- Test Message -- Test Message ";
+
+ /// <summary> The default timeout in milliseconds to use on receives. </summary>
+ private const long RECEIVE_WAIT = 2000;
+
+ /// <summary> The default AMQ connection URL to use for tests. </summary>
+ public const string connectionUri = "amqp://guest:guest@test/test?brokerlist='tcp://localhost:5672'";
+
+ /// <summary> The default AMQ connection URL parsed as a connection info. </summary>
+ protected IConnectionInfo connectionInfo;
+
+ /// <summary> Holds an array of connections for building mutiple test end-points. </summary>
+ protected IConnection[] testConnection = new IConnection[10];
+
+ /// <summary> Holds an array of channels for building mutiple test end-points. </summary>
+ protected IChannel[] testChannel = new IChannel[10];
+
+ /// <summary> Holds an array of queues for building mutiple test end-points. </summary>
+ protected String[] testQueue = new String[10];
+
+ /// <summary> Holds an array of producers for building mutiple test end-points. </summary>
+ protected IMessagePublisher[] testProducer = new IMessagePublisher[10];
+
+ /// <summary> Holds an array of consumers for building mutiple test end-points. </summary>
+ protected IMessageConsumer[] testConsumer = new IMessageConsumer[10];
+
+ /// <summary> A counter used to supply unique ids. </summary>
+ private static int uniqueId = 0;
+
+ /// <summary> Used to hold unique ids per test. </summary>
+ protected Guid testId;
+
+ /// <summary> Creates the test connection and channel. </summary>
+ [SetUp]
+ public virtual void Init()
+ {
+ log.Debug("public virtual void Init(): called");
+
+ // Set up a unique id for this test.
+ testId = System.Guid.NewGuid();
+ }
+
+ /// <summary>
+ /// Disposes of the test connection. This is called manually because the connection is a field so dispose will not be automatically
+ /// called on it.
+ /// </summary>
+ [TearDown]
+ public virtual void Shutdown()
+ {
+ log.Debug("public virtual void Shutdown(): called");
+ }
+
+ /// <summary> Sets up the nth test end-point. </summary>
+ ///
+ /// <param name="n">The index of the test end-point to set up.</param>
+ /// <param name="producer"><tt>true</tt> to set up a producer on the end-point.</param>
+ /// <param name="consumer"><tt>true</tt> to set up a consumer on the end-point.</param>
+ /// <param name="routingKey">The routing key for the producer to send on.</param>
+ /// <param name="ackMode">The ack mode for the end-points channel.</param>
+ /// <param name="transacted"><tt>true</tt> to use transactions on the end-points channel.</param>
+ /// <param name="exchangeName">The exchange to produce or consume on.</param>
+ /// <param name="declareBind"><tt>true</tt> if the consumers queue should be declared and bound, <tt>false</tt> if it has already been.</param>
+ /// <param name="durable"><tt>true</tt> to declare the consumers queue as durable.</param>
+ /// <param name="subscriptionName">If durable is true, the fixed unique queue name to use.</param>
+ public void SetUpEndPoint(int n, bool producer, bool consumer, string routingKey, AcknowledgeMode ackMode, bool transacted,
+ string exchangeName, bool declareBind, bool durable, string subscriptionName)
+ {
+ SetUpEndPoint(n, producer, consumer, routingKey, ackMode, transacted, exchangeName, declareBind, durable, subscriptionName, true, false);
+ }
+ /// <summary> Sets up the nth test end-point. </summary>
+ ///
+ /// <param name="n">The index of the test end-point to set up.</param>
+ /// <param name="producer"><tt>true</tt> to set up a producer on the end-point.</param>
+ /// <param name="consumer"><tt>true</tt> to set up a consumer on the end-point.</param>
+ /// <param name="routingKey">The routing key for the producer to send on.</param>
+ /// <param name="ackMode">The ack mode for the end-points channel.</param>
+ /// <param name="transacted"><tt>true</tt> to use transactions on the end-points channel.</param>
+ /// <param name="exchangeName">The exchange to produce or consume on.</param>
+ /// <param name="declareBind"><tt>true</tt> if the consumers queue should be declared and bound, <tt>false</tt> if it has already been.</param>
+ /// <param name="durable"><tt>true</tt> to declare the consumers queue as durable.</param>
+ /// <param name="subscriptionName">If durable is true, the fixed unique queue name to use.</param>
+ /// <param name="exclusive"><tt>true</tt> declare queue as exclusive.</param>
+ /// <param name="browse"><tt>true</tt> only browse, don''t consume.</param>
+ public void SetUpEndPoint(int n, bool producer, bool consumer, string routingKey, AcknowledgeMode ackMode, bool transacted,
+ string exchangeName, bool declareBind, bool durable, string subscriptionName, bool exclusive, bool browse)
+ {
+ // Allow client id to be fixed, or undefined.
+ {
+ // Use unique id for end point.
+ connectionInfo = QpidConnectionInfo.FromUrl(connectionUri);
+
+ connectionInfo.ClientName = "test" + n;
+ }
+
+ testConnection[n] = new AMQConnection(connectionInfo);
+ testConnection[n].Start();
+ testChannel[n] = testConnection[n].CreateChannel(transacted, ackMode);
+
+ if (producer)
+ {
+ testProducer[n] = testChannel[n].CreatePublisherBuilder()
+ .WithExchangeName(exchangeName)
+ .WithRoutingKey(routingKey)
+ .Create();
+ }
+
+ if (consumer)
+ {
+ string queueName;
+
+ // Use the subscription name as the queue name if the subscription is durable, otherwise use a generated name.
+ if (durable)
+ {
+ // The durable queue is declared without auto-delete, and passively, in case it has already been declared.
+ queueName = subscriptionName;
+
+ if (declareBind)
+ {
+ testChannel[n].DeclareQueue(queueName, durable, exclusive, false);
+ testChannel[n].Bind(queueName, exchangeName, routingKey);
+ }
+ }
+ else
+ {
+ queueName = testChannel[n].GenerateUniqueName();
+
+ if (declareBind)
+ {
+ if (durable)
+ {
+ testQueue[n] = queueName;
+ }
+ testChannel[n].DeclareQueue(queueName, durable, true, true);
+ testChannel[n].Bind(queueName, exchangeName, routingKey);
+ }
+ }
+
+ testConsumer[n] = testChannel[n].CreateConsumerBuilder(queueName).WithBrowse(browse).Create();
+ }
+ }
+
+ /// <summary> Closes down the nth test end-point. </summary>
+ public void CloseEndPoint(int n)
+ {
+ log.Debug("public void CloseEndPoint(int n): called");
+
+ if (testProducer[n] != null)
+ {
+ testProducer[n].Close();
+ testProducer[n].Dispose();
+ testProducer[n] = null;
+ }
+
+ if (testConsumer[n] != null)
+ {
+ if (testQueue[n] != null)
+ {
+ testChannel[n].DeleteQueue(testQueue[n], false, false, true);
+ }
+ testConsumer[n].Close();
+ testConsumer[n].Dispose();
+ testConsumer[n] = null;
+ }
+
+ if (testConnection[n] != null)
+ {
+ testConnection[n].Stop();
+ testConnection[n].Close();
+ testConnection[n].Dispose();
+ testConnection[n] = null;
+ }
+ }
+
+ /// <summary>
+ /// Consumes n messages, checking that the n+1th is not available within a timeout, and that the consumed messages
+ /// are text messages with contents equal to the specified message body.
+ /// </summary>
+ ///
+ /// <param name="n">The number of messages to consume.</param>
+ /// <param name="body">The body text to match against all messages.</param>
+ /// <param name="consumer">The message consumer to recieve the messages on.</param>
+ public static void ConsumeNMessagesOnly(int n, string body, IMessageConsumer consumer)
+ {
+ ConsumeNMessages(n, body, consumer);
+
+ // Check that one more than n cannot be received.
+ IMessage msg = consumer.Receive(RECEIVE_WAIT);
+ Assert.IsNull(msg, "Consumer got more messages than the number requested (" + n + ").");
+ }
+
+ /// <summary>
+ /// Consumes n messages, checking that the n+1th is not available within a timeout, and that the consumed messages
+ /// are text messages with contents equal to the specified message body.
+ /// </summary>
+ ///
+ /// <param name="n">The number of messages to consume.</param>
+ /// <param name="body">The body text to match against all messages.</param>
+ /// <param name="consumer">The message consumer to recieve the messages on.</param>
+ public static void ConsumeNMessages(int n, string body, IMessageConsumer consumer)
+ {
+ IMessage msg;
+
+ // Try to receive n messages.
+ for (int i = 0; i < n; i++)
+ {
+ msg = consumer.Receive(RECEIVE_WAIT);
+ Assert.IsNotNull(msg, "Consumer did not receive message number: " + i);
+ Assert.AreEqual(body, ((ITextMessage)msg).Text, "Incorrect Message recevied on consumer1.");
+ }
+ }
+
+ /// <summary>Creates the requested number of bytes of dummy text. Usually used for filling test messages. </summary>
+ ///
+ /// <param name="size">The number of bytes of dummy text to generate.</param>
+ ///
+ /// <return>The requested number of bytes of dummy text.</return>
+ public static String GetData(int size)
+ {
+ StringBuilder buf = new StringBuilder(size);
+
+ if (size > 0)
+ {
+ int div = MESSAGE_DATA_BYTES.Length / size;
+ int mod = MESSAGE_DATA_BYTES.Length % size;
+
+ for (int i = 0; i < div; i++)
+ {
+ buf.Append(MESSAGE_DATA_BYTES);
+ }
+
+ if (mod != 0)
+ {
+ buf.Append(MESSAGE_DATA_BYTES, 0, mod);
+ }
+ }
+
+ return buf.ToString();
+ }
+ }
+}
diff --git a/qpid/dotnet/Qpid.Integration.Tests/testcases/ChannelQueueTest.cs b/qpid/dotnet/Qpid.Integration.Tests/testcases/ChannelQueueTest.cs
new file mode 100644
index 0000000000..4692e7ecb1
--- /dev/null
+++ b/qpid/dotnet/Qpid.Integration.Tests/testcases/ChannelQueueTest.cs
@@ -0,0 +1,237 @@
+/*
+ *
+ * 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.
+ *
+ */
+using System;
+using System.Net;
+using System.Threading;
+using log4net;
+using Apache.Qpid.Client.Qms;
+using Apache.Qpid.Client;
+using Apache.Qpid.Messaging;
+using NUnit.Framework;
+
+namespace Apache.Qpid.Integration.Tests.testcases
+{
+ /// <summary>
+ /// Test the queue methods
+ /// </summary>
+ [TestFixture, Category("Integration")]
+ public class ChannelQueueTest
+ {
+ private static ILog _logger = LogManager.GetLogger(typeof(ChannelQueueTest));
+
+ /// <summary> The default AMQ connection URL to use for tests. </summary>
+ const string DEFAULT_URI = "amqp://guest:guest@default/test?brokerlist='tcp://localhost:5672'";
+ const string _routingKey = "ServiceQ1";
+
+ private ExceptionListenerDelegate _exceptionDelegate;
+ private AutoResetEvent _evt = new AutoResetEvent(false);
+ private Exception _lastException = null;
+
+ private IMessageConsumer _consumer;
+ private IMessagePublisher _publisher;
+ private IChannel _channel;
+ private IConnection _connection;
+
+ private string _queueName;
+
+ [SetUp]
+ public virtual void Init()
+ {
+ _logger.Info("public virtual void Init(): called");
+
+ // Create a connection to the broker.
+ IConnectionInfo connectionInfo = QpidConnectionInfo.FromUrl(DEFAULT_URI);
+ _connection = new AMQConnection(connectionInfo);
+ _logger.Info("Starting...");
+
+ // Register this to listen for exceptions on the test connection.
+ _exceptionDelegate = new ExceptionListenerDelegate(OnException);
+ _connection.ExceptionListener += _exceptionDelegate;
+
+ // Establish a session on the broker.
+ _channel = _connection.CreateChannel(false, AcknowledgeMode.AutoAcknowledge, 1);
+
+ // Create a durable, non-temporary, non-exclusive queue.
+ _queueName = _channel.GenerateUniqueName();
+ _channel.DeclareQueue(_queueName, true, false, false);
+
+ _channel.Bind(_queueName, ExchangeNameDefaults.TOPIC, _routingKey);
+
+ // Clear the most recent message and exception.
+ _lastException = null;
+ }
+
+ [TearDown]
+ public virtual void ShutDown()
+ {
+ _logger.Info("public virtual void Shutdown(): called");
+
+ if (_connection != null)
+ {
+ _logger.Info("Disposing connection.");
+ _connection.Dispose();
+ _logger.Info("Connection disposed.");
+ }
+ }
+
+ [Test]
+ public void DeleteUsedQueue()
+ {
+ // Create the consumer
+ _consumer = _channel.CreateConsumerBuilder(_queueName)
+ .WithPrefetchLow(100)
+ .Create();
+ _logger.Info("Consumer was created...");
+
+ // delete the queue
+ _channel.DeleteQueue(_queueName, false, true, true);
+ _logger.InfoFormat("Queue {0} was delete", _queueName);
+
+ Assert.IsNull(_lastException);
+ }
+
+ [Test]
+ public void DeleteUnusedQueue()
+ {
+ // delete the queue
+ _channel.DeleteQueue(_queueName, true, true, true);
+ _logger.InfoFormat("Queue {0} was delete", _queueName);
+
+ Assert.IsNull(_lastException);
+ }
+
+ [Test]
+ public void DeleteNonEmptyQueue()
+ {
+ // Create the publisher
+ _publisher = _channel.CreatePublisherBuilder()
+ .WithExchangeName(ExchangeNameDefaults.TOPIC)
+ .WithRoutingKey(_routingKey)
+ .Create();
+ _logger.Info("Publisher created...");
+ SendTestMessage("DeleteNonEmptyQueue Message 1");
+
+ try
+ {
+ _channel.DeleteQueue(_queueName, true, false, true);
+ }
+ catch (AMQException)
+ {
+ Assert.Fail("The test fails");
+ }
+ }
+
+ [Test]
+ public void DeleteEmptyQueue()
+ {
+ // Create the publisher
+ _publisher = _channel.CreatePublisherBuilder()
+ .WithExchangeName(ExchangeNameDefaults.TOPIC)
+ .WithRoutingKey(_routingKey)
+ .Create();
+ _logger.Info("Publisher created...");
+
+ // delete an empty queue with ifEmpty = true
+ _channel.DeleteQueue(_queueName, false, true, true);
+
+ Assert.IsNull(_lastException);
+ }
+
+ [Test]
+ public void DeleteQueueWithResponse()
+ {
+ // Create the publisher
+ _publisher = _channel.CreatePublisherBuilder()
+ .WithExchangeName(ExchangeNameDefaults.TOPIC)
+ .WithRoutingKey(_routingKey)
+ .Create();
+ _logger.Info("Publisher created...");
+
+ SendTestMessage("DeleteQueueWithResponse Message 1");
+ SendTestMessage("DeleteQueueWithResponse Message 2");
+
+ // delete the queue, the server must respond
+ _channel.DeleteQueue(_queueName, false, false, false);
+ }
+
+ [Test]
+ public void PurgeQueueWithResponse()
+ {
+ _publisher = _channel.CreatePublisherBuilder()
+ .WithExchangeName(ExchangeNameDefaults.TOPIC)
+ .WithRoutingKey(_routingKey)
+ .Create();
+ _logger.Info("Pubisher created");
+
+ SendTestMessage("Message 1");
+ SendTestMessage("Message 2");
+
+ _channel.PurgeQueue(_queueName, false);
+ }
+
+ [Test]
+ public void PurgeQueueWithOutResponse()
+ {
+ _publisher = _channel.CreatePublisherBuilder()
+ .WithExchangeName(ExchangeNameDefaults.TOPIC)
+ .WithRoutingKey(_routingKey)
+ .Create();
+ _logger.Info("Pubisher created");
+
+ SendTestMessage("Message 1");
+ SendTestMessage("Message 2");
+
+ _channel.PurgeQueue(_queueName, true);
+ }
+
+
+ /// <summary>
+ /// Callback method to handle any exceptions raised by the test connection.</summary> ///
+ /// <param name="e">The connection exception.</param>
+ public void OnException(Exception e)
+ {
+ // Preserve the most recent exception in case test cases need to examine it.
+ _lastException = e;
+
+ // Notify any waiting threads that an exception event has occurred.
+ _evt.Set();
+ }
+
+ /// <summary>
+ /// Sends the specified message to the test publisher, and confirms that it was received by the test consumer or not
+ /// depending on whether or not the message should be received by the consumer.
+ ///
+ /// Any exceptions raised by the connection will cause an Assert failure exception to be raised.
+ /// </summary>
+ ///
+ /// <param name="msgSend">The message to send.</param>
+ private void SendTestMessage(string msg)
+ {
+ // create the IMessage object
+ IMessage msgSend = _channel.CreateTextMessage(msg);
+
+ // send the message
+ _publisher.Send(msgSend);
+ _logger.InfoFormat("The messages \"{0}\" was sent", msg);
+ }
+
+ }
+}
diff --git a/qpid/dotnet/Qpid.Integration.Tests/testcases/CommitRollbackTest.cs b/qpid/dotnet/Qpid.Integration.Tests/testcases/CommitRollbackTest.cs
new file mode 100644
index 0000000000..dbb3f70aec
--- /dev/null
+++ b/qpid/dotnet/Qpid.Integration.Tests/testcases/CommitRollbackTest.cs
@@ -0,0 +1,261 @@
+/*
+ *
+ * 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.
+ *
+ */
+using System;
+using System.Threading;
+using log4net;
+using NUnit.Framework;
+using Apache.Qpid.Messaging;
+using Apache.Qpid.Client.Qms;
+using Apache.Qpid.Client;
+
+namespace Apache.Qpid.Integration.Tests.testcases
+{
+ /// <summary>
+ /// CommitRollbackTest
+ ///
+ /// <p><table id="crc"><caption>CRC Card</caption>
+ /// <tr><th> Responsibilities <th> Collaborations
+ /// <tr><td> Check that an uncommitted send cannot be received.
+ /// <tr><td> Check that a committed send can be received.
+ /// <tr><td> Check that a rolled back send cannot be received.
+ /// <tr><td> Check that an uncommitted receive can be re-received.
+ /// <tr><td> Check that a committed receive cannot be re-received.
+ /// <tr><td> Check that a rolled back receive can be re-received.
+ /// </table>
+ /// </summary>
+ [TestFixture, Category("Integration")]
+ public class CommitRollbackTest : BaseMessagingTestFixture
+ {
+ /// <summary>Used for debugging purposes.</summary>
+ private static ILog log = LogManager.GetLogger(typeof(CommitRollbackTest));
+
+ /// <summary>Defines the name of the test topic to use with the tests.</summary>
+ public const string TEST_ROUTING_KEY = "commitrollbacktestkey";
+
+ /// <summary>Used to count test messages received so far.</summary>
+ private int messageReceivedCount;
+
+ /// <summary>Used to hold the expected number of messages to receive.</summary>
+ private int expectedMessageCount;
+
+ /// <summary>Monitor used to signal succesfull receipt of all test messages.</summary>
+ AutoResetEvent finishedEvent;
+
+ /// <summary>Flag used to indicate that all messages really were received, and that the test did not just time out. </summary>
+ private bool allReceived;
+
+ [SetUp]
+ public override void Init()
+ {
+ base.Init();
+
+ // Create one producer and one consumer, p2p, tx, consumer with queue bound to producers routing key.
+ SetUpEndPoint(0, true, false, TEST_ROUTING_KEY + testId, AcknowledgeMode.AutoAcknowledge, true, ExchangeNameDefaults.DIRECT,
+ true, false, null);
+ SetUpEndPoint(1, true, true, TEST_ROUTING_KEY + testId, AcknowledgeMode.AutoAcknowledge, true, ExchangeNameDefaults.DIRECT,
+ true, false, null);
+
+ // Clear counts
+ messageReceivedCount = 0;
+ expectedMessageCount = 0;
+ finishedEvent = new AutoResetEvent(false);
+ allReceived = false;
+ }
+
+ [TearDown]
+ public override void Shutdown()
+ {
+ try
+ {
+ // Clean up after the test.
+ CloseEndPoint(0);
+ CloseEndPoint(1);
+ }
+ finally
+ {
+ base.Shutdown();
+ }
+ }
+
+ /// <summary> Check that an uncommitted send cannot be received. </summary>
+ [Test]
+ public void TestUncommittedSendNotReceived()
+ {
+ // Send messages.
+ testProducer[0].Send(testChannel[0].CreateTextMessage("A"));
+
+ // Try to receive messages.
+ ConsumeNMessagesOnly(0, "A", testConsumer[1]);
+ testChannel[1].Commit();
+ }
+
+ /// <summary> Check that a committed send can be received. </summary>
+ [Test]
+ public void TestCommittedSendReceived()
+ {
+ // Send messages.
+ testProducer[0].Send(testChannel[0].CreateTextMessage("B"));
+ testChannel[0].Commit();
+
+ // Try to receive messages.
+ ConsumeNMessagesOnly(1, "B", testConsumer[1]);
+ testChannel[1].Commit();
+ }
+
+ /// <summary> Check that a rolled back send cannot be received. </summary>
+ [Test]
+ public void TestRolledBackSendNotReceived()
+ {
+ // Send messages.
+ testProducer[0].Send(testChannel[0].CreateTextMessage("B"));
+ testChannel[0].Rollback();
+
+ // Try to receive messages.
+ ConsumeNMessagesOnly(0, "B", testConsumer[1]);
+ testChannel[1].Commit();
+ }
+
+ /// <summary> Check that an uncommitted receive can be re-received. </summary>
+ [Test]
+ public void TestUncommittedReceiveCanBeRereceived()
+ {
+ // Create a third end-point as an alternative delivery route for the message.
+ SetUpEndPoint(2, false, true, TEST_ROUTING_KEY + testId, AcknowledgeMode.AutoAcknowledge, true, ExchangeNameDefaults.DIRECT,
+ true, false, null);
+
+ // Send messages.
+ testProducer[0].Send(testChannel[0].CreateTextMessage("C"));
+ testChannel[0].Commit();
+
+ // Try to receive messages.
+ ConsumeNMessagesOnly(1, "C", testConsumer[1]);
+
+ // Close end-point 1 without committing the message, then re-open to consume again.
+ CloseEndPoint(1);
+
+ // Check that the message was released from the rolled back end-point an can be received on the alternative one instead.
+ ConsumeNMessagesOnly(1, "C", testConsumer[2]);
+
+ CloseEndPoint(2);
+ }
+
+ /// <summary> Check that a committed receive cannot be re-received. </summary>
+ [Test]
+ public void TestCommittedReceiveNotRereceived()
+ {
+ // Send messages.
+ testProducer[0].Send(testChannel[0].CreateTextMessage("D"));
+ testChannel[0].Commit();
+
+ // Try to receive messages.
+ ConsumeNMessagesOnly(1, "D", testConsumer[1]);
+ testChannel[1].Commit();
+
+ // Try to receive messages.
+ ConsumeNMessagesOnly(0, "D", testConsumer[1]);
+ }
+
+ /// <summary> Check that a rolled back receive can be re-received. </summary>
+ [Test]
+ public void TestRolledBackReceiveCanBeRereceived()
+ {
+ // Send messages.
+ testProducer[0].Send(testChannel[0].CreateTextMessage("E"));
+ testChannel[0].Commit();
+
+ // Try to receive messages.
+ ConsumeNMessagesOnly(1, "E", testConsumer[1]);
+
+ testChannel[1].Rollback();
+
+ // Try to receive messages.
+ ConsumeNMessagesOnly(1, "E", testConsumer[1]);
+
+ }
+
+ [Test]
+ public void TestReceiveAndSendRollback()
+ {
+ // Send messages
+ testProducer[0].Send(testChannel[0].CreateTextMessage("F"));
+ testChannel[0].Commit();
+
+ // Try to receive messages.
+ ConsumeNMessagesOnly(1, "F", testConsumer[1]);
+ testProducer[1].Send(testChannel[1].CreateTextMessage("G"));
+ testChannel[1].Rollback();
+
+ // Try to receive messages.
+ ConsumeNMessagesOnly(1, "F", testConsumer[1]);
+
+ }
+
+ [Test]
+ public void TestReceivePrePublished()
+ {
+ // Send messages
+ for (int i = 0; i < 10; ++i)
+ {
+ testProducer[0].Send(testChannel[0].CreateTextMessage("G"+i));
+ testChannel[0].Commit();
+ }
+
+ for (int i = 0; i < 10; ++i)
+ {
+ ConsumeNMessages(1, "G"+i, testConsumer[1]);
+ }
+ testChannel[1].Commit();
+ }
+
+ [Test]
+ public void TestReceivePrePublishedOnMessageHandler()
+ {
+ testConsumer[1].OnMessage += new MessageReceivedDelegate(OnMessage);
+ // Send messages
+ for (int i = 0; i < 10; ++i)
+ {
+ testProducer[0].Send(testChannel[0].CreateTextMessage("G"+i));
+ testChannel[0].Commit();
+ }
+ expectedMessageCount = 10;
+
+ finishedEvent.WaitOne(new TimeSpan(0, 0, 0, 30), false);
+
+ // Check that all messages really were received.
+ Assert.IsTrue(allReceived, "All messages were not received, only got: " + messageReceivedCount + " but wanted " + expectedMessageCount);
+
+ testChannel[1].Commit();
+ }
+
+ /// <summary> Atomically increments the message count on every message, and signals once all messages in the test are received. </summary>
+ public void OnMessage(IMessage m)
+ {
+ int newCount = Interlocked.Increment(ref messageReceivedCount);
+
+ if (newCount >= expectedMessageCount)
+ {
+ allReceived = true;
+ finishedEvent.Set();
+ }
+ }
+
+ }
+}
diff --git a/qpid/dotnet/Qpid.Integration.Tests/testcases/ConnectionTest.cs b/qpid/dotnet/Qpid.Integration.Tests/testcases/ConnectionTest.cs
new file mode 100644
index 0000000000..d7b4a4ddd2
--- /dev/null
+++ b/qpid/dotnet/Qpid.Integration.Tests/testcases/ConnectionTest.cs
@@ -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.
+ *
+ */
+using System;
+using NUnit.Framework;
+using Apache.Qpid.Client.Qms;
+using Apache.Qpid.Client;
+using Apache.Qpid.Messaging;
+
+namespace Apache.Qpid.Integration.Tests.testcases
+{
+ [TestFixture, Category("Integration")]
+ public class ConnectionTest
+ {
+ private AmqBrokerInfo _broker =
+ new AmqBrokerInfo("amqp", "localhost", 5672, false);
+
+ [Test]
+ public void SimpleConnection()
+ {
+ IConnectionInfo connectionInfo = new QpidConnectionInfo();
+ connectionInfo.VirtualHost = "test";
+ connectionInfo.AddBrokerInfo(_broker);
+ using (IConnection connection = new AMQConnection(connectionInfo))
+ {
+ Console.WriteLine("connection = " + connection);
+ }
+ }
+
+ [Test]
+ [ExpectedException(typeof(AMQAuthenticationException))]
+ public void PasswordFailureConnection()
+ {
+ IConnectionInfo connectionInfo = new QpidConnectionInfo();
+ connectionInfo.VirtualHost = "test";
+ connectionInfo.Password = "rubbish";
+ connectionInfo.AddBrokerInfo(_broker);
+
+ using (IConnection connection = new AMQConnection(connectionInfo))
+ {
+ Console.WriteLine("connection = " + connection);
+ // wrong
+ Assert.Fail("Authentication succeeded but should've failed");
+ }
+ }
+
+ [Test]
+ [ExpectedException(typeof(AMQConnectionException))]
+ public void ConnectionFailure()
+ {
+ string url = "amqp://guest:guest@clientid/testpath?brokerlist='tcp://localhost:5673?retries='0''";
+ new AMQConnection(QpidConnectionInfo.FromUrl(url));
+ Assert.Fail("Connection should not be established");
+ }
+ }
+}
diff --git a/qpid/dotnet/Qpid.Integration.Tests/testcases/DurableSubscriptionTest.cs b/qpid/dotnet/Qpid.Integration.Tests/testcases/DurableSubscriptionTest.cs
new file mode 100644
index 0000000000..b7973ae3f5
--- /dev/null
+++ b/qpid/dotnet/Qpid.Integration.Tests/testcases/DurableSubscriptionTest.cs
@@ -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.
+ *
+ */
+using System;
+using System.Threading;
+using log4net;
+using NUnit.Framework;
+using Apache.Qpid.Messaging;
+using Apache.Qpid.Client.Qms;
+
+namespace Apache.Qpid.Integration.Tests.testcases
+{
+ /// <summary>
+ /// DurableSubscriptionTest checks that durable subscriptions work, by sending messages that can be picked up by
+ /// a subscription that is currently off-line, and checking that the subscriber gets all of its messages when it
+ /// does come on-line.
+ ///
+ /// <p/><table id="crc"><caption>CRC Card</caption>
+ /// <tr><th> Responsibilities <th> Collaborations
+ /// <tr><td>
+ /// </table>
+ /// </summary>
+ [TestFixture, Category("Integration")]
+ public class DurableSubscriptionTest : BaseMessagingTestFixture
+ {
+ /// <summary>Used for debugging purposes.</summary>
+ private static ILog log = LogManager.GetLogger(typeof(DurableSubscriptionTest));
+
+ /// <summary>Defines the name of the test topic to use with the tests.</summary>
+ public const string TEST_ROUTING_KEY = "durablesubtestkey";
+
+ [SetUp]
+ public override void Init()
+ {
+ base.Init();
+ }
+
+ [TearDown]
+ public override void Shutdown()
+ {
+ base.Shutdown();
+ }
+
+ [Test]
+ public void TestDurableSubscriptionNoAck()
+ {
+ TestDurableSubscription(AcknowledgeMode.NoAcknowledge);
+ }
+
+ [Test]
+ public void TestDurableSubscriptionAutoAck()
+ {
+ TestDurableSubscription(AcknowledgeMode.AutoAcknowledge);
+ }
+
+ private void TestDurableSubscription(AcknowledgeMode ackMode)
+ {
+ // Create a topic with one producer and two consumers.
+ SetUpEndPoint(0, true, false, TEST_ROUTING_KEY + testId, ackMode, false, ExchangeNameDefaults.TOPIC, true, false, null);
+ SetUpEndPoint(1, false, true, TEST_ROUTING_KEY + testId, ackMode, false, ExchangeNameDefaults.TOPIC, true, false, null);
+ SetUpEndPoint(2, false, true, TEST_ROUTING_KEY + testId, ackMode, false, ExchangeNameDefaults.TOPIC, true,
+ true, "TestSubscription" + testId);
+
+ Thread.Sleep(500);
+
+ // Send messages and receive on both consumers.
+ testProducer[0].Send(testChannel[0].CreateTextMessage("A"));
+
+ ConsumeNMessagesOnly(1, "A", testConsumer[1]);
+ ConsumeNMessagesOnly(1, "A", testConsumer[2]);
+
+ // Detach one consumer.
+ CloseEndPoint(2);
+
+ // Send message and receive on one consumer.
+ testProducer[0].Send(testChannel[0].CreateTextMessage("B"));
+
+ ConsumeNMessagesOnly(1, "B", testConsumer[1]);
+
+ // Re-attach consumer, check that it gets the messages that it missed.
+ SetUpEndPoint(2, false, true, TEST_ROUTING_KEY + testId, ackMode, false, ExchangeNameDefaults.TOPIC, true,
+ true, "TestSubscription" + testId);
+
+ ConsumeNMessagesOnly(1, "B", testConsumer[2]);
+
+ // Clean up any open consumers at the end of the test.
+ CloseEndPoint(2);
+ CloseEndPoint(1);
+ CloseEndPoint(0);
+ }
+
+ /// <summary> Check that an uncommitted receive can be re-received, on re-consume from the same durable subscription. </summary>
+ [Test]
+ public void TestUncommittedReceiveCanBeRereceivedNewConnection()
+ {
+ SetUpEndPoint(0, true, false, TEST_ROUTING_KEY + testId, AcknowledgeMode.AutoAcknowledge, true, ExchangeNameDefaults.TOPIC,
+ true, false, null);
+ SetUpEndPoint(1, false, true, TEST_ROUTING_KEY + testId, AcknowledgeMode.AutoAcknowledge, true, ExchangeNameDefaults.TOPIC,
+ true, true, "foo"+testId);
+
+ // Send messages.
+ testProducer[0].Send(testChannel[0].CreateTextMessage("C"));
+ testChannel[0].Commit();
+
+ // Try to receive messages, but don't commit them.
+ ConsumeNMessagesOnly(1, "C", testConsumer[1]);
+
+ // Close end-point 1 without committing the message, then re-open the subscription to consume again.
+ CloseEndPoint(1);
+ SetUpEndPoint(1, false, true, TEST_ROUTING_KEY + testId, AcknowledgeMode.AutoAcknowledge, true, ExchangeNameDefaults.TOPIC,
+ true, true, "foo"+testId);
+
+ // Check that the message was released from the rolled back end-point an can be received on the alternative one instead.
+ ConsumeNMessagesOnly(1, "C", testConsumer[1]);
+ testChannel[1].Commit();
+ CloseEndPoint(1);
+ CloseEndPoint(0);
+ }
+
+ /// <summary> Check that a rolled back receive can be re-received, on re-consume from the same durable subscription. </summary>
+ [Test]
+ public void TestRolledBackReceiveCanBeRereceivedNewConnection()
+ {
+ SetUpEndPoint(0, true, false, TEST_ROUTING_KEY + testId, AcknowledgeMode.AutoAcknowledge, true, ExchangeNameDefaults.TOPIC,
+ true, false, null);
+ SetUpEndPoint(1, false, true, TEST_ROUTING_KEY + testId, AcknowledgeMode.AutoAcknowledge, true, ExchangeNameDefaults.TOPIC,
+ true, true, "foo"+testId);
+
+ // Send messages.
+ testProducer[0].Send(testChannel[0].CreateTextMessage("D"));
+ testChannel[0].Commit();
+
+ // Try to receive messages, but roll them back.
+ ConsumeNMessagesOnly(1, "D", testConsumer[1]);
+ testChannel[1].Rollback();
+
+ // Close end-point 1 without committing the message, then re-open the subscription to consume again.
+ CloseEndPoint(1);
+ SetUpEndPoint(1, false, true, TEST_ROUTING_KEY + testId, AcknowledgeMode.AutoAcknowledge, true, ExchangeNameDefaults.TOPIC,
+ true, true, "foo"+testId);
+
+ // Check that the message was released from the rolled back end-point an can be received on the alternative one instead.
+ ConsumeNMessagesOnly(1, "D", testConsumer[1]);
+ testChannel[1].Commit();
+ CloseEndPoint(1);
+ CloseEndPoint(0);
+ }
+ }
+}
diff --git a/qpid/dotnet/Qpid.Integration.Tests/testcases/HeadersExchangeTest.cs b/qpid/dotnet/Qpid.Integration.Tests/testcases/HeadersExchangeTest.cs
new file mode 100644
index 0000000000..2094aa3b1b
--- /dev/null
+++ b/qpid/dotnet/Qpid.Integration.Tests/testcases/HeadersExchangeTest.cs
@@ -0,0 +1,282 @@
+/*
+ *
+ * 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.
+ *
+ */
+using System;
+using System.Threading;
+using log4net;
+using NUnit.Framework;
+using Apache.Qpid.Framing;
+using Apache.Qpid.Messaging;
+using Apache.Qpid.Client.Qms;
+using Apache.Qpid.Client;
+
+namespace Apache.Qpid.Integration.Tests.testcases
+{
+ /// <summary>
+ /// Sets up a producer/consumer pair to send test messages through a header exchange. The header exchange matching pattern is tested to
+ /// verify that it correctly matches or filters out messages based on their headers.
+ ///
+ /// Check that a message matching all fields of a headers exchange is passed by the exchange.
+ /// Check that a message containing values for empty fields of a headers exchange is passed by the exchange.
+ /// Check that a message matching only some fields of a headers exhcnage is not passed by the exchange.
+ /// Check that a message with additional fields to the correct matching fields of a headers exchange is passed by the exchange.
+ /// </summary>
+ ///
+ /// <todo>Remove the HeadersMatchingProducer class and rename this to HeaderExchangeTest. The producer and consumer are implemented
+ /// in a single test class to make running this as part of an automated test suite possible.</todo>
+ ///
+ /// <todo>Consider not using a delegate to callback the OnMessage method. Easier to just call receive on the consumer but using the
+ /// callback does demonstrate how to do so.</todo>
+ [TestFixture, Category("Integration")]
+ public class HeadersExchangeTest : BaseMessagingTestFixture
+ {
+ private static ILog _logger = LogManager.GetLogger(typeof(HeadersExchangeTest));
+
+ /// <summary> Holds the default test timeout for broker communications before tests give up. </summary>
+ private static readonly int TIMEOUT = 2000;
+
+ /// <summary> Holds the name of the headers exchange to create to send test messages on. </summary>
+ private string _exchangeName = "ServiceQ1";
+
+ /// <summary> Used to preserve the most recent exception in case test cases need to examine it. </summary>
+ private Exception _lastException = null;
+
+ /// <summary> Used to preserve the most recent message from the test consumer. </summary>
+ private IMessage _lastMessage = null;
+
+ /// <summary> The test consumer to get messages from the broker with. </summary>
+ private IMessageConsumer _consumer;
+
+ private IMessagePublisher _publisher;
+
+ private AutoResetEvent _evt = new AutoResetEvent(false);
+
+ private MessageReceivedDelegate _msgRecDelegate;
+ private ExceptionListenerDelegate _exceptionDelegate;
+
+ /// <summary> Holds the test connection. </summary>
+ protected IConnection _connection;
+
+ /// <summary> Holds the test channel. </summary>
+ protected IChannel _channel;
+
+ [SetUp]
+ public override void Init()
+ {
+ // Ensure that the base init method is called. It establishes a connection with the broker.
+ base.Init();
+
+ connectionInfo = QpidConnectionInfo.FromUrl(connectionUri);
+ _connection = new AMQConnection(connectionInfo);
+ _channel = _connection.CreateChannel(false, AcknowledgeMode.AutoAcknowledge, 500, 300);
+
+ _logger.Info("Starting...");
+ _logger.Info("Exchange name is '" + _exchangeName + "'...");
+
+ // Register this to listen for exceptions on the test connection.
+ _exceptionDelegate = new ExceptionListenerDelegate(OnException);
+ _connection.ExceptionListener += _exceptionDelegate;
+
+ // Declare a new headers exchange with the name of the test service.
+ _channel.DeclareExchange(_exchangeName, ExchangeClassConstants.HEADERS);
+
+ // Create a non-durable, temporary (aka auto-delete), exclusive queue.
+ string queueName = _channel.GenerateUniqueName();
+ _channel.DeclareQueue(queueName, false, true, true);
+
+ // Bind the queue to the new headers exchange, setting up some header patterns for the exchange to match.
+ _channel.Bind(queueName, _exchangeName, null, CreatePatternAsFieldTable());
+
+ // Create a test consumer to consume messages from the test exchange.
+ _consumer = _channel.CreateConsumerBuilder(queueName)
+ .WithPrefetchLow(100)
+ .WithPrefetchHigh(500)
+ .WithNoLocal(false) // make sure we get our own messages
+ .Create();
+
+ // Register this to listen for messages on the consumer.
+ _msgRecDelegate = new MessageReceivedDelegate(OnMessage);
+ _consumer.OnMessage += _msgRecDelegate;
+
+ // Clear the most recent message and exception.
+ _lastException = null;
+ _lastMessage = null;
+
+ _publisher = _channel.CreatePublisherBuilder()
+ .WithExchangeName(_exchangeName)
+ .WithMandatory(true)
+ .Create();
+
+ _publisher.DeliveryMode = DeliveryMode.NonPersistent;
+
+ // Start all channel
+ _connection.Start();
+ }
+
+ /// <summary>
+ /// Deregisters the on message delegate before closing the connection.
+ /// </summary>
+ [TearDown]
+ public override void Shutdown()
+ {
+ _logger.Info("public void Shutdown(): called");
+
+ //_consumer.OnMessage -= _msgRecDelegate;
+ //_connection.ExceptionListener -= _exceptionDelegate;
+
+ _connection.Stop();
+ _connection.Close();
+ _connection.Dispose();
+
+ base.Shutdown();
+ }
+
+ /// <summary>
+ /// Callback method that is passed any messages received on the test channel.
+ /// </summary>
+ ///
+ /// <param name="message">The received message.</param>
+ public void OnMessage(IMessage message)
+ {
+ _logger.Debug(string.Format("message.Type = {0}", message.GetType()));
+ _logger.Debug("Got message '" + message + "'");
+
+ // Preserve the most recent exception so that test cases can examine it.
+ _lastMessage = message;
+
+ // Notify any waiting threads that a message has been received.
+ _evt.Set();
+ }
+
+ /// <summary>Callback method to handle any exceptions raised by the test connection.</summary>
+ ///
+ /// <param name="e">The connection exception.</param>
+ public void OnException(Exception e)
+ {
+ // Preserve the most recent exception in case test cases need to examine it.
+ _lastException = e;
+
+ // Notify any waiting threads that an exception event has occurred.
+ _evt.Set();
+ }
+
+ /// <summary>Check that a message matching all fields of a headers exchange is passed by the exchange.</summary>
+ [Test]
+ public void TestMatchAll()
+ {
+ IMessage msg = _channel.CreateTextMessage("matches match2=''");
+ msg.Headers["match1"] = "foo";
+ msg.Headers["match2"] = "";
+
+ // Use the SendTestMessage helper method to verify that the message was sent and received.
+ SendTestMessage(msg, true);
+ }
+
+ /// <summary>Check that a message containing values for empty fields of a headers exchange is passed by the exchange.</summary>
+ [Test]
+ public void TestMatchEmptyMatchesAnything()
+ {
+ // Send a test message that matches the headers exchange.
+ IMessage msg = _channel.CreateTextMessage("matches match1='foo' and match2='bar'");
+ msg.Headers["match1"] = "foo";
+ msg.Headers["match2"] = "bar";
+
+ // Use the SendTestMessage helper method to verify that the message was sent and received.
+ SendTestMessage(msg, true);
+ }
+
+ /// <summary>Check that a message matching only some fields of a headers exchange is not passed by the exchange.</summary>
+ [Test]
+ public void TestMatchOneFails()
+ {
+ IMessage msg = _channel.CreateTextMessage("not match - only match1");
+ msg.Headers["match1"] = "foo";
+
+ // Use the SendTestMessage helper method to verify that the message was sent and not received.
+ SendTestMessage(msg, false);
+ }
+
+ /// <summary>
+ /// Check that a message with additional fields to the correct matching fields of a headers exchange is passed by
+ /// the exchange.
+ /// </summary>
+ [Test]
+ public void TestMatchExtraFields()
+ {
+ IMessage msg = _channel.CreateTextMessage("matches - extra headers");
+ msg.Headers["match1"] = "foo";
+ msg.Headers["match2"] = "bar";
+ msg.Headers["match3"] = "not required";
+
+ // Use the SendTestMessage helper method to verify that the message was sent and received.
+ SendTestMessage(msg, true);
+ }
+
+ /// <summary>
+ /// Sends the specified message to the test publisher, and confirms that it was received by the test consumer or not
+ /// depending on whether or not the message should be received by the consumer.
+ ///
+ /// Any exceptions raised by the connection will cause an Assert failure exception to be raised.
+ /// </summary>
+ ///
+ /// <param name="msgSend">The message to send.</param>
+ /// <param name="shouldPass">A flag to indicate whether or not the message should be received by the consumer.</param>
+ private void SendTestMessage(IMessage msgSend, bool shouldPass)
+ {
+ _publisher.Send(msgSend);
+ _evt.WaitOne(TIMEOUT, true);
+
+ // Check that an exception other than not routable was raised in which case re-raise it as a test error.
+ if (_lastException != null && !(_lastException.InnerException is AMQUndeliveredException))
+ {
+ Assert.Fail("Exception {0} was raised by the broker connection.", _lastException);
+ }
+ // Check that a message was returned if the test is expecting the message to pass.
+ else if (shouldPass)
+ {
+ Assert.IsNotNull(_lastMessage, "Did not get a matching message from the headers exchange.");
+ }
+ // Check that a not routable exception was raised if the test is expecting the message to fail.
+ else if (_lastException != null && _lastException.InnerException is AMQUndeliveredException)
+ {
+ Assert.IsNull(_lastMessage, "Message could not be routed so consumer should not have received it.");
+ }
+ // The broker did not respond within the test timeout so fail the test.
+ else
+ {
+ Assert.Fail("The test timed out without a response from the broker.");
+ }
+ }
+
+ /// <summary> Returns a field table containing patterns to match the test header exchange against. </summary>
+ ///
+ /// <returns> A field table containing test patterns. </returns>
+ private FieldTable CreatePatternAsFieldTable()
+ {
+ FieldTable matchTable = new FieldTable();
+
+ matchTable["match1"] = "foo";
+ matchTable["match2"] = "";
+ matchTable["x-match"] = "all";
+
+ return matchTable;
+ }
+ }
+}
diff --git a/qpid/dotnet/Qpid.Integration.Tests/testcases/MandatoryMessageTest.cs b/qpid/dotnet/Qpid.Integration.Tests/testcases/MandatoryMessageTest.cs
new file mode 100644
index 0000000000..4abc56905f
--- /dev/null
+++ b/qpid/dotnet/Qpid.Integration.Tests/testcases/MandatoryMessageTest.cs
@@ -0,0 +1,149 @@
+/*
+ *
+ * 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.
+ *
+ */
+using System;
+using System.Threading;
+using log4net;
+using NUnit.Framework;
+using Apache.Qpid.Messaging;
+using Apache.Qpid.Client.Qms;
+using Apache.Qpid.Client;
+
+namespace Apache.Qpid.Integration.Tests.testcases
+{
+ /// <summary>
+ /// MandatoryMessageTest checks that messages sent with the 'mandatory' flag, must either be routed to a valid
+ /// queue or returned to the sender when no route is available.
+ ///
+ /// <p><table id="crc"><caption>CRC Card</caption>
+ /// <tr><th> Responsibilities <th> Collaborations
+ /// <tr><td> Check default exchange returns unroutable mandatory messages.
+ /// <tr><td> Check direct exchange returns unroutable mandatory messages.
+ /// <tr><td> Check headers exchange returns unroutable mandatory messages.
+ /// <tr><td> Check topic exchange returns unroutable mandatory messages.
+ /// </table>
+ /// </summary>
+ [TestFixture, Category("Integration")]
+ public class MandatoryMessageTest : BaseMessagingTestFixture
+ {
+ /// <summary>Used for debugging purposes.</summary>
+ private static ILog log = LogManager.GetLogger(typeof(MandatoryMessageTest));
+
+ /// <summary>Defines the maximum time in milliseconds, to wait for redelivery to occurr.</summary>
+ public const int TIMEOUT = 1000;
+
+ /// <summary>Defines the name of the routing key to use with the tests.</summary>
+ public const string TEST_ROUTING_KEY = "unboundkey";
+
+ /// <summary>Condition used to coordinate receipt of redelivery exception to the sending thread.</summary>
+ private ManualResetEvent errorEvent;
+
+ /// <summary>Holds the last received error condition, for examination by the tests sending thread.</summary>
+ private Exception lastErrorException;
+
+ /// <summary> Holds the test connection. </summary>
+ protected IConnection _connection;
+
+ /// <summary> Holds the test channel. </summary>
+ protected IChannel _channel;
+
+ [SetUp]
+ public override void Init()
+ {
+ base.Init();
+
+ errorEvent = new ManualResetEvent(false);
+ lastErrorException = null;
+ }
+
+ [TearDown]
+ public override void Shutdown()
+ {
+ base.Shutdown();
+ }
+
+ /// <summary>
+ /// Handles all exception conditions on the connection. The error event is notified and the exception recorded as the last seen.
+ /// </summary>
+ ///
+ /// <param name="e">The asynchronous exception on the connection.</param>
+ public void OnException(Exception e)
+ {
+ lastErrorException = e;
+ errorEvent.Set();
+ }
+
+ [Test]
+ public void SendUndeliverableMessageOnDirectExchange()
+ {
+ SendOne(ExchangeNameDefaults.DIRECT);
+ }
+
+ [Test]
+ public void SendUndeliverableMessageOnTopicExchange()
+ {
+ SendOne(ExchangeNameDefaults.TOPIC);
+ }
+
+ [Test]
+ public void SendUndeliverableMessageOnHeadersExchange()
+ {
+ SendOne(ExchangeNameDefaults.HEADERS);
+ }
+
+ /// <summary>
+ /// Sends a single message to the specified exchange with the routing key 'unboundkey', marked as mandatory.
+ /// A check is performed to assert that a redelivery error is returned from the broker for the message.
+ /// </summary>
+ ///
+ /// <param name="exchangeName">The name of the exchange to send to.</param>
+ private void SendOne(string exchangeName)
+ {
+ log.Debug("private void SendOne(string exchangeName = " + exchangeName + "): called");
+
+ // Send a test message to a unbound key on the specified exchange.
+ SetUpEndPoint(0, false, false, TEST_ROUTING_KEY + testId, AcknowledgeMode.AutoAcknowledge, false, exchangeName,
+ true, false, null);
+ testProducer[0] = testChannel[0].CreatePublisherBuilder()
+ .WithRoutingKey(TEST_ROUTING_KEY + testId)
+ .WithMandatory(true)
+ .WithExchangeName(exchangeName)
+ .Create();
+
+ // Set up the exception listener on the connection.
+ testConnection[0].ExceptionListener = new ExceptionListenerDelegate(OnException);
+
+ // Send message that should fail.
+ testProducer[0].Send(testChannel[0].CreateTextMessage("Test Message"));
+
+ // Wait for up to the timeout for a redelivery exception to be returned.
+ errorEvent.WaitOne(TIMEOUT, true);
+
+ // Asserts that a redelivery exception was returned, and is of the correct type.
+ Type expectedException = typeof(AMQUndeliveredException);
+ Exception ex = lastErrorException;
+
+ Assert.IsNotNull(ex, "No exception was thrown by the test. Expected " + expectedException);
+ Assert.IsInstanceOfType(expectedException, ex.InnerException);
+
+ CloseEndPoint(0);
+ }
+ }
+}
diff --git a/qpid/dotnet/Qpid.Integration.Tests/testcases/ProducerMultiConsumerTest.cs b/qpid/dotnet/Qpid.Integration.Tests/testcases/ProducerMultiConsumerTest.cs
new file mode 100644
index 0000000000..bae6c76818
--- /dev/null
+++ b/qpid/dotnet/Qpid.Integration.Tests/testcases/ProducerMultiConsumerTest.cs
@@ -0,0 +1,167 @@
+/*
+ *
+ * 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.
+ *
+ */
+using System;
+using System.Text;
+using System.Threading;
+using log4net;
+using NUnit.Framework;
+using Apache.Qpid.Messaging;
+using Apache.Qpid.Client.Qms;
+using Apache.Qpid.Client;
+
+namespace Apache.Qpid.Integration.Tests.testcases
+{
+ /// ProducerMultiConsumerTest provides some tests for one producer and multiple consumers.
+ ///
+ /// <p><table id="crc"><caption>CRC Card</caption>
+ /// <tr><th> Responsibilities <th> Collaborations
+ /// <tr><td> Check that all consumers on a topic each receive all message on it.
+ /// <tr><td> Check that consumers on the same queue receive each message once accross all consumers.
+ /// </table>
+ /// </summary>
+ [TestFixture, Category("Integration")]
+ public class ProducerMultiConsumerTest : BaseMessagingTestFixture
+ {
+ private static readonly ILog _logger = LogManager.GetLogger(typeof(ProducerMultiConsumerTest));
+
+ /// <summary>Base name for the routing key used for this test (made unique by adding in test id).</summary>
+ private const string TEST_ROUTING_KEY = "ProducerMultiConsumerTest";
+
+ /// <summary>The number of consumers to test.</summary>
+ private const int CONSUMER_COUNT = 5;
+
+ /// <summary>The number of test messages to send.</summary>
+ private const int MESSAGE_COUNT = 10;
+
+ /// <summary>Monitor used to signal succesfull receipt of all test messages.</summary>
+ AutoResetEvent _finishedEvent;
+
+ /// <summary>Used to count test messages received so far.</summary>
+ private int _messageReceivedCount;
+
+ /// <summary>Used to hold the expected number of messages to receive.</summary>
+ private int expectedMessageCount;
+
+ /// <summary>Flag used to indicate that all messages really were received, and that the test did not just time out. </summary>
+ private bool allReceived;
+
+ /// <summary> Creates one producing end-point and many consuming end-points connected on a topic. </summary>
+ [SetUp]
+ public override void Init()
+ {
+ base.Init();
+
+ // Reset all test counts and flags.
+ _messageReceivedCount = 0;
+ allReceived = false;
+ _finishedEvent = new AutoResetEvent(false);
+ }
+
+ /// <summary> Cleans up all test end-points. </summary>
+ [TearDown]
+ public override void Shutdown()
+ {
+ try
+ {
+ // Close all end points for producer and consumers.
+ // Producer is on 0, and consumers on 1 .. n, so loop is from 0 to n inclusive.
+ for (int i = 0; i <= CONSUMER_COUNT; i++)
+ {
+ CloseEndPoint(i);
+ }
+ }
+ finally
+ {
+ base.Shutdown();
+ }
+ }
+
+ /// <summary> Check that all consumers on a topic each receive all message on it. </summary>
+ [Test]
+ public void AllConsumerReceiveAllMessagesOnTopic()
+ {
+ // Create end-points for all the consumers in the test.
+ for (int i = 1; i <= CONSUMER_COUNT; i++)
+ {
+ SetUpEndPoint(i, false, true, TEST_ROUTING_KEY + testId, AcknowledgeMode.AutoAcknowledge, false, ExchangeNameDefaults.TOPIC,
+ true, false, null);
+ testConsumer[i].OnMessage += new MessageReceivedDelegate(OnMessage);
+ }
+
+ // Create an end-point to publish to the test topic.
+ SetUpEndPoint(0, true, false, TEST_ROUTING_KEY + testId, AcknowledgeMode.AutoAcknowledge, false, ExchangeNameDefaults.TOPIC,
+ true, false, null);
+
+ expectedMessageCount = (MESSAGE_COUNT * CONSUMER_COUNT);
+
+ for (int i = 0; i < MESSAGE_COUNT; i++)
+ {
+ testProducer[0].Send(testChannel[0].CreateTextMessage("A"));
+ }
+
+ _finishedEvent.WaitOne(new TimeSpan(0, 0, 0, 30), false);
+
+ // Check that all messages really were received.
+ Assert.IsTrue(allReceived, "All messages were not received, only got " + _messageReceivedCount + " but wanted " + expectedMessageCount);
+ }
+
+ /// <summary> Check that consumers on the same queue receive each message once accross all consumers. </summary>
+ [Test]
+ public void AllConsumerReceiveAllMessagesOnDirect()
+ {
+ // Create end-points for all the consumers in the test.
+ for (int i = 1; i <= CONSUMER_COUNT; i++)
+ {
+ SetUpEndPoint(i, false, true, TEST_ROUTING_KEY + testId, AcknowledgeMode.AutoAcknowledge, false, ExchangeNameDefaults.DIRECT,
+ true, false, null);
+ testConsumer[i].OnMessage += new MessageReceivedDelegate(OnMessage);
+ }
+
+ // Create an end-point to publish to the test topic.
+ SetUpEndPoint(0, true, false, TEST_ROUTING_KEY + testId, AcknowledgeMode.AutoAcknowledge, false, ExchangeNameDefaults.DIRECT,
+ true, false, null);
+
+ expectedMessageCount = (MESSAGE_COUNT * CONSUMER_COUNT);
+
+ for (int i = 0; i < MESSAGE_COUNT; i++)
+ {
+ testProducer[0].Send(testChannel[0].CreateTextMessage("A"));
+ }
+
+ _finishedEvent.WaitOne(new TimeSpan(0, 0, 0, 30), false);
+
+ // Check that all messages really were received.
+ Assert.IsTrue(allReceived, "All messages were not received, only got: " + _messageReceivedCount + " but wanted " + expectedMessageCount);
+ }
+
+ /// <summary> Atomically increments the message count on every message, and signals once all messages in the test are received. </summary>
+ public void OnMessage(IMessage m)
+ {
+ int newCount = Interlocked.Increment(ref _messageReceivedCount);
+
+ if (newCount >= expectedMessageCount)
+ {
+ allReceived = true;
+ _finishedEvent.Set();
+ }
+ }
+ }
+}
diff --git a/qpid/dotnet/Qpid.Integration.Tests/testcases/Qpid.Integration.Tests.csproj b/qpid/dotnet/Qpid.Integration.Tests/testcases/Qpid.Integration.Tests.csproj
new file mode 100755
index 0000000000..01ca2cc5bd
--- /dev/null
+++ b/qpid/dotnet/Qpid.Integration.Tests/testcases/Qpid.Integration.Tests.csproj
@@ -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.
+
+-->
+
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <ProjectGuid>{EFEB9E41-B66E-4674-85F7-18FAD056AD67}</ProjectGuid>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <OutputType>Exe</OutputType>
+ <RootNamespace>Qpid.Integration.Tests</RootNamespace>
+ <AssemblyName>Qpid.Integration.Tests</AssemblyName>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
+ <OutputPath>bin\Debug\</OutputPath>
+ <DebugSymbols>True</DebugSymbols>
+ <DebugType>Full</DebugType>
+ <Optimize>False</Optimize>
+ <CheckForOverflowUnderflow>True</CheckForOverflowUnderflow>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
+ <OutputPath>bin\Release\</OutputPath>
+ <DebugSymbols>False</DebugSymbols>
+ <DebugType>None</DebugType>
+ <Optimize>True</Optimize>
+ <CheckForOverflowUnderflow>False</CheckForOverflowUnderflow>
+ <DefineConstants>TRACE</DefineConstants>
+ </PropertyGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.Targets" />
+ <ItemGroup>
+ <Reference Include="System" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="BaseMessagingTestFixture.cs" />
+ <Compile Include="ChannelQueueTest.cs" />
+ <Compile Include="CommitRollbackTest.cs" />
+ <Compile Include="ConnectionTest.cs" />
+ <Compile Include="DurableSubscriptionTest.cs" />
+ <Compile Include="HeadersExchangeTest.cs" />
+ <Compile Include="MandatoryMessageTest.cs" />
+ <Compile Include="ProducerMultiConsumerTest.cs" />
+ <Compile Include="SslConnectionTest.cs" />
+ <Compile Include="QueueBrowsingTest.cs" />
+ </ItemGroup>
+</Project>
diff --git a/qpid/dotnet/Qpid.Integration.Tests/testcases/QueueBrowsingTest.cs b/qpid/dotnet/Qpid.Integration.Tests/testcases/QueueBrowsingTest.cs
new file mode 100644
index 0000000000..536439a44b
--- /dev/null
+++ b/qpid/dotnet/Qpid.Integration.Tests/testcases/QueueBrowsingTest.cs
@@ -0,0 +1,121 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+using System;
+using System.Threading;
+using log4net;
+using NUnit.Framework;
+using Apache.Qpid.Messaging;
+using Apache.Qpid.Client.Qms;
+using Apache.Qpid.Framing;
+
+namespace Apache.Qpid.Integration.Tests.testcases
+{
+ [TestFixture, Category("Integration")]
+ public class QueueBrowsingTest : BaseMessagingTestFixture
+ {
+ /// <summary>Used for debugging purposes.</summary>
+ private static ILog log = LogManager.GetLogger(typeof(QueueBrowsingTest));
+
+ public const string TEST_ROUTING_KEY = "queuebrowsingkey";
+ public const string TEST_ROUTING_KEY2 = "lvqbrowsingkey";
+
+
+ [SetUp]
+ public override void Init()
+ {
+ base.Init();
+ }
+
+ [TearDown]
+ public override void Shutdown()
+ {
+ base.Shutdown();
+ }
+
+ [Test]
+ public void TestQueueBrowsing()
+ {
+ // Create a topic with one producer and two consumers.
+ SetUpEndPoint(0, true, false, TEST_ROUTING_KEY + testId, AcknowledgeMode.AutoAcknowledge, false, ExchangeNameDefaults.DIRECT, true, true, null, false, false);
+ SetUpEndPoint(1, false, true, TEST_ROUTING_KEY + testId, AcknowledgeMode.NoAcknowledge, false, ExchangeNameDefaults.DIRECT, true, true, TEST_ROUTING_KEY + testId, false, true);
+ SetUpEndPoint(2, false, true, TEST_ROUTING_KEY + testId, AcknowledgeMode.NoAcknowledge, false, ExchangeNameDefaults.DIRECT, true, true, TEST_ROUTING_KEY + testId, false, true);
+
+ Thread.Sleep(500);
+
+ // Send messages and receive on both consumers.
+ testProducer[0].Send(testChannel[0].CreateTextMessage("msg"));
+ testProducer[0].Send(testChannel[0].CreateTextMessage("msg"));
+ testProducer[0].Send(testChannel[0].CreateTextMessage("msg"));
+ testProducer[0].Send(testChannel[0].CreateTextMessage("msg"));
+ testProducer[0].Send(testChannel[0].CreateTextMessage("msg"));
+ testProducer[0].Send(testChannel[0].CreateTextMessage("msg"));
+
+ Thread.Sleep(2000);
+
+
+ ConsumeNMessagesOnly(6, "msg", testConsumer[1]);
+ ConsumeNMessagesOnly(6, "msg", testConsumer[2]);
+
+ // Clean up any open consumers at the end of the test.
+ CloseEndPoint(2);
+ CloseEndPoint(1);
+ CloseEndPoint(0);
+ }
+
+ [Test]
+ public void TestQueueBrowsingLVQ()
+ {
+ // Create a topic with one producer and two consumers.
+ SetUpEndPoint(0, true, false, TEST_ROUTING_KEY2 + testId, AcknowledgeMode.AutoAcknowledge, false, ExchangeNameDefaults.DIRECT, true, true, TEST_ROUTING_KEY2 + testId, false, false);
+ FieldTable args = new FieldTable();
+ args.SetBoolean("qpid.last_value_queue", true);
+ args.SetString("qpid.last_value_queue_key", "key");
+ testChannel[0].DeclareQueue(TEST_ROUTING_KEY2 + testId, true, false, false, args);
+ testChannel[0].Bind(TEST_ROUTING_KEY2 + testId, ExchangeNameDefaults.DIRECT, TEST_ROUTING_KEY2 + testId);
+ Thread.Sleep(500);
+
+
+ for (int i = 0; i < 12; i++)
+ {
+ ITextMessage msg = testChannel[0].CreateTextMessage("msg");
+ msg.Headers.SetInt("key", i%6);
+ testProducer[0].Send(msg);
+ }
+
+ Thread.Sleep(2000);
+
+ SetUpEndPoint(1, false, true, TEST_ROUTING_KEY2 + testId, AcknowledgeMode.NoAcknowledge, false, ExchangeNameDefaults.DIRECT, true, true, TEST_ROUTING_KEY2 + testId, false, true);
+ SetUpEndPoint(2, false, true, TEST_ROUTING_KEY2 + testId, AcknowledgeMode.NoAcknowledge, false, ExchangeNameDefaults.DIRECT, true, true, TEST_ROUTING_KEY2 + testId, false, true);
+
+ Thread.Sleep(500);
+
+
+ ConsumeNMessagesOnly(6, "msg", testConsumer[1]);
+ ConsumeNMessagesOnly(6, "msg", testConsumer[2]);
+
+ // Clean up any open consumers at the end of the test.
+ CloseEndPoint(2);
+ CloseEndPoint(1);
+ CloseEndPoint(0);
+ }
+
+ }
+}
diff --git a/qpid/dotnet/Qpid.Integration.Tests/testcases/SslConnectionTest.cs b/qpid/dotnet/Qpid.Integration.Tests/testcases/SslConnectionTest.cs
new file mode 100644
index 0000000000..5f953e1470
--- /dev/null
+++ b/qpid/dotnet/Qpid.Integration.Tests/testcases/SslConnectionTest.cs
@@ -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.
+ *
+ */
+using System;
+using System.IO;
+using System.Reflection;
+using System.Security.Cryptography.X509Certificates;
+using NUnit.Framework;
+using Apache.Qpid.Client.Qms;
+using Apache.Qpid.Client;
+using Apache.Qpid.Messaging;
+
+namespace Apache.Qpid.Integration.Tests.testcases
+{
+ /// <summary>
+ /// Test SSL/TLS connections to the broker
+ /// </summary>
+ [TestFixture, Category("Integration")]
+ public class SslConnectionTest
+ {
+ /// <summary>
+ /// Make a test TLS connection to the broker
+ /// without using client-certificates
+ /// </summary>
+ //[Test]
+ public void DoSslConnection()
+ {
+ // because for tests we don't usually trust the server certificate
+ // we need here to tell the client to ignore certificate validation errors
+ SslOptions sslConfig = new SslOptions(null, true);
+
+ MakeBrokerConnection(sslConfig);
+ }
+
+ private static void MakeBrokerConnection(SslOptions options)
+ {
+ IConnectionInfo connectionInfo = new QpidConnectionInfo();
+ connectionInfo.VirtualHost = "test";
+ connectionInfo.AddBrokerInfo(new AmqBrokerInfo("amqp", "localhost", 8672, options));
+
+ using ( IConnection connection = new AMQConnection(connectionInfo) )
+ {
+ Console.WriteLine("connection = " + connection);
+ }
+ }
+ }
+}
diff --git a/qpid/dotnet/Qpid.Integration.Tests/testcases/SustainedTest.cs b/qpid/dotnet/Qpid.Integration.Tests/testcases/SustainedTest.cs
new file mode 100644
index 0000000000..4074055eba
--- /dev/null
+++ b/qpid/dotnet/Qpid.Integration.Tests/testcases/SustainedTest.cs
@@ -0,0 +1,109 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+using System;
+using System.IO;
+using System.Reflection;
+using System.Threading;
+using NUnit.Framework;
+using Apache.Qpid.Client.Qms;
+using Apache.Qpid.Client;
+using Apache.Qpid.Messaging;
+using log4net;
+
+namespace Apache.Qpid.Integration.Tests.testcases
+{
+ /// <summary>
+ /// Runs through the range of ack modes for each test case, sending and recieving a large number of messages
+ /// </summary>
+ [TestFixture, Category("Integration")]
+ public class SustainedTest : BaseMessagingTestFixture
+ {
+ /// <summary>The number of test messages to send.</summary>
+ private const int MESSAGE_COUNT = 50;//00;
+
+ /// <summary>Base name for the routing key used for this test (made unique by adding in test id).</summary>
+ private const string TEST_ROUTING_KEY = "MessageOrderTest";
+
+ /// <summary>
+ /// The logger
+ /// </summary>
+ private static ILog _logger = LogManager.GetLogger(typeof(SustainedTest));
+
+ [Test]
+ public void MessageOrderTestAutoAck()
+ {
+ MessageOrderTest(AcknowledgeMode.AutoAcknowledge);
+ }
+
+ [Test]
+ public void MessageOrderTestNoAck()
+ {
+ MessageOrderTest(AcknowledgeMode.NoAcknowledge);
+ }
+
+ public void MessageOrderTest(AcknowledgeMode consumerMode)
+ {
+
+ // Consumer
+ SetUpEndPoint(1, false, true, TEST_ROUTING_KEY, consumerMode, false, ExchangeNameDefaults.DIRECT,
+ true, false, null);
+
+
+ Console.WriteLine("Starting producer thread");
+ Thread prodThread = new Thread(new ThreadStart(SendMessages));
+ prodThread.Start();
+
+ Thread.Sleep(2000);
+ Console.WriteLine("Starting consuming");
+ for (int i = 0; i < MESSAGE_COUNT; i++)
+ {
+ if ((i % 10) == 0)
+ {
+ Console.WriteLine("Consuming message "+i);
+ }
+ ConsumeNMessages(1, "Msg"+i, testConsumer[1]);
+ }
+ prodThread.Join();
+ CloseEndPoint(0);
+ CloseEndPoint(1);
+ }
+
+ private static void SendMessages()
+ {
+ AMQConnection conn = new AMQConnection(QpidConnectionInfo.FromUrl(BaseMessagingTestFixture.connectionUri));
+ conn.Start();
+ IChannel channel = conn.CreateChannel(false, AcknowledgeMode.AutoAcknowledge);
+ IMessagePublisher producer = channel.CreatePublisherBuilder().
+ WithExchangeName(ExchangeNameDefaults.DIRECT).
+ WithRoutingKey(TEST_ROUTING_KEY).
+ Create();
+
+ for (int i = 0; i < MESSAGE_COUNT ; i++)
+ {
+ if ((i % 10) == 0)
+ {
+ Console.WriteLine("Sending message "+i);
+ }
+ producer.Send(channel.CreateTextMessage("Msg" + i));
+ }
+ }
+ }
+}
diff --git a/qpid/dotnet/Qpid.Messaging/AcknowledgeMode.cs b/qpid/dotnet/Qpid.Messaging/AcknowledgeMode.cs
new file mode 100644
index 0000000000..4896b64f68
--- /dev/null
+++ b/qpid/dotnet/Qpid.Messaging/AcknowledgeMode.cs
@@ -0,0 +1,42 @@
+/*
+ *
+ * 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.
+ *
+ */
+namespace Apache.Qpid.Messaging
+{
+ public enum AcknowledgeMode
+ {
+ AutoAcknowledge,
+ ClientAcknowledge,
+ DupsOkAcknowledge,
+ SessionTransacted,
+
+ /// <summary>
+ /// Indicates that no client acknowledgements are required. Broker assumes that once it has
+ /// delivered a message packet successfully it is acknowledged.
+ /// </summary>
+ NoAcknowledge,
+
+ /// <summary>
+ /// Pre acknowledge means that an ack is sent per message but sent before user code has processed
+ /// the message (i.e. before the onMessage() call or the receive() method has returned).
+ /// </summary>
+ PreAcknowledge
+ }
+}
diff --git a/qpid/dotnet/Qpid.Messaging/ChannelLimitReachedException.cs b/qpid/dotnet/Qpid.Messaging/ChannelLimitReachedException.cs
new file mode 100644
index 0000000000..8b43422f5c
--- /dev/null
+++ b/qpid/dotnet/Qpid.Messaging/ChannelLimitReachedException.cs
@@ -0,0 +1,60 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+using System;
+using System.Runtime.Serialization;
+
+namespace Apache.Qpid.Messaging
+{
+ [Serializable]
+ public class ChannelLimitReachedException : ResourceAllocationException
+ {
+ private long _limit;
+
+ public ChannelLimitReachedException(long limit)
+ : base("Unable to create session since maximum number of sessions per connection is " +
+ limit + ". Either close one or more sessions or increase the " +
+ "maximum number of sessions per connection (or contact your OpenAMQ administrator.")
+ {
+ _limit = limit;
+ }
+
+ protected ChannelLimitReachedException(SerializationInfo info, StreamingContext ctxt)
+ : base(info, ctxt)
+ {
+ _limit = info.GetInt64("Limit");
+ }
+
+ public long Limit
+ {
+ get
+ {
+ return _limit;
+ }
+ }
+
+ public override void GetObjectData(SerializationInfo info, StreamingContext context)
+ {
+ base.GetObjectData(info, context);
+ info.AddValue("Limit", _limit);
+ }
+ }
+}
diff --git a/qpid/dotnet/Qpid.Messaging/DeliveryMode.cs b/qpid/dotnet/Qpid.Messaging/DeliveryMode.cs
new file mode 100644
index 0000000000..3c4713ee2a
--- /dev/null
+++ b/qpid/dotnet/Qpid.Messaging/DeliveryMode.cs
@@ -0,0 +1,28 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+namespace Apache.Qpid.Messaging
+{
+ public enum DeliveryMode
+ {
+ NonPersistent,
+ Persistent
+ }
+}
diff --git a/qpid/dotnet/Qpid.Messaging/ExchangeClassConstants.cs b/qpid/dotnet/Qpid.Messaging/ExchangeClassConstants.cs
new file mode 100644
index 0000000000..984e8b0f17
--- /dev/null
+++ b/qpid/dotnet/Qpid.Messaging/ExchangeClassConstants.cs
@@ -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.
+ *
+ */
+namespace Apache.Qpid.Messaging
+{
+ public class ExchangeClassConstants
+ {
+ public readonly static string TOPIC = "topic";
+ public readonly static string DIRECT = "direct";
+ public readonly static string HEADERS = "headers";
+ }
+}
diff --git a/qpid/dotnet/Qpid.Messaging/ExchangeNameDefaults.cs b/qpid/dotnet/Qpid.Messaging/ExchangeNameDefaults.cs
new file mode 100644
index 0000000000..2689fb5e46
--- /dev/null
+++ b/qpid/dotnet/Qpid.Messaging/ExchangeNameDefaults.cs
@@ -0,0 +1,42 @@
+/*
+ *
+ * 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.
+ *
+ */
+namespace Apache.Qpid.Messaging
+{
+ public class ExchangeNameDefaults
+ {
+ public readonly static string TOPIC = "amq.topic";
+ public readonly static string DIRECT = "amq.direct";
+ public readonly static string HEADERS = "amq.match";
+ public readonly static string FANOUT = "amq.fanout";
+
+ /// <summary> Defines the identifying type name of topic exchanges. </summary>
+ public readonly static string TOPIC_EXCHANGE_CLASS = "topic";
+
+ /// <summary> Defines the identifying type name of direct exchanges. </summary>
+ public readonly static string DIRECT_EXCHANGE_CLASS = "direct";
+
+ /// <summary> Defines the identifying type name of headers exchanges. </summary>
+ public readonly static string HEADERS_EXCHANGE_CLASS = "headers";
+
+ /// <summary> Defines the identifying type name of fanout exchanges. </summary>
+ public readonly static string FANOUT_EXCHANGE_CLASS = "fanout";
+ }
+}
diff --git a/qpid/dotnet/Qpid.Messaging/IBytesMessage.cs b/qpid/dotnet/Qpid.Messaging/IBytesMessage.cs
new file mode 100644
index 0000000000..5be942423d
--- /dev/null
+++ b/qpid/dotnet/Qpid.Messaging/IBytesMessage.cs
@@ -0,0 +1,63 @@
+/*
+ *
+ * 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.
+ *
+ */
+namespace Apache.Qpid.Messaging
+{
+ public interface IBytesMessage : IMessage
+ {
+ long BodyLength { get; }
+
+ bool ReadBoolean();
+ void WriteBoolean(bool value);
+
+ byte ReadByte();
+ int ReadBytes(byte[] array);
+ int ReadBytes(byte[] array, int length);
+ void WriteByte(byte value);
+ void WriteBytes(byte[] value);
+ void WriteBytes(byte[] value, int offset, int length);
+
+ char ReadChar();
+ void WriteChar(char value);
+
+ double ReadDouble();
+ void WriteDouble(double value);
+
+ float ReadFloat();
+ void WriteFloat(float value);
+
+ int ReadInt();
+ void WriteInt(int value);
+
+ long ReadLong();
+ void WriteLong(long value);
+
+ short ReadShort();
+ void WriteShort(short value);
+
+ short ReadSignedByte();
+ void WriteSignedByte(short value);
+
+ string ReadUTF();
+ void WriteUTF(string value);
+
+ void Reset();
+ }
+}
diff --git a/qpid/dotnet/Qpid.Messaging/IChannel.cs b/qpid/dotnet/Qpid.Messaging/IChannel.cs
new file mode 100644
index 0000000000..1db8b5fbdb
--- /dev/null
+++ b/qpid/dotnet/Qpid.Messaging/IChannel.cs
@@ -0,0 +1,280 @@
+/*
+ *
+ * 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.
+ *
+ */
+using System;
+
+namespace Apache.Qpid.Messaging
+{
+ public delegate void MessageReceivedDelegate(IMessage msg);
+
+ /// <summary>
+ /// IChannel provides methods to access the commands in AMQP that operate at the channel level. This can be summarized as
+ /// the ability to declare queues and exchanges, bind queues to exchanges, create messages of various types, declare transaction
+ /// boundaries (commit and rollback), and to set up producers and consumers on the channel.
+ ///
+ /// <p/>You can create a channel by using the CreateChannel() method
+ /// of the connection object.
+ ///
+ /// <p/><table id="crc"><caption>CRC Card</caption>
+ /// <tr><th> Responsibilities
+ /// <tr><td> Declare queues.
+ /// <tr><td> Declare exchanges.
+ /// <tr><td> Bind queues to exchanges.
+ /// <tr><td> Create messages.
+ /// <tr><td> Set up message consumers on the channel.
+ /// <tr><td> Set up message producers on the channel.
+ /// <tr><td> Commit the current transaction.
+ /// <tr><td> Roll-back the current transaction.
+ /// <tr><td> Close the channel.
+ /// </table>
+ /// </summary>
+ public interface IChannel : IDisposable, ICloseable
+ {
+ /// <summary>
+ /// Acknowledge mode for messages received.
+ /// </summary>
+ AcknowledgeMode AcknowledgeMode { get; }
+
+ /// <summary>
+ /// True if the channel should use transactions.
+ /// </summary>
+ bool Transacted { get; }
+
+ /// <summary>
+ /// Prefetch value to be used as the default for
+ /// consumers created on this channel.
+ /// </summary>
+ int DefaultPrefetch { get; }
+
+ /// <summary>
+ /// Prefetch low value to be used as the default for
+ /// consumers created on this channel.
+ /// </summary>
+ int DefaultPrefetchLow { get; }
+
+ /// <summary>
+ /// Prefetch high value to be used as the default for
+ /// consumers created on this channel.
+ /// </summary>
+ int DefaultPrefetchHigh { get; }
+
+ /// <summary>
+ /// Declare a new exchange.
+ /// </summary>
+ /// <param name="exchangeName">Name of the exchange</param>
+ /// <param name="exchangeClass">Class of the exchange, from <see cref="ExchangeClassConstants"/></param>
+ void DeclareExchange(string exchangeName, string exchangeClass);
+
+ /// <summary>
+ /// Declare a new exchange using the default exchange class.
+ /// </summary>
+ /// <param name="exchangeName">Name of the exchange</param>
+ void DeleteExchange(string exchangeName);
+
+ /// <summary>
+ /// Declare a new queue with the specified set of arguments.
+ /// </summary>
+ /// <param name="queueName">Name of the queue</param>
+ /// <param name="isDurable">True if the queue should be durable</param>
+ /// <param name="isExclusive">True if the queue should be exclusive to this channel</param>
+ /// <param name="isAutoDelete">True if the queue should be deleted when the channel closes</param>
+ void DeclareQueue(string queueName, bool isDurable, bool isExclusive, bool isAutoDelete);
+
+
+ /// <summary>
+ /// Declare a new queue with the specified set of arguments.
+ /// </summary>
+ /// <param name="queueName">Name of the queue</param>
+ /// <param name="isDurable">True if the queue should be durable</param>
+ /// <param name="isExclusive">True if the queue should be exclusive to this channel</param>
+ /// <param name="isAutoDelete">True if the queue should be deleted when the channel closes</param>
+ /// <param name="args">Optional arguments to Queue.Declare</param>
+ void DeclareQueue(string queueName, bool isDurable, bool isExclusive, bool isAutoDelete, IFieldTable args);
+
+ /// <summary>
+ /// Delete a queue with the specifies arguments.
+ /// </summary>
+ /// <param name="queueName">Name of the queue to delete</param>
+ /// <param name="ifUnused">If true, the queue will not deleted if it has no consumers</param>
+ /// <param name="ifEmpty">If true, the queue will not deleted if it has no messages</param>
+ /// <param name="noWait">If true, the server will not respond to the method</param>
+ void DeleteQueue(string queueName, bool ifUnused, bool ifEmpty, bool noWait);
+
+ /// <summary>
+ /// Generate a new Unique name to use for a queue.
+ /// </summary>
+ /// <returns>A unique name to this channel</returns>
+ string GenerateUniqueName();
+
+ /// <summary>
+ /// Removes all messages from a queue.
+ /// </summary>
+ /// <param name="queueName">Name of the queue to delete</param>
+ /// <param name="noWait">If true, the server will not respond to the method</param>
+ void PurgeQueue(string queueName, bool noWait);
+
+ /// <summary>
+ /// Bind a queue to the specified exchange.
+ /// </summary>
+ /// <param name="queueName">Name of queue to bind</param>
+ /// <param name="exchangeName">Name of exchange to bind to</param>
+ /// <param name="routingKey">Routing key</param>
+ void Bind(string queueName, string exchangeName, string routingKey);
+
+ /// <summary>
+ /// Bind a queue to the specified exchange.
+ /// </summary>
+ /// <param name="queueName">Name of queue to bind</param>
+ /// <param name="exchangeName">Name of exchange to bind to</param>
+ /// <param name="routingKey">Routing key</param>
+ /// <param name="args">Table of arguments for the binding. Used to bind with a Headers Exchange</param>
+ void Bind(string queueName, string exchangeName, string routingKey, IFieldTable args);
+
+ /// <summary>
+ /// Create a new empty message with no body.
+ /// </summary>
+ /// <returns>The new message</returns>
+ IMessage CreateMessage();
+
+ /// <summary>
+ /// Create a new message of the specified MIME type.
+ /// </summary>
+ /// <param name="mimeType">The mime type to create</param>
+ /// <returns>The new message</returns>
+ IMessage CreateMessage(string mimeType);
+
+ /// <summary>
+ /// Creates a new message for bytes (application/octet-stream).
+ /// </summary>
+ /// <returns>The new message</returns>
+ IBytesMessage CreateBytesMessage();
+
+ /// <summary>
+ /// Creates a new text message (text/plain) with empty content.
+ /// </summary>
+ /// <returns>The new message</returns>
+ ITextMessage CreateTextMessage();
+
+ /// <summary>
+ /// Creates a new text message (text/plain) with a body.
+ /// </summary>
+ /// <param name="initialValue">Initial body of the message</param>
+ /// <returns>The new message</returns>
+ ITextMessage CreateTextMessage(string initialValue);
+
+ #region Consuming
+
+ /// <summary>
+ /// Creates a new Consumer using the builder pattern.
+ /// </summary>
+ /// <param name="queueName">Name of queue to receive messages from</param>
+ /// <returns>The builder object</returns>
+ MessageConsumerBuilder CreateConsumerBuilder(string queueName);
+
+ /// <summary>
+ /// Creates a new consumer.
+ /// </summary>
+ /// <param name="queueName">Name of queue to receive messages from</param>
+ /// <param name="prefetchLow">Low prefetch value</param>
+ /// <param name="prefetchHigh">High prefetch value</param>
+ /// <param name="noLocal">If true, messages sent on this channel will not be received by this consumer</param>
+ /// <param name="exclusive">If true, the consumer opens the queue in exclusive mode</param>
+ /// <returns>The new consumer</returns>
+ IMessageConsumer CreateConsumer(string queueName,
+ int prefetchLow,
+ int prefetchHigh,
+ bool noLocal,
+ bool exclusive);
+
+ /// <summary>
+ /// Creates a new consumer.
+ /// </summary>
+ /// <param name="queueName">Name of queue to receive messages from</param>
+ /// <param name="prefetchLow">Low prefetch value</param>
+ /// <param name="prefetchHigh">High prefetch value</param>
+ /// <param name="noLocal">If true, messages sent on this channel will not be received by this consumer</param>
+ /// <param name="exclusive">If true, the consumer opens the queue in exclusive mode</param>
+ /// <param name="browse">If true, the consumer only browses and does not consume</param>
+ /// <returns>The new consumer</returns>
+ IMessageConsumer CreateConsumer(string queueName,
+ int prefetchLow,
+ int prefetchHigh,
+ bool noLocal,
+ bool exclusive,
+ bool browse);
+
+ /// <summary>
+ /// Unsubscribe from a queue.
+ /// </summary>
+ /// <param name="subscriptionName">Subscription name</param>
+ void Unsubscribe(string subscriptionName);
+
+ #endregion
+
+ #region Publishing
+
+ /// <summary>
+ /// Create a new message publisher using the builder pattern.
+ /// </summary>
+ /// <returns>The builder object</returns>
+ MessagePublisherBuilder CreatePublisherBuilder();
+
+ /// <summary>
+ /// Create a new message publisher.
+ /// </summary>
+ /// <param name="exchangeName">Name of exchange to publish to</param>
+ /// <param name="routingKey">Routing key</param>
+ /// <param name="deliveryMode">Default delivery mode</param>
+ /// <param name="timeToLive">Default TTL time of messages</param>
+ /// <param name="immediate">If true, sent immediately</param>
+ /// <param name="mandatory">If true, the broker will return an error
+ /// (as a connection exception) if the message cannot be delivered</param>
+ /// <param name="priority">Default message priority</param>
+ /// <returns>The new message publisher</returns>
+ IMessagePublisher CreatePublisher(string exchangeName,
+ string routingKey,
+ DeliveryMode deliveryMode,
+ long timeToLive,
+ bool immediate,
+ bool mandatory,
+ int priority);
+
+ #endregion
+
+ #region Transactions
+
+ /// <summary>
+ /// Recover after transaction failure.
+ /// </summary>
+ void Recover();
+
+ /// <summary>
+ /// Commit the transaction.
+ /// </summary>
+ void Commit();
+
+ /// <summary>
+ /// Rollback the transaction.
+ /// </summary>
+ void Rollback();
+
+ #endregion
+ }
+}
diff --git a/qpid/dotnet/Qpid.Messaging/ICloseable.cs b/qpid/dotnet/Qpid.Messaging/ICloseable.cs
new file mode 100644
index 0000000000..658a5ed5a4
--- /dev/null
+++ b/qpid/dotnet/Qpid.Messaging/ICloseable.cs
@@ -0,0 +1,38 @@
+/*
+ *
+ * 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.
+ *
+ */
+using System;
+
+namespace Apache.Qpid.Messaging
+{
+ /// <summary>An ICloseable is a resource that can be explicitly closed. Generally speaking a closed resource can no longer be used, and the
+ /// act of closing a resource is usually interpreted as a signal that the closed item can have its resource cleaned up and de-allocated.
+ ///
+ /// <p/><table id="crc"><caption>CRC Card</caption>
+ /// <tr><th> Responsibilities <th> Collaborations
+ /// <tr><td> Close (and clean-up) a resource.
+ /// </table>
+ /// </summary>
+ public interface ICloseable
+ {
+ /// <summary> Close the resource. </summary>
+ void Close();
+ }
+}
diff --git a/qpid/dotnet/Qpid.Messaging/IConnection.cs b/qpid/dotnet/Qpid.Messaging/IConnection.cs
new file mode 100644
index 0000000000..f664137e02
--- /dev/null
+++ b/qpid/dotnet/Qpid.Messaging/IConnection.cs
@@ -0,0 +1,55 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+using System;
+
+namespace Apache.Qpid.Messaging
+{
+ public delegate void ExceptionListenerDelegate(Exception ex);
+
+ public interface IConnection : IDisposable, ICloseable
+ {
+ /// <summary>
+ /// The connection listener that has been registered with this connection.
+ /// </summary>
+ IConnectionListener ConnectionListener
+ {
+ get;
+ set;
+ }
+
+ ExceptionListenerDelegate ExceptionListener { get; set; }
+
+ string ClientID { get; set; }
+
+ /// <return>the maximum number of sessions supported by this Connection</return>
+ int MaximumChannelCount
+ {
+ get;
+ }
+
+ IChannel CreateChannel(bool transacted, AcknowledgeMode acknowledgeMode);
+ IChannel CreateChannel(bool transacted, AcknowledgeMode acknowledgeMode, int prefetch);
+ IChannel CreateChannel(bool transacted, AcknowledgeMode acknowledgeMode, int prefetchHigh, int prefetchLow);
+
+ void Start();
+ void Stop();
+ }
+}
diff --git a/qpid/dotnet/Qpid.Messaging/IConnectionFactory.cs b/qpid/dotnet/Qpid.Messaging/IConnectionFactory.cs
new file mode 100644
index 0000000000..f141d509be
--- /dev/null
+++ b/qpid/dotnet/Qpid.Messaging/IConnectionFactory.cs
@@ -0,0 +1,28 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+namespace Apache.Qpid.Messaging
+{
+ public interface IConnectionFactory
+ {
+ IConnection CreateConnection();
+ IConnection CreateConnection(string userId, string password);
+ }
+}
diff --git a/qpid/dotnet/Qpid.Messaging/IConnectionListener.cs b/qpid/dotnet/Qpid.Messaging/IConnectionListener.cs
new file mode 100644
index 0000000000..02d9eb38da
--- /dev/null
+++ b/qpid/dotnet/Qpid.Messaging/IConnectionListener.cs
@@ -0,0 +1,59 @@
+/*
+ *
+ * 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.
+ *
+ */
+namespace Apache.Qpid.Messaging
+{
+ public interface IConnectionListener
+ {
+ /// <summary>
+ /// Called when bytes have been transmitted to the server
+ /// </summary>
+ /// <param>count the number of bytes sent in total since the connection was opened</param>
+ void BytesSent(long count);
+
+ /// <summary>
+ /// Called when some bytes have been received on a connection
+ /// </summary>
+ /// <param>count the number of bytes received in total since the connection was opened</param>
+ void BytesReceived(long count);
+
+ /// <summary>
+ /// Called after the infrastructure has detected that failover is required but before attempting failover.
+ /// </summary>
+ /// <param>redirect true if the broker requested redirect. false if failover is occurring due to a connection error.</param>
+ /// <return>true to continue failing over, false to veto failover and raise a connection exception</return>
+ bool PreFailover(bool redirect);
+
+ /// <summary>
+ /// Called after connection has been made to another broker after failover has been started but before
+ /// any resubscription has been done.
+ /// <return> true to continue with resubscription, false to prevent automatic resubscription. This is useful in
+ /// cases where the application wants to handle resubscription. Note that in the latter case all sessions, producers
+ /// and consumers are invalidated.
+ /// </return
+ bool PreResubscribe();
+
+ /// <summary>
+ /// Called once failover has completed successfully. This is called irrespective of whether the client has
+ /// vetoed automatic resubscription.
+ /// </summary>
+ void FailoverComplete();
+ }
+}
diff --git a/qpid/dotnet/Qpid.Messaging/IFieldTable.cs b/qpid/dotnet/Qpid.Messaging/IFieldTable.cs
new file mode 100644
index 0000000000..730ce399d4
--- /dev/null
+++ b/qpid/dotnet/Qpid.Messaging/IFieldTable.cs
@@ -0,0 +1,42 @@
+/*
+ *
+ * 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.
+ *
+ */
+using System.Collections;
+
+namespace Apache.Qpid.Messaging
+{
+ public interface IFieldTable : IEnumerable
+ {
+ int Count { get; }
+
+ object this[string key] { get; set; }
+
+ /// <summary>
+ /// Adds all the items from another field table in this one.
+ /// Will overwrite any items in the current table with the same key.
+ /// </summary>
+ /// <param name="source">the source field table</param>
+ void AddAll(IFieldTable source);
+
+ bool Contains(string s);
+ void Clear();
+ void Remove(string key);
+ }
+}
diff --git a/qpid/dotnet/Qpid.Messaging/IHeaders.cs b/qpid/dotnet/Qpid.Messaging/IHeaders.cs
new file mode 100644
index 0000000000..7fdf26ebda
--- /dev/null
+++ b/qpid/dotnet/Qpid.Messaging/IHeaders.cs
@@ -0,0 +1,67 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+namespace Apache.Qpid.Messaging
+{
+ /// <summary>
+ /// IHeaders represents the header fields of an AMQ message and provides methods to access those fields. There are accessor methods to
+ /// get and set each header field for each supported header field data type.
+ ///
+ /// <para/><table id="crc"><caption>CRC Card</caption>
+ /// <tr><th>Responsibilities</th></tr>
+ /// <tr><td>Provide accessors for all supported header field types.</td></tr>
+ /// <tr><td>Check if a set of headers contains a named property.</td></tr>
+ /// </table>
+ ///
+ /// </summary>
+ public interface IHeaders
+ {
+ bool Contains(string name);
+
+ object this[string name] { get; set; }
+
+ bool GetBoolean(string name);
+ void SetBoolean(string name, bool value);
+
+ byte GetByte(string name);
+ void SetByte(string name, byte value);
+
+ //sbyte GetSByte(string name);
+ //void SetSByte(string name, sbyte value);
+
+ short GetShort(string name);
+ void SetShort(string name, short value);
+
+ int GetInt(string name);
+ void SetInt(string name, int value);
+
+ long GetLong(string name);
+ void SetLong(string name, long value);
+
+ float GetFloat(string name);
+ void SetFloat(string name, float value);
+
+ double GetDouble(string name);
+ void SetDouble(string name, double value);
+
+ string GetString(string name);
+ void SetString(string name, string value);
+ }
+}
diff --git a/qpid/dotnet/Qpid.Messaging/IMessage.cs b/qpid/dotnet/Qpid.Messaging/IMessage.cs
new file mode 100644
index 0000000000..20ae5ee130
--- /dev/null
+++ b/qpid/dotnet/Qpid.Messaging/IMessage.cs
@@ -0,0 +1,97 @@
+/*
+ *
+ * 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.
+ *
+ */
+namespace Apache.Qpid.Messaging
+{
+ public interface IMessage
+ {
+ /// <summary>
+ /// The MIME Content Type
+ /// </summary>
+ string ContentType { get; set;}
+ /// <summary>
+ /// The MIME Content Encoding
+ /// </summary>
+ string ContentEncoding { get; set; }
+ /// <summary>
+ /// The application correlation identifier
+ /// </summary>
+ string CorrelationId { get; set; }
+ /// <summary>
+ /// The application correlation identifier, as an array of bytes
+ /// </summary>
+ byte[] CorrelationIdAsBytes { get; set; }
+ /// <summary>
+ /// Non-persistent (1) or persistent (2)
+ /// </summary>
+ DeliveryMode DeliveryMode { get; set; }
+ /// <summary>
+ /// Message expiration specification
+ /// </summary>
+ long Expiration { get; set; }
+ /// <summary>
+ /// The application message identifier
+ /// </summary>
+ string MessageId { get; set; }
+ /// <summary>
+ /// The message priority, 0 to 9
+ /// </summary>
+ byte Priority { get; set; }
+ /// <summary>
+ /// True if the message has been redelivered
+ /// </summary>
+ bool Redelivered { get; set; }
+ /// <summary>
+ /// Exchange name of the reply-to address
+ /// </summary>
+ string ReplyToExchangeName { get; set; }
+ /// <summary>
+ /// Routing key of the reply-to address
+ /// </summary>
+ string ReplyToRoutingKey { get; set; }
+ /// <summary>
+ /// The message timestamp
+ /// </summary>
+ long Timestamp { get; set; }
+ /// <summary>
+ /// The message type name
+ /// </summary>
+ string Type { get; set; }
+ /// <summary>
+ /// Message headers
+ /// </summary>
+ IHeaders Headers { get; }
+ /// <summary>
+ /// The creating user id
+ /// </summary>
+ string UserId { get; set; }
+ /// <summary>
+ /// The creating application id
+ /// </summary>
+ string AppId { get; set; }
+ /// <summary>
+ /// Intra-cluster routing identifier
+ /// </summary>
+ string ClusterId { get; set; }
+
+ void Acknowledge();
+ void ClearBody();
+ }
+}
diff --git a/qpid/dotnet/Qpid.Messaging/IMessageConsumer.cs b/qpid/dotnet/Qpid.Messaging/IMessageConsumer.cs
new file mode 100644
index 0000000000..86b5405707
--- /dev/null
+++ b/qpid/dotnet/Qpid.Messaging/IMessageConsumer.cs
@@ -0,0 +1,79 @@
+/*
+ *
+ * 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.
+ *
+ */
+using System;
+
+namespace Apache.Qpid.Messaging
+{
+ /// <summary>
+ /// Describes an object that can be used to receive (consume)
+ /// messages from an AMQP queue.
+ /// </summary>
+ /// <remarks>
+ /// Consumers are created using either
+ /// <see cref="IChannel.CreateConsumer"/> or using
+ /// the builder pattern (preferred) with
+ /// <see cref="IChannel.CreateConsumerBuilder"/>.
+ ///
+ /// <para>
+ /// Consumers offer two different ways of receiving messages:
+ /// You can attach a delegate to the <see cref="OnMessage"/>
+ /// event and be notified when a message arrives, or you can
+ /// use the <see cref="Receive"/> and <see cref="ReceiveNoWait"/>
+ /// methods to control when you receive messages. Be aware that you can use
+ /// one or the other, but not both at the same time.
+ /// </para>
+ /// <para>
+ /// Regardless of which method you choose, the prefetch settings
+ /// specified when creating the channel will still control when messages
+ /// are actually received from the AMQP broker. Any messages that arrive
+ /// between the prefetch window will be queued by the channel
+ /// until they can be delivered to the consumer (either though the event
+ /// or until the consumer actively calls <see cref="Receive"/>).
+ /// </para>
+ /// </remarks>
+ public interface IMessageConsumer : IDisposable, ICloseable
+ {
+ /// <summary>
+ /// Fired when a message is received from the broker by the consumer
+ /// </summary>
+ MessageReceivedDelegate OnMessage { get; set; }
+
+ /// <summary>
+ /// Wait infinitely for a message to be received from the broker
+ /// </summary>
+ /// <returns>The message received</returns>
+ IMessage Receive();
+
+ /// <summary>
+ /// Wait the specified time until a message is receive from the broker
+ /// </summary>
+ /// <param name="delay">Maximum number of milliseconds to wait for a message</param>
+ /// <returns>The message received, or null if the timeout expires</returns>
+ IMessage Receive(long delay);
+
+ /// <summary>
+ /// Return a message if one is already available in the channel.
+ /// Does not wait for one to be received from the broker.
+ /// </summary>
+ /// <returns>The message, if it was available, otherwise null</returns>
+ IMessage ReceiveNoWait();
+ }
+}
diff --git a/qpid/dotnet/Qpid.Messaging/IMessagePublisher.cs b/qpid/dotnet/Qpid.Messaging/IMessagePublisher.cs
new file mode 100644
index 0000000000..d895a9749b
--- /dev/null
+++ b/qpid/dotnet/Qpid.Messaging/IMessagePublisher.cs
@@ -0,0 +1,92 @@
+/*
+ *
+ * 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.
+ *
+ */
+using System;
+
+namespace Apache.Qpid.Messaging
+{
+ /// <summary>
+ /// Defines an object capable of publishing messages
+ /// to an AMQP broker.
+ /// </summary>
+ /// <remarks>
+ /// A publisher can be created using either
+ /// <see cref="IChannel.CreatePublisher"/> or
+ /// using the builder pattern (preferred) with
+ /// <see cref="IChannel.CreatePublisherBuilder"/>
+ /// </remarks>
+ public interface IMessagePublisher : IDisposable, ICloseable
+ {
+ /// <summary>
+ /// Default delivery mode to use with this publisher
+ /// </summary>
+ DeliveryMode DeliveryMode { get; set; }
+ /// <summary>
+ /// Name of exchange messages are published to
+ /// </summary>
+ string ExchangeName { get; }
+ /// <summary>
+ /// Routing key used when publishing messages
+ /// </summary>
+ string RoutingKey { get; }
+ /// <summary>
+ /// If true, a message ID will not be generated by the publisher
+ /// when sending the message
+ /// </summary>
+ bool DisableMessageID { get; set; }
+ /// <summary>
+ /// If true, no timestamp will be added to the message
+ /// when publishing it
+ /// </summary>
+ bool DisableMessageTimestamp { get; set; }
+ /// <summary>
+ /// Default priority used when publishing messages
+ /// </summary>
+ int Priority { get; set; }
+ /// <summary>
+ /// Default time to live used when publishing messages
+ /// </summary>
+ long TimeToLive { get; set; }
+ /// <summary>
+ /// Set the default MIME type for messages produced by this producer.
+ /// This reduces the overhead of each message.
+ /// </summary>
+ string MimeType { get; set; }
+ /// <summary>
+ /// Set the default encoding for messages produced by this producer.
+ /// This reduces the overhead of each message.
+ /// </summary>
+ string Encoding { get; set; }
+
+ /// <summary>
+ /// Publish a message, using any default values configured
+ /// </summary>
+ /// <param name="msg">Message to publish</param>
+ void Send(IMessage msg);
+ /// <summary>
+ /// Publish a message with the specified options
+ /// </summary>
+ /// <param name="msg">Message to publish</param>
+ /// <param name="deliveryMode">Delivery mode to use</param>
+ /// <param name="priority">Priority of the message</param>
+ /// <param name="timeToLive">Time to live of the message</param>
+ void Send(IMessage msg, DeliveryMode deliveryMode, int priority, long timeToLive);
+ }
+}
diff --git a/qpid/dotnet/Qpid.Messaging/ITextMessage.cs b/qpid/dotnet/Qpid.Messaging/ITextMessage.cs
new file mode 100644
index 0000000000..902beb70f8
--- /dev/null
+++ b/qpid/dotnet/Qpid.Messaging/ITextMessage.cs
@@ -0,0 +1,27 @@
+/*
+ *
+ * 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.
+ *
+ */
+namespace Apache.Qpid.Messaging
+{
+ public interface ITextMessage : IMessage
+ {
+ string Text { get; set; }
+ }
+}
diff --git a/qpid/dotnet/Qpid.Messaging/MessageConsumerBuilder.cs b/qpid/dotnet/Qpid.Messaging/MessageConsumerBuilder.cs
new file mode 100644
index 0000000000..91a2371788
--- /dev/null
+++ b/qpid/dotnet/Qpid.Messaging/MessageConsumerBuilder.cs
@@ -0,0 +1,113 @@
+/*
+ *
+ * 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.
+ *
+ */
+namespace Apache.Qpid.Messaging
+{
+ /// <summary>
+ /// MessageConsumerBuilder provides a builder with a fluent interface to assist with creating message consumers on a channel.
+ ///
+ /// <p/><table id="crc"><caption>CRC Card</caption>
+ /// <tr><th> Responsibilities <th> Collaborations
+ /// <tr><td> Create message consumers from consume parameters. <td> <see cref="IChannel">
+ /// </table>
+ /// </summary>
+ ///
+ /// <remarks>It may be better to replace the Create method with a DeclareBindAndCreate method, that declares and binds the consumers queue,
+ /// as well as creating the consumer. This is a common use case, so the method will generally be usefull. Need to consider situations where
+ /// the declare and bind is not to be done, for example when resubscribing to a durable subscription. There may be others too.</remarks>
+ public class MessageConsumerBuilder
+ {
+ private bool _noLocal = false;
+
+ private bool _exclusive = false;
+
+ private bool _browse = false;
+
+ //private bool _durable = false;
+ //private string _subscriptionName = null;
+
+ private IChannel _channel;
+
+ private readonly string _queueName;
+
+ private int _prefetchLow;
+
+ private int _prefetchHigh;
+
+ public MessageConsumerBuilder(IChannel channel, string queueName)
+ {
+ _channel = channel;
+ _queueName = queueName;
+ _prefetchHigh = _channel.DefaultPrefetchHigh;
+ _prefetchLow = _channel.DefaultPrefetchLow;
+ }
+
+ public MessageConsumerBuilder WithPrefetchLow(int prefetchLow)
+ {
+ _prefetchLow = prefetchLow;
+ return this;
+ }
+
+ public MessageConsumerBuilder WithPrefetchHigh(int prefetchHigh)
+ {
+ _prefetchHigh = prefetchHigh;
+ return this;
+ }
+
+ public MessageConsumerBuilder WithNoLocal(bool noLocal)
+ {
+ _noLocal = noLocal;
+ return this;
+ }
+
+ public MessageConsumerBuilder WithExclusive(bool exclusive)
+ {
+ _exclusive = exclusive;
+ return this;
+ }
+
+ public MessageConsumerBuilder WithBrowse(bool browse)
+ {
+ _browse = browse;
+ return this;
+ }
+
+ /*
+ public MessageConsumerBuilder WithDurable(bool durable)
+ {
+ _durable = durable;
+ return this;
+ }
+ */
+
+ /*
+ public MessageConsumerBuilder WithSubscriptionName(string subscriptionName)
+ {
+ _subscriptionName = subscriptionName;
+ return this;
+ }
+ */
+
+ public IMessageConsumer Create()
+ {
+ return _channel.CreateConsumer(_queueName, _prefetchLow, _prefetchHigh, _noLocal, _exclusive, _browse);
+ }
+ }
+}
diff --git a/qpid/dotnet/Qpid.Messaging/MessageNotReadableException.cs b/qpid/dotnet/Qpid.Messaging/MessageNotReadableException.cs
new file mode 100644
index 0000000000..2afcffd531
--- /dev/null
+++ b/qpid/dotnet/Qpid.Messaging/MessageNotReadableException.cs
@@ -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.
+ *
+ */
+
+using System;
+using System.Runtime.Serialization;
+
+namespace Apache.Qpid.Messaging
+{
+ [Serializable]
+ public class MessageNotReadableException : QpidException
+ {
+ public MessageNotReadableException(string reason) : base(reason)
+ {
+ }
+
+ protected MessageNotReadableException(SerializationInfo info, StreamingContext ctxt)
+ : base(info, ctxt)
+ {
+ }
+ }
+}
diff --git a/qpid/dotnet/Qpid.Messaging/MessageNotWritableException.cs b/qpid/dotnet/Qpid.Messaging/MessageNotWritableException.cs
new file mode 100644
index 0000000000..9b00f01948
--- /dev/null
+++ b/qpid/dotnet/Qpid.Messaging/MessageNotWritableException.cs
@@ -0,0 +1,38 @@
+/*
+ *
+ * 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.
+ *
+ */
+using System;
+using System.Runtime.Serialization;
+
+namespace Apache.Qpid.Messaging
+{
+ [Serializable]
+ public class MessageNotWriteableException : QpidException
+ {
+ public MessageNotWriteableException(string reason) : base(reason)
+ {
+ }
+
+ protected MessageNotWriteableException(SerializationInfo info, StreamingContext ctxt)
+ : base(info, ctxt)
+ {
+ }
+ }
+}
diff --git a/qpid/dotnet/Qpid.Messaging/MessagePublisherBuilder.cs b/qpid/dotnet/Qpid.Messaging/MessagePublisherBuilder.cs
new file mode 100644
index 0000000000..79c7575d0a
--- /dev/null
+++ b/qpid/dotnet/Qpid.Messaging/MessagePublisherBuilder.cs
@@ -0,0 +1,91 @@
+/*
+ *
+ * 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.
+ *
+ */
+namespace Apache.Qpid.Messaging
+{
+ public class MessagePublisherBuilder
+ {
+ /// <summary>
+ /// Default value for immediate flag is false, i.e. a consumer does not need to be attached to a queue
+ /// </summary>
+ const bool DEFAULT_IMMEDIATE = false;
+
+ /// <summary>
+ /// Default value for mandatory flag is true, i.e. server will not silently drop messages where no queue is
+ /// connected to the exchange for the message
+ /// </summary>
+ const bool DEFAULT_MANDATORY = true;
+
+ IChannel _channel;
+ string _exchangeName = null;
+ string _routingKey = null;
+ DeliveryMode _deliveryMode = DeliveryMode.Persistent;
+ long _timeToLive;
+ bool _immediate = DEFAULT_IMMEDIATE;
+ bool _mandatory = DEFAULT_MANDATORY;
+ int _priority = 0;
+
+ public MessagePublisherBuilder(IChannel channel)
+ {
+ _channel = channel;
+ }
+
+ public MessagePublisherBuilder WithRoutingKey(string routingKey)
+ {
+ _routingKey = routingKey;
+ return this;
+ }
+
+ public MessagePublisherBuilder WithExchangeName(string exchangeName)
+ {
+ _exchangeName = exchangeName;
+ return this;
+ }
+
+ public MessagePublisherBuilder WithDeliveryMode(DeliveryMode deliveryMode)
+ {
+ _deliveryMode = deliveryMode;
+ return this;
+ }
+
+ public MessagePublisherBuilder WithTimeToLive(long timeToLive)
+ {
+ _timeToLive = timeToLive;
+ return this;
+ }
+
+ public MessagePublisherBuilder WithImmediate(bool immediate)
+ {
+ _immediate = immediate;
+ return this;
+ }
+
+ public MessagePublisherBuilder WithMandatory(bool mandatory)
+ {
+ _mandatory = mandatory;
+ return this;
+ }
+
+ public IMessagePublisher Create()
+ {
+ return _channel.CreatePublisher(_exchangeName, _routingKey, _deliveryMode, _timeToLive, _immediate, _mandatory, _priority);
+ }
+ }
+}
diff --git a/qpid/dotnet/Qpid.Messaging/Properties/AssemblyInfo.cs b/qpid/dotnet/Qpid.Messaging/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000000..d9dff07f3f
--- /dev/null
+++ b/qpid/dotnet/Qpid.Messaging/Properties/AssemblyInfo.cs
@@ -0,0 +1,56 @@
+/*
+ *
+ * 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.
+ *
+ */
+using System;
+using System.Reflection;
+using System.Runtime.InteropServices;
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("Apache.Qpid.Messaging")]
+[assembly: AssemblyDescription("Built from svn revision number: ")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Apache Software Foundation")]
+[assembly: AssemblyProduct("Apache.Qpid.Messaging")]
+[assembly: AssemblyCopyright("Apache Software Foundation")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("e74f1805-b355-42e0-ba70-afc7c8570f03")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Revision and Build Numbers
+// by using the '*' as shown below:
+[assembly: AssemblyVersion("0.5.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
+
+[assembly: CLSCompliant(true)]
diff --git a/qpid/dotnet/Qpid.Messaging/Qpid.Messaging.csproj b/qpid/dotnet/Qpid.Messaging/Qpid.Messaging.csproj
new file mode 100644
index 0000000000..37b80d1515
--- /dev/null
+++ b/qpid/dotnet/Qpid.Messaging/Qpid.Messaging.csproj
@@ -0,0 +1,115 @@
+<!--
+
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+
+-->
+
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProductVersion>9.0.30729</ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{6688F826-C58E-4C1B-AA1F-22AFAB4B7D07}</ProjectGuid>
+ <OutputType>Library</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>Apache.Qpid.Messaging</RootNamespace>
+ <AssemblyName>Apache.Qpid.Messaging</AssemblyName>
+ <SignAssembly>true</SignAssembly>
+ <FileUpgradeFlags>
+ </FileUpgradeFlags>
+ <OldToolsVersion>2.0</OldToolsVersion>
+ <UpgradeBackupLocation>
+ </UpgradeBackupLocation>
+ <PublishUrl>http://localhost/Apache.Qpid.Messaging/</PublishUrl>
+ <Install>true</Install>
+ <InstallFrom>Web</InstallFrom>
+ <UpdateEnabled>true</UpdateEnabled>
+ <UpdateMode>Foreground</UpdateMode>
+ <UpdateInterval>7</UpdateInterval>
+ <UpdateIntervalUnits>Days</UpdateIntervalUnits>
+ <UpdatePeriodically>false</UpdatePeriodically>
+ <UpdateRequired>false</UpdateRequired>
+ <MapFileExtensions>true</MapFileExtensions>
+ <ApplicationRevision>0</ApplicationRevision>
+ <ApplicationVersion>1.0.0.%2a</ApplicationVersion>
+ <IsWebBootstrapper>true</IsWebBootstrapper>
+ <UseApplicationTrust>false</UseApplicationTrust>
+ <BootstrapperEnabled>true</BootstrapperEnabled>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>..\bin\net-2.0\debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>..\bin\net-2.0\release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="System" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="**\*.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <BootstrapperPackage Include="Microsoft.Net.Client.3.5">
+ <Visible>False</Visible>
+ <ProductName>.NET Framework Client Profile</ProductName>
+ <Install>false</Install>
+ </BootstrapperPackage>
+ <BootstrapperPackage Include="Microsoft.Net.Framework.2.0">
+ <Visible>False</Visible>
+ <ProductName>.NET Framework 2.0 %28x86%29</ProductName>
+ <Install>true</Install>
+ </BootstrapperPackage>
+ <BootstrapperPackage Include="Microsoft.Net.Framework.3.0">
+ <Visible>False</Visible>
+ <ProductName>.NET Framework 3.0 %28x86%29</ProductName>
+ <Install>false</Install>
+ </BootstrapperPackage>
+ <BootstrapperPackage Include="Microsoft.Net.Framework.3.5">
+ <Visible>False</Visible>
+ <ProductName>.NET Framework 3.5</ProductName>
+ <Install>false</Install>
+ </BootstrapperPackage>
+ <BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
+ <Visible>False</Visible>
+ <ProductName>.NET Framework 3.5 SP1</ProductName>
+ <Install>false</Install>
+ </BootstrapperPackage>
+ </ItemGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+ <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
+ Other similar extension points exist, see Microsoft.Common.targets.
+ <Target Name="BeforeBuild">
+ </Target>
+ <Target Name="AfterBuild">
+ </Target>
+ -->
+</Project>
diff --git a/qpid/dotnet/Qpid.Messaging/QpidException.cs b/qpid/dotnet/Qpid.Messaging/QpidException.cs
new file mode 100644
index 0000000000..3e39f2293d
--- /dev/null
+++ b/qpid/dotnet/Qpid.Messaging/QpidException.cs
@@ -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.
+ *
+ */
+using System;
+using System.Runtime.Serialization;
+
+namespace Apache.Qpid.Messaging
+{
+ [Serializable]
+ public class QpidException : Exception
+ {
+ public QpidException(string reason) : base(reason)
+ {
+ }
+
+ public QpidException(string reason, Exception e)
+ : base(reason, e)
+ {
+ }
+
+ protected QpidException(SerializationInfo info, StreamingContext ctxt)
+ : base(info, ctxt)
+ {
+ }
+ }
+}
diff --git a/qpid/dotnet/Qpid.Messaging/ResourceAllocationException.cs b/qpid/dotnet/Qpid.Messaging/ResourceAllocationException.cs
new file mode 100644
index 0000000000..954dcdd94c
--- /dev/null
+++ b/qpid/dotnet/Qpid.Messaging/ResourceAllocationException.cs
@@ -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.
+ *
+ */
+
+using System;
+using System.Runtime.Serialization;
+
+namespace Apache.Qpid.Messaging
+{
+ [Serializable]
+ public class ResourceAllocationException : QpidException
+ {
+ public ResourceAllocationException(string reason) : base(reason)
+ {
+ }
+
+ protected ResourceAllocationException(SerializationInfo info, StreamingContext ctxt)
+ : base(info, ctxt)
+ {
+ }
+ }
+}
diff --git a/qpid/dotnet/Qpid.Messaging/default.build b/qpid/dotnet/Qpid.Messaging/default.build
new file mode 100644
index 0000000000..e351def886
--- /dev/null
+++ b/qpid/dotnet/Qpid.Messaging/default.build
@@ -0,0 +1,45 @@
+<?xml version="1.0"?>
+<!--
+
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+
+-->
+
+<project name="Apache.Qpid.Messaging" default="build">
+ <!--
+ Properties that come from master build file
+ - build.dir: root directory for build
+ - build.debug: true if building debug release
+ - build.defines: variables to define during build
+ -->
+
+ <target name="build">
+ <csc target="library"
+ define="${build.defines}"
+ debug="${build.debug}"
+ output="${build.dir}/${project::get-name()}.dll">
+
+ <sources>
+ <include name="**/*.cs" />
+ </sources>
+ <references>
+ </references>
+ </csc>
+ </target>
+</project>
+
diff --git a/qpid/dotnet/Qpid.NET.FxCop b/qpid/dotnet/Qpid.NET.FxCop
new file mode 100644
index 0000000000..ba6b3e3ac5
--- /dev/null
+++ b/qpid/dotnet/Qpid.NET.FxCop
@@ -0,0 +1,16775 @@
+<?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.
+ -
+ -->
+<FxCopProject Version="1.35" Name="My FxCop Project">
+ <ProjectOptions>
+ <SharedProject>True</SharedProject>
+ <Stylesheet Apply="False">http://www.gotdotnet.com/team/fxcop//xsl/1.35/FxCopReport.xsl</Stylesheet>
+ <SaveMessages>
+ <Project Status="Active, Excluded" NewOnly="False" />
+ <Report Status="Active" NewOnly="False" />
+ </SaveMessages>
+ <ProjectFile Compress="True" DefaultTargetCheck="True" DefaultRuleCheck="True" SaveByRuleGroup="" Deterministic="True" />
+ <EnableMultithreadedLoad>True</EnableMultithreadedLoad>
+ <EnableMultithreadedAnalysis>True</EnableMultithreadedAnalysis>
+ <SourceLookup>True</SourceLookup>
+ <AnalysisExceptionsThreshold>10</AnalysisExceptionsThreshold>
+ <RuleExceptionsThreshold>1</RuleExceptionsThreshold>
+ <Spelling Locale="en-us" />
+ <VersionAware>False</VersionAware>
+ <OverrideRuleVisibilities>False</OverrideRuleVisibilities>
+ <CustomDictionaries SearchFxCopDir="True" SearchUserProfile="True" SearchProjectDir="True" />
+ <SearchGlobalAssemblyCache>False</SearchGlobalAssemblyCache>
+ <DeadlockDetectionTimeout>120</DeadlockDetectionTimeout>
+ </ProjectOptions>
+ <Targets>
+ <Target Name="$(ProjectDir)/Qpid.Client.Tests/bin/Debug/Qpid.Buffer.dll" Analyze="True" AnalyzeAllChildren="True" />
+ <Target Name="$(ProjectDir)/Qpid.Client.Tests/bin/Debug/Qpid.Client.dll" Analyze="True" AnalyzeAllChildren="True" />
+ <Target Name="$(ProjectDir)/Qpid.Client.Tests/bin/Debug/Qpid.Client.Tests.dll" Analyze="True" AnalyzeAllChildren="True" />
+ <Target Name="$(ProjectDir)/Qpid.Client.Tests/bin/Debug/Qpid.Client.Transport.Socket.Blocking.dll" Analyze="True" AnalyzeAllChildren="True" />
+ <Target Name="$(ProjectDir)/Qpid.Client.Tests/bin/Debug/Qpid.Codec.dll" Analyze="True" AnalyzeAllChildren="True" />
+ <Target Name="$(ProjectDir)/Qpid.Client.Tests/bin/Debug/Qpid.Common.dll" Analyze="True" AnalyzeAllChildren="True" />
+ <Target Name="$(ProjectDir)/Qpid.Client.Tests/bin/Debug/Qpid.Messaging.dll" Analyze="True" AnalyzeAllChildren="True" />
+ </Targets>
+ <Rules>
+ <RuleFiles>
+ <RuleFile Name="$(FxCopDir)\Rules\DesignRules.dll" Enabled="True" AllRulesEnabled="True" />
+ <RuleFile Name="$(FxCopDir)\Rules\GlobalizationRules.dll" Enabled="True" AllRulesEnabled="True" />
+ <RuleFile Name="$(FxCopDir)\Rules\InteroperabilityRules.dll" Enabled="True" AllRulesEnabled="True" />
+ <RuleFile Name="$(FxCopDir)\Rules\MobilityRules.dll" Enabled="True" AllRulesEnabled="True" />
+ <RuleFile Name="$(FxCopDir)\Rules\NamingRules.dll" Enabled="True" AllRulesEnabled="True" />
+ <RuleFile Name="$(FxCopDir)\Rules\PerformanceRules.dll" Enabled="True" AllRulesEnabled="True" />
+ <RuleFile Name="$(FxCopDir)\Rules\PortabilityRules.dll" Enabled="True" AllRulesEnabled="True" />
+ <RuleFile Name="$(FxCopDir)\Rules\SecurityRules.dll" Enabled="True" AllRulesEnabled="True" />
+ <RuleFile Name="$(FxCopDir)\Rules\UsageRules.dll" Enabled="True" AllRulesEnabled="True" />
+ </RuleFiles>
+ <Groups />
+ <Settings />
+ </Rules>
+ <FxCopReport Version="1.35">
+ <Namespaces>
+ <Namespace Name="Qpid">
+ <Messages>
+ <Message Id="Qpid" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Namespace">
+ <Item>Qpid</Item>
+ <Item>Qpid</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Namespace>
+ <Namespace Name="Qpid.Buffer">
+ <Messages>
+ <Message Id="Qpid" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Namespace">
+ <Item>Qpid</Item>
+ <Item>Qpid.Buffer</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Namespace>
+ <Namespace Name="Qpid.Client">
+ <Messages>
+ <Message Id="Qpid" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Namespace">
+ <Item>Qpid</Item>
+ <Item>Qpid.Client</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Namespace>
+ <Namespace Name="Qpid.Client.Failover">
+ <Messages>
+ <Message TypeName="AvoidNamespacesWithFewTypes" Category="Microsoft.Design" CheckId="CA1020" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Qpid.Client.Failover</Item>
+ </Issue>
+ </Message>
+ <Message Id="Qpid" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Namespace">
+ <Item>Qpid</Item>
+ <Item>Qpid.Client.Failover</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Namespace>
+ <Namespace Name="Qpid.Client.Handler">
+ <Messages>
+ <Message Id="Qpid" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Namespace">
+ <Item>Qpid</Item>
+ <Item>Qpid.Client.Handler</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Namespace>
+ <Namespace Name="Qpid.Client.Message">
+ <Messages>
+ <Message Id="Qpid" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Namespace">
+ <Item>Qpid</Item>
+ <Item>Qpid.Client.Message</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Namespace>
+ <Namespace Name="Qpid.Client.Protocol">
+ <Messages>
+ <Message Id="Qpid" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Namespace">
+ <Item>Qpid</Item>
+ <Item>Qpid.Client.Protocol</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Namespace>
+ <Namespace Name="Qpid.Client.Protocol.Listener">
+ <Messages>
+ <Message TypeName="AvoidNamespacesWithFewTypes" Category="Microsoft.Design" CheckId="CA1020" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Qpid.Client.Protocol.Listener</Item>
+ </Issue>
+ </Message>
+ <Message Id="Qpid" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Namespace">
+ <Item>Qpid</Item>
+ <Item>Qpid.Client.Protocol.Listener</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Namespace>
+ <Namespace Name="Qpid.Client.qms">
+ <Messages>
+ <Message TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Namespace">
+ <Item>Qpid.Client.qms</Item>
+ </Issue>
+ </Message>
+ <Message Id="Qpid" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Namespace">
+ <Item>Qpid</Item>
+ <Item>Qpid.Client.qms</Item>
+ </Issue>
+ </Message>
+ <Message Id="qms" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Namespace">
+ <Item>qms</Item>
+ <Item>Qpid.Client.qms</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Namespace>
+ <Namespace Name="Qpid.Client.qms.failover">
+ <Messages>
+ <Message TypeName="AvoidNamespacesWithFewTypes" Category="Microsoft.Design" CheckId="CA1020" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Qpid.Client.qms.failover</Item>
+ </Issue>
+ </Message>
+ <Message TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Namespace">
+ <Item>Qpid.Client.qms.failover</Item>
+ </Issue>
+ <Issue Name="Namespace">
+ <Item>Qpid.Client.qms.failover</Item>
+ </Issue>
+ </Message>
+ <Message Id="Qpid" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Namespace">
+ <Item>Qpid</Item>
+ <Item>Qpid.Client.qms.failover</Item>
+ </Issue>
+ </Message>
+ <Message Id="qms" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Namespace">
+ <Item>qms</Item>
+ <Item>Qpid.Client.qms.failover</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Namespace>
+ <Namespace Name="Qpid.Client.State">
+ <Messages>
+ <Message Id="Qpid" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Namespace">
+ <Item>Qpid</Item>
+ <Item>Qpid.Client.State</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Namespace>
+ <Namespace Name="Qpid.Client.Tests">
+ <Messages>
+ <Message Id="Qpid" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Namespace">
+ <Item>Qpid</Item>
+ <Item>Qpid.Client.Tests</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Namespace>
+ <Namespace Name="Qpid.Client.Tests.connection">
+ <Messages>
+ <Message TypeName="AvoidNamespacesWithFewTypes" Category="Microsoft.Design" CheckId="CA1020" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Qpid.Client.Tests.connection</Item>
+ </Issue>
+ </Message>
+ <Message TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Namespace">
+ <Item>Qpid.Client.Tests.connection</Item>
+ </Issue>
+ </Message>
+ <Message Id="Qpid" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Namespace">
+ <Item>Qpid</Item>
+ <Item>Qpid.Client.Tests.connection</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Namespace>
+ <Namespace Name="Qpid.Client.Tests.failover">
+ <Messages>
+ <Message TypeName="AvoidNamespacesWithFewTypes" Category="Microsoft.Design" CheckId="CA1020" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Qpid.Client.Tests.failover</Item>
+ </Issue>
+ </Message>
+ <Message TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Namespace">
+ <Item>Qpid.Client.Tests.failover</Item>
+ </Issue>
+ </Message>
+ <Message Id="Qpid" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Namespace">
+ <Item>Qpid</Item>
+ <Item>Qpid.Client.Tests.failover</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Namespace>
+ <Namespace Name="Qpid.Client.Tests.url">
+ <Messages>
+ <Message TypeName="AvoidNamespacesWithFewTypes" Category="Microsoft.Design" CheckId="CA1020" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Qpid.Client.Tests.url</Item>
+ </Issue>
+ </Message>
+ <Message TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Namespace">
+ <Item>Qpid.Client.Tests.url</Item>
+ </Issue>
+ </Message>
+ <Message Id="Qpid" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Namespace">
+ <Item>Qpid</Item>
+ <Item>Qpid.Client.Tests.url</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Namespace>
+ <Namespace Name="Qpid.Client.Transport">
+ <Messages>
+ <Message Id="Qpid" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Namespace">
+ <Item>Qpid</Item>
+ <Item>Qpid.Client.Transport</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Namespace>
+ <Namespace Name="Qpid.Client.Transport.Socket.Blocking">
+ <Messages>
+ <Message Id="Qpid" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Namespace">
+ <Item>Qpid</Item>
+ <Item>Qpid.Client.Transport.Socket.Blocking</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Namespace>
+ <Namespace Name="Qpid.Codec">
+ <Messages>
+ <Message Id="Qpid" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Namespace">
+ <Item>Qpid</Item>
+ <Item>Qpid.Codec</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Namespace>
+ <Namespace Name="Qpid.Codec.Demux">
+ <Messages>
+ <Message Id="Demux" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Namespace">
+ <Item>Demux</Item>
+ <Item>Qpid.Codec.Demux</Item>
+ </Issue>
+ </Message>
+ <Message Id="Qpid" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Namespace">
+ <Item>Qpid</Item>
+ <Item>Qpid.Codec.Demux</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Namespace>
+ <Namespace Name="Qpid.Codec.Support">
+ <Messages>
+ <Message TypeName="AvoidNamespacesWithFewTypes" Category="Microsoft.Design" CheckId="CA1020" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Qpid.Codec.Support</Item>
+ </Issue>
+ </Message>
+ <Message Id="Qpid" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Namespace">
+ <Item>Qpid</Item>
+ <Item>Qpid.Codec.Support</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Namespace>
+ <Namespace Name="Qpid.Collections">
+ <Messages>
+ <Message TypeName="AvoidNamespacesWithFewTypes" Category="Microsoft.Design" CheckId="CA1020" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Qpid.Collections</Item>
+ </Issue>
+ </Message>
+ <Message Id="Qpid" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Namespace">
+ <Item>Qpid</Item>
+ <Item>Qpid.Collections</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Namespace>
+ <Namespace Name="Qpid.Common">
+ <Messages>
+ <Message TypeName="AvoidNamespacesWithFewTypes" Category="Microsoft.Design" CheckId="CA1020" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Qpid.Common</Item>
+ </Issue>
+ </Message>
+ <Message Id="Qpid" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Namespace">
+ <Item>Qpid</Item>
+ <Item>Qpid.Common</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Namespace>
+ <Namespace Name="Qpid.Framing">
+ <Messages>
+ <Message Id="Qpid" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Namespace">
+ <Item>Qpid</Item>
+ <Item>Qpid.Framing</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Namespace>
+ <Namespace Name="Qpid.Messaging">
+ <Messages>
+ <Message Id="Qpid" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Namespace">
+ <Item>Qpid</Item>
+ <Item>Qpid.Messaging</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Namespace>
+ </Namespaces>
+ <Targets>
+ <Target Name="$(ProjectDir)/Qpid.Client.Tests/bin/Debug/Qpid.Buffer.dll">
+ <Modules>
+ <Module Name="qpid.buffer.dll">
+ <Messages>
+ <Message TypeName="AssembliesShouldDeclareMinimumSecurity" Category="Microsoft.Usage" CheckId="CA2209" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Qpid.Buffer</Item>
+ </Issue>
+ </Message>
+ <Message TypeName="AssembliesShouldHaveValidStrongNames" Category="Microsoft.Design" CheckId="CA2210" Created="2006-12-04 13:11:47Z">
+ <Issue Name="NoStrongName">
+ <Item>Qpid.Buffer</Item>
+ </Issue>
+ </Message>
+ <Message TypeName="MarkAssembliesWithClsCompliant" Category="Microsoft.Design" CheckId="CA1014" Created="2006-12-04 13:11:47Z">
+ <Issue Name="NoAttr">
+ <Item>Qpid.Buffer</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ <Namespaces>
+ <Namespace Name="Qpid.Buffer">
+ <Types>
+ <Type Name="BufferOverflowException">
+ <Messages>
+ <Message TypeName="ImplementStandardExceptionConstructors" Category="Microsoft.Design" CheckId="CA1032" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Qpid.Buffer.BufferOverflowException</Item>
+ <Item>protected BufferOverflowException(SerializationInfo, StreamingContext)</Item>
+ </Issue>
+ <Issue>
+ <Item>Qpid.Buffer.BufferOverflowException</Item>
+ <Item>public BufferOverflowException()</Item>
+ </Issue>
+ <Issue>
+ <Item>Qpid.Buffer.BufferOverflowException</Item>
+ <Item>public BufferOverflowException(String, Exception)</Item>
+ </Issue>
+ </Message>
+ <Message TypeName="MarkISerializableTypesWithSerializable" Category="Microsoft.Usage" CheckId="CA2237" Created="2006-12-04 13:11:47Z">
+ <Issue Level="Error">
+ <Item>BufferOverflowException</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Type>
+ <Type Name="BufferUnderflowException">
+ <Messages>
+ <Message TypeName="ImplementStandardExceptionConstructors" Category="Microsoft.Design" CheckId="CA1032" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Qpid.Buffer.BufferUnderflowException</Item>
+ <Item>protected BufferUnderflowException(SerializationInfo, StreamingContext)</Item>
+ </Issue>
+ <Issue>
+ <Item>Qpid.Buffer.BufferUnderflowException</Item>
+ <Item>public BufferUnderflowException()</Item>
+ </Issue>
+ <Issue>
+ <Item>Qpid.Buffer.BufferUnderflowException</Item>
+ <Item>public BufferUnderflowException(String, Exception)</Item>
+ </Issue>
+ </Message>
+ <Message TypeName="MarkISerializableTypesWithSerializable" Category="Microsoft.Usage" CheckId="CA2237" Created="2006-12-04 13:11:47Z">
+ <Issue Level="Error">
+ <Item>BufferUnderflowException</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Type>
+ <Type Name="ByteBuffer">
+ <Members>
+ <Member Name="_containerStack">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>_containerStack</Item>
+ </Issue>
+ </Message>
+ <Message TypeName="NonConstantFieldsShouldNotBeVisible" Category="Microsoft.Usage" CheckId="CA2211" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>_containerStack</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="_heapBufferStacks">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>_heapBufferStacks</Item>
+ </Issue>
+ </Message>
+ <Message TypeName="NonConstantFieldsShouldNotBeVisible" Category="Microsoft.Usage" CheckId="CA2211" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>_heapBufferStacks</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Allocate0(System.Int32,System.Boolean):Qpid.Buffer.ByteBuffer">
+ <Messages>
+ <Message Id="System.NotSupportedException.#ctor(System.String)" TypeName="DoNotPassLiteralsAsLocalizedParameters" Category="Microsoft.Globalization" CheckId="CA1303" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>ByteBuffer.Allocate0(Int32, Boolean):ByteBuffer</Item>
+ <Item>1</Item>
+ <Item>NotSupportedException.NotSupportedException(String)</Item>
+ <Item>Direct buffers not currently implemented</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Equals(System.Object):System.Boolean">
+ <Messages>
+ <Message TypeName="DoNotCastUnnecessarily" Category="Microsoft.Performance" CheckId="CA1800" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>obj</Item>
+ <Item>Qpid.Buffer.ByteBuffer</Item>
+ <Item>ByteBuffer.Equals(Object):Boolean</Item>
+ <Item>castclass</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="GetBufferStackIndex(System.Collections.Stack[],System.Int32):System.Int32">
+ <Messages>
+ <Message Id="System.ArgumentOutOfRangeException.#ctor(System.String,System.String)" TypeName="DoNotPassLiteralsAsLocalizedParameters" Category="Microsoft.Globalization" CheckId="CA1303" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>ByteBuffer.GetBufferStackIndex(Stack[], Int32):Int32</Item>
+ <Item>2</Item>
+ <Item>ArgumentOutOfRangeException.ArgumentOutOfRangeException(String, String)</Item>
+ <Item>Buffer size is too big: __</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="GetUnsignedInt():System.UInt32">
+ <Messages>
+ <Message TypeName="UsePropertiesWhereAppropriate" Category="Microsoft.Design" CheckId="CA1024" Created="2006-12-04 13:11:47Z">
+ <Issue Certainty="50">
+ <Item>GetUnsignedInt</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="GetUnsignedLong():System.UInt64">
+ <Messages>
+ <Message TypeName="UsePropertiesWhereAppropriate" Category="Microsoft.Design" CheckId="CA1024" Created="2006-12-04 13:11:47Z">
+ <Issue Certainty="50">
+ <Item>GetUnsignedLong</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="GetUnsignedShort():System.UInt16">
+ <Messages>
+ <Message TypeName="UsePropertiesWhereAppropriate" Category="Microsoft.Design" CheckId="CA1024" Created="2006-12-04 13:11:47Z">
+ <Issue Certainty="50">
+ <Item>GetUnsignedShort</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="MINIMUM_CAPACITY">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>MINIMUM_CAPACITY</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>ByteBuffer.MINIMUM_CAPACITY</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Put(Qpid.Buffer.ByteBuffer):System.Void">
+ <Messages>
+ <Message Id="0#buf" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>ByteBuffer.Put(ByteBuffer):Void</Item>
+ <Item>buf</Item>
+ <Item>buf</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Release0(Qpid.Buffer.ByteBuffer):System.Void">
+ <Messages>
+ <Message Id="0#buf" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>ByteBuffer.Release0(ByteBuffer):Void</Item>
+ <Item>buf</Item>
+ <Item>buf</Item>
+ </Issue>
+ </Message>
+ <Message TypeName="ValidateArgumentsOfPublicMethods" Category="Microsoft.Design" CheckId="CA1062" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>'buf'</Item>
+ <Item>ByteBuffer.Release0(ByteBuffer):Void</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="ByteBufferHexDumper">
+ <Messages>
+ <Message TypeName="StaticHolderTypesShouldNotHaveConstructors" Category="Microsoft.Design" CheckId="CA1053" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>ByteBufferHexDumper</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ <Members>
+ <Member Name=".cctor()">
+ <Messages>
+ <Message TypeName="InitializeReferenceTypeStaticFieldsInline" Category="Microsoft.Performance" CheckId="CA1810" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Qpid.Buffer.ByteBufferHexDumper</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="GetHexDump(Qpid.Buffer.ByteBuffer):System.String">
+ <Messages>
+ <Message TypeName="ValidateArgumentsOfPublicMethods" Category="Microsoft.Design" CheckId="CA1062" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>'input'</Item>
+ <Item>ByteBufferHexDumper.GetHexDump(ByteBuffer):String</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="ByteBufferProxy">
+ <Members>
+ <Member Name=".ctor(Qpid.Buffer.ByteBuffer)">
+ <Messages>
+ <Message Id="0#buf" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>ByteBufferProxy.ByteBufferProxy(ByteBuffer)</Item>
+ <Item>buf</Item>
+ <Item>buf</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="_buf">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>_buf</Item>
+ </Issue>
+ </Message>
+ <Message Id="_buf" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>_buf</Item>
+ <Item>ByteBufferProxy._buf</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>_buf</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="HeapByteBuffer">
+ <Members>
+ <Member Name="CheckSpace(System.Int32):System.Void">
+ <Messages>
+ <Message Id="Qpid.Buffer.BufferOverflowException.#ctor(System.String)" TypeName="DoNotPassLiteralsAsLocalizedParameters" Category="Microsoft.Globalization" CheckId="CA1303" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>HeapByteBuffer.CheckSpace(Int32):Void</Item>
+ <Item>1</Item>
+ <Item>BufferOverflowException.BufferOverflowException(String)</Item>
+ <Item>Attempt to write ____ byte(s) to buffer where position is ____ and limit is __</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="CheckSpaceForReading(System.Int32):System.Void">
+ <Messages>
+ <Message Id="Qpid.Buffer.BufferUnderflowException.#ctor(System.String)" TypeName="DoNotPassLiteralsAsLocalizedParameters" Category="Microsoft.Globalization" CheckId="CA1303" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>HeapByteBuffer.CheckSpaceForReading(Int32):Void</Item>
+ <Item>1</Item>
+ <Item>BufferUnderflowException.BufferUnderflowException(String)</Item>
+ <Item>Attempt to read ____ byte(s) to buffer where position is ____ and limit is __</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="GetString(System.UInt32,System.Text.Encoding):System.String">
+ <Messages>
+ <Message TypeName="ValidateArgumentsOfPublicMethods" Category="Microsoft.Design" CheckId="CA1062" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>'encoder'</Item>
+ <Item>HeapByteBuffer.GetString(UInt32, Encoding):String</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Limit">
+ <Accessors>
+ <Accessor Name="set_Limit(System.Int32):System.Void">
+ <Messages>
+ <Message Id="System.ArgumentException.#ctor(System.String)" TypeName="DoNotPassLiteralsAsLocalizedParameters" Category="Microsoft.Globalization" CheckId="CA1303" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>HeapByteBuffer.set_Limit(Int32):Void</Item>
+ <Item>1</Item>
+ <Item>ArgumentException.ArgumentException(String)</Item>
+ <Item>Limit must not be greater than Capacity</Item>
+ </Issue>
+ <Issue>
+ <Item>HeapByteBuffer.set_Limit(Int32):Void</Item>
+ <Item>1</Item>
+ <Item>ArgumentException.ArgumentException(String)</Item>
+ <Item>Limit must not be negative</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Accessor>
+ </Accessors>
+ </Member>
+ <Member Name="Mark():System.Void">
+ <Messages>
+ <Message TypeName="MarkMembersAsStatic" Category="Microsoft.Performance" CheckId="CA1822" Created="2006-12-04 13:11:47Z" FixCategory="Breaking">
+ <Issue>
+ <Item>HeapByteBuffer.Mark():Void</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Put(Qpid.Buffer.ByteBuffer):System.Void">
+ <Messages>
+ <Message TypeName="DoNotCastUnnecessarily" Category="Microsoft.Performance" CheckId="CA1800" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>src</Item>
+ <Item>Qpid.Buffer.HeapByteBuffer</Item>
+ <Item>HeapByteBuffer.Put(ByteBuffer):Void</Item>
+ <Item>castclass</Item>
+ </Issue>
+ </Message>
+ <Message Id="Qpid.Buffer.BufferOverflowException.#ctor(System.String)" TypeName="DoNotPassLiteralsAsLocalizedParameters" Category="Microsoft.Globalization" CheckId="CA1303" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>HeapByteBuffer.Put(ByteBuffer):Void</Item>
+ <Item>1</Item>
+ <Item>BufferOverflowException.BufferOverflowException(String)</Item>
+ <Item>Not enought capacity in this buffer for ____ elements - only ____ remaining</Item>
+ </Issue>
+ </Message>
+ <Message Id="System.ArgumentException.#ctor(System.String)" TypeName="DoNotPassLiteralsAsLocalizedParameters" Category="Microsoft.Globalization" CheckId="CA1303" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>HeapByteBuffer.Put(ByteBuffer):Void</Item>
+ <Item>1</Item>
+ <Item>ArgumentException.ArgumentException(String)</Item>
+ <Item>Cannot copy self into self!</Item>
+ </Issue>
+ </Message>
+ <Message Id="enought" TypeName="LiteralsShouldBeSpelledCorrectly" Category="Microsoft.Usage" CheckId="CA2204" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>enought</Item>
+ <Item>Not enought capacity in this buffer for ____ elements - only ____ remaining</Item>
+ </Issue>
+ </Message>
+ <Message Id="0#" TypeName="ParameterNamesShouldMatchBaseDeclaration" Category="Microsoft.Naming" CheckId="CA1725" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>src</Item>
+ <Item>HeapByteBuffer.Put(ByteBuffer):Void</Item>
+ <Item>buf</Item>
+ <Item>ByteBuffer.Put(ByteBuffer):Void</Item>
+ </Issue>
+ </Message>
+ <Message TypeName="ValidateArgumentsOfPublicMethods" Category="Microsoft.Design" CheckId="CA1062" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>'src'</Item>
+ <Item>HeapByteBuffer.Put(ByteBuffer):Void</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Put(System.Byte[]):System.Void">
+ <Messages>
+ <Message TypeName="ValidateArgumentsOfPublicMethods" Category="Microsoft.Design" CheckId="CA1062" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>'data'</Item>
+ <Item>HeapByteBuffer.Put(Byte[]):Void</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Reset():System.Void">
+ <Messages>
+ <Message TypeName="MarkMembersAsStatic" Category="Microsoft.Performance" CheckId="CA1822" Created="2006-12-04 13:11:47Z" FixCategory="Breaking">
+ <Issue>
+ <Item>HeapByteBuffer.Reset():Void</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="wrap(System.Byte[]):Qpid.Buffer.HeapByteBuffer">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>wrap</Item>
+ </Issue>
+ </Message>
+ <Message TypeName="ValidateArgumentsOfPublicMethods" Category="Microsoft.Design" CheckId="CA1062" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>'bytes'</Item>
+ <Item>HeapByteBuffer.wrap(Byte[]):HeapByteBuffer</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="wrap(System.Byte[],System.Int32):Qpid.Buffer.HeapByteBuffer">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>wrap</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="RefCountingByteBuffer">
+ <Members>
+ <Member Name="Acquire():System.Void">
+ <Messages>
+ <Message Id="System.Exception.#ctor(System.String)" TypeName="DoNotPassLiteralsAsLocalizedParameters" Category="Microsoft.Globalization" CheckId="CA1303" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>RefCountingByteBuffer.Acquire():Void</Item>
+ <Item>1</Item>
+ <Item>Exception.Exception(String)</Item>
+ <Item>Already released buffer</Item>
+ </Issue>
+ </Message>
+ <Message TypeName="DoNotRaiseReservedExceptionTypes" Category="Microsoft.Usage" CheckId="CA2201" Created="2006-12-04 13:11:47Z">
+ <Issue Name="TooGeneric">
+ <Item>RefCountingByteBuffer.Acquire():Void</Item>
+ <Item>System.Exception</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Buf">
+ <Messages>
+ <Message Id="Buf" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>Buf</Item>
+ <Item>RefCountingByteBuffer.Buf:ByteBuffer</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Init(Qpid.Buffer.ByteBuffer):System.Void">
+ <Messages>
+ <Message Id="0#buf" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>RefCountingByteBuffer.Init(ByteBuffer):Void</Item>
+ <Item>buf</Item>
+ <Item>buf</Item>
+ </Issue>
+ </Message>
+ <Message TypeName="ValidateArgumentsOfPublicMethods" Category="Microsoft.Design" CheckId="CA1062" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>'buf'</Item>
+ <Item>RefCountingByteBuffer.Init(ByteBuffer):Void</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Put(Qpid.Buffer.ByteBuffer):System.Void">
+ <Messages>
+ <Message TypeName="ValidateArgumentsOfPublicMethods" Category="Microsoft.Design" CheckId="CA1062" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>'buf'</Item>
+ <Item>RefCountingByteBuffer.Put(ByteBuffer):Void</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Put(System.Byte[]):System.Void">
+ <Messages>
+ <Message TypeName="ValidateArgumentsOfPublicMethods" Category="Microsoft.Design" CheckId="CA1062" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>'data'</Item>
+ <Item>RefCountingByteBuffer.Put(Byte[]):Void</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Release():System.Void">
+ <Messages>
+ <Message Id="System.Exception.#ctor(System.String)" TypeName="DoNotPassLiteralsAsLocalizedParameters" Category="Microsoft.Globalization" CheckId="CA1303" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>RefCountingByteBuffer.Release():Void</Item>
+ <Item>1</Item>
+ <Item>Exception.Exception(String)</Item>
+ <Item>Already released buffer. Release called too many times</Item>
+ </Issue>
+ </Message>
+ <Message TypeName="DoNotRaiseReservedExceptionTypes" Category="Microsoft.Usage" CheckId="CA2201" Created="2006-12-04 13:11:47Z">
+ <Issue Name="TooGeneric">
+ <Item>RefCountingByteBuffer.Release():Void</Item>
+ <Item>System.Exception</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ </Types>
+ </Namespace>
+ </Namespaces>
+ </Module>
+ </Modules>
+ </Target>
+ <Target Name="$(ProjectDir)/Qpid.Client.Tests/bin/Debug/Qpid.Client.dll">
+ <Modules>
+ <Module Name="qpid.client.dll">
+ <Messages>
+ <Message TypeName="AssembliesShouldDeclareMinimumSecurity" Category="Microsoft.Usage" CheckId="CA2209" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Qpid.Client</Item>
+ </Issue>
+ </Message>
+ <Message TypeName="AssembliesShouldHaveValidStrongNames" Category="Microsoft.Design" CheckId="CA2210" Created="2006-12-04 13:11:47Z">
+ <Issue Name="NoStrongName">
+ <Item>Qpid.Client</Item>
+ </Issue>
+ </Message>
+ <Message TypeName="MarkAssembliesWithClsCompliant" Category="Microsoft.Design" CheckId="CA1014" Created="2006-12-04 13:11:47Z">
+ <Issue Name="NoAttr">
+ <Item>Qpid.Client</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ <Namespaces>
+ <Namespace Name="Qpid.Client">
+ <Types>
+ <Type Name="AmqBrokerInfo">
+ <Messages>
+ <Message Id="Amq" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Type">
+ <Item>Amq</Item>
+ <Item>Qpid.Client.AmqBrokerInfo</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ <Members>
+ <Member Name=".ctor(System.String)">
+ <Messages>
+ <Message Id="url" TypeName="ReviewUnusedParameters" Category="Microsoft.Usage" CheckId="CA1801" Created="2006-12-04 13:11:47Z" FixCategory="Breaking">
+ <Issue>
+ <Item>url</Item>
+ <Item>AmqBrokerInfo.AmqBrokerInfo(String)</Item>
+ </Issue>
+ </Message>
+ <Message Id="0#" TypeName="UriParametersShouldNotBeStrings" Category="Microsoft.Design" CheckId="CA1054" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>url</Item>
+ <Item>AmqBrokerInfo.AmqBrokerInfo(String)</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="DEFAULT_CONNECT_TIMEOUT">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>DEFAULT_CONNECT_TIMEOUT</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>AmqBrokerInfo.DEFAULT_CONNECT_TIMEOUT</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Equals(System.Object):System.Boolean">
+ <Messages>
+ <Message TypeName="DoNotCastUnnecessarily" Category="Microsoft.Performance" CheckId="CA1800" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>obj</Item>
+ <Item>Qpid.Client.qms.BrokerInfo</Item>
+ <Item>AmqBrokerInfo.Equals(Object):Boolean</Item>
+ <Item>castclass</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="GetHashCode():System.Int32">
+ <Messages>
+ <Message Id="System.String.ToLower" TypeName="SpecifyCultureInfo" Category="Microsoft.Globalization" CheckId="CA1304" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>AmqBrokerInfo.GetHashCode():Int32</Item>
+ <Item>System.String.ToLower</Item>
+ <Item>System.String.ToLower(System.Globalization.CultureInfo)</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="getTimeout():System.Int64">
+ <Messages>
+ <Message Id="System.Int64.Parse(System.String)" TypeName="SpecifyIFormatProvider" Category="Microsoft.Globalization" CheckId="CA1305" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>AmqBrokerInfo.getTimeout():Int64</Item>
+ <Item>System.Int64.Parse(System.String)</Item>
+ <Item>System.Int64.Parse(System.String,System.IFormatProvider)</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="setHost(System.String):System.Void">
+ <Messages>
+ <Message Id="0#" TypeName="ParameterNamesShouldMatchBaseDeclaration" Category="Microsoft.Naming" CheckId="CA1725" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>_host</Item>
+ <Item>AmqBrokerInfo.setHost(String):Void</Item>
+ <Item>host</Item>
+ <Item>BrokerInfo.setHost(String):Void</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="setPort(System.Int32):System.Void">
+ <Messages>
+ <Message Id="0#" TypeName="ParameterNamesShouldMatchBaseDeclaration" Category="Microsoft.Naming" CheckId="CA1725" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>_port</Item>
+ <Item>AmqBrokerInfo.setPort(Int32):Void</Item>
+ <Item>port</Item>
+ <Item>BrokerInfo.setPort(Int32):Void</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="setTimeout(System.Int64):System.Void">
+ <Messages>
+ <Message Id="System.Int64.ToString" TypeName="SpecifyIFormatProvider" Category="Microsoft.Globalization" CheckId="CA1305" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>AmqBrokerInfo.setTimeout(Int64):Void</Item>
+ <Item>System.Int64.ToString</Item>
+ <Item>System.Int64.ToString(System.IFormatProvider)</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="setTransport(System.String):System.Void">
+ <Messages>
+ <Message Id="0#" TypeName="ParameterNamesShouldMatchBaseDeclaration" Category="Microsoft.Naming" CheckId="CA1725" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>_transport</Item>
+ <Item>AmqBrokerInfo.setTransport(String):Void</Item>
+ <Item>transport</Item>
+ <Item>BrokerInfo.setTransport(String):Void</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="StringEqualsIgnoreCase(System.String,System.String):System.Boolean">
+ <Messages>
+ <Message Id="one" TypeName="AvoidUnnecessaryStringCreation" Category="Microsoft.Performance" CheckId="CA1807" Created="2006-12-04 13:11:47Z">
+ <Issue Name="UseStringCompareParameter">
+ <Item>AmqBrokerInfo.StringEqualsIgnoreCase(String, String):Boolean</Item>
+ <Item>String.Equals(String):Boolean</Item>
+ <Item>one</Item>
+ </Issue>
+ </Message>
+ <Message Id="two" TypeName="AvoidUnnecessaryStringCreation" Category="Microsoft.Performance" CheckId="CA1807" Created="2006-12-04 13:11:47Z">
+ <Issue Name="UseStringCompareParameter">
+ <Item>AmqBrokerInfo.StringEqualsIgnoreCase(String, String):Boolean</Item>
+ <Item>String.Equals(String):Boolean</Item>
+ <Item>two</Item>
+ </Issue>
+ </Message>
+ <Message TypeName="MarkMembersAsStatic" Category="Microsoft.Performance" CheckId="CA1822" Created="2006-12-04 13:11:47Z" FixCategory="NonBreaking">
+ <Issue>
+ <Item>AmqBrokerInfo.StringEqualsIgnoreCase(String, String):Boolean</Item>
+ </Issue>
+ </Message>
+ <Message Id="System.String.ToLower" TypeName="SpecifyCultureInfo" Category="Microsoft.Globalization" CheckId="CA1304" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>AmqBrokerInfo.StringEqualsIgnoreCase(String, String):Boolean</Item>
+ <Item>System.String.ToLower</Item>
+ <Item>System.String.ToLower(System.Globalization.CultureInfo)</Item>
+ </Issue>
+ <Issue>
+ <Item>AmqBrokerInfo.StringEqualsIgnoreCase(String, String):Boolean</Item>
+ <Item>System.String.ToLower</Item>
+ <Item>System.String.ToLower(System.Globalization.CultureInfo)</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="ToString():System.String">
+ <Messages>
+ <Message Id="this._transport" TypeName="AvoidUnnecessaryStringCreation" Category="Microsoft.Performance" CheckId="CA1807" Created="2006-12-04 13:11:47Z">
+ <Issue Name="UseStringCompareLocal">
+ <Item>AmqBrokerInfo.ToString():String</Item>
+ <Item>String.Equals(String):Boolean</Item>
+ <Item>this._transport</Item>
+ </Issue>
+ </Message>
+ <Message Id="System.String.ToLower" TypeName="SpecifyCultureInfo" Category="Microsoft.Globalization" CheckId="CA1304" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>AmqBrokerInfo.ToString():String</Item>
+ <Item>System.String.ToLower</Item>
+ <Item>System.String.ToLower(System.Globalization.CultureInfo)</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="URL_FORMAT_EXAMPLE">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>URL_FORMAT_EXAMPLE</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>URL_FORMAT_EXAMPLE</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="AmqChannel">
+ <Messages>
+ <Message Id="Amq" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Type">
+ <Item>Amq</Item>
+ <Item>Qpid.Client.AmqChannel</Item>
+ </Issue>
+ </Message>
+ <Message TypeName="ImplementIDisposableCorrectly" Category="Microsoft.Design" CheckId="CA1063" Created="2006-12-04 13:11:47Z">
+ <Issue Name="ProvideDisposeBool">
+ <Item>Qpid.Client.AmqChannel</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ <Members>
+ <Member Name=".cctor()">
+ <Messages>
+ <Message TypeName="DoNotInitializeUnnecessarily" Category="Microsoft.Performance" CheckId="CA1805" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>AmqChannel.AmqChannel()</Item>
+ <Item>_nextSessionNumber</Item>
+ <Item>System.Int32</Item>
+ <Item>0</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name=".ctor(Qpid.Client.AMQConnection,System.UInt16,System.Boolean,Qpid.Messaging.AcknowledgeMode,Qpid.Client.Message.MessageFactoryRegistry,System.Int32)">
+ <Messages>
+ <Message Id="defaultPrefetch" TypeName="ReviewUnusedParameters" Category="Microsoft.Usage" CheckId="CA1801" Created="2006-12-04 13:11:47Z" FixCategory="NonBreaking">
+ <Issue>
+ <Item>defaultPrefetch</Item>
+ <Item>AmqChannel.AmqChannel(AMQConnection, UInt16, Boolean, AcknowledgeMode, MessageFactoryRegistry, Int32)</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="CheckNotTransacted():System.Void">
+ <Messages>
+ <Message Id="System.InvalidOperationException.#ctor(System.String)" TypeName="DoNotPassLiteralsAsLocalizedParameters" Category="Microsoft.Globalization" CheckId="CA1303" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>AmqChannel.CheckNotTransacted():Void</Item>
+ <Item>1</Item>
+ <Item>InvalidOperationException.InvalidOperationException(String)</Item>
+ <Item>Channel is transacted</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="CheckTransacted():System.Void">
+ <Messages>
+ <Message Id="System.InvalidOperationException.#ctor(System.String)" TypeName="DoNotPassLiteralsAsLocalizedParameters" Category="Microsoft.Globalization" CheckId="CA1303" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>AmqChannel.CheckTransacted():Void</Item>
+ <Item>1</Item>
+ <Item>InvalidOperationException.InvalidOperationException(String)</Item>
+ <Item>Channel is not transacted</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="ClosedWithException(System.Exception):System.Void">
+ <Messages>
+ <Message TypeName="DoNotCastUnnecessarily" Category="Microsoft.Performance" CheckId="CA1800" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>e</Item>
+ <Item>Qpid.AMQException</Item>
+ <Item>AmqChannel.ClosedWithException(Exception):Void</Item>
+ <Item>castclass</Item>
+ </Issue>
+ </Message>
+ <Message Id="Qpid.AMQException.#ctor(System.String,System.Exception)" TypeName="DoNotPassLiteralsAsLocalizedParameters" Category="Microsoft.Globalization" CheckId="CA1303" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>AmqChannel.ClosedWithException(Exception):Void</Item>
+ <Item>1</Item>
+ <Item>AMQException.AMQException(String, Exception)</Item>
+ <Item>Closing session forcibly</Item>
+ </Issue>
+ </Message>
+ <Message Id="0#e" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="ParameterOneLetter">
+ <Item>AmqChannel.ClosedWithException(Exception):Void</Item>
+ <Item>e</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="ConsumeFromQueue(System.String,System.Boolean,System.Boolean,Qpid.Messaging.AcknowledgeMode):System.String">
+ <Messages>
+ <Message Id="System.String.Format(System.String,System.Object,System.Object)" TypeName="SpecifyIFormatProvider" Category="Microsoft.Globalization" CheckId="CA1305" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>AmqChannel.ConsumeFromQueue(String, Boolean, Boolean, AcknowledgeMode):String</Item>
+ <Item>System.String.Format(System.String,System.Object,System.Object)</Item>
+ <Item>System.String.Format(System.IFormatProvider,System.String,System.Object[])</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="CreateConsumer(System.String,System.Int32,System.Int32,System.Boolean,System.Boolean,System.Boolean,System.String):Qpid.Messaging.IMessageConsumer">
+ <Messages>
+ <Message Id="System.String.Format(System.String,System.Object[])" TypeName="SpecifyIFormatProvider" Category="Microsoft.Globalization" CheckId="CA1305" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>AmqChannel.CreateConsumer(String, Int32, Int32, Boolean, Boolean, Boolean, String):IMessageConsumer</Item>
+ <Item>System.String.Format(System.String,System.Object[])</Item>
+ <Item>System.String.Format(System.IFormatProvider,System.String,System.Object[])</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="CreatePublisher(System.String,System.String,Qpid.Messaging.DeliveryMode,System.Int64,System.Boolean,System.Boolean,System.Int32):Qpid.Messaging.IMessagePublisher">
+ <Messages>
+ <Message Id="System.String.Format(System.String,System.Object,System.Object,System.Object)" TypeName="SpecifyIFormatProvider" Category="Microsoft.Globalization" CheckId="CA1305" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>AmqChannel.CreatePublisher(String, String, DeliveryMode, Int64, Boolean, Boolean, Int32):IMessagePublisher</Item>
+ <Item>System.String.Format(System.String,System.Object,System.Object,System.Object)</Item>
+ <Item>System.String.Format(System.IFormatProvider,System.String,System.Object[])</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="CreateTextMessage(System.String):Qpid.Messaging.ITextMessage">
+ <Messages>
+ <Message Id="0#" TypeName="ParameterNamesShouldMatchBaseDeclaration" Category="Microsoft.Naming" CheckId="CA1725" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>text</Item>
+ <Item>AmqChannel.CreateTextMessage(String):ITextMessage</Item>
+ <Item>initialValue</Item>
+ <Item>IChannel.CreateTextMessage(String):ITextMessage</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="DeclareExchange(System.String,System.String):System.Void">
+ <Messages>
+ <Message Id="System.String.Format(System.String,System.Object,System.Object)" TypeName="SpecifyIFormatProvider" Category="Microsoft.Globalization" CheckId="CA1305" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>AmqChannel.DeclareExchange(String, String):Void</Item>
+ <Item>System.String.Format(System.String,System.Object,System.Object)</Item>
+ <Item>System.String.Format(System.IFormatProvider,System.String,System.Object[])</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="DeclareExchange(System.UInt16,System.UInt16,System.String,System.String,System.Boolean,System.Boolean,System.Boolean,System.Boolean,System.Boolean,Qpid.Framing.FieldTable):System.Void">
+ <Messages>
+ <Message Id="System.NotImplementedException.#ctor(System.String)" TypeName="DoNotPassLiteralsAsLocalizedParameters" Category="Microsoft.Globalization" CheckId="CA1303" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>AmqChannel.DeclareExchange(UInt16, UInt16, String, String, Boolean, Boolean, Boolean, Boolean, Boolean, FieldTable):Void</Item>
+ <Item>1</Item>
+ <Item>NotImplementedException.NotImplementedException(String)</Item>
+ <Item>Don't use nowait=false with DeclareExchange</Item>
+ </Issue>
+ </Message>
+ <Message Id="nowait" TypeName="LiteralsShouldBeSpelledCorrectly" Category="Microsoft.Usage" CheckId="CA2204" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>nowait</Item>
+ <Item>Don't use nowait=false with DeclareExchange</Item>
+ </Issue>
+ </Message>
+ <Message Id="System.String.Format(System.String,System.Object,System.Object,System.Object)" TypeName="SpecifyIFormatProvider" Category="Microsoft.Globalization" CheckId="CA1305" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>AmqChannel.DeclareExchange(UInt16, UInt16, String, String, Boolean, Boolean, Boolean, Boolean, Boolean, FieldTable):Void</Item>
+ <Item>System.String.Format(System.String,System.Object,System.Object,System.Object)</Item>
+ <Item>System.String.Format(System.IFormatProvider,System.String,System.Object[])</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Dispose():System.Void">
+ <Messages>
+ <Message TypeName="ImplementIDisposableCorrectly" Category="Microsoft.Design" CheckId="CA1063" Created="2006-12-04 13:11:47Z">
+ <Issue Name="DisposeImplementation">
+ <Item>AmqChannel.Dispose():Void</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="DoBasicPublish(System.String,System.String,System.Boolean,System.Boolean,Qpid.Client.Message.AbstractQmsMessage,Qpid.Messaging.DeliveryMode,System.UInt32,System.Int32,System.Boolean):System.Void">
+ <Messages>
+ <Message Id="System.String.Format(System.String,System.Object,System.Object)" TypeName="SpecifyIFormatProvider" Category="Microsoft.Globalization" CheckId="CA1305" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>AmqChannel.DoBasicPublish(String, String, Boolean, Boolean, AbstractQmsMessage, DeliveryMode, UInt32, Int32, Boolean):Void</Item>
+ <Item>System.String.Format(System.String,System.Object,System.Object)</Item>
+ <Item>System.String.Format(System.IFormatProvider,System.String,System.Object[])</Item>
+ </Issue>
+ <Issue>
+ <Item>AmqChannel.DoBasicPublish(String, String, Boolean, Boolean, AbstractQmsMessage, DeliveryMode, UInt32, Int32, Boolean):Void</Item>
+ <Item>System.String.Format(System.String,System.Object,System.Object)</Item>
+ <Item>System.String.Format(System.IFormatProvider,System.String,System.Object[])</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="DoBind(System.String,System.String,System.String,Qpid.Framing.FieldTable):System.Void">
+ <Messages>
+ <Message Id="System.String.Format(System.String,System.Object[])" TypeName="SpecifyIFormatProvider" Category="Microsoft.Globalization" CheckId="CA1305" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>AmqChannel.DoBind(String, String, String, FieldTable):Void</Item>
+ <Item>System.String.Format(System.String,System.Object[])</Item>
+ <Item>System.String.Format(System.IFormatProvider,System.String,System.Object[])</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="DoQueueDeclare(System.String,System.Boolean,System.Boolean,System.Boolean):System.Void">
+ <Messages>
+ <Message Id="System.String.Format(System.String,System.Object[])" TypeName="SpecifyIFormatProvider" Category="Microsoft.Globalization" CheckId="CA1305" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>AmqChannel.DoQueueDeclare(String, Boolean, Boolean, Boolean):Void</Item>
+ <Item>System.String.Format(System.String,System.Object[])</Item>
+ <Item>System.String.Format(System.IFormatProvider,System.String,System.Object[])</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="ReplayOnFailOver():System.Void">
+ <Messages>
+ <Message Id="System.String.Format(System.String,System.Object)" TypeName="SpecifyIFormatProvider" Category="Microsoft.Globalization" CheckId="CA1305" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>AmqChannel.ReplayOnFailOver():Void</Item>
+ <Item>System.String.Format(System.String,System.Object)</Item>
+ <Item>System.String.Format(System.IFormatProvider,System.String,System.Object[])</Item>
+ </Issue>
+ <Issue>
+ <Item>AmqChannel.ReplayOnFailOver():Void</Item>
+ <Item>System.String.Format(System.String,System.Object)</Item>
+ <Item>System.String.Format(System.IFormatProvider,System.String,System.Object[])</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Run():System.Void">
+ <Messages>
+ <Message TypeName="MarkMembersAsStatic" Category="Microsoft.Performance" CheckId="CA1822" Created="2006-12-04 13:11:47Z" FixCategory="Breaking">
+ <Issue>
+ <Item>AmqChannel.Run():Void</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Unsubscribe(System.String):System.Void">
+ <Messages>
+ <Message Id="0#" TypeName="ParameterNamesShouldMatchBaseDeclaration" Category="Microsoft.Naming" CheckId="CA1725" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>name</Item>
+ <Item>AmqChannel.Unsubscribe(String):Void</Item>
+ <Item>subscriptionName</Item>
+ <Item>IChannel.Unsubscribe(String):Void</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="AmqChannel+Dispatcher">
+ <Members>
+ <Member Name=".ctor(Qpid.Client.AmqChannel)">
+ <Messages>
+ <Message TypeName="DoNotInitializeUnnecessarily" Category="Microsoft.Performance" CheckId="CA1805" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Dispatcher.Dispatcher(AmqChannel)</Item>
+ <Item>_stopped</Item>
+ <Item>System.Int32</Item>
+ <Item>0</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="DispatchMessage(Qpid.Client.Message.UnprocessedMessage):System.Void">
+ <Messages>
+ <Message TypeName="DoNotCatchGeneralExceptionTypes" Category="Microsoft.Design" CheckId="CA1031" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Dispatcher.DispatchMessage(UnprocessedMessage):Void</Item>
+ <Item>System.Exception</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="AMQConnection">
+ <Messages>
+ <Message TypeName="ImplementIDisposableCorrectly" Category="Microsoft.Design" CheckId="CA1063" Created="2006-12-04 13:11:47Z">
+ <Issue Name="ProvideDisposeBool">
+ <Item>Qpid.Client.AMQConnection</Item>
+ </Issue>
+ </Message>
+ <Message TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Type">
+ <Item>AMQConnection</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ <Members>
+ <Member Name=".ctor(Qpid.Client.qms.ConnectionInfo)">
+ <Messages>
+ <Message TypeName="DoNotCatchGeneralExceptionTypes" Category="Microsoft.Design" CheckId="CA1031" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>AMQConnection.AMQConnection(ConnectionInfo)</Item>
+ <Item>System.Exception</Item>
+ </Issue>
+ </Message>
+ <Message TypeName="DoNotInitializeUnnecessarily" Category="Microsoft.Performance" CheckId="CA1805" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>AMQConnection.AMQConnection(ConnectionInfo)</Item>
+ <Item>_connected</Item>
+ <Item>System.Boolean</Item>
+ <Item>false</Item>
+ </Issue>
+ <Issue>
+ <Item>AMQConnection.AMQConnection(ConnectionInfo)</Item>
+ <Item>_lastAMQException</Item>
+ <Item>Qpid.AMQException</Item>
+ <Item>null</Item>
+ </Issue>
+ <Issue>
+ <Item>AMQConnection.AMQConnection(ConnectionInfo)</Item>
+ <Item>_nextChannelId</Item>
+ <Item>System.Int32</Item>
+ <Item>0</Item>
+ </Issue>
+ </Message>
+ <Message Id="Qpid.Client.AMQConnectionException.#ctor(System.String,System.Exception)" TypeName="DoNotPassLiteralsAsLocalizedParameters" Category="Microsoft.Globalization" CheckId="CA1303" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>AMQConnection.AMQConnection(ConnectionInfo)</Item>
+ <Item>1</Item>
+ <Item>AMQConnectionException.AMQConnectionException(String, Exception)</Item>
+ <Item>Unable to connect</Item>
+ </Issue>
+ </Message>
+ <Message Id="System.ArgumentException.#ctor(System.String)" TypeName="DoNotPassLiteralsAsLocalizedParameters" Category="Microsoft.Globalization" CheckId="CA1303" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>AMQConnection.AMQConnection(ConnectionInfo)</Item>
+ <Item>1</Item>
+ <Item>ArgumentException.ArgumentException(String)</Item>
+ <Item>ConnectionInfo must be specified</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="AttemptReconnection():System.Boolean">
+ <Messages>
+ <Message TypeName="DoNotCatchGeneralExceptionTypes" Category="Microsoft.Design" CheckId="CA1031" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>AMQConnection.AttemptReconnection():Boolean</Item>
+ <Item>System.Exception</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="AttemptReconnection(System.String,System.Int32,System.Boolean):System.Boolean">
+ <Messages>
+ <Message TypeName="DoNotCatchGeneralExceptionTypes" Category="Microsoft.Design" CheckId="CA1031" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>AMQConnection.AttemptReconnection(String, Int32, Boolean):Boolean</Item>
+ <Item>System.Exception</Item>
+ </Issue>
+ </Message>
+ <Message Id="2#" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>useSSL</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="CloseSession(Qpid.Client.AmqChannel):System.Void">
+ <Messages>
+ <Message TypeName="ValidateArgumentsOfPublicMethods" Category="Microsoft.Design" CheckId="CA1062" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>'channel'</Item>
+ <Item>AMQConnection.CloseSession(AmqChannel):Void</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Dispose():System.Void">
+ <Messages>
+ <Message TypeName="ImplementIDisposableCorrectly" Category="Microsoft.Design" CheckId="CA1063" Created="2006-12-04 13:11:47Z">
+ <Issue Name="DisposeImplementation">
+ <Item>AMQConnection.Dispose():Void</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="ExceptionReceived(System.Exception):System.Void">
+ <Messages>
+ <Message TypeName="DoNotCastUnnecessarily" Category="Microsoft.Performance" CheckId="CA1800" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>cause</Item>
+ <Item>Qpid.Messaging.QpidException</Item>
+ <Item>AMQConnection.ExceptionReceived(Exception):Void</Item>
+ <Item>castclass</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="FireFailoverComplete():System.Void">
+ <Messages>
+ <Message TypeName="UseEventsWhereAppropriate" Category="Microsoft.Design" CheckId="CA1030" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>FireFailoverComplete</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="FirePreFailover(System.Boolean):System.Boolean">
+ <Messages>
+ <Message TypeName="UseEventsWhereAppropriate" Category="Microsoft.Design" CheckId="CA1030" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>FirePreFailover</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="FirePreResubscribe():System.Boolean">
+ <Messages>
+ <Message Id="Resubscribe" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>Resubscribe</Item>
+ <Item>AMQConnection.FirePreResubscribe():Boolean</Item>
+ </Issue>
+ </Message>
+ <Message TypeName="UseEventsWhereAppropriate" Category="Microsoft.Design" CheckId="CA1030" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>FirePreResubscribe</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="LoadTransportFromAssembly(System.String,System.Int32,System.String,System.String):Qpid.Client.Transport.ITransport">
+ <Messages>
+ <Message Id="System.String.Format(System.String,System.Object)" TypeName="SpecifyIFormatProvider" Category="Microsoft.Globalization" CheckId="CA1305" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>AMQConnection.LoadTransportFromAssembly(String, Int32, String, String):ITransport</Item>
+ <Item>System.String.Format(System.String,System.Object)</Item>
+ <Item>System.String.Format(System.IFormatProvider,System.String,System.Object[])</Item>
+ </Issue>
+ </Message>
+ <Message Id="System.String.Format(System.String,System.Object,System.Object)" TypeName="SpecifyIFormatProvider" Category="Microsoft.Globalization" CheckId="CA1305" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>AMQConnection.LoadTransportFromAssembly(String, Int32, String, String):ITransport</Item>
+ <Item>System.String.Format(System.String,System.Object,System.Object)</Item>
+ <Item>System.String.Format(System.IFormatProvider,System.String,System.Object[])</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="MakeBrokerConnection(Qpid.Client.qms.BrokerInfo):System.Void">
+ <Messages>
+ <Message TypeName="RethrowToPreserveStackDetails" Category="Microsoft.Usage" CheckId="CA2200" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>AMQConnection.MakeBrokerConnection(BrokerInfo):Void</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="ReopenChannel(System.UInt16,System.UInt16,System.Boolean):System.Void">
+ <Messages>
+ <Message Id="Qpid.AMQException.#ctor(System.String)" TypeName="DoNotPassLiteralsAsLocalizedParameters" Category="Microsoft.Globalization" CheckId="CA1303" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>AMQConnection.ReopenChannel(UInt16, UInt16, Boolean):Void</Item>
+ <Item>1</Item>
+ <Item>AMQException.AMQException(String)</Item>
+ <Item>Error reopening channel ____ after failover: __</Item>
+ </Issue>
+ </Message>
+ <Message Id="System.String.Format(System.String,System.Object,System.Object,System.Object)" TypeName="SpecifyIFormatProvider" Category="Microsoft.Globalization" CheckId="CA1305" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>AMQConnection.ReopenChannel(UInt16, UInt16, Boolean):Void</Item>
+ <Item>System.String.Format(System.String,System.Object,System.Object,System.Object)</Item>
+ <Item>System.String.Format(System.IFormatProvider,System.String,System.Object[])</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="ResubscribeChannels():System.Void">
+ <Messages>
+ <Message Id="Resubscribe" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>Resubscribe</Item>
+ <Item>AMQConnection.ResubscribeChannels():Void</Item>
+ </Issue>
+ </Message>
+ <Message Id="System.String.Format(System.String,System.Object,System.Object)" TypeName="SpecifyIFormatProvider" Category="Microsoft.Globalization" CheckId="CA1305" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>AMQConnection.ResubscribeChannels():Void</Item>
+ <Item>System.String.Format(System.String,System.Object,System.Object)</Item>
+ <Item>System.String.Format(System.IFormatProvider,System.String,System.Object[])</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="StartHeartBeatThread(System.Int32):System.Void">
+ <Messages>
+ <Message Id="HeartBeat" TypeName="CompoundWordsShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1702" Created="2006-12-04 13:11:47Z">
+ <Issue Name="ShouldBeDiscreteTerm">
+ <Item>HeartBeat</Item>
+ <Item>method</Item>
+ <Item>StartHeartBeatThread</Item>
+ <Item>Heartbeat</Item>
+ </Issue>
+ </Message>
+ <Message Id="heartbeatSeconds*1000" TypeName="OperationsShouldNotOverflow" Category="Microsoft.Usage" CheckId="CA2233" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>heartbeatSeconds*1000</Item>
+ <Item>AMQConnection.StartHeartBeatThread(Int32):Void</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="StopHeartBeatThread():System.Void">
+ <Messages>
+ <Message Id="HeartBeat" TypeName="CompoundWordsShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1702" Created="2006-12-04 13:11:47Z">
+ <Issue Name="ShouldBeDiscreteTerm">
+ <Item>HeartBeat</Item>
+ <Item>method</Item>
+ <Item>StopHeartBeatThread</Item>
+ <Item>Heartbeat</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="toURL():System.String">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>toURL</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>AMQConnection.toURL():String</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Username">
+ <Messages>
+ <Message Id="Username" TypeName="CompoundWordsShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1702" Created="2006-12-04 13:11:47Z">
+ <Issue Name="ShouldBeCompoundWord">
+ <Item>Username</Item>
+ <Item>property</Item>
+ <Item>Username</Item>
+ <Item>UserName</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="AMQConnectionException">
+ <Messages>
+ <Message TypeName="ImplementStandardExceptionConstructors" Category="Microsoft.Design" CheckId="CA1032" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Qpid.Client.AMQConnectionException</Item>
+ <Item>protected AMQConnectionException(SerializationInfo, StreamingContext)</Item>
+ </Issue>
+ <Issue>
+ <Item>Qpid.Client.AMQConnectionException</Item>
+ <Item>public AMQConnectionException()</Item>
+ </Issue>
+ <Issue>
+ <Item>Qpid.Client.AMQConnectionException</Item>
+ <Item>public AMQConnectionException(String)</Item>
+ </Issue>
+ </Message>
+ <Message TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Type">
+ <Item>AMQConnectionException</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ <Members>
+ <Member Name=".ctor(System.String,System.Exception)">
+ <Messages>
+ <Message Id="1#e" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="ParameterOneLetter">
+ <Item>AMQConnectionException.AMQConnectionException(String, Exception)</Item>
+ <Item>e</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="AMQDestination">
+ <Messages>
+ <Message TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Type">
+ <Item>AMQDestination</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ <Members>
+ <Member Name="_destinationName">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>_destinationName</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>_destinationName</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="_exchangeClass">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>_exchangeClass</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>_exchangeClass</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="_exchangeName">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>_exchangeName</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>_exchangeName</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="_isAutoDelete">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>_isAutoDelete</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>_isAutoDelete</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="_isDurable">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>_isDurable</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>_isDurable</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="_isExclusive">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>_isExclusive</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>_isExclusive</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="_queueName">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>_queueName</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>_queueName</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Equals(System.Object):System.Boolean">
+ <Messages>
+ <Message Id="0#" TypeName="ParameterNamesShouldMatchBaseDeclaration" Category="Microsoft.Naming" CheckId="CA1725" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>o</Item>
+ <Item>AMQDestination.Equals(Object):Boolean</Item>
+ <Item>obj</Item>
+ <Item>Object.Equals(Object):Boolean</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="StringsNotEqualNullSafe(System.String,System.String):System.Boolean">
+ <Messages>
+ <Message TypeName="MarkMembersAsStatic" Category="Microsoft.Performance" CheckId="CA1822" Created="2006-12-04 13:11:47Z" FixCategory="NonBreaking">
+ <Issue>
+ <Item>AMQDestination.StringsNotEqualNullSafe(String, String):Boolean</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="BasicMessageConsumer">
+ <Messages>
+ <Message TypeName="ImplementIDisposableCorrectly" Category="Microsoft.Design" CheckId="CA1063" Created="2006-12-04 13:11:47Z">
+ <Issue Name="ProvideDisposeBool">
+ <Item>Qpid.Client.BasicMessageConsumer</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ <Members>
+ <Member Name="Dispose():System.Void">
+ <Messages>
+ <Message TypeName="ImplementIDisposableCorrectly" Category="Microsoft.Design" CheckId="CA1063" Created="2006-12-04 13:11:47Z">
+ <Issue Name="DisposeImplementation">
+ <Item>BasicMessageConsumer.Dispose():Void</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="NotifyMessage(Qpid.Client.Message.UnprocessedMessage,System.Int32):System.Void">
+ <Messages>
+ <Message TypeName="DoNotCatchGeneralExceptionTypes" Category="Microsoft.Design" CheckId="CA1031" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>BasicMessageConsumer.NotifyMessage(UnprocessedMessage, Int32):Void</Item>
+ <Item>System.Exception</Item>
+ </Issue>
+ </Message>
+ <Message Id="channelId" TypeName="ReviewUnusedParameters" Category="Microsoft.Usage" CheckId="CA1801" Created="2006-12-04 13:11:47Z" FixCategory="NonBreaking">
+ <Issue>
+ <Item>channelId</Item>
+ <Item>BasicMessageConsumer.NotifyMessage(UnprocessedMessage, Int32):Void</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="OnMessage">
+ <Accessors>
+ <Accessor Name="set_OnMessage(Qpid.Messaging.MessageReceivedDelegate):System.Void">
+ <Messages>
+ <Message Id="System.InvalidOperationException.#ctor(System.String)" TypeName="DoNotPassLiteralsAsLocalizedParameters" Category="Microsoft.Globalization" CheckId="CA1303" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>BasicMessageConsumer.set_OnMessage(MessageReceivedDelegate):Void</Item>
+ <Item>1</Item>
+ <Item>InvalidOperationException.InvalidOperationException(String)</Item>
+ <Item>Another thread is already receiving...</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Accessor>
+ </Accessors>
+ </Member>
+ <Member Name="Receive(System.Int64):Qpid.Messaging.IMessage">
+ <Messages>
+ <Message Id="System.InvalidOperationException.#ctor(System.String)" TypeName="DoNotPassLiteralsAsLocalizedParameters" Category="Microsoft.Globalization" CheckId="CA1303" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>BasicMessageConsumer.Receive(Int64):IMessage</Item>
+ <Item>1</Item>
+ <Item>InvalidOperationException.InvalidOperationException(String)</Item>
+ <Item>Another thread is already receiving (possibly asynchronously)...</Item>
+ </Issue>
+ </Message>
+ <Message Id="System.NotImplementedException.#ctor(System.String)" TypeName="DoNotPassLiteralsAsLocalizedParameters" Category="Microsoft.Globalization" CheckId="CA1303" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>BasicMessageConsumer.Receive(Int64):IMessage</Item>
+ <Item>1</Item>
+ <Item>NotImplementedException.NotImplementedException(String)</Item>
+ <Item>Need to implement synchronousQueue.Poll(timeout</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="ReceiveNoWait():Qpid.Messaging.IMessage">
+ <Messages>
+ <Message Id="System.InvalidOperationException.#ctor(System.String)" TypeName="DoNotPassLiteralsAsLocalizedParameters" Category="Microsoft.Globalization" CheckId="CA1303" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>BasicMessageConsumer.ReceiveNoWait():IMessage</Item>
+ <Item>1</Item>
+ <Item>InvalidOperationException.InvalidOperationException(String)</Item>
+ <Item>Another thread is already receiving (possibly asynchronously)...</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="ReturnMessageOrThrow(System.Object):Qpid.Messaging.IMessage">
+ <Messages>
+ <Message TypeName="DoNotCastUnnecessarily" Category="Microsoft.Performance" CheckId="CA1800" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>o</Item>
+ <Item>System.Exception</Item>
+ <Item>BasicMessageConsumer.ReturnMessageOrThrow(Object):IMessage</Item>
+ <Item>castclass</Item>
+ </Issue>
+ </Message>
+ <Message TypeName="MarkMembersAsStatic" Category="Microsoft.Performance" CheckId="CA1822" Created="2006-12-04 13:11:47Z" FixCategory="NonBreaking">
+ <Issue>
+ <Item>BasicMessageConsumer.ReturnMessageOrThrow(Object):IMessage</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="BasicMessageProducer">
+ <Messages>
+ <Message TypeName="ImplementIDisposableCorrectly" Category="Microsoft.Design" CheckId="CA1063" Created="2006-12-04 13:11:47Z">
+ <Issue Name="ProvideDisposeBool">
+ <Item>Qpid.Client.BasicMessageProducer</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ <Members>
+ <Member Name=".ctor(System.String,System.String,System.Boolean,System.UInt16,Qpid.Client.AmqChannel,System.Int64,Qpid.Messaging.DeliveryMode,System.Int64,System.Boolean,System.Boolean,System.Int32)">
+ <Messages>
+ <Message TypeName="ValidateArgumentsOfPublicMethods" Category="Microsoft.Design" CheckId="CA1062" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>'channel'</Item>
+ <Item>BasicMessageProducer.BasicMessageProducer(String, String, Boolean, UInt16, AmqChannel, Int64, DeliveryMode, Int64, Boolean, Boolean, Int32)</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="_channelId">
+ <Messages>
+ <Message TypeName="AvoidUnusedPrivateFields" Category="Microsoft.Performance" CheckId="CA1823" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>BasicMessageProducer._channelId</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="_encoding">
+ <Messages>
+ <Message TypeName="AvoidUnusedPrivateFields" Category="Microsoft.Performance" CheckId="CA1823" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>BasicMessageProducer._encoding</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="_immediate">
+ <Messages>
+ <Message TypeName="AvoidUnusedPrivateFields" Category="Microsoft.Performance" CheckId="CA1823" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>BasicMessageProducer._immediate</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="_logger">
+ <Messages>
+ <Message TypeName="DoNotDeclareReadOnlyMutableReferenceTypes" Category="Microsoft.Security" CheckId="CA2104" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>BasicMessageProducer._logger</Item>
+ <Item>log4net.ILog</Item>
+ </Issue>
+ </Message>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>_logger</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>_logger</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="_mandatory">
+ <Messages>
+ <Message TypeName="AvoidUnusedPrivateFields" Category="Microsoft.Performance" CheckId="CA1823" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>BasicMessageProducer._mandatory</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="_mimeType">
+ <Messages>
+ <Message TypeName="AvoidUnusedPrivateFields" Category="Microsoft.Performance" CheckId="CA1823" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>BasicMessageProducer._mimeType</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="_transacted">
+ <Messages>
+ <Message TypeName="AvoidUnusedPrivateFields" Category="Microsoft.Performance" CheckId="CA1823" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>BasicMessageProducer._transacted</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="DEFAULT_IMMEDIATE">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>DEFAULT_IMMEDIATE</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>BasicMessageProducer.DEFAULT_IMMEDIATE</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="DEFAULT_MANDATORY">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>DEFAULT_MANDATORY</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>BasicMessageProducer.DEFAULT_MANDATORY</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="DisableMessageID">
+ <Accessors>
+ <Accessor Name="get_DisableMessageID():System.Boolean">
+ <Messages>
+ <Message Id="System.Exception.#ctor(System.String)" TypeName="DoNotPassLiteralsAsLocalizedParameters" Category="Microsoft.Globalization" CheckId="CA1303" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>BasicMessageProducer.get_DisableMessageID():Boolean</Item>
+ <Item>1</Item>
+ <Item>Exception.Exception(String)</Item>
+ <Item>The method or operation is not implemented.</Item>
+ </Issue>
+ </Message>
+ <Message TypeName="DoNotRaiseReservedExceptionTypes" Category="Microsoft.Usage" CheckId="CA2201" Created="2006-12-04 13:11:47Z">
+ <Issue Name="TooGeneric">
+ <Item>BasicMessageProducer.get_DisableMessageID():Boolean</Item>
+ <Item>System.Exception</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Accessor>
+ <Accessor Name="set_DisableMessageID(System.Boolean):System.Void">
+ <Messages>
+ <Message Id="System.Exception.#ctor(System.String)" TypeName="DoNotPassLiteralsAsLocalizedParameters" Category="Microsoft.Globalization" CheckId="CA1303" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>BasicMessageProducer.set_DisableMessageID(Boolean):Void</Item>
+ <Item>1</Item>
+ <Item>Exception.Exception(String)</Item>
+ <Item>The method or operation is not implemented.</Item>
+ </Issue>
+ </Message>
+ <Message TypeName="DoNotRaiseReservedExceptionTypes" Category="Microsoft.Usage" CheckId="CA2201" Created="2006-12-04 13:11:47Z">
+ <Issue Name="TooGeneric">
+ <Item>BasicMessageProducer.set_DisableMessageID(Boolean):Void</Item>
+ <Item>System.Exception</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Accessor>
+ </Accessors>
+ </Member>
+ <Member Name="Dispose():System.Void">
+ <Messages>
+ <Message TypeName="ImplementIDisposableCorrectly" Category="Microsoft.Design" CheckId="CA1063" Created="2006-12-04 13:11:47Z">
+ <Issue Name="DisposeImplementation">
+ <Item>BasicMessageProducer.Dispose():Void</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Encoding">
+ <Messages>
+ <Message TypeName="PropertiesShouldNotBeWriteOnly" Category="Microsoft.Design" CheckId="CA1044" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Encoding</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="MimeType">
+ <Messages>
+ <Message TypeName="PropertiesShouldNotBeWriteOnly" Category="Microsoft.Design" CheckId="CA1044" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>MimeType</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Priority">
+ <Accessors>
+ <Accessor Name="set_Priority(System.Int32):System.Void">
+ <Messages>
+ <Message TypeName="InstantiateArgumentExceptionsCorrectly" Category="Microsoft.Usage" CheckId="CA2208" Created="2006-12-04 13:11:47Z">
+ <Issue Name="OneArgumentShouldBeParameterName">
+ <Item>System.ArgumentOutOfRangeException</Item>
+ <Item>ArgumentOutOfRangeException.ArgumentOutOfRangeException(String)</Item>
+ <Item>Priority of ____ is illegal. Value must be in range 0 to 9</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Accessor>
+ </Accessors>
+ </Member>
+ <Member Name="TimeToLive">
+ <Accessors>
+ <Accessor Name="set_TimeToLive(System.Int64):System.Void">
+ <Messages>
+ <Message TypeName="InstantiateArgumentExceptionsCorrectly" Category="Microsoft.Usage" CheckId="CA2208" Created="2006-12-04 13:11:47Z">
+ <Issue Name="OneArgumentShouldBeParameterName">
+ <Item>System.ArgumentOutOfRangeException</Item>
+ <Item>ArgumentOutOfRangeException.ArgumentOutOfRangeException(String)</Item>
+ <Item>Time to live must be non-negative - supplied value was __</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Accessor>
+ </Accessors>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="Closeable">
+ <Messages>
+ <Message TypeName="IdentifiersShouldDifferByMoreThanCase" Category="Microsoft.Naming" CheckId="CA1708" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>'CLOSED'</Item>
+ <Item>Closed</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ <Members>
+ <Member Name="_closed">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>_closed</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>_closed</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="_closingLock">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>_closingLock</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>_closingLock</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="CheckNotClosed():System.Void">
+ <Messages>
+ <Message Id="System.InvalidOperationException.#ctor(System.String)" TypeName="DoNotPassLiteralsAsLocalizedParameters" Category="Microsoft.Globalization" CheckId="CA1303" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Closeable.CheckNotClosed():Void</Item>
+ <Item>1</Item>
+ <Item>InvalidOperationException.InvalidOperationException(String)</Item>
+ <Item>Object ____ has been closed</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="CLOSED">
+ <Messages>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>Closeable.CLOSED</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="NOT_CLOSED">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>NOT_CLOSED</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>Closeable.NOT_CLOSED</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="ConnectionTuneParameters">
+ <Members>
+ <Member Name="TxnLimit">
+ <Messages>
+ <Message Id="Txn" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>Txn</Item>
+ <Item>ConnectionTuneParameters.TxnLimit:UInt32</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="QpidConnectionInfo">
+ <Messages>
+ <Message Id="Qpid" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Type">
+ <Item>Qpid</Item>
+ <Item>Qpid.Client.QpidConnectionInfo</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ <Members>
+ <Member Name=".ctor()">
+ <Messages>
+ <Message TypeName="DoNotInitializeUnnecessarily" Category="Microsoft.Performance" CheckId="CA1805" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>QpidConnectionInfo.QpidConnectionInfo()</Item>
+ <Item>_failoverMethod</Item>
+ <Item>System.String</Item>
+ <Item>null</Item>
+ </Issue>
+ </Message>
+ <Message Id="System.String.Format(System.String,System.Object,System.Object)" TypeName="SpecifyIFormatProvider" Category="Microsoft.Globalization" CheckId="CA1305" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>QpidConnectionInfo.QpidConnectionInfo()</Item>
+ <Item>System.String.Format(System.String,System.Object,System.Object)</Item>
+ <Item>System.String.Format(System.IFormatProvider,System.String,System.Object[])</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="_logger">
+ <Messages>
+ <Message TypeName="AvoidUnusedPrivateFields" Category="Microsoft.Performance" CheckId="CA1823" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>QpidConnectionInfo._logger</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="AddBrokerInfo(Qpid.Client.qms.BrokerInfo):System.Void">
+ <Messages>
+ <Message Id="0#" TypeName="ParameterNamesShouldMatchBaseDeclaration" Category="Microsoft.Naming" CheckId="CA1725" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>brokerInfo</Item>
+ <Item>QpidConnectionInfo.AddBrokerInfo(BrokerInfo):Void</Item>
+ <Item>broker</Item>
+ <Item>ConnectionInfo.AddBrokerInfo(BrokerInfo):Void</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="AsUrl():System.String">
+ <Messages>
+ <Message TypeName="DoNotConcatenateStringsInsideLoops" Category="Microsoft.Performance" CheckId="CA1818" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>QpidConnectionInfo.AsUrl():String</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="FromUrl(System.String):Qpid.Client.qms.ConnectionInfo">
+ <Messages>
+ <Message Id="0#" TypeName="UriParametersShouldNotBeStrings" Category="Microsoft.Design" CheckId="CA1054" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>url</Item>
+ <Item>QpidConnectionInfo.FromUrl(String):ConnectionInfo</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="QpidConnectionUrl">
+ <Messages>
+ <Message Id="Qpid" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Type">
+ <Item>Qpid</Item>
+ <Item>Qpid.Client.QpidConnectionUrl</Item>
+ </Issue>
+ </Message>
+ <Message TypeName="StaticHolderTypesShouldNotHaveConstructors" Category="Microsoft.Design" CheckId="CA1053" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>QpidConnectionUrl</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ <Members>
+ <Member Name="FromUri(System.Uri):Qpid.Client.qms.ConnectionInfo">
+ <Messages>
+ <Message TypeName="AvoidUncalledPrivateCode" Category="Microsoft.Performance" CheckId="CA1811" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>QpidConnectionUrl.FromUri(Uri):ConnectionInfo</Item>
+ </Issue>
+ </Message>
+ <Message Id="uri" TypeName="ReviewUnusedParameters" Category="Microsoft.Usage" CheckId="CA1801" Created="2006-12-04 13:11:47Z" FixCategory="NonBreaking">
+ <Issue>
+ <Item>uri</Item>
+ <Item>QpidConnectionUrl.FromUri(Uri):ConnectionInfo</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="FromUrl(System.String):Qpid.Client.qms.ConnectionInfo">
+ <Messages>
+ <Message Id="url" TypeName="ReviewUnusedParameters" Category="Microsoft.Usage" CheckId="CA1801" Created="2006-12-04 13:11:47Z" FixCategory="NonBreaking">
+ <Issue>
+ <Item>url</Item>
+ <Item>QpidConnectionUrl.FromUrl(String):ConnectionInfo</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ </Types>
+ </Namespace>
+ <Namespace Name="Qpid.Client.Failover">
+ <Types>
+ <Type Name="FailoverException">
+ <Messages>
+ <Message TypeName="ExceptionsShouldBePublic" Category="Microsoft.Design" CheckId="CA1064" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Qpid.Client.Failover.FailoverException</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Type>
+ <Type Name="FailoverHandler">
+ <Messages>
+ <Message TypeName="TypesThatOwnDisposableFieldsShouldBeDisposable" Category="Microsoft.Design" CheckId="CA1001" Created="2006-12-04 13:11:47Z" FixCategory="Breaking">
+ <Issue>
+ <Item>Qpid.Client.Failover.FailoverHandler</Item>
+ <Item>System.Threading.ManualResetEvent</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ <Members>
+ <Member Name="getHost():System.String">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>getHost</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="getPort():System.Int32">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>getPort</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Run():System.Void">
+ <Messages>
+ <Message TypeName="DoNotCatchGeneralExceptionTypes" Category="Microsoft.Design" CheckId="CA1031" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>FailoverHandler.Run():Void</Item>
+ <Item>System.Exception</Item>
+ </Issue>
+ <Issue>
+ <Item>FailoverHandler.Run():Void</Item>
+ <Item>System.Exception</Item>
+ </Issue>
+ </Message>
+ <Message Id="Qpid.AMQDisconnectedException.#ctor(System.String)" TypeName="DoNotPassLiteralsAsLocalizedParameters" Category="Microsoft.Globalization" CheckId="CA1303" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>FailoverHandler.Run():Void</Item>
+ <Item>1</Item>
+ <Item>AMQDisconnectedException.AMQDisconnectedException(String)</Item>
+ <Item>Redirect was vetoed by client</Item>
+ </Issue>
+ <Issue>
+ <Item>FailoverHandler.Run():Void</Item>
+ <Item>1</Item>
+ <Item>AMQDisconnectedException.AMQDisconnectedException(String)</Item>
+ <Item>Server closed connection and no failover was successful</Item>
+ </Issue>
+ </Message>
+ <Message Id="Qpid.Client.Failover.FailoverException.#ctor(System.String)" TypeName="DoNotPassLiteralsAsLocalizedParameters" Category="Microsoft.Globalization" CheckId="CA1303" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>FailoverHandler.Run():Void</Item>
+ <Item>1</Item>
+ <Item>FailoverException.FailoverException(String)</Item>
+ <Item>Failing over about to start</Item>
+ </Issue>
+ </Message>
+ <Message Id="System.InvalidOperationException.#ctor(System.String)" TypeName="DoNotPassLiteralsAsLocalizedParameters" Category="Microsoft.Globalization" CheckId="CA1303" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>FailoverHandler.Run():Void</Item>
+ <Item>1</Item>
+ <Item>InvalidOperationException.InvalidOperationException(String)</Item>
+ <Item>FailoverHandler must Run on a non-background thread.</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="setHost(System.String):System.Void">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>setHost</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="setPort(System.Int32):System.Void">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>setPort</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="FailoverSupport">
+ <Members>
+ <Member Name="execute(Qpid.Client.AMQConnection):System.Object">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>execute</Item>
+ </Issue>
+ </Message>
+ <Message TypeName="ValidateArgumentsOfPublicMethods" Category="Microsoft.Design" CheckId="CA1062" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>'con'</Item>
+ <Item>FailoverSupport.execute(AMQConnection):Object</Item>
+ </Issue>
+ <Issue>
+ <Item>'con'</Item>
+ <Item>FailoverSupport.execute(AMQConnection):Object</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="operation():System.Object">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>operation</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ </Types>
+ </Namespace>
+ <Namespace Name="Qpid.Client.Handler">
+ <Types>
+ <Type Name="BasicDeliverMethodHandler">
+ <Members>
+ <Member Name="MethodReceived(Qpid.Client.State.AMQStateManager,Qpid.Client.Protocol.AMQMethodEvent):System.Void">
+ <Messages>
+ <Message TypeName="ValidateArgumentsOfPublicMethods" Category="Microsoft.Design" CheckId="CA1062" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>'evt'</Item>
+ <Item>BasicDeliverMethodHandler.MethodReceived(AMQStateManager, AMQMethodEvent):Void</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="BasicReturnMethodHandler">
+ <Members>
+ <Member Name="MethodReceived(Qpid.Client.State.AMQStateManager,Qpid.Client.Protocol.AMQMethodEvent):System.Void">
+ <Messages>
+ <Message TypeName="ValidateArgumentsOfPublicMethods" Category="Microsoft.Design" CheckId="CA1062" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>'evt'</Item>
+ <Item>BasicReturnMethodHandler.MethodReceived(AMQStateManager, AMQMethodEvent):Void</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="ChannelCloseMethodHandler">
+ <Members>
+ <Member Name="MethodReceived(Qpid.Client.State.AMQStateManager,Qpid.Client.Protocol.AMQMethodEvent):System.Void">
+ <Messages>
+ <Message Id="Qpid.AMQChannelClosedException.#ctor(System.Int32,System.String)" TypeName="DoNotPassLiteralsAsLocalizedParameters" Category="Microsoft.Globalization" CheckId="CA1303" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>ChannelCloseMethodHandler.MethodReceived(AMQStateManager, AMQMethodEvent):Void</Item>
+ <Item>2</Item>
+ <Item>AMQChannelClosedException.AMQChannelClosedException(Int32, String)</Item>
+ <Item>Error: __</Item>
+ </Issue>
+ </Message>
+ <Message TypeName="ValidateArgumentsOfPublicMethods" Category="Microsoft.Design" CheckId="CA1062" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>'evt'</Item>
+ <Item>ChannelCloseMethodHandler.MethodReceived(AMQStateManager, AMQMethodEvent):Void</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="ConnectionCloseMethodHandler">
+ <Members>
+ <Member Name="MethodReceived(Qpid.Client.State.AMQStateManager,Qpid.Client.Protocol.AMQMethodEvent):System.Void">
+ <Messages>
+ <Message Id="Qpid.AMQConnectionClosedException.#ctor(System.Int32,System.String)" TypeName="DoNotPassLiteralsAsLocalizedParameters" Category="Microsoft.Globalization" CheckId="CA1303" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>ConnectionCloseMethodHandler.MethodReceived(AMQStateManager, AMQMethodEvent):Void</Item>
+ <Item>2</Item>
+ <Item>AMQConnectionClosedException.AMQConnectionClosedException(Int32, String)</Item>
+ <Item>Error: __</Item>
+ </Issue>
+ </Message>
+ <Message TypeName="ValidateArgumentsOfPublicMethods" Category="Microsoft.Design" CheckId="CA1062" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>'evt'</Item>
+ <Item>ConnectionCloseMethodHandler.MethodReceived(AMQStateManager, AMQMethodEvent):Void</Item>
+ </Issue>
+ <Issue>
+ <Item>'stateManager'</Item>
+ <Item>ConnectionCloseMethodHandler.MethodReceived(AMQStateManager, AMQMethodEvent):Void</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="ConnectionCloseOkHandler">
+ <Members>
+ <Member Name="MethodReceived(Qpid.Client.State.AMQStateManager,Qpid.Client.Protocol.AMQMethodEvent):System.Void">
+ <Messages>
+ <Message Id="method" TypeName="RemoveUnusedLocals" Category="Microsoft.Performance" CheckId="CA1804" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>ConnectionCloseOkHandler.MethodReceived(AMQStateManager, AMQMethodEvent):Void</Item>
+ <Item>method</Item>
+ <Item>Qpid.Framing.ConnectionCloseOkBody</Item>
+ </Issue>
+ </Message>
+ <Message TypeName="ValidateArgumentsOfPublicMethods" Category="Microsoft.Design" CheckId="CA1062" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>'evt'</Item>
+ <Item>ConnectionCloseOkHandler.MethodReceived(AMQStateManager, AMQMethodEvent):Void</Item>
+ </Issue>
+ <Issue>
+ <Item>'stateManager'</Item>
+ <Item>ConnectionCloseOkHandler.MethodReceived(AMQStateManager, AMQMethodEvent):Void</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="ConnectionOpenOkMethodHandler">
+ <Members>
+ <Member Name="MethodReceived(Qpid.Client.State.AMQStateManager,Qpid.Client.Protocol.AMQMethodEvent):System.Void">
+ <Messages>
+ <Message TypeName="ValidateArgumentsOfPublicMethods" Category="Microsoft.Design" CheckId="CA1062" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>'stateManager'</Item>
+ <Item>ConnectionOpenOkMethodHandler.MethodReceived(AMQStateManager, AMQMethodEvent):Void</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="ConnectionRedirectMethodHandler">
+ <Members>
+ <Member Name="_logger">
+ <Messages>
+ <Message TypeName="AvoidUnusedPrivateFields" Category="Microsoft.Performance" CheckId="CA1823" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>ConnectionRedirectMethodHandler._logger</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="GetInstance():Qpid.Client.Handler.ConnectionRedirectMethodHandler">
+ <Messages>
+ <Message TypeName="UsePropertiesWhereAppropriate" Category="Microsoft.Design" CheckId="CA1024" Created="2006-12-04 13:11:47Z">
+ <Issue Certainty="50">
+ <Item>GetInstance</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="ConnectionSecureMethodHandler">
+ <Members>
+ <Member Name="MethodReceived(Qpid.Client.State.AMQStateManager,Qpid.Client.Protocol.AMQMethodEvent):System.Void">
+ <Messages>
+ <Message TypeName="ValidateArgumentsOfPublicMethods" Category="Microsoft.Design" CheckId="CA1062" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>'evt'</Item>
+ <Item>ConnectionSecureMethodHandler.MethodReceived(AMQStateManager, AMQMethodEvent):Void</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="ConnectionStartMethodHandler">
+ <Members>
+ <Member Name="GetFullSystemInfo():System.String">
+ <Messages>
+ <Message TypeName="MarkMembersAsStatic" Category="Microsoft.Performance" CheckId="CA1822" Created="2006-12-04 13:11:47Z" FixCategory="NonBreaking">
+ <Issue>
+ <Item>ConnectionStartMethodHandler.GetFullSystemInfo():String</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="MethodReceived(Qpid.Client.State.AMQStateManager,Qpid.Client.Protocol.AMQMethodEvent):System.Void">
+ <Messages>
+ <Message Id="Qpid.AMQException.#ctor(System.String)" TypeName="DoNotPassLiteralsAsLocalizedParameters" Category="Microsoft.Globalization" CheckId="CA1303" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>ConnectionStartMethodHandler.MethodReceived(AMQStateManager, AMQMethodEvent):Void</Item>
+ <Item>1</Item>
+ <Item>AMQException.AMQException(String)</Item>
+ <Item>No locales sent from server, passed: __</Item>
+ </Issue>
+ <Issue>
+ <Item>ConnectionStartMethodHandler.MethodReceived(AMQStateManager, AMQMethodEvent):Void</Item>
+ <Item>1</Item>
+ <Item>AMQException.AMQException(String)</Item>
+ <Item>No supported security mechanism found, passed: __</Item>
+ </Issue>
+ </Message>
+ <Message Id="Qpid.AMQException.#ctor(log4net.ILog,System.String,System.Exception)" TypeName="DoNotPassLiteralsAsLocalizedParameters" Category="Microsoft.Globalization" CheckId="CA1303" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>ConnectionStartMethodHandler.MethodReceived(AMQStateManager, AMQMethodEvent):Void</Item>
+ <Item>2</Item>
+ <Item>AMQException.AMQException(ILog, String, Exception)</Item>
+ <Item>Unable to decode data: __</Item>
+ </Issue>
+ </Message>
+ <Message TypeName="ValidateArgumentsOfPublicMethods" Category="Microsoft.Design" CheckId="CA1062" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>'evt'</Item>
+ <Item>ConnectionStartMethodHandler.MethodReceived(AMQStateManager, AMQMethodEvent):Void</Item>
+ </Issue>
+ <Issue>
+ <Item>'stateManager'</Item>
+ <Item>ConnectionStartMethodHandler.MethodReceived(AMQStateManager, AMQMethodEvent):Void</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="ConnectionTuneMethodHandler">
+ <Members>
+ <Member Name="MethodReceived(Qpid.Client.State.AMQStateManager,Qpid.Client.Protocol.AMQMethodEvent):System.Void">
+ <Messages>
+ <Message Id="System.String.Format(System.String,System.Object)" TypeName="SpecifyIFormatProvider" Category="Microsoft.Globalization" CheckId="CA1305" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>ConnectionTuneMethodHandler.MethodReceived(AMQStateManager, AMQMethodEvent):Void</Item>
+ <Item>System.String.Format(System.String,System.Object)</Item>
+ <Item>System.String.Format(System.IFormatProvider,System.String,System.Object[])</Item>
+ </Issue>
+ </Message>
+ <Message TypeName="ValidateArgumentsOfPublicMethods" Category="Microsoft.Design" CheckId="CA1062" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>'evt'</Item>
+ <Item>ConnectionTuneMethodHandler.MethodReceived(AMQStateManager, AMQMethodEvent):Void</Item>
+ </Issue>
+ <Issue>
+ <Item>'stateManager'</Item>
+ <Item>ConnectionTuneMethodHandler.MethodReceived(AMQStateManager, AMQMethodEvent):Void</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ </Types>
+ </Namespace>
+ <Namespace Name="Qpid.Client.Message">
+ <Types>
+ <Type Name="AbstractQmsMessage">
+ <Messages>
+ <Message Id="Qms" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Type">
+ <Item>Qms</Item>
+ <Item>Qpid.Client.Message.AbstractQmsMessage</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ <Members>
+ <Member Name="_data">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>_data</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>_data</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="_redelivered">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>_redelivered</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>_redelivered</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="GetExchangeName(System.String,System.String&amp;):System.String">
+ <Messages>
+ <Message TypeName="ProvideCorrectArgumentsToFormattingMethods" Category="Microsoft.Usage" CheckId="CA2241" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MissingSpecifier">
+ <Item>String.Format(String, Object[]):String</Item>
+ <Item>AbstractQmsMessage.GetExchangeName(String, String&amp;):String</Item>
+ <Item>'stack2'</Item>
+ <Item>split = {0}</Item>
+ </Issue>
+ </Message>
+ <Message Id="System.String.Format(System.String,System.Object)" TypeName="SpecifyIFormatProvider" Category="Microsoft.Globalization" CheckId="CA1305" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>AbstractQmsMessage.GetExchangeName(String, String&amp;):String</Item>
+ <Item>System.String.Format(System.String,System.Object)</Item>
+ <Item>System.String.Format(System.IFormatProvider,System.String,System.Object[])</Item>
+ </Issue>
+ <Issue>
+ <Item>AbstractQmsMessage.GetExchangeName(String, String&amp;):String</Item>
+ <Item>System.String.Format(System.String,System.Object)</Item>
+ <Item>System.String.Format(System.IFormatProvider,System.String,System.Object[])</Item>
+ </Issue>
+ <Issue>
+ <Item>AbstractQmsMessage.GetExchangeName(String, String&amp;):String</Item>
+ <Item>System.String.Format(System.String,System.Object)</Item>
+ <Item>System.String.Format(System.IFormatProvider,System.String,System.Object[])</Item>
+ </Issue>
+ </Message>
+ <Message Id="System.String.Format(System.String,System.Object[])" TypeName="SpecifyIFormatProvider" Category="Microsoft.Globalization" CheckId="CA1305" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>AbstractQmsMessage.GetExchangeName(String, String&amp;):String</Item>
+ <Item>System.String.Format(System.String,System.Object[])</Item>
+ <Item>System.String.Format(System.IFormatProvider,System.String,System.Object[])</Item>
+ </Issue>
+ <Issue>
+ <Item>AbstractQmsMessage.GetExchangeName(String, String&amp;):String</Item>
+ <Item>System.String.Format(System.String,System.Object[])</Item>
+ <Item>System.String.Format(System.IFormatProvider,System.String,System.Object[])</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="ToString():System.String">
+ <Messages>
+ <Message TypeName="DoNotCatchGeneralExceptionTypes" Category="Microsoft.Design" CheckId="CA1031" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>AbstractQmsMessage.ToString():String</Item>
+ <Item>System.Exception</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="WriteReplyToHeader(Qpid.Client.Message.AbstractQmsMessage+Dest):System.Void">
+ <Messages>
+ <Message Id="System.String.Format(System.String,System.Object,System.Object)" TypeName="SpecifyIFormatProvider" Category="Microsoft.Globalization" CheckId="CA1305" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>AbstractQmsMessage.WriteReplyToHeader(Dest):Void</Item>
+ <Item>System.String.Format(System.String,System.Object,System.Object)</Item>
+ <Item>System.String.Format(System.IFormatProvider,System.String,System.Object[])</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="AbstractQmsMessageFactory">
+ <Messages>
+ <Message Id="Qms" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Type">
+ <Item>Qms</Item>
+ <Item>Qpid.Client.Message.AbstractQmsMessageFactory</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ <Members>
+ <Member Name="CreateMessage(System.Int64,Qpid.Buffer.ByteBuffer,Qpid.Framing.ContentHeaderBody):Qpid.Client.Message.AbstractQmsMessage">
+ <Messages>
+ <Message Id="0#Nbr" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>AbstractQmsMessageFactory.CreateMessage(Int64, ByteBuffer, ContentHeaderBody):AbstractQmsMessage</Item>
+ <Item>Nbr</Item>
+ <Item>messageNbr</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="CreateMessage(System.Int64,System.Boolean,Qpid.Framing.ContentHeaderBody,System.Collections.IList):Qpid.Client.Message.AbstractQmsMessage">
+ <Messages>
+ <Message Id="0#" TypeName="ParameterNamesShouldMatchBaseDeclaration" Category="Microsoft.Naming" CheckId="CA1725" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>messageNbr</Item>
+ <Item>AbstractQmsMessageFactory.CreateMessage(Int64, Boolean, ContentHeaderBody, IList):AbstractQmsMessage</Item>
+ <Item>deliverTag</Item>
+ <Item>IMessageFactory.CreateMessage(Int64, Boolean, ContentHeaderBody, IList):AbstractQmsMessage</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="CreateMessageWithBody(System.Int64,Qpid.Framing.ContentHeaderBody,System.Collections.IList):Qpid.Client.Message.AbstractQmsMessage">
+ <Messages>
+ <Message Id="0#Nbr" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>AbstractQmsMessageFactory.CreateMessageWithBody(Int64, ContentHeaderBody, IList):AbstractQmsMessage</Item>
+ <Item>Nbr</Item>
+ <Item>messageNbr</Item>
+ </Issue>
+ </Message>
+ <Message TypeName="ValidateArgumentsOfPublicMethods" Category="Microsoft.Design" CheckId="CA1062" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>'bodies'</Item>
+ <Item>AbstractQmsMessageFactory.CreateMessageWithBody(Int64, ContentHeaderBody, IList):AbstractQmsMessage</Item>
+ </Issue>
+ <Issue>
+ <Item>'bodies'</Item>
+ <Item>AbstractQmsMessageFactory.CreateMessageWithBody(Int64, ContentHeaderBody, IList):AbstractQmsMessage</Item>
+ </Issue>
+ <Issue>
+ <Item>'contentHeader'</Item>
+ <Item>AbstractQmsMessageFactory.CreateMessageWithBody(Int64, ContentHeaderBody, IList):AbstractQmsMessage</Item>
+ </Issue>
+ <Issue>
+ <Item>'contentHeader'</Item>
+ <Item>AbstractQmsMessageFactory.CreateMessageWithBody(Int64, ContentHeaderBody, IList):AbstractQmsMessage</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="AMQMessage">
+ <Messages>
+ <Message TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Type">
+ <Item>AMQMessage</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ <Members>
+ <Member Name="_channel">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>_channel</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>_channel</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="_contentHeaderProperties">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>_contentHeaderProperties</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>_contentHeaderProperties</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="MessageFactoryRegistry">
+ <Members>
+ <Member Name="CreateMessage(System.Int64,System.Boolean,Qpid.Framing.ContentHeaderBody,System.Collections.IList):Qpid.Client.Message.AbstractQmsMessage">
+ <Messages>
+ <Message Id="Qpid.AMQException.#ctor(System.String)" TypeName="DoNotPassLiteralsAsLocalizedParameters" Category="Microsoft.Globalization" CheckId="CA1303" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>MessageFactoryRegistry.CreateMessage(Int64, Boolean, ContentHeaderBody, IList):AbstractQmsMessage</Item>
+ <Item>1</Item>
+ <Item>AMQException.AMQException(String)</Item>
+ <Item>Unsupport MIME type of __</Item>
+ </Issue>
+ </Message>
+ <Message Id="0#Nbr" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>MessageFactoryRegistry.CreateMessage(Int64, Boolean, ContentHeaderBody, IList):AbstractQmsMessage</Item>
+ <Item>Nbr</Item>
+ <Item>messageNbr</Item>
+ </Issue>
+ </Message>
+ <Message Id="Unsupport" TypeName="LiteralsShouldBeSpelledCorrectly" Category="Microsoft.Usage" CheckId="CA2204" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Unsupport</Item>
+ <Item>Unsupport MIME type of __</Item>
+ </Issue>
+ </Message>
+ <Message TypeName="ValidateArgumentsOfPublicMethods" Category="Microsoft.Design" CheckId="CA1062" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>'contentHeader'</Item>
+ <Item>MessageFactoryRegistry.CreateMessage(Int64, Boolean, ContentHeaderBody, IList):AbstractQmsMessage</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="CreateMessage(System.String):Qpid.Client.Message.AbstractQmsMessage">
+ <Messages>
+ <Message Id="Qpid.AMQException.#ctor(System.String)" TypeName="DoNotPassLiteralsAsLocalizedParameters" Category="Microsoft.Globalization" CheckId="CA1303" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>MessageFactoryRegistry.CreateMessage(String):AbstractQmsMessage</Item>
+ <Item>1</Item>
+ <Item>AMQException.AMQException(String)</Item>
+ <Item>Unsupport MIME type of __</Item>
+ </Issue>
+ </Message>
+ <Message TypeName="InstantiateArgumentExceptionsCorrectly" Category="Microsoft.Usage" CheckId="CA2208" Created="2006-12-04 13:11:47Z">
+ <Issue Name="OneArgumentShouldBeParameterName">
+ <Item>System.ArgumentNullException</Item>
+ <Item>ArgumentNullException.ArgumentNullException(String)</Item>
+ <Item>Mime type must not be null</Item>
+ </Issue>
+ </Message>
+ <Message Id="Unsupport" TypeName="LiteralsShouldBeSpelledCorrectly" Category="Microsoft.Usage" CheckId="CA2204" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Unsupport</Item>
+ <Item>Unsupport MIME type of __</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="RegisterFactory(System.String,Qpid.Client.Message.IMessageFactory):System.Void">
+ <Messages>
+ <Message TypeName="InstantiateArgumentExceptionsCorrectly" Category="Microsoft.Usage" CheckId="CA2208" Created="2006-12-04 13:11:47Z">
+ <Issue Name="OneArgumentShouldBeParameterName">
+ <Item>System.ArgumentNullException</Item>
+ <Item>ArgumentNullException.ArgumentNullException(String)</Item>
+ <Item>Message factory</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="QpidBytesMessage">
+ <Messages>
+ <Message Id="Qpid" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Type">
+ <Item>Qpid</Item>
+ <Item>Qpid.Client.Message.QpidBytesMessage</Item>
+ </Issue>
+ </Message>
+ <Message TypeName="TypesThatOwnDisposableFieldsShouldBeDisposable" Category="Microsoft.Design" CheckId="CA1001" Created="2006-12-04 13:11:47Z" FixCategory="Breaking">
+ <Issue>
+ <Item>Qpid.Client.Message.QpidBytesMessage</Item>
+ <Item>System.IO.MemoryStream, System.IO.BinaryWriter, System.IO.BinaryReader</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ <Members>
+ <Member Name="ReadBytes(System.Byte[]):System.Int32">
+ <Messages>
+ <Message Id="0#" TypeName="ParameterNamesShouldMatchBaseDeclaration" Category="Microsoft.Naming" CheckId="CA1725" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>bytes</Item>
+ <Item>QpidBytesMessage.ReadBytes(Byte[]):Int32</Item>
+ <Item>array</Item>
+ <Item>IBytesMessage.ReadBytes(Byte[]):Int32</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="ReadBytes(System.Byte[],System.Int32):System.Int32">
+ <Messages>
+ <Message TypeName="InstantiateArgumentExceptionsCorrectly" Category="Microsoft.Usage" CheckId="CA2208" Created="2006-12-04 13:11:47Z">
+ <Issue Name="OneArgumentShouldBeParameterName">
+ <Item>System.ArgumentOutOfRangeException</Item>
+ <Item>ArgumentOutOfRangeException.ArgumentOutOfRangeException(String)</Item>
+ <Item>count must be &gt;= 0</Item>
+ </Issue>
+ </Message>
+ <Message Id="0#" TypeName="ParameterNamesShouldMatchBaseDeclaration" Category="Microsoft.Naming" CheckId="CA1725" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>bytes</Item>
+ <Item>QpidBytesMessage.ReadBytes(Byte[], Int32):Int32</Item>
+ <Item>array</Item>
+ <Item>IBytesMessage.ReadBytes(Byte[], Int32):Int32</Item>
+ </Issue>
+ </Message>
+ <Message Id="1#" TypeName="ParameterNamesShouldMatchBaseDeclaration" Category="Microsoft.Naming" CheckId="CA1725" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>count</Item>
+ <Item>QpidBytesMessage.ReadBytes(Byte[], Int32):Int32</Item>
+ <Item>length</Item>
+ <Item>IBytesMessage.ReadBytes(Byte[], Int32):Int32</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Write(System.Double):System.Void">
+ <Messages>
+ <Message Id="0#v" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="ParameterOneLetter">
+ <Item>QpidBytesMessage.Write(Double):Void</Item>
+ <Item>v</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Write(System.Int32):System.Void">
+ <Messages>
+ <Message Id="0#i" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="ParameterOneLetter">
+ <Item>QpidBytesMessage.Write(Int32):Void</Item>
+ <Item>i</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Write(System.Int64):System.Void">
+ <Messages>
+ <Message Id="0#l" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="ParameterOneLetter">
+ <Item>QpidBytesMessage.Write(Int64):Void</Item>
+ <Item>l</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Write(System.Single):System.Void">
+ <Messages>
+ <Message Id="0#v" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="ParameterOneLetter">
+ <Item>QpidBytesMessage.Write(Single):Void</Item>
+ <Item>v</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="WriteBoolean(System.Boolean):System.Void">
+ <Messages>
+ <Message Id="0#" TypeName="ParameterNamesShouldMatchBaseDeclaration" Category="Microsoft.Naming" CheckId="CA1725" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>b</Item>
+ <Item>QpidBytesMessage.WriteBoolean(Boolean):Void</Item>
+ <Item>value</Item>
+ <Item>IBytesMessage.WriteBoolean(Boolean):Void</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="WriteByte(System.Byte):System.Void">
+ <Messages>
+ <Message Id="0#" TypeName="ParameterNamesShouldMatchBaseDeclaration" Category="Microsoft.Naming" CheckId="CA1725" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>b</Item>
+ <Item>QpidBytesMessage.WriteByte(Byte):Void</Item>
+ <Item>value</Item>
+ <Item>IBytesMessage.WriteByte(Byte):Void</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="WriteBytes(System.Byte[]):System.Void">
+ <Messages>
+ <Message Id="0#" TypeName="ParameterNamesShouldMatchBaseDeclaration" Category="Microsoft.Naming" CheckId="CA1725" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>bytes</Item>
+ <Item>QpidBytesMessage.WriteBytes(Byte[]):Void</Item>
+ <Item>value</Item>
+ <Item>IBytesMessage.WriteBytes(Byte[]):Void</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="WriteBytes(System.Byte[],System.Int32,System.Int32):System.Void">
+ <Messages>
+ <Message Id="0#" TypeName="ParameterNamesShouldMatchBaseDeclaration" Category="Microsoft.Naming" CheckId="CA1725" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>bytes</Item>
+ <Item>QpidBytesMessage.WriteBytes(Byte[], Int32, Int32):Void</Item>
+ <Item>value</Item>
+ <Item>IBytesMessage.WriteBytes(Byte[], Int32, Int32):Void</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="WriteChar(System.Char):System.Void">
+ <Messages>
+ <Message Id="0#" TypeName="ParameterNamesShouldMatchBaseDeclaration" Category="Microsoft.Naming" CheckId="CA1725" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>c</Item>
+ <Item>QpidBytesMessage.WriteChar(Char):Void</Item>
+ <Item>value</Item>
+ <Item>IBytesMessage.WriteChar(Char):Void</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="WriteShort(System.Int16):System.Void">
+ <Messages>
+ <Message Id="0#" TypeName="ParameterNamesShouldMatchBaseDeclaration" Category="Microsoft.Naming" CheckId="CA1725" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>i</Item>
+ <Item>QpidBytesMessage.WriteShort(Int16):Void</Item>
+ <Item>value</Item>
+ <Item>IBytesMessage.WriteShort(Int16):Void</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="QpidBytesMessageFactory">
+ <Messages>
+ <Message Id="Qpid" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Type">
+ <Item>Qpid</Item>
+ <Item>Qpid.Client.Message.QpidBytesMessageFactory</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ <Members>
+ <Member Name="CreateMessage(System.Int64,Qpid.Buffer.ByteBuffer,Qpid.Framing.ContentHeaderBody):Qpid.Client.Message.AbstractQmsMessage">
+ <Messages>
+ <Message Id="0#" TypeName="ParameterNamesShouldMatchBaseDeclaration" Category="Microsoft.Naming" CheckId="CA1725" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>deliveryTag</Item>
+ <Item>QpidBytesMessageFactory.CreateMessage(Int64, ByteBuffer, ContentHeaderBody):AbstractQmsMessage</Item>
+ <Item>messageNbr</Item>
+ <Item>AbstractQmsMessageFactory.CreateMessage(Int64, ByteBuffer, ContentHeaderBody):AbstractQmsMessage</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="QpidHeaders">
+ <Members>
+ <Member Name="CheckPropertyName(System.String):System.Void">
+ <Messages>
+ <Message Id="System.ArgumentException.#ctor(System.String)" TypeName="DoNotPassLiteralsAsLocalizedParameters" Category="Microsoft.Globalization" CheckId="CA1303" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>QpidHeaders.CheckPropertyName(String):Void</Item>
+ <Item>1</Item>
+ <Item>ArgumentException.ArgumentException(String)</Item>
+ <Item>Property name must not be the empty string</Item>
+ </Issue>
+ </Message>
+ <Message TypeName="TestForEmptyStringsUsingStringLength" Category="Microsoft.Performance" CheckId="CA1820" Created="2006-12-04 13:11:47Z">
+ <Issue Name="IsNullOrEmpty">
+ <Item>Equals</Item>
+ <Item>""</Item>
+ <Item>QpidHeaders.CheckPropertyName(String):Void</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Clear():System.Void">
+ <Messages>
+ <Message TypeName="AvoidUncalledPrivateCode" Category="Microsoft.Performance" CheckId="CA1811" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>QpidHeaders.Clear():Void</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="QpidTextMessage">
+ <Messages>
+ <Message Id="Qpid" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Type">
+ <Item>Qpid</Item>
+ <Item>Qpid.Client.Message.QpidTextMessage</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ <Members>
+ <Member Name=".ctor(Qpid.Buffer.ByteBuffer)">
+ <Messages>
+ <Message TypeName="AvoidUncalledPrivateCode" Category="Microsoft.Performance" CheckId="CA1811" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>QpidTextMessage.QpidTextMessage(ByteBuffer)</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name=".ctor(System.String)">
+ <Messages>
+ <Message TypeName="AvoidUncalledPrivateCode" Category="Microsoft.Performance" CheckId="CA1811" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>QpidTextMessage.QpidTextMessage(String)</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="QpidTextMessageFactory">
+ <Messages>
+ <Message Id="Qpid" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Type">
+ <Item>Qpid</Item>
+ <Item>Qpid.Client.Message.QpidTextMessageFactory</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ <Members>
+ <Member Name="CreateMessage(System.Int64,Qpid.Buffer.ByteBuffer,Qpid.Framing.ContentHeaderBody):Qpid.Client.Message.AbstractQmsMessage">
+ <Messages>
+ <Message Id="0#" TypeName="ParameterNamesShouldMatchBaseDeclaration" Category="Microsoft.Naming" CheckId="CA1725" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>deliveryTag</Item>
+ <Item>QpidTextMessageFactory.CreateMessage(Int64, ByteBuffer, ContentHeaderBody):AbstractQmsMessage</Item>
+ <Item>messageNbr</Item>
+ <Item>AbstractQmsMessageFactory.CreateMessage(Int64, ByteBuffer, ContentHeaderBody):AbstractQmsMessage</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="UnexpectedBodyReceivedException">
+ <Messages>
+ <Message TypeName="ImplementStandardExceptionConstructors" Category="Microsoft.Design" CheckId="CA1032" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Qpid.Client.Message.UnexpectedBodyReceivedException</Item>
+ <Item>protected UnexpectedBodyReceivedException(SerializationInfo, StreamingContext)</Item>
+ </Issue>
+ <Issue>
+ <Item>Qpid.Client.Message.UnexpectedBodyReceivedException</Item>
+ <Item>public UnexpectedBodyReceivedException()</Item>
+ </Issue>
+ <Issue>
+ <Item>Qpid.Client.Message.UnexpectedBodyReceivedException</Item>
+ <Item>public UnexpectedBodyReceivedException(String)</Item>
+ </Issue>
+ <Issue>
+ <Item>Qpid.Client.Message.UnexpectedBodyReceivedException</Item>
+ <Item>public UnexpectedBodyReceivedException(String, Exception)</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ <Members>
+ <Member Name=".ctor(log4net.ILog,System.String,System.Exception)">
+ <Messages>
+ <Message Id="2#t" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="ParameterOneLetter">
+ <Item>UnexpectedBodyReceivedException.UnexpectedBodyReceivedException(ILog, String, Exception)</Item>
+ <Item>t</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="UnprocessedMessage">
+ <Members>
+ <Member Name=".ctor()">
+ <Messages>
+ <Message TypeName="DoNotInitializeUnnecessarily" Category="Microsoft.Performance" CheckId="CA1805" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>UnprocessedMessage.UnprocessedMessage()</Item>
+ <Item>_bytesReceived</Item>
+ <Item>System.UInt64</Item>
+ <Item>0</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Bodies">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Bodies</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="BounceBody">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>BounceBody</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="ChannelId">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>ChannelId</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="ContentHeader">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>ContentHeader</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="DeliverBody">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>DeliverBody</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="ReceiveBody(Qpid.Framing.ContentBody):System.Void">
+ <Messages>
+ <Message TypeName="ValidateArgumentsOfPublicMethods" Category="Microsoft.Design" CheckId="CA1062" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>'body'</Item>
+ <Item>UnprocessedMessage.ReceiveBody(ContentBody):Void</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ </Types>
+ </Namespace>
+ <Namespace Name="Qpid.Client.Protocol">
+ <Types>
+ <Type Name="AMQMethodEvent">
+ <Messages>
+ <Message TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Type">
+ <Item>AMQMethodEvent</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Type>
+ <Type Name="AMQProtocolListener">
+ <Messages>
+ <Message TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Type">
+ <Item>AMQProtocolListener</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ <Members>
+ <Member Name=".ctor(Qpid.Client.AMQConnection,Qpid.Client.State.AMQStateManager)">
+ <Messages>
+ <Message TypeName="DoNotInitializeUnnecessarily" Category="Microsoft.Performance" CheckId="CA1805" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>AMQProtocolListener.AMQProtocolListener(AMQConnection, AMQStateManager)</Item>
+ <Item>_protocolSession</Item>
+ <Item>Qpid.Client.Protocol.AMQProtocolSession</Item>
+ <Item>null</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="OnException(System.Exception):System.Void">
+ <Messages>
+ <Message Id="Qpid.AMQException.#ctor(System.String,System.Exception)" TypeName="DoNotPassLiteralsAsLocalizedParameters" Category="Microsoft.Globalization" CheckId="CA1303" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>AMQProtocolListener.OnException(Exception):Void</Item>
+ <Item>1</Item>
+ <Item>AMQException.AMQException(String, Exception)</Item>
+ <Item>Protocol handler error: __</Item>
+ </Issue>
+ </Message>
+ <Message Id="0#" TypeName="ParameterNamesShouldMatchBaseDeclaration" Category="Microsoft.Naming" CheckId="CA1725" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>cause</Item>
+ <Item>AMQProtocolListener.OnException(Exception):Void</Item>
+ <Item>e</Item>
+ <Item>IProtocolListener.OnException(Exception):Void</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="OnMessage(Qpid.Framing.IDataBlock):System.Void">
+ <Messages>
+ <Message TypeName="DoNotCatchGeneralExceptionTypes" Category="Microsoft.Design" CheckId="CA1031" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>AMQProtocolListener.OnMessage(IDataBlock):Void</Item>
+ <Item>System.Exception</Item>
+ </Issue>
+ </Message>
+ <Message Id="Qpid.AMQException.#ctor(System.String)" TypeName="DoNotPassLiteralsAsLocalizedParameters" Category="Microsoft.Globalization" CheckId="CA1303" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>AMQProtocolListener.OnMessage(IDataBlock):Void</Item>
+ <Item>1</Item>
+ <Item>AMQException.AMQException(String)</Item>
+ <Item>AMQMethodEvent ____ was not processed by any listener.</Item>
+ </Issue>
+ </Message>
+ <Message Id="System.String.Format(System.String,System.Object)" TypeName="SpecifyIFormatProvider" Category="Microsoft.Globalization" CheckId="CA1305" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>AMQProtocolListener.OnMessage(IDataBlock):Void</Item>
+ <Item>System.String.Format(System.String,System.Object)</Item>
+ <Item>System.String.Format(System.IFormatProvider,System.String,System.Object[])</Item>
+ </Issue>
+ </Message>
+ <Message TypeName="ValidateArgumentsOfPublicMethods" Category="Microsoft.Design" CheckId="CA1062" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>'message'</Item>
+ <Item>AMQProtocolListener.OnMessage(IDataBlock):Void</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="PropagateExceptionToWaiters(System.Exception):System.Void">
+ <Messages>
+ <Message Id="0#e" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="ParameterOneLetter">
+ <Item>AMQProtocolListener.PropagateExceptionToWaiters(Exception):Void</Item>
+ <Item>e</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="ProtocolSession">
+ <Messages>
+ <Message TypeName="PropertiesShouldNotBeWriteOnly" Category="Microsoft.Design" CheckId="CA1044" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>ProtocolSession</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="RemoveFrameListener(Qpid.Client.Protocol.Listener.IAMQMethodListener):System.Void">
+ <Messages>
+ <Message TypeName="ValidateArgumentsOfPublicMethods" Category="Microsoft.Design" CheckId="CA1062" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>'listener'</Item>
+ <Item>AMQProtocolListener.RemoveFrameListener(IAMQMethodListener):Void</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="WhenClosed():System.Void">
+ <Messages>
+ <Message Id="Qpid.AMQDisconnectedException.#ctor(System.String)" TypeName="DoNotPassLiteralsAsLocalizedParameters" Category="Microsoft.Globalization" CheckId="CA1303" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>AMQProtocolListener.WhenClosed():Void</Item>
+ <Item>1</Item>
+ <Item>AMQDisconnectedException.AMQDisconnectedException(String)</Item>
+ <Item>Server closed connection and reconnection not permitted.</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="AMQProtocolSession">
+ <Messages>
+ <Message TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Type">
+ <Item>AMQProtocolSession</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ <Members>
+ <Member Name="AddSessionByChannel(System.UInt16,Qpid.Client.AmqChannel):System.Void">
+ <Messages>
+ <Message TypeName="InstantiateArgumentExceptionsCorrectly" Category="Microsoft.Usage" CheckId="CA2208" Created="2006-12-04 13:11:47Z">
+ <Issue Name="OneArgumentShouldBeParameterName">
+ <Item>System.ArgumentNullException</Item>
+ <Item>ArgumentNullException.ArgumentNullException(String)</Item>
+ <Item>Attempt to register a null channel</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="AMQConnection">
+ <Messages>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>AMQProtocolSession.AMQConnection:AMQConnection</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="CloseSession(Qpid.Client.AmqChannel):System.Void">
+ <Messages>
+ <Message TypeName="ValidateArgumentsOfPublicMethods" Category="Microsoft.Design" CheckId="CA1062" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>'channel'</Item>
+ <Item>AMQProtocolSession.CloseSession(AmqChannel):Void</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="ConnectionTuneParameters">
+ <Accessors>
+ <Accessor Name="set_ConnectionTuneParameters(Qpid.Client.ConnectionTuneParameters):System.Void">
+ <Messages>
+ <Message TypeName="ValidateArgumentsOfPublicMethods" Category="Microsoft.Design" CheckId="CA1062" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>'value'</Item>
+ <Item>AMQProtocolSession.set_ConnectionTuneParameters(ConnectionTuneParameters):Void</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Accessor>
+ </Accessors>
+ </Member>
+ <Member Name="MessageContentBodyReceived(System.UInt16,Qpid.Framing.ContentBody):System.Void">
+ <Messages>
+ <Message Id="Qpid.AMQException.#ctor(System.String)" TypeName="DoNotPassLiteralsAsLocalizedParameters" Category="Microsoft.Globalization" CheckId="CA1303" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>AMQProtocolSession.MessageContentBodyReceived(UInt16, ContentBody):Void</Item>
+ <Item>1</Item>
+ <Item>AMQException.AMQException(String)</Item>
+ <Item>Error: received content body without having received a BasicDeliver frame first</Item>
+ </Issue>
+ </Message>
+ <Message TypeName="RethrowToPreserveStackDetails" Category="Microsoft.Usage" CheckId="CA2200" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>AMQProtocolSession.MessageContentBodyReceived(UInt16, ContentBody):Void</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="MessageContentHeaderReceived(System.UInt16,Qpid.Framing.ContentHeaderBody):System.Void">
+ <Messages>
+ <Message Id="Qpid.AMQException.#ctor(System.String)" TypeName="DoNotPassLiteralsAsLocalizedParameters" Category="Microsoft.Globalization" CheckId="CA1303" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>AMQProtocolSession.MessageContentHeaderReceived(UInt16, ContentHeaderBody):Void</Item>
+ <Item>1</Item>
+ <Item>AMQException.AMQException(String)</Item>
+ <Item>Error: received content header without having received a JMSDeliver frame first</Item>
+ </Issue>
+ <Issue>
+ <Item>AMQProtocolSession.MessageContentHeaderReceived(UInt16, ContentHeaderBody):Void</Item>
+ <Item>1</Item>
+ <Item>AMQException.AMQException(String)</Item>
+ <Item>Error: received duplicate content header or did not receive correct number of content body frames</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="UnprocessedMessageReceived(Qpid.Client.Message.UnprocessedMessage):System.Void">
+ <Messages>
+ <Message TypeName="ValidateArgumentsOfPublicMethods" Category="Microsoft.Design" CheckId="CA1062" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>'message'</Item>
+ <Item>AMQProtocolSession.UnprocessedMessageReceived(UnprocessedMessage):Void</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Username">
+ <Messages>
+ <Message Id="Username" TypeName="CompoundWordsShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1702" Created="2006-12-04 13:11:47Z">
+ <Issue Name="ShouldBeCompoundWord">
+ <Item>Username</Item>
+ <Item>property</Item>
+ <Item>Username</Item>
+ <Item>UserName</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="IProtocolListener">
+ <Members>
+ <Member Name="OnException(System.Exception):System.Void">
+ <Messages>
+ <Message Id="0#e" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="ParameterOneLetter">
+ <Item>IProtocolListener.OnException(Exception):Void</Item>
+ <Item>e</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="ProtocolWriter">
+ <Members>
+ <Member Name="SyncWrite(Qpid.Framing.AMQFrame,System.Type):Qpid.Client.Protocol.AMQMethodEvent">
+ <Messages>
+ <Message TypeName="ValidateArgumentsOfPublicMethods" Category="Microsoft.Design" CheckId="CA1062" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>'frame'</Item>
+ <Item>ProtocolWriter.SyncWrite(AMQFrame, Type):AMQMethodEvent</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ </Types>
+ </Namespace>
+ <Namespace Name="Qpid.Client.Protocol.Listener">
+ <Types>
+ <Type Name="BlockingMethodFrameListener">
+ <Messages>
+ <Message TypeName="AbstractTypesShouldNotHaveConstructors" Category="Microsoft.Design" CheckId="CA1012" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>BlockingMethodFrameListener</Item>
+ </Issue>
+ </Message>
+ <Message TypeName="TypesThatOwnDisposableFieldsShouldBeDisposable" Category="Microsoft.Design" CheckId="CA1001" Created="2006-12-04 13:11:47Z" FixCategory="Breaking">
+ <Issue>
+ <Item>Qpid.Client.Protocol.Listener.BlockingMethodFrameListener</Item>
+ <Item>System.Threading.ManualResetEvent</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ <Members>
+ <Member Name=".ctor(System.UInt16)">
+ <Messages>
+ <Message TypeName="DoNotInitializeUnnecessarily" Category="Microsoft.Performance" CheckId="CA1805" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>BlockingMethodFrameListener.BlockingMethodFrameListener(UInt16)</Item>
+ <Item>_doneEvt</Item>
+ <Item>Qpid.Client.Protocol.AMQMethodEvent</Item>
+ <Item>null</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="_channelId">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>_channelId</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>_channelId</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="_doneEvt">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>_doneEvt</Item>
+ </Issue>
+ </Message>
+ <Message Id="Evt" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>Evt</Item>
+ <Item>BlockingMethodFrameListener._doneEvt</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>_doneEvt</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="MethodReceived(Qpid.Client.Protocol.AMQMethodEvent):System.Boolean">
+ <Messages>
+ <Message TypeName="RethrowToPreserveStackDetails" Category="Microsoft.Usage" CheckId="CA2200" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>BlockingMethodFrameListener.MethodReceived(AMQMethodEvent):Boolean</Item>
+ </Issue>
+ </Message>
+ <Message TypeName="ValidateArgumentsOfPublicMethods" Category="Microsoft.Design" CheckId="CA1062" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>'evt'</Item>
+ <Item>BlockingMethodFrameListener.MethodReceived(AMQMethodEvent):Boolean</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="IAMQMethodListener">
+ <Messages>
+ <Message TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Type">
+ <Item>IAMQMethodListener</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ <Members>
+ <Member Name="Error(System.Exception):System.Void">
+ <Messages>
+ <Message Id="0#e" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="ParameterOneLetter">
+ <Item>IAMQMethodListener.Error(Exception):Void</Item>
+ <Item>e</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="MethodReceived(Qpid.Client.Protocol.AMQMethodEvent):System.Boolean">
+ <Messages>
+ <Message Id="0#evt" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>IAMQMethodListener.MethodReceived(AMQMethodEvent):Boolean</Item>
+ <Item>evt</Item>
+ <Item>evt</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ </Types>
+ </Namespace>
+ <Namespace Name="Qpid.Client.qms">
+ <Types>
+ <Type Name="BrokerInfo">
+ <Messages>
+ <Message TypeName="IdentifiersShouldHaveCorrectPrefix" Category="Microsoft.Naming" CheckId="CA1715" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>BrokerInfo</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ <Members>
+ <Member Name="getHost():System.String">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>getHost</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="getOption(System.String):System.String">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>getOption</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="getPort():System.Int32">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>getPort</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="getTimeout():System.Int64">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>getTimeout</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="getTransport():System.String">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>getTransport</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="setHost(System.String):System.Void">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>setHost</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="setOption(System.String,System.String):System.Void">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>setOption</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="setPort(System.Int32):System.Void">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>setPort</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="setTimeout(System.Int64):System.Void">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>setTimeout</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="setTransport(System.String):System.Void">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>setTransport</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="useSSL():System.Boolean">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>useSSL</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>BrokerInfo.useSSL():Boolean</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="useSSL(System.Boolean):System.Void">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>useSSL</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>BrokerInfo.useSSL(Boolean):Void</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="BrokerInfoConstants">
+ <Members>
+ <Member Name="DEFAULT_CONNECT_TIMEOUT">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>DEFAULT_CONNECT_TIMEOUT</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>BrokerInfoConstants.DEFAULT_CONNECT_TIMEOUT</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="DEFAULT_PORT">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>DEFAULT_PORT</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>BrokerInfoConstants.DEFAULT_PORT</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="DEFAULT_TRANSPORT">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>DEFAULT_TRANSPORT</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>BrokerInfoConstants.DEFAULT_TRANSPORT</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="OPTIONS_CONNECT_TIMEOUT">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>OPTIONS_CONNECT_TIMEOUT</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>BrokerInfoConstants.OPTIONS_CONNECT_TIMEOUT</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="OPTIONS_RETRY">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>OPTIONS_RETRY</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>BrokerInfoConstants.OPTIONS_RETRY</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="OPTIONS_SSL">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>OPTIONS_SSL</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>BrokerInfoConstants.OPTIONS_SSL</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="URL_FORMAT_EXAMPLE">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>URL_FORMAT_EXAMPLE</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>URL_FORMAT_EXAMPLE</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="ConnectionInfo">
+ <Messages>
+ <Message TypeName="IdentifiersShouldHaveCorrectPrefix" Category="Microsoft.Naming" CheckId="CA1715" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>ConnectionInfo</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ <Members>
+ <Member Name="AsUrl():System.String">
+ <Messages>
+ <Message TypeName="UriReturnValuesShouldNotBeStrings" Category="Microsoft.Design" CheckId="CA1055" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>ConnectionInfo.AsUrl():String</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="GetAllBrokerInfos():System.Collections.IList">
+ <Messages>
+ <Message Id="Infos" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>Infos</Item>
+ <Item>ConnectionInfo.GetAllBrokerInfos():IList</Item>
+ </Issue>
+ </Message>
+ <Message TypeName="UsePropertiesWhereAppropriate" Category="Microsoft.Design" CheckId="CA1024" Created="2006-12-04 13:11:47Z">
+ <Issue Certainty="50">
+ <Item>GetAllBrokerInfos</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="GetBrokerCount():System.Int32">
+ <Messages>
+ <Message TypeName="UsePropertiesWhereAppropriate" Category="Microsoft.Design" CheckId="CA1024" Created="2006-12-04 13:11:47Z">
+ <Issue Certainty="50">
+ <Item>GetBrokerCount</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="GetClientName():System.String">
+ <Messages>
+ <Message TypeName="UsePropertiesWhereAppropriate" Category="Microsoft.Design" CheckId="CA1024" Created="2006-12-04 13:11:47Z">
+ <Issue Certainty="50">
+ <Item>GetClientName</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="GetFailoverMethod():System.String">
+ <Messages>
+ <Message TypeName="UsePropertiesWhereAppropriate" Category="Microsoft.Design" CheckId="CA1024" Created="2006-12-04 13:11:47Z">
+ <Issue Certainty="50">
+ <Item>GetFailoverMethod</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="GetPassword():System.String">
+ <Messages>
+ <Message TypeName="UsePropertiesWhereAppropriate" Category="Microsoft.Design" CheckId="CA1024" Created="2006-12-04 13:11:47Z">
+ <Issue Certainty="50">
+ <Item>GetPassword</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="GetUsername():System.String">
+ <Messages>
+ <Message Id="Username" TypeName="CompoundWordsShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1702" Created="2006-12-04 13:11:47Z">
+ <Issue Name="ShouldBeCompoundWord">
+ <Item>Username</Item>
+ <Item>method</Item>
+ <Item>GetUsername</Item>
+ <Item>UserName</Item>
+ </Issue>
+ </Message>
+ <Message TypeName="UsePropertiesWhereAppropriate" Category="Microsoft.Design" CheckId="CA1024" Created="2006-12-04 13:11:47Z">
+ <Issue Certainty="50">
+ <Item>GetUsername</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="GetVirtualHost():System.String">
+ <Messages>
+ <Message TypeName="UsePropertiesWhereAppropriate" Category="Microsoft.Design" CheckId="CA1024" Created="2006-12-04 13:11:47Z">
+ <Issue Certainty="50">
+ <Item>GetVirtualHost</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="setUsername(System.String):System.Void">
+ <Messages>
+ <Message Id="Username" TypeName="CompoundWordsShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1702" Created="2006-12-04 13:11:47Z">
+ <Issue Name="ShouldBeCompoundWord">
+ <Item>Username</Item>
+ <Item>method</Item>
+ <Item>setUsername</Item>
+ <Item>UserName</Item>
+ </Issue>
+ </Message>
+ <Message Id="username" TypeName="CompoundWordsShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1702" Created="2006-12-04 13:11:47Z">
+ <Issue Name="ShouldBeCompoundWord">
+ <Item>username</Item>
+ <Item>parameter</Item>
+ <Item>username</Item>
+ <Item>userName</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>setUsername</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="ConnectionUrlConstants">
+ <Messages>
+ <Message TypeName="AvoidUninstantiatedInternalClasses" Category="Microsoft.Performance" CheckId="CA1812" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Qpid.Client.qms.ConnectionUrlConstants</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Type>
+ <Type Name="FailoverPolicy">
+ <Members>
+ <Member Name=".ctor(Qpid.Client.qms.ConnectionInfo)">
+ <Messages>
+ <Message TypeName="DoNotInitializeUnnecessarily" Category="Microsoft.Performance" CheckId="CA1805" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>FailoverPolicy.FailoverPolicy(ConnectionInfo)</Item>
+ <Item>_methodsRetries</Item>
+ <Item>System.Int32</Item>
+ <Item>0</Item>
+ </Issue>
+ </Message>
+ <Message Id="System.NotImplementedException.#ctor(System.String)" TypeName="DoNotPassLiteralsAsLocalizedParameters" Category="Microsoft.Globalization" CheckId="CA1303" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>FailoverPolicy.FailoverPolicy(ConnectionInfo)</Item>
+ <Item>1</Item>
+ <Item>NotImplementedException.NotImplementedException(String)</Item>
+ <Item>Dynamic loading of FailoverMethods not yet implemented.</Item>
+ </Issue>
+ </Message>
+ <Message TypeName="ValidateArgumentsOfPublicMethods" Category="Microsoft.Design" CheckId="CA1062" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>'connectionInfo'</Item>
+ <Item>FailoverPolicy.FailoverPolicy(ConnectionInfo)</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="addMethod(Qpid.Client.qms.failover.FailoverMethod):System.Void">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>addMethod</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="attainedConnection():System.Void">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>attainedConnection</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="GetCurrentBrokerInfo():Qpid.Client.qms.BrokerInfo">
+ <Messages>
+ <Message TypeName="UsePropertiesWhereAppropriate" Category="Microsoft.Design" CheckId="CA1024" Created="2006-12-04 13:11:47Z">
+ <Issue Certainty="50">
+ <Item>GetCurrentBrokerInfo</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="getCurrentMethod():Qpid.Client.qms.failover.FailoverMethod">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>getCurrentMethod</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="GetNextBrokerInfo():Qpid.Client.qms.BrokerInfo">
+ <Messages>
+ <Message TypeName="UsePropertiesWhereAppropriate" Category="Microsoft.Design" CheckId="CA1024" Created="2006-12-04 13:11:47Z">
+ <Issue Certainty="50">
+ <Item>GetNextBrokerInfo</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="setBroker(Qpid.Client.qms.BrokerInfo):System.Void">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>setBroker</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="setMethodRetries(System.Int32):System.Void">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>setMethodRetries</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="toString():System.String">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>toString</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="UrlSyntaxException">
+ <Messages>
+ <Message TypeName="ImplementStandardExceptionConstructors" Category="Microsoft.Design" CheckId="CA1032" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Qpid.Client.qms.UrlSyntaxException</Item>
+ <Item>protected UrlSyntaxException(SerializationInfo, StreamingContext)</Item>
+ </Issue>
+ <Issue>
+ <Item>Qpid.Client.qms.UrlSyntaxException</Item>
+ <Item>public UrlSyntaxException()</Item>
+ </Issue>
+ <Issue>
+ <Item>Qpid.Client.qms.UrlSyntaxException</Item>
+ <Item>public UrlSyntaxException(String)</Item>
+ </Issue>
+ <Issue>
+ <Item>Qpid.Client.qms.UrlSyntaxException</Item>
+ <Item>public UrlSyntaxException(String, Exception)</Item>
+ </Issue>
+ </Message>
+ <Message TypeName="MarkISerializableTypesWithSerializable" Category="Microsoft.Usage" CheckId="CA2237" Created="2006-12-04 13:11:47Z">
+ <Issue Level="Error">
+ <Item>UrlSyntaxException</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ <Members>
+ <Member Name=".ctor(System.String,System.String,System.Int32,System.Int32)">
+ <Messages>
+ <Message Id="0#" TypeName="UriParametersShouldNotBeStrings" Category="Microsoft.Design" CheckId="CA1054" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>url</Item>
+ <Item>UrlSyntaxException.UrlSyntaxException(String, String, Int32, Int32)</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="GetIndex():System.Int32">
+ <Messages>
+ <Message TypeName="UsePropertiesWhereAppropriate" Category="Microsoft.Design" CheckId="CA1024" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>GetIndex</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="GetReason():System.String">
+ <Messages>
+ <Message TypeName="MarkMembersAsStatic" Category="Microsoft.Performance" CheckId="CA1822" Created="2006-12-04 13:11:47Z" FixCategory="Breaking">
+ <Issue>
+ <Item>UrlSyntaxException.GetReason():String</Item>
+ </Issue>
+ </Message>
+ <Message TypeName="UsePropertiesWhereAppropriate" Category="Microsoft.Design" CheckId="CA1024" Created="2006-12-04 13:11:47Z">
+ <Issue Certainty="50">
+ <Item>GetReason</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="toString():System.String">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>toString</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ </Types>
+ </Namespace>
+ <Namespace Name="Qpid.Client.qms.failover">
+ <Types>
+ <Type Name="FailoverMethod">
+ <Messages>
+ <Message TypeName="IdentifiersShouldHaveCorrectPrefix" Category="Microsoft.Naming" CheckId="CA1715" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>FailoverMethod</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ <Members>
+ <Member Name="attainedConnection():System.Void">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>attainedConnection</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="failoverAllowed():System.Boolean">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>failoverAllowed</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="GetCurrentBrokerInfo():Qpid.Client.qms.BrokerInfo">
+ <Messages>
+ <Message TypeName="UsePropertiesWhereAppropriate" Category="Microsoft.Design" CheckId="CA1024" Created="2006-12-04 13:11:47Z">
+ <Issue Certainty="50">
+ <Item>GetCurrentBrokerInfo</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="getNextBrokerDetails():Qpid.Client.qms.BrokerInfo">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>getNextBrokerDetails</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="methodName():System.String">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>methodName</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="reset():System.Void">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>reset</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="setBroker(Qpid.Client.qms.BrokerInfo):System.Void">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>setBroker</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="setRetries(System.Int32):System.Void">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>setRetries</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="FailoverMethodConstants">
+ <Members>
+ <Member Name="RANDOM">
+ <Messages>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>FailoverMethodConstants.RANDOM</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="ROUND_ROBIN">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>ROUND_ROBIN</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>FailoverMethodConstants.ROUND_ROBIN</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="FailoverRoundRobin">
+ <Members>
+ <Member Name=".ctor(Qpid.Client.qms.ConnectionInfo)">
+ <Messages>
+ <Message TypeName="DoNotInitializeUnnecessarily" Category="Microsoft.Performance" CheckId="CA1805" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>FailoverRoundRobin.FailoverRoundRobin(ConnectionInfo)</Item>
+ <Item>_currentCycleRetries</Item>
+ <Item>System.Int32</Item>
+ <Item>0</Item>
+ </Issue>
+ <Issue>
+ <Item>FailoverRoundRobin.FailoverRoundRobin(ConnectionInfo)</Item>
+ <Item>_cycleRetries</Item>
+ <Item>System.Int32</Item>
+ <Item>0</Item>
+ </Issue>
+ <Issue>
+ <Item>FailoverRoundRobin.FailoverRoundRobin(ConnectionInfo)</Item>
+ <Item>_serverRetries</Item>
+ <Item>System.Int32</Item>
+ <Item>0</Item>
+ </Issue>
+ </Message>
+ <Message Id="System.ArgumentException.#ctor(System.String)" TypeName="DoNotPassLiteralsAsLocalizedParameters" Category="Microsoft.Globalization" CheckId="CA1303" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>FailoverRoundRobin.FailoverRoundRobin(ConnectionInfo)</Item>
+ <Item>1</Item>
+ <Item>ArgumentException.ArgumentException(String)</Item>
+ <Item>At least one broker details must be specified.</Item>
+ </Issue>
+ </Message>
+ <Message Id="System.Int32.Parse(System.String)" TypeName="SpecifyIFormatProvider" Category="Microsoft.Globalization" CheckId="CA1305" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>FailoverRoundRobin.FailoverRoundRobin(ConnectionInfo)</Item>
+ <Item>System.Int32.Parse(System.String)</Item>
+ <Item>System.Int32.Parse(System.String,System.IFormatProvider)</Item>
+ </Issue>
+ </Message>
+ <Message TypeName="ValidateArgumentsOfPublicMethods" Category="Microsoft.Design" CheckId="CA1062" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>'connectionDetails'</Item>
+ <Item>FailoverRoundRobin.FailoverRoundRobin(ConnectionInfo)</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="DEFAULT_CYCLE_RETRIES">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>DEFAULT_CYCLE_RETRIES</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>FailoverRoundRobin.DEFAULT_CYCLE_RETRIES</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="DEFAULT_SERVER_RETRIES">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>DEFAULT_SERVER_RETRIES</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>FailoverRoundRobin.DEFAULT_SERVER_RETRIES</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="setBroker(Qpid.Client.qms.BrokerInfo):System.Void">
+ <Messages>
+ <Message Id="System.Int32.Parse(System.String)" TypeName="SpecifyIFormatProvider" Category="Microsoft.Globalization" CheckId="CA1305" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>FailoverRoundRobin.setBroker(BrokerInfo):Void</Item>
+ <Item>System.Int32.Parse(System.String)</Item>
+ <Item>System.Int32.Parse(System.String,System.IFormatProvider)</Item>
+ </Issue>
+ </Message>
+ <Message TypeName="ValidateArgumentsOfPublicMethods" Category="Microsoft.Design" CheckId="CA1062" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>'broker'</Item>
+ <Item>FailoverRoundRobin.setBroker(BrokerInfo):Void</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="FailoverSingleServer">
+ <Members>
+ <Member Name=".ctor(Qpid.Client.qms.ConnectionInfo)">
+ <Messages>
+ <Message Id="System.ArgumentException.#ctor(System.String)" TypeName="DoNotPassLiteralsAsLocalizedParameters" Category="Microsoft.Globalization" CheckId="CA1303" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>FailoverSingleServer.FailoverSingleServer(ConnectionInfo)</Item>
+ <Item>1</Item>
+ <Item>ArgumentException.ArgumentException(String)</Item>
+ <Item>BrokerInfo details required for connection.</Item>
+ </Issue>
+ </Message>
+ <Message TypeName="ValidateArgumentsOfPublicMethods" Category="Microsoft.Design" CheckId="CA1062" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>'connectionDetails'</Item>
+ <Item>FailoverSingleServer.FailoverSingleServer(ConnectionInfo)</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="DEFAULT_SERVER_RETRIES">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>DEFAULT_SERVER_RETRIES</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>FailoverSingleServer.DEFAULT_SERVER_RETRIES</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="setBroker(Qpid.Client.qms.BrokerInfo):System.Void">
+ <Messages>
+ <Message Id="System.ArgumentException.#ctor(System.String)" TypeName="DoNotPassLiteralsAsLocalizedParameters" Category="Microsoft.Globalization" CheckId="CA1303" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>FailoverSingleServer.setBroker(BrokerInfo):Void</Item>
+ <Item>1</Item>
+ <Item>ArgumentException.ArgumentException(String)</Item>
+ <Item>BrokerInfo details cannot be null</Item>
+ </Issue>
+ </Message>
+ <Message Id="System.Int32.Parse(System.String)" TypeName="SpecifyIFormatProvider" Category="Microsoft.Globalization" CheckId="CA1305" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>FailoverSingleServer.setBroker(BrokerInfo):Void</Item>
+ <Item>System.Int32.Parse(System.String)</Item>
+ <Item>System.Int32.Parse(System.String,System.IFormatProvider)</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="setRetries(System.Int32):System.Void">
+ <Messages>
+ <Message Id="0#" TypeName="ParameterNamesShouldMatchBaseDeclaration" Category="Microsoft.Naming" CheckId="CA1725" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>retries</Item>
+ <Item>FailoverSingleServer.setRetries(Int32):Void</Item>
+ <Item>maxRetries</Item>
+ <Item>FailoverMethod.setRetries(Int32):Void</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="toString():System.String">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>toString</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ </Types>
+ </Namespace>
+ <Namespace Name="Qpid.Client.State">
+ <Types>
+ <Type Name="AMQState">
+ <Messages>
+ <Message TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Type">
+ <Item>AMQState</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ <Members>
+ <Member Name="ALL">
+ <Messages>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>AMQState.ALL</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="CONNECTION_CLOSED">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>CONNECTION_CLOSED</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>AMQState.CONNECTION_CLOSED</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="CONNECTION_CLOSING">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>CONNECTION_CLOSING</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>AMQState.CONNECTION_CLOSING</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="CONNECTION_NOT_OPENED">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>CONNECTION_NOT_OPENED</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>AMQState.CONNECTION_NOT_OPENED</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="CONNECTION_NOT_STARTED">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>CONNECTION_NOT_STARTED</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>AMQState.CONNECTION_NOT_STARTED</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="CONNECTION_NOT_TUNED">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>CONNECTION_NOT_TUNED</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>AMQState.CONNECTION_NOT_TUNED</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="CONNECTION_OPEN">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>CONNECTION_OPEN</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>AMQState.CONNECTION_OPEN</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="AMQStateChangedEvent">
+ <Messages>
+ <Message TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Type">
+ <Item>AMQStateChangedEvent</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Type>
+ <Type Name="AMQStateManager">
+ <Messages>
+ <Message TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Type">
+ <Item>AMQStateManager</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ <Members>
+ <Member Name="AttainState(Qpid.Client.State.AMQState):System.Void">
+ <Messages>
+ <Message Id="0#s" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="ParameterOneLetter">
+ <Item>AMQStateManager.AttainState(AMQState):Void</Item>
+ <Item>s</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="MethodReceived(Qpid.Client.Protocol.AMQMethodEvent):System.Boolean">
+ <Messages>
+ <Message Id="System.String.Format(System.String,System.Object,System.Object)" TypeName="SpecifyIFormatProvider" Category="Microsoft.Globalization" CheckId="CA1305" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>AMQStateManager.MethodReceived(AMQMethodEvent):Boolean</Item>
+ <Item>System.String.Format(System.String,System.Object,System.Object)</Item>
+ <Item>System.String.Format(System.IFormatProvider,System.String,System.Object[])</Item>
+ </Issue>
+ </Message>
+ <Message TypeName="ValidateArgumentsOfPublicMethods" Category="Microsoft.Design" CheckId="CA1062" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>'evt'</Item>
+ <Item>AMQStateManager.MethodReceived(AMQMethodEvent):Boolean</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="IAMQStateListener">
+ <Messages>
+ <Message TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Type">
+ <Item>IAMQStateListener</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ <Members>
+ <Member Name="StateChanged(Qpid.Client.State.AMQStateChangedEvent):System.Void">
+ <Messages>
+ <Message Id="0#evt" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>IAMQStateListener.StateChanged(AMQStateChangedEvent):Void</Item>
+ <Item>evt</Item>
+ <Item>evt</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="IllegalStateTransitionException">
+ <Messages>
+ <Message TypeName="ImplementStandardExceptionConstructors" Category="Microsoft.Design" CheckId="CA1032" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Qpid.Client.State.IllegalStateTransitionException</Item>
+ <Item>protected IllegalStateTransitionException(SerializationInfo, StreamingContext)</Item>
+ </Issue>
+ <Issue>
+ <Item>Qpid.Client.State.IllegalStateTransitionException</Item>
+ <Item>public IllegalStateTransitionException()</Item>
+ </Issue>
+ <Issue>
+ <Item>Qpid.Client.State.IllegalStateTransitionException</Item>
+ <Item>public IllegalStateTransitionException(String)</Item>
+ </Issue>
+ <Issue>
+ <Item>Qpid.Client.State.IllegalStateTransitionException</Item>
+ <Item>public IllegalStateTransitionException(String, Exception)</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ <Members>
+ <Member Name=".ctor(Qpid.Client.State.AMQState,System.Type)">
+ <Messages>
+ <Message Id="Qpid.AMQException.#ctor(System.String)" TypeName="DoNotPassLiteralsAsLocalizedParameters" Category="Microsoft.Globalization" CheckId="CA1303" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>IllegalStateTransitionException.IllegalStateTransitionException(AMQState, Type)</Item>
+ <Item>1</Item>
+ <Item>AMQException.AMQException(String)</Item>
+ <Item>No valid state transition defined for receiving frame ____ from state __</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="IStateAwareMethodListener">
+ <Members>
+ <Member Name="MethodReceived(Qpid.Client.State.AMQStateManager,Qpid.Client.Protocol.AMQMethodEvent):System.Void">
+ <Messages>
+ <Message Id="1#evt" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>IStateAwareMethodListener.MethodReceived(AMQStateManager, AMQMethodEvent):Void</Item>
+ <Item>evt</Item>
+ <Item>evt</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="IStateListener">
+ <Members>
+ <Member Name="Error(System.Exception):System.Void">
+ <Messages>
+ <Message Id="0#e" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="ParameterOneLetter">
+ <Item>IStateListener.Error(Exception):Void</Item>
+ <Item>e</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="StateWaiter">
+ <Messages>
+ <Message TypeName="TypesThatOwnDisposableFieldsShouldBeDisposable" Category="Microsoft.Design" CheckId="CA1001" Created="2006-12-04 13:11:47Z" FixCategory="Breaking">
+ <Issue>
+ <Item>Qpid.Client.State.StateWaiter</Item>
+ <Item>System.Threading.ManualResetEvent</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ <Members>
+ <Member Name="WaituntilStateHasChanged():System.Void">
+ <Messages>
+ <Message Id="Qpid.AMQException.#ctor(System.String,System.Exception)" TypeName="DoNotPassLiteralsAsLocalizedParameters" Category="Microsoft.Globalization" CheckId="CA1303" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>StateWaiter.WaituntilStateHasChanged():Void</Item>
+ <Item>1</Item>
+ <Item>AMQException.AMQException(String, Exception)</Item>
+ <Item>Error: __</Item>
+ </Issue>
+ </Message>
+ <Message Id="Waituntil" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>Waituntil</Item>
+ <Item>StateWaiter.WaituntilStateHasChanged():Void</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ </Types>
+ </Namespace>
+ <Namespace Name="Qpid.Client.Transport">
+ <Types>
+ <Type Name="AmqpChannel">
+ <Messages>
+ <Message Id="Amqp" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Type">
+ <Item>Amqp</Item>
+ <Item>Qpid.Client.Transport.AmqpChannel</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ <Members>
+ <Member Name=".ctor(Qpid.Client.Transport.IByteChannel)">
+ <Messages>
+ <Message Id="0#" TypeName="AvoidTypeNamesInParameters" Category="Microsoft.Naming" CheckId="CA1720" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>byteChannel</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Read():System.Collections.Queue">
+ <Messages>
+ <Message Id="System.String.Format(System.String,System.Object)" TypeName="SpecifyIFormatProvider" Category="Microsoft.Globalization" CheckId="CA1305" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>AmqpChannel.Read():Queue</Item>
+ <Item>System.String.Format(System.String,System.Object)</Item>
+ <Item>System.String.Format(System.IFormatProvider,System.String,System.Object[])</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Write(Qpid.Framing.IDataBlock):System.Void">
+ <Messages>
+ <Message Id="System.String.Format(System.String,System.Object)" TypeName="SpecifyIFormatProvider" Category="Microsoft.Globalization" CheckId="CA1305" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>AmqpChannel.Write(IDataBlock):Void</Item>
+ <Item>System.String.Format(System.String,System.Object)</Item>
+ <Item>System.String.Format(System.IFormatProvider,System.String,System.Object[])</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="AMQProtocolProvider">
+ <Messages>
+ <Message TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Type">
+ <Item>AMQProtocolProvider</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Type>
+ <Type Name="IProtocolWriter">
+ <Members>
+ <Member Name="Write(Qpid.Framing.IDataBlock):System.Void">
+ <Messages>
+ <Message Id="0#o" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="ParameterOneLetter">
+ <Item>IProtocolWriter.Write(IDataBlock):Void</Item>
+ <Item>o</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="ITransport">
+ <Members>
+ <Member Name="getLocalEndPoint():System.String">
+ <Messages>
+ <Message Id="EndPoint" TypeName="CompoundWordsShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1702" Created="2006-12-04 13:11:47Z">
+ <Issue Name="ShouldBeDiscreteTerm">
+ <Item>EndPoint</Item>
+ <Item>method</Item>
+ <Item>getLocalEndPoint</Item>
+ <Item>Endpoint</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>getLocalEndPoint</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="SingleProtocolEncoderOutput">
+ <Members>
+ <Member Name="buffer">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>buffer</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Write(Qpid.Buffer.ByteBuffer):System.Void">
+ <Messages>
+ <Message Id="System.InvalidOperationException.#ctor(System.String)" TypeName="DoNotPassLiteralsAsLocalizedParameters" Category="Microsoft.Globalization" CheckId="CA1303" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>SingleProtocolEncoderOutput.Write(ByteBuffer):Void</Item>
+ <Item>1</Item>
+ <Item>InvalidOperationException.InvalidOperationException(String)</Item>
+ <Item>{0} does not allow the writing of more than one buffer</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ </Types>
+ </Namespace>
+ </Namespaces>
+ </Module>
+ </Modules>
+ </Target>
+ <Target Name="$(ProjectDir)/Qpid.Client.Tests/bin/Debug/Qpid.Client.Tests.dll">
+ <Modules>
+ <Module Name="qpid.client.tests.dll">
+ <Messages>
+ <Message TypeName="AssembliesShouldDeclareMinimumSecurity" Category="Microsoft.Usage" CheckId="CA2209" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Qpid.Client.Tests</Item>
+ </Issue>
+ </Message>
+ <Message TypeName="AssembliesShouldHaveValidStrongNames" Category="Microsoft.Design" CheckId="CA2210" Created="2006-12-04 13:11:47Z">
+ <Issue Name="NoStrongName">
+ <Item>Qpid.Client.Tests</Item>
+ </Issue>
+ </Message>
+ <Message TypeName="MarkAssembliesWithClsCompliant" Category="Microsoft.Design" CheckId="CA1014" Created="2006-12-04 13:11:47Z">
+ <Issue Name="NoAttr">
+ <Item>Qpid.Client.Tests</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ <Namespaces>
+ <Namespace Name="Qpid.Client.Tests">
+ <Types>
+ <Type Name="Avergager">
+ <Members>
+ <Member Name=".ctor()">
+ <Messages>
+ <Message TypeName="DoNotInitializeUnnecessarily" Category="Microsoft.Performance" CheckId="CA1805" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Avergager.Avergager()</Item>
+ <Item>num</Item>
+ <Item>System.Int64</Item>
+ <Item>0</Item>
+ </Issue>
+ <Issue>
+ <Item>Avergager.Avergager()</Item>
+ <Item>sum</Item>
+ <Item>System.Int64</Item>
+ <Item>0</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="ToString():System.String">
+ <Messages>
+ <Message Id="System.String.Format(System.String,System.Object,System.Object,System.Object)" TypeName="SpecifyIFormatProvider" Category="Microsoft.Globalization" CheckId="CA1305" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Avergager.ToString():String</Item>
+ <Item>System.String.Format(System.String,System.Object,System.Object,System.Object)</Item>
+ <Item>System.String.Format(System.IFormatProvider,System.String,System.Object[])</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="BaseMessagingTestFixture">
+ <Messages>
+ <Message TypeName="TypesThatOwnDisposableFieldsShouldBeDisposable" Category="Microsoft.Design" CheckId="CA1001" Created="2006-12-04 13:11:47Z" FixCategory="Breaking">
+ <Issue>
+ <Item>Qpid.Client.Tests.BaseMessagingTestFixture</Item>
+ <Item>Qpid.Client.AMQConnection</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ <Members>
+ <Member Name="_channel">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>_channel</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>_channel</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="_connection">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>_connection</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>_connection</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Init():System.Void">
+ <Messages>
+ <Message TypeName="RethrowToPreserveStackDetails" Category="Microsoft.Usage" CheckId="CA2200" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>BaseMessagingTestFixture.Init():Void</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="HeadersMatchingConsumer">
+ <Messages>
+ <Message TypeName="TypesThatOwnDisposableFieldsShouldBeDisposable" Category="Microsoft.Design" CheckId="CA1001" Created="2006-12-04 13:11:47Z" FixCategory="Breaking">
+ <Issue>
+ <Item>Qpid.Client.Tests.HeadersMatchingConsumer</Item>
+ <Item>System.Threading.AutoResetEvent</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ <Members>
+ <Member Name="CreatePatternAsFieldTable():Qpid.Framing.FieldTable">
+ <Messages>
+ <Message TypeName="MarkMembersAsStatic" Category="Microsoft.Performance" CheckId="CA1822" Created="2006-12-04 13:11:47Z" FixCategory="NonBreaking">
+ <Issue>
+ <Item>HeadersMatchingConsumer.CreatePatternAsFieldTable():FieldTable</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="OnException(System.Exception):System.Void">
+ <Messages>
+ <Message Id="0#e" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="ParameterOneLetter">
+ <Item>HeadersMatchingConsumer.OnException(Exception):Void</Item>
+ <Item>e</Item>
+ </Issue>
+ </Message>
+ <Message TypeName="ValidateArgumentsOfPublicMethods" Category="Microsoft.Design" CheckId="CA1062" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>'e'</Item>
+ <Item>HeadersMatchingConsumer.OnException(Exception):Void</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="OnMessage(Qpid.Messaging.IMessage):System.Void">
+ <Messages>
+ <Message Id="System.String.Format(System.String,System.Object)" TypeName="SpecifyIFormatProvider" Category="Microsoft.Globalization" CheckId="CA1305" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>HeadersMatchingConsumer.OnMessage(IMessage):Void</Item>
+ <Item>System.String.Format(System.String,System.Object)</Item>
+ <Item>System.String.Format(System.IFormatProvider,System.String,System.Object[])</Item>
+ </Issue>
+ </Message>
+ <Message TypeName="ValidateArgumentsOfPublicMethods" Category="Microsoft.Design" CheckId="CA1062" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>'message'</Item>
+ <Item>HeadersMatchingConsumer.OnMessage(IMessage):Void</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="ProducerMultiConsumer">
+ <Messages>
+ <Message Id="Multi" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Type">
+ <Item>Multi</Item>
+ <Item>Qpid.Client.Tests.ProducerMultiConsumer</Item>
+ </Issue>
+ </Message>
+ <Message TypeName="TypesThatOwnDisposableFieldsShouldBeDisposable" Category="Microsoft.Design" CheckId="CA1001" Created="2006-12-04 13:11:47Z" FixCategory="Breaking">
+ <Issue>
+ <Item>Qpid.Client.Tests.ProducerMultiConsumer</Item>
+ <Item>System.Threading.AutoResetEvent</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ <Members>
+ <Member Name=".ctor()">
+ <Messages>
+ <Message TypeName="DoNotInitializeUnnecessarily" Category="Microsoft.Performance" CheckId="CA1805" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>ProducerMultiConsumer.ProducerMultiConsumer()</Item>
+ <Item>_messageReceivedCount</Item>
+ <Item>System.Int32</Item>
+ <Item>0</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="OnMessage(Qpid.Messaging.IMessage):System.Void">
+ <Messages>
+ <Message Id="0#m" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="ParameterOneLetter">
+ <Item>ProducerMultiConsumer.OnMessage(IMessage):Void</Item>
+ <Item>m</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="RunTest():System.Void">
+ <Messages>
+ <Message TypeName="DoNotCatchGeneralExceptionTypes" Category="Microsoft.Design" CheckId="CA1031" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>ProducerMultiConsumer.RunTest():Void</Item>
+ <Item>System.Exception</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="ServiceProvidingClient">
+ <Messages>
+ <Message TypeName="TypesThatOwnDisposableFieldsShouldBeDisposable" Category="Microsoft.Design" CheckId="CA1001" Created="2006-12-04 13:11:47Z" FixCategory="Breaking">
+ <Issue>
+ <Item>Qpid.Client.Tests.ServiceProvidingClient</Item>
+ <Item>System.Threading.AutoResetEvent</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ <Members>
+ <Member Name=".ctor()">
+ <Messages>
+ <Message TypeName="DoNotInitializeUnnecessarily" Category="Microsoft.Performance" CheckId="CA1805" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>ServiceProvidingClient.ServiceProvidingClient()</Item>
+ <Item>_selector</Item>
+ <Item>System.String</Item>
+ <Item>null</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="OnMessage(Qpid.Messaging.IMessage):System.Void">
+ <Messages>
+ <Message TypeName="RethrowToPreserveStackDetails" Category="Microsoft.Usage" CheckId="CA2200" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>ServiceProvidingClient.OnMessage(IMessage):Void</Item>
+ </Issue>
+ <Issue>
+ <Item>ServiceProvidingClient.OnMessage(IMessage):Void</Item>
+ </Issue>
+ </Message>
+ <Message Id="System.String.Format(System.String,System.Object,System.Object)" TypeName="SpecifyIFormatProvider" Category="Microsoft.Globalization" CheckId="CA1305" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>ServiceProvidingClient.OnMessage(IMessage):Void</Item>
+ <Item>System.String.Format(System.String,System.Object,System.Object)</Item>
+ <Item>System.String.Format(System.IFormatProvider,System.String,System.Object[])</Item>
+ </Issue>
+ <Issue>
+ <Item>ServiceProvidingClient.OnMessage(IMessage):Void</Item>
+ <Item>System.String.Format(System.String,System.Object,System.Object)</Item>
+ <Item>System.String.Format(System.IFormatProvider,System.String,System.Object[])</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="ServiceRequestingClient">
+ <Messages>
+ <Message TypeName="TypesThatOwnDisposableFieldsShouldBeDisposable" Category="Microsoft.Design" CheckId="CA1001" Created="2006-12-04 13:11:47Z" FixCategory="Breaking">
+ <Issue>
+ <Item>Qpid.Client.Tests.ServiceRequestingClient</Item>
+ <Item>System.Threading.AutoResetEvent</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ <Members>
+ <Member Name="Main(System.String[]):System.Void">
+ <Messages>
+ <Message Id="args" TypeName="ReviewUnusedParameters" Category="Microsoft.Usage" CheckId="CA1801" Created="2006-12-04 13:11:47Z" FixCategory="Breaking">
+ <Issue>
+ <Item>args</Item>
+ <Item>ServiceRequestingClient.Main(String[]):Void</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="OnMessage(Qpid.Messaging.IMessage):System.Void">
+ <Messages>
+ <Message Id="System.Exception.#ctor(System.String)" TypeName="DoNotPassLiteralsAsLocalizedParameters" Category="Microsoft.Globalization" CheckId="CA1303" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>ServiceRequestingClient.OnMessage(IMessage):Void</Item>
+ <Item>1</Item>
+ <Item>Exception.Exception(String)</Item>
+ <Item>Set timeSent!</Item>
+ </Issue>
+ </Message>
+ <Message TypeName="DoNotRaiseReservedExceptionTypes" Category="Microsoft.Usage" CheckId="CA2201" Created="2006-12-04 13:11:47Z">
+ <Issue Name="TooGeneric">
+ <Item>ServiceRequestingClient.OnMessage(IMessage):Void</Item>
+ <Item>System.Exception</Item>
+ </Issue>
+ </Message>
+ <Message Id="0#m" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="ParameterOneLetter">
+ <Item>ServiceRequestingClient.OnMessage(IMessage):Void</Item>
+ <Item>m</Item>
+ </Issue>
+ </Message>
+ <Message Id="System.Int64.Parse(System.String)" TypeName="SpecifyIFormatProvider" Category="Microsoft.Globalization" CheckId="CA1305" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>ServiceRequestingClient.OnMessage(IMessage):Void</Item>
+ <Item>System.Int64.Parse(System.String)</Item>
+ <Item>System.Int64.Parse(System.String,System.IFormatProvider)</Item>
+ </Issue>
+ </Message>
+ <Message Id="System.String.Format(System.String,System.Object)" TypeName="SpecifyIFormatProvider" Category="Microsoft.Globalization" CheckId="CA1305" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>ServiceRequestingClient.OnMessage(IMessage):Void</Item>
+ <Item>System.String.Format(System.String,System.Object)</Item>
+ <Item>System.String.Format(System.IFormatProvider,System.String,System.Object[])</Item>
+ </Issue>
+ <Issue>
+ <Item>ServiceRequestingClient.OnMessage(IMessage):Void</Item>
+ <Item>System.String.Format(System.String,System.Object)</Item>
+ <Item>System.String.Format(System.IFormatProvider,System.String,System.Object[])</Item>
+ </Issue>
+ </Message>
+ <Message TypeName="ValidateArgumentsOfPublicMethods" Category="Microsoft.Design" CheckId="CA1062" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>'m'</Item>
+ <Item>ServiceRequestingClient.OnMessage(IMessage):Void</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="SendMessages():System.Void">
+ <Messages>
+ <Message TypeName="DoNotCatchGeneralExceptionTypes" Category="Microsoft.Design" CheckId="CA1031" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>ServiceRequestingClient.SendMessages():Void</Item>
+ <Item>System.Exception</Item>
+ </Issue>
+ <Issue>
+ <Item>ServiceRequestingClient.SendMessages():Void</Item>
+ <Item>System.Exception</Item>
+ </Issue>
+ <Issue>
+ <Item>ServiceRequestingClient.SendMessages():Void</Item>
+ <Item>System.Exception</Item>
+ </Issue>
+ </Message>
+ <Message Id="System.String.Format(System.String,System.Object)" TypeName="SpecifyIFormatProvider" Category="Microsoft.Globalization" CheckId="CA1305" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>ServiceRequestingClient.SendMessages():Void</Item>
+ <Item>System.String.Format(System.String,System.Object)</Item>
+ <Item>System.String.Format(System.IFormatProvider,System.String,System.Object[])</Item>
+ </Issue>
+ <Issue>
+ <Item>ServiceRequestingClient.SendMessages():Void</Item>
+ <Item>System.String.Format(System.String,System.Object)</Item>
+ <Item>System.String.Format(System.IFormatProvider,System.String,System.Object[])</Item>
+ </Issue>
+ <Issue>
+ <Item>ServiceRequestingClient.SendMessages():Void</Item>
+ <Item>System.String.Format(System.String,System.Object)</Item>
+ <Item>System.String.Format(System.IFormatProvider,System.String,System.Object[])</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="UndeliverableTest">
+ <Members>
+ <Member Name="OnException(System.Exception):System.Void">
+ <Messages>
+ <Message TypeName="DoNotCastUnnecessarily" Category="Microsoft.Performance" CheckId="CA1800" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>e</Item>
+ <Item>Qpid.Messaging.QpidException</Item>
+ <Item>UndeliverableTest.OnException(Exception):Void</Item>
+ <Item>castclass</Item>
+ </Issue>
+ </Message>
+ <Message Id="0#e" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="ParameterOneLetter">
+ <Item>UndeliverableTest.OnException(Exception):Void</Item>
+ <Item>e</Item>
+ </Issue>
+ </Message>
+ <Message Id="System.String.Format(System.String,System.Object)" TypeName="SpecifyIFormatProvider" Category="Microsoft.Globalization" CheckId="CA1305" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>UndeliverableTest.OnException(Exception):Void</Item>
+ <Item>System.String.Format(System.String,System.Object)</Item>
+ <Item>System.String.Format(System.IFormatProvider,System.String,System.Object[])</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ </Types>
+ </Namespace>
+ <Namespace Name="Qpid.Client.Tests.connection">
+ <Types>
+ <Type Name="ConnectionTest">
+ <Members>
+ <Member Name="passwordFailureConnection():System.Void">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>passwordFailureConnection</Item>
+ </Issue>
+ </Message>
+ <Message TypeName="MarkMembersAsStatic" Category="Microsoft.Performance" CheckId="CA1822" Created="2006-12-04 13:11:47Z" FixCategory="Breaking">
+ <Issue>
+ <Item>ConnectionTest.passwordFailureConnection():Void</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="simpleConnection():System.Void">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>simpleConnection</Item>
+ </Issue>
+ </Message>
+ <Message TypeName="MarkMembersAsStatic" Category="Microsoft.Performance" CheckId="CA1822" Created="2006-12-04 13:11:47Z" FixCategory="Breaking">
+ <Issue>
+ <Item>ConnectionTest.simpleConnection():Void</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ </Types>
+ </Namespace>
+ <Namespace Name="Qpid.Client.Tests.failover">
+ <Types>
+ <Type Name="FailoverTest">
+ <Members>
+ <Member Name="DoFailoverTest(Qpid.Messaging.IConnection):System.Void">
+ <Messages>
+ <Message Id="Qpid.Client.Tests.failover.FailoverTest+MsgListener" TypeName="DoNotIgnoreMethodResults" Category="Microsoft.Usage" CheckId="CA1806" Created="2006-12-04 13:11:47Z">
+ <Issue Name="ObjectCreation">
+ <Item>FailoverTest.DoFailoverTest(IConnection):Void</Item>
+ <Item>Qpid.Client.Tests.failover.FailoverTest+MsgListener</Item>
+ </Issue>
+ </Message>
+ <Message Id="System.String.Format(System.String,System.Object)" TypeName="SpecifyIFormatProvider" Category="Microsoft.Globalization" CheckId="CA1305" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>FailoverTest.DoFailoverTest(IConnection):Void</Item>
+ <Item>System.String.Format(System.String,System.Object)</Item>
+ <Item>System.String.Format(System.IFormatProvider,System.String,System.Object[])</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="OnMessage(Qpid.Messaging.IMessage):System.Void">
+ <Messages>
+ <Message TypeName="ValidateArgumentsOfPublicMethods" Category="Microsoft.Design" CheckId="CA1062" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>'message'</Item>
+ <Item>FailoverTest.OnMessage(IMessage):Void</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="TestWithBasicInfo():System.Void">
+ <Messages>
+ <Message TypeName="DoNotCatchGeneralExceptionTypes" Category="Microsoft.Design" CheckId="CA1031" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>FailoverTest.TestWithBasicInfo():Void</Item>
+ <Item>System.Exception</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="FailoverTest+MsgListener">
+ <Members>
+ <Member Name="init(Qpid.Messaging.IMessage):Qpid.Messaging.IMessagePublisher">
+ <Messages>
+ <Message Id="System.String.Format(System.String,System.Object,System.Object)" TypeName="SpecifyIFormatProvider" Category="Microsoft.Globalization" CheckId="CA1305" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>MsgListener.init(IMessage):IMessagePublisher</Item>
+ <Item>System.String.Format(System.String,System.Object,System.Object)</Item>
+ <Item>System.String.Format(System.IFormatProvider,System.String,System.Object[])</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="FailoverTxTest">
+ <Messages>
+ <Message TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Type">
+ <Item>Tx</Item>
+ <Item>Qpid.Client.Tests.failover.FailoverTxTest</Item>
+ </Issue>
+ </Message>
+ <Message TypeName="TypesThatOwnDisposableFieldsShouldBeDisposable" Category="Microsoft.Design" CheckId="CA1001" Created="2006-12-04 13:11:47Z" FixCategory="Breaking">
+ <Issue>
+ <Item>Qpid.Client.Tests.failover.FailoverTxTest</Item>
+ <Item>Qpid.Client.AMQConnection</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ <Members>
+ <Member Name="OnMessage(Qpid.Messaging.IMessage):System.Void">
+ <Messages>
+ <Message TypeName="ValidateArgumentsOfPublicMethods" Category="Microsoft.Design" CheckId="CA1062" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>'message'</Item>
+ <Item>FailoverTxTest.OnMessage(IMessage):Void</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="TestWithBasicInfo():System.Void">
+ <Messages>
+ <Message TypeName="DoNotCatchGeneralExceptionTypes" Category="Microsoft.Design" CheckId="CA1031" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>FailoverTxTest.TestWithBasicInfo():Void</Item>
+ <Item>System.Exception</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ </Types>
+ </Namespace>
+ <Namespace Name="Qpid.Client.Transport">
+ <Types>
+ <Type Name="BlockingIo">
+ <Messages>
+ <Message TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Type">
+ <Item>Io</Item>
+ <Item>Qpid.Client.Transport.BlockingIo</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ <Members>
+ <Member Name="connectFromOutside():System.Void">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>connectFromOutside</Item>
+ </Issue>
+ </Message>
+ <Message TypeName="MarkMembersAsStatic" Category="Microsoft.Performance" CheckId="CA1822" Created="2006-12-04 13:11:47Z" FixCategory="Breaking">
+ <Issue>
+ <Item>BlockingIo.connectFromOutside():Void</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="connectionAndSleepForHeartbeats():System.Void">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>connectionAndSleepForHeartbeats</Item>
+ </Issue>
+ </Message>
+ <Message TypeName="MarkMembersAsStatic" Category="Microsoft.Performance" CheckId="CA1822" Created="2006-12-04 13:11:47Z" FixCategory="Breaking">
+ <Issue>
+ <Item>BlockingIo.connectionAndSleepForHeartbeats():Void</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="regularConnection():System.Void">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>regularConnection</Item>
+ </Issue>
+ </Message>
+ <Message TypeName="MarkMembersAsStatic" Category="Microsoft.Performance" CheckId="CA1822" Created="2006-12-04 13:11:47Z" FixCategory="Breaking">
+ <Issue>
+ <Item>BlockingIo.regularConnection():Void</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ </Types>
+ </Namespace>
+ </Namespaces>
+ </Module>
+ </Modules>
+ </Target>
+ <Target Name="$(ProjectDir)/Qpid.Client.Tests/bin/Debug/Qpid.Client.Transport.Socket.Blocking.dll">
+ <Modules>
+ <Module Name="qpid.client.transport.socket.blocking.dll">
+ <Messages>
+ <Message TypeName="AssembliesShouldDeclareMinimumSecurity" Category="Microsoft.Usage" CheckId="CA2209" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Qpid.Client.Transport.Socket.Blocking</Item>
+ </Issue>
+ </Message>
+ <Message TypeName="AssembliesShouldHaveValidStrongNames" Category="Microsoft.Design" CheckId="CA2210" Created="2006-12-04 13:11:47Z">
+ <Issue Name="NoStrongName">
+ <Item>Qpid.Client.Transport.Socket.Blocking</Item>
+ </Issue>
+ </Message>
+ <Message TypeName="MarkAssembliesWithClsCompliant" Category="Microsoft.Design" CheckId="CA1014" Created="2006-12-04 13:11:47Z">
+ <Issue Name="NoAttr">
+ <Item>Qpid.Client.Transport.Socket.Blocking</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ <Namespaces>
+ <Namespace Name="Qpid.Client.Transport.Socket.Blocking">
+ <Types>
+ <Type Name="BlockingSocketProcessor">
+ <Members>
+ <Member Name="Write(Qpid.Buffer.ByteBuffer):System.Void">
+ <Messages>
+ <Message TypeName="DoNotCatchGeneralExceptionTypes" Category="Microsoft.Design" CheckId="CA1031" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>BlockingSocketProcessor.Write(ByteBuffer):Void</Item>
+ <Item>System.Exception</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="BlockingSocketTransport">
+ <Members>
+ <Member Name=".ctor(System.String,System.Int32,Qpid.Client.AMQConnection)">
+ <Messages>
+ <Message TypeName="ValidateArgumentsOfPublicMethods" Category="Microsoft.Design" CheckId="CA1062" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>'connection'</Item>
+ <Item>BlockingSocketTransport.BlockingSocketTransport(String, Int32, AMQConnection)</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="_log">
+ <Messages>
+ <Message TypeName="AvoidUnusedPrivateFields" Category="Microsoft.Performance" CheckId="CA1823" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>BlockingSocketTransport._log</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="BlockingSocketTransport+ReaderRunner">
+ <Members>
+ <Member Name="Run():System.Void">
+ <Messages>
+ <Message TypeName="DoNotCatchGeneralExceptionTypes" Category="Microsoft.Design" CheckId="CA1031" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>ReaderRunner.Run():Void</Item>
+ <Item>System.Exception</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="ByteChannel">
+ <Members>
+ <Member Name="Read():Qpid.Buffer.ByteBuffer">
+ <Messages>
+ <Message Id="System.String.Format(System.String,System.Object)" TypeName="SpecifyIFormatProvider" Category="Microsoft.Globalization" CheckId="CA1305" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>ByteChannel.Read():ByteBuffer</Item>
+ <Item>System.String.Format(System.String,System.Object)</Item>
+ <Item>System.String.Format(System.IFormatProvider,System.String,System.Object[])</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Write(Qpid.Buffer.ByteBuffer):System.Void">
+ <Messages>
+ <Message Id="System.String.Format(System.String,System.Object)" TypeName="SpecifyIFormatProvider" Category="Microsoft.Globalization" CheckId="CA1305" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>ByteChannel.Write(ByteBuffer):Void</Item>
+ <Item>System.String.Format(System.String,System.Object)</Item>
+ <Item>System.String.Format(System.IFormatProvider,System.String,System.Object[])</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ </Types>
+ </Namespace>
+ </Namespaces>
+ </Module>
+ </Modules>
+ </Target>
+ <Target Name="$(ProjectDir)/Qpid.Client.Tests/bin/Debug/Qpid.Codec.dll">
+ <Modules>
+ <Module Name="qpid.codec.dll">
+ <Messages>
+ <Message TypeName="AssembliesShouldDeclareMinimumSecurity" Category="Microsoft.Usage" CheckId="CA2209" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Qpid.Codec</Item>
+ </Issue>
+ </Message>
+ <Message TypeName="AssembliesShouldHaveValidStrongNames" Category="Microsoft.Design" CheckId="CA2210" Created="2006-12-04 13:11:47Z">
+ <Issue Name="NoStrongName">
+ <Item>Qpid.Codec</Item>
+ </Issue>
+ </Message>
+ <Message TypeName="MarkAssembliesWithClsCompliant" Category="Microsoft.Design" CheckId="CA1014" Created="2006-12-04 13:11:47Z">
+ <Issue Name="NoAttr">
+ <Item>Qpid.Codec</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ <Namespaces>
+ <Namespace Name="Qpid.Codec">
+ <Types>
+ <Type Name="CumulativeProtocolDecoder">
+ <Members>
+ <Member Name="DecodeAll(Qpid.Buffer.ByteBuffer,Qpid.Codec.IProtocolDecoderOutput):System.Void">
+ <Messages>
+ <Message Id="System.Exception.#ctor(System.String)" TypeName="DoNotPassLiteralsAsLocalizedParameters" Category="Microsoft.Globalization" CheckId="CA1303" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>CumulativeProtocolDecoder.DecodeAll(ByteBuffer, IProtocolDecoderOutput):Void</Item>
+ <Item>1</Item>
+ <Item>Exception.Exception(String)</Item>
+ <Item>doDecode() can't return true when buffer is not consumed.</Item>
+ </Issue>
+ </Message>
+ <Message TypeName="DoNotRaiseReservedExceptionTypes" Category="Microsoft.Usage" CheckId="CA2201" Created="2006-12-04 13:11:47Z">
+ <Issue Name="TooGeneric">
+ <Item>CumulativeProtocolDecoder.DecodeAll(ByteBuffer, IProtocolDecoderOutput):Void</Item>
+ <Item>System.Exception</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Dispose():System.Void">
+ <Messages>
+ <Message TypeName="ImplementIDisposableCorrectly" Category="Microsoft.Design" CheckId="CA1063" Created="2006-12-04 13:11:47Z">
+ <Issue Name="DisposeImplementation">
+ <Item>CumulativeProtocolDecoder.Dispose():Void</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="IProtocolEncoderOutput">
+ <Members>
+ <Member Name="Write(Qpid.Buffer.ByteBuffer):System.Void">
+ <Messages>
+ <Message Id="0#buf" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>IProtocolEncoderOutput.Write(ByteBuffer):Void</Item>
+ <Item>buf</Item>
+ <Item>buf</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="ProtocolCodecException">
+ <Messages>
+ <Message TypeName="ImplementStandardExceptionConstructors" Category="Microsoft.Design" CheckId="CA1032" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Qpid.Codec.ProtocolCodecException</Item>
+ <Item>protected ProtocolCodecException(SerializationInfo, StreamingContext)</Item>
+ </Issue>
+ <Issue>
+ <Item>Qpid.Codec.ProtocolCodecException</Item>
+ <Item>public ProtocolCodecException(String, Exception)</Item>
+ </Issue>
+ </Message>
+ <Message TypeName="MarkISerializableTypesWithSerializable" Category="Microsoft.Usage" CheckId="CA2237" Created="2006-12-04 13:11:47Z">
+ <Issue Level="Error">
+ <Item>ProtocolCodecException</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ <Members>
+ <Member Name=".ctor(System.Exception)">
+ <Messages>
+ <Message Id="System.Exception.#ctor(System.String,System.Exception)" TypeName="DoNotPassLiteralsAsLocalizedParameters" Category="Microsoft.Globalization" CheckId="CA1303" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>ProtocolCodecException.ProtocolCodecException(Exception)</Item>
+ <Item>1</Item>
+ <Item>Exception.Exception(String, Exception)</Item>
+ <Item>Codec Exception</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="ProtocolDecoderException">
+ <Messages>
+ <Message TypeName="ImplementStandardExceptionConstructors" Category="Microsoft.Design" CheckId="CA1032" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Qpid.Codec.ProtocolDecoderException</Item>
+ <Item>protected ProtocolDecoderException(SerializationInfo, StreamingContext)</Item>
+ </Issue>
+ <Issue>
+ <Item>Qpid.Codec.ProtocolDecoderException</Item>
+ <Item>public ProtocolDecoderException(String, Exception)</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Type>
+ <Type Name="ProtocolEncoderException">
+ <Messages>
+ <Message TypeName="ImplementStandardExceptionConstructors" Category="Microsoft.Design" CheckId="CA1032" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Qpid.Codec.ProtocolEncoderException</Item>
+ <Item>protected ProtocolEncoderException(SerializationInfo, StreamingContext)</Item>
+ </Issue>
+ <Issue>
+ <Item>Qpid.Codec.ProtocolEncoderException</Item>
+ <Item>public ProtocolEncoderException(String, Exception)</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Type>
+ </Types>
+ </Namespace>
+ <Namespace Name="Qpid.Codec.Demux">
+ <Types>
+ <Type Name="DemuxingProtocolCodecFactory">
+ <Messages>
+ <Message Id="Demuxing" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Type">
+ <Item>Demuxing</Item>
+ <Item>Qpid.Codec.Demux.DemuxingProtocolCodecFactory</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ <Members>
+ <Member Name="DisposeCodecResources():System.Void">
+ <Messages>
+ <Message TypeName="MarkMembersAsStatic" Category="Microsoft.Performance" CheckId="CA1822" Created="2006-12-04 13:11:47Z" FixCategory="Breaking">
+ <Issue>
+ <Item>DemuxingProtocolCodecFactory.DisposeCodecResources():Void</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Register(System.Type):System.Void">
+ <Messages>
+ <Message Id="System.ArgumentException.#ctor(System.String)" TypeName="DoNotPassLiteralsAsLocalizedParameters" Category="Microsoft.Globalization" CheckId="CA1303" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>DemuxingProtocolCodecFactory.Register(Type):Void</Item>
+ <Item>1</Item>
+ <Item>ArgumentException.ArgumentException(String)</Item>
+ <Item>Unregisterable type: __</Item>
+ </Issue>
+ </Message>
+ <Message Id="Unregisterable" TypeName="LiteralsShouldBeSpelledCorrectly" Category="Microsoft.Usage" CheckId="CA2204" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Unregisterable</Item>
+ <Item>Unregisterable type: __</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="DemuxingProtocolCodecFactory+DefaultConstructorMessageDecoderFactory">
+ <Members>
+ <Member Name=".ctor(System.Type)">
+ <Messages>
+ <Message Id="System.ArgumentException.#ctor(System.String)" TypeName="DoNotPassLiteralsAsLocalizedParameters" Category="Microsoft.Globalization" CheckId="CA1303" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>DefaultConstructorMessageDecoderFactory.DefaultConstructorMessageDecoderFactory(Type)</Item>
+ <Item>1</Item>
+ <Item>ArgumentException.ArgumentException(String)</Item>
+ <Item>decoderClass is not assignable to MessageDecoder</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="NewDecoder():Qpid.Codec.Demux.IMessageDecoder">
+ <Messages>
+ <Message Id="System.Exception.#ctor(System.String,System.Exception)" TypeName="DoNotPassLiteralsAsLocalizedParameters" Category="Microsoft.Globalization" CheckId="CA1303" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>DefaultConstructorMessageDecoderFactory.NewDecoder():IMessageDecoder</Item>
+ <Item>1</Item>
+ <Item>Exception.Exception(String, Exception)</Item>
+ <Item>Failed to create a new instance of __</Item>
+ </Issue>
+ </Message>
+ <Message TypeName="DoNotRaiseReservedExceptionTypes" Category="Microsoft.Usage" CheckId="CA2201" Created="2006-12-04 13:11:47Z">
+ <Issue Name="TooGeneric">
+ <Item>DefaultConstructorMessageDecoderFactory.NewDecoder():IMessageDecoder</Item>
+ <Item>System.Exception</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="DemuxingProtocolCodecFactory+DefaultConstructorMessageEncoderFactory">
+ <Members>
+ <Member Name=".ctor(System.Type)">
+ <Messages>
+ <Message Id="System.ArgumentException.#ctor(System.String)" TypeName="DoNotPassLiteralsAsLocalizedParameters" Category="Microsoft.Globalization" CheckId="CA1303" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>DefaultConstructorMessageEncoderFactory.DefaultConstructorMessageEncoderFactory(Type)</Item>
+ <Item>1</Item>
+ <Item>ArgumentException.ArgumentException(String)</Item>
+ <Item>encoderClass is not assignable to MessageEncoder</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="NewEncoder():Qpid.Codec.Demux.IMessageEncoder">
+ <Messages>
+ <Message Id="System.Exception.#ctor(System.String,System.Exception)" TypeName="DoNotPassLiteralsAsLocalizedParameters" Category="Microsoft.Globalization" CheckId="CA1303" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>DefaultConstructorMessageEncoderFactory.NewEncoder():IMessageEncoder</Item>
+ <Item>1</Item>
+ <Item>Exception.Exception(String, Exception)</Item>
+ <Item>Failed to create a new instance of __</Item>
+ </Issue>
+ </Message>
+ <Message TypeName="DoNotRaiseReservedExceptionTypes" Category="Microsoft.Usage" CheckId="CA2201" Created="2006-12-04 13:11:47Z">
+ <Issue Name="TooGeneric">
+ <Item>DefaultConstructorMessageEncoderFactory.NewEncoder():IMessageEncoder</Item>
+ <Item>System.Exception</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="DemuxingProtocolCodecFactory+ProtocolDecoderImpl">
+ <Members>
+ <Member Name="DoDecode(Qpid.Buffer.ByteBuffer,Qpid.Codec.IProtocolDecoderOutput):System.Boolean">
+ <Messages>
+ <Message Id="Qpid.Codec.ProtocolDecoderException.#ctor(System.String)" TypeName="DoNotPassLiteralsAsLocalizedParameters" Category="Microsoft.Globalization" CheckId="CA1303" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>ProtocolDecoderImpl.DoDecode(ByteBuffer, IProtocolDecoderOutput):Boolean</Item>
+ <Item>1</Item>
+ <Item>ProtocolDecoderException.ProtocolDecoderException(String)</Item>
+ <Item>Message decoder returned NOT_OK.</Item>
+ </Issue>
+ </Message>
+ <Message Id="System.Exception.#ctor(System.String)" TypeName="DoNotPassLiteralsAsLocalizedParameters" Category="Microsoft.Globalization" CheckId="CA1303" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>ProtocolDecoderImpl.DoDecode(ByteBuffer, IProtocolDecoderOutput):Boolean</Item>
+ <Item>1</Item>
+ <Item>Exception.Exception(String)</Item>
+ <Item>Unexpected decode result (see your decode()): __</Item>
+ </Issue>
+ </Message>
+ <Message TypeName="DoNotRaiseReservedExceptionTypes" Category="Microsoft.Usage" CheckId="CA2201" Created="2006-12-04 13:11:47Z">
+ <Issue Name="TooGeneric">
+ <Item>ProtocolDecoderImpl.DoDecode(ByteBuffer, IProtocolDecoderOutput):Boolean</Item>
+ <Item>System.Exception</Item>
+ </Issue>
+ <Issue Name="TooGeneric">
+ <Item>ProtocolDecoderImpl.DoDecode(ByteBuffer, IProtocolDecoderOutput):Boolean</Item>
+ <Item>System.Exception</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="MessageDecoderResult">
+ <Members>
+ <Member Name="NEED_DATA">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>NEED_DATA</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>MessageDecoderResult.NEED_DATA</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="NOT_OK">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>NOT_OK</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberOk">
+ <Item>MessageDecoderResult.NOT_OK</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="OK">
+ <Messages>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberOk">
+ <Item>MessageDecoderResult.OK</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ </Types>
+ </Namespace>
+ </Namespaces>
+ </Module>
+ </Modules>
+ </Target>
+ <Target Name="$(ProjectDir)/Qpid.Client.Tests/bin/Debug/Qpid.Common.dll">
+ <Modules>
+ <Module Name="qpid.common.dll">
+ <Messages>
+ <Message TypeName="AssembliesShouldDeclareMinimumSecurity" Category="Microsoft.Usage" CheckId="CA2209" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Qpid.Common</Item>
+ </Issue>
+ </Message>
+ <Message TypeName="AssembliesShouldHaveValidStrongNames" Category="Microsoft.Design" CheckId="CA2210" Created="2006-12-04 13:11:47Z">
+ <Issue Name="NoStrongName">
+ <Item>Qpid.Common</Item>
+ </Issue>
+ </Message>
+ <Message TypeName="MarkAssembliesWithClsCompliant" Category="Microsoft.Design" CheckId="CA1014" Created="2006-12-04 13:11:47Z">
+ <Issue Name="NoAttr">
+ <Item>Qpid.Common</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ <Namespaces>
+ <Namespace Name="Qpid">
+ <Types>
+ <Type Name="AMQChannelClosedException">
+ <Messages>
+ <Message TypeName="ImplementStandardExceptionConstructors" Category="Microsoft.Design" CheckId="CA1032" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Qpid.AMQChannelClosedException</Item>
+ <Item>protected AMQChannelClosedException(SerializationInfo, StreamingContext)</Item>
+ </Issue>
+ <Issue>
+ <Item>Qpid.AMQChannelClosedException</Item>
+ <Item>public AMQChannelClosedException()</Item>
+ </Issue>
+ <Issue>
+ <Item>Qpid.AMQChannelClosedException</Item>
+ <Item>public AMQChannelClosedException(String)</Item>
+ </Issue>
+ <Issue>
+ <Item>Qpid.AMQChannelClosedException</Item>
+ <Item>public AMQChannelClosedException(String, Exception)</Item>
+ </Issue>
+ </Message>
+ <Message TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Type">
+ <Item>AMQChannelClosedException</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Type>
+ <Type Name="AMQConnectionClosedException">
+ <Messages>
+ <Message TypeName="ImplementStandardExceptionConstructors" Category="Microsoft.Design" CheckId="CA1032" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Qpid.AMQConnectionClosedException</Item>
+ <Item>protected AMQConnectionClosedException(SerializationInfo, StreamingContext)</Item>
+ </Issue>
+ <Issue>
+ <Item>Qpid.AMQConnectionClosedException</Item>
+ <Item>public AMQConnectionClosedException()</Item>
+ </Issue>
+ <Issue>
+ <Item>Qpid.AMQConnectionClosedException</Item>
+ <Item>public AMQConnectionClosedException(String)</Item>
+ </Issue>
+ <Issue>
+ <Item>Qpid.AMQConnectionClosedException</Item>
+ <Item>public AMQConnectionClosedException(String, Exception)</Item>
+ </Issue>
+ </Message>
+ <Message TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Type">
+ <Item>AMQConnectionClosedException</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Type>
+ <Type Name="AMQDisconnectedException">
+ <Messages>
+ <Message TypeName="ImplementStandardExceptionConstructors" Category="Microsoft.Design" CheckId="CA1032" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Qpid.AMQDisconnectedException</Item>
+ <Item>protected AMQDisconnectedException(SerializationInfo, StreamingContext)</Item>
+ </Issue>
+ <Issue>
+ <Item>Qpid.AMQDisconnectedException</Item>
+ <Item>public AMQDisconnectedException()</Item>
+ </Issue>
+ <Issue>
+ <Item>Qpid.AMQDisconnectedException</Item>
+ <Item>public AMQDisconnectedException(String, Exception)</Item>
+ </Issue>
+ </Message>
+ <Message TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Type">
+ <Item>AMQDisconnectedException</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Type>
+ <Type Name="AMQException">
+ <Messages>
+ <Message TypeName="ImplementStandardExceptionConstructors" Category="Microsoft.Design" CheckId="CA1032" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Qpid.AMQException</Item>
+ <Item>protected AMQException(SerializationInfo, StreamingContext)</Item>
+ </Issue>
+ <Issue>
+ <Item>Qpid.AMQException</Item>
+ <Item>public AMQException()</Item>
+ </Issue>
+ </Message>
+ <Message TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Type">
+ <Item>AMQException</Item>
+ </Issue>
+ </Message>
+ <Message TypeName="MarkISerializableTypesWithSerializable" Category="Microsoft.Usage" CheckId="CA2237" Created="2006-12-04 13:11:47Z">
+ <Issue Level="Error">
+ <Item>AMQException</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ <Members>
+ <Member Name=".ctor(log4net.ILog,System.Int32,System.String)">
+ <Messages>
+ <Message TypeName="ValidateArgumentsOfPublicMethods" Category="Microsoft.Design" CheckId="CA1062" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>'logger'</Item>
+ <Item>AMQException.AMQException(ILog, Int32, String)</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name=".ctor(log4net.ILog,System.Int32,System.String,System.Exception)">
+ <Messages>
+ <Message TypeName="ValidateArgumentsOfPublicMethods" Category="Microsoft.Design" CheckId="CA1062" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>'logger'</Item>
+ <Item>AMQException.AMQException(ILog, Int32, String, Exception)</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name=".ctor(log4net.ILog,System.String)">
+ <Messages>
+ <Message TypeName="ValidateArgumentsOfPublicMethods" Category="Microsoft.Design" CheckId="CA1062" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>'logger'</Item>
+ <Item>AMQException.AMQException(ILog, String)</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name=".ctor(log4net.ILog,System.String,System.Exception)">
+ <Messages>
+ <Message TypeName="ValidateArgumentsOfPublicMethods" Category="Microsoft.Design" CheckId="CA1062" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>'logger'</Item>
+ <Item>AMQException.AMQException(ILog, String, Exception)</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="AMQUndeliveredException">
+ <Messages>
+ <Message TypeName="ImplementStandardExceptionConstructors" Category="Microsoft.Design" CheckId="CA1032" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Qpid.AMQUndeliveredException</Item>
+ <Item>protected AMQUndeliveredException(SerializationInfo, StreamingContext)</Item>
+ </Issue>
+ <Issue>
+ <Item>Qpid.AMQUndeliveredException</Item>
+ <Item>public AMQUndeliveredException()</Item>
+ </Issue>
+ <Issue>
+ <Item>Qpid.AMQUndeliveredException</Item>
+ <Item>public AMQUndeliveredException(String)</Item>
+ </Issue>
+ <Issue>
+ <Item>Qpid.AMQUndeliveredException</Item>
+ <Item>public AMQUndeliveredException(String, Exception)</Item>
+ </Issue>
+ </Message>
+ <Message TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Type">
+ <Item>AMQUndeliveredException</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ <Members>
+ <Member Name="GetUndeliveredMessage():System.Object">
+ <Messages>
+ <Message TypeName="UsePropertiesWhereAppropriate" Category="Microsoft.Design" CheckId="CA1024" Created="2006-12-04 13:11:47Z">
+ <Issue Certainty="50">
+ <Item>GetUndeliveredMessage</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ </Types>
+ </Namespace>
+ <Namespace Name="Qpid.Collections">
+ <Types>
+ <Type Name="BlockingQueue">
+ <Members>
+ <Member Name="EnqueueBlocking(System.Object):System.Void">
+ <Messages>
+ <Message Id="0#e" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="ParameterOneLetter">
+ <Item>BlockingQueue.EnqueueBlocking(Object):Void</Item>
+ <Item>e</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="EnqueueNoThrow(System.Object):System.Boolean">
+ <Messages>
+ <Message Id="0#e" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="ParameterOneLetter">
+ <Item>BlockingQueue.EnqueueNoThrow(Object):Boolean</Item>
+ <Item>e</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="LinkedBlockingQueue">
+ <Messages>
+ <Message TypeName="ICollectionImplementationsHaveStronglyTypedMembers" Category="Microsoft.Design" CheckId="CA1035" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>LinkedBlockingQueue</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ <Members>
+ <Member Name=".ctor(System.Int32)">
+ <Messages>
+ <Message Id="System.ArgumentException.#ctor(System.String)" TypeName="DoNotPassLiteralsAsLocalizedParameters" Category="Microsoft.Globalization" CheckId="CA1303" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>LinkedBlockingQueue.LinkedBlockingQueue(Int32)</Item>
+ <Item>1</Item>
+ <Item>ArgumentException.ArgumentException(String)</Item>
+ <Item>Capacity must be positive, was passed __</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="EnqueueBlocking(System.Object):System.Void">
+ <Messages>
+ <Message TypeName="InstantiateArgumentExceptionsCorrectly" Category="Microsoft.Usage" CheckId="CA2208" Created="2006-12-04 13:11:47Z">
+ <Issue Name="OneArgumentShouldBeParameterName">
+ <Item>System.ArgumentNullException</Item>
+ <Item>ArgumentNullException.ArgumentNullException(String)</Item>
+ <Item>Object must not be null</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="EnqueueNoThrow(System.Object):System.Boolean">
+ <Messages>
+ <Message TypeName="InstantiateArgumentExceptionsCorrectly" Category="Microsoft.Usage" CheckId="CA2208" Created="2006-12-04 13:11:47Z">
+ <Issue Name="OneArgumentShouldBeParameterName">
+ <Item>System.ArgumentNullException</Item>
+ <Item>ArgumentNullException.ArgumentNullException(String)</Item>
+ <Item>e must not be null</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="LinkedHashtable">
+ <Messages>
+ <Message TypeName="ICollectionImplementationsHaveStronglyTypedMembers" Category="Microsoft.Design" CheckId="CA1035" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>LinkedHashtable</Item>
+ </Issue>
+ </Message>
+ <Message TypeName="IdentifiersShouldHaveCorrectSuffix" Category="Microsoft.Naming" CheckId="CA1710" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Qpid.Collections.LinkedHashtable</Item>
+ <Item>Dictionary</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ <Members>
+ <Member Name="Add(System.Object,System.Object):System.Void">
+ <Messages>
+ <Message Id="System.ArgumentException.#ctor(System.String)" TypeName="DoNotPassLiteralsAsLocalizedParameters" Category="Microsoft.Globalization" CheckId="CA1303" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>LinkedHashtable.Add(Object, Object):Void</Item>
+ <Item>1</Item>
+ <Item>ArgumentException.ArgumentException(String)</Item>
+ <Item>LinkedHashtable already contains key. key=__</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="MoveToHead(System.Object):System.Void">
+ <Messages>
+ <Message Id="System.ArgumentException.#ctor(System.String)" TypeName="DoNotPassLiteralsAsLocalizedParameters" Category="Microsoft.Globalization" CheckId="CA1303" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>LinkedHashtable.MoveToHead(Object):Void</Item>
+ <Item>1</Item>
+ <Item>ArgumentException.ArgumentException(String)</Item>
+ <Item>Key ____ not found</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Tail">
+ <Accessors>
+ <Accessor Name="get_Tail():Qpid.Collections.LinkedHashtable+LinkedDictionaryEntry">
+ <Messages>
+ <Message TypeName="AvoidUncalledPrivateCode" Category="Microsoft.Performance" CheckId="CA1811" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>LinkedHashtable.get_Tail():LinkedDictionaryEntry</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Accessor>
+ </Accessors>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="LinkedHashtable+LHTEnumerator">
+ <Members>
+ <Member Name=".ctor(Qpid.Collections.LinkedHashtable)">
+ <Messages>
+ <Message TypeName="DoNotInitializeUnnecessarily" Category="Microsoft.Performance" CheckId="CA1805" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>LHTEnumerator.LHTEnumerator(LinkedHashtable)</Item>
+ <Item>_needsReset</Item>
+ <Item>System.Boolean</Item>
+ <Item>false</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Current">
+ <Accessors>
+ <Accessor Name="get_Current():System.Object">
+ <Messages>
+ <Message TypeName="DoNotRaiseReservedExceptionTypes" Category="Microsoft.Usage" CheckId="CA2201" Created="2006-12-04 13:11:47Z">
+ <Issue Name="TooGeneric">
+ <Item>LHTEnumerator.get_Current():Object</Item>
+ <Item>System.Exception</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Accessor>
+ </Accessors>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="SynchronousQueue">
+ <Messages>
+ <Message TypeName="ICollectionImplementationsHaveStronglyTypedMembers" Category="Microsoft.Design" CheckId="CA1035" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>SynchronousQueue</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ <Members>
+ <Member Name=".ctor(System.Boolean)">
+ <Messages>
+ <Message Id="strict" TypeName="ReviewUnusedParameters" Category="Microsoft.Usage" CheckId="CA1801" Created="2006-12-04 13:11:47Z" FixCategory="Breaking">
+ <Issue>
+ <Item>strict</Item>
+ <Item>SynchronousQueue.SynchronousQueue(Boolean)</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="_qlock">
+ <Messages>
+ <Message TypeName="AvoidUnusedPrivateFields" Category="Microsoft.Performance" CheckId="CA1823" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>SynchronousQueue._qlock</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="_waitingConsumers">
+ <Messages>
+ <Message TypeName="AvoidUnusedPrivateFields" Category="Microsoft.Performance" CheckId="CA1823" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>SynchronousQueue._waitingConsumers</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="_waitingProducers">
+ <Messages>
+ <Message TypeName="AvoidUnusedPrivateFields" Category="Microsoft.Performance" CheckId="CA1823" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>SynchronousQueue._waitingProducers</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="SynchronousQueue+FifoWaitQueue">
+ <Messages>
+ <Message TypeName="AvoidUninstantiatedInternalClasses" Category="Microsoft.Performance" CheckId="CA1812" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Qpid.Collections.SynchronousQueue+FifoWaitQueue</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Type>
+ <Type Name="SynchronousQueue+LifoWaitQueue">
+ <Messages>
+ <Message TypeName="AvoidUninstantiatedInternalClasses" Category="Microsoft.Performance" CheckId="CA1812" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Qpid.Collections.SynchronousQueue+LifoWaitQueue</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Type>
+ <Type Name="SynchronousQueue+Node">
+ <Members>
+ <Member Name=".ctor(System.Object)">
+ <Messages>
+ <Message TypeName="DoNotInitializeUnnecessarily" Category="Microsoft.Performance" CheckId="CA1805" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Node.Node(Object)</Item>
+ <Item>state</Item>
+ <Item>System.Int32</Item>
+ <Item>0</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name=".ctor(System.Object,Qpid.Collections.SynchronousQueue+Node)">
+ <Messages>
+ <Message TypeName="DoNotInitializeUnnecessarily" Category="Microsoft.Performance" CheckId="CA1805" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Node.Node(Object, Node)</Item>
+ <Item>state</Item>
+ <Item>System.Int32</Item>
+ <Item>0</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Attempt(System.Int64):System.Boolean">
+ <Messages>
+ <Message TypeName="AvoidUncalledPrivateCode" Category="Microsoft.Performance" CheckId="CA1811" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Node.Attempt(Int64):Boolean</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Extract():System.Object">
+ <Messages>
+ <Message TypeName="AvoidUncalledPrivateCode" Category="Microsoft.Performance" CheckId="CA1811" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Node.Extract():Object</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="GetItem():System.Object">
+ <Messages>
+ <Message TypeName="AvoidUncalledPrivateCode" Category="Microsoft.Performance" CheckId="CA1811" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Node.GetItem():Object</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="SetItem(System.Object):System.Boolean">
+ <Messages>
+ <Message TypeName="AvoidUncalledPrivateCode" Category="Microsoft.Performance" CheckId="CA1811" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Node.SetItem(Object):Boolean</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="WaitForPut():System.Object">
+ <Messages>
+ <Message TypeName="AvoidUncalledPrivateCode" Category="Microsoft.Performance" CheckId="CA1811" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Node.WaitForPut():Object</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="WaitForPut(System.Int64):System.Object">
+ <Messages>
+ <Message TypeName="AvoidUncalledPrivateCode" Category="Microsoft.Performance" CheckId="CA1811" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Node.WaitForPut(Int64):Object</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="WaitForTake():System.Void">
+ <Messages>
+ <Message TypeName="AvoidUncalledPrivateCode" Category="Microsoft.Performance" CheckId="CA1811" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Node.WaitForTake():Void</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="WaitForTake(System.Int64):System.Boolean">
+ <Messages>
+ <Message TypeName="AvoidUncalledPrivateCode" Category="Microsoft.Performance" CheckId="CA1811" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Node.WaitForTake(Int64):Boolean</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ </Types>
+ </Namespace>
+ <Namespace Name="Qpid.Common">
+ <Types>
+ <Type Name="AssemblySettings">
+ <Members>
+ <Member Name="GetConfig(System.Reflection.Assembly):System.Collections.IDictionary">
+ <Messages>
+ <Message TypeName="DoNotCatchGeneralExceptionTypes" Category="Microsoft.Design" CheckId="CA1031" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>AssemblySettings.GetConfig(Assembly):IDictionary</Item>
+ <Item>System.Exception</Item>
+ </Issue>
+ </Message>
+ <Message TypeName="ValidateArgumentsOfPublicMethods" Category="Microsoft.Design" CheckId="CA1062" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>'asm'</Item>
+ <Item>AssemblySettings.GetConfig(Assembly):IDictionary</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ </Types>
+ </Namespace>
+ <Namespace Name="Qpid.Framing">
+ <Types>
+ <Type Name="AccessRequestBody">
+ <Members>
+ <Member Name="Active">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Active</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="CLASS_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>AccessRequestBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>AccessRequestBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="CreateAMQFrame(System.UInt16,System.String,System.Boolean,System.Boolean,System.Boolean,System.Boolean,System.Boolean):Qpid.Framing.AMQFrame">
+ <Messages>
+ <Message Id="1#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>Realm</Item>
+ </Issue>
+ </Message>
+ <Message Id="2#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>Exclusive</Item>
+ </Issue>
+ </Message>
+ <Message Id="3#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>Passive</Item>
+ </Issue>
+ </Message>
+ <Message Id="4#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>Active</Item>
+ </Issue>
+ </Message>
+ <Message Id="5#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>Write</Item>
+ </Issue>
+ </Message>
+ <Message Id="6#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>Read</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>AccessRequestBody.CreateAMQFrame(UInt16, String, Boolean, Boolean, Boolean, Boolean, Boolean):AMQFrame</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Exclusive">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Exclusive</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="METHOD_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>AccessRequestBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>AccessRequestBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Passive">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Passive</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Read">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Read</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Realm">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Realm</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Write">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Write</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="AccessRequestOkBody">
+ <Members>
+ <Member Name="CLASS_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>AccessRequestOkBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>AccessRequestOkBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="CreateAMQFrame(System.UInt16,System.UInt16):Qpid.Framing.AMQFrame">
+ <Messages>
+ <Message Id="1#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>Ticket</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>AccessRequestOkBody.CreateAMQFrame(UInt16, UInt16):AMQFrame</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="METHOD_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>AccessRequestOkBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>AccessRequestOkBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Ticket">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Ticket</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="AMQDataBlockDecoder">
+ <Messages>
+ <Message TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Type">
+ <Item>AMQDataBlockDecoder</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ <Members>
+ <Member Name=".ctor()">
+ <Messages>
+ <Message TypeName="DoNotInitializeUnnecessarily" Category="Microsoft.Performance" CheckId="CA1805" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>AMQDataBlockDecoder.AMQDataBlockDecoder()</Item>
+ <Item>_disabled</Item>
+ <Item>System.Boolean</Item>
+ <Item>false</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="CreateAndPopulateFrame(Qpid.Buffer.ByteBuffer):System.Object">
+ <Messages>
+ <Message Id="Qpid.Framing.AMQFrameDecodingException.#ctor(System.String)" TypeName="DoNotPassLiteralsAsLocalizedParameters" Category="Microsoft.Globalization" CheckId="CA1303" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>AMQDataBlockDecoder.CreateAndPopulateFrame(ByteBuffer):Object</Item>
+ <Item>1</Item>
+ <Item>AMQFrameDecodingException.AMQFrameDecodingException(String)</Item>
+ <Item>Unsupported body type: __</Item>
+ </Issue>
+ </Message>
+ <Message Id="marker" TypeName="RemoveUnusedLocals" Category="Microsoft.Performance" CheckId="CA1804" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>AMQDataBlockDecoder.CreateAndPopulateFrame(ByteBuffer):Object</Item>
+ <Item>marker</Item>
+ <Item>System.Byte</Item>
+ </Issue>
+ </Message>
+ <Message TypeName="ValidateArgumentsOfPublicMethods" Category="Microsoft.Design" CheckId="CA1062" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>'input'</Item>
+ <Item>AMQDataBlockDecoder.CreateAndPopulateFrame(ByteBuffer):Object</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Decodable(Qpid.Buffer.ByteBuffer):Qpid.Codec.Demux.MessageDecoderResult">
+ <Messages>
+ <Message Id="0#" TypeName="ParameterNamesShouldMatchBaseDeclaration" Category="Microsoft.Naming" CheckId="CA1725" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>input</Item>
+ <Item>AMQDataBlockDecoder.Decodable(ByteBuffer):MessageDecoderResult</Item>
+ <Item>buffer</Item>
+ <Item>IMessageDecoder.Decodable(ByteBuffer):MessageDecoderResult</Item>
+ </Issue>
+ </Message>
+ <Message Id="System.String.Format(System.String,System.Object,System.Object,System.Object)" TypeName="SpecifyIFormatProvider" Category="Microsoft.Globalization" CheckId="CA1305" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>AMQDataBlockDecoder.Decodable(ByteBuffer):MessageDecoderResult</Item>
+ <Item>System.String.Format(System.String,System.Object,System.Object,System.Object)</Item>
+ <Item>System.String.Format(System.IFormatProvider,System.String,System.Object[])</Item>
+ </Issue>
+ </Message>
+ <Message TypeName="ValidateArgumentsOfPublicMethods" Category="Microsoft.Design" CheckId="CA1062" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>'input'</Item>
+ <Item>AMQDataBlockDecoder.Decodable(ByteBuffer):MessageDecoderResult</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Decode(Qpid.Buffer.ByteBuffer,Qpid.Codec.IProtocolDecoderOutput):Qpid.Codec.Demux.MessageDecoderResult">
+ <Messages>
+ <Message Id="0#" TypeName="ParameterNamesShouldMatchBaseDeclaration" Category="Microsoft.Naming" CheckId="CA1725" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>input</Item>
+ <Item>AMQDataBlockDecoder.Decode(ByteBuffer, IProtocolDecoderOutput):MessageDecoderResult</Item>
+ <Item>buffer</Item>
+ <Item>IMessageDecoder.Decode(ByteBuffer, IProtocolDecoderOutput):MessageDecoderResult</Item>
+ </Issue>
+ </Message>
+ <Message TypeName="ValidateArgumentsOfPublicMethods" Category="Microsoft.Design" CheckId="CA1062" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>'output'</Item>
+ <Item>AMQDataBlockDecoder.Decode(ByteBuffer, IProtocolDecoderOutput):MessageDecoderResult</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Disabled">
+ <Messages>
+ <Message TypeName="PropertiesShouldNotBeWriteOnly" Category="Microsoft.Design" CheckId="CA1044" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Disabled</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="AMQDataBlockEncoder">
+ <Messages>
+ <Message TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Type">
+ <Item>AMQDataBlockEncoder</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ <Members>
+ <Member Name="Encode(System.Object,Qpid.Codec.IProtocolEncoderOutput):System.Void">
+ <Messages>
+ <Message TypeName="ValidateArgumentsOfPublicMethods" Category="Microsoft.Design" CheckId="CA1062" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>'output'</Item>
+ <Item>AMQDataBlockEncoder.Encode(Object, IProtocolEncoderOutput):Void</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="AMQFrame">
+ <Messages>
+ <Message TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Type">
+ <Item>AMQFrame</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ <Members>
+ <Member Name="PopulateFromBuffer(Qpid.Buffer.ByteBuffer,System.UInt16,System.UInt32,Qpid.Framing.IBodyFactory):System.Void">
+ <Messages>
+ <Message TypeName="ValidateArgumentsOfPublicMethods" Category="Microsoft.Design" CheckId="CA1062" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>'bodyFactory'</Item>
+ <Item>AMQFrame.PopulateFromBuffer(ByteBuffer, UInt16, UInt32, IBodyFactory):Void</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="WritePayload(Qpid.Buffer.ByteBuffer):System.Void">
+ <Messages>
+ <Message TypeName="ValidateArgumentsOfPublicMethods" Category="Microsoft.Design" CheckId="CA1062" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>'buffer'</Item>
+ <Item>AMQFrame.WritePayload(ByteBuffer):Void</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="AMQFrameDecodingException">
+ <Messages>
+ <Message TypeName="ImplementStandardExceptionConstructors" Category="Microsoft.Design" CheckId="CA1032" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Qpid.Framing.AMQFrameDecodingException</Item>
+ <Item>protected AMQFrameDecodingException(SerializationInfo, StreamingContext)</Item>
+ </Issue>
+ <Issue>
+ <Item>Qpid.Framing.AMQFrameDecodingException</Item>
+ <Item>public AMQFrameDecodingException()</Item>
+ </Issue>
+ </Message>
+ <Message TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Type">
+ <Item>AMQFrameDecodingException</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Type>
+ <Type Name="AMQMethodBody">
+ <Messages>
+ <Message TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Type">
+ <Item>AMQMethodBody</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ <Members>
+ <Member Name="Clazz">
+ <Messages>
+ <Message Id="Clazz" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>Clazz</Item>
+ <Item>AMQMethodBody.Clazz:UInt16</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="ToString():System.String">
+ <Messages>
+ <Message Id="System.String.Format(System.String,System.Object,System.Object,System.Object)" TypeName="SpecifyIFormatProvider" Category="Microsoft.Globalization" CheckId="CA1305" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>AMQMethodBody.ToString():String</Item>
+ <Item>System.String.Format(System.String,System.Object,System.Object,System.Object)</Item>
+ <Item>System.String.Format(System.IFormatProvider,System.String,System.Object[])</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="TYPE">
+ <Messages>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>AMQMethodBody.TYPE</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="WritePayload(Qpid.Buffer.ByteBuffer):System.Void">
+ <Messages>
+ <Message TypeName="ValidateArgumentsOfPublicMethods" Category="Microsoft.Design" CheckId="CA1062" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>'buffer'</Item>
+ <Item>AMQMethodBody.WritePayload(ByteBuffer):Void</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="AMQMethodBodyFactory">
+ <Messages>
+ <Message TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Type">
+ <Item>AMQMethodBodyFactory</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ <Members>
+ <Member Name="CreateBody(Qpid.Buffer.ByteBuffer):Qpid.Framing.IBody">
+ <Messages>
+ <Message TypeName="ValidateArgumentsOfPublicMethods" Category="Microsoft.Design" CheckId="CA1062" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>'inbuf'</Item>
+ <Item>AMQMethodBodyFactory.CreateBody(ByteBuffer):IBody</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="GetInstance():Qpid.Framing.AMQMethodBodyFactory">
+ <Messages>
+ <Message TypeName="UsePropertiesWhereAppropriate" Category="Microsoft.Design" CheckId="CA1024" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>GetInstance</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="AMQProtocolHeaderException">
+ <Messages>
+ <Message TypeName="ImplementStandardExceptionConstructors" Category="Microsoft.Design" CheckId="CA1032" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Qpid.Framing.AMQProtocolHeaderException</Item>
+ <Item>protected AMQProtocolHeaderException(SerializationInfo, StreamingContext)</Item>
+ </Issue>
+ <Issue>
+ <Item>Qpid.Framing.AMQProtocolHeaderException</Item>
+ <Item>public AMQProtocolHeaderException()</Item>
+ </Issue>
+ <Issue>
+ <Item>Qpid.Framing.AMQProtocolHeaderException</Item>
+ <Item>public AMQProtocolHeaderException(String, Exception)</Item>
+ </Issue>
+ </Message>
+ <Message TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Type">
+ <Item>AMQProtocolHeaderException</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Type>
+ <Type Name="BasicAckBody">
+ <Messages>
+ <Message Id="Ack" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Type">
+ <Item>Ack</Item>
+ <Item>Qpid.Framing.BasicAckBody</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ <Members>
+ <Member Name="CLASS_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>BasicAckBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>BasicAckBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="CreateAMQFrame(System.UInt16,System.UInt64,System.Boolean):Qpid.Framing.AMQFrame">
+ <Messages>
+ <Message Id="1#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>DeliveryTag</Item>
+ </Issue>
+ </Message>
+ <Message Id="2#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>Multiple</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>BasicAckBody.CreateAMQFrame(UInt16, UInt64, Boolean):AMQFrame</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="DeliveryTag">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>DeliveryTag</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="METHOD_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>BasicAckBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>BasicAckBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Multiple">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Multiple</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="BasicCancelBody">
+ <Members>
+ <Member Name="CLASS_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>BasicCancelBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>BasicCancelBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="ConsumerTag">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>ConsumerTag</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="CreateAMQFrame(System.UInt16,System.String,System.Boolean):Qpid.Framing.AMQFrame">
+ <Messages>
+ <Message Id="1#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>ConsumerTag</Item>
+ </Issue>
+ </Message>
+ <Message Id="2#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>Nowait</Item>
+ </Issue>
+ </Message>
+ <Message Id="2#Nowait" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>BasicCancelBody.CreateAMQFrame(UInt16, String, Boolean):AMQFrame</Item>
+ <Item>Nowait</Item>
+ <Item>Nowait</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>BasicCancelBody.CreateAMQFrame(UInt16, String, Boolean):AMQFrame</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="METHOD_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>BasicCancelBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>BasicCancelBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Nowait">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Nowait</Item>
+ </Issue>
+ </Message>
+ <Message Id="Nowait" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>Nowait</Item>
+ <Item>BasicCancelBody.Nowait</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="BasicCancelOkBody">
+ <Members>
+ <Member Name="CLASS_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>BasicCancelOkBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>BasicCancelOkBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="ConsumerTag">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>ConsumerTag</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="CreateAMQFrame(System.UInt16,System.String):Qpid.Framing.AMQFrame">
+ <Messages>
+ <Message Id="1#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>ConsumerTag</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>BasicCancelOkBody.CreateAMQFrame(UInt16, String):AMQFrame</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="METHOD_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>BasicCancelOkBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>BasicCancelOkBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="BasicConsumeBody">
+ <Members>
+ <Member Name="CLASS_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>BasicConsumeBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>BasicConsumeBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="ConsumerTag">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>ConsumerTag</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="CreateAMQFrame(System.UInt16,System.UInt16,System.String,System.String,System.Boolean,System.Boolean,System.Boolean,System.Boolean):Qpid.Framing.AMQFrame">
+ <Messages>
+ <Message Id="1#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>Ticket</Item>
+ </Issue>
+ </Message>
+ <Message Id="2#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>Queue</Item>
+ </Issue>
+ </Message>
+ <Message Id="3#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>ConsumerTag</Item>
+ </Issue>
+ </Message>
+ <Message Id="4#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>NoLocal</Item>
+ </Issue>
+ </Message>
+ <Message Id="5#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>NoAck</Item>
+ </Issue>
+ </Message>
+ <Message Id="6#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>Exclusive</Item>
+ </Issue>
+ </Message>
+ <Message Id="7#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>Nowait</Item>
+ </Issue>
+ </Message>
+ <Message Id="5#Ack" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>BasicConsumeBody.CreateAMQFrame(UInt16, UInt16, String, String, Boolean, Boolean, Boolean, Boolean):AMQFrame</Item>
+ <Item>Ack</Item>
+ <Item>NoAck</Item>
+ </Issue>
+ </Message>
+ <Message Id="7#Nowait" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>BasicConsumeBody.CreateAMQFrame(UInt16, UInt16, String, String, Boolean, Boolean, Boolean, Boolean):AMQFrame</Item>
+ <Item>Nowait</Item>
+ <Item>Nowait</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>BasicConsumeBody.CreateAMQFrame(UInt16, UInt16, String, String, Boolean, Boolean, Boolean, Boolean):AMQFrame</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Exclusive">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Exclusive</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="METHOD_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>BasicConsumeBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>BasicConsumeBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="NoAck">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>NoAck</Item>
+ </Issue>
+ </Message>
+ <Message Id="Ack" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>Ack</Item>
+ <Item>BasicConsumeBody.NoAck</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="NoLocal">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>NoLocal</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Nowait">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Nowait</Item>
+ </Issue>
+ </Message>
+ <Message Id="Nowait" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>Nowait</Item>
+ <Item>BasicConsumeBody.Nowait</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Queue">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Queue</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Ticket">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Ticket</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="BasicConsumeOkBody">
+ <Members>
+ <Member Name="CLASS_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>BasicConsumeOkBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>BasicConsumeOkBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="ConsumerTag">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>ConsumerTag</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="CreateAMQFrame(System.UInt16,System.String):Qpid.Framing.AMQFrame">
+ <Messages>
+ <Message Id="1#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>ConsumerTag</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>BasicConsumeOkBody.CreateAMQFrame(UInt16, String):AMQFrame</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="METHOD_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>BasicConsumeOkBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>BasicConsumeOkBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="BasicContentHeaderProperties">
+ <Members>
+ <Member Name="AppId">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>AppId</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="ClusterId">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>ClusterId</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="ContentType">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>ContentType</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="CorrelationId">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>CorrelationId</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="DeliveryMode">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>DeliveryMode</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Encoding">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Encoding</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Expiration">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Expiration</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Headers">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Headers</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="MessageId">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>MessageId</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="PopulatePropertiesFromBuffer(Qpid.Buffer.ByteBuffer,System.UInt16):System.Void">
+ <Messages>
+ <Message Id="System.UInt32.Parse(System.String)" TypeName="SpecifyIFormatProvider" Category="Microsoft.Globalization" CheckId="CA1305" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>BasicContentHeaderProperties.PopulatePropertiesFromBuffer(ByteBuffer, UInt16):Void</Item>
+ <Item>System.UInt32.Parse(System.String)</Item>
+ <Item>System.UInt32.Parse(System.String,System.IFormatProvider)</Item>
+ </Issue>
+ </Message>
+ <Message TypeName="ValidateArgumentsOfPublicMethods" Category="Microsoft.Design" CheckId="CA1062" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>'buffer'</Item>
+ <Item>BasicContentHeaderProperties.PopulatePropertiesFromBuffer(ByteBuffer, UInt16):Void</Item>
+ </Issue>
+ <Issue>
+ <Item>'buffer'</Item>
+ <Item>BasicContentHeaderProperties.PopulatePropertiesFromBuffer(ByteBuffer, UInt16):Void</Item>
+ </Issue>
+ <Issue>
+ <Item>'buffer'</Item>
+ <Item>BasicContentHeaderProperties.PopulatePropertiesFromBuffer(ByteBuffer, UInt16):Void</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Priority">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Priority</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="PropertyListSize">
+ <Accessors>
+ <Accessor Name="get_PropertyListSize():System.UInt32">
+ <Messages>
+ <Message Id="System.String.Format(System.String,System.Object)" TypeName="SpecifyIFormatProvider" Category="Microsoft.Globalization" CheckId="CA1305" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>BasicContentHeaderProperties.get_PropertyListSize():UInt32</Item>
+ <Item>System.String.Format(System.String,System.Object)</Item>
+ <Item>System.String.Format(System.IFormatProvider,System.String,System.Object[])</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Accessor>
+ </Accessors>
+ </Member>
+ <Member Name="ReplyTo">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>ReplyTo</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Timestamp">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Timestamp</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Type">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Type</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="UserId">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>UserId</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="WritePropertyListPayload(Qpid.Buffer.ByteBuffer):System.Void">
+ <Messages>
+ <Message Id="System.String.Format(System.String,System.Object)" TypeName="SpecifyIFormatProvider" Category="Microsoft.Globalization" CheckId="CA1305" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>BasicContentHeaderProperties.WritePropertyListPayload(ByteBuffer):Void</Item>
+ <Item>System.String.Format(System.String,System.Object)</Item>
+ <Item>System.String.Format(System.IFormatProvider,System.String,System.Object[])</Item>
+ </Issue>
+ </Message>
+ <Message TypeName="ValidateArgumentsOfPublicMethods" Category="Microsoft.Design" CheckId="CA1062" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>'buffer'</Item>
+ <Item>BasicContentHeaderProperties.WritePropertyListPayload(ByteBuffer):Void</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="BasicDeliverBody">
+ <Members>
+ <Member Name="CLASS_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>BasicDeliverBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>BasicDeliverBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="ConsumerTag">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>ConsumerTag</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="CreateAMQFrame(System.UInt16,System.String,System.UInt64,System.Boolean,System.String,System.String):Qpid.Framing.AMQFrame">
+ <Messages>
+ <Message Id="1#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>ConsumerTag</Item>
+ </Issue>
+ </Message>
+ <Message Id="2#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>DeliveryTag</Item>
+ </Issue>
+ </Message>
+ <Message Id="3#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>Redelivered</Item>
+ </Issue>
+ </Message>
+ <Message Id="4#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>Exchange</Item>
+ </Issue>
+ </Message>
+ <Message Id="5#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>RoutingKey</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>BasicDeliverBody.CreateAMQFrame(UInt16, String, UInt64, Boolean, String, String):AMQFrame</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="DeliveryTag">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>DeliveryTag</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Exchange">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Exchange</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="METHOD_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>BasicDeliverBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>BasicDeliverBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Redelivered">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Redelivered</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="RoutingKey">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>RoutingKey</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="BasicGetBody">
+ <Members>
+ <Member Name="CLASS_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>BasicGetBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>BasicGetBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="CreateAMQFrame(System.UInt16,System.UInt16,System.String,System.Boolean):Qpid.Framing.AMQFrame">
+ <Messages>
+ <Message Id="1#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>Ticket</Item>
+ </Issue>
+ </Message>
+ <Message Id="2#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>Queue</Item>
+ </Issue>
+ </Message>
+ <Message Id="3#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>NoAck</Item>
+ </Issue>
+ </Message>
+ <Message Id="3#Ack" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>BasicGetBody.CreateAMQFrame(UInt16, UInt16, String, Boolean):AMQFrame</Item>
+ <Item>Ack</Item>
+ <Item>NoAck</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>BasicGetBody.CreateAMQFrame(UInt16, UInt16, String, Boolean):AMQFrame</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="METHOD_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>BasicGetBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>BasicGetBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="NoAck">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>NoAck</Item>
+ </Issue>
+ </Message>
+ <Message Id="Ack" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>Ack</Item>
+ <Item>BasicGetBody.NoAck</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Queue">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Queue</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Ticket">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Ticket</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="BasicGetEmptyBody">
+ <Members>
+ <Member Name="CLASS_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>BasicGetEmptyBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>BasicGetEmptyBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="ClusterId">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>ClusterId</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="CreateAMQFrame(System.UInt16,System.String):Qpid.Framing.AMQFrame">
+ <Messages>
+ <Message Id="1#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>ClusterId</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>BasicGetEmptyBody.CreateAMQFrame(UInt16, String):AMQFrame</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="METHOD_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>BasicGetEmptyBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>BasicGetEmptyBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="BasicGetOkBody">
+ <Members>
+ <Member Name="CLASS_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>BasicGetOkBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>BasicGetOkBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="CreateAMQFrame(System.UInt16,System.UInt64,System.Boolean,System.String,System.String,System.UInt32):Qpid.Framing.AMQFrame">
+ <Messages>
+ <Message Id="1#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>DeliveryTag</Item>
+ </Issue>
+ </Message>
+ <Message Id="2#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>Redelivered</Item>
+ </Issue>
+ </Message>
+ <Message Id="3#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>Exchange</Item>
+ </Issue>
+ </Message>
+ <Message Id="4#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>RoutingKey</Item>
+ </Issue>
+ </Message>
+ <Message Id="5#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>MessageCount</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>BasicGetOkBody.CreateAMQFrame(UInt16, UInt64, Boolean, String, String, UInt32):AMQFrame</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="DeliveryTag">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>DeliveryTag</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Exchange">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Exchange</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="MessageCount">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>MessageCount</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="METHOD_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>BasicGetOkBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>BasicGetOkBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Redelivered">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Redelivered</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="RoutingKey">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>RoutingKey</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="BasicPublishBody">
+ <Members>
+ <Member Name="CLASS_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>BasicPublishBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>BasicPublishBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="CreateAMQFrame(System.UInt16,System.UInt16,System.String,System.String,System.Boolean,System.Boolean):Qpid.Framing.AMQFrame">
+ <Messages>
+ <Message Id="1#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>Ticket</Item>
+ </Issue>
+ </Message>
+ <Message Id="2#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>Exchange</Item>
+ </Issue>
+ </Message>
+ <Message Id="3#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>RoutingKey</Item>
+ </Issue>
+ </Message>
+ <Message Id="4#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>Mandatory</Item>
+ </Issue>
+ </Message>
+ <Message Id="5#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>Immediate</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>BasicPublishBody.CreateAMQFrame(UInt16, UInt16, String, String, Boolean, Boolean):AMQFrame</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Exchange">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Exchange</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Immediate">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Immediate</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Mandatory">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Mandatory</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="METHOD_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>BasicPublishBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>BasicPublishBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="RoutingKey">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>RoutingKey</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Ticket">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Ticket</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="BasicQosBody">
+ <Messages>
+ <Message Id="Qos" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Type">
+ <Item>Qos</Item>
+ <Item>Qpid.Framing.BasicQosBody</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ <Members>
+ <Member Name="CLASS_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>BasicQosBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>BasicQosBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="CreateAMQFrame(System.UInt16,System.UInt32,System.UInt16,System.Boolean):Qpid.Framing.AMQFrame">
+ <Messages>
+ <Message Id="1#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>PrefetchSize</Item>
+ </Issue>
+ </Message>
+ <Message Id="2#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>PrefetchCount</Item>
+ </Issue>
+ </Message>
+ <Message Id="3#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>Global</Item>
+ </Issue>
+ </Message>
+ <Message Id="1#Prefetch" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>BasicQosBody.CreateAMQFrame(UInt16, UInt32, UInt16, Boolean):AMQFrame</Item>
+ <Item>Prefetch</Item>
+ <Item>PrefetchSize</Item>
+ </Issue>
+ </Message>
+ <Message Id="2#Prefetch" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>BasicQosBody.CreateAMQFrame(UInt16, UInt32, UInt16, Boolean):AMQFrame</Item>
+ <Item>Prefetch</Item>
+ <Item>PrefetchCount</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>BasicQosBody.CreateAMQFrame(UInt16, UInt32, UInt16, Boolean):AMQFrame</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Global">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Global</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="METHOD_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>BasicQosBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>BasicQosBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="PrefetchCount">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>PrefetchCount</Item>
+ </Issue>
+ </Message>
+ <Message Id="Prefetch" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>Prefetch</Item>
+ <Item>BasicQosBody.PrefetchCount</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="PrefetchSize">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>PrefetchSize</Item>
+ </Issue>
+ </Message>
+ <Message Id="Prefetch" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>Prefetch</Item>
+ <Item>BasicQosBody.PrefetchSize</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="BasicQosOkBody">
+ <Messages>
+ <Message Id="Qos" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Type">
+ <Item>Qos</Item>
+ <Item>Qpid.Framing.BasicQosOkBody</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ <Members>
+ <Member Name="CLASS_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>BasicQosOkBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>BasicQosOkBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="CreateAMQFrame(System.UInt16):Qpid.Framing.AMQFrame">
+ <Messages>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>BasicQosOkBody.CreateAMQFrame(UInt16):AMQFrame</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="METHOD_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>BasicQosOkBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>BasicQosOkBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="BasicRecoverBody">
+ <Members>
+ <Member Name="CLASS_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>BasicRecoverBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>BasicRecoverBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="CreateAMQFrame(System.UInt16,System.Boolean):Qpid.Framing.AMQFrame">
+ <Messages>
+ <Message Id="1#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>Requeue</Item>
+ </Issue>
+ </Message>
+ <Message Id="1#Requeue" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>BasicRecoverBody.CreateAMQFrame(UInt16, Boolean):AMQFrame</Item>
+ <Item>Requeue</Item>
+ <Item>Requeue</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>BasicRecoverBody.CreateAMQFrame(UInt16, Boolean):AMQFrame</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="METHOD_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>BasicRecoverBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>BasicRecoverBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Requeue">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Requeue</Item>
+ </Issue>
+ </Message>
+ <Message Id="Requeue" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>Requeue</Item>
+ <Item>BasicRecoverBody.Requeue</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="BasicRejectBody">
+ <Members>
+ <Member Name="CLASS_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>BasicRejectBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>BasicRejectBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="CreateAMQFrame(System.UInt16,System.UInt64,System.Boolean):Qpid.Framing.AMQFrame">
+ <Messages>
+ <Message Id="1#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>DeliveryTag</Item>
+ </Issue>
+ </Message>
+ <Message Id="2#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>Requeue</Item>
+ </Issue>
+ </Message>
+ <Message Id="2#Requeue" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>BasicRejectBody.CreateAMQFrame(UInt16, UInt64, Boolean):AMQFrame</Item>
+ <Item>Requeue</Item>
+ <Item>Requeue</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>BasicRejectBody.CreateAMQFrame(UInt16, UInt64, Boolean):AMQFrame</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="DeliveryTag">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>DeliveryTag</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="METHOD_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>BasicRejectBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>BasicRejectBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Requeue">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Requeue</Item>
+ </Issue>
+ </Message>
+ <Message Id="Requeue" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>Requeue</Item>
+ <Item>BasicRejectBody.Requeue</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="BasicReturnBody">
+ <Members>
+ <Member Name="CLASS_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>BasicReturnBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>BasicReturnBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="CreateAMQFrame(System.UInt16,System.UInt16,System.String,System.String,System.String):Qpid.Framing.AMQFrame">
+ <Messages>
+ <Message Id="1#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>ReplyCode</Item>
+ </Issue>
+ </Message>
+ <Message Id="2#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>ReplyText</Item>
+ </Issue>
+ </Message>
+ <Message Id="3#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>Exchange</Item>
+ </Issue>
+ </Message>
+ <Message Id="4#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>RoutingKey</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>BasicReturnBody.CreateAMQFrame(UInt16, UInt16, String, String, String):AMQFrame</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Exchange">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Exchange</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="METHOD_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>BasicReturnBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>BasicReturnBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="ReplyCode">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>ReplyCode</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="ReplyText">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>ReplyText</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="RoutingKey">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>RoutingKey</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="ChannelAlertBody">
+ <Members>
+ <Member Name="CLASS_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>ChannelAlertBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>ChannelAlertBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="CreateAMQFrame(System.UInt16,System.UInt16,System.String,Qpid.Framing.FieldTable):Qpid.Framing.AMQFrame">
+ <Messages>
+ <Message Id="1#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>ReplyCode</Item>
+ </Issue>
+ </Message>
+ <Message Id="2#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>ReplyText</Item>
+ </Issue>
+ </Message>
+ <Message Id="3#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>Details</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>ChannelAlertBody.CreateAMQFrame(UInt16, UInt16, String, FieldTable):AMQFrame</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Details">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Details</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="METHOD_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>ChannelAlertBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>ChannelAlertBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="ReplyCode">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>ReplyCode</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="ReplyText">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>ReplyText</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="ChannelCloseBody">
+ <Members>
+ <Member Name="CLASS_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>ChannelCloseBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>ChannelCloseBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="ClassId">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>ClassId</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="CreateAMQFrame(System.UInt16,System.UInt16,System.String,System.UInt16,System.UInt16):Qpid.Framing.AMQFrame">
+ <Messages>
+ <Message Id="1#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>ReplyCode</Item>
+ </Issue>
+ </Message>
+ <Message Id="2#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>ReplyText</Item>
+ </Issue>
+ </Message>
+ <Message Id="3#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>ClassId</Item>
+ </Issue>
+ </Message>
+ <Message Id="4#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>MethodId</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>ChannelCloseBody.CreateAMQFrame(UInt16, UInt16, String, UInt16, UInt16):AMQFrame</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="METHOD_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>ChannelCloseBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>ChannelCloseBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="MethodId">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>MethodId</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="ReplyCode">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>ReplyCode</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="ReplyText">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>ReplyText</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="ChannelCloseOkBody">
+ <Members>
+ <Member Name="CLASS_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>ChannelCloseOkBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>ChannelCloseOkBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="CreateAMQFrame(System.UInt16):Qpid.Framing.AMQFrame">
+ <Messages>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>ChannelCloseOkBody.CreateAMQFrame(UInt16):AMQFrame</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="METHOD_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>ChannelCloseOkBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>ChannelCloseOkBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="ChannelFlowBody">
+ <Members>
+ <Member Name="Active">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Active</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="CLASS_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>ChannelFlowBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>ChannelFlowBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="CreateAMQFrame(System.UInt16,System.Boolean):Qpid.Framing.AMQFrame">
+ <Messages>
+ <Message Id="1#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>Active</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>ChannelFlowBody.CreateAMQFrame(UInt16, Boolean):AMQFrame</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="METHOD_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>ChannelFlowBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>ChannelFlowBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="ChannelFlowOkBody">
+ <Members>
+ <Member Name="Active">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Active</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="CLASS_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>ChannelFlowOkBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>ChannelFlowOkBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="CreateAMQFrame(System.UInt16,System.Boolean):Qpid.Framing.AMQFrame">
+ <Messages>
+ <Message Id="1#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>Active</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>ChannelFlowOkBody.CreateAMQFrame(UInt16, Boolean):AMQFrame</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="METHOD_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>ChannelFlowOkBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>ChannelFlowOkBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="ChannelOpenBody">
+ <Members>
+ <Member Name="CLASS_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>ChannelOpenBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>ChannelOpenBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="CreateAMQFrame(System.UInt16,System.String):Qpid.Framing.AMQFrame">
+ <Messages>
+ <Message Id="1#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>OutOfBand</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>ChannelOpenBody.CreateAMQFrame(UInt16, String):AMQFrame</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="METHOD_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>ChannelOpenBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>ChannelOpenBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="OutOfBand">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>OutOfBand</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="ChannelOpenOkBody">
+ <Members>
+ <Member Name="CLASS_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>ChannelOpenOkBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>ChannelOpenOkBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="CreateAMQFrame(System.UInt16):Qpid.Framing.AMQFrame">
+ <Messages>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>ChannelOpenOkBody.CreateAMQFrame(UInt16):AMQFrame</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="METHOD_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>ChannelOpenOkBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>ChannelOpenOkBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="CompositeAMQDataBlock">
+ <Messages>
+ <Message TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Type">
+ <Item>CompositeAMQDataBlock</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ <Members>
+ <Member Name="Blocks">
+ <Messages>
+ <Message TypeName="PropertiesShouldNotReturnArrays" Category="Microsoft.Performance" CheckId="CA1819" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>CompositeAMQDataBlock.Blocks:IDataBlock[]</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="ConnectionCloseBody">
+ <Members>
+ <Member Name="CLASS_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>ConnectionCloseBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>ConnectionCloseBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="ClassId">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>ClassId</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="CreateAMQFrame(System.UInt16,System.UInt16,System.String,System.UInt16,System.UInt16):Qpid.Framing.AMQFrame">
+ <Messages>
+ <Message Id="1#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>ReplyCode</Item>
+ </Issue>
+ </Message>
+ <Message Id="2#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>ReplyText</Item>
+ </Issue>
+ </Message>
+ <Message Id="3#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>ClassId</Item>
+ </Issue>
+ </Message>
+ <Message Id="4#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>MethodId</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>ConnectionCloseBody.CreateAMQFrame(UInt16, UInt16, String, UInt16, UInt16):AMQFrame</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="METHOD_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>ConnectionCloseBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>ConnectionCloseBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="MethodId">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>MethodId</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="ReplyCode">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>ReplyCode</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="ReplyText">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>ReplyText</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="ConnectionCloseOkBody">
+ <Members>
+ <Member Name="CLASS_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>ConnectionCloseOkBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>ConnectionCloseOkBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="CreateAMQFrame(System.UInt16):Qpid.Framing.AMQFrame">
+ <Messages>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>ConnectionCloseOkBody.CreateAMQFrame(UInt16):AMQFrame</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="METHOD_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>ConnectionCloseOkBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>ConnectionCloseOkBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="ConnectionOpenBody">
+ <Members>
+ <Member Name="Capabilities">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Capabilities</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="CLASS_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>ConnectionOpenBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>ConnectionOpenBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="CreateAMQFrame(System.UInt16,System.String,System.String,System.Boolean):Qpid.Framing.AMQFrame">
+ <Messages>
+ <Message Id="1#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>VirtualHost</Item>
+ </Issue>
+ </Message>
+ <Message Id="2#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>Capabilities</Item>
+ </Issue>
+ </Message>
+ <Message Id="3#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>Insist</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>ConnectionOpenBody.CreateAMQFrame(UInt16, String, String, Boolean):AMQFrame</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Insist">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Insist</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="METHOD_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>ConnectionOpenBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>ConnectionOpenBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="VirtualHost">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>VirtualHost</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="ConnectionOpenOkBody">
+ <Members>
+ <Member Name="CLASS_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>ConnectionOpenOkBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>ConnectionOpenOkBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="CreateAMQFrame(System.UInt16,System.String):Qpid.Framing.AMQFrame">
+ <Messages>
+ <Message Id="1#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>KnownHosts</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>ConnectionOpenOkBody.CreateAMQFrame(UInt16, String):AMQFrame</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="KnownHosts">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>KnownHosts</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="METHOD_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>ConnectionOpenOkBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>ConnectionOpenOkBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="ConnectionRedirectBody">
+ <Members>
+ <Member Name="CLASS_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>ConnectionRedirectBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>ConnectionRedirectBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="CreateAMQFrame(System.UInt16,System.String,System.String):Qpid.Framing.AMQFrame">
+ <Messages>
+ <Message Id="1#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>Host</Item>
+ </Issue>
+ </Message>
+ <Message Id="2#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>KnownHosts</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>ConnectionRedirectBody.CreateAMQFrame(UInt16, String, String):AMQFrame</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Host">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Host</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="KnownHosts">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>KnownHosts</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="METHOD_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>ConnectionRedirectBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>ConnectionRedirectBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="ConnectionSecureBody">
+ <Members>
+ <Member Name="Challenge">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Challenge</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="CLASS_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>ConnectionSecureBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>ConnectionSecureBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="CreateAMQFrame(System.UInt16,System.Byte[]):Qpid.Framing.AMQFrame">
+ <Messages>
+ <Message Id="1#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>Challenge</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>ConnectionSecureBody.CreateAMQFrame(UInt16, Byte[]):AMQFrame</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="METHOD_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>ConnectionSecureBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>ConnectionSecureBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="ConnectionSecureOkBody">
+ <Members>
+ <Member Name="CLASS_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>ConnectionSecureOkBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>ConnectionSecureOkBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="CreateAMQFrame(System.UInt16,System.Byte[]):Qpid.Framing.AMQFrame">
+ <Messages>
+ <Message Id="1#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>Response</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>ConnectionSecureOkBody.CreateAMQFrame(UInt16, Byte[]):AMQFrame</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="METHOD_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>ConnectionSecureOkBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>ConnectionSecureOkBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Response">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Response</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="ConnectionStartBody">
+ <Members>
+ <Member Name="CLASS_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>ConnectionStartBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>ConnectionStartBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="CreateAMQFrame(System.UInt16,System.Byte,System.Byte,Qpid.Framing.FieldTable,System.Byte[],System.Byte[]):Qpid.Framing.AMQFrame">
+ <Messages>
+ <Message Id="1#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>VersionMajor</Item>
+ </Issue>
+ </Message>
+ <Message Id="2#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>VersionMinor</Item>
+ </Issue>
+ </Message>
+ <Message Id="3#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>ServerProperties</Item>
+ </Issue>
+ </Message>
+ <Message Id="4#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>Mechanisms</Item>
+ </Issue>
+ </Message>
+ <Message Id="5#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>Locales</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>ConnectionStartBody.CreateAMQFrame(UInt16, Byte, Byte, FieldTable, Byte[], Byte[]):AMQFrame</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Locales">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Locales</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Mechanisms">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Mechanisms</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="METHOD_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>ConnectionStartBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>ConnectionStartBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="ServerProperties">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>ServerProperties</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="VersionMajor">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>VersionMajor</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="VersionMinor">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>VersionMinor</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="ConnectionStartOkBody">
+ <Members>
+ <Member Name="CLASS_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>ConnectionStartOkBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>ConnectionStartOkBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="ClientProperties">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>ClientProperties</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="CreateAMQFrame(System.UInt16,Qpid.Framing.FieldTable,System.String,System.Byte[],System.String):Qpid.Framing.AMQFrame">
+ <Messages>
+ <Message Id="1#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>ClientProperties</Item>
+ </Issue>
+ </Message>
+ <Message Id="2#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>Mechanism</Item>
+ </Issue>
+ </Message>
+ <Message Id="3#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>Response</Item>
+ </Issue>
+ </Message>
+ <Message Id="4#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>Locale</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>ConnectionStartOkBody.CreateAMQFrame(UInt16, FieldTable, String, Byte[], String):AMQFrame</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Locale">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Locale</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Mechanism">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Mechanism</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="METHOD_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>ConnectionStartOkBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>ConnectionStartOkBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Response">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Response</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="ConnectionTuneBody">
+ <Members>
+ <Member Name="ChannelMax">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>ChannelMax</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="CLASS_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>ConnectionTuneBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>ConnectionTuneBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="CreateAMQFrame(System.UInt16,System.UInt16,System.UInt32,System.UInt16):Qpid.Framing.AMQFrame">
+ <Messages>
+ <Message Id="1#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>ChannelMax</Item>
+ </Issue>
+ </Message>
+ <Message Id="2#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>FrameMax</Item>
+ </Issue>
+ </Message>
+ <Message Id="3#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>Heartbeat</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>ConnectionTuneBody.CreateAMQFrame(UInt16, UInt16, UInt32, UInt16):AMQFrame</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="FrameMax">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>FrameMax</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Heartbeat">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Heartbeat</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="METHOD_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>ConnectionTuneBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>ConnectionTuneBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="ConnectionTuneOkBody">
+ <Members>
+ <Member Name="ChannelMax">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>ChannelMax</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="CLASS_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>ConnectionTuneOkBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>ConnectionTuneOkBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="CreateAMQFrame(System.UInt16,System.UInt16,System.UInt32,System.UInt16):Qpid.Framing.AMQFrame">
+ <Messages>
+ <Message Id="1#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>ChannelMax</Item>
+ </Issue>
+ </Message>
+ <Message Id="2#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>FrameMax</Item>
+ </Issue>
+ </Message>
+ <Message Id="3#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>Heartbeat</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>ConnectionTuneOkBody.CreateAMQFrame(UInt16, UInt16, UInt32, UInt16):AMQFrame</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="FrameMax">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>FrameMax</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Heartbeat">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Heartbeat</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="METHOD_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>ConnectionTuneOkBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>ConnectionTuneOkBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="ContentBody">
+ <Members>
+ <Member Name="CreateAMQFrame(System.UInt16,Qpid.Framing.ContentBody):Qpid.Framing.AMQFrame">
+ <Messages>
+ <Message TypeName="ConsiderPassingBaseTypesAsParameters" Category="Microsoft.Design" CheckId="CA1011" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>body</Item>
+ <Item>ContentBody.CreateAMQFrame(UInt16, ContentBody):AMQFrame</Item>
+ <Item>Qpid.Framing.ContentBody</Item>
+ <Item>Qpid.Framing.IBody</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>ContentBody.CreateAMQFrame(UInt16, ContentBody):AMQFrame</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Payload">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Payload</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="PopulateFromBuffer(Qpid.Buffer.ByteBuffer,System.UInt32):System.Void">
+ <Messages>
+ <Message TypeName="ValidateArgumentsOfPublicMethods" Category="Microsoft.Design" CheckId="CA1062" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>'buffer'</Item>
+ <Item>ContentBody.PopulateFromBuffer(ByteBuffer, UInt32):Void</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="TYPE">
+ <Messages>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>ContentBody.TYPE</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="WritePayload(Qpid.Buffer.ByteBuffer):System.Void">
+ <Messages>
+ <Message TypeName="ValidateArgumentsOfPublicMethods" Category="Microsoft.Design" CheckId="CA1062" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>'buffer'</Item>
+ <Item>ContentBody.WritePayload(ByteBuffer):Void</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="ContentBodyFactory">
+ <Members>
+ <Member Name="GetInstance():Qpid.Framing.ContentBodyFactory">
+ <Messages>
+ <Message TypeName="UsePropertiesWhereAppropriate" Category="Microsoft.Design" CheckId="CA1024" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>GetInstance</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="ContentHeaderBody">
+ <Members>
+ <Member Name="BodySize">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>BodySize</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="ClassId">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>ClassId</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="CreateAMQFrame(System.UInt16,Qpid.Framing.ContentHeaderBody):Qpid.Framing.AMQFrame">
+ <Messages>
+ <Message TypeName="ConsiderPassingBaseTypesAsParameters" Category="Microsoft.Design" CheckId="CA1011" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>body</Item>
+ <Item>ContentHeaderBody.CreateAMQFrame(UInt16, ContentHeaderBody):AMQFrame</Item>
+ <Item>Qpid.Framing.ContentHeaderBody</Item>
+ <Item>Qpid.Framing.IBody</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>ContentHeaderBody.CreateAMQFrame(UInt16, ContentHeaderBody):AMQFrame</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="CreateAMQFrame(System.UInt16,System.UInt16,System.UInt16,Qpid.Framing.BasicContentHeaderProperties,System.UInt32):Qpid.Framing.AMQFrame">
+ <Messages>
+ <Message TypeName="ConsiderPassingBaseTypesAsParameters" Category="Microsoft.Design" CheckId="CA1011" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>properties</Item>
+ <Item>ContentHeaderBody.CreateAMQFrame(UInt16, UInt16, UInt16, BasicContentHeaderProperties, UInt32):AMQFrame</Item>
+ <Item>Qpid.Framing.BasicContentHeaderProperties</Item>
+ <Item>Qpid.Framing.IContentHeaderProperties</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>ContentHeaderBody.CreateAMQFrame(UInt16, UInt16, UInt16, BasicContentHeaderProperties, UInt32):AMQFrame</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="PopulateFromBuffer(Qpid.Buffer.ByteBuffer,System.UInt32):System.Void">
+ <Messages>
+ <Message TypeName="ValidateArgumentsOfPublicMethods" Category="Microsoft.Design" CheckId="CA1062" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>'buffer'</Item>
+ <Item>ContentHeaderBody.PopulateFromBuffer(ByteBuffer, UInt32):Void</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Properties">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Properties</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="ToString():System.String">
+ <Messages>
+ <Message Id="System.String.Format(System.String,System.Object[])" TypeName="SpecifyIFormatProvider" Category="Microsoft.Globalization" CheckId="CA1305" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>ContentHeaderBody.ToString():String</Item>
+ <Item>System.String.Format(System.String,System.Object[])</Item>
+ <Item>System.String.Format(System.IFormatProvider,System.String,System.Object[])</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="TYPE">
+ <Messages>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>ContentHeaderBody.TYPE</Item>
+ </Issue>
+ </Message>
+ <Message TypeName="UseLiteralsWhereAppropriate" Category="Microsoft.Performance" CheckId="CA1802" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>TYPE</Item>
+ <Item>2</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Weight">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Weight</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="WritePayload(Qpid.Buffer.ByteBuffer):System.Void">
+ <Messages>
+ <Message TypeName="ValidateArgumentsOfPublicMethods" Category="Microsoft.Design" CheckId="CA1062" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>'buffer'</Item>
+ <Item>ContentHeaderBody.WritePayload(ByteBuffer):Void</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="ContentHeaderBodyFactory">
+ <Members>
+ <Member Name="GetInstance():Qpid.Framing.ContentHeaderBodyFactory">
+ <Messages>
+ <Message TypeName="UsePropertiesWhereAppropriate" Category="Microsoft.Design" CheckId="CA1024" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>GetInstance</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="ContentHeaderPropertiesFactory">
+ <Members>
+ <Member Name="CreateContentHeaderProperties(System.UInt16,System.UInt16,Qpid.Buffer.ByteBuffer):Qpid.Framing.IContentHeaderProperties">
+ <Messages>
+ <Message Id="Qpid.Framing.AMQFrameDecodingException.#ctor(System.String)" TypeName="DoNotPassLiteralsAsLocalizedParameters" Category="Microsoft.Globalization" CheckId="CA1303" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>ContentHeaderPropertiesFactory.CreateContentHeaderProperties(UInt16, UInt16, ByteBuffer):IContentHeaderProperties</Item>
+ <Item>1</Item>
+ <Item>AMQFrameDecodingException.AMQFrameDecodingException(String)</Item>
+ <Item>Unsupport content header class id: __</Item>
+ </Issue>
+ </Message>
+ <Message Id="Unsupport" TypeName="LiteralsShouldBeSpelledCorrectly" Category="Microsoft.Usage" CheckId="CA2204" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Unsupport</Item>
+ <Item>Unsupport content header class id: __</Item>
+ </Issue>
+ </Message>
+ <Message TypeName="MarkMembersAsStatic" Category="Microsoft.Performance" CheckId="CA1822" Created="2006-12-04 13:11:47Z" FixCategory="Breaking">
+ <Issue>
+ <Item>ContentHeaderPropertiesFactory.CreateContentHeaderProperties(UInt16, UInt16, ByteBuffer):IContentHeaderProperties</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="GetInstance():Qpid.Framing.ContentHeaderPropertiesFactory">
+ <Messages>
+ <Message TypeName="UsePropertiesWhereAppropriate" Category="Microsoft.Design" CheckId="CA1024" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>GetInstance</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="DtxSelectBody">
+ <Messages>
+ <Message Id="Dtx" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Type">
+ <Item>Dtx</Item>
+ <Item>Qpid.Framing.DtxSelectBody</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ <Members>
+ <Member Name="CLASS_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>DtxSelectBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>DtxSelectBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="CreateAMQFrame(System.UInt16):Qpid.Framing.AMQFrame">
+ <Messages>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>DtxSelectBody.CreateAMQFrame(UInt16):AMQFrame</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="METHOD_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>DtxSelectBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>DtxSelectBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="DtxSelectOkBody">
+ <Messages>
+ <Message Id="Dtx" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Type">
+ <Item>Dtx</Item>
+ <Item>Qpid.Framing.DtxSelectOkBody</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ <Members>
+ <Member Name="CLASS_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>DtxSelectOkBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>DtxSelectOkBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="CreateAMQFrame(System.UInt16):Qpid.Framing.AMQFrame">
+ <Messages>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>DtxSelectOkBody.CreateAMQFrame(UInt16):AMQFrame</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="METHOD_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>DtxSelectOkBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>DtxSelectOkBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="DtxStartBody">
+ <Messages>
+ <Message Id="Dtx" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Type">
+ <Item>Dtx</Item>
+ <Item>Qpid.Framing.DtxStartBody</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ <Members>
+ <Member Name="CLASS_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>DtxStartBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>DtxStartBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="CreateAMQFrame(System.UInt16,System.String):Qpid.Framing.AMQFrame">
+ <Messages>
+ <Message Id="1#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>DtxIdentifier</Item>
+ </Issue>
+ </Message>
+ <Message Id="1#Dtx" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>DtxStartBody.CreateAMQFrame(UInt16, String):AMQFrame</Item>
+ <Item>Dtx</Item>
+ <Item>DtxIdentifier</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>DtxStartBody.CreateAMQFrame(UInt16, String):AMQFrame</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="DtxIdentifier">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>DtxIdentifier</Item>
+ </Issue>
+ </Message>
+ <Message Id="Dtx" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>Dtx</Item>
+ <Item>DtxStartBody.DtxIdentifier</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="METHOD_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>DtxStartBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>DtxStartBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="DtxStartOkBody">
+ <Messages>
+ <Message Id="Dtx" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Type">
+ <Item>Dtx</Item>
+ <Item>Qpid.Framing.DtxStartOkBody</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ <Members>
+ <Member Name="CLASS_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>DtxStartOkBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>DtxStartOkBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="CreateAMQFrame(System.UInt16):Qpid.Framing.AMQFrame">
+ <Messages>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>DtxStartOkBody.CreateAMQFrame(UInt16):AMQFrame</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="METHOD_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>DtxStartOkBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>DtxStartOkBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="EncodingUtils">
+ <Messages>
+ <Message Id="Utils" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Type">
+ <Item>Utils</Item>
+ <Item>Qpid.Framing.EncodingUtils</Item>
+ </Issue>
+ </Message>
+ <Message TypeName="StaticHolderTypesShouldNotHaveConstructors" Category="Microsoft.Design" CheckId="CA1053" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>EncodingUtils</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ <Members>
+ <Member Name="EncodedLongStringLength(System.String):System.UInt32">
+ <Messages>
+ <Message Id="0#s" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="ParameterOneLetter">
+ <Item>EncodingUtils.EncodedLongStringLength(String):UInt32</Item>
+ <Item>s</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="EncodedLongstrLength(System.Byte[]):System.Int32">
+ <Messages>
+ <Message Id="Longstr" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>Longstr</Item>
+ <Item>EncodingUtils.EncodedLongstrLength(Byte[]):Int32</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="EncodedShortStringLength(System.String):System.UInt16">
+ <Messages>
+ <Message Id="0#s" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="ParameterOneLetter">
+ <Item>EncodingUtils.EncodedShortStringLength(String):UInt16</Item>
+ <Item>s</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="ReadBooleans(Qpid.Buffer.ByteBuffer):System.Boolean[]">
+ <Messages>
+ <Message TypeName="ValidateArgumentsOfPublicMethods" Category="Microsoft.Design" CheckId="CA1062" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>'buffer'</Item>
+ <Item>EncodingUtils.ReadBooleans(ByteBuffer):Boolean[]</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="ReadFieldTable(Qpid.Buffer.ByteBuffer):Qpid.Framing.FieldTable">
+ <Messages>
+ <Message TypeName="ValidateArgumentsOfPublicMethods" Category="Microsoft.Design" CheckId="CA1062" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>'buffer'</Item>
+ <Item>EncodingUtils.ReadFieldTable(ByteBuffer):FieldTable</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="ReadLongstr(Qpid.Buffer.ByteBuffer):System.Byte[]">
+ <Messages>
+ <Message Id="Longstr" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>Longstr</Item>
+ <Item>EncodingUtils.ReadLongstr(ByteBuffer):Byte[]</Item>
+ </Issue>
+ </Message>
+ <Message TypeName="ValidateArgumentsOfPublicMethods" Category="Microsoft.Design" CheckId="CA1062" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>'buffer'</Item>
+ <Item>EncodingUtils.ReadLongstr(ByteBuffer):Byte[]</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="ReadLongString(Qpid.Buffer.ByteBuffer):System.String">
+ <Messages>
+ <Message TypeName="ValidateArgumentsOfPublicMethods" Category="Microsoft.Design" CheckId="CA1062" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>'buffer'</Item>
+ <Item>EncodingUtils.ReadLongString(ByteBuffer):String</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="ReadShortString(Qpid.Buffer.ByteBuffer):System.String">
+ <Messages>
+ <Message TypeName="ValidateArgumentsOfPublicMethods" Category="Microsoft.Design" CheckId="CA1062" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>'buffer'</Item>
+ <Item>EncodingUtils.ReadShortString(ByteBuffer):String</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="WriteBooleans(Qpid.Buffer.ByteBuffer,System.Boolean[]):System.Void">
+ <Messages>
+ <Message TypeName="ValidateArgumentsOfPublicMethods" Category="Microsoft.Design" CheckId="CA1062" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>'buffer'</Item>
+ <Item>EncodingUtils.WriteBooleans(ByteBuffer, Boolean[]):Void</Item>
+ </Issue>
+ <Issue>
+ <Item>'values'</Item>
+ <Item>EncodingUtils.WriteBooleans(ByteBuffer, Boolean[]):Void</Item>
+ </Issue>
+ <Issue>
+ <Item>'values'</Item>
+ <Item>EncodingUtils.WriteBooleans(ByteBuffer, Boolean[]):Void</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="WriteFieldTableBytes(Qpid.Buffer.ByteBuffer,Qpid.Framing.FieldTable):System.Void">
+ <Messages>
+ <Message TypeName="ValidateArgumentsOfPublicMethods" Category="Microsoft.Design" CheckId="CA1062" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>'buffer'</Item>
+ <Item>EncodingUtils.WriteFieldTableBytes(ByteBuffer, FieldTable):Void</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="WriteLongstr(Qpid.Buffer.ByteBuffer,System.Byte[]):System.Void">
+ <Messages>
+ <Message Id="Longstr" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>Longstr</Item>
+ <Item>EncodingUtils.WriteLongstr(ByteBuffer, Byte[]):Void</Item>
+ </Issue>
+ </Message>
+ <Message TypeName="ValidateArgumentsOfPublicMethods" Category="Microsoft.Design" CheckId="CA1062" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>'buffer'</Item>
+ <Item>EncodingUtils.WriteLongstr(ByteBuffer, Byte[]):Void</Item>
+ </Issue>
+ <Issue>
+ <Item>'buffer'</Item>
+ <Item>EncodingUtils.WriteLongstr(ByteBuffer, Byte[]):Void</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="WriteLongStringBytes(Qpid.Buffer.ByteBuffer,System.String):System.Void">
+ <Messages>
+ <Message Id="System.ArgumentException.#ctor(System.String)" TypeName="DoNotPassLiteralsAsLocalizedParameters" Category="Microsoft.Globalization" CheckId="CA1303" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>EncodingUtils.WriteLongStringBytes(ByteBuffer, String):Void</Item>
+ <Item>1</Item>
+ <Item>ArgumentException.ArgumentException(String)</Item>
+ <Item>String too long</Item>
+ </Issue>
+ </Message>
+ <Message Id="1#s" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="ParameterOneLetter">
+ <Item>EncodingUtils.WriteLongStringBytes(ByteBuffer, String):Void</Item>
+ <Item>s</Item>
+ </Issue>
+ </Message>
+ <Message TypeName="ValidateArgumentsOfPublicMethods" Category="Microsoft.Design" CheckId="CA1062" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>'buffer'</Item>
+ <Item>EncodingUtils.WriteLongStringBytes(ByteBuffer, String):Void</Item>
+ </Issue>
+ <Issue>
+ <Item>'buffer'</Item>
+ <Item>EncodingUtils.WriteLongStringBytes(ByteBuffer, String):Void</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="WriteShortStringBytes(Qpid.Buffer.ByteBuffer,System.String):System.Void">
+ <Messages>
+ <Message Id="1#s" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="ParameterOneLetter">
+ <Item>EncodingUtils.WriteShortStringBytes(ByteBuffer, String):Void</Item>
+ <Item>s</Item>
+ </Issue>
+ </Message>
+ <Message TypeName="ValidateArgumentsOfPublicMethods" Category="Microsoft.Design" CheckId="CA1062" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>'buffer'</Item>
+ <Item>EncodingUtils.WriteShortStringBytes(ByteBuffer, String):Void</Item>
+ </Issue>
+ <Issue>
+ <Item>'buffer'</Item>
+ <Item>EncodingUtils.WriteShortStringBytes(ByteBuffer, String):Void</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="ExchangeDeclareBody">
+ <Members>
+ <Member Name="Arguments">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Arguments</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="AutoDelete">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>AutoDelete</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="CLASS_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>ExchangeDeclareBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>ExchangeDeclareBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="CreateAMQFrame(System.UInt16,System.UInt16,System.String,System.String,System.Boolean,System.Boolean,System.Boolean,System.Boolean,System.Boolean,Qpid.Framing.FieldTable):Qpid.Framing.AMQFrame">
+ <Messages>
+ <Message Id="1#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>Ticket</Item>
+ </Issue>
+ </Message>
+ <Message Id="2#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>Exchange</Item>
+ </Issue>
+ </Message>
+ <Message Id="3#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>Type</Item>
+ </Issue>
+ </Message>
+ <Message Id="4#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>Passive</Item>
+ </Issue>
+ </Message>
+ <Message Id="5#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>Durable</Item>
+ </Issue>
+ </Message>
+ <Message Id="6#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>AutoDelete</Item>
+ </Issue>
+ </Message>
+ <Message Id="7#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>Internal</Item>
+ </Issue>
+ </Message>
+ <Message Id="8#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>Nowait</Item>
+ </Issue>
+ </Message>
+ <Message Id="9#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>Arguments</Item>
+ </Issue>
+ </Message>
+ <Message Id="8#Nowait" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>ExchangeDeclareBody.CreateAMQFrame(UInt16, UInt16, String, String, Boolean, Boolean, Boolean, Boolean, Boolean, FieldTable):AMQFrame</Item>
+ <Item>Nowait</Item>
+ <Item>Nowait</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>ExchangeDeclareBody.CreateAMQFrame(UInt16, UInt16, String, String, Boolean, Boolean, Boolean, Boolean, Boolean, FieldTable):AMQFrame</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Durable">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Durable</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Exchange">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Exchange</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Internal">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Internal</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="METHOD_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>ExchangeDeclareBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>ExchangeDeclareBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Nowait">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Nowait</Item>
+ </Issue>
+ </Message>
+ <Message Id="Nowait" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>Nowait</Item>
+ <Item>ExchangeDeclareBody.Nowait</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Passive">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Passive</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Ticket">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Ticket</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Type">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Type</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="ExchangeDeclareOkBody">
+ <Members>
+ <Member Name="CLASS_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>ExchangeDeclareOkBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>ExchangeDeclareOkBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="CreateAMQFrame(System.UInt16):Qpid.Framing.AMQFrame">
+ <Messages>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>ExchangeDeclareOkBody.CreateAMQFrame(UInt16):AMQFrame</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="METHOD_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>ExchangeDeclareOkBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>ExchangeDeclareOkBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="ExchangeDeleteBody">
+ <Members>
+ <Member Name="CLASS_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>ExchangeDeleteBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>ExchangeDeleteBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="CreateAMQFrame(System.UInt16,System.UInt16,System.String,System.Boolean,System.Boolean):Qpid.Framing.AMQFrame">
+ <Messages>
+ <Message Id="1#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>Ticket</Item>
+ </Issue>
+ </Message>
+ <Message Id="2#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>Exchange</Item>
+ </Issue>
+ </Message>
+ <Message Id="3#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>IfUnused</Item>
+ </Issue>
+ </Message>
+ <Message Id="4#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>Nowait</Item>
+ </Issue>
+ </Message>
+ <Message Id="4#Nowait" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>ExchangeDeleteBody.CreateAMQFrame(UInt16, UInt16, String, Boolean, Boolean):AMQFrame</Item>
+ <Item>Nowait</Item>
+ <Item>Nowait</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>ExchangeDeleteBody.CreateAMQFrame(UInt16, UInt16, String, Boolean, Boolean):AMQFrame</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Exchange">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Exchange</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="IfUnused">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>IfUnused</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="METHOD_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>ExchangeDeleteBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>ExchangeDeleteBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Nowait">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Nowait</Item>
+ </Issue>
+ </Message>
+ <Message Id="Nowait" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>Nowait</Item>
+ <Item>ExchangeDeleteBody.Nowait</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Ticket">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Ticket</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="ExchangeDeleteOkBody">
+ <Members>
+ <Member Name="CLASS_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>ExchangeDeleteOkBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>ExchangeDeleteOkBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="CreateAMQFrame(System.UInt16):Qpid.Framing.AMQFrame">
+ <Messages>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>ExchangeDeleteOkBody.CreateAMQFrame(UInt16):AMQFrame</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="METHOD_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>ExchangeDeleteOkBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>ExchangeDeleteOkBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="FieldTable">
+ <Messages>
+ <Message TypeName="CollectionsShouldImplementGenericInterface" Category="Microsoft.Design" CheckId="CA1010" Created="2006-12-04 13:11:47Z">
+ <Issue Certainty="60">
+ <Item>FieldTable</Item>
+ <Item>IEnumerable</Item>
+ </Issue>
+ </Message>
+ <Message TypeName="IdentifiersShouldHaveCorrectSuffix" Category="Microsoft.Naming" CheckId="CA1710" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Qpid.Framing.FieldTable</Item>
+ <Item>Collection</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ <Members>
+ <Member Name=".ctor()">
+ <Messages>
+ <Message TypeName="DoNotInitializeUnnecessarily" Category="Microsoft.Performance" CheckId="CA1805" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>FieldTable.FieldTable()</Item>
+ <Item>_encodedSize</Item>
+ <Item>System.UInt32</Item>
+ <Item>0</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name=".ctor(Qpid.Buffer.ByteBuffer,System.UInt32)">
+ <Messages>
+ <Message Id="Qpid.Framing.AMQFrameDecodingException.#ctor(System.String)" TypeName="DoNotPassLiteralsAsLocalizedParameters" Category="Microsoft.Globalization" CheckId="CA1303" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>FieldTable.FieldTable(ByteBuffer, UInt32)</Item>
+ <Item>1</Item>
+ <Item>AMQFrameDecodingException.AMQFrameDecodingException(String)</Item>
+ <Item>Unsupported field table type: __</Item>
+ </Issue>
+ </Message>
+ <Message TypeName="ValidateArgumentsOfPublicMethods" Category="Microsoft.Design" CheckId="CA1062" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>'buffer'</Item>
+ <Item>FieldTable.FieldTable(ByteBuffer, UInt32)</Item>
+ </Issue>
+ <Issue>
+ <Item>'buffer'</Item>
+ <Item>FieldTable.FieldTable(ByteBuffer, UInt32)</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="AddAll(Qpid.Messaging.IFieldTable):System.Void">
+ <Messages>
+ <Message Id="0#" TypeName="ParameterNamesShouldMatchBaseDeclaration" Category="Microsoft.Naming" CheckId="CA1725" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>ft</Item>
+ <Item>FieldTable.AddAll(IFieldTable):Void</Item>
+ <Item>source</Item>
+ <Item>IFieldTable.AddAll(IFieldTable):Void</Item>
+ </Issue>
+ </Message>
+ <Message TypeName="ValidateArgumentsOfPublicMethods" Category="Microsoft.Design" CheckId="CA1062" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>'ft'</Item>
+ <Item>FieldTable.AddAll(IFieldTable):Void</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="AdjustEncodingSizeWhenAdding(System.Object,System.Object):System.Void">
+ <Messages>
+ <Message TypeName="DoNotCastUnnecessarily" Category="Microsoft.Performance" CheckId="CA1800" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>value</Item>
+ <Item>System.String</Item>
+ <Item>FieldTable.AdjustEncodingSizeWhenAdding(Object, Object):Void</Item>
+ <Item>castclass</Item>
+ </Issue>
+ </Message>
+ <Message Id="System.Exception.#ctor(System.String)" TypeName="DoNotPassLiteralsAsLocalizedParameters" Category="Microsoft.Globalization" CheckId="CA1303" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>FieldTable.AdjustEncodingSizeWhenAdding(Object, Object):Void</Item>
+ <Item>1</Item>
+ <Item>Exception.Exception(String)</Item>
+ <Item>Unsupported value type: __</Item>
+ </Issue>
+ </Message>
+ <Message TypeName="DoNotRaiseReservedExceptionTypes" Category="Microsoft.Usage" CheckId="CA2201" Created="2006-12-04 13:11:47Z">
+ <Issue Name="TooGeneric">
+ <Item>FieldTable.AdjustEncodingSizeWhenAdding(Object, Object):Void</Item>
+ <Item>System.Exception</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="AdjustEncodingSizeWhenRemoving(System.Object,System.Object):System.Void">
+ <Messages>
+ <Message TypeName="DoNotCastUnnecessarily" Category="Microsoft.Performance" CheckId="CA1800" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>value</Item>
+ <Item>System.String</Item>
+ <Item>FieldTable.AdjustEncodingSizeWhenRemoving(Object, Object):Void</Item>
+ <Item>castclass</Item>
+ </Issue>
+ </Message>
+ <Message Id="System.Exception.#ctor(System.String)" TypeName="DoNotPassLiteralsAsLocalizedParameters" Category="Microsoft.Globalization" CheckId="CA1303" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>FieldTable.AdjustEncodingSizeWhenRemoving(Object, Object):Void</Item>
+ <Item>1</Item>
+ <Item>Exception.Exception(String)</Item>
+ <Item>Illegal value type: __</Item>
+ </Issue>
+ </Message>
+ <Message TypeName="DoNotRaiseReservedExceptionTypes" Category="Microsoft.Usage" CheckId="CA2201" Created="2006-12-04 13:11:47Z">
+ <Issue Name="TooGeneric">
+ <Item>FieldTable.AdjustEncodingSizeWhenRemoving(Object, Object):Void</Item>
+ <Item>System.Exception</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="CheckKey(System.Object):System.Void">
+ <Messages>
+ <Message Id="System.ArgumentException.#ctor(System.String)" TypeName="DoNotPassLiteralsAsLocalizedParameters" Category="Microsoft.Globalization" CheckId="CA1303" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>FieldTable.CheckKey(Object):Void</Item>
+ <Item>1</Item>
+ <Item>ArgumentException.ArgumentException(String)</Item>
+ <Item>All keys must be Strings - was passed: __</Item>
+ </Issue>
+ </Message>
+ <Message TypeName="MarkMembersAsStatic" Category="Microsoft.Performance" CheckId="CA1822" Created="2006-12-04 13:11:47Z" FixCategory="NonBreaking">
+ <Issue>
+ <Item>FieldTable.CheckKey(Object):Void</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="CheckValue(System.Object):System.Void">
+ <Messages>
+ <Message Id="System.ArgumentException.#ctor(System.String)" TypeName="DoNotPassLiteralsAsLocalizedParameters" Category="Microsoft.Globalization" CheckId="CA1303" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>FieldTable.CheckValue(Object):Void</Item>
+ <Item>1</Item>
+ <Item>ArgumentException.ArgumentException(String)</Item>
+ <Item>All values must be type string or int or long or uint, was passed: __</Item>
+ </Issue>
+ </Message>
+ <Message TypeName="MarkMembersAsStatic" Category="Microsoft.Performance" CheckId="CA1822" Created="2006-12-04 13:11:47Z" FixCategory="NonBreaking">
+ <Issue>
+ <Item>FieldTable.CheckValue(Object):Void</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="WritePayload(Qpid.Buffer.ByteBuffer):System.Void">
+ <Messages>
+ <Message TypeName="DoNotCastUnnecessarily" Category="Microsoft.Performance" CheckId="CA1800" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Local">
+ <Item>value</Item>
+ <Item>System.Byte[]</Item>
+ <Item>FieldTable.WritePayload(ByteBuffer):Void</Item>
+ <Item>castclass</Item>
+ </Issue>
+ <Issue Name="Local">
+ <Item>value</Item>
+ <Item>System.String</Item>
+ <Item>FieldTable.WritePayload(ByteBuffer):Void</Item>
+ <Item>castclass</Item>
+ </Issue>
+ </Message>
+ <Message Id="System.InvalidOperationException.#ctor(System.String)" TypeName="DoNotPassLiteralsAsLocalizedParameters" Category="Microsoft.Globalization" CheckId="CA1303" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>FieldTable.WritePayload(ByteBuffer):Void</Item>
+ <Item>1</Item>
+ <Item>InvalidOperationException.InvalidOperationException(String)</Item>
+ <Item>Unsupported type in FieldTable: __</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="WriteToBuffer(Qpid.Buffer.ByteBuffer):System.Void">
+ <Messages>
+ <Message TypeName="ValidateArgumentsOfPublicMethods" Category="Microsoft.Design" CheckId="CA1062" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>'buffer'</Item>
+ <Item>FieldTable.WriteToBuffer(ByteBuffer):Void</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="FileAckBody">
+ <Messages>
+ <Message Id="Ack" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Type">
+ <Item>Ack</Item>
+ <Item>Qpid.Framing.FileAckBody</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ <Members>
+ <Member Name="CLASS_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>FileAckBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>FileAckBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="CreateAMQFrame(System.UInt16,System.UInt64,System.Boolean):Qpid.Framing.AMQFrame">
+ <Messages>
+ <Message Id="1#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>DeliveryTag</Item>
+ </Issue>
+ </Message>
+ <Message Id="2#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>Multiple</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>FileAckBody.CreateAMQFrame(UInt16, UInt64, Boolean):AMQFrame</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="DeliveryTag">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>DeliveryTag</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="METHOD_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>FileAckBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>FileAckBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Multiple">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Multiple</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="FileCancelBody">
+ <Members>
+ <Member Name="CLASS_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>FileCancelBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>FileCancelBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="ConsumerTag">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>ConsumerTag</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="CreateAMQFrame(System.UInt16,System.String,System.Boolean):Qpid.Framing.AMQFrame">
+ <Messages>
+ <Message Id="1#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>ConsumerTag</Item>
+ </Issue>
+ </Message>
+ <Message Id="2#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>Nowait</Item>
+ </Issue>
+ </Message>
+ <Message Id="2#Nowait" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>FileCancelBody.CreateAMQFrame(UInt16, String, Boolean):AMQFrame</Item>
+ <Item>Nowait</Item>
+ <Item>Nowait</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>FileCancelBody.CreateAMQFrame(UInt16, String, Boolean):AMQFrame</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="METHOD_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>FileCancelBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>FileCancelBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Nowait">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Nowait</Item>
+ </Issue>
+ </Message>
+ <Message Id="Nowait" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>Nowait</Item>
+ <Item>FileCancelBody.Nowait</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="FileCancelOkBody">
+ <Members>
+ <Member Name="CLASS_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>FileCancelOkBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>FileCancelOkBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="ConsumerTag">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>ConsumerTag</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="CreateAMQFrame(System.UInt16,System.String):Qpid.Framing.AMQFrame">
+ <Messages>
+ <Message Id="1#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>ConsumerTag</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>FileCancelOkBody.CreateAMQFrame(UInt16, String):AMQFrame</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="METHOD_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>FileCancelOkBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>FileCancelOkBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="FileConsumeBody">
+ <Members>
+ <Member Name="CLASS_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>FileConsumeBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>FileConsumeBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="ConsumerTag">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>ConsumerTag</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="CreateAMQFrame(System.UInt16,System.UInt16,System.String,System.String,System.Boolean,System.Boolean,System.Boolean,System.Boolean):Qpid.Framing.AMQFrame">
+ <Messages>
+ <Message Id="1#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>Ticket</Item>
+ </Issue>
+ </Message>
+ <Message Id="2#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>Queue</Item>
+ </Issue>
+ </Message>
+ <Message Id="3#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>ConsumerTag</Item>
+ </Issue>
+ </Message>
+ <Message Id="4#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>NoLocal</Item>
+ </Issue>
+ </Message>
+ <Message Id="5#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>NoAck</Item>
+ </Issue>
+ </Message>
+ <Message Id="6#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>Exclusive</Item>
+ </Issue>
+ </Message>
+ <Message Id="7#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>Nowait</Item>
+ </Issue>
+ </Message>
+ <Message Id="5#Ack" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>FileConsumeBody.CreateAMQFrame(UInt16, UInt16, String, String, Boolean, Boolean, Boolean, Boolean):AMQFrame</Item>
+ <Item>Ack</Item>
+ <Item>NoAck</Item>
+ </Issue>
+ </Message>
+ <Message Id="7#Nowait" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>FileConsumeBody.CreateAMQFrame(UInt16, UInt16, String, String, Boolean, Boolean, Boolean, Boolean):AMQFrame</Item>
+ <Item>Nowait</Item>
+ <Item>Nowait</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>FileConsumeBody.CreateAMQFrame(UInt16, UInt16, String, String, Boolean, Boolean, Boolean, Boolean):AMQFrame</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Exclusive">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Exclusive</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="METHOD_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>FileConsumeBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>FileConsumeBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="NoAck">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>NoAck</Item>
+ </Issue>
+ </Message>
+ <Message Id="Ack" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>Ack</Item>
+ <Item>FileConsumeBody.NoAck</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="NoLocal">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>NoLocal</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Nowait">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Nowait</Item>
+ </Issue>
+ </Message>
+ <Message Id="Nowait" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>Nowait</Item>
+ <Item>FileConsumeBody.Nowait</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Queue">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Queue</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Ticket">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Ticket</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="FileConsumeOkBody">
+ <Members>
+ <Member Name="CLASS_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>FileConsumeOkBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>FileConsumeOkBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="ConsumerTag">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>ConsumerTag</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="CreateAMQFrame(System.UInt16,System.String):Qpid.Framing.AMQFrame">
+ <Messages>
+ <Message Id="1#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>ConsumerTag</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>FileConsumeOkBody.CreateAMQFrame(UInt16, String):AMQFrame</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="METHOD_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>FileConsumeOkBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>FileConsumeOkBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="FileDeliverBody">
+ <Members>
+ <Member Name="CLASS_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>FileDeliverBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>FileDeliverBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="ConsumerTag">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>ConsumerTag</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="CreateAMQFrame(System.UInt16,System.String,System.UInt64,System.Boolean,System.String,System.String,System.String):Qpid.Framing.AMQFrame">
+ <Messages>
+ <Message Id="1#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>ConsumerTag</Item>
+ </Issue>
+ </Message>
+ <Message Id="2#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>DeliveryTag</Item>
+ </Issue>
+ </Message>
+ <Message Id="3#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>Redelivered</Item>
+ </Issue>
+ </Message>
+ <Message Id="4#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>Exchange</Item>
+ </Issue>
+ </Message>
+ <Message Id="5#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>RoutingKey</Item>
+ </Issue>
+ </Message>
+ <Message Id="6#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>Identifier</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>FileDeliverBody.CreateAMQFrame(UInt16, String, UInt64, Boolean, String, String, String):AMQFrame</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="DeliveryTag">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>DeliveryTag</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Exchange">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Exchange</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Identifier">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Identifier</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="METHOD_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>FileDeliverBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>FileDeliverBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Redelivered">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Redelivered</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="RoutingKey">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>RoutingKey</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="FileOpenBody">
+ <Members>
+ <Member Name="CLASS_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>FileOpenBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>FileOpenBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="ContentSize">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>ContentSize</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="CreateAMQFrame(System.UInt16,System.String,System.UInt64):Qpid.Framing.AMQFrame">
+ <Messages>
+ <Message Id="1#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>Identifier</Item>
+ </Issue>
+ </Message>
+ <Message Id="2#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>ContentSize</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>FileOpenBody.CreateAMQFrame(UInt16, String, UInt64):AMQFrame</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Identifier">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Identifier</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="METHOD_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>FileOpenBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>FileOpenBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="FileOpenOkBody">
+ <Members>
+ <Member Name="CLASS_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>FileOpenOkBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>FileOpenOkBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="CreateAMQFrame(System.UInt16,System.UInt64):Qpid.Framing.AMQFrame">
+ <Messages>
+ <Message Id="1#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>StagedSize</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>FileOpenOkBody.CreateAMQFrame(UInt16, UInt64):AMQFrame</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="METHOD_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>FileOpenOkBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>FileOpenOkBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="StagedSize">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>StagedSize</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="FilePublishBody">
+ <Members>
+ <Member Name="CLASS_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>FilePublishBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>FilePublishBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="CreateAMQFrame(System.UInt16,System.UInt16,System.String,System.String,System.Boolean,System.Boolean,System.String):Qpid.Framing.AMQFrame">
+ <Messages>
+ <Message Id="1#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>Ticket</Item>
+ </Issue>
+ </Message>
+ <Message Id="2#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>Exchange</Item>
+ </Issue>
+ </Message>
+ <Message Id="3#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>RoutingKey</Item>
+ </Issue>
+ </Message>
+ <Message Id="4#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>Mandatory</Item>
+ </Issue>
+ </Message>
+ <Message Id="5#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>Immediate</Item>
+ </Issue>
+ </Message>
+ <Message Id="6#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>Identifier</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>FilePublishBody.CreateAMQFrame(UInt16, UInt16, String, String, Boolean, Boolean, String):AMQFrame</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Exchange">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Exchange</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Identifier">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Identifier</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Immediate">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Immediate</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Mandatory">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Mandatory</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="METHOD_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>FilePublishBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>FilePublishBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="RoutingKey">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>RoutingKey</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Ticket">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Ticket</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="FileQosBody">
+ <Messages>
+ <Message Id="Qos" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Type">
+ <Item>Qos</Item>
+ <Item>Qpid.Framing.FileQosBody</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ <Members>
+ <Member Name="CLASS_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>FileQosBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>FileQosBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="CreateAMQFrame(System.UInt16,System.UInt32,System.UInt16,System.Boolean):Qpid.Framing.AMQFrame">
+ <Messages>
+ <Message Id="1#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>PrefetchSize</Item>
+ </Issue>
+ </Message>
+ <Message Id="2#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>PrefetchCount</Item>
+ </Issue>
+ </Message>
+ <Message Id="3#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>Global</Item>
+ </Issue>
+ </Message>
+ <Message Id="1#Prefetch" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>FileQosBody.CreateAMQFrame(UInt16, UInt32, UInt16, Boolean):AMQFrame</Item>
+ <Item>Prefetch</Item>
+ <Item>PrefetchSize</Item>
+ </Issue>
+ </Message>
+ <Message Id="2#Prefetch" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>FileQosBody.CreateAMQFrame(UInt16, UInt32, UInt16, Boolean):AMQFrame</Item>
+ <Item>Prefetch</Item>
+ <Item>PrefetchCount</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>FileQosBody.CreateAMQFrame(UInt16, UInt32, UInt16, Boolean):AMQFrame</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Global">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Global</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="METHOD_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>FileQosBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>FileQosBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="PrefetchCount">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>PrefetchCount</Item>
+ </Issue>
+ </Message>
+ <Message Id="Prefetch" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>Prefetch</Item>
+ <Item>FileQosBody.PrefetchCount</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="PrefetchSize">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>PrefetchSize</Item>
+ </Issue>
+ </Message>
+ <Message Id="Prefetch" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>Prefetch</Item>
+ <Item>FileQosBody.PrefetchSize</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="FileQosOkBody">
+ <Messages>
+ <Message Id="Qos" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Type">
+ <Item>Qos</Item>
+ <Item>Qpid.Framing.FileQosOkBody</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ <Members>
+ <Member Name="CLASS_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>FileQosOkBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>FileQosOkBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="CreateAMQFrame(System.UInt16):Qpid.Framing.AMQFrame">
+ <Messages>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>FileQosOkBody.CreateAMQFrame(UInt16):AMQFrame</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="METHOD_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>FileQosOkBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>FileQosOkBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="FileRejectBody">
+ <Members>
+ <Member Name="CLASS_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>FileRejectBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>FileRejectBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="CreateAMQFrame(System.UInt16,System.UInt64,System.Boolean):Qpid.Framing.AMQFrame">
+ <Messages>
+ <Message Id="1#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>DeliveryTag</Item>
+ </Issue>
+ </Message>
+ <Message Id="2#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>Requeue</Item>
+ </Issue>
+ </Message>
+ <Message Id="2#Requeue" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>FileRejectBody.CreateAMQFrame(UInt16, UInt64, Boolean):AMQFrame</Item>
+ <Item>Requeue</Item>
+ <Item>Requeue</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>FileRejectBody.CreateAMQFrame(UInt16, UInt64, Boolean):AMQFrame</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="DeliveryTag">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>DeliveryTag</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="METHOD_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>FileRejectBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>FileRejectBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Requeue">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Requeue</Item>
+ </Issue>
+ </Message>
+ <Message Id="Requeue" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>Requeue</Item>
+ <Item>FileRejectBody.Requeue</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="FileReturnBody">
+ <Members>
+ <Member Name="CLASS_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>FileReturnBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>FileReturnBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="CreateAMQFrame(System.UInt16,System.UInt16,System.String,System.String,System.String):Qpid.Framing.AMQFrame">
+ <Messages>
+ <Message Id="1#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>ReplyCode</Item>
+ </Issue>
+ </Message>
+ <Message Id="2#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>ReplyText</Item>
+ </Issue>
+ </Message>
+ <Message Id="3#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>Exchange</Item>
+ </Issue>
+ </Message>
+ <Message Id="4#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>RoutingKey</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>FileReturnBody.CreateAMQFrame(UInt16, UInt16, String, String, String):AMQFrame</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Exchange">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Exchange</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="METHOD_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>FileReturnBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>FileReturnBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="ReplyCode">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>ReplyCode</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="ReplyText">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>ReplyText</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="RoutingKey">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>RoutingKey</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="FileStageBody">
+ <Members>
+ <Member Name="CLASS_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>FileStageBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>FileStageBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="CreateAMQFrame(System.UInt16):Qpid.Framing.AMQFrame">
+ <Messages>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>FileStageBody.CreateAMQFrame(UInt16):AMQFrame</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="METHOD_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>FileStageBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>FileStageBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="HeartbeatBody">
+ <Members>
+ <Member Name="FRAME">
+ <Messages>
+ <Message TypeName="NonConstantFieldsShouldNotBeVisible" Category="Microsoft.Usage" CheckId="CA2211" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>FRAME</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="PopulateFromBuffer(Qpid.Buffer.ByteBuffer,System.UInt32):System.Void">
+ <Messages>
+ <Message TypeName="ValidateArgumentsOfPublicMethods" Category="Microsoft.Design" CheckId="CA1062" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>'buffer'</Item>
+ <Item>HeartbeatBody.PopulateFromBuffer(ByteBuffer, UInt32):Void</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="TYPE">
+ <Messages>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>HeartbeatBody.TYPE</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="HeartbeatBodyFactory">
+ <Members>
+ <Member Name="CreateBody(Qpid.Buffer.ByteBuffer):Qpid.Framing.IBody">
+ <Messages>
+ <Message Id="0#" TypeName="ParameterNamesShouldMatchBaseDeclaration" Category="Microsoft.Naming" CheckId="CA1725" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>input</Item>
+ <Item>HeartbeatBodyFactory.CreateBody(ByteBuffer):IBody</Item>
+ <Item>inbuf</Item>
+ <Item>IBodyFactory.CreateBody(ByteBuffer):IBody</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="IBodyFactory">
+ <Members>
+ <Member Name="CreateBody(Qpid.Buffer.ByteBuffer):Qpid.Framing.IBody">
+ <Messages>
+ <Message Id="0#inbuf" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>IBodyFactory.CreateBody(ByteBuffer):IBody</Item>
+ <Item>inbuf</Item>
+ <Item>inbuf</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="IEncodableAMQDataBlock">
+ <Messages>
+ <Message TypeName="AvoidEmptyInterfaces" Category="Microsoft.Design" CheckId="CA1040" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>IEncodableAMQDataBlock</Item>
+ </Issue>
+ </Message>
+ <Message TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Type">
+ <Item>IEncodableAMQDataBlock</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Type>
+ <Type Name="MainRegistry">
+ <Messages>
+ <Message TypeName="AvoidUninstantiatedInternalClasses" Category="Microsoft.Performance" CheckId="CA1812" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Qpid.Framing.MainRegistry</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Type>
+ <Type Name="MethodBodyDecoderRegistry">
+ <Messages>
+ <Message TypeName="StaticHolderTypesShouldNotHaveConstructors" Category="Microsoft.Design" CheckId="CA1053" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>MethodBodyDecoderRegistry</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ <Members>
+ <Member Name=".cctor()">
+ <Messages>
+ <Message TypeName="InitializeReferenceTypeStaticFieldsInline" Category="Microsoft.Performance" CheckId="CA1810" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Qpid.Framing.MethodBodyDecoderRegistry</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Get(System.Int32,System.Int32):Qpid.Framing.AMQMethodBody">
+ <Messages>
+ <Message Id="Qpid.Framing.AMQFrameDecodingException.#ctor(log4net.ILog,System.String)" TypeName="DoNotPassLiteralsAsLocalizedParameters" Category="Microsoft.Globalization" CheckId="CA1303" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>MethodBodyDecoderRegistry.Get(Int32, Int32):AMQMethodBody</Item>
+ <Item>2</Item>
+ <Item>AMQFrameDecodingException.AMQFrameDecodingException(ILog, String)</Item>
+ <Item>Unable to find a suitable decoder for class ____ and method __</Item>
+ </Issue>
+ </Message>
+ <Message Id="Qpid.Framing.AMQFrameDecodingException.#ctor(log4net.ILog,System.String,System.Exception)" TypeName="DoNotPassLiteralsAsLocalizedParameters" Category="Microsoft.Globalization" CheckId="CA1303" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>MethodBodyDecoderRegistry.Get(Int32, Int32):AMQMethodBody</Item>
+ <Item>2</Item>
+ <Item>AMQFrameDecodingException.AMQFrameDecodingException(ILog, String, Exception)</Item>
+ <Item>Unable to instantiate body class for class ____ and method ____: __</Item>
+ </Issue>
+ </Message>
+ <Message Id="0#clazz" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>MethodBodyDecoderRegistry.Get(Int32, Int32):AMQMethodBody</Item>
+ <Item>clazz</Item>
+ <Item>clazz</Item>
+ </Issue>
+ </Message>
+ <Message Id="clazz*1000" TypeName="OperationsShouldNotOverflow" Category="Microsoft.Usage" CheckId="CA2233" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>clazz*1000</Item>
+ <Item>MethodBodyDecoderRegistry.Get(Int32, Int32):AMQMethodBody</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="ProtocolInitiation">
+ <Members>
+ <Member Name=".cctor()">
+ <Messages>
+ <Message TypeName="InitializeReferenceTypeStaticFieldsInline" Category="Microsoft.Performance" CheckId="CA1810" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Qpid.Framing.ProtocolInitiation</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name=".ctor()">
+ <Messages>
+ <Message TypeName="DoNotInitializeUnnecessarily" Category="Microsoft.Performance" CheckId="CA1805" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>ProtocolInitiation.ProtocolInitiation()</Item>
+ <Item>ProtocolMinor</Item>
+ <Item>System.Byte</Item>
+ <Item>0</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="CURRENT_PROTOCOL_VERSION_MAJOR">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>CURRENT_PROTOCOL_VERSION_MAJOR</Item>
+ </Issue>
+ </Message>
+ <Message TypeName="NonConstantFieldsShouldNotBeVisible" Category="Microsoft.Usage" CheckId="CA2211" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>CURRENT_PROTOCOL_VERSION_MAJOR</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Header">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Header</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="PopulateFromBuffer(Qpid.Buffer.ByteBuffer):System.Void">
+ <Messages>
+ <Message Id="Qpid.AMQException.#ctor(System.String)" TypeName="DoNotPassLiteralsAsLocalizedParameters" Category="Microsoft.Globalization" CheckId="CA1303" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>ProtocolInitiation.PopulateFromBuffer(ByteBuffer):Void</Item>
+ <Item>1</Item>
+ <Item>AMQException.AMQException(String)</Item>
+ <Item>Method not implemented</Item>
+ </Issue>
+ </Message>
+ <Message TypeName="MarkMembersAsStatic" Category="Microsoft.Performance" CheckId="CA1822" Created="2006-12-04 13:11:47Z" FixCategory="Breaking">
+ <Issue>
+ <Item>ProtocolInitiation.PopulateFromBuffer(ByteBuffer):Void</Item>
+ </Issue>
+ </Message>
+ <Message Id="buffer" TypeName="ReviewUnusedParameters" Category="Microsoft.Usage" CheckId="CA1801" Created="2006-12-04 13:11:47Z" FixCategory="Breaking">
+ <Issue>
+ <Item>buffer</Item>
+ <Item>ProtocolInitiation.PopulateFromBuffer(ByteBuffer):Void</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="ProtocolClass">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>ProtocolClass</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="ProtocolInstance">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>ProtocolInstance</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="ProtocolMajor">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>ProtocolMajor</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="ProtocolMinor">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>ProtocolMinor</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="ToString():System.String">
+ <Messages>
+ <Message Id="System.String.Format(System.String,System.Object[])" TypeName="SpecifyIFormatProvider" Category="Microsoft.Globalization" CheckId="CA1305" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>ProtocolInitiation.ToString():String</Item>
+ <Item>System.String.Format(System.String,System.Object[])</Item>
+ <Item>System.String.Format(System.IFormatProvider,System.String,System.Object[])</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="WritePayload(Qpid.Buffer.ByteBuffer):System.Void">
+ <Messages>
+ <Message TypeName="ValidateArgumentsOfPublicMethods" Category="Microsoft.Design" CheckId="CA1062" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>'buffer'</Item>
+ <Item>ProtocolInitiation.WritePayload(ByteBuffer):Void</Item>
+ </Issue>
+ <Issue>
+ <Item>'buffer'</Item>
+ <Item>ProtocolInitiation.WritePayload(ByteBuffer):Void</Item>
+ </Issue>
+ <Issue>
+ <Item>'buffer'</Item>
+ <Item>ProtocolInitiation.WritePayload(ByteBuffer):Void</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="ProtocolInitiation+Decoder">
+ <Messages>
+ <Message TypeName="NestedTypesShouldNotBeVisible" Category="Microsoft.Design" CheckId="CA1034" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Qpid.Framing.ProtocolInitiation+Decoder</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ <Members>
+ <Member Name=".ctor()">
+ <Messages>
+ <Message TypeName="DoNotInitializeUnnecessarily" Category="Microsoft.Performance" CheckId="CA1805" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Decoder.Decoder()</Item>
+ <Item>_disabled</Item>
+ <Item>System.Boolean</Item>
+ <Item>false</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Decodable(Qpid.Buffer.ByteBuffer):Qpid.Codec.Demux.MessageDecoderResult">
+ <Messages>
+ <Message Id="0#" TypeName="ParameterNamesShouldMatchBaseDeclaration" Category="Microsoft.Naming" CheckId="CA1725" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>inbuf</Item>
+ <Item>Decoder.Decodable(ByteBuffer):MessageDecoderResult</Item>
+ <Item>buffer</Item>
+ <Item>IMessageDecoder.Decodable(ByteBuffer):MessageDecoderResult</Item>
+ </Issue>
+ </Message>
+ <Message TypeName="ValidateArgumentsOfPublicMethods" Category="Microsoft.Design" CheckId="CA1062" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>'inbuf'</Item>
+ <Item>Decoder.Decodable(ByteBuffer):MessageDecoderResult</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Decode(Qpid.Buffer.ByteBuffer,Qpid.Codec.IProtocolDecoderOutput):Qpid.Codec.Demux.MessageDecoderResult">
+ <Messages>
+ <Message Id="0#" TypeName="ParameterNamesShouldMatchBaseDeclaration" Category="Microsoft.Naming" CheckId="CA1725" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>inbuf</Item>
+ <Item>Decoder.Decode(ByteBuffer, IProtocolDecoderOutput):MessageDecoderResult</Item>
+ <Item>buffer</Item>
+ <Item>IMessageDecoder.Decode(ByteBuffer, IProtocolDecoderOutput):MessageDecoderResult</Item>
+ </Issue>
+ </Message>
+ <Message TypeName="ValidateArgumentsOfPublicMethods" Category="Microsoft.Design" CheckId="CA1062" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>'inbuf'</Item>
+ <Item>Decoder.Decode(ByteBuffer, IProtocolDecoderOutput):MessageDecoderResult</Item>
+ </Issue>
+ <Issue>
+ <Item>'output'</Item>
+ <Item>Decoder.Decode(ByteBuffer, IProtocolDecoderOutput):MessageDecoderResult</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Disabled">
+ <Messages>
+ <Message TypeName="PropertiesShouldNotBeWriteOnly" Category="Microsoft.Design" CheckId="CA1044" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Disabled</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="QueueBindBody">
+ <Members>
+ <Member Name="Arguments">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Arguments</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="CLASS_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>QueueBindBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>QueueBindBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="CreateAMQFrame(System.UInt16,System.UInt16,System.String,System.String,System.String,System.Boolean,Qpid.Framing.FieldTable):Qpid.Framing.AMQFrame">
+ <Messages>
+ <Message Id="1#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>Ticket</Item>
+ </Issue>
+ </Message>
+ <Message Id="2#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>Queue</Item>
+ </Issue>
+ </Message>
+ <Message Id="3#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>Exchange</Item>
+ </Issue>
+ </Message>
+ <Message Id="4#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>RoutingKey</Item>
+ </Issue>
+ </Message>
+ <Message Id="5#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>Nowait</Item>
+ </Issue>
+ </Message>
+ <Message Id="6#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>Arguments</Item>
+ </Issue>
+ </Message>
+ <Message Id="5#Nowait" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>QueueBindBody.CreateAMQFrame(UInt16, UInt16, String, String, String, Boolean, FieldTable):AMQFrame</Item>
+ <Item>Nowait</Item>
+ <Item>Nowait</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>QueueBindBody.CreateAMQFrame(UInt16, UInt16, String, String, String, Boolean, FieldTable):AMQFrame</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Exchange">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Exchange</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="METHOD_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>QueueBindBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>QueueBindBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Nowait">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Nowait</Item>
+ </Issue>
+ </Message>
+ <Message Id="Nowait" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>Nowait</Item>
+ <Item>QueueBindBody.Nowait</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Queue">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Queue</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="RoutingKey">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>RoutingKey</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Ticket">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Ticket</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="QueueBindOkBody">
+ <Members>
+ <Member Name="CLASS_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>QueueBindOkBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>QueueBindOkBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="CreateAMQFrame(System.UInt16):Qpid.Framing.AMQFrame">
+ <Messages>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>QueueBindOkBody.CreateAMQFrame(UInt16):AMQFrame</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="METHOD_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>QueueBindOkBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>QueueBindOkBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="QueueDeclareBody">
+ <Members>
+ <Member Name="Arguments">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Arguments</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="AutoDelete">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>AutoDelete</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="CLASS_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>QueueDeclareBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>QueueDeclareBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="CreateAMQFrame(System.UInt16,System.UInt16,System.String,System.Boolean,System.Boolean,System.Boolean,System.Boolean,System.Boolean,Qpid.Framing.FieldTable):Qpid.Framing.AMQFrame">
+ <Messages>
+ <Message Id="1#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>Ticket</Item>
+ </Issue>
+ </Message>
+ <Message Id="2#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>Queue</Item>
+ </Issue>
+ </Message>
+ <Message Id="3#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>Passive</Item>
+ </Issue>
+ </Message>
+ <Message Id="4#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>Durable</Item>
+ </Issue>
+ </Message>
+ <Message Id="5#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>Exclusive</Item>
+ </Issue>
+ </Message>
+ <Message Id="6#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>AutoDelete</Item>
+ </Issue>
+ </Message>
+ <Message Id="7#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>Nowait</Item>
+ </Issue>
+ </Message>
+ <Message Id="8#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>Arguments</Item>
+ </Issue>
+ </Message>
+ <Message Id="7#Nowait" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>QueueDeclareBody.CreateAMQFrame(UInt16, UInt16, String, Boolean, Boolean, Boolean, Boolean, Boolean, FieldTable):AMQFrame</Item>
+ <Item>Nowait</Item>
+ <Item>Nowait</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>QueueDeclareBody.CreateAMQFrame(UInt16, UInt16, String, Boolean, Boolean, Boolean, Boolean, Boolean, FieldTable):AMQFrame</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Durable">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Durable</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Exclusive">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Exclusive</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="METHOD_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>QueueDeclareBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>QueueDeclareBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Nowait">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Nowait</Item>
+ </Issue>
+ </Message>
+ <Message Id="Nowait" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>Nowait</Item>
+ <Item>QueueDeclareBody.Nowait</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Passive">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Passive</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Queue">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Queue</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Ticket">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Ticket</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="QueueDeclareOkBody">
+ <Members>
+ <Member Name="CLASS_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>QueueDeclareOkBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>QueueDeclareOkBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="ConsumerCount">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>ConsumerCount</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="CreateAMQFrame(System.UInt16,System.String,System.UInt32,System.UInt32):Qpid.Framing.AMQFrame">
+ <Messages>
+ <Message Id="1#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>Queue</Item>
+ </Issue>
+ </Message>
+ <Message Id="2#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>MessageCount</Item>
+ </Issue>
+ </Message>
+ <Message Id="3#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>ConsumerCount</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>QueueDeclareOkBody.CreateAMQFrame(UInt16, String, UInt32, UInt32):AMQFrame</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="MessageCount">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>MessageCount</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="METHOD_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>QueueDeclareOkBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>QueueDeclareOkBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Queue">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Queue</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="QueueDeleteBody">
+ <Members>
+ <Member Name="CLASS_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>QueueDeleteBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>QueueDeleteBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="CreateAMQFrame(System.UInt16,System.UInt16,System.String,System.Boolean,System.Boolean,System.Boolean):Qpid.Framing.AMQFrame">
+ <Messages>
+ <Message Id="1#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>Ticket</Item>
+ </Issue>
+ </Message>
+ <Message Id="2#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>Queue</Item>
+ </Issue>
+ </Message>
+ <Message Id="3#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>IfUnused</Item>
+ </Issue>
+ </Message>
+ <Message Id="4#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>IfEmpty</Item>
+ </Issue>
+ </Message>
+ <Message Id="5#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>Nowait</Item>
+ </Issue>
+ </Message>
+ <Message Id="5#Nowait" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>QueueDeleteBody.CreateAMQFrame(UInt16, UInt16, String, Boolean, Boolean, Boolean):AMQFrame</Item>
+ <Item>Nowait</Item>
+ <Item>Nowait</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>QueueDeleteBody.CreateAMQFrame(UInt16, UInt16, String, Boolean, Boolean, Boolean):AMQFrame</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="IfEmpty">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>IfEmpty</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="IfUnused">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>IfUnused</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="METHOD_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>QueueDeleteBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>QueueDeleteBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Nowait">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Nowait</Item>
+ </Issue>
+ </Message>
+ <Message Id="Nowait" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>Nowait</Item>
+ <Item>QueueDeleteBody.Nowait</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Queue">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Queue</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Ticket">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Ticket</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="QueueDeleteOkBody">
+ <Members>
+ <Member Name="CLASS_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>QueueDeleteOkBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>QueueDeleteOkBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="CreateAMQFrame(System.UInt16,System.UInt32):Qpid.Framing.AMQFrame">
+ <Messages>
+ <Message Id="1#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>MessageCount</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>QueueDeleteOkBody.CreateAMQFrame(UInt16, UInt32):AMQFrame</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="MessageCount">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>MessageCount</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="METHOD_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>QueueDeleteOkBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>QueueDeleteOkBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="QueuePurgeBody">
+ <Members>
+ <Member Name="CLASS_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>QueuePurgeBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>QueuePurgeBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="CreateAMQFrame(System.UInt16,System.UInt16,System.String,System.Boolean):Qpid.Framing.AMQFrame">
+ <Messages>
+ <Message Id="1#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>Ticket</Item>
+ </Issue>
+ </Message>
+ <Message Id="2#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>Queue</Item>
+ </Issue>
+ </Message>
+ <Message Id="3#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>Nowait</Item>
+ </Issue>
+ </Message>
+ <Message Id="3#Nowait" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>QueuePurgeBody.CreateAMQFrame(UInt16, UInt16, String, Boolean):AMQFrame</Item>
+ <Item>Nowait</Item>
+ <Item>Nowait</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>QueuePurgeBody.CreateAMQFrame(UInt16, UInt16, String, Boolean):AMQFrame</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="METHOD_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>QueuePurgeBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>QueuePurgeBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Nowait">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Nowait</Item>
+ </Issue>
+ </Message>
+ <Message Id="Nowait" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>Nowait</Item>
+ <Item>QueuePurgeBody.Nowait</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Queue">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Queue</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Ticket">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Ticket</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="QueuePurgeOkBody">
+ <Members>
+ <Member Name="CLASS_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>QueuePurgeOkBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>QueuePurgeOkBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="CreateAMQFrame(System.UInt16,System.UInt32):Qpid.Framing.AMQFrame">
+ <Messages>
+ <Message Id="1#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>MessageCount</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>QueuePurgeOkBody.CreateAMQFrame(UInt16, UInt32):AMQFrame</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="MessageCount">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>MessageCount</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="METHOD_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>QueuePurgeOkBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>QueuePurgeOkBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="StreamCancelBody">
+ <Members>
+ <Member Name="CLASS_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>StreamCancelBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>StreamCancelBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="ConsumerTag">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>ConsumerTag</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="CreateAMQFrame(System.UInt16,System.String,System.Boolean):Qpid.Framing.AMQFrame">
+ <Messages>
+ <Message Id="1#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>ConsumerTag</Item>
+ </Issue>
+ </Message>
+ <Message Id="2#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>Nowait</Item>
+ </Issue>
+ </Message>
+ <Message Id="2#Nowait" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>StreamCancelBody.CreateAMQFrame(UInt16, String, Boolean):AMQFrame</Item>
+ <Item>Nowait</Item>
+ <Item>Nowait</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>StreamCancelBody.CreateAMQFrame(UInt16, String, Boolean):AMQFrame</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="METHOD_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>StreamCancelBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>StreamCancelBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Nowait">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Nowait</Item>
+ </Issue>
+ </Message>
+ <Message Id="Nowait" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>Nowait</Item>
+ <Item>StreamCancelBody.Nowait</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="StreamCancelOkBody">
+ <Members>
+ <Member Name="CLASS_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>StreamCancelOkBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>StreamCancelOkBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="ConsumerTag">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>ConsumerTag</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="CreateAMQFrame(System.UInt16,System.String):Qpid.Framing.AMQFrame">
+ <Messages>
+ <Message Id="1#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>ConsumerTag</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>StreamCancelOkBody.CreateAMQFrame(UInt16, String):AMQFrame</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="METHOD_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>StreamCancelOkBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>StreamCancelOkBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="StreamConsumeBody">
+ <Members>
+ <Member Name="CLASS_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>StreamConsumeBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>StreamConsumeBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="ConsumerTag">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>ConsumerTag</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="CreateAMQFrame(System.UInt16,System.UInt16,System.String,System.String,System.Boolean,System.Boolean,System.Boolean):Qpid.Framing.AMQFrame">
+ <Messages>
+ <Message Id="1#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>Ticket</Item>
+ </Issue>
+ </Message>
+ <Message Id="2#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>Queue</Item>
+ </Issue>
+ </Message>
+ <Message Id="3#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>ConsumerTag</Item>
+ </Issue>
+ </Message>
+ <Message Id="4#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>NoLocal</Item>
+ </Issue>
+ </Message>
+ <Message Id="5#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>Exclusive</Item>
+ </Issue>
+ </Message>
+ <Message Id="6#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>Nowait</Item>
+ </Issue>
+ </Message>
+ <Message Id="6#Nowait" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>StreamConsumeBody.CreateAMQFrame(UInt16, UInt16, String, String, Boolean, Boolean, Boolean):AMQFrame</Item>
+ <Item>Nowait</Item>
+ <Item>Nowait</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>StreamConsumeBody.CreateAMQFrame(UInt16, UInt16, String, String, Boolean, Boolean, Boolean):AMQFrame</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Exclusive">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Exclusive</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="METHOD_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>StreamConsumeBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>StreamConsumeBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="NoLocal">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>NoLocal</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Nowait">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Nowait</Item>
+ </Issue>
+ </Message>
+ <Message Id="Nowait" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>Nowait</Item>
+ <Item>StreamConsumeBody.Nowait</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Queue">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Queue</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Ticket">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Ticket</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="StreamConsumeOkBody">
+ <Members>
+ <Member Name="CLASS_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>StreamConsumeOkBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>StreamConsumeOkBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="ConsumerTag">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>ConsumerTag</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="CreateAMQFrame(System.UInt16,System.String):Qpid.Framing.AMQFrame">
+ <Messages>
+ <Message Id="1#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>ConsumerTag</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>StreamConsumeOkBody.CreateAMQFrame(UInt16, String):AMQFrame</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="METHOD_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>StreamConsumeOkBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>StreamConsumeOkBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="StreamDeliverBody">
+ <Members>
+ <Member Name="CLASS_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>StreamDeliverBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>StreamDeliverBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="ConsumerTag">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>ConsumerTag</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="CreateAMQFrame(System.UInt16,System.String,System.UInt64,System.String,System.String):Qpid.Framing.AMQFrame">
+ <Messages>
+ <Message Id="1#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>ConsumerTag</Item>
+ </Issue>
+ </Message>
+ <Message Id="2#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>DeliveryTag</Item>
+ </Issue>
+ </Message>
+ <Message Id="3#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>Exchange</Item>
+ </Issue>
+ </Message>
+ <Message Id="4#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>Queue</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>StreamDeliverBody.CreateAMQFrame(UInt16, String, UInt64, String, String):AMQFrame</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="DeliveryTag">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>DeliveryTag</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Exchange">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Exchange</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="METHOD_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>StreamDeliverBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>StreamDeliverBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Queue">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Queue</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="StreamPublishBody">
+ <Members>
+ <Member Name="CLASS_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>StreamPublishBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>StreamPublishBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="CreateAMQFrame(System.UInt16,System.UInt16,System.String,System.String,System.Boolean,System.Boolean):Qpid.Framing.AMQFrame">
+ <Messages>
+ <Message Id="1#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>Ticket</Item>
+ </Issue>
+ </Message>
+ <Message Id="2#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>Exchange</Item>
+ </Issue>
+ </Message>
+ <Message Id="3#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>RoutingKey</Item>
+ </Issue>
+ </Message>
+ <Message Id="4#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>Mandatory</Item>
+ </Issue>
+ </Message>
+ <Message Id="5#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>Immediate</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>StreamPublishBody.CreateAMQFrame(UInt16, UInt16, String, String, Boolean, Boolean):AMQFrame</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Exchange">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Exchange</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Immediate">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Immediate</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Mandatory">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Mandatory</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="METHOD_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>StreamPublishBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>StreamPublishBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="RoutingKey">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>RoutingKey</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Ticket">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Ticket</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="StreamQosBody">
+ <Messages>
+ <Message Id="Qos" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Type">
+ <Item>Qos</Item>
+ <Item>Qpid.Framing.StreamQosBody</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ <Members>
+ <Member Name="CLASS_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>StreamQosBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>StreamQosBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="ConsumeRate">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>ConsumeRate</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="CreateAMQFrame(System.UInt16,System.UInt32,System.UInt16,System.UInt32,System.Boolean):Qpid.Framing.AMQFrame">
+ <Messages>
+ <Message Id="1#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>PrefetchSize</Item>
+ </Issue>
+ </Message>
+ <Message Id="2#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>PrefetchCount</Item>
+ </Issue>
+ </Message>
+ <Message Id="3#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>ConsumeRate</Item>
+ </Issue>
+ </Message>
+ <Message Id="4#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>Global</Item>
+ </Issue>
+ </Message>
+ <Message Id="1#Prefetch" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>StreamQosBody.CreateAMQFrame(UInt16, UInt32, UInt16, UInt32, Boolean):AMQFrame</Item>
+ <Item>Prefetch</Item>
+ <Item>PrefetchSize</Item>
+ </Issue>
+ </Message>
+ <Message Id="2#Prefetch" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>StreamQosBody.CreateAMQFrame(UInt16, UInt32, UInt16, UInt32, Boolean):AMQFrame</Item>
+ <Item>Prefetch</Item>
+ <Item>PrefetchCount</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>StreamQosBody.CreateAMQFrame(UInt16, UInt32, UInt16, UInt32, Boolean):AMQFrame</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Global">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Global</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="METHOD_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>StreamQosBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>StreamQosBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="PrefetchCount">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>PrefetchCount</Item>
+ </Issue>
+ </Message>
+ <Message Id="Prefetch" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>Prefetch</Item>
+ <Item>StreamQosBody.PrefetchCount</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="PrefetchSize">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>PrefetchSize</Item>
+ </Issue>
+ </Message>
+ <Message Id="Prefetch" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>Prefetch</Item>
+ <Item>StreamQosBody.PrefetchSize</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="StreamQosOkBody">
+ <Messages>
+ <Message Id="Qos" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Type">
+ <Item>Qos</Item>
+ <Item>Qpid.Framing.StreamQosOkBody</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ <Members>
+ <Member Name="CLASS_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>StreamQosOkBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>StreamQosOkBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="CreateAMQFrame(System.UInt16):Qpid.Framing.AMQFrame">
+ <Messages>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>StreamQosOkBody.CreateAMQFrame(UInt16):AMQFrame</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="METHOD_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>StreamQosOkBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>StreamQosOkBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="StreamReturnBody">
+ <Members>
+ <Member Name="CLASS_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>StreamReturnBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>StreamReturnBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="CreateAMQFrame(System.UInt16,System.UInt16,System.String,System.String,System.String):Qpid.Framing.AMQFrame">
+ <Messages>
+ <Message Id="1#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>ReplyCode</Item>
+ </Issue>
+ </Message>
+ <Message Id="2#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>ReplyText</Item>
+ </Issue>
+ </Message>
+ <Message Id="3#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>Exchange</Item>
+ </Issue>
+ </Message>
+ <Message Id="4#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>RoutingKey</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>StreamReturnBody.CreateAMQFrame(UInt16, UInt16, String, String, String):AMQFrame</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Exchange">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Exchange</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="METHOD_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>StreamReturnBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>StreamReturnBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="ReplyCode">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>ReplyCode</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="ReplyText">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>ReplyText</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="RoutingKey">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>RoutingKey</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="TestContentBody">
+ <Members>
+ <Member Name="CLASS_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>TestContentBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>TestContentBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="CreateAMQFrame(System.UInt16):Qpid.Framing.AMQFrame">
+ <Messages>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>TestContentBody.CreateAMQFrame(UInt16):AMQFrame</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="METHOD_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>TestContentBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>TestContentBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="TestContentOkBody">
+ <Members>
+ <Member Name="CLASS_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>TestContentOkBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>TestContentOkBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="ContentChecksum">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>ContentChecksum</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="CreateAMQFrame(System.UInt16,System.UInt32):Qpid.Framing.AMQFrame">
+ <Messages>
+ <Message Id="1#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>ContentChecksum</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>TestContentOkBody.CreateAMQFrame(UInt16, UInt32):AMQFrame</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="METHOD_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>TestContentOkBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>TestContentOkBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="TestIntegerBody">
+ <Members>
+ <Member Name="CLASS_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>TestIntegerBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>TestIntegerBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="CreateAMQFrame(System.UInt16,System.Byte,System.UInt16,System.UInt32,System.UInt64,System.Byte):Qpid.Framing.AMQFrame">
+ <Messages>
+ <Message Id="1#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>Integer1</Item>
+ </Issue>
+ </Message>
+ <Message Id="2#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>Integer2</Item>
+ </Issue>
+ </Message>
+ <Message Id="3#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>Integer3</Item>
+ </Issue>
+ </Message>
+ <Message Id="4#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>Integer4</Item>
+ </Issue>
+ </Message>
+ <Message Id="5#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>Operation</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>TestIntegerBody.CreateAMQFrame(UInt16, Byte, UInt16, UInt32, UInt64, Byte):AMQFrame</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Integer1">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Integer1</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Integer2">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Integer2</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Integer3">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Integer3</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Integer4">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Integer4</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="METHOD_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>TestIntegerBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>TestIntegerBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Operation">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Operation</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="TestIntegerOkBody">
+ <Members>
+ <Member Name="CLASS_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>TestIntegerOkBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>TestIntegerOkBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="CreateAMQFrame(System.UInt16,System.UInt64):Qpid.Framing.AMQFrame">
+ <Messages>
+ <Message Id="1#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>Result</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>TestIntegerOkBody.CreateAMQFrame(UInt16, UInt64):AMQFrame</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="METHOD_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>TestIntegerOkBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>TestIntegerOkBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Result">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Result</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="TestStringBody">
+ <Members>
+ <Member Name="CLASS_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>TestStringBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>TestStringBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="CreateAMQFrame(System.UInt16,System.String,System.Byte[],System.Byte):Qpid.Framing.AMQFrame">
+ <Messages>
+ <Message Id="1#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>String1</Item>
+ </Issue>
+ </Message>
+ <Message Id="2#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>String2</Item>
+ </Issue>
+ </Message>
+ <Message Id="3#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>Operation</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>TestStringBody.CreateAMQFrame(UInt16, String, Byte[], Byte):AMQFrame</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="METHOD_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>TestStringBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>TestStringBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Operation">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Operation</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="String1">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>String1</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="String2">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>String2</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="TestStringOkBody">
+ <Members>
+ <Member Name="CLASS_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>TestStringOkBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>TestStringOkBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="CreateAMQFrame(System.UInt16,System.Byte[]):Qpid.Framing.AMQFrame">
+ <Messages>
+ <Message Id="1#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>Result</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>TestStringOkBody.CreateAMQFrame(UInt16, Byte[]):AMQFrame</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="METHOD_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>TestStringOkBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>TestStringOkBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Result">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Result</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="TestTableBody">
+ <Members>
+ <Member Name="CLASS_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>TestTableBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>TestTableBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="CreateAMQFrame(System.UInt16,Qpid.Framing.FieldTable,System.Byte,System.Byte):Qpid.Framing.AMQFrame">
+ <Messages>
+ <Message Id="2#" TypeName="AvoidLanguageSpecificTypeNamesInParameters" Category="Microsoft.Naming" CheckId="CA1718" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>IntegerOp</Item>
+ </Issue>
+ </Message>
+ <Message Id="2#" TypeName="AvoidTypeNamesInParameters" Category="Microsoft.Naming" CheckId="CA1720" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>IntegerOp</Item>
+ </Issue>
+ </Message>
+ <Message Id="1#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>Table</Item>
+ </Issue>
+ </Message>
+ <Message Id="2#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>IntegerOp</Item>
+ </Issue>
+ </Message>
+ <Message Id="3#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>StringOp</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>TestTableBody.CreateAMQFrame(UInt16, FieldTable, Byte, Byte):AMQFrame</Item>
+ </Issue>
+ </Message>
+ <Message Id="2#" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>Op</Item>
+ <Item>IntegerOp</Item>
+ </Issue>
+ </Message>
+ <Message Id="3#" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>Op</Item>
+ <Item>StringOp</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="IntegerOp">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>IntegerOp</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="METHOD_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>TestTableBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>TestTableBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="StringOp">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>StringOp</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Table">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Table</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="TestTableOkBody">
+ <Members>
+ <Member Name="CLASS_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>TestTableOkBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>TestTableOkBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="CreateAMQFrame(System.UInt16,System.UInt64,System.Byte[]):Qpid.Framing.AMQFrame">
+ <Messages>
+ <Message Id="1#" TypeName="AvoidLanguageSpecificTypeNamesInParameters" Category="Microsoft.Naming" CheckId="CA1718" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>IntegerResult</Item>
+ </Issue>
+ </Message>
+ <Message Id="1#" TypeName="AvoidTypeNamesInParameters" Category="Microsoft.Naming" CheckId="CA1720" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>IntegerResult</Item>
+ </Issue>
+ </Message>
+ <Message Id="1#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>IntegerResult</Item>
+ </Issue>
+ </Message>
+ <Message Id="2#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>StringResult</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>TestTableOkBody.CreateAMQFrame(UInt16, UInt64, Byte[]):AMQFrame</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="IntegerResult">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>IntegerResult</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="METHOD_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>TestTableOkBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>TestTableOkBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="StringResult">
+ <Messages>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>StringResult</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="TunnelRequestBody">
+ <Members>
+ <Member Name="CLASS_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>TunnelRequestBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>TunnelRequestBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="CreateAMQFrame(System.UInt16,Qpid.Framing.FieldTable):Qpid.Framing.AMQFrame">
+ <Messages>
+ <Message Id="MetaData" TypeName="CompoundWordsShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1702" Created="2006-12-04 13:11:47Z">
+ <Issue Name="ShouldBeDiscreteTerm">
+ <Item>MetaData</Item>
+ <Item>parameter</Item>
+ <Item>MetaData</Item>
+ <Item>Metadata</Item>
+ </Issue>
+ </Message>
+ <Message Id="1#" TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>MetaData</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>TunnelRequestBody.CreateAMQFrame(UInt16, FieldTable):AMQFrame</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="MetaData">
+ <Messages>
+ <Message Id="MetaData" TypeName="CompoundWordsShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1702" Created="2006-12-04 13:11:47Z">
+ <Issue Name="ShouldBeDiscreteTerm">
+ <Item>MetaData</Item>
+ <Item>field</Item>
+ <Item>MetaData</Item>
+ <Item>Metadata</Item>
+ </Issue>
+ </Message>
+ <Message TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>MetaData</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="METHOD_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>TunnelRequestBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>TunnelRequestBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="TxCommitBody">
+ <Messages>
+ <Message TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Type">
+ <Item>Tx</Item>
+ <Item>Qpid.Framing.TxCommitBody</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ <Members>
+ <Member Name="CLASS_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>TxCommitBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>TxCommitBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="CreateAMQFrame(System.UInt16):Qpid.Framing.AMQFrame">
+ <Messages>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>TxCommitBody.CreateAMQFrame(UInt16):AMQFrame</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="METHOD_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>TxCommitBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>TxCommitBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="TxCommitOkBody">
+ <Messages>
+ <Message TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Type">
+ <Item>Tx</Item>
+ <Item>Qpid.Framing.TxCommitOkBody</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ <Members>
+ <Member Name="CLASS_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>TxCommitOkBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>TxCommitOkBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="CreateAMQFrame(System.UInt16):Qpid.Framing.AMQFrame">
+ <Messages>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>TxCommitOkBody.CreateAMQFrame(UInt16):AMQFrame</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="METHOD_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>TxCommitOkBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>TxCommitOkBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="TxRollbackBody">
+ <Messages>
+ <Message TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Type">
+ <Item>Tx</Item>
+ <Item>Qpid.Framing.TxRollbackBody</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ <Members>
+ <Member Name="CLASS_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>TxRollbackBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>TxRollbackBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="CreateAMQFrame(System.UInt16):Qpid.Framing.AMQFrame">
+ <Messages>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>TxRollbackBody.CreateAMQFrame(UInt16):AMQFrame</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="METHOD_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>TxRollbackBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>TxRollbackBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="TxRollbackOkBody">
+ <Messages>
+ <Message TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Type">
+ <Item>Tx</Item>
+ <Item>Qpid.Framing.TxRollbackOkBody</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ <Members>
+ <Member Name="CLASS_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>TxRollbackOkBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>TxRollbackOkBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="CreateAMQFrame(System.UInt16):Qpid.Framing.AMQFrame">
+ <Messages>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>TxRollbackOkBody.CreateAMQFrame(UInt16):AMQFrame</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="METHOD_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>TxRollbackOkBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>TxRollbackOkBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="TxSelectBody">
+ <Messages>
+ <Message TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Type">
+ <Item>Tx</Item>
+ <Item>Qpid.Framing.TxSelectBody</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ <Members>
+ <Member Name="CLASS_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>TxSelectBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>TxSelectBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="CreateAMQFrame(System.UInt16):Qpid.Framing.AMQFrame">
+ <Messages>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>TxSelectBody.CreateAMQFrame(UInt16):AMQFrame</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="METHOD_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>TxSelectBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>TxSelectBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="TxSelectOkBody">
+ <Messages>
+ <Message TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Type">
+ <Item>Tx</Item>
+ <Item>Qpid.Framing.TxSelectOkBody</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ <Members>
+ <Member Name="CLASS_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>TxSelectOkBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>TxSelectOkBody.CLASS_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="CreateAMQFrame(System.UInt16):Qpid.Framing.AMQFrame">
+ <Messages>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>TxSelectOkBody.CreateAMQFrame(UInt16):AMQFrame</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="METHOD_ID">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>TxSelectOkBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>TxSelectOkBody.METHOD_ID</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ </Types>
+ </Namespace>
+ </Namespaces>
+ </Module>
+ </Modules>
+ </Target>
+ <Target Name="$(ProjectDir)/Qpid.Client.Tests/bin/Debug/Qpid.Messaging.dll">
+ <Modules>
+ <Module Name="qpid.messaging.dll">
+ <Messages>
+ <Message TypeName="AssembliesShouldDeclareMinimumSecurity" Category="Microsoft.Usage" CheckId="CA2209" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Qpid.Messaging</Item>
+ </Issue>
+ </Message>
+ <Message TypeName="AssembliesShouldHaveValidStrongNames" Category="Microsoft.Design" CheckId="CA2210" Created="2006-12-04 13:11:47Z">
+ <Issue Name="NoStrongName">
+ <Item>Qpid.Messaging</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ <Namespaces>
+ <Namespace Name="Qpid.Messaging">
+ <Types>
+ <Type Name="AcknowledgeMode">
+ <Members>
+ <Member Name="DupsOkAcknowledge">
+ <Messages>
+ <Message Id="Dups" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>Dups</Item>
+ <Item>AcknowledgeMode.DupsOkAcknowledge</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="ChannelLimitReachedException">
+ <Messages>
+ <Message TypeName="ImplementStandardExceptionConstructors" Category="Microsoft.Design" CheckId="CA1032" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Qpid.Messaging.ChannelLimitReachedException</Item>
+ <Item>protected ChannelLimitReachedException(SerializationInfo, StreamingContext)</Item>
+ </Issue>
+ <Issue>
+ <Item>Qpid.Messaging.ChannelLimitReachedException</Item>
+ <Item>public ChannelLimitReachedException()</Item>
+ </Issue>
+ <Issue>
+ <Item>Qpid.Messaging.ChannelLimitReachedException</Item>
+ <Item>public ChannelLimitReachedException(String)</Item>
+ </Issue>
+ <Issue>
+ <Item>Qpid.Messaging.ChannelLimitReachedException</Item>
+ <Item>public ChannelLimitReachedException(String, Exception)</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Type>
+ <Type Name="ExceptionListenerDelegate">
+ <Messages>
+ <Message TypeName="IdentifiersShouldNotHaveIncorrectSuffix" Category="Microsoft.Naming" CheckId="CA1711" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Qpid.Messaging.ExceptionListenerDelegate</Item>
+ <Item>Delegate</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Type>
+ <Type Name="ExchangeClassConstants">
+ <Members>
+ <Member Name="DIRECT">
+ <Messages>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>ExchangeClassConstants.DIRECT</Item>
+ </Issue>
+ </Message>
+ <Message TypeName="UseLiteralsWhereAppropriate" Category="Microsoft.Performance" CheckId="CA1802" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>DIRECT</Item>
+ <Item>direct</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="HEADERS">
+ <Messages>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>ExchangeClassConstants.HEADERS</Item>
+ </Issue>
+ </Message>
+ <Message TypeName="UseLiteralsWhereAppropriate" Category="Microsoft.Performance" CheckId="CA1802" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>HEADERS</Item>
+ <Item>headers</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="TOPIC">
+ <Messages>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>ExchangeClassConstants.TOPIC</Item>
+ </Issue>
+ </Message>
+ <Message TypeName="UseLiteralsWhereAppropriate" Category="Microsoft.Performance" CheckId="CA1802" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>TOPIC</Item>
+ <Item>topic</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="ExchangeNameDefaults">
+ <Members>
+ <Member Name="DIRECT">
+ <Messages>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>ExchangeNameDefaults.DIRECT</Item>
+ </Issue>
+ </Message>
+ <Message TypeName="UseLiteralsWhereAppropriate" Category="Microsoft.Performance" CheckId="CA1802" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>DIRECT</Item>
+ <Item>amq.direct</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="HEADERS">
+ <Messages>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>ExchangeNameDefaults.HEADERS</Item>
+ </Issue>
+ </Message>
+ <Message TypeName="UseLiteralsWhereAppropriate" Category="Microsoft.Performance" CheckId="CA1802" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>HEADERS</Item>
+ <Item>amq.match</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="TOPIC">
+ <Messages>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>ExchangeNameDefaults.TOPIC</Item>
+ </Issue>
+ </Message>
+ <Message TypeName="UseLiteralsWhereAppropriate" Category="Microsoft.Performance" CheckId="CA1802" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>TOPIC</Item>
+ <Item>amq.topic</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="IBytesMessage">
+ <Members>
+ <Member Name="ReadUTF():System.String">
+ <Messages>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>IBytesMessage.ReadUTF():String</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="WriteUTF(System.String):System.Void">
+ <Messages>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>IBytesMessage.WriteUTF(String):Void</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="IChannel">
+ <Members>
+ <Member Name="CreateConsumer(System.String,System.Int32,System.Int32,System.Boolean,System.Boolean,System.Boolean,System.String):Qpid.Messaging.IMessageConsumer">
+ <Messages>
+ <Message Id="1#prefetch" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>IChannel.CreateConsumer(String, Int32, Int32, Boolean, Boolean, Boolean, String):IMessageConsumer</Item>
+ <Item>prefetch</Item>
+ <Item>prefetchLow</Item>
+ </Issue>
+ </Message>
+ <Message Id="2#prefetch" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>IChannel.CreateConsumer(String, Int32, Int32, Boolean, Boolean, Boolean, String):IMessageConsumer</Item>
+ <Item>prefetch</Item>
+ <Item>prefetchHigh</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="DefaultPrefetch">
+ <Messages>
+ <Message Id="Prefetch" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>Prefetch</Item>
+ <Item>IChannel.DefaultPrefetch:Int32</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="IConnection">
+ <Members>
+ <Member Name="ClientID">
+ <Messages>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>IConnection.ClientID:String</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="CreateChannel(System.Boolean,Qpid.Messaging.AcknowledgeMode,System.Int32):Qpid.Messaging.IChannel">
+ <Messages>
+ <Message Id="2#prefetch" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>IConnection.CreateChannel(Boolean, AcknowledgeMode, Int32):IChannel</Item>
+ <Item>prefetch</Item>
+ <Item>prefetch</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="IConnectionListener">
+ <Members>
+ <Member Name="PreResubscribe():System.Boolean">
+ <Messages>
+ <Message Id="Resubscribe" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>Resubscribe</Item>
+ <Item>IConnectionListener.PreResubscribe():Boolean</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="IFieldTable">
+ <Messages>
+ <Message TypeName="IdentifiersShouldHaveCorrectSuffix" Category="Microsoft.Naming" CheckId="CA1710" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Qpid.Messaging.IFieldTable</Item>
+ <Item>Collection</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ <Members>
+ <Member Name="Contains(System.String):System.Boolean">
+ <Messages>
+ <Message Id="0#s" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="ParameterOneLetter">
+ <Item>IFieldTable.Contains(String):Boolean</Item>
+ <Item>s</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="IMessage">
+ <Members>
+ <Member Name="CorrelationIdAsBytes">
+ <Messages>
+ <Message TypeName="PropertiesShouldNotReturnArrays" Category="Microsoft.Performance" CheckId="CA1819" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>IMessage.CorrelationIdAsBytes:Byte[]</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="IMessagePublisher">
+ <Members>
+ <Member Name="DisableMessageID">
+ <Messages>
+ <Message Id="Member" TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706" Created="2006-12-04 13:11:47Z">
+ <Issue Name="MemberId">
+ <Item>IMessagePublisher.DisableMessageID:Boolean</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="Encoding">
+ <Messages>
+ <Message TypeName="PropertiesShouldNotBeWriteOnly" Category="Microsoft.Design" CheckId="CA1044" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Encoding</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="MimeType">
+ <Messages>
+ <Message TypeName="PropertiesShouldNotBeWriteOnly" Category="Microsoft.Design" CheckId="CA1044" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>MimeType</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="MessageConsumerBuilder">
+ <Members>
+ <Member Name=".ctor(Qpid.Messaging.IChannel,System.String)">
+ <Messages>
+ <Message TypeName="DoNotInitializeUnnecessarily" Category="Microsoft.Performance" CheckId="CA1805" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>MessageConsumerBuilder.MessageConsumerBuilder(IChannel, String)</Item>
+ <Item>_durable</Item>
+ <Item>System.Boolean</Item>
+ <Item>false</Item>
+ </Issue>
+ <Issue>
+ <Item>MessageConsumerBuilder.MessageConsumerBuilder(IChannel, String)</Item>
+ <Item>_exclusive</Item>
+ <Item>System.Boolean</Item>
+ <Item>false</Item>
+ </Issue>
+ <Issue>
+ <Item>MessageConsumerBuilder.MessageConsumerBuilder(IChannel, String)</Item>
+ <Item>_noLocal</Item>
+ <Item>System.Boolean</Item>
+ <Item>false</Item>
+ </Issue>
+ <Issue>
+ <Item>MessageConsumerBuilder.MessageConsumerBuilder(IChannel, String)</Item>
+ <Item>_subscriptionName</Item>
+ <Item>System.String</Item>
+ <Item>null</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="DEFAULT_PREFETCH_HIGH">
+ <Messages>
+ <Message Id="Member" TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>DEFAULT_PREFETCH_HIGH</Item>
+ </Issue>
+ </Message>
+ <Message Id="Member" TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>MessageConsumerBuilder.DEFAULT_PREFETCH_HIGH</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="WithPrefetchHigh(System.Int32):Qpid.Messaging.MessageConsumerBuilder">
+ <Messages>
+ <Message Id="0#prefetch" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>MessageConsumerBuilder.WithPrefetchHigh(Int32):MessageConsumerBuilder</Item>
+ <Item>prefetch</Item>
+ <Item>prefetchHigh</Item>
+ </Issue>
+ </Message>
+ <Message Id="Prefetch" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>Prefetch</Item>
+ <Item>MessageConsumerBuilder.WithPrefetchHigh(Int32):MessageConsumerBuilder</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ <Member Name="WithPrefetchLow(System.Int32):Qpid.Messaging.MessageConsumerBuilder">
+ <Messages>
+ <Message Id="0#prefetch" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Parameter">
+ <Item>MessageConsumerBuilder.WithPrefetchLow(Int32):MessageConsumerBuilder</Item>
+ <Item>prefetch</Item>
+ <Item>prefetchLow</Item>
+ </Issue>
+ </Message>
+ <Message Id="Prefetch" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Member">
+ <Item>Prefetch</Item>
+ <Item>MessageConsumerBuilder.WithPrefetchLow(Int32):MessageConsumerBuilder</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="MessageNotReadableException">
+ <Messages>
+ <Message TypeName="ImplementStandardExceptionConstructors" Category="Microsoft.Design" CheckId="CA1032" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Qpid.Messaging.MessageNotReadableException</Item>
+ <Item>protected MessageNotReadableException(SerializationInfo, StreamingContext)</Item>
+ </Issue>
+ <Issue>
+ <Item>Qpid.Messaging.MessageNotReadableException</Item>
+ <Item>public MessageNotReadableException()</Item>
+ </Issue>
+ <Issue>
+ <Item>Qpid.Messaging.MessageNotReadableException</Item>
+ <Item>public MessageNotReadableException(String, Exception)</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Type>
+ <Type Name="MessageNotWriteableException">
+ <Messages>
+ <Message TypeName="ImplementStandardExceptionConstructors" Category="Microsoft.Design" CheckId="CA1032" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Qpid.Messaging.MessageNotWriteableException</Item>
+ <Item>protected MessageNotWriteableException(SerializationInfo, StreamingContext)</Item>
+ </Issue>
+ <Issue>
+ <Item>Qpid.Messaging.MessageNotWriteableException</Item>
+ <Item>public MessageNotWriteableException()</Item>
+ </Issue>
+ <Issue>
+ <Item>Qpid.Messaging.MessageNotWriteableException</Item>
+ <Item>public MessageNotWriteableException(String, Exception)</Item>
+ </Issue>
+ </Message>
+ <Message Id="Writeable" TypeName="UsePreferredTerms" Category="Microsoft.Naming" CheckId="CA1726" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Type">
+ <Item>Writeable</Item>
+ <Item>MessageNotWriteableException</Item>
+ <Item>Writable</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Type>
+ <Type Name="MessagePublisherBuilder">
+ <Members>
+ <Member Name=".ctor(Qpid.Messaging.IChannel)">
+ <Messages>
+ <Message TypeName="DoNotInitializeUnnecessarily" Category="Microsoft.Performance" CheckId="CA1805" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>MessagePublisherBuilder.MessagePublisherBuilder(IChannel)</Item>
+ <Item>_exchangeName</Item>
+ <Item>System.String</Item>
+ <Item>null</Item>
+ </Issue>
+ <Issue>
+ <Item>MessagePublisherBuilder.MessagePublisherBuilder(IChannel)</Item>
+ <Item>_immediate</Item>
+ <Item>System.Boolean</Item>
+ <Item>false</Item>
+ </Issue>
+ <Issue>
+ <Item>MessagePublisherBuilder.MessagePublisherBuilder(IChannel)</Item>
+ <Item>_priority</Item>
+ <Item>System.Int32</Item>
+ <Item>0</Item>
+ </Issue>
+ <Issue>
+ <Item>MessagePublisherBuilder.MessagePublisherBuilder(IChannel)</Item>
+ <Item>_routingKey</Item>
+ <Item>System.String</Item>
+ <Item>null</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="MessageReceivedDelegate">
+ <Messages>
+ <Message TypeName="IdentifiersShouldNotHaveIncorrectSuffix" Category="Microsoft.Naming" CheckId="CA1711" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Qpid.Messaging.MessageReceivedDelegate</Item>
+ <Item>Delegate</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Type>
+ <Type Name="QpidException">
+ <Messages>
+ <Message Id="Qpid" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="Type">
+ <Item>Qpid</Item>
+ <Item>Qpid.Messaging.QpidException</Item>
+ </Issue>
+ </Message>
+ <Message TypeName="ImplementStandardExceptionConstructors" Category="Microsoft.Design" CheckId="CA1032" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Qpid.Messaging.QpidException</Item>
+ <Item>protected QpidException(SerializationInfo, StreamingContext)</Item>
+ </Issue>
+ <Issue>
+ <Item>Qpid.Messaging.QpidException</Item>
+ <Item>public QpidException()</Item>
+ </Issue>
+ </Message>
+ <Message TypeName="MarkISerializableTypesWithSerializable" Category="Microsoft.Usage" CheckId="CA2237" Created="2006-12-04 13:11:47Z">
+ <Issue Level="Error">
+ <Item>QpidException</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ <Members>
+ <Member Name=".ctor(System.String,System.Exception)">
+ <Messages>
+ <Message Id="1#e" TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704" Created="2006-12-04 13:11:47Z">
+ <Issue Name="ParameterOneLetter">
+ <Item>QpidException.QpidException(String, Exception)</Item>
+ <Item>e</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Member>
+ </Members>
+ </Type>
+ <Type Name="ResourceAllocationException">
+ <Messages>
+ <Message TypeName="ImplementStandardExceptionConstructors" Category="Microsoft.Design" CheckId="CA1032" Created="2006-12-04 13:11:47Z">
+ <Issue>
+ <Item>Qpid.Messaging.ResourceAllocationException</Item>
+ <Item>protected ResourceAllocationException(SerializationInfo, StreamingContext)</Item>
+ </Issue>
+ <Issue>
+ <Item>Qpid.Messaging.ResourceAllocationException</Item>
+ <Item>public ResourceAllocationException()</Item>
+ </Issue>
+ <Issue>
+ <Item>Qpid.Messaging.ResourceAllocationException</Item>
+ <Item>public ResourceAllocationException(String, Exception)</Item>
+ </Issue>
+ </Message>
+ </Messages>
+ </Type>
+ </Types>
+ </Namespace>
+ </Namespaces>
+ </Module>
+ </Modules>
+ </Target>
+ </Targets>
+ <Rules>
+ <Rule TypeName="AbstractTypesShouldNotHaveConstructors" Category="Microsoft.Design" CheckId="CA1012">
+ <Resolution Name="Default">Change the accessibility of all public constructors in '{0}' to protected.</Resolution>
+ </Rule>
+ <Rule TypeName="AssembliesShouldDeclareMinimumSecurity" Category="Microsoft.Usage" CheckId="CA2209">
+ <Resolution Name="Default">No valid permission requests were found for assembly '{0}'. You should always specify the minimum security permissions using SecurityAction.RequestMinimum.</Resolution>
+ </Rule>
+ <Rule TypeName="AssembliesShouldHaveValidStrongNames" Category="Microsoft.Design" CheckId="CA2210">
+ <Resolution Name="NoStrongName">Sign '{0}' with a strong name key.</Resolution>
+ </Rule>
+ <Rule TypeName="AvoidEmptyInterfaces" Category="Microsoft.Design" CheckId="CA1040">
+ <Resolution Name="Default">Define a custom attribute to replace '{0}'.</Resolution>
+ </Rule>
+ <Rule TypeName="AvoidLanguageSpecificTypeNamesInParameters" Category="Microsoft.Naming" CheckId="CA1718">
+ <Resolution Name="Default">Use a generic name for parameter '{0}'. If this is not possible, replace the type identifier with a universal type name.</Resolution>
+ </Rule>
+ <Rule TypeName="AvoidNamespacesWithFewTypes" Category="Microsoft.Design" CheckId="CA1020">
+ <Resolution Name="Default">Consider merging the types defined in '{0}' with another namespace.</Resolution>
+ </Rule>
+ <Rule TypeName="AvoidTypeNamesInParameters" Category="Microsoft.Naming" CheckId="CA1720">
+ <Resolution Name="Default">Remove the type identifier from parameter name '{0}'.</Resolution>
+ </Rule>
+ <Rule TypeName="AvoidUncalledPrivateCode" Category="Microsoft.Performance" CheckId="CA1811">
+ <Resolution Name="Default">'{0}' appears to have no upstream public or protected callers.</Resolution>
+ </Rule>
+ <Rule TypeName="AvoidUninstantiatedInternalClasses" Category="Microsoft.Performance" CheckId="CA1812">
+ <Resolution Name="Default">'{0}' is an internal class that is apparently never instantiated. If so, remove the code from the assembly. If this class is intended to contain only static methods, consider adding a private constructor to prevent the compiler from generating a default constructor.</Resolution>
+ </Rule>
+ <Rule TypeName="AvoidUnnecessaryStringCreation" Category="Microsoft.Performance" CheckId="CA1807">
+ <Resolution Name="UseStringCompareLocal">{0} calls {1} after converting '{2}', a local, to upper or lowercase. If possible, eliminate the string creation and call the overload of String.Compare that performs a case-insensitive comparison.</Resolution>
+ <Resolution Name="UseStringCompareParameter">{0} calls {1} after converting '{2}', a parameter, to upper or lowercase. If possible, eliminate the string creation and call the overload of String.Compare that performs a case-insensitive comparison.</Resolution>
+ </Rule>
+ <Rule TypeName="AvoidUnusedPrivateFields" Category="Microsoft.Performance" CheckId="CA1823">
+ <Resolution Name="Default">It appears that field '{0}' is never used or is only ever assigned to. Use this field or remove it.</Resolution>
+ </Rule>
+ <Rule TypeName="CollectionsShouldImplementGenericInterface" Category="Microsoft.Design" CheckId="CA1010">
+ <Resolution Name="Default">'{0}' appears to be a non-generic, strongly typed collection. Add an implementation to the instance of {1}&lt;T&gt; where T is {0}'s underlying element type.</Resolution>
+ </Rule>
+ <Rule TypeName="CompoundWordsShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1702">
+ <Resolution Name="ShouldBeCompoundWord">The discrete term '{0}' in {1} '{2}' should be expressed as a compound term, '{3}'.</Resolution>
+ <Resolution Name="ShouldBeDiscreteTerm">The compound word '{0}' in {1} '{2}' exists as a discrete term. If your usage is intended to be single word, case it as '{3}'.</Resolution>
+ </Rule>
+ <Rule TypeName="ConsiderPassingBaseTypesAsParameters" Category="Microsoft.Design" CheckId="CA1011">
+ <Resolution Name="Default">Consider changing the type of parameter '{0}' in {1} from {2} to its base type {3}. This method appears to only require base class members in its implementation. Suppress this violation if there is a compelling reason to require the more derived type in the method signature.</Resolution>
+ </Rule>
+ <Rule TypeName="DoNotCastUnnecessarily" Category="Microsoft.Performance" CheckId="CA1800">
+ <Resolution Name="Local">'{0}', a local, is cast to type '{1}' multiple times in method {2}. Cache the result of the 'as' operator or direct cast in order to eliminate the redundant {3} instruction.</Resolution>
+ <Resolution Name="Parameter">'{0}', a parameter, is cast to type '{1}' multiple times in method {2}. Cache the result of the 'as' operator or direct cast in order to eliminate the redundant {3} instruction.</Resolution>
+ </Rule>
+ <Rule TypeName="DoNotCatchGeneralExceptionTypes" Category="Microsoft.Design" CheckId="CA1031">
+ <Resolution Name="Default">Modify '{0}' to catch a more specific exception than '{1}' or rethrow the exception.</Resolution>
+ </Rule>
+ <Rule TypeName="DoNotConcatenateStringsInsideLoops" Category="Microsoft.Performance" CheckId="CA1818">
+ <Resolution Name="Default">Change {0} to use StringBuilder instead of String.Concat or +=</Resolution>
+ </Rule>
+ <Rule TypeName="DoNotDeclareReadOnlyMutableReferenceTypes" Category="Microsoft.Security" CheckId="CA2104">
+ <Resolution Name="Default">Remove the readonly declaration from '{0}' or change the field to one that is an immutable reference type. If the reference type '{1}' is, in fact, immutable, exclude this message.</Resolution>
+ </Rule>
+ <Rule TypeName="DoNotDeclareVisibleInstanceFields" Category="Microsoft.Design" CheckId="CA1051">
+ <Resolution Name="Default">Make '{0}' private or internal (Friend in VB, public private in C++) and provide a public or protected property to access it.</Resolution>
+ </Rule>
+ <Rule TypeName="DoNotIgnoreMethodResults" Category="Microsoft.Usage" CheckId="CA1806">
+ <Resolution Name="ObjectCreation">{0} creates an instance of {1} which is either not assigned to a variable or is never used. Remove the object creation if it is unnecessary or use it within the method.</Resolution>
+ </Rule>
+ <Rule TypeName="DoNotInitializeUnnecessarily" Category="Microsoft.Performance" CheckId="CA1805">
+ <Resolution Name="Default">{0} initializes field {1} of type {2} to {3}. Remove this initialization as it will be done automatically by the runtime.</Resolution>
+ </Rule>
+ <Rule TypeName="DoNotPassLiteralsAsLocalizedParameters" Category="Microsoft.Globalization" CheckId="CA1303">
+ <Resolution Name="Default">{0} passes a literal as parameter {1} of a call to {2}. Retrieve the following string argument from a resource table instead: '{3}'</Resolution>
+ </Rule>
+ <Rule TypeName="DoNotRaiseReservedExceptionTypes" Category="Microsoft.Usage" CheckId="CA2201">
+ <Resolution Name="TooGeneric">{0} creates an exception of type '{1}', an exception type that is not sufficiently specific and should never be raised by user code. If this exception instance might be thrown, use a different exception type.</Resolution>
+ </Rule>
+ <Rule TypeName="ExceptionsShouldBePublic" Category="Microsoft.Design" CheckId="CA1064">
+ <Resolution Name="Default">Make exception class {0} public.</Resolution>
+ </Rule>
+ <Rule TypeName="ICollectionImplementationsHaveStronglyTypedMembers" Category="Microsoft.Design" CheckId="CA1035">
+ <Resolution Name="Default">'{0}' should provide a strongly typed implementation of ICollection.CopyTo.</Resolution>
+ </Rule>
+ <Rule TypeName="IdentifiersShouldBeCasedCorrectly" Category="Microsoft.Naming" CheckId="CA1709">
+ <Resolution Name="Member">Correct the casing of member name '{0}'.</Resolution>
+ <Resolution Name="Namespace">Correct the casing of namespace name '{0}'.</Resolution>
+ <Resolution Name="Parameter">Correct the casing of parameter name '{0}'.</Resolution>
+ </Rule>
+ <Rule TypeName="IdentifiersShouldBeSpelledCorrectly" Category="Microsoft.Naming" CheckId="CA1704">
+ <Resolution Name="Member">Correct the spelling of the unrecognized token '{0}' in member name '{1}'.</Resolution>
+ <Resolution Name="Namespace">Correct the spelling of the unrecognized token '{0}' in namespace '{1}'.</Resolution>
+ <Resolution Name="Parameter">In method {0}, correct the spelling of the unrecognized token '{1}' in parameter name '{2}' or strip it entirely if it represents any sort of hungarian notation.</Resolution>
+ <Resolution Name="ParameterOneLetter">In method {0}, consider providing a more meaningful name than the one-letter parameter name '{1}'.</Resolution>
+ <Resolution Name="Type">Correct the spelling of the unrecognized token '{0}' in type name '{1}'.</Resolution>
+ </Rule>
+ <Rule TypeName="IdentifiersShouldDifferByMoreThanCase" Category="Microsoft.Naming" CheckId="CA1708">
+ <Resolution Name="Member">Change member names {0} and '{1}' so that they differ by more than case.</Resolution>
+ </Rule>
+ <Rule TypeName="IdentifiersShouldHaveCorrectPrefix" Category="Microsoft.Naming" CheckId="CA1715">
+ <Resolution Name="Default">Prefix interface name '{0}' with 'I'.</Resolution>
+ </Rule>
+ <Rule TypeName="IdentifiersShouldHaveCorrectSuffix" Category="Microsoft.Naming" CheckId="CA1710">
+ <Resolution Name="Default">Rename '{0}' to end in '{1}'.</Resolution>
+ </Rule>
+ <Rule TypeName="IdentifiersShouldNotContainUnderscores" Category="Microsoft.Naming" CheckId="CA1707">
+ <Resolution Name="Member">Remove all underscores from member '{0}'.</Resolution>
+ </Rule>
+ <Rule TypeName="IdentifiersShouldNotHaveIncorrectSuffix" Category="Microsoft.Naming" CheckId="CA1711">
+ <Resolution Name="Default">Rename '{0}' so that it does not end in '{1}'.</Resolution>
+ </Rule>
+ <Rule TypeName="ImplementIDisposableCorrectly" Category="Microsoft.Design" CheckId="CA1063">
+ <Resolution Name="DisposeImplementation">Modify {0} so that it calls Dispose(true), then calls GC.SuppressFinalize on the current object instance ('this' or 'Me' in VB), and then returns.</Resolution>
+ <Resolution Name="ProvideDisposeBool">Provide an overridable implementation of Dispose(bool) on {0} or mark the type as sealed. A call to Dispose(false) should only clean up native resources. A call to Dispose(true) should clean up both managed and native resources.</Resolution>
+ </Rule>
+ <Rule TypeName="ImplementStandardExceptionConstructors" Category="Microsoft.Design" CheckId="CA1032">
+ <Resolution Name="Default">Add the following constructor to {0}: {1}.</Resolution>
+ </Rule>
+ <Rule TypeName="InitializeReferenceTypeStaticFieldsInline" Category="Microsoft.Performance" CheckId="CA1810">
+ <Resolution Name="Default">Initialize all static fields in {0} when those fields are declared and remove the explicit static constructor.</Resolution>
+ </Rule>
+ <Rule TypeName="InstantiateArgumentExceptionsCorrectly" Category="Microsoft.Usage" CheckId="CA2208">
+ <Resolution Name="OneArgumentShouldBeParameterName">Calls to {0}'s constructor '{1}' should contain one of the method's parameter names instead of '{2}'. Note that the provided parameter name should have the exact casing as declared on the method.</Resolution>
+ </Rule>
+ <Rule TypeName="LiteralsShouldBeSpelledCorrectly" Category="Microsoft.Usage" CheckId="CA2204">
+ <Resolution Name="Default">Correct the spelling of the unrecognized token '{0}' in the literal '{1}'.</Resolution>
+ </Rule>
+ <Rule TypeName="LongAcronymsShouldBePascalCased" Category="Microsoft.Naming" CheckId="CA1705">
+ <Resolution Name="Member">Correct the capitalization of member name '{0}'.</Resolution>
+ <Resolution Name="Parameter">Correct the capitalization of parameter name '{0}'.</Resolution>
+ <Resolution Name="Type">Correct the capitalization of type name '{0}'.</Resolution>
+ </Rule>
+ <Rule TypeName="MarkAssembliesWithClsCompliant" Category="Microsoft.Design" CheckId="CA1014">
+ <Resolution Name="NoAttr">'{0}' should be marked with CLSCompliantAttribute and its value should be true.</Resolution>
+ </Rule>
+ <Rule TypeName="MarkISerializableTypesWithSerializable" Category="Microsoft.Usage" CheckId="CA2237">
+ <Resolution Name="Default">Add [Serializable] to '{0}' as this type implements ISerializable.</Resolution>
+ </Rule>
+ <Rule TypeName="MarkMembersAsStatic" Category="Microsoft.Performance" CheckId="CA1822">
+ <Resolution Name="Default">The 'this' parameter (or 'Me' in VB) of {0} is never used. Mark the member as static (or Shared in VB) or use 'this'/'Me' in the method body or at least one property accessor, if appropriate.</Resolution>
+ </Rule>
+ <Rule TypeName="NestedTypesShouldNotBeVisible" Category="Microsoft.Design" CheckId="CA1034">
+ <Resolution Name="Default">Do not nest type '{0}'. Alternatively, change its accessibility so that it is not externally visible.</Resolution>
+ </Rule>
+ <Rule TypeName="NonConstantFieldsShouldNotBeVisible" Category="Microsoft.Usage" CheckId="CA2211">
+ <Resolution Name="Default">Consider making '{0}' non-public or a constant.</Resolution>
+ </Rule>
+ <Rule TypeName="OperationsShouldNotOverflow" Category="Microsoft.Usage" CheckId="CA2233">
+ <Resolution Name="Default">Correct the potential overflow in the operation '{0}' in '{1}'.</Resolution>
+ </Rule>
+ <Rule TypeName="ParameterNamesShouldMatchBaseDeclaration" Category="Microsoft.Naming" CheckId="CA1725">
+ <Resolution Name="Default">Change parameter name '{0}' of method {1} to '{2}' in order to match the identifier as it has been declared in {3}.</Resolution>
+ </Rule>
+ <Rule TypeName="PropertiesShouldNotBeWriteOnly" Category="Microsoft.Design" CheckId="CA1044">
+ <Resolution Name="Default">Add a property getter to '{0}'.</Resolution>
+ </Rule>
+ <Rule TypeName="PropertiesShouldNotReturnArrays" Category="Microsoft.Performance" CheckId="CA1819">
+ <Resolution Name="Default">Change {0} to return a collection or make it a method.</Resolution>
+ </Rule>
+ <Rule TypeName="ProvideCorrectArgumentsToFormattingMethods" Category="Microsoft.Usage" CheckId="CA2241">
+ <Resolution Name="MissingSpecifier">A call to {0} in {1} does not appear to provide a format specifier for argument {2}. The complete format string provided is '{3}'.</Resolution>
+ </Rule>
+ <Rule TypeName="RemoveUnusedLocals" Category="Microsoft.Performance" CheckId="CA1804">
+ <Resolution Name="Default">{0} declares a local, '{1}', of type {2}, which is never used or is only assigned to. Use this local or remove it.</Resolution>
+ </Rule>
+ <Rule TypeName="RethrowToPreserveStackDetails" Category="Microsoft.Usage" CheckId="CA2200">
+ <Resolution Name="Default">{0} rethrows a caught exception and specifies it explicitly as an argument. Use 'throw' without an argument instead, in order to preserve the stack location where the exception was initially raised.</Resolution>
+ </Rule>
+ <Rule TypeName="ReviewUnusedParameters" Category="Microsoft.Usage" CheckId="CA1801">
+ <Resolution Name="Default">Parameter '{0}' of {1} is never used. Remove the parameter or use it in the method body.</Resolution>
+ </Rule>
+ <Rule TypeName="ShortAcronymsShouldBeUppercase" Category="Microsoft.Naming" CheckId="CA1706">
+ <Resolution Name="MemberId">'Id' is an abbreviation and therefore is not subject to acronym casing guidelines. Correct the capitalization of 'ID' in member name '{0}' by changing it to 'Id'.</Resolution>
+ <Resolution Name="MemberOk">To insure consistency with legacy api, 'OK' is not subject to acronym casing guidelines. Correct the capitalization of 'OK' in member name '{0}' by changing it to 'Ok'.</Resolution>
+ <Resolution Name="Parameter">Correct the capitalization of '{0}' in parameter name '{1}'.</Resolution>
+ <Resolution Name="Type">Correct the capitalization of '{0}' in type name '{1}'.</Resolution>
+ </Rule>
+ <Rule TypeName="SpecifyCultureInfo" Category="Microsoft.Globalization" CheckId="CA1304">
+ <Resolution Name="Default">{0} makes a call to {1} that does not explicitly provide a CultureInfo. This should be replaced with a call to {2}.</Resolution>
+ </Rule>
+ <Rule TypeName="SpecifyIFormatProvider" Category="Microsoft.Globalization" CheckId="CA1305">
+ <Resolution Name="Default">{0} makes a call to {1} that does not explicitly provide an IFormatProvider. This should be replaced with a call to {2}.</Resolution>
+ </Rule>
+ <Rule TypeName="StaticHolderTypesShouldNotHaveConstructors" Category="Microsoft.Design" CheckId="CA1053">
+ <Resolution Name="Default">Remove the public constructors from '{0}'.</Resolution>
+ </Rule>
+ <Rule TypeName="TestForEmptyStringsUsingStringLength" Category="Microsoft.Performance" CheckId="CA1820">
+ <Resolution Name="IsNullOrEmpty">Replace the call to String.{0}({1}) in '{2}' with a call to String.IsNullOrEmpty.</Resolution>
+ </Rule>
+ <Rule TypeName="TypesThatOwnDisposableFieldsShouldBeDisposable" Category="Microsoft.Design" CheckId="CA1001">
+ <Resolution Name="Default">Implement IDisposable on '{0}' as it instantiates members of the following IDisposable types: {1}</Resolution>
+ </Rule>
+ <Rule TypeName="UriParametersShouldNotBeStrings" Category="Microsoft.Design" CheckId="CA1054">
+ <Resolution Name="Default">Change the type of parameter '{0}' of method {1} from string to System.Uri, or provide an overload of {1}, that allows '{0}' to be passed as a System.Uri object.</Resolution>
+ </Rule>
+ <Rule TypeName="UriReturnValuesShouldNotBeStrings" Category="Microsoft.Design" CheckId="CA1055">
+ <Resolution Name="Default">Change the return type of {0} from string to System.Uri.</Resolution>
+ </Rule>
+ <Rule TypeName="UseEventsWhereAppropriate" Category="Microsoft.Design" CheckId="CA1030">
+ <Resolution Name="Default">Consider making '{0}' an event.</Resolution>
+ </Rule>
+ <Rule TypeName="UseLiteralsWhereAppropriate" Category="Microsoft.Performance" CheckId="CA1802">
+ <Resolution Name="Default">Field '{0}' is declared as 'static readonly' but is initialized with a constant value '{1}'. Mark this field as 'const' instead.</Resolution>
+ </Rule>
+ <Rule TypeName="UsePreferredTerms" Category="Microsoft.Naming" CheckId="CA1726">
+ <Resolution Name="Type">Replace the term '{0}' in type name '{1}' with the preferred alternate '{2}'.</Resolution>
+ </Rule>
+ <Rule TypeName="UsePropertiesWhereAppropriate" Category="Microsoft.Design" CheckId="CA1024">
+ <Resolution Name="Default">Change '{0}' to a property if appropriate.</Resolution>
+ </Rule>
+ <Rule TypeName="ValidateArgumentsOfPublicMethods" Category="Microsoft.Design" CheckId="CA1062">
+ <Resolution Name="Default">Validate parameter {0} passed to externally visible method {1}.</Resolution>
+ </Rule>
+ </Rules>
+ </FxCopReport>
+</FxCopProject>
diff --git a/qpid/dotnet/Qpid.NET.sln b/qpid/dotnet/Qpid.NET.sln
new file mode 100644
index 0000000000..a6417aaad1
--- /dev/null
+++ b/qpid/dotnet/Qpid.NET.sln
@@ -0,0 +1,116 @@
+
+Microsoft Visual Studio Solution File, Format Version 10.00
+# Visual Studio 2008
+
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Qpid.Messaging", "Qpid.Messaging\Qpid.Messaging.csproj", "{6688F826-C58E-4C1B-AA1F-22AFAB4B7D07}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Qpid.Common.Tests", "Qpid.Common.Tests\Qpid.Common.Tests.csproj", "{F83624B0-762B-4D82-900D-FF4C1B36E36E}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Qpid.Buffer", "Qpid.Buffer\Qpid.Buffer.csproj", "{44384DF2-B0A4-4580-BDBC-EE4BAA87D995}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Qpid.Codec", "Qpid.Codec\Qpid.Codec.csproj", "{22D0D0C2-77AF-4DE3-B456-7FF3893F9F88}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Qpid.Client", "Qpid.Client\Qpid.Client.csproj", "{68987C05-3768-452C-A6FC-6BA1D372852F}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Qpid.Common", "Qpid.Common\Qpid.Common.csproj", "{77064C42-24D2-4CEB-9EA2-0EF481A43205}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Qpid.Client.Tests", "Qpid.Client.Tests\Qpid.Client.Tests.csproj", "{BA1B0032-4CE6-40DD-A2DC-119F0FFA0A1D}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Qpid.Sasl", "Qpid.Sasl\Qpid.Sasl.csproj", "{1465B0EE-6452-42A6-AB73-B2F9EABEEE75}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Qpid.Sasl.Tests", "Qpid.Sasl.Tests\Qpid.Sasl.Tests.csproj", "{587B3520-EBB9-41ED-B019-E96116B651CE}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Qpid.Buffer.Tests", "Qpid.Buffer.Tests\Qpid.Buffer.Tests.csproj", "{74640962-99D0-4D06-B57A-9CD66517CF52}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TopicPublisher", "TopicPublisher\TopicPublisher.csproj", "{A06C9FFD-22FF-4654-856D-897C230978AF}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TopicListener", "TopicListener\TopicListener.csproj", "{9A112DF2-146F-4CF4-919B-9D3BE7D088E9}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestClient", "TestClient\TestClient.csproj", "{6E0374D9-99BE-4D4F-B41D-B227E37E04C6}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Qpid.Integration.Tests", "Qpid.Integration.Tests\Qpid.Integration.Tests.csproj", "{DE21CEBC-F38C-43EA-B576-38CA9738A00A}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {6688F826-C58E-4C1B-AA1F-22AFAB4B7D07}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {6688F826-C58E-4C1B-AA1F-22AFAB4B7D07}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {6688F826-C58E-4C1B-AA1F-22AFAB4B7D07}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {6688F826-C58E-4C1B-AA1F-22AFAB4B7D07}.Release|Any CPU.Build.0 = Release|Any CPU
+ {F83624B0-762B-4D82-900D-FF4C1B36E36E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {F83624B0-762B-4D82-900D-FF4C1B36E36E}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {F83624B0-762B-4D82-900D-FF4C1B36E36E}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {F83624B0-762B-4D82-900D-FF4C1B36E36E}.Release|Any CPU.Build.0 = Release|Any CPU
+ {44384DF2-B0A4-4580-BDBC-EE4BAA87D995}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {44384DF2-B0A4-4580-BDBC-EE4BAA87D995}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {44384DF2-B0A4-4580-BDBC-EE4BAA87D995}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {44384DF2-B0A4-4580-BDBC-EE4BAA87D995}.Release|Any CPU.Build.0 = Release|Any CPU
+ {22D0D0C2-77AF-4DE3-B456-7FF3893F9F88}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {22D0D0C2-77AF-4DE3-B456-7FF3893F9F88}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {22D0D0C2-77AF-4DE3-B456-7FF3893F9F88}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {22D0D0C2-77AF-4DE3-B456-7FF3893F9F88}.Release|Any CPU.Build.0 = Release|Any CPU
+ {68987C05-3768-452C-A6FC-6BA1D372852F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {68987C05-3768-452C-A6FC-6BA1D372852F}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {68987C05-3768-452C-A6FC-6BA1D372852F}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {68987C05-3768-452C-A6FC-6BA1D372852F}.Release|Any CPU.Build.0 = Release|Any CPU
+ {77064C42-24D2-4CEB-9EA2-0EF481A43205}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {77064C42-24D2-4CEB-9EA2-0EF481A43205}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {77064C42-24D2-4CEB-9EA2-0EF481A43205}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {77064C42-24D2-4CEB-9EA2-0EF481A43205}.Release|Any CPU.Build.0 = Release|Any CPU
+ {BA1B0032-4CE6-40DD-A2DC-119F0FFA0A1D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {BA1B0032-4CE6-40DD-A2DC-119F0FFA0A1D}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {BA1B0032-4CE6-40DD-A2DC-119F0FFA0A1D}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {BA1B0032-4CE6-40DD-A2DC-119F0FFA0A1D}.Release|Any CPU.Build.0 = Release|Any CPU
+ {1465B0EE-6452-42A6-AB73-B2F9EABEEE75}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {1465B0EE-6452-42A6-AB73-B2F9EABEEE75}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {1465B0EE-6452-42A6-AB73-B2F9EABEEE75}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {1465B0EE-6452-42A6-AB73-B2F9EABEEE75}.Release|Any CPU.Build.0 = Release|Any CPU
+ {587B3520-EBB9-41ED-B019-E96116B651CE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {587B3520-EBB9-41ED-B019-E96116B651CE}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {587B3520-EBB9-41ED-B019-E96116B651CE}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {587B3520-EBB9-41ED-B019-E96116B651CE}.Release|Any CPU.Build.0 = Release|Any CPU
+ {74640962-99D0-4D06-B57A-9CD66517CF52}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {74640962-99D0-4D06-B57A-9CD66517CF52}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {74640962-99D0-4D06-B57A-9CD66517CF52}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {74640962-99D0-4D06-B57A-9CD66517CF52}.Release|Any CPU.Build.0 = Release|Any CPU
+ {A06C9FFD-22FF-4654-856D-897C230978AF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {A06C9FFD-22FF-4654-856D-897C230978AF}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {A06C9FFD-22FF-4654-856D-897C230978AF}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {A06C9FFD-22FF-4654-856D-897C230978AF}.Release|Any CPU.Build.0 = Release|Any CPU
+ {9A112DF2-146F-4CF4-919B-9D3BE7D088E9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {9A112DF2-146F-4CF4-919B-9D3BE7D088E9}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {9A112DF2-146F-4CF4-919B-9D3BE7D088E9}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {9A112DF2-146F-4CF4-919B-9D3BE7D088E9}.Release|Any CPU.Build.0 = Release|Any CPU
+ {6E0374D9-99BE-4D4F-B41D-B227E37E04C6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {6E0374D9-99BE-4D4F-B41D-B227E37E04C6}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {DE21CEBC-F38C-43EA-B576-38CA9738A00A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {DE21CEBC-F38C-43EA-B576-38CA9738A00A}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {DE21CEBC-F38C-43EA-B576-38CA9738A00A}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {DE21CEBC-F38C-43EA-B576-38CA9738A00A}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/qpid/dotnet/Qpid.Sasl.Tests/App.config b/qpid/dotnet/Qpid.Sasl.Tests/App.config
new file mode 100644
index 0000000000..021399939e
--- /dev/null
+++ b/qpid/dotnet/Qpid.Sasl.Tests/App.config
@@ -0,0 +1,33 @@
+<?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.
+
+-->
+
+<configuration>
+ <configSections>
+ <section name="qpid.sasl" type="Apache.Qpid.Sasl.Configuration.SaslConfigurationSectionHandler, Apache.Qpid.Sasl"/>
+ </configSections>
+
+ <qpid.sasl>
+ <clientFactories>
+ <add type="Apache.Qpid.Sasl.Tests.TestClientFactory, Apache.Qpid.Sasl.Tests"/>
+ </clientFactories>
+ </qpid.sasl>
+</configuration>
diff --git a/qpid/dotnet/Qpid.Sasl.Tests/Mechanisms/AnonymousSaslClientTests.cs b/qpid/dotnet/Qpid.Sasl.Tests/Mechanisms/AnonymousSaslClientTests.cs
new file mode 100644
index 0000000000..5839f310e1
--- /dev/null
+++ b/qpid/dotnet/Qpid.Sasl.Tests/Mechanisms/AnonymousSaslClientTests.cs
@@ -0,0 +1,72 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+using System;
+using System.Collections;
+using System.Text;
+
+using NUnit.Framework;
+using Apache.Qpid.Sasl;
+using Apache.Qpid.Sasl.Mechanisms;
+
+namespace Apache.Qpid.Sasl.Tests.Mechanisms
+{
+ [TestFixture]
+ public class AnonymousSaslClientTests : ISaslCallbackHandler
+ {
+ private const string AUTHID = "nobody@nowhere.com";
+
+ [Test]
+ public void ReturnsRightMechanismName()
+ {
+ ISaslClient client = new AnonymousSaslClient(AUTHID, new Hashtable(), this);
+
+ Assert.AreEqual("ANONYMOUS", client.MechanismName);
+ }
+
+ [Test]
+ public void HasInitialResponseReturnsTrue()
+ {
+ ISaslClient client = new AnonymousSaslClient(AUTHID, new Hashtable(), this);
+
+ Assert.IsTrue(client.HasInitialResponse);
+ }
+
+ [Test]
+ public void CanEvaluateChallenge()
+ {
+ Hashtable props = new Hashtable();
+ ISaslClient client = new AnonymousSaslClient(AUTHID, props, this);
+
+ Assert.IsFalse(client.IsComplete);
+ byte[] response = client.EvaluateChallenge(new byte[0]);
+ Assert.AreEqual(AUTHID, Encoding.UTF8.GetString(response));
+
+ Assert.IsTrue(client.IsComplete);
+ }
+
+ void ISaslCallbackHandler.Handle(ISaslCallback[] callbacks)
+ {
+ }
+
+ } // class AnonymousSaslClientTests
+
+} // namespace Apache.Qpid.Sasl.Tests.Mechanisms
diff --git a/qpid/dotnet/Qpid.Sasl.Tests/Mechanisms/CramMD5SaslClientTests.cs b/qpid/dotnet/Qpid.Sasl.Tests/Mechanisms/CramMD5SaslClientTests.cs
new file mode 100644
index 0000000000..baeeafb2d2
--- /dev/null
+++ b/qpid/dotnet/Qpid.Sasl.Tests/Mechanisms/CramMD5SaslClientTests.cs
@@ -0,0 +1,90 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+using System;
+using System.Collections;
+using System.Text;
+
+using NUnit.Framework;
+using Apache.Qpid.Sasl;
+using Apache.Qpid.Sasl.Mechanisms;
+
+namespace Apache.Qpid.Sasl.Tests.Mechanisms
+{
+ [TestFixture]
+ public class CramMD5SaslClientTests : ISaslCallbackHandler
+ {
+ private const string USERNAME = "testuser";
+ private const string PASSWORD = "tanstaaftanstaaf";
+ private const string AUTHID = "test";
+
+ [Test]
+ public void ReturnsRightMechanismName()
+ {
+ ISaslClient client = new CramMD5SaslClient(AUTHID, new Hashtable(), this);
+
+ Assert.AreEqual("CRAM-MD5", client.MechanismName);
+ }
+
+ [Test]
+ public void HasInitialResponseReturnsFalse()
+ {
+ ISaslClient client = new CramMD5SaslClient(AUTHID, new Hashtable(), this);
+
+ Assert.IsFalse(client.HasInitialResponse);
+ }
+
+ [Test]
+ public void CanEvaluateChallenge()
+ {
+ Hashtable props = new Hashtable();
+
+ ISaslClient client = new CramMD5SaslClient(AUTHID, props, this);
+
+ Assert.IsFalse(client.IsComplete);
+
+ byte[] challenge =
+ Encoding.UTF8.GetBytes("<1896.697170952@postoffice.reston.mci.net>");
+ byte[] response = client.EvaluateChallenge(challenge);
+ string[] parts = Encoding.UTF8.GetString(response).Split(' ');
+
+ Assert.AreEqual(2, parts.Length);
+ Assert.AreEqual(USERNAME, parts[0]);
+ Assert.AreEqual("b913a602c7eda7a495b4e6e7334d3890", parts[1]);
+ Assert.IsTrue(client.IsComplete);
+ }
+
+ void ISaslCallbackHandler.Handle(ISaslCallback[] callbacks)
+ {
+ foreach ( ISaslCallback cb in callbacks )
+ {
+ if ( cb is NameCallback )
+ {
+ ((NameCallback)cb).Text = USERNAME;
+ } else if ( cb is PasswordCallback )
+ {
+ ((PasswordCallback)cb).Text = PASSWORD;
+ }
+ }
+ }
+ } // class CramMD5SaslClientTests
+
+} // namespace Apache.Qpid.Sasl.Tests.Mechanisms
diff --git a/qpid/dotnet/Qpid.Sasl.Tests/Mechanisms/DigestSaslClientTests.cs b/qpid/dotnet/Qpid.Sasl.Tests/Mechanisms/DigestSaslClientTests.cs
new file mode 100644
index 0000000000..5a18ebaefd
--- /dev/null
+++ b/qpid/dotnet/Qpid.Sasl.Tests/Mechanisms/DigestSaslClientTests.cs
@@ -0,0 +1,249 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+using System;
+using System.Collections;
+using System.Collections.Specialized;
+using System.Text;
+
+using NUnit.Framework;
+using Apache.Qpid.Sasl;
+using Apache.Qpid.Sasl.Mechanisms;
+
+namespace Apache.Qpid.Sasl.Tests.Mechanisms
+{
+ [TestFixture]
+ public class DigestSaslClientTests : ISaslCallbackHandler
+ {
+ private const string USERNAME = "chris";
+ private const string PASSWORD = "secret";
+ private const string AUTHID = null;
+ private const string PROTOCOL = "IMAP";
+ private const string SERVERNAME = "elwood.innosoft.com";
+
+ #region Digest Challenge Parsing Tests
+ //
+ // Digest Challenge Parsing Tests
+ //
+
+ [Test]
+ public void CanParseSimpleString()
+ {
+ string challenge = "realm=\"elwood.innosoft.com\", algorithm=md5-sess";
+ StringDictionary values = DigestChallenge.ParseParameters(challenge);
+ Assert.AreEqual(2, values.Count);
+ Assert.AreEqual("elwood.innosoft.com", values["realm"]);
+ Assert.AreEqual("md5-sess", values["algorithm"]);
+ }
+
+ [Test]
+ public void CanParseEscapedQuotes()
+ {
+ string challenge = "realm=\"elwood\\\".innosoft.com\", algorithm=md5-sess";
+ StringDictionary values = DigestChallenge.ParseParameters(challenge);
+ Assert.AreEqual(2, values.Count);
+ Assert.AreEqual("elwood\\\".innosoft.com", values["realm"]);
+ Assert.AreEqual("md5-sess", values["algorithm"]);
+ }
+
+ [Test]
+ public void CanParseEmbeddedDelimiter()
+ {
+ string challenge = "realm=\"elwood,innosoft.com\", algorithm=md5-sess";
+ StringDictionary values = DigestChallenge.ParseParameters(challenge);
+ Assert.AreEqual(2, values.Count);
+ Assert.AreEqual("elwood,innosoft.com", values["realm"]);
+ Assert.AreEqual("md5-sess", values["algorithm"]);
+ }
+
+ [Test]
+ public void CanParse1()
+ {
+ string challenge = "realm=\"elwood.innosoft.com\",nonce=\"OA6MG9tEQGm2hh\",qop=\"auth\",algorithm=md5-sess,charset=utf-8";
+ DigestChallenge parsed = DigestChallenge.Parse(challenge);
+
+ Assert.AreEqual("elwood.innosoft.com", parsed.Realm);
+ Assert.AreEqual("OA6MG9tEQGm2hh", parsed.Nonce);
+ Assert.Contains("auth", parsed.QopOptions);
+ Assert.AreEqual("md5-sess", parsed.Algorithm);
+ Assert.AreEqual("utf-8", parsed.Charset);
+ }
+
+ #endregion // Digest Challenge Parsing Tests
+
+
+ #region Digest Response Tests
+ //
+ // Digest Response Tests
+ //
+
+ [Test]
+ public void CanWriteResponse()
+ {
+ DigestResponse resp = new DigestResponse();
+ resp.Username = "user";
+ resp.Realm = "nowhere.com";
+ resp.Nonce = "OA9BSXrbuRhWay";
+ resp.Cnonce = "OA9BSuZWMSpW8m";
+ resp.NonceCount = 16;
+ resp.DigestUri = "acap/elwood.innosoft.com";
+ resp.Response = "6084c6db3fede7352c551284490fd0fc";
+ resp.Qop = "auth";
+ resp.MaxBuffer = 65536;
+ resp.Cipher = "3des";
+ resp.Authzid = "user2";
+ resp.AuthParam = "ap";
+ resp.Charset = "utf-8";
+
+ string expected = "username=\"user\",realm=\"nowhere.com\",nonce=\"OA9BSXrbuRhWay\",cnonce=\"OA9BSuZWMSpW8m\",nc=00000010,qop=auth,digest-uri=\"acap/elwood.innosoft.com\",response=\"6084c6db3fede7352c551284490fd0fc\",maxbuf=65536,charset=utf-8,cipher=3des,authzid=\"user2\",auth-param=\"ap\"";
+ Assert.AreEqual(expected, resp.ToString());
+ }
+
+ [Test]
+ public void CanWriteEscapedSecuence()
+ {
+ DigestResponse resp = new DigestResponse();
+ resp.Username = "us\"er";
+
+ string expected = "username=\"us\\\"er\",nc=00000000,maxbuf=0";
+ Assert.AreEqual(expected, resp.ToString());
+ }
+
+ #endregion // Digest Response Tests
+
+
+ #region Authentication Tests
+ //
+ // Authentication Tests
+ //
+
+ [Test]
+ public void ReturnsRightMechanismName()
+ {
+ ISaslClient client = CreateClient();
+
+ Assert.AreEqual("DIGEST-MD5", client.MechanismName);
+ }
+
+ [Test]
+ public void HasInitialResponseReturnsFalse()
+ {
+ ISaslClient client = CreateClient();
+
+ Assert.IsFalse(client.HasInitialResponse);
+ }
+
+ [Test]
+ public void CanAuthenticate()
+ {
+ string challenge = "realm=\"elwood.innosoft.com\",nonce=\"OA6MG9tEQGm2hh\",qop=\"auth\",algorithm=md5-sess,charset=utf-8";
+ DigestSaslClient client = CreateClient();
+ client.Cnonce = "OA6MHXh6VqTrRk";
+
+ byte[] bresp = client.EvaluateChallenge(Encoding.UTF8.GetBytes(challenge));
+ string response = Encoding.UTF8.GetString(bresp);
+ string expectedResp = "username=\"chris\",realm=\"elwood.innosoft.com\",nonce=\"OA6MG9tEQGm2hh\",cnonce=\"" +
+ client.Cnonce + "\",nc=00000001,qop=auth,digest-uri=\"imap/elwood.innosoft.com\",response=\"d388dad90d4bbd760a152321f2143af7\",maxbuf=65536,charset=utf-8";
+
+ Assert.AreEqual(expectedResp, response);
+ Assert.IsFalse(client.IsComplete);
+
+ string challenge2 = "rspauth=ea40f60335c427b5527b84dbabcdfffd";
+ bresp = client.EvaluateChallenge(Encoding.UTF8.GetBytes(challenge2));
+ // client responds with zero-length array
+ Assert.AreEqual(0, bresp.Length);
+ Assert.IsTrue(client.IsComplete);
+ }
+
+ [Test]
+ [ExpectedException(typeof(ArgumentNullException))]
+ public void ThrowsExceptionWhenChallengeIsMissing()
+ {
+ DigestSaslClient client = CreateClient();
+ client.EvaluateChallenge(null);
+ }
+
+
+ [Test]
+ [ExpectedException(typeof(SaslException))]
+ public void ThrowsExceptionWhenNonceMissing()
+ {
+ string challenge = "realm=\"elwood.innosoft.com\"";
+ DigestSaslClient client = CreateClient();
+
+ client.EvaluateChallenge(Encoding.UTF8.GetBytes(challenge));
+ }
+
+ [Test]
+ [ExpectedException(typeof(SaslException))]
+ public void ThrowsExceptionWhenAlgorithmMissing()
+ {
+ string challenge = "realm=\"elwood.innosoft.com\",nonce=\"asdasadsad\"";
+ DigestSaslClient client = CreateClient();
+
+ client.EvaluateChallenge(Encoding.UTF8.GetBytes(challenge));
+ }
+
+ [Test]
+ [ExpectedException(typeof(SaslException))]
+ public void ThrowsExceptionWhenSecondChallengeInvalid()
+ {
+ string challenge = "realm=\"elwood.innosoft.com\",nonce=\"OA6MG9tEQGm2hh\",qop=\"auth\",algorithm=md5-sess,charset=utf-8";
+ DigestSaslClient client = CreateClient();
+
+ byte[] bresp = client.EvaluateChallenge(Encoding.UTF8.GetBytes(challenge));
+ Encoding.UTF8.GetString(bresp);
+
+ // repeat challenge 1, which is incorrect
+ client.EvaluateChallenge(Encoding.UTF8.GetBytes(challenge));
+ }
+
+ private DigestSaslClient CreateClient()
+ {
+ return new DigestSaslClient(
+ AUTHID, SERVERNAME, PROTOCOL,
+ new Hashtable(), this
+ );
+ }
+
+ void ISaslCallbackHandler.Handle(ISaslCallback[] callbacks)
+ {
+ foreach ( ISaslCallback cb in callbacks )
+ {
+ if ( cb is NameCallback )
+ {
+ ((NameCallback)cb).Text = USERNAME;
+ } else if ( cb is PasswordCallback )
+ {
+ ((PasswordCallback)cb).Text = PASSWORD;
+ } else if ( cb is RealmCallback )
+ {
+ ((RealmCallback)cb).Text = SERVERNAME;
+ }
+ }
+ }
+
+ #endregion // Authentication Tests
+
+
+ } // class DigestSaslClientTests
+
+} // namespace Apache.Qpid.Sasl.Tests.Mechanisms
diff --git a/qpid/dotnet/Qpid.Sasl.Tests/Mechanisms/ExternalSaslClientTests.cs b/qpid/dotnet/Qpid.Sasl.Tests/Mechanisms/ExternalSaslClientTests.cs
new file mode 100644
index 0000000000..57efcf7614
--- /dev/null
+++ b/qpid/dotnet/Qpid.Sasl.Tests/Mechanisms/ExternalSaslClientTests.cs
@@ -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.
+ *
+ */
+
+using System;
+using System.Collections;
+using System.Text;
+
+using NUnit.Framework;
+using Apache.Qpid.Sasl;
+using Apache.Qpid.Sasl.Mechanisms;
+
+namespace Apache.Qpid.Sasl.Tests.Mechanisms
+{
+ [TestFixture]
+ public class ExternalSaslClientTests : ISaslCallbackHandler
+ {
+ private const string AUTHID = "nobody@nowhere.com";
+
+ [Test]
+ public void ReturnsRightMechanismName()
+ {
+ ISaslClient client = new ExternalSaslClient(AUTHID, new Hashtable(), this);
+
+ Assert.AreEqual("EXTERNAL", client.MechanismName);
+ }
+
+ [Test]
+ public void HasInitialResponseReturnsTrue()
+ {
+ ISaslClient client = new ExternalSaslClient(AUTHID, new Hashtable(), this);
+
+ Assert.IsTrue(client.HasInitialResponse);
+ }
+
+ [Test]
+ public void CanEvaluateChallenge()
+ {
+ ISaslClient client = new ExternalSaslClient(AUTHID, new Hashtable(), this);
+
+ Assert.IsFalse(client.IsComplete);
+ byte[] response = client.EvaluateChallenge(new byte[0]);
+ Assert.AreEqual(AUTHID, Encoding.UTF8.GetString(response));
+
+ Assert.IsTrue(client.IsComplete);
+ }
+
+ void ISaslCallbackHandler.Handle(ISaslCallback[] callbacks)
+ {
+ }
+
+ } // class AnonymousSaslClientTests
+
+} // namespace Apache.Qpid.Sasl.Tests.Mechanisms
diff --git a/qpid/dotnet/Qpid.Sasl.Tests/Mechanisms/PlainSaslClientTests.cs b/qpid/dotnet/Qpid.Sasl.Tests/Mechanisms/PlainSaslClientTests.cs
new file mode 100644
index 0000000000..f4fc00e038
--- /dev/null
+++ b/qpid/dotnet/Qpid.Sasl.Tests/Mechanisms/PlainSaslClientTests.cs
@@ -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.
+ *
+ */
+
+using System;
+using System.Collections;
+using System.Text;
+
+using NUnit.Framework;
+using Apache.Qpid.Sasl;
+using Apache.Qpid.Sasl.Mechanisms;
+
+namespace Apache.Qpid.Sasl.Tests.Mechanisms
+{
+ [TestFixture]
+ public class PlainSaslClientTests : ISaslCallbackHandler
+ {
+ private const string USERNAME = "testuser";
+ private const string PASSWORD = "thepasswd";
+ private const string AUTHID = "theauth";
+
+ [Test]
+ public void ReturnsRightMechanismName()
+ {
+ ISaslClient client = new PlainSaslClient(AUTHID, new Hashtable(), this);
+
+ Assert.AreEqual("PLAIN", client.MechanismName);
+ }
+
+ [Test]
+ public void HasInitialResponseReturnsTrue()
+ {
+ ISaslClient client = new PlainSaslClient(AUTHID, new Hashtable(), this);
+
+ Assert.IsTrue(client.HasInitialResponse);
+ }
+
+ [Test]
+ public void CanEvaluateChallenge()
+ {
+ Hashtable props = new Hashtable();
+ ISaslClient client = new PlainSaslClient(AUTHID, props, this);
+
+ Assert.IsFalse(client.IsComplete);
+ byte[] response = client.EvaluateChallenge(new byte[0]);
+ string[] parts = Encoding.UTF8.GetString(response).Split('\0');
+
+ Assert.AreEqual(3, parts.Length);
+ Assert.AreEqual(AUTHID, parts[0]);
+ Assert.AreEqual(USERNAME, parts[1]);
+ Assert.AreEqual(PASSWORD, parts[2]);
+ Assert.IsTrue(client.IsComplete);
+ }
+
+ void ISaslCallbackHandler.Handle(ISaslCallback[] callbacks)
+ {
+ foreach ( ISaslCallback cb in callbacks )
+ {
+ if ( cb is NameCallback )
+ {
+ ((NameCallback)cb).Text = USERNAME;
+ } else if ( cb is PasswordCallback )
+ {
+ ((PasswordCallback)cb).Text = PASSWORD;
+ }
+ }
+ }
+
+ } // class PlainSaslClientTests
+
+} // namespace Apache.Qpid.Sasl.Tests.Mechanisms
diff --git a/qpid/dotnet/Qpid.Sasl.Tests/Properties/AssemblyInfo.cs b/qpid/dotnet/Qpid.Sasl.Tests/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000000..e795c267a7
--- /dev/null
+++ b/qpid/dotnet/Qpid.Sasl.Tests/Properties/AssemblyInfo.cs
@@ -0,0 +1,56 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("Apache.Qpid.Sasl.Tests")]
+[assembly: AssemblyDescription("Built from svn revision number: ")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Apache Software Foundation")]
+[assembly: AssemblyProduct("Apache.Qpid.Sasl.Tests")]
+[assembly: AssemblyCopyright("Apache Software Foundation")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("84cc3267-8019-4fad-a426-0a40155b3352")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Revision and Build Numbers
+// by using the '*' as shown below:
+[assembly: AssemblyVersion("0.5.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/qpid/dotnet/Qpid.Sasl.Tests/Qpid.Sasl.Tests.csproj b/qpid/dotnet/Qpid.Sasl.Tests/Qpid.Sasl.Tests.csproj
new file mode 100644
index 0000000000..f1a7b07e5a
--- /dev/null
+++ b/qpid/dotnet/Qpid.Sasl.Tests/Qpid.Sasl.Tests.csproj
@@ -0,0 +1,86 @@
+<!--
+
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+
+-->
+
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProductVersion>8.0.50727</ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{587B3520-EBB9-41ED-B019-E96116B651CE}</ProjectGuid>
+ <OutputType>Library</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>Apache.Qpid.Sasl.Tests</RootNamespace>
+ <AssemblyName>Apache.Qpid.Sasl.Tests</AssemblyName>
+ <FileUpgradeFlags>
+ </FileUpgradeFlags>
+ <OldToolsVersion>2.0</OldToolsVersion>
+ <UpgradeBackupLocation>
+ </UpgradeBackupLocation>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>..\bin\net-2.0\debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ <UseVSHostingProcess>true</UseVSHostingProcess>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>..\bin\net-2.0\release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="nunit.framework, Version=2.2.8.0, Culture=neutral, PublicKeyToken=96d09a1eb7f44a77">
+ <SpecificVersion>False</SpecificVersion>
+ <HintPath>..\Qpid.Client.Tests\lib\nunit\nunit.framework.dll</HintPath>
+ </Reference>
+ <Reference Include="System" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="**\*.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\Qpid.Sasl\Qpid.Sasl.csproj">
+ <Project>{1465B0EE-6452-42A6-AB73-B2F9EABEEE75}</Project>
+ <Name>Qpid.Sasl</Name>
+ </ProjectReference>
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="App.config" />
+ </ItemGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+ <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
+ Other similar extension points exist, see Microsoft.Common.targets.
+ <Target Name="BeforeBuild">
+ </Target>
+ <Target Name="AfterBuild">
+ </Target>
+ -->
+</Project>
diff --git a/qpid/dotnet/Qpid.Sasl.Tests/SaslTests.cs b/qpid/dotnet/Qpid.Sasl.Tests/SaslTests.cs
new file mode 100644
index 0000000000..e7ae91d6b6
--- /dev/null
+++ b/qpid/dotnet/Qpid.Sasl.Tests/SaslTests.cs
@@ -0,0 +1,133 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+using System;
+using System.Collections;
+using System.Text;
+
+using NUnit.Framework;
+using Apache.Qpid.Sasl;
+using Apache.Qpid.Sasl.Mechanisms;
+
+namespace Apache.Qpid.Sasl.Tests
+{
+ [TestFixture]
+ public class SaslTests : ISaslCallbackHandler
+ {
+
+ [Test]
+ public void CanCreatePlain()
+ {
+ Hashtable props = new Hashtable();
+ string[] mechanisms = new string[] { "PLAIN", "OTHER" };
+ ISaslClient client = Sasl.CreateClient(mechanisms, "", "", "", props, this);
+
+ Assert.IsNotNull(client);
+ Assert.IsInstanceOfType(typeof(PlainSaslClient), client);
+ }
+
+ [Test]
+ public void CanCreateCramMD5()
+ {
+ Hashtable props = new Hashtable();
+ string[] mechanisms = new string[] { "CRAM-MD5", "OTHER" };
+ ISaslClient client = Sasl.CreateClient(mechanisms, "", "", "", props, this);
+
+ Assert.IsNotNull(client);
+ Assert.IsInstanceOfType(typeof(CramMD5SaslClient), client);
+ }
+
+ [Test]
+ public void CanCreateAnonymous()
+ {
+ Hashtable props = new Hashtable();
+ string[] mechanisms = new string[] { "ANONYMOUS", "OTHER" };
+ ISaslClient client = Sasl.CreateClient(mechanisms, "", "", "", props, this);
+
+ Assert.IsNotNull(client);
+ Assert.IsInstanceOfType(typeof(AnonymousSaslClient), client);
+ }
+
+ [Test]
+ public void CanCreateDigest()
+ {
+ Hashtable props = new Hashtable();
+ string[] mechanisms = new string[] { "DIGEST-MD5", "OTHER" };
+ ISaslClient client = Sasl.CreateClient(mechanisms, "", "", "", props, this);
+
+ Assert.IsNotNull(client);
+ Assert.IsInstanceOfType(typeof(DigestSaslClient), client);
+ }
+
+ [Test]
+ public void CanCreateExternal()
+ {
+ Hashtable props = new Hashtable();
+ string[] mechanisms = new string[] { "EXTERNAL", "OTHER" };
+ ISaslClient client = Sasl.CreateClient(mechanisms, "", "", "", props, this);
+
+ Assert.IsNotNull(client);
+ Assert.IsInstanceOfType(typeof(ExternalSaslClient), client);
+ }
+
+ [Test]
+ public void ReturnsNullIfNoFactoryFound()
+ {
+ Hashtable props = new Hashtable();
+ props.Add(SaslProperties.PolicyNoPlainText, true);
+ string[] mechanisms = new string[] { "PLAIN", "OTHER" };
+ ISaslClient client = Sasl.CreateClient(mechanisms, "", "", "", props, this);
+
+ Assert.IsNull(client);
+ }
+
+ [Test]
+ public void ParsesConfigurationSection()
+ {
+ // if the TEST mechanism is available, then we know
+ // the configuration section worked!
+ Hashtable props = new Hashtable();
+ string[] mechanisms = new string[] { "TEST" };
+ ISaslClient client = Sasl.CreateClient(mechanisms, "", "", "", props, this);
+
+ Assert.IsNotNull(client);
+ Assert.IsInstanceOfType(typeof(TestSaslClient), client);
+ }
+
+ [Test]
+ public void ChoosesStrongerMechanism()
+ {
+ Hashtable props = new Hashtable();
+ string[] mechanisms = new string[] { "PLAIN", "OTHER", "CRAM-MD5" };
+ ISaslClient client = Sasl.CreateClient(mechanisms, "", "", "", props, this);
+
+ Assert.IsNotNull(client);
+ Assert.IsInstanceOfType(typeof(CramMD5SaslClient), client);
+ }
+
+
+ void ISaslCallbackHandler.Handle(ISaslCallback[] callbacks)
+ {
+ }
+
+ } // class SaslTests
+
+} // namespace Apache.Qpid.Sasl.Tests
diff --git a/qpid/dotnet/Qpid.Sasl.Tests/TestClientFactory.cs b/qpid/dotnet/Qpid.Sasl.Tests/TestClientFactory.cs
new file mode 100644
index 0000000000..62099237e9
--- /dev/null
+++ b/qpid/dotnet/Qpid.Sasl.Tests/TestClientFactory.cs
@@ -0,0 +1,75 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+using System;
+using System.Collections;
+using System.Text;
+
+using NUnit.Framework;
+using Apache.Qpid.Sasl;
+using Apache.Qpid.Sasl.Mechanisms;
+
+namespace Apache.Qpid.Sasl.Tests
+{
+ public class TestClientFactory : ISaslClientFactory
+ {
+ public string[] GetSupportedMechanisms(IDictionary props)
+ {
+ return new string[] { TestSaslClient.Mechanism };
+ }
+
+ public ISaslClient CreateClient(string[] mechanisms, string authorizationId, string protocol, string serverName, IDictionary props, ISaslCallbackHandler handler)
+ {
+ foreach ( string mech in mechanisms )
+ {
+ if ( mech == TestSaslClient.Mechanism )
+ return new TestSaslClient(props, handler);
+ }
+ return null;
+ }
+
+ } // class TestClientFactory
+
+ internal class TestSaslClient : SaslClient
+ {
+ public const string Mechanism = "TEST";
+
+ public override string MechanismName
+ {
+ get { return Mechanism; }
+ }
+ public override bool HasInitialResponse
+ {
+ get { return false; }
+ }
+
+ public TestSaslClient(IDictionary props, ISaslCallbackHandler handler)
+ : base("", "", "", props, handler)
+ {
+ }
+
+ public override byte[] EvaluateChallenge(byte[] challenge)
+ {
+ throw new NotImplementedException();
+ }
+ } // class TestSaslClient
+
+} // namespace Apache.Qpid.Sasl.Tests
diff --git a/qpid/dotnet/Qpid.Sasl.Tests/default.build b/qpid/dotnet/Qpid.Sasl.Tests/default.build
new file mode 100644
index 0000000000..5b51c0a6fa
--- /dev/null
+++ b/qpid/dotnet/Qpid.Sasl.Tests/default.build
@@ -0,0 +1,52 @@
+<?xml version="1.0"?>
+<!--
+
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+
+-->
+
+<project name="Apache.Qpid.Sasl" default="test">
+
+ <target name="build">
+ <csc target="library"
+ define="${build.defines}"
+ warnaserror="true" debug="${build.debug}"
+ output="${build.dir}/${project::get-name()}.Tests.dll">
+
+ <sources>
+ <include name="**/*.cs" />
+ </sources>
+ <references>
+ <include name="${build.dir}/nunit.framework.dll" />
+ <include name="${build.dir}/${project::get-name()}.dll" />
+ </references>
+
+ </csc>
+ <copy
+ tofile="${build.dir}/${project::get-name()}.Tests.dll.config"
+ file="App.config"
+ />
+ </target>
+ <target name="test" depends="build">
+ <nunit2>
+ <formatter type="${nant.formatter}" usefile="false" />
+ <test assemblyname="${build.dir}/${project::get-name()}.Tests.dll" />
+ </nunit2>
+ </target>
+</project>
+
diff --git a/qpid/dotnet/Qpid.Sasl/Callbacks.cs b/qpid/dotnet/Qpid.Sasl/Callbacks.cs
new file mode 100644
index 0000000000..f4fcc1c54b
--- /dev/null
+++ b/qpid/dotnet/Qpid.Sasl/Callbacks.cs
@@ -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.
+ *
+ */
+
+using System;
+using System.Text;
+using System.Globalization;
+using System.Security.Cryptography;
+
+namespace Apache.Qpid.Sasl
+{
+ /// <summary>
+ /// Marker interface for Sasl Callbacks
+ /// </summary>
+ public interface ISaslCallback
+ {
+ } // interface ISaslCallback
+
+ public abstract class TextSaslCallback : ISaslCallback
+ {
+ private string _prompt;
+ private string _text;
+ private string _defaultText;
+
+ public string Prompt
+ {
+ get { return _prompt; }
+ set { _prompt = value; }
+ }
+
+ public string Text
+ {
+ get {
+ if ( _text == null || _text.Length == 0 )
+ return DefaultText;
+ else
+ return _text;
+ }
+ set { _text = value; }
+ }
+
+ public string DefaultText
+ {
+ get { return _defaultText; }
+ set { _defaultText = value; }
+ }
+
+ protected TextSaslCallback(string prompt, string text, string defaultText)
+ {
+ _prompt = prompt;
+ _text = text;
+ _defaultText = defaultText;
+ }
+
+ } // class TextSaslCallback
+
+ public class NameCallback : TextSaslCallback
+ {
+ public NameCallback()
+ : this(Environment.UserName)
+ {
+ }
+ public NameCallback(string defaultText)
+ : base("username:", "", defaultText)
+ {
+ }
+ } // class NameCallback
+
+ public class PasswordCallback : TextSaslCallback
+ {
+ public PasswordCallback()
+ : base("password:", "", "")
+ {
+ }
+
+ public byte[] HashedText
+ {
+ get
+ {
+ string _text = this.Text;
+ System.Security.Cryptography.MD5CryptoServiceProvider x = new System.Security.Cryptography.MD5CryptoServiceProvider();
+ byte[] bs = x.ComputeHash(Encoding.UTF8.GetBytes(_text));
+ return bs;
+ }
+
+ }
+ } // class PasswordCallback
+
+ public class HashedPasswordCallback : TextSaslCallback
+ {
+ public HashedPasswordCallback()
+ : base("password:", "", "")
+ {
+ }
+
+ public byte[] HashedText
+ {
+ get {
+ string _text = this.Text;
+ System.Security.Cryptography.MD5CryptoServiceProvider x = new System.Security.Cryptography.MD5CryptoServiceProvider();
+ _text = _text.PadRight(16, '\0');
+ byte[] bs = x.ComputeHash(Encoding.UTF8.GetBytes(_text));
+ return bs;
+ }
+ }
+ } // class PasswordCallback
+
+ public class RealmCallback : TextSaslCallback
+ {
+ public RealmCallback()
+ : this("localhost")
+ {
+ }
+ public RealmCallback(string defaultText)
+ : base("realm:", "", defaultText)
+ {
+ }
+ } // class RealmCallback
+
+} // namespace Apache.Qpid.Sasl
+
+
diff --git a/qpid/dotnet/Qpid.Sasl/Configuration/SaslConfiguration.cs b/qpid/dotnet/Qpid.Sasl/Configuration/SaslConfiguration.cs
new file mode 100644
index 0000000000..7a71ec28da
--- /dev/null
+++ b/qpid/dotnet/Qpid.Sasl/Configuration/SaslConfiguration.cs
@@ -0,0 +1,90 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+using System;
+using System.Collections;
+using System.Configuration;
+using System.Text;
+using System.Xml;
+
+namespace Apache.Qpid.Sasl.Configuration
+{
+ /// <summary>
+ /// Represents an Sasl configuration section
+ /// in the config file
+ /// </summary>
+ internal class SaslConfiguration
+ {
+ private IList _clientFactories;
+
+ /// <summary>
+ /// Set of configured client factores
+ /// </summary>
+ public IList ClientFactories
+ {
+ get { return _clientFactories; }
+ }
+
+ internal SaslConfiguration(IList clientFactoryTypes)
+ {
+ _clientFactories = new ArrayList();
+ foreach ( Type type in clientFactoryTypes )
+ {
+ _clientFactories.Add(Activator.CreateInstance(type));
+ }
+ }
+
+ /// <summary>
+ /// Get the configuration for the library
+ /// </summary>
+ /// <returns>The configuration from app.config or a default configuration</returns>
+ internal static SaslConfiguration GetConfiguration()
+ {
+ // 'obsolete' warning, but needed for .NET 1.1 compatibility
+ SaslConfiguration config = (SaslConfiguration)
+ ConfigurationSettings.GetConfig("qpid.sasl");
+ if ( config == null )
+ {
+ // create default configuration
+ IList clientFactories = GetDefaultClientFactories();
+ config = new SaslConfiguration(clientFactories);
+ }
+ return config;
+ }
+
+ /// <summary>
+ /// Create a list filled with the default client
+ /// factories supported by the library
+ /// </summary>
+ /// <returns>The list of client factory types</returns>
+ internal static IList GetDefaultClientFactories()
+ {
+ IList clientFactories = new ArrayList();
+ clientFactories.Add(typeof(DefaultClientFactory));
+ return clientFactories;
+ }
+
+
+ } // class SaslConfiguration
+
+} // namespace Apache.Qpid.Sasl.Configuration
+
+
diff --git a/qpid/dotnet/Qpid.Sasl/Configuration/SaslConfigurationSectionHandler.cs b/qpid/dotnet/Qpid.Sasl/Configuration/SaslConfigurationSectionHandler.cs
new file mode 100644
index 0000000000..ea8669f8c4
--- /dev/null
+++ b/qpid/dotnet/Qpid.Sasl/Configuration/SaslConfigurationSectionHandler.cs
@@ -0,0 +1,84 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+using System;
+using System.Collections;
+using System.Configuration;
+using System.Text;
+using System.Xml;
+
+namespace Apache.Qpid.Sasl.Configuration
+{
+ /// <summary>
+ /// Defines the configuration section to configure extra
+ /// Sasl client factories
+ /// </summary>
+ public class SaslConfigurationSectionHandler
+ : IConfigurationSectionHandler
+ {
+ public object Create(object parent, object configContext, XmlNode section)
+ {
+ IList clientFactories = SaslConfiguration.GetDefaultClientFactories();
+
+ foreach ( XmlNode node in section.ChildNodes )
+ {
+ if ( node.LocalName == "clientFactories" )
+ {
+ ProcessFactories(node, clientFactories);
+ }
+ }
+
+ SaslConfiguration config = new SaslConfiguration(clientFactories);
+ return config;
+ }
+
+
+ private void ProcessFactories(XmlNode node, IList factories)
+ {
+ foreach ( XmlNode child in node.ChildNodes )
+ {
+ Type type;
+ switch ( child.LocalName )
+ {
+ case "add":
+ type = Type.GetType(child.Attributes["type"].Value);
+ if ( !factories.Contains(type) )
+ factories.Add(type);
+ break;
+ case "remove":
+ type = Type.GetType(child.Attributes["type"].Value);
+ if ( factories.Contains(type) )
+ factories.Remove(type);
+ break;
+ case "clear":
+ factories.Clear();
+ break;
+ default:
+ // gives obsolete warning but needed for .NET 1.1 support
+ throw new ConfigurationException(string.Format("Unknown element '{0}' in section '{0}'", child.LocalName, node.LocalName));
+ }
+ }
+ }
+ } // class SaslConfigurationSectionHandler
+
+} // namespace Apache.Qpid.Sasl.Configuration
+
+
diff --git a/qpid/dotnet/Qpid.Sasl/DefaultClientFactory.cs b/qpid/dotnet/Qpid.Sasl/DefaultClientFactory.cs
new file mode 100644
index 0000000000..744d7cae40
--- /dev/null
+++ b/qpid/dotnet/Qpid.Sasl/DefaultClientFactory.cs
@@ -0,0 +1,99 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+using System;
+using System.Collections;
+
+using Apache.Qpid.Sasl.Mechanisms;
+
+namespace Apache.Qpid.Sasl
+{
+ public class DefaultClientFactory : ISaslClientFactory
+ {
+ private static readonly string[] SUPPORTED = new string[] {
+ DigestSaslClient.Mechanism,
+ CramMD5SaslClient.Mechanism,
+ CramMD5HexSaslClient.Mechanism,
+ PlainSaslClient.Mechanism,
+ AnonymousSaslClient.Mechanism,
+ ExternalSaslClient.Mechanism,
+ };
+
+ public string[] GetSupportedMechanisms(IDictionary props)
+ {
+ if ( props == null )
+ throw new ArgumentNullException("props");
+
+ ArrayList vetoed = new ArrayList();
+
+ if ( props.Contains(SaslProperties.PolicyNoPlainText) ||
+ props.Contains(SaslProperties.PolicyNoDictionary) ||
+ props.Contains(SaslProperties.PolicyNoActive) ||
+ props.Contains(SaslProperties.PolicyForwardSecrecy) ||
+ props.Contains(SaslProperties.PolicyPassCredentials) )
+ {
+ vetoed.Add(CramMD5SaslClient.Mechanism);
+ vetoed.Add(CramMD5HexSaslClient.Mechanism);
+ vetoed.Add(PlainSaslClient.Mechanism);
+ vetoed.Add(AnonymousSaslClient.Mechanism);
+ vetoed.Add(ExternalSaslClient.Mechanism);
+ }
+ if ( props.Contains(SaslProperties.PolicyNoAnonymous) )
+ {
+ vetoed.Add(AnonymousSaslClient.Mechanism);
+ }
+
+ ArrayList available = new ArrayList();
+ foreach ( string mech in SUPPORTED )
+ {
+ if ( !vetoed.Contains(mech) )
+ available.Add(mech);
+ }
+ return (string[])available.ToArray(typeof(string));
+ }
+
+ public ISaslClient CreateClient(
+ string[] mechanisms, string authorizationId,
+ string protocol, string serverName,
+ IDictionary props, ISaslCallbackHandler handler
+ )
+ {
+ IList mechs = mechanisms;
+ if ( mechs.Contains(ExternalSaslClient.Mechanism) )
+ return new ExternalSaslClient(authorizationId, props, handler);
+ if ( mechs.Contains(DigestSaslClient.Mechanism) )
+ return new DigestSaslClient(authorizationId, serverName, protocol, props, handler);
+ if ( mechs.Contains(CramMD5SaslClient.Mechanism) )
+ return new CramMD5SaslClient(authorizationId, props, handler);
+ if ( mechs.Contains(CramMD5HexSaslClient.Mechanism) )
+ return new CramMD5HexSaslClient(authorizationId, props, handler);
+ if ( mechs.Contains(PlainSaslClient.Mechanism) )
+ return new PlainSaslClient(authorizationId, props, handler);
+ if ( mechs.Contains(AnonymousSaslClient.Mechanism) )
+ return new AnonymousSaslClient(authorizationId, props, handler);
+ // unknown mechanism
+ return null;
+ }
+ } // class DefaultClientFactory
+
+} // namespace Apache.Qpid.Sasl
+
+
diff --git a/qpid/dotnet/Qpid.Sasl/ISaslCallbackHandler.cs b/qpid/dotnet/Qpid.Sasl/ISaslCallbackHandler.cs
new file mode 100644
index 0000000000..c2638f245e
--- /dev/null
+++ b/qpid/dotnet/Qpid.Sasl/ISaslCallbackHandler.cs
@@ -0,0 +1,35 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+using System;
+using System.Text;
+
+namespace Apache.Qpid.Sasl
+{
+ public interface ISaslCallbackHandler
+ {
+ void Handle(ISaslCallback[] callbacks);
+
+ } // interface ISaslCallbackHandler
+
+} // namespace Apache.Qpid.Sasl
+
+
diff --git a/qpid/dotnet/Qpid.Sasl/ISaslClient.cs b/qpid/dotnet/Qpid.Sasl/ISaslClient.cs
new file mode 100644
index 0000000000..668ca05d26
--- /dev/null
+++ b/qpid/dotnet/Qpid.Sasl/ISaslClient.cs
@@ -0,0 +1,42 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+using System;
+using System.Text;
+
+namespace Apache.Qpid.Sasl
+{
+ public interface ISaslClient
+ {
+ string MechanismName { get; }
+ bool HasInitialResponse { get; }
+ bool IsComplete { get; }
+
+ byte[] EvaluateChallenge(byte[] challenge);
+ object GetNegotiatedProperty(string propName);
+ byte[] Unwrap(byte[] buffer, int offset, int length);
+ byte[] Wrap(byte[] buffer, int offset, int lenght);
+
+ } // interface ISaslClient
+
+} // namespace Apache.Qpid.Sasl
+
+
diff --git a/qpid/dotnet/Qpid.Sasl/ISaslClientFactory.cs b/qpid/dotnet/Qpid.Sasl/ISaslClientFactory.cs
new file mode 100644
index 0000000000..f052e07ad9
--- /dev/null
+++ b/qpid/dotnet/Qpid.Sasl/ISaslClientFactory.cs
@@ -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.
+ *
+ */
+
+using System;
+using System.Collections;
+using System.Text;
+
+namespace Apache.Qpid.Sasl
+{
+ public interface ISaslClientFactory
+ {
+ string[] GetSupportedMechanisms(IDictionary props);
+ ISaslClient CreateClient(
+ string[] mechanisms, string authorizationId,
+ string protocol, string serverName,
+ IDictionary props, ISaslCallbackHandler handler
+ );
+ } // interface ISaslClientFactory
+
+} // namespace Apache.Qpid.Sasl
+
+
diff --git a/qpid/dotnet/Qpid.Sasl/MD5HMAC.cs b/qpid/dotnet/Qpid.Sasl/MD5HMAC.cs
new file mode 100644
index 0000000000..7e310c5364
--- /dev/null
+++ b/qpid/dotnet/Qpid.Sasl/MD5HMAC.cs
@@ -0,0 +1,115 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+using System;
+using System.Security.Cryptography;
+
+namespace Apache.Qpid.Sasl
+{
+ /// <summary>
+ /// Rough HMAC MD5 implementation as presented in
+ /// RFC 2104. Used because the HMACMD5 class in the
+ /// .NET framework is not available in v1.1.
+ /// </summary>
+ public sealed class MD5HMAC : IDisposable
+ {
+ private const int BLOCK_LEN = 64;
+ private MD5 _hash;
+ private byte[] _key;
+ private byte[] _ipad;
+ private byte[] _opad;
+
+ public MD5HMAC(byte[] key)
+ {
+ if ( key == null || key.Length == 0 )
+ throw new ArgumentNullException("key");
+
+ _hash = new MD5CryptoServiceProvider();
+
+ byte[] theKey = key;
+ if ( theKey.Length > BLOCK_LEN )
+ {
+ theKey = _hash.ComputeHash(theKey);
+ }
+ // pad key with 0's up to BLOCK_LEN
+ _key = new byte[BLOCK_LEN];
+ Array.Copy(theKey, _key, theKey.Length);
+
+ CreatePads();
+ }
+
+ public byte[] ComputeHash(byte[] input)
+ {
+ // H(K XOR opad, H(K XOR ipad, text))
+ return H(_opad, H(_ipad, input));
+ }
+
+ public void Dispose()
+ {
+ if ( _hash != null )
+ {
+ ((IDisposable)_hash).Dispose();
+ _hash = null;
+ }
+ }
+
+ #region Private Methods
+ //
+ // Private Methods
+ //
+
+ private void CreatePads()
+ {
+ _ipad = new byte[BLOCK_LEN];
+ _opad = new byte[BLOCK_LEN];
+ for ( int i = 0; i < BLOCK_LEN; i++ )
+ {
+ _ipad[i] = 0x36;
+ _opad[i] = 0x5c;
+ }
+
+ XOR(_ipad, _key);
+ XOR(_opad, _key);
+ }
+
+ private static void XOR(byte[] dest, byte[] other)
+ {
+ // assume both are same size
+ for ( int i = 0; i < dest.Length; i++ )
+ {
+ dest[i] ^= other[i];
+ }
+ }
+
+ private byte[] H(byte[] v1, byte[] v2)
+ {
+ byte[] total = new byte[v1.Length + v2.Length];
+ Array.Copy(v1, total, v1.Length);
+ Array.Copy(v2, 0, total, v1.Length, v2.Length);
+
+ return _hash.ComputeHash(total);
+ }
+
+ #endregion // Private Methods
+
+ } // class MD5HMAC
+
+} // namespace Apache.Qpid.Sasl
diff --git a/qpid/dotnet/Qpid.Sasl/Mechanisms/AnonymousSaslClient.cs b/qpid/dotnet/Qpid.Sasl/Mechanisms/AnonymousSaslClient.cs
new file mode 100644
index 0000000000..e550d10d97
--- /dev/null
+++ b/qpid/dotnet/Qpid.Sasl/Mechanisms/AnonymousSaslClient.cs
@@ -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.
+ *
+ */
+
+using System;
+using System.Collections;
+using System.Text;
+
+namespace Apache.Qpid.Sasl.Mechanisms
+{
+ /// <summary>
+ /// Implements the ANONYMOUS authentication mechanism
+ /// as outlined in RFC 2245
+ /// </summary>
+ public class AnonymousSaslClient : SaslClient
+ {
+ public const string Mechanism = "ANONYMOUS";
+
+ public AnonymousSaslClient(
+ string authid, IDictionary properties,
+ ISaslCallbackHandler handler)
+ : base(authid, null, null, properties, handler)
+ {
+ }
+
+ #region ISaslClient Implementation
+ //
+ // ISaslClient Implementation
+ //
+
+ public override string MechanismName
+ {
+ get { return Mechanism; }
+ }
+
+ public override bool HasInitialResponse
+ {
+ get { return true; }
+ }
+
+ public override byte[] EvaluateChallenge(byte[] challenge)
+ {
+ // ignore challenge
+ SetComplete();
+ return Encoding.UTF8.GetBytes(AuthorizationId);
+ }
+
+ #endregion // ISaslClient Implementation
+
+ } // class AnonymousSaslClient
+
+} // namespace Apache.Qpid.Sasl.Mechanisms
diff --git a/qpid/dotnet/Qpid.Sasl/Mechanisms/CramMD5HexSaslClient.cs b/qpid/dotnet/Qpid.Sasl/Mechanisms/CramMD5HexSaslClient.cs
new file mode 100644
index 0000000000..3cce0e3a2d
--- /dev/null
+++ b/qpid/dotnet/Qpid.Sasl/Mechanisms/CramMD5HexSaslClient.cs
@@ -0,0 +1,93 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+using System;
+using System.Collections;
+using System.Security.Cryptography;
+using System.Text;
+
+namespace Apache.Qpid.Sasl.Mechanisms
+{
+ /// <summary>
+ /// Implements the CRAM-MD5 authentication mechanism as outlined
+ /// in RFC 2195
+ /// </summary>
+ public class CramMD5HexSaslClient : SaslClient
+ {
+ public const string Mechanism = "CRAM-MD5-HEX";
+ private const int MinPwdLen = 16;
+
+ public CramMD5HexSaslClient(
+ string authorizationId,
+ IDictionary properties,
+ ISaslCallbackHandler handler)
+ : base(authorizationId, null, null, properties, handler)
+ {
+ }
+
+ #region ISaslClient Implementation
+ //
+ // ISaslClient Implementation
+ //
+
+ public override string MechanismName
+ {
+ get { return Mechanism; }
+ }
+
+ public override bool HasInitialResponse
+ {
+ get { return false; }
+ }
+
+
+ public override byte[] EvaluateChallenge(byte[] challenge)
+ {
+ if ( challenge == null || challenge.Length == 0 )
+ throw new ArgumentNullException("challenge");
+
+
+ NameCallback nameCB = new NameCallback(AuthorizationId);
+ PasswordCallback pwdCB = new PasswordCallback();
+ ISaslCallback[] callbacks = { nameCB, pwdCB };
+ Handler.Handle(callbacks);
+
+ string username = nameCB.Text;
+
+ //Encode the Hashed Password as Hex
+ byte[] passwd = Encoding.UTF8.GetBytes(ToHex(pwdCB.HashedText));
+
+ string s = System.Text.UTF8Encoding.UTF8.GetString(challenge);
+
+ using ( HMAC hmac = new HMACMD5(passwd) )
+ {
+ byte[] value = hmac.ComputeHash(challenge);
+ string encoded = ToHex(value);
+ SetComplete();
+ return Encoding.UTF8.GetBytes(username + " " + encoded);
+ }
+ }
+
+ #endregion // ISaslClient Implementation
+
+ } // class CramMD5HashedSaslClient
+
+} // namespace Apache.Qpid.Sasl.Mechanisms
diff --git a/qpid/dotnet/Qpid.Sasl/Mechanisms/CramMD5SaslClient.cs b/qpid/dotnet/Qpid.Sasl/Mechanisms/CramMD5SaslClient.cs
new file mode 100644
index 0000000000..56b0f6ecd4
--- /dev/null
+++ b/qpid/dotnet/Qpid.Sasl/Mechanisms/CramMD5SaslClient.cs
@@ -0,0 +1,91 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+using System;
+using System.Collections;
+using System.Security.Cryptography;
+using System.Text;
+
+namespace Apache.Qpid.Sasl.Mechanisms
+{
+ /// <summary>
+ /// Implements the CRAM-MD5 authentication mechanism as outlined
+ /// in RFC 2195
+ /// </summary>
+ public class CramMD5SaslClient : SaslClient
+ {
+ public const string Mechanism = "CRAM-MD5";
+ private const int MinPwdLen = 16;
+
+ public CramMD5SaslClient(
+ string authorizationId,
+ IDictionary properties,
+ ISaslCallbackHandler handler)
+ : base(authorizationId, null, null, properties, handler)
+ {
+ }
+
+ #region ISaslClient Implementation
+ //
+ // ISaslClient Implementation
+ //
+
+ public override string MechanismName
+ {
+ get { return Mechanism; }
+ }
+
+ public override bool HasInitialResponse
+ {
+ get { return false; }
+ }
+
+ public override byte[] EvaluateChallenge(byte[] challenge)
+ {
+ if ( challenge == null || challenge.Length == 0 )
+ throw new ArgumentNullException("challenge");
+
+ NameCallback nameCB = new NameCallback(AuthorizationId);
+ PasswordCallback pwdCB = new PasswordCallback();
+ ISaslCallback[] callbacks = { nameCB, pwdCB };
+ Handler.Handle(callbacks);
+
+ string username = nameCB.Text;
+ string passwd = pwdCB.Text.PadRight(MinPwdLen, '\0');
+
+ byte[] secret = Encoding.UTF8.GetBytes(passwd);
+
+ //using ( HMAC hmac = new HMACMD5(secret) )
+ using ( MD5HMAC hmac = new MD5HMAC(secret) )
+ {
+ byte[] value = hmac.ComputeHash(challenge);
+ string encoded = ToHex(value);
+ SetComplete();
+ return Encoding.UTF8.GetBytes(username + " " + encoded);
+ }
+
+ }
+
+ #endregion // ISaslClient Implementation
+
+ } // class CramMD5SaslClient
+
+} // namespace Apache.Qpid.Sasl.Mechanisms
diff --git a/qpid/dotnet/Qpid.Sasl/Mechanisms/DigestSaslClient.cs b/qpid/dotnet/Qpid.Sasl/Mechanisms/DigestSaslClient.cs
new file mode 100644
index 0000000000..79843587c7
--- /dev/null
+++ b/qpid/dotnet/Qpid.Sasl/Mechanisms/DigestSaslClient.cs
@@ -0,0 +1,576 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+using System;
+using System.Collections;
+using System.Collections.Specialized;
+using System.Globalization;
+using System.Security.Cryptography;
+using System.Text;
+
+namespace Apache.Qpid.Sasl.Mechanisms
+{
+
+ /// <summary>
+ /// Implements the DIGEST MD5 authentication mechanism
+ /// as outlined in RFC 2831
+ /// </summary>
+ public class DigestSaslClient : SaslClient
+ {
+ public const string Mechanism = "DIGEST-MD5";
+ private static readonly MD5 _md5 = new MD5CryptoServiceProvider();
+ private int _state;
+ private string _cnonce;
+ private Encoding _encoding = Encoding.UTF8;
+
+ public string Cnonce
+ {
+ get { return _cnonce; }
+ set { _cnonce = value; }
+ }
+
+ public DigestSaslClient(
+ string authid, string serverName, string protocol,
+ IDictionary properties, ISaslCallbackHandler handler)
+ : base(authid, serverName, protocol, properties, handler)
+ {
+ _cnonce = Guid.NewGuid().ToString("N");
+ }
+
+ #region ISaslClient Implementation
+ //
+ // ISaslClient Implementation
+ //
+
+ public override string MechanismName
+ {
+ get { return Mechanism; }
+ }
+
+ public override bool HasInitialResponse
+ {
+ get { return false; }
+ }
+
+ public override byte[] EvaluateChallenge(byte[] challenge)
+ {
+ if ( challenge == null || challenge.Length <= 0 )
+ throw new ArgumentNullException("challenge");
+
+ switch ( _state++ )
+ {
+ case 0: return OnInitialChallenge(challenge);
+ case 1: return OnFinalResponse(challenge);
+ }
+ throw new SaslException("Invalid State for authentication");
+ }
+
+ #endregion // ISaslClient Implementation
+
+
+ #region Private Methods
+ //
+ // Private Methods
+ //
+
+ /// <summary>
+ /// Process the first challenge from the server
+ /// and calculate a response
+ /// </summary>
+ /// <param name="challenge">The server issued challenge</param>
+ /// <returns>Client response</returns>
+ private byte[] OnInitialChallenge(byte[] challenge)
+ {
+ DigestChallenge dch =
+ DigestChallenge.Parse(_encoding.GetString(challenge));
+ // validate input challenge
+ if ( dch.Nonce == null || dch.Nonce.Length == 0 )
+ throw new SaslException("Nonce value missing in server challenge");
+ if ( dch.Algorithm != "md5-sess" )
+ throw new SaslException("Invalid or missing algorithm value in server challenge");
+
+
+ NameCallback nameCB = new NameCallback(AuthorizationId);
+ PasswordCallback pwdCB = new PasswordCallback();
+ RealmCallback realmCB = new RealmCallback(dch.Realm);
+ ISaslCallback[] callbacks = { nameCB, pwdCB, realmCB };
+ Handler.Handle(callbacks);
+
+ DigestResponse response = new DigestResponse();
+ response.Username = nameCB.Text;
+ response.Realm = realmCB.Text;
+ response.Nonce = dch.Nonce;
+ response.Cnonce = Cnonce;
+ response.NonceCount = 1;
+ response.Qop = DigestQop.Auth; // only auth supported for now
+ response.DigestUri = Protocol.ToLower() + "/" + ServerName;
+ response.MaxBuffer = dch.MaxBuffer;
+ response.Charset = dch.Charset;
+ response.Cipher = null; // not supported for now
+ response.Authzid = AuthorizationId;
+ response.AuthParam = dch.AuthParam;
+
+ response.Response = CalculateResponse(
+ nameCB.Text, realmCB.Text, pwdCB.Text,
+ dch.Nonce, response.NonceCount, response.Qop, response.DigestUri
+ );
+
+ return _encoding.GetBytes(response.ToString());
+ }
+
+ /// <summary>
+ /// Process the second server challenge
+ /// </summary>
+ /// <param name="challenge">Server issued challenge</param>
+ /// <returns>The client response</returns>
+ private byte[] OnFinalResponse(byte[] challenge)
+ {
+ DigestChallenge dch =
+ DigestChallenge.Parse(_encoding.GetString(challenge));
+
+ if ( dch.Rspauth == null || dch.Rspauth.Length == 0 )
+ throw new SaslException("Expected 'rspauth' in server challenge not found");
+
+ SetComplete();
+ return new byte[0];
+ }
+
+
+
+ /// <summary>
+ /// Calculate the response field of the client response
+ /// </summary>
+ /// <param name="username">The user name</param>
+ /// <param name="realm">The realm</param>
+ /// <param name="passwd">The user's password</param>
+ /// <param name="nonce">Server nonce value</param>
+ /// <param name="nc">Client nonce count (always 1)</param>
+ /// <param name="qop">Quality of Protection</param>
+ /// <param name="digestUri">Digest-URI</param>
+ /// <returns>The value for the response field</returns>
+ private string CalculateResponse(
+ string username, string realm, string passwd,
+ string nonce, int nc, string qop, string digestUri
+ )
+ {
+ string a1 = CalcHexA1(username, realm, passwd, nonce);
+ string a2 = CalcHexA2(digestUri, qop);
+
+ string ncs = nc.ToString("x8", CultureInfo.InvariantCulture);
+ StringBuilder prekd = new StringBuilder();
+ prekd.Append(a1).Append(':').Append(nonce).Append(':')
+ .Append(ncs).Append(':').Append(Cnonce)
+ .Append(':').Append(qop).Append(':').Append(a2);
+
+ return ToHex(CalcH(_encoding.GetBytes(prekd.ToString())));
+ }
+
+ private string CalcHexA1(
+ string username, string realm,
+ string passwd, string nonce
+ )
+ {
+ bool hasAuthId = AuthorizationId != null && AuthorizationId.Length > 0;
+
+ string premd = username + ":" + realm + ":" + passwd;
+ byte[] temp1 = CalcH(_encoding.GetBytes(premd));
+
+
+ int a1len = 16 + 1 + nonce.Length + 1 + Cnonce.Length;
+ if ( hasAuthId )
+ a1len += 1 + AuthorizationId.Length;
+
+ byte[] buffer = new byte[a1len];
+ Array.Copy(temp1, buffer, temp1.Length);
+
+ string p2 = ":" + nonce + ":" + Cnonce;
+ if ( hasAuthId )
+ p2 += ":" + AuthorizationId;
+
+ byte[] temp2 = _encoding.GetBytes(p2);
+ Array.Copy(temp2, 0, buffer, 16, temp2.Length);
+
+ return ToHex(CalcH(buffer));
+ }
+
+ private string CalcHexA2(string digestUri, string qop)
+ {
+ string a2 = "AUTHENTICATE:" + digestUri;
+ if ( qop != DigestQop.Auth )
+ a2 += ":00000000000000000000000000000000";
+ return ToHex(CalcH(_encoding.GetBytes(a2)));
+ }
+
+ private static byte[] CalcH(byte[] value)
+ {
+ return _md5.ComputeHash(value);
+ }
+
+ #endregion // Private Methods
+
+
+ } // class DigestSaslClient
+
+
+ /// <summary>
+ /// Available QOP options in the DIGEST scheme
+ /// </summary>
+ public sealed class DigestQop
+ {
+ public const string Auth = "auth";
+ public const string AuthInt = "auth-int";
+ public const string AuthConf = "auth-conf";
+ } // class DigestQop
+
+
+ /// <summary>
+ /// Represents and parses a digest server challenge
+ /// </summary>
+ public class DigestChallenge
+ {
+ private string _realm = "localhost";
+ private string _nonce;
+ private string[] _qopOptions = { DigestQop.Auth };
+ private bool _stale;
+ private int _maxBuffer = 65536;
+ private string _charset = "ISO 8859-1";
+ private string _algorithm;
+ private string[] _cipherOptions;
+ private string _authParam;
+ private string _rspauth;
+
+ #region Properties
+ //
+ // Properties
+ //
+
+ public string Realm
+ {
+ get { return _realm; }
+ }
+
+ public string Nonce
+ {
+ get { return _nonce; }
+ }
+
+ public string[] QopOptions
+ {
+ get { return _qopOptions; }
+ }
+
+ public bool Stale
+ {
+ get { return _stale; }
+ }
+
+ public int MaxBuffer
+ {
+ get { return _maxBuffer; }
+ set { _maxBuffer = value; }
+ }
+
+ public string Charset
+ {
+ get { return _charset; }
+ }
+
+ public string Algorithm
+ {
+ get { return _algorithm; }
+ }
+
+ public string[] CipherOptions
+ {
+ get { return _cipherOptions; }
+ }
+
+ public string AuthParam
+ {
+ get { return _authParam; }
+ }
+
+ public string Rspauth
+ {
+ get { return _rspauth; }
+ }
+
+ #endregion // Properties
+
+ public static DigestChallenge Parse(string challenge)
+ {
+ DigestChallenge parsed = new DigestChallenge();
+ StringDictionary parts = ParseParameters(challenge);
+ foreach ( string optname in parts.Keys )
+ {
+ switch ( optname )
+ {
+ case "realm":
+ parsed._realm = parts[optname];
+ break;
+ case "nonce":
+ parsed._nonce = parts[optname];
+ break;
+ case "qop-options":
+ parsed._qopOptions = GetOptions(parts[optname]);
+ break;
+ case "cipher-opts":
+ parsed._cipherOptions = GetOptions(parts[optname]);
+ break;
+ case "stale":
+ parsed._stale = Convert.ToBoolean(parts[optname], CultureInfo.InvariantCulture);
+ break;
+ case "maxbuf":
+ parsed._maxBuffer = Convert.ToInt32(parts[optname], CultureInfo.InvariantCulture);
+ break;
+ case "charset":
+ parsed._charset = parts[optname];
+ break;
+ case "algorithm":
+ parsed._algorithm = parts[optname];
+ break;
+ case "auth-param":
+ parsed._authParam = parts[optname];
+ break;
+ case "rspauth":
+ parsed._rspauth = parts[optname];
+ break;
+ }
+ }
+
+ return parsed;
+ }
+
+
+ public static StringDictionary ParseParameters(string source)
+ {
+ if ( source == null )
+ throw new ArgumentNullException("source");
+
+ StringDictionary ret = new StringDictionary();
+
+ string remaining = source.Trim();
+ while ( remaining.Length > 0 )
+ {
+ int equals = remaining.IndexOf('=');
+ if ( equals < 0 )
+ break;
+
+ string optname = remaining.Substring(0, equals).Trim();
+ remaining = remaining.Substring(equals + 1);
+
+ string value = ParseQuoted(ref remaining);
+ ret[optname] = value.Trim();
+ }
+ return ret;
+ }
+
+ private static string ParseQuoted(ref string str)
+ {
+ string ns = str.TrimStart();
+
+ int start = 0;
+ bool quoted = ns[0] == '\"';
+ if ( quoted ) start++;
+ bool inquotes = quoted;
+ bool escaped = false;
+
+ int pos = start;
+ for ( ; pos < ns.Length; pos++ )
+ {
+ if ( !inquotes && ns[pos] == ',' )
+ break;
+
+ // at end of quotes?
+ if ( quoted && !escaped && ns[pos] == '\"' )
+ inquotes = false;
+ // is this char an escape for the next one?
+ escaped = inquotes && ns[pos] == '\\';
+ }
+ // pos has end of string
+ string value = ns.Substring(start, pos-start).Trim();
+ if ( quoted )
+ {
+ // remove trailing quote
+ value = value.Substring(0, value.Length - 1);
+ }
+ str = ns.Substring(pos < ns.Length-1 ? pos+1 : pos);
+ return value;
+ }
+
+ private static string[] GetOptions(string value)
+ {
+ return value.Split(' ');
+ }
+
+ } // class DigestChallenge
+
+
+ /// <summary>
+ /// Represents and knows how to write a
+ /// digest client response
+ /// </summary>
+ public class DigestResponse
+ {
+ private string _username;
+ private string _realm;
+ private string _nonce;
+ private string _cnonce;
+ private int _nonceCount;
+ private string _qop;
+ private string _digestUri;
+ private string _response;
+ private int _maxBuffer;
+ private string _charset;
+ private string _cipher;
+ private string _authzid;
+ private string _authParam;
+
+ #region Properties
+ //
+ // Properties
+ //
+
+ public string Username
+ {
+ get { return _username; }
+ set { _username = value; }
+ }
+
+ public string Realm
+ {
+ get { return _realm; }
+ set { _realm = value; }
+ }
+
+ public string Nonce
+ {
+ get { return _nonce; }
+ set { _nonce = value; }
+ }
+
+ public string Cnonce
+ {
+ get { return _cnonce; }
+ set { _cnonce = value; }
+ }
+
+ public int NonceCount
+ {
+ get { return _nonceCount; }
+ set { _nonceCount = value; }
+ }
+
+ public string Qop
+ {
+ get { return _qop; }
+ set { _qop = value; }
+ }
+
+ public string DigestUri
+ {
+ get { return _digestUri; }
+ set { _digestUri = value; }
+ }
+
+ public string Response
+ {
+ get { return _response; }
+ set { _response = value; }
+ }
+
+ public int MaxBuffer
+ {
+ get { return _maxBuffer; }
+ set { _maxBuffer = value; }
+ }
+
+ public string Charset
+ {
+ get { return _charset; }
+ set { _charset = value; }
+ }
+
+ public string Cipher
+ {
+ get { return _cipher; }
+ set { _cipher = value; }
+ }
+
+ public string Authzid
+ {
+ get { return _authzid; }
+ set { _authzid = value; }
+ }
+
+ public string AuthParam
+ {
+ get { return _authParam; }
+ set { _authParam = value; }
+ }
+
+ #endregion // Properties
+
+
+ public override string ToString()
+ {
+ StringBuilder buffer = new StringBuilder();
+ Pair(buffer, "username", Username, true);
+ Pair(buffer, "realm", Realm, true);
+ Pair(buffer, "nonce", Nonce, true);
+ Pair(buffer, "cnonce", Cnonce, true);
+ string nc = NonceCount.ToString("x8", CultureInfo.InvariantCulture);
+ Pair(buffer, "nc", nc, false);
+ Pair(buffer, "qop", Qop, false);
+ Pair(buffer, "digest-uri", DigestUri, true);
+ Pair(buffer, "response", Response, true);
+ string maxBuffer = MaxBuffer.ToString(CultureInfo.InvariantCulture);
+ Pair(buffer, "maxbuf", maxBuffer, false);
+ Pair(buffer, "charset", Charset, false);
+ Pair(buffer, "cipher", Cipher, false);
+ Pair(buffer, "authzid", Authzid, true);
+ Pair(buffer, "auth-param", AuthParam, true);
+
+ return buffer.ToString().TrimEnd(',');
+ }
+
+ private static void Pair(StringBuilder buffer, string name, string value, bool quoted)
+ {
+ if ( value != null && value.Length > 0 )
+ {
+ buffer.Append(name);
+ buffer.Append('=');
+ if ( quoted )
+ {
+ buffer.Append('\"');
+ buffer.Append(value.Replace("\"", "\\\""));
+ buffer.Append('\"');
+ } else
+ {
+ buffer.Append(value);
+ }
+ buffer.Append(',');
+ }
+ }
+
+ } // class DigestResponse
+
+} // namespace Apache.Qpid.Sasl.Mechanisms
diff --git a/qpid/dotnet/Qpid.Sasl/Mechanisms/ExternalSaslClient.cs b/qpid/dotnet/Qpid.Sasl/Mechanisms/ExternalSaslClient.cs
new file mode 100644
index 0000000000..fec0d2d3c2
--- /dev/null
+++ b/qpid/dotnet/Qpid.Sasl/Mechanisms/ExternalSaslClient.cs
@@ -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.
+ *
+ */
+
+using System;
+using System.Collections;
+using System.Text;
+
+namespace Apache.Qpid.Sasl.Mechanisms
+{
+ /// <summary>
+ /// Implements the EXTERNAL authentication mechanism
+ /// as outlined in RFC 2222
+ /// </summary>
+ public class ExternalSaslClient : SaslClient
+ {
+ public const string Mechanism = "EXTERNAL";
+
+ public ExternalSaslClient(
+ string authid, IDictionary properties,
+ ISaslCallbackHandler handler)
+ : base(authid, null, null, properties, handler)
+ {
+ }
+
+ #region ISaslClient Implementation
+ //
+ // ISaslClient Implementation
+ //
+
+ public override string MechanismName
+ {
+ get { return Mechanism; }
+ }
+
+ public override bool HasInitialResponse
+ {
+ get { return true; }
+ }
+
+ public override byte[] EvaluateChallenge(byte[] challenge)
+ {
+ // ignore challenge
+ SetComplete();
+ return Encoding.UTF8.GetBytes(AuthorizationId);
+ }
+
+ #endregion // ISaslClient Implementation
+
+ } // class ExternalSaslClient
+
+} // namespace Apache.Qpid.Sasl.Mechanisms
diff --git a/qpid/dotnet/Qpid.Sasl/Mechanisms/PlainSaslClient.cs b/qpid/dotnet/Qpid.Sasl/Mechanisms/PlainSaslClient.cs
new file mode 100644
index 0000000000..534be171b7
--- /dev/null
+++ b/qpid/dotnet/Qpid.Sasl/Mechanisms/PlainSaslClient.cs
@@ -0,0 +1,81 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+using System;
+using System.Collections;
+using System.Text;
+
+namespace Apache.Qpid.Sasl.Mechanisms
+{
+
+ /// <summary>
+ /// Implements the PLAIN authentication mechanism
+ /// as outlined in RFC 4616
+ /// </summary>
+ public class PlainSaslClient : SaslClient
+ {
+ public const string Mechanism = "PLAIN";
+
+ public PlainSaslClient(
+ string authid, IDictionary properties,
+ ISaslCallbackHandler handler)
+ : base(authid, null, null, properties, handler)
+ {
+ }
+
+ #region ISaslClient Implementation
+ //
+ // ISaslClient Implementation
+ //
+
+ public override string MechanismName
+ {
+ get { return Mechanism; }
+ }
+
+ public override bool HasInitialResponse
+ {
+ get { return true; }
+ }
+
+ public override byte[] EvaluateChallenge(byte[] challenge)
+ {
+ // ignore challenge
+
+ NameCallback nameCB = new NameCallback();
+ PasswordCallback pwdCB = new PasswordCallback();
+ ISaslCallback[] callbacks = { nameCB, pwdCB };
+ Handler.Handle(callbacks);
+
+ string username = nameCB.Text;
+ string authid = AuthorizationId;
+ string passwd = pwdCB.Text;
+
+ string response =
+ string.Format("{0}\0{1}\0{2}", authid, username, passwd);
+ SetComplete();
+ return Encoding.UTF8.GetBytes(response);
+ }
+
+ #endregion // ISaslClient Implementation
+
+ } // class PlainSaslClient
+} // namespace Apache.Qpid.Sasl.Mechanisms
diff --git a/qpid/dotnet/Qpid.Sasl/Properties/AssemblyInfo.cs b/qpid/dotnet/Qpid.Sasl/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000000..5245b97d1f
--- /dev/null
+++ b/qpid/dotnet/Qpid.Sasl/Properties/AssemblyInfo.cs
@@ -0,0 +1,57 @@
+/*
+ *
+ * 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.
+ *
+ */
+using System;
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("Apache.Qpid.Sasl")]
+[assembly: AssemblyDescription("Built from svn revision number: ")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Apache Software Foundation")]
+[assembly: AssemblyProduct("Apache.Qpid.Sasl")]
+[assembly: AssemblyCopyright("Apache Software Foundation")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("27ea23e4-6f84-4a54-8f1f-5725e6d767cc")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Revision and Build Numbers
+// by using the '*' as shown below:
+[assembly: AssemblyVersion("0.5.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
+[assembly: CLSCompliant(true)]
diff --git a/qpid/dotnet/Qpid.Sasl/Qpid.Sasl.csproj b/qpid/dotnet/Qpid.Sasl/Qpid.Sasl.csproj
new file mode 100644
index 0000000000..8c1d568aa3
--- /dev/null
+++ b/qpid/dotnet/Qpid.Sasl/Qpid.Sasl.csproj
@@ -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.
+
+-->
+
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProductVersion>8.0.50727</ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{1465B0EE-6452-42A6-AB73-B2F9EABEEE75}</ProjectGuid>
+ <OutputType>Library</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>Apache.Qpid.Sasl</RootNamespace>
+ <AssemblyName>Apache.Qpid.Sasl</AssemblyName>
+ <FileUpgradeFlags>
+ </FileUpgradeFlags>
+ <OldToolsVersion>2.0</OldToolsVersion>
+ <UpgradeBackupLocation>
+ </UpgradeBackupLocation>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>..\bin\net-2.0\debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ <UseVSHostingProcess>true</UseVSHostingProcess>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="System" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="**\*.cs" />
+ </ItemGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+ <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
+ Other similar extension points exist, see Microsoft.Common.targets.
+ <Target Name="BeforeBuild">
+ </Target>
+ <Target Name="AfterBuild">
+ </Target>
+ -->
+</Project>
diff --git a/qpid/dotnet/Qpid.Sasl/Sasl.cs b/qpid/dotnet/Qpid.Sasl/Sasl.cs
new file mode 100644
index 0000000000..2f7bacb939
--- /dev/null
+++ b/qpid/dotnet/Qpid.Sasl/Sasl.cs
@@ -0,0 +1,115 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+using System;
+using System.Collections;
+using System.Configuration;
+using System.Text;
+
+using Apache.Qpid.Sasl.Configuration;
+
+namespace Apache.Qpid.Sasl
+{
+ /// <summary>
+ /// Static class used to access the SASL functionality.
+ /// The core SASL mechanism is described in RFC 2222.
+ /// </summary>
+ /// <remarks>
+ /// Only client side mechanisms are implemented.
+ /// <para>
+ /// New client side factories can be added programatically using the
+ /// RegisterClientFactory method, or through the application
+ /// configuration file, like this:
+ /// </para>
+ /// <example><![CDATA[
+ /// <configuration>
+ /// <configSections>
+ /// <section name="qpid.sasl" type="Apache.Qpid.Sasl.Configuration.SaslConfigurationSectionHandler, Apache.Qpid.Sasl"/>
+ /// </configSections>
+ ///
+ /// <qpid.sasl>
+ /// <clientFactories>
+ /// <add type="Apache.Qpid.Sasl.Tests.TestClientFactory, Apache.Qpid.Sasl.Tests"/>
+ /// </clientFactories>
+ /// </qpid.sasl>
+ /// </configuration>
+ /// ]]></example>
+ /// </remarks>
+ public sealed class Sasl
+ {
+ private static IList _clientFactories;
+
+
+ static Sasl()
+ {
+ SaslConfiguration config = SaslConfiguration.GetConfiguration();
+ _clientFactories = config.ClientFactories;
+ }
+ private Sasl()
+ {
+ }
+
+ public static ISaslClient CreateClient(
+ string[] mechanisms, string authorizationId,
+ string protocol, string serverName,
+ IDictionary props, ISaslCallbackHandler handler
+ )
+ {
+ ISaslClientFactory factory = FindFactory(mechanisms, props);
+ if ( factory == null )
+ return null;
+
+ return factory.CreateClient (
+ mechanisms, authorizationId,
+ protocol, serverName, props, handler
+ );
+ }
+
+ public static void RegisterClientFactory(ISaslClientFactory factory)
+ {
+ lock ( _clientFactories )
+ {
+ _clientFactories.Add(factory);
+ }
+ }
+
+ private static ISaslClientFactory FindFactory(string[] mechanisms, IDictionary props)
+ {
+ lock ( _clientFactories )
+ {
+ foreach ( ISaslClientFactory factory in _clientFactories )
+ {
+ string[] mechs = factory.GetSupportedMechanisms(props);
+ foreach ( string m1 in mechs )
+ {
+ foreach (string m2 in mechanisms )
+ {
+ if ( m1 == m2 )
+ return factory;
+ }
+ }
+ }
+ return null;
+ }
+ }
+ } // class Sasl
+
+} // namespace Apache.Qpid.Sasl.Mechanisms
diff --git a/qpid/dotnet/Qpid.Sasl/SaslClient.cs b/qpid/dotnet/Qpid.Sasl/SaslClient.cs
new file mode 100644
index 0000000000..a22013181b
--- /dev/null
+++ b/qpid/dotnet/Qpid.Sasl/SaslClient.cs
@@ -0,0 +1,145 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+using System;
+using System.Collections;
+using System.Globalization;
+using System.Text;
+
+namespace Apache.Qpid.Sasl
+{
+ public abstract class SaslClient : ISaslClient
+ {
+ private bool _isComplete;
+ private IDictionary _properties;
+ private string _authorizationId;
+ private string _serverName;
+ private string _protocol;
+ private ISaslCallbackHandler _handler;
+
+ protected string AuthorizationId
+ {
+ get { return _authorizationId; }
+ }
+ protected string ServerName
+ {
+ get { return _serverName; }
+ }
+
+ protected string Protocol
+ {
+ get { return _protocol; }
+ }
+
+ protected ISaslCallbackHandler Handler
+ {
+ get { return _handler; }
+ }
+
+ protected IDictionary Properties
+ {
+ get { return _properties; }
+ }
+
+ protected SaslClient(
+ string authid, string serverName,
+ string protocol, IDictionary properties,
+ ISaslCallbackHandler handler)
+ {
+ if ( properties == null )
+ throw new ArgumentNullException("properties");
+ if ( handler == null )
+ throw new ArgumentNullException("handler");
+
+ _authorizationId = authid==null ? "" : authid;
+ _serverName = serverName;
+ _protocol = protocol;
+ _properties = properties;
+ _handler = handler;
+
+ if ( _serverName == null || _serverName.Length == 0 )
+ {
+ _serverName = System.Net.Dns.GetHostName();
+ }
+ }
+
+
+
+
+ #region ISaslClient Implementation
+ //
+ // ISaslClient Implementation
+ //
+
+ public abstract string MechanismName { get; }
+
+ public abstract bool HasInitialResponse { get; }
+
+ public bool IsComplete
+ {
+ get { return _isComplete; }
+ }
+
+ public abstract byte[] EvaluateChallenge(byte[] challenge);
+
+ public virtual object GetNegotiatedProperty(string propName)
+ {
+ return null;
+ }
+
+ public virtual byte[] Unwrap(byte[] buffer, int offset, int length)
+ {
+ throw new NotImplementedException();
+ }
+
+ public virtual byte[] Wrap(byte[] buffer, int offset, int lenght)
+ {
+ throw new NotImplementedException();
+ }
+
+ #endregion // ISaslClient Implementation
+
+
+ #region Helper Methods
+ //
+ // Helper Methods
+ //
+
+ protected void SetComplete()
+ {
+ _isComplete = true;
+ }
+
+ protected static string ToHex(byte[] buffer)
+ {
+ StringBuilder builder = new StringBuilder();
+ foreach ( byte b in buffer )
+ {
+ builder.Append(b.ToString("x2", CultureInfo.InvariantCulture));
+ }
+ return builder.ToString();
+ }
+
+ #endregion // Helper Methods
+
+ } // class SaslClient
+
+} // namespace Apache.Qpid.Sasl.Mechanisms
diff --git a/qpid/dotnet/Qpid.Sasl/SaslException.cs b/qpid/dotnet/Qpid.Sasl/SaslException.cs
new file mode 100644
index 0000000000..d770ee63fd
--- /dev/null
+++ b/qpid/dotnet/Qpid.Sasl/SaslException.cs
@@ -0,0 +1,56 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+using System;
+using System.Collections;
+using System.Runtime.Serialization;
+using System.Text;
+
+namespace Apache.Qpid.Sasl
+{
+ /// <summary>
+ /// Reports an exception during the processing of an SASL
+ /// Operation. Only used for authentication-relared errors
+ /// </summary>
+ [Serializable]
+ public class SaslException : Exception
+ {
+ public SaslException()
+ {
+ }
+
+ public SaslException(string message)
+ : base(message)
+ {
+ }
+ public SaslException(string message, Exception innerException)
+ : base(message, innerException)
+ {
+ }
+
+ protected SaslException(SerializationInfo info, StreamingContext ctxt)
+ : base(info, ctxt)
+ {
+ }
+
+ } // class SaslException
+
+} // namespace Apache.Qpid.Sasl.Mechanisms
diff --git a/qpid/dotnet/Qpid.Sasl/SaslProperties.cs b/qpid/dotnet/Qpid.Sasl/SaslProperties.cs
new file mode 100644
index 0000000000..f9ad1c68cd
--- /dev/null
+++ b/qpid/dotnet/Qpid.Sasl/SaslProperties.cs
@@ -0,0 +1,42 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+using System;
+using System.Collections;
+using System.Text;
+
+namespace Apache.Qpid.Sasl
+{
+ public sealed class SaslProperties
+ {
+ public const string PolicyNoPlainText = "NOPLAINTEXT";
+ public const string PolicyNoActive = "NOACTIVE";
+ public const string PolicyNoDictionary = "NODICTIONARY";
+ public const string PolicyNoAnonymous = "NOANONYMOUS";
+ public const string PolicyForwardSecrecy = "FORWARD_SECRECY";
+ public const string PolicyPassCredentials = "PASS_CREDENTIALS";
+
+ public const string Qop = "QOP";
+ public const string Strength = "STRENGTH";
+
+ } // class SaslProperties
+
+} // namespace Apache.Qpid.Sasl.Mechanisms
diff --git a/qpid/dotnet/Qpid.Sasl/default.build b/qpid/dotnet/Qpid.Sasl/default.build
new file mode 100644
index 0000000000..57049ee2ee
--- /dev/null
+++ b/qpid/dotnet/Qpid.Sasl/default.build
@@ -0,0 +1,45 @@
+<?xml version="1.0"?>
+<!--
+
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+
+-->
+
+<project name="Apache.Qpid.Sasl" default="build">
+ <!--
+ Properties that come from master build file
+ - build.dir: root directory for build
+ - build.debug: true if building debug release
+ - build.defines: variables to define during build
+ -->
+
+ <target name="build">
+ <csc target="library"
+ define="${build.defines}"
+ debug="${build.debug}"
+ output="${build.dir}/${project::get-name()}.dll">
+
+ <sources>
+ <include name="**/*.cs" />
+ </sources>
+ <references>
+ </references>
+ </csc>
+ </target>
+</project>
+
diff --git a/qpid/dotnet/README.txt b/qpid/dotnet/README.txt
new file mode 100644
index 0000000000..0199ad6410
--- /dev/null
+++ b/qpid/dotnet/README.txt
@@ -0,0 +1,68 @@
+Info
+====
+
+There are two separate .NET clients: one that implements AMQP 0-8 (and
+can communicate with the Java broker) and another that implements
+0-10 (and can communicate with the C++ broker).
+
+This README contains instructions for building the 0-8 client.
+
+Instructions for building and installing the 0-10 client are located in client-010/README.txt.
+
+Setup
+=====
+
+Essential:
+
+ .NET 2.0 or later
+ Ant 1.6.5 (Java build tool, http://ant.apache.org)
+
+Either:
+ NAnt 0.85 - only required for builds outside Visual Studio
+OR
+ Microsoft Visual Studio 2008 (VS2008)
+
+Ensure that your PATH includes ant, e.g.:
+
+ $ PATH=c:\java\ant\bin:%PATH%
+
+If using nant, set up PATH to include Nant.exe, e.g.:
+
+ $ set PATH=C:\dotnet\nant\bin;%PATH%
+
+If using msbuild, it is recommended to use a "Visual Studio Command Prompt"
+
+Building
+========
+
+Generate framing from /Qpid.Common/amqp.xml specification file by running this script:
+
+ $ build-framing.bat
+
+Alternatively, just switch to /Qpid.Common and run "ant" there.
+
+You can build from Visual Studio 2008 or from the command-line by running msbuild.
+
+The script build-msbuild.bat provides some standard options to do a full build.
+
+If you are using nant, the script build-nant.bat contains standard arguments that do a full build.
+
+To build for Mono on Linux (to bin/mono-2.0) the build-mono shell script is provided.
+
+Releasing
+=========
+
+nant can be used to create a release zip archive. A script is provided:
+
+For .NET 2.0
+
+ $ release net-2.0
+
+Generates ./bin/net-2.0/release/Qpid.NET-net-2.0-yyyyMMdd.zip
+
+For Mono
+
+ $ release mono-2.0
+
+Generates ./bin/mono-2.0/release/Qpid.NET-mono-2.0-yyyyMMdd.zip
+
diff --git a/qpid/dotnet/RELEASE_NOTES.txt b/qpid/dotnet/RELEASE_NOTES.txt
new file mode 100644
index 0000000000..e824757b42
--- /dev/null
+++ b/qpid/dotnet/RELEASE_NOTES.txt
@@ -0,0 +1,11 @@
+Apache Qpid .NET 0.8 Release Notes
+-------------------------------------------
+
+The Qpid 0.8 release contains seperate clients that support the AMQP
+0-10 and AMQP 0-8 protocols.
+
+Known Issues/Outstanding Work
+-----------------------------
+
+You can view the outstanding task list for Qpid by visiting our JIRA:
+http://issues.apache.org/jira/browse/QPID
diff --git a/qpid/dotnet/TestClient/Program.cs b/qpid/dotnet/TestClient/Program.cs
new file mode 100644
index 0000000000..f4b2db568e
--- /dev/null
+++ b/qpid/dotnet/TestClient/Program.cs
@@ -0,0 +1,30 @@
+/*
+ *
+ * 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.
+ *
+ */
+namespace TopicListener
+{
+ class Program
+ {
+ static void Main(string[] args)
+ {
+ Apache.Qpid.Integration.Tests.interop.TestClient.Main(args);
+ }
+ }
+}
diff --git a/qpid/dotnet/TestClient/Properties/AssemblyInfo.cs b/qpid/dotnet/TestClient/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000000..e8ffbc5aba
--- /dev/null
+++ b/qpid/dotnet/TestClient/Properties/AssemblyInfo.cs
@@ -0,0 +1,53 @@
+/*
+ *
+ * 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.
+ *
+ */
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("TestClient")]
+[assembly: AssemblyDescription("Built from svn revision number: ")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Apache Software Foundation")]
+[assembly: AssemblyProduct("TestClient")]
+[assembly: AssemblyCopyright("Apache Software Foundation")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("1c2db1cd-239f-495a-b6b4-c815ea534489")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+[assembly: AssemblyVersion("0.5.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/qpid/dotnet/TestClient/TestClient.csproj b/qpid/dotnet/TestClient/TestClient.csproj
new file mode 100644
index 0000000000..cc7ab37657
--- /dev/null
+++ b/qpid/dotnet/TestClient/TestClient.csproj
@@ -0,0 +1,115 @@
+<!--
+
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+
+-->
+
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProductVersion>9.0.30729</ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{6E0374D9-99BE-4D4F-B41D-B227E37E04C6}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>TestClient</RootNamespace>
+ <AssemblyName>TestClient</AssemblyName>
+ <FileUpgradeFlags>
+ </FileUpgradeFlags>
+ <OldToolsVersion>2.0</OldToolsVersion>
+ <UpgradeBackupLocation>
+ </UpgradeBackupLocation>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>..\bin\net-2.0\debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>..\bin\net-2.0\release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="System" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="Program.cs" />
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\Qpid.Buffer.Tests\Qpid.Buffer.Tests.csproj">
+ <Project>{74640962-99D0-4D06-B57A-9CD66517CF52}</Project>
+ <Name>Qpid.Buffer.Tests</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\Qpid.Buffer\Qpid.Buffer.csproj">
+ <Project>{44384DF2-B0A4-4580-BDBC-EE4BAA87D995}</Project>
+ <Name>Qpid.Buffer</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\Qpid.Client.Tests\Qpid.Client.Tests.csproj">
+ <Project>{BA1B0032-4CE6-40DD-A2DC-119F0FFA0A1D}</Project>
+ <Name>Qpid.Client.Tests</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\Qpid.Client\Qpid.Client.csproj">
+ <Project>{68987C05-3768-452C-A6FC-6BA1D372852F}</Project>
+ <Name>Qpid.Client</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\Qpid.Codec\Qpid.Codec.csproj">
+ <Project>{22D0D0C2-77AF-4DE3-B456-7FF3893F9F88}</Project>
+ <Name>Qpid.Codec</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\Qpid.Common.Tests\Qpid.Common.Tests.csproj">
+ <Project>{F83624B0-762B-4D82-900D-FF4C1B36E36E}</Project>
+ <Name>Qpid.Common.Tests</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\Qpid.Common\Qpid.Common.csproj">
+ <Project>{77064C42-24D2-4CEB-9EA2-0EF481A43205}</Project>
+ <Name>Qpid.Common</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\Qpid.Messaging\Qpid.Messaging.csproj">
+ <Project>{6688F826-C58E-4C1B-AA1F-22AFAB4B7D07}</Project>
+ <Name>Qpid.Messaging</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\Qpid.Sasl.Tests\Qpid.Sasl.Tests.csproj">
+ <Project>{587B3520-EBB9-41ED-B019-E96116B651CE}</Project>
+ <Name>Qpid.Sasl.Tests</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\Qpid.Sasl\Qpid.Sasl.csproj">
+ <Project>{1465B0EE-6452-42A6-AB73-B2F9EABEEE75}</Project>
+ <Name>Qpid.Sasl</Name>
+ </ProjectReference>
+ </ItemGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+ <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
+ Other similar extension points exist, see Microsoft.Common.targets.
+ <Target Name="BeforeBuild">
+ </Target>
+ <Target Name="AfterBuild">
+ </Target>
+ -->
+</Project>
diff --git a/qpid/dotnet/TestClient/default.build b/qpid/dotnet/TestClient/default.build
new file mode 100644
index 0000000000..ce1114425e
--- /dev/null
+++ b/qpid/dotnet/TestClient/default.build
@@ -0,0 +1,47 @@
+<?xml version="1.0"?>
+<!--
+
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+
+-->
+
+<project name="TestClient" default="build">
+ <!--
+ Properties that come from master build file
+ - build.dir: root directory for build
+ - build.debug: true if building debug release
+ - build.defines: variables to define during build
+ -->
+
+ <target name="build">
+ <csc target="exe"
+ define="${build.defines}"
+ debug="${build.debug}"
+ unsafe="true"
+ output="${build.dir}/${project::get-name()}.exe">
+
+ <sources>
+ <include name="**/*.cs" />
+ </sources>
+ <references>
+ <include name="${build.dir}\Apache.Qpid.Integration.Tests.dll"/>
+ </references>
+ </csc>
+ </target>
+</project>
+
diff --git a/qpid/dotnet/TopicListener/Program.cs b/qpid/dotnet/TopicListener/Program.cs
new file mode 100644
index 0000000000..14626d6134
--- /dev/null
+++ b/qpid/dotnet/TopicListener/Program.cs
@@ -0,0 +1,30 @@
+/*
+ *
+ * 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.
+ *
+ */
+namespace TopicListener
+{
+ class Program
+ {
+ static void Main(string[] args)
+ {
+ Apache.Qpid.Client.Tests.interop.TopicListener.Main(args);
+ }
+ }
+}
diff --git a/qpid/dotnet/TopicListener/Properties/AssemblyInfo.cs b/qpid/dotnet/TopicListener/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000000..1fe9bb8249
--- /dev/null
+++ b/qpid/dotnet/TopicListener/Properties/AssemblyInfo.cs
@@ -0,0 +1,53 @@
+/*
+ *
+ * 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.
+ *
+ */
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("TopicListener")]
+[assembly: AssemblyDescription("Built from svn revision number: ")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Apache Software Foundation")]
+[assembly: AssemblyProduct("TopicListener")]
+[assembly: AssemblyCopyright("Apache Software Foundation")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("1c2db1cd-239f-495a-b6b4-c815ea534489")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+[assembly: AssemblyVersion("0.5.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/qpid/dotnet/TopicListener/TopicListener.csproj b/qpid/dotnet/TopicListener/TopicListener.csproj
new file mode 100644
index 0000000000..46da42ea61
--- /dev/null
+++ b/qpid/dotnet/TopicListener/TopicListener.csproj
@@ -0,0 +1,115 @@
+<!--
+
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+
+-->
+
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProductVersion>8.0.50727</ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{9A112DF2-146F-4CF4-919B-9D3BE7D088E9}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>TopicListener</RootNamespace>
+ <AssemblyName>TopicListener</AssemblyName>
+ <FileUpgradeFlags>
+ </FileUpgradeFlags>
+ <OldToolsVersion>2.0</OldToolsVersion>
+ <UpgradeBackupLocation>
+ </UpgradeBackupLocation>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>..\bin\net-2.0\debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>..\bin\net-2.0\release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="System" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="Program.cs" />
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\Qpid.Buffer.Tests\Qpid.Buffer.Tests.csproj">
+ <Project>{74640962-99D0-4D06-B57A-9CD66517CF52}</Project>
+ <Name>Qpid.Buffer.Tests</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\Qpid.Buffer\Qpid.Buffer.csproj">
+ <Project>{44384DF2-B0A4-4580-BDBC-EE4BAA87D995}</Project>
+ <Name>Qpid.Buffer</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\Qpid.Client.Tests\Qpid.Client.Tests.csproj">
+ <Project>{BA1B0032-4CE6-40DD-A2DC-119F0FFA0A1D}</Project>
+ <Name>Qpid.Client.Tests</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\Qpid.Client\Qpid.Client.csproj">
+ <Project>{68987C05-3768-452C-A6FC-6BA1D372852F}</Project>
+ <Name>Qpid.Client</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\Qpid.Codec\Qpid.Codec.csproj">
+ <Project>{22D0D0C2-77AF-4DE3-B456-7FF3893F9F88}</Project>
+ <Name>Qpid.Codec</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\Qpid.Common.Tests\Qpid.Common.Tests.csproj">
+ <Project>{F83624B0-762B-4D82-900D-FF4C1B36E36E}</Project>
+ <Name>Qpid.Common.Tests</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\Qpid.Common\Qpid.Common.csproj">
+ <Project>{77064C42-24D2-4CEB-9EA2-0EF481A43205}</Project>
+ <Name>Qpid.Common</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\Qpid.Messaging\Qpid.Messaging.csproj">
+ <Project>{6688F826-C58E-4C1B-AA1F-22AFAB4B7D07}</Project>
+ <Name>Qpid.Messaging</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\Qpid.Sasl.Tests\Qpid.Sasl.Tests.csproj">
+ <Project>{587B3520-EBB9-41ED-B019-E96116B651CE}</Project>
+ <Name>Qpid.Sasl.Tests</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\Qpid.Sasl\Qpid.Sasl.csproj">
+ <Project>{1465B0EE-6452-42A6-AB73-B2F9EABEEE75}</Project>
+ <Name>Qpid.Sasl</Name>
+ </ProjectReference>
+ </ItemGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+ <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
+ Other similar extension points exist, see Microsoft.Common.targets.
+ <Target Name="BeforeBuild">
+ </Target>
+ <Target Name="AfterBuild">
+ </Target>
+ -->
+</Project>
diff --git a/qpid/dotnet/TopicListener/default.build b/qpid/dotnet/TopicListener/default.build
new file mode 100644
index 0000000000..f9b0f97094
--- /dev/null
+++ b/qpid/dotnet/TopicListener/default.build
@@ -0,0 +1,47 @@
+<?xml version="1.0"?>
+<!--
+
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+
+-->
+
+<project name="TopicListener" default="build">
+ <!--
+ Properties that come from master build file
+ - build.dir: root directory for build
+ - build.debug: true if building debug release
+ - build.defines: variables to define during build
+ -->
+
+ <target name="build">
+ <csc target="exe"
+ define="${build.defines}"
+ debug="${build.debug}"
+ unsafe="true"
+ output="${build.dir}/${project::get-name()}.exe">
+
+ <sources>
+ <include name="**/*.cs" />
+ </sources>
+ <references>
+ <include name="${build.dir}\Apache.Qpid.Client.Tests.dll"/>
+ </references>
+ </csc>
+ </target>
+</project>
+
diff --git a/qpid/dotnet/TopicPublisher/Program.cs b/qpid/dotnet/TopicPublisher/Program.cs
new file mode 100644
index 0000000000..b5209b9317
--- /dev/null
+++ b/qpid/dotnet/TopicPublisher/Program.cs
@@ -0,0 +1,30 @@
+/*
+ *
+ * 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.
+ *
+ */
+namespace TopicPublisher
+{
+ class Program
+ {
+ static void Main(string[] args)
+ {
+ Apache.Qpid.Client.Tests.interop.TopicPublisher.Main(args);
+ }
+ }
+}
diff --git a/qpid/dotnet/TopicPublisher/Properties/AssemblyInfo.cs b/qpid/dotnet/TopicPublisher/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000000..051b34ee37
--- /dev/null
+++ b/qpid/dotnet/TopicPublisher/Properties/AssemblyInfo.cs
@@ -0,0 +1,53 @@
+/*
+ *
+ * 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.
+ *
+ */
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("TopicPublisher")]
+[assembly: AssemblyDescription("Built from svn revision number: ")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Apache Software Foundation")]
+[assembly: AssemblyProduct("TopicPublisher")]
+[assembly: AssemblyCopyright("Apache Software Foundation")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("93fa1c32-c0f8-47e5-b167-dc581e33eb9b")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+[assembly: AssemblyVersion("0.5.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/qpid/dotnet/TopicPublisher/TopicPublisher.csproj b/qpid/dotnet/TopicPublisher/TopicPublisher.csproj
new file mode 100644
index 0000000000..fbbf77fb8e
--- /dev/null
+++ b/qpid/dotnet/TopicPublisher/TopicPublisher.csproj
@@ -0,0 +1,111 @@
+<!--
+
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+
+-->
+
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProductVersion>8.0.50727</ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{A06C9FFD-22FF-4654-856D-897C230978AF}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>TopicPublisher</RootNamespace>
+ <AssemblyName>TopicPublisher</AssemblyName>
+ <FileUpgradeFlags>
+ </FileUpgradeFlags>
+ <OldToolsVersion>2.0</OldToolsVersion>
+ <UpgradeBackupLocation>
+ </UpgradeBackupLocation>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>..\bin\net-2.0\debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>..\bin\net-2.0\release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="System" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="Program.cs" />
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\Qpid.Buffer\Qpid.Buffer.csproj">
+ <Project>{44384DF2-B0A4-4580-BDBC-EE4BAA87D995}</Project>
+ <Name>Qpid.Buffer</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\Qpid.Client.Tests\Qpid.Client.Tests.csproj">
+ <Project>{BA1B0032-4CE6-40DD-A2DC-119F0FFA0A1D}</Project>
+ <Name>Qpid.Client.Tests</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\Qpid.Client\Qpid.Client.csproj">
+ <Project>{68987C05-3768-452C-A6FC-6BA1D372852F}</Project>
+ <Name>Qpid.Client</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\Qpid.Codec\Qpid.Codec.csproj">
+ <Project>{22D0D0C2-77AF-4DE3-B456-7FF3893F9F88}</Project>
+ <Name>Qpid.Codec</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\Qpid.Common.Tests\Qpid.Common.Tests.csproj">
+ <Project>{F83624B0-762B-4D82-900D-FF4C1B36E36E}</Project>
+ <Name>Qpid.Common.Tests</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\Qpid.Common\Qpid.Common.csproj">
+ <Project>{77064C42-24D2-4CEB-9EA2-0EF481A43205}</Project>
+ <Name>Qpid.Common</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\Qpid.Messaging\Qpid.Messaging.csproj">
+ <Project>{6688F826-C58E-4C1B-AA1F-22AFAB4B7D07}</Project>
+ <Name>Qpid.Messaging</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\Qpid.Sasl.Tests\Qpid.Sasl.Tests.csproj">
+ <Project>{587B3520-EBB9-41ED-B019-E96116B651CE}</Project>
+ <Name>Qpid.Sasl.Tests</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\Qpid.Sasl\Qpid.Sasl.csproj">
+ <Project>{1465B0EE-6452-42A6-AB73-B2F9EABEEE75}</Project>
+ <Name>Qpid.Sasl</Name>
+ </ProjectReference>
+ </ItemGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+ <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
+ Other similar extension points exist, see Microsoft.Common.targets.
+ <Target Name="BeforeBuild">
+ </Target>
+ <Target Name="AfterBuild">
+ </Target>
+ -->
+</Project>
diff --git a/qpid/dotnet/TopicPublisher/default.build b/qpid/dotnet/TopicPublisher/default.build
new file mode 100644
index 0000000000..9b01c2a1bc
--- /dev/null
+++ b/qpid/dotnet/TopicPublisher/default.build
@@ -0,0 +1,47 @@
+<?xml version="1.0"?>
+<!--
+
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+
+-->
+
+<project name="TopicPublisher" default="build">
+ <!--
+ Properties that come from master build file
+ - build.dir: root directory for build
+ - build.debug: true if building debug release
+ - build.defines: variables to define during build
+ -->
+
+ <target name="build">
+ <csc target="exe"
+ define="${build.defines}"
+ debug="${build.debug}"
+ unsafe="true"
+ output="${build.dir}/${project::get-name()}.exe">
+
+ <sources>
+ <include name="**/*.cs" />
+ </sources>
+ <references>
+ <include name="${build.dir}\Apache.Qpid.Client.Tests.dll"/>
+ </references>
+ </csc>
+ </target>
+</project>
+
diff --git a/qpid/dotnet/build-framing.bat b/qpid/dotnet/build-framing.bat
new file mode 100644
index 0000000000..ae9bc749a9
--- /dev/null
+++ b/qpid/dotnet/build-framing.bat
@@ -0,0 +1,23 @@
+@REM
+@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
+
+cd Qpid.Common
+ant
diff --git a/qpid/dotnet/build-mono b/qpid/dotnet/build-mono
new file mode 100755
index 0000000000..2bb6147b53
--- /dev/null
+++ b/qpid/dotnet/build-mono
@@ -0,0 +1,21 @@
+#!/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.
+#
+
+nant -t:mono-2.0
diff --git a/qpid/dotnet/build-msbuild.bat b/qpid/dotnet/build-msbuild.bat
new file mode 100644
index 0000000000..1fe4b5d64c
--- /dev/null
+++ b/qpid/dotnet/build-msbuild.bat
@@ -0,0 +1,22 @@
+@REM
+@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
+
+MSBuild.exe Qpid.NET.sln /p:Configuration=Release /t:rebuild
diff --git a/qpid/dotnet/build-nant-release b/qpid/dotnet/build-nant-release
new file mode 100755
index 0000000000..611a1efe08
--- /dev/null
+++ b/qpid/dotnet/build-nant-release
@@ -0,0 +1,55 @@
+#
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+#
+
+#!/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.
+#
+#
+
+
+Usage()
+{
+ echo "usage: $0 net-2.0|mono-2.0"
+ exit 2
+}
+
+if [[ $# -ne 1 ]]; then
+ Usage
+fi
+
+nant -t:$1 release-pkg -D:build.config=release
diff --git a/qpid/dotnet/build-nant.bat b/qpid/dotnet/build-nant.bat
new file mode 100644
index 0000000000..785450a9f7
--- /dev/null
+++ b/qpid/dotnet/build-nant.bat
@@ -0,0 +1,22 @@
+@REM
+@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
+
+nant -t:net-2.0
diff --git a/qpid/dotnet/client-010/App.config b/qpid/dotnet/client-010/App.config
new file mode 100644
index 0000000000..36b4ffab3e
--- /dev/null
+++ b/qpid/dotnet/client-010/App.config
@@ -0,0 +1,34 @@
+<?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.
+
+-->
+
+<configuration>
+ <appSettings>
+ <add key="Username" value="guest"/>
+ <add key="Password" value="guest123"/>
+ <add key="Host" value="localhost"/>
+ <add key="Port" value="5672"/>
+ <add key="VirtualHost" value="test"/>
+
+ <!-- <add key="ProcessorAssembly" value="C:\Project\qpid\dotnet\client-010\addins\ExcelAddInMessageProcessor\bin\Debug\ExcelAddInMessageProcessor.dll"/>
+ <add key="ProcessorClass" value="ExcelAddInMessageProcessor.Processor"/> -->
+ </appSettings>
+</configuration>
diff --git a/qpid/dotnet/client-010/LICENSE.txt b/qpid/dotnet/client-010/LICENSE.txt
new file mode 100644
index 0000000000..981d2f83c3
--- /dev/null
+++ b/qpid/dotnet/client-010/LICENSE.txt
@@ -0,0 +1,757 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+
+=========================================================================
+== Saxon XSLT License ==
+=========================================================================
+
+Mozilla Public License Version 1.0
+
+1. Definitions.
+
+ 1.1. "Contributor" means each entity that creates or contributes
+ to the creation of Modifications.
+
+ 1.2. "Contributor Version" means the combination of the
+ Original Code, prior Modifications used by a Contributor, and the
+ Modifications made by that particular Contributor.
+
+ 1.3. "Covered Code" means the Original Code or Modifications
+ or the combination of the Original Code and Modifications, in each case
+ including portions thereof.
+
+ 1.4. "Electronic Distribution Mechanism" means a mechanism
+ generally accepted in the software development community for the
+ electronic transfer of data.
+
+ 1.5. "Executable" means Covered Code in any form other than
+ Source Code.
+
+ 1.6. "Initial Developer" means the individual or entity
+ identified as the Initial Developer in the Source Code notice required by
+ Exhibit A.
+
+ 1.7. "Larger Work" means a work which combines Covered Code
+ or portions thereof with code not governed by the terms of this License.
+
+ 1.8. "License" means this document.
+
+ 1.9. "Modifications" means any addition to or deletion from
+ the substance or structure of either the Original Code or any previous
+ Modifications. When Covered Code is released as a series of files, a
+ Modification is:
+
+ A. Any addition to or deletion from the contents of a file
+ containing Original Code or previous Modifications.
+
+ B. Any new file that contains any part of the Original
+ Code or previous Modifications.
+
+ 1.10. "Original Code" means Source Code of computer software
+ code which is described in the Source Code notice required by Exhibit
+ A as Original Code, and which, at the time of its release under this
+ License is not already Covered Code governed by this License.
+
+ 1.11. "Source Code" means the preferred form of the Covered
+ Code for making modifications to it, including all modules it contains,
+ plus any associated interface definition files, scripts used to control
+ compilation and installation of an Executable, or a list of source code
+ differential comparisons against either the Original Code or another well
+ known, available Covered Code of the Contributor's choice. The Source
+ Code can be in a compressed or archival form, provided the appropriate
+ decompression or de-archiving software is widely available for no charge.
+
+ 1.12. "You" means an individual or a legal entity exercising
+ rights under, and complying with all of the terms of, this License or a
+ future version of this License issued under Section 6.1. For legal
+ entities, "You" includes any entity which controls, is controlled by,
+ or is under common control with You. For purposes of this definition,
+ "control" means (a) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or otherwise,
+ or (b) ownership of fifty percent (50%) or more of the outstanding shares
+ or beneficial ownership of such entity.
+
+2. Source Code License.
+
+ 2.1. The Initial Developer Grant.
+
+
+ The Initial Developer hereby grants You a world-wide, royalty-free,
+ non-exclusive license, subject to third party intellectual property
+ claims:
+
+ (a) to use, reproduce, modify, display, perform, sublicense
+ and distribute the Original Code (or portions thereof) with or
+ without Modifications, or as part of a Larger Work; and
+
+ (b) under patents now or hereafter owned or controlled by
+ Initial Developer, to make, have made, use and sell ("Utilize") the
+ Original Code (or portions thereof), but solely to the extent that
+ any such patent is reasonably necessary to enable You to Utilize the
+ Original Code (or portions thereof) and not to any greater extent
+ that may be necessary to Utilize further Modifications or
+ combinations.
+
+ 2.2. Contributor Grant.
+
+
+ Each Contributor hereby grants You a world-wide, royalty-free,
+ non-exclusive license, subject to third party intellectual property
+ claims:
+
+ (a) to use, reproduce, modify, display, perform, sublicense and
+ distribute the Modifications created by such Contributor (or portions
+ thereof) either on an unmodified basis, with other Modifications, as
+ Covered Code or as part of a Larger Work; and
+
+ (b) under patents now or hereafter owned or controlled by
+ Contributor, to Utilize the Contributor Version (or portions thereof),
+ but solely to the extent that any such patent is reasonably necessary to
+ enable You to Utilize the Contributor Version (or portions thereof), and
+ not to any greater extent that may be necessary to Utilize further
+ Modifications or combinations.
+
+3. Distribution Obligations.
+
+ 3.1. Application of License.
+
+
+ The Modifications which You create or to which You contribute are
+ governed by the terms of this License, including without limitation
+ Section 2.2. The Source Code version of Covered Code may be
+ distributed only under the terms of this License or a future version of
+ this License released under Section 6.1, and You must include a
+ copy of this License with every copy of the Source Code You
+ distribute. You may not offer or impose any terms on any Source Code
+ version that alters or restricts the applicable version of this License
+ or the recipients' rights hereunder. However, You may include an
+ additional document offering the additional rights described in Section
+ 3.5.
+
+ 3.2. Availability of Source Code.
+
+
+ Any Modification which You create or to which You contribute must be
+ made available in Source Code form under the terms of this License either
+ on the same media as an Executable version or via an accepted Electronic
+ Distribution Mechanism to anyone to whom you made an Executable version
+ available; and if made available via Electronic Distribution Mechanism,
+ must remain available for at least twelve (12) months after the date it
+ initially became available, or at least six (6) months after a subsequent
+ version of that particular Modification has been made available to such
+ recipients. You are responsible for ensuring that the Source Code version
+ remains available even if the Electronic Distribution Mechanism is
+ maintained by a third party.
+
+ 3.3. Description of Modifications.
+
+
+ You must cause all Covered Code to which you contribute to contain a
+ file documenting the changes You made to create that Covered Code and the
+ date of any change. You must include a prominent statement that the
+ Modification is derived, directly or indirectly, from Original Code
+ provided by the Initial Developer and including the name of the Initial
+ Developer in (a) the Source Code, and (b) in any notice in an Executable
+ version or related documentation in which You describe the origin or
+ ownership of the Covered Code.
+
+ 3.4. Intellectual Property Matters
+
+ (a) Third Party Claims.
+
+
+ If You have knowledge that a party claims an intellectual
+ property right in particular functionality or code (or its
+ utilization under this License), you must include a text file with
+ the source code distribution titled "LEGAL" which describes the
+ claim and the party making the claim in sufficient detail that a
+ recipient will know whom to contact. If you obtain such knowledge
+ after You make Your Modification available as described in Section
+ 3.2, You shall promptly modify the LEGAL file in all copies
+ You make available thereafter and shall take other steps (such as
+ notifying appropriate mailing lists or newsgroups) reasonably
+ calculated to inform those who received the Covered Code that new
+ knowledge has been obtained.
+
+ (b) Contributor APIs.
+
+
+ If Your Modification is an application programming interface and
+ You own or control patents which are reasonably necessary to
+ implement that API, you must also include this information in the
+ LEGAL file.
+
+ 3.5. Required Notices.
+
+
+ You must duplicate the notice in Exhibit A in each file of the
+ Source Code, and this License in any documentation for the Source Code,
+ where You describe recipients' rights relating to Covered Code. If You
+ created one or more Modification(s), You may add your name as a
+ Contributor to the notice described in Exhibit A. If it is not
+ possible to put such notice in a particular Source Code file due to its
+ structure, then you must include such notice in a location (such as a
+ relevant directory file) where a user would be likely to look for such a
+ notice. You may choose to offer, and to charge a fee for, warranty,
+ support, indemnity or liability obligations to one or more recipients of
+ Covered Code. However, You may do so only on Your own behalf, and not on
+ behalf of the Initial Developer or any Contributor. You must make it
+ absolutely clear than any such warranty, support, indemnity or liability
+ obligation is offered by You alone, and You hereby agree to indemnify the
+ Initial Developer and every Contributor for any liability incurred by the
+ Initial Developer or such Contributor as a result of warranty, support,
+ indemnity or liability terms You offer.
+
+ 3.6. Distribution of Executable Versions.
+
+
+ You may distribute Covered Code in Executable form only if the
+ requirements of Section 3.1-3.5 have been met for that Covered
+ Code, and if You include a notice stating that the Source Code version of
+ the Covered Code is available under the terms of this License, including
+ a description of how and where You have fulfilled the obligations of
+ Section 3.2. The notice must be conspicuously included in any
+ notice in an Executable version, related documentation or collateral in
+ which You describe recipients' rights relating to the Covered Code. You
+ may distribute the Executable version of Covered Code under a license of
+ Your choice, which may contain terms different from this License,
+ provided that You are in compliance with the terms of this License and
+ that the license for the Executable version does not attempt to limit or
+ alter the recipient's rights in the Source Code version from the rights
+ set forth in this License. If You distribute the Executable version under
+ a different license You must make it absolutely clear that any terms
+ which differ from this License are offered by You alone, not by the
+ Initial Developer or any Contributor. You hereby agree to indemnify the
+ Initial Developer and every Contributor for any liability incurred by the
+ Initial Developer or such Contributor as a result of any such terms You
+ offer.
+
+ 3.7. Larger Works.
+
+
+ You may create a Larger Work by combining Covered Code with other
+ code not governed by the terms of this License and distribute the Larger
+ Work as a single product. In such a case, You must make sure the
+ requirements of this License are fulfilled for the Covered Code.
+
+4. Inability to Comply Due to Statute or Regulation.
+
+ If it is impossible for You to comply with any of the terms of this
+ License with respect to some or all of the Covered Code due to statute or
+ regulation then You must: (a) comply with the terms of this License to
+ the maximum extent possible; and (b) describe the limitations and the
+ code they affect. Such description must be included in the LEGAL file
+ described in Section 3.4 and must be included with all
+ distributions of the Source Code. Except to the extent prohibited by
+ statute or regulation, such description must be sufficiently detailed for
+ a recipient of ordinary skill
+ to be able to understand it.
+
+5. Application of this License.
+
+ This License applies to code to which the Initial Developer has attached
+ the notice in Exhibit A, and to related Covered Code.
+
+6. Versions of the License.
+
+ 6.1. New Versions.
+
+
+ Netscape Communications Corporation ("Netscape") may publish
+ revised and/or new versions of the License from time to time. Each
+ version will be given a distinguishing version number.
+
+ 6.2. Effect of New Versions.
+
+
+ Once Covered Code has been published under a particular version of
+ the License, You may always continue to use it under the terms of that
+ version. You may also choose to use such Covered Code under the terms of
+ any subsequent version of the License published by Netscape. No one other
+ than Netscape has the right to modify the terms applicable to Covered
+ Code created under this License.
+
+ 6.3. Derivative Works.
+
+
+ If you create or use a modified version of this License (which you
+ may only do in order to apply it to code which is not already Covered
+ Code governed by this License), you must (a) rename Your license so that
+ the phrases "Mozilla", "MOZILLAPL", "MOZPL", "Netscape", "NPL"
+ or any confusingly similar phrase do not appear anywhere in your license
+ and (b) otherwise make it clear that your version of the license contains
+ terms which differ from the Mozilla Public License and Netscape Public
+ License. (Filling in the name of the Initial Developer, Original Code or
+ Contributor in the notice described in Exhibit A shall not of
+ themselves be deemed to be modifications of this License.)
+
+7. DISCLAIMER OF WARRANTY.
+
+ COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ WITHOUT LIMITATION, WARRANTIES THAT THE COVERED CODE IS FREE OF DEFECTS,
+ MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE OR NON-INFRINGING. THE ENTIRE
+ RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED CODE IS WITH
+ YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT THE
+ INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY
+ NECESSARY SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY
+ CONSTITUTES AN ESSENTIAL PART OF THIS LICENSE. NO USE OF ANY COVERED CODE
+ IS AUTHORIZED HEREUNDER EXCEPT UNDER THIS DISCLAIMER.
+
+8. TERMINATION.
+
+ This License and the rights granted hereunder will terminate
+ automatically if You fail to comply with terms herein and fail to cure
+ such breach within 30 days of becoming aware of the breach. All
+ sublicenses to the Covered Code which are properly granted shall survive
+ any termination of this License. Provisions which, by their nature, must
+ remain in effect beyond the termination of this License shall survive.
+
+9. LIMITATION OF LIABILITY.
+
+ UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, WHETHER TORT (INCLUDING
+ NEGLIGENCE), CONTRACT, OR OTHERWISE, SHALL THE INITIAL DEVELOPER, ANY
+ OTHER CONTRIBUTOR, OR ANY DISTRIBUTOR OF COVERED CODE, OR ANY SUPPLIER OF
+ ANY OF SUCH PARTIES, BE LIABLE TO YOU OR ANY OTHER PERSON FOR ANY
+ INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY CHARACTER
+ INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF GOODWILL, WORK
+ STOPPAGE, COMPUTER FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER
+ COMMERCIAL DAMAGES OR LOSSES, EVEN IF SUCH PARTY SHALL HAVE BEEN INFORMED
+ OF THE POSSIBILITY OF SUCH DAMAGES. THIS LIMITATION OF LIABILITY SHALL
+ NOT APPLY TO LIABILITY FOR DEATH OR PERSONAL INJURY RESULTING FROM SUCH
+ PARTY'S NEGLIGENCE TO THE EXTENT APPLICABLE LAW PROHIBITS SUCH
+ LIMITATION. SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION OR LIMITATION
+ OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO THAT EXCLUSION AND LIMITATION
+ MAY NOT APPLY TO YOU.
+
+10. U.S. GOVERNMENT END USERS.
+
+ The Covered Code is a "commercial item," as that term is defined in 48
+ C.F.R. 2.101 (Oct. 1995), consisting of "commercial computer software"
+ and "commercial computer software documentation," as such terms are
+ used in 48 C.F.R. 12.212 (Sept. 1995). Consistent with 48 C.F.R. 12.212
+ and 48 C.F.R. 227.7202-1 through 227.7202-4 (June 1995), all
+ U.S. Government End Users acquire Covered Code with only those rights set
+ forth herein.
+
+11. MISCELLANEOUS.
+
+ This License represents the complete agreement concerning subject matter
+ hereof. If any provision of this License is held to be unenforceable,
+ such provision shall be reformed only to the extent necessary to make it
+ enforceable. This License shall be governed by California law provisions
+ (except to the extent applicable law, if any, provides otherwise),
+ excluding its conflict-of-law provisions. With respect to disputes in
+ which at least one party is a citizen of, or an entity chartered or
+ registered to do business in, the United States of America: (a) unless
+ otherwise agreed in writing, all disputes relating to this License
+ (excepting any dispute relating to intellectual property rights) shall be
+ subject to final and binding arbitration, with the losing party paying
+ all costs of arbitration; (b) any arbitration relating to this Agreement
+ shall be held in Santa Clara County, California, under the auspices of
+ JAMS/EndDispute; and (c) any litigation relating to this Agreement shall
+ be subject to the jurisdiction of the Federal Courts of the Northern
+ District of California, with venue lying in Santa Clara County,
+ California, with the losing party responsible for costs, including
+ without limitation, court costs and reasonable attorneys fees and
+ expenses. The application of the United Nations Convention on Contracts
+ for the International Sale of Goods is expressly excluded. Any law or
+ regulation which provides that the language of a contract shall be
+ construed against the drafter shall not apply to this License.
+
+12. RESPONSIBILITY FOR CLAIMS.
+
+ Except in cases where another Contributor has failed to comply with
+ Section 3.4, You are responsible for damages arising, directly or
+ indirectly, out of Your utilization of rights under this License, based
+ on the number of copies of Covered Code you made available, the revenues
+ you received from utilizing such rights, and other relevant factors. You
+ agree to work with affected parties to distribute responsibility on an
+ equitable basis.
+
+EXHIBIT A.
+
+ "The contents of this file are subject to the Mozilla Public License
+ Version 1.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.mozilla.org/MPL/
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
+ License for the specific language governing rights and limitations under
+ the License.
+
+ The Original Code is ______________________________________.
+
+ The Initial Developer of the Original Code is
+ ________________________. Portions created by ______________________ are
+ Copyright (C) ______ _______________________. All Rights Reserved.
+
+ Contributor(s): ______________________________________."
+
+
+=========================================================================
+== Nunit License ==
+=========================================================================
+Copyright (c) 2002 James W. Newkirk, Michael C. Two, Alexei A. Vorontsov
+Copyright (c) 2000-2002 Philip A. Craig
+
+This software is provided 'as-is', without any express or implied
+warranty. In no event will the authors be held liable for any damages
+arising from the use of this software.
+
+Permission is granted to anyone to use this software for any purpose,
+including commercial applications, and to alter it and redistribute it
+freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+
+ 3. This notice may not be removed or altered from any source
+ distribution.
+
+=========================================================================
+== Mentalis Security LibraryLicense ==
+=========================================================================
+
+Source Code License
+
+Copyright © 2002-2007, The Mentalis.org Team
+All rights reserved.
+http://www.mentalis.org/
+
+Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+
+- Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
+
+- Neither the name of the Mentalis.org Team, nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+=========================================================================
+== AMQP License ==
+=========================================================================
+
+ Copyright Notice
+ ================
+ (c) Copyright JPMorgan Chase Bank & Co., Cisco Systems, Inc., Envoy Technologies Inc.,
+ iMatix Corporation, IONA\ufffd Technologies, Red Hat, Inc.,
+ TWIST Process Innovations, and 29West Inc. 2006. All rights reserved.
+
+ License
+ =======
+ JPMorgan Chase Bank & Co., Cisco Systems, Inc., Envoy Technologies Inc., iMatix
+ Corporation, IONA\ufffd Technologies, Red Hat, Inc., TWIST Process Innovations, and
+ 29West Inc. (collectively, the "Authors") each hereby grants to you a worldwide,
+ perpetual, royalty-free, nontransferable, nonexclusive license to
+ (i) copy, display, and implement the Advanced Messaging Queue Protocol
+ ("AMQP") Specification and (ii) the Licensed Claims that are held by
+ the Authors, all for the purpose of implementing the Advanced Messaging
+ Queue Protocol Specification. Your license and any rights under this
+ Agreement will terminate immediately without notice from
+ any Author if you bring any claim, suit, demand, or action related to
+ the Advanced Messaging Queue Protocol Specification against any Author.
+ Upon termination, you shall destroy all copies of the Advanced Messaging
+ Queue Protocol Specification in your possession or control.
+
+ As used hereunder, "Licensed Claims" means those claims of a patent or
+ patent application, throughout the world, excluding design patents and
+ design registrations, owned or controlled, or that can be sublicensed
+ without fee and in compliance with the requirements of this
+ Agreement, by an Author or its affiliates now or at any
+ future time and which would necessarily be infringed by implementation
+ of the Advanced Messaging Queue Protocol Specification. A claim is
+ necessarily infringed hereunder only when it is not possible to avoid
+ infringing it because there is no plausible non-infringing alternative
+ for implementing the required portions of the Advanced Messaging Queue
+ Protocol Specification. Notwithstanding the foregoing, Licensed Claims
+ shall not include any claims other than as set forth above even if
+ contained in the same patent as Licensed Claims; or that read solely
+ on any implementations of any portion of the Advanced Messaging Queue
+ Protocol Specification that are not required by the Advanced Messaging
+ Queue Protocol Specification, or that, if licensed, would require a
+ payment of royalties by the licensor to unaffiliated third parties.
+ Moreover, Licensed Claims shall not include (i) any enabling technologies
+ that may be necessary to make or use any Licensed Product but are not
+ themselves expressly set forth in the Advanced Messaging Queue Protocol
+ Specification (e.g., semiconductor manufacturing technology, compiler
+ technology, object oriented technology, networking technology, operating
+ system technology, and the like); or (ii) the implementation of other
+ published standards developed elsewhere and merely referred to in the
+ body of the Advanced Messaging Queue Protocol Specification, or
+ (iii) any Licensed Product and any combinations thereof the purpose or
+ function of which is not required for compliance with the Advanced
+ Messaging Queue Protocol Specification. For purposes of this definition,
+ the Advanced Messaging Queue Protocol Specification shall be deemed to
+ include both architectural and interconnection requirements essential
+ for interoperability and may also include supporting source code artifacts
+ where such architectural, interconnection requirements and source code
+ artifacts are expressly identified as being required or documentation to
+ achieve compliance with the Advanced Messaging Queue Protocol Specification.
+
+ As used hereunder, "Licensed Products" means only those specific portions
+ of products (hardware, software or combinations thereof) that implement
+ and are compliant with all relevant portions of the Advanced Messaging
+ Queue Protocol Specification.
+
+ The following disclaimers, which you hereby also acknowledge as to any
+ use you may make of the Advanced Messaging Queue Protocol Specification:
+
+ THE ADVANCED MESSAGING QUEUE PROTOCOL SPECIFICATION IS PROVIDED "AS IS,"
+ AND THE AUTHORS MAKE NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR
+ IMPLIED, INCLUDING, BUT NOT LIMITED TO, WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, OR TITLE; THAT THE
+ CONTENTS OF THE ADVANCED MESSAGING QUEUE PROTOCOL SPECIFICATION ARE
+ SUITABLE FOR ANY PURPOSE; NOR THAT THE IMPLEMENTATION OF THE ADVANCED
+ MESSAGING QUEUE PROTOCOL SPECIFICATION WILL NOT INFRINGE ANY THIRD PARTY
+ PATENTS, COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS.
+
+ THE AUTHORS WILL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL,
+ INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF OR RELATING TO ANY
+ USE, IMPLEMENTATION OR DISTRIBUTION OF THE ADVANCED MESSAGING QUEUE
+ PROTOCOL SPECIFICATION.
+
+ The name and trademarks of the Authors may NOT be used in any manner,
+ including advertising or publicity pertaining to the Advanced Messaging
+ Queue Protocol Specification or its contents without specific, written
+ prior permission. Title to copyright in the Advanced Messaging Queue
+ Protocol Specification will at all times remain with the Authors.
+
+ No other rights are granted by implication, estoppel or otherwise.
+
+ Upon termination of your license or rights under this Agreement, you
+ shall destroy all copies of the Advanced Messaging Queue Protocol
+ Specification in your possession or control.
+
+ Trademarks
+ ==========
+ "JPMorgan", "JPMorgan Chase", "Chase", the JPMorgan Chase logo and the
+ Octagon Symbol are trademarks of JPMorgan Chase & Co.
+
+ IMATIX and the iMatix logo are trademarks of iMatix Corporation sprl.
+
+ IONA, IONA Technologies, and the IONA logos are trademarks of IONA
+ Technologies PLC and/or its subsidiaries.
+
+ LINUX is a trademark of Linus Torvalds. RED HAT and JBOSS are registered
+ trademarks of Red Hat, Inc. in the US and other countries.
+
+ Java, all Java-based trademarks and OpenOffice.org are trademarks of
+ Sun Microsystems, Inc. in the United States, other countries, or both.
+
+ Other company, product, or service names may be trademarks or service
+ marks of others.
+
+ Links to full AMQP specification:
+ =================================
+ http://www.envoytech.org/spec/amq/
+ http://www.iona.com/opensource/amqp/
+ http://www.redhat.com/solutions/specifications/amqp/
+ http://www.twiststandards.org/tiki-index.php?page=AMQ
+ http://www.imatix.com/amqp
diff --git a/qpid/dotnet/client-010/NOTICE.txt b/qpid/dotnet/client-010/NOTICE.txt
new file mode 100644
index 0000000000..0b22ed3ab2
--- /dev/null
+++ b/qpid/dotnet/client-010/NOTICE.txt
@@ -0,0 +1,32 @@
+=========================================================================
+== NOTICE file corresponding to the section 4 d of ==
+== the Apache License, Version 2.0, ==
+== in this case for the Apache Ant distribution. ==
+=========================================================================
+
+Apache Qpid.NET
+Copyright 2006 The Apache Software Foundation
+
+This product includes software developed by
+The Apache Software Foundation (http://www.apache.org/).
+
+This product also includes software developed by:
+
+ - The SAXON XSLT Processor from Michael Kay distributed under the Mozilla
+ Public License v1.0, which is available for download at
+ http://saxon.sourceforge.net/
+
+ - The nunit library, Copyright © 2002 James W. Newkirk, Michael C. Two,
+ Alexei A. Vorontsov or Copyright © 2000-2002 Philip A. Craig. Available
+ under terms based on the zlib/libpng licence. Available from
+ http://www.nunit.org/
+
+ - The Mentalis Security Library, Copyright © 2002-2006, , The Mentalis.org Team
+ under tterms based on the BSD license (http://www.mentalis.org/site/license.qpx).
+ Available from http://www.mentalis.org/soft/projects/seclib/
+
+This product includes software, Apache Log4Net
+(http://logging.apache.org/log4net)
+License: Apache 2.0 License (http://www.apache.org/licenses/LICENSE-2.0)
+
+
diff --git a/qpid/dotnet/client-010/README.txt b/qpid/dotnet/client-010/README.txt
new file mode 100644
index 0000000000..74d54a9786
--- /dev/null
+++ b/qpid/dotnet/client-010/README.txt
@@ -0,0 +1,69 @@
+Info
+====
+
+AMQP 0.10 Native .NET client supporting WCF and xcel
+
+In order to build this client from the sources you'll need the following folders :
+- <project home>/java/lib
+- <project home>/python
+- <project home>/specs
+
+
+Setup
+=====
+
+Install:
+ Microsoft Visual Studio 2008 (VS2008). It's also possible to build with vs2005 by creating a new solution and adding Client.csproj
+ NAnt 0.85 - only required for builds outside VS2008 (.net 1.1, .net 2.0, mono 2.0)
+ Ant 1.6.5 (requires Java)
+ Cygwin (or alternatively build via cmd but alter instructions below accordingly)
+
+Set up PATH to include Nant.exe:
+
+ $ PATH=/cygdrive/c/WINDOWS/Microsoft.NET/Framework/v2.0.50727:$PATH
+
+Set up PATH to include ant:
+
+ $ PATH=$ANT_HOME/bin:$PATH
+
+
+Building
+========
+
+Generate code from <project home>/dotnet/client-010/gentool:
+
+ $ cd <project home>/dotnet/client-010/gentool
+ $ ant
+
+You can build from Visual Studio 2008 normally. Alternatively, you
+can build debug releases for any supported framework from the
+command line using Nant:
+
+To build .NET 2.0 executables (to bin/net-2.0):
+
+ $ cd <project home>/dotnet/client-010/
+ $ nant
+
+
+To build for Mono on Linux (to bin/mono-2.0):
+
+ $ cd <project home>/dotnet/client-010/
+ $ nant -t:mono-2.0
+
+Releasing
+=========
+
+For .NET 2.0
+
+ $ cd <project home>/dotnet/client-010/
+ $ nant release-pkg
+
+Generates ./bin/net-2.0/release/Qpid.NET-net-2.0-yyyyMMdd.zip
+
+For Mono
+
+ $ cd <project home>/dotnet/client-010/
+ $ nant -t:mono-2.0 release-pkg
+
+Generates ./bin/mono-2.0/release/Qpid.NET-mono-2.0-yyyyMMdd.zip
+
diff --git a/qpid/dotnet/client-010/addins/ExcelAddIn/Excel.exe.config b/qpid/dotnet/client-010/addins/ExcelAddIn/Excel.exe.config
new file mode 100644
index 0000000000..66bf63532e
--- /dev/null
+++ b/qpid/dotnet/client-010/addins/ExcelAddIn/Excel.exe.config
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<configuration>
+ <appSettings>
+ <add key="Host" value="localhost" />
+ <add key="Port" value="5672" />
+ <add key="VirtualHost" value="test" />
+ <add key="UserName" value="guest" />
+ <add key="Password" value="guest" />
+ <!-- <add key="ProcessorAssembly" value="C:\Project\qpid\dotnet\client-010\addins\ExcelAddInMessageProcessor\bin\Debug\ExcelAddInMessageProcessor.dll"/>
+ <add key="ProcessorClass" value="ExcelAddInMessageProcessor.Processor"/> -->
+ </appSettings>
+</configuration> \ No newline at end of file
diff --git a/qpid/dotnet/client-010/addins/ExcelAddIn/ExcelAddIn.cs b/qpid/dotnet/client-010/addins/ExcelAddIn/ExcelAddIn.cs
new file mode 100644
index 0000000000..66c9b7a8f9
--- /dev/null
+++ b/qpid/dotnet/client-010/addins/ExcelAddIn/ExcelAddIn.cs
@@ -0,0 +1,290 @@
+/*
+*
+* 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.
+*
+*/
+
+using System;
+using System.Collections.Generic;
+using System.Configuration;
+using System.IO;
+using System.Reflection;
+using System.Runtime.InteropServices;
+using System.Text;
+using Microsoft.Office.Interop.Excel;
+using org.apache.qpid.client;
+using org.apache.qpid.transport;
+
+namespace ExcelAddIn
+{
+ public delegate string ProcessMessage(IMessage m);
+
+ /// <summary>
+ /// This interface must be implemented so to use a user defined message processor
+ /// </summary>
+ public interface MessageProcessor
+ {
+ string ProcessMessage(IMessage m);
+ }
+
+ [ComVisible(true), ProgId("Qpid")]
+ public class ExcelAddIn : IRtdServer
+ {
+ private IRTDUpdateEvent _onMessage;
+ private readonly Dictionary<int, IMessage> _topicMessages = new Dictionary<int, IMessage>();
+ private readonly Dictionary<string, QpidListener> _queueListener = new Dictionary<string, QpidListener>();
+ private readonly Dictionary<int, string> _topicQueueName = new Dictionary<int, string>();
+ private IClient _client;
+ private IClientSession _session;
+ private ProcessMessage _messageProcessor;
+
+ #region properties
+
+ public IRTDUpdateEvent OnMessage
+ {
+ get { return _onMessage; }
+ }
+
+ public Dictionary<int, IMessage> TopicMessages
+ {
+ get { return _topicMessages; }
+ }
+
+ public IClientSession Session
+ {
+ get { return _session; }
+ }
+
+ #endregion
+
+
+ #region IRtdServer Members
+
+ /// <summary>
+ /// Called when Excel requests the first RTD topic for the server.
+ /// Connect to the broker, returns a on success and 0 otherwise
+ /// </summary>
+ /// <param name="CallbackObject"></param>
+ /// <returns></returns>
+ public int ServerStart(IRTDUpdateEvent CallbackObject)
+ {
+ _onMessage = CallbackObject;
+ string host = "localhost";
+ string port = "5673";
+ string virtualhost = "test";
+ string username = "guest";
+ string password = "guest";
+ _messageProcessor = getMessage;
+
+ if( ConfigurationManager.AppSettings["Host"] != null )
+ {
+ host = ConfigurationManager.AppSettings["Host"];
+ }
+ if (ConfigurationManager.AppSettings["Port"] != null)
+ {
+ port = ConfigurationManager.AppSettings["Port"];
+ }
+ if (ConfigurationManager.AppSettings["VirtualHost"] != null)
+ {
+ virtualhost = ConfigurationManager.AppSettings["VirtualHost"];
+ }
+ if (ConfigurationManager.AppSettings["Username"] != null)
+ {
+ username = ConfigurationManager.AppSettings["UserName"];
+ }
+ if (ConfigurationManager.AppSettings["Password"] != null)
+ {
+ password = ConfigurationManager.AppSettings["Password"];
+ }
+ if (ConfigurationManager.AppSettings["ProcessorAssembly"] != null)
+ {
+ try
+ {
+ Assembly a = Assembly.LoadFrom(ConfigurationManager.AppSettings["ProcessorAssembly"]);
+ Object o = a.CreateInstance(ConfigurationManager.AppSettings["ProcessorClass"]);
+ MessageProcessor p = (MessageProcessor) o;
+ _messageProcessor = p.ProcessMessage;
+ }
+ catch (Exception e)
+ {
+ System.Windows.Forms.MessageBox.Show("Error: \n" + e.StackTrace);
+ return 0;
+ }
+ }
+
+ System.Windows.Forms.MessageBox.Show("Connection parameters: \n host: " + host + "\n port: "
+ + port + "\n user: " + username);
+ try
+ {
+ _client = new Client();
+ _client.Connect(host, Convert.ToInt16(port), virtualhost, username, password);
+ // create a session
+ _session = _client.CreateSession(0);
+ }
+ catch (Exception e)
+ {
+ System.Windows.Forms.MessageBox.Show("Error: \n" + e.StackTrace);
+ return 0;
+ }
+
+ // always successful
+ return 1;
+ }
+
+ /// <summary>
+ /// Called whenever Excel requests a new RTD topic from the RealTimeData server.
+ /// </summary>
+ /// <param name="TopicID"></param>
+ /// <param name="Strings"></param>
+ /// <param name="GetNewValues"></param>
+ /// <returns></returns>
+ public object ConnectData(int TopicID, ref Array Strings, ref bool GetNewValues)
+ {
+ try
+ {
+ string queuename = "defaultExcelAddInQueue";
+ string destinationName = "ExcelAddIn-" + queuename;
+ if( Strings.Length > 0 )
+ {
+ queuename = (string) Strings.GetValue(0);
+ }
+ // Error message if the queue does not exist
+ QueueQueryResult result = (QueueQueryResult)_session.QueueQuery(queuename).Result;
+ if( result.GetQueue() == null )
+ {
+ System.Windows.Forms.MessageBox.Show("Error: \n queue " + queuename + " does not exist");
+ return "error";
+ }
+
+ QpidListener listener;
+ _topicMessages.Add(TopicID, null);
+ _topicQueueName.Add(TopicID, queuename);
+ if (_queueListener.ContainsKey(queuename))
+ {
+ listener = _queueListener[queuename];
+ listener.addTopic(TopicID);
+ }
+ else
+ {
+ listener = new QpidListener(this);
+ listener.addTopic(TopicID);
+ _queueListener.Add(queuename, listener);
+ _session.AttachMessageListener(listener, destinationName);
+ _session.MessageSubscribe(queuename, destinationName, MessageAcceptMode.EXPLICIT,
+ MessageAcquireMode.PRE_ACQUIRED, null, 0, null);
+ // issue credits
+ _session.MessageSetFlowMode(destinationName, MessageFlowMode.WINDOW);
+ _session.MessageFlow(destinationName, MessageCreditUnit.BYTE, ClientSession.MESSAGE_FLOW_MAX_BYTES);
+ _session.MessageFlow(destinationName, MessageCreditUnit.MESSAGE, 1000);
+ _session.Sync();
+ }
+ }
+ catch (Exception e)
+ {
+ System.Windows.Forms.MessageBox.Show("Error: \n" + e.StackTrace);
+ return "error";
+ }
+ return "waiting";
+ }
+
+ /// <summary>
+ /// Called whenever Excel no longer requires a specific topic.
+ /// </summary>
+ /// <param name="TopicID"></param>
+ public void DisconnectData(int TopicID)
+ {
+ _topicMessages.Remove(TopicID);
+ string queueName = _topicQueueName[TopicID];
+ if (_topicQueueName.Remove(TopicID) && !_topicQueueName.ContainsValue(queueName))
+ {
+ _session.MessageStop("ExcelAddIn-" + queueName);
+ _session.MessageListeners.Remove("ExcelAddIn-" + queueName);
+ }
+ }
+
+ public int Heartbeat()
+ {
+ return 1;
+ }
+
+ public Array RefreshData(ref int TopicCount)
+ {
+ Array result = new object[2, _topicMessages.Count];
+ foreach (KeyValuePair<int, IMessage> pair in _topicMessages)
+ {
+ result.SetValue(pair.Key, 0, pair.Key);
+ string value = _messageProcessor(pair.Value);
+ result.SetValue(value, 1, pair.Key);
+ }
+ TopicCount = _topicMessages.Count;
+ return result;
+ }
+
+ public void ServerTerminate()
+ {
+
+ }
+
+ #endregion
+ //END IRTDServer METHODS
+
+ private string getMessage(IMessage m)
+ {
+ string res;
+ BinaryReader reader = new BinaryReader(m.Body, Encoding.UTF8);
+ byte[] body = new byte[m.Body.Length - m.Body.Position];
+ reader.Read(body, 0, body.Length);
+ ASCIIEncoding enc = new ASCIIEncoding();
+ res = enc.GetString(body);
+ return res;
+ }
+
+ }
+
+ class QpidListener : IMessageListener
+ {
+ private readonly ExcelAddIn _excel;
+ private readonly List<int> _topics = new List<int>();
+
+ public QpidListener(ExcelAddIn excel)
+ {
+ _excel = excel;
+ }
+
+ public void addTopic(int topic)
+ {
+ _topics.Add(topic);
+ }
+
+ public void MessageTransfer(IMessage m)
+ {
+ foreach (int i in _topics)
+ {
+ if (_excel.TopicMessages.ContainsKey(i))
+ {
+ _excel.TopicMessages[i] = m;
+ }
+ }
+ // ack this message
+ RangeSet rs = new RangeSet();
+ rs.Add(m.Id);
+ _excel.Session.MessageAccept(rs);
+ _excel.OnMessage.UpdateNotify();
+ }
+ }
+}
diff --git a/qpid/dotnet/client-010/addins/ExcelAddIn/ExcelAddIn.csproj b/qpid/dotnet/client-010/addins/ExcelAddIn/ExcelAddIn.csproj
new file mode 100644
index 0000000000..b44bf9cc69
--- /dev/null
+++ b/qpid/dotnet/client-010/addins/ExcelAddIn/ExcelAddIn.csproj
@@ -0,0 +1,89 @@
+<!--
+ -
+ - Licensed to the Apache Software Foundation (ASF) under one
+ - or more contributor license agreements. See the NOTICE file
+ - distributed with this work for additional information
+ - regarding copyright ownership. The ASF licenses this file
+ - to you under the Apache License, Version 2.0 (the
+ - "License"); you may not use this file except in compliance
+ - with the License. You may obtain a copy of the License at
+ -
+ - http://www.apache.org/licenses/LICENSE-2.0
+ -
+ - Unless required by applicable law or agreed to in writing,
+ - software distributed under the License is distributed on an
+ - "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ - KIND, either express or implied. See the License for the
+ - specific language governing permissions and limitations
+ - under the License.
+ -
+ -->
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProductVersion>9.0.30729</ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{85EFD719-39F6-4471-90FF-9E621430344B}</ProjectGuid>
+ <OutputType>Library</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>ExcelAddIn</RootNamespace>
+ <AssemblyName>Qpid Excel AddIn</AssemblyName>
+ <StartupObject>
+ </StartupObject>
+ <FileUpgradeFlags>
+ </FileUpgradeFlags>
+ <UpgradeBackupLocation>
+ </UpgradeBackupLocation>
+ <OldToolsVersion>2.0</OldToolsVersion>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ <RegisterForComInterop>true</RegisterForComInterop>
+ <DocumentationFile>bin\Debug\Qpid Excel AddIn.XML</DocumentationFile>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="Microsoft.Office.Interop.Excel, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" />
+ <Reference Include="System" />
+ <Reference Include="System.configuration" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Windows.Forms" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="**\*.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\..\client\Client.csproj">
+ <Project>{B911FFD7-754F-4735-A188-218D5065BE79}</Project>
+ <Name>Client</Name>
+ </ProjectReference>
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="..\..\App.config">
+ <Link>App.config</Link>
+ </None>
+ </ItemGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+ <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
+ Other similar extension points exist, see Microsoft.Common.targets.
+ <Target Name="BeforeBuild">
+ </Target>
+ <Target Name="AfterBuild">
+ </Target>
+ -->
+</Project>
diff --git a/qpid/dotnet/client-010/addins/ExcelAddIn/Properties/AssemblyInfo.cs b/qpid/dotnet/client-010/addins/ExcelAddIn/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000000..67e95f69a3
--- /dev/null
+++ b/qpid/dotnet/client-010/addins/ExcelAddIn/Properties/AssemblyInfo.cs
@@ -0,0 +1,56 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("Qpid Excel AddIn")]
+[assembly: AssemblyDescription("Built from svn revision number: ")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Apache Software Foundation")]
+[assembly: AssemblyProduct("Qpid Excel AddIn")]
+[assembly: AssemblyCopyright("Apache Software Foundation")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("3bbd4414-60df-407f-9c64-c14b221167af")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Revision and Build Numbers
+// by using the '*' as shown below:
+[assembly: AssemblyVersion("0.5.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/qpid/dotnet/client-010/addins/ExcelAddInMessageProcessor/ExcelAddInMessageProcessor.csproj b/qpid/dotnet/client-010/addins/ExcelAddInMessageProcessor/ExcelAddInMessageProcessor.csproj
new file mode 100644
index 0000000000..447ded4b55
--- /dev/null
+++ b/qpid/dotnet/client-010/addins/ExcelAddInMessageProcessor/ExcelAddInMessageProcessor.csproj
@@ -0,0 +1,86 @@
+<!--
+ -
+ - Licensed to the Apache Software Foundation (ASF) under one
+ - or more contributor license agreements. See the NOTICE file
+ - distributed with this work for additional information
+ - regarding copyright ownership. The ASF licenses this file
+ - to you under the Apache License, Version 2.0 (the
+ - "License"); you may not use this file except in compliance
+ - with the License. You may obtain a copy of the License at
+ -
+ - http://www.apache.org/licenses/LICENSE-2.0
+ -
+ - Unless required by applicable law or agreed to in writing,
+ - software distributed under the License is distributed on an
+ - "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ - KIND, either express or implied. See the License for the
+ - specific language governing permissions and limitations
+ - under the License.
+ -
+ -->
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProductVersion>9.0.30729</ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{C2AE83A3-D5D1-469D-8611-A4738B9997CF}</ProjectGuid>
+ <OutputType>Library</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>ExcelAddInMessageProcessor</RootNamespace>
+ <AssemblyName>ExcelAddInMessageProcessor</AssemblyName>
+ <FileUpgradeFlags>
+ </FileUpgradeFlags>
+ <OldToolsVersion>2.0</OldToolsVersion>
+ <UpgradeBackupLocation>
+ </UpgradeBackupLocation>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="System" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="**\*.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\..\client\Client.csproj">
+ <Project>{B911FFD7-754F-4735-A188-218D5065BE79}</Project>
+ <Name>Client</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\ExcelAddIn\ExcelAddIn.csproj">
+ <Project>{85EFD719-39F6-4471-90FF-9E621430344B}</Project>
+ <Name>ExcelAddIn</Name>
+ </ProjectReference>
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="..\..\App.config">
+ <Link>App.config</Link>
+ </None>
+ </ItemGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+ <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
+ Other similar extension points exist, see Microsoft.Common.targets.
+ <Target Name="BeforeBuild">
+ </Target>
+ <Target Name="AfterBuild">
+ </Target>
+ -->
+</Project>
diff --git a/qpid/dotnet/client-010/addins/ExcelAddInMessageProcessor/Processor.cs b/qpid/dotnet/client-010/addins/ExcelAddInMessageProcessor/Processor.cs
new file mode 100644
index 0000000000..e414da131f
--- /dev/null
+++ b/qpid/dotnet/client-010/addins/ExcelAddInMessageProcessor/Processor.cs
@@ -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.
+*
+*/
+
+using System.IO;
+using System.Text;
+using org.apache.qpid.client;
+
+namespace ExcelAddInMessageProcessor
+{
+ class Processor : ExcelAddIn.MessageProcessor
+ {
+ public string ProcessMessage(IMessage m)
+ {
+ BinaryReader reader = new BinaryReader(m.Body, Encoding.UTF8);
+ byte[] body = new byte[m.Body.Length - m.Body.Position];
+ reader.Read(body, 0, body.Length);
+ ASCIIEncoding enc = new ASCIIEncoding();
+ string res = enc.GetString(body);
+ if (m.ApplicationHeaders.ContainsKey("price"))
+ {
+ res = res + ": price: " + m.ApplicationHeaders["price"];
+ }
+ return res;
+ }
+ }
+} \ No newline at end of file
diff --git a/qpid/dotnet/client-010/addins/ExcelAddInMessageProcessor/Properties/AssemblyInfo.cs b/qpid/dotnet/client-010/addins/ExcelAddInMessageProcessor/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000000..302007674f
--- /dev/null
+++ b/qpid/dotnet/client-010/addins/ExcelAddInMessageProcessor/Properties/AssemblyInfo.cs
@@ -0,0 +1,56 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("ExcelAddInMessageProcessor")]
+[assembly: AssemblyDescription("Built from svn revision number: ")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Apache Software Foundation")]
+[assembly: AssemblyProduct("ExcelAddInMessageProcessor")]
+[assembly: AssemblyCopyright("Apache Software Foundation")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("d20b2d75-7b8b-4f7d-8a81-40a4cce94195")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Revision and Build Numbers
+// by using the '*' as shown below:
+[assembly: AssemblyVersion("0.5.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/qpid/dotnet/client-010/addins/ExcelAddInProducer/ExcelAddInProducer.csproj b/qpid/dotnet/client-010/addins/ExcelAddInProducer/ExcelAddInProducer.csproj
new file mode 100644
index 0000000000..d9b1b63737
--- /dev/null
+++ b/qpid/dotnet/client-010/addins/ExcelAddInProducer/ExcelAddInProducer.csproj
@@ -0,0 +1,83 @@
+<!--
+ -
+ - Licensed to the Apache Software Foundation (ASF) under one
+ - or more contributor license agreements. See the NOTICE file
+ - distributed with this work for additional information
+ - regarding copyright ownership. The ASF licenses this file
+ - to you under the Apache License, Version 2.0 (the
+ - "License"); you may not use this file except in compliance
+ - with the License. You may obtain a copy of the License at
+ -
+ - http://www.apache.org/licenses/LICENSE-2.0
+ -
+ - Unless required by applicable law or agreed to in writing,
+ - software distributed under the License is distributed on an
+ - "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ - KIND, either express or implied. See the License for the
+ - specific language governing permissions and limitations
+ - under the License.
+ -
+ -->
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProductVersion>9.0.30729</ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{80F00C3B-EB38-4B3B-9F77-68977A30B155}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>ExcelAddInProducer</RootNamespace>
+ <AssemblyName>Qpid Excel AddIn Producer</AssemblyName>
+ <FileUpgradeFlags>
+ </FileUpgradeFlags>
+ <OldToolsVersion>2.0</OldToolsVersion>
+ <UpgradeBackupLocation>
+ </UpgradeBackupLocation>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="System" />
+ <Reference Include="System.configuration" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="**\*.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\..\client\Client.csproj">
+ <Project>{B911FFD7-754F-4735-A188-218D5065BE79}</Project>
+ <Name>Client</Name>
+ </ProjectReference>
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="..\..\App.config">
+ <Link>App.config</Link>
+ </None>
+ </ItemGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+ <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
+ Other similar extension points exist, see Microsoft.Common.targets.
+ <Target Name="BeforeBuild">
+ </Target>
+ <Target Name="AfterBuild">
+ </Target>
+ -->
+</Project>
diff --git a/qpid/dotnet/client-010/addins/ExcelAddInProducer/Program.cs b/qpid/dotnet/client-010/addins/ExcelAddInProducer/Program.cs
new file mode 100644
index 0000000000..a8bbdf2fbd
--- /dev/null
+++ b/qpid/dotnet/client-010/addins/ExcelAddInProducer/Program.cs
@@ -0,0 +1,62 @@
+/*
+*
+* 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.
+*
+*/
+using System;
+using System.Configuration;
+using System.Text;
+using System.Threading;
+using org.apache.qpid.client;
+
+namespace ExcelAddInProducer
+{
+ class Program
+ {
+ static void Main(string[] args)
+ {
+ string host = ConfigurationManager.AppSettings["Host"];
+ int port = int.Parse(ConfigurationManager.AppSettings["Port"]);
+ string virtualhost = ConfigurationManager.AppSettings["VirtualHost"];
+ string username = ConfigurationManager.AppSettings["Username"];
+ string password = ConfigurationManager.AppSettings["Password"];
+
+ Client client = new Client();
+ Console.WriteLine("Client created");
+ client.Connect(host, port, virtualhost, username, password);
+ Console.WriteLine("Connection established");
+
+ IClientSession ssn = client.CreateSession(50000);
+ Console.WriteLine("Session created");
+ ssn.QueueDeclare("queue1", null, null);
+ ssn.ExchangeBind("queue1", "amq.direct", "queue1", null);
+ IMessage message = new Message();
+ message.ApplicationHeaders.Add("price", 0);
+ for (int i = 0; i < 100; i++)
+ {
+ message.ClearData();
+ message.AppendData( Encoding.UTF8.GetBytes("test: " + i));
+ message.ApplicationHeaders["price"] = i;
+ ssn.MessageTransfer("amq.direct", "queue1", message);
+ Thread.Sleep(1000);
+ }
+
+ client.Close();
+ }
+ }
+}
diff --git a/qpid/dotnet/client-010/addins/ExcelAddInProducer/Properties/AssemblyInfo.cs b/qpid/dotnet/client-010/addins/ExcelAddInProducer/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000000..28fe3427cb
--- /dev/null
+++ b/qpid/dotnet/client-010/addins/ExcelAddInProducer/Properties/AssemblyInfo.cs
@@ -0,0 +1,54 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("Qpid Excel AddIn Producer")]
+[assembly: AssemblyDescription("Built from svn revision number: ")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Apache Software Foundation")]
+[assembly: AssemblyProduct("Qpid Excel AddIn Producer")]
+[assembly: AssemblyCopyright("Apache Software Foundation")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("3416a5c2-eb70-4d77-b401-dfa659bd419e")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+[assembly: AssemblyVersion("0.5.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/qpid/dotnet/client-010/addins/README.txt b/qpid/dotnet/client-010/addins/README.txt
new file mode 100644
index 0000000000..5f8df77189
--- /dev/null
+++ b/qpid/dotnet/client-010/addins/README.txt
@@ -0,0 +1,29 @@
+This project contains three sub-projects:
+- The RTD excell Addin
+- A sample client sending messages to queue1
+- A ample message processor
+
+RDT AddIn
+Excel provides a function called RTD (real-time data) that lets you specify a COM server via its ProgId here "Qpid" so that you can push qpid messages into Excel.
+For using the Qpid RTD follows those steps:
+
+1) Copy the configuration Excel.exe.config into C:\Program Files\Microsoft Office\Office12
+2) Edit Excel.exe.xml and set the targeted Qpid broker host, port number
+3) Select the cell or cell range to contain the information
+4) enter the following formula =rtd("Qpid",,"myQueue") Where MyQueue is the queue from which you wish to receive messages from
+
+Note: The Qpid RTD is a COM-AddIn that must be registered with Excel. This is done automatically when compiling the Addin with visual studio.
+
+The default behavior of the RDT AddIn is to display the message payload. This could be altered by specifying your own message processor.
+A Message processor is a class that implements the API ExcelAddIn.MessageProcessor. For example, the provided processor in client-010\addins\ExcelAddInMessageProcessor displays the message body and the the header price when specified.
+
+To use you own message processor follows those steps:
+1) Write your own message processor that extends ExcelAddIn.MessageProcessor
+2) Edit Excel.exe.config and uncomment the entries:
+ <add key="ProcessorAssembly" value="<path>\qpid\dotnet\client-010\addins\ExcelAddInMessageProcessor\bin\Debug\ExcelAddInMessageProcessor.dll"/>
+ <add key="ProcessorClass" value="ExcelAddInMessageProcessor.Processor"/>
+- ProcessorAssembly is the path on the Assembly that contains your processor class
+- ProcessorClass is your processor class name
+3) run excel and define a rtd function
+
+Note: the provided ExcelAddInProducer can be used for testing the provided message processor. As messages are sent to queue1 the following rtd fucntion should be used =rtd("Qpiud",,"queue1") \ No newline at end of file
diff --git a/qpid/dotnet/client-010/client/Client.csproj b/qpid/dotnet/client-010/client/Client.csproj
new file mode 100644
index 0000000000..000407da59
--- /dev/null
+++ b/qpid/dotnet/client-010/client/Client.csproj
@@ -0,0 +1,242 @@
+<!--
+ -
+ - Licensed to the Apache Software Foundation (ASF) under one
+ - or more contributor license agreements. See the NOTICE file
+ - distributed with this work for additional information
+ - regarding copyright ownership. The ASF licenses this file
+ - to you under the Apache License, Version 2.0 (the
+ - "License"); you may not use this file except in compliance
+ - with the License. You may obtain a copy of the License at
+ -
+ - http://www.apache.org/licenses/LICENSE-2.0
+ -
+ - Unless required by applicable law or agreed to in writing,
+ - software distributed under the License is distributed on an
+ - "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ - KIND, either express or implied. See the License for the
+ - specific language governing permissions and limitations
+ - under the License.
+ -
+ -->
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProductVersion>9.0.30729</ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{B911FFD7-754F-4735-A188-218D5065BE79}</ProjectGuid>
+ <OutputType>Library</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>client</RootNamespace>
+ <AssemblyName>Qpid Client</AssemblyName>
+ <FileUpgradeFlags>
+ </FileUpgradeFlags>
+ <OldToolsVersion>2.0</OldToolsVersion>
+ <UpgradeBackupLocation>
+ </UpgradeBackupLocation>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="log4net, Version=1.2.10.0, Culture=neutral, PublicKeyToken=1b44e1d426115821">
+ <SpecificVersion>False</SpecificVersion>
+ <HintPath>..\lib\log4net\log4net.dll</HintPath>
+ </Reference>
+ <Reference Include="System" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="client\Client.cs" />
+ <Compile Include="client\ClientConnectionDelegate.cs" />
+ <Compile Include="client\ClientSession.cs" />
+ <Compile Include="client\ClientSessionDelegate.cs" />
+ <Compile Include="client\ErrorCode.cs" />
+ <Compile Include="client\IClient.cs" />
+ <Compile Include="client\IClientSession.cs" />
+ <Compile Include="client\IClosedListener.cs" />
+ <Compile Include="client\IMessage.cs" />
+ <Compile Include="client\Message.cs" />
+ <Compile Include="client\IMessageListener.cs" />
+ <Compile Include="generated\Acquired.cs" />
+ <Compile Include="generated\ConnectionClose.cs" />
+ <Compile Include="generated\ConnectionCloseCode.cs" />
+ <Compile Include="generated\ConnectionCloseOk.cs" />
+ <Compile Include="generated\ConnectionHeartbeat.cs" />
+ <Compile Include="generated\ConnectionOpen.cs" />
+ <Compile Include="generated\ConnectionOpenOk.cs" />
+ <Compile Include="generated\ConnectionRedirect.cs" />
+ <Compile Include="generated\ConnectionSecure.cs" />
+ <Compile Include="generated\ConnectionSecureOk.cs" />
+ <Compile Include="generated\ConnectionStart.cs" />
+ <Compile Include="generated\ConnectionStartOk.cs" />
+ <Compile Include="generated\ConnectionTune.cs" />
+ <Compile Include="generated\ConnectionTuneOk.cs" />
+ <Compile Include="generated\Constant.cs" />
+ <Compile Include="generated\DeliveryProperties.cs" />
+ <Compile Include="generated\DtxCommit.cs" />
+ <Compile Include="generated\DtxEnd.cs" />
+ <Compile Include="generated\DtxForget.cs" />
+ <Compile Include="generated\DtxGetTimeout.cs" />
+ <Compile Include="generated\DtxPrepare.cs" />
+ <Compile Include="generated\DtxRecover.cs" />
+ <Compile Include="generated\DtxRollback.cs" />
+ <Compile Include="generated\DtxSelect.cs" />
+ <Compile Include="generated\DtxSetTimeout.cs" />
+ <Compile Include="generated\DtxStart.cs" />
+ <Compile Include="generated\DtxXaStatus.cs" />
+ <Compile Include="generated\ExchangeBind.cs" />
+ <Compile Include="generated\ExchangeBound.cs" />
+ <Compile Include="generated\ExchangeBoundResult.cs" />
+ <Compile Include="generated\ExchangeDeclare.cs" />
+ <Compile Include="generated\ExchangeDelete.cs" />
+ <Compile Include="generated\ExchangeQuery.cs" />
+ <Compile Include="generated\ExchangeQueryResult.cs" />
+ <Compile Include="generated\ExchangeUnbind.cs" />
+ <Compile Include="generated\ExecutionErrorCode.cs" />
+ <Compile Include="generated\ExecutionException.cs" />
+ <Compile Include="generated\ExecutionResult.cs" />
+ <Compile Include="generated\ExecutionSync.cs" />
+ <Compile Include="generated\FileReturnCode.cs" />
+ <Compile Include="generated\FragmentProperties.cs" />
+ <Compile Include="generated\GetTimeoutResult.cs" />
+ <Compile Include="generated\IInvoker.cs" />
+ <Compile Include="generated\Invoker.cs" />
+ <Compile Include="generated\MessageAccept.cs" />
+ <Compile Include="generated\MessageAcceptMode.cs" />
+ <Compile Include="generated\MessageAcquire.cs" />
+ <Compile Include="generated\MessageAcquireMode.cs" />
+ <Compile Include="generated\MessageCancel.cs" />
+ <Compile Include="generated\MessageCreditUnit.cs" />
+ <Compile Include="generated\MessageDeliveryMode.cs" />
+ <Compile Include="generated\MessageDeliveryPriority.cs" />
+ <Compile Include="generated\MessageFlow.cs" />
+ <Compile Include="generated\MessageFlowMode.cs" />
+ <Compile Include="generated\MessageFlush.cs" />
+ <Compile Include="generated\MessageProperties.cs" />
+ <Compile Include="generated\MessageReject.cs" />
+ <Compile Include="generated\MessageRejectCode.cs" />
+ <Compile Include="generated\MessageRelease.cs" />
+ <Compile Include="generated\MessageResume.cs" />
+ <Compile Include="generated\MessageResumeResult.cs" />
+ <Compile Include="generated\MessageSetFlowMode.cs" />
+ <Compile Include="generated\MessageStop.cs" />
+ <Compile Include="generated\MessageSubscribe.cs" />
+ <Compile Include="generated\MessageTransfer.cs" />
+ <Compile Include="generated\MethodDelegate.cs" />
+ <Compile Include="generated\Option.cs" />
+ <Compile Include="generated\QueueDeclare.cs" />
+ <Compile Include="generated\QueueDelete.cs" />
+ <Compile Include="generated\QueuePurge.cs" />
+ <Compile Include="generated\QueueQuery.cs" />
+ <Compile Include="generated\QueueQueryResult.cs" />
+ <Compile Include="generated\RecoverResult.cs" />
+ <Compile Include="generated\ReplyTo.cs" />
+ <Compile Include="generated\SegmentType.cs" />
+ <Compile Include="generated\SessionAttach.cs" />
+ <Compile Include="generated\SessionAttached.cs" />
+ <Compile Include="generated\SessionCommandFragment.cs" />
+ <Compile Include="generated\SessionCommandPoint.cs" />
+ <Compile Include="generated\SessionCompleted.cs" />
+ <Compile Include="generated\SessionConfirmed.cs" />
+ <Compile Include="generated\SessionDetach.cs" />
+ <Compile Include="generated\SessionDetachCode.cs" />
+ <Compile Include="generated\SessionDetached.cs" />
+ <Compile Include="generated\SessionExpected.cs" />
+ <Compile Include="generated\SessionFlush.cs" />
+ <Compile Include="generated\SessionGap.cs" />
+ <Compile Include="generated\SessionHeader.cs" />
+ <Compile Include="generated\SessionKnownCompleted.cs" />
+ <Compile Include="generated\SessionRequestTimeout.cs" />
+ <Compile Include="generated\SessionTimeout.cs" />
+ <Compile Include="generated\StreamReturnCode.cs" />
+ <Compile Include="generated\StructFactory.cs" />
+ <Compile Include="generated\Track.cs" />
+ <Compile Include="generated\TxCommit.cs" />
+ <Compile Include="generated\TxRollback.cs" />
+ <Compile Include="generated\TxSelect.cs" />
+ <Compile Include="generated\Type.cs" />
+ <Compile Include="generated\XaResult.cs" />
+ <Compile Include="generated\Xid.cs" />
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ <Compile Include="transport\Binary.cs" />
+ <Compile Include="transport\IBinding.cs" />
+ <Compile Include="transport\Channel.cs" />
+ <Compile Include="transport\ChannelDelegate.cs" />
+ <Compile Include="transport\ClientDelegate.cs" />
+ <Compile Include="transport\codec\AbstractDecoder.cs" />
+ <Compile Include="transport\codec\AbstractEncoder.cs" />
+ <Compile Include="transport\codec\IDecoder.cs" />
+ <Compile Include="transport\codec\IEncodable.cs" />
+ <Compile Include="transport\codec\IEncoder.cs" />
+ <Compile Include="transport\codec\MSDecoder.cs" />
+ <Compile Include="transport\codec\MSEncoder.cs" />
+ <Compile Include="transport\Connection.cs" />
+ <Compile Include="transport\ConnectionDelegate.cs" />
+ <Compile Include="transport\exception\ConnectionException.cs" />
+ <Compile Include="transport\exception\ExceptionArgs.cs" />
+ <Compile Include="transport\exception\ProtocolVersionException.cs" />
+ <Compile Include="transport\exception\SessionClosedException.cs" />
+ <Compile Include="transport\exception\SessionException.cs" />
+ <Compile Include="transport\exception\TransportException.cs" />
+ <Compile Include="transport\Field.cs" />
+ <Compile Include="transport\IFuture.cs" />
+ <Compile Include="transport\Header.cs" />
+ <Compile Include="transport\ISession.cs" />
+ <Compile Include="transport\Method.cs" />
+ <Compile Include="transport\network\Assembler.cs" />
+ <Compile Include="transport\network\Disassembler.cs" />
+ <Compile Include="transport\network\Frame.cs" />
+ <Compile Include="transport\network\io\IIoSender.cs" />
+ <Compile Include="transport\network\InputHandler.cs" />
+ <Compile Include="transport\network\io\IIoTransport.cs" />
+ <Compile Include="transport\network\io\IoReceiver.cs" />
+ <Compile Include="transport\network\io\IoSender.cs" />
+ <Compile Include="transport\network\io\IoSSLTransport.cs" />
+ <Compile Include="transport\network\io\IoTransport.cs" />
+ <Compile Include="transport\network\INetworkDelegate.cs" />
+ <Compile Include="transport\network\INetworkEvent.cs" />
+ <Compile Include="transport\IProtocolDelegate.cs" />
+ <Compile Include="transport\ProtocolError.cs" />
+ <Compile Include="transport\IProtocolEvent.cs" />
+ <Compile Include="transport\ProtocolHeader.cs" />
+ <Compile Include="transport\Range.cs" />
+ <Compile Include="transport\RangeSet.cs" />
+ <Compile Include="transport\ReceivedPayload.cs" />
+ <Compile Include="transport\IReceiver.cs" />
+ <Compile Include="transport\ISender.cs" />
+ <Compile Include="transport\Session.cs" />
+ <Compile Include="transport\SessionDelegate.cs" />
+ <Compile Include="transport\Struct.cs" />
+ <Compile Include="transport\util\ByteEncoder.cs" />
+ <Compile Include="transport\util\CircularBuffer.cs" />
+ <Compile Include="transport\util\Functions.cs" />
+ <Compile Include="transport\util\Logger.cs" />
+ <Compile Include="transport\util\ResultFuture.cs" />
+ <Compile Include="transport\util\Serial.cs" />
+ <Compile Include="transport\util\UUID.cs" />
+ </ItemGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+ <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
+ Other similar extension points exist, see Microsoft.Common.targets.
+ <Target Name="BeforeBuild">
+ </Target>
+ <Target Name="AfterBuild">
+ </Target>
+ -->
+</Project>
diff --git a/qpid/dotnet/client-010/client/Properties/AssemblyInfo.cs b/qpid/dotnet/client-010/client/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000000..2b6c525b86
--- /dev/null
+++ b/qpid/dotnet/client-010/client/Properties/AssemblyInfo.cs
@@ -0,0 +1,56 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("Qpid Client")]
+[assembly: AssemblyDescription("Built from svn revision number: ")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Apache Software Foundation")]
+[assembly: AssemblyProduct("Qpid Client")]
+[assembly: AssemblyCopyright("Apache Software Foundation")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("dac7ef42-e9c8-45a5-8050-1301b6f8160e")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Revision and Build Numbers
+// by using the '*' as shown below:
+[assembly: AssemblyVersion("0.5.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/qpid/dotnet/client-010/client/client.sln b/qpid/dotnet/client-010/client/client.sln
new file mode 100644
index 0000000000..37455fd177
--- /dev/null
+++ b/qpid/dotnet/client-010/client/client.sln
@@ -0,0 +1,129 @@
+
+Microsoft Visual Studio Solution File, Format Version 10.00
+# Visual Studio 2008
+
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License
+#
+
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Client", "Client.csproj", "{B911FFD7-754F-4735-A188-218D5065BE79}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Demo", "..\demo\Demo.csproj", "{E4C46FBC-7560-406D-BFEF-CA010E584DF4}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ExcelAddIn", "..\addins\ExcelAddIn\ExcelAddIn.csproj", "{85EFD719-39F6-4471-90FF-9E621430344B}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ExcelAddInProducer", "..\addins\ExcelAddInProducer\ExcelAddInProducer.csproj", "{80F00C3B-EB38-4B3B-9F77-68977A30B155}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "example-direct-producer", "..\examples\direct\example-direct-producer\example-direct-producer.csproj", "{96FCB250-8142-40EE-9BDD-CA839EE21021}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "example-direct-Listener", "..\examples\direct\example-direct-Listener\example-direct-Listener.csproj", "{AE65B1B9-8779-4CB1-91AF-E7F6C7A736D7}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "example-pub-sub-Listener", "..\examples\pub-sub\example-pub-sub-Listener\example-pub-sub-Listener.csproj", "{2BCDC2CC-5BDA-4CC7-944D-2899AD8A53C7}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "example-pub-sub-Publisher", "..\examples\pub-sub\example-pub-sub-Publisher\example-pub-sub-Publisher.csproj", "{F8857634-A134-44E7-A953-F2B22688C599}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Test", "..\test\Test.csproj", "{95CB4C90-7C53-44A9-B11C-96235F158ACA}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "example-request-response-Client", "..\examples\request-response\example-request-response-Client\example-request-response-Client.csproj", "{1BC63815-4029-4039-9207-35E7E06ECC99}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "example-request-response-Server", "..\examples\request-response\example-request-response-Server\example-request-response-Server.csproj", "{922FBA9C-E483-4AEF-ABE8-AC87421E829B}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "example-fanout-Producer", "..\examples\fanout\example-fanout-Producer\example-fanout-Producer.csproj", "{4513BF94-D54A-42FE-8506-FE2CD57B2C51}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "example-fanout-Listener", "..\examples\fanout\example-fanout-Listener\example-fanout-Listener.csproj", "{18A0792B-DC3A-4EC5-93D6-DB8A111D8F15}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "perftest", "..\perftest\perftest.csproj", "{7F7E8DE7-FDF2-4A52-A4CE-D3756B05273C}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ExcelAddInMessageProcessor", "..\addins\ExcelAddInMessageProcessor\ExcelAddInMessageProcessor.csproj", "{C2AE83A3-D5D1-469D-8611-A4738B9997CF}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{3CE4FA2A-393F-4DED-ABDF-1BC2F253ACA8}"
+ ProjectSection(SolutionItems) = preProject
+ ..\App.config = ..\App.config
+ EndProjectSection
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {B911FFD7-754F-4735-A188-218D5065BE79}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {B911FFD7-754F-4735-A188-218D5065BE79}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {B911FFD7-754F-4735-A188-218D5065BE79}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {B911FFD7-754F-4735-A188-218D5065BE79}.Release|Any CPU.Build.0 = Release|Any CPU
+ {E4C46FBC-7560-406D-BFEF-CA010E584DF4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {E4C46FBC-7560-406D-BFEF-CA010E584DF4}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {E4C46FBC-7560-406D-BFEF-CA010E584DF4}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {E4C46FBC-7560-406D-BFEF-CA010E584DF4}.Release|Any CPU.Build.0 = Release|Any CPU
+ {85EFD719-39F6-4471-90FF-9E621430344B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {85EFD719-39F6-4471-90FF-9E621430344B}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {85EFD719-39F6-4471-90FF-9E621430344B}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {85EFD719-39F6-4471-90FF-9E621430344B}.Release|Any CPU.Build.0 = Release|Any CPU
+ {80F00C3B-EB38-4B3B-9F77-68977A30B155}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {80F00C3B-EB38-4B3B-9F77-68977A30B155}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {80F00C3B-EB38-4B3B-9F77-68977A30B155}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {80F00C3B-EB38-4B3B-9F77-68977A30B155}.Release|Any CPU.Build.0 = Release|Any CPU
+ {96FCB250-8142-40EE-9BDD-CA839EE21021}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {96FCB250-8142-40EE-9BDD-CA839EE21021}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {96FCB250-8142-40EE-9BDD-CA839EE21021}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {96FCB250-8142-40EE-9BDD-CA839EE21021}.Release|Any CPU.Build.0 = Release|Any CPU
+ {AE65B1B9-8779-4CB1-91AF-E7F6C7A736D7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {AE65B1B9-8779-4CB1-91AF-E7F6C7A736D7}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {AE65B1B9-8779-4CB1-91AF-E7F6C7A736D7}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {AE65B1B9-8779-4CB1-91AF-E7F6C7A736D7}.Release|Any CPU.Build.0 = Release|Any CPU
+ {2BCDC2CC-5BDA-4CC7-944D-2899AD8A53C7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {2BCDC2CC-5BDA-4CC7-944D-2899AD8A53C7}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {2BCDC2CC-5BDA-4CC7-944D-2899AD8A53C7}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {2BCDC2CC-5BDA-4CC7-944D-2899AD8A53C7}.Release|Any CPU.Build.0 = Release|Any CPU
+ {F8857634-A134-44E7-A953-F2B22688C599}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {F8857634-A134-44E7-A953-F2B22688C599}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {F8857634-A134-44E7-A953-F2B22688C599}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {F8857634-A134-44E7-A953-F2B22688C599}.Release|Any CPU.Build.0 = Release|Any CPU
+ {95CB4C90-7C53-44A9-B11C-96235F158ACA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {95CB4C90-7C53-44A9-B11C-96235F158ACA}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {95CB4C90-7C53-44A9-B11C-96235F158ACA}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {95CB4C90-7C53-44A9-B11C-96235F158ACA}.Release|Any CPU.Build.0 = Release|Any CPU
+ {1BC63815-4029-4039-9207-35E7E06ECC99}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {1BC63815-4029-4039-9207-35E7E06ECC99}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {1BC63815-4029-4039-9207-35E7E06ECC99}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {1BC63815-4029-4039-9207-35E7E06ECC99}.Release|Any CPU.Build.0 = Release|Any CPU
+ {922FBA9C-E483-4AEF-ABE8-AC87421E829B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {922FBA9C-E483-4AEF-ABE8-AC87421E829B}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {922FBA9C-E483-4AEF-ABE8-AC87421E829B}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {922FBA9C-E483-4AEF-ABE8-AC87421E829B}.Release|Any CPU.Build.0 = Release|Any CPU
+ {4513BF94-D54A-42FE-8506-FE2CD57B2C51}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {4513BF94-D54A-42FE-8506-FE2CD57B2C51}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {4513BF94-D54A-42FE-8506-FE2CD57B2C51}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {4513BF94-D54A-42FE-8506-FE2CD57B2C51}.Release|Any CPU.Build.0 = Release|Any CPU
+ {18A0792B-DC3A-4EC5-93D6-DB8A111D8F15}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {18A0792B-DC3A-4EC5-93D6-DB8A111D8F15}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {18A0792B-DC3A-4EC5-93D6-DB8A111D8F15}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {18A0792B-DC3A-4EC5-93D6-DB8A111D8F15}.Release|Any CPU.Build.0 = Release|Any CPU
+ {7F7E8DE7-FDF2-4A52-A4CE-D3756B05273C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {7F7E8DE7-FDF2-4A52-A4CE-D3756B05273C}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {7F7E8DE7-FDF2-4A52-A4CE-D3756B05273C}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {7F7E8DE7-FDF2-4A52-A4CE-D3756B05273C}.Release|Any CPU.Build.0 = Release|Any CPU
+ {C2AE83A3-D5D1-469D-8611-A4738B9997CF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {C2AE83A3-D5D1-469D-8611-A4738B9997CF}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {C2AE83A3-D5D1-469D-8611-A4738B9997CF}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {C2AE83A3-D5D1-469D-8611-A4738B9997CF}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/qpid/dotnet/client-010/client/client.suo b/qpid/dotnet/client-010/client/client.suo
new file mode 100644
index 0000000000..0640275f99
--- /dev/null
+++ b/qpid/dotnet/client-010/client/client.suo
Binary files differ
diff --git a/qpid/dotnet/client-010/client/client/Client.cs b/qpid/dotnet/client-010/client/client/Client.cs
new file mode 100644
index 0000000000..fc9ff22191
--- /dev/null
+++ b/qpid/dotnet/client-010/client/client/Client.cs
@@ -0,0 +1,195 @@
+/*
+* 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.
+*/
+using System;
+using System.Text;
+using System.Threading;
+using org.apache.qpid.transport;
+using org.apache.qpid.transport.network.io;
+using org.apache.qpid.transport.util;
+using System.Security.Cryptography.X509Certificates;
+
+namespace org.apache.qpid.client
+{
+ public class Client : IClient
+ {
+ private Connection _conn;
+ private static readonly Logger _log = Logger.Get(typeof (Client));
+ private const long timeout = 60000;
+ private bool _isClosed;
+ private readonly Object _closeOK;
+ private IClosedListener _closedListner;
+
+ public event EventHandler<ExceptionArgs> ExceptionRaised;
+ public event EventHandler ConnectionOpenOK;
+ public event EventHandler ConnectionLost;
+
+ public bool IsClosed
+ {
+ get { return _isClosed; }
+ set
+ {
+ _isClosed = value;
+ if(_isClosed && ConnectionLost != null)
+ ConnectionLost(this, EventArgs.Empty);
+ }
+ }
+
+ public Object CloseOk
+ {
+ get { return _closeOK; }
+ }
+
+ public Client()
+ {
+ _isClosed = false;
+ _closeOK = new object();
+ }
+
+ #region Interface IClient
+
+ public void Connect(String host, int port, String virtualHost, String username, String password)
+ {
+ Connect(host, port, virtualHost, username, password, "PLAIN");
+ }
+
+ /// <summary>
+ /// Establishes a connection with a broker using the provided user auths
+ ///
+ /// </summary>
+ /// <param name="host">Host name on which a broker is deployed</param>
+ /// <param name="port">Broker port </param>
+ /// <param name="virtualHost">virtual host name</param>
+ /// <param name="username">User Name</param>
+ /// <param name="password">Password</param>
+ /// <param name="mechanism">SASL authentication mechanism, possible values: PLAIN, EXTERNAL, DIGEST-MD5, ANONYMOUS</param>
+ public void Connect(String host, int port, String virtualHost, String username, String password, String mechanism)
+ {
+ _log.Debug(String.Format("Client Connecting to host {0}; port {1}; virtualHost {2}; username {3}; mechanism {4}",
+ host, port, virtualHost, username, mechanism));
+ ClientConnectionDelegate connectionDelegate = new ClientConnectionDelegate(this, username, password, mechanism);
+ ManualResetEvent negotiationComplete = new ManualResetEvent(false);
+ connectionDelegate.SetCondition(negotiationComplete);
+ connectionDelegate.VirtualHost = virtualHost;
+ _conn = IoTransport.Connect(host, port, connectionDelegate);
+
+ _conn.Send(new ProtocolHeader(1, 0, 10));
+ negotiationComplete.WaitOne();
+
+ if (connectionDelegate.Exception != null)
+ throw connectionDelegate.Exception;
+
+ connectionDelegate.SetCondition(null);
+
+ }
+
+ /// <summary>
+ /// Establishes a connection with a broker using SSL
+ ///
+ /// </summary>
+ /// <param name="host">Host name on which a broker is deployed</param>
+ /// <param name="port">Broker port </param>
+ /// <param name="virtualHost">virtual host name</param>
+ /// <param name="username">User Name</param>
+ /// <param name="password">Password</param>
+ /// <param name="mechanism">SASL authentication mechanism, possible values: PLAIN, EXTERNAL, DIGEST-MD5, ANONYMOUS</param>
+ /// <param name="serverName">Name of the SSL server</param>
+ /// <param name="certPath">Path to the X509 certificate to be used for client authentication</param>
+ /// <param name="certPass">Password to certificate file, pass null if no password is required</param>
+ /// <param name="rejectUntrusted">If true connection will not be established if the broker is not trusted</param>
+ public void ConnectSSL(String host, int port, String virtualHost, String username, String password, String mechanism, string serverName, string certPath, String certPass, bool rejectUntrusted)
+ {
+ _log.Debug(String.Format("Client Connecting to host {0}; port {1}; virtualHost {2}; username {3}; mechanism {4}",
+ host, port, virtualHost, username, mechanism));
+ _log.Debug(String.Format("SSL parameters: serverName: {0}; certPath: {1}; rejectUntrusted: {2}", serverName, certPath, rejectUntrusted));
+ _conn = IoSSLTransport.Connect(host, port, virtualHost, mechanism, serverName, certPath, certPass, rejectUntrusted, this);
+ }
+
+ /// <summary>
+ /// Establishes a connection with a broker using SSL
+ ///
+ /// </summary>
+ /// <param name="host">Host name on which a broker is deployed</param>
+ /// <param name="port">Broker port </param>
+ /// <param name="mechanism">SASL authentication mechanism, possible values: PLAIN, EXTERNAL, DIGEST-MD5, ANONYMOUS</param>
+ /// <param name="certificate">X509 certificate to be used for client authentication</param>
+ /// <param name="rejectUntrusted">If true connection will not be established if the broker is not trusted</param>
+ public void ConnectSSL(String host, int port, String mechanism, X509Certificate certificate, bool rejectUntrusted)
+ {
+ _log.Debug(String.Format("Client Connecting to host {0}; port {1}; mechanism {2}",
+ host, port, mechanism));
+ _log.Debug(String.Format("SSL parameters: certSubject: {0}; rejectUntrusted: {1}",
+ certificate.Subject, rejectUntrusted));
+
+ _conn = IoSSLTransport.Connect(host, port, mechanism, certificate, rejectUntrusted, this);
+ }
+
+ public void Close()
+ {
+ Channel ch = _conn.GetChannel(0);
+ ch.ConnectionClose(ConnectionCloseCode.NORMAL, "client is closing");
+ lock (CloseOk)
+ {
+ DateTime start = DateTime.Now;
+ long elapsed = 0;
+ while (!IsClosed && elapsed < timeout)
+ {
+ Monitor.Wait(CloseOk, (int) (timeout - elapsed));
+ elapsed = DateTime.Now.Subtract(start).Milliseconds;
+ }
+ if (!IsClosed)
+ {
+ throw new Exception("Timed out when closing connection");
+ }
+ _conn.Close();
+ }
+ }
+
+ public IClientSession CreateSession(long expiryInSeconds)
+ {
+ Channel ch = _conn.GetChannel();
+ ClientSession ssn = new ClientSession(Encoding.UTF8.GetBytes(UUID.RandomUuid().ToString()));
+ ssn.Attach(ch);
+ ssn.SessionAttach(ssn.GetName());
+ ssn.SessionRequestTimeout(expiryInSeconds);
+ return ssn;
+ }
+
+ public IClosedListener ClosedListener
+ {
+ set { _closedListner = value; }
+ get { return _closedListner; }
+ }
+
+ #endregion
+
+ public void RaiseException(Exception exception)
+ {
+ if (ExceptionRaised != null)
+ ExceptionRaised(this, new ExceptionArgs(exception));
+ }
+
+ internal void ConnectionOpenOk(Channel context, ConnectionOpenOk mstruct)
+ {
+ if (ConnectionOpenOK != null)
+ {
+ ConnectionOpenOK(this, new EventArgs());
+ }
+ }
+ }
+}
diff --git a/qpid/dotnet/client-010/client/client/ClientConnectionDelegate.cs b/qpid/dotnet/client-010/client/client/ClientConnectionDelegate.cs
new file mode 100644
index 0000000000..83aac80e83
--- /dev/null
+++ b/qpid/dotnet/client-010/client/client/ClientConnectionDelegate.cs
@@ -0,0 +1,128 @@
+/*
+* 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.
+*/
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Text;
+using System.Threading;
+using org.apache.qpid.transport;
+using org.apache.qpid.transport.util;
+
+namespace org.apache.qpid.client
+{
+ internal class ClientConnectionDelegate : ClientDelegate
+ {
+ private static readonly Logger log = Logger.Get(typeof (ClientConnectionDelegate));
+ private readonly Client _client;
+ private string _username;
+ private string _password;
+
+ // PLAIN SASL mechanism by default
+ private string _mechanism = "PLAIN";
+ private Exception _exception;
+
+ public ClientConnectionDelegate(Client client, string username, string pasword)
+ {
+ _client = client;
+ _username = username;
+ _password = pasword;
+ }
+
+ public ClientConnectionDelegate(Client client, string username, string pasword, string mechanism)
+ : this(client, username, pasword)
+ {
+ _mechanism = mechanism;
+ }
+
+ public Exception Exception
+ {
+ get { return _exception; }
+ }
+
+ public override SessionDelegate GetSessionDelegate()
+ {
+ return new ClientSessionDelegate();
+ }
+
+ public override void RaiseException(Exception exception)
+ {
+ _exception = exception;
+
+ if (_negotiationComplete != null)
+ _negotiationComplete.Set();
+ else
+ _client.RaiseException(exception);
+ }
+
+ public override void ConnectionStart(Channel context, ConnectionStart mystruct)
+ {
+ MemoryStream stResponse = new MemoryStream();
+
+ // do not send username and password for EXTERNAL mechanism,
+ // because they are inside a certificate file
+ if (_mechanism != "EXTERNAL")
+ {
+ byte[] part = Encoding.UTF8.GetBytes(_username);
+ stResponse.WriteByte(0);
+ stResponse.Write(part, 0, part.Length);
+ stResponse.WriteByte(0);
+ part = Encoding.UTF8.GetBytes(_password);
+ stResponse.Write(part, 0, part.Length);
+ }
+ Dictionary<String, Object> props = new Dictionary<String, Object>();
+ context.ConnectionStartOk(props, _mechanism, stResponse.ToArray(), "utf8");
+ }
+
+ public override void ConnectionOpenOk(Channel context, ConnectionOpenOk mstruct)
+ {
+ base.ConnectionOpenOk(context, mstruct);
+ _client.ConnectionOpenOk(context, mstruct);
+ }
+
+ public override void Closed()
+ {
+ log.Debug("Delegate Closed");
+ lock (_client.CloseOk)
+ {
+ try
+ {
+ _client.IsClosed = true;
+ Monitor.PulseAll(_client.CloseOk);
+ }
+ catch (Exception e)
+ {
+ throw new SystemException("Error when closing client", e);
+ }
+ }
+ }
+
+ public override void ConnectionClose(Channel context, ConnectionClose connectionClose)
+ {
+ base.ConnectionClose(context, connectionClose);
+ ErrorCode errorCode = ErrorCode.GetErrorCode((int) connectionClose.GetReplyCode());
+
+ if(_client.ClosedListener != null)
+ _client.ClosedListener.OnClosed(errorCode, connectionClose.GetReplyText(), null);
+
+ if (errorCode.Code != (int)QpidErrorCode.NO_ERROR)
+ throw new Exception ("Server Closed the connection: Reason " + connectionClose.GetReplyText());
+ }
+ }
+}
diff --git a/qpid/dotnet/client-010/client/client/ClientInterface.cs b/qpid/dotnet/client-010/client/client/ClientInterface.cs
new file mode 100644
index 0000000000..fcf7ae9f31
--- /dev/null
+++ b/qpid/dotnet/client-010/client/client/ClientInterface.cs
@@ -0,0 +1,59 @@
+/*
+* 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.
+*/
+
+using System;
+
+namespace org.apache.qpid.client
+{
+ public interface ClientInterface
+ {
+ /// <summary>
+ /// Establish a connection with the broker using the given parameters
+ ///
+ /// </summary>
+ /// <param name="host">host name</param>
+ /// <param name="port">port number</param>
+ /// <param name="virtualHost">virtualHost the virtual host name</param>
+ /// <param name="username"> username user name</param>
+ /// <param name="passwor">password password</param>
+ void connect(String host, int port, String virtualHost, String username, String passwor);
+
+ /// <summary>
+ /// Close this client
+ /// </summary>
+ void close();
+
+ /// <summary>
+ /// Create a session for this connection.
+ /// The returned session is suspended
+ /// (i.e. this session is not attached to an underlying channel)
+ /// </summary>
+ /// <param name="expiryInSeconds">Expiry time expressed in seconds, if the value is less than
+ /// or equal to 0 then the session does not expire.</param>
+ /// <returns>A newly created (suspended) session.</returns>
+ ClientSession createSession(long expiryInSeconds);
+
+ /// <summary>
+ /// If the communication layer detects a serious problem with a connection, it
+ // informs the client's ClosedListener
+ /// </summary>
+ ///
+ ClosedListener ClosedListener { set; }
+ }
+}
diff --git a/qpid/dotnet/client-010/client/client/ClientSession.cs b/qpid/dotnet/client-010/client/client/ClientSession.cs
new file mode 100644
index 0000000000..190fd7c940
--- /dev/null
+++ b/qpid/dotnet/client-010/client/client/ClientSession.cs
@@ -0,0 +1,109 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using org.apache.qpid.transport;
+using org.apache.qpid.transport.util;
+
+namespace org.apache.qpid.client
+{
+ /// <summary> Implements a Qpid Sesion.</summary>
+ public class ClientSession : Session, IClientSession
+ {
+ public static short TRANSFER_ACQUIRE_MODE_NO_ACQUIRE = 1;
+ public static short TRANSFER_ACQUIRE_MODE_PRE_ACQUIRE = 0;
+ public static short TRANSFER_CONFIRM_MODE_REQUIRED = 0;
+ public static short TRANSFER_CONFIRM_MODE_NOT_REQUIRED = 1;
+ public static short MESSAGE_FLOW_MODE_CREDIT = 0;
+ public static short MESSAGE_FLOW_MODE_WINDOW = 1;
+ public static short MESSAGE_FLOW_UNIT_MESSAGE = 0;
+ public static short MESSAGE_FLOW_UNIT_BYTE = 1;
+ public static long MESSAGE_FLOW_MAX_BYTES = 0xFFFFFFFF;
+ public static short MESSAGE_REJECT_CODE_GENERIC = 0;
+ public static short MESSAGE_REJECT_CODE_IMMEDIATE_DELIVERY_FAILED = 1;
+ public static short MESSAGE_ACQUIRE_ANY_AVAILABLE_MESSAGE = 0;
+ public static short MESSAGE_ACQUIRE_MESSAGES_IF_ALL_ARE_AVAILABLE = 1;
+
+ private readonly Dictionary<String, IMessageListener> _listeners = new Dictionary<String, IMessageListener>();
+
+ public ClientSession(byte[] name) : base(name)
+ {
+ }
+
+ public void AttachMessageListener(IMessageListener listener, string Destination)
+ {
+ _listeners.Add(Destination, listener);
+ }
+
+ public Dictionary<String, IMessageListener> MessageListeners
+ {
+ get { return _listeners; }
+ }
+
+ public void MessageTransfer(String destination, string routingkey, IMessage message)
+ {
+ message.DeliveryProperties.SetRoutingKey(routingkey);
+ MessageTransfer(destination, message);
+ }
+
+ public void MessageTransfer(String destination, IMessage message)
+ {
+ byte[] body = new byte[message.Body.Position];
+ message.Body.Seek(0, SeekOrigin.Begin);
+ message.Body.Read(body, 0, body.Length);
+ message.MessageProperties.SetMessageId(UUID.RandomUuid());
+ MessageTransfer(destination,
+ MessageAcceptMode.NONE,
+ MessageAcquireMode.PRE_ACQUIRED,
+ message.Header,
+ body);
+ }
+
+ public void QueueDeclare(String queue)
+ {
+ QueueDeclare(queue, null, null);
+ }
+
+ public void QueueDeclare(String queue, params Option[] options)
+ {
+ QueueDeclare(queue, null, null, options);
+ }
+
+ public void ExchangeBind(String queue, String exchange, String bindingKey)
+ {
+ ExchangeBind(queue, exchange, bindingKey, null);
+ }
+
+ public void MessageSubscribe(String queue)
+ {
+ MessageSubscribe(queue, queue, MessageAcceptMode.EXPLICIT, MessageAcquireMode.PRE_ACQUIRED, null, 0, null);
+ // issue credits
+ MessageSetFlowMode(queue, MessageFlowMode.WINDOW);
+ MessageFlow(queue, MessageCreditUnit.BYTE, MESSAGE_FLOW_MAX_BYTES);
+ MessageFlow(queue, MessageCreditUnit.MESSAGE, 10000);
+ }
+
+ }
+}
diff --git a/qpid/dotnet/client-010/client/client/ClientSessionDelegate.cs b/qpid/dotnet/client-010/client/client/ClientSessionDelegate.cs
new file mode 100644
index 0000000000..7cc4042557
--- /dev/null
+++ b/qpid/dotnet/client-010/client/client/ClientSessionDelegate.cs
@@ -0,0 +1,55 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing,
+* software distributed under the License is distributed on an
+* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+* KIND, either express or implied. See the License for the
+* specific language governing permissions and limitations
+* under the License.
+*/
+using org.apache.qpid.transport;
+using org.apache.qpid.transport.util;
+
+namespace org.apache.qpid.client
+{
+ public class ClientSessionDelegate : SessionDelegate
+ {
+ private static readonly Logger _log = Logger.Get(typeof (ClientSessionDelegate));
+
+ // --------------------------------------------
+ // Message methods
+ // --------------------------------------------
+ public override void MessageTransfer(Session session, MessageTransfer xfr)
+ {
+ if (((ClientSession) session).MessageListeners.ContainsKey(xfr.GetDestination()))
+ {
+ IMessageListener listener = ((ClientSession)session).MessageListeners[xfr.GetDestination()];
+ listener.MessageTransfer( new Message(xfr));
+ }
+ else
+ {
+ _log.Warn("No listener set for: {0}", xfr);
+ }
+ }
+
+ public override void MessageReject(Session session, MessageReject mstruct)
+ {
+ foreach (Range range in mstruct.GetTransfers())
+ {
+ for (long l = range.Lower; l <= range.Upper; l++)
+ {
+ _log.Warn("message rejected: " + session.GetCommand((int) l));
+ }
+ }
+ }
+ }
+}
diff --git a/qpid/dotnet/client-010/client/client/ClosedListenerInterface.cs b/qpid/dotnet/client-010/client/client/ClosedListenerInterface.cs
new file mode 100644
index 0000000000..133b00abdd
--- /dev/null
+++ b/qpid/dotnet/client-010/client/client/ClosedListenerInterface.cs
@@ -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.
+*/
+
+using System;
+
+namespace org.apache.qpid.client
+{
+ public interface ClosedListener
+ {
+
+ void onClosed(ErrorCode errorCode, String reason, Exception t);
+ }
+}
diff --git a/qpid/dotnet/client-010/client/client/ErrorCode.cs b/qpid/dotnet/client-010/client/client/ErrorCode.cs
new file mode 100644
index 0000000000..74c3daba4b
--- /dev/null
+++ b/qpid/dotnet/client-010/client/client/ErrorCode.cs
@@ -0,0 +1,140 @@
+/*
+* 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.
+*/
+
+using System;
+
+namespace org.apache.qpid.client
+{
+ public enum QpidErrorCode
+ {
+ NO_ERROR = 200,
+ CONTENT_TOO_LARGE = 311,
+ NO_ROUTE = 312,
+ NO_CONSUMERS = 313,
+ CONNECTION_FORCED = 320,
+ INVALID_PATH = 402,
+ ACCESS_REFUSED = 403,
+ NOT_FOUND = 404,
+ RESOURCE_LOCKED = 405,
+ PRE_CONDITION_FAILED = 406,
+ FRAME_ERROR = 501,
+ SYNTAX_ERROR = 502,
+ COMMAND_INVALID = 503,
+ SESSION_ERROR = 504,
+ NOT_ALLOWED = 530,
+ NOT_IMPLEMENTED = 540,
+ INTERNAL_ERROR = 541,
+ INVALID_ARGUMENT = 542,
+ UNDEFINED = 1
+ }
+
+ public struct ErrorCode
+ {
+ private int _code;
+ private String _desc;
+ private readonly bool _hardError;
+
+ public ErrorCode(int code, String desc, bool hardError)
+ {
+ _code = code;
+ _desc = desc;
+ _hardError = hardError;
+ }
+
+ public int Code
+ {
+ get { return _code; }
+ set { _code = value; }
+ }
+
+ public String Description
+ {
+ get { return _desc; }
+ set { _desc = value; }
+ }
+
+ public bool ISHardError
+ {
+ get { return _hardError; }
+ }
+
+ public static ErrorCode GetErrorCode(int code)
+ {
+ switch (code)
+ {
+ case 200:
+ return
+ new ErrorCode(200, "reply-success", true);
+ case 311:
+ return
+ new ErrorCode(311, "content-too-large", false);
+ case 312:
+ return
+ new ErrorCode(312, "no-route", false);
+ case 313:
+ return
+ new ErrorCode(313, "content-consumers", false);
+ case 320:
+ return
+ new ErrorCode(320, "connection-forced", true);
+ case 402:
+ return
+ new ErrorCode(402, "invalid-path", true);
+ case 403:
+ return
+ new ErrorCode(403, "access-refused", false);
+ case 404:
+ return
+ new ErrorCode(404, "not-found", false);
+ case 405:
+ return
+ new ErrorCode(405, "resource-locked", false);
+ case 406:
+ return
+ new ErrorCode(406, "precondition-failed", false);
+ case 501:
+ return
+ new ErrorCode(501, "frame_error", true);
+ case 502:
+ return
+ new ErrorCode(502, "syntax_error", true);
+ case 503:
+ return
+ new ErrorCode(503, "command_invalid", true);
+ case 504:
+ return
+ new ErrorCode(504, "sesion_error", true);
+ case 530:
+ return
+ new ErrorCode(530, "not_allowed", true);
+ case 540:
+ return
+ new ErrorCode(540, "not_implemented", true);
+ case 541:
+ return
+ new ErrorCode(541, "internal_error", true);
+ case 542:
+ return
+ new ErrorCode(542, "invalid_argument", true);
+ default:
+ return new ErrorCode(1, "undefined", true);
+ }
+ }
+ }
+}
diff --git a/qpid/dotnet/client-010/client/client/IClient.cs b/qpid/dotnet/client-010/client/client/IClient.cs
new file mode 100644
index 0000000000..b7b6c26957
--- /dev/null
+++ b/qpid/dotnet/client-010/client/client/IClient.cs
@@ -0,0 +1,82 @@
+/*
+* 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.
+*/
+
+using System;
+using org.apache.qpid.transport;
+
+namespace org.apache.qpid.client
+{
+ public interface IClient
+ {
+ /// <summary>
+ /// Establish a connection with the broker using the given parameters
+ ///
+ /// </summary>
+ /// <param name="host">host name</param>
+ /// <param name="port">port number</param>
+ /// <param name="virtualHost">virtualHost the virtual host name</param>
+ /// <param name="username"> username user name</param>
+ /// <param name="passwor">password password</param>
+ void Connect(String host, int port, String virtualHost, String username, String password, String mechanism);
+ void Connect(String host, int port, String virtualHost, String username, String password);
+
+ /// <summary>
+ /// Close this client
+ /// </summary>
+ void Close();
+
+ /// <summary>
+ /// Create a session for this connection.
+ /// The returned session is suspended
+ /// (i.e. this session is not attached to an underlying channel)
+ /// </summary>
+ /// <param name="expiryInSeconds">Expiry time expressed in seconds, if the value is less than
+ /// or equal to 0 then the session does not expire.</param>
+ /// <returns>A newly created (suspended) session.</returns>
+ IClientSession CreateSession(long expiryInSeconds);
+
+
+ event EventHandler<ExceptionArgs> ExceptionRaised;
+ event EventHandler ConnectionLost;
+
+ /// <summary>
+ /// If the broker sends a disconnect message, it will notify the ClosedListener
+ /// </summary>
+ ///
+ IClosedListener ClosedListener { set; }
+
+
+
+ bool IsClosed { get; set; }
+
+ /// <summary>
+ /// Establishes a connection with a broker using SSL
+ ///
+ /// </summary>
+ /// <param name="host">Host name on which a broker is deployed</param>
+ /// <param name="port">Broker port </param>
+ /// <param name="virtualHost">virtual host name</param>
+ /// <param name="username">User Name</param>
+ /// <param name="password">Password</param>
+ /// <param name="serverName">Name of the SSL server</param>
+ /// <param name="certPath">Path to the X509 certificate to be used for client authentication</param>
+ /// <param name="rejectUntrusted">If true connection will not be established if the broker is not trusted</param>
+ void ConnectSSL(String host, int port, String virtualHost, String username, String password, String mechanism, string serverName, string certPath, String certPass, bool rejectUntrusted);
+ }
+}
diff --git a/qpid/dotnet/client-010/client/client/IClientSession.cs b/qpid/dotnet/client-010/client/client/IClientSession.cs
new file mode 100644
index 0000000000..8667db1fb4
--- /dev/null
+++ b/qpid/dotnet/client-010/client/client/IClientSession.cs
@@ -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.
+ *
+ */
+
+using System;
+using System.Collections.Generic;
+using org.apache.qpid.transport;
+
+namespace org.apache.qpid.client
+{
+ public interface IClientSession : ISession
+ {
+ void AttachMessageListener(IMessageListener listener, string Destination);
+ Dictionary<String, IMessageListener> MessageListeners { get; }
+ void MessageTransfer(String destination, string routingkey, IMessage message);
+ void MessageTransfer(String destination, IMessage message);
+ void QueueDeclare(String queue);
+ void QueueDeclare(String queue, params Option[] options);
+ void ExchangeBind(String queue, String exchange, String bindingKey);
+ void MessageSubscribe(String queue);
+ }
+}
diff --git a/qpid/dotnet/client-010/client/client/IClosedListener.cs b/qpid/dotnet/client-010/client/client/IClosedListener.cs
new file mode 100644
index 0000000000..0e2472bba6
--- /dev/null
+++ b/qpid/dotnet/client-010/client/client/IClosedListener.cs
@@ -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.
+*/
+
+using System;
+
+namespace org.apache.qpid.client
+{
+ public interface IClosedListener
+ {
+
+ void OnClosed(ErrorCode errorCode, String reason, Exception t);
+ }
+}
diff --git a/qpid/dotnet/client-010/client/client/IMessage.cs b/qpid/dotnet/client-010/client/client/IMessage.cs
new file mode 100644
index 0000000000..6eae826a4c
--- /dev/null
+++ b/qpid/dotnet/client-010/client/client/IMessage.cs
@@ -0,0 +1,48 @@
+/*
+*
+* 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.
+*
+*/
+using System;
+using System.Collections.Generic;
+using System.IO;
+using org.apache.qpid.transport;
+
+namespace org.apache.qpid.client
+{
+ public interface IMessage
+ {
+ int Id { get; }
+
+ Header Header { get; set; }
+
+ MessageProperties MessageProperties { get; set; }
+
+ DeliveryProperties DeliveryProperties { get; set; }
+
+ Dictionary<String, Object> ApplicationHeaders { get; set; }
+
+ void AppendData(byte[] bytes);
+
+ MemoryStream Body { get; }
+
+ string Destination { get; }
+
+ void ClearData();
+ }
+}
diff --git a/qpid/dotnet/client-010/client/client/IMessageListener.cs b/qpid/dotnet/client-010/client/client/IMessageListener.cs
new file mode 100644
index 0000000000..44ceb3721e
--- /dev/null
+++ b/qpid/dotnet/client-010/client/client/IMessageListener.cs
@@ -0,0 +1,31 @@
+/*
+* 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.
+*/
+
+
+namespace org.apache.qpid.client
+{
+ public interface IMessageListener
+ {
+ /// <summary>
+ /// Inform the listener of the message transfer
+ /// </summary>
+ /// <param name="xfr">The message transfer object</param>
+ void MessageTransfer(IMessage xfr);
+ }
+}
diff --git a/qpid/dotnet/client-010/client/client/Message.cs b/qpid/dotnet/client-010/client/client/Message.cs
new file mode 100644
index 0000000000..6ab62070d2
--- /dev/null
+++ b/qpid/dotnet/client-010/client/client/Message.cs
@@ -0,0 +1,131 @@
+/*
+*
+* 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.
+*
+*/
+using System.Collections.Generic;
+using System.IO;
+using org.apache.qpid.transport;
+
+namespace org.apache.qpid.client
+{
+ public class Message : IMessage
+ {
+ private readonly MessageTransfer _message;
+
+ public Message(MessageTransfer m)
+ {
+ _message = m;
+ }
+
+ public Message()
+ {
+ _message = new MessageTransfer();
+ _message.Header = new Header( new MessageProperties(), new DeliveryProperties());
+ ((MessageProperties) _message.Header.Structs[0]).SetApplicationHeaders(new Dictionary<string, object>());
+ }
+
+ public MessageProperties MessageProperties
+ {
+ get
+ {
+ if (_message.Header != null && Header.Structs.Length > 1)
+ return (MessageProperties) Header.Structs[0];
+ return null;
+ }
+ set
+ {
+ if (_message.Header != null)
+ {
+ Header.Structs[0] = value;
+ }
+ }
+ }
+
+ public DeliveryProperties DeliveryProperties
+ {
+ get
+ {
+ if (Header != null)
+ {
+ if( Header.Structs.Length > 1 )
+ return (DeliveryProperties)Header.Structs[1];
+ return (DeliveryProperties)Header.Structs[0];
+ }
+
+ return null;
+ }
+ set
+ {
+ if (Header != null)
+ {
+ Header.Structs[1] = value;
+ }
+ }
+ }
+
+ public Dictionary<string, object> ApplicationHeaders
+ {
+ get
+ {
+ if (Header != null)
+ return ((MessageProperties) Header.Structs[0]).GetApplicationHeaders();
+ return null;
+ }
+ set
+ {
+ if (Header != null)
+ {
+ ((MessageProperties) Header.Structs[0]).SetApplicationHeaders(value);
+ }
+ }
+ }
+
+ public void AppendData(byte[] bytes)
+ {
+ Body.Write(bytes, 0, bytes.Length);
+ }
+
+ public void ClearData()
+ {
+ Body.Seek(0, SeekOrigin.Begin);
+ }
+
+ public Header Header
+ {
+ get{ return _message.Header;}
+ set{ _message.Header = value;}
+ }
+
+ public MemoryStream Body
+ {
+ get { return _message.Body; }
+ set { _message.Body = value; }
+ }
+
+ public int Id
+ {
+ get { return _message.Id; }
+ }
+
+ public string Destination
+ {
+ get{ return _message.GetDestination();}
+ }
+ }
+}
diff --git a/qpid/dotnet/client-010/client/default.build b/qpid/dotnet/client-010/client/default.build
new file mode 100644
index 0000000000..139796a58d
--- /dev/null
+++ b/qpid/dotnet/client-010/client/default.build
@@ -0,0 +1,46 @@
+<?xml version="1.0"?>
+<!--
+
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+
+-->
+
+<project name="qpid.client" default="build">
+ <!--
+ Properties that come from master build file
+ - build.dir: root directory for build
+ - build.debug: true if building debug release
+ - build.defines: variables to define during build
+ -->
+
+ <target name="build">
+ <csc target="library"
+ define="${build.defines}"
+ debug="${build.debug}"
+ output="${build.dir}/${project::get-name()}.dll">
+
+ <sources>
+ <include name="**/*.cs" />
+ </sources>
+ <references>
+ <include name="${build.dir}/log4net.dll" />
+ </references>
+ </csc>
+ </target>
+</project>
+
diff --git a/qpid/dotnet/client-010/client/transport/Binary.cs b/qpid/dotnet/client-010/client/transport/Binary.cs
new file mode 100644
index 0000000000..f9bd3612dc
--- /dev/null
+++ b/qpid/dotnet/client-010/client/transport/Binary.cs
@@ -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.
+*
+*/
+
+namespace org.apache.qpid.transport
+{
+
+
+ /// <summary>
+ /// Binary
+ /// </summary>
+
+ public sealed class Binary
+ {
+
+ private readonly byte[] bytes;
+ private readonly int offset_Renamed_Field;
+ private readonly int size_Renamed_Field;
+ private int hash = 0;
+
+ public Binary(byte[] bytes, int offset, int size)
+ {
+ if (offset + size > bytes.Length)
+ {
+ throw new System.IndexOutOfRangeException();
+ }
+
+ this.bytes = bytes;
+ offset_Renamed_Field = offset;
+ size_Renamed_Field = size;
+ }
+
+ public Binary(byte[] bytes):this(bytes, 0, bytes.Length)
+ {
+ }
+
+ public byte[] Array()
+ {
+ return bytes;
+ }
+
+ public int Offset()
+ {
+ return offset_Renamed_Field;
+ }
+
+ public int Size()
+ {
+ return size_Renamed_Field;
+ }
+
+ public Binary Slice(int low, int high)
+ {
+ int sz;
+
+ if (high < 0)
+ {
+ sz = size_Renamed_Field + high;
+ }
+ else
+ {
+ sz = high - low;
+ }
+
+ if (sz < 0)
+ {
+ sz = 0;
+ }
+
+ return new Binary(bytes, offset_Renamed_Field + low, sz);
+ }
+
+ public override int GetHashCode()
+ {
+ if (hash == 0)
+ {
+ int hc = 0;
+ for (int i = 0; i < size_Renamed_Field; i++)
+ {
+ hc = 31 * hc + (0xFF & bytes[offset_Renamed_Field + i]);
+ }
+ hash = hc;
+ }
+
+ return hash;
+ }
+
+ public override bool Equals(System.Object o)
+ {
+ if (!(o is Binary))
+ {
+ return false;
+ }
+
+ Binary buf = (Binary) o;
+ if (size_Renamed_Field != buf.size_Renamed_Field)
+ {
+ return false;
+ }
+
+ for (int i = 0; i < size_Renamed_Field; i++)
+ {
+ if (bytes[offset_Renamed_Field + i] != buf.bytes[buf.offset_Renamed_Field + i])
+ {
+ return false;
+ }
+ }
+
+ return true;
+ }
+ }
+}
diff --git a/qpid/dotnet/client-010/client/transport/Binding.cs b/qpid/dotnet/client-010/client/transport/Binding.cs
new file mode 100644
index 0000000000..a0899c1066
--- /dev/null
+++ b/qpid/dotnet/client-010/client/transport/Binding.cs
@@ -0,0 +1,34 @@
+/*
+*
+* 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.
+*
+*/
+using System;
+
+namespace org.apache.qpid.transport
+{
+ /// <summary>
+ /// Binding
+ /// </summary>
+ internal interface Binding<E, T>
+ {
+ E endpoint(Sender<T> sender);
+
+ Receiver<R> receiver<R>(E endpoint) where R : EventArgs;
+ }
+} \ No newline at end of file
diff --git a/qpid/dotnet/client-010/client/transport/Channel.cs b/qpid/dotnet/client-010/client/transport/Channel.cs
new file mode 100644
index 0000000000..48ba707182
--- /dev/null
+++ b/qpid/dotnet/client-010/client/transport/Channel.cs
@@ -0,0 +1,174 @@
+/*
+*
+* 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.
+*
+*/
+using System;
+using org.apache.qpid.transport.network;
+using org.apache.qpid.transport.util;
+
+namespace org.apache.qpid.transport
+{
+ /// <summary>
+ /// Channel
+ /// </summary>
+ public class Channel : Invoker, IProtocolDelegate<Object>
+ {
+ private static readonly Logger log = Logger.Get(typeof (Channel));
+
+ private readonly Connection _connection;
+ private readonly int _channel;
+ private readonly MethodDelegate<Channel> _methoddelegate;
+ private readonly SessionDelegate _sessionDelegate;
+ // session may be null
+ private Session _session;
+
+ public Channel(Connection connection, int channel, SessionDelegate sessionDelegate)
+ {
+ _connection = connection;
+ _channel = channel;
+ _methoddelegate = new ChannelDelegate();
+ _sessionDelegate = sessionDelegate;
+ }
+
+ public Connection Connection
+ {
+ get { return _connection; }
+ }
+
+ // Invoked when a network event is received
+ public void On_ReceivedEvent(object sender, ReceivedPayload<IProtocolEvent> payload)
+ {
+ if (payload.Payload.Channel == _channel)
+ {
+ payload.Payload.ProcessProtocolEvent(null, this);
+ }
+ }
+
+ #region ProtocolDelegate<T>
+
+ public void Init(Object v, ProtocolHeader hdr)
+ {
+ _connection.ConnectionDelegate.Init(this, hdr);
+ }
+
+ public void Control(Object v, Method method)
+ {
+ switch (method.EncodedTrack)
+ {
+ case Frame.L1:
+ method.Dispatch(this, _connection.ConnectionDelegate);
+ break;
+ case Frame.L2:
+ method.Dispatch(this, _methoddelegate);
+ break;
+ case Frame.L3:
+ method.ProcessProtocolEvent(_session, _sessionDelegate);
+ break;
+ default:
+ throw new Exception("unknown track: " + method.EncodedTrack);
+ }
+ }
+
+ public void Command(Object v, Method method)
+ {
+ method.ProcessProtocolEvent(_session, _sessionDelegate);
+ }
+
+ public void Error(Object v, ProtocolError error)
+ {
+ throw new Exception(error.Message);
+ }
+
+ #endregion
+
+ public void Exception(Exception t)
+ {
+ _session.Exception(t);
+ }
+
+ public void ClosedFromConnection()
+ {
+ log.Debug("channel Closed: ", this);
+ if (_session != null)
+ {
+ _session.Closed();
+ }
+ }
+
+ public void Closed()
+ {
+ log.Debug("channel Closed: ", this);
+ if (_session != null)
+ {
+ _session.Closed();
+ }
+ _connection.RemoveChannel(_channel);
+ }
+
+ public int EncodedChannel
+ {
+ get { return _channel; }
+ }
+
+ public Session Session
+ {
+ get { return _session; }
+ set { _session = value; }
+ }
+
+ public void CloseCode(ConnectionClose close)
+ {
+ if (_session != null)
+ {
+ _session.CloseCode(close);
+ }
+ }
+
+ private void Emit(IProtocolEvent pevent)
+ {
+ pevent.Channel = _channel;
+ _connection.Send(pevent);
+ }
+
+ public void Method(Method m)
+ {
+ Emit(m);
+
+ if (!m.Batch)
+ {
+ _connection.Flush();
+ }
+ }
+
+ protected override void Invoke(Method m)
+ {
+ Method(m);
+ }
+
+ public override IFuture Invoke(Method m, IFuture future)
+ {
+ throw new Exception("UnsupportedOperation");
+ }
+
+ public override String ToString()
+ {
+ return String.Format("{0}:{1}", _connection, _channel);
+ }
+ }
+} \ No newline at end of file
diff --git a/qpid/dotnet/client-010/client/transport/ChannelDelegate.cs b/qpid/dotnet/client-010/client/transport/ChannelDelegate.cs
new file mode 100644
index 0000000000..3a43d6d231
--- /dev/null
+++ b/qpid/dotnet/client-010/client/transport/ChannelDelegate.cs
@@ -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.
+*
+*/
+namespace org.apache.qpid.transport
+{
+ /// <summary>
+ /// ChannelDelegate
+ ///
+ /// </summary>
+ internal class ChannelDelegate : MethodDelegate<Channel>
+ {
+ public override void SessionDetached(Channel channel, SessionDetached closed)
+ {
+ channel.Closed();
+ }
+
+ public override void SessionDetach(Channel channel, SessionDetach dtc)
+ {
+ channel.Session.Closed();
+ channel.SessionDetached(dtc.GetName(), SessionDetachCode.NORMAL);
+ channel.Closed();
+ }
+ }
+}
diff --git a/qpid/dotnet/client-010/client/transport/ClientDelegate.cs b/qpid/dotnet/client-010/client/transport/ClientDelegate.cs
new file mode 100644
index 0000000000..957324ad41
--- /dev/null
+++ b/qpid/dotnet/client-010/client/transport/ClientDelegate.cs
@@ -0,0 +1,35 @@
+/*
+*
+* 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.
+*
+*/
+using org.apache.qpid.transport;
+
+namespace org.apache.qpid.transport
+{
+ abstract class ClientDelegate : ConnectionDelegate
+ {
+ public override void Init(Channel ch, ProtocolHeader hdr)
+ {
+ if (hdr.Major != 0 && hdr.Minor != 10)
+ {
+ throw new ProtocolVersionException((sbyte) hdr.Major, (sbyte) hdr.Minor);
+ }
+ }
+ }
+}
diff --git a/qpid/dotnet/client-010/client/transport/Connection.cs b/qpid/dotnet/client-010/client/transport/Connection.cs
new file mode 100644
index 0000000000..b97357a96b
--- /dev/null
+++ b/qpid/dotnet/client-010/client/transport/Connection.cs
@@ -0,0 +1,168 @@
+/*
+*
+* 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.
+*
+*/
+using System;
+using System.Collections.Generic;
+using Logger = org.apache.qpid.transport.util.Logger;
+
+namespace org.apache.qpid.transport
+{
+ /// <summary>
+ /// Connection
+ /// </summary>
+ public class Connection
+ {
+ private static readonly Logger log = Logger.Get(typeof (Connection));
+
+ private readonly ISender<IProtocolEvent> _sender;
+ private readonly ConnectionDelegate _connDdelegate;
+ private int _channelMax = 1;
+ private int _connectionId;
+ private readonly IReceiver<ReceivedPayload<IProtocolEvent>> _receiver;
+
+ private readonly Dictionary<int, Channel> _channels = new Dictionary<int, Channel>();
+
+ public Connection(IReceiver<ReceivedPayload<IProtocolEvent>> receiver, ISender<IProtocolEvent> sender, ConnectionDelegate connDdelegate)
+ {
+ _receiver = receiver;
+ _sender = sender;
+ _connDdelegate = connDdelegate;
+ }
+
+ public int ConnectionId
+ {
+ get { return _connectionId; }
+ set { _connectionId = value; }
+ }
+
+ public ConnectionDelegate ConnectionDelegate
+ {
+ get { return _connDdelegate; }
+ }
+
+ public int ChannelMax
+ {
+ get { return _channelMax; }
+ set { _channelMax = value; }
+ }
+
+ public void Send(IProtocolEvent pevent)
+ {
+ log.Debug("SEND: [{0}] {1}", this, pevent);
+ _sender.Send(pevent);
+ }
+
+ public void Flush()
+ {
+ log.Debug("FLUSH: [{0}]", this);
+ _sender.Flush();
+ }
+
+
+ public Channel GetChannel()
+ {
+ lock (_channels)
+ {
+ for (int i = 0; i < ChannelMax; i++)
+ {
+ if (!_channels.ContainsKey(i))
+ {
+ return GetChannel(i);
+ }
+ }
+ throw new Exception("no more _channels available");
+ }
+ }
+
+ public Channel GetChannel(int number)
+ {
+ lock (_channels)
+ {
+ Channel channel = null;
+ if (_channels.Count > 0)
+ {
+ if( _channels.ContainsKey(number))
+ channel = _channels[number];
+ }
+ if (channel == null)
+ {
+ channel = new Channel(this, number, _connDdelegate.GetSessionDelegate());
+ _receiver.Received += channel.On_ReceivedEvent;
+ _channels.Add(number, channel);
+ }
+ return channel;
+ }
+ }
+
+ public void RemoveChannel(int number)
+ {
+ lock (_channels)
+ {
+ _receiver.Received -= _channels[number].On_ReceivedEvent;
+ _channels.Remove(number);
+ }
+ }
+
+ public void On_ReceivedEvent(object sender, ReceivedPayload<IProtocolEvent> payload)
+ {
+ log.Debug("RECV: [{0}] {1}", this, payload.Payload);
+ if (_channels.ContainsKey(payload.Payload.Channel)) return;
+ Channel channel = GetChannel(payload.Payload.Channel);
+ channel.On_ReceivedEvent(sender, payload);
+ }
+
+ public void On_ReceivedException(Object sender, ExceptionArgs arg)
+ {
+ _connDdelegate.RaiseException(arg.Exception);
+ }
+
+ public void On_ReceivedClosed(Object sender, EventArgs arg)
+ {
+ log.Debug("Connection Closed: {0}", this);
+ lock (_channels)
+ {
+ foreach (Channel ch in _channels.Values)
+ {
+ ch.ClosedFromConnection();
+ }
+ }
+ _channels.Clear();
+ _connDdelegate.Closed();
+ }
+
+
+ public void CloseCode(ConnectionClose close)
+ {
+ lock (_channels)
+ {
+ foreach (Channel ch in _channels.Values)
+ {
+ ch.CloseCode(close);
+ }
+ }
+ }
+
+ public void Close()
+ {
+ _sender.Close();
+ }
+ }
+
+}
diff --git a/qpid/dotnet/client-010/client/transport/ConnectionDelegate.cs b/qpid/dotnet/client-010/client/transport/ConnectionDelegate.cs
new file mode 100644
index 0000000000..5d491bc06f
--- /dev/null
+++ b/qpid/dotnet/client-010/client/transport/ConnectionDelegate.cs
@@ -0,0 +1,108 @@
+/*
+*
+* 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.
+*
+*/
+using System;
+using System.Collections.Generic;
+using System.Threading;
+using Logger = org.apache.qpid.transport.util.Logger;
+
+namespace org.apache.qpid.transport
+{
+ /// <summary>
+ /// ConnectionDelegate
+ ///
+ /// Currently only implemented client specific methods
+ /// </summary>
+ public abstract class ConnectionDelegate : MethodDelegate<Channel>
+ {
+ private static readonly Logger log = Logger.Get(typeof(ConnectionDelegate));
+ private String _virtualHost;
+
+ protected ManualResetEvent _negotiationComplete;
+
+ public abstract SessionDelegate GetSessionDelegate();
+
+ public abstract void RaiseException(Exception t);
+
+ public abstract void Closed();
+
+ public void SetCondition(ManualResetEvent negotiationComplete)
+ {
+ _negotiationComplete = negotiationComplete;
+ }
+
+ public virtual void Init(Channel ch, ProtocolHeader hdr)
+ {
+ ch.Connection.Send(new ProtocolHeader((byte)1, hdr.Major, hdr.Minor));
+ List<Object> plain = new List<Object>();
+ plain.Add("PLAIN");
+ List<Object> utf8 = new List<Object>();
+ utf8.Add("utf8");
+ ch.ConnectionStart(null, plain, utf8);
+ }
+
+ public String VirtualHost
+ {
+ get { return _virtualHost; }
+ set { _virtualHost = value; }
+ }
+
+ // ----------------------------------------------
+ // Client side
+ //-----------------------------------------------
+ public override void ConnectionStart(Channel context, ConnectionStart mstruct)
+ {
+ Dictionary<String, Object> props = new Dictionary<String, Object>();
+ context.ConnectionStartOk(props, null, null, "utf8");
+ }
+
+ public override void ConnectionSecure(Channel context, ConnectionSecure mstruct)
+ { // todo SASL
+ context.ConnectionSecureOk(new byte[0]);
+ }
+
+ public override void ConnectionTune(Channel context, ConnectionTune mstruct)
+ {
+ context.Connection.ChannelMax = mstruct.GetChannelMax();
+ context.ConnectionTuneOk(mstruct.GetChannelMax(), mstruct.GetMaxFrameSize(), mstruct.GetHeartbeatMax());
+ context.ConnectionOpen(_virtualHost, null, Option.INSIST);
+ }
+
+ public override void ConnectionOpenOk(Channel context, ConnectionOpenOk mstruct)
+ {
+ List<Object> knownHosts = mstruct.GetKnownHosts();
+ if (_negotiationComplete != null)
+ {
+ _negotiationComplete.Set();
+ }
+ }
+
+ public override void ConnectionRedirect(Channel context, ConnectionRedirect mstruct)
+ {
+ // not going to bother at the moment
+ }
+
+ public override void ConnectionClose(Channel ch, ConnectionClose close)
+ {
+ ch.Connection.CloseCode(close);
+ ch.ConnectionCloseOk();
+ }
+ }
+} \ No newline at end of file
diff --git a/qpid/dotnet/client-010/client/transport/Field.cs b/qpid/dotnet/client-010/client/transport/Field.cs
new file mode 100644
index 0000000000..9af8c4a476
--- /dev/null
+++ b/qpid/dotnet/client-010/client/transport/Field.cs
@@ -0,0 +1,74 @@
+/*
+*
+* 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.
+*
+*/
+using System;
+using org.apache.qpid.transport.codec;
+
+namespace org.apache.qpid.transport
+{
+ /// <summary>
+ /// Field
+ /// </summary>
+ public abstract class Field<C, T>
+ {
+ private C container;
+ private T type;
+ private String name;
+ private int index;
+
+ protected Field(C container, T type, String name, int index)
+ {
+ this.container = container;
+ this.type = type;
+ this.name = name;
+ this.index = index;
+ }
+
+ public C Container
+ {
+ get { return container; }
+ }
+
+ public T Type
+ {
+ get { return type; }
+ }
+
+ public String Name
+ {
+ get { return name; }
+ }
+
+ public int Index
+ {
+ get { return index; }
+ }
+
+ public abstract bool Has(Object mystruct);
+
+ public abstract void Has(Object mystruct, bool value);
+
+ public abstract T Get(Object mystruct);
+
+ public abstract void Read(IDecoder dec, Object mystruct);
+
+ public abstract void Write(IEncoder enc, Object mystruct);
+ }
+}
diff --git a/qpid/dotnet/client-010/client/transport/Future.cs b/qpid/dotnet/client-010/client/transport/Future.cs
new file mode 100644
index 0000000000..c0eadfb7ae
--- /dev/null
+++ b/qpid/dotnet/client-010/client/transport/Future.cs
@@ -0,0 +1,38 @@
+/*
+*
+* 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.
+*
+*/
+
+namespace org.apache.qpid.transport
+{
+ /// <summary>
+ /// Future
+ /// </summary>
+ public interface Future
+ {
+ Struct Result
+ {
+ get; set;
+ }
+
+ Session Session
+ { set;
+ }
+ }
+} \ No newline at end of file
diff --git a/qpid/dotnet/client-010/client/transport/Header.cs b/qpid/dotnet/client-010/client/transport/Header.cs
new file mode 100644
index 0000000000..742531cfd8
--- /dev/null
+++ b/qpid/dotnet/client-010/client/transport/Header.cs
@@ -0,0 +1,83 @@
+/*
+*
+* 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.
+*
+*/
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace org.apache.qpid.transport
+{
+ /// <summary>
+ /// Header
+ /// </summary>
+ public class Header
+ {
+ private readonly Struct[] _mystructs;
+
+ public Header(List<Struct> structs)
+ : this(structs.ToArray())
+ {
+ }
+
+ public Header(params Struct[] structs)
+ {
+ _mystructs = structs;
+ }
+
+ public Struct[] Structs
+ {
+ get { return _mystructs; }
+ }
+
+
+ public Struct Get(Struct klass)
+ {
+ foreach (Struct st in _mystructs)
+ {
+ if (Equals(st.GetType(), klass.GetType()))
+ {
+ return st;
+ }
+ }
+ return null;
+ }
+
+ public override String ToString()
+ {
+ StringBuilder str = new StringBuilder();
+ str.Append(" Header(");
+ bool first = true;
+ foreach (Struct s in _mystructs)
+ {
+ if (first)
+ {
+ first = false;
+ }
+ else
+ {
+ str.Append(", ");
+ }
+ str.Append(s);
+ }
+ str.Append(")");
+ return str.ToString();
+ }
+ }
+}
diff --git a/qpid/dotnet/client-010/client/transport/IBinding.cs b/qpid/dotnet/client-010/client/transport/IBinding.cs
new file mode 100644
index 0000000000..607212f1fe
--- /dev/null
+++ b/qpid/dotnet/client-010/client/transport/IBinding.cs
@@ -0,0 +1,34 @@
+/*
+*
+* 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.
+*
+*/
+using System;
+
+namespace org.apache.qpid.transport
+{
+ /// <summary>
+ /// Binding
+ /// </summary>
+ internal interface IBinding<E, T>
+ {
+ E Endpoint(ISender<T> sender);
+
+ IReceiver<R> Receiver<R>(E endpoint) where R : EventArgs;
+ }
+}
diff --git a/qpid/dotnet/client-010/client/transport/IFuture.cs b/qpid/dotnet/client-010/client/transport/IFuture.cs
new file mode 100644
index 0000000000..054b828d13
--- /dev/null
+++ b/qpid/dotnet/client-010/client/transport/IFuture.cs
@@ -0,0 +1,38 @@
+/*
+*
+* 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.
+*
+*/
+
+namespace org.apache.qpid.transport
+{
+ /// <summary>
+ /// Future
+ /// </summary>
+ public interface IFuture
+ {
+ Struct Result
+ {
+ get; set;
+ }
+
+ Session Session
+ { set;
+ }
+ }
+}
diff --git a/qpid/dotnet/client-010/client/transport/IProtocolDelegate.cs b/qpid/dotnet/client-010/client/transport/IProtocolDelegate.cs
new file mode 100644
index 0000000000..a9875fd290
--- /dev/null
+++ b/qpid/dotnet/client-010/client/transport/IProtocolDelegate.cs
@@ -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.
+*
+*/
+
+namespace org.apache.qpid.transport
+{
+ /// <summary>
+ /// ProtocolDelegate
+ /// </summary>
+ public interface IProtocolDelegate<T>
+ {
+ void Init(T context, ProtocolHeader header);
+
+ void Control(T context, Method control);
+
+ void Command(T context, Method command);
+
+ void Error(T context, ProtocolError error);
+ }
+}
diff --git a/qpid/dotnet/client-010/client/transport/IProtocolEvent.cs b/qpid/dotnet/client-010/client/transport/IProtocolEvent.cs
new file mode 100644
index 0000000000..8f915b204a
--- /dev/null
+++ b/qpid/dotnet/client-010/client/transport/IProtocolEvent.cs
@@ -0,0 +1,42 @@
+/*
+*
+* 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.
+*
+*/
+namespace org.apache.qpid.transport
+{
+ /// <summary>
+ /// IProtocolEvent
+ /// </summary>
+ public interface IProtocolEvent
+ {
+ int Channel
+ {
+ get;
+ set;
+ }
+
+ byte EncodedTrack
+ {
+ set;
+ get;
+ }
+
+ void ProcessProtocolEvent<C>(C context, IProtocolDelegate<C> protocoldelegate);
+ }
+}
diff --git a/qpid/dotnet/client-010/client/transport/IReceiver.cs b/qpid/dotnet/client-010/client/transport/IReceiver.cs
new file mode 100644
index 0000000000..4c4c9572b9
--- /dev/null
+++ b/qpid/dotnet/client-010/client/transport/IReceiver.cs
@@ -0,0 +1,38 @@
+/*
+*
+* 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.
+*
+*/
+
+using System;
+
+namespace org.apache.qpid.transport
+{
+ /// <summary>
+ /// a receiver will raise an event when:
+ /// - data is received
+ /// - an exception is thrown
+ /// - it is Closed
+ /// </summary>
+ public interface IReceiver <T> where T : EventArgs
+ {
+ event EventHandler<T> Received;
+ event EventHandler<ExceptionArgs> Exception;
+ event EventHandler Closed;
+ }
+}
diff --git a/qpid/dotnet/client-010/client/transport/ISender.cs b/qpid/dotnet/client-010/client/transport/ISender.cs
new file mode 100644
index 0000000000..d7d1781aec
--- /dev/null
+++ b/qpid/dotnet/client-010/client/transport/ISender.cs
@@ -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.
+*
+*/
+namespace org.apache.qpid.transport
+{
+ /// <summary>
+ /// Sender
+ /// </summary>
+ public interface ISender<T>
+ {
+ void Send(T msg);
+ void Flush();
+ void Close();
+ }
+}
diff --git a/qpid/dotnet/client-010/client/transport/ISession.cs b/qpid/dotnet/client-010/client/transport/ISession.cs
new file mode 100644
index 0000000000..e843095df6
--- /dev/null
+++ b/qpid/dotnet/client-010/client/transport/ISession.cs
@@ -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.
+ *
+ */
+
+using System;
+using System.Collections.Generic;
+
+namespace org.apache.qpid.transport
+{
+ public interface ISession : IInvoker
+ {
+ bool IsClosed { get; set; }
+ string Name { get; }
+ int CommandsIn { get; set; }
+ byte[] GetName();
+ void SetAutoSync(bool value);
+ Dictionary<int, Method> GetOutstandingCommands();
+ int GetCommandsOut();
+ int NextCommandId();
+ void Identify(Method cmd);
+ void Processed(Method command);
+ void Processed(int command);
+ void Processed(int lower, int upper);
+ void Processed(Range range);
+ void FlushProcessed(params Option[] options);
+ void KnownComplete(RangeSet kc);
+ void SyncPoint();
+ void Attach(Channel channel);
+ Method GetCommand(int id);
+ bool Complete(int lower, int upper);
+ void Sync();
+ void Sync(long timeout);
+ void Result(int command, Struct result);
+ void AddException(ExecutionException exc);
+ void CloseCode(ConnectionClose close);
+ List<ExecutionException> GetExceptions();
+
+ void MessageTransfer(String destination,
+ MessageAcceptMode acceptMode,
+ MessageAcquireMode acquireMode,
+ Header header,
+ byte[] body,
+ params Option[] options);
+
+ void MessageTransfer(String destination,
+ MessageAcceptMode acceptMode,
+ MessageAcquireMode acquireMode,
+ Header header,
+ String body,
+ params Option[] options);
+
+ void Close();
+ void Exception(Exception t);
+ void Closed();
+ }
+}
diff --git a/qpid/dotnet/client-010/client/transport/Method.cs b/qpid/dotnet/client-010/client/transport/Method.cs
new file mode 100644
index 0000000000..8540698822
--- /dev/null
+++ b/qpid/dotnet/client-010/client/transport/Method.cs
@@ -0,0 +1,150 @@
+/*
+*
+* 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.
+*
+*/
+using System;
+using System.IO;
+using System.Text;
+using Frame = org.apache.qpid.transport.network.Frame;
+
+namespace org.apache.qpid.transport
+{
+ /// <summary>
+ /// Method
+ /// </summary>
+ public abstract class Method : Struct, IProtocolEvent
+ {
+ public new static Method Create(int type)
+ {
+ return (Method) StructFactory.createInstruction(type);
+ }
+
+ // XXX: command subclass?
+ private int id;
+ private int channel;
+ private bool idSet;
+ private bool sync;
+ private bool batch;
+
+ public int Id
+ {
+ get { return id; }
+ set
+ {
+ id = value;
+ idSet = true;
+ }
+ }
+
+
+ public bool Sync
+ {
+ get { return sync; }
+ set { sync = value; }
+ }
+
+ public bool Batch
+ {
+ get { return batch; }
+ set { batch = value; }
+ }
+
+ public abstract bool HasPayload();
+
+ public virtual Header Header
+ {
+ get { return null; }
+ set { throw new Exception(); }
+ }
+
+ public virtual MemoryStream Body
+ {
+ get { return null; }
+ set { throw new Exception(); }
+ }
+
+
+ public abstract void Dispatch<C>(C context, MethodDelegate<C> mdelegate );
+
+ #region IProtocolEvent
+
+ public int Channel
+ {
+ get { return channel; }
+ set { channel = value; }
+ }
+
+ public abstract byte EncodedTrack { get; set; }
+
+ public void ProcessProtocolEvent<C>(C context, IProtocolDelegate<C> protocoldelegate)
+ {
+ if (EncodedTrack == Frame.L4)
+ {
+ protocoldelegate.Command(context, this);
+ }
+ else
+ {
+ protocoldelegate.Control(context, this);
+ }
+ }
+
+ #endregion
+
+ public override String ToString()
+ {
+ StringBuilder str = new StringBuilder();
+
+ str.Append("ch=");
+ str.Append(channel);
+
+ if (EncodedTrack == Frame.L4 && idSet)
+ {
+ str.Append(" id=");
+ str.Append(id);
+ }
+
+ if (sync || batch)
+ {
+ str.Append(" ");
+ str.Append("[");
+ if (Sync)
+ {
+ str.Append("S");
+ }
+ if (Batch)
+ {
+ str.Append("B");
+ }
+ str.Append("]");
+ }
+ str.Append(" ");
+ str.Append(base.ToString());
+ if (Header != null)
+ {
+ str.Append(Header.ToString());
+ }
+ if (Body != null)
+ {
+ str.Append("\n body=");
+ str.Append(Body.ToString());
+ }
+ return str.ToString();
+ }
+ }
+}
diff --git a/qpid/dotnet/client-010/client/transport/ProtocolDelegate.cs b/qpid/dotnet/client-010/client/transport/ProtocolDelegate.cs
new file mode 100644
index 0000000000..32dbd116ff
--- /dev/null
+++ b/qpid/dotnet/client-010/client/transport/ProtocolDelegate.cs
@@ -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.
+*
+*/
+
+namespace org.apache.qpid.transport
+{
+ /// <summary>
+ /// ProtocolDelegate
+ /// </summary>
+ public interface ProtocolDelegate<T>
+ {
+ void Init(T context, ProtocolHeader header);
+
+ void Control(T context, Method control);
+
+ void Command(T context, Method command);
+
+ void Error(T context, ProtocolError error);
+ }
+} \ No newline at end of file
diff --git a/qpid/dotnet/client-010/client/transport/ProtocolError.cs b/qpid/dotnet/client-010/client/transport/ProtocolError.cs
new file mode 100644
index 0000000000..2a5bf39565
--- /dev/null
+++ b/qpid/dotnet/client-010/client/transport/ProtocolError.cs
@@ -0,0 +1,85 @@
+/*
+*
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing,
+* software distributed under the License is distributed on an
+* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+* KIND, either express or implied. See the License for the
+* specific language governing permissions and limitations
+* under the License.
+*
+*/
+using System;
+using org.apache.qpid.transport.network;
+
+namespace org.apache.qpid.transport
+{
+ /// <summary>
+ /// ProtocolError
+ /// </summary>
+ public sealed class ProtocolError : INetworkEvent, IProtocolEvent
+ {
+ private int channel;
+ private byte track;
+ private String format;
+ private Object[] args;
+
+ public ProtocolError(byte track, String format, params Object[] args)
+ {
+ this.track = track;
+ this.format = format;
+ this.args = args;
+ }
+
+ #region INetworkEvent Methods
+
+ public void ProcessNetworkEvent(INetworkDelegate ndelegate)
+ {
+ ndelegate.Error(this);
+ }
+
+ #endregion
+
+ #region IProtocolEvent Methods
+
+ public int Channel
+ {
+ get { return channel; }
+ set { channel = value; }
+ }
+
+ public byte EncodedTrack
+ {
+ get { return track; }
+ set { throw new NotImplementedException(); }
+ }
+
+ public void ProcessProtocolEvent<C>(C context, IProtocolDelegate<C> protocoldelegate)
+ {
+ protocoldelegate.Error(context, this);
+ }
+
+ #endregion
+
+ public String Message
+ {
+ get { return String.Format(format, args); }
+ }
+
+
+ public override String ToString()
+ {
+ return String.Format("protocol error: {0}", Message);
+ }
+
+ }
+}
diff --git a/qpid/dotnet/client-010/client/transport/ProtocolEvent.cs b/qpid/dotnet/client-010/client/transport/ProtocolEvent.cs
new file mode 100644
index 0000000000..990d5ecc3a
--- /dev/null
+++ b/qpid/dotnet/client-010/client/transport/ProtocolEvent.cs
@@ -0,0 +1,42 @@
+/*
+*
+* 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.
+*
+*/
+namespace org.apache.qpid.transport
+{
+ /// <summary>
+ /// ProtocolEvent
+ /// </summary>
+ public interface ProtocolEvent
+ {
+ int Channel
+ {
+ get;
+ set;
+ }
+
+ byte EncodedTrack
+ {
+ set;
+ get;
+ }
+
+ void ProcessProtocolEvent<C>(C context, ProtocolDelegate<C> protocoldelegate);
+ }
+} \ No newline at end of file
diff --git a/qpid/dotnet/client-010/client/transport/ProtocolHeader.cs b/qpid/dotnet/client-010/client/transport/ProtocolHeader.cs
new file mode 100644
index 0000000000..4adfee25df
--- /dev/null
+++ b/qpid/dotnet/client-010/client/transport/ProtocolHeader.cs
@@ -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.
+*
+*/
+using System;
+using System.IO;
+using System.Text;
+using org.apache.qpid.transport.network;
+using Frame = org.apache.qpid.transport.network.Frame;
+
+namespace org.apache.qpid.transport
+{
+ /// <summary> ProtocolHeader
+ ///
+ /// </summary>
+ public sealed class ProtocolHeader : INetworkEvent, IProtocolEvent
+ {
+ private readonly char[] AMQP = new char[] {'A', 'M', 'Q', 'P'};
+ private const byte CLASS = 1;
+
+ private readonly byte instance;
+ private readonly byte major;
+ private readonly byte minor;
+ private int channel;
+
+ public ProtocolHeader(byte instance, byte major, byte minor)
+ {
+ this.instance = instance;
+ this.major = major;
+ this.minor = minor;
+ }
+
+ public ProtocolHeader(int instance, int major, int minor) : this((byte)instance, (byte)major, (byte)minor)
+ {
+ }
+
+ #region INetworkEvent Methods
+
+ public void ProcessNetworkEvent(INetworkDelegate ndelegate)
+ {
+ ndelegate.Init(this);
+ }
+
+ #endregion
+
+ #region IProtocolEvent Methods
+
+ public int Channel
+ {
+ get
+ {
+ return channel;
+ }
+ set
+ {
+ channel = value;
+ }
+ }
+
+ public byte EncodedTrack
+ {
+ get
+ {
+ return Frame.L1;
+ }
+ set { throw new NotImplementedException(); }
+ }
+
+ public void ProcessProtocolEvent<C>(C context, IProtocolDelegate<C> protocoldelegate)
+ {
+ protocoldelegate.Init(context, this);
+ }
+
+ #endregion
+
+ public byte Instance
+ {
+ get { return instance; }
+ }
+
+ public byte Major
+ {
+ get { return major; }
+ }
+
+ public byte Minor
+ {
+ get { return minor; }
+ }
+
+ public MemoryStream ToMemoryStream()
+ {
+ MemoryStream buf = new MemoryStream(8);
+ BinaryWriter writer = new BinaryWriter(buf);
+ writer.Write(AMQP);
+ writer.Write(CLASS);
+ writer.Write(instance);
+ writer.Write((sbyte) major);
+ writer.Write((sbyte) minor);
+ return buf;
+ }
+
+ public override String ToString()
+ {
+ return String.Format("AMQP.{0:d} {1:d}-{2:d}", instance, major, minor);
+ }
+ }
+}
diff --git a/qpid/dotnet/client-010/client/transport/Range.cs b/qpid/dotnet/client-010/client/transport/Range.cs
new file mode 100644
index 0000000000..904b1c1229
--- /dev/null
+++ b/qpid/dotnet/client-010/client/transport/Range.cs
@@ -0,0 +1,117 @@
+/*
+*
+* 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.
+*
+*/
+using System;
+using System.Collections.Generic;
+using org.apache.qpid.transport.util;
+
+namespace org.apache.qpid.transport
+{
+
+ /// <summary>
+ /// Range
+ /// </summary>
+
+
+ public sealed class Range
+ {
+ private int _lower;
+ private int _upper;
+
+ public Range(int lower, int upper)
+ {
+ _lower = lower;
+ _upper = upper;
+ }
+
+ public int Lower
+ {
+ get { return _lower; }
+ set { _lower = value; }
+ }
+ public int Upper
+ {
+ get { return _upper; }
+ set { _upper = value; }
+ }
+
+ public bool Includes(int value)
+ {
+ return Serial.Le(_lower, value) && Serial.Le(value, _upper);
+ }
+
+ public bool Includes(Range range)
+ {
+ return Includes(range._lower) && Includes(range._upper);
+ }
+
+ public bool Intersects(Range range)
+ {
+ return (Includes(range._lower) || Includes(range._upper) ||
+ range.Includes(_lower) || range.Includes(_upper));
+ }
+
+ public bool Touches(Range range)
+ {
+ return (Intersects(range) ||
+ Includes(range._upper + 1) || Includes(range._lower - 1) ||
+ range.Includes(_upper + 1) || range.Includes(_lower - 1));
+ }
+
+ public Range Span(Range range)
+ {
+ return new Range(Serial.Min(_lower, range._lower), Serial.Max(_upper, range._upper));
+ }
+
+ public List<Range> Subtract(Range range)
+ {
+ List<Range> result = new List<Range>();
+
+ if (Includes(range._lower) && Serial.Le(_lower, range._lower - 1))
+ {
+ result.Add(new Range(_lower, range._lower - 1));
+ }
+
+ if (Includes(range._upper) && Serial.Le(range._upper + 1, _upper))
+ {
+ result.Add(new Range(range._upper + 1, _upper));
+ }
+
+ if (result.Count == 0 && !range.Includes(this))
+ {
+ result.Add(this);
+ }
+
+ return result;
+ }
+
+ public Range Intersect(Range range)
+ {
+ int l = Serial.Max(_lower, range._lower);
+ int r = Serial.Min(_upper, range._upper);
+ return Serial.Gt(l, r) ? null : new Range(l, r);
+ }
+
+ public override String ToString()
+ {
+ return "[" + _lower + ", " + _upper + "]";
+ }
+ }
+}
diff --git a/qpid/dotnet/client-010/client/transport/RangeSet.cs b/qpid/dotnet/client-010/client/transport/RangeSet.cs
new file mode 100644
index 0000000000..0a856ee979
--- /dev/null
+++ b/qpid/dotnet/client-010/client/transport/RangeSet.cs
@@ -0,0 +1,150 @@
+/*
+*
+* 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.
+*
+*/
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Text;
+using org.apache.qpid.transport.util;
+
+namespace org.apache.qpid.transport
+{
+ /// <summary>
+ /// RangeSet
+ /// </summary>
+ public sealed class RangeSet : IEnumerable<Range>
+ {
+ private readonly List<Range> _ranges = new List<Range>();
+
+ IEnumerator IEnumerable.GetEnumerator()
+ {
+ return GetEnumerator();
+ }
+
+ public IEnumerator<Range> GetEnumerator()
+ {
+ return _ranges.GetEnumerator();
+ }
+
+
+ public int Size()
+ {
+ return _ranges.Count;
+ }
+
+
+ public Range GetFirst()
+ {
+ return _ranges[0];
+ }
+
+ public bool Includes(Range range)
+ {
+ foreach (Range r in this)
+ {
+ if (r.Includes(range))
+ {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ public bool Includes(int n)
+ {
+ foreach (Range r in this)
+ {
+ if (r.Includes(n))
+ {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ public void Add(Range range)
+ {
+ for (int i = 0; i < _ranges.Count; i++)
+ {
+ Range r = _ranges[i];
+ if (range.Touches(r))
+ {
+ _ranges.Remove(r);
+ range = range.Span(r);
+ }
+ else if (Serial.Lt(range.Upper, r.Lower))
+ {
+ _ranges.Insert(i - 1 , range);
+ return;
+ }
+ }
+ _ranges.Add(range);
+ }
+
+ public void Add(int lower, int upper)
+ {
+ Add(new Range(lower, upper));
+ }
+
+ public void Add(int value)
+ {
+ Add(value, value);
+ }
+
+ public void Clear()
+ {
+ _ranges.Clear();
+ }
+
+ public RangeSet Copy()
+ {
+ RangeSet copy = new RangeSet();
+ foreach (Range r in _ranges)
+ {
+ copy._ranges.Add(r);
+ }
+ return copy;
+ }
+
+ public override String ToString()
+ {
+ StringBuilder str = new StringBuilder();
+ str.Append("{");
+ bool first = true;
+ foreach (Range range in _ranges)
+ {
+ if (first)
+ {
+ first = false;
+ }
+ else
+ {
+ str.Append(", ");
+ }
+ str.Append(range);
+ }
+ str.Append("}");
+ return str.ToString();
+ }
+ }
+}
diff --git a/qpid/dotnet/client-010/client/transport/ReceivedPayload.cs b/qpid/dotnet/client-010/client/transport/ReceivedPayload.cs
new file mode 100644
index 0000000000..e072ba7493
--- /dev/null
+++ b/qpid/dotnet/client-010/client/transport/ReceivedPayload.cs
@@ -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.
+*
+*/
+using System;
+
+namespace org.apache.qpid.transport
+{
+ public class ReceivedPayload<T> : EventArgs
+ {
+ public ReceivedPayload()
+ {
+ }
+
+ public ReceivedPayload(T payload)
+ {
+ m_payload = payload;
+ }
+ private T m_payload;
+
+ public T Payload
+ {
+ get { return m_payload; }
+ set { m_payload = value; }
+ }
+ }
+}
diff --git a/qpid/dotnet/client-010/client/transport/Receiver.cs b/qpid/dotnet/client-010/client/transport/Receiver.cs
new file mode 100644
index 0000000000..f8d91c3f10
--- /dev/null
+++ b/qpid/dotnet/client-010/client/transport/Receiver.cs
@@ -0,0 +1,38 @@
+/*
+*
+* 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.
+*
+*/
+
+using System;
+
+namespace org.apache.qpid.transport
+{
+ /// <summary>
+ /// a receiver will raise an event when:
+ /// - data is received
+ /// - an exception is thrown
+ /// - it is closed
+ /// </summary>
+ public interface Receiver <T> where T : EventArgs
+ {
+ event EventHandler<T> Received;
+ event EventHandler<ExceptionArgs> Exception;
+ event EventHandler Closed;
+ }
+} \ No newline at end of file
diff --git a/qpid/dotnet/client-010/client/transport/Sender.cs b/qpid/dotnet/client-010/client/transport/Sender.cs
new file mode 100644
index 0000000000..f8b5bdef06
--- /dev/null
+++ b/qpid/dotnet/client-010/client/transport/Sender.cs
@@ -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.
+*
+*/
+namespace org.apache.qpid.transport
+{
+ /// <summary>
+ /// Sender
+ /// </summary>
+ public interface Sender<T>
+ {
+ void send(T msg);
+ void flush();
+ void close();
+ }
+} \ No newline at end of file
diff --git a/qpid/dotnet/client-010/client/transport/Session.cs b/qpid/dotnet/client-010/client/transport/Session.cs
new file mode 100644
index 0000000000..7b4aff9811
--- /dev/null
+++ b/qpid/dotnet/client-010/client/transport/Session.cs
@@ -0,0 +1,522 @@
+/*
+*
+* 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.
+*
+*/
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Text;
+using System.Threading;
+using org.apache.qpid.transport.util;
+using Frame = org.apache.qpid.transport.network.Frame;
+using Logger = org.apache.qpid.transport.util.Logger;
+
+
+namespace org.apache.qpid.transport
+{
+ /// <summary>
+ /// Session
+ ///
+ /// </summary>
+ public class Session : Invoker, ISession
+ {
+ private static readonly Logger log = Logger.Get(typeof (Session));
+ private static readonly bool ENABLE_REPLAY;
+
+ static Session()
+ {
+ const string enableReplay = "enable_command_replay";
+ try
+ {
+ String var = Environment.GetEnvironmentVariable(enableReplay);
+ if (var != null)
+ {
+ ENABLE_REPLAY = bool.Parse(var);
+ }
+ }
+ catch (Exception)
+ {
+ ENABLE_REPLAY = false;
+ }
+ }
+
+ private readonly byte[] _name;
+ private const long _timeout = 600000;
+ private bool _autoSync = false;
+
+ // channel may be null
+ private Channel _channel;
+
+ // incoming command count
+ private int _commandsIn = 0;
+ // completed incoming commands
+ private readonly Object _processedLock = new Object();
+ private RangeSet _processed = new RangeSet();
+ private int _maxProcessed = - 1;
+ private int _syncPoint = -1;
+
+ // outgoing command count
+ private int _commandsOut = 0;
+ private readonly Dictionary<int, Method> _commands = new Dictionary<int, Method>();
+ private int _maxComplete = - 1;
+ private bool _needSync = false;
+ private bool _closed;
+ private readonly Dictionary<int, IFuture> _results = new Dictionary<int, IFuture>();
+ private readonly List<ExecutionException> _exceptions = new List<ExecutionException>();
+
+
+ public bool IsClosed
+ {
+ get
+ {
+ lock (this)
+ {
+ return _closed;
+ }
+ }
+ set
+ {
+ lock (this)
+ {
+ _closed = value;
+ }
+ }
+ }
+
+ public string Name
+ {
+ get
+ {
+ ASCIIEncoding enc = new ASCIIEncoding();
+ return enc.GetString(_name);
+ }
+ }
+
+ public Session(byte[] name)
+ {
+ _name = name;
+ }
+
+ public byte[] GetName()
+ {
+ return _name;
+ }
+
+ public void SetAutoSync(bool value)
+ {
+ lock (_commands)
+ {
+ _autoSync = value;
+ }
+ }
+
+ public Dictionary<int, Method> GetOutstandingCommands()
+ {
+ return _commands;
+ }
+
+ public int GetCommandsOut()
+ {
+ return _commandsOut;
+ }
+
+ public int CommandsIn
+ {
+ get { return _commandsIn; }
+ set { _commandsIn = value; }
+ }
+
+ public int NextCommandId()
+ {
+ return _commandsIn++;
+ }
+
+ public void Identify(Method cmd)
+ {
+ int id = NextCommandId();
+ cmd.Id = id;
+
+ if (log.IsDebugEnabled())
+ {
+ log.Debug("ID: [{0}] %{1}", _channel, id);
+ }
+
+ //if ((id % 65536) == 0)
+ if ((id & 0xff) == 0)
+ {
+ FlushProcessed(Option.TIMELY_REPLY);
+ }
+ }
+
+ public void Processed(Method command)
+ {
+ Processed(command.Id);
+ }
+
+ public void Processed(int command)
+ {
+ Processed(new Range(command, command));
+ }
+
+ public void Processed(int lower, int upper)
+ {
+ Processed(new Range(lower, upper));
+ }
+
+ public void Processed(Range range)
+ {
+ log.Debug("{0} processed({1})", this, range);
+
+ bool flush;
+ lock (_processedLock)
+ {
+ _processed.Add(range);
+ Range first = _processed.GetFirst();
+ int lower = first.Lower;
+ int upper = first.Upper;
+ int old = _maxProcessed;
+ if (Serial.Le(lower, _maxProcessed + 1))
+ {
+ _maxProcessed = Serial.Max(_maxProcessed, upper);
+ }
+ flush = Serial.Lt(old, _syncPoint) && Serial.Ge(_maxProcessed, _syncPoint);
+ _syncPoint = _maxProcessed;
+ }
+ if (flush)
+ {
+ FlushProcessed();
+ }
+ }
+
+ public void FlushProcessed(params Option[] options)
+ {
+ RangeSet copy;
+ lock (_processedLock)
+ {
+ copy = _processed.Copy();
+ }
+ SessionCompleted(copy, options);
+ }
+
+ public void KnownComplete(RangeSet kc)
+ {
+ lock (_processedLock)
+ {
+ RangeSet newProcessed = new RangeSet();
+ foreach (Range pr in _processed)
+ {
+ foreach (Range kr in kc)
+ {
+ foreach (Range r in pr.Subtract(kr))
+ {
+ newProcessed.Add(r);
+ }
+ }
+ }
+ _processed = newProcessed;
+ }
+ }
+
+ public void SyncPoint()
+ {
+ int id = CommandsIn - 1;
+ log.Debug("{0} synced to {1}", this, id);
+ bool flush;
+ lock (_processedLock)
+ {
+ _syncPoint = id;
+ flush = Serial.Ge(_maxProcessed, _syncPoint);
+ }
+ if (flush)
+ {
+ FlushProcessed();
+ }
+ }
+
+ public void Attach(Channel channel)
+ {
+ _channel = channel;
+ _channel.Session = this;
+ }
+
+ public Method GetCommand(int id)
+ {
+ lock (_commands)
+ {
+ return _commands[id];
+ }
+ }
+
+ public bool Complete(int lower, int upper)
+ {
+ //avoid autoboxing
+ if (log.IsDebugEnabled())
+ {
+ log.Debug("{0} complete({1}, {2})", this, lower, upper);
+ }
+ lock (_commands)
+ {
+ int old = _maxComplete;
+ for (int id = Serial.Max(_maxComplete, lower); Serial.Le(id, upper); id++)
+ {
+ _commands.Remove(id);
+ }
+ if (Serial.Le(lower, _maxComplete + 1))
+ {
+ _maxComplete = Serial.Max(_maxComplete, upper);
+ }
+ log.Debug("{0} commands remaining: {1}", this, _commands);
+ Monitor.PulseAll(_commands);
+ return Serial.Gt(_maxComplete, old);
+ }
+ }
+
+ protected override void Invoke(Method m)
+ {
+ if (IsClosed)
+ {
+ List<ExecutionException> exc = GetExceptions();
+ if (exc.Count > 0)
+ {
+ throw new SessionException(exc);
+ }
+ else if (_close != null)
+ {
+ throw new ConnectionException(_close);
+ }
+ else
+ {
+ throw new SessionClosedException();
+ }
+ }
+
+ if (m.EncodedTrack == Frame.L4)
+ {
+ lock (_commands)
+ {
+ int next = _commandsOut++;
+ m.Id = next;
+ if (next == 0)
+ {
+ SessionCommandPoint(0, 0);
+ }
+ if (ENABLE_REPLAY)
+ {
+ _commands.Add(next, m);
+ }
+ if (_autoSync)
+ {
+ m.Sync = true;
+ }
+ _needSync = ! m.Sync;
+ _channel.Method(m);
+ if (_autoSync)
+ {
+ Sync();
+ }
+
+ // flush every 64K commands to avoid ambiguity on
+ // wraparound
+ if ((next%65536) == 0)
+ {
+ SessionFlush(Option.COMPLETED);
+ }
+ }
+ }
+ else
+ {
+ _channel.Method(m);
+ }
+ }
+
+ public void Sync()
+ {
+ Sync(_timeout);
+ }
+
+ public void Sync(long timeout)
+ {
+ log.Debug("{0} sync()", this);
+ lock (_commands)
+ {
+ int point = _commandsOut - 1;
+
+ if (_needSync && Serial.Lt(_maxComplete, point))
+ {
+ ExecutionSync(Option.SYNC);
+ }
+
+ DateTime start = DateTime.Now;
+ long elapsed = 0;
+
+ while (!IsClosed && elapsed < timeout && Serial.Lt(_maxComplete, point))
+ {
+ log.Debug("{0} waiting for[{1}]: {2}, {3}", this, point,
+ _maxComplete, _commands);
+ Monitor.Wait(_commands, (int) (timeout - elapsed));
+ elapsed = DateTime.Now.Subtract(start).Milliseconds;
+ }
+
+ if (Serial.Lt(_maxComplete, point))
+ {
+ if (IsClosed)
+ {
+ throw new SessionException(GetExceptions());
+ }
+ else
+ {
+ throw new Exception
+ (String.Format
+ ("timed out waiting for sync: complete = {0}, point = {1}", _maxComplete, point));
+ }
+ }
+ }
+ }
+
+
+ public void Result(int command, Struct result)
+ {
+ IFuture future;
+ lock (_results)
+ {
+ if (_results.ContainsKey(command))
+ {
+ future = _results[command];
+ _results.Remove(command);
+ }
+ else
+ {
+ throw new Exception(String.Format("Cannot ger result {0} for {1}", command, result));
+ }
+ }
+ future.Result = result;
+ }
+
+ public void AddException(ExecutionException exc)
+ {
+ lock (_exceptions)
+ {
+ _exceptions.Add(exc);
+ }
+ }
+
+ private ConnectionClose _close = null;
+
+ public void CloseCode(ConnectionClose close)
+ {
+ _close = close;
+ }
+
+ public List<ExecutionException> GetExceptions()
+ {
+ lock (_exceptions)
+ {
+ return new List<ExecutionException>(_exceptions);
+ }
+ }
+
+ public override IFuture Invoke(Method m, IFuture future)
+ {
+ lock (_commands)
+ {
+ future.Session = this;
+ int command = _commandsOut;
+ lock (_results)
+ {
+ _results.Add(command, future);
+ }
+ Invoke(m);
+ }
+ return future;
+ }
+
+
+ public void MessageTransfer(String destination,
+ MessageAcceptMode acceptMode,
+ MessageAcquireMode acquireMode,
+ Header header,
+ byte[] body,
+ params Option[] options)
+ {
+ MemoryStream mbody = new MemoryStream();
+ mbody.Write(body,0, body.Length);
+ MessageTransfer(destination, acceptMode, acquireMode, header,
+ mbody, options);
+ }
+
+ public void MessageTransfer(String destination,
+ MessageAcceptMode acceptMode,
+ MessageAcquireMode acquireMode,
+ Header header,
+ String body,
+ params Option[] options)
+ {
+ MessageTransfer(destination, acceptMode, acquireMode, header,
+ new MemoryStream(Convert.ToByte(body)), options);
+ }
+
+ public void Close()
+ {
+ SessionRequestTimeout(0);
+ SessionDetach(_name);
+ lock (_commands)
+ {
+ DateTime start = DateTime.Now;
+ long elapsed = 0;
+
+ while (!IsClosed && elapsed < _timeout)
+ {
+ Monitor.Wait(_commands, (int) (_timeout - elapsed));
+ elapsed = DateTime.Now.Subtract(start).Milliseconds;
+ }
+ }
+ }
+
+ public void Exception(Exception t)
+ {
+ log.Error(t, "Caught exception");
+ }
+
+ public void Closed()
+ {
+ IsClosed = true;
+ lock (_commands)
+ {
+ Monitor.PulseAll(_commands);
+ }
+ lock (_results)
+ {
+ foreach (IFuture result in _results.Values)
+ {
+ lock (result)
+ {
+ Monitor.PulseAll(result);
+ }
+ }
+ }
+ _channel.Session = null;
+ _channel = null;
+ }
+
+ public override String ToString()
+ {
+ return String.Format("session:{0}", _name);
+ }
+ }
+}
diff --git a/qpid/dotnet/client-010/client/transport/SessionDelegate.cs b/qpid/dotnet/client-010/client/transport/SessionDelegate.cs
new file mode 100644
index 0000000000..973e22df16
--- /dev/null
+++ b/qpid/dotnet/client-010/client/transport/SessionDelegate.cs
@@ -0,0 +1,126 @@
+/*
+*
+* 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.
+*
+*/
+
+namespace org.apache.qpid.transport
+{
+ /// <summary>
+ /// SessionDelegate
+ ///
+ /// </summary>
+ public abstract class SessionDelegate : MethodDelegate<Session>, IProtocolDelegate<Session>
+ {
+ public void Init(Session ssn, ProtocolHeader hdr)
+ {
+ }
+
+ public void Control(Session ssn, Method method)
+ {
+ method.Dispatch(ssn, this);
+ }
+
+ public void Command(Session ssn, Method method)
+ {
+ ssn.Identify(method);
+ method.Dispatch(ssn, this);
+ if (!method.HasPayload())
+ {
+ ssn.Processed(method);
+ }
+ }
+
+ public void Error(Session ssn, ProtocolError error)
+ {
+ }
+
+ public override void ExecutionResult(Session ssn, ExecutionResult result)
+ {
+ ssn.Result(result.GetCommandId(), result.GetValue());
+ }
+
+ public override void ExecutionException(Session ssn, ExecutionException exc)
+ {
+ ssn.AddException(exc);
+ }
+
+ public override void SessionCompleted(Session ssn, SessionCompleted cmp)
+ {
+ RangeSet ranges = cmp.GetCommands();
+ RangeSet known = null;
+ if (cmp.GetTimelyReply())
+ {
+ known = new RangeSet();
+ }
+
+ if (ranges != null)
+ {
+ foreach (Range range in ranges)
+ {
+ bool advanced = ssn.Complete(range.Lower, range.Upper);
+ if (advanced && known != null)
+ {
+ known.Add(range);
+ }
+ }
+ }
+
+ if (known != null)
+ {
+ ssn.SessionKnownCompleted(known);
+ }
+ }
+
+ public override void SessionKnownCompleted(Session ssn, SessionKnownCompleted kcmp)
+ {
+ RangeSet kc = kcmp.GetCommands();
+ if (kc != null)
+ {
+ ssn.KnownComplete(kc);
+ }
+ }
+
+ public override void SessionFlush(Session ssn, SessionFlush flush)
+ {
+ if (flush.GetCompleted())
+ {
+ ssn.FlushProcessed();
+ }
+ if (flush.GetConfirmed())
+ {
+ ssn.FlushProcessed();
+ }
+ if (flush.GetExpected())
+ {
+ // to be done
+ //throw new Exception("not implemented");
+ }
+ }
+
+ public override void SessionCommandPoint(Session ssn, SessionCommandPoint scp)
+ {
+ ssn.CommandsIn = scp.GetCommandId();
+ }
+
+ public override void ExecutionSync(Session ssn, ExecutionSync sync)
+ {
+ ssn.SyncPoint();
+ }
+ }
+}
diff --git a/qpid/dotnet/client-010/client/transport/Struct.cs b/qpid/dotnet/client-010/client/transport/Struct.cs
new file mode 100644
index 0000000000..ff8d80fcb1
--- /dev/null
+++ b/qpid/dotnet/client-010/client/transport/Struct.cs
@@ -0,0 +1,121 @@
+/*
+*
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing,
+* software distributed under the License is distributed on an
+* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+* KIND, either express or implied. See the License for the
+* specific language governing permissions and limitations
+* under the License.
+*
+*/
+using System;
+using System.Collections.Generic;
+using System.Text;
+using org.apache.qpid.transport.codec;
+
+namespace org.apache.qpid.transport
+{
+ /// <summary>
+ /// Struct
+ /// </summary>
+
+ public abstract class Struct : IEncodable
+ {
+ public static Struct Create(int type)
+ {
+ return StructFactory.create(type);
+ }
+
+ bool dirty = true;
+
+ public bool Dirty
+ {
+ get { return dirty; }
+ set { dirty = value; }
+ }
+
+ public abstract int GetStructType();
+
+ public abstract int GetSizeWidth();
+
+ public abstract int GetPackWidth();
+
+ public int GetEncodedType()
+ {
+ int type = GetStructType();
+ if (type < 0)
+ {
+ throw new Exception();
+ }
+ return type;
+ }
+
+ private bool IsBit<C, T>(Field<C, T> f)
+ {
+ return Equals(f.Type, typeof(Boolean));
+ }
+
+ private bool Packed()
+ {
+ return GetPackWidth() > 0;
+ }
+
+ private bool Encoded<C, T>(Field<C, T> f)
+ {
+ return !Packed() || !IsBit(f) && f.Has(this);
+ }
+
+ private int GetFlagWidth()
+ {
+ return (Fields.Count + 7) / 8;
+ }
+
+ private int GetFlagCount()
+ {
+ return 8 * GetPackWidth();
+ }
+
+ public abstract void Read(IDecoder dec);
+
+ public abstract void Write(IEncoder enc);
+
+ public abstract Dictionary<String, Object> Fields
+ {
+ get;
+ }
+
+ public override String ToString()
+ {
+ StringBuilder str = new StringBuilder();
+ str.Append(GetType());
+ str.Append("(");
+ bool first = true;
+ foreach (KeyValuePair<String, Object> me in Fields)
+ {
+ if (first)
+ {
+ first = false;
+ }
+ else
+ {
+ str.Append(", ");
+ }
+ str.Append(me.Key);
+ str.Append("=");
+ str.Append(me.Value);
+ }
+ str.Append(")");
+ return str.ToString();
+ }
+ }
+}
diff --git a/qpid/dotnet/client-010/client/transport/codec/AbstractDecoder.cs b/qpid/dotnet/client-010/client/transport/codec/AbstractDecoder.cs
new file mode 100644
index 0000000000..2e9e587407
--- /dev/null
+++ b/qpid/dotnet/client-010/client/transport/codec/AbstractDecoder.cs
@@ -0,0 +1,399 @@
+/*
+*
+* 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.
+*
+*/
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Text;
+using org.apache.qpid.transport.util;
+
+namespace org.apache.qpid.transport.codec
+{
+ /// <summary>
+ /// AbstractDecoder
+ /// </summary>
+ public abstract class AbstractDecoder : IDecoder
+ {
+ private readonly Dictionary<Binary, String> str8cache = new Dictionary<Binary, String>();
+
+ protected abstract byte DoGet();
+
+ protected abstract void DoGet(byte[] bytes);
+ public abstract bool HasRemaining();
+
+ protected byte Get()
+ {
+ return DoGet();
+ }
+
+ protected void Get(byte[] bytes)
+ {
+ DoGet(bytes);
+ }
+
+ protected Binary Get(int size)
+ {
+ byte[] bytes = new byte[size];
+ Get(bytes);
+ return new Binary(bytes);
+ }
+
+ protected short Uget()
+ {
+ return (short) (0xFF & Get());
+ }
+
+ public virtual short ReadUint8()
+ {
+ return Uget();
+ }
+
+ public abstract int ReadUint16();
+
+
+ public abstract long ReadUint32();
+
+
+ public int ReadSequenceNo()
+ {
+ return (int) ReadUint32();
+ }
+
+ public virtual long ReadUint64()
+ {
+ long l = 0;
+ for (int i = 0; i < 8; i++)
+ {
+ l |= ((long) (0xFF & Get())) << (56 - i*8);
+ }
+ return l;
+ }
+
+ public abstract short ReadInt8();
+ public abstract int ReadInt16();
+ public abstract long ReadInt32() ;
+ public abstract long ReadInt64();
+ public abstract float ReadFloat() ;
+ public abstract double ReadDouble() ;
+
+ public long ReadDatetime()
+ {
+ return ReadUint64();
+ }
+
+ private static String Decode(byte[] bytes, int offset, int length, Encoding encoding)
+ {
+ return encoding.GetString(bytes, offset, length);
+ }
+
+ private static String Decode(byte[] bytes, Encoding encoding)
+ {
+ return Decode(bytes, 0, bytes.Length, encoding);
+ }
+
+ public String ReadStr8()
+ {
+ short size = ReadUint8();
+ Binary bin = Get(size);
+ String str;
+ if (! str8cache.TryGetValue(bin, out str))
+ {
+ str = Decode(bin.Array(), bin.Offset(), bin.Size(), Encoding.UTF8);
+ str8cache.Add(bin, str);
+ }
+ return str;
+ }
+
+ public String ReadStr16()
+ {
+ int size = ReadUint16();
+ byte[] bytes = new byte[size];
+ Get(bytes);
+ return Decode(bytes, Encoding.UTF8);
+ }
+
+ public byte[] ReadVbin8()
+ {
+ int size = ReadUint8();
+ byte[] bytes = new byte[size];
+ Get(bytes);
+ return bytes;
+ }
+
+ public byte[] ReadVbin16()
+ {
+ int size = ReadUint16();
+ byte[] bytes = new byte[size];
+ Get(bytes);
+ return bytes;
+ }
+
+ public byte[] ReadVbin32()
+ {
+ int size = (int) ReadUint32();
+ byte[] bytes = new byte[size];
+ Get(bytes);
+ return bytes;
+ }
+
+ public RangeSet ReadSequenceSet()
+ {
+ int count = ReadUint16()/8;
+ if (count == 0)
+ {
+ return null;
+ }
+ RangeSet ranges = new RangeSet();
+ for (int i = 0; i < count; i++)
+ {
+ ranges.Add(ReadSequenceNo(), ReadSequenceNo());
+ }
+ return ranges;
+ }
+
+ public RangeSet ReadByteRanges()
+ {
+ throw new Exception("not implemented");
+ }
+
+ public UUID ReadUuid()
+ {
+ long msb = ReadUint64();
+ long lsb = ReadUint64();
+ return new UUID(msb, lsb);
+ }
+
+ public String ReadContent()
+ {
+ throw new Exception("Deprecated");
+ }
+
+ public Struct ReadStruct(int type)
+ {
+ Struct st = Struct.Create(type);
+ int width = st.GetSizeWidth();
+ if (width > 0)
+ {
+ long size = ReadSize(width);
+ if (size == 0)
+ {
+ return null;
+ }
+ }
+ if (type > 0)
+ {
+ int code = ReadUint16();
+ Debug.Assert(code == type);
+ }
+ st.Read(this);
+ return st;
+ }
+
+ public Struct ReadStruct32()
+ {
+ long size = ReadUint32();
+ if (size == 0)
+ {
+ return null;
+ }
+ int type = ReadUint16();
+ Struct result = Struct.Create(type);
+ result.Read(this);
+ return result;
+ }
+
+ public Dictionary<String, Object> ReadMap()
+ {
+ long size = ReadUint32();
+
+ if (size == 0)
+ {
+ return null;
+ }
+
+ long count = ReadUint32();
+
+ Dictionary<String, Object> result = new Dictionary<String, Object>();
+ for (int i = 0; i < count; i++)
+ {
+ String key = ReadStr8();
+ byte code = Get();
+ QpidType t = GetType(code);
+ Object value = Read(t);
+ result.Add(key, value);
+ }
+
+ return result;
+ }
+
+ public List<Object> ReadList()
+ {
+ long size = ReadUint32();
+
+ if (size == 0)
+ {
+ return null;
+ }
+
+ long count = ReadUint32();
+
+ List<Object> result = new List<Object>();
+ for (int i = 0; i < count; i++)
+ {
+ byte code = Get();
+ QpidType t = GetType(code);
+ Object value = Read(t);
+ result.Add(value);
+ }
+ return result;
+ }
+
+ public List<Object> ReadArray()
+ {
+ long size = ReadUint32();
+
+ if (size == 0)
+ {
+ return null;
+ }
+
+ byte code = Get();
+ QpidType t = GetType(code);
+ long count = ReadUint32();
+
+ List<Object> result = new List<Object>();
+ for (int i = 0; i < count; i++)
+ {
+ Object value = Read(t);
+ result.Add(value);
+ }
+ return result;
+ }
+
+ private QpidType GetType(byte code)
+ {
+ return QpidType.get(code);
+ }
+
+ private long ReadSize(QpidType t)
+ {
+ return t.Fixed ? t.Width : ReadSize(t.Width);
+ }
+
+ private long ReadSize(int width)
+ {
+ switch (width)
+ {
+ case 1:
+ return ReadUint8();
+ case 2:
+ return ReadUint16();
+ case 4:
+ return ReadUint32();
+ default:
+ throw new Exception("illegal width: " + width);
+ }
+ }
+
+ private byte[] ReadBytes(QpidType t)
+ {
+ long size = ReadSize(t);
+ byte[] result = new byte[(int) size];
+ Get(result);
+ return result;
+ }
+
+ private Object Read(QpidType t)
+ {
+ switch (t.Code)
+ {
+ case Code.BIN8:
+ case Code.UINT8:
+ return ReadUint8();
+ case Code.INT8:
+ return Get();
+ case Code.CHAR:
+ return (char) Get();
+ case Code.BOOLEAN:
+ return Get() > 0;
+
+ case Code.BIN16:
+ case Code.UINT16:
+ return ReadUint16();
+ case Code.INT16:
+ return (short) ReadUint16();
+
+ case Code.BIN32:
+ case Code.UINT32:
+ return ReadUint32();
+
+ case Code.CHAR_UTF32:
+ case Code.INT32:
+ return (int) ReadUint32();
+
+ case Code.FLOAT:
+ return (float)BitConverter.Int64BitsToDouble(ReadUint32() << 32);
+
+ case Code.BIN64:
+ case Code.UINT64:
+ case Code.INT64:
+ case Code.DATETIME:
+ return ReadUint64();
+
+ case Code.DOUBLE:
+ return BitConverter.Int64BitsToDouble(ReadUint64());
+ case Code.UUID:
+ return ReadUuid();
+ case Code.STR8:
+ return ReadStr8();
+ case Code.STR16:
+ return ReadStr16();
+ case Code.STR8_LATIN:
+ case Code.STR8_UTF16:
+ case Code.STR16_LATIN:
+ case Code.STR16_UTF16:
+ // XXX: need to do character conversion
+ return Encoding.UTF8.GetString(ReadBytes(t));
+
+ case Code.MAP:
+ return ReadMap();
+ case Code.LIST:
+ return ReadList();
+ case Code.ARRAY:
+ return ReadArray();
+ case Code.STRUCT32:
+ return ReadStruct32();
+
+ case Code.BIN40:
+ case Code.DEC32:
+ case Code.BIN72:
+ case Code.DEC64:
+ // XXX: what types are we supposed to use here?
+ return ReadBytes(t);
+
+ case Code.VOID:
+ return null;
+
+ default:
+ return ReadBytes(t);
+ }
+ }
+ }
+}
diff --git a/qpid/dotnet/client-010/client/transport/codec/AbstractEncoder.cs b/qpid/dotnet/client-010/client/transport/codec/AbstractEncoder.cs
new file mode 100644
index 0000000000..eb8bdae80a
--- /dev/null
+++ b/qpid/dotnet/client-010/client/transport/codec/AbstractEncoder.cs
@@ -0,0 +1,590 @@
+/*
+*
+* 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.
+*
+*/
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.IO;
+using System.Text;
+using org.apache.qpid.transport.util;
+
+namespace org.apache.qpid.transport.codec
+{
+ /// <summary>
+ /// AbstractEncoder
+ /// </summary>
+ public abstract class AbstractEncoder : IEncoder
+ {
+ private static readonly Dictionary<Type, Code> ENCODINGS = new Dictionary<Type, Code>();
+ private readonly Dictionary<String, byte[]> str8cache = new Dictionary<String, byte[]>();
+
+ static AbstractEncoder()
+ {
+ ENCODINGS.Add(typeof (Boolean), Code.BOOLEAN);
+ ENCODINGS.Add(typeof (String), Code.STR16);
+ ENCODINGS.Add(typeof (long), Code.INT64);
+ ENCODINGS.Add(typeof (int), Code.INT32);
+ ENCODINGS.Add(typeof (short), Code.INT16);
+ ENCODINGS.Add(typeof (Byte), Code.INT8);
+ ENCODINGS.Add(typeof (Dictionary<String, Object>), Code.MAP);
+ ENCODINGS.Add(typeof (List<Object>), Code.LIST);
+ ENCODINGS.Add(typeof (float), Code.FLOAT);
+ ENCODINGS.Add(typeof (Double), Code.DOUBLE);
+ ENCODINGS.Add(typeof (char), Code.CHAR);
+ ENCODINGS.Add(typeof (byte[]), Code.VBIN32);
+ ENCODINGS.Add(typeof (UUID), Code.UUID);
+ }
+
+ protected abstract void DoPut(byte b);
+
+ protected abstract void DoPut(MemoryStream src);
+
+
+ protected void Put(byte b)
+ {
+ DoPut(b);
+ }
+
+ protected void Put(MemoryStream src)
+ {
+ DoPut(src);
+ }
+
+ protected virtual void Put(byte[] bytes)
+ {
+ Put(new MemoryStream(bytes));
+ }
+
+ protected abstract int BeginSize8();
+ protected abstract void EndSize8(int pos);
+
+ protected abstract int BeginSize16();
+ protected abstract void EndSize16(int pos);
+
+ protected abstract int BeginSize32();
+ protected abstract void EndSize32(int pos);
+
+ public virtual void WriteUint8(short b)
+ {
+ Debug.Assert(b < 0x100);
+ Put((byte) b);
+ }
+
+ public virtual void WriteUint16(int s)
+ {
+ Debug.Assert(s < 0x10000);
+ Put((byte) Functions.Lsb(s >> 8));
+ Put((byte) Functions.Lsb(s));
+ }
+
+ public virtual void WriteUint32(long i)
+ {
+ Debug.Assert(i < 0x100000000L);
+ Put((byte) Functions.Lsb(i >> 24));
+ Put((byte) Functions.Lsb(i >> 16));
+ Put((byte) Functions.Lsb(i >> 8));
+ Put((byte) Functions.Lsb(i));
+ }
+
+ public void WriteSequenceNo(int i)
+ {
+ WriteUint32(i);
+ }
+
+ public virtual void WriteUint64(long l)
+ {
+ for (int i = 0; i < 8; i++)
+ {
+ Put((byte) Functions.Lsb(l >> (56 - i*8)));
+ }
+ }
+
+ public abstract void WriteInt8(short b) ;
+ public abstract void WriteInt16(int s) ;
+ public abstract void WriteInt32(long i) ;
+ public abstract void WriteInt64(long l) ;
+ public abstract void WriteFloat(float f) ;
+ public abstract void WriteDouble(double d) ;
+
+ public void WriteDatetime(long l)
+ {
+ WriteUint64(l);
+ }
+
+ private static byte[] Encode(String s, Encoding encoding)
+ {
+ return encoding.GetBytes(s);
+ }
+
+ public void WriteStr8(String s)
+ {
+ if (s == null)
+ {
+ s = "";
+ }
+
+ byte[] bytes;
+ if (! str8cache.ContainsKey(s))
+ {
+ bytes = Encode(s, System.Text.Encoding.UTF8);
+ str8cache.Add(s, bytes);
+ }
+ else
+ {
+ bytes = str8cache[s];
+ }
+ WriteUint8((short) bytes.Length);
+ Put(bytes);
+ }
+
+ public void WriteStr16(String s)
+ {
+ if (s == null)
+ {
+ s = "";
+ }
+
+ byte[] bytes = Encode(s, System.Text.Encoding.UTF8);
+ WriteUint16(bytes.Length);
+ Put(bytes);
+ }
+
+ public void WriteVbin8(byte[] bytes)
+ {
+ if (bytes == null)
+ {
+ bytes = new byte[0];
+ }
+ if (bytes.Length > 255)
+ {
+ throw new Exception("array too long: " + bytes.Length);
+ }
+ WriteUint8((short) bytes.Length);
+ Put(bytes);
+ }
+
+ public void WriteVbin16(byte[] bytes)
+ {
+ if (bytes == null)
+ {
+ bytes = new byte[0];
+ }
+ WriteUint16(bytes.Length);
+ Put(bytes);
+ }
+
+ public void WriteVbin32(byte[] bytes)
+ {
+ if (bytes == null)
+ {
+ bytes = new byte[0];
+ }
+ WriteUint32(bytes.Length);
+ Put(bytes);
+ }
+
+ public void WriteSequenceSet(RangeSet ranges)
+ {
+ if (ranges == null)
+ {
+ WriteUint16(0);
+ }
+ else
+ {
+ WriteUint16(ranges.Size()*8);
+ foreach (Range range in ranges)
+ {
+ WriteSequenceNo(range.Lower);
+ WriteSequenceNo(range.Upper);
+ }
+ }
+ }
+
+ public void WriteByteRanges(RangeSet ranges)
+ {
+ throw new Exception("not implemented");
+ }
+
+ public void WriteUuid(UUID uuid)
+ {
+ long msb = 0;
+ long lsb = 0;
+ if (uuid != null)
+ {
+ msb = uuid.MostSignificantBits;
+ lsb = uuid.LeastSignificantBits;
+ }
+ WriteUint64(msb);
+ WriteUint64(lsb);
+ }
+
+ public void WriteStruct(int type, Struct s)
+ {
+ if (s == null)
+ {
+ s = Struct.Create(type);
+ }
+
+ int width = s.GetSizeWidth();
+ int pos = -1;
+ if (width > 0)
+ {
+ pos = BeginSize(width);
+ }
+
+ if (type > 0)
+ {
+ WriteUint16(type);
+ }
+
+ s.Write(this);
+
+ if (width > 0)
+ {
+ EndSize(width, pos);
+ }
+ }
+
+ public void WriteStruct32(Struct s)
+ {
+ if (s == null)
+ {
+ WriteUint32(0);
+ }
+ else
+ {
+ int pos = BeginSize32();
+ WriteUint16(s.GetEncodedType());
+ s.Write(this);
+ EndSize32(pos);
+ }
+ }
+
+ private Code Encoding(Object value)
+ {
+ if (value == null)
+ {
+ return Code.VOID;
+ }
+
+ Type klass = value.GetType();
+ Code type = Resolve(klass);
+
+ if (type == Code.VOID)
+ {
+ throw new Exception
+ ("unable to resolve type: " + klass + ", " + value);
+ }
+ else
+ {
+ return type;
+ }
+ }
+
+ private static Code Resolve(Type klass)
+ {
+ Code type;
+ if(ENCODINGS.ContainsKey(klass))
+ {
+ return ENCODINGS[klass];
+ }
+
+ Type sup = klass.BaseType;
+ if (sup != null)
+ {
+ type = Resolve(sup);
+
+ if (type != Code.VOID)
+ {
+ return type;
+ }
+ }
+ foreach (Type iface in klass.GetInterfaces())
+ {
+ type = Resolve(iface);
+ if (type != Code.VOID)
+ {
+ return type;
+ }
+ }
+ return Code.VOID;
+ }
+
+ public void WriteMap(Dictionary<String, Object> map)
+ {
+ int pos = BeginSize32();
+ if (map != null)
+ {
+ WriteUint32(map.Count);
+ WriteMapEntries(map);
+ }
+ EndSize32(pos);
+ }
+
+ protected void WriteMapEntries(Dictionary<String, Object> map)
+ {
+ foreach (KeyValuePair<String, Object> entry in map)
+ {
+ String key = entry.Key;
+ Object value = entry.Value;
+ Code type = Encoding(value);
+ WriteStr8(key);
+ Put((byte) type);
+ Write(type, value);
+ }
+ }
+
+ public void WriteList(List<Object> list)
+ {
+ int pos = BeginSize32();
+ if (list != null)
+ {
+ WriteUint32(list.Count);
+ WriteListEntries(list);
+ }
+ EndSize32(pos);
+ }
+
+ protected void WriteListEntries(List<Object> list)
+ {
+ foreach (Object value in list)
+ {
+ Code type = Encoding(value);
+ Put((byte) type);
+ Write(type, value);
+ }
+ }
+
+ public void WriteArray(List<Object> array)
+ {
+ int pos = BeginSize32();
+ if (array != null)
+ {
+ WriteArrayEntries(array);
+ }
+ EndSize32(pos);
+ }
+
+ protected void WriteArrayEntries(List<Object> array)
+ {
+ Code type;
+
+ if (array.Count == 0)
+ {
+ return;
+ }
+ else
+ {
+ type = Encoding(array[0]);
+ }
+ Put((byte) type);
+ WriteUint32(array.Count);
+
+ foreach (Object value in array)
+ {
+ Write(type, value);
+ }
+ }
+
+ private void WriteSize(QpidType t, int size)
+ {
+ if (t.Fixed)
+ {
+ if (size != t.width)
+ {
+ throw new Exception("size does not match fixed width " + t.width + ": " + size);
+ }
+ }
+ else
+ {
+ WriteSize(t.width, size);
+ }
+ }
+
+ private void WriteSize(int width, int size)
+ {
+ // XXX: should check lengths
+ switch (width)
+ {
+ case 1:
+ WriteUint8((short) size);
+ break;
+ case 2:
+ WriteUint16(size);
+ break;
+ case 4:
+ WriteUint32(size);
+ break;
+ default:
+ throw new Exception("illegal width: " + width);
+ }
+ }
+
+ private int BeginSize(int width)
+ {
+ switch (width)
+ {
+ case 1:
+ return BeginSize8();
+ case 2:
+ return BeginSize16();
+ case 4:
+ return BeginSize32();
+ default:
+ throw new Exception("illegal width: " + width);
+ }
+ }
+
+ private void EndSize(int width, int pos)
+ {
+ switch (width)
+ {
+ case 1:
+ EndSize8(pos);
+ break;
+ case 2:
+ EndSize16(pos);
+ break;
+ case 4:
+ EndSize32(pos);
+ break;
+ default:
+ throw new Exception("illegal width: " + width);
+ }
+ }
+
+ private void WriteBytes(QpidType t, byte[] bytes)
+ {
+ WriteSize(t, bytes.Length);
+ Put(bytes);
+ }
+
+ private void Write(Code t, Object value)
+ {
+ switch (t)
+ {
+ case Code.BIN8:
+ case Code.UINT8:
+ WriteUint8((short) value);
+ break;
+ case Code.INT8:
+ Put((Byte) value);
+ break;
+ case Code.CHAR:
+ byte[] b = BitConverter.GetBytes((char) value);
+ Put(b[0]);
+ break;
+ case Code.BOOLEAN:
+ if ((bool) value)
+ {
+ Put(1);
+ }
+ else
+ {
+ Put(0);
+ }
+
+ break;
+
+ case Code.BIN16:
+ case Code.UINT16:
+ WriteUint16((int) value);
+ break;
+
+ case Code.INT16:
+ WriteUint16((short) value);
+ break;
+
+ case Code.BIN32:
+ case Code.UINT32:
+ WriteUint32((long) value);
+ break;
+
+ case Code.CHAR_UTF32:
+ case Code.INT32:
+ WriteUint32((int) value);
+ break;
+
+ case Code.FLOAT:
+ WriteUint32(BitConverter.DoubleToInt64Bits((float) value) >> 32);
+ break;
+
+ case Code.BIN64:
+ case Code.UINT64:
+ case Code.INT64:
+ case Code.DATETIME:
+ WriteUint64((long) value);
+ break;
+
+ case Code.DOUBLE:
+ WriteUint64( BitConverter.DoubleToInt64Bits((double) value));
+ break;
+
+ case Code.UUID:
+ WriteUuid((UUID) value);
+ break;
+
+ case Code.STR8:
+ WriteStr8((string) value);
+ break;
+
+ case Code.STR16:
+ WriteStr16((string) value);
+ break;
+
+ case Code.STR8_LATIN:
+ case Code.STR8_UTF16:
+ case Code.STR16_LATIN:
+ case Code.STR16_UTF16:
+ // XXX: need to do character conversion
+ WriteBytes(QpidType.get((byte) t), Encode((string) value, System.Text.Encoding.Unicode));
+ break;
+
+ case Code.MAP:
+ WriteMap((Dictionary<String, Object>) value);
+ break;
+ case Code.LIST:
+ WriteList((List<Object>) value);
+ break;
+ case Code.ARRAY:
+ WriteList((List<Object>) value);
+ break;
+ case Code.STRUCT32:
+ WriteStruct32((Struct) value);
+ break;
+
+ case Code.BIN40:
+ case Code.DEC32:
+ case Code.BIN72:
+ case Code.DEC64:
+ // XXX: what types are we supposed to use here?
+ WriteBytes(QpidType.get((byte) t), (byte[]) value);
+ break;
+
+ case Code.VOID:
+ break;
+
+ default:
+ WriteBytes(QpidType.get((byte) t), (byte[]) value);
+ break;
+ }
+ }
+ }
+}
diff --git a/qpid/dotnet/client-010/client/transport/codec/Decoder.cs b/qpid/dotnet/client-010/client/transport/codec/Decoder.cs
new file mode 100644
index 0000000000..9afc23fd4e
--- /dev/null
+++ b/qpid/dotnet/client-010/client/transport/codec/Decoder.cs
@@ -0,0 +1,72 @@
+/*
+*
+* 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.
+*
+*/
+
+using System;
+using System.Collections.Generic;
+using org.apache.qpid.transport.util;
+
+namespace org.apache.qpid.transport.codec
+{
+ /// <summary>
+ /// Decoder
+ /// </summary>
+
+ public interface Decoder
+ {
+
+ bool hasRemaining();
+
+ short readUint8();
+ int readUint16();
+ long readUint32();
+ long readUint64();
+
+ short readInt8();
+ int readInt16();
+ long readInt32();
+ long readInt64();
+
+ double readDouble() ;
+ float readFloat() ;
+ long readDatetime();
+
+ UUID readUuid();
+
+ int readSequenceNo();
+ RangeSet readSequenceSet(); // XXX
+ RangeSet readByteRanges(); // XXX
+
+ String readStr8();
+ String readStr16();
+
+ byte[] readVbin8();
+ byte[] readVbin16();
+ byte[] readVbin32();
+
+ Struct readStruct32();
+ Dictionary<String, Object> readMap();
+ List<Object> readList();
+ List<Object> readArray();
+
+ Struct readStruct(int type);
+ }
+
+}
diff --git a/qpid/dotnet/client-010/client/transport/codec/Encodable.cs b/qpid/dotnet/client-010/client/transport/codec/Encodable.cs
new file mode 100644
index 0000000000..71f4f62458
--- /dev/null
+++ b/qpid/dotnet/client-010/client/transport/codec/Encodable.cs
@@ -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.
+*
+*/
+
+namespace org.apache.qpid.transport.codec
+{
+
+
+ /// <summary>
+ /// Encodable
+ /// </summary>
+
+ public interface Encodable
+ {
+
+ void write(Encoder enc);
+
+ void read(Decoder dec);
+ }
+} \ No newline at end of file
diff --git a/qpid/dotnet/client-010/client/transport/codec/Encoder.cs b/qpid/dotnet/client-010/client/transport/codec/Encoder.cs
new file mode 100644
index 0000000000..282e3ff5b5
--- /dev/null
+++ b/qpid/dotnet/client-010/client/transport/codec/Encoder.cs
@@ -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.
+*
+*/
+
+using System;
+using System.Collections.Generic;
+using org.apache.qpid.transport.util;
+using RangeSet = org.apache.qpid.transport.RangeSet;
+using Struct = org.apache.qpid.transport.Struct;
+namespace org.apache.qpid.transport.codec
+{
+ /// <summary>
+ /// Encoder
+ /// </summary>
+
+ public interface Encoder
+ {
+
+ void writeUint8(short b);
+ void writeUint16(int s);
+ void writeUint32(long i);
+ void writeUint64(long l);
+
+ void writeInt8(short b);
+ void writeInt16(int s);
+ void writeInt32(long i);
+ void writeInt64(long l);
+
+ void writeFloat(float f) ;
+ void writeDouble(double d) ;
+
+ void writeDatetime(long l);
+ void writeUuid(UUID uuid);
+
+ void writeSequenceNo(int s);
+ void writeSequenceSet(RangeSet ranges); // XXX
+ void writeByteRanges(RangeSet ranges); // XXX
+
+ void writeStr8(string s);
+ void writeStr16(string s);
+
+ void writeVbin8(byte[] bytes);
+ void writeVbin16(byte[] bytes);
+ void writeVbin32(byte[] bytes);
+
+ void writeStruct32(Struct s);
+ void writeMap(Dictionary<String, Object> map);
+ void writeList(List<Object> list);
+ void writeArray(List<Object> array);
+
+ void writeStruct(int type, Struct s);
+ }
+}
diff --git a/qpid/dotnet/client-010/client/transport/codec/IDecoder.cs b/qpid/dotnet/client-010/client/transport/codec/IDecoder.cs
new file mode 100644
index 0000000000..7de2e93fe7
--- /dev/null
+++ b/qpid/dotnet/client-010/client/transport/codec/IDecoder.cs
@@ -0,0 +1,72 @@
+/*
+*
+* 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.
+*
+*/
+
+using System;
+using System.Collections.Generic;
+using org.apache.qpid.transport.util;
+
+namespace org.apache.qpid.transport.codec
+{
+ /// <summary>
+ /// Decoder
+ /// </summary>
+
+ public interface IDecoder
+ {
+
+ bool HasRemaining();
+
+ short ReadUint8();
+ int ReadUint16();
+ long ReadUint32();
+ long ReadUint64();
+
+ short ReadInt8();
+ int ReadInt16();
+ long ReadInt32();
+ long ReadInt64();
+
+ double ReadDouble() ;
+ float ReadFloat() ;
+ long ReadDatetime();
+
+ UUID ReadUuid();
+
+ int ReadSequenceNo();
+ RangeSet ReadSequenceSet(); // XXX
+ RangeSet ReadByteRanges(); // XXX
+
+ String ReadStr8();
+ String ReadStr16();
+
+ byte[] ReadVbin8();
+ byte[] ReadVbin16();
+ byte[] ReadVbin32();
+
+ Struct ReadStruct32();
+ Dictionary<String, Object> ReadMap();
+ List<Object> ReadList();
+ List<Object> ReadArray();
+
+ Struct ReadStruct(int type);
+ }
+
+}
diff --git a/qpid/dotnet/client-010/client/transport/codec/IEncodable.cs b/qpid/dotnet/client-010/client/transport/codec/IEncodable.cs
new file mode 100644
index 0000000000..5c63e17fdd
--- /dev/null
+++ b/qpid/dotnet/client-010/client/transport/codec/IEncodable.cs
@@ -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.
+*
+*/
+
+namespace org.apache.qpid.transport.codec
+{
+
+
+ /// <summary>
+ /// Encodable
+ /// </summary>
+
+ public interface IEncodable
+ {
+
+ void Write(IEncoder enc);
+
+ void Read(IDecoder dec);
+ }
+}
diff --git a/qpid/dotnet/client-010/client/transport/codec/IEncoder.cs b/qpid/dotnet/client-010/client/transport/codec/IEncoder.cs
new file mode 100644
index 0000000000..4ffc852052
--- /dev/null
+++ b/qpid/dotnet/client-010/client/transport/codec/IEncoder.cs
@@ -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.
+*
+*/
+
+using System;
+using System.Collections.Generic;
+using org.apache.qpid.transport.util;
+using RangeSet = org.apache.qpid.transport.RangeSet;
+using Struct = org.apache.qpid.transport.Struct;
+namespace org.apache.qpid.transport.codec
+{
+ /// <summary>
+ /// Encoder
+ /// </summary>
+
+ public interface IEncoder
+ {
+
+ void WriteUint8(short b);
+ void WriteUint16(int s);
+ void WriteUint32(long i);
+ void WriteUint64(long l);
+
+ void WriteInt8(short b);
+ void WriteInt16(int s);
+ void WriteInt32(long i);
+ void WriteInt64(long l);
+
+ void WriteFloat(float f) ;
+ void WriteDouble(double d) ;
+
+ void WriteDatetime(long l);
+ void WriteUuid(UUID uuid);
+
+ void WriteSequenceNo(int s);
+ void WriteSequenceSet(RangeSet ranges); // XXX
+ void WriteByteRanges(RangeSet ranges); // XXX
+
+ void WriteStr8(string s);
+ void WriteStr16(string s);
+
+ void WriteVbin8(byte[] bytes);
+ void WriteVbin16(byte[] bytes);
+ void WriteVbin32(byte[] bytes);
+
+ void WriteStruct32(Struct s);
+ void WriteMap(Dictionary<String, Object> map);
+ void WriteList(List<Object> list);
+ void WriteArray(List<Object> array);
+
+ void WriteStruct(int type, Struct s);
+ }
+}
diff --git a/qpid/dotnet/client-010/client/transport/codec/MSDecoder.cs b/qpid/dotnet/client-010/client/transport/codec/MSDecoder.cs
new file mode 100644
index 0000000000..59731b739a
--- /dev/null
+++ b/qpid/dotnet/client-010/client/transport/codec/MSDecoder.cs
@@ -0,0 +1,110 @@
+/*
+*
+* 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.
+*
+*/
+
+using System;
+using System.IO;
+using System.Text;
+using org.apache.qpid.transport.util;
+
+namespace org.apache.qpid.transport.codec
+{
+
+
+ /// <summary>
+ /// MSDecoder
+ ///
+ /// </summary>
+
+
+ public sealed class MSDecoder : AbstractDecoder
+ {
+
+ private BinaryReader _reader;
+
+ public void Init(MemoryStream st)
+ {
+ _reader = new BinaryReader(st, Encoding.BigEndianUnicode);
+ }
+
+ protected override byte DoGet()
+ {
+ return _reader.ReadByte();
+ }
+
+ protected override void DoGet(byte[] bytes)
+ {
+ _reader.Read(bytes, 0, bytes.Length);
+ }
+
+ public override bool HasRemaining()
+ {
+ return (_reader.BaseStream.Position < _reader.BaseStream.Length);
+ }
+
+ public override short ReadUint8()
+ {
+ return (short) (0xFF & _reader.ReadByte());
+ }
+
+ public override int ReadUint16()
+ {
+ return ByteEncoder.GetBigEndian((UInt16) _reader.ReadInt16());
+ }
+
+ public override long ReadUint32()
+ {
+ return ByteEncoder.GetBigEndian((UInt32) _reader.ReadInt32());
+ }
+
+ public override long ReadUint64()
+ {
+ return (long) ByteEncoder.GetBigEndian(_reader.ReadInt64());
+ }
+
+ public override short ReadInt8()
+ {
+ return (short) (0xFF & _reader.ReadByte());
+ }
+
+ public override int ReadInt16()
+ {
+ return ByteEncoder.GetBigEndian((Int16) _reader.ReadInt16());
+ }
+
+ public override long ReadInt32()
+ {
+ return ByteEncoder.GetBigEndian((Int32) _reader.ReadInt32());
+ }
+
+ public override long ReadInt64()
+ {
+ return (long) ByteEncoder.GetBigEndian(_reader.ReadInt64());
+ }
+
+ public override double ReadDouble() {
+ return (double) ByteEncoder.GetBigEndian(_reader.ReadDouble()) ;
+ }
+
+ public override float ReadFloat() {
+ return (float) _reader.ReadSingle() ;
+ }
+ }
+}
diff --git a/qpid/dotnet/client-010/client/transport/codec/MSEncoder.cs b/qpid/dotnet/client-010/client/transport/codec/MSEncoder.cs
new file mode 100644
index 0000000000..d863c57dee
--- /dev/null
+++ b/qpid/dotnet/client-010/client/transport/codec/MSEncoder.cs
@@ -0,0 +1,172 @@
+/*
+*
+* 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.
+*
+*/
+
+using System;
+using System.Diagnostics;
+using System.IO;
+using org.apache.qpid.transport.util;
+
+namespace org.apache.qpid.transport.codec
+{
+ /// <summary>
+ /// MSEncoder
+ /// </summary>
+ public sealed class MSEncoder : AbstractEncoder
+ {
+ private readonly MemoryStream _out;
+ private readonly BinaryWriter _writer;
+
+ public MSEncoder(int capacity)
+ {
+ _out = new MemoryStream(capacity);
+ _writer = new BinaryWriter(_out);
+ }
+
+ public void Init()
+ {
+ _out.Seek(0, SeekOrigin.Begin);
+ }
+
+ public MemoryStream Segment()
+ {
+ int length = (int) _out.Position;
+ MemoryStream result = new MemoryStream(_out.ToArray(), 0, length);
+ result.Seek(length, SeekOrigin.Begin);
+ _out.Seek(0, SeekOrigin.Begin);
+ return result;
+ }
+
+
+ protected override void DoPut(byte b)
+ {
+ _writer.Write(b);
+ }
+
+ protected override void DoPut(MemoryStream src)
+ {
+ _writer.Write(src.ToArray());
+ }
+
+ protected override void Put(byte[] bytes)
+ {
+ _writer.Write(bytes);
+ }
+
+ public override void WriteUint8(short b)
+ {
+ Debug.Assert(b < 0x100);
+ _writer.Write((byte) b);
+ }
+
+ public override void WriteUint16(int s)
+ {
+ Debug.Assert(s < 0x10000);
+ _writer.Write(ByteEncoder.GetBigEndian((UInt16) s));
+ }
+
+ public override void WriteUint32(long i)
+ {
+ Debug.Assert(i < 0x100000000L);
+ _writer.Write(ByteEncoder.GetBigEndian((UInt32) i));
+ }
+
+ public override void WriteUint64(long l)
+ {
+ _writer.Write(ByteEncoder.GetBigEndian(l));
+ }
+
+ public override void WriteInt8(short b)
+ {
+ Debug.Assert(b < 0x100);
+ _writer.Write((byte) b);
+ }
+
+ public override void WriteInt16(int s)
+ {
+ Debug.Assert(s < 0x10000);
+ _writer.Write(ByteEncoder.GetBigEndian((Int16) s));
+ }
+
+ public override void WriteInt32(long i)
+ {
+ Debug.Assert(i < 0x100000000L);
+ _writer.Write(ByteEncoder.GetBigEndian((Int32) i));
+ }
+
+ public override void WriteInt64(long l)
+ {
+ _writer.Write(ByteEncoder.GetBigEndian(l));
+ }
+
+ public override void WriteFloat(float f) {
+ _writer.Write(f) ;
+ }
+
+ public override void WriteDouble(double d) {
+ _writer.Write(ByteEncoder.GetBigEndian(d)) ;
+ }
+
+ protected override int BeginSize8()
+ {
+ int pos = (int) _out.Position;
+ _writer.Write((byte) 0);
+ return pos;
+ }
+
+ protected override void EndSize8(int pos)
+ {
+ int cur = (int) _out.Position;
+ _out.Seek(pos, SeekOrigin.Begin);
+ _writer.Write((byte) (cur - pos - 1));
+ _out.Seek(cur, SeekOrigin.Begin);
+ }
+
+ protected override int BeginSize16()
+ {
+ int pos = (int) _out.Position;
+ _writer.Write((short) 0);
+ return pos;
+ }
+
+ protected override void EndSize16(int pos)
+ {
+ int cur = (int) _out.Position;
+ _out.Seek(pos, SeekOrigin.Begin);
+ _writer.Write((short) (cur - pos - 2));
+ _out.Seek(cur, SeekOrigin.Begin);
+ }
+
+ protected override int BeginSize32()
+ {
+ int pos = (int) _out.Position;
+ _writer.Write(0);
+ return pos;
+ }
+
+ protected override void EndSize32(int pos)
+ {
+ int cur = (int) _out.Position;
+ _out.Seek(pos, SeekOrigin.Begin);
+ _writer.Write(ByteEncoder.GetBigEndian((Int32) cur - pos - 4));
+ _out.Seek(cur, SeekOrigin.Begin);
+ }
+ }
+}
diff --git a/qpid/dotnet/client-010/client/transport/exception/ConnectionException.cs b/qpid/dotnet/client-010/client/transport/exception/ConnectionException.cs
new file mode 100644
index 0000000000..cbf5e39e52
--- /dev/null
+++ b/qpid/dotnet/client-010/client/transport/exception/ConnectionException.cs
@@ -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.
+*
+*/
+using System;
+namespace org.apache.qpid.transport
+{
+
+
+ /// <summary>
+ /// ConnectionException
+ /// </summary>
+
+ [Serializable]
+ public class ConnectionException : Exception
+ {
+ virtual public ConnectionClose Close
+ {
+ get
+ {
+ return _close;
+ }
+
+ }
+
+ private ConnectionClose _close;
+
+ public ConnectionException(ConnectionClose close):base(close.GetReplyText())
+ {
+ _close = close;
+ }
+ }
+}
diff --git a/qpid/dotnet/client-010/client/transport/exception/ExceptionArgs.cs b/qpid/dotnet/client-010/client/transport/exception/ExceptionArgs.cs
new file mode 100644
index 0000000000..01793a6ad0
--- /dev/null
+++ b/qpid/dotnet/client-010/client/transport/exception/ExceptionArgs.cs
@@ -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.
+*
+*/
+
+using System;
+
+namespace org.apache.qpid.transport
+{
+ public class ExceptionArgs : EventArgs
+ {
+ public ExceptionArgs(Exception e)
+ {
+ _exception = e;
+ }
+ private Exception _exception;
+
+ public Exception Exception
+ {
+ get { return _exception; }
+ set { _exception = value; }
+ }
+
+ }
+}
diff --git a/qpid/dotnet/client-010/client/transport/exception/ProtocolVersionException.cs b/qpid/dotnet/client-010/client/transport/exception/ProtocolVersionException.cs
new file mode 100644
index 0000000000..f18fc1173f
--- /dev/null
+++ b/qpid/dotnet/client-010/client/transport/exception/ProtocolVersionException.cs
@@ -0,0 +1,59 @@
+/*
+*
+* 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.
+*
+*/
+using System;
+namespace org.apache.qpid.transport
+{
+
+
+ /// <summary> ProtocolVersionException
+ ///
+ /// </summary>
+
+ [Serializable]
+ public sealed class ProtocolVersionException:TransportException
+ {
+ public sbyte Major
+ {
+ get
+ {
+ return _major;
+ }
+
+ }
+ public sbyte Minor
+ {
+ get
+ {
+ return _minor;
+ }
+
+ }
+
+ private sbyte _major;
+ private sbyte _minor;
+
+ public ProtocolVersionException(sbyte major, sbyte minor):base(String.Format("version missmatch: %{0}-{1}", major, minor))
+ {
+ this._major = major;
+ this._minor = minor;
+ }
+ }
+}
diff --git a/qpid/dotnet/client-010/client/transport/exception/SessionClosedException.cs b/qpid/dotnet/client-010/client/transport/exception/SessionClosedException.cs
new file mode 100644
index 0000000000..89453433ee
--- /dev/null
+++ b/qpid/dotnet/client-010/client/transport/exception/SessionClosedException.cs
@@ -0,0 +1,38 @@
+/*
+*
+* 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.
+*
+*/
+using System.Collections.Generic;
+
+namespace org.apache.qpid.transport
+{
+
+
+ /// <summary>
+ /// SessionClosedException
+ /// </summary>
+
+ public class SessionClosedException : SessionException
+ {
+
+ public SessionClosedException(): base(new List<ExecutionException>())
+ {
+ }
+ }
+} \ No newline at end of file
diff --git a/qpid/dotnet/client-010/client/transport/exception/SessionException.cs b/qpid/dotnet/client-010/client/transport/exception/SessionException.cs
new file mode 100644
index 0000000000..f02ffa5c2f
--- /dev/null
+++ b/qpid/dotnet/client-010/client/transport/exception/SessionException.cs
@@ -0,0 +1,45 @@
+/*
+*
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing,
+* software distributed under the License is distributed on an
+* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+* KIND, either express or implied. See the License for the
+* specific language governing permissions and limitations
+* under the License.
+*
+*/
+using System;
+using System.Collections.Generic;
+
+namespace org.apache.qpid.transport
+{
+ /// <summary>
+ /// SessionException
+ /// </summary>
+ public class SessionException : Exception
+ {
+ private readonly List<ExecutionException> _exceptions;
+
+ public SessionException(List<ExecutionException> exceptions)
+ : base(exceptions.Count == 0 ? "" : exceptions.ToString())
+
+ {
+ _exceptions = exceptions;
+ }
+
+ public List<ExecutionException> Exceptions
+ {
+ get { return _exceptions; }
+ }
+ }
+} \ No newline at end of file
diff --git a/qpid/dotnet/client-010/client/transport/exception/TransportException.cs b/qpid/dotnet/client-010/client/transport/exception/TransportException.cs
new file mode 100644
index 0000000000..d016f90a83
--- /dev/null
+++ b/qpid/dotnet/client-010/client/transport/exception/TransportException.cs
@@ -0,0 +1,46 @@
+/*
+*
+* 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.
+*
+*/
+using System;
+namespace org.apache.qpid.transport
+{
+
+
+ /// <summary>
+ /// TransportException
+ /// </summary>
+
+
+ public class TransportException : Exception
+ {
+ public TransportException(String msg) : base(msg)
+ {
+ }
+
+ public TransportException(String msg, Exception cause) : base(msg, cause)
+ {
+ }
+
+ public TransportException(Exception cause): base("Transport Exception", cause)
+ {
+ }
+
+ }
+} \ No newline at end of file
diff --git a/qpid/dotnet/client-010/client/transport/network/Assembler.cs b/qpid/dotnet/client-010/client/transport/network/Assembler.cs
new file mode 100644
index 0000000000..ff85f11c2f
--- /dev/null
+++ b/qpid/dotnet/client-010/client/transport/network/Assembler.cs
@@ -0,0 +1,254 @@
+/*
+*
+* 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.
+*
+*/
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using org.apache.qpid.transport.codec;
+using org.apache.qpid.transport.util;
+
+namespace org.apache.qpid.transport.network
+{
+ /// <summary>
+ /// Assembler
+ /// </summary>
+ public delegate void Processor(INetworkDelegate ndelegate);
+
+ public class Assembler : INetworkDelegate, IReceiver<ReceivedPayload<IProtocolEvent>>
+ {
+ private static readonly Logger log = Logger.Get(typeof (Assembler));
+ private readonly Dictionary<int, List<byte[]>> segments;
+ private readonly Method[] incomplete;
+ [ThreadStatic] static MSDecoder _decoder;
+ private readonly Object m_objectLock = new object();
+
+ // the event raised when a buffer is read from the wire
+ public event EventHandler<ReceivedPayload<IProtocolEvent>> ReceivedEvent;
+ public event EventHandler Closed;
+
+
+ // Not in use :
+ public event EventHandler<ExceptionArgs> Exception;
+
+ event EventHandler<ReceivedPayload<IProtocolEvent>> IReceiver<ReceivedPayload<IProtocolEvent>>.Received
+ {
+ add
+ {
+ lock (m_objectLock)
+ {
+ ReceivedEvent += value;
+ }
+ }
+ remove
+ {
+ lock (m_objectLock)
+ {
+ ReceivedEvent -= value;
+ }
+ }
+ }
+
+ public Assembler()
+ {
+ segments = new Dictionary<int, List<byte[]>>();
+ incomplete = new Method[64*1024];
+ }
+
+ // Invoked when a network event is received
+ public void On_ReceivedEvent(object sender, ReceivedPayload<INetworkEvent> payload)
+ {
+ payload.Payload.ProcessNetworkEvent(this);
+ }
+
+ #region Interface INetworkDelegate
+
+ public void Init(ProtocolHeader header)
+ {
+ Emit(0, header);
+ }
+
+ public void Error(ProtocolError error)
+ {
+ Emit(0, error);
+ }
+
+ public void Frame(Frame frame)
+ {
+ MemoryStream segment;
+ if (frame.IsFirstFrame() && frame.IsLastFrame())
+ {
+ byte[] tmp = new byte[frame.BodySize];
+ frame.Body.Read(tmp, 0, tmp.Length);
+ segment = new MemoryStream();
+ BinaryWriter w = new BinaryWriter(segment);
+ w.Write(tmp);
+ Assemble(frame, new MemoryStream(tmp));
+ }
+ else
+ {
+ List<byte[]> frames;
+ if (frame.IsFirstFrame())
+ {
+ frames = new List<byte[]>();
+ SetSegment(frame, frames);
+ }
+ else
+ {
+ frames = GetSegment(frame);
+ }
+ byte[] tmp = new byte[frame.BodySize];
+ frame.Body.Read(tmp, 0, tmp.Length);
+ frames.Add(tmp);
+
+ if (frame.IsLastFrame())
+ {
+ ClearSegment(frame);
+ segment = new MemoryStream();
+ BinaryWriter w = new BinaryWriter(segment);
+ foreach (byte[] f in frames)
+ {
+ w.Write(f);
+ }
+ Assemble(frame, segment);
+ }
+ }
+ }
+
+ #endregion
+
+ #region Private Support Functions
+
+
+ private MSDecoder GetDecoder()
+ {
+ if( _decoder == null )
+ {
+ _decoder = new MSDecoder();
+ }
+ return _decoder;
+ }
+
+ private void Assemble(Frame frame, MemoryStream segment)
+ {
+ MSDecoder decoder = GetDecoder();
+ decoder.Init(segment);
+ int channel = frame.Channel;
+ Method command;
+ switch (frame.Type)
+ {
+ case SegmentType.CONTROL:
+ int controlType = decoder.ReadUint16();
+ Method control = Method.Create(controlType);
+ control.Read(decoder);
+ Emit(channel, control);
+ break;
+ case SegmentType.COMMAND:
+ int commandType = decoder.ReadUint16();
+ // read in the session header, right now we don't use it
+ decoder.ReadUint16();
+ command = Method.Create(commandType);
+ command.Read(decoder);
+ if (command.HasPayload())
+ {
+ incomplete[channel] = command;
+ }
+ else
+ {
+ Emit(channel, command);
+ }
+ break;
+ case SegmentType.HEADER:
+ command = incomplete[channel];
+ List<Struct> structs = new List<Struct>();
+ while (decoder.HasRemaining())
+ {
+ structs.Add(decoder.ReadStruct32());
+ }
+ command.Header = new Header(structs);
+ if (frame.IsLastSegment())
+ {
+ incomplete[channel] = null;
+ Emit(channel, command);
+ }
+ break;
+ case SegmentType.BODY:
+ command = incomplete[channel];
+ segment.Seek(0, SeekOrigin.Begin);
+ command.Body = segment;
+ incomplete[channel] = null;
+ Emit(channel, command);
+ break;
+ default:
+ throw new Exception("unknown frame type: " + frame.Type);
+ }
+ }
+
+ private int SegmentKey(Frame frame)
+ {
+ return (frame.Track + 1)*frame.Channel;
+ }
+
+ private List<byte[]> GetSegment(Frame frame)
+ {
+ return segments[SegmentKey(frame)];
+ }
+
+ private void SetSegment(Frame frame, List<byte[]> segment)
+ {
+ int key = SegmentKey(frame);
+ if (segments.ContainsKey(key))
+ {
+ Error(new ProtocolError(network.Frame.L2, "segment in progress: %s",
+ frame));
+ }
+ segments.Add(SegmentKey(frame), segment);
+ }
+
+ private void ClearSegment(Frame frame)
+ {
+ segments.Remove(SegmentKey(frame));
+ }
+
+ // Emit a protocol event
+ private void Emit(int channel, IProtocolEvent protevent)
+ {
+ protevent.Channel = channel;
+ log.Debug("Assembler: protocol event:", protevent);
+ ReceivedPayload<IProtocolEvent> payload = new ReceivedPayload<IProtocolEvent>();
+ payload.Payload = protevent;
+
+ if (protevent is ConnectionCloseOk)
+ {
+ if (Closed != null)
+ Closed(this, EventArgs.Empty);
+ }
+ else
+ {
+ if (ReceivedEvent != null)
+ ReceivedEvent(this, payload);
+ else
+ log.Debug("No listener for event: {0}", protevent);
+ }
+ }
+
+ #endregion
+ }
+} \ No newline at end of file
diff --git a/qpid/dotnet/client-010/client/transport/network/Disassembler.cs b/qpid/dotnet/client-010/client/transport/network/Disassembler.cs
new file mode 100644
index 0000000000..3f0a6a8974
--- /dev/null
+++ b/qpid/dotnet/client-010/client/transport/network/Disassembler.cs
@@ -0,0 +1,222 @@
+/*
+*
+* 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.
+*
+*/
+using System;
+using System.IO;
+using org.apache.qpid.transport.codec;
+using org.apache.qpid.transport.util;
+
+namespace org.apache.qpid.transport.network
+{
+ /// <summary>
+ /// Disassembler
+ /// </summary>
+ public sealed class Disassembler : ISender<IProtocolEvent>, IProtocolDelegate<Object>
+ {
+ private readonly IIoSender<MemoryStream> _sender;
+ private readonly int _maxPayload;
+ private readonly MemoryStream _header;
+ private readonly BinaryWriter _writer;
+ private readonly Object _sendlock = new Object();
+ [ThreadStatic] static MSEncoder _encoder;
+
+
+ public Disassembler(IIoSender<MemoryStream> sender, int maxFrame)
+ {
+ if (maxFrame <= network.Frame.HEADER_SIZE || maxFrame >= 64*1024)
+ {
+ throw new Exception(String.Format("maxFrame must be > {0} and < 64K: ", network.Frame.HEADER_SIZE) + maxFrame);
+ }
+ _sender = sender;
+ _maxPayload = maxFrame - network.Frame.HEADER_SIZE;
+ _header = new MemoryStream(network.Frame.HEADER_SIZE);
+ _writer = new BinaryWriter(_header);
+ }
+
+ #region Sender Interface
+
+ public void Send(IProtocolEvent pevent)
+ {
+ pevent.ProcessProtocolEvent(null, this);
+ }
+
+ public void Flush()
+ {
+ lock (_sendlock)
+ {
+ _sender.Flush();
+ }
+ }
+
+ public void Close()
+ {
+ lock (_sendlock)
+ {
+ _sender.Close();
+ }
+ }
+
+ #endregion
+
+ #region ProtocolDelegate<Object> Interface
+
+ public void Init(Object v, ProtocolHeader header)
+ {
+ lock (_sendlock)
+ {
+ _sender.Send(header.ToMemoryStream());
+ _sender.Flush();
+ }
+ }
+
+ public void Control(Object v, Method method)
+ {
+ InvokeMethod(method, SegmentType.CONTROL);
+ }
+
+ public void Command(Object v, Method method)
+ {
+ InvokeMethod(method, SegmentType.COMMAND);
+ }
+
+ public void Error(Object v, ProtocolError error)
+ {
+ throw new Exception("Error: " + error);
+ }
+
+ #endregion
+
+ #region private
+
+ private void Frame(byte flags, byte type, byte track, int channel, int size, MemoryStream buf)
+ {
+ lock (_sendlock)
+ {
+ _writer.Write(flags);
+ _writer.Write(type);
+ _writer.Write(ByteEncoder.GetBigEndian((UInt16)(size + network.Frame.HEADER_SIZE)));
+ _writer.Write((byte)0);
+ _writer.Write(track);
+ _writer.Write(ByteEncoder.GetBigEndian((UInt16)( channel)));
+ _writer.Write((byte)0);
+ _writer.Write((byte)0);
+ _writer.Write((byte)0);
+ _writer.Write((byte)0);
+ _sender.Send(_header);
+ _header.Seek(0, SeekOrigin.Begin);
+ _sender.Send(buf, size);
+ }
+ }
+
+ private void Fragment(byte flags, SegmentType type, IProtocolEvent mevent, MemoryStream buf)
+ {
+ byte typeb = (byte) type;
+ byte track = mevent.EncodedTrack == network.Frame.L4 ? (byte) 1 : (byte) 0;
+ int remaining = (int) buf.Length;
+ buf.Seek(0, SeekOrigin.Begin);
+ bool first = true;
+ while (true)
+ {
+ int size = Math.Min(_maxPayload, remaining);
+ remaining -= size;
+
+ byte newflags = flags;
+ if (first)
+ {
+ newflags |= network.Frame.FIRST_FRAME;
+ first = false;
+ }
+ if (remaining == 0)
+ {
+ newflags |= network.Frame.LAST_FRAME;
+ }
+
+ Frame(newflags, typeb, track, mevent.Channel, size, buf);
+
+ if (remaining == 0)
+ {
+ break;
+ }
+ }
+ }
+
+ private MSEncoder GetEncoder()
+ {
+ if( _encoder == null)
+ {
+ _encoder = new MSEncoder(4 * 1024);
+ }
+ return _encoder;
+ }
+
+ private void InvokeMethod(Method method, SegmentType type)
+ {
+ MSEncoder encoder = GetEncoder();
+ encoder.Init();
+ encoder.WriteUint16(method.GetEncodedType());
+ if (type == SegmentType.COMMAND)
+ {
+ if (method.Sync)
+ {
+ encoder.WriteUint16(0x0101);
+ }
+ else
+ {
+ encoder.WriteUint16(0x0100);
+ }
+ }
+ method.Write(_encoder);
+ MemoryStream methodSeg = encoder.Segment();
+
+ byte flags = network.Frame.FIRST_SEG;
+
+ bool payload = method.HasPayload();
+ if (!payload)
+ {
+ flags |= network.Frame.LAST_SEG;
+ }
+
+ MemoryStream headerSeg = null;
+ if (payload)
+ {
+ Header hdr = method.Header;
+ Struct[] structs = hdr.Structs;
+
+ foreach (Struct st in structs)
+ {
+ encoder.WriteStruct32(st);
+ }
+ headerSeg = encoder.Segment();
+ }
+
+ lock (_sendlock)
+ {
+ Fragment(flags, type, method, methodSeg);
+ if (payload)
+ {
+ Fragment( 0x0, SegmentType.HEADER, method, headerSeg);
+ Fragment(network.Frame.LAST_SEG, SegmentType.BODY, method, method.Body);
+ }
+ }
+ }
+
+ #endregion
+ }
+}
diff --git a/qpid/dotnet/client-010/client/transport/network/Frame.cs b/qpid/dotnet/client-010/client/transport/network/Frame.cs
new file mode 100644
index 0000000000..b8ec36d8b6
--- /dev/null
+++ b/qpid/dotnet/client-010/client/transport/network/Frame.cs
@@ -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.
+*
+*/
+using System;
+using System.IO;
+
+namespace org.apache.qpid.transport.network
+{
+ public sealed class Frame : INetworkEvent
+ {
+ internal static int HEADER_SIZE = 12;
+
+ // XXX: enums?
+ public const byte L1 = 0;
+ public const byte L2 = 1;
+ public const byte L3 = 2;
+ public const byte L4 = 3;
+
+ public static byte RESERVED = 0x0;
+
+ public static byte VERSION = 0x0;
+
+ public static byte FIRST_SEG = 0x8;
+ public static byte LAST_SEG = 0x4;
+ public static byte FIRST_FRAME = 0x2;
+ public static byte LAST_FRAME = 0x1;
+
+ private readonly byte flags;
+ private readonly SegmentType type;
+ private readonly byte track;
+ private readonly int channel;
+ private readonly MemoryStream body;
+ private int _bodySize;
+
+
+ public Frame(byte flags, SegmentType type, byte track, int channel, int bodySize,
+ MemoryStream body)
+ {
+ this.flags = flags;
+ this.type = type;
+ this.track = track;
+ this.channel = channel;
+ this.body = body;
+ _bodySize = bodySize;
+ }
+
+ public int BodySize
+ {
+ get { return _bodySize; }
+ }
+
+ public MemoryStream Body
+ {
+ get { return body; }
+ }
+
+ public byte Flags
+ {
+ get { return flags; }
+ }
+
+ public int Channel
+ {
+ get { return channel; }
+ }
+
+ public int Size
+ {
+ get { return (int) body.Length;}
+ }
+
+ public SegmentType Type
+ {
+ get { return type; }
+ }
+
+ public byte Track
+ {
+ get { return track; }
+ }
+
+ private bool Flag(byte mask)
+ {
+ return (flags & mask) != 0;
+ }
+
+ public bool IsFirstSegment()
+ {
+ return Flag(FIRST_SEG);
+ }
+
+ public bool IsLastSegment()
+ {
+ return Flag(LAST_SEG);
+ }
+
+ public bool IsFirstFrame()
+ {
+ return Flag(FIRST_FRAME);
+ }
+
+ public bool IsLastFrame()
+ {
+ return Flag(LAST_FRAME);
+ }
+
+ #region INetworkEvent Methods
+
+ public void ProcessNetworkEvent(INetworkDelegate ndelegate)
+ {
+ ndelegate.Frame(this);
+ }
+
+ #endregion
+
+ public override String ToString()
+ {
+ return String.Format
+ ("[{0:d} {1:d} {2:d} {3} {4}{5}{6}{7}] ", Channel, Size, Track, Type,
+ IsFirstSegment() ? 1 : 0, IsLastSegment() ? 1 : 0,
+ IsFirstFrame() ? 1 : 0, IsLastFrame() ? 1 : 0);
+ }
+
+
+ }
+}
diff --git a/qpid/dotnet/client-010/client/transport/network/IIoSender.cs b/qpid/dotnet/client-010/client/transport/network/IIoSender.cs
new file mode 100644
index 0000000000..747b5b9f98
--- /dev/null
+++ b/qpid/dotnet/client-010/client/transport/network/IIoSender.cs
@@ -0,0 +1,28 @@
+/*
+*
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing,
+* software distributed under the License is distributed on an
+* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+* KIND, either express or implied. See the License for the
+* specific language governing permissions and limitations
+* under the License.
+*
+*/
+
+namespace org.apache.qpid.transport.network
+{
+ public interface IIOSender<T>:Sender<T>
+ {
+ void send(T body, int siz);
+ }
+}
diff --git a/qpid/dotnet/client-010/client/transport/network/INetworkDelegate.cs b/qpid/dotnet/client-010/client/transport/network/INetworkDelegate.cs
new file mode 100644
index 0000000000..9226adc2b7
--- /dev/null
+++ b/qpid/dotnet/client-010/client/transport/network/INetworkDelegate.cs
@@ -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.
+*
+*/
+using ProtocolError = org.apache.qpid.transport.ProtocolError;
+using ProtocolHeader = org.apache.qpid.transport.ProtocolHeader;
+namespace org.apache.qpid.transport.network
+{
+
+
+ /// <summary>
+ /// NetworkDelegate
+ /// </summary>
+
+ public interface INetworkDelegate
+ {
+
+ void Init(ProtocolHeader header);
+
+ void Frame(Frame frame);
+
+ void Error(ProtocolError error);
+ }
+}
diff --git a/qpid/dotnet/client-010/client/transport/network/INetworkEvent.cs b/qpid/dotnet/client-010/client/transport/network/INetworkEvent.cs
new file mode 100644
index 0000000000..e6f0d6fc8a
--- /dev/null
+++ b/qpid/dotnet/client-010/client/transport/network/INetworkEvent.cs
@@ -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.
+*
+*/
+namespace org.apache.qpid.transport.network
+{
+
+ /// <summary>
+ /// INetworkEvent
+ /// </summary>
+
+ public interface INetworkEvent
+ {
+ void ProcessNetworkEvent(INetworkDelegate networkDelegate);
+ }
+}
diff --git a/qpid/dotnet/client-010/client/transport/network/InputHandler.cs b/qpid/dotnet/client-010/client/transport/network/InputHandler.cs
new file mode 100644
index 0000000000..c5d5f13727
--- /dev/null
+++ b/qpid/dotnet/client-010/client/transport/network/InputHandler.cs
@@ -0,0 +1,266 @@
+/*
+*
+* 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.
+*
+*/
+using System;
+using System.IO;
+using System.Text;
+using org.apache.qpid.transport.util;
+
+namespace org.apache.qpid.transport.network
+{
+ /// <summary>
+ /// InputHandler
+ /// </summary>
+ public sealed class InputHandler : IReceiver<ReceivedPayload<INetworkEvent>>
+ {
+ public enum State
+ {
+ PROTO_HDR,
+ FRAME_HDR,
+ FRAME_BODY,
+ ERROR
+ }
+
+ private static readonly Logger log = Logger.Get(typeof(InputHandler));
+ private readonly Object m_objectLock = new object();
+
+ // the event raised when a buffer is read from the wire
+ public event EventHandler<ReceivedPayload<INetworkEvent>> ReceivedEvent;
+ public event EventHandler<ExceptionArgs> ExceptionProcessing;
+
+ // Not in used... This even is never raised in the code => the application will block on Close() until the timeout is reached
+ public event EventHandler Closed;
+
+ event EventHandler<ReceivedPayload<INetworkEvent>> IReceiver<ReceivedPayload<INetworkEvent>>.Received
+ {
+ add
+ {
+ lock (m_objectLock)
+ {
+ ReceivedEvent += value;
+ }
+ }
+ remove
+ {
+ lock (m_objectLock)
+ {
+ ReceivedEvent -= value;
+ }
+ }
+ }
+
+ event EventHandler<ExceptionArgs> IReceiver<ReceivedPayload<INetworkEvent>>.Exception
+ {
+ add
+ {
+ lock (m_objectLock)
+ {
+ ExceptionProcessing += value;
+ }
+ }
+ remove
+ {
+ lock (m_objectLock)
+ {
+ ExceptionProcessing -= value;
+ }
+ }
+ }
+
+ private State state;
+ private MemoryStream input;
+ private int needed;
+
+ private byte flags;
+ private SegmentType type;
+ private byte track;
+ private int channel;
+
+ public InputHandler(State state)
+ {
+ this.state = state;
+ switch (state)
+ {
+ case State.PROTO_HDR:
+ needed = 8;
+ break;
+ case State.FRAME_HDR:
+ needed = Frame.HEADER_SIZE;
+ break;
+ }
+ }
+
+ // The command listening for a buffer read.
+ public void On_ReceivedBuffer(object sender, ReceivedPayload<MemoryStream> payload)
+ {
+ MemoryStream buf = payload.Payload;
+ int remaining = (int) buf.Length;
+ if( input != null )
+ {
+ remaining += (int) input.Length;
+ }
+ try
+ {
+ while (remaining > 0)
+ {
+ if (remaining >= needed)
+ {
+ if (input != null)
+ {
+ byte[] tmp = new byte[buf.Length];
+ buf.Read(tmp, 0, tmp.Length);
+ input.Write(tmp, 0, tmp.Length);
+ input.Seek(0, SeekOrigin.Begin);
+ buf = input;
+ }
+ int startPos = (int)buf.Position;
+ int consumed = needed;
+ state = Next(buf);
+ if ((buf.Position - startPos) < consumed)
+ {
+ buf.Seek(consumed - (buf.Position - startPos), SeekOrigin.Current);
+ }
+ remaining -= consumed;
+ input = null;
+ }
+ else
+ {
+ byte[] tmp;
+ if (input == null)
+ {
+ input = new MemoryStream();
+ tmp = new byte[remaining];
+ }
+ else
+ {
+ // this is a full buffer
+ tmp = new byte[buf.Length];
+ }
+ buf.Read(tmp, 0, tmp.Length);
+ input.Write(tmp, 0, tmp.Length);
+ remaining = 0;
+ }
+ }
+ }
+ catch (Exception t)
+ {
+ Console.Write(t);
+ if (ExceptionProcessing != null)
+ {
+ ExceptionProcessing(this, new ExceptionArgs(t));
+ }
+ }
+ }
+
+ #region Private Support Functions
+
+ private State Next(MemoryStream buf)
+ {
+ BinaryReader reader = new BinaryReader(buf);
+
+ switch (state)
+ {
+ case State.PROTO_HDR:
+ char a = reader.ReadChar();
+ char m = reader.ReadChar();
+ char q = reader.ReadChar();
+ char p = reader.ReadChar();
+ if (a != 'A' &&
+ m != 'M' &&
+ q != 'Q' &&
+ p != 'P')
+ {
+ Error("bad protocol header: {0}", buf.ToString());
+ return State.ERROR;
+ }
+ reader.ReadByte();
+ byte instance = reader.ReadByte();
+ byte major = reader.ReadByte();
+ byte minor = reader.ReadByte();
+ Fire_NetworkEvent(new ProtocolHeader(instance, major, minor));
+ needed = Frame.HEADER_SIZE;
+ return State.FRAME_HDR;
+ case State.FRAME_HDR:
+ reader = new BinaryReader(buf, Encoding.BigEndianUnicode);
+ flags = reader.ReadByte();
+ type = SegmentTypeGetter.Get(reader.ReadByte()); // generated code
+ int size = reader.ReadUInt16();
+ size = ByteEncoder.GetBigEndian((UInt16)size);
+ size -= Frame.HEADER_SIZE;
+ if (size < 0 || size > (64 * 1024 - 12))
+ {
+ Error("bad frame size: {0:d}", size);
+ return State.ERROR;
+ }
+ reader.ReadByte();
+ byte b = reader.ReadByte();
+ if ((b & 0xF0) != 0)
+ {
+ Error("non-zero reserved bits in upper nibble of " +
+ "frame header byte 5: {0}", b);
+ return State.ERROR;
+ }
+ track = (byte)(b & 0xF);
+ channel = reader.ReadUInt16();
+ channel = ByteEncoder.GetBigEndian((UInt16)channel);
+ if (size == 0)
+ {
+ Fire_NetworkEvent(new Frame(flags, type, track, channel, 0, new MemoryStream()));
+ needed = Frame.HEADER_SIZE;
+ return State.FRAME_HDR;
+ }
+ needed = size;
+ return State.FRAME_BODY;
+ case State.FRAME_BODY:
+ Fire_NetworkEvent(new Frame(flags, type, track, channel, needed, buf));
+ needed = Frame.HEADER_SIZE;
+ return State.FRAME_HDR;
+ default:
+ if (ExceptionProcessing != null)
+ {
+ ExceptionProcessing(this, new ExceptionArgs(new Exception("Error creating frame")));
+ }
+ throw new Exception("Error creating frame");
+ }
+ }
+
+ private void Error(String fmt, params Object[] args)
+ {
+ Fire_NetworkEvent(new ProtocolError(Frame.L1, fmt, args));
+ }
+
+ private void Fire_NetworkEvent(INetworkEvent netevent)
+ {
+ log.Debug("InputHandler: network event:", netevent);
+ ReceivedPayload<INetworkEvent> payload = new ReceivedPayload<INetworkEvent>();
+ payload.Payload = netevent;
+ if (ReceivedEvent != null)
+ {
+ ReceivedEvent(this, payload);
+ }
+ else
+ {
+ log.Debug("Nobody listening for event: {0}");
+ }
+ }
+
+ #endregion
+ }
+} \ No newline at end of file
diff --git a/qpid/dotnet/client-010/client/transport/network/NetworkDelegate.cs b/qpid/dotnet/client-010/client/transport/network/NetworkDelegate.cs
new file mode 100644
index 0000000000..69598a43e8
--- /dev/null
+++ b/qpid/dotnet/client-010/client/transport/network/NetworkDelegate.cs
@@ -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.
+*
+*/
+using ProtocolError = org.apache.qpid.transport.ProtocolError;
+using ProtocolHeader = org.apache.qpid.transport.ProtocolHeader;
+namespace org.apache.qpid.transport.network
+{
+
+
+ /// <summary>
+ /// NetworkDelegate
+ /// </summary>
+
+ public interface NetworkDelegate
+ {
+
+ void Init(ProtocolHeader header);
+
+ void Frame(Frame frame);
+
+ void Error(ProtocolError error);
+ }
+} \ No newline at end of file
diff --git a/qpid/dotnet/client-010/client/transport/network/NetworkEvent.cs b/qpid/dotnet/client-010/client/transport/network/NetworkEvent.cs
new file mode 100644
index 0000000000..e5ac6de93a
--- /dev/null
+++ b/qpid/dotnet/client-010/client/transport/network/NetworkEvent.cs
@@ -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.
+*
+*/
+namespace org.apache.qpid.transport.network
+{
+
+ /// <summary>
+ /// NetworkEvent
+ /// </summary>
+
+ public interface NetworkEvent
+ {
+ void ProcessNetworkEvent(NetworkDelegate networkDelegate);
+ }
+} \ No newline at end of file
diff --git a/qpid/dotnet/client-010/client/transport/network/io/IIoSender.cs b/qpid/dotnet/client-010/client/transport/network/io/IIoSender.cs
new file mode 100644
index 0000000000..acc7724a06
--- /dev/null
+++ b/qpid/dotnet/client-010/client/transport/network/io/IIoSender.cs
@@ -0,0 +1,28 @@
+/*
+*
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing,
+* software distributed under the License is distributed on an
+* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+* KIND, either express or implied. See the License for the
+* specific language governing permissions and limitations
+* under the License.
+*
+*/
+
+namespace org.apache.qpid.transport.network
+{
+ public interface IIoSender<T>:ISender<T>
+ {
+ void Send(T body, int siz);
+ }
+}
diff --git a/qpid/dotnet/client-010/client/transport/network/io/IIoTransport.cs b/qpid/dotnet/client-010/client/transport/network/io/IIoTransport.cs
new file mode 100644
index 0000000000..41a09e7079
--- /dev/null
+++ b/qpid/dotnet/client-010/client/transport/network/io/IIoTransport.cs
@@ -0,0 +1,57 @@
+/*
+* 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.
+*/
+using System.IO;
+using System.Net.Sockets;
+
+namespace org.apache.qpid.transport.network.io
+{
+ public interface IIoTransport
+ {
+ Connection Connection
+ {
+ get;
+ set;
+ }
+
+ IReceiver<ReceivedPayload<MemoryStream>> Receiver
+ {
+ get;
+ set;
+ }
+
+ IoSender Sender
+ {
+ get;
+ set;
+ }
+
+
+ Stream Stream
+ {
+ get;
+ set;
+ }
+
+ TcpClient Socket
+ {
+ get;
+ set;
+ }
+ }
+}
diff --git a/qpid/dotnet/client-010/client/transport/network/io/IoReceiver.cs b/qpid/dotnet/client-010/client/transport/network/io/IoReceiver.cs
new file mode 100644
index 0000000000..b60444fa29
--- /dev/null
+++ b/qpid/dotnet/client-010/client/transport/network/io/IoReceiver.cs
@@ -0,0 +1,185 @@
+/*
+*
+* 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.
+*
+*/
+using System;
+using System.IO;
+using System.Threading;
+using Logger = org.apache.qpid.transport.util.Logger;
+
+
+namespace org.apache.qpid.transport.network.io
+{
+ /// <summary>
+ /// IoReceiver
+ /// </summary>
+ public sealed class IoReceiver : IReceiver<ReceivedPayload<MemoryStream>>
+ {
+ private static readonly Logger log = Logger.Get(typeof(IoReceiver));
+ private readonly int m_bufferSize;
+ private readonly Stream m_bufStream;
+ private readonly int m_timeout;
+ private readonly Thread m_thread;
+ private bool m_closed;
+ private readonly Object m_objectLock = new object();
+
+ // the event raised when a buffer is read from the wire
+ event EventHandler<ReceivedPayload<MemoryStream>> ReceivedBuffer;
+ event EventHandler<ExceptionArgs> ExceptionReading;
+ event EventHandler ReceiverClosed;
+
+ event EventHandler<ReceivedPayload<MemoryStream>> IReceiver<ReceivedPayload<MemoryStream>>.Received
+ {
+ add
+ {
+ lock (m_objectLock)
+ {
+ ReceivedBuffer += value;
+ }
+ }
+ remove
+ {
+ lock (m_objectLock)
+ {
+ ReceivedBuffer -= value;
+ }
+ }
+ }
+
+ event EventHandler<ExceptionArgs> IReceiver<ReceivedPayload<MemoryStream>>.Exception
+ {
+ add
+ {
+ lock (m_objectLock)
+ {
+ ExceptionReading += value;
+ }
+ }
+ remove
+ {
+ lock (m_objectLock)
+ {
+ ExceptionReading -= value;
+ }
+ }
+ }
+
+ event EventHandler IReceiver<ReceivedPayload<MemoryStream>>.Closed
+ {
+ add
+ {
+ lock (m_objectLock)
+ {
+ ReceiverClosed += value;
+ }
+ }
+ remove
+ {
+ lock (m_objectLock)
+ {
+ ReceiverClosed -= value;
+ }
+ }
+ }
+
+ public IoReceiver(Stream stream, int bufferSize, int timeout)
+ {
+ m_bufferSize = bufferSize;
+ m_bufStream = stream;
+ m_timeout = timeout;
+ m_thread = new Thread(Go);
+ m_thread.Name = String.Format("IoReceiver - {0}", stream);
+ m_thread.IsBackground = true;
+ m_thread.Start();
+ }
+
+ public void Close()
+ {
+ Mutex mut = new Mutex();
+ mut.WaitOne();
+ if (!m_closed)
+ {
+ m_closed = true;
+ try
+ {
+ log.Debug("Receiver closing");
+ m_bufStream.Close();
+ m_thread.Join(m_timeout);
+ if (m_thread.IsAlive)
+ {
+ throw new TransportException("join timed out");
+ }
+ }
+ catch (ThreadInterruptedException e)
+ {
+ throw new TransportException(e);
+ }
+ catch (IOException e)
+ {
+ throw new TransportException(e);
+ }
+ }
+ mut.ReleaseMutex();
+ }
+
+ void Go()
+ {
+ // create a BufferedStream on top of the NetworkStream.
+ int threshold = m_bufferSize/2;
+ byte[] buffer = new byte[m_bufferSize];
+ try
+ {
+ int read;
+ int offset = 0;
+ ReceivedPayload<MemoryStream> payload = new ReceivedPayload<MemoryStream>();
+ while ((read = m_bufStream.Read(buffer, offset, m_bufferSize - offset)) > 0)
+ {
+ MemoryStream memStream = new MemoryStream(buffer, offset, read);
+ if (ReceivedBuffer != null)
+ {
+ // call the event
+ payload.Payload = memStream;
+ ReceivedBuffer(this, payload);
+ }
+ offset += read;
+ if (offset > threshold)
+ {
+ offset = 0;
+ buffer = new byte[m_bufferSize];
+ }
+ }
+ log.Debug("Receiver thread terminating");
+ }
+ catch (Exception t)
+ {
+ if (ExceptionReading != null)
+ {
+ ExceptionReading(this, new ExceptionArgs(t));
+ }
+ }
+ finally
+ {
+ if (ReceiverClosed != null)
+ {
+ ReceiverClosed(this, new EventArgs());
+ }
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/qpid/dotnet/client-010/client/transport/network/io/IoSSLTransport.cs b/qpid/dotnet/client-010/client/transport/network/io/IoSSLTransport.cs
new file mode 100644
index 0000000000..b6c7940a1d
--- /dev/null
+++ b/qpid/dotnet/client-010/client/transport/network/io/IoSSLTransport.cs
@@ -0,0 +1,227 @@
+/*
+* 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.
+*/
+using System;
+using System.IO;
+using System.Net.Security;
+using System.Net.Sockets;
+using System.Security.Authentication;
+using System.Security.Cryptography.X509Certificates;
+using System.Threading;
+
+using org.apache.qpid.transport.util;
+using org.apache.qpid.client;
+
+namespace org.apache.qpid.transport.network.io
+{
+ public sealed class IoSSLTransport : IIoTransport
+ {
+ // constants
+ private const int DEFAULT_READ_WRITE_BUFFER_SIZE = 64*1024;
+ private const int TIMEOUT = 60000;
+ private const int QUEUE_SIZE = 1000;
+ // props
+ private static readonly Logger log = Logger.Get(typeof (IoSSLTransport));
+ private Stream m_stream;
+ private IoSender m_sender;
+ private IReceiver<ReceivedPayload<MemoryStream>> m_receiver;
+ private TcpClient m_socket;
+ private Connection m_con;
+ private readonly bool _rejectUntrusted;
+
+ public static Connection Connect(String host, int port, String mechanism, X509Certificate certificate, bool rejectUntrusted, Client client)
+ {
+ ClientConnectionDelegate connectionDelegate = new ClientConnectionDelegate(client, string.Empty, string.Empty, mechanism);
+ ManualResetEvent negotiationComplete = new ManualResetEvent(true);
+ connectionDelegate.SetCondition(negotiationComplete);
+ connectionDelegate.VirtualHost = string.Empty;
+
+ IIoTransport transport = new IoSSLTransport(host, port, certificate, rejectUntrusted, connectionDelegate);
+
+ Connection _conn = transport.Connection;
+ _conn.Send(new ProtocolHeader(1, 0, 10));
+ negotiationComplete.WaitOne();
+
+ if (connectionDelegate.Exception != null)
+ throw connectionDelegate.Exception;
+
+ connectionDelegate.SetCondition(null);
+
+ return _conn;
+ }
+
+ public static Connection Connect(String host, int port, String virtualHost, String mechanism, string serverName, string certPath, String certPass, bool rejectUntrusted, Client client)
+ {
+ // create certificate object based on whether or not password is null
+ X509Certificate cert;
+ if (certPass != null)
+ {
+ cert = new X509Certificate2(certPath, certPass);
+ }
+ else
+ {
+ cert = X509Certificate.CreateFromCertFile(certPath);
+ }
+
+ return Connect(host, port, mechanism, cert, rejectUntrusted, client);
+ }
+
+ public IoSSLTransport(String host, int port, X509Certificate certificate, bool rejectUntrusted, ConnectionDelegate conndel)
+ {
+ _rejectUntrusted = rejectUntrusted;
+ CreateSocket(host, port);
+ CreateSSLStream(host, Socket, certificate);
+ Sender = new IoSender(this, QUEUE_SIZE, TIMEOUT);
+ Receiver = new IoReceiver(Stream, Socket.ReceiveBufferSize*2, TIMEOUT);
+ Assembler assembler = new Assembler();
+ InputHandler inputHandler = new InputHandler(InputHandler.State.PROTO_HDR);
+ Connection = new Connection(assembler, new Disassembler(Sender, 64*1024 - 1), conndel);
+ // Input handler listen to Receiver events
+ Receiver.Received += inputHandler.On_ReceivedBuffer;
+ // Assembler listen to inputhandler events
+ inputHandler.ReceivedEvent += assembler.On_ReceivedEvent;
+ // Connection listen to asembler protocol event
+ Receiver.Closed += Connection.On_ReceivedClosed;
+ assembler.Closed += Connection.On_ReceivedClosed;
+ Receiver.Exception += Connection.On_ReceivedException;
+ inputHandler.ExceptionProcessing += Connection.On_ReceivedException;
+ assembler.ReceivedEvent += Connection.On_ReceivedEvent;
+ }
+
+ public Connection Connection
+ {
+ get { return m_con; }
+ set { m_con = value; }
+ }
+
+ public IReceiver<ReceivedPayload<MemoryStream>> Receiver
+ {
+ get { return m_receiver; }
+ set { m_receiver = value; }
+ }
+
+ public IoSender Sender
+ {
+ get { return m_sender; }
+ set { m_sender = value; }
+ }
+
+
+ public Stream Stream
+ {
+ get { return m_stream; }
+ set { m_stream = value; }
+ }
+
+ public TcpClient Socket
+ {
+ get { return m_socket; }
+ set { m_socket = value; }
+ }
+
+ #region Private Support Functions
+
+ private void CreateSocket(String host, int port)
+ {
+ TcpClient socket;
+ try
+ {
+ socket = new TcpClient();
+ String noDelay = Environment.GetEnvironmentVariable("qpid.tcpNoDelay");
+ String writeBufferSize = Environment.GetEnvironmentVariable("qpid.writeBufferSize");
+ String readBufferSize = Environment.GetEnvironmentVariable("qpid.readBufferSize");
+ socket.NoDelay = noDelay != null && bool.Parse(noDelay);
+ socket.ReceiveBufferSize = readBufferSize == null
+ ? DEFAULT_READ_WRITE_BUFFER_SIZE
+ : int.Parse(readBufferSize);
+ socket.SendBufferSize = writeBufferSize == null
+ ? DEFAULT_READ_WRITE_BUFFER_SIZE
+ : int.Parse(writeBufferSize);
+
+ log.Debug("NoDelay : {0}", socket.NoDelay);
+ log.Debug("ReceiveBufferSize : {0}", socket.ReceiveBufferSize);
+ log.Debug("SendBufferSize : {0}", socket.SendBufferSize);
+ log.Debug("Openning connection with host : {0}; port: {1}", host, port);
+
+ socket.Connect(host, port);
+ Socket = socket;
+ }
+ catch (Exception e)
+ {
+ throw new TransportException(string.Format("Error connecting to broker: {0}", e.Message));
+ }
+ }
+
+ private void CreateSSLStream(String host, TcpClient socket, X509Certificate certificate)
+ {
+ try
+ {
+ //Initializes a new instance of the SslStream class using the specified Stream, stream closure behavior, certificate validation delegate and certificate selection delegate
+ SslStream sslStream = new SslStream(socket.GetStream(), false, ValidateServerCertificate, LocalCertificateSelection);
+
+ X509CertificateCollection certCol = new X509CertificateCollection();
+ certCol.Add(certificate);
+
+ sslStream.AuthenticateAsClient(host, certCol, SslProtocols.Default, true);
+ Stream = sslStream;
+ }
+ catch (AuthenticationException e)
+ {
+ log.Warn("Exception: {0}", e.Message);
+ if (e.InnerException != null)
+ {
+ log.Warn("Inner exception: {0}", e.InnerException.Message);
+ e = new AuthenticationException(e.InnerException.Message, e.InnerException);
+ }
+ socket.Close();
+ throw new TransportException(string.Format("Authentication failed, closing connection to broker: {0}", e.Message));
+ }
+ }
+
+ // The following method is invoked by the RemoteCertificateValidationDelegate.
+ public bool ValidateServerCertificate(
+ object sender,
+ X509Certificate certificate,
+ X509Chain chain,
+ SslPolicyErrors sslPolicyErrors)
+ {
+ bool result = true;
+ if (sslPolicyErrors != SslPolicyErrors.None && _rejectUntrusted )
+ {
+ log.Warn("Certificate error: {0}", sslPolicyErrors);
+ // Do not allow this client to communicate with unauthenticated servers.
+ result = false;
+ }
+ return result;
+ }
+
+ public X509Certificate LocalCertificateSelection(
+ Object sender,
+ string targetHost,
+ X509CertificateCollection localCertificates,
+ X509Certificate remoteCertificate,
+ string[] acceptableIssuers
+ )
+ {
+ // used to be return null; in the original version
+ return localCertificates[0];
+ }
+
+ #endregion
+ }
+}
diff --git a/qpid/dotnet/client-010/client/transport/network/io/IoSender.cs b/qpid/dotnet/client-010/client/transport/network/io/IoSender.cs
new file mode 100644
index 0000000000..025b782a12
--- /dev/null
+++ b/qpid/dotnet/client-010/client/transport/network/io/IoSender.cs
@@ -0,0 +1,137 @@
+/*
+* 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.
+*/
+using System;
+using System.IO;
+using System.Threading;
+using common.org.apache.qpid.transport.util;
+using org.apache.qpid.transport.util;
+
+namespace org.apache.qpid.transport.network.io
+{
+ public sealed class IoSender : IIoSender<MemoryStream>
+ {
+ private static readonly Logger log = Logger.Get(typeof (IoReceiver));
+ private readonly IIoTransport ioTransport;
+ private readonly Stream bufStream;
+ private bool closed;
+ private readonly Mutex mutClosed = new Mutex();
+ private readonly CircularBuffer<byte[]> queue;
+ private readonly Thread thread;
+ private readonly int timeout;
+ private readonly MemoryStream _tobeSent = new MemoryStream();
+ public IoSender(IIoTransport transport, int queueSize, int timeout)
+ {
+ this.timeout = timeout;
+ ioTransport = transport;
+ bufStream = transport.Stream;
+ queue = new CircularBuffer<byte[]>(queueSize);
+ thread = new Thread(Go);
+ log.Debug("Creating IoSender thread");
+ thread.Name = String.Format("IoSender - {0}", transport.Socket) ;
+ thread.IsBackground = true;
+ thread.Start();
+ }
+
+ public void Send(MemoryStream str)
+ {
+ int pos = (int) str.Position;
+ str.Seek(0, SeekOrigin.Begin);
+ Send(str, pos);
+ }
+
+ public void Send(MemoryStream str, int size)
+ {
+ mutClosed.WaitOne();
+ if (closed)
+ {
+ throw new TransportException("sender is Closed");
+ }
+ mutClosed.ReleaseMutex();
+ byte[] buf = new byte[size];
+ str.Read(buf, 0, size);
+ _tobeSent.Write(buf, 0, size);
+ }
+
+ public void Flush()
+ {
+ int length = (int)_tobeSent.Position;
+ byte[] buf = new byte[length];
+ _tobeSent.Seek(0, SeekOrigin.Begin);
+ _tobeSent.Read(buf, 0, length);
+ queue.Enqueue(buf);
+ // bufStream.Write(buf, 0, length);
+ // _tobeSent = new MemoryStream();
+ // _writer.Write(buf, 0, length);
+ // _writer.Flush();
+ _tobeSent.Seek(0, SeekOrigin.Begin);
+ }
+
+ public void Close()
+ {
+ log.Debug("Closing Sender");
+ mutClosed.WaitOne();
+ if (!closed)
+ {
+ try
+ {
+ closed = true;
+ queue.Close();
+ thread.Join(timeout);
+ if (thread.IsAlive)
+ {
+ throw new TransportException("join timed out");
+ }
+ }
+ catch (ThreadInterruptedException e)
+ {
+ throw new TransportException(e);
+ }
+ catch (IOException e)
+ {
+ throw new TransportException(e);
+ }
+ }
+ mutClosed.ReleaseMutex();
+ }
+
+ private void Go()
+ {
+ while (! closed)
+ {
+ //MemoryStream st = queue.Dequeue();
+ byte[] st = queue.Dequeue();
+ if (st != null)
+ {
+ try
+ {
+ // int length = (int) st.Length;
+ // byte[] buf = new byte[length];
+ // st.Read(buf, 0, length);
+ bufStream.Write(st, 0, st.Length);
+ }
+ catch (Exception e)
+ {
+ closed = true;
+ ioTransport.Connection.On_ReceivedException(this, new ExceptionArgs(e));
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/qpid/dotnet/client-010/client/transport/network/io/IoTransport.cs b/qpid/dotnet/client-010/client/transport/network/io/IoTransport.cs
new file mode 100644
index 0000000000..483e5428b8
--- /dev/null
+++ b/qpid/dotnet/client-010/client/transport/network/io/IoTransport.cs
@@ -0,0 +1,141 @@
+/*
+* 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.
+*/
+using System;
+using System.IO;
+using System.Net.Sockets;
+using org.apache.qpid.transport.util;
+
+namespace org.apache.qpid.transport.network.io
+{
+ /// <summary>
+ /// This class provides a socket based transport using sync io classes.
+ ///
+ /// The following params are configurable via JVM arguments
+ /// TCP_NO_DELAY - qpid.tcpNoDelay
+ /// SO_RCVBUF - qpid.readBufferSize
+ /// SO_SNDBUF - qpid.writeBufferSize
+ /// </summary>
+ public sealed class IoTransport : IIoTransport
+ {
+ // constants
+ private const int DEFAULT_READ_WRITE_BUFFER_SIZE = 64*1024;
+ private const int TIMEOUT = 60000;
+ private const int QUEUE_SIZE = 1000;
+ // props
+ private static readonly Logger log = Logger.Get(typeof (IoTransport));
+ private Stream m_stream;
+ private IoSender m_sender;
+ private IReceiver<ReceivedPayload<MemoryStream>> m_receiver;
+ private TcpClient m_socket;
+ private Connection m_con;
+
+ public static Connection Connect(String host, int port, ConnectionDelegate conndel)
+ {
+ IoTransport transport = new IoTransport(host, port, conndel);
+ return transport.Connection;
+ }
+
+ public IoTransport(String host, int port, ConnectionDelegate conndel)
+ {
+ CreateSocket(host, port);
+ Sender = new IoSender(this, QUEUE_SIZE, TIMEOUT);
+ Receiver = new IoReceiver(Stream, Socket.ReceiveBufferSize * 2, TIMEOUT);
+ Assembler assembler = new Assembler();
+ InputHandler inputHandler = new InputHandler(InputHandler.State.PROTO_HDR);
+ Connection = new Connection(assembler, new Disassembler(Sender, 64 * 1024 - 1), conndel);
+ // Input handler listen to Receiver events
+ Receiver.Received += inputHandler.On_ReceivedBuffer;
+ // Assembler listen to inputhandler events
+ inputHandler.ReceivedEvent += assembler.On_ReceivedEvent;
+ // Connection listen to asembler protocol event
+ Receiver.Closed += Connection.On_ReceivedClosed;
+ assembler.Closed += Connection.On_ReceivedClosed;
+ Receiver.Exception += Connection.On_ReceivedException;
+ inputHandler.ExceptionProcessing += Connection.On_ReceivedException;
+ assembler.ReceivedEvent += Connection.On_ReceivedEvent;
+ }
+
+ public Connection Connection
+ {
+ get { return m_con; }
+ set { m_con = value; }
+ }
+
+ public IReceiver<ReceivedPayload<MemoryStream>> Receiver
+ {
+ get { return m_receiver; }
+ set { m_receiver = value; }
+ }
+
+ public IoSender Sender
+ {
+ get { return m_sender; }
+ set { m_sender = value; }
+ }
+
+
+ public Stream Stream
+ {
+ get { return m_stream; }
+ set { m_stream = value; }
+ }
+
+ public TcpClient Socket
+ {
+ get { return m_socket; }
+ set { m_socket = value; }
+ }
+
+ #region Private Support Functions
+
+ private void CreateSocket(String host, int port)
+ {
+ try
+ {
+ TcpClient socket = new TcpClient();
+ String noDelay = Environment.GetEnvironmentVariable("qpid.tcpNoDelay");
+ String writeBufferSize = Environment.GetEnvironmentVariable("qpid.writeBufferSize");
+ String readBufferSize = Environment.GetEnvironmentVariable("qpid.readBufferSize");
+ socket.NoDelay = noDelay != null && bool.Parse(noDelay);
+ socket.ReceiveBufferSize = readBufferSize == null ? DEFAULT_READ_WRITE_BUFFER_SIZE : int.Parse(readBufferSize);
+ socket.SendBufferSize = writeBufferSize == null ? DEFAULT_READ_WRITE_BUFFER_SIZE : int.Parse(writeBufferSize);
+
+ log.Debug("NoDelay : {0}", socket.NoDelay);
+ log.Debug("ReceiveBufferSize : {0}", socket.ReceiveBufferSize);
+ log.Debug("SendBufferSize : {0}", socket.SendBufferSize);
+ log.Debug("Openning connection with host : {0}; port: {1}", host, port);
+
+ socket.Connect(host, port);
+ Socket = socket;
+ Stream = socket.GetStream();
+ }
+ catch (SocketException e)
+ {
+ Console.WriteLine(e.StackTrace);
+ throw new TransportException("Error connecting to broker", e);
+ }
+ catch (IOException e)
+ {
+ throw new TransportException("Error connecting to broker", e);
+ }
+ }
+
+ #endregion
+ }
+} \ No newline at end of file
diff --git a/qpid/dotnet/client-010/client/transport/util/ByteEncoder.cs b/qpid/dotnet/client-010/client/transport/util/ByteEncoder.cs
new file mode 100644
index 0000000000..873ca75688
--- /dev/null
+++ b/qpid/dotnet/client-010/client/transport/util/ByteEncoder.cs
@@ -0,0 +1,218 @@
+/*
+*
+* 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.
+*
+*/
+using System;
+
+namespace org.apache.qpid.transport.util
+{
+ public static class ByteEncoder
+ {
+ #region Endian conversion helper routines
+ /// <summary>
+ /// Returns the value encoded in Big Endian (PPC, XDR) format.
+ /// </summary>
+ /// <param name="value">Value to encode.</param>
+ /// <returns>Big-endian encoded value.</returns>
+ public static Int32 GetBigEndian(Int32 value)
+ {
+ if (BitConverter.IsLittleEndian)
+ {
+ return SwapByteOrder(value);
+ }
+ return value;
+ }
+
+ /// <summary>
+ /// Returns the value encoded in Big Endian (PPC, XDR) format.
+ /// </summary>
+ /// <param name="value">Value to encode.</param>
+ /// <returns>Big-endian encoded value.</returns>
+ public static UInt16 GetBigEndian(UInt16 value)
+ {
+ if (BitConverter.IsLittleEndian)
+ {
+ return SwapByteOrder(value);
+ }
+ return value;
+ }
+
+ /// <summary>
+ /// Returns the value encoded in Big Endian (PPC, XDR) format.
+ /// </summary>
+ /// <param name="value">Value to encode.</param>
+ /// <returns>Big-endian encoded value.</returns>
+ public static UInt32 GetBigEndian(UInt32 value)
+ {
+ if (BitConverter.IsLittleEndian)
+ {
+ return SwapByteOrder(value);
+ }
+ return value;
+ }
+
+ /// <summary>
+ /// Returns the value encoded in Big Endian (PPC, XDR) format.
+ /// </summary>
+ /// <param name="value">Value to encode.</param>
+ /// <returns>Big-endian encoded value.</returns>
+ public static long GetBigEndian(long value)
+ {
+ if (BitConverter.IsLittleEndian)
+ {
+ return SwapByteOrder(value);
+ }
+ return value;
+ }
+
+ public static double GetBigEndian(double value)
+ {
+ if (BitConverter.IsLittleEndian)
+ {
+ return SwapByteOrder(value);
+ }
+ return value;
+ }
+
+ /// <summary>
+ /// Returns the value encoded in Little Endian (x86, NDR) format.
+ /// </summary>
+ /// <param name="value">Value to encode.</param>
+ /// <returns>Little-endian encoded value.</returns>
+ public static Int32 GetLittleEndian(Int32 value)
+ {
+ if (BitConverter.IsLittleEndian)
+ {
+ return value;
+ }
+ return SwapByteOrder(value);
+ }
+
+ /// <summary>
+ /// Returns the value encoded in Little Endian (x86, NDR) format.
+ /// </summary>
+ /// <param name="value">Value to encode.</param>
+ /// <returns>Little-endian encoded value.</returns>
+ public static UInt32 GetLittleEndian(UInt32 value)
+ {
+ if (BitConverter.IsLittleEndian)
+ {
+ return value;
+ }
+ return SwapByteOrder(value);
+ }
+
+ /// <summary>
+ /// Returns the value encoded in Little Endian (x86, NDR) format.
+ /// </summary>
+ /// <param name="value">Value to encode.</param>
+ /// <returns>Little-endian encoded value.</returns>
+ public static UInt16 GetLittleEndian(UInt16 value)
+ {
+ if (BitConverter.IsLittleEndian)
+ {
+ return value;
+ }
+ return SwapByteOrder(value);
+ }
+
+ /// <summary>
+ /// Returns the value encoded in Little Endian (x86, NDR) format.
+ /// </summary>
+ /// <param name="value">Value to encode.</param>
+ /// <returns>Little-endian encoded value.</returns>
+ public static long GetLittleEndian(long value)
+ {
+ if (BitConverter.IsLittleEndian)
+ {
+ return value;
+ }
+ return SwapByteOrder(value);
+ }
+
+ public static double GetLittleEndian(double value)
+ {
+ if (BitConverter.IsLittleEndian)
+ {
+ return value;
+ }
+ return SwapByteOrder(value);
+ }
+
+ /// <summary>
+ /// Swaps the Byte order of an <see cref="Int32"/>.
+ /// </summary>
+ /// <param name="value"><see cref="Int32"/> to swap the bytes of.</param>
+ /// <returns>Byte order swapped <see cref="Int32"/>.</returns>
+ private static Int32 SwapByteOrder(Int32 value)
+ {
+ Int32 swapped = (Int32)((0x000000FF) & (value >> 24)
+ | (0x0000FF00) & (value >> 8)
+ | (0x00FF0000) & (value << 8)
+ | (0xFF000000) & (value << 24));
+ return swapped;
+ }
+
+ /// <summary>
+ /// Swaps the byte order of a <see cref="UInt16"/>.
+ /// </summary>
+ /// <param name="value"><see cref="UInt16"/> to swap the bytes of.</param>
+ /// <returns>Byte order swapped <see cref="UInt16"/>.</returns>
+ private static UInt16 SwapByteOrder(UInt16 value)
+ {
+ return (UInt16)((0x00FF & (value >> 8))
+ | (0xFF00 & (value << 8)));
+ }
+
+ /// <summary>
+ /// Swaps the byte order of a <see cref="UInt32"/>.
+ /// </summary>
+ /// <param name="value"><see cref="UInt32"/> to swap the bytes of.</param>
+ /// <returns>Byte order swapped <see cref="UInt32"/>.</returns>
+ private static UInt32 SwapByteOrder(UInt32 value)
+ {
+ UInt32 swapped = ((0x000000FF) & (value >> 24)
+ | (0x0000FF00) & (value >> 8)
+ | (0x00FF0000) & (value << 8)
+ | (0xFF000000) & (value << 24));
+ return swapped;
+ }
+
+ /// <summary>
+ /// Swaps the byte order of a <see cref="Double"/> (double precision IEEE 754)
+ /// </summary>
+ /// <param name="value"><see cref="Double"/> to swap.</param>
+ /// <returns>Byte order swapped <see cref="Double"/> value.</returns>
+ private static long SwapByteOrder(long value)
+ {
+ Byte[] buffer = BitConverter.GetBytes(value);
+ Array.Reverse(buffer, 0, buffer.Length);
+ return BitConverter.ToInt64(buffer, 0);
+ }
+
+ private static double SwapByteOrder(double value)
+ {
+ Byte[] buffer = BitConverter.GetBytes(value);
+ Array.Reverse(buffer, 0, buffer.Length);
+ return BitConverter.ToDouble(buffer,0) ;
+ }
+ #endregion
+ }
+
+}
diff --git a/qpid/dotnet/client-010/client/transport/util/CircularBuffer.cs b/qpid/dotnet/client-010/client/transport/util/CircularBuffer.cs
new file mode 100644
index 0000000000..00d7b20d4c
--- /dev/null
+++ b/qpid/dotnet/client-010/client/transport/util/CircularBuffer.cs
@@ -0,0 +1,132 @@
+/*
+*
+* 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.
+*
+*/
+
+using System;
+using System.Threading;
+
+namespace common.org.apache.qpid.transport.util
+{
+ public class CircularBuffer<T>
+ {
+ private readonly T[] buffer;
+ private Int32 nrp, nwp;
+ private readonly Int32 len;
+ private Int32 countValue;
+ private readonly Int32 add;
+
+
+ /// <summary>
+ /// Constructor creates N=len element
+ /// Circular Buffer that olds MemoryStream
+ /// </summary>
+ public CircularBuffer(Int32 len)
+ {
+ buffer = new T[len];
+ this.len = len;
+ add = 1 - len;
+ nrp = 0;
+ nwp = 0;
+ countValue = 0;
+ }
+
+
+ public void Enqueue(T t)
+ {
+ lock (this)
+ {
+ if (countValue >= (len - 1))
+ {
+ // wait for room to be available
+ Monitor.Wait(this);
+ }
+ bool notifyDequeue = countValue <= 0;
+ Load(t);
+ if (notifyDequeue) //notifyDequeue)
+ {
+ Monitor.PulseAll(this);
+ }
+ }
+ }
+
+
+ public T Dequeue()
+ {
+ lock (this)
+ {
+ if (countValue <= 0)
+ {
+ Monitor.Wait(this);
+ }
+ bool notifyEnqueue = countValue >= (len - 1);
+ T temp = Get();
+ if (notifyEnqueue) //notifyEnqueue)
+ {
+ Monitor.PulseAll(this);
+ }
+ return temp;
+ }
+ }
+
+ public void Close()
+ {
+ nrp = 0;
+ nwp = 0;
+ countValue = 0;
+ Array.Clear(buffer, 0, len);
+ lock (this)
+ {
+ Monitor.PulseAll(this);
+ }
+ }
+
+ #region Private Support Functions
+
+ private void Load(T t)
+ {
+ Int32 i = nwp;
+ buffer[i] = t;
+ i += add;
+ if (i < 0) i += len;
+ nwp = i;
+ UpdateCount();
+ }
+
+ private void UpdateCount()
+ {
+ countValue = nwp - nrp;
+ if (countValue <= 0 )
+ countValue += len; // modulo buffer size
+ }
+
+ private T Get()
+ {
+ Int32 i = nrp;
+ T temp = buffer[i];
+ i += add;
+ if (i < 0) i += len;
+ nrp = i;
+ countValue--;
+ return (temp);
+ }
+
+ #endregion
+ }
+}
diff --git a/qpid/dotnet/client-010/client/transport/util/Functions.cs b/qpid/dotnet/client-010/client/transport/util/Functions.cs
new file mode 100644
index 0000000000..eee3848386
--- /dev/null
+++ b/qpid/dotnet/client-010/client/transport/util/Functions.cs
@@ -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.
+*
+*/
+
+namespace org.apache.qpid.transport.util
+{
+
+ /// <summary>
+ /// Functions
+ /// </summary>
+
+ public class Functions
+ {
+ public static sbyte Lsb(int i)
+ {
+ return (sbyte) (0xFF & i);
+ }
+
+ public static sbyte Lsb(long l)
+ {
+ return (sbyte) (0xFF & l);
+ }
+ }
+}
diff --git a/qpid/dotnet/client-010/client/transport/util/Logger.cs b/qpid/dotnet/client-010/client/transport/util/Logger.cs
new file mode 100644
index 0000000000..f889fe2aab
--- /dev/null
+++ b/qpid/dotnet/client-010/client/transport/util/Logger.cs
@@ -0,0 +1,114 @@
+/*
+*
+* 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.
+*
+*/
+using System;
+using log4net;
+
+namespace org.apache.qpid.transport.util
+{
+
+ /// <summary> Logger
+ ///
+ /// </summary>
+
+ public sealed class Logger
+ {
+ private readonly ILog log;
+
+ public static Logger Get(Type type)
+ {
+ return new Logger(LogManager.GetLogger(type));
+ }
+
+ private Logger(ILog log)
+ {
+ this.log = log;
+ }
+
+ public bool IsDebugEnabled()
+ {
+ return log.IsDebugEnabled;
+ }
+
+ public void Debug(String message, params Object[] args)
+ {
+ if (log.IsDebugEnabled)
+ {
+ log.Debug(String.Format(message, args));
+ }
+ }
+
+ public void Debug(Exception t, String message, params Object[] args)
+ {
+ if (log.IsDebugEnabled)
+ {
+ log.Debug(String.Format(message, args), t);
+ }
+ }
+
+ public void Error(String message, params Object[] args)
+ {
+ if (log.IsErrorEnabled)
+ {
+ log.Error(String.Format(message, args));
+ }
+ }
+
+ public void Error(Exception t, String message, params Object[] args)
+ {
+ if (log.IsErrorEnabled)
+ {
+ log.Error(String.Format(message, args), t);
+ }
+ }
+
+ public void Warn(String message, params Object[] args)
+ {
+ if (log.IsWarnEnabled)
+ {
+ log.Warn(String.Format(message, args));
+ }
+ }
+
+ public void Warn(Exception t, String message, params Object[] args)
+ {
+ if (log.IsWarnEnabled)
+ {
+ log.Warn(String.Format(message, args), t);
+ }
+ }
+
+ public void Info(String message, params Object[] args)
+ {
+ if (log.IsInfoEnabled)
+ {
+ log.Info(String.Format(message, args));
+ }
+ }
+
+ public void Info(Exception t, String message, params Object[] args)
+ {
+ if (log.IsInfoEnabled)
+ {
+ log.Info(String.Format(message, args), t);
+ }
+ }
+ }
+}
diff --git a/qpid/dotnet/client-010/client/transport/util/ResultFuture.cs b/qpid/dotnet/client-010/client/transport/util/ResultFuture.cs
new file mode 100644
index 0000000000..0de2b27656
--- /dev/null
+++ b/qpid/dotnet/client-010/client/transport/util/ResultFuture.cs
@@ -0,0 +1,80 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+using System;
+using System.Threading;
+using org.apache.qpid.transport;
+using org.apache.qpid.transport.util;
+
+namespace common.org.apache.qpid.transport.util
+{
+ public class ResultFuture : IFuture
+ {
+ const long _timeout = 60000;
+ private Struct _result;
+ private Session _session;
+ private static readonly Logger log = Logger.Get(typeof(ResultFuture));
+
+ public Struct Get(long timeout)
+ {
+ lock (this)
+ {
+ DateTime start = DateTime.Now;
+ long elapsed = 0;
+ while (! _session.IsClosed && timeout - elapsed > 0 && _result == null)
+ {
+ log.Debug("{0} waiting for result: {1}", _session, this );
+ Monitor.Wait(this, (int) (timeout - elapsed));
+ elapsed = (long) (DateTime.Now.Subtract(start)).TotalMilliseconds;
+ }
+ }
+ if( _session.IsClosed )
+ {
+ throw new SessionException(_session.GetExceptions());
+ }
+ return _result;
+ }
+
+ public Struct Result
+ {
+ get { return Get(_timeout); }
+ set
+ {
+ lock (this)
+ {
+ _result = value;
+ Monitor.PulseAll(this);
+ }
+ }
+ }
+
+ public Session Session
+ {
+ set { _session = value; }
+ }
+
+ public override String ToString()
+ {
+ return String.Format("Future({0})", _result);
+ }
+
+ }
+}
diff --git a/qpid/dotnet/client-010/client/transport/util/Serial.cs b/qpid/dotnet/client-010/client/transport/util/Serial.cs
new file mode 100644
index 0000000000..874097084a
--- /dev/null
+++ b/qpid/dotnet/client-010/client/transport/util/Serial.cs
@@ -0,0 +1,94 @@
+/*
+*
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing,
+* software distributed under the License is distributed on an
+* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+* KIND, either express or implied. See the License for the
+* specific language governing permissions and limitations
+* under the License.
+*
+*/
+namespace org.apache.qpid.transport.util
+{
+ /// <summary>
+ /// This class provides basic serial number comparisons as defined in
+ /// RFC 1982.
+ /// </summary>
+ public class Serial
+ {
+ ///
+ ///
+ ///Compares two numbers using serial arithmetic.
+ ///
+ /// param s1 the first serial number
+ /// param s2 the second serial number
+ ///
+ /// return a negative integer, zero, or a positive integer as the
+ /// first argument is less than, equal to, or greater than the
+ /// second
+ ///
+ public static int Compare(int s1, int s2)
+ {
+ return s1 - s2;
+ }
+
+ public static bool Lt(int s1, int s2)
+ {
+ return Compare(s1, s2) < 0;
+ }
+
+ public static bool Le(int s1, int s2)
+ {
+ return Compare(s1, s2) <= 0;
+ }
+
+ public static bool Gt(int s1, int s2)
+ {
+ return Compare(s1, s2) > 0;
+ }
+
+ public static bool Ge(int s1, int s2)
+ {
+ return Compare(s1, s2) >= 0;
+ }
+
+ public static bool Eq(int s1, int s2)
+ {
+ return s1 == s2;
+ }
+
+ public static int Min(int s1, int s2)
+ {
+ if (Lt(s1, s2))
+ {
+ return s1;
+ }
+ else
+ {
+ return s2;
+ }
+ }
+
+ public static int Max(int s1, int s2)
+ {
+ if (Gt(s1, s2))
+ {
+ return s1;
+ }
+ else
+ {
+ return s2;
+ }
+ }
+ }
+}
diff --git a/qpid/dotnet/client-010/client/transport/util/UUID.cs b/qpid/dotnet/client-010/client/transport/util/UUID.cs
new file mode 100644
index 0000000000..07a3d267a5
--- /dev/null
+++ b/qpid/dotnet/client-010/client/transport/util/UUID.cs
@@ -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.
+*
+*/
+
+using System;
+
+namespace org.apache.qpid.transport.util
+{
+ public class UUID
+ {
+ private long _mostSigBits;
+ private long _leastSigBits;
+ private static readonly Random _random = new Random();
+ private static readonly object _randomLock = new object();
+
+
+ public UUID(long mostSigBits, long leastSigBits)
+ {
+ _mostSigBits = mostSigBits;
+ _leastSigBits = leastSigBits;
+ }
+
+ public long MostSignificantBits
+ {
+ get { return _mostSigBits; }
+ set { _mostSigBits = value; }
+ }
+
+ public long LeastSignificantBits
+ {
+ get { return _leastSigBits; }
+ set { _leastSigBits = value; }
+ }
+
+ internal UUID(byte[] r)
+ {
+ MostSignificantBits = 0;
+ LeastSignificantBits = 0;
+ for (int i = 0; i < 8; i++)
+ MostSignificantBits = (MostSignificantBits << 8) | (r[i] & 0xff);
+ for (int i = 8; i < 16; i++)
+ LeastSignificantBits = (LeastSignificantBits << 8) | (r[i] & 0xff);
+ }
+
+ public static UUID RandomUuid()
+ {
+ byte[] randomBytes = new byte[16];
+ lock (_randomLock)
+ {
+ _random.NextBytes(randomBytes);
+ }
+
+ randomBytes[6] &= 0x0f;
+ randomBytes[6] |= 0x40;
+ randomBytes[8] &= 0x3f;
+ randomBytes[8] |= 0x80;
+
+ return new UUID(randomBytes);
+ }
+
+
+ public override String ToString()
+ {
+ return (Digits(_mostSigBits >> 32, 8) + "-" +
+ Digits(_mostSigBits >> 16, 4) + "-" +
+ Digits(_mostSigBits, 4) + "-" +
+ Digits(_leastSigBits >> 48, 4) + "-" +
+ Digits(_leastSigBits, 12));
+ }
+
+ private static String Digits(long val, int digits)
+ {
+ long hi = 1L << (digits * 4);
+ return Convert.ToString((hi | (val & (hi - 1))), 16);
+ }
+
+ #region equality
+ public bool Equals(UUID other)
+ {
+ if (ReferenceEquals(null, other)) return false;
+ if (ReferenceEquals(this, other)) return true;
+ return other._mostSigBits == _mostSigBits && other._leastSigBits == _leastSigBits;
+ }
+
+ public override bool Equals(object obj)
+ {
+ if (ReferenceEquals(null, obj)) return false;
+ if (ReferenceEquals(this, obj)) return true;
+ if (obj.GetType() != typeof (UUID)) return false;
+ return Equals((UUID) obj);
+ }
+
+ public override int GetHashCode()
+ {
+ unchecked
+ {
+ return (_mostSigBits.GetHashCode()*397) ^ _leastSigBits.GetHashCode();
+ }
+ }
+
+ public static bool operator ==(UUID left, UUID right)
+ {
+ return Equals(left, right);
+ }
+
+ public static bool operator !=(UUID left, UUID right)
+ {
+ return !Equals(left, right);
+ }
+ #endregion
+ }
+}
diff --git a/qpid/dotnet/client-010/default.build b/qpid/dotnet/client-010/default.build
new file mode 100644
index 0000000000..eb6ee371f7
--- /dev/null
+++ b/qpid/dotnet/client-010/default.build
@@ -0,0 +1,275 @@
+<?xml version="1.0"?>
+<!--
+
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+
+-->
+
+<project name="Qpid.NET" default="build">
+
+ <!-- Determines the formatter to use to format output of test results. -->
+ <property name="nant.formatter" value="Plain" />
+
+ <!-- Determines whether a 'debug' or 'release' build is to be done. Defaults to 'debug' -->
+ <property name="build.config" value="debug" />
+
+ <!-- Sets build properties consistently accross all assemblies in the project. -->
+ <property name="build.version.major" value="0"/>
+ <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"/>
+ <property name="build.copyright" value="Apache Software Foundation"/>
+ <property name="build.description" value="Built from svn revision number: "/>
+
+ <!-- Fileset with build files for each 'core' assembly. -->
+ <fileset id="src.builds">
+ <include name="client/default.build" />
+ <include name="management/console/default.build" />
+ <include name="demo/default.build" />
+ </fileset>
+
+ <!-- Fileset with build files for each 'core' assembly. -->
+ <fileset id="examples.builds">
+ <include name="examples/request-response/example-request-response-Client/default.build" />
+ <include name="examples/request-response/example-request-response-Server/default.build" />
+ <include name="examples/direct/example-direct-Listener/default.build" />
+ <include name="examples/direct/example-direct-producer/default.build" />
+ <include name="examples/fanout/example-fanout-Listener/default.build" />
+ <include name="examples/fanout/example-fanout-Producer/default.build" />
+ <include name="examples/pub-sub/example-pub-sub-Listener/default.build" />
+ <include name="examples/pub-sub/example-pub-sub-Publisher/default.build" />
+ </fileset>
+
+ <!-- Fileset with build files for 'integration' test assemblies. -->
+ <fileset id="tests.builds">
+ <include name="test/default.build" />
+ </fileset>
+
+ <!-- Fileset with build files for 'performence' test assemblies. -->
+ <fileset id="perftest.builds">
+ <include name="perftest/default.build" />
+ </fileset>
+
+ <!-- Prepare environment for a debug build. -->
+ <target name="debug">
+ <property name="build.debug" value="true" />
+ <property name="build.defines" value="DEBUG;TRACE"/>
+ </target>
+
+ <!-- Prepare environment for a release build. -->
+ <target name="release">
+ <property name="build.debug" value="false" />
+ <property name="build.defines" value=""/>
+ </target>
+
+ <!-- Prepare environment for build. -->
+ <target name="init">
+ <property name="base.dir" value="${project::get-base-directory()}" />
+ <property name="build.dir" value="${base.dir}/bin/${framework::get-target-framework()}/${build.config}" />
+ <call target="${build.config}" />
+ </target>
+
+ <!-- Cleans up the build output directory. -->
+ <target name="clean" depends="init">
+ <delete dir="${build.dir}" failonerror="false" />
+ </target>
+
+ <!-- Runs 'svnversion' to get the repository revision into the build property 'build.svnversion'. -->
+ <target name="svnversion" description="Runs svnversion to get the current repository version into a build script property.">
+ <exec program="svnversion" output="svnversion_tmp.txt">
+ <arg value="-n"/>
+ </exec>
+
+ <loadfile file="svnversion_tmp.txt" property="build.svnversion"/>
+ <delete file="svnversion_tmp.txt"/>
+
+ <!-- For some competely retarted reason the '-n' parameter to svnversion doesn't really work under windows...
+ Here is some code to strip the unwanted newlines. -->
+ <script language="C#">
+ <code><![CDATA[
+ public static void ScriptMain(Project project)
+ {
+ project.Properties["build.svnversion"] = project.Properties["build.svnversion"].Trim("\n\r".ToCharArray());
+ }
+ ]]>
+ </code>
+ </script>
+
+ </target>
+
+ <!-- Performs a regex find-and-replace on assembly info files, substituting fields defined as build properties. -->
+ <target name="setversion" description="Stamp the version info onto assemblyinfo.cs files" depends="svnversion">
+
+ <echo>build.svnversion = ${build.svnversion}</echo>
+
+ <foreach item="File" property="filename">
+ <in>
+ <items basedir=".">
+ <include name="**\AssemblyInfo.cs"></include>
+ </items>
+ </in>
+ <do>
+ <script language="C#">
+ <code><![CDATA[
+ public static void ScriptMain(Project project)
+ {
+ // Read in the entire file to perform the substitution in.
+ StreamReader reader = new StreamReader(project.Properties["filename"]);
+ string contents = reader.ReadToEnd();
+ reader.Close();
+
+ // Substitute the version numbers.
+ string replacement = string.Format("[assembly: AssemblyVersion(\"{0}.{1}.{2}.{3}\")]",
+ project.Properties["build.version.major"],
+ project.Properties["build.version.minor"],
+ project.Properties["build.version.build"],
+ project.Properties["build.version.revision"]);
+ contents = Regex.Replace(contents, @"\[assembly: AssemblyVersion\("".*""\)\]", replacement);
+
+ // Substitute the company name and copyright.
+ replacement = string.Format("[assembly: AssemblyCompany(\"{0}\")]",
+ project.Properties["build.company"]);
+ contents = Regex.Replace(contents, @"\[assembly: AssemblyCompany\("".*""\)\]", replacement);
+
+ replacement = string.Format("[assembly: AssemblyCopyright(\"{0}\")]",
+ project.Properties["build.copyright"]);
+ contents = Regex.Replace(contents, @"\[assembly: AssemblyCopyright\("".*""\)\]", replacement);
+
+ // Update the description.
+ //replacement = string.Format("[assembly: AssemblyDescription(\"{0} {1}\")]",
+ // project.Properties["build.description"],
+ // project.Properties["build.svnversion"]);
+ replacement = string.Format("[assembly: AssemblyDescription(\"{0}\")]",
+ project.Properties["build.description"]);
+ contents = Regex.Replace(contents, @"\[assembly: AssemblyDescription\("".*""\)\]", replacement);
+
+ // Write out the file with the substituted version.
+ StreamWriter writer = new StreamWriter(project.Properties["filename"], false);
+ writer.Write(contents);
+ writer.Close();
+ }
+ ]]>
+ </code>
+ </script>
+ </do>
+ </foreach>
+ </target>
+
+ <!-- Do the build. -->
+ <target name="build" depends="init, setversion">
+ <echo message="Building all modules including tests."/>
+
+ <!-- Make sure output folder exists. -->
+ <mkdir dir="${build.dir}" />
+
+ <echo message="Output folder: ${build.dir}"/>
+
+ <!-- copy reference assemblies over to the output dir -->
+ <copy todir="${build.dir}" file="lib/log4net/log4net.dll"/>
+ <copy todir="${build.dir}" file="lib/nunit/nunit.framework.dll"/>
+ <copy todir="${build.dir}" file="lib/plossum/C5.dll"/>
+ <copy todir="${build.dir}" file="lib/plossum/Plossum CommandLine.dll"/>
+
+ <!-- Compile assemblies. -->
+ <nant target="build">
+ <buildfiles refid="src.builds" />
+ </nant>
+
+ <!-- Compile test assemblies. -->
+ <nant target="build">
+ <buildfiles refid="examples.builds" />
+ </nant>
+
+ <!-- Compile test assemblies. -->
+ <nant target="build">
+ <buildfiles refid="tests.builds" />
+ </nant>
+
+ <!-- Compile test assemblies. -->
+ <nant target="build">
+ <buildfiles refid="perftest.builds" />
+ </nant>
+
+ <!-- copy config files over to the output dir -->
+ <copy todir="${build.dir}" file="test/Qpid Test.dll.config"/>
+ <copy todir="${build.dir}" file="log.xml"/>
+
+
+ </target>
+
+ <!-- Runs all 'pure unit' tests. -->
+ <target name="test" depends="build">
+ <echo message="Running all pure unit tests."/>
+ <nant target="test">
+ <buildfiles refid="tests.builds" />
+ </nant>
+ </target>
+
+ <!-- Creates a release package. -->
+ <target name="release-pkg">
+ <echo message="Building and packaging a release."/>
+
+ <call target="clean"/>
+ <call target="build"/>
+
+ <property name="build.date" value="${datetime::now()}"/>
+
+ <zip zipfile="${build.dir}/Qpid.NET-${framework::get-target-framework()}-${datetime::get-year(build.date)}${datetime::get-month(build.date)}${datetime::get-day(build.date)}.zip">
+ <fileset basedir="${build.dir}" prefix="qpid/lib">
+ <include name="**/*.*"/>
+ <exclude name="**/*.tests.*"/>
+ <exclude name="**/example*.*"/>
+ <exclude name="**/nunit.framework.dll"/>
+ <exclude name="**/*.exe"/>
+ <exclude name="**/*.pdb"/>
+ </fileset>
+
+ <fileset basedir="${build.dir}" prefix="qpid/examples/direct">
+ <include name="**/example*direct*.exe"/>
+ </fileset>
+
+ <fileset basedir="${build.dir}" prefix="qpid/examples/fanout">
+ <include name="**/example*fanout*.exe"/>
+ </fileset>
+
+ <fileset basedir="${build.dir}" prefix="qpid/examples/pub-sub">
+ <include name="**/example*pub-sub*.exe"/>
+ </fileset>
+
+ <fileset basedir="${build.dir}" prefix="qpid/examples/request-response">
+ <include name="**/example*request-response*.exe"/>
+ </fileset>
+
+ <fileset basedir="${base.dir}/.." prefix="qpid">
+ <include name="LICENSE.txt"/>
+ <include name="NOTICE.txt"/>
+ <include name="RELEASE_NOTES.txt"/>
+ <include name="DISCLAIMER"/>
+ </fileset>
+
+
+ <fileset basedir="${base.dir}" prefix="qpid">
+ <include name="README.txt"/>
+ </fileset>
+ </zip>
+ </target>
+
+</project>
+
+
diff --git a/qpid/dotnet/client-010/demo/Demo.csproj b/qpid/dotnet/client-010/demo/Demo.csproj
new file mode 100644
index 0000000000..1668314425
--- /dev/null
+++ b/qpid/dotnet/client-010/demo/Demo.csproj
@@ -0,0 +1,110 @@
+<?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.
+ -
+ -->
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProductVersion>9.0.30729</ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{E4C46FBC-7560-406D-BFEF-CA010E584DF4}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>demo</RootNamespace>
+ <AssemblyName>Qpid Demo</AssemblyName>
+ <FileUpgradeFlags>
+ </FileUpgradeFlags>
+ <OldToolsVersion>2.0</OldToolsVersion>
+ <UpgradeBackupLocation>
+ </UpgradeBackupLocation>
+ <StartupObject>
+ </StartupObject>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="log4net, Version=1.2.10.0, Culture=neutral, PublicKeyToken=1b44e1d426115821">
+ <SpecificVersion>False</SpecificVersion>
+ <HintPath>..\lib\log4net\log4net.dll</HintPath>
+ </Reference>
+ <Reference Include="System" />
+ <Reference Include="System.configuration" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Deployment" />
+ <Reference Include="System.Drawing" />
+ <Reference Include="System.Windows.Forms" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="*.cs" />
+ <EmbeddedResource Include="Properties\Resources.resx">
+ <Generator>ResXFileCodeGenerator</Generator>
+ <LastGenOutput>Resources.Designer.cs</LastGenOutput>
+ <SubType>Designer</SubType>
+ </EmbeddedResource>
+ <Compile Include="Properties\Resources.Designer.cs">
+ <AutoGen>True</AutoGen>
+ <DependentUpon>Resources.resx</DependentUpon>
+ <DesignTime>True</DesignTime>
+ </Compile>
+ <None Include="..\App.config">
+ <Link>App.config</Link>
+ </None>
+ <None Include="Properties\Settings.settings">
+ <Generator>SettingsSingleFileGenerator</Generator>
+ <LastGenOutput>Settings.Designer.cs</LastGenOutput>
+ </None>
+ <Compile Include="Properties\Settings.Designer.cs">
+ <AutoGen>True</AutoGen>
+ <DependentUpon>Settings.settings</DependentUpon>
+ <DesignTimeSharedInput>True</DesignTimeSharedInput>
+ </Compile>
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\client\Client.csproj">
+ <Project>{B911FFD7-754F-4735-A188-218D5065BE79}</Project>
+ <Name>Client</Name>
+ </ProjectReference>
+ </ItemGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+ <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
+ Other similar extension points exist, see Microsoft.Common.targets.
+ <Target Name="BeforeBuild">
+ </Target>
+ <Target Name="AfterBuild">
+ </Target>
+ -->
+</Project>
diff --git a/qpid/dotnet/client-010/demo/Program.cs b/qpid/dotnet/client-010/demo/Program.cs
new file mode 100644
index 0000000000..aa748544a0
--- /dev/null
+++ b/qpid/dotnet/client-010/demo/Program.cs
@@ -0,0 +1,126 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+using System;
+using System.Configuration;
+using System.IO;
+using System.Text;
+using System.Threading;
+using log4net.Config;
+using org.apache.qpid.client;
+using org.apache.qpid.transport;
+using org.apache.qpid.transport.util;
+
+namespace WindowsClient
+{
+ class Program
+ {
+ static void Main(string[] args)
+ {
+ XmlConfigurator.Configure(new FileInfo("..\\..\\log.xml"));
+ // DOMConfigurator.Configure()
+
+ string host = ConfigurationManager.AppSettings["Host"];
+ int port = int.Parse(ConfigurationManager.AppSettings["Port"]);
+ string virtualhost = ConfigurationManager.AppSettings["VirtualHost"];
+ string username = ConfigurationManager.AppSettings["Username"];
+ string password = ConfigurationManager.AppSettings["Password"];
+
+ Client client = new Client();
+ Console.WriteLine("Client created");
+ client.Connect(host, port, virtualhost, username, password);
+ Console.WriteLine("Connection established");
+
+ IClientSession ssn = client.CreateSession(50000);
+ Console.WriteLine("Session created");
+ ssn.QueueDeclare("queue1", null, null);
+ ssn.ExchangeBind("queue1", "amq.direct", "queue1", null);
+
+
+ Object wl = new Object();
+ ssn.AttachMessageListener(new MyListener(ssn, wl), "myDest");
+
+ ssn.MessageSubscribe("queue1", "myDest", MessageAcceptMode.EXPLICIT, MessageAcquireMode.PRE_ACQUIRED, null,
+ 0, null);
+ DateTime start = DateTime.Now;
+
+ // issue credits
+ ssn.MessageSetFlowMode("myDest", MessageFlowMode.WINDOW);
+ ssn.MessageFlow("myDest", MessageCreditUnit.BYTE, ClientSession.MESSAGE_FLOW_MAX_BYTES);
+ ssn.MessageFlow("myDest", MessageCreditUnit.MESSAGE, 10000);
+ ssn.Sync();
+
+
+ for (int i = 0; i < 10000; i ++)
+ {
+ ssn.MessageTransfer("amq.direct", MessageAcceptMode.NONE, MessageAcquireMode.PRE_ACQUIRED,
+ new Header(new DeliveryProperties().SetRoutingKey("queue1"),
+ new MessageProperties().SetMessageId(UUID.RandomUuid())),
+ Encoding.UTF8.GetBytes("test: " + i));
+ }
+
+ lock(wl)
+ {
+ Monitor.Wait(wl);
+ }
+ DateTime now = DateTime.Now;
+ Console.WriteLine("Start time " + start + " now: " + now);
+
+ Console.WriteLine("Done time: " + (now - start));
+ lock (wl)
+ {
+ Monitor.Wait(wl, 30000);
+ }
+ client.Close();
+ }
+ }
+
+ class MyListener : IMessageListener
+ {
+ private readonly Object _wl;
+ private IClientSession _session;
+ private int _count;
+
+ public MyListener(IClientSession session, object wl)
+ {
+ _wl = wl;
+ _session = session;
+ _count = 0;
+ }
+
+ public void MessageTransfer(IMessage m)
+ {
+ BinaryReader reader = new BinaryReader(m.Body, Encoding.UTF8);
+ byte[] body = new byte[m.Body.Length - m.Body.Position];
+ reader.Read(body, 0, body.Length);
+ ASCIIEncoding enc = new ASCIIEncoding();
+ // Console.WriteLine("Got a message: " + enc.GetString(body) + " count = " + _count);
+ _count++;
+ if (_count == 10000)
+ {
+ lock (_wl)
+ {
+ Monitor.PulseAll(_wl);
+ }
+ }
+ }
+ }
+}
diff --git a/qpid/dotnet/client-010/demo/Properties/AssemblyInfo.cs b/qpid/dotnet/client-010/demo/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000000..58c7baf4b4
--- /dev/null
+++ b/qpid/dotnet/client-010/demo/Properties/AssemblyInfo.cs
@@ -0,0 +1,54 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("Qpid Demo")]
+[assembly: AssemblyDescription("Built from svn revision number: ")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Apache Software Foundation")]
+[assembly: AssemblyProduct("Qpid Demo")]
+[assembly: AssemblyCopyright("Apache Software Foundation")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("434bc34e-b59b-4800-87cf-c2d301cb5082")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+[assembly: AssemblyVersion("0.5.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/qpid/dotnet/client-010/demo/Properties/Resources.Designer.cs b/qpid/dotnet/client-010/demo/Properties/Resources.Designer.cs
new file mode 100644
index 0000000000..912f9e5b81
--- /dev/null
+++ b/qpid/dotnet/client-010/demo/Properties/Resources.Designer.cs
@@ -0,0 +1,84 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+//------------------------------------------------------------------------------
+// <auto-generated>
+// This code was generated by a tool.
+// Runtime Version:2.0.50727.3053
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace demo.Properties {
+ using System;
+
+
+ /// <summary>
+ /// A strongly-typed resource class, for looking up localized strings, etc.
+ /// </summary>
+ // This class was auto-generated by the StronglyTypedResourceBuilder
+ // class via a tool like ResGen or Visual Studio.
+ // To add or remove a member, edit your .ResX file then rerun ResGen
+ // with the /str option, or rebuild your VS project.
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "2.0.0.0")]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+ internal class Resources {
+
+ private static global::System.Resources.ResourceManager resourceMan;
+
+ private static global::System.Globalization.CultureInfo resourceCulture;
+
+ [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+ internal Resources() {
+ }
+
+ /// <summary>
+ /// Returns the cached ResourceManager instance used by this class.
+ /// </summary>
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ internal static global::System.Resources.ResourceManager ResourceManager {
+ get {
+ if (object.ReferenceEquals(resourceMan, null)) {
+ global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("demo.Properties.Resources", typeof(Resources).Assembly);
+ resourceMan = temp;
+ }
+ return resourceMan;
+ }
+ }
+
+ /// <summary>
+ /// Overrides the current thread's CurrentUICulture property for all
+ /// resource lookups using this strongly typed resource class.
+ /// </summary>
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ internal static global::System.Globalization.CultureInfo Culture {
+ get {
+ return resourceCulture;
+ }
+ set {
+ resourceCulture = value;
+ }
+ }
+ }
+}
diff --git a/qpid/dotnet/client-010/demo/Properties/Resources.resx b/qpid/dotnet/client-010/demo/Properties/Resources.resx
new file mode 100644
index 0000000000..af03750170
--- /dev/null
+++ b/qpid/dotnet/client-010/demo/Properties/Resources.resx
@@ -0,0 +1,137 @@
+<?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.
+ -
+ -->
+<root>
+ <!--
+ Microsoft ResX Schema
+
+ Version 2.0
+
+ The primary goals of this format is to allow a simple XML format
+ that is mostly human readable. The generation and parsing of the
+ various data types are done through the TypeConverter classes
+ associated with the data types.
+
+ Example:
+
+ ... ado.net/XML headers & schema ...
+ <resheader name="resmimetype">text/microsoft-resx</resheader>
+ <resheader name="version">2.0</resheader>
+ <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+ <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+ <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+ <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+ <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+ <value>[base64 mime encoded serialized .NET Framework object]</value>
+ </data>
+ <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+ <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+ <comment>This is a comment</comment>
+ </data>
+
+ There are any number of "resheader" rows that contain simple
+ name/value pairs.
+
+ Each data row contains a name, and value. The row also contains a
+ type or mimetype. Type corresponds to a .NET class that support
+ text/value conversion through the TypeConverter architecture.
+ Classes that don't support this are serialized and stored with the
+ mimetype set.
+
+ The mimetype is used for serialized objects, and tells the
+ ResXResourceReader how to depersist the object. This is currently not
+ extensible. For a given mimetype the value must be set accordingly:
+
+ Note - application/x-microsoft.net.object.binary.base64 is the format
+ that the ResXResourceWriter will generate, however the reader can
+ read any of the formats listed below.
+
+ mimetype: application/x-microsoft.net.object.binary.base64
+ value : The object must be serialized with
+ : System.Serialization.Formatters.Binary.BinaryFormatter
+ : and then encoded with base64 encoding.
+
+ mimetype: application/x-microsoft.net.object.soap.base64
+ value : The object must be serialized with
+ : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+ : and then encoded with base64 encoding.
+
+ mimetype: application/x-microsoft.net.object.bytearray.base64
+ value : The object must be serialized into a byte array
+ : using a System.ComponentModel.TypeConverter
+ : and then encoded with base64 encoding.
+ -->
+ <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+ <xsd:element name="root" msdata:IsDataSet="true">
+ <xsd:complexType>
+ <xsd:choice maxOccurs="unbounded">
+ <xsd:element name="metadata">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" />
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" />
+ <xsd:attribute name="type" type="xsd:string" />
+ <xsd:attribute name="mimetype" type="xsd:string" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="assembly">
+ <xsd:complexType>
+ <xsd:attribute name="alias" type="xsd:string" />
+ <xsd:attribute name="name" type="xsd:string" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="data">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+ <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
+ <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+ <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="resheader">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" use="required" />
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:choice>
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:schema>
+ <resheader name="resmimetype">
+ <value>text/microsoft-resx</value>
+ </resheader>
+ <resheader name="version">
+ <value>2.0</value>
+ </resheader>
+ <resheader name="reader">
+ <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+ </resheader>
+ <resheader name="writer">
+ <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+ </resheader>
+</root> \ No newline at end of file
diff --git a/qpid/dotnet/client-010/demo/Properties/Settings.Designer.cs b/qpid/dotnet/client-010/demo/Properties/Settings.Designer.cs
new file mode 100644
index 0000000000..fc41e577fe
--- /dev/null
+++ b/qpid/dotnet/client-010/demo/Properties/Settings.Designer.cs
@@ -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.
+ *
+ */
+
+//------------------------------------------------------------------------------
+// <auto-generated>
+// This code was generated by a tool.
+// Runtime Version:2.0.50727.3053
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace demo.Properties {
+
+
+ [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "9.0.0.0")]
+ internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
+
+ private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
+
+ public static Settings Default {
+ get {
+ return defaultInstance;
+ }
+ }
+ }
+}
diff --git a/qpid/dotnet/client-010/demo/Properties/Settings.settings b/qpid/dotnet/client-010/demo/Properties/Settings.settings
new file mode 100644
index 0000000000..64cfd9241c
--- /dev/null
+++ b/qpid/dotnet/client-010/demo/Properties/Settings.settings
@@ -0,0 +1,27 @@
+<?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.
+ -
+ -->
+<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)">
+ <Profiles>
+ <Profile Name="(Default)" />
+ </Profiles>
+ <Settings />
+</SettingsFile>
diff --git a/qpid/dotnet/client-010/demo/default.build b/qpid/dotnet/client-010/demo/default.build
new file mode 100644
index 0000000000..f582e392f8
--- /dev/null
+++ b/qpid/dotnet/client-010/demo/default.build
@@ -0,0 +1,48 @@
+<?xml version="1.0"?>
+<!--
+
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+
+-->
+
+<project name="qpid.client.demo" default="build">
+ <!--
+ Properties that come from master build file
+ - build.dir: root directory for build
+ - build.debug: true if building debug release
+ - build.defines: variables to define during build
+ -->
+
+ <target name="build">
+ <csc target="exe"
+ define="${build.defines}"
+ debug="${build.debug}"
+ output="${build.dir}/${project::get-name()}.exe">
+
+ <sources>
+ <include name="**/*.cs" />
+ </sources>
+ <references>
+ <include name="${build.dir}/log4net.dll" />
+ <include name="${build.dir}/qpid.client.dll" />
+ <include name="System.Configuration.dll"/>
+ </references>
+ </csc>
+ </target>
+</project>
+
diff --git a/qpid/dotnet/client-010/examples/direct/example-direct-Listener/Listener.cs b/qpid/dotnet/client-010/examples/direct/example-direct-Listener/Listener.cs
new file mode 100644
index 0000000000..f20090526d
--- /dev/null
+++ b/qpid/dotnet/client-010/examples/direct/example-direct-Listener/Listener.cs
@@ -0,0 +1,117 @@
+/*
+* 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.
+*/
+
+using System;
+using System.Configuration;
+using System.IO;
+using System.Text;
+using System.Threading;
+using org.apache.qpid.client;
+using org.apache.qpid.transport;
+
+namespace org.apache.qpid.example.direct
+{
+ /// <summary>
+ /// This program is one of three programs designed to be used
+ /// together. These programs use the "amq.direct" exchange.
+ ///
+ /// Producer:
+ ///
+ /// Publishes to a broker, specifying a routing key.
+ ///
+ /// Listener (this program):
+ ///
+ /// Reads from a queue on the broker using a message listener.
+ ///
+ /// </summary>
+ public class Listener
+ {
+ private static void Main(string[] args)
+ {
+ string host = ConfigurationManager.AppSettings["Host"];
+ int port = int.Parse(ConfigurationManager.AppSettings["Port"]);
+ string virtualhost = ConfigurationManager.AppSettings["VirtualHost"];
+ string username = ConfigurationManager.AppSettings["Username"];
+ string password = ConfigurationManager.AppSettings["Password"];
+
+ Client connection = new Client();
+ try
+ {
+ connection.Connect(host, port, virtualhost, username, password);
+ IClientSession session = connection.CreateSession(50000);
+
+ //--------- Main body of program --------------------------------------------
+ // Create a queue named "message_queue", and route all messages whose
+ // routing key is "routing_key" to this newly created queue.
+
+ session.QueueDeclare("message_queue");
+ session.ExchangeBind("message_queue", "amq.direct", "routing_key");
+
+ lock (session)
+ {
+ // Create a listener and subscribe it to the queue named "message_queue"
+ IMessageListener listener = new MessageListener(session);
+ session.AttachMessageListener(listener, "message_queue");
+ session.MessageSubscribe("message_queue");
+ // Receive messages until all messages are received
+ Monitor.Wait(session);
+ }
+
+ //---------------------------------------------------------------------------
+
+ connection.Close();
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine("Error: \n" + e.StackTrace);
+ }
+ }
+ }
+
+ public class MessageListener : IMessageListener
+ {
+ private readonly IClientSession _session;
+ private readonly RangeSet _range = new RangeSet();
+ public MessageListener(IClientSession session)
+ {
+ _session = session;
+ }
+
+ public void MessageTransfer(IMessage m)
+ {
+ BinaryReader reader = new BinaryReader(m.Body, Encoding.UTF8);
+ byte[] body = new byte[m.Body.Length - m.Body.Position];
+ reader.Read(body, 0, body.Length);
+ ASCIIEncoding enc = new ASCIIEncoding();
+ string message = enc.GetString(body);
+ Console.WriteLine("Message: " + message);
+ // Add this message to the list of message to be acknowledged
+ _range.Add(m.Id);
+ if( message.Equals("That's all, folks!") )
+ {
+ // Acknowledge all the received messages
+ _session.MessageAccept(_range);
+ lock(_session)
+ {
+ Monitor.Pulse(_session);
+ }
+ }
+ }
+ }
+}
diff --git a/qpid/dotnet/client-010/examples/direct/example-direct-Listener/Properties/AssemblyInfo.cs b/qpid/dotnet/client-010/examples/direct/example-direct-Listener/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000000..2fab6a538a
--- /dev/null
+++ b/qpid/dotnet/client-010/examples/direct/example-direct-Listener/Properties/AssemblyInfo.cs
@@ -0,0 +1,54 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("example-direct-Listener")]
+[assembly: AssemblyDescription("Built from svn revision number: ")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Apache Software Foundation")]
+[assembly: AssemblyProduct("example-direct-Listener")]
+[assembly: AssemblyCopyright("Apache Software Foundation")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("6a24bfe4-4714-4d2a-acf4-96cf9a678a06")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+[assembly: AssemblyVersion("0.5.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/qpid/dotnet/client-010/examples/direct/example-direct-Listener/default.build b/qpid/dotnet/client-010/examples/direct/example-direct-Listener/default.build
new file mode 100644
index 0000000000..f5db519af7
--- /dev/null
+++ b/qpid/dotnet/client-010/examples/direct/example-direct-Listener/default.build
@@ -0,0 +1,48 @@
+<?xml version="1.0"?>
+<!--
+
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+
+-->
+
+<project name="example-direct-Listener" default="build">
+ <!--
+ Properties that come from master build file
+ - build.dir: root directory for build
+ - build.debug: true if building debug release
+ - build.defines: variables to define during build
+ -->
+
+ <target name="build">
+ <csc target="exe"
+ define="${build.defines}"
+ debug="${build.debug}"
+ output="${build.dir}/${project::get-name()}.exe">
+
+ <sources>
+ <include name="**/*.cs" />
+ </sources>
+ <references>
+ <include name="${build.dir}/log4net.dll" />
+ <include name="${build.dir}/qpid.client.dll" />
+ <include name="System.Configuration.dll" />
+ </references>
+ </csc>
+ </target>
+</project>
+
diff --git a/qpid/dotnet/client-010/examples/direct/example-direct-Listener/example-direct-Listener.csproj b/qpid/dotnet/client-010/examples/direct/example-direct-Listener/example-direct-Listener.csproj
new file mode 100644
index 0000000000..ac026b397d
--- /dev/null
+++ b/qpid/dotnet/client-010/examples/direct/example-direct-Listener/example-direct-Listener.csproj
@@ -0,0 +1,85 @@
+<?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.
+ -
+ -->
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProductVersion>9.0.30729</ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{AE65B1B9-8779-4CB1-91AF-E7F6C7A736D7}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>example_direct_Listener</RootNamespace>
+ <AssemblyName>example-direct-Listener</AssemblyName>
+ <FileUpgradeFlags>
+ </FileUpgradeFlags>
+ <OldToolsVersion>2.0</OldToolsVersion>
+ <UpgradeBackupLocation>
+ </UpgradeBackupLocation>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="System" />
+ <Reference Include="System.configuration" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="Listener.cs" />
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\..\..\client\Client.csproj">
+ <Project>{B911FFD7-754F-4735-A188-218D5065BE79}</Project>
+ <Name>Client</Name>
+ </ProjectReference>
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="..\..\..\App.config">
+ <Link>App.config</Link>
+ </None>
+ </ItemGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+ <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
+ Other similar extension points exist, see Microsoft.Common.targets.
+ <Target Name="BeforeBuild">
+ </Target>
+ <Target Name="AfterBuild">
+ </Target>
+ -->
+</Project>
diff --git a/qpid/dotnet/client-010/examples/direct/example-direct-producer/Producer.cs b/qpid/dotnet/client-010/examples/direct/example-direct-producer/Producer.cs
new file mode 100644
index 0000000000..f62667bf98
--- /dev/null
+++ b/qpid/dotnet/client-010/examples/direct/example-direct-producer/Producer.cs
@@ -0,0 +1,92 @@
+/*
+* 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.
+*/
+
+using System;
+using System.Configuration;
+using System.Text;
+using org.apache.qpid.client;
+
+namespace org.apache.qpid.example.direct
+{
+ /// <summary>
+ /// This program is one of three programs designed to be used
+ /// together. These programs use the "amq.direct" exchange.
+ ///
+ /// Producer (this program):
+ ///
+ /// Publishes to a broker, specifying a routing key.
+ ///
+ /// Listener:
+ ///
+ /// Reads from a queue on the broker using a message listener.
+ ///
+ /// </summary>
+ class Producer
+ {
+ static void Main(string[] args)
+ {
+ string host = ConfigurationManager.AppSettings["Host"];
+ int port = int.Parse(ConfigurationManager.AppSettings["Port"]);
+ string virtualhost = ConfigurationManager.AppSettings["VirtualHost"];
+ string username = ConfigurationManager.AppSettings["Username"];
+ string password = ConfigurationManager.AppSettings["Password"];
+
+ Client connection = new Client();
+ try
+ {
+ connection.Connect(host, port, virtualhost, username, password);
+ IClientSession session = connection.CreateSession(50000);
+
+ //--------- Main body of program --------------------------------------------
+
+ IMessage message = new Message();
+
+ // The routing key is a message property. We will use the same
+ // routing key for each message, so we'll set this property
+ // just once. (In most simple cases, there is no need to set
+ // other message properties.)
+
+ message.DeliveryProperties.SetRoutingKey("routing_key");
+
+ // Asynchronous transfer sends messages as quickly as
+ // possible without waiting for confirmation.
+ for (int i = 0; i < 10; i++)
+ {
+ message.ClearData();
+ message.AppendData(Encoding.UTF8.GetBytes("Message " + i));
+ session.MessageTransfer("amq.direct", message);
+ }
+
+ // And send a syncrhonous final message to indicate termination.
+ message.ClearData();
+ message.AppendData(Encoding.UTF8.GetBytes("That's all, folks!"));
+ session.MessageTransfer("amq.direct", "routing_key", message);
+ session.Sync();
+
+ //-----------------------------------------------------------------------------
+
+ connection.Close();
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine("Error: \n" + e.StackTrace);
+ }
+ }
+ }
+}
diff --git a/qpid/dotnet/client-010/examples/direct/example-direct-producer/Properties/AssemblyInfo.cs b/qpid/dotnet/client-010/examples/direct/example-direct-producer/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000000..84590e67c1
--- /dev/null
+++ b/qpid/dotnet/client-010/examples/direct/example-direct-producer/Properties/AssemblyInfo.cs
@@ -0,0 +1,54 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("example-direct-producer")]
+[assembly: AssemblyDescription("Built from svn revision number: ")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Apache Software Foundation")]
+[assembly: AssemblyProduct("example-direct-producer")]
+[assembly: AssemblyCopyright("Apache Software Foundation")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("006144c2-5e45-4543-8e16-c09cd4309ed7")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+[assembly: AssemblyVersion("0.5.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/qpid/dotnet/client-010/examples/direct/example-direct-producer/default.build b/qpid/dotnet/client-010/examples/direct/example-direct-producer/default.build
new file mode 100644
index 0000000000..c4e78444c7
--- /dev/null
+++ b/qpid/dotnet/client-010/examples/direct/example-direct-producer/default.build
@@ -0,0 +1,48 @@
+<?xml version="1.0"?>
+<!--
+
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+
+-->
+
+<project name="example-direct-Producer" default="build">
+ <!--
+ Properties that come from master build file
+ - build.dir: root directory for build
+ - build.debug: true if building debug release
+ - build.defines: variables to define during build
+ -->
+
+ <target name="build">
+ <csc target="exe"
+ define="${build.defines}"
+ debug="${build.debug}"
+ output="${build.dir}/${project::get-name()}.exe">
+
+ <sources>
+ <include name="**/*.cs" />
+ </sources>
+ <references>
+ <include name="${build.dir}/log4net.dll" />
+ <include name="${build.dir}/qpid.client.dll" />
+ <include name="System.Configuration.dll" />
+ </references>
+ </csc>
+ </target>
+</project>
+
diff --git a/qpid/dotnet/client-010/examples/direct/example-direct-producer/example-direct-producer.csproj b/qpid/dotnet/client-010/examples/direct/example-direct-producer/example-direct-producer.csproj
new file mode 100644
index 0000000000..10d9d96aea
--- /dev/null
+++ b/qpid/dotnet/client-010/examples/direct/example-direct-producer/example-direct-producer.csproj
@@ -0,0 +1,85 @@
+<?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.
+ -
+ -->
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProductVersion>9.0.30729</ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{96FCB250-8142-40EE-9BDD-CA839EE21021}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>example_direct_producer</RootNamespace>
+ <AssemblyName>example-direct-producer</AssemblyName>
+ <FileUpgradeFlags>
+ </FileUpgradeFlags>
+ <OldToolsVersion>2.0</OldToolsVersion>
+ <UpgradeBackupLocation>
+ </UpgradeBackupLocation>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="System" />
+ <Reference Include="System.configuration" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="Producer.cs" />
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\..\..\client\Client.csproj">
+ <Project>{B911FFD7-754F-4735-A188-218D5065BE79}</Project>
+ <Name>Client</Name>
+ </ProjectReference>
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="..\..\..\App.config">
+ <Link>App.config</Link>
+ </None>
+ </ItemGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+ <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
+ Other similar extension points exist, see Microsoft.Common.targets.
+ <Target Name="BeforeBuild">
+ </Target>
+ <Target Name="AfterBuild">
+ </Target>
+ -->
+</Project>
diff --git a/qpid/dotnet/client-010/examples/direct/verify b/qpid/dotnet/client-010/examples/direct/verify
new file mode 100644
index 0000000000..7da08480a2
--- /dev/null
+++ b/qpid/dotnet/client-010/examples/direct/verify
@@ -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.
+##
+##
+#
+
+# See https://svn.apache.org/repos/asf/incubator/qpid/trunk/qpid/bin/verify
+cpp=$CPP/direct
+
+direct_listener_dotnet()
+{
+mono $DOTNET_EXAMPLES/example-direct-Listener.exe localhost 5672
+}
+
+direct_producer_dotnet()
+{
+mono $DOTNET_EXAMPLES/example-direct-Producer.exe localhost 5672
+}
+
+clients $cpp/declare_queues direct_producer_dotnet direct_listener_dotnet
+outputs $cpp/declare_queues.out ./direct_producer_dotnet.out ./direct_listener_dotnet.out
diff --git a/qpid/dotnet/client-010/examples/direct/verify.in b/qpid/dotnet/client-010/examples/direct/verify.in
new file mode 100644
index 0000000000..f57d931663
--- /dev/null
+++ b/qpid/dotnet/client-010/examples/direct/verify.in
@@ -0,0 +1,14 @@
+==== declare_queues.out
+==== direct_producer_dotnet.out
+==== direct_listener_dotnet.out
+Message: Message 0
+Message: Message 1
+Message: Message 2
+Message: Message 3
+Message: Message 4
+Message: Message 5
+Message: Message 6
+Message: Message 7
+Message: Message 8
+Message: Message 9
+Message: That's all, folks!
diff --git a/qpid/dotnet/client-010/examples/direct/verify_cpp_dotnet b/qpid/dotnet/client-010/examples/direct/verify_cpp_dotnet
new file mode 100644
index 0000000000..648c8b6bc1
--- /dev/null
+++ b/qpid/dotnet/client-010/examples/direct/verify_cpp_dotnet
@@ -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.
+#
+
+# See https://svn.apache.org/repos/asf/incubator/qpid/trunk/qpid/bin/verify
+cpp=$CPP/direct
+
+direct_listener_dotnet()
+{
+mono $DOTNET_EXAMPLES/example-direct-Listener.exe localhost 5672
+}
+
+clients $cpp/declare_queues $cpp/direct_producer direct_listener_dotnet
+outputs $cpp/declare_queues.out $cpp/direct_producer.out ./direct_listener_dotnet.out
diff --git a/qpid/dotnet/client-010/examples/direct/verify_cpp_dotnet.in b/qpid/dotnet/client-010/examples/direct/verify_cpp_dotnet.in
new file mode 100644
index 0000000000..b3543cefe5
--- /dev/null
+++ b/qpid/dotnet/client-010/examples/direct/verify_cpp_dotnet.in
@@ -0,0 +1,14 @@
+==== declare_queues.out
+==== direct_producer.out
+==== direct_listener_dotnet.out
+Message: Message 0
+Message: Message 1
+Message: Message 2
+Message: Message 3
+Message: Message 4
+Message: Message 5
+Message: Message 6
+Message: Message 7
+Message: Message 8
+Message: Message 9
+Message: That's all, folks!
diff --git a/qpid/dotnet/client-010/examples/direct/verify_dotnet_cpp b/qpid/dotnet/client-010/examples/direct/verify_dotnet_cpp
new file mode 100644
index 0000000000..5093da6088
--- /dev/null
+++ b/qpid/dotnet/client-010/examples/direct/verify_dotnet_cpp
@@ -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.
+#
+
+# See https://svn.apache.org/repos/asf/incubator/qpid/trunk/qpid/bin/verify
+cpp=$CPP/direct
+
+direct_producer_dotnet()
+{
+mono $DOTNET_EXAMPLES/example-direct-Producer.exe localhost 5672
+}
+
+clients $cpp/declare_queues direct_producer_dotnet $cpp/listener
+outputs $cpp/declare_queues.out ./direct_producer_dotnet.out $cpp/listener.out
diff --git a/qpid/dotnet/client-010/examples/direct/verify_dotnet_cpp.in b/qpid/dotnet/client-010/examples/direct/verify_dotnet_cpp.in
new file mode 100644
index 0000000000..fcb6cd66de
--- /dev/null
+++ b/qpid/dotnet/client-010/examples/direct/verify_dotnet_cpp.in
@@ -0,0 +1,15 @@
+==== declare_queues.out
+==== direct_producer_dotnet.out
+==== listener.out
+Message: Message 0
+Message: Message 1
+Message: Message 2
+Message: Message 3
+Message: Message 4
+Message: Message 5
+Message: Message 6
+Message: Message 7
+Message: Message 8
+Message: Message 9
+Message: That's all, folks!
+Shutting down listener for message_queue
diff --git a/qpid/dotnet/client-010/examples/fanout/example-fanout-Listener/Listener.cs b/qpid/dotnet/client-010/examples/fanout/example-fanout-Listener/Listener.cs
new file mode 100644
index 0000000000..b1967b59be
--- /dev/null
+++ b/qpid/dotnet/client-010/examples/fanout/example-fanout-Listener/Listener.cs
@@ -0,0 +1,126 @@
+/*
+* 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.
+*/
+
+using System;
+using System.Configuration;
+using System.IO;
+using System.Text;
+using System.Threading;
+using org.apache.qpid.client;
+using org.apache.qpid.transport;
+
+namespace org.apache.qpid.example.fanout
+{
+ /// <summary>
+ /// This program is one of two programs designed to be used
+ /// together.
+ ///
+ /// Producer (this program):
+ ///
+ /// Publishes to a broker, specifying a routing key.
+ ///
+ /// Listener:
+ ///
+ /// Reads from a queue on the broker using a message listener.
+ ///
+ /// </summary>
+ public class Listener
+ {
+ private static void Main(string[] args)
+ {
+ string host = ConfigurationManager.AppSettings["Host"];
+ int port = int.Parse(ConfigurationManager.AppSettings["Port"]);
+ string virtualhost = ConfigurationManager.AppSettings["VirtualHost"];
+ string username = ConfigurationManager.AppSettings["Username"];
+ string password = ConfigurationManager.AppSettings["Password"];
+
+ Client connection = new Client();
+ try
+ {
+ connection.Connect(host, port, virtualhost, username, password);
+ IClientSession session = connection.CreateSession(50000);
+
+ //--------- Main body of program --------------------------------------------
+ // Each client creates its own private queue, using the
+ // session id to guarantee a unique name. It then routes
+ // all messages from the fanout exchange to its own queue
+ // by binding to the queue.
+ //
+ // The binding specifies a binding key, but for a fanout
+ // exchange, the binding key is optional and is not used
+ // for routing decisions. It can be useful for tracking
+ // messages and routing in logs.
+
+ string myQueue = session.Name;
+ session.QueueDeclare(myQueue, Option.EXCLUSIVE, Option.AUTO_DELETE);
+ session.ExchangeBind(myQueue, "amq.fanout", "my-key");
+
+ lock (session)
+ {
+ Console.WriteLine("Listening");
+ // Create a listener and subscribe it to my queue.
+ IMessageListener listener = new MessageListener(session);
+ session.AttachMessageListener(listener, myQueue);
+ session.MessageSubscribe(myQueue);
+ // Receive messages until all messages are received
+ Monitor.Wait(session);
+ }
+
+ //---------------------------------------------------------------------------
+
+ connection.Close();
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine("Error: \n" + e.StackTrace);
+ }
+ }
+ }
+
+ public class MessageListener : IMessageListener
+ {
+ private readonly IClientSession _session;
+ private readonly RangeSet _range = new RangeSet();
+ public MessageListener(IClientSession session)
+ {
+ _session = session;
+ }
+
+ public void MessageTransfer(IMessage m)
+ {
+ BinaryReader reader = new BinaryReader(m.Body, Encoding.UTF8);
+ byte[] body = new byte[m.Body.Length - m.Body.Position];
+ reader.Read(body, 0, body.Length);
+ ASCIIEncoding enc = new ASCIIEncoding();
+ string message = enc.GetString(body);
+ Console.WriteLine("Message: " + message);
+ // Add this message to the list of message to be acknowledged
+ _range.Add(m.Id);
+ if (message.Equals("That's all, folks!"))
+ {
+ // Acknowledge all the received messages
+ _session.MessageAccept(_range);
+ lock (_session)
+ {
+ Monitor.Pulse(_session);
+ }
+ }
+ }
+ }
+}
diff --git a/qpid/dotnet/client-010/examples/fanout/example-fanout-Listener/Properties/AssemblyInfo.cs b/qpid/dotnet/client-010/examples/fanout/example-fanout-Listener/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000000..45ff62073e
--- /dev/null
+++ b/qpid/dotnet/client-010/examples/fanout/example-fanout-Listener/Properties/AssemblyInfo.cs
@@ -0,0 +1,54 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("example-fanout-Listener")]
+[assembly: AssemblyDescription("Built from svn revision number: ")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Apache Software Foundation")]
+[assembly: AssemblyProduct("example-fanout-Listener")]
+[assembly: AssemblyCopyright("Apache Software Foundation")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("68686ef9-aa0a-4334-9c52-d7e6fc507bec")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+[assembly: AssemblyVersion("0.5.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/qpid/dotnet/client-010/examples/fanout/example-fanout-Listener/default.build b/qpid/dotnet/client-010/examples/fanout/example-fanout-Listener/default.build
new file mode 100644
index 0000000000..dde36daf17
--- /dev/null
+++ b/qpid/dotnet/client-010/examples/fanout/example-fanout-Listener/default.build
@@ -0,0 +1,48 @@
+<?xml version="1.0"?>
+<!--
+
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+
+-->
+
+<project name="example-fanout-Listener" default="build">
+ <!--
+ Properties that come from master build file
+ - build.dir: root directory for build
+ - build.debug: true if building debug release
+ - build.defines: variables to define during build
+ -->
+
+ <target name="build">
+ <csc target="exe"
+ define="${build.defines}"
+ debug="${build.debug}"
+ output="${build.dir}/${project::get-name()}.exe">
+
+ <sources>
+ <include name="**/*.cs" />
+ </sources>
+ <references>
+ <include name="${build.dir}/log4net.dll" />
+ <include name="${build.dir}/qpid.client.dll" />
+ <include name="System.Configuration.dll" />
+ </references>
+ </csc>
+ </target>
+</project>
+
diff --git a/qpid/dotnet/client-010/examples/fanout/example-fanout-Listener/example-fanout-Listener.csproj b/qpid/dotnet/client-010/examples/fanout/example-fanout-Listener/example-fanout-Listener.csproj
new file mode 100644
index 0000000000..3bd0b3d0d0
--- /dev/null
+++ b/qpid/dotnet/client-010/examples/fanout/example-fanout-Listener/example-fanout-Listener.csproj
@@ -0,0 +1,85 @@
+<?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.
+ -
+ -->
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProductVersion>9.0.30729</ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{18A0792B-DC3A-4EC5-93D6-DB8A111D8F15}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>example_fanout_Listener</RootNamespace>
+ <AssemblyName>example-fanout-Listener</AssemblyName>
+ <FileUpgradeFlags>
+ </FileUpgradeFlags>
+ <OldToolsVersion>2.0</OldToolsVersion>
+ <UpgradeBackupLocation>
+ </UpgradeBackupLocation>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="System" />
+ <Reference Include="System.configuration" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="Listener.cs" />
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\..\..\client\Client.csproj">
+ <Project>{B911FFD7-754F-4735-A188-218D5065BE79}</Project>
+ <Name>Client</Name>
+ </ProjectReference>
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="..\..\..\App.config">
+ <Link>App.config</Link>
+ </None>
+ </ItemGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+ <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
+ Other similar extension points exist, see Microsoft.Common.targets.
+ <Target Name="BeforeBuild">
+ </Target>
+ <Target Name="AfterBuild">
+ </Target>
+ -->
+</Project>
diff --git a/qpid/dotnet/client-010/examples/fanout/example-fanout-Producer/Producer.cs b/qpid/dotnet/client-010/examples/fanout/example-fanout-Producer/Producer.cs
new file mode 100644
index 0000000000..a781358a7e
--- /dev/null
+++ b/qpid/dotnet/client-010/examples/fanout/example-fanout-Producer/Producer.cs
@@ -0,0 +1,89 @@
+/*
+* 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.
+*/
+
+using System;
+using System.Configuration;
+using System.Text;
+using org.apache.qpid.client;
+
+namespace org.apache.qpid.example.fanout
+{
+ /// <summary>
+ /// This program is one of two programs designed to be used
+ /// together. These programs do not specify the exchange type - the
+ /// default exchange type is the direct exchange.
+ ///
+ ///
+ /// Producer (this program):
+ ///
+ /// Publishes to a broker, specifying a routing key.
+ ///
+ /// Listener:
+ ///
+ /// Reads from a queue on the broker using a message listener.
+ ///
+ /// </summary>
+ class Producer
+ {
+ static void Main(string[] args)
+ {
+ string host = ConfigurationManager.AppSettings["Host"];
+ int port = int.Parse(ConfigurationManager.AppSettings["Port"]);
+ string virtualhost = ConfigurationManager.AppSettings["VirtualHost"];
+ string username = ConfigurationManager.AppSettings["Username"];
+ string password = ConfigurationManager.AppSettings["Password"];
+
+ Client connection = new Client();
+ try
+ {
+ connection.Connect(host, port, virtualhost, username, password);
+ IClientSession session = connection.CreateSession(50000);
+
+ //--------- Main body of program --------------------------------------------
+
+ // Unlike topic exchanges and direct exchanges, a fanout
+ // exchange need not set a routing key.
+ IMessage message = new Message();
+
+ // Asynchronous transfer sends messages as quickly as
+ // possible without waiting for confirmation.
+ for (int i = 0; i < 10; i++)
+ {
+ message.ClearData();
+ message.AppendData(Encoding.UTF8.GetBytes("Message " + i));
+ session.MessageTransfer("amq.fanout", message);
+ }
+
+ // And send a syncrhonous final message to indicate termination.
+ message.ClearData();
+ message.AppendData(Encoding.UTF8.GetBytes("That's all, folks!"));
+ session.MessageTransfer("amq.fanout", message);
+ session.Sync();
+
+ //-----------------------------------------------------------------------------
+
+ connection.Close();
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine("Error: \n" + e.StackTrace);
+ }
+ }
+ }
+}
diff --git a/qpid/dotnet/client-010/examples/fanout/example-fanout-Producer/Properties/AssemblyInfo.cs b/qpid/dotnet/client-010/examples/fanout/example-fanout-Producer/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000000..c19bb5b949
--- /dev/null
+++ b/qpid/dotnet/client-010/examples/fanout/example-fanout-Producer/Properties/AssemblyInfo.cs
@@ -0,0 +1,54 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("example-fanout-Producer")]
+[assembly: AssemblyDescription("Built from svn revision number: ")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Apache Software Foundation")]
+[assembly: AssemblyProduct("example-fanout-Producer")]
+[assembly: AssemblyCopyright("Apache Software Foundation")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("01c0ba10-2f23-409b-9adc-bc514a13131a")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+[assembly: AssemblyVersion("0.5.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/qpid/dotnet/client-010/examples/fanout/example-fanout-Producer/default.build b/qpid/dotnet/client-010/examples/fanout/example-fanout-Producer/default.build
new file mode 100644
index 0000000000..c4d39e41da
--- /dev/null
+++ b/qpid/dotnet/client-010/examples/fanout/example-fanout-Producer/default.build
@@ -0,0 +1,48 @@
+<?xml version="1.0"?>
+<!--
+
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+
+-->
+
+<project name="example-fanout-Producer" default="build">
+ <!--
+ Properties that come from master build file
+ - build.dir: root directory for build
+ - build.debug: true if building debug release
+ - build.defines: variables to define during build
+ -->
+
+ <target name="build">
+ <csc target="exe"
+ define="${build.defines}"
+ debug="${build.debug}"
+ output="${build.dir}/${project::get-name()}.exe">
+
+ <sources>
+ <include name="**/*.cs" />
+ </sources>
+ <references>
+ <include name="${build.dir}/log4net.dll" />
+ <include name="${build.dir}/qpid.client.dll" />
+ <include name="System.Configuration.dll" />
+ </references>
+ </csc>
+ </target>
+</project>
+
diff --git a/qpid/dotnet/client-010/examples/fanout/example-fanout-Producer/example-fanout-Producer.csproj b/qpid/dotnet/client-010/examples/fanout/example-fanout-Producer/example-fanout-Producer.csproj
new file mode 100644
index 0000000000..8b04dd8199
--- /dev/null
+++ b/qpid/dotnet/client-010/examples/fanout/example-fanout-Producer/example-fanout-Producer.csproj
@@ -0,0 +1,85 @@
+<?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.
+ -
+ -->
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProductVersion>9.0.30729</ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{4513BF94-D54A-42FE-8506-FE2CD57B2C51}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>example_fanout_Producer</RootNamespace>
+ <AssemblyName>example-fanout-Producer</AssemblyName>
+ <FileUpgradeFlags>
+ </FileUpgradeFlags>
+ <OldToolsVersion>2.0</OldToolsVersion>
+ <UpgradeBackupLocation>
+ </UpgradeBackupLocation>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="System" />
+ <Reference Include="System.configuration" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="Producer.cs" />
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\..\..\client\Client.csproj">
+ <Project>{B911FFD7-754F-4735-A188-218D5065BE79}</Project>
+ <Name>Client</Name>
+ </ProjectReference>
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="..\..\..\App.config">
+ <Link>App.config</Link>
+ </None>
+ </ItemGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+ <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
+ Other similar extension points exist, see Microsoft.Common.targets.
+ <Target Name="BeforeBuild">
+ </Target>
+ <Target Name="AfterBuild">
+ </Target>
+ -->
+</Project>
diff --git a/qpid/dotnet/client-010/examples/fanout/verify b/qpid/dotnet/client-010/examples/fanout/verify
new file mode 100644
index 0000000000..51b7327243
--- /dev/null
+++ b/qpid/dotnet/client-010/examples/fanout/verify
@@ -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.
+#
+#
+
+# See https://svn.apache.org/repos/asf/incubator/qpid/trunk/qpid/bin/verify
+
+fanout_listener_dotnet()
+{
+mono $DOTNET_EXAMPLES/example-fanout-Listener.exe localhost 5672
+}
+
+fanout_producer_dotnet()
+{
+mono $DOTNET_EXAMPLES/example-fanout-Producer.exe localhost 5672
+}
+
+background "Listening" fanout_listener_dotnet
+clients fanout_producer_dotnet
+outputs ./fanout_listener_dotnet.out ./fanout_producer_dotnet.out
diff --git a/qpid/dotnet/client-010/examples/fanout/verify.in b/qpid/dotnet/client-010/examples/fanout/verify.in
new file mode 100644
index 0000000000..37a4a4aaa8
--- /dev/null
+++ b/qpid/dotnet/client-010/examples/fanout/verify.in
@@ -0,0 +1,14 @@
+==== fanout_listener_dotnet.out
+Listening
+Message: Message 0
+Message: Message 1
+Message: Message 2
+Message: Message 3
+Message: Message 4
+Message: Message 5
+Message: Message 6
+Message: Message 7
+Message: Message 8
+Message: Message 9
+Message: That's all, folks!
+==== fanout_producer_dotnet.out
diff --git a/qpid/dotnet/client-010/examples/fanout/verify_cpp_dotnet b/qpid/dotnet/client-010/examples/fanout/verify_cpp_dotnet
new file mode 100644
index 0000000000..5716d3119b
--- /dev/null
+++ b/qpid/dotnet/client-010/examples/fanout/verify_cpp_dotnet
@@ -0,0 +1,30 @@
+#
+# 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.
+#
+
+# See https://svn.apache.org/repos/asf/incubator/qpid/trunk/qpid/bin/verify
+cpp=$CPP/fanout
+
+fanout_listener_dotnet()
+{
+mono $DOTNET_EXAMPLES/example-fanout-Listener.exe localhost 5672
+}
+
+background "Listening" fanout_listener_dotnet
+clients $cpp/fanout_producer
+outputs $cpp/fanout_producer.out "./fanout_listener_dotnet.out | remove_uuid"
diff --git a/qpid/dotnet/client-010/examples/fanout/verify_cpp_dotnet.in b/qpid/dotnet/client-010/examples/fanout/verify_cpp_dotnet.in
new file mode 100644
index 0000000000..0a72d8fd3c
--- /dev/null
+++ b/qpid/dotnet/client-010/examples/fanout/verify_cpp_dotnet.in
@@ -0,0 +1,14 @@
+==== fanout_producer.out
+==== fanout_listener_dotnet.out | remove_uuid
+Listening
+Message: Message 0
+Message: Message 1
+Message: Message 2
+Message: Message 3
+Message: Message 4
+Message: Message 5
+Message: Message 6
+Message: Message 7
+Message: Message 8
+Message: Message 9
+Message: That's all, folks!
diff --git a/qpid/dotnet/client-010/examples/fanout/verify_dotnet_cpp b/qpid/dotnet/client-010/examples/fanout/verify_dotnet_cpp
new file mode 100644
index 0000000000..c755d1da41
--- /dev/null
+++ b/qpid/dotnet/client-010/examples/fanout/verify_dotnet_cpp
@@ -0,0 +1,31 @@
+#
+# 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.
+#
+
+# See https://svn.apache.org/repos/asf/incubator/qpid/trunk/qpid/bin/verify
+cpp=$CPP/fanout
+
+fanout_producer_dotnet()
+{
+mono $DOTNET_EXAMPLES/example-fanout-Producer.exe localhost 5672
+}
+
+
+background "Listening" $cpp/listener
+clients fanout_producer_dotnet
+outputs ./fanout_producer_dotnet.out "$cpp/listener.out | remove_uuid"
diff --git a/qpid/dotnet/client-010/examples/fanout/verify_dotnet_cpp.in b/qpid/dotnet/client-010/examples/fanout/verify_dotnet_cpp.in
new file mode 100644
index 0000000000..588559938f
--- /dev/null
+++ b/qpid/dotnet/client-010/examples/fanout/verify_dotnet_cpp.in
@@ -0,0 +1,15 @@
+==== fanout_producer_dotnet.out
+==== listener.out | remove_uuid
+Listening
+Message: Message 0
+Message: Message 1
+Message: Message 2
+Message: Message 3
+Message: Message 4
+Message: Message 5
+Message: Message 6
+Message: Message 7
+Message: Message 8
+Message: Message 9
+Message: That's all, folks!
+Shutting down listener for
diff --git a/qpid/dotnet/client-010/examples/pub-sub/example-pub-sub-Listener/Listener.cs b/qpid/dotnet/client-010/examples/pub-sub/example-pub-sub-Listener/Listener.cs
new file mode 100644
index 0000000000..aeaf3f043b
--- /dev/null
+++ b/qpid/dotnet/client-010/examples/pub-sub/example-pub-sub-Listener/Listener.cs
@@ -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.
+*/
+
+using System;
+using System.Configuration;
+using System.IO;
+using System.Text;
+using System.Threading;
+using org.apache.qpid.client;
+using org.apache.qpid.transport;
+
+namespace org.apache.qpid.example.pubsub
+{
+ /// <summary>
+ /// This program is one of two programs designed to be used
+ /// together. These programs use the topic exchange.
+ ///
+ /// Publisher:
+ ///
+ /// Publishes to a broker, specifying a routing key.
+ ///
+ /// Listener (this program):
+ ///
+ /// Reads from a queue on the broker using a message listener.
+ ///
+ /// </summary>
+ internal class Listener
+ {
+ public static int _count = 4;
+
+ private static void Main(string[] args)
+ {
+ string host = ConfigurationManager.AppSettings["Host"];
+ int port = int.Parse(ConfigurationManager.AppSettings["Port"]);
+ string virtualhost = ConfigurationManager.AppSettings["VirtualHost"];
+ string username = ConfigurationManager.AppSettings["Username"];
+ string password = ConfigurationManager.AppSettings["Password"];
+
+ Client connection = new Client();
+ try
+ {
+ connection.Connect(host, port, virtualhost, username, password);
+ IClientSession session = connection.CreateSession(50000);
+
+ //--------- Main body of program --------------------------------------------
+
+ lock (session)
+ {
+ Console.WriteLine("Listening for messages ...");
+ // Create a listener
+ prepareQueue("usa", "usa.#", session);
+ prepareQueue("europe", "europe.#", session);
+ prepareQueue("news", "#.news", session);
+ prepareQueue("weather", "#.weather", session);
+ while (_count > 0)
+ {
+ Monitor.Wait(session);
+ }
+ }
+
+ //---------------------------------------------------------------------------
+
+ connection.Close();
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine("Error: \n" + e.StackTrace);
+ }
+ }
+
+ private static void prepareQueue(string queue, string routing_key, IClientSession session)
+ {
+ // Create a unique queue name for this consumer by concatenating
+ // the queue name parameter with the Session ID.
+ Console.WriteLine("Declaring queue: " + queue);
+ session.QueueDeclare(queue, Option.EXCLUSIVE, Option.AUTO_DELETE);
+
+ // Route messages to the new queue if they match the routing key.
+ // Also route any messages to with the "control" routing key to
+ // this queue so we know when it's time to stop. A publisher sends
+ // a message with the content "That's all, Folks!", using the
+ // "control" routing key, when it is finished.
+
+ session.ExchangeBind(queue, "amq.topic", routing_key);
+ session.ExchangeBind(queue, "amq.topic", "control");
+
+ // subscribe the listener to the queue
+ IMessageListener listener = new MessageListener(session);
+ session.AttachMessageListener(listener, queue);
+ session.MessageSubscribe(queue);
+ }
+ }
+
+ public class MessageListener : IMessageListener
+ {
+ private readonly IClientSession _session;
+ private readonly RangeSet _range = new RangeSet();
+
+ public MessageListener(IClientSession session)
+ {
+ _session = session;
+ }
+
+ public void MessageTransfer(IMessage m)
+ {
+ BinaryReader reader = new BinaryReader(m.Body, Encoding.UTF8);
+ byte[] body = new byte[m.Body.Length - m.Body.Position];
+ reader.Read(body, 0, body.Length);
+ ASCIIEncoding enc = new ASCIIEncoding();
+ string message = enc.GetString(body);
+ Console.WriteLine("Message: " + message + " from " + m.Destination);
+ // Add this message to the list of message to be acknowledged
+ _range.Add(m.Id);
+ if (message.Equals("That's all, folks!"))
+ {
+ Console.WriteLine("Shutting down listener for " + m.DeliveryProperties.GetRoutingKey());
+ Listener._count--;
+ // Acknowledge all the received messages
+ _session.MessageAccept(_range);
+ lock (_session)
+ {
+ Monitor.Pulse(_session);
+ }
+ }
+ }
+ }
+}
diff --git a/qpid/dotnet/client-010/examples/pub-sub/example-pub-sub-Listener/Properties/AssemblyInfo.cs b/qpid/dotnet/client-010/examples/pub-sub/example-pub-sub-Listener/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000000..ef791c6738
--- /dev/null
+++ b/qpid/dotnet/client-010/examples/pub-sub/example-pub-sub-Listener/Properties/AssemblyInfo.cs
@@ -0,0 +1,54 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("example-pub-sub-Listener")]
+[assembly: AssemblyDescription("Built from svn revision number: ")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Apache Software Foundation")]
+[assembly: AssemblyProduct("example-pub-sub-Listener")]
+[assembly: AssemblyCopyright("Apache Software Foundation")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("74ab02ae-95d1-4bad-a7cf-9964005b9b05")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+[assembly: AssemblyVersion("0.5.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/qpid/dotnet/client-010/examples/pub-sub/example-pub-sub-Listener/default.build b/qpid/dotnet/client-010/examples/pub-sub/example-pub-sub-Listener/default.build
new file mode 100644
index 0000000000..fe2d9bf4ba
--- /dev/null
+++ b/qpid/dotnet/client-010/examples/pub-sub/example-pub-sub-Listener/default.build
@@ -0,0 +1,48 @@
+<?xml version="1.0"?>
+<!--
+
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+
+-->
+
+<project name="example-pub-sub-Listener" default="build">
+ <!--
+ Properties that come from master build file
+ - build.dir: root directory for build
+ - build.debug: true if building debug release
+ - build.defines: variables to define during build
+ -->
+
+ <target name="build">
+ <csc target="exe"
+ define="${build.defines}"
+ debug="${build.debug}"
+ output="${build.dir}/${project::get-name()}.exe">
+
+ <sources>
+ <include name="**/*.cs" />
+ </sources>
+ <references>
+ <include name="${build.dir}/log4net.dll" />
+ <include name="${build.dir}/qpid.client.dll" />
+ <include name="System.Configuration.dll" />
+ </references>
+ </csc>
+ </target>
+</project>
+
diff --git a/qpid/dotnet/client-010/examples/pub-sub/example-pub-sub-Listener/example-pub-sub-Listener.csproj b/qpid/dotnet/client-010/examples/pub-sub/example-pub-sub-Listener/example-pub-sub-Listener.csproj
new file mode 100644
index 0000000000..851faa7f21
--- /dev/null
+++ b/qpid/dotnet/client-010/examples/pub-sub/example-pub-sub-Listener/example-pub-sub-Listener.csproj
@@ -0,0 +1,85 @@
+<?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.
+ -
+ -->
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProductVersion>9.0.30729</ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{2BCDC2CC-5BDA-4CC7-944D-2899AD8A53C7}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>example_pub_sub_Listener</RootNamespace>
+ <AssemblyName>example-pub-sub-Listener</AssemblyName>
+ <FileUpgradeFlags>
+ </FileUpgradeFlags>
+ <OldToolsVersion>2.0</OldToolsVersion>
+ <UpgradeBackupLocation>
+ </UpgradeBackupLocation>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="System" />
+ <Reference Include="System.configuration" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="Listener.cs" />
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\..\..\client\Client.csproj">
+ <Project>{B911FFD7-754F-4735-A188-218D5065BE79}</Project>
+ <Name>Client</Name>
+ </ProjectReference>
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="..\..\..\App.config">
+ <Link>App.config</Link>
+ </None>
+ </ItemGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+ <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
+ Other similar extension points exist, see Microsoft.Common.targets.
+ <Target Name="BeforeBuild">
+ </Target>
+ <Target Name="AfterBuild">
+ </Target>
+ -->
+</Project>
diff --git a/qpid/dotnet/client-010/examples/pub-sub/example-pub-sub-Publisher/Properties/AssemblyInfo.cs b/qpid/dotnet/client-010/examples/pub-sub/example-pub-sub-Publisher/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000000..b6d7f3c818
--- /dev/null
+++ b/qpid/dotnet/client-010/examples/pub-sub/example-pub-sub-Publisher/Properties/AssemblyInfo.cs
@@ -0,0 +1,54 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("example-pub-sub-Publisher")]
+[assembly: AssemblyDescription("Built from svn revision number: ")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Apache Software Foundation")]
+[assembly: AssemblyProduct("example-pub-sub-Publisher")]
+[assembly: AssemblyCopyright("Apache Software Foundation")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("f6d282a0-9dc5-46cf-a4cd-44ae402d667f")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+[assembly: AssemblyVersion("0.5.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/qpid/dotnet/client-010/examples/pub-sub/example-pub-sub-Publisher/Publisher.cs b/qpid/dotnet/client-010/examples/pub-sub/example-pub-sub-Publisher/Publisher.cs
new file mode 100644
index 0000000000..c87985d288
--- /dev/null
+++ b/qpid/dotnet/client-010/examples/pub-sub/example-pub-sub-Publisher/Publisher.cs
@@ -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.
+*/
+
+using System;
+using System.Configuration;
+using System.Text;
+using org.apache.qpid.client;
+
+namespace org.apache.qpid.example.pubsub
+{
+ /// <summary>
+ /// This program is one of two programs designed to be used
+ /// together. These programs use the topic exchange.
+ ///
+ /// Publisher (this program):
+ ///
+ /// Publishes to a broker, specifying a routing key.
+ ///
+ /// Listener:
+ ///
+ /// Reads from a queue on the broker using a message listener.
+ ///
+ /// </summary>
+ internal class Publisher
+ {
+ private static void Main(string[] args)
+ {
+ string host = ConfigurationManager.AppSettings["Host"];
+ int port = int.Parse(ConfigurationManager.AppSettings["Port"]);
+ string virtualhost = ConfigurationManager.AppSettings["VirtualHost"];
+ string username = ConfigurationManager.AppSettings["Username"];
+ string password = ConfigurationManager.AppSettings["Password"];
+
+ Client connection = new Client();
+ try
+ {
+ connection.Connect(host, port, virtualhost, username, password);
+ IClientSession session = connection.CreateSession(50000);
+
+ //--------- Main body of program --------------------------------------------
+
+ publishMessages(session, "usa.news");
+ publishMessages(session, "usa.weather");
+ publishMessages(session, "europe.news");
+ publishMessages(session, "europe.weather");
+
+ noMoreMessages(session);
+
+ //-----------------------------------------------------------------------------
+
+ connection.Close();
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine("Error: \n" + e.StackTrace);
+ }
+ }
+
+ private static void publishMessages(IClientSession session, string routing_key)
+ {
+ IMessage message = new Message();
+ // Asynchronous transfer sends messages as quickly as
+ // possible without waiting for confirmation.
+ for (int i = 0; i < 10; i++)
+ {
+ message.ClearData();
+ message.AppendData(Encoding.UTF8.GetBytes("Message " + i));
+ session.MessageTransfer("amq.topic", routing_key, message);
+ }
+ }
+
+ private static void noMoreMessages(IClientSession session)
+ {
+ IMessage message = new Message();
+ // And send a syncrhonous final message to indicate termination.
+ message.ClearData();
+ message.AppendData(Encoding.UTF8.GetBytes("That's all, folks!"));
+ session.MessageTransfer("amq.topic", "control", message);
+ session.Sync();
+ }
+ }
+}
diff --git a/qpid/dotnet/client-010/examples/pub-sub/example-pub-sub-Publisher/default.build b/qpid/dotnet/client-010/examples/pub-sub/example-pub-sub-Publisher/default.build
new file mode 100644
index 0000000000..3f270afe9e
--- /dev/null
+++ b/qpid/dotnet/client-010/examples/pub-sub/example-pub-sub-Publisher/default.build
@@ -0,0 +1,48 @@
+<?xml version="1.0"?>
+<!--
+
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+
+-->
+
+<project name="example-pub-sub-Publisher" default="build">
+ <!--
+ Properties that come from master build file
+ - build.dir: root directory for build
+ - build.debug: true if building debug release
+ - build.defines: variables to define during build
+ -->
+
+ <target name="build">
+ <csc target="exe"
+ define="${build.defines}"
+ debug="${build.debug}"
+ output="${build.dir}/${project::get-name()}.exe">
+
+ <sources>
+ <include name="**/*.cs" />
+ </sources>
+ <references>
+ <include name="${build.dir}/log4net.dll" />
+ <include name="${build.dir}/qpid.client.dll" />
+ <include name="System.Configuration.dll" />
+ </references>
+ </csc>
+ </target>
+</project>
+
diff --git a/qpid/dotnet/client-010/examples/pub-sub/example-pub-sub-Publisher/example-pub-sub-Publisher.csproj b/qpid/dotnet/client-010/examples/pub-sub/example-pub-sub-Publisher/example-pub-sub-Publisher.csproj
new file mode 100644
index 0000000000..a9dee76a36
--- /dev/null
+++ b/qpid/dotnet/client-010/examples/pub-sub/example-pub-sub-Publisher/example-pub-sub-Publisher.csproj
@@ -0,0 +1,85 @@
+<?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.
+ -
+ -->
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProductVersion>9.0.30729</ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{F8857634-A134-44E7-A953-F2B22688C599}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>example_pub_sub_Publisher</RootNamespace>
+ <AssemblyName>example-pub-sub-Publisher</AssemblyName>
+ <FileUpgradeFlags>
+ </FileUpgradeFlags>
+ <OldToolsVersion>2.0</OldToolsVersion>
+ <UpgradeBackupLocation>
+ </UpgradeBackupLocation>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="System" />
+ <Reference Include="System.configuration" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="Publisher.cs" />
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\..\..\client\Client.csproj">
+ <Project>{B911FFD7-754F-4735-A188-218D5065BE79}</Project>
+ <Name>Client</Name>
+ </ProjectReference>
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="..\..\..\App.config">
+ <Link>App.config</Link>
+ </None>
+ </ItemGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+ <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
+ Other similar extension points exist, see Microsoft.Common.targets.
+ <Target Name="BeforeBuild">
+ </Target>
+ <Target Name="AfterBuild">
+ </Target>
+ -->
+</Project>
diff --git a/qpid/dotnet/client-010/examples/pub-sub/verify b/qpid/dotnet/client-010/examples/pub-sub/verify
new file mode 100644
index 0000000000..45d80c4866
--- /dev/null
+++ b/qpid/dotnet/client-010/examples/pub-sub/verify
@@ -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.
+#
+#
+
+# See https://svn.apache.org/repos/asf/incubator/qpid/trunk/qpid/bin/verify
+
+pubsub_listener_dotnet()
+{
+mono $DOTNET_EXAMPLES/example-pub-sub-Listener.exe localhost 5672
+}
+
+pubsub_producer_dotnet()
+{
+mono $DOTNET_EXAMPLES/example-pub-sub-Publisher.exe localhost 5672
+}
+
+background "Listening for messages ..." pubsub_listener_dotnet
+clients pubsub_producer_dotnet
+outputs pubsub_producer_dotnet.out "pubsub_listener_dotnet.out | remove_uuid | sort"
diff --git a/qpid/dotnet/client-010/examples/pub-sub/verify.in b/qpid/dotnet/client-010/examples/pub-sub/verify.in
new file mode 100644
index 0000000000..6a5adc4d89
--- /dev/null
+++ b/qpid/dotnet/client-010/examples/pub-sub/verify.in
@@ -0,0 +1,95 @@
+==== pubsub_producer_dotnet.out
+==== pubsub_listener_dotnet.out | remove_uuid | sort
+Declaring queue: europe
+Declaring queue: news
+Declaring queue: usa
+Declaring queue: weather
+Listening for messages ...
+Message: Message 0 from europe
+Message: Message 0 from europe
+Message: Message 0 from news
+Message: Message 0 from news
+Message: Message 0 from usa
+Message: Message 0 from usa
+Message: Message 0 from weather
+Message: Message 0 from weather
+Message: Message 1 from europe
+Message: Message 1 from europe
+Message: Message 1 from news
+Message: Message 1 from news
+Message: Message 1 from usa
+Message: Message 1 from usa
+Message: Message 1 from weather
+Message: Message 1 from weather
+Message: Message 2 from europe
+Message: Message 2 from europe
+Message: Message 2 from news
+Message: Message 2 from news
+Message: Message 2 from usa
+Message: Message 2 from usa
+Message: Message 2 from weather
+Message: Message 2 from weather
+Message: Message 3 from europe
+Message: Message 3 from europe
+Message: Message 3 from news
+Message: Message 3 from news
+Message: Message 3 from usa
+Message: Message 3 from usa
+Message: Message 3 from weather
+Message: Message 3 from weather
+Message: Message 4 from europe
+Message: Message 4 from europe
+Message: Message 4 from news
+Message: Message 4 from news
+Message: Message 4 from usa
+Message: Message 4 from usa
+Message: Message 4 from weather
+Message: Message 4 from weather
+Message: Message 5 from europe
+Message: Message 5 from europe
+Message: Message 5 from news
+Message: Message 5 from news
+Message: Message 5 from usa
+Message: Message 5 from usa
+Message: Message 5 from weather
+Message: Message 5 from weather
+Message: Message 6 from europe
+Message: Message 6 from europe
+Message: Message 6 from news
+Message: Message 6 from news
+Message: Message 6 from usa
+Message: Message 6 from usa
+Message: Message 6 from weather
+Message: Message 6 from weather
+Message: Message 7 from europe
+Message: Message 7 from europe
+Message: Message 7 from news
+Message: Message 7 from news
+Message: Message 7 from usa
+Message: Message 7 from usa
+Message: Message 7 from weather
+Message: Message 7 from weather
+Message: Message 8 from europe
+Message: Message 8 from europe
+Message: Message 8 from news
+Message: Message 8 from news
+Message: Message 8 from usa
+Message: Message 8 from usa
+Message: Message 8 from weather
+Message: Message 8 from weather
+Message: Message 9 from europe
+Message: Message 9 from europe
+Message: Message 9 from news
+Message: Message 9 from news
+Message: Message 9 from usa
+Message: Message 9 from usa
+Message: Message 9 from weather
+Message: Message 9 from weather
+Message: That's all, folks! from europe
+Message: That's all, folks! from news
+Message: That's all, folks! from usa
+Message: That's all, folks! from weather
+Shutting down listener for control
+Shutting down listener for control
+Shutting down listener for control
+Shutting down listener for control
diff --git a/qpid/dotnet/client-010/examples/pub-sub/verify_cpp_dotnet b/qpid/dotnet/client-010/examples/pub-sub/verify_cpp_dotnet
new file mode 100644
index 0000000000..39d92cbb8b
--- /dev/null
+++ b/qpid/dotnet/client-010/examples/pub-sub/verify_cpp_dotnet
@@ -0,0 +1,31 @@
+#
+# 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.
+#
+
+# See https://svn.apache.org/repos/asf/incubator/qpid/trunk/qpid/bin/verify
+cpp=$CPP/pub-sub
+
+pubsub_listener_dotnet()
+{
+mono $DOTNET_EXAMPLES/example-pub-sub-Listener.exe localhost 5672
+}
+
+
+background "Listening for messages ..." pubsub_listener_dotnet
+clients $cpp/topic_publisher
+outputs $cpp/topic_publisher.out "pubsub_listener_dotnet.out | remove_uuid | sort"
diff --git a/qpid/dotnet/client-010/examples/pub-sub/verify_cpp_dotnet.in b/qpid/dotnet/client-010/examples/pub-sub/verify_cpp_dotnet.in
new file mode 100644
index 0000000000..4e058f7645
--- /dev/null
+++ b/qpid/dotnet/client-010/examples/pub-sub/verify_cpp_dotnet.in
@@ -0,0 +1,55 @@
+==== topic_publisher.out
+==== pubsub_listener_dotnet.out | remove_uuid | sort
+Declaring queue: europe
+Declaring queue: news
+Declaring queue: usa
+Declaring queue: weather
+Listening for messages ...
+Message: Message 0 from europe
+Message: Message 0 from europe
+Message: Message 0 from news
+Message: Message 0 from news
+Message: Message 0 from usa
+Message: Message 0 from usa
+Message: Message 0 from weather
+Message: Message 0 from weather
+Message: Message 1 from europe
+Message: Message 1 from europe
+Message: Message 1 from news
+Message: Message 1 from news
+Message: Message 1 from usa
+Message: Message 1 from usa
+Message: Message 1 from weather
+Message: Message 1 from weather
+Message: Message 2 from europe
+Message: Message 2 from europe
+Message: Message 2 from news
+Message: Message 2 from news
+Message: Message 2 from usa
+Message: Message 2 from usa
+Message: Message 2 from weather
+Message: Message 2 from weather
+Message: Message 3 from europe
+Message: Message 3 from europe
+Message: Message 3 from news
+Message: Message 3 from news
+Message: Message 3 from usa
+Message: Message 3 from usa
+Message: Message 3 from weather
+Message: Message 3 from weather
+Message: Message 4 from europe
+Message: Message 4 from europe
+Message: Message 4 from news
+Message: Message 4 from news
+Message: Message 4 from usa
+Message: Message 4 from usa
+Message: Message 4 from weather
+Message: Message 4 from weather
+Message: That's all, folks! from europe
+Message: That's all, folks! from news
+Message: That's all, folks! from usa
+Message: That's all, folks! from weather
+Shutting down listener for control
+Shutting down listener for control
+Shutting down listener for control
+Shutting down listener for control
diff --git a/qpid/dotnet/client-010/examples/pub-sub/verify_dotnet_cpp b/qpid/dotnet/client-010/examples/pub-sub/verify_dotnet_cpp
new file mode 100644
index 0000000000..bf99e422a1
--- /dev/null
+++ b/qpid/dotnet/client-010/examples/pub-sub/verify_dotnet_cpp
@@ -0,0 +1,30 @@
+#
+# 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.
+#
+
+# See https://svn.apache.org/repos/asf/incubator/qpid/trunk/qpid/bin/verify
+cpp=$CPP/pub-sub
+
+pubsub_producer_dotnet()
+{
+mono $DOTNET_EXAMPLES/example-pub-sub-Publisher.exe localhost 5672
+}
+
+background "Listening" $cpp/topic_listener
+clients pubsub_producer_dotnet
+outputs pubsub_producer_dotnet.out "$cpp/topic_listener.out | remove_uuid | sort"
diff --git a/qpid/dotnet/client-010/examples/pub-sub/verify_dotnet_cpp.in b/qpid/dotnet/client-010/examples/pub-sub/verify_dotnet_cpp.in
new file mode 100644
index 0000000000..64ac27846d
--- /dev/null
+++ b/qpid/dotnet/client-010/examples/pub-sub/verify_dotnet_cpp.in
@@ -0,0 +1,99 @@
+==== pubsub_producer_dotnet.out
+==== topic_listener.out | remove_uuid | sort
+Declaring queue: europe
+Declaring queue: news
+Declaring queue: usa
+Declaring queue: weather
+Listening for messages ...
+Message: Message 0 from europe
+Message: Message 0 from europe
+Message: Message 0 from news
+Message: Message 0 from news
+Message: Message 0 from usa
+Message: Message 0 from usa
+Message: Message 0 from weather
+Message: Message 0 from weather
+Message: Message 1 from europe
+Message: Message 1 from europe
+Message: Message 1 from news
+Message: Message 1 from news
+Message: Message 1 from usa
+Message: Message 1 from usa
+Message: Message 1 from weather
+Message: Message 1 from weather
+Message: Message 2 from europe
+Message: Message 2 from europe
+Message: Message 2 from news
+Message: Message 2 from news
+Message: Message 2 from usa
+Message: Message 2 from usa
+Message: Message 2 from weather
+Message: Message 2 from weather
+Message: Message 3 from europe
+Message: Message 3 from europe
+Message: Message 3 from news
+Message: Message 3 from news
+Message: Message 3 from usa
+Message: Message 3 from usa
+Message: Message 3 from weather
+Message: Message 3 from weather
+Message: Message 4 from europe
+Message: Message 4 from europe
+Message: Message 4 from news
+Message: Message 4 from news
+Message: Message 4 from usa
+Message: Message 4 from usa
+Message: Message 4 from weather
+Message: Message 4 from weather
+Message: Message 5 from europe
+Message: Message 5 from europe
+Message: Message 5 from news
+Message: Message 5 from news
+Message: Message 5 from usa
+Message: Message 5 from usa
+Message: Message 5 from weather
+Message: Message 5 from weather
+Message: Message 6 from europe
+Message: Message 6 from europe
+Message: Message 6 from news
+Message: Message 6 from news
+Message: Message 6 from usa
+Message: Message 6 from usa
+Message: Message 6 from weather
+Message: Message 6 from weather
+Message: Message 7 from europe
+Message: Message 7 from europe
+Message: Message 7 from news
+Message: Message 7 from news
+Message: Message 7 from usa
+Message: Message 7 from usa
+Message: Message 7 from weather
+Message: Message 7 from weather
+Message: Message 8 from europe
+Message: Message 8 from europe
+Message: Message 8 from news
+Message: Message 8 from news
+Message: Message 8 from usa
+Message: Message 8 from usa
+Message: Message 8 from weather
+Message: Message 8 from weather
+Message: Message 9 from europe
+Message: Message 9 from europe
+Message: Message 9 from news
+Message: Message 9 from news
+Message: Message 9 from usa
+Message: Message 9 from usa
+Message: Message 9 from weather
+Message: Message 9 from weather
+Message: That's all, folks! from europe
+Message: That's all, folks! from news
+Message: That's all, folks! from usa
+Message: That's all, folks! from weather
+Shutting down listener for europe
+Shutting down listener for news
+Shutting down listener for usa
+Shutting down listener for weather
+Subscribing to queue europe
+Subscribing to queue news
+Subscribing to queue usa
+Subscribing to queue weather
diff --git a/qpid/dotnet/client-010/examples/request-response/example-request-response-Client/Properties/AssemblyInfo.cs b/qpid/dotnet/client-010/examples/request-response/example-request-response-Client/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000000..a438acaa1f
--- /dev/null
+++ b/qpid/dotnet/client-010/examples/request-response/example-request-response-Client/Properties/AssemblyInfo.cs
@@ -0,0 +1,54 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("example-request-response-Client")]
+[assembly: AssemblyDescription("Built from svn revision number: ")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Apache Software Foundation")]
+[assembly: AssemblyProduct("example-request-response-Client")]
+[assembly: AssemblyCopyright("Apache Software Foundation")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("08bf6aed-bf79-4d16-9a28-6363d5322cdd")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+[assembly: AssemblyVersion("0.5.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/qpid/dotnet/client-010/examples/request-response/example-request-response-Client/RequestResponseClient.cs b/qpid/dotnet/client-010/examples/request-response/example-request-response-Client/RequestResponseClient.cs
new file mode 100644
index 0000000000..170008c840
--- /dev/null
+++ b/qpid/dotnet/client-010/examples/request-response/example-request-response-Client/RequestResponseClient.cs
@@ -0,0 +1,142 @@
+/*
+* 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.
+*/
+
+using System;
+using System.Configuration;
+using System.IO;
+using System.Text;
+using System.Threading;
+using org.apache.qpid.client;
+using org.apache.qpid.transport;
+
+namespace org.apache.qpid.example.requestresponse
+{
+ /// <summary>
+ /// This program is one of two programs that illustrate the
+ /// request/response pattern.
+ ///
+ /// Client (this program):
+ /// Make requests of a service, print the response.
+ ///
+ /// Server:
+ /// Accept requests, set the letters to uppercase in each message, and
+ /// return it as a response.
+ ///
+ /// </summary>
+ internal class RequestResponseClient
+ {
+ private static void Main(string[] args)
+ {
+ string host = ConfigurationManager.AppSettings["Host"];
+ int port = int.Parse(ConfigurationManager.AppSettings["Port"]);
+ string virtualhost = ConfigurationManager.AppSettings["VirtualHost"];
+ string username = ConfigurationManager.AppSettings["Username"];
+ string password = ConfigurationManager.AppSettings["Password"];
+
+ Client connection = new Client();
+ try
+ {
+ connection.Connect(host, port, virtualhost, username, password);
+ IClientSession session = connection.CreateSession(50000);
+ IMessage request = new Message();
+
+ //--------- Main body of program --------------------------------------------
+ // Create a response queue so the server can send us responses
+ // to our requests. Use the client's session ID as the name
+ // of the response queue.
+ string response_queue = "client" + session.GetName();
+ // Use the name of the response queue as the routing key
+ session.QueueDeclare(response_queue);
+ session.ExchangeBind(response_queue, "amq.direct", response_queue);
+
+ // Each client sends the name of their own response queue so
+ // the service knows where to route messages.
+ request.DeliveryProperties.SetRoutingKey("request");
+ request.MessageProperties.SetReplyTo(new ReplyTo("amq.direct", response_queue));
+
+ lock (session)
+ {
+ // Create a listener for the response queue and listen for response messages.
+ Console.WriteLine("Activating response queue listener for: " + response_queue);
+ IMessageListener listener = new ClientMessageListener(session);
+ session.AttachMessageListener(listener, response_queue);
+ session.MessageSubscribe(response_queue);
+
+ // Now send some requests ...
+ string[] strs = {
+ "Twas brillig, and the slithy toves",
+ "Did gire and gymble in the wabe.",
+ "All mimsy were the borogroves,",
+ "And the mome raths outgrabe.",
+ "That's all, folks!"
+ };
+ foreach (string s in strs)
+ {
+ request.ClearData();
+ request.AppendData(Encoding.UTF8.GetBytes(s));
+ session.MessageTransfer("amq.direct", request);
+ }
+ Console.WriteLine("Waiting for all responses to arrive ...");
+ Monitor.Wait(session);
+ }
+ //---------------------------------------------------------------------------
+
+ connection.Close();
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine("Error: \n" + e.StackTrace);
+ }
+ }
+ }
+
+ public class ClientMessageListener : IMessageListener
+ {
+ private readonly IClientSession _session;
+ private readonly RangeSet _range = new RangeSet();
+ private int _counter;
+ public ClientMessageListener(IClientSession session)
+ {
+ _session = session;
+ }
+
+ public void MessageTransfer(IMessage m)
+ {
+ _counter++;
+ BinaryReader reader = new BinaryReader(m.Body, Encoding.UTF8);
+ byte[] body = new byte[m.Body.Length - m.Body.Position];
+ reader.Read(body, 0, body.Length);
+ ASCIIEncoding enc = new ASCIIEncoding();
+ string message = enc.GetString(body);
+ Console.WriteLine("Response: " + message);
+ // Add this message to the list of message to be acknowledged
+ _range.Add(m.Id);
+ if (_counter == 4)
+ {
+ Console.WriteLine("Shutting down listener for " + m.DeliveryProperties.GetRoutingKey());
+ // Acknowledge all the received messages
+ _session.MessageAccept(_range);
+ lock (_session)
+ {
+ Monitor.Pulse(_session);
+ }
+ }
+ }
+ }
+}
diff --git a/qpid/dotnet/client-010/examples/request-response/example-request-response-Client/default.build b/qpid/dotnet/client-010/examples/request-response/example-request-response-Client/default.build
new file mode 100644
index 0000000000..c3d9af9baf
--- /dev/null
+++ b/qpid/dotnet/client-010/examples/request-response/example-request-response-Client/default.build
@@ -0,0 +1,48 @@
+<?xml version="1.0"?>
+<!--
+
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+
+-->
+
+<project name="example-request-response-Client" default="build">
+ <!--
+ Properties that come from master build file
+ - build.dir: root directory for build
+ - build.debug: true if building debug release
+ - build.defines: variables to define during build
+ -->
+
+ <target name="build">
+ <csc target="exe"
+ define="${build.defines}"
+ debug="${build.debug}"
+ output="${build.dir}/${project::get-name()}.exe">
+
+ <sources>
+ <include name="**/*.cs" />
+ </sources>
+ <references>
+ <include name="${build.dir}/log4net.dll" />
+ <include name="${build.dir}/qpid.client.dll" />
+ <include name="System.Configuration.dll" />
+ </references>
+ </csc>
+ </target>
+</project>
+
diff --git a/qpid/dotnet/client-010/examples/request-response/example-request-response-Client/example-request-response-Client.csproj b/qpid/dotnet/client-010/examples/request-response/example-request-response-Client/example-request-response-Client.csproj
new file mode 100644
index 0000000000..21dc6ceed4
--- /dev/null
+++ b/qpid/dotnet/client-010/examples/request-response/example-request-response-Client/example-request-response-Client.csproj
@@ -0,0 +1,85 @@
+<?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.
+ -
+ -->
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProductVersion>9.0.30729</ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{1BC63815-4029-4039-9207-35E7E06ECC99}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>example_request_response_Client</RootNamespace>
+ <AssemblyName>example-request-response-Client</AssemblyName>
+ <FileUpgradeFlags>
+ </FileUpgradeFlags>
+ <OldToolsVersion>2.0</OldToolsVersion>
+ <UpgradeBackupLocation>
+ </UpgradeBackupLocation>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="System" />
+ <Reference Include="System.configuration" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="RequestResponseClient.cs" />
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\..\..\client\Client.csproj">
+ <Project>{B911FFD7-754F-4735-A188-218D5065BE79}</Project>
+ <Name>Client</Name>
+ </ProjectReference>
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="..\..\..\App.config">
+ <Link>App.config</Link>
+ </None>
+ </ItemGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+ <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
+ Other similar extension points exist, see Microsoft.Common.targets.
+ <Target Name="BeforeBuild">
+ </Target>
+ <Target Name="AfterBuild">
+ </Target>
+ -->
+</Project>
diff --git a/qpid/dotnet/client-010/examples/request-response/example-request-response-Server/Properties/AssemblyInfo.cs b/qpid/dotnet/client-010/examples/request-response/example-request-response-Server/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000000..ba702a28cc
--- /dev/null
+++ b/qpid/dotnet/client-010/examples/request-response/example-request-response-Server/Properties/AssemblyInfo.cs
@@ -0,0 +1,54 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("example-request-response-Server")]
+[assembly: AssemblyDescription("Built from svn revision number: ")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Apache Software Foundation")]
+[assembly: AssemblyProduct("example-request-response-Server")]
+[assembly: AssemblyCopyright("Apache Software Foundation")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("ef3456e2-7c19-47aa-8dd6-aeaa88c5c4ad")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+[assembly: AssemblyVersion("0.5.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/qpid/dotnet/client-010/examples/request-response/example-request-response-Server/Server.cs b/qpid/dotnet/client-010/examples/request-response/example-request-response-Server/Server.cs
new file mode 100644
index 0000000000..ea87627dbf
--- /dev/null
+++ b/qpid/dotnet/client-010/examples/request-response/example-request-response-Server/Server.cs
@@ -0,0 +1,141 @@
+/*
+* 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.
+*/
+
+using System;
+using System.Configuration;
+using System.IO;
+using System.Text;
+using System.Threading;
+using org.apache.qpid.client;
+using org.apache.qpid.transport;
+
+namespace org.apache.qpid.example.requestresponse
+{
+ /// <summary>
+ /// This program is one of two programs that illustrate the
+ /// request/response pattern.
+ ///
+ /// Client:
+ /// Make requests of a service, print the response.
+ ///
+ /// Server (this program):
+ /// Accept requests, set the letters to uppercase in each message, and
+ /// return it as a response.
+ ///
+ /// </summary>
+ class Server
+ {
+ static void Main(string[] args)
+ {
+ string host = ConfigurationManager.AppSettings["Host"];
+ int port = int.Parse(ConfigurationManager.AppSettings["Port"]);
+ string virtualhost = ConfigurationManager.AppSettings["VirtualHost"];
+ string username = ConfigurationManager.AppSettings["Username"];
+ string password = ConfigurationManager.AppSettings["Password"];
+
+ Client connection = new Client();
+ try
+ {
+ connection.Connect(host, port, virtualhost, username, password);
+ IClientSession session = connection.CreateSession(50000);
+
+ //--------- Main body of program --------------------------------------------
+ // Create a request queue for clients to use when making
+ // requests.
+ const string request_queue = "request";
+ // Use the name of the request queue as the routing key
+ session.QueueDeclare(request_queue);
+ session.ExchangeBind(request_queue, "amq.direct", request_queue);
+
+ lock (session)
+ {
+ // Create a listener and subscribe it to the request_queue
+ IMessageListener listener = new MessageListener(session);
+ session.AttachMessageListener(listener, request_queue);
+ session.MessageSubscribe(request_queue);
+ // Receive messages until all messages are received
+ Console.WriteLine("Waiting for requests");
+ Monitor.Wait(session);
+ }
+
+ //---------------------------------------------------------------------------
+
+ connection.Close();
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine("Error: \n" + e.StackTrace);
+ }
+ }
+ }
+
+ public class MessageListener : IMessageListener
+ {
+ private readonly IClientSession _session;
+ private readonly RangeSet _range = new RangeSet();
+ public MessageListener(IClientSession session)
+ {
+ _session = session;
+ }
+
+ public void MessageTransfer(IMessage request)
+ {
+ IMessage response = new Message();
+
+ // Get routing key for response from the request's replyTo property
+ string routingKey;
+ if( request.MessageProperties.HasReplyTo() )
+ {
+ routingKey = request.MessageProperties.GetReplyTo().GetRoutingKey();
+ }
+ else
+ {
+ Console.WriteLine("Error: \n No routing key for request " + request);
+ return;
+ }
+
+ BinaryReader reader = new BinaryReader(request.Body, Encoding.UTF8);
+ byte[] body = new byte[request.Body.Length - request.Body.Position];
+ reader.Read(body, 0, body.Length);
+ ASCIIEncoding enc = new ASCIIEncoding();
+ string message = enc.GetString(body);
+ Console.WriteLine("Request: " + message);
+
+ // Transform message content to upper case
+ string responseBody = message.ToUpper();
+
+ // Send it back to the user
+ response.ClearData();
+ response.AppendData(Encoding.UTF8.GetBytes(responseBody));
+ _session.MessageTransfer("amq.direct", routingKey, response);
+
+ // Add this message to the list of message to be acknowledged
+ _range.Add(request.Id);
+ if (message.Equals("That's all, folks!"))
+ {
+ // Acknowledge all the received messages
+ _session.MessageAccept(_range);
+ lock (_session)
+ {
+ Monitor.Pulse(_session);
+ }
+ }
+ }
+ }
+}
diff --git a/qpid/dotnet/client-010/examples/request-response/example-request-response-Server/default.build b/qpid/dotnet/client-010/examples/request-response/example-request-response-Server/default.build
new file mode 100644
index 0000000000..a3e4691d10
--- /dev/null
+++ b/qpid/dotnet/client-010/examples/request-response/example-request-response-Server/default.build
@@ -0,0 +1,48 @@
+<?xml version="1.0"?>
+<!--
+
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+
+-->
+
+<project name="example-request-response-Server" default="build">
+ <!--
+ Properties that come from master build file
+ - build.dir: root directory for build
+ - build.debug: true if building debug release
+ - build.defines: variables to define during build
+ -->
+
+ <target name="build">
+ <csc target="exe"
+ define="${build.defines}"
+ debug="${build.debug}"
+ output="${build.dir}/${project::get-name()}.exe">
+
+ <sources>
+ <include name="**/*.cs" />
+ </sources>
+ <references>
+ <include name="${build.dir}/log4net.dll" />
+ <include name="${build.dir}/qpid.client.dll" />
+ <include name="System.Configuration.dll" />
+ </references>
+ </csc>
+ </target>
+</project>
+
diff --git a/qpid/dotnet/client-010/examples/request-response/example-request-response-Server/example-request-response-Server.csproj b/qpid/dotnet/client-010/examples/request-response/example-request-response-Server/example-request-response-Server.csproj
new file mode 100644
index 0000000000..3eb2a3c035
--- /dev/null
+++ b/qpid/dotnet/client-010/examples/request-response/example-request-response-Server/example-request-response-Server.csproj
@@ -0,0 +1,85 @@
+<?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.
+ -
+ -->
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProductVersion>9.0.30729</ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{922FBA9C-E483-4AEF-ABE8-AC87421E829B}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>example_request_response_Server</RootNamespace>
+ <AssemblyName>example-request-response-Server</AssemblyName>
+ <FileUpgradeFlags>
+ </FileUpgradeFlags>
+ <OldToolsVersion>2.0</OldToolsVersion>
+ <UpgradeBackupLocation>
+ </UpgradeBackupLocation>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="System" />
+ <Reference Include="System.configuration" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="Server.cs" />
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\..\..\client\Client.csproj">
+ <Project>{B911FFD7-754F-4735-A188-218D5065BE79}</Project>
+ <Name>Client</Name>
+ </ProjectReference>
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="..\..\..\App.config">
+ <Link>App.config</Link>
+ </None>
+ </ItemGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+ <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
+ Other similar extension points exist, see Microsoft.Common.targets.
+ <Target Name="BeforeBuild">
+ </Target>
+ <Target Name="AfterBuild">
+ </Target>
+ -->
+</Project>
diff --git a/qpid/dotnet/client-010/examples/request-response/verify b/qpid/dotnet/client-010/examples/request-response/verify
new file mode 100644
index 0000000000..fa69461f68
--- /dev/null
+++ b/qpid/dotnet/client-010/examples/request-response/verify
@@ -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.
+#
+#
+
+# See https://svn.apache.org/repos/asf/incubator/qpid/trunk/qpid/bin/verify
+
+server_dotnet()
+{
+mono $DOTNET_EXAMPLES/example-request-response-Server.exe localhost 5672
+}
+
+client_dotnet()
+{
+mono $DOTNET_EXAMPLES/example-request-response-Client.exe localhost 5672
+}
+
+background "Waiting for requests" server_dotnet
+clients client_dotnet
+outputs ./server_dotnet.out ./client_dotnet.out
diff --git a/qpid/dotnet/client-010/examples/request-response/verify.in b/qpid/dotnet/client-010/examples/request-response/verify.in
new file mode 100644
index 0000000000..5357591289
--- /dev/null
+++ b/qpid/dotnet/client-010/examples/request-response/verify.in
@@ -0,0 +1,16 @@
+==== server_dotnet.out
+Waiting for requests
+Request: Twas brillig, and the slithy toves
+Request: Did gire and gymble in the wabe.
+Request: All mimsy were the borogroves,
+Request: And the mome raths outgrabe.
+Request: That's all, folks!
+==== client_dotnet.out
+Activating response queue listener for: clientSystem.Byte[]
+Waiting for all responses to arrive ...
+Response: TWAS BRILLIG, AND THE SLITHY TOVES
+Response: DID GIRE AND GYMBLE IN THE WABE.
+Response: ALL MIMSY WERE THE BOROGROVES,
+Response: AND THE MOME RATHS OUTGRABE.
+Shutting down listener for clientSystem.Byte[]
+Response: THAT'S ALL, FOLKS!
diff --git a/qpid/dotnet/client-010/examples/request-response/verify_cpp_dotnet b/qpid/dotnet/client-010/examples/request-response/verify_cpp_dotnet
new file mode 100644
index 0000000000..791f48fe60
--- /dev/null
+++ b/qpid/dotnet/client-010/examples/request-response/verify_cpp_dotnet
@@ -0,0 +1,31 @@
+#
+# 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.
+#
+
+# See https://svn.apache.org/repos/asf/incubator/qpid/trunk/qpid/bin/verify
+cpp=$CPP/request-response
+
+client_dotnet()
+{
+mono $DOTNET_EXAMPLES/example-request-response-Client.exe localhost 5672
+}
+
+background "Waiting" $cpp/server
+clients client_dotnet
+kill %%
+outputs ./client_dotnet.out "$cpp/server.out | remove_uuid"
diff --git a/qpid/dotnet/client-010/examples/request-response/verify_cpp_dotnet.in b/qpid/dotnet/client-010/examples/request-response/verify_cpp_dotnet.in
new file mode 100644
index 0000000000..0f4b5341b2
--- /dev/null
+++ b/qpid/dotnet/client-010/examples/request-response/verify_cpp_dotnet.in
@@ -0,0 +1,17 @@
+==== client_dotnet.out
+Activating response queue listener for: clientSystem.Byte[]
+Waiting for all responses to arrive ...
+Response: TWAS BRILLIG, AND THE SLITHY TOVES
+Response: DID GIRE AND GYMBLE IN THE WABE.
+Response: ALL MIMSY WERE THE BOROGROVES,
+Response: AND THE MOME RATHS OUTGRABE.
+Shutting down listener for clientSystem.Byte[]
+Response: THAT'S ALL, FOLKS!
+==== server.out | remove_uuid
+Activating request queue listener for: request
+Waiting for requests
+Request: Twas brillig, and the slithy toves (clientSystem.Byte[])
+Request: Did gire and gymble in the wabe. (clientSystem.Byte[])
+Request: All mimsy were the borogroves, (clientSystem.Byte[])
+Request: And the mome raths outgrabe. (clientSystem.Byte[])
+Request: That's all, folks! (clientSystem.Byte[])
diff --git a/qpid/dotnet/client-010/examples/request-response/verify_dotnet_cpp b/qpid/dotnet/client-010/examples/request-response/verify_dotnet_cpp
new file mode 100644
index 0000000000..95905c43c9
--- /dev/null
+++ b/qpid/dotnet/client-010/examples/request-response/verify_dotnet_cpp
@@ -0,0 +1,31 @@
+#
+# 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.
+#
+
+# See https://svn.apache.org/repos/asf/incubator/qpid/trunk/qpid/bin/verify
+cpp=$CPP/request-response
+
+server_dotnet()
+{
+mono $DOTNET_EXAMPLES/example-request-response-Server.exe localhost 5672
+}
+
+background "Waiting for requests" server_dotnet
+clients $cpp/client
+kill %%
+outputs "$cpp/client.out | remove_uuid" ./server_dotnet.out
diff --git a/qpid/dotnet/client-010/examples/request-response/verify_dotnet_cpp.in b/qpid/dotnet/client-010/examples/request-response/verify_dotnet_cpp.in
new file mode 100644
index 0000000000..849fad39c6
--- /dev/null
+++ b/qpid/dotnet/client-010/examples/request-response/verify_dotnet_cpp.in
@@ -0,0 +1,18 @@
+==== client.out | remove_uuid
+Activating response queue listener for: client
+Request: Twas brillig, and the slithy toves
+Request: Did gire and gymble in the wabe.
+Request: All mimsy were the borogroves,
+Request: And the mome raths outgrabe.
+Waiting for all responses to arrive ...
+Response: TWAS BRILLIG, AND THE SLITHY TOVES
+Response: DID GIRE AND GYMBLE IN THE WABE.
+Response: ALL MIMSY WERE THE BOROGROVES,
+Response: AND THE MOME RATHS OUTGRABE.
+Shutting down listener for client
+==== server_dotnet.out
+Waiting for requests
+Request: Twas brillig, and the slithy toves
+Request: Did gire and gymble in the wabe.
+Request: All mimsy were the borogroves,
+Request: And the mome raths outgrabe.
diff --git a/qpid/dotnet/client-010/gentool/Composite.tpl b/qpid/dotnet/client-010/gentool/Composite.tpl
new file mode 100644
index 0000000000..c5a1099ef3
--- /dev/null
+++ b/qpid/dotnet/client-010/gentool/Composite.tpl
@@ -0,0 +1,291 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+using System;
+using org.apache.qpid.transport.codec;
+using System.Collections.Generic;
+using org.apache.qpid.transport.util;
+using org.apache.qpid.transport.network;
+using System.IO;
+
+namespace org.apache.qpid.transport
+{
+
+${
+from genutil import *
+
+cls = klass(type)["@name"]
+
+segments = type["segments"]
+
+if type.name in ("control", "command"):
+ override = "override"
+ base = "Method"
+ size = 0
+ pack = 2
+ if segments:
+ payload = "true"
+ else:
+ payload = "false"
+ if type.name == "control" and cls == "connection":
+ track = "Frame.L1"
+ elif cls == "session" and type["@name"] in ("attach", "attached", "detach", "detached"):
+ track = "Frame.L2"
+ elif type.name == "command":
+ track = "Frame.L4"
+ else:
+ track = "Frame.L3"
+else:
+ override = ""
+ base = "Struct"
+ size = type["@size"]
+ pack = num(type["@pack"])
+ payload = "false"
+ track = "4"
+
+PACK_TYPES = {
+ 1: "byte",
+ 2: "int",
+ 4: "int"
+}
+
+typecode = code(type)
+}
+
+public sealed class $name : $base {
+
+ public const int TYPE = $typecode;
+
+ public override int GetStructType() {
+ return TYPE;
+ }
+
+ public override int GetSizeWidth() {
+ return $size;
+ }
+
+ public override int GetPackWidth() {
+ return $pack;
+ }
+
+ public $override bool HasPayload() {
+ return $payload;
+ }
+
+ public $override byte EncodedTrack
+ {
+ get{ return $track; }
+ set { throw new NotImplementedException(); }
+ }
+
+${
+from dotnetgenutil import *
+if pack > 0:
+ out(" private $(PACK_TYPES[pack]) packing_flags = 0;\n");
+
+fields = get_fields(type)
+params = get_dotnetparameters(type, fields)
+options = get_options(fields)
+
+for f in fields:
+ if not f.empty:
+ out(" private $(f.type) _$(f.name);\n")
+
+if segments:
+ out(" private Header _header;\n")
+ out(" private MemoryStream _body = new MemoryStream();\n")
+}
+
+${
+if fields:
+ out(" public $name() {}\n")
+}
+
+ public $name($(", ".join(params))) {
+${
+for f in fields:
+ if f.option: continue
+ out(" $(f.set)($(f.name));\n")
+
+if segments:
+ out(" Header = header;\n")
+ out(" Body = body;\n")
+
+if options or base == "Method":
+ out("""
+ for (int i=0; i < options.Length; i++) {
+ switch (options[i]) {
+""")
+
+ for f in options:
+ out(" case Option.$(f.option): packing_flags |= $(f.flag_mask(pack)); break;\n")
+
+ if base == "Method":
+ out(""" case Option.SYNC: Sync = true; break;
+ case Option.BATCH: Batch = true; break;
+""")
+ out(""" case Option.NONE: break;
+ default: throw new Exception("invalid option: " + options[i]);
+ }
+ }
+""")
+}
+ }
+
+ public $override void Dispatch<C>(C context, MethodDelegate<C> mdelegate) {
+ mdelegate.$(name)(context, this);
+ }
+
+${
+for f in fields:
+ if pack > 0:
+ out("""
+ public bool $(f.has)() {
+ return (packing_flags & $(f.flag_mask(pack))) != 0;
+ }
+
+ public $name $(f.clear)() {
+ packing_flags = (byte) (packing_flags & ~$(f.flag_mask(pack)));
+${
+if (not f.empty and not (f.default == "null")):
+ out(" _$(f.name) = $(f.default);")
+}
+ Dirty = true;
+ return this;
+ }
+""")
+
+ out("""
+ public $(f.type) $(f.get)() {
+${
+if f.empty:
+ out(" return $(f.has)();")
+else:
+ out(" return _$(f.name);")
+}
+ }
+
+ public $name $(f.set)($(f.type) value) {
+${
+if not f.empty:
+ out(" _$(f.name) = value;")
+}
+${
+if pack > 0:
+ out(" packing_flags |= $(f.flag_mask(pack));")
+}
+ Dirty = true;
+ return this;
+ }
+
+""")
+}
+
+${
+if segments:
+ out(""" public override Header Header {
+ get { return _header;}
+ set { _header = value;}
+ }
+
+ public $name SetHeader(Header header) {
+ Header = header;
+ return this;
+ }
+
+ public override MemoryStream Body
+ {
+ get{ return _body;}
+ set{ _body = value;}
+ }
+
+ public $name SetBody(MemoryStream body)
+ {
+ Body = body;
+ return this;
+ }
+""")
+}
+
+ public override void Write(IEncoder enc)
+ {
+${
+if pack > 0:
+ out(" enc.WriteUint%s(packing_flags);\n" % (pack*8));
+
+for f in fields:
+ if f.empty:
+ continue
+ if pack > 0:
+ out(" if ((packing_flags & $(f.flag_mask(pack))) != 0)\n ")
+ pre = ""
+ post = ""
+ if f.type_node.name == "struct":
+ pre = "%s.TYPE, " % cname(f.type_node)
+ elif f.type_node.name == "domain":
+ post = ""
+ pre = "(short)"
+ out(" enc.Write$(f.coder)($(pre)_$(f.name)$(post));\n")
+}
+ }
+
+ public override void Read(IDecoder dec)
+ {
+${
+if pack > 0:
+ out(" packing_flags = ($(PACK_TYPES[pack])) dec.ReadUint%s();\n" % (pack*8));
+
+for f in fields:
+ if f.empty:
+ continue
+ if pack > 0:
+ out(" if ((packing_flags & $(f.flag_mask(pack))) != 0)\n ")
+ pre = ""
+ post = ""
+ arg = ""
+ if f.type_node.name == "struct":
+ pre = "(%s)" % cname(f.type_node)
+ arg = "%s.TYPE" % cname(f.type_node)
+ elif f.type_node.name == "domain":
+ pre = "%sGetter.Get(" % cname(f.type_node)
+ post = ")"
+ out(" _$(f.name) = $(pre)dec.Read$(f.coder)($(arg))$(post);\n")
+}
+ }
+
+ public override Dictionary<String,Object> Fields
+ {
+ get
+ {
+ Dictionary<String,Object> result = new Dictionary<String,Object>();
+
+${
+for f in fields:
+ if pack > 0:
+ out(" if ((packing_flags & $(f.flag_mask(pack))) != 0)\n ")
+ out(' result.Add("_$(f.name)", $(f.get)());\n')
+}
+ return result;
+ }
+ }
+
+}
+}
diff --git a/qpid/dotnet/client-010/gentool/Constant.tpl b/qpid/dotnet/client-010/gentool/Constant.tpl
new file mode 100644
index 0000000000..191a1dbd6e
--- /dev/null
+++ b/qpid/dotnet/client-010/gentool/Constant.tpl
@@ -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.
+ *
+ */
+
+namespace org.apache.qpid.transport
+{
+
+${from genutil import *}
+
+public class Constant
+{
+${
+constants = spec.query["amqp/constant"]
+
+for c in constants:
+ name = scream(c["@name"])
+ value = c["@value"]
+ out(" public const int $name = $value;\n")
+}}
+}
diff --git a/qpid/dotnet/client-010/gentool/Enum.tpl b/qpid/dotnet/client-010/gentool/Enum.tpl
new file mode 100644
index 0000000000..5d958c7bf6
--- /dev/null
+++ b/qpid/dotnet/client-010/gentool/Enum.tpl
@@ -0,0 +1,59 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+using System;
+namespace org.apache.qpid.transport
+{
+${
+from genutil import *
+
+vtype = jtype(resolve_type(type))
+
+out(" public enum $name : $vtype")
+
+choices = [(scream(ch["@name"]), "= %s" % (ch["@value"]))
+ for ch in type.query["enum/choice"]]
+}
+ {
+ $(",\n ".join(["%s%s" % ch for ch in choices]))
+ }
+
+${
+
+out(" public struct $name")
+out("Getter")
+}
+ {
+ public static $name Get($vtype value)
+ {
+ switch (value)
+ {
+${
+choices = [(scream(ch["@name"]), "%s" % (ch["@value"]))
+ for ch in type.query["enum/choice"]]
+
+for ch, value in choices:
+ out(' case $value: return $name.$ch;\n')
+} default: throw new Exception("no such value: " + value);
+ }
+ }
+ }
+}
diff --git a/qpid/dotnet/client-010/gentool/IInvoker.tpl b/qpid/dotnet/client-010/gentool/IInvoker.tpl
new file mode 100644
index 0000000000..713d10c610
--- /dev/null
+++ b/qpid/dotnet/client-010/gentool/IInvoker.tpl
@@ -0,0 +1,57 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+
+namespace org.apache.qpid.transport
+{
+
+public interface IInvoker {
+
+ IFuture Invoke(Method method, IFuture resultClass);
+
+${
+from dotnetgenutil import *
+
+for c in composites:
+ name = cname(c)
+ fields = get_fields(c)
+ params = get_dotnetparameters(c, fields)
+ args = get_arguments(c, fields)
+ result = c["result"]
+ if result:
+ if not result["@type"]:
+ rname = cname(result["struct"])
+ else:
+ rname = cname(result, "@type")
+ jresult = "IFuture"
+ else:
+ jresult = "void"
+
+ out("""
+ $jresult $(name)($(", ".join(params)));
+""")
+}
+
+}
+}
diff --git a/qpid/dotnet/client-010/gentool/Invoker.tpl b/qpid/dotnet/client-010/gentool/Invoker.tpl
new file mode 100644
index 0000000000..2f69aee66d
--- /dev/null
+++ b/qpid/dotnet/client-010/gentool/Invoker.tpl
@@ -0,0 +1,67 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using common.org.apache.qpid.transport.util;
+
+namespace org.apache.qpid.transport
+{
+
+public abstract class Invoker : IInvoker {
+
+ protected abstract void Invoke(Method method);
+ public abstract IFuture Invoke(Method method, IFuture resultClass);
+
+${
+from dotnetgenutil import *
+
+for c in composites:
+ name = cname(c)
+ fields = get_fields(c)
+ params = get_dotnetparameters(c, fields)
+ args = get_arguments(c, fields)
+ result = c["result"]
+ if result:
+ if not result["@type"]:
+ rname = cname(result["struct"])
+ else:
+ rname = cname(result, "@type")
+ jresult = "IFuture"
+ jreturn = "return "
+ jclass = ", new ResultFuture()"
+ jinvoke = "Invoke"
+ else:
+ jinvoke = "Invoke"
+ jresult = "void"
+ jreturn = ""
+ jclass = ""
+
+ out("""
+ public $jresult $(name)($(", ".join(params))) {
+ $(jreturn)$jinvoke(new $name($(", ".join(args)))$jclass);
+ }
+""")
+}
+
+}
+}
diff --git a/qpid/dotnet/client-010/gentool/MethodDelegate.tpl b/qpid/dotnet/client-010/gentool/MethodDelegate.tpl
new file mode 100644
index 0000000000..788d2e29e6
--- /dev/null
+++ b/qpid/dotnet/client-010/gentool/MethodDelegate.tpl
@@ -0,0 +1,35 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+namespace org.apache.qpid.transport
+{
+
+public abstract class MethodDelegate<C> {
+
+${
+from genutil import *
+
+for c in composites:
+ name = cname(c)
+ out(" public virtual void $(name)(C context, $name mystruct) {}\n")
+}
+}
+}
diff --git a/qpid/dotnet/client-010/gentool/Option.tpl b/qpid/dotnet/client-010/gentool/Option.tpl
new file mode 100644
index 0000000000..d6e1a44870
--- /dev/null
+++ b/qpid/dotnet/client-010/gentool/Option.tpl
@@ -0,0 +1,42 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+namespace org.apache.qpid.transport
+{
+public enum Option {
+
+${
+from genutil import *
+
+options = {}
+
+for c in composites:
+ for f in c.query["field"]:
+ t = resolve_type(f)
+ if t["@name"] == "bit":
+ option = scream(f["@name"])
+ if not options.has_key(option):
+ options[option] = None
+ out(" $option,\n")}
+ BATCH,
+ NONE
+}
+}
diff --git a/qpid/dotnet/client-010/gentool/StructFactory.tpl b/qpid/dotnet/client-010/gentool/StructFactory.tpl
new file mode 100644
index 0000000000..2a11e2530c
--- /dev/null
+++ b/qpid/dotnet/client-010/gentool/StructFactory.tpl
@@ -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.
+ *
+ */
+
+using System;
+
+namespace org.apache.qpid.transport
+{
+
+class StructFactory {
+
+ public static Struct create(int type)
+ {
+ switch (type)
+ {
+${
+from genutil import *
+
+fragment = """ case $name.TYPE:
+ return new $name();
+"""
+
+for c in composites:
+ name = cname(c)
+ if c.name == "struct":
+ out(fragment)
+} default:
+ throw new Exception("type: " + type);
+ }
+ }
+
+ public static Struct createInstruction(int type)
+ {
+ switch (type)
+ {
+${
+for c in composites:
+ name = cname(c)
+ if c.name in ("command", "control"):
+ out(fragment)
+} default:
+ throw new Exception("type: " + type);
+ }
+ }
+
+}
+}
diff --git a/qpid/dotnet/client-010/gentool/Type.tpl b/qpid/dotnet/client-010/gentool/Type.tpl
new file mode 100644
index 0000000000..c8ec7ac153
--- /dev/null
+++ b/qpid/dotnet/client-010/gentool/Type.tpl
@@ -0,0 +1,103 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+using System;
+
+namespace org.apache.qpid.transport
+{
+
+${from genutil import *}
+
+public struct QpidType
+{
+ public Code code;
+ public int width;
+ public bool isfixed;
+
+ public Code Code
+ {
+ get { return code; }
+ set { code = value; }
+ }
+
+ public int Width
+ {
+ get { return width; }
+ set { width = value; }
+ }
+
+ public bool Fixed
+ {
+ get { return isfixed; }
+ set { isfixed = value; }
+ }
+
+ QpidType(Code code, int width, bool isfixed)
+ {
+ this.code = code;
+ this.width = width;
+ this.isfixed = isfixed;
+ }
+
+ public static QpidType get(byte code)
+ {
+ switch (code)
+ {
+${
+types = spec.query["amqp/type"] + spec.query["amqp/class/type"]
+codes = {}
+first = True
+for t in types:
+ code = t["@code"]
+ fix_width = t["@fixed-width"]
+ var_width = t["@variable-width"]
+
+ if code is None:
+ continue
+
+ if fix_width is None:
+ width = var_width
+ fixed = "false"
+ else:
+ width = fix_width
+ fixed = "true"
+
+ name = scream(t["@name"])
+ codes[code] = name
+
+ out(" case $code : return new QpidType(Code.$name, $width, $fixed);\n")
+}
+ default: throw new Exception("unknown code: " + code);
+ }
+ }
+}
+
+public enum Code : byte
+ {
+${
+keys = list(codes.keys())
+keys.sort()
+
+for code in keys:
+ out(" $(codes[code]) = $code,\n")
+}
+ }
+}
diff --git a/qpid/dotnet/client-010/gentool/build.xml b/qpid/dotnet/client-010/gentool/build.xml
new file mode 100644
index 0000000000..76ddb1571d
--- /dev/null
+++ b/qpid/dotnet/client-010/gentool/build.xml
@@ -0,0 +1,52 @@
+<!--
+ -
+ - Licensed to the Apache Software Foundation (ASF) under one
+ - or more contributor license agreements. See the NOTICE file
+ - distributed with this work for additional information
+ - regarding copyright ownership. The ASF licenses this file
+ - to you under the Apache License, Version 2.0 (the
+ - "License"); you may not use this file except in compliance
+ - with the License. You may obtain a copy of the License at
+ -
+ - http://www.apache.org/licenses/LICENSE-2.0
+ -
+ - Unless required by applicable law or agreed to in writing,
+ - software distributed under the License is distributed on an
+ - "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ - KIND, either express or implied. See the License for the
+ - specific language governing permissions and limitations
+ - under the License.
+ -
+ -->
+<project name="GenTool" default="build">
+
+ <property name="generated.dir" location="../client/" />
+ <property name="gentools.timestamp" location="${generated.dir}/gentools.timestamp" />
+ <property name="jython.timestamp" location="${generated.dir}/jython.timestamp" />
+ <property name="java.basedir" location="../../../java/common" />
+ <property name="mllib.dir" location="../../../python" />
+ <property name="xml.spec.dir" location="../../../specs" />
+
+
+ <target name="check_jython_deps">
+ <uptodate property="jython.notRequired" targetfile="${jython.timestamp}">
+ <srcfiles dir="${xml.spec.dir}" includes="amqp.0-10-qpid-errata.xml" />
+ </uptodate>
+ </target>
+
+ <target name="build" depends="check_jython_deps" unless="jython.notRequired">
+ <java classname="org.python.util.jython" fork="true" failonerror="true">
+ <arg value="-Dpython.cachedir.skip=true"/>
+ <arg value="-Dpython.path=${java.basedir}/../lib/jython-lib.jar/Lib${path.separator}${mllib.dir}${path.separator}${java.basedir}${path.separator}${basedir}"/>
+ <arg value="${basedir}/codegen"/>
+ <arg value="${generated.dir}"/>
+ <arg value="${xml.spec.dir}/amqp.0-10-qpid-errata.xml"/>
+ <arg value="${basedir}"/>
+ <classpath>
+ <pathelement location="../../../java/lib/jython-2.5.0.jar"/>
+ </classpath>
+ </java>
+ <touch file="${jython.timestamp}" />
+ </target>
+
+</project>
diff --git a/qpid/dotnet/client-010/gentool/codegen b/qpid/dotnet/client-010/gentool/codegen
new file mode 100644
index 0000000000..baebf378fd
--- /dev/null
+++ b/qpid/dotnet/client-010/gentool/codegen
@@ -0,0 +1,86 @@
+#!/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, sys, mllib
+from templating import Parser
+from dotnetgenutil import *
+
+out_dir = sys.argv[1]
+spec_file = sys.argv[2]
+tpl_dir = sys.argv[3]
+pkg_dir = os.path.join(out_dir, "generated")
+
+if not os.path.exists(pkg_dir):
+ os.makedirs(pkg_dir)
+
+spec = mllib.xml_parse(spec_file)
+
+def excludes(nd):
+ if (nd.parent is not None and
+ nd.parent.name == "class" and
+ nd.parent["@name"] in ("file", "stream")):
+ return False
+ else:
+ return True
+
+def execute(output, template, **kwargs):
+ f = open(os.path.join(tpl_dir, template))
+ input = f.read()
+ f.close()
+ p = Parser(**kwargs)
+ p.parse(input)
+ fname = os.path.join(pkg_dir, output)
+ f = open(fname, "w")
+ f.write(p.output)
+ f.close()
+
+execute("Type.cs", "Type.tpl", spec = spec)
+execute("Constant.cs", "Constant.tpl", spec = spec)
+
+structs = spec.query["amqp/struct"] + \
+ spec.query["amqp/class/struct", excludes] + \
+ spec.query["amqp/class/command/result/struct", excludes]
+controls = spec.query["amqp/class/control", excludes]
+commands = spec.query["amqp/class/command", excludes]
+
+composites = structs + controls + commands
+
+for c in composites:
+ name = cname(c)
+ execute("%s.cs" % name, "Composite.tpl", type = c, name = name)
+
+execute("MethodDelegate.cs", "MethodDelegate.tpl", composites = composites)
+execute("Option.cs", "Option.tpl", composites = composites)
+execute("Invoker.cs", "Invoker.tpl", composites = controls + commands)
+execute("IInvoker.cs", "IInvoker.tpl", composites = controls + commands)
+execute("StructFactory.cs", "StructFactory.tpl", composites = composites)
+
+def is_enum(nd):
+ return nd["enum"] is not None
+
+enums = spec.query["amqp/domain", is_enum] + \
+ spec.query["amqp/class/domain", is_enum]
+
+for e in enums:
+ name = cname(e)
+ execute("%s.cs" % name, "Enum.tpl", name = name, type = e)
diff --git a/qpid/dotnet/client-010/gentool/dotnetgenutil.py b/qpid/dotnet/client-010/gentool/dotnetgenutil.py
new file mode 100644
index 0000000000..4d9c8a69d7
--- /dev/null
+++ b/qpid/dotnet/client-010/gentool/dotnetgenutil.py
@@ -0,0 +1,271 @@
+#
+#
+# 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.
+#
+#
+
+
+def pascal(offset, *args):
+ parts = []
+ for a in args:
+ parts.extend(a.split("-"))
+ return "".join([p[0].upper() + p[1:] for p in parts[:offset]] + [p[0].upper() + p[1:] for p in parts[offset:]])
+
+
+def scream(*args):
+ return "_".join([a.replace("-", "_").upper() for a in args])
+
+def num(x, default=None):
+ if x is not None and x != "":
+ return int(x, 0)
+ else:
+ return default
+
+def klass(nd):
+ parent = nd.parent
+ while parent is not None:
+ if hasattr(parent, "name") and parent.name == "class":
+ return parent
+ parent = parent.parent
+
+untyped = -1
+
+def code(nd):
+ global untyped
+ cd = num(nd["@code"])
+ if cd is None:
+ cd = untyped
+ untyped -= 1
+ return cd
+
+ cls = klass(nd)
+ if cls:
+ cd |= (num(cls["@code"]) << 8)
+ return cd
+
+def root(nd):
+ if nd.parent is None:
+ return nd
+ else:
+ return root(nd.parent)
+
+def qname(nd):
+ name = nd["@name"]
+ cls = klass(nd)
+ if cls != None:
+ return "%s.%s" % (cls["@name"], name)
+ else:
+ return name
+
+RESOLVED = {}
+
+def resolve(node, name):
+ key = (node, name)
+ if RESOLVED.has_key(key):
+ return RESOLVED[key]
+ else:
+ spec = root(node)
+ cls = klass(node)
+ if cls:
+ for nd in cls.query["#tag"]:
+ if nd["@name"] == name:
+ RESOLVED[key] = nd
+ return nd
+ for nd in spec.query["amqp/#tag"] + spec.query["amqp/class/#tag"]:
+ if name == qname(nd):
+ RESOLVED[key] = nd
+ return nd
+ raise Exception("unresolved name: %s" % name)
+
+def resolve_type(nd):
+ if hasattr(nd, "_resolved_type"):
+ return nd._resolved_type
+ else:
+ name = nd["@type"]
+ type = resolve(nd, name)
+ if type.name == "domain" and not type["enum"]:
+ type = resolve_type(type)
+ nd._resolved_type = type
+ return type
+
+TYPES = {
+ "bit": "bool",
+ "uint8": "short",
+ "uint16": "int",
+ "uint32": "long",
+ "uint64": "long",
+ "datetime": "long",
+ "uuid": "UUID",
+ "sequence-no": "int",
+ "sequence-set": "RangeSet", # XXX
+ "byte-ranges": "RangeSet", # XXX
+ "str8": "String",
+ "str16": "String",
+ "vbin8": "byte[]",
+ "vbin16": "byte[]",
+ "vbin32": "byte[]",
+ "struct32": "Struct",
+ "map": "Dictionary<String,Object>",
+ "array": "List<Object>"
+ }
+
+def cname(nd, field="@name"):
+ cls = klass(nd)
+ if cls:
+ if (nd.name in ("struct", "result") and
+ cls["@name"] != "session" and
+ nd[field] != "header"):
+ return pascal(0, nd[field])
+ else:
+ return pascal(0, cls["@name"], nd[field])
+ else:
+ return pascal(0, nd[field])
+
+def jtype(nd):
+ if nd.name == "struct" or nd["enum"]:
+ return cname(nd)
+ else:
+ return TYPES[nd["@name"]]
+
+REFS = {
+ "bool": "Boolean",
+ "byte": "Byte",
+ "short": "Short",
+ "int": "Integer",
+ "long": "Long",
+ "float": "Float",
+ "double": "Double",
+ "char": "Character"
+}
+
+def jref(jt):
+ return REFS.get(jt, jt)
+
+def jclass(jt):
+ idx = jt.find('<')
+ if idx > 0:
+ return jt[:idx]
+ else:
+ return jt
+
+DEFAULTS = {
+ "long": 0,
+ "int": 0,
+ "short": 0,
+ "byte": 0,
+ "char": 0,
+ "bool": "false"
+ }
+
+class Field:
+
+ def __init__(self, index, nd):
+ self.index = index
+ self.name = pascal(1, nd["@name"])
+ self.type_node = resolve_type(nd)
+ if self.type_node.name == "domain":
+ self.prim_type = resolve_type(self.type_node)
+ else:
+ self.prim_type = self.type_node
+ self.variable_width = num(self.prim_type["@variable-width"], 0)
+ self.fixed_width = num(self.prim_type["@fixed-width"], 0)
+ self.empty = self.variable_width == 0 and self.fixed_width == 0 and self.prim_type.name != "struct"
+ tname = cname(self.type_node)
+ if self.type_node.name == "struct":
+ self.read = "(%s) dec.ReadStruct(%s.TYPE)" % (tname, tname)
+ self.write = "enc.WriteStruct(%s.TYPE, check(struct).%s)" % (tname, self.name)
+ self.coder = "Struct"
+ elif self.type_node.name == "domain":
+ self.coder = pascal(0, self.prim_type["@name"])
+ self.read = "%s.Get(dec.Read%s())" % (tname, self.coder)
+ self.write = "enc.Write%s(check(struct).%s.GetValue())" % (self.coder, self.name)
+ else:
+ self.coder = pascal(0, self.type_node["@name"])
+ self.read = "dec.Read%s()" % self.coder
+ self.write = "enc.Write%s(check(struct).%s)" % (self.coder, self.name)
+ self.type = jtype(self.type_node)
+ self.default = DEFAULTS.get(self.type, "null")
+ self.has = pascal(1, "Has", self.name)
+ self.get = pascal(1, "Get", self.name)
+ self.set = pascal(1, "Set", self.name)
+ self.clear = pascal(1, "clear", self.name)
+ if self.type == "bool":
+ self.option = scream(nd["@name"])
+ else:
+ self.option = None
+
+ def flag_mask(self, pack):
+ flag = pack * 8 - 8 - (self.index/8)*8 + (self.index % 8)
+ return 1 << flag
+
+
+def get_fields(nd):
+ fields = []
+ index = 0
+ for f in nd.query["field"]:
+ fields.append(Field(index, f))
+ index += 1
+ return fields
+
+def get_parameters(type, fields):
+ params = []
+ options = False
+ for f in fields:
+ if f.option:
+ options = True
+ else:
+ params.append("%s %s" % (f.type, f.name))
+ if type["segments"]:
+ params.append("Header header")
+ params.append("MemoryStream body")
+ if options or type.name in ("control", "command"):
+ params.append("Option ... options")
+ return params
+
+def get_arguments(type, fields):
+ args = []
+ options = False
+ for f in fields:
+ if f.option:
+ options = True
+ else:
+ args.append(f.name)
+ if type["segments"]:
+ args.append("header")
+ args.append("body")
+ if options or type.name in ("control", "command"):
+ args.append("options")
+ return args
+
+def get_options(fields):
+ return [f for f in fields if f.option]
+
+def get_dotnetparameters(type, fields):
+ params = []
+ options = False
+ for f in fields:
+ if f.option:
+ options = True
+ else:
+ params.append("%s %s" % (f.type, f.name))
+ if type["segments"]:
+ params.append("Header header")
+ params.append("MemoryStream body")
+ if options or type.name in ("control", "command"):
+ params.append("params Option[] options")
+ return params
diff --git a/qpid/dotnet/client-010/lib/log4net/log4net-licence.txt b/qpid/dotnet/client-010/lib/log4net/log4net-licence.txt
new file mode 100644
index 0000000000..261eeb9e9f
--- /dev/null
+++ b/qpid/dotnet/client-010/lib/log4net/log4net-licence.txt
@@ -0,0 +1,201 @@
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
diff --git a/qpid/dotnet/client-010/lib/log4net/log4net.dll b/qpid/dotnet/client-010/lib/log4net/log4net.dll
new file mode 100644
index 0000000000..995816f27b
--- /dev/null
+++ b/qpid/dotnet/client-010/lib/log4net/log4net.dll
Binary files differ
diff --git a/qpid/dotnet/client-010/lib/log4net/log4net.xml b/qpid/dotnet/client-010/lib/log4net/log4net.xml
new file mode 100644
index 0000000000..5beb669ab0
--- /dev/null
+++ b/qpid/dotnet/client-010/lib/log4net/log4net.xml
@@ -0,0 +1,28676 @@
+<?xml version="1.0"?>
+<!--
+
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+
+-->
+
+<doc>
+ <assembly>
+ <name>log4net</name>
+ </assembly>
+ <members>
+ <member name="T:log4net.Appender.AdoNetAppender">
+ <summary>
+ Appender that logs to a database.
+ </summary>
+ <remarks>
+ <para>
+ <see cref="T:log4net.Appender.AdoNetAppender"/> appends logging events to a table within a
+ database. The appender can be configured to specify the connection
+ string by setting the <see cref="P:log4net.Appender.AdoNetAppender.ConnectionString"/> property.
+ The connection type (provider) can be specified by setting the <see cref="P:log4net.Appender.AdoNetAppender.ConnectionType"/>
+ property. For more information on database connection strings for
+ your specific database see <a href="http://www.connectionstrings.com/">http://www.connectionstrings.com/</a>.
+ </para>
+ <para>
+ Records are written into the database either using a prepared
+ statement or a stored procedure. The <see cref="P:log4net.Appender.AdoNetAppender.CommandType"/> property
+ is set to <see cref="F:System.Data.CommandType.Text"/> (<c>System.Data.CommandType.Text</c>) to specify a prepared statement
+ or to <see cref="F:System.Data.CommandType.StoredProcedure"/> (<c>System.Data.CommandType.StoredProcedure</c>) to specify a stored
+ procedure.
+ </para>
+ <para>
+ The prepared statement text or the name of the stored procedure
+ must be set in the <see cref="P:log4net.Appender.AdoNetAppender.CommandText"/> property.
+ </para>
+ <para>
+ The prepared statement or stored procedure can take a number
+ of parameters. Parameters are added using the <see cref="M:log4net.Appender.AdoNetAppender.AddParameter(log4net.Appender.AdoNetAppenderParameter)"/>
+ method. This adds a single <see cref="T:log4net.Appender.AdoNetAppenderParameter"/> to the
+ ordered list of parameters. The <see cref="T:log4net.Appender.AdoNetAppenderParameter"/>
+ type may be subclassed if required to provide database specific
+ functionality. The <see cref="T:log4net.Appender.AdoNetAppenderParameter"/> specifies
+ the parameter name, database type, size, and how the value should
+ be generated using a <see cref="T:log4net.Layout.ILayout"/>.
+ </para>
+ </remarks>
+ <example>
+ An example of a SQL Server table that could be logged to:
+ <code lang="SQL">
+ CREATE TABLE [dbo].[Log] (
+ [ID] [int] IDENTITY (1, 1) NOT NULL ,
+ [Date] [datetime] NOT NULL ,
+ [Thread] [varchar] (255) NOT NULL ,
+ [Level] [varchar] (20) NOT NULL ,
+ [Logger] [varchar] (255) NOT NULL ,
+ [Message] [varchar] (4000) NOT NULL
+ ) ON [PRIMARY]
+ </code>
+ </example>
+ <example>
+ An example configuration to log to the above table:
+ <code lang="XML" escaped="true">
+ <appender name="AdoNetAppender_SqlServer" type="log4net.Appender.AdoNetAppender">
+ <connectionType value="System.Data.SqlClient.SqlConnection, System.Data, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>
+ <connectionString value="data source=SQLSVR;initial catalog=test_log4net;integrated security=false;persist security info=True;User ID=sa;Password=sa"/>
+ <commandText value="INSERT INTO Log ([Date],[Thread],[Level],[Logger],[Message]) VALUES (@log_date, @thread, @log_level, @logger, @message)"/>
+ <parameter>
+ <parameterName value="@log_date"/>
+ <dbType value="DateTime"/>
+ <layout type="log4net.Layout.PatternLayout" value="%date{yyyy'-'MM'-'dd HH':'mm':'ss'.'fff}"/>
+ </parameter>
+ <parameter>
+ <parameterName value="@thread"/>
+ <dbType value="String"/>
+ <size value="255"/>
+ <layout type="log4net.Layout.PatternLayout" value="%thread"/>
+ </parameter>
+ <parameter>
+ <parameterName value="@log_level"/>
+ <dbType value="String"/>
+ <size value="50"/>
+ <layout type="log4net.Layout.PatternLayout" value="%level"/>
+ </parameter>
+ <parameter>
+ <parameterName value="@logger"/>
+ <dbType value="String"/>
+ <size value="255"/>
+ <layout type="log4net.Layout.PatternLayout" value="%logger"/>
+ </parameter>
+ <parameter>
+ <parameterName value="@message"/>
+ <dbType value="String"/>
+ <size value="4000"/>
+ <layout type="log4net.Layout.PatternLayout" value="%message"/>
+ </parameter>
+ </appender>
+ </code>
+ </example>
+ <author>Julian Biddle</author>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ <author>Lance Nehring</author>
+ </member>
+ <member name="T:log4net.Appender.BufferingAppenderSkeleton">
+ <summary>
+ Abstract base class implementation of <see cref="T:log4net.Appender.IAppender"/> that
+ buffers events in a fixed size buffer.
+ </summary>
+ <remarks>
+ <para>
+ This base class should be used by appenders that need to buffer a
+ number of events before logging them. For example the <see cref="T:log4net.Appender.AdoNetAppender"/>
+ buffers events and then submits the entire contents of the buffer to
+ the underlying database in one go.
+ </para>
+ <para>
+ Subclasses should override the <see cref="M:log4net.Appender.BufferingAppenderSkeleton.SendBuffer(log4net.Core.LoggingEvent[])"/>
+ method to deliver the buffered events.
+ </para>
+ <para>The BufferingAppenderSkeleton maintains a fixed size cyclic
+ buffer of events. The size of the buffer is set using
+ the <see cref="P:log4net.Appender.BufferingAppenderSkeleton.BufferSize"/> property.
+ </para>
+ <para>A <see cref="T:log4net.Core.ITriggeringEventEvaluator"/> is used to inspect
+ each event as it arrives in the appender. If the <see cref="P:log4net.Appender.BufferingAppenderSkeleton.Evaluator"/>
+ triggers, then the current buffer is sent immediately
+ (see <see cref="M:log4net.Appender.BufferingAppenderSkeleton.SendBuffer(log4net.Core.LoggingEvent[])"/>). Otherwise the event
+ is stored in the buffer. For example, an evaluator can be used to
+ deliver the events immediately when an ERROR event arrives.
+ </para>
+ <para>
+ The buffering appender can be configured in a <see cref="P:log4net.Appender.BufferingAppenderSkeleton.Lossy"/> mode.
+ By default the appender is NOT lossy. When the buffer is full all
+ the buffered events are sent with <see cref="M:log4net.Appender.BufferingAppenderSkeleton.SendBuffer(log4net.Core.LoggingEvent[])"/>.
+ If the <see cref="P:log4net.Appender.BufferingAppenderSkeleton.Lossy"/> property is set to <c>true</c> then the
+ buffer will not be sent when it is full, and new events arriving
+ in the appender will overwrite the oldest event in the buffer.
+ In lossy mode the buffer will only be sent when the <see cref="P:log4net.Appender.BufferingAppenderSkeleton.Evaluator"/>
+ triggers. This can be useful behavior when you need to know about
+ ERROR events but not about events with a lower level, configure an
+ evaluator that will trigger when an ERROR event arrives, the whole
+ buffer will be sent which gives a history of events leading up to
+ the ERROR event.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="T:log4net.Appender.AppenderSkeleton">
+ <summary>
+ Abstract base class implementation of <see cref="T:log4net.Appender.IAppender"/>.
+ </summary>
+ <remarks>
+ <para>
+ This class provides the code for common functionality, such
+ as support for threshold filtering and support for general filters.
+ </para>
+ <para>
+ Appenders can also implement the <see cref="T:log4net.Core.IOptionHandler"/> interface. Therefore
+ they would require that the <see cref="M:log4net.Core.IOptionHandler.ActivateOptions"/> method
+ be called after the appenders properties have been configured.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="T:log4net.Appender.IAppender">
+ <summary>
+ Implement this interface for your own strategies for printing log statements.
+ </summary>
+ <remarks>
+ <para>
+ Implementors should consider extending the <see cref="T:log4net.Appender.AppenderSkeleton"/>
+ class which provides a default implementation of this interface.
+ </para>
+ <para>
+ Appenders can also implement the <see cref="T:log4net.Core.IOptionHandler"/> interface. Therefore
+ they would require that the <see cref="M:log4net.Core.IOptionHandler.ActivateOptions"/> method
+ be called after the appenders properties have been configured.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="M:log4net.Appender.IAppender.Close">
+ <summary>
+ Closes the appender and releases resources.
+ </summary>
+ <remarks>
+ <para>
+ Releases any resources allocated within the appender such as file handles,
+ network connections, etc.
+ </para>
+ <para>
+ It is a programming error to append to a closed appender.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.IAppender.DoAppend(log4net.Core.LoggingEvent)">
+ <summary>
+ Log the logging event in Appender specific way.
+ </summary>
+ <param name="loggingEvent">The event to log</param>
+ <remarks>
+ <para>
+ This method is called to log a message into this appender.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.IAppender.Name">
+ <summary>
+ Gets or sets the name of this appender.
+ </summary>
+ <value>The name of the appender.</value>
+ <remarks>
+ <para>The name uniquely identifies the appender.</para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Appender.IBulkAppender">
+ <summary>
+ Interface for appenders that support bulk logging.
+ </summary>
+ <remarks>
+ <para>
+ This interface extends the <see cref="T:log4net.Appender.IAppender"/> interface to
+ support bulk logging of <see cref="T:log4net.Core.LoggingEvent"/> objects. Appenders
+ should only implement this interface if they can bulk log efficiently.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="M:log4net.Appender.IBulkAppender.DoAppend(log4net.Core.LoggingEvent[])">
+ <summary>
+ Log the array of logging events in Appender specific way.
+ </summary>
+ <param name="loggingEvents">The events to log</param>
+ <remarks>
+ <para>
+ This method is called to log an array of events into this appender.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Core.IOptionHandler">
+ <summary>
+ Interface used to delay activate a configured object.
+ </summary>
+ <remarks>
+ <para>
+ This allows an object to defer activation of its options until all
+ options have been set. This is required for components which have
+ related options that remain ambiguous until all are set.
+ </para>
+ <para>
+ If a component implements this interface then the <see cref="M:log4net.Core.IOptionHandler.ActivateOptions"/> method
+ must be called by the container after its all the configured properties have been set
+ and before the component can be used.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="M:log4net.Core.IOptionHandler.ActivateOptions">
+ <summary>
+ Activate the options that were previously set with calls to properties.
+ </summary>
+ <remarks>
+ <para>
+ This allows an object to defer activation of its options until all
+ options have been set. This is required for components which have
+ related options that remain ambiguous until all are set.
+ </para>
+ <para>
+ If a component implements this interface then this method must be called
+ after its properties have been set before the component can be used.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Appender.AppenderSkeleton.c_renderBufferSize">
+ <summary>
+ Initial buffer size
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.AppenderSkeleton.c_renderBufferMaxCapacity">
+ <summary>
+ Maximum buffer size before it is recycled
+ </summary>
+ </member>
+ <member name="M:log4net.Appender.AppenderSkeleton.#ctor">
+ <summary>
+ Default constructor
+ </summary>
+ <remarks>
+ <para>Empty default constructor</para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.AppenderSkeleton.Finalize">
+ <summary>
+ Finalizes this appender by calling the implementation's
+ <see cref="M:log4net.Appender.AppenderSkeleton.Close"/> method.
+ </summary>
+ <remarks>
+ <para>
+ If this appender has not been closed then the <c>Finalize</c> method
+ will call <see cref="M:log4net.Appender.AppenderSkeleton.Close"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.AppenderSkeleton.ActivateOptions">
+ <summary>
+ Initialize the appender based on the options set
+ </summary>
+ <remarks>
+ <para>
+ This is part of the <see cref="T:log4net.Core.IOptionHandler"/> delayed object
+ activation scheme. The <see cref="M:log4net.Appender.AppenderSkeleton.ActivateOptions"/> method must
+ be called on this object after the configuration properties have
+ been set. Until <see cref="M:log4net.Appender.AppenderSkeleton.ActivateOptions"/> is called this
+ object is in an undefined state and must not be used.
+ </para>
+ <para>
+ If any of the configuration properties are modified then
+ <see cref="M:log4net.Appender.AppenderSkeleton.ActivateOptions"/> must be called again.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.AppenderSkeleton.Close">
+ <summary>
+ Closes the appender and release resources.
+ </summary>
+ <remarks>
+ <para>
+ Release any resources allocated within the appender such as file handles,
+ network connections, etc.
+ </para>
+ <para>
+ It is a programming error to append to a closed appender.
+ </para>
+ <para>
+ This method cannot be overridden by subclasses. This method
+ delegates the closing of the appender to the <see cref="M:log4net.Appender.AppenderSkeleton.OnClose"/>
+ method which must be overridden in the subclass.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.AppenderSkeleton.DoAppend(log4net.Core.LoggingEvent)">
+ <summary>
+ Performs threshold checks and invokes filters before
+ delegating actual logging to the subclasses specific
+ <see cref="M:log4net.Appender.AppenderSkeleton.Append(log4net.Core.LoggingEvent)"/> method.
+ </summary>
+ <param name="loggingEvent">The event to log.</param>
+ <remarks>
+ <para>
+ This method cannot be overridden by derived classes. A
+ derived class should override the <see cref="M:log4net.Appender.AppenderSkeleton.Append(log4net.Core.LoggingEvent)"/> method
+ which is called by this method.
+ </para>
+ <para>
+ The implementation of this method is as follows:
+ </para>
+ <para>
+ <list type="bullet">
+ <item>
+ <description>
+ Checks that the severity of the <paramref name="loggingEvent"/>
+ is greater than or equal to the <see cref="P:log4net.Appender.AppenderSkeleton.Threshold"/> of this
+ appender.</description>
+ </item>
+ <item>
+ <description>
+ Checks that the <see cref="T:log4net.Filter.IFilter"/> chain accepts the
+ <paramref name="loggingEvent"/>.
+ </description>
+ </item>
+ <item>
+ <description>
+ Calls <see cref="M:log4net.Appender.AppenderSkeleton.PreAppendCheck"/> and checks that
+ it returns <c>true</c>.</description>
+ </item>
+ </list>
+ </para>
+ <para>
+ If all of the above steps succeed then the <paramref name="loggingEvent"/>
+ will be passed to the abstract <see cref="M:log4net.Appender.AppenderSkeleton.Append(log4net.Core.LoggingEvent)"/> method.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.AppenderSkeleton.DoAppend(log4net.Core.LoggingEvent[])">
+ <summary>
+ Performs threshold checks and invokes filters before
+ delegating actual logging to the subclasses specific
+ <see cref="M:log4net.Appender.AppenderSkeleton.Append(log4net.Core.LoggingEvent[])"/> method.
+ </summary>
+ <param name="loggingEvents">The array of events to log.</param>
+ <remarks>
+ <para>
+ This method cannot be overridden by derived classes. A
+ derived class should override the <see cref="M:log4net.Appender.AppenderSkeleton.Append(log4net.Core.LoggingEvent[])"/> method
+ which is called by this method.
+ </para>
+ <para>
+ The implementation of this method is as follows:
+ </para>
+ <para>
+ <list type="bullet">
+ <item>
+ <description>
+ Checks that the severity of the <paramref name="loggingEvent"/>
+ is greater than or equal to the <see cref="P:log4net.Appender.AppenderSkeleton.Threshold"/> of this
+ appender.</description>
+ </item>
+ <item>
+ <description>
+ Checks that the <see cref="T:log4net.Filter.IFilter"/> chain accepts the
+ <paramref name="loggingEvent"/>.
+ </description>
+ </item>
+ <item>
+ <description>
+ Calls <see cref="M:log4net.Appender.AppenderSkeleton.PreAppendCheck"/> and checks that
+ it returns <c>true</c>.</description>
+ </item>
+ </list>
+ </para>
+ <para>
+ If all of the above steps succeed then the <paramref name="loggingEvents"/>
+ will be passed to the <see cref="M:log4net.Appender.AppenderSkeleton.Append(log4net.Core.LoggingEvent[])"/> method.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.AppenderSkeleton.FilterEvent(log4net.Core.LoggingEvent)">
+ <summary>
+ Test if the logging event should we output by this appender
+ </summary>
+ <param name="loggingEvent">the event to test</param>
+ <returns><c>true</c> if the event should be output, <c>false</c> if the event should be ignored</returns>
+ <remarks>
+ <para>
+ This method checks the logging event against the threshold level set
+ on this appender and also against the filters specified on this
+ appender.
+ </para>
+ <para>
+ The implementation of this method is as follows:
+ </para>
+ <para>
+ <list type="bullet">
+ <item>
+ <description>
+ Checks that the severity of the <paramref name="loggingEvent"/>
+ is greater than or equal to the <see cref="P:log4net.Appender.AppenderSkeleton.Threshold"/> of this
+ appender.</description>
+ </item>
+ <item>
+ <description>
+ Checks that the <see cref="T:log4net.Filter.IFilter"/> chain accepts the
+ <paramref name="loggingEvent"/>.
+ </description>
+ </item>
+ </list>
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.AppenderSkeleton.AddFilter(log4net.Filter.IFilter)">
+ <summary>
+ Adds a filter to the end of the filter chain.
+ </summary>
+ <param name="filter">the filter to add to this appender</param>
+ <remarks>
+ <para>
+ The Filters are organized in a linked list.
+ </para>
+ <para>
+ Setting this property causes the new filter to be pushed onto the
+ back of the filter chain.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.AppenderSkeleton.ClearFilters">
+ <summary>
+ Clears the filter list for this appender.
+ </summary>
+ <remarks>
+ <para>
+ Clears the filter list for this appender.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.AppenderSkeleton.IsAsSevereAsThreshold(log4net.Core.Level)">
+ <summary>
+ Checks if the message level is below this appender's threshold.
+ </summary>
+ <param name="level"><see cref="T:log4net.Core.Level"/> to test against.</param>
+ <remarks>
+ <para>
+ If there is no threshold set, then the return value is always <c>true</c>.
+ </para>
+ </remarks>
+ <returns>
+ <c>true</c> if the <paramref name="level"/> meets the <see cref="P:log4net.Appender.AppenderSkeleton.Threshold"/>
+ requirements of this appender.
+ </returns>
+ </member>
+ <member name="M:log4net.Appender.AppenderSkeleton.OnClose">
+ <summary>
+ Is called when the appender is closed. Derived classes should override
+ this method if resources need to be released.
+ </summary>
+ <remarks>
+ <para>
+ Releases any resources allocated within the appender such as file handles,
+ network connections, etc.
+ </para>
+ <para>
+ It is a programming error to append to a closed appender.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.AppenderSkeleton.Append(log4net.Core.LoggingEvent)">
+ <summary>
+ Subclasses of <see cref="T:log4net.Appender.AppenderSkeleton"/> should implement this method
+ to perform actual logging.
+ </summary>
+ <param name="loggingEvent">The event to append.</param>
+ <remarks>
+ <para>
+ A subclass must implement this method to perform
+ logging of the <paramref name="loggingEvent"/>.
+ </para>
+ <para>This method will be called by <see cref="M:log4net.Appender.AppenderSkeleton.DoAppend(log4net.Core.LoggingEvent)"/>
+ if all the conditions listed for that method are met.
+ </para>
+ <para>
+ To restrict the logging of events in the appender
+ override the <see cref="M:log4net.Appender.AppenderSkeleton.PreAppendCheck"/> method.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.AppenderSkeleton.Append(log4net.Core.LoggingEvent[])">
+ <summary>
+ Append a bulk array of logging events.
+ </summary>
+ <param name="loggingEvents">the array of logging events</param>
+ <remarks>
+ <para>
+ This base class implementation calls the <see cref="M:log4net.Appender.AppenderSkeleton.Append(log4net.Core.LoggingEvent)"/>
+ method for each element in the bulk array.
+ </para>
+ <para>
+ A sub class that can better process a bulk array of events should
+ override this method in addition to <see cref="M:log4net.Appender.AppenderSkeleton.Append(log4net.Core.LoggingEvent)"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.AppenderSkeleton.PreAppendCheck">
+ <summary>
+ Called before <see cref="M:log4net.Appender.AppenderSkeleton.Append(log4net.Core.LoggingEvent)"/> as a precondition.
+ </summary>
+ <remarks>
+ <para>
+ This method is called by <see cref="M:log4net.Appender.AppenderSkeleton.DoAppend(log4net.Core.LoggingEvent)"/>
+ before the call to the abstract <see cref="M:log4net.Appender.AppenderSkeleton.Append(log4net.Core.LoggingEvent)"/> method.
+ </para>
+ <para>
+ This method can be overridden in a subclass to extend the checks
+ made before the event is passed to the <see cref="M:log4net.Appender.AppenderSkeleton.Append(log4net.Core.LoggingEvent)"/> method.
+ </para>
+ <para>
+ A subclass should ensure that they delegate this call to
+ this base class if it is overridden.
+ </para>
+ </remarks>
+ <returns><c>true</c> if the call to <see cref="M:log4net.Appender.AppenderSkeleton.Append(log4net.Core.LoggingEvent)"/> should proceed.</returns>
+ </member>
+ <member name="M:log4net.Appender.AppenderSkeleton.RenderLoggingEvent(log4net.Core.LoggingEvent)">
+ <summary>
+ Renders the <see cref="T:log4net.Core.LoggingEvent"/> to a string.
+ </summary>
+ <param name="loggingEvent">The event to render.</param>
+ <returns>The event rendered as a string.</returns>
+ <remarks>
+ <para>
+ Helper method to render a <see cref="T:log4net.Core.LoggingEvent"/> to
+ a string. This appender must have a <see cref="P:log4net.Appender.AppenderSkeleton.Layout"/>
+ set to render the <paramref name="loggingEvent"/> to
+ a string.
+ </para>
+ <para>If there is exception data in the logging event and
+ the layout does not process the exception, this method
+ will append the exception text to the rendered string.
+ </para>
+ <para>
+ Where possible use the alternative version of this method
+ <see cref="M:log4net.Appender.AppenderSkeleton.RenderLoggingEvent(System.IO.TextWriter,log4net.Core.LoggingEvent)"/>.
+ That method streams the rendering onto an existing Writer
+ which can give better performance if the caller already has
+ a <see cref="T:System.IO.TextWriter"/> open and ready for writing.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.AppenderSkeleton.RenderLoggingEvent(System.IO.TextWriter,log4net.Core.LoggingEvent)">
+ <summary>
+ Renders the <see cref="T:log4net.Core.LoggingEvent"/> to a string.
+ </summary>
+ <param name="loggingEvent">The event to render.</param>
+ <param name="writer">The TextWriter to write the formatted event to</param>
+ <remarks>
+ <para>
+ Helper method to render a <see cref="T:log4net.Core.LoggingEvent"/> to
+ a string. This appender must have a <see cref="P:log4net.Appender.AppenderSkeleton.Layout"/>
+ set to render the <paramref name="loggingEvent"/> to
+ a string.
+ </para>
+ <para>If there is exception data in the logging event and
+ the layout does not process the exception, this method
+ will append the exception text to the rendered string.
+ </para>
+ <para>
+ Use this method in preference to <see cref="M:log4net.Appender.AppenderSkeleton.RenderLoggingEvent(log4net.Core.LoggingEvent)"/>
+ where possible. If, however, the caller needs to render the event
+ to a string then <see cref="M:log4net.Appender.AppenderSkeleton.RenderLoggingEvent(log4net.Core.LoggingEvent)"/> does
+ provide an efficient mechanism for doing so.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Appender.AppenderSkeleton.m_layout">
+ <summary>
+ The layout of this appender.
+ </summary>
+ <remarks>
+ See <see cref="P:log4net.Appender.AppenderSkeleton.Layout"/> for more information.
+ </remarks>
+ </member>
+ <member name="F:log4net.Appender.AppenderSkeleton.m_name">
+ <summary>
+ The name of this appender.
+ </summary>
+ <remarks>
+ See <see cref="P:log4net.Appender.AppenderSkeleton.Name"/> for more information.
+ </remarks>
+ </member>
+ <member name="F:log4net.Appender.AppenderSkeleton.m_threshold">
+ <summary>
+ The level threshold of this appender.
+ </summary>
+ <remarks>
+ <para>
+ There is no level threshold filtering by default.
+ </para>
+ <para>
+ See <see cref="P:log4net.Appender.AppenderSkeleton.Threshold"/> for more information.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Appender.AppenderSkeleton.m_errorHandler">
+ <summary>
+ It is assumed and enforced that errorHandler is never null.
+ </summary>
+ <remarks>
+ <para>
+ It is assumed and enforced that errorHandler is never null.
+ </para>
+ <para>
+ See <see cref="P:log4net.Appender.AppenderSkeleton.ErrorHandler"/> for more information.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Appender.AppenderSkeleton.m_headFilter">
+ <summary>
+ The first filter in the filter chain.
+ </summary>
+ <remarks>
+ <para>
+ Set to <c>null</c> initially.
+ </para>
+ <para>
+ See <see cref="T:log4net.Filter.IFilter"/> for more information.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Appender.AppenderSkeleton.m_tailFilter">
+ <summary>
+ The last filter in the filter chain.
+ </summary>
+ <remarks>
+ See <see cref="T:log4net.Filter.IFilter"/> for more information.
+ </remarks>
+ </member>
+ <member name="F:log4net.Appender.AppenderSkeleton.m_closed">
+ <summary>
+ Flag indicating if this appender is closed.
+ </summary>
+ <remarks>
+ See <see cref="M:log4net.Appender.AppenderSkeleton.Close"/> for more information.
+ </remarks>
+ </member>
+ <member name="F:log4net.Appender.AppenderSkeleton.m_recursiveGuard">
+ <summary>
+ The guard prevents an appender from repeatedly calling its own DoAppend method
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.AppenderSkeleton.m_renderWriter">
+ <summary>
+ StringWriter used to render events
+ </summary>
+ </member>
+ <member name="P:log4net.Appender.AppenderSkeleton.Threshold">
+ <summary>
+ Gets or sets the threshold <see cref="T:log4net.Core.Level"/> of this appender.
+ </summary>
+ <value>
+ The threshold <see cref="T:log4net.Core.Level"/> of the appender.
+ </value>
+ <remarks>
+ <para>
+ All log events with lower level than the threshold level are ignored
+ by the appender.
+ </para>
+ <para>
+ In configuration files this option is specified by setting the
+ value of the <see cref="P:log4net.Appender.AppenderSkeleton.Threshold"/> option to a level
+ string, such as "DEBUG", "INFO" and so on.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.AppenderSkeleton.ErrorHandler">
+ <summary>
+ Gets or sets the <see cref="T:log4net.Core.IErrorHandler"/> for this appender.
+ </summary>
+ <value>The <see cref="T:log4net.Core.IErrorHandler"/> of the appender</value>
+ <remarks>
+ <para>
+ The <see cref="T:log4net.Appender.AppenderSkeleton"/> provides a default
+ implementation for the <see cref="P:log4net.Appender.AppenderSkeleton.ErrorHandler"/> property.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.AppenderSkeleton.FilterHead">
+ <summary>
+ The filter chain.
+ </summary>
+ <value>The head of the filter chain filter chain.</value>
+ <remarks>
+ <para>
+ Returns the head Filter. The Filters are organized in a linked list
+ and so all Filters on this Appender are available through the result.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.AppenderSkeleton.Layout">
+ <summary>
+ Gets or sets the <see cref="T:log4net.Layout.ILayout"/> for this appender.
+ </summary>
+ <value>The layout of the appender.</value>
+ <remarks>
+ <para>
+ See <see cref="P:log4net.Appender.AppenderSkeleton.RequiresLayout"/> for more information.
+ </para>
+ </remarks>
+ <seealso cref="P:log4net.Appender.AppenderSkeleton.RequiresLayout"/>
+ </member>
+ <member name="P:log4net.Appender.AppenderSkeleton.Name">
+ <summary>
+ Gets or sets the name of this appender.
+ </summary>
+ <value>The name of the appender.</value>
+ <remarks>
+ <para>
+ The name uniquely identifies the appender.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.AppenderSkeleton.RequiresLayout">
+ <summary>
+ Tests if this appender requires a <see cref="P:log4net.Appender.AppenderSkeleton.Layout"/> to be set.
+ </summary>
+ <remarks>
+ <para>
+ In the rather exceptional case, where the appender
+ implementation admits a layout but can also work without it,
+ then the appender should return <c>true</c>.
+ </para>
+ <para>
+ This default implementation always returns <c>true</c>.
+ </para>
+ </remarks>
+ <returns>
+ <c>true</c> if the appender requires a layout object, otherwise <c>false</c>.
+ </returns>
+ </member>
+ <member name="F:log4net.Appender.BufferingAppenderSkeleton.DEFAULT_BUFFER_SIZE">
+ <summary>
+ The default buffer size.
+ </summary>
+ <remarks>
+ The default size of the cyclic buffer used to store events.
+ This is set to 512 by default.
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.BufferingAppenderSkeleton.#ctor">
+ <summary>
+ Initializes a new instance of the <see cref="T:log4net.Appender.BufferingAppenderSkeleton"/> class.
+ </summary>
+ <remarks>
+ <para>
+ Protected default constructor to allow subclassing.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.BufferingAppenderSkeleton.#ctor(System.Boolean)">
+ <summary>
+ Initializes a new instance of the <see cref="T:log4net.Appender.BufferingAppenderSkeleton"/> class.
+ </summary>
+ <param name="eventMustBeFixed">the events passed through this appender must be
+ fixed by the time that they arrive in the derived class' <c>SendBuffer</c> method.</param>
+ <remarks>
+ <para>
+ Protected constructor to allow subclassing.
+ </para>
+ <para>
+ The <paramref name="eventMustBeFixed"/> should be set if the subclass
+ expects the events delivered to be fixed even if the
+ <see cref="P:log4net.Appender.BufferingAppenderSkeleton.BufferSize"/> is set to zero, i.e. when no buffering occurs.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.BufferingAppenderSkeleton.Flush">
+ <summary>
+ Flush the currently buffered events
+ </summary>
+ <remarks>
+ <para>
+ Flushes any events that have been buffered.
+ </para>
+ <para>
+ If the appender is buffering in <see cref="P:log4net.Appender.BufferingAppenderSkeleton.Lossy"/> mode then the contents
+ of the buffer will NOT be flushed to the appender.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.BufferingAppenderSkeleton.Flush(System.Boolean)">
+ <summary>
+ Flush the currently buffered events
+ </summary>
+ <param name="flushLossyBuffer">set to <c>true</c> to flush the buffer of lossy events</param>
+ <remarks>
+ <para>
+ Flushes events that have been buffered. If <paramref name="flushLossyBuffer"/> is
+ <c>false</c> then events will only be flushed if this buffer is non-lossy mode.
+ </para>
+ <para>
+ If the appender is buffering in <see cref="P:log4net.Appender.BufferingAppenderSkeleton.Lossy"/> mode then the contents
+ of the buffer will only be flushed if <paramref name="flushLossyBuffer"/> is <c>true</c>.
+ In this case the contents of the buffer will be tested against the
+ <see cref="P:log4net.Appender.BufferingAppenderSkeleton.LossyEvaluator"/> and if triggering will be output. All other buffered
+ events will be discarded.
+ </para>
+ <para>
+ If <paramref name="flushLossyBuffer"/> is <c>true</c> then the buffer will always
+ be emptied by calling this method.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.BufferingAppenderSkeleton.ActivateOptions">
+ <summary>
+ Initialize the appender based on the options set
+ </summary>
+ <remarks>
+ <para>
+ This is part of the <see cref="T:log4net.Core.IOptionHandler"/> delayed object
+ activation scheme. The <see cref="M:log4net.Appender.BufferingAppenderSkeleton.ActivateOptions"/> method must
+ be called on this object after the configuration properties have
+ been set. Until <see cref="M:log4net.Appender.BufferingAppenderSkeleton.ActivateOptions"/> is called this
+ object is in an undefined state and must not be used.
+ </para>
+ <para>
+ If any of the configuration properties are modified then
+ <see cref="M:log4net.Appender.BufferingAppenderSkeleton.ActivateOptions"/> must be called again.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.BufferingAppenderSkeleton.OnClose">
+ <summary>
+ Close this appender instance.
+ </summary>
+ <remarks>
+ <para>
+ Close this appender instance. If this appender is marked
+ as not <see cref="P:log4net.Appender.BufferingAppenderSkeleton.Lossy"/> then the remaining events in
+ the buffer must be sent when the appender is closed.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.BufferingAppenderSkeleton.Append(log4net.Core.LoggingEvent)">
+ <summary>
+ This method is called by the <see cref="M:log4net.Appender.AppenderSkeleton.DoAppend(log4net.Core.LoggingEvent)"/> method.
+ </summary>
+ <param name="loggingEvent">the event to log</param>
+ <remarks>
+ <para>
+ Stores the <paramref name="loggingEvent"/> in the cyclic buffer.
+ </para>
+ <para>
+ The buffer will be sent (i.e. passed to the <see cref="M:log4net.Appender.BufferingAppenderSkeleton.SendBuffer(log4net.Core.LoggingEvent[])"/>
+ method) if one of the following conditions is met:
+ </para>
+ <list type="bullet">
+ <item>
+ <description>The cyclic buffer is full and this appender is
+ marked as not lossy (see <see cref="P:log4net.Appender.BufferingAppenderSkeleton.Lossy"/>)</description>
+ </item>
+ <item>
+ <description>An <see cref="P:log4net.Appender.BufferingAppenderSkeleton.Evaluator"/> is set and
+ it is triggered for the <paramref name="loggingEvent"/>
+ specified.</description>
+ </item>
+ </list>
+ <para>
+ Before the event is stored in the buffer it is fixed
+ (see <see cref="M:log4net.Core.LoggingEvent.FixVolatileData(log4net.Core.FixFlags)"/>) to ensure that
+ any data referenced by the event will be valid when the buffer
+ is processed.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.BufferingAppenderSkeleton.SendFromBuffer(log4net.Core.LoggingEvent,log4net.Util.CyclicBuffer)">
+ <summary>
+ Sends the contents of the buffer.
+ </summary>
+ <param name="firstLoggingEvent">The first logging event.</param>
+ <param name="buffer">The buffer containing the events that need to be send.</param>
+ <remarks>
+ <para>
+ The subclass must override <see cref="M:log4net.Appender.BufferingAppenderSkeleton.SendBuffer(log4net.Core.LoggingEvent[])"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.BufferingAppenderSkeleton.SendBuffer(log4net.Core.LoggingEvent[])">
+ <summary>
+ Sends the events.
+ </summary>
+ <param name="events">The events that need to be send.</param>
+ <remarks>
+ <para>
+ The subclass must override this method to process the buffered events.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Appender.BufferingAppenderSkeleton.m_bufferSize">
+ <summary>
+ The size of the cyclic buffer used to hold the logging events.
+ </summary>
+ <remarks>
+ Set to <see cref="F:log4net.Appender.BufferingAppenderSkeleton.DEFAULT_BUFFER_SIZE"/> by default.
+ </remarks>
+ </member>
+ <member name="F:log4net.Appender.BufferingAppenderSkeleton.m_cb">
+ <summary>
+ The cyclic buffer used to store the logging events.
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.BufferingAppenderSkeleton.m_evaluator">
+ <summary>
+ The triggering event evaluator that causes the buffer to be sent immediately.
+ </summary>
+ <remarks>
+ The object that is used to determine if an event causes the entire
+ buffer to be sent immediately. This field can be <c>null</c>, which
+ indicates that event triggering is not to be done. The evaluator
+ can be set using the <see cref="P:log4net.Appender.BufferingAppenderSkeleton.Evaluator"/> property. If this appender
+ has the <see cref="F:log4net.Appender.BufferingAppenderSkeleton.m_lossy"/> (<see cref="P:log4net.Appender.BufferingAppenderSkeleton.Lossy"/> property) set to
+ <c>true</c> then an <see cref="P:log4net.Appender.BufferingAppenderSkeleton.Evaluator"/> must be set.
+ </remarks>
+ </member>
+ <member name="F:log4net.Appender.BufferingAppenderSkeleton.m_lossy">
+ <summary>
+ Indicates if the appender should overwrite events in the cyclic buffer
+ when it becomes full, or if the buffer should be flushed when the
+ buffer is full.
+ </summary>
+ <remarks>
+ If this field is set to <c>true</c> then an <see cref="P:log4net.Appender.BufferingAppenderSkeleton.Evaluator"/> must
+ be set.
+ </remarks>
+ </member>
+ <member name="F:log4net.Appender.BufferingAppenderSkeleton.m_lossyEvaluator">
+ <summary>
+ The triggering event evaluator filters discarded events.
+ </summary>
+ <remarks>
+ The object that is used to determine if an event that is discarded should
+ really be discarded or if it should be sent to the appenders.
+ This field can be <c>null</c>, which indicates that all discarded events will
+ be discarded.
+ </remarks>
+ </member>
+ <member name="F:log4net.Appender.BufferingAppenderSkeleton.m_fixFlags">
+ <summary>
+ Value indicating which fields in the event should be fixed
+ </summary>
+ <remarks>
+ By default all fields are fixed
+ </remarks>
+ </member>
+ <member name="F:log4net.Appender.BufferingAppenderSkeleton.m_eventMustBeFixed">
+ <summary>
+ The events delivered to the subclass must be fixed.
+ </summary>
+ </member>
+ <member name="P:log4net.Appender.BufferingAppenderSkeleton.Lossy">
+ <summary>
+ Gets or sets a value that indicates whether the appender is lossy.
+ </summary>
+ <value>
+ <c>true</c> if the appender is lossy, otherwise <c>false</c>. The default is <c>false</c>.
+ </value>
+ <remarks>
+ <para>
+ This appender uses a buffer to store logging events before
+ delivering them. A triggering event causes the whole buffer
+ to be send to the remote sink. If the buffer overruns before
+ a triggering event then logging events could be lost. Set
+ <see cref="P:log4net.Appender.BufferingAppenderSkeleton.Lossy"/> to <c>false</c> to prevent logging events
+ from being lost.
+ </para>
+ <para>If <see cref="P:log4net.Appender.BufferingAppenderSkeleton.Lossy"/> is set to <c>true</c> then an
+ <see cref="P:log4net.Appender.BufferingAppenderSkeleton.Evaluator"/> must be specified.</para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.BufferingAppenderSkeleton.BufferSize">
+ <summary>
+ Gets or sets the size of the cyclic buffer used to hold the
+ logging events.
+ </summary>
+ <value>
+ The size of the cyclic buffer used to hold the logging events.
+ </value>
+ <remarks>
+ <para>
+ The <see cref="P:log4net.Appender.BufferingAppenderSkeleton.BufferSize"/> option takes a positive integer
+ representing the maximum number of logging events to collect in
+ a cyclic buffer. When the <see cref="P:log4net.Appender.BufferingAppenderSkeleton.BufferSize"/> is reached,
+ oldest events are deleted as new events are added to the
+ buffer. By default the size of the cyclic buffer is 512 events.
+ </para>
+ <para>
+ If the <see cref="P:log4net.Appender.BufferingAppenderSkeleton.BufferSize"/> is set to a value less than
+ or equal to 1 then no buffering will occur. The logging event
+ will be delivered synchronously (depending on the <see cref="P:log4net.Appender.BufferingAppenderSkeleton.Lossy"/>
+ and <see cref="P:log4net.Appender.BufferingAppenderSkeleton.Evaluator"/> properties). Otherwise the event will
+ be buffered.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.BufferingAppenderSkeleton.Evaluator">
+ <summary>
+ Gets or sets the <see cref="T:log4net.Core.ITriggeringEventEvaluator"/> that causes the
+ buffer to be sent immediately.
+ </summary>
+ <value>
+ The <see cref="T:log4net.Core.ITriggeringEventEvaluator"/> that causes the buffer to be
+ sent immediately.
+ </value>
+ <remarks>
+ <para>
+ The evaluator will be called for each event that is appended to this
+ appender. If the evaluator triggers then the current buffer will
+ immediately be sent (see <see cref="M:log4net.Appender.BufferingAppenderSkeleton.SendBuffer(log4net.Core.LoggingEvent[])"/>).
+ </para>
+ <para>If <see cref="P:log4net.Appender.BufferingAppenderSkeleton.Lossy"/> is set to <c>true</c> then an
+ <see cref="P:log4net.Appender.BufferingAppenderSkeleton.Evaluator"/> must be specified.</para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.BufferingAppenderSkeleton.LossyEvaluator">
+ <summary>
+ Gets or sets the value of the <see cref="T:log4net.Core.ITriggeringEventEvaluator"/> to use.
+ </summary>
+ <value>
+ The value of the <see cref="T:log4net.Core.ITriggeringEventEvaluator"/> to use.
+ </value>
+ <remarks>
+ <para>
+ The evaluator will be called for each event that is discarded from this
+ appender. If the evaluator triggers then the current buffer will immediately
+ be sent (see <see cref="M:log4net.Appender.BufferingAppenderSkeleton.SendBuffer(log4net.Core.LoggingEvent[])"/>).
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.BufferingAppenderSkeleton.OnlyFixPartialEventData">
+ <summary>
+ Gets or sets a value indicating if only part of the logging event data
+ should be fixed.
+ </summary>
+ <value>
+ <c>true</c> if the appender should only fix part of the logging event
+ data, otherwise <c>false</c>. The default is <c>false</c>.
+ </value>
+ <remarks>
+ <para>
+ Setting this property to <c>true</c> will cause only part of the
+ event data to be fixed and serialized. This will improve performance.
+ </para>
+ <para>
+ See <see cref="M:log4net.Core.LoggingEvent.FixVolatileData(log4net.Core.FixFlags)"/> for more information.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.BufferingAppenderSkeleton.Fix">
+ <summary>
+ Gets or sets a the fields that will be fixed in the event
+ </summary>
+ <value>
+ The event fields that will be fixed before the event is buffered
+ </value>
+ <remarks>
+ <para>
+ The logging event needs to have certain thread specific values
+ captured before it can be buffered. See <see cref="P:log4net.Core.LoggingEvent.Fix"/>
+ for details.
+ </para>
+ </remarks>
+ <seealso cref="P:log4net.Core.LoggingEvent.Fix"/>
+ </member>
+ <member name="M:log4net.Appender.AdoNetAppender.#ctor">
+ <summary>
+ Initializes a new instance of the <see cref="T:log4net.Appender.AdoNetAppender"/> class.
+ </summary>
+ <remarks>
+ Public default constructor to initialize a new instance of this class.
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.AdoNetAppender.ActivateOptions">
+ <summary>
+ Initialize the appender based on the options set
+ </summary>
+ <remarks>
+ <para>
+ This is part of the <see cref="T:log4net.Core.IOptionHandler"/> delayed object
+ activation scheme. The <see cref="M:log4net.Appender.AdoNetAppender.ActivateOptions"/> method must
+ be called on this object after the configuration properties have
+ been set. Until <see cref="M:log4net.Appender.AdoNetAppender.ActivateOptions"/> is called this
+ object is in an undefined state and must not be used.
+ </para>
+ <para>
+ If any of the configuration properties are modified then
+ <see cref="M:log4net.Appender.AdoNetAppender.ActivateOptions"/> must be called again.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.AdoNetAppender.OnClose">
+ <summary>
+ Override the parent method to close the database
+ </summary>
+ <remarks>
+ <para>
+ Closes the database command and database connection.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.AdoNetAppender.SendBuffer(log4net.Core.LoggingEvent[])">
+ <summary>
+ Inserts the events into the database.
+ </summary>
+ <param name="events">The events to insert into the database.</param>
+ <remarks>
+ <para>
+ Insert all the events specified in the <paramref name="events"/>
+ array into the database.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.AdoNetAppender.AddParameter(log4net.Appender.AdoNetAppenderParameter)">
+ <summary>
+ Adds a parameter to the command.
+ </summary>
+ <param name="parameter">The parameter to add to the command.</param>
+ <remarks>
+ <para>
+ Adds a parameter to the ordered list of command parameters.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.AdoNetAppender.SendBuffer(System.Data.IDbTransaction,log4net.Core.LoggingEvent[])">
+ <summary>
+ Writes the events to the database using the transaction specified.
+ </summary>
+ <param name="dbTran">The transaction that the events will be executed under.</param>
+ <param name="events">The array of events to insert into the database.</param>
+ <remarks>
+ <para>
+ The transaction argument can be <c>null</c> if the appender has been
+ configured not to use transactions. See <see cref="P:log4net.Appender.AdoNetAppender.UseTransactions"/>
+ property for more information.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.AdoNetAppender.GetLogStatement(log4net.Core.LoggingEvent)">
+ <summary>
+ Formats the log message into database statement text.
+ </summary>
+ <param name="logEvent">The event being logged.</param>
+ <remarks>
+ This method can be overridden by subclasses to provide
+ more control over the format of the database statement.
+ </remarks>
+ <returns>
+ Text that can be passed to a <see cref="T:System.Data.IDbCommand"/>.
+ </returns>
+ </member>
+ <member name="M:log4net.Appender.AdoNetAppender.InitializeDatabaseConnection">
+ <summary>
+ Connects to the database.
+ </summary>
+ </member>
+ <member name="M:log4net.Appender.AdoNetAppender.ResolveConnectionType">
+ <summary>
+ Retrieves the class type of the ADO.NET provider.
+ </summary>
+ <remarks>
+ <para>
+ Gets the Type of the ADO.NET provider to use to connect to the
+ database. This method resolves the type specified in the
+ <see cref="P:log4net.Appender.AdoNetAppender.ConnectionType"/> property.
+ </para>
+ <para>
+ Subclasses can override this method to return a different type
+ if necessary.
+ </para>
+ </remarks>
+ <returns>The <see cref="T:System.Type"/> of the ADO.NET provider</returns>
+ </member>
+ <member name="M:log4net.Appender.AdoNetAppender.InitializeDatabaseCommand">
+ <summary>
+ Prepares the database command and initialize the parameters.
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.AdoNetAppender.m_usePreparedCommand">
+ <summary>
+ Flag to indicate if we are using a command object
+ </summary>
+ <remarks>
+ <para>
+ Set to <c>true</c> when the appender is to use a prepared
+ statement or stored procedure to insert into the database.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Appender.AdoNetAppender.m_parameters">
+ <summary>
+ The list of <see cref="T:log4net.Appender.AdoNetAppenderParameter"/> objects.
+ </summary>
+ <remarks>
+ <para>
+ The list of <see cref="T:log4net.Appender.AdoNetAppenderParameter"/> objects.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Appender.AdoNetAppender.m_securityContext">
+ <summary>
+ The security context to use for privileged calls
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.AdoNetAppender.m_dbConnection">
+ <summary>
+ The <see cref="T:System.Data.IDbConnection"/> that will be used
+ to insert logging events into a database.
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.AdoNetAppender.m_dbCommand">
+ <summary>
+ The database command.
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.AdoNetAppender.m_connectionString">
+ <summary>
+ Database connection string.
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.AdoNetAppender.m_connectionType">
+ <summary>
+ String type name of the <see cref="T:System.Data.IDbConnection"/> type name.
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.AdoNetAppender.m_commandText">
+ <summary>
+ The text of the command.
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.AdoNetAppender.m_commandType">
+ <summary>
+ The command type.
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.AdoNetAppender.m_useTransactions">
+ <summary>
+ Indicates whether to use transactions when writing to the database.
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.AdoNetAppender.m_reconnectOnError">
+ <summary>
+ Indicates whether to use transactions when writing to the database.
+ </summary>
+ </member>
+ <member name="P:log4net.Appender.AdoNetAppender.ConnectionString">
+ <summary>
+ Gets or sets the database connection string that is used to connect to
+ the database.
+ </summary>
+ <value>
+ The database connection string used to connect to the database.
+ </value>
+ <remarks>
+ <para>
+ The connections string is specific to the connection type.
+ See <see cref="P:log4net.Appender.AdoNetAppender.ConnectionType"/> for more information.
+ </para>
+ </remarks>
+ <example>Connection string for MS Access via ODBC:
+ <code>"DSN=MS Access Database;UID=admin;PWD=;SystemDB=C:\data\System.mdw;SafeTransactions = 0;FIL=MS Access;DriverID = 25;DBQ=C:\data\train33.mdb"</code>
+ </example>
+ <example>Another connection string for MS Access via ODBC:
+ <code>"Driver={Microsoft Access Driver (*.mdb)};DBQ=C:\Work\cvs_root\log4net-1.2\access.mdb;UID=;PWD=;"</code>
+ </example>
+ <example>Connection string for MS Access via OLE DB:
+ <code>"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\Work\cvs_root\log4net-1.2\access.mdb;User Id=;Password=;"</code>
+ </example>
+ </member>
+ <member name="P:log4net.Appender.AdoNetAppender.ConnectionType">
+ <summary>
+ Gets or sets the type name of the <see cref="T:System.Data.IDbConnection"/> connection
+ that should be created.
+ </summary>
+ <value>
+ The type name of the <see cref="T:System.Data.IDbConnection"/> connection.
+ </value>
+ <remarks>
+ <para>
+ The type name of the ADO.NET provider to use.
+ </para>
+ <para>
+ The default is to use the OLE DB provider.
+ </para>
+ </remarks>
+ <example>Use the OLE DB Provider. This is the default value.
+ <code>System.Data.OleDb.OleDbConnection, System.Data, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</code>
+ </example>
+ <example>Use the MS SQL Server Provider.
+ <code>System.Data.SqlClient.SqlConnection, System.Data, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</code>
+ </example>
+ <example>Use the ODBC Provider.
+ <code>Microsoft.Data.Odbc.OdbcConnection,Microsoft.Data.Odbc,version=1.0.3300.0,publicKeyToken=b77a5c561934e089,culture=neutral</code>
+ This is an optional package that you can download from
+ <a href="http://msdn.microsoft.com/downloads">http://msdn.microsoft.com/downloads</a>
+ search for <b>ODBC .NET Data Provider</b>.
+ </example>
+ <example>Use the Oracle Provider.
+ <code>System.Data.OracleClient.OracleConnection, System.Data.OracleClient, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</code>
+ This is an optional package that you can download from
+ <a href="http://msdn.microsoft.com/downloads">http://msdn.microsoft.com/downloads</a>
+ search for <b>.NET Managed Provider for Oracle</b>.
+ </example>
+ </member>
+ <member name="P:log4net.Appender.AdoNetAppender.CommandText">
+ <summary>
+ Gets or sets the command text that is used to insert logging events
+ into the database.
+ </summary>
+ <value>
+ The command text used to insert logging events into the database.
+ </value>
+ <remarks>
+ <para>
+ Either the text of the prepared statement or the
+ name of the stored procedure to execute to write into
+ the database.
+ </para>
+ <para>
+ The <see cref="P:log4net.Appender.AdoNetAppender.CommandType"/> property determines if
+ this text is a prepared statement or a stored procedure.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.AdoNetAppender.CommandType">
+ <summary>
+ Gets or sets the command type to execute.
+ </summary>
+ <value>
+ The command type to execute.
+ </value>
+ <remarks>
+ <para>
+ This value may be either <see cref="F:System.Data.CommandType.Text"/> (<c>System.Data.CommandType.Text</c>) to specify
+ that the <see cref="P:log4net.Appender.AdoNetAppender.CommandText"/> is a prepared statement to execute,
+ or <see cref="F:System.Data.CommandType.StoredProcedure"/> (<c>System.Data.CommandType.StoredProcedure</c>) to specify that the
+ <see cref="P:log4net.Appender.AdoNetAppender.CommandText"/> property is the name of a stored procedure
+ to execute.
+ </para>
+ <para>
+ The default value is <see cref="F:System.Data.CommandType.Text"/> (<c>System.Data.CommandType.Text</c>).
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.AdoNetAppender.UseTransactions">
+ <summary>
+ Should transactions be used to insert logging events in the database.
+ </summary>
+ <value>
+ <c>true</c> if transactions should be used to insert logging events in
+ the database, otherwise <c>false</c>. The default value is <c>true</c>.
+ </value>
+ <remarks>
+ <para>
+ Gets or sets a value that indicates whether transactions should be used
+ to insert logging events in the database.
+ </para>
+ <para>
+ When set a single transaction will be used to insert the buffered events
+ into the database. Otherwise each event will be inserted without using
+ an explicit transaction.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.AdoNetAppender.SecurityContext">
+ <summary>
+ Gets or sets the <see cref="P:log4net.Appender.AdoNetAppender.SecurityContext"/> used to call the NetSend method.
+ </summary>
+ <value>
+ The <see cref="P:log4net.Appender.AdoNetAppender.SecurityContext"/> used to call the NetSend method.
+ </value>
+ <remarks>
+ <para>
+ Unless a <see cref="P:log4net.Appender.AdoNetAppender.SecurityContext"/> specified here for this appender
+ the <see cref="P:log4net.Core.SecurityContextProvider.DefaultProvider"/> is queried for the
+ security context to use. The default behavior is to use the security context
+ of the current thread.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.AdoNetAppender.ReconnectOnError">
+ <summary>
+ Should this appender try to reconnect to the database on error.
+ </summary>
+ <value>
+ <c>true</c> if the appender should try to reconnect to the database after an
+ error has occurred, otherwise <c>false</c>. The default value is <c>false</c>,
+ i.e. not to try to reconnect.
+ </value>
+ <remarks>
+ <para>
+ The default behaviour is for the appender not to try to reconnect to the
+ database if an error occurs. Subsequent logging events are discarded.
+ </para>
+ <para>
+ To force the appender to attempt to reconnect to the database set this
+ property to <c>true</c>.
+ </para>
+ <note>
+ When the appender attempts to connect to the database there may be a
+ delay of up to the connection timeout specified in the connection string.
+ This delay will block the calling application's thread.
+ Until the connection can be reestablished this potential delay may occur multiple times.
+ </note>
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.AdoNetAppender.Connection">
+ <summary>
+ Gets or sets the underlying <see cref="T:System.Data.IDbConnection"/>.
+ </summary>
+ <value>
+ The underlying <see cref="T:System.Data.IDbConnection"/>.
+ </value>
+ <remarks>
+ <see cref="T:log4net.Appender.AdoNetAppender"/> creates a <see cref="T:System.Data.IDbConnection"/> to insert
+ logging events into a database. Classes deriving from <see cref="T:log4net.Appender.AdoNetAppender"/>
+ can use this property to get or set this <see cref="T:System.Data.IDbConnection"/>. Use the
+ underlying <see cref="T:System.Data.IDbConnection"/> returned from <see cref="P:log4net.Appender.AdoNetAppender.Connection"/> if
+ you require access beyond that which <see cref="T:log4net.Appender.AdoNetAppender"/> provides.
+ </remarks>
+ </member>
+ <member name="T:log4net.Appender.AdoNetAppenderParameter">
+ <summary>
+ Parameter type used by the <see cref="T:log4net.Appender.AdoNetAppender"/>.
+ </summary>
+ <remarks>
+ <para>
+ This class provides the basic database parameter properties
+ as defined by the <see cref="T:System.Data.IDbDataParameter"/> interface.
+ </para>
+ <para>This type can be subclassed to provide database specific
+ functionality. The two methods that are called externally are
+ <see cref="M:log4net.Appender.AdoNetAppenderParameter.Prepare(System.Data.IDbCommand)"/> and <see cref="M:log4net.Appender.AdoNetAppenderParameter.FormatValue(System.Data.IDbCommand,log4net.Core.LoggingEvent)"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.AdoNetAppenderParameter.#ctor">
+ <summary>
+ Initializes a new instance of the <see cref="T:log4net.Appender.AdoNetAppenderParameter"/> class.
+ </summary>
+ <remarks>
+ Default constructor for the AdoNetAppenderParameter class.
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.AdoNetAppenderParameter.Prepare(System.Data.IDbCommand)">
+ <summary>
+ Prepare the specified database command object.
+ </summary>
+ <param name="command">The command to prepare.</param>
+ <remarks>
+ <para>
+ Prepares the database command object by adding
+ this parameter to its collection of parameters.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.AdoNetAppenderParameter.FormatValue(System.Data.IDbCommand,log4net.Core.LoggingEvent)">
+ <summary>
+ Renders the logging event and set the parameter value in the command.
+ </summary>
+ <param name="command">The command containing the parameter.</param>
+ <param name="loggingEvent">The event to be rendered.</param>
+ <remarks>
+ <para>
+ Renders the logging event using this parameters layout
+ object. Sets the value of the parameter on the command object.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Appender.AdoNetAppenderParameter.m_parameterName">
+ <summary>
+ The name of this parameter.
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.AdoNetAppenderParameter.m_dbType">
+ <summary>
+ The database type for this parameter.
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.AdoNetAppenderParameter.m_inferType">
+ <summary>
+ Flag to infer type rather than use the DbType
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.AdoNetAppenderParameter.m_precision">
+ <summary>
+ The precision for this parameter.
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.AdoNetAppenderParameter.m_scale">
+ <summary>
+ The scale for this parameter.
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.AdoNetAppenderParameter.m_size">
+ <summary>
+ The size for this parameter.
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.AdoNetAppenderParameter.m_layout">
+ <summary>
+ The <see cref="T:log4net.Layout.IRawLayout"/> to use to render the
+ logging event into an object for this parameter.
+ </summary>
+ </member>
+ <member name="P:log4net.Appender.AdoNetAppenderParameter.ParameterName">
+ <summary>
+ Gets or sets the name of this parameter.
+ </summary>
+ <value>
+ The name of this parameter.
+ </value>
+ <remarks>
+ <para>
+ The name of this parameter. The parameter name
+ must match up to a named parameter to the SQL stored procedure
+ or prepared statement.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.AdoNetAppenderParameter.DbType">
+ <summary>
+ Gets or sets the database type for this parameter.
+ </summary>
+ <value>
+ The database type for this parameter.
+ </value>
+ <remarks>
+ <para>
+ The database type for this parameter. This property should
+ be set to the database type from the <see cref="P:log4net.Appender.AdoNetAppenderParameter.DbType"/>
+ enumeration. See <see cref="P:System.Data.IDataParameter.DbType"/>.
+ </para>
+ <para>
+ This property is optional. If not specified the ADO.NET provider
+ will attempt to infer the type from the value.
+ </para>
+ </remarks>
+ <seealso cref="P:System.Data.IDataParameter.DbType"/>
+ </member>
+ <member name="P:log4net.Appender.AdoNetAppenderParameter.Precision">
+ <summary>
+ Gets or sets the precision for this parameter.
+ </summary>
+ <value>
+ The precision for this parameter.
+ </value>
+ <remarks>
+ <para>
+ The maximum number of digits used to represent the Value.
+ </para>
+ <para>
+ This property is optional. If not specified the ADO.NET provider
+ will attempt to infer the precision from the value.
+ </para>
+ </remarks>
+ <seealso cref="P:System.Data.IDbDataParameter.Precision"/>
+ </member>
+ <member name="P:log4net.Appender.AdoNetAppenderParameter.Scale">
+ <summary>
+ Gets or sets the scale for this parameter.
+ </summary>
+ <value>
+ The scale for this parameter.
+ </value>
+ <remarks>
+ <para>
+ The number of decimal places to which Value is resolved.
+ </para>
+ <para>
+ This property is optional. If not specified the ADO.NET provider
+ will attempt to infer the scale from the value.
+ </para>
+ </remarks>
+ <seealso cref="P:System.Data.IDbDataParameter.Scale"/>
+ </member>
+ <member name="P:log4net.Appender.AdoNetAppenderParameter.Size">
+ <summary>
+ Gets or sets the size for this parameter.
+ </summary>
+ <value>
+ The size for this parameter.
+ </value>
+ <remarks>
+ <para>
+ The maximum size, in bytes, of the data within the column.
+ </para>
+ <para>
+ This property is optional. If not specified the ADO.NET provider
+ will attempt to infer the size from the value.
+ </para>
+ </remarks>
+ <seealso cref="P:System.Data.IDbDataParameter.Size"/>
+ </member>
+ <member name="P:log4net.Appender.AdoNetAppenderParameter.Layout">
+ <summary>
+ Gets or sets the <see cref="T:log4net.Layout.IRawLayout"/> to use to
+ render the logging event into an object for this
+ parameter.
+ </summary>
+ <value>
+ The <see cref="T:log4net.Layout.IRawLayout"/> used to render the
+ logging event into an object for this parameter.
+ </value>
+ <remarks>
+ <para>
+ The <see cref="T:log4net.Layout.IRawLayout"/> that renders the value for this
+ parameter.
+ </para>
+ <para>
+ The <see cref="T:log4net.Layout.RawLayoutConverter"/> can be used to adapt
+ any <see cref="T:log4net.Layout.ILayout"/> into a <see cref="T:log4net.Layout.IRawLayout"/>
+ for use in the property.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Appender.AnsiColorTerminalAppender">
+ <summary>
+ Appends logging events to the terminal using ANSI color escape sequences.
+ </summary>
+ <remarks>
+ <para>
+ AnsiColorTerminalAppender appends log events to the standard output stream
+ or the error output stream using a layout specified by the
+ user. It also allows the color of a specific level of message to be set.
+ </para>
+ <note>
+ This appender expects the terminal to understand the VT100 control set
+ in order to interpret the color codes. If the terminal or console does not
+ understand the control codes the behavior is not defined.
+ </note>
+ <para>
+ By default, all output is written to the console's standard output stream.
+ The <see cref="P:log4net.Appender.AnsiColorTerminalAppender.Target"/> property can be set to direct the output to the
+ error stream.
+ </para>
+ <para>
+ NOTE: This appender writes each message to the <c>System.Console.Out</c> or
+ <c>System.Console.Error</c> that is set at the time the event is appended.
+ Therefore it is possible to programmatically redirect the output of this appender
+ (for example NUnit does this to capture program output). While this is the desired
+ behavior of this appender it may have security implications in your application.
+ </para>
+ <para>
+ When configuring the ANSI colored terminal appender, a mapping should be
+ specified to map a logging level to a color. For example:
+ </para>
+ <code lang="XML" escaped="true">
+ <mapping>
+ <level value="ERROR"/>
+ <foreColor value="White"/>
+ <backColor value="Red"/>
+ <attributes value="Bright,Underscore"/>
+ </mapping>
+ <mapping>
+ <level value="DEBUG"/>
+ <backColor value="Green"/>
+ </mapping>
+ </code>
+ <para>
+ The Level is the standard log4net logging level and ForeColor and BackColor can be any
+ of the following values:
+ <list type="bullet">
+ <item><term>Blue</term><description></description></item>
+ <item><term>Green</term><description></description></item>
+ <item><term>Red</term><description></description></item>
+ <item><term>White</term><description></description></item>
+ <item><term>Yellow</term><description></description></item>
+ <item><term>Purple</term><description></description></item>
+ <item><term>Cyan</term><description></description></item>
+ </list>
+ These color values cannot be combined together to make new colors.
+ </para>
+ <para>
+ The attributes can be any combination of the following:
+ <list type="bullet">
+ <item><term>Bright</term><description>foreground is brighter</description></item>
+ <item><term>Dim</term><description>foreground is dimmer</description></item>
+ <item><term>Underscore</term><description>message is underlined</description></item>
+ <item><term>Blink</term><description>foreground is blinking (does not work on all terminals)</description></item>
+ <item><term>Reverse</term><description>foreground and background are reversed</description></item>
+ <item><term>Hidden</term><description>output is hidden</description></item>
+ <item><term>Strikethrough</term><description>message has a line through it</description></item>
+ </list>
+ While any of these attributes may be combined together not all combinations
+ work well together, for example setting both <i>Bright</i> and <i>Dim</i> attributes makes
+ no sense.
+ </para>
+ </remarks>
+ <author>Patrick Wagstrom</author>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="F:log4net.Appender.AnsiColorTerminalAppender.ConsoleOut">
+ <summary>
+ The <see cref="P:log4net.Appender.AnsiColorTerminalAppender.Target"/> to use when writing to the Console
+ standard output stream.
+ </summary>
+ <remarks>
+ <para>
+ The <see cref="P:log4net.Appender.AnsiColorTerminalAppender.Target"/> to use when writing to the Console
+ standard output stream.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Appender.AnsiColorTerminalAppender.ConsoleError">
+ <summary>
+ The <see cref="P:log4net.Appender.AnsiColorTerminalAppender.Target"/> to use when writing to the Console
+ standard error output stream.
+ </summary>
+ <remarks>
+ <para>
+ The <see cref="P:log4net.Appender.AnsiColorTerminalAppender.Target"/> to use when writing to the Console
+ standard error output stream.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Appender.AnsiColorTerminalAppender.PostEventCodes">
+ <summary>
+ Ansi code to reset terminal
+ </summary>
+ </member>
+ <member name="M:log4net.Appender.AnsiColorTerminalAppender.#ctor">
+ <summary>
+ Initializes a new instance of the <see cref="T:log4net.Appender.AnsiColorTerminalAppender"/> class.
+ </summary>
+ <remarks>
+ The instance of the <see cref="T:log4net.Appender.AnsiColorTerminalAppender"/> class is set up to write
+ to the standard output stream.
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.AnsiColorTerminalAppender.AddMapping(log4net.Appender.AnsiColorTerminalAppender.LevelColors)">
+ <summary>
+ Add a mapping of level to color
+ </summary>
+ <param name="mapping">The mapping to add</param>
+ <remarks>
+ <para>
+ Add a <see cref="T:log4net.Appender.AnsiColorTerminalAppender.LevelColors"/> mapping to this appender.
+ Each mapping defines the foreground and background colours
+ for a level.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.AnsiColorTerminalAppender.Append(log4net.Core.LoggingEvent)">
+ <summary>
+ This method is called by the <see cref="M:log4net.Appender.AppenderSkeleton.DoAppend(log4net.Core.LoggingEvent)"/> method.
+ </summary>
+ <param name="loggingEvent">The event to log.</param>
+ <remarks>
+ <para>
+ Writes the event to the console.
+ </para>
+ <para>
+ The format of the output will depend on the appender's layout.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.AnsiColorTerminalAppender.ActivateOptions">
+ <summary>
+ Initialize the options for this appender
+ </summary>
+ <remarks>
+ <para>
+ Initialize the level to color mappings set on this appender.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Appender.AnsiColorTerminalAppender.m_writeToErrorStream">
+ <summary>
+ Flag to write output to the error stream rather than the standard output stream
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.AnsiColorTerminalAppender.m_levelMapping">
+ <summary>
+ Mapping from level object to color value
+ </summary>
+ </member>
+ <member name="P:log4net.Appender.AnsiColorTerminalAppender.Target">
+ <summary>
+ Target is the value of the console output stream.
+ </summary>
+ <value>
+ Target is the value of the console output stream.
+ This is either <c>"Console.Out"</c> or <c>"Console.Error"</c>.
+ </value>
+ <remarks>
+ <para>
+ Target is the value of the console output stream.
+ This is either <c>"Console.Out"</c> or <c>"Console.Error"</c>.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.AnsiColorTerminalAppender.RequiresLayout">
+ <summary>
+ This appender requires a <see cref="N:log4net.Layout"/> to be set.
+ </summary>
+ <value><c>true</c></value>
+ <remarks>
+ <para>
+ This appender requires a <see cref="N:log4net.Layout"/> to be set.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Appender.AnsiColorTerminalAppender.AnsiAttributes">
+ <summary>
+ The enum of possible display attributes
+ </summary>
+ <remarks>
+ <para>
+ The following flags can be combined together to
+ form the ANSI color attributes.
+ </para>
+ </remarks>
+ <seealso cref="T:log4net.Appender.AnsiColorTerminalAppender"/>
+ </member>
+ <member name="F:log4net.Appender.AnsiColorTerminalAppender.AnsiAttributes.Bright">
+ <summary>
+ text is bright
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.AnsiColorTerminalAppender.AnsiAttributes.Dim">
+ <summary>
+ text is dim
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.AnsiColorTerminalAppender.AnsiAttributes.Underscore">
+ <summary>
+ text is underlined
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.AnsiColorTerminalAppender.AnsiAttributes.Blink">
+ <summary>
+ text is blinking
+ </summary>
+ <remarks>
+ Not all terminals support this attribute
+ </remarks>
+ </member>
+ <member name="F:log4net.Appender.AnsiColorTerminalAppender.AnsiAttributes.Reverse">
+ <summary>
+ text and background colors are reversed
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.AnsiColorTerminalAppender.AnsiAttributes.Hidden">
+ <summary>
+ text is hidden
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.AnsiColorTerminalAppender.AnsiAttributes.Strikethrough">
+ <summary>
+ text is displayed with a strikethrough
+ </summary>
+ </member>
+ <member name="T:log4net.Appender.AnsiColorTerminalAppender.AnsiColor">
+ <summary>
+ The enum of possible foreground or background color values for
+ use with the color mapping method
+ </summary>
+ <remarks>
+ <para>
+ The output can be in one for the following ANSI colors.
+ </para>
+ </remarks>
+ <seealso cref="T:log4net.Appender.AnsiColorTerminalAppender"/>
+ </member>
+ <member name="F:log4net.Appender.AnsiColorTerminalAppender.AnsiColor.Black">
+ <summary>
+ color is black
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.AnsiColorTerminalAppender.AnsiColor.Red">
+ <summary>
+ color is red
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.AnsiColorTerminalAppender.AnsiColor.Green">
+ <summary>
+ color is green
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.AnsiColorTerminalAppender.AnsiColor.Yellow">
+ <summary>
+ color is yellow
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.AnsiColorTerminalAppender.AnsiColor.Blue">
+ <summary>
+ color is blue
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.AnsiColorTerminalAppender.AnsiColor.Magenta">
+ <summary>
+ color is magenta
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.AnsiColorTerminalAppender.AnsiColor.Cyan">
+ <summary>
+ color is cyan
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.AnsiColorTerminalAppender.AnsiColor.White">
+ <summary>
+ color is white
+ </summary>
+ </member>
+ <member name="T:log4net.Appender.AnsiColorTerminalAppender.LevelColors">
+ <summary>
+ A class to act as a mapping between the level that a logging call is made at and
+ the color it should be displayed as.
+ </summary>
+ <remarks>
+ <para>
+ Defines the mapping between a level and the color it should be displayed in.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Util.LevelMappingEntry">
+ <summary>
+ An entry in the <see cref="T:log4net.Util.LevelMapping"/>
+ </summary>
+ <remarks>
+ <para>
+ This is an abstract base class for types that are stored in the
+ <see cref="T:log4net.Util.LevelMapping"/> object.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="M:log4net.Util.LevelMappingEntry.#ctor">
+ <summary>
+ Default protected constructor
+ </summary>
+ <remarks>
+ <para>
+ Default protected constructor
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.LevelMappingEntry.ActivateOptions">
+ <summary>
+ Initialize any options defined on this entry
+ </summary>
+ <remarks>
+ <para>
+ Should be overridden by any classes that need to initialise based on their options
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Util.LevelMappingEntry.Level">
+ <summary>
+ The level that is the key for this mapping
+ </summary>
+ <value>
+ The <see cref="P:log4net.Util.LevelMappingEntry.Level"/> that is the key for this mapping
+ </value>
+ <remarks>
+ <para>
+ Get or set the <see cref="P:log4net.Util.LevelMappingEntry.Level"/> that is the key for this
+ mapping subclass.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.AnsiColorTerminalAppender.LevelColors.ActivateOptions">
+ <summary>
+ Initialize the options for the object
+ </summary>
+ <remarks>
+ <para>
+ Combine the <see cref="P:log4net.Appender.AnsiColorTerminalAppender.LevelColors.ForeColor"/> and <see cref="P:log4net.Appender.AnsiColorTerminalAppender.LevelColors.BackColor"/> together
+ and append the attributes.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.AnsiColorTerminalAppender.LevelColors.ForeColor">
+ <summary>
+ The mapped foreground color for the specified level
+ </summary>
+ <remarks>
+ <para>
+ Required property.
+ The mapped foreground color for the specified level
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.AnsiColorTerminalAppender.LevelColors.BackColor">
+ <summary>
+ The mapped background color for the specified level
+ </summary>
+ <remarks>
+ <para>
+ Required property.
+ The mapped background color for the specified level
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.AnsiColorTerminalAppender.LevelColors.Attributes">
+ <summary>
+ The color attributes for the specified level
+ </summary>
+ <remarks>
+ <para>
+ Required property.
+ The color attributes for the specified level
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.AnsiColorTerminalAppender.LevelColors.CombinedColor">
+ <summary>
+ The combined <see cref="P:log4net.Appender.AnsiColorTerminalAppender.LevelColors.ForeColor"/>, <see cref="P:log4net.Appender.AnsiColorTerminalAppender.LevelColors.BackColor"/> and
+ <see cref="P:log4net.Appender.AnsiColorTerminalAppender.LevelColors.Attributes"/> suitable for setting the ansi terminal color.
+ </summary>
+ </member>
+ <member name="T:log4net.Appender.AppenderCollection">
+ <summary>
+ A strongly-typed collection of <see cref="T:log4net.Appender.IAppender"/> objects.
+ </summary>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="M:log4net.Appender.AppenderCollection.ReadOnly(log4net.Appender.AppenderCollection)">
+ <summary>
+ Creates a read-only wrapper for a <c>AppenderCollection</c> instance.
+ </summary>
+ <param name="list">list to create a readonly wrapper arround</param>
+ <returns>
+ An <c>AppenderCollection</c> wrapper that is read-only.
+ </returns>
+ </member>
+ <member name="F:log4net.Appender.AppenderCollection.EmptyCollection">
+ <summary>
+ An empty readonly static AppenderCollection
+ </summary>
+ </member>
+ <member name="M:log4net.Appender.AppenderCollection.#ctor">
+ <summary>
+ Initializes a new instance of the <c>AppenderCollection</c> class
+ that is empty and has the default initial capacity.
+ </summary>
+ </member>
+ <member name="M:log4net.Appender.AppenderCollection.#ctor(System.Int32)">
+ <summary>
+ Initializes a new instance of the <c>AppenderCollection</c> class
+ that has the specified initial capacity.
+ </summary>
+ <param name="capacity">
+ The number of elements that the new <c>AppenderCollection</c> is initially capable of storing.
+ </param>
+ </member>
+ <member name="M:log4net.Appender.AppenderCollection.#ctor(log4net.Appender.AppenderCollection)">
+ <summary>
+ Initializes a new instance of the <c>AppenderCollection</c> class
+ that contains elements copied from the specified <c>AppenderCollection</c>.
+ </summary>
+ <param name="c">The <c>AppenderCollection</c> whose elements are copied to the new collection.</param>
+ </member>
+ <member name="M:log4net.Appender.AppenderCollection.#ctor(log4net.Appender.IAppender[])">
+ <summary>
+ Initializes a new instance of the <c>AppenderCollection</c> class
+ that contains elements copied from the specified <see cref="T:log4net.Appender.IAppender"/> array.
+ </summary>
+ <param name="a">The <see cref="T:log4net.Appender.IAppender"/> array whose elements are copied to the new list.</param>
+ </member>
+ <member name="M:log4net.Appender.AppenderCollection.#ctor(System.Collections.ICollection)">
+ <summary>
+ Initializes a new instance of the <c>AppenderCollection</c> class
+ that contains elements copied from the specified <see cref="T:log4net.Appender.IAppender"/> collection.
+ </summary>
+ <param name="col">The <see cref="T:log4net.Appender.IAppender"/> collection whose elements are copied to the new list.</param>
+ </member>
+ <member name="M:log4net.Appender.AppenderCollection.#ctor(log4net.Appender.AppenderCollection.Tag)">
+ <summary>
+ Allow subclasses to avoid our default constructors
+ </summary>
+ <param name="tag"></param>
+ <exclude/>
+ </member>
+ <member name="M:log4net.Appender.AppenderCollection.CopyTo(log4net.Appender.IAppender[])">
+ <summary>
+ Copies the entire <c>AppenderCollection</c> to a one-dimensional
+ <see cref="T:log4net.Appender.IAppender"/> array.
+ </summary>
+ <param name="array">The one-dimensional <see cref="T:log4net.Appender.IAppender"/> array to copy to.</param>
+ </member>
+ <member name="M:log4net.Appender.AppenderCollection.CopyTo(log4net.Appender.IAppender[],System.Int32)">
+ <summary>
+ Copies the entire <c>AppenderCollection</c> to a one-dimensional
+ <see cref="T:log4net.Appender.IAppender"/> array, starting at the specified index of the target array.
+ </summary>
+ <param name="array">The one-dimensional <see cref="T:log4net.Appender.IAppender"/> array to copy to.</param>
+ <param name="start">The zero-based index in <paramref name="array"/> at which copying begins.</param>
+ </member>
+ <member name="M:log4net.Appender.AppenderCollection.Add(log4net.Appender.IAppender)">
+ <summary>
+ Adds a <see cref="T:log4net.Appender.IAppender"/> to the end of the <c>AppenderCollection</c>.
+ </summary>
+ <param name="item">The <see cref="T:log4net.Appender.IAppender"/> to be added to the end of the <c>AppenderCollection</c>.</param>
+ <returns>The index at which the value has been added.</returns>
+ </member>
+ <member name="M:log4net.Appender.AppenderCollection.Clear">
+ <summary>
+ Removes all elements from the <c>AppenderCollection</c>.
+ </summary>
+ </member>
+ <member name="M:log4net.Appender.AppenderCollection.Clone">
+ <summary>
+ Creates a shallow copy of the <see cref="T:log4net.Appender.AppenderCollection"/>.
+ </summary>
+ <returns>A new <see cref="T:log4net.Appender.AppenderCollection"/> with a shallow copy of the collection data.</returns>
+ </member>
+ <member name="M:log4net.Appender.AppenderCollection.Contains(log4net.Appender.IAppender)">
+ <summary>
+ Determines whether a given <see cref="T:log4net.Appender.IAppender"/> is in the <c>AppenderCollection</c>.
+ </summary>
+ <param name="item">The <see cref="T:log4net.Appender.IAppender"/> to check for.</param>
+ <returns><c>true</c> if <paramref name="item"/> is found in the <c>AppenderCollection</c>; otherwise, <c>false</c>.</returns>
+ </member>
+ <member name="M:log4net.Appender.AppenderCollection.IndexOf(log4net.Appender.IAppender)">
+ <summary>
+ Returns the zero-based index of the first occurrence of a <see cref="T:log4net.Appender.IAppender"/>
+ in the <c>AppenderCollection</c>.
+ </summary>
+ <param name="item">The <see cref="T:log4net.Appender.IAppender"/> to locate in the <c>AppenderCollection</c>.</param>
+ <returns>
+ The zero-based index of the first occurrence of <paramref name="item"/>
+ in the entire <c>AppenderCollection</c>, if found; otherwise, -1.
+ </returns>
+ </member>
+ <member name="M:log4net.Appender.AppenderCollection.Insert(System.Int32,log4net.Appender.IAppender)">
+ <summary>
+ Inserts an element into the <c>AppenderCollection</c> at the specified index.
+ </summary>
+ <param name="index">The zero-based index at which <paramref name="item"/> should be inserted.</param>
+ <param name="item">The <see cref="T:log4net.Appender.IAppender"/> to insert.</param>
+ <exception cref="T:System.ArgumentOutOfRangeException">
+ <para><paramref name="index"/> is less than zero</para>
+ <para>-or-</para>
+ <para><paramref name="index"/> is equal to or greater than <see cref="P:log4net.Appender.AppenderCollection.Count"/>.</para>
+ </exception>
+ </member>
+ <member name="M:log4net.Appender.AppenderCollection.Remove(log4net.Appender.IAppender)">
+ <summary>
+ Removes the first occurrence of a specific <see cref="T:log4net.Appender.IAppender"/> from the <c>AppenderCollection</c>.
+ </summary>
+ <param name="item">The <see cref="T:log4net.Appender.IAppender"/> to remove from the <c>AppenderCollection</c>.</param>
+ <exception cref="T:System.ArgumentException">
+ The specified <see cref="T:log4net.Appender.IAppender"/> was not found in the <c>AppenderCollection</c>.
+ </exception>
+ </member>
+ <member name="M:log4net.Appender.AppenderCollection.RemoveAt(System.Int32)">
+ <summary>
+ Removes the element at the specified index of the <c>AppenderCollection</c>.
+ </summary>
+ <param name="index">The zero-based index of the element to remove.</param>
+ <exception cref="T:System.ArgumentOutOfRangeException">
+ <para><paramref name="index"/> is less than zero</para>
+ <para>-or-</para>
+ <para><paramref name="index"/> is equal to or greater than <see cref="P:log4net.Appender.AppenderCollection.Count"/>.</para>
+ </exception>
+ </member>
+ <member name="M:log4net.Appender.AppenderCollection.GetEnumerator">
+ <summary>
+ Returns an enumerator that can iterate through the <c>AppenderCollection</c>.
+ </summary>
+ <returns>An <see cref="T:log4net.Appender.AppenderCollection.Enumerator"/> for the entire <c>AppenderCollection</c>.</returns>
+ </member>
+ <member name="M:log4net.Appender.AppenderCollection.AddRange(log4net.Appender.AppenderCollection)">
+ <summary>
+ Adds the elements of another <c>AppenderCollection</c> to the current <c>AppenderCollection</c>.
+ </summary>
+ <param name="x">The <c>AppenderCollection</c> whose elements should be added to the end of the current <c>AppenderCollection</c>.</param>
+ <returns>The new <see cref="P:log4net.Appender.AppenderCollection.Count"/> of the <c>AppenderCollection</c>.</returns>
+ </member>
+ <member name="M:log4net.Appender.AppenderCollection.AddRange(log4net.Appender.IAppender[])">
+ <summary>
+ Adds the elements of a <see cref="T:log4net.Appender.IAppender"/> array to the current <c>AppenderCollection</c>.
+ </summary>
+ <param name="x">The <see cref="T:log4net.Appender.IAppender"/> array whose elements should be added to the end of the <c>AppenderCollection</c>.</param>
+ <returns>The new <see cref="P:log4net.Appender.AppenderCollection.Count"/> of the <c>AppenderCollection</c>.</returns>
+ </member>
+ <member name="M:log4net.Appender.AppenderCollection.AddRange(System.Collections.ICollection)">
+ <summary>
+ Adds the elements of a <see cref="T:log4net.Appender.IAppender"/> collection to the current <c>AppenderCollection</c>.
+ </summary>
+ <param name="col">The <see cref="T:log4net.Appender.IAppender"/> collection whose elements should be added to the end of the <c>AppenderCollection</c>.</param>
+ <returns>The new <see cref="P:log4net.Appender.AppenderCollection.Count"/> of the <c>AppenderCollection</c>.</returns>
+ </member>
+ <member name="M:log4net.Appender.AppenderCollection.TrimToSize">
+ <summary>
+ Sets the capacity to the actual number of elements.
+ </summary>
+ </member>
+ <member name="M:log4net.Appender.AppenderCollection.ToArray">
+ <summary>
+ Return the collection elements as an array
+ </summary>
+ <returns>the array</returns>
+ </member>
+ <member name="M:log4net.Appender.AppenderCollection.ValidateIndex(System.Int32)">
+ <exception cref="T:System.ArgumentOutOfRangeException">
+ <para><paramref name="index"/> is less than zero</para>
+ <para>-or-</para>
+ <para><paramref name="index"/> is equal to or greater than <see cref="P:log4net.Appender.AppenderCollection.Count"/>.</para>
+ </exception>
+ </member>
+ <member name="M:log4net.Appender.AppenderCollection.ValidateIndex(System.Int32,System.Boolean)">
+ <exception cref="T:System.ArgumentOutOfRangeException">
+ <para><paramref name="index"/> is less than zero</para>
+ <para>-or-</para>
+ <para><paramref name="index"/> is equal to or greater than <see cref="P:log4net.Appender.AppenderCollection.Count"/>.</para>
+ </exception>
+ </member>
+ <member name="P:log4net.Appender.AppenderCollection.Count">
+ <summary>
+ Gets the number of elements actually contained in the <c>AppenderCollection</c>.
+ </summary>
+ </member>
+ <member name="P:log4net.Appender.AppenderCollection.IsSynchronized">
+ <summary>
+ Gets a value indicating whether access to the collection is synchronized (thread-safe).
+ </summary>
+ <returns>true if access to the ICollection is synchronized (thread-safe); otherwise, false.</returns>
+ </member>
+ <member name="P:log4net.Appender.AppenderCollection.SyncRoot">
+ <summary>
+ Gets an object that can be used to synchronize access to the collection.
+ </summary>
+ </member>
+ <member name="P:log4net.Appender.AppenderCollection.Item(System.Int32)">
+ <summary>
+ Gets or sets the <see cref="T:log4net.Appender.IAppender"/> at the specified index.
+ </summary>
+ <param name="index">The zero-based index of the element to get or set.</param>
+ <exception cref="T:System.ArgumentOutOfRangeException">
+ <para><paramref name="index"/> is less than zero</para>
+ <para>-or-</para>
+ <para><paramref name="index"/> is equal to or greater than <see cref="P:log4net.Appender.AppenderCollection.Count"/>.</para>
+ </exception>
+ </member>
+ <member name="P:log4net.Appender.AppenderCollection.IsFixedSize">
+ <summary>
+ Gets a value indicating whether the collection has a fixed size.
+ </summary>
+ <value>true if the collection has a fixed size; otherwise, false. The default is false</value>
+ </member>
+ <member name="P:log4net.Appender.AppenderCollection.IsReadOnly">
+ <summary>
+ Gets a value indicating whether the IList is read-only.
+ </summary>
+ <value>true if the collection is read-only; otherwise, false. The default is false</value>
+ </member>
+ <member name="P:log4net.Appender.AppenderCollection.Capacity">
+ <summary>
+ Gets or sets the number of elements the <c>AppenderCollection</c> can contain.
+ </summary>
+ </member>
+ <member name="T:log4net.Appender.AppenderCollection.IAppenderCollectionEnumerator">
+ <summary>
+ Supports type-safe iteration over a <see cref="T:log4net.Appender.AppenderCollection"/>.
+ </summary>
+ <exclude/>
+ </member>
+ <member name="M:log4net.Appender.AppenderCollection.IAppenderCollectionEnumerator.MoveNext">
+ <summary>
+ Advances the enumerator to the next element in the collection.
+ </summary>
+ <returns>
+ <c>true</c> if the enumerator was successfully advanced to the next element;
+ <c>false</c> if the enumerator has passed the end of the collection.
+ </returns>
+ <exception cref="T:System.InvalidOperationException">
+ The collection was modified after the enumerator was created.
+ </exception>
+ </member>
+ <member name="M:log4net.Appender.AppenderCollection.IAppenderCollectionEnumerator.Reset">
+ <summary>
+ Sets the enumerator to its initial position, before the first element in the collection.
+ </summary>
+ </member>
+ <member name="P:log4net.Appender.AppenderCollection.IAppenderCollectionEnumerator.Current">
+ <summary>
+ Gets the current element in the collection.
+ </summary>
+ </member>
+ <member name="T:log4net.Appender.AppenderCollection.Tag">
+ <summary>
+ Type visible only to our subclasses
+ Used to access protected constructor
+ </summary>
+ <exclude/>
+ </member>
+ <member name="F:log4net.Appender.AppenderCollection.Tag.Default">
+ <summary>
+ A value
+ </summary>
+ </member>
+ <member name="T:log4net.Appender.AppenderCollection.Enumerator">
+ <summary>
+ Supports simple iteration over a <see cref="T:log4net.Appender.AppenderCollection"/>.
+ </summary>
+ <exclude/>
+ </member>
+ <member name="M:log4net.Appender.AppenderCollection.Enumerator.#ctor(log4net.Appender.AppenderCollection)">
+ <summary>
+ Initializes a new instance of the <c>Enumerator</c> class.
+ </summary>
+ <param name="tc"></param>
+ </member>
+ <member name="M:log4net.Appender.AppenderCollection.Enumerator.MoveNext">
+ <summary>
+ Advances the enumerator to the next element in the collection.
+ </summary>
+ <returns>
+ <c>true</c> if the enumerator was successfully advanced to the next element;
+ <c>false</c> if the enumerator has passed the end of the collection.
+ </returns>
+ <exception cref="T:System.InvalidOperationException">
+ The collection was modified after the enumerator was created.
+ </exception>
+ </member>
+ <member name="M:log4net.Appender.AppenderCollection.Enumerator.Reset">
+ <summary>
+ Sets the enumerator to its initial position, before the first element in the collection.
+ </summary>
+ </member>
+ <member name="P:log4net.Appender.AppenderCollection.Enumerator.Current">
+ <summary>
+ Gets the current element in the collection.
+ </summary>
+ </member>
+ <member name="T:log4net.Appender.AppenderCollection.ReadOnlyAppenderCollection">
+ <exclude/>
+ </member>
+ <member name="T:log4net.Appender.AspNetTraceAppender">
+ <summary>
+ <para>
+ Appends log events to the ASP.NET <see cref="T:System.Web.TraceContext"/> system.
+ </para>
+ </summary>
+ <remarks>
+ <para>
+ Diagnostic information and tracing messages that you specify are appended to the output
+ of the page that is sent to the requesting browser. Optionally, you can view this information
+ from a separate trace viewer (Trace.axd) that displays trace information for every page in a
+ given application.
+ </para>
+ <para>
+ Trace statements are processed and displayed only when tracing is enabled. You can control
+ whether tracing is displayed to a page, to the trace viewer, or both.
+ </para>
+ <para>
+ The logging event is passed to the <see cref="M:System.Web.TraceContext.Write(System.String)"/> or
+ <see cref="M:System.Web.TraceContext.Warn(System.String)"/> method depending on the level of the logging event.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="M:log4net.Appender.AspNetTraceAppender.#ctor">
+ <summary>
+ Initializes a new instance of the <see cref="T:log4net.Appender.AspNetTraceAppender"/> class.
+ </summary>
+ <remarks>
+ <para>
+ Default constructor.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.AspNetTraceAppender.Append(log4net.Core.LoggingEvent)">
+ <summary>
+ Write the logging event to the ASP.NET trace
+ </summary>
+ <param name="loggingEvent">the event to log</param>
+ <remarks>
+ <para>
+ Write the logging event to the ASP.NET trace
+ <c>HttpContext.Current.Trace</c>
+ (<see cref="T:System.Web.TraceContext"/>).
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.AspNetTraceAppender.RequiresLayout">
+ <summary>
+ This appender requires a <see cref="N:log4net.Layout"/> to be set.
+ </summary>
+ <value><c>true</c></value>
+ <remarks>
+ <para>
+ This appender requires a <see cref="N:log4net.Layout"/> to be set.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Appender.BufferingForwardingAppender">
+ <summary>
+ Buffers events and then forwards them to attached appenders.
+ </summary>
+ <remarks>
+ <para>
+ The events are buffered in this appender until conditions are
+ met to allow the appender to deliver the events to the attached
+ appenders. See <see cref="T:log4net.Appender.BufferingAppenderSkeleton"/> for the
+ conditions that cause the buffer to be sent.
+ </para>
+ <para>The forwarding appender can be used to specify different
+ thresholds and filters for the same appender at different locations
+ within the hierarchy.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="T:log4net.Core.IAppenderAttachable">
+ <summary>
+ Interface for attaching appenders to objects.
+ </summary>
+ <remarks>
+ <para>
+ Interface for attaching, removing and retrieving appenders.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="M:log4net.Core.IAppenderAttachable.AddAppender(log4net.Appender.IAppender)">
+ <summary>
+ Attaches an appender.
+ </summary>
+ <param name="appender">The appender to add.</param>
+ <remarks>
+ <para>
+ Add the specified appender. The implementation may
+ choose to allow or deny duplicate appenders.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.IAppenderAttachable.GetAppender(System.String)">
+ <summary>
+ Gets an attached appender with the specified name.
+ </summary>
+ <param name="name">The name of the appender to get.</param>
+ <returns>
+ The appender with the name specified, or <c>null</c> if no appender with the
+ specified name is found.
+ </returns>
+ <remarks>
+ <para>
+ Returns an attached appender with the <paramref name="name"/> specified.
+ If no appender with the specified name is found <c>null</c> will be
+ returned.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.IAppenderAttachable.RemoveAllAppenders">
+ <summary>
+ Removes all attached appenders.
+ </summary>
+ <remarks>
+ <para>
+ Removes and closes all attached appenders
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.IAppenderAttachable.RemoveAppender(log4net.Appender.IAppender)">
+ <summary>
+ Removes the specified appender from the list of attached appenders.
+ </summary>
+ <param name="appender">The appender to remove.</param>
+ <returns>The appender removed from the list</returns>
+ <remarks>
+ <para>
+ The appender removed is not closed.
+ If you are discarding the appender you must call
+ <see cref="M:log4net.Appender.IAppender.Close"/> on the appender removed.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.IAppenderAttachable.RemoveAppender(System.String)">
+ <summary>
+ Removes the appender with the specified name from the list of appenders.
+ </summary>
+ <param name="name">The name of the appender to remove.</param>
+ <returns>The appender removed from the list</returns>
+ <remarks>
+ <para>
+ The appender removed is not closed.
+ If you are discarding the appender you must call
+ <see cref="M:log4net.Appender.IAppender.Close"/> on the appender removed.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Core.IAppenderAttachable.Appenders">
+ <summary>
+ Gets all attached appenders.
+ </summary>
+ <value>
+ A collection of attached appenders.
+ </value>
+ <remarks>
+ <para>
+ Gets a collection of attached appenders.
+ If there are no attached appenders the
+ implementation should return an empty
+ collection rather than <c>null</c>.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.BufferingForwardingAppender.#ctor">
+ <summary>
+ Initializes a new instance of the <see cref="T:log4net.Appender.BufferingForwardingAppender"/> class.
+ </summary>
+ <remarks>
+ <para>
+ Default constructor.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.BufferingForwardingAppender.OnClose">
+ <summary>
+ Closes the appender and releases resources.
+ </summary>
+ <remarks>
+ <para>
+ Releases any resources allocated within the appender such as file handles,
+ network connections, etc.
+ </para>
+ <para>
+ It is a programming error to append to a closed appender.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.BufferingForwardingAppender.SendBuffer(log4net.Core.LoggingEvent[])">
+ <summary>
+ Send the events.
+ </summary>
+ <param name="events">The events that need to be send.</param>
+ <remarks>
+ <para>
+ Forwards the events to the attached appenders.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.BufferingForwardingAppender.AddAppender(log4net.Appender.IAppender)">
+ <summary>
+ Adds an <see cref="T:log4net.Appender.IAppender"/> to the list of appenders of this
+ instance.
+ </summary>
+ <param name="newAppender">The <see cref="T:log4net.Appender.IAppender"/> to add to this appender.</param>
+ <remarks>
+ <para>
+ If the specified <see cref="T:log4net.Appender.IAppender"/> is already in the list of
+ appenders, then it won't be added again.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.BufferingForwardingAppender.GetAppender(System.String)">
+ <summary>
+ Looks for the appender with the specified name.
+ </summary>
+ <param name="name">The name of the appender to lookup.</param>
+ <returns>
+ The appender with the specified name, or <c>null</c>.
+ </returns>
+ <remarks>
+ <para>
+ Get the named appender attached to this buffering appender.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.BufferingForwardingAppender.RemoveAllAppenders">
+ <summary>
+ Removes all previously added appenders from this appender.
+ </summary>
+ <remarks>
+ <para>
+ This is useful when re-reading configuration information.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.BufferingForwardingAppender.RemoveAppender(log4net.Appender.IAppender)">
+ <summary>
+ Removes the specified appender from the list of appenders.
+ </summary>
+ <param name="appender">The appender to remove.</param>
+ <returns>The appender removed from the list</returns>
+ <remarks>
+ The appender removed is not closed.
+ If you are discarding the appender you must call
+ <see cref="M:log4net.Appender.IAppender.Close"/> on the appender removed.
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.BufferingForwardingAppender.RemoveAppender(System.String)">
+ <summary>
+ Removes the appender with the specified name from the list of appenders.
+ </summary>
+ <param name="name">The name of the appender to remove.</param>
+ <returns>The appender removed from the list</returns>
+ <remarks>
+ The appender removed is not closed.
+ If you are discarding the appender you must call
+ <see cref="M:log4net.Appender.IAppender.Close"/> on the appender removed.
+ </remarks>
+ </member>
+ <member name="F:log4net.Appender.BufferingForwardingAppender.m_appenderAttachedImpl">
+ <summary>
+ Implementation of the <see cref="T:log4net.Core.IAppenderAttachable"/> interface
+ </summary>
+ </member>
+ <member name="P:log4net.Appender.BufferingForwardingAppender.Appenders">
+ <summary>
+ Gets the appenders contained in this appender as an
+ <see cref="T:System.Collections.ICollection"/>.
+ </summary>
+ <remarks>
+ If no appenders can be found, then an <see cref="T:log4net.Util.EmptyCollection"/>
+ is returned.
+ </remarks>
+ <returns>
+ A collection of the appenders in this appender.
+ </returns>
+ </member>
+ <member name="T:log4net.Appender.ColoredConsoleAppender">
+ <summary>
+ Appends logging events to the console.
+ </summary>
+ <remarks>
+ <para>
+ ColoredConsoleAppender appends log events to the standard output stream
+ or the error output stream using a layout specified by the
+ user. It also allows the color of a specific type of message to be set.
+ </para>
+ <para>
+ By default, all output is written to the console's standard output stream.
+ The <see cref="P:log4net.Appender.ColoredConsoleAppender.Target"/> property can be set to direct the output to the
+ error stream.
+ </para>
+ <para>
+ NOTE: This appender writes directly to the application's attached console
+ not to the <c>System.Console.Out</c> or <c>System.Console.Error</c> <c>TextWriter</c>.
+ The <c>System.Console.Out</c> and <c>System.Console.Error</c> streams can be
+ programmatically redirected (for example NUnit does this to capture program output).
+ This appender will ignore these redirections because it needs to use Win32
+ API calls to colorize the output. To respect these redirections the <see cref="T:log4net.Appender.ConsoleAppender"/>
+ must be used.
+ </para>
+ <para>
+ When configuring the colored console appender, mapping should be
+ specified to map a logging level to a color. For example:
+ </para>
+ <code lang="XML" escaped="true">
+ <mapping>
+ <level value="ERROR"/>
+ <foreColor value="White"/>
+ <backColor value="Red, HighIntensity"/>
+ </mapping>
+ <mapping>
+ <level value="DEBUG"/>
+ <backColor value="Green"/>
+ </mapping>
+ </code>
+ <para>
+ The Level is the standard log4net logging level and ForeColor and BackColor can be any
+ combination of the following values:
+ <list type="bullet">
+ <item><term>Blue</term><description></description></item>
+ <item><term>Green</term><description></description></item>
+ <item><term>Red</term><description></description></item>
+ <item><term>White</term><description></description></item>
+ <item><term>Yellow</term><description></description></item>
+ <item><term>Purple</term><description></description></item>
+ <item><term>Cyan</term><description></description></item>
+ <item><term>HighIntensity</term><description></description></item>
+ </list>
+ </para>
+ </remarks>
+ <author>Rick Hobbs</author>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="F:log4net.Appender.ColoredConsoleAppender.ConsoleOut">
+ <summary>
+ The <see cref="P:log4net.Appender.ColoredConsoleAppender.Target"/> to use when writing to the Console
+ standard output stream.
+ </summary>
+ <remarks>
+ <para>
+ The <see cref="P:log4net.Appender.ColoredConsoleAppender.Target"/> to use when writing to the Console
+ standard output stream.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Appender.ColoredConsoleAppender.ConsoleError">
+ <summary>
+ The <see cref="P:log4net.Appender.ColoredConsoleAppender.Target"/> to use when writing to the Console
+ standard error output stream.
+ </summary>
+ <remarks>
+ <para>
+ The <see cref="P:log4net.Appender.ColoredConsoleAppender.Target"/> to use when writing to the Console
+ standard error output stream.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.ColoredConsoleAppender.#ctor">
+ <summary>
+ Initializes a new instance of the <see cref="T:log4net.Appender.ColoredConsoleAppender"/> class.
+ </summary>
+ <remarks>
+ The instance of the <see cref="T:log4net.Appender.ColoredConsoleAppender"/> class is set up to write
+ to the standard output stream.
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.ColoredConsoleAppender.#ctor(log4net.Layout.ILayout)">
+ <summary>
+ Initializes a new instance of the <see cref="T:log4net.Appender.ColoredConsoleAppender"/> class
+ with the specified layout.
+ </summary>
+ <param name="layout">the layout to use for this appender</param>
+ <remarks>
+ The instance of the <see cref="T:log4net.Appender.ColoredConsoleAppender"/> class is set up to write
+ to the standard output stream.
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.ColoredConsoleAppender.#ctor(log4net.Layout.ILayout,System.Boolean)">
+ <summary>
+ Initializes a new instance of the <see cref="T:log4net.Appender.ColoredConsoleAppender"/> class
+ with the specified layout.
+ </summary>
+ <param name="layout">the layout to use for this appender</param>
+ <param name="writeToErrorStream">flag set to <c>true</c> to write to the console error stream</param>
+ <remarks>
+ When <paramref name="writeToErrorStream"/> is set to <c>true</c>, output is written to
+ the standard error output stream. Otherwise, output is written to the standard
+ output stream.
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.ColoredConsoleAppender.AddMapping(log4net.Appender.ColoredConsoleAppender.LevelColors)">
+ <summary>
+ Add a mapping of level to color - done by the config file
+ </summary>
+ <param name="mapping">The mapping to add</param>
+ <remarks>
+ <para>
+ Add a <see cref="T:log4net.Appender.ColoredConsoleAppender.LevelColors"/> mapping to this appender.
+ Each mapping defines the foreground and background colors
+ for a level.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.ColoredConsoleAppender.Append(log4net.Core.LoggingEvent)">
+ <summary>
+ This method is called by the <see cref="M:log4net.Appender.AppenderSkeleton.DoAppend(log4net.Core.LoggingEvent)"/> method.
+ </summary>
+ <param name="loggingEvent">The event to log.</param>
+ <remarks>
+ <para>
+ Writes the event to the console.
+ </para>
+ <para>
+ The format of the output will depend on the appender's layout.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.ColoredConsoleAppender.ActivateOptions">
+ <summary>
+ Initialize the options for this appender
+ </summary>
+ <remarks>
+ <para>
+ Initialize the level to color mappings set on this appender.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Appender.ColoredConsoleAppender.m_writeToErrorStream">
+ <summary>
+ Flag to write output to the error stream rather than the standard output stream
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.ColoredConsoleAppender.m_levelMapping">
+ <summary>
+ Mapping from level object to color value
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.ColoredConsoleAppender.m_consoleOutputWriter">
+ <summary>
+ The console output stream writer to write to
+ </summary>
+ <remarks>
+ <para>
+ This writer is not thread safe.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.ColoredConsoleAppender.Target">
+ <summary>
+ Target is the value of the console output stream.
+ This is either <c>"Console.Out"</c> or <c>"Console.Error"</c>.
+ </summary>
+ <value>
+ Target is the value of the console output stream.
+ This is either <c>"Console.Out"</c> or <c>"Console.Error"</c>.
+ </value>
+ <remarks>
+ <para>
+ Target is the value of the console output stream.
+ This is either <c>"Console.Out"</c> or <c>"Console.Error"</c>.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.ColoredConsoleAppender.RequiresLayout">
+ <summary>
+ This appender requires a <see cref="N:log4net.Layout"/> to be set.
+ </summary>
+ <value><c>true</c></value>
+ <remarks>
+ <para>
+ This appender requires a <see cref="N:log4net.Layout"/> to be set.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Appender.ColoredConsoleAppender.Colors">
+ <summary>
+ The enum of possible color values for use with the color mapping method
+ </summary>
+ <remarks>
+ <para>
+ The following flags can be combined together to
+ form the colors.
+ </para>
+ </remarks>
+ <seealso cref="T:log4net.Appender.ColoredConsoleAppender"/>
+ </member>
+ <member name="F:log4net.Appender.ColoredConsoleAppender.Colors.Blue">
+ <summary>
+ color is blue
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.ColoredConsoleAppender.Colors.Green">
+ <summary>
+ color is green
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.ColoredConsoleAppender.Colors.Red">
+ <summary>
+ color is red
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.ColoredConsoleAppender.Colors.White">
+ <summary>
+ color is white
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.ColoredConsoleAppender.Colors.Yellow">
+ <summary>
+ color is yellow
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.ColoredConsoleAppender.Colors.Purple">
+ <summary>
+ color is purple
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.ColoredConsoleAppender.Colors.Cyan">
+ <summary>
+ color is cyan
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.ColoredConsoleAppender.Colors.HighIntensity">
+ <summary>
+ color is intensified
+ </summary>
+ </member>
+ <member name="T:log4net.Appender.ColoredConsoleAppender.LevelColors">
+ <summary>
+ A class to act as a mapping between the level that a logging call is made at and
+ the color it should be displayed as.
+ </summary>
+ <remarks>
+ <para>
+ Defines the mapping between a level and the color it should be displayed in.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.ColoredConsoleAppender.LevelColors.ActivateOptions">
+ <summary>
+ Initialize the options for the object
+ </summary>
+ <remarks>
+ <para>
+ Combine the <see cref="P:log4net.Appender.ColoredConsoleAppender.LevelColors.ForeColor"/> and <see cref="P:log4net.Appender.ColoredConsoleAppender.LevelColors.BackColor"/> together.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.ColoredConsoleAppender.LevelColors.ForeColor">
+ <summary>
+ The mapped foreground color for the specified level
+ </summary>
+ <remarks>
+ <para>
+ Required property.
+ The mapped foreground color for the specified level.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.ColoredConsoleAppender.LevelColors.BackColor">
+ <summary>
+ The mapped background color for the specified level
+ </summary>
+ <remarks>
+ <para>
+ Required property.
+ The mapped background color for the specified level.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.ColoredConsoleAppender.LevelColors.CombinedColor">
+ <summary>
+ The combined <see cref="P:log4net.Appender.ColoredConsoleAppender.LevelColors.ForeColor"/> and <see cref="P:log4net.Appender.ColoredConsoleAppender.LevelColors.BackColor"/> suitable for
+ setting the console color.
+ </summary>
+ </member>
+ <member name="T:log4net.Appender.ConsoleAppender">
+ <summary>
+ Appends logging events to the console.
+ </summary>
+ <remarks>
+ <para>
+ ConsoleAppender appends log events to the standard output stream
+ or the error output stream using a layout specified by the
+ user.
+ </para>
+ <para>
+ By default, all output is written to the console's standard output stream.
+ The <see cref="P:log4net.Appender.ConsoleAppender.Target"/> property can be set to direct the output to the
+ error stream.
+ </para>
+ <para>
+ NOTE: This appender writes each message to the <c>System.Console.Out</c> or
+ <c>System.Console.Error</c> that is set at the time the event is appended.
+ Therefore it is possible to programmatically redirect the output of this appender
+ (for example NUnit does this to capture program output). While this is the desired
+ behavior of this appender it may have security implications in your application.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="F:log4net.Appender.ConsoleAppender.ConsoleOut">
+ <summary>
+ The <see cref="P:log4net.Appender.ConsoleAppender.Target"/> to use when writing to the Console
+ standard output stream.
+ </summary>
+ <remarks>
+ <para>
+ The <see cref="P:log4net.Appender.ConsoleAppender.Target"/> to use when writing to the Console
+ standard output stream.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Appender.ConsoleAppender.ConsoleError">
+ <summary>
+ The <see cref="P:log4net.Appender.ConsoleAppender.Target"/> to use when writing to the Console
+ standard error output stream.
+ </summary>
+ <remarks>
+ <para>
+ The <see cref="P:log4net.Appender.ConsoleAppender.Target"/> to use when writing to the Console
+ standard error output stream.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.ConsoleAppender.#ctor">
+ <summary>
+ Initializes a new instance of the <see cref="T:log4net.Appender.ConsoleAppender"/> class.
+ </summary>
+ <remarks>
+ The instance of the <see cref="T:log4net.Appender.ConsoleAppender"/> class is set up to write
+ to the standard output stream.
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.ConsoleAppender.#ctor(log4net.Layout.ILayout)">
+ <summary>
+ Initializes a new instance of the <see cref="T:log4net.Appender.ConsoleAppender"/> class
+ with the specified layout.
+ </summary>
+ <param name="layout">the layout to use for this appender</param>
+ <remarks>
+ The instance of the <see cref="T:log4net.Appender.ConsoleAppender"/> class is set up to write
+ to the standard output stream.
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.ConsoleAppender.#ctor(log4net.Layout.ILayout,System.Boolean)">
+ <summary>
+ Initializes a new instance of the <see cref="T:log4net.Appender.ConsoleAppender"/> class
+ with the specified layout.
+ </summary>
+ <param name="layout">the layout to use for this appender</param>
+ <param name="writeToErrorStream">flag set to <c>true</c> to write to the console error stream</param>
+ <remarks>
+ When <paramref name="writeToErrorStream"/> is set to <c>true</c>, output is written to
+ the standard error output stream. Otherwise, output is written to the standard
+ output stream.
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.ConsoleAppender.Append(log4net.Core.LoggingEvent)">
+ <summary>
+ This method is called by the <see cref="M:log4net.Appender.AppenderSkeleton.DoAppend(log4net.Core.LoggingEvent)"/> method.
+ </summary>
+ <param name="loggingEvent">The event to log.</param>
+ <remarks>
+ <para>
+ Writes the event to the console.
+ </para>
+ <para>
+ The format of the output will depend on the appender's layout.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.ConsoleAppender.Target">
+ <summary>
+ Target is the value of the console output stream.
+ This is either <c>"Console.Out"</c> or <c>"Console.Error"</c>.
+ </summary>
+ <value>
+ Target is the value of the console output stream.
+ This is either <c>"Console.Out"</c> or <c>"Console.Error"</c>.
+ </value>
+ <remarks>
+ <para>
+ Target is the value of the console output stream.
+ This is either <c>"Console.Out"</c> or <c>"Console.Error"</c>.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.ConsoleAppender.RequiresLayout">
+ <summary>
+ This appender requires a <see cref="N:log4net.Layout"/> to be set.
+ </summary>
+ <value><c>true</c></value>
+ <remarks>
+ <para>
+ This appender requires a <see cref="N:log4net.Layout"/> to be set.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Appender.DebugAppender">
+ <summary>
+ Appends log events to the <see cref="T:System.Diagnostics.Debug"/> system.
+ </summary>
+ <remarks>
+ <para>
+ The application configuration file can be used to control what listeners
+ are actually used. See the MSDN documentation for the
+ <see cref="T:System.Diagnostics.Debug"/> class for details on configuring the
+ debug system.
+ </para>
+ <para>
+ Events are written using the <see cref="M:System.Diagnostics.Debug.Write(System.String,System.String)"/>
+ method. The event's logger name is passed as the value for the category name to the Write method.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="M:log4net.Appender.DebugAppender.#ctor">
+ <summary>
+ Initializes a new instance of the <see cref="T:log4net.Appender.DebugAppender"/>.
+ </summary>
+ <remarks>
+ <para>
+ Default constructor.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.DebugAppender.#ctor(log4net.Layout.ILayout)">
+ <summary>
+ Initializes a new instance of the <see cref="T:log4net.Appender.DebugAppender"/>
+ with a specified layout.
+ </summary>
+ <param name="layout">The layout to use with this appender.</param>
+ <remarks>
+ <para>
+ Obsolete constructor.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.DebugAppender.Append(log4net.Core.LoggingEvent)">
+ <summary>
+ Writes the logging event to the <see cref="T:System.Diagnostics.Debug"/> system.
+ </summary>
+ <param name="loggingEvent">The event to log.</param>
+ <remarks>
+ <para>
+ Writes the logging event to the <see cref="T:System.Diagnostics.Debug"/> system.
+ If <see cref="P:log4net.Appender.DebugAppender.ImmediateFlush"/> is <c>true</c> then the <see cref="M:System.Diagnostics.Debug.Flush"/>
+ is called.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Appender.DebugAppender.m_immediateFlush">
+ <summary>
+ Immediate flush means that the underlying writer or output stream
+ will be flushed at the end of each append operation.
+ </summary>
+ <remarks>
+ <para>
+ Immediate flush is slower but ensures that each append request is
+ actually written. If <see cref="P:log4net.Appender.DebugAppender.ImmediateFlush"/> is set to
+ <c>false</c>, then there is a good chance that the last few
+ logs events are not actually written to persistent media if and
+ when the application crashes.
+ </para>
+ <para>
+ The default value is <c>true</c>.</para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.DebugAppender.ImmediateFlush">
+ <summary>
+ Gets or sets a value that indicates whether the appender will
+ flush at the end of each write.
+ </summary>
+ <remarks>
+ <para>The default behavior is to flush at the end of each
+ write. If the option is set to<c>false</c>, then the underlying
+ stream can defer writing to physical medium to a later time.
+ </para>
+ <para>
+ Avoiding the flush operation at the end of each append results
+ in a performance gain of 10 to 20 percent. However, there is safety
+ trade-off involved in skipping flushing. Indeed, when flushing is
+ skipped, then it is likely that the last few log events will not
+ be recorded on disk when the application exits. This is a high
+ price to pay even for a 20% performance gain.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.DebugAppender.RequiresLayout">
+ <summary>
+ This appender requires a <see cref="N:log4net.Layout"/> to be set.
+ </summary>
+ <value><c>true</c></value>
+ <remarks>
+ <para>
+ This appender requires a <see cref="N:log4net.Layout"/> to be set.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Appender.EventLogAppender">
+ <summary>
+ Writes events to the system event log.
+ </summary>
+ <remarks>
+ <para>
+ The <c>EventID</c> of the event log entry can be
+ set using the <c>EventLogEventID</c> property (<see cref="P:log4net.Core.LoggingEvent.Properties"/>)
+ on the <see cref="T:log4net.Core.LoggingEvent"/>.
+ </para>
+ <para>
+ There is a limit of 32K characters for an event log message
+ </para>
+ <para>
+ When configuring the EventLogAppender a mapping can be
+ specified to map a logging level to an event log entry type. For example:
+ </para>
+ <code lang="XML">
+ &lt;mapping&gt;
+ &lt;level value="ERROR" /&gt;
+ &lt;eventLogEntryType value="Error" /&gt;
+ &lt;/mapping&gt;
+ &lt;mapping&gt;
+ &lt;level value="DEBUG" /&gt;
+ &lt;eventLogEntryType value="Information" /&gt;
+ &lt;/mapping&gt;
+ </code>
+ <para>
+ The Level is the standard log4net logging level and eventLogEntryType can be any value
+ from the <see cref="T:System.Diagnostics.EventLogEntryType"/> enum, i.e.:
+ <list type="bullet">
+ <item><term>Error</term><description>an error event</description></item>
+ <item><term>Warning</term><description>a warning event</description></item>
+ <item><term>Information</term><description>an informational event</description></item>
+ </list>
+ </para>
+ </remarks>
+ <author>Aspi Havewala</author>
+ <author>Douglas de la Torre</author>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ <author>Thomas Voss</author>
+ </member>
+ <member name="M:log4net.Appender.EventLogAppender.#ctor">
+ <summary>
+ Initializes a new instance of the <see cref="T:log4net.Appender.EventLogAppender"/> class.
+ </summary>
+ <remarks>
+ <para>
+ Default constructor.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.EventLogAppender.#ctor(log4net.Layout.ILayout)">
+ <summary>
+ Initializes a new instance of the <see cref="T:log4net.Appender.EventLogAppender"/> class
+ with the specified <see cref="T:log4net.Layout.ILayout"/>.
+ </summary>
+ <param name="layout">The <see cref="T:log4net.Layout.ILayout"/> to use with this appender.</param>
+ <remarks>
+ <para>
+ Obsolete constructor.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.EventLogAppender.AddMapping(log4net.Appender.EventLogAppender.Level2EventLogEntryType)">
+ <summary>
+ Add a mapping of level to <see cref="T:System.Diagnostics.EventLogEntryType"/> - done by the config file
+ </summary>
+ <param name="mapping">The mapping to add</param>
+ <remarks>
+ <para>
+ Add a <see cref="T:log4net.Appender.EventLogAppender.Level2EventLogEntryType"/> mapping to this appender.
+ Each mapping defines the event log entry type for a level.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.EventLogAppender.ActivateOptions">
+ <summary>
+ Initialize the appender based on the options set
+ </summary>
+ <remarks>
+ <para>
+ This is part of the <see cref="T:log4net.Core.IOptionHandler"/> delayed object
+ activation scheme. The <see cref="M:log4net.Appender.EventLogAppender.ActivateOptions"/> method must
+ be called on this object after the configuration properties have
+ been set. Until <see cref="M:log4net.Appender.EventLogAppender.ActivateOptions"/> is called this
+ object is in an undefined state and must not be used.
+ </para>
+ <para>
+ If any of the configuration properties are modified then
+ <see cref="M:log4net.Appender.EventLogAppender.ActivateOptions"/> must be called again.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.EventLogAppender.CreateEventSource(System.String,System.String,System.String)">
+ <summary>
+ Create an event log source
+ </summary>
+ <remarks>
+ Uses different API calls under NET_2_0
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.EventLogAppender.Append(log4net.Core.LoggingEvent)">
+ <summary>
+ This method is called by the <see cref="M:log4net.Appender.AppenderSkeleton.DoAppend(log4net.Core.LoggingEvent)"/>
+ method.
+ </summary>
+ <param name="loggingEvent">the event to log</param>
+ <remarks>
+ <para>Writes the event to the system event log using the
+ <see cref="P:log4net.Appender.EventLogAppender.ApplicationName"/>.</para>
+
+ <para>If the event has an <c>EventID</c> property (see <see cref="P:log4net.Core.LoggingEvent.Properties"/>)
+ set then this integer will be used as the event log event id.</para>
+
+ <para>
+ There is a limit of 32K characters for an event log message
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.EventLogAppender.GetEntryType(log4net.Core.Level)">
+ <summary>
+ Get the equivalent <see cref="T:System.Diagnostics.EventLogEntryType"/> for a <see cref="T:log4net.Core.Level"/> <paramref name="p"/>
+ </summary>
+ <param name="level">the Level to convert to an EventLogEntryType</param>
+ <returns>The equivalent <see cref="T:System.Diagnostics.EventLogEntryType"/> for a <see cref="T:log4net.Core.Level"/> <paramref name="p"/></returns>
+ <remarks>
+ Because there are fewer applicable <see cref="T:System.Diagnostics.EventLogEntryType"/>
+ values to use in logging levels than there are in the
+ <see cref="T:log4net.Core.Level"/> this is a one way mapping. There is
+ a loss of information during the conversion.
+ </remarks>
+ </member>
+ <member name="F:log4net.Appender.EventLogAppender.m_logName">
+ <summary>
+ The log name is the section in the event logs where the messages
+ are stored.
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.EventLogAppender.m_applicationName">
+ <summary>
+ Name of the application to use when logging. This appears in the
+ application column of the event log named by <see cref="F:log4net.Appender.EventLogAppender.m_logName"/>.
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.EventLogAppender.m_machineName">
+ <summary>
+ The name of the machine which holds the event log. This is
+ currently only allowed to be '.' i.e. the current machine.
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.EventLogAppender.m_levelMapping">
+ <summary>
+ Mapping from level object to EventLogEntryType
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.EventLogAppender.m_securityContext">
+ <summary>
+ The security context to use for privileged calls
+ </summary>
+ </member>
+ <member name="P:log4net.Appender.EventLogAppender.LogName">
+ <summary>
+ The name of the log where messages will be stored.
+ </summary>
+ <value>
+ The string name of the log where messages will be stored.
+ </value>
+ <remarks>
+ <para>This is the name of the log as it appears in the Event Viewer
+ tree. The default value is to log into the <c>Application</c>
+ log, this is where most applications write their events. However
+ if you need a separate log for your application (or applications)
+ then you should set the <see cref="P:log4net.Appender.EventLogAppender.LogName"/> appropriately.</para>
+ <para>This should not be used to distinguish your event log messages
+ from those of other applications, the <see cref="P:log4net.Appender.EventLogAppender.ApplicationName"/>
+ property should be used to distinguish events. This property should be
+ used to group together events into a single log.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.EventLogAppender.ApplicationName">
+ <summary>
+ Property used to set the Application name. This appears in the
+ event logs when logging.
+ </summary>
+ <value>
+ The string used to distinguish events from different sources.
+ </value>
+ <remarks>
+ Sets the event log source property.
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.EventLogAppender.MachineName">
+ <summary>
+ This property is used to return the name of the computer to use
+ when accessing the event logs. Currently, this is the current
+ computer, denoted by a dot "."
+ </summary>
+ <value>
+ The string name of the machine holding the event log that
+ will be logged into.
+ </value>
+ <remarks>
+ This property cannot be changed. It is currently set to '.'
+ i.e. the local machine. This may be changed in future.
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.EventLogAppender.SecurityContext">
+ <summary>
+ Gets or sets the <see cref="P:log4net.Appender.EventLogAppender.SecurityContext"/> used to write to the EventLog.
+ </summary>
+ <value>
+ The <see cref="P:log4net.Appender.EventLogAppender.SecurityContext"/> used to write to the EventLog.
+ </value>
+ <remarks>
+ <para>
+ The system security context used to write to the EventLog.
+ </para>
+ <para>
+ Unless a <see cref="P:log4net.Appender.EventLogAppender.SecurityContext"/> specified here for this appender
+ the <see cref="P:log4net.Core.SecurityContextProvider.DefaultProvider"/> is queried for the
+ security context to use. The default behavior is to use the security context
+ of the current thread.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.EventLogAppender.RequiresLayout">
+ <summary>
+ This appender requires a <see cref="N:log4net.Layout"/> to be set.
+ </summary>
+ <value><c>true</c></value>
+ <remarks>
+ <para>
+ This appender requires a <see cref="N:log4net.Layout"/> to be set.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Appender.EventLogAppender.Level2EventLogEntryType">
+ <summary>
+ A class to act as a mapping between the level that a logging call is made at and
+ the color it should be displayed as.
+ </summary>
+ <remarks>
+ <para>
+ Defines the mapping between a level and its event log entry type.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.EventLogAppender.Level2EventLogEntryType.EventLogEntryType">
+ <summary>
+ The <see cref="P:log4net.Appender.EventLogAppender.Level2EventLogEntryType.EventLogEntryType"/> for this entry
+ </summary>
+ <remarks>
+ <para>
+ Required property.
+ The <see cref="P:log4net.Appender.EventLogAppender.Level2EventLogEntryType.EventLogEntryType"/> for this entry
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Appender.FileAppender">
+ <summary>
+ Appends logging events to a file.
+ </summary>
+ <remarks>
+ <para>
+ Logging events are sent to the file specified by
+ the <see cref="P:log4net.Appender.FileAppender.File"/> property.
+ </para>
+ <para>
+ The file can be opened in either append or overwrite mode
+ by specifying the <see cref="P:log4net.Appender.FileAppender.AppendToFile"/> property.
+ If the file path is relative it is taken as relative from
+ the application base directory. The file encoding can be
+ specified by setting the <see cref="P:log4net.Appender.FileAppender.Encoding"/> property.
+ </para>
+ <para>
+ The layout's <see cref="P:log4net.Layout.ILayout.Header"/> and <see cref="P:log4net.Layout.ILayout.Footer"/>
+ values will be written each time the file is opened and closed
+ respectively. If the <see cref="P:log4net.Appender.FileAppender.AppendToFile"/> property is <see langword="true"/>
+ then the file may contain multiple copies of the header and footer.
+ </para>
+ <para>
+ This appender will first try to open the file for writing when <see cref="M:log4net.Appender.FileAppender.ActivateOptions"/>
+ is called. This will typically be during configuration.
+ If the file cannot be opened for writing the appender will attempt
+ to open the file again each time a message is logged to the appender.
+ If the file cannot be opened for writing when a message is logged then
+ the message will be discarded by this appender.
+ </para>
+ <para>
+ The <see cref="T:log4net.Appender.FileAppender"/> supports pluggable file locking models via
+ the <see cref="P:log4net.Appender.FileAppender.LockingModel"/> property.
+ The default behavior, implemented by <see cref="T:log4net.Appender.FileAppender.ExclusiveLock"/>
+ is to obtain an exclusive write lock on the file until this appender is closed.
+ The alternative model, <see cref="T:log4net.Appender.FileAppender.MinimalLock"/>, only holds a
+ write lock while the appender is writing a logging event.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ <author>Rodrigo B. de Oliveira</author>
+ <author>Douglas de la Torre</author>
+ <author>Niall Daley</author>
+ </member>
+ <member name="T:log4net.Appender.TextWriterAppender">
+ <summary>
+ Sends logging events to a <see cref="T:System.IO.TextWriter"/>.
+ </summary>
+ <remarks>
+ <para>
+ An Appender that writes to a <see cref="T:System.IO.TextWriter"/>.
+ </para>
+ <para>
+ This appender may be used stand alone if initialized with an appropriate
+ writer, however it is typically used as a base class for an appender that
+ can open a <see cref="T:System.IO.TextWriter"/> to write to.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ <author>Douglas de la Torre</author>
+ </member>
+ <member name="M:log4net.Appender.TextWriterAppender.#ctor">
+ <summary>
+ Initializes a new instance of the <see cref="T:log4net.Appender.TextWriterAppender"/> class.
+ </summary>
+ <remarks>
+ <para>
+ Default constructor.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.TextWriterAppender.#ctor(log4net.Layout.ILayout,System.IO.Stream)">
+ <summary>
+ Initializes a new instance of the <see cref="T:log4net.Appender.TextWriterAppender"/> class and
+ sets the output destination to a new <see cref="T:System.IO.StreamWriter"/> initialized
+ with the specified <see cref="T:System.IO.Stream"/>.
+ </summary>
+ <param name="layout">The layout to use with this appender.</param>
+ <param name="os">The <see cref="T:System.IO.Stream"/> to output to.</param>
+ <remarks>
+ <para>
+ Obsolete constructor.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.TextWriterAppender.#ctor(log4net.Layout.ILayout,System.IO.TextWriter)">
+ <summary>
+ Initializes a new instance of the <see cref="T:log4net.Appender.TextWriterAppender"/> class and sets
+ the output destination to the specified <see cref="T:System.IO.StreamWriter"/>.
+ </summary>
+ <param name="layout">The layout to use with this appender</param>
+ <param name="writer">The <see cref="T:System.IO.TextWriter"/> to output to</param>
+ <remarks>
+ The <see cref="T:System.IO.TextWriter"/> must have been previously opened.
+ </remarks>
+ <remarks>
+ <para>
+ Obsolete constructor.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.TextWriterAppender.PreAppendCheck">
+ <summary>
+ This method determines if there is a sense in attempting to append.
+ </summary>
+ <remarks>
+ <para>
+ This method checked if an output target has been set and if a
+ layout has been set.
+ </para>
+ </remarks>
+ <returns><c>false</c> if any of the preconditions fail.</returns>
+ </member>
+ <member name="M:log4net.Appender.TextWriterAppender.Append(log4net.Core.LoggingEvent)">
+ <summary>
+ This method is called by the <see cref="M:log4net.Appender.AppenderSkeleton.DoAppend(log4net.Core.LoggingEvent)"/>
+ method.
+ </summary>
+ <param name="loggingEvent">The event to log.</param>
+ <remarks>
+ <para>
+ Writes a log statement to the output stream if the output stream exists
+ and is writable.
+ </para>
+ <para>
+ The format of the output will depend on the appender's layout.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.TextWriterAppender.Append(log4net.Core.LoggingEvent[])">
+ <summary>
+ This method is called by the <see cref="M:log4net.Appender.AppenderSkeleton.DoAppend(log4net.Core.LoggingEvent[])"/>
+ method.
+ </summary>
+ <param name="loggingEvents">The array of events to log.</param>
+ <remarks>
+ <para>
+ This method writes all the bulk logged events to the output writer
+ before flushing the stream.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.TextWriterAppender.OnClose">
+ <summary>
+ Close this appender instance. The underlying stream or writer is also closed.
+ </summary>
+ <remarks>
+ Closed appenders cannot be reused.
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.TextWriterAppender.WriteFooterAndCloseWriter">
+ <summary>
+ Writes the footer and closes the underlying <see cref="T:System.IO.TextWriter"/>.
+ </summary>
+ <remarks>
+ <para>
+ Writes the footer and closes the underlying <see cref="T:System.IO.TextWriter"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.TextWriterAppender.CloseWriter">
+ <summary>
+ Closes the underlying <see cref="T:System.IO.TextWriter"/>.
+ </summary>
+ <remarks>
+ <para>
+ Closes the underlying <see cref="T:System.IO.TextWriter"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.TextWriterAppender.Reset">
+ <summary>
+ Clears internal references to the underlying <see cref="T:System.IO.TextWriter"/>
+ and other variables.
+ </summary>
+ <remarks>
+ <para>
+ Subclasses can override this method for an alternate closing behavior.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.TextWriterAppender.WriteFooter">
+ <summary>
+ Writes a footer as produced by the embedded layout's <see cref="P:log4net.Layout.ILayout.Footer"/> property.
+ </summary>
+ <remarks>
+ <para>
+ Writes a footer as produced by the embedded layout's <see cref="P:log4net.Layout.ILayout.Footer"/> property.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.TextWriterAppender.WriteHeader">
+ <summary>
+ Writes a header produced by the embedded layout's <see cref="P:log4net.Layout.ILayout.Header"/> property.
+ </summary>
+ <remarks>
+ <para>
+ Writes a header produced by the embedded layout's <see cref="P:log4net.Layout.ILayout.Header"/> property.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.TextWriterAppender.PrepareWriter">
+ <summary>
+ Called to allow a subclass to lazily initialize the writer
+ </summary>
+ <remarks>
+ <para>
+ This method is called when an event is logged and the <see cref="P:log4net.Appender.TextWriterAppender.Writer"/> or
+ <see cref="P:log4net.Appender.TextWriterAppender.QuietWriter"/> have not been set. This allows a subclass to
+ attempt to initialize the writer multiple times.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Appender.TextWriterAppender.m_qtw">
+ <summary>
+ This is the <see cref="T:log4net.Util.QuietTextWriter"/> where logging events
+ will be written to.
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.TextWriterAppender.m_immediateFlush">
+ <summary>
+ Immediate flush means that the underlying <see cref="T:System.IO.TextWriter"/>
+ or output stream will be flushed at the end of each append operation.
+ </summary>
+ <remarks>
+ <para>
+ Immediate flush is slower but ensures that each append request is
+ actually written. If <see cref="P:log4net.Appender.TextWriterAppender.ImmediateFlush"/> is set to
+ <c>false</c>, then there is a good chance that the last few
+ logging events are not actually persisted if and when the application
+ crashes.
+ </para>
+ <para>
+ The default value is <c>true</c>.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.TextWriterAppender.ImmediateFlush">
+ <summary>
+ Gets or set whether the appender will flush at the end
+ of each append operation.
+ </summary>
+ <value>
+ <para>
+ The default behavior is to flush at the end of each
+ append operation.
+ </para>
+ <para>
+ If this option is set to <c>false</c>, then the underlying
+ stream can defer persisting the logging event to a later
+ time.
+ </para>
+ </value>
+ <remarks>
+ Avoiding the flush operation at the end of each append results in
+ a performance gain of 10 to 20 percent. However, there is safety
+ trade-off involved in skipping flushing. Indeed, when flushing is
+ skipped, then it is likely that the last few log events will not
+ be recorded on disk when the application exits. This is a high
+ price to pay even for a 20% performance gain.
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.TextWriterAppender.Writer">
+ <summary>
+ Sets the <see cref="T:System.IO.TextWriter"/> where the log output will go.
+ </summary>
+ <remarks>
+ <para>
+ The specified <see cref="T:System.IO.TextWriter"/> must be open and writable.
+ </para>
+ <para>
+ The <see cref="T:System.IO.TextWriter"/> will be closed when the appender
+ instance is closed.
+ </para>
+ <para>
+ <b>Note:</b> Logging to an unopened <see cref="T:System.IO.TextWriter"/> will fail.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.TextWriterAppender.ErrorHandler">
+ <summary>
+ Gets or set the <see cref="T:log4net.Core.IErrorHandler"/> and the underlying
+ <see cref="T:log4net.Util.QuietTextWriter"/>, if any, for this appender.
+ </summary>
+ <value>
+ The <see cref="T:log4net.Core.IErrorHandler"/> for this appender.
+ </value>
+ </member>
+ <member name="P:log4net.Appender.TextWriterAppender.RequiresLayout">
+ <summary>
+ This appender requires a <see cref="N:log4net.Layout"/> to be set.
+ </summary>
+ <value><c>true</c></value>
+ <remarks>
+ <para>
+ This appender requires a <see cref="N:log4net.Layout"/> to be set.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.TextWriterAppender.QuietWriter">
+ <summary>
+ Gets or sets the <see cref="T:log4net.Util.QuietTextWriter"/> where logging events
+ will be written to.
+ </summary>
+ <value>
+ The <see cref="T:log4net.Util.QuietTextWriter"/> where logging events are written.
+ </value>
+ <remarks>
+ <para>
+ This is the <see cref="T:log4net.Util.QuietTextWriter"/> where logging events
+ will be written to.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.FileAppender.#ctor">
+ <summary>
+ Default constructor
+ </summary>
+ <remarks>
+ <para>
+ Default constructor
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.FileAppender.#ctor(log4net.Layout.ILayout,System.String,System.Boolean)">
+ <summary>
+ Construct a new appender using the layout, file and append mode.
+ </summary>
+ <param name="layout">the layout to use with this appender</param>
+ <param name="filename">the full path to the file to write to</param>
+ <param name="append">flag to indicate if the file should be appended to</param>
+ <remarks>
+ <para>
+ Obsolete constructor.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.FileAppender.#ctor(log4net.Layout.ILayout,System.String)">
+ <summary>
+ Construct a new appender using the layout and file specified.
+ The file will be appended to.
+ </summary>
+ <param name="layout">the layout to use with this appender</param>
+ <param name="filename">the full path to the file to write to</param>
+ <remarks>
+ <para>
+ Obsolete constructor.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.FileAppender.ActivateOptions">
+ <summary>
+ Activate the options on the file appender.
+ </summary>
+ <remarks>
+ <para>
+ This is part of the <see cref="T:log4net.Core.IOptionHandler"/> delayed object
+ activation scheme. The <see cref="M:log4net.Appender.FileAppender.ActivateOptions"/> method must
+ be called on this object after the configuration properties have
+ been set. Until <see cref="M:log4net.Appender.FileAppender.ActivateOptions"/> is called this
+ object is in an undefined state and must not be used.
+ </para>
+ <para>
+ If any of the configuration properties are modified then
+ <see cref="M:log4net.Appender.FileAppender.ActivateOptions"/> must be called again.
+ </para>
+ <para>
+ This will cause the file to be opened.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.FileAppender.Reset">
+ <summary>
+ Closes any previously opened file and calls the parent's <see cref="M:log4net.Appender.TextWriterAppender.Reset"/>.
+ </summary>
+ <remarks>
+ <para>
+ Resets the filename and the file stream.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.FileAppender.PrepareWriter">
+ <summary>
+ Called to initialize the file writer
+ </summary>
+ <remarks>
+ <para>
+ Will be called for each logged message until the file is
+ successfully opened.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.FileAppender.Append(log4net.Core.LoggingEvent)">
+ <summary>
+ This method is called by the <see cref="M:log4net.Appender.AppenderSkeleton.DoAppend(log4net.Core.LoggingEvent)"/>
+ method.
+ </summary>
+ <param name="loggingEvent">The event to log.</param>
+ <remarks>
+ <para>
+ Writes a log statement to the output stream if the output stream exists
+ and is writable.
+ </para>
+ <para>
+ The format of the output will depend on the appender's layout.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.FileAppender.Append(log4net.Core.LoggingEvent[])">
+ <summary>
+ This method is called by the <see cref="M:log4net.Appender.AppenderSkeleton.DoAppend(log4net.Core.LoggingEvent[])"/>
+ method.
+ </summary>
+ <param name="loggingEvents">The array of events to log.</param>
+ <remarks>
+ <para>
+ Acquires the output file locks once before writing all the events to
+ the stream.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.FileAppender.WriteFooter">
+ <summary>
+ Writes a footer as produced by the embedded layout's <see cref="P:log4net.Layout.ILayout.Footer"/> property.
+ </summary>
+ <remarks>
+ <para>
+ Writes a footer as produced by the embedded layout's <see cref="P:log4net.Layout.ILayout.Footer"/> property.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.FileAppender.WriteHeader">
+ <summary>
+ Writes a header produced by the embedded layout's <see cref="P:log4net.Layout.ILayout.Header"/> property.
+ </summary>
+ <remarks>
+ <para>
+ Writes a header produced by the embedded layout's <see cref="P:log4net.Layout.ILayout.Header"/> property.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.FileAppender.CloseWriter">
+ <summary>
+ Closes the underlying <see cref="T:System.IO.TextWriter"/>.
+ </summary>
+ <remarks>
+ <para>
+ Closes the underlying <see cref="T:System.IO.TextWriter"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.FileAppender.CloseFile">
+ <summary>
+ Closes the previously opened file.
+ </summary>
+ <remarks>
+ <para>
+ Writes the <see cref="P:log4net.Layout.ILayout.Footer"/> to the file and then
+ closes the file.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.FileAppender.SafeOpenFile(System.String,System.Boolean)">
+ <summary>
+ Sets and <i>opens</i> the file where the log output will go. The specified file must be writable.
+ </summary>
+ <param name="fileName">The path to the log file. Must be a fully qualified path.</param>
+ <param name="append">If true will append to fileName. Otherwise will truncate fileName</param>
+ <remarks>
+ <para>
+ Calls <see cref="M:log4net.Appender.FileAppender.OpenFile(System.String,System.Boolean)"/> but guarantees not to throw an exception.
+ Errors are passed to the <see cref="P:log4net.Appender.TextWriterAppender.ErrorHandler"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.FileAppender.OpenFile(System.String,System.Boolean)">
+ <summary>
+ Sets and <i>opens</i> the file where the log output will go. The specified file must be writable.
+ </summary>
+ <param name="fileName">The path to the log file. Must be a fully qualified path.</param>
+ <param name="append">If true will append to fileName. Otherwise will truncate fileName</param>
+ <remarks>
+ <para>
+ If there was already an opened file, then the previous file
+ is closed first.
+ </para>
+ <para>
+ This method will ensure that the directory structure
+ for the <paramref name="fileName"/> specified exists.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.FileAppender.SetQWForFiles(System.IO.Stream)">
+ <summary>
+ Sets the quiet writer used for file output
+ </summary>
+ <param name="fileStream">the file stream that has been opened for writing</param>
+ <remarks>
+ <para>
+ This implementation of <see cref="M:log4net.Appender.FileAppender.SetQWForFiles(System.IO.Stream)"/> creates a <see cref="T:System.IO.StreamWriter"/>
+ over the <paramref name="fileStream"/> and passes it to the
+ <see cref="M:log4net.Appender.FileAppender.SetQWForFiles(System.IO.TextWriter)"/> method.
+ </para>
+ <para>
+ This method can be overridden by sub classes that want to wrap the
+ <see cref="T:System.IO.Stream"/> in some way, for example to encrypt the output
+ data using a <c>System.Security.Cryptography.CryptoStream</c>.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.FileAppender.SetQWForFiles(System.IO.TextWriter)">
+ <summary>
+ Sets the quiet writer being used.
+ </summary>
+ <param name="writer">the writer over the file stream that has been opened for writing</param>
+ <remarks>
+ <para>
+ This method can be overridden by sub classes that want to
+ wrap the <see cref="T:System.IO.TextWriter"/> in some way.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.FileAppender.ConvertToFullPath(System.String)">
+ <summary>
+ Convert a path into a fully qualified path.
+ </summary>
+ <param name="path">The path to convert.</param>
+ <returns>The fully qualified path.</returns>
+ <remarks>
+ <para>
+ Converts the path specified to a fully
+ qualified path. If the path is relative it is
+ taken as relative from the application base
+ directory.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Appender.FileAppender.m_appendToFile">
+ <summary>
+ Flag to indicate if we should append to the file
+ or overwrite the file. The default is to append.
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.FileAppender.m_fileName">
+ <summary>
+ The name of the log file.
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.FileAppender.m_encoding">
+ <summary>
+ The encoding to use for the file stream.
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.FileAppender.m_securityContext">
+ <summary>
+ The security context to use for privileged calls
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.FileAppender.m_stream">
+ <summary>
+ The stream to log to. Has added locking semantics
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.FileAppender.m_lockingModel">
+ <summary>
+ The locking model to use
+ </summary>
+ </member>
+ <member name="P:log4net.Appender.FileAppender.File">
+ <summary>
+ Gets or sets the path to the file that logging will be written to.
+ </summary>
+ <value>
+ The path to the file that logging will be written to.
+ </value>
+ <remarks>
+ <para>
+ If the path is relative it is taken as relative from
+ the application base directory.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.FileAppender.AppendToFile">
+ <summary>
+ Gets or sets a flag that indicates whether the file should be
+ appended to or overwritten.
+ </summary>
+ <value>
+ Indicates whether the file should be appended to or overwritten.
+ </value>
+ <remarks>
+ <para>
+ If the value is set to false then the file will be overwritten, if
+ it is set to true then the file will be appended to.
+ </para>
+ The default value is true.
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.FileAppender.Encoding">
+ <summary>
+ Gets or sets <see cref="P:log4net.Appender.FileAppender.Encoding"/> used to write to the file.
+ </summary>
+ <value>
+ The <see cref="P:log4net.Appender.FileAppender.Encoding"/> used to write to the file.
+ </value>
+ <remarks>
+ <para>
+ The default encoding set is <see cref="P:System.Text.Encoding.Default"/>
+ which is the encoding for the system's current ANSI code page.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.FileAppender.SecurityContext">
+ <summary>
+ Gets or sets the <see cref="P:log4net.Appender.FileAppender.SecurityContext"/> used to write to the file.
+ </summary>
+ <value>
+ The <see cref="P:log4net.Appender.FileAppender.SecurityContext"/> used to write to the file.
+ </value>
+ <remarks>
+ <para>
+ Unless a <see cref="P:log4net.Appender.FileAppender.SecurityContext"/> specified here for this appender
+ the <see cref="P:log4net.Core.SecurityContextProvider.DefaultProvider"/> is queried for the
+ security context to use. The default behavior is to use the security context
+ of the current thread.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.FileAppender.LockingModel">
+ <summary>
+ Gets or sets the <see cref="P:log4net.Appender.FileAppender.LockingModel"/> used to handle locking of the file.
+ </summary>
+ <value>
+ The <see cref="P:log4net.Appender.FileAppender.LockingModel"/> used to lock the file.
+ </value>
+ <remarks>
+ <para>
+ Gets or sets the <see cref="P:log4net.Appender.FileAppender.LockingModel"/> used to handle locking of the file.
+ </para>
+ <para>
+ There are two built in locking models, <see cref="T:log4net.Appender.FileAppender.ExclusiveLock"/> and <see cref="T:log4net.Appender.FileAppender.MinimalLock"/>.
+ The former locks the file from the start of logging to the end and the
+ later lock only for the minimal amount of time when logging each message.
+ </para>
+ <para>
+ The default locking model is the <see cref="T:log4net.Appender.FileAppender.ExclusiveLock"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Appender.FileAppender.LockingStream">
+ <summary>
+ Write only <see cref="T:System.IO.Stream"/> that uses the <see cref="T:log4net.Appender.FileAppender.LockingModelBase"/>
+ to manage access to an underlying resource.
+ </summary>
+ </member>
+ <member name="M:log4net.Appender.FileAppender.LockingStream.BeginWrite(System.Byte[],System.Int32,System.Int32,System.AsyncCallback,System.Object)">
+ <summary>
+ True asynchronous writes are not supported, the implementation forces a synchronous write.
+ </summary>
+ </member>
+ <member name="T:log4net.Core.LogException">
+ <summary>
+ Exception base type for log4net.
+ </summary>
+ <remarks>
+ <para>
+ This type extends <see cref="T:System.ApplicationException"/>. It
+ does not add any new functionality but does differentiate the
+ type of exception being thrown.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="M:log4net.Core.LogException.#ctor">
+ <summary>
+ Constructor
+ </summary>
+ <remarks>
+ <para>
+ Initializes a new instance of the <see cref="T:log4net.Core.LogException"/> class.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LogException.#ctor(System.String)">
+ <summary>
+ Constructor
+ </summary>
+ <param name="message">A message to include with the exception.</param>
+ <remarks>
+ <para>
+ Initializes a new instance of the <see cref="T:log4net.Core.LogException"/> class with
+ the specified message.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LogException.#ctor(System.String,System.Exception)">
+ <summary>
+ Constructor
+ </summary>
+ <param name="message">A message to include with the exception.</param>
+ <param name="innerException">A nested exception to include.</param>
+ <remarks>
+ <para>
+ Initializes a new instance of the <see cref="T:log4net.Core.LogException"/> class
+ with the specified message and inner exception.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LogException.#ctor(System.Runtime.Serialization.SerializationInfo,System.Runtime.Serialization.StreamingContext)">
+ <summary>
+ Serialization constructor
+ </summary>
+ <param name="info">The <see cref="T:System.Runtime.Serialization.SerializationInfo"/> that holds the serialized object data about the exception being thrown.</param>
+ <param name="context">The <see cref="T:System.Runtime.Serialization.StreamingContext"/> that contains contextual information about the source or destination.</param>
+ <remarks>
+ <para>
+ Initializes a new instance of the <see cref="T:log4net.Core.LogException"/> class
+ with serialized data.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Appender.FileAppender.LockingModelBase">
+ <summary>
+ Locking model base class
+ </summary>
+ <remarks>
+ <para>
+ Base class for the locking models available to the <see cref="T:log4net.Appender.FileAppender"/> derived loggers.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.FileAppender.LockingModelBase.OpenFile(System.String,System.Boolean,System.Text.Encoding)">
+ <summary>
+ Open the output file
+ </summary>
+ <param name="filename">The filename to use</param>
+ <param name="append">Whether to append to the file, or overwrite</param>
+ <param name="encoding">The encoding to use</param>
+ <remarks>
+ <para>
+ Open the file specified and prepare for logging.
+ No writes will be made until <see cref="M:log4net.Appender.FileAppender.LockingModelBase.AcquireLock"/> is called.
+ Must be called before any calls to <see cref="M:log4net.Appender.FileAppender.LockingModelBase.AcquireLock"/>,
+ <see cref="M:log4net.Appender.FileAppender.LockingModelBase.ReleaseLock"/> and <see cref="M:log4net.Appender.FileAppender.LockingModelBase.CloseFile"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.FileAppender.LockingModelBase.CloseFile">
+ <summary>
+ Close the file
+ </summary>
+ <remarks>
+ <para>
+ Close the file. No further writes will be made.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.FileAppender.LockingModelBase.AcquireLock">
+ <summary>
+ Acquire the lock on the file
+ </summary>
+ <returns>A stream that is ready to be written to.</returns>
+ <remarks>
+ <para>
+ Acquire the lock on the file in preparation for writing to it.
+ Return a stream pointing to the file. <see cref="M:log4net.Appender.FileAppender.LockingModelBase.ReleaseLock"/>
+ must be called to release the lock on the output file.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.FileAppender.LockingModelBase.ReleaseLock">
+ <summary>
+ Release the lock on the file
+ </summary>
+ <remarks>
+ <para>
+ Release the lock on the file. No further writes will be made to the
+ stream until <see cref="M:log4net.Appender.FileAppender.LockingModelBase.AcquireLock"/> is called again.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.FileAppender.LockingModelBase.CurrentAppender">
+ <summary>
+ Gets or sets the <see cref="T:log4net.Appender.FileAppender"/> for this LockingModel
+ </summary>
+ <value>
+ The <see cref="T:log4net.Appender.FileAppender"/> for this LockingModel
+ </value>
+ <remarks>
+ <para>
+ The file appender this locking model is attached to and working on
+ behalf of.
+ </para>
+ <para>
+ The file appender is used to locate the security context and the error handler to use.
+ </para>
+ <para>
+ The value of this property will be set before <see cref="M:log4net.Appender.FileAppender.LockingModelBase.OpenFile(System.String,System.Boolean,System.Text.Encoding)"/> is
+ called.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Appender.FileAppender.ExclusiveLock">
+ <summary>
+ Hold an exclusive lock on the output file
+ </summary>
+ <remarks>
+ <para>
+ Open the file once for writing and hold it open until <see cref="M:log4net.Appender.FileAppender.ExclusiveLock.CloseFile"/> is called.
+ Maintains an exclusive lock on the file during this time.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.FileAppender.ExclusiveLock.OpenFile(System.String,System.Boolean,System.Text.Encoding)">
+ <summary>
+ Open the file specified and prepare for logging.
+ </summary>
+ <param name="filename">The filename to use</param>
+ <param name="append">Whether to append to the file, or overwrite</param>
+ <param name="encoding">The encoding to use</param>
+ <remarks>
+ <para>
+ Open the file specified and prepare for logging.
+ No writes will be made until <see cref="M:log4net.Appender.FileAppender.ExclusiveLock.AcquireLock"/> is called.
+ Must be called before any calls to <see cref="M:log4net.Appender.FileAppender.ExclusiveLock.AcquireLock"/>,
+ <see cref="M:log4net.Appender.FileAppender.ExclusiveLock.ReleaseLock"/> and <see cref="M:log4net.Appender.FileAppender.ExclusiveLock.CloseFile"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.FileAppender.ExclusiveLock.CloseFile">
+ <summary>
+ Close the file
+ </summary>
+ <remarks>
+ <para>
+ Close the file. No further writes will be made.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.FileAppender.ExclusiveLock.AcquireLock">
+ <summary>
+ Acquire the lock on the file
+ </summary>
+ <returns>A stream that is ready to be written to.</returns>
+ <remarks>
+ <para>
+ Does nothing. The lock is already taken
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.FileAppender.ExclusiveLock.ReleaseLock">
+ <summary>
+ Release the lock on the file
+ </summary>
+ <remarks>
+ <para>
+ Does nothing. The lock will be released when the file is closed.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Appender.FileAppender.MinimalLock">
+ <summary>
+ Acquires the file lock for each write
+ </summary>
+ <remarks>
+ <para>
+ Opens the file once for each <see cref="M:log4net.Appender.FileAppender.MinimalLock.AcquireLock"/>/<see cref="M:log4net.Appender.FileAppender.MinimalLock.ReleaseLock"/> cycle,
+ thus holding the lock for the minimal amount of time. This method of locking
+ is considerably slower than <see cref="T:log4net.Appender.FileAppender.ExclusiveLock"/> but allows
+ other processes to move/delete the log file whilst logging continues.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.FileAppender.MinimalLock.OpenFile(System.String,System.Boolean,System.Text.Encoding)">
+ <summary>
+ Prepares to open the file when the first message is logged.
+ </summary>
+ <param name="filename">The filename to use</param>
+ <param name="append">Whether to append to the file, or overwrite</param>
+ <param name="encoding">The encoding to use</param>
+ <remarks>
+ <para>
+ Open the file specified and prepare for logging.
+ No writes will be made until <see cref="M:log4net.Appender.FileAppender.MinimalLock.AcquireLock"/> is called.
+ Must be called before any calls to <see cref="M:log4net.Appender.FileAppender.MinimalLock.AcquireLock"/>,
+ <see cref="M:log4net.Appender.FileAppender.MinimalLock.ReleaseLock"/> and <see cref="M:log4net.Appender.FileAppender.MinimalLock.CloseFile"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.FileAppender.MinimalLock.CloseFile">
+ <summary>
+ Close the file
+ </summary>
+ <remarks>
+ <para>
+ Close the file. No further writes will be made.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.FileAppender.MinimalLock.AcquireLock">
+ <summary>
+ Acquire the lock on the file
+ </summary>
+ <returns>A stream that is ready to be written to.</returns>
+ <remarks>
+ <para>
+ Acquire the lock on the file in preparation for writing to it.
+ Return a stream pointing to the file. <see cref="M:log4net.Appender.FileAppender.MinimalLock.ReleaseLock"/>
+ must be called to release the lock on the output file.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.FileAppender.MinimalLock.ReleaseLock">
+ <summary>
+ Release the lock on the file
+ </summary>
+ <remarks>
+ <para>
+ Release the lock on the file. No further writes will be made to the
+ stream until <see cref="M:log4net.Appender.FileAppender.MinimalLock.AcquireLock"/> is called again.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Appender.ForwardingAppender">
+ <summary>
+ This appender forwards logging events to attached appenders.
+ </summary>
+ <remarks>
+ <para>
+ The forwarding appender can be used to specify different thresholds
+ and filters for the same appender at different locations within the hierarchy.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="M:log4net.Appender.ForwardingAppender.#ctor">
+ <summary>
+ Initializes a new instance of the <see cref="T:log4net.Appender.ForwardingAppender"/> class.
+ </summary>
+ <remarks>
+ <para>
+ Default constructor.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.ForwardingAppender.OnClose">
+ <summary>
+ Closes the appender and releases resources.
+ </summary>
+ <remarks>
+ <para>
+ Releases any resources allocated within the appender such as file handles,
+ network connections, etc.
+ </para>
+ <para>
+ It is a programming error to append to a closed appender.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.ForwardingAppender.Append(log4net.Core.LoggingEvent)">
+ <summary>
+ Forward the logging event to the attached appenders
+ </summary>
+ <param name="loggingEvent">The event to log.</param>
+ <remarks>
+ <para>
+ Delivers the logging event to all the attached appenders.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.ForwardingAppender.Append(log4net.Core.LoggingEvent[])">
+ <summary>
+ Forward the logging events to the attached appenders
+ </summary>
+ <param name="loggingEvents">The array of events to log.</param>
+ <remarks>
+ <para>
+ Delivers the logging events to all the attached appenders.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.ForwardingAppender.AddAppender(log4net.Appender.IAppender)">
+ <summary>
+ Adds an <see cref="T:log4net.Appender.IAppender"/> to the list of appenders of this
+ instance.
+ </summary>
+ <param name="newAppender">The <see cref="T:log4net.Appender.IAppender"/> to add to this appender.</param>
+ <remarks>
+ <para>
+ If the specified <see cref="T:log4net.Appender.IAppender"/> is already in the list of
+ appenders, then it won't be added again.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.ForwardingAppender.GetAppender(System.String)">
+ <summary>
+ Looks for the appender with the specified name.
+ </summary>
+ <param name="name">The name of the appender to lookup.</param>
+ <returns>
+ The appender with the specified name, or <c>null</c>.
+ </returns>
+ <remarks>
+ <para>
+ Get the named appender attached to this appender.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.ForwardingAppender.RemoveAllAppenders">
+ <summary>
+ Removes all previously added appenders from this appender.
+ </summary>
+ <remarks>
+ <para>
+ This is useful when re-reading configuration information.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.ForwardingAppender.RemoveAppender(log4net.Appender.IAppender)">
+ <summary>
+ Removes the specified appender from the list of appenders.
+ </summary>
+ <param name="appender">The appender to remove.</param>
+ <returns>The appender removed from the list</returns>
+ <remarks>
+ The appender removed is not closed.
+ If you are discarding the appender you must call
+ <see cref="M:log4net.Appender.IAppender.Close"/> on the appender removed.
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.ForwardingAppender.RemoveAppender(System.String)">
+ <summary>
+ Removes the appender with the specified name from the list of appenders.
+ </summary>
+ <param name="name">The name of the appender to remove.</param>
+ <returns>The appender removed from the list</returns>
+ <remarks>
+ The appender removed is not closed.
+ If you are discarding the appender you must call
+ <see cref="M:log4net.Appender.IAppender.Close"/> on the appender removed.
+ </remarks>
+ </member>
+ <member name="F:log4net.Appender.ForwardingAppender.m_appenderAttachedImpl">
+ <summary>
+ Implementation of the <see cref="T:log4net.Core.IAppenderAttachable"/> interface
+ </summary>
+ </member>
+ <member name="P:log4net.Appender.ForwardingAppender.Appenders">
+ <summary>
+ Gets the appenders contained in this appender as an
+ <see cref="T:System.Collections.ICollection"/>.
+ </summary>
+ <remarks>
+ If no appenders can be found, then an <see cref="T:log4net.Util.EmptyCollection"/>
+ is returned.
+ </remarks>
+ <returns>
+ A collection of the appenders in this appender.
+ </returns>
+ </member>
+ <member name="T:log4net.Appender.LocalSyslogAppender">
+ <summary>
+ Logs events to a local syslog service.
+ </summary>
+ <remarks>
+ <note>
+ This appender uses the POSIX libc library functions <c>openlog</c>, <c>syslog</c>, and <c>closelog</c>.
+ If these functions are not available on the local system then this appender will not work!
+ </note>
+ <para>
+ The functions <c>openlog</c>, <c>syslog</c>, and <c>closelog</c> are specified in SUSv2 and
+ POSIX 1003.1-2001 standards. These are used to log messages to the local syslog service.
+ </para>
+ <para>
+ This appender talks to a local syslog service. If you need to log to a remote syslog
+ daemon and you cannot configure your local syslog service to do this you may be
+ able to use the <see cref="T:log4net.Appender.RemoteSyslogAppender"/> to log via UDP.
+ </para>
+ <para>
+ Syslog messages must have a facility and and a severity. The severity
+ is derived from the Level of the logging event.
+ The facility must be chosen from the set of defined syslog
+ <see cref="T:log4net.Appender.LocalSyslogAppender.SyslogFacility"/> values. The facilities list is predefined
+ and cannot be extended.
+ </para>
+ <para>
+ An identifier is specified with each log message. This can be specified
+ by setting the <see cref="P:log4net.Appender.LocalSyslogAppender.Identity"/> property. The identity (also know
+ as the tag) must not contain white space. The default value for the
+ identity is the application name (from <see cref="P:log4net.Util.SystemInfo.ApplicationFriendlyName"/>).
+ </para>
+ </remarks>
+ <author>Rob Lyon</author>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="M:log4net.Appender.LocalSyslogAppender.#ctor">
+ <summary>
+ Initializes a new instance of the <see cref="T:log4net.Appender.LocalSyslogAppender"/> class.
+ </summary>
+ <remarks>
+ This instance of the <see cref="T:log4net.Appender.LocalSyslogAppender"/> class is set up to write
+ to a local syslog service.
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.LocalSyslogAppender.AddMapping(log4net.Appender.LocalSyslogAppender.LevelSeverity)">
+ <summary>
+ Add a mapping of level to severity
+ </summary>
+ <param name="mapping">The mapping to add</param>
+ <remarks>
+ <para>
+ Adds a <see cref="T:log4net.Appender.LocalSyslogAppender.LevelSeverity"/> to this appender.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.LocalSyslogAppender.ActivateOptions">
+ <summary>
+ Initialize the appender based on the options set.
+ </summary>
+ <remarks>
+ <para>
+ This is part of the <see cref="T:log4net.Core.IOptionHandler"/> delayed object
+ activation scheme. The <see cref="M:log4net.Appender.LocalSyslogAppender.ActivateOptions"/> method must
+ be called on this object after the configuration properties have
+ been set. Until <see cref="M:log4net.Appender.LocalSyslogAppender.ActivateOptions"/> is called this
+ object is in an undefined state and must not be used.
+ </para>
+ <para>
+ If any of the configuration properties are modified then
+ <see cref="M:log4net.Appender.LocalSyslogAppender.ActivateOptions"/> must be called again.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.LocalSyslogAppender.Append(log4net.Core.LoggingEvent)">
+ <summary>
+ This method is called by the <see cref="M:log4net.Appender.AppenderSkeleton.DoAppend(log4net.Core.LoggingEvent)"/> method.
+ </summary>
+ <param name="loggingEvent">The event to log.</param>
+ <remarks>
+ <para>
+ Writes the event to a remote syslog daemon.
+ </para>
+ <para>
+ The format of the output will depend on the appender's layout.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.LocalSyslogAppender.OnClose">
+ <summary>
+ Close the syslog when the appender is closed
+ </summary>
+ <remarks>
+ <para>
+ Close the syslog when the appender is closed
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.LocalSyslogAppender.GetSeverity(log4net.Core.Level)">
+ <summary>
+ Translates a log4net level to a syslog severity.
+ </summary>
+ <param name="level">A log4net level.</param>
+ <returns>A syslog severity.</returns>
+ <remarks>
+ <para>
+ Translates a log4net level to a syslog severity.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.LocalSyslogAppender.GeneratePriority(log4net.Appender.LocalSyslogAppender.SyslogFacility,log4net.Appender.LocalSyslogAppender.SyslogSeverity)">
+ <summary>
+ Generate a syslog priority.
+ </summary>
+ <param name="facility">The syslog facility.</param>
+ <param name="severity">The syslog severity.</param>
+ <returns>A syslog priority.</returns>
+ </member>
+ <member name="F:log4net.Appender.LocalSyslogAppender.m_facility">
+ <summary>
+ The facility. The default facility is <see cref="F:log4net.Appender.LocalSyslogAppender.SyslogFacility.User"/>.
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.LocalSyslogAppender.m_identity">
+ <summary>
+ The message identity
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.LocalSyslogAppender.m_handleToIdentity">
+ <summary>
+ Marshaled handle to the identity string. We have to hold on to the
+ string as the <c>openlog</c> and <c>syslog</c> APIs just hold the
+ pointer to the ident and dereference it for each log message.
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.LocalSyslogAppender.m_levelMapping">
+ <summary>
+ Mapping from level object to syslog severity
+ </summary>
+ </member>
+ <member name="M:log4net.Appender.LocalSyslogAppender.openlog(System.IntPtr,System.Int32,log4net.Appender.LocalSyslogAppender.SyslogFacility)">
+ <summary>
+ Open connection to system logger.
+ </summary>
+ </member>
+ <member name="M:log4net.Appender.LocalSyslogAppender.syslog(System.Int32,System.String,System.String)">
+ <summary>
+ Generate a log message.
+ </summary>
+ <remarks>
+ <para>
+ The libc syslog method takes a format string and a variable argument list similar
+ to the classic printf function. As this type of vararg list is not supported
+ by C# we need to specify the arguments explicitly. Here we have specified the
+ format string with a single message argument. The caller must set the format
+ string to <c>"%s"</c>.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.LocalSyslogAppender.closelog">
+ <summary>
+ Close descriptor used to write to system logger.
+ </summary>
+ </member>
+ <member name="P:log4net.Appender.LocalSyslogAppender.Identity">
+ <summary>
+ Message identity
+ </summary>
+ <remarks>
+ <para>
+ An identifier is specified with each log message. This can be specified
+ by setting the <see cref="P:log4net.Appender.LocalSyslogAppender.Identity"/> property. The identity (also know
+ as the tag) must not contain white space. The default value for the
+ identity is the application name (from <see cref="P:log4net.Util.SystemInfo.ApplicationFriendlyName"/>).
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.LocalSyslogAppender.Facility">
+ <summary>
+ Syslog facility
+ </summary>
+ <remarks>
+ Set to one of the <see cref="T:log4net.Appender.LocalSyslogAppender.SyslogFacility"/> values. The list of
+ facilities is predefined and cannot be extended. The default value
+ is <see cref="F:log4net.Appender.LocalSyslogAppender.SyslogFacility.User"/>.
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.LocalSyslogAppender.RequiresLayout">
+ <summary>
+ This appender requires a <see cref="P:log4net.Appender.AppenderSkeleton.Layout"/> to be set.
+ </summary>
+ <value><c>true</c></value>
+ <remarks>
+ <para>
+ This appender requires a <see cref="P:log4net.Appender.AppenderSkeleton.Layout"/> to be set.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Appender.LocalSyslogAppender.SyslogSeverity">
+ <summary>
+ syslog severities
+ </summary>
+ <remarks>
+ <para>
+ The log4net Level maps to a syslog severity using the
+ <see cref="M:log4net.Appender.LocalSyslogAppender.AddMapping(log4net.Appender.LocalSyslogAppender.LevelSeverity)"/> method and the <see cref="T:log4net.Appender.LocalSyslogAppender.LevelSeverity"/>
+ class. The severity is set on <see cref="P:log4net.Appender.LocalSyslogAppender.LevelSeverity.Severity"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Appender.LocalSyslogAppender.SyslogSeverity.Emergency">
+ <summary>
+ system is unusable
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.LocalSyslogAppender.SyslogSeverity.Alert">
+ <summary>
+ action must be taken immediately
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.LocalSyslogAppender.SyslogSeverity.Critical">
+ <summary>
+ critical conditions
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.LocalSyslogAppender.SyslogSeverity.Error">
+ <summary>
+ error conditions
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.LocalSyslogAppender.SyslogSeverity.Warning">
+ <summary>
+ warning conditions
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.LocalSyslogAppender.SyslogSeverity.Notice">
+ <summary>
+ normal but significant condition
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.LocalSyslogAppender.SyslogSeverity.Informational">
+ <summary>
+ informational
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.LocalSyslogAppender.SyslogSeverity.Debug">
+ <summary>
+ debug-level messages
+ </summary>
+ </member>
+ <member name="T:log4net.Appender.LocalSyslogAppender.SyslogFacility">
+ <summary>
+ syslog facilities
+ </summary>
+ <remarks>
+ <para>
+ The syslog facility defines which subsystem the logging comes from.
+ This is set on the <see cref="P:log4net.Appender.LocalSyslogAppender.Facility"/> property.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Appender.LocalSyslogAppender.SyslogFacility.Kernel">
+ <summary>
+ kernel messages
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.LocalSyslogAppender.SyslogFacility.User">
+ <summary>
+ random user-level messages
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.LocalSyslogAppender.SyslogFacility.Mail">
+ <summary>
+ mail system
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.LocalSyslogAppender.SyslogFacility.Daemons">
+ <summary>
+ system daemons
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.LocalSyslogAppender.SyslogFacility.Authorization">
+ <summary>
+ security/authorization messages
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.LocalSyslogAppender.SyslogFacility.Syslog">
+ <summary>
+ messages generated internally by syslogd
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.LocalSyslogAppender.SyslogFacility.Printer">
+ <summary>
+ line printer subsystem
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.LocalSyslogAppender.SyslogFacility.News">
+ <summary>
+ network news subsystem
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.LocalSyslogAppender.SyslogFacility.Uucp">
+ <summary>
+ UUCP subsystem
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.LocalSyslogAppender.SyslogFacility.Clock">
+ <summary>
+ clock (cron/at) daemon
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.LocalSyslogAppender.SyslogFacility.Authorization2">
+ <summary>
+ security/authorization messages (private)
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.LocalSyslogAppender.SyslogFacility.Ftp">
+ <summary>
+ ftp daemon
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.LocalSyslogAppender.SyslogFacility.Ntp">
+ <summary>
+ NTP subsystem
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.LocalSyslogAppender.SyslogFacility.Audit">
+ <summary>
+ log audit
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.LocalSyslogAppender.SyslogFacility.Alert">
+ <summary>
+ log alert
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.LocalSyslogAppender.SyslogFacility.Clock2">
+ <summary>
+ clock daemon
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.LocalSyslogAppender.SyslogFacility.Local0">
+ <summary>
+ reserved for local use
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.LocalSyslogAppender.SyslogFacility.Local1">
+ <summary>
+ reserved for local use
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.LocalSyslogAppender.SyslogFacility.Local2">
+ <summary>
+ reserved for local use
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.LocalSyslogAppender.SyslogFacility.Local3">
+ <summary>
+ reserved for local use
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.LocalSyslogAppender.SyslogFacility.Local4">
+ <summary>
+ reserved for local use
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.LocalSyslogAppender.SyslogFacility.Local5">
+ <summary>
+ reserved for local use
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.LocalSyslogAppender.SyslogFacility.Local6">
+ <summary>
+ reserved for local use
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.LocalSyslogAppender.SyslogFacility.Local7">
+ <summary>
+ reserved for local use
+ </summary>
+ </member>
+ <member name="T:log4net.Appender.LocalSyslogAppender.LevelSeverity">
+ <summary>
+ A class to act as a mapping between the level that a logging call is made at and
+ the syslog severity that is should be logged at.
+ </summary>
+ <remarks>
+ <para>
+ A class to act as a mapping between the level that a logging call is made at and
+ the syslog severity that is should be logged at.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.LocalSyslogAppender.LevelSeverity.Severity">
+ <summary>
+ The mapped syslog severity for the specified level
+ </summary>
+ <remarks>
+ <para>
+ Required property.
+ The mapped syslog severity for the specified level
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Appender.MemoryAppender">
+ <summary>
+ Stores logging events in an array.
+ </summary>
+ <remarks>
+ <para>
+ The memory appender stores all the logging events
+ that are appended in an in-memory array.
+ </para>
+ <para>
+ Use the <see cref="M:log4net.Appender.MemoryAppender.GetEvents"/> method to get
+ the current list of events that have been appended.
+ </para>
+ <para>
+ Use the <see cref="M:log4net.Appender.MemoryAppender.Clear"/> method to clear the
+ current list of events.
+ </para>
+ </remarks>
+ <author>Julian Biddle</author>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="M:log4net.Appender.MemoryAppender.#ctor">
+ <summary>
+ Initializes a new instance of the <see cref="T:log4net.Appender.MemoryAppender"/> class.
+ </summary>
+ <remarks>
+ <para>
+ Default constructor.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.MemoryAppender.GetEvents">
+ <summary>
+ Gets the events that have been logged.
+ </summary>
+ <returns>The events that have been logged</returns>
+ <remarks>
+ <para>
+ Gets the events that have been logged.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.MemoryAppender.Append(log4net.Core.LoggingEvent)">
+ <summary>
+ This method is called by the <see cref="M:log4net.Appender.AppenderSkeleton.DoAppend(log4net.Core.LoggingEvent)"/> method.
+ </summary>
+ <param name="loggingEvent">the event to log</param>
+ <remarks>
+ <para>Stores the <paramref name="loggingEvent"/> in the events list.</para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.MemoryAppender.Clear">
+ <summary>
+ Clear the list of events
+ </summary>
+ <remarks>
+ Clear the list of events
+ </remarks>
+ </member>
+ <member name="F:log4net.Appender.MemoryAppender.m_eventsList">
+ <summary>
+ The list of events that have been appended.
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.MemoryAppender.m_fixFlags">
+ <summary>
+ Value indicating which fields in the event should be fixed
+ </summary>
+ <remarks>
+ By default all fields are fixed
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.MemoryAppender.OnlyFixPartialEventData">
+ <summary>
+ Gets or sets a value indicating whether only part of the logging event
+ data should be fixed.
+ </summary>
+ <value>
+ <c>true</c> if the appender should only fix part of the logging event
+ data, otherwise <c>false</c>. The default is <c>false</c>.
+ </value>
+ <remarks>
+ <para>
+ Setting this property to <c>true</c> will cause only part of the event
+ data to be fixed and stored in the appender, hereby improving performance.
+ </para>
+ <para>
+ See <see cref="M:log4net.Core.LoggingEvent.FixVolatileData(System.Boolean)"/> for more information.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.MemoryAppender.Fix">
+ <summary>
+ Gets or sets the fields that will be fixed in the event
+ </summary>
+ <remarks>
+ <para>
+ The logging event needs to have certain thread specific values
+ captured before it can be buffered. See <see cref="P:log4net.Core.LoggingEvent.Fix"/>
+ for details.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Appender.NetSendAppender">
+ <summary>
+ Logs entries by sending network messages using the
+ <see cref="M:log4net.Appender.NetSendAppender.NetMessageBufferSend(System.String,System.String,System.String,System.String,System.Int32)"/> native function.
+ </summary>
+ <remarks>
+ <para>
+ You can send messages only to names that are active
+ on the network. If you send the message to a user name,
+ that user must be logged on and running the Messenger
+ service to receive the message.
+ </para>
+ <para>
+ The receiver will get a top most window displaying the
+ messages one at a time, therefore this appender should
+ not be used to deliver a high volume of messages.
+ </para>
+ <para>
+ The following table lists some possible uses for this appender :
+ </para>
+ <para>
+ <list type="table">
+ <listheader>
+ <term>Action</term>
+ <description>Property Value(s)</description>
+ </listheader>
+ <item>
+ <term>Send a message to a user account on the local machine</term>
+ <description>
+ <para>
+ <paramref name="Server"/> = &lt;name of the local machine&gt;
+ </para>
+ <para>
+ <paramref name="Recipient"/> = &lt;user name&gt;
+ </para>
+ </description>
+ </item>
+ <item>
+ <term>Send a message to a user account on a remote machine</term>
+ <description>
+ <para>
+ <paramref name="Server"/> = &lt;name of the remote machine&gt;
+ </para>
+ <para>
+ <paramref name="Recipient"/> = &lt;user name&gt;
+ </para>
+ </description>
+ </item>
+ <item>
+ <term>Send a message to a domain user account</term>
+ <description>
+ <para>
+ <paramref name="Server"/> = &lt;name of a domain controller | uninitialized&gt;
+ </para>
+ <para>
+ <paramref name="Recipient"/> = &lt;user name&gt;
+ </para>
+ </description>
+ </item>
+ <item>
+ <term>Send a message to all the names in a workgroup or domain</term>
+ <description>
+ <para>
+ <paramref name="Recipient"/> = &lt;workgroup name | domain name&gt;*
+ </para>
+ </description>
+ </item>
+ <item>
+ <term>Send a message from the local machine to a remote machine</term>
+ <description>
+ <para>
+ <paramref name="Server"/> = &lt;name of the local machine | uninitialized&gt;
+ </para>
+ <para>
+ <paramref name="Recipient"/> = &lt;name of the remote machine&gt;
+ </para>
+ </description>
+ </item>
+ </list>
+ </para>
+ <para>
+ <b>Note :</b> security restrictions apply for sending
+ network messages, see <see cref="M:log4net.Appender.NetSendAppender.NetMessageBufferSend(System.String,System.String,System.String,System.String,System.Int32)"/>
+ for more information.
+ </para>
+ </remarks>
+ <example>
+ <para>
+ An example configuration section to log information
+ using this appender from the local machine, named
+ LOCAL_PC, to machine OPERATOR_PC :
+ </para>
+ <code lang="XML" escaped="true">
+ <appender name="NetSendAppender_Operator" type="log4net.Appender.NetSendAppender">
+ <server value="LOCAL_PC"/>
+ <recipient value="OPERATOR_PC"/>
+ <layout type="log4net.Layout.PatternLayout" value="%-5p %c [%x] - %m%n"/>
+ </appender>
+ </code>
+ </example>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="F:log4net.Appender.NetSendAppender.m_server">
+ <summary>
+ The DNS or NetBIOS name of the server on which the function is to execute.
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.NetSendAppender.m_sender">
+ <summary>
+ The sender of the network message.
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.NetSendAppender.m_recipient">
+ <summary>
+ The message alias to which the message should be sent.
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.NetSendAppender.m_securityContext">
+ <summary>
+ The security context to use for privileged calls
+ </summary>
+ </member>
+ <member name="M:log4net.Appender.NetSendAppender.#ctor">
+ <summary>
+ Initializes the appender.
+ </summary>
+ <remarks>
+ The default constructor initializes all fields to their default values.
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.NetSendAppender.ActivateOptions">
+ <summary>
+ Initialize the appender based on the options set.
+ </summary>
+ <remarks>
+ <para>
+ This is part of the <see cref="T:log4net.Core.IOptionHandler"/> delayed object
+ activation scheme. The <see cref="M:log4net.Appender.NetSendAppender.ActivateOptions"/> method must
+ be called on this object after the configuration properties have
+ been set. Until <see cref="M:log4net.Appender.NetSendAppender.ActivateOptions"/> is called this
+ object is in an undefined state and must not be used.
+ </para>
+ <para>
+ If any of the configuration properties are modified then
+ <see cref="M:log4net.Appender.NetSendAppender.ActivateOptions"/> must be called again.
+ </para>
+ <para>
+ The appender will be ignored if no <see cref="P:log4net.Appender.NetSendAppender.Recipient"/> was specified.
+ </para>
+ </remarks>
+ <exception cref="T:System.ArgumentNullException">The required property <see cref="P:log4net.Appender.NetSendAppender.Recipient"/> was not specified.</exception>
+ </member>
+ <member name="M:log4net.Appender.NetSendAppender.Append(log4net.Core.LoggingEvent)">
+ <summary>
+ This method is called by the <see cref="M:log4net.Appender.AppenderSkeleton.DoAppend(log4net.Core.LoggingEvent)"/> method.
+ </summary>
+ <param name="loggingEvent">The event to log.</param>
+ <remarks>
+ <para>
+ Sends the event using a network message.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.NetSendAppender.NetMessageBufferSend(System.String,System.String,System.String,System.String,System.Int32)">
+ <summary>
+ Sends a buffer of information to a registered message alias.
+ </summary>
+ <param name="serverName">The DNS or NetBIOS name of the server on which the function is to execute.</param>
+ <param name="msgName">The message alias to which the message buffer should be sent</param>
+ <param name="fromName">The originator of the message.</param>
+ <param name="buffer">The message text.</param>
+ <param name="bufferSize">The length, in bytes, of the message text.</param>
+ <remarks>
+ <para>
+ The following restrictions apply for sending network messages:
+ </para>
+ <para>
+ <list type="table">
+ <listheader>
+ <term>Platform</term>
+ <description>Requirements</description>
+ </listheader>
+ <item>
+ <term>Windows NT</term>
+ <description>
+ <para>
+ No special group membership is required to send a network message.
+ </para>
+ <para>
+ Admin, Accounts, Print, or Server Operator group membership is required to
+ successfully send a network message on a remote server.
+ </para>
+ </description>
+ </item>
+ <item>
+ <term>Windows 2000 or later</term>
+ <description>
+ <para>
+ If you send a message on a domain controller that is running Active Directory,
+ access is allowed or denied based on the access control list (ACL) for the securable
+ object. The default ACL permits only Domain Admins and Account Operators to send a network message.
+ </para>
+ <para>
+ On a member server or workstation, only Administrators and Server Operators can send a network message.
+ </para>
+ </description>
+ </item>
+ </list>
+ </para>
+ <para>
+ For more information see <a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/netmgmt/netmgmt/security_requirements_for_the_network_management_functions.asp">Security Requirements for the Network Management Functions</a>.
+ </para>
+ </remarks>
+ <returns>
+ <para>
+ If the function succeeds, the return value is zero.
+ </para>
+ </returns>
+ </member>
+ <member name="P:log4net.Appender.NetSendAppender.Sender">
+ <summary>
+ Gets or sets the sender of the message.
+ </summary>
+ <value>
+ The sender of the message.
+ </value>
+ <remarks>
+ If this property is not specified, the message is sent from the local computer.
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.NetSendAppender.Recipient">
+ <summary>
+ Gets or sets the message alias to which the message should be sent.
+ </summary>
+ <value>
+ The recipient of the message.
+ </value>
+ <remarks>
+ This property should always be specified in order to send a message.
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.NetSendAppender.Server">
+ <summary>
+ Gets or sets the DNS or NetBIOS name of the remote server on which the function is to execute.
+ </summary>
+ <value>
+ DNS or NetBIOS name of the remote server on which the function is to execute.
+ </value>
+ <remarks>
+ <para>
+ For Windows NT 4.0 and earlier, the string should begin with \\.
+ </para>
+ <para>
+ If this property is not specified, the local computer is used.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.NetSendAppender.SecurityContext">
+ <summary>
+ Gets or sets the <see cref="P:log4net.Appender.NetSendAppender.SecurityContext"/> used to call the NetSend method.
+ </summary>
+ <value>
+ The <see cref="P:log4net.Appender.NetSendAppender.SecurityContext"/> used to call the NetSend method.
+ </value>
+ <remarks>
+ <para>
+ Unless a <see cref="P:log4net.Appender.NetSendAppender.SecurityContext"/> specified here for this appender
+ the <see cref="P:log4net.Core.SecurityContextProvider.DefaultProvider"/> is queried for the
+ security context to use. The default behavior is to use the security context
+ of the current thread.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.NetSendAppender.RequiresLayout">
+ <summary>
+ This appender requires a <see cref="N:log4net.Layout"/> to be set.
+ </summary>
+ <value><c>true</c></value>
+ <remarks>
+ <para>
+ This appender requires a <see cref="N:log4net.Layout"/> to be set.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Appender.OutputDebugStringAppender">
+ <summary>
+ Appends log events to the OutputDebugString system.
+ </summary>
+ <remarks>
+ <para>
+ OutputDebugStringAppender appends log events to the
+ OutputDebugString system.
+ </para>
+ <para>
+ The string is passed to the native <c>OutputDebugString</c>
+ function.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="M:log4net.Appender.OutputDebugStringAppender.#ctor">
+ <summary>
+ Initializes a new instance of the <see cref="T:log4net.Appender.OutputDebugStringAppender"/> class.
+ </summary>
+ <remarks>
+ <para>
+ Default constructor.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.OutputDebugStringAppender.Append(log4net.Core.LoggingEvent)">
+ <summary>
+ Write the logging event to the output debug string API
+ </summary>
+ <param name="loggingEvent">the event to log</param>
+ <remarks>
+ <para>
+ Write the logging event to the output debug string API
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.OutputDebugStringAppender.OutputDebugString(System.String)">
+ <summary>
+ Stub for OutputDebugString native method
+ </summary>
+ <param name="message">the string to output</param>
+ <remarks>
+ <para>
+ Stub for OutputDebugString native method
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.OutputDebugStringAppender.RequiresLayout">
+ <summary>
+ This appender requires a <see cref="N:log4net.Layout"/> to be set.
+ </summary>
+ <value><c>true</c></value>
+ <remarks>
+ <para>
+ This appender requires a <see cref="N:log4net.Layout"/> to be set.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Appender.RemoteSyslogAppender">
+ <summary>
+ Logs events to a remote syslog daemon.
+ </summary>
+ <remarks>
+ <para>
+ The BSD syslog protocol is used to remotely log to
+ a syslog daemon. The syslogd listens for for messages
+ on UDP port 514.
+ </para>
+ <para>
+ The syslog UDP protocol is not authenticated. Most syslog daemons
+ do not accept remote log messages because of the security implications.
+ You may be able to use the LocalSyslogAppender to talk to a local
+ syslog service.
+ </para>
+ <para>
+ There is an RFC 3164 that claims to document the BSD Syslog Protocol.
+ This RFC can be seen here: http://www.faqs.org/rfcs/rfc3164.html.
+ This appender generates what the RFC calls an "Original Device Message",
+ i.e. does not include the TIMESTAMP or HOSTNAME fields. By observation
+ this format of message will be accepted by all current syslog daemon
+ implementations. The daemon will attach the current time and the source
+ hostname or IP address to any messages received.
+ </para>
+ <para>
+ Syslog messages must have a facility and and a severity. The severity
+ is derived from the Level of the logging event.
+ The facility must be chosen from the set of defined syslog
+ <see cref="T:log4net.Appender.RemoteSyslogAppender.SyslogFacility"/> values. The facilities list is predefined
+ and cannot be extended.
+ </para>
+ <para>
+ An identifier is specified with each log message. This can be specified
+ by setting the <see cref="P:log4net.Appender.RemoteSyslogAppender.Identity"/> property. The identity (also know
+ as the tag) must not contain white space. The default value for the
+ identity is the application name (from <see cref="P:log4net.Core.LoggingEvent.Domain"/>).
+ </para>
+ </remarks>
+ <author>Rob Lyon</author>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="T:log4net.Appender.UdpAppender">
+ <summary>
+ Sends logging events as connectionless UDP datagrams to a remote host or a
+ multicast group using an <see cref="T:System.Net.Sockets.UdpClient"/>.
+ </summary>
+ <remarks>
+ <para>
+ UDP guarantees neither that messages arrive, nor that they arrive in the correct order.
+ </para>
+ <para>
+ To view the logging results, a custom application can be developed that listens for logging
+ events.
+ </para>
+ <para>
+ When decoding events send via this appender remember to use the same encoding
+ to decode the events as was used to send the events. See the <see cref="P:log4net.Appender.UdpAppender.Encoding"/>
+ property to specify the encoding to use.
+ </para>
+ </remarks>
+ <example>
+ This example shows how to log receive logging events that are sent
+ on IP address 244.0.0.1 and port 8080 to the console. The event is
+ encoded in the packet as a unicode string and it is decoded as such.
+ <code lang="C#">
+ IPEndPoint remoteEndPoint = new IPEndPoint(IPAddress.Any, 0);
+ UdpClient udpClient;
+ byte[] buffer;
+ string loggingEvent;
+
+ try
+ {
+ udpClient = new UdpClient(8080);
+
+ while(true)
+ {
+ buffer = udpClient.Receive(ref remoteEndPoint);
+ loggingEvent = System.Text.Encoding.Unicode.GetString(buffer);
+ Console.WriteLine(loggingEvent);
+ }
+ }
+ catch(Exception e)
+ {
+ Console.WriteLine(e.ToString());
+ }
+ </code>
+ <code lang="Visual Basic">
+ Dim remoteEndPoint as IPEndPoint
+ Dim udpClient as UdpClient
+ Dim buffer as Byte()
+ Dim loggingEvent as String
+
+ Try
+ remoteEndPoint = new IPEndPoint(IPAddress.Any, 0)
+ udpClient = new UdpClient(8080)
+
+ While True
+ buffer = udpClient.Receive(ByRef remoteEndPoint)
+ loggingEvent = System.Text.Encoding.Unicode.GetString(buffer)
+ Console.WriteLine(loggingEvent)
+ Wend
+ Catch e As Exception
+ Console.WriteLine(e.ToString())
+ End Try
+ </code>
+ <para>
+ An example configuration section to log information using this appender to the
+ IP 224.0.0.1 on port 8080:
+ </para>
+ <code lang="XML" escaped="true">
+ <appender name="UdpAppender" type="log4net.Appender.UdpAppender">
+ <remoteAddress value="224.0.0.1"/>
+ <remotePort value="8080"/>
+ <layout type="log4net.Layout.PatternLayout" value="%-5level %logger [%ndc] - %message%newline"/>
+ </appender>
+ </code>
+ </example>
+ <author>Gert Driesen</author>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="M:log4net.Appender.UdpAppender.#ctor">
+ <summary>
+ Initializes a new instance of the <see cref="T:log4net.Appender.UdpAppender"/> class.
+ </summary>
+ <remarks>
+ The default constructor initializes all fields to their default values.
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.UdpAppender.ActivateOptions">
+ <summary>
+ Initialize the appender based on the options set.
+ </summary>
+ <remarks>
+ <para>
+ This is part of the <see cref="T:log4net.Core.IOptionHandler"/> delayed object
+ activation scheme. The <see cref="M:log4net.Appender.UdpAppender.ActivateOptions"/> method must
+ be called on this object after the configuration properties have
+ been set. Until <see cref="M:log4net.Appender.UdpAppender.ActivateOptions"/> is called this
+ object is in an undefined state and must not be used.
+ </para>
+ <para>
+ If any of the configuration properties are modified then
+ <see cref="M:log4net.Appender.UdpAppender.ActivateOptions"/> must be called again.
+ </para>
+ <para>
+ The appender will be ignored if no <see cref="P:log4net.Appender.UdpAppender.RemoteAddress"/> was specified or
+ an invalid remote or local TCP port number was specified.
+ </para>
+ </remarks>
+ <exception cref="T:System.ArgumentNullException">The required property <see cref="P:log4net.Appender.UdpAppender.RemoteAddress"/> was not specified.</exception>
+ <exception cref="T:System.ArgumentOutOfRangeException">The TCP port number assigned to <see cref="P:log4net.Appender.UdpAppender.LocalPort"/> or <see cref="P:log4net.Appender.UdpAppender.RemotePort"/> is less than <see cref="F:System.Net.IPEndPoint.MinPort"/> or greater than <see cref="F:System.Net.IPEndPoint.MaxPort"/>.</exception>
+ </member>
+ <member name="M:log4net.Appender.UdpAppender.Append(log4net.Core.LoggingEvent)">
+ <summary>
+ This method is called by the <see cref="M:log4net.Appender.AppenderSkeleton.DoAppend(log4net.Core.LoggingEvent)"/> method.
+ </summary>
+ <param name="loggingEvent">The event to log.</param>
+ <remarks>
+ <para>
+ Sends the event using an UDP datagram.
+ </para>
+ <para>
+ Exceptions are passed to the <see cref="P:log4net.Appender.AppenderSkeleton.ErrorHandler"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.UdpAppender.OnClose">
+ <summary>
+ Closes the UDP connection and releases all resources associated with
+ this <see cref="T:log4net.Appender.UdpAppender"/> instance.
+ </summary>
+ <remarks>
+ <para>
+ Disables the underlying <see cref="T:System.Net.Sockets.UdpClient"/> and releases all managed
+ and unmanaged resources associated with the <see cref="T:log4net.Appender.UdpAppender"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.UdpAppender.InitializeClientConnection">
+ <summary>
+ Initializes the underlying <see cref="T:System.Net.Sockets.UdpClient"/> connection.
+ </summary>
+ <remarks>
+ <para>
+ The underlying <see cref="T:System.Net.Sockets.UdpClient"/> is initialized and binds to the
+ port number from which you intend to communicate.
+ </para>
+ <para>
+ Exceptions are passed to the <see cref="P:log4net.Appender.AppenderSkeleton.ErrorHandler"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Appender.UdpAppender.m_remoteAddress">
+ <summary>
+ The IP address of the remote host or multicast group to which
+ the logging event will be sent.
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.UdpAppender.m_remotePort">
+ <summary>
+ The TCP port number of the remote host or multicast group to
+ which the logging event will be sent.
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.UdpAppender.m_remoteEndPoint">
+ <summary>
+ The cached remote endpoint to which the logging events will be sent.
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.UdpAppender.m_localPort">
+ <summary>
+ The TCP port number from which the <see cref="T:System.Net.Sockets.UdpClient"/> will communicate.
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.UdpAppender.m_client">
+ <summary>
+ The <see cref="T:System.Net.Sockets.UdpClient"/> instance that will be used for sending the
+ logging events.
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.UdpAppender.m_encoding">
+ <summary>
+ The encoding to use for the packet.
+ </summary>
+ </member>
+ <member name="P:log4net.Appender.UdpAppender.RemoteAddress">
+ <summary>
+ Gets or sets the IP address of the remote host or multicast group to which
+ the underlying <see cref="T:System.Net.Sockets.UdpClient"/> should sent the logging event.
+ </summary>
+ <value>
+ The IP address of the remote host or multicast group to which the logging event
+ will be sent.
+ </value>
+ <remarks>
+ <para>
+ Multicast addresses are identified by IP class <b>D</b> addresses (in the range 224.0.0.0 to
+ 239.255.255.255). Multicast packets can pass across different networks through routers, so
+ it is possible to use multicasts in an Internet scenario as long as your network provider
+ supports multicasting.
+ </para>
+ <para>
+ Hosts that want to receive particular multicast messages must register their interest by joining
+ the multicast group. Multicast messages are not sent to networks where no host has joined
+ the multicast group. Class <b>D</b> IP addresses are used for multicast groups, to differentiate
+ them from normal host addresses, allowing nodes to easily detect if a message is of interest.
+ </para>
+ <para>
+ Static multicast addresses that are needed globally are assigned by IANA. A few examples are listed in the table below:
+ </para>
+ <para>
+ <list type="table">
+ <listheader>
+ <term>IP Address</term>
+ <description>Description</description>
+ </listheader>
+ <item>
+ <term>224.0.0.1</term>
+ <description>
+ <para>
+ Sends a message to all system on the subnet.
+ </para>
+ </description>
+ </item>
+ <item>
+ <term>224.0.0.2</term>
+ <description>
+ <para>
+ Sends a message to all routers on the subnet.
+ </para>
+ </description>
+ </item>
+ <item>
+ <term>224.0.0.12</term>
+ <description>
+ <para>
+ The DHCP server answers messages on the IP address 224.0.0.12, but only on a subnet.
+ </para>
+ </description>
+ </item>
+ </list>
+ </para>
+ <para>
+ A complete list of actually reserved multicast addresses and their owners in the ranges
+ defined by RFC 3171 can be found at the <A href="http://www.iana.org/assignments/multicast-addresses">IANA web site</A>.
+ </para>
+ <para>
+ The address range 239.0.0.0 to 239.255.255.255 is reserved for administrative scope-relative
+ addresses. These addresses can be reused with other local groups. Routers are typically
+ configured with filters to prevent multicast traffic in this range from flowing outside
+ of the local network.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.UdpAppender.RemotePort">
+ <summary>
+ Gets or sets the TCP port number of the remote host or multicast group to which
+ the underlying <see cref="T:System.Net.Sockets.UdpClient"/> should sent the logging event.
+ </summary>
+ <value>
+ An integer value in the range <see cref="F:System.Net.IPEndPoint.MinPort"/> to <see cref="F:System.Net.IPEndPoint.MaxPort"/>
+ indicating the TCP port number of the remote host or multicast group to which the logging event
+ will be sent.
+ </value>
+ <remarks>
+ The underlying <see cref="T:System.Net.Sockets.UdpClient"/> will send messages to this TCP port number
+ on the remote host or multicast group.
+ </remarks>
+ <exception cref="T:System.ArgumentOutOfRangeException">The value specified is less than <see cref="F:System.Net.IPEndPoint.MinPort"/> or greater than <see cref="F:System.Net.IPEndPoint.MaxPort"/>.</exception>
+ </member>
+ <member name="P:log4net.Appender.UdpAppender.LocalPort">
+ <summary>
+ Gets or sets the TCP port number from which the underlying <see cref="T:System.Net.Sockets.UdpClient"/> will communicate.
+ </summary>
+ <value>
+ An integer value in the range <see cref="F:System.Net.IPEndPoint.MinPort"/> to <see cref="F:System.Net.IPEndPoint.MaxPort"/>
+ indicating the TCP port number from which the underlying <see cref="T:System.Net.Sockets.UdpClient"/> will communicate.
+ </value>
+ <remarks>
+ <para>
+ The underlying <see cref="T:System.Net.Sockets.UdpClient"/> will bind to this port for sending messages.
+ </para>
+ <para>
+ Setting the value to 0 (the default) will cause the udp client not to bind to
+ a local port.
+ </para>
+ </remarks>
+ <exception cref="T:System.ArgumentOutOfRangeException">The value specified is less than <see cref="F:System.Net.IPEndPoint.MinPort"/> or greater than <see cref="F:System.Net.IPEndPoint.MaxPort"/>.</exception>
+ </member>
+ <member name="P:log4net.Appender.UdpAppender.Encoding">
+ <summary>
+ Gets or sets <see cref="P:log4net.Appender.UdpAppender.Encoding"/> used to write the packets.
+ </summary>
+ <value>
+ The <see cref="P:log4net.Appender.UdpAppender.Encoding"/> used to write the packets.
+ </value>
+ <remarks>
+ <para>
+ The <see cref="P:log4net.Appender.UdpAppender.Encoding"/> used to write the packets.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.UdpAppender.Client">
+ <summary>
+ Gets or sets the underlying <see cref="T:System.Net.Sockets.UdpClient"/>.
+ </summary>
+ <value>
+ The underlying <see cref="T:System.Net.Sockets.UdpClient"/>.
+ </value>
+ <remarks>
+ <see cref="T:log4net.Appender.UdpAppender"/> creates a <see cref="T:System.Net.Sockets.UdpClient"/> to send logging events
+ over a network. Classes deriving from <see cref="T:log4net.Appender.UdpAppender"/> can use this
+ property to get or set this <see cref="T:System.Net.Sockets.UdpClient"/>. Use the underlying <see cref="T:System.Net.Sockets.UdpClient"/>
+ returned from <see cref="P:log4net.Appender.UdpAppender.Client"/> if you require access beyond that which
+ <see cref="T:log4net.Appender.UdpAppender"/> provides.
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.UdpAppender.RemoteEndPoint">
+ <summary>
+ Gets or sets the cached remote endpoint to which the logging events should be sent.
+ </summary>
+ <value>
+ The cached remote endpoint to which the logging events will be sent.
+ </value>
+ <remarks>
+ The <see cref="M:log4net.Appender.UdpAppender.ActivateOptions"/> method will initialize the remote endpoint
+ with the values of the <see cref="P:log4net.Appender.UdpAppender.RemoteAddress"/> and <see cref="P:log4net.Appender.UdpAppender.RemotePort"/>
+ properties.
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.UdpAppender.RequiresLayout">
+ <summary>
+ This appender requires a <see cref="N:log4net.Layout"/> to be set.
+ </summary>
+ <value><c>true</c></value>
+ <remarks>
+ <para>
+ This appender requires a <see cref="N:log4net.Layout"/> to be set.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Appender.RemoteSyslogAppender.DefaultSyslogPort">
+ <summary>
+ Syslog port 514
+ </summary>
+ </member>
+ <member name="M:log4net.Appender.RemoteSyslogAppender.#ctor">
+ <summary>
+ Initializes a new instance of the <see cref="T:log4net.Appender.RemoteSyslogAppender"/> class.
+ </summary>
+ <remarks>
+ This instance of the <see cref="T:log4net.Appender.RemoteSyslogAppender"/> class is set up to write
+ to a remote syslog daemon.
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.RemoteSyslogAppender.AddMapping(log4net.Appender.RemoteSyslogAppender.LevelSeverity)">
+ <summary>
+ Add a mapping of level to severity
+ </summary>
+ <param name="mapping">The mapping to add</param>
+ <remarks>
+ <para>
+ Add a <see cref="T:log4net.Appender.RemoteSyslogAppender.LevelSeverity"/> mapping to this appender.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.RemoteSyslogAppender.Append(log4net.Core.LoggingEvent)">
+ <summary>
+ This method is called by the <see cref="M:log4net.Appender.AppenderSkeleton.DoAppend(log4net.Core.LoggingEvent)"/> method.
+ </summary>
+ <param name="loggingEvent">The event to log.</param>
+ <remarks>
+ <para>
+ Writes the event to a remote syslog daemon.
+ </para>
+ <para>
+ The format of the output will depend on the appender's layout.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.RemoteSyslogAppender.ActivateOptions">
+ <summary>
+ Initialize the options for this appender
+ </summary>
+ <remarks>
+ <para>
+ Initialize the level to syslog severity mappings set on this appender.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.RemoteSyslogAppender.GetSeverity(log4net.Core.Level)">
+ <summary>
+ Translates a log4net level to a syslog severity.
+ </summary>
+ <param name="level">A log4net level.</param>
+ <returns>A syslog severity.</returns>
+ <remarks>
+ <para>
+ Translates a log4net level to a syslog severity.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.RemoteSyslogAppender.GeneratePriority(log4net.Appender.RemoteSyslogAppender.SyslogFacility,log4net.Appender.RemoteSyslogAppender.SyslogSeverity)">
+ <summary>
+ Generate a syslog priority.
+ </summary>
+ <param name="facility">The syslog facility.</param>
+ <param name="severity">The syslog severity.</param>
+ <returns>A syslog priority.</returns>
+ <remarks>
+ <para>
+ Generate a syslog priority.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Appender.RemoteSyslogAppender.m_facility">
+ <summary>
+ The facility. The default facility is <see cref="F:log4net.Appender.RemoteSyslogAppender.SyslogFacility.User"/>.
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.RemoteSyslogAppender.m_identity">
+ <summary>
+ The message identity
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.RemoteSyslogAppender.m_levelMapping">
+ <summary>
+ Mapping from level object to syslog severity
+ </summary>
+ </member>
+ <member name="P:log4net.Appender.RemoteSyslogAppender.Identity">
+ <summary>
+ Message identity
+ </summary>
+ <remarks>
+ <para>
+ An identifier is specified with each log message. This can be specified
+ by setting the <see cref="P:log4net.Appender.RemoteSyslogAppender.Identity"/> property. The identity (also know
+ as the tag) must not contain white space. The default value for the
+ identity is the application name (from <see cref="P:log4net.Core.LoggingEvent.Domain"/>).
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.RemoteSyslogAppender.Facility">
+ <summary>
+ Syslog facility
+ </summary>
+ <remarks>
+ Set to one of the <see cref="T:log4net.Appender.RemoteSyslogAppender.SyslogFacility"/> values. The list of
+ facilities is predefined and cannot be extended. The default value
+ is <see cref="F:log4net.Appender.RemoteSyslogAppender.SyslogFacility.User"/>.
+ </remarks>
+ </member>
+ <member name="T:log4net.Appender.RemoteSyslogAppender.SyslogSeverity">
+ <summary>
+ syslog severities
+ </summary>
+ <remarks>
+ <para>
+ The syslog severities.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Appender.RemoteSyslogAppender.SyslogSeverity.Emergency">
+ <summary>
+ system is unusable
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.RemoteSyslogAppender.SyslogSeverity.Alert">
+ <summary>
+ action must be taken immediately
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.RemoteSyslogAppender.SyslogSeverity.Critical">
+ <summary>
+ critical conditions
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.RemoteSyslogAppender.SyslogSeverity.Error">
+ <summary>
+ error conditions
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.RemoteSyslogAppender.SyslogSeverity.Warning">
+ <summary>
+ warning conditions
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.RemoteSyslogAppender.SyslogSeverity.Notice">
+ <summary>
+ normal but significant condition
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.RemoteSyslogAppender.SyslogSeverity.Informational">
+ <summary>
+ informational
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.RemoteSyslogAppender.SyslogSeverity.Debug">
+ <summary>
+ debug-level messages
+ </summary>
+ </member>
+ <member name="T:log4net.Appender.RemoteSyslogAppender.SyslogFacility">
+ <summary>
+ syslog facilities
+ </summary>
+ <remarks>
+ <para>
+ The syslog facilities
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Appender.RemoteSyslogAppender.SyslogFacility.Kernel">
+ <summary>
+ kernel messages
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.RemoteSyslogAppender.SyslogFacility.User">
+ <summary>
+ random user-level messages
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.RemoteSyslogAppender.SyslogFacility.Mail">
+ <summary>
+ mail system
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.RemoteSyslogAppender.SyslogFacility.Daemons">
+ <summary>
+ system daemons
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.RemoteSyslogAppender.SyslogFacility.Authorization">
+ <summary>
+ security/authorization messages
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.RemoteSyslogAppender.SyslogFacility.Syslog">
+ <summary>
+ messages generated internally by syslogd
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.RemoteSyslogAppender.SyslogFacility.Printer">
+ <summary>
+ line printer subsystem
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.RemoteSyslogAppender.SyslogFacility.News">
+ <summary>
+ network news subsystem
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.RemoteSyslogAppender.SyslogFacility.Uucp">
+ <summary>
+ UUCP subsystem
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.RemoteSyslogAppender.SyslogFacility.Clock">
+ <summary>
+ clock (cron/at) daemon
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.RemoteSyslogAppender.SyslogFacility.Authorization2">
+ <summary>
+ security/authorization messages (private)
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.RemoteSyslogAppender.SyslogFacility.Ftp">
+ <summary>
+ ftp daemon
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.RemoteSyslogAppender.SyslogFacility.Ntp">
+ <summary>
+ NTP subsystem
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.RemoteSyslogAppender.SyslogFacility.Audit">
+ <summary>
+ log audit
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.RemoteSyslogAppender.SyslogFacility.Alert">
+ <summary>
+ log alert
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.RemoteSyslogAppender.SyslogFacility.Clock2">
+ <summary>
+ clock daemon
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.RemoteSyslogAppender.SyslogFacility.Local0">
+ <summary>
+ reserved for local use
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.RemoteSyslogAppender.SyslogFacility.Local1">
+ <summary>
+ reserved for local use
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.RemoteSyslogAppender.SyslogFacility.Local2">
+ <summary>
+ reserved for local use
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.RemoteSyslogAppender.SyslogFacility.Local3">
+ <summary>
+ reserved for local use
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.RemoteSyslogAppender.SyslogFacility.Local4">
+ <summary>
+ reserved for local use
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.RemoteSyslogAppender.SyslogFacility.Local5">
+ <summary>
+ reserved for local use
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.RemoteSyslogAppender.SyslogFacility.Local6">
+ <summary>
+ reserved for local use
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.RemoteSyslogAppender.SyslogFacility.Local7">
+ <summary>
+ reserved for local use
+ </summary>
+ </member>
+ <member name="T:log4net.Appender.RemoteSyslogAppender.LevelSeverity">
+ <summary>
+ A class to act as a mapping between the level that a logging call is made at and
+ the syslog severity that is should be logged at.
+ </summary>
+ <remarks>
+ <para>
+ A class to act as a mapping between the level that a logging call is made at and
+ the syslog severity that is should be logged at.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.RemoteSyslogAppender.LevelSeverity.Severity">
+ <summary>
+ The mapped syslog severity for the specified level
+ </summary>
+ <remarks>
+ <para>
+ Required property.
+ The mapped syslog severity for the specified level
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Appender.RemotingAppender">
+ <summary>
+ Delivers logging events to a remote logging sink.
+ </summary>
+ <remarks>
+ <para>
+ This Appender is designed to deliver events to a remote sink.
+ That is any object that implements the <see cref="T:log4net.Appender.RemotingAppender.IRemoteLoggingSink"/>
+ interface. It delivers the events using .NET remoting. The
+ object to deliver events to is specified by setting the
+ appenders <see cref="P:log4net.Appender.RemotingAppender.Sink"/> property.</para>
+ <para>
+ The RemotingAppender buffers events before sending them. This allows it to
+ make more efficient use of the remoting infrastructure.</para>
+ <para>
+ Once the buffer is full the events are still not sent immediately.
+ They are scheduled to be sent using a pool thread. The effect is that
+ the send occurs asynchronously. This is very important for a
+ number of non obvious reasons. The remoting infrastructure will
+ flow thread local variables (stored in the <see cref="T:System.Runtime.Remoting.Messaging.CallContext"/>),
+ if they are marked as <see cref="T:System.Runtime.Remoting.Messaging.ILogicalThreadAffinative"/>, across the
+ remoting boundary. If the server is not contactable then
+ the remoting infrastructure will clear the <see cref="T:System.Runtime.Remoting.Messaging.ILogicalThreadAffinative"/>
+ objects from the <see cref="T:System.Runtime.Remoting.Messaging.CallContext"/>. To prevent a logging failure from
+ having side effects on the calling application the remoting call must be made
+ from a separate thread to the one used by the application. A <see cref="T:System.Threading.ThreadPool"/>
+ thread is used for this. If no <see cref="T:System.Threading.ThreadPool"/> thread is available then
+ the events will block in the thread pool manager until a thread is available.</para>
+ <para>
+ Because the events are sent asynchronously using pool threads it is possible to close
+ this appender before all the queued events have been sent.
+ When closing the appender attempts to wait until all the queued events have been sent, but
+ this will timeout after 30 seconds regardless.</para>
+ <para>
+ If this appender is being closed because the <see cref="E:System.AppDomain.ProcessExit"/>
+ event has fired it may not be possible to send all the queued events. During process
+ exit the runtime limits the time that a <see cref="E:System.AppDomain.ProcessExit"/>
+ event handler is allowed to run for. If the runtime terminates the threads before
+ the queued events have been sent then they will be lost. To ensure that all events
+ are sent the appender must be closed before the application exits. See
+ <see cref="M:log4net.Core.LoggerManager.Shutdown"/> for details on how to shutdown
+ log4net programmatically.</para>
+ </remarks>
+ <seealso cref="T:log4net.Appender.RemotingAppender.IRemoteLoggingSink"/>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ <author>Daniel Cazzulino</author>
+ </member>
+ <member name="M:log4net.Appender.RemotingAppender.#ctor">
+ <summary>
+ Initializes a new instance of the <see cref="T:log4net.Appender.RemotingAppender"/> class.
+ </summary>
+ <remarks>
+ <para>
+ Default constructor.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.RemotingAppender.ActivateOptions">
+ <summary>
+ Initialize the appender based on the options set
+ </summary>
+ <remarks>
+ <para>
+ This is part of the <see cref="T:log4net.Core.IOptionHandler"/> delayed object
+ activation scheme. The <see cref="M:log4net.Appender.RemotingAppender.ActivateOptions"/> method must
+ be called on this object after the configuration properties have
+ been set. Until <see cref="M:log4net.Appender.RemotingAppender.ActivateOptions"/> is called this
+ object is in an undefined state and must not be used.
+ </para>
+ <para>
+ If any of the configuration properties are modified then
+ <see cref="M:log4net.Appender.RemotingAppender.ActivateOptions"/> must be called again.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.RemotingAppender.SendBuffer(log4net.Core.LoggingEvent[])">
+ <summary>
+ Send the contents of the buffer to the remote sink.
+ </summary>
+ <remarks>
+ The events are not sent immediately. They are scheduled to be sent
+ using a pool thread. The effect is that the send occurs asynchronously.
+ This is very important for a number of non obvious reasons. The remoting
+ infrastructure will flow thread local variables (stored in the <see cref="T:System.Runtime.Remoting.Messaging.CallContext"/>),
+ if they are marked as <see cref="T:System.Runtime.Remoting.Messaging.ILogicalThreadAffinative"/>, across the
+ remoting boundary. If the server is not contactable then
+ the remoting infrastructure will clear the <see cref="T:System.Runtime.Remoting.Messaging.ILogicalThreadAffinative"/>
+ objects from the <see cref="T:System.Runtime.Remoting.Messaging.CallContext"/>. To prevent a logging failure from
+ having side effects on the calling application the remoting call must be made
+ from a separate thread to the one used by the application. A <see cref="T:System.Threading.ThreadPool"/>
+ thread is used for this. If no <see cref="T:System.Threading.ThreadPool"/> thread is available then
+ the events will block in the thread pool manager until a thread is available.
+ </remarks>
+ <param name="events">The events to send.</param>
+ </member>
+ <member name="M:log4net.Appender.RemotingAppender.OnClose">
+ <summary>
+ Override base class close.
+ </summary>
+ <remarks>
+ <para>
+ This method waits while there are queued work items. The events are
+ sent asynchronously using <see cref="T:System.Threading.ThreadPool"/> work items. These items
+ will be sent once a thread pool thread is available to send them, therefore
+ it is possible to close the appender before all the queued events have been
+ sent.</para>
+ <para>
+ This method attempts to wait until all the queued events have been sent, but this
+ method will timeout after 30 seconds regardless.</para>
+ <para>
+ If the appender is being closed because the <see cref="E:System.AppDomain.ProcessExit"/>
+ event has fired it may not be possible to send all the queued events. During process
+ exit the runtime limits the time that a <see cref="E:System.AppDomain.ProcessExit"/>
+ event handler is allowed to run for.</para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.RemotingAppender.BeginAsyncSend">
+ <summary>
+ A work item is being queued into the thread pool
+ </summary>
+ </member>
+ <member name="M:log4net.Appender.RemotingAppender.EndAsyncSend">
+ <summary>
+ A work item from the thread pool has completed
+ </summary>
+ </member>
+ <member name="M:log4net.Appender.RemotingAppender.SendBufferCallback(System.Object)">
+ <summary>
+ Send the contents of the buffer to the remote sink.
+ </summary>
+ <remarks>
+ This method is designed to be used with the <see cref="T:System.Threading.ThreadPool"/>.
+ This method expects to be passed an array of <see cref="T:log4net.Core.LoggingEvent"/>
+ objects in the state param.
+ </remarks>
+ <param name="state">the logging events to send</param>
+ </member>
+ <member name="F:log4net.Appender.RemotingAppender.m_sinkUrl">
+ <summary>
+ The URL of the remote sink.
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.RemotingAppender.m_sinkObj">
+ <summary>
+ The local proxy (.NET remoting) for the remote logging sink.
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.RemotingAppender.m_queuedCallbackCount">
+ <summary>
+ The number of queued callbacks currently waiting or executing
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.RemotingAppender.m_workQueueEmptyEvent">
+ <summary>
+ Event used to signal when there are no queued work items
+ </summary>
+ <remarks>
+ This event is set when there are no queued work items. In this
+ state it is safe to close the appender.
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.RemotingAppender.Sink">
+ <summary>
+ Gets or sets the URL of the well-known object that will accept
+ the logging events.
+ </summary>
+ <value>
+ The well-known URL of the remote sink.
+ </value>
+ <remarks>
+ <para>
+ The URL of the remoting sink that will accept logging events.
+ The sink must implement the <see cref="T:log4net.Appender.RemotingAppender.IRemoteLoggingSink"/>
+ interface.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Appender.RemotingAppender.IRemoteLoggingSink">
+ <summary>
+ Interface used to deliver <see cref="T:log4net.Core.LoggingEvent"/> objects to a remote sink.
+ </summary>
+ <remarks>
+ This interface must be implemented by a remoting sink
+ if the <see cref="T:log4net.Appender.RemotingAppender"/> is to be used
+ to deliver logging events to the sink.
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.RemotingAppender.IRemoteLoggingSink.LogEvents(log4net.Core.LoggingEvent[])">
+ <summary>
+ Delivers logging events to the remote sink
+ </summary>
+ <param name="events">Array of events to log.</param>
+ <remarks>
+ <para>
+ Delivers logging events to the remote sink
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Appender.RollingFileAppender">
+ <summary>
+ Appender that rolls log files based on size or date or both.
+ </summary>
+ <remarks>
+ <para>
+ RollingFileAppender can roll log files based on size or date or both
+ depending on the setting of the <see cref="P:log4net.Appender.RollingFileAppender.RollingStyle"/> property.
+ When set to <see cref="F:log4net.Appender.RollingFileAppender.RollingMode.Size"/> the log file will be rolled
+ once its size exceeds the <see cref="P:log4net.Appender.RollingFileAppender.MaximumFileSize"/>.
+ When set to <see cref="F:log4net.Appender.RollingFileAppender.RollingMode.Date"/> the log file will be rolled
+ once the date boundary specified in the <see cref="P:log4net.Appender.RollingFileAppender.DatePattern"/> property
+ is crossed.
+ When set to <see cref="F:log4net.Appender.RollingFileAppender.RollingMode.Composite"/> the log file will be
+ rolled once the date boundary specified in the <see cref="P:log4net.Appender.RollingFileAppender.DatePattern"/> property
+ is crossed, but within a date boundary the file will also be rolled
+ once its size exceeds the <see cref="P:log4net.Appender.RollingFileAppender.MaximumFileSize"/>.
+ When set to <see cref="F:log4net.Appender.RollingFileAppender.RollingMode.Once"/> the log file will be rolled when
+ the appender is configured. This effectively means that the log file can be
+ rolled once per program execution.
+ </para>
+ <para>
+ A of few additional optional features have been added:
+ <list type="bullet">
+ <item>Attach date pattern for current log file <see cref="P:log4net.Appender.RollingFileAppender.StaticLogFileName"/></item>
+ <item>Backup number increments for newer files <see cref="P:log4net.Appender.RollingFileAppender.CountDirection"/></item>
+ <item>Infinite number of backups by file size <see cref="P:log4net.Appender.RollingFileAppender.MaxSizeRollBackups"/></item>
+ </list>
+ </para>
+
+ <note>
+ <para>
+ For large or infinite numbers of backup files a <see cref="P:log4net.Appender.RollingFileAppender.CountDirection"/>
+ greater than zero is highly recommended, otherwise all the backup files need
+ to be renamed each time a new backup is created.
+ </para>
+ <para>
+ When Date/Time based rolling is used setting <see cref="P:log4net.Appender.RollingFileAppender.StaticLogFileName"/>
+ to <see langword="true"/> will reduce the number of file renamings to few or none.
+ </para>
+ </note>
+
+ <note type="caution">
+ <para>
+ Changing <see cref="P:log4net.Appender.RollingFileAppender.StaticLogFileName"/> or <see cref="P:log4net.Appender.RollingFileAppender.CountDirection"/> without clearing
+ the log file directory of backup files will cause unexpected and unwanted side effects.
+ </para>
+ </note>
+
+ <para>
+ If Date/Time based rolling is enabled this appender will attempt to roll existing files
+ in the directory without a Date/Time tag based on the last write date of the base log file.
+ The appender only rolls the log file when a message is logged. If Date/Time based rolling
+ is enabled then the appender will not roll the log file at the Date/Time boundary but
+ at the point when the next message is logged after the boundary has been crossed.
+ </para>
+
+ <para>
+ The <see cref="T:log4net.Appender.RollingFileAppender"/> extends the <see cref="T:log4net.Appender.FileAppender"/> and
+ has the same behavior when opening the log file.
+ The appender will first try to open the file for writing when <see cref="M:log4net.Appender.RollingFileAppender.ActivateOptions"/>
+ is called. This will typically be during configuration.
+ If the file cannot be opened for writing the appender will attempt
+ to open the file again each time a message is logged to the appender.
+ If the file cannot be opened for writing when a message is logged then
+ the message will be discarded by this appender.
+ </para>
+ <para>
+ When rolling a backup file necessitates deleting an older backup file the
+ file to be deleted is moved to a temporary name before being deleted.
+ </para>
+
+ <note type="caution">
+ <para>
+ A maximum number of backup files when rolling on date/time boundaries is not supported.
+ </para>
+ </note>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ <author>Aspi Havewala</author>
+ <author>Douglas de la Torre</author>
+ <author>Edward Smit</author>
+ </member>
+ <member name="M:log4net.Appender.RollingFileAppender.#ctor">
+ <summary>
+ Initializes a new instance of the <see cref="T:log4net.Appender.RollingFileAppender"/> class.
+ </summary>
+ <remarks>
+ <para>
+ Default constructor.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.RollingFileAppender.SetQWForFiles(System.IO.TextWriter)">
+ <summary>
+ Sets the quiet writer being used.
+ </summary>
+ <remarks>
+ This method can be overridden by sub classes.
+ </remarks>
+ <param name="writer">the writer to set</param>
+ </member>
+ <member name="M:log4net.Appender.RollingFileAppender.Append(log4net.Core.LoggingEvent)">
+ <summary>
+ Write out a logging event.
+ </summary>
+ <param name="loggingEvent">the event to write to file.</param>
+ <remarks>
+ <para>
+ Handles append time behavior for RollingFileAppender. This checks
+ if a roll over either by date (checked first) or time (checked second)
+ is need and then appends to the file last.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.RollingFileAppender.Append(log4net.Core.LoggingEvent[])">
+ <summary>
+ Write out an array of logging events.
+ </summary>
+ <param name="loggingEvents">the events to write to file.</param>
+ <remarks>
+ <para>
+ Handles append time behavior for RollingFileAppender. This checks
+ if a roll over either by date (checked first) or time (checked second)
+ is need and then appends to the file last.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.RollingFileAppender.AdjustFileBeforeAppend">
+ <summary>
+ Performs any required rolling before outputting the next event
+ </summary>
+ <remarks>
+ <para>
+ Handles append time behavior for RollingFileAppender. This checks
+ if a roll over either by date (checked first) or time (checked second)
+ is need and then appends to the file last.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.RollingFileAppender.OpenFile(System.String,System.Boolean)">
+ <summary>
+ Creates and opens the file for logging. If <see cref="P:log4net.Appender.RollingFileAppender.StaticLogFileName"/>
+ is false then the fully qualified name is determined and used.
+ </summary>
+ <param name="fileName">the name of the file to open</param>
+ <param name="append">true to append to existing file</param>
+ <remarks>
+ <para>This method will ensure that the directory structure
+ for the <paramref name="fileName"/> specified exists.</para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.RollingFileAppender.GetNextOutputFileName(System.String)">
+ <summary>
+ Get the current output file name
+ </summary>
+ <param name="fileName">the base file name</param>
+ <returns>the output file name</returns>
+ <remarks>
+ The output file name is based on the base fileName specified.
+ If <see cref="P:log4net.Appender.RollingFileAppender.StaticLogFileName"/> is set then the output
+ file name is the same as the base file passed in. Otherwise
+ the output file depends on the date pattern, on the count
+ direction or both.
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.RollingFileAppender.DetermineCurSizeRollBackups">
+ <summary>
+ Determines curSizeRollBackups (only within the current roll point)
+ </summary>
+ </member>
+ <member name="M:log4net.Appender.RollingFileAppender.GetWildcardPatternForFile(System.String)">
+ <summary>
+ Generates a wildcard pattern that can be used to find all files
+ that are similar to the base file name.
+ </summary>
+ <param name="baseFileName"></param>
+ <returns></returns>
+ </member>
+ <member name="M:log4net.Appender.RollingFileAppender.GetExistingFiles(System.String)">
+ <summary>
+ Builds a list of filenames for all files matching the base filename plus a file
+ pattern.
+ </summary>
+ <param name="baseFilePath"></param>
+ <returns></returns>
+ </member>
+ <member name="M:log4net.Appender.RollingFileAppender.RollOverIfDateBoundaryCrossing">
+ <summary>
+ Initiates a roll over if needed for crossing a date boundary since the last run.
+ </summary>
+ </member>
+ <member name="M:log4net.Appender.RollingFileAppender.ExistingInit">
+ <summary>
+ Initializes based on existing conditions at time of <see cref="M:log4net.Appender.RollingFileAppender.ActivateOptions"/>.
+ </summary>
+ <remarks>
+ <para>
+ Initializes based on existing conditions at time of <see cref="M:log4net.Appender.RollingFileAppender.ActivateOptions"/>.
+ The following is done
+ <list type="bullet">
+ <item>determine curSizeRollBackups (only within the current roll point)</item>
+ <item>initiates a roll over if needed for crossing a date boundary since the last run.</item>
+ </list>
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.RollingFileAppender.InitializeFromOneFile(System.String,System.String)">
+ <summary>
+ Does the work of bumping the 'current' file counter higher
+ to the highest count when an incremental file name is seen.
+ The highest count is either the first file (when count direction
+ is greater than 0) or the last file (when count direction less than 0).
+ In either case, we want to know the highest count that is present.
+ </summary>
+ <param name="baseFile"></param>
+ <param name="curFileName"></param>
+ </member>
+ <member name="M:log4net.Appender.RollingFileAppender.InitializeRollBackups(System.String,System.Collections.ArrayList)">
+ <summary>
+ Takes a list of files and a base file name, and looks for
+ 'incremented' versions of the base file. Bumps the max
+ count up to the highest count seen.
+ </summary>
+ <param name="baseFile"></param>
+ <param name="arrayFiles"></param>
+ </member>
+ <member name="M:log4net.Appender.RollingFileAppender.ComputeCheckPeriod(System.String)">
+ <summary>
+ Calculates the RollPoint for the datePattern supplied.
+ </summary>
+ <param name="datePattern">the date pattern to calculate the check period for</param>
+ <returns>The RollPoint that is most accurate for the date pattern supplied</returns>
+ <remarks>
+ Essentially the date pattern is examined to determine what the
+ most suitable roll point is. The roll point chosen is the roll point
+ with the smallest period that can be detected using the date pattern
+ supplied. i.e. if the date pattern only outputs the year, month, day
+ and hour then the smallest roll point that can be detected would be
+ and hourly roll point as minutes could not be detected.
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.RollingFileAppender.ActivateOptions">
+ <summary>
+ Initialize the appender based on the options set
+ </summary>
+ <remarks>
+ <para>
+ This is part of the <see cref="T:log4net.Core.IOptionHandler"/> delayed object
+ activation scheme. The <see cref="M:log4net.Appender.RollingFileAppender.ActivateOptions"/> method must
+ be called on this object after the configuration properties have
+ been set. Until <see cref="M:log4net.Appender.RollingFileAppender.ActivateOptions"/> is called this
+ object is in an undefined state and must not be used.
+ </para>
+ <para>
+ If any of the configuration properties are modified then
+ <see cref="M:log4net.Appender.RollingFileAppender.ActivateOptions"/> must be called again.
+ </para>
+ <para>
+ Sets initial conditions including date/time roll over information, first check,
+ scheduledFilename, and calls <see cref="M:log4net.Appender.RollingFileAppender.ExistingInit"/> to initialize
+ the current number of backups.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.RollingFileAppender.RollOverTime(System.Boolean)">
+ <summary>
+ Rollover the file(s) to date/time tagged file(s).
+ </summary>
+ <param name="fileIsOpen">set to true if the file to be rolled is currently open</param>
+ <remarks>
+ <para>
+ Rollover the file(s) to date/time tagged file(s).
+ Resets curSizeRollBackups.
+ If fileIsOpen is set then the new file is opened (through SafeOpenFile).
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.RollingFileAppender.RollFile(System.String,System.String)">
+ <summary>
+ Renames file <paramref name="fromFile"/> to file <paramref name="toFile"/>.
+ </summary>
+ <param name="fromFile">Name of existing file to roll.</param>
+ <param name="toFile">New name for file.</param>
+ <remarks>
+ <para>
+ Renames file <paramref name="fromFile"/> to file <paramref name="toFile"/>. It
+ also checks for existence of target file and deletes if it does.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.RollingFileAppender.FileExists(System.String)">
+ <summary>
+ Test if a file exists at a specified path
+ </summary>
+ <param name="path">the path to the file</param>
+ <returns>true if the file exists</returns>
+ <remarks>
+ <para>
+ Test if a file exists at a specified path
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.RollingFileAppender.DeleteFile(System.String)">
+ <summary>
+ Deletes the specified file if it exists.
+ </summary>
+ <param name="fileName">The file to delete.</param>
+ <remarks>
+ <para>
+ Delete a file if is exists.
+ The file is first moved to a new filename then deleted.
+ This allows the file to be removed even when it cannot
+ be deleted, but it still can be moved.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.RollingFileAppender.RollOverSize">
+ <summary>
+ Implements file roll base on file size.
+ </summary>
+ <remarks>
+ <para>
+ If the maximum number of size based backups is reached
+ (<c>curSizeRollBackups == maxSizeRollBackups</c>) then the oldest
+ file is deleted -- its index determined by the sign of countDirection.
+ If <c>countDirection</c> &lt; 0, then files
+ {<c>File.1</c>, ..., <c>File.curSizeRollBackups -1</c>}
+ are renamed to {<c>File.2</c>, ...,
+ <c>File.curSizeRollBackups</c>}. Moreover, <c>File</c> is
+ renamed <c>File.1</c> and closed.
+ </para>
+ <para>
+ A new file is created to receive further log output.
+ </para>
+ <para>
+ If <c>maxSizeRollBackups</c> is equal to zero, then the
+ <c>File</c> is truncated with no backup files created.
+ </para>
+ <para>
+ If <c>maxSizeRollBackups</c> &lt; 0, then <c>File</c> is
+ renamed if needed and no files are deleted.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.RollingFileAppender.RollOverRenameFiles(System.String)">
+ <summary>
+ Implements file roll.
+ </summary>
+ <param name="baseFileName">the base name to rename</param>
+ <remarks>
+ <para>
+ If the maximum number of size based backups is reached
+ (<c>curSizeRollBackups == maxSizeRollBackups</c>) then the oldest
+ file is deleted -- its index determined by the sign of countDirection.
+ If <c>countDirection</c> &lt; 0, then files
+ {<c>File.1</c>, ..., <c>File.curSizeRollBackups -1</c>}
+ are renamed to {<c>File.2</c>, ...,
+ <c>File.curSizeRollBackups</c>}.
+ </para>
+ <para>
+ If <c>maxSizeRollBackups</c> is equal to zero, then the
+ <c>File</c> is truncated with no backup files created.
+ </para>
+ <para>
+ If <c>maxSizeRollBackups</c> &lt; 0, then <c>File</c> is
+ renamed if needed and no files are deleted.
+ </para>
+ <para>
+ This is called by <see cref="M:log4net.Appender.RollingFileAppender.RollOverSize"/> to rename the files.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.RollingFileAppender.NextCheckDate(System.DateTime,log4net.Appender.RollingFileAppender.RollPoint)">
+ <summary>
+ Get the start time of the next window for the current rollpoint
+ </summary>
+ <param name="currentDateTime">the current date</param>
+ <param name="rollPoint">the type of roll point we are working with</param>
+ <returns>the start time for the next roll point an interval after the currentDateTime date</returns>
+ <remarks>
+ <para>
+ Returns the date of the next roll point after the currentDateTime date passed to the method.
+ </para>
+ <para>
+ The basic strategy is to subtract the time parts that are less significant
+ than the rollpoint from the current time. This should roll the time back to
+ the start of the time window for the current rollpoint. Then we add 1 window
+ worth of time and get the start time of the next window for the rollpoint.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Appender.RollingFileAppender.m_dateTime">
+ <summary>
+ This object supplies the current date/time. Allows test code to plug in
+ a method to control this class when testing date/time based rolling.
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.RollingFileAppender.m_datePattern">
+ <summary>
+ The date pattern. By default, the pattern is set to <c>".yyyy-MM-dd"</c>
+ meaning daily rollover.
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.RollingFileAppender.m_scheduledFilename">
+ <summary>
+ The actual formatted filename that is currently being written to
+ or will be the file transferred to on roll over
+ (based on staticLogFileName).
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.RollingFileAppender.m_nextCheck">
+ <summary>
+ The timestamp when we shall next recompute the filename.
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.RollingFileAppender.m_now">
+ <summary>
+ Holds date of last roll over
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.RollingFileAppender.m_rollPoint">
+ <summary>
+ The type of rolling done
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.RollingFileAppender.m_maxFileSize">
+ <summary>
+ The default maximum file size is 10MB
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.RollingFileAppender.m_maxSizeRollBackups">
+ <summary>
+ There is zero backup files by default
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.RollingFileAppender.m_curSizeRollBackups">
+ <summary>
+ How many sized based backups have been made so far
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.RollingFileAppender.m_countDirection">
+ <summary>
+ The rolling file count direction.
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.RollingFileAppender.m_rollingStyle">
+ <summary>
+ The rolling mode used in this appender.
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.RollingFileAppender.m_rollDate">
+ <summary>
+ Cache flag set if we are rolling by date.
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.RollingFileAppender.m_rollSize">
+ <summary>
+ Cache flag set if we are rolling by size.
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.RollingFileAppender.m_staticLogFileName">
+ <summary>
+ Value indicating whether to always log to the same file.
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.RollingFileAppender.m_baseFileName">
+ <summary>
+ FileName provided in configuration. Used for rolling properly
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.RollingFileAppender.s_date1970">
+ <summary>
+ The 1st of January 1970 in UTC
+ </summary>
+ </member>
+ <member name="P:log4net.Appender.RollingFileAppender.DatePattern">
+ <summary>
+ Gets or sets the date pattern to be used for generating file names
+ when rolling over on date.
+ </summary>
+ <value>
+ The date pattern to be used for generating file names when rolling
+ over on date.
+ </value>
+ <remarks>
+ <para>
+ Takes a string in the same format as expected by
+ <see cref="T:log4net.DateFormatter.SimpleDateFormatter"/>.
+ </para>
+ <para>
+ This property determines the rollover schedule when rolling over
+ on date.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.RollingFileAppender.MaxSizeRollBackups">
+ <summary>
+ Gets or sets the maximum number of backup files that are kept before
+ the oldest is erased.
+ </summary>
+ <value>
+ The maximum number of backup files that are kept before the oldest is
+ erased.
+ </value>
+ <remarks>
+ <para>
+ If set to zero, then there will be no backup files and the log file
+ will be truncated when it reaches <see cref="P:log4net.Appender.RollingFileAppender.MaxFileSize"/>.
+ </para>
+ <para>
+ If a negative number is supplied then no deletions will be made. Note
+ that this could result in very slow performance as a large number of
+ files are rolled over unless <see cref="P:log4net.Appender.RollingFileAppender.CountDirection"/> is used.
+ </para>
+ <para>
+ The maximum applies to <b>each</b> time based group of files and
+ <b>not</b> the total.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.RollingFileAppender.MaxFileSize">
+ <summary>
+ Gets or sets the maximum size that the output file is allowed to reach
+ before being rolled over to backup files.
+ </summary>
+ <value>
+ The maximum size in bytes that the output file is allowed to reach before being
+ rolled over to backup files.
+ </value>
+ <remarks>
+ <para>
+ This property is equivalent to <see cref="P:log4net.Appender.RollingFileAppender.MaximumFileSize"/> except
+ that it is required for differentiating the setter taking a
+ <see cref="T:System.Int64"/> argument from the setter taking a <see cref="T:System.String"/>
+ argument.
+ </para>
+ <para>
+ The default maximum file size is 10MB (10*1024*1024).
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.RollingFileAppender.MaximumFileSize">
+ <summary>
+ Gets or sets the maximum size that the output file is allowed to reach
+ before being rolled over to backup files.
+ </summary>
+ <value>
+ The maximum size that the output file is allowed to reach before being
+ rolled over to backup files.
+ </value>
+ <remarks>
+ <para>
+ This property allows you to specify the maximum size with the
+ suffixes "KB", "MB" or "GB" so that the size is interpreted being
+ expressed respectively in kilobytes, megabytes or gigabytes.
+ </para>
+ <para>
+ For example, the value "10KB" will be interpreted as 10240 bytes.
+ </para>
+ <para>
+ The default maximum file size is 10MB.
+ </para>
+ <para>
+ If you have the option to set the maximum file size programmatically
+ consider using the <see cref="P:log4net.Appender.RollingFileAppender.MaxFileSize"/> property instead as this
+ allows you to set the size in bytes as a <see cref="T:System.Int64"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.RollingFileAppender.CountDirection">
+ <summary>
+ Gets or sets the rolling file count direction.
+ </summary>
+ <value>
+ The rolling file count direction.
+ </value>
+ <remarks>
+ <para>
+ Indicates if the current file is the lowest numbered file or the
+ highest numbered file.
+ </para>
+ <para>
+ By default newer files have lower numbers (<see cref="P:log4net.Appender.RollingFileAppender.CountDirection"/> &lt; 0),
+ i.e. log.1 is most recent, log.5 is the 5th backup, etc...
+ </para>
+ <para>
+ <see cref="P:log4net.Appender.RollingFileAppender.CountDirection"/> &gt;= 0 does the opposite i.e.
+ log.1 is the first backup made, log.5 is the 5th backup made, etc.
+ For infinite backups use <see cref="P:log4net.Appender.RollingFileAppender.CountDirection"/> &gt;= 0 to reduce
+ rollover costs.
+ </para>
+ <para>The default file count direction is -1.</para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.RollingFileAppender.RollingStyle">
+ <summary>
+ Gets or sets the rolling style.
+ </summary>
+ <value>The rolling style.</value>
+ <remarks>
+ <para>
+ The default rolling style is <see cref="F:log4net.Appender.RollingFileAppender.RollingMode.Composite"/>.
+ </para>
+ <para>
+ When set to <see cref="F:log4net.Appender.RollingFileAppender.RollingMode.Once"/> this appender's
+ <see cref="P:log4net.Appender.FileAppender.AppendToFile"/> property is set to <c>false</c>, otherwise
+ the appender would append to a single file rather than rolling
+ the file each time it is opened.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.RollingFileAppender.StaticLogFileName">
+ <summary>
+ Gets or sets a value indicating whether to always log to
+ the same file.
+ </summary>
+ <value>
+ <c>true</c> if always should be logged to the same file, otherwise <c>false</c>.
+ </value>
+ <remarks>
+ <para>
+ By default file.log is always the current file. Optionally
+ file.log.yyyy-mm-dd for current formatted datePattern can by the currently
+ logging file (or file.log.curSizeRollBackup or even
+ file.log.yyyy-mm-dd.curSizeRollBackup).
+ </para>
+ <para>
+ This will make time based rollovers with a large number of backups
+ much faster as the appender it won't have to rename all the backups!
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Appender.RollingFileAppender.RollingMode">
+ <summary>
+ Style of rolling to use
+ </summary>
+ <remarks>
+ <para>
+ Style of rolling to use
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Appender.RollingFileAppender.RollingMode.Once">
+ <summary>
+ Roll files once per program execution
+ </summary>
+ <remarks>
+ <para>
+ Roll files once per program execution.
+ Well really once each time this appender is
+ configured.
+ </para>
+ <para>
+ Setting this option also sets <c>AppendToFile</c> to
+ <c>false</c> on the <c>RollingFileAppender</c>, otherwise
+ this appender would just be a normal file appender.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Appender.RollingFileAppender.RollingMode.Size">
+ <summary>
+ Roll files based only on the size of the file
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.RollingFileAppender.RollingMode.Date">
+ <summary>
+ Roll files based only on the date
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.RollingFileAppender.RollingMode.Composite">
+ <summary>
+ Roll files based on both the size and date of the file
+ </summary>
+ </member>
+ <member name="T:log4net.Appender.RollingFileAppender.RollPoint">
+ <summary>
+ The code assumes that the following 'time' constants are in a increasing sequence.
+ </summary>
+ <remarks>
+ <para>
+ The code assumes that the following 'time' constants are in a increasing sequence.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Appender.RollingFileAppender.RollPoint.InvalidRollPoint">
+ <summary>
+ Roll the log not based on the date
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.RollingFileAppender.RollPoint.TopOfMinute">
+ <summary>
+ Roll the log for each minute
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.RollingFileAppender.RollPoint.TopOfHour">
+ <summary>
+ Roll the log for each hour
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.RollingFileAppender.RollPoint.HalfDay">
+ <summary>
+ Roll the log twice a day (midday and midnight)
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.RollingFileAppender.RollPoint.TopOfDay">
+ <summary>
+ Roll the log each day (midnight)
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.RollingFileAppender.RollPoint.TopOfWeek">
+ <summary>
+ Roll the log each week
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.RollingFileAppender.RollPoint.TopOfMonth">
+ <summary>
+ Roll the log each month
+ </summary>
+ </member>
+ <member name="T:log4net.Appender.RollingFileAppender.IDateTime">
+ <summary>
+ This interface is used to supply Date/Time information to the <see cref="T:log4net.Appender.RollingFileAppender"/>.
+ </summary>
+ <remarks>
+ This interface is used to supply Date/Time information to the <see cref="T:log4net.Appender.RollingFileAppender"/>.
+ Used primarily to allow test classes to plug themselves in so they can
+ supply test date/times.
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.RollingFileAppender.IDateTime.Now">
+ <summary>
+ Gets the <i>current</i> time.
+ </summary>
+ <value>The <i>current</i> time.</value>
+ <remarks>
+ <para>
+ Gets the <i>current</i> time.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Appender.RollingFileAppender.DefaultDateTime">
+ <summary>
+ Default implementation of <see cref="T:log4net.Appender.RollingFileAppender.IDateTime"/> that returns the current time.
+ </summary>
+ </member>
+ <member name="P:log4net.Appender.RollingFileAppender.DefaultDateTime.Now">
+ <summary>
+ Gets the <b>current</b> time.
+ </summary>
+ <value>The <b>current</b> time.</value>
+ <remarks>
+ <para>
+ Gets the <b>current</b> time.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Appender.SmtpAppender">
+ <summary>
+ Send an e-mail when a specific logging event occurs, typically on errors
+ or fatal errors.
+ </summary>
+ <remarks>
+ <para>
+ The number of logging events delivered in this e-mail depend on
+ the value of <see cref="P:log4net.Appender.BufferingAppenderSkeleton.BufferSize"/> option. The
+ <see cref="T:log4net.Appender.SmtpAppender"/> keeps only the last
+ <see cref="P:log4net.Appender.BufferingAppenderSkeleton.BufferSize"/> logging events in its
+ cyclic buffer. This keeps memory requirements at a reasonable level while
+ still delivering useful application context.
+ </para>
+ <note type="caution">
+ Authentication and setting the server Port are only available on the MS .NET 1.1 runtime.
+ For these features to be enabled you need to ensure that you are using a version of
+ the log4net assembly that is built against the MS .NET 1.1 framework and that you are
+ running the your application on the MS .NET 1.1 runtime. On all other platforms only sending
+ unauthenticated messages to a server listening on port 25 (the default) is supported.
+ </note>
+ <para>
+ Authentication is supported by setting the <see cref="P:log4net.Appender.SmtpAppender.Authentication"/> property to
+ either <see cref="F:log4net.Appender.SmtpAppender.SmtpAuthentication.Basic"/> or <see cref="F:log4net.Appender.SmtpAppender.SmtpAuthentication.Ntlm"/>.
+ If using <see cref="F:log4net.Appender.SmtpAppender.SmtpAuthentication.Basic"/> authentication then the <see cref="P:log4net.Appender.SmtpAppender.Username"/>
+ and <see cref="P:log4net.Appender.SmtpAppender.Password"/> properties must also be set.
+ </para>
+ <para>
+ To set the SMTP server port use the <see cref="P:log4net.Appender.SmtpAppender.Port"/> property. The default port is 25.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="M:log4net.Appender.SmtpAppender.#ctor">
+ <summary>
+ Default constructor
+ </summary>
+ <remarks>
+ <para>
+ Default constructor
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.SmtpAppender.SendBuffer(log4net.Core.LoggingEvent[])">
+ <summary>
+ Sends the contents of the cyclic buffer as an e-mail message.
+ </summary>
+ <param name="events">The logging events to send.</param>
+ </member>
+ <member name="M:log4net.Appender.SmtpAppender.SendEmail(System.String)">
+ <summary>
+ Send the email message
+ </summary>
+ <param name="messageBody">the body text to include in the mail</param>
+ </member>
+ <member name="P:log4net.Appender.SmtpAppender.To">
+ <summary>
+ Gets or sets a semicolon-delimited list of recipient e-mail addresses.
+ </summary>
+ <value>
+ A semicolon-delimited list of e-mail addresses.
+ </value>
+ <remarks>
+ <para>
+ A semicolon-delimited list of recipient e-mail addresses.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.SmtpAppender.From">
+ <summary>
+ Gets or sets the e-mail address of the sender.
+ </summary>
+ <value>
+ The e-mail address of the sender.
+ </value>
+ <remarks>
+ <para>
+ The e-mail address of the sender.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.SmtpAppender.Subject">
+ <summary>
+ Gets or sets the subject line of the e-mail message.
+ </summary>
+ <value>
+ The subject line of the e-mail message.
+ </value>
+ <remarks>
+ <para>
+ The subject line of the e-mail message.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.SmtpAppender.SmtpHost">
+ <summary>
+ Gets or sets the name of the SMTP relay mail server to use to send
+ the e-mail messages.
+ </summary>
+ <value>
+ The name of the e-mail relay server. If SmtpServer is not set, the
+ name of the local SMTP server is used.
+ </value>
+ <remarks>
+ <para>
+ The name of the e-mail relay server. If SmtpServer is not set, the
+ name of the local SMTP server is used.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.SmtpAppender.LocationInfo">
+ <summary>
+ Obsolete
+ </summary>
+ <remarks>
+ Use the BufferingAppenderSkeleton Fix methods instead
+ </remarks>
+ <remarks>
+ <para>
+ Obsolete property.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.SmtpAppender.Authentication">
+ <summary>
+ The mode to use to authentication with the SMTP server
+ </summary>
+ <remarks>
+ <note type="caution">Authentication is only available on the MS .NET 1.1 runtime.</note>
+ <para>
+ Valid Authentication mode values are: <see cref="F:log4net.Appender.SmtpAppender.SmtpAuthentication.None"/>,
+ <see cref="F:log4net.Appender.SmtpAppender.SmtpAuthentication.Basic"/>, and <see cref="F:log4net.Appender.SmtpAppender.SmtpAuthentication.Ntlm"/>.
+ The default value is <see cref="F:log4net.Appender.SmtpAppender.SmtpAuthentication.None"/>. When using
+ <see cref="F:log4net.Appender.SmtpAppender.SmtpAuthentication.Basic"/> you must specify the <see cref="P:log4net.Appender.SmtpAppender.Username"/>
+ and <see cref="P:log4net.Appender.SmtpAppender.Password"/> to use to authenticate.
+ When using <see cref="F:log4net.Appender.SmtpAppender.SmtpAuthentication.Ntlm"/> the Windows credentials for the current
+ thread, if impersonating, or the process will be used to authenticate.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.SmtpAppender.Username">
+ <summary>
+ The username to use to authenticate with the SMTP server
+ </summary>
+ <remarks>
+ <note type="caution">Authentication is only available on the MS .NET 1.1 runtime.</note>
+ <para>
+ A <see cref="P:log4net.Appender.SmtpAppender.Username"/> and <see cref="P:log4net.Appender.SmtpAppender.Password"/> must be specified when
+ <see cref="P:log4net.Appender.SmtpAppender.Authentication"/> is set to <see cref="F:log4net.Appender.SmtpAppender.SmtpAuthentication.Basic"/>,
+ otherwise the username will be ignored.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.SmtpAppender.Password">
+ <summary>
+ The password to use to authenticate with the SMTP server
+ </summary>
+ <remarks>
+ <note type="caution">Authentication is only available on the MS .NET 1.1 runtime.</note>
+ <para>
+ A <see cref="P:log4net.Appender.SmtpAppender.Username"/> and <see cref="P:log4net.Appender.SmtpAppender.Password"/> must be specified when
+ <see cref="P:log4net.Appender.SmtpAppender.Authentication"/> is set to <see cref="F:log4net.Appender.SmtpAppender.SmtpAuthentication.Basic"/>,
+ otherwise the password will be ignored.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.SmtpAppender.Port">
+ <summary>
+ The port on which the SMTP server is listening
+ </summary>
+ <remarks>
+ <note type="caution">Server Port is only available on the MS .NET 1.1 runtime.</note>
+ <para>
+ The port on which the SMTP server is listening. The default
+ port is <c>25</c>. The Port can only be changed when running on
+ the MS .NET 1.1 runtime.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.SmtpAppender.Priority">
+ <summary>
+ Gets or sets the priority of the e-mail message
+ </summary>
+ <value>
+ One of the <see cref="T:System.Web.Mail.MailPriority"/> values.
+ </value>
+ <remarks>
+ <para>
+ Sets the priority of the e-mails generated by this
+ appender. The default priority is <see cref="F:System.Web.Mail.MailPriority.Normal"/>.
+ </para>
+ <para>
+ If you are using this appender to report errors then
+ you may want to set the priority to <see cref="F:System.Web.Mail.MailPriority.High"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.SmtpAppender.RequiresLayout">
+ <summary>
+ This appender requires a <see cref="N:log4net.Layout"/> to be set.
+ </summary>
+ <value><c>true</c></value>
+ <remarks>
+ <para>
+ This appender requires a <see cref="N:log4net.Layout"/> to be set.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Appender.SmtpAppender.SmtpAuthentication">
+ <summary>
+ Values for the <see cref="P:log4net.Appender.SmtpAppender.Authentication"/> property.
+ </summary>
+ <remarks>
+ <para>
+ SMTP authentication modes.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Appender.SmtpAppender.SmtpAuthentication.None">
+ <summary>
+ No authentication
+ </summary>
+ </member>
+ <member name="F:log4net.Appender.SmtpAppender.SmtpAuthentication.Basic">
+ <summary>
+ Basic authentication.
+ </summary>
+ <remarks>
+ Requires a username and password to be supplied
+ </remarks>
+ </member>
+ <member name="F:log4net.Appender.SmtpAppender.SmtpAuthentication.Ntlm">
+ <summary>
+ Integrated authentication
+ </summary>
+ <remarks>
+ Uses the Windows credentials from the current thread or process to authenticate.
+ </remarks>
+ </member>
+ <member name="T:log4net.Appender.SmtpPickupDirAppender">
+ <summary>
+ Send an email when a specific logging event occurs, typically on errors
+ or fatal errors. Rather than sending via smtp it writes a file into the
+ directory specified by <see cref="P:log4net.Appender.SmtpPickupDirAppender.PickupDir"/>. This allows services such
+ as the IIS SMTP agent to manage sending the messages.
+ </summary>
+ <remarks>
+ <para>
+ The configuration for this appender is identical to that of the <c>SMTPAppender</c>,
+ except that instead of specifying the <c>SMTPAppender.SMTPHost</c> you specify
+ <see cref="P:log4net.Appender.SmtpPickupDirAppender.PickupDir"/>.
+ </para>
+ <para>
+ The number of logging events delivered in this e-mail depend on
+ the value of <see cref="P:log4net.Appender.BufferingAppenderSkeleton.BufferSize"/> option. The
+ <see cref="T:log4net.Appender.SmtpPickupDirAppender"/> keeps only the last
+ <see cref="P:log4net.Appender.BufferingAppenderSkeleton.BufferSize"/> logging events in its
+ cyclic buffer. This keeps memory requirements at a reasonable level while
+ still delivering useful application context.
+ </para>
+ </remarks>
+ <author>Niall Daley</author>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="M:log4net.Appender.SmtpPickupDirAppender.#ctor">
+ <summary>
+ Default constructor
+ </summary>
+ <remarks>
+ <para>
+ Default constructor
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.SmtpPickupDirAppender.SendBuffer(log4net.Core.LoggingEvent[])">
+ <summary>
+ Sends the contents of the cyclic buffer as an e-mail message.
+ </summary>
+ <param name="events">The logging events to send.</param>
+ <remarks>
+ <para>
+ Sends the contents of the cyclic buffer as an e-mail message.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.SmtpPickupDirAppender.ActivateOptions">
+ <summary>
+ Activate the options on this appender.
+ </summary>
+ <remarks>
+ <para>
+ This is part of the <see cref="T:log4net.Core.IOptionHandler"/> delayed object
+ activation scheme. The <see cref="M:log4net.Appender.SmtpPickupDirAppender.ActivateOptions"/> method must
+ be called on this object after the configuration properties have
+ been set. Until <see cref="M:log4net.Appender.SmtpPickupDirAppender.ActivateOptions"/> is called this
+ object is in an undefined state and must not be used.
+ </para>
+ <para>
+ If any of the configuration properties are modified then
+ <see cref="M:log4net.Appender.SmtpPickupDirAppender.ActivateOptions"/> must be called again.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.SmtpPickupDirAppender.ConvertToFullPath(System.String)">
+ <summary>
+ Convert a path into a fully qualified path.
+ </summary>
+ <param name="path">The path to convert.</param>
+ <returns>The fully qualified path.</returns>
+ <remarks>
+ <para>
+ Converts the path specified to a fully
+ qualified path. If the path is relative it is
+ taken as relative from the application base
+ directory.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Appender.SmtpPickupDirAppender.m_securityContext">
+ <summary>
+ The security context to use for privileged calls
+ </summary>
+ </member>
+ <member name="P:log4net.Appender.SmtpPickupDirAppender.To">
+ <summary>
+ Gets or sets a semicolon-delimited list of recipient e-mail addresses.
+ </summary>
+ <value>
+ A semicolon-delimited list of e-mail addresses.
+ </value>
+ <remarks>
+ <para>
+ A semicolon-delimited list of e-mail addresses.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.SmtpPickupDirAppender.From">
+ <summary>
+ Gets or sets the e-mail address of the sender.
+ </summary>
+ <value>
+ The e-mail address of the sender.
+ </value>
+ <remarks>
+ <para>
+ The e-mail address of the sender.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.SmtpPickupDirAppender.Subject">
+ <summary>
+ Gets or sets the subject line of the e-mail message.
+ </summary>
+ <value>
+ The subject line of the e-mail message.
+ </value>
+ <remarks>
+ <para>
+ The subject line of the e-mail message.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.SmtpPickupDirAppender.PickupDir">
+ <summary>
+ Gets or sets the path to write the messages to.
+ </summary>
+ <remarks>
+ <para>
+ Gets or sets the path to write the messages to. This should be the same
+ as that used by the agent sending the messages.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.SmtpPickupDirAppender.SecurityContext">
+ <summary>
+ Gets or sets the <see cref="P:log4net.Appender.SmtpPickupDirAppender.SecurityContext"/> used to write to the pickup directory.
+ </summary>
+ <value>
+ The <see cref="P:log4net.Appender.SmtpPickupDirAppender.SecurityContext"/> used to write to the pickup directory.
+ </value>
+ <remarks>
+ <para>
+ Unless a <see cref="P:log4net.Appender.SmtpPickupDirAppender.SecurityContext"/> specified here for this appender
+ the <see cref="P:log4net.Core.SecurityContextProvider.DefaultProvider"/> is queried for the
+ security context to use. The default behavior is to use the security context
+ of the current thread.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.SmtpPickupDirAppender.RequiresLayout">
+ <summary>
+ This appender requires a <see cref="N:log4net.Layout"/> to be set.
+ </summary>
+ <value><c>true</c></value>
+ <remarks>
+ <para>
+ This appender requires a <see cref="N:log4net.Layout"/> to be set.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Appender.TelnetAppender">
+ <summary>
+ Appender that allows clients to connect via Telnet to receive log messages
+ </summary>
+ <remarks>
+ <para>
+ The TelnetAppender accepts socket connections and streams logging messages
+ back to the client.
+ The output is provided in a telnet-friendly way so that a log can be monitored
+ over a TCP/IP socket.
+ This allows simple remote monitoring of application logging.
+ </para>
+ <para>
+ The default <see cref="P:log4net.Appender.TelnetAppender.Port"/> is 23 (the telnet port).
+ </para>
+ </remarks>
+ <author>Keith Long</author>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="M:log4net.Appender.TelnetAppender.#ctor">
+ <summary>
+ Default constructor
+ </summary>
+ <remarks>
+ <para>
+ Default constructor
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.TelnetAppender.OnClose">
+ <summary>
+ Overrides the parent method to close the socket handler
+ </summary>
+ <remarks>
+ <para>
+ Closes all the outstanding connections.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.TelnetAppender.ActivateOptions">
+ <summary>
+ Initialize the appender based on the options set.
+ </summary>
+ <remarks>
+ <para>
+ This is part of the <see cref="T:log4net.Core.IOptionHandler"/> delayed object
+ activation scheme. The <see cref="M:log4net.Appender.TelnetAppender.ActivateOptions"/> method must
+ be called on this object after the configuration properties have
+ been set. Until <see cref="M:log4net.Appender.TelnetAppender.ActivateOptions"/> is called this
+ object is in an undefined state and must not be used.
+ </para>
+ <para>
+ If any of the configuration properties are modified then
+ <see cref="M:log4net.Appender.TelnetAppender.ActivateOptions"/> must be called again.
+ </para>
+ <para>
+ Create the socket handler and wait for connections
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.TelnetAppender.Append(log4net.Core.LoggingEvent)">
+ <summary>
+ Writes the logging event to each connected client.
+ </summary>
+ <param name="loggingEvent">The event to log.</param>
+ <remarks>
+ <para>
+ Writes the logging event to each connected client.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.TelnetAppender.Port">
+ <summary>
+ Gets or sets the TCP port number on which this <see cref="T:log4net.Appender.TelnetAppender"/> will listen for connections.
+ </summary>
+ <value>
+ An integer value in the range <see cref="F:System.Net.IPEndPoint.MinPort"/> to <see cref="F:System.Net.IPEndPoint.MaxPort"/>
+ indicating the TCP port number on which this <see cref="T:log4net.Appender.TelnetAppender"/> will listen for connections.
+ </value>
+ <remarks>
+ <para>
+ The default value is 23 (the telnet port).
+ </para>
+ </remarks>
+ <exception cref="T:System.ArgumentOutOfRangeException">The value specified is less than <see cref="F:System.Net.IPEndPoint.MinPort"/>
+ or greater than <see cref="F:System.Net.IPEndPoint.MaxPort"/>.</exception>
+ </member>
+ <member name="P:log4net.Appender.TelnetAppender.RequiresLayout">
+ <summary>
+ This appender requires a <see cref="N:log4net.Layout"/> to be set.
+ </summary>
+ <value><c>true</c></value>
+ <remarks>
+ <para>
+ This appender requires a <see cref="N:log4net.Layout"/> to be set.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Appender.TelnetAppender.SocketHandler">
+ <summary>
+ Helper class to manage connected clients
+ </summary>
+ <remarks>
+ <para>
+ The SocketHandler class is used to accept connections from
+ clients. It is threaded so that clients can connect/disconnect
+ asynchronously.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.TelnetAppender.SocketHandler.#ctor(System.Int32)">
+ <summary>
+ Opens a new server port on <paramref ref="port"/>
+ </summary>
+ <param name="port">the local port to listen on for connections</param>
+ <remarks>
+ <para>
+ Creates a socket handler on the specified local server port.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.TelnetAppender.SocketHandler.Send(System.String)">
+ <summary>
+ Sends a string message to each of the connected clients
+ </summary>
+ <param name="message">the text to send</param>
+ <remarks>
+ <para>
+ Sends a string message to each of the connected clients
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.TelnetAppender.SocketHandler.AddClient(log4net.Appender.TelnetAppender.SocketHandler.SocketClient)">
+ <summary>
+ Add a client to the internal clients list
+ </summary>
+ <param name="client">client to add</param>
+ </member>
+ <member name="M:log4net.Appender.TelnetAppender.SocketHandler.RemoveClient(log4net.Appender.TelnetAppender.SocketHandler.SocketClient)">
+ <summary>
+ Remove a client from the internal clients list
+ </summary>
+ <param name="client">client to remove</param>
+ </member>
+ <member name="M:log4net.Appender.TelnetAppender.SocketHandler.OnConnect(System.IAsyncResult)">
+ <summary>
+ Callback used to accept a connection on the server socket
+ </summary>
+ <param name="asyncResult">The result of the asynchronous operation</param>
+ <remarks>
+ <para>
+ On connection adds to the list of connections
+ if there are two many open connections you will be disconnected
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.TelnetAppender.SocketHandler.Dispose">
+ <summary>
+ Close all network connections
+ </summary>
+ <remarks>
+ <para>
+ Make sure we close all network connections
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.TelnetAppender.SocketHandler.HasConnections">
+ <summary>
+ Test if this handler has active connections
+ </summary>
+ <value>
+ <c>true</c> if this handler has active connections
+ </value>
+ <remarks>
+ <para>
+ This property will be <c>true</c> while this handler has
+ active connections, that is at least one connection that
+ the handler will attempt to send a message to.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Appender.TelnetAppender.SocketHandler.SocketClient">
+ <summary>
+ Class that represents a client connected to this handler
+ </summary>
+ <remarks>
+ <para>
+ Class that represents a client connected to this handler
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.TelnetAppender.SocketHandler.SocketClient.#ctor(System.Net.Sockets.Socket)">
+ <summary>
+ Create this <see cref="T:log4net.Appender.TelnetAppender.SocketHandler.SocketClient"/> for the specified <see cref="T:System.Net.Sockets.Socket"/>
+ </summary>
+ <param name="socket">the client's socket</param>
+ <remarks>
+ <para>
+ Opens a stream writer on the socket.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.TelnetAppender.SocketHandler.SocketClient.Send(System.String)">
+ <summary>
+ Write a string to the client
+ </summary>
+ <param name="message">string to send</param>
+ <remarks>
+ <para>
+ Write a string to the client
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.TelnetAppender.SocketHandler.SocketClient.Dispose">
+ <summary>
+ Cleanup the clients connection
+ </summary>
+ <remarks>
+ <para>
+ Close the socket connection.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Appender.TraceAppender">
+ <summary>
+ Appends log events to the <see cref="T:System.Diagnostics.Trace"/> system.
+ </summary>
+ <remarks>
+ <para>
+ The application configuration file can be used to control what listeners
+ are actually used. See the MSDN documentation for the
+ <see cref="T:System.Diagnostics.Trace"/> class for details on configuring the
+ trace system.
+ </para>
+ <para>
+ Events are written using the <c>System.Diagnostics.Trace.Write(string,string)</c>
+ method. The event's logger name is passed as the value for the category name to the Write method.
+ </para>
+ <para>
+ <b>Compact Framework</b><br/>
+ The Compact Framework does not support the <see cref="T:System.Diagnostics.Trace"/>
+ class for any operation except <c>Assert</c>. When using the Compact Framework this
+ appender will write to the <see cref="T:System.Diagnostics.Debug"/> system rather than
+ the Trace system. This appender will therefore behave like the <see cref="T:log4net.Appender.DebugAppender"/>.
+ </para>
+ </remarks>
+ <author>Douglas de la Torre</author>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="M:log4net.Appender.TraceAppender.#ctor">
+ <summary>
+ Initializes a new instance of the <see cref="T:log4net.Appender.TraceAppender"/>.
+ </summary>
+ <remarks>
+ <para>
+ Default constructor.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.TraceAppender.#ctor(log4net.Layout.ILayout)">
+ <summary>
+ Initializes a new instance of the <see cref="T:log4net.Appender.TraceAppender"/>
+ with a specified layout.
+ </summary>
+ <param name="layout">The layout to use with this appender.</param>
+ <remarks>
+ <para>
+ Obsolete constructor.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Appender.TraceAppender.Append(log4net.Core.LoggingEvent)">
+ <summary>
+ Writes the logging event to the <see cref="T:System.Diagnostics.Trace"/> system.
+ </summary>
+ <param name="loggingEvent">The event to log.</param>
+ <remarks>
+ <para>
+ Writes the logging event to the <see cref="T:System.Diagnostics.Trace"/> system.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Appender.TraceAppender.m_immediateFlush">
+ <summary>
+ Immediate flush means that the underlying writer or output stream
+ will be flushed at the end of each append operation.
+ </summary>
+ <remarks>
+ <para>
+ Immediate flush is slower but ensures that each append request is
+ actually written. If <see cref="P:log4net.Appender.TraceAppender.ImmediateFlush"/> is set to
+ <c>false</c>, then there is a good chance that the last few
+ logs events are not actually written to persistent media if and
+ when the application crashes.
+ </para>
+ <para>
+ The default value is <c>true</c>.</para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.TraceAppender.ImmediateFlush">
+ <summary>
+ Gets or sets a value that indicates whether the appender will
+ flush at the end of each write.
+ </summary>
+ <remarks>
+ <para>The default behavior is to flush at the end of each
+ write. If the option is set to<c>false</c>, then the underlying
+ stream can defer writing to physical medium to a later time.
+ </para>
+ <para>
+ Avoiding the flush operation at the end of each append results
+ in a performance gain of 10 to 20 percent. However, there is safety
+ trade-off involved in skipping flushing. Indeed, when flushing is
+ skipped, then it is likely that the last few log events will not
+ be recorded on disk when the application exits. This is a high
+ price to pay even for a 20% performance gain.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Appender.TraceAppender.RequiresLayout">
+ <summary>
+ This appender requires a <see cref="N:log4net.Layout"/> to be set.
+ </summary>
+ <value><c>true</c></value>
+ <remarks>
+ <para>
+ This appender requires a <see cref="N:log4net.Layout"/> to be set.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Config.AliasDomainAttribute">
+ <summary>
+ Assembly level attribute that specifies a domain to alias to this assembly's repository.
+ </summary>
+ <remarks>
+ <para>
+ <b>AliasDomainAttribute is obsolete. Use AliasRepositoryAttribute instead of AliasDomainAttribute.</b>
+ </para>
+ <para>
+ An assembly's logger repository is defined by its <see cref="T:log4net.Config.DomainAttribute"/>,
+ however this can be overridden by an assembly loaded before the target assembly.
+ </para>
+ <para>
+ An assembly can alias another assembly's domain to its repository by
+ specifying this attribute with the name of the target domain.
+ </para>
+ <para>
+ This attribute can only be specified on the assembly and may be used
+ as many times as necessary to alias all the required domains.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="T:log4net.Config.AliasRepositoryAttribute">
+ <summary>
+ Assembly level attribute that specifies a repository to alias to this assembly's repository.
+ </summary>
+ <remarks>
+ <para>
+ An assembly's logger repository is defined by its <see cref="T:log4net.Config.RepositoryAttribute"/>,
+ however this can be overridden by an assembly loaded before the target assembly.
+ </para>
+ <para>
+ An assembly can alias another assembly's repository to its repository by
+ specifying this attribute with the name of the target repository.
+ </para>
+ <para>
+ This attribute can only be specified on the assembly and may be used
+ as many times as necessary to alias all the required repositories.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="M:log4net.Config.AliasRepositoryAttribute.#ctor(System.String)">
+ <summary>
+ Initializes a new instance of the <see cref="T:log4net.Config.AliasRepositoryAttribute"/> class with
+ the specified repository to alias to this assembly's repository.
+ </summary>
+ <param name="name">The repository to alias to this assemby's repository.</param>
+ <remarks>
+ <para>
+ Initializes a new instance of the <see cref="T:log4net.Config.AliasRepositoryAttribute"/> class with
+ the specified repository to alias to this assembly's repository.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Config.AliasRepositoryAttribute.Name">
+ <summary>
+ Gets or sets the repository to alias to this assemby's repository.
+ </summary>
+ <value>
+ The repository to alias to this assemby's repository.
+ </value>
+ <remarks>
+ <para>
+ The name of the repository to alias to this assemby's repository.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Config.AliasDomainAttribute.#ctor(System.String)">
+ <summary>
+ Initializes a new instance of the <see cref="T:log4net.Config.AliasDomainAttribute"/> class with
+ the specified domain to alias to this assembly's repository.
+ </summary>
+ <param name="name">The domain to alias to this assemby's repository.</param>
+ <remarks>
+ <para>
+ Obsolete. Use <see cref="T:log4net.Config.AliasRepositoryAttribute"/> instead of <see cref="T:log4net.Config.AliasDomainAttribute"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Config.BasicConfigurator">
+ <summary>
+ Use this class to quickly configure a <see cref="T:log4net.Repository.Hierarchy.Hierarchy"/>.
+ </summary>
+ <remarks>
+ <para>
+ Allows very simple programmatic configuration of log4net.
+ </para>
+ <para>
+ Only one appender can be configured using this configurator.
+ The appender is set at the root of the hierarchy and all logging
+ events will be delivered to that appender.
+ </para>
+ <para>
+ Appenders can also implement the <see cref="T:log4net.Core.IOptionHandler"/> interface. Therefore
+ they would require that the <see cref="M:log4net.Core.IOptionHandler.ActivateOptions"/> method
+ be called after the appenders properties have been configured.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="M:log4net.Config.BasicConfigurator.#ctor">
+ <summary>
+ Initializes a new instance of the <see cref="T:log4net.Config.BasicConfigurator"/> class.
+ </summary>
+ <remarks>
+ <para>
+ Uses a private access modifier to prevent instantiation of this class.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Config.BasicConfigurator.Configure">
+ <summary>
+ Initializes the log4net system with a default configuration.
+ </summary>
+ <remarks>
+ <para>
+ Initializes the log4net logging system using a <see cref="T:log4net.Appender.ConsoleAppender"/>
+ that will write to <c>Console.Out</c>. The log messages are
+ formatted using the <see cref="T:log4net.Layout.PatternLayout"/> layout object
+ with the <see cref="F:log4net.Layout.PatternLayout.DetailConversionPattern"/>
+ layout style.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Config.BasicConfigurator.Configure(log4net.Appender.IAppender)">
+ <summary>
+ Initializes the log4net system using the specified appender.
+ </summary>
+ <param name="appender">The appender to use to log all logging events.</param>
+ <remarks>
+ <para>
+ Initializes the log4net system using the specified appender.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Config.BasicConfigurator.Configure(log4net.Repository.ILoggerRepository)">
+ <summary>
+ Initializes the <see cref="T:log4net.Repository.ILoggerRepository"/> with a default configuration.
+ </summary>
+ <param name="repository">The repository to configure.</param>
+ <remarks>
+ <para>
+ Initializes the specified repository using a <see cref="T:log4net.Appender.ConsoleAppender"/>
+ that will write to <c>Console.Out</c>. The log messages are
+ formatted using the <see cref="T:log4net.Layout.PatternLayout"/> layout object
+ with the <see cref="F:log4net.Layout.PatternLayout.DetailConversionPattern"/>
+ layout style.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Config.BasicConfigurator.Configure(log4net.Repository.ILoggerRepository,log4net.Appender.IAppender)">
+ <summary>
+ Initializes the <see cref="T:log4net.Repository.ILoggerRepository"/> using the specified appender.
+ </summary>
+ <param name="repository">The repository to configure.</param>
+ <param name="appender">The appender to use to log all logging events.</param>
+ <remarks>
+ <para>
+ Initializes the <see cref="T:log4net.Repository.ILoggerRepository"/> using the specified appender.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Config.ConfiguratorAttribute">
+ <summary>
+ Base class for all log4net configuration attributes.
+ </summary>
+ <remarks>
+ This is an abstract class that must be extended by
+ specific configurators. This attribute allows the
+ configurator to be parameterized by an assembly level
+ attribute.
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="M:log4net.Config.ConfiguratorAttribute.#ctor(System.Int32)">
+ <summary>
+ Constructor used by subclasses.
+ </summary>
+ <param name="priority">the ordering priority for this configurator</param>
+ <remarks>
+ <para>
+ The <paramref name="priority"/> is used to order the configurator
+ attributes before they are invoked. Higher priority configurators are executed
+ before lower priority ones.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Config.ConfiguratorAttribute.Configure(System.Reflection.Assembly,log4net.Repository.ILoggerRepository)">
+ <summary>
+ Configures the <see cref="T:log4net.Repository.ILoggerRepository"/> for the specified assembly.
+ </summary>
+ <param name="sourceAssembly">The assembly that this attribute was defined on.</param>
+ <param name="targetRepository">The repository to configure.</param>
+ <remarks>
+ <para>
+ Abstract method implemented by a subclass. When this method is called
+ the subclass should configure the <paramref name="targetRepository"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Config.ConfiguratorAttribute.CompareTo(System.Object)">
+ <summary>
+ Compare this instance to another ConfiguratorAttribute
+ </summary>
+ <param name="obj">the object to compare to</param>
+ <returns>see <see cref="M:System.IComparable.CompareTo(System.Object)"/></returns>
+ <remarks>
+ <para>
+ Compares the priorities of the two <see cref="T:log4net.Config.ConfiguratorAttribute"/> instances.
+ Sorts by priority in descending order. Objects with the same priority are
+ randomly ordered.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Config.DomainAttribute">
+ <summary>
+ Assembly level attribute that specifies the logging domain for the assembly.
+ </summary>
+ <remarks>
+ <para>
+ <b>DomainAttribute is obsolete. Use RepositoryAttribute instead of DomainAttribute.</b>
+ </para>
+ <para>
+ Assemblies are mapped to logging domains. Each domain has its own
+ logging repository. This attribute specified on the assembly controls
+ the configuration of the domain. The <see cref="P:log4net.Config.RepositoryAttribute.Name"/> property specifies the name
+ of the domain that this assembly is a part of. The <see cref="P:log4net.Config.RepositoryAttribute.RepositoryType"/>
+ specifies the type of the repository objects to create for the domain. If
+ this attribute is not specified and a <see cref="P:log4net.Config.RepositoryAttribute.Name"/> is not specified
+ then the assembly will be part of the default shared logging domain.
+ </para>
+ <para>
+ This attribute can only be specified on the assembly and may only be used
+ once per assembly.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="T:log4net.Config.RepositoryAttribute">
+ <summary>
+ Assembly level attribute that specifies the logging repository for the assembly.
+ </summary>
+ <remarks>
+ <para>
+ Assemblies are mapped to logging repository. This attribute specified
+ on the assembly controls
+ the configuration of the repository. The <see cref="P:log4net.Config.RepositoryAttribute.Name"/> property specifies the name
+ of the repository that this assembly is a part of. The <see cref="P:log4net.Config.RepositoryAttribute.RepositoryType"/>
+ specifies the type of the <see cref="T:log4net.Repository.ILoggerRepository"/> object
+ to create for the assembly. If this attribute is not specified or a <see cref="P:log4net.Config.RepositoryAttribute.Name"/>
+ is not specified then the assembly will be part of the default shared logging repository.
+ </para>
+ <para>
+ This attribute can only be specified on the assembly and may only be used
+ once per assembly.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="M:log4net.Config.RepositoryAttribute.#ctor">
+ <summary>
+ Initializes a new instance of the <see cref="T:log4net.Config.RepositoryAttribute"/> class.
+ </summary>
+ <remarks>
+ <para>
+ Default constructor.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Config.RepositoryAttribute.#ctor(System.String)">
+ <summary>
+ Initialize a new instance of the <see cref="T:log4net.Config.RepositoryAttribute"/> class
+ with the name of the repository.
+ </summary>
+ <param name="name">The name of the repository.</param>
+ <remarks>
+ <para>
+ Initialize the attribute with the name for the assembly's repository.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Config.RepositoryAttribute.Name">
+ <summary>
+ Gets or sets the name of the logging repository.
+ </summary>
+ <value>
+ The string name to use as the name of the repository associated with this
+ assembly.
+ </value>
+ <remarks>
+ <para>
+ This value does not have to be unique. Several assemblies can share the
+ same repository. They will share the logging configuration of the repository.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Config.RepositoryAttribute.RepositoryType">
+ <summary>
+ Gets or sets the type of repository to create for this assembly.
+ </summary>
+ <value>
+ The type of repository to create for this assembly.
+ </value>
+ <remarks>
+ <para>
+ The type of the repository to create for the assembly.
+ The type must implement the <see cref="T:log4net.Repository.ILoggerRepository"/>
+ interface.
+ </para>
+ <para>
+ This will be the type of repository created when
+ the repository is created. If multiple assemblies reference the
+ same repository then the repository is only created once using the
+ <see cref="P:log4net.Config.RepositoryAttribute.RepositoryType"/> of the first assembly to call into the
+ repository.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Config.DomainAttribute.#ctor">
+ <summary>
+ Initializes a new instance of the <see cref="T:log4net.Config.DomainAttribute"/> class.
+ </summary>
+ <remarks>
+ <para>
+ Obsolete. Use RepositoryAttribute instead of DomainAttribute.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Config.DomainAttribute.#ctor(System.String)">
+ <summary>
+ Initialize a new instance of the <see cref="T:log4net.Config.DomainAttribute"/> class
+ with the name of the domain.
+ </summary>
+ <param name="name">The name of the domain.</param>
+ <remarks>
+ <para>
+ Obsolete. Use RepositoryAttribute instead of DomainAttribute.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Config.DOMConfigurator">
+ <summary>
+ Use this class to initialize the log4net environment using an Xml tree.
+ </summary>
+ <remarks>
+ <para>
+ <b>DOMConfigurator is obsolete. Use XmlConfigurator instead of DOMConfigurator.</b>
+ </para>
+ <para>
+ Configures a <see cref="T:log4net.Repository.ILoggerRepository"/> using an Xml tree.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="M:log4net.Config.DOMConfigurator.#ctor">
+ <summary>
+ Private constructor
+ </summary>
+ </member>
+ <member name="M:log4net.Config.DOMConfigurator.Configure">
+ <summary>
+ Automatically configures the log4net system based on the
+ application's configuration settings.
+ </summary>
+ <remarks>
+ <para>
+ <b>DOMConfigurator is obsolete. Use XmlConfigurator instead of DOMConfigurator.</b>
+ </para>
+ Each application has a configuration file. This has the
+ same name as the application with '.config' appended.
+ This file is XML and calling this function prompts the
+ configurator to look in that file for a section called
+ <c>log4net</c> that contains the configuration data.
+ </remarks>
+ </member>
+ <member name="M:log4net.Config.DOMConfigurator.Configure(log4net.Repository.ILoggerRepository)">
+ <summary>
+ Automatically configures the <see cref="T:log4net.Repository.ILoggerRepository"/> using settings
+ stored in the application's configuration file.
+ </summary>
+ <remarks>
+ <para>
+ <b>DOMConfigurator is obsolete. Use XmlConfigurator instead of DOMConfigurator.</b>
+ </para>
+ Each application has a configuration file. This has the
+ same name as the application with '.config' appended.
+ This file is XML and calling this function prompts the
+ configurator to look in that file for a section called
+ <c>log4net</c> that contains the configuration data.
+ </remarks>
+ <param name="repository">The repository to configure.</param>
+ </member>
+ <member name="M:log4net.Config.DOMConfigurator.Configure(System.Xml.XmlElement)">
+ <summary>
+ Configures log4net using a <c>log4net</c> element
+ </summary>
+ <remarks>
+ <para>
+ <b>DOMConfigurator is obsolete. Use XmlConfigurator instead of DOMConfigurator.</b>
+ </para>
+ Loads the log4net configuration from the XML element
+ supplied as <paramref name="element"/>.
+ </remarks>
+ <param name="element">The element to parse.</param>
+ </member>
+ <member name="M:log4net.Config.DOMConfigurator.Configure(log4net.Repository.ILoggerRepository,System.Xml.XmlElement)">
+ <summary>
+ Configures the <see cref="T:log4net.Repository.ILoggerRepository"/> using the specified XML
+ element.
+ </summary>
+ <remarks>
+ <para>
+ <b>DOMConfigurator is obsolete. Use XmlConfigurator instead of DOMConfigurator.</b>
+ </para>
+ Loads the log4net configuration from the XML element
+ supplied as <paramref name="element"/>.
+ </remarks>
+ <param name="repository">The repository to configure.</param>
+ <param name="element">The element to parse.</param>
+ </member>
+ <member name="M:log4net.Config.DOMConfigurator.Configure(System.IO.FileInfo)">
+ <summary>
+ Configures log4net using the specified configuration file.
+ </summary>
+ <param name="configFile">The XML file to load the configuration from.</param>
+ <remarks>
+ <para>
+ <b>DOMConfigurator is obsolete. Use XmlConfigurator instead of DOMConfigurator.</b>
+ </para>
+ <para>
+ The configuration file must be valid XML. It must contain
+ at least one element called <c>log4net</c> that holds
+ the log4net configuration data.
+ </para>
+ <para>
+ The log4net configuration file can possible be specified in the application's
+ configuration file (either <c>MyAppName.exe.config</c> for a
+ normal application on <c>Web.config</c> for an ASP.NET application).
+ </para>
+ <example>
+ The following example configures log4net using a configuration file, of which the
+ location is stored in the application's configuration file :
+ </example>
+ <code lang="C#">
+ using log4net.Config;
+ using System.IO;
+ using System.Configuration;
+
+ ...
+
+ DOMConfigurator.Configure(new FileInfo(ConfigurationSettings.AppSettings["log4net-config-file"]));
+ </code>
+ <para>
+ In the <c>.config</c> file, the path to the log4net can be specified like this :
+ </para>
+ <code lang="XML" escaped="true">
+ <configuration>
+ <appSettings>
+ <add key="log4net-config-file" value="log.config"/>
+ </appSettings>
+ </configuration>
+ </code>
+ </remarks>
+ </member>
+ <member name="M:log4net.Config.DOMConfigurator.Configure(System.IO.Stream)">
+ <summary>
+ Configures log4net using the specified configuration file.
+ </summary>
+ <param name="configStream">A stream to load the XML configuration from.</param>
+ <remarks>
+ <para>
+ <b>DOMConfigurator is obsolete. Use XmlConfigurator instead of DOMConfigurator.</b>
+ </para>
+ <para>
+ The configuration data must be valid XML. It must contain
+ at least one element called <c>log4net</c> that holds
+ the log4net configuration data.
+ </para>
+ <para>
+ Note that this method will NOT close the stream parameter.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Config.DOMConfigurator.Configure(log4net.Repository.ILoggerRepository,System.IO.FileInfo)">
+ <summary>
+ Configures the <see cref="T:log4net.Repository.ILoggerRepository"/> using the specified configuration
+ file.
+ </summary>
+ <param name="repository">The repository to configure.</param>
+ <param name="configFile">The XML file to load the configuration from.</param>
+ <remarks>
+ <para>
+ <b>DOMConfigurator is obsolete. Use XmlConfigurator instead of DOMConfigurator.</b>
+ </para>
+ <para>
+ The configuration file must be valid XML. It must contain
+ at least one element called <c>log4net</c> that holds
+ the configuration data.
+ </para>
+ <para>
+ The log4net configuration file can possible be specified in the application's
+ configuration file (either <c>MyAppName.exe.config</c> for a
+ normal application on <c>Web.config</c> for an ASP.NET application).
+ </para>
+ <example>
+ The following example configures log4net using a configuration file, of which the
+ location is stored in the application's configuration file :
+ </example>
+ <code lang="C#">
+ using log4net.Config;
+ using System.IO;
+ using System.Configuration;
+
+ ...
+
+ DOMConfigurator.Configure(new FileInfo(ConfigurationSettings.AppSettings["log4net-config-file"]));
+ </code>
+ <para>
+ In the <c>.config</c> file, the path to the log4net can be specified like this :
+ </para>
+ <code lang="XML" escaped="true">
+ <configuration>
+ <appSettings>
+ <add key="log4net-config-file" value="log.config"/>
+ </appSettings>
+ </configuration>
+ </code>
+ </remarks>
+ </member>
+ <member name="M:log4net.Config.DOMConfigurator.Configure(log4net.Repository.ILoggerRepository,System.IO.Stream)">
+ <summary>
+ Configures the <see cref="T:log4net.Repository.ILoggerRepository"/> using the specified configuration
+ file.
+ </summary>
+ <param name="repository">The repository to configure.</param>
+ <param name="configStream">The stream to load the XML configuration from.</param>
+ <remarks>
+ <para>
+ <b>DOMConfigurator is obsolete. Use XmlConfigurator instead of DOMConfigurator.</b>
+ </para>
+ <para>
+ The configuration data must be valid XML. It must contain
+ at least one element called <c>log4net</c> that holds
+ the configuration data.
+ </para>
+ <para>
+ Note that this method will NOT close the stream parameter.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Config.DOMConfigurator.ConfigureAndWatch(System.IO.FileInfo)">
+ <summary>
+ Configures log4net using the file specified, monitors the file for changes
+ and reloads the configuration if a change is detected.
+ </summary>
+ <param name="configFile">The XML file to load the configuration from.</param>
+ <remarks>
+ <para>
+ <b>DOMConfigurator is obsolete. Use XmlConfigurator instead of DOMConfigurator.</b>
+ </para>
+ <para>
+ The configuration file must be valid XML. It must contain
+ at least one element called <c>log4net</c> that holds
+ the configuration data.
+ </para>
+ <para>
+ The configuration file will be monitored using a <see cref="T:System.IO.FileSystemWatcher"/>
+ and depends on the behavior of that class.
+ </para>
+ <para>
+ For more information on how to configure log4net using
+ a separate configuration file, see <see cref="M:log4net.Config.DOMConfigurator.Configure(System.IO.FileInfo)"/>.
+ </para>
+ </remarks>
+ <seealso cref="M:log4net.Config.DOMConfigurator.Configure(System.IO.FileInfo)"/>
+ </member>
+ <member name="M:log4net.Config.DOMConfigurator.ConfigureAndWatch(log4net.Repository.ILoggerRepository,System.IO.FileInfo)">
+ <summary>
+ Configures the <see cref="T:log4net.Repository.ILoggerRepository"/> using the file specified,
+ monitors the file for changes and reloads the configuration if a change
+ is detected.
+ </summary>
+ <param name="repository">The repository to configure.</param>
+ <param name="configFile">The XML file to load the configuration from.</param>
+ <remarks>
+ <para>
+ <b>DOMConfigurator is obsolete. Use XmlConfigurator instead of DOMConfigurator.</b>
+ </para>
+ <para>
+ The configuration file must be valid XML. It must contain
+ at least one element called <c>log4net</c> that holds
+ the configuration data.
+ </para>
+ <para>
+ The configuration file will be monitored using a <see cref="T:System.IO.FileSystemWatcher"/>
+ and depends on the behavior of that class.
+ </para>
+ <para>
+ For more information on how to configure log4net using
+ a separate configuration file, see <see cref="M:log4net.Config.DOMConfigurator.Configure(System.IO.FileInfo)"/>.
+ </para>
+ </remarks>
+ <seealso cref="M:log4net.Config.DOMConfigurator.Configure(System.IO.FileInfo)"/>
+ </member>
+ <member name="T:log4net.Config.DOMConfiguratorAttribute">
+ <summary>
+ Assembly level attribute to configure the <see cref="T:log4net.Config.XmlConfigurator"/>.
+ </summary>
+ <remarks>
+ <para>
+ <b>AliasDomainAttribute is obsolete. Use AliasRepositoryAttribute instead of AliasDomainAttribute.</b>
+ </para>
+ <para>
+ This attribute may only be used at the assembly scope and can only
+ be used once per assembly.
+ </para>
+ <para>
+ Use this attribute to configure the <see cref="T:log4net.Config.XmlConfigurator"/>
+ without calling one of the <see cref="M:log4net.Config.XmlConfigurator.Configure"/>
+ methods.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="T:log4net.Config.XmlConfiguratorAttribute">
+ <summary>
+ Assembly level attribute to configure the <see cref="T:log4net.Config.XmlConfigurator"/>.
+ </summary>
+ <remarks>
+ <para>
+ This attribute may only be used at the assembly scope and can only
+ be used once per assembly.
+ </para>
+ <para>
+ Use this attribute to configure the <see cref="T:log4net.Config.XmlConfigurator"/>
+ without calling one of the <see cref="M:log4net.Config.XmlConfigurator.Configure"/>
+ methods.
+ </para>
+ <para>
+ If neither of the <see cref="P:log4net.Config.XmlConfiguratorAttribute.ConfigFile"/> or <see cref="P:log4net.Config.XmlConfiguratorAttribute.ConfigFileExtension"/>
+ properties are set the configuration is loaded from the application's .config file.
+ If set the <see cref="P:log4net.Config.XmlConfiguratorAttribute.ConfigFile"/> property takes priority over the
+ <see cref="P:log4net.Config.XmlConfiguratorAttribute.ConfigFileExtension"/> property. The <see cref="P:log4net.Config.XmlConfiguratorAttribute.ConfigFile"/> property
+ specifies a path to a file to load the config from. The path is relative to the
+ application's base directory; <see cref="P:System.AppDomain.BaseDirectory"/>.
+ The <see cref="P:log4net.Config.XmlConfiguratorAttribute.ConfigFileExtension"/> property is used as a postfix to the assembly file name.
+ The config file must be located in the application's base directory; <see cref="P:System.AppDomain.BaseDirectory"/>.
+ For example in a console application setting the <see cref="P:log4net.Config.XmlConfiguratorAttribute.ConfigFileExtension"/> to
+ <c>config</c> has the same effect as not specifying the <see cref="P:log4net.Config.XmlConfiguratorAttribute.ConfigFile"/> or
+ <see cref="P:log4net.Config.XmlConfiguratorAttribute.ConfigFileExtension"/> properties.
+ </para>
+ <para>
+ The <see cref="P:log4net.Config.XmlConfiguratorAttribute.Watch"/> property can be set to cause the <see cref="T:log4net.Config.XmlConfigurator"/>
+ to watch the configuration file for changes.
+ </para>
+ <note>
+ <para>
+ Log4net will only look for assembly level configuration attributes once.
+ When using the log4net assembly level attributes to control the configuration
+ of log4net you must ensure that the first call to any of the
+ <see cref="T:log4net.Core.LoggerManager"/> methods is made from the assembly with the configuration
+ attributes.
+ </para>
+ <para>
+ If you cannot guarantee the order in which log4net calls will be made from
+ different assemblies you must use programmatic configuration instead, i.e.
+ call the <see cref="M:log4net.Config.XmlConfigurator.Configure"/> method directly.
+ </para>
+ </note>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="M:log4net.Config.XmlConfiguratorAttribute.#ctor">
+ <summary>
+ Default constructor
+ </summary>
+ <remarks>
+ <para>
+ Default constructor
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Config.XmlConfiguratorAttribute.Configure(System.Reflection.Assembly,log4net.Repository.ILoggerRepository)">
+ <summary>
+ Configures the <see cref="T:log4net.Repository.ILoggerRepository"/> for the specified assembly.
+ </summary>
+ <param name="sourceAssembly">The assembly that this attribute was defined on.</param>
+ <param name="targetRepository">The repository to configure.</param>
+ <remarks>
+ <para>
+ Configure the repository using the <see cref="T:log4net.Config.XmlConfigurator"/>.
+ The <paramref name="targetRepository"/> specified must extend the <see cref="T:log4net.Repository.Hierarchy.Hierarchy"/>
+ class otherwise the <see cref="T:log4net.Config.XmlConfigurator"/> will not be able to
+ configure it.
+ </para>
+ </remarks>
+ <exception cref="T:System.ArgumentOutOfRangeException">The <paramref name="repository"/> does not extend <see cref="T:log4net.Repository.Hierarchy.Hierarchy"/>.</exception>
+ </member>
+ <member name="M:log4net.Config.XmlConfiguratorAttribute.ConfigureFromFile(System.Reflection.Assembly,log4net.Repository.ILoggerRepository)">
+ <summary>
+ Attempt to load configuration from the local file system
+ </summary>
+ <param name="sourceAssembly">The assembly that this attribute was defined on.</param>
+ <param name="targetRepository">The repository to configure.</param>
+ </member>
+ <member name="M:log4net.Config.XmlConfiguratorAttribute.ConfigureFromFile(log4net.Repository.ILoggerRepository,System.IO.FileInfo)">
+ <summary>
+ Configure the specified repository using a <see cref="T:System.IO.FileInfo"/>
+ </summary>
+ <param name="targetRepository">The repository to configure.</param>
+ <param name="configFile">the FileInfo pointing to the config file</param>
+ </member>
+ <member name="M:log4net.Config.XmlConfiguratorAttribute.ConfigureFromUri(System.Reflection.Assembly,log4net.Repository.ILoggerRepository)">
+ <summary>
+ Attempt to load configuration from a URI
+ </summary>
+ <param name="sourceAssembly">The assembly that this attribute was defined on.</param>
+ <param name="targetRepository">The repository to configure.</param>
+ </member>
+ <member name="P:log4net.Config.XmlConfiguratorAttribute.ConfigFile">
+ <summary>
+ Gets or sets the filename of the configuration file.
+ </summary>
+ <value>
+ The filename of the configuration file.
+ </value>
+ <remarks>
+ <para>
+ If specified, this is the name of the configuration file to use with
+ the <see cref="T:log4net.Config.XmlConfigurator"/>. This file path is relative to the
+ <b>application base</b> directory (<see cref="P:System.AppDomain.BaseDirectory"/>).
+ </para>
+ <para>
+ The <see cref="P:log4net.Config.XmlConfiguratorAttribute.ConfigFile"/> takes priority over the <see cref="P:log4net.Config.XmlConfiguratorAttribute.ConfigFileExtension"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Config.XmlConfiguratorAttribute.ConfigFileExtension">
+ <summary>
+ Gets or sets the extension of the configuration file.
+ </summary>
+ <value>
+ The extension of the configuration file.
+ </value>
+ <remarks>
+ <para>
+ If specified this is the extension for the configuration file.
+ The path to the config file is built by using the <b>application
+ base</b> directory (<see cref="P:System.AppDomain.BaseDirectory"/>),
+ the <b>assembly file name</b> and the config file extension.
+ </para>
+ <para>
+ If the <see cref="P:log4net.Config.XmlConfiguratorAttribute.ConfigFileExtension"/> is set to <c>MyExt</c> then
+ possible config file names would be: <c>MyConsoleApp.exe.MyExt</c> or
+ <c>MyClassLibrary.dll.MyExt</c>.
+ </para>
+ <para>
+ The <see cref="P:log4net.Config.XmlConfiguratorAttribute.ConfigFile"/> takes priority over the <see cref="P:log4net.Config.XmlConfiguratorAttribute.ConfigFileExtension"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Config.XmlConfiguratorAttribute.Watch">
+ <summary>
+ Gets or sets a value indicating whether to watch the configuration file.
+ </summary>
+ <value>
+ <c>true</c> if the configuration should be watched, <c>false</c> otherwise.
+ </value>
+ <remarks>
+ <para>
+ If this flag is specified and set to <c>true</c> then the framework
+ will watch the configuration file and will reload the config each time
+ the file is modified.
+ </para>
+ <para>
+ The config file can only be watched if it is loaded from local disk.
+ In a No-Touch (Smart Client) deployment where the application is downloaded
+ from a web server the config file may not reside on the local disk
+ and therefore it may not be able to watch it.
+ </para>
+ <note>
+ Watching configuration is not supported on the SSCLI.
+ </note>
+ </remarks>
+ </member>
+ <member name="T:log4net.Config.Log4NetConfigurationSectionHandler">
+ <summary>
+ Class to register for the log4net section of the configuration file
+ </summary>
+ <remarks>
+ The log4net section of the configuration file needs to have a section
+ handler registered. This is the section handler used. It simply returns
+ the XML element that is the root of the section.
+ </remarks>
+ <example>
+ Example of registering the log4net section handler :
+ <code lang="XML" escaped="true">
+ <configuration>
+ <configSections>
+ <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" />
+ </configSections>
+ <log4net>
+ log4net configuration XML goes here
+ </log4net>
+ </configuration>
+ </code>
+ </example>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="M:log4net.Config.Log4NetConfigurationSectionHandler.#ctor">
+ <summary>
+ Initializes a new instance of the <see cref="T:log4net.Config.Log4NetConfigurationSectionHandler"/> class.
+ </summary>
+ <remarks>
+ <para>
+ Default constructor.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Config.Log4NetConfigurationSectionHandler.Create(System.Object,System.Object,System.Xml.XmlNode)">
+ <summary>
+ Parses the configuration section.
+ </summary>
+ <param name="parent">The configuration settings in a corresponding parent configuration section.</param>
+ <param name="configContext">The configuration context when called from the ASP.NET configuration system. Otherwise, this parameter is reserved and is a null reference.</param>
+ <param name="section">The <see cref="T:System.Xml.XmlNode"/> for the log4net section.</param>
+ <returns>The <see cref="T:System.Xml.XmlNode"/> for the log4net section.</returns>
+ <remarks>
+ <para>
+ Returns the <see cref="T:System.Xml.XmlNode"/> containing the configuration data,
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Config.PluginAttribute">
+ <summary>
+ Assembly level attribute that specifies a plugin to attach to
+ the repository.
+ </summary>
+ <remarks>
+ <para>
+ Specifies the type of a plugin to create and attach to the
+ assembly's repository. The plugin type must implement the
+ <see cref="T:log4net.Plugin.IPlugin"/> interface.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="T:log4net.Plugin.IPluginFactory">
+ <summary>
+ Interface used to create plugins.
+ </summary>
+ <remarks>
+ <para>
+ Interface used to create a plugin.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="M:log4net.Plugin.IPluginFactory.CreatePlugin">
+ <summary>
+ Creates the plugin object.
+ </summary>
+ <returns>the new plugin instance</returns>
+ <remarks>
+ <para>
+ Create and return a new plugin instance.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Config.PluginAttribute.#ctor(System.String)">
+ <summary>
+ Initializes a new instance of the <see cref="T:log4net.Config.PluginAttribute"/> class
+ with the specified type.
+ </summary>
+ <param name="typeName">The type name of plugin to create.</param>
+ <remarks>
+ <para>
+ Create the attribute with the plugin type specified.
+ </para>
+ <para>
+ Where possible use the constructor that takes a <see cref="T:System.Type"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Config.PluginAttribute.#ctor(System.Type)">
+ <summary>
+ Initializes a new instance of the <see cref="T:log4net.Config.PluginAttribute"/> class
+ with the specified type.
+ </summary>
+ <param name="type">The type of plugin to create.</param>
+ <remarks>
+ <para>
+ Create the attribute with the plugin type specified.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Config.PluginAttribute.CreatePlugin">
+ <summary>
+ Creates the plugin object defined by this attribute.
+ </summary>
+ <remarks>
+ <para>
+ Creates the instance of the <see cref="T:log4net.Plugin.IPlugin"/> object as
+ specified by this attribute.
+ </para>
+ </remarks>
+ <returns>The plugin object.</returns>
+ </member>
+ <member name="M:log4net.Config.PluginAttribute.ToString">
+ <summary>
+ Returns a representation of the properties of this object.
+ </summary>
+ <remarks>
+ <para>
+ Overrides base class <see cref="M:System.Object.ToString"/> method to
+ return a representation of the properties of this object.
+ </para>
+ </remarks>
+ <returns>A representation of the properties of this object</returns>
+ </member>
+ <member name="P:log4net.Config.PluginAttribute.Type">
+ <summary>
+ Gets or sets the type for the plugin.
+ </summary>
+ <value>
+ The type for the plugin.
+ </value>
+ <remarks>
+ <para>
+ The type for the plugin.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Config.PluginAttribute.TypeName">
+ <summary>
+ Gets or sets the type name for the plugin.
+ </summary>
+ <value>
+ The type name for the plugin.
+ </value>
+ <remarks>
+ <para>
+ The type name for the plugin.
+ </para>
+ <para>
+ Where possible use the <see cref="P:log4net.Config.PluginAttribute.Type"/> property instead.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Config.SecurityContextProviderAttribute">
+ <summary>
+ Assembly level attribute to configure the <see cref="T:log4net.Core.SecurityContextProvider"/>.
+ </summary>
+ <remarks>
+ <para>
+ This attribute may only be used at the assembly scope and can only
+ be used once per assembly.
+ </para>
+ <para>
+ Use this attribute to configure the <see cref="T:log4net.Config.XmlConfigurator"/>
+ without calling one of the <see cref="M:log4net.Config.XmlConfigurator.Configure"/>
+ methods.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="M:log4net.Config.SecurityContextProviderAttribute.#ctor(System.Type)">
+ <summary>
+ Construct provider attribute with type specified
+ </summary>
+ <param name="providerType">the type of the provider to use</param>
+ <remarks>
+ <para>
+ The provider specified must subclass the <see cref="T:log4net.Core.SecurityContextProvider"/>
+ class.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Config.SecurityContextProviderAttribute.Configure(System.Reflection.Assembly,log4net.Repository.ILoggerRepository)">
+ <summary>
+ Configures the SecurityContextProvider
+ </summary>
+ <param name="sourceAssembly">The assembly that this attribute was defined on.</param>
+ <param name="targetRepository">The repository to configure.</param>
+ <remarks>
+ <para>
+ Creates a provider instance from the <see cref="P:log4net.Config.SecurityContextProviderAttribute.ProviderType"/> specified.
+ Sets this as the default security context provider <see cref="P:log4net.Core.SecurityContextProvider.DefaultProvider"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Config.SecurityContextProviderAttribute.ProviderType">
+ <summary>
+ Gets or sets the type of the provider to use.
+ </summary>
+ <value>
+ the type of the provider to use.
+ </value>
+ <remarks>
+ <para>
+ The provider specified must subclass the <see cref="T:log4net.Core.SecurityContextProvider"/>
+ class.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Config.XmlConfigurator">
+ <summary>
+ Use this class to initialize the log4net environment using an Xml tree.
+ </summary>
+ <remarks>
+ <para>
+ Configures a <see cref="T:log4net.Repository.ILoggerRepository"/> using an Xml tree.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="M:log4net.Config.XmlConfigurator.#ctor">
+ <summary>
+ Private constructor
+ </summary>
+ </member>
+ <member name="M:log4net.Config.XmlConfigurator.Configure">
+ <summary>
+ Automatically configures the log4net system based on the
+ application's configuration settings.
+ </summary>
+ <remarks>
+ <para>
+ Each application has a configuration file. This has the
+ same name as the application with '.config' appended.
+ This file is XML and calling this function prompts the
+ configurator to look in that file for a section called
+ <c>log4net</c> that contains the configuration data.
+ </para>
+ <para>
+ To use this method to configure log4net you must specify
+ the <see cref="T:log4net.Config.Log4NetConfigurationSectionHandler"/> section
+ handler for the <c>log4net</c> configuration section. See the
+ <see cref="T:log4net.Config.Log4NetConfigurationSectionHandler"/> for an example.
+ </para>
+ </remarks>
+ <seealso cref="T:log4net.Config.Log4NetConfigurationSectionHandler"/>
+ </member>
+ <member name="M:log4net.Config.XmlConfigurator.Configure(log4net.Repository.ILoggerRepository)">
+ <summary>
+ Automatically configures the <see cref="T:log4net.Repository.ILoggerRepository"/> using settings
+ stored in the application's configuration file.
+ </summary>
+ <remarks>
+ <para>
+ Each application has a configuration file. This has the
+ same name as the application with '.config' appended.
+ This file is XML and calling this function prompts the
+ configurator to look in that file for a section called
+ <c>log4net</c> that contains the configuration data.
+ </para>
+ <para>
+ To use this method to configure log4net you must specify
+ the <see cref="T:log4net.Config.Log4NetConfigurationSectionHandler"/> section
+ handler for the <c>log4net</c> configuration section. See the
+ <see cref="T:log4net.Config.Log4NetConfigurationSectionHandler"/> for an example.
+ </para>
+ </remarks>
+ <param name="repository">The repository to configure.</param>
+ </member>
+ <member name="M:log4net.Config.XmlConfigurator.Configure(System.Xml.XmlElement)">
+ <summary>
+ Configures log4net using a <c>log4net</c> element
+ </summary>
+ <remarks>
+ <para>
+ Loads the log4net configuration from the XML element
+ supplied as <paramref name="element"/>.
+ </para>
+ </remarks>
+ <param name="element">The element to parse.</param>
+ </member>
+ <member name="M:log4net.Config.XmlConfigurator.Configure(log4net.Repository.ILoggerRepository,System.Xml.XmlElement)">
+ <summary>
+ Configures the <see cref="T:log4net.Repository.ILoggerRepository"/> using the specified XML
+ element.
+ </summary>
+ <remarks>
+ Loads the log4net configuration from the XML element
+ supplied as <paramref name="element"/>.
+ </remarks>
+ <param name="repository">The repository to configure.</param>
+ <param name="element">The element to parse.</param>
+ </member>
+ <member name="M:log4net.Config.XmlConfigurator.Configure(System.IO.FileInfo)">
+ <summary>
+ Configures log4net using the specified configuration file.
+ </summary>
+ <param name="configFile">The XML file to load the configuration from.</param>
+ <remarks>
+ <para>
+ The configuration file must be valid XML. It must contain
+ at least one element called <c>log4net</c> that holds
+ the log4net configuration data.
+ </para>
+ <para>
+ The log4net configuration file can possible be specified in the application's
+ configuration file (either <c>MyAppName.exe.config</c> for a
+ normal application on <c>Web.config</c> for an ASP.NET application).
+ </para>
+ <para>
+ The first element matching <c>&lt;configuration&gt;</c> will be read as the
+ configuration. If this file is also a .NET .config file then you must specify
+ a configuration section for the <c>log4net</c> element otherwise .NET will
+ complain. Set the type for the section handler to <see cref="T:System.Configuration.IgnoreSectionHandler"/>, for example:
+ <code lang="XML" escaped="true">
+ <configSections>
+ <section name="log4net" type="System.Configuration.IgnoreSectionHandler"/>
+ </configSections>
+ </code>
+ </para>
+ <example>
+ The following example configures log4net using a configuration file, of which the
+ location is stored in the application's configuration file :
+ </example>
+ <code lang="C#">
+ using log4net.Config;
+ using System.IO;
+ using System.Configuration;
+
+ ...
+
+ XmlConfigurator.Configure(new FileInfo(ConfigurationSettings.AppSettings["log4net-config-file"]));
+ </code>
+ <para>
+ In the <c>.config</c> file, the path to the log4net can be specified like this :
+ </para>
+ <code lang="XML" escaped="true">
+ <configuration>
+ <appSettings>
+ <add key="log4net-config-file" value="log.config"/>
+ </appSettings>
+ </configuration>
+ </code>
+ </remarks>
+ </member>
+ <member name="M:log4net.Config.XmlConfigurator.Configure(System.Uri)">
+ <summary>
+ Configures log4net using the specified configuration URI.
+ </summary>
+ <param name="configUri">A URI to load the XML configuration from.</param>
+ <remarks>
+ <para>
+ The configuration data must be valid XML. It must contain
+ at least one element called <c>log4net</c> that holds
+ the log4net configuration data.
+ </para>
+ <para>
+ The <see cref="T:System.Net.WebRequest"/> must support the URI scheme specified.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Config.XmlConfigurator.Configure(System.IO.Stream)">
+ <summary>
+ Configures log4net using the specified configuration data stream.
+ </summary>
+ <param name="configStream">A stream to load the XML configuration from.</param>
+ <remarks>
+ <para>
+ The configuration data must be valid XML. It must contain
+ at least one element called <c>log4net</c> that holds
+ the log4net configuration data.
+ </para>
+ <para>
+ Note that this method will NOT close the stream parameter.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Config.XmlConfigurator.Configure(log4net.Repository.ILoggerRepository,System.IO.FileInfo)">
+ <summary>
+ Configures the <see cref="T:log4net.Repository.ILoggerRepository"/> using the specified configuration
+ file.
+ </summary>
+ <param name="repository">The repository to configure.</param>
+ <param name="configFile">The XML file to load the configuration from.</param>
+ <remarks>
+ <para>
+ The configuration file must be valid XML. It must contain
+ at least one element called <c>log4net</c> that holds
+ the configuration data.
+ </para>
+ <para>
+ The log4net configuration file can possible be specified in the application's
+ configuration file (either <c>MyAppName.exe.config</c> for a
+ normal application on <c>Web.config</c> for an ASP.NET application).
+ </para>
+ <para>
+ The first element matching <c>&lt;configuration&gt;</c> will be read as the
+ configuration. If this file is also a .NET .config file then you must specify
+ a configuration section for the <c>log4net</c> element otherwise .NET will
+ complain. Set the type for the section handler to <see cref="T:System.Configuration.IgnoreSectionHandler"/>, for example:
+ <code lang="XML" escaped="true">
+ <configSections>
+ <section name="log4net" type="System.Configuration.IgnoreSectionHandler"/>
+ </configSections>
+ </code>
+ </para>
+ <example>
+ The following example configures log4net using a configuration file, of which the
+ location is stored in the application's configuration file :
+ </example>
+ <code lang="C#">
+ using log4net.Config;
+ using System.IO;
+ using System.Configuration;
+
+ ...
+
+ XmlConfigurator.Configure(new FileInfo(ConfigurationSettings.AppSettings["log4net-config-file"]));
+ </code>
+ <para>
+ In the <c>.config</c> file, the path to the log4net can be specified like this :
+ </para>
+ <code lang="XML" escaped="true">
+ <configuration>
+ <appSettings>
+ <add key="log4net-config-file" value="log.config"/>
+ </appSettings>
+ </configuration>
+ </code>
+ </remarks>
+ </member>
+ <member name="M:log4net.Config.XmlConfigurator.Configure(log4net.Repository.ILoggerRepository,System.Uri)">
+ <summary>
+ Configures the <see cref="T:log4net.Repository.ILoggerRepository"/> using the specified configuration
+ URI.
+ </summary>
+ <param name="repository">The repository to configure.</param>
+ <param name="configUri">A URI to load the XML configuration from.</param>
+ <remarks>
+ <para>
+ The configuration data must be valid XML. It must contain
+ at least one element called <c>log4net</c> that holds
+ the configuration data.
+ </para>
+ <para>
+ The <see cref="T:System.Net.WebRequest"/> must support the URI scheme specified.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Config.XmlConfigurator.Configure(log4net.Repository.ILoggerRepository,System.IO.Stream)">
+ <summary>
+ Configures the <see cref="T:log4net.Repository.ILoggerRepository"/> using the specified configuration
+ file.
+ </summary>
+ <param name="repository">The repository to configure.</param>
+ <param name="configStream">The stream to load the XML configuration from.</param>
+ <remarks>
+ <para>
+ The configuration data must be valid XML. It must contain
+ at least one element called <c>log4net</c> that holds
+ the configuration data.
+ </para>
+ <para>
+ Note that this method will NOT close the stream parameter.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Config.XmlConfigurator.ConfigureAndWatch(System.IO.FileInfo)">
+ <summary>
+ Configures log4net using the file specified, monitors the file for changes
+ and reloads the configuration if a change is detected.
+ </summary>
+ <param name="configFile">The XML file to load the configuration from.</param>
+ <remarks>
+ <para>
+ The configuration file must be valid XML. It must contain
+ at least one element called <c>log4net</c> that holds
+ the configuration data.
+ </para>
+ <para>
+ The configuration file will be monitored using a <see cref="T:System.IO.FileSystemWatcher"/>
+ and depends on the behavior of that class.
+ </para>
+ <para>
+ For more information on how to configure log4net using
+ a separate configuration file, see <see cref="M:log4net.Config.XmlConfigurator.Configure(System.IO.FileInfo)"/>.
+ </para>
+ </remarks>
+ <seealso cref="M:log4net.Config.XmlConfigurator.Configure(System.IO.FileInfo)"/>
+ </member>
+ <member name="M:log4net.Config.XmlConfigurator.ConfigureAndWatch(log4net.Repository.ILoggerRepository,System.IO.FileInfo)">
+ <summary>
+ Configures the <see cref="T:log4net.Repository.ILoggerRepository"/> using the file specified,
+ monitors the file for changes and reloads the configuration if a change
+ is detected.
+ </summary>
+ <param name="repository">The repository to configure.</param>
+ <param name="configFile">The XML file to load the configuration from.</param>
+ <remarks>
+ <para>
+ The configuration file must be valid XML. It must contain
+ at least one element called <c>log4net</c> that holds
+ the configuration data.
+ </para>
+ <para>
+ The configuration file will be monitored using a <see cref="T:System.IO.FileSystemWatcher"/>
+ and depends on the behavior of that class.
+ </para>
+ <para>
+ For more information on how to configure log4net using
+ a separate configuration file, see <see cref="M:log4net.Config.XmlConfigurator.Configure(System.IO.FileInfo)"/>.
+ </para>
+ </remarks>
+ <seealso cref="M:log4net.Config.XmlConfigurator.Configure(System.IO.FileInfo)"/>
+ </member>
+ <member name="M:log4net.Config.XmlConfigurator.ConfigureFromXml(log4net.Repository.ILoggerRepository,System.Xml.XmlElement)">
+ <summary>
+ Configures the specified repository using a <c>log4net</c> element.
+ </summary>
+ <param name="repository">The hierarchy to configure.</param>
+ <param name="element">The element to parse.</param>
+ <remarks>
+ <para>
+ Loads the log4net configuration from the XML element
+ supplied as <paramref name="element"/>.
+ </para>
+ <para>
+ This method is ultimately called by one of the Configure methods
+ to load the configuration from an <see cref="T:System.Xml.XmlElement"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Config.XmlConfigurator.ConfigureAndWatchHandler">
+ <summary>
+ Class used to watch config files.
+ </summary>
+ <remarks>
+ <para>
+ Uses the <see cref="T:System.IO.FileSystemWatcher"/> to monitor
+ changes to a specified file. Because multiple change notifications
+ may be raised when the file is modified, a timer is used to
+ compress the notifications into a single event. The timer
+ waits for <see cref="F:log4net.Config.XmlConfigurator.ConfigureAndWatchHandler.TimeoutMillis"/> time before delivering
+ the event notification. If any further <see cref="T:System.IO.FileSystemWatcher"/>
+ change notifications arrive while the timer is waiting it
+ is reset and waits again for <see cref="F:log4net.Config.XmlConfigurator.ConfigureAndWatchHandler.TimeoutMillis"/> to
+ elapse.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Config.XmlConfigurator.ConfigureAndWatchHandler.TimeoutMillis">
+ <summary>
+ The default amount of time to wait after receiving notification
+ before reloading the config file.
+ </summary>
+ </member>
+ <member name="M:log4net.Config.XmlConfigurator.ConfigureAndWatchHandler.StartWatching(log4net.Repository.ILoggerRepository,System.IO.FileInfo)">
+ <summary>
+ Watch a specified config file used to configure a repository
+ </summary>
+ <param name="repository">The repository to configure.</param>
+ <param name="configFile">The configuration file to watch.</param>
+ <remarks>
+ <para>
+ Watch a specified config file used to configure a repository
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Config.XmlConfigurator.ConfigureAndWatchHandler.m_configFile">
+ <summary>
+ Holds the FileInfo used to configure the XmlConfigurator
+ </summary>
+ </member>
+ <member name="F:log4net.Config.XmlConfigurator.ConfigureAndWatchHandler.m_repository">
+ <summary>
+ Holds the repository being configured.
+ </summary>
+ </member>
+ <member name="F:log4net.Config.XmlConfigurator.ConfigureAndWatchHandler.m_timer">
+ <summary>
+ The timer used to compress the notification events.
+ </summary>
+ </member>
+ <member name="M:log4net.Config.XmlConfigurator.ConfigureAndWatchHandler.#ctor(log4net.Repository.ILoggerRepository,System.IO.FileInfo)">
+ <summary>
+ Initializes a new instance of the <see cref="T:log4net.Config.XmlConfigurator.ConfigureAndWatchHandler"/> class.
+ </summary>
+ <param name="repository">The repository to configure.</param>
+ <param name="configFile">The configuration file to watch.</param>
+ <remarks>
+ <para>
+ Initializes a new instance of the <see cref="T:log4net.Config.XmlConfigurator.ConfigureAndWatchHandler"/> class.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Config.XmlConfigurator.ConfigureAndWatchHandler.ConfigureAndWatchHandler_OnChanged(System.Object,System.IO.FileSystemEventArgs)">
+ <summary>
+ Event handler used by <see cref="T:log4net.Config.XmlConfigurator.ConfigureAndWatchHandler"/>.
+ </summary>
+ <param name="source">The <see cref="T:System.IO.FileSystemWatcher"/> firing the event.</param>
+ <param name="e">The argument indicates the file that caused the event to be fired.</param>
+ <remarks>
+ <para>
+ This handler reloads the configuration from the file when the event is fired.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Config.XmlConfigurator.ConfigureAndWatchHandler.ConfigureAndWatchHandler_OnRenamed(System.Object,System.IO.RenamedEventArgs)">
+ <summary>
+ Event handler used by <see cref="T:log4net.Config.XmlConfigurator.ConfigureAndWatchHandler"/>.
+ </summary>
+ <param name="source">The <see cref="T:System.IO.FileSystemWatcher"/> firing the event.</param>
+ <param name="e">The argument indicates the file that caused the event to be fired.</param>
+ <remarks>
+ <para>
+ This handler reloads the configuration from the file when the event is fired.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Config.XmlConfigurator.ConfigureAndWatchHandler.OnWatchedFileChange(System.Object)">
+ <summary>
+ Called by the timer when the configuration has been updated.
+ </summary>
+ <param name="state">null</param>
+ </member>
+ <member name="T:log4net.Core.CompactRepositorySelector">
+ <summary>
+ The implementation of the <see cref="T:log4net.Core.IRepositorySelector"/> interface suitable
+ for use with the compact framework
+ </summary>
+ <remarks>
+ <para>
+ This <see cref="T:log4net.Core.IRepositorySelector"/> implementation is a simple
+ mapping between repository name and <see cref="T:log4net.Repository.ILoggerRepository"/>
+ object.
+ </para>
+ <para>
+ The .NET Compact Framework 1.0 does not support retrieving assembly
+ level attributes therefore unlike the <c>DefaultRepositorySelector</c>
+ this selector does not examine the calling assembly for attributes.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="T:log4net.Core.IRepositorySelector">
+ <summary>
+ Interface used by the <see cref="T:log4net.LogManager"/> to select the <see cref="T:log4net.Repository.ILoggerRepository"/>.
+ </summary>
+ <remarks>
+ <para>
+ The <see cref="T:log4net.LogManager"/> uses a <see cref="T:log4net.Core.IRepositorySelector"/>
+ to specify the policy for selecting the correct <see cref="T:log4net.Repository.ILoggerRepository"/>
+ to return to the caller.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="M:log4net.Core.IRepositorySelector.GetRepository(System.Reflection.Assembly)">
+ <summary>
+ Gets the <see cref="T:log4net.Repository.ILoggerRepository"/> for the specified assembly.
+ </summary>
+ <param name="assembly">The assembly to use to lookup to the <see cref="T:log4net.Repository.ILoggerRepository"/></param>
+ <returns>The <see cref="T:log4net.Repository.ILoggerRepository"/> for the assembly.</returns>
+ <remarks>
+ <para>
+ Gets the <see cref="T:log4net.Repository.ILoggerRepository"/> for the specified assembly.
+ </para>
+ <para>
+ How the association between <see cref="T:System.Reflection.Assembly"/> and <see cref="T:log4net.Repository.ILoggerRepository"/>
+ is made is not defined. The implementation may choose any method for
+ this association. The results of this method must be repeatable, i.e.
+ when called again with the same arguments the result must be the
+ save value.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.IRepositorySelector.GetRepository(System.String)">
+ <summary>
+ Gets the named <see cref="T:log4net.Repository.ILoggerRepository"/>.
+ </summary>
+ <param name="repositoryName">The name to use to lookup to the <see cref="T:log4net.Repository.ILoggerRepository"/>.</param>
+ <returns>The named <see cref="T:log4net.Repository.ILoggerRepository"/></returns>
+ <remarks>
+ Lookup a named <see cref="T:log4net.Repository.ILoggerRepository"/>. This is the repository created by
+ calling <see cref="M:log4net.Core.IRepositorySelector.CreateRepository(System.String,System.Type)"/>.
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.IRepositorySelector.CreateRepository(System.Reflection.Assembly,System.Type)">
+ <summary>
+ Creates a new repository for the assembly specified.
+ </summary>
+ <param name="assembly">The assembly to use to create the domain to associate with the <see cref="T:log4net.Repository.ILoggerRepository"/>.</param>
+ <param name="repositoryType">The type of repository to create, must implement <see cref="T:log4net.Repository.ILoggerRepository"/>.</param>
+ <returns>The repository created.</returns>
+ <remarks>
+ <para>
+ The <see cref="T:log4net.Repository.ILoggerRepository"/> created will be associated with the domain
+ specified such that a call to <see cref="M:log4net.Core.IRepositorySelector.GetRepository(System.Reflection.Assembly)"/> with the
+ same assembly specified will return the same repository instance.
+ </para>
+ <para>
+ How the association between <see cref="T:System.Reflection.Assembly"/> and <see cref="T:log4net.Repository.ILoggerRepository"/>
+ is made is not defined. The implementation may choose any method for
+ this association.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.IRepositorySelector.CreateRepository(System.String,System.Type)">
+ <summary>
+ Creates a new repository with the name specified.
+ </summary>
+ <param name="repositoryName">The name to associate with the <see cref="T:log4net.Repository.ILoggerRepository"/>.</param>
+ <param name="repositoryType">The type of repository to create, must implement <see cref="T:log4net.Repository.ILoggerRepository"/>.</param>
+ <returns>The repository created.</returns>
+ <remarks>
+ <para>
+ The <see cref="T:log4net.Repository.ILoggerRepository"/> created will be associated with the name
+ specified such that a call to <see cref="M:log4net.Core.IRepositorySelector.GetRepository(System.String)"/> with the
+ same name will return the same repository instance.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.IRepositorySelector.ExistsRepository(System.String)">
+ <summary>
+ Test if a named repository exists
+ </summary>
+ <param name="repositoryName">the named repository to check</param>
+ <returns><c>true</c> if the repository exists</returns>
+ <remarks>
+ <para>
+ Test if a named repository exists. Use <see cref="M:log4net.Core.IRepositorySelector.CreateRepository(System.Reflection.Assembly,System.Type)"/>
+ to create a new repository and <see cref="M:log4net.Core.IRepositorySelector.GetRepository(System.Reflection.Assembly)"/> to retrieve
+ a repository.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.IRepositorySelector.GetAllRepositories">
+ <summary>
+ Gets an array of all currently defined repositories.
+ </summary>
+ <returns>
+ An array of the <see cref="T:log4net.Repository.ILoggerRepository"/> instances created by
+ this <see cref="T:log4net.Core.IRepositorySelector"/>.</returns>
+ <remarks>
+ <para>
+ Gets an array of all of the repositories created by this selector.
+ </para>
+ </remarks>
+ </member>
+ <member name="E:log4net.Core.IRepositorySelector.LoggerRepositoryCreatedEvent">
+ <summary>
+ Event to notify that a logger repository has been created.
+ </summary>
+ <value>
+ Event to notify that a logger repository has been created.
+ </value>
+ <remarks>
+ <para>
+ Event raised when a new repository is created.
+ The event source will be this selector. The event args will
+ be a <see cref="T:log4net.Core.LoggerRepositoryCreationEventArgs"/> which
+ holds the newly created <see cref="T:log4net.Repository.ILoggerRepository"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.CompactRepositorySelector.#ctor(System.Type)">
+ <summary>
+ Create a new repository selector
+ </summary>
+ <param name="defaultRepositoryType">the type of the repositories to create, must implement <see cref="T:log4net.Repository.ILoggerRepository"/></param>
+ <remarks>
+ <para>
+ Create an new compact repository selector.
+ The default type for repositories must be specified,
+ an appropriate value would be <see cref="T:log4net.Repository.Hierarchy.Hierarchy"/>.
+ </para>
+ </remarks>
+ <exception cref="T:System.ArgumentNullException">throw if <paramref name="defaultRepositoryType"/> is null</exception>
+ <exception cref="T:System.ArgumentOutOfRangeException">throw if <paramref name="defaultRepositoryType"/> does not implement <see cref="T:log4net.Repository.ILoggerRepository"/></exception>
+ </member>
+ <member name="M:log4net.Core.CompactRepositorySelector.GetRepository(System.Reflection.Assembly)">
+ <summary>
+ Get the <see cref="T:log4net.Repository.ILoggerRepository"/> for the specified assembly
+ </summary>
+ <param name="assembly">not used</param>
+ <returns>The default <see cref="T:log4net.Repository.ILoggerRepository"/></returns>
+ <remarks>
+ <para>
+ The <paramref name="assembly"/> argument is not used. This selector does not create a
+ separate repository for each assembly.
+ </para>
+ <para>
+ As a named repository is not specified the default repository is
+ returned. The default repository is named <c>log4net-default-repository</c>.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.CompactRepositorySelector.GetRepository(System.String)">
+ <summary>
+ Get the named <see cref="T:log4net.Repository.ILoggerRepository"/>
+ </summary>
+ <param name="repositoryName">the name of the repository to lookup</param>
+ <returns>The named <see cref="T:log4net.Repository.ILoggerRepository"/></returns>
+ <remarks>
+ <para>
+ Get the named <see cref="T:log4net.Repository.ILoggerRepository"/>. The default
+ repository is <c>log4net-default-repository</c>. Other repositories
+ must be created using the <see cref="M:log4net.Core.CompactRepositorySelector.CreateRepository(System.String,System.Type)"/>.
+ If the named repository does not exist an exception is thrown.
+ </para>
+ </remarks>
+ <exception cref="T:System.ArgumentNullException">throw if <paramref name="repositoryName"/> is null</exception>
+ <exception cref="T:log4net.Core.LogException">throw if the <paramref name="repositoryName"/> does not exist</exception>
+ </member>
+ <member name="M:log4net.Core.CompactRepositorySelector.CreateRepository(System.Reflection.Assembly,System.Type)">
+ <summary>
+ Create a new repository for the assembly specified
+ </summary>
+ <param name="assembly">not used</param>
+ <param name="repositoryType">the type of repository to create, must implement <see cref="T:log4net.Repository.ILoggerRepository"/></param>
+ <returns>the repository created</returns>
+ <remarks>
+ <para>
+ The <paramref name="assembly"/> argument is not used. This selector does not create a
+ separate repository for each assembly.
+ </para>
+ <para>
+ If the <paramref name="repositoryType"/> is <c>null</c> then the
+ default repository type specified to the constructor is used.
+ </para>
+ <para>
+ As a named repository is not specified the default repository is
+ returned. The default repository is named <c>log4net-default-repository</c>.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.CompactRepositorySelector.CreateRepository(System.String,System.Type)">
+ <summary>
+ Create a new repository for the repository specified
+ </summary>
+ <param name="repositoryName">the repository to associate with the <see cref="T:log4net.Repository.ILoggerRepository"/></param>
+ <param name="repositoryType">the type of repository to create, must implement <see cref="T:log4net.Repository.ILoggerRepository"/>.
+ If this param is null then the default repository type is used.</param>
+ <returns>the repository created</returns>
+ <remarks>
+ <para>
+ The <see cref="T:log4net.Repository.ILoggerRepository"/> created will be associated with the repository
+ specified such that a call to <see cref="M:log4net.Core.CompactRepositorySelector.GetRepository(System.String)"/> with the
+ same repository specified will return the same repository instance.
+ </para>
+ <para>
+ If the named repository already exists an exception will be thrown.
+ </para>
+ <para>
+ If <paramref name="repositoryType"/> is <c>null</c> then the default
+ repository type specified to the constructor is used.
+ </para>
+ </remarks>
+ <exception cref="T:System.ArgumentNullException">throw if <paramref name="repositoryName"/> is null</exception>
+ <exception cref="T:log4net.Core.LogException">throw if the <paramref name="repositoryName"/> already exists</exception>
+ </member>
+ <member name="M:log4net.Core.CompactRepositorySelector.ExistsRepository(System.String)">
+ <summary>
+ Test if a named repository exists
+ </summary>
+ <param name="repositoryName">the named repository to check</param>
+ <returns><c>true</c> if the repository exists</returns>
+ <remarks>
+ <para>
+ Test if a named repository exists. Use <see cref="M:log4net.Core.CompactRepositorySelector.CreateRepository(System.String,System.Type)"/>
+ to create a new repository and <see cref="M:log4net.Core.CompactRepositorySelector.GetRepository(System.String)"/> to retrieve
+ a repository.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.CompactRepositorySelector.GetAllRepositories">
+ <summary>
+ Gets a list of <see cref="T:log4net.Repository.ILoggerRepository"/> objects
+ </summary>
+ <returns>an array of all known <see cref="T:log4net.Repository.ILoggerRepository"/> objects</returns>
+ <remarks>
+ <para>
+ Gets an array of all of the repositories created by this selector.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.CompactRepositorySelector.OnLoggerRepositoryCreatedEvent(log4net.Repository.ILoggerRepository)">
+ <summary>
+ Notify the registered listeners that the repository has been created
+ </summary>
+ <param name="repository">The repository that has been created</param>
+ <remarks>
+ <para>
+ Raises the <event cref="E:log4net.Core.CompactRepositorySelector.LoggerRepositoryCreatedEvent">LoggerRepositoryCreatedEvent</event>
+ event.
+ </para>
+ </remarks>
+ </member>
+ <member name="E:log4net.Core.CompactRepositorySelector.LoggerRepositoryCreatedEvent">
+ <summary>
+ Event to notify that a logger repository has been created.
+ </summary>
+ <value>
+ Event to notify that a logger repository has been created.
+ </value>
+ <remarks>
+ <para>
+ Event raised when a new repository is created.
+ The event source will be this selector. The event args will
+ be a <see cref="T:log4net.Core.LoggerRepositoryCreationEventArgs"/> which
+ holds the newly created <see cref="T:log4net.Repository.ILoggerRepository"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Core.DefaultRepositorySelector">
+ <summary>
+ The default implementation of the <see cref="T:log4net.Core.IRepositorySelector"/> interface.
+ </summary>
+ <remarks>
+ <para>
+ Uses attributes defined on the calling assembly to determine how to
+ configure the hierarchy for the repository.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="M:log4net.Core.DefaultRepositorySelector.#ctor(System.Type)">
+ <summary>
+ Creates a new repository selector.
+ </summary>
+ <param name="defaultRepositoryType">The type of the repositories to create, must implement <see cref="T:log4net.Repository.ILoggerRepository"/></param>
+ <remarks>
+ <para>
+ Create an new repository selector.
+ The default type for repositories must be specified,
+ an appropriate value would be <see cref="T:log4net.Repository.Hierarchy.Hierarchy"/>.
+ </para>
+ </remarks>
+ <exception cref="T:System.ArgumentNullException"><paramref name="defaultRepositoryType"/> is <see langword="null"/>.</exception>
+ <exception cref="T:System.ArgumentOutOfRangeException"><paramref name="defaultRepositoryType"/> does not implement <see cref="T:log4net.Repository.ILoggerRepository"/>.</exception>
+ </member>
+ <member name="M:log4net.Core.DefaultRepositorySelector.GetRepository(System.Reflection.Assembly)">
+ <summary>
+ Gets the <see cref="T:log4net.Repository.ILoggerRepository"/> for the specified assembly.
+ </summary>
+ <param name="repositoryAssembly">The assembly use to lookup the <see cref="T:log4net.Repository.ILoggerRepository"/>.</param>
+ <remarks>
+ <para>
+ The type of the <see cref="T:log4net.Repository.ILoggerRepository"/> created and the repository
+ to create can be overridden by specifying the <see cref="T:log4net.Config.RepositoryAttribute"/>
+ attribute on the <paramref name="repositoryAssembly"/>.
+ </para>
+ <para>
+ The default values are to use the <see cref="T:log4net.Repository.Hierarchy.Hierarchy"/>
+ implementation of the <see cref="T:log4net.Repository.ILoggerRepository"/> interface and to use the
+ <see cref="P:System.Reflection.AssemblyName.Name"/> as the name of the repository.
+ </para>
+ <para>
+ The <see cref="T:log4net.Repository.ILoggerRepository"/> created will be automatically configured using
+ any <see cref="T:log4net.Config.ConfiguratorAttribute"/> attributes defined on
+ the <paramref name="repositoryAssembly"/>.
+ </para>
+ </remarks>
+ <returns>The <see cref="T:log4net.Repository.ILoggerRepository"/> for the assembly</returns>
+ <exception cref="T:System.ArgumentNullException"><paramref name="repositoryAssembly"/> is <see langword="null"/>.</exception>
+ </member>
+ <member name="M:log4net.Core.DefaultRepositorySelector.GetRepository(System.String)">
+ <summary>
+ Gets the <see cref="T:log4net.Repository.ILoggerRepository"/> for the specified repository.
+ </summary>
+ <param name="repositoryName">The repository to use to lookup the <see cref="T:log4net.Repository.ILoggerRepository"/>.</param>
+ <returns>The <see cref="T:log4net.Repository.ILoggerRepository"/> for the specified repository.</returns>
+ <remarks>
+ <para>
+ Returns the named repository. If <paramref name="repositoryName"/> is <c>null</c>
+ a <see cref="T:System.ArgumentNullException"/> is thrown. If the repository
+ does not exist a <see cref="T:log4net.Core.LogException"/> is thrown.
+ </para>
+ <para>
+ Use <see cref="M:log4net.Core.DefaultRepositorySelector.CreateRepository(System.String,System.Type)"/> to create a repository.
+ </para>
+ </remarks>
+ <exception cref="T:System.ArgumentNullException"><paramref name="repositoryName"/> is <see langword="null"/>.</exception>
+ <exception cref="T:log4net.Core.LogException"><paramref name="repositoryName"/> does not exist.</exception>
+ </member>
+ <member name="M:log4net.Core.DefaultRepositorySelector.CreateRepository(System.Reflection.Assembly,System.Type)">
+ <summary>
+ Create a new repository for the assembly specified
+ </summary>
+ <param name="repositoryAssembly">the assembly to use to create the repository to associate with the <see cref="T:log4net.Repository.ILoggerRepository"/>.</param>
+ <param name="repositoryType">The type of repository to create, must implement <see cref="T:log4net.Repository.ILoggerRepository"/>.</param>
+ <returns>The repository created.</returns>
+ <remarks>
+ <para>
+ The <see cref="T:log4net.Repository.ILoggerRepository"/> created will be associated with the repository
+ specified such that a call to <see cref="M:log4net.Core.DefaultRepositorySelector.GetRepository(System.Reflection.Assembly)"/> with the
+ same assembly specified will return the same repository instance.
+ </para>
+ <para>
+ The type of the <see cref="T:log4net.Repository.ILoggerRepository"/> created and
+ the repository to create can be overridden by specifying the
+ <see cref="T:log4net.Config.RepositoryAttribute"/> attribute on the
+ <paramref name="repositoryAssembly"/>. The default values are to use the
+ <paramref name="repositoryType"/> implementation of the
+ <see cref="T:log4net.Repository.ILoggerRepository"/> interface and to use the
+ <see cref="P:System.Reflection.AssemblyName.Name"/> as the name of the repository.
+ </para>
+ <para>
+ The <see cref="T:log4net.Repository.ILoggerRepository"/> created will be automatically
+ configured using any <see cref="T:log4net.Config.ConfiguratorAttribute"/>
+ attributes defined on the <paramref name="repositoryAssembly"/>.
+ </para>
+ <para>
+ If a repository for the <paramref name="repositoryAssembly"/> already exists
+ that repository will be returned. An error will not be raised and that
+ repository may be of a different type to that specified in <paramref name="repositoryType"/>.
+ Also the <see cref="T:log4net.Config.RepositoryAttribute"/> attribute on the
+ assembly may be used to override the repository type specified in
+ <paramref name="repositoryType"/>.
+ </para>
+ </remarks>
+ <exception cref="T:System.ArgumentNullException"><paramref name="repositoryAssembly"/> is <see langword="null"/>.</exception>
+ </member>
+ <member name="M:log4net.Core.DefaultRepositorySelector.CreateRepository(System.Reflection.Assembly,System.Type,System.String,System.Boolean)">
+ <summary>
+ Creates a new repository for the assembly specified.
+ </summary>
+ <param name="repositoryAssembly">the assembly to use to create the repository to associate with the <see cref="T:log4net.Repository.ILoggerRepository"/>.</param>
+ <param name="repositoryType">The type of repository to create, must implement <see cref="T:log4net.Repository.ILoggerRepository"/>.</param>
+ <param name="repositoryName">The name to assign to the created repository</param>
+ <param name="readAssemblyAttributes">Set to <c>true</c> to read and apply the assembly attributes</param>
+ <returns>The repository created.</returns>
+ <remarks>
+ <para>
+ The <see cref="T:log4net.Repository.ILoggerRepository"/> created will be associated with the repository
+ specified such that a call to <see cref="M:log4net.Core.DefaultRepositorySelector.GetRepository(System.Reflection.Assembly)"/> with the
+ same assembly specified will return the same repository instance.
+ </para>
+ <para>
+ The type of the <see cref="T:log4net.Repository.ILoggerRepository"/> created and
+ the repository to create can be overridden by specifying the
+ <see cref="T:log4net.Config.RepositoryAttribute"/> attribute on the
+ <paramref name="repositoryAssembly"/>. The default values are to use the
+ <paramref name="repositoryType"/> implementation of the
+ <see cref="T:log4net.Repository.ILoggerRepository"/> interface and to use the
+ <see cref="P:System.Reflection.AssemblyName.Name"/> as the name of the repository.
+ </para>
+ <para>
+ The <see cref="T:log4net.Repository.ILoggerRepository"/> created will be automatically
+ configured using any <see cref="T:log4net.Config.ConfiguratorAttribute"/>
+ attributes defined on the <paramref name="repositoryAssembly"/>.
+ </para>
+ <para>
+ If a repository for the <paramref name="repositoryAssembly"/> already exists
+ that repository will be returned. An error will not be raised and that
+ repository may be of a different type to that specified in <paramref name="repositoryType"/>.
+ Also the <see cref="T:log4net.Config.RepositoryAttribute"/> attribute on the
+ assembly may be used to override the repository type specified in
+ <paramref name="repositoryType"/>.
+ </para>
+ </remarks>
+ <exception cref="T:System.ArgumentNullException"><paramref name="repositoryAssembly"/> is <see langword="null"/>.</exception>
+ </member>
+ <member name="M:log4net.Core.DefaultRepositorySelector.CreateRepository(System.String,System.Type)">
+ <summary>
+ Creates a new repository for the specified repository.
+ </summary>
+ <param name="repositoryName">The repository to associate with the <see cref="T:log4net.Repository.ILoggerRepository"/>.</param>
+ <param name="repositoryType">The type of repository to create, must implement <see cref="T:log4net.Repository.ILoggerRepository"/>.
+ If this param is <see langword="null"/> then the default repository type is used.</param>
+ <returns>The new repository.</returns>
+ <remarks>
+ <para>
+ The <see cref="T:log4net.Repository.ILoggerRepository"/> created will be associated with the repository
+ specified such that a call to <see cref="M:log4net.Core.DefaultRepositorySelector.GetRepository(System.String)"/> with the
+ same repository specified will return the same repository instance.
+ </para>
+ </remarks>
+ <exception cref="T:System.ArgumentNullException"><paramref name="repositoryName"/> is <see langword="null"/>.</exception>
+ <exception cref="T:log4net.Core.LogException"><paramref name="repositoryName"/> already exists.</exception>
+ </member>
+ <member name="M:log4net.Core.DefaultRepositorySelector.ExistsRepository(System.String)">
+ <summary>
+ Test if a named repository exists
+ </summary>
+ <param name="repositoryName">the named repository to check</param>
+ <returns><c>true</c> if the repository exists</returns>
+ <remarks>
+ <para>
+ Test if a named repository exists. Use <see cref="M:log4net.Core.DefaultRepositorySelector.CreateRepository(System.String,System.Type)"/>
+ to create a new repository and <see cref="M:log4net.Core.DefaultRepositorySelector.GetRepository(System.String)"/> to retrieve
+ a repository.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.DefaultRepositorySelector.GetAllRepositories">
+ <summary>
+ Gets a list of <see cref="T:log4net.Repository.ILoggerRepository"/> objects
+ </summary>
+ <returns>an array of all known <see cref="T:log4net.Repository.ILoggerRepository"/> objects</returns>
+ <remarks>
+ <para>
+ Gets an array of all of the repositories created by this selector.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.DefaultRepositorySelector.AliasRepository(System.String,log4net.Repository.ILoggerRepository)">
+ <summary>
+ Aliases a repository to an existing repository.
+ </summary>
+ <param name="repositoryAlias">The repository to alias.</param>
+ <param name="repositoryTarget">The repository that the repository is aliased to.</param>
+ <remarks>
+ <para>
+ The repository specified will be aliased to the repository when created.
+ The repository must not already exist.
+ </para>
+ <para>
+ When the repository is created it must utilize the same repository type as
+ the repository it is aliased to, otherwise the aliasing will fail.
+ </para>
+ </remarks>
+ <exception cref="T:System.ArgumentNullException">
+ <para><paramref name="repositoryAlias"/> is <see langword="null"/>.</para>
+ <para>-or-</para>
+ <para><paramref name="repositoryTarget"/> is <see langword="null"/>.</para>
+ </exception>
+ </member>
+ <member name="M:log4net.Core.DefaultRepositorySelector.OnLoggerRepositoryCreatedEvent(log4net.Repository.ILoggerRepository)">
+ <summary>
+ Notifies the registered listeners that the repository has been created.
+ </summary>
+ <param name="repository">The repository that has been created.</param>
+ <remarks>
+ <para>
+ Raises the <see cref="E:log4net.Core.DefaultRepositorySelector.LoggerRepositoryCreatedEvent"/> event.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.DefaultRepositorySelector.GetInfoForAssembly(System.Reflection.Assembly,System.String@,System.Type@)">
+ <summary>
+ Gets the repository name and repository type for the specified assembly.
+ </summary>
+ <param name="assembly">The assembly that has a <see cref="T:log4net.Config.RepositoryAttribute"/>.</param>
+ <param name="repositoryName">in/out param to hold the repository name to use for the assembly, caller should set this to the default value before calling.</param>
+ <param name="repositoryType">in/out param to hold the type of the repository to create for the assembly, caller should set this to the default value before calling.</param>
+ <exception cref="T:System.ArgumentNullException"><paramref name="assembly"/> is <see langword="null"/>.</exception>
+ </member>
+ <member name="M:log4net.Core.DefaultRepositorySelector.ConfigureRepository(System.Reflection.Assembly,log4net.Repository.ILoggerRepository)">
+ <summary>
+ Configures the repository using information from the assembly.
+ </summary>
+ <param name="assembly">The assembly containing <see cref="T:log4net.Config.ConfiguratorAttribute"/>
+ attributes which define the configuration for the repository.</param>
+ <param name="repository">The repository to configure.</param>
+ <exception cref="T:System.ArgumentNullException">
+ <para><paramref name="assembly"/> is <see langword="null"/>.</para>
+ <para>-or-</para>
+ <para><paramref name="repository"/> is <see langword="null"/>.</para>
+ </exception>
+ </member>
+ <member name="M:log4net.Core.DefaultRepositorySelector.LoadPlugins(System.Reflection.Assembly,log4net.Repository.ILoggerRepository)">
+ <summary>
+ Loads the attribute defined plugins on the assembly.
+ </summary>
+ <param name="assembly">The assembly that contains the attributes.</param>
+ <param name="repository">The repository to add the plugins to.</param>
+ <exception cref="T:System.ArgumentNullException">
+ <para><paramref name="assembly"/> is <see langword="null"/>.</para>
+ <para>-or-</para>
+ <para><paramref name="repository"/> is <see langword="null"/>.</para>
+ </exception>
+ </member>
+ <member name="M:log4net.Core.DefaultRepositorySelector.LoadAliases(System.Reflection.Assembly,log4net.Repository.ILoggerRepository)">
+ <summary>
+ Loads the attribute defined aliases on the assembly.
+ </summary>
+ <param name="assembly">The assembly that contains the attributes.</param>
+ <param name="repository">The repository to alias to.</param>
+ <exception cref="T:System.ArgumentNullException">
+ <para><paramref name="assembly"/> is <see langword="null"/>.</para>
+ <para>-or-</para>
+ <para><paramref name="repository"/> is <see langword="null"/>.</para>
+ </exception>
+ </member>
+ <member name="E:log4net.Core.DefaultRepositorySelector.LoggerRepositoryCreatedEvent">
+ <summary>
+ Event to notify that a logger repository has been created.
+ </summary>
+ <value>
+ Event to notify that a logger repository has been created.
+ </value>
+ <remarks>
+ <para>
+ Event raised when a new repository is created.
+ The event source will be this selector. The event args will
+ be a <see cref="T:log4net.Core.LoggerRepositoryCreationEventArgs"/> which
+ holds the newly created <see cref="T:log4net.Repository.ILoggerRepository"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Core.ErrorCode">
+ <summary>
+ Defined error codes that can be passed to the <see cref="M:log4net.Core.IErrorHandler.Error(System.String,System.Exception,log4net.Core.ErrorCode)"/> method.
+ </summary>
+ <remarks>
+ <para>
+ Values passed to the <see cref="M:log4net.Core.IErrorHandler.Error(System.String,System.Exception,log4net.Core.ErrorCode)"/> method.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="F:log4net.Core.ErrorCode.GenericFailure">
+ <summary>
+ A general error
+ </summary>
+ </member>
+ <member name="F:log4net.Core.ErrorCode.WriteFailure">
+ <summary>
+ Error while writing output
+ </summary>
+ </member>
+ <member name="F:log4net.Core.ErrorCode.FlushFailure">
+ <summary>
+ Failed to flush file
+ </summary>
+ </member>
+ <member name="F:log4net.Core.ErrorCode.CloseFailure">
+ <summary>
+ Failed to close file
+ </summary>
+ </member>
+ <member name="F:log4net.Core.ErrorCode.FileOpenFailure">
+ <summary>
+ Unable to open output file
+ </summary>
+ </member>
+ <member name="F:log4net.Core.ErrorCode.MissingLayout">
+ <summary>
+ No layout specified
+ </summary>
+ </member>
+ <member name="F:log4net.Core.ErrorCode.AddressParseFailure">
+ <summary>
+ Failed to parse address
+ </summary>
+ </member>
+ <member name="T:log4net.Core.IErrorHandler">
+ <summary>
+ Appenders may delegate their error handling to an <see cref="T:log4net.Core.IErrorHandler"/>.
+ </summary>
+ <remarks>
+ <para>
+ Error handling is a particularly tedious to get right because by
+ definition errors are hard to predict and to reproduce.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="M:log4net.Core.IErrorHandler.Error(System.String,System.Exception,log4net.Core.ErrorCode)">
+ <summary>
+ Handles the error and information about the error condition is passed as
+ a parameter.
+ </summary>
+ <param name="message">The message associated with the error.</param>
+ <param name="e">The <see cref="T:System.Exception"/> that was thrown when the error occurred.</param>
+ <param name="errorCode">The error code associated with the error.</param>
+ <remarks>
+ <para>
+ Handles the error and information about the error condition is passed as
+ a parameter.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.IErrorHandler.Error(System.String,System.Exception)">
+ <summary>
+ Prints the error message passed as a parameter.
+ </summary>
+ <param name="message">The message associated with the error.</param>
+ <param name="e">The <see cref="T:System.Exception"/> that was thrown when the error occurred.</param>
+ <remarks>
+ <para>
+ See <see cref="M:log4net.Core.IErrorHandler.Error(System.String,System.Exception,log4net.Core.ErrorCode)"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.IErrorHandler.Error(System.String)">
+ <summary>
+ Prints the error message passed as a parameter.
+ </summary>
+ <param name="message">The message associated with the error.</param>
+ <remarks>
+ <para>
+ See <see cref="M:log4net.Core.IErrorHandler.Error(System.String,System.Exception,log4net.Core.ErrorCode)"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Core.IFixingRequired">
+ <summary>
+ Interface for objects that require fixing.
+ </summary>
+ <remarks>
+ <para>
+ Interface that indicates that the object requires fixing before it
+ can be taken outside the context of the appender's
+ <see cref="M:log4net.Appender.IAppender.DoAppend(log4net.Core.LoggingEvent)"/> method.
+ </para>
+ <para>
+ When objects that implement this interface are stored
+ in the context properties maps <see cref="T:log4net.GlobalContext"/>
+ <see cref="P:log4net.GlobalContext.Properties"/> and <see cref="T:log4net.ThreadContext"/>
+ <see cref="P:log4net.ThreadContext.Properties"/> are fixed
+ (see <see cref="P:log4net.Core.LoggingEvent.Fix"/>) the <see cref="M:log4net.Core.IFixingRequired.GetFixedObject"/>
+ method will be called.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="M:log4net.Core.IFixingRequired.GetFixedObject">
+ <summary>
+ Get a portable version of this object
+ </summary>
+ <returns>the portable instance of this object</returns>
+ <remarks>
+ <para>
+ Get a portable instance object that represents the current
+ state of this object. The portable object can be stored
+ and logged from any thread with identical results.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Core.ILogger">
+ <summary>
+ Interface that all loggers implement
+ </summary>
+ <remarks>
+ <para>
+ This interface supports logging events and testing if a level
+ is enabled for logging.
+ </para>
+ <para>
+ These methods will not throw exceptions. Note to implementor, ensure
+ that the implementation of these methods cannot allow an exception
+ to be thrown to the caller.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="M:log4net.Core.ILogger.Log(System.Type,log4net.Core.Level,System.Object,System.Exception)">
+ <summary>
+ This generic form is intended to be used by wrappers.
+ </summary>
+ <param name="callerStackBoundaryDeclaringType">The declaring type of the method that is
+ the stack boundary into the logging system for this call.</param>
+ <param name="level">The level of the message to be logged.</param>
+ <param name="message">The message object to log.</param>
+ <param name="exception">the exception to log, including its stack trace. Pass <c>null</c> to not log an exception.</param>
+ <remarks>
+ <para>
+ Generates a logging event for the specified <paramref name="level"/> using
+ the <paramref name="message"/> and <paramref name="exception"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.ILogger.Log(log4net.Core.LoggingEvent)">
+ <summary>
+ This is the most generic printing method that is intended to be used
+ by wrappers.
+ </summary>
+ <param name="logEvent">The event being logged.</param>
+ <remarks>
+ <para>
+ Logs the specified logging event through this logger.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.ILogger.IsEnabledFor(log4net.Core.Level)">
+ <summary>
+ Checks if this logger is enabled for a given <see cref="T:log4net.Core.Level"/> passed as parameter.
+ </summary>
+ <param name="level">The level to check.</param>
+ <returns>
+ <c>true</c> if this logger is enabled for <c>level</c>, otherwise <c>false</c>.
+ </returns>
+ <remarks>
+ <para>
+ Test if this logger is going to log events of the specified <paramref name="level"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Core.ILogger.Name">
+ <summary>
+ Gets the name of the logger.
+ </summary>
+ <value>
+ The name of the logger.
+ </value>
+ <remarks>
+ <para>
+ The name of this logger
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Core.ILogger.Repository">
+ <summary>
+ Gets the <see cref="T:log4net.Repository.ILoggerRepository"/> where this
+ <c>Logger</c> instance is attached to.
+ </summary>
+ <value>
+ The <see cref="T:log4net.Repository.ILoggerRepository"/> that this logger belongs to.
+ </value>
+ <remarks>
+ <para>
+ Gets the <see cref="T:log4net.Repository.ILoggerRepository"/> where this
+ <c>Logger</c> instance is attached to.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Core.ILoggerWrapper">
+ <summary>
+ Base interface for all wrappers
+ </summary>
+ <remarks>
+ <para>
+ Base interface for all wrappers.
+ </para>
+ <para>
+ All wrappers must implement this interface.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="P:log4net.Core.ILoggerWrapper.Logger">
+ <summary>
+ Get the implementation behind this wrapper object.
+ </summary>
+ <value>
+ The <see cref="T:log4net.Core.ILogger"/> object that in implementing this object.
+ </value>
+ <remarks>
+ <para>
+ The <see cref="T:log4net.Core.ILogger"/> object that in implementing this
+ object. The <c>Logger</c> object may not
+ be the same object as this object because of logger decorators.
+ This gets the actual underlying objects that is used to process
+ the log events.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Core.LoggerRepositoryCreationEventHandler">
+ <summary>
+ Delegate used to handle logger repository creation event notifications
+ </summary>
+ <param name="sender">The <see cref="T:log4net.Core.IRepositorySelector"/> which created the repository.</param>
+ <param name="e">The <see cref="T:log4net.Core.LoggerRepositoryCreationEventArgs"/> event args
+ that holds the <see cref="T:log4net.Repository.ILoggerRepository"/> instance that has been created.</param>
+ <remarks>
+ <para>
+ Delegate used to handle logger repository creation event notifications.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Core.LoggerRepositoryCreationEventArgs">
+ <summary>
+ Provides data for the <see cref="E:log4net.Core.IRepositorySelector.LoggerRepositoryCreatedEvent"/> event.
+ </summary>
+ <remarks>
+ <para>
+ A <see cref="E:log4net.Core.IRepositorySelector.LoggerRepositoryCreatedEvent"/>
+ event is raised every time a <see cref="T:log4net.Repository.ILoggerRepository"/> is created.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Core.LoggerRepositoryCreationEventArgs.m_repository">
+ <summary>
+ The <see cref="T:log4net.Repository.ILoggerRepository"/> created
+ </summary>
+ </member>
+ <member name="M:log4net.Core.LoggerRepositoryCreationEventArgs.#ctor(log4net.Repository.ILoggerRepository)">
+ <summary>
+ Construct instance using <see cref="T:log4net.Repository.ILoggerRepository"/> specified
+ </summary>
+ <param name="repository">the <see cref="T:log4net.Repository.ILoggerRepository"/> that has been created</param>
+ <remarks>
+ <para>
+ Construct instance using <see cref="T:log4net.Repository.ILoggerRepository"/> specified
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Core.LoggerRepositoryCreationEventArgs.LoggerRepository">
+ <summary>
+ The <see cref="T:log4net.Repository.ILoggerRepository"/> that has been created
+ </summary>
+ <value>
+ The <see cref="T:log4net.Repository.ILoggerRepository"/> that has been created
+ </value>
+ <remarks>
+ <para>
+ The <see cref="T:log4net.Repository.ILoggerRepository"/> that has been created
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Core.ITriggeringEventEvaluator">
+ <summary>
+ Test if an <see cref="T:log4net.Core.LoggingEvent"/> triggers an action
+ </summary>
+ <remarks>
+ <para>
+ Implementations of this interface allow certain appenders to decide
+ when to perform an appender specific action.
+ </para>
+ <para>
+ The action or behavior triggered is defined by the implementation.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="M:log4net.Core.ITriggeringEventEvaluator.IsTriggeringEvent(log4net.Core.LoggingEvent)">
+ <summary>
+ Test if this event triggers the action
+ </summary>
+ <param name="loggingEvent">The event to check</param>
+ <returns><c>true</c> if this event triggers the action, otherwise <c>false</c></returns>
+ <remarks>
+ <para>
+ Return <c>true</c> if this event triggers the action
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Core.Level">
+ <summary>
+ Defines the default set of levels recognized by the system.
+ </summary>
+ <remarks>
+ <para>
+ Each <see cref="T:log4net.Core.LoggingEvent"/> has an associated <see cref="T:log4net.Core.Level"/>.
+ </para>
+ <para>
+ Levels have a numeric <see cref="P:log4net.Core.Level.Value"/> that defines the relative
+ ordering between levels. Two Levels with the same <see cref="P:log4net.Core.Level.Value"/>
+ are deemed to be equivalent.
+ </para>
+ <para>
+ The levels that are recognized by log4net are set for each <see cref="T:log4net.Repository.ILoggerRepository"/>
+ and each repository can have different levels defined. The levels are stored
+ in the <see cref="P:log4net.Repository.ILoggerRepository.LevelMap"/> on the repository. Levels are
+ looked up by name from the <see cref="P:log4net.Repository.ILoggerRepository.LevelMap"/>.
+ </para>
+ <para>
+ When logging at level INFO the actual level used is not <see cref="F:log4net.Core.Level.Info"/> but
+ the value of <c>LoggerRepository.LevelMap["INFO"]</c>. The default value for this is
+ <see cref="F:log4net.Core.Level.Info"/>, but this can be changed by reconfiguring the level map.
+ </para>
+ <para>
+ Each level has a <see cref="P:log4net.Core.Level.DisplayName"/> in addition to its <see cref="P:log4net.Core.Level.Name"/>. The
+ <see cref="P:log4net.Core.Level.DisplayName"/> is the string that is written into the output log. By default
+ the display name is the same as the level name, but this can be used to alias levels
+ or to localize the log output.
+ </para>
+ <para>
+ Some of the predefined levels recognized by the system are:
+ </para>
+ <list type="bullet">
+ <item>
+ <description><see cref="F:log4net.Core.Level.Off"/>.</description>
+ </item>
+ <item>
+ <description><see cref="F:log4net.Core.Level.Fatal"/>.</description>
+ </item>
+ <item>
+ <description><see cref="F:log4net.Core.Level.Error"/>.</description>
+ </item>
+ <item>
+ <description><see cref="F:log4net.Core.Level.Warn"/>.</description>
+ </item>
+ <item>
+ <description><see cref="F:log4net.Core.Level.Info"/>.</description>
+ </item>
+ <item>
+ <description><see cref="F:log4net.Core.Level.Debug"/>.</description>
+ </item>
+ <item>
+ <description><see cref="F:log4net.Core.Level.All"/>.</description>
+ </item>
+ </list>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="M:log4net.Core.Level.#ctor(System.Int32,System.String,System.String)">
+ <summary>
+ Constructor
+ </summary>
+ <param name="level">Integer value for this level, higher values represent more severe levels.</param>
+ <param name="levelName">The string name of this level.</param>
+ <param name="displayName">The display name for this level. This may be localized or otherwise different from the name</param>
+ <remarks>
+ <para>
+ Initializes a new instance of the <see cref="T:log4net.Core.Level"/> class with
+ the specified level name and value.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.Level.#ctor(System.Int32,System.String)">
+ <summary>
+ Constructor
+ </summary>
+ <param name="level">Integer value for this level, higher values represent more severe levels.</param>
+ <param name="levelName">The string name of this level.</param>
+ <remarks>
+ <para>
+ Initializes a new instance of the <see cref="T:log4net.Core.Level"/> class with
+ the specified level name and value.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.Level.ToString">
+ <summary>
+ Returns the <see cref="T:System.String"/> representation of the current
+ <see cref="T:log4net.Core.Level"/>.
+ </summary>
+ <returns>
+ A <see cref="T:System.String"/> representation of the current <see cref="T:log4net.Core.Level"/>.
+ </returns>
+ <remarks>
+ <para>
+ Returns the level <see cref="P:log4net.Core.Level.Name"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.Level.Equals(System.Object)">
+ <summary>
+ Compares levels.
+ </summary>
+ <param name="o">The object to compare against.</param>
+ <returns><c>true</c> if the objects are equal.</returns>
+ <remarks>
+ <para>
+ Compares the levels of <see cref="T:log4net.Core.Level"/> instances, and
+ defers to base class if the target object is not a <see cref="T:log4net.Core.Level"/>
+ instance.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.Level.GetHashCode">
+ <summary>
+ Returns a hash code
+ </summary>
+ <returns>A hash code for the current <see cref="T:log4net.Core.Level"/>.</returns>
+ <remarks>
+ <para>
+ Returns a hash code suitable for use in hashing algorithms and data
+ structures like a hash table.
+ </para>
+ <para>
+ Returns the hash code of the level <see cref="P:log4net.Core.Level.Value"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.Level.CompareTo(System.Object)">
+ <summary>
+ Compares this instance to a specified object and returns an
+ indication of their relative values.
+ </summary>
+ <param name="r">A <see cref="T:log4net.Core.Level"/> instance or <see langword="null"/> to compare with this instance.</param>
+ <returns>
+ A 32-bit signed integer that indicates the relative order of the
+ values compared. The return value has these meanings:
+ <list type="table">
+ <listheader>
+ <term>Value</term>
+ <description>Meaning</description>
+ </listheader>
+ <item>
+ <term>Less than zero</term>
+ <description>This instance is less than <paramref name="r"/>.</description>
+ </item>
+ <item>
+ <term>Zero</term>
+ <description>This instance is equal to <paramref name="r"/>.</description>
+ </item>
+ <item>
+ <term>Greater than zero</term>
+ <description>
+ <para>This instance is greater than <paramref name="r"/>.</para>
+ <para>-or-</para>
+ <para><paramref name="r"/> is <see langword="null"/>.</para>
+ </description>
+ </item>
+ </list>
+ </returns>
+ <remarks>
+ <para>
+ <paramref name="r"/> must be an instance of <see cref="T:log4net.Core.Level"/>
+ or <see langword="null"/>; otherwise, an exception is thrown.
+ </para>
+ </remarks>
+ <exception cref="T:System.ArgumentException"><paramref name="r"/> is not a <see cref="T:log4net.Core.Level"/>.</exception>
+ </member>
+ <member name="M:log4net.Core.Level.op_GreaterThan(log4net.Core.Level,log4net.Core.Level)">
+ <summary>
+ Returns a value indicating whether a specified <see cref="T:log4net.Core.Level"/>
+ is greater than another specified <see cref="T:log4net.Core.Level"/>.
+ </summary>
+ <param name="l">A <see cref="T:log4net.Core.Level"/></param>
+ <param name="r">A <see cref="T:log4net.Core.Level"/></param>
+ <returns>
+ <c>true</c> if <paramref name="l"/> is greater than
+ <paramref name="r"/>; otherwise, <c>false</c>.
+ </returns>
+ <remarks>
+ <para>
+ Compares two levels.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.Level.op_LessThan(log4net.Core.Level,log4net.Core.Level)">
+ <summary>
+ Returns a value indicating whether a specified <see cref="T:log4net.Core.Level"/>
+ is less than another specified <see cref="T:log4net.Core.Level"/>.
+ </summary>
+ <param name="l">A <see cref="T:log4net.Core.Level"/></param>
+ <param name="r">A <see cref="T:log4net.Core.Level"/></param>
+ <returns>
+ <c>true</c> if <paramref name="l"/> is less than
+ <paramref name="r"/>; otherwise, <c>false</c>.
+ </returns>
+ <remarks>
+ <para>
+ Compares two levels.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.Level.op_GreaterThanOrEqual(log4net.Core.Level,log4net.Core.Level)">
+ <summary>
+ Returns a value indicating whether a specified <see cref="T:log4net.Core.Level"/>
+ is greater than or equal to another specified <see cref="T:log4net.Core.Level"/>.
+ </summary>
+ <param name="l">A <see cref="T:log4net.Core.Level"/></param>
+ <param name="r">A <see cref="T:log4net.Core.Level"/></param>
+ <returns>
+ <c>true</c> if <paramref name="l"/> is greater than or equal to
+ <paramref name="r"/>; otherwise, <c>false</c>.
+ </returns>
+ <remarks>
+ <para>
+ Compares two levels.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.Level.op_LessThanOrEqual(log4net.Core.Level,log4net.Core.Level)">
+ <summary>
+ Returns a value indicating whether a specified <see cref="T:log4net.Core.Level"/>
+ is less than or equal to another specified <see cref="T:log4net.Core.Level"/>.
+ </summary>
+ <param name="l">A <see cref="T:log4net.Core.Level"/></param>
+ <param name="r">A <see cref="T:log4net.Core.Level"/></param>
+ <returns>
+ <c>true</c> if <paramref name="l"/> is less than or equal to
+ <paramref name="r"/>; otherwise, <c>false</c>.
+ </returns>
+ <remarks>
+ <para>
+ Compares two levels.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.Level.op_Equality(log4net.Core.Level,log4net.Core.Level)">
+ <summary>
+ Returns a value indicating whether two specified <see cref="T:log4net.Core.Level"/>
+ objects have the same value.
+ </summary>
+ <param name="l">A <see cref="T:log4net.Core.Level"/> or <see langword="null"/>.</param>
+ <param name="r">A <see cref="T:log4net.Core.Level"/> or <see langword="null"/>.</param>
+ <returns>
+ <c>true</c> if the value of <paramref name="l"/> is the same as the
+ value of <paramref name="r"/>; otherwise, <c>false</c>.
+ </returns>
+ <remarks>
+ <para>
+ Compares two levels.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.Level.op_Inequality(log4net.Core.Level,log4net.Core.Level)">
+ <summary>
+ Returns a value indicating whether two specified <see cref="T:log4net.Core.Level"/>
+ objects have different values.
+ </summary>
+ <param name="l">A <see cref="T:log4net.Core.Level"/> or <see langword="null"/>.</param>
+ <param name="r">A <see cref="T:log4net.Core.Level"/> or <see langword="null"/>.</param>
+ <returns>
+ <c>true</c> if the value of <paramref name="l"/> is different from
+ the value of <paramref name="r"/>; otherwise, <c>false</c>.
+ </returns>
+ <remarks>
+ <para>
+ Compares two levels.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.Level.Compare(log4net.Core.Level,log4net.Core.Level)">
+ <summary>
+ Compares two specified <see cref="T:log4net.Core.Level"/> instances.
+ </summary>
+ <param name="l">The first <see cref="T:log4net.Core.Level"/> to compare.</param>
+ <param name="r">The second <see cref="T:log4net.Core.Level"/> to compare.</param>
+ <returns>
+ A 32-bit signed integer that indicates the relative order of the
+ two values compared. The return value has these meanings:
+ <list type="table">
+ <listheader>
+ <term>Value</term>
+ <description>Meaning</description>
+ </listheader>
+ <item>
+ <term>Less than zero</term>
+ <description><paramref name="l"/> is less than <paramref name="r"/>.</description>
+ </item>
+ <item>
+ <term>Zero</term>
+ <description><paramref name="l"/> is equal to <paramref name="r"/>.</description>
+ </item>
+ <item>
+ <term>Greater than zero</term>
+ <description><paramref name="l"/> is greater than <paramref name="r"/>.</description>
+ </item>
+ </list>
+ </returns>
+ <remarks>
+ <para>
+ Compares two levels.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Core.Level.Off">
+ <summary>
+ The <see cref="F:log4net.Core.Level.Off"/> level designates a higher level than all the rest.
+ </summary>
+ </member>
+ <member name="F:log4net.Core.Level.Emergency">
+ <summary>
+ The <see cref="F:log4net.Core.Level.Emergency"/> level designates very severe error events.
+ System unusable, emergencies.
+ </summary>
+ </member>
+ <member name="F:log4net.Core.Level.Fatal">
+ <summary>
+ The <see cref="F:log4net.Core.Level.Fatal"/> level designates very severe error events
+ that will presumably lead the application to abort.
+ </summary>
+ </member>
+ <member name="F:log4net.Core.Level.Alert">
+ <summary>
+ The <see cref="F:log4net.Core.Level.Alert"/> level designates very severe error events.
+ Take immediate action, alerts.
+ </summary>
+ </member>
+ <member name="F:log4net.Core.Level.Critical">
+ <summary>
+ The <see cref="F:log4net.Core.Level.Critical"/> level designates very severe error events.
+ Critical condition, critical.
+ </summary>
+ </member>
+ <member name="F:log4net.Core.Level.Severe">
+ <summary>
+ The <see cref="F:log4net.Core.Level.Severe"/> level designates very severe error events.
+ </summary>
+ </member>
+ <member name="F:log4net.Core.Level.Error">
+ <summary>
+ The <see cref="F:log4net.Core.Level.Error"/> level designates error events that might
+ still allow the application to continue running.
+ </summary>
+ </member>
+ <member name="F:log4net.Core.Level.Warn">
+ <summary>
+ The <see cref="F:log4net.Core.Level.Warn"/> level designates potentially harmful
+ situations.
+ </summary>
+ </member>
+ <member name="F:log4net.Core.Level.Notice">
+ <summary>
+ The <see cref="F:log4net.Core.Level.Notice"/> level designates informational messages
+ that highlight the progress of the application at the highest level.
+ </summary>
+ </member>
+ <member name="F:log4net.Core.Level.Info">
+ <summary>
+ The <see cref="F:log4net.Core.Level.Info"/> level designates informational messages that
+ highlight the progress of the application at coarse-grained level.
+ </summary>
+ </member>
+ <member name="F:log4net.Core.Level.Debug">
+ <summary>
+ The <see cref="F:log4net.Core.Level.Debug"/> level designates fine-grained informational
+ events that are most useful to debug an application.
+ </summary>
+ </member>
+ <member name="F:log4net.Core.Level.Fine">
+ <summary>
+ The <see cref="F:log4net.Core.Level.Fine"/> level designates fine-grained informational
+ events that are most useful to debug an application.
+ </summary>
+ </member>
+ <member name="F:log4net.Core.Level.Trace">
+ <summary>
+ The <see cref="F:log4net.Core.Level.Trace"/> level designates fine-grained informational
+ events that are most useful to debug an application.
+ </summary>
+ </member>
+ <member name="F:log4net.Core.Level.Finer">
+ <summary>
+ The <see cref="F:log4net.Core.Level.Finer"/> level designates fine-grained informational
+ events that are most useful to debug an application.
+ </summary>
+ </member>
+ <member name="F:log4net.Core.Level.Verbose">
+ <summary>
+ The <see cref="F:log4net.Core.Level.Verbose"/> level designates fine-grained informational
+ events that are most useful to debug an application.
+ </summary>
+ </member>
+ <member name="F:log4net.Core.Level.Finest">
+ <summary>
+ The <see cref="F:log4net.Core.Level.Finest"/> level designates fine-grained informational
+ events that are most useful to debug an application.
+ </summary>
+ </member>
+ <member name="F:log4net.Core.Level.All">
+ <summary>
+ The <see cref="F:log4net.Core.Level.All"/> level designates the lowest level possible.
+ </summary>
+ </member>
+ <member name="P:log4net.Core.Level.Name">
+ <summary>
+ Gets the name of this level.
+ </summary>
+ <value>
+ The name of this level.
+ </value>
+ <remarks>
+ <para>
+ Gets the name of this level.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Core.Level.Value">
+ <summary>
+ Gets the value of this level.
+ </summary>
+ <value>
+ The value of this level.
+ </value>
+ <remarks>
+ <para>
+ Gets the value of this level.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Core.Level.DisplayName">
+ <summary>
+ Gets the display name of this level.
+ </summary>
+ <value>
+ The display name of this level.
+ </value>
+ <remarks>
+ <para>
+ Gets the display name of this level.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Core.LevelCollection">
+ <summary>
+ A strongly-typed collection of <see cref="T:log4net.Core.Level"/> objects.
+ </summary>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="M:log4net.Core.LevelCollection.ReadOnly(log4net.Core.LevelCollection)">
+ <summary>
+ Creates a read-only wrapper for a <c>LevelCollection</c> instance.
+ </summary>
+ <param name="list">list to create a readonly wrapper arround</param>
+ <returns>
+ A <c>LevelCollection</c> wrapper that is read-only.
+ </returns>
+ </member>
+ <member name="M:log4net.Core.LevelCollection.#ctor">
+ <summary>
+ Initializes a new instance of the <c>LevelCollection</c> class
+ that is empty and has the default initial capacity.
+ </summary>
+ </member>
+ <member name="M:log4net.Core.LevelCollection.#ctor(System.Int32)">
+ <summary>
+ Initializes a new instance of the <c>LevelCollection</c> class
+ that has the specified initial capacity.
+ </summary>
+ <param name="capacity">
+ The number of elements that the new <c>LevelCollection</c> is initially capable of storing.
+ </param>
+ </member>
+ <member name="M:log4net.Core.LevelCollection.#ctor(log4net.Core.LevelCollection)">
+ <summary>
+ Initializes a new instance of the <c>LevelCollection</c> class
+ that contains elements copied from the specified <c>LevelCollection</c>.
+ </summary>
+ <param name="c">The <c>LevelCollection</c> whose elements are copied to the new collection.</param>
+ </member>
+ <member name="M:log4net.Core.LevelCollection.#ctor(log4net.Core.Level[])">
+ <summary>
+ Initializes a new instance of the <c>LevelCollection</c> class
+ that contains elements copied from the specified <see cref="T:log4net.Core.Level"/> array.
+ </summary>
+ <param name="a">The <see cref="T:log4net.Core.Level"/> array whose elements are copied to the new list.</param>
+ </member>
+ <member name="M:log4net.Core.LevelCollection.#ctor(System.Collections.ICollection)">
+ <summary>
+ Initializes a new instance of the <c>LevelCollection</c> class
+ that contains elements copied from the specified <see cref="T:log4net.Core.Level"/> collection.
+ </summary>
+ <param name="col">The <see cref="T:log4net.Core.Level"/> collection whose elements are copied to the new list.</param>
+ </member>
+ <member name="M:log4net.Core.LevelCollection.#ctor(log4net.Core.LevelCollection.Tag)">
+ <summary>
+ Allow subclasses to avoid our default constructors
+ </summary>
+ <param name="tag"></param>
+ </member>
+ <member name="M:log4net.Core.LevelCollection.CopyTo(log4net.Core.Level[])">
+ <summary>
+ Copies the entire <c>LevelCollection</c> to a one-dimensional
+ <see cref="T:log4net.Core.Level"/> array.
+ </summary>
+ <param name="array">The one-dimensional <see cref="T:log4net.Core.Level"/> array to copy to.</param>
+ </member>
+ <member name="M:log4net.Core.LevelCollection.CopyTo(log4net.Core.Level[],System.Int32)">
+ <summary>
+ Copies the entire <c>LevelCollection</c> to a one-dimensional
+ <see cref="T:log4net.Core.Level"/> array, starting at the specified index of the target array.
+ </summary>
+ <param name="array">The one-dimensional <see cref="T:log4net.Core.Level"/> array to copy to.</param>
+ <param name="start">The zero-based index in <paramref name="array"/> at which copying begins.</param>
+ </member>
+ <member name="M:log4net.Core.LevelCollection.Add(log4net.Core.Level)">
+ <summary>
+ Adds a <see cref="T:log4net.Core.Level"/> to the end of the <c>LevelCollection</c>.
+ </summary>
+ <param name="item">The <see cref="T:log4net.Core.Level"/> to be added to the end of the <c>LevelCollection</c>.</param>
+ <returns>The index at which the value has been added.</returns>
+ </member>
+ <member name="M:log4net.Core.LevelCollection.Clear">
+ <summary>
+ Removes all elements from the <c>LevelCollection</c>.
+ </summary>
+ </member>
+ <member name="M:log4net.Core.LevelCollection.Clone">
+ <summary>
+ Creates a shallow copy of the <see cref="T:log4net.Core.LevelCollection"/>.
+ </summary>
+ <returns>A new <see cref="T:log4net.Core.LevelCollection"/> with a shallow copy of the collection data.</returns>
+ </member>
+ <member name="M:log4net.Core.LevelCollection.Contains(log4net.Core.Level)">
+ <summary>
+ Determines whether a given <see cref="T:log4net.Core.Level"/> is in the <c>LevelCollection</c>.
+ </summary>
+ <param name="item">The <see cref="T:log4net.Core.Level"/> to check for.</param>
+ <returns><c>true</c> if <paramref name="item"/> is found in the <c>LevelCollection</c>; otherwise, <c>false</c>.</returns>
+ </member>
+ <member name="M:log4net.Core.LevelCollection.IndexOf(log4net.Core.Level)">
+ <summary>
+ Returns the zero-based index of the first occurrence of a <see cref="T:log4net.Core.Level"/>
+ in the <c>LevelCollection</c>.
+ </summary>
+ <param name="item">The <see cref="T:log4net.Core.Level"/> to locate in the <c>LevelCollection</c>.</param>
+ <returns>
+ The zero-based index of the first occurrence of <paramref name="item"/>
+ in the entire <c>LevelCollection</c>, if found; otherwise, -1.
+ </returns>
+ </member>
+ <member name="M:log4net.Core.LevelCollection.Insert(System.Int32,log4net.Core.Level)">
+ <summary>
+ Inserts an element into the <c>LevelCollection</c> at the specified index.
+ </summary>
+ <param name="index">The zero-based index at which <paramref name="item"/> should be inserted.</param>
+ <param name="item">The <see cref="T:log4net.Core.Level"/> to insert.</param>
+ <exception cref="T:System.ArgumentOutOfRangeException">
+ <para><paramref name="index"/> is less than zero</para>
+ <para>-or-</para>
+ <para><paramref name="index"/> is equal to or greater than <see cref="P:log4net.Core.LevelCollection.Count"/>.</para>
+ </exception>
+ </member>
+ <member name="M:log4net.Core.LevelCollection.Remove(log4net.Core.Level)">
+ <summary>
+ Removes the first occurrence of a specific <see cref="T:log4net.Core.Level"/> from the <c>LevelCollection</c>.
+ </summary>
+ <param name="item">The <see cref="T:log4net.Core.Level"/> to remove from the <c>LevelCollection</c>.</param>
+ <exception cref="T:System.ArgumentException">
+ The specified <see cref="T:log4net.Core.Level"/> was not found in the <c>LevelCollection</c>.
+ </exception>
+ </member>
+ <member name="M:log4net.Core.LevelCollection.RemoveAt(System.Int32)">
+ <summary>
+ Removes the element at the specified index of the <c>LevelCollection</c>.
+ </summary>
+ <param name="index">The zero-based index of the element to remove.</param>
+ <exception cref="T:System.ArgumentOutOfRangeException">
+ <para><paramref name="index"/> is less than zero</para>
+ <para>-or-</para>
+ <para><paramref name="index"/> is equal to or greater than <see cref="P:log4net.Core.LevelCollection.Count"/>.</para>
+ </exception>
+ </member>
+ <member name="M:log4net.Core.LevelCollection.GetEnumerator">
+ <summary>
+ Returns an enumerator that can iterate through the <c>LevelCollection</c>.
+ </summary>
+ <returns>An <see cref="T:log4net.Core.LevelCollection.Enumerator"/> for the entire <c>LevelCollection</c>.</returns>
+ </member>
+ <member name="M:log4net.Core.LevelCollection.AddRange(log4net.Core.LevelCollection)">
+ <summary>
+ Adds the elements of another <c>LevelCollection</c> to the current <c>LevelCollection</c>.
+ </summary>
+ <param name="x">The <c>LevelCollection</c> whose elements should be added to the end of the current <c>LevelCollection</c>.</param>
+ <returns>The new <see cref="P:log4net.Core.LevelCollection.Count"/> of the <c>LevelCollection</c>.</returns>
+ </member>
+ <member name="M:log4net.Core.LevelCollection.AddRange(log4net.Core.Level[])">
+ <summary>
+ Adds the elements of a <see cref="T:log4net.Core.Level"/> array to the current <c>LevelCollection</c>.
+ </summary>
+ <param name="x">The <see cref="T:log4net.Core.Level"/> array whose elements should be added to the end of the <c>LevelCollection</c>.</param>
+ <returns>The new <see cref="P:log4net.Core.LevelCollection.Count"/> of the <c>LevelCollection</c>.</returns>
+ </member>
+ <member name="M:log4net.Core.LevelCollection.AddRange(System.Collections.ICollection)">
+ <summary>
+ Adds the elements of a <see cref="T:log4net.Core.Level"/> collection to the current <c>LevelCollection</c>.
+ </summary>
+ <param name="col">The <see cref="T:log4net.Core.Level"/> collection whose elements should be added to the end of the <c>LevelCollection</c>.</param>
+ <returns>The new <see cref="P:log4net.Core.LevelCollection.Count"/> of the <c>LevelCollection</c>.</returns>
+ </member>
+ <member name="M:log4net.Core.LevelCollection.TrimToSize">
+ <summary>
+ Sets the capacity to the actual number of elements.
+ </summary>
+ </member>
+ <member name="M:log4net.Core.LevelCollection.ValidateIndex(System.Int32)">
+ <exception cref="T:System.ArgumentOutOfRangeException">
+ <para><paramref name="index"/> is less than zero</para>
+ <para>-or-</para>
+ <para><paramref name="index"/> is equal to or greater than <see cref="P:log4net.Core.LevelCollection.Count"/>.</para>
+ </exception>
+ </member>
+ <member name="M:log4net.Core.LevelCollection.ValidateIndex(System.Int32,System.Boolean)">
+ <exception cref="T:System.ArgumentOutOfRangeException">
+ <para><paramref name="index"/> is less than zero</para>
+ <para>-or-</para>
+ <para><paramref name="index"/> is equal to or greater than <see cref="P:log4net.Core.LevelCollection.Count"/>.</para>
+ </exception>
+ </member>
+ <member name="P:log4net.Core.LevelCollection.Count">
+ <summary>
+ Gets the number of elements actually contained in the <c>LevelCollection</c>.
+ </summary>
+ </member>
+ <member name="P:log4net.Core.LevelCollection.IsSynchronized">
+ <summary>
+ Gets a value indicating whether access to the collection is synchronized (thread-safe).
+ </summary>
+ <value>true if access to the ICollection is synchronized (thread-safe); otherwise, false.</value>
+ </member>
+ <member name="P:log4net.Core.LevelCollection.SyncRoot">
+ <summary>
+ Gets an object that can be used to synchronize access to the collection.
+ </summary>
+ </member>
+ <member name="P:log4net.Core.LevelCollection.Item(System.Int32)">
+ <summary>
+ Gets or sets the <see cref="T:log4net.Core.Level"/> at the specified index.
+ </summary>
+ <param name="index">The zero-based index of the element to get or set.</param>
+ <exception cref="T:System.ArgumentOutOfRangeException">
+ <para><paramref name="index"/> is less than zero</para>
+ <para>-or-</para>
+ <para><paramref name="index"/> is equal to or greater than <see cref="P:log4net.Core.LevelCollection.Count"/>.</para>
+ </exception>
+ </member>
+ <member name="P:log4net.Core.LevelCollection.IsFixedSize">
+ <summary>
+ Gets a value indicating whether the collection has a fixed size.
+ </summary>
+ <value>true if the collection has a fixed size; otherwise, false. The default is false</value>
+ </member>
+ <member name="P:log4net.Core.LevelCollection.IsReadOnly">
+ <summary>
+ Gets a value indicating whether the IList is read-only.
+ </summary>
+ <value>true if the collection is read-only; otherwise, false. The default is false</value>
+ </member>
+ <member name="P:log4net.Core.LevelCollection.Capacity">
+ <summary>
+ Gets or sets the number of elements the <c>LevelCollection</c> can contain.
+ </summary>
+ </member>
+ <member name="T:log4net.Core.LevelCollection.ILevelCollectionEnumerator">
+ <summary>
+ Supports type-safe iteration over a <see cref="T:log4net.Core.LevelCollection"/>.
+ </summary>
+ </member>
+ <member name="M:log4net.Core.LevelCollection.ILevelCollectionEnumerator.MoveNext">
+ <summary>
+ Advances the enumerator to the next element in the collection.
+ </summary>
+ <returns>
+ <c>true</c> if the enumerator was successfully advanced to the next element;
+ <c>false</c> if the enumerator has passed the end of the collection.
+ </returns>
+ <exception cref="T:System.InvalidOperationException">
+ The collection was modified after the enumerator was created.
+ </exception>
+ </member>
+ <member name="M:log4net.Core.LevelCollection.ILevelCollectionEnumerator.Reset">
+ <summary>
+ Sets the enumerator to its initial position, before the first element in the collection.
+ </summary>
+ </member>
+ <member name="P:log4net.Core.LevelCollection.ILevelCollectionEnumerator.Current">
+ <summary>
+ Gets the current element in the collection.
+ </summary>
+ </member>
+ <member name="T:log4net.Core.LevelCollection.Tag">
+ <summary>
+ Type visible only to our subclasses
+ Used to access protected constructor
+ </summary>
+ </member>
+ <member name="F:log4net.Core.LevelCollection.Tag.Default">
+ <summary>
+ A value
+ </summary>
+ </member>
+ <member name="T:log4net.Core.LevelCollection.Enumerator">
+ <summary>
+ Supports simple iteration over a <see cref="T:log4net.Core.LevelCollection"/>.
+ </summary>
+ </member>
+ <member name="M:log4net.Core.LevelCollection.Enumerator.#ctor(log4net.Core.LevelCollection)">
+ <summary>
+ Initializes a new instance of the <c>Enumerator</c> class.
+ </summary>
+ <param name="tc"></param>
+ </member>
+ <member name="M:log4net.Core.LevelCollection.Enumerator.MoveNext">
+ <summary>
+ Advances the enumerator to the next element in the collection.
+ </summary>
+ <returns>
+ <c>true</c> if the enumerator was successfully advanced to the next element;
+ <c>false</c> if the enumerator has passed the end of the collection.
+ </returns>
+ <exception cref="T:System.InvalidOperationException">
+ The collection was modified after the enumerator was created.
+ </exception>
+ </member>
+ <member name="M:log4net.Core.LevelCollection.Enumerator.Reset">
+ <summary>
+ Sets the enumerator to its initial position, before the first element in the collection.
+ </summary>
+ </member>
+ <member name="P:log4net.Core.LevelCollection.Enumerator.Current">
+ <summary>
+ Gets the current element in the collection.
+ </summary>
+ </member>
+ <member name="T:log4net.Core.LevelEvaluator">
+ <summary>
+ An evaluator that triggers at a threshold level
+ </summary>
+ <remarks>
+ <para>
+ This evaluator will trigger if the level of the event
+ passed to <see cref="M:log4net.Core.LevelEvaluator.IsTriggeringEvent(log4net.Core.LoggingEvent)"/>
+ is equal to or greater than the <see cref="P:log4net.Core.LevelEvaluator.Threshold"/>
+ level.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="F:log4net.Core.LevelEvaluator.m_threshold">
+ <summary>
+ The threshold for triggering
+ </summary>
+ </member>
+ <member name="M:log4net.Core.LevelEvaluator.#ctor">
+ <summary>
+ Create a new evaluator using the <see cref="F:log4net.Core.Level.Off"/> threshold.
+ </summary>
+ <remarks>
+ <para>
+ Create a new evaluator using the <see cref="F:log4net.Core.Level.Off"/> threshold.
+ </para>
+ <para>
+ This evaluator will trigger if the level of the event
+ passed to <see cref="M:log4net.Core.LevelEvaluator.IsTriggeringEvent(log4net.Core.LoggingEvent)"/>
+ is equal to or greater than the <see cref="P:log4net.Core.LevelEvaluator.Threshold"/>
+ level.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LevelEvaluator.#ctor(log4net.Core.Level)">
+ <summary>
+ Create a new evaluator using the specified <see cref="T:log4net.Core.Level"/> threshold.
+ </summary>
+ <param name="threshold">the threshold to trigger at</param>
+ <remarks>
+ <para>
+ Create a new evaluator using the specified <see cref="T:log4net.Core.Level"/> threshold.
+ </para>
+ <para>
+ This evaluator will trigger if the level of the event
+ passed to <see cref="M:log4net.Core.LevelEvaluator.IsTriggeringEvent(log4net.Core.LoggingEvent)"/>
+ is equal to or greater than the <see cref="P:log4net.Core.LevelEvaluator.Threshold"/>
+ level.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LevelEvaluator.IsTriggeringEvent(log4net.Core.LoggingEvent)">
+ <summary>
+ Is this <paramref name="loggingEvent"/> the triggering event?
+ </summary>
+ <param name="loggingEvent">The event to check</param>
+ <returns>This method returns <c>true</c>, if the event level
+ is equal or higher than the <see cref="P:log4net.Core.LevelEvaluator.Threshold"/>.
+ Otherwise it returns <c>false</c></returns>
+ <remarks>
+ <para>
+ This evaluator will trigger if the level of the event
+ passed to <see cref="M:log4net.Core.LevelEvaluator.IsTriggeringEvent(log4net.Core.LoggingEvent)"/>
+ is equal to or greater than the <see cref="P:log4net.Core.LevelEvaluator.Threshold"/>
+ level.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Core.LevelEvaluator.Threshold">
+ <summary>
+ the threshold to trigger at
+ </summary>
+ <value>
+ The <see cref="T:log4net.Core.Level"/> that will cause this evaluator to trigger
+ </value>
+ <remarks>
+ <para>
+ This evaluator will trigger if the level of the event
+ passed to <see cref="M:log4net.Core.LevelEvaluator.IsTriggeringEvent(log4net.Core.LoggingEvent)"/>
+ is equal to or greater than the <see cref="P:log4net.Core.LevelEvaluator.Threshold"/>
+ level.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Core.LevelMap">
+ <summary>
+ Mapping between string name and Level object
+ </summary>
+ <remarks>
+ <para>
+ Mapping between string name and <see cref="T:log4net.Core.Level"/> object.
+ This mapping is held separately for each <see cref="T:log4net.Repository.ILoggerRepository"/>.
+ The level name is case insensitive.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="F:log4net.Core.LevelMap.m_mapName2Level">
+ <summary>
+ Mapping from level name to Level object. The
+ level name is case insensitive
+ </summary>
+ </member>
+ <member name="M:log4net.Core.LevelMap.#ctor">
+ <summary>
+ Construct the level map
+ </summary>
+ <remarks>
+ <para>
+ Construct the level map.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LevelMap.Clear">
+ <summary>
+ Clear the internal maps of all levels
+ </summary>
+ <remarks>
+ <para>
+ Clear the internal maps of all levels
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LevelMap.Add(System.String,System.Int32)">
+ <summary>
+ Create a new Level and add it to the map
+ </summary>
+ <param name="name">the string to display for the Level</param>
+ <param name="value">the level value to give to the Level</param>
+ <remarks>
+ <para>
+ Create a new Level and add it to the map
+ </para>
+ </remarks>
+ <seealso cref="M:log4net.Core.LevelMap.Add(System.String,System.Int32,System.String)"/>
+ </member>
+ <member name="M:log4net.Core.LevelMap.Add(System.String,System.Int32,System.String)">
+ <summary>
+ Create a new Level and add it to the map
+ </summary>
+ <param name="name">the string to display for the Level</param>
+ <param name="value">the level value to give to the Level</param>
+ <param name="displayName">the display name to give to the Level</param>
+ <remarks>
+ <para>
+ Create a new Level and add it to the map
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LevelMap.Add(log4net.Core.Level)">
+ <summary>
+ Add a Level to the map
+ </summary>
+ <param name="level">the Level to add</param>
+ <remarks>
+ <para>
+ Add a Level to the map
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LevelMap.LookupWithDefault(log4net.Core.Level)">
+ <summary>
+ Lookup a named level from the map
+ </summary>
+ <param name="defaultLevel">the name of the level to lookup is taken from this level.
+ If the level is not set on the map then this level is added</param>
+ <returns>the level in the map with the name specified</returns>
+ <remarks>
+ <para>
+ Lookup a named level from the map. The name of the level to lookup is taken
+ from the <see cref="P:log4net.Core.Level.Name"/> property of the <paramref name="defaultLevel"/>
+ argument.
+ </para>
+ <para>
+ If no level with the specified name is found then the
+ <paramref name="defaultLevel"/> argument is added to the level map
+ and returned.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Core.LevelMap.Item(System.String)">
+ <summary>
+ Lookup a <see cref="T:log4net.Core.Level"/> by name
+ </summary>
+ <param name="name">The name of the Level to lookup</param>
+ <returns>a Level from the map with the name specified</returns>
+ <remarks>
+ <para>
+ Returns the <see cref="T:log4net.Core.Level"/> from the
+ map with the name specified. If the no level is
+ found then <c>null</c> is returned.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Core.LevelMap.AllLevels">
+ <summary>
+ Return all possible levels as a list of Level objects.
+ </summary>
+ <returns>all possible levels as a list of Level objects</returns>
+ <remarks>
+ <para>
+ Return all possible levels as a list of Level objects.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Core.LocationInfo">
+ <summary>
+ The internal representation of caller location information.
+ </summary>
+ <remarks>
+ <para>
+ This class uses the <c>System.Diagnostics.StackTrace</c> class to generate
+ a call stack. The caller's information is then extracted from this stack.
+ </para>
+ <para>
+ The <c>System.Diagnostics.StackTrace</c> class is not supported on the
+ .NET Compact Framework 1.0 therefore caller location information is not
+ available on that framework.
+ </para>
+ <para>
+ The <c>System.Diagnostics.StackTrace</c> class has this to say about Release builds:
+ </para>
+ <para>
+ "StackTrace information will be most informative with Debug build configurations.
+ By default, Debug builds include debug symbols, while Release builds do not. The
+ debug symbols contain most of the file, method name, line number, and column
+ information used in constructing StackFrame and StackTrace objects. StackTrace
+ might not report as many method calls as expected, due to code transformations
+ that occur during optimization."
+ </para>
+ <para>
+ This means that in a Release build the caller information may be incomplete or may
+ not exist at all! Therefore caller location information cannot be relied upon in a Release build.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="F:log4net.Core.LocationInfo.NA">
+ <summary>
+ When location information is not available the constant
+ <c>NA</c> is returned. Current value of this string
+ constant is <b>?</b>.
+ </summary>
+ </member>
+ <member name="M:log4net.Core.LocationInfo.#ctor(System.Type)">
+ <summary>
+ Constructor
+ </summary>
+ <param name="callerStackBoundaryDeclaringType">The declaring type of the method that is
+ the stack boundary into the logging system for this call.</param>
+ <remarks>
+ <para>
+ Initializes a new instance of the <see cref="T:log4net.Core.LocationInfo"/>
+ class based on the current thread.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LocationInfo.#ctor(System.String,System.String,System.String,System.String)">
+ <summary>
+ Constructor
+ </summary>
+ <param name="className">The fully qualified class name.</param>
+ <param name="methodName">The method name.</param>
+ <param name="fileName">The file name.</param>
+ <param name="lineNumber">The line number of the method within the file.</param>
+ <remarks>
+ <para>
+ Initializes a new instance of the <see cref="T:log4net.Core.LocationInfo"/>
+ class with the specified data.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Core.LocationInfo.ClassName">
+ <summary>
+ Gets the fully qualified class name of the caller making the logging
+ request.
+ </summary>
+ <value>
+ The fully qualified class name of the caller making the logging
+ request.
+ </value>
+ <remarks>
+ <para>
+ Gets the fully qualified class name of the caller making the logging
+ request.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Core.LocationInfo.FileName">
+ <summary>
+ Gets the file name of the caller.
+ </summary>
+ <value>
+ The file name of the caller.
+ </value>
+ <remarks>
+ <para>
+ Gets the file name of the caller.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Core.LocationInfo.LineNumber">
+ <summary>
+ Gets the line number of the caller.
+ </summary>
+ <value>
+ The line number of the caller.
+ </value>
+ <remarks>
+ <para>
+ Gets the line number of the caller.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Core.LocationInfo.MethodName">
+ <summary>
+ Gets the method name of the caller.
+ </summary>
+ <value>
+ The method name of the caller.
+ </value>
+ <remarks>
+ <para>
+ Gets the method name of the caller.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Core.LocationInfo.FullInfo">
+ <summary>
+ Gets all available caller information
+ </summary>
+ <value>
+ All available caller information, in the format
+ <c>fully.qualified.classname.of.caller.methodName(Filename:line)</c>
+ </value>
+ <remarks>
+ <para>
+ Gets all available caller information, in the format
+ <c>fully.qualified.classname.of.caller.methodName(Filename:line)</c>
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Core.LoggerManager">
+ <summary>
+ Static manager that controls the creation of repositories
+ </summary>
+ <remarks>
+ <para>
+ Static manager that controls the creation of repositories
+ </para>
+ <para>
+ This class is used by the wrapper managers (e.g. <see cref="T:log4net.LogManager"/>)
+ to provide access to the <see cref="T:log4net.Core.ILogger"/> objects.
+ </para>
+ <para>
+ This manager also holds the <see cref="T:log4net.Core.IRepositorySelector"/> that is used to
+ lookup and create repositories. The selector can be set either programmatically using
+ the <see cref="P:log4net.Core.LoggerManager.RepositorySelector"/> property, or by setting the <c>log4net.RepositorySelector</c>
+ AppSetting in the applications config file to the fully qualified type name of the
+ selector to use.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="M:log4net.Core.LoggerManager.#ctor">
+ <summary>
+ Private constructor to prevent instances. Only static methods should be used.
+ </summary>
+ <remarks>
+ <para>
+ Private constructor to prevent instances. Only static methods should be used.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LoggerManager.#cctor">
+ <summary>
+ Hook the shutdown event
+ </summary>
+ <remarks>
+ <para>
+ On the full .NET runtime, the static constructor hooks up the
+ <c>AppDomain.ProcessExit</c> and <c>AppDomain.DomainUnload</c>> events.
+ These are used to shutdown the log4net system as the application exits.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LoggerManager.RegisterAppDomainEvents">
+ <summary>
+ Register for ProcessExit and DomainUnload events on the AppDomain
+ </summary>
+ <remarks>
+ <para>
+ This needs to be in a separate method because the events make
+ a LinkDemand for the ControlAppDomain SecurityPermission. Because
+ this is a LinkDemand it is demanded at JIT time. Therefore we cannot
+ catch the exception in the method itself, we have to catch it in the
+ caller.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LoggerManager.GetLoggerRepository(System.String)">
+ <summary>
+ Return the default <see cref="T:log4net.Repository.ILoggerRepository"/> instance.
+ </summary>
+ <param name="repository">the repository to lookup in</param>
+ <returns>Return the default <see cref="T:log4net.Repository.ILoggerRepository"/> instance</returns>
+ <remarks>
+ <para>
+ Gets the <see cref="T:log4net.Repository.ILoggerRepository"/> for the repository specified
+ by the <paramref name="repository"/> argument.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LoggerManager.GetLoggerRepository(System.Reflection.Assembly)">
+ <summary>
+ Returns the default <see cref="T:log4net.Repository.ILoggerRepository"/> instance.
+ </summary>
+ <param name="repositoryAssembly">The assembly to use to lookup the repository.</param>
+ <returns>The default <see cref="T:log4net.Repository.ILoggerRepository"/> instance.</returns>
+ </member>
+ <member name="M:log4net.Core.LoggerManager.GetRepository(System.String)">
+ <summary>
+ Return the default <see cref="T:log4net.Repository.ILoggerRepository"/> instance.
+ </summary>
+ <param name="repository">the repository to lookup in</param>
+ <returns>Return the default <see cref="T:log4net.Repository.ILoggerRepository"/> instance</returns>
+ <remarks>
+ <para>
+ Gets the <see cref="T:log4net.Repository.ILoggerRepository"/> for the repository specified
+ by the <paramref name="repository"/> argument.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LoggerManager.GetRepository(System.Reflection.Assembly)">
+ <summary>
+ Returns the default <see cref="T:log4net.Repository.ILoggerRepository"/> instance.
+ </summary>
+ <param name="repositoryAssembly">The assembly to use to lookup the repository.</param>
+ <returns>The default <see cref="T:log4net.Repository.ILoggerRepository"/> instance.</returns>
+ <remarks>
+ <para>
+ Returns the default <see cref="T:log4net.Repository.ILoggerRepository"/> instance.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LoggerManager.Exists(System.String,System.String)">
+ <summary>
+ Returns the named logger if it exists.
+ </summary>
+ <param name="repository">The repository to lookup in.</param>
+ <param name="name">The fully qualified logger name to look for.</param>
+ <returns>
+ The logger found, or <c>null</c> if the named logger does not exist in the
+ specified repository.
+ </returns>
+ <remarks>
+ <para>
+ If the named logger exists (in the specified repository) then it
+ returns a reference to the logger, otherwise it returns
+ <c>null</c>.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LoggerManager.Exists(System.Reflection.Assembly,System.String)">
+ <summary>
+ Returns the named logger if it exists.
+ </summary>
+ <param name="repositoryAssembly">The assembly to use to lookup the repository.</param>
+ <param name="name">The fully qualified logger name to look for.</param>
+ <returns>
+ The logger found, or <c>null</c> if the named logger does not exist in the
+ specified assembly's repository.
+ </returns>
+ <remarks>
+ <para>
+ If the named logger exists (in the specified assembly's repository) then it
+ returns a reference to the logger, otherwise it returns
+ <c>null</c>.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LoggerManager.GetCurrentLoggers(System.String)">
+ <summary>
+ Returns all the currently defined loggers in the specified repository.
+ </summary>
+ <param name="repository">The repository to lookup in.</param>
+ <returns>All the defined loggers.</returns>
+ <remarks>
+ <para>
+ The root logger is <b>not</b> included in the returned array.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LoggerManager.GetCurrentLoggers(System.Reflection.Assembly)">
+ <summary>
+ Returns all the currently defined loggers in the specified assembly's repository.
+ </summary>
+ <param name="repositoryAssembly">The assembly to use to lookup the repository.</param>
+ <returns>All the defined loggers.</returns>
+ <remarks>
+ <para>
+ The root logger is <b>not</b> included in the returned array.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LoggerManager.GetLogger(System.String,System.String)">
+ <summary>
+ Retrieves or creates a named logger.
+ </summary>
+ <param name="repository">The repository to lookup in.</param>
+ <param name="name">The name of the logger to retrieve.</param>
+ <returns>The logger with the name specified.</returns>
+ <remarks>
+ <para>
+ Retrieves a logger named as the <paramref name="name"/>
+ parameter. If the named logger already exists, then the
+ existing instance will be returned. Otherwise, a new instance is
+ created.
+ </para>
+ <para>
+ By default, loggers do not have a set level but inherit
+ it from the hierarchy. This is one of the central features of
+ log4net.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LoggerManager.GetLogger(System.Reflection.Assembly,System.String)">
+ <summary>
+ Retrieves or creates a named logger.
+ </summary>
+ <param name="repositoryAssembly">The assembly to use to lookup the repository.</param>
+ <param name="name">The name of the logger to retrieve.</param>
+ <returns>The logger with the name specified.</returns>
+ <remarks>
+ <para>
+ Retrieves a logger named as the <paramref name="name"/>
+ parameter. If the named logger already exists, then the
+ existing instance will be returned. Otherwise, a new instance is
+ created.
+ </para>
+ <para>
+ By default, loggers do not have a set level but inherit
+ it from the hierarchy. This is one of the central features of
+ log4net.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LoggerManager.GetLogger(System.String,System.Type)">
+ <summary>
+ Shorthand for <see cref="M:log4net.LogManager.GetLogger(System.String)"/>.
+ </summary>
+ <param name="repository">The repository to lookup in.</param>
+ <param name="type">The <paramref name="type"/> of which the fullname will be used as the name of the logger to retrieve.</param>
+ <returns>The logger with the name specified.</returns>
+ <remarks>
+ <para>
+ Gets the logger for the fully qualified name of the type specified.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LoggerManager.GetLogger(System.Reflection.Assembly,System.Type)">
+ <summary>
+ Shorthand for <see cref="M:log4net.LogManager.GetLogger(System.String)"/>.
+ </summary>
+ <param name="repositoryAssembly">the assembly to use to lookup the repository</param>
+ <param name="type">The <paramref name="type"/> of which the fullname will be used as the name of the logger to retrieve.</param>
+ <returns>The logger with the name specified.</returns>
+ <remarks>
+ <para>
+ Gets the logger for the fully qualified name of the type specified.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LoggerManager.Shutdown">
+ <summary>
+ Shuts down the log4net system.
+ </summary>
+ <remarks>
+ <para>
+ Calling this method will <b>safely</b> close and remove all
+ appenders in all the loggers including root contained in all the
+ default repositories.
+ </para>
+ <para>
+ Some appenders need to be closed before the application exists.
+ Otherwise, pending logging events might be lost.
+ </para>
+ <para>
+ The <c>shutdown</c> method is careful to close nested
+ appenders before closing regular appenders. This is allows
+ configurations where a regular appender is attached to a logger
+ and again to a nested appender.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LoggerManager.ShutdownRepository(System.String)">
+ <summary>
+ Shuts down the repository for the repository specified.
+ </summary>
+ <param name="repository">The repository to shutdown.</param>
+ <remarks>
+ <para>
+ Calling this method will <b>safely</b> close and remove all
+ appenders in all the loggers including root contained in the
+ repository for the <paramref name="repository"/> specified.
+ </para>
+ <para>
+ Some appenders need to be closed before the application exists.
+ Otherwise, pending logging events might be lost.
+ </para>
+ <para>
+ The <c>shutdown</c> method is careful to close nested
+ appenders before closing regular appenders. This is allows
+ configurations where a regular appender is attached to a logger
+ and again to a nested appender.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LoggerManager.ShutdownRepository(System.Reflection.Assembly)">
+ <summary>
+ Shuts down the repository for the repository specified.
+ </summary>
+ <param name="repositoryAssembly">The assembly to use to lookup the repository.</param>
+ <remarks>
+ <para>
+ Calling this method will <b>safely</b> close and remove all
+ appenders in all the loggers including root contained in the
+ repository for the repository. The repository is looked up using
+ the <paramref name="repositoryAssembly"/> specified.
+ </para>
+ <para>
+ Some appenders need to be closed before the application exists.
+ Otherwise, pending logging events might be lost.
+ </para>
+ <para>
+ The <c>shutdown</c> method is careful to close nested
+ appenders before closing regular appenders. This is allows
+ configurations where a regular appender is attached to a logger
+ and again to a nested appender.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LoggerManager.ResetConfiguration(System.String)">
+ <summary>
+ Resets all values contained in this repository instance to their defaults.
+ </summary>
+ <param name="repository">The repository to reset.</param>
+ <remarks>
+ <para>
+ Resets all values contained in the repository instance to their
+ defaults. This removes all appenders from all loggers, sets
+ the level of all non-root loggers to <c>null</c>,
+ sets their additivity flag to <c>true</c> and sets the level
+ of the root logger to <see cref="F:log4net.Core.Level.Debug"/>. Moreover,
+ message disabling is set its default "off" value.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LoggerManager.ResetConfiguration(System.Reflection.Assembly)">
+ <summary>
+ Resets all values contained in this repository instance to their defaults.
+ </summary>
+ <param name="repositoryAssembly">The assembly to use to lookup the repository to reset.</param>
+ <remarks>
+ <para>
+ Resets all values contained in the repository instance to their
+ defaults. This removes all appenders from all loggers, sets
+ the level of all non-root loggers to <c>null</c>,
+ sets their additivity flag to <c>true</c> and sets the level
+ of the root logger to <see cref="F:log4net.Core.Level.Debug"/>. Moreover,
+ message disabling is set its default "off" value.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LoggerManager.CreateDomain(System.String)">
+ <summary>
+ Creates a repository with the specified name.
+ </summary>
+ <param name="repository">The name of the repository, this must be unique amongst repositories.</param>
+ <returns>The <see cref="T:log4net.Repository.ILoggerRepository"/> created for the repository.</returns>
+ <remarks>
+ <para>
+ <b>CreateDomain is obsolete. Use CreateRepository instead of CreateDomain.</b>
+ </para>
+ <para>
+ Creates the default type of <see cref="T:log4net.Repository.ILoggerRepository"/> which is a
+ <see cref="T:log4net.Repository.Hierarchy.Hierarchy"/> object.
+ </para>
+ <para>
+ The <paramref name="repository"/> name must be unique. Repositories cannot be redefined.
+ An <see cref="T:System.Exception"/> will be thrown if the repository already exists.
+ </para>
+ </remarks>
+ <exception cref="T:log4net.Core.LogException">The specified repository already exists.</exception>
+ </member>
+ <member name="M:log4net.Core.LoggerManager.CreateRepository(System.String)">
+ <summary>
+ Creates a repository with the specified name.
+ </summary>
+ <param name="repository">The name of the repository, this must be unique amongst repositories.</param>
+ <returns>The <see cref="T:log4net.Repository.ILoggerRepository"/> created for the repository.</returns>
+ <remarks>
+ <para>
+ Creates the default type of <see cref="T:log4net.Repository.ILoggerRepository"/> which is a
+ <see cref="T:log4net.Repository.Hierarchy.Hierarchy"/> object.
+ </para>
+ <para>
+ The <paramref name="repository"/> name must be unique. Repositories cannot be redefined.
+ An <see cref="T:System.Exception"/> will be thrown if the repository already exists.
+ </para>
+ </remarks>
+ <exception cref="T:log4net.Core.LogException">The specified repository already exists.</exception>
+ </member>
+ <member name="M:log4net.Core.LoggerManager.CreateDomain(System.String,System.Type)">
+ <summary>
+ Creates a repository with the specified name and repository type.
+ </summary>
+ <param name="repository">The name of the repository, this must be unique to the repository.</param>
+ <param name="repositoryType">A <see cref="T:System.Type"/> that implements <see cref="T:log4net.Repository.ILoggerRepository"/>
+ and has a no arg constructor. An instance of this type will be created to act
+ as the <see cref="T:log4net.Repository.ILoggerRepository"/> for the repository specified.</param>
+ <returns>The <see cref="T:log4net.Repository.ILoggerRepository"/> created for the repository.</returns>
+ <remarks>
+ <para>
+ <b>CreateDomain is obsolete. Use CreateRepository instead of CreateDomain.</b>
+ </para>
+ <para>
+ The <paramref name="repository"/> name must be unique. Repositories cannot be redefined.
+ An Exception will be thrown if the repository already exists.
+ </para>
+ </remarks>
+ <exception cref="T:log4net.Core.LogException">The specified repository already exists.</exception>
+ </member>
+ <member name="M:log4net.Core.LoggerManager.CreateRepository(System.String,System.Type)">
+ <summary>
+ Creates a repository with the specified name and repository type.
+ </summary>
+ <param name="repository">The name of the repository, this must be unique to the repository.</param>
+ <param name="repositoryType">A <see cref="T:System.Type"/> that implements <see cref="T:log4net.Repository.ILoggerRepository"/>
+ and has a no arg constructor. An instance of this type will be created to act
+ as the <see cref="T:log4net.Repository.ILoggerRepository"/> for the repository specified.</param>
+ <returns>The <see cref="T:log4net.Repository.ILoggerRepository"/> created for the repository.</returns>
+ <remarks>
+ <para>
+ The <paramref name="repository"/> name must be unique. Repositories cannot be redefined.
+ An Exception will be thrown if the repository already exists.
+ </para>
+ </remarks>
+ <exception cref="T:log4net.Core.LogException">The specified repository already exists.</exception>
+ </member>
+ <member name="M:log4net.Core.LoggerManager.CreateDomain(System.Reflection.Assembly,System.Type)">
+ <summary>
+ Creates a repository for the specified assembly and repository type.
+ </summary>
+ <param name="repositoryAssembly">The assembly to use to get the name of the repository.</param>
+ <param name="repositoryType">A <see cref="T:System.Type"/> that implements <see cref="T:log4net.Repository.ILoggerRepository"/>
+ and has a no arg constructor. An instance of this type will be created to act
+ as the <see cref="T:log4net.Repository.ILoggerRepository"/> for the repository specified.</param>
+ <returns>The <see cref="T:log4net.Repository.ILoggerRepository"/> created for the repository.</returns>
+ <remarks>
+ <para>
+ <b>CreateDomain is obsolete. Use CreateRepository instead of CreateDomain.</b>
+ </para>
+ <para>
+ The <see cref="T:log4net.Repository.ILoggerRepository"/> created will be associated with the repository
+ specified such that a call to <see cref="M:log4net.Core.LoggerManager.GetRepository(System.Reflection.Assembly)"/> with the
+ same assembly specified will return the same repository instance.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LoggerManager.CreateRepository(System.Reflection.Assembly,System.Type)">
+ <summary>
+ Creates a repository for the specified assembly and repository type.
+ </summary>
+ <param name="repositoryAssembly">The assembly to use to get the name of the repository.</param>
+ <param name="repositoryType">A <see cref="T:System.Type"/> that implements <see cref="T:log4net.Repository.ILoggerRepository"/>
+ and has a no arg constructor. An instance of this type will be created to act
+ as the <see cref="T:log4net.Repository.ILoggerRepository"/> for the repository specified.</param>
+ <returns>The <see cref="T:log4net.Repository.ILoggerRepository"/> created for the repository.</returns>
+ <remarks>
+ <para>
+ The <see cref="T:log4net.Repository.ILoggerRepository"/> created will be associated with the repository
+ specified such that a call to <see cref="M:log4net.Core.LoggerManager.GetRepository(System.Reflection.Assembly)"/> with the
+ same assembly specified will return the same repository instance.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LoggerManager.GetAllRepositories">
+ <summary>
+ Gets an array of all currently defined repositories.
+ </summary>
+ <returns>An array of all the known <see cref="T:log4net.Repository.ILoggerRepository"/> objects.</returns>
+ <remarks>
+ <para>
+ Gets an array of all currently defined repositories.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LoggerManager.GetVersionInfo">
+ <summary>
+ Internal method to get pertinent version info.
+ </summary>
+ <returns>A string of version info.</returns>
+ </member>
+ <member name="M:log4net.Core.LoggerManager.OnDomainUnload(System.Object,System.EventArgs)">
+ <summary>
+ Called when the <see cref="E:System.AppDomain.DomainUnload"/> event fires
+ </summary>
+ <param name="sender">the <see cref="T:System.AppDomain"/> that is exiting</param>
+ <param name="e">null</param>
+ <remarks>
+ <para>
+ Called when the <see cref="E:System.AppDomain.DomainUnload"/> event fires.
+ </para>
+ <para>
+ When the event is triggered the log4net system is <see cref="M:log4net.Core.LoggerManager.Shutdown"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LoggerManager.OnProcessExit(System.Object,System.EventArgs)">
+ <summary>
+ Called when the <see cref="E:System.AppDomain.ProcessExit"/> event fires
+ </summary>
+ <param name="sender">the <see cref="T:System.AppDomain"/> that is exiting</param>
+ <param name="e">null</param>
+ <remarks>
+ <para>
+ Called when the <see cref="E:System.AppDomain.ProcessExit"/> event fires.
+ </para>
+ <para>
+ When the event is triggered the log4net system is <see cref="M:log4net.Core.LoggerManager.Shutdown"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Core.LoggerManager.s_repositorySelector">
+ <summary>
+ Initialize the default repository selector
+ </summary>
+ </member>
+ <member name="P:log4net.Core.LoggerManager.RepositorySelector">
+ <summary>
+ Gets or sets the repository selector used by the <see cref="T:log4net.LogManager"/>.
+ </summary>
+ <value>
+ The repository selector used by the <see cref="T:log4net.LogManager"/>.
+ </value>
+ <remarks>
+ <para>
+ The repository selector (<see cref="T:log4net.Core.IRepositorySelector"/>) is used by
+ the <see cref="T:log4net.LogManager"/> to create and select repositories
+ (<see cref="T:log4net.Repository.ILoggerRepository"/>).
+ </para>
+ <para>
+ The caller to <see cref="T:log4net.LogManager"/> supplies either a string name
+ or an assembly (if not supplied the assembly is inferred using
+ <see cref="M:System.Reflection.Assembly.GetCallingAssembly"/>).
+ </para>
+ <para>
+ This context is used by the selector to lookup a specific repository.
+ </para>
+ <para>
+ For the full .NET Framework, the default repository is <c>DefaultRepositorySelector</c>;
+ for the .NET Compact Framework <c>CompactRepositorySelector</c> is the default
+ repository.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Core.LoggerWrapperImpl">
+ <summary>
+ Implementation of the <see cref="T:log4net.Core.ILoggerWrapper"/> interface.
+ </summary>
+ <remarks>
+ <para>
+ This class should be used as the base for all wrapper implementations.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="M:log4net.Core.LoggerWrapperImpl.#ctor(log4net.Core.ILogger)">
+ <summary>
+ Constructs a new wrapper for the specified logger.
+ </summary>
+ <param name="logger">The logger to wrap.</param>
+ <remarks>
+ <para>
+ Constructs a new wrapper for the specified logger.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Core.LoggerWrapperImpl.m_logger">
+ <summary>
+ The logger that this object is wrapping
+ </summary>
+ </member>
+ <member name="P:log4net.Core.LoggerWrapperImpl.Logger">
+ <summary>
+ Gets the implementation behind this wrapper object.
+ </summary>
+ <value>
+ The <see cref="T:log4net.Core.ILogger"/> object that this object is implementing.
+ </value>
+ <remarks>
+ <para>
+ The <c>Logger</c> object may not be the same object as this object
+ because of logger decorators.
+ </para>
+ <para>
+ This gets the actual underlying objects that is used to process
+ the log events.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Core.LoggingEventData">
+ <summary>
+ Portable data structure used by <see cref="T:log4net.Core.LoggingEvent"/>
+ </summary>
+ <remarks>
+ <para>
+ Portable data structure used by <see cref="T:log4net.Core.LoggingEvent"/>
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="F:log4net.Core.LoggingEventData.LoggerName">
+ <summary>
+ The logger name.
+ </summary>
+ <remarks>
+ <para>
+ The logger name.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Core.LoggingEventData.Level">
+ <summary>
+ Level of logging event.
+ </summary>
+ <remarks>
+ <para>
+ Level of logging event. Level cannot be Serializable
+ because it is a flyweight. Due to its special serialization it
+ cannot be declared final either.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Core.LoggingEventData.Message">
+ <summary>
+ The application supplied message.
+ </summary>
+ <remarks>
+ <para>
+ The application supplied message of logging event.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Core.LoggingEventData.ThreadName">
+ <summary>
+ The name of thread
+ </summary>
+ <remarks>
+ <para>
+ The name of thread in which this logging event was generated
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Core.LoggingEventData.TimeStamp">
+ <summary>
+ The time the event was logged
+ </summary>
+ <remarks>
+ <para>
+ The TimeStamp is stored in the local time zone for this computer.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Core.LoggingEventData.LocationInfo">
+ <summary>
+ Location information for the caller.
+ </summary>
+ <remarks>
+ <para>
+ Location information for the caller.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Core.LoggingEventData.UserName">
+ <summary>
+ String representation of the user
+ </summary>
+ <remarks>
+ <para>
+ String representation of the user's windows name,
+ like DOMAIN\username
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Core.LoggingEventData.Identity">
+ <summary>
+ String representation of the identity.
+ </summary>
+ <remarks>
+ <para>
+ String representation of the current thread's principal identity.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Core.LoggingEventData.ExceptionString">
+ <summary>
+ The string representation of the exception
+ </summary>
+ <remarks>
+ <para>
+ The string representation of the exception
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Core.LoggingEventData.Domain">
+ <summary>
+ String representation of the AppDomain.
+ </summary>
+ <remarks>
+ <para>
+ String representation of the AppDomain.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Core.LoggingEventData.Properties">
+ <summary>
+ Additional event specific properties
+ </summary>
+ <remarks>
+ <para>
+ A logger or an appender may attach additional
+ properties to specific events. These properties
+ have a string key and an object value.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Core.FixFlags">
+ <summary>
+ Flags passed to the <see cref="P:log4net.Core.LoggingEvent.Fix"/> property
+ </summary>
+ <remarks>
+ <para>
+ Flags passed to the <see cref="P:log4net.Core.LoggingEvent.Fix"/> property
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="F:log4net.Core.FixFlags.Mdc">
+ <summary>
+ Fix the MDC
+ </summary>
+ </member>
+ <member name="F:log4net.Core.FixFlags.Ndc">
+ <summary>
+ Fix the NDC
+ </summary>
+ </member>
+ <member name="F:log4net.Core.FixFlags.Message">
+ <summary>
+ Fix the rendered message
+ </summary>
+ </member>
+ <member name="F:log4net.Core.FixFlags.ThreadName">
+ <summary>
+ Fix the thread name
+ </summary>
+ </member>
+ <member name="F:log4net.Core.FixFlags.LocationInfo">
+ <summary>
+ Fix the callers location information
+ </summary>
+ <remarks>
+ CAUTION: Very slow to generate
+ </remarks>
+ </member>
+ <member name="F:log4net.Core.FixFlags.UserName">
+ <summary>
+ Fix the callers windows user name
+ </summary>
+ <remarks>
+ CAUTION: Slow to generate
+ </remarks>
+ </member>
+ <member name="F:log4net.Core.FixFlags.Domain">
+ <summary>
+ Fix the domain friendly name
+ </summary>
+ </member>
+ <member name="F:log4net.Core.FixFlags.Identity">
+ <summary>
+ Fix the callers principal name
+ </summary>
+ <remarks>
+ CAUTION: May be slow to generate
+ </remarks>
+ </member>
+ <member name="F:log4net.Core.FixFlags.Exception">
+ <summary>
+ Fix the exception text
+ </summary>
+ </member>
+ <member name="F:log4net.Core.FixFlags.Properties">
+ <summary>
+ Fix the event properties
+ </summary>
+ </member>
+ <member name="F:log4net.Core.FixFlags.None">
+ <summary>
+ No fields fixed
+ </summary>
+ </member>
+ <member name="F:log4net.Core.FixFlags.All">
+ <summary>
+ All fields fixed
+ </summary>
+ </member>
+ <member name="F:log4net.Core.FixFlags.Partial">
+ <summary>
+ Partial fields fixed
+ </summary>
+ <remarks>
+ <para>
+ This set of partial fields gives good performance. The following fields are fixed:
+ </para>
+ <list type="bullet">
+ <item><description><see cref="F:log4net.Core.FixFlags.Message"/></description></item>
+ <item><description><see cref="F:log4net.Core.FixFlags.ThreadName"/></description></item>
+ <item><description><see cref="F:log4net.Core.FixFlags.Exception"/></description></item>
+ <item><description><see cref="F:log4net.Core.FixFlags.Domain"/></description></item>
+ <item><description><see cref="F:log4net.Core.FixFlags.Properties"/></description></item>
+ </list>
+ </remarks>
+ </member>
+ <member name="T:log4net.Core.LoggingEvent">
+ <summary>
+ The internal representation of logging events.
+ </summary>
+ <remarks>
+ <para>
+ When an affirmative decision is made to log then a
+ <see cref="T:log4net.Core.LoggingEvent"/> instance is created. This instance
+ is passed around to the different log4net components.
+ </para>
+ <para>
+ This class is of concern to those wishing to extend log4net.
+ </para>
+ <para>
+ Some of the values in instances of <see cref="T:log4net.Core.LoggingEvent"/>
+ are considered volatile, that is the values are correct at the
+ time the event is delivered to appenders, but will not be consistent
+ at any time afterwards. If an event is to be stored and then processed
+ at a later time these volatile values must be fixed by calling
+ <see cref="M:log4net.Core.LoggingEvent.FixVolatileData"/>. There is a performance penalty
+ for incurred by calling <see cref="M:log4net.Core.LoggingEvent.FixVolatileData"/> but it
+ is essential to maintaining data consistency.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ <author>Douglas de la Torre</author>
+ <author>Daniel Cazzulino</author>
+ </member>
+ <member name="F:log4net.Core.LoggingEvent.HostNameProperty">
+ <summary>
+ The key into the Properties map for the host name value.
+ </summary>
+ </member>
+ <member name="F:log4net.Core.LoggingEvent.IdentityProperty">
+ <summary>
+ The key into the Properties map for the thread identity value.
+ </summary>
+ </member>
+ <member name="F:log4net.Core.LoggingEvent.UserNameProperty">
+ <summary>
+ The key into the Properties map for the user name value.
+ </summary>
+ </member>
+ <member name="M:log4net.Core.LoggingEvent.#ctor(System.Type,log4net.Repository.ILoggerRepository,System.String,log4net.Core.Level,System.Object,System.Exception)">
+ <summary>
+ Initializes a new instance of the <see cref="T:log4net.Core.LoggingEvent"/> class
+ from the supplied parameters.
+ </summary>
+ <param name="callerStackBoundaryDeclaringType">The declaring type of the method that is
+ the stack boundary into the logging system for this call.</param>
+ <param name="repository">The repository this event is logged in.</param>
+ <param name="loggerName">The name of the logger of this event.</param>
+ <param name="level">The level of this event.</param>
+ <param name="message">The message of this event.</param>
+ <param name="exception">The exception for this event.</param>
+ <remarks>
+ <para>
+ Except <see cref="P:log4net.Core.LoggingEvent.TimeStamp"/>, <see cref="P:log4net.Core.LoggingEvent.Level"/> and <see cref="P:log4net.Core.LoggingEvent.LoggerName"/>,
+ all fields of <c>LoggingEvent</c> are filled when actually needed. Call
+ <see cref="M:log4net.Core.LoggingEvent.FixVolatileData"/> to cache all data locally
+ to prevent inconsistencies.
+ </para>
+ <para>This method is called by the log4net framework
+ to create a logging event.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LoggingEvent.#ctor(System.Type,log4net.Repository.ILoggerRepository,log4net.Core.LoggingEventData,log4net.Core.FixFlags)">
+ <summary>
+ Initializes a new instance of the <see cref="T:log4net.Core.LoggingEvent"/> class
+ using specific data.
+ </summary>
+ <param name="callerStackBoundaryDeclaringType">The declaring type of the method that is
+ the stack boundary into the logging system for this call.</param>
+ <param name="repository">The repository this event is logged in.</param>
+ <param name="data">Data used to initialize the logging event.</param>
+ <param name="fixedData">The fields in the <paranref name="data"/> struct that have already been fixed.</param>
+ <remarks>
+ <para>
+ This constructor is provided to allow a <see cref="T:log4net.Core.LoggingEvent"/>
+ to be created independently of the log4net framework. This can
+ be useful if you require a custom serialization scheme.
+ </para>
+ <para>
+ Use the <see cref="M:log4net.Core.LoggingEvent.GetLoggingEventData(log4net.Core.FixFlags)"/> method to obtain an
+ instance of the <see cref="T:log4net.Core.LoggingEventData"/> class.
+ </para>
+ <para>
+ The <paramref name="fixedData"/> parameter should be used to specify which fields in the
+ <paramref name="data"/> struct have been preset. Fields not specified in the <paramref name="fixedData"/>
+ will be captured from the environment if requested or fixed.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LoggingEvent.#ctor(System.Type,log4net.Repository.ILoggerRepository,log4net.Core.LoggingEventData)">
+ <summary>
+ Initializes a new instance of the <see cref="T:log4net.Core.LoggingEvent"/> class
+ using specific data.
+ </summary>
+ <param name="callerStackBoundaryDeclaringType">The declaring type of the method that is
+ the stack boundary into the logging system for this call.</param>
+ <param name="repository">The repository this event is logged in.</param>
+ <param name="data">Data used to initialize the logging event.</param>
+ <remarks>
+ <para>
+ This constructor is provided to allow a <see cref="T:log4net.Core.LoggingEvent"/>
+ to be created independently of the log4net framework. This can
+ be useful if you require a custom serialization scheme.
+ </para>
+ <para>
+ Use the <see cref="M:log4net.Core.LoggingEvent.GetLoggingEventData(log4net.Core.FixFlags)"/> method to obtain an
+ instance of the <see cref="T:log4net.Core.LoggingEventData"/> class.
+ </para>
+ <para>
+ This constructor sets this objects <see cref="P:log4net.Core.LoggingEvent.Fix"/> flags to <see cref="F:log4net.Core.FixFlags.All"/>,
+ this assumes that all the data relating to this event is passed in via the <paramref name="data"/>
+ parameter and no other data should be captured from the environment.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LoggingEvent.#ctor(log4net.Core.LoggingEventData)">
+ <summary>
+ Initializes a new instance of the <see cref="T:log4net.Core.LoggingEvent"/> class
+ using specific data.
+ </summary>
+ <param name="data">Data used to initialize the logging event.</param>
+ <remarks>
+ <para>
+ This constructor is provided to allow a <see cref="T:log4net.Core.LoggingEvent"/>
+ to be created independently of the log4net framework. This can
+ be useful if you require a custom serialization scheme.
+ </para>
+ <para>
+ Use the <see cref="M:log4net.Core.LoggingEvent.GetLoggingEventData(log4net.Core.FixFlags)"/> method to obtain an
+ instance of the <see cref="T:log4net.Core.LoggingEventData"/> class.
+ </para>
+ <para>
+ This constructor sets this objects <see cref="P:log4net.Core.LoggingEvent.Fix"/> flags to <see cref="F:log4net.Core.FixFlags.All"/>,
+ this assumes that all the data relating to this event is passed in via the <paramref name="data"/>
+ parameter and no other data should be captured from the environment.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LoggingEvent.#ctor(System.Runtime.Serialization.SerializationInfo,System.Runtime.Serialization.StreamingContext)">
+ <summary>
+ Serialization constructor
+ </summary>
+ <param name="info">The <see cref="T:System.Runtime.Serialization.SerializationInfo"/> that holds the serialized object data.</param>
+ <param name="context">The <see cref="T:System.Runtime.Serialization.StreamingContext"/> that contains contextual information about the source or destination.</param>
+ <remarks>
+ <para>
+ Initializes a new instance of the <see cref="T:log4net.Core.LoggingEvent"/> class
+ with serialized data.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LoggingEvent.EnsureRepository(log4net.Repository.ILoggerRepository)">
+ <summary>
+ Ensure that the repository is set.
+ </summary>
+ <param name="repository">the value for the repository</param>
+ </member>
+ <member name="M:log4net.Core.LoggingEvent.WriteRenderedMessage(System.IO.TextWriter)">
+ <summary>
+ Write the rendered message to a TextWriter
+ </summary>
+ <param name="writer">the writer to write the message to</param>
+ <remarks>
+ <para>
+ Unlike the <see cref="P:log4net.Core.LoggingEvent.RenderedMessage"/> property this method
+ does store the message data in the internal cache. Therefore
+ if called only once this method should be faster than the
+ <see cref="P:log4net.Core.LoggingEvent.RenderedMessage"/> property, however if the message is
+ to be accessed multiple times then the property will be more efficient.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LoggingEvent.GetObjectData(System.Runtime.Serialization.SerializationInfo,System.Runtime.Serialization.StreamingContext)">
+ <summary>
+ Serializes this object into the <see cref="T:System.Runtime.Serialization.SerializationInfo"/> provided.
+ </summary>
+ <param name="info">The <see cref="T:System.Runtime.Serialization.SerializationInfo"/> to populate with data.</param>
+ <param name="context">The destination for this serialization.</param>
+ <remarks>
+ <para>
+ The data in this event must be fixed before it can be serialized.
+ </para>
+ <para>
+ The <see cref="M:log4net.Core.LoggingEvent.FixVolatileData"/> method must be called during the
+ <see cref="M:log4net.Appender.IAppender.DoAppend(log4net.Core.LoggingEvent)"/> method call if this event
+ is to be used outside that method.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LoggingEvent.GetLoggingEventData">
+ <summary>
+ Gets the portable data for this <see cref="T:log4net.Core.LoggingEvent"/>.
+ </summary>
+ <returns>The <see cref="T:log4net.Core.LoggingEventData"/> for this event.</returns>
+ <remarks>
+ <para>
+ A new <see cref="T:log4net.Core.LoggingEvent"/> can be constructed using a
+ <see cref="T:log4net.Core.LoggingEventData"/> instance.
+ </para>
+ <para>
+ Does a <see cref="F:log4net.Core.FixFlags.Partial"/> fix of the data
+ in the logging event before returning the event data.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LoggingEvent.GetLoggingEventData(log4net.Core.FixFlags)">
+ <summary>
+ Gets the portable data for this <see cref="T:log4net.Core.LoggingEvent"/>.
+ </summary>
+ <param name="fixFlags">The set of data to ensure is fixed in the LoggingEventData</param>
+ <returns>The <see cref="T:log4net.Core.LoggingEventData"/> for this event.</returns>
+ <remarks>
+ <para>
+ A new <see cref="T:log4net.Core.LoggingEvent"/> can be constructed using a
+ <see cref="T:log4net.Core.LoggingEventData"/> instance.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LoggingEvent.GetExceptionStrRep">
+ <summary>
+ Returns this event's exception's rendered using the
+ <see cref="P:log4net.Repository.ILoggerRepository.RendererMap"/>.
+ </summary>
+ <returns>
+ This event's exception's rendered using the <see cref="P:log4net.Repository.ILoggerRepository.RendererMap"/>.
+ </returns>
+ <remarks>
+ <para>
+ <b>Obsolete. Use <see cref="M:log4net.Core.LoggingEvent.GetExceptionString"/> instead.</b>
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LoggingEvent.GetExceptionString">
+ <summary>
+ Returns this event's exception's rendered using the
+ <see cref="P:log4net.Repository.ILoggerRepository.RendererMap"/>.
+ </summary>
+ <returns>
+ This event's exception's rendered using the <see cref="P:log4net.Repository.ILoggerRepository.RendererMap"/>.
+ </returns>
+ <remarks>
+ <para>
+ Returns this event's exception's rendered using the
+ <see cref="P:log4net.Repository.ILoggerRepository.RendererMap"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LoggingEvent.FixVolatileData">
+ <summary>
+ Fix instance fields that hold volatile data.
+ </summary>
+ <remarks>
+ <para>
+ Some of the values in instances of <see cref="T:log4net.Core.LoggingEvent"/>
+ are considered volatile, that is the values are correct at the
+ time the event is delivered to appenders, but will not be consistent
+ at any time afterwards. If an event is to be stored and then processed
+ at a later time these volatile values must be fixed by calling
+ <see cref="M:log4net.Core.LoggingEvent.FixVolatileData"/>. There is a performance penalty
+ incurred by calling <see cref="M:log4net.Core.LoggingEvent.FixVolatileData"/> but it
+ is essential to maintaining data consistency.
+ </para>
+ <para>
+ Calling <see cref="M:log4net.Core.LoggingEvent.FixVolatileData"/> is equivalent to
+ calling <see cref="M:log4net.Core.LoggingEvent.FixVolatileData(System.Boolean)"/> passing the parameter
+ <c>false</c>.
+ </para>
+ <para>
+ See <see cref="M:log4net.Core.LoggingEvent.FixVolatileData(System.Boolean)"/> for more
+ information.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LoggingEvent.FixVolatileData(System.Boolean)">
+ <summary>
+ Fixes instance fields that hold volatile data.
+ </summary>
+ <param name="fastButLoose">Set to <c>true</c> to not fix data that takes a long time to fix.</param>
+ <remarks>
+ <para>
+ Some of the values in instances of <see cref="T:log4net.Core.LoggingEvent"/>
+ are considered volatile, that is the values are correct at the
+ time the event is delivered to appenders, but will not be consistent
+ at any time afterwards. If an event is to be stored and then processed
+ at a later time these volatile values must be fixed by calling
+ <see cref="M:log4net.Core.LoggingEvent.FixVolatileData"/>. There is a performance penalty
+ for incurred by calling <see cref="M:log4net.Core.LoggingEvent.FixVolatileData"/> but it
+ is essential to maintaining data consistency.
+ </para>
+ <para>
+ The <paramref name="fastButLoose"/> param controls the data that
+ is fixed. Some of the data that can be fixed takes a long time to
+ generate, therefore if you do not require those settings to be fixed
+ they can be ignored by setting the <paramref name="fastButLoose"/> param
+ to <c>true</c>. This setting will ignore the <see cref="P:log4net.Core.LoggingEvent.LocationInformation"/>
+ and <see cref="P:log4net.Core.LoggingEvent.UserName"/> settings.
+ </para>
+ <para>
+ Set <paramref name="fastButLoose"/> to <c>false</c> to ensure that all
+ settings are fixed.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LoggingEvent.FixVolatileData(log4net.Core.FixFlags)">
+ <summary>
+ Fix the fields specified by the <see cref="T:log4net.Core.FixFlags"/> parameter
+ </summary>
+ <param name="flags">the fields to fix</param>
+ <remarks>
+ <para>
+ Only fields specified in the <paramref name="flags"/> will be fixed.
+ Fields will not be fixed if they have previously been fixed.
+ It is not possible to 'unfix' a field.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LoggingEvent.LookupProperty(System.String)">
+ <summary>
+ Lookup a composite property in this event
+ </summary>
+ <param name="key">the key for the property to lookup</param>
+ <returns>the value for the property</returns>
+ <remarks>
+ <para>
+ This event has composite properties that combine together properties from
+ several different contexts in the following order:
+ <list type="definition">
+ <item>
+ <term>this events properties</term>
+ <description>
+ This event has <see cref="P:log4net.Core.LoggingEvent.Properties"/> that can be set. These
+ properties are specific to this event only.
+ </description>
+ </item>
+ <item>
+ <term>the thread properties</term>
+ <description>
+ The <see cref="P:log4net.ThreadContext.Properties"/> that are set on the current
+ thread. These properties are shared by all events logged on this thread.
+ </description>
+ </item>
+ <item>
+ <term>the global properties</term>
+ <description>
+ The <see cref="P:log4net.GlobalContext.Properties"/> that are set globally. These
+ properties are shared by all the threads in the AppDomain.
+ </description>
+ </item>
+ </list>
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LoggingEvent.GetProperties">
+ <summary>
+ Get all the composite properties in this event
+ </summary>
+ <returns>the <see cref="T:log4net.Util.PropertiesDictionary"/> containing all the properties</returns>
+ <remarks>
+ <para>
+ See <see cref="M:log4net.Core.LoggingEvent.LookupProperty(System.String)"/> for details of the composite properties
+ stored by the event.
+ </para>
+ <para>
+ This method returns a single <see cref="T:log4net.Util.PropertiesDictionary"/> containing all the
+ properties defined for this event.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Core.LoggingEvent.m_data">
+ <summary>
+ The internal logging event data.
+ </summary>
+ </member>
+ <member name="F:log4net.Core.LoggingEvent.m_compositeProperties">
+ <summary>
+ The internal logging event data.
+ </summary>
+ </member>
+ <member name="F:log4net.Core.LoggingEvent.m_eventProperties">
+ <summary>
+ The internal logging event data.
+ </summary>
+ </member>
+ <member name="F:log4net.Core.LoggingEvent.m_callerStackBoundaryDeclaringType">
+ <summary>
+ The fully qualified Type of the calling
+ logger class in the stack frame (i.e. the declaring type of the method).
+ </summary>
+ </member>
+ <member name="F:log4net.Core.LoggingEvent.m_message">
+ <summary>
+ The application supplied message of logging event.
+ </summary>
+ </member>
+ <member name="F:log4net.Core.LoggingEvent.m_thrownException">
+ <summary>
+ The exception that was thrown.
+ </summary>
+ <remarks>
+ This is not serialized. The string representation
+ is serialized instead.
+ </remarks>
+ </member>
+ <member name="F:log4net.Core.LoggingEvent.m_repository">
+ <summary>
+ The repository that generated the logging event
+ </summary>
+ <remarks>
+ This is not serialized.
+ </remarks>
+ </member>
+ <member name="F:log4net.Core.LoggingEvent.m_fixFlags">
+ <summary>
+ The fix state for this event
+ </summary>
+ <remarks>
+ These flags indicate which fields have been fixed.
+ Not serialized.
+ </remarks>
+ </member>
+ <member name="F:log4net.Core.LoggingEvent.m_cacheUpdatable">
+ <summary>
+ Indicated that the internal cache is updateable (ie not fixed)
+ </summary>
+ <remarks>
+ This is a seperate flag to m_fixFlags as it allows incrementel fixing and simpler
+ changes in the caching strategy.
+ </remarks>
+ </member>
+ <member name="P:log4net.Core.LoggingEvent.StartTime">
+ <summary>
+ Gets the time when the current process started.
+ </summary>
+ <value>
+ This is the time when this process started.
+ </value>
+ <remarks>
+ <para>
+ The TimeStamp is stored in the local time zone for this computer.
+ </para>
+ <para>
+ Tries to get the start time for the current process.
+ Failing that it returns the time of the first call to
+ this property.
+ </para>
+ <para>
+ Note that AppDomains may be loaded and unloaded within the
+ same process without the process terminating and therefore
+ without the process start time being reset.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Core.LoggingEvent.Level">
+ <summary>
+ Gets the <see cref="P:log4net.Core.LoggingEvent.Level"/> of the logging event.
+ </summary>
+ <value>
+ The <see cref="P:log4net.Core.LoggingEvent.Level"/> of the logging event.
+ </value>
+ <remarks>
+ <para>
+ Gets the <see cref="P:log4net.Core.LoggingEvent.Level"/> of the logging event.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Core.LoggingEvent.TimeStamp">
+ <summary>
+ Gets the time of the logging event.
+ </summary>
+ <value>
+ The time of the logging event.
+ </value>
+ <remarks>
+ <para>
+ The TimeStamp is stored in the local time zone for this computer.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Core.LoggingEvent.LoggerName">
+ <summary>
+ Gets the name of the logger that logged the event.
+ </summary>
+ <value>
+ The name of the logger that logged the event.
+ </value>
+ <remarks>
+ <para>
+ Gets the name of the logger that logged the event.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Core.LoggingEvent.LocationInformation">
+ <summary>
+ Gets the location information for this logging event.
+ </summary>
+ <value>
+ The location information for this logging event.
+ </value>
+ <remarks>
+ <para>
+ The collected information is cached for future use.
+ </para>
+ <para>
+ See the <see cref="T:log4net.Core.LocationInfo"/> class for more information on
+ supported frameworks and the different behavior in Debug and
+ Release builds.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Core.LoggingEvent.MessageObject">
+ <summary>
+ Gets the message object used to initialize this event.
+ </summary>
+ <value>
+ The message object used to initialize this event.
+ </value>
+ <remarks>
+ <para>
+ Gets the message object used to initialize this event.
+ Note that this event may not have a valid message object.
+ If the event is serialized the message object will not
+ be transferred. To get the text of the message the
+ <see cref="P:log4net.Core.LoggingEvent.RenderedMessage"/> property must be used
+ not this property.
+ </para>
+ <para>
+ If there is no defined message object for this event then
+ null will be returned.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Core.LoggingEvent.ExceptionObject">
+ <summary>
+ Gets the exception object used to initialize this event.
+ </summary>
+ <value>
+ The exception object used to initialize this event.
+ </value>
+ <remarks>
+ <para>
+ Gets the exception object used to initialize this event.
+ Note that this event may not have a valid exception object.
+ If the event is serialized the exception object will not
+ be transferred. To get the text of the exception the
+ <see cref="M:log4net.Core.LoggingEvent.GetExceptionString"/> method must be used
+ not this property.
+ </para>
+ <para>
+ If there is no defined exception object for this event then
+ null will be returned.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Core.LoggingEvent.Repository">
+ <summary>
+ The <see cref="T:log4net.Repository.ILoggerRepository"/> that this event was created in.
+ </summary>
+ <remarks>
+ <para>
+ The <see cref="T:log4net.Repository.ILoggerRepository"/> that this event was created in.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Core.LoggingEvent.RenderedMessage">
+ <summary>
+ Gets the message, rendered through the <see cref="P:log4net.Repository.ILoggerRepository.RendererMap"/>.
+ </summary>
+ <value>
+ The message rendered through the <see cref="P:log4net.Repository.ILoggerRepository.RendererMap"/>.
+ </value>
+ <remarks>
+ <para>
+ The collected information is cached for future use.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Core.LoggingEvent.ThreadName">
+ <summary>
+ Gets the name of the current thread.
+ </summary>
+ <value>
+ The name of the current thread, or the thread ID when
+ the name is not available.
+ </value>
+ <remarks>
+ <para>
+ The collected information is cached for future use.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Core.LoggingEvent.UserName">
+ <summary>
+ Gets the name of the current user.
+ </summary>
+ <value>
+ The name of the current user, or <c>NOT AVAILABLE</c> when the
+ underlying runtime has no support for retrieving the name of the
+ current user.
+ </value>
+ <remarks>
+ <para>
+ Calls <c>WindowsIdentity.GetCurrent().Name</c> to get the name of
+ the current windows user.
+ </para>
+ <para>
+ To improve performance, we could cache the string representation of
+ the name, and reuse that as long as the identity stayed constant.
+ Once the identity changed, we would need to re-assign and re-render
+ the string.
+ </para>
+ <para>
+ However, the <c>WindowsIdentity.GetCurrent()</c> call seems to
+ return different objects every time, so the current implementation
+ doesn't do this type of caching.
+ </para>
+ <para>
+ Timing for these operations:
+ </para>
+ <list type="table">
+ <listheader>
+ <term>Method</term>
+ <description>Results</description>
+ </listheader>
+ <item>
+ <term><c>WindowsIdentity.GetCurrent()</c></term>
+ <description>10000 loops, 00:00:00.2031250 seconds</description>
+ </item>
+ <item>
+ <term><c>WindowsIdentity.GetCurrent().Name</c></term>
+ <description>10000 loops, 00:00:08.0468750 seconds</description>
+ </item>
+ </list>
+ <para>
+ This means we could speed things up almost 40 times by caching the
+ value of the <c>WindowsIdentity.GetCurrent().Name</c> property, since
+ this takes (8.04-0.20) = 7.84375 seconds.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Core.LoggingEvent.Identity">
+ <summary>
+ Gets the identity of the current thread principal.
+ </summary>
+ <value>
+ The string name of the identity of the current thread principal.
+ </value>
+ <remarks>
+ <para>
+ Calls <c>System.Threading.Thread.CurrentPrincipal.Identity.Name</c> to get
+ the name of the current thread principal.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Core.LoggingEvent.Domain">
+ <summary>
+ Gets the AppDomain friendly name.
+ </summary>
+ <value>
+ The AppDomain friendly name.
+ </value>
+ <remarks>
+ <para>
+ Gets the AppDomain friendly name.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Core.LoggingEvent.Properties">
+ <summary>
+ Additional event specific properties.
+ </summary>
+ <value>
+ Additional event specific properties.
+ </value>
+ <remarks>
+ <para>
+ A logger or an appender may attach additional
+ properties to specific events. These properties
+ have a string key and an object value.
+ </para>
+ <para>
+ This property is for events that have been added directly to
+ this event. The aggregate properties (which include these
+ event properties) can be retrieved using <see cref="M:log4net.Core.LoggingEvent.LookupProperty(System.String)"/>
+ and <see cref="M:log4net.Core.LoggingEvent.GetProperties"/>.
+ </para>
+ <para>
+ Once the properties have been fixed <see cref="P:log4net.Core.LoggingEvent.Fix"/> this property
+ returns the combined cached properties. This ensures that updates to
+ this property are always reflected in the underlying storage. When
+ returning the combined properties there may be more keys in the
+ Dictionary than expected.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Core.LoggingEvent.Fix">
+ <summary>
+ The fixed fields in this event
+ </summary>
+ <value>
+ The set of fields that are fixed in this event
+ </value>
+ <remarks>
+ <para>
+ Fields will not be fixed if they have previously been fixed.
+ It is not possible to 'unfix' a field.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Core.LogImpl">
+ <summary>
+ Implementation of <see cref="T:log4net.ILog"/> wrapper interface.
+ </summary>
+ <remarks>
+ <para>
+ This implementation of the <see cref="T:log4net.ILog"/> interface
+ forwards to the <see cref="T:log4net.Core.ILogger"/> held by the base class.
+ </para>
+ <para>
+ This logger has methods to allow the caller to log at the following
+ levels:
+ </para>
+ <list type="definition">
+ <item>
+ <term>DEBUG</term>
+ <description>
+ The <see cref="M:log4net.Core.LogImpl.Debug(System.Object)"/> and <see cref="M:log4net.Core.LogImpl.DebugFormat(System.String,System.Object[])"/> methods log messages
+ at the <c>DEBUG</c> level. That is the level with that name defined in the
+ repositories <see cref="P:log4net.Repository.ILoggerRepository.LevelMap"/>. The default value
+ for this level is <see cref="F:log4net.Core.Level.Debug"/>. The <see cref="P:log4net.Core.LogImpl.IsDebugEnabled"/>
+ property tests if this level is enabled for logging.
+ </description>
+ </item>
+ <item>
+ <term>INFO</term>
+ <description>
+ The <see cref="M:log4net.Core.LogImpl.Info(System.Object)"/> and <see cref="M:log4net.Core.LogImpl.InfoFormat(System.String,System.Object[])"/> methods log messages
+ at the <c>INFO</c> level. That is the level with that name defined in the
+ repositories <see cref="P:log4net.Repository.ILoggerRepository.LevelMap"/>. The default value
+ for this level is <see cref="F:log4net.Core.Level.Info"/>. The <see cref="P:log4net.Core.LogImpl.IsInfoEnabled"/>
+ property tests if this level is enabled for logging.
+ </description>
+ </item>
+ <item>
+ <term>WARN</term>
+ <description>
+ The <see cref="M:log4net.Core.LogImpl.Warn(System.Object)"/> and <see cref="M:log4net.Core.LogImpl.WarnFormat(System.String,System.Object[])"/> methods log messages
+ at the <c>WARN</c> level. That is the level with that name defined in the
+ repositories <see cref="P:log4net.Repository.ILoggerRepository.LevelMap"/>. The default value
+ for this level is <see cref="F:log4net.Core.Level.Warn"/>. The <see cref="P:log4net.Core.LogImpl.IsWarnEnabled"/>
+ property tests if this level is enabled for logging.
+ </description>
+ </item>
+ <item>
+ <term>ERROR</term>
+ <description>
+ The <see cref="M:log4net.Core.LogImpl.Error(System.Object)"/> and <see cref="M:log4net.Core.LogImpl.ErrorFormat(System.String,System.Object[])"/> methods log messages
+ at the <c>ERROR</c> level. That is the level with that name defined in the
+ repositories <see cref="P:log4net.Repository.ILoggerRepository.LevelMap"/>. The default value
+ for this level is <see cref="F:log4net.Core.Level.Error"/>. The <see cref="P:log4net.Core.LogImpl.IsErrorEnabled"/>
+ property tests if this level is enabled for logging.
+ </description>
+ </item>
+ <item>
+ <term>FATAL</term>
+ <description>
+ The <see cref="M:log4net.Core.LogImpl.Fatal(System.Object)"/> and <see cref="M:log4net.Core.LogImpl.FatalFormat(System.String,System.Object[])"/> methods log messages
+ at the <c>FATAL</c> level. That is the level with that name defined in the
+ repositories <see cref="P:log4net.Repository.ILoggerRepository.LevelMap"/>. The default value
+ for this level is <see cref="F:log4net.Core.Level.Fatal"/>. The <see cref="P:log4net.Core.LogImpl.IsFatalEnabled"/>
+ property tests if this level is enabled for logging.
+ </description>
+ </item>
+ </list>
+ <para>
+ The values for these levels and their semantic meanings can be changed by
+ configuring the <see cref="P:log4net.Repository.ILoggerRepository.LevelMap"/> for the repository.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="T:log4net.ILog">
+ <summary>
+ The ILog interface is use by application to log messages into
+ the log4net framework.
+ </summary>
+ <remarks>
+ <para>
+ Use the <see cref="T:log4net.LogManager"/> to obtain logger instances
+ that implement this interface. The <see cref="M:log4net.LogManager.GetLogger(System.Reflection.Assembly,System.Type)"/>
+ static method is used to get logger instances.
+ </para>
+ <para>
+ This class contains methods for logging at different levels and also
+ has properties for determining if those logging levels are
+ enabled in the current configuration.
+ </para>
+ <para>
+ This interface can be implemented in different ways. This documentation
+ specifies reasonable behavior that a caller can expect from the actual
+ implementation, however different implementations reserve the right to
+ do things differently.
+ </para>
+ </remarks>
+ <example>Simple example of logging messages
+ <code lang="C#">
+ ILog log = LogManager.GetLogger("application-log");
+
+ log.Info("Application Start");
+ log.Debug("This is a debug message");
+
+ if (log.IsDebugEnabled)
+ {
+ log.Debug("This is another debug message");
+ }
+ </code>
+ </example>
+ <seealso cref="T:log4net.LogManager"/>
+ <seealso cref="M:log4net.LogManager.GetLogger(System.Reflection.Assembly,System.Type)"/>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="M:log4net.ILog.Debug(System.Object)">
+ <overloads>Log a message object with the <see cref="F:log4net.Core.Level.Debug"/> level.</overloads>
+ <summary>
+ Log a message object with the <see cref="F:log4net.Core.Level.Debug"/> level.
+ </summary>
+ <param name="message">The message object to log.</param>
+ <remarks>
+ <para>
+ This method first checks if this logger is <c>DEBUG</c>
+ enabled by comparing the level of this logger with the
+ <see cref="F:log4net.Core.Level.Debug"/> level. If this logger is
+ <c>DEBUG</c> enabled, then it converts the message object
+ (passed as parameter) to a string by invoking the appropriate
+ <see cref="T:log4net.ObjectRenderer.IObjectRenderer"/>. It then
+ proceeds to call all the registered appenders in this logger
+ and also higher in the hierarchy depending on the value of
+ the additivity flag.
+ </para>
+ <para><b>WARNING</b> Note that passing an <see cref="T:System.Exception"/>
+ to this method will print the name of the <see cref="T:System.Exception"/>
+ but no stack trace. To print a stack trace use the
+ <see cref="M:log4net.ILog.Debug(System.Object,System.Exception)"/> form instead.
+ </para>
+ </remarks>
+ <seealso cref="M:log4net.ILog.Debug(System.Object,System.Exception)"/>
+ <seealso cref="P:log4net.ILog.IsDebugEnabled"/>
+ </member>
+ <member name="M:log4net.ILog.Debug(System.Object,System.Exception)">
+ <summary>
+ Log a message object with the <see cref="F:log4net.Core.Level.Debug"/> level including
+ the stack trace of the <see cref="T:System.Exception"/> passed
+ as a parameter.
+ </summary>
+ <param name="message">The message object to log.</param>
+ <param name="exception">The exception to log, including its stack trace.</param>
+ <remarks>
+ <para>
+ See the <see cref="M:log4net.ILog.Debug(System.Object)"/> form for more detailed information.
+ </para>
+ </remarks>
+ <seealso cref="M:log4net.ILog.Debug(System.Object)"/>
+ <seealso cref="P:log4net.ILog.IsDebugEnabled"/>
+ </member>
+ <member name="M:log4net.ILog.DebugFormat(System.String,System.Object[])">
+ <overloads>Log a formatted string with the <see cref="F:log4net.Core.Level.Debug"/> level.</overloads>
+ <summary>
+ Logs a formatted message string with the <see cref="F:log4net.Core.Level.Debug"/> level.
+ </summary>
+ <param name="format">A String containing zero or more format items</param>
+ <param name="args">An Object array containing zero or more objects to format</param>
+ <remarks>
+ <para>
+ The message is formatted using the <c>String.Format</c> method. See
+ <see cref="M:System.String.Format(System.String,System.Object[])"/> for details of the syntax of the format string and the behavior
+ of the formatting.
+ </para>
+ <para>
+ This method does not take an <see cref="T:System.Exception"/> object to include in the
+ log event. To pass an <see cref="T:System.Exception"/> use one of the <see cref="M:log4net.ILog.Debug(System.Object,System.Exception)"/>
+ methods instead.
+ </para>
+ </remarks>
+ <seealso cref="M:log4net.ILog.Debug(System.Object)"/>
+ <seealso cref="P:log4net.ILog.IsDebugEnabled"/>
+ </member>
+ <member name="M:log4net.ILog.DebugFormat(System.String,System.Object)">
+ <summary>
+ Logs a formatted message string with the <see cref="F:log4net.Core.Level.Debug"/> level.
+ </summary>
+ <param name="format">A String containing zero or more format items</param>
+ <param name="arg0">An Object to format</param>
+ <remarks>
+ <para>
+ The message is formatted using the <c>String.Format</c> method. See
+ <see cref="M:System.String.Format(System.String,System.Object[])"/> for details of the syntax of the format string and the behavior
+ of the formatting.
+ </para>
+ <para>
+ This method does not take an <see cref="T:System.Exception"/> object to include in the
+ log event. To pass an <see cref="T:System.Exception"/> use one of the <see cref="M:log4net.ILog.Debug(System.Object,System.Exception)"/>
+ methods instead.
+ </para>
+ </remarks>
+ <seealso cref="M:log4net.ILog.Debug(System.Object)"/>
+ <seealso cref="P:log4net.ILog.IsDebugEnabled"/>
+ </member>
+ <member name="M:log4net.ILog.DebugFormat(System.String,System.Object,System.Object)">
+ <summary>
+ Logs a formatted message string with the <see cref="F:log4net.Core.Level.Debug"/> level.
+ </summary>
+ <param name="format">A String containing zero or more format items</param>
+ <param name="arg0">An Object to format</param>
+ <param name="arg1">An Object to format</param>
+ <remarks>
+ <para>
+ The message is formatted using the <c>String.Format</c> method. See
+ <see cref="M:System.String.Format(System.String,System.Object[])"/> for details of the syntax of the format string and the behavior
+ of the formatting.
+ </para>
+ <para>
+ This method does not take an <see cref="T:System.Exception"/> object to include in the
+ log event. To pass an <see cref="T:System.Exception"/> use one of the <see cref="M:log4net.ILog.Debug(System.Object,System.Exception)"/>
+ methods instead.
+ </para>
+ </remarks>
+ <seealso cref="M:log4net.ILog.Debug(System.Object)"/>
+ <seealso cref="P:log4net.ILog.IsDebugEnabled"/>
+ </member>
+ <member name="M:log4net.ILog.DebugFormat(System.String,System.Object,System.Object,System.Object)">
+ <summary>
+ Logs a formatted message string with the <see cref="F:log4net.Core.Level.Debug"/> level.
+ </summary>
+ <param name="format">A String containing zero or more format items</param>
+ <param name="arg0">An Object to format</param>
+ <param name="arg1">An Object to format</param>
+ <param name="arg2">An Object to format</param>
+ <remarks>
+ <para>
+ The message is formatted using the <c>String.Format</c> method. See
+ <see cref="M:System.String.Format(System.String,System.Object[])"/> for details of the syntax of the format string and the behavior
+ of the formatting.
+ </para>
+ <para>
+ This method does not take an <see cref="T:System.Exception"/> object to include in the
+ log event. To pass an <see cref="T:System.Exception"/> use one of the <see cref="M:log4net.ILog.Debug(System.Object,System.Exception)"/>
+ methods instead.
+ </para>
+ </remarks>
+ <seealso cref="M:log4net.ILog.Debug(System.Object)"/>
+ <seealso cref="P:log4net.ILog.IsDebugEnabled"/>
+ </member>
+ <member name="M:log4net.ILog.DebugFormat(System.IFormatProvider,System.String,System.Object[])">
+ <summary>
+ Logs a formatted message string with the <see cref="F:log4net.Core.Level.Debug"/> level.
+ </summary>
+ <param name="provider">An <see cref="T:System.IFormatProvider"/> that supplies culture-specific formatting information</param>
+ <param name="format">A String containing zero or more format items</param>
+ <param name="args">An Object array containing zero or more objects to format</param>
+ <remarks>
+ <para>
+ The message is formatted using the <c>String.Format</c> method. See
+ <see cref="M:System.String.Format(System.String,System.Object[])"/> for details of the syntax of the format string and the behavior
+ of the formatting.
+ </para>
+ <para>
+ This method does not take an <see cref="T:System.Exception"/> object to include in the
+ log event. To pass an <see cref="T:System.Exception"/> use one of the <see cref="M:log4net.ILog.Debug(System.Object,System.Exception)"/>
+ methods instead.
+ </para>
+ </remarks>
+ <seealso cref="M:log4net.ILog.Debug(System.Object)"/>
+ <seealso cref="P:log4net.ILog.IsDebugEnabled"/>
+ </member>
+ <member name="M:log4net.ILog.Info(System.Object)">
+ <overloads>Log a message object with the <see cref="F:log4net.Core.Level.Info"/> level.</overloads>
+ <summary>
+ Logs a message object with the <see cref="F:log4net.Core.Level.Info"/> level.
+ </summary>
+ <remarks>
+ <para>
+ This method first checks if this logger is <c>INFO</c>
+ enabled by comparing the level of this logger with the
+ <see cref="F:log4net.Core.Level.Info"/> level. If this logger is
+ <c>INFO</c> enabled, then it converts the message object
+ (passed as parameter) to a string by invoking the appropriate
+ <see cref="T:log4net.ObjectRenderer.IObjectRenderer"/>. It then
+ proceeds to call all the registered appenders in this logger
+ and also higher in the hierarchy depending on the value of the
+ additivity flag.
+ </para>
+ <para><b>WARNING</b> Note that passing an <see cref="T:System.Exception"/>
+ to this method will print the name of the <see cref="T:System.Exception"/>
+ but no stack trace. To print a stack trace use the
+ <see cref="M:log4net.ILog.Info(System.Object,System.Exception)"/> form instead.
+ </para>
+ </remarks>
+ <param name="message">The message object to log.</param>
+ <seealso cref="M:log4net.ILog.Info(System.Object,System.Exception)"/>
+ <seealso cref="P:log4net.ILog.IsInfoEnabled"/>
+ </member>
+ <member name="M:log4net.ILog.Info(System.Object,System.Exception)">
+ <summary>
+ Logs a message object with the <c>INFO</c> level including
+ the stack trace of the <see cref="T:System.Exception"/> passed
+ as a parameter.
+ </summary>
+ <param name="message">The message object to log.</param>
+ <param name="exception">The exception to log, including its stack trace.</param>
+ <remarks>
+ <para>
+ See the <see cref="M:log4net.ILog.Info(System.Object)"/> form for more detailed information.
+ </para>
+ </remarks>
+ <seealso cref="M:log4net.ILog.Info(System.Object)"/>
+ <seealso cref="P:log4net.ILog.IsInfoEnabled"/>
+ </member>
+ <member name="M:log4net.ILog.InfoFormat(System.String,System.Object[])">
+ <overloads>Log a formatted message string with the <see cref="F:log4net.Core.Level.Info"/> level.</overloads>
+ <summary>
+ Logs a formatted message string with the <see cref="F:log4net.Core.Level.Info"/> level.
+ </summary>
+ <param name="format">A String containing zero or more format items</param>
+ <param name="args">An Object array containing zero or more objects to format</param>
+ <remarks>
+ <para>
+ The message is formatted using the <c>String.Format</c> method. See
+ <see cref="M:System.String.Format(System.String,System.Object[])"/> for details of the syntax of the format string and the behavior
+ of the formatting.
+ </para>
+ <para>
+ This method does not take an <see cref="T:System.Exception"/> object to include in the
+ log event. To pass an <see cref="T:System.Exception"/> use one of the <see cref="M:log4net.ILog.Info(System.Object)"/>
+ methods instead.
+ </para>
+ </remarks>
+ <seealso cref="M:log4net.ILog.Info(System.Object,System.Exception)"/>
+ <seealso cref="P:log4net.ILog.IsInfoEnabled"/>
+ </member>
+ <member name="M:log4net.ILog.InfoFormat(System.String,System.Object)">
+ <summary>
+ Logs a formatted message string with the <see cref="F:log4net.Core.Level.Info"/> level.
+ </summary>
+ <param name="format">A String containing zero or more format items</param>
+ <param name="arg0">An Object to format</param>
+ <remarks>
+ <para>
+ The message is formatted using the <c>String.Format</c> method. See
+ <see cref="M:System.String.Format(System.String,System.Object[])"/> for details of the syntax of the format string and the behavior
+ of the formatting.
+ </para>
+ <para>
+ This method does not take an <see cref="T:System.Exception"/> object to include in the
+ log event. To pass an <see cref="T:System.Exception"/> use one of the <see cref="M:log4net.ILog.Info(System.Object,System.Exception)"/>
+ methods instead.
+ </para>
+ </remarks>
+ <seealso cref="M:log4net.ILog.Info(System.Object)"/>
+ <seealso cref="P:log4net.ILog.IsInfoEnabled"/>
+ </member>
+ <member name="M:log4net.ILog.InfoFormat(System.String,System.Object,System.Object)">
+ <summary>
+ Logs a formatted message string with the <see cref="F:log4net.Core.Level.Info"/> level.
+ </summary>
+ <param name="format">A String containing zero or more format items</param>
+ <param name="arg0">An Object to format</param>
+ <param name="arg1">An Object to format</param>
+ <remarks>
+ <para>
+ The message is formatted using the <c>String.Format</c> method. See
+ <see cref="M:System.String.Format(System.String,System.Object[])"/> for details of the syntax of the format string and the behavior
+ of the formatting.
+ </para>
+ <para>
+ This method does not take an <see cref="T:System.Exception"/> object to include in the
+ log event. To pass an <see cref="T:System.Exception"/> use one of the <see cref="M:log4net.ILog.Info(System.Object,System.Exception)"/>
+ methods instead.
+ </para>
+ </remarks>
+ <seealso cref="M:log4net.ILog.Info(System.Object)"/>
+ <seealso cref="P:log4net.ILog.IsInfoEnabled"/>
+ </member>
+ <member name="M:log4net.ILog.InfoFormat(System.String,System.Object,System.Object,System.Object)">
+ <summary>
+ Logs a formatted message string with the <see cref="F:log4net.Core.Level.Info"/> level.
+ </summary>
+ <param name="format">A String containing zero or more format items</param>
+ <param name="arg0">An Object to format</param>
+ <param name="arg1">An Object to format</param>
+ <param name="arg2">An Object to format</param>
+ <remarks>
+ <para>
+ The message is formatted using the <c>String.Format</c> method. See
+ <see cref="M:System.String.Format(System.String,System.Object[])"/> for details of the syntax of the format string and the behavior
+ of the formatting.
+ </para>
+ <para>
+ This method does not take an <see cref="T:System.Exception"/> object to include in the
+ log event. To pass an <see cref="T:System.Exception"/> use one of the <see cref="M:log4net.ILog.Info(System.Object,System.Exception)"/>
+ methods instead.
+ </para>
+ </remarks>
+ <seealso cref="M:log4net.ILog.Info(System.Object)"/>
+ <seealso cref="P:log4net.ILog.IsInfoEnabled"/>
+ </member>
+ <member name="M:log4net.ILog.InfoFormat(System.IFormatProvider,System.String,System.Object[])">
+ <summary>
+ Logs a formatted message string with the <see cref="F:log4net.Core.Level.Info"/> level.
+ </summary>
+ <param name="provider">An <see cref="T:System.IFormatProvider"/> that supplies culture-specific formatting information</param>
+ <param name="format">A String containing zero or more format items</param>
+ <param name="args">An Object array containing zero or more objects to format</param>
+ <remarks>
+ <para>
+ The message is formatted using the <c>String.Format</c> method. See
+ <see cref="M:System.String.Format(System.String,System.Object[])"/> for details of the syntax of the format string and the behavior
+ of the formatting.
+ </para>
+ <para>
+ This method does not take an <see cref="T:System.Exception"/> object to include in the
+ log event. To pass an <see cref="T:System.Exception"/> use one of the <see cref="M:log4net.ILog.Info(System.Object)"/>
+ methods instead.
+ </para>
+ </remarks>
+ <seealso cref="M:log4net.ILog.Info(System.Object,System.Exception)"/>
+ <seealso cref="P:log4net.ILog.IsInfoEnabled"/>
+ </member>
+ <member name="M:log4net.ILog.Warn(System.Object)">
+ <overloads>Log a message object with the <see cref="F:log4net.Core.Level.Warn"/> level.</overloads>
+ <summary>
+ Log a message object with the <see cref="F:log4net.Core.Level.Warn"/> level.
+ </summary>
+ <remarks>
+ <para>
+ This method first checks if this logger is <c>WARN</c>
+ enabled by comparing the level of this logger with the
+ <see cref="F:log4net.Core.Level.Warn"/> level. If this logger is
+ <c>WARN</c> enabled, then it converts the message object
+ (passed as parameter) to a string by invoking the appropriate
+ <see cref="T:log4net.ObjectRenderer.IObjectRenderer"/>. It then
+ proceeds to call all the registered appenders in this logger
+ and also higher in the hierarchy depending on the value of the
+ additivity flag.
+ </para>
+ <para><b>WARNING</b> Note that passing an <see cref="T:System.Exception"/>
+ to this method will print the name of the <see cref="T:System.Exception"/>
+ but no stack trace. To print a stack trace use the
+ <see cref="M:log4net.ILog.Warn(System.Object,System.Exception)"/> form instead.
+ </para>
+ </remarks>
+ <param name="message">The message object to log.</param>
+ <seealso cref="M:log4net.ILog.Warn(System.Object,System.Exception)"/>
+ <seealso cref="P:log4net.ILog.IsWarnEnabled"/>
+ </member>
+ <member name="M:log4net.ILog.Warn(System.Object,System.Exception)">
+ <summary>
+ Log a message object with the <see cref="F:log4net.Core.Level.Warn"/> level including
+ the stack trace of the <see cref="T:System.Exception"/> passed
+ as a parameter.
+ </summary>
+ <param name="message">The message object to log.</param>
+ <param name="exception">The exception to log, including its stack trace.</param>
+ <remarks>
+ <para>
+ See the <see cref="M:log4net.ILog.Warn(System.Object)"/> form for more detailed information.
+ </para>
+ </remarks>
+ <seealso cref="M:log4net.ILog.Warn(System.Object)"/>
+ <seealso cref="P:log4net.ILog.IsWarnEnabled"/>
+ </member>
+ <member name="M:log4net.ILog.WarnFormat(System.String,System.Object[])">
+ <overloads>Log a formatted message string with the <see cref="F:log4net.Core.Level.Warn"/> level.</overloads>
+ <summary>
+ Logs a formatted message string with the <see cref="F:log4net.Core.Level.Warn"/> level.
+ </summary>
+ <param name="format">A String containing zero or more format items</param>
+ <param name="args">An Object array containing zero or more objects to format</param>
+ <remarks>
+ <para>
+ The message is formatted using the <c>String.Format</c> method. See
+ <see cref="M:System.String.Format(System.String,System.Object[])"/> for details of the syntax of the format string and the behavior
+ of the formatting.
+ </para>
+ <para>
+ This method does not take an <see cref="T:System.Exception"/> object to include in the
+ log event. To pass an <see cref="T:System.Exception"/> use one of the <see cref="M:log4net.ILog.Warn(System.Object)"/>
+ methods instead.
+ </para>
+ </remarks>
+ <seealso cref="M:log4net.ILog.Warn(System.Object,System.Exception)"/>
+ <seealso cref="P:log4net.ILog.IsWarnEnabled"/>
+ </member>
+ <member name="M:log4net.ILog.WarnFormat(System.String,System.Object)">
+ <summary>
+ Logs a formatted message string with the <see cref="F:log4net.Core.Level.Warn"/> level.
+ </summary>
+ <param name="format">A String containing zero or more format items</param>
+ <param name="arg0">An Object to format</param>
+ <remarks>
+ <para>
+ The message is formatted using the <c>String.Format</c> method. See
+ <see cref="M:System.String.Format(System.String,System.Object[])"/> for details of the syntax of the format string and the behavior
+ of the formatting.
+ </para>
+ <para>
+ This method does not take an <see cref="T:System.Exception"/> object to include in the
+ log event. To pass an <see cref="T:System.Exception"/> use one of the <see cref="M:log4net.ILog.Warn(System.Object,System.Exception)"/>
+ methods instead.
+ </para>
+ </remarks>
+ <seealso cref="M:log4net.ILog.Warn(System.Object)"/>
+ <seealso cref="P:log4net.ILog.IsWarnEnabled"/>
+ </member>
+ <member name="M:log4net.ILog.WarnFormat(System.String,System.Object,System.Object)">
+ <summary>
+ Logs a formatted message string with the <see cref="F:log4net.Core.Level.Warn"/> level.
+ </summary>
+ <param name="format">A String containing zero or more format items</param>
+ <param name="arg0">An Object to format</param>
+ <param name="arg1">An Object to format</param>
+ <remarks>
+ <para>
+ The message is formatted using the <c>String.Format</c> method. See
+ <see cref="M:System.String.Format(System.String,System.Object[])"/> for details of the syntax of the format string and the behavior
+ of the formatting.
+ </para>
+ <para>
+ This method does not take an <see cref="T:System.Exception"/> object to include in the
+ log event. To pass an <see cref="T:System.Exception"/> use one of the <see cref="M:log4net.ILog.Warn(System.Object,System.Exception)"/>
+ methods instead.
+ </para>
+ </remarks>
+ <seealso cref="M:log4net.ILog.Warn(System.Object)"/>
+ <seealso cref="P:log4net.ILog.IsWarnEnabled"/>
+ </member>
+ <member name="M:log4net.ILog.WarnFormat(System.String,System.Object,System.Object,System.Object)">
+ <summary>
+ Logs a formatted message string with the <see cref="F:log4net.Core.Level.Warn"/> level.
+ </summary>
+ <param name="format">A String containing zero or more format items</param>
+ <param name="arg0">An Object to format</param>
+ <param name="arg1">An Object to format</param>
+ <param name="arg2">An Object to format</param>
+ <remarks>
+ <para>
+ The message is formatted using the <c>String.Format</c> method. See
+ <see cref="M:System.String.Format(System.String,System.Object[])"/> for details of the syntax of the format string and the behavior
+ of the formatting.
+ </para>
+ <para>
+ This method does not take an <see cref="T:System.Exception"/> object to include in the
+ log event. To pass an <see cref="T:System.Exception"/> use one of the <see cref="M:log4net.ILog.Warn(System.Object,System.Exception)"/>
+ methods instead.
+ </para>
+ </remarks>
+ <seealso cref="M:log4net.ILog.Warn(System.Object)"/>
+ <seealso cref="P:log4net.ILog.IsWarnEnabled"/>
+ </member>
+ <member name="M:log4net.ILog.WarnFormat(System.IFormatProvider,System.String,System.Object[])">
+ <summary>
+ Logs a formatted message string with the <see cref="F:log4net.Core.Level.Warn"/> level.
+ </summary>
+ <param name="provider">An <see cref="T:System.IFormatProvider"/> that supplies culture-specific formatting information</param>
+ <param name="format">A String containing zero or more format items</param>
+ <param name="args">An Object array containing zero or more objects to format</param>
+ <remarks>
+ <para>
+ The message is formatted using the <c>String.Format</c> method. See
+ <see cref="M:System.String.Format(System.String,System.Object[])"/> for details of the syntax of the format string and the behavior
+ of the formatting.
+ </para>
+ <para>
+ This method does not take an <see cref="T:System.Exception"/> object to include in the
+ log event. To pass an <see cref="T:System.Exception"/> use one of the <see cref="M:log4net.ILog.Warn(System.Object)"/>
+ methods instead.
+ </para>
+ </remarks>
+ <seealso cref="M:log4net.ILog.Warn(System.Object,System.Exception)"/>
+ <seealso cref="P:log4net.ILog.IsWarnEnabled"/>
+ </member>
+ <member name="M:log4net.ILog.Error(System.Object)">
+ <overloads>Log a message object with the <see cref="F:log4net.Core.Level.Error"/> level.</overloads>
+ <summary>
+ Logs a message object with the <see cref="F:log4net.Core.Level.Error"/> level.
+ </summary>
+ <param name="message">The message object to log.</param>
+ <remarks>
+ <para>
+ This method first checks if this logger is <c>ERROR</c>
+ enabled by comparing the level of this logger with the
+ <see cref="F:log4net.Core.Level.Error"/> level. If this logger is
+ <c>ERROR</c> enabled, then it converts the message object
+ (passed as parameter) to a string by invoking the appropriate
+ <see cref="T:log4net.ObjectRenderer.IObjectRenderer"/>. It then
+ proceeds to call all the registered appenders in this logger
+ and also higher in the hierarchy depending on the value of the
+ additivity flag.
+ </para>
+ <para><b>WARNING</b> Note that passing an <see cref="T:System.Exception"/>
+ to this method will print the name of the <see cref="T:System.Exception"/>
+ but no stack trace. To print a stack trace use the
+ <see cref="M:log4net.ILog.Error(System.Object,System.Exception)"/> form instead.
+ </para>
+ </remarks>
+ <seealso cref="M:log4net.ILog.Error(System.Object,System.Exception)"/>
+ <seealso cref="P:log4net.ILog.IsErrorEnabled"/>
+ </member>
+ <member name="M:log4net.ILog.Error(System.Object,System.Exception)">
+ <summary>
+ Log a message object with the <see cref="F:log4net.Core.Level.Error"/> level including
+ the stack trace of the <see cref="T:System.Exception"/> passed
+ as a parameter.
+ </summary>
+ <param name="message">The message object to log.</param>
+ <param name="exception">The exception to log, including its stack trace.</param>
+ <remarks>
+ <para>
+ See the <see cref="M:log4net.ILog.Error(System.Object)"/> form for more detailed information.
+ </para>
+ </remarks>
+ <seealso cref="M:log4net.ILog.Error(System.Object)"/>
+ <seealso cref="P:log4net.ILog.IsErrorEnabled"/>
+ </member>
+ <member name="M:log4net.ILog.ErrorFormat(System.String,System.Object[])">
+ <overloads>Log a formatted message string with the <see cref="F:log4net.Core.Level.Error"/> level.</overloads>
+ <summary>
+ Logs a formatted message string with the <see cref="F:log4net.Core.Level.Error"/> level.
+ </summary>
+ <param name="format">A String containing zero or more format items</param>
+ <param name="args">An Object array containing zero or more objects to format</param>
+ <remarks>
+ <para>
+ The message is formatted using the <c>String.Format</c> method. See
+ <see cref="M:System.String.Format(System.String,System.Object[])"/> for details of the syntax of the format string and the behavior
+ of the formatting.
+ </para>
+ <para>
+ This method does not take an <see cref="T:System.Exception"/> object to include in the
+ log event. To pass an <see cref="T:System.Exception"/> use one of the <see cref="M:log4net.ILog.Error(System.Object)"/>
+ methods instead.
+ </para>
+ </remarks>
+ <seealso cref="M:log4net.ILog.Error(System.Object,System.Exception)"/>
+ <seealso cref="P:log4net.ILog.IsErrorEnabled"/>
+ </member>
+ <member name="M:log4net.ILog.ErrorFormat(System.String,System.Object)">
+ <summary>
+ Logs a formatted message string with the <see cref="F:log4net.Core.Level.Error"/> level.
+ </summary>
+ <param name="format">A String containing zero or more format items</param>
+ <param name="arg0">An Object to format</param>
+ <remarks>
+ <para>
+ The message is formatted using the <c>String.Format</c> method. See
+ <see cref="M:System.String.Format(System.String,System.Object[])"/> for details of the syntax of the format string and the behavior
+ of the formatting.
+ </para>
+ <para>
+ This method does not take an <see cref="T:System.Exception"/> object to include in the
+ log event. To pass an <see cref="T:System.Exception"/> use one of the <see cref="M:log4net.ILog.Error(System.Object,System.Exception)"/>
+ methods instead.
+ </para>
+ </remarks>
+ <seealso cref="M:log4net.ILog.Error(System.Object)"/>
+ <seealso cref="P:log4net.ILog.IsErrorEnabled"/>
+ </member>
+ <member name="M:log4net.ILog.ErrorFormat(System.String,System.Object,System.Object)">
+ <summary>
+ Logs a formatted message string with the <see cref="F:log4net.Core.Level.Error"/> level.
+ </summary>
+ <param name="format">A String containing zero or more format items</param>
+ <param name="arg0">An Object to format</param>
+ <param name="arg1">An Object to format</param>
+ <remarks>
+ <para>
+ The message is formatted using the <c>String.Format</c> method. See
+ <see cref="M:System.String.Format(System.String,System.Object[])"/> for details of the syntax of the format string and the behavior
+ of the formatting.
+ </para>
+ <para>
+ This method does not take an <see cref="T:System.Exception"/> object to include in the
+ log event. To pass an <see cref="T:System.Exception"/> use one of the <see cref="M:log4net.ILog.Error(System.Object,System.Exception)"/>
+ methods instead.
+ </para>
+ </remarks>
+ <seealso cref="M:log4net.ILog.Error(System.Object)"/>
+ <seealso cref="P:log4net.ILog.IsErrorEnabled"/>
+ </member>
+ <member name="M:log4net.ILog.ErrorFormat(System.String,System.Object,System.Object,System.Object)">
+ <summary>
+ Logs a formatted message string with the <see cref="F:log4net.Core.Level.Error"/> level.
+ </summary>
+ <param name="format">A String containing zero or more format items</param>
+ <param name="arg0">An Object to format</param>
+ <param name="arg1">An Object to format</param>
+ <param name="arg2">An Object to format</param>
+ <remarks>
+ <para>
+ The message is formatted using the <c>String.Format</c> method. See
+ <see cref="M:System.String.Format(System.String,System.Object[])"/> for details of the syntax of the format string and the behavior
+ of the formatting.
+ </para>
+ <para>
+ This method does not take an <see cref="T:System.Exception"/> object to include in the
+ log event. To pass an <see cref="T:System.Exception"/> use one of the <see cref="M:log4net.ILog.Error(System.Object,System.Exception)"/>
+ methods instead.
+ </para>
+ </remarks>
+ <seealso cref="M:log4net.ILog.Error(System.Object)"/>
+ <seealso cref="P:log4net.ILog.IsErrorEnabled"/>
+ </member>
+ <member name="M:log4net.ILog.ErrorFormat(System.IFormatProvider,System.String,System.Object[])">
+ <summary>
+ Logs a formatted message string with the <see cref="F:log4net.Core.Level.Error"/> level.
+ </summary>
+ <param name="provider">An <see cref="T:System.IFormatProvider"/> that supplies culture-specific formatting information</param>
+ <param name="format">A String containing zero or more format items</param>
+ <param name="args">An Object array containing zero or more objects to format</param>
+ <remarks>
+ <para>
+ The message is formatted using the <c>String.Format</c> method. See
+ <see cref="M:System.String.Format(System.String,System.Object[])"/> for details of the syntax of the format string and the behavior
+ of the formatting.
+ </para>
+ <para>
+ This method does not take an <see cref="T:System.Exception"/> object to include in the
+ log event. To pass an <see cref="T:System.Exception"/> use one of the <see cref="M:log4net.ILog.Error(System.Object)"/>
+ methods instead.
+ </para>
+ </remarks>
+ <seealso cref="M:log4net.ILog.Error(System.Object,System.Exception)"/>
+ <seealso cref="P:log4net.ILog.IsErrorEnabled"/>
+ </member>
+ <member name="M:log4net.ILog.Fatal(System.Object)">
+ <overloads>Log a message object with the <see cref="F:log4net.Core.Level.Fatal"/> level.</overloads>
+ <summary>
+ Log a message object with the <see cref="F:log4net.Core.Level.Fatal"/> level.
+ </summary>
+ <remarks>
+ <para>
+ This method first checks if this logger is <c>FATAL</c>
+ enabled by comparing the level of this logger with the
+ <see cref="F:log4net.Core.Level.Fatal"/> level. If this logger is
+ <c>FATAL</c> enabled, then it converts the message object
+ (passed as parameter) to a string by invoking the appropriate
+ <see cref="T:log4net.ObjectRenderer.IObjectRenderer"/>. It then
+ proceeds to call all the registered appenders in this logger
+ and also higher in the hierarchy depending on the value of the
+ additivity flag.
+ </para>
+ <para><b>WARNING</b> Note that passing an <see cref="T:System.Exception"/>
+ to this method will print the name of the <see cref="T:System.Exception"/>
+ but no stack trace. To print a stack trace use the
+ <see cref="M:log4net.ILog.Fatal(System.Object,System.Exception)"/> form instead.
+ </para>
+ </remarks>
+ <param name="message">The message object to log.</param>
+ <seealso cref="M:log4net.ILog.Fatal(System.Object,System.Exception)"/>
+ <seealso cref="P:log4net.ILog.IsFatalEnabled"/>
+ </member>
+ <member name="M:log4net.ILog.Fatal(System.Object,System.Exception)">
+ <summary>
+ Log a message object with the <see cref="F:log4net.Core.Level.Fatal"/> level including
+ the stack trace of the <see cref="T:System.Exception"/> passed
+ as a parameter.
+ </summary>
+ <param name="message">The message object to log.</param>
+ <param name="exception">The exception to log, including its stack trace.</param>
+ <remarks>
+ <para>
+ See the <see cref="M:log4net.ILog.Fatal(System.Object)"/> form for more detailed information.
+ </para>
+ </remarks>
+ <seealso cref="M:log4net.ILog.Fatal(System.Object)"/>
+ <seealso cref="P:log4net.ILog.IsFatalEnabled"/>
+ </member>
+ <member name="M:log4net.ILog.FatalFormat(System.String,System.Object[])">
+ <overloads>Log a formatted message string with the <see cref="F:log4net.Core.Level.Fatal"/> level.</overloads>
+ <summary>
+ Logs a formatted message string with the <see cref="F:log4net.Core.Level.Fatal"/> level.
+ </summary>
+ <param name="format">A String containing zero or more format items</param>
+ <param name="args">An Object array containing zero or more objects to format</param>
+ <remarks>
+ <para>
+ The message is formatted using the <c>String.Format</c> method. See
+ <see cref="M:System.String.Format(System.String,System.Object[])"/> for details of the syntax of the format string and the behavior
+ of the formatting.
+ </para>
+ <para>
+ This method does not take an <see cref="T:System.Exception"/> object to include in the
+ log event. To pass an <see cref="T:System.Exception"/> use one of the <see cref="M:log4net.ILog.Fatal(System.Object)"/>
+ methods instead.
+ </para>
+ </remarks>
+ <seealso cref="M:log4net.ILog.Fatal(System.Object,System.Exception)"/>
+ <seealso cref="P:log4net.ILog.IsFatalEnabled"/>
+ </member>
+ <member name="M:log4net.ILog.FatalFormat(System.String,System.Object)">
+ <summary>
+ Logs a formatted message string with the <see cref="F:log4net.Core.Level.Fatal"/> level.
+ </summary>
+ <param name="format">A String containing zero or more format items</param>
+ <param name="arg0">An Object to format</param>
+ <remarks>
+ <para>
+ The message is formatted using the <c>String.Format</c> method. See
+ <see cref="M:System.String.Format(System.String,System.Object[])"/> for details of the syntax of the format string and the behavior
+ of the formatting.
+ </para>
+ <para>
+ This method does not take an <see cref="T:System.Exception"/> object to include in the
+ log event. To pass an <see cref="T:System.Exception"/> use one of the <see cref="M:log4net.ILog.Fatal(System.Object,System.Exception)"/>
+ methods instead.
+ </para>
+ </remarks>
+ <seealso cref="M:log4net.ILog.Fatal(System.Object)"/>
+ <seealso cref="P:log4net.ILog.IsFatalEnabled"/>
+ </member>
+ <member name="M:log4net.ILog.FatalFormat(System.String,System.Object,System.Object)">
+ <summary>
+ Logs a formatted message string with the <see cref="F:log4net.Core.Level.Fatal"/> level.
+ </summary>
+ <param name="format">A String containing zero or more format items</param>
+ <param name="arg0">An Object to format</param>
+ <param name="arg1">An Object to format</param>
+ <remarks>
+ <para>
+ The message is formatted using the <c>String.Format</c> method. See
+ <see cref="M:System.String.Format(System.String,System.Object[])"/> for details of the syntax of the format string and the behavior
+ of the formatting.
+ </para>
+ <para>
+ This method does not take an <see cref="T:System.Exception"/> object to include in the
+ log event. To pass an <see cref="T:System.Exception"/> use one of the <see cref="M:log4net.ILog.Fatal(System.Object,System.Exception)"/>
+ methods instead.
+ </para>
+ </remarks>
+ <seealso cref="M:log4net.ILog.Fatal(System.Object)"/>
+ <seealso cref="P:log4net.ILog.IsFatalEnabled"/>
+ </member>
+ <member name="M:log4net.ILog.FatalFormat(System.String,System.Object,System.Object,System.Object)">
+ <summary>
+ Logs a formatted message string with the <see cref="F:log4net.Core.Level.Fatal"/> level.
+ </summary>
+ <param name="format">A String containing zero or more format items</param>
+ <param name="arg0">An Object to format</param>
+ <param name="arg1">An Object to format</param>
+ <param name="arg2">An Object to format</param>
+ <remarks>
+ <para>
+ The message is formatted using the <c>String.Format</c> method. See
+ <see cref="M:System.String.Format(System.String,System.Object[])"/> for details of the syntax of the format string and the behavior
+ of the formatting.
+ </para>
+ <para>
+ This method does not take an <see cref="T:System.Exception"/> object to include in the
+ log event. To pass an <see cref="T:System.Exception"/> use one of the <see cref="M:log4net.ILog.Fatal(System.Object,System.Exception)"/>
+ methods instead.
+ </para>
+ </remarks>
+ <seealso cref="M:log4net.ILog.Fatal(System.Object)"/>
+ <seealso cref="P:log4net.ILog.IsFatalEnabled"/>
+ </member>
+ <member name="M:log4net.ILog.FatalFormat(System.IFormatProvider,System.String,System.Object[])">
+ <summary>
+ Logs a formatted message string with the <see cref="F:log4net.Core.Level.Fatal"/> level.
+ </summary>
+ <param name="provider">An <see cref="T:System.IFormatProvider"/> that supplies culture-specific formatting information</param>
+ <param name="format">A String containing zero or more format items</param>
+ <param name="args">An Object array containing zero or more objects to format</param>
+ <remarks>
+ <para>
+ The message is formatted using the <c>String.Format</c> method. See
+ <see cref="M:System.String.Format(System.String,System.Object[])"/> for details of the syntax of the format string and the behavior
+ of the formatting.
+ </para>
+ <para>
+ This method does not take an <see cref="T:System.Exception"/> object to include in the
+ log event. To pass an <see cref="T:System.Exception"/> use one of the <see cref="M:log4net.ILog.Fatal(System.Object)"/>
+ methods instead.
+ </para>
+ </remarks>
+ <seealso cref="M:log4net.ILog.Fatal(System.Object,System.Exception)"/>
+ <seealso cref="P:log4net.ILog.IsFatalEnabled"/>
+ </member>
+ <member name="P:log4net.ILog.IsDebugEnabled">
+ <summary>
+ Checks if this logger is enabled for the <see cref="F:log4net.Core.Level.Debug"/> level.
+ </summary>
+ <value>
+ <c>true</c> if this logger is enabled for <see cref="F:log4net.Core.Level.Debug"/> events, <c>false</c> otherwise.
+ </value>
+ <remarks>
+ <para>
+ This function is intended to lessen the computational cost of
+ disabled log debug statements.
+ </para>
+ <para> For some ILog interface <c>log</c>, when you write:</para>
+ <code lang="C#">
+ log.Debug("This is entry number: " + i );
+ </code>
+ <para>
+ You incur the cost constructing the message, string construction and concatenation in
+ this case, regardless of whether the message is logged or not.
+ </para>
+ <para>
+ If you are worried about speed (who isn't), then you should write:
+ </para>
+ <code lang="C#">
+ if (log.IsDebugEnabled)
+ {
+ log.Debug("This is entry number: " + i );
+ }
+ </code>
+ <para>
+ This way you will not incur the cost of parameter
+ construction if debugging is disabled for <c>log</c>. On
+ the other hand, if the <c>log</c> is debug enabled, you
+ will incur the cost of evaluating whether the logger is debug
+ enabled twice. Once in <see cref="P:log4net.ILog.IsDebugEnabled"/> and once in
+ the <see cref="M:log4net.ILog.Debug(System.Object)"/>. This is an insignificant overhead
+ since evaluating a logger takes about 1% of the time it
+ takes to actually log. This is the preferred style of logging.
+ </para>
+ <para>Alternatively if your logger is available statically then the is debug
+ enabled state can be stored in a static variable like this:
+ </para>
+ <code lang="C#">
+ private static readonly bool isDebugEnabled = log.IsDebugEnabled;
+ </code>
+ <para>
+ Then when you come to log you can write:
+ </para>
+ <code lang="C#">
+ if (isDebugEnabled)
+ {
+ log.Debug("This is entry number: " + i );
+ }
+ </code>
+ <para>
+ This way the debug enabled state is only queried once
+ when the class is loaded. Using a <c>private static readonly</c>
+ variable is the most efficient because it is a run time constant
+ and can be heavily optimized by the JIT compiler.
+ </para>
+ <para>
+ Of course if you use a static readonly variable to
+ hold the enabled state of the logger then you cannot
+ change the enabled state at runtime to vary the logging
+ that is produced. You have to decide if you need absolute
+ speed or runtime flexibility.
+ </para>
+ </remarks>
+ <seealso cref="M:log4net.ILog.Debug(System.Object)"/>
+ <seealso cref="M:log4net.ILog.DebugFormat(System.IFormatProvider,System.String,System.Object[])"/>
+ </member>
+ <member name="P:log4net.ILog.IsInfoEnabled">
+ <summary>
+ Checks if this logger is enabled for the <see cref="F:log4net.Core.Level.Info"/> level.
+ </summary>
+ <value>
+ <c>true</c> if this logger is enabled for <see cref="F:log4net.Core.Level.Info"/> events, <c>false</c> otherwise.
+ </value>
+ <remarks>
+ For more information see <see cref="P:log4net.ILog.IsDebugEnabled"/>.
+ </remarks>
+ <seealso cref="M:log4net.ILog.Info(System.Object)"/>
+ <seealso cref="M:log4net.ILog.InfoFormat(System.IFormatProvider,System.String,System.Object[])"/>
+ <seealso cref="P:log4net.ILog.IsDebugEnabled"/>
+ </member>
+ <member name="P:log4net.ILog.IsWarnEnabled">
+ <summary>
+ Checks if this logger is enabled for the <see cref="F:log4net.Core.Level.Warn"/> level.
+ </summary>
+ <value>
+ <c>true</c> if this logger is enabled for <see cref="F:log4net.Core.Level.Warn"/> events, <c>false</c> otherwise.
+ </value>
+ <remarks>
+ For more information see <see cref="P:log4net.ILog.IsDebugEnabled"/>.
+ </remarks>
+ <seealso cref="M:log4net.ILog.Warn(System.Object)"/>
+ <seealso cref="M:log4net.ILog.WarnFormat(System.IFormatProvider,System.String,System.Object[])"/>
+ <seealso cref="P:log4net.ILog.IsDebugEnabled"/>
+ </member>
+ <member name="P:log4net.ILog.IsErrorEnabled">
+ <summary>
+ Checks if this logger is enabled for the <see cref="F:log4net.Core.Level.Error"/> level.
+ </summary>
+ <value>
+ <c>true</c> if this logger is enabled for <see cref="F:log4net.Core.Level.Error"/> events, <c>false</c> otherwise.
+ </value>
+ <remarks>
+ For more information see <see cref="P:log4net.ILog.IsDebugEnabled"/>.
+ </remarks>
+ <seealso cref="M:log4net.ILog.Error(System.Object)"/>
+ <seealso cref="M:log4net.ILog.ErrorFormat(System.IFormatProvider,System.String,System.Object[])"/>
+ <seealso cref="P:log4net.ILog.IsDebugEnabled"/>
+ </member>
+ <member name="P:log4net.ILog.IsFatalEnabled">
+ <summary>
+ Checks if this logger is enabled for the <see cref="F:log4net.Core.Level.Fatal"/> level.
+ </summary>
+ <value>
+ <c>true</c> if this logger is enabled for <see cref="F:log4net.Core.Level.Fatal"/> events, <c>false</c> otherwise.
+ </value>
+ <remarks>
+ For more information see <see cref="P:log4net.ILog.IsDebugEnabled"/>.
+ </remarks>
+ <seealso cref="M:log4net.ILog.Fatal(System.Object)"/>
+ <seealso cref="M:log4net.ILog.FatalFormat(System.IFormatProvider,System.String,System.Object[])"/>
+ <seealso cref="P:log4net.ILog.IsDebugEnabled"/>
+ </member>
+ <member name="M:log4net.Core.LogImpl.#ctor(log4net.Core.ILogger)">
+ <summary>
+ Construct a new wrapper for the specified logger.
+ </summary>
+ <param name="logger">The logger to wrap.</param>
+ <remarks>
+ <para>
+ Construct a new wrapper for the specified logger.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LogImpl.ReloadLevels(log4net.Repository.ILoggerRepository)">
+ <summary>
+ Virtual method called when the configuration of the repository changes
+ </summary>
+ <param name="repository">the repository holding the levels</param>
+ <remarks>
+ <para>
+ Virtual method called when the configuration of the repository changes
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LogImpl.Debug(System.Object)">
+ <summary>
+ Logs a message object with the <c>DEBUG</c> level.
+ </summary>
+ <param name="message">The message object to log.</param>
+ <remarks>
+ <para>
+ This method first checks if this logger is <c>DEBUG</c>
+ enabled by comparing the level of this logger with the
+ <c>DEBUG</c> level. If this logger is
+ <c>DEBUG</c> enabled, then it converts the message object
+ (passed as parameter) to a string by invoking the appropriate
+ <see cref="T:log4net.ObjectRenderer.IObjectRenderer"/>. It then
+ proceeds to call all the registered appenders in this logger
+ and also higher in the hierarchy depending on the value of the
+ additivity flag.
+ </para>
+ <para>
+ <b>WARNING</b> Note that passing an <see cref="T:System.Exception"/>
+ to this method will print the name of the <see cref="T:System.Exception"/>
+ but no stack trace. To print a stack trace use the
+ <see cref="M:log4net.Core.LogImpl.Debug(System.Object,System.Exception)"/> form instead.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LogImpl.Debug(System.Object,System.Exception)">
+ <summary>
+ Logs a message object with the <c>DEBUG</c> level
+ </summary>
+ <param name="message">The message object to log.</param>
+ <param name="exception">The exception to log, including its stack trace.</param>
+ <remarks>
+ <para>
+ Logs a message object with the <c>DEBUG</c> level including
+ the stack trace of the <see cref="T:System.Exception"/> <paramref name="exception"/> passed
+ as a parameter.
+ </para>
+ <para>
+ See the <see cref="M:log4net.Core.LogImpl.Debug(System.Object)"/> form for more detailed information.
+ </para>
+ </remarks>
+ <seealso cref="M:log4net.Core.LogImpl.Debug(System.Object)"/>
+ </member>
+ <member name="M:log4net.Core.LogImpl.DebugFormat(System.String,System.Object[])">
+ <summary>
+ Logs a formatted message string with the <c>DEBUG</c> level.
+ </summary>
+ <param name="format">A String containing zero or more format items</param>
+ <param name="args">An Object array containing zero or more objects to format</param>
+ <remarks>
+ <para>
+ The message is formatted using the <see cref="M:System.String.Format(System.IFormatProvider,System.String,System.Object[])"/> method. See
+ <c>String.Format</c> for details of the syntax of the format string and the behavior
+ of the formatting.
+ </para>
+ <para>
+ The string is formatted using the <see cref="P:System.Globalization.CultureInfo.InvariantCulture"/>
+ format provider. To specify a localized provider use the
+ <see cref="M:log4net.Core.LogImpl.DebugFormat(System.IFormatProvider,System.String,System.Object[])"/> method.
+ </para>
+ <para>
+ This method does not take an <see cref="T:System.Exception"/> object to include in the
+ log event. To pass an <see cref="T:System.Exception"/> use one of the <see cref="M:log4net.Core.LogImpl.Debug(System.Object)"/>
+ methods instead.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LogImpl.DebugFormat(System.String,System.Object)">
+ <summary>
+ Logs a formatted message string with the <c>DEBUG</c> level.
+ </summary>
+ <param name="format">A String containing zero or more format items</param>
+ <param name="arg0">An Object to format</param>
+ <remarks>
+ <para>
+ The message is formatted using the <see cref="M:System.String.Format(System.IFormatProvider,System.String,System.Object[])"/> method. See
+ <c>String.Format</c> for details of the syntax of the format string and the behavior
+ of the formatting.
+ </para>
+ <para>
+ The string is formatted using the <see cref="P:System.Globalization.CultureInfo.InvariantCulture"/>
+ format provider. To specify a localized provider use the
+ <see cref="M:log4net.Core.LogImpl.DebugFormat(System.IFormatProvider,System.String,System.Object[])"/> method.
+ </para>
+ <para>
+ This method does not take an <see cref="T:System.Exception"/> object to include in the
+ log event. To pass an <see cref="T:System.Exception"/> use one of the <see cref="M:log4net.Core.LogImpl.Debug(System.Object)"/>
+ methods instead.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LogImpl.DebugFormat(System.String,System.Object,System.Object)">
+ <summary>
+ Logs a formatted message string with the <c>DEBUG</c> level.
+ </summary>
+ <param name="format">A String containing zero or more format items</param>
+ <param name="arg0">An Object to format</param>
+ <param name="arg1">An Object to format</param>
+ <remarks>
+ <para>
+ The message is formatted using the <see cref="M:System.String.Format(System.IFormatProvider,System.String,System.Object[])"/> method. See
+ <c>String.Format</c> for details of the syntax of the format string and the behavior
+ of the formatting.
+ </para>
+ <para>
+ The string is formatted using the <see cref="P:System.Globalization.CultureInfo.InvariantCulture"/>
+ format provider. To specify a localized provider use the
+ <see cref="M:log4net.Core.LogImpl.DebugFormat(System.IFormatProvider,System.String,System.Object[])"/> method.
+ </para>
+ <para>
+ This method does not take an <see cref="T:System.Exception"/> object to include in the
+ log event. To pass an <see cref="T:System.Exception"/> use one of the <see cref="M:log4net.Core.LogImpl.Debug(System.Object)"/>
+ methods instead.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LogImpl.DebugFormat(System.String,System.Object,System.Object,System.Object)">
+ <summary>
+ Logs a formatted message string with the <c>DEBUG</c> level.
+ </summary>
+ <param name="format">A String containing zero or more format items</param>
+ <param name="arg0">An Object to format</param>
+ <param name="arg1">An Object to format</param>
+ <param name="arg2">An Object to format</param>
+ <remarks>
+ <para>
+ The message is formatted using the <see cref="M:System.String.Format(System.IFormatProvider,System.String,System.Object[])"/> method. See
+ <c>String.Format</c> for details of the syntax of the format string and the behavior
+ of the formatting.
+ </para>
+ <para>
+ The string is formatted using the <see cref="P:System.Globalization.CultureInfo.InvariantCulture"/>
+ format provider. To specify a localized provider use the
+ <see cref="M:log4net.Core.LogImpl.DebugFormat(System.IFormatProvider,System.String,System.Object[])"/> method.
+ </para>
+ <para>
+ This method does not take an <see cref="T:System.Exception"/> object to include in the
+ log event. To pass an <see cref="T:System.Exception"/> use one of the <see cref="M:log4net.Core.LogImpl.Debug(System.Object)"/>
+ methods instead.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LogImpl.DebugFormat(System.IFormatProvider,System.String,System.Object[])">
+ <summary>
+ Logs a formatted message string with the <c>DEBUG</c> level.
+ </summary>
+ <param name="provider">An <see cref="T:System.IFormatProvider"/> that supplies culture-specific formatting information</param>
+ <param name="format">A String containing zero or more format items</param>
+ <param name="args">An Object array containing zero or more objects to format</param>
+ <remarks>
+ <para>
+ The message is formatted using the <see cref="M:System.String.Format(System.IFormatProvider,System.String,System.Object[])"/> method. See
+ <c>String.Format</c> for details of the syntax of the format string and the behavior
+ of the formatting.
+ </para>
+ <para>
+ This method does not take an <see cref="T:System.Exception"/> object to include in the
+ log event. To pass an <see cref="T:System.Exception"/> use one of the <see cref="M:log4net.Core.LogImpl.Debug(System.Object)"/>
+ methods instead.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LogImpl.Info(System.Object)">
+ <summary>
+ Logs a message object with the <c>INFO</c> level.
+ </summary>
+ <param name="message">The message object to log.</param>
+ <remarks>
+ <para>
+ This method first checks if this logger is <c>INFO</c>
+ enabled by comparing the level of this logger with the
+ <c>INFO</c> level. If this logger is
+ <c>INFO</c> enabled, then it converts the message object
+ (passed as parameter) to a string by invoking the appropriate
+ <see cref="T:log4net.ObjectRenderer.IObjectRenderer"/>. It then
+ proceeds to call all the registered appenders in this logger
+ and also higher in the hierarchy depending on the value of
+ the additivity flag.
+ </para>
+ <para>
+ <b>WARNING</b> Note that passing an <see cref="T:System.Exception"/>
+ to this method will print the name of the <see cref="T:System.Exception"/>
+ but no stack trace. To print a stack trace use the
+ <see cref="M:log4net.Core.LogImpl.Info(System.Object,System.Exception)"/> form instead.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LogImpl.Info(System.Object,System.Exception)">
+ <summary>
+ Logs a message object with the <c>INFO</c> level.
+ </summary>
+ <param name="message">The message object to log.</param>
+ <param name="exception">The exception to log, including its stack trace.</param>
+ <remarks>
+ <para>
+ Logs a message object with the <c>INFO</c> level including
+ the stack trace of the <see cref="T:System.Exception"/> <paramref name="exception"/>
+ passed as a parameter.
+ </para>
+ <para>
+ See the <see cref="M:log4net.Core.LogImpl.Info(System.Object)"/> form for more detailed information.
+ </para>
+ </remarks>
+ <seealso cref="M:log4net.Core.LogImpl.Info(System.Object)"/>
+ </member>
+ <member name="M:log4net.Core.LogImpl.InfoFormat(System.String,System.Object[])">
+ <summary>
+ Logs a formatted message string with the <c>INFO</c> level.
+ </summary>
+ <param name="format">A String containing zero or more format items</param>
+ <param name="args">An Object array containing zero or more objects to format</param>
+ <remarks>
+ <para>
+ The message is formatted using the <see cref="M:System.String.Format(System.IFormatProvider,System.String,System.Object[])"/> method. See
+ <c>String.Format</c> for details of the syntax of the format string and the behavior
+ of the formatting.
+ </para>
+ <para>
+ The string is formatted using the <see cref="P:System.Globalization.CultureInfo.InvariantCulture"/>
+ format provider. To specify a localized provider use the
+ <see cref="M:log4net.Core.LogImpl.InfoFormat(System.IFormatProvider,System.String,System.Object[])"/> method.
+ </para>
+ <para>
+ This method does not take an <see cref="T:System.Exception"/> object to include in the
+ log event. To pass an <see cref="T:System.Exception"/> use one of the <see cref="M:log4net.Core.LogImpl.Info(System.Object)"/>
+ methods instead.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LogImpl.InfoFormat(System.String,System.Object)">
+ <summary>
+ Logs a formatted message string with the <c>INFO</c> level.
+ </summary>
+ <param name="format">A String containing zero or more format items</param>
+ <param name="arg0">An Object to format</param>
+ <remarks>
+ <para>
+ The message is formatted using the <see cref="M:System.String.Format(System.IFormatProvider,System.String,System.Object[])"/> method. See
+ <c>String.Format</c> for details of the syntax of the format string and the behavior
+ of the formatting.
+ </para>
+ <para>
+ The string is formatted using the <see cref="P:System.Globalization.CultureInfo.InvariantCulture"/>
+ format provider. To specify a localized provider use the
+ <see cref="M:log4net.Core.LogImpl.InfoFormat(System.IFormatProvider,System.String,System.Object[])"/> method.
+ </para>
+ <para>
+ This method does not take an <see cref="T:System.Exception"/> object to include in the
+ log event. To pass an <see cref="T:System.Exception"/> use one of the <see cref="M:log4net.Core.LogImpl.Info(System.Object)"/>
+ methods instead.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LogImpl.InfoFormat(System.String,System.Object,System.Object)">
+ <summary>
+ Logs a formatted message string with the <c>INFO</c> level.
+ </summary>
+ <param name="format">A String containing zero or more format items</param>
+ <param name="arg0">An Object to format</param>
+ <param name="arg1">An Object to format</param>
+ <remarks>
+ <para>
+ The message is formatted using the <see cref="M:System.String.Format(System.IFormatProvider,System.String,System.Object[])"/> method. See
+ <c>String.Format</c> for details of the syntax of the format string and the behavior
+ of the formatting.
+ </para>
+ <para>
+ The string is formatted using the <see cref="P:System.Globalization.CultureInfo.InvariantCulture"/>
+ format provider. To specify a localized provider use the
+ <see cref="M:log4net.Core.LogImpl.InfoFormat(System.IFormatProvider,System.String,System.Object[])"/> method.
+ </para>
+ <para>
+ This method does not take an <see cref="T:System.Exception"/> object to include in the
+ log event. To pass an <see cref="T:System.Exception"/> use one of the <see cref="M:log4net.Core.LogImpl.Info(System.Object)"/>
+ methods instead.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LogImpl.InfoFormat(System.String,System.Object,System.Object,System.Object)">
+ <summary>
+ Logs a formatted message string with the <c>INFO</c> level.
+ </summary>
+ <param name="format">A String containing zero or more format items</param>
+ <param name="arg0">An Object to format</param>
+ <param name="arg1">An Object to format</param>
+ <param name="arg2">An Object to format</param>
+ <remarks>
+ <para>
+ The message is formatted using the <see cref="M:System.String.Format(System.IFormatProvider,System.String,System.Object[])"/> method. See
+ <c>String.Format</c> for details of the syntax of the format string and the behavior
+ of the formatting.
+ </para>
+ <para>
+ The string is formatted using the <see cref="P:System.Globalization.CultureInfo.InvariantCulture"/>
+ format provider. To specify a localized provider use the
+ <see cref="M:log4net.Core.LogImpl.InfoFormat(System.IFormatProvider,System.String,System.Object[])"/> method.
+ </para>
+ <para>
+ This method does not take an <see cref="T:System.Exception"/> object to include in the
+ log event. To pass an <see cref="T:System.Exception"/> use one of the <see cref="M:log4net.Core.LogImpl.Info(System.Object)"/>
+ methods instead.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LogImpl.InfoFormat(System.IFormatProvider,System.String,System.Object[])">
+ <summary>
+ Logs a formatted message string with the <c>INFO</c> level.
+ </summary>
+ <param name="provider">An <see cref="T:System.IFormatProvider"/> that supplies culture-specific formatting information</param>
+ <param name="format">A String containing zero or more format items</param>
+ <param name="args">An Object array containing zero or more objects to format</param>
+ <remarks>
+ <para>
+ The message is formatted using the <see cref="M:System.String.Format(System.IFormatProvider,System.String,System.Object[])"/> method. See
+ <c>String.Format</c> for details of the syntax of the format string and the behavior
+ of the formatting.
+ </para>
+ <para>
+ This method does not take an <see cref="T:System.Exception"/> object to include in the
+ log event. To pass an <see cref="T:System.Exception"/> use one of the <see cref="M:log4net.Core.LogImpl.Info(System.Object)"/>
+ methods instead.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LogImpl.Warn(System.Object)">
+ <summary>
+ Logs a message object with the <c>WARN</c> level.
+ </summary>
+ <param name="message">the message object to log</param>
+ <remarks>
+ <para>
+ This method first checks if this logger is <c>WARN</c>
+ enabled by comparing the level of this logger with the
+ <c>WARN</c> level. If this logger is
+ <c>WARN</c> enabled, then it converts the message object
+ (passed as parameter) to a string by invoking the appropriate
+ <see cref="T:log4net.ObjectRenderer.IObjectRenderer"/>. It then
+ proceeds to call all the registered appenders in this logger and
+ also higher in the hierarchy depending on the value of the
+ additivity flag.
+ </para>
+ <para>
+ <b>WARNING</b> Note that passing an <see cref="T:System.Exception"/> to this
+ method will print the name of the <see cref="T:System.Exception"/> but no
+ stack trace. To print a stack trace use the
+ <see cref="M:log4net.Core.LogImpl.Warn(System.Object,System.Exception)"/> form instead.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LogImpl.Warn(System.Object,System.Exception)">
+ <summary>
+ Logs a message object with the <c>WARN</c> level
+ </summary>
+ <param name="message">The message object to log.</param>
+ <param name="exception">The exception to log, including its stack trace.</param>
+ <remarks>
+ <para>
+ Logs a message object with the <c>WARN</c> level including
+ the stack trace of the <see cref="T:System.Exception"/> <paramref name="exception"/>
+ passed as a parameter.
+ </para>
+ <para>
+ See the <see cref="M:log4net.Core.LogImpl.Warn(System.Object)"/> form for more detailed information.
+ </para>
+ </remarks>
+ <seealso cref="M:log4net.Core.LogImpl.Warn(System.Object)"/>
+ </member>
+ <member name="M:log4net.Core.LogImpl.WarnFormat(System.String,System.Object[])">
+ <summary>
+ Logs a formatted message string with the <c>WARN</c> level.
+ </summary>
+ <param name="format">A String containing zero or more format items</param>
+ <param name="args">An Object array containing zero or more objects to format</param>
+ <remarks>
+ <para>
+ The message is formatted using the <see cref="M:System.String.Format(System.IFormatProvider,System.String,System.Object[])"/> method. See
+ <c>String.Format</c> for details of the syntax of the format string and the behavior
+ of the formatting.
+ </para>
+ <para>
+ The string is formatted using the <see cref="P:System.Globalization.CultureInfo.InvariantCulture"/>
+ format provider. To specify a localized provider use the
+ <see cref="M:log4net.Core.LogImpl.WarnFormat(System.IFormatProvider,System.String,System.Object[])"/> method.
+ </para>
+ <para>
+ This method does not take an <see cref="T:System.Exception"/> object to include in the
+ log event. To pass an <see cref="T:System.Exception"/> use one of the <see cref="M:log4net.Core.LogImpl.Warn(System.Object)"/>
+ methods instead.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LogImpl.WarnFormat(System.String,System.Object)">
+ <summary>
+ Logs a formatted message string with the <c>WARN</c> level.
+ </summary>
+ <param name="format">A String containing zero or more format items</param>
+ <param name="arg0">An Object to format</param>
+ <remarks>
+ <para>
+ The message is formatted using the <see cref="M:System.String.Format(System.IFormatProvider,System.String,System.Object[])"/> method. See
+ <c>String.Format</c> for details of the syntax of the format string and the behavior
+ of the formatting.
+ </para>
+ <para>
+ The string is formatted using the <see cref="P:System.Globalization.CultureInfo.InvariantCulture"/>
+ format provider. To specify a localized provider use the
+ <see cref="M:log4net.Core.LogImpl.WarnFormat(System.IFormatProvider,System.String,System.Object[])"/> method.
+ </para>
+ <para>
+ This method does not take an <see cref="T:System.Exception"/> object to include in the
+ log event. To pass an <see cref="T:System.Exception"/> use one of the <see cref="M:log4net.Core.LogImpl.Warn(System.Object)"/>
+ methods instead.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LogImpl.WarnFormat(System.String,System.Object,System.Object)">
+ <summary>
+ Logs a formatted message string with the <c>WARN</c> level.
+ </summary>
+ <param name="format">A String containing zero or more format items</param>
+ <param name="arg0">An Object to format</param>
+ <param name="arg1">An Object to format</param>
+ <remarks>
+ <para>
+ The message is formatted using the <see cref="M:System.String.Format(System.IFormatProvider,System.String,System.Object[])"/> method. See
+ <c>String.Format</c> for details of the syntax of the format string and the behavior
+ of the formatting.
+ </para>
+ <para>
+ The string is formatted using the <see cref="P:System.Globalization.CultureInfo.InvariantCulture"/>
+ format provider. To specify a localized provider use the
+ <see cref="M:log4net.Core.LogImpl.WarnFormat(System.IFormatProvider,System.String,System.Object[])"/> method.
+ </para>
+ <para>
+ This method does not take an <see cref="T:System.Exception"/> object to include in the
+ log event. To pass an <see cref="T:System.Exception"/> use one of the <see cref="M:log4net.Core.LogImpl.Warn(System.Object)"/>
+ methods instead.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LogImpl.WarnFormat(System.String,System.Object,System.Object,System.Object)">
+ <summary>
+ Logs a formatted message string with the <c>WARN</c> level.
+ </summary>
+ <param name="format">A String containing zero or more format items</param>
+ <param name="arg0">An Object to format</param>
+ <param name="arg1">An Object to format</param>
+ <param name="arg2">An Object to format</param>
+ <remarks>
+ <para>
+ The message is formatted using the <see cref="M:System.String.Format(System.IFormatProvider,System.String,System.Object[])"/> method. See
+ <c>String.Format</c> for details of the syntax of the format string and the behavior
+ of the formatting.
+ </para>
+ <para>
+ The string is formatted using the <see cref="P:System.Globalization.CultureInfo.InvariantCulture"/>
+ format provider. To specify a localized provider use the
+ <see cref="M:log4net.Core.LogImpl.WarnFormat(System.IFormatProvider,System.String,System.Object[])"/> method.
+ </para>
+ <para>
+ This method does not take an <see cref="T:System.Exception"/> object to include in the
+ log event. To pass an <see cref="T:System.Exception"/> use one of the <see cref="M:log4net.Core.LogImpl.Warn(System.Object)"/>
+ methods instead.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LogImpl.WarnFormat(System.IFormatProvider,System.String,System.Object[])">
+ <summary>
+ Logs a formatted message string with the <c>WARN</c> level.
+ </summary>
+ <param name="provider">An <see cref="T:System.IFormatProvider"/> that supplies culture-specific formatting information</param>
+ <param name="format">A String containing zero or more format items</param>
+ <param name="args">An Object array containing zero or more objects to format</param>
+ <remarks>
+ <para>
+ The message is formatted using the <see cref="M:System.String.Format(System.IFormatProvider,System.String,System.Object[])"/> method. See
+ <c>String.Format</c> for details of the syntax of the format string and the behavior
+ of the formatting.
+ </para>
+ <para>
+ This method does not take an <see cref="T:System.Exception"/> object to include in the
+ log event. To pass an <see cref="T:System.Exception"/> use one of the <see cref="M:log4net.Core.LogImpl.Warn(System.Object)"/>
+ methods instead.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LogImpl.Error(System.Object)">
+ <summary>
+ Logs a message object with the <c>ERROR</c> level.
+ </summary>
+ <param name="message">The message object to log.</param>
+ <remarks>
+ <para>
+ This method first checks if this logger is <c>ERROR</c>
+ enabled by comparing the level of this logger with the
+ <c>ERROR</c> level. If this logger is
+ <c>ERROR</c> enabled, then it converts the message object
+ (passed as parameter) to a string by invoking the appropriate
+ <see cref="T:log4net.ObjectRenderer.IObjectRenderer"/>. It then
+ proceeds to call all the registered appenders in this logger and
+ also higher in the hierarchy depending on the value of the
+ additivity flag.
+ </para>
+ <para>
+ <b>WARNING</b> Note that passing an <see cref="T:System.Exception"/> to this
+ method will print the name of the <see cref="T:System.Exception"/> but no
+ stack trace. To print a stack trace use the
+ <see cref="M:log4net.Core.LogImpl.Error(System.Object,System.Exception)"/> form instead.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LogImpl.Error(System.Object,System.Exception)">
+ <summary>
+ Logs a message object with the <c>ERROR</c> level
+ </summary>
+ <param name="message">The message object to log.</param>
+ <param name="exception">The exception to log, including its stack trace.</param>
+ <remarks>
+ <para>
+ Logs a message object with the <c>ERROR</c> level including
+ the stack trace of the <see cref="T:System.Exception"/> <paramref name="exception"/>
+ passed as a parameter.
+ </para>
+ <para>
+ See the <see cref="M:log4net.Core.LogImpl.Error(System.Object)"/> form for more detailed information.
+ </para>
+ </remarks>
+ <seealso cref="M:log4net.Core.LogImpl.Error(System.Object)"/>
+ </member>
+ <member name="M:log4net.Core.LogImpl.ErrorFormat(System.String,System.Object[])">
+ <summary>
+ Logs a formatted message string with the <c>ERROR</c> level.
+ </summary>
+ <param name="format">A String containing zero or more format items</param>
+ <param name="args">An Object array containing zero or more objects to format</param>
+ <remarks>
+ <para>
+ The message is formatted using the <see cref="M:System.String.Format(System.IFormatProvider,System.String,System.Object[])"/> method. See
+ <c>String.Format</c> for details of the syntax of the format string and the behavior
+ of the formatting.
+ </para>
+ <para>
+ The string is formatted using the <see cref="P:System.Globalization.CultureInfo.InvariantCulture"/>
+ format provider. To specify a localized provider use the
+ <see cref="M:log4net.Core.LogImpl.ErrorFormat(System.IFormatProvider,System.String,System.Object[])"/> method.
+ </para>
+ <para>
+ This method does not take an <see cref="T:System.Exception"/> object to include in the
+ log event. To pass an <see cref="T:System.Exception"/> use one of the <see cref="M:log4net.Core.LogImpl.Error(System.Object)"/>
+ methods instead.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LogImpl.ErrorFormat(System.String,System.Object)">
+ <summary>
+ Logs a formatted message string with the <c>ERROR</c> level.
+ </summary>
+ <param name="format">A String containing zero or more format items</param>
+ <param name="arg0">An Object to format</param>
+ <remarks>
+ <para>
+ The message is formatted using the <see cref="M:System.String.Format(System.IFormatProvider,System.String,System.Object[])"/> method. See
+ <c>String.Format</c> for details of the syntax of the format string and the behavior
+ of the formatting.
+ </para>
+ <para>
+ The string is formatted using the <see cref="P:System.Globalization.CultureInfo.InvariantCulture"/>
+ format provider. To specify a localized provider use the
+ <see cref="M:log4net.Core.LogImpl.ErrorFormat(System.IFormatProvider,System.String,System.Object[])"/> method.
+ </para>
+ <para>
+ This method does not take an <see cref="T:System.Exception"/> object to include in the
+ log event. To pass an <see cref="T:System.Exception"/> use one of the <see cref="M:log4net.Core.LogImpl.Error(System.Object)"/>
+ methods instead.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LogImpl.ErrorFormat(System.String,System.Object,System.Object)">
+ <summary>
+ Logs a formatted message string with the <c>ERROR</c> level.
+ </summary>
+ <param name="format">A String containing zero or more format items</param>
+ <param name="arg0">An Object to format</param>
+ <param name="arg1">An Object to format</param>
+ <remarks>
+ <para>
+ The message is formatted using the <see cref="M:System.String.Format(System.IFormatProvider,System.String,System.Object[])"/> method. See
+ <c>String.Format</c> for details of the syntax of the format string and the behavior
+ of the formatting.
+ </para>
+ <para>
+ The string is formatted using the <see cref="P:System.Globalization.CultureInfo.InvariantCulture"/>
+ format provider. To specify a localized provider use the
+ <see cref="M:log4net.Core.LogImpl.ErrorFormat(System.IFormatProvider,System.String,System.Object[])"/> method.
+ </para>
+ <para>
+ This method does not take an <see cref="T:System.Exception"/> object to include in the
+ log event. To pass an <see cref="T:System.Exception"/> use one of the <see cref="M:log4net.Core.LogImpl.Error(System.Object)"/>
+ methods instead.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LogImpl.ErrorFormat(System.String,System.Object,System.Object,System.Object)">
+ <summary>
+ Logs a formatted message string with the <c>ERROR</c> level.
+ </summary>
+ <param name="format">A String containing zero or more format items</param>
+ <param name="arg0">An Object to format</param>
+ <param name="arg1">An Object to format</param>
+ <param name="arg2">An Object to format</param>
+ <remarks>
+ <para>
+ The message is formatted using the <see cref="M:System.String.Format(System.IFormatProvider,System.String,System.Object[])"/> method. See
+ <c>String.Format</c> for details of the syntax of the format string and the behavior
+ of the formatting.
+ </para>
+ <para>
+ The string is formatted using the <see cref="P:System.Globalization.CultureInfo.InvariantCulture"/>
+ format provider. To specify a localized provider use the
+ <see cref="M:log4net.Core.LogImpl.ErrorFormat(System.IFormatProvider,System.String,System.Object[])"/> method.
+ </para>
+ <para>
+ This method does not take an <see cref="T:System.Exception"/> object to include in the
+ log event. To pass an <see cref="T:System.Exception"/> use one of the <see cref="M:log4net.Core.LogImpl.Error(System.Object)"/>
+ methods instead.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LogImpl.ErrorFormat(System.IFormatProvider,System.String,System.Object[])">
+ <summary>
+ Logs a formatted message string with the <c>ERROR</c> level.
+ </summary>
+ <param name="provider">An <see cref="T:System.IFormatProvider"/> that supplies culture-specific formatting information</param>
+ <param name="format">A String containing zero or more format items</param>
+ <param name="args">An Object array containing zero or more objects to format</param>
+ <remarks>
+ <para>
+ The message is formatted using the <see cref="M:System.String.Format(System.IFormatProvider,System.String,System.Object[])"/> method. See
+ <c>String.Format</c> for details of the syntax of the format string and the behavior
+ of the formatting.
+ </para>
+ <para>
+ This method does not take an <see cref="T:System.Exception"/> object to include in the
+ log event. To pass an <see cref="T:System.Exception"/> use one of the <see cref="M:log4net.Core.LogImpl.Error(System.Object)"/>
+ methods instead.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LogImpl.Fatal(System.Object)">
+ <summary>
+ Logs a message object with the <c>FATAL</c> level.
+ </summary>
+ <param name="message">The message object to log.</param>
+ <remarks>
+ <para>
+ This method first checks if this logger is <c>FATAL</c>
+ enabled by comparing the level of this logger with the
+ <c>FATAL</c> level. If this logger is
+ <c>FATAL</c> enabled, then it converts the message object
+ (passed as parameter) to a string by invoking the appropriate
+ <see cref="T:log4net.ObjectRenderer.IObjectRenderer"/>. It then
+ proceeds to call all the registered appenders in this logger and
+ also higher in the hierarchy depending on the value of the
+ additivity flag.
+ </para>
+ <para>
+ <b>WARNING</b> Note that passing an <see cref="T:System.Exception"/> to this
+ method will print the name of the <see cref="T:System.Exception"/> but no
+ stack trace. To print a stack trace use the
+ <see cref="M:log4net.Core.LogImpl.Fatal(System.Object,System.Exception)"/> form instead.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LogImpl.Fatal(System.Object,System.Exception)">
+ <summary>
+ Logs a message object with the <c>FATAL</c> level
+ </summary>
+ <param name="message">The message object to log.</param>
+ <param name="exception">The exception to log, including its stack trace.</param>
+ <remarks>
+ <para>
+ Logs a message object with the <c>FATAL</c> level including
+ the stack trace of the <see cref="T:System.Exception"/> <paramref name="exception"/>
+ passed as a parameter.
+ </para>
+ <para>
+ See the <see cref="M:log4net.Core.LogImpl.Fatal(System.Object)"/> form for more detailed information.
+ </para>
+ </remarks>
+ <seealso cref="M:log4net.Core.LogImpl.Fatal(System.Object)"/>
+ </member>
+ <member name="M:log4net.Core.LogImpl.FatalFormat(System.String,System.Object[])">
+ <summary>
+ Logs a formatted message string with the <c>FATAL</c> level.
+ </summary>
+ <param name="format">A String containing zero or more format items</param>
+ <param name="args">An Object array containing zero or more objects to format</param>
+ <remarks>
+ <para>
+ The message is formatted using the <see cref="M:System.String.Format(System.IFormatProvider,System.String,System.Object[])"/> method. See
+ <c>String.Format</c> for details of the syntax of the format string and the behavior
+ of the formatting.
+ </para>
+ <para>
+ The string is formatted using the <see cref="P:System.Globalization.CultureInfo.InvariantCulture"/>
+ format provider. To specify a localized provider use the
+ <see cref="M:log4net.Core.LogImpl.FatalFormat(System.IFormatProvider,System.String,System.Object[])"/> method.
+ </para>
+ <para>
+ This method does not take an <see cref="T:System.Exception"/> object to include in the
+ log event. To pass an <see cref="T:System.Exception"/> use one of the <see cref="M:log4net.Core.LogImpl.Fatal(System.Object)"/>
+ methods instead.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LogImpl.FatalFormat(System.String,System.Object)">
+ <summary>
+ Logs a formatted message string with the <c>FATAL</c> level.
+ </summary>
+ <param name="format">A String containing zero or more format items</param>
+ <param name="arg0">An Object to format</param>
+ <remarks>
+ <para>
+ The message is formatted using the <see cref="M:System.String.Format(System.IFormatProvider,System.String,System.Object[])"/> method. See
+ <c>String.Format</c> for details of the syntax of the format string and the behavior
+ of the formatting.
+ </para>
+ <para>
+ The string is formatted using the <see cref="P:System.Globalization.CultureInfo.InvariantCulture"/>
+ format provider. To specify a localized provider use the
+ <see cref="M:log4net.Core.LogImpl.FatalFormat(System.IFormatProvider,System.String,System.Object[])"/> method.
+ </para>
+ <para>
+ This method does not take an <see cref="T:System.Exception"/> object to include in the
+ log event. To pass an <see cref="T:System.Exception"/> use one of the <see cref="M:log4net.Core.LogImpl.Fatal(System.Object)"/>
+ methods instead.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LogImpl.FatalFormat(System.String,System.Object,System.Object)">
+ <summary>
+ Logs a formatted message string with the <c>FATAL</c> level.
+ </summary>
+ <param name="format">A String containing zero or more format items</param>
+ <param name="arg0">An Object to format</param>
+ <param name="arg1">An Object to format</param>
+ <remarks>
+ <para>
+ The message is formatted using the <see cref="M:System.String.Format(System.IFormatProvider,System.String,System.Object[])"/> method. See
+ <c>String.Format</c> for details of the syntax of the format string and the behavior
+ of the formatting.
+ </para>
+ <para>
+ The string is formatted using the <see cref="P:System.Globalization.CultureInfo.InvariantCulture"/>
+ format provider. To specify a localized provider use the
+ <see cref="M:log4net.Core.LogImpl.FatalFormat(System.IFormatProvider,System.String,System.Object[])"/> method.
+ </para>
+ <para>
+ This method does not take an <see cref="T:System.Exception"/> object to include in the
+ log event. To pass an <see cref="T:System.Exception"/> use one of the <see cref="M:log4net.Core.LogImpl.Fatal(System.Object)"/>
+ methods instead.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LogImpl.FatalFormat(System.String,System.Object,System.Object,System.Object)">
+ <summary>
+ Logs a formatted message string with the <c>FATAL</c> level.
+ </summary>
+ <param name="format">A String containing zero or more format items</param>
+ <param name="arg0">An Object to format</param>
+ <param name="arg1">An Object to format</param>
+ <param name="arg2">An Object to format</param>
+ <remarks>
+ <para>
+ The message is formatted using the <see cref="M:System.String.Format(System.IFormatProvider,System.String,System.Object[])"/> method. See
+ <c>String.Format</c> for details of the syntax of the format string and the behavior
+ of the formatting.
+ </para>
+ <para>
+ The string is formatted using the <see cref="P:System.Globalization.CultureInfo.InvariantCulture"/>
+ format provider. To specify a localized provider use the
+ <see cref="M:log4net.Core.LogImpl.FatalFormat(System.IFormatProvider,System.String,System.Object[])"/> method.
+ </para>
+ <para>
+ This method does not take an <see cref="T:System.Exception"/> object to include in the
+ log event. To pass an <see cref="T:System.Exception"/> use one of the <see cref="M:log4net.Core.LogImpl.Fatal(System.Object)"/>
+ methods instead.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LogImpl.FatalFormat(System.IFormatProvider,System.String,System.Object[])">
+ <summary>
+ Logs a formatted message string with the <c>FATAL</c> level.
+ </summary>
+ <param name="provider">An <see cref="T:System.IFormatProvider"/> that supplies culture-specific formatting information</param>
+ <param name="format">A String containing zero or more format items</param>
+ <param name="args">An Object array containing zero or more objects to format</param>
+ <remarks>
+ <para>
+ The message is formatted using the <see cref="M:System.String.Format(System.IFormatProvider,System.String,System.Object[])"/> method. See
+ <c>String.Format</c> for details of the syntax of the format string and the behavior
+ of the formatting.
+ </para>
+ <para>
+ This method does not take an <see cref="T:System.Exception"/> object to include in the
+ log event. To pass an <see cref="T:System.Exception"/> use one of the <see cref="M:log4net.Core.LogImpl.Fatal(System.Object)"/>
+ methods instead.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.LogImpl.LoggerRepositoryConfigurationChanged(System.Object,System.EventArgs)">
+ <summary>
+ Event handler for the <see cref="E:log4net.Repository.ILoggerRepository.ConfigurationChanged"/> event
+ </summary>
+ <param name="sender">the repository</param>
+ <param name="e">Empty</param>
+ </member>
+ <member name="F:log4net.Core.LogImpl.ThisDeclaringType">
+ <summary>
+ The fully qualified name of this declaring type not the type of any subclass.
+ </summary>
+ </member>
+ <member name="P:log4net.Core.LogImpl.IsDebugEnabled">
+ <summary>
+ Checks if this logger is enabled for the <c>DEBUG</c>
+ level.
+ </summary>
+ <value>
+ <c>true</c> if this logger is enabled for <c>DEBUG</c> events,
+ <c>false</c> otherwise.
+ </value>
+ <remarks>
+ <para>
+ This function is intended to lessen the computational cost of
+ disabled log debug statements.
+ </para>
+ <para>
+ For some <c>log</c> Logger object, when you write:
+ </para>
+ <code lang="C#">
+ log.Debug("This is entry number: " + i );
+ </code>
+ <para>
+ You incur the cost constructing the message, concatenation in
+ this case, regardless of whether the message is logged or not.
+ </para>
+ <para>
+ If you are worried about speed, then you should write:
+ </para>
+ <code lang="C#">
+ if (log.IsDebugEnabled())
+ {
+ log.Debug("This is entry number: " + i );
+ }
+ </code>
+ <para>
+ This way you will not incur the cost of parameter
+ construction if debugging is disabled for <c>log</c>. On
+ the other hand, if the <c>log</c> is debug enabled, you
+ will incur the cost of evaluating whether the logger is debug
+ enabled twice. Once in <c>IsDebugEnabled</c> and once in
+ the <c>Debug</c>. This is an insignificant overhead
+ since evaluating a logger takes about 1% of the time it
+ takes to actually log.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Core.LogImpl.IsInfoEnabled">
+ <summary>
+ Checks if this logger is enabled for the <c>INFO</c> level.
+ </summary>
+ <value>
+ <c>true</c> if this logger is enabled for <c>INFO</c> events,
+ <c>false</c> otherwise.
+ </value>
+ <remarks>
+ <para>
+ See <see cref="P:log4net.Core.LogImpl.IsDebugEnabled"/> for more information and examples
+ of using this method.
+ </para>
+ </remarks>
+ <seealso cref="P:log4net.Core.LogImpl.IsDebugEnabled"/>
+ </member>
+ <member name="P:log4net.Core.LogImpl.IsWarnEnabled">
+ <summary>
+ Checks if this logger is enabled for the <c>WARN</c> level.
+ </summary>
+ <value>
+ <c>true</c> if this logger is enabled for <c>WARN</c> events,
+ <c>false</c> otherwise.
+ </value>
+ <remarks>
+ <para>
+ See <see cref="P:log4net.Core.LogImpl.IsDebugEnabled"/> for more information and examples
+ of using this method.
+ </para>
+ </remarks>
+ <seealso cref="P:log4net.ILog.IsDebugEnabled"/>
+ </member>
+ <member name="P:log4net.Core.LogImpl.IsErrorEnabled">
+ <summary>
+ Checks if this logger is enabled for the <c>ERROR</c> level.
+ </summary>
+ <value>
+ <c>true</c> if this logger is enabled for <c>ERROR</c> events,
+ <c>false</c> otherwise.
+ </value>
+ <remarks>
+ <para>
+ See <see cref="P:log4net.Core.LogImpl.IsDebugEnabled"/> for more information and examples of using this method.
+ </para>
+ </remarks>
+ <seealso cref="P:log4net.ILog.IsDebugEnabled"/>
+ </member>
+ <member name="P:log4net.Core.LogImpl.IsFatalEnabled">
+ <summary>
+ Checks if this logger is enabled for the <c>FATAL</c> level.
+ </summary>
+ <value>
+ <c>true</c> if this logger is enabled for <c>FATAL</c> events,
+ <c>false</c> otherwise.
+ </value>
+ <remarks>
+ <para>
+ See <see cref="P:log4net.Core.LogImpl.IsDebugEnabled"/> for more information and examples of using this method.
+ </para>
+ </remarks>
+ <seealso cref="P:log4net.ILog.IsDebugEnabled"/>
+ </member>
+ <member name="T:log4net.Core.SecurityContext">
+ <summary>
+ A SecurityContext used by log4net when interacting with protected resources
+ </summary>
+ <remarks>
+ <para>
+ A SecurityContext used by log4net when interacting with protected resources
+ for example with operating system services. This can be used to impersonate
+ a principal that has been granted privileges on the system resources.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="M:log4net.Core.SecurityContext.Impersonate(System.Object)">
+ <summary>
+ Impersonate this SecurityContext
+ </summary>
+ <param name="state">State supplied by the caller</param>
+ <returns>An <see cref="T:System.IDisposable"/> instance that will
+ revoke the impersonation of this SecurityContext, or <c>null</c></returns>
+ <remarks>
+ <para>
+ Impersonate this security context. Further calls on the current
+ thread should now be made in the security context provided
+ by this object. When the <see cref="T:System.IDisposable"/> result
+ <see cref="M:System.IDisposable.Dispose"/> method is called the security
+ context of the thread should be reverted to the state it was in
+ before <see cref="M:log4net.Core.SecurityContext.Impersonate(System.Object)"/> was called.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Core.SecurityContextProvider">
+ <summary>
+ The <see cref="T:log4net.Core.SecurityContextProvider"/> providers default <see cref="T:log4net.Core.SecurityContext"/> instances.
+ </summary>
+ <remarks>
+ <para>
+ A configured component that interacts with potentially protected system
+ resources uses a <see cref="T:log4net.Core.SecurityContext"/> to provide the elevated
+ privileges required. If the <see cref="T:log4net.Core.SecurityContext"/> object has
+ been not been explicitly provided to the component then the component
+ will request one from this <see cref="T:log4net.Core.SecurityContextProvider"/>.
+ </para>
+ <para>
+ By default the <see cref="P:log4net.Core.SecurityContextProvider.DefaultProvider"/> is
+ an instance of <see cref="T:log4net.Core.SecurityContextProvider"/> which returns only
+ <see cref="T:log4net.Util.NullSecurityContext"/> objects. This is a reasonable default
+ where the privileges required are not know by the system.
+ </para>
+ <para>
+ This default behavior can be overridden by subclassing the <see cref="T:log4net.Core.SecurityContextProvider"/>
+ and overriding the <see cref="M:log4net.Core.SecurityContextProvider.CreateSecurityContext(System.Object)"/> method to return
+ the desired <see cref="T:log4net.Core.SecurityContext"/> objects. The default provider
+ can be replaced by programmatically setting the value of the
+ <see cref="P:log4net.Core.SecurityContextProvider.DefaultProvider"/> property.
+ </para>
+ <para>
+ An alternative is to use the <c>log4net.Config.SecurityContextProviderAttribute</c>
+ This attribute can be applied to an assembly in the same way as the
+ <c>log4net.Config.XmlConfiguratorAttribute"</c>. The attribute takes
+ the type to use as the <see cref="T:log4net.Core.SecurityContextProvider"/> as an argument.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="F:log4net.Core.SecurityContextProvider.s_defaultProvider">
+ <summary>
+ The default provider
+ </summary>
+ </member>
+ <member name="M:log4net.Core.SecurityContextProvider.#ctor">
+ <summary>
+ Protected default constructor to allow subclassing
+ </summary>
+ <remarks>
+ <para>
+ Protected default constructor to allow subclassing
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.SecurityContextProvider.CreateSecurityContext(System.Object)">
+ <summary>
+ Create a SecurityContext for a consumer
+ </summary>
+ <param name="consumer">The consumer requesting the SecurityContext</param>
+ <returns>An impersonation context</returns>
+ <remarks>
+ <para>
+ The default implementation is to return a <see cref="T:log4net.Util.NullSecurityContext"/>.
+ </para>
+ <para>
+ Subclasses should override this method to provide their own
+ behavior.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Core.SecurityContextProvider.DefaultProvider">
+ <summary>
+ Gets or sets the default SecurityContextProvider
+ </summary>
+ <value>
+ The default SecurityContextProvider
+ </value>
+ <remarks>
+ <para>
+ The default provider is used by configured components that
+ require a <see cref="T:log4net.Core.SecurityContext"/> and have not had one
+ given to them.
+ </para>
+ <para>
+ By default this is an instance of <see cref="T:log4net.Core.SecurityContextProvider"/>
+ that returns <see cref="T:log4net.Util.NullSecurityContext"/> objects.
+ </para>
+ <para>
+ The default provider can be set programmatically by setting
+ the value of this property to a sub class of <see cref="T:log4net.Core.SecurityContextProvider"/>
+ that has the desired behavior.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Core.WrapperCreationHandler">
+ <summary>
+ Delegate used to handle creation of new wrappers.
+ </summary>
+ <param name="logger">The logger to wrap in a wrapper.</param>
+ <remarks>
+ <para>
+ Delegate used to handle creation of new wrappers. This delegate
+ is called from the <see cref="M:log4net.Core.WrapperMap.CreateNewWrapperObject(log4net.Core.ILogger)"/>
+ method to construct the wrapper for the specified logger.
+ </para>
+ <para>
+ The delegate to use is supplied to the <see cref="T:log4net.Core.WrapperMap"/>
+ constructor.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Core.WrapperMap">
+ <summary>
+ Maps between logger objects and wrapper objects.
+ </summary>
+ <remarks>
+ <para>
+ This class maintains a mapping between <see cref="T:log4net.Core.ILogger"/> objects and
+ <see cref="T:log4net.Core.ILoggerWrapper"/> objects. Use the <see cref="M:log4net.Core.WrapperMap.GetWrapper(log4net.Core.ILogger)"/> method to
+ lookup the <see cref="T:log4net.Core.ILoggerWrapper"/> for the specified <see cref="T:log4net.Core.ILogger"/>.
+ </para>
+ <para>
+ New wrapper instances are created by the <see cref="M:log4net.Core.WrapperMap.CreateNewWrapperObject(log4net.Core.ILogger)"/>
+ method. The default behavior is for this method to delegate construction
+ of the wrapper to the <see cref="T:log4net.Core.WrapperCreationHandler"/> delegate supplied
+ to the constructor. This allows specialization of the behavior without
+ requiring subclassing of this type.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="M:log4net.Core.WrapperMap.#ctor(log4net.Core.WrapperCreationHandler)">
+ <summary>
+ Initializes a new instance of the <see cref="T:log4net.Core.WrapperMap"/>
+ </summary>
+ <param name="createWrapperHandler">The handler to use to create the wrapper objects.</param>
+ <remarks>
+ <para>
+ Initializes a new instance of the <see cref="T:log4net.Core.WrapperMap"/> class with
+ the specified handler to create the wrapper objects.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.WrapperMap.GetWrapper(log4net.Core.ILogger)">
+ <summary>
+ Gets the wrapper object for the specified logger.
+ </summary>
+ <returns>The wrapper object for the specified logger</returns>
+ <remarks>
+ <para>
+ If the logger is null then the corresponding wrapper is null.
+ </para>
+ <para>
+ Looks up the wrapper it it has previously been requested and
+ returns it. If the wrapper has never been requested before then
+ the <see cref="M:log4net.Core.WrapperMap.CreateNewWrapperObject(log4net.Core.ILogger)"/> virtual method is
+ called.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.WrapperMap.CreateNewWrapperObject(log4net.Core.ILogger)">
+ <summary>
+ Creates the wrapper object for the specified logger.
+ </summary>
+ <param name="logger">The logger to wrap in a wrapper.</param>
+ <returns>The wrapper object for the logger.</returns>
+ <remarks>
+ <para>
+ This implementation uses the <see cref="T:log4net.Core.WrapperCreationHandler"/>
+ passed to the constructor to create the wrapper. This method
+ can be overridden in a subclass.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.WrapperMap.RepositoryShutdown(log4net.Repository.ILoggerRepository)">
+ <summary>
+ Called when a monitored repository shutdown event is received.
+ </summary>
+ <param name="repository">The <see cref="T:log4net.Repository.ILoggerRepository"/> that is shutting down</param>
+ <remarks>
+ <para>
+ This method is called when a <see cref="T:log4net.Repository.ILoggerRepository"/> that this
+ <see cref="T:log4net.Core.WrapperMap"/> is holding loggers for has signaled its shutdown
+ event <see cref="E:log4net.Repository.ILoggerRepository.ShutdownEvent"/>. The default
+ behavior of this method is to release the references to the loggers
+ and their wrappers generated for this repository.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Core.WrapperMap.ILoggerRepository_Shutdown(System.Object,System.EventArgs)">
+ <summary>
+ Event handler for repository shutdown event.
+ </summary>
+ <param name="sender">The sender of the event.</param>
+ <param name="e">The event args.</param>
+ </member>
+ <member name="F:log4net.Core.WrapperMap.m_repositories">
+ <summary>
+ Map of logger repositories to hashtables of ILogger to ILoggerWrapper mappings
+ </summary>
+ </member>
+ <member name="F:log4net.Core.WrapperMap.m_createWrapperHandler">
+ <summary>
+ The handler to use to create the extension wrapper objects.
+ </summary>
+ </member>
+ <member name="F:log4net.Core.WrapperMap.m_shutdownHandler">
+ <summary>
+ Internal reference to the delegate used to register for repository shutdown events.
+ </summary>
+ </member>
+ <member name="P:log4net.Core.WrapperMap.Repositories">
+ <summary>
+ Gets the map of logger repositories.
+ </summary>
+ <value>
+ Map of logger repositories.
+ </value>
+ <remarks>
+ <para>
+ Gets the hashtable that is keyed on <see cref="T:log4net.Repository.ILoggerRepository"/>. The
+ values are hashtables keyed on <see cref="T:log4net.Core.ILogger"/> with the
+ value being the corresponding <see cref="T:log4net.Core.ILoggerWrapper"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.DateFormatter.AbsoluteTimeDateFormatter">
+ <summary>
+ Formats a <see cref="T:System.DateTime"/> as <c>"HH:mm:ss,fff"</c>.
+ </summary>
+ <remarks>
+ <para>
+ Formats a <see cref="T:System.DateTime"/> in the format <c>"HH:mm:ss,fff"</c> for example, <c>"15:49:37,459"</c>.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="T:log4net.DateFormatter.IDateFormatter">
+ <summary>
+ Render a <see cref="T:System.DateTime"/> as a string.
+ </summary>
+ <remarks>
+ <para>
+ Interface to abstract the rendering of a <see cref="T:System.DateTime"/>
+ instance into a string.
+ </para>
+ <para>
+ The <see cref="M:log4net.DateFormatter.IDateFormatter.FormatDate(System.DateTime,System.IO.TextWriter)"/> method is used to render the
+ date to a text writer.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="M:log4net.DateFormatter.IDateFormatter.FormatDate(System.DateTime,System.IO.TextWriter)">
+ <summary>
+ Formats the specified date as a string.
+ </summary>
+ <param name="dateToFormat">The date to format.</param>
+ <param name="writer">The writer to write to.</param>
+ <remarks>
+ <para>
+ Format the <see cref="T:System.DateTime"/> as a string and write it
+ to the <see cref="T:System.IO.TextWriter"/> provided.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.DateFormatter.AbsoluteTimeDateFormatter.AbsoluteTimeDateFormat">
+ <summary>
+ String constant used to specify AbsoluteTimeDateFormat in layouts. Current value is <b>ABSOLUTE</b>.
+ </summary>
+ </member>
+ <member name="F:log4net.DateFormatter.AbsoluteTimeDateFormatter.DateAndTimeDateFormat">
+ <summary>
+ String constant used to specify DateTimeDateFormat in layouts. Current value is <b>DATE</b>.
+ </summary>
+ </member>
+ <member name="F:log4net.DateFormatter.AbsoluteTimeDateFormatter.Iso8601TimeDateFormat">
+ <summary>
+ String constant used to specify ISO8601DateFormat in layouts. Current value is <b>ISO8601</b>.
+ </summary>
+ </member>
+ <member name="M:log4net.DateFormatter.AbsoluteTimeDateFormatter.FormatDateWithoutMillis(System.DateTime,System.Text.StringBuilder)">
+ <summary>
+ Renders the date into a string. Format is <c>"HH:mm:ss"</c>.
+ </summary>
+ <param name="dateToFormat">The date to render into a string.</param>
+ <param name="buffer">The string builder to write to.</param>
+ <remarks>
+ <para>
+ Subclasses should override this method to render the date
+ into a string using a precision up to the second. This method
+ will be called at most once per second and the result will be
+ reused if it is needed again during the same second.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.DateFormatter.AbsoluteTimeDateFormatter.FormatDate(System.DateTime,System.IO.TextWriter)">
+ <summary>
+ Renders the date into a string. Format is "HH:mm:ss,fff".
+ </summary>
+ <param name="dateToFormat">The date to render into a string.</param>
+ <param name="writer">The writer to write to.</param>
+ <remarks>
+ <para>
+ Uses the <see cref="M:log4net.DateFormatter.AbsoluteTimeDateFormatter.FormatDateWithoutMillis(System.DateTime,System.Text.StringBuilder)"/> method to generate the
+ time string up to the seconds and then appends the current
+ milliseconds. The results from <see cref="M:log4net.DateFormatter.AbsoluteTimeDateFormatter.FormatDateWithoutMillis(System.DateTime,System.Text.StringBuilder)"/> are
+ cached and <see cref="M:log4net.DateFormatter.AbsoluteTimeDateFormatter.FormatDateWithoutMillis(System.DateTime,System.Text.StringBuilder)"/> is called at most once
+ per second.
+ </para>
+ <para>
+ Sub classes should override <see cref="M:log4net.DateFormatter.AbsoluteTimeDateFormatter.FormatDateWithoutMillis(System.DateTime,System.Text.StringBuilder)"/>
+ rather than <see cref="M:log4net.DateFormatter.AbsoluteTimeDateFormatter.FormatDate(System.DateTime,System.IO.TextWriter)"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.DateFormatter.AbsoluteTimeDateFormatter.s_lastTimeToTheSecond">
+ <summary>
+ Last stored time with precision up to the second.
+ </summary>
+ </member>
+ <member name="F:log4net.DateFormatter.AbsoluteTimeDateFormatter.s_lastTimeBuf">
+ <summary>
+ Last stored time with precision up to the second, formatted
+ as a string.
+ </summary>
+ </member>
+ <member name="F:log4net.DateFormatter.AbsoluteTimeDateFormatter.s_lastTimeString">
+ <summary>
+ Last stored time with precision up to the second, formatted
+ as a string.
+ </summary>
+ </member>
+ <member name="T:log4net.DateFormatter.DateTimeDateFormatter">
+ <summary>
+ Formats a <see cref="T:System.DateTime"/> as <c>"dd MMM yyyy HH:mm:ss,fff"</c>
+ </summary>
+ <remarks>
+ <para>
+ Formats a <see cref="T:System.DateTime"/> in the format
+ <c>"dd MMM yyyy HH:mm:ss,fff"</c> for example,
+ <c>"06 Nov 1994 15:49:37,459"</c>.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ <author>Angelika Schnagl</author>
+ </member>
+ <member name="M:log4net.DateFormatter.DateTimeDateFormatter.#ctor">
+ <summary>
+ Default constructor.
+ </summary>
+ <remarks>
+ <para>
+ Initializes a new instance of the <see cref="T:log4net.DateFormatter.DateTimeDateFormatter"/> class.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.DateFormatter.DateTimeDateFormatter.FormatDateWithoutMillis(System.DateTime,System.Text.StringBuilder)">
+ <summary>
+ Formats the date without the milliseconds part
+ </summary>
+ <param name="dateToFormat">The date to format.</param>
+ <param name="buffer">The string builder to write to.</param>
+ <remarks>
+ <para>
+ Formats a DateTime in the format <c>"dd MMM yyyy HH:mm:ss"</c>
+ for example, <c>"06 Nov 1994 15:49:37"</c>.
+ </para>
+ <para>
+ The base class will append the <c>",fff"</c> milliseconds section.
+ This method will only be called at most once per second.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.DateFormatter.DateTimeDateFormatter.m_dateTimeFormatInfo">
+ <summary>
+ The format info for the invariant culture.
+ </summary>
+ </member>
+ <member name="T:log4net.DateFormatter.Iso8601DateFormatter">
+ <summary>
+ Formats the <see cref="T:System.DateTime"/> as <c>"yyyy-MM-dd HH:mm:ss,fff"</c>.
+ </summary>
+ <remarks>
+ <para>
+ Formats the <see cref="T:System.DateTime"/> specified as a string: <c>"yyyy-MM-dd HH:mm:ss,fff"</c>.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="M:log4net.DateFormatter.Iso8601DateFormatter.#ctor">
+ <summary>
+ Default constructor
+ </summary>
+ <remarks>
+ <para>
+ Initializes a new instance of the <see cref="T:log4net.DateFormatter.Iso8601DateFormatter"/> class.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.DateFormatter.Iso8601DateFormatter.FormatDateWithoutMillis(System.DateTime,System.Text.StringBuilder)">
+ <summary>
+ Formats the date without the milliseconds part
+ </summary>
+ <param name="dateToFormat">The date to format.</param>
+ <param name="buffer">The string builder to write to.</param>
+ <remarks>
+ <para>
+ Formats the date specified as a string: <c>"yyyy-MM-dd HH:mm:ss"</c>.
+ </para>
+ <para>
+ The base class will append the <c>",fff"</c> milliseconds section.
+ This method will only be called at most once per second.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.DateFormatter.SimpleDateFormatter">
+ <summary>
+ Formats the <see cref="T:System.DateTime"/> using the <see cref="M:System.DateTime.ToString(System.String,System.IFormatProvider)"/> method.
+ </summary>
+ <remarks>
+ <para>
+ Formats the <see cref="T:System.DateTime"/> using the <see cref="T:System.DateTime"/> <see cref="M:System.DateTime.ToString(System.String,System.IFormatProvider)"/> method.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="M:log4net.DateFormatter.SimpleDateFormatter.#ctor(System.String)">
+ <summary>
+ Constructor
+ </summary>
+ <param name="format">The format string.</param>
+ <remarks>
+ <para>
+ Initializes a new instance of the <see cref="T:log4net.DateFormatter.SimpleDateFormatter"/> class
+ with the specified format string.
+ </para>
+ <para>
+ The format string must be compatible with the options
+ that can be supplied to <see cref="M:System.DateTime.ToString(System.String,System.IFormatProvider)"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.DateFormatter.SimpleDateFormatter.FormatDate(System.DateTime,System.IO.TextWriter)">
+ <summary>
+ Formats the date using <see cref="M:System.DateTime.ToString(System.String,System.IFormatProvider)"/>.
+ </summary>
+ <param name="dateToFormat">The date to convert to a string.</param>
+ <param name="writer">The writer to write to.</param>
+ <remarks>
+ <para>
+ Uses the date format string supplied to the constructor to call
+ the <see cref="M:System.DateTime.ToString(System.String,System.IFormatProvider)"/> method to format the date.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.DateFormatter.SimpleDateFormatter.m_formatString">
+ <summary>
+ The format string used to format the <see cref="T:System.DateTime"/>.
+ </summary>
+ <remarks>
+ <para>
+ The format string must be compatible with the options
+ that can be supplied to <see cref="M:System.DateTime.ToString(System.String,System.IFormatProvider)"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Filter.DenyAllFilter">
+ <summary>
+ This filter drops all <see cref="T:log4net.Core.LoggingEvent"/>.
+ </summary>
+ <remarks>
+ <para>
+ You can add this filter to the end of a filter chain to
+ switch from the default "accept all unless instructed otherwise"
+ filtering behavior to a "deny all unless instructed otherwise"
+ behavior.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="T:log4net.Filter.FilterSkeleton">
+ <summary>
+ Subclass this type to implement customized logging event filtering
+ </summary>
+ <remarks>
+ <para>
+ Users should extend this class to implement customized logging
+ event filtering. Note that <see cref="T:log4net.Repository.Hierarchy.Logger"/> and
+ <see cref="T:log4net.Appender.AppenderSkeleton"/>, the parent class of all standard
+ appenders, have built-in filtering rules. It is suggested that you
+ first use and understand the built-in rules before rushing to write
+ your own custom filters.
+ </para>
+ <para>
+ This abstract class assumes and also imposes that filters be
+ organized in a linear chain. The <see cref="M:log4net.Filter.FilterSkeleton.Decide(log4net.Core.LoggingEvent)"/>
+ method of each filter is called sequentially, in the order of their
+ addition to the chain.
+ </para>
+ <para>
+ The <see cref="M:log4net.Filter.FilterSkeleton.Decide(log4net.Core.LoggingEvent)"/> method must return one
+ of the integer constants <see cref="F:log4net.Filter.FilterDecision.Deny"/>,
+ <see cref="F:log4net.Filter.FilterDecision.Neutral"/> or <see cref="F:log4net.Filter.FilterDecision.Accept"/>.
+ </para>
+ <para>
+ If the value <see cref="F:log4net.Filter.FilterDecision.Deny"/> is returned, then the log event is dropped
+ immediately without consulting with the remaining filters.
+ </para>
+ <para>
+ If the value <see cref="F:log4net.Filter.FilterDecision.Neutral"/> is returned, then the next filter
+ in the chain is consulted. If there are no more filters in the
+ chain, then the log event is logged. Thus, in the presence of no
+ filters, the default behavior is to log all logging events.
+ </para>
+ <para>
+ If the value <see cref="F:log4net.Filter.FilterDecision.Accept"/> is returned, then the log
+ event is logged without consulting the remaining filters.
+ </para>
+ <para>
+ The philosophy of log4net filters is largely inspired from the
+ Linux ipchains.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="T:log4net.Filter.IFilter">
+ <summary>
+ Implement this interface to provide customized logging event filtering
+ </summary>
+ <remarks>
+ <para>
+ Users should implement this interface to implement customized logging
+ event filtering. Note that <see cref="T:log4net.Repository.Hierarchy.Logger"/> and
+ <see cref="T:log4net.Appender.AppenderSkeleton"/>, the parent class of all standard
+ appenders, have built-in filtering rules. It is suggested that you
+ first use and understand the built-in rules before rushing to write
+ your own custom filters.
+ </para>
+ <para>
+ This abstract class assumes and also imposes that filters be
+ organized in a linear chain. The <see cref="M:log4net.Filter.IFilter.Decide(log4net.Core.LoggingEvent)"/>
+ method of each filter is called sequentially, in the order of their
+ addition to the chain.
+ </para>
+ <para>
+ The <see cref="M:log4net.Filter.IFilter.Decide(log4net.Core.LoggingEvent)"/> method must return one
+ of the integer constants <see cref="F:log4net.Filter.FilterDecision.Deny"/>,
+ <see cref="F:log4net.Filter.FilterDecision.Neutral"/> or <see cref="F:log4net.Filter.FilterDecision.Accept"/>.
+ </para>
+ <para>
+ If the value <see cref="F:log4net.Filter.FilterDecision.Deny"/> is returned, then the log event is dropped
+ immediately without consulting with the remaining filters.
+ </para>
+ <para>
+ If the value <see cref="F:log4net.Filter.FilterDecision.Neutral"/> is returned, then the next filter
+ in the chain is consulted. If there are no more filters in the
+ chain, then the log event is logged. Thus, in the presence of no
+ filters, the default behavior is to log all logging events.
+ </para>
+ <para>
+ If the value <see cref="F:log4net.Filter.FilterDecision.Accept"/> is returned, then the log
+ event is logged without consulting the remaining filters.
+ </para>
+ <para>
+ The philosophy of log4net filters is largely inspired from the
+ Linux ipchains.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="M:log4net.Filter.IFilter.Decide(log4net.Core.LoggingEvent)">
+ <summary>
+ Decide if the logging event should be logged through an appender.
+ </summary>
+ <param name="loggingEvent">The LoggingEvent to decide upon</param>
+ <returns>The decision of the filter</returns>
+ <remarks>
+ <para>
+ If the decision is <see cref="F:log4net.Filter.FilterDecision.Deny"/>, then the event will be
+ dropped. If the decision is <see cref="F:log4net.Filter.FilterDecision.Neutral"/>, then the next
+ filter, if any, will be invoked. If the decision is <see cref="F:log4net.Filter.FilterDecision.Accept"/> then
+ the event will be logged without consulting with other filters in
+ the chain.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Filter.IFilter.Next">
+ <summary>
+ Property to get and set the next filter
+ </summary>
+ <value>
+ The next filter in the chain
+ </value>
+ <remarks>
+ <para>
+ Filters are typically composed into chains. This property allows the next filter in
+ the chain to be accessed.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Filter.FilterSkeleton.m_next">
+ <summary>
+ Points to the next filter in the filter chain.
+ </summary>
+ <remarks>
+ <para>
+ See <see cref="P:log4net.Filter.FilterSkeleton.Next"/> for more information.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Filter.FilterSkeleton.ActivateOptions">
+ <summary>
+ Initialize the filter with the options set
+ </summary>
+ <remarks>
+ <para>
+ This is part of the <see cref="T:log4net.Core.IOptionHandler"/> delayed object
+ activation scheme. The <see cref="M:log4net.Filter.FilterSkeleton.ActivateOptions"/> method must
+ be called on this object after the configuration properties have
+ been set. Until <see cref="M:log4net.Filter.FilterSkeleton.ActivateOptions"/> is called this
+ object is in an undefined state and must not be used.
+ </para>
+ <para>
+ If any of the configuration properties are modified then
+ <see cref="M:log4net.Filter.FilterSkeleton.ActivateOptions"/> must be called again.
+ </para>
+ <para>
+ Typically filter's options become active immediately on set,
+ however this method must still be called.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Filter.FilterSkeleton.Decide(log4net.Core.LoggingEvent)">
+ <summary>
+ Decide if the <see cref="T:log4net.Core.LoggingEvent"/> should be logged through an appender.
+ </summary>
+ <param name="loggingEvent">The <see cref="T:log4net.Core.LoggingEvent"/> to decide upon</param>
+ <returns>The decision of the filter</returns>
+ <remarks>
+ <para>
+ If the decision is <see cref="F:log4net.Filter.FilterDecision.Deny"/>, then the event will be
+ dropped. If the decision is <see cref="F:log4net.Filter.FilterDecision.Neutral"/>, then the next
+ filter, if any, will be invoked. If the decision is <see cref="F:log4net.Filter.FilterDecision.Accept"/> then
+ the event will be logged without consulting with other filters in
+ the chain.
+ </para>
+ <para>
+ This method is marked <c>abstract</c> and must be implemented
+ in a subclass.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Filter.FilterSkeleton.Next">
+ <summary>
+ Property to get and set the next filter
+ </summary>
+ <value>
+ The next filter in the chain
+ </value>
+ <remarks>
+ <para>
+ Filters are typically composed into chains. This property allows the next filter in
+ the chain to be accessed.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Filter.DenyAllFilter.#ctor">
+ <summary>
+ Default constructor
+ </summary>
+ </member>
+ <member name="M:log4net.Filter.DenyAllFilter.Decide(log4net.Core.LoggingEvent)">
+ <summary>
+ Always returns the integer constant <see cref="F:log4net.Filter.FilterDecision.Deny"/>
+ </summary>
+ <param name="loggingEvent">the LoggingEvent to filter</param>
+ <returns>Always returns <see cref="F:log4net.Filter.FilterDecision.Deny"/></returns>
+ <remarks>
+ <para>
+ Ignores the event being logged and just returns
+ <see cref="F:log4net.Filter.FilterDecision.Deny"/>. This can be used to change the default filter
+ chain behavior from <see cref="F:log4net.Filter.FilterDecision.Accept"/> to <see cref="F:log4net.Filter.FilterDecision.Deny"/>. This filter
+ should only be used as the last filter in the chain
+ as any further filters will be ignored!
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Filter.FilterDecision">
+ <summary>
+ The return result from <see cref="M:log4net.Filter.IFilter.Decide(log4net.Core.LoggingEvent)"/>
+ </summary>
+ <remarks>
+ <para>
+ The return result from <see cref="M:log4net.Filter.IFilter.Decide(log4net.Core.LoggingEvent)"/>
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Filter.FilterDecision.Deny">
+ <summary>
+ The log event must be dropped immediately without
+ consulting with the remaining filters, if any, in the chain.
+ </summary>
+ </member>
+ <member name="F:log4net.Filter.FilterDecision.Neutral">
+ <summary>
+ This filter is neutral with respect to the log event.
+ The remaining filters, if any, should be consulted for a final decision.
+ </summary>
+ </member>
+ <member name="F:log4net.Filter.FilterDecision.Accept">
+ <summary>
+ The log event must be logged immediately without
+ consulting with the remaining filters, if any, in the chain.
+ </summary>
+ </member>
+ <member name="T:log4net.Filter.LevelMatchFilter">
+ <summary>
+ This is a very simple filter based on <see cref="T:log4net.Core.Level"/> matching.
+ </summary>
+ <remarks>
+ <para>
+ The filter admits two options <see cref="P:log4net.Filter.LevelMatchFilter.LevelToMatch"/> and
+ <see cref="P:log4net.Filter.LevelMatchFilter.AcceptOnMatch"/>. If there is an exact match between the value
+ of the <see cref="P:log4net.Filter.LevelMatchFilter.LevelToMatch"/> option and the <see cref="T:log4net.Core.Level"/> of the
+ <see cref="T:log4net.Core.LoggingEvent"/>, then the <see cref="M:log4net.Filter.LevelMatchFilter.Decide(log4net.Core.LoggingEvent)"/> method returns <see cref="F:log4net.Filter.FilterDecision.Accept"/> in
+ case the <see cref="P:log4net.Filter.LevelMatchFilter.AcceptOnMatch"/> option value is set
+ to <c>true</c>, if it is <c>false</c> then
+ <see cref="F:log4net.Filter.FilterDecision.Deny"/> is returned. If the <see cref="T:log4net.Core.Level"/> does not match then
+ the result will be <see cref="F:log4net.Filter.FilterDecision.Neutral"/>.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="F:log4net.Filter.LevelMatchFilter.m_acceptOnMatch">
+ <summary>
+ flag to indicate if the filter should <see cref="F:log4net.Filter.FilterDecision.Accept"/> on a match
+ </summary>
+ </member>
+ <member name="F:log4net.Filter.LevelMatchFilter.m_levelToMatch">
+ <summary>
+ the <see cref="T:log4net.Core.Level"/> to match against
+ </summary>
+ </member>
+ <member name="M:log4net.Filter.LevelMatchFilter.#ctor">
+ <summary>
+ Default constructor
+ </summary>
+ </member>
+ <member name="M:log4net.Filter.LevelMatchFilter.Decide(log4net.Core.LoggingEvent)">
+ <summary>
+ Tests if the <see cref="T:log4net.Core.Level"/> of the logging event matches that of the filter
+ </summary>
+ <param name="loggingEvent">the event to filter</param>
+ <returns>see remarks</returns>
+ <remarks>
+ <para>
+ If the <see cref="T:log4net.Core.Level"/> of the event matches the level of the
+ filter then the result of the function depends on the
+ value of <see cref="P:log4net.Filter.LevelMatchFilter.AcceptOnMatch"/>. If it is true then
+ the function will return <see cref="F:log4net.Filter.FilterDecision.Accept"/>, it it is false then it
+ will return <see cref="F:log4net.Filter.FilterDecision.Deny"/>. If the <see cref="T:log4net.Core.Level"/> does not match then
+ the result will be <see cref="F:log4net.Filter.FilterDecision.Neutral"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Filter.LevelMatchFilter.AcceptOnMatch">
+ <summary>
+ <see cref="F:log4net.Filter.FilterDecision.Accept"/> when matching <see cref="P:log4net.Filter.LevelMatchFilter.LevelToMatch"/>
+ </summary>
+ <remarks>
+ <para>
+ The <see cref="P:log4net.Filter.LevelMatchFilter.AcceptOnMatch"/> property is a flag that determines
+ the behavior when a matching <see cref="T:log4net.Core.Level"/> is found. If the
+ flag is set to true then the filter will <see cref="F:log4net.Filter.FilterDecision.Accept"/> the
+ logging event, otherwise it will <see cref="F:log4net.Filter.FilterDecision.Deny"/> the event.
+ </para>
+ <para>
+ The default is <c>true</c> i.e. to <see cref="F:log4net.Filter.FilterDecision.Accept"/> the event.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Filter.LevelMatchFilter.LevelToMatch">
+ <summary>
+ The <see cref="T:log4net.Core.Level"/> that the filter will match
+ </summary>
+ <remarks>
+ <para>
+ The level that this filter will attempt to match against the
+ <see cref="T:log4net.Core.LoggingEvent"/> level. If a match is found then
+ the result depends on the value of <see cref="P:log4net.Filter.LevelMatchFilter.AcceptOnMatch"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Filter.LevelRangeFilter">
+ <summary>
+ This is a simple filter based on <see cref="T:log4net.Core.Level"/> matching.
+ </summary>
+ <remarks>
+ <para>
+ The filter admits three options <see cref="P:log4net.Filter.LevelRangeFilter.LevelMin"/> and <see cref="P:log4net.Filter.LevelRangeFilter.LevelMax"/>
+ that determine the range of priorities that are matched, and
+ <see cref="P:log4net.Filter.LevelRangeFilter.AcceptOnMatch"/>. If there is a match between the range
+ of priorities and the <see cref="T:log4net.Core.Level"/> of the <see cref="T:log4net.Core.LoggingEvent"/>, then the
+ <see cref="M:log4net.Filter.LevelRangeFilter.Decide(log4net.Core.LoggingEvent)"/> method returns <see cref="F:log4net.Filter.FilterDecision.Accept"/> in case the <see cref="P:log4net.Filter.LevelRangeFilter.AcceptOnMatch"/>
+ option value is set to <c>true</c>, if it is <c>false</c>
+ then <see cref="F:log4net.Filter.FilterDecision.Deny"/> is returned. If there is no match, <see cref="F:log4net.Filter.FilterDecision.Deny"/> is returned.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="F:log4net.Filter.LevelRangeFilter.m_acceptOnMatch">
+ <summary>
+ Flag to indicate the behavior when matching a <see cref="T:log4net.Core.Level"/>
+ </summary>
+ </member>
+ <member name="F:log4net.Filter.LevelRangeFilter.m_levelMin">
+ <summary>
+ the minimum <see cref="T:log4net.Core.Level"/> value to match
+ </summary>
+ </member>
+ <member name="F:log4net.Filter.LevelRangeFilter.m_levelMax">
+ <summary>
+ the maximum <see cref="T:log4net.Core.Level"/> value to match
+ </summary>
+ </member>
+ <member name="M:log4net.Filter.LevelRangeFilter.#ctor">
+ <summary>
+ Default constructor
+ </summary>
+ </member>
+ <member name="M:log4net.Filter.LevelRangeFilter.Decide(log4net.Core.LoggingEvent)">
+ <summary>
+ Check if the event should be logged.
+ </summary>
+ <param name="loggingEvent">the logging event to check</param>
+ <returns>see remarks</returns>
+ <remarks>
+ <para>
+ If the <see cref="T:log4net.Core.Level"/> of the logging event is outside the range
+ matched by this filter then <see cref="F:log4net.Filter.FilterDecision.Deny"/>
+ is returned. If the <see cref="T:log4net.Core.Level"/> is matched then the value of
+ <see cref="P:log4net.Filter.LevelRangeFilter.AcceptOnMatch"/> is checked. If it is true then
+ <see cref="F:log4net.Filter.FilterDecision.Accept"/> is returned, otherwise
+ <see cref="F:log4net.Filter.FilterDecision.Neutral"/> is returned.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Filter.LevelRangeFilter.AcceptOnMatch">
+ <summary>
+ <see cref="F:log4net.Filter.FilterDecision.Accept"/> when matching <see cref="P:log4net.Filter.LevelRangeFilter.LevelMin"/> and <see cref="P:log4net.Filter.LevelRangeFilter.LevelMax"/>
+ </summary>
+ <remarks>
+ <para>
+ The <see cref="P:log4net.Filter.LevelRangeFilter.AcceptOnMatch"/> property is a flag that determines
+ the behavior when a matching <see cref="T:log4net.Core.Level"/> is found. If the
+ flag is set to true then the filter will <see cref="F:log4net.Filter.FilterDecision.Accept"/> the
+ logging event, otherwise it will <see cref="F:log4net.Filter.FilterDecision.Neutral"/> the event.
+ </para>
+ <para>
+ The default is <c>true</c> i.e. to <see cref="F:log4net.Filter.FilterDecision.Accept"/> the event.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Filter.LevelRangeFilter.LevelMin">
+ <summary>
+ Set the minimum matched <see cref="T:log4net.Core.Level"/>
+ </summary>
+ <remarks>
+ <para>
+ The minimum level that this filter will attempt to match against the
+ <see cref="T:log4net.Core.LoggingEvent"/> level. If a match is found then
+ the result depends on the value of <see cref="P:log4net.Filter.LevelRangeFilter.AcceptOnMatch"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Filter.LevelRangeFilter.LevelMax">
+ <summary>
+ Sets the maximum matched <see cref="T:log4net.Core.Level"/>
+ </summary>
+ <remarks>
+ <para>
+ The maximum level that this filter will attempt to match against the
+ <see cref="T:log4net.Core.LoggingEvent"/> level. If a match is found then
+ the result depends on the value of <see cref="P:log4net.Filter.LevelRangeFilter.AcceptOnMatch"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Filter.LoggerMatchFilter">
+ <summary>
+ Simple filter to match a string in the event's logger name.
+ </summary>
+ <remarks>
+ <para>
+ The works very similar to the <see cref="T:log4net.Filter.LevelMatchFilter"/>. It admits two
+ options <see cref="P:log4net.Filter.LoggerMatchFilter.LoggerToMatch"/> and <see cref="P:log4net.Filter.LoggerMatchFilter.AcceptOnMatch"/>. If the
+ <see cref="P:log4net.Core.LoggingEvent.LoggerName"/> of the <see cref="T:log4net.Core.LoggingEvent"/> starts
+ with the value of the <see cref="P:log4net.Filter.LoggerMatchFilter.LoggerToMatch"/> option, then the
+ <see cref="M:log4net.Filter.LoggerMatchFilter.Decide(log4net.Core.LoggingEvent)"/> method returns <see cref="F:log4net.Filter.FilterDecision.Accept"/> in
+ case the <see cref="P:log4net.Filter.LoggerMatchFilter.AcceptOnMatch"/> option value is set to <c>true</c>,
+ if it is <c>false</c> then <see cref="F:log4net.Filter.FilterDecision.Deny"/> is returned.
+ </para>
+ </remarks>
+ <author>Daniel Cazzulino</author>
+ </member>
+ <member name="F:log4net.Filter.LoggerMatchFilter.m_acceptOnMatch">
+ <summary>
+ Flag to indicate the behavior when we have a match
+ </summary>
+ </member>
+ <member name="F:log4net.Filter.LoggerMatchFilter.m_loggerToMatch">
+ <summary>
+ The logger name string to substring match against the event
+ </summary>
+ </member>
+ <member name="M:log4net.Filter.LoggerMatchFilter.#ctor">
+ <summary>
+ Default constructor
+ </summary>
+ </member>
+ <member name="M:log4net.Filter.LoggerMatchFilter.Decide(log4net.Core.LoggingEvent)">
+ <summary>
+ Check if this filter should allow the event to be logged
+ </summary>
+ <param name="loggingEvent">the event being logged</param>
+ <returns>see remarks</returns>
+ <remarks>
+ <para>
+ The rendered message is matched against the <see cref="P:log4net.Filter.LoggerMatchFilter.LoggerToMatch"/>.
+ If the <see cref="P:log4net.Filter.LoggerMatchFilter.LoggerToMatch"/> equals the beginning of
+ the incoming <see cref="P:log4net.Core.LoggingEvent.LoggerName"/> (<see cref="M:System.String.StartsWith(System.String)"/>)
+ then a match will have occurred. If no match occurs
+ this function will return <see cref="F:log4net.Filter.FilterDecision.Neutral"/>
+ allowing other filters to check the event. If a match occurs then
+ the value of <see cref="P:log4net.Filter.LoggerMatchFilter.AcceptOnMatch"/> is checked. If it is
+ true then <see cref="F:log4net.Filter.FilterDecision.Accept"/> is returned otherwise
+ <see cref="F:log4net.Filter.FilterDecision.Deny"/> is returned.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Filter.LoggerMatchFilter.AcceptOnMatch">
+ <summary>
+ <see cref="F:log4net.Filter.FilterDecision.Accept"/> when matching <see cref="P:log4net.Filter.LoggerMatchFilter.LoggerToMatch"/>
+ </summary>
+ <remarks>
+ <para>
+ The <see cref="P:log4net.Filter.LoggerMatchFilter.AcceptOnMatch"/> property is a flag that determines
+ the behavior when a matching <see cref="T:log4net.Core.Level"/> is found. If the
+ flag is set to true then the filter will <see cref="F:log4net.Filter.FilterDecision.Accept"/> the
+ logging event, otherwise it will <see cref="F:log4net.Filter.FilterDecision.Deny"/> the event.
+ </para>
+ <para>
+ The default is <c>true</c> i.e. to <see cref="F:log4net.Filter.FilterDecision.Accept"/> the event.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Filter.LoggerMatchFilter.LoggerToMatch">
+ <summary>
+ The <see cref="P:log4net.Core.LoggingEvent.LoggerName"/> that the filter will match
+ </summary>
+ <remarks>
+ <para>
+ This filter will attempt to match this value against logger name in
+ the following way. The match will be done against the beginning of the
+ logger name (using <see cref="M:System.String.StartsWith(System.String)"/>). The match is
+ case sensitive. If a match is found then
+ the result depends on the value of <see cref="P:log4net.Filter.LoggerMatchFilter.AcceptOnMatch"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Filter.MdcFilter">
+ <summary>
+ Simple filter to match a keyed string in the <see cref="T:log4net.MDC"/>
+ </summary>
+ <remarks>
+ <para>
+ Simple filter to match a keyed string in the <see cref="T:log4net.MDC"/>
+ </para>
+ <para>
+ As the MDC has been replaced with layered properties the
+ <see cref="T:log4net.Filter.PropertyFilter"/> should be used instead.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="T:log4net.Filter.PropertyFilter">
+ <summary>
+ Simple filter to match a string an event property
+ </summary>
+ <remarks>
+ <para>
+ Simple filter to match a string in the value for a
+ specific event property
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="T:log4net.Filter.StringMatchFilter">
+ <summary>
+ Simple filter to match a string in the rendered message
+ </summary>
+ <remarks>
+ <para>
+ Simple filter to match a string in the rendered message
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="F:log4net.Filter.StringMatchFilter.m_acceptOnMatch">
+ <summary>
+ Flag to indicate the behavior when we have a match
+ </summary>
+ </member>
+ <member name="F:log4net.Filter.StringMatchFilter.m_stringToMatch">
+ <summary>
+ The string to substring match against the message
+ </summary>
+ </member>
+ <member name="F:log4net.Filter.StringMatchFilter.m_stringRegexToMatch">
+ <summary>
+ A string regex to match
+ </summary>
+ </member>
+ <member name="F:log4net.Filter.StringMatchFilter.m_regexToMatch">
+ <summary>
+ A regex object to match (generated from m_stringRegexToMatch)
+ </summary>
+ </member>
+ <member name="M:log4net.Filter.StringMatchFilter.#ctor">
+ <summary>
+ Default constructor
+ </summary>
+ </member>
+ <member name="M:log4net.Filter.StringMatchFilter.ActivateOptions">
+ <summary>
+ Initialize and precompile the Regex if required
+ </summary>
+ <remarks>
+ <para>
+ This is part of the <see cref="T:log4net.Core.IOptionHandler"/> delayed object
+ activation scheme. The <see cref="M:log4net.Filter.StringMatchFilter.ActivateOptions"/> method must
+ be called on this object after the configuration properties have
+ been set. Until <see cref="M:log4net.Filter.StringMatchFilter.ActivateOptions"/> is called this
+ object is in an undefined state and must not be used.
+ </para>
+ <para>
+ If any of the configuration properties are modified then
+ <see cref="M:log4net.Filter.StringMatchFilter.ActivateOptions"/> must be called again.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Filter.StringMatchFilter.Decide(log4net.Core.LoggingEvent)">
+ <summary>
+ Check if this filter should allow the event to be logged
+ </summary>
+ <param name="loggingEvent">the event being logged</param>
+ <returns>see remarks</returns>
+ <remarks>
+ <para>
+ The rendered message is matched against the <see cref="P:log4net.Filter.StringMatchFilter.StringToMatch"/>.
+ If the <see cref="P:log4net.Filter.StringMatchFilter.StringToMatch"/> occurs as a substring within
+ the message then a match will have occurred. If no match occurs
+ this function will return <see cref="F:log4net.Filter.FilterDecision.Neutral"/>
+ allowing other filters to check the event. If a match occurs then
+ the value of <see cref="P:log4net.Filter.StringMatchFilter.AcceptOnMatch"/> is checked. If it is
+ true then <see cref="F:log4net.Filter.FilterDecision.Accept"/> is returned otherwise
+ <see cref="F:log4net.Filter.FilterDecision.Deny"/> is returned.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Filter.StringMatchFilter.AcceptOnMatch">
+ <summary>
+ <see cref="F:log4net.Filter.FilterDecision.Accept"/> when matching <see cref="P:log4net.Filter.StringMatchFilter.StringToMatch"/> or <see cref="P:log4net.Filter.StringMatchFilter.RegexToMatch"/>
+ </summary>
+ <remarks>
+ <para>
+ The <see cref="P:log4net.Filter.StringMatchFilter.AcceptOnMatch"/> property is a flag that determines
+ the behavior when a matching <see cref="T:log4net.Core.Level"/> is found. If the
+ flag is set to true then the filter will <see cref="F:log4net.Filter.FilterDecision.Accept"/> the
+ logging event, otherwise it will <see cref="F:log4net.Filter.FilterDecision.Neutral"/> the event.
+ </para>
+ <para>
+ The default is <c>true</c> i.e. to <see cref="F:log4net.Filter.FilterDecision.Accept"/> the event.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Filter.StringMatchFilter.StringToMatch">
+ <summary>
+ Sets the static string to match
+ </summary>
+ <remarks>
+ <para>
+ The string that will be substring matched against
+ the rendered message. If the message contains this
+ string then the filter will match. If a match is found then
+ the result depends on the value of <see cref="P:log4net.Filter.StringMatchFilter.AcceptOnMatch"/>.
+ </para>
+ <para>
+ One of <see cref="P:log4net.Filter.StringMatchFilter.StringToMatch"/> or <see cref="P:log4net.Filter.StringMatchFilter.RegexToMatch"/>
+ must be specified.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Filter.StringMatchFilter.RegexToMatch">
+ <summary>
+ Sets the regular expression to match
+ </summary>
+ <remarks>
+ <para>
+ The regular expression pattern that will be matched against
+ the rendered message. If the message matches this
+ pattern then the filter will match. If a match is found then
+ the result depends on the value of <see cref="P:log4net.Filter.StringMatchFilter.AcceptOnMatch"/>.
+ </para>
+ <para>
+ One of <see cref="P:log4net.Filter.StringMatchFilter.StringToMatch"/> or <see cref="P:log4net.Filter.StringMatchFilter.RegexToMatch"/>
+ must be specified.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Filter.PropertyFilter.m_key">
+ <summary>
+ The key to use to lookup the string from the event properties
+ </summary>
+ </member>
+ <member name="M:log4net.Filter.PropertyFilter.#ctor">
+ <summary>
+ Default constructor
+ </summary>
+ </member>
+ <member name="M:log4net.Filter.PropertyFilter.Decide(log4net.Core.LoggingEvent)">
+ <summary>
+ Check if this filter should allow the event to be logged
+ </summary>
+ <param name="loggingEvent">the event being logged</param>
+ <returns>see remarks</returns>
+ <remarks>
+ <para>
+ The event property for the <see cref="P:log4net.Filter.PropertyFilter.Key"/> is matched against
+ the <see cref="P:log4net.Filter.StringMatchFilter.StringToMatch"/>.
+ If the <see cref="P:log4net.Filter.StringMatchFilter.StringToMatch"/> occurs as a substring within
+ the property value then a match will have occurred. If no match occurs
+ this function will return <see cref="F:log4net.Filter.FilterDecision.Neutral"/>
+ allowing other filters to check the event. If a match occurs then
+ the value of <see cref="P:log4net.Filter.StringMatchFilter.AcceptOnMatch"/> is checked. If it is
+ true then <see cref="F:log4net.Filter.FilterDecision.Accept"/> is returned otherwise
+ <see cref="F:log4net.Filter.FilterDecision.Deny"/> is returned.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Filter.PropertyFilter.Key">
+ <summary>
+ The key to lookup in the event properties and then match against.
+ </summary>
+ <remarks>
+ <para>
+ The key name to use to lookup in the properties map of the
+ <see cref="T:log4net.Core.LoggingEvent"/>. The match will be performed against
+ the value of this property if it exists.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Filter.NdcFilter">
+ <summary>
+ Simple filter to match a string in the <see cref="T:log4net.NDC"/>
+ </summary>
+ <remarks>
+ <para>
+ Simple filter to match a string in the <see cref="T:log4net.NDC"/>
+ </para>
+ <para>
+ As the MDC has been replaced with named stacks stored in the
+ properties collections the <see cref="T:log4net.Filter.PropertyFilter"/> should
+ be used instead.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="M:log4net.Filter.NdcFilter.#ctor">
+ <summary>
+ Default constructor
+ </summary>
+ <remarks>
+ <para>
+ Sets the <see cref="P:log4net.Filter.PropertyFilter.Key"/> to <c>"NDC"</c>.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Layout.Pattern.AppDomainPatternConverter">
+ <summary>
+ Write the event appdomain name to the output
+ </summary>
+ <remarks>
+ <para>
+ Writes the <see cref="P:log4net.Core.LoggingEvent.Domain"/> to the output writer.
+ </para>
+ </remarks>
+ <author>Daniel Cazzulino</author>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="T:log4net.Layout.Pattern.PatternLayoutConverter">
+ <summary>
+ Abstract class that provides the formatting functionality that
+ derived classes need.
+ </summary>
+ <remarks>
+ Conversion specifiers in a conversion patterns are parsed to
+ individual PatternConverters. Each of which is responsible for
+ converting a logging event in a converter specific manner.
+ </remarks>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="T:log4net.Util.PatternConverter">
+ <summary>
+ Abstract class that provides the formatting functionality that
+ derived classes need.
+ </summary>
+ <remarks>
+ <para>
+ Conversion specifiers in a conversion patterns are parsed to
+ individual PatternConverters. Each of which is responsible for
+ converting a logging event in a converter specific manner.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="F:log4net.Util.PatternConverter.c_renderBufferSize">
+ <summary>
+ Initial buffer size
+ </summary>
+ </member>
+ <member name="F:log4net.Util.PatternConverter.c_renderBufferMaxCapacity">
+ <summary>
+ Maximum buffer size before it is recycled
+ </summary>
+ </member>
+ <member name="M:log4net.Util.PatternConverter.#ctor">
+ <summary>
+ Protected constructor
+ </summary>
+ <remarks>
+ <para>
+ Initializes a new instance of the <see cref="T:log4net.Util.PatternConverter"/> class.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.PatternConverter.Convert(System.IO.TextWriter,System.Object)">
+ <summary>
+ Evaluate this pattern converter and write the output to a writer.
+ </summary>
+ <param name="writer"><see cref="T:System.IO.TextWriter"/> that will receive the formatted result.</param>
+ <param name="state">The state object on which the pattern converter should be executed.</param>
+ <remarks>
+ <para>
+ Derived pattern converters must override this method in order to
+ convert conversion specifiers in the appropriate way.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.PatternConverter.SetNext(log4net.Util.PatternConverter)">
+ <summary>
+ Set the next pattern converter in the chains
+ </summary>
+ <param name="patternConverter">the pattern converter that should follow this converter in the chain</param>
+ <returns>the next converter</returns>
+ <remarks>
+ <para>
+ The PatternConverter can merge with its neighbor during this method (or a sub class).
+ Therefore the return value may or may not be the value of the argument passed in.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.PatternConverter.Format(System.IO.TextWriter,System.Object)">
+ <summary>
+ Write the pattern converter to the writer with appropriate formatting
+ </summary>
+ <param name="writer"><see cref="T:System.IO.TextWriter"/> that will receive the formatted result.</param>
+ <param name="state">The state object on which the pattern converter should be executed.</param>
+ <remarks>
+ <para>
+ This method calls <see cref="M:log4net.Util.PatternConverter.Convert(System.IO.TextWriter,System.Object)"/> to allow the subclass to perform
+ appropriate conversion of the pattern converter. If formatting options have
+ been specified via the <see cref="P:log4net.Util.PatternConverter.FormattingInfo"/> then this method will
+ apply those formattings before writing the output.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.PatternConverter.SpacePad(System.IO.TextWriter,System.Int32)">
+ <summary>
+ Fast space padding method.
+ </summary>
+ <param name="writer"><see cref="T:System.IO.TextWriter"/> to which the spaces will be appended.</param>
+ <param name="length">The number of spaces to be padded.</param>
+ <remarks>
+ <para>
+ Fast space padding method.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Util.PatternConverter.m_option">
+ <summary>
+ The option string to the converter
+ </summary>
+ </member>
+ <member name="M:log4net.Util.PatternConverter.WriteDictionary(System.IO.TextWriter,log4net.Repository.ILoggerRepository,System.Collections.IDictionary)">
+ <summary>
+ Write an dictionary to a <see cref="T:System.IO.TextWriter"/>
+ </summary>
+ <param name="writer">the writer to write to</param>
+ <param name="repository">a <see cref="T:log4net.Repository.ILoggerRepository"/> to use for object conversion</param>
+ <param name="value">the value to write to the writer</param>
+ <remarks>
+ <para>
+ Writes the <see cref="T:System.Collections.IDictionary"/> to a writer in the form:
+ </para>
+ <code>
+ {key1=value1, key2=value2, key3=value3}
+ </code>
+ <para>
+ If the <see cref="T:log4net.Repository.ILoggerRepository"/> specified
+ is not null then it is used to render the key and value to text, otherwise
+ the object's ToString method is called.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.PatternConverter.WriteObject(System.IO.TextWriter,log4net.Repository.ILoggerRepository,System.Object)">
+ <summary>
+ Write an object to a <see cref="T:System.IO.TextWriter"/>
+ </summary>
+ <param name="writer">the writer to write to</param>
+ <param name="repository">a <see cref="T:log4net.Repository.ILoggerRepository"/> to use for object conversion</param>
+ <param name="value">the value to write to the writer</param>
+ <remarks>
+ <para>
+ Writes the Object to a writer. If the <see cref="T:log4net.Repository.ILoggerRepository"/> specified
+ is not null then it is used to render the object to text, otherwise
+ the object's ToString method is called.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Util.PatternConverter.Next">
+ <summary>
+ Get the next pattern converter in the chain
+ </summary>
+ <value>
+ the next pattern converter in the chain
+ </value>
+ <remarks>
+ <para>
+ Get the next pattern converter in the chain
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Util.PatternConverter.FormattingInfo">
+ <summary>
+ Gets or sets the formatting info for this converter
+ </summary>
+ <value>
+ The formatting info for this converter
+ </value>
+ <remarks>
+ <para>
+ Gets or sets the formatting info for this converter
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Util.PatternConverter.Option">
+ <summary>
+ Gets or sets the option value for this converter
+ </summary>
+ <summary>
+ The option for this converter
+ </summary>
+ <remarks>
+ <para>
+ Gets or sets the option value for this converter
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Layout.Pattern.PatternLayoutConverter.#ctor">
+ <summary>
+ Initializes a new instance of the <see cref="T:log4net.Layout.Pattern.PatternLayoutConverter"/> class.
+ </summary>
+ </member>
+ <member name="M:log4net.Layout.Pattern.PatternLayoutConverter.Convert(System.IO.TextWriter,log4net.Core.LoggingEvent)">
+ <summary>
+ Derived pattern converters must override this method in order to
+ convert conversion specifiers in the correct way.
+ </summary>
+ <param name="writer"><see cref="T:System.IO.TextWriter"/> that will receive the formatted result.</param>
+ <param name="loggingEvent">The <see cref="T:log4net.Core.LoggingEvent"/> on which the pattern converter should be executed.</param>
+ </member>
+ <member name="M:log4net.Layout.Pattern.PatternLayoutConverter.Convert(System.IO.TextWriter,System.Object)">
+ <summary>
+ Derived pattern converters must override this method in order to
+ convert conversion specifiers in the correct way.
+ </summary>
+ <param name="writer"><see cref="T:System.IO.TextWriter"/> that will receive the formatted result.</param>
+ <param name="state">The state object on which the pattern converter should be executed.</param>
+ </member>
+ <member name="F:log4net.Layout.Pattern.PatternLayoutConverter.m_ignoresException">
+ <summary>
+ Flag indicating if this converter handles exceptions
+ </summary>
+ <remarks>
+ <c>false</c> if this converter handles exceptions
+ </remarks>
+ </member>
+ <member name="P:log4net.Layout.Pattern.PatternLayoutConverter.IgnoresException">
+ <summary>
+ Flag indicating if this converter handles the logging event exception
+ </summary>
+ <value><c>false</c> if this converter handles the logging event exception</value>
+ <remarks>
+ <para>
+ If this converter handles the exception object contained within
+ <see cref="T:log4net.Core.LoggingEvent"/>, then this property should be set to
+ <c>false</c>. Otherwise, if the layout ignores the exception
+ object, then the property should be set to <c>true</c>.
+ </para>
+ <para>
+ Set this value to override a this default setting. The default
+ value is <c>true</c>, this converter does not handle the exception.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Layout.Pattern.AppDomainPatternConverter.Convert(System.IO.TextWriter,log4net.Core.LoggingEvent)">
+ <summary>
+ Write the event appdomain name to the output
+ </summary>
+ <param name="writer"><see cref="T:System.IO.TextWriter"/> that will receive the formatted result.</param>
+ <param name="loggingEvent">the event being logged</param>
+ <remarks>
+ <para>
+ Writes the <see cref="P:log4net.Core.LoggingEvent.Domain"/> to the output <paramref name="writer"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Layout.Pattern.DatePatternConverter">
+ <summary>
+ Date pattern converter, uses a <see cref="T:log4net.DateFormatter.IDateFormatter"/> to format
+ the date of a <see cref="T:log4net.Core.LoggingEvent"/>.
+ </summary>
+ <remarks>
+ <para>
+ Render the <see cref="P:log4net.Core.LoggingEvent.TimeStamp"/> to the writer as a string.
+ </para>
+ <para>
+ The value of the <see cref="P:log4net.Util.PatternConverter.Option"/> determines
+ the formatting of the date. The following values are allowed:
+ <list type="definition">
+ <listheader>
+ <term>Option value</term>
+ <description>Output</description>
+ </listheader>
+ <item>
+ <term>ISO8601</term>
+ <description>
+ Uses the <see cref="T:log4net.DateFormatter.Iso8601DateFormatter"/> formatter.
+ Formats using the <c>"yyyy-MM-dd HH:mm:ss,fff"</c> pattern.
+ </description>
+ </item>
+ <item>
+ <term>DATE</term>
+ <description>
+ Uses the <see cref="T:log4net.DateFormatter.DateTimeDateFormatter"/> formatter.
+ Formats using the <c>"dd MMM yyyy HH:mm:ss,fff"</c> for example, <c>"06 Nov 1994 15:49:37,459"</c>.
+ </description>
+ </item>
+ <item>
+ <term>ABSOLUTE</term>
+ <description>
+ Uses the <see cref="T:log4net.DateFormatter.AbsoluteTimeDateFormatter"/> formatter.
+ Formats using the <c>"HH:mm:ss,yyyy"</c> for example, <c>"15:49:37,459"</c>.
+ </description>
+ </item>
+ <item>
+ <term>other</term>
+ <description>
+ Any other pattern string uses the <see cref="T:log4net.DateFormatter.SimpleDateFormatter"/> formatter.
+ This formatter passes the pattern string to the <see cref="T:System.DateTime"/>
+ <see cref="M:System.DateTime.ToString(System.String)"/> method.
+ For details on valid patterns see
+ <a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfsystemglobalizationdatetimeformatinfoclasstopic.asp">DateTimeFormatInfo Class</a>.
+ </description>
+ </item>
+ </list>
+ </para>
+ <para>
+ The <see cref="P:log4net.Core.LoggingEvent.TimeStamp"/> is in the local time zone and is rendered in that zone.
+ To output the time in Universal time see <see cref="T:log4net.Layout.Pattern.UtcDatePatternConverter"/>.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="F:log4net.Layout.Pattern.DatePatternConverter.m_dateFormatter">
+ <summary>
+ The <see cref="T:log4net.DateFormatter.IDateFormatter"/> used to render the date to a string
+ </summary>
+ <remarks>
+ <para>
+ The <see cref="T:log4net.DateFormatter.IDateFormatter"/> used to render the date to a string
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Layout.Pattern.DatePatternConverter.ActivateOptions">
+ <summary>
+ Initialize the converter pattern based on the <see cref="P:log4net.Util.PatternConverter.Option"/> property.
+ </summary>
+ <remarks>
+ <para>
+ This is part of the <see cref="T:log4net.Core.IOptionHandler"/> delayed object
+ activation scheme. The <see cref="M:log4net.Layout.Pattern.DatePatternConverter.ActivateOptions"/> method must
+ be called on this object after the configuration properties have
+ been set. Until <see cref="M:log4net.Layout.Pattern.DatePatternConverter.ActivateOptions"/> is called this
+ object is in an undefined state and must not be used.
+ </para>
+ <para>
+ If any of the configuration properties are modified then
+ <see cref="M:log4net.Layout.Pattern.DatePatternConverter.ActivateOptions"/> must be called again.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Layout.Pattern.DatePatternConverter.Convert(System.IO.TextWriter,log4net.Core.LoggingEvent)">
+ <summary>
+ Convert the pattern into the rendered message
+ </summary>
+ <param name="writer"><see cref="T:System.IO.TextWriter"/> that will receive the formatted result.</param>
+ <param name="loggingEvent">the event being logged</param>
+ <remarks>
+ <para>
+ Pass the <see cref="P:log4net.Core.LoggingEvent.TimeStamp"/> to the <see cref="T:log4net.DateFormatter.IDateFormatter"/>
+ for it to render it to the writer.
+ </para>
+ <para>
+ The <see cref="P:log4net.Core.LoggingEvent.TimeStamp"/> passed is in the local time zone.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Layout.Pattern.ExceptionPatternConverter">
+ <summary>
+ Write the exception text to the output
+ </summary>
+ <remarks>
+ <para>
+ If an exception object is stored in the logging event
+ it will be rendered into the pattern output with a
+ trailing newline.
+ </para>
+ <para>
+ If there is no exception then nothing will be output
+ and no trailing newline will be appended.
+ It is typical to put a newline before the exception
+ and to have the exception as the last data in the pattern.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="M:log4net.Layout.Pattern.ExceptionPatternConverter.#ctor">
+ <summary>
+ Default constructor
+ </summary>
+ </member>
+ <member name="M:log4net.Layout.Pattern.ExceptionPatternConverter.Convert(System.IO.TextWriter,log4net.Core.LoggingEvent)">
+ <summary>
+ Write the exception text to the output
+ </summary>
+ <param name="writer"><see cref="T:System.IO.TextWriter"/> that will receive the formatted result.</param>
+ <param name="loggingEvent">the event being logged</param>
+ <remarks>
+ <para>
+ If an exception object is stored in the logging event
+ it will be rendered into the pattern output with a
+ trailing newline.
+ </para>
+ <para>
+ If there is no exception then nothing will be output
+ and no trailing newline will be appended.
+ It is typical to put a newline before the exception
+ and to have the exception as the last data in the pattern.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Layout.Pattern.FileLocationPatternConverter">
+ <summary>
+ Writes the caller location file name to the output
+ </summary>
+ <remarks>
+ <para>
+ Writes the value of the <see cref="P:log4net.Core.LocationInfo.FileName"/> for
+ the event to the output writer.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="M:log4net.Layout.Pattern.FileLocationPatternConverter.Convert(System.IO.TextWriter,log4net.Core.LoggingEvent)">
+ <summary>
+ Write the caller location file name to the output
+ </summary>
+ <param name="writer"><see cref="T:System.IO.TextWriter"/> that will receive the formatted result.</param>
+ <param name="loggingEvent">the event being logged</param>
+ <remarks>
+ <para>
+ Writes the value of the <see cref="P:log4net.Core.LocationInfo.FileName"/> for
+ the <paramref name="loggingEvent"/> to the output <paramref name="writer"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Layout.Pattern.FullLocationPatternConverter">
+ <summary>
+ Write the caller location info to the output
+ </summary>
+ <remarks>
+ <para>
+ Writes the <see cref="P:log4net.Core.LocationInfo.FullInfo"/> to the output writer.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="M:log4net.Layout.Pattern.FullLocationPatternConverter.Convert(System.IO.TextWriter,log4net.Core.LoggingEvent)">
+ <summary>
+ Write the caller location info to the output
+ </summary>
+ <param name="writer"><see cref="T:System.IO.TextWriter"/> that will receive the formatted result.</param>
+ <param name="loggingEvent">the event being logged</param>
+ <remarks>
+ <para>
+ Writes the <see cref="P:log4net.Core.LocationInfo.FullInfo"/> to the output writer.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Layout.Pattern.IdentityPatternConverter">
+ <summary>
+ Writes the event identity to the output
+ </summary>
+ <remarks>
+ <para>
+ Writes the value of the <see cref="P:log4net.Core.LoggingEvent.Identity"/> to
+ the output writer.
+ </para>
+ </remarks>
+ <author>Daniel Cazzulino</author>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="M:log4net.Layout.Pattern.IdentityPatternConverter.Convert(System.IO.TextWriter,log4net.Core.LoggingEvent)">
+ <summary>
+ Writes the event identity to the output
+ </summary>
+ <param name="writer"><see cref="T:System.IO.TextWriter"/> that will receive the formatted result.</param>
+ <param name="loggingEvent">the event being logged</param>
+ <remarks>
+ <para>
+ Writes the value of the <paramref name="loggingEvent"/>
+ <see cref="P:log4net.Core.LoggingEvent.Identity"/> to
+ the output <paramref name="writer"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Layout.Pattern.LevelPatternConverter">
+ <summary>
+ Write the event level to the output
+ </summary>
+ <remarks>
+ <para>
+ Writes the display name of the event <see cref="P:log4net.Core.LoggingEvent.Level"/>
+ to the writer.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="M:log4net.Layout.Pattern.LevelPatternConverter.Convert(System.IO.TextWriter,log4net.Core.LoggingEvent)">
+ <summary>
+ Write the event level to the output
+ </summary>
+ <param name="writer"><see cref="T:System.IO.TextWriter"/> that will receive the formatted result.</param>
+ <param name="loggingEvent">the event being logged</param>
+ <remarks>
+ <para>
+ Writes the <see cref="P:log4net.Core.Level.DisplayName"/> of the <paramref name="loggingEvent"/> <see cref="P:log4net.Core.LoggingEvent.Level"/>
+ to the <paramref name="writer"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Layout.Pattern.LineLocationPatternConverter">
+ <summary>
+ Write the caller location line number to the output
+ </summary>
+ <remarks>
+ <para>
+ Writes the value of the <see cref="P:log4net.Core.LocationInfo.LineNumber"/> for
+ the event to the output writer.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="M:log4net.Layout.Pattern.LineLocationPatternConverter.Convert(System.IO.TextWriter,log4net.Core.LoggingEvent)">
+ <summary>
+ Write the caller location line number to the output
+ </summary>
+ <param name="writer"><see cref="T:System.IO.TextWriter"/> that will receive the formatted result.</param>
+ <param name="loggingEvent">the event being logged</param>
+ <remarks>
+ <para>
+ Writes the value of the <see cref="P:log4net.Core.LocationInfo.LineNumber"/> for
+ the <paramref name="loggingEvent"/> to the output <paramref name="writer"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Layout.Pattern.LoggerPatternConverter">
+ <summary>
+ Converter for logger name
+ </summary>
+ <remarks>
+ <para>
+ Outputs the <see cref="P:log4net.Core.LoggingEvent.LoggerName"/> of the event.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="T:log4net.Layout.Pattern.NamedPatternConverter">
+ <summary>
+ Converter to output and truncate <c>'.'</c> separated strings
+ </summary>
+ <remarks>
+ <para>
+ This abstract class supports truncating a <c>'.'</c> separated string
+ to show a specified number of elements from the right hand side.
+ This is used to truncate class names that are fully qualified.
+ </para>
+ <para>
+ Subclasses should override the <see cref="M:log4net.Layout.Pattern.NamedPatternConverter.GetFullyQualifiedName(log4net.Core.LoggingEvent)"/> method to
+ return the fully qualified string.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="M:log4net.Layout.Pattern.NamedPatternConverter.ActivateOptions">
+ <summary>
+ Initialize the converter
+ </summary>
+ <remarks>
+ <para>
+ This is part of the <see cref="T:log4net.Core.IOptionHandler"/> delayed object
+ activation scheme. The <see cref="M:log4net.Layout.Pattern.NamedPatternConverter.ActivateOptions"/> method must
+ be called on this object after the configuration properties have
+ been set. Until <see cref="M:log4net.Layout.Pattern.NamedPatternConverter.ActivateOptions"/> is called this
+ object is in an undefined state and must not be used.
+ </para>
+ <para>
+ If any of the configuration properties are modified then
+ <see cref="M:log4net.Layout.Pattern.NamedPatternConverter.ActivateOptions"/> must be called again.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Layout.Pattern.NamedPatternConverter.GetFullyQualifiedName(log4net.Core.LoggingEvent)">
+ <summary>
+ Get the fully qualified string data
+ </summary>
+ <param name="loggingEvent">the event being logged</param>
+ <returns>the fully qualified name</returns>
+ <remarks>
+ <para>
+ Overridden by subclasses to get the fully qualified name before the
+ precision is applied to it.
+ </para>
+ <para>
+ Return the fully qualified <c>'.'</c> (dot/period) separated string.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Layout.Pattern.NamedPatternConverter.Convert(System.IO.TextWriter,log4net.Core.LoggingEvent)">
+ <summary>
+ Convert the pattern to the rendered message
+ </summary>
+ <param name="writer"><see cref="T:System.IO.TextWriter"/> that will receive the formatted result.</param>
+ <param name="loggingEvent">the event being logged</param>
+ <remarks>
+ Render the <see cref="M:log4net.Layout.Pattern.NamedPatternConverter.GetFullyQualifiedName(log4net.Core.LoggingEvent)"/> to the precision
+ specified by the <see cref="P:log4net.Util.PatternConverter.Option"/> property.
+ </remarks>
+ </member>
+ <member name="M:log4net.Layout.Pattern.LoggerPatternConverter.GetFullyQualifiedName(log4net.Core.LoggingEvent)">
+ <summary>
+ Gets the fully qualified name of the logger
+ </summary>
+ <param name="loggingEvent">the event being logged</param>
+ <returns>The fully qualified logger name</returns>
+ <remarks>
+ <para>
+ Returns the <see cref="P:log4net.Core.LoggingEvent.LoggerName"/> of the <paramref name="loggingEvent"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Layout.Pattern.MessagePatternConverter">
+ <summary>
+ Writes the event message to the output
+ </summary>
+ <remarks>
+ <para>
+ Uses the <see cref="M:log4net.Core.LoggingEvent.WriteRenderedMessage(System.IO.TextWriter)"/> method
+ to write out the event message.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="M:log4net.Layout.Pattern.MessagePatternConverter.Convert(System.IO.TextWriter,log4net.Core.LoggingEvent)">
+ <summary>
+ Writes the event message to the output
+ </summary>
+ <param name="writer"><see cref="T:System.IO.TextWriter"/> that will receive the formatted result.</param>
+ <param name="loggingEvent">the event being logged</param>
+ <remarks>
+ <para>
+ Uses the <see cref="M:log4net.Core.LoggingEvent.WriteRenderedMessage(System.IO.TextWriter)"/> method
+ to write out the event message.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Layout.Pattern.MethodLocationPatternConverter">
+ <summary>
+ Write the method name to the output
+ </summary>
+ <remarks>
+ <para>
+ Writes the caller location <see cref="P:log4net.Core.LocationInfo.MethodName"/> to
+ the output.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="M:log4net.Layout.Pattern.MethodLocationPatternConverter.Convert(System.IO.TextWriter,log4net.Core.LoggingEvent)">
+ <summary>
+ Write the method name to the output
+ </summary>
+ <param name="writer"><see cref="T:System.IO.TextWriter"/> that will receive the formatted result.</param>
+ <param name="loggingEvent">the event being logged</param>
+ <remarks>
+ <para>
+ Writes the caller location <see cref="P:log4net.Core.LocationInfo.MethodName"/> to
+ the output.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Layout.Pattern.NdcPatternConverter">
+ <summary>
+ Converter to include event NDC
+ </summary>
+ <remarks>
+ <para>
+ Outputs the value of the event property named <c>NDC</c>.
+ </para>
+ <para>
+ The <see cref="T:log4net.Layout.Pattern.PropertyPatternConverter"/> should be used instead.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="M:log4net.Layout.Pattern.NdcPatternConverter.Convert(System.IO.TextWriter,log4net.Core.LoggingEvent)">
+ <summary>
+ Write the event NDC to the output
+ </summary>
+ <param name="writer"><see cref="T:System.IO.TextWriter"/> that will receive the formatted result.</param>
+ <param name="loggingEvent">the event being logged</param>
+ <remarks>
+ <para>
+ As the thread context stacks are now stored in named event properties
+ this converter simply looks up the value of the <c>NDC</c> property.
+ </para>
+ <para>
+ The <see cref="T:log4net.Layout.Pattern.PropertyPatternConverter"/> should be used instead.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Layout.Pattern.PropertyPatternConverter">
+ <summary>
+ Property pattern converter
+ </summary>
+ <remarks>
+ <para>
+ Writes out the value of a named property. The property name
+ should be set in the <see cref="P:log4net.Util.PatternConverter.Option"/>
+ property.
+ </para>
+ <para>
+ If the <see cref="P:log4net.Util.PatternConverter.Option"/> is set to <c>null</c>
+ then all the properties are written as key value pairs.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="M:log4net.Layout.Pattern.PropertyPatternConverter.Convert(System.IO.TextWriter,log4net.Core.LoggingEvent)">
+ <summary>
+ Write the property value to the output
+ </summary>
+ <param name="writer"><see cref="T:System.IO.TextWriter"/> that will receive the formatted result.</param>
+ <param name="loggingEvent">the event being logged</param>
+ <remarks>
+ <para>
+ Writes out the value of a named property. The property name
+ should be set in the <see cref="P:log4net.Util.PatternConverter.Option"/>
+ property.
+ </para>
+ <para>
+ If the <see cref="P:log4net.Util.PatternConverter.Option"/> is set to <c>null</c>
+ then all the properties are written as key value pairs.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Layout.Pattern.RelativeTimePatternConverter">
+ <summary>
+ Converter to output the relative time of the event
+ </summary>
+ <remarks>
+ <para>
+ Converter to output the time of the event relative to the start of the program.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="M:log4net.Layout.Pattern.RelativeTimePatternConverter.Convert(System.IO.TextWriter,log4net.Core.LoggingEvent)">
+ <summary>
+ Write the relative time to the output
+ </summary>
+ <param name="writer"><see cref="T:System.IO.TextWriter"/> that will receive the formatted result.</param>
+ <param name="loggingEvent">the event being logged</param>
+ <remarks>
+ <para>
+ Writes out the relative time of the event in milliseconds.
+ That is the number of milliseconds between the event <see cref="P:log4net.Core.LoggingEvent.TimeStamp"/>
+ and the <see cref="P:log4net.Core.LoggingEvent.StartTime"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Layout.Pattern.RelativeTimePatternConverter.TimeDifferenceInMillis(System.DateTime,System.DateTime)">
+ <summary>
+ Helper method to get the time difference between two DateTime objects
+ </summary>
+ <param name="start">start time (in the current local time zone)</param>
+ <param name="end">end time (in the current local time zone)</param>
+ <returns>the time difference in milliseconds</returns>
+ </member>
+ <member name="T:log4net.Layout.Pattern.ThreadPatternConverter">
+ <summary>
+ Converter to include event thread name
+ </summary>
+ <remarks>
+ <para>
+ Writes the <see cref="P:log4net.Core.LoggingEvent.ThreadName"/> to the output.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="M:log4net.Layout.Pattern.ThreadPatternConverter.Convert(System.IO.TextWriter,log4net.Core.LoggingEvent)">
+ <summary>
+ Write the ThreadName to the output
+ </summary>
+ <param name="writer"><see cref="T:System.IO.TextWriter"/> that will receive the formatted result.</param>
+ <param name="loggingEvent">the event being logged</param>
+ <remarks>
+ <para>
+ Writes the <see cref="P:log4net.Core.LoggingEvent.ThreadName"/> to the <paramref name="writer"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Layout.Pattern.TypeNamePatternConverter">
+ <summary>
+ Pattern converter for the class name
+ </summary>
+ <remarks>
+ <para>
+ Outputs the <see cref="P:log4net.Core.LocationInfo.ClassName"/> of the event.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="M:log4net.Layout.Pattern.TypeNamePatternConverter.GetFullyQualifiedName(log4net.Core.LoggingEvent)">
+ <summary>
+ Gets the fully qualified name of the class
+ </summary>
+ <param name="loggingEvent">the event being logged</param>
+ <returns>The fully qualified type name for the caller location</returns>
+ <remarks>
+ <para>
+ Returns the <see cref="P:log4net.Core.LocationInfo.ClassName"/> of the <paramref name="loggingEvent"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Layout.Pattern.UserNamePatternConverter">
+ <summary>
+ Converter to include event user name
+ </summary>
+ <author>Douglas de la Torre</author>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="M:log4net.Layout.Pattern.UserNamePatternConverter.Convert(System.IO.TextWriter,log4net.Core.LoggingEvent)">
+ <summary>
+ Convert the pattern to the rendered message
+ </summary>
+ <param name="writer"><see cref="T:System.IO.TextWriter"/> that will receive the formatted result.</param>
+ <param name="loggingEvent">the event being logged</param>
+ </member>
+ <member name="T:log4net.Layout.Pattern.UtcDatePatternConverter">
+ <summary>
+ Write the TimeStamp to the output
+ </summary>
+ <remarks>
+ <para>
+ Date pattern converter, uses a <see cref="T:log4net.DateFormatter.IDateFormatter"/> to format
+ the date of a <see cref="T:log4net.Core.LoggingEvent"/>.
+ </para>
+ <para>
+ Uses a <see cref="T:log4net.DateFormatter.IDateFormatter"/> to format the <see cref="P:log4net.Core.LoggingEvent.TimeStamp"/>
+ in Universal time.
+ </para>
+ <para>
+ See the <see cref="T:log4net.Layout.Pattern.DatePatternConverter"/> for details on the date pattern syntax.
+ </para>
+ </remarks>
+ <seealso cref="T:log4net.Layout.Pattern.DatePatternConverter"/>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="M:log4net.Layout.Pattern.UtcDatePatternConverter.Convert(System.IO.TextWriter,log4net.Core.LoggingEvent)">
+ <summary>
+ Write the TimeStamp to the output
+ </summary>
+ <param name="writer"><see cref="T:System.IO.TextWriter"/> that will receive the formatted result.</param>
+ <param name="loggingEvent">the event being logged</param>
+ <remarks>
+ <para>
+ Pass the <see cref="P:log4net.Core.LoggingEvent.TimeStamp"/> to the <see cref="T:log4net.DateFormatter.IDateFormatter"/>
+ for it to render it to the writer.
+ </para>
+ <para>
+ The <see cref="P:log4net.Core.LoggingEvent.TimeStamp"/> passed is in the local time zone, this is converted
+ to Universal time before it is rendered.
+ </para>
+ </remarks>
+ <seealso cref="T:log4net.Layout.Pattern.DatePatternConverter"/>
+ </member>
+ <member name="T:log4net.Layout.ExceptionLayout">
+ <summary>
+ A Layout that renders only the Exception text from the logging event
+ </summary>
+ <remarks>
+ <para>
+ A Layout that renders only the Exception text from the logging event.
+ </para>
+ <para>
+ This Layout should only be used with appenders that utilize multiple
+ layouts (e.g. <see cref="T:log4net.Appender.AdoNetAppender"/>).
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="T:log4net.Layout.LayoutSkeleton">
+ <summary>
+ Extend this abstract class to create your own log layout format.
+ </summary>
+ <remarks>
+ <para>
+ This is the base implementation of the <see cref="T:log4net.Layout.ILayout"/>
+ interface. Most layout objects should extend this class.
+ </para>
+ </remarks>
+ <remarks>
+ <note type="inheritinfo">
+ <para>
+ Subclasses must implement the <see cref="M:log4net.Layout.LayoutSkeleton.Format(System.IO.TextWriter,log4net.Core.LoggingEvent)"/>
+ method.
+ </para>
+ <para>
+ Subclasses should set the <see cref="P:log4net.Layout.LayoutSkeleton.IgnoresException"/> in their default
+ constructor.
+ </para>
+ </note>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="T:log4net.Layout.ILayout">
+ <summary>
+ Interface implemented by layout objects
+ </summary>
+ <remarks>
+ <para>
+ An <see cref="T:log4net.Layout.ILayout"/> object is used to format a <see cref="T:log4net.Core.LoggingEvent"/>
+ as text. The <see cref="M:log4net.Layout.ILayout.Format(System.IO.TextWriter,log4net.Core.LoggingEvent)"/> method is called by an
+ appender to transform the <see cref="T:log4net.Core.LoggingEvent"/> into a string.
+ </para>
+ <para>
+ The layout can also supply <see cref="P:log4net.Layout.ILayout.Header"/> and <see cref="P:log4net.Layout.ILayout.Footer"/>
+ text that is appender before any events and after all the events respectively.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="M:log4net.Layout.ILayout.Format(System.IO.TextWriter,log4net.Core.LoggingEvent)">
+ <summary>
+ Implement this method to create your own layout format.
+ </summary>
+ <param name="writer">The TextWriter to write the formatted event to</param>
+ <param name="loggingEvent">The event to format</param>
+ <remarks>
+ <para>
+ This method is called by an appender to format
+ the <paramref name="loggingEvent"/> as text and output to a writer.
+ </para>
+ <para>
+ If the caller does not have a <see cref="T:System.IO.TextWriter"/> and prefers the
+ event to be formatted as a <see cref="T:System.String"/> then the following
+ code can be used to format the event into a <see cref="T:System.IO.StringWriter"/>.
+ </para>
+ <code lang="C#">
+ StringWriter writer = new StringWriter();
+ Layout.Format(writer, loggingEvent);
+ string formattedEvent = writer.ToString();
+ </code>
+ </remarks>
+ </member>
+ <member name="P:log4net.Layout.ILayout.ContentType">
+ <summary>
+ The content type output by this layout.
+ </summary>
+ <value>The content type</value>
+ <remarks>
+ <para>
+ The content type output by this layout.
+ </para>
+ <para>
+ This is a MIME type e.g. <c>"text/plain"</c>.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Layout.ILayout.Header">
+ <summary>
+ The header for the layout format.
+ </summary>
+ <value>the layout header</value>
+ <remarks>
+ <para>
+ The Header text will be appended before any logging events
+ are formatted and appended.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Layout.ILayout.Footer">
+ <summary>
+ The footer for the layout format.
+ </summary>
+ <value>the layout footer</value>
+ <remarks>
+ <para>
+ The Footer text will be appended after all the logging events
+ have been formatted and appended.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Layout.ILayout.IgnoresException">
+ <summary>
+ Flag indicating if this layout handle exceptions
+ </summary>
+ <value><c>false</c> if this layout handles exceptions</value>
+ <remarks>
+ <para>
+ If this layout handles the exception object contained within
+ <see cref="T:log4net.Core.LoggingEvent"/>, then the layout should return
+ <c>false</c>. Otherwise, if the layout ignores the exception
+ object, then the layout should return <c>true</c>.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Layout.LayoutSkeleton.m_header">
+ <summary>
+ The header text
+ </summary>
+ <remarks>
+ <para>
+ See <see cref="P:log4net.Layout.LayoutSkeleton.Header"/> for more information.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Layout.LayoutSkeleton.m_footer">
+ <summary>
+ The footer text
+ </summary>
+ <remarks>
+ <para>
+ See <see cref="P:log4net.Layout.LayoutSkeleton.Footer"/> for more information.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Layout.LayoutSkeleton.m_ignoresException">
+ <summary>
+ Flag indicating if this layout handles exceptions
+ </summary>
+ <remarks>
+ <para>
+ <c>false</c> if this layout handles exceptions
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Layout.LayoutSkeleton.#ctor">
+ <summary>
+ Empty default constructor
+ </summary>
+ <remarks>
+ <para>
+ Empty default constructor
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Layout.LayoutSkeleton.ActivateOptions">
+ <summary>
+ Activate component options
+ </summary>
+ <remarks>
+ <para>
+ This is part of the <see cref="T:log4net.Core.IOptionHandler"/> delayed object
+ activation scheme. The <see cref="M:log4net.Layout.LayoutSkeleton.ActivateOptions"/> method must
+ be called on this object after the configuration properties have
+ been set. Until <see cref="M:log4net.Layout.LayoutSkeleton.ActivateOptions"/> is called this
+ object is in an undefined state and must not be used.
+ </para>
+ <para>
+ If any of the configuration properties are modified then
+ <see cref="M:log4net.Layout.LayoutSkeleton.ActivateOptions"/> must be called again.
+ </para>
+ <para>
+ This method must be implemented by the subclass.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Layout.LayoutSkeleton.Format(System.IO.TextWriter,log4net.Core.LoggingEvent)">
+ <summary>
+ Implement this method to create your own layout format.
+ </summary>
+ <param name="writer">The TextWriter to write the formatted event to</param>
+ <param name="loggingEvent">The event to format</param>
+ <remarks>
+ <para>
+ This method is called by an appender to format
+ the <paramref name="loggingEvent"/> as text.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Layout.LayoutSkeleton.ContentType">
+ <summary>
+ The content type output by this layout.
+ </summary>
+ <value>The content type is <c>"text/plain"</c></value>
+ <remarks>
+ <para>
+ The content type output by this layout.
+ </para>
+ <para>
+ This base class uses the value <c>"text/plain"</c>.
+ To change this value a subclass must override this
+ property.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Layout.LayoutSkeleton.Header">
+ <summary>
+ The header for the layout format.
+ </summary>
+ <value>the layout header</value>
+ <remarks>
+ <para>
+ The Header text will be appended before any logging events
+ are formatted and appended.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Layout.LayoutSkeleton.Footer">
+ <summary>
+ The footer for the layout format.
+ </summary>
+ <value>the layout footer</value>
+ <remarks>
+ <para>
+ The Footer text will be appended after all the logging events
+ have been formatted and appended.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Layout.LayoutSkeleton.IgnoresException">
+ <summary>
+ Flag indicating if this layout handles exceptions
+ </summary>
+ <value><c>false</c> if this layout handles exceptions</value>
+ <remarks>
+ <para>
+ If this layout handles the exception object contained within
+ <see cref="T:log4net.Core.LoggingEvent"/>, then the layout should return
+ <c>false</c>. Otherwise, if the layout ignores the exception
+ object, then the layout should return <c>true</c>.
+ </para>
+ <para>
+ Set this value to override a this default setting. The default
+ value is <c>true</c>, this layout does not handle the exception.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Layout.ExceptionLayout.#ctor">
+ <summary>
+ Default constructor
+ </summary>
+ <remarks>
+ <para>
+ Constructs a ExceptionLayout
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Layout.ExceptionLayout.ActivateOptions">
+ <summary>
+ Activate component options
+ </summary>
+ <remarks>
+ <para>
+ Part of the <see cref="T:log4net.Core.IOptionHandler"/> component activation
+ framework.
+ </para>
+ <para>
+ This method does nothing as options become effective immediately.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Layout.ExceptionLayout.Format(System.IO.TextWriter,log4net.Core.LoggingEvent)">
+ <summary>
+ Gets the exception text from the logging event
+ </summary>
+ <param name="writer">The TextWriter to write the formatted event to</param>
+ <param name="loggingEvent">the event being logged</param>
+ <remarks>
+ <para>
+ Write the exception string to the <see cref="T:System.IO.TextWriter"/>.
+ The exception string is retrieved from <see cref="M:log4net.Core.LoggingEvent.GetExceptionString"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Layout.IRawLayout">
+ <summary>
+ Interface for raw layout objects
+ </summary>
+ <remarks>
+ <para>
+ Interface used to format a <see cref="T:log4net.Core.LoggingEvent"/>
+ to an object.
+ </para>
+ <para>
+ This interface should not be confused with the
+ <see cref="T:log4net.Layout.ILayout"/> interface. This interface is used in
+ only certain specialized situations where a raw object is
+ required rather than a formatted string. The <see cref="T:log4net.Layout.ILayout"/>
+ is not generally useful than this interface.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="M:log4net.Layout.IRawLayout.Format(log4net.Core.LoggingEvent)">
+ <summary>
+ Implement this method to create your own layout format.
+ </summary>
+ <param name="loggingEvent">The event to format</param>
+ <returns>returns the formatted event</returns>
+ <remarks>
+ <para>
+ Implement this method to create your own layout format.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Layout.Layout2RawLayoutAdapter">
+ <summary>
+ Adapts any <see cref="T:log4net.Layout.ILayout"/> to a <see cref="T:log4net.Layout.IRawLayout"/>
+ </summary>
+ <remarks>
+ <para>
+ Where an <see cref="T:log4net.Layout.IRawLayout"/> is required this adapter
+ allows a <see cref="T:log4net.Layout.ILayout"/> to be specified.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="F:log4net.Layout.Layout2RawLayoutAdapter.m_layout">
+ <summary>
+ The layout to adapt
+ </summary>
+ </member>
+ <member name="M:log4net.Layout.Layout2RawLayoutAdapter.#ctor(log4net.Layout.ILayout)">
+ <summary>
+ Construct a new adapter
+ </summary>
+ <param name="layout">the layout to adapt</param>
+ <remarks>
+ <para>
+ Create the adapter for the specified <paramref name="layout"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Layout.Layout2RawLayoutAdapter.Format(log4net.Core.LoggingEvent)">
+ <summary>
+ Format the logging event as an object.
+ </summary>
+ <param name="loggingEvent">The event to format</param>
+ <returns>returns the formatted event</returns>
+ <remarks>
+ <para>
+ Format the logging event as an object.
+ </para>
+ <para>
+ Uses the <see cref="T:log4net.Layout.ILayout"/> object supplied to
+ the constructor to perform the formatting.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Layout.PatternLayout">
+ <summary>
+ A flexible layout configurable with pattern string.
+ </summary>
+ <remarks>
+ <para>
+ The goal of this class is to <see cref="M:log4net.Layout.PatternLayout.Format(System.IO.TextWriter,log4net.Core.LoggingEvent)"/> a
+ <see cref="T:log4net.Core.LoggingEvent"/> as a string. The results
+ depend on the <i>conversion pattern</i>.
+ </para>
+ <para>
+ The conversion pattern is closely related to the conversion
+ pattern of the printf function in C. A conversion pattern is
+ composed of literal text and format control expressions called
+ <i>conversion specifiers</i>.
+ </para>
+ <para>
+ <i>You are free to insert any literal text within the conversion
+ pattern.</i>
+ </para>
+ <para>
+ Each conversion specifier starts with a percent sign (%) and is
+ followed by optional <i>format modifiers</i> and a <i>conversion
+ pattern name</i>. The conversion pattern name specifies the type of
+ data, e.g. logger, level, date, thread name. The format
+ modifiers control such things as field width, padding, left and
+ right justification. The following is a simple example.
+ </para>
+ <para>
+ Let the conversion pattern be <b>"%-5level [%thread]: %message%newline"</b> and assume
+ that the log4net environment was set to use a PatternLayout. Then the
+ statements
+ </para>
+ <code lang="C#">
+ ILog log = LogManager.GetLogger(typeof(TestApp));
+ log.Debug("Message 1");
+ log.Warn("Message 2");
+ </code>
+ <para>would yield the output</para>
+ <code>
+ DEBUG [main]: Message 1
+ WARN [main]: Message 2
+ </code>
+ <para>
+ Note that there is no explicit separator between text and
+ conversion specifiers. The pattern parser knows when it has reached
+ the end of a conversion specifier when it reads a conversion
+ character. In the example above the conversion specifier
+ <b>%-5level</b> means the level of the logging event should be left
+ justified to a width of five characters.
+ </para>
+ <para>
+ The recognized conversion pattern names are:
+ </para>
+ <list type="table">
+ <listheader>
+ <term>Conversion Pattern Name</term>
+ <description>Effect</description>
+ </listheader>
+ <item>
+ <term>a</term>
+ <description>Equivalent to <b>appdomain</b></description>
+ </item>
+ <item>
+ <term>appdomain</term>
+ <description>
+ Used to output the friendly name of the AppDomain where the
+ logging event was generated.
+ </description>
+ </item>
+ <item>
+ <term>c</term>
+ <description>Equivalent to <b>logger</b></description>
+ </item>
+ <item>
+ <term>C</term>
+ <description>Equivalent to <b>type</b></description>
+ </item>
+ <item>
+ <term>class</term>
+ <description>Equivalent to <b>type</b></description>
+ </item>
+ <item>
+ <term>d</term>
+ <description>Equivalent to <b>date</b></description>
+ </item>
+ <item>
+ <term>date</term>
+ <description>
+ <para>
+ Used to output the date of the logging event in the local time zone.
+ To output the date in universal time use the <c>%utcdate</c> pattern.
+ The date conversion
+ specifier may be followed by a <i>date format specifier</i> enclosed
+ between braces. For example, <b>%date{HH:mm:ss,fff}</b> or
+ <b>%date{dd MMM yyyy HH:mm:ss,fff}</b>. If no date format specifier is
+ given then ISO8601 format is
+ assumed (<see cref="T:log4net.DateFormatter.Iso8601DateFormatter"/>).
+ </para>
+ <para>
+ The date format specifier admits the same syntax as the
+ time pattern string of the <see cref="M:System.DateTime.ToString(System.String)"/>.
+ </para>
+ <para>
+ For better results it is recommended to use the log4net date
+ formatters. These can be specified using one of the strings
+ "ABSOLUTE", "DATE" and "ISO8601" for specifying
+ <see cref="T:log4net.DateFormatter.AbsoluteTimeDateFormatter"/>,
+ <see cref="T:log4net.DateFormatter.DateTimeDateFormatter"/> and respectively
+ <see cref="T:log4net.DateFormatter.Iso8601DateFormatter"/>. For example,
+ <b>%date{ISO8601}</b> or <b>%date{ABSOLUTE}</b>.
+ </para>
+ <para>
+ These dedicated date formatters perform significantly
+ better than <see cref="M:System.DateTime.ToString(System.String)"/>.
+ </para>
+ </description>
+ </item>
+ <item>
+ <term>exception</term>
+ <description>
+ <para>
+ Used to output the exception passed in with the log message.
+ </para>
+ <para>
+ If an exception object is stored in the logging event
+ it will be rendered into the pattern output with a
+ trailing newline.
+ If there is no exception then nothing will be output
+ and no trailing newline will be appended.
+ It is typical to put a newline before the exception
+ and to have the exception as the last data in the pattern.
+ </para>
+ </description>
+ </item>
+ <item>
+ <term>F</term>
+ <description>Equivalent to <b>file</b></description>
+ </item>
+ <item>
+ <term>file</term>
+ <description>
+ <para>
+ Used to output the file name where the logging request was
+ issued.
+ </para>
+ <para>
+ <b>WARNING</b> Generating caller location information is
+ extremely slow. Its use should be avoided unless execution speed
+ is not an issue.
+ </para>
+ <para>
+ See the note below on the availability of caller location information.
+ </para>
+ </description>
+ </item>
+ <item>
+ <term>identity</term>
+ <description>
+ <para>
+ Used to output the user name for the currently active user
+ (Principal.Identity.Name).
+ </para>
+ <para>
+ <b>WARNING</b> Generating caller information is
+ extremely slow. Its use should be avoided unless execution speed
+ is not an issue.
+ </para>
+ </description>
+ </item>
+ <item>
+ <term>l</term>
+ <description>Equivalent to <b>location</b></description>
+ </item>
+ <item>
+ <term>L</term>
+ <description>Equivalent to <b>line</b></description>
+ </item>
+ <item>
+ <term>location</term>
+ <description>
+ <para>
+ Used to output location information of the caller which generated
+ the logging event.
+ </para>
+ <para>
+ The location information depends on the CLI implementation but
+ usually consists of the fully qualified name of the calling
+ method followed by the callers source the file name and line
+ number between parentheses.
+ </para>
+ <para>
+ The location information can be very useful. However, its
+ generation is <b>extremely</b> slow. Its use should be avoided
+ unless execution speed is not an issue.
+ </para>
+ <para>
+ See the note below on the availability of caller location information.
+ </para>
+ </description>
+ </item>
+ <item>
+ <term>level</term>
+ <description>
+ <para>
+ Used to output the level of the logging event.
+ </para>
+ </description>
+ </item>
+ <item>
+ <term>line</term>
+ <description>
+ <para>
+ Used to output the line number from where the logging request
+ was issued.
+ </para>
+ <para>
+ <b>WARNING</b> Generating caller location information is
+ extremely slow. Its use should be avoided unless execution speed
+ is not an issue.
+ </para>
+ <para>
+ See the note below on the availability of caller location information.
+ </para>
+ </description>
+ </item>
+ <item>
+ <term>logger</term>
+ <description>
+ <para>
+ Used to output the logger of the logging event. The
+ logger conversion specifier can be optionally followed by
+ <i>precision specifier</i>, that is a decimal constant in
+ brackets.
+ </para>
+ <para>
+ If a precision specifier is given, then only the corresponding
+ number of right most components of the logger name will be
+ printed. By default the logger name is printed in full.
+ </para>
+ <para>
+ For example, for the logger name "a.b.c" the pattern
+ <b>%logger{2}</b> will output "b.c".
+ </para>
+ </description>
+ </item>
+ <item>
+ <term>m</term>
+ <description>Equivalent to <b>message</b></description>
+ </item>
+ <item>
+ <term>M</term>
+ <description>Equivalent to <b>method</b></description>
+ </item>
+ <item>
+ <term>message</term>
+ <description>
+ <para>
+ Used to output the application supplied message associated with
+ the logging event.
+ </para>
+ </description>
+ </item>
+ <item>
+ <term>mdc</term>
+ <description>
+ <para>
+ The MDC (old name for the ThreadContext.Properties) is now part of the
+ combined event properties. This pattern is supported for compatibility
+ but is equivalent to <b>property</b>.
+ </para>
+ </description>
+ </item>
+ <item>
+ <term>method</term>
+ <description>
+ <para>
+ Used to output the method name where the logging request was
+ issued.
+ </para>
+ <para>
+ <b>WARNING</b> Generating caller location information is
+ extremely slow. Its use should be avoided unless execution speed
+ is not an issue.
+ </para>
+ <para>
+ See the note below on the availability of caller location information.
+ </para>
+ </description>
+ </item>
+ <item>
+ <term>n</term>
+ <description>Equivalent to <b>newline</b></description>
+ </item>
+ <item>
+ <term>newline</term>
+ <description>
+ <para>
+ Outputs the platform dependent line separator character or
+ characters.
+ </para>
+ <para>
+ This conversion pattern offers the same performance as using
+ non-portable line separator strings such as "\n", or "\r\n".
+ Thus, it is the preferred way of specifying a line separator.
+ </para>
+ </description>
+ </item>
+ <item>
+ <term>ndc</term>
+ <description>
+ <para>
+ Used to output the NDC (nested diagnostic context) associated
+ with the thread that generated the logging event.
+ </para>
+ </description>
+ </item>
+ <item>
+ <term>p</term>
+ <description>Equivalent to <b>level</b></description>
+ </item>
+ <item>
+ <term>P</term>
+ <description>Equivalent to <b>property</b></description>
+ </item>
+ <item>
+ <term>properties</term>
+ <description>Equivalent to <b>property</b></description>
+ </item>
+ <item>
+ <term>property</term>
+ <description>
+ <para>
+ Used to output the an event specific property. The key to
+ lookup must be specified within braces and directly following the
+ pattern specifier, e.g. <b>%property{user}</b> would include the value
+ from the property that is keyed by the string 'user'. Each property value
+ that is to be included in the log must be specified separately.
+ Properties are added to events by loggers or appenders. By default
+ the <c>log4net:HostName</c> property is set to the name of machine on
+ which the event was originally logged.
+ </para>
+ <para>
+ If no key is specified, e.g. <b>%property</b> then all the keys and their
+ values are printed in a comma separated list.
+ </para>
+ <para>
+ The properties of an event are combined from a number of different
+ contexts. These are listed below in the order in which they are searched.
+ </para>
+ <list type="definition">
+ <item>
+ <term>the event properties</term>
+ <description>
+ The event has <see cref="P:log4net.Core.LoggingEvent.Properties"/> that can be set. These
+ properties are specific to this event only.
+ </description>
+ </item>
+ <item>
+ <term>the thread properties</term>
+ <description>
+ The <see cref="P:log4net.ThreadContext.Properties"/> that are set on the current
+ thread. These properties are shared by all events logged on this thread.
+ </description>
+ </item>
+ <item>
+ <term>the global properties</term>
+ <description>
+ The <see cref="P:log4net.GlobalContext.Properties"/> that are set globally. These
+ properties are shared by all the threads in the AppDomain.
+ </description>
+ </item>
+ </list>
+
+ </description>
+ </item>
+ <item>
+ <term>r</term>
+ <description>Equivalent to <b>timestamp</b></description>
+ </item>
+ <item>
+ <term>t</term>
+ <description>Equivalent to <b>thread</b></description>
+ </item>
+ <item>
+ <term>timestamp</term>
+ <description>
+ <para>
+ Used to output the number of milliseconds elapsed since the start
+ of the application until the creation of the logging event.
+ </para>
+ </description>
+ </item>
+ <item>
+ <term>thread</term>
+ <description>
+ <para>
+ Used to output the name of the thread that generated the
+ logging event. Uses the thread number if no name is available.
+ </para>
+ </description>
+ </item>
+ <item>
+ <term>type</term>
+ <description>
+ <para>
+ Used to output the fully qualified type name of the caller
+ issuing the logging request. This conversion specifier
+ can be optionally followed by <i>precision specifier</i>, that
+ is a decimal constant in brackets.
+ </para>
+ <para>
+ If a precision specifier is given, then only the corresponding
+ number of right most components of the class name will be
+ printed. By default the class name is output in fully qualified form.
+ </para>
+ <para>
+ For example, for the class name "log4net.Layout.PatternLayout", the
+ pattern <b>%type{1}</b> will output "PatternLayout".
+ </para>
+ <para>
+ <b>WARNING</b> Generating the caller class information is
+ slow. Thus, its use should be avoided unless execution speed is
+ not an issue.
+ </para>
+ <para>
+ See the note below on the availability of caller location information.
+ </para>
+ </description>
+ </item>
+ <item>
+ <term>u</term>
+ <description>Equivalent to <b>identity</b></description>
+ </item>
+ <item>
+ <term>username</term>
+ <description>
+ <para>
+ Used to output the WindowsIdentity for the currently
+ active user.
+ </para>
+ <para>
+ <b>WARNING</b> Generating caller WindowsIdentity information is
+ extremely slow. Its use should be avoided unless execution speed
+ is not an issue.
+ </para>
+ </description>
+ </item>
+ <item>
+ <term>utcdate</term>
+ <description>
+ <para>
+ Used to output the date of the logging event in universal time.
+ The date conversion
+ specifier may be followed by a <i>date format specifier</i> enclosed
+ between braces. For example, <b>%utcdate{HH:mm:ss,fff}</b> or
+ <b>%utcdate{dd MMM yyyy HH:mm:ss,fff}</b>. If no date format specifier is
+ given then ISO8601 format is
+ assumed (<see cref="T:log4net.DateFormatter.Iso8601DateFormatter"/>).
+ </para>
+ <para>
+ The date format specifier admits the same syntax as the
+ time pattern string of the <see cref="M:System.DateTime.ToString(System.String)"/>.
+ </para>
+ <para>
+ For better results it is recommended to use the log4net date
+ formatters. These can be specified using one of the strings
+ "ABSOLUTE", "DATE" and "ISO8601" for specifying
+ <see cref="T:log4net.DateFormatter.AbsoluteTimeDateFormatter"/>,
+ <see cref="T:log4net.DateFormatter.DateTimeDateFormatter"/> and respectively
+ <see cref="T:log4net.DateFormatter.Iso8601DateFormatter"/>. For example,
+ <b>%utcdate{ISO8601}</b> or <b>%utcdate{ABSOLUTE}</b>.
+ </para>
+ <para>
+ These dedicated date formatters perform significantly
+ better than <see cref="M:System.DateTime.ToString(System.String)"/>.
+ </para>
+ </description>
+ </item>
+ <item>
+ <term>w</term>
+ <description>Equivalent to <b>username</b></description>
+ </item>
+ <item>
+ <term>x</term>
+ <description>Equivalent to <b>ndc</b></description>
+ </item>
+ <item>
+ <term>X</term>
+ <description>Equivalent to <b>mdc</b></description>
+ </item>
+ <item>
+ <term>%</term>
+ <description>
+ <para>
+ The sequence %% outputs a single percent sign.
+ </para>
+ </description>
+ </item>
+ </list>
+ <para>
+ The single letter patterns are deprecated in favor of the
+ longer more descriptive pattern names.
+ </para>
+ <para>
+ By default the relevant information is output as is. However,
+ with the aid of format modifiers it is possible to change the
+ minimum field width, the maximum field width and justification.
+ </para>
+ <para>
+ The optional format modifier is placed between the percent sign
+ and the conversion pattern name.
+ </para>
+ <para>
+ The first optional format modifier is the <i>left justification
+ flag</i> which is just the minus (-) character. Then comes the
+ optional <i>minimum field width</i> modifier. This is a decimal
+ constant that represents the minimum number of characters to
+ output. If the data item requires fewer characters, it is padded on
+ either the left or the right until the minimum width is
+ reached. The default is to pad on the left (right justify) but you
+ can specify right padding with the left justification flag. The
+ padding character is space. If the data item is larger than the
+ minimum field width, the field is expanded to accommodate the
+ data. The value is never truncated.
+ </para>
+ <para>
+ This behavior can be changed using the <i>maximum field
+ width</i> modifier which is designated by a period followed by a
+ decimal constant. If the data item is longer than the maximum
+ field, then the extra characters are removed from the
+ <i>beginning</i> of the data item and not from the end. For
+ example, it the maximum field width is eight and the data item is
+ ten characters long, then the first two characters of the data item
+ are dropped. This behavior deviates from the printf function in C
+ where truncation is done from the end.
+ </para>
+ <para>
+ Below are various format modifier examples for the logger
+ conversion specifier.
+ </para>
+ <div class="tablediv">
+ <table class="dtTABLE" cellspacing="0">
+ <tr>
+ <th>Format modifier</th>
+ <th>left justify</th>
+ <th>minimum width</th>
+ <th>maximum width</th>
+ <th>comment</th>
+ </tr>
+ <tr>
+ <td align="center">%20logger</td>
+ <td align="center">false</td>
+ <td align="center">20</td>
+ <td align="center">none</td>
+ <td>
+ <para>
+ Left pad with spaces if the logger name is less than 20
+ characters long.
+ </para>
+ </td>
+ </tr>
+ <tr>
+ <td align="center">%-20logger</td>
+ <td align="center">true</td>
+ <td align="center">20</td>
+ <td align="center">none</td>
+ <td>
+ <para>
+ Right pad with spaces if the logger
+ name is less than 20 characters long.
+ </para>
+ </td>
+ </tr>
+ <tr>
+ <td align="center">%.30logger</td>
+ <td align="center">NA</td>
+ <td align="center">none</td>
+ <td align="center">30</td>
+ <td>
+ <para>
+ Truncate from the beginning if the logger
+ name is longer than 30 characters.
+ </para>
+ </td>
+ </tr>
+ <tr>
+ <td align="center"><nobr>%20.30logger</nobr></td>
+ <td align="center">false</td>
+ <td align="center">20</td>
+ <td align="center">30</td>
+ <td>
+ <para>
+ Left pad with spaces if the logger name is shorter than 20
+ characters. However, if logger name is longer than 30 characters,
+ then truncate from the beginning.
+ </para>
+ </td>
+ </tr>
+ <tr>
+ <td align="center">%-20.30logger</td>
+ <td align="center">true</td>
+ <td align="center">20</td>
+ <td align="center">30</td>
+ <td>
+ <para>
+ Right pad with spaces if the logger name is shorter than 20
+ characters. However, if logger name is longer than 30 characters,
+ then truncate from the beginning.
+ </para>
+ </td>
+ </tr>
+ </table>
+ </div>
+ <para>
+ <b>Note about caller location information.</b><br/>
+ The following patterns <c>%type %file %line %method %location %class %C %F %L %l %M</c>
+ all generate caller location information.
+ Location information uses the <c>System.Diagnostics.StackTrace</c> class to generate
+ a call stack. The caller's information is then extracted from this stack.
+ </para>
+ <note type="caution">
+ <para>
+ The <c>System.Diagnostics.StackTrace</c> class is not supported on the
+ .NET Compact Framework 1.0 therefore caller location information is not
+ available on that framework.
+ </para>
+ </note>
+ <note type="caution">
+ <para>
+ The <c>System.Diagnostics.StackTrace</c> class has this to say about Release builds:
+ </para>
+ <para>
+ "StackTrace information will be most informative with Debug build configurations.
+ By default, Debug builds include debug symbols, while Release builds do not. The
+ debug symbols contain most of the file, method name, line number, and column
+ information used in constructing StackFrame and StackTrace objects. StackTrace
+ might not report as many method calls as expected, due to code transformations
+ that occur during optimization."
+ </para>
+ <para>
+ This means that in a Release build the caller information may be incomplete or may
+ not exist at all! Therefore caller location information cannot be relied upon in a Release build.
+ </para>
+ </note>
+ <para>
+ Additional pattern converters may be registered with a specific <see cref="T:log4net.Layout.PatternLayout"/>
+ instance using the <see cref="M:log4net.Layout.PatternLayout.AddConverter(System.String,System.Type)"/> method.
+ </para>
+ </remarks>
+ <example>
+ This is a more detailed pattern.
+ <code><b>%timestamp [%thread] %level %logger %ndc - %message%newline</b></code>
+ </example>
+ <example>
+ A similar pattern except that the relative time is
+ right padded if less than 6 digits, thread name is right padded if
+ less than 15 characters and truncated if longer and the logger
+ name is left padded if shorter than 30 characters and truncated if
+ longer.
+ <code><b>%-6timestamp [%15.15thread] %-5level %30.30logger %ndc - %message%newline</b></code>
+ </example>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ <author>Douglas de la Torre</author>
+ <author>Daniel Cazzulino</author>
+ </member>
+ <member name="F:log4net.Layout.PatternLayout.DefaultConversionPattern">
+ <summary>
+ Default pattern string for log output.
+ </summary>
+ <remarks>
+ <para>
+ Default pattern string for log output.
+ Currently set to the string <b>"%message%newline"</b>
+ which just prints the application supplied message.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Layout.PatternLayout.DetailConversionPattern">
+ <summary>
+ A detailed conversion pattern
+ </summary>
+ <remarks>
+ <para>
+ A conversion pattern which includes Time, Thread, Logger, and Nested Context.
+ Current value is <b>%timestamp [%thread] %level %logger %ndc - %message%newline</b>.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Layout.PatternLayout.s_globalRulesRegistry">
+ <summary>
+ Internal map of converter identifiers to converter types.
+ </summary>
+ <remarks>
+ <para>
+ This static map is overridden by the m_converterRegistry instance map
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Layout.PatternLayout.m_pattern">
+ <summary>
+ the pattern
+ </summary>
+ </member>
+ <member name="F:log4net.Layout.PatternLayout.m_head">
+ <summary>
+ the head of the pattern converter chain
+ </summary>
+ </member>
+ <member name="F:log4net.Layout.PatternLayout.m_instanceRulesRegistry">
+ <summary>
+ patterns defined on this PatternLayout only
+ </summary>
+ </member>
+ <member name="M:log4net.Layout.PatternLayout.#cctor">
+ <summary>
+ Initialize the global registry
+ </summary>
+ <remarks>
+ <para>
+ Defines the builtin global rules.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Layout.PatternLayout.#ctor">
+ <summary>
+ Constructs a PatternLayout using the DefaultConversionPattern
+ </summary>
+ <remarks>
+ <para>
+ The default pattern just produces the application supplied message.
+ </para>
+ <para>
+ Note to Inheritors: This constructor calls the virtual method
+ <see cref="M:log4net.Layout.PatternLayout.CreatePatternParser(System.String)"/>. If you override this method be
+ aware that it will be called before your is called constructor.
+ </para>
+ <para>
+ As per the <see cref="T:log4net.Core.IOptionHandler"/> contract the <see cref="M:log4net.Layout.PatternLayout.ActivateOptions"/>
+ method must be called after the properties on this object have been
+ configured.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Layout.PatternLayout.#ctor(System.String)">
+ <summary>
+ Constructs a PatternLayout using the supplied conversion pattern
+ </summary>
+ <param name="pattern">the pattern to use</param>
+ <remarks>
+ <para>
+ Note to Inheritors: This constructor calls the virtual method
+ <see cref="M:log4net.Layout.PatternLayout.CreatePatternParser(System.String)"/>. If you override this method be
+ aware that it will be called before your is called constructor.
+ </para>
+ <para>
+ When using this constructor the <see cref="M:log4net.Layout.PatternLayout.ActivateOptions"/> method
+ need not be called. This may not be the case when using a subclass.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Layout.PatternLayout.CreatePatternParser(System.String)">
+ <summary>
+ Create the pattern parser instance
+ </summary>
+ <param name="pattern">the pattern to parse</param>
+ <returns>The <see cref="T:log4net.Util.PatternParser"/> that will format the event</returns>
+ <remarks>
+ <para>
+ Creates the <see cref="T:log4net.Util.PatternParser"/> used to parse the conversion string. Sets the
+ global and instance rules on the <see cref="T:log4net.Util.PatternParser"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Layout.PatternLayout.ActivateOptions">
+ <summary>
+ Initialize layout options
+ </summary>
+ <remarks>
+ <para>
+ This is part of the <see cref="T:log4net.Core.IOptionHandler"/> delayed object
+ activation scheme. The <see cref="M:log4net.Layout.PatternLayout.ActivateOptions"/> method must
+ be called on this object after the configuration properties have
+ been set. Until <see cref="M:log4net.Layout.PatternLayout.ActivateOptions"/> is called this
+ object is in an undefined state and must not be used.
+ </para>
+ <para>
+ If any of the configuration properties are modified then
+ <see cref="M:log4net.Layout.PatternLayout.ActivateOptions"/> must be called again.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Layout.PatternLayout.Format(System.IO.TextWriter,log4net.Core.LoggingEvent)">
+ <summary>
+ Produces a formatted string as specified by the conversion pattern.
+ </summary>
+ <param name="loggingEvent">the event being logged</param>
+ <param name="writer">The TextWriter to write the formatted event to</param>
+ <remarks>
+ <para>
+ Parse the <see cref="T:log4net.Core.LoggingEvent"/> using the patter format
+ specified in the <see cref="P:log4net.Layout.PatternLayout.ConversionPattern"/> property.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Layout.PatternLayout.AddConverter(log4net.Layout.PatternLayout.ConverterInfo)">
+ <summary>
+ Add a converter to this PatternLayout
+ </summary>
+ <param name="converterInfo">the converter info</param>
+ <remarks>
+ <para>
+ This version of the method is used by the configurator.
+ Programmatic users should use the alternative <see cref="M:log4net.Layout.PatternLayout.AddConverter(System.String,System.Type)"/> method.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Layout.PatternLayout.AddConverter(System.String,System.Type)">
+ <summary>
+ Add a converter to this PatternLayout
+ </summary>
+ <param name="name">the name of the conversion pattern for this converter</param>
+ <param name="type">the type of the converter</param>
+ <remarks>
+ <para>
+ Add a named pattern converter to this instance. This
+ converter will be used in the formatting of the event.
+ This method must be called before <see cref="M:log4net.Layout.PatternLayout.ActivateOptions"/>.
+ </para>
+ <para>
+ The <paramref name="type"/> specified must extend the
+ <see cref="T:log4net.Util.PatternConverter"/> type.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Layout.PatternLayout.ConversionPattern">
+ <summary>
+ The pattern formatting string
+ </summary>
+ <remarks>
+ <para>
+ The <b>ConversionPattern</b> option. This is the string which
+ controls formatting and consists of a mix of literal content and
+ conversion specifiers.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Layout.PatternLayout.ConverterInfo">
+ <summary>
+ Wrapper class used to map converter names to converter types
+ </summary>
+ <remarks>
+ <para>
+ Pattern converter info class used during configuration to
+ pass to the <see cref="M:log4net.Layout.PatternLayout.AddConverter(log4net.Layout.PatternLayout.ConverterInfo)"/>
+ method.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Layout.PatternLayout.ConverterInfo.#ctor">
+ <summary>
+ default constructor
+ </summary>
+ </member>
+ <member name="P:log4net.Layout.PatternLayout.ConverterInfo.Name">
+ <summary>
+ Gets or sets the name of the conversion pattern
+ </summary>
+ <remarks>
+ <para>
+ The name of the pattern in the format string
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Layout.PatternLayout.ConverterInfo.Type">
+ <summary>
+ Gets or sets the type of the converter
+ </summary>
+ <remarks>
+ <para>
+ The value specified must extend the
+ <see cref="T:log4net.Util.PatternConverter"/> type.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Layout.RawLayoutConverter">
+ <summary>
+ Type converter for the <see cref="T:log4net.Layout.IRawLayout"/> interface
+ </summary>
+ <remarks>
+ <para>
+ Used to convert objects to the <see cref="T:log4net.Layout.IRawLayout"/> interface.
+ Supports converting from the <see cref="T:log4net.Layout.ILayout"/> interface to
+ the <see cref="T:log4net.Layout.IRawLayout"/> interface using the <see cref="T:log4net.Layout.Layout2RawLayoutAdapter"/>.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="T:log4net.Util.TypeConverters.IConvertFrom">
+ <summary>
+ Interface supported by type converters
+ </summary>
+ <remarks>
+ <para>
+ This interface supports conversion from arbitrary types
+ to a single target type. See <see cref="T:log4net.Util.TypeConverters.TypeConverterAttribute"/>.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="M:log4net.Util.TypeConverters.IConvertFrom.CanConvertFrom(System.Type)">
+ <summary>
+ Can the source type be converted to the type supported by this object
+ </summary>
+ <param name="sourceType">the type to convert</param>
+ <returns>true if the conversion is possible</returns>
+ <remarks>
+ <para>
+ Test if the <paramref name="sourceType"/> can be converted to the
+ type supported by this converter.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.TypeConverters.IConvertFrom.ConvertFrom(System.Object)">
+ <summary>
+ Convert the source object to the type supported by this object
+ </summary>
+ <param name="source">the object to convert</param>
+ <returns>the converted object</returns>
+ <remarks>
+ <para>
+ Converts the <paramref name="source"/> to the type supported
+ by this converter.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Layout.RawLayoutConverter.CanConvertFrom(System.Type)">
+ <summary>
+ Can the sourceType be converted to an <see cref="T:log4net.Layout.IRawLayout"/>
+ </summary>
+ <param name="sourceType">the source to be to be converted</param>
+ <returns><c>true</c> if the source type can be converted to <see cref="T:log4net.Layout.IRawLayout"/></returns>
+ <remarks>
+ <para>
+ Test if the <paramref name="sourceType"/> can be converted to a
+ <see cref="T:log4net.Layout.IRawLayout"/>. Only <see cref="T:log4net.Layout.ILayout"/> is supported
+ as the <paramref name="sourceType"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Layout.RawLayoutConverter.ConvertFrom(System.Object)">
+ <summary>
+ Convert the value to a <see cref="T:log4net.Layout.IRawLayout"/> object
+ </summary>
+ <param name="source">the value to convert</param>
+ <returns>the <see cref="T:log4net.Layout.IRawLayout"/> object</returns>
+ <remarks>
+ <para>
+ Convert the <paramref name="source"/> object to a
+ <see cref="T:log4net.Layout.IRawLayout"/> object. If the <paramref name="source"/> object
+ is a <see cref="T:log4net.Layout.ILayout"/> then the <see cref="T:log4net.Layout.Layout2RawLayoutAdapter"/>
+ is used to adapt between the two interfaces, otherwise an
+ exception is thrown.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Layout.RawPropertyLayout">
+ <summary>
+ Extract the value of a property from the <see cref="T:log4net.Core.LoggingEvent"/>
+ </summary>
+ <remarks>
+ <para>
+ Extract the value of a property from the <see cref="T:log4net.Core.LoggingEvent"/>
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="M:log4net.Layout.RawPropertyLayout.#ctor">
+ <summary>
+ Constructs a RawPropertyLayout
+ </summary>
+ </member>
+ <member name="M:log4net.Layout.RawPropertyLayout.Format(log4net.Core.LoggingEvent)">
+ <summary>
+ Lookup the property for <see cref="P:log4net.Layout.RawPropertyLayout.Key"/>
+ </summary>
+ <param name="loggingEvent">The event to format</param>
+ <returns>returns property value</returns>
+ <remarks>
+ <para>
+ Looks up and returns the object value of the property
+ named <see cref="P:log4net.Layout.RawPropertyLayout.Key"/>. If there is no property defined
+ with than name then <c>null</c> will be returned.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Layout.RawPropertyLayout.Key">
+ <summary>
+ The name of the value to lookup in the LoggingEvent Properties collection.
+ </summary>
+ <value>
+ Value to lookup in the LoggingEvent Properties collection
+ </value>
+ <remarks>
+ <para>
+ String name of the property to lookup in the <see cref="T:log4net.Core.LoggingEvent"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Layout.RawTimeStampLayout">
+ <summary>
+ Extract the date from the <see cref="T:log4net.Core.LoggingEvent"/>
+ </summary>
+ <remarks>
+ <para>
+ Extract the date from the <see cref="T:log4net.Core.LoggingEvent"/>
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="M:log4net.Layout.RawTimeStampLayout.#ctor">
+ <summary>
+ Constructs a RawTimeStampLayout
+ </summary>
+ </member>
+ <member name="M:log4net.Layout.RawTimeStampLayout.Format(log4net.Core.LoggingEvent)">
+ <summary>
+ Gets the <see cref="P:log4net.Core.LoggingEvent.TimeStamp"/> as a <see cref="T:System.DateTime"/>.
+ </summary>
+ <param name="loggingEvent">The event to format</param>
+ <returns>returns the time stamp</returns>
+ <remarks>
+ <para>
+ Gets the <see cref="P:log4net.Core.LoggingEvent.TimeStamp"/> as a <see cref="T:System.DateTime"/>.
+ </para>
+ <para>
+ The time stamp is in local time. To format the time stamp
+ in universal time use <see cref="T:log4net.Layout.RawUtcTimeStampLayout"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Layout.RawUtcTimeStampLayout">
+ <summary>
+ Extract the date from the <see cref="T:log4net.Core.LoggingEvent"/>
+ </summary>
+ <remarks>
+ <para>
+ Extract the date from the <see cref="T:log4net.Core.LoggingEvent"/>
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="M:log4net.Layout.RawUtcTimeStampLayout.#ctor">
+ <summary>
+ Constructs a RawUtcTimeStampLayout
+ </summary>
+ </member>
+ <member name="M:log4net.Layout.RawUtcTimeStampLayout.Format(log4net.Core.LoggingEvent)">
+ <summary>
+ Gets the <see cref="P:log4net.Core.LoggingEvent.TimeStamp"/> as a <see cref="T:System.DateTime"/>.
+ </summary>
+ <param name="loggingEvent">The event to format</param>
+ <returns>returns the time stamp</returns>
+ <remarks>
+ <para>
+ Gets the <see cref="P:log4net.Core.LoggingEvent.TimeStamp"/> as a <see cref="T:System.DateTime"/>.
+ </para>
+ <para>
+ The time stamp is in universal time. To format the time stamp
+ in local time use <see cref="T:log4net.Layout.RawTimeStampLayout"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Layout.SimpleLayout">
+ <summary>
+ A very simple layout
+ </summary>
+ <remarks>
+ <para>
+ SimpleLayout consists of the level of the log statement,
+ followed by " - " and then the log message itself. For example,
+ <code>
+ DEBUG - Hello world
+ </code>
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="M:log4net.Layout.SimpleLayout.#ctor">
+ <summary>
+ Constructs a SimpleLayout
+ </summary>
+ </member>
+ <member name="M:log4net.Layout.SimpleLayout.ActivateOptions">
+ <summary>
+ Initialize layout options
+ </summary>
+ <remarks>
+ <para>
+ This is part of the <see cref="T:log4net.Core.IOptionHandler"/> delayed object
+ activation scheme. The <see cref="M:log4net.Layout.SimpleLayout.ActivateOptions"/> method must
+ be called on this object after the configuration properties have
+ been set. Until <see cref="M:log4net.Layout.SimpleLayout.ActivateOptions"/> is called this
+ object is in an undefined state and must not be used.
+ </para>
+ <para>
+ If any of the configuration properties are modified then
+ <see cref="M:log4net.Layout.SimpleLayout.ActivateOptions"/> must be called again.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Layout.SimpleLayout.Format(System.IO.TextWriter,log4net.Core.LoggingEvent)">
+ <summary>
+ Produces a simple formatted output.
+ </summary>
+ <param name="loggingEvent">the event being logged</param>
+ <param name="writer">The TextWriter to write the formatted event to</param>
+ <remarks>
+ <para>
+ Formats the event as the level of the even,
+ followed by " - " and then the log message itself. The
+ output is terminated by a newline.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Layout.XmlLayout">
+ <summary>
+ Layout that formats the log events as XML elements.
+ </summary>
+ <remarks>
+ <para>
+ The output of the <see cref="T:log4net.Layout.XmlLayout"/> consists of a series of
+ log4net:event elements. It does not output a complete well-formed XML
+ file. The output is designed to be included as an <em>external entity</em>
+ in a separate file to form a correct XML file.
+ </para>
+ <para>
+ For example, if <c>abc</c> is the name of the file where
+ the <see cref="T:log4net.Layout.XmlLayout"/> output goes, then a well-formed XML file would
+ be:
+ </para>
+ <code lang="XML">
+ &lt;?xml version="1.0" ?&gt;
+
+ &lt;!DOCTYPE log4net:events SYSTEM "log4net-events.dtd" [&lt;!ENTITY data SYSTEM "abc"&gt;]&gt;
+
+ &lt;log4net:events version="1.2" xmlns:log4net="http://logging.apache.org/log4net/schemas/log4net-events-1.2&gt;
+ &amp;data;
+ &lt;/log4net:events&gt;
+ </code>
+ <para>
+ This approach enforces the independence of the <see cref="T:log4net.Layout.XmlLayout"/>
+ and the appender where it is embedded.
+ </para>
+ <para>
+ The <c>version</c> attribute helps components to correctly
+ interpret output generated by <see cref="T:log4net.Layout.XmlLayout"/>. The value of
+ this attribute should be "1.2" for release 1.2 and later.
+ </para>
+ <para>
+ Alternatively the <c>Header</c> and <c>Footer</c> properties can be
+ configured to output the correct XML header, open tag and close tag.
+ When setting the <c>Header</c> and <c>Footer</c> properties it is essential
+ that the underlying data store not be appendable otherwise the data
+ will become invalid XML.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="T:log4net.Layout.XmlLayoutBase">
+ <summary>
+ Layout that formats the log events as XML elements.
+ </summary>
+ <remarks>
+ <para>
+ This is an abstract class that must be subclassed by an implementation
+ to conform to a specific schema.
+ </para>
+ <para>
+ Deriving classes must implement the <see cref="M:log4net.Layout.XmlLayoutBase.FormatXml(System.Xml.XmlWriter,log4net.Core.LoggingEvent)"/> method.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="M:log4net.Layout.XmlLayoutBase.#ctor">
+ <summary>
+ Protected constructor to support subclasses
+ </summary>
+ <remarks>
+ <para>
+ Initializes a new instance of the <see cref="T:log4net.Layout.XmlLayoutBase"/> class
+ with no location info.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Layout.XmlLayoutBase.#ctor(System.Boolean)">
+ <summary>
+ Protected constructor to support subclasses
+ </summary>
+ <remarks>
+ <para>
+ The <paramref name="locationInfo" /> parameter determines whether
+ location information will be output by the layout. If
+ <paramref name="locationInfo" /> is set to <c>true</c>, then the
+ file name and line number of the statement at the origin of the log
+ statement will be output.
+ </para>
+ <para>
+ If you are embedding this layout within an SMTPAppender
+ then make sure to set the <b>LocationInfo</b> option of that
+ appender as well.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Layout.XmlLayoutBase.ActivateOptions">
+ <summary>
+ Initialize layout options
+ </summary>
+ <remarks>
+ <para>
+ This is part of the <see cref="T:log4net.Core.IOptionHandler"/> delayed object
+ activation scheme. The <see cref="M:log4net.Layout.XmlLayoutBase.ActivateOptions"/> method must
+ be called on this object after the configuration properties have
+ been set. Until <see cref="M:log4net.Layout.XmlLayoutBase.ActivateOptions"/> is called this
+ object is in an undefined state and must not be used.
+ </para>
+ <para>
+ If any of the configuration properties are modified then
+ <see cref="M:log4net.Layout.XmlLayoutBase.ActivateOptions"/> must be called again.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Layout.XmlLayoutBase.Format(System.IO.TextWriter,log4net.Core.LoggingEvent)">
+ <summary>
+ Produces a formatted string.
+ </summary>
+ <param name="loggingEvent">The event being logged.</param>
+ <param name="writer">The TextWriter to write the formatted event to</param>
+ <remarks>
+ <para>
+ Format the <see cref="T:log4net.Core.LoggingEvent"/> and write it to the <see cref="T:System.IO.TextWriter"/>.
+ </para>
+ <para>
+ This method creates an <see cref="T:System.Xml.XmlTextWriter"/> that writes to the
+ <paramref name="writer"/>. The <see cref="T:System.Xml.XmlTextWriter"/> is passed
+ to the <see cref="M:log4net.Layout.XmlLayoutBase.FormatXml(System.Xml.XmlWriter,log4net.Core.LoggingEvent)"/> method. Subclasses should override the
+ <see cref="M:log4net.Layout.XmlLayoutBase.FormatXml(System.Xml.XmlWriter,log4net.Core.LoggingEvent)"/> method rather than this method.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Layout.XmlLayoutBase.FormatXml(System.Xml.XmlWriter,log4net.Core.LoggingEvent)">
+ <summary>
+ Does the actual writing of the XML.
+ </summary>
+ <param name="writer">The writer to use to output the event to.</param>
+ <param name="loggingEvent">The event to write.</param>
+ <remarks>
+ <para>
+ Subclasses should override this method to format
+ the <see cref="T:log4net.Core.LoggingEvent"/> as XML.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Layout.XmlLayoutBase.m_locationInfo">
+ <summary>
+ Flag to indicate if location information should be included in
+ the XML events.
+ </summary>
+ </member>
+ <member name="F:log4net.Layout.XmlLayoutBase.m_protectCloseTextWriter">
+ <summary>
+ Writer adapter that ignores Close
+ </summary>
+ </member>
+ <member name="F:log4net.Layout.XmlLayoutBase.m_invalidCharReplacement">
+ <summary>
+ The string to replace invalid chars with
+ </summary>
+ </member>
+ <member name="P:log4net.Layout.XmlLayoutBase.LocationInfo">
+ <summary>
+ Gets a value indicating whether to include location information in
+ the XML events.
+ </summary>
+ <value>
+ <c>true</c> if location information should be included in the XML
+ events; otherwise, <c>false</c>.
+ </value>
+ <remarks>
+ <para>
+ If <see cref="P:log4net.Layout.XmlLayoutBase.LocationInfo"/> is set to <c>true</c>, then the file
+ name and line number of the statement at the origin of the log
+ statement will be output.
+ </para>
+ <para>
+ If you are embedding this layout within an <c>SMTPAppender</c>
+ then make sure to set the <b>LocationInfo</b> option of that
+ appender as well.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Layout.XmlLayoutBase.InvalidCharReplacement">
+ <summary>
+ The string to replace characters that can not be expressed in XML with.
+ <remarks>
+ <para>
+ Not all characters may be expressed in XML. This property contains the
+ string to replace those that can not with. This defaults to a ?. Set it
+ to the empty string to simply remove offending characters. For more
+ details on the allowed character ranges see http://www.w3.org/TR/REC-xml/#charsets
+ Character replacement will occur in the log message, the property names
+ and the property values.
+ </para>
+ </remarks>
+ </summary>
+ </member>
+ <member name="P:log4net.Layout.XmlLayoutBase.ContentType">
+ <summary>
+ Gets the content type output by this layout.
+ </summary>
+ <value>
+ As this is the XML layout, the value is always <c>"text/xml"</c>.
+ </value>
+ <remarks>
+ <para>
+ As this is the XML layout, the value is always <c>"text/xml"</c>.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Layout.XmlLayout.#ctor">
+ <summary>
+ Constructs an XmlLayout
+ </summary>
+ </member>
+ <member name="M:log4net.Layout.XmlLayout.#ctor(System.Boolean)">
+ <summary>
+ Constructs an XmlLayout.
+ </summary>
+ <remarks>
+ <para>
+ The <b>LocationInfo</b> option takes a boolean value. By
+ default, it is set to false which means there will be no location
+ information output by this layout. If the the option is set to
+ true, then the file name and line number of the statement
+ at the origin of the log statement will be output.
+ </para>
+ <para>
+ If you are embedding this layout within an SmtpAppender
+ then make sure to set the <b>LocationInfo</b> option of that
+ appender as well.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Layout.XmlLayout.ActivateOptions">
+ <summary>
+ Initialize layout options
+ </summary>
+ <remarks>
+ <para>
+ This is part of the <see cref="T:log4net.Core.IOptionHandler"/> delayed object
+ activation scheme. The <see cref="M:log4net.Layout.XmlLayout.ActivateOptions"/> method must
+ be called on this object after the configuration properties have
+ been set. Until <see cref="M:log4net.Layout.XmlLayout.ActivateOptions"/> is called this
+ object is in an undefined state and must not be used.
+ </para>
+ <para>
+ If any of the configuration properties are modified then
+ <see cref="M:log4net.Layout.XmlLayout.ActivateOptions"/> must be called again.
+ </para>
+ <para>
+ Builds a cache of the element names
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Layout.XmlLayout.FormatXml(System.Xml.XmlWriter,log4net.Core.LoggingEvent)">
+ <summary>
+ Does the actual writing of the XML.
+ </summary>
+ <param name="writer">The writer to use to output the event to.</param>
+ <param name="loggingEvent">The event to write.</param>
+ <remarks>
+ <para>
+ Override the base class <see cref="M:log4net.Layout.XmlLayoutBase.FormatXml(System.Xml.XmlWriter,log4net.Core.LoggingEvent)"/> method
+ to write the <see cref="T:log4net.Core.LoggingEvent"/> to the <see cref="T:System.Xml.XmlWriter"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Layout.XmlLayout.m_prefix">
+ <summary>
+ The prefix to use for all generated element names
+ </summary>
+ </member>
+ <member name="P:log4net.Layout.XmlLayout.Prefix">
+ <summary>
+ The prefix to use for all element names
+ </summary>
+ <remarks>
+ <para>
+ The default prefix is <b>log4net</b>. Set this property
+ to change the prefix. If the prefix is set to an empty string
+ then no prefix will be written.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Layout.XmlLayout.Base64EncodeMessage">
+ <summary>
+ Set whether or not to base64 encode the message.
+ </summary>
+ <remarks>
+ <para>
+ By default the log message will be written as text to the xml
+ output. This can cause problems when the message contains binary
+ data. By setting this to true the contents of the message will be
+ base64 encoded. If this is set then invalid character replacement
+ (see <see cref="P:log4net.Layout.XmlLayoutBase.InvalidCharReplacement"/>) will not be performed
+ on the log message.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Layout.XmlLayout.Base64EncodeProperties">
+ <summary>
+ Set whether or not to base64 encode the property values.
+ </summary>
+ <remarks>
+ <para>
+ By default the properties will be written as text to the xml
+ output. This can cause problems when one or more properties contain
+ binary data. By setting this to true the values of the properties
+ will be base64 encoded. If this is set then invalid character replacement
+ (see <see cref="P:log4net.Layout.XmlLayoutBase.InvalidCharReplacement"/>) will not be performed
+ on the property values.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Layout.XmlLayoutSchemaLog4j">
+ <summary>
+ Layout that formats the log events as XML elements compatible with the log4j schema
+ </summary>
+ <remarks>
+ <para>
+ Formats the log events according to the http://logging.apache.org/log4j schema.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="F:log4net.Layout.XmlLayoutSchemaLog4j.s_date1970">
+ <summary>
+ The 1st of January 1970 in UTC
+ </summary>
+ </member>
+ <member name="M:log4net.Layout.XmlLayoutSchemaLog4j.#ctor">
+ <summary>
+ Constructs an XMLLayoutSchemaLog4j
+ </summary>
+ </member>
+ <member name="M:log4net.Layout.XmlLayoutSchemaLog4j.#ctor(System.Boolean)">
+ <summary>
+ Constructs an XMLLayoutSchemaLog4j.
+ </summary>
+ <remarks>
+ <para>
+ The <b>LocationInfo</b> option takes a boolean value. By
+ default, it is set to false which means there will be no location
+ information output by this layout. If the the option is set to
+ true, then the file name and line number of the statement
+ at the origin of the log statement will be output.
+ </para>
+ <para>
+ If you are embedding this layout within an SMTPAppender
+ then make sure to set the <b>LocationInfo</b> option of that
+ appender as well.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Layout.XmlLayoutSchemaLog4j.FormatXml(System.Xml.XmlWriter,log4net.Core.LoggingEvent)">
+ <summary>
+ Actually do the writing of the xml
+ </summary>
+ <param name="writer">the writer to use</param>
+ <param name="loggingEvent">the event to write</param>
+ <remarks>
+ <para>
+ Generate XML that is compatible with the log4j schema.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Layout.XmlLayoutSchemaLog4j.Version">
+ <summary>
+ The version of the log4j schema to use.
+ </summary>
+ <remarks>
+ <para>
+ Only version 1.2 of the log4j schema is supported.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.ObjectRenderer.DefaultRenderer">
+ <summary>
+ The default object Renderer.
+ </summary>
+ <remarks>
+ <para>
+ The default renderer supports rendering objects and collections to strings.
+ </para>
+ <para>
+ See the <see cref="M:log4net.ObjectRenderer.DefaultRenderer.RenderObject(log4net.ObjectRenderer.RendererMap,System.Object,System.IO.TextWriter)"/> method for details of the output.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="T:log4net.ObjectRenderer.IObjectRenderer">
+ <summary>
+ Implement this interface in order to render objects as strings
+ </summary>
+ <remarks>
+ <para>
+ Certain types require special case conversion to
+ string form. This conversion is done by an object renderer.
+ Object renderers implement the <see cref="T:log4net.ObjectRenderer.IObjectRenderer"/>
+ interface.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="M:log4net.ObjectRenderer.IObjectRenderer.RenderObject(log4net.ObjectRenderer.RendererMap,System.Object,System.IO.TextWriter)">
+ <summary>
+ Render the object <paramref name="obj"/> to a string
+ </summary>
+ <param name="rendererMap">The map used to lookup renderers</param>
+ <param name="obj">The object to render</param>
+ <param name="writer">The writer to render to</param>
+ <remarks>
+ <para>
+ Render the object <paramref name="obj"/> to a
+ string.
+ </para>
+ <para>
+ The <paramref name="rendererMap"/> parameter is
+ provided to lookup and render other objects. This is
+ very useful where <paramref name="obj"/> contains
+ nested objects of unknown type. The <see cref="M:log4net.ObjectRenderer.RendererMap.FindAndRender(System.Object,System.IO.TextWriter)"/>
+ method can be used to render these objects.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.ObjectRenderer.DefaultRenderer.#ctor">
+ <summary>
+ Default constructor
+ </summary>
+ <remarks>
+ <para>
+ Default constructor
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.ObjectRenderer.DefaultRenderer.RenderObject(log4net.ObjectRenderer.RendererMap,System.Object,System.IO.TextWriter)">
+ <summary>
+ Render the object <paramref name="obj"/> to a string
+ </summary>
+ <param name="rendererMap">The map used to lookup renderers</param>
+ <param name="obj">The object to render</param>
+ <param name="writer">The writer to render to</param>
+ <remarks>
+ <para>
+ Render the object <paramref name="obj"/> to a string.
+ </para>
+ <para>
+ The <paramref name="rendererMap"/> parameter is
+ provided to lookup and render other objects. This is
+ very useful where <paramref name="obj"/> contains
+ nested objects of unknown type. The <see cref="M:log4net.ObjectRenderer.RendererMap.FindAndRender(System.Object)"/>
+ method can be used to render these objects.
+ </para>
+ <para>
+ The default renderer supports rendering objects to strings as follows:
+ </para>
+ <list type="table">
+ <listheader>
+ <term>Value</term>
+ <description>Rendered String</description>
+ </listheader>
+ <item>
+ <term><c>null</c></term>
+ <description>
+ <para>"(null)"</para>
+ </description>
+ </item>
+ <item>
+ <term><see cref="T:System.Array"/></term>
+ <description>
+ <para>
+ For a one dimensional array this is the
+ array type name, an open brace, followed by a comma
+ separated list of the elements (using the appropriate
+ renderer), followed by a close brace.
+ </para>
+ <para>
+ For example: <c>int[] {1, 2, 3}</c>.
+ </para>
+ <para>
+ If the array is not one dimensional the
+ <c>Array.ToString()</c> is returned.
+ </para>
+ </description>
+ </item>
+ <item>
+ <term><see cref="T:System.Collections.IEnumerable"/>, <see cref="T:System.Collections.ICollection"/> &amp; <see cref="T:System.Collections.IEnumerator"/></term>
+ <description>
+ <para>
+ Rendered as an open brace, followed by a comma
+ separated list of the elements (using the appropriate
+ renderer), followed by a close brace.
+ </para>
+ <para>
+ For example: <c>{a, b, c}</c>.
+ </para>
+ <para>
+ All collection classes that implement <see cref="T:System.Collections.ICollection"/> its subclasses,
+ or generic equivalents all implement the <see cref="T:System.Collections.IEnumerable"/> interface.
+ </para>
+ </description>
+ </item>
+ <item>
+ <term><see cref="T:System.Collections.DictionaryEntry"/></term>
+ <description>
+ <para>
+ Rendered as the key, an equals sign ('='), and the value (using the appropriate
+ renderer).
+ </para>
+ <para>
+ For example: <c>key=value</c>.
+ </para>
+ </description>
+ </item>
+ <item>
+ <term>other</term>
+ <description>
+ <para><c>Object.ToString()</c></para>
+ </description>
+ </item>
+ </list>
+ </remarks>
+ </member>
+ <member name="M:log4net.ObjectRenderer.DefaultRenderer.RenderArray(log4net.ObjectRenderer.RendererMap,System.Array,System.IO.TextWriter)">
+ <summary>
+ Render the array argument into a string
+ </summary>
+ <param name="rendererMap">The map used to lookup renderers</param>
+ <param name="array">the array to render</param>
+ <param name="writer">The writer to render to</param>
+ <remarks>
+ <para>
+ For a one dimensional array this is the
+ array type name, an open brace, followed by a comma
+ separated list of the elements (using the appropriate
+ renderer), followed by a close brace. For example:
+ <c>int[] {1, 2, 3}</c>.
+ </para>
+ <para>
+ If the array is not one dimensional the
+ <c>Array.ToString()</c> is returned.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.ObjectRenderer.DefaultRenderer.RenderEnumerator(log4net.ObjectRenderer.RendererMap,System.Collections.IEnumerator,System.IO.TextWriter)">
+ <summary>
+ Render the enumerator argument into a string
+ </summary>
+ <param name="rendererMap">The map used to lookup renderers</param>
+ <param name="enumerator">the enumerator to render</param>
+ <param name="writer">The writer to render to</param>
+ <remarks>
+ <para>
+ Rendered as an open brace, followed by a comma
+ separated list of the elements (using the appropriate
+ renderer), followed by a close brace. For example:
+ <c>{a, b, c}</c>.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.ObjectRenderer.DefaultRenderer.RenderDictionaryEntry(log4net.ObjectRenderer.RendererMap,System.Collections.DictionaryEntry,System.IO.TextWriter)">
+ <summary>
+ Render the DictionaryEntry argument into a string
+ </summary>
+ <param name="rendererMap">The map used to lookup renderers</param>
+ <param name="entry">the DictionaryEntry to render</param>
+ <param name="writer">The writer to render to</param>
+ <remarks>
+ <para>
+ Render the key, an equals sign ('='), and the value (using the appropriate
+ renderer). For example: <c>key=value</c>.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.ObjectRenderer.RendererMap">
+ <summary>
+ Map class objects to an <see cref="T:log4net.ObjectRenderer.IObjectRenderer"/>.
+ </summary>
+ <remarks>
+ <para>
+ Maintains a mapping between types that require special
+ rendering and the <see cref="T:log4net.ObjectRenderer.IObjectRenderer"/> that
+ is used to render them.
+ </para>
+ <para>
+ The <see cref="M:log4net.ObjectRenderer.RendererMap.FindAndRender(System.Object)"/> method is used to render an
+ <c>object</c> using the appropriate renderers defined in this map.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="M:log4net.ObjectRenderer.RendererMap.#ctor">
+ <summary>
+ Default Constructor
+ </summary>
+ <remarks>
+ <para>
+ Default constructor.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.ObjectRenderer.RendererMap.FindAndRender(System.Object)">
+ <summary>
+ Render <paramref name="obj"/> using the appropriate renderer.
+ </summary>
+ <param name="obj">the object to render to a string</param>
+ <returns>the object rendered as a string</returns>
+ <remarks>
+ <para>
+ This is a convenience method used to render an object to a string.
+ The alternative method <see cref="M:log4net.ObjectRenderer.RendererMap.FindAndRender(System.Object,System.IO.TextWriter)"/>
+ should be used when streaming output to a <see cref="T:System.IO.TextWriter"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.ObjectRenderer.RendererMap.FindAndRender(System.Object,System.IO.TextWriter)">
+ <summary>
+ Render <paramref name="obj"/> using the appropriate renderer.
+ </summary>
+ <param name="obj">the object to render to a string</param>
+ <param name="writer">The writer to render to</param>
+ <remarks>
+ <para>
+ Find the appropriate renderer for the type of the
+ <paramref name="obj"/> parameter. This is accomplished by calling the
+ <see cref="M:log4net.ObjectRenderer.RendererMap.Get(System.Type)"/> method. Once a renderer is found, it is
+ applied on the object <paramref name="obj"/> and the result is returned
+ as a <see cref="T:System.String"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.ObjectRenderer.RendererMap.Get(System.Object)">
+ <summary>
+ Gets the renderer for the specified object type
+ </summary>
+ <param name="obj">the object to lookup the renderer for</param>
+ <returns>the renderer for <paramref name="obj"/></returns>
+ <remarks>
+ <param>
+ Gets the renderer for the specified object type.
+ </param>
+ <param>
+ Syntactic sugar method that calls <see cref="M:log4net.ObjectRenderer.RendererMap.Get(System.Type)"/>
+ with the type of the object parameter.
+ </param>
+ </remarks>
+ </member>
+ <member name="M:log4net.ObjectRenderer.RendererMap.Get(System.Type)">
+ <summary>
+ Gets the renderer for the specified type
+ </summary>
+ <param name="type">the type to lookup the renderer for</param>
+ <returns>the renderer for the specified type</returns>
+ <remarks>
+ <para>
+ Returns the renderer for the specified type.
+ If no specific renderer has been defined the
+ <see cref="P:log4net.ObjectRenderer.RendererMap.DefaultRenderer"/> will be returned.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.ObjectRenderer.RendererMap.SearchTypeAndInterfaces(System.Type)">
+ <summary>
+ Internal function to recursively search interfaces
+ </summary>
+ <param name="type">the type to lookup the renderer for</param>
+ <returns>the renderer for the specified type</returns>
+ </member>
+ <member name="M:log4net.ObjectRenderer.RendererMap.Clear">
+ <summary>
+ Clear the map of renderers
+ </summary>
+ <remarks>
+ <para>
+ Clear the custom renderers defined by using
+ <see cref="M:log4net.ObjectRenderer.RendererMap.Put(System.Type,log4net.ObjectRenderer.IObjectRenderer)"/>. The <see cref="P:log4net.ObjectRenderer.RendererMap.DefaultRenderer"/>
+ cannot be removed.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.ObjectRenderer.RendererMap.Put(System.Type,log4net.ObjectRenderer.IObjectRenderer)">
+ <summary>
+ Register an <see cref="T:log4net.ObjectRenderer.IObjectRenderer"/> for <paramref name="typeToRender"/>.
+ </summary>
+ <param name="typeToRender">the type that will be rendered by <paramref name="renderer"/></param>
+ <param name="renderer">the renderer for <paramref name="typeToRender"/></param>
+ <remarks>
+ <para>
+ Register an object renderer for a specific source type.
+ This renderer will be returned from a call to <see cref="M:log4net.ObjectRenderer.RendererMap.Get(System.Type)"/>
+ specifying the same <paramref name="typeToRender"/> as an argument.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.ObjectRenderer.RendererMap.DefaultRenderer">
+ <summary>
+ Get the default renderer instance
+ </summary>
+ <value>the default renderer</value>
+ <remarks>
+ <para>
+ Get the default renderer
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Plugin.IPlugin">
+ <summary>
+ Interface implemented by logger repository plugins.
+ </summary>
+ <remarks>
+ <para>
+ Plugins define additional behavior that can be associated
+ with a <see cref="T:log4net.Repository.ILoggerRepository"/>.
+ The <see cref="T:log4net.Plugin.PluginMap"/> held by the <see cref="P:log4net.Repository.ILoggerRepository.PluginMap"/>
+ property is used to store the plugins for a repository.
+ </para>
+ <para>
+ The <c>log4net.Config.PluginAttribute</c> can be used to
+ attach plugins to repositories created using configuration
+ attributes.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="M:log4net.Plugin.IPlugin.Attach(log4net.Repository.ILoggerRepository)">
+ <summary>
+ Attaches the plugin to the specified <see cref="T:log4net.Repository.ILoggerRepository"/>.
+ </summary>
+ <param name="repository">The <see cref="T:log4net.Repository.ILoggerRepository"/> that this plugin should be attached to.</param>
+ <remarks>
+ <para>
+ A plugin may only be attached to a single repository.
+ </para>
+ <para>
+ This method is called when the plugin is attached to the repository.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Plugin.IPlugin.Shutdown">
+ <summary>
+ Is called when the plugin is to shutdown.
+ </summary>
+ <remarks>
+ <para>
+ This method is called to notify the plugin that
+ it should stop operating and should detach from
+ the repository.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Plugin.IPlugin.Name">
+ <summary>
+ Gets the name of the plugin.
+ </summary>
+ <value>
+ The name of the plugin.
+ </value>
+ <remarks>
+ <para>
+ Plugins are stored in the <see cref="T:log4net.Plugin.PluginMap"/>
+ keyed by name. Each plugin instance attached to a
+ repository must be a unique name.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Plugin.PluginCollection">
+ <summary>
+ A strongly-typed collection of <see cref="T:log4net.Plugin.IPlugin"/> objects.
+ </summary>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="M:log4net.Plugin.PluginCollection.ReadOnly(log4net.Plugin.PluginCollection)">
+ <summary>
+ Creates a read-only wrapper for a <c>PluginCollection</c> instance.
+ </summary>
+ <param name="list">list to create a readonly wrapper arround</param>
+ <returns>
+ A <c>PluginCollection</c> wrapper that is read-only.
+ </returns>
+ </member>
+ <member name="M:log4net.Plugin.PluginCollection.#ctor">
+ <summary>
+ Initializes a new instance of the <c>PluginCollection</c> class
+ that is empty and has the default initial capacity.
+ </summary>
+ </member>
+ <member name="M:log4net.Plugin.PluginCollection.#ctor(System.Int32)">
+ <summary>
+ Initializes a new instance of the <c>PluginCollection</c> class
+ that has the specified initial capacity.
+ </summary>
+ <param name="capacity">
+ The number of elements that the new <c>PluginCollection</c> is initially capable of storing.
+ </param>
+ </member>
+ <member name="M:log4net.Plugin.PluginCollection.#ctor(log4net.Plugin.PluginCollection)">
+ <summary>
+ Initializes a new instance of the <c>PluginCollection</c> class
+ that contains elements copied from the specified <c>PluginCollection</c>.
+ </summary>
+ <param name="c">The <c>PluginCollection</c> whose elements are copied to the new collection.</param>
+ </member>
+ <member name="M:log4net.Plugin.PluginCollection.#ctor(log4net.Plugin.IPlugin[])">
+ <summary>
+ Initializes a new instance of the <c>PluginCollection</c> class
+ that contains elements copied from the specified <see cref="T:log4net.Plugin.IPlugin"/> array.
+ </summary>
+ <param name="a">The <see cref="T:log4net.Plugin.IPlugin"/> array whose elements are copied to the new list.</param>
+ </member>
+ <member name="M:log4net.Plugin.PluginCollection.#ctor(System.Collections.ICollection)">
+ <summary>
+ Initializes a new instance of the <c>PluginCollection</c> class
+ that contains elements copied from the specified <see cref="T:log4net.Plugin.IPlugin"/> collection.
+ </summary>
+ <param name="col">The <see cref="T:log4net.Plugin.IPlugin"/> collection whose elements are copied to the new list.</param>
+ </member>
+ <member name="M:log4net.Plugin.PluginCollection.#ctor(log4net.Plugin.PluginCollection.Tag)">
+ <summary>
+ Allow subclasses to avoid our default constructors
+ </summary>
+ <param name="tag"></param>
+ <exclude/>
+ </member>
+ <member name="M:log4net.Plugin.PluginCollection.CopyTo(log4net.Plugin.IPlugin[])">
+ <summary>
+ Copies the entire <c>PluginCollection</c> to a one-dimensional
+ <see cref="T:log4net.Plugin.IPlugin"/> array.
+ </summary>
+ <param name="array">The one-dimensional <see cref="T:log4net.Plugin.IPlugin"/> array to copy to.</param>
+ </member>
+ <member name="M:log4net.Plugin.PluginCollection.CopyTo(log4net.Plugin.IPlugin[],System.Int32)">
+ <summary>
+ Copies the entire <c>PluginCollection</c> to a one-dimensional
+ <see cref="T:log4net.Plugin.IPlugin"/> array, starting at the specified index of the target array.
+ </summary>
+ <param name="array">The one-dimensional <see cref="T:log4net.Plugin.IPlugin"/> array to copy to.</param>
+ <param name="start">The zero-based index in <paramref name="array"/> at which copying begins.</param>
+ </member>
+ <member name="M:log4net.Plugin.PluginCollection.Add(log4net.Plugin.IPlugin)">
+ <summary>
+ Adds a <see cref="T:log4net.Plugin.IPlugin"/> to the end of the <c>PluginCollection</c>.
+ </summary>
+ <param name="item">The <see cref="T:log4net.Plugin.IPlugin"/> to be added to the end of the <c>PluginCollection</c>.</param>
+ <returns>The index at which the value has been added.</returns>
+ </member>
+ <member name="M:log4net.Plugin.PluginCollection.Clear">
+ <summary>
+ Removes all elements from the <c>PluginCollection</c>.
+ </summary>
+ </member>
+ <member name="M:log4net.Plugin.PluginCollection.Clone">
+ <summary>
+ Creates a shallow copy of the <see cref="T:log4net.Plugin.PluginCollection"/>.
+ </summary>
+ <returns>A new <see cref="T:log4net.Plugin.PluginCollection"/> with a shallow copy of the collection data.</returns>
+ </member>
+ <member name="M:log4net.Plugin.PluginCollection.Contains(log4net.Plugin.IPlugin)">
+ <summary>
+ Determines whether a given <see cref="T:log4net.Plugin.IPlugin"/> is in the <c>PluginCollection</c>.
+ </summary>
+ <param name="item">The <see cref="T:log4net.Plugin.IPlugin"/> to check for.</param>
+ <returns><c>true</c> if <paramref name="item"/> is found in the <c>PluginCollection</c>; otherwise, <c>false</c>.</returns>
+ </member>
+ <member name="M:log4net.Plugin.PluginCollection.IndexOf(log4net.Plugin.IPlugin)">
+ <summary>
+ Returns the zero-based index of the first occurrence of a <see cref="T:log4net.Plugin.IPlugin"/>
+ in the <c>PluginCollection</c>.
+ </summary>
+ <param name="item">The <see cref="T:log4net.Plugin.IPlugin"/> to locate in the <c>PluginCollection</c>.</param>
+ <returns>
+ The zero-based index of the first occurrence of <paramref name="item"/>
+ in the entire <c>PluginCollection</c>, if found; otherwise, -1.
+ </returns>
+ </member>
+ <member name="M:log4net.Plugin.PluginCollection.Insert(System.Int32,log4net.Plugin.IPlugin)">
+ <summary>
+ Inserts an element into the <c>PluginCollection</c> at the specified index.
+ </summary>
+ <param name="index">The zero-based index at which <paramref name="item"/> should be inserted.</param>
+ <param name="item">The <see cref="T:log4net.Plugin.IPlugin"/> to insert.</param>
+ <exception cref="T:System.ArgumentOutOfRangeException">
+ <para><paramref name="index"/> is less than zero</para>
+ <para>-or-</para>
+ <para><paramref name="index"/> is equal to or greater than <see cref="P:log4net.Plugin.PluginCollection.Count"/>.</para>
+ </exception>
+ </member>
+ <member name="M:log4net.Plugin.PluginCollection.Remove(log4net.Plugin.IPlugin)">
+ <summary>
+ Removes the first occurrence of a specific <see cref="T:log4net.Plugin.IPlugin"/> from the <c>PluginCollection</c>.
+ </summary>
+ <param name="item">The <see cref="T:log4net.Plugin.IPlugin"/> to remove from the <c>PluginCollection</c>.</param>
+ <exception cref="T:System.ArgumentException">
+ The specified <see cref="T:log4net.Plugin.IPlugin"/> was not found in the <c>PluginCollection</c>.
+ </exception>
+ </member>
+ <member name="M:log4net.Plugin.PluginCollection.RemoveAt(System.Int32)">
+ <summary>
+ Removes the element at the specified index of the <c>PluginCollection</c>.
+ </summary>
+ <param name="index">The zero-based index of the element to remove.</param>
+ <exception cref="T:System.ArgumentOutOfRangeException">
+ <para><paramref name="index"/> is less than zero.</para>
+ <para>-or-</para>
+ <para><paramref name="index"/> is equal to or greater than <see cref="P:log4net.Plugin.PluginCollection.Count"/>.</para>
+ </exception>
+ </member>
+ <member name="M:log4net.Plugin.PluginCollection.GetEnumerator">
+ <summary>
+ Returns an enumerator that can iterate through the <c>PluginCollection</c>.
+ </summary>
+ <returns>An <see cref="T:log4net.Plugin.PluginCollection.Enumerator"/> for the entire <c>PluginCollection</c>.</returns>
+ </member>
+ <member name="M:log4net.Plugin.PluginCollection.AddRange(log4net.Plugin.PluginCollection)">
+ <summary>
+ Adds the elements of another <c>PluginCollection</c> to the current <c>PluginCollection</c>.
+ </summary>
+ <param name="x">The <c>PluginCollection</c> whose elements should be added to the end of the current <c>PluginCollection</c>.</param>
+ <returns>The new <see cref="P:log4net.Plugin.PluginCollection.Count"/> of the <c>PluginCollection</c>.</returns>
+ </member>
+ <member name="M:log4net.Plugin.PluginCollection.AddRange(log4net.Plugin.IPlugin[])">
+ <summary>
+ Adds the elements of a <see cref="T:log4net.Plugin.IPlugin"/> array to the current <c>PluginCollection</c>.
+ </summary>
+ <param name="x">The <see cref="T:log4net.Plugin.IPlugin"/> array whose elements should be added to the end of the <c>PluginCollection</c>.</param>
+ <returns>The new <see cref="P:log4net.Plugin.PluginCollection.Count"/> of the <c>PluginCollection</c>.</returns>
+ </member>
+ <member name="M:log4net.Plugin.PluginCollection.AddRange(System.Collections.ICollection)">
+ <summary>
+ Adds the elements of a <see cref="T:log4net.Plugin.IPlugin"/> collection to the current <c>PluginCollection</c>.
+ </summary>
+ <param name="col">The <see cref="T:log4net.Plugin.IPlugin"/> collection whose elements should be added to the end of the <c>PluginCollection</c>.</param>
+ <returns>The new <see cref="P:log4net.Plugin.PluginCollection.Count"/> of the <c>PluginCollection</c>.</returns>
+ </member>
+ <member name="M:log4net.Plugin.PluginCollection.TrimToSize">
+ <summary>
+ Sets the capacity to the actual number of elements.
+ </summary>
+ </member>
+ <member name="M:log4net.Plugin.PluginCollection.ValidateIndex(System.Int32)">
+ <exception cref="T:System.ArgumentOutOfRangeException">
+ <para><paramref name="index"/> is less than zero.</para>
+ <para>-or-</para>
+ <para><paramref name="index"/> is equal to or greater than <see cref="P:log4net.Plugin.PluginCollection.Count"/>.</para>
+ </exception>
+ </member>
+ <member name="M:log4net.Plugin.PluginCollection.ValidateIndex(System.Int32,System.Boolean)">
+ <exception cref="T:System.ArgumentOutOfRangeException">
+ <para><paramref name="index"/> is less than zero.</para>
+ <para>-or-</para>
+ <para><paramref name="index"/> is equal to or greater than <see cref="P:log4net.Plugin.PluginCollection.Count"/>.</para>
+ </exception>
+ </member>
+ <member name="P:log4net.Plugin.PluginCollection.Count">
+ <summary>
+ Gets the number of elements actually contained in the <c>PluginCollection</c>.
+ </summary>
+ </member>
+ <member name="P:log4net.Plugin.PluginCollection.IsSynchronized">
+ <summary>
+ Gets a value indicating whether access to the collection is synchronized (thread-safe).
+ </summary>
+ <returns>true if access to the ICollection is synchronized (thread-safe); otherwise, false.</returns>
+ </member>
+ <member name="P:log4net.Plugin.PluginCollection.SyncRoot">
+ <summary>
+ Gets an object that can be used to synchronize access to the collection.
+ </summary>
+ <value>
+ An object that can be used to synchronize access to the collection.
+ </value>
+ </member>
+ <member name="P:log4net.Plugin.PluginCollection.Item(System.Int32)">
+ <summary>
+ Gets or sets the <see cref="T:log4net.Plugin.IPlugin"/> at the specified index.
+ </summary>
+ <value>
+ The <see cref="T:log4net.Plugin.IPlugin"/> at the specified index.
+ </value>
+ <param name="index">The zero-based index of the element to get or set.</param>
+ <exception cref="T:System.ArgumentOutOfRangeException">
+ <para><paramref name="index"/> is less than zero.</para>
+ <para>-or-</para>
+ <para><paramref name="index"/> is equal to or greater than <see cref="P:log4net.Plugin.PluginCollection.Count"/>.</para>
+ </exception>
+ </member>
+ <member name="P:log4net.Plugin.PluginCollection.IsFixedSize">
+ <summary>
+ Gets a value indicating whether the collection has a fixed size.
+ </summary>
+ <value><c>true</c> if the collection has a fixed size; otherwise, <c>false</c>. The default is <c>false</c>.</value>
+ </member>
+ <member name="P:log4net.Plugin.PluginCollection.IsReadOnly">
+ <summary>
+ Gets a value indicating whether the IList is read-only.
+ </summary>
+ <value><c>true</c> if the collection is read-only; otherwise, <c>false</c>. The default is <c>false</c>.</value>
+ </member>
+ <member name="P:log4net.Plugin.PluginCollection.Capacity">
+ <summary>
+ Gets or sets the number of elements the <c>PluginCollection</c> can contain.
+ </summary>
+ <value>
+ The number of elements the <c>PluginCollection</c> can contain.
+ </value>
+ </member>
+ <member name="T:log4net.Plugin.PluginCollection.IPluginCollectionEnumerator">
+ <summary>
+ Supports type-safe iteration over a <see cref="T:log4net.Plugin.PluginCollection"/>.
+ </summary>
+ <exclude/>
+ </member>
+ <member name="M:log4net.Plugin.PluginCollection.IPluginCollectionEnumerator.MoveNext">
+ <summary>
+ Advances the enumerator to the next element in the collection.
+ </summary>
+ <returns>
+ <c>true</c> if the enumerator was successfully advanced to the next element;
+ <c>false</c> if the enumerator has passed the end of the collection.
+ </returns>
+ <exception cref="T:System.InvalidOperationException">
+ The collection was modified after the enumerator was created.
+ </exception>
+ </member>
+ <member name="M:log4net.Plugin.PluginCollection.IPluginCollectionEnumerator.Reset">
+ <summary>
+ Sets the enumerator to its initial position, before the first element in the collection.
+ </summary>
+ </member>
+ <member name="P:log4net.Plugin.PluginCollection.IPluginCollectionEnumerator.Current">
+ <summary>
+ Gets the current element in the collection.
+ </summary>
+ </member>
+ <member name="T:log4net.Plugin.PluginCollection.Tag">
+ <summary>
+ Type visible only to our subclasses
+ Used to access protected constructor
+ </summary>
+ <exclude/>
+ </member>
+ <member name="F:log4net.Plugin.PluginCollection.Tag.Default">
+ <summary>
+ A value
+ </summary>
+ </member>
+ <member name="T:log4net.Plugin.PluginCollection.Enumerator">
+ <summary>
+ Supports simple iteration over a <see cref="T:log4net.Plugin.PluginCollection"/>.
+ </summary>
+ <exclude/>
+ </member>
+ <member name="M:log4net.Plugin.PluginCollection.Enumerator.#ctor(log4net.Plugin.PluginCollection)">
+ <summary>
+ Initializes a new instance of the <c>Enumerator</c> class.
+ </summary>
+ <param name="tc"></param>
+ </member>
+ <member name="M:log4net.Plugin.PluginCollection.Enumerator.MoveNext">
+ <summary>
+ Advances the enumerator to the next element in the collection.
+ </summary>
+ <returns>
+ <c>true</c> if the enumerator was successfully advanced to the next element;
+ <c>false</c> if the enumerator has passed the end of the collection.
+ </returns>
+ <exception cref="T:System.InvalidOperationException">
+ The collection was modified after the enumerator was created.
+ </exception>
+ </member>
+ <member name="M:log4net.Plugin.PluginCollection.Enumerator.Reset">
+ <summary>
+ Sets the enumerator to its initial position, before the first element in the collection.
+ </summary>
+ </member>
+ <member name="P:log4net.Plugin.PluginCollection.Enumerator.Current">
+ <summary>
+ Gets the current element in the collection.
+ </summary>
+ <value>
+ The current element in the collection.
+ </value>
+ </member>
+ <member name="T:log4net.Plugin.PluginCollection.ReadOnlyPluginCollection">
+ <exclude/>
+ </member>
+ <member name="T:log4net.Plugin.PluginMap">
+ <summary>
+ Map of repository plugins.
+ </summary>
+ <remarks>
+ <para>
+ This class is a name keyed map of the plugins that are
+ attached to a repository.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="M:log4net.Plugin.PluginMap.#ctor(log4net.Repository.ILoggerRepository)">
+ <summary>
+ Constructor
+ </summary>
+ <param name="repository">The repository that the plugins should be attached to.</param>
+ <remarks>
+ <para>
+ Initialize a new instance of the <see cref="T:log4net.Plugin.PluginMap"/> class with a
+ repository that the plugins should be attached to.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Plugin.PluginMap.Add(log4net.Plugin.IPlugin)">
+ <summary>
+ Adds a <see cref="T:log4net.Plugin.IPlugin"/> to the map.
+ </summary>
+ <param name="plugin">The <see cref="T:log4net.Plugin.IPlugin"/> to add to the map.</param>
+ <remarks>
+ <para>
+ The <see cref="T:log4net.Plugin.IPlugin"/> will be attached to the repository when added.
+ </para>
+ <para>
+ If there already exists a plugin with the same name
+ attached to the repository then the old plugin will
+ be <see cref="M:log4net.Plugin.IPlugin.Shutdown"/> and replaced with
+ the new plugin.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Plugin.PluginMap.Remove(log4net.Plugin.IPlugin)">
+ <summary>
+ Removes a <see cref="T:log4net.Plugin.IPlugin"/> from the map.
+ </summary>
+ <param name="plugin">The <see cref="T:log4net.Plugin.IPlugin"/> to remove from the map.</param>
+ <remarks>
+ <para>
+ Remove a specific plugin from this map.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Plugin.PluginMap.Item(System.String)">
+ <summary>
+ Gets a <see cref="T:log4net.Plugin.IPlugin"/> by name.
+ </summary>
+ <param name="name">The name of the <see cref="T:log4net.Plugin.IPlugin"/> to lookup.</param>
+ <returns>
+ The <see cref="T:log4net.Plugin.IPlugin"/> from the map with the name specified, or
+ <c>null</c> if no plugin is found.
+ </returns>
+ <remarks>
+ <para>
+ Lookup a plugin by name. If the plugin is not found <c>null</c>
+ will be returned.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Plugin.PluginMap.AllPlugins">
+ <summary>
+ Gets all possible plugins as a list of <see cref="T:log4net.Plugin.IPlugin"/> objects.
+ </summary>
+ <value>All possible plugins as a list of <see cref="T:log4net.Plugin.IPlugin"/> objects.</value>
+ <remarks>
+ <para>
+ Get a collection of all the plugins defined in this map.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Plugin.PluginSkeleton">
+ <summary>
+ Base implementation of <see cref="T:log4net.Plugin.IPlugin"/>
+ </summary>
+ <remarks>
+ <para>
+ Default abstract implementation of the <see cref="T:log4net.Plugin.IPlugin"/>
+ interface. This base class can be used by implementors
+ of the <see cref="T:log4net.Plugin.IPlugin"/> interface.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="M:log4net.Plugin.PluginSkeleton.#ctor(System.String)">
+ <summary>
+ Constructor
+ </summary>
+ <param name="name">the name of the plugin</param>
+ <remarks>
+ Initializes a new Plugin with the specified name.
+ </remarks>
+ </member>
+ <member name="M:log4net.Plugin.PluginSkeleton.Attach(log4net.Repository.ILoggerRepository)">
+ <summary>
+ Attaches this plugin to a <see cref="T:log4net.Repository.ILoggerRepository"/>.
+ </summary>
+ <param name="repository">The <see cref="T:log4net.Repository.ILoggerRepository"/> that this plugin should be attached to.</param>
+ <remarks>
+ <para>
+ A plugin may only be attached to a single repository.
+ </para>
+ <para>
+ This method is called when the plugin is attached to the repository.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Plugin.PluginSkeleton.Shutdown">
+ <summary>
+ Is called when the plugin is to shutdown.
+ </summary>
+ <remarks>
+ <para>
+ This method is called to notify the plugin that
+ it should stop operating and should detach from
+ the repository.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Plugin.PluginSkeleton.m_name">
+ <summary>
+ The name of this plugin.
+ </summary>
+ </member>
+ <member name="F:log4net.Plugin.PluginSkeleton.m_repository">
+ <summary>
+ The repository this plugin is attached to.
+ </summary>
+ </member>
+ <member name="P:log4net.Plugin.PluginSkeleton.Name">
+ <summary>
+ Gets or sets the name of the plugin.
+ </summary>
+ <value>
+ The name of the plugin.
+ </value>
+ <remarks>
+ <para>
+ Plugins are stored in the <see cref="T:log4net.Plugin.PluginMap"/>
+ keyed by name. Each plugin instance attached to a
+ repository must be a unique name.
+ </para>
+ <para>
+ The name of the plugin must not change one the
+ plugin has been attached to a repository.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Plugin.PluginSkeleton.LoggerRepository">
+ <summary>
+ The repository for this plugin
+ </summary>
+ <value>
+ The <see cref="T:log4net.Repository.ILoggerRepository"/> that this plugin is attached to.
+ </value>
+ <remarks>
+ <para>
+ Gets or sets the <see cref="T:log4net.Repository.ILoggerRepository"/> that this plugin is
+ attached to.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Plugin.RemoteLoggingServerPlugin">
+ <summary>
+ Plugin that listens for events from the <see cref="T:log4net.Appender.RemotingAppender"/>
+ </summary>
+ <remarks>
+ <para>
+ This plugin publishes an instance of <see cref="T:log4net.Appender.RemotingAppender.IRemoteLoggingSink"/>
+ on a specified <see cref="P:log4net.Plugin.RemoteLoggingServerPlugin.SinkUri"/>. This listens for logging events delivered from
+ a remote <see cref="T:log4net.Appender.RemotingAppender"/>.
+ </para>
+ <para>
+ When an event is received it is relogged within the attached repository
+ as if it had been raised locally.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="M:log4net.Plugin.RemoteLoggingServerPlugin.#ctor">
+ <summary>
+ Default constructor
+ </summary>
+ <remarks>
+ <para>
+ Initializes a new instance of the <see cref="T:log4net.Plugin.RemoteLoggingServerPlugin"/> class.
+ </para>
+ <para>
+ The <see cref="P:log4net.Plugin.RemoteLoggingServerPlugin.SinkUri"/> property must be set.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Plugin.RemoteLoggingServerPlugin.#ctor(System.String)">
+ <summary>
+ Construct with sink Uri.
+ </summary>
+ <param name="sinkUri">The name to publish the sink under in the remoting infrastructure.
+ See <see cref="P:log4net.Plugin.RemoteLoggingServerPlugin.SinkUri"/> for more details.</param>
+ <remarks>
+ <para>
+ Initializes a new instance of the <see cref="T:log4net.Plugin.RemoteLoggingServerPlugin"/> class
+ with specified name.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Plugin.RemoteLoggingServerPlugin.Attach(log4net.Repository.ILoggerRepository)">
+ <summary>
+ Attaches this plugin to a <see cref="T:log4net.Repository.ILoggerRepository"/>.
+ </summary>
+ <param name="repository">The <see cref="T:log4net.Repository.ILoggerRepository"/> that this plugin should be attached to.</param>
+ <remarks>
+ <para>
+ A plugin may only be attached to a single repository.
+ </para>
+ <para>
+ This method is called when the plugin is attached to the repository.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Plugin.RemoteLoggingServerPlugin.Shutdown">
+ <summary>
+ Is called when the plugin is to shutdown.
+ </summary>
+ <remarks>
+ <para>
+ When the plugin is shutdown the remote logging
+ sink is disconnected.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Plugin.RemoteLoggingServerPlugin.SinkUri">
+ <summary>
+ Gets or sets the URI of this sink.
+ </summary>
+ <value>
+ The URI of this sink.
+ </value>
+ <remarks>
+ <para>
+ This is the name under which the object is marshaled.
+ <see cref="M:System.Runtime.Remoting.RemotingServices.Marshal(System.MarshalByRefObject,System.String,System.Type)"/>
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Plugin.RemoteLoggingServerPlugin.RemoteLoggingSinkImpl">
+ <summary>
+ Delivers <see cref="T:log4net.Core.LoggingEvent"/> objects to a remote sink.
+ </summary>
+ <remarks>
+ <para>
+ Internal class used to listen for logging events
+ and deliver them to the local repository.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Plugin.RemoteLoggingServerPlugin.RemoteLoggingSinkImpl.#ctor(log4net.Repository.ILoggerRepository)">
+ <summary>
+ Constructor
+ </summary>
+ <param name="repository">The repository to log to.</param>
+ <remarks>
+ <para>
+ Initializes a new instance of the <see cref="T:log4net.Plugin.RemoteLoggingServerPlugin.RemoteLoggingSinkImpl"/> for the
+ specified <see cref="T:log4net.Repository.ILoggerRepository"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Plugin.RemoteLoggingServerPlugin.RemoteLoggingSinkImpl.LogEvents(log4net.Core.LoggingEvent[])">
+ <summary>
+ Logs the events to the repository.
+ </summary>
+ <param name="events">The events to log.</param>
+ <remarks>
+ <para>
+ The events passed are logged to the <see cref="T:log4net.Repository.ILoggerRepository"/>
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Plugin.RemoteLoggingServerPlugin.RemoteLoggingSinkImpl.InitializeLifetimeService">
+ <summary>
+ Obtains a lifetime service object to control the lifetime
+ policy for this instance.
+ </summary>
+ <returns><c>null</c> to indicate that this instance should live forever.</returns>
+ <remarks>
+ <para>
+ Obtains a lifetime service object to control the lifetime
+ policy for this instance. This object should live forever
+ therefore this implementation returns <c>null</c>.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Plugin.RemoteLoggingServerPlugin.RemoteLoggingSinkImpl.m_repository">
+ <summary>
+ The underlying <see cref="T:log4net.Repository.ILoggerRepository"/> that events should
+ be logged to.
+ </summary>
+ </member>
+ <member name="T:log4net.Repository.Hierarchy.DefaultLoggerFactory">
+ <summary>
+ Default implementation of <see cref="T:log4net.Repository.Hierarchy.ILoggerFactory"/>
+ </summary>
+ <remarks>
+ <para>
+ This default implementation of the <see cref="T:log4net.Repository.Hierarchy.ILoggerFactory"/>
+ interface is used to create the default subclass
+ of the <see cref="T:log4net.Repository.Hierarchy.Logger"/> object.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="T:log4net.Repository.Hierarchy.ILoggerFactory">
+ <summary>
+ Interface abstracts creation of <see cref="T:log4net.Repository.Hierarchy.Logger"/> instances
+ </summary>
+ <remarks>
+ <para>
+ This interface is used by the <see cref="T:log4net.Repository.Hierarchy.Hierarchy"/> to
+ create new <see cref="T:log4net.Repository.Hierarchy.Logger"/> objects.
+ </para>
+ <para>
+ The <see cref="M:log4net.Repository.Hierarchy.ILoggerFactory.CreateLogger(System.String)"/> method is called
+ to create a named <see cref="T:log4net.Repository.Hierarchy.Logger"/>.
+ </para>
+ <para>
+ Implement this interface to create new subclasses of <see cref="T:log4net.Repository.Hierarchy.Logger"/>.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="M:log4net.Repository.Hierarchy.ILoggerFactory.CreateLogger(System.String)">
+ <summary>
+ Create a new <see cref="T:log4net.Repository.Hierarchy.Logger"/> instance
+ </summary>
+ <param name="name">The name of the <see cref="T:log4net.Repository.Hierarchy.Logger"/>.</param>
+ <returns>The <see cref="T:log4net.Repository.Hierarchy.Logger"/> instance for the specified name.</returns>
+ <remarks>
+ <para>
+ Create a new <see cref="T:log4net.Repository.Hierarchy.Logger"/> instance with the
+ specified name.
+ </para>
+ <para>
+ Called by the <see cref="T:log4net.Repository.Hierarchy.Hierarchy"/> to create
+ new named <see cref="T:log4net.Repository.Hierarchy.Logger"/> instances.
+ </para>
+ <para>
+ If the <paramref name="name"/> is <c>null</c> then the root logger
+ must be returned.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Repository.Hierarchy.DefaultLoggerFactory.#ctor">
+ <summary>
+ Default constructor
+ </summary>
+ <remarks>
+ <para>
+ Initializes a new instance of the <see cref="T:log4net.Repository.Hierarchy.DefaultLoggerFactory"/> class.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Repository.Hierarchy.DefaultLoggerFactory.CreateLogger(System.String)">
+ <summary>
+ Create a new <see cref="T:log4net.Repository.Hierarchy.Logger"/> instance
+ </summary>
+ <param name="name">The name of the <see cref="T:log4net.Repository.Hierarchy.Logger"/>.</param>
+ <returns>The <see cref="T:log4net.Repository.Hierarchy.Logger"/> instance for the specified name.</returns>
+ <remarks>
+ <para>
+ Create a new <see cref="T:log4net.Repository.Hierarchy.Logger"/> instance with the
+ specified name.
+ </para>
+ <para>
+ Called by the <see cref="T:log4net.Repository.Hierarchy.Hierarchy"/> to create
+ new named <see cref="T:log4net.Repository.Hierarchy.Logger"/> instances.
+ </para>
+ <para>
+ If the <paramref name="name"/> is <c>null</c> then the root logger
+ must be returned.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Repository.Hierarchy.DefaultLoggerFactory.LoggerImpl">
+ <summary>
+ Default internal subclass of <see cref="T:log4net.Repository.Hierarchy.Logger"/>
+ </summary>
+ <remarks>
+ <para>
+ This subclass has no additional behavior over the
+ <see cref="T:log4net.Repository.Hierarchy.Logger"/> class but does allow instances
+ to be created.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Repository.Hierarchy.Logger">
+ <summary>
+ Implementation of <see cref="T:log4net.Core.ILogger"/> used by <see cref="P:log4net.Repository.Hierarchy.Logger.Hierarchy"/>
+ </summary>
+ <remarks>
+ <para>
+ Internal class used to provide implementation of <see cref="T:log4net.Core.ILogger"/>
+ interface. Applications should use <see cref="T:log4net.LogManager"/> to get
+ logger instances.
+ </para>
+ <para>
+ This is one of the central classes in the log4net implementation. One of the
+ distinctive features of log4net are hierarchical loggers and their
+ evaluation. The <see cref="P:log4net.Repository.Hierarchy.Logger.Hierarchy"/> organizes the <see cref="T:log4net.Repository.Hierarchy.Logger"/>
+ instances into a rooted tree hierarchy.
+ </para>
+ <para>
+ The <see cref="T:log4net.Repository.Hierarchy.Logger"/> class is abstract. Only concrete subclasses of
+ <see cref="T:log4net.Repository.Hierarchy.Logger"/> can be created. The <see cref="T:log4net.Repository.Hierarchy.ILoggerFactory"/>
+ is used to create instances of this type for the <see cref="P:log4net.Repository.Hierarchy.Logger.Hierarchy"/>.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ <author>Aspi Havewala</author>
+ <author>Douglas de la Torre</author>
+ </member>
+ <member name="M:log4net.Repository.Hierarchy.Logger.#ctor(System.String)">
+ <summary>
+ This constructor created a new <see cref="T:log4net.Repository.Hierarchy.Logger"/> instance and
+ sets its name.
+ </summary>
+ <param name="name">The name of the <see cref="T:log4net.Repository.Hierarchy.Logger"/>.</param>
+ <remarks>
+ <para>
+ This constructor is protected and designed to be used by
+ a subclass that is not abstract.
+ </para>
+ <para>
+ Loggers are constructed by <see cref="T:log4net.Repository.Hierarchy.ILoggerFactory"/>
+ objects. See <see cref="T:log4net.Repository.Hierarchy.DefaultLoggerFactory"/> for the default
+ logger creator.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Repository.Hierarchy.Logger.AddAppender(log4net.Appender.IAppender)">
+ <summary>
+ Add <paramref name="newAppender"/> to the list of appenders of this
+ Logger instance.
+ </summary>
+ <param name="newAppender">An appender to add to this logger</param>
+ <remarks>
+ <para>
+ Add <paramref name="newAppender"/> to the list of appenders of this
+ Logger instance.
+ </para>
+ <para>
+ If <paramref name="newAppender"/> is already in the list of
+ appenders, then it won't be added again.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Repository.Hierarchy.Logger.GetAppender(System.String)">
+ <summary>
+ Look for the appender named as <c>name</c>
+ </summary>
+ <param name="name">The name of the appender to lookup</param>
+ <returns>The appender with the name specified, or <c>null</c>.</returns>
+ <remarks>
+ <para>
+ Returns the named appender, or null if the appender is not found.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Repository.Hierarchy.Logger.RemoveAllAppenders">
+ <summary>
+ Remove all previously added appenders from this Logger instance.
+ </summary>
+ <remarks>
+ <para>
+ Remove all previously added appenders from this Logger instance.
+ </para>
+ <para>
+ This is useful when re-reading configuration information.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Repository.Hierarchy.Logger.RemoveAppender(log4net.Appender.IAppender)">
+ <summary>
+ Remove the appender passed as parameter form the list of appenders.
+ </summary>
+ <param name="appender">The appender to remove</param>
+ <returns>The appender removed from the list</returns>
+ <remarks>
+ <para>
+ Remove the appender passed as parameter form the list of appenders.
+ The appender removed is not closed.
+ If you are discarding the appender you must call
+ <see cref="M:log4net.Appender.IAppender.Close"/> on the appender removed.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Repository.Hierarchy.Logger.RemoveAppender(System.String)">
+ <summary>
+ Remove the appender passed as parameter form the list of appenders.
+ </summary>
+ <param name="name">The name of the appender to remove</param>
+ <returns>The appender removed from the list</returns>
+ <remarks>
+ <para>
+ Remove the named appender passed as parameter form the list of appenders.
+ The appender removed is not closed.
+ If you are discarding the appender you must call
+ <see cref="M:log4net.Appender.IAppender.Close"/> on the appender removed.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Repository.Hierarchy.Logger.Log(System.Type,log4net.Core.Level,System.Object,System.Exception)">
+ <summary>
+ This generic form is intended to be used by wrappers.
+ </summary>
+ <param name="callerStackBoundaryDeclaringType">The declaring type of the method that is
+ the stack boundary into the logging system for this call.</param>
+ <param name="level">The level of the message to be logged.</param>
+ <param name="message">The message object to log.</param>
+ <param name="exception">The exception to log, including its stack trace.</param>
+ <remarks>
+ <para>
+ Generate a logging event for the specified <paramref name="level"/> using
+ the <paramref name="message"/> and <paramref name="exception"/>.
+ </para>
+ <para>
+ This method must not throw any exception to the caller.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Repository.Hierarchy.Logger.Log(log4net.Core.LoggingEvent)">
+ <summary>
+ This is the most generic printing method that is intended to be used
+ by wrappers.
+ </summary>
+ <param name="logEvent">The event being logged.</param>
+ <remarks>
+ <para>
+ Logs the specified logging event through this logger.
+ </para>
+ <para>
+ This method must not throw any exception to the caller.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Repository.Hierarchy.Logger.IsEnabledFor(log4net.Core.Level)">
+ <summary>
+ Checks if this logger is enabled for a given <see cref="P:log4net.Repository.Hierarchy.Logger.Level"/> passed as parameter.
+ </summary>
+ <param name="level">The level to check.</param>
+ <returns>
+ <c>true</c> if this logger is enabled for <c>level</c>, otherwise <c>false</c>.
+ </returns>
+ <remarks>
+ <para>
+ Test if this logger is going to log events of the specified <paramref name="level"/>.
+ </para>
+ <para>
+ This method must not throw any exception to the caller.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Repository.Hierarchy.Logger.CallAppenders(log4net.Core.LoggingEvent)">
+ <summary>
+ Deliver the <see cref="T:log4net.Core.LoggingEvent"/> to the attached appenders.
+ </summary>
+ <param name="loggingEvent">The event to log.</param>
+ <remarks>
+ <para>
+ Call the appenders in the hierarchy starting at
+ <c>this</c>. If no appenders could be found, emit a
+ warning.
+ </para>
+ <para>
+ This method calls all the appenders inherited from the
+ hierarchy circumventing any evaluation of whether to log or not
+ to log the particular log request.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Repository.Hierarchy.Logger.CloseNestedAppenders">
+ <summary>
+ Closes all attached appenders implementing the <see cref="T:log4net.Core.IAppenderAttachable"/> interface.
+ </summary>
+ <remarks>
+ <para>
+ Used to ensure that the appenders are correctly shutdown.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Repository.Hierarchy.Logger.Log(log4net.Core.Level,System.Object,System.Exception)">
+ <summary>
+ This is the most generic printing method. This generic form is intended to be used by wrappers
+ </summary>
+ <param name="level">The level of the message to be logged.</param>
+ <param name="message">The message object to log.</param>
+ <param name="exception">The exception to log, including its stack trace.</param>
+ <remarks>
+ <para>
+ Generate a logging event for the specified <paramref name="level"/> using
+ the <paramref name="message"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Repository.Hierarchy.Logger.ForcedLog(System.Type,log4net.Core.Level,System.Object,System.Exception)">
+ <summary>
+ Creates a new logging event and logs the event without further checks.
+ </summary>
+ <param name="callerStackBoundaryDeclaringType">The declaring type of the method that is
+ the stack boundary into the logging system for this call.</param>
+ <param name="level">The level of the message to be logged.</param>
+ <param name="message">The message object to log.</param>
+ <param name="exception">The exception to log, including its stack trace.</param>
+ <remarks>
+ <para>
+ Generates a logging event and delivers it to the attached
+ appenders.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Repository.Hierarchy.Logger.ForcedLog(log4net.Core.LoggingEvent)">
+ <summary>
+ Creates a new logging event and logs the event without further checks.
+ </summary>
+ <param name="logEvent">The event being logged.</param>
+ <remarks>
+ <para>
+ Delivers the logging event to the attached appenders.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Repository.Hierarchy.Logger.ThisDeclaringType">
+ <summary>
+ The fully qualified type of the Logger class.
+ </summary>
+ </member>
+ <member name="F:log4net.Repository.Hierarchy.Logger.m_name">
+ <summary>
+ The name of this logger.
+ </summary>
+ </member>
+ <member name="F:log4net.Repository.Hierarchy.Logger.m_level">
+ <summary>
+ The assigned level of this logger.
+ </summary>
+ <remarks>
+ <para>
+ The <c>level</c> variable need not be
+ assigned a value in which case it is inherited
+ form the hierarchy.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Repository.Hierarchy.Logger.m_parent">
+ <summary>
+ The parent of this logger.
+ </summary>
+ <remarks>
+ <para>
+ The parent of this logger.
+ All loggers have at least one ancestor which is the root logger.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Repository.Hierarchy.Logger.m_hierarchy">
+ <summary>
+ Loggers need to know what Hierarchy they are in.
+ </summary>
+ <remarks>
+ <para>
+ Loggers need to know what Hierarchy they are in.
+ The hierarchy that this logger is a member of is stored
+ here.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Repository.Hierarchy.Logger.m_appenderAttachedImpl">
+ <summary>
+ Helper implementation of the <see cref="T:log4net.Core.IAppenderAttachable"/> interface
+ </summary>
+ </member>
+ <member name="F:log4net.Repository.Hierarchy.Logger.m_additive">
+ <summary>
+ Flag indicating if child loggers inherit their parents appenders
+ </summary>
+ <remarks>
+ <para>
+ Additivity is set to true by default, that is children inherit
+ the appenders of their ancestors by default. If this variable is
+ set to <c>false</c> then the appenders found in the
+ ancestors of this logger are not used. However, the children
+ of this logger will inherit its appenders, unless the children
+ have their additivity flag set to <c>false</c> too. See
+ the user manual for more details.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Repository.Hierarchy.Logger.m_appenderLock">
+ <summary>
+ Lock to protect AppenderAttachedImpl variable m_appenderAttachedImpl
+ </summary>
+ </member>
+ <member name="P:log4net.Repository.Hierarchy.Logger.Parent">
+ <summary>
+ Gets or sets the parent logger in the hierarchy.
+ </summary>
+ <value>
+ The parent logger in the hierarchy.
+ </value>
+ <remarks>
+ <para>
+ Part of the Composite pattern that makes the hierarchy.
+ The hierarchy is parent linked rather than child linked.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Repository.Hierarchy.Logger.Additivity">
+ <summary>
+ Gets or sets a value indicating if child loggers inherit their parent's appenders.
+ </summary>
+ <value>
+ <c>true</c> if child loggers inherit their parent's appenders.
+ </value>
+ <remarks>
+ <para>
+ Additivity is set to <c>true</c> by default, that is children inherit
+ the appenders of their ancestors by default. If this variable is
+ set to <c>false</c> then the appenders found in the
+ ancestors of this logger are not used. However, the children
+ of this logger will inherit its appenders, unless the children
+ have their additivity flag set to <c>false</c> too. See
+ the user manual for more details.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Repository.Hierarchy.Logger.EffectiveLevel">
+ <summary>
+ Gets the effective level for this logger.
+ </summary>
+ <returns>The nearest level in the logger hierarchy.</returns>
+ <remarks>
+ <para>
+ Starting from this logger, searches the logger hierarchy for a
+ non-null level and returns it. Otherwise, returns the level of the
+ root logger.
+ </para>
+ <para>The Logger class is designed so that this method executes as
+ quickly as possible.</para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Repository.Hierarchy.Logger.Hierarchy">
+ <summary>
+ Gets or sets the <see cref="P:log4net.Repository.Hierarchy.Logger.Hierarchy"/> where this
+ <c>Logger</c> instance is attached to.
+ </summary>
+ <value>The hierarchy that this logger belongs to.</value>
+ <remarks>
+ <para>
+ This logger must be attached to a single <see cref="P:log4net.Repository.Hierarchy.Logger.Hierarchy"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Repository.Hierarchy.Logger.Level">
+ <summary>
+ Gets or sets the assigned <see cref="P:log4net.Repository.Hierarchy.Logger.Level"/>, if any, for this Logger.
+ </summary>
+ <value>
+ The <see cref="P:log4net.Repository.Hierarchy.Logger.Level"/> of this logger.
+ </value>
+ <remarks>
+ <para>
+ The assigned <see cref="P:log4net.Repository.Hierarchy.Logger.Level"/> can be <c>null</c>.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Repository.Hierarchy.Logger.Appenders">
+ <summary>
+ Get the appenders contained in this logger as an
+ <see cref="T:System.Collections.ICollection"/>.
+ </summary>
+ <returns>A collection of the appenders in this logger</returns>
+ <remarks>
+ <para>
+ Get the appenders contained in this logger as an
+ <see cref="T:System.Collections.ICollection"/>. If no appenders
+ can be found, then a <see cref="T:log4net.Util.EmptyCollection"/> is returned.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Repository.Hierarchy.Logger.Name">
+ <summary>
+ Gets the logger name.
+ </summary>
+ <value>
+ The name of the logger.
+ </value>
+ <remarks>
+ <para>
+ The name of this logger
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Repository.Hierarchy.Logger.Repository">
+ <summary>
+ Gets the <see cref="T:log4net.Repository.ILoggerRepository"/> where this
+ <c>Logger</c> instance is attached to.
+ </summary>
+ <value>
+ The <see cref="T:log4net.Repository.ILoggerRepository"/> that this logger belongs to.
+ </value>
+ <remarks>
+ <para>
+ Gets the <see cref="T:log4net.Repository.ILoggerRepository"/> where this
+ <c>Logger</c> instance is attached to.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Repository.Hierarchy.DefaultLoggerFactory.LoggerImpl.#ctor(System.String)">
+ <summary>
+ Construct a new Logger
+ </summary>
+ <param name="name">the name of the logger</param>
+ <remarks>
+ <para>
+ Initializes a new instance of the <see cref="T:log4net.Repository.Hierarchy.DefaultLoggerFactory.LoggerImpl"/> class
+ with the specified name.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Repository.Hierarchy.LoggerCreationEventHandler">
+ <summary>
+ Delegate used to handle logger creation event notifications.
+ </summary>
+ <param name="sender">The <see cref="T:log4net.Repository.Hierarchy.Hierarchy"/> in which the <see cref="T:log4net.Repository.Hierarchy.Logger"/> has been created.</param>
+ <param name="e">The <see cref="T:log4net.Repository.Hierarchy.LoggerCreationEventArgs"/> event args that hold the <see cref="T:log4net.Repository.Hierarchy.Logger"/> instance that has been created.</param>
+ <remarks>
+ <para>
+ Delegate used to handle logger creation event notifications.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Repository.Hierarchy.LoggerCreationEventArgs">
+ <summary>
+ Provides data for the <see cref="E:log4net.Repository.Hierarchy.Hierarchy.LoggerCreatedEvent"/> event.
+ </summary>
+ <remarks>
+ <para>
+ A <see cref="E:log4net.Repository.Hierarchy.Hierarchy.LoggerCreatedEvent"/> event is raised every time a
+ <see cref="P:log4net.Repository.Hierarchy.LoggerCreationEventArgs.Logger"/> is created.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Repository.Hierarchy.LoggerCreationEventArgs.m_log">
+ <summary>
+ The <see cref="P:log4net.Repository.Hierarchy.LoggerCreationEventArgs.Logger"/> created
+ </summary>
+ </member>
+ <member name="M:log4net.Repository.Hierarchy.LoggerCreationEventArgs.#ctor(log4net.Repository.Hierarchy.Logger)">
+ <summary>
+ Constructor
+ </summary>
+ <param name="log">The <see cref="P:log4net.Repository.Hierarchy.LoggerCreationEventArgs.Logger"/> that has been created.</param>
+ <remarks>
+ <para>
+ Initializes a new instance of the <see cref="T:log4net.Repository.Hierarchy.LoggerCreationEventArgs"/> event argument
+ class,with the specified <see cref="P:log4net.Repository.Hierarchy.LoggerCreationEventArgs.Logger"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Repository.Hierarchy.LoggerCreationEventArgs.Logger">
+ <summary>
+ Gets the <see cref="P:log4net.Repository.Hierarchy.LoggerCreationEventArgs.Logger"/> that has been created.
+ </summary>
+ <value>
+ The <see cref="P:log4net.Repository.Hierarchy.LoggerCreationEventArgs.Logger"/> that has been created.
+ </value>
+ <remarks>
+ <para>
+ The <see cref="P:log4net.Repository.Hierarchy.LoggerCreationEventArgs.Logger"/> that has been created.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Repository.Hierarchy.Hierarchy">
+ <summary>
+ Hierarchical organization of loggers
+ </summary>
+ <remarks>
+ <para>
+ <i>The casual user should not have to deal with this class
+ directly.</i>
+ </para>
+ <para>
+ This class is specialized in retrieving loggers by name and
+ also maintaining the logger hierarchy. Implements the
+ <see cref="T:log4net.Repository.ILoggerRepository"/> interface.
+ </para>
+ <para>
+ The structure of the logger hierarchy is maintained by the
+ <see cref="M:log4net.Repository.Hierarchy.Hierarchy.GetLogger(System.String)"/> method. The hierarchy is such that children
+ link to their parent but parents do not have any references to their
+ children. Moreover, loggers can be instantiated in any order, in
+ particular descendant before ancestor.
+ </para>
+ <para>
+ In case a descendant is created before a particular ancestor,
+ then it creates a provision node for the ancestor and adds itself
+ to the provision node. Other descendants of the same ancestor add
+ themselves to the previously created provision node.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="T:log4net.Repository.LoggerRepositorySkeleton">
+ <summary>
+ Base implementation of <see cref="T:log4net.Repository.ILoggerRepository"/>
+ </summary>
+ <remarks>
+ <para>
+ Default abstract implementation of the <see cref="T:log4net.Repository.ILoggerRepository"/> interface.
+ </para>
+ <para>
+ Skeleton implementation of the <see cref="T:log4net.Repository.ILoggerRepository"/> interface.
+ All <see cref="T:log4net.Repository.ILoggerRepository"/> types can extend this type.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="T:log4net.Repository.ILoggerRepository">
+ <summary>
+ Interface implemented by logger repositories.
+ </summary>
+ <remarks>
+ <para>
+ This interface is implemented by logger repositories. e.g.
+ <see cref="T:log4net.Repository.Hierarchy.Hierarchy"/>.
+ </para>
+ <para>
+ This interface is used by the <see cref="T:log4net.LogManager"/>
+ to obtain <see cref="T:log4net.ILog"/> interfaces.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="M:log4net.Repository.ILoggerRepository.Exists(System.String)">
+ <summary>
+ Check if the named logger exists in the repository. If so return
+ its reference, otherwise returns <c>null</c>.
+ </summary>
+ <param name="name">The name of the logger to lookup</param>
+ <returns>The Logger object with the name specified</returns>
+ <remarks>
+ <para>
+ If the names logger exists it is returned, otherwise
+ <c>null</c> is returned.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Repository.ILoggerRepository.GetCurrentLoggers">
+ <summary>
+ Returns all the currently defined loggers as an Array.
+ </summary>
+ <returns>All the defined loggers</returns>
+ <remarks>
+ <para>
+ Returns all the currently defined loggers as an Array.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Repository.ILoggerRepository.GetLogger(System.String)">
+ <summary>
+ Returns a named logger instance
+ </summary>
+ <param name="name">The name of the logger to retrieve</param>
+ <returns>The logger object with the name specified</returns>
+ <remarks>
+ <para>
+ Returns a named logger instance.
+ </para>
+ <para>
+ If a logger of that name already exists, then it will be
+ returned. Otherwise, a new logger will be instantiated and
+ then linked with its existing ancestors as well as children.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Repository.ILoggerRepository.Shutdown">
+ <summary>Shutdown the repository</summary>
+ <remarks>
+ <para>
+ Shutting down a repository will <i>safely</i> close and remove
+ all appenders in all loggers including the root logger.
+ </para>
+ <para>
+ Some appenders need to be closed before the
+ application exists. Otherwise, pending logging events might be
+ lost.
+ </para>
+ <para>
+ The <see cref="M:log4net.Repository.ILoggerRepository.Shutdown"/> method is careful to close nested
+ appenders before closing regular appenders. This is allows
+ configurations where a regular appender is attached to a logger
+ and again to a nested appender.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Repository.ILoggerRepository.ResetConfiguration">
+ <summary>
+ Reset the repositories configuration to a default state
+ </summary>
+ <remarks>
+ <para>
+ Reset all values contained in this instance to their
+ default state.
+ </para>
+ <para>
+ Existing loggers are not removed. They are just reset.
+ </para>
+ <para>
+ This method should be used sparingly and with care as it will
+ block all logging until it is completed.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Repository.ILoggerRepository.Log(log4net.Core.LoggingEvent)">
+ <summary>
+ Log the <see cref="T:log4net.Core.LoggingEvent"/> through this repository.
+ </summary>
+ <param name="logEvent">the event to log</param>
+ <remarks>
+ <para>
+ This method should not normally be used to log.
+ The <see cref="T:log4net.ILog"/> interface should be used
+ for routine logging. This interface can be obtained
+ using the <see cref="M:log4net.LogManager.GetLogger(System.String)"/> method.
+ </para>
+ <para>
+ The <c>logEvent</c> is delivered to the appropriate logger and
+ that logger is then responsible for logging the event.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Repository.ILoggerRepository.GetAppenders">
+ <summary>
+ Returns all the Appenders that are configured as an Array.
+ </summary>
+ <returns>All the Appenders</returns>
+ <remarks>
+ <para>
+ Returns all the Appenders that are configured as an Array.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Repository.ILoggerRepository.Name">
+ <summary>
+ The name of the repository
+ </summary>
+ <value>
+ The name of the repository
+ </value>
+ <remarks>
+ <para>
+ The name of the repository.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Repository.ILoggerRepository.RendererMap">
+ <summary>
+ RendererMap accesses the object renderer map for this repository.
+ </summary>
+ <value>
+ RendererMap accesses the object renderer map for this repository.
+ </value>
+ <remarks>
+ <para>
+ RendererMap accesses the object renderer map for this repository.
+ </para>
+ <para>
+ The RendererMap holds a mapping between types and
+ <see cref="T:log4net.ObjectRenderer.IObjectRenderer"/> objects.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Repository.ILoggerRepository.PluginMap">
+ <summary>
+ The plugin map for this repository.
+ </summary>
+ <value>
+ The plugin map for this repository.
+ </value>
+ <remarks>
+ <para>
+ The plugin map holds the <see cref="T:log4net.Plugin.IPlugin"/> instances
+ that have been attached to this repository.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Repository.ILoggerRepository.LevelMap">
+ <summary>
+ Get the level map for the Repository.
+ </summary>
+ <remarks>
+ <para>
+ Get the level map for the Repository.
+ </para>
+ <para>
+ The level map defines the mappings between
+ level names and <see cref="T:log4net.Core.Level"/> objects in
+ this repository.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Repository.ILoggerRepository.Threshold">
+ <summary>
+ The threshold for all events in this repository
+ </summary>
+ <value>
+ The threshold for all events in this repository
+ </value>
+ <remarks>
+ <para>
+ The threshold for all events in this repository.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Repository.ILoggerRepository.Configured">
+ <summary>
+ Flag indicates if this repository has been configured.
+ </summary>
+ <value>
+ Flag indicates if this repository has been configured.
+ </value>
+ <remarks>
+ <para>
+ Flag indicates if this repository has been configured.
+ </para>
+ </remarks>
+ </member>
+ <member name="E:log4net.Repository.ILoggerRepository.ShutdownEvent">
+ <summary>
+ Event to notify that the repository has been shutdown.
+ </summary>
+ <value>
+ Event to notify that the repository has been shutdown.
+ </value>
+ <remarks>
+ <para>
+ Event raised when the repository has been shutdown.
+ </para>
+ </remarks>
+ </member>
+ <member name="E:log4net.Repository.ILoggerRepository.ConfigurationReset">
+ <summary>
+ Event to notify that the repository has had its configuration reset.
+ </summary>
+ <value>
+ Event to notify that the repository has had its configuration reset.
+ </value>
+ <remarks>
+ <para>
+ Event raised when the repository's configuration has been
+ reset to default.
+ </para>
+ </remarks>
+ </member>
+ <member name="E:log4net.Repository.ILoggerRepository.ConfigurationChanged">
+ <summary>
+ Event to notify that the repository has had its configuration changed.
+ </summary>
+ <value>
+ Event to notify that the repository has had its configuration changed.
+ </value>
+ <remarks>
+ <para>
+ Event raised when the repository's configuration has been changed.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Repository.ILoggerRepository.Properties">
+ <summary>
+ Repository specific properties
+ </summary>
+ <value>
+ Repository specific properties
+ </value>
+ <remarks>
+ <para>
+ These properties can be specified on a repository specific basis.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Repository.LoggerRepositorySkeleton.#ctor">
+ <summary>
+ Default Constructor
+ </summary>
+ <remarks>
+ <para>
+ Initializes the repository with default (empty) properties.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Repository.LoggerRepositorySkeleton.#ctor(log4net.Util.PropertiesDictionary)">
+ <summary>
+ Construct the repository using specific properties
+ </summary>
+ <param name="properties">the properties to set for this repository</param>
+ <remarks>
+ <para>
+ Initializes the repository with specified properties.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Repository.LoggerRepositorySkeleton.Exists(System.String)">
+ <summary>
+ Test if logger exists
+ </summary>
+ <param name="name">The name of the logger to lookup</param>
+ <returns>The Logger object with the name specified</returns>
+ <remarks>
+ <para>
+ Check if the named logger exists in the repository. If so return
+ its reference, otherwise returns <c>null</c>.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Repository.LoggerRepositorySkeleton.GetCurrentLoggers">
+ <summary>
+ Returns all the currently defined loggers in the repository
+ </summary>
+ <returns>All the defined loggers</returns>
+ <remarks>
+ <para>
+ Returns all the currently defined loggers in the repository as an Array.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Repository.LoggerRepositorySkeleton.GetLogger(System.String)">
+ <summary>
+ Return a new logger instance
+ </summary>
+ <param name="name">The name of the logger to retrieve</param>
+ <returns>The logger object with the name specified</returns>
+ <remarks>
+ <para>
+ Return a new logger instance.
+ </para>
+ <para>
+ If a logger of that name already exists, then it will be
+ returned. Otherwise, a new logger will be instantiated and
+ then linked with its existing ancestors as well as children.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Repository.LoggerRepositorySkeleton.Shutdown">
+ <summary>
+ Shutdown the repository
+ </summary>
+ <remarks>
+ <para>
+ Shutdown the repository. Can be overridden in a subclass.
+ This base class implementation notifies the <see cref="E:log4net.Repository.LoggerRepositorySkeleton.ShutdownEvent"/>
+ listeners and all attached plugins of the shutdown event.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Repository.LoggerRepositorySkeleton.ResetConfiguration">
+ <summary>
+ Reset the repositories configuration to a default state
+ </summary>
+ <remarks>
+ <para>
+ Reset all values contained in this instance to their
+ default state.
+ </para>
+ <para>
+ Existing loggers are not removed. They are just reset.
+ </para>
+ <para>
+ This method should be used sparingly and with care as it will
+ block all logging until it is completed.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Repository.LoggerRepositorySkeleton.Log(log4net.Core.LoggingEvent)">
+ <summary>
+ Log the logEvent through this repository.
+ </summary>
+ <param name="logEvent">the event to log</param>
+ <remarks>
+ <para>
+ This method should not normally be used to log.
+ The <see cref="T:log4net.ILog"/> interface should be used
+ for routine logging. This interface can be obtained
+ using the <see cref="M:log4net.LogManager.GetLogger(System.String)"/> method.
+ </para>
+ <para>
+ The <c>logEvent</c> is delivered to the appropriate logger and
+ that logger is then responsible for logging the event.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Repository.LoggerRepositorySkeleton.GetAppenders">
+ <summary>
+ Returns all the Appenders that are configured as an Array.
+ </summary>
+ <returns>All the Appenders</returns>
+ <remarks>
+ <para>
+ Returns all the Appenders that are configured as an Array.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Repository.LoggerRepositorySkeleton.AddRenderer(System.Type,log4net.ObjectRenderer.IObjectRenderer)">
+ <summary>
+ Adds an object renderer for a specific class.
+ </summary>
+ <param name="typeToRender">The type that will be rendered by the renderer supplied.</param>
+ <param name="rendererInstance">The object renderer used to render the object.</param>
+ <remarks>
+ <para>
+ Adds an object renderer for a specific class.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Repository.LoggerRepositorySkeleton.OnShutdown(System.EventArgs)">
+ <summary>
+ Notify the registered listeners that the repository is shutting down
+ </summary>
+ <param name="e">Empty EventArgs</param>
+ <remarks>
+ <para>
+ Notify any listeners that this repository is shutting down.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Repository.LoggerRepositorySkeleton.OnConfigurationReset(System.EventArgs)">
+ <summary>
+ Notify the registered listeners that the repository has had its configuration reset
+ </summary>
+ <param name="e">Empty EventArgs</param>
+ <remarks>
+ <para>
+ Notify any listeners that this repository's configuration has been reset.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Repository.LoggerRepositorySkeleton.OnConfigurationChanged(System.EventArgs)">
+ <summary>
+ Notify the registered listeners that the repository has had its configuration changed
+ </summary>
+ <param name="e">Empty EventArgs</param>
+ <remarks>
+ <para>
+ Notify any listeners that this repository's configuration has changed.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Repository.LoggerRepositorySkeleton.RaiseConfigurationChanged(System.EventArgs)">
+ <summary>
+ Raise a configuration changed event on this repository
+ </summary>
+ <param name="e">EventArgs.Empty</param>
+ <remarks>
+ <para>
+ Applications that programmatically change the configuration of the repository should
+ raise this event notification to notify listeners.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Repository.LoggerRepositorySkeleton.Name">
+ <summary>
+ The name of the repository
+ </summary>
+ <value>
+ The string name of the repository
+ </value>
+ <remarks>
+ <para>
+ The name of this repository. The name is
+ used to store and lookup the repositories
+ stored by the <see cref="T:log4net.Core.IRepositorySelector"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Repository.LoggerRepositorySkeleton.Threshold">
+ <summary>
+ The threshold for all events in this repository
+ </summary>
+ <value>
+ The threshold for all events in this repository
+ </value>
+ <remarks>
+ <para>
+ The threshold for all events in this repository
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Repository.LoggerRepositorySkeleton.RendererMap">
+ <summary>
+ RendererMap accesses the object renderer map for this repository.
+ </summary>
+ <value>
+ RendererMap accesses the object renderer map for this repository.
+ </value>
+ <remarks>
+ <para>
+ RendererMap accesses the object renderer map for this repository.
+ </para>
+ <para>
+ The RendererMap holds a mapping between types and
+ <see cref="T:log4net.ObjectRenderer.IObjectRenderer"/> objects.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Repository.LoggerRepositorySkeleton.PluginMap">
+ <summary>
+ The plugin map for this repository.
+ </summary>
+ <value>
+ The plugin map for this repository.
+ </value>
+ <remarks>
+ <para>
+ The plugin map holds the <see cref="T:log4net.Plugin.IPlugin"/> instances
+ that have been attached to this repository.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Repository.LoggerRepositorySkeleton.LevelMap">
+ <summary>
+ Get the level map for the Repository.
+ </summary>
+ <remarks>
+ <para>
+ Get the level map for the Repository.
+ </para>
+ <para>
+ The level map defines the mappings between
+ level names and <see cref="T:log4net.Core.Level"/> objects in
+ this repository.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Repository.LoggerRepositorySkeleton.Configured">
+ <summary>
+ Flag indicates if this repository has been configured.
+ </summary>
+ <value>
+ Flag indicates if this repository has been configured.
+ </value>
+ <remarks>
+ <para>
+ Flag indicates if this repository has been configured.
+ </para>
+ </remarks>
+ </member>
+ <member name="E:log4net.Repository.LoggerRepositorySkeleton.ShutdownEvent">
+ <summary>
+ Event to notify that the repository has been shutdown.
+ </summary>
+ <value>
+ Event to notify that the repository has been shutdown.
+ </value>
+ <remarks>
+ <para>
+ Event raised when the repository has been shutdown.
+ </para>
+ </remarks>
+ </member>
+ <member name="E:log4net.Repository.LoggerRepositorySkeleton.ConfigurationReset">
+ <summary>
+ Event to notify that the repository has had its configuration reset.
+ </summary>
+ <value>
+ Event to notify that the repository has had its configuration reset.
+ </value>
+ <remarks>
+ <para>
+ Event raised when the repository's configuration has been
+ reset to default.
+ </para>
+ </remarks>
+ </member>
+ <member name="E:log4net.Repository.LoggerRepositorySkeleton.ConfigurationChanged">
+ <summary>
+ Event to notify that the repository has had its configuration changed.
+ </summary>
+ <value>
+ Event to notify that the repository has had its configuration changed.
+ </value>
+ <remarks>
+ <para>
+ Event raised when the repository's configuration has been changed.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Repository.LoggerRepositorySkeleton.Properties">
+ <summary>
+ Repository specific properties
+ </summary>
+ <value>
+ Repository specific properties
+ </value>
+ <remarks>
+ These properties can be specified on a repository specific basis
+ </remarks>
+ </member>
+ <member name="T:log4net.Repository.IBasicRepositoryConfigurator">
+ <summary>
+ Basic Configurator interface for repositories
+ </summary>
+ <remarks>
+ <para>
+ Interface used by basic configurator to configure a <see cref="T:log4net.Repository.ILoggerRepository"/>
+ with a default <see cref="T:log4net.Appender.IAppender"/>.
+ </para>
+ <para>
+ A <see cref="T:log4net.Repository.ILoggerRepository"/> should implement this interface to support
+ configuration by the <see cref="T:log4net.Config.BasicConfigurator"/>.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="M:log4net.Repository.IBasicRepositoryConfigurator.Configure(log4net.Appender.IAppender)">
+ <summary>
+ Initialize the repository using the specified appender
+ </summary>
+ <param name="appender">the appender to use to log all logging events</param>
+ <remarks>
+ <para>
+ Configure the repository to route all logging events to the
+ specified appender.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Repository.IXmlRepositoryConfigurator">
+ <summary>
+ Configure repository using XML
+ </summary>
+ <remarks>
+ <para>
+ Interface used by Xml configurator to configure a <see cref="T:log4net.Repository.ILoggerRepository"/>.
+ </para>
+ <para>
+ A <see cref="T:log4net.Repository.ILoggerRepository"/> should implement this interface to support
+ configuration by the <see cref="T:log4net.Config.XmlConfigurator"/>.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="M:log4net.Repository.IXmlRepositoryConfigurator.Configure(System.Xml.XmlElement)">
+ <summary>
+ Initialize the repository using the specified config
+ </summary>
+ <param name="element">the element containing the root of the config</param>
+ <remarks>
+ <para>
+ The schema for the XML configuration data is defined by
+ the implementation.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Repository.Hierarchy.Hierarchy.#ctor">
+ <summary>
+ Default constructor
+ </summary>
+ <remarks>
+ <para>
+ Initializes a new instance of the <see cref="T:log4net.Repository.Hierarchy.Hierarchy"/> class.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Repository.Hierarchy.Hierarchy.#ctor(log4net.Util.PropertiesDictionary)">
+ <summary>
+ Construct with properties
+ </summary>
+ <param name="properties">The properties to pass to this repository.</param>
+ <remarks>
+ <para>
+ Initializes a new instance of the <see cref="T:log4net.Repository.Hierarchy.Hierarchy"/> class.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Repository.Hierarchy.Hierarchy.#ctor(log4net.Repository.Hierarchy.ILoggerFactory)">
+ <summary>
+ Construct with a logger factory
+ </summary>
+ <param name="loggerFactory">The factory to use to create new logger instances.</param>
+ <remarks>
+ <para>
+ Initializes a new instance of the <see cref="T:log4net.Repository.Hierarchy.Hierarchy"/> class with
+ the specified <see cref="T:log4net.Repository.Hierarchy.ILoggerFactory"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Repository.Hierarchy.Hierarchy.#ctor(log4net.Util.PropertiesDictionary,log4net.Repository.Hierarchy.ILoggerFactory)">
+ <summary>
+ Construct with properties and a logger factory
+ </summary>
+ <param name="properties">The properties to pass to this repository.</param>
+ <param name="loggerFactory">The factory to use to create new logger instances.</param>
+ <remarks>
+ <para>
+ Initializes a new instance of the <see cref="T:log4net.Repository.Hierarchy.Hierarchy"/> class with
+ the specified <see cref="T:log4net.Repository.Hierarchy.ILoggerFactory"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Repository.Hierarchy.Hierarchy.Exists(System.String)">
+ <summary>
+ Test if a logger exists
+ </summary>
+ <param name="name">The name of the logger to lookup</param>
+ <returns>The Logger object with the name specified</returns>
+ <remarks>
+ <para>
+ Check if the named logger exists in the hierarchy. If so return
+ its reference, otherwise returns <c>null</c>.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Repository.Hierarchy.Hierarchy.GetCurrentLoggers">
+ <summary>
+ Returns all the currently defined loggers in the hierarchy as an Array
+ </summary>
+ <returns>All the defined loggers</returns>
+ <remarks>
+ <para>
+ Returns all the currently defined loggers in the hierarchy as an Array.
+ The root logger is <b>not</b> included in the returned
+ enumeration.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Repository.Hierarchy.Hierarchy.GetLogger(System.String)">
+ <summary>
+ Return a new logger instance named as the first parameter using
+ the default factory.
+ </summary>
+ <remarks>
+ <para>
+ Return a new logger instance named as the first parameter using
+ the default factory.
+ </para>
+ <para>
+ If a logger of that name already exists, then it will be
+ returned. Otherwise, a new logger will be instantiated and
+ then linked with its existing ancestors as well as children.
+ </para>
+ </remarks>
+ <param name="name">The name of the logger to retrieve</param>
+ <returns>The logger object with the name specified</returns>
+ </member>
+ <member name="M:log4net.Repository.Hierarchy.Hierarchy.Shutdown">
+ <summary>
+ Shutting down a hierarchy will <i>safely</i> close and remove
+ all appenders in all loggers including the root logger.
+ </summary>
+ <remarks>
+ <para>
+ Shutting down a hierarchy will <i>safely</i> close and remove
+ all appenders in all loggers including the root logger.
+ </para>
+ <para>
+ Some appenders need to be closed before the
+ application exists. Otherwise, pending logging events might be
+ lost.
+ </para>
+ <para>
+ The <c>Shutdown</c> method is careful to close nested
+ appenders before closing regular appenders. This is allows
+ configurations where a regular appender is attached to a logger
+ and again to a nested appender.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Repository.Hierarchy.Hierarchy.ResetConfiguration">
+ <summary>
+ Reset all values contained in this hierarchy instance to their default.
+ </summary>
+ <remarks>
+ <para>
+ Reset all values contained in this hierarchy instance to their
+ default. This removes all appenders from all loggers, sets
+ the level of all non-root loggers to <c>null</c>,
+ sets their additivity flag to <c>true</c> and sets the level
+ of the root logger to <see cref="F:log4net.Core.Level.Debug"/>. Moreover,
+ message disabling is set its default "off" value.
+ </para>
+ <para>
+ Existing loggers are not removed. They are just reset.
+ </para>
+ <para>
+ This method should be used sparingly and with care as it will
+ block all logging until it is completed.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Repository.Hierarchy.Hierarchy.Log(log4net.Core.LoggingEvent)">
+ <summary>
+ Log the logEvent through this hierarchy.
+ </summary>
+ <param name="logEvent">the event to log</param>
+ <remarks>
+ <para>
+ This method should not normally be used to log.
+ The <see cref="T:log4net.ILog"/> interface should be used
+ for routine logging. This interface can be obtained
+ using the <see cref="M:log4net.LogManager.GetLogger(System.String)"/> method.
+ </para>
+ <para>
+ The <c>logEvent</c> is delivered to the appropriate logger and
+ that logger is then responsible for logging the event.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Repository.Hierarchy.Hierarchy.GetAppenders">
+ <summary>
+ Returns all the Appenders that are currently configured
+ </summary>
+ <returns>An array containing all the currently configured appenders</returns>
+ <remarks>
+ <para>
+ Returns all the <see cref="T:log4net.Appender.IAppender"/> instances that are currently configured.
+ All the loggers are searched for appenders. The appenders may also be containers
+ for appenders and these are also searched for additional loggers.
+ </para>
+ <para>
+ The list returned is unordered but does not contain duplicates.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Repository.Hierarchy.Hierarchy.CollectAppender(System.Collections.ArrayList,log4net.Appender.IAppender)">
+ <summary>
+ Collect the appenders from an <see cref="T:log4net.Core.IAppenderAttachable"/>.
+ The appender may also be a container.
+ </summary>
+ <param name="appenderList"></param>
+ <param name="appender"></param>
+ </member>
+ <member name="M:log4net.Repository.Hierarchy.Hierarchy.CollectAppenders(System.Collections.ArrayList,log4net.Core.IAppenderAttachable)">
+ <summary>
+ Collect the appenders from an <see cref="T:log4net.Core.IAppenderAttachable"/> container
+ </summary>
+ <param name="appenderList"></param>
+ <param name="container"></param>
+ </member>
+ <member name="M:log4net.Repository.Hierarchy.Hierarchy.log4net#Repository#IBasicRepositoryConfigurator#Configure(log4net.Appender.IAppender)">
+ <summary>
+ Initialize the log4net system using the specified appender
+ </summary>
+ <param name="appender">the appender to use to log all logging events</param>
+ </member>
+ <member name="M:log4net.Repository.Hierarchy.Hierarchy.BasicRepositoryConfigure(log4net.Appender.IAppender)">
+ <summary>
+ Initialize the log4net system using the specified appender
+ </summary>
+ <param name="appender">the appender to use to log all logging events</param>
+ <remarks>
+ <para>
+ This method provides the same functionality as the
+ <see cref="M:log4net.Repository.IBasicRepositoryConfigurator.Configure(log4net.Appender.IAppender)"/> method implemented
+ on this object, but it is protected and therefore can be called by subclasses.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Repository.Hierarchy.Hierarchy.log4net#Repository#IXmlRepositoryConfigurator#Configure(System.Xml.XmlElement)">
+ <summary>
+ Initialize the log4net system using the specified config
+ </summary>
+ <param name="element">the element containing the root of the config</param>
+ </member>
+ <member name="M:log4net.Repository.Hierarchy.Hierarchy.XmlRepositoryConfigure(System.Xml.XmlElement)">
+ <summary>
+ Initialize the log4net system using the specified config
+ </summary>
+ <param name="element">the element containing the root of the config</param>
+ <remarks>
+ <para>
+ This method provides the same functionality as the
+ <see cref="M:log4net.Repository.IBasicRepositoryConfigurator.Configure(log4net.Appender.IAppender)"/> method implemented
+ on this object, but it is protected and therefore can be called by subclasses.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Repository.Hierarchy.Hierarchy.IsDisabled(log4net.Core.Level)">
+ <summary>
+ Test if this hierarchy is disabled for the specified <see cref="T:log4net.Core.Level"/>.
+ </summary>
+ <param name="level">The level to check against.</param>
+ <returns>
+ <c>true</c> if the repository is disabled for the level argument, <c>false</c> otherwise.
+ </returns>
+ <remarks>
+ <para>
+ If this hierarchy has not been configured then this method will
+ always return <c>true</c>.
+ </para>
+ <para>
+ This method will return <c>true</c> if this repository is
+ disabled for <c>level</c> object passed as parameter and
+ <c>false</c> otherwise.
+ </para>
+ <para>
+ See also the <see cref="P:log4net.Repository.ILoggerRepository.Threshold"/> property.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Repository.Hierarchy.Hierarchy.Clear">
+ <summary>
+ Clear all logger definitions from the internal hashtable
+ </summary>
+ <remarks>
+ <para>
+ This call will clear all logger definitions from the internal
+ hashtable. Invoking this method will irrevocably mess up the
+ logger hierarchy.
+ </para>
+ <para>
+ You should <b>really</b> know what you are doing before
+ invoking this method.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Repository.Hierarchy.Hierarchy.GetLogger(System.String,log4net.Repository.Hierarchy.ILoggerFactory)">
+ <summary>
+ Return a new logger instance named as the first parameter using
+ <paramref name="factory"/>.
+ </summary>
+ <param name="name">The name of the logger to retrieve</param>
+ <param name="factory">The factory that will make the new logger instance</param>
+ <returns>The logger object with the name specified</returns>
+ <remarks>
+ <para>
+ If a logger of that name already exists, then it will be
+ returned. Otherwise, a new logger will be instantiated by the
+ <paramref name="factory"/> parameter and linked with its existing
+ ancestors as well as children.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Repository.Hierarchy.Hierarchy.OnLoggerCreationEvent(log4net.Repository.Hierarchy.Logger)">
+ <summary>
+ Sends a logger creation event to all registered listeners
+ </summary>
+ <param name="logger">The newly created logger</param>
+ <remarks>
+ Raises the logger creation event.
+ </remarks>
+ </member>
+ <member name="M:log4net.Repository.Hierarchy.Hierarchy.UpdateParents(log4net.Repository.Hierarchy.Logger)">
+ <summary>
+ Updates all the parents of the specified logger
+ </summary>
+ <param name="log">The logger to update the parents for</param>
+ <remarks>
+ <para>
+ This method loops through all the <i>potential</i> parents of
+ <paramref name="log"/>. There 3 possible cases:
+ </para>
+ <list type="number">
+ <item>
+ <term>No entry for the potential parent of <paramref name="log"/> exists</term>
+ <description>
+ We create a ProvisionNode for this potential
+ parent and insert <paramref name="log"/> in that provision node.
+ </description>
+ </item>
+ <item>
+ <term>The entry is of type Logger for the potential parent.</term>
+ <description>
+ The entry is <paramref name="log"/>'s nearest existing parent. We
+ update <paramref name="log"/>'s parent field with this entry. We also break from
+ he loop because updating our parent's parent is our parent's
+ responsibility.
+ </description>
+ </item>
+ <item>
+ <term>The entry is of type ProvisionNode for this potential parent.</term>
+ <description>
+ We add <paramref name="log"/> to the list of children for this
+ potential parent.
+ </description>
+ </item>
+ </list>
+ </remarks>
+ </member>
+ <member name="M:log4net.Repository.Hierarchy.Hierarchy.UpdateChildren(log4net.Repository.Hierarchy.ProvisionNode,log4net.Repository.Hierarchy.Logger)">
+ <summary>
+ Replace a <see cref="T:log4net.Repository.Hierarchy.ProvisionNode"/> with a <see cref="T:log4net.Repository.Hierarchy.Logger"/> in the hierarchy.
+ </summary>
+ <param name="pn"></param>
+ <param name="log"></param>
+ <remarks>
+ <para>
+ We update the links for all the children that placed themselves
+ in the provision node 'pn'. The second argument 'log' is a
+ reference for the newly created Logger, parent of all the
+ children in 'pn'.
+ </para>
+ <para>
+ We loop on all the children 'c' in 'pn'.
+ </para>
+ <para>
+ If the child 'c' has been already linked to a child of
+ 'log' then there is no need to update 'c'.
+ </para>
+ <para>
+ Otherwise, we set log's parent field to c's parent and set
+ c's parent field to log.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Repository.Hierarchy.Hierarchy.AddLevel(log4net.Repository.Hierarchy.Hierarchy.LevelEntry)">
+ <summary>
+ Define or redefine a Level using the values in the <see cref="T:log4net.Repository.Hierarchy.Hierarchy.LevelEntry"/> argument
+ </summary>
+ <param name="levelEntry">the level values</param>
+ <remarks>
+ <para>
+ Define or redefine a Level using the values in the <see cref="T:log4net.Repository.Hierarchy.Hierarchy.LevelEntry"/> argument
+ </para>
+ <para>
+ Supports setting levels via the configuration file.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Repository.Hierarchy.Hierarchy.AddProperty(log4net.Repository.Hierarchy.Hierarchy.PropertyEntry)">
+ <summary>
+ Set a Property using the values in the <see cref="T:log4net.Repository.Hierarchy.Hierarchy.LevelEntry"/> argument
+ </summary>
+ <param name="propertyEntry">the property value</param>
+ <remarks>
+ <para>
+ Set a Property using the values in the <see cref="T:log4net.Repository.Hierarchy.Hierarchy.LevelEntry"/> argument.
+ </para>
+ <para>
+ Supports setting property values via the configuration file.
+ </para>
+ </remarks>
+ </member>
+ <member name="E:log4net.Repository.Hierarchy.Hierarchy.LoggerCreatedEvent">
+ <summary>
+ Event used to notify that a logger has been created.
+ </summary>
+ <remarks>
+ <para>
+ Event raised when a logger is created.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Repository.Hierarchy.Hierarchy.EmittedNoAppenderWarning">
+ <summary>
+ Has no appender warning been emitted
+ </summary>
+ <remarks>
+ <para>
+ Flag to indicate if we have already issued a warning
+ about not having an appender warning.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Repository.Hierarchy.Hierarchy.Root">
+ <summary>
+ Get the root of this hierarchy
+ </summary>
+ <remarks>
+ <para>
+ Get the root of this hierarchy.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Repository.Hierarchy.Hierarchy.LoggerFactory">
+ <summary>
+ Gets or sets the default <see cref="T:log4net.Repository.Hierarchy.ILoggerFactory"/> instance.
+ </summary>
+ <value>The default <see cref="T:log4net.Repository.Hierarchy.ILoggerFactory"/></value>
+ <remarks>
+ <para>
+ The logger factory is used to create logger instances.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Repository.Hierarchy.Hierarchy.LevelEntry">
+ <summary>
+ A class to hold the value, name and display name for a level
+ </summary>
+ <remarks>
+ <para>
+ A class to hold the value, name and display name for a level
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Repository.Hierarchy.Hierarchy.LevelEntry.ToString">
+ <summary>
+ Override <c>Object.ToString</c> to return sensible debug info
+ </summary>
+ <returns>string info about this object</returns>
+ </member>
+ <member name="P:log4net.Repository.Hierarchy.Hierarchy.LevelEntry.Value">
+ <summary>
+ Value of the level
+ </summary>
+ <remarks>
+ <para>
+ If the value is not set (defaults to -1) the value will be looked
+ up for the current level with the same name.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Repository.Hierarchy.Hierarchy.LevelEntry.Name">
+ <summary>
+ Name of the level
+ </summary>
+ <value>
+ The name of the level
+ </value>
+ <remarks>
+ <para>
+ The name of the level.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Repository.Hierarchy.Hierarchy.LevelEntry.DisplayName">
+ <summary>
+ Display name for the level
+ </summary>
+ <value>
+ The display name of the level
+ </value>
+ <remarks>
+ <para>
+ The display name of the level.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Repository.Hierarchy.Hierarchy.PropertyEntry">
+ <summary>
+ A class to hold the key and data for a property set in the config file
+ </summary>
+ <remarks>
+ <para>
+ A class to hold the key and data for a property set in the config file
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Repository.Hierarchy.Hierarchy.PropertyEntry.ToString">
+ <summary>
+ Override <c>Object.ToString</c> to return sensible debug info
+ </summary>
+ <returns>string info about this object</returns>
+ </member>
+ <member name="P:log4net.Repository.Hierarchy.Hierarchy.PropertyEntry.Key">
+ <summary>
+ Property Key
+ </summary>
+ <value>
+ Property Key
+ </value>
+ <remarks>
+ <para>
+ Property Key.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Repository.Hierarchy.Hierarchy.PropertyEntry.Value">
+ <summary>
+ Property Value
+ </summary>
+ <value>
+ Property Value
+ </value>
+ <remarks>
+ <para>
+ Property Value.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Repository.Hierarchy.LoggerKey">
+ <summary>
+ Used internally to accelerate hash table searches.
+ </summary>
+ <remarks>
+ <para>
+ Internal class used to improve performance of
+ string keyed hashtables.
+ </para>
+ <para>
+ The hashcode of the string is cached for reuse.
+ The string is stored as an interned value.
+ When comparing two <see cref="T:log4net.Repository.Hierarchy.LoggerKey"/> objects for equality
+ the reference equality of the interned strings is compared.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="M:log4net.Repository.Hierarchy.LoggerKey.#ctor(System.String)">
+ <summary>
+ Construct key with string name
+ </summary>
+ <remarks>
+ <para>
+ Initializes a new instance of the <see cref="T:log4net.Repository.Hierarchy.LoggerKey"/> class
+ with the specified name.
+ </para>
+ <para>
+ Stores the hashcode of the string and interns
+ the string key to optimize comparisons.
+ </para>
+ <note>
+ The Compact Framework 1.0 the <see cref="M:System.String.Intern(System.String)"/>
+ method does not work. On the Compact Framework
+ the string keys are not interned nor are they
+ compared by reference.
+ </note>
+ </remarks>
+ <param name="name">The name of the logger.</param>
+ </member>
+ <member name="M:log4net.Repository.Hierarchy.LoggerKey.GetHashCode">
+ <summary>
+ Returns a hash code for the current instance.
+ </summary>
+ <returns>A hash code for the current instance.</returns>
+ <remarks>
+ <para>
+ Returns the cached hashcode.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Repository.Hierarchy.LoggerKey.Equals(System.Object)">
+ <summary>
+ Determines whether two <see cref="T:log4net.Repository.Hierarchy.LoggerKey"/> instances
+ are equal.
+ </summary>
+ <param name="obj">The <see cref="T:System.Object"/> to compare with the current <see cref="T:log4net.Repository.Hierarchy.LoggerKey"/>.</param>
+ <returns>
+ <c>true</c> if the specified <see cref="T:System.Object"/> is equal to the current <see cref="T:log4net.Repository.Hierarchy.LoggerKey"/>; otherwise, <c>false</c>.
+ </returns>
+ <remarks>
+ <para>
+ Compares the references of the interned strings.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Repository.Hierarchy.ProvisionNode">
+ <summary>
+ Provision nodes are used where no logger instance has been specified
+ </summary>
+ <remarks>
+ <para>
+ <see cref="T:log4net.Repository.Hierarchy.ProvisionNode"/> instances are used in the
+ <see cref="T:log4net.Repository.Hierarchy.Hierarchy"/> when there is no specified
+ <see cref="T:log4net.Repository.Hierarchy.Logger"/> for that node.
+ </para>
+ <para>
+ A provision node holds a list of child loggers on behalf of
+ a logger that does not exist.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="M:log4net.Repository.Hierarchy.ProvisionNode.#ctor(log4net.Repository.Hierarchy.Logger)">
+ <summary>
+ Create a new provision node with child node
+ </summary>
+ <param name="log">A child logger to add to this node.</param>
+ <remarks>
+ <para>
+ Initializes a new instance of the <see cref="T:log4net.Repository.Hierarchy.ProvisionNode"/> class
+ with the specified child logger.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Repository.Hierarchy.RootLogger">
+ <summary>
+ The <see cref="T:log4net.Repository.Hierarchy.RootLogger"/> sits at the root of the logger hierarchy tree.
+ </summary>
+ <remarks>
+ <para>
+ The <see cref="T:log4net.Repository.Hierarchy.RootLogger"/> is a regular <see cref="T:log4net.Repository.Hierarchy.Logger"/> except
+ that it provides several guarantees.
+ </para>
+ <para>
+ First, it cannot be assigned a <c>null</c>
+ level. Second, since the root logger cannot have a parent, the
+ <see cref="P:log4net.Repository.Hierarchy.RootLogger.EffectiveLevel"/> property always returns the value of the
+ level field without walking the hierarchy.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="M:log4net.Repository.Hierarchy.RootLogger.#ctor(log4net.Core.Level)">
+ <summary>
+ Construct a <see cref="T:log4net.Repository.Hierarchy.RootLogger"/>
+ </summary>
+ <param name="level">The level to assign to the root logger.</param>
+ <remarks>
+ <para>
+ Initializes a new instance of the <see cref="T:log4net.Repository.Hierarchy.RootLogger"/> class with
+ the specified logging level.
+ </para>
+ <para>
+ The root logger names itself as "root". However, the root
+ logger cannot be retrieved by name.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Repository.Hierarchy.RootLogger.EffectiveLevel">
+ <summary>
+ Gets the assigned level value without walking the logger hierarchy.
+ </summary>
+ <value>The assigned level value without walking the logger hierarchy.</value>
+ <remarks>
+ <para>
+ Because the root logger cannot have a parent and its level
+ must not be <c>null</c> this property just returns the
+ value of <see cref="P:log4net.Repository.Hierarchy.Logger.Level"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Repository.Hierarchy.RootLogger.Level">
+ <summary>
+ Gets or sets the assigned <see cref="P:log4net.Repository.Hierarchy.RootLogger.Level"/> for the root logger.
+ </summary>
+ <value>
+ The <see cref="P:log4net.Repository.Hierarchy.RootLogger.Level"/> of the root logger.
+ </value>
+ <remarks>
+ <para>
+ Setting the level of the root logger to a <c>null</c> reference
+ may have catastrophic results. We prevent this here.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Repository.Hierarchy.XmlHierarchyConfigurator">
+ <summary>
+ Initializes the log4net environment using an XML DOM.
+ </summary>
+ <remarks>
+ <para>
+ Configures a <see cref="T:log4net.Repository.Hierarchy.Hierarchy"/> using an XML DOM.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="M:log4net.Repository.Hierarchy.XmlHierarchyConfigurator.#ctor(log4net.Repository.Hierarchy.Hierarchy)">
+ <summary>
+ Construct the configurator for a hierarchy
+ </summary>
+ <param name="hierarchy">The hierarchy to build.</param>
+ <remarks>
+ <para>
+ Initializes a new instance of the <see cref="T:log4net.Repository.Hierarchy.XmlHierarchyConfigurator"/> class
+ with the specified <see cref="T:log4net.Repository.Hierarchy.Hierarchy"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Repository.Hierarchy.XmlHierarchyConfigurator.Configure(System.Xml.XmlElement)">
+ <summary>
+ Configure the hierarchy by parsing a DOM tree of XML elements.
+ </summary>
+ <param name="element">The root element to parse.</param>
+ <remarks>
+ <para>
+ Configure the hierarchy by parsing a DOM tree of XML elements.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Repository.Hierarchy.XmlHierarchyConfigurator.FindAppenderByReference(System.Xml.XmlElement)">
+ <summary>
+ Parse appenders by IDREF.
+ </summary>
+ <param name="appenderRef">The appender ref element.</param>
+ <returns>The instance of the appender that the ref refers to.</returns>
+ <remarks>
+ <para>
+ Parse an XML element that represents an appender and return
+ the appender.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Repository.Hierarchy.XmlHierarchyConfigurator.ParseAppender(System.Xml.XmlElement)">
+ <summary>
+ Parses an appender element.
+ </summary>
+ <param name="appenderElement">The appender element.</param>
+ <returns>The appender instance or <c>null</c> when parsing failed.</returns>
+ <remarks>
+ <para>
+ Parse an XML element that represents an appender and return
+ the appender instance.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Repository.Hierarchy.XmlHierarchyConfigurator.ParseLogger(System.Xml.XmlElement)">
+ <summary>
+ Parses a logger element.
+ </summary>
+ <param name="loggerElement">The logger element.</param>
+ <remarks>
+ <para>
+ Parse an XML element that represents a logger.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Repository.Hierarchy.XmlHierarchyConfigurator.ParseRoot(System.Xml.XmlElement)">
+ <summary>
+ Parses the root logger element.
+ </summary>
+ <param name="rootElement">The root element.</param>
+ <remarks>
+ <para>
+ Parse an XML element that represents the root logger.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Repository.Hierarchy.XmlHierarchyConfigurator.ParseChildrenOfLoggerElement(System.Xml.XmlElement,log4net.Repository.Hierarchy.Logger,System.Boolean)">
+ <summary>
+ Parses the children of a logger element.
+ </summary>
+ <param name="catElement">The category element.</param>
+ <param name="log">The logger instance.</param>
+ <param name="isRoot">Flag to indicate if the logger is the root logger.</param>
+ <remarks>
+ <para>
+ Parse the child elements of a &lt;logger&gt; element.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Repository.Hierarchy.XmlHierarchyConfigurator.ParseRenderer(System.Xml.XmlElement)">
+ <summary>
+ Parses an object renderer.
+ </summary>
+ <param name="element">The renderer element.</param>
+ <remarks>
+ <para>
+ Parse an XML element that represents a renderer.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Repository.Hierarchy.XmlHierarchyConfigurator.ParseLevel(System.Xml.XmlElement,log4net.Repository.Hierarchy.Logger,System.Boolean)">
+ <summary>
+ Parses a level element.
+ </summary>
+ <param name="element">The level element.</param>
+ <param name="log">The logger object to set the level on.</param>
+ <param name="isRoot">Flag to indicate if the logger is the root logger.</param>
+ <remarks>
+ <para>
+ Parse an XML element that represents a level.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Repository.Hierarchy.XmlHierarchyConfigurator.SetParameter(System.Xml.XmlElement,System.Object)">
+ <summary>
+ Sets a parameter on an object.
+ </summary>
+ <param name="element">The parameter element.</param>
+ <param name="target">The object to set the parameter on.</param>
+ <remarks>
+ The parameter name must correspond to a writable property
+ on the object. The value of the parameter is a string,
+ therefore this function will attempt to set a string
+ property first. If unable to set a string property it
+ will inspect the property and its argument type. It will
+ attempt to call a static method called <c>Parse</c> on the
+ type of the property. This method will take a single
+ string argument and return a value that can be used to
+ set the property.
+ </remarks>
+ </member>
+ <member name="M:log4net.Repository.Hierarchy.XmlHierarchyConfigurator.HasAttributesOrElements(System.Xml.XmlElement)">
+ <summary>
+ Test if an element has no attributes or child elements
+ </summary>
+ <param name="element">the element to inspect</param>
+ <returns><c>true</c> if the element has any attributes or child elements, <c>false</c> otherwise</returns>
+ </member>
+ <member name="M:log4net.Repository.Hierarchy.XmlHierarchyConfigurator.IsTypeConstructible(System.Type)">
+ <summary>
+ Test if a <see cref="T:System.Type"/> is constructible with <c>Activator.CreateInstance</c>.
+ </summary>
+ <param name="type">the type to inspect</param>
+ <returns><c>true</c> if the type is creatable using a default constructor, <c>false</c> otherwise</returns>
+ </member>
+ <member name="M:log4net.Repository.Hierarchy.XmlHierarchyConfigurator.FindMethodInfo(System.Type,System.String)">
+ <summary>
+ Look for a method on the <paramref name="targetType"/> that matches the <paramref name="name"/> supplied
+ </summary>
+ <param name="targetType">the type that has the method</param>
+ <param name="name">the name of the method</param>
+ <returns>the method info found</returns>
+ <remarks>
+ <para>
+ The method must be a public instance method on the <paramref name="targetType"/>.
+ The method must be named <paramref name="name"/> or "Add" followed by <paramref name="name"/>.
+ The method must take a single parameter.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Repository.Hierarchy.XmlHierarchyConfigurator.ConvertStringTo(System.Type,System.String)">
+ <summary>
+ Converts a string value to a target type.
+ </summary>
+ <param name="type">The type of object to convert the string to.</param>
+ <param name="value">The string value to use as the value of the object.</param>
+ <returns>
+ <para>
+ An object of type <paramref name="type"/> with value <paramref name="value"/> or
+ <c>null</c> when the conversion could not be performed.
+ </para>
+ </returns>
+ </member>
+ <member name="M:log4net.Repository.Hierarchy.XmlHierarchyConfigurator.CreateObjectFromXml(System.Xml.XmlElement,System.Type,System.Type)">
+ <summary>
+ Creates an object as specified in XML.
+ </summary>
+ <param name="element">The XML element that contains the definition of the object.</param>
+ <param name="defaultTargetType">The object type to use if not explicitly specified.</param>
+ <param name="typeConstraint">The type that the returned object must be or must inherit from.</param>
+ <returns>The object or <c>null</c></returns>
+ <remarks>
+ <para>
+ Parse an XML element and create an object instance based on the configuration
+ data.
+ </para>
+ <para>
+ The type of the instance may be specified in the XML. If not
+ specified then the <paramref name="defaultTargetType"/> is used
+ as the type. However the type is specified it must support the
+ <paramref name="typeConstraint"/> type.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Repository.Hierarchy.XmlHierarchyConfigurator.m_appenderBag">
+ <summary>
+ key: appenderName, value: appender.
+ </summary>
+ </member>
+ <member name="F:log4net.Repository.Hierarchy.XmlHierarchyConfigurator.m_hierarchy">
+ <summary>
+ The Hierarchy being configured.
+ </summary>
+ </member>
+ <member name="T:log4net.Repository.LoggerRepositoryShutdownEventHandler">
+ <summary>
+ Delegate used to handle logger repository shutdown event notifications
+ </summary>
+ <param name="sender">The <see cref="T:log4net.Repository.ILoggerRepository"/> that is shutting down.</param>
+ <param name="e">Empty event args</param>
+ <remarks>
+ <para>
+ Delegate used to handle logger repository shutdown event notifications.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Repository.LoggerRepositoryConfigurationResetEventHandler">
+ <summary>
+ Delegate used to handle logger repository configuration reset event notifications
+ </summary>
+ <param name="sender">The <see cref="T:log4net.Repository.ILoggerRepository"/> that has had its configuration reset.</param>
+ <param name="e">Empty event args</param>
+ <remarks>
+ <para>
+ Delegate used to handle logger repository configuration reset event notifications.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Repository.LoggerRepositoryConfigurationChangedEventHandler">
+ <summary>
+ Delegate used to handle event notifications for logger repository configuration changes.
+ </summary>
+ <param name="sender">The <see cref="T:log4net.Repository.ILoggerRepository"/> that has had its configuration changed.</param>
+ <param name="e">Empty event arguments.</param>
+ <remarks>
+ <para>
+ Delegate used to handle event notifications for logger repository configuration changes.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Util.PatternStringConverters.AppDomainPatternConverter">
+ <summary>
+ Write the name of the current AppDomain to the output
+ </summary>
+ <remarks>
+ <para>
+ Write the name of the current AppDomain to the output writer
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="M:log4net.Util.PatternStringConverters.AppDomainPatternConverter.Convert(System.IO.TextWriter,System.Object)">
+ <summary>
+ Write the name of the current AppDomain to the output
+ </summary>
+ <param name="writer">the writer to write to</param>
+ <param name="state">null, state is not set</param>
+ <remarks>
+ <para>
+ Writes name of the current AppDomain to the output <paramref name="writer"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Util.PatternStringConverters.DatePatternConverter">
+ <summary>
+ Write the current date to the output
+ </summary>
+ <remarks>
+ <para>
+ Date pattern converter, uses a <see cref="T:log4net.DateFormatter.IDateFormatter"/> to format
+ the current date and time to the writer as a string.
+ </para>
+ <para>
+ The value of the <see cref="P:log4net.Util.PatternConverter.Option"/> determines
+ the formatting of the date. The following values are allowed:
+ <list type="definition">
+ <listheader>
+ <term>Option value</term>
+ <description>Output</description>
+ </listheader>
+ <item>
+ <term>ISO8601</term>
+ <description>
+ Uses the <see cref="T:log4net.DateFormatter.Iso8601DateFormatter"/> formatter.
+ Formats using the <c>"yyyy-MM-dd HH:mm:ss,fff"</c> pattern.
+ </description>
+ </item>
+ <item>
+ <term>DATE</term>
+ <description>
+ Uses the <see cref="T:log4net.DateFormatter.DateTimeDateFormatter"/> formatter.
+ Formats using the <c>"dd MMM yyyy HH:mm:ss,fff"</c> for example, <c>"06 Nov 1994 15:49:37,459"</c>.
+ </description>
+ </item>
+ <item>
+ <term>ABSOLUTE</term>
+ <description>
+ Uses the <see cref="T:log4net.DateFormatter.AbsoluteTimeDateFormatter"/> formatter.
+ Formats using the <c>"HH:mm:ss,fff"</c> for example, <c>"15:49:37,459"</c>.
+ </description>
+ </item>
+ <item>
+ <term>other</term>
+ <description>
+ Any other pattern string uses the <see cref="T:log4net.DateFormatter.SimpleDateFormatter"/> formatter.
+ This formatter passes the pattern string to the <see cref="T:System.DateTime"/>
+ <see cref="M:System.DateTime.ToString(System.String)"/> method.
+ For details on valid patterns see
+ <a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfsystemglobalizationdatetimeformatinfoclasstopic.asp">DateTimeFormatInfo Class</a>.
+ </description>
+ </item>
+ </list>
+ </para>
+ <para>
+ The date and time is in the local time zone and is rendered in that zone.
+ To output the time in Universal time see <see cref="T:log4net.Util.PatternStringConverters.UtcDatePatternConverter"/>.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="F:log4net.Util.PatternStringConverters.DatePatternConverter.m_dateFormatter">
+ <summary>
+ The <see cref="T:log4net.DateFormatter.IDateFormatter"/> used to render the date to a string
+ </summary>
+ <remarks>
+ <para>
+ The <see cref="T:log4net.DateFormatter.IDateFormatter"/> used to render the date to a string
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.PatternStringConverters.DatePatternConverter.ActivateOptions">
+ <summary>
+ Initialize the converter options
+ </summary>
+ <remarks>
+ <para>
+ This is part of the <see cref="T:log4net.Core.IOptionHandler"/> delayed object
+ activation scheme. The <see cref="M:log4net.Util.PatternStringConverters.DatePatternConverter.ActivateOptions"/> method must
+ be called on this object after the configuration properties have
+ been set. Until <see cref="M:log4net.Util.PatternStringConverters.DatePatternConverter.ActivateOptions"/> is called this
+ object is in an undefined state and must not be used.
+ </para>
+ <para>
+ If any of the configuration properties are modified then
+ <see cref="M:log4net.Util.PatternStringConverters.DatePatternConverter.ActivateOptions"/> must be called again.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.PatternStringConverters.DatePatternConverter.Convert(System.IO.TextWriter,System.Object)">
+ <summary>
+ Write the current date to the output
+ </summary>
+ <param name="writer"><see cref="T:System.IO.TextWriter"/> that will receive the formatted result.</param>
+ <param name="state">null, state is not set</param>
+ <remarks>
+ <para>
+ Pass the current date and time to the <see cref="T:log4net.DateFormatter.IDateFormatter"/>
+ for it to render it to the writer.
+ </para>
+ <para>
+ The date and time passed is in the local time zone.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Util.PatternStringConverters.EnvironmentPatternConverter">
+ <summary>
+ Write an environment variable to the output
+ </summary>
+ <remarks>
+ <para>
+ Write an environment variable to the output writer.
+ The value of the <see cref="P:log4net.Util.PatternConverter.Option"/> determines
+ the name of the variable to output.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="M:log4net.Util.PatternStringConverters.EnvironmentPatternConverter.Convert(System.IO.TextWriter,System.Object)">
+ <summary>
+ Write an environment variable to the output
+ </summary>
+ <param name="writer">the writer to write to</param>
+ <param name="state">null, state is not set</param>
+ <remarks>
+ <para>
+ Writes the environment variable to the output <paramref name="writer"/>.
+ The name of the environment variable to output must be set
+ using the <see cref="P:log4net.Util.PatternConverter.Option"/>
+ property.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Util.PatternStringConverters.IdentityPatternConverter">
+ <summary>
+ Write the current thread identity to the output
+ </summary>
+ <remarks>
+ <para>
+ Write the current thread identity to the output writer
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="M:log4net.Util.PatternStringConverters.IdentityPatternConverter.Convert(System.IO.TextWriter,System.Object)">
+ <summary>
+ Write the current thread identity to the output
+ </summary>
+ <param name="writer">the writer to write to</param>
+ <param name="state">null, state is not set</param>
+ <remarks>
+ <para>
+ Writes the current thread identity to the output <paramref name="writer"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Util.PatternStringConverters.LiteralPatternConverter">
+ <summary>
+ Pattern converter for literal string instances in the pattern
+ </summary>
+ <remarks>
+ <para>
+ Writes the literal string value specified in the
+ <see cref="P:log4net.Util.PatternConverter.Option"/> property to
+ the output.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="M:log4net.Util.PatternStringConverters.LiteralPatternConverter.SetNext(log4net.Util.PatternConverter)">
+ <summary>
+ Set the next converter in the chain
+ </summary>
+ <param name="pc">The next pattern converter in the chain</param>
+ <returns>The next pattern converter</returns>
+ <remarks>
+ <para>
+ Special case the building of the pattern converter chain
+ for <see cref="T:log4net.Util.PatternStringConverters.LiteralPatternConverter"/> instances. Two adjacent
+ literals in the pattern can be represented by a single combined
+ pattern converter. This implementation detects when a
+ <see cref="T:log4net.Util.PatternStringConverters.LiteralPatternConverter"/> is added to the chain
+ after this converter and combines its value with this converter's
+ literal value.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.PatternStringConverters.LiteralPatternConverter.Format(System.IO.TextWriter,System.Object)">
+ <summary>
+ Write the literal to the output
+ </summary>
+ <param name="writer">the writer to write to</param>
+ <param name="state">null, not set</param>
+ <remarks>
+ <para>
+ Override the formatting behavior to ignore the FormattingInfo
+ because we have a literal instead.
+ </para>
+ <para>
+ Writes the value of <see cref="P:log4net.Util.PatternConverter.Option"/>
+ to the output <paramref name="writer"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.PatternStringConverters.LiteralPatternConverter.Convert(System.IO.TextWriter,System.Object)">
+ <summary>
+ Convert this pattern into the rendered message
+ </summary>
+ <param name="writer"><see cref="T:System.IO.TextWriter"/> that will receive the formatted result.</param>
+ <param name="state">null, not set</param>
+ <remarks>
+ <para>
+ This method is not used.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Util.PatternStringConverters.NewLinePatternConverter">
+ <summary>
+ Writes a newline to the output
+ </summary>
+ <remarks>
+ <para>
+ Writes the system dependent line terminator to the output.
+ This behavior can be overridden by setting the <see cref="P:log4net.Util.PatternConverter.Option"/>:
+ </para>
+ <list type="definition">
+ <listheader>
+ <term>Option Value</term>
+ <description>Output</description>
+ </listheader>
+ <item>
+ <term>DOS</term>
+ <description>DOS or Windows line terminator <c>"\r\n"</c></description>
+ </item>
+ <item>
+ <term>UNIX</term>
+ <description>UNIX line terminator <c>"\n"</c></description>
+ </item>
+ </list>
+ </remarks>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="M:log4net.Util.PatternStringConverters.NewLinePatternConverter.ActivateOptions">
+ <summary>
+ Initialize the converter
+ </summary>
+ <remarks>
+ <para>
+ This is part of the <see cref="T:log4net.Core.IOptionHandler"/> delayed object
+ activation scheme. The <see cref="M:log4net.Util.PatternStringConverters.NewLinePatternConverter.ActivateOptions"/> method must
+ be called on this object after the configuration properties have
+ been set. Until <see cref="M:log4net.Util.PatternStringConverters.NewLinePatternConverter.ActivateOptions"/> is called this
+ object is in an undefined state and must not be used.
+ </para>
+ <para>
+ If any of the configuration properties are modified then
+ <see cref="M:log4net.Util.PatternStringConverters.NewLinePatternConverter.ActivateOptions"/> must be called again.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Util.PatternStringConverters.ProcessIdPatternConverter">
+ <summary>
+ Write the current process ID to the output
+ </summary>
+ <remarks>
+ <para>
+ Write the current process ID to the output writer
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="M:log4net.Util.PatternStringConverters.ProcessIdPatternConverter.Convert(System.IO.TextWriter,System.Object)">
+ <summary>
+ Write the current process ID to the output
+ </summary>
+ <param name="writer">the writer to write to</param>
+ <param name="state">null, state is not set</param>
+ <remarks>
+ <para>
+ Write the current process ID to the output <paramref name="writer"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Util.PatternStringConverters.PropertyPatternConverter">
+ <summary>
+ Property pattern converter
+ </summary>
+ <remarks>
+ <para>
+ This pattern converter reads the thread and global properties.
+ The thread properties take priority over global properties.
+ See <see cref="P:log4net.ThreadContext.Properties"/> for details of the
+ thread properties. See <see cref="P:log4net.GlobalContext.Properties"/> for
+ details of the global properties.
+ </para>
+ <para>
+ If the <see cref="P:log4net.Util.PatternConverter.Option"/> is specified then that will be used to
+ lookup a single property. If no <see cref="P:log4net.Util.PatternConverter.Option"/> is specified
+ then all properties will be dumped as a list of key value pairs.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="M:log4net.Util.PatternStringConverters.PropertyPatternConverter.Convert(System.IO.TextWriter,System.Object)">
+ <summary>
+ Write the property value to the output
+ </summary>
+ <param name="writer"><see cref="T:System.IO.TextWriter"/> that will receive the formatted result.</param>
+ <param name="state">null, state is not set</param>
+ <remarks>
+ <para>
+ Writes out the value of a named property. The property name
+ should be set in the <see cref="P:log4net.Util.PatternConverter.Option"/>
+ property.
+ </para>
+ <para>
+ If the <see cref="P:log4net.Util.PatternConverter.Option"/> is set to <c>null</c>
+ then all the properties are written as key value pairs.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Util.PatternStringConverters.RandomStringPatternConverter">
+ <summary>
+ A Pattern converter that generates a string of random characters
+ </summary>
+ <remarks>
+ <para>
+ The converter generates a string of random characters. By default
+ the string is length 4. This can be changed by setting the <see cref="P:log4net.Util.PatternConverter.Option"/>
+ to the string value of the length required.
+ </para>
+ <para>
+ The random characters in the string are limited to uppercase letters
+ and numbers only.
+ </para>
+ <para>
+ The random number generator used by this class is not cryptographically secure.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="F:log4net.Util.PatternStringConverters.RandomStringPatternConverter.s_random">
+ <summary>
+ Shared random number generator
+ </summary>
+ </member>
+ <member name="F:log4net.Util.PatternStringConverters.RandomStringPatternConverter.m_length">
+ <summary>
+ Length of random string to generate. Default length 4.
+ </summary>
+ </member>
+ <member name="M:log4net.Util.PatternStringConverters.RandomStringPatternConverter.ActivateOptions">
+ <summary>
+ Initialize the converter options
+ </summary>
+ <remarks>
+ <para>
+ This is part of the <see cref="T:log4net.Core.IOptionHandler"/> delayed object
+ activation scheme. The <see cref="M:log4net.Util.PatternStringConverters.RandomStringPatternConverter.ActivateOptions"/> method must
+ be called on this object after the configuration properties have
+ been set. Until <see cref="M:log4net.Util.PatternStringConverters.RandomStringPatternConverter.ActivateOptions"/> is called this
+ object is in an undefined state and must not be used.
+ </para>
+ <para>
+ If any of the configuration properties are modified then
+ <see cref="M:log4net.Util.PatternStringConverters.RandomStringPatternConverter.ActivateOptions"/> must be called again.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.PatternStringConverters.RandomStringPatternConverter.Convert(System.IO.TextWriter,System.Object)">
+ <summary>
+ Write a randoim string to the output
+ </summary>
+ <param name="writer">the writer to write to</param>
+ <param name="state">null, state is not set</param>
+ <remarks>
+ <para>
+ Write a randoim string to the output <paramref name="writer"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Util.PatternStringConverters.UserNamePatternConverter">
+ <summary>
+ Write the current threads username to the output
+ </summary>
+ <remarks>
+ <para>
+ Write the current threads username to the output writer
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="M:log4net.Util.PatternStringConverters.UserNamePatternConverter.Convert(System.IO.TextWriter,System.Object)">
+ <summary>
+ Write the current threads username to the output
+ </summary>
+ <param name="writer">the writer to write to</param>
+ <param name="state">null, state is not set</param>
+ <remarks>
+ <para>
+ Write the current threads username to the output <paramref name="writer"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Util.PatternStringConverters.UtcDatePatternConverter">
+ <summary>
+ Write the UTC date time to the output
+ </summary>
+ <remarks>
+ <para>
+ Date pattern converter, uses a <see cref="T:log4net.DateFormatter.IDateFormatter"/> to format
+ the current date and time in Universal time.
+ </para>
+ <para>
+ See the <see cref="T:log4net.Util.PatternStringConverters.DatePatternConverter"/> for details on the date pattern syntax.
+ </para>
+ </remarks>
+ <seealso cref="T:log4net.Util.PatternStringConverters.DatePatternConverter"/>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="M:log4net.Util.PatternStringConverters.UtcDatePatternConverter.Convert(System.IO.TextWriter,System.Object)">
+ <summary>
+ Write the current date and time to the output
+ </summary>
+ <param name="writer"><see cref="T:System.IO.TextWriter"/> that will receive the formatted result.</param>
+ <param name="state">null, state is not set</param>
+ <remarks>
+ <para>
+ Pass the current date and time to the <see cref="T:log4net.DateFormatter.IDateFormatter"/>
+ for it to render it to the writer.
+ </para>
+ <para>
+ The date is in Universal time when it is rendered.
+ </para>
+ </remarks>
+ <seealso cref="T:log4net.Util.PatternStringConverters.DatePatternConverter"/>
+ </member>
+ <member name="T:log4net.Util.TypeConverters.BooleanConverter">
+ <summary>
+ Type converter for Boolean.
+ </summary>
+ <remarks>
+ <para>
+ Supports conversion from string to <c>bool</c> type.
+ </para>
+ </remarks>
+ <seealso cref="T:log4net.Util.TypeConverters.ConverterRegistry"/>
+ <seealso cref="T:log4net.Util.TypeConverters.IConvertFrom"/>
+ <seealso cref="T:log4net.Util.TypeConverters.IConvertTo"/>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="M:log4net.Util.TypeConverters.BooleanConverter.CanConvertFrom(System.Type)">
+ <summary>
+ Can the source type be converted to the type supported by this object
+ </summary>
+ <param name="sourceType">the type to convert</param>
+ <returns>true if the conversion is possible</returns>
+ <remarks>
+ <para>
+ Returns <c>true</c> if the <paramref name="sourceType"/> is
+ the <see cref="T:System.String"/> type.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.TypeConverters.BooleanConverter.ConvertFrom(System.Object)">
+ <summary>
+ Convert the source object to the type supported by this object
+ </summary>
+ <param name="source">the object to convert</param>
+ <returns>the converted object</returns>
+ <remarks>
+ <para>
+ Uses the <see cref="M:System.Boolean.Parse(System.String)"/> method to convert the
+ <see cref="T:System.String"/> argument to a <see cref="T:System.Boolean"/>.
+ </para>
+ </remarks>
+ <exception cref="T:log4net.Util.TypeConverters.ConversionNotSupportedException">
+ The <paramref name="source"/> object cannot be converted to the
+ target type. To check for this condition use the <see cref="M:log4net.Util.TypeConverters.BooleanConverter.CanConvertFrom(System.Type)"/>
+ method.
+ </exception>
+ </member>
+ <member name="T:log4net.Util.TypeConverters.ConversionNotSupportedException">
+ <summary>
+ Exception base type for conversion errors.
+ </summary>
+ <remarks>
+ <para>
+ This type extends <see cref="T:System.ApplicationException"/>. It
+ does not add any new functionality but does differentiate the
+ type of exception being thrown.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="M:log4net.Util.TypeConverters.ConversionNotSupportedException.#ctor">
+ <summary>
+ Constructor
+ </summary>
+ <remarks>
+ <para>
+ Initializes a new instance of the <see cref="T:log4net.Util.TypeConverters.ConversionNotSupportedException"/> class.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.TypeConverters.ConversionNotSupportedException.#ctor(System.String)">
+ <summary>
+ Constructor
+ </summary>
+ <param name="message">A message to include with the exception.</param>
+ <remarks>
+ <para>
+ Initializes a new instance of the <see cref="T:log4net.Util.TypeConverters.ConversionNotSupportedException"/> class
+ with the specified message.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.TypeConverters.ConversionNotSupportedException.#ctor(System.String,System.Exception)">
+ <summary>
+ Constructor
+ </summary>
+ <param name="message">A message to include with the exception.</param>
+ <param name="innerException">A nested exception to include.</param>
+ <remarks>
+ <para>
+ Initializes a new instance of the <see cref="T:log4net.Util.TypeConverters.ConversionNotSupportedException"/> class
+ with the specified message and inner exception.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.TypeConverters.ConversionNotSupportedException.#ctor(System.Runtime.Serialization.SerializationInfo,System.Runtime.Serialization.StreamingContext)">
+ <summary>
+ Serialization constructor
+ </summary>
+ <param name="info">The <see cref="T:System.Runtime.Serialization.SerializationInfo"/> that holds the serialized object data about the exception being thrown.</param>
+ <param name="context">The <see cref="T:System.Runtime.Serialization.StreamingContext"/> that contains contextual information about the source or destination.</param>
+ <remarks>
+ <para>
+ Initializes a new instance of the <see cref="T:log4net.Util.TypeConverters.ConversionNotSupportedException"/> class
+ with serialized data.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.TypeConverters.ConversionNotSupportedException.Create(System.Type,System.Object)">
+ <summary>
+ Creates a new instance of the <see cref="T:log4net.Util.TypeConverters.ConversionNotSupportedException"/> class.
+ </summary>
+ <param name="destinationType">The conversion destination type.</param>
+ <param name="sourceValue">The value to convert.</param>
+ <returns>An instance of the <see cref="T:log4net.Util.TypeConverters.ConversionNotSupportedException"/>.</returns>
+ <remarks>
+ <para>
+ Creates a new instance of the <see cref="T:log4net.Util.TypeConverters.ConversionNotSupportedException"/> class.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.TypeConverters.ConversionNotSupportedException.Create(System.Type,System.Object,System.Exception)">
+ <summary>
+ Creates a new instance of the <see cref="T:log4net.Util.TypeConverters.ConversionNotSupportedException"/> class.
+ </summary>
+ <param name="destinationType">The conversion destination type.</param>
+ <param name="sourceValue">The value to convert.</param>
+ <param name="innerException">A nested exception to include.</param>
+ <returns>An instance of the <see cref="T:log4net.Util.TypeConverters.ConversionNotSupportedException"/>.</returns>
+ <remarks>
+ <para>
+ Creates a new instance of the <see cref="T:log4net.Util.TypeConverters.ConversionNotSupportedException"/> class.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Util.TypeConverters.ConverterRegistry">
+ <summary>
+ Register of type converters for specific types.
+ </summary>
+ <remarks>
+ <para>
+ Maintains a registry of type converters used to convert between
+ types.
+ </para>
+ <para>
+ Use the <see cref="M:log4net.Util.TypeConverters.ConverterRegistry.AddConverter(System.Type,System.Object)"/> and
+ <see cref="M:log4net.Util.TypeConverters.ConverterRegistry.AddConverter(System.Type,System.Type)"/> methods to register new converters.
+ The <see cref="M:log4net.Util.TypeConverters.ConverterRegistry.GetConvertTo(System.Type,System.Type)"/> and <see cref="M:log4net.Util.TypeConverters.ConverterRegistry.GetConvertFrom(System.Type)"/> methods
+ lookup appropriate converters to use.
+ </para>
+ </remarks>
+ <seealso cref="T:log4net.Util.TypeConverters.IConvertFrom"/>
+ <seealso cref="T:log4net.Util.TypeConverters.IConvertTo"/>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="M:log4net.Util.TypeConverters.ConverterRegistry.#ctor">
+ <summary>
+ Private constructor
+ </summary>
+ <remarks>
+ Initializes a new instance of the <see cref="T:log4net.Util.TypeConverters.ConverterRegistry"/> class.
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.TypeConverters.ConverterRegistry.#cctor">
+ <summary>
+ Static constructor.
+ </summary>
+ <remarks>
+ <para>
+ This constructor defines the intrinsic type converters.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.TypeConverters.ConverterRegistry.AddConverter(System.Type,System.Object)">
+ <summary>
+ Adds a converter for a specific type.
+ </summary>
+ <param name="destinationType">The type being converted to.</param>
+ <param name="converter">The type converter to use to convert to the destination type.</param>
+ <remarks>
+ <para>
+ Adds a converter instance for a specific type.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.TypeConverters.ConverterRegistry.AddConverter(System.Type,System.Type)">
+ <summary>
+ Adds a converter for a specific type.
+ </summary>
+ <param name="destinationType">The type being converted to.</param>
+ <param name="converterType">The type of the type converter to use to convert to the destination type.</param>
+ <remarks>
+ <para>
+ Adds a converter <see cref="T:System.Type"/> for a specific type.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.TypeConverters.ConverterRegistry.GetConvertTo(System.Type,System.Type)">
+ <summary>
+ Gets the type converter to use to convert values to the destination type.
+ </summary>
+ <param name="sourceType">The type being converted from.</param>
+ <param name="destinationType">The type being converted to.</param>
+ <returns>
+ The type converter instance to use for type conversions or <c>null</c>
+ if no type converter is found.
+ </returns>
+ <remarks>
+ <para>
+ Gets the type converter to use to convert values to the destination type.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.TypeConverters.ConverterRegistry.GetConvertFrom(System.Type)">
+ <summary>
+ Gets the type converter to use to convert values to the destination type.
+ </summary>
+ <param name="destinationType">The type being converted to.</param>
+ <returns>
+ The type converter instance to use for type conversions or <c>null</c>
+ if no type converter is found.
+ </returns>
+ <remarks>
+ <para>
+ Gets the type converter to use to convert values to the destination type.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.TypeConverters.ConverterRegistry.GetConverterFromAttribute(System.Type)">
+ <summary>
+ Lookups the type converter to use as specified by the attributes on the
+ destination type.
+ </summary>
+ <param name="destinationType">The type being converted to.</param>
+ <returns>
+ The type converter instance to use for type conversions or <c>null</c>
+ if no type converter is found.
+ </returns>
+ </member>
+ <member name="M:log4net.Util.TypeConverters.ConverterRegistry.CreateConverterInstance(System.Type)">
+ <summary>
+ Creates the instance of the type converter.
+ </summary>
+ <param name="converterType">The type of the type converter.</param>
+ <returns>
+ The type converter instance to use for type conversions or <c>null</c>
+ if no type converter is found.
+ </returns>
+ <remarks>
+ <para>
+ The type specified for the type converter must implement
+ the <see cref="T:log4net.Util.TypeConverters.IConvertFrom"/> or <see cref="T:log4net.Util.TypeConverters.IConvertTo"/> interfaces
+ and must have a public default (no argument) constructor.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Util.TypeConverters.ConverterRegistry.s_type2converter">
+ <summary>
+ Mapping from <see cref="T:System.Type"/> to type converter.
+ </summary>
+ </member>
+ <member name="T:log4net.Util.TypeConverters.EncodingConverter">
+ <summary>
+ Supports conversion from string to <see cref="T:System.Text.Encoding"/> type.
+ </summary>
+ <remarks>
+ <para>
+ Supports conversion from string to <see cref="T:System.Text.Encoding"/> type.
+ </para>
+ </remarks>
+ <seealso cref="T:log4net.Util.TypeConverters.ConverterRegistry"/>
+ <seealso cref="T:log4net.Util.TypeConverters.IConvertFrom"/>
+ <seealso cref="T:log4net.Util.TypeConverters.IConvertTo"/>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="M:log4net.Util.TypeConverters.EncodingConverter.CanConvertFrom(System.Type)">
+ <summary>
+ Can the source type be converted to the type supported by this object
+ </summary>
+ <param name="sourceType">the type to convert</param>
+ <returns>true if the conversion is possible</returns>
+ <remarks>
+ <para>
+ Returns <c>true</c> if the <paramref name="sourceType"/> is
+ the <see cref="T:System.String"/> type.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.TypeConverters.EncodingConverter.ConvertFrom(System.Object)">
+ <summary>
+ Overrides the ConvertFrom method of IConvertFrom.
+ </summary>
+ <param name="source">the object to convert to an encoding</param>
+ <returns>the encoding</returns>
+ <remarks>
+ <para>
+ Uses the <see cref="M:System.Text.Encoding.GetEncoding(System.String)"/> method to
+ convert the <see cref="T:System.String"/> argument to an <see cref="T:System.Text.Encoding"/>.
+ </para>
+ </remarks>
+ <exception cref="T:log4net.Util.TypeConverters.ConversionNotSupportedException">
+ The <paramref name="source"/> object cannot be converted to the
+ target type. To check for this condition use the <see cref="M:log4net.Util.TypeConverters.EncodingConverter.CanConvertFrom(System.Type)"/>
+ method.
+ </exception>
+ </member>
+ <member name="T:log4net.Util.TypeConverters.IConvertTo">
+ <summary>
+ Interface supported by type converters
+ </summary>
+ <remarks>
+ <para>
+ This interface supports conversion from a single type to arbitrary types.
+ See <see cref="T:log4net.Util.TypeConverters.TypeConverterAttribute"/>.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="M:log4net.Util.TypeConverters.IConvertTo.CanConvertTo(System.Type)">
+ <summary>
+ Returns whether this converter can convert the object to the specified type
+ </summary>
+ <param name="targetType">A Type that represents the type you want to convert to</param>
+ <returns>true if the conversion is possible</returns>
+ <remarks>
+ <para>
+ Test if the type supported by this converter can be converted to the
+ <paramref name="targetType"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.TypeConverters.IConvertTo.ConvertTo(System.Object,System.Type)">
+ <summary>
+ Converts the given value object to the specified type, using the arguments
+ </summary>
+ <param name="source">the object to convert</param>
+ <param name="targetType">The Type to convert the value parameter to</param>
+ <returns>the converted object</returns>
+ <remarks>
+ <para>
+ Converts the <paramref name="source"/> (which must be of the type supported
+ by this converter) to the <paramref name="targetType"/> specified..
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Util.TypeConverters.IPAddressConverter">
+ <summary>
+ Supports conversion from string to <see cref="T:System.Net.IPAddress"/> type.
+ </summary>
+ <remarks>
+ <para>
+ Supports conversion from string to <see cref="T:System.Net.IPAddress"/> type.
+ </para>
+ </remarks>
+ <seealso cref="T:log4net.Util.TypeConverters.ConverterRegistry"/>
+ <seealso cref="T:log4net.Util.TypeConverters.IConvertFrom"/>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="M:log4net.Util.TypeConverters.IPAddressConverter.CanConvertFrom(System.Type)">
+ <summary>
+ Can the source type be converted to the type supported by this object
+ </summary>
+ <param name="sourceType">the type to convert</param>
+ <returns>true if the conversion is possible</returns>
+ <remarks>
+ <para>
+ Returns <c>true</c> if the <paramref name="sourceType"/> is
+ the <see cref="T:System.String"/> type.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.TypeConverters.IPAddressConverter.ConvertFrom(System.Object)">
+ <summary>
+ Overrides the ConvertFrom method of IConvertFrom.
+ </summary>
+ <param name="source">the object to convert to an IPAddress</param>
+ <returns>the IPAddress</returns>
+ <remarks>
+ <para>
+ Uses the <see cref="M:System.Net.IPAddress.Parse(System.String)"/> method to convert the
+ <see cref="T:System.String"/> argument to an <see cref="T:System.Net.IPAddress"/>.
+ If that fails then the string is resolved as a DNS hostname.
+ </para>
+ </remarks>
+ <exception cref="T:log4net.Util.TypeConverters.ConversionNotSupportedException">
+ The <paramref name="source"/> object cannot be converted to the
+ target type. To check for this condition use the <see cref="M:log4net.Util.TypeConverters.IPAddressConverter.CanConvertFrom(System.Type)"/>
+ method.
+ </exception>
+ </member>
+ <member name="F:log4net.Util.TypeConverters.IPAddressConverter.validIpAddressChars">
+ <summary>
+ Valid characters in an IPv4 or IPv6 address string. (Does not support subnets)
+ </summary>
+ </member>
+ <member name="T:log4net.Util.TypeConverters.PatternLayoutConverter">
+ <summary>
+ Supports conversion from string to <see cref="T:log4net.Layout.PatternLayout"/> type.
+ </summary>
+ <remarks>
+ <para>
+ Supports conversion from string to <see cref="T:log4net.Layout.PatternLayout"/> type.
+ </para>
+ <para>
+ The string is used as the <see cref="P:log4net.Layout.PatternLayout.ConversionPattern"/>
+ of the <see cref="T:log4net.Layout.PatternLayout"/>.
+ </para>
+ </remarks>
+ <seealso cref="T:log4net.Util.TypeConverters.ConverterRegistry"/>
+ <seealso cref="T:log4net.Util.TypeConverters.IConvertFrom"/>
+ <seealso cref="T:log4net.Util.TypeConverters.IConvertTo"/>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="M:log4net.Util.TypeConverters.PatternLayoutConverter.CanConvertFrom(System.Type)">
+ <summary>
+ Can the source type be converted to the type supported by this object
+ </summary>
+ <param name="sourceType">the type to convert</param>
+ <returns>true if the conversion is possible</returns>
+ <remarks>
+ <para>
+ Returns <c>true</c> if the <paramref name="sourceType"/> is
+ the <see cref="T:System.String"/> type.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.TypeConverters.PatternLayoutConverter.ConvertFrom(System.Object)">
+ <summary>
+ Overrides the ConvertFrom method of IConvertFrom.
+ </summary>
+ <param name="source">the object to convert to a PatternLayout</param>
+ <returns>the PatternLayout</returns>
+ <remarks>
+ <para>
+ Creates and returns a new <see cref="T:log4net.Layout.PatternLayout"/> using
+ the <paramref name="source"/> <see cref="T:System.String"/> as the
+ <see cref="P:log4net.Layout.PatternLayout.ConversionPattern"/>.
+ </para>
+ </remarks>
+ <exception cref="T:log4net.Util.TypeConverters.ConversionNotSupportedException">
+ The <paramref name="source"/> object cannot be converted to the
+ target type. To check for this condition use the <see cref="M:log4net.Util.TypeConverters.PatternLayoutConverter.CanConvertFrom(System.Type)"/>
+ method.
+ </exception>
+ </member>
+ <member name="T:log4net.Util.TypeConverters.PatternStringConverter">
+ <summary>
+ Convert between string and <see cref="T:log4net.Util.PatternString"/>
+ </summary>
+ <remarks>
+ <para>
+ Supports conversion from string to <see cref="T:log4net.Util.PatternString"/> type,
+ and from a <see cref="T:log4net.Util.PatternString"/> type to a string.
+ </para>
+ <para>
+ The string is used as the <see cref="P:log4net.Util.PatternString.ConversionPattern"/>
+ of the <see cref="T:log4net.Util.PatternString"/>.
+ </para>
+ </remarks>
+ <seealso cref="T:log4net.Util.TypeConverters.ConverterRegistry"/>
+ <seealso cref="T:log4net.Util.TypeConverters.IConvertFrom"/>
+ <seealso cref="T:log4net.Util.TypeConverters.IConvertTo"/>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="M:log4net.Util.TypeConverters.PatternStringConverter.CanConvertTo(System.Type)">
+ <summary>
+ Can the target type be converted to the type supported by this object
+ </summary>
+ <param name="targetType">A <see cref="T:System.Type"/> that represents the type you want to convert to</param>
+ <returns>true if the conversion is possible</returns>
+ <remarks>
+ <para>
+ Returns <c>true</c> if the <paramref name="targetType"/> is
+ assignable from a <see cref="T:System.String"/> type.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.TypeConverters.PatternStringConverter.ConvertTo(System.Object,System.Type)">
+ <summary>
+ Converts the given value object to the specified type, using the arguments
+ </summary>
+ <param name="source">the object to convert</param>
+ <param name="targetType">The Type to convert the value parameter to</param>
+ <returns>the converted object</returns>
+ <remarks>
+ <para>
+ Uses the <see cref="M:log4net.Util.PatternString.Format"/> method to convert the
+ <see cref="T:log4net.Util.PatternString"/> argument to a <see cref="T:System.String"/>.
+ </para>
+ </remarks>
+ <exception cref="T:log4net.Util.TypeConverters.ConversionNotSupportedException">
+ The <paramref name="source"/> object cannot be converted to the
+ <paramref name="targetType"/>. To check for this condition use the
+ <see cref="M:log4net.Util.TypeConverters.PatternStringConverter.CanConvertTo(System.Type)"/> method.
+ </exception>
+ </member>
+ <member name="M:log4net.Util.TypeConverters.PatternStringConverter.CanConvertFrom(System.Type)">
+ <summary>
+ Can the source type be converted to the type supported by this object
+ </summary>
+ <param name="sourceType">the type to convert</param>
+ <returns>true if the conversion is possible</returns>
+ <remarks>
+ <para>
+ Returns <c>true</c> if the <paramref name="sourceType"/> is
+ the <see cref="T:System.String"/> type.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.TypeConverters.PatternStringConverter.ConvertFrom(System.Object)">
+ <summary>
+ Overrides the ConvertFrom method of IConvertFrom.
+ </summary>
+ <param name="source">the object to convert to a PatternString</param>
+ <returns>the PatternString</returns>
+ <remarks>
+ <para>
+ Creates and returns a new <see cref="T:log4net.Util.PatternString"/> using
+ the <paramref name="source"/> <see cref="T:System.String"/> as the
+ <see cref="P:log4net.Util.PatternString.ConversionPattern"/>.
+ </para>
+ </remarks>
+ <exception cref="T:log4net.Util.TypeConverters.ConversionNotSupportedException">
+ The <paramref name="source"/> object cannot be converted to the
+ target type. To check for this condition use the <see cref="M:log4net.Util.TypeConverters.PatternStringConverter.CanConvertFrom(System.Type)"/>
+ method.
+ </exception>
+ </member>
+ <member name="T:log4net.Util.TypeConverters.TypeConverter">
+ <summary>
+ Supports conversion from string to <see cref="T:System.Type"/> type.
+ </summary>
+ <remarks>
+ <para>
+ Supports conversion from string to <see cref="T:System.Type"/> type.
+ </para>
+ </remarks>
+ <seealso cref="T:log4net.Util.TypeConverters.ConverterRegistry"/>
+ <seealso cref="T:log4net.Util.TypeConverters.IConvertFrom"/>
+ <seealso cref="T:log4net.Util.TypeConverters.IConvertTo"/>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="M:log4net.Util.TypeConverters.TypeConverter.CanConvertFrom(System.Type)">
+ <summary>
+ Can the source type be converted to the type supported by this object
+ </summary>
+ <param name="sourceType">the type to convert</param>
+ <returns>true if the conversion is possible</returns>
+ <remarks>
+ <para>
+ Returns <c>true</c> if the <paramref name="sourceType"/> is
+ the <see cref="T:System.String"/> type.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.TypeConverters.TypeConverter.ConvertFrom(System.Object)">
+ <summary>
+ Overrides the ConvertFrom method of IConvertFrom.
+ </summary>
+ <param name="source">the object to convert to a Type</param>
+ <returns>the Type</returns>
+ <remarks>
+ <para>
+ Uses the <see cref="M:System.Type.GetType(System.String,System.Boolean)"/> method to convert the
+ <see cref="T:System.String"/> argument to a <see cref="T:System.Type"/>.
+ Additional effort is made to locate partially specified types
+ by searching the loaded assemblies.
+ </para>
+ </remarks>
+ <exception cref="T:log4net.Util.TypeConverters.ConversionNotSupportedException">
+ The <paramref name="source"/> object cannot be converted to the
+ target type. To check for this condition use the <see cref="M:log4net.Util.TypeConverters.TypeConverter.CanConvertFrom(System.Type)"/>
+ method.
+ </exception>
+ </member>
+ <member name="T:log4net.Util.TypeConverters.TypeConverterAttribute">
+ <summary>
+ Attribute used to associate a type converter
+ </summary>
+ <remarks>
+ <para>
+ Class and Interface level attribute that specifies a type converter
+ to use with the associated type.
+ </para>
+ <para>
+ To associate a type converter with a target type apply a
+ <c>TypeConverterAttribute</c> to the target type. Specify the
+ type of the type converter on the attribute.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="F:log4net.Util.TypeConverters.TypeConverterAttribute.m_typeName">
+ <summary>
+ The string type name of the type converter
+ </summary>
+ </member>
+ <member name="M:log4net.Util.TypeConverters.TypeConverterAttribute.#ctor">
+ <summary>
+ Default constructor
+ </summary>
+ <remarks>
+ <para>
+ Default constructor
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.TypeConverters.TypeConverterAttribute.#ctor(System.String)">
+ <summary>
+ Create a new type converter attribute for the specified type name
+ </summary>
+ <param name="typeName">The string type name of the type converter</param>
+ <remarks>
+ <para>
+ The type specified must implement the <see cref="T:log4net.Util.TypeConverters.IConvertFrom"/>
+ or the <see cref="T:log4net.Util.TypeConverters.IConvertTo"/> interfaces.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.TypeConverters.TypeConverterAttribute.#ctor(System.Type)">
+ <summary>
+ Create a new type converter attribute for the specified type
+ </summary>
+ <param name="converterType">The type of the type converter</param>
+ <remarks>
+ <para>
+ The type specified must implement the <see cref="T:log4net.Util.TypeConverters.IConvertFrom"/>
+ or the <see cref="T:log4net.Util.TypeConverters.IConvertTo"/> interfaces.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Util.TypeConverters.TypeConverterAttribute.ConverterTypeName">
+ <summary>
+ The string type name of the type converter
+ </summary>
+ <value>
+ The string type name of the type converter
+ </value>
+ <remarks>
+ <para>
+ The type specified must implement the <see cref="T:log4net.Util.TypeConverters.IConvertFrom"/>
+ or the <see cref="T:log4net.Util.TypeConverters.IConvertTo"/> interfaces.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Util.AppenderAttachedImpl">
+ <summary>
+ A straightforward implementation of the <see cref="T:log4net.Core.IAppenderAttachable"/> interface.
+ </summary>
+ <remarks>
+ <para>
+ This is the default implementation of the <see cref="T:log4net.Core.IAppenderAttachable"/>
+ interface. Implementors of the <see cref="T:log4net.Core.IAppenderAttachable"/> interface
+ should aggregate an instance of this type.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="M:log4net.Util.AppenderAttachedImpl.#ctor">
+ <summary>
+ Constructor
+ </summary>
+ <remarks>
+ <para>
+ Initializes a new instance of the <see cref="T:log4net.Util.AppenderAttachedImpl"/> class.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.AppenderAttachedImpl.AppendLoopOnAppenders(log4net.Core.LoggingEvent)">
+ <summary>
+ Append on on all attached appenders.
+ </summary>
+ <param name="loggingEvent">The event being logged.</param>
+ <returns>The number of appenders called.</returns>
+ <remarks>
+ <para>
+ Calls the <see cref="M:log4net.Appender.IAppender.DoAppend(log4net.Core.LoggingEvent)"/> method on all
+ attached appenders.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.AppenderAttachedImpl.AppendLoopOnAppenders(log4net.Core.LoggingEvent[])">
+ <summary>
+ Append on on all attached appenders.
+ </summary>
+ <param name="loggingEvents">The array of events being logged.</param>
+ <returns>The number of appenders called.</returns>
+ <remarks>
+ <para>
+ Calls the <see cref="M:log4net.Appender.IAppender.DoAppend(log4net.Core.LoggingEvent)"/> method on all
+ attached appenders.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.AppenderAttachedImpl.CallAppend(log4net.Appender.IAppender,log4net.Core.LoggingEvent[])">
+ <summary>
+ Calls the DoAppende method on the <see cref="T:log4net.Appender.IAppender"/> with
+ the <see cref="T:log4net.Core.LoggingEvent"/> objects supplied.
+ </summary>
+ <param name="appender">The appender</param>
+ <param name="loggingEvents">The events</param>
+ <remarks>
+ <para>
+ If the <paramref name="appender"/> supports the <see cref="T:log4net.Appender.IBulkAppender"/>
+ interface then the <paramref name="loggingEvents"/> will be passed
+ through using that interface. Otherwise the <see cref="T:log4net.Core.LoggingEvent"/>
+ objects in the array will be passed one at a time.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.AppenderAttachedImpl.AddAppender(log4net.Appender.IAppender)">
+ <summary>
+ Attaches an appender.
+ </summary>
+ <param name="newAppender">The appender to add.</param>
+ <remarks>
+ <para>
+ If the appender is already in the list it won't be added again.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.AppenderAttachedImpl.GetAppender(System.String)">
+ <summary>
+ Gets an attached appender with the specified name.
+ </summary>
+ <param name="name">The name of the appender to get.</param>
+ <returns>
+ The appender with the name specified, or <c>null</c> if no appender with the
+ specified name is found.
+ </returns>
+ <remarks>
+ <para>
+ Lookup an attached appender by name.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.AppenderAttachedImpl.RemoveAllAppenders">
+ <summary>
+ Removes all attached appenders.
+ </summary>
+ <remarks>
+ <para>
+ Removes and closes all attached appenders
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.AppenderAttachedImpl.RemoveAppender(log4net.Appender.IAppender)">
+ <summary>
+ Removes the specified appender from the list of attached appenders.
+ </summary>
+ <param name="appender">The appender to remove.</param>
+ <returns>The appender removed from the list</returns>
+ <remarks>
+ <para>
+ The appender removed is not closed.
+ If you are discarding the appender you must call
+ <see cref="M:log4net.Appender.IAppender.Close"/> on the appender removed.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.AppenderAttachedImpl.RemoveAppender(System.String)">
+ <summary>
+ Removes the appender with the specified name from the list of appenders.
+ </summary>
+ <param name="name">The name of the appender to remove.</param>
+ <returns>The appender removed from the list</returns>
+ <remarks>
+ <para>
+ The appender removed is not closed.
+ If you are discarding the appender you must call
+ <see cref="M:log4net.Appender.IAppender.Close"/> on the appender removed.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Util.AppenderAttachedImpl.m_appenderList">
+ <summary>
+ List of appenders
+ </summary>
+ </member>
+ <member name="F:log4net.Util.AppenderAttachedImpl.m_appenderArray">
+ <summary>
+ Array of appenders, used to cache the m_appenderList
+ </summary>
+ </member>
+ <member name="P:log4net.Util.AppenderAttachedImpl.Appenders">
+ <summary>
+ Gets all attached appenders.
+ </summary>
+ <returns>
+ A collection of attached appenders, or <c>null</c> if there
+ are no attached appenders.
+ </returns>
+ <remarks>
+ <para>
+ The read only collection of all currently attached appenders.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Util.CompositeProperties">
+ <summary>
+ This class aggregates several PropertiesDictionary collections together.
+ </summary>
+ <remarks>
+ <para>
+ Provides a dictionary style lookup over an ordered list of
+ <see cref="T:log4net.Util.PropertiesDictionary"/> collections.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="M:log4net.Util.CompositeProperties.#ctor">
+ <summary>
+ Constructor
+ </summary>
+ <remarks>
+ <para>
+ Initializes a new instance of the <see cref="T:log4net.Util.CompositeProperties"/> class.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.CompositeProperties.Add(log4net.Util.ReadOnlyPropertiesDictionary)">
+ <summary>
+ Add a Properties Dictionary to this composite collection
+ </summary>
+ <param name="properties">the properties to add</param>
+ <remarks>
+ <para>
+ Properties dictionaries added first take precedence over dictionaries added
+ later.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.CompositeProperties.Flatten">
+ <summary>
+ Flatten this composite collection into a single properties dictionary
+ </summary>
+ <returns>the flattened dictionary</returns>
+ <remarks>
+ <para>
+ Reduces the collection of ordered dictionaries to a single dictionary
+ containing the resultant values for the keys.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Util.CompositeProperties.Item(System.String)">
+ <summary>
+ Gets the value of a property
+ </summary>
+ <value>
+ The value for the property with the specified key
+ </value>
+ <remarks>
+ <para>
+ Looks up the value for the <paramref name="key"/> specified.
+ The <see cref="T:log4net.Util.PropertiesDictionary"/> collections are searched
+ in the order in which they were added to this collection. The value
+ returned is the value held by the first collection that contains
+ the specified key.
+ </para>
+ <para>
+ If none of the collections contain the specified key then
+ <c>null</c> is returned.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Util.ContextPropertiesBase">
+ <summary>
+ Base class for Context Properties implementations
+ </summary>
+ <remarks>
+ <para>
+ This class defines a basic property get set accessor
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="P:log4net.Util.ContextPropertiesBase.Item(System.String)">
+ <summary>
+ Gets or sets the value of a property
+ </summary>
+ <value>
+ The value for the property with the specified key
+ </value>
+ <remarks>
+ <para>
+ Gets or sets the value of a property
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Util.CountingQuietTextWriter">
+ <summary>
+ Subclass of <see cref="T:log4net.Util.QuietTextWriter"/> that maintains a count of
+ the number of bytes written.
+ </summary>
+ <remarks>
+ <para>
+ This writer counts the number of bytes written.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="T:log4net.Util.QuietTextWriter">
+ <summary>
+ <see cref="T:System.IO.TextWriter"/> that does not leak exceptions
+ </summary>
+ <remarks>
+ <para>
+ <see cref="T:log4net.Util.QuietTextWriter"/> does not throw exceptions when things go wrong.
+ Instead, it delegates error handling to its <see cref="T:log4net.Core.IErrorHandler"/>.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="T:log4net.Util.TextWriterAdapter">
+ <summary>
+ Adapter that extends <see cref="T:System.IO.TextWriter"/> and forwards all
+ messages to an instance of <see cref="T:System.IO.TextWriter"/>.
+ </summary>
+ <remarks>
+ <para>
+ Adapter that extends <see cref="T:System.IO.TextWriter"/> and forwards all
+ messages to an instance of <see cref="T:System.IO.TextWriter"/>.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="F:log4net.Util.TextWriterAdapter.m_writer">
+ <summary>
+ The writer to forward messages to
+ </summary>
+ </member>
+ <member name="M:log4net.Util.TextWriterAdapter.#ctor(System.IO.TextWriter)">
+ <summary>
+ Create an instance of <see cref="T:log4net.Util.TextWriterAdapter"/> that forwards all
+ messages to a <see cref="T:System.IO.TextWriter"/>.
+ </summary>
+ <param name="writer">The <see cref="T:System.IO.TextWriter"/> to forward to</param>
+ <remarks>
+ <para>
+ Create an instance of <see cref="T:log4net.Util.TextWriterAdapter"/> that forwards all
+ messages to a <see cref="T:System.IO.TextWriter"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.TextWriterAdapter.Close">
+ <summary>
+ Closes the writer and releases any system resources associated with the writer
+ </summary>
+ <remarks>
+ <para>
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.TextWriterAdapter.Dispose(System.Boolean)">
+ <summary>
+ Dispose this writer
+ </summary>
+ <param name="disposing">flag indicating if we are being disposed</param>
+ <remarks>
+ <para>
+ Dispose this writer
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.TextWriterAdapter.Flush">
+ <summary>
+ Flushes any buffered output
+ </summary>
+ <remarks>
+ <para>
+ Clears all buffers for the writer and causes any buffered data to be written
+ to the underlying device
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.TextWriterAdapter.Write(System.Char)">
+ <summary>
+ Writes a character to the wrapped TextWriter
+ </summary>
+ <param name="value">the value to write to the TextWriter</param>
+ <remarks>
+ <para>
+ Writes a character to the wrapped TextWriter
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.TextWriterAdapter.Write(System.Char[],System.Int32,System.Int32)">
+ <summary>
+ Writes a character buffer to the wrapped TextWriter
+ </summary>
+ <param name="buffer">the data buffer</param>
+ <param name="index">the start index</param>
+ <param name="count">the number of characters to write</param>
+ <remarks>
+ <para>
+ Writes a character buffer to the wrapped TextWriter
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.TextWriterAdapter.Write(System.String)">
+ <summary>
+ Writes a string to the wrapped TextWriter
+ </summary>
+ <param name="value">the value to write to the TextWriter</param>
+ <remarks>
+ <para>
+ Writes a string to the wrapped TextWriter
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Util.TextWriterAdapter.Writer">
+ <summary>
+ Gets or sets the underlying <see cref="T:System.IO.TextWriter"/>.
+ </summary>
+ <value>
+ The underlying <see cref="T:System.IO.TextWriter"/>.
+ </value>
+ <remarks>
+ <para>
+ Gets or sets the underlying <see cref="T:System.IO.TextWriter"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Util.TextWriterAdapter.Encoding">
+ <summary>
+ The Encoding in which the output is written
+ </summary>
+ <value>
+ The <see cref="P:log4net.Util.TextWriterAdapter.Encoding"/>
+ </value>
+ <remarks>
+ <para>
+ The Encoding in which the output is written
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Util.TextWriterAdapter.FormatProvider">
+ <summary>
+ Gets an object that controls formatting
+ </summary>
+ <value>
+ The format provider
+ </value>
+ <remarks>
+ <para>
+ Gets an object that controls formatting
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Util.TextWriterAdapter.NewLine">
+ <summary>
+ Gets or sets the line terminator string used by the TextWriter
+ </summary>
+ <value>
+ The line terminator to use
+ </value>
+ <remarks>
+ <para>
+ Gets or sets the line terminator string used by the TextWriter
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.QuietTextWriter.#ctor(System.IO.TextWriter,log4net.Core.IErrorHandler)">
+ <summary>
+ Constructor
+ </summary>
+ <param name="writer">the writer to actually write to</param>
+ <param name="errorHandler">the error handler to report error to</param>
+ <remarks>
+ <para>
+ Create a new QuietTextWriter using a writer and error handler
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.QuietTextWriter.Write(System.Char)">
+ <summary>
+ Writes a character to the underlying writer
+ </summary>
+ <param name="value">the char to write</param>
+ <remarks>
+ <para>
+ Writes a character to the underlying writer
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.QuietTextWriter.Write(System.Char[],System.Int32,System.Int32)">
+ <summary>
+ Writes a buffer to the underlying writer
+ </summary>
+ <param name="buffer">the buffer to write</param>
+ <param name="index">the start index to write from</param>
+ <param name="count">the number of characters to write</param>
+ <remarks>
+ <para>
+ Writes a buffer to the underlying writer
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.QuietTextWriter.Write(System.String)">
+ <summary>
+ Writes a string to the output.
+ </summary>
+ <param name="value">The string data to write to the output.</param>
+ <remarks>
+ <para>
+ Writes a string to the output.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.QuietTextWriter.Close">
+ <summary>
+ Closes the underlying output writer.
+ </summary>
+ <remarks>
+ <para>
+ Closes the underlying output writer.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Util.QuietTextWriter.m_errorHandler">
+ <summary>
+ The error handler instance to pass all errors to
+ </summary>
+ </member>
+ <member name="F:log4net.Util.QuietTextWriter.m_closed">
+ <summary>
+ Flag to indicate if this writer is closed
+ </summary>
+ </member>
+ <member name="P:log4net.Util.QuietTextWriter.ErrorHandler">
+ <summary>
+ Gets or sets the error handler that all errors are passed to.
+ </summary>
+ <value>
+ The error handler that all errors are passed to.
+ </value>
+ <remarks>
+ <para>
+ Gets or sets the error handler that all errors are passed to.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Util.QuietTextWriter.Closed">
+ <summary>
+ Gets a value indicating whether this writer is closed.
+ </summary>
+ <value>
+ <c>true</c> if this writer is closed, otherwise <c>false</c>.
+ </value>
+ <remarks>
+ <para>
+ Gets a value indicating whether this writer is closed.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.CountingQuietTextWriter.#ctor(System.IO.TextWriter,log4net.Core.IErrorHandler)">
+ <summary>
+ Constructor
+ </summary>
+ <param name="writer">The <see cref="T:System.IO.TextWriter"/> to actually write to.</param>
+ <param name="errorHandler">The <see cref="T:log4net.Core.IErrorHandler"/> to report errors to.</param>
+ <remarks>
+ <para>
+ Creates a new instance of the <see cref="T:log4net.Util.CountingQuietTextWriter"/> class
+ with the specified <see cref="T:System.IO.TextWriter"/> and <see cref="T:log4net.Core.IErrorHandler"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.CountingQuietTextWriter.Write(System.Char)">
+ <summary>
+ Writes a character to the underlying writer and counts the number of bytes written.
+ </summary>
+ <param name="value">the char to write</param>
+ <remarks>
+ <para>
+ Overrides implementation of <see cref="T:log4net.Util.QuietTextWriter"/>. Counts
+ the number of bytes written.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.CountingQuietTextWriter.Write(System.Char[],System.Int32,System.Int32)">
+ <summary>
+ Writes a buffer to the underlying writer and counts the number of bytes written.
+ </summary>
+ <param name="buffer">the buffer to write</param>
+ <param name="index">the start index to write from</param>
+ <param name="count">the number of characters to write</param>
+ <remarks>
+ <para>
+ Overrides implementation of <see cref="T:log4net.Util.QuietTextWriter"/>. Counts
+ the number of bytes written.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.CountingQuietTextWriter.Write(System.String)">
+ <summary>
+ Writes a string to the output and counts the number of bytes written.
+ </summary>
+ <param name="str">The string data to write to the output.</param>
+ <remarks>
+ <para>
+ Overrides implementation of <see cref="T:log4net.Util.QuietTextWriter"/>. Counts
+ the number of bytes written.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Util.CountingQuietTextWriter.m_countBytes">
+ <summary>
+ Total number of bytes written.
+ </summary>
+ </member>
+ <member name="P:log4net.Util.CountingQuietTextWriter.Count">
+ <summary>
+ Gets or sets the total number of bytes written.
+ </summary>
+ <value>
+ The total number of bytes written.
+ </value>
+ <remarks>
+ <para>
+ Gets or sets the total number of bytes written.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Util.CyclicBuffer">
+ <summary>
+ A fixed size rolling buffer of logging events.
+ </summary>
+ <remarks>
+ <para>
+ An array backed fixed size leaky bucket.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="M:log4net.Util.CyclicBuffer.#ctor(System.Int32)">
+ <summary>
+ Constructor
+ </summary>
+ <param name="maxSize">The maximum number of logging events in the buffer.</param>
+ <remarks>
+ <para>
+ Initializes a new instance of the <see cref="T:log4net.Util.CyclicBuffer"/> class with
+ the specified maximum number of buffered logging events.
+ </para>
+ </remarks>
+ <exception cref="T:System.ArgumentOutOfRangeException">The <paramref name="maxSize"/> argument is not a positive integer.</exception>
+ </member>
+ <member name="M:log4net.Util.CyclicBuffer.Append(log4net.Core.LoggingEvent)">
+ <summary>
+ Appends a <paramref name="loggingEvent"/> to the buffer.
+ </summary>
+ <param name="loggingEvent">The event to append to the buffer.</param>
+ <returns>The event discarded from the buffer, if the buffer is full, otherwise <c>null</c>.</returns>
+ <remarks>
+ <para>
+ Append an event to the buffer. If the buffer still contains free space then
+ <c>null</c> is returned. If the buffer is full then an event will be dropped
+ to make space for the new event, the event dropped is returned.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.CyclicBuffer.PopOldest">
+ <summary>
+ Get and remove the oldest event in the buffer.
+ </summary>
+ <returns>The oldest logging event in the buffer</returns>
+ <remarks>
+ <para>
+ Gets the oldest (first) logging event in the buffer and removes it
+ from the buffer.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.CyclicBuffer.PopAll">
+ <summary>
+ Pops all the logging events from the buffer into an array.
+ </summary>
+ <returns>An array of all the logging events in the buffer.</returns>
+ <remarks>
+ <para>
+ Get all the events in the buffer and clear the buffer.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.CyclicBuffer.Clear">
+ <summary>
+ Clear the buffer
+ </summary>
+ <remarks>
+ <para>
+ Clear the buffer of all events. The events in the buffer are lost.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Util.CyclicBuffer.Item(System.Int32)">
+ <summary>
+ Gets the <paramref name="i"/>th oldest event currently in the buffer.
+ </summary>
+ <value>The <paramref name="i"/>th oldest event currently in the buffer.</value>
+ <remarks>
+ <para>
+ If <paramref name="i"/> is outside the range 0 to the number of events
+ currently in the buffer, then <c>null</c> is returned.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Util.CyclicBuffer.MaxSize">
+ <summary>
+ Gets the maximum size of the buffer.
+ </summary>
+ <value>The maximum size of the buffer.</value>
+ <remarks>
+ <para>
+ Gets the maximum size of the buffer
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Util.CyclicBuffer.Length">
+ <summary>
+ Gets the number of logging events in the buffer.
+ </summary>
+ <value>The number of logging events in the buffer.</value>
+ <remarks>
+ <para>
+ This number is guaranteed to be in the range 0 to <see cref="P:log4net.Util.CyclicBuffer.MaxSize"/>
+ (inclusive).
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Util.EmptyCollection">
+ <summary>
+ An always empty <see cref="T:System.Collections.ICollection"/>.
+ </summary>
+ <remarks>
+ <para>
+ A singleton implementation of the <see cref="T:System.Collections.ICollection"/>
+ interface that always represents an empty collection.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="M:log4net.Util.EmptyCollection.#ctor">
+ <summary>
+ Initializes a new instance of the <see cref="T:log4net.Util.EmptyCollection"/> class.
+ </summary>
+ <remarks>
+ <para>
+ Uses a private access modifier to enforce the singleton pattern.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.EmptyCollection.CopyTo(System.Array,System.Int32)">
+ <summary>
+ Copies the elements of the <see cref="T:System.Collections.ICollection"/> to an
+ <see cref="T:System.Array"/>, starting at a particular Array index.
+ </summary>
+ <param name="array">The one-dimensional <see cref="T:System.Array"/>
+ that is the destination of the elements copied from
+ <see cref="T:System.Collections.ICollection"/>. The Array must have zero-based
+ indexing.</param>
+ <param name="index">The zero-based index in array at which
+ copying begins.</param>
+ <remarks>
+ <para>
+ As the collection is empty no values are copied into the array.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.EmptyCollection.GetEnumerator">
+ <summary>
+ Returns an enumerator that can iterate through a collection.
+ </summary>
+ <returns>
+ An <see cref="T:System.Collections.IEnumerator"/> that can be used to
+ iterate through the collection.
+ </returns>
+ <remarks>
+ <para>
+ As the collection is empty a <see cref="T:log4net.Util.NullEnumerator"/> is returned.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Util.EmptyCollection.s_instance">
+ <summary>
+ The singleton instance of the empty collection.
+ </summary>
+ </member>
+ <member name="P:log4net.Util.EmptyCollection.Instance">
+ <summary>
+ Gets the singleton instance of the empty collection.
+ </summary>
+ <returns>The singleton instance of the empty collection.</returns>
+ <remarks>
+ <para>
+ Gets the singleton instance of the empty collection.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Util.EmptyCollection.IsSynchronized">
+ <summary>
+ Gets a value indicating if access to the <see cref="T:System.Collections.ICollection"/> is synchronized (thread-safe).
+ </summary>
+ <value>
+ <b>true</b> if access to the <see cref="T:System.Collections.ICollection"/> is synchronized (thread-safe); otherwise, <b>false</b>.
+ </value>
+ <remarks>
+ <para>
+ For the <see cref="T:log4net.Util.EmptyCollection"/> this property is always <c>true</c>.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Util.EmptyCollection.Count">
+ <summary>
+ Gets the number of elements contained in the <see cref="T:System.Collections.ICollection"/>.
+ </summary>
+ <value>
+ The number of elements contained in the <see cref="T:System.Collections.ICollection"/>.
+ </value>
+ <remarks>
+ <para>
+ As the collection is empty the <see cref="P:log4net.Util.EmptyCollection.Count"/> is always <c>0</c>.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Util.EmptyCollection.SyncRoot">
+ <summary>
+ Gets an object that can be used to synchronize access to the <see cref="T:System.Collections.ICollection"/>.
+ </summary>
+ <value>
+ An object that can be used to synchronize access to the <see cref="T:System.Collections.ICollection"/>.
+ </value>
+ <remarks>
+ <para>
+ As the collection is empty and thread safe and synchronized this instance is also
+ the <see cref="P:log4net.Util.EmptyCollection.SyncRoot"/> object.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Util.EmptyDictionary">
+ <summary>
+ An always empty <see cref="T:System.Collections.IDictionary"/>.
+ </summary>
+ <remarks>
+ <para>
+ A singleton implementation of the <see cref="T:System.Collections.IDictionary"/>
+ interface that always represents an empty collection.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="M:log4net.Util.EmptyDictionary.#ctor">
+ <summary>
+ Initializes a new instance of the <see cref="T:log4net.Util.EmptyDictionary"/> class.
+ </summary>
+ <remarks>
+ <para>
+ Uses a private access modifier to enforce the singleton pattern.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.EmptyDictionary.CopyTo(System.Array,System.Int32)">
+ <summary>
+ Copies the elements of the <see cref="T:System.Collections.ICollection"/> to an
+ <see cref="T:System.Array"/>, starting at a particular Array index.
+ </summary>
+ <param name="array">The one-dimensional <see cref="T:System.Array"/>
+ that is the destination of the elements copied from
+ <see cref="T:System.Collections.ICollection"/>. The Array must have zero-based
+ indexing.</param>
+ <param name="index">The zero-based index in array at which
+ copying begins.</param>
+ <remarks>
+ <para>
+ As the collection is empty no values are copied into the array.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.EmptyDictionary.System#Collections#IEnumerable#GetEnumerator">
+ <summary>
+ Returns an enumerator that can iterate through a collection.
+ </summary>
+ <returns>
+ An <see cref="T:System.Collections.IEnumerator"/> that can be used to
+ iterate through the collection.
+ </returns>
+ <remarks>
+ <para>
+ As the collection is empty a <see cref="T:log4net.Util.NullEnumerator"/> is returned.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.EmptyDictionary.Add(System.Object,System.Object)">
+ <summary>
+ Adds an element with the provided key and value to the
+ <see cref="T:log4net.Util.EmptyDictionary"/>.
+ </summary>
+ <param name="key">The <see cref="T:System.Object"/> to use as the key of the element to add.</param>
+ <param name="value">The <see cref="T:System.Object"/> to use as the value of the element to add.</param>
+ <remarks>
+ <para>
+ As the collection is empty no new values can be added. A <see cref="T:System.InvalidOperationException"/>
+ is thrown if this method is called.
+ </para>
+ </remarks>
+ <exception cref="T:System.InvalidOperationException">This dictionary is always empty and cannot be modified.</exception>
+ </member>
+ <member name="M:log4net.Util.EmptyDictionary.Clear">
+ <summary>
+ Removes all elements from the <see cref="T:log4net.Util.EmptyDictionary"/>.
+ </summary>
+ <remarks>
+ <para>
+ As the collection is empty no values can be removed. A <see cref="T:System.InvalidOperationException"/>
+ is thrown if this method is called.
+ </para>
+ </remarks>
+ <exception cref="T:System.InvalidOperationException">This dictionary is always empty and cannot be modified.</exception>
+ </member>
+ <member name="M:log4net.Util.EmptyDictionary.Contains(System.Object)">
+ <summary>
+ Determines whether the <see cref="T:log4net.Util.EmptyDictionary"/> contains an element
+ with the specified key.
+ </summary>
+ <param name="key">The key to locate in the <see cref="T:log4net.Util.EmptyDictionary"/>.</param>
+ <returns><c>false</c></returns>
+ <remarks>
+ <para>
+ As the collection is empty the <see cref="M:log4net.Util.EmptyDictionary.Contains(System.Object)"/> method always returns <c>false</c>.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.EmptyDictionary.GetEnumerator">
+ <summary>
+ Returns an enumerator that can iterate through a collection.
+ </summary>
+ <returns>
+ An <see cref="T:System.Collections.IEnumerator"/> that can be used to
+ iterate through the collection.
+ </returns>
+ <remarks>
+ <para>
+ As the collection is empty a <see cref="T:log4net.Util.NullEnumerator"/> is returned.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.EmptyDictionary.Remove(System.Object)">
+ <summary>
+ Removes the element with the specified key from the <see cref="T:log4net.Util.EmptyDictionary"/>.
+ </summary>
+ <param name="key">The key of the element to remove.</param>
+ <remarks>
+ <para>
+ As the collection is empty no values can be removed. A <see cref="T:System.InvalidOperationException"/>
+ is thrown if this method is called.
+ </para>
+ </remarks>
+ <exception cref="T:System.InvalidOperationException">This dictionary is always empty and cannot be modified.</exception>
+ </member>
+ <member name="F:log4net.Util.EmptyDictionary.s_instance">
+ <summary>
+ The singleton instance of the empty dictionary.
+ </summary>
+ </member>
+ <member name="P:log4net.Util.EmptyDictionary.Instance">
+ <summary>
+ Gets the singleton instance of the <see cref="T:log4net.Util.EmptyDictionary"/>.
+ </summary>
+ <returns>The singleton instance of the <see cref="T:log4net.Util.EmptyDictionary"/>.</returns>
+ <remarks>
+ <para>
+ Gets the singleton instance of the <see cref="T:log4net.Util.EmptyDictionary"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Util.EmptyDictionary.IsSynchronized">
+ <summary>
+ Gets a value indicating if access to the <see cref="T:System.Collections.ICollection"/> is synchronized (thread-safe).
+ </summary>
+ <value>
+ <b>true</b> if access to the <see cref="T:System.Collections.ICollection"/> is synchronized (thread-safe); otherwise, <b>false</b>.
+ </value>
+ <remarks>
+ <para>
+ For the <see cref="T:log4net.Util.EmptyCollection"/> this property is always <b>true</b>.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Util.EmptyDictionary.Count">
+ <summary>
+ Gets the number of elements contained in the <see cref="T:System.Collections.ICollection"/>
+ </summary>
+ <value>
+ The number of elements contained in the <see cref="T:System.Collections.ICollection"/>.
+ </value>
+ <remarks>
+ <para>
+ As the collection is empty the <see cref="P:log4net.Util.EmptyDictionary.Count"/> is always <c>0</c>.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Util.EmptyDictionary.SyncRoot">
+ <summary>
+ Gets an object that can be used to synchronize access to the <see cref="T:System.Collections.ICollection"/>.
+ </summary>
+ <value>
+ An object that can be used to synchronize access to the <see cref="T:System.Collections.ICollection"/>.
+ </value>
+ <remarks>
+ <para>
+ As the collection is empty and thread safe and synchronized this instance is also
+ the <see cref="P:log4net.Util.EmptyDictionary.SyncRoot"/> object.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Util.EmptyDictionary.IsFixedSize">
+ <summary>
+ Gets a value indicating whether the <see cref="T:log4net.Util.EmptyDictionary"/> has a fixed size.
+ </summary>
+ <value><c>true</c></value>
+ <remarks>
+ <para>
+ As the collection is empty <see cref="P:log4net.Util.EmptyDictionary.IsFixedSize"/> always returns <c>true</c>.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Util.EmptyDictionary.IsReadOnly">
+ <summary>
+ Gets a value indicating whether the <see cref="T:log4net.Util.EmptyDictionary"/> is read-only.
+ </summary>
+ <value><c>true</c></value>
+ <remarks>
+ <para>
+ As the collection is empty <see cref="P:log4net.Util.EmptyDictionary.IsReadOnly"/> always returns <c>true</c>.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Util.EmptyDictionary.Keys">
+ <summary>
+ Gets an <see cref="T:System.Collections.ICollection"/> containing the keys of the <see cref="T:log4net.Util.EmptyDictionary"/>.
+ </summary>
+ <value>An <see cref="T:System.Collections.ICollection"/> containing the keys of the <see cref="T:log4net.Util.EmptyDictionary"/>.</value>
+ <remarks>
+ <para>
+ As the collection is empty a <see cref="T:log4net.Util.EmptyCollection"/> is returned.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Util.EmptyDictionary.Values">
+ <summary>
+ Gets an <see cref="T:System.Collections.ICollection"/> containing the values of the <see cref="T:log4net.Util.EmptyDictionary"/>.
+ </summary>
+ <value>An <see cref="T:System.Collections.ICollection"/> containing the values of the <see cref="T:log4net.Util.EmptyDictionary"/>.</value>
+ <remarks>
+ <para>
+ As the collection is empty a <see cref="T:log4net.Util.EmptyCollection"/> is returned.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Util.EmptyDictionary.Item(System.Object)">
+ <summary>
+ Gets or sets the element with the specified key.
+ </summary>
+ <param name="key">The key of the element to get or set.</param>
+ <value><c>null</c></value>
+ <remarks>
+ <para>
+ As the collection is empty no values can be looked up or stored.
+ If the index getter is called then <c>null</c> is returned.
+ A <see cref="T:System.InvalidOperationException"/> is thrown if the setter is called.
+ </para>
+ </remarks>
+ <exception cref="T:System.InvalidOperationException">This dictionary is always empty and cannot be modified.</exception>
+ </member>
+ <member name="T:log4net.Util.FormattingInfo">
+ <summary>
+ Contain the information obtained when parsing formatting modifiers
+ in conversion modifiers.
+ </summary>
+ <remarks>
+ <para>
+ Holds the formatting information extracted from the format string by
+ the <see cref="T:log4net.Util.PatternParser"/>. This is used by the <see cref="T:log4net.Util.PatternConverter"/>
+ objects when rendering the output.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="M:log4net.Util.FormattingInfo.#ctor">
+ <summary>
+ Defaut Constructor
+ </summary>
+ <remarks>
+ <para>
+ Initializes a new instance of the <see cref="T:log4net.Util.FormattingInfo"/> class.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.FormattingInfo.#ctor(System.Int32,System.Int32,System.Boolean)">
+ <summary>
+ Constructor
+ </summary>
+ <remarks>
+ <para>
+ Initializes a new instance of the <see cref="T:log4net.Util.FormattingInfo"/> class
+ with the specified parameters.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Util.FormattingInfo.Min">
+ <summary>
+ Gets or sets the minimum value.
+ </summary>
+ <value>
+ The minimum value.
+ </value>
+ <remarks>
+ <para>
+ Gets or sets the minimum value.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Util.FormattingInfo.Max">
+ <summary>
+ Gets or sets the maximum value.
+ </summary>
+ <value>
+ The maximum value.
+ </value>
+ <remarks>
+ <para>
+ Gets or sets the maximum value.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Util.FormattingInfo.LeftAlign">
+ <summary>
+ Gets or sets a flag indicating whether left align is enabled
+ or not.
+ </summary>
+ <value>
+ A flag indicating whether left align is enabled or not.
+ </value>
+ <remarks>
+ <para>
+ Gets or sets a flag indicating whether left align is enabled or not.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Util.GlobalContextProperties">
+ <summary>
+ Implementation of Properties collection for the <see cref="T:log4net.GlobalContext"/>
+ </summary>
+ <remarks>
+ <para>
+ This class implements a properties collection that is thread safe and supports both
+ storing properties and capturing a read only copy of the current propertied.
+ </para>
+ <para>
+ This class is optimized to the scenario where the properties are read frequently
+ and are modified infrequently.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="F:log4net.Util.GlobalContextProperties.m_readOnlyProperties">
+ <summary>
+ The read only copy of the properties.
+ </summary>
+ <remarks>
+ <para>
+ This variable is declared <c>volatile</c> to prevent the compiler and JIT from
+ reordering reads and writes of this thread performed on different threads.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Util.GlobalContextProperties.m_syncRoot">
+ <summary>
+ Lock object used to synchronize updates within this instance
+ </summary>
+ </member>
+ <member name="M:log4net.Util.GlobalContextProperties.#ctor">
+ <summary>
+ Constructor
+ </summary>
+ <remarks>
+ <para>
+ Initializes a new instance of the <see cref="T:log4net.Util.GlobalContextProperties"/> class.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.GlobalContextProperties.Remove(System.String)">
+ <summary>
+ Remove a property from the global context
+ </summary>
+ <param name="key">the key for the entry to remove</param>
+ <remarks>
+ <para>
+ Removing an entry from the global context properties is relatively expensive compared
+ with reading a value.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.GlobalContextProperties.Clear">
+ <summary>
+ Clear the global context properties
+ </summary>
+ </member>
+ <member name="M:log4net.Util.GlobalContextProperties.GetReadOnlyProperties">
+ <summary>
+ Get a readonly immutable copy of the properties
+ </summary>
+ <returns>the current global context properties</returns>
+ <remarks>
+ <para>
+ This implementation is fast because the GlobalContextProperties class
+ stores a readonly copy of the properties.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Util.GlobalContextProperties.Item(System.String)">
+ <summary>
+ Gets or sets the value of a property
+ </summary>
+ <value>
+ The value for the property with the specified key
+ </value>
+ <remarks>
+ <para>
+ Reading the value for a key is faster than setting the value.
+ When the value is written a new read only copy of
+ the properties is created.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Util.LevelMapping">
+ <summary>
+ Manages a mapping from levels to <see cref="T:log4net.Util.LevelMappingEntry"/>
+ </summary>
+ <remarks>
+ <para>
+ Manages an ordered mapping from <see cref="T:log4net.Core.Level"/> instances
+ to <see cref="T:log4net.Util.LevelMappingEntry"/> subclasses.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="M:log4net.Util.LevelMapping.#ctor">
+ <summary>
+ Default constructor
+ </summary>
+ <remarks>
+ <para>
+ Initialise a new instance of <see cref="T:log4net.Util.LevelMapping"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.LevelMapping.Add(log4net.Util.LevelMappingEntry)">
+ <summary>
+ Add a <see cref="T:log4net.Util.LevelMappingEntry"/> to this mapping
+ </summary>
+ <param name="entry">the entry to add</param>
+ <remarks>
+ <para>
+ If a <see cref="T:log4net.Util.LevelMappingEntry"/> has previously been added
+ for the same <see cref="T:log4net.Core.Level"/> then that entry will be
+ overwritten.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.LevelMapping.Lookup(log4net.Core.Level)">
+ <summary>
+ Lookup the mapping for the specified level
+ </summary>
+ <param name="level">the level to lookup</param>
+ <returns>the <see cref="T:log4net.Util.LevelMappingEntry"/> for the level or <c>null</c> if no mapping found</returns>
+ <remarks>
+ <para>
+ Lookup the value for the specified level. Finds the nearest
+ mapping value for the level that is equal to or less than the
+ <paramref name="level"/> specified.
+ </para>
+ <para>
+ If no mapping could be found then <c>null</c> is returned.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.LevelMapping.ActivateOptions">
+ <summary>
+ Initialize options
+ </summary>
+ <remarks>
+ <para>
+ Caches the sorted list of <see cref="T:log4net.Util.LevelMappingEntry"/> in an array
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Util.LogicalThreadContextProperties">
+ <summary>
+ Implementation of Properties collection for the <see cref="T:log4net.LogicalThreadContext"/>
+ </summary>
+ <remarks>
+ <para>
+ Class implements a collection of properties that is specific to each thread.
+ The class is not synchronized as each thread has its own <see cref="T:log4net.Util.PropertiesDictionary"/>.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="M:log4net.Util.LogicalThreadContextProperties.#ctor">
+ <summary>
+ Constructor
+ </summary>
+ <remarks>
+ <para>
+ Initializes a new instance of the <see cref="T:log4net.Util.LogicalThreadContextProperties"/> class.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.LogicalThreadContextProperties.Remove(System.String)">
+ <summary>
+ Remove a property
+ </summary>
+ <param name="key">the key for the entry to remove</param>
+ <remarks>
+ <para>
+ Remove the value for the specified <paramref name="key"/> from the context.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.LogicalThreadContextProperties.Clear">
+ <summary>
+ Clear all the context properties
+ </summary>
+ <remarks>
+ <para>
+ Clear all the context properties
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.LogicalThreadContextProperties.GetProperties(System.Boolean)">
+ <summary>
+ Get the PropertiesDictionary stored in the LocalDataStoreSlot for this thread.
+ </summary>
+ <param name="create">create the dictionary if it does not exist, otherwise return null if is does not exist</param>
+ <returns>the properties for this thread</returns>
+ <remarks>
+ <para>
+ The collection returned is only to be used on the calling thread. If the
+ caller needs to share the collection between different threads then the
+ caller must clone the collection before doings so.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Util.LogicalThreadContextProperties.Item(System.String)">
+ <summary>
+ Gets or sets the value of a property
+ </summary>
+ <value>
+ The value for the property with the specified key
+ </value>
+ <remarks>
+ <para>
+ Get or set the property value for the <paramref name="key"/> specified.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Util.LogLog">
+ <summary>
+ Outputs log statements from within the log4net assembly.
+ </summary>
+ <remarks>
+ <para>
+ Log4net components cannot make log4net logging calls. However, it is
+ sometimes useful for the user to learn about what log4net is
+ doing.
+ </para>
+ <para>
+ All log4net internal debug calls go to the standard output stream
+ whereas internal error messages are sent to the standard error output
+ stream.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="M:log4net.Util.LogLog.#ctor">
+ <summary>
+ Initializes a new instance of the <see cref="T:log4net.Util.LogLog"/> class.
+ </summary>
+ <remarks>
+ <para>
+ Uses a private access modifier to prevent instantiation of this class.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.LogLog.#cctor">
+ <summary>
+ Static constructor that initializes logging by reading
+ settings from the application configuration file.
+ </summary>
+ <remarks>
+ <para>
+ The <c>log4net.Internal.Debug</c> application setting
+ controls internal debugging. This setting should be set
+ to <c>true</c> to enable debugging.
+ </para>
+ <para>
+ The <c>log4net.Internal.Quiet</c> application setting
+ suppresses all internal logging including error messages.
+ This setting should be set to <c>true</c> to enable message
+ suppression.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.LogLog.Debug(System.String)">
+ <summary>
+ Writes log4net internal debug messages to the
+ standard output stream.
+ </summary>
+ <param name="message">The message to log.</param>
+ <remarks>
+ <para>
+ All internal debug messages are prepended with
+ the string "log4net: ".
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.LogLog.Debug(System.String,System.Exception)">
+ <summary>
+ Writes log4net internal debug messages to the
+ standard output stream.
+ </summary>
+ <param name="message">The message to log.</param>
+ <param name="exception">An exception to log.</param>
+ <remarks>
+ <para>
+ All internal debug messages are prepended with
+ the string "log4net: ".
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.LogLog.Warn(System.String)">
+ <summary>
+ Writes log4net internal warning messages to the
+ standard error stream.
+ </summary>
+ <param name="message">The message to log.</param>
+ <remarks>
+ <para>
+ All internal warning messages are prepended with
+ the string "log4net:WARN ".
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.LogLog.Warn(System.String,System.Exception)">
+ <summary>
+ Writes log4net internal warning messages to the
+ standard error stream.
+ </summary>
+ <param name="message">The message to log.</param>
+ <param name="exception">An exception to log.</param>
+ <remarks>
+ <para>
+ All internal warning messages are prepended with
+ the string "log4net:WARN ".
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.LogLog.Error(System.String)">
+ <summary>
+ Writes log4net internal error messages to the
+ standard error stream.
+ </summary>
+ <param name="message">The message to log.</param>
+ <remarks>
+ <para>
+ All internal error messages are prepended with
+ the string "log4net:ERROR ".
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.LogLog.Error(System.String,System.Exception)">
+ <summary>
+ Writes log4net internal error messages to the
+ standard error stream.
+ </summary>
+ <param name="message">The message to log.</param>
+ <param name="exception">An exception to log.</param>
+ <remarks>
+ <para>
+ All internal debug messages are prepended with
+ the string "log4net:ERROR ".
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.LogLog.EmitOutLine(System.String)">
+ <summary>
+ Writes output to the standard output stream.
+ </summary>
+ <param name="message">The message to log.</param>
+ <remarks>
+ <para>
+ Writes to both Console.Out and System.Diagnostics.Trace.
+ Note that the System.Diagnostics.Trace is not supported
+ on the Compact Framework.
+ </para>
+ <para>
+ If the AppDomain is not configured with a config file then
+ the call to System.Diagnostics.Trace may fail. This is only
+ an issue if you are programmatically creating your own AppDomains.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.LogLog.EmitErrorLine(System.String)">
+ <summary>
+ Writes output to the standard error stream.
+ </summary>
+ <param name="message">The message to log.</param>
+ <remarks>
+ <para>
+ Writes to both Console.Error and System.Diagnostics.Trace.
+ Note that the System.Diagnostics.Trace is not supported
+ on the Compact Framework.
+ </para>
+ <para>
+ If the AppDomain is not configured with a config file then
+ the call to System.Diagnostics.Trace may fail. This is only
+ an issue if you are programmatically creating your own AppDomains.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Util.LogLog.s_debugEnabled">
+ <summary>
+ Default debug level
+ </summary>
+ </member>
+ <member name="F:log4net.Util.LogLog.s_quietMode">
+ <summary>
+ In quietMode not even errors generate any output.
+ </summary>
+ </member>
+ <member name="P:log4net.Util.LogLog.InternalDebugging">
+ <summary>
+ Gets or sets a value indicating whether log4net internal logging
+ is enabled or disabled.
+ </summary>
+ <value>
+ <c>true</c> if log4net internal logging is enabled, otherwise
+ <c>false</c>.
+ </value>
+ <remarks>
+ <para>
+ When set to <c>true</c>, internal debug level logging will be
+ displayed.
+ </para>
+ <para>
+ This value can be set by setting the application setting
+ <c>log4net.Internal.Debug</c> in the application configuration
+ file.
+ </para>
+ <para>
+ The default value is <c>false</c>, i.e. debugging is
+ disabled.
+ </para>
+ </remarks>
+ <example>
+ <para>
+ The following example enables internal debugging using the
+ application configuration file :
+ </para>
+ <code lang="XML" escaped="true">
+ <configuration>
+ <appSettings>
+ <add key="log4net.Internal.Debug" value="true" />
+ </appSettings>
+ </configuration>
+ </code>
+ </example>
+ </member>
+ <member name="P:log4net.Util.LogLog.QuietMode">
+ <summary>
+ Gets or sets a value indicating whether log4net should generate no output
+ from internal logging, not even for errors.
+ </summary>
+ <value>
+ <c>true</c> if log4net should generate no output at all from internal
+ logging, otherwise <c>false</c>.
+ </value>
+ <remarks>
+ <para>
+ When set to <c>true</c> will cause internal logging at all levels to be
+ suppressed. This means that no warning or error reports will be logged.
+ This option overrides the <see cref="P:log4net.Util.LogLog.InternalDebugging"/> setting and
+ disables all debug also.
+ </para>
+ <para>This value can be set by setting the application setting
+ <c>log4net.Internal.Quiet</c> in the application configuration file.
+ </para>
+ <para>
+ The default value is <c>false</c>, i.e. internal logging is not
+ disabled.
+ </para>
+ </remarks>
+ <example>
+ The following example disables internal logging using the
+ application configuration file :
+ <code lang="XML" escaped="true">
+ <configuration>
+ <appSettings>
+ <add key="log4net.Internal.Quiet" value="true"/>
+ </appSettings>
+ </configuration>
+ </code>
+ </example>
+ </member>
+ <member name="P:log4net.Util.LogLog.IsDebugEnabled">
+ <summary>
+ Test if LogLog.Debug is enabled for output.
+ </summary>
+ <value>
+ <c>true</c> if Debug is enabled
+ </value>
+ <remarks>
+ <para>
+ Test if LogLog.Debug is enabled for output.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Util.LogLog.IsWarnEnabled">
+ <summary>
+ Test if LogLog.Warn is enabled for output.
+ </summary>
+ <value>
+ <c>true</c> if Warn is enabled
+ </value>
+ <remarks>
+ <para>
+ Test if LogLog.Warn is enabled for output.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Util.LogLog.IsErrorEnabled">
+ <summary>
+ Test if LogLog.Error is enabled for output.
+ </summary>
+ <value>
+ <c>true</c> if Error is enabled
+ </value>
+ <remarks>
+ <para>
+ Test if LogLog.Error is enabled for output.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Util.NativeError">
+ <summary>
+ Represents a native error code and message.
+ </summary>
+ <remarks>
+ <para>
+ Represents a Win32 platform native error.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="M:log4net.Util.NativeError.#ctor(System.Int32,System.String)">
+ <summary>
+ Create an instance of the <see cref="T:log4net.Util.NativeError"/> class with the specified
+ error number and message.
+ </summary>
+ <param name="number">The number of the native error.</param>
+ <param name="message">The message of the native error.</param>
+ <remarks>
+ <para>
+ Create an instance of the <see cref="T:log4net.Util.NativeError"/> class with the specified
+ error number and message.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.NativeError.GetLastError">
+ <summary>
+ Create a new instance of the <see cref="T:log4net.Util.NativeError"/> class for the last Windows error.
+ </summary>
+ <returns>
+ An instance of the <see cref="T:log4net.Util.NativeError"/> class for the last windows error.
+ </returns>
+ <remarks>
+ <para>
+ The message for the <see cref="M:System.Runtime.InteropServices.Marshal.GetLastWin32Error"/> error number is lookup up using the
+ native Win32 <c>FormatMessage</c> function.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.NativeError.GetError(System.Int32)">
+ <summary>
+ Create a new instance of the <see cref="T:log4net.Util.NativeError"/> class.
+ </summary>
+ <param name="number">the error number for the native error</param>
+ <returns>
+ An instance of the <see cref="T:log4net.Util.NativeError"/> class for the specified
+ error number.
+ </returns>
+ <remarks>
+ <para>
+ The message for the specified error number is lookup up using the
+ native Win32 <c>FormatMessage</c> function.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.NativeError.GetErrorMessage(System.Int32)">
+ <summary>
+ Retrieves the message corresponding with a Win32 message identifier.
+ </summary>
+ <param name="messageId">Message identifier for the requested message.</param>
+ <returns>
+ The message corresponding with the specified message identifier.
+ </returns>
+ <remarks>
+ <para>
+ The message will be searched for in system message-table resource(s)
+ using the native <c>FormatMessage</c> function.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.NativeError.ToString">
+ <summary>
+ Return error information string
+ </summary>
+ <returns>error information string</returns>
+ <remarks>
+ <para>
+ Return error information string
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.NativeError.FormatMessage(System.Int32,System.IntPtr@,System.Int32,System.Int32,System.String@,System.Int32,System.IntPtr)">
+ <summary>
+ Formats a message string.
+ </summary>
+ <param name="dwFlags">Formatting options, and how to interpret the <paramref name="lpSource"/> parameter.</param>
+ <param name="lpSource">Location of the message definition.</param>
+ <param name="dwMessageId">Message identifier for the requested message.</param>
+ <param name="dwLanguageId">Language identifier for the requested message.</param>
+ <param name="lpBuffer">If <paramref name="dwFlags"/> includes FORMAT_MESSAGE_ALLOCATE_BUFFER, the function allocates a buffer using the <c>LocalAlloc</c> function, and places the pointer to the buffer at the address specified in <paramref name="lpBuffer"/>.</param>
+ <param name="nSize">If the FORMAT_MESSAGE_ALLOCATE_BUFFER flag is not set, this parameter specifies the maximum number of TCHARs that can be stored in the output buffer. If FORMAT_MESSAGE_ALLOCATE_BUFFER is set, this parameter specifies the minimum number of TCHARs to allocate for an output buffer.</param>
+ <param name="Arguments">Pointer to an array of values that are used as insert values in the formatted message.</param>
+ <remarks>
+ <para>
+ The function requires a message definition as input. The message definition can come from a
+ buffer passed into the function. It can come from a message table resource in an
+ already-loaded module. Or the caller can ask the function to search the system's message
+ table resource(s) for the message definition. The function finds the message definition
+ in a message table resource based on a message identifier and a language identifier.
+ The function copies the formatted message text to an output buffer, processing any embedded
+ insert sequences if requested.
+ </para>
+ <para>
+ To prevent the usage of unsafe code, this stub does not support inserting values in the formatted message.
+ </para>
+ </remarks>
+ <returns>
+ <para>
+ If the function succeeds, the return value is the number of TCHARs stored in the output
+ buffer, excluding the terminating null character.
+ </para>
+ <para>
+ If the function fails, the return value is zero. To get extended error information,
+ call <see cref="M:System.Runtime.InteropServices.Marshal.GetLastWin32Error"/>.
+ </para>
+ </returns>
+ </member>
+ <member name="P:log4net.Util.NativeError.Number">
+ <summary>
+ Gets the number of the native error.
+ </summary>
+ <value>
+ The number of the native error.
+ </value>
+ <remarks>
+ <para>
+ Gets the number of the native error.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Util.NativeError.Message">
+ <summary>
+ Gets the message of the native error.
+ </summary>
+ <value>
+ The message of the native error.
+ </value>
+ <remarks>
+ <para>
+ </para>
+ Gets the message of the native error.
+ </remarks>
+ </member>
+ <member name="T:log4net.Util.NullDictionaryEnumerator">
+ <summary>
+ An always empty <see cref="T:System.Collections.IDictionaryEnumerator"/>.
+ </summary>
+ <remarks>
+ <para>
+ A singleton implementation of the <see cref="T:System.Collections.IDictionaryEnumerator"/> over a collection
+ that is empty and not modifiable.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="M:log4net.Util.NullDictionaryEnumerator.#ctor">
+ <summary>
+ Initializes a new instance of the <see cref="T:log4net.Util.NullDictionaryEnumerator"/> class.
+ </summary>
+ <remarks>
+ <para>
+ Uses a private access modifier to enforce the singleton pattern.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.NullDictionaryEnumerator.MoveNext">
+ <summary>
+ Test if the enumerator can advance, if so advance.
+ </summary>
+ <returns><c>false</c> as the <see cref="T:log4net.Util.NullDictionaryEnumerator"/> cannot advance.</returns>
+ <remarks>
+ <para>
+ As the enumerator is over an empty collection its <see cref="P:log4net.Util.NullDictionaryEnumerator.Current"/>
+ value cannot be moved over a valid position, therefore <see cref="M:log4net.Util.NullDictionaryEnumerator.MoveNext"/>
+ will always return <c>false</c>.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.NullDictionaryEnumerator.Reset">
+ <summary>
+ Resets the enumerator back to the start.
+ </summary>
+ <remarks>
+ <para>
+ As the enumerator is over an empty collection <see cref="M:log4net.Util.NullDictionaryEnumerator.Reset"/> does nothing.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Util.NullDictionaryEnumerator.s_instance">
+ <summary>
+ The singleton instance of the <see cref="T:log4net.Util.NullDictionaryEnumerator"/>.
+ </summary>
+ </member>
+ <member name="P:log4net.Util.NullDictionaryEnumerator.Instance">
+ <summary>
+ Gets the singleton instance of the <see cref="T:log4net.Util.NullDictionaryEnumerator"/>.
+ </summary>
+ <returns>The singleton instance of the <see cref="T:log4net.Util.NullDictionaryEnumerator"/>.</returns>
+ <remarks>
+ <para>
+ Gets the singleton instance of the <see cref="T:log4net.Util.NullDictionaryEnumerator"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Util.NullDictionaryEnumerator.Current">
+ <summary>
+ Gets the current object from the enumerator.
+ </summary>
+ <remarks>
+ Throws an <see cref="T:System.InvalidOperationException"/> because the
+ <see cref="T:log4net.Util.NullDictionaryEnumerator"/> never has a current value.
+ </remarks>
+ <remarks>
+ <para>
+ As the enumerator is over an empty collection its <see cref="P:log4net.Util.NullDictionaryEnumerator.Current"/>
+ value cannot be moved over a valid position, therefore <see cref="P:log4net.Util.NullDictionaryEnumerator.Current"/>
+ will throw an <see cref="T:System.InvalidOperationException"/>.
+ </para>
+ </remarks>
+ <exception cref="T:System.InvalidOperationException">The collection is empty and <see cref="P:log4net.Util.NullDictionaryEnumerator.Current"/>
+ cannot be positioned over a valid location.</exception>
+ </member>
+ <member name="P:log4net.Util.NullDictionaryEnumerator.Key">
+ <summary>
+ Gets the current key from the enumerator.
+ </summary>
+ <remarks>
+ Throws an exception because the <see cref="T:log4net.Util.NullDictionaryEnumerator"/>
+ never has a current value.
+ </remarks>
+ <remarks>
+ <para>
+ As the enumerator is over an empty collection its <see cref="P:log4net.Util.NullDictionaryEnumerator.Current"/>
+ value cannot be moved over a valid position, therefore <see cref="P:log4net.Util.NullDictionaryEnumerator.Key"/>
+ will throw an <see cref="T:System.InvalidOperationException"/>.
+ </para>
+ </remarks>
+ <exception cref="T:System.InvalidOperationException">The collection is empty and <see cref="P:log4net.Util.NullDictionaryEnumerator.Current"/>
+ cannot be positioned over a valid location.</exception>
+ </member>
+ <member name="P:log4net.Util.NullDictionaryEnumerator.Value">
+ <summary>
+ Gets the current value from the enumerator.
+ </summary>
+ <value>The current value from the enumerator.</value>
+ <remarks>
+ Throws an <see cref="T:System.InvalidOperationException"/> because the
+ <see cref="T:log4net.Util.NullDictionaryEnumerator"/> never has a current value.
+ </remarks>
+ <remarks>
+ <para>
+ As the enumerator is over an empty collection its <see cref="P:log4net.Util.NullDictionaryEnumerator.Current"/>
+ value cannot be moved over a valid position, therefore <see cref="P:log4net.Util.NullDictionaryEnumerator.Value"/>
+ will throw an <see cref="T:System.InvalidOperationException"/>.
+ </para>
+ </remarks>
+ <exception cref="T:System.InvalidOperationException">The collection is empty and <see cref="P:log4net.Util.NullDictionaryEnumerator.Current"/>
+ cannot be positioned over a valid location.</exception>
+ </member>
+ <member name="P:log4net.Util.NullDictionaryEnumerator.Entry">
+ <summary>
+ Gets the current entry from the enumerator.
+ </summary>
+ <remarks>
+ Throws an <see cref="T:System.InvalidOperationException"/> because the
+ <see cref="T:log4net.Util.NullDictionaryEnumerator"/> never has a current entry.
+ </remarks>
+ <remarks>
+ <para>
+ As the enumerator is over an empty collection its <see cref="P:log4net.Util.NullDictionaryEnumerator.Current"/>
+ value cannot be moved over a valid position, therefore <see cref="P:log4net.Util.NullDictionaryEnumerator.Entry"/>
+ will throw an <see cref="T:System.InvalidOperationException"/>.
+ </para>
+ </remarks>
+ <exception cref="T:System.InvalidOperationException">The collection is empty and <see cref="P:log4net.Util.NullDictionaryEnumerator.Current"/>
+ cannot be positioned over a valid location.</exception>
+ </member>
+ <member name="T:log4net.Util.NullEnumerator">
+ <summary>
+ An always empty <see cref="T:System.Collections.IEnumerator"/>.
+ </summary>
+ <remarks>
+ <para>
+ A singleton implementation of the <see cref="T:System.Collections.IEnumerator"/> over a collection
+ that is empty and not modifiable.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="M:log4net.Util.NullEnumerator.#ctor">
+ <summary>
+ Initializes a new instance of the <see cref="T:log4net.Util.NullEnumerator"/> class.
+ </summary>
+ <remarks>
+ <para>
+ Uses a private access modifier to enforce the singleton pattern.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.NullEnumerator.MoveNext">
+ <summary>
+ Test if the enumerator can advance, if so advance
+ </summary>
+ <returns><c>false</c> as the <see cref="T:log4net.Util.NullEnumerator"/> cannot advance.</returns>
+ <remarks>
+ <para>
+ As the enumerator is over an empty collection its <see cref="P:log4net.Util.NullEnumerator.Current"/>
+ value cannot be moved over a valid position, therefore <see cref="M:log4net.Util.NullEnumerator.MoveNext"/>
+ will always return <c>false</c>.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.NullEnumerator.Reset">
+ <summary>
+ Resets the enumerator back to the start.
+ </summary>
+ <remarks>
+ <para>
+ As the enumerator is over an empty collection <see cref="M:log4net.Util.NullEnumerator.Reset"/> does nothing.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Util.NullEnumerator.s_instance">
+ <summary>
+ The singleton instance of the <see cref="T:log4net.Util.NullEnumerator"/>.
+ </summary>
+ </member>
+ <member name="P:log4net.Util.NullEnumerator.Instance">
+ <summary>
+ Get the singleton instance of the <see cref="T:log4net.Util.NullEnumerator"/>.
+ </summary>
+ <returns>The singleton instance of the <see cref="T:log4net.Util.NullEnumerator"/>.</returns>
+ <remarks>
+ <para>
+ Gets the singleton instance of the <see cref="T:log4net.Util.NullEnumerator"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Util.NullEnumerator.Current">
+ <summary>
+ Gets the current object from the enumerator.
+ </summary>
+ <remarks>
+ Throws an <see cref="T:System.InvalidOperationException"/> because the
+ <see cref="T:log4net.Util.NullDictionaryEnumerator"/> never has a current value.
+ </remarks>
+ <remarks>
+ <para>
+ As the enumerator is over an empty collection its <see cref="P:log4net.Util.NullEnumerator.Current"/>
+ value cannot be moved over a valid position, therefore <see cref="P:log4net.Util.NullEnumerator.Current"/>
+ will throw an <see cref="T:System.InvalidOperationException"/>.
+ </para>
+ </remarks>
+ <exception cref="T:System.InvalidOperationException">The collection is empty and <see cref="P:log4net.Util.NullEnumerator.Current"/>
+ cannot be positioned over a valid location.</exception>
+ </member>
+ <member name="T:log4net.Util.NullSecurityContext">
+ <summary>
+ A SecurityContext used when a SecurityContext is not required
+ </summary>
+ <remarks>
+ <para>
+ The <see cref="T:log4net.Util.NullSecurityContext"/> is a no-op implementation of the
+ <see cref="T:log4net.Core.SecurityContext"/> base class. It is used where a <see cref="T:log4net.Core.SecurityContext"/>
+ is required but one has not been provided.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="F:log4net.Util.NullSecurityContext.Instance">
+ <summary>
+ Singleton instance of <see cref="T:log4net.Util.NullSecurityContext"/>
+ </summary>
+ <remarks>
+ <para>
+ Singleton instance of <see cref="T:log4net.Util.NullSecurityContext"/>
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.NullSecurityContext.#ctor">
+ <summary>
+ Private constructor
+ </summary>
+ <remarks>
+ <para>
+ Private constructor for singleton pattern.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.NullSecurityContext.Impersonate(System.Object)">
+ <summary>
+ Impersonate this SecurityContext
+ </summary>
+ <param name="state">State supplied by the caller</param>
+ <returns><c>null</c></returns>
+ <remarks>
+ <para>
+ No impersonation is done and <c>null</c> is always returned.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Util.OnlyOnceErrorHandler">
+ <summary>
+ Implements log4net's default error handling policy which consists
+ of emitting a message for the first error in an appender and
+ ignoring all subsequent errors.
+ </summary>
+ <remarks>
+ <para>
+ The error message is printed on the standard error output stream.
+ </para>
+ <para>
+ This policy aims at protecting an otherwise working application
+ from being flooded with error messages when logging fails.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="M:log4net.Util.OnlyOnceErrorHandler.#ctor">
+ <summary>
+ Default Constructor
+ </summary>
+ <remarks>
+ <para>
+ Initializes a new instance of the <see cref="T:log4net.Util.OnlyOnceErrorHandler"/> class.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.OnlyOnceErrorHandler.#ctor(System.String)">
+ <summary>
+ Constructor
+ </summary>
+ <param name="prefix">The prefix to use for each message.</param>
+ <remarks>
+ <para>
+ Initializes a new instance of the <see cref="T:log4net.Util.OnlyOnceErrorHandler"/> class
+ with the specified prefix.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.OnlyOnceErrorHandler.Error(System.String,System.Exception,log4net.Core.ErrorCode)">
+ <summary>
+ Log an Error
+ </summary>
+ <param name="message">The error message.</param>
+ <param name="e">The exception.</param>
+ <param name="errorCode">The internal error code.</param>
+ <remarks>
+ <para>
+ Prints the message and the stack trace of the exception on the standard
+ error output stream.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.OnlyOnceErrorHandler.Error(System.String,System.Exception)">
+ <summary>
+ Log an Error
+ </summary>
+ <param name="message">The error message.</param>
+ <param name="e">The exception.</param>
+ <remarks>
+ <para>
+ Prints the message and the stack trace of the exception on the standard
+ error output stream.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.OnlyOnceErrorHandler.Error(System.String)">
+ <summary>
+ Log an error
+ </summary>
+ <param name="message">The error message.</param>
+ <remarks>
+ <para>
+ Print a the error message passed as parameter on the standard
+ error output stream.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Util.OnlyOnceErrorHandler.m_firstTime">
+ <summary>
+ Flag to indicate if it is the first error
+ </summary>
+ </member>
+ <member name="F:log4net.Util.OnlyOnceErrorHandler.m_prefix">
+ <summary>
+ String to prefix each message with
+ </summary>
+ </member>
+ <member name="P:log4net.Util.OnlyOnceErrorHandler.IsEnabled">
+ <summary>
+ Is error logging enabled
+ </summary>
+ <remarks>
+ <para>
+ Is error logging enabled. Logging is only enabled for the
+ first error delivered to the <see cref="T:log4net.Util.OnlyOnceErrorHandler"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Util.OptionConverter">
+ <summary>
+ A convenience class to convert property values to specific types.
+ </summary>
+ <remarks>
+ <para>
+ Utility functions for converting types and parsing values.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="M:log4net.Util.OptionConverter.#ctor">
+ <summary>
+ Initializes a new instance of the <see cref="T:log4net.Util.OptionConverter"/> class.
+ </summary>
+ <remarks>
+ <para>
+ Uses a private access modifier to prevent instantiation of this class.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.OptionConverter.ToBoolean(System.String,System.Boolean)">
+ <summary>
+ Converts a string to a <see cref="T:System.Boolean"/> value.
+ </summary>
+ <param name="argValue">String to convert.</param>
+ <param name="defaultValue">The default value.</param>
+ <returns>The <see cref="T:System.Boolean"/> value of <paramref name="argValue"/>.</returns>
+ <remarks>
+ <para>
+ If <paramref name="argValue"/> is "true", then <c>true</c> is returned.
+ If <paramref name="argValue"/> is "false", then <c>false</c> is returned.
+ Otherwise, <paramref name="defaultValue"/> is returned.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.OptionConverter.ToFileSize(System.String,System.Int64)">
+ <summary>
+ Parses a file size into a number.
+ </summary>
+ <param name="argValue">String to parse.</param>
+ <param name="defaultValue">The default value.</param>
+ <returns>The <see cref="T:System.Int64"/> value of <paramref name="argValue"/>.</returns>
+ <remarks>
+ <para>
+ Parses a file size of the form: number[KB|MB|GB] into a
+ long value. It is scaled with the appropriate multiplier.
+ </para>
+ <para>
+ <paramref name="defaultValue"/> is returned when <paramref name="argValue"/>
+ cannot be converted to a <see cref="T:System.Int64"/> value.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.OptionConverter.ConvertStringTo(System.Type,System.String)">
+ <summary>
+ Converts a string to an object.
+ </summary>
+ <param name="target">The target type to convert to.</param>
+ <param name="txt">The string to convert to an object.</param>
+ <returns>
+ The object converted from a string or <c>null</c> when the
+ conversion failed.
+ </returns>
+ <remarks>
+ <para>
+ Converts a string to an object. Uses the converter registry to try
+ to convert the string value into the specified target type.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.OptionConverter.CanConvertTypeTo(System.Type,System.Type)">
+ <summary>
+ Checks if there is an appropriate type conversion from the source type to the target type.
+ </summary>
+ <param name="sourceType">The type to convert from.</param>
+ <param name="targetType">The type to convert to.</param>
+ <returns><c>true</c> if there is a conversion from the source type to the target type.</returns>
+ <remarks>
+ Checks if there is an appropriate type conversion from the source type to the target type.
+ <para>
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.OptionConverter.ConvertTypeTo(System.Object,System.Type)">
+ <summary>
+ Converts an object to the target type.
+ </summary>
+ <param name="sourceInstance">The object to convert to the target type.</param>
+ <param name="targetType">The type to convert to.</param>
+ <returns>The converted object.</returns>
+ <remarks>
+ <para>
+ Converts an object to the target type.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.OptionConverter.InstantiateByClassName(System.String,System.Type,System.Object)">
+ <summary>
+ Instantiates an object given a class name.
+ </summary>
+ <param name="className">The fully qualified class name of the object to instantiate.</param>
+ <param name="superClass">The class to which the new object should belong.</param>
+ <param name="defaultValue">The object to return in case of non-fulfillment.</param>
+ <returns>
+ An instance of the <paramref name="className"/> or <paramref name="defaultValue"/>
+ if the object could not be instantiated.
+ </returns>
+ <remarks>
+ <para>
+ Checks that the <paramref name="className"/> is a subclass of
+ <paramref name="superClass"/>. If that test fails or the object could
+ not be instantiated, then <paramref name="defaultValue"/> is returned.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.OptionConverter.SubstituteVariables(System.String,System.Collections.IDictionary)">
+ <summary>
+ Performs variable substitution in string <paramref name="val"/> from the
+ values of keys found in <paramref name="props"/>.
+ </summary>
+ <param name="value">The string on which variable substitution is performed.</param>
+ <param name="props">The dictionary to use to lookup variables.</param>
+ <returns>The result of the substitutions.</returns>
+ <remarks>
+ <para>
+ The variable substitution delimiters are <b>${</b> and <b>}</b>.
+ </para>
+ <para>
+ For example, if props contains <c>key=value</c>, then the call
+ </para>
+ <para>
+ <code lang="C#">
+ string s = OptionConverter.SubstituteVariables("Value of key is ${key}.");
+ </code>
+ </para>
+ <para>
+ will set the variable <c>s</c> to "Value of key is value.".
+ </para>
+ <para>
+ If no value could be found for the specified key, then substitution
+ defaults to an empty string.
+ </para>
+ <para>
+ For example, if system properties contains no value for the key
+ "nonExistentKey", then the call
+ </para>
+ <para>
+ <code lang="C#">
+ string s = OptionConverter.SubstituteVariables("Value of nonExistentKey is [${nonExistentKey}]");
+ </code>
+ </para>
+ <para>
+ will set <s>s</s> to "Value of nonExistentKey is []".
+ </para>
+ <para>
+ An Exception is thrown if <paramref name="value"/> contains a start
+ delimiter "${" which is not balanced by a stop delimiter "}".
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.OptionConverter.ParseEnum(System.Type,System.String,System.Boolean)">
+ <summary>
+ Converts the string representation of the name or numeric value of one or
+ more enumerated constants to an equivalent enumerated object.
+ </summary>
+ <param name="enumType">The type to convert to.</param>
+ <param name="value">The enum string value.</param>
+ <param name="ignoreCase">If <c>true</c>, ignore case; otherwise, regard case.</param>
+ <returns>An object of type <paramref name="enumType" /> whose value is represented by <paramref name="value" />.</returns>
+ </member>
+ <member name="T:log4net.Util.PatternParser">
+ <summary>
+ Most of the work of the <see cref="T:log4net.Layout.PatternLayout"/> class
+ is delegated to the PatternParser class.
+ </summary>
+ <remarks>
+ <para>
+ The <c>PatternParser</c> processes a pattern string and
+ returns a chain of <see cref="T:log4net.Util.PatternConverter"/> objects.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="M:log4net.Util.PatternParser.#ctor(System.String)">
+ <summary>
+ Constructor
+ </summary>
+ <param name="pattern">The pattern to parse.</param>
+ <remarks>
+ <para>
+ Initializes a new instance of the <see cref="T:log4net.Util.PatternParser"/> class
+ with the specified pattern string.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.PatternParser.Parse">
+ <summary>
+ Parses the pattern into a chain of pattern converters.
+ </summary>
+ <returns>The head of a chain of pattern converters.</returns>
+ <remarks>
+ <para>
+ Parses the pattern into a chain of pattern converters.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.PatternParser.BuildCache">
+ <summary>
+ Build the unified cache of converters from the static and instance maps
+ </summary>
+ <returns>the list of all the converter names</returns>
+ <remarks>
+ <para>
+ Build the unified cache of converters from the static and instance maps
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.PatternParser.ParseInternal(System.String,System.String[])">
+ <summary>
+ Internal method to parse the specified pattern to find specified matches
+ </summary>
+ <param name="pattern">the pattern to parse</param>
+ <param name="matches">the converter names to match in the pattern</param>
+ <remarks>
+ <para>
+ The matches param must be sorted such that longer strings come before shorter ones.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.PatternParser.ProcessLiteral(System.String)">
+ <summary>
+ Process a parsed literal
+ </summary>
+ <param name="text">the literal text</param>
+ </member>
+ <member name="M:log4net.Util.PatternParser.ProcessConverter(System.String,System.String,log4net.Util.FormattingInfo)">
+ <summary>
+ Process a parsed converter pattern
+ </summary>
+ <param name="converterName">the name of the converter</param>
+ <param name="option">the optional option for the converter</param>
+ <param name="formattingInfo">the formatting info for the converter</param>
+ </member>
+ <member name="M:log4net.Util.PatternParser.AddConverter(log4net.Util.PatternConverter)">
+ <summary>
+ Resets the internal state of the parser and adds the specified pattern converter
+ to the chain.
+ </summary>
+ <param name="pc">The pattern converter to add.</param>
+ </member>
+ <member name="F:log4net.Util.PatternParser.m_head">
+ <summary>
+ The first pattern converter in the chain
+ </summary>
+ </member>
+ <member name="F:log4net.Util.PatternParser.m_tail">
+ <summary>
+ the last pattern converter in the chain
+ </summary>
+ </member>
+ <member name="F:log4net.Util.PatternParser.m_pattern">
+ <summary>
+ The pattern
+ </summary>
+ </member>
+ <member name="F:log4net.Util.PatternParser.m_patternConverters">
+ <summary>
+ Internal map of converter identifiers to converter types
+ </summary>
+ <remarks>
+ <para>
+ This map overrides the static s_globalRulesRegistry map.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Util.PatternParser.PatternConverters">
+ <summary>
+ Get the converter registry used by this parser
+ </summary>
+ <value>
+ The converter registry used by this parser
+ </value>
+ <remarks>
+ <para>
+ Get the converter registry used by this parser
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Util.PatternParser.StringLengthComparer">
+ <summary>
+ Sort strings by length
+ </summary>
+ <remarks>
+ <para>
+ <see cref="T:System.Collections.IComparer"/> that orders strings by string length.
+ The longest strings are placed first
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Util.PatternString">
+ <summary>
+ This class implements a patterned string.
+ </summary>
+ <remarks>
+ <para>
+ This string has embedded patterns that are resolved and expanded
+ when the string is formatted.
+ </para>
+ <para>
+ This class functions similarly to the <see cref="T:log4net.Layout.PatternLayout"/>
+ in that it accepts a pattern and renders it to a string. Unlike the
+ <see cref="T:log4net.Layout.PatternLayout"/> however the <c>PatternString</c>
+ does not render the properties of a specific <see cref="T:log4net.Core.LoggingEvent"/> but
+ of the process in general.
+ </para>
+ <para>
+ The recognized conversion pattern names are:
+ </para>
+ <list type="table">
+ <listheader>
+ <term>Conversion Pattern Name</term>
+ <description>Effect</description>
+ </listheader>
+ <item>
+ <term>appdomain</term>
+ <description>
+ <para>
+ Used to output the friendly name of the current AppDomain.
+ </para>
+ </description>
+ </item>
+ <item>
+ <term>date</term>
+ <description>
+ <para>
+ Used to output the date of the logging event in the local time zone.
+ To output the date in universal time use the <c>%utcdate</c> pattern.
+ The date conversion
+ specifier may be followed by a <i>date format specifier</i> enclosed
+ between braces. For example, <b>%date{HH:mm:ss,fff}</b> or
+ <b>%date{dd MMM yyyy HH:mm:ss,fff}</b>. If no date format specifier is
+ given then ISO8601 format is
+ assumed (<see cref="T:log4net.DateFormatter.Iso8601DateFormatter"/>).
+ </para>
+ <para>
+ The date format specifier admits the same syntax as the
+ time pattern string of the <see cref="M:System.DateTime.ToString(System.String)"/>.
+ </para>
+ <para>
+ For better results it is recommended to use the log4net date
+ formatters. These can be specified using one of the strings
+ "ABSOLUTE", "DATE" and "ISO8601" for specifying
+ <see cref="T:log4net.DateFormatter.AbsoluteTimeDateFormatter"/>,
+ <see cref="T:log4net.DateFormatter.DateTimeDateFormatter"/> and respectively
+ <see cref="T:log4net.DateFormatter.Iso8601DateFormatter"/>. For example,
+ <b>%date{ISO8601}</b> or <b>%date{ABSOLUTE}</b>.
+ </para>
+ <para>
+ These dedicated date formatters perform significantly
+ better than <see cref="M:System.DateTime.ToString(System.String)"/>.
+ </para>
+ </description>
+ </item>
+ <item>
+ <term>env</term>
+ <description>
+ <para>
+ Used to output the a specific environment variable. The key to
+ lookup must be specified within braces and directly following the
+ pattern specifier, e.g. <b>%env{COMPUTERNAME}</b> would include the value
+ of the <c>COMPUTERNAME</c> environment variable.
+ </para>
+ <para>
+ The <c>env</c> pattern is not supported on the .NET Compact Framework.
+ </para>
+ </description>
+ </item>
+ <item>
+ <term>identity</term>
+ <description>
+ <para>
+ Used to output the user name for the currently active user
+ (Principal.Identity.Name).
+ </para>
+ </description>
+ </item>
+ <item>
+ <term>newline</term>
+ <description>
+ <para>
+ Outputs the platform dependent line separator character or
+ characters.
+ </para>
+ <para>
+ This conversion pattern name offers the same performance as using
+ non-portable line separator strings such as "\n", or "\r\n".
+ Thus, it is the preferred way of specifying a line separator.
+ </para>
+ </description>
+ </item>
+ <item>
+ <term>processid</term>
+ <description>
+ <para>
+ Used to output the system process ID for the current process.
+ </para>
+ </description>
+ </item>
+ <item>
+ <term>property</term>
+ <description>
+ <para>
+ Used to output a specific context property. The key to
+ lookup must be specified within braces and directly following the
+ pattern specifier, e.g. <b>%property{user}</b> would include the value
+ from the property that is keyed by the string 'user'. Each property value
+ that is to be included in the log must be specified separately.
+ Properties are stored in logging contexts. By default
+ the <c>log4net:HostName</c> property is set to the name of machine on
+ which the event was originally logged.
+ </para>
+ <para>
+ If no key is specified, e.g. <b>%property</b> then all the keys and their
+ values are printed in a comma separated list.
+ </para>
+ <para>
+ The properties of an event are combined from a number of different
+ contexts. These are listed below in the order in which they are searched.
+ </para>
+ <list type="definition">
+ <item>
+ <term>the thread properties</term>
+ <description>
+ The <see cref="P:log4net.ThreadContext.Properties"/> that are set on the current
+ thread. These properties are shared by all events logged on this thread.
+ </description>
+ </item>
+ <item>
+ <term>the global properties</term>
+ <description>
+ The <see cref="P:log4net.GlobalContext.Properties"/> that are set globally. These
+ properties are shared by all the threads in the AppDomain.
+ </description>
+ </item>
+ </list>
+ </description>
+ </item>
+ <item>
+ <term>random</term>
+ <description>
+ <para>
+ Used to output a random string of characters. The string is made up of
+ uppercase letters and numbers. By default the string is 4 characters long.
+ The length of the string can be specified within braces directly following the
+ pattern specifier, e.g. <b>%random{8}</b> would output an 8 character string.
+ </para>
+ </description>
+ </item>
+ <item>
+ <term>username</term>
+ <description>
+ <para>
+ Used to output the WindowsIdentity for the currently
+ active user.
+ </para>
+ </description>
+ </item>
+ <item>
+ <term>utcdate</term>
+ <description>
+ <para>
+ Used to output the date of the logging event in universal time.
+ The date conversion
+ specifier may be followed by a <i>date format specifier</i> enclosed
+ between braces. For example, <b>%utcdate{HH:mm:ss,fff}</b> or
+ <b>%utcdate{dd MMM yyyy HH:mm:ss,fff}</b>. If no date format specifier is
+ given then ISO8601 format is
+ assumed (<see cref="T:log4net.DateFormatter.Iso8601DateFormatter"/>).
+ </para>
+ <para>
+ The date format specifier admits the same syntax as the
+ time pattern string of the <see cref="M:System.DateTime.ToString(System.String)"/>.
+ </para>
+ <para>
+ For better results it is recommended to use the log4net date
+ formatters. These can be specified using one of the strings
+ "ABSOLUTE", "DATE" and "ISO8601" for specifying
+ <see cref="T:log4net.DateFormatter.AbsoluteTimeDateFormatter"/>,
+ <see cref="T:log4net.DateFormatter.DateTimeDateFormatter"/> and respectively
+ <see cref="T:log4net.DateFormatter.Iso8601DateFormatter"/>. For example,
+ <b>%utcdate{ISO8601}</b> or <b>%utcdate{ABSOLUTE}</b>.
+ </para>
+ <para>
+ These dedicated date formatters perform significantly
+ better than <see cref="M:System.DateTime.ToString(System.String)"/>.
+ </para>
+ </description>
+ </item>
+ <item>
+ <term>%</term>
+ <description>
+ <para>
+ The sequence %% outputs a single percent sign.
+ </para>
+ </description>
+ </item>
+ </list>
+ <para>
+ Additional pattern converters may be registered with a specific <see cref="T:log4net.Util.PatternString"/>
+ instance using <see cref="M:log4net.Util.PatternString.AddConverter(log4net.Util.PatternString.ConverterInfo)"/> or
+ <see cref="M:log4net.Util.PatternString.AddConverter(System.String,System.Type)"/>.
+ </para>
+ <para>
+ See the <see cref="T:log4net.Layout.PatternLayout"/> for details on the
+ <i>format modifiers</i> supported by the patterns.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="F:log4net.Util.PatternString.s_globalRulesRegistry">
+ <summary>
+ Internal map of converter identifiers to converter types.
+ </summary>
+ </member>
+ <member name="F:log4net.Util.PatternString.m_pattern">
+ <summary>
+ the pattern
+ </summary>
+ </member>
+ <member name="F:log4net.Util.PatternString.m_head">
+ <summary>
+ the head of the pattern converter chain
+ </summary>
+ </member>
+ <member name="F:log4net.Util.PatternString.m_instanceRulesRegistry">
+ <summary>
+ patterns defined on this PatternString only
+ </summary>
+ </member>
+ <member name="M:log4net.Util.PatternString.#cctor">
+ <summary>
+ Initialize the global registry
+ </summary>
+ </member>
+ <member name="M:log4net.Util.PatternString.#ctor">
+ <summary>
+ Default constructor
+ </summary>
+ <remarks>
+ <para>
+ Initialize a new instance of <see cref="T:log4net.Util.PatternString"/>
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.PatternString.#ctor(System.String)">
+ <summary>
+ Constructs a PatternString
+ </summary>
+ <param name="pattern">The pattern to use with this PatternString</param>
+ <remarks>
+ <para>
+ Initialize a new instance of <see cref="T:log4net.Util.PatternString"/> with the pattern specified.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.PatternString.ActivateOptions">
+ <summary>
+ Initialize object options
+ </summary>
+ <remarks>
+ <para>
+ This is part of the <see cref="T:log4net.Core.IOptionHandler"/> delayed object
+ activation scheme. The <see cref="M:log4net.Util.PatternString.ActivateOptions"/> method must
+ be called on this object after the configuration properties have
+ been set. Until <see cref="M:log4net.Util.PatternString.ActivateOptions"/> is called this
+ object is in an undefined state and must not be used.
+ </para>
+ <para>
+ If any of the configuration properties are modified then
+ <see cref="M:log4net.Util.PatternString.ActivateOptions"/> must be called again.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.PatternString.CreatePatternParser(System.String)">
+ <summary>
+ Create the <see cref="T:log4net.Util.PatternParser"/> used to parse the pattern
+ </summary>
+ <param name="pattern">the pattern to parse</param>
+ <returns>The <see cref="T:log4net.Util.PatternParser"/></returns>
+ <remarks>
+ <para>
+ Returns PatternParser used to parse the conversion string. Subclasses
+ may override this to return a subclass of PatternParser which recognize
+ custom conversion pattern name.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.PatternString.Format(System.IO.TextWriter)">
+ <summary>
+ Produces a formatted string as specified by the conversion pattern.
+ </summary>
+ <param name="writer">The TextWriter to write the formatted event to</param>
+ <remarks>
+ <para>
+ Format the pattern to the <paramref name="writer"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.PatternString.Format">
+ <summary>
+ Format the pattern as a string
+ </summary>
+ <returns>the pattern formatted as a string</returns>
+ <remarks>
+ <para>
+ Format the pattern to a string.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.PatternString.AddConverter(log4net.Util.PatternString.ConverterInfo)">
+ <summary>
+ Add a converter to this PatternString
+ </summary>
+ <param name="converterInfo">the converter info</param>
+ <remarks>
+ <para>
+ This version of the method is used by the configurator.
+ Programmatic users should use the alternative <see cref="M:log4net.Util.PatternString.AddConverter(System.String,System.Type)"/> method.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.PatternString.AddConverter(System.String,System.Type)">
+ <summary>
+ Add a converter to this PatternString
+ </summary>
+ <param name="name">the name of the conversion pattern for this converter</param>
+ <param name="type">the type of the converter</param>
+ <remarks>
+ <para>
+ Add a converter to this PatternString
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Util.PatternString.ConversionPattern">
+ <summary>
+ Gets or sets the pattern formatting string
+ </summary>
+ <value>
+ The pattern formatting string
+ </value>
+ <remarks>
+ <para>
+ The <b>ConversionPattern</b> option. This is the string which
+ controls formatting and consists of a mix of literal content and
+ conversion specifiers.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Util.PatternString.ConverterInfo">
+ <summary>
+ Wrapper class used to map converter names to converter types
+ </summary>
+ <remarks>
+ <para>
+ Wrapper class used to map converter names to converter types
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.PatternString.ConverterInfo.#ctor">
+ <summary>
+ default constructor
+ </summary>
+ </member>
+ <member name="P:log4net.Util.PatternString.ConverterInfo.Name">
+ <summary>
+ Gets or sets the name of the conversion pattern
+ </summary>
+ <value>
+ The name of the conversion pattern
+ </value>
+ <remarks>
+ <para>
+ Gets or sets the name of the conversion pattern
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Util.PatternString.ConverterInfo.Type">
+ <summary>
+ Gets or sets the type of the converter
+ </summary>
+ <value>
+ The type of the converter
+ </value>
+ <remarks>
+ <para>
+ Gets or sets the type of the converter
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Util.PropertiesDictionary">
+ <summary>
+ String keyed object map.
+ </summary>
+ <remarks>
+ <para>
+ While this collection is serializable only member
+ objects that are serializable will
+ be serialized along with this collection.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="T:log4net.Util.ReadOnlyPropertiesDictionary">
+ <summary>
+ String keyed object map that is read only.
+ </summary>
+ <remarks>
+ <para>
+ This collection is readonly and cannot be modified.
+ </para>
+ <para>
+ While this collection is serializable only member
+ objects that are serializable will
+ be serialized along with this collection.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="F:log4net.Util.ReadOnlyPropertiesDictionary.m_hashtable">
+ <summary>
+ The Hashtable used to store the properties data
+ </summary>
+ </member>
+ <member name="M:log4net.Util.ReadOnlyPropertiesDictionary.#ctor">
+ <summary>
+ Constructor
+ </summary>
+ <remarks>
+ <para>
+ Initializes a new instance of the <see cref="T:log4net.Util.ReadOnlyPropertiesDictionary"/> class.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.ReadOnlyPropertiesDictionary.#ctor(log4net.Util.ReadOnlyPropertiesDictionary)">
+ <summary>
+ Copy Constructor
+ </summary>
+ <param name="propertiesDictionary">properties to copy</param>
+ <remarks>
+ <para>
+ Initializes a new instance of the <see cref="T:log4net.Util.ReadOnlyPropertiesDictionary"/> class.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.ReadOnlyPropertiesDictionary.#ctor(System.Runtime.Serialization.SerializationInfo,System.Runtime.Serialization.StreamingContext)">
+ <summary>
+ Deserialization constructor
+ </summary>
+ <param name="info">The <see cref="T:System.Runtime.Serialization.SerializationInfo"/> that holds the serialized object data.</param>
+ <param name="context">The <see cref="T:System.Runtime.Serialization.StreamingContext"/> that contains contextual information about the source or destination.</param>
+ <remarks>
+ <para>
+ Initializes a new instance of the <see cref="T:log4net.Util.ReadOnlyPropertiesDictionary"/> class
+ with serialized data.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.ReadOnlyPropertiesDictionary.GetKeys">
+ <summary>
+ Gets the key names.
+ </summary>
+ <returns>An array of all the keys.</returns>
+ <remarks>
+ <para>
+ Gets the key names.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.ReadOnlyPropertiesDictionary.Contains(System.String)">
+ <summary>
+ Test if the dictionary contains a specified key
+ </summary>
+ <param name="key">the key to look for</param>
+ <returns>true if the dictionary contains the specified key</returns>
+ <remarks>
+ <para>
+ Test if the dictionary contains a specified key
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.ReadOnlyPropertiesDictionary.GetObjectData(System.Runtime.Serialization.SerializationInfo,System.Runtime.Serialization.StreamingContext)">
+ <summary>
+ Serializes this object into the <see cref="T:System.Runtime.Serialization.SerializationInfo"/> provided.
+ </summary>
+ <param name="info">The <see cref="T:System.Runtime.Serialization.SerializationInfo"/> to populate with data.</param>
+ <param name="context">The destination for this serialization.</param>
+ <remarks>
+ <para>
+ Serializes this object into the <see cref="T:System.Runtime.Serialization.SerializationInfo"/> provided.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.ReadOnlyPropertiesDictionary.System#Collections#IDictionary#GetEnumerator">
+ <summary>
+ See <see cref="M:System.Collections.IDictionary.GetEnumerator"/>
+ </summary>
+ </member>
+ <member name="M:log4net.Util.ReadOnlyPropertiesDictionary.System#Collections#IDictionary#Remove(System.Object)">
+ <summary>
+ See <see cref="M:System.Collections.IDictionary.Remove(System.Object)"/>
+ </summary>
+ <param name="key"></param>
+ </member>
+ <member name="M:log4net.Util.ReadOnlyPropertiesDictionary.System#Collections#IDictionary#Contains(System.Object)">
+ <summary>
+ See <see cref="M:System.Collections.IDictionary.Contains(System.Object)"/>
+ </summary>
+ <param name="key"></param>
+ <returns></returns>
+ </member>
+ <member name="M:log4net.Util.ReadOnlyPropertiesDictionary.Clear">
+ <summary>
+ Remove all properties from the properties collection
+ </summary>
+ </member>
+ <member name="M:log4net.Util.ReadOnlyPropertiesDictionary.System#Collections#IDictionary#Add(System.Object,System.Object)">
+ <summary>
+ See <see cref="M:System.Collections.IDictionary.Add(System.Object,System.Object)"/>
+ </summary>
+ <param name="key"></param>
+ <param name="value"></param>
+ </member>
+ <member name="M:log4net.Util.ReadOnlyPropertiesDictionary.System#Collections#ICollection#CopyTo(System.Array,System.Int32)">
+ <summary>
+ See <see cref="M:System.Collections.ICollection.CopyTo(System.Array,System.Int32)"/>
+ </summary>
+ <param name="array"></param>
+ <param name="index"></param>
+ </member>
+ <member name="M:log4net.Util.ReadOnlyPropertiesDictionary.System#Collections#IEnumerable#GetEnumerator">
+ <summary>
+ See <see cref="M:System.Collections.IEnumerable.GetEnumerator"/>
+ </summary>
+ </member>
+ <member name="P:log4net.Util.ReadOnlyPropertiesDictionary.Item(System.String)">
+ <summary>
+ Gets or sets the value of the property with the specified key.
+ </summary>
+ <value>
+ The value of the property with the specified key.
+ </value>
+ <param name="key">The key of the property to get or set.</param>
+ <remarks>
+ <para>
+ The property value will only be serialized if it is serializable.
+ If it cannot be serialized it will be silently ignored if
+ a serialization operation is performed.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Util.ReadOnlyPropertiesDictionary.InnerHashtable">
+ <summary>
+ The hashtable used to store the properties
+ </summary>
+ <value>
+ The internal collection used to store the properties
+ </value>
+ <remarks>
+ <para>
+ The hashtable used to store the properties
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Util.ReadOnlyPropertiesDictionary.System#Collections#IDictionary#IsReadOnly">
+ <summary>
+ See <see cref="P:System.Collections.IDictionary.IsReadOnly"/>
+ </summary>
+ </member>
+ <member name="P:log4net.Util.ReadOnlyPropertiesDictionary.System#Collections#IDictionary#Item(System.Object)">
+ <summary>
+ See <see cref="P:System.Collections.IDictionary.Item(System.Object)"/>
+ </summary>
+ </member>
+ <member name="P:log4net.Util.ReadOnlyPropertiesDictionary.System#Collections#IDictionary#Values">
+ <summary>
+ See <see cref="P:System.Collections.IDictionary.Values"/>
+ </summary>
+ </member>
+ <member name="P:log4net.Util.ReadOnlyPropertiesDictionary.System#Collections#IDictionary#Keys">
+ <summary>
+ See <see cref="P:System.Collections.IDictionary.Keys"/>
+ </summary>
+ </member>
+ <member name="P:log4net.Util.ReadOnlyPropertiesDictionary.System#Collections#IDictionary#IsFixedSize">
+ <summary>
+ See <see cref="P:System.Collections.IDictionary.IsFixedSize"/>
+ </summary>
+ </member>
+ <member name="P:log4net.Util.ReadOnlyPropertiesDictionary.System#Collections#ICollection#IsSynchronized">
+ <summary>
+ See <see cref="P:System.Collections.ICollection.IsSynchronized"/>
+ </summary>
+ </member>
+ <member name="P:log4net.Util.ReadOnlyPropertiesDictionary.Count">
+ <summary>
+ The number of properties in this collection
+ </summary>
+ </member>
+ <member name="P:log4net.Util.ReadOnlyPropertiesDictionary.System#Collections#ICollection#SyncRoot">
+ <summary>
+ See <see cref="P:System.Collections.ICollection.SyncRoot"/>
+ </summary>
+ </member>
+ <member name="M:log4net.Util.PropertiesDictionary.#ctor">
+ <summary>
+ Constructor
+ </summary>
+ <remarks>
+ <para>
+ Initializes a new instance of the <see cref="T:log4net.Util.PropertiesDictionary"/> class.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.PropertiesDictionary.#ctor(log4net.Util.ReadOnlyPropertiesDictionary)">
+ <summary>
+ Constructor
+ </summary>
+ <param name="propertiesDictionary">properties to copy</param>
+ <remarks>
+ <para>
+ Initializes a new instance of the <see cref="T:log4net.Util.PropertiesDictionary"/> class.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.PropertiesDictionary.#ctor(System.Runtime.Serialization.SerializationInfo,System.Runtime.Serialization.StreamingContext)">
+ <summary>
+ Initializes a new instance of the <see cref="T:log4net.Util.PropertiesDictionary"/> class
+ with serialized data.
+ </summary>
+ <param name="info">The <see cref="T:System.Runtime.Serialization.SerializationInfo"/> that holds the serialized object data.</param>
+ <param name="context">The <see cref="T:System.Runtime.Serialization.StreamingContext"/> that contains contextual information about the source or destination.</param>
+ <remarks>
+ <para>
+ Because this class is sealed the serialization constructor is private.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.PropertiesDictionary.Remove(System.String)">
+ <summary>
+ Remove the entry with the specified key from this dictionary
+ </summary>
+ <param name="key">the key for the entry to remove</param>
+ <remarks>
+ <para>
+ Remove the entry with the specified key from this dictionary
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.PropertiesDictionary.System#Collections#IDictionary#GetEnumerator">
+ <summary>
+ See <see cref="M:System.Collections.IDictionary.GetEnumerator"/>
+ </summary>
+ <returns>an enumerator</returns>
+ <remarks>
+ <para>
+ Returns a <see cref="T:System.Collections.IDictionaryEnumerator"/> over the contest of this collection.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.PropertiesDictionary.System#Collections#IDictionary#Remove(System.Object)">
+ <summary>
+ See <see cref="M:System.Collections.IDictionary.Remove(System.Object)"/>
+ </summary>
+ <param name="key">the key to remove</param>
+ <remarks>
+ <para>
+ Remove the entry with the specified key from this dictionary
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.PropertiesDictionary.System#Collections#IDictionary#Contains(System.Object)">
+ <summary>
+ See <see cref="M:System.Collections.IDictionary.Contains(System.Object)"/>
+ </summary>
+ <param name="key">the key to lookup in the collection</param>
+ <returns><c>true</c> if the collection contains the specified key</returns>
+ <remarks>
+ <para>
+ Test if this collection contains a specified key.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.PropertiesDictionary.Clear">
+ <summary>
+ Remove all properties from the properties collection
+ </summary>
+ <remarks>
+ <para>
+ Remove all properties from the properties collection
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.PropertiesDictionary.System#Collections#IDictionary#Add(System.Object,System.Object)">
+ <summary>
+ See <see cref="M:System.Collections.IDictionary.Add(System.Object,System.Object)"/>
+ </summary>
+ <param name="key">the key</param>
+ <param name="value">the value to store for the key</param>
+ <remarks>
+ <para>
+ Store a value for the specified <see cref="T:System.String"/> <paramref name="key"/>.
+ </para>
+ </remarks>
+ <exception cref="T:System.ArgumentException">Thrown if the <paramref name="key"/> is not a string</exception>
+ </member>
+ <member name="M:log4net.Util.PropertiesDictionary.System#Collections#ICollection#CopyTo(System.Array,System.Int32)">
+ <summary>
+ See <see cref="M:System.Collections.ICollection.CopyTo(System.Array,System.Int32)"/>
+ </summary>
+ <param name="array"></param>
+ <param name="index"></param>
+ </member>
+ <member name="M:log4net.Util.PropertiesDictionary.System#Collections#IEnumerable#GetEnumerator">
+ <summary>
+ See <see cref="M:System.Collections.IEnumerable.GetEnumerator"/>
+ </summary>
+ </member>
+ <member name="P:log4net.Util.PropertiesDictionary.Item(System.String)">
+ <summary>
+ Gets or sets the value of the property with the specified key.
+ </summary>
+ <value>
+ The value of the property with the specified key.
+ </value>
+ <param name="key">The key of the property to get or set.</param>
+ <remarks>
+ <para>
+ The property value will only be serialized if it is serializable.
+ If it cannot be serialized it will be silently ignored if
+ a serialization operation is performed.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Util.PropertiesDictionary.System#Collections#IDictionary#IsReadOnly">
+ <summary>
+ See <see cref="P:System.Collections.IDictionary.IsReadOnly"/>
+ </summary>
+ <value>
+ <c>false</c>
+ </value>
+ <remarks>
+ <para>
+ This collection is modifiable. This property always
+ returns <c>false</c>.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Util.PropertiesDictionary.System#Collections#IDictionary#Item(System.Object)">
+ <summary>
+ See <see cref="P:System.Collections.IDictionary.Item(System.Object)"/>
+ </summary>
+ <value>
+ The value for the key specified.
+ </value>
+ <remarks>
+ <para>
+ Get or set a value for the specified <see cref="T:System.String"/> <paramref name="key"/>.
+ </para>
+ </remarks>
+ <exception cref="T:System.ArgumentException">Thrown if the <paramref name="key"/> is not a string</exception>
+ </member>
+ <member name="P:log4net.Util.PropertiesDictionary.System#Collections#IDictionary#Values">
+ <summary>
+ See <see cref="P:System.Collections.IDictionary.Values"/>
+ </summary>
+ </member>
+ <member name="P:log4net.Util.PropertiesDictionary.System#Collections#IDictionary#Keys">
+ <summary>
+ See <see cref="P:System.Collections.IDictionary.Keys"/>
+ </summary>
+ </member>
+ <member name="P:log4net.Util.PropertiesDictionary.System#Collections#IDictionary#IsFixedSize">
+ <summary>
+ See <see cref="P:System.Collections.IDictionary.IsFixedSize"/>
+ </summary>
+ </member>
+ <member name="P:log4net.Util.PropertiesDictionary.System#Collections#ICollection#IsSynchronized">
+ <summary>
+ See <see cref="P:System.Collections.ICollection.IsSynchronized"/>
+ </summary>
+ </member>
+ <member name="P:log4net.Util.PropertiesDictionary.System#Collections#ICollection#SyncRoot">
+ <summary>
+ See <see cref="P:System.Collections.ICollection.SyncRoot"/>
+ </summary>
+ </member>
+ <member name="T:log4net.Util.ProtectCloseTextWriter">
+ <summary>
+ A <see cref="T:System.IO.TextWriter"/> that ignores the <see cref="M:log4net.Util.ProtectCloseTextWriter.Close"/> message
+ </summary>
+ <remarks>
+ <para>
+ This writer is used in special cases where it is necessary
+ to protect a writer from being closed by a client.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="M:log4net.Util.ProtectCloseTextWriter.#ctor(System.IO.TextWriter)">
+ <summary>
+ Constructor
+ </summary>
+ <param name="writer">the writer to actually write to</param>
+ <remarks>
+ <para>
+ Create a new ProtectCloseTextWriter using a writer
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.ProtectCloseTextWriter.Attach(System.IO.TextWriter)">
+ <summary>
+ Attach this instance to a different underlying <see cref="T:System.IO.TextWriter"/>
+ </summary>
+ <param name="writer">the writer to attach to</param>
+ <remarks>
+ <para>
+ Attach this instance to a different underlying <see cref="T:System.IO.TextWriter"/>
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.ProtectCloseTextWriter.Close">
+ <summary>
+ Does not close the underlying output writer.
+ </summary>
+ <remarks>
+ <para>
+ Does not close the underlying output writer.
+ This method does nothing.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Util.ReaderWriterLock">
+ <summary>
+ Defines a lock that supports single writers and multiple readers
+ </summary>
+ <remarks>
+ <para>
+ <c>ReaderWriterLock</c> is used to synchronize access to a resource.
+ At any given time, it allows either concurrent read access for
+ multiple threads, or write access for a single thread. In a
+ situation where a resource is changed infrequently, a
+ <c>ReaderWriterLock</c> provides better throughput than a simple
+ one-at-a-time lock, such as <see cref="T:System.Threading.Monitor"/>.
+ </para>
+ <para>
+ If a platform does not support a <c>System.Threading.ReaderWriterLock</c>
+ implementation then all readers and writers are serialized. Therefore
+ the caller must not rely on multiple simultaneous readers.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="M:log4net.Util.ReaderWriterLock.#ctor">
+ <summary>
+ Constructor
+ </summary>
+ <remarks>
+ <para>
+ Initializes a new instance of the <see cref="T:log4net.Util.ReaderWriterLock"/> class.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.ReaderWriterLock.AcquireReaderLock">
+ <summary>
+ Acquires a reader lock
+ </summary>
+ <remarks>
+ <para>
+ <see cref="M:log4net.Util.ReaderWriterLock.AcquireReaderLock"/> blocks if a different thread has the writer
+ lock, or if at least one thread is waiting for the writer lock.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.ReaderWriterLock.ReleaseReaderLock">
+ <summary>
+ Decrements the lock count
+ </summary>
+ <remarks>
+ <para>
+ <see cref="M:log4net.Util.ReaderWriterLock.ReleaseReaderLock"/> decrements the lock count. When the count
+ reaches zero, the lock is released.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.ReaderWriterLock.AcquireWriterLock">
+ <summary>
+ Acquires the writer lock
+ </summary>
+ <remarks>
+ <para>
+ This method blocks if another thread has a reader lock or writer lock.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.ReaderWriterLock.ReleaseWriterLock">
+ <summary>
+ Decrements the lock count on the writer lock
+ </summary>
+ <remarks>
+ <para>
+ ReleaseWriterLock decrements the writer lock count.
+ When the count reaches zero, the writer lock is released.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Util.ReusableStringWriter">
+ <summary>
+ A <see cref="T:System.IO.StringWriter"/> that can be <see cref="M:log4net.Util.ReusableStringWriter.Reset(System.Int32,System.Int32)"/> and reused
+ </summary>
+ <remarks>
+ <para>
+ A <see cref="T:System.IO.StringWriter"/> that can be <see cref="M:log4net.Util.ReusableStringWriter.Reset(System.Int32,System.Int32)"/> and reused.
+ This uses a single buffer for string operations.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="M:log4net.Util.ReusableStringWriter.#ctor(System.IFormatProvider)">
+ <summary>
+ Create an instance of <see cref="T:log4net.Util.ReusableStringWriter"/>
+ </summary>
+ <param name="formatProvider">the format provider to use</param>
+ <remarks>
+ <para>
+ Create an instance of <see cref="T:log4net.Util.ReusableStringWriter"/>
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.ReusableStringWriter.Dispose(System.Boolean)">
+ <summary>
+ Override Dispose to prevent closing of writer
+ </summary>
+ <param name="disposing">flag</param>
+ <remarks>
+ <para>
+ Override Dispose to prevent closing of writer
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.ReusableStringWriter.Reset(System.Int32,System.Int32)">
+ <summary>
+ Reset this string writer so that it can be reused.
+ </summary>
+ <param name="maxCapacity">the maximum buffer capacity before it is trimmed</param>
+ <param name="defaultSize">the default size to make the buffer</param>
+ <remarks>
+ <para>
+ Reset this string writer so that it can be reused.
+ The internal buffers are cleared and reset.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Util.SystemInfo">
+ <summary>
+ Utility class for system specific information.
+ </summary>
+ <remarks>
+ <para>
+ Utility class of static methods for system specific information.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ <author>Alexey Solofnenko</author>
+ </member>
+ <member name="M:log4net.Util.SystemInfo.#ctor">
+ <summary>
+ Private constructor to prevent instances.
+ </summary>
+ <remarks>
+ <para>
+ Only static methods are exposed from this type.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.SystemInfo.#cctor">
+ <summary>
+ Initialize default values for private static fields.
+ </summary>
+ <remarks>
+ <para>
+ Only static methods are exposed from this type.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.SystemInfo.AssemblyLocationInfo(System.Reflection.Assembly)">
+ <summary>
+ Gets the assembly location path for the specified assembly.
+ </summary>
+ <param name="myAssembly">The assembly to get the location for.</param>
+ <returns>The location of the assembly.</returns>
+ <remarks>
+ <para>
+ This method does not guarantee to return the correct path
+ to the assembly. If only tries to give an indication as to
+ where the assembly was loaded from.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.SystemInfo.AssemblyQualifiedName(System.Type)">
+ <summary>
+ Gets the fully qualified name of the <see cref="T:System.Type"/>, including
+ the name of the assembly from which the <see cref="T:System.Type"/> was
+ loaded.
+ </summary>
+ <param name="type">The <see cref="T:System.Type"/> to get the fully qualified name for.</param>
+ <returns>The fully qualified name for the <see cref="T:System.Type"/>.</returns>
+ <remarks>
+ <para>
+ This is equivalent to the <c>Type.AssemblyQualifiedName</c> property,
+ but this method works on the .NET Compact Framework 1.0 as well as
+ the full .NET runtime.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.SystemInfo.AssemblyShortName(System.Reflection.Assembly)">
+ <summary>
+ Gets the short name of the <see cref="T:System.Reflection.Assembly"/>.
+ </summary>
+ <param name="myAssembly">The <see cref="T:System.Reflection.Assembly"/> to get the name for.</param>
+ <returns>The short name of the <see cref="T:System.Reflection.Assembly"/>.</returns>
+ <remarks>
+ <para>
+ The short name of the assembly is the <see cref="P:System.Reflection.Assembly.FullName"/>
+ without the version, culture, or public key. i.e. it is just the
+ assembly's file name without the extension.
+ </para>
+ <para>
+ Use this rather than <c>Assembly.GetName().Name</c> because that
+ is not available on the Compact Framework.
+ </para>
+ <para>
+ Because of a FileIOPermission security demand we cannot do
+ the obvious Assembly.GetName().Name. We are allowed to get
+ the <see cref="P:System.Reflection.Assembly.FullName"/> of the assembly so we
+ start from there and strip out just the assembly name.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.SystemInfo.AssemblyFileName(System.Reflection.Assembly)">
+ <summary>
+ Gets the file name portion of the <see cref="T:System.Reflection.Assembly"/>, including the extension.
+ </summary>
+ <param name="myAssembly">The <see cref="T:System.Reflection.Assembly"/> to get the file name for.</param>
+ <returns>The file name of the assembly.</returns>
+ <remarks>
+ <para>
+ Gets the file name portion of the <see cref="T:System.Reflection.Assembly"/>, including the extension.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.SystemInfo.GetTypeFromString(System.Type,System.String,System.Boolean,System.Boolean)">
+ <summary>
+ Loads the type specified in the type string.
+ </summary>
+ <param name="relativeType">A sibling type to use to load the type.</param>
+ <param name="typeName">The name of the type to load.</param>
+ <param name="throwOnError">Flag set to <c>true</c> to throw an exception if the type cannot be loaded.</param>
+ <param name="ignoreCase"><c>true</c> to ignore the case of the type name; otherwise, <c>false</c></param>
+ <returns>The type loaded or <c>null</c> if it could not be loaded.</returns>
+ <remarks>
+ <para>
+ If the type name is fully qualified, i.e. if contains an assembly name in
+ the type name, the type will be loaded from the system using
+ <see cref="M:System.Type.GetType(System.String,System.Boolean)"/>.
+ </para>
+ <para>
+ If the type name is not fully qualified, it will be loaded from the assembly
+ containing the specified relative type. If the type is not found in the assembly
+ then all the loaded assemblies will be searched for the type.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.SystemInfo.GetTypeFromString(System.String,System.Boolean,System.Boolean)">
+ <summary>
+ Loads the type specified in the type string.
+ </summary>
+ <param name="typeName">The name of the type to load.</param>
+ <param name="throwOnError">Flag set to <c>true</c> to throw an exception if the type cannot be loaded.</param>
+ <param name="ignoreCase"><c>true</c> to ignore the case of the type name; otherwise, <c>false</c></param>
+ <returns>The type loaded or <c>null</c> if it could not be loaded.</returns>
+ <remarks>
+ <para>
+ If the type name is fully qualified, i.e. if contains an assembly name in
+ the type name, the type will be loaded from the system using
+ <see cref="M:System.Type.GetType(System.String,System.Boolean)"/>.
+ </para>
+ <para>
+ If the type name is not fully qualified it will be loaded from the
+ assembly that is directly calling this method. If the type is not found
+ in the assembly then all the loaded assemblies will be searched for the type.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.SystemInfo.GetTypeFromString(System.Reflection.Assembly,System.String,System.Boolean,System.Boolean)">
+ <summary>
+ Loads the type specified in the type string.
+ </summary>
+ <param name="relativeAssembly">An assembly to load the type from.</param>
+ <param name="typeName">The name of the type to load.</param>
+ <param name="throwOnError">Flag set to <c>true</c> to throw an exception if the type cannot be loaded.</param>
+ <param name="ignoreCase"><c>true</c> to ignore the case of the type name; otherwise, <c>false</c></param>
+ <returns>The type loaded or <c>null</c> if it could not be loaded.</returns>
+ <remarks>
+ <para>
+ If the type name is fully qualified, i.e. if contains an assembly name in
+ the type name, the type will be loaded from the system using
+ <see cref="M:System.Type.GetType(System.String,System.Boolean)"/>.
+ </para>
+ <para>
+ If the type name is not fully qualified it will be loaded from the specified
+ assembly. If the type is not found in the assembly then all the loaded assemblies
+ will be searched for the type.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.SystemInfo.NewGuid">
+ <summary>
+ Generate a new guid
+ </summary>
+ <returns>A new Guid</returns>
+ <remarks>
+ <para>
+ Generate a new guid
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.SystemInfo.CreateArgumentOutOfRangeException(System.String,System.Object,System.String)">
+ <summary>
+ Create an <see cref="T:System.ArgumentOutOfRangeException"/>
+ </summary>
+ <param name="parameterName">The name of the parameter that caused the exception</param>
+ <param name="actualValue">The value of the argument that causes this exception</param>
+ <param name="message">The message that describes the error</param>
+ <returns>the ArgumentOutOfRangeException object</returns>
+ <remarks>
+ <para>
+ Create a new instance of the <see cref="T:System.ArgumentOutOfRangeException"/> class
+ with a specified error message, the parameter name, and the value
+ of the argument.
+ </para>
+ <para>
+ The Compact Framework does not support the 3 parameter constructor for the
+ <see cref="T:System.ArgumentOutOfRangeException"/> type. This method provides an
+ implementation that works for all platforms.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.SystemInfo.TryParse(System.String,System.Int32@)">
+ <summary>
+ Parse a string into an <see cref="T:System.Int32"/> value
+ </summary>
+ <param name="s">the string to parse</param>
+ <param name="val">out param where the parsed value is placed</param>
+ <returns><c>true</c> if the string was able to be parsed into an integer</returns>
+ <remarks>
+ <para>
+ Attempts to parse the string into an integer. If the string cannot
+ be parsed then this method returns <c>false</c>. The method does not throw an exception.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.SystemInfo.TryParse(System.String,System.Int64@)">
+ <summary>
+ Parse a string into an <see cref="T:System.Int64"/> value
+ </summary>
+ <param name="s">the string to parse</param>
+ <param name="val">out param where the parsed value is placed</param>
+ <returns><c>true</c> if the string was able to be parsed into an integer</returns>
+ <remarks>
+ <para>
+ Attempts to parse the string into an integer. If the string cannot
+ be parsed then this method returns <c>false</c>. The method does not throw an exception.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.SystemInfo.GetAppSetting(System.String)">
+ <summary>
+ Lookup an application setting
+ </summary>
+ <param name="key">the application settings key to lookup</param>
+ <returns>the value for the key, or <c>null</c></returns>
+ <remarks>
+ <para>
+ Configuration APIs are not supported under the Compact Framework
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.SystemInfo.ConvertToFullPath(System.String)">
+ <summary>
+ Convert a path into a fully qualified local file path.
+ </summary>
+ <param name="path">The path to convert.</param>
+ <returns>The fully qualified path.</returns>
+ <remarks>
+ <para>
+ Converts the path specified to a fully
+ qualified path. If the path is relative it is
+ taken as relative from the application base
+ directory.
+ </para>
+ <para>
+ The path specified must be a local file path, a URI is not supported.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.SystemInfo.CreateCaseInsensitiveHashtable">
+ <summary>
+ Creates a new case-insensitive instance of the <see cref="T:System.Collections.Hashtable"/> class with the default initial capacity.
+ </summary>
+ <returns>A new case-insensitive instance of the <see cref="T:System.Collections.Hashtable"/> class with the default initial capacity</returns>
+ <remarks>
+ <para>
+ The new Hashtable instance uses the default load factor, the CaseInsensitiveHashCodeProvider, and the CaseInsensitiveComparer.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Util.SystemInfo.EmptyTypes">
+ <summary>
+ Gets an empty array of types.
+ </summary>
+ <remarks>
+ <para>
+ The <c>Type.EmptyTypes</c> field is not available on
+ the .NET Compact Framework 1.0.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Util.SystemInfo.s_hostName">
+ <summary>
+ Cache the host name for the current machine
+ </summary>
+ </member>
+ <member name="F:log4net.Util.SystemInfo.s_appFriendlyName">
+ <summary>
+ Cache the application friendly name
+ </summary>
+ </member>
+ <member name="F:log4net.Util.SystemInfo.s_nullText">
+ <summary>
+ Text to output when a <c>null</c> is encountered.
+ </summary>
+ </member>
+ <member name="F:log4net.Util.SystemInfo.s_notAvailableText">
+ <summary>
+ Text to output when an unsupported feature is requested.
+ </summary>
+ </member>
+ <member name="F:log4net.Util.SystemInfo.s_processStartTime">
+ <summary>
+ Start time for the current process.
+ </summary>
+ </member>
+ <member name="P:log4net.Util.SystemInfo.NewLine">
+ <summary>
+ Gets the system dependent line terminator.
+ </summary>
+ <value>
+ The system dependent line terminator.
+ </value>
+ <remarks>
+ <para>
+ Gets the system dependent line terminator.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Util.SystemInfo.ApplicationBaseDirectory">
+ <summary>
+ Gets the base directory for this <see cref="T:System.AppDomain"/>.
+ </summary>
+ <value>The base directory path for the current <see cref="T:System.AppDomain"/>.</value>
+ <remarks>
+ <para>
+ Gets the base directory for this <see cref="T:System.AppDomain"/>.
+ </para>
+ <para>
+ The value returned may be either a local file path or a URI.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Util.SystemInfo.ConfigurationFileLocation">
+ <summary>
+ Gets the path to the configuration file for the current <see cref="T:System.AppDomain"/>.
+ </summary>
+ <value>The path to the configuration file for the current <see cref="T:System.AppDomain"/>.</value>
+ <remarks>
+ <para>
+ The .NET Compact Framework 1.0 does not have a concept of a configuration
+ file. For this runtime, we use the entry assembly location as the root for
+ the configuration file name.
+ </para>
+ <para>
+ The value returned may be either a local file path or a URI.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Util.SystemInfo.EntryAssemblyLocation">
+ <summary>
+ Gets the path to the file that first executed in the current <see cref="T:System.AppDomain"/>.
+ </summary>
+ <value>The path to the entry assembly.</value>
+ <remarks>
+ <para>
+ Gets the path to the file that first executed in the current <see cref="T:System.AppDomain"/>.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Util.SystemInfo.CurrentThreadId">
+ <summary>
+ Gets the ID of the current thread.
+ </summary>
+ <value>The ID of the current thread.</value>
+ <remarks>
+ <para>
+ On the .NET framework, the <c>AppDomain.GetCurrentThreadId</c> method
+ is used to obtain the thread ID for the current thread. This is the
+ operating system ID for the thread.
+ </para>
+ <para>
+ On the .NET Compact Framework 1.0 it is not possible to get the
+ operating system thread ID for the current thread. The native method
+ <c>GetCurrentThreadId</c> is implemented inline in a header file
+ and cannot be called.
+ </para>
+ <para>
+ On the .NET Framework 2.0 the <c>Thread.ManagedThreadId</c> is used as this
+ gives a stable id unrelated to the operating system thread ID which may
+ change if the runtime is using fibers.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Util.SystemInfo.HostName">
+ <summary>
+ Get the host name or machine name for the current machine
+ </summary>
+ <value>
+ The hostname or machine name
+ </value>
+ <remarks>
+ <para>
+ Get the host name or machine name for the current machine
+ </para>
+ <para>
+ The host name (<see cref="M:System.Net.Dns.GetHostName"/>) or
+ the machine name (<c>Environment.MachineName</c>) for
+ the current machine, or if neither of these are available
+ then <c>NOT AVAILABLE</c> is returned.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Util.SystemInfo.ApplicationFriendlyName">
+ <summary>
+ Get this application's friendly name
+ </summary>
+ <value>
+ The friendly name of this application as a string
+ </value>
+ <remarks>
+ <para>
+ If available the name of the application is retrieved from
+ the <c>AppDomain</c> using <c>AppDomain.CurrentDomain.FriendlyName</c>.
+ </para>
+ <para>
+ Otherwise the file name of the entry assembly is used.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Util.SystemInfo.ProcessStartTime">
+ <summary>
+ Get the start time for the current process.
+ </summary>
+ <remarks>
+ <para>
+ This is the time at which the log4net library was loaded into the
+ AppDomain. Due to reports of a hang in the call to <c>System.Diagnostics.Process.StartTime</c>
+ this is not the start time for the current process.
+ </para>
+ <para>
+ The log4net library should be loaded by an application early during its
+ startup, therefore this start time should be a good approximation for
+ the actual start time.
+ </para>
+ <para>
+ Note that AppDomains may be loaded and unloaded within the
+ same process without the process terminating, however this start time
+ will be set per AppDomain.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Util.SystemInfo.NullText">
+ <summary>
+ Text to output when a <c>null</c> is encountered.
+ </summary>
+ <remarks>
+ <para>
+ Use this value to indicate a <c>null</c> has been encountered while
+ outputting a string representation of an item.
+ </para>
+ <para>
+ The default value is <c>(null)</c>. This value can be overridden by specifying
+ a value for the <c>log4net.NullText</c> appSetting in the application's
+ .config file.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Util.SystemInfo.NotAvailableText">
+ <summary>
+ Text to output when an unsupported feature is requested.
+ </summary>
+ <remarks>
+ <para>
+ Use this value when an unsupported feature is requested.
+ </para>
+ <para>
+ The default value is <c>NOT AVAILABLE</c>. This value can be overridden by specifying
+ a value for the <c>log4net.NotAvailableText</c> appSetting in the application's
+ .config file.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Util.SystemStringFormat">
+ <summary>
+ Utility class that represents a format string.
+ </summary>
+ <remarks>
+ <para>
+ Utility class that represents a format string.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="M:log4net.Util.SystemStringFormat.#ctor(System.IFormatProvider,System.String,System.Object[])">
+ <summary>
+ Initialise the <see cref="T:log4net.Util.SystemStringFormat"/>
+ </summary>
+ <param name="provider">An <see cref="T:System.IFormatProvider"/> that supplies culture-specific formatting information.</param>
+ <param name="format">A <see cref="T:System.String"/> containing zero or more format items.</param>
+ <param name="args">An <see cref="T:System.Object"/> array containing zero or more objects to format.</param>
+ </member>
+ <member name="M:log4net.Util.SystemStringFormat.ToString">
+ <summary>
+ Format the string and arguments
+ </summary>
+ <returns>the formatted string</returns>
+ </member>
+ <member name="M:log4net.Util.SystemStringFormat.StringFormat(System.IFormatProvider,System.String,System.Object[])">
+ <summary>
+ Replaces the format item in a specified <see cref="T:System.String"/> with the text equivalent
+ of the value of a corresponding <see cref="T:System.Object"/> instance in a specified array.
+ A specified parameter supplies culture-specific formatting information.
+ </summary>
+ <param name="provider">An <see cref="T:System.IFormatProvider"/> that supplies culture-specific formatting information.</param>
+ <param name="format">A <see cref="T:System.String"/> containing zero or more format items.</param>
+ <param name="args">An <see cref="T:System.Object"/> array containing zero or more objects to format.</param>
+ <returns>
+ A copy of format in which the format items have been replaced by the <see cref="T:System.String"/>
+ equivalent of the corresponding instances of <see cref="T:System.Object"/> in args.
+ </returns>
+ <remarks>
+ <para>
+ This method does not throw exceptions. If an exception thrown while formatting the result the
+ exception and arguments are returned in the result string.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.SystemStringFormat.StringFormatError(System.Exception,System.String,System.Object[])">
+ <summary>
+ Process an error during StringFormat
+ </summary>
+ </member>
+ <member name="M:log4net.Util.SystemStringFormat.RenderArray(System.Array,System.Text.StringBuilder)">
+ <summary>
+ Dump the contents of an array into a string builder
+ </summary>
+ </member>
+ <member name="M:log4net.Util.SystemStringFormat.RenderObject(System.Object,System.Text.StringBuilder)">
+ <summary>
+ Dump an object to a string
+ </summary>
+ </member>
+ <member name="T:log4net.Util.ThreadContextProperties">
+ <summary>
+ Implementation of Properties collection for the <see cref="T:log4net.ThreadContext"/>
+ </summary>
+ <remarks>
+ <para>
+ Class implements a collection of properties that is specific to each thread.
+ The class is not synchronized as each thread has its own <see cref="T:log4net.Util.PropertiesDictionary"/>.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="F:log4net.Util.ThreadContextProperties.s_threadLocalSlot">
+ <summary>
+ The thread local data slot to use to store a PropertiesDictionary.
+ </summary>
+ </member>
+ <member name="M:log4net.Util.ThreadContextProperties.#ctor">
+ <summary>
+ Internal constructor
+ </summary>
+ <remarks>
+ <para>
+ Initializes a new instance of the <see cref="T:log4net.Util.ThreadContextProperties"/> class.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.ThreadContextProperties.Remove(System.String)">
+ <summary>
+ Remove a property
+ </summary>
+ <param name="key">the key for the entry to remove</param>
+ <remarks>
+ <para>
+ Remove a property
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.ThreadContextProperties.Clear">
+ <summary>
+ Clear all properties
+ </summary>
+ <remarks>
+ <para>
+ Clear all properties
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.ThreadContextProperties.GetProperties(System.Boolean)">
+ <summary>
+ Get the <c>PropertiesDictionary</c> for this thread.
+ </summary>
+ <param name="create">create the dictionary if it does not exist, otherwise return null if is does not exist</param>
+ <returns>the properties for this thread</returns>
+ <remarks>
+ <para>
+ The collection returned is only to be used on the calling thread. If the
+ caller needs to share the collection between different threads then the
+ caller must clone the collection before doing so.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Util.ThreadContextProperties.Item(System.String)">
+ <summary>
+ Gets or sets the value of a property
+ </summary>
+ <value>
+ The value for the property with the specified key
+ </value>
+ <remarks>
+ <para>
+ Gets or sets the value of a property
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Util.ThreadContextStack">
+ <summary>
+ Implementation of Stack for the <see cref="T:log4net.ThreadContext"/>
+ </summary>
+ <remarks>
+ <para>
+ Implementation of Stack for the <see cref="T:log4net.ThreadContext"/>
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="F:log4net.Util.ThreadContextStack.m_stack">
+ <summary>
+ The stack store.
+ </summary>
+ </member>
+ <member name="M:log4net.Util.ThreadContextStack.#ctor">
+ <summary>
+ Internal constructor
+ </summary>
+ <remarks>
+ <para>
+ Initializes a new instance of the <see cref="T:log4net.Util.ThreadContextStack"/> class.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.ThreadContextStack.Clear">
+ <summary>
+ Clears all the contextual information held in this stack.
+ </summary>
+ <remarks>
+ <para>
+ Clears all the contextual information held in this stack.
+ Only call this if you think that this tread is being reused after
+ a previous call execution which may not have completed correctly.
+ You do not need to use this method if you always guarantee to call
+ the <see cref="M:System.IDisposable.Dispose"/> method of the <see cref="T:System.IDisposable"/>
+ returned from <see cref="M:log4net.Util.ThreadContextStack.Push(System.String)"/> even in exceptional circumstances,
+ for example by using the <c>using(log4net.ThreadContext.Stacks["NDC"].Push("Stack_Message"))</c>
+ syntax.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.ThreadContextStack.Pop">
+ <summary>
+ Removes the top context from this stack.
+ </summary>
+ <returns>The message in the context that was removed from the top of this stack.</returns>
+ <remarks>
+ <para>
+ Remove the top context from this stack, and return
+ it to the caller. If this stack is empty then an
+ empty string (not <see langword="null"/>) is returned.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.ThreadContextStack.Push(System.String)">
+ <summary>
+ Pushes a new context message into this stack.
+ </summary>
+ <param name="message">The new context message.</param>
+ <returns>
+ An <see cref="T:System.IDisposable"/> that can be used to clean up the context stack.
+ </returns>
+ <remarks>
+ <para>
+ Pushes a new context onto this stack. An <see cref="T:System.IDisposable"/>
+ is returned that can be used to clean up this stack. This
+ can be easily combined with the <c>using</c> keyword to scope the
+ context.
+ </para>
+ </remarks>
+ <example>Simple example of using the <c>Push</c> method with the <c>using</c> keyword.
+ <code lang="C#">
+ using(log4net.ThreadContext.Stacks["NDC"].Push("Stack_Message"))
+ {
+ log.Warn("This should have an ThreadContext Stack message");
+ }
+ </code>
+ </example>
+ </member>
+ <member name="M:log4net.Util.ThreadContextStack.GetFullMessage">
+ <summary>
+ Gets the current context information for this stack.
+ </summary>
+ <returns>The current context information.</returns>
+ </member>
+ <member name="M:log4net.Util.ThreadContextStack.ToString">
+ <summary>
+ Gets the current context information for this stack.
+ </summary>
+ <returns>Gets the current context information</returns>
+ <remarks>
+ <para>
+ Gets the current context information for this stack.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.ThreadContextStack.log4net#Core#IFixingRequired#GetFixedObject">
+ <summary>
+ Get a portable version of this object
+ </summary>
+ <returns>the portable instance of this object</returns>
+ <remarks>
+ <para>
+ Get a cross thread portable version of this object
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Util.ThreadContextStack.Count">
+ <summary>
+ The number of messages in the stack
+ </summary>
+ <value>
+ The current number of messages in the stack
+ </value>
+ <remarks>
+ <para>
+ The current number of messages in the stack. That is
+ the number of times <see cref="M:log4net.Util.ThreadContextStack.Push(System.String)"/> has been called
+ minus the number of times <see cref="M:log4net.Util.ThreadContextStack.Pop"/> has been called.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Util.ThreadContextStack.InternalStack">
+ <summary>
+ Gets and sets the internal stack used by this <see cref="T:log4net.Util.ThreadContextStack"/>
+ </summary>
+ <value>The internal storage stack</value>
+ <remarks>
+ <para>
+ This property is provided only to support backward compatability
+ of the <see cref="T:log4net.NDC"/>. Tytpically the internal stack should not
+ be modified.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Util.ThreadContextStack.StackFrame">
+ <summary>
+ Inner class used to represent a single context frame in the stack.
+ </summary>
+ <remarks>
+ <para>
+ Inner class used to represent a single context frame in the stack.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.ThreadContextStack.StackFrame.#ctor(System.String,log4net.Util.ThreadContextStack.StackFrame)">
+ <summary>
+ Constructor
+ </summary>
+ <param name="message">The message for this context.</param>
+ <param name="parent">The parent context in the chain.</param>
+ <remarks>
+ <para>
+ Initializes a new instance of the <see cref="T:log4net.Util.ThreadContextStack.StackFrame"/> class
+ with the specified message and parent context.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Util.ThreadContextStack.StackFrame.Message">
+ <summary>
+ Get the message.
+ </summary>
+ <value>The message.</value>
+ <remarks>
+ <para>
+ Get the message.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Util.ThreadContextStack.StackFrame.FullMessage">
+ <summary>
+ Gets the full text of the context down to the root level.
+ </summary>
+ <value>
+ The full text of the context down to the root level.
+ </value>
+ <remarks>
+ <para>
+ Gets the full text of the context down to the root level.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Util.ThreadContextStack.AutoPopStackFrame">
+ <summary>
+ Struct returned from the <see cref="M:log4net.Util.ThreadContextStack.Push(System.String)"/> method.
+ </summary>
+ <remarks>
+ <para>
+ This struct implements the <see cref="T:System.IDisposable"/> and is designed to be used
+ with the <see langword="using"/> pattern to remove the stack frame at the end of the scope.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Util.ThreadContextStack.AutoPopStackFrame.m_frameStack">
+ <summary>
+ The ThreadContextStack internal stack
+ </summary>
+ </member>
+ <member name="F:log4net.Util.ThreadContextStack.AutoPopStackFrame.m_frameDepth">
+ <summary>
+ The depth to trim the stack to when this instance is disposed
+ </summary>
+ </member>
+ <member name="M:log4net.Util.ThreadContextStack.AutoPopStackFrame.#ctor(System.Collections.Stack,System.Int32)">
+ <summary>
+ Constructor
+ </summary>
+ <param name="frameStack">The internal stack used by the ThreadContextStack.</param>
+ <param name="frameDepth">The depth to return the stack to when this object is disposed.</param>
+ <remarks>
+ <para>
+ Initializes a new instance of the <see cref="T:log4net.Util.ThreadContextStack.AutoPopStackFrame"/> class with
+ the specified stack and return depth.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.ThreadContextStack.AutoPopStackFrame.Dispose">
+ <summary>
+ Returns the stack to the correct depth.
+ </summary>
+ <remarks>
+ <para>
+ Returns the stack to the correct depth.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Util.ThreadContextStacks">
+ <summary>
+ Implementation of Stacks collection for the <see cref="T:log4net.ThreadContext"/>
+ </summary>
+ <remarks>
+ <para>
+ Implementation of Stacks collection for the <see cref="T:log4net.ThreadContext"/>
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="M:log4net.Util.ThreadContextStacks.#ctor(log4net.Util.ContextPropertiesBase)">
+ <summary>
+ Internal constructor
+ </summary>
+ <remarks>
+ <para>
+ Initializes a new instance of the <see cref="T:log4net.Util.ThreadContextStacks"/> class.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Util.ThreadContextStacks.Item(System.String)">
+ <summary>
+ Gets the named thread context stack
+ </summary>
+ <value>
+ The named stack
+ </value>
+ <remarks>
+ <para>
+ Gets the named thread context stack
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Util.Transform">
+ <summary>
+ Utility class for transforming strings.
+ </summary>
+ <remarks>
+ <para>
+ Utility class for transforming strings.
+ </para>
+ </remarks>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="M:log4net.Util.Transform.#ctor">
+ <summary>
+ Initializes a new instance of the <see cref="T:log4net.Util.Transform"/> class.
+ </summary>
+ <remarks>
+ <para>
+ Uses a private access modifier to prevent instantiation of this class.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.Transform.WriteEscapedXmlString(System.Xml.XmlWriter,System.String,System.String)">
+ <summary>
+ Write a string to an <see cref="T:System.Xml.XmlWriter"/>
+ </summary>
+ <param name="writer">the writer to write to</param>
+ <param name="textData">the string to write</param>
+ <param name="invalidCharReplacement">The string to replace non XML compliant chars with</param>
+ <remarks>
+ <para>
+ The test is escaped either using XML escape entities
+ or using CDATA sections.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.Transform.MaskXmlInvalidCharacters(System.String,System.String)">
+ <summary>
+ Replace invalid XML characters in text string
+ </summary>
+ <param name="textData">the XML text input string</param>
+ <param name="mask">the string to use in place of invalid characters</param>
+ <returns>A string that does not contain invalid XML characters.</returns>
+ <remarks>
+ <para>
+ Certain Unicode code points are not allowed in the XML InfoSet, for
+ details see: <a href="http://www.w3.org/TR/REC-xml/#charsets">http://www.w3.org/TR/REC-xml/#charsets</a>.
+ </para>
+ <para>
+ This method replaces any illegal characters in the input string
+ with the mask string specified.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.Transform.CountSubstrings(System.String,System.String)">
+ <summary>
+ Count the number of times that the substring occurs in the text
+ </summary>
+ <param name="text">the text to search</param>
+ <param name="substring">the substring to find</param>
+ <returns>the number of times the substring occurs in the text</returns>
+ <remarks>
+ <para>
+ The substring is assumed to be non repeating within itself.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Util.WindowsSecurityContext">
+ <summary>
+ Impersonate a Windows Account
+ </summary>
+ <remarks>
+ <para>
+ This <see cref="T:log4net.Core.SecurityContext"/> impersonates a Windows account.
+ </para>
+ <para>
+ How the impersonation is done depends on the value of <see cref="M:log4net.Util.WindowsSecurityContext.Impersonate(System.Object)"/>.
+ This allows the context to either impersonate a set of user credentials specified
+ using username, domain name and password or to revert to the process credentials.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.WindowsSecurityContext.#ctor">
+ <summary>
+ Default constructor
+ </summary>
+ <remarks>
+ <para>
+ Default constructor
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.WindowsSecurityContext.ActivateOptions">
+ <summary>
+ Initialize the SecurityContext based on the options set.
+ </summary>
+ <remarks>
+ <para>
+ This is part of the <see cref="T:log4net.Core.IOptionHandler"/> delayed object
+ activation scheme. The <see cref="M:log4net.Util.WindowsSecurityContext.ActivateOptions"/> method must
+ be called on this object after the configuration properties have
+ been set. Until <see cref="M:log4net.Util.WindowsSecurityContext.ActivateOptions"/> is called this
+ object is in an undefined state and must not be used.
+ </para>
+ <para>
+ If any of the configuration properties are modified then
+ <see cref="M:log4net.Util.WindowsSecurityContext.ActivateOptions"/> must be called again.
+ </para>
+ <para>
+ The security context will try to Logon the specified user account and
+ capture a primary token for impersonation.
+ </para>
+ </remarks>
+ <exception cref="T:System.ArgumentNullException">The required <see cref="P:log4net.Util.WindowsSecurityContext.UserName"/>,
+ <see cref="P:log4net.Util.WindowsSecurityContext.DomainName"/> or <see cref="P:log4net.Util.WindowsSecurityContext.Password"/> properties were not specified.</exception>
+ </member>
+ <member name="M:log4net.Util.WindowsSecurityContext.Impersonate(System.Object)">
+ <summary>
+ Impersonate the Windows account specified by the <see cref="P:log4net.Util.WindowsSecurityContext.UserName"/> and <see cref="P:log4net.Util.WindowsSecurityContext.DomainName"/> properties.
+ </summary>
+ <param name="state">caller provided state</param>
+ <returns>
+ An <see cref="T:System.IDisposable"/> instance that will revoke the impersonation of this SecurityContext
+ </returns>
+ <remarks>
+ <para>
+ Depending on the <see cref="P:log4net.Util.WindowsSecurityContext.Credentials"/> property either
+ impersonate a user using credentials supplied or revert
+ to the process credentials.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.WindowsSecurityContext.LogonUser(System.String,System.String,System.String)">
+ <summary>
+ Create a <see cref="T:System.Security.Principal.WindowsIdentity"/> given the userName, domainName and password.
+ </summary>
+ <param name="userName">the user name</param>
+ <param name="domainName">the domain name</param>
+ <param name="password">the password</param>
+ <returns>the <see cref="T:System.Security.Principal.WindowsIdentity"/> for the account specified</returns>
+ <remarks>
+ <para>
+ Uses the Windows API call LogonUser to get a principal token for the account. This
+ token is used to initialize the WindowsIdentity.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Util.WindowsSecurityContext.Credentials">
+ <summary>
+ Gets or sets the impersonation mode for this security context
+ </summary>
+ <value>
+ The impersonation mode for this security context
+ </value>
+ <remarks>
+ <para>
+ Impersonate either a user with user credentials or
+ revert this thread to the credentials of the process.
+ The value is one of the <see cref="T:log4net.Util.WindowsSecurityContext.ImpersonationMode"/>
+ enum.
+ </para>
+ <para>
+ The default value is <see cref="F:log4net.Util.WindowsSecurityContext.ImpersonationMode.User"/>
+ </para>
+ <para>
+ When the mode is set to <see cref="F:log4net.Util.WindowsSecurityContext.ImpersonationMode.User"/>
+ the user's credentials are established using the
+ <see cref="P:log4net.Util.WindowsSecurityContext.UserName"/>, <see cref="P:log4net.Util.WindowsSecurityContext.DomainName"/> and <see cref="P:log4net.Util.WindowsSecurityContext.Password"/>
+ values.
+ </para>
+ <para>
+ When the mode is set to <see cref="F:log4net.Util.WindowsSecurityContext.ImpersonationMode.Process"/>
+ no other properties need to be set. If the calling thread is
+ impersonating then it will be reverted back to the process credentials.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Util.WindowsSecurityContext.UserName">
+ <summary>
+ Gets or sets the Windows username for this security context
+ </summary>
+ <value>
+ The Windows username for this security context
+ </value>
+ <remarks>
+ <para>
+ This property must be set if <see cref="P:log4net.Util.WindowsSecurityContext.Credentials"/>
+ is set to <see cref="F:log4net.Util.WindowsSecurityContext.ImpersonationMode.User"/> (the default setting).
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Util.WindowsSecurityContext.DomainName">
+ <summary>
+ Gets or sets the Windows domain name for this security context
+ </summary>
+ <value>
+ The Windows domain name for this security context
+ </value>
+ <remarks>
+ <para>
+ The default value for <see cref="P:log4net.Util.WindowsSecurityContext.DomainName"/> is the local machine name
+ taken from the <see cref="P:System.Environment.MachineName"/> property.
+ </para>
+ <para>
+ This property must be set if <see cref="P:log4net.Util.WindowsSecurityContext.Credentials"/>
+ is set to <see cref="F:log4net.Util.WindowsSecurityContext.ImpersonationMode.User"/> (the default setting).
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.Util.WindowsSecurityContext.Password">
+ <summary>
+ Sets the password for the Windows account specified by the <see cref="P:log4net.Util.WindowsSecurityContext.UserName"/> and <see cref="P:log4net.Util.WindowsSecurityContext.DomainName"/> properties.
+ </summary>
+ <value>
+ The password for the Windows account specified by the <see cref="P:log4net.Util.WindowsSecurityContext.UserName"/> and <see cref="P:log4net.Util.WindowsSecurityContext.DomainName"/> properties.
+ </value>
+ <remarks>
+ <para>
+ This property must be set if <see cref="P:log4net.Util.WindowsSecurityContext.Credentials"/>
+ is set to <see cref="F:log4net.Util.WindowsSecurityContext.ImpersonationMode.User"/> (the default setting).
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.Util.WindowsSecurityContext.ImpersonationMode">
+ <summary>
+ The impersonation modes for the <see cref="T:log4net.Util.WindowsSecurityContext"/>
+ </summary>
+ <remarks>
+ <para>
+ See the <see cref="P:log4net.Util.WindowsSecurityContext.Credentials"/> property for
+ details.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.Util.WindowsSecurityContext.ImpersonationMode.User">
+ <summary>
+ Impersonate a user using the credentials supplied
+ </summary>
+ </member>
+ <member name="F:log4net.Util.WindowsSecurityContext.ImpersonationMode.Process">
+ <summary>
+ Revert this the thread to the credentials of the process
+ </summary>
+ </member>
+ <member name="T:log4net.Util.WindowsSecurityContext.DisposableImpersonationContext">
+ <summary>
+ Adds <see cref="T:System.IDisposable"/> to <see cref="T:System.Security.Principal.WindowsImpersonationContext"/>
+ </summary>
+ <remarks>
+ <para>
+ Helper class to expose the <see cref="T:System.Security.Principal.WindowsImpersonationContext"/>
+ through the <see cref="T:System.IDisposable"/> interface.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.WindowsSecurityContext.DisposableImpersonationContext.#ctor(System.Security.Principal.WindowsImpersonationContext)">
+ <summary>
+ Constructor
+ </summary>
+ <param name="impersonationContext">the impersonation context being wrapped</param>
+ <remarks>
+ <para>
+ Constructor
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.Util.WindowsSecurityContext.DisposableImpersonationContext.Dispose">
+ <summary>
+ Revert the impersonation
+ </summary>
+ <remarks>
+ <para>
+ Revert the impersonation
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.GlobalContext">
+ <summary>
+ The log4net Global Context.
+ </summary>
+ <remarks>
+ <para>
+ The <c>GlobalContext</c> provides a location for global debugging
+ information to be stored.
+ </para>
+ <para>
+ The global context has a properties map and these properties can
+ be included in the output of log messages. The <see cref="T:log4net.Layout.PatternLayout"/>
+ supports selecting and outputing these properties.
+ </para>
+ <para>
+ By default the <c>log4net:HostName</c> property is set to the name of
+ the current machine.
+ </para>
+ </remarks>
+ <example>
+ <code lang="C#">
+ GlobalContext.Properties["hostname"] = Environment.MachineName;
+ </code>
+ </example>
+ <threadsafety static="true" instance="true"/>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="M:log4net.GlobalContext.#ctor">
+ <summary>
+ Private Constructor.
+ </summary>
+ <remarks>
+ Uses a private access modifier to prevent instantiation of this class.
+ </remarks>
+ </member>
+ <member name="F:log4net.GlobalContext.s_properties">
+ <summary>
+ The global context properties instance
+ </summary>
+ </member>
+ <member name="P:log4net.GlobalContext.Properties">
+ <summary>
+ The global properties map.
+ </summary>
+ <value>
+ The global properties map.
+ </value>
+ <remarks>
+ <para>
+ The global properties map.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.LogicalThreadContext">
+ <summary>
+ The log4net Logical Thread Context.
+ </summary>
+ <remarks>
+ <para>
+ The <c>LogicalThreadContext</c> provides a location for <see cref="T:System.Runtime.Remoting.Messaging.CallContext"/> specific debugging
+ information to be stored.
+ The <c>LogicalThreadContext</c> properties override any <see cref="T:log4net.ThreadContext"/> or <see cref="T:log4net.GlobalContext"/>
+ properties with the same name.
+ </para>
+ <para>
+ The Logical Thread Context has a properties map and a stack.
+ The properties and stack can
+ be included in the output of log messages. The <see cref="T:log4net.Layout.PatternLayout"/>
+ supports selecting and outputting these properties.
+ </para>
+ <para>
+ The Logical Thread Context provides a diagnostic context for the current call context.
+ This is an instrument for distinguishing interleaved log
+ output from different sources. Log output is typically interleaved
+ when a server handles multiple clients near-simultaneously.
+ </para>
+ <para>
+ The Logical Thread Context is managed on a per <see cref="T:System.Runtime.Remoting.Messaging.CallContext"/> basis.
+ </para>
+ </remarks>
+ <example>Example of using the thread context properties to store a username.
+ <code lang="C#">
+ LogicalThreadContext.Properties["user"] = userName;
+ log.Info("This log message has a LogicalThreadContext Property called 'user'");
+ </code>
+ </example>
+ <example>Example of how to push a message into the context stack
+ <code lang="C#">
+ using(LogicalThreadContext.Stacks["LDC"].Push("my context message"))
+ {
+ log.Info("This log message has a LogicalThreadContext Stack message that includes 'my context message'");
+
+ } // at the end of the using block the message is automatically popped
+ </code>
+ </example>
+ <threadsafety static="true" instance="true"/>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="M:log4net.LogicalThreadContext.#ctor">
+ <summary>
+ Private Constructor.
+ </summary>
+ <remarks>
+ <para>
+ Uses a private access modifier to prevent instantiation of this class.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.LogicalThreadContext.s_properties">
+ <summary>
+ The thread context properties instance
+ </summary>
+ </member>
+ <member name="F:log4net.LogicalThreadContext.s_stacks">
+ <summary>
+ The thread context stacks instance
+ </summary>
+ </member>
+ <member name="P:log4net.LogicalThreadContext.Properties">
+ <summary>
+ The thread properties map
+ </summary>
+ <value>
+ The thread properties map
+ </value>
+ <remarks>
+ <para>
+ The <c>LogicalThreadContext</c> properties override any <see cref="T:log4net.ThreadContext"/>
+ or <see cref="T:log4net.GlobalContext"/> properties with the same name.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.LogicalThreadContext.Stacks">
+ <summary>
+ The thread stacks
+ </summary>
+ <value>
+ stack map
+ </value>
+ <remarks>
+ <para>
+ The logical thread stacks.
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.LogManager">
+ <summary>
+ This class is used by client applications to request logger instances.
+ </summary>
+ <remarks>
+ <para>
+ This class has static methods that are used by a client to request
+ a logger instance. The <see cref="M:log4net.LogManager.GetLogger(System.String)"/> method is
+ used to retrieve a logger.
+ </para>
+ <para>
+ See the <see cref="T:log4net.ILog"/> interface for more details.
+ </para>
+ </remarks>
+ <example>Simple example of logging messages
+ <code lang="C#">
+ ILog log = LogManager.GetLogger("application-log");
+
+ log.Info("Application Start");
+ log.Debug("This is a debug message");
+
+ if (log.IsDebugEnabled)
+ {
+ log.Debug("This is another debug message");
+ }
+ </code>
+ </example>
+ <threadsafety static="true" instance="true"/>
+ <seealso cref="T:log4net.ILog"/>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="M:log4net.LogManager.#ctor">
+ <summary>
+ Initializes a new instance of the <see cref="T:log4net.LogManager"/> class.
+ </summary>
+ <remarks>
+ Uses a private access modifier to prevent instantiation of this class.
+ </remarks>
+ </member>
+ <member name="M:log4net.LogManager.Exists(System.String)">
+ <overloads>Returns the named logger if it exists.</overloads>
+ <summary>
+ Returns the named logger if it exists.
+ </summary>
+ <remarks>
+ <para>
+ If the named logger exists (in the default repository) then it
+ returns a reference to the logger, otherwise it returns <c>null</c>.
+ </para>
+ </remarks>
+ <param name="name">The fully qualified logger name to look for.</param>
+ <returns>The logger found, or <c>null</c> if no logger could be found.</returns>
+ </member>
+ <member name="M:log4net.LogManager.Exists(System.String,System.String)">
+ <summary>
+ Returns the named logger if it exists.
+ </summary>
+ <remarks>
+ <para>
+ If the named logger exists (in the specified repository) then it
+ returns a reference to the logger, otherwise it returns
+ <c>null</c>.
+ </para>
+ </remarks>
+ <param name="repository">The repository to lookup in.</param>
+ <param name="name">The fully qualified logger name to look for.</param>
+ <returns>
+ The logger found, or <c>null</c> if the logger doesn't exist in the specified
+ repository.
+ </returns>
+ </member>
+ <member name="M:log4net.LogManager.Exists(System.Reflection.Assembly,System.String)">
+ <summary>
+ Returns the named logger if it exists.
+ </summary>
+ <remarks>
+ <para>
+ If the named logger exists (in the repository for the specified assembly) then it
+ returns a reference to the logger, otherwise it returns
+ <c>null</c>.
+ </para>
+ </remarks>
+ <param name="repositoryAssembly">The assembly to use to lookup the repository.</param>
+ <param name="name">The fully qualified logger name to look for.</param>
+ <returns>
+ The logger, or <c>null</c> if the logger doesn't exist in the specified
+ assembly's repository.
+ </returns>
+ </member>
+ <member name="M:log4net.LogManager.GetCurrentLoggers">
+ <overloads>Get the currently defined loggers.</overloads>
+ <summary>
+ Returns all the currently defined loggers in the default repository.
+ </summary>
+ <remarks>
+ <para>The root logger is <b>not</b> included in the returned array.</para>
+ </remarks>
+ <returns>All the defined loggers.</returns>
+ </member>
+ <member name="M:log4net.LogManager.GetCurrentLoggers(System.String)">
+ <summary>
+ Returns all the currently defined loggers in the specified repository.
+ </summary>
+ <param name="repository">The repository to lookup in.</param>
+ <remarks>
+ The root logger is <b>not</b> included in the returned array.
+ </remarks>
+ <returns>All the defined loggers.</returns>
+ </member>
+ <member name="M:log4net.LogManager.GetCurrentLoggers(System.Reflection.Assembly)">
+ <summary>
+ Returns all the currently defined loggers in the specified assembly's repository.
+ </summary>
+ <param name="repositoryAssembly">The assembly to use to lookup the repository.</param>
+ <remarks>
+ The root logger is <b>not</b> included in the returned array.
+ </remarks>
+ <returns>All the defined loggers.</returns>
+ </member>
+ <member name="M:log4net.LogManager.GetLogger(System.String)">
+ <overloads>Get or create a logger.</overloads>
+ <summary>
+ Retrieves or creates a named logger.
+ </summary>
+ <remarks>
+ <para>
+ Retrieves a logger named as the <paramref name="name"/>
+ parameter. If the named logger already exists, then the
+ existing instance will be returned. Otherwise, a new instance is
+ created.
+ </para>
+ <para>By default, loggers do not have a set level but inherit
+ it from the hierarchy. This is one of the central features of
+ log4net.
+ </para>
+ </remarks>
+ <param name="name">The name of the logger to retrieve.</param>
+ <returns>The logger with the name specified.</returns>
+ </member>
+ <member name="M:log4net.LogManager.GetLogger(System.String,System.String)">
+ <summary>
+ Retrieves or creates a named logger.
+ </summary>
+ <remarks>
+ <para>
+ Retrieve a logger named as the <paramref name="name"/>
+ parameter. If the named logger already exists, then the
+ existing instance will be returned. Otherwise, a new instance is
+ created.
+ </para>
+ <para>
+ By default, loggers do not have a set level but inherit
+ it from the hierarchy. This is one of the central features of
+ log4net.
+ </para>
+ </remarks>
+ <param name="repository">The repository to lookup in.</param>
+ <param name="name">The name of the logger to retrieve.</param>
+ <returns>The logger with the name specified.</returns>
+ </member>
+ <member name="M:log4net.LogManager.GetLogger(System.Reflection.Assembly,System.String)">
+ <summary>
+ Retrieves or creates a named logger.
+ </summary>
+ <remarks>
+ <para>
+ Retrieve a logger named as the <paramref name="name"/>
+ parameter. If the named logger already exists, then the
+ existing instance will be returned. Otherwise, a new instance is
+ created.
+ </para>
+ <para>
+ By default, loggers do not have a set level but inherit
+ it from the hierarchy. This is one of the central features of
+ log4net.
+ </para>
+ </remarks>
+ <param name="repositoryAssembly">The assembly to use to lookup the repository.</param>
+ <param name="name">The name of the logger to retrieve.</param>
+ <returns>The logger with the name specified.</returns>
+ </member>
+ <member name="M:log4net.LogManager.GetLogger(System.Type)">
+ <summary>
+ Shorthand for <see cref="M:log4net.LogManager.GetLogger(System.String)"/>.
+ </summary>
+ <remarks>
+ Get the logger for the fully qualified name of the type specified.
+ </remarks>
+ <param name="type">The full name of <paramref name="type"/> will be used as the name of the logger to retrieve.</param>
+ <returns>The logger with the name specified.</returns>
+ </member>
+ <member name="M:log4net.LogManager.GetLogger(System.String,System.Type)">
+ <summary>
+ Shorthand for <see cref="M:log4net.LogManager.GetLogger(System.String)"/>.
+ </summary>
+ <remarks>
+ Gets the logger for the fully qualified name of the type specified.
+ </remarks>
+ <param name="repository">The repository to lookup in.</param>
+ <param name="type">The full name of <paramref name="type"/> will be used as the name of the logger to retrieve.</param>
+ <returns>The logger with the name specified.</returns>
+ </member>
+ <member name="M:log4net.LogManager.GetLogger(System.Reflection.Assembly,System.Type)">
+ <summary>
+ Shorthand for <see cref="M:log4net.LogManager.GetLogger(System.String)"/>.
+ </summary>
+ <remarks>
+ Gets the logger for the fully qualified name of the type specified.
+ </remarks>
+ <param name="repositoryAssembly">The assembly to use to lookup the repository.</param>
+ <param name="type">The full name of <paramref name="type"/> will be used as the name of the logger to retrieve.</param>
+ <returns>The logger with the name specified.</returns>
+ </member>
+ <member name="M:log4net.LogManager.Shutdown">
+ <summary>
+ Shuts down the log4net system.
+ </summary>
+ <remarks>
+ <para>
+ Calling this method will <b>safely</b> close and remove all
+ appenders in all the loggers including root contained in all the
+ default repositories.
+ </para>
+ <para>
+ Some appenders need to be closed before the application exists.
+ Otherwise, pending logging events might be lost.
+ </para>
+ <para>The <c>shutdown</c> method is careful to close nested
+ appenders before closing regular appenders. This is allows
+ configurations where a regular appender is attached to a logger
+ and again to a nested appender.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.LogManager.ShutdownRepository">
+ <overloads>Shutdown a logger repository.</overloads>
+ <summary>
+ Shuts down the default repository.
+ </summary>
+ <remarks>
+ <para>
+ Calling this method will <b>safely</b> close and remove all
+ appenders in all the loggers including root contained in the
+ default repository.
+ </para>
+ <para>Some appenders need to be closed before the application exists.
+ Otherwise, pending logging events might be lost.
+ </para>
+ <para>The <c>shutdown</c> method is careful to close nested
+ appenders before closing regular appenders. This is allows
+ configurations where a regular appender is attached to a logger
+ and again to a nested appender.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.LogManager.ShutdownRepository(System.String)">
+ <summary>
+ Shuts down the repository for the repository specified.
+ </summary>
+ <remarks>
+ <para>
+ Calling this method will <b>safely</b> close and remove all
+ appenders in all the loggers including root contained in the
+ <paramref name="repository"/> specified.
+ </para>
+ <para>
+ Some appenders need to be closed before the application exists.
+ Otherwise, pending logging events might be lost.
+ </para>
+ <para>The <c>shutdown</c> method is careful to close nested
+ appenders before closing regular appenders. This is allows
+ configurations where a regular appender is attached to a logger
+ and again to a nested appender.
+ </para>
+ </remarks>
+ <param name="repository">The repository to shutdown.</param>
+ </member>
+ <member name="M:log4net.LogManager.ShutdownRepository(System.Reflection.Assembly)">
+ <summary>
+ Shuts down the repository specified.
+ </summary>
+ <remarks>
+ <para>
+ Calling this method will <b>safely</b> close and remove all
+ appenders in all the loggers including root contained in the
+ repository. The repository is looked up using
+ the <paramref name="repositoryAssembly"/> specified.
+ </para>
+ <para>
+ Some appenders need to be closed before the application exists.
+ Otherwise, pending logging events might be lost.
+ </para>
+ <para>
+ The <c>shutdown</c> method is careful to close nested
+ appenders before closing regular appenders. This is allows
+ configurations where a regular appender is attached to a logger
+ and again to a nested appender.
+ </para>
+ </remarks>
+ <param name="repositoryAssembly">The assembly to use to lookup the repository.</param>
+ </member>
+ <member name="M:log4net.LogManager.ResetConfiguration">
+ <overloads>Reset the configuration of a repository</overloads>
+ <summary>
+ Resets all values contained in this repository instance to their defaults.
+ </summary>
+ <remarks>
+ <para>
+ Resets all values contained in the repository instance to their
+ defaults. This removes all appenders from all loggers, sets
+ the level of all non-root loggers to <c>null</c>,
+ sets their additivity flag to <c>true</c> and sets the level
+ of the root logger to <see cref="F:log4net.Core.Level.Debug"/>. Moreover,
+ message disabling is set to its default "off" value.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.LogManager.ResetConfiguration(System.String)">
+ <summary>
+ Resets all values contained in this repository instance to their defaults.
+ </summary>
+ <remarks>
+ <para>
+ Reset all values contained in the repository instance to their
+ defaults. This removes all appenders from all loggers, sets
+ the level of all non-root loggers to <c>null</c>,
+ sets their additivity flag to <c>true</c> and sets the level
+ of the root logger to <see cref="F:log4net.Core.Level.Debug"/>. Moreover,
+ message disabling is set to its default "off" value.
+ </para>
+ </remarks>
+ <param name="repository">The repository to reset.</param>
+ </member>
+ <member name="M:log4net.LogManager.ResetConfiguration(System.Reflection.Assembly)">
+ <summary>
+ Resets all values contained in this repository instance to their defaults.
+ </summary>
+ <remarks>
+ <para>
+ Reset all values contained in the repository instance to their
+ defaults. This removes all appenders from all loggers, sets
+ the level of all non-root loggers to <c>null</c>,
+ sets their additivity flag to <c>true</c> and sets the level
+ of the root logger to <see cref="F:log4net.Core.Level.Debug"/>. Moreover,
+ message disabling is set to its default "off" value.
+ </para>
+ </remarks>
+ <param name="repositoryAssembly">The assembly to use to lookup the repository to reset.</param>
+ </member>
+ <member name="M:log4net.LogManager.GetLoggerRepository">
+ <overloads>Get the logger repository.</overloads>
+ <summary>
+ Returns the default <see cref="T:log4net.Repository.ILoggerRepository"/> instance.
+ </summary>
+ <remarks>
+ <para>
+ Gets the <see cref="T:log4net.Repository.ILoggerRepository"/> for the repository specified
+ by the callers assembly (<see cref="M:System.Reflection.Assembly.GetCallingAssembly"/>).
+ </para>
+ </remarks>
+ <returns>The <see cref="T:log4net.Repository.ILoggerRepository"/> instance for the default repository.</returns>
+ </member>
+ <member name="M:log4net.LogManager.GetLoggerRepository(System.String)">
+ <summary>
+ Returns the default <see cref="T:log4net.Repository.ILoggerRepository"/> instance.
+ </summary>
+ <returns>The default <see cref="T:log4net.Repository.ILoggerRepository"/> instance.</returns>
+ <remarks>
+ <para>
+ Gets the <see cref="T:log4net.Repository.ILoggerRepository"/> for the repository specified
+ by the <paramref name="repository"/> argument.
+ </para>
+ </remarks>
+ <param name="repository">The repository to lookup in.</param>
+ </member>
+ <member name="M:log4net.LogManager.GetLoggerRepository(System.Reflection.Assembly)">
+ <summary>
+ Returns the default <see cref="T:log4net.Repository.ILoggerRepository"/> instance.
+ </summary>
+ <returns>The default <see cref="T:log4net.Repository.ILoggerRepository"/> instance.</returns>
+ <remarks>
+ <para>
+ Gets the <see cref="T:log4net.Repository.ILoggerRepository"/> for the repository specified
+ by the <paramref name="repositoryAssembly"/> argument.
+ </para>
+ </remarks>
+ <param name="repositoryAssembly">The assembly to use to lookup the repository.</param>
+ </member>
+ <member name="M:log4net.LogManager.GetRepository">
+ <overloads>Get a logger repository.</overloads>
+ <summary>
+ Returns the default <see cref="T:log4net.Repository.ILoggerRepository"/> instance.
+ </summary>
+ <remarks>
+ <para>
+ Gets the <see cref="T:log4net.Repository.ILoggerRepository"/> for the repository specified
+ by the callers assembly (<see cref="M:System.Reflection.Assembly.GetCallingAssembly"/>).
+ </para>
+ </remarks>
+ <returns>The <see cref="T:log4net.Repository.ILoggerRepository"/> instance for the default repository.</returns>
+ </member>
+ <member name="M:log4net.LogManager.GetRepository(System.String)">
+ <summary>
+ Returns the default <see cref="T:log4net.Repository.ILoggerRepository"/> instance.
+ </summary>
+ <returns>The default <see cref="T:log4net.Repository.ILoggerRepository"/> instance.</returns>
+ <remarks>
+ <para>
+ Gets the <see cref="T:log4net.Repository.ILoggerRepository"/> for the repository specified
+ by the <paramref name="repository"/> argument.
+ </para>
+ </remarks>
+ <param name="repository">The repository to lookup in.</param>
+ </member>
+ <member name="M:log4net.LogManager.GetRepository(System.Reflection.Assembly)">
+ <summary>
+ Returns the default <see cref="T:log4net.Repository.ILoggerRepository"/> instance.
+ </summary>
+ <returns>The default <see cref="T:log4net.Repository.ILoggerRepository"/> instance.</returns>
+ <remarks>
+ <para>
+ Gets the <see cref="T:log4net.Repository.ILoggerRepository"/> for the repository specified
+ by the <paramref name="repositoryAssembly"/> argument.
+ </para>
+ </remarks>
+ <param name="repositoryAssembly">The assembly to use to lookup the repository.</param>
+ </member>
+ <member name="M:log4net.LogManager.CreateDomain(System.Type)">
+ <overloads>Create a domain</overloads>
+ <summary>
+ Creates a repository with the specified repository type.
+ </summary>
+ <remarks>
+ <para>
+ <b>CreateDomain is obsolete. Use CreateRepository instead of CreateDomain.</b>
+ </para>
+ <para>
+ The <see cref="T:log4net.Repository.ILoggerRepository"/> created will be associated with the repository
+ specified such that a call to <see cref="M:log4net.LogManager.GetRepository"/> will return
+ the same repository instance.
+ </para>
+ </remarks>
+ <param name="repositoryType">A <see cref="T:System.Type"/> that implements <see cref="T:log4net.Repository.ILoggerRepository"/>
+ and has a no arg constructor. An instance of this type will be created to act
+ as the <see cref="T:log4net.Repository.ILoggerRepository"/> for the repository specified.</param>
+ <returns>The <see cref="T:log4net.Repository.ILoggerRepository"/> created for the repository.</returns>
+ </member>
+ <member name="M:log4net.LogManager.CreateRepository(System.Type)">
+ <overloads>Create a logger repository.</overloads>
+ <summary>
+ Creates a repository with the specified repository type.
+ </summary>
+ <param name="repositoryType">A <see cref="T:System.Type"/> that implements <see cref="T:log4net.Repository.ILoggerRepository"/>
+ and has a no arg constructor. An instance of this type will be created to act
+ as the <see cref="T:log4net.Repository.ILoggerRepository"/> for the repository specified.</param>
+ <returns>The <see cref="T:log4net.Repository.ILoggerRepository"/> created for the repository.</returns>
+ <remarks>
+ <para>
+ The <see cref="T:log4net.Repository.ILoggerRepository"/> created will be associated with the repository
+ specified such that a call to <see cref="M:log4net.LogManager.GetRepository"/> will return
+ the same repository instance.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.LogManager.CreateDomain(System.String)">
+ <summary>
+ Creates a repository with the specified name.
+ </summary>
+ <remarks>
+ <para>
+ <b>CreateDomain is obsolete. Use CreateRepository instead of CreateDomain.</b>
+ </para>
+ <para>
+ Creates the default type of <see cref="T:log4net.Repository.ILoggerRepository"/> which is a
+ <see cref="T:log4net.Repository.Hierarchy.Hierarchy"/> object.
+ </para>
+ <para>
+ The <paramref name="repository"/> name must be unique. Repositories cannot be redefined.
+ An <see cref="T:System.Exception"/> will be thrown if the repository already exists.
+ </para>
+ </remarks>
+ <param name="repository">The name of the repository, this must be unique amongst repositories.</param>
+ <returns>The <see cref="T:log4net.Repository.ILoggerRepository"/> created for the repository.</returns>
+ <exception cref="T:log4net.Core.LogException">The specified repository already exists.</exception>
+ </member>
+ <member name="M:log4net.LogManager.CreateRepository(System.String)">
+ <summary>
+ Creates a repository with the specified name.
+ </summary>
+ <remarks>
+ <para>
+ Creates the default type of <see cref="T:log4net.Repository.ILoggerRepository"/> which is a
+ <see cref="T:log4net.Repository.Hierarchy.Hierarchy"/> object.
+ </para>
+ <para>
+ The <paramref name="repository"/> name must be unique. Repositories cannot be redefined.
+ An <see cref="T:System.Exception"/> will be thrown if the repository already exists.
+ </para>
+ </remarks>
+ <param name="repository">The name of the repository, this must be unique amongst repositories.</param>
+ <returns>The <see cref="T:log4net.Repository.ILoggerRepository"/> created for the repository.</returns>
+ <exception cref="T:log4net.Core.LogException">The specified repository already exists.</exception>
+ </member>
+ <member name="M:log4net.LogManager.CreateDomain(System.String,System.Type)">
+ <summary>
+ Creates a repository with the specified name and repository type.
+ </summary>
+ <remarks>
+ <para>
+ <b>CreateDomain is obsolete. Use CreateRepository instead of CreateDomain.</b>
+ </para>
+ <para>
+ The <paramref name="repository"/> name must be unique. Repositories cannot be redefined.
+ An <see cref="T:System.Exception"/> will be thrown if the repository already exists.
+ </para>
+ </remarks>
+ <param name="repository">The name of the repository, this must be unique to the repository.</param>
+ <param name="repositoryType">A <see cref="T:System.Type"/> that implements <see cref="T:log4net.Repository.ILoggerRepository"/>
+ and has a no arg constructor. An instance of this type will be created to act
+ as the <see cref="T:log4net.Repository.ILoggerRepository"/> for the repository specified.</param>
+ <returns>The <see cref="T:log4net.Repository.ILoggerRepository"/> created for the repository.</returns>
+ <exception cref="T:log4net.Core.LogException">The specified repository already exists.</exception>
+ </member>
+ <member name="M:log4net.LogManager.CreateRepository(System.String,System.Type)">
+ <summary>
+ Creates a repository with the specified name and repository type.
+ </summary>
+ <remarks>
+ <para>
+ The <paramref name="repository"/> name must be unique. Repositories cannot be redefined.
+ An <see cref="T:System.Exception"/> will be thrown if the repository already exists.
+ </para>
+ </remarks>
+ <param name="repository">The name of the repository, this must be unique to the repository.</param>
+ <param name="repositoryType">A <see cref="T:System.Type"/> that implements <see cref="T:log4net.Repository.ILoggerRepository"/>
+ and has a no arg constructor. An instance of this type will be created to act
+ as the <see cref="T:log4net.Repository.ILoggerRepository"/> for the repository specified.</param>
+ <returns>The <see cref="T:log4net.Repository.ILoggerRepository"/> created for the repository.</returns>
+ <exception cref="T:log4net.Core.LogException">The specified repository already exists.</exception>
+ </member>
+ <member name="M:log4net.LogManager.CreateDomain(System.Reflection.Assembly,System.Type)">
+ <summary>
+ Creates a repository for the specified assembly and repository type.
+ </summary>
+ <remarks>
+ <para>
+ <b>CreateDomain is obsolete. Use CreateRepository instead of CreateDomain.</b>
+ </para>
+ <para>
+ The <see cref="T:log4net.Repository.ILoggerRepository"/> created will be associated with the repository
+ specified such that a call to <see cref="M:log4net.LogManager.GetRepository(System.Reflection.Assembly)"/> with the
+ same assembly specified will return the same repository instance.
+ </para>
+ </remarks>
+ <param name="repositoryAssembly">The assembly to use to get the name of the repository.</param>
+ <param name="repositoryType">A <see cref="T:System.Type"/> that implements <see cref="T:log4net.Repository.ILoggerRepository"/>
+ and has a no arg constructor. An instance of this type will be created to act
+ as the <see cref="T:log4net.Repository.ILoggerRepository"/> for the repository specified.</param>
+ <returns>The <see cref="T:log4net.Repository.ILoggerRepository"/> created for the repository.</returns>
+ </member>
+ <member name="M:log4net.LogManager.CreateRepository(System.Reflection.Assembly,System.Type)">
+ <summary>
+ Creates a repository for the specified assembly and repository type.
+ </summary>
+ <remarks>
+ <para>
+ The <see cref="T:log4net.Repository.ILoggerRepository"/> created will be associated with the repository
+ specified such that a call to <see cref="M:log4net.LogManager.GetRepository(System.Reflection.Assembly)"/> with the
+ same assembly specified will return the same repository instance.
+ </para>
+ </remarks>
+ <param name="repositoryAssembly">The assembly to use to get the name of the repository.</param>
+ <param name="repositoryType">A <see cref="T:System.Type"/> that implements <see cref="T:log4net.Repository.ILoggerRepository"/>
+ and has a no arg constructor. An instance of this type will be created to act
+ as the <see cref="T:log4net.Repository.ILoggerRepository"/> for the repository specified.</param>
+ <returns>The <see cref="T:log4net.Repository.ILoggerRepository"/> created for the repository.</returns>
+ </member>
+ <member name="M:log4net.LogManager.GetAllRepositories">
+ <summary>
+ Gets the list of currently defined repositories.
+ </summary>
+ <remarks>
+ <para>
+ Get an array of all the <see cref="T:log4net.Repository.ILoggerRepository"/> objects that have been created.
+ </para>
+ </remarks>
+ <returns>An array of all the known <see cref="T:log4net.Repository.ILoggerRepository"/> objects.</returns>
+ </member>
+ <member name="M:log4net.LogManager.WrapLogger(log4net.Core.ILogger)">
+ <summary>
+ Looks up the wrapper object for the logger specified.
+ </summary>
+ <param name="logger">The logger to get the wrapper for.</param>
+ <returns>The wrapper for the logger specified.</returns>
+ </member>
+ <member name="M:log4net.LogManager.WrapLoggers(log4net.Core.ILogger[])">
+ <summary>
+ Looks up the wrapper objects for the loggers specified.
+ </summary>
+ <param name="loggers">The loggers to get the wrappers for.</param>
+ <returns>The wrapper objects for the loggers specified.</returns>
+ </member>
+ <member name="M:log4net.LogManager.WrapperCreationHandler(log4net.Core.ILogger)">
+ <summary>
+ Create the <see cref="T:log4net.Core.ILoggerWrapper"/> objects used by
+ this manager.
+ </summary>
+ <param name="logger">The logger to wrap.</param>
+ <returns>The wrapper for the logger specified.</returns>
+ </member>
+ <member name="F:log4net.LogManager.s_wrapperMap">
+ <summary>
+ The wrapper map to use to hold the <see cref="T:log4net.Core.LogImpl"/> objects.
+ </summary>
+ </member>
+ <member name="T:log4net.MDC">
+ <summary>
+ Implementation of Mapped Diagnostic Contexts.
+ </summary>
+ <remarks>
+ <note>
+ <para>
+ The MDC is deprecated and has been replaced by the <see cref="P:log4net.ThreadContext.Properties"/>.
+ The current MDC implementation forwards to the <c>ThreadContext.Properties</c>.
+ </para>
+ </note>
+ <para>
+ The MDC class is similar to the <see cref="T:log4net.NDC"/> class except that it is
+ based on a map instead of a stack. It provides <i>mapped
+ diagnostic contexts</i>. A <i>Mapped Diagnostic Context</i>, or
+ MDC in short, is an instrument for distinguishing interleaved log
+ output from different sources. Log output is typically interleaved
+ when a server handles multiple clients near-simultaneously.
+ </para>
+ <para>
+ The MDC is managed on a per thread basis.
+ </para>
+ </remarks>
+ <threadsafety static="true" instance="true"/>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="M:log4net.MDC.#ctor">
+ <summary>
+ Initializes a new instance of the <see cref="T:log4net.MDC"/> class.
+ </summary>
+ <remarks>
+ Uses a private access modifier to prevent instantiation of this class.
+ </remarks>
+ </member>
+ <member name="M:log4net.MDC.Get(System.String)">
+ <summary>
+ Gets the context value identified by the <paramref name="key"/> parameter.
+ </summary>
+ <param name="key">The key to lookup in the MDC.</param>
+ <returns>The string value held for the key, or a <c>null</c> reference if no corresponding value is found.</returns>
+ <remarks>
+ <note>
+ <para>
+ The MDC is deprecated and has been replaced by the <see cref="P:log4net.ThreadContext.Properties"/>.
+ The current MDC implementation forwards to the <c>ThreadContext.Properties</c>.
+ </para>
+ </note>
+ <para>
+ If the <paramref name="key"/> parameter does not look up to a
+ previously defined context then <c>null</c> will be returned.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.MDC.Set(System.String,System.String)">
+ <summary>
+ Add an entry to the MDC
+ </summary>
+ <param name="key">The key to store the value under.</param>
+ <param name="value">The value to store.</param>
+ <remarks>
+ <note>
+ <para>
+ The MDC is deprecated and has been replaced by the <see cref="P:log4net.ThreadContext.Properties"/>.
+ The current MDC implementation forwards to the <c>ThreadContext.Properties</c>.
+ </para>
+ </note>
+ <para>
+ Puts a context value (the <paramref name="val"/> parameter) as identified
+ with the <paramref name="key"/> parameter into the current thread's
+ context map.
+ </para>
+ <para>
+ If a value is already defined for the <paramref name="key"/>
+ specified then the value will be replaced. If the <paramref name="val"/>
+ is specified as <c>null</c> then the key value mapping will be removed.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.MDC.Remove(System.String)">
+ <summary>
+ Removes the key value mapping for the key specified.
+ </summary>
+ <param name="key">The key to remove.</param>
+ <remarks>
+ <note>
+ <para>
+ The MDC is deprecated and has been replaced by the <see cref="P:log4net.ThreadContext.Properties"/>.
+ The current MDC implementation forwards to the <c>ThreadContext.Properties</c>.
+ </para>
+ </note>
+ <para>
+ Remove the specified entry from this thread's MDC
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.MDC.Clear">
+ <summary>
+ Clear all entries in the MDC
+ </summary>
+ <remarks>
+ <note>
+ <para>
+ The MDC is deprecated and has been replaced by the <see cref="P:log4net.ThreadContext.Properties"/>.
+ The current MDC implementation forwards to the <c>ThreadContext.Properties</c>.
+ </para>
+ </note>
+ <para>
+ Remove all the entries from this thread's MDC
+ </para>
+ </remarks>
+ </member>
+ <member name="T:log4net.NDC">
+ <summary>
+ Implementation of Nested Diagnostic Contexts.
+ </summary>
+ <remarks>
+ <note>
+ <para>
+ The NDC is deprecated and has been replaced by the <see cref="P:log4net.ThreadContext.Stacks"/>.
+ The current NDC implementation forwards to the <c>ThreadContext.Stacks["NDC"]</c>.
+ </para>
+ </note>
+ <para>
+ A Nested Diagnostic Context, or NDC in short, is an instrument
+ to distinguish interleaved log output from different sources. Log
+ output is typically interleaved when a server handles multiple
+ clients near-simultaneously.
+ </para>
+ <para>
+ Interleaved log output can still be meaningful if each log entry
+ from different contexts had a distinctive stamp. This is where NDCs
+ come into play.
+ </para>
+ <para>
+ Note that NDCs are managed on a per thread basis. The NDC class
+ is made up of static methods that operate on the context of the
+ calling thread.
+ </para>
+ </remarks>
+ <example>How to push a message into the context
+ <code lang="C#">
+ using(NDC.Push("my context message"))
+ {
+ ... all log calls will have 'my context message' included ...
+
+ } // at the end of the using block the message is automatically removed
+ </code>
+ </example>
+ <threadsafety static="true" instance="true"/>
+ <author>Nicko Cadell</author>
+ <author>Gert Driesen</author>
+ </member>
+ <member name="M:log4net.NDC.#ctor">
+ <summary>
+ Initializes a new instance of the <see cref="T:log4net.NDC"/> class.
+ </summary>
+ <remarks>
+ Uses a private access modifier to prevent instantiation of this class.
+ </remarks>
+ </member>
+ <member name="M:log4net.NDC.Clear">
+ <summary>
+ Clears all the contextual information held on the current thread.
+ </summary>
+ <remarks>
+ <note>
+ <para>
+ The NDC is deprecated and has been replaced by the <see cref="P:log4net.ThreadContext.Stacks"/>.
+ The current NDC implementation forwards to the <c>ThreadContext.Stacks["NDC"]</c>.
+ </para>
+ </note>
+ <para>
+ Clears the stack of NDC data held on the current thread.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.NDC.CloneStack">
+ <summary>
+ Creates a clone of the stack of context information.
+ </summary>
+ <returns>A clone of the context info for this thread.</returns>
+ <remarks>
+ <note>
+ <para>
+ The NDC is deprecated and has been replaced by the <see cref="P:log4net.ThreadContext.Stacks"/>.
+ The current NDC implementation forwards to the <c>ThreadContext.Stacks["NDC"]</c>.
+ </para>
+ </note>
+ <para>
+ The results of this method can be passed to the <see cref="M:log4net.NDC.Inherit(System.Collections.Stack)"/>
+ method to allow child threads to inherit the context of their
+ parent thread.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.NDC.Inherit(System.Collections.Stack)">
+ <summary>
+ Inherits the contextual information from another thread.
+ </summary>
+ <param name="stack">The context stack to inherit.</param>
+ <remarks>
+ <note>
+ <para>
+ The NDC is deprecated and has been replaced by the <see cref="P:log4net.ThreadContext.Stacks"/>.
+ The current NDC implementation forwards to the <c>ThreadContext.Stacks["NDC"]</c>.
+ </para>
+ </note>
+ <para>
+ This thread will use the context information from the stack
+ supplied. This can be used to initialize child threads with
+ the same contextual information as their parent threads. These
+ contexts will <b>NOT</b> be shared. Any further contexts that
+ are pushed onto the stack will not be visible to the other.
+ Call <see cref="M:log4net.NDC.CloneStack"/> to obtain a stack to pass to
+ this method.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.NDC.Pop">
+ <summary>
+ Removes the top context from the stack.
+ </summary>
+ <returns>
+ The message in the context that was removed from the top
+ of the stack.
+ </returns>
+ <remarks>
+ <note>
+ <para>
+ The NDC is deprecated and has been replaced by the <see cref="P:log4net.ThreadContext.Stacks"/>.
+ The current NDC implementation forwards to the <c>ThreadContext.Stacks["NDC"]</c>.
+ </para>
+ </note>
+ <para>
+ Remove the top context from the stack, and return
+ it to the caller. If the stack is empty then an
+ empty string (not <c>null</c>) is returned.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.NDC.Push(System.String)">
+ <summary>
+ Pushes a new context message.
+ </summary>
+ <param name="message">The new context message.</param>
+ <returns>
+ An <see cref="T:System.IDisposable"/> that can be used to clean up
+ the context stack.
+ </returns>
+ <remarks>
+ <note>
+ <para>
+ The NDC is deprecated and has been replaced by the <see cref="P:log4net.ThreadContext.Stacks"/>.
+ The current NDC implementation forwards to the <c>ThreadContext.Stacks["NDC"]</c>.
+ </para>
+ </note>
+ <para>
+ Pushes a new context onto the context stack. An <see cref="T:System.IDisposable"/>
+ is returned that can be used to clean up the context stack. This
+ can be easily combined with the <c>using</c> keyword to scope the
+ context.
+ </para>
+ </remarks>
+ <example>Simple example of using the <c>Push</c> method with the <c>using</c> keyword.
+ <code lang="C#">
+ using(log4net.NDC.Push("NDC_Message"))
+ {
+ log.Warn("This should have an NDC message");
+ }
+ </code>
+ </example>
+ </member>
+ <member name="M:log4net.NDC.Remove">
+ <summary>
+ Removes the context information for this thread. It is
+ not required to call this method.
+ </summary>
+ <remarks>
+ <note>
+ <para>
+ The NDC is deprecated and has been replaced by the <see cref="P:log4net.ThreadContext.Stacks"/>.
+ The current NDC implementation forwards to the <c>ThreadContext.Stacks["NDC"]</c>.
+ </para>
+ </note>
+ <para>
+ This method is not implemented.
+ </para>
+ </remarks>
+ </member>
+ <member name="M:log4net.NDC.SetMaxDepth(System.Int32)">
+ <summary>
+ Forces the stack depth to be at most <paramref name="maxDepth"/>.
+ </summary>
+ <param name="maxDepth">The maximum depth of the stack</param>
+ <remarks>
+ <note>
+ <para>
+ The NDC is deprecated and has been replaced by the <see cref="P:log4net.ThreadContext.Stacks"/>.
+ The current NDC implementation forwards to the <c>ThreadContext.Stacks["NDC"]</c>.
+ </para>
+ </note>
+ <para>
+ Forces the stack depth to be at most <paramref name="maxDepth"/>.
+ This may truncate the head of the stack. This only affects the
+ stack in the current thread. Also it does not prevent it from
+ growing, it only sets the maximum depth at the time of the
+ call. This can be used to return to a known context depth.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.NDC.Depth">
+ <summary>
+ Gets the current context depth.
+ </summary>
+ <value>The current context depth.</value>
+ <remarks>
+ <note>
+ <para>
+ The NDC is deprecated and has been replaced by the <see cref="P:log4net.ThreadContext.Stacks"/>.
+ The current NDC implementation forwards to the <c>ThreadContext.Stacks["NDC"]</c>.
+ </para>
+ </note>
+ <para>
+ The number of context values pushed onto the context stack.
+ </para>
+ <para>
+ Used to record the current depth of the context. This can then
+ be restored using the <see cref="M:log4net.NDC.SetMaxDepth(System.Int32)"/> method.
+ </para>
+ </remarks>
+ <seealso cref="M:log4net.NDC.SetMaxDepth(System.Int32)"/>
+ </member>
+ <member name="T:log4net.ThreadContext">
+ <summary>
+ The log4net Thread Context.
+ </summary>
+ <remarks>
+ <para>
+ The <c>ThreadContext</c> provides a location for thread specific debugging
+ information to be stored.
+ The <c>ThreadContext</c> properties override any <see cref="T:log4net.GlobalContext"/>
+ properties with the same name.
+ </para>
+ <para>
+ The thread context has a properties map and a stack.
+ The properties and stack can
+ be included in the output of log messages. The <see cref="T:log4net.Layout.PatternLayout"/>
+ supports selecting and outputting these properties.
+ </para>
+ <para>
+ The Thread Context provides a diagnostic context for the current thread.
+ This is an instrument for distinguishing interleaved log
+ output from different sources. Log output is typically interleaved
+ when a server handles multiple clients near-simultaneously.
+ </para>
+ <para>
+ The Thread Context is managed on a per thread basis.
+ </para>
+ </remarks>
+ <example>Example of using the thread context properties to store a username.
+ <code lang="C#">
+ ThreadContext.Properties["user"] = userName;
+ log.Info("This log message has a ThreadContext Property called 'user'");
+ </code>
+ </example>
+ <example>Example of how to push a message into the context stack
+ <code lang="C#">
+ using(ThreadContext.Stacks["NDC"].Push("my context message"))
+ {
+ log.Info("This log message has a ThreadContext Stack message that includes 'my context message'");
+
+ } // at the end of the using block the message is automatically popped
+ </code>
+ </example>
+ <threadsafety static="true" instance="true"/>
+ <author>Nicko Cadell</author>
+ </member>
+ <member name="M:log4net.ThreadContext.#ctor">
+ <summary>
+ Private Constructor.
+ </summary>
+ <remarks>
+ <para>
+ Uses a private access modifier to prevent instantiation of this class.
+ </para>
+ </remarks>
+ </member>
+ <member name="F:log4net.ThreadContext.s_properties">
+ <summary>
+ The thread context properties instance
+ </summary>
+ </member>
+ <member name="F:log4net.ThreadContext.s_stacks">
+ <summary>
+ The thread context stacks instance
+ </summary>
+ </member>
+ <member name="P:log4net.ThreadContext.Properties">
+ <summary>
+ The thread properties map
+ </summary>
+ <value>
+ The thread properties map
+ </value>
+ <remarks>
+ <para>
+ The <c>ThreadContext</c> properties override any <see cref="T:log4net.GlobalContext"/>
+ properties with the same name.
+ </para>
+ </remarks>
+ </member>
+ <member name="P:log4net.ThreadContext.Stacks">
+ <summary>
+ The thread stacks
+ </summary>
+ <value>
+ stack map
+ </value>
+ <remarks>
+ <para>
+ The thread local stacks.
+ </para>
+ </remarks>
+ </member>
+ </members>
+</doc>
diff --git a/qpid/dotnet/client-010/lib/nunit/nunit-licence.txt b/qpid/dotnet/client-010/lib/nunit/nunit-licence.txt
new file mode 100644
index 0000000000..b2316295d3
--- /dev/null
+++ b/qpid/dotnet/client-010/lib/nunit/nunit-licence.txt
@@ -0,0 +1,23 @@
+Copyright © 2002-2004 James W. Newkirk, Michael C. Two, Alexei A. Vorontsov,
+ Charlie Poole
+Copyright © 2000-2004 Philip A. Craig
+
+This software is provided 'as-is', without any express or implied warranty. In
+no event will the authors be held liable for any damages arising from the use
+of this software.
+
+Permission is granted to anyone to use this software for any purpose, including
+commercial applications, and to alter it and redistribute it freely, subject to
+the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must not claim
+ that you wrote the original software. If you use this software in a product, an
+ acknowledgment (see the following) in the product documentation is required.
+
+ Portions Copyright © 2002 James W. Newkirk, Michael C. Two, Alexei A. Vorontsov
+ or Copyright © 2000-2002 Philip A. Craig
+
+2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+
+3. This notice may not be removed or altered from any source distribution.
diff --git a/qpid/dotnet/client-010/lib/nunit/nunit.framework.dll b/qpid/dotnet/client-010/lib/nunit/nunit.framework.dll
new file mode 100644
index 0000000000..53666e74c9
--- /dev/null
+++ b/qpid/dotnet/client-010/lib/nunit/nunit.framework.dll
Binary files differ
diff --git a/qpid/dotnet/client-010/lib/plossum/C5-License.txt b/qpid/dotnet/client-010/lib/plossum/C5-License.txt
new file mode 100644
index 0000000000..5649c70cf3
--- /dev/null
+++ b/qpid/dotnet/client-010/lib/plossum/C5-License.txt
@@ -0,0 +1,27 @@
+-----------------------------------------------------------------------------
+
+The following license applies to the C5 library (found in C5.dll and C5.pdb)
+The source code for this library together with more information can be found on
+http://www.itu.dk/research/c5/.
+
+-----------------------------------------------------------------------------
+
+Copyright (c) 2003-2007 Niels Kokholm and Peter Sestoft.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/qpid/dotnet/client-010/lib/plossum/C5.dll b/qpid/dotnet/client-010/lib/plossum/C5.dll
new file mode 100644
index 0000000000..08362849c9
--- /dev/null
+++ b/qpid/dotnet/client-010/lib/plossum/C5.dll
Binary files differ
diff --git a/qpid/dotnet/client-010/lib/plossum/Plossum CommandLine.dll b/qpid/dotnet/client-010/lib/plossum/Plossum CommandLine.dll
new file mode 100644
index 0000000000..d3aad9485d
--- /dev/null
+++ b/qpid/dotnet/client-010/lib/plossum/Plossum CommandLine.dll
Binary files differ
diff --git a/qpid/dotnet/client-010/lib/plossum/license.txt b/qpid/dotnet/client-010/lib/plossum/license.txt
new file mode 100644
index 0000000000..532b9c11a3
--- /dev/null
+++ b/qpid/dotnet/client-010/lib/plossum/license.txt
@@ -0,0 +1,28 @@
+Copyright (c) Peter Palotas 2007
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the distribution.
+ * Neither the name of the copyright holder nor the names of its
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/qpid/dotnet/client-010/log.xml b/qpid/dotnet/client-010/log.xml
new file mode 100644
index 0000000000..cda84d7c7b
--- /dev/null
+++ b/qpid/dotnet/client-010/log.xml
@@ -0,0 +1,46 @@
+<!--
+
+ 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.
+
+-->
+<log4net>
+ <appender name="Console" type="log4net.Appender.ConsoleAppender">
+ <layout type="log4net.Layout.PatternLayout">
+ <!-- Pattern to output the caller's file name and line number -->
+ <conversionPattern value="%5level [%thread] (%file:%line) - %message%newline" />
+ </layout>
+ </appender>
+
+ <appender name="RollingFile" type="log4net.Appender.RollingFileAppender">
+ <file value="logs/mylogfile.log" />
+ <appendToFile value="true" />
+ <maximumFileSize value="8192KB" />
+ <maxSizeRollBackups value="2" />
+
+ <layout type="log4net.Layout.PatternLayout">
+ <conversionPattern value="%date [%thread] %-5level %ndc - %message%newline" />
+ <!--<conversionPattern value="%level %thread %logger - %message%newline" />-->
+ </layout>
+ </appender>
+
+ <root>
+ <level value="DEBUG" />
+ <appender-ref ref="Console" />
+ <appender-ref ref="RollingFile" />
+ </root>
+</log4net>
diff --git a/qpid/dotnet/client-010/management/console/AbstractConsole.cs b/qpid/dotnet/client-010/management/console/AbstractConsole.cs
new file mode 100644
index 0000000000..315b2b6d48
--- /dev/null
+++ b/qpid/dotnet/client-010/management/console/AbstractConsole.cs
@@ -0,0 +1,45 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+using System;
+
+namespace org.apache.qpid.console
+{
+ public class AbstractConsole : Console
+ {
+ public AbstractConsole(){}
+ public virtual void NewAgent(Agent agent) {}
+ public virtual void AgentRemoved(Agent agent) {}
+ public virtual void BrokerConnected(Broker broker) {}
+ public virtual void BrokerDisconnected(Broker broker) {}
+ public virtual void BrokerInformation(Broker broker) {}
+ public virtual void NewPackage(String packageName) {}
+ public virtual void NewClass(short kind, ClassKey key) {}
+ public virtual void ObjectProperties(Broker broker, QMFObject obj) {}
+ public virtual void ObjectStatistics(Broker broker, QMFObject obj) {}
+ public virtual void MethodResponse(Broker broker, long seq, MethodResult response) {}
+ public virtual void EventRecieved(Broker broker, QMFEvent anEvent) {}
+ public virtual void HearbeatRecieved(Agent agent, long timestamp) {}
+ public virtual Type TypeMapping(ClassKey key) {
+ return typeof(QMFObject) ;
+ }
+ }
+}
diff --git a/qpid/dotnet/client-010/management/console/Agent.cs b/qpid/dotnet/client-010/management/console/Agent.cs
new file mode 100644
index 0000000000..df544a4dd0
--- /dev/null
+++ b/qpid/dotnet/client-010/management/console/Agent.cs
@@ -0,0 +1,75 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+using System;
+using log4net ;
+
+namespace org.apache.qpid.console
+{
+
+ /**
+ * Local representation of a remote agent which has been found on the bus.
+ */
+ public class Agent
+ {
+ public static ILog log = LogManager.GetLogger(typeof(Agent)) ;
+
+ public Broker Broker {get;set;}
+ public long BrokerBank {get;set;}
+ public long AgentBank {get;set;}
+ public string label {get;set;}
+
+ public Agent(Broker broker, long agentBank, string label)
+ {
+ this.Broker = broker ;
+ this.BrokerBank = broker.BrokerBank() ;
+ this.AgentBank = agentBank ;
+ this.label = label ;
+ }
+
+ public string AgentKey() {
+ return Agent.AgentKey(AgentBank, BrokerBank) ;
+ }
+
+ public string RoutingCode() {
+ return Agent.RoutingCode(AgentBank, BrokerBank) ;
+ }
+
+ public static string AgentKey(long AgentBank, long BrokerBank) {
+ return String.Format("{0}:{1}", AgentBank, BrokerBank) ;
+ }
+
+ public static string RoutingCode(long AgentBank, long BrokerBank) {
+ return String.Format("agent.{0}.{1}", BrokerBank, AgentBank) ;
+ }
+
+ public static long GetBrokerBank(string routingKey) {
+ string delim = "." ;
+ return long.Parse(routingKey.Split(delim.ToCharArray())[2]) ;
+ }
+
+ public static long GetAgentBank(string routingKey) {
+ string delim = "." ;
+ return long.Parse(routingKey.Split(delim.ToCharArray())[3]) ;
+ }
+
+ }
+}
diff --git a/qpid/dotnet/client-010/management/console/Broker.cs b/qpid/dotnet/client-010/management/console/Broker.cs
new file mode 100644
index 0000000000..7684da9e12
--- /dev/null
+++ b/qpid/dotnet/client-010/management/console/Broker.cs
@@ -0,0 +1,351 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+using System;
+using System.Collections.Generic ;
+using System.Threading ;
+using org.apache.qpid.client ;
+using org.apache.qpid.transport ;
+using org.apache.qpid.transport.codec ;
+using log4net ;
+
+namespace org.apache.qpid.console
+{
+
+ /**
+ * Controls all communication with a broker. Works with the session to provide
+ * synhchronous method calls across the asynchronous QMF bus.
+ */
+ public class Broker : IMessageListener
+ {
+ public static ILog log = LogManager.GetLogger(typeof(Broker)) ;
+ public static int SYNC_TIME = 60000 ;
+
+ public BrokerURL url ;
+ public Dictionary<string, Agent> Agents = new Dictionary<string, Agent>() ;
+
+ private IClient client ;
+ private IClientSession clientSession ;
+ //FIXME This second session should not be needed. There is a bug in the underlieing code.
+ private IClientSession outSession ;
+ private int timeout = 50000 ;
+ private string replyName ;
+ private string topicName ;
+ private bool connected = false ;
+ private bool syncInFlight = false ;
+ private bool topicBound = false ;
+ private int reqsOutstanding = 0 ;
+ private org.apache.qpid.console.Session consoleSession ;
+ private object lockObject = new Object() ;
+
+
+ public Broker(org.apache.qpid.console.Session session, BrokerURL url)
+ {
+ log.Debug("Creating a new Broker for url " + url) ;
+ this.url = url;
+ consoleSession = session ;
+ this.TryToConnect() ;
+ }
+
+ ~Broker() {
+ if (connected) {
+ this.Shutdown() ;
+ }
+ }
+
+ public int BrokerBank() {
+ return 1 ;
+ }
+
+ public bool IsConnected() {
+ return connected ;
+ }
+
+ protected void TryToConnect() {
+ reqsOutstanding = 1 ;
+ Agent newAgent = new Agent(this,0,"BrokerAgent") ;
+ Agents.Add(newAgent.AgentKey(), newAgent) ;
+ client = new Client() ;
+ client.Connect(url.Hostname, url.Port, null, url.AuthName, url.AuthPassword) ;
+ clientSession = client.CreateSession(timeout) ;
+ //clientSession.SetAutoSync(false) ;
+ string name = System.Text.Encoding.UTF8.GetString(clientSession.GetName()) ;
+ replyName = "reply-" + name ;
+ topicName = "topic-" + name ;
+ clientSession.SetAutoSync(true) ;
+ Option[] options = new Option[] {Option.EXCLUSIVE, Option.AUTO_DELETE} ;
+
+ // This queue is used for responses to messages which are sent.
+ clientSession.QueueDeclare(replyName,options) ;
+ clientSession.ExchangeBind(replyName,"amq.direct",replyName) ;
+ clientSession.AttachMessageListener(this, "rdest") ;
+ clientSession.MessageSubscribe(replyName,"rdest",MessageAcceptMode.NONE,MessageAcquireMode.PRE_ACQUIRED,null,0,null) ;
+ clientSession.MessageSetFlowMode("rdest", MessageFlowMode.WINDOW);
+ clientSession.MessageFlow("rdest", MessageCreditUnit.BYTE, ClientSession.MESSAGE_FLOW_MAX_BYTES);
+ clientSession.MessageFlow("rdest", MessageCreditUnit.MESSAGE, ClientSession.MESSAGE_FLOW_MAX_BYTES);
+
+ // This queue is used for unsolicited messages sent to this class.
+ clientSession.QueueDeclare(topicName, options) ;
+ clientSession.AttachMessageListener(this, "tdest") ;
+ clientSession.MessageSubscribe(topicName,"tdest",MessageAcceptMode.NONE,MessageAcquireMode.PRE_ACQUIRED,null,0,null) ;
+ clientSession.MessageSetFlowMode("tdest", MessageFlowMode.WINDOW);
+ clientSession.MessageFlow("tdest", MessageCreditUnit.BYTE, ClientSession.MESSAGE_FLOW_MAX_BYTES);
+ clientSession.MessageFlow("tdest", MessageCreditUnit.MESSAGE, ClientSession.MESSAGE_FLOW_MAX_BYTES);
+
+ outSession = client.CreateSession(timeout) ;
+ outSession.ExchangeBind(replyName,"amq.direct",replyName) ;
+
+ connected = true ;
+ consoleSession.HandleBrokerConnect(this) ;
+
+
+ IEncoder encoder = CreateEncoder() ;
+ this.SetHeader(encoder, 'B', 0) ;
+ this.Send(encoder) ;
+ }
+
+ public void Shutdown() {
+ if (connected) {
+ this.WaitForStable() ;
+ clientSession.MessageStop("rdest") ;
+ clientSession.MessageStop("tdest") ;
+ clientSession.Close() ;
+ client.Close() ;
+ this.connected = false ;
+ }
+ }
+
+ public void UpdateAgent(QMFObject obj) {
+ long agentBank = (long)obj.GetProperty("agentBank") ;
+ long brokerBank = (long)obj.GetProperty("brokerBank") ;
+ String key = Agent.AgentKey(agentBank, brokerBank) ;
+ if (obj.IsDeleted()) {
+ if (Agents.ContainsKey(key)) {
+ Agent agent = Agents[key] ;
+ Agents.Remove(key) ;
+ consoleSession.HandleAgentRemoved(agent) ;
+ }
+ }
+ else {
+ if (! Agents.ContainsKey(key)) {
+ Agent newAgent = new Agent(this, agentBank, (string)obj.GetProperty("label")) ;
+ Agents.Add(key, newAgent) ;
+ consoleSession.HandleNewAgent(newAgent) ;
+ }
+ }
+ }
+
+ public IEncoder CreateEncoder() {
+ return new MSEncoder(1000) ;
+ }
+
+
+ public IEncoder CreateEncoder(char opcode, long sequence) {
+ return SetHeader(this.CreateEncoder(), opcode, sequence) ;
+ }
+
+ public IEncoder SetHeader(IEncoder enc, char opcode, long sequence) {
+ enc.WriteUint8((short)'A') ;
+ enc.WriteUint8((short)'M') ;
+ enc.WriteUint8((short)'2') ;
+ enc.WriteUint8((short)opcode) ;
+ enc.WriteUint32(sequence) ;
+ return enc ;
+ }
+
+ public Message CreateMessage(IEncoder enc) {
+ return this.CreateMessage(enc, "broker", -1) ;
+ }
+
+ public Message CreateMessage(IEncoder enc, string routingKey) {
+ return this.CreateMessage(enc, routingKey, -1) ;
+ }
+
+ public Message CreateMessage(IEncoder enc, string routingKey, long ttl) {
+ Message msg = new Message() ;
+ msg.Body = ((MSEncoder)enc).Segment() ;
+ msg.DeliveryProperties.SetRoutingKey(routingKey) ;
+ if (-1 != ttl) {
+ msg.DeliveryProperties.SetTtl(ttl) ;
+ }
+ msg.MessageProperties.SetContentType("x-application/qmf") ;
+ msg.MessageProperties.SetReplyTo(new ReplyTo("amq.direct", replyName)) ;
+ return msg ;
+ }
+
+ public void Send(IEncoder enc) {
+ this.Send(this.CreateMessage(enc)) ;
+ }
+
+ public void Send(Message msg) {
+
+ lock (lockObject) {
+ log.Debug(String.Format("Sending message to routing key '{0}'", msg.DeliveryProperties.GetRoutingKey())) ;
+ //log.Debug(System.Text.Encoding.UTF8.GetString(msg.Body.ToArray())) ;
+ outSession.MessageTransfer("qpid.management", msg) ;
+ //clientSession.sync() ;
+ }
+ }
+
+ protected bool CheckHeader(IDecoder decoder, out char opcode, out long sequence) {
+ bool returnValue = false ;
+ opcode = 'x' ;
+ sequence = -1 ;
+ if(decoder.HasRemaining()) {
+ char character = (char) decoder.ReadUint8() ;
+ if (character != 'A') {
+ return returnValue ;
+ }
+ character = (char) decoder.ReadUint8() ;
+ if (character != 'M') {
+ return returnValue ;
+ }
+ character = (char) decoder.ReadUint8() ;
+ if (character != '2') {
+ return returnValue ;
+ }
+ returnValue = true ;
+ opcode = (char) decoder.ReadUint8() ;
+ sequence = decoder.ReadUint32() ;
+ }
+ return returnValue ;
+ }
+
+ public void MessageTransfer(IMessage msg) {
+ MSDecoder decoder = new MSDecoder() ;
+ decoder.Init(msg.Body) ;
+ RangeSet rangeSet = new RangeSet() ;
+ rangeSet.Add(msg.Id) ;
+ char opcode = 'x' ;
+ long seq = -1 ;
+ while (this.CheckHeader(decoder, out opcode, out seq)) {
+ //log.Debug("Message recieved with opcode " + opcode + " and sequence " + seq) ;
+ //log.Debug(System.Text.Encoding.UTF8.GetString(msg.Body.ToArray())) ;
+ switch (opcode) {
+ case 'b':
+ consoleSession.HandleBrokerResponse(this, decoder, seq) ;
+ break ;
+ case 'p':
+ consoleSession.HandlePackageIndicator(this, decoder, seq) ;
+ break ;
+ case 'z':
+ consoleSession.HandleCommandComplete(this, decoder, seq) ;
+ break ;
+ case 'q':
+ consoleSession.HandleClassIndicator(this, decoder, seq) ;
+ break ;
+ case 'm':
+ consoleSession.HandleMethodResponse(this, decoder, seq) ;
+ break ;
+ case 'h':
+ consoleSession.HandleHeartbeatIndicator(this, decoder, seq, msg) ;
+ break ;
+ case 'e':
+ consoleSession.HandleEventIndicator(this, decoder, seq) ;
+ break ;
+ case 's':
+ consoleSession.HandleSchemaResponse(this, decoder, seq) ;
+ break ;
+ case 'c':
+ consoleSession.HandleContentIndicator(this, decoder, seq, true, false) ;
+ break ;
+ case 'i':
+ consoleSession.HandleContentIndicator(this, decoder, seq, false, true) ;
+ break ;
+ case 'g':
+ consoleSession.HandleContentIndicator(this, decoder, seq, true, true) ;
+ break ;
+ default:
+ log.Error("Invalid message type recieved with opcode " + opcode) ;
+ break ;
+ }
+ }
+ lock (lockObject) {
+ outSession.MessageAccept(rangeSet) ;
+ }
+ }
+
+ public void IncrementOutstanding() {
+ lock (lockObject) {
+ this.reqsOutstanding += 1 ;
+ }
+ }
+
+ public void DecrementOutstanding() {
+ lock (lockObject) {
+ this.reqsOutstanding -= 1 ;
+ if ((reqsOutstanding == 0) & !topicBound) {
+ foreach (string key in consoleSession.BindingKeys()) {
+ //this.clientSession.ExchangeBind(topicName, "qpid.mannagement", key) ;
+ log.Debug("Setting Topic Binding " + key) ;
+ this.outSession.ExchangeBind(topicName, "qpid.management", key) ;
+ }
+ topicBound = true ;
+ }
+ if ((reqsOutstanding == 0) & syncInFlight) {
+ syncInFlight = false ;
+ Monitor.PulseAll(lockObject) ;
+ }
+ }
+ }
+
+ public void WaitForStable() {
+ lock (lockObject) {
+ if (connected) {
+ DateTime start = DateTime.Now ;
+ syncInFlight = true ;
+ while (reqsOutstanding != 0) {
+ log.Debug("Waiting to recieve messages") ;
+ Monitor.Wait(lockObject,SYNC_TIME) ;
+ TimeSpan duration = DateTime.Now - start;
+ if (duration.TotalMilliseconds > SYNC_TIME) {
+ throw new Exception("Timeout waiting for Broker to Sync") ;
+ }
+ }
+ }
+ }
+ }
+
+ public void SetSyncInFlight(bool inFlight) {
+ lock(lockObject) {
+ syncInFlight = inFlight ;
+ Monitor.PulseAll(lockObject) ;
+ }
+ }
+
+ public bool GetSyncInFlight() {
+ return syncInFlight ;
+ }
+
+ public void WaitForSync(int timeout) {
+ lock(lockObject) {
+ DateTime start = DateTime.Now ;
+ while (syncInFlight) {
+ Monitor.Wait(lockObject,timeout) ;
+ }
+ TimeSpan duration = DateTime.Now - start;
+ if (duration.TotalMilliseconds > timeout) {
+ throw new Exception("Timeout waiting for Broker to Sync") ;
+ }
+ }
+ }
+ }
+}
diff --git a/qpid/dotnet/client-010/management/console/BrokerURL.cs b/qpid/dotnet/client-010/management/console/BrokerURL.cs
new file mode 100644
index 0000000000..77318e4295
--- /dev/null
+++ b/qpid/dotnet/client-010/management/console/BrokerURL.cs
@@ -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.
+ *
+ */
+
+using System;
+
+namespace org.apache.qpid.console
+{
+
+ /**
+ * URL which defines the connection to the broker to hook up to the QMF
+ * Bus.
+ */
+ public class BrokerURL
+ {
+ public string Hostname {get;set;}
+ public int Port {get;set;}
+ public string AuthName {get;set;}
+ public string AuthPassword {get;set;}
+ public string AuthMechanism {get;set;}
+ protected bool ssl = false ;
+
+ public BrokerURL(string str)
+ {
+ Uri uri = new Uri(str) ;
+ this.Hostname = uri.Host ;
+ if (uri.Scheme.Equals("amqp")) {
+ Port=5672 ;
+ } else {
+ ssl = true ;
+ Port=5673 ;
+ }
+
+ //FIXME Make this more robust
+ this.AuthName = "guest" ;
+ this.AuthPassword = "guest" ;
+ this.AuthMechanism = "PLAIN" ;
+ }
+
+ public string GetURI() {
+ return Hostname ;
+ }
+
+ public override string ToString ()
+ {
+ if (ssl) {
+ return String.Format("amqps://{0}:{1}", Hostname, Port) ;
+ } else {
+ return String.Format("amqp://{0}:{1}", Hostname, Port) ;
+ }
+ }
+
+ }
+}
diff --git a/qpid/dotnet/client-010/management/console/ClassKey.cs b/qpid/dotnet/client-010/management/console/ClassKey.cs
new file mode 100644
index 0000000000..a3aba2761a
--- /dev/null
+++ b/qpid/dotnet/client-010/management/console/ClassKey.cs
@@ -0,0 +1,107 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+using System;
+using System.Globalization ;
+using org.apache.qpid.transport.util;
+using org.apache.qpid.transport.codec ;
+
+namespace org.apache.qpid.console
+{
+
+ /**
+ * Identifies a specific class and version on the bus.
+ */
+ public class ClassKey
+ {
+ public string PackageName { get; set; }
+ public string ClassName { get; set; }
+ public long[] Hash = new long[4] ;
+
+ public ClassKey(String keyString) {
+ string delims = ":()" ;
+ string[] parts = keyString.Split(delims.ToCharArray()) ;
+ if (parts.Length < 3) {
+ throw new Exception("Invalid class key format. Format should be package:class(bytes)") ;
+ }
+ PackageName = parts[0] ;
+ ClassName = parts[1] ;
+ delims = "-" ;
+ string[] bytes = parts[2].Split(delims.ToCharArray()) ;
+ if (bytes.Length != 4) {
+ throw new Exception("Invalid class key format. Bytes should be in the format HEX-HEX-HEX-HEX") ;
+ }
+ Hash[0] = long.Parse(bytes[0], NumberStyles.HexNumber) ;
+ Hash[1] = long.Parse(bytes[1], NumberStyles.HexNumber) ;
+ Hash[2] = long.Parse(bytes[2], NumberStyles.HexNumber) ;
+ Hash[3] = long.Parse(bytes[3], NumberStyles.HexNumber) ;
+ }
+
+ public ClassKey(IDecoder dec) {
+ PackageName = dec.ReadStr8() ;
+ ClassName = dec.ReadStr8() ;
+ Hash[0] = dec.ReadUint32() ;
+ Hash[1] = dec.ReadUint32() ;
+ Hash[2] = dec.ReadUint32() ;
+ Hash[3] = dec.ReadUint32() ;
+
+ }
+
+ public string GetKeyString() {
+ string hashString = GetHashString() ;
+ return String.Format("{0}:{1}({2})", PackageName, ClassName, hashString) ;
+ }
+
+ public string GetHashString() {
+ return String.Format("{0:x8}-{1:x8}-{2:x8}-{3:x8}", (long) Hash[0],Hash[1], Hash[2],Hash[3]) ;
+ }
+
+ public void encode(IEncoder enc) {
+ enc.WriteStr8(PackageName) ;
+ enc.WriteStr8(ClassName) ;
+ enc.WriteUint32(Hash[0]) ;
+ enc.WriteUint32(Hash[1]) ;
+ enc.WriteUint32(Hash[2]) ;
+ enc.WriteUint32(Hash[3]) ;
+ }
+
+ override public string ToString() {
+ return String.Format("ClassKey: {0}", GetKeyString()) ;
+ }
+
+ public override int GetHashCode ()
+ {
+ return GetKeyString().GetHashCode() ;
+ }
+
+ public override bool Equals (object obj)
+ {
+ if (obj.GetType().Equals(this.GetType())) {
+ ClassKey other = (ClassKey) obj ;
+ return (other.GetKeyString().Equals(this.GetKeyString())) ;
+ }
+ else {
+ return false ;
+ }
+ }
+
+ }
+}
diff --git a/qpid/dotnet/client-010/management/console/Console.cs b/qpid/dotnet/client-010/management/console/Console.cs
new file mode 100644
index 0000000000..8ff201c676
--- /dev/null
+++ b/qpid/dotnet/client-010/management/console/Console.cs
@@ -0,0 +1,46 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+using System;
+
+namespace org.apache.qpid.console
+{
+ /**
+ * Callbacks which are exposed by the Session. Clients should create anm implementaiton of this
+ * for more fine grained interaction with the bus.
+ */
+ public interface Console
+ {
+ void NewAgent(Agent agent) ;
+ void AgentRemoved(Agent agent) ;
+ void BrokerConnected(Broker broker) ;
+ void BrokerDisconnected(Broker broker) ;
+ void BrokerInformation(Broker broker) ;
+ void NewPackage(String packageName) ;
+ void NewClass(short kind, ClassKey key) ;
+ void ObjectProperties(Broker broker, QMFObject obj) ;
+ void ObjectStatistics(Broker broker, QMFObject obj) ;
+ void MethodResponse(Broker broker, long seq, MethodResult response) ;
+ void EventRecieved(Broker broker, QMFEvent anEvent) ;
+ void HearbeatRecieved(Agent agent, long timestamp) ;
+ Type TypeMapping(ClassKey key) ;
+ }
+}
diff --git a/qpid/dotnet/client-010/management/console/MethodResult.cs b/qpid/dotnet/client-010/management/console/MethodResult.cs
new file mode 100644
index 0000000000..7215f5dcbc
--- /dev/null
+++ b/qpid/dotnet/client-010/management/console/MethodResult.cs
@@ -0,0 +1,67 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+using System;
+using System.Collections.Generic ;
+
+namespace org.apache.qpid.console
+{
+ /**
+ * The result on invoking a method on a managed object
+ */
+ public class MethodResult
+ {
+
+ public long ReturnCode {get;set;}
+ public string Text {get;set;}
+ protected Dictionary<string, object> ReturnValues ;
+
+ public MethodResult(long aCode, string aMsg, Dictionary<string, object> args)
+ {
+ ReturnCode = aCode ;
+ Text = aMsg ;
+ ReturnValues = args ;
+ }
+
+ public object GetReturnValue(string name) {
+ object returnValue = null ;
+ if (ReturnValues.ContainsKey(name)) {
+ returnValue = ReturnValues[name] ;
+ }
+ return returnValue ;
+ }
+
+ public Dictionary<string, object> GetReturnValues() {
+ return ReturnValues ;
+ }
+
+ public override string ToString()
+ {
+ string returnString = "" ;
+ foreach (KeyValuePair<string, object> pair in ReturnValues) {
+ returnString = returnString + String.Format("(Key: '{0}' Value: '{1}')", pair.Key, pair.Value) ;
+ }
+
+ return string.Format("MethodResult: ReturnCode={0}, Text={1} Values=[{2}]", ReturnCode, Text, returnString);
+ }
+
+ }
+}
diff --git a/qpid/dotnet/client-010/management/console/ObjectID.cs b/qpid/dotnet/client-010/management/console/ObjectID.cs
new file mode 100644
index 0000000000..9532c8e64c
--- /dev/null
+++ b/qpid/dotnet/client-010/management/console/ObjectID.cs
@@ -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.
+ *
+ */
+
+using System;
+using org.apache.qpid.transport.codec ;
+
+namespace org.apache.qpid.console
+{
+
+ /**
+ * Uniquely identifies an object on the bus.
+ */
+ public class ObjectID
+ {
+
+ protected long first ;
+ protected long second ;
+
+ public ObjectID() {
+ }
+
+ public ObjectID(IDecoder dec)
+ {
+ first = (long)dec.ReadUint64() ;
+ second = (long)dec.ReadUint64() ;
+ }
+
+ public ObjectID(long first, long second) {
+ this.first = first ;
+ this.second = second ;
+ }
+
+ public long Flags() {
+ return (long) ((ulong)this.first & 0xF000000000000000) >> 60 ;
+ }
+
+ public long Sequence() {
+ return (long)((ulong)this.first & 0x0FFF000000000000) >> 48 ;
+ }
+
+ public long BrokerBank() {
+ return (long)((ulong)this.first & 0x0000FFFFF0000000) >> 28 ;
+ }
+
+ public long AgentBank() {
+ return (this.first & 0x000000000FFFFFFF) ;
+ }
+
+ public long Object() {
+ return second ;
+ }
+
+ public bool IsDurable() {
+ return Sequence() == 0 ;
+ }
+
+ public void encode(IEncoder enc) {
+ enc.WriteUint64((long)first) ;
+ enc.WriteUint64((long)second) ;
+ }
+
+ override public string ToString() {
+ return "" + Flags() + "-" + Sequence() + "-" + BrokerBank() + "-" + AgentBank() + "-" + Object() ;
+ }
+
+ public string RoutingCode() {
+ return Agent.RoutingCode((long)AgentBank(), (long)BrokerBank()) ;
+ }
+ }
+}
diff --git a/qpid/dotnet/client-010/management/console/QMFEvent.cs b/qpid/dotnet/client-010/management/console/QMFEvent.cs
new file mode 100644
index 0000000000..73e1a34c43
--- /dev/null
+++ b/qpid/dotnet/client-010/management/console/QMFEvent.cs
@@ -0,0 +1,74 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+using System;
+using System.Collections.Generic;
+using org.apache.qpid.transport.codec ;
+
+
+namespace org.apache.qpid.console
+{
+ public enum EventSeverity : short {
+ EMER = 0 ,
+ ALERT = 1 ,
+ CRIT = 2 ,
+ ERROR = 3 ,
+ WARN = 4 ,
+ NOTIC = 5 ,
+ INFO = 6 ,
+ DEBUG = 7
+ }
+
+ /**
+ * An event raised by an agent on the bus.
+ */
+ public class QMFEvent
+ {
+ public Session Session { get;set; }
+ public ClassKey ClassKey {get;set;}
+ //FIXME time?
+ public long Timestamp {get;set;}
+ public EventSeverity Severity {get;set;}
+ public Dictionary<string, object> Arguments {get;set;}
+
+ public QMFEvent(Session session, IDecoder dec)
+ {
+ Session = session ;
+ ClassKey = new ClassKey(dec) ;
+ Timestamp = dec.ReadInt64() ;
+ Severity = (EventSeverity) dec.ReadUint8() ;
+ SchemaClass sClass = Session.GetSchema(ClassKey) ;
+ Arguments = new Dictionary<string, object>() ;
+
+ if (sClass != null) {
+ foreach (SchemaArgument arg in sClass.Arguments) {
+ Arguments[arg.Name] = Session.DecodeValue(dec, arg.Type) ;
+ }
+ }
+ }
+
+ public object GetArgument(string argName) {
+ object returnValue = null ;
+ Arguments.TryGetValue(argName, out returnValue) ;
+ return returnValue ;
+ }
+ }
+}
diff --git a/qpid/dotnet/client-010/management/console/QMFObject.cs b/qpid/dotnet/client-010/management/console/QMFObject.cs
new file mode 100644
index 0000000000..905422efd9
--- /dev/null
+++ b/qpid/dotnet/client-010/management/console/QMFObject.cs
@@ -0,0 +1,294 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+using System;
+using System.Collections.Generic ;
+using log4net ;
+using org.apache.qpid.transport.codec ;
+
+namespace org.apache.qpid.console
+{
+
+ /**
+ * An object which is returned from an agent by the Session. It can have
+ * methods, properties, and statistics.
+ */
+ public class QMFObject
+ {
+
+ public static ILog log = LogManager.GetLogger(typeof(QMFObject)) ;
+
+ public Session Session {get;set;}
+ protected SchemaClass _Schema ;
+ virtual public SchemaClass Schema {get {return _Schema;} set {_Schema=value;}}
+ bool Managed ;
+ public DateTime CurrentTime {get;set;}
+ public DateTime CreateTime {get;set;}
+ public DateTime DeleteTime {get;set;}
+ public ObjectID ObjectID {get;set;}
+ public Dictionary<string, object> Properties = new Dictionary<string, object>() ;
+ public Dictionary<string, object> Statistics = new Dictionary<string, object>() ;
+
+
+ // This constructor is the "naked" constructor which creates
+ // an object without a session or a schema. It is used by
+ // subclasses which are auto generated
+ public QMFObject() {
+ }
+
+ public QMFObject(QMFObject source) {
+ this.Session = source.Session ;
+ this.Schema = source.Schema ;
+ this.Managed = source.Managed ;
+ this.CurrentTime = source.CurrentTime ;
+ this.CreateTime = source.CreateTime ;
+ this.DeleteTime = source.DeleteTime ;
+ this.ObjectID = source.ObjectID ;
+ this.Properties = source.Properties ;
+ this.Statistics = source.Statistics ;
+ }
+
+ // This constructor is used by a session make object call to
+ // create a blank object from a schema.
+ public QMFObject(Session session, SchemaClass schema, bool hasProperties, bool hasStats , bool isManaged) {
+ Session = session ;
+ Schema = schema ;
+ Managed = isManaged ;
+
+ if (hasProperties) {
+ foreach (SchemaProperty prop in Schema.GetAllProperties()) {
+ object propValue = null ;
+ if (!prop.Optional) {
+ propValue = Util.DefaultValue(prop.Type) ;
+ }
+ this.SetProperty(prop.Name, propValue) ;
+ }
+ }
+
+ if (hasStats) {
+ foreach (SchemaStatistic stat in Schema.Statistics) {
+ SetStatistic(stat.Name, Util.DefaultValue(stat.Type)) ;
+ }
+ }
+ }
+
+ // This constructor is used by the session to create an object based on a data
+ // stream by the agent.
+ public QMFObject(Session session, SchemaClass schema, IDecoder dec, bool hasProperties, bool hasStats , bool isManaged)
+ {
+ Session = session ;
+ Schema = schema ;
+ Managed = isManaged ;
+
+ if (Managed) {
+ // FIXME DateTime or Uint64??
+ CurrentTime = new DateTime(dec.ReadDatetime()) ;
+ CreateTime = new DateTime(dec.ReadDatetime()) ;
+ DeleteTime = new DateTime(dec.ReadDatetime()) ;
+ ObjectID = new ObjectID(dec) ;
+ }
+
+ if (hasProperties) {
+ List<string> excluded = ProcessPresenceMasks(dec, Schema) ;
+
+ foreach (SchemaProperty prop in Schema.GetAllProperties()) {
+ if (excluded.Contains(prop.Name)) {
+ log.Debug(String.Format("Setting Property Default {0}", prop.Name)) ;
+ safeAddProperty(prop.Name, null) ;
+ } else {
+ //log.Debug(String.Format("Setting Property {0}", prop.Name)) ;
+ safeAddProperty(prop.Name, session.DecodeValue(dec, prop.Type)) ;
+ }
+ }
+ }
+
+ if (hasStats) {
+ foreach (SchemaStatistic stat in Schema.GetAllStatistics()) {
+ //log.Debug(String.Format("Setting Statistic {0}", stat.Name)) ;
+ Statistics.Add(stat.Name, session.DecodeValue(dec, stat.Type)) ;
+ }
+ }
+
+ }
+
+ protected List<string> ProcessPresenceMasks(IDecoder dec, SchemaClass schema) {
+ List<string> excludes = new List<string> () ;
+ short bit = 0 ;
+ short mask = 0 ;
+ foreach (SchemaProperty prop in Schema.GetAllProperties()) {
+ if (prop.Optional) {
+ //log.Debug(String.Format("Property named {0} is optional", prop.Name)) ;
+ if (bit == 0) {
+ mask=dec.ReadUint8() ;
+ bit = 1 ;
+ }
+
+ if ((mask & bit) == 0) {
+ //log.Debug(String.Format("Property named {0} is not present", prop.Name)) ;
+ excludes.Add(prop.Name) ;
+ }
+ bit *= 2 ;
+ if (bit == 256) {
+ bit = 0 ;
+ }
+ }
+ }
+ return excludes ;
+ }
+
+ protected List<SchemaMethod> getMethods() {
+ return Schema.GetAllMethods() ;
+ }
+
+ public object GetProperty(string attributeName) {
+ //FIXME any object refs?
+ object returnValue = null ;
+ Properties.TryGetValue(attributeName, out returnValue) ;
+ return returnValue ;
+ }
+
+ protected void SetStatistic(string attributeName, object newValue) {
+ Statistics.Remove(attributeName) ;
+ Statistics.Add(attributeName, newValue) ;
+ }
+
+ public void SetProperty(string attributeName, object newValue) {
+ Properties.Remove(attributeName) ;
+ Properties.Add(attributeName, newValue) ;
+ }
+
+ public bool IsDeleted() {
+ return !DeleteTime.Equals(new DateTime(0)) ;
+ }
+
+ public string RoutingKey() {
+ return ObjectID.RoutingCode() ;
+ }
+
+ public long AgentBank() {
+ return ObjectID.AgentBank() ;
+ }
+
+ public long BrokerBank() {
+ return ObjectID.BrokerBank() ;
+ }
+
+ override public string ToString() {
+ string propertyString = "" ;
+ foreach (KeyValuePair<string, object> pair in Properties) {
+ propertyString = propertyString + String.Format("(Name: '{0}' Value: '{1}')", pair.Key, pair.Value) ;
+ }
+
+ string statsString = "" ;
+ foreach (KeyValuePair<string, object> sPair in Statistics) {
+ statsString = statsString + String.Format("(Name: '{0}' Value: '{1}')", sPair.Key, sPair.Value) ;
+ }
+ if (Managed) {
+ return String.Format("Managed QMFObject {0}:{1}({2}) Properties: [{3}] Statistics: [{4}])", Schema.PackageName, Schema.ClassName, ObjectID, propertyString, statsString) ;
+ } else {
+ return String.Format("QMFObject {0}:{1} Properties: [{2}] Statistics: [{3}]", Schema.PackageName, Schema.ClassName, propertyString, statsString) ;
+ }
+ }
+
+ public MethodResult InvokeMethod(string name, params object[] args) {
+ return this.InternalInvokeMethod(name, new List<object>(args), true, Broker.SYNC_TIME ) ;
+ }
+
+ public MethodResult InvokeMethod(string name, int timeToLive, params object[] args) {
+ return this.InternalInvokeMethod(name, new List<object>(args), true, timeToLive) ;
+ }
+
+ public MethodResult InvokeMethod(string name, bool synchronous, int timeToLive, params object[] args) {
+ return this.InternalInvokeMethod(name, new List<object>(args), synchronous, timeToLive ) ;
+ }
+
+ public MethodResult InvokeMethod(string name, bool synchronous, params object[] args) {
+ return this.InternalInvokeMethod(name, new List<object>(args), synchronous, Broker.SYNC_TIME) ;
+ }
+
+ protected MethodResult InternalInvokeMethod(string name, List<object> args, bool synchronous, int timeToLive) {
+ if (!Managed) {
+ throw new Exception ("Object is not Managed") ;
+ }
+ if (Schema.GetMethod(name) == null) {
+ throw new Exception (String.Format("Method named '{0}' does not exist", name)) ;
+ }
+ return Session.InvokeMethod(this, name, args, synchronous, timeToLive) ;
+ }
+
+ public void Encode (IEncoder enc) {
+ int mask = 0 ;
+ int bit = 0 ;
+ List<SchemaProperty> propsToEncode = new List<SchemaProperty>() ;
+ log.Debug(String.Format("Encoding class {0}:{1}", Schema.PackageName, Schema.ClassName)) ;
+
+ enc.WriteUint8(20) ;
+ Schema.Key.encode(enc) ;
+
+ foreach (SchemaProperty prop in Schema.GetAllProperties()) {
+ if (prop.Optional) {
+ if (bit == 0) {
+ bit =1 ;
+ }
+ if ((Properties.ContainsKey(prop.Name)) && (Properties[prop.Name] != null)) {
+ mask |= bit ;
+ propsToEncode.Add(prop) ;
+ } else {
+ }
+ bit = bit << 1 ;
+ if (bit == 256) {
+ bit = 0 ;
+ enc.WriteUint8((short)mask) ;
+ mask = 0 ;
+ }
+ } else {
+ propsToEncode.Add(prop) ;
+ }
+ }
+ if (bit != 0) {
+ enc.WriteUint8((short)mask) ;
+ }
+
+ foreach (SchemaProperty prop in propsToEncode) {
+ object obj = Properties[prop.Name] ;
+ //log.Debug(String.Format("Encoding property {0}", prop.Name)) ;
+ Session.EncodeValue(enc, prop.Type, obj) ;
+ }
+ foreach (SchemaStatistic stat in Schema.Statistics) {
+ object obj = Statistics[stat.Name] ;
+ Session.EncodeValue(enc, stat.Type, obj) ;
+ }
+ log.Debug("Done") ;
+
+ }
+
+
+ protected void safeAddProperty(string propName, object value) {
+ if (Properties.ContainsKey(propName)) {
+ Properties[propName] = value ;
+ } else {
+ Properties.Add(propName, value) ;
+ }
+ }
+
+
+ }
+}
diff --git a/qpid/dotnet/client-010/management/console/SchemaArgument.cs b/qpid/dotnet/client-010/management/console/SchemaArgument.cs
new file mode 100644
index 0000000000..d3ee508b31
--- /dev/null
+++ b/qpid/dotnet/client-010/management/console/SchemaArgument.cs
@@ -0,0 +1,59 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+using System;
+using System.Collections.Generic ;
+using org.apache.qpid.transport.codec ;
+
+namespace org.apache.qpid.console
+{
+
+ /**
+ * Metadata that describes the mapping of a method parameter to a QMF Object
+ */
+ public class SchemaArgument : SchemaVariable
+ {
+
+ public string Direction {get;set;}
+
+ public SchemaArgument(IDecoder dec, bool methodArg)
+ {
+ Dictionary<string, Object> map = dec.ReadMap() ;
+ base.PopulateData(map) ;
+
+ if (map.ContainsKey("dir")) {
+ Direction = (string) map["dir"] ;
+ }
+ }
+
+ public bool IsInput() {
+ return Direction.Equals("I") | Direction.Equals("IO") ;
+ }
+
+ public bool IsOutput() {
+ return Direction.Equals("O") | Direction.Equals("IO") ;
+ }
+
+ public bool IsBidirectional() {
+ return Direction.Equals("IO") ;
+ }
+ }
+}
diff --git a/qpid/dotnet/client-010/management/console/SchemaClass.cs b/qpid/dotnet/client-010/management/console/SchemaClass.cs
new file mode 100644
index 0000000000..320312b61d
--- /dev/null
+++ b/qpid/dotnet/client-010/management/console/SchemaClass.cs
@@ -0,0 +1,141 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+using System;
+using System.Collections.Generic ;
+using org.apache.qpid.transport;
+using org.apache.qpid.transport.codec ;
+
+using log4net ;
+
+namespace org.apache.qpid.console
+{
+
+ /**
+ * Metadata that describes the mapping of a class to a QMF Object
+ */
+ public class SchemaClass
+ {
+ public static int CLASS_KIND_TABLE = 1 ;
+ public static int CLASS_KIND_EVENT = 2 ;
+
+ public static ILog log = LogManager.GetLogger(typeof(SchemaClass)) ;
+
+
+ public ClassKey Key {get;set;}
+ public ClassKey SuperType {get;set;}
+ public int Kind {get;set;}
+ public List<SchemaMethod> Methods = new List<SchemaMethod>() ;
+ public List<SchemaArgument> Arguments = new List<SchemaArgument>() ;
+ public List<SchemaProperty> Properties = new List<SchemaProperty>() ;
+ public List<SchemaStatistic> Statistics = new List<SchemaStatistic>() ;
+
+ public string ClassName { get { return Key.ClassName;}}
+ public string PackageName { get { return Key.PackageName;}}
+ public string ClassKeyString { get { return Key.GetKeyString();}}
+
+ protected Session Session {get;set;}
+
+ public SchemaClass(int kind, ClassKey key, IDecoder dec, Session session)
+ {
+ log.Debug(String.Format("New schema class {0}", key)) ;
+ Kind = kind ;
+ Session = session ;
+ this.Key = key ;
+ bool hasSupertype = false ;
+
+ if (kind == CLASS_KIND_TABLE) {
+ int propCount = dec.ReadUint16() ;
+ int statCount = dec.ReadUint16() ;
+ int methodCount = dec.ReadUint16() ;
+
+ if (hasSupertype) {
+ SuperType = new ClassKey(dec) ;
+ }
+
+ for(int x = 0 ; x < propCount ; x++) {
+ Properties.Add(new SchemaProperty(dec)) ;
+ }
+ for(int x = 0 ; x < statCount ; x++) {
+ Statistics.Add(new SchemaStatistic(dec)) ;
+ }
+ for(int x = 0 ; x < methodCount ; x++) {
+ Methods.Add(new SchemaMethod(dec)) ;
+ }
+ }
+
+ if (kind == CLASS_KIND_EVENT) {
+ int argCount = dec.ReadUint16() ;
+ if (hasSupertype) {
+ SuperType = new ClassKey(dec) ;
+ }
+ for(int x = 0 ; x < argCount ; x++) {
+ Arguments.Add(new SchemaArgument(dec, false)) ;
+ }
+ }
+ }
+
+ public SchemaMethod GetMethod(string name) {
+ SchemaMethod returnValue = null ;
+ foreach(SchemaMethod method in Methods) {
+ if (method.Name.Equals(name)) {
+ returnValue = method ;
+ break ;
+ }
+ }
+ return returnValue ;
+ }
+
+ public List<SchemaProperty> GetAllProperties() {
+ if (SuperType == null) {
+ return Properties ;
+ } else {
+ List<SchemaProperty> allProperties = new List<SchemaProperty>(Properties) ;
+ allProperties.AddRange(Session.GetSchema(SuperType).GetAllProperties()) ;
+ return allProperties ;
+ }
+ }
+
+ public List<SchemaStatistic> GetAllStatistics() {
+ if (SuperType == null) {
+ return Statistics ;
+ } else {
+ List<SchemaStatistic> allStats = new List<SchemaStatistic>(Statistics) ;
+ allStats.AddRange(Session.GetSchema(SuperType).GetAllStatistics()) ;
+ return allStats ;
+ }
+ }
+
+ public List<SchemaMethod> GetAllMethods() {
+ if (SuperType == null) {
+ return Methods ;
+ } else {
+ List<SchemaMethod> allMethods = new List<SchemaMethod>(Methods) ;
+ allMethods.AddRange(Session.GetSchema(SuperType).GetAllMethods()) ;
+ return allMethods ;
+ }
+ }
+
+ public bool HasSuperType() {
+ return SuperType != null ;
+ }
+ }
+}
diff --git a/qpid/dotnet/client-010/management/console/SchemaMethod.cs b/qpid/dotnet/client-010/management/console/SchemaMethod.cs
new file mode 100644
index 0000000000..0a843262a4
--- /dev/null
+++ b/qpid/dotnet/client-010/management/console/SchemaMethod.cs
@@ -0,0 +1,66 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+using System;
+using System.Collections.Generic ;
+using org.apache.qpid.transport;
+using org.apache.qpid.transport.codec ;
+
+namespace org.apache.qpid.console
+{
+
+ /**
+ * Metadata that describes the mapping of a method to a QMF Object
+ */
+ public class SchemaMethod
+ {
+ public string Name {get;set;}
+ public int ArgCount {get;set;}
+ public int InputArgCount {get;set;}
+ public int OutputArgCount {get;set;}
+ public int BidirectionalArgCount {get;set;}
+ public string Description {get;set;}
+ public List<SchemaArgument> Arguments = new List<SchemaArgument>();
+
+ public SchemaMethod(IDecoder dec)
+ {
+ Dictionary<string, Object> map = dec.ReadMap() ;
+ Name = (string) map["name"] ;
+ ArgCount = (int) map["argCount"] ;
+ if (map.ContainsKey("desc")) {
+ Description = (string) map["desc"] ;
+ }
+ for (int x = 0 ; x < ArgCount ; x++) {
+ SchemaArgument arg = new SchemaArgument(dec, true) ;
+ Arguments.Add(arg) ;
+ if (arg.IsInput()) {
+ InputArgCount += 1 ;
+ }
+ if (arg.IsOutput()) {
+ OutputArgCount += 1 ;
+ }
+ if (arg.IsBidirectional()) {
+ BidirectionalArgCount += 1 ;
+ }
+ }
+ }
+ }
+}
diff --git a/qpid/dotnet/client-010/management/console/SchemaProperty.cs b/qpid/dotnet/client-010/management/console/SchemaProperty.cs
new file mode 100644
index 0000000000..50d3c62f8d
--- /dev/null
+++ b/qpid/dotnet/client-010/management/console/SchemaProperty.cs
@@ -0,0 +1,59 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+using System;
+using System.Collections.Generic ;
+using org.apache.qpid.transport.codec ;
+
+namespace org.apache.qpid.console
+{
+
+ /**
+ * Metadata that describes the mapping of an object property to a QMF Object
+ */
+ public class SchemaProperty : SchemaVariable
+ {
+ public int Access {get;set;}
+ public bool Index {get;set;}
+ public bool Optional {get;set;}
+
+ public SchemaProperty(IDecoder dec)
+ {
+ Dictionary<string, Object> map = dec.ReadMap() ;
+ base.PopulateData(map) ;
+ Name = (string) map["name"] ;
+
+ if (map.ContainsKey("optional")) {
+ //System.Console.WriteLine("optional") ;
+ Optional = (int)map["optional"] != 0 ;
+ }
+ if (map.ContainsKey("index")) {
+ //System.Console.WriteLine("index") ;
+ Index = (int)map["index"] != 0 ;
+ }
+ if (map.ContainsKey("access")) {
+ //System.Console.WriteLine("access") ;
+ Access = (int) map["access"] ;
+ }
+
+ }
+ }
+}
diff --git a/qpid/dotnet/client-010/management/console/SchemaStatistic.cs b/qpid/dotnet/client-010/management/console/SchemaStatistic.cs
new file mode 100644
index 0000000000..ff96b98388
--- /dev/null
+++ b/qpid/dotnet/client-010/management/console/SchemaStatistic.cs
@@ -0,0 +1,54 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+using System;
+using System.Collections.Generic ;
+using org.apache.qpid.transport.codec ;
+
+namespace org.apache.qpid.console
+{
+
+ /**
+ * Metadata that describes the mapping of an object Statistic
+ */
+ public class SchemaStatistic
+ {
+
+ public string Name {get;set;}
+ public short Type {get;set;}
+ public string Description {get;set;}
+ public string Unit {get;set;}
+
+ public SchemaStatistic(IDecoder dec)
+ {
+ Dictionary<string, Object> map = dec.ReadMap() ;
+ Name = (string) map["name"] ;
+ Type = (short) short.Parse(""+map["type"]) ;
+
+ if (map.ContainsKey("unit")) {
+ Unit = (string) map["unit"] ;
+ }
+ if (map.ContainsKey("description")) {
+ Description = (string) map["description"] ;
+ }
+ }
+ }
+}
diff --git a/qpid/dotnet/client-010/management/console/SchemaVariable.cs b/qpid/dotnet/client-010/management/console/SchemaVariable.cs
new file mode 100644
index 0000000000..50455ab38a
--- /dev/null
+++ b/qpid/dotnet/client-010/management/console/SchemaVariable.cs
@@ -0,0 +1,84 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+using System;
+using System.Collections.Generic ;
+using org.apache.qpid.transport.codec ;
+
+namespace org.apache.qpid.console
+{
+
+ /**
+ * Metadata for mapping properties, arguments, and statistics
+ */
+ public abstract class SchemaVariable
+ {
+ public string Name {get;set;}
+ public short Type {get;set;}
+ public string Description {get;set;}
+ public string Unit {get;set;}
+ public int? Min {get;set;}
+ public int? Max {get;set;}
+ public int? MaxLength {get;set;}
+ public string Default {get;set;}
+ public string RefPackage {get;set;}
+ public string RefClass {get;set;}
+
+ public SchemaVariable() {
+ }
+
+ protected void PopulateData(Dictionary<string, Object> map)
+ {
+
+ if (map.ContainsKey("name")) {
+ Name = (string) map["name"] ;
+ }
+ if (map.ContainsKey("type")) {
+ Type = short.Parse((""+ map["type"])) ;
+ }
+
+ if (map.ContainsKey("unit")) {
+ Unit = (string) map["unit"] ;
+ }
+ if (map.ContainsKey("min")) {
+ Min = (int) map["min"] ;
+ }
+ if (map.ContainsKey("max")) {
+ Max = (int) map["max"] ;
+ }
+ if (map.ContainsKey("maxlen")) {
+ MaxLength = (int) map["maxlen"] ;
+ }
+ if (map.ContainsKey("description")) {
+ Description = (string) map["description"] ;
+ }
+ if (map.ContainsKey("refClass")) {
+ RefClass = (string) map["refClass"] ;
+ }
+ if (map.ContainsKey("refPackage")) {
+ RefPackage = (string) map["refPackage"] ;
+ }
+ if (map.ContainsKey("Default")) {
+ Default = (string) map["default"] ;
+ }
+ }
+ }
+}
diff --git a/qpid/dotnet/client-010/management/console/SequenceManager.cs b/qpid/dotnet/client-010/management/console/SequenceManager.cs
new file mode 100644
index 0000000000..29f1ba26b0
--- /dev/null
+++ b/qpid/dotnet/client-010/management/console/SequenceManager.cs
@@ -0,0 +1,62 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Threading ;
+
+namespace org.apache.qpid.console
+{
+
+ /**
+ * Holds state during asynchronous calls to the broker.
+ */
+ public class SequenceManager
+ {
+ long sequence = 0 ;
+ Dictionary<long, Object> pending = new Dictionary<long, Object>() ;
+ Object lockObject = new Object() ;
+
+ public SequenceManager()
+ {
+ }
+
+ public long Reserve(Object data) {
+ long returnValue = 0 ;
+ lock(lockObject) {
+ returnValue = sequence ;
+ sequence += 1 ;
+ pending.Add(returnValue, data) ;
+ }
+ return returnValue;
+ }
+
+ public Object Release(long seq) {
+ Object returnValue = null ;
+ lock(lockObject) {
+ returnValue = pending[seq] ;
+ pending.Remove(seq) ;
+ }
+
+ return returnValue ;
+ }
+ }
+}
diff --git a/qpid/dotnet/client-010/management/console/Session.cs b/qpid/dotnet/client-010/management/console/Session.cs
new file mode 100644
index 0000000000..d9c5948e57
--- /dev/null
+++ b/qpid/dotnet/client-010/management/console/Session.cs
@@ -0,0 +1,796 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+using System;
+using System.Collections.Generic;
+using System.IO ;
+using System.Reflection ;
+using System.Threading ;
+using log4net ;
+using org.apache.qpid.client ;
+using org.apache.qpid.transport.util;
+using org.apache.qpid.transport.codec ;
+
+namespace org.apache.qpid.console
+{
+
+ /**
+ * Main Interaction point for interaction with the bus. Can be used to locate objects
+ * on the bus, and invoke messages on them.
+ */
+ public class Session
+ {
+ public static ILog log = LogManager.GetLogger(typeof(Session)) ;
+
+ public static int CONTEXT_SYNC = 1 ;
+ public static int CONTEXT_STARTUP = 2 ;
+ public static int CONTEXT_MULTIGET = 3 ;
+ public static int DEFAULT_GET_WAIT_TIME = 60000 ;
+
+ public bool RecieveObjects = true ;
+ public bool RecieveEvents = true ;
+ public bool RecieveHeartbeat = true ;
+ public bool UserBindings = false ;
+ public Console Console ;
+
+ protected Dictionary<string, Dictionary<string, SchemaClass>> Packages = new Dictionary<string, Dictionary<string, SchemaClass>>() ;
+ protected List<Broker> Brokers = new List<Broker>() ;
+ protected SequenceManager SequenceManager = new SequenceManager() ;
+ protected object LockObject = new Object();
+ protected List<long> SyncSequenceList = new List<long>() ;
+ protected List<QMFObject> GetResult ;
+ protected Object SyncResult ;
+
+ public Session()
+ {
+ }
+
+ public Session(Console console) {
+ Console = console ;
+ }
+
+ public void AddBroker(string url) {
+ BrokerURL brokerurl = GetBrokerURL(url) ;
+ Broker broker = new Broker(this, brokerurl) ;
+ Brokers.Add(broker) ;
+
+ Dictionary<string, object> args = new Dictionary<string, object>() ;
+ args.Add("_class", "agent") ;
+ args.Add("_broker", broker) ;
+ this.GetObjects(args) ;
+ }
+
+ public void RemoveBroker(Broker broker) {
+ if (Brokers.Contains(broker)) {
+ Brokers.Remove(broker) ;
+ }
+
+ broker.Shutdown() ;
+ }
+
+ public void Close() {
+ foreach (Broker broker in Brokers.ToArray()) {
+ this.RemoveBroker(broker) ;
+ }
+ }
+
+ protected BrokerURL GetBrokerURL(string url) {
+ return new BrokerURL(url) ;
+ }
+
+
+ public List<QMFObject> GetObjects(Dictionary<string, object> args) {
+ List<Broker> brokerList = null ;
+ List<Agent> agentList = new List<Agent>() ;
+
+ if (args.ContainsKey("_broker")) {
+ brokerList = new List<Broker>() ;
+ brokerList.Add((Broker)args["_broker"]) ;
+ } else {
+ brokerList = this.Brokers ;
+ }
+
+ foreach (Broker broker in brokerList) {
+ broker.WaitForStable() ;
+ }
+
+ if (args.ContainsKey("_agent")) {
+ Agent agent = (Agent)args["_agent"] ;
+ if (brokerList.Contains(agent.Broker)) {
+ agentList.Add(agent) ;
+ } else {
+ throw new Exception("Agent is not managed by this console or the supplied broker") ;
+ }
+ } else {
+ if (args.ContainsKey("_objectId")) {
+ ObjectID oid = (ObjectID) args["_objectId"] ;
+ foreach (Broker broker in Brokers) {
+ foreach (Agent agent in broker.Agents.Values) {
+ if ((agent.AgentBank == oid.AgentBank()) && (agent.BrokerBank == oid.BrokerBank())) {
+ agentList.Add(agent) ;
+ }
+ }
+ }
+ }
+ else {
+ foreach (Broker broker in brokerList) {
+ foreach (Agent agent in broker.Agents.Values) {
+ if (agent.Broker.IsConnected()) {
+ agentList.Add(agent) ;
+ }
+ }
+ }
+ }
+ }
+
+ GetResult = new List<QMFObject>() ;
+
+ if (agentList.Count > 0) {
+ //FIXME Add a bunch of other suff too
+ foreach (Agent agent in agentList) {
+ Dictionary<string, object> getParameters = new Dictionary<string, object>() ;
+ Broker broker = agent.Broker ;
+ long seq = -1 ;
+ lock(LockObject) {
+ seq = SequenceManager.Reserve(Session.CONTEXT_MULTIGET) ;
+ SyncSequenceList.Add(seq) ;
+ }
+ object packageName = null ;
+ object className = null ;
+ object key = null ;
+ object sClass = null ;
+ object oid = null ;
+ object hash = null ;
+
+ args.TryGetValue("_schema", out sClass) ;
+ args.TryGetValue("_key", out key) ;
+ args.TryGetValue("_class", out className) ;
+ args.TryGetValue("_package", out packageName) ;
+ args.TryGetValue("_objectID", out oid) ;
+ args.TryGetValue("_hash", out hash) ;
+
+ if ((className == null) && (oid == null) && (oid == null)) {
+ throw new Exception("No class supplied, use '_schema', '_key', '_class', or '_objectId' argument") ;
+ }
+
+ if (oid != null) {
+ getParameters.Add("_objectID", oid) ;
+ }
+ else {
+ if (sClass != null) {
+ key = key ?? ((SchemaClass)sClass).Key ;
+ }
+ if (key != null) {
+ ClassKey cKey = (ClassKey)key ;
+ className = className ?? cKey.ClassName ;
+ packageName = packageName ?? cKey.PackageName ;
+ hash = hash ?? cKey.Hash ;
+ }
+
+ if (packageName != null) {
+ getParameters.Add("_package", packageName) ;
+ }
+ if (className != null) {
+ getParameters.Add("_class", className) ;
+ }
+ if (hash != null) {
+ getParameters.Add("_hash", hash) ;
+ }
+ foreach (KeyValuePair<string, object> pair in args) {
+ if (!pair.Key.StartsWith("_")) {
+ getParameters.Add(pair.Key, pair.Value) ;
+ }
+ }
+ }
+
+ IEncoder enc = broker.CreateEncoder('G', seq) ;
+ enc.WriteMap(getParameters) ;
+ string routingKey = String.Format("agent.{0}.{1}", agent.BrokerBank, agent.AgentBank) ;
+ Message msg = broker.CreateMessage(enc, routingKey) ;
+ log.Debug("Get Object Keys: ") ;
+ foreach (string pKey in getParameters.Keys) {
+ log.Debug(String.Format("\tKey: '{0}' Value: '{1}'", pKey, getParameters[pKey])) ;
+ }
+ broker.Send(msg) ;
+ }
+
+ int waittime = DEFAULT_GET_WAIT_TIME ;
+ bool timeout = false ;
+ if (args.ContainsKey("_timeout")) {
+ waittime = (int) args["_timeout"] ;
+ }
+ DateTime start = DateTime.Now ;
+ lock (LockObject) {
+ // FIXME ERROR
+ while (SyncSequenceList.Count > 0){
+ Monitor.Wait(LockObject,waittime) ;
+ TimeSpan duration = DateTime.Now - start;
+ if (duration.TotalMilliseconds > waittime) {
+ foreach (long pendingSeq in SyncSequenceList) {
+ SequenceManager.Release(pendingSeq) ;
+ }
+ SyncSequenceList.Clear() ;
+ timeout = true ;
+ }
+ }
+ }
+
+ //FIXME Add the error logic
+ if ((GetResult.Count == 0) && timeout) {
+ throw new Exception ("Get Request timed out") ;
+ }
+ }
+ return GetResult ;
+ }
+
+ public List<string> GetPackages() {
+ this.WaitForStable() ;
+ List<string> returnValue = new List<string>() ;
+ foreach (String name in Packages.Keys) {
+ returnValue.Add(name) ;
+ }
+
+ return returnValue ;
+ }
+
+ public List<ClassKey> GetClasses(string packageName) {
+ List<ClassKey> returnValue = new List<ClassKey>() ;
+ this.WaitForStable() ;
+
+ if (Packages.ContainsKey(packageName)) {
+ foreach (SchemaClass sClass in Packages[packageName].Values) {
+ returnValue.Add(sClass.Key) ;
+ }
+ }
+
+ return returnValue ;
+ }
+
+ public SchemaClass GetSchema(ClassKey key) {
+ return GetSchema(key, true) ;
+ }
+
+ protected SchemaClass GetSchema(ClassKey key, bool waitForStable) {
+ if (waitForStable) {
+ this.WaitForStable() ;
+ }
+
+ SchemaClass returnValue = null ;
+
+ try {
+ returnValue = Packages[key.PackageName][key.GetKeyString()] ;
+ }
+ catch (KeyNotFoundException) {
+ // eat it
+ }
+
+ return returnValue ;
+ }
+
+
+ protected void WaitForStable() {
+ foreach (Broker broker in Brokers) {
+ broker.WaitForStable() ;
+ }
+ }
+
+
+ public Broker GetBroker(long BrokerBank) {
+ Broker returnValue = null ;
+
+ foreach (Broker broker in Brokers) {
+ if (broker.BrokerBank() == BrokerBank) {
+ returnValue = broker ;
+ break ;
+ }
+ }
+
+ return returnValue ;
+ }
+
+ public MethodResult InvokeMethod(QMFObject obj, string name, List<object> args, bool synchronous, int timeToLive) {
+ Broker aBroker = this.GetBroker(obj.BrokerBank()) ;
+
+ long seq = this.SendMethodRequest(obj, aBroker, name, args, synchronous, timeToLive) ;
+ if (seq != 0) {
+ if (!synchronous) {
+ return null ;
+ }
+ try {
+ aBroker.WaitForSync(timeToLive) ;
+ } catch (Exception e) {
+ SequenceManager.Release(seq) ;
+ throw e ;
+ }
+
+ // FIXME missing error logic in the broker
+ return (MethodResult) SyncResult ;
+ }
+
+ return null ;
+ }
+
+ protected long SendMethodRequest(QMFObject obj, Broker aBroker, string name, List<object> args, bool synchronous, int timeToLive) {
+
+ SchemaMethod method = obj.Schema.GetMethod(name) ;
+ if (args == null) {
+ args = new List<object>() ;
+ }
+
+ long seq = 0 ;
+ if (method != null) {
+ KeyValuePair<SchemaMethod, bool> pair = new KeyValuePair<SchemaMethod, bool>(method, synchronous) ;
+ seq = SequenceManager.Reserve(pair) ;
+ IEncoder enc = aBroker.CreateEncoder('M', seq) ;
+ obj.ObjectID.encode(enc) ;
+ obj.Schema.Key.encode(enc) ;
+ enc.WriteStr8(name) ;
+
+ if (args.Count < method.InputArgCount) {
+ throw new Exception(String.Format("Incorrect number of arguments: expected {0}, got{1}", method.InputArgCount, args.Count)) ;
+ }
+
+ int argIndex = 0 ;
+ foreach (SchemaArgument arg in method.Arguments) {
+ if (arg.IsInput()) {;
+ this.EncodeValue(enc, arg.Type, args[argIndex]) ;
+ argIndex += 1 ;
+ }
+ }
+
+ Message msg = aBroker.CreateMessage(enc,obj.RoutingKey(),timeToLive) ;
+
+ if (synchronous) {
+ aBroker.SetSyncInFlight(true) ;
+ }
+ aBroker.Send(msg) ;
+ }
+ return seq ;
+ }
+
+ public QMFObject MakeObject(ClassKey key) {
+ SchemaClass sClass = this.GetSchema(key) ;
+ if (sClass == null) {
+ throw new Exception("No schema found for class " + key.ToString()) ;
+ }
+
+ return this.CreateQMFObject(sClass, true, true, false) ;
+ }
+
+ public QMFObject MakeObject(String keyString) {
+ return this.MakeObject(new ClassKey(keyString)) ;
+ }
+
+ // Callback Methods
+ public void HandleNewAgent(Agent agent) {
+ if (Console != null) {
+ Console.NewAgent(agent) ;
+ }
+ }
+
+ public void HandleAgentRemoved(Agent agent) {
+ if (Console != null) {
+ Console.AgentRemoved(agent) ;
+ }
+ }
+
+ public void HandleBrokerConnect(Broker broker) {
+ if (Console != null) {
+ Console.BrokerConnected(broker) ;
+ }
+ }
+
+ public void HandleBrokerDisconnect(Broker broker) {
+ if (Console != null) {
+ Console.BrokerDisconnected(broker) ;
+ }
+ }
+
+ public void HandleBrokerResponse(Broker broker, IDecoder decoder, long sequence) {
+ if (Console != null) {
+ Console.BrokerInformation(broker) ;
+ }
+
+ long seq = SequenceManager.Reserve(CONTEXT_STARTUP) ;
+ IEncoder endocder = broker.CreateEncoder('P', seq) ;
+ broker.Send(endocder) ;
+ }
+
+ public void HandlePackageIndicator(Broker broker, IDecoder decoder, long sequence) {
+ string packageName = decoder.ReadStr8() ;
+ bool notify = false ;
+ if (!Packages.ContainsKey(packageName)) {
+ lock (LockObject) {
+ Packages[packageName] = new Dictionary<string, SchemaClass>() ;
+ notify = true ;
+ }
+ }
+
+ if (notify && Console != null) {
+ Console.NewPackage(packageName) ;
+ }
+
+ broker.IncrementOutstanding() ;
+ long seq = SequenceManager.Reserve(Session.CONTEXT_STARTUP) ;
+ IEncoder enc = broker.CreateEncoder('Q', seq) ;
+ enc.WriteStr8(packageName) ;
+ broker.Send(enc) ;
+ }
+
+ public void HandleCommandComplete(Broker broker, IDecoder decoder, long sequence) {
+
+ long code = decoder.ReadUint32() ;
+ string text = decoder.ReadStr8() ;
+ Object context = this.SequenceManager.Release(sequence) ;
+
+ if (context.Equals(CONTEXT_STARTUP)) {
+ broker.DecrementOutstanding() ;
+ } else {
+ if ((context.Equals(CONTEXT_SYNC)) & broker.GetSyncInFlight()) {
+ broker.SetSyncInFlight(false) ;
+ } else {
+ if (context.Equals(CONTEXT_MULTIGET) && SyncSequenceList.Contains(sequence)) {
+ lock(LockObject) {
+ SyncSequenceList.Remove(sequence) ;
+ if (SyncSequenceList.Count == 0) {
+ Monitor.PulseAll(LockObject) ;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ public void HandleClassIndicator(Broker broker, IDecoder decoder, long sequence) {
+ short kind = decoder.ReadUint8() ;
+ ClassKey classKey = new ClassKey(decoder) ;
+ bool unknown = false ;
+
+
+ lock (LockObject) {
+ if (Packages.ContainsKey(classKey.PackageName)) {
+ if (!Packages[classKey.PackageName].ContainsKey(classKey.GetKeyString())) {
+ unknown = true ;
+ }
+ }
+ }
+
+ if (unknown) {
+ broker.IncrementOutstanding() ;
+ long seq = SequenceManager.Reserve(Session.CONTEXT_STARTUP) ;
+ IEncoder enc = broker.CreateEncoder('S', seq) ;
+ classKey.encode(enc) ;
+ broker.Send(enc) ;
+ }
+ }
+
+ public void HandleMethodResponse(Broker broker, IDecoder decoder, long sequence) {
+ long code = decoder.ReadUint32() ;
+ string text = decoder.ReadStr16() ;
+
+ Dictionary<string, object> outArgs = new Dictionary<string, object>() ;
+ object obj = SequenceManager.Release(sequence) ;
+
+ if (obj == null) {
+ return ;
+ }
+
+ KeyValuePair<SchemaMethod, bool> pair = (KeyValuePair<SchemaMethod, bool>) obj ;
+ if (code == 0) {
+ foreach (SchemaArgument arg in pair.Key.Arguments) {
+ if (arg.IsOutput()) {
+ outArgs.Add(arg.Name, this.DecodeValue(decoder, arg.Type)) ;
+ }
+ }
+ }
+
+ MethodResult result = new MethodResult(code, text, outArgs) ;
+
+ if (pair.Value) {
+ this.SyncResult = result;
+ broker.SetSyncInFlight(false) ;
+ }
+
+ if (Console != null) {
+ Console.MethodResponse(broker, sequence, result) ;
+ }
+ }
+
+ public void HandleHeartbeatIndicator(Broker broker, IDecoder decoder, long sequence, IMessage msg) {
+ if (Console != null) {
+ long brokerBank = 1 ;
+ long agentBank = 0 ;
+ try {
+ string routingKey = msg.DeliveryProperties.GetRoutingKey() ;
+ if (routingKey != null) {
+ agentBank = Agent.GetBrokerBank(routingKey) ;
+ brokerBank = Agent.GetBrokerBank(routingKey) ;
+ }
+ }
+ catch (Exception e) {
+ log.Warn("Internal QPID error", e) ;
+ }
+
+ string agentKey = Agent.AgentKey(agentBank, brokerBank) ;
+ long timestamp = decoder.ReadUint64() ;
+ if (broker.Agents.ContainsKey(agentKey)) {
+ Agent agent = broker.Agents[agentKey] ;
+ Console.HearbeatRecieved(agent, timestamp) ;
+ }
+ }
+
+ }
+
+ public void HandleEventIndicator(Broker broker, IDecoder decoder, long sequence) {
+ if (Console != null) {
+ QMFEvent newEvent = new QMFEvent(this, decoder) ;
+ Console.EventRecieved(broker, newEvent) ;
+ }
+ }
+
+ public void HandleSchemaResponse(Broker broker, IDecoder decoder, long sequence) {
+ short kind = decoder.ReadUint8() ;
+ ClassKey classKey = new ClassKey(decoder) ;
+ SchemaClass sClass = new SchemaClass(kind, classKey, decoder, this) ;
+ lock(LockObject) {
+ Dictionary<string, SchemaClass> classMappings = Packages[sClass.PackageName] ;
+ classMappings.Remove(sClass.ClassKeyString) ;
+ classMappings.Add(sClass.ClassKeyString, sClass) ;
+ }
+
+ SequenceManager.Release(sequence) ;
+ broker.DecrementOutstanding() ;
+ if (Console != null) {
+ this.Console.NewClass(kind, classKey) ;
+ }
+ }
+
+ public void HandleContentIndicator(Broker broker, IDecoder decoder, long sequence, bool hasProperties, bool hasStatistics) {
+
+ ClassKey key = new ClassKey(decoder) ;
+ SchemaClass sClass = null ;;
+ lock (LockObject) {
+ sClass = GetSchema(key, false) ;
+ }
+ if (sClass != null) {
+ QMFObject obj = this.CreateQMFObject(sClass, decoder, hasProperties, hasStatistics, true) ;
+
+ if (key.PackageName.Equals("org.apache.qpid.broker") && key.ClassName.Equals("agent") && hasProperties) {
+ broker.UpdateAgent(obj) ;
+ }
+
+ lock (LockObject) {
+ if (SyncSequenceList.Contains(sequence)) {
+ if (!obj.IsDeleted() && this.SelectMatch(obj)) {
+ GetResult.Add(obj) ;
+ }
+ }
+ }
+
+ if (Console != null) {
+ if (hasProperties) {
+ Console.ObjectProperties(broker, obj) ;
+ }
+ if (hasStatistics) {
+ Console.ObjectStatistics(broker, obj) ;
+ }
+ }
+ }
+ }
+
+ public bool SelectMatch(QMFObject obj) {
+ return true ;
+ }
+
+ public object DecodeValue(IDecoder dec, short type) {
+
+ switch (type) {
+ case 1: return dec.ReadUint8() ; // U8
+ case 2: return dec.ReadUint16() ; // U16
+ case 3: return dec.ReadUint32() ; // U32
+ case 4: return dec.ReadUint64() ; // U64
+ case 6: return dec.ReadStr8() ; // SSTR
+ case 7: return dec.ReadStr16() ; // LSTR
+ case 8: return dec.ReadDatetime() ; // ABSTIME
+ case 9: return dec.ReadUint32() ; // DELTATIME
+ case 10: return new ObjectID(dec) ; // ref
+ case 11: return dec.ReadUint8() != 0 ; // bool
+ case 12: return dec.ReadFloat() ; // float
+ case 13: return dec.ReadDouble() ; // double
+ case 14: return dec.ReadUuid() ; // UUID
+ case 15: return dec.ReadMap() ; // Ftable
+ case 16: return dec.ReadInt8() ; // int8
+ case 17: return dec.ReadInt16() ; // int16
+ case 18: return dec.ReadInt32() ; // int32
+ case 19: return dec.ReadInt64() ; // int64
+ case 20: // Object
+ // Peek into the inner type code, make sure
+ // it is actually an object
+ object returnValue = null ;
+ short innerTypeCode = dec.ReadUint8() ;
+ if (innerTypeCode != 20) {
+ returnValue = this.DecodeValue(dec, innerTypeCode) ;
+ }
+ else {
+ ClassKey classKey = new ClassKey(dec) ;
+ lock(LockObject) {
+ SchemaClass sClass = GetSchema(classKey) ;
+ if (sClass != null) {
+ returnValue = this.CreateQMFObject(sClass, dec, true, true, false) ;
+ }
+ }
+ }
+ return returnValue;
+ case 21: // List
+ {
+ MSDecoder lDec = new MSDecoder();
+ lDec.Init(new MemoryStream(dec.ReadVbin32()));
+ long count = lDec.ReadUint32();
+ List<object> newList = new List<object>();
+ while (count > 0)
+ {
+ short innerType = lDec.ReadUint8();
+ newList.Add(this.DecodeValue(lDec, innerType));
+ count -= 1;
+ }
+ return newList;
+ }
+ case 22: // Array
+ {
+ MSDecoder aDec = new MSDecoder();
+ aDec.Init(new MemoryStream(dec.ReadVbin32()));
+ long cnt = aDec.ReadUint32();
+ short innerType = aDec.ReadUint8();
+ List<object> aList = new List<object>();
+ while (cnt > 0)
+ {
+ aList.Add(this.DecodeValue(aDec, innerType));
+ cnt -= 1;
+ }
+ return aList;
+ }
+ default:
+ throw new Exception(String.Format("Invalid Type Code: {0}", type)) ;
+ }
+ }
+
+
+ public void EncodeValue(IEncoder enc, short type, object val) {
+ try {
+ switch ((int)type) {
+ case 1: enc.WriteUint8((short) val) ; break; // U8
+ case 2: enc.WriteUint16((int) val) ; break; // U16
+ case 3: enc.WriteUint32((long) val) ; break; // U32
+ case 4: enc.WriteUint64((long) val) ; break; // U64
+ case 6: enc.WriteStr8((string) val) ; break; // SSTR
+ case 7: enc.WriteStr16((string) val) ; break; // LSTR
+ case 8: enc.WriteDatetime((long) val); break; // ABSTIME
+ case 9: enc.WriteUint32((long) val); break; // DELTATIME
+ case 10: ((ObjectID)val).encode(enc) ; break; // ref
+ case 11:
+ if ((bool) val) {
+ enc.WriteUint8(1) ;
+ } else {
+ enc.WriteUint8(0) ;
+ }
+ break ;
+ case 12: enc.WriteFloat((float) val); break; // FLOAT
+ case 13: enc.WriteDouble((double) val); break; // DOUBLE
+ case 14: enc.WriteUuid((UUID) val) ; break ; // UUID
+ case 15: enc.WriteMap((Dictionary<string, object>) val) ; break ; // Ftable
+ case 16: enc.WriteInt8((short) val) ; break; // int8
+ case 17: enc.WriteInt16((int) val) ; break; // int16
+ case 18: enc.WriteInt32(long.Parse(""+ val)) ; break; // int32
+ case 19: enc.WriteInt64(long.Parse("" + val)) ; break; // int64
+ case 20: // Object
+ // Check that the object has a session, if not
+ // take ownership of it
+ QMFObject qObj = (QMFObject) val ;
+ if (qObj.Session == null) {
+ qObj.Session = this ;
+ }
+ qObj.Encode(enc) ;
+ break;
+ case 21: // List
+ List<object> items = (List<object>) val ;
+ MSEncoder lEnc = new MSEncoder(1) ;
+ lEnc.Init() ;
+ lEnc.WriteUint32(items.Count) ;
+ foreach (object obj in items) {
+ short innerType = Util.QMFType(obj) ;
+ lEnc.WriteUint8(innerType) ;
+ this.EncodeValue(lEnc,innerType,obj) ;
+ }
+ enc.WriteVbin32(lEnc.Segment().ToArray()) ;
+ break ;
+ case 22: // Array
+ List<object> aItems = (List<object>) val ;
+ MSEncoder aEnc = new MSEncoder(1) ;
+ aEnc.Init() ;
+ long aCount = aItems.Count ;
+ aEnc.WriteUint32(aCount) ;
+ if (aCount > 0) {
+ Object anObj = aItems[0] ;
+ short innerType = Util.QMFType(anObj) ;
+ aEnc.WriteUint8(innerType) ;
+ foreach (object obj in aItems) {
+ this.EncodeValue(aEnc,innerType,obj) ;
+ }
+ }
+ enc.WriteVbin32(aEnc.Segment().ToArray()) ;
+ break ;
+ default:
+ throw new Exception(String.Format("Invalid Type Code: {0}", type)) ;
+ }
+ }
+ catch (System.InvalidCastException e) {
+ string msg = String.Format("Class cast exception for typecode {0}, type {1} ", type, val.GetType()) ;
+ log.Error(msg) ;
+ throw new Exception(msg + type, e) ;
+ }
+ }
+
+ public List<string> BindingKeys() {
+ List<string> bindings = new List<string>() ;
+ bindings.Add("schema.#") ;
+ if (RecieveObjects & RecieveEvents & RecieveHeartbeat & !UserBindings) {
+ bindings.Add("console.#") ;
+ }
+ else {
+ if (RecieveObjects & !UserBindings) {
+ bindings.Add("console.obj.#") ;
+ }
+ else {
+ bindings.Add("console.obj.*.*.org.apache.qpid.broker.agent") ;
+ }
+ if (RecieveEvents) {
+ bindings.Add("console.event.#") ;
+ }
+ if (RecieveHeartbeat) {
+ bindings.Add("console.heartbeat.#") ;
+ }
+ }
+ return bindings ;
+ }
+
+ protected QMFObject CreateQMFObject(SchemaClass schema, bool hasProperties, bool hasStats , bool isManaged) {
+ Type realClass = typeof(QMFObject) ;
+ if (Console != null) {
+ realClass = Console.TypeMapping(schema.Key) ;
+ }
+ Type[] types = new Type[] {typeof(Session), typeof(SchemaClass), typeof(bool), typeof(bool),typeof(bool)} ;
+ object[] args = new object[] {this, schema, hasProperties, hasStats, isManaged} ;
+ ConstructorInfo ci = realClass.GetConstructor(types);
+ return (QMFObject) ci.Invoke(args) ;
+ }
+
+ protected QMFObject CreateQMFObject(SchemaClass schema, IDecoder dec, bool hasProperties, bool hasStats , bool isManaged) {
+ Type realClass = typeof(QMFObject) ;
+ if (Console != null) {
+ realClass = Console.TypeMapping(schema.Key) ;
+ }
+ Type[] types = new Type[] {typeof(Session), typeof(SchemaClass), typeof(IDecoder), typeof(bool), typeof(bool),typeof(bool)} ;
+ object[] args = new object[] {this, schema, dec, hasProperties, hasStats, isManaged} ;
+ ConstructorInfo ci = realClass.GetConstructor(types);
+ return (QMFObject) ci.Invoke(args) ;
+ }
+ }
+}
diff --git a/qpid/dotnet/client-010/management/console/Util.cs b/qpid/dotnet/client-010/management/console/Util.cs
new file mode 100644
index 0000000000..4a06f4e6af
--- /dev/null
+++ b/qpid/dotnet/client-010/management/console/Util.cs
@@ -0,0 +1,150 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+using System;
+using System.Collections.Generic;
+using org.apache.qpid.client ;
+using org.apache.qpid.transport.util;
+using org.apache.qpid.transport.codec ;
+
+namespace org.apache.qpid.console
+{
+ public class Util
+ {
+ static Dictionary<Type, short> ENCODINGS = new Dictionary<Type, short>() ;
+
+
+ static Util() {
+ ENCODINGS.Add(typeof(string), 7) ;
+ ENCODINGS.Add(typeof(short), 1) ;
+ //ENCODINGS.Add(typeof(int), 2) ;
+ //ENCODINGS.Add(typeof(long), 3) ;
+ ENCODINGS.Add(typeof(float), 13) ;
+ ENCODINGS.Add(typeof(QMFObject), 20) ;
+ ENCODINGS.Add(typeof(int), 17) ;
+ ENCODINGS.Add(typeof(long), 18) ;
+ ENCODINGS.Add(typeof(System.Collections.Generic.List<>), 21) ;
+ }
+
+ /**
+ * Converts type numbers to schema type names
+ */
+ public static string TypeName(short type) {
+ switch(type) {
+ //case 0: return "UNKNOWN" ;
+ case 1: return "uint8" ;
+ case 2: return "uint16" ;
+ case 3: return "uint32" ;
+ case 4: return "uint64" ;
+ case 5: return "bool" ;
+ case 6: return "short-string" ;
+ case 7: return "long-string" ;
+ case 8: return "abs-time" ;
+ case 9: return "delta-time" ;
+ case 10: return "reference" ;
+ case 11: return "boolean" ;
+ case 12: return "float" ;
+ case 13: return "double" ;
+ case 14: return "uuid" ;
+ case 15: return "field-table" ;
+ case 16: return "int8" ;
+ case 17: return "int16" ;
+ case 18: return "int32" ;
+ case 19: return "int64" ;
+ case 20: return "object" ;
+ case 21: return "list" ;
+ case 22: return "array" ;
+ }
+
+ throw new Exception(String.Format("Invalid Type Code: {0}", type)) ;
+ }
+
+ /**
+ * Converts schema numbers to schema access names
+ */
+ public static string AccessName(int type) {
+ switch(type) {
+ //case 0: return "UNKNOWN" ;
+ case 1: return "ReadCreate" ;
+ case 2: return "ReadWrite" ;
+ case 3: return "ReadOnly" ;
+ }
+
+ throw new Exception(String.Format("Invalid Access Code: {0}", type)) ;
+ }
+
+ /**
+ * Default values per schema type
+ */
+ public static object DefaultValue(short type) {
+ switch(type) {
+ //case 0: return "UNKNOWN" ;
+ case 1: return 0 ;
+ case 2: return 0 ;
+ case 3: return 0l ;
+ case 4: return 0l ;
+ case 5: return false ;
+ case 6: return "" ;
+ case 7: return "" ;
+ case 8: return 0l ;
+ case 9: return 0l ;
+ case 10: return new ObjectID() ;
+ case 11: return false ;
+ case 12: return 0f ;
+ case 13: return 0d ;
+ case 14: return new UUID(0,0) ;
+ case 15: return new Dictionary<string, object>();
+ case 16: return 0 ;
+ case 17: return 0 ;
+ case 18: return 0l ;
+ case 19: return 0l ;
+ case 20: return null ;
+ case 21: return new List<object>() ;
+ case 22: return new List<object>() ;
+ }
+
+ throw new Exception(String.Format("Invalid Type Code: {0}", type)) ;
+ }
+
+ /**
+ * Returns a QMF type based on C# object type
+ */
+ public static short QMFType(object obj) {
+ if (ENCODINGS.ContainsKey(obj.GetType())) {
+ return ENCODINGS[obj.GetType()] ;
+ } else {
+ throw new Exception (String.Format("Unkown Type of {0}", obj.GetType())) ;
+ }
+ }
+
+ /**
+ * Grabs a friendly string version of bytes.
+ */
+ public static string ByteString(byte[] bytes) {
+ return System.Text.Encoding.UTF8.GetString(bytes) ;
+ }
+
+ protected Util()
+ {
+
+ }
+ }
+}
diff --git a/qpid/dotnet/client-010/management/console/XMLUtil.cs b/qpid/dotnet/client-010/management/console/XMLUtil.cs
new file mode 100644
index 0000000000..b24ad51747
--- /dev/null
+++ b/qpid/dotnet/client-010/management/console/XMLUtil.cs
@@ -0,0 +1,127 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+
+using System;
+using System.Collections.Generic;
+using org.apache.qpid.client ;
+
+namespace org.apache.qpid.console
+{
+
+
+ public class XMLUtil
+ {
+
+ public static string CommonAttributes(SchemaVariable var) {
+ string returnString = "" ;
+ if (var.Description != null){
+ returnString = returnString + String.Format(" desc='{0}'", var.Description) ;
+ }
+
+ if (var.RefPackage != null){
+ returnString = returnString + String.Format(" refPackage='{0}'", var.RefPackage) ;
+ }
+
+ if (var.RefClass != null){
+ returnString = returnString + String.Format(" refClass='{0}'", var.RefClass) ;
+ }
+
+ if (var.Unit != null){
+ returnString = returnString + String.Format(" unit='{0}'", var.Unit) ;
+ }
+
+ if (var.Min != null){
+ returnString = returnString + String.Format(" min='{0}'", var.Min) ;
+ }
+ if (var.Max != null){
+ returnString = returnString + String.Format(" max='{0}'", var.Max) ;
+ }
+ if (var.MaxLength != null){
+ returnString = returnString + String.Format(" maxLength='{0}'", var.MaxLength) ;
+ }
+
+ return returnString ;
+ }
+
+ public static string SchemaXML(Session sess, string packageName) {
+ string returnValue = String.Format("<schema package='{0}'>\n", packageName) ;
+ foreach (ClassKey key in sess.GetClasses(packageName)) {
+ SchemaClass schema = sess.GetSchema(key) ;
+ if (schema.Kind == 1) {
+ if (schema.SuperType == null)
+ returnValue += String.Format("\t<class name='{0}' hash='{1}'>\n", key.ClassName, key.GetHashString()) ;
+ else
+ returnValue += String.Format("\t<class name='{0}' hash='{1}' extends='{2}'>\n", key.ClassName, key.GetHashString(), schema.SuperType.GetKeyString()) ;
+ foreach (SchemaProperty prop in schema.Properties) {
+ object[] attributes = new object[5] ;
+ attributes[0] = prop.Name ;
+ attributes[1] = Util.TypeName(prop.Type) ;
+ attributes[2] = Util.AccessName(prop.Access) ;
+ attributes[3] = prop.Optional ;
+ attributes[4] = XMLUtil.CommonAttributes(prop);
+ returnValue += String.Format("\t\t<property name='{0}' type='{1}' access='{2}' optional='{3}'{4}/>\n", attributes) ;
+ }
+ foreach (SchemaMethod meth in schema.Methods) {
+ returnValue += String.Format("\t\t<method name='{0}'/>\n", meth.Name) ;
+ foreach (SchemaArgument arg in meth.Arguments) {
+ object[] attributes = new object[4] ;
+ attributes[0] = arg.Name ;
+ attributes[1] = arg.Direction ;
+ attributes[2] = Util.TypeName(arg.Type) ;
+ attributes[3] = XMLUtil.CommonAttributes(arg);
+ returnValue += String.Format("\t\t\t<arg name='{0}' dir='{1}' type='{2}'{3}/>\n", attributes) ;
+ }
+ returnValue += String.Format("\t\t</method>\n") ;
+ }
+ returnValue += String.Format("\t</class>\n") ;
+ } else {
+ returnValue += String.Format("\t<event name='{0}' hash='{1}'>\n", key.ClassName, key.GetHashString()) ;
+ foreach (SchemaArgument arg in schema.Arguments) {
+ object[] attributes = new object[4] ;
+ attributes[0] = arg.Name ;
+ attributes[1] = Util.TypeName(arg.Type) ;
+ attributes[2] = XMLUtil.CommonAttributes(arg);
+ returnValue += String.Format("\t\t\t<arg name='{0}' type='{1}'{2}/>\n", attributes) ;
+ }
+ returnValue += String.Format("\t</event>\n") ;
+ }
+ }
+ returnValue += String.Format("</schema>\n") ;
+
+ return returnValue ;
+ }
+
+ public static string SchemaXML(Session sess, string[] packageNames) {
+ string returnValue = "<schemas>\n" ;
+ foreach (string package in packageNames) {
+ returnValue += XMLUtil.SchemaXML(sess, package) ;
+ returnValue += "\n" ;
+ }
+ returnValue += "</schemas>\n" ;
+ return returnValue ;
+ }
+
+ protected XMLUtil()
+ {
+ }
+ }
+}
diff --git a/qpid/dotnet/client-010/management/console/console.csproj b/qpid/dotnet/client-010/management/console/console.csproj
new file mode 100644
index 0000000000..3cc84e6073
--- /dev/null
+++ b/qpid/dotnet/client-010/management/console/console.csproj
@@ -0,0 +1,101 @@
+<?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.
+ -
+ -->
+<Project ToolsVersion="3.5" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProductVersion>9.0.30729</ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{E8D2202F-3959-4F29-AA0D-875CD37905CA}</ProjectGuid>
+ <OutputType>Library</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>Console</RootNamespace>
+ <AssemblyName>Console</AssemblyName>
+ <TargetFrameworkVersion>v2.0</TargetFrameworkVersion>
+ <FileAlignment>512</FileAlignment>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="log4net, Version=1.2.10.0, Culture=neutral, PublicKeyToken=1b44e1d426115821">
+ <SpecificVersion>False</SpecificVersion>
+ <HintPath>..\..\lib\log4net\log4net.dll</HintPath>
+ </Reference>
+ <Reference Include="System" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="AbstractConsole.cs" />
+ <Compile Include="Agent.cs" />
+ <Compile Include="Broker.cs" />
+ <Compile Include="BrokerURL.cs" />
+ <Compile Include="ClassKey.cs" />
+ <Compile Include="Console.cs" />
+ <Compile Include="MethodResult.cs" />
+ <Compile Include="ObjectID.cs" />
+ <Compile Include="QMFEvent.cs" />
+ <Compile Include="QMFObject.cs" />
+ <Compile Include="SchemaArgument.cs" />
+ <Compile Include="SchemaClass.cs" />
+ <Compile Include="SchemaMethod.cs" />
+ <Compile Include="SchemaProperty.cs" />
+ <Compile Include="SchemaStatistic.cs" />
+ <Compile Include="SchemaVariable.cs" />
+ <Compile Include="SequenceManager.cs" />
+ <Compile Include="Session.cs" />
+ <Compile Include="Util.cs" />
+ <Compile Include="XMLUtil.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\..\client\Client.csproj">
+ <Project>{B911FFD7-754F-4735-A188-218D5065BE79}</Project>
+ <Name>Client</Name>
+ </ProjectReference>
+ </ItemGroup>
+ <ItemGroup>
+ <Folder Include="Properties\" />
+ </ItemGroup>
+ <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+ <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
+ Other similar extension points exist, see Microsoft.Common.targets.
+ <Target Name="BeforeBuild">
+ </Target>
+ <Target Name="AfterBuild">
+ </Target>
+ -->
+</Project>
diff --git a/qpid/dotnet/client-010/management/console/console.sln b/qpid/dotnet/client-010/management/console/console.sln
new file mode 100644
index 0000000000..1cfc056302
--- /dev/null
+++ b/qpid/dotnet/client-010/management/console/console.sln
@@ -0,0 +1,46 @@
+
+Microsoft Visual Studio Solution File, Format Version 10.00
+# Visual Studio 2008
+
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Console", "Console.csproj", "{E8D2202F-3959-4F29-AA0D-875CD37905CA}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Client", "..\..\client\Client.csproj", "{B911FFD7-754F-4735-A188-218D5065BE79}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {E8D2202F-3959-4F29-AA0D-875CD37905CA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {E8D2202F-3959-4F29-AA0D-875CD37905CA}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {E8D2202F-3959-4F29-AA0D-875CD37905CA}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {E8D2202F-3959-4F29-AA0D-875CD37905CA}.Release|Any CPU.Build.0 = Release|Any CPU
+ {B911FFD7-754F-4735-A188-218D5065BE79}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {B911FFD7-754F-4735-A188-218D5065BE79}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {B911FFD7-754F-4735-A188-218D5065BE79}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {B911FFD7-754F-4735-A188-218D5065BE79}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/qpid/dotnet/client-010/management/console/default.build b/qpid/dotnet/client-010/management/console/default.build
new file mode 100644
index 0000000000..c71e695569
--- /dev/null
+++ b/qpid/dotnet/client-010/management/console/default.build
@@ -0,0 +1,54 @@
+<?xml version="1.0"?>
+<!--
+
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+
+-->
+
+<project name="qpid.console" default="build">
+ <!--
+ Properties that come from master build file
+ - build.dir: root directory for build
+ - build.debug: true if building debug release
+ - build.defines: variables to define during build
+ -->
+
+ <property name="build.config" value="debug" />
+ <property name="build.debug" value="true" />
+ <property name="build.defines" value="DEBUG;TRACE"/>
+ <property name="base.dir" value="${project::get-base-directory()}/../.." />
+ <property name="build.dir" value="${base.dir}/bin/${framework::get-target-framework()}/${build.config}" />
+
+
+ <target name="build">
+ <csc target="library"
+ define="${build.defines}"
+ debug="${build.debug}"
+ output="${build.dir}/${project::get-name()}.dll">
+
+ <sources>
+ <include name="***.cs" />
+ <exclude name="test/*.cs"/>
+ </sources>
+ <references>
+ <include name="${build.dir}/log4net.dll" />
+ <include name="${build.dir}/qpid.client.dll" />
+ </references>
+ </csc>
+ </target>
+</project>
diff --git a/qpid/dotnet/client-010/perftest/PerfTest.cs b/qpid/dotnet/client-010/perftest/PerfTest.cs
new file mode 100644
index 0000000000..c94dd865d5
--- /dev/null
+++ b/qpid/dotnet/client-010/perftest/PerfTest.cs
@@ -0,0 +1,715 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Text;
+using System.Threading;
+using common.org.apache.qpid.transport.util;
+using org.apache.qpid.client;
+using org.apache.qpid.transport;
+using org.apache.qpid.transport.util;
+using Plossum.CommandLine;
+
+namespace PerfTest
+{
+ [CommandLineManager(ApplicationName = "Qpid Perf Tests", Copyright = "Apache Software Foundation")]
+ public class Options
+ {
+ [CommandLineOption(Description = "Displays this help text")]
+ public bool Help;
+
+ [CommandLineOption(Description = "Create shared queues.", MinOccurs = 0)]
+ public Boolean Setup;
+
+ [CommandLineOption(Description = "Run test, print report.", MinOccurs = 0)]
+ public Boolean Control;
+
+ [CommandLineOption(Description = "Publish messages.", MinOccurs = 0)]
+ public Boolean Publish;
+
+ [CommandLineOption(Description = "Subscribe for messages.", MinOccurs = 0)]
+ public Boolean Subscribe;
+
+ [CommandLineOption(Description = "Test mode: [shared|fanout|topic]", MinOccurs = 0)]
+ public string Mode
+ {
+ get { return _mMode; }
+ set
+ {
+ if (! value.Equals("shared") && ! value.Equals("fanout") && ! value.Equals("topic"))
+ throw new InvalidOptionValueException(
+ "The mode must not be shared|fanout|topic", false);
+ _mMode = value;
+ }
+ }
+
+ private string _mMode = "shared";
+
+ [CommandLineOption(Description = "Specifies the broler name", MinOccurs = 0)]
+ public string Broker
+ {
+ get { return _broker; }
+ set
+ {
+ if (String.IsNullOrEmpty(value))
+ throw new InvalidOptionValueException(
+ "The broker name must not be empty", false);
+ _broker = value;
+ }
+ }
+
+ private string _broker = "localhost";
+
+ [CommandLineOption(Description = "Specifies the port name", MinOccurs = 0)]
+ public int Port
+ {
+ get { return _port; }
+ set { _port = value; }
+ }
+
+ private int _port = 5672;
+
+ #region Publisher
+
+ [CommandLineOption(Description = "Create N publishers.", MinOccurs = 0)]
+ public int Pubs
+ {
+ get { return _pubs; }
+ set { _pubs = value; }
+ }
+
+ private int _pubs = 1;
+
+ [CommandLineOption(Description = "Each publisher sends N messages.", MinOccurs = 0)]
+ public double Count
+ {
+ get { return _count; }
+ set { _count = value; }
+ }
+
+ private double _count = 5000;
+
+ [CommandLineOption(Description = "Size of messages in bytes.", MinOccurs = 0)]
+ public long Size
+ {
+ get { return _size; }
+ set { _size = value; }
+ }
+
+ private long _size = 1024;
+
+ [CommandLineOption(Description = "Publisher use confirm-mode.", MinOccurs = 0)]
+ public Boolean Confirm = true;
+
+ [CommandLineOption(Description = "Publish messages as durable.", MinOccurs = 0)]
+ public Boolean Durable;
+
+ [CommandLineOption(Description = "Make data for each message unique.", MinOccurs = 0)]
+ public Boolean UniqueData;
+
+ [CommandLineOption(Description = "Wait for confirmation of each message before sending the next one.",
+ MinOccurs = 0)]
+ public Boolean SyncPub;
+
+ [CommandLineOption(Description = ">=0 delay between msg publish.", MinOccurs = 0)]
+ public double IntervalPub
+ {
+ get { return _interval_pub; }
+ set { _interval_pub = value; }
+ }
+
+ private double _interval_pub;
+
+ #endregion
+
+ #region Subscriber
+
+ [CommandLineOption(Description = "Create N subscribers.", MinOccurs = 0)]
+ public int Subs
+ {
+ get { return _subs; }
+ set { _subs = value; }
+ }
+
+ private int _subs = 1;
+
+ [CommandLineOption(Description = "N>0: Subscriber acks batches of N.\n N==0: Subscriber uses unconfirmed mode",
+ MinOccurs = 0)]
+ public int SubAck
+ {
+ get { return _suback; }
+ set { _suback = value; }
+ }
+
+ private int _suback;
+
+ [CommandLineOption(Description = ">=0 delay between msg consume", MinOccurs = 0)]
+ public double IntervalSub
+ {
+ get { return _interval_sub; }
+ set { _interval_sub = value; }
+ }
+
+ private double _interval_sub;
+
+ #endregion
+
+ [CommandLineOption(Description = "Create N queues.", MinOccurs = 0)]
+ public int Queues
+ {
+ get { return _qt; }
+ set { _qt = value; }
+ }
+
+ private int _qt = 1;
+
+ [CommandLineOption(Description = "Desired number of iterations of the test.", MinOccurs = 0)]
+ public int Iterations
+ {
+ get { return _iterations; }
+ set { _iterations = value; }
+ }
+
+ private int _iterations = 1;
+
+ [CommandLineOption(Description = "If non-zero, the transaction batch size.", MinOccurs = 0)]
+ public int Tx
+ {
+ get { return _tx; }
+ set { _tx = value; }
+ }
+
+ private int _tx;
+
+ [CommandLineOption(Description = "Make queue durable (implied if durable set.", MinOccurs = 0)]
+ public Boolean QueueDurable;
+
+ [CommandLineOption(Description = "Queue policy: count to trigger 'flow to disk'", MinOccurs = 0)]
+ public double QueueMaxCount
+ {
+ get { return _queueMaxCount; }
+ set { _queueMaxCount = value; }
+ }
+
+ private double _queueMaxCount;
+
+ [CommandLineOption(Description = "Queue policy: accumulated size to trigger 'flow to disk'", MinOccurs = 0)]
+ public double QueueMaxSize
+ {
+ get { return _queueMaxSize; }
+ set { _queueMaxSize = value; }
+ }
+
+ private double _queueMaxSize;
+
+ public double SubQuota
+ {
+ get { return _subQuota; }
+ set { _subQuota = value; }
+ }
+
+ private double _subQuota;
+ }
+
+ internal interface Startable
+ {
+ void Start();
+ }
+
+ public abstract class PerfTestClient : Startable
+ {
+ private readonly IClient _connection;
+ private readonly IClientSession _session;
+ private readonly Options _options;
+
+ public IClientSession Session
+ {
+ get { return _session; }
+ }
+
+ public Options Options
+ {
+ get { return _options; }
+ }
+
+ protected PerfTestClient(Options options)
+ {
+ _options = options;
+ _connection = new Client();
+ _connection.Connect(options.Broker, options.Port, "test", "guest", "guest");
+ _session = _connection.CreateSession(50000);
+ }
+
+ public abstract void Start();
+ }
+
+ public class SetupTest : PerfTestClient
+ {
+ public SetupTest(Options options)
+ : base(options)
+ {
+ }
+
+ private void queueInit(String name, Boolean durable, Dictionary<String, Object> arguments)
+ {
+ Session.QueueDeclare(name, null, arguments, durable ? Option.DURABLE : Option.NONE);
+ Session.QueuePurge(name);
+ Session.ExchangeBind(name, "amq.direct", name);
+ Session.Sync();
+ }
+
+ public override void Start()
+ {
+ queueInit("pub_start", false, null);
+ queueInit("pub_done", false, null);
+ queueInit("sub_ready", false, null);
+ queueInit("sub_done", false, null);
+ if (Options.Mode.Equals("shared"))
+ {
+ Dictionary<String, Object> settings = new Dictionary<string, object>();
+ if (Options.QueueMaxCount > 0)
+ settings.Add("qpid.max_count", Options.QueueMaxCount);
+ if (Options.QueueMaxSize > 0)
+ settings.Add("qpid.max_size", Options.QueueMaxSize);
+ for (int i = 0; i < Options.Queues; ++i)
+ {
+ string qname = "perftest" + i;
+ queueInit(qname, Options.Durable || Options.QueueDurable, settings);
+ }
+ }
+ }
+ }
+
+ public class SubscribeThread : PerfTestClient
+ {
+ private readonly string _queue;
+
+ public SubscribeThread(Options options, string key, string exchange)
+ : base(options)
+ {
+ _queue = "perftest" + (new UUID(10, 10));
+ Session.QueueDeclare(_queue, null, null, Option.EXCLUSIVE, Option.AUTO_DELETE,
+ Options.Durable ? Option.DURABLE : Option.NONE);
+ Session.ExchangeBind(_queue, exchange, key);
+ }
+
+ public SubscribeThread(Options options, string key)
+ : base(options)
+ {
+ _queue = key;
+ }
+
+ public override void Start()
+ {
+ if (Options.Tx > 0)
+ {
+ Session.TxSelect();
+ Session.Sync();
+ }
+ CircularBuffer<IMessage> buffer = new CircularBuffer<IMessage>(100);
+ // Create a listener and subscribe it to the queue named "message_queue"
+ IMessageListener listener = new SyncListener(buffer);
+
+ string dest = "dest" + UUID.RandomUuid();
+ Session.AttachMessageListener(listener, dest);
+ Session.MessageSubscribe(_queue, dest,
+ Options.Tx > 0 || Options.SubAck > 0
+ ? MessageAcceptMode.EXPLICIT
+ : MessageAcceptMode.NONE,
+ MessageAcquireMode.PRE_ACQUIRED, null, 0, null);
+ // issue credits
+ Session.MessageSetFlowMode(dest, MessageFlowMode.WINDOW);
+ Session.MessageFlow(dest, MessageCreditUnit.BYTE, ClientSession.MESSAGE_FLOW_MAX_BYTES);
+
+ // Notify controller we are ready.
+ IMessage message = new Message();
+ message.DeliveryProperties.SetRoutingKey("sub_ready");
+
+ message.AppendData(Encoding.UTF8.GetBytes("ready"));
+ Session.MessageTransfer("amq.direct", message);
+
+ if (Options.Tx > 0)
+ {
+ Session.TxCommit();
+ Session.Sync();
+ }
+
+
+ for (int j = 0; j < Options.Iterations; ++j)
+ {
+
+ //need to allocate some more credit
+ Session.MessageFlow(dest, MessageCreditUnit.MESSAGE, (long)Options.SubQuota);
+
+ RangeSet range = new RangeSet();
+ IMessage msg;
+ DateTime start = DateTime.Now;
+ for (long i = 0; i < Options.SubQuota; ++i)
+ {
+ msg = buffer.Dequeue();
+ if (Options.Tx > 0 && ((i + 1)%Options.Tx == 0))
+ {
+ Session.TxCommit();
+ Session.Sync();
+ }
+ if (Options.IntervalSub > 0)
+ {
+ Thread.Sleep((int) Options.IntervalSub*1000);
+ }
+ range.Add(msg.Id);
+ }
+ if (Options.Tx > 0 || Options.SubAck > 0)
+ Session.MessageAccept(range);
+ range.Clear();
+ if (Options.Tx > 0)
+ {
+ Session.TxSelect();
+ Session.Sync();
+ }
+ DateTime end = DateTime.Now;
+
+ // Report to publisher.
+ message.DeliveryProperties.SetRoutingKey("sub_done");
+ message.ClearData();
+ message.AppendData(BitConverter.GetBytes(Options.SubQuota / end.Subtract(start).TotalMilliseconds ));
+ Session.MessageTransfer("amq.direct", message);
+ if (Options.Tx > 0)
+ {
+ Session.TxSelect();
+ Session.Sync();
+ }
+ }
+ Session.Close();
+ }
+ }
+
+ public class SyncListener : IMessageListener
+ {
+ private readonly CircularBuffer<IMessage> _buffer;
+
+ public SyncListener(CircularBuffer<IMessage> buffer)
+ {
+ _buffer = buffer;
+ }
+
+ public void MessageTransfer(IMessage m)
+ {
+ _buffer.Enqueue(m);
+ }
+ }
+
+
+ public class PublishThread : PerfTestClient
+ {
+ private readonly string _exchange;
+ private readonly string _key;
+
+ public PublishThread(Options options, string key, string exchange)
+ : base(options)
+ {
+ _key = key;
+ _exchange = exchange;
+ }
+
+
+ public override void Start()
+ {
+ byte[] data = new byte[Options.Size];
+ // randomly populate data
+ Random r = new Random(34);
+ r.NextBytes(data);
+ IMessage message = new Message();
+ message.AppendData(data);
+
+ message.DeliveryProperties.SetRoutingKey(_key);
+
+ if (Options.Durable)
+ message.DeliveryProperties.SetDeliveryMode(MessageDeliveryMode.PERSISTENT);
+
+ if (Options.Tx > 0)
+ {
+ Session.TxSelect();
+ Session.Sync();
+ }
+
+ CircularBuffer<IMessage> buffer = new CircularBuffer<IMessage>(100);
+ // Create a listener and subscribe it to the queue named "pub_start"
+ IMessageListener listener = new SyncListener(buffer);
+ string localQueue = "localQueue-" + UUID.RandomUuid().ToString();
+ Session.QueueDeclare(localQueue, null, null, Option.AUTO_DELETE);
+ Session.ExchangeBind(localQueue, "amq.direct", "pub_start");
+ Session.AttachMessageListener(listener, localQueue);
+ Session.MessageSubscribe(localQueue);
+ if (Options.Tx > 0)
+ {
+ Session.TxCommit();
+ Session.Sync();
+ }
+ buffer.Dequeue();
+
+ for (int j = 0; j < Options.Iterations; ++j)
+ {
+ DateTime start = DateTime.Now;
+ for (long i = 0; i < Options.Count; ++i)
+ {
+ Session.MessageTransfer(_exchange, message);
+
+ if (Options.SyncPub)
+ {
+ Session.Sync();
+ }
+ if (Options.Tx > 0 && (i + 1)%Options.Tx == 0)
+ {
+ Session.TxSelect();
+ Session.Sync();
+ }
+ if (Options.IntervalPub > 0)
+ {
+ Thread.Sleep((int) Options.IntervalSub*1000);
+ }
+ }
+ Session.Sync();
+ DateTime end = DateTime.Now;
+
+ // Report to publisher.
+ message.DeliveryProperties.SetRoutingKey("pub_done");
+ message.ClearData();
+ double time = end.Subtract(start).TotalMilliseconds;
+ byte[] rate = BitConverter.GetBytes( Options.Count / time );
+ message.AppendData(rate);
+ Session.MessageTransfer("amq.direct", message);
+ if (Options.Tx > 0)
+ {
+ Session.TxSelect();
+ Session.Sync();
+ }
+ }
+ Session.Close();
+ }
+ }
+
+ public class Controller : PerfTestClient
+ {
+ public Controller(Options options)
+ : base(options)
+ {
+ }
+
+ private void process(int size, string queue)
+ {
+ CircularBuffer<IMessage> buffer = new CircularBuffer<IMessage>(100);
+ IMessageListener listener = new SyncListener(buffer);
+ string localQueue = "queue-" + UUID.RandomUuid();
+ Session.QueueDeclare(localQueue, null, null, Option.AUTO_DELETE);
+ Session.ExchangeBind(localQueue, "amq.direct", queue);
+ Session.AttachMessageListener(listener, localQueue);
+ Session.MessageSubscribe(localQueue);
+ for (int i = 0; i < size; ++i)
+ {
+ buffer.Dequeue();
+ }
+ }
+
+ private double processRate(int size, string queue)
+ {
+ CircularBuffer<IMessage> buffer = new CircularBuffer<IMessage>(100);
+ IMessageListener listener = new SyncListener(buffer);
+ string localQueue = "queue-" + UUID.RandomUuid();
+ Session.QueueDeclare(localQueue, null, null, Option.AUTO_DELETE);
+ Session.ExchangeBind(localQueue, "amq.direct", queue);
+ Session.AttachMessageListener(listener, localQueue);
+ Session.MessageSubscribe(localQueue);
+ double rate = 0;
+ RangeSet range = new RangeSet();
+ for (int i = 0; i < size; ++i)
+ {
+ IMessage m = buffer.Dequeue();
+ range.Add(m.Id);
+ BinaryReader reader = new BinaryReader(m.Body, Encoding.UTF8);
+ byte[] body = new byte[m.Body.Length - m.Body.Position];
+ reader.Read(body, 0, body.Length);
+ rate += BitConverter.ToDouble(body,0);
+ }
+ Session.MessageAccept(range);
+ return rate;
+ }
+
+ private void send(int size, string queue, string data)
+ {
+ IMessage message = new Message();
+ message.DeliveryProperties.SetRoutingKey(queue);
+ message.AppendData(Encoding.UTF8.GetBytes(data));
+ for (int i = 0; i < size; ++i)
+ {
+ Session.MessageTransfer("amq.direct", message);
+ }
+ }
+
+ public override void Start()
+ {
+ process(Options.Subs, "sub_ready");
+ for (int j = 0; j < Options.Iterations; ++j)
+ {
+ DateTime start = DateTime.Now;
+ send(Options.Pubs, "pub_start", "start"); // Start publishers
+ double pubrate = processRate(Options.Pubs, "pub_done");
+ double subrate = processRate(Options.Subs, "sub_done");
+ DateTime end = DateTime.Now;
+
+ double transfers = (Options.Pubs*Options.Count) + (Options.Subs*Options.SubQuota);
+ double time = end.Subtract(start).TotalSeconds;
+ double txrate = transfers/time;
+ double mbytes = (txrate*Options.Size) / (1024 * 1024) ;
+
+ Console.WriteLine("Total: " + transfers + " transfers of " + Options.Size + " bytes in "
+ + time + " seconds.\n" +
+ "Publish transfers/sec: " + pubrate * 1000 + "\n" +
+ "Subscribe transfers/sec: " + subrate * 1000 + "\n" +
+ "Total transfers/sec: " + txrate + "\n" +
+ "Total Mbytes/sec: " + mbytes);
+ Console.WriteLine("done");
+ }
+
+ }
+ }
+
+
+ public class PerfTest
+ {
+ private static int Main(string[] args)
+ {
+ Options options = new Options();
+ CommandLineParser parser = new CommandLineParser(options);
+ parser.Parse();
+ if (parser.HasErrors)
+ {
+ Console.WriteLine(parser.UsageInfo.GetErrorsAsString(78));
+ return -1;
+ }
+ if (options.Help)
+ {
+ Console.WriteLine(parser.UsageInfo.GetOptionsAsString(78));
+ return 0;
+ }
+ bool singleProcess =
+ (!options.Setup && !options.Control && !options.Publish && !options.Subscribe);
+ if (singleProcess)
+ {
+ options.Setup = options.Control = options.Publish = true;
+ options.Subscribe = true;
+ }
+
+
+ string exchange = "amq.direct";
+ switch (options.Mode)
+ {
+ case "shared":
+ options.SubQuota = (options.Pubs*options.Count)/options.Subs;
+ break;
+ case "fanout":
+ options.SubQuota = (options.Pubs*options.Count);
+ exchange = "amq.fanout";
+ break;
+ case "topic":
+ options.SubQuota = (options.Pubs*options.Count);
+ exchange = "amq.topic";
+ break;
+ }
+
+ if (options.Setup)
+ {
+ SetupTest setup = new SetupTest(options);
+ setup.Start(); // Set up queues
+ }
+
+ Thread contT = null;
+ if ( options.Control)
+ {
+ Controller c = new Controller(options);
+ contT = new Thread(c.Start);
+ contT.Start();
+ }
+
+ Thread[] publishers = null;
+ Thread[] subscribers = null;
+
+ // Start pubs/subs for each queue/topic.
+ for (int i = 0; i < options.Queues; ++i)
+ {
+ string key = "perftest" + i; // Queue or topic name.
+ if (options.Publish)
+ {
+ int n = singleProcess ? options.Pubs : 1;
+ publishers = new Thread[n];
+ for (int j = 0; j < n; ++j)
+ {
+ PublishThread pt = new PublishThread(options, key, exchange);
+ publishers[i] = new Thread(pt.Start);
+ publishers[i].Start();
+ }
+ }
+ if ( options.Subscribe)
+ {
+ int n = singleProcess ? options.Subs : 1;
+ subscribers = new Thread[n];
+ for (int j = 0; j < n; ++j)
+ {
+ SubscribeThread st;
+ if (options.Mode.Equals("shared"))
+ st = new SubscribeThread(options, key);
+ else
+ st = new SubscribeThread(options, key, exchange);
+ subscribers[i] = new Thread(st.Start);
+ subscribers[i].Start();
+ }
+ }
+ }
+
+ if (options.Control)
+ {
+ contT.Join();
+ }
+
+
+ // Wait for started threads.
+ if (options.Publish)
+ {
+ foreach (Thread t in publishers)
+ {
+ t.Join();
+ }
+ }
+
+ if (options.Subscribe)
+ {
+ foreach (Thread t in subscribers)
+ {
+ t.Join();
+ }
+ }
+
+
+ return 0;
+ }
+ }
+}
diff --git a/qpid/dotnet/client-010/perftest/Properties/AssemblyInfo.cs b/qpid/dotnet/client-010/perftest/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000000..415ad1f1ae
--- /dev/null
+++ b/qpid/dotnet/client-010/perftest/Properties/AssemblyInfo.cs
@@ -0,0 +1,54 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("perftest")]
+[assembly: AssemblyDescription("Built from svn revision number: ")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Apache Software Foundation")]
+[assembly: AssemblyProduct("perftest")]
+[assembly: AssemblyCopyright("Apache Software Foundation")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("11b542db-0d57-4a67-8b92-24ac1d4ed4cf")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+[assembly: AssemblyVersion("0.5.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/qpid/dotnet/client-010/perftest/README.txt b/qpid/dotnet/client-010/perftest/README.txt
new file mode 100644
index 0000000000..1c920a30b6
--- /dev/null
+++ b/qpid/dotnet/client-010/perftest/README.txt
@@ -0,0 +1,38 @@
+There are two ways to use perftest:
+- single process:
+If none of the -Setup, -Publish, -Subscribe or -Control options are given perftest will run a single-process test.
+- multi-process:
+For a multi-process test first run:
+Perftest.exe -Setup <other options>
+and wait for it to complete. The remaining process should run concurrently:
+Run -Pubs times: Perftest.exe -Publish <other options>
+Run -Subs times: Perftest.exe -Subscribe <other options>
+Run once: Perftest.exe -Control <other options>
+Note the <other options> must be identical for all processes.
+
+Options:
+ -Broker Specifies the broler name
+ -Confirm Publisher use confirm-mode.
+ -Control Run test, print report.
+ -Count Each publisher sends N messages.
+ -Durable Publish messages as durable.
+ -Help Displays this help text
+ -IntervalPub >=0 delay between msg publish.
+ -IntervalSub >=0 delay between msg consume
+ -Iterations Desired number of iterations of the test.
+ -Mode Test mode: [shared|fanout|topic]
+ -Port Specifies the port name
+ -Publish Publish messages.
+ -Pubs Create N publishers.
+ -QueueDurable Make queue durable (implied if durable set.
+ -QueueMaxCount Queue policy: count to trigger 'flow to disk'
+ -QueueMaxSize Queue policy: accumulated size to trigger 'flow to disk'
+ -Queues Create N queues.
+ -Setup Create shared queues.
+ -Size Size of messages in bytes.
+ -SubAck N>0: Subscriber acks batches of N. N==0: Subscriber uses unconfirmed mode
+ -Subs Create N subscribers.
+ -Subscribe Subscribe for messages.
+ -SyncPub Wait for confirmation of each message before sending the next one.
+ -Tx If non-zero, the transaction batch size.
+ -UniqueData Make data for each message unique. \ No newline at end of file
diff --git a/qpid/dotnet/client-010/perftest/default.build b/qpid/dotnet/client-010/perftest/default.build
new file mode 100644
index 0000000000..756f6c6493
--- /dev/null
+++ b/qpid/dotnet/client-010/perftest/default.build
@@ -0,0 +1,50 @@
+<?xml version="1.0"?>
+<!--
+
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+
+-->
+
+<project name="perftest" default="build">
+ <!--
+ Properties that come from master build file
+ - build.dir: root directory for build
+ - build.debug: true if building debug release
+ - build.defines: variables to define during build
+ -->
+
+ <target name="build">
+ <csc target="exe"
+ define="${build.defines}"
+ debug="${build.debug}"
+ output="${build.dir}/${project::get-name()}.exe">
+
+ <sources>
+ <include name="**/*.cs" />
+ </sources>
+ <references>
+ <include name="${build.dir}/log4net.dll" />
+ <include name="${build.dir}/qpid.client.dll" />
+ <include name="${build.dir}/C5.dll" />
+ <include name="${build.dir}/Plossum CommandLine.dll" />
+ </references>
+ </csc>
+ </target>
+
+</project>
+
diff --git a/qpid/dotnet/client-010/perftest/perftest.csproj b/qpid/dotnet/client-010/perftest/perftest.csproj
new file mode 100644
index 0000000000..90136f18bb
--- /dev/null
+++ b/qpid/dotnet/client-010/perftest/perftest.csproj
@@ -0,0 +1,92 @@
+<?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.
+ -
+ -->
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProductVersion>9.0.30729</ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{7F7E8DE7-FDF2-4A52-A4CE-D3756B05273C}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>perftest</RootNamespace>
+ <AssemblyName>perftest</AssemblyName>
+ <FileUpgradeFlags>
+ </FileUpgradeFlags>
+ <OldToolsVersion>2.0</OldToolsVersion>
+ <UpgradeBackupLocation>
+ </UpgradeBackupLocation>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="C5, Version=1.0.2.0, Culture=neutral, PublicKeyToken=06a1b38866503b69, processorArchitecture=MSIL">
+ <SpecificVersion>False</SpecificVersion>
+ <HintPath>..\lib\plossum\C5.dll</HintPath>
+ </Reference>
+ <Reference Include="Plossum CommandLine, Version=0.3.0.14, Culture=neutral, processorArchitecture=MSIL">
+ <SpecificVersion>False</SpecificVersion>
+ <HintPath>..\lib\plossum\Plossum CommandLine.dll</HintPath>
+ </Reference>
+ <Reference Include="System" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="PerfTest.cs" />
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\client\Client.csproj">
+ <Project>{B911FFD7-754F-4735-A188-218D5065BE79}</Project>
+ <Name>Client</Name>
+ </ProjectReference>
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="..\App.config">
+ <Link>App.config</Link>
+ </None>
+ </ItemGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+ <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
+ Other similar extension points exist, see Microsoft.Common.targets.
+ <Target Name="BeforeBuild">
+ </Target>
+ <Target Name="AfterBuild">
+ </Target>
+ -->
+</Project>
diff --git a/qpid/dotnet/client-010/test/Helpers/ConfigHelpers.cs b/qpid/dotnet/client-010/test/Helpers/ConfigHelpers.cs
new file mode 100644
index 0000000000..883e52c264
--- /dev/null
+++ b/qpid/dotnet/client-010/test/Helpers/ConfigHelpers.cs
@@ -0,0 +1,65 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Text;
+using System.Xml;
+using log4net.Config;
+
+namespace test.Helpers
+{
+ class ConfigHelpers
+ {
+ public static Dictionary<string, string> LoadConfig()
+ {
+ Dictionary<string, string> properties = new Dictionary<string, string>();
+
+ XmlConfigurator.Configure(new FileInfo("/log.xml"));
+ // populate default properties
+ properties.Add("Username", "guest");
+ properties.Add("Password", "guest");
+ properties.Add("Host", "localhost");
+ properties.Add("Port", "5672");
+ properties.Add("VirtualHost", "test");
+ //Read the test config file
+ XmlTextReader reader = new XmlTextReader(Environment.CurrentDirectory + "/Qpid Test.dll.config");
+ while (reader.Read())
+ {
+ // if node type is an element
+ if (reader.NodeType == XmlNodeType.Element && reader.Name.Equals("add"))
+ {
+ if (properties.ContainsKey(reader.GetAttribute("key")))
+ {
+ properties[reader.GetAttribute("key")] = reader.GetAttribute("value");
+ }
+ else
+ {
+ properties.Add(reader.GetAttribute("key"), reader.GetAttribute("value"));
+ }
+ }
+ }
+
+ return properties;
+ }
+ }
+}
diff --git a/qpid/dotnet/client-010/test/Properties/AssemblyInfo.cs b/qpid/dotnet/client-010/test/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000000..871d450240
--- /dev/null
+++ b/qpid/dotnet/client-010/test/Properties/AssemblyInfo.cs
@@ -0,0 +1,56 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("Qpid Test")]
+[assembly: AssemblyDescription("Built from svn revision number: ")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Apache Software Foundation")]
+[assembly: AssemblyProduct("Qpid Test")]
+[assembly: AssemblyCopyright("Apache Software Foundation")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("3d62cb4f-4353-4eed-9669-3e1bc902081d")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Revision and Build Numbers
+// by using the '*' as shown below:
+[assembly: AssemblyVersion("0.5.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/qpid/dotnet/client-010/test/Qpid Test.dll.config b/qpid/dotnet/client-010/test/Qpid Test.dll.config
new file mode 100644
index 0000000000..2a2fb72b61
--- /dev/null
+++ b/qpid/dotnet/client-010/test/Qpid Test.dll.config
@@ -0,0 +1,31 @@
+<?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.
+
+-->
+
+<configuration>
+ <appSettings>
+ <add key="UserMame" value="guest"/>
+ <add key="Password" value="guest"/>
+ <add key="Host" value="localhost"/>
+ <add key="Port" value="5672"/>
+ <add key="VirtualHost" value="test"/>
+ </appSettings>
+</configuration>
diff --git a/qpid/dotnet/client-010/test/Test.csproj b/qpid/dotnet/client-010/test/Test.csproj
new file mode 100644
index 0000000000..a9cd7c18af
--- /dev/null
+++ b/qpid/dotnet/client-010/test/Test.csproj
@@ -0,0 +1,102 @@
+<?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.
+ -
+ -->
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProductVersion>9.0.30729</ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{95CB4C90-7C53-44A9-B11C-96235F158ACA}</ProjectGuid>
+ <OutputType>Library</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>test</RootNamespace>
+ <AssemblyName>Qpid Test</AssemblyName>
+ <FileUpgradeFlags>
+ </FileUpgradeFlags>
+ <OldToolsVersion>2.0</OldToolsVersion>
+ <UpgradeBackupLocation>
+ </UpgradeBackupLocation>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="log4net, Version=1.2.10.0, Culture=neutral, PublicKeyToken=1b44e1d426115821">
+ <SpecificVersion>False</SpecificVersion>
+ <HintPath>..\lib\log4net\log4net.dll</HintPath>
+ </Reference>
+ <Reference Include="nunit.framework, Version=2.2.8.0, Culture=neutral, PublicKeyToken=96d09a1eb7f44a77">
+ <SpecificVersion>False</SpecificVersion>
+ <HintPath>..\lib\nunit\nunit.framework.dll</HintPath>
+ </Reference>
+ <Reference Include="System" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="interop\ConnectionTests.cs" />
+ <Compile Include="Helpers\ConfigHelpers.cs" />
+ <Compile Include="interop\Admin.cs" />
+ <Compile Include="interop\ApplicationHeaders.cs" />
+ <Compile Include="interop\Message.cs" />
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ <Compile Include="interop\TestCase.cs" />
+ <Compile Include="transport\util\ByteEncoderTest.cs" />
+ <Compile Include="transport\util\CircularBufferTest.cs" />
+ <Compile Include="transport\util\ResultFutureTest.cs" />
+ <Compile Include="transport\util\SerialTest.cs" />
+ <Compile Include="transport\util\UUIDTest.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\client\Client.csproj">
+ <Project>{B911FFD7-754F-4735-A188-218D5065BE79}</Project>
+ <Name>Client</Name>
+ </ProjectReference>
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="..\App.config">
+ <Link>App.config</Link>
+ </None>
+ </ItemGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+ <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
+ Other similar extension points exist, see Microsoft.Common.targets.
+ <Target Name="BeforeBuild">
+ </Target>
+ <Target Name="AfterBuild">
+ </Target>
+ -->
+</Project> \ No newline at end of file
diff --git a/qpid/dotnet/client-010/test/default.build b/qpid/dotnet/client-010/test/default.build
new file mode 100644
index 0000000000..f9dadb174b
--- /dev/null
+++ b/qpid/dotnet/client-010/test/default.build
@@ -0,0 +1,55 @@
+<?xml version="1.0"?>
+<!--
+
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+
+-->
+
+<project name="qpid.client.tests" default="build">
+ <!--
+ Properties that come from master build file
+ - build.dir: root directory for build
+ - build.debug: true if building debug release
+ - build.defines: variables to define during build
+ -->
+
+ <target name="build">
+ <csc target="library"
+ define="${build.defines}"
+ debug="${build.debug}"
+ output="${build.dir}/${project::get-name()}.dll">
+
+ <sources>
+ <include name="**/*.cs" />
+ </sources>
+ <references>
+ <include name="${build.dir}/log4net.dll" />
+ <include name="${build.dir}/nunit.framework.dll" />
+ <include name="${build.dir}/qpid.client.dll" />
+ </references>
+ </csc>
+ </target>
+
+ <target name="test" depends="build">
+ <nunit2>
+ <formatter type="${nant.formatter}" usefile="false" />
+ <test assemblyname="${build.dir}/qpid.client.tests.dll" />
+ </nunit2>
+ </target>
+</project>
+
diff --git a/qpid/dotnet/client-010/test/interop/Admin.cs b/qpid/dotnet/client-010/test/interop/Admin.cs
new file mode 100644
index 0000000000..163e4cf49a
--- /dev/null
+++ b/qpid/dotnet/client-010/test/interop/Admin.cs
@@ -0,0 +1,90 @@
+/*
+*
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing,
+* software distributed under the License is distributed on an
+* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+* KIND, either express or implied. See the License for the
+* specific language governing permissions and limitations
+* under the License.
+*
+*/
+
+using NUnit.Framework;
+using org.apache.qpid.client;
+using org.apache.qpid.transport;
+using org.apache.qpid.transport.util;
+
+namespace test.interop
+{
+ public class Admin : TestCase
+ {
+ private static readonly Logger _log = Logger.Get(typeof(Admin));
+
+ [Test]
+ public void createSession()
+ {
+ _log.Debug("Running: CreateSession");
+ IClientSession ssn = Client.CreateSession(0);
+ ssn.Close();
+ // This test fails if an exception is thrown
+ }
+
+ [Test]
+ public void queueLifecycle()
+ {
+ _log.Debug("Running: queueLifecycle");
+ IClientSession ssn = Client.CreateSession(0);
+ ssn.QueueDeclare("queue1", null, null);
+ ssn.Sync();
+ ssn.QueueDelete("queue1");
+ ssn.Sync();
+ try
+ {
+ ssn.ExchangeBind("queue1", "amq.direct", "queue1", null);
+ ssn.Sync();
+ }
+ catch (SessionException)
+ {
+ // as expected
+ }
+ // This test fails if an exception is thrown
+ }
+
+ [Test]
+ public void exchangeCheck()
+ {
+ _log.Debug("Running: exchangeCheck");
+ IClientSession ssn = Client.CreateSession(0);
+ ExchangeQueryResult query = (ExchangeQueryResult) ssn.ExchangeQuery("amq.direct").Result;
+ Assert.IsFalse(query.GetNotFound());
+ Assert.IsTrue(query.GetDurable());
+ query = (ExchangeQueryResult)ssn.ExchangeQuery("amq.topic").Result;
+ Assert.IsFalse(query.GetNotFound());
+ Assert.IsTrue(query.GetDurable());
+ query = (ExchangeQueryResult) ssn.ExchangeQuery("foo").Result;
+ Assert.IsTrue(query.GetNotFound());
+ }
+
+ [Test]
+ public void exchangeBind()
+ {
+ _log.Debug("Running: ExchangeBind");
+ IClientSession ssn = Client.CreateSession(0);
+ ssn.QueueDeclare("queue1", null, null);
+ ssn.ExchangeBind("queue1", "amq.direct", "queue1", null);
+ // This test fails if an exception is thrown
+ }
+
+
+ }
+}
diff --git a/qpid/dotnet/client-010/test/interop/ApplicationHeaders.cs b/qpid/dotnet/client-010/test/interop/ApplicationHeaders.cs
new file mode 100644
index 0000000000..d932057fd2
--- /dev/null
+++ b/qpid/dotnet/client-010/test/interop/ApplicationHeaders.cs
@@ -0,0 +1,83 @@
+/*
+*
+* 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.
+*
+*/
+using System;
+using common.org.apache.qpid.transport.util;
+using NUnit.Framework;
+using org.apache.qpid.client;
+using org.apache.qpid.transport.util;
+
+namespace test.interop
+{
+ public class ApplicationHeaders:TestCase
+ {
+ private static readonly Logger _log = Logger.Get(typeof(ApplicationHeaders));
+
+ [Test]
+ public void setHeaders()
+ {
+ _log.Debug("Running: setHeaders");
+ IClientSession ssn = Client.CreateSession(0);
+ ssn.QueueDeclare("queue1");
+ ssn.ExchangeBind("queue1", "amq.direct", "queue1");
+ ssn.Sync();
+ CircularBuffer<IMessage> buff = new CircularBuffer<IMessage>(10);
+ SyncListener listener = new SyncListener(ssn, buff);
+ ssn.AttachMessageListener(listener, "queue1");
+ ssn.MessageSubscribe("queue1");
+
+ IMessage message = new org.apache.qpid.client.Message();
+ message.DeliveryProperties.SetRoutingKey("queue1");
+ const long someLong = 14444444;
+ message.ApplicationHeaders.Add("someLong", someLong);
+ const int someInt = 14;
+ message.ApplicationHeaders.Add("soneInt", someInt);
+ const float someFloat = 14.001F;
+ message.ApplicationHeaders.Add("soneFloat", someFloat);
+ const double someDouble = 14.5555555;
+ message.ApplicationHeaders.Add("someDouble", someDouble);
+ const byte someByte = 2;
+ message.ApplicationHeaders.Add("someByte", someByte);
+ const string someString = "someString";
+ message.ApplicationHeaders.Add("someString", someString);
+ const char someChar = 'a';
+ message.ApplicationHeaders.Add("someChar", someChar);
+ const Boolean someBoolean = true;
+ message.ApplicationHeaders.Add("someBoolean", someBoolean);
+
+ // transfer the message
+ ssn.MessageTransfer("amq.direct", message);
+
+ // get the message and check the headers
+ IMessage messageBack = buff.Dequeue();
+ Assert.IsTrue(((string) messageBack.ApplicationHeaders["someString"]).Equals(someString));
+ Assert.IsTrue(((char)messageBack.ApplicationHeaders["someChar"]).Equals(someChar));
+ Assert.IsTrue((long)messageBack.ApplicationHeaders["someLong"] == someLong);
+ Assert.IsTrue((int)messageBack.ApplicationHeaders["soneInt"] == someInt);
+ Assert.IsTrue((double)messageBack.ApplicationHeaders["someDouble"] == someDouble);
+ Assert.IsTrue((byte) messageBack.ApplicationHeaders["someByte"] == someByte);
+ Assert.IsTrue((Boolean)messageBack.ApplicationHeaders["someBoolean"]);
+ // c# has an conversion precision issue with decimal
+ Assert.IsTrue((float) messageBack.ApplicationHeaders["soneFloat"] <= someFloat);
+ float b = (float) messageBack.ApplicationHeaders["soneFloat"];
+ Assert.IsTrue(Convert.ToInt32(b) == Convert.ToInt32(someFloat));
+ }
+ }
+}
diff --git a/qpid/dotnet/client-010/test/interop/ConnectionTests.cs b/qpid/dotnet/client-010/test/interop/ConnectionTests.cs
new file mode 100644
index 0000000000..37fd0e7933
--- /dev/null
+++ b/qpid/dotnet/client-010/test/interop/ConnectionTests.cs
@@ -0,0 +1,80 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+using System;
+using System.Net.Sockets;
+using NUnit.Framework;
+using org.apache.qpid.client;
+using test.Helpers;
+
+namespace test
+{
+ [TestFixture]
+ public class ConnectionTests
+ {
+ [SetUp]
+ public void Setup()
+ {
+
+ }
+
+ [Test]
+ [ExpectedException(typeof(Exception))]
+ public void should_raise_exception_in_calling_thread_on_authentification_failure()
+ {
+ var properties = ConfigHelpers.LoadConfig();
+
+ var client = new Client();
+ client.Connect(properties["Host"], Convert.ToInt16(properties["Port"]), properties["VirtualHost"],
+ properties["Username"], "some silly password to make sure the authentification fail");
+ }
+
+ [Test]
+ [ExpectedException(typeof(Exception))]
+ public void should_raise_exception_in_calling_thread_on_authentification_failure_with_clodedListener()
+ {
+ var properties = ConfigHelpers.LoadConfig();
+
+ var client = new Client();
+ client.ClosedListener = new FakeListener();
+ client.Connect(properties["Host"], Convert.ToInt16(properties["Port"]), properties["VirtualHost"],
+ properties["Username"], "some silly password to make sure the authentification fail");
+ }
+
+ [Test]
+ public void should_not_block_on_close()
+ {
+ var properties = ConfigHelpers.LoadConfig();
+
+ var client = new Client();
+ client.Connect(properties["Host"], Convert.ToInt16(properties["Port"]), properties["VirtualHost"],
+ properties["Username"], properties["Password"]);
+ client.Close();
+ }
+ }
+
+ public class FakeListener : IClosedListener
+ {
+ public void OnClosed(ErrorCode errorCode, string reason, Exception t)
+ {
+ }
+ }
+}
diff --git a/qpid/dotnet/client-010/test/interop/Message.cs b/qpid/dotnet/client-010/test/interop/Message.cs
new file mode 100644
index 0000000000..107e69c287
--- /dev/null
+++ b/qpid/dotnet/client-010/test/interop/Message.cs
@@ -0,0 +1,180 @@
+/*
+*
+* 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.
+*
+*/
+using System;
+using System.Text;
+using System.Threading;
+using NUnit.Framework;
+using org.apache.qpid.client;
+using org.apache.qpid.transport;
+using org.apache.qpid.transport.util;
+
+namespace test.interop
+{
+ public class Message : TestCase
+ {
+ private static readonly Logger _log = Logger.Get(typeof (Message));
+
+ [Test]
+ public void sendAndPurge()
+ {
+ _log.Debug("Running: ExchangeBind");
+ IClientSession ssn = Client.CreateSession(0);
+ ssn.QueueDelete("queue1");
+ QueueQueryResult result = (QueueQueryResult) ssn.QueueQuery("queue1").Result;
+ Assert.IsNull(result.GetQueue());
+ ssn.QueueDeclare("queue1", null, null);
+ ssn.ExchangeBind("queue1", "amq.direct", "queue1", null);
+
+ for (int i = 0; i < 10; i++)
+ {
+ ssn.MessageTransfer("amq.direct", MessageAcceptMode.NONE, MessageAcquireMode.PRE_ACQUIRED,
+ new Header(new DeliveryProperties().SetRoutingKey("queue1"),
+ new MessageProperties().SetMessageId(UUID.RandomUuid())),
+ Encoding.UTF8.GetBytes("test: " + i));
+ }
+ ssn.Sync();
+ result = (QueueQueryResult) ssn.QueueQuery("queue1").Result;
+ Assert.IsTrue(result.GetMessageCount() == 10);
+ ssn.QueuePurge("queue1");
+ ssn.Sync();
+ result = (QueueQueryResult) ssn.QueueQuery("queue1").Result;
+ Assert.IsTrue(result.GetMessageCount() == 0);
+ }
+
+ [Test]
+ public void sendAndReceiveSmallMessages()
+ {
+ _log.Debug("Running: sendAndReceiveSmallMessages");
+ byte[] smallMessage = Encoding.UTF8.GetBytes("test");
+ sendAndReceive(smallMessage, 100);
+ }
+
+ [Test]
+ public void sendAndReceiveLargeMessages()
+ {
+ _log.Debug("Running: sendAndReceiveSmallMessages");
+ byte[] largeMessage = new byte[100 * 1024];
+ Random random = new Random();
+ random.NextBytes(largeMessage);
+ sendAndReceive(largeMessage, 10);
+ }
+
+ [Test]
+ public void sendAndReceiveVeryLargeMessages()
+ {
+ _log.Debug("Running: sendAndReceiveSmallMessages");
+ byte[] verylargeMessage = new byte[1000 * 1024];
+ Random random = new Random();
+ random.NextBytes(verylargeMessage);
+ sendAndReceive(verylargeMessage, 2);
+ }
+
+ private void sendAndReceive(byte[] messageBody, int count)
+ {
+ IClientSession ssn = Client.CreateSession(0);
+ ssn.Sync();
+ ssn.QueueDeclare("queue1", null, null);
+ ssn.QueueDelete("queue1");
+ QueueQueryResult result = (QueueQueryResult) ssn.QueueQuery("queue1").Result;
+ Assert.IsNull(result.GetQueue());
+ ssn.QueueDeclare("queue1", null, null);
+ ssn.ExchangeBind("queue1", "amq.direct", "queue1", null);
+ Object myLock = new Object();
+ MyListener myListener = new MyListener(myLock, count);
+ ssn.AttachMessageListener(myListener, "myDest");
+
+ ssn.MessageSubscribe("queue1", "myDest", MessageAcceptMode.EXPLICIT, MessageAcquireMode.PRE_ACQUIRED, null,
+ 0, null);
+
+
+ // issue credits
+ ssn.MessageSetFlowMode("myDest", MessageFlowMode.WINDOW);
+ ssn.MessageFlow("myDest", MessageCreditUnit.BYTE, ClientSession.MESSAGE_FLOW_MAX_BYTES);
+ ssn.MessageFlow("myDest", MessageCreditUnit.MESSAGE, 10000);
+ ssn.Sync();
+
+ for (int i = 0; i < count; i++)
+ {
+ ssn.MessageTransfer("amq.direct", MessageAcceptMode.NONE, MessageAcquireMode.PRE_ACQUIRED,
+ new Header(new DeliveryProperties().SetRoutingKey("queue1"),
+ new MessageProperties().SetMessageId(UUID.RandomUuid())),
+ messageBody);
+ }
+ ssn.Sync();
+
+ lock (myLock)
+ {
+ if (myListener.Count != 0)
+ {
+ Monitor.Wait(myLock, 10000000);
+ }
+ }
+ Assert.IsTrue(myListener.Count == 0);
+ ssn.MessageAccept(myListener.UnAck);
+ ssn.Sync();
+ // the queue should be empty
+ result = (QueueQueryResult)ssn.QueueQuery("queue1").Result;
+ Assert.IsTrue(result.GetMessageCount() == 0);
+ ssn.Close();
+ }
+
+
+
+ private class MyListener : IMessageListener
+ {
+ private static readonly Logger _log = Logger.Get(typeof (MyListener));
+ private readonly Object _wl;
+ private int _count;
+ private RangeSet _rs = new RangeSet();
+
+ public MyListener(Object wl, int count)
+ {
+ _wl = wl;
+ _count = count;
+ }
+
+ public void MessageTransfer(IMessage m)
+ {
+ byte[] body = new byte[m.Body.Length - m.Body.Position];
+ _log.Debug("Got a message of size: " + body.Length + " count = " + _count);
+ _rs.Add(m.Id);
+ lock (_wl)
+ {
+ _count--;
+ if (_count == 0)
+ {
+ Monitor.PulseAll(_wl);
+ }
+ }
+ }
+
+ public int Count
+ {
+ get { return _count; }
+ }
+
+ public RangeSet UnAck
+ {
+ get { return _rs; }
+ }
+ }
+ }
+}
diff --git a/qpid/dotnet/client-010/test/interop/TestCase.cs b/qpid/dotnet/client-010/test/interop/TestCase.cs
new file mode 100644
index 0000000000..867f082000
--- /dev/null
+++ b/qpid/dotnet/client-010/test/interop/TestCase.cs
@@ -0,0 +1,96 @@
+/*
+*
+* 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.
+*
+*/
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Threading;
+using System.Xml;
+using common.org.apache.qpid.transport.util;
+using log4net.Config;
+using NUnit.Framework;
+using org.apache.qpid.client;
+using org.apache.qpid.transport;
+using org.apache.qpid.transport.util;
+using test.Helpers;
+
+namespace test.interop
+{
+ [TestFixture]
+
+ public class TestCase
+ {
+ private readonly Dictionary<string,string> _properties = new Dictionary<string, string>();
+ private Client _client;
+
+ [TestFixtureSetUp]
+ public void Init()
+ {
+ var properties = ConfigHelpers.LoadConfig();
+ // create a client and connect to the broker
+ _client = new Client();
+ _client.Connect(properties["Host"], Convert.ToInt16(properties["Port"]), properties["VirtualHost"],
+ properties["Username"], properties["Password"]);
+
+ }
+
+ [TestFixtureTearDown]
+ public void Cleanup()
+ {
+ // Note : breaks the Resharper nunit test runner. It blocks on the Monitor.WaitAll()
+ // Certainly a problem with the threading context..
+ //_client.Close();
+ }
+
+ public Client Client
+ {
+ get{ return _client;}
+ }
+
+ public Dictionary<string,string> Properties
+ {
+ get { return _properties; }
+ }
+
+
+ public class SyncListener : IMessageListener
+ {
+ private static readonly Logger _log = Logger.Get(typeof(SyncListener));
+ private readonly CircularBuffer<IMessage> _buffer;
+ private readonly RangeSet _range = new RangeSet();
+ private readonly IClientSession _session;
+
+ public SyncListener(IClientSession session, CircularBuffer<IMessage> buffer)
+ {
+ _buffer = buffer;
+ _session = session;
+ }
+
+ public void MessageTransfer(IMessage m)
+ {
+ _range.Clear();
+ _range.Add(m.Id);
+ _session.MessageAccept(_range);
+ _buffer.Enqueue(m);
+ }
+ }
+ }
+}
diff --git a/qpid/dotnet/client-010/test/transport/util/ByteEncoderTest.cs b/qpid/dotnet/client-010/test/transport/util/ByteEncoderTest.cs
new file mode 100644
index 0000000000..f3a05f1c3c
--- /dev/null
+++ b/qpid/dotnet/client-010/test/transport/util/ByteEncoderTest.cs
@@ -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.
+*
+*/
+using System;
+using NUnit.Framework;
+using org.apache.qpid.transport.util;
+
+
+namespace test.transport.util
+{
+ [TestFixture]
+
+ public class ByteEncoderTest
+ {
+ private static readonly Logger _log = Logger.Get(typeof(ByteEncoderTest));
+
+ [Test]
+ public void GetBigEndianInt32()
+ {
+ _log.Debug("Running: GetBigEndianInt32");
+ const int anInt = -12345;
+ Int32 aNewInt = ByteEncoder.GetBigEndian(anInt);
+ Assert.IsTrue( anInt == ByteEncoder.GetBigEndian(aNewInt) );
+ }
+
+ [Test]
+ public void GetBigEndianUInt16()
+ {
+ _log.Debug("Running: GetBigEndianUInt16");
+ const UInt16 anInt = 123;
+ UInt16 aNewInt = ByteEncoder.GetBigEndian(anInt);
+ Assert.IsTrue(anInt == ByteEncoder.GetBigEndian(aNewInt));
+ }
+
+ [Test]
+ public void GetBigEndianUInt32()
+ {
+ _log.Debug("Running: GetBigEndianUInt32");
+ const UInt32 anInt = 12345;
+ UInt32 aNewInt = ByteEncoder.GetBigEndian(anInt);
+ Assert.IsTrue(anInt == ByteEncoder.GetBigEndian(aNewInt));
+ }
+
+ [Test]
+ public void GetBigEndianlong()
+ {
+ _log.Debug("Running: GetBigEndianlong");
+ const long anInt = 123456660700770;
+ long aNewInt = ByteEncoder.GetBigEndian(anInt);
+ Assert.IsTrue(anInt == ByteEncoder.GetBigEndian(aNewInt));
+ }
+
+ [Test]
+ public void GetLittleEndianInt32()
+ {
+ _log.Debug("Running: GetBigEndianInt32");
+ const int anInt = -12345;
+ Int32 aNewInt = ByteEncoder.GetLittleEndian(anInt);
+ Assert.IsTrue(anInt == ByteEncoder.GetLittleEndian(aNewInt));
+ }
+
+ [Test]
+ public void GetLittleEndianUInt16()
+ {
+ _log.Debug("Running: GetLittleEndianUInt16");
+ const UInt16 anInt = 123;
+ UInt16 aNewInt = ByteEncoder.GetLittleEndian(anInt);
+ Assert.IsTrue(anInt == ByteEncoder.GetLittleEndian(aNewInt));
+ }
+
+ [Test]
+ public void GetLittleEndianUInt32()
+ {
+ _log.Debug("Running: GetLittleEndianUInt32");
+ const UInt32 anInt = 12345;
+ UInt32 aNewInt = ByteEncoder.GetLittleEndian(anInt);
+ Assert.IsTrue(anInt == ByteEncoder.GetLittleEndian(aNewInt));
+ }
+
+ [Test]
+ public void GetLittleEndianlong()
+ {
+ _log.Debug("Running: GetLittleEndianlong");
+ const long anInt = 123456660700770;
+ long aNewInt = ByteEncoder.GetLittleEndian(anInt);
+ Assert.IsTrue(anInt == ByteEncoder.GetLittleEndian(aNewInt));
+ }
+ }
+}
diff --git a/qpid/dotnet/client-010/test/transport/util/CircularBufferTest.cs b/qpid/dotnet/client-010/test/transport/util/CircularBufferTest.cs
new file mode 100644
index 0000000000..5e39569cf8
--- /dev/null
+++ b/qpid/dotnet/client-010/test/transport/util/CircularBufferTest.cs
@@ -0,0 +1,89 @@
+/*
+*
+* 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.
+*
+*/
+
+using System;
+using System.Threading;
+using common.org.apache.qpid.transport.util;
+using NUnit.Framework;
+using org.apache.qpid.transport.util;
+
+namespace test.transport.util
+{
+ [TestFixture]
+
+ public class CircularBufferTest
+ {
+ private CircularBuffer<Object> _buf;
+ private static readonly Logger _log = Logger.Get(typeof(CircularBufferTest));
+
+ [Test]
+ public void BlockingEnqueue()
+ {
+ _log.Debug("Running: BlockingEnqueue");
+ const int size = 10;
+ _buf = new CircularBuffer<Object>(size);
+ // add size element anc check that the size +1 add blocks
+ for (int i = 1; i < size; i++ )
+ {
+ _buf.Enqueue(new object());
+ }
+ // check tha the buffer is now full
+ Thread t = new Thread(Go);
+ t.Start();
+ Thread.Sleep(100);
+ // the trhead t should block until an element is dequeued
+ Assert.IsTrue(t.ThreadState == ThreadState.WaitSleepJoin);
+ _buf.Dequeue();
+ // t should now be stopped
+ Thread.Sleep(100);
+ Assert.IsTrue(t.ThreadState == ThreadState.Stopped);
+ }
+
+ [Test]
+ public void Close()
+ {
+ _log.Debug("Running: BlockingEnqueue");
+ const int size = 10;
+ _buf = new CircularBuffer<Object>(size);
+ // add size element anc check that the size +1 add blocks
+ for (int i = 1; i < size; i++)
+ {
+ _buf.Enqueue(new object());
+ }
+ // check tha the buffer is now full
+ Thread t = new Thread(Go);
+ t.Start();
+ Thread.Sleep(1000);
+ // the trhead t should block until the buffer is closed
+ Assert.IsTrue(t.ThreadState == ThreadState.WaitSleepJoin);
+ _buf.Close();
+ Thread.Sleep(100);
+ // t should now be stopped
+ Assert.IsTrue(t.ThreadState == ThreadState.Stopped);
+ }
+
+ void Go()
+ {
+ _buf.Enqueue(new object());
+ }
+
+ }
+}
diff --git a/qpid/dotnet/client-010/test/transport/util/ResultFutureTest.cs b/qpid/dotnet/client-010/test/transport/util/ResultFutureTest.cs
new file mode 100644
index 0000000000..e8e011a1e9
--- /dev/null
+++ b/qpid/dotnet/client-010/test/transport/util/ResultFutureTest.cs
@@ -0,0 +1,103 @@
+/*
+*
+* 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.
+*
+*/
+using System;
+using System.Collections.Generic;
+using System.Threading;
+using common.org.apache.qpid.transport.util;
+using NUnit.Framework;
+using org.apache.qpid.transport;
+using org.apache.qpid.transport.codec;
+using org.apache.qpid.transport.util;
+
+
+namespace test.transport.util
+{
+ [TestFixture]
+ public class ResultFutureTest
+ {
+ private static readonly Logger _log = Logger.Get(typeof (ByteEncoderTest));
+ private static ResultFuture _future;
+
+ [Test]
+ public void getFutureTimeout()
+ {
+ _log.Debug("Running: getFutureTimeout");
+ _future = new ResultFuture();
+ _future.Session = new Session(new byte[1]);
+ DateTime start = DateTime.Now;
+ Struct result = _future.Get(1000);
+ Assert.IsTrue(DateTime.Now.Subtract(start).TotalMilliseconds >= 1000);
+ Assert.IsNull(result);
+ }
+
+ [Test]
+ public void getFuture()
+ {
+ _log.Debug("Running: getFuture");
+ _future = new ResultFuture();
+ _future.Session = new Session(new byte[1]);
+ Thread t = new Thread(Go);
+ t.Start();
+ Struct result = _future.Get(2000);
+ Assert.IsNotNull(result);
+ }
+
+
+ void Go()
+ {
+ Thread.Sleep(500);
+ _future.Result = new myStruct();
+ }
+ }
+
+ public class myStruct:Struct
+ {
+ public override int GetStructType()
+ {
+ throw new System.NotImplementedException();
+ }
+
+ public override int GetSizeWidth()
+ {
+ throw new System.NotImplementedException();
+ }
+
+ public override int GetPackWidth()
+ {
+ throw new System.NotImplementedException();
+ }
+
+ public override void Read(IDecoder dec)
+ {
+ throw new System.NotImplementedException();
+ }
+
+ public override void Write(IEncoder enc)
+ {
+ throw new System.NotImplementedException();
+ }
+
+ public override Dictionary<string, object> Fields
+ {
+ get { throw new System.NotImplementedException(); }
+ }
+ }
+}
diff --git a/qpid/dotnet/client-010/test/transport/util/SerialTest.cs b/qpid/dotnet/client-010/test/transport/util/SerialTest.cs
new file mode 100644
index 0000000000..772327c3b0
--- /dev/null
+++ b/qpid/dotnet/client-010/test/transport/util/SerialTest.cs
@@ -0,0 +1,75 @@
+/*
+*
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing,
+* software distributed under the License is distributed on an
+* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+* KIND, either express or implied. See the License for the
+* specific language governing permissions and limitations
+* under the License.
+*
+*/
+using NUnit.Framework;
+using org.apache.qpid.transport.util;
+
+namespace test.transport.util
+{
+ [TestFixture]
+ public class SerialTest
+ {
+ private static readonly Logger _log = Logger.Get(typeof (SerialTest));
+
+ [Test]
+ ///
+ /// Test the key boundaries where wraparound occurs.
+ ///
+ public void testBoundaries()
+ {
+ Assert.IsTrue(Serial.Gt(1, 0));
+ Assert.IsTrue(Serial.Lt(0, 1));
+
+ Assert.IsTrue(Serial.Gt(int.MaxValue, int.MaxValue - 1));
+ Assert.IsTrue(Serial.Lt(int.MaxValue - 1, int.MaxValue));
+ }
+
+ ///
+ /// Test the first Corollary of RFC 1982
+ /// For any sequence number s and any integer n such that addition of n
+ /// to s is well defined, (s + n) >= s. Further (s + n) == s only when
+ /// n == 0, in all other defined cases, (s + n) > s.
+ ///
+ public void testCorollary1()
+ {
+ int wrapcount = 0;
+
+ int s = 0;
+
+ for (int i = 0; i < 67108664; i++)
+ {
+ for (int n = 1; n < 4096; n += 512)
+ {
+ Assert.IsTrue(Serial.Gt(s + n, s));
+ Assert.IsTrue(Serial.Lt(s, s + n));
+ }
+
+ s += 1024;
+
+ if (s == 0)
+ {
+ wrapcount += 1;
+ }
+ }
+
+ Assert.IsTrue(wrapcount > 0);
+ }
+ }
+}
diff --git a/qpid/dotnet/client-010/test/transport/util/UUIDTest.cs b/qpid/dotnet/client-010/test/transport/util/UUIDTest.cs
new file mode 100644
index 0000000000..41104f8873
--- /dev/null
+++ b/qpid/dotnet/client-010/test/transport/util/UUIDTest.cs
@@ -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.
+*
+*/
+using System;
+using NUnit.Framework;
+using org.apache.qpid.transport.util;
+
+namespace test.transport.util
+{
+ [TestFixture]
+
+ public class UUIDTest
+ {
+
+
+ [Test]
+ public void createUUID()
+ {
+ UUID uuid = UUID.RandomUuid();
+ String uuidStr = uuid.ToString();
+ Assert.IsNotNull(uuid);
+ UUID uuid2 = UUID.RandomUuid();
+ Assert.AreNotSame(uuid, uuid2);
+ }
+
+ [Test]
+ public void ToString_should_override_and_not_hide_base()
+ {
+ UUID uuid = UUID.RandomUuid();
+
+ string uuidStr = uuid.ToString();
+ string uuidConcat = "Test." + uuid;
+
+ Assert.AreEqual("Test." + uuidStr, uuidConcat);
+ }
+
+ [Test]
+ public void two_uuid_with_same_value_should_have_same_hash_code()
+ {
+ UUID uuid = UUID.RandomUuid();
+ UUID uuid2 = new UUID(uuid.MostSignificantBits, uuid.LeastSignificantBits);
+
+ Assert.AreEqual(uuid, uuid2);
+ Assert.AreEqual(uuid.GetHashCode(), uuid2.GetHashCode());
+ }
+ }
+}
diff --git a/qpid/dotnet/client-010/wcf/Properties/AssemblyInfo.cs b/qpid/dotnet/client-010/wcf/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000000..66f2bb1268
--- /dev/null
+++ b/qpid/dotnet/client-010/wcf/Properties/AssemblyInfo.cs
@@ -0,0 +1,57 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("Qpid WCF")]
+[assembly: AssemblyDescription("Built from svn revision number: ")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Apache Software Foundation")]
+[assembly: AssemblyProduct("Qpid WCF")]
+[assembly: AssemblyCopyright("Apache Software Foundation")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("a39d56ec-7d81-48e1-9602-347a3ce6f638")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("0.5.0.0")]
+[assembly: AssemblyVersion("0.5.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/qpid/dotnet/client-010/wcf/demo/ConfigDemo.suo b/qpid/dotnet/client-010/wcf/demo/ConfigDemo.suo
new file mode 100644
index 0000000000..baa935693b
--- /dev/null
+++ b/qpid/dotnet/client-010/wcf/demo/ConfigDemo.suo
Binary files differ
diff --git a/qpid/dotnet/client-010/wcf/demo/Demo.suo b/qpid/dotnet/client-010/wcf/demo/Demo.suo
new file mode 100644
index 0000000000..ee4cb5d21e
--- /dev/null
+++ b/qpid/dotnet/client-010/wcf/demo/Demo.suo
Binary files differ
diff --git a/qpid/dotnet/client-010/wcf/demo/wcfBookingClient/Form1.Designer.cs b/qpid/dotnet/client-010/wcf/demo/wcfBookingClient/Form1.Designer.cs
new file mode 100644
index 0000000000..9ec3a08359
--- /dev/null
+++ b/qpid/dotnet/client-010/wcf/demo/wcfBookingClient/Form1.Designer.cs
@@ -0,0 +1,185 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+namespace WindowsFormsBooking
+{
+ partial class Form1
+ {
+ /// <summary>
+ /// Required designer variable.
+ /// </summary>
+ private System.ComponentModel.IContainer components = null;
+
+ /// <summary>
+ /// Clean up any resources being used.
+ /// </summary>
+ /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Windows Form Designer generated code
+
+ /// <summary>
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ /// </summary>
+ private void InitializeComponent()
+ {
+ this.comboBox1 = new System.Windows.Forms.ComboBox();
+ this.label1 = new System.Windows.Forms.Label();
+ this.numericUpDown1 = new System.Windows.Forms.NumericUpDown();
+ this.label2 = new System.Windows.Forms.Label();
+ this.button1 = new System.Windows.Forms.Button();
+ this.richTextBox1 = new System.Windows.Forms.RichTextBox();
+ this.button2 = new System.Windows.Forms.Button();
+ ((System.ComponentModel.ISupportInitialize)(this.numericUpDown1)).BeginInit();
+ this.SuspendLayout();
+ //
+ // comboBox1
+ //
+ this.comboBox1.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+ this.comboBox1.FormattingEnabled = true;
+ this.comboBox1.Items.AddRange(new object[] {
+ "Hotel",
+ "Taxi",
+ "Train",
+ "Cinema",
+ "Theater",
+ "Restaurant"});
+ this.comboBox1.Location = new System.Drawing.Point(60, 20);
+ this.comboBox1.Name = "comboBox1";
+ this.comboBox1.Size = new System.Drawing.Size(76, 21);
+ this.comboBox1.TabIndex = 0;
+ this.comboBox1.SelectedIndexChanged += new System.EventHandler(this.comboBox1_SelectedIndexChanged);
+ //
+ // label1
+ //
+ this.label1.AutoSize = true;
+ this.label1.Location = new System.Drawing.Point(23, 20);
+ this.label1.Name = "label1";
+ this.label1.Size = new System.Drawing.Size(31, 13);
+ this.label1.TabIndex = 1;
+ this.label1.Text = "Type";
+ //
+ // numericUpDown1
+ //
+ this.numericUpDown1.Increment = new decimal(new int[] {
+ 10,
+ 0,
+ 0,
+ 0});
+ this.numericUpDown1.Location = new System.Drawing.Point(60, 49);
+ this.numericUpDown1.Maximum = new decimal(new int[] {
+ 200,
+ 0,
+ 0,
+ 0});
+ this.numericUpDown1.Minimum = new decimal(new int[] {
+ 30,
+ 0,
+ 0,
+ 0});
+ this.numericUpDown1.Name = "numericUpDown1";
+ this.numericUpDown1.Size = new System.Drawing.Size(76, 20);
+ this.numericUpDown1.TabIndex = 2;
+ this.numericUpDown1.Value = new decimal(new int[] {
+ 30,
+ 0,
+ 0,
+ 0});
+ this.numericUpDown1.ValueChanged += new System.EventHandler(this.numericUpDown1_ValueChanged);
+ //
+ // label2
+ //
+ this.label2.AutoSize = true;
+ this.label2.Location = new System.Drawing.Point(23, 56);
+ this.label2.Name = "label2";
+ this.label2.Size = new System.Drawing.Size(31, 13);
+ this.label2.TabIndex = 3;
+ this.label2.Text = "Price";
+ //
+ // button1
+ //
+ this.button1.Location = new System.Drawing.Point(142, 20);
+ this.button1.Name = "button1";
+ this.button1.Size = new System.Drawing.Size(40, 49);
+ this.button1.TabIndex = 4;
+ this.button1.Text = "Add";
+ this.button1.UseVisualStyleBackColor = true;
+ this.button1.Click += new System.EventHandler(this.button1_Click);
+ //
+ // richTextBox1
+ //
+ this.richTextBox1.ForeColor = System.Drawing.SystemColors.ControlText;
+ this.richTextBox1.Location = new System.Drawing.Point(27, 113);
+ this.richTextBox1.Name = "richTextBox1";
+ this.richTextBox1.Size = new System.Drawing.Size(155, 83);
+ this.richTextBox1.TabIndex = 5;
+ this.richTextBox1.Text = "";
+ //
+ // button2
+ //
+ this.button2.Location = new System.Drawing.Point(27, 81);
+ this.button2.Name = "button2";
+ this.button2.Size = new System.Drawing.Size(155, 29);
+ this.button2.TabIndex = 6;
+ this.button2.Text = "Receipt";
+ this.button2.UseVisualStyleBackColor = true;
+ this.button2.Click += new System.EventHandler(this.button2_Click);
+ //
+ // Form1
+ //
+ this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.ClientSize = new System.Drawing.Size(211, 211);
+ this.Controls.Add(this.button2);
+ this.Controls.Add(this.richTextBox1);
+ this.Controls.Add(this.button1);
+ this.Controls.Add(this.label2);
+ this.Controls.Add(this.numericUpDown1);
+ this.Controls.Add(this.label1);
+ this.Controls.Add(this.comboBox1);
+ this.Name = "Form1";
+ this.Text = "Booking Client";
+ ((System.ComponentModel.ISupportInitialize)(this.numericUpDown1)).EndInit();
+ this.ResumeLayout(false);
+ this.PerformLayout();
+
+ }
+
+ #endregion
+
+ private System.Windows.Forms.ComboBox comboBox1;
+ private System.Windows.Forms.Label label1;
+ private System.Windows.Forms.NumericUpDown numericUpDown1;
+ private System.Windows.Forms.Label label2;
+ private System.Windows.Forms.Button button1;
+ private System.Windows.Forms.RichTextBox richTextBox1;
+ private System.Windows.Forms.Button button2;
+ }
+}
+
diff --git a/qpid/dotnet/client-010/wcf/demo/wcfBookingClient/Form1.cs b/qpid/dotnet/client-010/wcf/demo/wcfBookingClient/Form1.cs
new file mode 100644
index 0000000000..89205bd6bd
--- /dev/null
+++ b/qpid/dotnet/client-010/wcf/demo/wcfBookingClient/Form1.cs
@@ -0,0 +1,96 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+using System;
+using System.ServiceModel;
+using System.Windows.Forms;
+using org.apache.qpid.wcf.demo;
+using org.apache.qpid.wcf.model;
+using org.apache.qpid.wcf.demo.bookingServer;
+
+namespace WindowsFormsBooking
+{
+ public partial class Form1 : Form
+ {
+ private ChannelFactory<IBooking> _fac;
+ private readonly Order _order = new Order();
+ private IBooking _calc;
+
+ public Form1()
+ {
+ InitializeComponent();
+ _calc = StartClient(new QpidBinding("192.168.1.14", 5673));
+ _order.Type = "Default";
+ _order.Price = 0;
+ }
+
+ public IBooking StartClient(System.ServiceModel.Channels.Binding binding)
+ {
+ IBooking res = null;
+ try
+ {
+ Console.WriteLine(" Starting Client...");
+ _fac = new ChannelFactory<IBooking>(binding, "soap.amqp:///Booking");
+ _fac.Open();
+ res = _fac.CreateChannel();
+ Console.WriteLine("[DONE]");
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine(e);
+ }
+ return res;
+ }
+
+ public void StopClient(IBooking client)
+ {
+ Console.WriteLine(" Stopping Client...");
+ ((System.ServiceModel.Channels.IChannel)client).Close();
+ _fac.Close();
+ Console.WriteLine("[DONE]");
+ }
+
+ private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
+ {
+ _order.Type = ((ComboBox) sender).SelectedItem.ToString();
+ }
+
+ private void numericUpDown1_ValueChanged(object sender, EventArgs e)
+ {
+ _order.Price = (double) ((NumericUpDown) sender).Value;
+ }
+
+ private void button1_Click(object sender, EventArgs e)
+ {
+ _calc.Add(_order);
+ }
+
+ private void button2_Click(object sender, EventArgs e)
+ {
+ Receipt r = _calc.Checkout();
+ richTextBox1.Text = r.Summary + "\n" + "Total Price = " + r.Price;
+ // reset
+ _calc = StartClient(new QpidBinding("192.168.1.14", 5673));
+ }
+
+
+ }
+}
diff --git a/qpid/dotnet/client-010/wcf/demo/wcfBookingClient/Form1.resx b/qpid/dotnet/client-010/wcf/demo/wcfBookingClient/Form1.resx
new file mode 100644
index 0000000000..7c6a1b6a50
--- /dev/null
+++ b/qpid/dotnet/client-010/wcf/demo/wcfBookingClient/Form1.resx
@@ -0,0 +1,143 @@
+<?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.
+ -
+ -->
+<root>
+ <!--
+ Microsoft ResX Schema
+
+ Version 2.0
+
+ The primary goals of this format is to allow a simple XML format
+ that is mostly human readable. The generation and parsing of the
+ various data types are done through the TypeConverter classes
+ associated with the data types.
+
+ Example:
+
+ ... ado.net/XML headers & schema ...
+ <resheader name="resmimetype">text/microsoft-resx</resheader>
+ <resheader name="version">2.0</resheader>
+ <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+ <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+ <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+ <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+ <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+ <value>[base64 mime encoded serialized .NET Framework object]</value>
+ </data>
+ <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+ <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+ <comment>This is a comment</comment>
+ </data>
+
+ There are any number of "resheader" rows that contain simple
+ name/value pairs.
+
+ Each data row contains a name, and value. The row also contains a
+ type or mimetype. Type corresponds to a .NET class that support
+ text/value conversion through the TypeConverter architecture.
+ Classes that don't support this are serialized and stored with the
+ mimetype set.
+
+ The mimetype is used for serialized objects, and tells the
+ ResXResourceReader how to depersist the object. This is currently not
+ extensible. For a given mimetype the value must be set accordingly:
+
+ Note - application/x-microsoft.net.object.binary.base64 is the format
+ that the ResXResourceWriter will generate, however the reader can
+ read any of the formats listed below.
+
+ mimetype: application/x-microsoft.net.object.binary.base64
+ value : The object must be serialized with
+ : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
+ : and then encoded with base64 encoding.
+
+ mimetype: application/x-microsoft.net.object.soap.base64
+ value : The object must be serialized with
+ : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+ : and then encoded with base64 encoding.
+
+ mimetype: application/x-microsoft.net.object.bytearray.base64
+ value : The object must be serialized into a byte array
+ : using a System.ComponentModel.TypeConverter
+ : and then encoded with base64 encoding.
+ -->
+ <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+ <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
+ <xsd:element name="root" msdata:IsDataSet="true">
+ <xsd:complexType>
+ <xsd:choice maxOccurs="unbounded">
+ <xsd:element name="metadata">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" />
+ </xsd:sequence>
+ <xsd:attribute name="name" use="required" type="xsd:string" />
+ <xsd:attribute name="type" type="xsd:string" />
+ <xsd:attribute name="mimetype" type="xsd:string" />
+ <xsd:attribute ref="xml:space" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="assembly">
+ <xsd:complexType>
+ <xsd:attribute name="alias" type="xsd:string" />
+ <xsd:attribute name="name" type="xsd:string" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="data">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+ <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
+ <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+ <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+ <xsd:attribute ref="xml:space" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="resheader">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" use="required" />
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:choice>
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:schema>
+ <resheader name="resmimetype">
+ <value>text/microsoft-resx</value>
+ </resheader>
+ <resheader name="version">
+ <value>2.0</value>
+ </resheader>
+ <resheader name="reader">
+ <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+ </resheader>
+ <resheader name="writer">
+ <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+ </resheader>
+ <metadata name="richTextBox1.Locked" type="System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <value>True</value>
+ </metadata>
+</root> \ No newline at end of file
diff --git a/qpid/dotnet/client-010/wcf/demo/wcfBookingClient/Program.cs b/qpid/dotnet/client-010/wcf/demo/wcfBookingClient/Program.cs
new file mode 100644
index 0000000000..59189bf600
--- /dev/null
+++ b/qpid/dotnet/client-010/wcf/demo/wcfBookingClient/Program.cs
@@ -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.
+ *
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Windows.Forms;
+
+namespace WindowsFormsBooking
+{
+ static class Program
+ {
+ /// <summary>
+ /// The main entry point for the application.
+ /// </summary>
+ [STAThread]
+ static void Main()
+ {
+ Application.EnableVisualStyles();
+ Application.SetCompatibleTextRenderingDefault(false);
+ Application.Run(new Form1());
+ }
+ }
+}
diff --git a/qpid/dotnet/client-010/wcf/demo/wcfBookingClient/Properties/AssemblyInfo.cs b/qpid/dotnet/client-010/wcf/demo/wcfBookingClient/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000000..be301395d3
--- /dev/null
+++ b/qpid/dotnet/client-010/wcf/demo/wcfBookingClient/Properties/AssemblyInfo.cs
@@ -0,0 +1,57 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("Booking Client")]
+[assembly: AssemblyDescription("Built from svn revision number: ")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Apache Software Foundation")]
+[assembly: AssemblyProduct("Booking Client")]
+[assembly: AssemblyCopyright("Apache Software Foundation")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("fc8b1e0e-1ca9-46fe-9aae-b1ed046716b8")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("0.5.0.0")]
+[assembly: AssemblyVersion("0.5.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/qpid/dotnet/client-010/wcf/demo/wcfBookingClient/Properties/Resources.Designer.cs b/qpid/dotnet/client-010/wcf/demo/wcfBookingClient/Properties/Resources.Designer.cs
new file mode 100644
index 0000000000..42f9731a3d
--- /dev/null
+++ b/qpid/dotnet/client-010/wcf/demo/wcfBookingClient/Properties/Resources.Designer.cs
@@ -0,0 +1,92 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+//------------------------------------------------------------------------------
+// <auto-generated>
+// This code was generated by a tool.
+// Runtime Version:2.0.50727.1433
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace WindowsFormsBooking.Properties
+{
+
+
+ /// <summary>
+ /// A strongly-typed resource class, for looking up localized strings, etc.
+ /// </summary>
+ // This class was auto-generated by the StronglyTypedResourceBuilder
+ // class via a tool like ResGen or Visual Studio.
+ // To add or remove a member, edit your .ResX file then rerun ResGen
+ // with the /str option, or rebuild your VS project.
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "2.0.0.0")]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+ internal class Resources
+ {
+
+ private static global::System.Resources.ResourceManager resourceMan;
+
+ private static global::System.Globalization.CultureInfo resourceCulture;
+
+ [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+ internal Resources()
+ {
+ }
+
+ /// <summary>
+ /// Returns the cached ResourceManager instance used by this class.
+ /// </summary>
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ internal static global::System.Resources.ResourceManager ResourceManager
+ {
+ get
+ {
+ if ((resourceMan == null))
+ {
+ global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("WindowsFormsBooking.Properties.Resources", typeof(Resources).Assembly);
+ resourceMan = temp;
+ }
+ return resourceMan;
+ }
+ }
+
+ /// <summary>
+ /// Overrides the current thread's CurrentUICulture property for all
+ /// resource lookups using this strongly typed resource class.
+ /// </summary>
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ internal static global::System.Globalization.CultureInfo Culture
+ {
+ get
+ {
+ return resourceCulture;
+ }
+ set
+ {
+ resourceCulture = value;
+ }
+ }
+ }
+}
diff --git a/qpid/dotnet/client-010/wcf/demo/wcfBookingClient/Properties/Resources.resx b/qpid/dotnet/client-010/wcf/demo/wcfBookingClient/Properties/Resources.resx
new file mode 100644
index 0000000000..af03750170
--- /dev/null
+++ b/qpid/dotnet/client-010/wcf/demo/wcfBookingClient/Properties/Resources.resx
@@ -0,0 +1,137 @@
+<?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.
+ -
+ -->
+<root>
+ <!--
+ Microsoft ResX Schema
+
+ Version 2.0
+
+ The primary goals of this format is to allow a simple XML format
+ that is mostly human readable. The generation and parsing of the
+ various data types are done through the TypeConverter classes
+ associated with the data types.
+
+ Example:
+
+ ... ado.net/XML headers & schema ...
+ <resheader name="resmimetype">text/microsoft-resx</resheader>
+ <resheader name="version">2.0</resheader>
+ <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+ <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+ <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+ <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+ <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+ <value>[base64 mime encoded serialized .NET Framework object]</value>
+ </data>
+ <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+ <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+ <comment>This is a comment</comment>
+ </data>
+
+ There are any number of "resheader" rows that contain simple
+ name/value pairs.
+
+ Each data row contains a name, and value. The row also contains a
+ type or mimetype. Type corresponds to a .NET class that support
+ text/value conversion through the TypeConverter architecture.
+ Classes that don't support this are serialized and stored with the
+ mimetype set.
+
+ The mimetype is used for serialized objects, and tells the
+ ResXResourceReader how to depersist the object. This is currently not
+ extensible. For a given mimetype the value must be set accordingly:
+
+ Note - application/x-microsoft.net.object.binary.base64 is the format
+ that the ResXResourceWriter will generate, however the reader can
+ read any of the formats listed below.
+
+ mimetype: application/x-microsoft.net.object.binary.base64
+ value : The object must be serialized with
+ : System.Serialization.Formatters.Binary.BinaryFormatter
+ : and then encoded with base64 encoding.
+
+ mimetype: application/x-microsoft.net.object.soap.base64
+ value : The object must be serialized with
+ : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+ : and then encoded with base64 encoding.
+
+ mimetype: application/x-microsoft.net.object.bytearray.base64
+ value : The object must be serialized into a byte array
+ : using a System.ComponentModel.TypeConverter
+ : and then encoded with base64 encoding.
+ -->
+ <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+ <xsd:element name="root" msdata:IsDataSet="true">
+ <xsd:complexType>
+ <xsd:choice maxOccurs="unbounded">
+ <xsd:element name="metadata">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" />
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" />
+ <xsd:attribute name="type" type="xsd:string" />
+ <xsd:attribute name="mimetype" type="xsd:string" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="assembly">
+ <xsd:complexType>
+ <xsd:attribute name="alias" type="xsd:string" />
+ <xsd:attribute name="name" type="xsd:string" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="data">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+ <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
+ <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+ <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="resheader">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" use="required" />
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:choice>
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:schema>
+ <resheader name="resmimetype">
+ <value>text/microsoft-resx</value>
+ </resheader>
+ <resheader name="version">
+ <value>2.0</value>
+ </resheader>
+ <resheader name="reader">
+ <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+ </resheader>
+ <resheader name="writer">
+ <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+ </resheader>
+</root> \ No newline at end of file
diff --git a/qpid/dotnet/client-010/wcf/demo/wcfBookingClient/Properties/Settings.Designer.cs b/qpid/dotnet/client-010/wcf/demo/wcfBookingClient/Properties/Settings.Designer.cs
new file mode 100644
index 0000000000..212fb91438
--- /dev/null
+++ b/qpid/dotnet/client-010/wcf/demo/wcfBookingClient/Properties/Settings.Designer.cs
@@ -0,0 +1,51 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+//------------------------------------------------------------------------------
+// <auto-generated>
+// This code was generated by a tool.
+// Runtime Version:2.0.50727.1433
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace WindowsFormsBooking.Properties
+{
+
+
+ [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "9.0.0.0")]
+ internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase
+ {
+
+ private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
+
+ public static Settings Default
+ {
+ get
+ {
+ return defaultInstance;
+ }
+ }
+ }
+}
diff --git a/qpid/dotnet/client-010/wcf/demo/wcfBookingClient/Properties/Settings.settings b/qpid/dotnet/client-010/wcf/demo/wcfBookingClient/Properties/Settings.settings
new file mode 100644
index 0000000000..64cfd9241c
--- /dev/null
+++ b/qpid/dotnet/client-010/wcf/demo/wcfBookingClient/Properties/Settings.settings
@@ -0,0 +1,27 @@
+<?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.
+ -
+ -->
+<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)">
+ <Profiles>
+ <Profile Name="(Default)" />
+ </Profiles>
+ <Settings />
+</SettingsFile>
diff --git a/qpid/dotnet/client-010/wcf/demo/wcfBookingClient/wcBookingClient.csproj b/qpid/dotnet/client-010/wcf/demo/wcfBookingClient/wcBookingClient.csproj
new file mode 100644
index 0000000000..1449446ae2
--- /dev/null
+++ b/qpid/dotnet/client-010/wcf/demo/wcfBookingClient/wcBookingClient.csproj
@@ -0,0 +1,123 @@
+<?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.
+ -
+ -->
+<Project ToolsVersion="3.5" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProductVersion>9.0.30729</ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{4086B3FE-F745-4DCC-952A-682CAE01F4C9}</ProjectGuid>
+ <OutputType>WinExe</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>WindowsFormsBooking</RootNamespace>
+ <AssemblyName>Booking Client</AssemblyName>
+ <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
+ <FileAlignment>512</FileAlignment>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="System" />
+ <Reference Include="System.Core">
+ <RequiredTargetFramework>3.5</RequiredTargetFramework>
+ </Reference>
+ <Reference Include="System.ServiceModel">
+ <RequiredTargetFramework>3.0</RequiredTargetFramework>
+ </Reference>
+ <Reference Include="System.Xml.Linq">
+ <RequiredTargetFramework>3.5</RequiredTargetFramework>
+ </Reference>
+ <Reference Include="System.Data.DataSetExtensions">
+ <RequiredTargetFramework>3.5</RequiredTargetFramework>
+ </Reference>
+ <Reference Include="System.Data" />
+ <Reference Include="System.Deployment" />
+ <Reference Include="System.Drawing" />
+ <Reference Include="System.Windows.Forms" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="Form1.cs">
+ <SubType>Form</SubType>
+ </Compile>
+ <Compile Include="Form1.Designer.cs">
+ <DependentUpon>Form1.cs</DependentUpon>
+ </Compile>
+ <Compile Include="Program.cs" />
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ <EmbeddedResource Include="Form1.resx">
+ <DependentUpon>Form1.cs</DependentUpon>
+ <SubType>Designer</SubType>
+ </EmbeddedResource>
+ <EmbeddedResource Include="Properties\Resources.resx">
+ <Generator>ResXFileCodeGenerator</Generator>
+ <LastGenOutput>Resources.Designer.cs</LastGenOutput>
+ <SubType>Designer</SubType>
+ </EmbeddedResource>
+ <Compile Include="Properties\Resources.Designer.cs">
+ <AutoGen>True</AutoGen>
+ <DependentUpon>Resources.resx</DependentUpon>
+ </Compile>
+ <None Include="Properties\Settings.settings">
+ <Generator>SettingsSingleFileGenerator</Generator>
+ <LastGenOutput>Settings.Designer.cs</LastGenOutput>
+ </None>
+ <Compile Include="Properties\Settings.Designer.cs">
+ <AutoGen>True</AutoGen>
+ <DependentUpon>Settings.settings</DependentUpon>
+ <DesignTimeSharedInput>True</DesignTimeSharedInput>
+ </Compile>
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\..\wcf.csproj">
+ <Project>{F1D80D9D-FE22-4213-A760-BFFDE7D131DD}</Project>
+ <Name>wcf</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\wcfBookingServer\wcfBookingServer.csproj">
+ <Project>{B34E21C4-A742-4886-8569-1A89490E093E}</Project>
+ <Name>wcfBookingServer</Name>
+ </ProjectReference>
+ </ItemGroup>
+ <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+ <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
+ Other similar extension points exist, see Microsoft.Common.targets.
+ <Target Name="BeforeBuild">
+ </Target>
+ <Target Name="AfterBuild">
+ </Target>
+ -->
+</Project> \ No newline at end of file
diff --git a/qpid/dotnet/client-010/wcf/demo/wcfBookingServer/Booking.cs b/qpid/dotnet/client-010/wcf/demo/wcfBookingServer/Booking.cs
new file mode 100644
index 0000000000..7c0fbb39b4
--- /dev/null
+++ b/qpid/dotnet/client-010/wcf/demo/wcfBookingServer/Booking.cs
@@ -0,0 +1,62 @@
+/*
+*
+* 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.
+*
+*/
+
+using System;
+using System.Collections.Generic;
+using System.ServiceModel;
+
+
+namespace org.apache.qpid.wcf.demo.bookingServer
+{
+ [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession)]
+ public class Booking : IBooking
+ {
+ private Guid _id;
+ private List<Order> _orders;
+
+ public Booking()
+ {
+ _id = Guid.NewGuid();
+ _orders = new List<Order>();
+ }
+
+ public void Add(Order order)
+ {
+ _orders.Add(order);
+ }
+
+ public Receipt Checkout()
+ {
+ var r = new Receipt();
+ foreach (Order order in _orders)
+ {
+ r.Price += order.Price;
+ r.Summary = r.Summary + " \n " + order.Type + " Price: " + order.Price;
+ }
+ return r;
+ }
+
+ public Guid Id
+ {
+ get { return _id; }
+ }
+ }
+}
diff --git a/qpid/dotnet/client-010/wcf/demo/wcfBookingServer/IBooking.cs b/qpid/dotnet/client-010/wcf/demo/wcfBookingServer/IBooking.cs
new file mode 100644
index 0000000000..cead4d0471
--- /dev/null
+++ b/qpid/dotnet/client-010/wcf/demo/wcfBookingServer/IBooking.cs
@@ -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.
+*
+*/
+
+using System;
+using System.ServiceModel;
+
+namespace org.apache.qpid.wcf.demo.bookingServer
+{
+ [ServiceContract(SessionMode=SessionMode.Required)]
+ public interface IBooking
+ {
+ [OperationContract]
+ void Add(Order order);
+
+ [OperationContract]
+ Receipt Checkout();
+
+ Guid Id
+ {
+ [OperationContract]
+ get;
+ }
+ }
+
+}
diff --git a/qpid/dotnet/client-010/wcf/demo/wcfBookingServer/Order.cs b/qpid/dotnet/client-010/wcf/demo/wcfBookingServer/Order.cs
new file mode 100644
index 0000000000..aa52908692
--- /dev/null
+++ b/qpid/dotnet/client-010/wcf/demo/wcfBookingServer/Order.cs
@@ -0,0 +1,45 @@
+/*
+*
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing,
+* software distributed under the License is distributed on an
+* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+* KIND, either express or implied. See the License for the
+* specific language governing permissions and limitations
+* under the License.
+*
+*/
+using System.Runtime.Serialization;
+
+namespace org.apache.qpid.wcf.demo.bookingServer
+{
+ [DataContract]
+ public sealed class Order
+ {
+ private double _price;
+ private string _type;
+
+ [DataMember]
+ public double Price
+ {
+ get { return _price; }
+ set { _price = value; }
+ }
+
+ [DataMember]
+ public string Type
+ {
+ get { return _type; }
+ set { _type = value; }
+ }
+ }
+}
diff --git a/qpid/dotnet/client-010/wcf/demo/wcfBookingServer/Program.cs b/qpid/dotnet/client-010/wcf/demo/wcfBookingServer/Program.cs
new file mode 100644
index 0000000000..ebb75308cf
--- /dev/null
+++ b/qpid/dotnet/client-010/wcf/demo/wcfBookingServer/Program.cs
@@ -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.
+*
+*/
+
+using System;
+using System.ServiceModel;
+using System.ServiceModel.Channels;
+using System.Threading;
+using org.apache.qpid.wcf.model;
+
+
+namespace org.apache.qpid.wcf.demo.bookingServer
+{
+ internal class Program
+ {
+ private ServiceHost _service;
+ private ChannelFactory<IBooking> fac;
+
+ public void StartService(Binding binding)
+ {
+ try
+ {
+ Console.WriteLine(" Binding Service...");
+ _service = new ServiceHost(typeof(Booking), new Uri("soap.amqp:///"));
+ _service.AddServiceEndpoint(typeof(IBooking), binding, "Booking");
+ _service.Open();
+ Thread.Sleep(500);
+ Console.WriteLine("[DONE]");
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine(e);
+ }
+ }
+
+ public void StopService()
+ {
+ Console.WriteLine(" Stopping Service...");
+ _service.Close();
+ Console.WriteLine("[DONE]");
+ }
+
+ public IBooking StartClient(Binding binding)
+ {
+ IBooking res = null;
+ try
+ {
+ Console.WriteLine(" Starting Client...");
+ fac = new ChannelFactory<IBooking>(binding, "soap.amqp:///Booking");
+ fac.Open();
+ res = fac.CreateChannel();
+ Console.WriteLine("[DONE]");
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine(e);
+ }
+ return res;
+ }
+
+ public void StopClient(IBooking client)
+ {
+ Console.WriteLine(" Stopping Client...");
+ ((IChannel)client).Close();
+ fac.Close();
+ Console.WriteLine("[DONE]");
+ }
+
+ private static void Main(string[] args)
+ {
+ var p = new Program();
+
+ Binding binding = new QpidBinding("192.168.1.14", 5673);
+ p.StartService(binding);
+
+ Console.ReadLine();
+
+ p.StopService();
+ }
+ }
+}
diff --git a/qpid/dotnet/client-010/wcf/demo/wcfBookingServer/Properties/AssemblyInfo.cs b/qpid/dotnet/client-010/wcf/demo/wcfBookingServer/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000000..cc0208c9ca
--- /dev/null
+++ b/qpid/dotnet/client-010/wcf/demo/wcfBookingServer/Properties/AssemblyInfo.cs
@@ -0,0 +1,57 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("Booking Server")]
+[assembly: AssemblyDescription("Built from svn revision number: ")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Apache Software Foundation")]
+[assembly: AssemblyProduct("Booking Server")]
+[assembly: AssemblyCopyright("Apache Software Foundation")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("12ef158b-ac5f-43b3-99f6-e4a4c096d6f8")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("0.5.0.0")]
+[assembly: AssemblyVersion("0.5.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/qpid/dotnet/client-010/wcf/demo/wcfBookingServer/Receipt.cs b/qpid/dotnet/client-010/wcf/demo/wcfBookingServer/Receipt.cs
new file mode 100644
index 0000000000..d5ab0f3eb3
--- /dev/null
+++ b/qpid/dotnet/client-010/wcf/demo/wcfBookingServer/Receipt.cs
@@ -0,0 +1,46 @@
+/*
+*
+* 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.
+*
+*/
+
+using System.Runtime.Serialization;
+
+namespace org.apache.qpid.wcf.demo.bookingServer
+{
+ [DataContract]
+ public sealed class Receipt
+ {
+ private double _price;
+ private string _summary;
+
+ [DataMember]
+ public double Price
+ {
+ get { return _price; }
+ set { _price = value; }
+ }
+
+ [DataMember]
+ public string Summary
+ {
+ get { return _summary; }
+ set { _summary = value; }
+ }
+ }
+}
diff --git a/qpid/dotnet/client-010/wcf/demo/wcfBookingServer/wcfBookingServer.csproj b/qpid/dotnet/client-010/wcf/demo/wcfBookingServer/wcfBookingServer.csproj
new file mode 100644
index 0000000000..2f744f8b6b
--- /dev/null
+++ b/qpid/dotnet/client-010/wcf/demo/wcfBookingServer/wcfBookingServer.csproj
@@ -0,0 +1,97 @@
+<?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.
+ -
+ -->
+<Project ToolsVersion="3.5" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProductVersion>9.0.30729</ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{B34E21C4-A742-4886-8569-1A89490E093E}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>wcfSession</RootNamespace>
+ <AssemblyName>Booking Server</AssemblyName>
+ <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
+ <FileAlignment>512</FileAlignment>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="System" />
+ <Reference Include="System.Core">
+ <RequiredTargetFramework>3.5</RequiredTargetFramework>
+ </Reference>
+ <Reference Include="System.Drawing" />
+ <Reference Include="System.Runtime.Serialization">
+ <RequiredTargetFramework>3.0</RequiredTargetFramework>
+ </Reference>
+ <Reference Include="System.ServiceModel">
+ <RequiredTargetFramework>3.0</RequiredTargetFramework>
+ </Reference>
+ <Reference Include="System.Windows.Forms" />
+ <Reference Include="System.Xml.Linq">
+ <RequiredTargetFramework>3.5</RequiredTargetFramework>
+ </Reference>
+ <Reference Include="System.Data.DataSetExtensions">
+ <RequiredTargetFramework>3.5</RequiredTargetFramework>
+ </Reference>
+ <Reference Include="System.Data" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="Booking.cs" />
+ <Compile Include="Receipt.cs" />
+ <Compile Include="IBooking.cs" />
+ <Compile Include="Order.cs" />
+ <Compile Include="Program.cs" />
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\..\wcf.csproj">
+ <Project>{F1D80D9D-FE22-4213-A760-BFFDE7D131DD}</Project>
+ <Name>wcf</Name>
+ </ProjectReference>
+ </ItemGroup>
+ <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+ <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
+ Other similar extension points exist, see Microsoft.Common.targets.
+ <Target Name="BeforeBuild">
+ </Target>
+ <Target Name="AfterBuild">
+ </Target>
+ -->
+</Project> \ No newline at end of file
diff --git a/qpid/dotnet/client-010/wcf/demo/wcfHelloClient/App.config b/qpid/dotnet/client-010/wcf/demo/wcfHelloClient/App.config
new file mode 100644
index 0000000000..1545d71d6f
--- /dev/null
+++ b/qpid/dotnet/client-010/wcf/demo/wcfHelloClient/App.config
@@ -0,0 +1,56 @@
+<?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.
+
+-->
+
+<configuration>
+ <system.serviceModel>
+
+ <client>
+ <endpoint address="soap.amqp:///Hello"
+ binding="customBinding"
+ bindingConfiguration="QpidBinding"
+ contract="org.apache.qpid.wcf.demo.helloClient.IHelloContract"
+ name="HelloService" />
+ </client>
+
+
+ <bindings>
+ <customBinding>
+ <binding name="QpidBinding">
+ <textMessageEncoding />
+ <QpidTransport
+ host="localhost"
+ port="5672" />
+ </binding>
+ </customBinding>
+ </bindings>
+
+ <extensions>
+ <bindingElementExtensions>
+ <add
+ name="QpidTransport"
+ type="org.apache.qpid.wcf.model.QpidTransportElement, qpidWCFModel"/>
+ </bindingElementExtensions>
+ </extensions>
+
+
+ </system.serviceModel>
+</configuration>
diff --git a/qpid/dotnet/client-010/wcf/demo/wcfHelloClient/HelloClient.cs b/qpid/dotnet/client-010/wcf/demo/wcfHelloClient/HelloClient.cs
new file mode 100644
index 0000000000..31743c62cf
--- /dev/null
+++ b/qpid/dotnet/client-010/wcf/demo/wcfHelloClient/HelloClient.cs
@@ -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.
+*
+*/
+
+using System.ServiceModel;
+
+namespace org.apache.qpid.wcf.demo.helloClient
+{
+ public class HelloClient : ClientBase<IHelloContract>, IHelloContract
+ {
+ public HelloClient(string configurationName)
+ : base(configurationName) { }
+
+ public void Hello(string name)
+ {
+ Channel.Hello(name);
+ }
+ }
+}
diff --git a/qpid/dotnet/client-010/wcf/demo/wcfHelloClient/IHelloService.cs b/qpid/dotnet/client-010/wcf/demo/wcfHelloClient/IHelloService.cs
new file mode 100644
index 0000000000..d3b9a354ba
--- /dev/null
+++ b/qpid/dotnet/client-010/wcf/demo/wcfHelloClient/IHelloService.cs
@@ -0,0 +1,33 @@
+/*
+*
+* 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.
+*
+*/
+
+using System.ServiceModel;
+
+namespace org.apache.qpid.wcf.demo.helloClient
+{
+ [ServiceContract]
+ public interface IHelloContract
+ {
+ [OperationContract(IsOneWay=true)]
+ void Hello(string name);
+ }
+
+}
diff --git a/qpid/dotnet/client-010/wcf/demo/wcfHelloClient/Program.cs b/qpid/dotnet/client-010/wcf/demo/wcfHelloClient/Program.cs
new file mode 100644
index 0000000000..fc68d2556a
--- /dev/null
+++ b/qpid/dotnet/client-010/wcf/demo/wcfHelloClient/Program.cs
@@ -0,0 +1,48 @@
+/*
+*
+* 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.
+*
+*/
+
+using System;
+
+namespace org.apache.qpid.wcf.demo.helloClient
+{
+ class Program
+ {
+ static void Main(string[] args)
+ {
+ Console.Title = "Hello Service Client";
+ Console.ForegroundColor = ConsoleColor.White;
+ Console.WriteLine("Hello Service Client");
+ Console.ForegroundColor = ConsoleColor.Gray;
+ Console.WriteLine();
+ // create a client using the configuration file App.config
+ var client = new HelloClient("HelloService");
+ Console.WriteLine("Client Saying Hello to Qpid");
+ client.Hello("Qpid");
+ Console.WriteLine("Client Saying Hello to AMQP");
+ client.Hello("AMQP");
+ // closing the client service
+ client.ChannelFactory.Close();
+ Console.WriteLine();
+ Console.Write("Press Enter to Exit...");
+ Console.ReadLine();
+ }
+ }
+}
diff --git a/qpid/dotnet/client-010/wcf/demo/wcfHelloClient/Properties/AssemblyInfo.cs b/qpid/dotnet/client-010/wcf/demo/wcfHelloClient/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000000..83dfbcd5f4
--- /dev/null
+++ b/qpid/dotnet/client-010/wcf/demo/wcfHelloClient/Properties/AssemblyInfo.cs
@@ -0,0 +1,57 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("Qpid WCF Hello Client")]
+[assembly: AssemblyDescription("Built from svn revision number: ")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Apache Software Foundation")]
+[assembly: AssemblyProduct("Qpid WCF Hello Client")]
+[assembly: AssemblyCopyright("Apache Software Foundation")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("f7628695-280a-4689-ac6f-1186177f9a25")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("0.5.0.0")]
+[assembly: AssemblyVersion("0.5.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/qpid/dotnet/client-010/wcf/demo/wcfHelloClient/wcfHelloClient.csproj b/qpid/dotnet/client-010/wcf/demo/wcfHelloClient/wcfHelloClient.csproj
new file mode 100644
index 0000000000..2e518d0da0
--- /dev/null
+++ b/qpid/dotnet/client-010/wcf/demo/wcfHelloClient/wcfHelloClient.csproj
@@ -0,0 +1,85 @@
+<?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.
+ -
+ -->
+<Project ToolsVersion="3.5" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProductVersion>9.0.30729</ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{A24E27DB-A38D-40C9-9879-8390B68C2F06}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>wcfHelloClient</RootNamespace>
+ <AssemblyName>Qpid WCF Hello Client</AssemblyName>
+ <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
+ <FileAlignment>512</FileAlignment>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="System" />
+ <Reference Include="System.configuration" />
+ <Reference Include="System.ServiceModel">
+ <RequiredTargetFramework>3.0</RequiredTargetFramework>
+ </Reference>
+ <Reference Include="System.Data" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="HelloClient.cs" />
+ <Compile Include="IHelloService.cs" />
+ <Compile Include="Program.cs" />
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="App.config" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\..\wcf.csproj">
+ <Project>{F1D80D9D-FE22-4213-A760-BFFDE7D131DD}</Project>
+ <Name>wcf</Name>
+ </ProjectReference>
+ </ItemGroup>
+ <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+ <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
+ Other similar extension points exist, see Microsoft.Common.targets.
+ <Target Name="BeforeBuild">
+ </Target>
+ <Target Name="AfterBuild">
+ </Target>
+ -->
+</Project> \ No newline at end of file
diff --git a/qpid/dotnet/client-010/wcf/demo/wcfHelloServer/App.config b/qpid/dotnet/client-010/wcf/demo/wcfHelloServer/App.config
new file mode 100644
index 0000000000..de71f890b5
--- /dev/null
+++ b/qpid/dotnet/client-010/wcf/demo/wcfHelloServer/App.config
@@ -0,0 +1,64 @@
+<?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.
+
+-->
+
+<configuration>
+ <system.serviceModel>
+
+
+ <services>
+ <service name="org.apache.qpid.wcf.demo.HelloService">
+ <host>
+ <baseAddresses>
+ <add baseAddress="soap.amqp:///" />
+ </baseAddresses>
+ </host>
+ <endpoint
+ address="Hello"
+ binding="customBinding"
+ bindingConfiguration="QpidBinding"
+ contract="org.apache.qpid.wcf.demo.IHelloContract"/>
+ </service>
+ </services>
+
+
+ <bindings>
+ <customBinding>
+ <binding name="QpidBinding">
+ <textMessageEncoding />
+ <QpidTransport
+ host="192.168.1.14"
+ port="5673" />
+ </binding>
+ </customBinding>
+ </bindings>
+
+ <extensions>
+ <bindingElementExtensions>
+ <add
+ name="QpidTransport"
+ type="org.apache.qpid.wcf.model.QpidTransportElement, qpidWCFModel"/>
+ </bindingElementExtensions>
+ </extensions>
+
+
+ </system.serviceModel>
+</configuration>
diff --git a/qpid/dotnet/client-010/wcf/demo/wcfHelloServer/HelloService.cs b/qpid/dotnet/client-010/wcf/demo/wcfHelloServer/HelloService.cs
new file mode 100644
index 0000000000..3b7df01ece
--- /dev/null
+++ b/qpid/dotnet/client-010/wcf/demo/wcfHelloServer/HelloService.cs
@@ -0,0 +1,34 @@
+/*
+*
+* 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.
+*
+*/
+
+using System;
+
+namespace org.apache.qpid.wcf.demo.helloServer
+{
+ public class HelloService : IHelloContract
+ {
+ public void Hello(string name)
+ {
+ Console.WriteLine("Hello {0}!", name);
+
+ }
+ }
+}
diff --git a/qpid/dotnet/client-010/wcf/demo/wcfHelloServer/IHelloService.cs b/qpid/dotnet/client-010/wcf/demo/wcfHelloServer/IHelloService.cs
new file mode 100644
index 0000000000..1609439b94
--- /dev/null
+++ b/qpid/dotnet/client-010/wcf/demo/wcfHelloServer/IHelloService.cs
@@ -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.
+*
+*/
+using System.ServiceModel;
+
+namespace org.apache.qpid.wcf.demo.helloServer
+{
+ [ServiceContract]
+ public interface IHelloContract
+ {
+ [OperationContract(IsOneWay=true)]
+ void Hello(string name);
+ }
+
+}
diff --git a/qpid/dotnet/client-010/wcf/demo/wcfHelloServer/Program.cs b/qpid/dotnet/client-010/wcf/demo/wcfHelloServer/Program.cs
new file mode 100644
index 0000000000..1b8b8947ee
--- /dev/null
+++ b/qpid/dotnet/client-010/wcf/demo/wcfHelloServer/Program.cs
@@ -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.
+*
+*/
+
+using System;
+using System.ServiceModel;
+
+namespace org.apache.qpid.wcf.demo.helloServer
+{
+ class Program
+ {
+ static void Main(string[] args)
+ {
+ Console.Title = "Hello Service Server";
+ Console.ForegroundColor = ConsoleColor.White;
+ Console.WriteLine("Hello Service Server");
+ Console.ForegroundColor = ConsoleColor.Gray;
+ Console.WriteLine();
+
+ var host = new ServiceHost(typeof(HelloService));
+ host.Open();
+
+ Console.WriteLine("Service Ready");
+ Console.WriteLine("Press Enter to Exit...");
+ Console.ReadLine();
+
+ host.Close();
+ }
+ }
+}
diff --git a/qpid/dotnet/client-010/wcf/demo/wcfHelloServer/Properties/AssemblyInfo.cs b/qpid/dotnet/client-010/wcf/demo/wcfHelloServer/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000000..a32f32e864
--- /dev/null
+++ b/qpid/dotnet/client-010/wcf/demo/wcfHelloServer/Properties/AssemblyInfo.cs
@@ -0,0 +1,57 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("Qpid WCF Hello Server")]
+[assembly: AssemblyDescription("Built from svn revision number: ")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Apache Software Foundation")]
+[assembly: AssemblyProduct("Qpid WCF Hello Server")]
+[assembly: AssemblyCopyright("Apache Software Foundation")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("afa87185-f224-4948-904c-b4f3cd19dadb")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("0.5.0.0")]
+[assembly: AssemblyVersion("0.5.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/qpid/dotnet/client-010/wcf/demo/wcfHelloServer/wcfHelloServer.csproj b/qpid/dotnet/client-010/wcf/demo/wcfHelloServer/wcfHelloServer.csproj
new file mode 100644
index 0000000000..3a672a87f4
--- /dev/null
+++ b/qpid/dotnet/client-010/wcf/demo/wcfHelloServer/wcfHelloServer.csproj
@@ -0,0 +1,87 @@
+<?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.
+ -
+ -->
+<Project ToolsVersion="3.5" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProductVersion>9.0.30729</ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{3EF848D7-5FAC-482C-922A-D4D45A4CCD2A}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>wcfHelloServer</RootNamespace>
+ <AssemblyName>Qpid WCF Hello Server</AssemblyName>
+ <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
+ <FileAlignment>512</FileAlignment>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="System" />
+ <Reference Include="System.Core">
+ <RequiredTargetFramework>3.5</RequiredTargetFramework>
+ </Reference>
+ <Reference Include="System.ServiceModel">
+ <RequiredTargetFramework>3.0</RequiredTargetFramework>
+ </Reference>
+ <Reference Include="System.Xml.Linq">
+ <RequiredTargetFramework>3.5</RequiredTargetFramework>
+ </Reference>
+ <Reference Include="System.Data.DataSetExtensions">
+ <RequiredTargetFramework>3.5</RequiredTargetFramework>
+ </Reference>
+ <Reference Include="System.Data" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="HelloService.cs" />
+ <Compile Include="IHelloService.cs" />
+ <Compile Include="Program.cs" />
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="App.config" />
+ </ItemGroup>
+ <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+ <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
+ Other similar extension points exist, see Microsoft.Common.targets.
+ <Target Name="BeforeBuild">
+ </Target>
+ <Target Name="AfterBuild">
+ </Target>
+ -->
+</Project> \ No newline at end of file
diff --git a/qpid/dotnet/client-010/wcf/demo/wcfRPC/IUpperCase.cs b/qpid/dotnet/client-010/wcf/demo/wcfRPC/IUpperCase.cs
new file mode 100644
index 0000000000..668450948d
--- /dev/null
+++ b/qpid/dotnet/client-010/wcf/demo/wcfRPC/IUpperCase.cs
@@ -0,0 +1,31 @@
+/*
+*
+* 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.
+*
+*/
+using System.ServiceModel;
+
+namespace org.apache.qpid.wcf.demo.rpc
+{
+ [ServiceContract]
+ public interface IUpperCase
+ {
+ [OperationContract]
+ string ToUpperCase(string message);
+ }
+}
diff --git a/qpid/dotnet/client-010/wcf/demo/wcfRPC/Program.cs b/qpid/dotnet/client-010/wcf/demo/wcfRPC/Program.cs
new file mode 100644
index 0000000000..e2b54a0f61
--- /dev/null
+++ b/qpid/dotnet/client-010/wcf/demo/wcfRPC/Program.cs
@@ -0,0 +1,113 @@
+/*
+*
+* 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.
+*
+*/
+
+using System;
+using System.ServiceModel;
+using System.ServiceModel.Channels;
+using System.Threading;
+using org.apache.qpid.wcf.model;
+
+
+namespace org.apache.qpid.wcf.demo.rpc
+{
+ internal class Program
+ {
+ private ServiceHost _service;
+ private ChannelFactory<IUpperCase> fac;
+
+ public void StartService(Binding binding)
+ {
+ try
+ {
+ Console.WriteLine(" Binding Service...");
+ _service = new ServiceHost(typeof (UpperCase), new Uri("soap.amqp:///"));
+ _service.AddServiceEndpoint(typeof(IUpperCase), binding, "UpperCase");
+ _service.Open();
+ Thread.Sleep(500);
+ Console.WriteLine("[DONE]");
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine(e);
+ }
+ }
+
+ public void StopService()
+ {
+ Console.WriteLine(" Stopping Service...");
+ _service.Close();
+ Console.WriteLine("[DONE]");
+ }
+
+ public IUpperCase StartClient(Binding binding)
+ {
+ IUpperCase res = null;
+ try
+ {
+ Console.WriteLine(" Starting Client...");
+ fac = new ChannelFactory<IUpperCase>(binding, "soap.amqp:///UpperCase");
+ fac.Open();
+ res = fac.CreateChannel();
+ Console.WriteLine("[DONE]");
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine(e);
+ }
+ return res;
+ }
+
+ public void StopClient(IUpperCase client)
+ {
+ Console.WriteLine(" Stopping Client...");
+ ((IChannel) client).Close();
+ fac.Close();
+ Console.WriteLine("[DONE]");
+ }
+
+ private static void Main(string[] args)
+ {
+ var p = new Program();
+
+ Binding binding = new QpidBinding("192.168.1.14", 5673);
+ p.StartService(binding);
+
+
+ IUpperCase calc = p.StartClient(new QpidBinding("192.168.1.14", 5673));
+
+ string[] messages = {"Twas brillig, and the slithy toves",
+ "Did gire and gymble in the wabe. ",
+ "All mimsy were the borogroves, ",
+ "And the mome raths outgrabe. "};
+ foreach (string m in messages)
+ {
+ Console.Write(m + " --UperCase--> " );
+ Console.Write(calc.ToUpperCase(m));
+ Console.WriteLine();
+ }
+
+ Console.ReadLine();
+
+ p.StopClient(calc);
+ p.StopService();
+ }
+ }
+}
diff --git a/qpid/dotnet/client-010/wcf/demo/wcfRPC/Properties/AssemblyInfo.cs b/qpid/dotnet/client-010/wcf/demo/wcfRPC/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000000..703fb9fcea
--- /dev/null
+++ b/qpid/dotnet/client-010/wcf/demo/wcfRPC/Properties/AssemblyInfo.cs
@@ -0,0 +1,57 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("Qpid WCF UpperCase")]
+[assembly: AssemblyDescription("Built from svn revision number: ")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Apache Software Foundation")]
+[assembly: AssemblyProduct("Qpid WCF UpperCase")]
+[assembly: AssemblyCopyright("Apache Software Foundation")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("14ba3707-3fcc-4033-8bbc-0db65c5424f3")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("0.5.0.0")]
+[assembly: AssemblyVersion("0.5.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/qpid/dotnet/client-010/wcf/demo/wcfRPC/QpidBindingConfigurationElement.cs b/qpid/dotnet/client-010/wcf/demo/wcfRPC/QpidBindingConfigurationElement.cs
new file mode 100644
index 0000000000..1d12868497
--- /dev/null
+++ b/qpid/dotnet/client-010/wcf/demo/wcfRPC/QpidBindingConfigurationElement.cs
@@ -0,0 +1,205 @@
+/*
+*
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing,
+* software distributed under the License is distributed on an
+* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+* KIND, either express or implied. See the License for the
+* specific language governing permissions and limitations
+* under the License.
+*
+*/
+
+using System;
+using System.Reflection;
+using System.ServiceModel.Channels;
+using System.ServiceModel.Configuration;
+using System.Configuration;
+
+namespace org.apache.qpid.wcf.model
+{
+
+ /// <remarks>
+ /// This configuration element should be imported into the client
+ /// and server configuration files to provide declarative configuration
+ /// of a AMQP bound service.
+ /// </remarks>
+ public sealed class QpidBindingConfigurationElement : StandardBindingElement
+ {
+ /// <summary>
+ /// Creates a new instance of the QpidBindingConfigurationElement
+ /// Class initialized with values from the specified configuration.
+ /// </summary>
+ /// <param name="configurationName"></param>
+ public QpidBindingConfigurationElement(string configurationName)
+ : base(configurationName)
+ {
+ }
+
+ /// <summary>
+ /// Creates a new instance of the RabbitMQBindingConfigurationElement Class.
+ /// </summary>
+ public QpidBindingConfigurationElement()
+ : this(null)
+ {
+ }
+
+
+ protected override void InitializeFrom(Binding binding)
+ {
+ base.InitializeFrom(binding);
+ QpidBinding qpidbinding = binding as QpidBinding;
+ if (qpidbinding != null)
+ {
+ Host = qpidbinding.Host;
+ OneWayOnly = qpidbinding.OneWayOnly;
+ TransactionFlowEnabled = qpidbinding.TransactionFlow;
+ VirtualHost = qpidbinding.VirtualHost;
+ PortNumber = qpidbinding.PortNumber;
+ UserName = qpidbinding.UserName;
+ Password = qpidbinding.Password;
+ }
+ }
+
+ protected override void OnApplyConfiguration(Binding binding)
+ {
+ if (binding == null)
+ throw new ArgumentNullException("binding");
+
+ var qpidbinding = binding as QpidBinding;
+ if (qpidbinding == null)
+ {
+ throw new ArgumentException(
+ string.Format("Invalid type for binding. Expected {0}, Passed: {1}",
+ typeof(QpidBinding).AssemblyQualifiedName,
+ binding.GetType().AssemblyQualifiedName));
+ }
+
+ qpidbinding.Host = Host;
+ qpidbinding.OneWayOnly = OneWayOnly;
+ qpidbinding.TransactionFlow = TransactionFlowEnabled;
+ qpidbinding.Password = Password;
+ qpidbinding.UserName = UserName;
+ qpidbinding.VirtualHost = VirtualHost;
+ qpidbinding.PortNumber = PortNumber;
+ }
+
+
+ /// <summary>
+ /// Specifies the host that the binding should connect to.
+ /// </summary>
+ [ConfigurationProperty("host", DefaultValue = "localhost")]
+ public string Host
+ {
+ get { return ((string) base["host"]); }
+ set { base["host"] = value; }
+ }
+
+ /// <summary>
+ /// Specifies the broker port number that the binding should connect to.
+ /// </summary>
+ [ConfigurationProperty("port", DefaultValue = "5672")]
+ public int PortNumber
+ {
+ get { return (Convert.ToInt16(base["port"])); }
+ set { base["port"] = value; }
+ }
+
+
+ /// <summary>
+ /// Specifies whether or not the CompositeDuplex and ReliableSession
+ /// binding elements are added to the channel stack.
+ /// </summary>
+ [ConfigurationProperty("oneWay", DefaultValue = false)]
+ public bool OneWayOnly
+ {
+ get { return ((bool)base["oneWay"]); }
+ set { base["oneWay"] = value; }
+ }
+
+ /// <summary>
+ /// Password to use when authenticating with the broker
+ /// </summary>
+ [ConfigurationProperty("password", DefaultValue = "guest")]
+ public string Password
+ {
+ get { return ((string)base["password"]); }
+ set { base["password"] = value; }
+ }
+
+ /// <summary>
+ /// Specifies whether or not WS-AtomicTransactions are supported by the binding
+ /// </summary>
+ [ConfigurationProperty("transactionFlow", DefaultValue = false)]
+ public bool TransactionFlowEnabled
+ {
+ get { return ((bool)base["transactionFlow"]); }
+ set { base["transactionFlow"] = value; }
+ }
+
+ /// <summary>
+ /// The username to use when authenticating with the broker
+ /// </summary>
+ [ConfigurationProperty("username", DefaultValue = "guest")]
+ public string UserName
+ {
+ get { return ((string)base["username"]); }
+ set { base["username"] = value; }
+ }
+
+
+
+
+ /// <summary>
+ /// The virtual host to access.
+ /// </summary>
+ [ConfigurationProperty("virtualHost", DefaultValue = "test")]
+ public string VirtualHost
+ {
+ get { return ((string)base["virtualHost"]); }
+ set { base["virtualHost"] = value; }
+ }
+
+ ///<summary>The security realm to use when calling IModel.AccessRequest</summary>
+ [ConfigurationProperty("realm", DefaultValue = "plain")]
+ public string Realm
+ {
+ get { return ((string)base["realm"]); }
+ set { base["realm"] = value; }
+ }
+
+ protected override Type BindingElementType
+ {
+ get { return typeof(QpidBinding); }
+ }
+
+ protected override ConfigurationPropertyCollection Properties
+ {
+ get
+ {
+ ConfigurationPropertyCollection configProperties = base.Properties;
+ foreach (PropertyInfo prop in this.GetType().GetProperties(BindingFlags.DeclaredOnly
+ | BindingFlags.Public
+ | BindingFlags.Instance))
+ {
+ foreach (ConfigurationPropertyAttribute attr in prop.GetCustomAttributes(typeof(ConfigurationPropertyAttribute), false))
+ {
+ configProperties.Add(
+ new ConfigurationProperty(attr.Name, prop.PropertyType, attr.DefaultValue));
+ }
+ }
+
+ return configProperties;
+ }
+ }
+ }
+}
diff --git a/qpid/dotnet/client-010/wcf/demo/wcfRPC/UpperCase.cs b/qpid/dotnet/client-010/wcf/demo/wcfRPC/UpperCase.cs
new file mode 100644
index 0000000000..3e10926be4
--- /dev/null
+++ b/qpid/dotnet/client-010/wcf/demo/wcfRPC/UpperCase.cs
@@ -0,0 +1,33 @@
+/*
+*
+* 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.
+*
+*/
+using System.ServiceModel;
+
+namespace org.apache.qpid.wcf.demo.rpc
+{
+ [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
+ public sealed class UpperCase : IUpperCase
+ {
+ public string ToUpperCase(string message)
+ {
+ return message.ToUpper();
+ }
+ }
+}
diff --git a/qpid/dotnet/client-010/wcf/demo/wcfRPC/wcfRPC.csproj b/qpid/dotnet/client-010/wcf/demo/wcfRPC/wcfRPC.csproj
new file mode 100644
index 0000000000..e8f7fee8f5
--- /dev/null
+++ b/qpid/dotnet/client-010/wcf/demo/wcfRPC/wcfRPC.csproj
@@ -0,0 +1,93 @@
+<?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.
+ -
+ -->
+<Project ToolsVersion="3.5" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProductVersion>9.0.30729</ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{C988F456-1025-486F-9BCD-49C0F83B91DB}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>wcfRPC</RootNamespace>
+ <AssemblyName>Qpid WCF UpperCase</AssemblyName>
+ <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
+ <FileAlignment>512</FileAlignment>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="System" />
+ <Reference Include="System.configuration" />
+ <Reference Include="System.Core">
+ <RequiredTargetFramework>3.5</RequiredTargetFramework>
+ </Reference>
+ <Reference Include="System.Drawing" />
+ <Reference Include="System.ServiceModel">
+ <RequiredTargetFramework>3.0</RequiredTargetFramework>
+ </Reference>
+ <Reference Include="System.Windows.Forms" />
+ <Reference Include="System.Xml.Linq">
+ <RequiredTargetFramework>3.5</RequiredTargetFramework>
+ </Reference>
+ <Reference Include="System.Data.DataSetExtensions">
+ <RequiredTargetFramework>3.5</RequiredTargetFramework>
+ </Reference>
+ <Reference Include="System.Data" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="IUpperCase.cs" />
+ <Compile Include="Program.cs" />
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ <Compile Include="UpperCase.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\..\wcf.csproj">
+ <Project>{F1D80D9D-FE22-4213-A760-BFFDE7D131DD}</Project>
+ <Name>wcf</Name>
+ </ProjectReference>
+ </ItemGroup>
+ <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+ <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
+ Other similar extension points exist, see Microsoft.Common.targets.
+ <Target Name="BeforeBuild">
+ </Target>
+ <Target Name="AfterBuild">
+ </Target>
+ -->
+</Project> \ No newline at end of file
diff --git a/qpid/dotnet/client-010/wcf/model/CommunicationOperation.cs b/qpid/dotnet/client-010/wcf/model/CommunicationOperation.cs
new file mode 100644
index 0000000000..3506d6729c
--- /dev/null
+++ b/qpid/dotnet/client-010/wcf/model/CommunicationOperation.cs
@@ -0,0 +1,31 @@
+/*
+*
+* 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.
+*
+*/
+
+using System;
+using System.ServiceModel.Channels;
+
+namespace org.apache.qpid.wcf.model
+{
+ internal delegate void CommunicationOperation(TimeSpan timeout);
+ internal delegate TResult CommunicationOperation<TResult>(TimeSpan timeout);
+ internal delegate TResult CommunicationOperation<TResult, TArg>(TimeSpan timeout, out TArg arg0);
+ internal delegate void SendOperation(Message message, TimeSpan timeout);
+}
diff --git a/qpid/dotnet/client-010/wcf/model/QpidBinding.cs b/qpid/dotnet/client-010/wcf/model/QpidBinding.cs
new file mode 100644
index 0000000000..8f4684c1a1
--- /dev/null
+++ b/qpid/dotnet/client-010/wcf/model/QpidBinding.cs
@@ -0,0 +1,185 @@
+/*
+*
+* 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.
+*
+*/
+
+using System.Configuration;
+using System.ServiceModel;
+using System.ServiceModel.Channels;
+
+namespace org.apache.qpid.wcf.model
+{
+ public sealed class QpidBinding : Binding
+ {
+ private string _host;
+ private int _port;
+ private string _username;
+ private string _password;
+ private string _virtuaHost;
+ private readonly CompositeDuplexBindingElement _compositeDuplex;
+ private readonly MessageEncodingBindingElement _encoding;
+ private bool _oneWayOnly;
+ private readonly ReliableSessionBindingElement _session;
+ private readonly TransactionFlowBindingElement _transactionFlow;
+ private bool _transactionsEnabled;
+ private readonly QpidTransportBindingElement _transport;
+
+
+
+ public QpidBinding() : this("localhost", 5672, "guest", "guest", "test")
+ {
+ }
+
+
+ public QpidBinding(string host, int port ) : this (host, port, "guest", "guest", "test")
+ {
+ }
+
+ public QpidBinding(string host, int port, string username, string password, string virtualhost)
+ {
+ Host = host;
+ PortNumber = port;
+ UserName = username;
+ Password = password;
+ VirtualHost = virtualhost;
+ _transport = new QpidTransportBindingElement();
+ _transport.Host = host;
+ _transport.PortNumber = port;
+ _transport.Password = password;
+ _transport.UserName = username;
+ _transport.VirtualHost = virtualhost;
+ _encoding = new TextMessageEncodingBindingElement();
+ _session = new ReliableSessionBindingElement();
+ _compositeDuplex = new CompositeDuplexBindingElement();
+ _transactionFlow = new TransactionFlowBindingElement();
+ }
+
+ public override BindingElementCollection CreateBindingElements()
+ {
+ var elements = new BindingElementCollection();
+
+ if (_transactionsEnabled)
+ {
+ elements.Add(_transactionFlow);
+ }
+ if (!OneWayOnly)
+ {
+ elements.Add(_session);
+ elements.Add(_compositeDuplex);
+ }
+ elements.Add(_encoding);
+ elements.Add(_transport);
+
+ return elements;
+ }
+
+
+
+ /// <summary>
+ /// Gets the scheme used by the binding, soap.amqp
+ /// </summary>
+ public override string Scheme
+ {
+ get { return "soap.amqp"; }
+ }
+
+ /// <summary>
+ /// Specifies the broker host
+ /// </summary>
+ [ConfigurationProperty("host")]
+ public string Host
+ {
+ get { return _host; }
+ set { _host = value; }
+ }
+
+ /// <summary>
+ /// Specifies the broker port
+ /// </summary>
+ public int PortNumber
+ {
+ get { return _port; }
+ set { _port = value; }
+ }
+
+ /// <summary>
+ /// Specifies the username
+ /// </summary>
+ public string UserName
+ {
+ get { return _username; }
+ set { _username = value; }
+ }
+
+ /// <summary>
+ /// Specifies the password
+ /// </summary>
+ public string Password
+ {
+ get { return _password; }
+ set { _password = value; }
+ }
+
+ /// <summary>
+ /// Specifies the virtualhost
+ /// </summary>
+ public string VirtualHost
+ {
+ get { return _virtuaHost; }
+ set { _virtuaHost = value; }
+ }
+
+
+ /// <summary>
+ /// Gets the AMQP _transport binding element
+ /// </summary>
+ public QpidTransportBindingElement Transport
+ {
+ get { return _transport; }
+ }
+
+ /// <summary>
+ /// Gets the reliable _session parameters for this binding instance
+ /// </summary>
+ public ReliableSession ReliableSession
+ {
+ get { return new ReliableSession(_session); }
+ }
+
+ /// <summary>
+ /// Determines whether or not the TransactionFlowBindingElement will
+ /// be added to the channel stack
+ /// </summary>
+ public bool TransactionFlow
+ {
+ get { return _transactionsEnabled; }
+ set { _transactionsEnabled = value; }
+ }
+
+ /// <summary>
+ /// Specifies whether or not the CompositeDuplex and ReliableSession
+ /// binding elements are added to the channel stack.
+ /// </summary>
+ public bool OneWayOnly
+ {
+ get { return _oneWayOnly; }
+ set { _oneWayOnly = value; }
+ }
+ }
+} \ No newline at end of file
diff --git a/qpid/dotnet/client-010/wcf/model/QpidChannelBase.cs b/qpid/dotnet/client-010/wcf/model/QpidChannelBase.cs
new file mode 100644
index 0000000000..174c28e108
--- /dev/null
+++ b/qpid/dotnet/client-010/wcf/model/QpidChannelBase.cs
@@ -0,0 +1,167 @@
+/*
+*
+* 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.
+*
+*/
+
+using System;
+using System.ServiceModel;
+using System.ServiceModel.Channels;
+
+namespace org.apache.qpid.wcf.model
+{
+ internal abstract class QpidChannelBase : IChannel
+ {
+ private readonly CommunicationOperation _closeMethod;
+ private readonly BindingContext _context;
+ private readonly CommunicationOperation _openMethod;
+ private CommunicationState _state;
+
+ private QpidChannelBase()
+ {
+ _state = CommunicationState.Created;
+ _closeMethod = Close;
+ _openMethod = Open;
+ }
+
+ protected QpidChannelBase(BindingContext context)
+ : this()
+ {
+ _context = context;
+ }
+
+ public abstract void Close(TimeSpan timeout);
+
+ public abstract void Open(TimeSpan timeout);
+
+ public virtual void Abort()
+ {
+ Close();
+ }
+
+ public virtual void Close()
+ {
+ Close(_context.Binding.CloseTimeout);
+ }
+
+ public virtual T GetProperty<T>() where T : class
+ {
+ return default(T);
+ }
+
+ public virtual void Open()
+ {
+ Open(_context.Binding.OpenTimeout);
+ }
+
+ #region Async Methods
+
+ public virtual IAsyncResult BeginClose(TimeSpan timeout, AsyncCallback callback, object state)
+ {
+ return _closeMethod.BeginInvoke(timeout, callback, state);
+ }
+
+ public virtual IAsyncResult BeginClose(AsyncCallback callback, object state)
+ {
+ return _closeMethod.BeginInvoke(_context.Binding.CloseTimeout, callback, state);
+ }
+
+ public virtual IAsyncResult BeginOpen(TimeSpan timeout, AsyncCallback callback, object state)
+ {
+ return _openMethod.BeginInvoke(timeout, callback, state);
+ }
+
+ public virtual IAsyncResult BeginOpen(AsyncCallback callback, object state)
+ {
+ return _openMethod.BeginInvoke(_context.Binding.OpenTimeout, callback, state);
+ }
+
+ public virtual void EndClose(IAsyncResult result)
+ {
+ _closeMethod.EndInvoke(result);
+ }
+
+ public virtual void EndOpen(IAsyncResult result)
+ {
+ _openMethod.EndInvoke(result);
+ }
+
+ #endregion
+
+ #region Event Raising Methods
+
+ protected void OnOpening()
+ {
+ _state = CommunicationState.Opening;
+ if (Opening != null)
+ Opening(this, null);
+ }
+
+ protected void OnOpened()
+ {
+ _state = CommunicationState.Opened;
+ if (Opened != null)
+ Opened(this, null);
+ }
+
+ protected void OnClosing()
+ {
+ _state = CommunicationState.Closing;
+ if (Closing != null)
+ Closing(this, null);
+ }
+
+ protected void OnClosed()
+ {
+ _state = CommunicationState.Closed;
+ if (Closed != null)
+ Closed(this, null);
+ }
+
+ protected void OnFaulted()
+ {
+ _state = CommunicationState.Faulted;
+ if (Faulted != null)
+ Faulted(this, null);
+ }
+
+ #endregion
+
+
+ public CommunicationState State
+ {
+ get { return _state; }
+ }
+
+ protected BindingContext Context
+ {
+ get { return _context; }
+ }
+
+
+ public event EventHandler Closed;
+
+ public event EventHandler Closing;
+
+ public event EventHandler Faulted;
+
+ public event EventHandler Opened;
+
+ public event EventHandler Opening;
+ }
+}
diff --git a/qpid/dotnet/client-010/wcf/model/QpidChannelFactory.cs b/qpid/dotnet/client-010/wcf/model/QpidChannelFactory.cs
new file mode 100644
index 0000000000..84518cb1c3
--- /dev/null
+++ b/qpid/dotnet/client-010/wcf/model/QpidChannelFactory.cs
@@ -0,0 +1,74 @@
+/*
+*
+* 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.
+*
+*/
+
+using System;
+using System.ServiceModel;
+using System.ServiceModel.Channels;
+using org.apache.qpid.client;
+
+namespace org.apache.qpid.wcf.model
+{
+ public class QpidChannelFactory : ChannelFactoryBase<IOutputChannel>
+ {
+ private readonly BindingContext _context;
+ private readonly CommunicationOperation _openMethod;
+ private readonly QpidTransportBindingElement _bindingElement;
+ private ClientSession _session;
+
+ public QpidChannelFactory(BindingContext context)
+ {
+ _context = context;
+ _openMethod = Open;
+ _bindingElement = context.Binding.Elements.Find<QpidTransportBindingElement>();
+ }
+
+ protected override IOutputChannel OnCreateChannel(EndpointAddress address, Uri via)
+ {
+ return new QpidOutputChannel(_context, _session, address);
+ }
+
+ protected override IAsyncResult OnBeginOpen(TimeSpan timeout, AsyncCallback callback, object state)
+ {
+ return _openMethod.BeginInvoke(timeout, callback, state);
+ }
+
+ protected override void OnEndOpen(IAsyncResult result)
+ {
+ _openMethod.EndInvoke(result);
+ }
+
+ protected override void OnOpen(TimeSpan timeout)
+ {
+ _session = _bindingElement.Open(timeout.Milliseconds);
+ }
+
+ protected override void OnClose(TimeSpan timeout)
+ {
+ _bindingElement.Close();
+ }
+
+ protected override void OnAbort()
+ {
+ base.OnAbort();
+ OnClose(_context.Binding.CloseTimeout);
+ }
+ }
+}
diff --git a/qpid/dotnet/client-010/wcf/model/QpidChannelListener.cs b/qpid/dotnet/client-010/wcf/model/QpidChannelListener.cs
new file mode 100644
index 0000000000..f776fce9a5
--- /dev/null
+++ b/qpid/dotnet/client-010/wcf/model/QpidChannelListener.cs
@@ -0,0 +1,79 @@
+/*
+*
+* 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.
+*
+*/
+
+using System;
+using System.ServiceModel;
+using System.ServiceModel.Channels;
+using org.apache.qpid.client;
+
+namespace org.apache.qpid.wcf.model
+{
+ public sealed class QpidChannelListener : QpidChannelListenerBase<IInputChannel>
+ {
+
+ private IInputChannel _channel;
+ private ClientSession _session;
+
+ public QpidChannelListener(BindingContext context)
+ : base(context)
+ {
+ _channel = null;
+ _session = null;
+ }
+
+ protected override IInputChannel OnAcceptChannel(TimeSpan timeout)
+ {
+ // Since only one connection to a broker is required (even for communication
+ // with multiple exchanges
+ if (_channel != null)
+ return null;
+
+ _channel = new QpidInputChannel(Context, _session, new EndpointAddress(Uri.ToString()));
+ _channel.Closed += ListenChannelClosed;
+ return _channel;
+ }
+
+ protected override bool OnWaitForChannel(TimeSpan timeout)
+ {
+ return false;
+ }
+
+ protected override void OnOpen(TimeSpan timeout)
+ {
+ _session = _bindingElement.Open(timeout.Milliseconds);
+ }
+
+ protected override void OnClose(TimeSpan timeout)
+ {
+ if (_channel != null)
+ {
+ _channel.Close();
+ _channel = null;
+ }
+ _bindingElement.Close();
+ }
+
+ private void ListenChannelClosed(object sender, EventArgs args)
+ {
+ Close();
+ }
+}
+}
diff --git a/qpid/dotnet/client-010/wcf/model/QpidChannelListenerBase.cs b/qpid/dotnet/client-010/wcf/model/QpidChannelListenerBase.cs
new file mode 100644
index 0000000000..bdecb38c9d
--- /dev/null
+++ b/qpid/dotnet/client-010/wcf/model/QpidChannelListenerBase.cs
@@ -0,0 +1,111 @@
+/*
+*
+* 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.
+*
+*/
+
+using System;
+using System.ServiceModel.Channels;
+using System.ServiceModel.Description;
+
+namespace org.apache.qpid.wcf.model
+{
+ public abstract class QpidChannelListenerBase<TChannel> : ChannelListenerBase<TChannel> where TChannel: class, IChannel
+ {
+ private readonly Uri _listenUri;
+ private readonly BindingContext _context;
+ protected QpidTransportBindingElement _bindingElement;
+ private readonly CommunicationOperation _closeMethod;
+ private readonly CommunicationOperation _openMethod;
+ private readonly CommunicationOperation<TChannel> _acceptChannelMethod;
+ private readonly CommunicationOperation<bool> _waitForChannelMethod;
+
+ protected QpidChannelListenerBase(BindingContext context)
+ {
+ _context = context;
+ _bindingElement = context.Binding.Elements.Find<QpidTransportBindingElement>();
+ _closeMethod = OnClose;
+ _openMethod = OnOpen;
+ _waitForChannelMethod = OnWaitForChannel;
+ _acceptChannelMethod = OnAcceptChannel;
+ if (context.ListenUriMode == ListenUriMode.Explicit && context.ListenUriBaseAddress != null)
+ {
+ _listenUri = new Uri(context.ListenUriBaseAddress, context.ListenUriRelativeAddress);
+ }
+ else
+ {
+ _listenUri = new Uri(new Uri("soap.amqp:///"), Guid.NewGuid().ToString());
+ }
+ }
+
+ protected override void OnAbort()
+ {
+ OnClose(_context.Binding.CloseTimeout);
+ }
+
+ protected override IAsyncResult OnBeginAcceptChannel(TimeSpan timeout, AsyncCallback callback, object state)
+ {
+ return _acceptChannelMethod.BeginInvoke(timeout, callback, state);
+ }
+
+ protected override TChannel OnEndAcceptChannel(IAsyncResult result)
+ {
+ return _acceptChannelMethod.EndInvoke(result);
+ }
+
+ protected override IAsyncResult OnBeginWaitForChannel(TimeSpan timeout, AsyncCallback callback, object state)
+ {
+ return _waitForChannelMethod.BeginInvoke(timeout, callback, state);
+ }
+
+ protected override bool OnEndWaitForChannel(IAsyncResult result)
+ {
+ return _waitForChannelMethod.EndInvoke(result);
+ }
+
+ protected override IAsyncResult OnBeginClose(TimeSpan timeout, AsyncCallback callback, object state)
+ {
+ return _closeMethod.BeginInvoke(timeout, callback, state);
+ }
+
+ protected override IAsyncResult OnBeginOpen(TimeSpan timeout, AsyncCallback callback, object state)
+ {
+ return _openMethod.BeginInvoke(timeout, callback, state);
+ }
+
+ protected override void OnEndClose(IAsyncResult result)
+ {
+ _closeMethod.EndInvoke(result);
+ }
+
+ protected override void OnEndOpen(IAsyncResult result)
+ {
+ _openMethod.EndInvoke(result);
+ }
+
+ public override Uri Uri
+ {
+ get { return _listenUri; }
+ }
+
+ protected BindingContext Context
+ {
+ get { return _context; }
+ }
+ }
+}
diff --git a/qpid/dotnet/client-010/wcf/model/QpidInputChannel.cs b/qpid/dotnet/client-010/wcf/model/QpidInputChannel.cs
new file mode 100644
index 0000000000..7a05153df9
--- /dev/null
+++ b/qpid/dotnet/client-010/wcf/model/QpidInputChannel.cs
@@ -0,0 +1,218 @@
+/*
+*
+* 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.
+*
+*/
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.ServiceModel;
+using System.ServiceModel.Channels;
+using System.Text;
+using System.Threading;
+using org.apache.qpid.client;
+using org.apache.qpid.transport;
+using org.apache.qpid.transport.util;
+
+namespace org.apache.qpid.wcf.model
+{
+ internal sealed class QpidInputChannel : QpidInputChannelBase
+ {
+ private static readonly Logger _log = Logger.get(typeof (QpidInputChannel));
+
+ private readonly QpidTransportBindingElement _bindingElement;
+ private readonly MessageEncoder _encoder;
+ private readonly ClientSession _session;
+ private readonly string _queueName;
+ private BlockingQueue _queue;
+ private bool _closed = false;
+
+ public QpidInputChannel(BindingContext context, ClientSession session, EndpointAddress address)
+ : base(context, address)
+ {
+ _bindingElement = context.Binding.Elements.Find<QpidTransportBindingElement>();
+ var encoderElem = context.BindingParameters.Find<MessageEncodingBindingElement>();
+ if (encoderElem != null)
+ {
+ _encoder = encoderElem.CreateMessageEncoderFactory().Encoder;
+ }
+ _session = session;
+ _queueName = address.Uri.ToString();
+ _queue = new BlockingQueue();
+ }
+
+
+ public override System.ServiceModel.Channels.Message Receive(TimeSpan timeout)
+ {
+ _session.messageFlow("myDest", MessageCreditUnit.MESSAGE, 1);
+ _session.sync();
+ IMessage m = _queue.Dequeue();
+ System.ServiceModel.Channels.Message result = null;
+ if (m != null)
+ {
+ var reader = new BinaryReader(m.Body, Encoding.UTF8);
+ var body = new byte[m.Body.Length - m.Body.Position];
+ reader.Read(body, 0, body.Length);
+ try
+ {
+ result = _encoder.ReadMessage(new MemoryStream(body),
+ (int) _bindingElement.MaxReceivedMessageSize);
+ }
+ catch(Exception e)
+ {
+ Console.WriteLine(e.StackTrace);
+ }
+ result.Headers.To = LocalAddress.Uri;
+
+ var ack = new RangeSet();
+ // ack this message
+ ack.add(m.Id);
+ _session.messageAccept(ack);
+ _session.sync();
+ }
+ else
+ {
+ if(! _closed )
+ {
+ return Receive(timeout);
+ }
+ }
+ return result;
+ }
+
+ public override bool TryReceive(TimeSpan timeout, out System.ServiceModel.Channels.Message message)
+ {
+ message = Receive(timeout);
+ return message != null;
+ }
+
+ public override bool WaitForMessage(TimeSpan timeout)
+ {
+ throw new NotImplementedException();
+ }
+
+ public override void Close(TimeSpan timeout)
+ {
+ _closed = true;
+ _queue = null;
+ }
+
+ public override void Open(TimeSpan timeout)
+ {
+ if (State != CommunicationState.Created && State != CommunicationState.Closed)
+ throw new InvalidOperationException(string.Format("Cannot open the channel from the {0} state.", State));
+
+ OnOpening();
+
+ var qr = (QueueQueryResult) _session.queueQuery(_queueName).Result;
+ if (qr.getQueue() == null)
+ {
+ // create the queue
+ _session.queueDeclare(_queueName, null, null);
+ }
+ // bind the queue
+ _session.exchangeBind(_queueName, "amq.direct", _queueName, null);
+ var myListener = new WCFListener(_queue);
+ _session.attachMessageListener(myListener, "myDest");
+ _session.messageSubscribe(_queueName, "myDest", MessageAcceptMode.EXPLICIT, MessageAcquireMode.PRE_ACQUIRED,
+ null,
+ 0, null);
+ // issue credits
+ _session.messageSetFlowMode("myDest", MessageFlowMode.WINDOW);
+ _session.messageFlow("myDest", MessageCreditUnit.BYTE, ClientSession.MESSAGE_FLOW_MAX_BYTES);
+ _session.sync();
+
+ OnOpened();
+ }
+ }
+
+ internal class WCFListener : IMessageListener
+ {
+ private static readonly Logger _log = Logger.get(typeof (WCFListener));
+ private readonly BlockingQueue _q;
+
+ public WCFListener(BlockingQueue q)
+ {
+ _q = q;
+ }
+
+ public void messageTransfer(IMessage m)
+ {
+ _log.debug("message received by listener");
+ _q.Enqueue(m);
+ }
+ }
+
+ internal class BlockingQueue
+ {
+ private int _count;
+ private readonly Queue<IMessage> _queue = new Queue<IMessage>();
+
+ public IMessage Dequeue(TimeSpan timeout)
+ {
+ lock (_queue)
+ {
+ DateTime start = DateTime.Now;
+ long elapsed = 0;
+ while (_count <= 0 && elapsed < timeout.Milliseconds)
+ {
+ Monitor.Wait(_queue, new TimeSpan(timeout.Milliseconds - elapsed));
+ elapsed = DateTime.Now.Subtract(start).Milliseconds;
+ }
+ if (_count > 0)
+ {
+ _count--;
+ return _queue.Dequeue();
+ }
+ return null;
+ }
+ }
+
+ public IMessage Dequeue()
+ {
+ lock (_queue)
+ {
+ while (_count <= 0)
+ {
+ Monitor.Wait(_queue);
+ }
+ if (_count > 0)
+ {
+ _count--;
+ return _queue.Dequeue();
+ }
+ return null;
+ }
+ }
+
+ public void Enqueue(IMessage data)
+ {
+ if (data != null)
+ {
+ lock (_queue)
+ {
+ _queue.Enqueue(data);
+ _count++;
+ Monitor.Pulse(_queue);
+ }
+ }
+ }
+ }
+}
+
diff --git a/qpid/dotnet/client-010/wcf/model/QpidInputChannelBase.cs b/qpid/dotnet/client-010/wcf/model/QpidInputChannelBase.cs
new file mode 100644
index 0000000000..0bd9e85c0a
--- /dev/null
+++ b/qpid/dotnet/client-010/wcf/model/QpidInputChannelBase.cs
@@ -0,0 +1,101 @@
+/*
+*
+* 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.
+*
+*/
+
+using System;
+using System.ServiceModel;
+using System.ServiceModel.Channels;
+
+namespace org.apache.qpid.wcf.model
+{
+ internal abstract class QpidInputChannelBase : QpidChannelBase, IInputChannel
+ {
+ private readonly EndpointAddress _localAddress;
+ private readonly CommunicationOperation<Message> _receiveMethod;
+ private readonly CommunicationOperation<bool, Message> _tryReceiveMethod;
+ private readonly CommunicationOperation<bool> _waitForMessage;
+
+
+ protected QpidInputChannelBase(BindingContext context, EndpointAddress localAddress)
+ :base(context)
+ {
+ _localAddress = localAddress;
+ _receiveMethod = Receive;
+ _tryReceiveMethod = TryReceive;
+ _waitForMessage = WaitForMessage;
+ }
+
+
+ #region Async Methods
+ public virtual IAsyncResult BeginReceive(TimeSpan timeout, AsyncCallback callback, object state)
+ {
+ return _receiveMethod.BeginInvoke(timeout, callback, state);
+ }
+
+ public virtual IAsyncResult BeginReceive(AsyncCallback callback, object state)
+ {
+ return _receiveMethod.BeginInvoke(Context.Binding.ReceiveTimeout, callback, state);
+ }
+
+ public virtual IAsyncResult BeginTryReceive(TimeSpan timeout, AsyncCallback callback, object state)
+ {
+ Message message;
+ return _tryReceiveMethod.BeginInvoke(timeout, out message, callback, state);
+ }
+
+ public virtual IAsyncResult BeginWaitForMessage(TimeSpan timeout, AsyncCallback callback, object state)
+ {
+ return _waitForMessage.BeginInvoke(timeout, callback, state);
+ }
+
+ public virtual Message EndReceive(IAsyncResult result)
+ {
+ return _receiveMethod.EndInvoke(result);
+ }
+
+ public virtual bool EndTryReceive(IAsyncResult result, out Message message)
+ {
+ return _tryReceiveMethod.EndInvoke(out message, result);
+ }
+
+ public virtual bool EndWaitForMessage(IAsyncResult result)
+ {
+ return _waitForMessage.EndInvoke(result);
+ }
+ #endregion
+
+ public abstract Message Receive(TimeSpan timeout);
+
+ public abstract bool TryReceive(TimeSpan timeout, out Message message);
+
+ public abstract bool WaitForMessage(TimeSpan timeout);
+
+ public virtual Message Receive()
+ {
+ return Receive(Context.Binding.ReceiveTimeout);
+ }
+
+
+ public EndpointAddress LocalAddress
+ {
+ get { return _localAddress; }
+ }
+ }
+}
diff --git a/qpid/dotnet/client-010/wcf/model/QpidOutputChannel.cs b/qpid/dotnet/client-010/wcf/model/QpidOutputChannel.cs
new file mode 100644
index 0000000000..f53ed9b9b8
--- /dev/null
+++ b/qpid/dotnet/client-010/wcf/model/QpidOutputChannel.cs
@@ -0,0 +1,89 @@
+/*
+*
+* 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.
+*
+*/
+
+using System;
+using System.IO;
+using System.ServiceModel;
+using System.ServiceModel.Channels;
+using org.apache.qpid.client;
+using org.apache.qpid.transport;
+using org.apache.qpid.transport.util;
+
+namespace org.apache.qpid.wcf.model
+{
+ internal sealed class QpidOutputChannel : QpidOutputChannelBase
+ {
+ private readonly MessageEncoder _encoder;
+ private readonly ClientSession _session;
+ private readonly string _queueName;
+
+ public QpidOutputChannel(BindingContext context, ClientSession session, EndpointAddress address)
+ : base(context, address)
+ {
+ var encoderElement = context.Binding.Elements.Find<MessageEncodingBindingElement>();
+ if (encoderElement != null)
+ {
+ _encoder = encoderElement.CreateMessageEncoderFactory().Encoder;
+ }
+ _queueName = address.Uri.ToString();
+ _session = session;
+ }
+
+ public override void Send(System.ServiceModel.Channels.Message message, TimeSpan timeout)
+ {
+ if (message.State != MessageState.Closed)
+ {
+ byte[] body;
+ using (var str = new MemoryStream())
+ {
+ _encoder.WriteMessage(message, str);
+ body = str.ToArray();
+ }
+ _session.messageTransfer("amq.direct", MessageAcceptMode.NONE, MessageAcquireMode.PRE_ACQUIRED,
+ new Header(new DeliveryProperties().setRoutingKey(_queueName),
+ new transport.MessageProperties().setMessageId(UUID.randomUUID())),
+ body);
+ }
+ }
+
+ public override void Close(TimeSpan timeout)
+ {
+ if (State == CommunicationState.Closed || State == CommunicationState.Closing)
+ return; // Ignore the call, we're already closing.
+ OnClosing();
+ OnClosed();
+ }
+
+ public override void Open(TimeSpan timeout)
+ {
+ if (State != CommunicationState.Created && State != CommunicationState.Closed)
+ throw new InvalidOperationException(string.Format("Cannot open the channel from the {0} state.", State));
+ OnOpening();
+ var qr = (QueueQueryResult) _session.queueQuery(_queueName).Result;
+ if (qr.getQueue() == null)
+ {
+ // create the queue
+ _session.queueDeclare(_queueName, null, null);
+ }
+ OnOpened();
+ }
+ }
+}
diff --git a/qpid/dotnet/client-010/wcf/model/QpidOutputChannelBase.cs b/qpid/dotnet/client-010/wcf/model/QpidOutputChannelBase.cs
new file mode 100644
index 0000000000..a3cd9020ff
--- /dev/null
+++ b/qpid/dotnet/client-010/wcf/model/QpidOutputChannelBase.cs
@@ -0,0 +1,77 @@
+/*
+*
+* 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.
+*
+*/
+
+using System;
+using System.ServiceModel;
+using System.ServiceModel.Channels;
+
+namespace org.apache.qpid.wcf.model
+{
+ internal abstract class QpidOutputChannelBase : QpidChannelBase, IOutputChannel
+ {
+
+ private readonly SendOperation _sendMethod;
+ private readonly EndpointAddress _address;
+
+ protected QpidOutputChannelBase(BindingContext context, EndpointAddress address)
+ : base(context)
+ {
+ _address = address;
+ _sendMethod = Send;
+ }
+
+ #region Async Methods
+
+ public IAsyncResult BeginSend(Message message, TimeSpan timeout, AsyncCallback callback, object state)
+ {
+ return _sendMethod.BeginInvoke(message, timeout, callback, state);
+ }
+
+ public IAsyncResult BeginSend(Message message, AsyncCallback callback, object state)
+ {
+ return _sendMethod.BeginInvoke(message, Context.Binding.SendTimeout, callback, state);
+ }
+
+ public void EndSend(IAsyncResult result)
+ {
+ _sendMethod.EndInvoke(result);
+ }
+
+ #endregion
+
+ public abstract void Send(Message message, TimeSpan timeout);
+
+ public virtual void Send(Message message)
+ {
+ Send(message, Context.Binding.SendTimeout);
+ }
+
+ public EndpointAddress RemoteAddress
+ {
+ get { return _address; }
+ }
+
+ public Uri Via
+ {
+ get { throw new NotImplementedException(); }
+ }
+ }
+}
diff --git a/qpid/dotnet/client-010/wcf/model/QpidTransportBindingElement.cs b/qpid/dotnet/client-010/wcf/model/QpidTransportBindingElement.cs
new file mode 100644
index 0000000000..50cc80422a
--- /dev/null
+++ b/qpid/dotnet/client-010/wcf/model/QpidTransportBindingElement.cs
@@ -0,0 +1,186 @@
+/*
+*
+* 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.
+*
+*/
+
+using System;
+using System.Configuration;
+using System.ServiceModel.Channels;
+using org.apache.qpid.client;
+
+namespace org.apache.qpid.wcf.model
+{
+ public sealed class QpidTransportBindingElement : TransportBindingElement
+ {
+ private Client _connection;
+ private string _host;
+ private int _port;
+ private string _username;
+ private string _password;
+ private string _virtuaHost;
+
+ /// <summary>
+ /// Creates a new instance of the QpidTransportBindingElement Class
+ /// </summary>
+ public QpidTransportBindingElement()
+ {
+ _host = "localhost";
+ _port = 5672;
+ _username = "guest";
+ _password = "guest";
+ _virtuaHost = "test";
+ }
+
+ private QpidTransportBindingElement(QpidTransportBindingElement other)
+ : this()
+ {
+ Connection = other.Connection;
+ Host = other.Host;
+ PortNumber = other.PortNumber;
+ UserName = other.UserName;
+ Password = other.Password;
+ }
+
+
+ public override IChannelFactory<TChannel> BuildChannelFactory<TChannel>(BindingContext context)
+ {
+ if (Host == null)
+ throw new InvalidOperationException("No broker was specified.");
+ return (IChannelFactory<TChannel>) new QpidChannelFactory(context);
+ }
+
+ public override IChannelListener<TChannel> BuildChannelListener<TChannel>(BindingContext context)
+ {
+ if (Host == null)
+ throw new InvalidOperationException("No broker was specified.");
+
+ return (IChannelListener<TChannel>) ((object) new QpidChannelListener(context));
+ }
+
+ public override bool CanBuildChannelFactory<TChannel>(BindingContext context)
+ {
+ return typeof (TChannel) == typeof (IOutputChannel);
+ }
+
+ public override bool CanBuildChannelListener<TChannel>(BindingContext context)
+ {
+ return typeof (TChannel) == typeof (IInputChannel);
+ }
+
+ public override BindingElement Clone()
+ {
+ return new QpidTransportBindingElement(this);
+ }
+
+ public override T GetProperty<T>(BindingContext context)
+ {
+ return context.GetInnerProperty<T>();
+ }
+
+ /// <summary>
+ /// Gets the scheme used by the binding, this is 0.10 as default for now.
+ /// </summary>
+ public override string Scheme
+ {
+ get { return "soap.amqp"; }
+ }
+
+
+ /// <summary>
+ /// Specifies the broker host
+ /// </summary>
+ [ConfigurationProperty("host")]
+ public string Host
+ {
+ get { return _host; }
+ set { _host = value; }
+ }
+
+ /// <summary>
+ /// Specifies the broker port
+ /// </summary>
+ public int PortNumber
+ {
+ get { return _port; }
+ set { _port = value; }
+ }
+
+ /// <summary>
+ /// Specifies the username
+ /// </summary>
+ public string UserName
+ {
+ get { return _username; }
+ set { _username = value; }
+ }
+
+ /// <summary>
+ /// Specifies the password
+ /// </summary>
+ public string Password
+ {
+ get { return _password; }
+ set { _password = value; }
+ }
+
+ /// <summary>
+ /// Specifies the virtualhost
+ /// </summary>
+ public string VirtualHost
+ {
+ get { return _virtuaHost; }
+ set { _virtuaHost = value; }
+ }
+
+ /// <summary>
+ /// Specifies the connection
+ /// </summary>
+ public Client Connection
+ {
+ get { return _connection; }
+ set { _connection = value; }
+ }
+
+
+ internal ClientSession Open(long timeout)
+ {
+ if (Connection == null)
+ {
+ Connection = new Client();
+ }
+ Connection.connect(Host, PortNumber, VirtualHost, UserName, Password);
+ return Connection.createSession(timeout);
+ }
+
+ internal void Close()
+ {
+ if (Connection != null)
+ {
+ try
+ {
+ Connection.close();
+ }
+ catch (Exception e)
+ {
+ // todo log it
+ }
+ }
+ }
+ }
+}
diff --git a/qpid/dotnet/client-010/wcf/model/QpidTransportElement.cs b/qpid/dotnet/client-010/wcf/model/QpidTransportElement.cs
new file mode 100644
index 0000000000..f531186148
--- /dev/null
+++ b/qpid/dotnet/client-010/wcf/model/QpidTransportElement.cs
@@ -0,0 +1,183 @@
+/*
+*
+* 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.
+*
+*/
+
+using System;
+using System.Configuration;
+using System.Reflection;
+using System.ServiceModel.Channels;
+using System.ServiceModel.Configuration;
+
+namespace org.apache.qpid.wcf.model
+{
+ public sealed class QpidTransportElement : TransportElement
+ {
+
+ public override void ApplyConfiguration(BindingElement bindingElement)
+ {
+ base.ApplyConfiguration(bindingElement);
+ if (bindingElement == null)
+ throw new ArgumentNullException("bindingElement");
+
+ var bindind = bindingElement as QpidTransportBindingElement;
+ if (bindind == null)
+ {
+ throw new ArgumentException(
+ string.Format("Invalid type for binding. Expected {0}, Passed: {1}",
+ typeof(QpidTransportBindingElement).AssemblyQualifiedName,
+ bindingElement.GetType().AssemblyQualifiedName));
+ }
+
+ bindind.Host = Host;
+ bindind.Password = Password;
+ bindind.UserName = UserName;
+ bindind.VirtualHost = VirtualHost;
+ bindind.PortNumber = PortNumber;
+ }
+
+ public override void CopyFrom(ServiceModelExtensionElement from)
+ {
+ base.CopyFrom(from);
+ var element = from as QpidTransportElement;
+ if (element != null)
+ {
+ Host = element.Host;
+ PortNumber = element.PortNumber;
+ Password = element.Password;
+ UserName = element.UserName;
+ VirtualHost = element.VirtualHost;
+ }
+ }
+
+ protected override BindingElement CreateBindingElement()
+ {
+ TransportBindingElement element = CreateDefaultBindingElement();
+ ApplyConfiguration(element);
+ return element;
+ }
+
+ protected override TransportBindingElement CreateDefaultBindingElement()
+ {
+ return new QpidTransportBindingElement();
+ }
+
+ protected override void InitializeFrom(BindingElement bindingElement)
+ {
+ base.InitializeFrom(bindingElement);
+
+ if (bindingElement == null)
+ throw new ArgumentNullException("bindingElement");
+
+ var binding = bindingElement as QpidTransportBindingElement;
+ if (binding == null)
+ {
+ throw new ArgumentException(
+ string.Format("Invalid type for binding. Expected {0}, Passed: {1}",
+ typeof(QpidTransportBindingElement).AssemblyQualifiedName,
+ bindingElement.GetType().AssemblyQualifiedName));
+ }
+
+ Host = binding.Host;
+ PortNumber = binding.PortNumber;
+ Password = binding.Password;
+ UserName = binding.UserName;
+ VirtualHost = binding.VirtualHost;
+ }
+
+ public override Type BindingElementType
+ {
+ get { return typeof(QpidTransportElement); }
+ }
+
+
+
+ /// <summary>
+ /// Specifies the broker host name that the binding should connect to.
+ /// </summary>
+ [ConfigurationProperty("host", DefaultValue = "localhost")]
+ public string Host
+ {
+ get { return ((string) base["host"]); }
+ set { base["host"] = value; }
+ }
+
+ /// <summary>
+ /// Specifies the broker port number that the binding should connect to.
+ /// </summary>
+ [ConfigurationProperty("port", DefaultValue = "5672")]
+ public int PortNumber
+ {
+ get { return (Convert.ToInt16(base["port"])); }
+ set { base["port"] = value; }
+ }
+
+ /// <summary>
+ /// Password to use when authenticating with the broker
+ /// </summary>
+ [ConfigurationProperty("password", DefaultValue = "guest")]
+ public string Password
+ {
+ get { return ((string)base["password"]); }
+ set { base["password"] = value; }
+ }
+
+ /// <summary>
+ /// The username to use when authenticating with the broker
+ /// </summary>
+ [ConfigurationProperty("username", DefaultValue = "guest")]
+ public string UserName
+ {
+ get { return ((string)base["username"]); }
+ set { base["username"] = value; }
+ }
+
+
+ /// <summary>
+ /// The virtual host to access.
+ /// </summary>
+ [ConfigurationProperty("virtualHost", DefaultValue = "test")]
+ public string VirtualHost
+ {
+ get { return ((string)base["virtualHost"]); }
+ set { base["virtualHost"] = value; }
+ }
+
+
+ protected override ConfigurationPropertyCollection Properties
+ {
+ get
+ {
+ ConfigurationPropertyCollection configProperties = base.Properties;
+ foreach (PropertyInfo prop in GetType().GetProperties(BindingFlags.DeclaredOnly
+ | BindingFlags.Public
+ | BindingFlags.Instance))
+ {
+ foreach (ConfigurationPropertyAttribute attr in prop.GetCustomAttributes(typeof(ConfigurationPropertyAttribute), false))
+ {
+ configProperties.Add(
+ new ConfigurationProperty(attr.Name, prop.PropertyType, attr.DefaultValue));
+ }
+ }
+
+ return configProperties;
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/qpid/dotnet/client-010/wcf/wcf.csproj b/qpid/dotnet/client-010/wcf/wcf.csproj
new file mode 100644
index 0000000000..f07c5ab1fd
--- /dev/null
+++ b/qpid/dotnet/client-010/wcf/wcf.csproj
@@ -0,0 +1,79 @@
+<?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.
+ -
+ -->
+<Project ToolsVersion="3.5" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProductVersion>9.0.30729</ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{F1D80D9D-FE22-4213-A760-BFFDE7D131DD}</ProjectGuid>
+ <OutputType>Library</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>WCF</RootNamespace>
+ <AssemblyName>qpidWCFModel</AssemblyName>
+ <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
+ <FileAlignment>512</FileAlignment>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="Qpid Client, Version=0.10.0.0, Culture=neutral, processorArchitecture=MSIL">
+ <SpecificVersion>False</SpecificVersion>
+ <HintPath>..\client\bin\Debug\Qpid Client.dll</HintPath>
+ </Reference>
+ <Reference Include="System" />
+ <Reference Include="System.configuration" />
+ <Reference Include="System.ServiceModel">
+ <RequiredTargetFramework>3.0</RequiredTargetFramework>
+ </Reference>
+ <Reference Include="System.Data" />
+ <Reference Include="System.Windows.Forms" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="model\*.cs" />
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ </ItemGroup>
+ <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+ <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
+ Other similar extension points exist, see Microsoft.Common.targets.
+ <Target Name="BeforeBuild">
+ </Target>
+ <Target Name="AfterBuild">
+ </Target>
+ -->
+</Project> \ No newline at end of file
diff --git a/qpid/dotnet/client-010/wcf/wcf.sln b/qpid/dotnet/client-010/wcf/wcf.sln
new file mode 100644
index 0000000000..8120f44576
--- /dev/null
+++ b/qpid/dotnet/client-010/wcf/wcf.sln
@@ -0,0 +1,70 @@
+
+Microsoft Visual Studio Solution File, Format Version 10.00
+# Visual Studio 2008
+
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "wcfHelloClient", "demo\wcfHelloClient\wcfHelloClient.csproj", "{A24E27DB-A38D-40C9-9879-8390B68C2F06}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "wcfHelloServer", "demo\wcfHelloServer\wcfHelloServer.csproj", "{3EF848D7-5FAC-482C-922A-D4D45A4CCD2A}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "wcfRPC", "demo\wcfRPC\wcfRPC.csproj", "{C988F456-1025-486F-9BCD-49C0F83B91DB}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "wcBookingClient", "demo\wcfBookingClient\wcBookingClient.csproj", "{4086B3FE-F745-4DCC-952A-682CAE01F4C9}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "wcfBookingServer", "demo\wcfBookingServer\wcfBookingServer.csproj", "{B34E21C4-A742-4886-8569-1A89490E093E}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "wcf", "wcf.csproj", "{F1D80D9D-FE22-4213-A760-BFFDE7D131DD}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {A24E27DB-A38D-40C9-9879-8390B68C2F06}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {A24E27DB-A38D-40C9-9879-8390B68C2F06}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {A24E27DB-A38D-40C9-9879-8390B68C2F06}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {A24E27DB-A38D-40C9-9879-8390B68C2F06}.Release|Any CPU.Build.0 = Release|Any CPU
+ {3EF848D7-5FAC-482C-922A-D4D45A4CCD2A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {3EF848D7-5FAC-482C-922A-D4D45A4CCD2A}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {3EF848D7-5FAC-482C-922A-D4D45A4CCD2A}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {3EF848D7-5FAC-482C-922A-D4D45A4CCD2A}.Release|Any CPU.Build.0 = Release|Any CPU
+ {C988F456-1025-486F-9BCD-49C0F83B91DB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {C988F456-1025-486F-9BCD-49C0F83B91DB}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {C988F456-1025-486F-9BCD-49C0F83B91DB}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {C988F456-1025-486F-9BCD-49C0F83B91DB}.Release|Any CPU.Build.0 = Release|Any CPU
+ {4086B3FE-F745-4DCC-952A-682CAE01F4C9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {4086B3FE-F745-4DCC-952A-682CAE01F4C9}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {4086B3FE-F745-4DCC-952A-682CAE01F4C9}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {4086B3FE-F745-4DCC-952A-682CAE01F4C9}.Release|Any CPU.Build.0 = Release|Any CPU
+ {B34E21C4-A742-4886-8569-1A89490E093E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {B34E21C4-A742-4886-8569-1A89490E093E}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {B34E21C4-A742-4886-8569-1A89490E093E}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {B34E21C4-A742-4886-8569-1A89490E093E}.Release|Any CPU.Build.0 = Release|Any CPU
+ {F1D80D9D-FE22-4213-A760-BFFDE7D131DD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {F1D80D9D-FE22-4213-A760-BFFDE7D131DD}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {F1D80D9D-FE22-4213-A760-BFFDE7D131DD}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {F1D80D9D-FE22-4213-A760-BFFDE7D131DD}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/qpid/dotnet/client-010/wcf/wcf.suo b/qpid/dotnet/client-010/wcf/wcf.suo
new file mode 100644
index 0000000000..60339d33e4
--- /dev/null
+++ b/qpid/dotnet/client-010/wcf/wcf.suo
Binary files differ
diff --git a/qpid/dotnet/default.build b/qpid/dotnet/default.build
new file mode 100644
index 0000000000..4cd38e90ff
--- /dev/null
+++ b/qpid/dotnet/default.build
@@ -0,0 +1,252 @@
+<?xml version="1.0"?>
+<!--
+
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+
+-->
+
+<project name="Qpid.NET" default="build">
+
+ <!-- Determines the formatter to use to format output of test results. -->
+ <property name="nant.formatter" value="Plain" />
+
+ <!-- Determines whether a 'debug' or 'release' build is to be done. Defaults to 'debug' -->
+ <property name="build.config" value="debug" />
+
+ <!-- Sets build properties consistently accross all assemblies in the project. -->
+ <property name="build.version.major" value="0"/>
+ <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"/>
+ <property name="build.copyright" value="Apache Software Foundation"/>
+ <property name="build.description" value="Built from svn revision number: "/>
+
+ <!-- Fileset with build files for each 'core' assembly. -->
+ <fileset id="src.builds">
+ <include name="Qpid.Buffer/default.build" />
+ <include name="Qpid.Sasl/default.build" />
+ <include name="Qpid.Messaging/default.build" />
+ <include name="Qpid.Codec/default.build" />
+ <include name="Qpid.Common/default.build" />
+ <include name="Qpid.Client/default.build" />
+ </fileset>
+
+ <!-- Fileset with build files for 'pure unit' test assemblies. -->
+ <fileset id="tests.pure.builds">
+ <include name="Qpid.Buffer.Tests/default.build" />
+ <include name="Qpid.Sasl.Tests/default.build" />
+ <include name="Qpid.Common.Tests/default.build" />
+ <include name="Qpid.Client.Tests/default.build" />
+ </fileset>
+
+ <!-- Fileset with build files for 'integration' test assemblies. -->
+ <fileset id="tests.integration.builds">
+ <include name="Qpid.Integration.Tests/default.build" />
+ </fileset>
+
+ <!-- Other test or utility assemblies. -->
+ <fileset id='other.builds'>
+ <include name="TopicListener/default.build" />
+ <include name="TopicPublisher/default.build" />
+ <include name="TestClient/default.build" />
+ </fileset>
+
+ <!-- Prepare environment for a debug build. -->
+ <target name="debug">
+ <property name="build.debug" value="true" />
+ <property name="build.defines" value="DEBUG;TRACE"/>
+ </target>
+
+ <!-- Prepare environment for a release build. -->
+ <target name="release">
+ <property name="build.debug" value="false" />
+ <property name="build.defines" value=""/>
+ </target>
+
+ <!-- Prepare environment for build. -->
+ <target name="init">
+ <property name="base.dir" value="${project::get-base-directory()}" />
+ <property name="build.dir" value="${base.dir}/bin/${framework::get-target-framework()}/${build.config}" />
+ <call target="${build.config}" />
+ </target>
+
+ <!-- Cleans up the build output directory. -->
+ <target name="clean" depends="init">
+ <delete dir="${build.dir}" failonerror="false" />
+ </target>
+
+ <!-- Runs 'svnversion' to get the repository revision into the build property 'build.svnversion'. -->
+ <target name="svnversion" description="Runs svnversion to get the current repository version into a build script property.">
+ <exec program="svnversion" output="svnversion_tmp.txt">
+ <arg value="-n"/>
+ </exec>
+
+ <loadfile file="svnversion_tmp.txt" property="build.svnversion"/>
+ <delete file="svnversion_tmp.txt"/>
+
+ <!-- For some competely retarted reason the '-n' parameter to svnversion doesn't really work under windows...
+ Here is some code to strip the unwanted newlines. -->
+ <script language="C#">
+ <code><![CDATA[
+ public static void ScriptMain(Project project)
+ {
+ project.Properties["build.svnversion"] = project.Properties["build.svnversion"].Trim("\n\r".ToCharArray());
+ }
+ ]]>
+ </code>
+ </script>
+
+ </target>
+
+ <!-- Performs a regex find-and-replace on assembly info files, substituting fields defined as build properties. -->
+ <target name="setversion" description="Stamp the version info onto assemblyinfo.cs files" depends="svnversion">
+
+ <echo>build.svnversion = ${build.svnversion}</echo>
+
+ <foreach item="File" property="filename">
+ <in>
+ <items basedir=".">
+ <include name="**\AssemblyInfo.cs"></include>
+ </items>
+ </in>
+ <do>
+ <script language="C#">
+ <code><![CDATA[
+ public static void ScriptMain(Project project)
+ {
+ // Read in the entire file to perform the substitution in.
+ StreamReader reader = new StreamReader(project.Properties["filename"]);
+ string contents = reader.ReadToEnd();
+ reader.Close();
+
+ // Substitute the version numbers.
+ string replacement = string.Format("[assembly: AssemblyVersion(\"{0}.{1}.{2}.{3}\")]",
+ project.Properties["build.version.major"],
+ project.Properties["build.version.minor"],
+ project.Properties["build.version.build"],
+ project.Properties["build.version.revision"]);
+ contents = System.Text.RegularExpressions.Regex.Replace(contents, @"\[assembly: AssemblyVersion\("".*""\)\]", replacement);
+
+ // Substitute the company name and copyright.
+ replacement = string.Format("[assembly: AssemblyCompany(\"{0}\")]",
+ project.Properties["build.company"]);
+ contents = System.Text.RegularExpressions.Regex.Replace(contents, @"\[assembly: AssemblyCompany\("".*""\)\]", replacement);
+
+ replacement = string.Format("[assembly: AssemblyCopyright(\"{0}\")]",
+ project.Properties["build.copyright"]);
+ contents = System.Text.RegularExpressions.Regex.Replace(contents, @"\[assembly: AssemblyCopyright\("".*""\)\]", replacement);
+
+ // Update the description.
+ //replacement = string.Format("[assembly: AssemblyDescription(\"{0} {1}\")]",
+ // project.Properties["build.description"],
+ // project.Properties["build.svnversion"]);
+ replacement = string.Format("[assembly: AssemblyDescription(\"{0}\")]",
+ project.Properties["build.description"]);
+ contents = System.Text.RegularExpressions.Regex.Replace(contents, @"\[assembly: AssemblyDescription\("".*""\)\]", replacement);
+
+ // Write out the file with the substituted version.
+ StreamWriter writer = new StreamWriter(project.Properties["filename"], false);
+ writer.Write(contents);
+ writer.Close();
+ }
+ ]]>
+ </code>
+ </script>
+ </do>
+ </foreach>
+ </target>
+
+ <!-- Do the build. -->
+ <target name="build" depends="init, setversion">
+ <echo message="Building all modules including tests."/>
+
+ <!-- Make sure output folder exists. -->
+ <mkdir dir="${build.dir}" />
+
+ <!-- copy reference assemblies over to the output dir -->
+ <copy todir="${build.dir}" file="Qpid.Common/lib/seclib-1.0.0/Org.Mentalis.Security.dll"/>
+ <copy todir="${build.dir}" file="Qpid.Common/lib/log4net/log4net.dll"/>
+ <copy todir="${build.dir}" file="Qpid.Client.Tests/lib/nunit/nunit.framework.dll"/>
+
+ <!-- Compile assemblies. -->
+ <nant target="build">
+ <buildfiles refid="src.builds" />
+ </nant>
+
+ <!-- Compile test assemblies. -->
+ <nant target="build">
+ <buildfiles refid="tests.pure.builds" />
+ </nant>
+ <nant target="build">
+ <buildfiles refid="tests.integration.builds" />
+ </nant>
+
+ <!-- Compile test assemblies. -->
+ <nant target="build">
+ <buildfiles refid="other.builds" />
+ </nant>
+ </target>
+
+ <!-- Runs all 'pure unit' tests. -->
+ <target name="test" depends="build">
+ <echo message="Running all pure unit tests."/>
+ <nant target="test">
+ <buildfiles refid="tests.pure.builds" />
+ </nant>
+ </target>
+
+ <!-- Runs all 'integration' tests. -->
+ <target name="integrationtest" depends="build">
+ <echo message="Running all integration tests."/>
+ <nant target="test">
+ <buildfiles refid="tests.integration.builds" />
+ </nant>
+ </target>
+
+ <!-- Creates a release package. -->
+ <target name="release-pkg">
+ <echo message="Building and packaging a release."/>
+
+ <call target="clean"/>
+ <call target="build"/>
+
+ <property name="build.date" value="${datetime::now()}"/>
+ <property name="build.timestamp" value="${framework::get-target-framework()}-${datetime::get-year(build.date)}${datetime::get-month(build.date)}${datetime::get-day(build.date)}"/>
+
+ <zip zipfile="${build.dir}/Qpid.NET-${build.timestamp}.zip">
+ <fileset basedir="${build.dir}" prefix="Qpid.NET-${build.timestamp}">
+ <include name="**/*.*"/>
+ <exclude name="**/*.Tests.*"/>
+ <exclude name="**/nunit.framework.dll"/>
+ <exclude name="**/*.exe"/>
+ </fileset>
+
+ <fileset basedir="${base.dir}" prefix="Qpid.NET-${build.timestamp}">
+ <include name="LICENSE.txt"/>
+ <include name="NOTICE.txt"/>
+ <include name="README.txt"/>
+ <include name="RELEASE_NOTES.txt"/>
+ <include name="DISCLAIMER"/>
+ </fileset>
+ </zip>
+ </target>
+
+</project>
+
+
diff --git a/qpid/extras/qmf/setup.py b/qpid/extras/qmf/setup.py
index ae35c42375..2e3ec7a38e 100755
--- a/qpid/extras/qmf/setup.py
+++ b/qpid/extras/qmf/setup.py
@@ -20,10 +20,10 @@
from distutils.core import setup
setup(name="qpid-qmf",
- version="0.13",
+ version="0.9",
author="Apache Qpid",
author_email="dev@qpid.apache.org",
- packages=["qmf"],
+ packages=["qmf", "qmf2", "qmf2.tests"],
package_dir={"": "src/py"},
url="http://qpid.apache.org/",
license="Apache Software License",
diff --git a/qpid/extras/qmf/src/py/qmf/console.py b/qpid/extras/qmf/src/py/qmf/console.py
index 291b9bcc5f..6f4c11ae15 100644
--- a/qpid/extras/qmf/src/py/qmf/console.py
+++ b/qpid/extras/qmf/src/py/qmf/console.py
@@ -359,8 +359,8 @@ class Object(object):
for arg in method.arguments:
if arg.dir.find("I") != -1:
count += 1
- if count != len(args) + len(kwargs):
- raise Exception("Incorrect number of arguments: expected %d, got %d" % (count, len(args) + len(kwargs)))
+ if count != len(args):
+ raise Exception("Incorrect number of arguments: expected %d, got %d" % (count, len(args)))
if self._agent.isV2:
#
@@ -372,10 +372,7 @@ class Object(object):
argMap = {}
for arg in method.arguments:
if arg.dir.find("I") != -1:
- if aIdx < len(args):
- argMap[arg.name] = args[aIdx]
- else:
- argMap[arg.name] = kwargs[arg.name]
+ argMap[arg.name] = args[aIdx]
aIdx += 1
call['_arguments'] = argMap
@@ -442,10 +439,6 @@ class Object(object):
else:
sync = True
- # Remove special "meta" kwargs before handing to _sendMethodRequest() to process
- if "_timeout" in kwargs: del kwargs["_timeout"]
- if "_async" in kwargs: del kwargs["_async"]
-
seq = self._sendMethodRequest(name, args, kwargs, sync, timeout)
if seq:
if not sync:
@@ -1218,22 +1211,11 @@ class Session:
try:
agentName = ah["qmf.agent"]
values = content["_values"]
-
- if '_timestamp' in values:
- timestamp = values["_timestamp"]
- else:
- timestamp = values['timestamp']
-
- if '_heartbeat_interval' in values:
- interval = values['_heartbeat_interval']
- else:
- interval = values['heartbeat_interval']
-
+ timestamp = values["_timestamp"]
+ interval = values["_heartbeat_interval"]
epoch = 0
if '_epoch' in values:
epoch = values['_epoch']
- elif 'epoch' in values:
- epoch = values['epoch']
except Exception,e:
return
@@ -2434,7 +2416,7 @@ class Broker(Thread):
if uid.__class__ == tuple and len(uid) == 2:
self.saslUser = uid[1]
else:
- self.saslUser = self.authUser
+ self.saslUser = None
# prevent topic queues from filling up (and causing the agents to
# disconnect) by discarding the oldest queued messages when full.
diff --git a/qpid/extras/qmf/src/py/qmf2-prototype/__init__.py b/qpid/extras/qmf/src/py/qmf2/__init__.py
index 31d5a2ef58..31d5a2ef58 100644
--- a/qpid/extras/qmf/src/py/qmf2-prototype/__init__.py
+++ b/qpid/extras/qmf/src/py/qmf2/__init__.py
diff --git a/qpid/extras/qmf/src/py/qmf2-prototype/agent.py b/qpid/extras/qmf/src/py/qmf2/agent.py
index 4ec00bd288..4ec00bd288 100644
--- a/qpid/extras/qmf/src/py/qmf2-prototype/agent.py
+++ b/qpid/extras/qmf/src/py/qmf2/agent.py
diff --git a/qpid/extras/qmf/src/py/qmf2-prototype/common.py b/qpid/extras/qmf/src/py/qmf2/common.py
index 2e5367f54f..2e5367f54f 100644
--- a/qpid/extras/qmf/src/py/qmf2-prototype/common.py
+++ b/qpid/extras/qmf/src/py/qmf2/common.py
diff --git a/qpid/extras/qmf/src/py/qmf2-prototype/console.py b/qpid/extras/qmf/src/py/qmf2/console.py
index 9227835b3f..9227835b3f 100644
--- a/qpid/extras/qmf/src/py/qmf2-prototype/console.py
+++ b/qpid/extras/qmf/src/py/qmf2/console.py
diff --git a/qpid/extras/qmf/src/py/qmf2-prototype/tests/__init__.py b/qpid/extras/qmf/src/py/qmf2/tests/__init__.py
index eff9357e1f..eff9357e1f 100644
--- a/qpid/extras/qmf/src/py/qmf2-prototype/tests/__init__.py
+++ b/qpid/extras/qmf/src/py/qmf2/tests/__init__.py
diff --git a/qpid/extras/qmf/src/py/qmf2-prototype/tests/agent_discovery.py b/qpid/extras/qmf/src/py/qmf2/tests/agent_discovery.py
index 2c20794aaa..2c20794aaa 100644
--- a/qpid/extras/qmf/src/py/qmf2-prototype/tests/agent_discovery.py
+++ b/qpid/extras/qmf/src/py/qmf2/tests/agent_discovery.py
diff --git a/qpid/extras/qmf/src/py/qmf2-prototype/tests/agent_test.py b/qpid/extras/qmf/src/py/qmf2/tests/agent_test.py
index 14d8ada197..14d8ada197 100644
--- a/qpid/extras/qmf/src/py/qmf2-prototype/tests/agent_test.py
+++ b/qpid/extras/qmf/src/py/qmf2/tests/agent_test.py
diff --git a/qpid/extras/qmf/src/py/qmf2-prototype/tests/async_method.py b/qpid/extras/qmf/src/py/qmf2/tests/async_method.py
index 2339fc71a9..2339fc71a9 100644
--- a/qpid/extras/qmf/src/py/qmf2-prototype/tests/async_method.py
+++ b/qpid/extras/qmf/src/py/qmf2/tests/async_method.py
diff --git a/qpid/extras/qmf/src/py/qmf2-prototype/tests/async_query.py b/qpid/extras/qmf/src/py/qmf2/tests/async_query.py
index b1c01611f7..b1c01611f7 100644
--- a/qpid/extras/qmf/src/py/qmf2-prototype/tests/async_query.py
+++ b/qpid/extras/qmf/src/py/qmf2/tests/async_query.py
diff --git a/qpid/extras/qmf/src/py/qmf2-prototype/tests/basic_method.py b/qpid/extras/qmf/src/py/qmf2/tests/basic_method.py
index 8d038bc4c8..8d038bc4c8 100644
--- a/qpid/extras/qmf/src/py/qmf2-prototype/tests/basic_method.py
+++ b/qpid/extras/qmf/src/py/qmf2/tests/basic_method.py
diff --git a/qpid/extras/qmf/src/py/qmf2-prototype/tests/basic_query.py b/qpid/extras/qmf/src/py/qmf2/tests/basic_query.py
index 9f5dda6d54..9f5dda6d54 100644
--- a/qpid/extras/qmf/src/py/qmf2-prototype/tests/basic_query.py
+++ b/qpid/extras/qmf/src/py/qmf2/tests/basic_query.py
diff --git a/qpid/extras/qmf/src/py/qmf2-prototype/tests/console_test.py b/qpid/extras/qmf/src/py/qmf2/tests/console_test.py
index ac0e064f20..ac0e064f20 100644
--- a/qpid/extras/qmf/src/py/qmf2-prototype/tests/console_test.py
+++ b/qpid/extras/qmf/src/py/qmf2/tests/console_test.py
diff --git a/qpid/extras/qmf/src/py/qmf2-prototype/tests/events.py b/qpid/extras/qmf/src/py/qmf2/tests/events.py
index 624c9b3823..624c9b3823 100644
--- a/qpid/extras/qmf/src/py/qmf2-prototype/tests/events.py
+++ b/qpid/extras/qmf/src/py/qmf2/tests/events.py
diff --git a/qpid/extras/qmf/src/py/qmf2-prototype/tests/multi_response.py b/qpid/extras/qmf/src/py/qmf2/tests/multi_response.py
index 991fa0114e..991fa0114e 100644
--- a/qpid/extras/qmf/src/py/qmf2-prototype/tests/multi_response.py
+++ b/qpid/extras/qmf/src/py/qmf2/tests/multi_response.py
diff --git a/qpid/extras/qmf/src/py/qmf2-prototype/tests/obj_gets.py b/qpid/extras/qmf/src/py/qmf2/tests/obj_gets.py
index 695b096973..695b096973 100644
--- a/qpid/extras/qmf/src/py/qmf2-prototype/tests/obj_gets.py
+++ b/qpid/extras/qmf/src/py/qmf2/tests/obj_gets.py
diff --git a/qpid/extras/qmf/src/py/qmf2-prototype/tests/subscriptions.py b/qpid/extras/qmf/src/py/qmf2/tests/subscriptions.py
index 5c39af4b32..5c39af4b32 100644
--- a/qpid/extras/qmf/src/py/qmf2-prototype/tests/subscriptions.py
+++ b/qpid/extras/qmf/src/py/qmf2/tests/subscriptions.py
diff --git a/qpid/extras/sasl/bootstrap b/qpid/extras/sasl/bootstrap
index 906e5a71e4..32085c325d 100755
--- a/qpid/extras/sasl/bootstrap
+++ b/qpid/extras/sasl/bootstrap
@@ -22,7 +22,7 @@ aclocal -I m4
autoheader
libtoolize --automake
-automake --add-missing
+automake
autoconf
if [ "$1" = "-build" -o "$1" = "--build" ] ; then
diff --git a/qpid/extras/sasl/configure.ac b/qpid/extras/sasl/configure.ac
index 206c2f497d..bc0fadbb31 100644
--- a/qpid/extras/sasl/configure.ac
+++ b/qpid/extras/sasl/configure.ac
@@ -23,6 +23,7 @@ AC_CONFIG_HEADERS([config.h])
AC_PROG_CC_STDC
AM_PROG_CC_C_O
AC_PROG_CXX
+AC_USE_SYSTEM_EXTENSIONS
AC_LANG([C++])
# Check for optional use of help2man
diff --git a/qpid/extras/sasl/python/Makefile.am b/qpid/extras/sasl/python/Makefile.am
index 7c61f37cee..43eef70923 100644
--- a/qpid/extras/sasl/python/Makefile.am
+++ b/qpid/extras/sasl/python/Makefile.am
@@ -29,7 +29,8 @@ BUILT_SOURCES = $(generated_file_list)
$(generated_file_list): python.i $(top_srcdir)/src/saslwrapper.i
$(SWIG) -c++ -python -Wall -I/usr/include $(INCLUDES) -o saslwrapper.cpp $(srcdir)/python.i
-pyexec_PYTHON = saslwrapper.py
+pylibdir = $(PYTHON_LIB)
+python_PYTHON = saslwrapper.py
pyexec_LTLIBRARIES = _saslwrapper.la
_saslwrapper_la_LDFLAGS = -avoid-version -module -shared
diff --git a/qpid/extras/sasl/ruby/Makefile.am b/qpid/extras/sasl/ruby/Makefile.am
index 85fde1085d..da64239323 100644
--- a/qpid/extras/sasl/ruby/Makefile.am
+++ b/qpid/extras/sasl/ruby/Makefile.am
@@ -35,7 +35,7 @@ rubylibarch_LTLIBRARIES = saslwrapper.la
saslwrapper_la_LDFLAGS = -avoid-version -module -shared ".$(RUBY_DLEXT)"
saslwrapper_la_LIBADD = $(RUBY_LIBS) $(top_builddir)/src/libsaslwrapper.la -lsasl2
-saslwrapper_la_CXXFLAGS = $(INCLUDES) -I$(RUBY_INC) -I$(RUBY_INC_ARCH) -fno-strict-aliasing
+saslwrapper_la_CXXFLAGS = $(INCLUDES) -I$(RUBY_INC) -I$(RUBY_INC_ARCH)
nodist_saslwrapper_la_SOURCES = saslwrapper.cpp
CLEANFILES = $(generated_file_list)
diff --git a/qpid/extras/sasl/src/Makefile.am b/qpid/extras/sasl/src/Makefile.am
index c2aa8dd188..25529a3607 100644
--- a/qpid/extras/sasl/src/Makefile.am
+++ b/qpid/extras/sasl/src/Makefile.am
@@ -24,7 +24,6 @@ nobase_include_HEADERS = ../include/saslwrapper.h
lib_LTLIBRARIES = libsaslwrapper.la
libsaslwrapper_la_SOURCES = cyrus/saslwrapper.cpp
-libsaslwrapper_la_CXXFLAGS = -fno-strict-aliasing
# Library Version Information:
#
diff --git a/qpid/java/broker-plugins/access-control/MANIFEST.MF b/qpid/java/broker-plugins/access-control/MANIFEST.MF
index 78072850e4..1cd285ba20 100644
--- a/qpid/java/broker-plugins/access-control/MANIFEST.MF
+++ b/qpid/java/broker-plugins/access-control/MANIFEST.MF
@@ -35,7 +35,6 @@ Import-Package: org.apache.qpid,
org.apache.log4j;version=1.0.0,
javax.management;version=1.0.0,
javax.management.openmbean;version=1.0.0,
- javax.security.auth;version=1.0.0,
org.osgi.util.tracker;version=1.0.0,
org.osgi.framework;version=1.3
Private-Package: org.apache.qpid.server.security.access.config,
diff --git a/qpid/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/RuleSet.java b/qpid/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/RuleSet.java
index 78355a7501..ebc73440ed 100644
--- a/qpid/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/RuleSet.java
+++ b/qpid/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/RuleSet.java
@@ -18,24 +18,20 @@
*/
package org.apache.qpid.server.security.access.config;
-import java.security.Principal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.EnumMap;
import java.util.HashMap;
-import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
-import java.util.Set;
import java.util.SortedMap;
import java.util.TreeMap;
import java.util.WeakHashMap;
-import javax.security.auth.Subject;
-
import org.apache.commons.lang.BooleanUtils;
import org.apache.commons.lang.StringUtils;
+import org.apache.log4j.Logger;
import org.apache.qpid.exchange.ExchangeDefaults;
import org.apache.qpid.server.logging.actors.CurrentActor;
import org.apache.qpid.server.security.Result;
@@ -49,132 +45,147 @@ import org.apache.qpid.server.security.access.logging.AccessControlMessages;
* Models the rule configuration for the access control plugin.
*
* The access control rule definitions are loaded from an external configuration file, passed in as the
- * target to the {@link load(ConfigurationFile)} method. The file specified
+ * target to the {@link load(ConfigurationFile)} method. The file specified
*/
public class RuleSet
{
+ private static final Logger _logger = Logger.getLogger(RuleSet.class);
+
private static final String AT = "@";
- private static final String SLASH = "/";
+ private static final String SLASH = "/";
- public static final String DEFAULT_ALLOW = "defaultallow";
- public static final String DEFAULT_DENY = "defaultdeny";
- public static final String TRANSITIVE = "transitive";
- public static final String EXPAND = "expand";
+ public static final String DEFAULT_ALLOW = "defaultallow";
+ public static final String DEFAULT_DENY = "defaultdeny";
+ public static final String TRANSITIVE = "transitive";
+ public static final String EXPAND = "expand";
public static final String AUTONUMBER = "autonumber";
public static final String CONTROLLED = "controlled";
public static final String VALIDATE = "validate";
-
+
public static final List<String> CONFIG_PROPERTIES = Arrays.asList(
DEFAULT_ALLOW, DEFAULT_DENY, TRANSITIVE, EXPAND, AUTONUMBER, CONTROLLED
);
-
+
private static final Integer _increment = 10;
-
- private final Map<String, List<String>> _aclGroups = new HashMap<String, List<String>>();
+
+ private final Map<String, List<String>> _groups = new HashMap<String, List<String>>();
private final SortedMap<Integer, Rule> _rules = new TreeMap<Integer, Rule>();
- private final Map<Subject, Map<Operation, Map<ObjectType, List<Rule>>>> _cache =
- new WeakHashMap<Subject, Map<Operation, Map<ObjectType, List<Rule>>>>();
+ private final Map<String, Map<Operation, Map<ObjectType, List<Rule>>>> _cache =
+ new WeakHashMap<String, Map<Operation, Map<ObjectType, List<Rule>>>>();
private final Map<String, Boolean> _config = new HashMap<String, Boolean>();
-
+
public RuleSet()
{
// set some default configuration properties
configure(DEFAULT_DENY, Boolean.TRUE);
configure(TRANSITIVE, Boolean.TRUE);
}
-
+
/**
- * Clear the contents, including acl groups, rules and configuration.
+ * Clear the contents, invluding groups, rules and configuration.
*/
public void clear()
{
_rules.clear();
_cache.clear();
_config.clear();
- _aclGroups.clear();
+ _groups.clear();
}
-
+
public int getRuleCount()
{
return _rules.size();
}
-
- /**
- * Filtered rules list based on a subject and operation.
- *
- * Allows only enabled rules with identity equal to all, the same, or a group with identity as a member,
- * and operation is either all or the same operation.
- */
- public List<Rule> getRules(final Subject subject, final Operation operation, final ObjectType objectType)
- {
- final Map<ObjectType, List<Rule>> objects = getObjectToRuleCache(subject, operation);
+
+ /**
+ * Filtered rules list based on an identity and operation.
+ *
+ * Allows only enabled rules with identity equal to all, the same, or a group with identity as a member,
+ * and operation is either all or the same operation.
+ */
+ public List<Rule> getRules(String identity, Operation operation, ObjectType objectType)
+ {
+ // Lookup identity in cache and create empty operation map if required
+ Map<Operation, Map<ObjectType, List<Rule>>> operations = _cache.get(identity);
+ if (operations == null)
+ {
+ operations = new EnumMap<Operation, Map<ObjectType, List<Rule>>>(Operation.class);
+ _cache.put(identity, operations);
+ }
+
+ // Lookup operation and create empty object type map if required
+ Map<ObjectType, List<Rule>> objects = operations.get(operation);
+ if (objects == null)
+ {
+ objects = new EnumMap<ObjectType, List<Rule>>(ObjectType.class);
+ operations.put(operation, objects);
+ }
// Lookup object type rules for the operation
if (!objects.containsKey(objectType))
{
- final Set<Principal> principals = subject.getPrincipals();
boolean controlled = false;
List<Rule> filtered = new LinkedList<Rule>();
for (Rule rule : _rules.values())
{
- final Action ruleAction = rule.getAction();
if (rule.isEnabled()
- && (ruleAction.getOperation() == Operation.ALL || ruleAction.getOperation() == operation)
- && (ruleAction.getObjectType() == ObjectType.ALL || ruleAction.getObjectType() == objectType))
+ && (rule.getAction().getOperation() == Operation.ALL || rule.getAction().getOperation() == operation)
+ && (rule.getAction().getObjectType() == ObjectType.ALL || rule.getAction().getObjectType() == objectType))
{
controlled = true;
- if (isRelevant(principals,rule))
+ if (rule.getIdentity().equalsIgnoreCase(Rule.ALL)
+ || rule.getIdentity().equalsIgnoreCase(identity)
+ || (_groups.containsKey(rule.getIdentity()) && _groups.get(rule.getIdentity()).contains(identity)))
{
filtered.add(rule);
}
}
}
-
+
// Return null if there are no rules at all for this operation and object type
if (filtered.isEmpty() && controlled == false)
{
filtered = null;
}
-
+
// Save the rules we selected
objects.put(objectType, filtered);
}
-
+
// Return the cached rules
- return objects.get(objectType);
- }
-
-
+ return objects.get(objectType);
+ }
+
public boolean isValidNumber(Integer number)
{
return !_rules.containsKey(number);
}
-
+
public void grant(Integer number, String identity, Permission permission, Operation operation)
{
Action action = new Action(operation);
addRule(number, identity, permission, action);
}
-
+
public void grant(Integer number, String identity, Permission permission, Operation operation, ObjectType object, ObjectProperties properties)
{
Action action = new Action(operation, object, properties);
addRule(number, identity, permission, action);
}
-
+
public boolean ruleExists(String identity, Action action)
{
- for (Rule rule : _rules.values())
- {
- if (rule.getIdentity().equals(identity) && rule.getAction().equals(action))
- {
- return true;
- }
- }
- return false;
+ for (Rule rule : _rules.values())
+ {
+ if (rule.getIdentity().equals(identity) && rule.getAction().equals(action))
+ {
+ return true;
+ }
+ }
+ return false;
}
-
+
private Permission noLog(Permission permission)
{
switch (permission)
@@ -192,17 +203,15 @@ public class RuleSet
// TODO make this work when group membership is not known at file parse time
public void addRule(Integer number, String identity, Permission permission, Action action)
{
- _cache.clear();
-
- if (!action.isAllowed())
- {
- throw new IllegalArgumentException("Action is not allowd: " + action);
- }
+ if (!action.isAllowed())
+ {
+ throw new IllegalArgumentException("Action is not allowd: " + action);
+ }
if (ruleExists(identity, action))
{
return;
}
-
+
// expand actions - possibly multiply number by
if (isSet(EXPAND))
{
@@ -225,8 +234,8 @@ public class RuleSet
return;
}
}
-
- // transitive action dependencies
+
+ // transitive action dependencies
if (isSet(TRANSITIVE))
{
if (action.getOperation() == Operation.CREATE && action.getObjectType() == ObjectType.QUEUE)
@@ -235,10 +244,10 @@ public class RuleSet
exchProperties.setName(ExchangeDefaults.DEFAULT_EXCHANGE_NAME);
exchProperties.put(ObjectProperties.Property.ROUTING_KEY, action.getProperties().get(ObjectProperties.Property.NAME));
addRule(null, identity, noLog(permission), new Action(Operation.BIND, ObjectType.EXCHANGE, exchProperties));
- if (action.getProperties().isSet(ObjectProperties.Property.AUTO_DELETE))
- {
- addRule(null, identity, noLog(permission), new Action(Operation.DELETE, ObjectType.QUEUE, action.getProperties()));
- }
+ if (action.getProperties().isSet(ObjectProperties.Property.AUTO_DELETE))
+ {
+ addRule(null, identity, noLog(permission), new Action(Operation.DELETE, ObjectType.QUEUE, action.getProperties()));
+ }
}
else if (action.getOperation() == Operation.DELETE && action.getObjectType() == ObjectType.QUEUE)
{
@@ -252,9 +261,9 @@ public class RuleSet
addRule(null, identity, noLog(permission), new Action(Operation.ACCESS, ObjectType.VIRTUALHOST));
}
}
-
+
// set rule number if needed
- Rule rule = new Rule(number, identity, action, permission);
+ Rule rule = new Rule(number, identity, action, permission);
if (rule.getNumber() == null)
{
if (_rules.isEmpty())
@@ -266,36 +275,34 @@ public class RuleSet
rule.setNumber(_rules.lastKey() + _increment);
}
}
-
+
// save rule
_cache.remove(identity);
_rules.put(rule.getNumber(), rule);
- }
-
+ }
+
public void enableRule(int ruleNumber)
{
_rules.get(Integer.valueOf(ruleNumber)).enable();
}
-
+
public void disableRule(int ruleNumber)
{
_rules.get(Integer.valueOf(ruleNumber)).disable();
}
-
+
public boolean addGroup(String group, List<String> constituents)
{
- _cache.clear();
-
- if (_aclGroups.containsKey(group))
+ if (_groups.containsKey(group))
{
// cannot redefine
return false;
}
else
{
- _aclGroups.put(group, new ArrayList<String>());
+ _groups.put(group, new ArrayList<String>());
}
-
+
for (String name : constituents)
{
if (name.equalsIgnoreCase(group))
@@ -303,17 +310,17 @@ public class RuleSet
// recursive definition
return false;
}
-
+
if (!checkName(name))
{
// invalid name
return false;
}
-
- if (_aclGroups.containsKey(name))
+
+ if (_groups.containsKey(name))
{
// is a group
- _aclGroups.get(group).addAll(_aclGroups.get(name));
+ _groups.get(group).addAll(_groups.get(name));
}
else
{
@@ -323,12 +330,12 @@ public class RuleSet
// invalid username
return false;
}
- _aclGroups.get(group).add(name);
+ _groups.get(group).add(name);
}
}
return true;
}
-
+
/** Return true if the name is well-formed (contains legal characters). */
protected boolean checkName(String name)
{
@@ -342,79 +349,79 @@ public class RuleSet
}
return true;
}
-
+
/** Returns true if a username has the name[@domain][/realm] format */
protected boolean isvalidUserName(String name)
- {
- // check for '@' and '/' in namne
- int atPos = name.indexOf(AT);
- int slashPos = name.indexOf(SLASH);
- boolean atFound = atPos != StringUtils.INDEX_NOT_FOUND && atPos == name.lastIndexOf(AT);
- boolean slashFound = slashPos != StringUtils.INDEX_NOT_FOUND && slashPos == name.lastIndexOf(SLASH);
-
- // must be at least one character after '@' or '/'
- if (atFound && atPos > name.length() - 2)
- {
- return false;
- }
- if (slashFound && slashPos > name.length() - 2)
- {
- return false;
- }
-
- // must be at least one character between '@' and '/'
- if (atFound && slashFound)
- {
- return (atPos < (slashPos - 1));
- }
-
- // otherwise all good
- return true;
+ {
+ // check for '@' and '/' in namne
+ int atPos = name.indexOf(AT);
+ int slashPos = name.indexOf(SLASH);
+ boolean atFound = atPos != StringUtils.INDEX_NOT_FOUND && atPos == name.lastIndexOf(AT);
+ boolean slashFound = slashPos != StringUtils.INDEX_NOT_FOUND && slashPos == name.lastIndexOf(SLASH);
+
+ // must be at least one character after '@' or '/'
+ if (atFound && atPos > name.length() - 2)
+ {
+ return false;
+ }
+ if (slashFound && slashPos > name.length() - 2)
+ {
+ return false;
+ }
+
+ // must be at least one character between '@' and '/'
+ if (atFound && slashFound)
+ {
+ return (atPos < (slashPos - 1));
+ }
+
+ // otherwise all good
+ return true;
}
- // C++ broker authorise function prototype
+ // C++ broker authorise function prototype
// virtual bool authorise(const std::string& id, const Action& action, const ObjectType& objType,
- // const std::string& name, std::map<Property, std::string>* params=0);
-
- // Possibly add a String name paramater?
+ // const std::string& name, std::map<Property, std::string>* params=0);
+
+ // Possibly add a String name paramater?
/**
* Check the authorisation granted to a particular identity for an operation on an object type with
* specific properties.
*
- * Looks up the entire ruleset, which may be cached, for the user and operation and goes through the rules
+ * Looks up the entire ruleset, whcih may be cached, for the user and operation and goes through the rules
* in order to find the first one that matches. Either defers if there are no rules, returns the result of
* the first match found, or denies access if there are no matching rules. Normally, it would be expected
* to have a default deny or allow rule at the end of an access configuration however.
*/
- public Result check(Subject subject, Operation operation, ObjectType objectType, ObjectProperties properties)
+ public Result check(String identity, Operation operation, ObjectType objectType, ObjectProperties properties)
{
// Create the action to check
Action action = new Action(operation, objectType, properties);
- // get the list of rules relevant for this request
- List<Rule> rules = getRules(subject, operation, objectType);
- if (rules == null)
- {
- if (isSet(CONTROLLED))
- {
- // Abstain if there are no rules for this operation
+ // get the list of rules relevant for this request
+ List<Rule> rules = getRules(identity, operation, objectType);
+ if (rules == null)
+ {
+ if (isSet(CONTROLLED))
+ {
+ // Abstain if there are no rules for this operation
return Result.ABSTAIN;
- }
- else
- {
- return getDefault();
- }
- }
-
- // Iterate through a filtered set of rules dealing with this identity and operation
+ }
+ else
+ {
+ return getDefault();
+ }
+ }
+
+ // Iterate through a filtered set of rules dealing with this identity and operation
for (Rule current : rules)
- {
- // Check if action matches
+ {
+ // Check if action matches
if (action.matches(current.getAction()))
{
Permission permission = current.getPermission();
-
+
switch (permission)
{
case ALLOW_LOG:
@@ -432,15 +439,15 @@ public class RuleSet
return Result.DENIED;
}
}
-
+
// Defer to the next plugin of this type, if it exists
- return Result.DEFER;
+ return Result.DEFER;
}
-
- /** Default deny. */
- public Result getDefault()
- {
- if (isSet(DEFAULT_ALLOW))
+
+ /** Default deny. */
+ public Result getDefault()
+ {
+ if (isSet(DEFAULT_ALLOW))
{
return Result.ALLOWED;
}
@@ -449,19 +456,19 @@ public class RuleSet
return Result.DENIED;
}
return Result.ABSTAIN;
- }
-
- /**
- * Check if a configuration property is set.
- */
- protected boolean isSet(String key)
- {
- return BooleanUtils.isTrue(_config.get(key));
- }
+ }
+
+ /**
+ * Check if a configuration property is set.
+ */
+ protected boolean isSet(String key)
+ {
+ return BooleanUtils.isTrue(_config.get(key));
+ }
/**
* Configure properties for the plugin instance.
- *
+ *
* @param properties
*/
public void configure(Map<String, Boolean> properties)
@@ -471,7 +478,7 @@ public class RuleSet
/**
* Configure a single property for the plugin instance.
- *
+ *
* @param key
* @param value
*/
@@ -479,48 +486,4 @@ public class RuleSet
{
_config.put(key, value);
}
-
- private boolean isRelevant(final Set<Principal> principals, final Rule rule)
- {
- if (rule.getIdentity().equalsIgnoreCase(Rule.ALL))
- {
- return true;
- }
- else
- {
- for (Iterator<Principal> iterator = principals.iterator(); iterator.hasNext();)
- {
- final Principal principal = iterator.next();
-
- if (rule.getIdentity().equalsIgnoreCase(principal.getName())
- || (_aclGroups.containsKey(rule.getIdentity()) && _aclGroups.get(rule.getIdentity()).contains(principal.getName())))
- {
- return true;
- }
- }
- }
-
- return false;
- }
-
- private Map<ObjectType, List<Rule>> getObjectToRuleCache(final Subject subject, final Operation operation)
- {
- // Lookup identity in cache and create empty operation map if required
- Map<Operation, Map<ObjectType, List<Rule>>> operations = _cache.get(subject);
- if (operations == null)
- {
- operations = new EnumMap<Operation, Map<ObjectType, List<Rule>>>(Operation.class);
- _cache.put(subject, operations);
- }
-
- // Lookup operation and create empty object type map if required
- Map<ObjectType, List<Rule>> objects = operations.get(operation);
- if (objects == null)
- {
- objects = new EnumMap<ObjectType, List<Rule>>(ObjectType.class);
- operations.put(operation, objects);
- }
- return objects;
- }
-
}
diff --git a/qpid/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/plugins/AccessControl.java b/qpid/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/plugins/AccessControl.java
index a7b3059262..69cfa173bd 100644
--- a/qpid/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/plugins/AccessControl.java
+++ b/qpid/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/plugins/AccessControl.java
@@ -20,7 +20,7 @@
*/
package org.apache.qpid.server.security.access.plugins;
-import javax.security.auth.Subject;
+import java.security.Principal;
import org.apache.commons.configuration.ConfigurationException;
import org.apache.log4j.Logger;
@@ -89,19 +89,20 @@ public class AccessControl extends AbstractPlugin
/**
* Check if an operation is authorised by asking the configuration object about the access
- * control rules granted to the current thread's {@link Subject}. If there is no current
+ * control rules granted to the current thread's {@link Principal}. If there is no current
* user the plugin will abstain.
*/
public Result authorise(Operation operation, ObjectType objectType, ObjectProperties properties)
{
- final Subject subject = SecurityManager.getThreadSubject();
- // Abstain if there is no subject/principal associated with this thread
- if (subject == null || subject.getPrincipals().size() == 0)
+ Principal principal = SecurityManager.getThreadPrincipal();
+
+ // Abstain if there is no user associated with this thread
+ if (principal == null)
{
return Result.ABSTAIN;
}
-
- return _ruleSet.check(subject, operation, objectType, properties);
+
+ return _ruleSet.check(principal.getName(), operation, objectType, properties);
}
public void configure(ConfigurationPlugin config)
diff --git a/qpid/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/plugins/AccessControlTest.java b/qpid/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/plugins/AccessControlTest.java
index 09d26e5451..309a3aeb2c 100644
--- a/qpid/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/plugins/AccessControlTest.java
+++ b/qpid/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/plugins/AccessControlTest.java
@@ -1,172 +1,195 @@
/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
*
- * Licensed 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.
+ * 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.Arrays;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileWriter;
+import java.io.PrintWriter;
import junit.framework.TestCase;
-import org.apache.qpid.server.configuration.plugins.ConfigurationPlugin;
-import org.apache.qpid.server.logging.UnitTestMessageLogger;
-import org.apache.qpid.server.logging.actors.CurrentActor;
-import org.apache.qpid.server.logging.actors.TestLogActor;
-import org.apache.qpid.server.security.Result;
-import org.apache.qpid.server.security.SecurityManager;
-import org.apache.qpid.server.security.access.ObjectProperties;
-import org.apache.qpid.server.security.access.ObjectType;
-import org.apache.qpid.server.security.access.Operation;
-import org.apache.qpid.server.security.access.Permission;
-import org.apache.qpid.server.security.access.config.Rule;
+import org.apache.commons.configuration.ConfigurationException;
+import org.apache.qpid.server.security.access.config.ConfigurationFile;
+import org.apache.qpid.server.security.access.config.PlainConfiguration;
import org.apache.qpid.server.security.access.config.RuleSet;
-import org.apache.qpid.server.security.auth.sasl.TestPrincipalUtils;
/**
- * Unit test for ACL V2 plugin.
- *
- * This unit test tests the AccessControl class and it collaboration with {@link RuleSet},
- * {@link SecurityManager} and {@link CurrentActor}. The ruleset is configured programmatically,
- * rather than from an external file.
+ * These tests check that the ACL file parsing works correctly.
*
- * @see RuleSetTest
+ * For each message that can be returned in a {@link ConfigurationException}, an ACL file is created that should trigger this
+ * particular message.
*/
public class AccessControlTest extends TestCase
{
- private AccessControl _plugin = null; // Class under test
- private final UnitTestMessageLogger messageLogger = new UnitTestMessageLogger();
-
- protected void setUp() throws Exception
+ public void writeACLConfig(String...aclData) throws Exception
{
- super.setUp();
-
- final RuleSet rs = new RuleSet();
- rs.addGroup("aclGroup1", Arrays.asList(new String[] {"member1", "member2"}));
-
- // Rule expressed with username
- rs.grant(0, "user1", Permission.ALLOW, Operation.ACCESS, ObjectType.VIRTUALHOST, ObjectProperties.EMPTY);
- // Rule expressed with a acl group
- rs.grant(1, "aclGroup1", Permission.ALLOW, Operation.ACCESS, ObjectType.VIRTUALHOST, ObjectProperties.EMPTY);
- // Rule expressed with an external group
- rs.grant(2, "extGroup1", Permission.DENY, Operation.ACCESS, ObjectType.VIRTUALHOST, ObjectProperties.EMPTY);
- // Catch all rule
- rs.grant(3, Rule.ALL, Permission.DENY_LOG, Operation.ACCESS, ObjectType.VIRTUALHOST, ObjectProperties.EMPTY);
-
- _plugin = (AccessControl) AccessControl.FACTORY.newInstance(createConfiguration(rs));
-
- SecurityManager.setThreadSubject(null);
+ File acl = File.createTempFile(getClass().getName() + getName(), "acl");
+ acl.deleteOnExit();
- CurrentActor.set(new TestLogActor(messageLogger));
+ // Write ACL file
+ PrintWriter aclWriter = new PrintWriter(new FileWriter(acl));
+ for (String line : aclData)
+ {
+ aclWriter.println(line);
+ }
+ aclWriter.close();
+
+ // Load ruleset
+ ConfigurationFile configFile = new PlainConfiguration(acl);
+ RuleSet ruleSet = configFile.load();
}
- protected void tearDown() throws Exception
+ public void testMissingACLConfig() throws Exception
{
- super.tearDown();
- SecurityManager.setThreadSubject(null);
+ try
+ {
+ // Load ruleset
+ ConfigurationFile configFile = new PlainConfiguration(new File("doesnotexist"));
+ RuleSet ruleSet = configFile.load();
+
+ fail("fail");
+ }
+ catch (ConfigurationException ce)
+ {
+ assertEquals(String.format(PlainConfiguration.CONFIG_NOT_FOUND_MSG, "doesnotexist"), ce.getMessage());
+ assertTrue(ce.getCause() instanceof FileNotFoundException);
+ assertEquals("doesnotexist (No such file or directory)", ce.getCause().getMessage());
+ }
}
- /**
- * ACL plugin must always abstain if there is no subject attached to the thread.
- */
- public void testNoSubjectAlwaysAbstains()
+ public void testACLFileSyntaxContinuation() throws Exception
{
- SecurityManager.setThreadSubject(null);
-
- final Result result = _plugin.authorise(Operation.ACCESS, ObjectType.VIRTUALHOST, ObjectProperties.EMPTY);
- assertEquals(Result.ABSTAIN, result);
+ try
+ {
+ writeACLConfig("ACL ALLOW ALL \\ ALL");
+ fail("fail");
+ }
+ catch (ConfigurationException ce)
+ {
+ assertEquals(String.format(PlainConfiguration.PREMATURE_CONTINUATION_MSG, 1), ce.getMessage());
+ }
}
- /**
- * Tests that an allow rule expressed with a username allows an operation performed by a thread running
- * with the same username.
- */
- public void testUsernameAllowsOperation()
+ public void testACLFileSyntaxTokens() throws Exception
{
- SecurityManager.setThreadSubject(TestPrincipalUtils.createTestSubject("user1"));
-
- final Result result = _plugin.authorise(Operation.ACCESS, ObjectType.VIRTUALHOST, ObjectProperties.EMPTY);
- assertEquals(Result.ALLOWED, result);
+ try
+ {
+ writeACLConfig("ACL unparsed ALL ALL");
+ fail("fail");
+ }
+ catch (ConfigurationException ce)
+ {
+ assertEquals(String.format(PlainConfiguration.PARSE_TOKEN_FAILED_MSG, 1), ce.getMessage());
+ assertTrue(ce.getCause() instanceof IllegalArgumentException);
+ assertEquals("Not a valid permission: unparsed", ce.getCause().getMessage());
+ }
}
- /**
- * Tests that an allow rule expressed with an <b>ACL groupname</b> allows an operation performed by a thread running
- * by a user who belongs to the same group..
- */
- public void testAclGroupMembershipAllowsOperation()
+ public void testACLFileSyntaxNotEnoughGroup() throws Exception
{
- SecurityManager.setThreadSubject(TestPrincipalUtils.createTestSubject("member1"));
+ try
+ {
+ writeACLConfig("GROUP blah");
+ fail("fail");
+ }
+ catch (ConfigurationException ce)
+ {
+ assertEquals(String.format(PlainConfiguration.NOT_ENOUGH_GROUP_MSG, 1), ce.getMessage());
+ }
+ }
- final Result result = _plugin.authorise(Operation.ACCESS, ObjectType.VIRTUALHOST, ObjectProperties.EMPTY);
- assertEquals(Result.ALLOWED, result);
+ public void testACLFileSyntaxNotEnoughACL() throws Exception
+ {
+ try
+ {
+ writeACLConfig("ACL ALLOW");
+ fail("fail");
+ }
+ catch (ConfigurationException ce)
+ {
+ assertEquals(String.format(PlainConfiguration.NOT_ENOUGH_ACL_MSG, 1), ce.getMessage());
+ }
}
- /**
- * Tests that a deny rule expressed with an <b>External groupname</b> denies an operation performed by a thread running
- * by a user who belongs to the same group.
- */
- public void testExternalGroupMembershipDeniesOperation()
+ public void testACLFileSyntaxNotEnoughConfig() throws Exception
{
- SecurityManager.setThreadSubject(TestPrincipalUtils.createTestSubject("user3", "extGroup1"));
-
- final Result result = _plugin.authorise(Operation.ACCESS, ObjectType.VIRTUALHOST, ObjectProperties.EMPTY);
- assertEquals(Result.DENIED, result);
+ try
+ {
+ writeACLConfig("CONFIG");
+ fail("fail");
+ }
+ catch (ConfigurationException ce)
+ {
+ assertEquals(String.format(PlainConfiguration.NOT_ENOUGH_TOKENS_MSG, 1), ce.getMessage());
+ }
}
- /**
- * Tests that the catch all deny denies the operation and logs with the logging actor.
- */
- public void testCatchAllRuleDeniesUnrecognisedUsername()
+ public void testACLFileSyntaxNotEnough() throws Exception
{
- SecurityManager.setThreadSubject(TestPrincipalUtils.createTestSubject("unknown", "unkgroup1", "unkgroup2"));
-
- assertEquals("Expecting zero messages before test", 0, messageLogger.getLogMessages().size());
- final Result result = _plugin.authorise(Operation.ACCESS, ObjectType.VIRTUALHOST, ObjectProperties.EMPTY);
- assertEquals(Result.DENIED, result);
-
- assertEquals("Expecting one message before test", 1, messageLogger.getLogMessages().size());
- assertTrue("Logged message does not contain expected string", messageLogger.messageContains(0, "ACL-1002"));
+ try
+ {
+ writeACLConfig("INVALID");
+ fail("fail");
+ }
+ catch (ConfigurationException ce)
+ {
+ assertEquals(String.format(PlainConfiguration.NOT_ENOUGH_TOKENS_MSG, 1), ce.getMessage());
+ }
}
-
- /**
- * Creates a configuration plugin for the {@link AccessControl} plugin.
- */
- private ConfigurationPlugin createConfiguration(final RuleSet rs)
+
+ public void testACLFileSyntaxPropertyKeyOnly() throws Exception
{
- final ConfigurationPlugin cp = new ConfigurationPlugin()
- {
- public AccessControlConfiguration getConfiguration(final String plugin)
- {
- return new AccessControlConfiguration()
- {
- public RuleSet getRuleSet()
- {
- return rs;
- }
- };
- }
+ try
+ {
+ writeACLConfig("ACL ALLOW adk CREATE QUEUE name");
+ fail("fail");
+ }
+ catch (ConfigurationException ce)
+ {
+ assertEquals(String.format(PlainConfiguration.PROPERTY_KEY_ONLY_MSG, 1), ce.getMessage());
+ }
+ }
- public String[] getElementsProcessed()
- {
- throw new UnsupportedOperationException();
- }
- };
+ public void testACLFileSyntaxPropertyNoEquals() throws Exception
+ {
+ try
+ {
+ writeACLConfig("ACL ALLOW adk CREATE QUEUE name test");
+ fail("fail");
+ }
+ catch (ConfigurationException ce)
+ {
+ assertEquals(String.format(PlainConfiguration.PROPERTY_NO_EQUALS_MSG, 1), ce.getMessage());
+ }
+ }
- return cp;
+ public void testACLFileSyntaxPropertyNoValue() throws Exception
+ {
+ try
+ {
+ writeACLConfig("ACL ALLOW adk CREATE QUEUE name =");
+ fail("fail");
+ }
+ catch (ConfigurationException ce)
+ {
+ assertEquals(String.format(PlainConfiguration.PROPERTY_NO_VALUE_MSG, 1), ce.getMessage());
+ }
}
}
diff --git a/qpid/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/plugins/PlainConfigurationTest.java b/qpid/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/plugins/PlainConfigurationTest.java
deleted file mode 100644
index e16f9943ba..0000000000
--- a/qpid/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/plugins/PlainConfigurationTest.java
+++ /dev/null
@@ -1,194 +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.security.access.plugins;
-
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.FileWriter;
-import java.io.PrintWriter;
-
-import junit.framework.TestCase;
-
-import org.apache.commons.configuration.ConfigurationException;
-import org.apache.qpid.server.security.access.config.ConfigurationFile;
-import org.apache.qpid.server.security.access.config.PlainConfiguration;
-
-/**
- * These tests check that the ACL file parsing works correctly.
- *
- * For each message that can be returned in a {@link ConfigurationException}, an ACL file is created that should trigger this
- * particular message.
- */
-public class PlainConfigurationTest extends TestCase
-{
- public void writeACLConfig(String...aclData) throws Exception
- {
- File acl = File.createTempFile(getClass().getName() + getName(), "acl");
- acl.deleteOnExit();
-
- // Write ACL file
- PrintWriter aclWriter = new PrintWriter(new FileWriter(acl));
- for (String line : aclData)
- {
- aclWriter.println(line);
- }
- aclWriter.close();
-
- // Load ruleset
- ConfigurationFile configFile = new PlainConfiguration(acl);
- configFile.load();
- }
-
- public void testMissingACLConfig() throws Exception
- {
- try
- {
- // Load ruleset
- ConfigurationFile configFile = new PlainConfiguration(new File("doesnotexist"));
- configFile.load();
-
- fail("fail");
- }
- catch (ConfigurationException ce)
- {
- assertEquals(String.format(PlainConfiguration.CONFIG_NOT_FOUND_MSG, "doesnotexist"), ce.getMessage());
- assertTrue(ce.getCause() instanceof FileNotFoundException);
- assertEquals("doesnotexist (No such file or directory)", ce.getCause().getMessage());
- }
- }
-
- public void testACLFileSyntaxContinuation() throws Exception
- {
- try
- {
- writeACLConfig("ACL ALLOW ALL \\ ALL");
- fail("fail");
- }
- catch (ConfigurationException ce)
- {
- assertEquals(String.format(PlainConfiguration.PREMATURE_CONTINUATION_MSG, 1), ce.getMessage());
- }
- }
-
- public void testACLFileSyntaxTokens() throws Exception
- {
- try
- {
- writeACLConfig("ACL unparsed ALL ALL");
- fail("fail");
- }
- catch (ConfigurationException ce)
- {
- assertEquals(String.format(PlainConfiguration.PARSE_TOKEN_FAILED_MSG, 1), ce.getMessage());
- assertTrue(ce.getCause() instanceof IllegalArgumentException);
- assertEquals("Not a valid permission: unparsed", ce.getCause().getMessage());
- }
- }
-
- public void testACLFileSyntaxNotEnoughGroup() throws Exception
- {
- try
- {
- writeACLConfig("GROUP blah");
- fail("fail");
- }
- catch (ConfigurationException ce)
- {
- assertEquals(String.format(PlainConfiguration.NOT_ENOUGH_GROUP_MSG, 1), ce.getMessage());
- }
- }
-
- public void testACLFileSyntaxNotEnoughACL() throws Exception
- {
- try
- {
- writeACLConfig("ACL ALLOW");
- fail("fail");
- }
- catch (ConfigurationException ce)
- {
- assertEquals(String.format(PlainConfiguration.NOT_ENOUGH_ACL_MSG, 1), ce.getMessage());
- }
- }
-
- public void testACLFileSyntaxNotEnoughConfig() throws Exception
- {
- try
- {
- writeACLConfig("CONFIG");
- fail("fail");
- }
- catch (ConfigurationException ce)
- {
- assertEquals(String.format(PlainConfiguration.NOT_ENOUGH_TOKENS_MSG, 1), ce.getMessage());
- }
- }
-
- public void testACLFileSyntaxNotEnough() throws Exception
- {
- try
- {
- writeACLConfig("INVALID");
- fail("fail");
- }
- catch (ConfigurationException ce)
- {
- assertEquals(String.format(PlainConfiguration.NOT_ENOUGH_TOKENS_MSG, 1), ce.getMessage());
- }
- }
-
- public void testACLFileSyntaxPropertyKeyOnly() throws Exception
- {
- try
- {
- writeACLConfig("ACL ALLOW adk CREATE QUEUE name");
- fail("fail");
- }
- catch (ConfigurationException ce)
- {
- assertEquals(String.format(PlainConfiguration.PROPERTY_KEY_ONLY_MSG, 1), ce.getMessage());
- }
- }
-
- public void testACLFileSyntaxPropertyNoEquals() throws Exception
- {
- try
- {
- writeACLConfig("ACL ALLOW adk CREATE QUEUE name test");
- fail("fail");
- }
- catch (ConfigurationException ce)
- {
- assertEquals(String.format(PlainConfiguration.PROPERTY_NO_EQUALS_MSG, 1), ce.getMessage());
- }
- }
-
- public void testACLFileSyntaxPropertyNoValue() throws Exception
- {
- try
- {
- writeACLConfig("ACL ALLOW adk CREATE QUEUE name =");
- fail("fail");
- }
- catch (ConfigurationException ce)
- {
- assertEquals(String.format(PlainConfiguration.PROPERTY_NO_VALUE_MSG, 1), ce.getMessage());
- }
- }
-}
diff --git a/qpid/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/plugins/RuleSetTest.java b/qpid/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/plugins/RuleSetTest.java
index bd9deac153..aad7290557 100644
--- a/qpid/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/plugins/RuleSetTest.java
+++ b/qpid/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/plugins/RuleSetTest.java
@@ -21,21 +21,13 @@
package org.apache.qpid.server.security.access.plugins;
-import java.security.Principal;
-import java.util.Arrays;
-
-import javax.security.auth.Subject;
-
import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.server.security.Result;
import org.apache.qpid.server.security.access.ObjectProperties;
import org.apache.qpid.server.security.access.ObjectType;
import org.apache.qpid.server.security.access.Operation;
import org.apache.qpid.server.security.access.Permission;
-import org.apache.qpid.server.security.access.config.Rule;
import org.apache.qpid.server.security.access.config.RuleSet;
-import org.apache.qpid.server.security.auth.sasl.TestPrincipalUtils;
-import org.apache.qpid.server.security.auth.sasl.UsernamePrincipal;
import org.apache.qpid.test.utils.QpidTestCase;
/**
@@ -44,24 +36,16 @@ import org.apache.qpid.test.utils.QpidTestCase;
* The ruleset is configured directly rather than using an external file by adding rules individually, calling the
* {@link RuleSet#grant(Integer, String, Permission, Operation, ObjectType, ObjectProperties)} method. Then, the
* access control mechanism is validated by checking whether operations would be authorised by calling the
- * {@link RuleSet#check(Principal, Operation, ObjectType, ObjectProperties)} method.
- *
- * It ensure that permissions can be granted correctly on users directly, ACL groups (that is those
- * groups declared directly in the ACL itself), and External groups (that is a group from an External
- * Authentication Provider, such as an LDAP).
-
+ * {@link RuleSet#check(String, Operation, ObjectType, ObjectProperties)} method.
*/
public class RuleSetTest extends QpidTestCase
{
- private RuleSet _ruleSet; // Object under test
-
- private static final String TEST_USER = "user";
+ private RuleSet _ruleSet;
// Common things that are passed to frame constructors
private AMQShortString _queueName = new AMQShortString(this.getClass().getName() + "queue");
private AMQShortString _exchangeName = new AMQShortString("amq.direct");
private AMQShortString _exchangeType = new AMQShortString("direct");
- private Subject _testSubject = TestPrincipalUtils.createTestSubject(TEST_USER);
@Override
public void setUp() throws Exception
@@ -79,36 +63,34 @@ public class RuleSetTest extends QpidTestCase
super.tearDown();
}
- public void assertDenyGrantAllow(Subject subject, Operation operation, ObjectType objectType)
+ public void assertDenyGrantAllow(String identity, Operation operation, ObjectType objectType)
{
- assertDenyGrantAllow(subject, operation, objectType, ObjectProperties.EMPTY);
+ assertDenyGrantAllow(identity, operation, objectType, ObjectProperties.EMPTY);
}
- public void assertDenyGrantAllow(Subject subject, Operation operation, ObjectType objectType, ObjectProperties properties)
+ public void assertDenyGrantAllow(String identity, Operation operation, ObjectType objectType, ObjectProperties properties)
{
- final Principal identity = UsernamePrincipal.getUsernamePrincipalFromSubject(subject);
-
- assertEquals(Result.DENIED, _ruleSet.check(subject, operation, objectType, properties));
- _ruleSet.grant(0, identity.getName(), Permission.ALLOW, operation, objectType, properties);
+ assertEquals(Result.DENIED, _ruleSet.check(identity, operation, objectType, properties));
+ _ruleSet.grant(0, identity, Permission.ALLOW, operation, objectType, properties);
assertEquals(1, _ruleSet.getRuleCount());
- assertEquals(Result.ALLOWED, _ruleSet.check(subject, operation, objectType, properties));
+ assertEquals(Result.ALLOWED, _ruleSet.check(identity, operation, objectType, properties));
}
public void testEmptyRuleSet()
{
assertNotNull(_ruleSet);
assertEquals(_ruleSet.getRuleCount(), 0);
- assertEquals(_ruleSet.getDefault(), _ruleSet.check(_testSubject, Operation.ACCESS, ObjectType.VIRTUALHOST, ObjectProperties.EMPTY));
+ assertEquals(_ruleSet.getDefault(), _ruleSet.check("user", Operation.ACCESS, ObjectType.VIRTUALHOST, ObjectProperties.EMPTY));
}
public void testVirtualHostAccess() throws Exception
{
- assertDenyGrantAllow(_testSubject, Operation.ACCESS, ObjectType.VIRTUALHOST);
+ assertDenyGrantAllow("user", Operation.ACCESS, ObjectType.VIRTUALHOST);
}
public void testQueueCreateNamed() throws Exception
{
- assertDenyGrantAllow(_testSubject, Operation.CREATE, ObjectType.QUEUE, new ObjectProperties(_queueName));
+ assertDenyGrantAllow("user", Operation.CREATE, ObjectType.QUEUE, new ObjectProperties(_queueName));
}
public void testQueueCreatenamedNullRoutingKey()
@@ -116,7 +98,7 @@ public class RuleSetTest extends QpidTestCase
ObjectProperties properties = new ObjectProperties(_queueName);
properties.put(ObjectProperties.Property.ROUTING_KEY, (String) null);
- assertDenyGrantAllow(_testSubject, Operation.CREATE, ObjectType.QUEUE, properties);
+ assertDenyGrantAllow("user", Operation.CREATE, ObjectType.QUEUE, properties);
}
public void testExchangeCreate()
@@ -124,17 +106,17 @@ public class RuleSetTest extends QpidTestCase
ObjectProperties properties = new ObjectProperties(_exchangeName);
properties.put(ObjectProperties.Property.TYPE, _exchangeType.asString());
- assertDenyGrantAllow(_testSubject, Operation.CREATE, ObjectType.EXCHANGE, properties);
+ assertDenyGrantAllow("user", Operation.CREATE, ObjectType.EXCHANGE, properties);
}
public void testConsume()
{
- assertDenyGrantAllow(_testSubject, Operation.CONSUME, ObjectType.QUEUE);
+ assertDenyGrantAllow("user", Operation.CONSUME, ObjectType.QUEUE);
}
public void testPublish()
{
- assertDenyGrantAllow(_testSubject, Operation.PUBLISH, ObjectType.EXCHANGE);
+ assertDenyGrantAllow("user", Operation.PUBLISH, ObjectType.EXCHANGE);
}
/**
@@ -149,13 +131,13 @@ public class RuleSetTest extends QpidTestCase
ObjectProperties normal = new ObjectProperties();
normal.put(ObjectProperties.Property.AUTO_DELETE, Boolean.FALSE);
- assertEquals(Result.DENIED, _ruleSet.check(_testSubject, Operation.CONSUME, ObjectType.QUEUE, temporary));
- _ruleSet.grant(0, TEST_USER, Permission.ALLOW, Operation.CONSUME, ObjectType.QUEUE, temporary);
+ assertEquals(Result.DENIED, _ruleSet.check("user", Operation.CONSUME, ObjectType.QUEUE, temporary));
+ _ruleSet.grant(0, "user", Permission.ALLOW, Operation.CONSUME, ObjectType.QUEUE, temporary);
assertEquals(1, _ruleSet.getRuleCount());
- assertEquals(Result.ALLOWED, _ruleSet.check(_testSubject, Operation.CONSUME, ObjectType.QUEUE, temporary));
+ assertEquals(Result.ALLOWED, _ruleSet.check("user", Operation.CONSUME, ObjectType.QUEUE, temporary));
// defer to global if exists, otherwise default answer - this is handled by the security manager
- assertEquals(Result.DEFER, _ruleSet.check(_testSubject, Operation.CONSUME, ObjectType.QUEUE, normal));
+ assertEquals(Result.DEFER, _ruleSet.check("user", Operation.CONSUME, ObjectType.QUEUE, normal));
}
/**
@@ -169,15 +151,15 @@ public class RuleSetTest extends QpidTestCase
ObjectProperties normal = new ObjectProperties(_queueName);
normal.put(ObjectProperties.Property.AUTO_DELETE, Boolean.FALSE);
- assertEquals(Result.DENIED, _ruleSet.check(_testSubject, Operation.CONSUME, ObjectType.QUEUE, temporary));
+ assertEquals(Result.DENIED, _ruleSet.check("user", Operation.CONSUME, ObjectType.QUEUE, temporary));
// should not matter if the temporary permission is processed first or last
- _ruleSet.grant(1, TEST_USER, Permission.ALLOW, Operation.CONSUME, ObjectType.QUEUE, normal);
- _ruleSet.grant(2, TEST_USER, Permission.ALLOW, Operation.CONSUME, ObjectType.QUEUE, temporary);
+ _ruleSet.grant(1, "user", Permission.ALLOW, Operation.CONSUME, ObjectType.QUEUE, normal);
+ _ruleSet.grant(2, "user", Permission.ALLOW, Operation.CONSUME, ObjectType.QUEUE, temporary);
assertEquals(2, _ruleSet.getRuleCount());
- assertEquals(Result.ALLOWED, _ruleSet.check(_testSubject, Operation.CONSUME, ObjectType.QUEUE, normal));
- assertEquals(Result.ALLOWED, _ruleSet.check(_testSubject, Operation.CONSUME, ObjectType.QUEUE, temporary));
+ assertEquals(Result.ALLOWED, _ruleSet.check("user", Operation.CONSUME, ObjectType.QUEUE, normal));
+ assertEquals(Result.ALLOWED, _ruleSet.check("user", Operation.CONSUME, ObjectType.QUEUE, temporary));
}
/**
@@ -191,15 +173,15 @@ public class RuleSetTest extends QpidTestCase
ObjectProperties normal = new ObjectProperties(_queueName);
normal.put(ObjectProperties.Property.AUTO_DELETE, Boolean.FALSE);
- assertEquals(Result.DENIED, _ruleSet.check(_testSubject, Operation.CONSUME, ObjectType.QUEUE, temporary));
+ assertEquals(Result.DENIED, _ruleSet.check("user", Operation.CONSUME, ObjectType.QUEUE, temporary));
// should not matter if the temporary permission is processed first or last
- _ruleSet.grant(1, TEST_USER, Permission.ALLOW, Operation.CONSUME, ObjectType.QUEUE, temporary);
- _ruleSet.grant(2, TEST_USER, Permission.ALLOW, Operation.CONSUME, ObjectType.QUEUE, normal);
+ _ruleSet.grant(1, "user", Permission.ALLOW, Operation.CONSUME, ObjectType.QUEUE, temporary);
+ _ruleSet.grant(2, "user", Permission.ALLOW, Operation.CONSUME, ObjectType.QUEUE, normal);
assertEquals(2, _ruleSet.getRuleCount());
- assertEquals(Result.ALLOWED, _ruleSet.check(_testSubject, Operation.CONSUME, ObjectType.QUEUE, normal));
- assertEquals(Result.ALLOWED, _ruleSet.check(_testSubject, Operation.CONSUME, ObjectType.QUEUE, temporary));
+ assertEquals(Result.ALLOWED, _ruleSet.check("user", Operation.CONSUME, ObjectType.QUEUE, normal));
+ assertEquals(Result.ALLOWED, _ruleSet.check("user", Operation.CONSUME, ObjectType.QUEUE, temporary));
}
/*
@@ -215,15 +197,15 @@ public class RuleSetTest extends QpidTestCase
ObjectProperties namedTemporary = new ObjectProperties(_queueName);
namedTemporary.put(ObjectProperties.Property.AUTO_DELETE, Boolean.TRUE);
- assertEquals(Result.DENIED, _ruleSet.check(_testSubject, Operation.CREATE, ObjectType.QUEUE, named));
- assertEquals(Result.DENIED, _ruleSet.check(_testSubject, Operation.CREATE, ObjectType.QUEUE, namedTemporary));
+ assertEquals(Result.DENIED, _ruleSet.check("user", Operation.CREATE, ObjectType.QUEUE, named));
+ assertEquals(Result.DENIED, _ruleSet.check("user", Operation.CREATE, ObjectType.QUEUE, namedTemporary));
- _ruleSet.grant(1, TEST_USER, Permission.ALLOW, Operation.CREATE, ObjectType.QUEUE, named);
- _ruleSet.grant(2, TEST_USER, Permission.DENY, Operation.CREATE, ObjectType.QUEUE, namedTemporary);
+ _ruleSet.grant(1, "user", Permission.ALLOW, Operation.CREATE, ObjectType.QUEUE, named);
+ _ruleSet.grant(2, "user", Permission.DENY, Operation.CREATE, ObjectType.QUEUE, namedTemporary);
assertEquals(2, _ruleSet.getRuleCount());
- assertEquals(Result.ALLOWED, _ruleSet.check(_testSubject, Operation.CREATE, ObjectType.QUEUE, named));
- assertEquals(Result.ALLOWED, _ruleSet.check(_testSubject, Operation.CREATE, ObjectType.QUEUE, namedTemporary));
+ assertEquals(Result.ALLOWED, _ruleSet.check("user", Operation.CREATE, ObjectType.QUEUE, named));
+ assertEquals(Result.ALLOWED, _ruleSet.check("user", Operation.CREATE, ObjectType.QUEUE, namedTemporary));
}
/**
@@ -235,15 +217,15 @@ public class RuleSetTest extends QpidTestCase
ObjectProperties namedTemporary = new ObjectProperties(_queueName);
namedTemporary.put(ObjectProperties.Property.AUTO_DELETE, Boolean.TRUE);
- assertEquals(Result.DENIED, _ruleSet.check(_testSubject, Operation.CREATE, ObjectType.QUEUE, named));
- assertEquals(Result.DENIED, _ruleSet.check(_testSubject, Operation.CREATE, ObjectType.QUEUE, namedTemporary));
+ assertEquals(Result.DENIED, _ruleSet.check("user", Operation.CREATE, ObjectType.QUEUE, named));
+ assertEquals(Result.DENIED, _ruleSet.check("user", Operation.CREATE, ObjectType.QUEUE, namedTemporary));
- _ruleSet.grant(1, TEST_USER, Permission.DENY, Operation.CREATE, ObjectType.QUEUE, namedTemporary);
- _ruleSet.grant(2, TEST_USER, Permission.ALLOW, Operation.CREATE, ObjectType.QUEUE, named);
+ _ruleSet.grant(1, "user", Permission.DENY, Operation.CREATE, ObjectType.QUEUE, namedTemporary);
+ _ruleSet.grant(2, "user", Permission.ALLOW, Operation.CREATE, ObjectType.QUEUE, named);
assertEquals(2, _ruleSet.getRuleCount());
- assertEquals(Result.ALLOWED, _ruleSet.check(_testSubject, Operation.CREATE, ObjectType.QUEUE, named));
- assertEquals(Result.DENIED, _ruleSet.check(_testSubject, Operation.CREATE, ObjectType.QUEUE, namedTemporary));
+ assertEquals(Result.ALLOWED, _ruleSet.check("user", Operation.CREATE, ObjectType.QUEUE, named));
+ assertEquals(Result.DENIED, _ruleSet.check("user", Operation.CREATE, ObjectType.QUEUE, namedTemporary));
}
/**
@@ -257,18 +239,18 @@ public class RuleSetTest extends QpidTestCase
ObjectProperties namedDurable = new ObjectProperties(_queueName);
namedDurable.put(ObjectProperties.Property.DURABLE, Boolean.TRUE);
- assertEquals(Result.DENIED, _ruleSet.check(_testSubject, Operation.CREATE, ObjectType.QUEUE, named));
- assertEquals(Result.DENIED, _ruleSet.check(_testSubject, Operation.CREATE, ObjectType.QUEUE, namedTemporary));
- assertEquals(Result.DENIED, _ruleSet.check(_testSubject, Operation.CREATE, ObjectType.QUEUE, namedDurable));
+ assertEquals(Result.DENIED, _ruleSet.check("user", Operation.CREATE, ObjectType.QUEUE, named));
+ assertEquals(Result.DENIED, _ruleSet.check("user", Operation.CREATE, ObjectType.QUEUE, namedTemporary));
+ assertEquals(Result.DENIED, _ruleSet.check("user", Operation.CREATE, ObjectType.QUEUE, namedDurable));
- _ruleSet.grant(1, TEST_USER, Permission.DENY, Operation.CREATE, ObjectType.QUEUE, namedTemporary);
- _ruleSet.grant(2, TEST_USER, Permission.DENY, Operation.CREATE, ObjectType.QUEUE, namedDurable);
- _ruleSet.grant(3, TEST_USER, Permission.ALLOW, Operation.CREATE, ObjectType.QUEUE, named);
+ _ruleSet.grant(1, "user", Permission.DENY, Operation.CREATE, ObjectType.QUEUE, namedTemporary);
+ _ruleSet.grant(2, "user", Permission.DENY, Operation.CREATE, ObjectType.QUEUE, namedDurable);
+ _ruleSet.grant(3, "user", Permission.ALLOW, Operation.CREATE, ObjectType.QUEUE, named);
assertEquals(3, _ruleSet.getRuleCount());
- assertEquals(Result.ALLOWED, _ruleSet.check(_testSubject, Operation.CREATE, ObjectType.QUEUE, named));
- assertEquals(Result.DENIED, _ruleSet.check(_testSubject, Operation.CREATE, ObjectType.QUEUE, namedTemporary));
- assertEquals(Result.DENIED, _ruleSet.check(_testSubject, Operation.CREATE, ObjectType.QUEUE, namedDurable));
+ assertEquals(Result.ALLOWED, _ruleSet.check("user", Operation.CREATE, ObjectType.QUEUE, named));
+ assertEquals(Result.DENIED, _ruleSet.check("user", Operation.CREATE, ObjectType.QUEUE, namedTemporary));
+ assertEquals(Result.DENIED, _ruleSet.check("user", Operation.CREATE, ObjectType.QUEUE, namedDurable));
}
public void testNamedTemporaryQueueAllowed()
@@ -277,15 +259,15 @@ public class RuleSetTest extends QpidTestCase
ObjectProperties namedTemporary = new ObjectProperties(_queueName);
namedTemporary.put(ObjectProperties.Property.AUTO_DELETE, Boolean.TRUE);
- assertEquals(Result.DENIED, _ruleSet.check(_testSubject, Operation.CREATE, ObjectType.QUEUE, named));
- assertEquals(Result.DENIED, _ruleSet.check(_testSubject, Operation.CREATE, ObjectType.QUEUE, namedTemporary));
+ assertEquals(Result.DENIED, _ruleSet.check("user", Operation.CREATE, ObjectType.QUEUE, named));
+ assertEquals(Result.DENIED, _ruleSet.check("user", Operation.CREATE, ObjectType.QUEUE, namedTemporary));
- _ruleSet.grant(1, TEST_USER, Permission.ALLOW, Operation.CREATE, ObjectType.QUEUE, namedTemporary);
- _ruleSet.grant(2, TEST_USER, Permission.ALLOW, Operation.CREATE, ObjectType.QUEUE, named);
+ _ruleSet.grant(1, "user", Permission.ALLOW, Operation.CREATE, ObjectType.QUEUE, namedTemporary);
+ _ruleSet.grant(2, "user", Permission.ALLOW, Operation.CREATE, ObjectType.QUEUE, named);
assertEquals(2, _ruleSet.getRuleCount());
- assertEquals(Result.ALLOWED, _ruleSet.check(_testSubject, Operation.CREATE, ObjectType.QUEUE, named));
- assertEquals(Result.ALLOWED, _ruleSet.check(_testSubject, Operation.CREATE, ObjectType.QUEUE, namedTemporary));
+ assertEquals(Result.ALLOWED, _ruleSet.check("user", Operation.CREATE, ObjectType.QUEUE, named));
+ assertEquals(Result.ALLOWED, _ruleSet.check("user", Operation.CREATE, ObjectType.QUEUE, namedTemporary));
}
public void testNamedTemporaryQueueDeniedAllowed()
@@ -294,101 +276,14 @@ public class RuleSetTest extends QpidTestCase
ObjectProperties namedTemporary = new ObjectProperties(_queueName);
namedTemporary.put(ObjectProperties.Property.AUTO_DELETE, Boolean.TRUE);
- assertEquals(Result.DENIED, _ruleSet.check(_testSubject, Operation.CREATE, ObjectType.QUEUE, named));
- assertEquals(Result.DENIED, _ruleSet.check(_testSubject, Operation.CREATE, ObjectType.QUEUE, namedTemporary));
+ assertEquals(Result.DENIED, _ruleSet.check("user", Operation.CREATE, ObjectType.QUEUE, named));
+ assertEquals(Result.DENIED, _ruleSet.check("user", Operation.CREATE, ObjectType.QUEUE, namedTemporary));
- _ruleSet.grant(1, TEST_USER, Permission.ALLOW, Operation.CREATE, ObjectType.QUEUE, namedTemporary);
- _ruleSet.grant(2, TEST_USER, Permission.DENY, Operation.CREATE, ObjectType.QUEUE, named);
+ _ruleSet.grant(1, "user", Permission.ALLOW, Operation.CREATE, ObjectType.QUEUE, namedTemporary);
+ _ruleSet.grant(2, "user", Permission.DENY, Operation.CREATE, ObjectType.QUEUE, named);
assertEquals(2, _ruleSet.getRuleCount());
- assertEquals(Result.DENIED, _ruleSet.check(_testSubject, Operation.CREATE, ObjectType.QUEUE, named));
- assertEquals(Result.ALLOWED, _ruleSet.check(_testSubject, Operation.CREATE, ObjectType.QUEUE, namedTemporary));
- }
-
- /**
- * Tests support for the {@link Rule#ALL} keyword.
- */
- public void testAllowToAll()
- {
- _ruleSet.grant(1, Rule.ALL, Permission.ALLOW, Operation.ACCESS, ObjectType.VIRTUALHOST, ObjectProperties.EMPTY);
- assertEquals(1, _ruleSet.getRuleCount());
-
- assertEquals(Result.ALLOWED, _ruleSet.check(TestPrincipalUtils.createTestSubject("usera"),Operation.ACCESS, ObjectType.VIRTUALHOST, ObjectProperties.EMPTY));
- assertEquals(Result.ALLOWED, _ruleSet.check(TestPrincipalUtils.createTestSubject("userb"),Operation.ACCESS, ObjectType.VIRTUALHOST, ObjectProperties.EMPTY));
- }
-
- /**
- * Tests support for ACL groups (i.e. inline groups declared in the ACL file itself).
- */
- public void testAclGroupsSupported()
- {
- assertTrue(_ruleSet.addGroup("aclgroup", Arrays.asList(new String[] {"usera", "userb"})));
-
- _ruleSet.grant(1, "aclgroup", Permission.ALLOW, Operation.ACCESS, ObjectType.VIRTUALHOST, ObjectProperties.EMPTY);
- assertEquals(1, _ruleSet.getRuleCount());
-
- assertEquals(Result.ALLOWED, _ruleSet.check(TestPrincipalUtils.createTestSubject("usera"),Operation.ACCESS, ObjectType.VIRTUALHOST, ObjectProperties.EMPTY));
- assertEquals(Result.ALLOWED, _ruleSet.check(TestPrincipalUtils.createTestSubject("userb"),Operation.ACCESS, ObjectType.VIRTUALHOST, ObjectProperties.EMPTY));
- assertEquals(Result.DEFER, _ruleSet.check(TestPrincipalUtils.createTestSubject("userc"),Operation.ACCESS, ObjectType.VIRTUALHOST, ObjectProperties.EMPTY));
- }
-
- /**
- * Tests support for nested ACL groups.
- */
- public void testNestedAclGroupsSupported()
- {
- assertTrue(_ruleSet.addGroup("aclgroup1", Arrays.asList(new String[] {"userb"})));
- assertTrue(_ruleSet.addGroup("aclgroup2", Arrays.asList(new String[] {"usera", "aclgroup1"})));
-
- _ruleSet.grant(1, "aclgroup2", Permission.ALLOW, Operation.ACCESS, ObjectType.VIRTUALHOST, ObjectProperties.EMPTY);
- assertEquals(1, _ruleSet.getRuleCount());
-
- assertEquals(Result.ALLOWED, _ruleSet.check(TestPrincipalUtils.createTestSubject("usera"),Operation.ACCESS, ObjectType.VIRTUALHOST, ObjectProperties.EMPTY));
- assertEquals(Result.ALLOWED, _ruleSet.check(TestPrincipalUtils.createTestSubject("userb"),Operation.ACCESS, ObjectType.VIRTUALHOST, ObjectProperties.EMPTY));
- }
-
- /**
- * Tests support for nested External groups (i.e. those groups coming from an external source such as an LDAP).
- */
- public void testExternalGroupsSupported()
- {
- _ruleSet.grant(1, "extgroup1", Permission.ALLOW, Operation.ACCESS, ObjectType.VIRTUALHOST, ObjectProperties.EMPTY);
- _ruleSet.grant(2, "extgroup2", Permission.DENY, Operation.ACCESS, ObjectType.VIRTUALHOST, ObjectProperties.EMPTY);
- assertEquals(2, _ruleSet.getRuleCount());
-
- assertEquals(Result.ALLOWED, _ruleSet.check(TestPrincipalUtils.createTestSubject("usera", "extgroup1"),Operation.ACCESS, ObjectType.VIRTUALHOST, ObjectProperties.EMPTY));
- assertEquals(Result.DENIED, _ruleSet.check(TestPrincipalUtils.createTestSubject("userb", "extgroup2"),Operation.ACCESS, ObjectType.VIRTUALHOST, ObjectProperties.EMPTY));
- }
-
- /**
- * Rule order in the ACL determines the outcome of the check. This test ensures that a user who is
- * granted explicit permission on an object, is granted that access even although late a group
- * to which the user belongs is later denied the permission.
- */
- public void testAllowDeterminedByRuleOrder()
- {
- assertTrue(_ruleSet.addGroup("aclgroup", Arrays.asList(new String[] {"usera"})));
-
- _ruleSet.grant(1, "usera", Permission.ALLOW, Operation.ACCESS, ObjectType.VIRTUALHOST, ObjectProperties.EMPTY);
- _ruleSet.grant(2, "aclgroup", Permission.DENY, Operation.ACCESS, ObjectType.VIRTUALHOST, ObjectProperties.EMPTY);
- assertEquals(2, _ruleSet.getRuleCount());
-
- assertEquals(Result.ALLOWED, _ruleSet.check(TestPrincipalUtils.createTestSubject("usera"),Operation.ACCESS, ObjectType.VIRTUALHOST, ObjectProperties.EMPTY));
- }
-
- /**
- * Rule order in the ACL determines the outcome of the check. This tests ensures that a user who is denied
- * access by group, is denied access, despite there being a later rule granting permission to that user.
- */
- public void testDenyDeterminedByRuleOrder()
- {
- assertTrue(_ruleSet.addGroup("aclgroup", Arrays.asList(new String[] {"usera"})));
-
- _ruleSet.grant(1, "aclgroup", Permission.DENY, Operation.ACCESS, ObjectType.VIRTUALHOST, ObjectProperties.EMPTY);
- _ruleSet.grant(2, "usera", Permission.ALLOW, Operation.ACCESS, ObjectType.VIRTUALHOST, ObjectProperties.EMPTY);
-
- assertEquals(2, _ruleSet.getRuleCount());
-
- assertEquals(Result.DENIED, _ruleSet.check(TestPrincipalUtils.createTestSubject("usera"),Operation.ACCESS, ObjectType.VIRTUALHOST, ObjectProperties.EMPTY));
+ assertEquals(Result.DENIED, _ruleSet.check("user", Operation.CREATE, ObjectType.QUEUE, named));
+ assertEquals(Result.ALLOWED, _ruleSet.check("user", Operation.CREATE, ObjectType.QUEUE, namedTemporary));
}
}
diff --git a/qpid/java/broker-plugins/experimental/info/src/main/java/org/apache/qpid/info/Activator.java b/qpid/java/broker-plugins/experimental/info/src/main/java/org/apache/qpid/info/Activator.java
index 21e7be26c1..c7d3fd38ff 100644
--- a/qpid/java/broker-plugins/experimental/info/src/main/java/org/apache/qpid/info/Activator.java
+++ b/qpid/java/broker-plugins/experimental/info/src/main/java/org/apache/qpid/info/Activator.java
@@ -59,14 +59,7 @@ public class Activator implements BundleActivator
_ctx = ctx;
_service = new InfoServiceImpl();
ctx.registerService(InfoService.class.getName(), _service, null);
-
- new Thread(new Runnable()
- {
- public void run()
- {
- sendInfo("STARTUP");
- }
- }).start();
+ sendInfo("STARTUP");
}
}
diff --git a/qpid/java/broker-plugins/experimental/info/src/main/java/org/apache/qpid/info/AppInfo.java b/qpid/java/broker-plugins/experimental/info/src/main/java/org/apache/qpid/info/AppInfo.java
index 9bdd4b9d17..a5d267282b 100644
--- a/qpid/java/broker-plugins/experimental/info/src/main/java/org/apache/qpid/info/AppInfo.java
+++ b/qpid/java/broker-plugins/experimental/info/src/main/java/org/apache/qpid/info/AppInfo.java
@@ -74,6 +74,8 @@ public class AppInfo
appInfoMap.put("port", sc.getPorts().toString());
appInfoMap.put("version", QpidProperties.getReleaseVersion());
appInfoMap.put("vhosts", "standalone");
+ appInfoMap.put("JMXPrincipalDatabase", sc
+ .getJMXPrincipalDatabase());
appInfoMap.put("KeystorePath", sc.getKeystorePath());
appInfoMap.put("PluginDirectory", sc.getPluginDirectory());
appInfoMap.put("CertType", sc.getCertType());
diff --git a/qpid/java/broker-plugins/experimental/shutdown/src/main/java/shutdown.bnd b/qpid/java/broker-plugins/experimental/shutdown/src/main/java/shutdown.bnd
index f6ae79536d..6e005f5bdb 100755
--- a/qpid/java/broker-plugins/experimental/shutdown/src/main/java/shutdown.bnd
+++ b/qpid/java/broker-plugins/experimental/shutdown/src/main/java/shutdown.bnd
@@ -17,7 +17,7 @@
# under the License.
#
-ver: 0.13.0
+ver: 0.9.0
Bundle-SymbolicName: qpid-shutdown-plugin
Bundle-Version: ${ver}
diff --git a/qpid/java/broker-plugins/firewall/src/test/java/org/apache/qpid/server/security/access/FirewallConfigurationTest.java b/qpid/java/broker-plugins/firewall/src/test/java/org/apache/qpid/server/security/access/FirewallConfigurationTest.java
index e078675efc..ab8957e7ef 100644
--- a/qpid/java/broker-plugins/firewall/src/test/java/org/apache/qpid/server/security/access/FirewallConfigurationTest.java
+++ b/qpid/java/broker-plugins/firewall/src/test/java/org/apache/qpid/server/security/access/FirewallConfigurationTest.java
@@ -28,19 +28,12 @@ import java.net.InetSocketAddress;
import org.apache.qpid.server.registry.ApplicationRegistry;
import org.apache.qpid.server.registry.ConfigurationFileApplicationRegistry;
+import org.apache.qpid.server.util.InternalBrokerBaseCase;
import org.apache.qpid.server.virtualhost.VirtualHost;
import org.apache.qpid.server.virtualhost.VirtualHostRegistry;
-import org.apache.qpid.test.utils.QpidTestCase;
-public class FirewallConfigurationTest extends QpidTestCase
+public class FirewallConfigurationTest extends InternalBrokerBaseCase
{
- @Override
- protected void tearDown() throws Exception
- {
- super.tearDown();
- ApplicationRegistry.remove();
- }
-
public void testFirewallConfiguration() throws Exception
{
// Write out config
@@ -50,11 +43,18 @@ public class FirewallConfigurationTest extends QpidTestCase
// Load config
ApplicationRegistry reg = new ConfigurationFileApplicationRegistry(mainFile);
- ApplicationRegistry.initialise(reg);
+ try
+ {
+ ApplicationRegistry.initialise(reg, 1);
- // Test config
- assertFalse(reg.getSecurityManager().accessVirtualhost("test", new InetSocketAddress("127.0.0.1", 65535)));
- assertTrue(reg.getSecurityManager().accessVirtualhost("test", new InetSocketAddress("127.1.2.3", 65535)));
+ // Test config
+ assertFalse(reg.getSecurityManager().accessVirtualhost("test", new InetSocketAddress("127.0.0.1", 65535)));
+ assertTrue(reg.getSecurityManager().accessVirtualhost("test", new InetSocketAddress("127.1.2.3", 65535)));
+ }
+ finally
+ {
+ ApplicationRegistry.remove(1);
+ }
}
public void testCombinedConfigurationFirewall() throws Exception
@@ -80,8 +80,9 @@ public class FirewallConfigurationTest extends QpidTestCase
out.write("\t<cache-directory>${QPID_WORK}/cache</cache-directory>\n");
out.write("\t<management><enabled>false</enabled></management>\n");
out.write("\t<security>\n");
- out.write("\t\t<pd-auth-manager>\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");
@@ -90,7 +91,11 @@ public class FirewallConfigurationTest extends QpidTestCase
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</pd-auth-manager>\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");
@@ -111,10 +116,17 @@ public class FirewallConfigurationTest extends QpidTestCase
// Load config
ApplicationRegistry reg = new ConfigurationFileApplicationRegistry(mainFile);
- ApplicationRegistry.initialise(reg);
+ try
+ {
+ ApplicationRegistry.initialise(reg, 1);
- // Test config
- assertFalse(reg.getSecurityManager().accessVirtualhost("test", new InetSocketAddress("127.0.0.1", 65535)));
+ // Test config
+ assertFalse(reg.getSecurityManager().accessVirtualhost("test", new InetSocketAddress("127.0.0.1", 65535)));
+ }
+ finally
+ {
+ ApplicationRegistry.remove(1);
+ }
}
public void testConfigurationFirewallReload() throws Exception
@@ -127,17 +139,24 @@ public class FirewallConfigurationTest extends QpidTestCase
// Load config
ApplicationRegistry reg = new ConfigurationFileApplicationRegistry(mainFile);
- ApplicationRegistry.initialise(reg);
+ try
+ {
+ ApplicationRegistry.initialise(reg, 1);
- // Test config
- assertFalse(reg.getSecurityManager().accessVirtualhost("test", new InetSocketAddress("127.0.0.1", 65535)));
+ // Test config
+ assertFalse(reg.getSecurityManager().accessVirtualhost("test", new InetSocketAddress("127.0.0.1", 65535)));
- // Switch to deny the connection
- writeConfigFile(mainFile, true);
+ // Switch to deny the connection
+ writeConfigFile(mainFile, true);
- reg.getConfiguration().reparseConfigFileSecuritySections();
+ reg.getConfiguration().reparseConfigFileSecuritySections();
- assertTrue(reg.getSecurityManager().accessVirtualhost("test", new InetSocketAddress("127.0.0.1", 65535)));
+ assertTrue(reg.getSecurityManager().accessVirtualhost("test", new InetSocketAddress("127.0.0.1", 65535)));
+ }
+ finally
+ {
+ ApplicationRegistry.remove(1);
+ }
}
public void testCombinedConfigurationFirewallReload() throws Exception
@@ -162,8 +181,9 @@ public class FirewallConfigurationTest extends QpidTestCase
out.write("\t<plugin-directory>${QPID_HOME}/lib/plugins</plugin-directory>\n");
out.write("\t<management><enabled>false</enabled></management>\n");
out.write("\t<security>\n");
- out.write("\t\t<pd-auth-manager>\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");
@@ -172,7 +192,11 @@ public class FirewallConfigurationTest extends QpidTestCase
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</pd-auth-manager>\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");
@@ -193,40 +217,47 @@ public class FirewallConfigurationTest extends QpidTestCase
// Load config
ApplicationRegistry reg = new ConfigurationFileApplicationRegistry(mainFile);
- ApplicationRegistry.initialise(reg);
+ try
+ {
+ ApplicationRegistry.initialise(reg, 1);
- // Test config
- assertFalse(reg.getSecurityManager().accessVirtualhost("test", new InetSocketAddress("127.0.0.1", 65535)));
+ // Test config
+ assertFalse(reg.getSecurityManager().accessVirtualhost("test", new InetSocketAddress("127.0.0.1", 65535)));
- RandomAccessFile fileBRandom = new RandomAccessFile(fileB, "rw");
- fileBRandom.setLength(0);
- fileBRandom.seek(0);
- fileBRandom.close();
+ 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();
+ 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().reparseConfigFileSecuritySections();
+ reg.getConfiguration().reparseConfigFileSecuritySections();
- assertTrue(reg.getSecurityManager().accessVirtualhost("test", new InetSocketAddress("127.0.0.1", 65535)));
+ assertTrue(reg.getSecurityManager().accessVirtualhost("test", new InetSocketAddress("127.0.0.1", 65535)));
- fileBRandom = new RandomAccessFile(fileB, "rw");
- fileBRandom.setLength(0);
- fileBRandom.seek(0);
- fileBRandom.close();
+ 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();
+ 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().reparseConfigFileSecuritySections();
+ reg.getConfiguration().reparseConfigFileSecuritySections();
- assertFalse(reg.getSecurityManager().accessVirtualhost("test", new InetSocketAddress("127.0.0.1", 65535)));
+ assertFalse(reg.getSecurityManager().accessVirtualhost("test", new InetSocketAddress("127.0.0.1", 65535)));
+ }
+ finally
+ {
+ ApplicationRegistry.remove(1);
+ }
}
private void writeFirewallVhostsFile(File vhostsFile, boolean allow) throws IOException
@@ -260,8 +291,9 @@ public class FirewallConfigurationTest extends QpidTestCase
out.write("\t<plugin-directory>${QPID_HOME}/lib/plugins</plugin-directory>\n");
out.write("\t<management><enabled>false</enabled></management>\n");
out.write("\t<security>\n");
- out.write("\t\t<pd-auth-manager>\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");
@@ -270,7 +302,11 @@ public class FirewallConfigurationTest extends QpidTestCase
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</pd-auth-manager>\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<rule access=\""+ ((allow) ? "allow" : "deny") +"\" network=\"127.0.0.1\"/>");
out.write("\t\t</firewall>\n");
@@ -310,8 +346,8 @@ public class FirewallConfigurationTest extends QpidTestCase
// Load config
ApplicationRegistry reg = new ConfigurationFileApplicationRegistry(mainFile);
- ApplicationRegistry.initialise(reg);
-
+ ApplicationRegistry.initialise(reg, 1);
+
// Test config
VirtualHostRegistry virtualHostRegistry = reg.getVirtualHostRegistry();
VirtualHost virtualHost = virtualHostRegistry.getVirtualHost("test");
diff --git a/qpid/java/broker-plugins/firewall/src/test/java/org/apache/qpid/server/security/access/FirewallPluginTest.java b/qpid/java/broker-plugins/firewall/src/test/java/org/apache/qpid/server/security/access/FirewallPluginTest.java
index 00077d9d9c..2b04962c89 100644
--- a/qpid/java/broker-plugins/firewall/src/test/java/org/apache/qpid/server/security/access/FirewallPluginTest.java
+++ b/qpid/java/broker-plugins/firewall/src/test/java/org/apache/qpid/server/security/access/FirewallPluginTest.java
@@ -27,15 +27,12 @@ import java.net.SocketAddress;
import org.apache.commons.configuration.ConfigurationException;
import org.apache.commons.configuration.XMLConfiguration;
-import org.apache.qpid.server.configuration.ServerConfiguration;
-import org.apache.qpid.server.registry.ApplicationRegistry;
import org.apache.qpid.server.security.Result;
import org.apache.qpid.server.security.access.plugins.Firewall;
import org.apache.qpid.server.security.access.plugins.FirewallConfiguration;
-import org.apache.qpid.server.util.TestApplicationRegistry;
-import org.apache.qpid.test.utils.QpidTestCase;
+import org.apache.qpid.server.util.InternalBrokerBaseCase;
-public class FirewallPluginTest extends QpidTestCase
+public class FirewallPluginTest extends InternalBrokerBaseCase
{
public class RuleInfo
{
@@ -76,23 +73,15 @@ public class FirewallPluginTest extends QpidTestCase
// IP address
private SocketAddress _address;
- private ServerConfiguration _serverConfig;
@Override
- protected void setUp() throws Exception
+ public void setUp() throws Exception
{
super.setUp();
- _serverConfig = new ServerConfiguration(new XMLConfiguration());
- ApplicationRegistry.initialise(new TestApplicationRegistry(_serverConfig));
+
_address = new InetSocketAddress("127.0.0.1", 65535);
}
- @Override
- protected void tearDown() throws Exception
- {
- super.tearDown();
- ApplicationRegistry.remove();
- }
private Firewall initialisePlugin(String defaultAction, RuleInfo[] rules) throws IOException, ConfigurationException
{
// Create sample config file
@@ -119,7 +108,7 @@ public class FirewallPluginTest extends QpidTestCase
}
buf.write("</firewall>");
buf.close();
-
+
// Configure plugin
FirewallConfiguration config = new FirewallConfiguration();
config.setConfiguration("", new XMLConfiguration(confFile));
diff --git a/qpid/java/broker-plugins/simple-xml/MANIFEST.MF b/qpid/java/broker-plugins/simple-xml/MANIFEST.MF
new file mode 100644
index 0000000000..04fe7518df
--- /dev/null
+++ b/qpid/java/broker-plugins/simple-xml/MANIFEST.MF
@@ -0,0 +1,36 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: Qpid Broker-Plugins Simple XML
+Bundle-SymbolicName: broker-plugins-simple-xml
+Bundle-Description: Simple XML ACL plugin for Qpid.
+Bundle-License: http://www.apache.org/licenses/LICENSE-2.0.txt
+Bundle-DocURL: http://www.apache.org/
+Bundle-Version: 1.0.0
+Bundle-Activator: org.apache.qpid.server.security.access.plugins.SimpleXMLActivator
+Bundle-RequiredExecutionEnvironment: JavaSE-1.5
+Bundle-ClassPath: .
+Bundle-ActivationPolicy: lazy
+Import-Package: org.apache.qpid,
+ org.apache.qpid.framing,
+ org.apache.qpid.junit.extensions.util,
+ org.apache.qpid.protocol,
+ org.apache.qpid.server.configuration,
+ org.apache.qpid.server.configuration.plugins,
+ org.apache.qpid.server.exchange,
+ org.apache.qpid.server.management,
+ org.apache.qpid.server.plugins,
+ org.apache.qpid.server.queue,
+ org.apache.qpid.server.security,
+ org.apache.qpid.server.security.access,
+ org.apache.qpid.server.virtualhost,
+ org.apache.qpid.util,
+ org.apache.commons.configuration;version=1.0.0,
+ org.apache.commons.lang;version=1.0.0,
+ org.apache.commons.lang.builder;version=1.0.0,
+ org.apache.log4j;version=1.0.0,
+ javax.management;version=1.0.0,
+ javax.management.openmbean;version=1.0.0,
+ org.osgi.util.tracker;version=1.0.0,
+ org.osgi.framework;version=1.3
+Private-Package: org.apache.qpid.server.security.access.config
+Export-Package: org.apache.qpid.server.security.access.plugins
diff --git a/qpid/java/broker-plugins/simple-xml/build.xml b/qpid/java/broker-plugins/simple-xml/build.xml
new file mode 100644
index 0000000000..d3cd451648
--- /dev/null
+++ b/qpid/java/broker-plugins/simple-xml/build.xml
@@ -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.
+ -->
+<project name="Qpid Broker-Plugins Simple XML" default="build">
+ <property name="module.depends" value="common broker broker-plugins" />
+ <property name="module.test.depends" value="test broker/test common/test management/common systests" />
+
+ <property name="module.manifest" value="MANIFEST.MF" />
+ <property name="module.plugin" value="true" />
+
+ <import file="../../module.xml" />
+
+ <target name="bundle" depends="bundle-tasks" />
+</project>
diff --git a/qpid/java/broker-plugins/simple-xml/src/main/java/org/apache/qpid/server/security/access/config/PrincipalPermissions.java b/qpid/java/broker-plugins/simple-xml/src/main/java/org/apache/qpid/server/security/access/config/PrincipalPermissions.java
new file mode 100755
index 0000000000..d9fc292f03
--- /dev/null
+++ b/qpid/java/broker-plugins/simple-xml/src/main/java/org/apache/qpid/server/security/access/config/PrincipalPermissions.java
@@ -0,0 +1,687 @@
+/*
+ *
+ * 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.config;
+
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.log4j.Logger;
+import org.apache.qpid.framing.AMQShortString;
+import org.apache.qpid.server.security.Result;
+
+@SuppressWarnings("unchecked")
+public class PrincipalPermissions
+{
+ public enum Permission
+ {
+ CONSUME,
+ PUBLISH,
+ CREATEQUEUE,
+ CREATEEXCHANGE,
+ ACCESS,
+ BIND,
+ UNBIND,
+ DELETE,
+ PURGE
+ }
+
+ private static final Logger _logger = Logger.getLogger(PrincipalPermissions.class);
+
+ private static final Object CONSUME_QUEUES_KEY = new Object();
+ private static final Object CONSUME_TEMPORARY_KEY = new Object();
+ private static final Object CONSUME_OWN_QUEUES_ONLY_KEY = new Object();
+
+ private static final Object CREATE_QUEUES_KEY = new Object();
+ private static final Object CREATE_EXCHANGES_KEY = new Object();
+
+
+ private static final Object CREATE_QUEUE_TEMPORARY_KEY = new Object();
+ private static final Object CREATE_QUEUE_QUEUES_KEY = new Object();
+ private static final Object CREATE_QUEUE_EXCHANGES_KEY = new Object();
+
+ private static final Object CREATE_QUEUE_EXCHANGES_ROUTINGKEYS_KEY = new Object();
+
+ private static final int PUBLISH_EXCHANGES_KEY = 0;
+
+ private Map _permissions;
+ private boolean _fullVHostAccess = false;
+
+ private String _user;
+
+
+ public PrincipalPermissions(String user)
+ {
+ _user = user;
+ _permissions = new ConcurrentHashMap();
+ }
+
+ /**
+ *
+ * @param permission the type of permission to check
+ *
+ * @param parameters vararg depending on what permission was passed in
+ * ACCESS: none
+ * BIND: none
+ * CONSUME: AMQShortString queueName, Boolean temporary, Boolean ownQueueOnly
+ * CREATEQUEUE: Boolean temporary, AMQShortString queueName, AMQShortString exchangeName, AMQShortString routingKey
+ * CREATEEXCHANGE: AMQShortString exchangeName, AMQShortString Class
+ * DELETE: none
+ * PUBLISH: Exchange exchange, AMQShortString routingKey
+ * PURGE: none
+ * UNBIND: none
+ */
+ public void grant(Permission permission, Object... parameters)
+ {
+ switch (permission)
+ {
+ case ACCESS:// Parameters : None
+ grantAccess(permission);
+ break;
+ case CONSUME: // Parameters : AMQShortString queueName, Boolean Temporary, Boolean ownQueueOnly
+ grantConsume(permission, parameters);
+ break;
+ case CREATEQUEUE: // Parameters : Boolean temporary, AMQShortString queueName
+ // , AMQShortString exchangeName , AMQShortString routingKey
+ grantCreateQueue(permission, parameters);
+ break;
+ case CREATEEXCHANGE:
+ // Parameters AMQShortString exchangeName , AMQShortString Class
+ grantCreateExchange(permission, parameters);
+ break;
+ case PUBLISH: // Parameters : Exchange exchange, AMQShortString routingKey
+ grantPublish(permission, parameters);
+ break;
+ /* The other cases just fall through to no-op */
+ case DELETE:
+ case BIND: // All the details are currently included in the create setup.
+ case PURGE:
+ case UNBIND:
+ break;
+ }
+
+ }
+
+ private void grantAccess(Permission permission)
+ {
+ _fullVHostAccess = true;
+ }
+
+ private void grantPublish(Permission permission, Object... parameters) {
+ Map publishRights = (Map) _permissions.get(permission);
+
+ if (publishRights == null)
+ {
+ publishRights = new ConcurrentHashMap();
+ _permissions.put(permission, publishRights);
+ }
+
+ if (parameters == null || parameters.length == 0)
+ {
+ //If we have no parameters then allow publish to all destinations
+ // this is signified by having a null value for publish_exchanges
+ }
+ else
+ {
+ Map publish_exchanges = (Map) publishRights.get(PUBLISH_EXCHANGES_KEY);
+
+ if (publish_exchanges == null)
+ {
+ publish_exchanges = new ConcurrentHashMap();
+ publishRights.put(PUBLISH_EXCHANGES_KEY, publish_exchanges);
+ }
+
+
+ HashSet routingKeys = (HashSet) publish_exchanges.get(parameters[0]);
+
+ // Check to see if we have a routing key
+ if (parameters.length == 2)
+ {
+ if (routingKeys == null)
+ {
+ routingKeys = new HashSet<AMQShortString>();
+ }
+ //Add routing key to permitted publish destinations
+ routingKeys.add(parameters[1]);
+ }
+
+ // Add the updated routingkey list or null if all values allowed
+ publish_exchanges.put(parameters[0], routingKeys);
+ }
+ }
+
+ private void grantCreateExchange(Permission permission, Object... parameters) {
+ Map rights = (Map) _permissions.get(permission);
+ if (rights == null)
+ {
+ rights = new ConcurrentHashMap();
+ _permissions.put(permission, rights);
+ }
+
+ Map create_exchanges = (Map) rights.get(CREATE_EXCHANGES_KEY);
+ if (create_exchanges == null)
+ {
+ create_exchanges = new ConcurrentHashMap();
+ rights.put(CREATE_EXCHANGES_KEY, create_exchanges);
+ }
+
+ //Should perhaps error if parameters[0] is null;
+ AMQShortString name = parameters.length > 0 ? (AMQShortString) parameters[0] : null;
+ AMQShortString className = parameters.length > 1 ? (AMQShortString) parameters[1] : new AMQShortString("direct");
+
+ //Store the exchangeName / class mapping if the mapping is null
+ rights.put(name, className);
+ }
+
+ private void grantCreateQueue(Permission permission, Object... parameters)
+ {
+ Map createRights = (Map) _permissions.get(permission);
+
+ if (createRights == null)
+ {
+ createRights = new ConcurrentHashMap();
+ _permissions.put(permission, createRights);
+ }
+
+ //The existence of the empty map mean permission to all.
+ if (parameters.length == 0)
+ {
+ return;
+ }
+
+ // Get the queues map
+ Map create_queues = (Map) createRights.get(CREATE_QUEUES_KEY);
+
+ //Initialiase the queue permissions if not already done
+ if (create_queues == null)
+ {
+ create_queues = new ConcurrentHashMap();
+ //initialise temp queue permission to false and overwrite below if true
+ create_queues.put(CREATE_QUEUE_TEMPORARY_KEY, false);
+ createRights.put(CREATE_QUEUES_KEY, create_queues);
+ }
+
+ //Create empty list of queues
+ Map create_queues_queues = (Map) create_queues.get(CREATE_QUEUE_QUEUES_KEY);
+
+ if (create_queues_queues == null)
+ {
+ create_queues_queues = new ConcurrentHashMap();
+ create_queues.put(CREATE_QUEUE_QUEUES_KEY, create_queues_queues);
+ }
+
+ // If we are initialising and granting CREATE rights to all temporary queues, then that's all we do
+ Boolean temporary = false;
+ if (parameters.length == 1)
+ {
+ temporary = (Boolean) parameters[0];
+ create_queues.put(CREATE_QUEUE_TEMPORARY_KEY, temporary);
+ return;
+ }
+
+ //From here we can be permissioning a variety of things, with varying parameters
+ AMQShortString queueName = parameters.length > 1 ? (AMQShortString) parameters[1] : null;
+ AMQShortString exchangeName = parameters.length > 2 ? (AMQShortString) parameters[2] : null;
+ //Set the routingkey to the specified value or the queueName if present
+ AMQShortString routingKey = (parameters.length > 3 && null != parameters[3]) ? (AMQShortString) parameters[3] : queueName;
+ // if we have a queueName then we need to store any associated exchange / rk bindings
+ if (queueName != null)
+ {
+ Map queue = (Map) create_queues_queues.get(queueName);
+ if (queue == null)
+ {
+ queue = new ConcurrentHashMap();
+ create_queues_queues.put(queueName, queue);
+ }
+
+ if (exchangeName != null)
+ {
+ queue.put(exchangeName, routingKey);
+ }
+
+ //If no exchange is specified then the presence of the queueName in the map says any exchange is ok
+ }
+
+ // Store the exchange that we are being granted rights to. This will be used as part of binding
+
+ //Lookup the list of exchanges
+ Map create_queues_exchanges = (Map) create_queues.get(CREATE_QUEUE_EXCHANGES_KEY);
+
+ if (create_queues_exchanges == null)
+ {
+ create_queues_exchanges = new ConcurrentHashMap();
+ create_queues.put(CREATE_QUEUE_EXCHANGES_KEY, create_queues_exchanges);
+ }
+
+ //if we have an exchange
+ if (exchangeName != null)
+ {
+ //Retrieve the list of permitted exchanges.
+ Map exchanges = (Map) create_queues_exchanges.get(exchangeName);
+
+ if (exchanges == null)
+ {
+ exchanges = new ConcurrentHashMap();
+ create_queues_exchanges.put(exchangeName, exchanges);
+ }
+
+ //Store the binding details of queue/rk for this exchange.
+ if (queueName != null)
+ {
+ //Retrieve the list of permitted routingKeys.
+ Map rKeys = (Map) exchanges.get(exchangeName);
+
+ if (rKeys == null)
+ {
+ rKeys = new ConcurrentHashMap();
+ exchanges.put(CREATE_QUEUE_EXCHANGES_ROUTINGKEYS_KEY, rKeys);
+ }
+
+ rKeys.put(queueName, routingKey);
+ }
+ }
+ }
+
+ /**
+ * Grant consume permissions
+ */
+ private void grantConsume(Permission permission, Object... parameters)
+ {
+ Map consumeRights = (Map) _permissions.get(permission);
+
+ if (consumeRights == null)
+ {
+ consumeRights = new ConcurrentHashMap();
+ _permissions.put(permission, consumeRights);
+
+ //initialise own and temporary rights to false to be overwritten below if set
+ consumeRights.put(CONSUME_TEMPORARY_KEY, false);
+ consumeRights.put(CONSUME_OWN_QUEUES_ONLY_KEY, false);
+ }
+
+
+ //if we only have one param then we're permissioning temporary queues and topics
+ if (parameters.length == 1)
+ {
+ Boolean temporary = (Boolean) parameters[0];
+
+ if (temporary)
+ {
+ consumeRights.put(CONSUME_TEMPORARY_KEY, true);
+ }
+ }
+
+ //if we have 2 parameters - should be a contract for this, but for now we'll handle it as is
+ if (parameters.length == 2)
+ {
+ AMQShortString queueName = (AMQShortString) parameters[0];
+ Boolean ownQueueOnly = (Boolean) parameters[1];
+
+ if (ownQueueOnly)
+ {
+ consumeRights.put(CONSUME_OWN_QUEUES_ONLY_KEY, true);
+ }
+
+ LinkedList queues = (LinkedList) consumeRights.get(CONSUME_QUEUES_KEY);
+ if (queues == null)
+ {
+ queues = new LinkedList();
+ consumeRights.put(CONSUME_QUEUES_KEY, queues);
+ }
+
+ if (queueName != null)
+ {
+ queues.add(queueName);
+ }
+ }
+ }
+
+ /**
+ *
+ * @param permission the type of permission to check
+ *
+ * @param parameters vararg depending on what permission was passed in
+ * ACCESS: none
+ * BIND: QueueBindBody bindmethod, Exchange exchange, AMQQueue queue, AMQShortString routingKey
+ * CONSUME: AMQQueue queue
+ * CREATEQUEUE: Boolean autodelete, AMQShortString name
+ * CREATEEXCHANGE: AMQShortString exchangeName
+ * DELETE: none
+ * PUBLISH: Exchange exchange, AMQShortString routingKey
+ * PURGE: none
+ * UNBIND: none
+ */
+ public Result authorise(Permission permission, String... parameters)
+ {
+
+ switch (permission)
+ {
+ case ACCESS://No Parameters
+ return Result.ALLOWED; // The existence of this user-specific PP infers some level of access is authorised
+ case BIND: // Parameters : QueueBindMethod , exhangeName , queueName, routingKey
+ return authoriseBind(parameters);
+ case CREATEQUEUE:// Parameters : autoDelete, queueName
+ return authoriseCreateQueue(permission, parameters);
+ case CREATEEXCHANGE: //Parameters: exchangeName
+ return authoriseCreateExchange(permission, parameters);
+ case CONSUME: // Parameters : queueName, autoDelete, owner
+ return authoriseConsume(permission, parameters);
+ case PUBLISH: // Parameters : exchangeName, routingKey
+ return authorisePublish(permission, parameters);
+ /* Fall through */
+ case DELETE:
+ case PURGE:
+ case UNBIND:
+ default:
+ if(_fullVHostAccess)
+ {
+ //user has been granted full access to the vhost
+ return Result.ALLOWED;
+ }
+ else
+ {
+ //SimpleXML ACL does not implement these permissions and should abstain
+ return Result.ABSTAIN;
+ }
+ }
+
+ }
+
+ private Result authoriseConsume(Permission permission, String... parameters)
+ {
+ if(_fullVHostAccess)
+ {
+ //user has been granted full access to the vhost
+ return Result.ALLOWED;
+ }
+
+ if (parameters.length == 3)
+ {
+ AMQShortString queueName = new AMQShortString(parameters[0]);
+ Boolean autoDelete = Boolean.valueOf(parameters[1]);
+ AMQShortString owner = new AMQShortString(parameters[2]);
+ Map queuePermissions = (Map) _permissions.get(permission);
+
+ _logger.error("auth consume on " + StringUtils.join(parameters, ", "));
+
+ if (queuePermissions == null)
+ {
+ //we have a problem - we've never granted this type of permission .....
+ return Result.DENIED;
+ }
+
+ List queues = (List) queuePermissions.get(CONSUME_QUEUES_KEY);
+
+ Boolean temporaryQueues = (Boolean) queuePermissions.get(CONSUME_TEMPORARY_KEY);
+ Boolean ownQueuesOnly = (Boolean) queuePermissions.get(CONSUME_OWN_QUEUES_ONLY_KEY);
+
+
+ // If user is allowed to consume from temporary queues and this is a temp queue then allow it.
+ if (temporaryQueues && autoDelete)
+ {
+ // This will allow consumption from any temporary queue including ones not owned by this user.
+ // Of course the exclusivity will not be broken.
+ {
+
+ // if not limited to ownQueuesOnly then ok else check queue Owner.
+ return (!ownQueuesOnly || owner.equals(_user)) ? Result.ALLOWED : Result.DENIED;
+ }
+ }
+ //if this is a temporary queue and the user does not have permissions for temporary queues then deny
+ else if (!temporaryQueues && autoDelete)
+ {
+ return Result.DENIED;
+ }
+
+ // if queues are white listed then ensure it is ok
+ if (queues != null)
+ {
+ // if no queues are listed then ALL are ok othereise it must be specified.
+ if (ownQueuesOnly)
+ {
+ if (owner.equals(_user))
+ {
+ return (queues.size() == 0 || queues.contains(queueName)) ? Result.ALLOWED : Result.DENIED;
+ }
+ else
+ {
+ return Result.DENIED;
+ }
+ }
+
+ // If we are
+ return (queues.size() == 0 || queues.contains(queueName)) ? Result.ALLOWED : Result.DENIED;
+ }
+ }
+
+ // Can't authenticate without the right parameters
+ return Result.DENIED;
+ }
+
+ private Result authorisePublish(Permission permission, String... parameters)
+ {
+ if(_fullVHostAccess)
+ {
+ //user has been granted full access to the vhost
+ return Result.ALLOWED;
+ }
+
+ Map publishRights = (Map) _permissions.get(permission);
+
+ if (publishRights == null)
+ {
+ return Result.DENIED;
+ }
+
+ Map exchanges = (Map) publishRights.get(PUBLISH_EXCHANGES_KEY);
+
+ // Having no exchanges listed gives full publish rights to all exchanges
+ if (exchanges == null)
+ {
+ return Result.ALLOWED;
+ }
+ // Otherwise exchange must be listed in the white list
+
+ // If the map doesn't have the exchange then it isn't allowed
+ AMQShortString exchangeName = new AMQShortString(parameters[0]);
+ if (!exchanges.containsKey(exchangeName))
+ {
+ return Result.DENIED;
+ }
+ else
+ {
+ // Get valid routing keys
+ HashSet routingKeys = (HashSet) exchanges.get(exchangeName);
+
+ // Having no routingKeys in the map then all are allowed.
+ if (routingKeys == null)
+ {
+ return Result.ALLOWED;
+ }
+ else
+ {
+ // We have routingKeys so a match must be found to allowed binding
+ Iterator keys = routingKeys.iterator();
+
+ AMQShortString publishRKey = new AMQShortString(parameters[1]);
+
+ boolean matched = false;
+ while (keys.hasNext() && !matched)
+ {
+ AMQShortString rkey = (AMQShortString) keys.next();
+
+ if (rkey.endsWith("*"))
+ {
+ matched = publishRKey.startsWith(rkey.subSequence(0, rkey.length() - 1));
+ }
+ else
+ {
+ matched = publishRKey.equals(rkey);
+ }
+ }
+ return (matched) ? Result.ALLOWED : Result.DENIED;
+ }
+ }
+ }
+
+ private Result authoriseCreateExchange(Permission permission, String... parameters)
+ {
+ if(_fullVHostAccess)
+ {
+ //user has been granted full access to the vhost
+ return Result.ALLOWED;
+ }
+
+ Map rights = (Map) _permissions.get(permission);
+
+ AMQShortString exchangeName = new AMQShortString(parameters[0]);
+
+ // If the exchange list is doesn't exist then all is allowed else
+ // check the valid exchanges
+ if (rights == null || rights.containsKey(exchangeName))
+ {
+ return Result.ALLOWED;
+ }
+ else
+ {
+ return Result.DENIED;
+ }
+ }
+
+ private Result authoriseCreateQueue(Permission permission, String... parameters)
+ {
+ if(_fullVHostAccess)
+ {
+ //user has been granted full access to the vhost
+ return Result.ALLOWED;
+ }
+
+ Map createRights = (Map) _permissions.get(permission);
+
+ // If there are no create rights then deny request
+ if (createRights == null)
+ {
+ return Result.DENIED;
+ }
+
+ //Look up the Queue Creation Rights
+ Map create_queues = (Map) createRights.get(CREATE_QUEUES_KEY);
+
+ //Lookup the list of queues allowed to be created
+ Map create_queues_queues = (Map) create_queues.get(CREATE_QUEUE_QUEUES_KEY);
+
+
+ Boolean autoDelete = Boolean.valueOf(parameters[0]);
+ AMQShortString queueName = new AMQShortString(parameters[1]);
+
+ if (autoDelete)// we have a temporary queue
+ {
+ return ((Boolean) create_queues.get(CREATE_QUEUE_TEMPORARY_KEY)) ? Result.ALLOWED : Result.DENIED;
+ }
+ else
+ {
+ // If there is a white list then check
+ if (create_queues_queues == null || create_queues_queues.containsKey(queueName))
+ {
+ return Result.ALLOWED;
+ }
+ else
+ {
+ return Result.DENIED;
+ }
+
+ }
+ }
+
+ private Result authoriseBind(String... parameters)
+ {
+ if(_fullVHostAccess)
+ {
+ //user has been granted full access to the vhost
+ return Result.ALLOWED;
+ }
+
+ AMQShortString exchangeName = new AMQShortString(parameters[1]);
+ AMQShortString bind_queueName = new AMQShortString(parameters[2]);
+ AMQShortString routingKey = new AMQShortString(parameters[3]);
+
+ //Get all Create Rights for this user
+ Map bindCreateRights = (Map) _permissions.get(Permission.CREATEQUEUE);
+
+ //Lookup the list of queues
+ Map bind_create_queues_queues = (Map) bindCreateRights.get(CREATE_QUEUE_QUEUES_KEY);
+
+ // Check and see if we have a queue white list to check
+ if (bind_create_queues_queues != null)
+ {
+ //There a white list for queues
+ Map exchangeDetails = (Map) bind_create_queues_queues.get(bind_queueName);
+
+ if (exchangeDetails == null) //Then all queue can be bound to all exchanges.
+ {
+ return Result.ALLOWED;
+ }
+
+ // Check to see if we have a white list of routingkeys to check
+ Map rkeys = (Map) exchangeDetails.get(exchangeName);
+
+ // if keys is null then any rkey is allowed on this exchange
+ if (rkeys == null)
+ {
+ // There is no routingkey white list
+ return Result.ALLOWED;
+ }
+ else
+ {
+ // We have routingKeys so a match must be found to allowed binding
+ Iterator keys = rkeys.keySet().iterator();
+
+ boolean matched = false;
+ while (keys.hasNext() && !matched)
+ {
+ AMQShortString rkey = (AMQShortString) keys.next();
+ if (rkey.endsWith("*"))
+ {
+ matched = routingKey.startsWith(rkey.subSequence(0, rkey.length() - 1).toString());
+ }
+ else
+ {
+ matched = routingKey.equals(rkey);
+ }
+ }
+
+
+ return (matched) ? Result.ALLOWED : Result.DENIED;
+ }
+
+
+ }
+ else
+ {
+ //no white list so all allowed.
+ return Result.ALLOWED;
+ }
+ }
+}
diff --git a/qpid/java/broker-plugins/simple-xml/src/main/java/org/apache/qpid/server/security/access/plugins/SimpleXML.java b/qpid/java/broker-plugins/simple-xml/src/main/java/org/apache/qpid/server/security/access/plugins/SimpleXML.java
new file mode 100644
index 0000000000..ab43653122
--- /dev/null
+++ b/qpid/java/broker-plugins/simple-xml/src/main/java/org/apache/qpid/server/security/access/plugins/SimpleXML.java
@@ -0,0 +1,427 @@
+/*
+ * 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 static org.apache.qpid.server.security.access.ObjectProperties.Property.*;
+
+import java.security.Principal;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+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.plugins.ConfigurationPlugin;
+import org.apache.qpid.server.security.AbstractPlugin;
+import org.apache.qpid.server.security.Result;
+import org.apache.qpid.server.security.SecurityManager;
+import org.apache.qpid.server.security.SecurityPluginFactory;
+import org.apache.qpid.server.security.access.ObjectProperties;
+import org.apache.qpid.server.security.access.ObjectType;
+import org.apache.qpid.server.security.access.Operation;
+import org.apache.qpid.server.security.access.config.PrincipalPermissions;
+import org.apache.qpid.server.security.access.config.PrincipalPermissions.Permission;
+
+/**
+ * This uses the default
+ */
+public class SimpleXML extends AbstractPlugin
+{
+ public static final Logger _logger = Logger.getLogger(SimpleXML.class);
+
+ private Map<String, PrincipalPermissions> _users;
+
+ public static final SecurityPluginFactory<SimpleXML> FACTORY = new SecurityPluginFactory<SimpleXML>()
+ {
+ public SimpleXML newInstance(ConfigurationPlugin config) throws ConfigurationException
+ {
+ SimpleXMLConfiguration configuration = config.getConfiguration(SimpleXMLConfiguration.class.getName());
+
+ // If there is no configuration for this plugin then don't load it.
+ if (configuration == null)
+ {
+ return null;
+ }
+
+ SimpleXML plugin = new SimpleXML();
+ plugin.configure(configuration);
+ return plugin;
+ }
+
+ public String getPluginName()
+ {
+ return SimpleXML.class.getName();
+ }
+
+ public Class<SimpleXML> getPluginClass()
+ {
+ return SimpleXML.class;
+ }
+ };
+
+ public void configure(ConfigurationPlugin config)
+ {
+ super.configure(config);
+
+ SimpleXMLConfiguration configuration = (SimpleXMLConfiguration) _config;
+
+ _users = new ConcurrentHashMap<String, PrincipalPermissions>();
+
+ processConfig(configuration.getConfiguration());
+ }
+
+ private void processConfig(Configuration config)
+ {
+ processPublish(config);
+ processConsume(config);
+ processCreate(config);
+ processAccess(config);
+ }
+
+ /**
+ * @param config XML Configuration
+ */
+ private void processAccess(Configuration config)
+ {
+ Configuration accessConfig = config.subset("access");
+
+ if (accessConfig.isEmpty())
+ {
+ //there is no access configuration to process
+ return;
+ }
+
+ // Process users that have full access permission
+ String[] users = accessConfig.getStringArray("users.user");
+
+ for (String user : users)
+ {
+ grant(Permission.ACCESS, user);
+ }
+ }
+
+ /**
+ * Publish format takes Exchange + Routing Key Pairs
+ *
+ * @param config XML Configuration
+ */
+ private void processPublish(Configuration config)
+ {
+ Configuration publishConfig = config.subset("publish");
+
+ // Process users that have full publish permission
+ String[] users = publishConfig.getStringArray("users.user");
+
+ for (String user : users)
+ {
+ grant(Permission.PUBLISH, user);
+ }
+
+ // Process exchange limited users
+ int exchangeCount = 0;
+ Configuration exchangeConfig = publishConfig.subset("exchanges.exchange(" + exchangeCount + ")");
+
+ while (!exchangeConfig.isEmpty())
+ {
+ // Get Exchange Name
+ AMQShortString exchangeName = new AMQShortString(exchangeConfig.getString("name"));
+
+ // Get Routing Keys
+ int keyCount = 0;
+ Configuration routingkeyConfig = exchangeConfig.subset("routing_keys.routing_key(" + keyCount + ")");
+
+ while (!routingkeyConfig.isEmpty())
+ {
+ // Get RoutingKey Value
+ AMQShortString routingKeyValue = new AMQShortString(routingkeyConfig.getString("value"));
+
+ // Apply Exchange + RoutingKey permissions to Users
+ users = routingkeyConfig.getStringArray("users.user");
+ for (String user : users)
+ {
+ grant(Permission.PUBLISH, user, exchangeName, routingKeyValue);
+ }
+
+ // Apply permissions to Groups
+
+ // Check for more configs
+ keyCount++;
+ routingkeyConfig = exchangeConfig.subset("routing_keys.routing_key(" + keyCount + ")");
+ }
+
+ // Apply Exchange wide permissions to Users
+ users = exchangeConfig.getStringArray("exchange(" + exchangeCount + ").users.user");
+
+ for (String user : users)
+ {
+ grant(Permission.PUBLISH, user, exchangeName);
+ }
+
+ // Apply permissions to Groups
+ exchangeCount++;
+ exchangeConfig = publishConfig.subset("exchanges.exchange(" + exchangeCount + ")");
+ }
+ }
+
+ private void grant(Permission permission, String user, Object... parameters)
+ {
+ PrincipalPermissions permissions = _users.get(user);
+
+ if (permissions == null)
+ {
+ permissions = new PrincipalPermissions(user);
+ }
+
+ _users.put(user, permissions);
+ permissions.grant(permission, parameters);
+ }
+
+ /**
+ * @param config XML Configuration
+ */
+ private void processConsume(Configuration config)
+ {
+ boolean temporary = false;
+ Configuration tempConfig = null;
+ Configuration consumeConfig = config.subset("consume");
+
+ tempConfig = consumeConfig.subset("queues.temporary(0)");
+ if (tempConfig != null)
+ {
+ temporary = true;
+ }
+
+ //Permission all users who have rights to temp queues and topics
+ if (tempConfig != null && !tempConfig.isEmpty())
+ {
+ String[] tempUsers = tempConfig.getStringArray("users.user");
+ for (String user : tempUsers)
+ {
+ grant(Permission.CONSUME, user, temporary);
+ }
+ }
+
+ // Process queue limited users
+ int queueCount = 0;
+ Configuration queueConfig = consumeConfig.subset("queues.queue(" + queueCount + ")");
+
+ while (!queueConfig.isEmpty())
+ {
+ // Get queue Name
+ AMQShortString queueName = new AMQShortString(queueConfig.getString("name"));
+ // if there is no name then there may be a temporary element
+
+ boolean ownQueues = queueConfig.containsKey("own_queues");
+
+ // Process permissions for this queue
+ String[] users = queueConfig.getStringArray("users.user");
+ for (String user : users)
+ {
+ grant(Permission.CONSUME, user, queueName, ownQueues);
+ }
+
+ // See if we have another config
+ queueCount++;
+ queueConfig = consumeConfig.subset("queues.queue(" + queueCount + ")");
+ }
+
+ // Process users that have full consume permission
+ String[] users = consumeConfig.getStringArray("users.user");
+
+ for (String user : users)
+ {
+ //NOTE: this call does not appear to do anything inside the grant section for consume
+ grant(Permission.CONSUME, user);
+ }
+ }
+
+ /**
+ * @param config XML Configuration
+ */
+ private void processCreate(Configuration config)
+ {
+ boolean temporary = false;
+ Configuration tempConfig = null;
+
+ Configuration createConfig = config.subset("create");
+
+ tempConfig = createConfig.subset("queues.temporary(0)");
+ if (tempConfig != null)
+ {
+ temporary = true;
+ }
+
+ //Permission all users who have rights to temp queues and topics
+ if (tempConfig != null && !tempConfig.isEmpty())
+ {
+ String[] tempUsers = tempConfig.getStringArray("users.user");
+ for (String user : tempUsers)
+ {
+ grant(Permission.CREATEQUEUE, user, temporary);
+ }
+ }
+ // Process create permissions for queue creation
+ int queueCount = 0;
+ Configuration queueConfig = createConfig.subset("queues.queue(" + queueCount + ")");
+
+ while (!queueConfig.isEmpty())
+ {
+ // Get queue Name
+ AMQShortString queueName = new AMQShortString(queueConfig.getString("name"));
+
+ int exchangeCount = 0;
+ Configuration exchangeConfig = queueConfig.subset("exchanges.exchange(" + exchangeCount + ")");
+
+ while (!exchangeConfig.isEmpty())
+ {
+
+ AMQShortString exchange = new AMQShortString(exchangeConfig.getString("name"));
+ AMQShortString routingKey = new AMQShortString(exchangeConfig.getString("routing_key"));
+
+ // Process permissions for this queue
+ String[] users = exchangeConfig.getStringArray("users.user");
+ for (String user : users)
+ {
+ //This is broken as the user name is not stored
+ grant(Permission.CREATEEXCHANGE, user, exchange);
+
+ //This call could be cleaned up as temporary is now being set earlier (above)
+ grant(Permission.CREATEQUEUE, user, temporary, (queueName.equals("") ? null : queueName), (exchange
+ .equals("") ? null : exchange), (routingKey.equals("") ? null : routingKey));
+ }
+
+ // See if we have another config
+ exchangeCount++;
+ exchangeConfig = queueConfig.subset("exchanges.exchange(" + exchangeCount + ")");
+ }
+
+ // Process users that are not bound to an exchange
+ String[] users = queueConfig.getStringArray("users.user");
+
+ for (String user : users)
+ {
+ grant(Permission.CREATEQUEUE, user, temporary, queueName);
+ }
+
+ // See if we have another config
+ queueCount++;
+ queueConfig = createConfig.subset("queues.queue(" + queueCount + ")");
+ }
+
+ // Process create permissions for exchange creation
+ int exchangeCount = 0;
+ Configuration exchangeConfig = createConfig.subset("exchanges.exchange(" + exchangeCount + ")");
+
+ while (!exchangeConfig.isEmpty())
+ {
+ AMQShortString exchange = new AMQShortString(exchangeConfig.getString("name"));
+ AMQShortString clazz = new AMQShortString(exchangeConfig.getString("class"));
+
+ // Process permissions for this queue
+ String[] users = exchangeConfig.getStringArray("users.user");
+ for (String user : users)
+ {
+ //And this is broken too
+ grant(Permission.CREATEEXCHANGE, user, exchange, clazz);
+ }
+
+ // See if we have another config
+ exchangeCount++;
+ exchangeConfig = queueConfig.subset("exchanges.exchange(" + exchangeCount + ")");
+ }
+
+ // Process users that have full create permission
+ String[] users = createConfig.getStringArray("users.user");
+
+ for (String user : users)
+ {
+ grant(Permission.CREATEEXCHANGE, user);
+ grant(Permission.CREATEQUEUE, user);
+ }
+ }
+
+ public Result access(ObjectType objectType, Object instance)
+ {
+ Principal principal = SecurityManager.getThreadPrincipal();
+ if (principal == null)
+ {
+ return getDefault(); // Default if there is no user associated with the thread
+ }
+ PrincipalPermissions principalPermissions = _users.get(principal.getName());
+ if (principalPermissions == null)
+ {
+ return Result.DENIED;
+ }
+
+ // Authorise object access
+ if (objectType == ObjectType.VIRTUALHOST)
+ {
+ return principalPermissions.authorise(Permission.ACCESS);
+ }
+
+ // Default
+ return getDefault();
+ }
+
+ public Result authorise(Operation operation, ObjectType objectType, ObjectProperties properties)
+ {
+ Principal principal = SecurityManager.getThreadPrincipal();
+ if (principal == null)
+ {
+ return getDefault(); // Default if there is no user associated with the thread
+ }
+ PrincipalPermissions principalPermissions = _users.get(principal.getName());
+ if (principalPermissions == null)
+ {
+ return Result.DENIED;
+ }
+
+ // Authorise operation
+ switch (operation)
+ {
+ case CONSUME:
+ return principalPermissions.authorise(Permission.CONSUME, properties.get(NAME), properties.get(AUTO_DELETE), properties.get(OWNER));
+ case PUBLISH:
+ return principalPermissions.authorise(Permission.PUBLISH, properties.get(NAME), properties.get(ROUTING_KEY));
+ case CREATE:
+ if (objectType == ObjectType.EXCHANGE)
+ {
+ return principalPermissions.authorise(Permission.CREATEEXCHANGE, properties.get(NAME));
+ }
+ else if (objectType == ObjectType.QUEUE)
+ {
+ return principalPermissions.authorise(Permission.CREATEQUEUE, properties.get(AUTO_DELETE), properties.get(NAME));
+ }
+ case ACCESS:
+ return principalPermissions.authorise(Permission.ACCESS);
+ case BIND:
+ return principalPermissions.authorise(Permission.BIND, null, properties.get(NAME), properties.get(QUEUE_NAME), properties.get(ROUTING_KEY));
+ case UNBIND:
+ return principalPermissions.authorise(Permission.UNBIND);
+ case DELETE:
+ return principalPermissions.authorise(Permission.DELETE);
+ case PURGE:
+ return principalPermissions.authorise(Permission.PURGE);
+ }
+
+ // Default
+ return getDefault();
+ }
+}
diff --git a/qpid/java/broker-plugins/simple-xml/src/main/java/org/apache/qpid/server/security/access/plugins/SimpleXMLActivator.java b/qpid/java/broker-plugins/simple-xml/src/main/java/org/apache/qpid/server/security/access/plugins/SimpleXMLActivator.java
new file mode 100644
index 0000000000..c09a9da0d8
--- /dev/null
+++ b/qpid/java/broker-plugins/simple-xml/src/main/java/org/apache/qpid/server/security/access/plugins/SimpleXMLActivator.java
@@ -0,0 +1,42 @@
+/*
+ *
+ * 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 org.apache.qpid.server.configuration.plugins.ConfigurationPluginFactory;
+import org.apache.qpid.server.security.SecurityPluginActivator;
+import org.apache.qpid.server.security.SecurityPluginFactory;
+import org.osgi.framework.BundleActivator;
+
+/**
+ * The OSGi {@link BundleActivator} for {@link SimpleXML}.
+ */
+public class SimpleXMLActivator extends SecurityPluginActivator
+{
+ public SecurityPluginFactory getFactory()
+ {
+ return SimpleXML.FACTORY;
+ }
+
+ public ConfigurationPluginFactory getConfigurationFactory()
+ {
+ return SimpleXMLConfiguration.FACTORY;
+ }
+}
diff --git a/qpid/java/broker-plugins/simple-xml/src/main/java/org/apache/qpid/server/security/access/plugins/SimpleXMLConfiguration.java b/qpid/java/broker-plugins/simple-xml/src/main/java/org/apache/qpid/server/security/access/plugins/SimpleXMLConfiguration.java
new file mode 100644
index 0000000000..e95c21b590
--- /dev/null
+++ b/qpid/java/broker-plugins/simple-xml/src/main/java/org/apache/qpid/server/security/access/plugins/SimpleXMLConfiguration.java
@@ -0,0 +1,57 @@
+/*
+ *
+ * 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.Arrays;
+import java.util.List;
+
+import org.apache.commons.configuration.Configuration;
+import org.apache.commons.configuration.ConfigurationException;
+import org.apache.qpid.server.configuration.plugins.ConfigurationPlugin;
+import org.apache.qpid.server.configuration.plugins.ConfigurationPluginFactory;
+
+public class SimpleXMLConfiguration extends ConfigurationPlugin
+{
+ public static final ConfigurationPluginFactory FACTORY = new ConfigurationPluginFactory()
+ {
+ public ConfigurationPlugin newInstance(String path, Configuration config) throws ConfigurationException
+ {
+ ConfigurationPlugin instance = new SimpleXMLConfiguration();
+ instance.setConfiguration(path, config);
+ return instance;
+ }
+
+ public List<String> getParentPaths()
+ {
+ return Arrays.asList("security.access_control_list", "virtualhosts.virtualhost.security.access_control_list");
+ }
+ };
+
+ public String[] getElementsProcessed()
+ {
+ return new String[] { "" };
+ }
+
+ public Configuration getConfiguration()
+ {
+ return _configuration;
+ }
+}
diff --git a/qpid/java/broker-plugins/simple-xml/src/test/java/org/apache/qpid/server/security/access/PrincipalPermissionsTest.java b/qpid/java/broker-plugins/simple-xml/src/test/java/org/apache/qpid/server/security/access/PrincipalPermissionsTest.java
new file mode 100644
index 0000000000..65ab12a095
--- /dev/null
+++ b/qpid/java/broker-plugins/simple-xml/src/test/java/org/apache/qpid/server/security/access/PrincipalPermissionsTest.java
@@ -0,0 +1,209 @@
+/*
+ *
+ * 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;
+
+import org.apache.qpid.AMQException;
+import org.apache.qpid.framing.AMQShortString;
+import org.apache.qpid.server.security.Result;
+import org.apache.qpid.server.security.access.config.PrincipalPermissions;
+import org.apache.qpid.server.security.access.config.PrincipalPermissions.Permission;
+import org.apache.qpid.test.utils.QpidTestCase;
+
+public class PrincipalPermissionsTest extends QpidTestCase
+{
+ private String _user = "user";
+ private PrincipalPermissions _perms;
+
+ // Common things that are passed to frame constructors
+ private AMQShortString _queueName = new AMQShortString(this.getClass().getName() + "queue");
+ private AMQShortString _tempQueueName = new AMQShortString(this.getClass().getName() + "tempqueue");
+ private AMQShortString _exchangeName = new AMQShortString("amq.direct");
+ private AMQShortString _routingKey = new AMQShortString(this.getClass().getName() + "route");
+ private boolean _autoDelete = false;
+ private AMQShortString _exchangeType = new AMQShortString("direct");
+ private Boolean _temporary = false;
+ private Boolean _ownQueue = false;
+
+ @Override
+ public void setUp() throws Exception
+ {
+ super.setUp();
+
+ _perms = new PrincipalPermissions(_user);
+ }
+
+
+ public void testPrincipalPermissions()
+ {
+ assertNotNull(_perms);
+ assertEquals(Result.ALLOWED, _perms.authorise(Permission.ACCESS, (String[]) null));
+ }
+
+ // FIXME: test has been disabled since the permissions assume that the user has tried to create
+ // the queue first. QPID-1597
+ public void disableTestBind() throws Exception
+ {
+ String[] args = new String[]{null, _exchangeName.asString(), _queueName.asString(), _routingKey.asString()};
+
+ assertEquals(Result.DENIED, _perms.authorise(Permission.BIND, args));
+ _perms.grant(Permission.BIND, (Object[]) null);
+ assertEquals(Result.ALLOWED, _perms.authorise(Permission.BIND, args));
+ }
+
+ public void testQueueCreate()
+ {
+ Object[] grantArgs = new Object[]{_temporary , _queueName, _exchangeName, _routingKey};
+ String[] authArgs = new String[]{Boolean.toString(_autoDelete), _queueName.asString()};
+
+ assertEquals(Result.DENIED, _perms.authorise(Permission.CREATEQUEUE, authArgs));
+ _perms.grant(Permission.CREATEQUEUE, grantArgs);
+ assertEquals(Result.ALLOWED, _perms.authorise(Permission.CREATEQUEUE, authArgs));
+ }
+
+ public void testQueueCreateWithNullRoutingKey()
+ {
+ Object[] grantArgs = new Object[]{_temporary , _queueName, _exchangeName, null};
+ String[] authArgs = new String[]{Boolean.toString(_autoDelete), _queueName.asString()};
+
+ assertEquals(Result.DENIED, _perms.authorise(Permission.CREATEQUEUE, authArgs));
+ _perms.grant(Permission.CREATEQUEUE, grantArgs);
+ assertEquals(Result.ALLOWED, _perms.authorise(Permission.CREATEQUEUE, authArgs));
+ }
+
+ // FIXME disabled, this fails due to grant putting the grant into the wrong map QPID-1598
+ public void disableTestExchangeCreate()
+ {
+ String[] authArgs = new String[]{_exchangeName.asString()};
+ Object[] grantArgs = new Object[]{_exchangeName, _exchangeType};
+
+ assertEquals(Result.DENIED, _perms.authorise(Permission.CREATEEXCHANGE, authArgs));
+ _perms.grant(Permission.CREATEEXCHANGE, grantArgs);
+ assertEquals(Result.ALLOWED, _perms.authorise(Permission.CREATEEXCHANGE, authArgs));
+ }
+
+ public void testConsume()
+ {
+ String[] authArgs = new String[]{_queueName.asString(), Boolean.toString(_autoDelete), _user};
+ Object[] grantArgs = new Object[]{_queueName, _ownQueue};
+
+ // FIXME: This throws a null pointer exception QPID-1599
+ // assertFalse(_perms.authorise(Permission.CONSUME, authArgs));
+ _perms.grant(Permission.CONSUME, grantArgs);
+ assertEquals(Result.ALLOWED, _perms.authorise(Permission.CONSUME, authArgs));
+ }
+
+ public void testPublish() throws AMQException
+ {
+ String[] authArgs = new String[]{_exchangeName.asString(), _routingKey.asString()};
+ Object[] grantArgs = new Object[]{_exchangeName, _routingKey};
+
+ assertEquals(Result.DENIED, _perms.authorise(Permission.PUBLISH, authArgs));
+ _perms.grant(Permission.PUBLISH, grantArgs);
+ assertEquals(Result.ALLOWED, _perms.authorise(Permission.PUBLISH, authArgs));
+ }
+
+ public void testVhostAccess()
+ {
+ //Tests that granting a user Virtualhost level access allows all authorisation requests
+ //where previously they would be denied
+
+ //QPID-2133 createExchange rights currently allow all exchange creation unless rights for creating some
+ //specific exchanges are granted. Grant a specific exchange creation to cause all others to be denied.
+ Object[] createArgsCreateExchange = new Object[]{new AMQShortString("madeup"), _exchangeType};
+ String[] authArgsCreateExchange = new String[]{_exchangeName.asString()};
+ assertEquals("Exchange creation was not allowed", Result.ALLOWED, _perms.authorise(Permission.CREATEEXCHANGE, authArgsCreateExchange));
+ _perms.grant(Permission.CREATEEXCHANGE, createArgsCreateExchange);
+
+ String[] authArgsPublish = new String[]{_exchangeName.asString(), _routingKey.asString()};
+ String[] authArgsConsume = new String[]{_queueName.asString(), Boolean.toString(_autoDelete), _user};
+ String[] authArgsCreateQueue = new String[]{Boolean.toString(_autoDelete), _queueName.asString()};
+// QueueBindBodyImpl bind = new QueueBindBodyImpl(_ticket, _queueName, _exchangeName, _routingKey, _nowait, _arguments);
+ String[] authArgsBind = new String[]{ null, _exchangeName.asString(), _queueName.asString(), _routingKey.asString()};
+
+ assertEquals("Exchange creation was not denied", Result.DENIED, _perms.authorise(Permission.CREATEEXCHANGE, authArgsCreateExchange));
+ assertEquals("Publish was not denied", Result.DENIED, _perms.authorise(Permission.PUBLISH, authArgsPublish));
+ assertEquals("Consume creation was not denied", Result.DENIED, _perms.authorise(Permission.CONSUME, authArgsConsume));
+ assertEquals("Queue creation was not denied", Result.DENIED, _perms.authorise(Permission.CREATEQUEUE, authArgsCreateQueue));
+ //BIND pre-grant authorise check disabled due to QPID-1597
+ //assertEquals("Binding creation was not denied", Result.DENIED, _perms.authorise(Permission.BIND, authArgsBind));
+
+ _perms.grant(Permission.ACCESS);
+
+ assertEquals("Exchange creation was not allowed", Result.ALLOWED, _perms.authorise(Permission.CREATEEXCHANGE, authArgsCreateExchange));
+ assertEquals("Publish was not allowed", Result.ALLOWED, _perms.authorise(Permission.PUBLISH, authArgsPublish));
+ assertEquals("Consume creation was not allowed", Result.ALLOWED, _perms.authorise(Permission.CONSUME, authArgsConsume));
+ assertEquals("Queue creation was not allowed", Result.ALLOWED, _perms.authorise(Permission.CREATEQUEUE, authArgsCreateQueue));
+ assertEquals("Binding creation was not allowed", Result.ALLOWED, _perms.authorise(Permission.BIND, authArgsBind));
+ }
+
+ /**
+ * If the consume permission for temporary queues is for an unnamed queue then is should
+ * be global for any temporary queue but not for any non-temporary queue
+ */
+ public void testTemporaryUnnamedQueueConsume()
+ {
+ String[] authNonTempQArgs = new String[]{_queueName.asString(), Boolean.toString(_autoDelete), _user};
+ String[] authTempQArgs = new String[]{_tempQueueName.asString(), Boolean.TRUE.toString(), _user};
+ Object[] grantArgs = new Object[]{true};
+
+ _perms.grant(Permission.CONSUME, grantArgs);
+
+ //Next line shows up bug - non temp queue should be denied
+ assertEquals(Result.DENIED, _perms.authorise(Permission.CONSUME, authNonTempQArgs));
+ assertEquals(Result.ALLOWED, _perms.authorise(Permission.CONSUME, authTempQArgs));
+ }
+
+ /**
+ * Test that temporary queue permissions before queue perms in the ACL config work correctly
+ */
+ public void testTemporaryQueueFirstConsume()
+ {
+ String[] authNonTempQArgs = new String[]{_queueName.asString(), Boolean.toString(_autoDelete), _user};
+ String[] authTempQArgs = new String[]{_tempQueueName.asString(), Boolean.TRUE.toString(), _user};
+ Object[] grantArgs = new Object[]{true};
+ Object[] grantNonTempQArgs = new Object[]{_queueName, _ownQueue};
+
+ //should not matter if the temporary permission is processed first or last
+ _perms.grant(Permission.CONSUME, grantNonTempQArgs);
+ _perms.grant(Permission.CONSUME, grantArgs);
+
+ assertEquals(Result.ALLOWED, _perms.authorise(Permission.CONSUME, authNonTempQArgs));
+ assertEquals(Result.ALLOWED, _perms.authorise(Permission.CONSUME, authTempQArgs));
+ }
+
+ /**
+ * Test that temporary queue permissions after queue perms in the ACL config work correctly
+ */
+ public void testTemporaryQueueLastConsume()
+ {
+ String[] authNonTempQArgs = new String[]{_queueName.asString(), Boolean.toString(_autoDelete), _user};
+ String[] authTempQArgs = new String[]{_tempQueueName.asString(), Boolean.TRUE.toString(), _user};
+ Object[] grantArgs = new Object[]{true};
+ Object[] grantNonTempQArgs = new Object[]{_queueName, _ownQueue};
+
+ //should not matter if the temporary permission is processed first or last
+ _perms.grant(Permission.CONSUME, grantArgs);
+ _perms.grant(Permission.CONSUME, grantNonTempQArgs);
+
+ assertEquals(Result.ALLOWED, _perms.authorise(Permission.CONSUME, authNonTempQArgs));
+ assertEquals(Result.ALLOWED, _perms.authorise(Permission.CONSUME, authTempQArgs));
+ }
+}
diff --git a/qpid/java/broker/bin/qpid-server.bat b/qpid/java/broker/bin/qpid-server.bat
index af543decb3..c81f5fc3e7 100644
--- a/qpid/java/broker/bin/qpid-server.bat
+++ b/qpid/java/broker/bin/qpid-server.bat
@@ -108,13 +108,13 @@ goto beforeRunShift
:runJdpa
REM USAGE: adds debugging options to the java command, use
-REM USAGE: JPDA_TRANSPORT and JPDA_ADDRESS to customize the debugging
+REM USAGE: JDPA_TRANSPORT and JPDA_ADDRESS to customize the debugging
REM USAGE: behavior and use JPDA_OPTS to override it entirely
-if not "%JPDA_OPTS%" == "" goto beforeRunShift
-if "%JPDA_TRANSPORT%" == "" set JPDA_TRANSPORT=dt_socket
+if "%JPDA_OPTS%" == "" goto beforeRunShift
+if "%JPDA_TRANSPORT%" == "" set JPDA_TRANSPORT=-dt_socket
if "%JPDA_ADDRESS%" == "" set JPDA_ADDRESS=8000
-set JPDA_OPTS=-Xdebug -Xrunjdwp:transport=%JPDA_TRANSPORT%,address=%JPDA_ADDRESS%,server=y,suspend=n
-REM set QPID_OPTS="%QPID_OPTS% %JPDA_OPTS%"
+set JPDA_OPTS="-Xdebug -Xrunjdwp:transport=%JPDA_TRANSPORT%,address=%JPDA_ADDRESS%,server=y,suspend=n"
+set QPID_OPTS="%QPID_OPTS% %JPDA_OPTS%"
goto beforeRunShift
:runExternalClasspath
@@ -192,7 +192,7 @@ rem QPID_OPTS intended to hold any -D props for use
rem user must enclose any value for QPID_OPTS in double quotes
:runCommand
set MODULE_JARS=%QPID_MODULE_JARS%
-set COMMAND="%JAVA_HOME%\bin\java" %JAVA_VM% %JAVA_MEM% %JAVA_GC% %QPID_OPTS% %JPDA_OPTS% %SYSTEM_PROPS% -cp "%CLASSPATH%;%MODULE_JARS%" org.apache.qpid.server.Main %QPID_ARGS%
+set COMMAND="%JAVA_HOME%\bin\java" %JAVA_VM% %JAVA_MEM% %JAVA_GC% %QPID_OPTS% %SYSTEM_PROPS% -cp "%CLASSPATH%;%MODULE_JARS%" org.apache.qpid.server.Main %QPID_ARGS%
if "%debug%" == "true" echo %CLASSPATH%;%LAUNCH_JAR%;%MODULE_JARS%
if "%debug%" == "true" echo %COMMAND%
diff --git a/qpid/java/broker/etc/access b/qpid/java/broker/etc/access
new file mode 100644
index 0000000000..58b7443fa9
--- /dev/null
+++ b/qpid/java/broker/etc/access
@@ -0,0 +1,19 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+guest:localhost(rw),test(rw) \ No newline at end of file
diff --git a/qpid/java/broker/etc/config.xml b/qpid/java/broker/etc/config.xml
index 61f1c832b1..14b9456067 100644
--- a/qpid/java/broker/etc/config.xml
+++ b/qpid/java/broker/etc/config.xml
@@ -37,10 +37,17 @@
<keystorePath>/path/to/keystore.ks</keystorePath>
<keystorePassword>keystorepass</keystorePassword>
</ssl>
+ <qpidnio>false</qpidnio>
+ <protectio>
+ <enabled>false</enabled>
+ <readBufferLimitSize>262144</readBufferLimitSize>
+ <writeBufferLimitSize>262144</writeBufferLimitSize>
+ </protectio>
+ <transport>nio</transport>
<port>5672</port>
<sslport>8672</sslport>
- <socketReceiveBuffer>262144</socketReceiveBuffer>
- <socketSendBuffer>262144</socketSendBuffer>
+ <socketReceiveBuffer>32768</socketReceiveBuffer>
+ <socketSendBuffer>32768</socketSendBuffer>
</connector>
<management>
<enabled>true</enabled>
@@ -62,8 +69,10 @@
</advanced>
<security>
- <pd-auth-manager>
+ <principal-databases>
+ <!-- Example use of Base64 encoded MD5 hashes for authentication via CRAM-MD5-Hashed -->
<principal-database>
+ <name>passwordfile</name>
<class>org.apache.qpid.server.security.auth.database.PlainPasswordFilePrincipalDatabase</class>
<attributes>
<attribute>
@@ -72,11 +81,16 @@
</attribute>
</attributes>
</principal-database>
- </pd-auth-manager>
+ </principal-databases>
<allow-all />
<msg-auth>false</msg-auth>
+
+ <jmx>
+ <access>${conf}/jmxremote.access</access>
+ <principal-database>passwordfile</principal-database>
+ </jmx>
</security>
<virtualhosts>${conf}/virtualhosts.xml</virtualhosts>
diff --git a/qpid/java/broker/etc/jmxremote.access b/qpid/java/broker/etc/jmxremote.access
new file mode 100644
index 0000000000..1a51a6991b
--- /dev/null
+++ b/qpid/java/broker/etc/jmxremote.access
@@ -0,0 +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.
+
+#Generated by JMX Console : Last edited by user:admin
+#Tue Jun 12 16:46:39 BST 2007
+admin=admin
+guest=readonly
+user=readwrite
diff --git a/qpid/java/broker/etc/passwdVhost b/qpid/java/broker/etc/passwdVhost
new file mode 100644
index 0000000000..48ce8299b6
--- /dev/null
+++ b/qpid/java/broker/etc/passwdVhost
@@ -0,0 +1,19 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+guest:guest:localhost,test
diff --git a/qpid/java/broker/etc/qpid-server.conf.jpp b/qpid/java/broker/etc/qpid-server.conf.jpp
index 0378c82fd9..3ed2431ef3 100644
--- a/qpid/java/broker/etc/qpid-server.conf.jpp
+++ b/qpid/java/broker/etc/qpid-server.conf.jpp
@@ -17,7 +17,8 @@
# under the License.
#
-QPID_LIBS=$(build-classpath commons-beanutils \
+QPID_LIBS=$(build-classpath backport-util-concurrent \
+ commons-beanutils \
commons-beanutils-core \
commons-cli \
commons-codec \
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/qmf/QMFService.java b/qpid/java/broker/src/main/java/org/apache/qpid/qmf/QMFService.java
index f0f7678cd9..a6f319cb1f 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/qmf/QMFService.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/qmf/QMFService.java
@@ -1096,11 +1096,6 @@ public class QMFService implements ConfigStore.ConfigEventListener, Closeable
return Boolean.FALSE;
}
- public Long getFlowStoppedCount()
- {
- return 0L;
- }
-
public BrokerSchema.QueueClass.PurgeMethodResponseCommand purge(final BrokerSchema.QueueClass.PurgeMethodResponseCommandFactory factory,
final Long request)
{
@@ -1311,12 +1306,6 @@ public class QMFService implements ConfigStore.ConfigEventListener, Closeable
{
return _obj.isShadow();
}
-
- public Boolean getUserProxyAuth()
- {
- // TODO
- return false;
- }
}
private class SessionDelegate implements BrokerSchema.SessionDelegate
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/AMQBrokerManagerMBean.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/AMQBrokerManagerMBean.java
index d1ea5dba69..a612f280d6 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
@@ -327,74 +327,4 @@ public class AMQBrokerManagerMBean extends AMQManagedObject implements ManagedBr
{
return getObjectNameForSingleInstanceMBean();
}
-
- public void resetStatistics() throws Exception
- {
- getVirtualHost().resetStatistics();
- }
-
- public double getPeakMessageDeliveryRate()
- {
- return getVirtualHost().getMessageDeliveryStatistics().getPeak();
- }
-
- public double getPeakDataDeliveryRate()
- {
- return getVirtualHost().getDataDeliveryStatistics().getPeak();
- }
-
- public double getMessageDeliveryRate()
- {
- return getVirtualHost().getMessageDeliveryStatistics().getRate();
- }
-
- public double getDataDeliveryRate()
- {
- return getVirtualHost().getDataDeliveryStatistics().getRate();
- }
-
- public long getTotalMessagesDelivered()
- {
- return getVirtualHost().getMessageDeliveryStatistics().getTotal();
- }
-
- public long getTotalDataDelivered()
- {
- return getVirtualHost().getDataDeliveryStatistics().getTotal();
- }
-
- public double getPeakMessageReceiptRate()
- {
- return getVirtualHost().getMessageReceiptStatistics().getPeak();
- }
-
- public double getPeakDataReceiptRate()
- {
- return getVirtualHost().getDataReceiptStatistics().getPeak();
- }
-
- public double getMessageReceiptRate()
- {
- return getVirtualHost().getMessageReceiptStatistics().getRate();
- }
-
- public double getDataReceiptRate()
- {
- return getVirtualHost().getDataReceiptStatistics().getRate();
- }
-
- public long getTotalMessagesReceived()
- {
- return getVirtualHost().getMessageReceiptStatistics().getTotal();
- }
-
- public long getTotalDataReceived()
- {
- return getVirtualHost().getDataReceiptStatistics().getTotal();
- }
-
- public boolean isStatisticsEnabled()
- {
- return getVirtualHost().isStatisticsEnabled();
- }
}
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 8141533045..4f86c82578 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
@@ -22,7 +22,6 @@ package org.apache.qpid.server;
import org.apache.log4j.Logger;
-import org.apache.qpid.AMQConnectionException;
import org.apache.qpid.AMQException;
import org.apache.qpid.AMQSecurityException;
import org.apache.qpid.framing.AMQMethodBody;
@@ -142,7 +141,6 @@ public class AMQChannel implements SessionConfig, AMQSessionModel
private final AtomicLong _txnCommits = new AtomicLong(0);
private final AtomicLong _txnRejects = new AtomicLong(0);
private final AtomicLong _txnCount = new AtomicLong(0);
- private final AtomicLong _txnUpdateTime = new AtomicLong(0);
private final AMQProtocolSession _session;
private AtomicBoolean _closing = new AtomicBoolean(false);
@@ -202,11 +200,6 @@ public class AMQChannel implements SessionConfig, AMQSessionModel
return !(_transaction instanceof AutoCommitTransaction);
}
- public boolean inTransaction()
- {
- return isTransactional() && _txnUpdateTime.get() > 0 && _transaction.getTransactionStartTime() > 0;
- }
-
private void incrementOutstandingTxnsIfNecessary()
{
if(isTransactional())
@@ -302,6 +295,7 @@ public class AMQChannel implements SessionConfig, AMQSessionModel
});
deliverCurrentMessageIfComplete();
+
}
}
@@ -339,15 +333,11 @@ public class AMQChannel implements SessionConfig, AMQSessionModel
{
_transaction.enqueue(destinationQueues, _currentMessage, new MessageDeliveryAction(_currentMessage, destinationQueues, isTransactional()));
incrementOutstandingTxnsIfNecessary();
- updateTransactionalActivity();
}
}
}
finally
{
- long bodySize = _currentMessage.getSize();
- long timestamp = ((BasicContentHeaderProperties) _currentMessage.getContentHeader().getProperties()).getTimestamp();
- _session.registerMessageReceived(bodySize, timestamp);
_currentMessage = null;
}
}
@@ -804,7 +794,6 @@ public class AMQChannel implements SessionConfig, AMQSessionModel
{
Collection<QueueEntry> ackedMessages = getAckedMessages(deliveryTag, multiple);
_transaction.dequeue(ackedMessages, new MessageAcknowledgeAction(ackedMessages));
- updateTransactionalActivity();
}
private Collection<QueueEntry> getAckedMessages(long deliveryTag, boolean multiple)
@@ -979,17 +968,6 @@ public class AMQChannel implements SessionConfig, AMQSessionModel
}
- /**
- * Update last transaction activity timestamp
- */
- private void updateTransactionalActivity()
- {
- if (isTransactional())
- {
- _txnUpdateTime.set(System.currentTimeMillis());
- }
- }
-
public String toString()
{
return "["+_session.toString()+":"+_channelId+"]";
@@ -1040,7 +1018,6 @@ public class AMQChannel implements SessionConfig, AMQSessionModel
{
getProtocolSession().getProtocolOutputConverter().writeDeliver(entry, getChannelId(),
deliveryTag, sub.getConsumerTag());
- _session.registerMessageDelivered(entry.getMessage().getSize());
}
};
@@ -1079,11 +1056,11 @@ public class AMQChannel implements SessionConfig, AMQSessionModel
private boolean checkMessageUserId(ContentHeaderBody header)
{
AMQShortString userID =
- header.getProperties() instanceof BasicContentHeaderProperties
- ? ((BasicContentHeaderProperties) header.getProperties()).getUserId()
+ header.properties instanceof BasicContentHeaderProperties
+ ? ((BasicContentHeaderProperties) header.properties).getUserId()
: null;
- return (!MSG_AUTH || _session.getAuthorizedPrincipal().getName().equals(userID == null? "" : userID.toString()));
+ return (!MSG_AUTH || _session.getPrincipal().getName().equals(userID == null? "" : userID.toString()));
}
@@ -1430,36 +1407,4 @@ public class AMQChannel implements SessionConfig, AMQSessionModel
{
_session.mgmtCloseChannel(_channelId);
}
-
- public void checkTransactionStatus(long openWarn, long openClose, long idleWarn, long idleClose) throws AMQException
- {
- if (inTransaction())
- {
- long currentTime = System.currentTimeMillis();
- long openTime = currentTime - _transaction.getTransactionStartTime();
- long idleTime = currentTime - _txnUpdateTime.get();
-
- // Log a warning on idle or open transactions
- if (idleWarn > 0L && idleTime > idleWarn)
- {
- CurrentActor.get().message(_logSubject, ChannelMessages.IDLE_TXN(idleTime));
- _logger.warn("IDLE TRANSACTION ALERT " + _logSubject.toString() + " " + idleTime + " ms");
- }
- else if (openWarn > 0L && openTime > openWarn)
- {
- CurrentActor.get().message(_logSubject, ChannelMessages.OPEN_TXN(openTime));
- _logger.warn("OPEN TRANSACTION ALERT " + _logSubject.toString() + " " + openTime + " ms");
- }
-
- // Close connection for idle or open transactions that have timed out
- if (idleClose > 0L && idleTime > idleClose)
- {
- getConnectionModel().closeSession(this, AMQConstant.RESOURCE_ERROR, "Idle transaction timed out");
- }
- else if (openClose > 0L && openTime > openClose)
- {
- getConnectionModel().closeSession(this, AMQConstant.RESOURCE_ERROR, "Open transaction timed out");
- }
- }
- }
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/Broker.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/Broker.java
deleted file mode 100644
index ffc323a23b..0000000000
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/Broker.java
+++ /dev/null
@@ -1,420 +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;
-
-import static org.apache.qpid.transport.ConnectionSettings.WILDCARD_ADDRESS;
-
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.InetAddress;
-import java.net.InetSocketAddress;
-import java.util.EnumSet;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Properties;
-import java.util.Set;
-
-import org.apache.log4j.PropertyConfigurator;
-import org.apache.log4j.xml.QpidLog4JConfigurator;
-import org.apache.qpid.server.configuration.ServerConfiguration;
-import org.apache.qpid.server.configuration.ServerNetworkTransportConfiguration;
-import org.apache.qpid.server.configuration.management.ConfigurationManagementMBean;
-import org.apache.qpid.server.information.management.ServerInformationMBean;
-import org.apache.qpid.server.logging.SystemOutMessageLogger;
-import org.apache.qpid.server.logging.actors.BrokerActor;
-import org.apache.qpid.server.logging.actors.CurrentActor;
-import org.apache.qpid.server.logging.actors.GenericActor;
-import org.apache.qpid.server.logging.management.LoggingManagementMBean;
-import org.apache.qpid.server.logging.messages.BrokerMessages;
-import org.apache.qpid.server.protocol.AMQProtocolEngineFactory;
-import org.apache.qpid.server.protocol.MultiVersionProtocolEngineFactory;
-import org.apache.qpid.server.protocol.AmqpProtocolVersion;
-import org.apache.qpid.server.registry.ApplicationRegistry;
-import org.apache.qpid.server.registry.ConfigurationFileApplicationRegistry;
-import org.apache.qpid.server.transport.QpidAcceptor;
-import org.apache.qpid.ssl.SSLContextFactory;
-import org.apache.qpid.transport.NetworkTransportConfiguration;
-import org.apache.qpid.transport.network.IncomingNetworkTransport;
-import org.apache.qpid.transport.network.Transport;
-import org.apache.qpid.transport.network.mina.MinaNetworkTransport;
-
-public class Broker
-{
- private static final int IPV4_ADDRESS_LENGTH = 4;
- private static final char IPV4_LITERAL_SEPARATOR = '.';
-
- protected static class InitException extends RuntimeException
- {
- private static final long serialVersionUID = 1L;
-
- InitException(String msg, Throwable cause)
- {
- super(msg, cause);
- }
- }
-
- public void shutdown()
- {
- ApplicationRegistry.remove();
- }
-
- public void startup() throws Exception
- {
- startup(new BrokerOptions());
- }
-
- public void startup(BrokerOptions options) throws Exception
- {
- try
- {
- CurrentActor.set(new BrokerActor(new SystemOutMessageLogger()));
- startupImpl(options);
- }
- finally
- {
- CurrentActor.remove();
- }
- }
-
- private void startupImpl(final BrokerOptions options) throws Exception
- {
- final String qpidHome = options.getQpidHome();
- final File configFile = getConfigFile(options.getConfigFile(),
- BrokerOptions.DEFAULT_CONFIG_FILE, qpidHome, true);
-
- CurrentActor.get().message(BrokerMessages.CONFIG(configFile.getAbsolutePath()));
-
- File logConfigFile = getConfigFile(options.getLogConfigFile(),
- BrokerOptions.DEFAULT_LOG_CONFIG_FILE, qpidHome, false);
-
- configureLogging(logConfigFile, options.getLogWatchFrequency());
-
- ConfigurationFileApplicationRegistry config = new ConfigurationFileApplicationRegistry(configFile);
- ServerConfiguration serverConfig = config.getConfiguration();
- updateManagementPort(serverConfig, options.getJmxPort());
-
- ApplicationRegistry.initialise(config);
-
- // We have already loaded the BrokerMessages class by this point so we
- // need to refresh the locale setting incase we had a different value in
- // the configuration.
- BrokerMessages.reload();
-
- // AR.initialise() sets and removes its own actor so we now need to set the actor
- // for the remainder of the startup, and the default actor if the stack is empty
- CurrentActor.set(new BrokerActor(config.getCompositeStartupMessageLogger()));
- CurrentActor.setDefault(new BrokerActor(config.getRootMessageLogger()));
- GenericActor.setDefaultMessageLogger(config.getRootMessageLogger());
-
- try
- {
- configureLoggingManagementMBean(logConfigFile, options.getLogWatchFrequency());
-
- ConfigurationManagementMBean configMBean = new ConfigurationManagementMBean();
- configMBean.register();
-
- ServerInformationMBean sysInfoMBean = new ServerInformationMBean(config);
- sysInfoMBean.register();
-
- Set<Integer> ports = new HashSet<Integer>(options.getPorts());
- if(ports.isEmpty())
- {
- parsePortList(ports, serverConfig.getPorts());
- }
-
- Set<Integer> sslPorts = new HashSet<Integer>(options.getSSLPorts());
- if(sslPorts.isEmpty())
- {
- parsePortList(sslPorts, serverConfig.getSSLPorts());
- }
-
- Set<Integer> exclude_0_10 = new HashSet<Integer>(options.getExcludedPorts(ProtocolExclusion.v0_10));
- if(exclude_0_10.isEmpty())
- {
- parsePortList(exclude_0_10, serverConfig.getPortExclude010());
- }
-
- Set<Integer> exclude_0_9_1 = new HashSet<Integer>(options.getExcludedPorts(ProtocolExclusion.v0_9_1));
- if(exclude_0_9_1.isEmpty())
- {
- parsePortList(exclude_0_9_1, serverConfig.getPortExclude091());
- }
-
- Set<Integer> exclude_0_9 = new HashSet<Integer>(options.getExcludedPorts(ProtocolExclusion.v0_9));
- if(exclude_0_9.isEmpty())
- {
- parsePortList(exclude_0_9, serverConfig.getPortExclude09());
- }
-
- Set<Integer> exclude_0_8 = new HashSet<Integer>(options.getExcludedPorts(ProtocolExclusion.v0_8));
- if(exclude_0_8.isEmpty())
- {
- parsePortList(exclude_0_8, serverConfig.getPortExclude08());
- }
-
- String bindAddr = options.getBind();
- if (bindAddr == null)
- {
- bindAddr = serverConfig.getBind();
- }
-
- InetAddress bindAddress = null;
- if (bindAddr.equals(WILDCARD_ADDRESS))
- {
- bindAddress = new InetSocketAddress(0).getAddress();
- }
- else
- {
- bindAddress = InetAddress.getByAddress(parseIP(bindAddr));
- }
- String hostName = bindAddress.getCanonicalHostName();
-
- if (!serverConfig.getSSLOnly())
- {
- for(int port : ports)
- {
- Set<AmqpProtocolVersion> supported = EnumSet.allOf(AmqpProtocolVersion.class);
-
- if(exclude_0_10.contains(port))
- {
- supported.remove(AmqpProtocolVersion.v0_10);
- }
-
- if(exclude_0_9_1.contains(port))
- {
- supported.remove(AmqpProtocolVersion.v0_9_1);
- }
- if(exclude_0_9.contains(port))
- {
- supported.remove(AmqpProtocolVersion.v0_9);
- }
- if(exclude_0_8.contains(port))
- {
- supported.remove(AmqpProtocolVersion.v0_8);
- }
-
- NetworkTransportConfiguration settings =
- new ServerNetworkTransportConfiguration(serverConfig, port, bindAddress.getHostName(), Transport.TCP);
-
- IncomingNetworkTransport transport = Transport.getIncomingTransportInstance();
- MultiVersionProtocolEngineFactory protocolEngineFactory =
- new MultiVersionProtocolEngineFactory(hostName, supported);
-
- transport.accept(settings, protocolEngineFactory, null);
- ApplicationRegistry.getInstance().addAcceptor(new InetSocketAddress(bindAddress, port),
- new QpidAcceptor(transport,"TCP"));
- CurrentActor.get().message(BrokerMessages.LISTENING("TCP", port));
- }
- }
-
- if (serverConfig.getEnableSSL())
- {
- String keystorePath = serverConfig.getKeystorePath();
- String keystorePassword = serverConfig.getKeystorePassword();
- String certType = serverConfig.getCertType();
- SSLContextFactory sslFactory =
- new SSLContextFactory(keystorePath, keystorePassword, certType);
-
- for(int sslPort : sslPorts)
- {
- NetworkTransportConfiguration settings =
- new ServerNetworkTransportConfiguration(serverConfig, sslPort, bindAddress.getHostName(), Transport.TCP);
-
- IncomingNetworkTransport transport = new MinaNetworkTransport();
-
- transport.accept(settings, new AMQProtocolEngineFactory(), sslFactory);
-
- ApplicationRegistry.getInstance().addAcceptor(new InetSocketAddress(bindAddress, sslPort),
- new QpidAcceptor(transport,"TCP"));
- CurrentActor.get().message(BrokerMessages.LISTENING("TCP/SSL", sslPort));
- }
- }
-
- CurrentActor.get().message(BrokerMessages.READY());
- }
- finally
- {
- // Startup is complete so remove the AR initialised Startup actor
- CurrentActor.remove();
- }
- }
-
- private File getConfigFile(final String fileName,
- final String defaultFileName,
- final String qpidHome, boolean throwOnFileNotFound) throws InitException
- {
- File configFile = null;
- if (fileName != null)
- {
- configFile = new File(fileName);
- }
- else
- {
- configFile = new File(qpidHome, defaultFileName);
- }
-
- if (!configFile.exists() && throwOnFileNotFound)
- {
- String error = "File " + fileName + " could not be found. Check the file exists and is readable.";
-
- if (qpidHome == null)
- {
- error = error + "\nNote: " + BrokerOptions.QPID_HOME + " is not set.";
- }
-
- throw new InitException(error, null);
- }
-
- return configFile;
- }
-
- public static void parsePortList(Set<Integer> output, List<?> ports) throws InitException
- {
- if(ports != null)
- {
- for(Object o : ports)
- {
- try
- {
- output.add(Integer.parseInt(String.valueOf(o)));
- }
- catch (NumberFormatException e)
- {
- throw new InitException("Invalid port: " + o, e);
- }
- }
- }
- }
-
- /**
- * Update the configuration data with the management port.
- * @param configuration
- * @param managementPort The string from the command line
- */
- private void updateManagementPort(ServerConfiguration configuration, Integer managementPort)
- {
- if (managementPort != null)
- {
- try
- {
- configuration.setJMXManagementPort(managementPort);
- }
- catch (NumberFormatException e)
- {
- throw new InitException("Invalid management port: " + managementPort, null);
- }
- }
- }
-
- private byte[] parseIP(String address) throws Exception
- {
- char[] literalBuffer = address.toCharArray();
- int byteCount = 0;
- int currByte = 0;
- byte[] ip = new byte[IPV4_ADDRESS_LENGTH];
- for (int i = 0; i < literalBuffer.length; i++)
- {
- char currChar = literalBuffer[i];
- if ((currChar >= '0') && (currChar <= '9'))
- {
- currByte = (currByte * 10) + (Character.digit(currChar, 10) & 0xFF);
- }
-
- if (currChar == IPV4_LITERAL_SEPARATOR || (i + 1 == literalBuffer.length))
- {
- ip[byteCount++] = (byte) currByte;
- currByte = 0;
- }
- }
-
- if (byteCount != 4)
- {
- throw new Exception("Invalid IP address: " + address);
- }
- return ip;
- }
-
- private void configureLogging(File logConfigFile, long logWatchTime) throws InitException, IOException
- {
- if (logConfigFile.exists() && logConfigFile.canRead())
- {
- CurrentActor.get().message(BrokerMessages.LOG_CONFIG(logConfigFile.getAbsolutePath()));
-
- if (logWatchTime > 0)
- {
- System.out.println("log file " + logConfigFile.getAbsolutePath() + " will be checked for changes every "
- + logWatchTime + " seconds");
- // log4j expects the watch interval in milliseconds
- try
- {
- QpidLog4JConfigurator.configureAndWatch(logConfigFile.getPath(), logWatchTime * 1000);
- }
- catch (Exception e)
- {
- throw new InitException(e.getMessage(),e);
- }
- }
- else
- {
- try
- {
- QpidLog4JConfigurator.configure(logConfigFile.getPath());
- }
- catch (Exception e)
- {
- throw new InitException(e.getMessage(),e);
- }
- }
- }
- else
- {
- System.err.println("Logging configuration error: unable to read file " + logConfigFile.getAbsolutePath());
- System.err.println("Using the fallback internal log4j.properties configuration");
-
- InputStream propsFile = this.getClass().getResourceAsStream("/log4j.properties");
- if(propsFile == null)
- {
- throw new IOException("Unable to load the fallback internal log4j.properties configuration file");
- }
- else
- {
- try
- {
- Properties fallbackProps = new Properties();
- fallbackProps.load(propsFile);
- PropertyConfigurator.configure(fallbackProps);
- }
- finally
- {
- propsFile.close();
- }
- }
- }
- }
-
- private void configureLoggingManagementMBean(File logConfigFile, int logWatchTime) throws Exception
- {
- LoggingManagementMBean blm = new LoggingManagementMBean(logConfigFile.getPath(),logWatchTime);
-
- blm.register();
- }
-}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/BrokerOptions.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/BrokerOptions.java
deleted file mode 100644
index b83da92660..0000000000
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/BrokerOptions.java
+++ /dev/null
@@ -1,152 +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;
-
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-
-public class BrokerOptions
-{
- /** serialVersionUID */
- private static final long serialVersionUID = 8051825964945442234L;
-
- public static final String DEFAULT_CONFIG_FILE = "etc/config.xml";
- public static final String DEFAULT_LOG_CONFIG_FILE = "etc/log4j.xml";
- public static final String QPID_HOME = "QPID_HOME";
-
- public static final String PORTS = "p";
- public static final String SSL_PORTS = "s";
- public static final String BIND = "b";
- public static final String MANAGEMENT = "m";
- public static final String LOG_CONFIG = "l";
- public static final String WATCH = "w";
- public static final String CONFIG = "c";
-
- private final Set<Integer> _ports = new HashSet<Integer>();
- private final Set<Integer> _sslPorts = new HashSet<Integer>();
- private final Map<ProtocolExclusion,Set<Integer>> _exclusionMap = new HashMap<ProtocolExclusion, Set<Integer>>();
-
- private String _configFile;
- private String _logConfigFile;
- private String _bind;
- private Integer _jmxPort;
-
- private Integer _logWatchFrequency = 0;
-
- public void addPort(final int port)
- {
- _ports.add(port);
- }
-
- public void addSSLPort(final int sslPort)
- {
- _sslPorts.add(sslPort);
- }
-
- public Set<Integer> getPorts()
- {
- return Collections.unmodifiableSet(_ports);
- }
-
- public Set<Integer> getSSLPorts()
- {
- return Collections.unmodifiableSet(_sslPorts);
- }
-
- public String getConfigFile()
- {
- return _configFile;
- }
-
- public void setConfigFile(final String configFile)
- {
- _configFile = configFile;
- }
-
- public String getLogConfigFile()
- {
- return _logConfigFile;
- }
-
- public void setLogConfigFile(final String logConfigFile)
- {
- _logConfigFile = logConfigFile;
- }
-
- public Integer getJmxPort()
- {
- return _jmxPort;
- }
-
- public void setJmxPort(final int jmxPort)
- {
- _jmxPort = jmxPort;
- }
-
- public String getQpidHome()
- {
- return System.getProperty(QPID_HOME);
- }
-
- public Set<Integer> getExcludedPorts(final ProtocolExclusion excludeProtocol)
- {
- final Set<Integer> excludedPorts = _exclusionMap.get(excludeProtocol);
- return excludedPorts == null ? Collections.<Integer>emptySet() : excludedPorts;
- }
-
- public void addExcludedPort(final ProtocolExclusion excludeProtocol, final int port)
- {
- if (!_exclusionMap.containsKey(excludeProtocol))
- {
- _exclusionMap.put(excludeProtocol, new HashSet<Integer>());
- }
-
- Set<Integer> ports = _exclusionMap.get(excludeProtocol);
- ports.add(port);
- }
-
- public String getBind()
- {
- return _bind;
- }
-
- public void setBind(final String bind)
- {
- _bind = bind;
- }
-
- public int getLogWatchFrequency()
- {
- return _logWatchFrequency;
- }
-
- /**
- * Set the frequency with which the log config file will be checked for updates.
- * @param logWatchFrequency frequency in seconds
- */
- public void setLogWatchFrequency(final int logWatchFrequency)
- {
- _logWatchFrequency = logWatchFrequency;
- }
-} \ No newline at end of file
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 449b52d737..71cf17ed60 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,17 @@
*/
package org.apache.qpid.server;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.util.EnumSet;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Properties;
+import java.util.Set;
+
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.HelpFormatter;
import org.apache.commons.cli.Option;
@@ -28,9 +39,28 @@ import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
import org.apache.commons.cli.PosixParser;
import org.apache.log4j.Logger;
-import org.apache.qpid.server.Broker.InitException;
+import org.apache.log4j.PropertyConfigurator;
+import org.apache.log4j.xml.QpidLog4JConfigurator;
+import org.apache.qpid.common.QpidProperties;
+import org.apache.qpid.framing.ProtocolVersion;
+import org.apache.qpid.server.configuration.ServerConfiguration;
+import org.apache.qpid.server.configuration.management.ConfigurationManagementMBean;
+import org.apache.qpid.server.information.management.ServerInformationMBean;
+import org.apache.qpid.server.logging.SystemOutMessageLogger;
+import org.apache.qpid.server.logging.actors.BrokerActor;
+import org.apache.qpid.server.logging.actors.CurrentActor;
+import org.apache.qpid.server.logging.actors.GenericActor;
+import org.apache.qpid.server.logging.management.LoggingManagementMBean;
+import org.apache.qpid.server.logging.messages.BrokerMessages;
+import org.apache.qpid.server.protocol.AMQProtocolEngineFactory;
+import org.apache.qpid.server.protocol.MultiVersionProtocolEngineFactory;
+import org.apache.qpid.server.protocol.MultiVersionProtocolEngineFactory.VERSION;
import org.apache.qpid.server.registry.ApplicationRegistry;
-
+import org.apache.qpid.server.registry.ConfigurationFileApplicationRegistry;
+import org.apache.qpid.server.transport.QpidAcceptor;
+import org.apache.qpid.ssl.SSLContextFactory;
+import org.apache.qpid.transport.NetworkDriver;
+import org.apache.qpid.transport.network.mina.MINANetworkDriver;
/**
* Main entry point for AMQPD.
@@ -38,41 +68,37 @@ import org.apache.qpid.server.registry.ApplicationRegistry;
*/
public class Main
{
- private final Options options = new Options();
- private CommandLine commandLine;
+ private static Logger _logger;
- public static void main(String[] args)
+ private static final String DEFAULT_CONFIG_FILE = "etc/config.xml";
+
+ public static final String DEFAULT_LOG_CONFIG_FILENAME = "log4j.xml";
+ public static final String QPID_HOME = "QPID_HOME";
+ private static final int IPV4_ADDRESS_LENGTH = 4;
+
+ private static final char IPV4_LITERAL_SEPARATOR = '.';
+
+ protected static class InitException extends Exception
{
- //if the -Dlog4j.configuration property has not been set, enable the init override
- //to stop Log4J wondering off and picking up the first log4j.xml/properties file it
- //finds from the classpath when we get the first Loggers
- if(System.getProperty("log4j.configuration") == null)
+ InitException(String msg, Throwable cause)
{
- System.setProperty("log4j.defaultInitOverride", "true");
+ super(msg, cause);
}
-
- new Main(args);
}
- public Main(final String[] args)
+ protected final Options options = new Options();
+ protected CommandLine commandLine;
+
+ protected Main(String[] args)
{
setOptions(options);
if (parseCommandline(args))
{
- try
- {
- execute();
- }
- catch(Exception e)
- {
- System.err.println("Exception during startup: " + e);
- e.printStackTrace();
- shutdown(1);
- }
+ execute();
}
}
- protected boolean parseCommandline(final String[] args)
+ protected boolean parseCommandline(String[] args)
{
try
{
@@ -90,7 +116,8 @@ public class Main
}
}
- protected void setOptions(final Options options)
+ @SuppressWarnings("static-access")
+ protected void setOptions(Options options)
{
Option help = new Option("h", "help", false, "print this message");
Option version = new Option("v", "version", false, "print the version information and exit");
@@ -134,21 +161,16 @@ public class Main
Option bind =
OptionBuilder.withArgName("bind").hasArg()
.withDescription("bind to the specified address. Overrides any value in the config file")
- .withLongOpt("bind").create(BrokerOptions.BIND);
+ .withLongOpt("bind").create("b");
Option logconfig =
OptionBuilder.withArgName("logconfig").hasArg()
.withDescription("use the specified log4j xml configuration file. By "
- + "default looks for a file named " + BrokerOptions.DEFAULT_LOG_CONFIG_FILE
- + " in the same directory as the configuration file").withLongOpt("logconfig").create(BrokerOptions.LOG_CONFIG);
+ + "default looks for a file named " + DEFAULT_LOG_CONFIG_FILENAME
+ + " in the same directory as the configuration file").withLongOpt("logconfig").create("l");
Option logwatchconfig =
OptionBuilder.withArgName("logwatch").hasArg()
.withDescription("monitor the log file configuration file for changes. Units are seconds. "
- + "Zero means do not check for changes.").withLongOpt("logwatch").create(BrokerOptions.WATCH);
-
- Option sslport =
- OptionBuilder.withArgName("sslport").hasArg()
- .withDescription("SSL port. Overrides any value in the config file")
- .withLongOpt("sslport").create(BrokerOptions.SSL_PORTS);
+ + "Zero means do not check for changes.").withLongOpt("logwatch").create("w");
options.addOption(help);
options.addOption(version);
@@ -162,120 +184,435 @@ public class Main
options.addOption(exclude0_8);
options.addOption(mport);
options.addOption(bind);
- options.addOption(sslport);
}
- protected void execute() throws Exception
+ protected void execute()
{
- BrokerOptions options = new BrokerOptions();
- String configFile = commandLine.getOptionValue(BrokerOptions.CONFIG);
- if(configFile != null)
+ // note this understands either --help or -h. If an option only has a long name you can use that but if
+ // an option has a short name and a long name you must use the short name here.
+ if (commandLine.hasOption("h"))
{
- options.setConfigFile(configFile);
+ HelpFormatter formatter = new HelpFormatter();
+ formatter.printHelp("Qpid", options, true);
}
+ else if (commandLine.hasOption("v"))
+ {
+ String ver = QpidProperties.getVersionString();
+
+ StringBuilder protocol = new StringBuilder("AMQP version(s) [major.minor]: ");
- String logWatchConfig = commandLine.getOptionValue(BrokerOptions.WATCH);
- if(logWatchConfig != null)
+ boolean first = true;
+ for (ProtocolVersion pv : ProtocolVersion.getSupportedProtocolVersions())
+ {
+ if (first)
+ {
+ first = false;
+ }
+ else
+ {
+ protocol.append(", ");
+ }
+
+ protocol.append(pv.getMajorVersion()).append('-').append(pv.getMinorVersion());
+
+ }
+
+ System.out.println(ver + " (" + protocol + ")");
+ }
+ else
{
- options.setLogWatchFrequency(Integer.parseInt(logWatchConfig));
+ try
+ {
+ CurrentActor.set(new BrokerActor(new SystemOutMessageLogger()));
+ startup();
+ CurrentActor.remove();
+ }
+ catch (InitException e)
+ {
+ System.out.println("Initialisation Error : " + e.getMessage());
+ shutdown(1);
+ }
+ catch (Throwable e)
+ {
+ System.out.println("Error initialising message broker: " + e);
+ e.printStackTrace();
+ shutdown(1);
+ }
}
+ }
- String logConfig = commandLine.getOptionValue(BrokerOptions.LOG_CONFIG);
- if(logConfig != null)
+ protected void shutdown(int status)
+ {
+ ApplicationRegistry.removeAll();
+ System.exit(status);
+ }
+
+ protected void startup() throws Exception
+ {
+ final String QpidHome = System.getProperty(QPID_HOME);
+ final File defaultConfigFile = new File(QpidHome, DEFAULT_CONFIG_FILE);
+ final File configFile = new File(commandLine.getOptionValue("c", defaultConfigFile.getPath()));
+ if (!configFile.exists())
{
- options.setLogConfigFile(logConfig);
+ String error = "File " + configFile + " could not be found. Check the file exists and is readable.";
+
+ if (QpidHome == null)
+ {
+ error = error + "\nNote: " + QPID_HOME + " is not set.";
+ }
+
+ throw new InitException(error, null);
}
+ else
+ {
+ CurrentActor.get().message(BrokerMessages.CONFIG(configFile.getAbsolutePath()));
+ }
+
+ String logConfig = commandLine.getOptionValue("l");
+ String logWatchConfig = commandLine.getOptionValue("w", "0");
- String jmxPort = commandLine.getOptionValue(BrokerOptions.MANAGEMENT);
- if(jmxPort != null)
+ int logWatchTime = 0;
+ try
{
- options.setJmxPort(Integer.parseInt(jmxPort));
+ 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");
}
- String bindAddr = commandLine.getOptionValue(BrokerOptions.BIND);
- if (bindAddr != null)
+ File logConfigFile;
+ if (logConfig != null)
+ {
+ logConfigFile = new File(logConfig);
+ configureLogging(logConfigFile, logWatchTime);
+ }
+ else
{
- options.setBind(bindAddr);
+ File configFileDirectory = configFile.getParentFile();
+ logConfigFile = new File(configFileDirectory, DEFAULT_LOG_CONFIG_FILENAME);
+ configureLogging(logConfigFile, logWatchTime);
}
- String[] portStr = commandLine.getOptionValues(BrokerOptions.PORTS);
+ ConfigurationFileApplicationRegistry config = new ConfigurationFileApplicationRegistry(configFile);
+ ServerConfiguration serverConfig = config.getConfiguration();
+ updateManagementPort(serverConfig, commandLine.getOptionValue("m"));
+
+ ApplicationRegistry.initialise(config);
+
+ // We have already loaded the BrokerMessages class by this point so we
+ // need to refresh the locale setting incase we had a different value in
+ // the configuration.
+ BrokerMessages.reload();
+
+ // AR.initialise() sets and removes its own actor so we now need to set the actor
+ // for the remainder of the startup, and the default actor if the stack is empty
+ CurrentActor.set(new BrokerActor(config.getCompositeStartupMessageLogger()));
+ CurrentActor.setDefault(new BrokerActor(config.getRootMessageLogger()));
+ GenericActor.setDefaultMessageLogger(config.getRootMessageLogger());
+
+
+ try
+ {
+ configureLoggingManagementMBean(logConfigFile, logWatchTime);
+
+ ConfigurationManagementMBean configMBean = new ConfigurationManagementMBean();
+ configMBean.register();
+
+ ServerInformationMBean sysInfoMBean =
+ new ServerInformationMBean(QpidProperties.getBuildVersion(), QpidProperties.getReleaseVersion());
+ sysInfoMBean.register();
+
+
+ String[] portStr = commandLine.getOptionValues("p");
+
+ Set<Integer> ports = new HashSet<Integer>();
+ Set<Integer> exclude_0_10 = new HashSet<Integer>();
+ Set<Integer> exclude_0_9_1 = new HashSet<Integer>();
+ Set<Integer> exclude_0_9 = new HashSet<Integer>();
+ Set<Integer> exclude_0_8 = new HashSet<Integer>();
+
+ if(portStr == null || portStr.length == 0)
+ {
+
+ parsePortList(ports, serverConfig.getPorts());
+ parsePortList(exclude_0_10, serverConfig.getPortExclude010());
+ parsePortList(exclude_0_9_1, serverConfig.getPortExclude091());
+ parsePortList(exclude_0_9, serverConfig.getPortExclude09());
+ parsePortList(exclude_0_8, serverConfig.getPortExclude08());
+
+ }
+ else
+ {
+ parsePortArray(ports, portStr);
+ parsePortArray(exclude_0_10, commandLine.getOptionValues("exclude-0-10"));
+ parsePortArray(exclude_0_9_1, commandLine.getOptionValues("exclude-0-9-1"));
+ parsePortArray(exclude_0_9, commandLine.getOptionValues("exclude-0-9"));
+ parsePortArray(exclude_0_8, commandLine.getOptionValues("exclude-0-8"));
+
+ }
+
+
+
+
+ String bindAddr = commandLine.getOptionValue("b");
+ if (bindAddr == null)
+ {
+ bindAddr = serverConfig.getBind();
+ }
+ InetAddress bindAddress = null;
+
+
+
+ if (bindAddr.equals("wildcard"))
+ {
+ bindAddress = new InetSocketAddress(0).getAddress();
+ }
+ else
+ {
+ bindAddress = InetAddress.getByAddress(parseIP(bindAddr));
+ }
+
+ String hostName = bindAddress.getCanonicalHostName();
+
+
+ String keystorePath = serverConfig.getKeystorePath();
+ String keystorePassword = serverConfig.getKeystorePassword();
+ String certType = serverConfig.getCertType();
+ SSLContextFactory sslFactory = null;
+
+ if (!serverConfig.getSSLOnly())
+ {
+
+ for(int port : ports)
+ {
+
+ NetworkDriver driver = new MINANetworkDriver();
+
+ Set<VERSION> supported = EnumSet.allOf(VERSION.class);
+
+ if(exclude_0_10.contains(port))
+ {
+ supported.remove(VERSION.v0_10);
+ }
+
+ if(exclude_0_9_1.contains(port))
+ {
+ supported.remove(VERSION.v0_9_1);
+ }
+ if(exclude_0_9.contains(port))
+ {
+ supported.remove(VERSION.v0_9);
+ }
+ if(exclude_0_8.contains(port))
+ {
+ supported.remove(VERSION.v0_8);
+ }
+
+ MultiVersionProtocolEngineFactory protocolEngineFactory =
+ new MultiVersionProtocolEngineFactory(hostName, supported);
+
+
+
+ driver.bind(port, new InetAddress[]{bindAddress}, protocolEngineFactory,
+ serverConfig.getNetworkConfiguration(), null);
+ ApplicationRegistry.getInstance().addAcceptor(new InetSocketAddress(bindAddress, port),
+ new QpidAcceptor(driver,"TCP"));
+ CurrentActor.get().message(BrokerMessages.LISTENING("TCP", port));
+
+ }
+
+ }
+
+ if (serverConfig.getEnableSSL())
+ {
+ sslFactory = new SSLContextFactory(keystorePath, keystorePassword, certType);
+ NetworkDriver driver = new MINANetworkDriver();
+ driver.bind(serverConfig.getSSLPort(), new InetAddress[]{bindAddress},
+ new AMQProtocolEngineFactory(), serverConfig.getNetworkConfiguration(), sslFactory);
+ ApplicationRegistry.getInstance().addAcceptor(new InetSocketAddress(bindAddress, serverConfig.getSSLPort()),
+ new QpidAcceptor(driver,"TCP"));
+ CurrentActor.get().message(BrokerMessages.LISTENING("TCP/SSL", serverConfig.getSSLPort()));
+ }
+
+ CurrentActor.get().message(BrokerMessages.READY());
+
+ }
+ finally
+ {
+ // Startup is complete so remove the AR initialised Startup actor
+ CurrentActor.remove();
+ }
+
+
+
+ }
+
+ private void parsePortArray(Set<Integer> ports, String[] portStr)
+ throws InitException
+ {
if(portStr != null)
{
- parsePortArray(options, portStr, false);
- for(ProtocolExclusion pe : ProtocolExclusion.values())
+ for(int i = 0; i < portStr.length; i++)
{
- parsePortArray(options, commandLine.getOptionValues(pe.getExcludeName()), pe);
+ try
+ {
+ ports.add(Integer.parseInt(portStr[i]));
+ }
+ catch (NumberFormatException e)
+ {
+ throw new InitException("Invalid port: " + portStr[i], e);
+ }
}
}
+ }
- String[] sslPortStr = commandLine.getOptionValues(BrokerOptions.SSL_PORTS);
- if(sslPortStr != null)
+ private void parsePortList(Set<Integer> output, List input)
+ throws InitException
+ {
+ if(input != null)
{
- parsePortArray(options, sslPortStr, true);
- for(ProtocolExclusion pe : ProtocolExclusion.values())
+ for(Object port : input)
{
- parsePortArray(options, commandLine.getOptionValues(pe.getExcludeName()), pe);
+ try
+ {
+ output.add(Integer.parseInt(String.valueOf(port)));
+ }
+ catch (NumberFormatException e)
+ {
+ throw new InitException("Invalid port: " + port, e);
+ }
+ }
+ }
+ }
+
+ /**
+ * Update the configuration data with the management port.
+ * @param configuration
+ * @param managementPort The string from the command line
+ */
+ private void updateManagementPort(ServerConfiguration configuration, String managementPort)
+ {
+ if (managementPort != null)
+ {
+ try
+ {
+ configuration.setJMXManagementPort(Integer.parseInt(managementPort));
+ }
+ catch (NumberFormatException e)
+ {
+ _logger.warn("Invalid management port: " + managementPort + " will use:" + configuration.getJMXManagementPort(), e);
}
}
-
- startBroker(options);
}
- protected void startBroker(final BrokerOptions options) throws Exception
+ public static void main(String[] args)
{
- Broker broker = new Broker();
- broker.startup(options);
+ //if the -Dlog4j.configuration property has not been set, enable the init override
+ //to stop Log4J wondering off and picking up the first log4j.xml/properties file it
+ //finds from the classpath when we get the first Loggers
+ if(System.getProperty("log4j.configuration") == null)
+ {
+ System.setProperty("log4j.defaultInitOverride", "true");
+ }
+
+ //now that the override status is know, we can instantiate the Loggers
+ _logger = Logger.getLogger(Main.class);
+
+ new Main(args);
}
- protected void shutdown(final int status)
+ private byte[] parseIP(String address) throws Exception
{
- ApplicationRegistry.remove();
- System.exit(status);
+ char[] literalBuffer = address.toCharArray();
+ int byteCount = 0;
+ int currByte = 0;
+ byte[] ip = new byte[IPV4_ADDRESS_LENGTH];
+ for (int i = 0; i < literalBuffer.length; i++)
+ {
+ char currChar = literalBuffer[i];
+ if ((currChar >= '0') && (currChar <= '9'))
+ {
+ currByte = (currByte * 10) + (Character.digit(currChar, 10) & 0xFF);
+ }
+
+ if (currChar == IPV4_LITERAL_SEPARATOR || (i + 1 == literalBuffer.length))
+ {
+ ip[byteCount++] = (byte) currByte;
+ currByte = 0;
+ }
+ }
+
+ if (byteCount != 4)
+ {
+ throw new Exception("Invalid IP address: " + address);
+ }
+ return ip;
}
- private static void parsePortArray(final BrokerOptions options,final Object[] ports,
- final boolean ssl) throws InitException
+ private void configureLogging(File logConfigFile, int logWatchTime) throws InitException, IOException
{
- if(ports != null)
+ if (logConfigFile.exists() && logConfigFile.canRead())
{
- for(int i = 0; i < ports.length; i++)
+ CurrentActor.get().message(BrokerMessages.LOG_CONFIG(logConfigFile.getAbsolutePath()));
+
+ if (logWatchTime > 0)
{
+ System.out.println("log file " + logConfigFile.getAbsolutePath() + " will be checked for changes every "
+ + logWatchTime + " seconds");
+ // log4j expects the watch interval in milliseconds
try
{
- if(ssl)
- {
- options.addSSLPort(Integer.parseInt(String.valueOf(ports[i])));
- }
- else
- {
- options.addPort(Integer.parseInt(String.valueOf(ports[i])));
- }
+ QpidLog4JConfigurator.configureAndWatch(logConfigFile.getPath(), logWatchTime * 1000);
}
- catch (NumberFormatException e)
+ catch (Exception e)
+ {
+ throw new InitException(e.getMessage(),e);
+ }
+ }
+ else
+ {
+ try
{
- throw new InitException("Invalid port: " + ports[i], e);
+ QpidLog4JConfigurator.configure(logConfigFile.getPath());
+ }
+ catch (Exception e)
+ {
+ throw new InitException(e.getMessage(),e);
}
}
}
- }
-
- private static void parsePortArray(final BrokerOptions options, final Object[] ports,
- final ProtocolExclusion excludedProtocol) throws InitException
- {
- if(ports != null)
+ else
{
- for(int i = 0; i < ports.length; i++)
+ System.err.println("Logging configuration error: unable to read file " + logConfigFile.getAbsolutePath());
+ System.err.println("Using the fallback internal log4j.properties configuration");
+
+ InputStream propsFile = this.getClass().getResourceAsStream("/log4j.properties");
+ if(propsFile == null)
+ {
+ throw new IOException("Unable to load the fallback internal log4j.properties configuration file");
+ }
+ else
{
try
{
- options.addExcludedPort(excludedProtocol,
- Integer.parseInt(String.valueOf(ports[i])));
+ Properties fallbackProps = new Properties();
+ fallbackProps.load(propsFile);
+ PropertyConfigurator.configure(fallbackProps);
}
- catch (NumberFormatException e)
+ finally
{
- throw new InitException("Invalid port for exclusion: " + ports[i], e);
+ propsFile.close();
}
}
}
}
+
+ private void configureLoggingManagementMBean(File logConfigFile, int logWatchTime) throws Exception
+ {
+ LoggingManagementMBean blm = new LoggingManagementMBean(logConfigFile.getPath(),logWatchTime);
+
+ blm.register();
+ }
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/ProtocolExclusion.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/ProtocolExclusion.java
deleted file mode 100644
index 22d97d36dd..0000000000
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/ProtocolExclusion.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
- */
-package org.apache.qpid.server;
-
-import java.util.HashMap;
-import java.util.Map;
-
-public enum ProtocolExclusion
-{
- v0_8("exclude-0-8","--exclude-0-8"),
- v0_9("exclude-0-9", "--exclude-0-9"),
- v0_9_1("exclude-0-9-1", "--exclude-0-9-1"),
- v0_10("exclude-0-10", "--exclude-0-10");
-
- private static final Map<String, ProtocolExclusion> MAP = new HashMap<String,ProtocolExclusion>();
-
- static
- {
- for(ProtocolExclusion pe : ProtocolExclusion.values())
- {
- MAP.put(pe.getArg(), pe);
- }
- }
-
- private String _arg;
- private String _excludeName;
-
- private ProtocolExclusion(final String excludeName, final String arg)
- {
- _excludeName = excludeName;
- _arg = arg;
- }
-
- public String getArg()
- {
- return _arg;
- }
-
- public String getExcludeName()
- {
- return _excludeName;
- }
-
- public static ProtocolExclusion lookup(final String arg)
- {
- ProtocolExclusion ex = MAP.get(arg);
-
- if(ex == null)
- {
- throw new IllegalArgumentException(arg + " is not a valid protocol exclusion");
- }
-
- return ex;
- }
-}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/ServerConfiguration.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/ServerConfiguration.java
index 0621b87f0a..7197ec8cdc 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/ServerConfiguration.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/ServerConfiguration.java
@@ -20,8 +20,6 @@
package org.apache.qpid.server.configuration;
-import static org.apache.qpid.transport.ConnectionSettings.WILDCARD_ADDRESS;
-
import java.io.File;
import java.util.Collections;
import java.util.HashMap;
@@ -44,7 +42,7 @@ import org.apache.qpid.server.configuration.plugins.ConfigurationPlugin;
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.transport.NetworkTransportConfiguration;
+import org.apache.qpid.transport.NetworkDriverConfiguration;
import sun.misc.Signal;
import sun.misc.SignalHandler;
@@ -54,7 +52,9 @@ public class ServerConfiguration extends ConfigurationPlugin implements SignalHa
protected static final Logger _logger = Logger.getLogger(ServerConfiguration.class);
// Default Configuration values
- public static final int DEFAULT_BUFFER_SIZE = 262144;
+ public static final int DEFAULT_BUFFER_READ_LIMIT_SIZE = 262144;
+ public static final int DEFAULT_BUFFER_WRITE_LIMIT_SIZE = 262144;
+ public static final boolean DEFAULT_BROKER_CONNECTOR_PROTECTIO_ENABLED = false;
public static final String DEFAULT_STATUS_UPDATES = "on";
public static final String SECURITY_CONFIG_RELOADED = "SECURITY CONFIGURATION RELOADED";
@@ -63,7 +63,7 @@ public class ServerConfiguration extends ConfigurationPlugin implements SignalHa
public static final int DEFAULT_SSL_PORT = 8672;
public static final long DEFAULT_HOUSEKEEPING_PERIOD = 30000L;
public static final int DEFAULT_JMXPORT = 8999;
-
+
public static final String QPID_HOME = "QPID_HOME";
public static final String QPID_WORK = "QPID_WORK";
public static final String LIB_DIR = "lib";
@@ -84,6 +84,9 @@ public class ServerConfiguration extends ConfigurationPlugin implements SignalHa
// Configuration values to be read from the configuration file
//todo Move all properties to static values to ensure system testing can be performed.
+ public static final String CONNECTOR_PROTECTIO_ENABLED = "connector.protectio.enabled";
+ public static final String CONNECTOR_PROTECTIO_READ_BUFFER_LIMIT_SIZE = "connector.protectio.readBufferLimitSize";
+ public static final String CONNECTOR_PROTECTIO_WRITE_BUFFER_LIMIT_SIZE = "connector.protectio.writeBufferLimitSize";
public static final String MGMT_CUSTOM_REGISTRY_SOCKET = "management.custom-registry-socket";
public static final String STATUS_UPDATES = "status-updates";
public static final String ADVANCED_LOCALE = "advanced.locale";
@@ -92,6 +95,7 @@ public class ServerConfiguration extends ConfigurationPlugin implements SignalHa
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");
@@ -144,7 +148,7 @@ public class ServerConfiguration extends ConfigurationPlugin implements SignalHa
}
catch (Exception e)
{
- _logger.info("Signal HUP not supported for OS: " + System.getProperty("os.name"));
+ _logger.error("Signal HUP not supported for OS: " + System.getProperty("os.name"));
// We're on something that doesn't handle SIGHUP, how sad, Windows.
}
}
@@ -201,29 +205,7 @@ public class ServerConfiguration extends ConfigurationPlugin implements SignalHa
@Override
public void validateConfiguration() throws ConfigurationException
{
- // Support for security.jmx.access was removed when JMX access rights were incorporated into the main ACL.
- // This ensure that users remove the element from their configuration file.
-
- if (getListValue("security.jmx.access").size() > 0)
- {
- String message = "Validation error : security/jmx/access is no longer a supported element within the configuration xml."
- + (_configFile == null ? "" : " Configuration file : " + _configFile);
- throw new ConfigurationException(message);
- }
-
- if (getListValue("security.jmx.principal-database").size() > 0)
- {
- String message = "Validation error : security/jmx/principal-database is no longer a supported element within the configuration xml."
- + (_configFile == null ? "" : " Configuration file : " + _configFile);
- throw new ConfigurationException(message);
- }
-
- if (getListValue("security.principal-databases.principal-database(0).class").size() > 0)
- {
- String message = "Validation error : security/principal-databases is no longer supported within the configuration xml."
- + (_configFile == null ? "" : " Configuration file : " + _configFile);
- throw new ConfigurationException(message);
- }
+ //Currently doesn't do validation
}
/*
@@ -521,11 +503,58 @@ public class ServerConfiguration extends ConfigurationPlugin implements SignalHa
_virtualHosts.put(config.getName(), config);
}
+ public List<String> getPrincipalDatabaseNames()
+ {
+ return getListValue("security.principal-databases.principal-database.name");
+ }
+
+ public List<String> getPrincipalDatabaseClass()
+ {
+ return getListValue("security.principal-databases.principal-database.class");
+ }
+
+ public List<String> getPrincipalDatabaseAttributeNames(int index)
+ {
+ String name = "security.principal-databases.principal-database(" + index + ")." + "attributes.attribute.name";
+ return getListValue(name);
+ }
+
+ public List<String> getPrincipalDatabaseAttributeValues(int index)
+ {
+ String name = "security.principal-databases.principal-database(" + index + ")." + "attributes.attribute.value";
+ return getListValue(name);
+ }
+
+ public List<String> getManagementPrincipalDBs()
+ {
+ return getListValue("security.jmx.principal-database");
+ }
+
+ public List<String> getManagementAccessList()
+ {
+ return getListValue("security.jmx.access");
+ }
+
public int getFrameSize()
{
return getIntValue("advanced.framesize", DEFAULT_FRAME_SIZE);
}
+ public boolean getProtectIOEnabled()
+ {
+ return getBooleanValue(CONNECTOR_PROTECTIO_ENABLED, DEFAULT_BROKER_CONNECTOR_PROTECTIO_ENABLED);
+ }
+
+ public int getBufferReadLimit()
+ {
+ return getIntValue(CONNECTOR_PROTECTIO_READ_BUFFER_LIMIT_SIZE, DEFAULT_BUFFER_READ_LIMIT_SIZE);
+ }
+
+ public int getBufferWriteLimit()
+ {
+ return getIntValue(CONNECTOR_PROTECTIO_WRITE_BUFFER_LIMIT_SIZE, DEFAULT_BUFFER_WRITE_LIMIT_SIZE);
+ }
+
public boolean getSynchedClocks()
{
return getBooleanValue("advanced.synced-clocks");
@@ -536,6 +565,11 @@ public class ServerConfiguration extends ConfigurationPlugin implements SignalHa
return getBooleanValue("security.msg-auth");
}
+ public String getJMXPrincipalDatabase()
+ {
+ return getStringValue("security.jmx.principal-database");
+ }
+
public String getManagementKeyStorePath()
{
return getStringValue("management.ssl.keyStorePath");
@@ -616,14 +650,14 @@ public class ServerConfiguration extends ConfigurationPlugin implements SignalHa
return getLongValue("flowResumeCapacity", getCapacity());
}
- public int getConnectorProcessors()
+ public int getProcessors()
{
return getIntValue("connector.processors", 4);
}
public List getPorts()
{
- return getListValue("connector.port", Collections.<Integer>singletonList(DEFAULT_PORT));
+ return getListValue("connector.port", Collections.singletonList(DEFAULT_PORT));
}
public List getPortExclude010()
@@ -648,17 +682,17 @@ public class ServerConfiguration extends ConfigurationPlugin implements SignalHa
public String getBind()
{
- return getStringValue("connector.bind", WILDCARD_ADDRESS);
+ return getStringValue("connector.bind", "wildcard");
}
public int getReceiveBufferSize()
{
- return getIntValue("connector.socketReceiveBuffer", DEFAULT_BUFFER_SIZE);
+ return getIntValue("connector.socketReceiveBuffer", 32767);
}
public int getWriteBufferSize()
{
- return getIntValue("connector.socketWriteBuffer", DEFAULT_BUFFER_SIZE);
+ return getIntValue("connector.socketWriteBuffer", 32767);
}
public boolean getTcpNoDelay()
@@ -681,9 +715,9 @@ public class ServerConfiguration extends ConfigurationPlugin implements SignalHa
return getBooleanValue("connector.ssl.sslOnly");
}
- public List getSSLPorts()
+ public int getSSLPort()
{
- return getListValue("connector.ssl.port", Collections.<Integer>singletonList(DEFAULT_SSL_PORT));
+ return getIntValue("connector.ssl.port", DEFAULT_SSL_PORT);
}
public String getKeystorePath()
@@ -701,6 +735,11 @@ public class ServerConfiguration extends ConfigurationPlugin implements SignalHa
return getStringValue("connector.ssl.certType", "SunX509");
}
+ public boolean getQpidNIO()
+ {
+ return getBooleanValue("connector.qpidnio");
+ }
+
public boolean getUseBiasedWrites()
{
return getBooleanValue("advanced.useWriteBiasedPool");
@@ -728,34 +767,57 @@ public class ServerConfiguration extends ConfigurationPlugin implements SignalHa
DEFAULT_HOUSEKEEPING_PERIOD));
}
- public long getStatisticsSamplePeriod()
+ public NetworkDriverConfiguration getNetworkConfiguration()
{
- return getConfig().getLong("statistics.sample.period", 5000L);
- }
+ return new NetworkDriverConfiguration()
+ {
- public boolean isStatisticsGenerationBrokerEnabled()
- {
- return getConfig().getBoolean("statistics.generation.broker", false);
- }
+ public Integer getTrafficClass()
+ {
+ return null;
+ }
- public boolean isStatisticsGenerationVirtualhostsEnabled()
- {
- return getConfig().getBoolean("statistics.generation.virtualhosts", false);
- }
+ public Boolean getTcpNoDelay()
+ {
+ // Can't call parent getTcpNoDelay since it just calls this one
+ return getBooleanValue("connector.tcpNoDelay", true);
+ }
- public boolean isStatisticsGenerationConnectionsEnabled()
- {
- return getConfig().getBoolean("statistics.generation.connections", false);
- }
+ public Integer getSoTimeout()
+ {
+ return null;
+ }
- public long getStatisticsReportingPeriod()
- {
- return getConfig().getLong("statistics.reporting.period", 0L);
- }
+ public Integer getSoLinger()
+ {
+ return null;
+ }
- public boolean isStatisticsReportResetEnabled()
- {
- return getConfig().getBoolean("statistics.reporting.reset", false);
+ public Integer getSendBufferSize()
+ {
+ return getBufferWriteLimit();
+ }
+
+ public Boolean getReuseAddress()
+ {
+ return null;
+ }
+
+ public Integer getReceiveBufferSize()
+ {
+ return getBufferReadLimit();
+ }
+
+ public Boolean getOOBInline()
+ {
+ return null;
+ }
+
+ public Boolean getKeepAlive()
+ {
+ return null;
+ }
+ };
}
public int getMaxChannelCount()
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/ServerNetworkTransportConfiguration.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/ServerNetworkTransportConfiguration.java
deleted file mode 100644
index 81dfcb4465..0000000000
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/ServerNetworkTransportConfiguration.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.configuration;
-
-import org.apache.qpid.transport.NetworkTransportConfiguration;
-
-public class ServerNetworkTransportConfiguration implements NetworkTransportConfiguration
-{
- private final ServerConfiguration _serverConfig;
- private final int _port;
- private final String _host;
- private final String _transport;
-
- public ServerNetworkTransportConfiguration(final ServerConfiguration serverConfig,
- final int port, final String host,
- final String transport)
- {
- _serverConfig = serverConfig;
- _port = port;
- _host = host;
- _transport = transport;
- }
-
- public Boolean getTcpNoDelay()
- {
- return _serverConfig.getTcpNoDelay();
- }
-
- public Integer getSendBufferSize()
- {
- return _serverConfig.getWriteBufferSize();
- }
-
- public Integer getReceiveBufferSize()
- {
- return _serverConfig.getReceiveBufferSize();
- }
-
- public Integer getPort()
- {
- return _port;
- }
-
- public String getHost()
- {
- return _host;
- }
-
- public String getTransport()
- {
- return _transport;
- }
-
- public Integer getConnectorProcessors()
- {
- return _serverConfig.getConnectorProcessors();
- }
-}
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 a710230616..d9d7083543 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
@@ -306,37 +306,11 @@ public class VirtualHostConfiguration extends ConfigurationPlugin
@Override
public void validateConfiguration() throws ConfigurationException
{
- // QPID-3249. Support for specifying authentication name at vhost level is no longer supported.
- if (getListValue("security.authentication.name").size() > 0)
- {
- String message = "Validation error : security/authentication/name is no longer a supported element within the configuration xml."
- + " It appears in virtual host definition : " + _name;
- throw new ConfigurationException(message);
- }
+ //Currently doesn't do validation
}
public int getHouseKeepingThreadCount()
{
return getIntValue("housekeeping.poolSize", Runtime.getRuntime().availableProcessors());
}
-
- public long getTransactionTimeoutOpenWarn()
- {
- return getLongValue("transactionTimeout.openWarn", 0L);
- }
-
- public long getTransactionTimeoutOpenClose()
- {
- return getLongValue("transactionTimeout.openClose", 0L);
- }
-
- public long getTransactionTimeoutIdleWarn()
- {
- return getLongValue("transactionTimeout.idleWarn", 0L);
- }
-
- public long getTransactionTimeoutIdleClose()
- {
- return getLongValue("transactionTimeout.idleClose", 0L);
- }
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/plugins/ConfigurationPlugin.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/plugins/ConfigurationPlugin.java
index b4f82649b0..82b576ea51 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/plugins/ConfigurationPlugin.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/plugins/ConfigurationPlugin.java
@@ -24,7 +24,6 @@ import org.apache.commons.configuration.ConversionException;
import org.apache.log4j.Logger;
import org.apache.qpid.server.configuration.ConfigurationManager;
import org.apache.qpid.server.registry.ApplicationRegistry;
-import org.apache.qpid.server.registry.IApplicationRegistry;
import java.util.Collections;
import java.util.HashMap;
@@ -139,28 +138,10 @@ public abstract class ConfigurationPlugin
}
}
- offerRemainingConfigurationToOtherPlugins(path, configuration, elements);
-
- validateConfiguration();
- }
-
- private void offerRemainingConfigurationToOtherPlugins(String path,
- Configuration configuration, Set<String> elements) throws ConfigurationException
- {
- final IApplicationRegistry appRegistry = safeGetApplicationRegistryInstance();
-
- if (appRegistry == null)
- {
- // We see this happen during shutdown due to asynchronous reconfig using IO threads.
- // Need to remove the responsibility for offering configuration to other class.
- _logger.info("Cannot offer remaining config to other plugins, can't find app registry");
- return;
- }
-
- final ConfigurationManager configurationManager = appRegistry.getConfigurationManager();
// Process the elements in the configuration
for (String element : elements)
{
+ ConfigurationManager configurationManager = ApplicationRegistry.getInstance().getConfigurationManager();
Configuration handled = element.length() == 0 ? configuration : configuration.subset(element);
String configurationElement = element;
@@ -181,18 +162,8 @@ public abstract class ConfigurationPlugin
_pluginConfiguration.put(plugin.getClass().getName(), plugin);
}
}
- }
- private IApplicationRegistry safeGetApplicationRegistryInstance()
- {
- try
- {
- return ApplicationRegistry.getInstance();
- }
- catch (IllegalStateException ise)
- {
- return null;
- }
+ validateConfiguration();
}
/** Helper method to print out list of keys in a {@link Configuration}. */
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/connection/ConnectionRegistry.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/connection/ConnectionRegistry.java
index 3786c2020c..bac751e0c8 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/connection/ConnectionRegistry.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/connection/ConnectionRegistry.java
@@ -20,19 +20,19 @@
*/
package org.apache.qpid.server.connection;
-import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import org.apache.log4j.Logger;
+import org.apache.qpid.AMQConnectionException;
import org.apache.qpid.AMQException;
import org.apache.qpid.common.Closeable;
import org.apache.qpid.protocol.AMQConstant;
-import org.apache.qpid.server.protocol.AMQConnectionModel;
+import org.apache.qpid.server.protocol.AMQProtocolSession;
public class ConnectionRegistry implements IConnectionRegistry, Closeable
{
- private List<AMQConnectionModel> _registry = new CopyOnWriteArrayList<AMQConnectionModel>();
+ private List<AMQProtocolSession> _registry = new CopyOnWriteArrayList<AMQProtocolSession>();
private Logger _logger = Logger.getLogger(ConnectionRegistry.class);
@@ -40,41 +40,44 @@ public class ConnectionRegistry implements IConnectionRegistry, Closeable
{
// None required
}
-
- /** Close all of the currently open connections. */
- public void close()
+
+ public void expireClosedChannels()
{
- while (!_registry.isEmpty())
+ for (AMQProtocolSession connection : _registry)
{
- AMQConnectionModel connection = _registry.get(0);
- closeConnection(connection, AMQConstant.INTERNAL_ERROR, "Broker is shutting down");
+ connection.closeIfLingeringClosedChannels();
}
}
-
- public void closeConnection(AMQConnectionModel connection, AMQConstant cause, String message)
+
+ /** Close all of the currently open connections. */
+ public void close()
{
- try
- {
- connection.close(cause, message);
- }
- catch (AMQException e)
+ while (!_registry.isEmpty())
{
- _logger.warn("Error closing connection:" + e.getMessage());
+ AMQProtocolSession connection = _registry.get(0);
+
+ try
+ {
+ connection.closeConnection(0, new AMQConnectionException(AMQConstant.INTERNAL_ERROR, "Broker is shutting down",
+ 0, 0,
+ connection.getProtocolOutputConverter().getProtocolMajorVersion(),
+ connection.getProtocolOutputConverter().getProtocolMinorVersion(),
+ (Throwable) null), true);
+ }
+ catch (AMQException e)
+ {
+ _logger.warn("Error closing connection:" + e.getMessage());
+ }
}
}
- public void registerConnection(AMQConnectionModel connnection)
+ public void registerConnection(AMQProtocolSession connnection)
{
_registry.add(connnection);
}
- public void deregisterConnection(AMQConnectionModel connnection)
+ public void deregisterConnection(AMQProtocolSession connnection)
{
_registry.remove(connnection);
}
-
- public List<AMQConnectionModel> getConnections()
- {
- return new ArrayList<AMQConnectionModel>(_registry);
- }
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/connection/IConnectionRegistry.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/connection/IConnectionRegistry.java
index b4f5bffa57..002269bbaa 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/connection/IConnectionRegistry.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/connection/IConnectionRegistry.java
@@ -20,23 +20,18 @@
*/
package org.apache.qpid.server.connection;
-import java.util.List;
-
+import org.apache.qpid.server.protocol.AMQProtocolSession;
import org.apache.qpid.AMQException;
-import org.apache.qpid.protocol.AMQConstant;
-import org.apache.qpid.server.protocol.AMQConnectionModel;
public interface IConnectionRegistry
{
+
public void initialise();
public void close() throws AMQException;
-
- public void closeConnection(AMQConnectionModel connection, AMQConstant cause, String message);
-
- public List<AMQConnectionModel> getConnections();
- public void registerConnection(AMQConnectionModel connnection);
+ public void registerConnection(AMQProtocolSession connnection);
+
+ public void deregisterConnection(AMQProtocolSession connnection);
- public void deregisterConnection(AMQConnectionModel connnection);
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/AbstractExchangeMBean.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/AbstractExchangeMBean.java
index 0f1b709475..7aeff2561e 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/AbstractExchangeMBean.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/AbstractExchangeMBean.java
@@ -90,12 +90,12 @@ public abstract class AbstractExchangeMBean<T extends AbstractExchange> extends
public String getObjectInstanceName()
{
- return ObjectName.quote(_exchange.getName());
+ return _exchange.getNameShortString().toString();
}
public String getName()
{
- return _exchange.getName();
+ return _exchange.getNameShortString().toString();
}
public String getExchangeType()
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/federation/BrokerLink.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/federation/BrokerLink.java
index f21158cd0c..fa2fb9ead1 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/federation/BrokerLink.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/federation/BrokerLink.java
@@ -258,6 +258,7 @@ public class BrokerLink implements LinkConfig, ConnectionListener
_remoteFederationTag = UUID.fromString(_transport+":"+_host+":"+_port).toString();
}
_qpidConnection.setSessionFactory(new SessionFactory());
+ _qpidConnection.setAuthorizationID(_username == null ? "" : _username);
updateState(State.ESTABLISHING, State.OPERATIONAL);
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/filter/PropertyExpression.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/filter/PropertyExpression.java
index 9848f90ea9..11fdeae2b1 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/filter/PropertyExpression.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/filter/PropertyExpression.java
@@ -37,8 +37,8 @@ import org.apache.qpid.server.queue.Filterable;
public class PropertyExpression implements Expression
{
// Constants - defined the same as JMS
- private static enum JMSDeliveryMode { NON_PERSISTENT, PERSISTENT }
-
+ private static final int NON_PERSISTENT = 1;
+ private static final int PERSISTENT = 2;
private static final int DEFAULT_PRIORITY = 4;
private static final Logger _logger = org.apache.log4j.Logger.getLogger(PropertyExpression.class);
@@ -172,14 +172,13 @@ public class PropertyExpression implements Expression
{
public Object evaluate(Filterable message)
{
- JMSDeliveryMode mode = message.isPersistent() ? JMSDeliveryMode.PERSISTENT :
- JMSDeliveryMode.NON_PERSISTENT;
+ int mode = message.isPersistent() ? PERSISTENT : NON_PERSISTENT;
if (_logger.isDebugEnabled())
{
_logger.debug("JMSDeliveryMode is :" + mode);
}
- return mode.toString();
+ return mode;
}
}
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 09f35da41d..d4b79134a2 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionSecureOkMethodHandler.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionSecureOkMethodHandler.java
@@ -20,9 +20,9 @@
*/
package org.apache.qpid.server.handler;
-
import javax.security.sasl.SaslException;
import javax.security.sasl.SaslServer;
+
import org.apache.log4j.Logger;
import org.apache.qpid.AMQException;
import org.apache.qpid.framing.ConnectionCloseBody;
@@ -68,7 +68,7 @@ public class ConnectionSecureOkMethodHandler implements StateAwareMethodListener
}
MethodRegistry methodRegistry = session.getMethodRegistry();
AuthenticationResult authResult = authMgr.authenticate(ss, body.getResponse());
- switch (authResult.getStatus())
+ switch (authResult.status)
{
case ERROR:
Exception cause = authResult.getCause();
@@ -88,10 +88,7 @@ public class ConnectionSecureOkMethodHandler implements StateAwareMethodListener
disposeSaslServer(session);
break;
case SUCCESS:
- if (_logger.isInfoEnabled())
- {
- _logger.info("Connected as: " + UsernamePrincipal.getUsernamePrincipalFromSubject(authResult.getSubject()));
- }
+ _logger.info("Connected as: " + ss.getAuthorizationID());
stateManager.changeState(AMQState.CONNECTION_NOT_TUNED);
ConnectionTuneBody tuneBody =
@@ -99,13 +96,13 @@ public class ConnectionSecureOkMethodHandler implements StateAwareMethodListener
ConnectionStartOkMethodHandler.getConfiguredFrameSize(),
ApplicationRegistry.getInstance().getConfiguration().getHeartBeatDelay());
session.writeFrame(tuneBody.generateFrame(0));
- session.setAuthorizedSubject(authResult.getSubject());
+ session.setAuthorizedID(new UsernamePrincipal(ss.getAuthorizationID()));
disposeSaslServer(session);
break;
case CONTINUE:
stateManager.changeState(AMQState.CONNECTION_NOT_AUTH);
- ConnectionSecureBody secureBody = methodRegistry.createConnectionSecureBody(authResult.getChallenge());
+ ConnectionSecureBody secureBody = methodRegistry.createConnectionSecureBody(authResult.challenge);
session.writeFrame(secureBody.generateFrame(0));
}
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionStartOkMethodHandler.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionStartOkMethodHandler.java
index 2dd9a63540..4442f969c4 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
@@ -65,6 +65,7 @@ public class ConnectionStartOkMethodHandler implements StateAwareMethodListener<
_logger.info("Locale selected: " + body.getLocale());
AuthenticationManager authMgr = ApplicationRegistry.getInstance().getAuthenticationManager();
+
SaslServer ss = null;
try
{
@@ -77,7 +78,8 @@ public class ConnectionStartOkMethodHandler implements StateAwareMethodListener<
session.setSaslServer(ss);
- final AuthenticationResult authResult = authMgr.authenticate(ss, body.getResponse());
+ AuthenticationResult authResult = authMgr.authenticate(ss, body.getResponse());
+
//save clientProperties
if (session.getClientProperties() == null)
{
@@ -86,7 +88,7 @@ public class ConnectionStartOkMethodHandler implements StateAwareMethodListener<
MethodRegistry methodRegistry = session.getMethodRegistry();
- switch (authResult.getStatus())
+ switch (authResult.status)
{
case ERROR:
Exception cause = authResult.getCause();
@@ -106,11 +108,8 @@ public class ConnectionStartOkMethodHandler implements StateAwareMethodListener<
break;
case SUCCESS:
- if (_logger.isInfoEnabled())
- {
- _logger.info("Connected as: " + UsernamePrincipal.getUsernamePrincipalFromSubject(authResult.getSubject()));
- }
- session.setAuthorizedSubject(authResult.getSubject());
+ _logger.info("Connected as: " + ss.getAuthorizationID());
+ session.setAuthorizedID(new UsernamePrincipal(ss.getAuthorizationID()));
stateManager.changeState(AMQState.CONNECTION_NOT_TUNED);
@@ -122,7 +121,7 @@ public class ConnectionStartOkMethodHandler implements StateAwareMethodListener<
case CONTINUE:
stateManager.changeState(AMQState.CONNECTION_NOT_AUTH);
- ConnectionSecureBody secureBody = methodRegistry.createConnectionSecureBody(authResult.getChallenge());
+ ConnectionSecureBody secureBody = methodRegistry.createConnectionSecureBody(authResult.challenge);
session.writeFrame(secureBody.generateFrame(0));
}
}
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 0cfed77f2e..8939cfa334 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
@@ -106,7 +106,7 @@ public class QueueDeclareHandler implements StateAwareMethodListener<QueueDeclar
else
{
queue = createQueue(queueName, body, virtualHost, protocolConnection);
- queue.setAuthorizationHolder(protocolConnection);
+ queue.setPrincipalHolder(protocolConnection);
if (queue.isDurable() && !queue.isAutoDelete())
{
store.createQueue(queue, body.getArguments());
@@ -119,7 +119,7 @@ public class QueueDeclareHandler implements StateAwareMethodListener<QueueDeclar
if (body.getExclusive())
{
queue.setExclusiveOwningSession(protocolConnection.getChannel(channelId));
- queue.setAuthorizationHolder(protocolConnection);
+ queue.setPrincipalHolder(protocolConnection);
if(!body.getDurable())
{
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/information/management/ServerInformationMBean.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/information/management/ServerInformationMBean.java
index 5e6a143d52..db2cc970b2 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/information/management/ServerInformationMBean.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/information/management/ServerInformationMBean.java
@@ -22,11 +22,9 @@ package org.apache.qpid.server.information.management;
import java.io.IOException;
-import org.apache.qpid.common.QpidProperties;
import org.apache.qpid.management.common.mbeans.ServerInformation;
import org.apache.qpid.management.common.mbeans.annotations.MBeanDescription;
import org.apache.qpid.server.management.AMQManagedObject;
-import org.apache.qpid.server.registry.ApplicationRegistry;
import javax.management.JMException;
@@ -36,15 +34,12 @@ public class ServerInformationMBean extends AMQManagedObject implements ServerIn
{
private String buildVersion;
private String productVersion;
- private ApplicationRegistry registry;
- public ServerInformationMBean(ApplicationRegistry applicationRegistry) throws JMException
+ public ServerInformationMBean(String buildVersion, String productVersion) throws JMException
{
super(ServerInformation.class, ServerInformation.TYPE);
-
- registry = applicationRegistry;
- buildVersion = QpidProperties.getBuildVersion();
- productVersion = QpidProperties.getReleaseVersion();
+ this.buildVersion = buildVersion;
+ this.productVersion = productVersion;
}
public String getObjectInstanceName()
@@ -72,75 +67,5 @@ public class ServerInformationMBean extends AMQManagedObject implements ServerIn
return productVersion;
}
-
- public void resetStatistics() throws Exception
- {
- registry.resetStatistics();
- }
-
- public double getPeakMessageDeliveryRate()
- {
- return registry.getMessageDeliveryStatistics().getPeak();
- }
-
- public double getPeakDataDeliveryRate()
- {
- return registry.getDataDeliveryStatistics().getPeak();
- }
-
- public double getMessageDeliveryRate()
- {
- return registry.getMessageDeliveryStatistics().getRate();
- }
-
- public double getDataDeliveryRate()
- {
- return registry.getDataDeliveryStatistics().getRate();
- }
-
- public long getTotalMessagesDelivered()
- {
- return registry.getMessageDeliveryStatistics().getTotal();
- }
-
- public long getTotalDataDelivered()
- {
- return registry.getDataDeliveryStatistics().getTotal();
- }
-
- public double getPeakMessageReceiptRate()
- {
- return registry.getMessageReceiptStatistics().getPeak();
- }
-
- public double getPeakDataReceiptRate()
- {
- return registry.getDataReceiptStatistics().getPeak();
- }
-
- public double getMessageReceiptRate()
- {
- return registry.getMessageReceiptStatistics().getRate();
- }
-
- public double getDataReceiptRate()
- {
- return registry.getDataReceiptStatistics().getRate();
- }
-
- public long getTotalMessagesReceived()
- {
- return registry.getMessageReceiptStatistics().getTotal();
- }
-
- public long getTotalDataReceived()
- {
- return registry.getDataReceiptStatistics().getTotal();
- }
-
- public boolean isStatisticsEnabled()
- {
- return registry.isStatisticsEnabled();
- }
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/messages/Broker_logmessages.properties b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/messages/Broker_logmessages.properties
index 5d1e85fe41..6b83a7e7a5 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/messages/Broker_logmessages.properties
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/messages/Broker_logmessages.properties
@@ -32,7 +32,4 @@ STOPPED = BRK-1005 : Stopped
# 0 - path
CONFIG = BRK-1006 : Using configuration : {0}
# 0 - path
-LOG_CONFIG = BRK-1007 : Using logging configuration : {0}
-
-STATS_DATA = BRK-1008 : {0,choice,0#delivered|1#received} : {1,number,#.###} kB/s peak : {2,number,#} bytes total
-STATS_MSGS = BRK-1009 : {0,choice,0#delivered|1#received} : {1,number,#.###} msg/s peak : {2,number,#} msgs total \ No newline at end of file
+LOG_CONFIG = BRK-1007 : Using logging configuration : {0} \ No newline at end of file
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/messages/Channel_logmessages.properties b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/messages/Channel_logmessages.properties
index ed8c0d0ce9..53bcd712f2 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/messages/Channel_logmessages.properties
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/messages/Channel_logmessages.properties
@@ -28,7 +28,3 @@ PREFETCH_SIZE = CHN-1004 : Prefetch Size (bytes) {0,number} : Count {1,number}
# 0 - queue causing flow control
FLOW_ENFORCED = CHN-1005 : Flow Control Enforced (Queue {0})
FLOW_REMOVED = CHN-1006 : Flow Control Removed
-# Channel Transactions
-# 0 - time in milliseconds
-OPEN_TXN = CHN-1007 : Open Transaction : {0,number} ms
-IDLE_TXN = CHN-1008 : Idle Transaction : {0,number} ms
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/messages/VirtualHost_logmessages.properties b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/messages/VirtualHost_logmessages.properties
index 3e640c7929..66bbefacb0 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/messages/VirtualHost_logmessages.properties
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/messages/VirtualHost_logmessages.properties
@@ -20,7 +20,4 @@
#
# 0 - name
CREATED = VHT-1001 : Created : {0}
-CLOSED = VHT-1002 : Closed
-
-STATS_DATA = VHT-1003 : {0} : {1,choice,0#delivered|1#received} : {2,number,#.###} kB/s peak : {3,number,#} bytes total
-STATS_MSGS = VHT-1004 : {0} : {1,choice,0#delivered|1#received} : {2,number,#.###} msg/s peak : {3,number,#} msgs total` \ No newline at end of file
+CLOSED = VHT-1002 : Closed \ No newline at end of file
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/subjects/ChannelLogSubject.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/subjects/ChannelLogSubject.java
index 9b357403a8..f28873940b 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/subjects/ChannelLogSubject.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/subjects/ChannelLogSubject.java
@@ -47,7 +47,7 @@ public class ChannelLogSubject extends AbstractLogSubject
*/
setLogStringWithFormat(CHANNEL_FORMAT,
session.getSessionID(),
- session.getAuthorizedPrincipal().getName(),
+ session.getPrincipal().getName(),
session.getRemoteAddress(),
session.getVirtualHost().getName(),
channel.getChannelId());
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/subjects/ConnectionLogSubject.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/subjects/ConnectionLogSubject.java
index c1c836f9b4..a697029d24 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/subjects/ConnectionLogSubject.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/subjects/ConnectionLogSubject.java
@@ -56,7 +56,7 @@ public class ConnectionLogSubject extends AbstractLogSubject
{
if (!_upToDate)
{
- if (_session.getAuthorizedPrincipal() != null)
+ if (_session.getPrincipal() != null)
{
if (_session.getVirtualHost() != null)
{
@@ -72,7 +72,7 @@ public class ConnectionLogSubject extends AbstractLogSubject
*/
_logString = "[" + MessageFormat.format(CONNECTION_FORMAT,
_session.getSessionID(),
- _session.getAuthorizedPrincipal().getName(),
+ _session.getPrincipal().getName(),
_session.getRemoteAddress(),
_session.getVirtualHost().getName())
+ "] ";
@@ -83,7 +83,7 @@ public class ConnectionLogSubject extends AbstractLogSubject
{
_logString = "[" + MessageFormat.format(USER_FORMAT,
_session.getSessionID(),
- _session.getAuthorizedPrincipal().getName(),
+ _session.getPrincipal().getName(),
_session.getRemoteAddress())
+ "] ";
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 e44b8c41cb..0a739af695 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
@@ -26,9 +26,8 @@ import javax.management.NotCompliantMBeanException;
import javax.management.ObjectName;
import javax.management.StandardMBean;
-import org.apache.log4j.Logger;
+import org.apache.qpid.AMQException;
import org.apache.qpid.server.registry.ApplicationRegistry;
-import org.apache.qpid.server.registry.IApplicationRegistry;
/**
* Provides implementation of the boilerplate ManagedObject interface. Most managed objects should find it useful
@@ -37,14 +36,10 @@ import org.apache.qpid.server.registry.IApplicationRegistry;
*/
public abstract class DefaultManagedObject extends StandardMBean implements ManagedObject
{
- private static final Logger LOGGER = Logger.getLogger(ApplicationRegistry.class);
-
private Class<?> _managementInterface;
private String _typeName;
- private ManagedObjectRegistry _registry;
-
protected DefaultManagedObject(Class<?> managementInterface, String typeName)
throws NotCompliantMBeanException
{
@@ -70,26 +65,23 @@ public abstract class DefaultManagedObject extends StandardMBean implements Mana
public void register() throws JMException
{
- _registry = ApplicationRegistry.getInstance().getManagedObjectRegistry();
- _registry.registerObject(this);
+ getManagedObjectRegistry().registerObject(this);
}
- public void unregister()
+ protected ManagedObjectRegistry getManagedObjectRegistry()
+ {
+ return ApplicationRegistry.getInstance().getManagedObjectRegistry();
+ }
+
+ public void unregister() throws AMQException
{
try
{
- if(_registry != null)
- {
- _registry.unregisterObject(this);
- }
+ getManagedObjectRegistry().unregisterObject(this);
}
catch (JMException e)
{
- LOGGER.error("Error unregistering managed object: " + this + ": " + e, e);
- }
- finally
- {
- _registry = null;
+ throw new AMQException("Error unregistering managed object: " + this + ": " + e, e);
}
}
@@ -161,4 +153,32 @@ public abstract class DefaultManagedObject extends StandardMBean implements Mana
return "";
}
+ protected static StringBuffer jmxEncode(StringBuffer jmxName, int attrPos)
+ {
+ for (int i = attrPos; i < jmxName.length(); i++)
+ {
+ if (jmxName.charAt(i) == ',')
+ {
+ jmxName.setCharAt(i, ';');
+ }
+ else if (jmxName.charAt(i) == ':')
+ {
+ jmxName.setCharAt(i, '-');
+ }
+ else if (jmxName.charAt(i) == '?' ||
+ jmxName.charAt(i) == '*' ||
+ jmxName.charAt(i) == '\\')
+ {
+ jmxName.insert(i, '\\');
+ i++;
+ }
+ else if (jmxName.charAt(i) == '\n')
+ {
+ jmxName.insert(i, '\\');
+ i++;
+ jmxName.setCharAt(i, 'n');
+ }
+ }
+ return jmxName;
+ }
}
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 6a34ff4a26..0334a856c1 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/management/JMXManagedObjectRegistry.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/management/JMXManagedObjectRegistry.java
@@ -20,6 +20,32 @@
*/
package org.apache.qpid.server.management;
+import org.apache.commons.configuration.ConfigurationException;
+import org.apache.log4j.Logger;
+import org.apache.qpid.AMQException;
+import org.apache.qpid.server.registry.ApplicationRegistry;
+import org.apache.qpid.server.registry.IApplicationRegistry;
+import org.apache.qpid.server.security.auth.database.PrincipalDatabase;
+import org.apache.qpid.server.security.auth.rmi.RMIPasswordAuthenticator;
+import org.apache.qpid.server.logging.actors.CurrentActor;
+import org.apache.qpid.server.logging.messages.ManagementConsoleMessages;
+
+import javax.management.JMException;
+import javax.management.MBeanServer;
+import javax.management.MBeanServerFactory;
+import javax.management.ObjectName;
+import javax.management.NotificationListener;
+import javax.management.NotificationFilterSupport;
+import javax.management.remote.JMXConnectorServer;
+import javax.management.remote.JMXServiceURL;
+import javax.management.remote.MBeanServerForwarder;
+import javax.management.remote.JMXConnectionNotification;
+import javax.management.remote.rmi.RMIConnectorServer;
+import javax.management.remote.rmi.RMIJRMPServerImpl;
+import javax.management.remote.rmi.RMIServerImpl;
+import javax.rmi.ssl.SslRMIClientSocketFactory;
+import javax.rmi.ssl.SslRMIServerSocketFactory;
+
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
@@ -38,31 +64,7 @@ import java.rmi.server.RMIClientSocketFactory;
import java.rmi.server.RMIServerSocketFactory;
import java.rmi.server.UnicastRemoteObject;
import java.util.HashMap;
-
-import javax.management.JMException;
-import javax.management.MBeanServer;
-import javax.management.MBeanServerFactory;
-import javax.management.NotificationFilterSupport;
-import javax.management.NotificationListener;
-import javax.management.ObjectName;
-import javax.management.remote.JMXConnectionNotification;
-import javax.management.remote.JMXConnectorServer;
-import javax.management.remote.JMXServiceURL;
-import javax.management.remote.MBeanServerForwarder;
-import javax.management.remote.rmi.RMIConnectorServer;
-import javax.management.remote.rmi.RMIJRMPServerImpl;
-import javax.management.remote.rmi.RMIServerImpl;
-import javax.rmi.ssl.SslRMIClientSocketFactory;
-import javax.rmi.ssl.SslRMIServerSocketFactory;
-
-import org.apache.commons.configuration.ConfigurationException;
-import org.apache.log4j.Logger;
-import org.apache.qpid.AMQException;
-import org.apache.qpid.server.logging.actors.CurrentActor;
-import org.apache.qpid.server.logging.messages.ManagementConsoleMessages;
-import org.apache.qpid.server.registry.ApplicationRegistry;
-import org.apache.qpid.server.registry.IApplicationRegistry;
-import org.apache.qpid.server.security.auth.rmi.RMIPasswordAuthenticator;
+import java.util.Map;
/**
* This class starts up an MBeanserver. If out of the box agent has been enabled then there are no
@@ -111,6 +113,12 @@ public class JMXManagedObjectRegistry implements ManagedObjectRegistry
IApplicationRegistry appRegistry = ApplicationRegistry.getInstance();
int port = appRegistry.getConfiguration().getJMXManagementPort();
+ //retrieve the Principal Database assigned to JMX authentication duties
+ String jmxDatabaseName = appRegistry.getConfiguration().getJMXPrincipalDatabase();
+ Map<String, PrincipalDatabase> map = appRegistry.getDatabaseManager().getDatabases();
+ PrincipalDatabase db = map.get(jmxDatabaseName);
+
+ HashMap<String,Object> env = new HashMap<String,Object>();
//Socket factories for the RMIConnectorServer, either default or SLL depending on configuration
RMIClientSocketFactory csf;
@@ -192,8 +200,7 @@ public class JMXManagedObjectRegistry implements ManagedObjectRegistry
//add a JMXAuthenticator implementation the env map to authenticate the RMI based JMX connector server
RMIPasswordAuthenticator rmipa = new RMIPasswordAuthenticator();
- rmipa.setAuthenticationManager(appRegistry.getAuthenticationManager());
- HashMap<String,Object> env = new HashMap<String,Object>();
+ rmipa.setPrincipalDatabase(db);
env.put(JMXConnectorServer.AUTHENTICATOR, rmipa);
/*
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/management/MBeanInvocationHandlerImpl.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/management/MBeanInvocationHandlerImpl.java
index 68f7689283..964b5ed5a0 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
@@ -26,6 +26,8 @@ import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.security.AccessControlContext;
import java.security.AccessController;
+import java.security.Principal;
+import java.util.Properties;
import java.util.Set;
import javax.management.Attribute;
@@ -42,6 +44,7 @@ import javax.management.remote.MBeanServerForwarder;
import javax.security.auth.Subject;
import org.apache.log4j.Logger;
+import org.apache.qpid.server.logging.actors.CurrentActor;
import org.apache.qpid.server.logging.actors.ManagementActor;
import org.apache.qpid.server.logging.messages.ManagementConsoleMessages;
import org.apache.qpid.server.registry.ApplicationRegistry;
@@ -49,15 +52,20 @@ import org.apache.qpid.server.security.SecurityManager;
import org.apache.qpid.server.security.access.Operation;
/**
- * This class can be used by the JMXConnectorServer as an InvocationHandler for the mbean operations. It delegates
- * JMX access decisions to the SecurityPlugin.
+ * This class can be used by the JMXConnectorServer as an InvocationHandler for the mbean operations. This implements
+ * the logic for allowing the users to invoke MBean operations and implements the restrictions for readOnly, readWrite
+ * and admin users.
*/
public class MBeanInvocationHandlerImpl implements InvocationHandler, NotificationListener
{
private static final Logger _logger = Logger.getLogger(MBeanInvocationHandlerImpl.class);
+ public final static String ADMIN = "admin";
+ public final static String READWRITE = "readwrite";
+ public final static String READONLY = "readonly";
private final static String DELEGATE = "JMImplementation:type=MBeanServerDelegate";
private MBeanServer _mbs;
+ private static Properties _userRoles = new Properties();
private static ManagementActor _logActor;
public static MBeanServerForwarder newProxyInstance()
@@ -129,13 +137,14 @@ public class MBeanInvocationHandlerImpl implements InvocationHandler, Notificati
Set<JMXPrincipal> principals = subject.getPrincipals(JMXPrincipal.class);
if (principals == null || principals.isEmpty())
{
- throw new SecurityException("Access denied: no JMX principal");
+ throw new SecurityException("Access denied: no principal");
}
-
- // Save the subject
- SecurityManager.setThreadSubject(subject);
-
- // Get the component, type and impact, which may be null
+
+ // Save the principal
+ Principal principal = principals.iterator().next();
+ SecurityManager.setThreadPrincipal(principal);
+
+ // Get the component, type and impact, which may be null
String type = getType(method, args);
String vhost = getVirtualHost(method, args);
int impact = getImpact(method, args);
@@ -204,20 +213,6 @@ public class MBeanInvocationHandlerImpl implements InvocationHandler, Notificati
ObjectName object = (ObjectName) args[0];
String vhost = object.getKeyProperty("VirtualHost");
- if(vhost != null)
- {
- try
- {
- //if the name is quoted in the ObjectName, unquote it
- vhost = ObjectName.unquote(vhost);
- }
- catch(IllegalArgumentException e)
- {
- //ignore, this just means the name is not quoted
- //and can be left unchanged
- }
- }
-
return vhost;
}
return null;
@@ -277,7 +272,7 @@ public class MBeanInvocationHandlerImpl implements InvocationHandler, Notificati
}
catch (JMException ex)
{
- _logger.error("Unable to determine mbean impact for method : " + mbeanMethod, ex);
+ ex.printStackTrace();
}
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/message/ContentHeaderBodyAdapter.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/message/ContentHeaderBodyAdapter.java
index 84a1642578..194835ac02 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/message/ContentHeaderBodyAdapter.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/message/ContentHeaderBodyAdapter.java
@@ -37,7 +37,7 @@ public class ContentHeaderBodyAdapter implements AMQMessageHeader
private BasicContentHeaderProperties getProperties()
{
- return (BasicContentHeaderProperties) _contentHeaderBody.getProperties();
+ return (BasicContentHeaderProperties) _contentHeaderBody.properties;
}
public String getCorrelationId()
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/message/MessageMetaData.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/message/MessageMetaData.java
index 66cb7ed83b..30bea7b6e6 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/message/MessageMetaData.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/message/MessageMetaData.java
@@ -161,7 +161,7 @@ public class MessageMetaData implements StorableMessageMetaData
public boolean isPersistent()
{
- BasicContentHeaderProperties properties = (BasicContentHeaderProperties) (_contentHeaderBody.getProperties());
+ BasicContentHeaderProperties properties = (BasicContentHeaderProperties) (_contentHeaderBody.properties);
return properties.getDeliveryMode() == BasicContentHeaderProperties.PERSISTENT;
}
@@ -229,7 +229,7 @@ public class MessageMetaData implements StorableMessageMetaData
{
private BasicContentHeaderProperties getProperties()
{
- return (BasicContentHeaderProperties) getContentHeaderBody().getProperties();
+ return (BasicContentHeaderProperties) getContentHeaderBody().properties;
}
public String getCorrelationId()
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/plugins/Plugin.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/plugins/Plugin.java
index 804a9d5027..e7f9983fff 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/plugins/Plugin.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/plugins/Plugin.java
@@ -27,5 +27,5 @@ public interface Plugin
/**
* Provide Configuration to this plugin
*/
- public void configure(ConfigurationPlugin config) throws ConfigurationException;
+ public void configure(ConfigurationPlugin config);
}
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 c8a7b56ccb..a6bab017a1 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
@@ -18,16 +18,8 @@
*/
package org.apache.qpid.server.plugins;
-import static org.apache.felix.framework.util.FelixConstants.SYSTEMBUNDLE_ACTIVATORS_PROP;
-import static org.apache.felix.main.AutoProcessor.AUTO_DEPLOY_ACTION_PROPERY;
-import static org.apache.felix.main.AutoProcessor.AUTO_DEPLOY_DIR_PROPERY;
-import static org.apache.felix.main.AutoProcessor.AUTO_DEPLOY_INSTALL_VALUE;
-import static org.apache.felix.main.AutoProcessor.AUTO_DEPLOY_START_VALUE;
-import static org.apache.felix.main.AutoProcessor.process;
-import static org.osgi.framework.Constants.FRAMEWORK_STORAGE;
-import static org.osgi.framework.Constants.FRAMEWORK_STORAGE_CLEAN;
-import static org.osgi.framework.Constants.FRAMEWORK_STORAGE_CLEAN_ONFIRSTINIT;
-import static org.osgi.framework.Constants.FRAMEWORK_SYSTEMPACKAGES;
+import static org.apache.felix.framework.util.FelixConstants.*;
+import static org.apache.felix.main.AutoProcessor.*;
import java.io.File;
import java.util.ArrayList;
@@ -43,20 +35,18 @@ import org.apache.felix.framework.util.StringMap;
import org.apache.log4j.Logger;
import org.apache.qpid.common.Closeable;
import org.apache.qpid.server.configuration.TopicConfiguration;
-import org.apache.qpid.server.configuration.plugins.ConfigurationPluginFactory;
import org.apache.qpid.server.configuration.plugins.SlowConsumerDetectionConfiguration.SlowConsumerDetectionConfigurationFactory;
import org.apache.qpid.server.configuration.plugins.SlowConsumerDetectionPolicyConfiguration.SlowConsumerDetectionPolicyConfigurationFactory;
import org.apache.qpid.server.configuration.plugins.SlowConsumerDetectionQueueConfiguration.SlowConsumerDetectionQueueConfigurationFactory;
+import org.apache.qpid.server.configuration.plugins.ConfigurationPluginFactory;
import org.apache.qpid.server.exchange.ExchangeType;
import org.apache.qpid.server.security.SecurityManager;
import org.apache.qpid.server.security.SecurityPluginFactory;
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.LegacyAccess;
-import org.apache.qpid.server.security.auth.manager.AuthenticationManagerPluginFactory;
-import org.apache.qpid.server.security.auth.manager.PrincipalDatabaseAuthenticationManager;
-import org.apache.qpid.server.virtualhost.plugins.SlowConsumerDetection;
import org.apache.qpid.server.virtualhost.plugins.VirtualHostPluginFactory;
+import org.apache.qpid.server.virtualhost.plugins.SlowConsumerDetection;
import org.apache.qpid.server.virtualhost.plugins.policies.TopicDeletePolicy;
import org.apache.qpid.slowconsumerdetection.policies.SlowConsumerPolicyPluginFactory;
import org.osgi.framework.BundleActivator;
@@ -73,7 +63,7 @@ public class PluginManager implements Closeable
private static final Logger _logger = Logger.getLogger(PluginManager.class);
private static final int FELIX_STOP_TIMEOUT = 30000;
- private static final String QPID_VER_SUFFIX = "version=0.13,";
+ private static final String QPID_VER_SUFFIX = "version=0.9,";
private Framework _felix;
@@ -82,7 +72,6 @@ public class PluginManager implements Closeable
private ServiceTracker _configTracker = null;
private ServiceTracker _virtualHostTracker = null;
private ServiceTracker _policyTracker = null;
- private ServiceTracker _authenticationManagerTracker = null;
private Activator _activator;
@@ -90,7 +79,6 @@ public class PluginManager implements Closeable
private Map<List<String>, ConfigurationPluginFactory> _configPlugins = new IdentityHashMap<List<String>, ConfigurationPluginFactory>();
private Map<String, VirtualHostPluginFactory> _vhostPlugins = new HashMap<String, VirtualHostPluginFactory>();
private Map<String, SlowConsumerPolicyPluginFactory> _policyPlugins = new HashMap<String, SlowConsumerPolicyPluginFactory>();
- private Map<String, AuthenticationManagerPluginFactory<? extends Plugin>> _authenticationManagerPlugins = new HashMap<String, AuthenticationManagerPluginFactory<? extends Plugin>>();
public PluginManager(String pluginPath, String cachePath) throws Exception
{
@@ -109,8 +97,7 @@ public class PluginManager implements Closeable
LegacyAccess.LegacyAccessConfiguration.FACTORY,
new SlowConsumerDetectionConfigurationFactory(),
new SlowConsumerDetectionPolicyConfigurationFactory(),
- new SlowConsumerDetectionQueueConfigurationFactory(),
- PrincipalDatabaseAuthenticationManager.PrincipalDatabaseAuthenticationManagerConfiguration.FACTORY))
+ new SlowConsumerDetectionQueueConfigurationFactory()))
{
_configPlugins.put(configFactory.getParentPaths(), configFactory);
}
@@ -125,12 +112,6 @@ public class PluginManager implements Closeable
_vhostPlugins.put(pluginFactory.getClass().getName(), pluginFactory);
}
- for (AuthenticationManagerPluginFactory<? extends Plugin> pluginFactory : Arrays.asList(
- PrincipalDatabaseAuthenticationManager.FACTORY))
- {
- _authenticationManagerPlugins.put(pluginFactory.getPluginName(), pluginFactory);
- }
-
// Check the plugin directory path is set and exist
if (pluginPath == null)
{
@@ -186,8 +167,7 @@ public class PluginManager implements Closeable
"org.apache.commons.logging; version=1.0.0," +
"org.apache.log4j; version=1.2.12," +
"javax.management.openmbean; version=1.0.0," +
- "javax.management; version=1.0.0," +
- "javax.security.auth; version=1.0.0"
+ "javax.management; version=1.0.0"
);
// No automatic shutdown hook
@@ -251,9 +231,6 @@ public class PluginManager implements Closeable
_policyTracker = new ServiceTracker(_activator.getContext(), SlowConsumerPolicyPluginFactory.class.getName(), null);
_policyTracker.open();
- _authenticationManagerTracker = new ServiceTracker(_activator.getContext(), AuthenticationManagerPluginFactory.class.getName(), null);
- _authenticationManagerTracker.open();
-
_logger.info("Opened service trackers");
}
@@ -324,11 +301,6 @@ public class PluginManager implements Closeable
return getServices(_securityTracker, _securityPlugins);
}
- public Map<String, AuthenticationManagerPluginFactory<? extends Plugin>> getAuthenticationManagerPlugins()
- {
- return getServices(_authenticationManagerTracker, _authenticationManagerPlugins);
- }
-
public void close()
{
if (_felix != null)
@@ -341,7 +313,6 @@ public class PluginManager implements Closeable
_configTracker.close();
_virtualHostTracker.close();
_policyTracker.close();
- _authenticationManagerTracker.close();
}
finally
{
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQConnectionModel.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQConnectionModel.java
index 061ebf50cd..bcda385f64 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQConnectionModel.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQConnectionModel.java
@@ -20,35 +20,14 @@
*/
package org.apache.qpid.server.protocol;
-import java.util.List;
-import java.util.UUID;
-
-import org.apache.qpid.AMQException;
import org.apache.qpid.protocol.AMQConstant;
-import org.apache.qpid.server.logging.LogSubject;
-import org.apache.qpid.server.stats.StatisticsGatherer;
+import org.apache.qpid.AMQException;
-public interface AMQConnectionModel extends StatisticsGatherer
+public interface AMQConnectionModel
{
- /**
- * get a unique id for this connection.
- *
- * @return a {@link UUID} representing the connection
- */
- public UUID getId();
-
- /**
- * Close the underlying Connection
- *
- * @param cause
- * @param message
- * @throws org.apache.qpid.AMQException
- */
- public void close(AMQConstant cause, String message) throws AMQException;
/**
* Close the given requested Session
- *
* @param session
* @param cause
* @param message
@@ -57,16 +36,4 @@ public interface AMQConnectionModel extends StatisticsGatherer
public void closeSession(AMQSessionModel session, AMQConstant cause, String message) throws AMQException;
public long getConnectionId();
-
- /**
- * Get a list of all sessions using this connection.
- *
- * @return a list of {@link AMQSessionModel}s
- */
- public List<AMQSessionModel> getSessionModels();
-
- /**
- * Return a {@link LogSubject} for the connection.
- */
- public LogSubject getLogSubject();
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolEngine.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolEngine.java
index d6201f7cf6..a1ffe272fd 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolEngine.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolEngine.java
@@ -30,6 +30,7 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
+import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.CopyOnWriteArraySet;
@@ -37,10 +38,10 @@ import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicLong;
import javax.management.JMException;
-import javax.security.auth.Subject;
import javax.security.sasl.SaslServer;
import org.apache.log4j.Logger;
+import org.apache.mina.transport.vmpipe.VmPipeAddress;
import org.apache.qpid.AMQChannelException;
import org.apache.qpid.AMQConnectionException;
import org.apache.qpid.AMQException;
@@ -89,14 +90,12 @@ import org.apache.qpid.server.management.ManagedObject;
import org.apache.qpid.server.output.ProtocolOutputConverter;
import org.apache.qpid.server.output.ProtocolOutputConverterRegistry;
import org.apache.qpid.server.registry.ApplicationRegistry;
-import org.apache.qpid.server.security.auth.sasl.UsernamePrincipal;
import org.apache.qpid.server.state.AMQState;
import org.apache.qpid.server.state.AMQStateManager;
-import org.apache.qpid.server.stats.StatisticsCounter;
import org.apache.qpid.server.virtualhost.VirtualHost;
import org.apache.qpid.server.virtualhost.VirtualHostRegistry;
+import org.apache.qpid.transport.NetworkDriver;
import org.apache.qpid.transport.Sender;
-import org.apache.qpid.transport.network.NetworkConnection;
public class AMQProtocolEngine implements ProtocolEngine, Managable, AMQProtocolSession, ConnectionConfig
{
@@ -147,7 +146,7 @@ public class AMQProtocolEngine implements ProtocolEngine, Managable, AMQProtocol
private Map<Integer, Long> _closingChannelsList = new ConcurrentHashMap<Integer, Long>();
private ProtocolOutputConverter _protocolOutputConverter;
- private Subject _authorizedSubject;
+ private Principal _authorizedID;
private MethodDispatcher _dispatcher;
private ProtocolSessionIdentifier _sessionIdentifier;
@@ -157,6 +156,8 @@ public class AMQProtocolEngine implements ProtocolEngine, Managable, AMQProtocol
private AMQPConnectionActor _actor;
private LogSubject _logSubject;
+ private NetworkDriver _networkDriver;
+
private long _lastIoTime;
private long _writtenBytes;
@@ -171,28 +172,21 @@ public class AMQProtocolEngine implements ProtocolEngine, Managable, AMQProtocol
private final UUID _id;
private final ConfigStore _configStore;
private long _createTime = System.currentTimeMillis();
-
- private ApplicationRegistry _registry;
- private boolean _statisticsEnabled = false;
- private StatisticsCounter _messagesDelivered, _dataDelivered, _messagesReceived, _dataReceived;
-
- private final NetworkConnection _network;
- private final Sender<ByteBuffer> _sender;
public ManagedObject getManagedObject()
{
return _managedObject;
}
- public AMQProtocolEngine(VirtualHostRegistry virtualHostRegistry, NetworkConnection network)
+ public AMQProtocolEngine(VirtualHostRegistry virtualHostRegistry, NetworkDriver driver)
{
_stateManager = new AMQStateManager(virtualHostRegistry, this);
+ _networkDriver = driver;
+
_codecFactory = new AMQCodecFactory(true, this);
_poolReference.acquireExecutorService();
_readJob = new Job(_poolReference, Job.MAX_JOB_EVENTS, true);
_writeJob = new Job(_poolReference, Job.MAX_JOB_EVENTS, false);
- _network = network;
- _sender = _network.getSender();
_actor = new AMQPConnectionActor(this, virtualHostRegistry.getApplicationRegistry().getRootMessageLogger());
@@ -201,10 +195,9 @@ public class AMQProtocolEngine implements ProtocolEngine, Managable, AMQProtocol
_configStore = virtualHostRegistry.getConfigStore();
_id = _configStore.createId();
+
_actor.message(ConnectionMessages.OPEN(null, null, false, false));
- _registry = virtualHostRegistry.getApplicationRegistry();
- initialiseStatistics();
}
private AMQProtocolSessionMBean createMBean() throws JMException
@@ -370,14 +363,14 @@ public class AMQProtocolEngine implements ProtocolEngine, Managable, AMQProtocol
null,
mechanisms.getBytes(),
locales.getBytes());
- _sender.send(responseBody.generateFrame(0).toNioByteBuffer());
+ _networkDriver.send(responseBody.generateFrame(0).toNioByteBuffer());
}
catch (AMQException e)
{
_logger.info("Received unsupported protocol initiation for protocol version: " + getProtocolVersion());
- _sender.send(new ProtocolInitiation(ProtocolVersion.getLatestSupportedVersion()).toNioByteBuffer());
+ _networkDriver.send(new ProtocolInitiation(ProtocolVersion.getLatestSupportedVersion()).toNioByteBuffer());
}
}
@@ -498,7 +491,7 @@ public class AMQProtocolEngine implements ProtocolEngine, Managable, AMQProtocol
{
public void run()
{
- _sender.send(buf);
+ _networkDriver.send(buf);
}
});
}
@@ -690,8 +683,8 @@ public class AMQProtocolEngine implements ProtocolEngine, Managable, AMQProtocol
{
if (delay > 0)
{
- _network.setMaxWriteIdle(delay);
- _network.setMaxReadIdle((int) (ApplicationRegistry.getInstance().getConfiguration().getHeartBeatTimeout() * delay));
+ _networkDriver.setMaxWriteIdle(delay);
+ _networkDriver.setMaxReadIdle((int) (ApplicationRegistry.getInstance().getConfiguration().getHeartBeatTimeout() * delay));
}
}
@@ -795,7 +788,7 @@ public class AMQProtocolEngine implements ProtocolEngine, Managable, AMQProtocol
public void closeProtocolSession()
{
- _sender.close();
+ _networkDriver.close();
try
{
_stateManager.changeState(AMQState.CONNECTION_CLOSED);
@@ -808,7 +801,7 @@ public class AMQProtocolEngine implements ProtocolEngine, Managable, AMQProtocol
public String toString()
{
- return getRemoteAddress() + "(" + (getAuthorizedPrincipal() == null ? "?" : getAuthorizedPrincipal().getName() + ")");
+ return getRemoteAddress() + "(" + (getAuthorizedID() == null ? "?" : getAuthorizedID().getName() + ")");
}
public String dump()
@@ -830,11 +823,17 @@ public class AMQProtocolEngine implements ProtocolEngine, Managable, AMQProtocol
*/
public String getLocalFQDN()
{
- SocketAddress address = _network.getLocalAddress();
+ SocketAddress address = _networkDriver.getLocalAddress();
+ // we use the vmpipe address in some tests hence the need for this rather ugly test. The host
+ // information is used by SASL primary.
if (address instanceof InetSocketAddress)
{
return ((InetSocketAddress) address).getHostName();
}
+ else if (address instanceof VmPipeAddress)
+ {
+ return "vmpipe:" + ((VmPipeAddress) address).getPort();
+ }
else
{
throw new IllegalArgumentException("Unsupported socket address class: " + address);
@@ -913,7 +912,7 @@ public class AMQProtocolEngine implements ProtocolEngine, Managable, AMQProtocol
public Object getClientIdentifier()
{
- return _network.getRemoteAddress();
+ return (_networkDriver != null) ? _networkDriver.getRemoteAddress() : null;
}
public VirtualHost getVirtualHost()
@@ -955,33 +954,29 @@ public class AMQProtocolEngine implements ProtocolEngine, Managable, AMQProtocol
return _protocolOutputConverter;
}
- public void setAuthorizedSubject(final Subject authorizedSubject)
+ public void setAuthorizedID(Principal authorizedID)
{
- if (authorizedSubject == null)
- {
- throw new IllegalArgumentException("authorizedSubject cannot be null");
- }
- _authorizedSubject = authorizedSubject;
+ _authorizedID = authorizedID;
}
-
- public Subject getAuthorizedSubject()
+
+ public Principal getAuthorizedID()
{
- return _authorizedSubject;
+ return _authorizedID;
}
-
- public Principal getAuthorizedPrincipal()
+
+ public Principal getPrincipal()
{
- return _authorizedSubject == null ? null : UsernamePrincipal.getUsernamePrincipalFromSubject(_authorizedSubject);
+ return _authorizedID;
}
public SocketAddress getRemoteAddress()
{
- return _network.getRemoteAddress();
+ return _networkDriver.getRemoteAddress();
}
public SocketAddress getLocalAddress()
{
- return _network.getLocalAddress();
+ return _networkDriver.getLocalAddress();
}
public MethodRegistry getMethodRegistry()
@@ -1011,9 +1006,14 @@ public class AMQProtocolEngine implements ProtocolEngine, Managable, AMQProtocol
// Nothing
}
+ public void setNetworkDriver(NetworkDriver driver)
+ {
+ _networkDriver = driver;
+ }
+
public void writerIdle()
{
- _sender.send(HeartbeatBody.FRAME.toNioByteBuffer());
+ _networkDriver.send(HeartbeatBody.FRAME.toNioByteBuffer());
}
public void exception(Throwable throwable)
@@ -1021,7 +1021,7 @@ public class AMQProtocolEngine implements ProtocolEngine, Managable, AMQProtocol
if (throwable instanceof AMQProtocolHeaderException)
{
writeFrame(new ProtocolInitiation(ProtocolVersion.getLatestSupportedVersion()));
- _sender.close();
+ _networkDriver.close();
_logger.error("Error in protocol initiation " + this + ":" + getRemoteAddress() + " :" + throwable.getMessage(), throwable);
}
@@ -1039,7 +1039,7 @@ public class AMQProtocolEngine implements ProtocolEngine, Managable, AMQProtocol
writeFrame(closeBody.generateFrame(0));
- _sender.close();
+ _networkDriver.close();
}
}
@@ -1078,6 +1078,19 @@ public class AMQProtocolEngine implements ProtocolEngine, Managable, AMQProtocol
return (_clientVersion == null) ? null : _clientVersion.toString();
}
+ public void closeIfLingeringClosedChannels()
+ {
+ for (Entry<Integer, Long>id : _closingChannelsList.entrySet())
+ {
+ if (id.getValue() + 30000 > System.currentTimeMillis())
+ {
+ // We have a channel that we closed 30 seconds ago. Client's dead, kill the connection
+ _logger.error("Closing connection as channel was closed more than 30 seconds ago and no ChannelCloseOk has been processed");
+ closeProtocolSession();
+ }
+ }
+ }
+
public Boolean isIncoming()
{
return true;
@@ -1095,7 +1108,7 @@ public class AMQProtocolEngine implements ProtocolEngine, Managable, AMQProtocol
public String getAuthId()
{
- return getAuthorizedPrincipal().getName();
+ return getAuthorizedID().getName();
}
public Integer getRemotePID()
@@ -1250,6 +1263,7 @@ public class AMQProtocolEngine implements ProtocolEngine, Managable, AMQProtocol
public void closeSession(AMQSessionModel session, AMQConstant cause, String message) throws AMQException
{
+
closeChannel((Integer)session.getID());
MethodRegistry methodRegistry = getMethodRegistry();
@@ -1260,97 +1274,5 @@ public class AMQProtocolEngine implements ProtocolEngine, Managable, AMQProtocol
0,0);
writeFrame(responseBody.generateFrame((Integer)session.getID()));
- }
-
- public void close(AMQConstant cause, String message) throws AMQException
- {
- closeConnection(0, new AMQConnectionException(cause, message, 0, 0,
- getProtocolOutputConverter().getProtocolMajorVersion(),
- getProtocolOutputConverter().getProtocolMinorVersion(),
- (Throwable) null), true);
- }
-
- public List<AMQSessionModel> getSessionModels()
- {
- List<AMQSessionModel> sessions = new ArrayList<AMQSessionModel>();
- for (AMQChannel channel : getChannels())
- {
- sessions.add((AMQSessionModel) channel);
- }
- return sessions;
- }
-
- public LogSubject getLogSubject()
- {
- return _logSubject;
- }
-
- public void registerMessageDelivered(long messageSize)
- {
- if (isStatisticsEnabled())
- {
- _messagesDelivered.registerEvent(1L);
- _dataDelivered.registerEvent(messageSize);
- }
- _virtualHost.registerMessageDelivered(messageSize);
- }
-
- public void registerMessageReceived(long messageSize, long timestamp)
- {
- if (isStatisticsEnabled())
- {
- _messagesReceived.registerEvent(1L, timestamp);
- _dataReceived.registerEvent(messageSize, timestamp);
- }
- _virtualHost.registerMessageReceived(messageSize, timestamp);
- }
-
- public StatisticsCounter getMessageReceiptStatistics()
- {
- return _messagesReceived;
- }
-
- public StatisticsCounter getDataReceiptStatistics()
- {
- return _dataReceived;
- }
-
- public StatisticsCounter getMessageDeliveryStatistics()
- {
- return _messagesDelivered;
- }
-
- public StatisticsCounter getDataDeliveryStatistics()
- {
- return _dataDelivered;
- }
-
- public void resetStatistics()
- {
- _messagesDelivered.reset();
- _dataDelivered.reset();
- _messagesReceived.reset();
- _dataReceived.reset();
- }
-
- public void initialiseStatistics()
- {
- setStatisticsEnabled(!StatisticsCounter.DISABLE_STATISTICS &&
- _registry.getConfiguration().isStatisticsGenerationConnectionsEnabled());
-
- _messagesDelivered = new StatisticsCounter("messages-delivered-" + getSessionID());
- _dataDelivered = new StatisticsCounter("data-delivered-" + getSessionID());
- _messagesReceived = new StatisticsCounter("messages-received-" + getSessionID());
- _dataReceived = new StatisticsCounter("data-received-" + getSessionID());
- }
-
- public boolean isStatisticsEnabled()
- {
- return _statisticsEnabled;
- }
-
- public void setStatisticsEnabled(boolean enabled)
- {
- _statisticsEnabled = enabled;
- }
+ }
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolEngineFactory.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolEngineFactory.java
index 94870c98bd..0e4444725e 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolEngineFactory.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolEngineFactory.java
@@ -25,7 +25,7 @@ import org.apache.qpid.protocol.ProtocolEngine;
import org.apache.qpid.protocol.ProtocolEngineFactory;
import org.apache.qpid.server.registry.ApplicationRegistry;
import org.apache.qpid.server.virtualhost.VirtualHostRegistry;
-import org.apache.qpid.transport.network.NetworkConnection;
+import org.apache.qpid.transport.NetworkDriver;
public class AMQProtocolEngineFactory implements ProtocolEngineFactory
{
@@ -38,12 +38,13 @@ public class AMQProtocolEngineFactory implements ProtocolEngineFactory
public AMQProtocolEngineFactory(Integer port)
{
- _vhosts = ApplicationRegistry.getInstance().getVirtualHostRegistry();
+ _vhosts = ApplicationRegistry.getInstance(port).getVirtualHostRegistry();
}
- public ProtocolEngine newProtocolEngine(NetworkConnection network)
+ public ProtocolEngine newProtocolEngine(NetworkDriver networkDriver)
{
- return new AMQProtocolEngine(_vhosts, network);
+ return new AMQProtocolEngine(_vhosts, networkDriver);
}
+
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolSession.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolSession.java
index 9116bf2767..f48a214933 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolSession.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolSession.java
@@ -20,7 +20,6 @@
*/
package org.apache.qpid.server.protocol;
-import javax.security.auth.Subject;
import javax.security.sasl.SaslServer;
import org.apache.qpid.AMQException;
@@ -29,15 +28,16 @@ import org.apache.qpid.framing.*;
import org.apache.qpid.AMQConnectionException;
import org.apache.qpid.protocol.AMQVersionAwareProtocolSession;
import org.apache.qpid.server.AMQChannel;
-import org.apache.qpid.server.security.AuthorizationHolder;
+import org.apache.qpid.server.security.PrincipalHolder;
import org.apache.qpid.server.logging.LogActor;
import org.apache.qpid.server.output.ProtocolOutputConverter;
import org.apache.qpid.server.virtualhost.VirtualHost;
+import java.security.Principal;
import java.util.List;
-public interface AMQProtocolSession extends AMQVersionAwareProtocolSession, AuthorizationHolder, AMQConnectionModel
+public interface AMQProtocolSession extends AMQVersionAwareProtocolSession, PrincipalHolder, AMQConnectionModel
{
long getSessionID();
@@ -205,7 +205,7 @@ public interface AMQProtocolSession extends AMQVersionAwareProtocolSession, Auth
public ProtocolOutputConverter getProtocolOutputConverter();
- void setAuthorizedSubject(Subject authorizedSubject);
+ void setAuthorizedID(Principal authorizedID);
public java.net.SocketAddress getRemoteAddress();
@@ -231,5 +231,7 @@ public interface AMQProtocolSession extends AMQVersionAwareProtocolSession, Auth
List<AMQChannel> getChannels();
+ void closeIfLingeringClosedChannels();
+
void mgmtCloseChannel(int channelId);
}
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 16d99de492..f4f2cab2c2 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,15 +37,25 @@
*/
package org.apache.qpid.server.protocol;
-import java.util.Date;
-import java.util.List;
+import org.apache.qpid.AMQException;
+import org.apache.qpid.framing.AMQShortString;
+import org.apache.qpid.framing.ConnectionCloseBody;
+import org.apache.qpid.framing.MethodRegistry;
+import org.apache.qpid.management.common.mbeans.ManagedConnection;
+import org.apache.qpid.management.common.mbeans.annotations.MBeanConstructor;
+import org.apache.qpid.management.common.mbeans.annotations.MBeanDescription;
+import org.apache.qpid.protocol.AMQConstant;
+import org.apache.qpid.server.AMQChannel;
+import org.apache.qpid.server.logging.actors.CurrentActor;
+import org.apache.qpid.server.logging.actors.ManagementActor;
+import org.apache.qpid.server.management.AMQManagedObject;
+import org.apache.qpid.server.management.ManagedObject;
import javax.management.JMException;
import javax.management.MBeanException;
import javax.management.MBeanNotificationInfo;
import javax.management.NotCompliantMBeanException;
import javax.management.Notification;
-import javax.management.ObjectName;
import javax.management.monitor.MonitorNotification;
import javax.management.openmbean.CompositeData;
import javax.management.openmbean.CompositeDataSupport;
@@ -56,20 +66,8 @@ import javax.management.openmbean.SimpleType;
import javax.management.openmbean.TabularData;
import javax.management.openmbean.TabularDataSupport;
import javax.management.openmbean.TabularType;
-
-import org.apache.qpid.AMQException;
-import org.apache.qpid.framing.AMQShortString;
-import org.apache.qpid.framing.ConnectionCloseBody;
-import org.apache.qpid.framing.MethodRegistry;
-import org.apache.qpid.management.common.mbeans.ManagedConnection;
-import org.apache.qpid.management.common.mbeans.annotations.MBeanConstructor;
-import org.apache.qpid.management.common.mbeans.annotations.MBeanDescription;
-import org.apache.qpid.protocol.AMQConstant;
-import org.apache.qpid.server.AMQChannel;
-import org.apache.qpid.server.logging.actors.CurrentActor;
-import org.apache.qpid.server.logging.actors.ManagementActor;
-import org.apache.qpid.server.management.AMQManagedObject;
-import org.apache.qpid.server.management.ManagedObject;
+import java.util.Date;
+import java.util.List;
/**
* This MBean class implements the management interface. In order to make more attributes, operations and notifications
@@ -96,7 +94,8 @@ public class AMQProtocolSessionMBean extends AMQManagedObject implements Managed
super(ManagedConnection.class, ManagedConnection.TYPE);
_protocolSession = amqProtocolSession;
String remote = getRemoteAddress();
- _name = "anonymous".equals(remote) ? (remote + hashCode()) : remote;
+ remote = "anonymous".equals(remote) ? (remote + hashCode()) : remote;
+ _name = jmxEncode(new StringBuffer(remote), 0).toString();
init();
}
@@ -131,7 +130,7 @@ public class AMQProtocolSessionMBean extends AMQManagedObject implements Managed
public String getAuthorizedId()
{
- return (_protocolSession.getAuthorizedPrincipal() != null ) ? _protocolSession.getAuthorizedPrincipal().getName() : null;
+ return (_protocolSession.getPrincipal() != null ) ? _protocolSession.getPrincipal().getName() : null;
}
public String getVersion()
@@ -176,7 +175,7 @@ public class AMQProtocolSessionMBean extends AMQManagedObject implements Managed
public String getObjectInstanceName()
{
- return ObjectName.quote(_name);
+ return _name;
}
/**
@@ -340,78 +339,4 @@ public class AMQProtocolSessionMBean extends AMQManagedObject implements Managed
_broadcaster.sendNotification(n);
}
- public void resetStatistics() throws Exception
- {
- _protocolSession.resetStatistics();
- }
-
- public double getPeakMessageDeliveryRate()
- {
- return _protocolSession.getMessageDeliveryStatistics().getPeak();
- }
-
- public double getPeakDataDeliveryRate()
- {
- return _protocolSession.getDataDeliveryStatistics().getPeak();
- }
-
- public double getMessageDeliveryRate()
- {
- return _protocolSession.getMessageDeliveryStatistics().getRate();
- }
-
- public double getDataDeliveryRate()
- {
- return _protocolSession.getDataDeliveryStatistics().getRate();
- }
-
- public long getTotalMessagesDelivered()
- {
- return _protocolSession.getMessageDeliveryStatistics().getTotal();
- }
-
- public long getTotalDataDelivered()
- {
- return _protocolSession.getDataDeliveryStatistics().getTotal();
- }
-
- public double getPeakMessageReceiptRate()
- {
- return _protocolSession.getMessageReceiptStatistics().getPeak();
- }
-
- public double getPeakDataReceiptRate()
- {
- return _protocolSession.getDataReceiptStatistics().getPeak();
- }
-
- public double getMessageReceiptRate()
- {
- return _protocolSession.getMessageReceiptStatistics().getRate();
- }
-
- public double getDataReceiptRate()
- {
- return _protocolSession.getDataReceiptStatistics().getRate();
- }
-
- public long getTotalMessagesReceived()
- {
- return _protocolSession.getMessageReceiptStatistics().getTotal();
- }
-
- public long getTotalDataReceived()
- {
- return _protocolSession.getDataReceiptStatistics().getTotal();
- }
-
- public boolean isStatisticsEnabled()
- {
- return _protocolSession.isStatisticsEnabled();
- }
-
- public void setStatisticsEnabled(boolean enabled)
- {
- _protocolSession.setStatisticsEnabled(enabled);
- }
-}
+} // End of MBean class
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQSessionModel.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQSessionModel.java
index bc63403a86..a9b2354d75 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQSessionModel.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQSessionModel.java
@@ -20,35 +20,15 @@
*/
package org.apache.qpid.server.protocol;
-import org.apache.qpid.AMQException;
import org.apache.qpid.server.logging.LogSubject;
public interface AMQSessionModel
{
- public Object getID();
+ Object getID();
- public AMQConnectionModel getConnectionModel();
+ AMQConnectionModel getConnectionModel();
- public String getClientID();
-
- public void close() throws AMQException;
+ String getClientID();
- public LogSubject getLogSubject();
-
- /**
- * This method is called from the housekeeping thread to check the status of
- * transactions on this session and react appropriately.
- *
- * If a transaction is open for too long or idle for too long then a warning
- * is logged or the connection is closed, depending on the configuration. An open
- * transaction is one that has recent activity. The transaction age is counted
- * from the time the transaction was started. An idle transaction is one that
- * has had no activity, such as publishing or acknowledgeing messages.
- *
- * @param openWarn time in milliseconds before alerting on open transaction
- * @param openClose time in milliseconds before closing connection with open transaction
- * @param idleWarn time in milliseconds before alerting on idle transaction
- * @param idleClose time in milliseconds before closing connection with idle transaction
- */
- public void checkTransactionStatus(long openWarn, long openClose, long idleWarn, long idleClose) throws AMQException;
+ LogSubject getLogSubject();
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AmqpProtocolVersion.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AmqpProtocolVersion.java
deleted file mode 100644
index e925d7a1ec..0000000000
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AmqpProtocolVersion.java
+++ /dev/null
@@ -1,23 +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;
-
-public enum AmqpProtocolVersion { v0_8, v0_9, v0_9_1, v0_10 } \ No newline at end of file
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/MultiVersionProtocolEngine.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/MultiVersionProtocolEngine.java
index 01b12b44ce..eb957ee33c 100755
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/MultiVersionProtocolEngine.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/MultiVersionProtocolEngine.java
@@ -23,11 +23,11 @@ package org.apache.qpid.server.protocol;
import org.apache.log4j.Logger;
import org.apache.qpid.protocol.ProtocolEngine;
+import org.apache.qpid.server.protocol.MultiVersionProtocolEngineFactory.VERSION;
import org.apache.qpid.server.registry.IApplicationRegistry;
import org.apache.qpid.server.transport.ServerConnection;
import org.apache.qpid.transport.ConnectionDelegate;
-import org.apache.qpid.transport.Sender;
-import org.apache.qpid.transport.network.NetworkConnection;
+import org.apache.qpid.transport.NetworkDriver;
import java.net.SocketAddress;
import java.nio.ByteBuffer;
@@ -37,24 +37,28 @@ public class MultiVersionProtocolEngine implements ProtocolEngine
{
private static final Logger _logger = Logger.getLogger(MultiVersionProtocolEngine.class);
- private Set<AmqpProtocolVersion> _supported;
+
+
+ private NetworkDriver _networkDriver;
+ private Set<VERSION> _supported;
private String _fqdn;
private IApplicationRegistry _appRegistry;
- private NetworkConnection _network;
- private Sender<ByteBuffer> _sender;
-
+
private volatile ProtocolEngine _delegate = new SelfDelegateProtocolEngine();
public MultiVersionProtocolEngine(IApplicationRegistry appRegistry,
String fqdn,
- Set<AmqpProtocolVersion> supported,
- NetworkConnection network)
+ Set<VERSION> supported, NetworkDriver networkDriver)
{
_appRegistry = appRegistry;
_fqdn = fqdn;
_supported = supported;
- _network = network;
- _sender = _network.getSender();
+ _networkDriver = networkDriver;
+ }
+
+ public void setNetworkDriver(NetworkDriver driver)
+ {
+ _delegate.setNetworkDriver(driver);
}
public SocketAddress getRemoteAddress()
@@ -151,7 +155,7 @@ private static final byte[] AMQP_0_9_1_HEADER =
private static interface DelegateCreator
{
- AmqpProtocolVersion getVersion();
+ VERSION getVersion();
byte[] getHeaderIdentifier();
ProtocolEngine getProtocolEngine();
}
@@ -159,9 +163,9 @@ private static final byte[] AMQP_0_9_1_HEADER =
private DelegateCreator creator_0_8 = new DelegateCreator()
{
- public AmqpProtocolVersion getVersion()
+ public VERSION getVersion()
{
- return AmqpProtocolVersion.v0_8;
+ return VERSION.v0_8;
}
public byte[] getHeaderIdentifier()
@@ -171,16 +175,16 @@ private static final byte[] AMQP_0_9_1_HEADER =
public ProtocolEngine getProtocolEngine()
{
- return new AMQProtocolEngine(_appRegistry.getVirtualHostRegistry(), _network);
+ return new AMQProtocolEngine(_appRegistry.getVirtualHostRegistry(), _networkDriver);
}
};
private DelegateCreator creator_0_9 = new DelegateCreator()
{
- public AmqpProtocolVersion getVersion()
+ public VERSION getVersion()
{
- return AmqpProtocolVersion.v0_9;
+ return VERSION.v0_9;
}
@@ -191,16 +195,16 @@ private static final byte[] AMQP_0_9_1_HEADER =
public ProtocolEngine getProtocolEngine()
{
- return new AMQProtocolEngine(_appRegistry.getVirtualHostRegistry(), _network);
+ return new AMQProtocolEngine(_appRegistry.getVirtualHostRegistry(), _networkDriver);
}
};
private DelegateCreator creator_0_9_1 = new DelegateCreator()
{
- public AmqpProtocolVersion getVersion()
+ public VERSION getVersion()
{
- return AmqpProtocolVersion.v0_9_1;
+ return VERSION.v0_9_1;
}
@@ -211,7 +215,7 @@ private static final byte[] AMQP_0_9_1_HEADER =
public ProtocolEngine getProtocolEngine()
{
- return new AMQProtocolEngine(_appRegistry.getVirtualHostRegistry(), _network);
+ return new AMQProtocolEngine(_appRegistry.getVirtualHostRegistry(), _networkDriver);
}
};
@@ -219,9 +223,9 @@ private static final byte[] AMQP_0_9_1_HEADER =
private DelegateCreator creator_0_10 = new DelegateCreator()
{
- public AmqpProtocolVersion getVersion()
+ public VERSION getVersion()
{
- return AmqpProtocolVersion.v0_10;
+ return VERSION.v0_10;
}
@@ -238,7 +242,7 @@ private static final byte[] AMQP_0_9_1_HEADER =
ServerConnection conn = new ServerConnection();
conn.setConnectionDelegate(connDelegate);
- return new ProtocolEngine_0_10( conn, _network, _appRegistry);
+ return new ProtocolEngine_0_10( conn, _networkDriver, _appRegistry);
}
};
@@ -248,14 +252,19 @@ private static final byte[] AMQP_0_9_1_HEADER =
private class ClosedDelegateProtocolEngine implements ProtocolEngine
{
+ public void setNetworkDriver(NetworkDriver driver)
+ {
+ _networkDriver = driver;
+ }
+
public SocketAddress getRemoteAddress()
{
- return _network.getRemoteAddress();
+ return _networkDriver.getRemoteAddress();
}
public SocketAddress getLocalAddress()
{
- return _network.getLocalAddress();
+ return _networkDriver.getLocalAddress();
}
public long getWrittenBytes()
@@ -296,16 +305,22 @@ private static final byte[] AMQP_0_9_1_HEADER =
private class SelfDelegateProtocolEngine implements ProtocolEngine
{
+
private final ByteBuffer _header = ByteBuffer.allocate(MINIMUM_REQUIRED_HEADER_BYTES);
+ public void setNetworkDriver(NetworkDriver driver)
+ {
+ _networkDriver = driver;
+ }
+
public SocketAddress getRemoteAddress()
{
- return _network.getRemoteAddress();
+ return _networkDriver.getRemoteAddress();
}
public SocketAddress getLocalAddress()
{
- return _network.getLocalAddress();
+ return _networkDriver.getLocalAddress();
}
public long getWrittenBytes()
@@ -365,12 +380,14 @@ private static final byte[] AMQP_0_9_1_HEADER =
// If no delegate is found then send back the most recent support protocol version id
if(newDelegate == null)
{
- _sender.send(ByteBuffer.wrap(newestSupported));
+ _networkDriver.send(ByteBuffer.wrap(newestSupported));
_delegate = new ClosedDelegateProtocolEngine();
}
else
{
+ newDelegate.setNetworkDriver(_networkDriver);
+
_delegate = newDelegate;
_header.flip();
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/MultiVersionProtocolEngineFactory.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/MultiVersionProtocolEngineFactory.java
index 96d46353c6..75358c42d9 100755
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/MultiVersionProtocolEngineFactory.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/MultiVersionProtocolEngineFactory.java
@@ -20,22 +20,28 @@
*/
package org.apache.qpid.server.protocol;
-import java.util.EnumSet;
-import java.util.Set;
-
-import org.apache.qpid.protocol.ProtocolEngine;
import org.apache.qpid.protocol.ProtocolEngineFactory;
+import org.apache.qpid.protocol.ProtocolEngine;
+import org.apache.qpid.transport.NetworkDriver;
import org.apache.qpid.server.registry.ApplicationRegistry;
import org.apache.qpid.server.registry.IApplicationRegistry;
-import org.apache.qpid.transport.network.NetworkConnection;
+
+import java.util.Set;
+import java.util.Arrays;
+import java.util.HashSet;
public class MultiVersionProtocolEngineFactory implements ProtocolEngineFactory
{
- private static final Set<AmqpProtocolVersion> ALL_VERSIONS = EnumSet.allOf(AmqpProtocolVersion.class);
+ ;
+
+
+ public enum VERSION { v0_8, v0_9, v0_9_1, v0_10 };
+
+ private static final Set<VERSION> ALL_VERSIONS = new HashSet<VERSION>(Arrays.asList(VERSION.values()));
private final IApplicationRegistry _appRegistry;
private final String _fqdn;
- private final Set<AmqpProtocolVersion> _supported;
+ private final Set<VERSION> _supported;
public MultiVersionProtocolEngineFactory()
@@ -43,7 +49,7 @@ public class MultiVersionProtocolEngineFactory implements ProtocolEngineFactory
this(1, "localhost", ALL_VERSIONS);
}
- public MultiVersionProtocolEngineFactory(String fqdn, Set<AmqpProtocolVersion> versions)
+ public MultiVersionProtocolEngineFactory(String fqdn, Set<VERSION> versions)
{
this(1, fqdn, versions);
}
@@ -54,16 +60,16 @@ public class MultiVersionProtocolEngineFactory implements ProtocolEngineFactory
this(1, fqdn, ALL_VERSIONS);
}
- public MultiVersionProtocolEngineFactory(int instance, String fqdn, Set<AmqpProtocolVersion> supportedVersions)
+ public MultiVersionProtocolEngineFactory(int instance, String fqdn, Set<VERSION> supportedVersions)
{
- _appRegistry = ApplicationRegistry.getInstance();
+ _appRegistry = ApplicationRegistry.getInstance(instance);
_fqdn = fqdn;
_supported = supportedVersions;
}
- public ProtocolEngine newProtocolEngine(NetworkConnection network)
+ public ProtocolEngine newProtocolEngine(NetworkDriver networkDriver)
{
- return new MultiVersionProtocolEngine(_appRegistry, _fqdn, _supported, network);
+ return new MultiVersionProtocolEngine(_appRegistry, _fqdn, _supported, networkDriver);
}
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/ProtocolEngine_0_10.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/ProtocolEngine_0_10.java
index 8c62441d59..30d506a89b 100755
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/ProtocolEngine_0_10.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/ProtocolEngine_0_10.java
@@ -21,12 +21,13 @@
package org.apache.qpid.server.protocol;
import org.apache.qpid.protocol.ProtocolEngine;
+import org.apache.qpid.transport.NetworkDriver;
import org.apache.qpid.transport.network.InputHandler;
import org.apache.qpid.transport.network.Assembler;
import org.apache.qpid.transport.network.Disassembler;
-import org.apache.qpid.transport.network.NetworkConnection;
import org.apache.qpid.server.configuration.*;
import org.apache.qpid.server.transport.ServerConnection;
+import org.apache.qpid.server.logging.actors.CurrentActor;
import org.apache.qpid.server.logging.messages.ConnectionMessages;
import org.apache.qpid.server.registry.IApplicationRegistry;
@@ -37,7 +38,7 @@ public class ProtocolEngine_0_10 extends InputHandler implements ProtocolEngine
{
public static final int MAX_FRAME_SIZE = 64 * 1024 - 1;
- private NetworkConnection _network;
+ private NetworkDriver _networkDriver;
private long _readBytes;
private long _writtenBytes;
private ServerConnection _connection;
@@ -46,17 +47,26 @@ public class ProtocolEngine_0_10 extends InputHandler implements ProtocolEngine
private long _createTime = System.currentTimeMillis();
public ProtocolEngine_0_10(ServerConnection conn,
- NetworkConnection network,
+ NetworkDriver networkDriver,
final IApplicationRegistry appRegistry)
{
super(new Assembler(conn));
_connection = conn;
_connection.setConnectionConfig(this);
- _network = network;
+ _networkDriver = networkDriver;
_id = appRegistry.getConfigStore().createId();
_appRegistry = appRegistry;
- _connection.setSender(new Disassembler(_network.getSender(), MAX_FRAME_SIZE));
+ // FIXME Two log messages to maintain compatinbility with earlier protocol versions
+ _connection.getLogActor().message(ConnectionMessages.OPEN(null, null, false, false));
+ _connection.getLogActor().message(ConnectionMessages.OPEN(null, "0-10", false, true));
+ }
+
+ public void setNetworkDriver(NetworkDriver driver)
+ {
+ _networkDriver = driver;
+ Disassembler dis = new Disassembler(driver, MAX_FRAME_SIZE);
+ _connection.setSender(dis);
_connection.onOpen(new Runnable()
{
public void run()
@@ -65,19 +75,16 @@ public class ProtocolEngine_0_10 extends InputHandler implements ProtocolEngine
}
});
- // FIXME Two log messages to maintain compatibility with earlier protocol versions
- _connection.getLogActor().message(ConnectionMessages.OPEN(null, null, false, false));
- _connection.getLogActor().message(ConnectionMessages.OPEN(null, "0-10", false, true));
}
public SocketAddress getRemoteAddress()
{
- return _network.getRemoteAddress();
+ return _networkDriver.getRemoteAddress();
}
public SocketAddress getLocalAddress()
{
- return _network.getLocalAddress();
+ return _networkDriver.getLocalAddress();
}
public long getReadBytes()
@@ -127,7 +134,7 @@ public class ProtocolEngine_0_10 extends InputHandler implements ProtocolEngine
public String getAuthId()
{
- return _connection.getAuthorizedPrincipal() == null ? null : _connection.getAuthorizedPrincipal().getName();
+ return _connection.getAuthorizationID();
}
public String getRemoteProcessName()
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 371ae0de50..b6e97e08fb 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/AMQPriorityQueue.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/AMQPriorityQueue.java
@@ -60,7 +60,7 @@ public class AMQPriorityQueue extends SimpleAMQQueue
{
// check that all subscriptions are not in advance of the entry
SubscriptionList.SubscriptionNodeIterator subIter = _subscriptionList.iterator();
- while(subIter.advance() && entry.isAvailable())
+ while(subIter.advance() && !entry.isAcquired())
{
final Subscription subscription = subIter.getNode().getSubscription();
if(!subscription.isClosed())
@@ -70,7 +70,7 @@ public class AMQPriorityQueue extends SimpleAMQQueue
{
QueueEntry subnode = context._lastSeenEntry;
QueueEntry released = context._releasedEntry;
- while(subnode != null && entry.compareTo(subnode) < 0 && entry.isAvailable() && (released == null || released.compareTo(entry) < 0))
+ while(subnode != null && entry.compareTo(subnode) < 0 && !entry.isAcquired() && (released == null || released.compareTo(entry) < 0))
{
if(QueueContext._releasedUpdater.compareAndSet(context,released,entry))
{
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueue.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueue.java
index 9140a13625..de9dc42de8 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
@@ -21,18 +21,21 @@
package org.apache.qpid.server.queue;
import org.apache.qpid.AMQException;
+import org.apache.qpid.AMQSecurityException;
import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.server.AMQChannel;
import org.apache.qpid.server.configuration.plugins.ConfigurationPlugin;
import org.apache.qpid.server.logging.LogSubject;
+import org.apache.qpid.server.protocol.AMQConnectionModel;
import org.apache.qpid.server.protocol.AMQSessionModel;
import org.apache.qpid.server.binding.Binding;
import org.apache.qpid.server.configuration.QueueConfig;
+import org.apache.qpid.server.configuration.QueueConfiguration;
import org.apache.qpid.server.exchange.Exchange;
import org.apache.qpid.server.exchange.ExchangeReferrer;
import org.apache.qpid.server.management.Managable;
import org.apache.qpid.server.management.ManagedObject;
-import org.apache.qpid.server.security.AuthorizationHolder;
+import org.apache.qpid.server.security.PrincipalHolder;
import org.apache.qpid.server.store.TransactionLogResource;
import org.apache.qpid.server.subscription.Subscription;
import org.apache.qpid.server.txn.ServerTransaction;
@@ -69,8 +72,8 @@ public interface AMQQueue extends Managable, Comparable<AMQQueue>, ExchangeRefer
boolean isAutoDelete();
AMQShortString getOwner();
- AuthorizationHolder getAuthorizationHolder();
- void setAuthorizationHolder(AuthorizationHolder principalHolder);
+ PrincipalHolder getPrincipalHolder();
+ void setPrincipalHolder(PrincipalHolder principalHolder);
void setExclusiveOwningSession(AMQSessionModel owner);
AMQSessionModel getExclusiveOwningSession();
@@ -105,16 +108,23 @@ public interface AMQQueue extends Managable, Comparable<AMQQueue>, ExchangeRefer
boolean isDeleted();
+
int delete() throws AMQException;
+
void requeue(QueueEntry entry);
+ void requeue(QueueEntryImpl storeContext, Subscription subscription);
+
void dequeue(QueueEntry entry, Subscription sub);
void decrementUnackedMsgCount();
+
boolean resend(final QueueEntry entry, final Subscription subscription) throws AMQException;
+
+
void addQueueDeleteTask(final Task task);
void removeQueueDeleteTask(final Task task);
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 c8eb118b11..b5294b6d2f 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
@@ -43,7 +43,6 @@ import javax.management.JMException;
import javax.management.MBeanException;
import javax.management.MBeanNotificationInfo;
import javax.management.Notification;
-import javax.management.ObjectName;
import javax.management.OperationsException;
import javax.management.monitor.MonitorNotification;
import javax.management.openmbean.ArrayType;
@@ -98,7 +97,7 @@ public class AMQQueueMBean extends AMQManagedObject implements ManagedQueue, Que
{
super(ManagedQueue.class, ManagedQueue.TYPE);
_queue = queue;
- _queueName = queue.getName();
+ _queueName = jmxEncode(new StringBuffer(queue.getNameShortString()), 0).toString();
}
public ManagedObject getParentObject()
@@ -148,7 +147,7 @@ public class AMQQueueMBean extends AMQManagedObject implements ManagedQueue, Que
public String getObjectInstanceName()
{
- return ObjectName.quote(_queueName);
+ return _queueName;
}
public String getName()
@@ -507,7 +506,7 @@ public class AMQQueueMBean extends AMQManagedObject implements ManagedQueue, Que
private String[] getMessageHeaderProperties(ContentHeaderBody headerBody)
{
List<String> list = new ArrayList<String>();
- BasicContentHeaderProperties headerProperties = (BasicContentHeaderProperties) headerBody.getProperties();
+ BasicContentHeaderProperties headerProperties = (BasicContentHeaderProperties) headerBody.properties;
list.add("reply-to = " + headerProperties.getReplyToAsString());
list.add("propertyFlags = " + headerProperties.getPropertyFlags());
list.add("ApplicationID = " + headerProperties.getAppIdAsString());
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 3e3288404f..2d2fb3a214 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
@@ -96,9 +96,9 @@ public class IncomingMessage implements Filterable, InboundMessage, EnqueableMes
public void setExpiration()
{
long expiration =
- ((BasicContentHeaderProperties) _contentHeaderBody.getProperties()).getExpiration();
+ ((BasicContentHeaderProperties) _contentHeaderBody.properties).getExpiration();
long timestamp =
- ((BasicContentHeaderProperties) _contentHeaderBody.getProperties()).getTimestamp();
+ ((BasicContentHeaderProperties) _contentHeaderBody.properties).getTimestamp();
if (SYNCHED_CLOCKS)
{
@@ -193,8 +193,8 @@ public class IncomingMessage implements Filterable, InboundMessage, EnqueableMes
public boolean isPersistent()
{
- return getContentHeader().getProperties() instanceof BasicContentHeaderProperties &&
- ((BasicContentHeaderProperties) getContentHeader().getProperties()).getDeliveryMode() ==
+ return getContentHeader().properties instanceof BasicContentHeaderProperties &&
+ ((BasicContentHeaderProperties) getContentHeader().properties).getDeliveryMode() ==
BasicContentHeaderProperties.PERSISTENT;
}
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 88349586c3..edd1e0bdc3 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/QueueEntry.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/QueueEntry.java
@@ -52,17 +52,6 @@ public interface QueueEntry extends Comparable<QueueEntry>, Filterable
}
public abstract State getState();
-
- /**
- * Returns true if state is either DEQUEUED or DELETED.
- *
- * @return true if state is either DEQUEUED or DELETED.
- */
- public boolean isDispensed()
- {
- State currentState = getState();
- return currentState == State.DEQUEUED || currentState == State.DELETED;
- }
}
@@ -206,6 +195,8 @@ public interface QueueEntry extends Comparable<QueueEntry>, Filterable
boolean isRejectedBy(Subscription subscription);
+ void requeue(Subscription subscription);
+
void dequeue();
void dispose();
@@ -218,18 +209,4 @@ public interface QueueEntry extends Comparable<QueueEntry>, Filterable
void addStateChangeListener(StateChangeListener listener);
boolean removeStateChangeListener(StateChangeListener listener);
-
- /**
- * Returns true if entry is in DEQUEUED state, otherwise returns false.
- *
- * @return true if entry is in DEQUEUED state, otherwise returns false
- */
- boolean isDequeued();
-
- /**
- * Returns true if entry is either DEQUED or DELETED state.
- *
- * @return true if entry is either DEQUED or DELETED state
- */
- boolean isDispensed();
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/QueueEntryImpl.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/QueueEntryImpl.java
index e951b3dfd4..1ba4f4d89b 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
@@ -358,6 +358,15 @@ public class QueueEntryImpl implements QueueEntry
}
}
+ public void requeue(Subscription subscription)
+ {
+ getQueue().requeue(this, subscription);
+ if(_stateChangeListeners != null)
+ {
+ notifyStateChange(QueueEntry.State.ACQUIRED, QueueEntry.State.AVAILABLE);
+ }
+ }
+
public void dequeue()
{
EntryState state = _state;
@@ -499,7 +508,7 @@ public class QueueEntryImpl implements QueueEntry
{
QueueEntryImpl next = nextNode();
- while(next != null && next.isDispensed() )
+ while(next != null && next.isDeleted())
{
final QueueEntryImpl newNext = next.nextNode();
@@ -547,14 +556,4 @@ public class QueueEntryImpl implements QueueEntry
return _queueEntryList;
}
- public boolean isDequeued()
- {
- return _state == DEQUEUED_STATE;
- }
-
- public boolean isDispensed()
- {
- return _state.isDispensed();
- }
-
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/QueueRunner.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/QueueRunner.java
deleted file mode 100644
index 7e1d57e205..0000000000
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/QueueRunner.java
+++ /dev/null
@@ -1,84 +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.log4j.Logger;
-import org.apache.qpid.AMQException;
-import org.apache.qpid.pool.ReadWriteRunnable;
-import org.apache.qpid.server.logging.actors.CurrentActor;
-import org.apache.qpid.server.queue.QueueRunner;
-import org.apache.qpid.server.queue.SimpleAMQQueue;
-
-/**
- * QueueRunners are Runnables used to process a queue when requiring
- * asynchronous message delivery to subscriptions, which is necessary
- * when straight-through delivery of a message to a subscription isn't
- * possible during the enqueue operation.
- */
-public class QueueRunner implements ReadWriteRunnable
-{
- private static final Logger _logger = Logger.getLogger(QueueRunner.class);
-
- private final String _name;
- private final SimpleAMQQueue _queue;
-
- public QueueRunner(SimpleAMQQueue queue, long count)
- {
- _queue = queue;
- _name = "QueueRunner-" + count + "-" + queue.getLogActor();
- }
-
- public void run()
- {
- String originalName = Thread.currentThread().getName();
- try
- {
- Thread.currentThread().setName(_name);
- CurrentActor.set(_queue.getLogActor());
-
- _queue.processQueue(this);
- }
- catch (AMQException e)
- {
- _logger.error("Exception during asynchronous delivery by " + _name, e);
- }
- finally
- {
- CurrentActor.remove();
- Thread.currentThread().setName(originalName);
- }
- }
-
- public boolean isRead()
- {
- return false;
- }
-
- public boolean isWrite()
- {
- return true;
- }
-
- public String toString()
- {
- return _name;
- }
-} \ No newline at end of file
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 a095ef47ea..b003152db6 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
@@ -44,7 +44,7 @@ import org.apache.qpid.server.logging.subjects.QueueLogSubject;
import org.apache.qpid.server.management.ManagedObject;
import org.apache.qpid.server.message.ServerMessage;
import org.apache.qpid.server.registry.ApplicationRegistry;
-import org.apache.qpid.server.security.AuthorizationHolder;
+import org.apache.qpid.server.security.PrincipalHolder;
import org.apache.qpid.server.subscription.Subscription;
import org.apache.qpid.server.subscription.SubscriptionList;
import org.apache.qpid.server.txn.AutoCommitTransaction;
@@ -83,7 +83,7 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener
/** null means shared */
private final AMQShortString _owner;
- private AuthorizationHolder _authorizationHolder;
+ private PrincipalHolder _prinicpalHolder;
private boolean _exclusive = false;
private AMQSessionModel _exclusiveOwner;
@@ -102,7 +102,9 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener
protected final QueueEntryList _entries;
- protected final SubscriptionList _subscriptionList = new SubscriptionList();
+ protected final SubscriptionList _subscriptionList = new SubscriptionList(this);
+
+ private final AtomicReference<SubscriptionList.SubscriptionNode> _lastSubscriptionNode = new AtomicReference<SubscriptionList.SubscriptionNode>(_subscriptionList.getHead());
private volatile Subscription _exclusiveSubscriber;
@@ -371,14 +373,14 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener
return _owner;
}
- public AuthorizationHolder getAuthorizationHolder()
+ public PrincipalHolder getPrincipalHolder()
{
- return _authorizationHolder;
+ return _prinicpalHolder;
}
- public void setAuthorizationHolder(final AuthorizationHolder authorizationHolder)
+ public void setPrincipalHolder(PrincipalHolder prinicpalHolder)
{
- _authorizationHolder = authorizationHolder;
+ _prinicpalHolder = prinicpalHolder;
}
@@ -600,25 +602,25 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener
iterate over subscriptions and if any is at the end of the queue and can deliver this message, then deliver the message
*/
- SubscriptionList.SubscriptionNode node = _subscriptionList.getMarkedNode();
- SubscriptionList.SubscriptionNode nextNode = node.findNext();
+ SubscriptionList.SubscriptionNode node = _lastSubscriptionNode.get();
+ SubscriptionList.SubscriptionNode nextNode = node.getNext();
if (nextNode == null)
{
- nextNode = _subscriptionList.getHead().findNext();
+ nextNode = _subscriptionList.getHead().getNext();
}
while (nextNode != null)
{
- if (_subscriptionList.updateMarkedNode(node, nextNode))
+ if (_lastSubscriptionNode.compareAndSet(node, nextNode))
{
break;
}
else
{
- node = _subscriptionList.getMarkedNode();
- nextNode = node.findNext();
+ node = _lastSubscriptionNode.get();
+ nextNode = node.getNext();
if (nextNode == null)
{
- nextNode = _subscriptionList.getHead().findNext();
+ nextNode = _subscriptionList.getHead().getNext();
}
}
}
@@ -627,7 +629,7 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener
// this catches the case where we *just* miss an update
int loops = 2;
- while (entry.isAvailable() && loops != 0)
+ while (!(entry.isAcquired() || entry.isDeleted()) && loops != 0)
{
if (nextNode == null)
{
@@ -640,13 +642,13 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener
Subscription sub = nextNode.getSubscription();
deliverToSubscription(sub, entry);
}
- nextNode = nextNode.findNext();
+ nextNode = nextNode.getNext();
}
}
- if (entry.isAvailable())
+ if (!(entry.isAcquired() || entry.isDeleted()))
{
checkSubscriptionsNotAheadOfDelivery(entry);
@@ -803,6 +805,24 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener
}
+ public void requeue(QueueEntryImpl entry, Subscription subscription)
+ {
+ SubscriptionList.SubscriptionNodeIterator subscriberIter = _subscriptionList.iterator();
+ // iterate over all the subscribers, and if they are in advance of this queue entry then move them backwards
+ while (subscriberIter.advance())
+ {
+ Subscription sub = subscriberIter.getNode().getSubscription();
+
+ // we don't make browsers send the same stuff twice
+ if (sub.seesRequeues() && (!sub.acquires() && sub == subscription))
+ {
+ updateSubRequeueEntry(sub, entry);
+ }
+ }
+
+ deliverAsync();
+ }
+
public void dequeue(QueueEntry entry, Subscription sub)
{
decrementQueueCount();
@@ -940,7 +960,7 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener
while (queueListIterator.advance())
{
QueueEntry node = queueListIterator.getNode();
- if (node != null && !node.isDispensed())
+ if (node != null && !node.isDeleted())
{
entryList.add(node);
}
@@ -1044,7 +1064,7 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener
while (queueListIterator.advance() && !filter.filterComplete())
{
QueueEntry node = queueListIterator.getNode();
- if (!node.isDispensed() && filter.accept(node))
+ if (!node.isDeleted() && filter.accept(node))
{
entryList.add(node);
}
@@ -1238,6 +1258,7 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener
if ((messageId >= fromMessageId)
&& (messageId <= toMessageId)
+ && !node.isDeleted()
&& node.acquire())
{
dequeueEntry(node);
@@ -1267,7 +1288,7 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener
while (noDeletes && queueListIterator.advance())
{
QueueEntry node = queueListIterator.getNode();
- if (node.acquire())
+ if (!node.isDeleted() && node.acquire())
{
dequeueEntry(node);
noDeletes = false;
@@ -1297,7 +1318,7 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener
while (queueListIterator.advance())
{
QueueEntry node = queueListIterator.getNode();
- if (node.acquire())
+ if (!node.isDeleted() && node.acquire())
{
dequeueEntry(node, txn);
if(++count == request)
@@ -1564,7 +1585,7 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener
public void deliverAsync()
{
- QueueRunner runner = new QueueRunner(this, _stateChangeCount.incrementAndGet());
+ Runner runner = new Runner(_stateChangeCount.incrementAndGet());
if (_asynchronousRunner.compareAndSet(null, runner))
{
@@ -1583,6 +1604,52 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener
_asyncDelivery.execute(flusher);
}
+
+ private class Runner implements ReadWriteRunnable
+ {
+ String _name;
+ public Runner(long count)
+ {
+ _name = "QueueRunner-" + count + "-" + _logActor;
+ }
+
+ public void run()
+ {
+ String originalName = Thread.currentThread().getName();
+ try
+ {
+ Thread.currentThread().setName(_name);
+ CurrentActor.set(_logActor);
+
+ processQueue(this);
+ }
+ catch (AMQException e)
+ {
+ _logger.error(e);
+ }
+ finally
+ {
+ CurrentActor.remove();
+ Thread.currentThread().setName(originalName);
+ }
+ }
+
+ public boolean isRead()
+ {
+ return false;
+ }
+
+ public boolean isWrite()
+ {
+ return true;
+ }
+
+ public String toString()
+ {
+ return _name;
+ }
+ }
+
public void flushSubscription(Subscription sub) throws AMQException
{
// Access control
@@ -1651,7 +1718,7 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener
QueueEntry node = getNextAvailableEntry(sub);
- if (node != null && node.isAvailable())
+ if (node != null && !(node.isAcquired() || node.isDeleted()))
{
if (sub.hasInterest(node))
{
@@ -1712,7 +1779,7 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener
QueueEntry node = (releasedNode != null && lastSeen.compareTo(releasedNode)>=0) ? releasedNode : _entries.next(lastSeen);
boolean expired = false;
- while (node != null && (!node.isAvailable() || (expired = node.expired()) || !sub.hasInterest(node)))
+ while (node != null && (node.isAcquired() || node.isDeleted() || (expired = node.expired()) || !sub.hasInterest(node)))
{
if (expired)
{
@@ -1741,40 +1808,14 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener
}
- /**
- * Used by queue Runners to asynchronously deliver messages to consumers.
- *
- * A queue Runner is started whenever a state change occurs, e.g when a new
- * message arrives on the queue and cannot be immediately delivered to a
- * subscription (i.e. asynchronous delivery is required). Unless there are
- * SubFlushRunners operating (due to subscriptions unsuspending) which are
- * capable of accepting/delivering all messages then these messages would
- * otherwise remain on the queue.
- *
- * processQueue should be running while there are messages on the queue AND
- * there are subscriptions that can deliver them. If there are no
- * subscriptions capable of delivering the remaining messages on the queue
- * then processQueue should stop to prevent spinning.
- *
- * Since processQueue is runs in a fixed size Executor, it should not run
- * indefinitely to prevent starving other tasks of CPU (e.g jobs to process
- * incoming messages may not be able to be scheduled in the thread pool
- * because all threads are working on clearing down large queues). To solve
- * this problem, after an arbitrary number of message deliveries the
- * processQueue job stops iterating, resubmits itself to the executor, and
- * ends the current instance
- *
- * @param runner the Runner to schedule
- * @throws AMQException
- */
- public void processQueue(QueueRunner runner) throws AMQException
+ private void processQueue(Runnable runner) throws AMQException
{
long stateChangeCount;
long previousStateChangeCount = Long.MIN_VALUE;
boolean deliveryIncomplete = true;
- boolean lastLoop = false;
- int iterations = MAX_ASYNC_DELIVERIES;
+ int extraLoops = 1;
+ long iterations = MAX_ASYNC_DELIVERIES;
_asynchronousRunner.compareAndSet(runner, null);
@@ -1791,14 +1832,12 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener
if (previousStateChangeCount != stateChangeCount)
{
- //further asynchronous delivery is required since the
- //previous loop. keep going if iteration slicing allows.
- lastLoop = false;
+ extraLoops = 1;
}
previousStateChangeCount = stateChangeCount;
- boolean allSubscriptionsDone = true;
- boolean subscriptionDone;
+ deliveryIncomplete = _subscriptionList.size() != 0;
+ boolean done;
SubscriptionList.SubscriptionNodeIterator subscriptionIter = _subscriptionList.iterator();
//iterate over the subscribers and try to advance their pointer
@@ -1808,25 +1847,30 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener
sub.getSendLock();
try
{
- //attempt delivery. returns true if no further delivery currently possible to this sub
- subscriptionDone = attemptDelivery(sub);
- if (subscriptionDone)
+
+ done = attemptDelivery(sub);
+
+ if (done)
{
- //close autoClose subscriptions if we are not currently intent on continuing
- if (lastLoop && sub.isAutoClose())
+ if (extraLoops == 0)
{
- unregisterSubscription(sub);
+ deliveryIncomplete = false;
+ if (sub.isAutoClose())
+ {
+ unregisterSubscription(sub);
- sub.confirmAutoClose();
+ sub.confirmAutoClose();
+ }
+ }
+ else
+ {
+ extraLoops--;
}
}
else
{
- //this subscription can accept additional deliveries, so we must
- //keep going after this (if iteration slicing allows it)
- allSubscriptionsDone = false;
- lastLoop = false;
iterations--;
+ extraLoops = 1;
}
}
finally
@@ -1834,34 +1878,10 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener
sub.releaseSendLock();
}
}
-
- if(allSubscriptionsDone && lastLoop)
- {
- //We have done an extra loop already and there are again
- //again no further delivery attempts possible, only
- //keep going if state change demands it.
- deliveryIncomplete = false;
- }
- else if(allSubscriptionsDone)
- {
- //All subscriptions reported being done, but we have to do
- //an extra loop if the iterations are not exhausted and
- //there is still any work to be done
- deliveryIncomplete = _subscriptionList.size() != 0;
- lastLoop = true;
- }
- else
- {
- //some subscriptions can still accept more messages,
- //keep going if iteration count allows.
- lastLoop = false;
- deliveryIncomplete = true;
- }
-
_asynchronousRunner.set(null);
}
- // If iterations == 0 then the limiting factor was the time-slicing rather than available messages or credit
+ // If deliveries == 0 then the limitting factor was the time-slicing rather than available messages or credit
// therefore we should schedule this runner again (unless someone beats us to it :-) ).
if (iterations == 0 && _asynchronousRunner.compareAndSet(null, runner))
{
@@ -1881,8 +1901,8 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener
while (queueListIterator.advance())
{
QueueEntry node = queueListIterator.getNode();
- // Only process nodes that are not currently deleted and not dequeued
- if (!node.isDispensed())
+ // Only process nodes that are not currently deleted
+ if (!node.isDeleted())
{
// If the node has exired then aquire it
if (node.expired() && node.acquire())
@@ -2222,9 +2242,4 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener
}
}
}
-
- public LogActor getLogActor()
- {
- return _logActor;
- }
}
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 46baab8c85..b97c2c55c5 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/SimpleQueueEntryList.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/SimpleQueueEntryList.java
@@ -1,5 +1,6 @@
package org.apache.qpid.server.queue;
+import org.apache.qpid.server.message.InboundMessage;
import org.apache.qpid.server.message.ServerMessage;
import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;
@@ -155,7 +156,7 @@ public class SimpleQueueEntryList implements QueueEntryList
if(!atTail())
{
QueueEntryImpl nextNode = _lastNode.nextNode();
- while(nextNode.isDispensed() && nextNode.nextNode() != null)
+ while(nextNode.isDeleted() && nextNode.nextNode() != null)
{
nextNode = nextNode.nextNode();
}
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 7c804fc1fd..78a642f22f 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
@@ -21,14 +21,9 @@
package org.apache.qpid.server.registry;
import java.net.InetSocketAddress;
-import java.util.Collection;
import java.util.HashMap;
-import java.util.Iterator;
import java.util.Map;
-import java.util.Timer;
-import java.util.TimerTask;
import java.util.UUID;
-import java.util.concurrent.atomic.AtomicReference;
import org.apache.commons.configuration.ConfigurationException;
import org.apache.log4j.Logger;
@@ -46,27 +41,24 @@ import org.apache.qpid.server.configuration.VirtualHostConfiguration;
import org.apache.qpid.server.logging.CompositeStartupMessageLogger;
import org.apache.qpid.server.logging.Log4jMessageLogger;
import org.apache.qpid.server.logging.RootMessageLogger;
+import org.apache.qpid.server.logging.AbstractRootMessageLogger;
import org.apache.qpid.server.logging.SystemOutMessageLogger;
-import org.apache.qpid.server.logging.actors.AbstractActor;
import org.apache.qpid.server.logging.actors.BrokerActor;
import org.apache.qpid.server.logging.actors.CurrentActor;
import org.apache.qpid.server.logging.messages.BrokerMessages;
-import org.apache.qpid.server.logging.messages.VirtualHostMessages;
import org.apache.qpid.server.management.ManagedObjectRegistry;
import org.apache.qpid.server.management.NoopManagedObjectRegistry;
-import org.apache.qpid.server.plugins.Plugin;
import org.apache.qpid.server.plugins.PluginManager;
import org.apache.qpid.server.security.SecurityManager;
-import org.apache.qpid.server.security.SecurityManager.SecurityConfiguration;
+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.AuthenticationManager;
-import org.apache.qpid.server.security.auth.manager.AuthenticationManagerPluginFactory;
-import org.apache.qpid.server.stats.StatisticsCounter;
+import org.apache.qpid.server.security.auth.manager.PrincipalDatabaseAuthenticationManager;
import org.apache.qpid.server.transport.QpidAcceptor;
import org.apache.qpid.server.virtualhost.VirtualHost;
import org.apache.qpid.server.virtualhost.VirtualHostImpl;
import org.apache.qpid.server.virtualhost.VirtualHostRegistry;
-
/**
* An abstract application registry that provides access to configuration information and handles the
* construction and caching of configurable objects.
@@ -77,10 +69,12 @@ public abstract class ApplicationRegistry implements IApplicationRegistry
{
protected static final Logger _logger = Logger.getLogger(ApplicationRegistry.class);
- private static AtomicReference<IApplicationRegistry> _instance = new AtomicReference<IApplicationRegistry>(null);
+ private static Map<Integer, IApplicationRegistry> _instanceMap = new HashMap<Integer, IApplicationRegistry>();
protected final ServerConfiguration _configuration;
+ public static final int DEFAULT_INSTANCE = 1;
+
protected final Map<InetSocketAddress, QpidAcceptor> _acceptors = new HashMap<InetSocketAddress, QpidAcceptor>();
protected ManagedObjectRegistry _managedObjectRegistry;
@@ -91,6 +85,8 @@ public abstract class ApplicationRegistry implements IApplicationRegistry
protected SecurityManager _securityManager;
+ protected PrincipalDatabaseManager _databaseManager;
+
protected PluginManager _pluginManager;
protected ConfigurationManager _configurationManager;
@@ -106,10 +102,8 @@ public abstract class ApplicationRegistry implements IApplicationRegistry
private BrokerConfig _broker;
private ConfigStore _configStore;
-
- private Timer _reportingTimer;
- private boolean _statisticsEnabled = false;
- private StatisticsCounter _messagesDelivered, _dataDelivered, _messagesReceived, _dataReceived;
+
+ protected String _registryName;
static
{
@@ -120,54 +114,53 @@ public abstract class ApplicationRegistry implements IApplicationRegistry
{
public void run()
{
- remove();
+ removeAll();
}
}
public static void initialise(IApplicationRegistry instance) throws Exception
{
- if(instance == null)
- {
- throw new IllegalArgumentException("ApplicationRegistry instance must not be null");
- }
+ initialise(instance, DEFAULT_INSTANCE);
+ }
- if(!_instance.compareAndSet(null, instance))
+ @SuppressWarnings("finally")
+ public static void initialise(IApplicationRegistry instance, int instanceID) throws Exception
+ {
+ if (instance != null)
{
- throw new IllegalStateException("An ApplicationRegistry is already initialised");
- }
-
- _logger.info("Initialising Application Registry(" + instance + ")");
+ _logger.info("Initialising Application Registry(" + instance + "):" + instanceID);
+ _instanceMap.put(instanceID, instance);
+ final ConfigStore store = ConfigStore.newInstance();
+ store.setRoot(new SystemConfigImpl(store));
+ instance.setConfigStore(store);
- final ConfigStore store = ConfigStore.newInstance();
- store.setRoot(new SystemConfigImpl(store));
- instance.setConfigStore(store);
+ BrokerConfig broker = new BrokerConfigAdapter(instance);
- BrokerConfig broker = new BrokerConfigAdapter(instance);
+ SystemConfig system = (SystemConfig) store.getRoot();
+ system.addBroker(broker);
+ instance.setBroker(broker);
- SystemConfig system = (SystemConfig) store.getRoot();
- system.addBroker(broker);
- instance.setBroker(broker);
-
- try
- {
- instance.initialise();
- }
- catch (Exception e)
- {
- _instance.set(null);
-
- //remove the Broker instance, then re-throw
try
{
- system.removeBroker(broker);
+ instance.initialise(instanceID);
}
- catch(Throwable t)
+ catch (Exception e)
{
- //ignore
+ _instanceMap.remove(instanceID);
+ try
+ {
+ system.removeBroker(broker);
+ }
+ finally
+ {
+ throw e;
+ }
}
-
- throw e;
+ }
+ else
+ {
+ remove(instanceID);
}
}
@@ -183,19 +176,35 @@ public abstract class ApplicationRegistry implements IApplicationRegistry
public static boolean isConfigured()
{
- return _instance.get() != null;
+ return isConfigured(DEFAULT_INSTANCE);
+ }
+
+ public static boolean isConfigured(int instanceID)
+ {
+ return _instanceMap.containsKey(instanceID);
}
+ /** Method to cleanly shutdown the default registry running in this JVM */
public static void remove()
{
- IApplicationRegistry instance = _instance.getAndSet(null);
+ remove(DEFAULT_INSTANCE);
+ }
+
+ /**
+ * Method to cleanly shutdown specified registry running in this JVM
+ *
+ * @param instanceID the instance to shutdown
+ */
+ public static void remove(int instanceID)
+ {
try
{
+ IApplicationRegistry instance = _instanceMap.get(instanceID);
if (instance != null)
{
if (_logger.isInfoEnabled())
{
- _logger.info("Shutting down ApplicationRegistry(" + instance + ")");
+ _logger.info("Shutting down ApplicationRegistry(" + instanceID + "):" + instance);
}
instance.close();
instance.getBroker().getSystem().removeBroker(instance.getBroker());
@@ -203,7 +212,21 @@ public abstract class ApplicationRegistry implements IApplicationRegistry
}
catch (Exception e)
{
- _logger.error("Error shutting down Application Registry(" + instance + "): " + e, e);
+ _logger.error("Error shutting down Application Registry(" + instanceID + "): " + e, e);
+ }
+ finally
+ {
+ _instanceMap.remove(instanceID);
+ }
+ }
+
+ /** Method to cleanly shutdown all registries currently running in this JVM */
+ public static void removeAll()
+ {
+ Object[] keys = _instanceMap.keySet().toArray();
+ for (Object k : keys)
+ {
+ remove((Integer) k);
}
}
@@ -228,10 +251,11 @@ public abstract class ApplicationRegistry implements IApplicationRegistry
_configuration.initialise();
}
- public void initialise() throws Exception
+ public void initialise(int instanceID) throws Exception
{
//Create the RootLogger to be used during broker operation
_rootMessageLogger = new Log4jMessageLogger(_configuration);
+ _registryName = String.valueOf(instanceID);
//Create the composite (log4j+SystemOut MessageLogger to be used during startup
RootMessageLogger[] messageLoggers = {new SystemOutMessageLogger(), _rootMessageLogger};
@@ -253,7 +277,11 @@ public abstract class ApplicationRegistry implements IApplicationRegistry
_securityManager = new SecurityManager(_configuration, _pluginManager);
- _authenticationManager = createAuthenticationManager();
+ createDatabaseManager(_configuration);
+
+ _authenticationManager = new PrincipalDatabaseAuthenticationManager(null, null);
+
+ _databaseManager.initialiseManagement(_configuration);
_managedObjectRegistry.start();
}
@@ -266,8 +294,6 @@ public abstract class ApplicationRegistry implements IApplicationRegistry
try
{
initialiseVirtualHosts();
- initialiseStatistics();
- initialiseStatisticsReporting();
}
finally
{
@@ -276,51 +302,9 @@ public abstract class ApplicationRegistry implements IApplicationRegistry
}
}
- /**
- * Iterates across all discovered authentication manager factories, offering the security configuration to each.
- * Expects <b>exactly</b> one authentication manager to configure and initialise itself.
- *
- * It is an error to configure more than one authentication manager, or to configure none.
- *
- * @return authentication manager
- * @throws ConfigurationException
- */
- protected AuthenticationManager createAuthenticationManager() throws ConfigurationException
+ protected void createDatabaseManager(ServerConfiguration configuration) throws Exception
{
- final SecurityConfiguration securityConfiguration = _configuration.getConfiguration(SecurityConfiguration.class.getName());
- final Collection<AuthenticationManagerPluginFactory<? extends Plugin>> factories = _pluginManager.getAuthenticationManagerPlugins().values();
-
- if (factories.size() == 0)
- {
- throw new ConfigurationException("No authentication manager factory plugins found. Check the desired authentication" +
- "manager plugin has been placed in the plugins directory.");
- }
-
- AuthenticationManager authMgr = null;
-
- for (final Iterator<AuthenticationManagerPluginFactory<? extends Plugin>> iterator = factories.iterator(); iterator.hasNext();)
- {
- final AuthenticationManagerPluginFactory<? extends Plugin> factory = (AuthenticationManagerPluginFactory<? extends Plugin>) iterator.next();
- final AuthenticationManager tmp = factory.newInstance(securityConfiguration);
- if (tmp != null)
- {
- if (authMgr != null)
- {
- throw new ConfigurationException("Cannot configure more than one authentication manager."
- + " Both " + tmp.getClass() + " and " + authMgr.getClass() + " are configured."
- + " Remove configuration for one of the authentication manager, or remove the plugin JAR"
- + " from the classpath.");
- }
- authMgr = tmp;
- }
- }
-
- if (authMgr == null)
- {
- throw new ConfigurationException("No authentication managers configured within the configure file.");
- }
-
- return authMgr;
+ _databaseManager = new ConfigurationFilePrincipalDatabaseManager(_configuration);
}
protected void initialiseVirtualHosts() throws Exception
@@ -336,88 +320,26 @@ public abstract class ApplicationRegistry implements IApplicationRegistry
{
_managedObjectRegistry = new NoopManagedObjectRegistry();
}
-
- public void initialiseStatisticsReporting()
- {
- long report = _configuration.getStatisticsReportingPeriod() * 1000; // convert to ms
- final boolean broker = _configuration.isStatisticsGenerationBrokerEnabled();
- final boolean virtualhost = _configuration.isStatisticsGenerationVirtualhostsEnabled();
- final boolean reset = _configuration.isStatisticsReportResetEnabled();
-
- /* add a timer task to report statistics if generation is enabled for broker or virtualhosts */
- if (report > 0L && (broker || virtualhost))
- {
- _reportingTimer = new Timer("Statistics-Reporting", true);
-
- class StatisticsReportingTask extends TimerTask
- {
- private final int DELIVERED = 0;
- private final int RECEIVED = 1;
-
- public void run()
- {
- CurrentActor.set(new AbstractActor(ApplicationRegistry.getInstance().getRootMessageLogger()) {
- public String getLogMessage()
- {
- return "[" + Thread.currentThread().getName() + "] ";
- }
- });
-
- if (broker)
- {
- CurrentActor.get().message(BrokerMessages.STATS_DATA(DELIVERED, _dataDelivered.getPeak() / 1024.0, _dataDelivered.getTotal()));
- CurrentActor.get().message(BrokerMessages.STATS_MSGS(DELIVERED, _messagesDelivered.getPeak(), _messagesDelivered.getTotal()));
- CurrentActor.get().message(BrokerMessages.STATS_DATA(RECEIVED, _dataReceived.getPeak() / 1024.0, _dataReceived.getTotal()));
- CurrentActor.get().message(BrokerMessages.STATS_MSGS(RECEIVED, _messagesReceived.getPeak(), _messagesReceived.getTotal()));
- }
-
- if (virtualhost)
- {
- for (VirtualHost vhost : getVirtualHostRegistry().getVirtualHosts())
- {
- String name = vhost.getName();
- StatisticsCounter dataDelivered = vhost.getDataDeliveryStatistics();
- StatisticsCounter messagesDelivered = vhost.getMessageDeliveryStatistics();
- StatisticsCounter dataReceived = vhost.getDataReceiptStatistics();
- StatisticsCounter messagesReceived = vhost.getMessageReceiptStatistics();
-
- CurrentActor.get().message(VirtualHostMessages.STATS_DATA(name, DELIVERED, dataDelivered.getPeak() / 1024.0, dataDelivered.getTotal()));
- CurrentActor.get().message(VirtualHostMessages.STATS_MSGS(name, DELIVERED, messagesDelivered.getPeak(), messagesDelivered.getTotal()));
- CurrentActor.get().message(VirtualHostMessages.STATS_DATA(name, RECEIVED, dataReceived.getPeak() / 1024.0, dataReceived.getTotal()));
- CurrentActor.get().message(VirtualHostMessages.STATS_MSGS(name, RECEIVED, messagesReceived.getPeak(), messagesReceived.getTotal()));
- }
- }
-
- if (reset)
- {
- resetStatistics();
- }
-
- CurrentActor.remove();
- }
- }
- _reportingTimer.scheduleAtFixedRate(new StatisticsReportingTask(),
- report / 2,
- report);
- }
+ public static IApplicationRegistry getInstance()
+ {
+ return getInstance(DEFAULT_INSTANCE);
}
- /**
- * Get the ApplicationRegistry
- * @return the IApplicationRegistry instance
- * @throws IllegalStateException if no registry instance has been initialised.
- */
- public static IApplicationRegistry getInstance() throws IllegalStateException
+ public static IApplicationRegistry getInstance(int instanceID)
{
- IApplicationRegistry iApplicationRegistry = _instance.get();
- if (iApplicationRegistry == null)
- {
- throw new IllegalStateException("No ApplicationRegistry has been initialised");
- }
- else
+ synchronized (IApplicationRegistry.class)
{
- return iApplicationRegistry;
+ IApplicationRegistry instance = _instanceMap.get(instanceID);
+
+ if (instance == null)
+ {
+ throw new IllegalStateException("Application Registry (" + instanceID + ") not created");
+ }
+ else
+ {
+ return instance;
+ }
}
}
@@ -447,12 +369,6 @@ public abstract class ApplicationRegistry implements IApplicationRegistry
{
_logger.info("Shutting down ApplicationRegistry:" + this);
}
-
- //Stop Statistics Reporting
- if (_reportingTimer != null)
- {
- _reportingTimer.cancel();
- }
//Stop incoming connections
unbind();
@@ -460,6 +376,10 @@ public abstract class ApplicationRegistry implements IApplicationRegistry
//Shutdown virtualhosts
close(_virtualHostRegistry);
+// close(_accessManager);
+//
+// close(_databaseManager);
+
close(_authenticationManager);
close(_managedObjectRegistry);
@@ -481,7 +401,7 @@ public abstract class ApplicationRegistry implements IApplicationRegistry
try
{
- acceptor.getNetworkTransport().close();
+ acceptor.getNetworkDriver().close();
}
catch (Throwable e)
{
@@ -521,6 +441,11 @@ public abstract class ApplicationRegistry implements IApplicationRegistry
return _managedObjectRegistry;
}
+ public PrincipalDatabaseManager getDatabaseManager()
+ {
+ return _databaseManager;
+ }
+
public AuthenticationManager getAuthenticationManager()
{
return _authenticationManager;
@@ -573,76 +498,4 @@ public abstract class ApplicationRegistry implements IApplicationRegistry
getBroker().addVirtualHost(virtualHost);
return virtualHost;
}
-
- public void registerMessageDelivered(long messageSize)
- {
- if (isStatisticsEnabled())
- {
- _messagesDelivered.registerEvent(1L);
- _dataDelivered.registerEvent(messageSize);
- }
- }
-
- public void registerMessageReceived(long messageSize, long timestamp)
- {
- if (isStatisticsEnabled())
- {
- _messagesReceived.registerEvent(1L, timestamp);
- _dataReceived.registerEvent(messageSize, timestamp);
- }
- }
-
- public StatisticsCounter getMessageReceiptStatistics()
- {
- return _messagesReceived;
- }
-
- public StatisticsCounter getDataReceiptStatistics()
- {
- return _dataReceived;
- }
-
- public StatisticsCounter getMessageDeliveryStatistics()
- {
- return _messagesDelivered;
- }
-
- public StatisticsCounter getDataDeliveryStatistics()
- {
- return _dataDelivered;
- }
-
- public void resetStatistics()
- {
- _messagesDelivered.reset();
- _dataDelivered.reset();
- _messagesReceived.reset();
- _dataReceived.reset();
-
- for (VirtualHost vhost : _virtualHostRegistry.getVirtualHosts())
- {
- vhost.resetStatistics();
- }
- }
-
- public void initialiseStatistics()
- {
- setStatisticsEnabled(!StatisticsCounter.DISABLE_STATISTICS &&
- getConfiguration().isStatisticsGenerationBrokerEnabled());
-
- _messagesDelivered = new StatisticsCounter("messages-delivered");
- _dataDelivered = new StatisticsCounter("bytes-delivered");
- _messagesReceived = new StatisticsCounter("messages-received");
- _dataReceived = new StatisticsCounter("bytes-received");
- }
-
- public boolean isStatisticsEnabled()
- {
- return _statisticsEnabled;
- }
-
- public void setStatisticsEnabled(boolean enabled)
- {
- _statisticsEnabled = enabled;
- }
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/registry/BrokerConfigAdapter.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/registry/BrokerConfigAdapter.java
index 108533ef96..4a4253153c 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/registry/BrokerConfigAdapter.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/registry/BrokerConfigAdapter.java
@@ -71,7 +71,7 @@ public class BrokerConfigAdapter implements BrokerConfig
public Integer getWorkerThreads()
{
- return _instance.getConfiguration().getConnectorProcessors();
+ return _instance.getConfiguration().getProcessors();
}
public Integer getMaxConnections()
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 c27e0d19ec..228c3b9112 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
@@ -33,20 +33,21 @@ import org.apache.qpid.server.logging.RootMessageLogger;
import org.apache.qpid.server.management.ManagedObjectRegistry;
import org.apache.qpid.server.plugins.PluginManager;
import org.apache.qpid.server.security.SecurityManager;
+import org.apache.qpid.server.security.auth.database.PrincipalDatabaseManager;
import org.apache.qpid.server.security.auth.manager.AuthenticationManager;
-import org.apache.qpid.server.stats.StatisticsGatherer;
import org.apache.qpid.server.transport.QpidAcceptor;
import org.apache.qpid.server.virtualhost.VirtualHost;
import org.apache.qpid.server.virtualhost.VirtualHostRegistry;
-public interface IApplicationRegistry extends StatisticsGatherer
+public interface IApplicationRegistry
{
/**
* Initialise the application registry. All initialisation must be done in this method so that any components
* that need access to the application registry itself for initialisation are able to use it. Attempting to
* initialise in the constructor will lead to failures since the registry reference will not have been set.
+ * @param instanceID the instanceID that we can use to identify this AR.
*/
- void initialise() throws Exception;
+ void initialise(int instanceID) throws Exception;
/**
* Shutdown this Registry
@@ -62,6 +63,8 @@ public interface IApplicationRegistry extends StatisticsGatherer
ManagedObjectRegistry getManagedObjectRegistry();
+ PrincipalDatabaseManager getDatabaseManager();
+
AuthenticationManager getAuthenticationManager();
VirtualHostRegistry getVirtualHostRegistry();
@@ -94,6 +97,4 @@ public interface IApplicationRegistry extends StatisticsGatherer
ConfigStore getConfigStore();
void setConfigStore(ConfigStore store);
-
- void initialiseStatisticsReporting();
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/AuthorizationHolder.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/AuthorizationHolder.java
deleted file mode 100755
index 3d8c77a86f..0000000000
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/AuthorizationHolder.java
+++ /dev/null
@@ -1,53 +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.security;
-
-import java.security.Principal;
-
-import javax.security.auth.Subject;
-
-import org.apache.qpid.server.security.auth.sasl.GroupPrincipal;
-import org.apache.qpid.server.security.auth.sasl.UsernamePrincipal;
-
-/**
- * Represents the authorization of the logged on user.
- *
- */
-public interface AuthorizationHolder
-{
- /**
- * Returns the {@link Subject} of the authorized user. This is guaranteed to
- * contain at least one {@link UsernamePrincipal}, representing the the identity
- * used when the user logged on to the application, and zero or more {@link GroupPrincipal}
- * representing the group(s) to which the user belongs.
- *
- * @return the Subject
- */
- Subject getAuthorizedSubject();
-
- /**
- * Returns the {@link Principal} representing the the identity
- * used when the user logged on to the application.
- *
- * @return a Principal
- */
- Principal getAuthorizedPrincipal();
-}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/PrincipalHolder.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/PrincipalHolder.java
new file mode 100755
index 0000000000..7e93623cab
--- /dev/null
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/PrincipalHolder.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.security;
+
+import java.security.Principal;
+
+public interface PrincipalHolder
+{
+ /** @return a Principal that was used to authorized this session */
+ Principal getPrincipal();
+}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/SecurityManager.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/SecurityManager.java
index f582fed6a0..f18c327692 100755
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/SecurityManager.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/SecurityManager.java
@@ -18,19 +18,8 @@
*/
package org.apache.qpid.server.security;
-import static org.apache.qpid.server.security.access.ObjectType.EXCHANGE;
-import static org.apache.qpid.server.security.access.ObjectType.METHOD;
-import static org.apache.qpid.server.security.access.ObjectType.OBJECT;
-import static org.apache.qpid.server.security.access.ObjectType.QUEUE;
-import static org.apache.qpid.server.security.access.ObjectType.VIRTUALHOST;
-import static org.apache.qpid.server.security.access.Operation.ACCESS;
-import static org.apache.qpid.server.security.access.Operation.BIND;
-import static org.apache.qpid.server.security.access.Operation.CONSUME;
-import static org.apache.qpid.server.security.access.Operation.CREATE;
-import static org.apache.qpid.server.security.access.Operation.DELETE;
-import static org.apache.qpid.server.security.access.Operation.PUBLISH;
-import static org.apache.qpid.server.security.access.Operation.PURGE;
-import static org.apache.qpid.server.security.access.Operation.UNBIND;
+import static org.apache.qpid.server.security.access.ObjectType.*;
+import static org.apache.qpid.server.security.access.Operation.*;
import java.net.SocketAddress;
import java.security.Principal;
@@ -40,8 +29,6 @@ import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
-import javax.security.auth.Subject;
-
import org.apache.commons.configuration.Configuration;
import org.apache.commons.configuration.ConfigurationException;
import org.apache.log4j.Logger;
@@ -50,9 +37,11 @@ import org.apache.qpid.server.configuration.plugins.ConfigurationPlugin;
import org.apache.qpid.server.configuration.plugins.ConfigurationPluginFactory;
import org.apache.qpid.server.exchange.Exchange;
import org.apache.qpid.server.plugins.PluginManager;
+import org.apache.qpid.server.protocol.AMQProtocolSession;
import org.apache.qpid.server.queue.AMQQueue;
import org.apache.qpid.server.security.access.ObjectProperties;
import org.apache.qpid.server.security.access.Operation;
+import org.apache.qpid.server.security.auth.sasl.UsernamePrincipal;
/**
* The security manager contains references to all loaded {@link SecurityPlugin}s and delegates security decisions to them based
@@ -66,7 +55,7 @@ public class SecurityManager
private static final Logger _logger = Logger.getLogger(SecurityManager.class);
/** Container for the {@link Principal} that is using to this thread. */
- private static final ThreadLocal<Subject> _subject = new ThreadLocal<Subject>();
+ private static final ThreadLocal<Principal> _principal = new ThreadLocal<Principal>();
private PluginManager _pluginManager;
private Map<String, SecurityPluginFactory> _pluginFactories = new HashMap<String, SecurityPluginFactory>();
@@ -137,14 +126,19 @@ public class SecurityManager
configureHostPlugins(configuration);
}
- public static Subject getThreadSubject()
+ public static Principal getThreadPrincipal()
+ {
+ return _principal.get();
+ }
+
+ public static void setThreadPrincipal(Principal principal)
{
- return _subject.get();
+ _principal.set(principal);
}
- public static void setThreadSubject(final Subject subject)
+ public static void setThreadPrincipal(String authId)
{
- _subject.set(subject);
+ setThreadPrincipal(new UsernamePrincipal(authId));
}
public void configureHostPlugins(ConfigurationPlugin hostConfig) throws ConfigurationException
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/ObjectProperties.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/ObjectProperties.java
index e4bf8df340..70a9ea5356 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/ObjectProperties.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/ObjectProperties.java
@@ -149,9 +149,9 @@ public class ObjectProperties extends HashMap<ObjectProperties.Property, String>
{
put(Property.OWNER, queue.getOwner());
}
- else if (queue.getAuthorizationHolder() != null)
+ else if (queue.getPrincipalHolder() != null)
{
- put(Property.OWNER, queue.getAuthorizationHolder().getAuthorizedPrincipal().getName());
+ put(Property.OWNER, queue.getPrincipalHolder().getPrincipal().getName());
}
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/AuthenticationResult.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/AuthenticationResult.java
index 8c2d60a660..62967ef7eb 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/AuthenticationResult.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/AuthenticationResult.java
@@ -20,93 +20,42 @@
*/
package org.apache.qpid.server.security.auth;
-import javax.security.auth.Subject;
-
-/**
- * Encapsulates the result of an attempt to authenticate.
- * <p>
- * The authentication status describes the overall outcome.
- * <p>
- * <ol>
- * <li>If authentication status is SUCCESS, the subject will be populated.
- * </li>
- * <li>If authentication status is CONTINUE, the authentication has failed because the user
- * supplied incorrect credentials (etc). If the authentication requires it, the next challenge
- * is made available.
- * </li>
- * <li>If authentication status is ERROR , the authentication decision could not be made due
- * to a failure (such as an external system), the {@link AuthenticationResult#getCause()}
- * will provide the underlying exception.
- * </li>
- * </ol>
- *
- */
public class AuthenticationResult
{
public enum AuthenticationStatus
{
- /** Authentication successful */
- SUCCESS,
- /** Authentication not successful due to credentials problem etc */
- CONTINUE,
- /** Problem prevented the authentication from being made e.g. failure of an external system */
- ERROR
+ SUCCESS, CONTINUE, ERROR
}
- public final AuthenticationStatus _status;
- public final byte[] _challenge;
- private final Exception _cause;
- private final Subject _subject;
+ public AuthenticationStatus status;
+ public byte[] challenge;
+
+ private Exception cause;
- public AuthenticationResult(final AuthenticationStatus status)
+ public AuthenticationResult(AuthenticationStatus status)
{
this(null, status, null);
}
- public AuthenticationResult(final byte[] challenge, final AuthenticationStatus status)
+ public AuthenticationResult(byte[] challenge, AuthenticationStatus status)
{
this(challenge, status, null);
}
- public AuthenticationResult(final AuthenticationStatus error, final Exception cause)
+ public AuthenticationResult(AuthenticationStatus error, Exception cause)
{
this(null, error, cause);
}
- public AuthenticationResult(final byte[] challenge, final AuthenticationStatus status, final Exception cause)
- {
- this._status = status;
- this._challenge = challenge;
- this._cause = cause;
- this._subject = null;
- }
-
- public AuthenticationResult(final Subject subject)
+ public AuthenticationResult(byte[] challenge, AuthenticationStatus status, Exception cause)
{
- this._status = AuthenticationStatus.SUCCESS;
- this._challenge = null;
- this._cause = null;
- this._subject = subject;
+ this.status = status;
+ this.challenge = challenge;
+ this.cause = cause;
}
public Exception getCause()
{
- return _cause;
- }
-
- public AuthenticationStatus getStatus()
- {
- return _status;
- }
-
- public byte[] getChallenge()
- {
- return _challenge;
+ return cause;
}
-
- public Subject getSubject()
- {
- return _subject;
- }
-
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/ConfigurationFilePrincipalDatabaseManager.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/ConfigurationFilePrincipalDatabaseManager.java
new file mode 100644
index 0000000000..5cebb7d2d8
--- /dev/null
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/ConfigurationFilePrincipalDatabaseManager.java
@@ -0,0 +1,221 @@
+/*
+ *
+ * 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 java.io.FileNotFoundException;
+import java.io.IOException;
+import java.lang.reflect.Method;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.commons.configuration.Configuration;
+import org.apache.commons.configuration.ConfigurationException;
+
+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;
+import org.apache.qpid.server.security.auth.management.AMQUserManagementMBean;
+import org.apache.qpid.AMQException;
+
+import javax.management.JMException;
+
+public class ConfigurationFilePrincipalDatabaseManager implements PrincipalDatabaseManager
+{
+ private static final Logger _logger = Logger.getLogger(ConfigurationFilePrincipalDatabaseManager.class);
+
+ Map<String, PrincipalDatabase> _databases;
+
+ public ConfigurationFilePrincipalDatabaseManager(ServerConfiguration _configuration) throws Exception
+ {
+ _logger.info("Initialising PrincipalDatabase authentication manager");
+ _databases = initialisePrincipalDatabases(_configuration);
+ }
+
+ private Map<String, PrincipalDatabase> initialisePrincipalDatabases(ServerConfiguration _configuration) throws Exception
+ {
+ List<String> databaseNames = _configuration.getPrincipalDatabaseNames();
+ List<String> databaseClasses = _configuration.getPrincipalDatabaseClass();
+ Map<String, PrincipalDatabase> databases = new HashMap<String, PrincipalDatabase>();
+
+ if (databaseNames.size() == 0)
+ {
+ _logger.warn("No Principal databases specified. Broker running with NO AUTHENTICATION");
+ }
+
+ for (int i = 0; i < databaseNames.size(); i++)
+ {
+ Object o;
+ try
+ {
+ o = Class.forName(databaseClasses.get(i)).newInstance();
+ }
+ catch (Exception e)
+ {
+ throw new Exception("Error initialising principal database: " + e, e);
+ }
+
+ if (!(o instanceof PrincipalDatabase))
+ {
+ throw new Exception("Principal databases must implement the PrincipalDatabase interface");
+ }
+
+ initialisePrincipalDatabase((PrincipalDatabase) o, _configuration, i);
+
+ String name = databaseNames.get(i);
+ if ((name == null) || (name.length() == 0))
+ {
+ throw new Exception("Principal database names must have length greater than or equal to one character");
+ }
+
+ PrincipalDatabase pd = databases.get(name);
+ if (pd != null)
+ {
+ throw new Exception("Duplicate principal database name not permitted");
+ }
+
+ _logger.info("Initialised principal database '" + name + "' successfully");
+ databases.put(name, (PrincipalDatabase) o);
+ }
+
+ return databases;
+ }
+
+ private void initialisePrincipalDatabase(PrincipalDatabase principalDatabase, ServerConfiguration _configuration, int index)
+ throws FileNotFoundException, ConfigurationException
+ {
+ 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);
+ if ((argName == null) || (argName.length() == 0))
+ {
+ throw new ConfigurationException("Argument names must have length >= 1 character");
+ }
+
+ if (Character.isLowerCase(argName.charAt(0)))
+ {
+ argName = Character.toUpperCase(argName.charAt(0)) + argName.substring(1);
+ }
+
+ String methodName = "set" + argName;
+ Method method = null;
+ try
+ {
+ method = principalDatabase.getClass().getMethod(methodName, String.class);
+ }
+ catch (Exception e)
+ {
+ // do nothing.. as on error method will be null
+ }
+
+ if (method == null)
+ {
+ throw new ConfigurationException("No method " + methodName + " found in class "
+ + principalDatabase.getClass()
+ + " hence unable to configure principal database. The method must be public and "
+ + "have a single String argument with a void return type");
+ }
+
+ try
+ {
+ method.invoke(principalDatabase, PropertyUtils.replaceProperties(argumentValues.get(i)));
+ }
+ catch (Exception ite)
+ {
+ if (ite instanceof ConfigurationException)
+ {
+ throw(ConfigurationException) ite;
+ }
+ else
+ {
+ throw new ConfigurationException(ite.getMessage(), ite);
+ }
+ }
+ }
+ }
+
+ public Map<String, PrincipalDatabase> getDatabases()
+ {
+ return _databases;
+ }
+
+ public void initialiseManagement(ServerConfiguration config) throws ConfigurationException
+ {
+ try
+ {
+ AMQUserManagementMBean _mbean = new AMQUserManagementMBean();
+
+ List<String> principalDBs = config.getManagementPrincipalDBs();
+ if (principalDBs.isEmpty())
+ {
+ throw new ConfigurationException("No principal-database specified for jmx security");
+ }
+
+ String databaseName = principalDBs.get(0);
+ PrincipalDatabase database = getDatabases().get(databaseName);
+ if (database == null)
+ {
+ throw new ConfigurationException("Principal-database '" + databaseName + "' not found");
+ }
+
+ _mbean.setPrincipalDatabase(database);
+
+ List<String> jmxaccesslist = config.getManagementAccessList();
+ if (jmxaccesslist.isEmpty())
+ {
+ throw new ConfigurationException("No access control files specified for jmx security");
+ }
+
+ String jmxaccesssFile = null;
+
+ try
+ {
+ jmxaccesssFile = PropertyUtils.replaceProperties(jmxaccesslist.get(0));
+ }
+ catch (PropertyException e)
+ {
+ throw new ConfigurationException("Unable to parse access control filename '" + jmxaccesssFile + "'");
+ }
+
+ try
+ {
+ _mbean.setAccessFile(jmxaccesssFile);
+ }
+ catch (IOException e)
+ {
+ _logger.warn("Unable to load access file:" + jmxaccesssFile);
+ }
+
+ _mbean.register();
+ }
+ catch (JMException e)
+ {
+ _logger.warn("User management disabled as unable to create MBean:" + e);
+ }
+ }
+}
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
new file mode 100644
index 0000000000..f9882f8810
--- /dev/null
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PrincipalDatabaseManager.java
@@ -0,0 +1,35 @@
+/*
+ * 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.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;
+
+import java.util.Map;
+
+public interface PrincipalDatabaseManager
+{
+ public Map<String, PrincipalDatabase> getDatabases();
+
+ 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
new file mode 100644
index 0000000000..8658101cd8
--- /dev/null
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PropertiesPrincipalDatabaseManager.java
@@ -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.
+ *
+ *
+ */
+package org.apache.qpid.server.security.auth.database;
+
+import org.apache.commons.configuration.ConfigurationException;
+import org.apache.qpid.server.configuration.ServerConfiguration;
+
+import java.util.Map;
+import java.util.Properties;
+import java.util.HashMap;
+
+public class PropertiesPrincipalDatabaseManager implements PrincipalDatabaseManager
+{
+
+ Map<String, PrincipalDatabase> _databases = new HashMap<String, PrincipalDatabase>();
+
+ public PropertiesPrincipalDatabaseManager(String name, Properties users)
+ {
+ _databases.put(name, new PropertiesPrincipalDatabase(users));
+ }
+
+ public Map<String, PrincipalDatabase> getDatabases()
+ {
+ return _databases;
+ }
+
+ public void initialiseManagement(ServerConfiguration _configuration) throws ConfigurationException
+ {
+ //todo
+ }
+}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/management/AMQUserManagementMBean.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/management/AMQUserManagementMBean.java
index 208130379e..ee4336055b 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/management/AMQUserManagementMBean.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/management/AMQUserManagementMBean.java
@@ -20,9 +20,19 @@
*/
package org.apache.qpid.server.security.auth.management;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
import java.io.IOException;
+import java.security.AccessControlContext;
+import java.security.AccessController;
import java.security.Principal;
+import java.util.Enumeration;
import java.util.List;
+import java.util.Properties;
+import java.util.Random;
+import java.util.Set;
+import java.util.concurrent.locks.ReentrantLock;
import javax.management.JMException;
import javax.management.openmbean.CompositeData;
@@ -34,13 +44,17 @@ import javax.management.openmbean.SimpleType;
import javax.management.openmbean.TabularData;
import javax.management.openmbean.TabularDataSupport;
import javax.management.openmbean.TabularType;
+import javax.management.remote.JMXPrincipal;
+import javax.security.auth.Subject;
import javax.security.auth.login.AccountNotFoundException;
+import org.apache.commons.configuration.ConfigurationException;
import org.apache.log4j.Logger;
import org.apache.qpid.management.common.mbeans.UserManagement;
import org.apache.qpid.management.common.mbeans.annotations.MBeanDescription;
import org.apache.qpid.management.common.mbeans.annotations.MBeanOperation;
import org.apache.qpid.server.management.AMQManagedObject;
+import org.apache.qpid.server.management.MBeanInvocationHandlerImpl;
import org.apache.qpid.server.security.auth.database.PrincipalDatabase;
import org.apache.qpid.server.security.auth.sasl.UsernamePrincipal;
@@ -51,18 +65,22 @@ public class AMQUserManagementMBean extends AMQManagedObject implements UserMana
private static final Logger _logger = Logger.getLogger(AMQUserManagementMBean.class);
private PrincipalDatabase _principalDatabase;
+ private Properties _accessRights;
+ private File _accessFile;
+
+ private ReentrantLock _accessRightsUpdate = new ReentrantLock();
// Setup for the TabularType
- private static final TabularType _userlistDataType; // Datatype for representing User Lists
- private static final CompositeType _userDataType; // Composite type for representing User
+ static TabularType _userlistDataType; // Datatype for representing User Lists
+ static CompositeType _userDataType; // Composite type for representing User
static
{
OpenType[] userItemTypes = new OpenType[4]; // User item types.
userItemTypes[0] = SimpleType.STRING; // For Username
- userItemTypes[1] = SimpleType.BOOLEAN; // For Rights - Read - No longer in use
- userItemTypes[2] = SimpleType.BOOLEAN; // For Rights - Write - No longer in use
- userItemTypes[3] = SimpleType.BOOLEAN; // For Rights - Admin - No longer is use
+ userItemTypes[1] = SimpleType.BOOLEAN; // For Rights - Read
+ userItemTypes[2] = SimpleType.BOOLEAN; // For Rights - Write
+ userItemTypes[3] = SimpleType.BOOLEAN; // For Rights - Admin
try
{
@@ -74,11 +92,12 @@ public class AMQUserManagementMBean extends AMQManagedObject implements UserMana
}
catch (OpenDataException e)
{
- _logger.error("Tabular data setup for viewing users incorrect.", e);
- throw new ExceptionInInitializerError("Tabular data setup for viewing users incorrect");
+ _logger.error("Tabular data setup for viewing users incorrect.");
+ _userlistDataType = null;
}
}
+
public AMQUserManagementMBean() throws JMException
{
super(UserManagement.class, UserManagement.TYPE);
@@ -91,23 +110,121 @@ public class AMQUserManagementMBean extends AMQManagedObject implements UserMana
public boolean setPassword(String username, String password)
{
+ return setPassword(username, password.toCharArray());
+ }
+
+ public boolean setPassword(String username, char[] password)
+ {
try
{
//delegate password changes to the Principal Database
- return _principalDatabase.updatePassword(new UsernamePrincipal(username), password.toCharArray());
+ return _principalDatabase.updatePassword(new UsernamePrincipal(username), password);
}
catch (AccountNotFoundException e)
{
- _logger.warn("Attempt to set password of non-existent user'" + username + "'");
+ _logger.warn("Attempt to set password of non-existant user'" + username + "'");
return false;
}
}
- public boolean createUser(String username, String password)
+ public boolean setRights(String username, boolean read, boolean write, boolean admin)
{
- if (_principalDatabase.createPrincipal(new UsernamePrincipal(username), password.toCharArray()))
+
+ Object oldRights = null;
+ if ((oldRights =_accessRights.get(username)) == null)
{
- return true;
+ // 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;
+ }
+ }
+
+ try
+ {
+ _accessRightsUpdate.lock();
+
+ // Update the access rights
+ if (admin)
+ {
+ _accessRights.put(username, MBeanInvocationHandlerImpl.ADMIN);
+ }
+ else
+ {
+ if (read | write)
+ {
+ if (read)
+ {
+ _accessRights.put(username, MBeanInvocationHandlerImpl.READONLY);
+ }
+ if (write)
+ {
+ _accessRights.put(username, MBeanInvocationHandlerImpl.READWRITE);
+ }
+ }
+ else
+ {
+ _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);
+
+ //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
+ {
+ _accessRightsUpdate.unlock();
+ }
+
+ return true;
+ }
+
+ public boolean createUser(String username, String password, boolean read, boolean write, boolean admin)
+ {
+ return createUser(username, password.toCharArray(), read, write, admin);
+ }
+
+ public boolean createUser(String username, char[] password, boolean read, boolean write, boolean admin)
+ {
+ if (_principalDatabase.createPrincipal(new UsernamePrincipal(username), password))
+ {
+ 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;
@@ -117,7 +234,29 @@ public class AMQUserManagementMBean extends AMQManagedObject implements UserMana
{
try
{
- _principalDatabase.deletePrincipal(new UsernamePrincipal(username));
+ if (_principalDatabase.deletePrincipal(new UsernamePrincipal(username)))
+ {
+ try
+ {
+ _accessRightsUpdate.lock();
+
+ _accessRights.remove(username);
+
+ try
+ {
+ saveAccessFile();
+ }
+ catch (IOException e)
+ {
+ _logger.warn("Problem occured saving '" + _accessFile + "', the access right changes will not be preserved: " + e);
+ return false;
+ }
+ }
+ finally
+ {
+ _accessRightsUpdate.unlock();
+ }
+ }
}
catch (AccountNotFoundException e)
{
@@ -130,23 +269,38 @@ public class AMQUserManagementMBean extends AMQManagedObject implements UserMana
public boolean reloadData()
{
- try
- {
- _principalDatabase.reload();
- }
- catch (IOException e)
- {
- _logger.warn("Reload failed due to:", e);
- return false;
- }
- // Reload successful
- return true;
+ try
+ {
+ loadAccessFile();
+ _principalDatabase.reload();
+ }
+ catch (ConfigurationException e)
+ {
+ _logger.warn("Reload failed due to:" + e);
+ return false;
+ }
+ catch (IOException e)
+ {
+ _logger.warn("Reload failed due to:" + e);
+ return false;
+ }
+ // Reload successful
+ return true;
}
- @MBeanOperation(name = "viewUsers", description = "All users that are currently available to the system.")
+ @MBeanOperation(name = "viewUsers", description = "All users with access rights to the system.")
public TabularData viewUsers()
{
+ // Table of users
+ // Username(string), Access rights Read,Write,Admin(bool,bool,bool)
+
+ if (_userlistDataType == null)
+ {
+ _logger.warn("TabluarData not setup correctly");
+ return null;
+ }
+
List<Principal> users = _principalDatabase.getUsers();
TabularDataSupport userList = new TabularDataSupport(_userlistDataType);
@@ -157,15 +311,29 @@ public class AMQUserManagementMBean extends AMQManagedObject implements UserMana
for (Principal user : users)
{
// Create header attributes list
- // Read,Write,Admin items are depcreated and we return always false.
- Object[] itemData = {user.getName(), false, false, false};
+
+ String rights = (String) _accessRights.get(user.getName());
+
+ Boolean read = false;
+ Boolean write = false;
+ Boolean admin = false;
+
+ if (rights != null)
+ {
+ read = rights.equals(MBeanInvocationHandlerImpl.READONLY)
+ || rights.equals(MBeanInvocationHandlerImpl.READWRITE);
+ write = rights.equals(MBeanInvocationHandlerImpl.READWRITE);
+ admin = rights.equals(MBeanInvocationHandlerImpl.ADMIN);
+ }
+
+ Object[] itemData = {user.getName(), read, write, admin};
CompositeData messageData = new CompositeDataSupport(_userDataType, COMPOSITE_ITEM_NAMES.toArray(new String[COMPOSITE_ITEM_NAMES.size()]), itemData);
userList.put(messageData);
}
}
catch (OpenDataException e)
{
- _logger.warn("Unable to create user list due to :", e);
+ _logger.warn("Unable to create user list due to :" + e);
return null;
}
@@ -183,4 +351,187 @@ public class AMQUserManagementMBean extends AMQManagedObject implements UserMana
{
_principalDatabase = database;
}
+
+ /**
+ * setAccessFile
+ *
+ * @param accessFile the file to use for updating.
+ *
+ * @throws java.io.IOException If the file cannot be accessed
+ * @throws org.apache.commons.configuration.ConfigurationException
+ * if checks on the file fail.
+ */
+ public void setAccessFile(String accessFile) throws IOException, ConfigurationException
+ {
+ 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
+ {
+ _logger.warn("Access rights file specified is null. Access rights not changed.");
+ }
+ }
+
+ private void loadAccessFile() throws IOException, ConfigurationException
+ {
+ if(_accessFile == null)
+ {
+ _logger.error("No jmx access rights file has been specified.");
+ return;
+ }
+
+ if(_accessFile.exists())
+ {
+ try
+ {
+ _accessRightsUpdate.lock();
+
+ Properties accessRights = new Properties();
+ FileInputStream inStream = new FileInputStream(_accessFile);
+ try
+ {
+ accessRights.load(inStream);
+ }
+ finally
+ {
+ inStream.close();
+ }
+
+ checkAccessRights(accessRights);
+ setAccessRights(accessRights);
+ }
+ finally
+ {
+ _accessRightsUpdate.unlock();
+ }
+ }
+ else
+ {
+ _logger.error("Specified jmxaccess rights file '" + _accessFile + "' does not exist.");
+ }
+ }
+
+ private void checkAccessRights(Properties accessRights)
+ {
+ Enumeration values = accessRights.propertyNames();
+
+ while (values.hasMoreElements())
+ {
+ String user = (String) values.nextElement();
+
+ if (_principalDatabase.getUser(user) == null)
+ {
+ _logger.warn("Access rights contains user '" + user + "' but there is no authentication data for that user");
+ }
+ }
+ }
+
+ private void saveAccessFile() throws IOException
+ {
+ try
+ {
+ _accessRightsUpdate.lock();
+
+ // Create temporary file
+ Random r = new Random();
+ File tmp;
+ do
+ {
+ tmp = new File(_accessFile.getPath() + r.nextInt() + ".tmp");
+ }
+ while(tmp.exists());
+
+ tmp.deleteOnExit();
+
+ FileOutputStream output = new FileOutputStream(tmp);
+ _accessRights.store(output, "Generated by AMQUserManagementMBean Console : Last edited by user:" + getCurrentJMXUser());
+ output.close();
+
+ // Swap temp file to main rights file.
+ File old = new File(_accessFile.getAbsoluteFile() + ".old");
+ if (old.exists())
+ {
+ old.delete();
+ }
+
+ if(!_accessFile.renameTo(old))
+ {
+ //unable to rename the existing file to the backup name
+ _logger.error("Could not backup the existing management rights file");
+ throw new IOException("Could not backup the existing management rights file");
+ }
+
+ if(!tmp.renameTo(_accessFile))
+ {
+ //failed to rename the new file to the required filename
+
+ if(!old.renameTo(_accessFile))
+ {
+ //unable to return the backup to required filename
+ _logger.error("Could not rename the new management rights file into place, and unable to restore original file");
+ throw new IOException("Could not rename the new management rights file into place, and unable to restore original file");
+ }
+
+ _logger.error("Could not rename the new management rights file into place");
+ throw new IOException("Could not rename the new management rights file into place");
+ }
+ }
+ finally
+ {
+ _accessRightsUpdate.unlock();
+ }
+
+ }
+
+ private String getCurrentJMXUser()
+ {
+ AccessControlContext acc = AccessController.getContext();
+
+ Subject subject = Subject.getSubject(acc);
+ if (subject == null)
+ {
+ return "Unknown user, authentication Subject was null";
+ }
+
+ // Retrieve JMXPrincipal from Subject
+ Set<JMXPrincipal> principals = subject.getPrincipals(JMXPrincipal.class);
+ if (principals == null || principals.isEmpty())
+ {
+ return "Unknown user principals were null";
+ }
+
+ Principal principal = principals.iterator().next();
+ return principal.getName();
+ }
+
+ /**
+ * user=read user=write user=readwrite user=admin
+ *
+ * @param accessRights The properties list of access rights to process
+ */
+ private void setAccessRights(Properties accessRights)
+ {
+ _logger.debug("Setting Access Rights:" + accessRights);
+ _accessRights = accessRights;
+
+ // TODO check where this is used
+ // MBeanInvocationHandlerImpl.setAccessRights(_accessRights);
+ }
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/AuthenticationManager.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/AuthenticationManager.java
index 4c59c25d84..bc771162fd 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/AuthenticationManager.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/AuthenticationManager.java
@@ -20,73 +20,17 @@
*/
package org.apache.qpid.server.security.auth.manager;
-import javax.security.auth.Subject;
import javax.security.sasl.SaslException;
import javax.security.sasl.SaslServer;
import org.apache.qpid.common.Closeable;
-import org.apache.qpid.server.plugins.Plugin;
import org.apache.qpid.server.security.auth.AuthenticationResult;
-/**
- * Implementations of the AuthenticationManager are responsible for determining
- * the authenticity of a user's credentials.
- *
- * If the authentication is successful, the manager is responsible for producing a populated
- * {@link Subject} containing the user's identity and zero or more principals representing
- * groups to which the user belongs.
- * <p>
- * The {@link #initialise()} method is responsible for registering SASL mechanisms required by
- * the manager. The {@link #close()} method must reverse this registration.
- *
- */
-public interface AuthenticationManager extends Closeable, Plugin
+public interface AuthenticationManager extends Closeable
{
- /** The name for the required SASL Server mechanisms */
- public static final String PROVIDER_NAME= "AMQSASLProvider-Server";
-
- /**
- * Initialise the authentication plugin.
- *
- */
- void initialise();
-
- /**
- * Gets the SASL mechanisms known to this manager.
- *
- * @return SASL mechanism names, space separated.
- */
String getMechanisms();
- /**
- * Creates a SASL server for the specified mechanism name for the given
- * fully qualified domain name.
- *
- * @param mechanism mechanism name
- * @param localFQDN domain name
- *
- * @return SASL server
- * @throws SaslException
- */
SaslServer createSaslServer(String mechanism, String localFQDN) throws SaslException;
- /**
- * Authenticates a user using SASL negotiation.
- *
- * @param server SASL server
- * @param response SASL response to process
- *
- * @return authentication result
- */
AuthenticationResult authenticate(SaslServer server, byte[] response);
-
- /**
- * Authenticates a user using their username and password.
- *
- * @param username username
- * @param password password
- *
- * @return authentication result
- */
- AuthenticationResult authenticate(String username, String password);
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/AuthenticationManagerPluginFactory.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/AuthenticationManagerPluginFactory.java
deleted file mode 100644
index a51f195761..0000000000
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/AuthenticationManagerPluginFactory.java
+++ /dev/null
@@ -1,32 +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.security.auth.manager;
-
-import org.apache.qpid.server.plugins.PluginFactory;
-
-/**
- * Factory producing authentication producing configured, initialised authentication
- * managers.
- */
-public interface AuthenticationManagerPluginFactory<S extends AuthenticationManager> extends PluginFactory<S>
-{
-
-}
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 1945c2e15f..2a967f02af 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
@@ -20,65 +20,27 @@
*/
package org.apache.qpid.server.security.auth.manager;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.security.Security;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.TreeMap;
-
-import javax.security.auth.Subject;
-import javax.security.auth.callback.CallbackHandler;
-import javax.security.auth.login.AccountNotFoundException;
-import javax.security.sasl.Sasl;
-import javax.security.sasl.SaslException;
-import javax.security.sasl.SaslServer;
-import javax.security.sasl.SaslServerFactory;
-
+import org.apache.log4j.Logger;
import org.apache.commons.configuration.Configuration;
import org.apache.commons.configuration.ConfigurationException;
-import org.apache.log4j.Logger;
-import org.apache.qpid.configuration.PropertyException;
-import org.apache.qpid.configuration.PropertyUtils;
-import org.apache.qpid.server.configuration.plugins.ConfigurationPlugin;
-import org.apache.qpid.server.configuration.plugins.ConfigurationPluginFactory;
-import org.apache.qpid.server.security.auth.AuthenticationResult;
-import org.apache.qpid.server.security.auth.AuthenticationResult.AuthenticationStatus;
+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;
-import org.apache.qpid.server.security.auth.management.AMQUserManagementMBean;
-import org.apache.qpid.server.security.auth.sasl.AuthenticationProviderInitialiser;
import org.apache.qpid.server.security.auth.sasl.JCAProvider;
-import org.apache.qpid.server.security.auth.sasl.UsernamePrincipal;
+import org.apache.qpid.server.security.auth.sasl.AuthenticationProviderInitialiser;
+import org.apache.qpid.server.security.auth.AuthenticationResult;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.sasl.SaslServerFactory;
+import javax.security.sasl.SaslServer;
+import javax.security.sasl.SaslException;
+import javax.security.sasl.Sasl;
+import java.util.Map;
+import java.util.HashMap;
+import java.util.TreeMap;
+import java.security.Security;
-/**
- * Concrete implementation of the AuthenticationManager that determines if supplied
- * user credentials match those appearing in a PrincipalDatabase. The implementation
- * of the PrincipalDatabase is determined from the configuration.
- *
- * This implementation also registers the JMX UserManagemement MBean.
- *
- * This plugin expects configuration such as:
- *
- * <pre>
- * &lt;pd-auth-manager&gt;
- * &lt;principal-database&gt;
- * &lt;class&gt;org.apache.qpid.server.security.auth.database.PlainPasswordFilePrincipalDatabase&lt;/class&gt;
- * &lt;attributes&gt;
- * &lt;attribute&gt;
- * &lt;name>passwordFile&lt;/name&gt;
- * &lt;value>${conf}/passwd&lt;/value&gt;
- * &lt;/attribute&gt;
- * &lt;/attributes&gt;
- * &lt;/principal-database&gt;
- * &lt;/pd-auth-manager&gt;
- * </pre>
- */
public class PrincipalDatabaseAuthenticationManager implements AuthenticationManager
{
private static final Logger _logger = Logger.getLogger(PrincipalDatabaseAuthenticationManager.class);
@@ -87,109 +49,55 @@ public class PrincipalDatabaseAuthenticationManager implements AuthenticationMan
private String _mechanisms;
/** Maps from the mechanism to the callback handler to use for handling those requests */
- private final Map<String, CallbackHandler> _callbackHandlerMap = new HashMap<String, CallbackHandler>();
+ private Map<String, CallbackHandler> _callbackHandlerMap = new HashMap<String, CallbackHandler>();
/**
* 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.
*/
- private final Map<String, Map<String, ?>> _serverCreationProperties = new HashMap<String, Map<String, ?>>();
-
- protected PrincipalDatabase _principalDatabase = null;
+ private Map<String, Map<String, ?>> _serverCreationProperties = new HashMap<String, Map<String, ?>>();
- protected AMQUserManagementMBean _mbean = null;
+ private AuthenticationManager _default = null;
+ /** The name for the required SASL Server mechanisms */
+ public static final String PROVIDER_NAME= "AMQSASLProvider-Server";
- public static final AuthenticationManagerPluginFactory<PrincipalDatabaseAuthenticationManager> FACTORY = new AuthenticationManagerPluginFactory<PrincipalDatabaseAuthenticationManager>()
+ public PrincipalDatabaseAuthenticationManager(String name, VirtualHostConfiguration hostConfig) throws Exception
{
- public PrincipalDatabaseAuthenticationManager newInstance(final ConfigurationPlugin config) throws ConfigurationException
- {
- final PrincipalDatabaseAuthenticationManagerConfiguration configuration = config.getConfiguration(PrincipalDatabaseAuthenticationManagerConfiguration.class.getName());
+ _logger.info("Initialising " + (name == null ? "Default" : "'" + name + "'")
+ + " PrincipalDatabase authentication manager.");
- // If there is no configuration for this plugin then don't load it.
- if (configuration == null)
- {
- _logger.info("No authentication-manager configuration found for PrincipalDatabaseAuthenticationManager");
- return null;
- }
+ // Fixme This should be done per Vhost but allowing global hack isn't right but ...
+ // required as authentication is done before Vhost selection
- final PrincipalDatabaseAuthenticationManager pdam = new PrincipalDatabaseAuthenticationManager();
- pdam.configure(configuration);
- pdam.initialise();
- return pdam;
- }
+ Map<String, Class<? extends SaslServerFactory>> providerMap = new TreeMap<String, Class<? extends SaslServerFactory>>();
- public Class<PrincipalDatabaseAuthenticationManager> getPluginClass()
- {
- return PrincipalDatabaseAuthenticationManager.class;
- }
- public String getPluginName()
+ if (name == null || hostConfig == null)
{
- return PrincipalDatabaseAuthenticationManager.class.getName();
+ initialiseAuthenticationMechanisms(providerMap, ApplicationRegistry.getInstance().getDatabaseManager().getDatabases());
}
- };
-
- public static class PrincipalDatabaseAuthenticationManagerConfiguration extends ConfigurationPlugin {
-
- public static final ConfigurationPluginFactory FACTORY = new ConfigurationPluginFactory()
+ else
{
- public List<String> getParentPaths()
- {
- return Arrays.asList("security.pd-auth-manager");
- }
+ String databaseName = hostConfig.getAuthenticationDatabase();
- public ConfigurationPlugin newInstance(final String path, final Configuration config) throws ConfigurationException
+ if (databaseName == null)
{
- final ConfigurationPlugin instance = new PrincipalDatabaseAuthenticationManagerConfiguration();
-
- instance.setConfiguration(path, config);
- return instance;
- }
- };
- public String[] getElementsProcessed()
- {
- return new String[] {"principal-database.class",
- "principal-database.attributes.attribute.name",
- "principal-database.attributes.attribute.value"};
- }
-
- public void validateConfiguration() throws ConfigurationException
- {
- }
-
- public String getPrincipalDatabaseClass()
- {
- return _configuration.getString("principal-database.class");
- }
-
- public Map<String,String> getPdClassAttributeMap() throws ConfigurationException
- {
- final List<String> argumentNames = _configuration.getList("principal-database.attributes.attribute.name");
- final List<String> argumentValues = _configuration.getList("principal-database.attributes.attribute.value");
- final Map<String,String> attributes = new HashMap<String,String>(argumentNames.size());
-
- for (int i = 0; i < argumentNames.size(); i++)
+ _default = ApplicationRegistry.getInstance().getAuthenticationManager();
+ return;
+ }
+ else
{
- final String argName = argumentNames.get(i);
- final String argValue = argumentValues.get(i);
+ PrincipalDatabase database = ApplicationRegistry.getInstance().getDatabaseManager().getDatabases().get(databaseName);
- attributes.put(argName, argValue);
- }
+ if (database == null)
+ {
+ throw new ConfigurationException("Requested database:" + databaseName + " was not found");
+ }
- return Collections.unmodifiableMap(attributes);
+ initialiseAuthenticationMechanisms(providerMap, database);
+ }
}
- }
-
- protected PrincipalDatabaseAuthenticationManager()
- {
- }
-
- public void initialise()
- {
- final Map<String, Class<? extends SaslServerFactory>> providerMap = new TreeMap<String, Class<? extends SaslServerFactory>>();
-
- initialiseAuthenticationMechanisms(providerMap, _principalDatabase);
if (providerMap.size() > 0)
{
@@ -202,16 +110,33 @@ public class PrincipalDatabaseAuthenticationManager implements AuthenticationMan
{
_logger.info("Additional SASL providers successfully registered.");
}
+
}
else
{
_logger.warn("No additional SASL providers registered.");
}
- registerManagement();
}
- private void initialiseAuthenticationMechanisms(Map<String, Class<? extends SaslServerFactory>> providerMap, PrincipalDatabase database)
+
+ private void initialiseAuthenticationMechanisms(Map<String, Class<? extends SaslServerFactory>> providerMap, Map<String, PrincipalDatabase> databases) throws Exception
+ {
+ if (databases.size() > 1)
+ {
+ _logger.warn("More than one principle database provided currently authentication mechanism will override each other.");
+ }
+
+ 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
{
if (database == null || database.getMechanisms().size() == 0)
{
@@ -227,6 +152,7 @@ public class PrincipalDatabaseAuthenticationManager implements AuthenticationMan
private void initialiseAuthenticationMechanism(String mechanism, AuthenticationProviderInitialiser initialiser,
Map<String, Class<? extends SaslServerFactory>> providerMap)
+ throws Exception
{
if (_mechanisms == null)
{
@@ -247,217 +173,65 @@ public class PrincipalDatabaseAuthenticationManager implements AuthenticationMan
_logger.info("Initialised " + mechanism + " SASL provider successfully");
}
- /**
- * @see org.apache.qpid.server.plugins.Plugin#configure(org.apache.qpid.server.configuration.plugins.ConfigurationPlugin)
- */
- public void configure(final ConfigurationPlugin config) throws ConfigurationException
- {
- final PrincipalDatabaseAuthenticationManagerConfiguration pdamConfig = (PrincipalDatabaseAuthenticationManagerConfiguration) config;
- final String pdClazz = pdamConfig.getPrincipalDatabaseClass();
-
- _logger.info("PrincipalDatabase concrete implementation : " + pdClazz);
-
- _principalDatabase = createPrincipalDatabaseImpl(pdClazz);
-
- configPrincipalDatabase(_principalDatabase, pdamConfig);
- }
-
public String getMechanisms()
{
- return _mechanisms;
- }
-
- public SaslServer createSaslServer(String mechanism, String localFQDN) throws SaslException
- {
- return Sasl.createSaslServer(mechanism, "AMQP", localFQDN, _serverCreationProperties.get(mechanism),
- _callbackHandlerMap.get(mechanism));
- }
-
- /**
- * @see org.apache.qpid.server.security.auth.manager.AuthenticationManager#authenticate(SaslServer, byte[])
- */
- public AuthenticationResult authenticate(SaslServer server, byte[] response)
- {
- try
+ if (_default != null)
{
- // Process response from the client
- byte[] challenge = server.evaluateResponse(response != null ? response : new byte[0]);
-
- if (server.isComplete())
- {
- final Subject subject = new Subject();
- subject.getPrincipals().add(new UsernamePrincipal(server.getAuthorizationID()));
- return new AuthenticationResult(subject);
- }
- else
- {
- return new AuthenticationResult(challenge, AuthenticationResult.AuthenticationStatus.CONTINUE);
- }
+ // Use the default AuthenticationManager if present
+ return _default.getMechanisms();
}
- catch (SaslException e)
+ else
{
- return new AuthenticationResult(AuthenticationResult.AuthenticationStatus.ERROR, e);
+ return _mechanisms;
}
}
- /**
- * @see org.apache.qpid.server.security.auth.manager.AuthenticationManager#authenticate(String, String)
- */
- public AuthenticationResult authenticate(final String username, final String password)
+ public SaslServer createSaslServer(String mechanism, String localFQDN) throws SaslException
{
- try
+ if (_default != null)
{
- if (_principalDatabase.verifyPassword(username, password.toCharArray()))
- {
- final Subject subject = new Subject();
- subject.getPrincipals().add(new UsernamePrincipal(username));
- return new AuthenticationResult(subject);
- }
- else
- {
- return new AuthenticationResult(AuthenticationStatus.CONTINUE);
- }
+ // Use the default AuthenticationManager if present
+ return _default.createSaslServer(mechanism, localFQDN);
}
- catch (AccountNotFoundException e)
+ else
{
- return new AuthenticationResult(AuthenticationStatus.CONTINUE);
+ return Sasl.createSaslServer(mechanism, "AMQP", localFQDN, _serverCreationProperties.get(mechanism),
+ _callbackHandlerMap.get(mechanism));
}
- }
-
- public void close()
- {
- _mechanisms = null;
- Security.removeProvider(PROVIDER_NAME);
- unregisterManagement();
}
- private PrincipalDatabase createPrincipalDatabaseImpl(final String pdClazz) throws ConfigurationException
+ public AuthenticationResult authenticate(SaslServer server, byte[] response)
{
- try
- {
- return (PrincipalDatabase) Class.forName(pdClazz).newInstance();
- }
- catch (InstantiationException ie)
- {
- throw new ConfigurationException("Cannot instantiate " + pdClazz, ie);
- }
- catch (IllegalAccessException iae)
+ // Use the default AuthenticationManager if present
+ if (_default != null)
{
- throw new ConfigurationException("Cannot access " + pdClazz, iae);
+ return _default.authenticate(server, response);
}
- catch (ClassNotFoundException cnfe)
- {
- throw new ConfigurationException("Cannot load " + pdClazz + " implementation", cnfe);
- }
- catch (ClassCastException cce)
- {
- throw new ConfigurationException("Expecting a " + PrincipalDatabase.class + " implementation", cce);
- }
- }
- private void configPrincipalDatabase(final PrincipalDatabase principalDatabase, final PrincipalDatabaseAuthenticationManagerConfiguration config)
- throws ConfigurationException
- {
- final Map<String,String> attributes = config.getPdClassAttributeMap();
-
- for (Iterator<Entry<String, String>> iterator = attributes.entrySet().iterator(); iterator.hasNext();)
+ try
{
- final Entry<String, String> nameValuePair = iterator.next();
- final String methodName = generateSetterName(nameValuePair.getKey());
- final Method method;
- try
- {
- method = principalDatabase.getClass().getMethod(methodName, String.class);
- }
- catch (Exception e)
- {
- throw new ConfigurationException("No method " + methodName + " found in class "
- + principalDatabase.getClass()
- + " hence unable to configure principal database. The method must be public and "
- + "have a single String argument with a void return type", e);
- }
- try
- {
- method.invoke(principalDatabase, PropertyUtils.replaceProperties(nameValuePair.getValue()));
- }
- catch (IllegalArgumentException e)
- {
- throw new ConfigurationException(e.getMessage(), e);
- }
- catch (PropertyException e)
- {
- throw new ConfigurationException(e.getMessage(), e);
- }
- catch (IllegalAccessException e)
+ // Process response from the client
+ byte[] challenge = server.evaluateResponse(response != null ? response : new byte[0]);
+
+ if (server.isComplete())
{
- throw new ConfigurationException(e.getMessage(), e);
+ return new AuthenticationResult(challenge, AuthenticationResult.AuthenticationStatus.SUCCESS);
}
- catch (InvocationTargetException e)
+ else
{
- // QPID-1347.. InvocationTargetException wraps the checked exception thrown from the reflective
- // method call. Pull out the underlying message and cause to make these more apparent to the user.
- throw new ConfigurationException(e.getCause().getMessage(), e.getCause());
+ return new AuthenticationResult(challenge, AuthenticationResult.AuthenticationStatus.CONTINUE);
}
}
- }
-
- private String generateSetterName(String argName) throws ConfigurationException
- {
- if ((argName == null) || (argName.length() == 0))
- {
- throw new ConfigurationException("Argument names must have length >= 1 character");
- }
-
- if (Character.isLowerCase(argName.charAt(0)))
- {
- argName = Character.toUpperCase(argName.charAt(0)) + argName.substring(1);
- }
-
- final String methodName = "set" + argName;
- return methodName;
- }
-
- protected void setPrincipalDatabase(final PrincipalDatabase principalDatabase)
- {
- _principalDatabase = principalDatabase;
- }
-
- protected void registerManagement()
- {
- try
- {
- _logger.info("Registering UserManagementMBean");
-
- _mbean = new AMQUserManagementMBean();
- _mbean.setPrincipalDatabase(_principalDatabase);
- _mbean.register();
- }
- catch (Exception e)
+ catch (SaslException e)
{
- _logger.warn("User management disabled as unable to create MBean:", e);
- _mbean = null;
+ return new AuthenticationResult(AuthenticationResult.AuthenticationStatus.ERROR, e);
}
}
- protected void unregisterManagement()
+ public void close()
{
- try
- {
- if (_mbean != null)
- {
- _logger.info("Unregistering UserManagementMBean");
- _mbean.unregister();
- }
- }
- catch (Exception e)
- {
- _logger.warn("Failed to unregister User management MBean:", e);
- }
- finally
- {
- _mbean = null;
- }
+ Security.removeProvider(PROVIDER_NAME);
}
}
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 b7985ad972..0cbbccb3b8 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,13 +20,14 @@
*/
package org.apache.qpid.server.security.auth.rmi;
+import java.util.Collections;
+
import javax.management.remote.JMXAuthenticator;
import javax.management.remote.JMXPrincipal;
import javax.security.auth.Subject;
+import javax.security.auth.login.AccountNotFoundException;
-import org.apache.qpid.server.security.auth.AuthenticationResult;
-import org.apache.qpid.server.security.auth.AuthenticationResult.AuthenticationStatus;
-import org.apache.qpid.server.security.auth.manager.AuthenticationManager;
+import org.apache.qpid.server.security.auth.database.PrincipalDatabase;
public class RMIPasswordAuthenticator implements JMXAuthenticator
{
@@ -38,15 +39,15 @@ public class RMIPasswordAuthenticator implements JMXAuthenticator
static final String CREDENTIALS_REQUIRED = "User details are required. " +
"Please ensure you are using an up to date management console to connect.";
- private AuthenticationManager _authenticationManager = null;
+ private PrincipalDatabase _db = null;
public RMIPasswordAuthenticator()
{
}
-
- public void setAuthenticationManager(final AuthenticationManager authenticationManager)
+
+ public void setPrincipalDatabase(PrincipalDatabase pd)
{
- _authenticationManager = authenticationManager;
+ this._db = pd;
}
public Subject authenticate(Object credentials) throws SecurityException
@@ -64,39 +65,50 @@ public class RMIPasswordAuthenticator implements JMXAuthenticator
}
}
- // Verify that required number of credentials.
+ // Verify that required number of credential's.
final String[] userCredentials = (String[]) credentials;
if (userCredentials.length != 2)
{
throw new SecurityException(SHOULD_HAVE_2_ELEMENTS);
}
- final String username = (String) userCredentials[0];
- final String password = (String) userCredentials[1];
+ String username = (String) userCredentials[0];
+ String password = (String) userCredentials[1];
- // Verify that all required credentials are actually present.
+ // Verify that all required credential's are actually present.
if (username == null || password == null)
{
throw new SecurityException(SHOULD_BE_NON_NULL);
}
- // Verify that an AuthenticationManager has been set.
- if (_authenticationManager == null)
+ // Verify that a PD has been set.
+ if (_db == null)
{
throw new SecurityException(UNABLE_TO_LOOKUP);
}
- final AuthenticationResult result = _authenticationManager.authenticate(username, password);
+
+ boolean authenticated = false;
- if (AuthenticationStatus.ERROR.equals(result.getStatus()))
+ // Perform authentication
+ try
{
- throw new SecurityException("Authentication manager failed", result.getCause());
+ if (_db.verifyPassword(username, password.toCharArray()))
+ {
+ authenticated = true;
+ }
+ }
+ catch (AccountNotFoundException e)
+ {
+ throw new SecurityException(INVALID_CREDENTIALS); // XXX
}
- else if (AuthenticationStatus.SUCCESS.equals(result.getStatus()))
+
+ if (authenticated)
{
- final Subject subject = result.getSubject();
- subject.getPrincipals().add(new JMXPrincipal(username));
- subject.setReadOnly();
- return subject;
+ //credential's check out, return the appropriate JAAS Subject
+ return new Subject(true,
+ Collections.singleton(new JMXPrincipal(username)),
+ Collections.EMPTY_SET,
+ Collections.EMPTY_SET);
}
else
{
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/AuthenticationProviderInitialiser.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/AuthenticationProviderInitialiser.java
index bc5d8a4f2b..89e545d6f5 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/AuthenticationProviderInitialiser.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/AuthenticationProviderInitialiser.java
@@ -25,6 +25,9 @@ import java.util.Map;
import javax.security.auth.callback.CallbackHandler;
import javax.security.sasl.SaslServerFactory;
+import org.apache.commons.configuration.Configuration;
+import org.apache.qpid.server.security.auth.database.PrincipalDatabase;
+
public interface AuthenticationProviderInitialiser
{
/**
@@ -34,6 +37,24 @@ public interface AuthenticationProviderInitialiser
String getMechanismName();
/**
+ * Initialise the authentication provider.
+ * @param baseConfigPath the path in the config file that points to any config options for this provider. Each
+ * provider can have its own set of configuration options
+ * @param configuration the Apache Commons Configuration instance used to configure this provider
+ * @param principalDatabases the set of principal databases that are available
+ * @throws Exception needs refined Exception is too broad.
+ */
+ void initialise(String baseConfigPath, Configuration configuration,
+ Map<String, PrincipalDatabase> principalDatabases) throws Exception;
+
+ /**
+ * Initialise the authentication provider.
+ * @param db The principal database to initialise with
+ */
+ void initialise(PrincipalDatabase db);
+
+
+ /**
* @return the callback handler that should be used to process authentication requests for this mechanism. This will
* be called after initialise and will be stored by the authentication manager. The callback handler <b>must</b> be
* fully threadsafe.
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/GroupPrincipal.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/GroupPrincipal.java
deleted file mode 100644
index 30a503c769..0000000000
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/GroupPrincipal.java
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
- */
-package org.apache.qpid.server.security.auth.sasl;
-
-import java.security.Principal;
-import java.security.acl.Group;
-import java.util.Enumeration;
-
-/**
- * Immutable representation of a user group. In Qpid, groups do <b>not</b> know
- * about their membership, and therefore the {@link #addMember(Principal)}
- * methods etc throw {@link UnsupportedOperationException}.
- *
- */
-public class GroupPrincipal implements Group
-{
- /** Name of the group */
- private final String _groupName;
-
- public GroupPrincipal(final String groupName)
- {
- _groupName = groupName;
- }
-
- public String getName()
- {
- return _groupName;
- }
-
- public boolean addMember(Principal user)
- {
- throw new UnsupportedOperationException("Not supported");
- }
-
- public boolean removeMember(Principal user)
- {
- throw new UnsupportedOperationException("Not supported");
- }
-
- public boolean isMember(Principal member)
- {
- throw new UnsupportedOperationException("Not supported");
- }
-
- public Enumeration<? extends Principal> members()
- {
- throw new UnsupportedOperationException("Not supported");
- }
-
- /**
- * @see java.lang.Object#hashCode()
- */
- public int hashCode()
- {
- final int prime = 37;
- return prime * _groupName.hashCode();
- }
-
- /**
- * @see java.lang.Object#equals(java.lang.Object)
- */
- public boolean equals(Object obj)
- {
- if (this == obj)
- {
- return true;
- }
- else
- {
- if (obj instanceof GroupPrincipal)
- {
- GroupPrincipal other = (GroupPrincipal) obj;
- return _groupName.equals(other._groupName);
- }
- else
- {
- return false;
- }
- }
- }
-}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/UsernamePrincipal.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/UsernamePrincipal.java
index b4ee13fe6b..d7c8383690 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/UsernamePrincipal.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/UsernamePrincipal.java
@@ -21,21 +21,14 @@
package org.apache.qpid.server.security.auth.sasl;
import java.security.Principal;
-import java.util.Set;
-
-import javax.security.auth.Subject;
/** A principal that is just a wrapper for a simple username. */
public class UsernamePrincipal implements Principal
{
- private final String _name;
+ private String _name;
public UsernamePrincipal(String name)
{
- if (name == null)
- {
- throw new IllegalArgumentException("name cannot be null");
- }
_name = name;
}
@@ -48,53 +41,4 @@ public class UsernamePrincipal implements Principal
{
return _name;
}
-
- /**
- * @see java.lang.Object#hashCode()
- */
- @Override
- public int hashCode()
- {
- final int prime = 31;
- return prime * _name.hashCode();
- }
-
- /**
- * @see java.lang.Object#equals(java.lang.Object)
- */
- @Override
- public boolean equals(Object obj)
- {
- if (this == obj)
- {
- return true;
- }
- else
- {
- if (obj instanceof UsernamePrincipal)
- {
- UsernamePrincipal other = (UsernamePrincipal) obj;
- return _name.equals(other._name);
- }
- else
- {
- return false;
- }
- }
- }
-
- public static UsernamePrincipal getUsernamePrincipalFromSubject(final Subject authSubject)
- {
- if (authSubject == null)
- {
- throw new IllegalArgumentException("No authenticated subject.");
- }
-
- final Set<UsernamePrincipal> principals = authSubject.getPrincipals(UsernamePrincipal.class);
- if (principals.size() != 1)
- {
- throw new IllegalArgumentException("Can't find single UsernamePrincipal in authenticated subject");
- }
- return principals.iterator().next();
- }
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/amqplain/AmqPlainSaslServerFactory.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/amqplain/AmqPlainSaslServerFactory.java
index 17d123eb0d..67d20136bf 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/amqplain/AmqPlainSaslServerFactory.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/amqplain/AmqPlainSaslServerFactory.java
@@ -45,10 +45,9 @@ public class AmqPlainSaslServerFactory implements SaslServerFactory
public String[] getMechanismNames(Map props)
{
- if (props != null &&
- (props.containsKey(Sasl.POLICY_NOPLAINTEXT) ||
- props.containsKey(Sasl.POLICY_NODICTIONARY) ||
- props.containsKey(Sasl.POLICY_NOACTIVE)))
+ if (props.containsKey(Sasl.POLICY_NOPLAINTEXT) ||
+ props.containsKey(Sasl.POLICY_NODICTIONARY) ||
+ props.containsKey(Sasl.POLICY_NOACTIVE))
{
// returned array must be non null according to interface documentation
return new String[0];
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/anonymous/AnonymousSaslServerFactory.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/anonymous/AnonymousSaslServerFactory.java
index 8a5ff7df2d..6032255870 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/anonymous/AnonymousSaslServerFactory.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/anonymous/AnonymousSaslServerFactory.java
@@ -47,11 +47,10 @@ public class AnonymousSaslServerFactory implements SaslServerFactory
public String[] getMechanismNames(Map props)
{
- if (props != null &&
- (props.containsKey(Sasl.POLICY_NOPLAINTEXT) ||
- props.containsKey(Sasl.POLICY_NODICTIONARY) ||
- props.containsKey(Sasl.POLICY_NOACTIVE) ||
- props.containsKey(Sasl.POLICY_NOANONYMOUS)))
+ if (props.containsKey(Sasl.POLICY_NOPLAINTEXT) ||
+ props.containsKey(Sasl.POLICY_NODICTIONARY) ||
+ props.containsKey(Sasl.POLICY_NOACTIVE) ||
+ props.containsKey(Sasl.POLICY_NOANONYMOUS))
{
// returned array must be non null according to interface documentation
return new String[0];
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/crammd5/CRAMMD5HexInitialiser.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/crammd5/CRAMMD5HexInitialiser.java
index 139818735f..8020d97364 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/crammd5/CRAMMD5HexInitialiser.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/crammd5/CRAMMD5HexInitialiser.java
@@ -70,7 +70,7 @@ public class CRAMMD5HexInitialiser extends UsernamePasswordInitialiser
for (char c : password)
{
//toHexString does not prepend 0 so we have to
- if (((byte) c > -1) && (byte) c < 0x10 )
+ if (((byte) c > -1) && (byte) c < 10)
{
sb.append(0);
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/plain/PlainSaslServerFactory.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/plain/PlainSaslServerFactory.java
index 3144bfbce6..f0dd9eeb6d 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/plain/PlainSaslServerFactory.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/plain/PlainSaslServerFactory.java
@@ -45,10 +45,9 @@ public class PlainSaslServerFactory implements SaslServerFactory
public String[] getMechanismNames(Map props)
{
- if (props != null &&
- (props.containsKey(Sasl.POLICY_NOPLAINTEXT) ||
- props.containsKey(Sasl.POLICY_NODICTIONARY) ||
- props.containsKey(Sasl.POLICY_NOACTIVE)))
+ if (props.containsKey(Sasl.POLICY_NOPLAINTEXT) ||
+ props.containsKey(Sasl.POLICY_NODICTIONARY) ||
+ props.containsKey(Sasl.POLICY_NOACTIVE))
{
// returned array must be non null according to interface documentation
return new String[0];
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/state/AMQStateManager.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/state/AMQStateManager.java
index 33aebffcfb..6cc5e7b019 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/state/AMQStateManager.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/state/AMQStateManager.java
@@ -259,7 +259,7 @@ public class AMQStateManager implements AMQMethodListener
public AMQProtocolSession getProtocolSession()
{
- SecurityManager.setThreadSubject(_protocolSession.getAuthorizedSubject());
+ SecurityManager.setThreadPrincipal(_protocolSession.getPrincipal());
return _protocolSession;
}
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/stats/StatisticsCounter.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/stats/StatisticsCounter.java
deleted file mode 100644
index b732121180..0000000000
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/stats/StatisticsCounter.java
+++ /dev/null
@@ -1,163 +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.stats;
-
-import java.util.Date;
-import java.util.concurrent.atomic.AtomicLong;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * This class collects statistics and counts the total, rate per second and
- * peak rate per second values for the events that are registered with it.
- */
-public class StatisticsCounter
-{
- private static final Logger _log = LoggerFactory.getLogger(StatisticsCounter.class);
-
- public static final long DEFAULT_SAMPLE_PERIOD = Long.getLong("qpid.statistics.samplePeriod", 2000L); // 2s
- public static final boolean DISABLE_STATISTICS = Boolean.getBoolean("qpid.statistics.disable");
-
- private static final String COUNTER = "counter";
- private static final AtomicLong _counterIds = new AtomicLong(0L);
-
- private long _peak = 0L;
- private long _total = 0L;
- private long _temp = 0L;
- private long _last = 0L;
- private long _rate = 0L;
-
- private long _start;
-
- private final long _period;
- private final String _name;
-
- public StatisticsCounter()
- {
- this(COUNTER);
- }
-
- public StatisticsCounter(String name)
- {
- this(name, DEFAULT_SAMPLE_PERIOD);
- }
-
- public StatisticsCounter(String name, long period)
- {
- _period = period;
- _name = name + "-" + + _counterIds.incrementAndGet();
- reset();
- }
-
- public void registerEvent()
- {
- registerEvent(1L);
- }
-
- public void registerEvent(long value)
- {
- registerEvent(value, System.currentTimeMillis());
- }
-
- public void registerEvent(long value, long timestamp)
- {
- if (DISABLE_STATISTICS)
- {
- return;
- }
-
- long thisSample = (timestamp / _period);
- synchronized (this)
- {
- if (thisSample > _last)
- {
- _last = thisSample;
- _rate = _temp;
- _temp = 0L;
- if (_rate > _peak)
- {
- _peak = _rate;
- }
- }
-
- _total += value;
- _temp += value;
- }
- }
-
- /**
- * Update the current rate and peak - may reset rate to zero if a new
- * sample period has started.
- */
- private void update()
- {
- registerEvent(0L, System.currentTimeMillis());
- }
-
- /**
- * Reset
- */
- public void reset()
- {
- _log.info("Resetting statistics for counter: " + _name);
- _peak = 0L;
- _rate = 0L;
- _total = 0L;
- _start = System.currentTimeMillis();
- _last = _start / _period;
- }
-
- public double getPeak()
- {
- update();
- return (double) _peak / ((double) _period / 1000.0d);
- }
-
- public double getRate()
- {
- update();
- return (double) _rate / ((double) _period / 1000.0d);
- }
-
- public long getTotal()
- {
- return _total;
- }
-
- public long getStart()
- {
- return _start;
- }
-
- public Date getStartTime()
- {
- return new Date(_start);
- }
-
- public String getName()
- {
- return _name;
- }
-
- public long getPeriod()
- {
- return _period;
- }
-}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/stats/StatisticsGatherer.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/stats/StatisticsGatherer.java
deleted file mode 100644
index 36fec4025a..0000000000
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/stats/StatisticsGatherer.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.stats;
-
-/**
- * This interface is to be implemented by any broker business object that
- * wishes to gather statistics about messages delivered through it.
- *
- * These statistics are exposed using a separate JMX Mbean interface, which
- * calls these methods to retrieve the underlying {@link StatisticsCounter}s
- * and return their attributes. This interface gives a standard way for
- * parts of the broker to set up and configure statistics generation.
- * <p>
- * When creating these objects, there should be a parent/child relationship
- * between them, such that the lowest level gatherer can record staticics if
- * enabled, and pass on the notification to the parent object to allow higher
- * level aggregation. When resetting statistics, this works in the opposite
- * direction, with higher level gatherers also resetting all of their children.
- */
-public interface StatisticsGatherer
-{
- /**
- * Initialise the statistics gathering for this object.
- *
- * This method is responsible for creating any {@link StatisticsCounter}
- * objects and for determining whether statistics generation should be
- * enabled, by checking broker and system configuration.
- *
- * @see StatisticsCounter#DISABLE_STATISTICS
- */
- void initialiseStatistics();
-
- /**
- * This method is responsible for registering the receipt of a message
- * with the counters, and also for passing this notification to any parent
- * {@link StatisticsGatherer}s. If statistics generation is not enabled,
- * then this method should simple delegate to the parent gatherer.
- *
- * @param messageSize the size in bytes of the delivered message
- * @param timestamp the time the message was delivered
- */
- void registerMessageReceived(long messageSize, long timestamp);
-
- /**
- * This method is responsible for registering the delivery of a message
- * with the counters. Message delivery is recorded by the counter using
- * the current system time, as opposed to the message timestamp.
- *
- * @param messageSize the size in bytes of the delivered message
- * @see #registerMessageReceived(long, long)
- */
- void registerMessageDelivered(long messageSize);
-
- /**
- * Gives access to the {@link StatisticsCounter} that is used to count
- * delivered message statistics.
- *
- * @return the {@link StatisticsCounter} that counts delivered messages
- */
- StatisticsCounter getMessageDeliveryStatistics();
-
- /**
- * Gives access to the {@link StatisticsCounter} that is used to count
- * received message statistics.
- *
- * @return the {@link StatisticsCounter} that counts received messages
- */
- StatisticsCounter getMessageReceiptStatistics();
-
- /**
- * Gives access to the {@link StatisticsCounter} that is used to count
- * delivered message size statistics.
- *
- * @return the {@link StatisticsCounter} that counts delivered bytes
- */
- StatisticsCounter getDataDeliveryStatistics();
-
- /**
- * Gives access to the {@link StatisticsCounter} that is used to count
- * received message size statistics.
- *
- * @return the {@link StatisticsCounter} that counts received bytes
- */
- StatisticsCounter getDataReceiptStatistics();
-
- /**
- * Reset the counters for this, and any child {@link StatisticsGatherer}s.
- */
- void resetStatistics();
-
- /**
- * Check if this object has statistics generation enabled.
- *
- * @return true if statistics generation is enabled
- */
- boolean isStatisticsEnabled();
-
- /**
- * Enable or disable statistics generation for this object.
- */
- void setStatisticsEnabled(boolean enabled);
-}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/subscription/SubscriptionList.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/subscription/SubscriptionList.java
index 3e6299cb8a..9ea81660c6 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/subscription/SubscriptionList.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/subscription/SubscriptionList.java
@@ -20,108 +20,121 @@
*/
package org.apache.qpid.server.subscription;
+import org.apache.qpid.server.queue.AMQQueue;
import org.apache.qpid.server.subscription.Subscription;
import java.util.concurrent.atomic.AtomicReference;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
+import java.nio.ByteBuffer;
public class SubscriptionList
{
+
private final SubscriptionNode _head = new SubscriptionNode();
- private final AtomicReference<SubscriptionNode> _tail = new AtomicReference<SubscriptionNode>(_head);
- private final AtomicReference<SubscriptionNode> _subNodeMarker = new AtomicReference<SubscriptionNode>(_head);
- private final AtomicInteger _size = new AtomicInteger();
+ private AtomicReference<SubscriptionNode> _tail = new AtomicReference<SubscriptionNode>(_head);
+ private AtomicInteger _size = new AtomicInteger();
+
- public static final class SubscriptionNode
+ public final class SubscriptionNode
{
private final AtomicBoolean _deleted = new AtomicBoolean();
private final AtomicReference<SubscriptionNode> _next = new AtomicReference<SubscriptionNode>();
private final Subscription _sub;
+
public SubscriptionNode()
{
- //used for sentinel head and dummy node construction
+
_sub = null;
_deleted.set(true);
}
public SubscriptionNode(final Subscription sub)
{
- //used for regular node construction
_sub = sub;
}
- /**
- * Retrieves the first non-deleted node following the current node.
- * Any deleted non-tail nodes encountered during the search are unlinked.
- *
- * @return the next non-deleted node, or null if none was found.
- */
- public SubscriptionNode findNext()
+
+ public SubscriptionNode getNext()
{
+
SubscriptionNode next = nextNode();
while(next != null && next.isDeleted())
{
+
final SubscriptionNode newNext = next.nextNode();
if(newNext != null)
{
- //try to move our _next reference forward to the 'newNext'
- //node to unlink the deleted node
_next.compareAndSet(next, newNext);
next = nextNode();
}
else
{
- //'newNext' is null, meaning 'next' is the current tail. Can't unlink
- //the tail node for thread safety reasons, just use the null.
next = null;
}
- }
+ }
return next;
}
- /**
- * Gets the immediately next referenced node in the structure.
- *
- * @return the immediately next node in the structure, or null if at the tail.
- */
- protected SubscriptionNode nextNode()
+ private SubscriptionNode nextNode()
{
return _next.get();
}
- /**
- * Used to initialise the 'next' reference. Will only succeed if the reference was not previously set.
- *
- * @param node the SubscriptionNode to set as 'next'
- * @return whether the operation succeeded
- */
- private boolean setNext(final SubscriptionNode node)
- {
- return _next.compareAndSet(null, node);
- }
-
public boolean isDeleted()
{
return _deleted.get();
}
+
public boolean delete()
{
- return _deleted.compareAndSet(false,true);
+ if(_deleted.compareAndSet(false,true))
+ {
+ _size.decrementAndGet();
+ advanceHead();
+ return true;
+ }
+ else
+ {
+ return false;
+ }
}
+
public Subscription getSubscription()
{
return _sub;
}
}
- private void insert(final SubscriptionNode node, final boolean count)
+
+ public SubscriptionList(AMQQueue queue)
+ {
+ }
+
+ private void advanceHead()
+ {
+ SubscriptionNode head = _head.nextNode();
+ while(head._next.get() != null && head.isDeleted())
+ {
+
+ final SubscriptionNode newhead = head.nextNode();
+ if(newhead != null)
+ {
+ _head._next.compareAndSet(head, newhead);
+ }
+ head = _head.nextNode();
+ }
+ }
+
+
+ public SubscriptionNode add(Subscription sub)
{
+ SubscriptionNode node = new SubscriptionNode(sub);
for (;;)
{
SubscriptionNode tail = _tail.get();
@@ -130,14 +143,11 @@ public class SubscriptionList
{
if (next == null)
{
- if (tail.setNext(node))
+ if (tail._next.compareAndSet(null, node))
{
_tail.compareAndSet(tail, node);
- if(count)
- {
- _size.incrementAndGet();
- }
- return;
+ _size.incrementAndGet();
+ return node;
}
}
else
@@ -146,101 +156,27 @@ public class SubscriptionList
}
}
}
- }
- public void add(final Subscription sub)
- {
- SubscriptionNode node = new SubscriptionNode(sub);
- insert(node, true);
}
- public boolean remove(final Subscription sub)
+ public boolean remove(Subscription sub)
{
- SubscriptionNode prevNode = _head;
- SubscriptionNode node = _head.nextNode();
-
+ SubscriptionNode node = _head.getNext();
while(node != null)
{
- if(sub.equals(node.getSubscription()) && node.delete())
+ if(sub.equals(node._sub) && node.delete())
{
- _size.decrementAndGet();
-
- SubscriptionNode tail = _tail.get();
- if(node == tail)
- {
- //we cant remove the last node from the structure for
- //correctness reasons, however we have just 'deleted'
- //the tail. Inserting an empty dummy node after it will
- //let us scavenge the node containing the Subscription.
- insert(new SubscriptionNode(), false);
- }
-
- //advance the next node reference in the 'prevNode' to scavange
- //the newly 'deleted' node for the Subscription.
- prevNode.findNext();
-
- nodeMarkerCleanup(node);
-
return true;
}
-
- prevNode = node;
- node = node.findNext();
+ node = node.getNext();
}
-
return false;
}
- private void nodeMarkerCleanup(final SubscriptionNode node)
- {
- SubscriptionNode markedNode = _subNodeMarker.get();
- if(node == markedNode)
- {
- //if the marked node is the one we are removing, then
- //replace it with a dummy pointing at the next node.
- //this is OK as the marked node is only used to index
- //into the list and find the next node to use.
- //Because we inserted a dummy if node was the
- //tail, markedNode.nextNode() can never be null.
- SubscriptionNode dummy = new SubscriptionNode();
- dummy.setNext(markedNode.nextNode());
-
- //if the CAS fails the marked node has changed, thus
- //we don't care about the dummy and just forget it
- _subNodeMarker.compareAndSet(markedNode, dummy);
- }
- else if(markedNode != null)
- {
- //if the marked node was already deleted then it could
- //hold subsequently removed nodes after it in the list
- //in memory. Scavenge it to ensure their actual removal.
- if(markedNode != _head && markedNode.isDeleted())
- {
- markedNode.findNext();
- }
- }
- }
-
- public boolean updateMarkedNode(final SubscriptionNode expected, final SubscriptionNode nextNode)
- {
- return _subNodeMarker.compareAndSet(expected, nextNode);
- }
-
- /**
- * Get the current marked SubscriptionNode. This should only be used only to index into the list and find the next node
- * after the mark, since if the previously marked node was subsequently deleted the item returned may be a dummy node
- * with reference to the next node.
- *
- * @return the previously marked node (or a dummy if it was subsequently deleted)
- */
- public SubscriptionNode getMarkedNode()
- {
- return _subNodeMarker.get();
- }
-
public static class SubscriptionNodeIterator
{
+
private SubscriptionNode _lastNode;
SubscriptionNodeIterator(SubscriptionNode startNode)
@@ -248,25 +184,49 @@ public class SubscriptionList
_lastNode = startNode;
}
+
+ public boolean atTail()
+ {
+ return _lastNode.nextNode() == null;
+ }
+
public SubscriptionNode getNode()
{
+
return _lastNode;
+
}
public boolean advance()
{
- SubscriptionNode nextNode = _lastNode.findNext();
- _lastNode = nextNode;
- return _lastNode != null;
+ if(!atTail())
+ {
+ SubscriptionNode nextNode = _lastNode.nextNode();
+ while(nextNode.isDeleted() && nextNode.nextNode() != null)
+ {
+ nextNode = nextNode.nextNode();
+ }
+ _lastNode = nextNode;
+ return true;
+
+ }
+ else
+ {
+ return false;
+ }
+
}
+
}
+
public SubscriptionNodeIterator iterator()
{
return new SubscriptionNodeIterator(_head);
}
+
public SubscriptionNode getHead()
{
return _head;
@@ -276,6 +236,9 @@ public class SubscriptionList
{
return _size.get();
}
+
+
+
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/subscription/Subscription_0_10.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/subscription/Subscription_0_10.java
index 68e47fd86a..b36ac84cdd 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/subscription/Subscription_0_10.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/subscription/Subscription_0_10.java
@@ -97,6 +97,7 @@ public class Subscription_0_10 implements Subscription, FlowCreditManager.FlowCr
private FlowCreditManager_0_10 _creditManager;
+
private StateListener _stateListener = new StateListener()
{
@@ -441,7 +442,7 @@ public class Subscription_0_10 implements Subscription, FlowCreditManager.FlowCr
Struct[] headers = new Struct[] { deliveryProps, messageProps };
BasicContentHeaderProperties properties =
- (BasicContentHeaderProperties) message_0_8.getContentHeaderBody().getProperties();
+ (BasicContentHeaderProperties) message_0_8.getContentHeaderBody().properties;
final AMQShortString exchange = message_0_8.getMessagePublishInfo().getExchange();
if(exchange != null)
{
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/transport/QpidAcceptor.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/transport/QpidAcceptor.java
index abbc5a3805..3ca22b60c8 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/transport/QpidAcceptor.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/transport/QpidAcceptor.java
@@ -20,21 +20,21 @@
*/
package org.apache.qpid.server.transport;
-import org.apache.qpid.transport.network.NetworkTransport;
+import org.apache.qpid.transport.NetworkDriver;
public class QpidAcceptor
{
- NetworkTransport _transport;
+ NetworkDriver _driver;
String _protocol;
- public QpidAcceptor(NetworkTransport transport, String protocol)
+ public QpidAcceptor(NetworkDriver driver, String protocol)
{
- _transport = transport;
+ _driver = driver;
_protocol = protocol;
}
- public NetworkTransport getNetworkTransport()
+ public NetworkDriver getNetworkDriver()
{
- return _transport;
+ return _driver;
}
public String toString()
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/transport/ServerConnection.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/transport/ServerConnection.java
index 9b3673e8b7..d2addfde0c 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/transport/ServerConnection.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/transport/ServerConnection.java
@@ -22,14 +22,8 @@ package org.apache.qpid.server.transport;
import static org.apache.qpid.server.logging.subjects.LogSubjectFormat.*;
-import java.security.Principal;
import java.text.MessageFormat;
import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.UUID;
-
-import javax.security.auth.Subject;
import org.apache.qpid.AMQException;
import org.apache.qpid.protocol.AMQConstant;
@@ -41,40 +35,25 @@ import org.apache.qpid.server.logging.actors.GenericActor;
import org.apache.qpid.server.logging.messages.ConnectionMessages;
import org.apache.qpid.server.protocol.AMQConnectionModel;
import org.apache.qpid.server.protocol.AMQSessionModel;
-import org.apache.qpid.server.security.AuthorizationHolder;
-import org.apache.qpid.server.security.auth.sasl.UsernamePrincipal;
-import org.apache.qpid.server.stats.StatisticsCounter;
import org.apache.qpid.server.virtualhost.VirtualHost;
import org.apache.qpid.transport.Connection;
-import org.apache.qpid.transport.ConnectionCloseCode;
import org.apache.qpid.transport.ExecutionErrorCode;
import org.apache.qpid.transport.ExecutionException;
import org.apache.qpid.transport.Method;
import org.apache.qpid.transport.ProtocolEvent;
-import org.apache.qpid.transport.Session;
-public class ServerConnection extends Connection implements AMQConnectionModel, LogSubject, AuthorizationHolder
+public class ServerConnection extends Connection implements AMQConnectionModel, LogSubject
{
private ConnectionConfig _config;
private Runnable _onOpenTask;
private AtomicBoolean _logClosed = new AtomicBoolean(false);
private LogActor _actor = GenericActor.getInstance(this);
- private Subject _authorizedSubject = null;
- private Principal _authorizedPrincipal = null;
- private boolean _statisticsEnabled = false;
- private StatisticsCounter _messagesDelivered, _dataDelivered, _messagesReceived, _dataReceived;
-
public ServerConnection()
{
}
- public UUID getId()
- {
- return _config.getId();
- }
-
@Override
protected void invoke(Method method)
{
@@ -93,18 +72,8 @@ public class ServerConnection extends Connection implements AMQConnectionModel,
_onOpenTask.run();
}
_actor.message(ConnectionMessages.OPEN(getClientId(), "0-10", true, true));
-
- getVirtualHost().getConnectionRegistry().registerConnection(this);
- }
-
- if (state == State.CLOSE_RCVD || state == State.CLOSED || state == State.CLOSING)
- {
- if(_virtualHost != null)
- {
- _virtualHost.getConnectionRegistry().deregisterConnection(this);
- }
}
-
+
if (state == State.CLOSED)
{
logClosed();
@@ -141,8 +110,6 @@ public class ServerConnection extends Connection implements AMQConnectionModel,
public void setVirtualHost(VirtualHost virtualHost)
{
_virtualHost = virtualHost;
-
- initialiseStatistics();
}
public void setConnectionConfig(final ConnectionConfig config)
@@ -178,11 +145,6 @@ public class ServerConnection extends Connection implements AMQConnectionModel,
((ServerSession)session).close();
}
-
- public LogSubject getLogSubject()
- {
- return (LogSubject) this;
- }
@Override
public void received(ProtocolEvent event)
@@ -217,9 +179,9 @@ public class ServerConnection extends Connection implements AMQConnectionModel,
public String toLogString()
{
boolean hasVirtualHost = (null != this.getVirtualHost());
- boolean hasClientId = (null != getClientId());
+ boolean hasPrincipal = (null != getAuthorizationID());
- if (hasClientId && hasVirtualHost)
+ if (hasPrincipal && hasVirtualHost)
{
return "[" +
MessageFormat.format(CONNECTION_FORMAT,
@@ -229,7 +191,7 @@ public class ServerConnection extends Connection implements AMQConnectionModel,
getVirtualHost().getName())
+ "] ";
}
- else if (hasClientId)
+ else if (hasPrincipal)
{
return "[" +
MessageFormat.format(USER_FORMAT,
@@ -253,130 +215,4 @@ public class ServerConnection extends Connection implements AMQConnectionModel,
{
return _actor;
}
-
- public void close(AMQConstant cause, String message) throws AMQException
- {
- ConnectionCloseCode replyCode = ConnectionCloseCode.NORMAL;
- try
- {
- replyCode = ConnectionCloseCode.get(cause.getCode());
- }
- catch (IllegalArgumentException iae)
- {
- // Ignore
- }
- close(replyCode, message);
- }
-
- public List<AMQSessionModel> getSessionModels()
- {
- List<AMQSessionModel> sessions = new ArrayList<AMQSessionModel>();
- for (Session ssn : getChannels())
- {
- sessions.add((AMQSessionModel) ssn);
- }
- return sessions;
- }
-
- public void registerMessageDelivered(long messageSize)
- {
- if (isStatisticsEnabled())
- {
- _messagesDelivered.registerEvent(1L);
- _dataDelivered.registerEvent(messageSize);
- }
- _virtualHost.registerMessageDelivered(messageSize);
- }
-
- public void registerMessageReceived(long messageSize, long timestamp)
- {
- if (isStatisticsEnabled())
- {
- _messagesReceived.registerEvent(1L, timestamp);
- _dataReceived.registerEvent(messageSize, timestamp);
- }
- _virtualHost.registerMessageReceived(messageSize, timestamp);
- }
-
- public StatisticsCounter getMessageReceiptStatistics()
- {
- return _messagesReceived;
- }
-
- public StatisticsCounter getDataReceiptStatistics()
- {
- return _dataReceived;
- }
-
- public StatisticsCounter getMessageDeliveryStatistics()
- {
- return _messagesDelivered;
- }
-
- public StatisticsCounter getDataDeliveryStatistics()
- {
- return _dataDelivered;
- }
-
- public void resetStatistics()
- {
- _messagesDelivered.reset();
- _dataDelivered.reset();
- _messagesReceived.reset();
- _dataReceived.reset();
- }
-
- public void initialiseStatistics()
- {
- setStatisticsEnabled(!StatisticsCounter.DISABLE_STATISTICS &&
- _virtualHost.getApplicationRegistry().getConfiguration().isStatisticsGenerationConnectionsEnabled());
-
- _messagesDelivered = new StatisticsCounter("messages-delivered-" + getConnectionId());
- _dataDelivered = new StatisticsCounter("data-delivered-" + getConnectionId());
- _messagesReceived = new StatisticsCounter("messages-received-" + getConnectionId());
- _dataReceived = new StatisticsCounter("data-received-" + getConnectionId());
- }
-
- public boolean isStatisticsEnabled()
- {
- return _statisticsEnabled;
- }
-
- public void setStatisticsEnabled(boolean enabled)
- {
- _statisticsEnabled = enabled;
- }
-
- /**
- * @return authorizedSubject
- */
- public Subject getAuthorizedSubject()
- {
- return _authorizedSubject;
- }
-
- /**
- * Sets the authorized subject. It also extracts the UsernamePrincipal from the subject
- * and caches it for optimisation purposes.
- *
- * @param authorizedSubject
- */
- public void setAuthorizedSubject(final Subject authorizedSubject)
- {
- if (authorizedSubject == null)
- {
- _authorizedSubject = null;
- _authorizedPrincipal = null;
- }
- else
- {
- _authorizedSubject = authorizedSubject;
- _authorizedPrincipal = UsernamePrincipal.getUsernamePrincipalFromSubject(_authorizedSubject);
- }
- }
-
- public Principal getAuthorizedPrincipal()
- {
- return _authorizedPrincipal;
- }
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/transport/ServerConnectionDelegate.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/transport/ServerConnectionDelegate.java
index 27e199291d..2b9e92f685 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/transport/ServerConnectionDelegate.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/transport/ServerConnectionDelegate.java
@@ -20,30 +20,26 @@
*/
package org.apache.qpid.server.transport;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.StringTokenizer;
-
-import javax.security.sasl.SaslException;
-import javax.security.sasl.SaslServer;
-
+import org.apache.qpid.transport.*;
+import org.apache.qpid.server.logging.actors.CurrentActor;
+import org.apache.qpid.server.logging.actors.GenericActor;
+import org.apache.qpid.common.ClientProperties;
import org.apache.qpid.protocol.ProtocolEngine;
+import org.apache.qpid.server.security.SecurityManager;
import org.apache.qpid.server.registry.ApplicationRegistry;
import org.apache.qpid.server.registry.IApplicationRegistry;
-import org.apache.qpid.server.security.SecurityManager;
-import org.apache.qpid.server.security.auth.AuthenticationResult;
-import org.apache.qpid.server.security.auth.AuthenticationResult.AuthenticationStatus;
import org.apache.qpid.server.virtualhost.VirtualHost;
-import org.apache.qpid.transport.*;
+
+import javax.security.sasl.SaslServer;
+import javax.security.sasl.SaslException;
+import java.util.*;
public class ServerConnectionDelegate extends ServerDelegate
{
private String _localFQDN;
private final IApplicationRegistry _appRegistry;
+
public ServerConnectionDelegate(IApplicationRegistry appRegistry, String localFQDN)
{
this(new HashMap<String,Object>(Collections.singletonMap("qpid.federation_tag",appRegistry.getBroker().getFederationTag())), Collections.singletonList((Object)"en_US"), appRegistry, localFQDN);
@@ -72,6 +68,7 @@ public class ServerConnectionDelegate extends ServerDelegate
return list;
}
+ @Override
public ServerSession getSession(Connection conn, SessionAttach atc)
{
SessionDelegate serverSessionDelegate = new ServerSessionDelegate(_appRegistry);
@@ -81,33 +78,14 @@ public class ServerConnectionDelegate extends ServerDelegate
return ssn;
}
+ @Override
protected SaslServer createSaslServer(String mechanism) throws SaslException
{
return _appRegistry.getAuthenticationManager().createSaslServer(mechanism, _localFQDN);
}
- protected void secure(final SaslServer ss, final Connection conn, final byte[] response)
- {
- final AuthenticationResult authResult = _appRegistry.getAuthenticationManager().authenticate(ss, response);
- final ServerConnection sconn = (ServerConnection) conn;
-
-
- if (AuthenticationStatus.SUCCESS.equals(authResult.getStatus()))
- {
- tuneAuthorizedConnection(sconn);
- sconn.setAuthorizedSubject(authResult.getSubject());
- }
- else if (AuthenticationStatus.CONTINUE.equals(authResult.getStatus()))
- {
- connectionAuthContinue(sconn, authResult.getChallenge());
- }
- else
- {
- connectionAuthFailed(sconn, authResult.getCause());
- }
- }
-
+ @Override
public void connectionClose(Connection conn, ConnectionClose close)
{
try
@@ -121,9 +99,10 @@ public class ServerConnectionDelegate extends ServerDelegate
}
+ @Override
public void connectionOpen(Connection conn, ConnectionOpen open)
{
- final ServerConnection sconn = (ServerConnection) conn;
+ ServerConnection sconn = (ServerConnection) conn;
VirtualHost vhost;
String vhostName;
@@ -137,7 +116,7 @@ public class ServerConnectionDelegate extends ServerDelegate
}
vhost = _appRegistry.getVirtualHostRegistry().getVirtualHost(vhostName);
- SecurityManager.setThreadSubject(sconn.getAuthorizedSubject());
+ SecurityManager.setThreadPrincipal(conn.getAuthorizationID());
if(vhost != null)
{
@@ -159,7 +138,6 @@ public class ServerConnectionDelegate extends ServerDelegate
sconn.invoke(new ConnectionClose(ConnectionCloseCode.INVALID_PATH, "Unknown virtualhost '"+vhostName+"'"));
sconn.setState(Connection.State.CLOSING);
}
-
}
@Override
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/transport/ServerSession.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/transport/ServerSession.java
index e9168f71fb..540ad3fffd 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/transport/ServerSession.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/transport/ServerSession.java
@@ -23,25 +23,9 @@ package org.apache.qpid.server.transport;
import static org.apache.qpid.server.logging.subjects.LogSubjectFormat.CHANNEL_FORMAT;
import static org.apache.qpid.util.Serial.gt;
-import java.lang.ref.WeakReference;
-import java.security.Principal;
-import java.text.MessageFormat;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.SortedMap;
-import java.util.UUID;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentSkipListMap;
-import java.util.concurrent.CopyOnWriteArrayList;
-import java.util.concurrent.atomic.AtomicLong;
-
-import javax.security.auth.Subject;
+import com.sun.security.auth.UserPrincipal;
import org.apache.qpid.AMQException;
-import org.apache.qpid.protocol.AMQConstant;
import org.apache.qpid.protocol.ProtocolEngine;
import org.apache.qpid.server.configuration.ConfigStore;
import org.apache.qpid.server.configuration.ConfiguredObject;
@@ -54,18 +38,18 @@ import org.apache.qpid.server.logging.actors.CurrentActor;
import org.apache.qpid.server.logging.actors.GenericActor;
import org.apache.qpid.server.logging.messages.ChannelMessages;
import org.apache.qpid.server.message.ServerMessage;
-import org.apache.qpid.server.protocol.AMQConnectionModel;
-import org.apache.qpid.server.protocol.AMQSessionModel;
import org.apache.qpid.server.queue.AMQQueue;
import org.apache.qpid.server.queue.BaseQueue;
import org.apache.qpid.server.queue.QueueEntry;
-import org.apache.qpid.server.security.AuthorizationHolder;
+import org.apache.qpid.server.security.PrincipalHolder;
import org.apache.qpid.server.store.MessageStore;
import org.apache.qpid.server.subscription.Subscription_0_10;
import org.apache.qpid.server.txn.AutoCommitTransaction;
import org.apache.qpid.server.txn.LocalTransaction;
import org.apache.qpid.server.txn.ServerTransaction;
import org.apache.qpid.server.virtualhost.VirtualHost;
+import org.apache.qpid.server.protocol.AMQSessionModel;
+import org.apache.qpid.server.protocol.AMQConnectionModel;
import org.apache.qpid.transport.Binary;
import org.apache.qpid.transport.Connection;
import org.apache.qpid.transport.MessageTransfer;
@@ -74,13 +58,24 @@ import org.apache.qpid.transport.Range;
import org.apache.qpid.transport.RangeSet;
import org.apache.qpid.transport.Session;
import org.apache.qpid.transport.SessionDelegate;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-public class ServerSession extends Session implements AuthorizationHolder, SessionConfig, AMQSessionModel, LogSubject
+import java.lang.ref.WeakReference;
+import java.security.Principal;
+import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.SortedMap;
+import java.util.UUID;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentSkipListMap;
+import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.concurrent.atomic.AtomicLong;
+
+public class ServerSession extends Session implements PrincipalHolder, SessionConfig, AMQSessionModel, LogSubject
{
- private static final Logger _logger = LoggerFactory.getLogger(ServerSession.class);
-
private static final String NULL_DESTINTATION = UUID.randomUUID().toString();
private final UUID _id;
@@ -116,7 +111,8 @@ public class ServerSession extends Session implements AuthorizationHolder, Sessi
private final AtomicLong _txnCommits = new AtomicLong(0);
private final AtomicLong _txnRejects = new AtomicLong(0);
private final AtomicLong _txnCount = new AtomicLong(0);
- private final AtomicLong _txnUpdateTime = new AtomicLong(0);
+
+ private Principal _principal;
private Map<String, Subscription_0_10> _subscriptions = new ConcurrentHashMap<String, Subscription_0_10>();
@@ -144,8 +140,8 @@ public class ServerSession extends Session implements AuthorizationHolder, Sessi
super(connection, delegate, name, expiry);
_connectionConfig = connConfig;
_transaction = new AutoCommitTransaction(this.getMessageStore());
-
- _reference = new WeakReference<Session>(this);
+ _principal = new UserPrincipal(connection.getAuthorizationID());
+ _reference = new WeakReference(this);
_id = getConfigStore().createId();
getConfigStore().addConfiguredObject(this);
}
@@ -164,8 +160,8 @@ public class ServerSession extends Session implements AuthorizationHolder, Sessi
public void enqueue(final ServerMessage message, final ArrayList<? extends BaseQueue> queues)
{
- getConnectionModel().registerMessageReceived(message.getSize(), message.getArrivalTime());
- _transaction.enqueue(queues,message, new ServerTransaction.Action()
+
+ _transaction.enqueue(queues,message, new ServerTransaction.Action()
{
BaseQueue[] _queues = queues.toArray(new BaseQueue[queues.size()]);
@@ -193,7 +189,6 @@ public class ServerSession extends Session implements AuthorizationHolder, Sessi
});
incrementOutstandingTxnsIfNecessary();
- updateTransactionalActivity();
}
@@ -201,7 +196,6 @@ public class ServerSession extends Session implements AuthorizationHolder, Sessi
Runnable postIdSettingAction)
{
invoke(xfr, postIdSettingAction);
- getConnectionModel().registerMessageDelivered(xfr.getBodySize());
}
public void onMessageDispositionChange(MessageTransfer xfr, MessageDispositionChangeListener acceptListener)
@@ -383,7 +377,6 @@ public class ServerSession extends Session implements AuthorizationHolder, Sessi
entry.release();
}
});
- updateTransactionalActivity();
}
public Collection<Subscription_0_10> getSubscriptions()
@@ -417,7 +410,7 @@ public class ServerSession extends Session implements AuthorizationHolder, Sessi
catch (AMQException e)
{
// TODO
- _logger.error("Failed to unregister subscription", e);
+ e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
}
finally
{
@@ -432,11 +425,6 @@ public class ServerSession extends Session implements AuthorizationHolder, Sessi
// theory
return !(_transaction instanceof AutoCommitTransaction);
}
-
- public boolean inTransaction()
- {
- return isTransactional() && _txnUpdateTime.get() > 0 && _transaction.getTransactionStartTime() > 0;
- }
public void selectTx()
{
@@ -483,17 +471,6 @@ public class ServerSession extends Session implements AuthorizationHolder, Sessi
}
}
- /**
- * Update last transaction activity timestamp
- */
- public void updateTransactionalActivity()
- {
- if (isTransactional())
- {
- _txnUpdateTime.set(System.currentTimeMillis());
- }
- }
-
public Long getTxnStarts()
{
return _txnStarts.get();
@@ -514,14 +491,9 @@ public class ServerSession extends Session implements AuthorizationHolder, Sessi
return _txnCount.get();
}
- public Principal getAuthorizedPrincipal()
- {
- return ((ServerConnection) getConnection()).getAuthorizedPrincipal();
- }
-
- public Subject getAuthorizedSubject()
+ public Principal getPrincipal()
{
- return ((ServerConnection) getConnection()).getAuthorizedSubject();
+ return _principal;
}
public void addSessionCloseTask(Task task)
@@ -634,38 +606,7 @@ public class ServerSession extends Session implements AuthorizationHolder, Sessi
return (LogSubject) this;
}
- public void checkTransactionStatus(long openWarn, long openClose, long idleWarn, long idleClose) throws AMQException
- {
- if (inTransaction())
- {
- long currentTime = System.currentTimeMillis();
- long openTime = currentTime - _transaction.getTransactionStartTime();
- long idleTime = currentTime - _txnUpdateTime.get();
-
- // Log a warning on idle or open transactions
- if (idleWarn > 0L && idleTime > idleWarn)
- {
- CurrentActor.get().message(getLogSubject(), ChannelMessages.IDLE_TXN(openTime));
- _logger.warn("IDLE TRANSACTION ALERT " + getLogSubject().toString() + " " + idleTime + " ms");
- }
- else if (openWarn > 0L && openTime > openWarn)
- {
- CurrentActor.get().message(getLogSubject(), ChannelMessages.OPEN_TXN(openTime));
- _logger.warn("OPEN TRANSACTION ALERT " + getLogSubject().toString() + " " + openTime + " ms");
- }
-
- // Close connection for idle or open transactions that have timed out
- if (idleClose > 0L && idleTime > idleClose)
- {
- getConnectionModel().closeSession(this, AMQConstant.RESOURCE_ERROR, "Idle transaction timed out");
- }
- else if (openClose > 0L && openTime > openClose)
- {
- getConnectionModel().closeSession(this, AMQConstant.RESOURCE_ERROR, "Open transaction timed out");
- }
- }
- }
-
+ @Override
public String toLogString()
{
return "[" +
@@ -676,5 +617,7 @@ public class ServerSession extends Session implements AuthorizationHolder, Sessi
getVirtualHost().getName(),
getChannel())
+ "] ";
+
}
+
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/transport/ServerSessionDelegate.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/transport/ServerSessionDelegate.java
index f316d60c6a..42a3975e24 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/transport/ServerSessionDelegate.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/transport/ServerSessionDelegate.java
@@ -25,23 +25,21 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.Map;
-import org.apache.log4j.Logger;
import org.apache.qpid.AMQException;
import org.apache.qpid.AMQUnknownExchangeType;
+import org.apache.qpid.common.AMQPFilterTypes;
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.ExchangeFactory;
-import org.apache.qpid.server.exchange.ExchangeInUseException;
-import org.apache.qpid.server.exchange.ExchangeRegistry;
-import org.apache.qpid.server.exchange.ExchangeType;
-import org.apache.qpid.server.exchange.HeadersExchange;
+import org.apache.qpid.server.exchange.*;
import org.apache.qpid.server.filter.FilterManager;
import org.apache.qpid.server.filter.FilterManagerFactory;
import org.apache.qpid.server.flow.FlowCreditManager_0_10;
import org.apache.qpid.server.flow.WindowCreditManager;
+import org.apache.qpid.server.logging.actors.CurrentActor;
+import org.apache.qpid.server.logging.actors.GenericActor;
import org.apache.qpid.server.message.MessageMetaData_0_10;
import org.apache.qpid.server.message.MessageTransferMessage;
+import org.apache.qpid.server.protocol.AMQSessionModel;
import org.apache.qpid.server.queue.AMQQueue;
import org.apache.qpid.server.queue.AMQQueueFactory;
import org.apache.qpid.server.queue.BaseQueue;
@@ -97,7 +95,6 @@ import org.apache.qpid.transport.TxSelect;
public class ServerSessionDelegate extends SessionDelegate
{
- private static final Logger LOGGER = Logger.getLogger(ServerSessionDelegate.class);
private final IApplicationRegistry _appRegistry;
public ServerSessionDelegate(IApplicationRegistry appRegistry)
@@ -108,24 +105,16 @@ public class ServerSessionDelegate extends SessionDelegate
@Override
public void command(Session session, Method method)
{
- try
- {
- setThreadSubject(session);
+ SecurityManager.setThreadPrincipal(session.getConnection().getAuthorizationID());
- if(!session.isClosing())
+ if(!session.isClosing())
+ {
+ super.command(session, method);
+ if (method.isSync())
{
- super.command(session, method);
- if (method.isSync())
- {
- session.flushProcessed();
- }
+ session.flushProcessed();
}
}
- catch(RuntimeException e)
- {
- LOGGER.error("Exception processing command", e);
- exception(session, method, ExecutionErrorCode.INTERNAL_ERROR, "Exception processing command: " + e);
- }
}
@Override
@@ -134,6 +123,8 @@ public class ServerSessionDelegate extends SessionDelegate
((ServerSession)session).accept(method.getTransfers());
}
+
+
@Override
public void messageReject(Session session, MessageReject method)
{
@@ -212,33 +203,32 @@ public class ServerSessionDelegate extends SessionDelegate
{
exception(session,method,ExecutionErrorCode.NOT_FOUND, "Queue: " + queueName + " not found");
}
- else if(queue.getAuthorizationHolder() != null && queue.getAuthorizationHolder() != session)
+ else if(queue.getPrincipalHolder() != null && queue.getPrincipalHolder() != session)
{
exception(session,method,ExecutionErrorCode.RESOURCE_LOCKED, "Exclusive Queue: " + queueName + " owned exclusively by another session");
}
else
{
+
if(queue.isExclusive())
{
- ServerSession s = (ServerSession) session;
- queue.setExclusiveOwningSession(s);
- if(queue.getAuthorizationHolder() == null)
+ if(queue.getPrincipalHolder() == null)
{
- queue.setAuthorizationHolder(s);
- queue.setExclusiveOwningSession(s);
+ queue.setPrincipalHolder((ServerSession)session);
((ServerSession) session).addSessionCloseTask(new ServerSession.Task()
{
+
public void doTask(ServerSession session)
{
- if(queue.getAuthorizationHolder() == session)
+ if(queue.getPrincipalHolder() == session)
{
- queue.setAuthorizationHolder(null);
- queue.setExclusiveOwningSession(null);
+ queue.setPrincipalHolder(null);
}
}
});
}
+
}
FlowCreditManager_0_10 creditManager = new WindowCreditManager(0L,0L);
@@ -379,6 +369,7 @@ public class ServerSessionDelegate extends SessionDelegate
}
ssn.processed(xfr);
+
}
@Override
@@ -398,7 +389,7 @@ public class ServerSessionDelegate extends SessionDelegate
((ServerSession)session).unregister(sub);
if(!queue.isDeleted() && queue.isExclusive() && queue.getConsumerCount() == 0)
{
- queue.setAuthorizationHolder(null);
+ queue.setPrincipalHolder(null);
}
}
}
@@ -457,19 +448,6 @@ public class ServerSessionDelegate extends SessionDelegate
VirtualHost virtualHost = getVirtualHost(session);
Exchange exchange = getExchange(session, exchangeName);
- //we must check for any unsupported arguments present and throw not-implemented
- if(method.hasArguments())
- {
- Map<String,Object> args = method.getArguments();
-
- //QPID-3392: currently we don't support any!
- if(!args.isEmpty())
- {
- exception(session, method, ExecutionErrorCode.NOT_IMPLEMENTED, "Unsupported exchange argument(s) found " + args.keySet().toString());
- return;
- }
- }
-
if(method.getPassive())
{
if(exchange == null)
@@ -479,6 +457,7 @@ public class ServerSessionDelegate extends SessionDelegate
}
else
{
+ // TODO - check exchange has same properties
if(!exchange.getTypeShortString().toString().equals(method.getType()))
{
exception(session, method, ExecutionErrorCode.NOT_ALLOWED, "Cannot redeclare with a different exchange type");
@@ -990,10 +969,10 @@ public class ServerSessionDelegate extends SessionDelegate
}
- if (method.hasAutoDelete()
- && method.getAutoDelete()
- && method.hasExclusive()
- && method.getExclusive())
+ if(method.hasAutoDelete()
+ && method.getAutoDelete()
+ && method.hasExclusive()
+ && method.getExclusive())
{
final AMQQueue q = queue;
final ServerSession.Task deleteQueueTask = new ServerSession.Task()
@@ -1020,23 +999,23 @@ public class ServerSessionDelegate extends SessionDelegate
}
});
}
- if (method.hasExclusive()
- && method.getExclusive())
+ else if(method.getExclusive())
{
final AMQQueue q = queue;
final ServerSession.Task removeExclusive = new ServerSession.Task()
{
+
public void doTask(ServerSession session)
{
- q.setAuthorizationHolder(null);
+ q.setPrincipalHolder(null);
q.setExclusiveOwningSession(null);
}
};
final ServerSession s = (ServerSession) session;
- q.setExclusiveOwningSession(s);
s.addSessionCloseTask(removeExclusive);
queue.addQueueDeleteTask(new AMQQueue.Task()
{
+
public void doTask(AMQQueue queue) throws AMQException
{
s.removeSessionCloseTask(removeExclusive);
@@ -1050,7 +1029,7 @@ public class ServerSessionDelegate extends SessionDelegate
}
}
}
- else if (method.getExclusive() && (queue.getExclusiveOwningSession() != null && !queue.getExclusiveOwningSession().equals(session)))
+ else if (method.getExclusive() && (queue.getPrincipalHolder() != null && !queue.getPrincipalHolder().equals(session)))
{
String description = "Cannot declare queue('" + queueName + "'),"
+ " as exclusive queue with same name "
@@ -1098,7 +1077,7 @@ public class ServerSessionDelegate extends SessionDelegate
}
else
{
- if(queue.getAuthorizationHolder() != null && queue.getAuthorizationHolder() != session)
+ if(queue.getPrincipalHolder() != null && queue.getPrincipalHolder() != session)
{
exception(session,method,ExecutionErrorCode.RESOURCE_LOCKED, "Exclusive Queue: " + queueName + " owned exclusively by another session");
}
@@ -1244,8 +1223,6 @@ public class ServerSessionDelegate extends SessionDelegate
@Override
public void closed(Session session)
{
- setThreadSubject(session);
-
for(Subscription_0_10 sub : getSubscriptions(session))
{
((ServerSession)session).unregister(sub);
@@ -1264,9 +1241,4 @@ public class ServerSessionDelegate extends SessionDelegate
return ((ServerSession)session).getSubscriptions();
}
- private void setThreadSubject(Session session)
- {
- final ServerConnection scon = (ServerConnection) session.getConnection();
- SecurityManager.setThreadSubject(scon.getAuthorizedSubject());
- }
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/txn/AutoCommitTransaction.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/txn/AutoCommitTransaction.java
index 36e9d78440..db781ead96 100755
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/txn/AutoCommitTransaction.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/txn/AutoCommitTransaction.java
@@ -50,11 +50,6 @@ public class AutoCommitTransaction implements ServerTransaction
_transactionLog = transactionLog;
}
- public long getTransactionStartTime()
- {
- return 0L;
- }
-
/**
* Since AutoCommitTransaction have no concept of a long lived transaction, any Actions registered
* by the caller are executed immediately.
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/txn/LocalTransaction.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/txn/LocalTransaction.java
index 946dbd7c28..a04c743be1 100755
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/txn/LocalTransaction.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/txn/LocalTransaction.java
@@ -20,23 +20,18 @@ package org.apache.qpid.server.txn;
*
*/
+
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
+import org.apache.log4j.Logger;
import org.apache.qpid.AMQException;
import org.apache.qpid.server.message.EnqueableMessage;
import org.apache.qpid.server.message.ServerMessage;
import org.apache.qpid.server.queue.BaseQueue;
import org.apache.qpid.server.queue.QueueEntry;
import org.apache.qpid.server.store.TransactionLog;
-import org.apache.qpid.server.queue.AMQQueue;
-import org.apache.qpid.server.queue.BaseQueue;
-import org.apache.qpid.server.queue.QueueEntry;
-import org.apache.qpid.server.store.TransactionLog;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
/**
* A concrete implementation of ServerTransaction where enqueue/dequeue
@@ -46,28 +41,17 @@ import org.slf4j.LoggerFactory;
*/
public class LocalTransaction implements ServerTransaction
{
- protected static final Logger _logger = LoggerFactory.getLogger(LocalTransaction.class);
+ protected static final Logger _logger = Logger.getLogger(LocalTransaction.class);
private final List<Action> _postTransactionActions = new ArrayList<Action>();
private volatile TransactionLog.Transaction _transaction;
private TransactionLog _transactionLog;
- private long _txnStartTime = 0L;
public LocalTransaction(TransactionLog transactionLog)
{
_transactionLog = transactionLog;
}
-
- public boolean inTransaction()
- {
- return _transaction != null;
- }
-
- public long getTransactionStartTime()
- {
- return _txnStartTime;
- }
public void addPostTransactionAction(Action postTransactionAction)
{
@@ -105,6 +89,7 @@ public class LocalTransaction implements ServerTransaction
try
{
+
for(QueueEntry entry : queueEntries)
{
ServerMessage message = entry.getMessage();
@@ -128,6 +113,7 @@ public class LocalTransaction implements ServerTransaction
_logger.error("Error during message dequeues", e);
tidyUpOnError(e);
}
+
}
private void tidyUpOnError(Exception e)
@@ -154,7 +140,8 @@ public class LocalTransaction implements ServerTransaction
}
finally
{
- resetDetails();
+ _transaction = null;
+ _postTransactionActions.clear();
}
}
@@ -206,11 +193,6 @@ public class LocalTransaction implements ServerTransaction
{
_postTransactionActions.add(postTransactionAction);
- if (_txnStartTime == 0L)
- {
- _txnStartTime = System.currentTimeMillis();
- }
-
if(message.isPersistent())
{
try
@@ -266,14 +248,17 @@ public class LocalTransaction implements ServerTransaction
}
finally
{
- resetDetails();
+ _transaction = null;
+ _postTransactionActions.clear();
}
+
}
public void rollback()
{
try
{
+
if(_transaction != null)
{
_transaction.abortTran();
@@ -295,15 +280,9 @@ public class LocalTransaction implements ServerTransaction
}
finally
{
- resetDetails();
+ _transaction = null;
+ _postTransactionActions.clear();
}
}
}
-
- private void resetDetails()
- {
- _transaction = null;
- _postTransactionActions.clear();
- _txnStartTime = 0L;
- }
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/txn/ServerTransaction.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/txn/ServerTransaction.java
index b3c6e1ac3a..b61b8a5c64 100755
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/txn/ServerTransaction.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/txn/ServerTransaction.java
@@ -52,13 +52,6 @@ public interface ServerTransaction
public void onRollback();
}
- /**
- * Return the time the current transaction started.
- *
- * @return the time this transaction started or 0 if not in a transaction
- */
- long getTransactionStartTime();
-
/**
* Register an Action for execution after transaction commit or rollback. Actions
* will be executed in the order in which they are registered.
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/virtualhost/HouseKeepingTask.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/virtualhost/HouseKeepingTask.java
index ebace95f65..2db1944cd1 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/virtualhost/HouseKeepingTask.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/virtualhost/HouseKeepingTask.java
@@ -63,10 +63,6 @@ public abstract class HouseKeepingTask implements Runnable
{
_logger.warn(this.getClass().getSimpleName() + " throw exception: " + e, e);
}
- finally
- {
- CurrentActor.remove();
- }
}
public VirtualHost getVirtualHost()
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 04f19b79bb..4ed0507228 100755
--- 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,28 +20,30 @@
*/
package org.apache.qpid.server.virtualhost;
-import java.util.UUID;
-
import org.apache.qpid.common.Closeable;
-import org.apache.qpid.server.binding.BindingFactory;
-import org.apache.qpid.server.configuration.ConfigStore;
-import org.apache.qpid.server.configuration.VirtualHostConfig;
-import org.apache.qpid.server.configuration.VirtualHostConfiguration;
import org.apache.qpid.server.connection.IConnectionRegistry;
-import org.apache.qpid.server.exchange.ExchangeFactory;
-import org.apache.qpid.server.exchange.ExchangeRegistry;
import org.apache.qpid.server.federation.BrokerLink;
-import org.apache.qpid.server.management.ManagedObject;
+import org.apache.qpid.server.configuration.VirtualHostConfiguration;
+import org.apache.qpid.server.configuration.VirtualHostConfig;
+import org.apache.qpid.server.configuration.ConfigStore;
import org.apache.qpid.server.queue.QueueRegistry;
-import org.apache.qpid.server.registry.IApplicationRegistry;
-import org.apache.qpid.server.security.SecurityManager;
-import org.apache.qpid.server.security.auth.manager.AuthenticationManager;
-import org.apache.qpid.server.stats.StatisticsGatherer;
-import org.apache.qpid.server.store.DurableConfigurationStore;
+import org.apache.qpid.server.exchange.ExchangeRegistry;
+import org.apache.qpid.server.exchange.ExchangeFactory;
import org.apache.qpid.server.store.MessageStore;
import org.apache.qpid.server.store.TransactionLog;
+import org.apache.qpid.server.store.DurableConfigurationStore;
+import org.apache.qpid.server.security.SecurityManager;
+import org.apache.qpid.server.security.auth.manager.AuthenticationManager;
+import org.apache.qpid.server.management.ManagedObject;
+import org.apache.qpid.server.registry.IApplicationRegistry;
+import org.apache.qpid.server.binding.BindingFactory;
+
+import java.util.List;
+import java.util.UUID;
+import java.util.TimerTask;
+import java.util.concurrent.FutureTask;
-public interface VirtualHost extends DurableConfigurationStore.Source, VirtualHostConfig, Closeable, StatisticsGatherer
+public interface VirtualHost extends DurableConfigurationStore.Source, VirtualHostConfig, Closeable
{
IConnectionRegistry getConnectionRegistry();
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHostImpl.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHostImpl.java
index 52acd9085b..6ec1c512e5 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHostImpl.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHostImpl.java
@@ -24,18 +24,19 @@ import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
+import java.util.TimerTask;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import javax.management.NotCompliantMBeanException;
-import javax.management.ObjectName;
import org.apache.commons.configuration.Configuration;
import org.apache.commons.configuration.ConfigurationException;
import org.apache.log4j.Logger;
import org.apache.qpid.AMQException;
+import org.apache.qpid.AMQInternalException;
import org.apache.qpid.AMQStoreException;
import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.framing.FieldTable;
@@ -62,8 +63,6 @@ import org.apache.qpid.server.logging.messages.VirtualHostMessages;
import org.apache.qpid.server.logging.subjects.MessageStoreLogSubject;
import org.apache.qpid.server.management.AMQManagedObject;
import org.apache.qpid.server.management.ManagedObject;
-import org.apache.qpid.server.protocol.AMQConnectionModel;
-import org.apache.qpid.server.protocol.AMQSessionModel;
import org.apache.qpid.server.queue.AMQQueue;
import org.apache.qpid.server.queue.AMQQueueFactory;
import org.apache.qpid.server.queue.DefaultQueueRegistry;
@@ -72,7 +71,7 @@ import org.apache.qpid.server.registry.ApplicationRegistry;
import org.apache.qpid.server.registry.IApplicationRegistry;
import org.apache.qpid.server.security.SecurityManager;
import org.apache.qpid.server.security.auth.manager.AuthenticationManager;
-import org.apache.qpid.server.stats.StatisticsCounter;
+import org.apache.qpid.server.security.auth.manager.PrincipalDatabaseAuthenticationManager;
import org.apache.qpid.server.store.ConfigurationRecoveryHandler;
import org.apache.qpid.server.store.DurableConfigurationStore;
import org.apache.qpid.server.store.MessageStore;
@@ -100,7 +99,7 @@ public class VirtualHostImpl implements VirtualHost
private AMQBrokerManagerMBean _brokerMBean;
- private final AuthenticationManager _authenticationManager;
+ private AuthenticationManager _authenticationManager;
private SecurityManager _securityManager;
@@ -112,8 +111,6 @@ public class VirtualHostImpl implements VirtualHost
private BrokerConfig _broker;
private UUID _id;
- private boolean _statisticsEnabled = false;
- private StatisticsCounter _messagesDelivered, _dataDelivered, _messagesReceived, _dataReceived;
private final long _createTime = System.currentTimeMillis();
private final ConcurrentHashMap<BrokerLink,BrokerLink> _links = new ConcurrentHashMap<BrokerLink, BrokerLink>();
@@ -164,12 +161,12 @@ public class VirtualHostImpl implements VirtualHost
public String getObjectInstanceName()
{
- return ObjectName.quote(_name);
+ return _name.toString();
}
public String getName()
{
- return _name;
+ return _name.toString();
}
public VirtualHostImpl getVirtualHost()
@@ -247,13 +244,11 @@ public class VirtualHostImpl implements VirtualHost
initialiseMessageStore(hostConfig);
}
- _authenticationManager = ApplicationRegistry.getInstance().getAuthenticationManager();
+ _authenticationManager = new PrincipalDatabaseAuthenticationManager(_name, _configuration);
_brokerMBean = new AMQBrokerManagerMBean(_virtualHostMBean);
_brokerMBean.register();
initialiseHouseKeeping(hostConfig.getHousekeepingExpiredMessageCheckPeriod());
-
- initialiseStatistics();
}
private void initialiseHouseKeeping(long period)
@@ -286,30 +281,19 @@ public class VirtualHostImpl implements VirtualHost
// house keeping task from running.
}
}
- for (AMQConnectionModel connection : getConnectionRegistry().getConnections())
- {
- _logger.debug("Checking for long running open transactions on connection " + connection);
- for (AMQSessionModel session : connection.getSessionModels())
- {
- _logger.debug("Checking for long running open transactions on session " + session);
- try
- {
- session.checkTransactionStatus(_configuration.getTransactionTimeoutOpenWarn(),
- _configuration.getTransactionTimeoutOpenClose(),
- _configuration.getTransactionTimeoutIdleWarn(),
- _configuration.getTransactionTimeoutIdleClose());
- }
- catch (Exception e)
- {
- _logger.error("Exception in housekeeping for connection: " + connection.toString(), e);
- }
- }
- }
}
}
scheduleHouseKeepingTask(period, new ExpiredMessagesTask(this));
+ class ForceChannelClosuresTask extends TimerTask
+ {
+ public void run()
+ {
+ _connectionRegistry.expireClosedChannels();
+ }
+ }
+
Map<String, VirtualHostPluginFactory> plugins =
ApplicationRegistry.getInstance().getPluginManager().getVirtualHostPlugins();
@@ -643,80 +627,6 @@ public class VirtualHostImpl implements VirtualHost
{
return _bindingFactory;
}
-
- public void registerMessageDelivered(long messageSize)
- {
- if (isStatisticsEnabled())
- {
- _messagesDelivered.registerEvent(1L);
- _dataDelivered.registerEvent(messageSize);
- }
- _appRegistry.registerMessageDelivered(messageSize);
- }
-
- public void registerMessageReceived(long messageSize, long timestamp)
- {
- if (isStatisticsEnabled())
- {
- _messagesReceived.registerEvent(1L, timestamp);
- _dataReceived.registerEvent(messageSize, timestamp);
- }
- _appRegistry.registerMessageReceived(messageSize, timestamp);
- }
-
- public StatisticsCounter getMessageReceiptStatistics()
- {
- return _messagesReceived;
- }
-
- public StatisticsCounter getDataReceiptStatistics()
- {
- return _dataReceived;
- }
-
- public StatisticsCounter getMessageDeliveryStatistics()
- {
- return _messagesDelivered;
- }
-
- public StatisticsCounter getDataDeliveryStatistics()
- {
- return _dataDelivered;
- }
-
- public void resetStatistics()
- {
- _messagesDelivered.reset();
- _dataDelivered.reset();
- _messagesReceived.reset();
- _dataReceived.reset();
-
- for (AMQConnectionModel connection : _connectionRegistry.getConnections())
- {
- connection.resetStatistics();
- }
- }
-
- public void initialiseStatistics()
- {
- setStatisticsEnabled(!StatisticsCounter.DISABLE_STATISTICS &&
- _appRegistry.getConfiguration().isStatisticsGenerationVirtualhostsEnabled());
-
- _messagesDelivered = new StatisticsCounter("messages-delivered-" + getName());
- _dataDelivered = new StatisticsCounter("bytes-delivered-" + getName());
- _messagesReceived = new StatisticsCounter("messages-received-" + getName());
- _dataReceived = new StatisticsCounter("bytes-received-" + getName());
- }
-
- public boolean isStatisticsEnabled()
- {
- return _statisticsEnabled;
- }
-
- public void setStatisticsEnabled(boolean enabled)
- {
- _statisticsEnabled = enabled;
- }
public void createBrokerConnection(final String transport,
final String host,
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/tools/messagestore/MessageStoreTool.java b/qpid/java/broker/src/main/java/org/apache/qpid/tools/messagestore/MessageStoreTool.java
index 2c0ceed80b..dca165fa7e 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/tools/messagestore/MessageStoreTool.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/tools/messagestore/MessageStoreTool.java
@@ -192,7 +192,7 @@ public class MessageStoreTool
if (_initialised)
{
- ApplicationRegistry.remove();
+ ApplicationRegistry.remove(1);
}
_console.println("...exiting");
@@ -274,7 +274,7 @@ public class MessageStoreTool
{
ConfigurationFileApplicationRegistry registry = new ConfigurationFileApplicationRegistry(configFile);
- ApplicationRegistry.remove();
+ ApplicationRegistry.remove(1);
ApplicationRegistry.initialise(registry);
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 806e161bbc..4fd4999b19 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
@@ -364,7 +364,7 @@ public class Show extends AbstractCommand
{
if(msg instanceof AMQMessage)
{
- headers = ((BasicContentHeaderProperties) ((AMQMessage)msg).getContentHeaderBody().getProperties());
+ headers = ((BasicContentHeaderProperties) ((AMQMessage)msg).getContentHeaderBody().properties);
}
}
catch (AMQException e)
diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/BrokerOptionsTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/BrokerOptionsTest.java
deleted file mode 100644
index 63423cbaa7..0000000000
--- a/qpid/java/broker/src/test/java/org/apache/qpid/server/BrokerOptionsTest.java
+++ /dev/null
@@ -1,196 +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;
-
-import static org.apache.qpid.transport.ConnectionSettings.WILDCARD_ADDRESS;
-import static org.apache.qpid.server.configuration.ServerConfiguration.DEFAULT_PORT;
-import static org.apache.qpid.server.configuration.ServerConfiguration.DEFAULT_JMXPORT;
-
-import java.util.Collections;
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.Set;
-
-
-import org.apache.qpid.test.utils.QpidTestCase;
-
-
-public class BrokerOptionsTest extends QpidTestCase
-{
- private BrokerOptions _options;
-
- private static final int TEST_PORT1 = 6789;
- private static final int TEST_PORT2 = 6790;
-
-
- protected void setUp()
- {
- _options = new BrokerOptions();
- }
-
- public void testDefaultPort()
- {
- assertEquals(Collections.<Integer>emptySet(), _options.getPorts());
- }
-
- public void testOverriddenPort()
- {
- _options.addPort(TEST_PORT1);
- assertEquals(Collections.singleton(TEST_PORT1), _options.getPorts());
- }
-
- public void testManyOverriddenPorts()
- {
- _options.addPort(TEST_PORT1);
- _options.addPort(TEST_PORT2);
- final Set<Integer> expectedPorts = new HashSet<Integer>(Arrays.asList(new Integer[] {TEST_PORT1, TEST_PORT2}));
- assertEquals(expectedPorts, _options.getPorts());
- }
-
- public void testDuplicateOverriddenPortsAreSilentlyIgnored()
- {
- _options.addPort(TEST_PORT1);
- _options.addPort(TEST_PORT2);
- _options.addPort(TEST_PORT1); // duplicate - should be silently ignored
- final Set<Integer> expectedPorts = new HashSet<Integer>(Arrays.asList(new Integer[] {TEST_PORT1, TEST_PORT2}));
- assertEquals(expectedPorts, _options.getPorts());
- }
-
- public void testDefaultSSLPort()
- {
- assertEquals(Collections.<Integer>emptySet(), _options.getSSLPorts());
- }
-
- public void testOverriddenSSLPort()
- {
- _options.addSSLPort(TEST_PORT1);
- assertEquals(Collections.singleton(TEST_PORT1), _options.getSSLPorts());
- }
-
- public void testManyOverriddenSSLPorts()
- {
- _options.addSSLPort(TEST_PORT1);
- _options.addSSLPort(TEST_PORT2);
- final Set<Integer> expectedPorts = new HashSet<Integer>(Arrays.asList(new Integer[] {TEST_PORT1, TEST_PORT2}));
- assertEquals(expectedPorts, _options.getSSLPorts());
- }
-
- public void testDuplicateOverriddenSSLPortsAreSilentlyIgnored()
- {
- _options.addSSLPort(TEST_PORT1);
- _options.addSSLPort(TEST_PORT2);
- _options.addSSLPort(TEST_PORT1); // duplicate - should be silently ignored
- final Set<Integer> expectedPorts = new HashSet<Integer>(Arrays.asList(new Integer[] {TEST_PORT1, TEST_PORT2}));
- assertEquals(expectedPorts, _options.getSSLPorts());
- }
-
- public void testDefaultConfigFile()
- {
- assertNull(_options.getConfigFile());
- }
-
- public void testOverriddenConfigFile()
- {
- final String testConfigFile = "etc/mytestconfig.xml";
- _options.setConfigFile(testConfigFile);
- assertEquals(testConfigFile, _options.getConfigFile());
- }
-
- public void testDefaultLogConfigFile()
- {
- assertNull(_options.getLogConfigFile());
- }
-
- public void testOverriddenLogConfigFile()
- {
- final String testLogConfigFile = "etc/mytestlog4j.xml";
- _options.setLogConfigFile(testLogConfigFile);
- assertEquals(testLogConfigFile, _options.getLogConfigFile());
- }
-
- public void testDefaultJmxPort()
- {
- assertNull(_options.getJmxPort());
- }
-
- public void testJmxPort()
- {
- _options.setJmxPort(TEST_PORT1);
- assertEquals(Integer.valueOf(TEST_PORT1), _options.getJmxPort());
- }
-
- public void testQpidHomeExposesSysProperty()
- {
- assertEquals(System.getProperty("QPID_HOME"), _options.getQpidHome());
- }
-
- public void testDefaultExcludesPortFor0_10()
- {
- assertEquals(Collections.EMPTY_SET, _options.getExcludedPorts(ProtocolExclusion.v0_10));
- }
-
- public void testOverriddenExcludesPortFor0_10()
- {
- _options.addExcludedPort(ProtocolExclusion.v0_10, TEST_PORT1);
- assertEquals(Collections.singleton(TEST_PORT1), _options.getExcludedPorts(ProtocolExclusion.v0_10));
- }
-
- public void testManyOverriddenExcludedPortFor0_10()
- {
- _options.addExcludedPort(ProtocolExclusion.v0_10, TEST_PORT1);
- _options.addExcludedPort(ProtocolExclusion.v0_10, TEST_PORT2);
- final Set<Integer> expectedPorts = new HashSet<Integer>(Arrays.asList(new Integer[] {TEST_PORT1, TEST_PORT2}));
- assertEquals(expectedPorts, _options.getExcludedPorts(ProtocolExclusion.v0_10));
- }
-
- public void testDuplicatedOverriddenExcludedPortFor0_10AreSilentlyIgnored()
- {
- _options.addExcludedPort(ProtocolExclusion.v0_10, TEST_PORT1);
- _options.addExcludedPort(ProtocolExclusion.v0_10, TEST_PORT2);
- final Set<Integer> expectedPorts = new HashSet<Integer>(Arrays.asList(new Integer[] {TEST_PORT1, TEST_PORT2}));
- assertEquals(expectedPorts, _options.getExcludedPorts(ProtocolExclusion.v0_10));
- }
-
- public void testDefaultBind()
- {
- assertNull(_options.getBind());
- }
-
- public void testOverriddenBind()
- {
- final String bind = "192.168.0.1";
- _options.setBind(bind);
- assertEquals(bind, _options.getBind());
- }
-
- public void testDefaultLogWatchFrequency()
- {
- assertEquals(0L, _options.getLogWatchFrequency());
- }
-
- public void testOverridenLogWatchFrequency()
- {
- final int myFreq = 10 * 1000;
-
- _options.setLogWatchFrequency(myFreq);
- assertEquals(myFreq, _options.getLogWatchFrequency());
- }
-}
diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/MainTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/MainTest.java
deleted file mode 100644
index 3bb8d33190..0000000000
--- a/qpid/java/broker/src/test/java/org/apache/qpid/server/MainTest.java
+++ /dev/null
@@ -1,143 +0,0 @@
-package org.apache.qpid.server;
-
-import java.util.EnumSet;
-
-import org.apache.qpid.test.utils.QpidTestCase;
-
-/**
- * Test to verify the command line parsing within the Main class, by
- * providing it a series of command line arguments and verifying the
- * BrokerOptions emerging for use in starting the Broker instance.
- */
-public class MainTest extends QpidTestCase
-{
- public void testNoOptionsSpecified()
- {
- BrokerOptions options = startDummyMain("");
-
- assertTrue(options.getPorts().isEmpty());
- assertTrue(options.getSSLPorts().isEmpty());
- assertEquals(null, options.getJmxPort());
- assertEquals(null, options.getConfigFile());
- assertEquals(null, options.getLogConfigFile());
- assertEquals(null, options.getBind());
-
- for(ProtocolExclusion pe : EnumSet.allOf(ProtocolExclusion.class))
- {
- assertEquals(0, options.getExcludedPorts(pe).size());
- }
- }
-
- public void testPortOverriddenSingle()
- {
- BrokerOptions options = startDummyMain("-p 1234");
-
- assertTrue(options.getPorts().contains(1234));
- assertEquals(1, options.getPorts().size());
- assertTrue(options.getSSLPorts().isEmpty());
- }
-
- public void testPortOverriddenMultiple()
- {
- BrokerOptions options = startDummyMain("-p 1234 -p 4321");
-
- assertTrue(options.getPorts().contains(1234));
- assertTrue(options.getPorts().contains(4321));
- assertEquals(2, options.getPorts().size());
- assertTrue(options.getSSLPorts().isEmpty());
- }
-
- public void testSSLPortOverriddenSingle()
- {
- BrokerOptions options = startDummyMain("-s 5678");
-
- assertTrue(options.getSSLPorts().contains(5678));
- assertEquals(1, options.getSSLPorts().size());
- assertTrue(options.getPorts().isEmpty());
- }
-
- public void testSSLPortOverriddenMultiple()
- {
- BrokerOptions options = startDummyMain("-s 5678 -s 8765");
-
- assertTrue(options.getSSLPorts().contains(5678));
- assertTrue(options.getSSLPorts().contains(8765));
- assertEquals(2, options.getSSLPorts().size());
- assertTrue(options.getPorts().isEmpty());
- }
-
- public void testNonSSLandSSLPortsOverridden()
- {
- BrokerOptions options = startDummyMain("-p 5678 -s 8765");
-
- assertTrue(options.getPorts().contains(5678));
- assertTrue(options.getSSLPorts().contains(8765));
- assertEquals(1, options.getPorts().size());
- assertEquals(1, options.getSSLPorts().size());
- }
-
- public void testJMXportOverridden()
- {
- BrokerOptions options = startDummyMain("-m 3456");
-
- assertEquals(Integer.valueOf(3456), options.getJmxPort());
- }
-
- public void testExclude0_10()
- {
- BrokerOptions options = startDummyMain("-p 3456 --exclude-0-10 3456");
-
- assertTrue(options.getPorts().contains(3456));
- assertEquals(1, options.getPorts().size());
- assertTrue(options.getExcludedPorts(ProtocolExclusion.v0_10).contains(3456));
- assertEquals(1, options.getExcludedPorts(ProtocolExclusion.v0_10).size());
- assertEquals(0, options.getExcludedPorts(ProtocolExclusion.v0_9_1).size());
- }
-
- public void testConfig()
- {
- BrokerOptions options = startDummyMain("-c abcd/config.xml");
-
- assertEquals("abcd/config.xml", options.getConfigFile());
- }
-
- public void testLogConfig()
- {
- BrokerOptions options = startDummyMain("-l wxyz/log4j.xml");
-
- assertEquals("wxyz/log4j.xml", options.getLogConfigFile());
- }
-
- public void testLogWatch()
- {
- BrokerOptions options = startDummyMain("-w 9");
-
- assertEquals(9, options.getLogWatchFrequency());
- }
-
- private BrokerOptions startDummyMain(String commandLine)
- {
- return (new TestMain(commandLine.split("\\s"))).getOptions();
- }
-
- private class TestMain extends Main
- {
- private BrokerOptions _options;
-
- public TestMain(String[] args)
- {
- super(args);
- }
-
- @Override
- protected void startBroker(BrokerOptions options)
- {
- _options = options;
- }
-
- public BrokerOptions getOptions()
- {
- return _options;
- }
- }
-}
diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/RunBrokerWithCommand.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/RunBrokerWithCommand.java
new file mode 100644
index 0000000000..59543874b4
--- /dev/null
+++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/RunBrokerWithCommand.java
@@ -0,0 +1,132 @@
+/*
+ * 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;
+
+import org.apache.log4j.Logger;
+import org.apache.log4j.Level;
+
+import java.io.InputStream;
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+import java.io.IOException;
+
+public class RunBrokerWithCommand
+{
+ public static void main(String[] args)
+ {
+ //Start the broker
+ try
+ {
+ String[] fudge = args.clone();
+
+ // Override the first value which is the command we are going to run later.
+ fudge[0] = "-v";
+ new Main(fudge).startup();
+ }
+ catch (Exception e)
+ {
+ System.err.println("Unable to start broker due to: " + e.getMessage());
+
+ e.printStackTrace();
+ exit(1);
+ }
+
+ Logger.getRootLogger().setLevel(Level.ERROR);
+
+ //run command
+ try
+ {
+ Process task = Runtime.getRuntime().exec(args[0]);
+ System.err.println("Started Proccess: " + args[0]);
+
+ InputStream inputStream = task.getInputStream();
+
+ InputStream errorStream = task.getErrorStream();
+
+ Thread out = new Thread(new Outputter("[OUT]", new BufferedReader(new InputStreamReader(inputStream))));
+ Thread err = new Thread(new Outputter("[ERR]", new BufferedReader(new InputStreamReader(errorStream))));
+
+ out.start();
+ err.start();
+
+ out.join();
+ err.join();
+
+ System.err.println("Waiting for process to exit: " + args[0]);
+ task.waitFor();
+ System.err.println("Done Proccess: " + args[0]);
+
+ }
+ catch (IOException e)
+ {
+ System.err.println("Proccess had problems: " + e.getMessage());
+ e.printStackTrace(System.err);
+ exit(1);
+ }
+ catch (InterruptedException e)
+ {
+ System.err.println("Proccess had problems: " + e.getMessage());
+ e.printStackTrace(System.err);
+
+ exit(1);
+ }
+
+
+ exit(0);
+ }
+
+ private static void exit(int i)
+ {
+ Logger.getRootLogger().setLevel(Level.INFO);
+ System.exit(i);
+ }
+
+ static class Outputter implements Runnable
+ {
+
+ BufferedReader reader;
+ String prefix;
+
+ Outputter(String s, BufferedReader r)
+ {
+ prefix = s;
+ reader = r;
+ }
+
+ public void run()
+ {
+ String line;
+ try
+ {
+ while ((line = reader.readLine()) != null)
+ {
+ System.out.println(prefix + line);
+ }
+ }
+ catch (IOException e)
+ {
+ System.out.println("Error occured reading; " + e.getMessage());
+ }
+ }
+
+ }
+
+}
diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/configuration/ServerConfigurationTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/configuration/ServerConfigurationTest.java
index b0893eb53f..718874cf69 100644
--- a/qpid/java/broker/src/test/java/org/apache/qpid/server/configuration/ServerConfigurationTest.java
+++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/configuration/ServerConfigurationTest.java
@@ -20,558 +20,742 @@
*/
package org.apache.qpid.server.configuration;
-import static org.apache.qpid.transport.ConnectionSettings.WILDCARD_ADDRESS;
-
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
+import java.io.RandomAccessFile;
+import java.util.List;
import java.util.Locale;
+import junit.framework.TestCase;
+
import org.apache.commons.configuration.ConfigurationException;
import org.apache.commons.configuration.XMLConfiguration;
import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.server.exchange.Exchange;
+import org.apache.qpid.server.protocol.AMQProtocolEngine;
+import org.apache.qpid.server.protocol.AMQProtocolSession;
import org.apache.qpid.server.registry.ApplicationRegistry;
import org.apache.qpid.server.registry.ConfigurationFileApplicationRegistry;
-import org.apache.qpid.server.util.TestApplicationRegistry;
+import org.apache.qpid.server.util.InternalBrokerBaseCase;
import org.apache.qpid.server.virtualhost.VirtualHost;
import org.apache.qpid.server.virtualhost.VirtualHostRegistry;
-import org.apache.qpid.test.utils.QpidTestCase;
+import org.apache.qpid.transport.TestNetworkDriver;
-public class ServerConfigurationTest extends QpidTestCase
+public class ServerConfigurationTest extends InternalBrokerBaseCase
{
private XMLConfiguration _config = new XMLConfiguration();
- private ServerConfiguration _serverConfig = null;
-
- @Override
- protected void setUp() throws Exception
- {
- super.setUp();
- _serverConfig = new ServerConfiguration(_config);
- ApplicationRegistry.initialise(new TestApplicationRegistry(_serverConfig));
- }
- @Override
- protected void tearDown() throws Exception
- {
- super.tearDown();
- ApplicationRegistry.remove();
- }
public void testSetJMXManagementPort() throws ConfigurationException
{
- _serverConfig.initialise();
- _serverConfig.setJMXManagementPort(23);
- assertEquals(23, _serverConfig.getJMXManagementPort());
+ ServerConfiguration serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
+ serverConfig.setJMXManagementPort(23);
+ assertEquals(23, serverConfig.getJMXManagementPort());
}
public void testGetJMXManagementPort() throws ConfigurationException
{
_config.setProperty("management.jmxport", 42);
- _serverConfig.initialise();
- assertEquals(42, _serverConfig.getJMXManagementPort());
+ ServerConfiguration serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
+ assertEquals(42, serverConfig.getJMXManagementPort());
}
public void testGetPlatformMbeanserver() throws ConfigurationException
{
- _serverConfig.initialise();
- assertEquals(true, _serverConfig.getPlatformMbeanserver());
+ // Check default
+ ServerConfiguration serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
+ assertEquals(true, serverConfig.getPlatformMbeanserver());
// Check value we set
_config.setProperty("management.platform-mbeanserver", false);
- _serverConfig = new ServerConfiguration(_config);
- _serverConfig.initialise();
- assertEquals(false, _serverConfig.getPlatformMbeanserver());
+ serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
+ assertEquals(false, serverConfig.getPlatformMbeanserver());
}
public void testGetPluginDirectory() throws ConfigurationException
{
// Check default
- _serverConfig.initialise();
- assertEquals(null, _serverConfig.getPluginDirectory());
+ ServerConfiguration serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
+ assertEquals(null, serverConfig.getPluginDirectory());
// Check value we set
_config.setProperty("plugin-directory", "/path/to/plugins");
- _serverConfig = new ServerConfiguration(_config);
- _serverConfig.initialise();
- assertEquals("/path/to/plugins", _serverConfig.getPluginDirectory());
+ serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
+ assertEquals("/path/to/plugins", serverConfig.getPluginDirectory());
}
public void testGetCacheDirectory() throws ConfigurationException
{
// Check default
- _serverConfig.initialise();
- assertEquals(null, _serverConfig.getCacheDirectory());
+ ServerConfiguration serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
+ assertEquals(null, serverConfig.getCacheDirectory());
// Check value we set
_config.setProperty("cache-directory", "/path/to/cache");
- _serverConfig = new ServerConfiguration(_config);
- _serverConfig.initialise();
- assertEquals("/path/to/cache", _serverConfig.getCacheDirectory());
+ serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
+ assertEquals("/path/to/cache", serverConfig.getCacheDirectory());
+ }
+
+ public void testGetPrincipalDatabaseNames() throws ConfigurationException
+ {
+ // Check default
+ ServerConfiguration serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
+ 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);
+ serverConfig.initialise();
+ 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);
+ serverConfig.initialise();
+ 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);
+ serverConfig.initialise();
+ 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);
+ serverConfig.initialise();
+ 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);
+ serverConfig.initialise();
+ 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);
+ serverConfig.initialise();
+ 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);
+ serverConfig.initialise();
+ 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);
+ serverConfig.initialise();
+ 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);
+ serverConfig.initialise();
+ 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
- _serverConfig.initialise();
- assertEquals(65536, _serverConfig.getFrameSize());
+ ServerConfiguration serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
+ assertEquals(65536, serverConfig.getFrameSize());
// Check value we set
_config.setProperty("advanced.framesize", "23");
- _serverConfig = new ServerConfiguration(_config);
- _serverConfig.initialise();
- assertEquals(23, _serverConfig.getFrameSize());
+ serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
+ assertEquals(23, serverConfig.getFrameSize());
+ }
+
+ public void testGetProtectIOEnabled() throws ConfigurationException
+ {
+ // Check default
+ ServerConfiguration serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
+ assertEquals(false, serverConfig.getProtectIOEnabled());
+
+ // Check value we set
+ _config.setProperty(ServerConfiguration.CONNECTOR_PROTECTIO_ENABLED, true);
+ serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
+ assertEquals(true, serverConfig.getProtectIOEnabled());
+ }
+
+ public void testGetBufferReadLimit() throws ConfigurationException
+ {
+ // Check default
+ ServerConfiguration serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
+ assertEquals(262144, serverConfig.getBufferReadLimit());
+
+ // Check value we set
+ _config.setProperty(ServerConfiguration.CONNECTOR_PROTECTIO_READ_BUFFER_LIMIT_SIZE, 23);
+ serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
+ assertEquals(23, serverConfig.getBufferReadLimit());
}
+ public void testGetBufferWriteLimit() throws ConfigurationException
+ {
+ // Check default
+ ServerConfiguration serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
+ assertEquals(262144, serverConfig.getBufferWriteLimit());
+
+ // Check value we set
+ _config.setProperty(ServerConfiguration.CONNECTOR_PROTECTIO_WRITE_BUFFER_LIMIT_SIZE, 23);
+ serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
+ assertEquals(23, serverConfig.getBufferWriteLimit());
+ }
+
+
public void testGetStatusEnabled() throws ConfigurationException
{
// Check default
- _serverConfig.initialise();
+ ServerConfiguration serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
assertEquals(ServerConfiguration.DEFAULT_STATUS_UPDATES.equalsIgnoreCase("on"),
- _serverConfig.getStatusUpdatesEnabled());
+ serverConfig.getStatusUpdatesEnabled());
// Check disabling we set
_config.setProperty(ServerConfiguration.STATUS_UPDATES, "off");
- _serverConfig = new ServerConfiguration(_config);
- _serverConfig.initialise();
- assertEquals(false, _serverConfig.getStatusUpdatesEnabled());
+ serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
+ assertEquals(false, serverConfig.getStatusUpdatesEnabled());
// Check invalid values don't cause error but result in disabled
_config.setProperty(ServerConfiguration.STATUS_UPDATES, "Yes Please");
- _serverConfig = new ServerConfiguration(_config);
- _serverConfig.initialise();
- assertEquals(false, _serverConfig.getStatusUpdatesEnabled());
+ serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
+ assertEquals(false, serverConfig.getStatusUpdatesEnabled());
}
public void testGetSynchedClocks() throws ConfigurationException
{
// Check default
- _serverConfig.initialise();
- assertEquals(false, _serverConfig.getSynchedClocks());
+ ServerConfiguration serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
+ assertEquals(false, serverConfig.getSynchedClocks());
// Check value we set
_config.setProperty("advanced.synced-clocks", true);
- _serverConfig = new ServerConfiguration(_config);
- _serverConfig.initialise();
- assertEquals(true, _serverConfig.getSynchedClocks());
+ serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
+ assertEquals(true, serverConfig.getSynchedClocks());
}
public void testGetLocale() throws ConfigurationException
{
// Check default
- _serverConfig.initialise();
+ ServerConfiguration serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
// The Default is what ever the VMs default is
Locale defaultLocale = Locale.getDefault();
- assertEquals(defaultLocale, _serverConfig.getLocale());
+ assertEquals(defaultLocale, serverConfig.getLocale());
//Test Language only
Locale update = new Locale("es");
_config.setProperty(ServerConfiguration.ADVANCED_LOCALE, "es");
- _serverConfig = new ServerConfiguration(_config);
- _serverConfig.initialise();
- assertEquals(update, _serverConfig.getLocale());
+ serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
+ assertEquals(update, serverConfig.getLocale());
//Test Language and Country
update = new Locale("es","ES");
_config.setProperty(ServerConfiguration.ADVANCED_LOCALE, "es_ES");
- _serverConfig = new ServerConfiguration(_config);
- _serverConfig.initialise();
- assertEquals(update, _serverConfig.getLocale());
+ serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
+ assertEquals(update, serverConfig.getLocale());
//Test Language and Country and Variant
update = new Locale("es","ES", "Traditional_WIN");
_config.setProperty(ServerConfiguration.ADVANCED_LOCALE, "es_ES_Traditional_WIN");
- _serverConfig = new ServerConfiguration(_config);
- _serverConfig.initialise();
- assertEquals(update, _serverConfig.getLocale());
+ serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
+ assertEquals(update, serverConfig.getLocale());
}
public void testGetMsgAuth() throws ConfigurationException
{
// Check default
- _serverConfig.initialise();
- assertEquals(false, _serverConfig.getMsgAuth());
+ ServerConfiguration serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
+ assertEquals(false, serverConfig.getMsgAuth());
// Check value we set
_config.setProperty("security.msg-auth", true);
- _serverConfig = new ServerConfiguration(_config);
- _serverConfig.initialise();
- assertEquals(true, _serverConfig.getMsgAuth());
+ serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
+ assertEquals(true, serverConfig.getMsgAuth());
+ }
+
+ public void testGetJMXPrincipalDatabase() throws ConfigurationException
+ {
+ // Check default
+ ServerConfiguration serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
+ assertEquals(null, serverConfig.getJMXPrincipalDatabase());
+
+ // Check value we set
+ _config.setProperty("security.jmx.principal-database", "a");
+ serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
+ assertEquals("a", serverConfig.getJMXPrincipalDatabase());
}
public void testGetManagementKeyStorePath() throws ConfigurationException
{
// Check default
- _serverConfig.initialise();
- assertEquals(null, _serverConfig.getManagementKeyStorePath());
+ ServerConfiguration serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
+ assertEquals(null, serverConfig.getManagementKeyStorePath());
// Check value we set
_config.setProperty("management.ssl.keyStorePath", "a");
- _serverConfig = new ServerConfiguration(_config);
- _serverConfig.initialise();
- assertEquals("a", _serverConfig.getManagementKeyStorePath());
+ serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
+ assertEquals("a", serverConfig.getManagementKeyStorePath());
}
public void testGetManagementSSLEnabled() throws ConfigurationException
{
// Check default
- _serverConfig.initialise();
- assertEquals(true, _serverConfig.getManagementSSLEnabled());
+ ServerConfiguration serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
+ assertEquals(true, serverConfig.getManagementSSLEnabled());
// Check value we set
_config.setProperty("management.ssl.enabled", false);
- _serverConfig = new ServerConfiguration(_config);
- _serverConfig.initialise();
- assertEquals(false, _serverConfig.getManagementSSLEnabled());
+ serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
+ assertEquals(false, serverConfig.getManagementSSLEnabled());
}
public void testGetManagementKeyStorePassword() throws ConfigurationException
{
// Check default
- _serverConfig.initialise();
- assertEquals(null, _serverConfig.getManagementKeyStorePassword());
+ ServerConfiguration serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
+ assertEquals(null, serverConfig.getManagementKeyStorePassword());
// Check value we set
_config.setProperty("management.ssl.keyStorePassword", "a");
- _serverConfig = new ServerConfiguration(_config);
- _serverConfig.initialise();
- assertEquals("a", _serverConfig.getManagementKeyStorePassword());
+ serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
+ assertEquals("a", serverConfig.getManagementKeyStorePassword());
}
public void testGetQueueAutoRegister() throws ConfigurationException
{
// Check default
- _serverConfig.initialise();
- assertEquals(true, _serverConfig.getQueueAutoRegister());
+ ServerConfiguration serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
+ assertEquals(true, serverConfig.getQueueAutoRegister());
// Check value we set
_config.setProperty("queue.auto_register", false);
- _serverConfig = new ServerConfiguration(_config);
- _serverConfig.initialise();
- assertEquals(false, _serverConfig.getQueueAutoRegister());
+ serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
+ assertEquals(false, serverConfig.getQueueAutoRegister());
}
public void testGetManagementEnabled() throws ConfigurationException
{
// Check default
- _serverConfig.initialise();
- assertEquals(true, _serverConfig.getManagementEnabled());
+ ServerConfiguration serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
+ assertEquals(true, serverConfig.getManagementEnabled());
// Check value we set
_config.setProperty("management.enabled", false);
- _serverConfig = new ServerConfiguration(_config);
- _serverConfig.initialise();
- assertEquals(false, _serverConfig.getManagementEnabled());
+ serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
+ assertEquals(false, serverConfig.getManagementEnabled());
}
public void testSetManagementEnabled() throws ConfigurationException
{
// Check value we set
- _serverConfig.initialise();
- _serverConfig.setManagementEnabled(false);
- assertEquals(false, _serverConfig.getManagementEnabled());
+ ServerConfiguration serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
+ serverConfig.setManagementEnabled(false);
+ assertEquals(false, serverConfig.getManagementEnabled());
}
public void testGetHeartBeatDelay() throws ConfigurationException
{
// Check default
- _serverConfig.initialise();
- assertEquals(5, _serverConfig.getHeartBeatDelay());
+ ServerConfiguration serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
+ assertEquals(5, serverConfig.getHeartBeatDelay());
// Check value we set
_config.setProperty("heartbeat.delay", 23);
- _serverConfig = new ServerConfiguration(_config);
- _serverConfig.initialise();
- assertEquals(23, _serverConfig.getHeartBeatDelay());
+ serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
+ assertEquals(23, serverConfig.getHeartBeatDelay());
}
public void testGetHeartBeatTimeout() throws ConfigurationException
{
// Check default
- _serverConfig.initialise();
- assertEquals(2.0, _serverConfig.getHeartBeatTimeout());
+ ServerConfiguration serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
+ assertEquals(2.0, serverConfig.getHeartBeatTimeout());
// Check value we set
_config.setProperty("heartbeat.timeoutFactor", 2.3);
- _serverConfig = new ServerConfiguration(_config);
- _serverConfig.initialise();
- assertEquals(2.3, _serverConfig.getHeartBeatTimeout());
+ serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
+ assertEquals(2.3, serverConfig.getHeartBeatTimeout());
}
public void testGetMaximumMessageAge() throws ConfigurationException
{
// Check default
- _serverConfig.initialise();
- assertEquals(0, _serverConfig.getMaximumMessageAge());
+ ServerConfiguration serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
+ assertEquals(0, serverConfig.getMaximumMessageAge());
// Check value we set
_config.setProperty("maximumMessageAge", 10L);
- _serverConfig = new ServerConfiguration(_config);
- _serverConfig.initialise();
- assertEquals(10, _serverConfig.getMaximumMessageAge());
+ serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
+ assertEquals(10, serverConfig.getMaximumMessageAge());
}
public void testGetMaximumMessageCount() throws ConfigurationException
{
// Check default
- _serverConfig.initialise();
- assertEquals(0, _serverConfig.getMaximumMessageCount());
+ ServerConfiguration serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
+ assertEquals(0, serverConfig.getMaximumMessageCount());
// Check value we set
_config.setProperty("maximumMessageCount", 10L);
- _serverConfig = new ServerConfiguration(_config);
- _serverConfig.initialise();
- assertEquals(10, _serverConfig.getMaximumMessageCount());
+ serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
+ assertEquals(10, serverConfig.getMaximumMessageCount());
}
public void testGetMaximumQueueDepth() throws ConfigurationException
{
// Check default
- _serverConfig.initialise();
- assertEquals(0, _serverConfig.getMaximumQueueDepth());
+ ServerConfiguration serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
+ assertEquals(0, serverConfig.getMaximumQueueDepth());
// Check value we set
_config.setProperty("maximumQueueDepth", 10L);
- _serverConfig = new ServerConfiguration(_config);
- _serverConfig.initialise();
- assertEquals(10, _serverConfig.getMaximumQueueDepth());
+ serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
+ assertEquals(10, serverConfig.getMaximumQueueDepth());
}
public void testGetMaximumMessageSize() throws ConfigurationException
{
// Check default
- _serverConfig.initialise();
- assertEquals(0, _serverConfig.getMaximumMessageSize());
+ ServerConfiguration serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
+ assertEquals(0, serverConfig.getMaximumMessageSize());
// Check value we set
_config.setProperty("maximumMessageSize", 10L);
- _serverConfig = new ServerConfiguration(_config);
- _serverConfig.initialise();
- assertEquals(10, _serverConfig.getMaximumMessageSize());
+ serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
+ assertEquals(10, serverConfig.getMaximumMessageSize());
}
public void testGetMinimumAlertRepeatGap() throws ConfigurationException
{
// Check default
- _serverConfig.initialise();
- assertEquals(0, _serverConfig.getMinimumAlertRepeatGap());
+ ServerConfiguration serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
+ assertEquals(0, serverConfig.getMinimumAlertRepeatGap());
// Check value we set
_config.setProperty("minimumAlertRepeatGap", 10L);
- _serverConfig = new ServerConfiguration(_config);
- _serverConfig.initialise();
- assertEquals(10, _serverConfig.getMinimumAlertRepeatGap());
+ serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
+ assertEquals(10, serverConfig.getMinimumAlertRepeatGap());
}
public void testGetProcessors() throws ConfigurationException
{
// Check default
- _serverConfig.initialise();
- assertEquals(4, _serverConfig.getConnectorProcessors());
+ ServerConfiguration serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
+ assertEquals(4, serverConfig.getProcessors());
// Check value we set
_config.setProperty("connector.processors", 10);
- _serverConfig = new ServerConfiguration(_config);
- _serverConfig.initialise();
- assertEquals(10, _serverConfig.getConnectorProcessors());
- }
+ serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
+ assertEquals(10, serverConfig.getProcessors());
+ }
- public void testGetPorts() throws ConfigurationException
+ public void testGetPort() throws ConfigurationException
{
// Check default
- _serverConfig.initialise();
- assertNotNull(_serverConfig.getPorts());
- assertEquals(1, _serverConfig.getPorts().size());
- assertEquals(5672, _serverConfig.getPorts().get(0));
+ ServerConfiguration serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
+ assertNotNull(serverConfig.getPorts());
+ assertEquals(1, serverConfig.getPorts().size());
+ assertEquals(5672, serverConfig.getPorts().get(0));
// Check value we set
_config.setProperty("connector.port", "10");
- _serverConfig = new ServerConfiguration(_config);
- _serverConfig.initialise();
- assertNotNull(_serverConfig.getPorts());
- assertEquals(1, _serverConfig.getPorts().size());
- assertEquals("10", _serverConfig.getPorts().get(0));
+ serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
+ assertNotNull(serverConfig.getPorts());
+ assertEquals(1, serverConfig.getPorts().size());
+ assertEquals("10", serverConfig.getPorts().get(0));
}
public void testGetBind() throws ConfigurationException
{
// Check default
- _serverConfig.initialise();
- assertEquals(WILDCARD_ADDRESS, _serverConfig.getBind());
+ ServerConfiguration serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
+ assertEquals("wildcard", serverConfig.getBind());
// Check value we set
_config.setProperty("connector.bind", "a");
- _serverConfig = new ServerConfiguration(_config);
- _serverConfig.initialise();
- assertEquals("a", _serverConfig.getBind());
+ serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
+ assertEquals("a", serverConfig.getBind());
}
public void testGetReceiveBufferSize() throws ConfigurationException
{
// Check default
- _serverConfig.initialise();
- assertEquals(ServerConfiguration.DEFAULT_BUFFER_SIZE, _serverConfig.getReceiveBufferSize());
+ ServerConfiguration serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
+ assertEquals(32767, serverConfig.getReceiveBufferSize());
// Check value we set
_config.setProperty("connector.socketReceiveBuffer", "23");
- _serverConfig = new ServerConfiguration(_config);
- _serverConfig.initialise();
- assertEquals(23, _serverConfig.getReceiveBufferSize());
+ serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
+ assertEquals(23, serverConfig.getReceiveBufferSize());
}
public void testGetWriteBufferSize() throws ConfigurationException
{
// Check default
- _serverConfig.initialise();
- assertEquals(ServerConfiguration.DEFAULT_BUFFER_SIZE, _serverConfig.getWriteBufferSize());
+ ServerConfiguration serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
+ assertEquals(32767, serverConfig.getWriteBufferSize());
// Check value we set
_config.setProperty("connector.socketWriteBuffer", "23");
- _serverConfig = new ServerConfiguration(_config);
- _serverConfig.initialise();
- assertEquals(23, _serverConfig.getWriteBufferSize());
+ serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
+ assertEquals(23, serverConfig.getWriteBufferSize());
}
public void testGetTcpNoDelay() throws ConfigurationException
{
// Check default
- _serverConfig.initialise();
- assertEquals(true, _serverConfig.getTcpNoDelay());
+ ServerConfiguration serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
+ assertEquals(true, serverConfig.getTcpNoDelay());
// Check value we set
_config.setProperty("connector.tcpNoDelay", false);
- _serverConfig = new ServerConfiguration(_config);
- _serverConfig.initialise();
- assertEquals(false, _serverConfig.getTcpNoDelay());
+ serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
+ assertEquals(false, serverConfig.getTcpNoDelay());
}
public void testGetEnableExecutorPool() throws ConfigurationException
{
// Check default
- _serverConfig.initialise();
- assertEquals(false, _serverConfig.getEnableExecutorPool());
+ ServerConfiguration serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
+ assertEquals(false, serverConfig.getEnableExecutorPool());
// Check value we set
_config.setProperty("advanced.filterchain[@enableExecutorPool]", true);
- _serverConfig = new ServerConfiguration(_config);
- _serverConfig.initialise();
- assertEquals(true, _serverConfig.getEnableExecutorPool());
+ serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
+ assertEquals(true, serverConfig.getEnableExecutorPool());
}
public void testGetEnableSSL() throws ConfigurationException
{
// Check default
- _serverConfig.initialise();
- assertEquals(false, _serverConfig.getEnableSSL());
+ ServerConfiguration serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
+ assertEquals(false, serverConfig.getEnableSSL());
// Check value we set
_config.setProperty("connector.ssl.enabled", true);
- _serverConfig = new ServerConfiguration(_config);
- _serverConfig.initialise();
- assertEquals(true, _serverConfig.getEnableSSL());
+ serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
+ assertEquals(true, serverConfig.getEnableSSL());
}
public void testGetSSLOnly() throws ConfigurationException
{
// Check default
- _serverConfig.initialise();
- assertEquals(false, _serverConfig.getSSLOnly());
+ ServerConfiguration serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
+ assertEquals(false, serverConfig.getSSLOnly());
// Check value we set
_config.setProperty("connector.ssl.sslOnly", true);
- _serverConfig = new ServerConfiguration(_config);
- _serverConfig.initialise();
- assertEquals(true, _serverConfig.getSSLOnly());
+ serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
+ assertEquals(true, serverConfig.getSSLOnly());
}
- public void testGetSSLPorts() throws ConfigurationException
+ public void testGetSSLPort() throws ConfigurationException
{
// Check default
- _serverConfig.initialise();
- assertNotNull(_serverConfig.getSSLPorts());
- assertEquals(1, _serverConfig.getSSLPorts().size());
- assertEquals(ServerConfiguration.DEFAULT_SSL_PORT, _serverConfig.getSSLPorts().get(0));
-
+ ServerConfiguration serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
+ assertEquals(8672, serverConfig.getSSLPort());
// Check value we set
- _config.setProperty("connector.ssl.port", "10");
- _serverConfig = new ServerConfiguration(_config);
- _serverConfig.initialise();
- assertNotNull(_serverConfig.getSSLPorts());
- assertEquals(1, _serverConfig.getSSLPorts().size());
- assertEquals("10", _serverConfig.getSSLPorts().get(0));
+ _config.setProperty("connector.ssl.port", 23);
+ serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
+ assertEquals(23, serverConfig.getSSLPort());
}
public void testGetKeystorePath() throws ConfigurationException
{
// Check default
- _serverConfig.initialise();
- assertEquals("none", _serverConfig.getKeystorePath());
+ ServerConfiguration serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
+ assertEquals("none", serverConfig.getKeystorePath());
// Check value we set
_config.setProperty("connector.ssl.keystorePath", "a");
- _serverConfig = new ServerConfiguration(_config);
- _serverConfig.initialise();
- assertEquals("a", _serverConfig.getKeystorePath());
+ serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
+ assertEquals("a", serverConfig.getKeystorePath());
}
public void testGetKeystorePassword() throws ConfigurationException
{
// Check default
- _serverConfig.initialise();
- assertEquals("none", _serverConfig.getKeystorePassword());
+ ServerConfiguration serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
+ assertEquals("none", serverConfig.getKeystorePassword());
// Check value we set
_config.setProperty("connector.ssl.keystorePassword", "a");
- _serverConfig = new ServerConfiguration(_config);
- _serverConfig.initialise();
- assertEquals("a", _serverConfig.getKeystorePassword());
+ serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
+ assertEquals("a", serverConfig.getKeystorePassword());
}
public void testGetCertType() throws ConfigurationException
{
// Check default
- _serverConfig.initialise();
- assertEquals("SunX509", _serverConfig.getCertType());
+ ServerConfiguration serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
+ assertEquals("SunX509", serverConfig.getCertType());
// Check value we set
_config.setProperty("connector.ssl.certType", "a");
- _serverConfig = new ServerConfiguration(_config);
- _serverConfig.initialise();
- assertEquals("a", _serverConfig.getCertType());
+ serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
+ assertEquals("a", serverConfig.getCertType());
+ }
+
+ public void testGetQpidNIO() throws ConfigurationException
+ {
+ // Check default
+ ServerConfiguration serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
+ assertEquals(false, serverConfig.getQpidNIO());
+
+ // Check value we set
+ _config.setProperty("connector.qpidnio", true);
+ serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
+ assertEquals(true, serverConfig.getQpidNIO());
}
public void testGetUseBiasedWrites() throws ConfigurationException
{
// Check default
- _serverConfig.initialise();
- assertEquals(false, _serverConfig.getUseBiasedWrites());
+ ServerConfiguration serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
+ assertEquals(false, serverConfig.getUseBiasedWrites());
// Check value we set
_config.setProperty("advanced.useWriteBiasedPool", true);
- _serverConfig = new ServerConfiguration(_config);
- _serverConfig.initialise();
- assertEquals(true, _serverConfig.getUseBiasedWrites());
+ serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
+ assertEquals(true, serverConfig.getUseBiasedWrites());
}
public void testGetHousekeepingExpiredMessageCheckPeriod() throws ConfigurationException
{
// Check default
- _serverConfig.initialise();
- assertEquals(30000, _serverConfig.getHousekeepingCheckPeriod());
+ ServerConfiguration serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
+ assertEquals(30000, serverConfig.getHousekeepingCheckPeriod());
// Check value we set
_config.setProperty("housekeeping.expiredMessageCheckPeriod", 23L);
- _serverConfig = new ServerConfiguration(_config);
- _serverConfig.initialise();
- assertEquals(23, _serverConfig.getHousekeepingCheckPeriod());
- _serverConfig.setHousekeepingExpiredMessageCheckPeriod(42L);
- assertEquals(42, _serverConfig.getHousekeepingCheckPeriod());
+ serverConfig = new ServerConfiguration(_config);
+ serverConfig.initialise();
+ assertEquals(23, serverConfig.getHousekeepingCheckPeriod());
+ serverConfig.setHousekeepingExpiredMessageCheckPeriod(42L);
+ assertEquals(42, serverConfig.getHousekeepingCheckPeriod());
}
public void testSingleConfiguration() throws IOException, ConfigurationException
@@ -583,7 +767,7 @@ public class ServerConfigurationTest extends QpidTestCase
out.close();
ServerConfiguration conf = new ServerConfiguration(fileA);
conf.initialise();
- assertEquals("4235", conf.getSSLPorts().get(0));
+ assertEquals(4235, conf.getSSLPort());
}
public void testCombinedConfiguration() throws IOException, ConfigurationException
@@ -608,17 +792,19 @@ public class ServerConfigurationTest extends QpidTestCase
out.close();
out = new FileWriter(fileB);
- out.write("<broker><connector><ssl><port>2345</port></ssl></connector></broker>");
+ out.write("<broker><connector><ssl><port>2345</port></ssl><qpidnio>true</qpidnio></connector></broker>");
out.close();
ServerConfiguration config = new ServerConfiguration(mainFile.getAbsoluteFile());
config.initialise();
- assertEquals("4235", config.getSSLPorts().get(0)); // From first file, not
+ assertEquals(4235, config.getSSLPort()); // From first file, not
// overriden by second
assertNotNull(config.getPorts());
assertEquals(1, config.getPorts().size());
assertEquals("2342", config.getPorts().get(0)); // From the first file, not
// present in the second
+ assertEquals(true, config.getQpidNIO()); // From the second file, not
+ // present in the first
}
public void testVariableInterpolation() throws Exception
@@ -649,8 +835,9 @@ public class ServerConfigurationTest extends QpidTestCase
out.write("<broker>\n");
out.write("\t<management><enabled>false</enabled></management>\n");
out.write("\t<security>\n");
- out.write("\t\t<pd-auth-manager>\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");
@@ -659,7 +846,11 @@ public class ServerConfigurationTest extends QpidTestCase
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</pd-auth-manager>\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<rule access=\""+ ((allow) ? "allow" : "deny") +"\" network=\"127.0.0.1\"/>");
out.write("\t\t</firewall>\n");
@@ -695,8 +886,9 @@ public class ServerConfigurationTest extends QpidTestCase
out.write("<broker>\n");
out.write("\t<management><enabled>false</enabled></management>\n");
out.write("\t<security>\n");
- out.write("\t\t<pd-auth-manager>\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");
@@ -705,7 +897,11 @@ public class ServerConfigurationTest extends QpidTestCase
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</pd-auth-manager>\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<rule access=\"allow\" network=\"127.0.0.1\"/>");
out.write("\t\t</firewall>\n");
@@ -796,8 +992,9 @@ public class ServerConfigurationTest extends QpidTestCase
out.write("<broker>\n");
out.write("\t<management><enabled>false</enabled></management>\n");
out.write("\t<security>\n");
- out.write("\t\t<pd-auth-manager>\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");
@@ -806,7 +1003,11 @@ public class ServerConfigurationTest extends QpidTestCase
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</pd-auth-manager>\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<rule access=\"allow\" network=\"127.0.0.1\"/>");
out.write("\t\t</firewall>\n");
@@ -843,9 +1044,8 @@ public class ServerConfigurationTest extends QpidTestCase
writeConfigFile(mainFile, false, true, null, "test");
// Load config
- ApplicationRegistry.remove();
ApplicationRegistry reg = new ConfigurationFileApplicationRegistry(mainFile);
- ApplicationRegistry.initialise(reg);
+ ApplicationRegistry.initialise(reg, 1);
// Test config
VirtualHostRegistry virtualHostRegistry = reg.getVirtualHostRegistry();
@@ -876,9 +1076,8 @@ public class ServerConfigurationTest extends QpidTestCase
writeVirtualHostsFile(vhostsFile, "test");
// Load config
- ApplicationRegistry.remove();
ApplicationRegistry reg = new ConfigurationFileApplicationRegistry(mainFile);
- ApplicationRegistry.initialise(reg);
+ ApplicationRegistry.initialise(reg, 1);
// Test config
VirtualHostRegistry virtualHostRegistry = reg.getVirtualHostRegistry();
@@ -911,9 +1110,8 @@ public class ServerConfigurationTest extends QpidTestCase
writeConfigFile(mainFile, false, false, vhostsFile, null);
// Load config
- ApplicationRegistry.remove();
ApplicationRegistry reg = new ConfigurationFileApplicationRegistry(mainFile);
- ApplicationRegistry.initialise(reg);
+ ApplicationRegistry.initialise(reg, 1);
// Test config
VirtualHostRegistry virtualHostRegistry = reg.getVirtualHostRegistry();
@@ -955,10 +1153,9 @@ public class ServerConfigurationTest extends QpidTestCase
// Load config
try
- {
- ApplicationRegistry.remove();
+ {
ApplicationRegistry reg = new ConfigurationFileApplicationRegistry(mainFile);
- ApplicationRegistry.initialise(reg);
+ ApplicationRegistry.initialise(reg, 1);
fail("Different virtualhost XML configurations not allowed");
}
catch (ConfigurationException ce)
@@ -991,9 +1188,8 @@ public class ServerConfigurationTest extends QpidTestCase
// Load config
try
{
- ApplicationRegistry.remove();
ApplicationRegistry reg = new ConfigurationFileApplicationRegistry(mainFile);
- ApplicationRegistry.initialise(reg);
+ ApplicationRegistry.initialise(reg, 1);
fail("Multiple virtualhost XML configurations not allowed");
}
catch (ConfigurationException ce)
@@ -1285,81 +1481,4 @@ public class ServerConfigurationTest extends QpidTestCase
fail("Should throw a ConfigurationException");
}
}
-
- /*
- * Tests that the old element security.jmx.access (that used to be used
- * to define JMX access rights) is rejected.
- */
- public void testManagementAccessRejected() throws ConfigurationException
- {
- // Check default
- _serverConfig.initialise();
-
- // Check value we set
- _config.setProperty("security.jmx.access(0)", "jmxremote.access");
- _serverConfig = new ServerConfiguration(_config);
-
- try
- {
- _serverConfig.initialise();
- fail("Exception not thrown");
- }
- catch (ConfigurationException ce)
- {
- assertEquals("Incorrect error message",
- "Validation error : security/jmx/access is no longer a supported element within the configuration xml.",
- ce.getMessage());
- }
- }
-
- /*
- * Tests that the old element security.jmx.principal-database (that used to define the
- * principal database used for JMX authentication) is rejected.
- */
- public void testManagementPrincipalDatabaseRejected() throws ConfigurationException
- {
- // Check default
- _serverConfig.initialise();
-
- // Check value we set
- _config.setProperty("security.jmx.principal-database(0)", "mydb");
- _serverConfig = new ServerConfiguration(_config);
-
- try
- {
- _serverConfig.initialise();
- fail("Exception not thrown");
- }
- catch (ConfigurationException ce)
- {
- assertEquals("Incorrect error message",
- "Validation error : security/jmx/principal-database is no longer a supported element within the configuration xml.",
- ce.getMessage());
- }
- }
-
- /*
- * Tests that the old element security.principal-databases. ... (that used to define
- * principal databases) is rejected.
- */
- public void testPrincipalDatabasesRejected() throws ConfigurationException
- {
- _serverConfig.initialise();
-
- // Check value we set
- _config.setProperty("security.principal-databases.principal-database.class", "myclass");
- _serverConfig = new ServerConfiguration(_config);
-
- try
- {
- _serverConfig.initialise();
- fail("Exception not thrown");
- }
- catch (ConfigurationException ce)
- {
- assertEquals("Incorrect error message",
- "Validation error : security/principal-databases is no longer supported within the configuration xml.",
- ce.getMessage());
- }
- }
}
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 593119041d..917755e8a5 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,8 +20,6 @@
package org.apache.qpid.server.configuration;
-import org.apache.commons.configuration.ConfigurationException;
-import org.apache.commons.configuration.XMLConfiguration;
import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.server.queue.AMQPriorityQueue;
import org.apache.qpid.server.queue.AMQQueue;
@@ -205,29 +203,5 @@ public class VirtualHostConfigurationTest extends InternalBrokerBaseCase
}
- /**
- * Tests that the old element security.authentication.name is rejected. This element
- * was never supported properly as authentication is performed before the virtual host
- * is considered.
- */
- public void testSecurityAuthenticationNameRejected() throws Exception
- {
- getConfigXml().addProperty("virtualhosts.virtualhost.testSecurityAuthenticationNameRejected.security.authentication.name",
- "testdb");
-
- try
- {
- super.createBroker();
- fail("Exception not thrown");
- }
- catch(ConfigurationException ce)
- {
- assertEquals("Incorrect error message",
- "Validation error : security/authentication/name is no longer a supported element within the configuration xml." +
- " It appears in virtual host definition : " + getName(),
- ce.getMessage());
- }
- }
-
}
diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/exchange/AbstractHeadersExchangeTestBase.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/exchange/AbstractHeadersExchangeTestBase.java
index 44da761353..7b58966a4c 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
@@ -276,7 +276,7 @@ public class AbstractHeadersExchangeTestBase extends InternalBrokerBaseCase
static ContentHeaderBody getContentHeader(FieldTable headers)
{
ContentHeaderBody header = new ContentHeaderBody();
- header.setProperties(getProperties(headers));
+ header.properties = getProperties(headers);
return header;
}
@@ -482,16 +482,6 @@ public class AbstractHeadersExchangeTestBase extends InternalBrokerBaseCase
{
return 0; //To change body of implemented methods use File | Settings | File Templates.
}
-
- public boolean isDequeued()
- {
- return false;
- }
-
- public boolean isDispensed()
- {
- return false;
- }
};
if(action != null)
diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/exchange/TopicExchangeTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/exchange/TopicExchangeTest.java
index 403a290a0f..f72961c03c 100644
--- a/qpid/java/broker/src/test/java/org/apache/qpid/server/exchange/TopicExchangeTest.java
+++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/exchange/TopicExchangeTest.java
@@ -396,7 +396,7 @@ public class TopicExchangeTest extends InternalBrokerBaseCase
IncomingMessage message = new IncomingMessage(info);
final ContentHeaderBody chb = new ContentHeaderBody();
BasicContentHeaderProperties props = new BasicContentHeaderProperties();
- chb.setProperties(props);
+ chb.properties = props;
message.setContentHeaderBody(chb);
diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/logging/UnitTestMessageLogger.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/logging/UnitTestMessageLogger.java
index e8defd0e58..3752dcb37e 100644
--- a/qpid/java/broker/src/test/java/org/apache/qpid/server/logging/UnitTestMessageLogger.java
+++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/logging/UnitTestMessageLogger.java
@@ -28,7 +28,11 @@ import org.apache.qpid.server.logging.AbstractRootMessageLogger;
public class UnitTestMessageLogger extends AbstractRootMessageLogger
{
- private final List<Object> _log = new LinkedList<Object>();
+ List<Object> _log;
+
+ {
+ _log = new LinkedList<Object>();
+ }
public UnitTestMessageLogger()
{
@@ -65,14 +69,4 @@ public class UnitTestMessageLogger extends AbstractRootMessageLogger
{
_log.clear();
}
-
- public boolean messageContains(final int index, final String contains)
- {
- if (index + 1 > _log.size())
- {
- throw new IllegalArgumentException("Message with index " + index + " has not been logged");
- }
- final String message = _log.get(index).toString();
- return message.contains(contains);
- }
}
diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/management/AMQUserManagementMBeanTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/management/AMQUserManagementMBeanTest.java
index f3ee2707b0..a6c17e042e 100644
--- a/qpid/java/broker/src/test/java/org/apache/qpid/server/management/AMQUserManagementMBeanTest.java
+++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/management/AMQUserManagementMBeanTest.java
@@ -21,26 +21,22 @@
package org.apache.qpid.server.management;
+import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
+import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
-import javax.management.openmbean.CompositeData;
-import javax.management.openmbean.TabularData;
-
-
-import org.apache.commons.lang.NotImplementedException;
-import org.apache.qpid.management.common.mbeans.UserManagement;
+import org.apache.commons.configuration.ConfigurationException;
import org.apache.qpid.server.security.auth.database.PlainPasswordFilePrincipalDatabase;
import org.apache.qpid.server.security.auth.management.AMQUserManagementMBean;
import org.apache.qpid.server.util.InternalBrokerBaseCase;
-/**
- *
- * Tests the AMQUserManagementMBean and its interaction with the PrincipalDatabase.
- *
+/* 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 InternalBrokerBaseCase
{
@@ -48,6 +44,7 @@ public class AMQUserManagementMBeanTest extends InternalBrokerBaseCase
private AMQUserManagementMBean _amqumMBean;
private File _passwordFile;
+ private File _accessFile;
private static final String TEST_USERNAME = "testuser";
private static final String TEST_PASSWORD = "password";
@@ -60,6 +57,7 @@ public class AMQUserManagementMBeanTest extends InternalBrokerBaseCase
_database = new PlainPasswordFilePrincipalDatabase();
_amqumMBean = new AMQUserManagementMBean();
loadFreshTestPasswordFile();
+ loadFreshTestAccessFile();
}
@Override
@@ -67,67 +65,142 @@ public class AMQUserManagementMBeanTest extends InternalBrokerBaseCase
{
//clean up test password/access files
File _oldPasswordFile = new File(_passwordFile.getAbsolutePath() + ".old");
+ File _oldAccessFile = new File(_accessFile.getAbsolutePath() + ".old");
_oldPasswordFile.delete();
+ _oldAccessFile.delete();
_passwordFile.delete();
+ _accessFile.delete();
super.tearDown();
}
public void testDeleteUser()
{
- assertEquals("Unexpected number of users before test", 1,_amqumMBean.viewUsers().size());
- assertTrue("Delete should return true to flag successful delete", _amqumMBean.deleteUser(TEST_USERNAME));
- assertEquals("Unexpected number of users after test", 0,_amqumMBean.viewUsers().size());
- }
-
- public void testDeleteUserWhereUserDoesNotExist()
- {
- assertEquals("Unexpected number of users before test", 1,_amqumMBean.viewUsers().size());
- assertFalse("Delete should return false to flag unsuccessful delete", _amqumMBean.deleteUser("made.up.username"));
- assertEquals("Unexpected number of users after test", 1,_amqumMBean.viewUsers().size());
+ loadFreshTestPasswordFile();
+ loadFreshTestAccessFile();
+ //try deleting a non existant user
+ assertFalse(_amqumMBean.deleteUser("made.up.username"));
+
+ assertTrue(_amqumMBean.deleteUser(TEST_USERNAME));
}
- public void testCreateUser()
+ public void testDeleteUserIsSavedToAccessFile()
{
- assertEquals("Unexpected number of users before test", 1,_amqumMBean.viewUsers().size());
- assertTrue("Create should return true to flag successful create", _amqumMBean.createUser("newuser", "mypass"));
- assertEquals("Unexpected number of users before test", 2,_amqumMBean.viewUsers().size());
- }
+ loadFreshTestPasswordFile();
+ loadFreshTestAccessFile();
- public void testCreateUserWhereUserAlreadyExists()
- {
- assertEquals("Unexpected number of users before test", 1,_amqumMBean.viewUsers().size());
- assertFalse("Create should return false to flag unsuccessful create", _amqumMBean.createUser(TEST_USERNAME, "mypass"));
- assertEquals("Unexpected number of users before test", 1,_amqumMBean.viewUsers().size());
+ 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)
+ {
+ fail("Unable to valdate file contents due to:" + e.getMessage());
+ }
+
}
- public void testSetPassword()
+ public void testSetRights()
{
- assertTrue("Set password should return true to flag successful change", _amqumMBean.setPassword(TEST_USERNAME, "newpassword"));
+ 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 testSetPasswordWhereUserDoesNotExist()
+ public void testSetRightsIsSavedToAccessFile()
{
- assertFalse("Set password should return false to flag successful change", _amqumMBean.setPassword("made.up.username", "newpassword"));
+ 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:"));
+
+ //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)
+ {
+ fail("Unable to valdate file contents due to:" + e.getMessage());
+ }
}
- public void testViewUsers()
+ public void testSetAccessFileWithMissingFile()
{
- TabularData userList = _amqumMBean.viewUsers();
+ 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"));
+ }
+ }
- assertNotNull(userList);
- assertEquals("Unexpected number of users in user list", 1, userList.size());
- assertTrue(userList.containsKey(new Object[]{TEST_USERNAME}));
-
- // Check the deprecated read, write and admin items continue to exist but return false.
- CompositeData userRec = userList.get(new Object[]{TEST_USERNAME});
- assertTrue(userRec.containsKey(UserManagement.RIGHTS_READ_ONLY));
- assertEquals(false, userRec.get(UserManagement.RIGHTS_READ_ONLY));
- assertEquals(false, userRec.get(UserManagement.RIGHTS_READ_WRITE));
- assertTrue(userRec.containsKey(UserManagement.RIGHTS_READ_WRITE));
- assertTrue(userRec.containsKey(UserManagement.RIGHTS_ADMIN));
- assertEquals(false, userRec.get(UserManagement.RIGHTS_ADMIN));
+ public void testSetAccessFileWithReadOnlyFile()
+ {
+ File testFile = null;
+ try
+ {
+ 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 (IOException e)
+ {
+ fail("Access file was not created." + e.getMessage());
+ }
+ catch (ConfigurationException e)
+ {
+ fail("There should not have been a configuration exception." + e.getMessage());
+ }
+
+ testFile.delete();
}
// ============================ Utility methods =========================
@@ -154,4 +227,37 @@ public class AMQUserManagementMBeanTest extends InternalBrokerBaseCase
fail("Unable to create test password file: " + e.getMessage());
}
}
+
+ private void loadFreshTestAccessFile()
+ {
+ try
+ {
+ if(_accessFile == null)
+ {
+ _accessFile = File.createTempFile(this.getClass().getName(),".access");
+ }
+
+ 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());
+ }
+
+ try{
+ _amqumMBean.setAccessFile(_accessFile.toString());
+ }
+ catch (Exception e)
+ {
+ fail("Unable to set access file: " + e.getMessage());
+ }
+ }
}
diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/protocol/InternalTestProtocolSession.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/protocol/InternalTestProtocolSession.java
index 3af665141c..3b6cd37ea9 100644
--- a/qpid/java/broker/src/test/java/org/apache/qpid/server/protocol/InternalTestProtocolSession.java
+++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/protocol/InternalTestProtocolSession.java
@@ -21,31 +21,23 @@
package org.apache.qpid.server.protocol;
import java.security.Principal;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
-import javax.security.auth.Subject;
-
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.protocol.AMQConstant;
import org.apache.qpid.server.AMQChannel;
-import org.apache.qpid.server.message.AMQMessage;
-import org.apache.qpid.server.message.MessageContentSource;
import org.apache.qpid.server.output.ProtocolOutputConverter;
+import org.apache.qpid.server.message.AMQMessage;
import org.apache.qpid.server.queue.QueueEntry;
import org.apache.qpid.server.registry.ApplicationRegistry;
-import org.apache.qpid.server.security.auth.sasl.UsernamePrincipal;
import org.apache.qpid.server.state.AMQState;
import org.apache.qpid.server.virtualhost.VirtualHost;
-import org.apache.qpid.transport.TestNetworkConnection;
+import org.apache.qpid.server.message.MessageContentSource;
+import org.apache.qpid.transport.TestNetworkDriver;
public class InternalTestProtocolSession extends AMQProtocolEngine implements ProtocolOutputConverter
{
@@ -55,13 +47,18 @@ public class InternalTestProtocolSession extends AMQProtocolEngine implements Pr
public InternalTestProtocolSession(VirtualHost virtualHost) throws AMQException
{
- super(ApplicationRegistry.getInstance().getVirtualHostRegistry(), new TestNetworkConnection());
+ super(ApplicationRegistry.getInstance().getVirtualHostRegistry(), new TestNetworkDriver());
_channelDelivers = new HashMap<Integer, Map<AMQShortString, LinkedList<DeliveryPair>>>();
// Need to authenticate session for it to be representative testing.
- setAuthorizedSubject(new Subject(true, Collections.singleton(new UsernamePrincipal("InternalTestProtocolSession")),
- Collections.EMPTY_SET, Collections.EMPTY_SET));
+ setAuthorizedID(new Principal()
+ {
+ public String getName()
+ {
+ return "InternalTestProtocolSession";
+ }
+ });
setVirtualHost(virtualHost);
}
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 3961b3b355..d52f4c03f3 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
@@ -96,7 +96,7 @@ public class AMQPriorityQueueTest extends SimpleAMQQueueTest
AMQMessage msg = super.createMessage(id);
BasicContentHeaderProperties props = new BasicContentHeaderProperties();
props.setPriority(i);
- msg.getContentHeaderBody().setProperties(props);
+ msg.getContentHeaderBody().properties = props;
return msg;
}
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 a8bddcf6bf..0707cab3d5 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
@@ -277,7 +277,7 @@ public class AMQQueueAlertTest extends InternalBrokerBaseCase
ContentHeaderBody contentHeaderBody = new ContentHeaderBody();
BasicContentHeaderProperties props = new BasicContentHeaderProperties();
- contentHeaderBody.setProperties(props);
+ contentHeaderBody.properties = props;
contentHeaderBody.bodySize = size; // in bytes
IncomingMessage message = new IncomingMessage(publish);
message.setContentHeaderBody(contentHeaderBody);
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 365353e734..5b72cfac40 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
@@ -402,8 +402,8 @@ public class AMQQueueMBeanTest extends InternalBrokerBaseCase
ContentHeaderBody contentHeaderBody = new ContentHeaderBody();
contentHeaderBody.bodySize = MESSAGE_SIZE; // in bytes
- contentHeaderBody.setProperties(new BasicContentHeaderProperties());
- ((BasicContentHeaderProperties) contentHeaderBody.getProperties()).setDeliveryMode((byte) (persistent ? 2 : 1));
+ contentHeaderBody.properties = new BasicContentHeaderProperties();
+ ((BasicContentHeaderProperties) contentHeaderBody.properties).setDeliveryMode((byte) (persistent ? 2 : 1));
IncomingMessage msg = new IncomingMessage(publish);
msg.setContentHeaderBody(contentHeaderBody);
return msg;
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 0f5374b3e5..04608275a3 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
@@ -126,7 +126,7 @@ public class AckTest extends InternalBrokerBaseCase
//IncomingMessage msg2 = null;
BasicContentHeaderProperties b = new BasicContentHeaderProperties();
ContentHeaderBody cb = new ContentHeaderBody();
- cb.setProperties(b);
+ cb.properties = b;
if (persistent)
{
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 4c31092983..888a16053c 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
@@ -29,7 +29,7 @@ import org.apache.qpid.server.subscription.Subscription;
import org.apache.qpid.server.virtualhost.VirtualHost;
import org.apache.qpid.server.management.ManagedObject;
import org.apache.qpid.server.message.ServerMessage;
-import org.apache.qpid.server.security.AuthorizationHolder;
+import org.apache.qpid.server.security.PrincipalHolder;
import org.apache.qpid.server.AMQChannel;
import org.apache.qpid.server.protocol.AMQSessionModel;
import org.apache.qpid.server.binding.Binding;
@@ -48,7 +48,7 @@ public class MockAMQQueue implements AMQQueue
private AMQShortString _name;
private VirtualHost _virtualhost;
- private AuthorizationHolder _authorizationHolder;
+ private PrincipalHolder _principalHolder;
private AMQSessionModel _exclusiveOwner;
private AMQShortString _owner;
@@ -536,14 +536,14 @@ public class MockAMQQueue implements AMQQueue
return null; //To change body of implemented methods use File | Settings | File Templates.
}
- public AuthorizationHolder getAuthorizationHolder()
+ public PrincipalHolder getPrincipalHolder()
{
- return _authorizationHolder;
+ return _principalHolder;
}
- public void setAuthorizationHolder(final AuthorizationHolder authorizationHolder)
+ public void setPrincipalHolder(PrincipalHolder principalHolder)
{
- _authorizationHolder = authorizationHolder;
+ _principalHolder = principalHolder;
}
public AMQSessionModel getExclusiveOwningSession()
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 a3f8f4c0d3..5bdbe2c68e 100644
--- a/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/MockQueueEntry.java
+++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/MockQueueEntry.java
@@ -231,14 +231,4 @@ public class MockQueueEntry implements QueueEntry
_message = msg;
}
- public boolean isDequeued()
- {
- return false;
- }
-
- public boolean isDispensed()
- {
- return false;
- }
-
}
diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/QueueEntryImplTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/QueueEntryImplTest.java
deleted file mode 100644
index 0899f25cc5..0000000000
--- a/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/QueueEntryImplTest.java
+++ /dev/null
@@ -1,213 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.qpid.server.queue;
-
-import java.lang.reflect.Field;
-
-import junit.framework.TestCase;
-
-import org.apache.qpid.AMQException;
-import org.apache.qpid.server.message.AMQMessage;
-import org.apache.qpid.server.queue.QueueEntry.EntryState;
-import org.apache.qpid.server.subscription.MockSubscription;
-
-/**
- * Tests for {@link QueueEntryImpl}
- *
- */
-public class QueueEntryImplTest extends TestCase
-{
- // tested entry
- private QueueEntryImpl _queueEntry;
-
- public void setUp() throws Exception
- {
- AMQMessage message = new MockAMQMessage(1);
- SimpleQueueEntryList queueEntryList = new SimpleQueueEntryList(new MockAMQQueue("test"));
- _queueEntry = new QueueEntryImpl(queueEntryList, message, 1);
- }
-
- public void testAquire()
- {
- assertTrue("Queue entry should be in AVAILABLE state before invoking of acquire method",
- _queueEntry.isAvailable());
- acquire();
- }
-
- public void testDequeue()
- {
- dequeue();
- }
-
- public void testDelete()
- {
- delete();
- }
-
- /**
- * Tests release method for entry in acquired state.
- * <p>
- * Entry in state ACQUIRED should be released and its status should be
- * changed to AVAILABLE.
- */
- public void testReleaseAquired()
- {
- acquire();
- _queueEntry.release();
- assertTrue("Queue entry should be in AVAILABLE state after invoking of release method",
- _queueEntry.isAvailable());
- }
-
- /**
- * Tests release method for entry in dequeued state.
- * <p>
- * Invoking release on dequeued entry should not have any effect on its
- * state.
- */
- public void testReleaseDequeued()
- {
- dequeue();
- _queueEntry.release();
- EntryState state = getState();
- assertEquals("Invoking of release on entry in DEQUEUED state should not have any effect",
- QueueEntry.DEQUEUED_STATE, state);
- }
-
- /**
- * Tests release method for entry in deleted state.
- * <p>
- * Invoking release on deleted entry should not have any effect on its
- * state.
- */
- public void testReleaseDeleted()
- {
- delete();
- _queueEntry.release();
- assertTrue("Invoking of release on entry in DELETED state should not have any effect",
- _queueEntry.isDeleted());
- }
-
- /**
- * Tests if entries in DEQUQUED or DELETED state are not returned by getNext method.
- */
- public void testGetNext()
- {
- int numberOfEntries = 5;
- QueueEntryImpl[] entries = new QueueEntryImpl[numberOfEntries];
- SimpleQueueEntryList queueEntryList = new SimpleQueueEntryList(new MockAMQQueue("test"));
-
- // create test entries
- for(int i = 0; i < numberOfEntries ; i++)
- {
- AMQMessage message = null;;
- try
- {
- message = new MockAMQMessage(i);
- }
- catch (AMQException e)
- {
- fail("Failure to create a mock message:" + e.getMessage());
- }
- QueueEntryImpl entry = (QueueEntryImpl)queueEntryList.add(message);
- entries[i] = entry;
- }
-
- // test getNext for not acquired entries
- for(int i = 0; i < numberOfEntries ; i++)
- {
- QueueEntryImpl queueEntry = entries[i];
- QueueEntryImpl next = queueEntry.getNext();
- if (i < numberOfEntries - 1)
- {
- assertEquals("Unexpected entry from QueueEntryImpl#getNext()", entries[i + 1], next);
- }
- else
- {
- assertNull("The next entry after the last should be null", next);
- }
- }
-
- // delete second
- entries[1].acquire();
- entries[1].delete();
-
- // dequeue third
- entries[2].acquire();
- entries[2].dequeue();
-
- QueueEntryImpl next = entries[0].getNext();
- assertEquals("expected forth entry",entries[3], next);
- next = next.getNext();
- assertEquals("expected fifth entry", entries[4], next);
- next = next.getNext();
- assertNull("The next entry after the last should be null", next);
- }
- /**
- * A helper method to put tested object into deleted state and assert the state
- */
- private void delete()
- {
- _queueEntry.delete();
- assertTrue("Queue entry should be in DELETED state after invoking of delete method",
- _queueEntry.isDeleted());
- }
-
- /**
- * A helper method to put tested entry into dequeue state and assert the sate
- */
- private void dequeue()
- {
- acquire();
- _queueEntry.dequeue();
- EntryState state = getState();
- assertEquals("Queue entry should be in DEQUEUED state after invoking of dequeue method",
- QueueEntry.DEQUEUED_STATE, state);
- }
-
- /**
- * A helper method to put tested entry into acquired state and assert the sate
- */
- private void acquire()
- {
- _queueEntry.acquire(new MockSubscription());
- assertTrue("Queue entry should be in ACQUIRED state after invoking of acquire method",
- _queueEntry.isAcquired());
- }
-
- /**
- * A helper method to get entry state
- *
- * @return entry state
- */
- private EntryState getState()
- {
- EntryState state = null;
- try
- {
- Field f = QueueEntryImpl.class.getDeclaredField("_state");
- f.setAccessible(true);
- state = (EntryState) f.get(_queueEntry);
- }
- catch (Exception e)
- {
- fail("Failure to get a state field: " + e.getMessage());
- }
- return state;
- }
-}
diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/SimpleAMQQueueTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/SimpleAMQQueueTest.java
index 0e136c523f..67d093d00a 100644
--- a/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/SimpleAMQQueueTest.java
+++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/SimpleAMQQueueTest.java
@@ -36,16 +36,13 @@ import org.apache.qpid.server.configuration.VirtualHostConfiguration;
import org.apache.qpid.server.exchange.DirectExchange;
import org.apache.qpid.server.message.AMQMessage;
import org.apache.qpid.server.message.MessageMetaData;
-import org.apache.qpid.server.message.ServerMessage;
import org.apache.qpid.server.queue.BaseQueue.PostEnqueueAction;
-import org.apache.qpid.server.queue.SimpleAMQQueue.QueueEntryFilter;
import org.apache.qpid.server.registry.ApplicationRegistry;
import org.apache.qpid.server.store.StoredMessage;
import org.apache.qpid.server.store.TestableMemoryMessageStore;
import org.apache.qpid.server.subscription.MockSubscription;
import org.apache.qpid.server.subscription.Subscription;
import org.apache.qpid.server.txn.AutoCommitTransaction;
-import org.apache.qpid.server.txn.LocalTransaction;
import org.apache.qpid.server.txn.ServerTransaction;
import org.apache.qpid.server.util.InternalBrokerBaseCase;
import org.apache.qpid.server.virtualhost.VirtualHost;
@@ -54,8 +51,6 @@ import org.apache.qpid.server.virtualhost.VirtualHostImpl;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
public class SimpleAMQQueueTest extends InternalBrokerBaseCase
{
@@ -232,10 +227,10 @@ public class SimpleAMQQueueTest extends InternalBrokerBaseCase
}
/**
- * Tests that a released queue entry is resent to the subscriber. Verifies also that the
+ * Tests that a re-queued message is resent to the subscriber. Verifies also that the
* QueueContext._releasedEntry is reset to null after the entry has been reset.
*/
- public void testReleasedMessageIsResentToSubscriber() throws Exception
+ public void testRequeuedMessageIsResentToSubscriber() throws Exception
{
_queue.registerSubscription(_subscription, false);
@@ -258,18 +253,19 @@ public class SimpleAMQQueueTest extends InternalBrokerBaseCase
_queue.enqueue(messageB, postEnqueueAction);
_queue.enqueue(messageC, postEnqueueAction);
- Thread.sleep(150); // Work done by SubFlushRunner/QueueRunner Threads
+ Thread.sleep(150); // Work done by SubFlushRunner Thread
assertEquals("Unexpected total number of messages sent to subscription", 3, _subscription.getMessages().size());
assertFalse("Redelivery flag should not be set", queueEntries.get(0).isRedelivered());
assertFalse("Redelivery flag should not be set", queueEntries.get(1).isRedelivered());
assertFalse("Redelivery flag should not be set", queueEntries.get(2).isRedelivered());
- /* Now release the first message only, causing it to be requeued */
+ /* Now requeue the first message only */
queueEntries.get(0).release();
+ _queue.requeue(queueEntries.get(0));
- Thread.sleep(150); // Work done by SubFlushRunner/QueueRunner Threads
+ Thread.sleep(150); // Work done by SubFlushRunner Thread
assertEquals("Unexpected total number of messages sent to subscription", 4, _subscription.getMessages().size());
assertTrue("Redelivery flag should now be set", queueEntries.get(0).isRedelivered());
@@ -279,11 +275,11 @@ public class SimpleAMQQueueTest extends InternalBrokerBaseCase
}
/**
- * Tests that a released message that becomes expired is not resent to the subscriber.
+ * Tests that a re-queued message that becomes expired is not resent to the subscriber.
* This tests ensures that SimpleAMQQueueEntry.getNextAvailableEntry avoids expired entries.
* Verifies also that the QueueContext._releasedEntry is reset to null after the entry has been reset.
*/
- public void testReleaseMessageThatBecomesExpiredIsNotRedelivered() throws Exception
+ public void testRequeuedMessageThatBecomesExpiredIsNotRedelivered() throws Exception
{
_queue.registerSubscription(_subscription, false);
@@ -305,16 +301,17 @@ public class SimpleAMQQueueTest extends InternalBrokerBaseCase
_queue.enqueue(messageA, postEnqueueAction);
int subFlushWaitTime = 150;
- Thread.sleep(subFlushWaitTime); // Work done by SubFlushRunner/QueueRunner Threads
+ Thread.sleep(subFlushWaitTime); // Work done by SubFlushRunner Thread
assertEquals("Unexpected total number of messages sent to subscription", 1, _subscription.getMessages().size());
assertFalse("Redelivery flag should not be set", queueEntries.get(0).isRedelivered());
- /* Wait a little more to be sure that message will have expired, then release the first message only, causing it to be requeued */
+ /* Wait a little more to be sure that message will have expired, then requeue it */
Thread.sleep(messageExpirationOffset - subFlushWaitTime + 10);
queueEntries.get(0).release();
+ _queue.requeue(queueEntries.get(0));
- Thread.sleep(subFlushWaitTime); // Work done by SubFlushRunner/QueueRunner Threads
+ Thread.sleep(subFlushWaitTime); // Work done by SubFlushRunner Thread
assertTrue("Expecting the queue entry to be now expired", queueEntries.get(0).expired());
assertEquals("Total number of messages sent should not have changed", 1, _subscription.getMessages().size());
@@ -324,12 +321,12 @@ public class SimpleAMQQueueTest extends InternalBrokerBaseCase
}
/**
- * Tests that if a client releases entries 'out of order' (the order
+ * Tests that if a client requeues messages 'out of order' (the order
* used by QueueEntryImpl.compareTo) that messages are still resent
* successfully. Specifically this test ensures the {@see SimpleAMQQueue#requeue()}
* can correctly move the _releasedEntry to an earlier position in the QueueEntry list.
*/
- public void testReleasedOutOfComparableOrderAreRedelivered() throws Exception
+ public void testMessagesRequeuedOutOfComparableOrderAreDelivered() throws Exception
{
_queue.registerSubscription(_subscription, false);
@@ -352,19 +349,21 @@ public class SimpleAMQQueueTest extends InternalBrokerBaseCase
_queue.enqueue(messageB, postEnqueueAction);
_queue.enqueue(messageC, postEnqueueAction);
- Thread.sleep(150); // Work done by SubFlushRunner/QueueRunner Threads
+ Thread.sleep(150); // Work done by SubFlushRunner Thread
assertEquals("Unexpected total number of messages sent to subscription", 3, _subscription.getMessages().size());
assertFalse("Redelivery flag should not be set", queueEntries.get(0).isRedelivered());
assertFalse("Redelivery flag should not be set", queueEntries.get(1).isRedelivered());
assertFalse("Redelivery flag should not be set", queueEntries.get(2).isRedelivered());
- /* Now release the third and first message only, causing it to be requeued */
+ /* Now requeue the third and first message only */
queueEntries.get(2).release();
queueEntries.get(0).release();
+ _queue.requeue(queueEntries.get(2));
+ _queue.requeue(queueEntries.get(0));
- Thread.sleep(150); // Work done by SubFlushRunner/QueueRunner Threads
+ Thread.sleep(150); // Work done by SubFlushRunner Thread
assertEquals("Unexpected total number of messages sent to subscription", 5, _subscription.getMessages().size());
assertTrue("Redelivery flag should now be set", queueEntries.get(0).isRedelivered());
@@ -375,10 +374,10 @@ public class SimpleAMQQueueTest extends InternalBrokerBaseCase
/**
- * Tests that a release requeues an entry for a queue with multiple subscriptions. Verifies that a
+ * Tests a requeue for a queue with multiple subscriptions. Verifies that a
* requeue resends a message to a <i>single</i> subscriber.
*/
- public void testReleaseForQueueWithMultipleSubscriptions() throws Exception
+ public void testRequeueForQueueWithMultipleSubscriptions() throws Exception
{
MockSubscription subscription1 = new MockSubscription();
MockSubscription subscription2 = new MockSubscription();
@@ -403,16 +402,66 @@ public class SimpleAMQQueueTest extends InternalBrokerBaseCase
_queue.enqueue(messageA, postEnqueueAction);
_queue.enqueue(messageB, postEnqueueAction);
- Thread.sleep(150); // Work done by SubFlushRunner/QueueRunner Threads
+ Thread.sleep(150); // Work done by SubFlushRunner Thread
- assertEquals("Unexpected total number of messages sent to both after enqueue", 2, subscription1.getMessages().size() + subscription2.getMessages().size());
+ assertEquals("Unexpected total number of messages sent to subscription1 after enqueue", 1, subscription1.getMessages().size());
+ assertEquals("Unexpected total number of messages sent to subscription2 after enqueue", 1, subscription2.getMessages().size());
- /* Now release the first message only, causing it to be requeued */
- queueEntries.get(0).release();
+ /* Now requeue a message (for any subscription) */
- Thread.sleep(150); // Work done by SubFlushRunner/QueueRunner Threads
+ queueEntries.get(0).release();
+ _queue.requeue((QueueEntryImpl)queueEntries.get(0));
+
+ Thread.sleep(150); // Work done by SubFlushRunner Thread
- assertEquals("Unexpected total number of messages sent to both subscriptions after release", 3, subscription1.getMessages().size() + subscription2.getMessages().size());
+ assertEquals("Unexpected total number of messages sent to all subscriptions after requeue", 3, subscription1.getMessages().size() + subscription2.getMessages().size());
+ assertNull("releasedEntry should be cleared after requeue processed", ((QueueContext)subscription1.getQueueContext())._releasedEntry);
+ assertNull("releasedEntry should be cleared after requeue processed", ((QueueContext)subscription2.getQueueContext())._releasedEntry);
+ }
+
+ /**
+ * Tests a requeue for a queue with multiple subscriptions. Verifies that a
+ * subscriber specific requeue resends the message to <i>that</i> subscriber.
+ */
+ public void testSubscriptionSpecificRequeueForQueueWithMultipleSubscriptions() throws Exception
+ {
+ MockSubscription subscription1 = new MockSubscription();
+ MockSubscription subscription2 = new MockSubscription();
+
+ _queue.registerSubscription(subscription1, false);
+ _queue.registerSubscription(subscription2, false);
+
+ final ArrayList<QueueEntry> queueEntries = new ArrayList<QueueEntry>();
+ PostEnqueueAction postEnqueueAction = new PostEnqueueAction()
+ {
+ public void onEnqueue(QueueEntry entry)
+ {
+ queueEntries.add(entry);
+ }
+ };
+
+ AMQMessage messageA = createMessage(new Long(24));
+ AMQMessage messageB = createMessage(new Long(25));
+
+ /* Enqueue two messages */
+
+ _queue.enqueue(messageA, postEnqueueAction);
+ _queue.enqueue(messageB, postEnqueueAction);
+
+ Thread.sleep(150); // Work done by SubFlushRunner Thread
+
+ assertEquals("Unexpected total number of messages sent to subscription1 after enqueue", 1, subscription1.getMessages().size());
+ assertEquals("Unexpected total number of messages sent to subscription2 after enqueue", 1, subscription2.getMessages().size());
+
+ /* Now requeue a message (for first subscription) */
+
+ queueEntries.get(0).release();
+ _queue.requeue((QueueEntryImpl)queueEntries.get(0), subscription1);
+
+ Thread.sleep(150); // Work done by SubFlushRunner Thread
+
+ assertEquals("Unexpected total number of messages sent to subscription1 after requeue", 2, subscription1.getMessages().size());
+ assertEquals("Unexpected total number of messages sent to subscription2 after requeue", 1, subscription2.getMessages().size());
assertNull("releasedEntry should be cleared after requeue processed", ((QueueContext)subscription1.getQueueContext())._releasedEntry);
assertNull("releasedEntry should be cleared after requeue processed", ((QueueContext)subscription2.getQueueContext())._releasedEntry);
}
@@ -611,8 +660,8 @@ public class SimpleAMQQueueTest extends InternalBrokerBaseCase
// Create IncomingMessage and nondurable queue
final IncomingMessage msg = new IncomingMessage(info);
ContentHeaderBody contentHeaderBody = new ContentHeaderBody();
- contentHeaderBody.setProperties(new BasicContentHeaderProperties());
- ((BasicContentHeaderProperties) contentHeaderBody.getProperties()).setDeliveryMode((byte) 2);
+ contentHeaderBody.properties = new BasicContentHeaderProperties();
+ ((BasicContentHeaderProperties) contentHeaderBody.properties).setDeliveryMode((byte) 2);
msg.setContentHeaderBody(contentHeaderBody);
final ArrayList<BaseQueue> qs = new ArrayList<BaseQueue>();
@@ -658,635 +707,6 @@ public class SimpleAMQQueueTest extends InternalBrokerBaseCase
}
- /**
- * processQueue() is used when asynchronously delivering messages to
- * subscriptions which could not be delivered immediately during the
- * enqueue() operation.
- *
- * A defect within the method would mean that delivery of these messages may
- * not occur should the Runner stop before all messages have been processed.
- * Such a defect was discovered when Selectors were used such that one and
- * only one subscription can/will accept any given messages, but multiple
- * subscriptions are present, and one of the earlier subscriptions receives
- * more messages than the others.
- *
- * This test is to validate that the processQueue() method is able to
- * correctly deliver all of the messages present for asynchronous delivery
- * to subscriptions in such a scenario.
- */
- public void testProcessQueueWithUniqueSelectors() throws Exception
- {
- TestSimpleQueueEntryListFactory factory = new TestSimpleQueueEntryListFactory();
- SimpleAMQQueue testQueue = new SimpleAMQQueue("testQueue", false, "testOwner",false,
- false, _virtualHost, factory, null)
- {
- @Override
- public void deliverAsync(Subscription sub)
- {
- // do nothing, i.e prevent deliveries by the SubFlushRunner
- // when registering the new subscriptions
- }
- };
-
- // retrieve the QueueEntryList the queue creates and insert the test
- // messages, thus avoiding straight-through delivery attempts during
- //enqueue() process.
- QueueEntryList list = factory.getQueueEntryList();
- assertNotNull("QueueEntryList should have been created", list);
-
- QueueEntry msg1 = list.add(createMessage(1L));
- QueueEntry msg2 = list.add(createMessage(2L));
- QueueEntry msg3 = list.add(createMessage(3L));
- QueueEntry msg4 = list.add(createMessage(4L));
- QueueEntry msg5 = list.add(createMessage(5L));
-
- // Create lists of the entries each subscription should be interested
- // in.Bias over 50% of the messages to the first subscription so that
- // the later subscriptions reject them and report being done before
- // the first subscription as the processQueue method proceeds.
- List<QueueEntry> msgListSub1 = createEntriesList(msg1, msg2, msg3);
- List<QueueEntry> msgListSub2 = createEntriesList(msg4);
- List<QueueEntry> msgListSub3 = createEntriesList(msg5);
-
- MockSubscription sub1 = new MockSubscription(msgListSub1);
- MockSubscription sub2 = new MockSubscription(msgListSub2);
- MockSubscription sub3 = new MockSubscription(msgListSub3);
-
- // register the subscriptions
- testQueue.registerSubscription(sub1, false);
- testQueue.registerSubscription(sub2, false);
- testQueue.registerSubscription(sub3, false);
-
- //check that no messages have been delivered to the
- //subscriptions during registration
- assertEquals("No messages should have been delivered yet", 0, sub1.getMessages().size());
- assertEquals("No messages should have been delivered yet", 0, sub2.getMessages().size());
- assertEquals("No messages should have been delivered yet", 0, sub3.getMessages().size());
-
- // call processQueue to deliver the messages
- testQueue.processQueue(new QueueRunner(testQueue, 1)
- {
- @Override
- public void run()
- {
- // we dont actually want/need this runner to do any work
- // because we we are already doing it!
- }
- });
-
- // check expected messages delivered to correct consumers
- verifyRecievedMessages(msgListSub1, sub1.getMessages());
- verifyRecievedMessages(msgListSub2, sub2.getMessages());
- verifyRecievedMessages(msgListSub3, sub3.getMessages());
- }
-
- /**
- * Tests that dequeued message is not present in the list returned form
- * {@link SimpleAMQQueue#getMessagesOnTheQueue()}
- */
- public void testGetMessagesOnTheQueueWithDequeuedEntry()
- {
- int messageNumber = 4;
- int dequeueMessageIndex = 1;
-
- // send test messages into a test queue
- enqueueGivenNumberOfMessages(_queue, messageNumber);
-
- // dequeue message
- dequeueMessage(_queue, dequeueMessageIndex);
-
- // get messages on the queue
- List<QueueEntry> entries = _queue.getMessagesOnTheQueue();
-
- // assert queue entries
- assertEquals(messageNumber - 1, entries.size());
- int expectedId = 0;
- for (int i = 0; i < messageNumber - 1; i++)
- {
- Long id = ((AMQMessage) entries.get(i).getMessage()).getMessageId();
- if (i == dequeueMessageIndex)
- {
- assertFalse("Message with id " + dequeueMessageIndex
- + " was dequeued and should not be returned by method getMessagesOnTheQueue!",
- new Long(expectedId).equals(id));
- expectedId++;
- }
- assertEquals("Expected message with id " + expectedId + " but got message with id " + id,
- new Long(expectedId), id);
- expectedId++;
- }
- }
-
- /**
- * Tests that dequeued message is not present in the list returned form
- * {@link SimpleAMQQueue#getMessagesOnTheQueue(QueueEntryFilter)}
- */
- public void testGetMessagesOnTheQueueByQueueEntryFilterWithDequeuedEntry()
- {
- int messageNumber = 4;
- int dequeueMessageIndex = 1;
-
- // send test messages into a test queue
- enqueueGivenNumberOfMessages(_queue, messageNumber);
-
- // dequeue message
- dequeueMessage(_queue, dequeueMessageIndex);
-
- // get messages on the queue with filter accepting all available messages
- List<QueueEntry> entries = _queue.getMessagesOnTheQueue(new QueueEntryFilter()
- {
- public boolean accept(QueueEntry entry)
- {
- return true;
- }
-
- public boolean filterComplete()
- {
- return false;
- }
- });
-
- // assert entries on the queue
- assertEquals(messageNumber - 1, entries.size());
- int expectedId = 0;
- for (int i = 0; i < messageNumber - 1; i++)
- {
- Long id = ((AMQMessage) entries.get(i).getMessage()).getMessageId();
- if (i == dequeueMessageIndex)
- {
- assertFalse("Message with id " + dequeueMessageIndex
- + " was dequeued and should not be returned by method getMessagesOnTheQueue!",
- new Long(expectedId).equals(id));
- expectedId++;
- }
- assertEquals("Expected message with id " + expectedId + " but got message with id " + id,
- new Long(expectedId), id);
- expectedId++;
- }
- }
-
- /**
- * Tests that dequeued message is not copied as part of invocation of
- * {@link SimpleAMQQueue#copyMessagesToAnotherQueue(long, long, String, StoreContext)}
- */
- public void testCopyMessagesWithDequeuedEntry()
- {
- int messageNumber = 4;
- int dequeueMessageIndex = 1;
- String anotherQueueName = "testQueue2";
-
- // put test messages into a test queue
- enqueueGivenNumberOfMessages(_queue, messageNumber);
-
- // dequeue message
- dequeueMessage(_queue, dequeueMessageIndex);
-
- // create another queue
- SimpleAMQQueue queue = createQueue(anotherQueueName);
-
- // create transaction
- ServerTransaction txn = new LocalTransaction(_queue.getVirtualHost().getTransactionLog());
-
- // copy messages into another queue
- _queue.copyMessagesToAnotherQueue(0, messageNumber, anotherQueueName, txn);
-
- // commit transaction
- txn.commit();
-
- // get messages on another queue
- List<QueueEntry> entries = queue.getMessagesOnTheQueue();
-
- // assert another queue entries
- assertEquals(messageNumber - 1, entries.size());
- int expectedId = 0;
- for (int i = 0; i < messageNumber - 1; i++)
- {
- Long id = ((AMQMessage)entries.get(i).getMessage()).getMessageId();
- if (i == dequeueMessageIndex)
- {
- assertFalse("Message with id " + dequeueMessageIndex
- + " was dequeued and should not been copied into another queue!",
- new Long(expectedId).equals(id));
- expectedId++;
- }
- assertEquals("Expected message with id " + expectedId + " but got message with id " + id,
- new Long(expectedId), id);
- expectedId++;
- }
- }
-
- /**
- * Tests that dequeued message is not moved as part of invocation of
- * {@link SimpleAMQQueue#moveMessagesToAnotherQueue(long, long, String, StoreContext)}
- */
- public void testMovedMessagesWithDequeuedEntry()
- {
- int messageNumber = 4;
- int dequeueMessageIndex = 1;
- String anotherQueueName = "testQueue2";
-
- // put messages into a test queue
- enqueueGivenNumberOfMessages(_queue, messageNumber);
-
- // dequeue message
- dequeueMessage(_queue, dequeueMessageIndex);
-
- // create another queue
- SimpleAMQQueue queue = createQueue(anotherQueueName);
-
- // create transaction
- ServerTransaction txn = new LocalTransaction(_queue.getVirtualHost().getTransactionLog());
-
- // move messages into another queue
- _queue.moveMessagesToAnotherQueue(0, messageNumber, anotherQueueName, txn);
-
- // commit transaction
- txn.commit();
-
- // get messages on another queue
- List<QueueEntry> entries = queue.getMessagesOnTheQueue();
-
- // assert another queue entries
- assertEquals(messageNumber - 1, entries.size());
- int expectedId = 0;
- for (int i = 0; i < messageNumber - 1; i++)
- {
- Long id = ((AMQMessage)entries.get(i).getMessage()).getMessageId();
- if (i == dequeueMessageIndex)
- {
- assertFalse("Message with id " + dequeueMessageIndex
- + " was dequeued and should not been copied into another queue!",
- new Long(expectedId).equals(id));
- expectedId++;
- }
- assertEquals("Expected message with id " + expectedId + " but got message with id " + id,
- new Long(expectedId), id);
- expectedId++;
- }
- }
-
- /**
- * Tests that messages in given range including dequeued one are deleted
- * from the queue on invocation of
- * {@link SimpleAMQQueue#removeMessagesFromQueue(long, long, StoreContext)}
- */
- public void testRemoveMessagesFromQueueWithDequeuedEntry()
- {
- int messageNumber = 4;
- int dequeueMessageIndex = 1;
-
- // put messages into a test queue
- enqueueGivenNumberOfMessages(_queue, messageNumber);
-
- // dequeue message
- dequeueMessage(_queue, dequeueMessageIndex);
-
- // remove messages
- _queue.removeMessagesFromQueue(0, messageNumber);
-
- // get queue entries
- List<QueueEntry> entries = _queue.getMessagesOnTheQueue();
-
- // assert queue entries
- assertNotNull("Null is returned from getMessagesOnTheQueue", entries);
- assertEquals("Queue should be empty", 0, entries.size());
- }
-
- /**
- * Tests that dequeued message on the top is not accounted and next message
- * is deleted from the queue on invocation of
- * {@link SimpleAMQQueue#deleteMessageFromTop(StoreContext)}
- */
- public void testDeleteMessageFromTopWithDequeuedEntryOnTop()
- {
- int messageNumber = 4;
- int dequeueMessageIndex = 0;
-
- // put messages into a test queue
- enqueueGivenNumberOfMessages(_queue, messageNumber);
-
- // dequeue message on top
- dequeueMessage(_queue, dequeueMessageIndex);
-
- //delete message from top
- _queue.deleteMessageFromTop();
-
- //get queue netries
- List<QueueEntry> entries = _queue.getMessagesOnTheQueue();
-
- // assert queue entries
- assertNotNull("Null is returned from getMessagesOnTheQueue", entries);
- assertEquals("Expected " + (messageNumber - 2) + " number of messages but recieved " + entries.size(),
- messageNumber - 2, entries.size());
- assertEquals("Expected first entry with id 2", new Long(2),
- ((AMQMessage) entries.get(0).getMessage()).getMessageId());
- }
-
- /**
- * Tests that all messages including dequeued one are deleted from the queue
- * on invocation of {@link SimpleAMQQueue#clearQueue(StoreContext)}
- */
- public void testClearQueueWithDequeuedEntry()
- {
- int messageNumber = 4;
- int dequeueMessageIndex = 1;
-
- // put messages into a test queue
- enqueueGivenNumberOfMessages(_queue, messageNumber);
-
- // dequeue message on a test queue
- dequeueMessage(_queue, dequeueMessageIndex);
-
- // clean queue
- try
- {
- _queue.clearQueue();
- }
- catch (AMQException e)
- {
- fail("Failure to clear queue:" + e.getMessage());
- }
-
- // get queue entries
- List<QueueEntry> entries = _queue.getMessagesOnTheQueue();
-
- // assert queue entries
- assertNotNull(entries);
- assertEquals(0, entries.size());
- }
-
- /**
- * Tests whether dequeued entry is sent to subscriber in result of
- * invocation of {@link SimpleAMQQueue#processQueue(QueueRunner)}
- */
- public void testProcessQueueWithDequeuedEntry()
- {
- // total number of messages to send
- int messageNumber = 4;
- int dequeueMessageIndex = 1;
-
- // create queue with overridden method deliverAsync
- SimpleAMQQueue testQueue = new SimpleAMQQueue(new AMQShortString("test"), false,
- new AMQShortString("testOwner"), false, false, _virtualHost, null)
- {
- @Override
- public void deliverAsync(Subscription sub)
- {
- // do nothing
- }
- };
-
- // put messages
- List<QueueEntry> entries = enqueueGivenNumberOfMessages(testQueue, messageNumber);
-
- // dequeue message
- dequeueMessage(testQueue, dequeueMessageIndex);
-
- // latch to wait for message receipt
- final CountDownLatch latch = new CountDownLatch(messageNumber -1);
-
- // create a subscription
- MockSubscription subscription = new MockSubscription()
- {
- /**
- * Send a message and decrement latch
- */
- public void send(QueueEntry msg) throws AMQException
- {
- super.send(msg);
- latch.countDown();
- }
- };
-
- try
- {
- // subscribe
- testQueue.registerSubscription(subscription, false);
-
- // process queue
- testQueue.processQueue(new QueueRunner(testQueue, 1)
- {
- public void run()
- {
- // do nothing
- }
- });
- }
- catch (AMQException e)
- {
- fail("Failure to process queue:" + e.getMessage());
- }
- // wait up to 1 minute for message receipt
- try
- {
- latch.await(1, TimeUnit.MINUTES);
- }
- catch (InterruptedException e1)
- {
- Thread.currentThread().interrupt();
- }
- List<QueueEntry> expected = createEntriesList(entries.get(0), entries.get(2), entries.get(3));
- verifyRecievedMessages(expected, subscription.getMessages());
- }
-
- /**
- * Tests that entry in dequeued state are not enqueued and not delivered to subscription
- */
- public void testEqueueDequeuedEntry()
- {
- // create a queue where each even entry is considered a dequeued
- SimpleAMQQueue queue = new SimpleAMQQueue(new AMQShortString("test"), false, new AMQShortString("testOwner"),
- false, false, _virtualHost, new QueueEntryListFactory()
- {
- public QueueEntryList createQueueEntryList(AMQQueue queue)
- {
- /**
- * Override SimpleQueueEntryList to create a dequeued
- * entries for messages with even id
- */
- return new SimpleQueueEntryList(queue)
- {
- /**
- * Entries with even message id are considered
- * dequeued!
- */
- protected QueueEntryImpl createQueueEntry(final ServerMessage message)
- {
- return new QueueEntryImpl(this, message)
- {
- public boolean isDequeued()
- {
- return (((AMQMessage) message).getMessageId().longValue() % 2 == 0);
- }
-
- public boolean isDispensed()
- {
- return (((AMQMessage) message).getMessageId().longValue() % 2 == 0);
- }
-
- public boolean isAvailable()
- {
- return !(((AMQMessage) message).getMessageId().longValue() % 2 == 0);
- }
- };
- }
- };
- }
- }, null);
- // create a subscription
- MockSubscription subscription = new MockSubscription();
-
- // register subscription
- try
- {
- queue.registerSubscription(subscription, false);
- }
- catch (AMQException e)
- {
- fail("Failure to register subscription:" + e.getMessage());
- }
-
- // put test messages into a queue
- putGivenNumberOfMessages(queue, 4);
-
- // assert received messages
- List<QueueEntry> messages = subscription.getMessages();
- assertEquals("Only 2 messages should be returned", 2, messages.size());
- assertEquals("ID of first message should be 1", new Long(1),
- ((AMQMessage) messages.get(0).getMessage()).getMessageId());
- assertEquals("ID of second message should be 3", new Long(3),
- ((AMQMessage) messages.get(1).getMessage()).getMessageId());
- }
-
- /**
- * A helper method to create a queue with given name
- *
- * @param name
- * queue name
- * @return queue
- */
- private SimpleAMQQueue createQueue(String name)
- {
- SimpleAMQQueue queue = null;
- try
- {
- AMQShortString queueName = new AMQShortString(name);
- AMQShortString ownerName = new AMQShortString(name + "Owner");
- queue = (SimpleAMQQueue) AMQQueueFactory.createAMQQueueImpl(queueName, false, ownerName, false, false,
- _virtualHost, _arguments);
- }
- catch (AMQException e)
- {
- fail("Failure to create a queue:" + e.getMessage());
- }
- assertNotNull("Queue was not created", queue);
- return queue;
- }
-
- /**
- * A helper method to put given number of messages into queue
- * <p>
- * All messages are asserted that they are present on queue
- *
- * @param queue
- * queue to put messages into
- * @param messageNumber
- * number of messages to put into queue
- */
- private List<QueueEntry> enqueueGivenNumberOfMessages(AMQQueue queue, int messageNumber)
- {
- putGivenNumberOfMessages(queue, messageNumber);
-
- // make sure that all enqueued messages are on the queue
- List<QueueEntry> entries = queue.getMessagesOnTheQueue();
- assertEquals(messageNumber, entries.size());
- for (int i = 0; i < messageNumber; i++)
- {
- assertEquals(new Long(i), ((AMQMessage)entries.get(i).getMessage()).getMessageId());
- }
- return entries;
- }
-
- /**
- * A helper method to put given number of messages into queue
- * <p>
- * Queue is not checked if messages are added into queue
- *
- * @param queue
- * queue to put messages into
- * @param messageNumber
- * number of messages to put into queue
- * @param queue
- * @param messageNumber
- */
- private void putGivenNumberOfMessages(AMQQueue queue, int messageNumber)
- {
- for (int i = 0; i < messageNumber; i++)
- {
- // Create message
- Long messageId = new Long(i);
- AMQMessage message = null;
- try
- {
- message = createMessage(messageId);
- }
- catch (AMQException e)
- {
- fail("Failure to create a test message:" + e.getMessage());
- }
- // Put message on queue
- try
- {
- queue.enqueue(message);
- }
- catch (AMQException e)
- {
- fail("Failure to put message on queue:" + e.getMessage());
- }
- }
- }
-
- /**
- * A helper method to dequeue an entry on queue with given index
- *
- * @param queue
- * queue to dequeue message on
- * @param dequeueMessageIndex
- * entry index to dequeue.
- */
- private QueueEntry dequeueMessage(AMQQueue queue, int dequeueMessageIndex)
- {
- List<QueueEntry> entries = queue.getMessagesOnTheQueue();
- QueueEntry entry = entries.get(dequeueMessageIndex);
- entry.acquire();
- entry.dequeue();
- assertTrue(entry.isDequeued());
- return entry;
- }
-
- private List<QueueEntry> createEntriesList(QueueEntry... entries)
- {
- ArrayList<QueueEntry> entriesList = new ArrayList<QueueEntry>();
- for (QueueEntry entry : entries)
- {
- entriesList.add(entry);
- }
- return entriesList;
- }
-
- private void verifyRecievedMessages(List<QueueEntry> expected,
- List<QueueEntry> delivered)
- {
- assertEquals("Consumer did not receive the expected number of messages",
- expected.size(), delivered.size());
-
- for (QueueEntry msg : expected)
- {
- assertTrue("Consumer did not recieve msg: "
- + msg.getMessage().getMessageNumber(), delivered.contains(msg));
- }
- }
-
public class TestMessage extends AMQMessage
{
private final long _tag;
@@ -1327,20 +747,4 @@ public class SimpleAMQQueueTest extends InternalBrokerBaseCase
AMQMessage messageA = new TestMessage(id, id, info);
return messageA;
}
-
- class TestSimpleQueueEntryListFactory implements QueueEntryListFactory
- {
- QueueEntryList _list;
-
- public QueueEntryList createQueueEntryList(AMQQueue queue)
- {
- _list = new SimpleQueueEntryList(queue);
- return _list;
- }
-
- public QueueEntryList getQueueEntryList()
- {
- return _list;
- }
- }
}
diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/SimpleQueueEntryListTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/SimpleQueueEntryListTest.java
index 7136f07ca5..320a75045a 100644
--- a/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/SimpleQueueEntryListTest.java
+++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/SimpleQueueEntryListTest.java
@@ -23,7 +23,6 @@ package org.apache.qpid.server.queue;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
-import org.apache.qpid.AMQException;
import org.apache.qpid.server.message.AMQMessage;
import junit.framework.TestCase;
@@ -156,55 +155,5 @@ public class SimpleQueueEntryListTest extends TestCase
assertEquals("Count should have been equal",count,remainingMessages.size());
}
-
- public void testDequedMessagedNotPresentInIterator()
- {
- int numberOfMessages = 10;
- SimpleQueueEntryList entryList = new SimpleQueueEntryList(new MockAMQQueue("test"));
- QueueEntry[] entries = new QueueEntry[numberOfMessages];
-
- for(int i = 0; i < numberOfMessages ; i++)
- {
- AMQMessage message = null;;
- try
- {
- message = new MockAMQMessage(i);
- }
- catch (AMQException e)
- {
- fail("Failure to create a mock message:" + e.getMessage());
- }
- QueueEntry entry = entryList.add(message);
- assertNotNull("QE should not be null", entry);
- entries[i]= entry;
- }
-
- // dequeue all even messages
- for (QueueEntry queueEntry : entries)
- {
- long i = ((AMQMessage)queueEntry.getMessage()).getMessageId().longValue();
- if (i%2 == 0)
- {
- queueEntry.acquire();
- queueEntry.dequeue();
- }
- }
-
- // iterate and check that dequeued messages are not returned by iterator
- QueueEntryIterator it = entryList.iterator();
- int counter = 0;
- int i = 1;
- while (it.advance())
- {
- QueueEntry entry = it.getNode();
- Long id = ((AMQMessage)entry.getMessage()).getMessageId();
- assertEquals("Expected message with id " + i + " but got message with id "
- + id, new Long(i), id);
- counter++;
- i += 2;
- }
- int expectedNumber = numberOfMessages / 2;
- assertEquals("Expected " + expectedNumber + " number of entries in iterator but got " + counter,
- expectedNumber, counter);
- }
+
}
diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/manager/PrincipalDatabaseAuthenticationManagerTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/manager/PrincipalDatabaseAuthenticationManagerTest.java
deleted file mode 100644
index b10442d7db..0000000000
--- a/qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/manager/PrincipalDatabaseAuthenticationManagerTest.java
+++ /dev/null
@@ -1,358 +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.security.auth.manager;
-
-import java.io.BufferedWriter;
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.FileWriter;
-import java.security.Provider;
-import java.security.Security;
-
-import javax.security.auth.Subject;
-import javax.security.sasl.SaslException;
-import javax.security.sasl.SaslServer;
-
-import org.apache.commons.configuration.CompositeConfiguration;
-import org.apache.commons.configuration.ConfigurationException;
-import org.apache.commons.configuration.XMLConfiguration;
-import org.apache.qpid.server.configuration.plugins.ConfigurationPlugin;
-import org.apache.qpid.server.security.auth.AuthenticationResult;
-import org.apache.qpid.server.security.auth.AuthenticationResult.AuthenticationStatus;
-import org.apache.qpid.server.security.auth.database.PlainPasswordFilePrincipalDatabase;
-import org.apache.qpid.server.security.auth.sasl.UsernamePrincipal;
-import org.apache.qpid.server.util.InternalBrokerBaseCase;
-
-/**
- *
- * Tests the public methods of PrincipalDatabaseAuthenticationManager.
- *
- */
-public class PrincipalDatabaseAuthenticationManagerTest extends InternalBrokerBaseCase
-{
- private AuthenticationManager _manager = null; // Class under test
- private String TEST_USERNAME = "guest";
- private String TEST_PASSWORD = "guest";
-
- /**
- * @see org.apache.qpid.server.util.InternalBrokerBaseCase#tearDown()
- */
- @Override
- public void tearDown() throws Exception
- {
- super.tearDown();
- if (_manager != null)
- {
- _manager.close();
- }
- }
-
- /**
- * @see org.apache.qpid.server.util.InternalBrokerBaseCase#setUp()
- */
- @Override
- public void setUp() throws Exception
- {
- super.setUp();
-
- final String passwdFilename = createPasswordFile().getCanonicalPath();
- final ConfigurationPlugin config = getConfig(PlainPasswordFilePrincipalDatabase.class.getName(),
- "passwordFile", passwdFilename);
-
- _manager = PrincipalDatabaseAuthenticationManager.FACTORY.newInstance(config);
- }
-
- /**
- * Tests where the case where the config specifies a PD implementation
- * that is not found.
- */
- public void testPrincipalDatabaseImplementationNotFound() throws Exception
- {
- try
- {
- _manager = PrincipalDatabaseAuthenticationManager.FACTORY.newInstance(getConfig("not.Found", null, null));
- fail("Exception not thrown");
- }
- catch (ConfigurationException ce)
- {
- // PASS
- }
- }
-
- /**
- * Tests where the case where the config specifies a PD implementation
- * of the wrong type.
- */
- public void testPrincipalDatabaseImplementationWrongType() throws Exception
- {
- try
- {
- _manager = PrincipalDatabaseAuthenticationManager.FACTORY.newInstance(getConfig(String.class.getName(), null, null)); // Not a PrincipalDatabase implementation
- fail("Exception not thrown");
- }
- catch (ConfigurationException ce)
- {
- // PASS
- }
- }
-
- /**
- * Tests the case where a setter with the desired name cannot be found.
- */
- public void testPrincipalDatabaseSetterNotFound() throws Exception
- {
- try
- {
- _manager = PrincipalDatabaseAuthenticationManager.FACTORY.newInstance(getConfig(PlainPasswordFilePrincipalDatabase.class.getName(), "noMethod", "test"));
- fail("Exception not thrown");
- }
- catch (ConfigurationException ce)
- {
- // PASS
- }
- }
-
- /**
- * QPID-1347. Make sure the exception message and stack trace is reasonable for an absent password file.
- */
- public void testPrincipalDatabaseThrowsSetterFileNotFound() throws Exception
- {
- try
- {
- _manager = PrincipalDatabaseAuthenticationManager.FACTORY.newInstance(getConfig(PlainPasswordFilePrincipalDatabase.class.getName(), "passwordFile", "/not/found"));
- fail("Exception not thrown");
- }
- catch (ConfigurationException ce)
- {
- // PASS
- assertNotNull("Expected an underlying cause", ce.getCause());
- assertEquals(FileNotFoundException.class, ce.getCause().getClass());
- }
- }
-
- /**
- * Tests that the PDAM registers SASL mechanisms correctly with the runtime.
- */
- public void testRegisteredMechanisms() throws Exception
- {
- assertNotNull(_manager.getMechanisms());
- // relies on those mechanisms attached to PropertiesPrincipalDatabaseManager
- assertEquals("AMQPLAIN PLAIN CRAM-MD5", _manager.getMechanisms());
-
- Provider qpidProvider = Security.getProvider(PrincipalDatabaseAuthenticationManager.PROVIDER_NAME);
- assertNotNull(qpidProvider);
- }
-
- /**
- * Tests that the SASL factory method createSaslServer correctly
- * returns a non-null implementation.
- */
- public void testSaslMechanismCreation() throws Exception
- {
- SaslServer server = _manager.createSaslServer("CRAM-MD5", "localhost");
- assertNotNull(server);
- // Merely tests the creation of the mechanism. Mechanisms themselves are tested
- // by their own tests.
- }
-
- /**
- * Tests that the authenticate method correctly interprets an
- * authentication success.
- *
- */
- public void testSaslAuthenticationSuccess() throws Exception
- {
- SaslServer testServer = createTestSaslServer(true, false);
-
- AuthenticationResult result = _manager.authenticate(testServer, "12345".getBytes());
- final Subject subject = result.getSubject();
- assertTrue(subject.getPrincipals().contains(new UsernamePrincipal("guest")));
- assertEquals(AuthenticationStatus.SUCCESS, result.getStatus());
- }
-
- /**
- *
- * Tests that the authenticate method correctly interprets an
- * authentication not complete.
- *
- */
- public void testSaslAuthenticationNotCompleted() throws Exception
- {
- SaslServer testServer = createTestSaslServer(false, false);
-
- AuthenticationResult result = _manager.authenticate(testServer, "12345".getBytes());
- assertNull(result.getSubject());
- assertEquals(AuthenticationStatus.CONTINUE, result.getStatus());
- }
-
- /**
- *
- * Tests that the authenticate method correctly interprets an
- * authentication error.
- *
- */
- public void testSaslAuthenticationError() throws Exception
- {
- SaslServer testServer = createTestSaslServer(false, true);
-
- AuthenticationResult result = _manager.authenticate(testServer, "12345".getBytes());
- assertNull(result.getSubject());
- assertEquals(AuthenticationStatus.ERROR, result.getStatus());
- }
-
- /**
- * Tests that the authenticate method correctly interprets an
- * authentication success.
- *
- */
- public void testNonSaslAuthenticationSuccess() throws Exception
- {
- AuthenticationResult result = _manager.authenticate("guest", "guest");
- final Subject subject = result.getSubject();
- assertFalse("Subject should not be set read-only", subject.isReadOnly());
- assertTrue(subject.getPrincipals().contains(new UsernamePrincipal("guest")));
- assertEquals(AuthenticationStatus.SUCCESS, result.getStatus());
- }
-
- /**
- * Tests that the authenticate method correctly interprets an
- * authentication success.
- *
- */
- public void testNonSaslAuthenticationNotCompleted() throws Exception
- {
- AuthenticationResult result = _manager.authenticate("guest", "wrongpassword");
- assertNull(result.getSubject());
- assertEquals(AuthenticationStatus.CONTINUE, result.getStatus());
- }
-
- /**
- * Tests the ability to de-register the provider.
- */
- public void testClose() throws Exception
- {
- assertEquals("AMQPLAIN PLAIN CRAM-MD5", _manager.getMechanisms());
- assertNotNull(Security.getProvider(PrincipalDatabaseAuthenticationManager.PROVIDER_NAME));
-
- _manager.close();
-
- // Check provider has been removed.
- assertNull(_manager.getMechanisms());
- assertNull(Security.getProvider(PrincipalDatabaseAuthenticationManager.PROVIDER_NAME));
- _manager = null;
- }
-
- /**
- * Test SASL implementation used to test the authenticate() method.
- */
- private SaslServer createTestSaslServer(final boolean complete, final boolean throwSaslException)
- {
- return new SaslServer()
- {
- public String getMechanismName()
- {
- return null;
- }
-
- public byte[] evaluateResponse(byte[] response) throws SaslException
- {
- if (throwSaslException)
- {
- throw new SaslException("Mocked exception");
- }
- return null;
- }
-
- public boolean isComplete()
- {
- return complete;
- }
-
- public String getAuthorizationID()
- {
- return complete ? "guest" : null;
- }
-
- public byte[] unwrap(byte[] incoming, int offset, int len) throws SaslException
- {
- return null;
- }
-
- public byte[] wrap(byte[] outgoing, int offset, int len) throws SaslException
- {
- return null;
- }
-
- public Object getNegotiatedProperty(String propName)
- {
- return null;
- }
-
- public void dispose() throws SaslException
- {
- }
- };
- }
-
- private ConfigurationPlugin getConfig(final String clazz, final String argName, final String argValue) throws Exception
- {
- final ConfigurationPlugin config = new PrincipalDatabaseAuthenticationManager.PrincipalDatabaseAuthenticationManagerConfiguration();
-
- XMLConfiguration xmlconfig = new XMLConfiguration();
- xmlconfig.addProperty("pd-auth-manager.principal-database.class", clazz);
-
- if (argName != null)
- {
- xmlconfig.addProperty("pd-auth-manager.principal-database.attributes.attribute.name", argName);
- xmlconfig.addProperty("pd-auth-manager.principal-database.attributes.attribute.value", argValue);
- }
-
- // Create a CompositeConfiguration as this is what the broker uses
- CompositeConfiguration composite = new CompositeConfiguration();
- composite.addConfiguration(xmlconfig);
- config.setConfiguration("security", xmlconfig);
- return config;
- }
-
- private File createPasswordFile() throws Exception
- {
- BufferedWriter writer = null;
- try
- {
- File testFile = File.createTempFile(this.getClass().getName(),"tmp");
- testFile.deleteOnExit();
-
- writer = new BufferedWriter(new FileWriter(testFile));
- writer.write(TEST_USERNAME + ":" + TEST_PASSWORD);
- writer.newLine();
-
- return testFile;
-
- }
- finally
- {
- if (writer != null)
- {
- writer.close();
- }
- }
- }
-}
diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/rmi/RMIPasswordAuthenticatorTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/rmi/RMIPasswordAuthenticatorTest.java
index 6dc7b19d3d..e8c24da68d 100644
--- a/qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/rmi/RMIPasswordAuthenticatorTest.java
+++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/rmi/RMIPasswordAuthenticatorTest.java
@@ -20,125 +20,188 @@
*/
package org.apache.qpid.server.security.auth.rmi;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
import java.util.Collections;
import javax.management.remote.JMXPrincipal;
import javax.security.auth.Subject;
-import javax.security.sasl.SaslException;
-import javax.security.sasl.SaslServer;
-import junit.framework.TestCase;
+import org.apache.qpid.server.security.auth.database.Base64MD5PasswordFilePrincipalDatabase;
+import org.apache.qpid.server.security.auth.database.PlainPasswordFilePrincipalDatabase;
-import org.apache.qpid.server.configuration.plugins.ConfigurationPlugin;
-import org.apache.qpid.server.security.auth.AuthenticationResult;
-import org.apache.qpid.server.security.auth.AuthenticationResult.AuthenticationStatus;
-import org.apache.qpid.server.security.auth.manager.AuthenticationManager;
+import junit.framework.TestCase;
-/**
- * Tests the RMIPasswordAuthenticator and its collaboration with the AuthenticationManager.
- *
- */
public class RMIPasswordAuthenticatorTest extends TestCase
{
private final String USERNAME = "guest";
private final String PASSWORD = "guest";
+ private final String B64_MD5HASHED_PASSWORD = "CE4DQ6BIb/BVMN9scFyLtA==";
private RMIPasswordAuthenticator _rmipa;
- private String[] _credentials;
+
+ private Base64MD5PasswordFilePrincipalDatabase _md5Pd;
+ private File _md5PwdFile;
+
+ private PlainPasswordFilePrincipalDatabase _plainPd;
+ private File _plainPwdFile;
+
+ private Subject testSubject;
protected void setUp() throws Exception
{
_rmipa = new RMIPasswordAuthenticator();
- _credentials = new String[] {USERNAME, PASSWORD};
- }
-
- /**
- * Tests a successful authentication. Ensures that a populated read-only subject it returned.
- */
- public void testAuthenticationSuccess()
- {
- final Subject expectedSubject = new Subject(true,
+ _md5Pd = new Base64MD5PasswordFilePrincipalDatabase();
+ _md5PwdFile = createTempPasswordFile(this.getClass().getName()+"md5pwd", USERNAME, B64_MD5HASHED_PASSWORD);
+ _md5Pd.setPasswordFile(_md5PwdFile.getAbsolutePath());
+
+ _plainPd = new PlainPasswordFilePrincipalDatabase();
+ _plainPwdFile = createTempPasswordFile(this.getClass().getName()+"plainpwd", USERNAME, PASSWORD);
+ _plainPd.setPasswordFile(_plainPwdFile.getAbsolutePath());
+
+ testSubject = new Subject(true,
Collections.singleton(new JMXPrincipal(USERNAME)),
Collections.EMPTY_SET,
Collections.EMPTY_SET);
+ }
+
+ private File createTempPasswordFile(String filenamePrefix, String user, String password)
+ {
+ try
+ {
+ File testFile = File.createTempFile(filenamePrefix,"tmp");
+ testFile.deleteOnExit();
+
+ BufferedWriter writer = new BufferedWriter(new FileWriter(testFile));
- _rmipa.setAuthenticationManager(createTestAuthenticationManager(true, null));
+ writer.write(user + ":" + password);
+ writer.newLine();
+ writer.flush();
+ writer.close();
- Subject newSubject = _rmipa.authenticate(_credentials);
- assertTrue("Subject must be readonly", newSubject.isReadOnly());
- assertTrue("Returned subject does not equal expected value",
- newSubject.equals(expectedSubject));
+ return testFile;
+ }
+ catch (IOException e)
+ {
+ fail("Unable to create temporary test password file." + e.getMessage());
+ }
+ return null;
}
+
+
+ //********** Test Methods *********//
+
- /**
- * Tests a unsuccessful authentication.
- */
- public void testUsernameOrPasswordInvalid()
+ public void testAuthenticate()
{
- _rmipa.setAuthenticationManager(createTestAuthenticationManager(false, null));
-
+ String[] credentials;
+ Subject newSubject;
+
+ // Test when no PD has been set
try
{
- _rmipa.authenticate(_credentials);
- fail("Exception not thrown");
+ credentials = new String[]{USERNAME, PASSWORD};
+ newSubject = _rmipa.authenticate(credentials);
+ fail("SecurityException expected due to lack of principal database");
}
catch (SecurityException se)
{
assertEquals("Unexpected exception message",
- RMIPasswordAuthenticator.INVALID_CREDENTIALS, se.getMessage());
-
+ RMIPasswordAuthenticator.UNABLE_TO_LOOKUP, se.getMessage());
}
- }
- /**
- * Tests case where authentication system itself fails.
- */
- public void testAuthenticationFailure()
- {
- final Exception mockAuthException = new Exception("Mock Auth system failure");
- _rmipa.setAuthenticationManager(createTestAuthenticationManager(false, mockAuthException));
+ //The PrincipalDatabase's are tested primarily by their own tests, but
+ //minimal tests are done here to exercise their usage in this area.
+
+ // Test correct passwords are verified with an MD5 PD
+ try
+ {
+ _rmipa.setPrincipalDatabase(_md5Pd);
+ credentials = new String[]{USERNAME, PASSWORD};
+ newSubject = _rmipa.authenticate(credentials);
+ assertTrue("Returned subject does not equal expected value",
+ newSubject.equals(testSubject));
+ }
+ catch (Exception e)
+ {
+ fail("Unexpected Exception:" + e.getMessage());
+ }
+ // Test incorrect passwords are not verified with an MD5 PD
try
{
- _rmipa.authenticate(_credentials);
- fail("Exception not thrown");
+ credentials = new String[]{USERNAME, PASSWORD+"incorrect"};
+ newSubject = _rmipa.authenticate(credentials);
+ fail("SecurityException expected due to incorrect password");
}
catch (SecurityException se)
{
- assertEquals("Initial cause not found", mockAuthException, se.getCause());
+ assertEquals("Unexpected exception message",
+ RMIPasswordAuthenticator.INVALID_CREDENTIALS, se.getMessage());
+ }
+
+ // Test non-existent accounts are not verified with an MD5 PD
+ try
+ {
+ credentials = new String[]{USERNAME+"invalid", PASSWORD};
+ newSubject = _rmipa.authenticate(credentials);
+ fail("SecurityException expected due to non-existant account");
+ }
+ catch (SecurityException se)
+ {
+ assertEquals("Unexpected exception message",
+ RMIPasswordAuthenticator.INVALID_CREDENTIALS, se.getMessage());
}
- }
+ // Test correct passwords are verified with a Plain PD
+ try
+ {
+ _rmipa.setPrincipalDatabase(_plainPd);
+ credentials = new String[]{USERNAME, PASSWORD};
+ newSubject = _rmipa.authenticate(credentials);
+ assertTrue("Returned subject does not equal expected value",
+ newSubject.equals(testSubject));
+ }
+ catch (Exception e)
+ {
+ fail("Unexpected Exception");
+ }
- /**
- * Tests case where authentication manager is not set.
- */
- public void testNullAuthenticationManager()
- {
+ // Test incorrect passwords are not verified with a Plain PD
try
{
- _rmipa.authenticate(_credentials);
- fail("SecurityException expected due to lack of authentication manager");
+ credentials = new String[]{USERNAME, PASSWORD+"incorrect"};
+ newSubject = _rmipa.authenticate(credentials);
+ fail("SecurityException expected due to incorrect password");
}
catch (SecurityException se)
{
assertEquals("Unexpected exception message",
- RMIPasswordAuthenticator.UNABLE_TO_LOOKUP, se.getMessage());
+ RMIPasswordAuthenticator.INVALID_CREDENTIALS, se.getMessage());
+ }
+
+ // Test non-existent accounts are not verified with an Plain PD
+ try
+ {
+ credentials = new String[]{USERNAME+"invalid", PASSWORD};
+ newSubject = _rmipa.authenticate(credentials);
+ fail("SecurityException expected due to non existant account");
+ }
+ catch (SecurityException se)
+ {
+ assertEquals("Unexpected exception message",
+ RMIPasswordAuthenticator.INVALID_CREDENTIALS, se.getMessage());
}
- }
- /**
- * Tests case where arguments are non-Strings..
- */
- public void testWithNonStringArrayArgument()
- {
// Test handling of non-string credential's
- final Object[] objCredentials = new Object[]{USERNAME, PASSWORD};
try
{
- _rmipa.authenticate(objCredentials);
+ Object[] objCredentials = new Object[]{USERNAME, PASSWORD};
+ newSubject = _rmipa.authenticate(objCredentials);
fail("SecurityException expected due to non string[] credentials");
}
catch (SecurityException se)
@@ -146,18 +209,12 @@ public class RMIPasswordAuthenticatorTest extends TestCase
assertEquals("Unexpected exception message",
RMIPasswordAuthenticator.SHOULD_BE_STRING_ARRAY, se.getMessage());
}
- }
-
- /**
- * Tests case where there are too many, too few or null arguments.
- */
- public void testWithIllegalNumberOfArguments()
- {
- // Test handling of incorrect number of credentials
+
+ // Test handling of incorrect number of credential's
try
{
- _credentials = new String[]{USERNAME, PASSWORD, PASSWORD};
- _rmipa.authenticate(_credentials);
+ credentials = new String[]{USERNAME, PASSWORD, PASSWORD};
+ newSubject = _rmipa.authenticate(credentials);
fail("SecurityException expected due to supplying wrong number of credentials");
}
catch (SecurityException se)
@@ -166,12 +223,12 @@ public class RMIPasswordAuthenticatorTest extends TestCase
RMIPasswordAuthenticator.SHOULD_HAVE_2_ELEMENTS, se.getMessage());
}
- // Test handling of null credentials
+ // Test handling of null credential's
try
{
//send a null array
- _credentials = null;
- _rmipa.authenticate(_credentials);
+ credentials = null;
+ newSubject = _rmipa.authenticate(credentials);
fail("SecurityException expected due to not supplying an array of credentials");
}
catch (SecurityException se)
@@ -183,8 +240,8 @@ public class RMIPasswordAuthenticatorTest extends TestCase
try
{
//send a null password
- _credentials = new String[]{USERNAME, null};
- _rmipa.authenticate(_credentials);
+ credentials = new String[]{USERNAME, null};
+ newSubject = _rmipa.authenticate(credentials);
fail("SecurityException expected due to sending a null password");
}
catch (SecurityException se)
@@ -196,8 +253,8 @@ public class RMIPasswordAuthenticatorTest extends TestCase
try
{
//send a null username
- _credentials = new String[]{null, PASSWORD};
- _rmipa.authenticate(_credentials);
+ credentials = new String[]{null, PASSWORD};
+ newSubject = _rmipa.authenticate(credentials);
fail("SecurityException expected due to sending a null username");
}
catch (SecurityException se)
@@ -207,54 +264,4 @@ public class RMIPasswordAuthenticatorTest extends TestCase
}
}
- private AuthenticationManager createTestAuthenticationManager(final boolean successfulAuth, final Exception exception)
- {
- return new AuthenticationManager()
- {
- public void configure(ConfigurationPlugin config)
- {
- throw new UnsupportedOperationException();
- }
-
- public void initialise()
- {
- throw new UnsupportedOperationException();
- }
-
- public void close()
- {
- throw new UnsupportedOperationException();
- }
-
- public String getMechanisms()
- {
- throw new UnsupportedOperationException();
- }
-
- public SaslServer createSaslServer(String mechanism, String localFQDN) throws SaslException
- {
- throw new UnsupportedOperationException();
- }
-
- public AuthenticationResult authenticate(SaslServer server, byte[] response)
- {
- throw new UnsupportedOperationException();
- }
-
- public AuthenticationResult authenticate(String username, String password)
- {
- if (exception != null) {
- return new AuthenticationResult(AuthenticationStatus.ERROR, exception);
- }
- else if (successfulAuth)
- {
- return new AuthenticationResult(new Subject());
- }
- else
- {
- return new AuthenticationResult(AuthenticationStatus.CONTINUE);
- }
- }
- };
- }
}
diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/sasl/CRAMMD5HexServerTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/sasl/CRAMMD5HexServerTest.java
deleted file mode 100644
index 86e4e23750..0000000000
--- a/qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/sasl/CRAMMD5HexServerTest.java
+++ /dev/null
@@ -1,228 +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.security.auth.sasl;
-
-import java.io.File;
-import java.io.IOException;
-import java.security.MessageDigest;
-import java.security.Principal;
-
-import javax.crypto.Mac;
-import javax.crypto.spec.SecretKeySpec;
-import javax.security.auth.login.AccountNotFoundException;
-import javax.security.sasl.SaslException;
-import javax.security.sasl.SaslServer;
-
-import junit.framework.TestCase;
-
-import org.apache.commons.codec.binary.Hex;
-import org.apache.qpid.server.security.auth.database.Base64MD5PasswordFilePrincipalDatabase;
-import org.apache.qpid.server.security.auth.sasl.crammd5.CRAMMD5HexInitialiser;
-import org.apache.qpid.server.security.auth.sasl.crammd5.CRAMMD5HexSaslServer;
-import org.apache.qpid.server.security.auth.sasl.crammd5.CRAMMD5HexServerFactory;
-
-/**
- * Test for the CRAM-MD5-HEX SASL mechanism.
- *
- * This test case focuses on testing {@link CRAMMD5HexSaslServer} but also exercises
- * collaborators {@link CRAMMD5HexInitialiser} and {@link Base64MD5PasswordFilePrincipalDatabase}
- */
-public class CRAMMD5HexServerTest extends TestCase
-{
-
- private SaslServer _saslServer; // Class under test
- private CRAMMD5HexServerFactory _saslFactory;
-
- @Override
- protected void setUp() throws Exception
- {
- super.setUp();
-
- CRAMMD5HexInitialiser _initializer = new CRAMMD5HexInitialiser();
-
- //Use properties to create a PrincipalDatabase
- Base64MD5PasswordFilePrincipalDatabase db = createTestPrincipalDatabase();
- assertEquals("Unexpected number of test users in the db", 2, db.getUsers().size());
-
- _initializer.initialise(db);
-
- _saslFactory = new CRAMMD5HexServerFactory();
-
- _saslServer = _saslFactory.createSaslServer(CRAMMD5HexSaslServer.MECHANISM,
- "AMQP",
- "localhost",
- _initializer.getProperties(),
- _initializer.getCallbackHandler());
- assertNotNull("Unable to create saslServer with mechanism type " + CRAMMD5HexSaslServer.MECHANISM, _saslServer);
-
- }
-
- public void testSuccessfulAuth() throws Exception
- {
-
- final byte[] serverChallenge = _saslServer.evaluateResponse(new byte[0]);
-
- // Generate client response
- final byte[] clientResponse = generateClientResponse("knownuser", "guest", serverChallenge);
-
-
- byte[] nextServerChallenge = _saslServer.evaluateResponse(clientResponse);
- assertTrue("Exchange must be flagged as complete after successful authentication", _saslServer.isComplete());
- assertNull("Next server challenge must be null after successful authentication", nextServerChallenge);
-
- }
-
- public void testKnownUserPresentsWrongPassword() throws Exception
- {
- byte[] serverChallenge = _saslServer.evaluateResponse(new byte[0]);
-
-
- final byte[] clientResponse = generateClientResponse("knownuser", "wrong!", serverChallenge);
- try
- {
- _saslServer.evaluateResponse(clientResponse);
- fail("Exception not thrown");
- }
- catch (SaslException se)
- {
- // PASS
- }
- assertFalse("Exchange must not be flagged as complete after unsuccessful authentication", _saslServer.isComplete());
- }
-
- public void testUnknownUser() throws Exception
- {
- final byte[] serverChallenge = _saslServer.evaluateResponse(new byte[0]);
-
-
- final byte[] clientResponse = generateClientResponse("unknownuser", "guest", serverChallenge);
-
- try
- {
- _saslServer.evaluateResponse(clientResponse);
- fail("Exception not thrown");
- }
- catch (SaslException se)
- {
- assertExceptionHasUnderlyingAsCause(AccountNotFoundException.class, se);
- // PASS
- }
- assertFalse("Exchange must not be flagged as complete after unsuccessful authentication", _saslServer.isComplete());
- }
-
- /**
- *
- * Demonstrates QPID-3158. A defect meant that users with some valid password were failing to
- * authenticate when using the .NET 0-8 client (uses this SASL mechanism).
- * It so happens that password "guest2" was one of the affected passwords.
- *
- * @throws Exception
- */
- public void testSuccessfulAuthReproducingQpid3158() throws Exception
- {
- byte[] serverChallenge = _saslServer.evaluateResponse(new byte[0]);
-
- // Generate client response
- byte[] resp = generateClientResponse("qpid3158user", "guest2", serverChallenge);
-
- byte[] nextServerChallenge = _saslServer.evaluateResponse(resp);
- assertTrue("Exchange must be flagged as complete after successful authentication", _saslServer.isComplete());
- assertNull("Next server challenge must be null after successful authentication", nextServerChallenge);
- }
-
- /**
- * Since we don't have a CRAM-MD5-HEX implementation client implementation in Java, this method
- * provides the implementation for first principals.
- *
- * @param userId user id
- * @param clearTextPassword clear text password
- * @param serverChallenge challenge from server
- *
- * @return challenge response
- */
- private byte[] generateClientResponse(final String userId, final String clearTextPassword, final byte[] serverChallenge) throws Exception
- {
- byte[] digestedPasswordBytes = MessageDigest.getInstance("MD5").digest(clearTextPassword.getBytes());
- char[] hexEncodedDigestedPassword = Hex.encodeHex(digestedPasswordBytes);
- byte[] hexEncodedDigestedPasswordBytes = new String(hexEncodedDigestedPassword).getBytes();
-
-
- Mac hmacMd5 = Mac.getInstance("HmacMD5");
- hmacMd5.init(new SecretKeySpec(hexEncodedDigestedPasswordBytes, "HmacMD5"));
- final byte[] messageAuthenticationCode = hmacMd5.doFinal(serverChallenge);
-
- // Build client response
- String responseAsString = userId + " " + new String(Hex.encodeHex(messageAuthenticationCode));
- byte[] resp = responseAsString.getBytes();
- return resp;
- }
-
- /**
- * Creates a test principal database.
- *
- * @return
- * @throws IOException
- */
- private Base64MD5PasswordFilePrincipalDatabase createTestPrincipalDatabase() throws IOException
- {
- Base64MD5PasswordFilePrincipalDatabase db = new Base64MD5PasswordFilePrincipalDatabase();
- File file = File.createTempFile("passwd", "db");
- file.deleteOnExit();
- db.setPasswordFile(file.getCanonicalPath());
- db.createPrincipal( createTestPrincipal("knownuser"), "guest".toCharArray());
- db.createPrincipal( createTestPrincipal("qpid3158user"), "guest2".toCharArray());
- return db;
- }
-
- private Principal createTestPrincipal(final String name)
- {
- return new Principal()
- {
- public String getName()
- {
- return name;
- }
- };
- }
-
- private void assertExceptionHasUnderlyingAsCause(final Class<? extends Throwable> expectedUnderlying, Throwable e)
- {
- assertNotNull(e);
- int infiniteLoopGuard = 0; // Guard against loops in the cause chain
- boolean foundExpectedUnderlying = false;
- while (e.getCause() != null && infiniteLoopGuard++ < 10)
- {
- if (expectedUnderlying.equals(e.getCause().getClass()))
- {
- foundExpectedUnderlying = true;
- break;
- }
- e = e.getCause();
- }
-
- if (!foundExpectedUnderlying)
- {
- fail("Not found expected underlying exception " + expectedUnderlying + " as underlying cause of " + e.getClass());
- }
- }
-
-}
diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/sasl/GroupPrincipalTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/sasl/GroupPrincipalTest.java
deleted file mode 100644
index 076b7c9248..0000000000
--- a/qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/sasl/GroupPrincipalTest.java
+++ /dev/null
@@ -1,86 +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.security.auth.sasl;
-
-import junit.framework.TestCase;
-
-public class GroupPrincipalTest extends TestCase
-{
- public void testGetName()
- {
- final GroupPrincipal principal = new GroupPrincipal("group");
- assertEquals("group", principal.getName());
- }
-
- public void testAddRejected()
- {
- final GroupPrincipal principal = new GroupPrincipal("group");
- final UsernamePrincipal user = new UsernamePrincipal("name");
-
- try
- {
- principal.addMember(user);
- fail("Exception not thrown");
- }
- catch (UnsupportedOperationException uso)
- {
- // PASS
- }
- }
-
- public void testEqualitySameName()
- {
- final String string = "string";
- final GroupPrincipal principal1 = new GroupPrincipal(string);
- final GroupPrincipal principal2 = new GroupPrincipal(string);
- assertTrue(principal1.equals(principal2));
- }
-
- public void testEqualityEqualName()
- {
- final GroupPrincipal principal1 = new GroupPrincipal(new String("string"));
- final GroupPrincipal principal2 = new GroupPrincipal(new String("string"));
- assertTrue(principal1.equals(principal2));
- }
-
- public void testInequalityDifferentGroupPrincipals()
- {
- GroupPrincipal principal1 = new GroupPrincipal("string1");
- GroupPrincipal principal2 = new GroupPrincipal("string2");
- assertFalse(principal1.equals(principal2));
- }
-
- public void testInequalityNonGroupPrincipal()
- {
- GroupPrincipal principal = new GroupPrincipal("string");
- assertFalse(principal.equals(new UsernamePrincipal("string")));
- }
-
- public void testInequalityNull()
- {
- GroupPrincipal principal = new GroupPrincipal("string");
- assertFalse(principal.equals(null));
- }
-
-
-
-
-}
diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/sasl/TestPrincipalUtils.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/sasl/TestPrincipalUtils.java
deleted file mode 100644
index 8b9b2df5a3..0000000000
--- a/qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/sasl/TestPrincipalUtils.java
+++ /dev/null
@@ -1,49 +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.security.auth.sasl;
-
-import java.security.Principal;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Set;
-
-import javax.security.auth.Subject;
-
-public class TestPrincipalUtils
-{
-
- /**
- * Creates a test subject, with exactly one UsernamePrincipal and zero or more GroupPrincipals.
- */
- public static Subject createTestSubject(final String username, final String... groups)
- {
- final Set<Principal> principals = new HashSet<Principal>(1 + groups.length);
- principals.add(new UsernamePrincipal(username));
- for (String group : groups)
- {
- principals.add(new GroupPrincipal(group));
- }
-
- final Subject subject = new Subject(true, principals, Collections.EMPTY_SET, Collections.EMPTY_SET);
- return subject;
- }
-
-}
diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/sasl/UsernamePrincipalTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/sasl/UsernamePrincipalTest.java
deleted file mode 100644
index 541f14d923..0000000000
--- a/qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/sasl/UsernamePrincipalTest.java
+++ /dev/null
@@ -1,122 +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.security.auth.sasl;
-
-import java.security.Principal;
-import javax.security.auth.Subject;
-import junit.framework.TestCase;
-
-/**
- * Tests the UsernamePrincipal.
- *
- */
-public class UsernamePrincipalTest extends TestCase
-{
- public void testEqualitySameObject()
- {
- final UsernamePrincipal principal = new UsernamePrincipal("string");
- assertTrue(principal.equals(principal));
- }
-
- public void testEqualitySameName()
- {
- final String string = "string";
- final UsernamePrincipal principal1 = new UsernamePrincipal(string);
- final UsernamePrincipal principal2 = new UsernamePrincipal(string);
- assertTrue(principal1.equals(principal2));
- }
-
- public void testEqualityEqualName()
- {
- final UsernamePrincipal principal1 = new UsernamePrincipal(new String("string"));
- final UsernamePrincipal principal2 = new UsernamePrincipal(new String("string"));
- assertTrue(principal1.equals(principal2));
- }
-
- public void testInequalityDifferentUserPrincipals()
- {
- UsernamePrincipal principal1 = new UsernamePrincipal("string1");
- UsernamePrincipal principal2 = new UsernamePrincipal("string2");
- assertFalse(principal1.equals(principal2));
- }
-
- public void testInequalityNonUserPrincipal()
- {
- UsernamePrincipal principal = new UsernamePrincipal("string");
- assertFalse(principal.equals(new String("string")));
- }
-
- public void testInequalityNull()
- {
- UsernamePrincipal principal = new UsernamePrincipal("string");
- assertFalse(principal.equals(null));
- }
-
- public void testGetUsernamePrincipalFromSubject()
- {
- final UsernamePrincipal expected = new UsernamePrincipal("name");
- final Principal other = new Principal()
- {
- public String getName()
- {
- return "otherprincipal";
- }
- };
-
- final Subject subject = new Subject();
- subject.getPrincipals().add(expected);
- subject.getPrincipals().add(other);
-
- final UsernamePrincipal actual = UsernamePrincipal.getUsernamePrincipalFromSubject(subject);
- assertSame(expected, actual);
- }
-
- public void testUsernamePrincipalNotInSubject()
- {
- try
- {
- UsernamePrincipal.getUsernamePrincipalFromSubject(new Subject());
- fail("Exception not thrown");
- }
- catch (IllegalArgumentException iae)
- {
- // PASS
- }
- }
-
- public void testTooManyUsernamePrincipalInSubject()
- {
- final Subject subject = new Subject();
- subject.getPrincipals().add(new UsernamePrincipal("name1"));
- subject.getPrincipals().add(new UsernamePrincipal("name2"));
- try
- {
-
- UsernamePrincipal.getUsernamePrincipalFromSubject(subject);
- fail("Exception not thrown");
- }
- catch (IllegalArgumentException iae)
- {
- // PASS
- }
- }
-
-}
diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/stats/StatisticsCounterTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/stats/StatisticsCounterTest.java
deleted file mode 100644
index fbaa1342c9..0000000000
--- a/qpid/java/broker/src/test/java/org/apache/qpid/server/stats/StatisticsCounterTest.java
+++ /dev/null
@@ -1,144 +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.stats;
-
-import junit.framework.TestCase;
-
-/**
- * Unit tests for the {@link StatisticsCounter} class.
- */
-public class StatisticsCounterTest extends TestCase
-{
- /**
- * Check that statistics counters are created correctly.
- */
- public void testCreate()
- {
- long before = System.currentTimeMillis();
- StatisticsCounter counter = new StatisticsCounter("name", 1234L);
- long after = System.currentTimeMillis();
-
- assertTrue(before <= counter.getStart());
- assertTrue(after >= counter.getStart());
- assertTrue(counter.getName().startsWith("name-"));
- assertEquals(1234L, counter.getPeriod());
- }
-
- /**
- * Check that totals add up correctly.
- */
- public void testTotal()
- {
- StatisticsCounter counter = new StatisticsCounter("test", 1000L);
- long start = counter.getStart();
- for (int i = 0; i < 100; i++)
- {
- counter.registerEvent(i, start + i);
- }
- assertEquals(99 * 50, counter.getTotal()); // cf. Gauss
- }
-
- /**
- * Test totals add up correctly even when messages are delivered
- * out-of-order.
- */
- public void testTotalOutOfOrder()
- {
- StatisticsCounter counter = new StatisticsCounter("test", 1000L);
- long start = counter.getStart();
- assertEquals(0, counter.getTotal());
- counter.registerEvent(10, start + 2500);
- assertEquals(10, counter.getTotal());
- counter.registerEvent(20, start + 1500);
- assertEquals(30, counter.getTotal());
- counter.registerEvent(10, start + 500);
- assertEquals(40, counter.getTotal());
- }
-
- /**
- * Test that the peak rate is reported correctly.
- */
- public void testPeak() throws Exception
- {
- StatisticsCounter counter = new StatisticsCounter("test", 1000L);
- long start = counter.getStart();
- assertEquals(0.0, counter.getPeak());
- Thread.sleep(500);
- counter.registerEvent(1000, start + 500);
- Thread.sleep(1000);
- assertEquals(1000.0, counter.getPeak());
- counter.registerEvent(2000, start + 1500);
- Thread.sleep(1000);
- assertEquals(2000.0, counter.getPeak());
- counter.registerEvent(1000, start + 2500);
- Thread.sleep(1000);
- assertEquals(2000.0, counter.getPeak());
- }
-
- /**
- * Test that peak rate is reported correctly for out-of-order messages,
- * and the total is also unaffected.
- */
- public void testPeakOutOfOrder() throws Exception
- {
- StatisticsCounter counter = new StatisticsCounter("test", 1000L);
- long start = counter.getStart();
- assertEquals(0.0, counter.getPeak());
- counter.registerEvent(1000, start + 2500);
- Thread.sleep(1500);
- assertEquals(0.0, counter.getPeak());
- counter.registerEvent(2000, start + 1500);
- Thread.sleep(1000L);
- assertEquals(0.0, counter.getPeak());
- counter.registerEvent(1000, start + 500);
- Thread.sleep(1500);
- assertEquals(4000.0, counter.getPeak());
- Thread.sleep(2000);
- assertEquals(4000.0, counter.getPeak());
- counter.registerEvent(1000, start + 500);
- assertEquals(4000.0, counter.getPeak());
- Thread.sleep(2000);
- counter.registerEvent(1000);
- assertEquals(4000.0, counter.getPeak());
- assertEquals(6000, counter.getTotal());
- }
-
- /**
- * Test the current rate is generated correctly.
- */
- public void testRate() throws Exception
- {
- StatisticsCounter counter = new StatisticsCounter("test", 1000L);
- assertEquals(0.0, counter.getRate());
- Thread.sleep(500);
- counter.registerEvent(1000);
- Thread.sleep(1000);
- assertEquals(1000.0, counter.getRate());
- counter.registerEvent(2000);
- Thread.sleep(1000);
- assertEquals(2000.0, counter.getRate());
- counter.registerEvent(1000);
- Thread.sleep(1000);
- assertEquals(1000.0, counter.getRate());
- Thread.sleep(1000);
- assertEquals(0.0, counter.getRate());
- }
-}
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 3acd064fd7..3ebe631f62 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
@@ -122,7 +122,6 @@ public class MessageStoreTest extends InternalBrokerBaseCase
}
catch (Exception e)
{
- e.printStackTrace();
fail(e.getMessage());
}
}
@@ -590,7 +589,7 @@ public class MessageStoreTest extends InternalBrokerBaseCase
headerBody.classId = BasicConsumeBodyImpl.CLASS_ID;
headerBody.bodySize = 0;
- headerBody.setProperties(properties);
+ headerBody.properties = properties;
try
{
diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/store/ReferenceCountingTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/store/ReferenceCountingTest.java
index 2d41eb9899..a75cbe8662 100644
--- a/qpid/java/broker/src/test/java/org/apache/qpid/server/store/ReferenceCountingTest.java
+++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/store/ReferenceCountingTest.java
@@ -102,7 +102,7 @@ public class ReferenceCountingTest extends QpidTestCase
ContentHeaderBody chb = new ContentHeaderBody();
BasicContentHeaderProperties bchp = new BasicContentHeaderProperties();
bchp.setDeliveryMode((byte)2);
- chb.setProperties(bchp);
+ chb.properties = bchp;
return chb;
}
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 6fbc627d8c..1ec134e90e 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
@@ -22,7 +22,6 @@ package org.apache.qpid.server.subscription;
*/
import java.util.ArrayList;
-import java.util.List;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
@@ -46,7 +45,6 @@ public class MockSubscription implements Subscription
private State _state = State.ACTIVE;
private ArrayList<QueueEntry> messages = new ArrayList<QueueEntry>();
private final Lock _stateChangeLock = new ReentrantLock();
- private List<QueueEntry> _acceptEntries = null;
private final QueueEntry.SubscriptionAcquiredState _owningState = new QueueEntry.SubscriptionAcquiredState(this);
private final QueueEntry.SubscriptionAssignedState _assignedState = new QueueEntry.SubscriptionAssignedState(this);
@@ -56,15 +54,6 @@ public class MockSubscription implements Subscription
// Create a simple ID that increments for ever new Subscription
private final long _subscriptionID = idGenerator.getAndIncrement();
- public MockSubscription()
- {
- }
-
- public MockSubscription(List<QueueEntry> acceptEntries)
- {
- _acceptEntries = acceptEntries;
- }
-
public void close()
{
_closed = true;
@@ -130,15 +119,8 @@ public class MockSubscription implements Subscription
_stateChangeLock.lock();
}
- public boolean hasInterest(QueueEntry entry)
+ public boolean hasInterest(QueueEntry msg)
{
- if(_acceptEntries != null)
- {
- //simulate selector behaviour, only signal
- //interest in the dictated queue entries
- return _acceptEntries.contains(entry);
- }
-
return true;
}
diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/subscription/SubscriptionListTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/subscription/SubscriptionListTest.java
deleted file mode 100644
index c4d1a1e614..0000000000
--- a/qpid/java/broker/src/test/java/org/apache/qpid/server/subscription/SubscriptionListTest.java
+++ /dev/null
@@ -1,429 +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.subscription;
-
-import org.apache.qpid.server.subscription.SubscriptionList.SubscriptionNode;
-import org.apache.qpid.server.subscription.SubscriptionList.SubscriptionNodeIterator;
-import org.apache.qpid.test.utils.QpidTestCase;
-
-public class SubscriptionListTest extends QpidTestCase
-{
- private SubscriptionList _subList;
- private MockSubscription _sub1;
- private MockSubscription _sub2;
- private MockSubscription _sub3;
- private SubscriptionNode _node;
-
- protected void setUp()
- {
- _subList = new SubscriptionList();
-
- _sub1 = new MockSubscription();
- _sub2 = new MockSubscription();
- _sub3 = new MockSubscription();
-
- _subList.add(_sub1);
- _subList.add(_sub2);
- _subList.add(_sub3);
-
- _node = _subList.getHead();
- }
-
- /**
- * Test that if the first (non-head) node in the list is deleted (but is still present),
- * it is not returned when searching through the list for the next viable node, and the
- * subsequent viable node is returned instead.
- */
- public void testFindNextSkipsFirstDeletedNode()
- {
- assertTrue("Deleting subscription node should have succeeded",
- getNodeForSubscription(_subList, _sub1).delete());
-
- assertNotNull("Returned node should not be null", _node = _node.findNext());
- assertEquals("Should have returned node for 2nd subscription", _sub2, _node.getSubscription());
-
- assertNotNull("Returned node should not be null", _node = _node.findNext());
- assertEquals("Should have returned node for 3rd subscription", _sub3, _node.getSubscription());
- }
-
- /**
- * Test that if a central node in the list is deleted (but is still present),
- * it is not returned when searching through the list for the next viable node,
- * and the subsequent viable node is returned instead.
- */
- public void testFindNextSkipsCentralDeletedNode()
- {
- assertNotNull("Returned node should not be null", _node = _node.findNext());
-
- assertTrue("Deleting subscription node should have succeeded",
- getNodeForSubscription(_subList, _sub2).delete());
-
- assertNotNull("Returned node should not be null", _node = _node.findNext());
- assertEquals("Should have returned node for 3rd subscription", _sub3, _node.getSubscription());
- }
-
- /**
- * Test that if the last node in the list is deleted (but is still present),
- * it is not returned when searching through the list for the next viable node,
- * and null is returned instead.
- */
- public void testFindNextSkipsLastDeletedNode()
- {
- assertNotNull("Returned node should not be null", _node = _node.findNext());
- assertEquals("Should have returned node for 1st subscription", _sub1, _node.getSubscription());
-
- assertNotNull("Returned node should not be null", _node = _node.findNext());
- assertEquals("Should have returned node for 2nd subscription", _sub2, _node.getSubscription());
-
- assertTrue("Deleting subscription node should have succeeded",
- getNodeForSubscription(_subList, _sub3).delete());
-
- assertNull("Returned node should be null", _node = _node.findNext());
- }
-
- /**
- * Test that if multiple nodes in the list are deleted (but still present), they
- * are not returned when searching through the list for the next viable node,
- * and the subsequent viable node is returned instead.
- */
- public void testFindNextSkipsMultipleDeletedNode()
- {
- assertTrue("Deleting subscription node should have succeeded",
- getNodeForSubscription(_subList, _sub1).delete());
- assertTrue("Deleting subscription node should have succeeded",
- getNodeForSubscription(_subList, _sub2).delete());
-
- assertNotNull("Returned node should not be null", _node = _node.findNext());
- assertEquals("Should have returned node for 3rd subscription", _sub3, _node.getSubscription());
- }
-
- /**
- * Test that if a node in the list is marked 'deleted' it is still present in the list
- * until actually removed. counter-test to verify above testing of getNext() method.
- */
- public void testDeletedNodeStillPresent()
- {
- assertTrue("Deleting subscription node should have succeeded",
- getNodeForSubscription(_subList, _sub1).delete());
-
- assertNotNull("Node marked deleted should still be present", getNodeForSubscription(_subList, _sub1));
- assertEquals("All 3 nodes are still expected to be present", 3, countNodes(_subList));
- }
-
- /**
- * Traverses the list nodes in a non-mutating fashion, returning the first node which matches the given
- * Subscription, or null if none is found.
- */
- private SubscriptionNode getNodeForSubscription(final SubscriptionList list, final Subscription sub)
- {
- SubscriptionNode node = list.getHead();
- while (node != null && node.getSubscription() != sub)
- {
- node = node.nextNode();
- }
-
- return node;
- }
-
- /**
- * Counts the number of (non-head) nodes in the list.
- */
- private int countNodes(final SubscriptionList list)
- {
- SubscriptionNode node = list.getHead();
- int count;
- for(count = -1; node != null; count++)
- {
- node = node.nextNode();
- }
-
- return count;
- }
-
- /**
- * Tests that the head is returned as expected, and isn't the node for the first subscription.
- */
- public void testGetHead()
- {
- assertNotNull("List head should be non null", _node);
- assertNotSame("Head should not be node for first subscription",
- _node, getNodeForSubscription(_subList, _sub1));
- }
-
- /**
- * Tests that the size is returned correctly in the face of additions and removals.
- */
- public void testGetSize()
- {
- SubscriptionList subList = new SubscriptionList();
-
- assertEquals("Unexpected size result", 0, subList.size());
-
- Subscription sub1 = new MockSubscription();
- Subscription sub2 = new MockSubscription();
- Subscription sub3 = new MockSubscription();
-
- subList.add(sub1);
- assertEquals("Unexpected size result", 1, subList.size());
-
- subList.add(sub2);
- assertEquals("Unexpected size result", 2, subList.size());
-
- subList.add(sub3);
- assertEquals("Unexpected size result", 3, subList.size());
-
- assertTrue("Removing subscription from list should have succeeded", subList.remove(sub1));
- assertEquals("Unexpected size result", 2, subList.size());
-
- assertTrue("Removing subscription from list should have succeeded", subList.remove(sub2));
- assertEquals("Unexpected size result", 1, subList.size());
-
- assertTrue("Removing subscription from list should have succeeded", subList.remove(sub3));
- assertEquals("Unexpected size result", 0, subList.size());
- }
-
- /**
- * Test that if the first (non-head) node in the list is removed it is no longer
- * present in the node structure of the list at all.
- */
- public void testRemoveFirstNode()
- {
- assertNotNull("Should have been a node present for the subscription", getNodeForSubscription(_subList, _sub1));
- assertTrue("Removing subscription node should have succeeded", _subList.remove(_sub1));
- assertNull("Should not have been a node present for the removed subscription", getNodeForSubscription(_subList, _sub1));
- assertEquals("Unexpected number of nodes", 2, countNodes(_subList));
- assertNotNull("Should have been a node present for the subscription", getNodeForSubscription(_subList, _sub2));
- assertNotNull("Should have been a node present for the subscription", getNodeForSubscription(_subList, _sub3));
- }
-
- /**
- * Test that if a central node in the list is removed it is no longer
- * present in the node structure of the list at all.
- */
- public void testRemoveCentralNode()
- {
- assertNotNull("Should have been a node present for the subscription", getNodeForSubscription(_subList, _sub2));
- assertTrue("Removing subscription node should have succeeded", _subList.remove(_sub2));
- assertNull("Should not have been a node present for the removed subscription", getNodeForSubscription(_subList, _sub2));
- assertEquals("Unexpected number of nodes", 2, countNodes(_subList));
- assertNotNull("Should have been a node present for the subscription", getNodeForSubscription(_subList, _sub1));
- assertNotNull("Should have been a node present for the subscription", getNodeForSubscription(_subList, _sub3));
- }
-
- /**
- * Test that if the subscription contained in the last node of the list is removed
- * it is no longer present in the node structure of the list at all. However,
- * as the last node in the structure can't actually be removed a dummy will instead
- * be present.
- */
- public void testRemoveLastNode()
- {
- assertNotNull("Should have been a node present for the subscription", getNodeForSubscription(_subList, _sub3));
- assertTrue("Removing subscription node should have succeeded", _subList.remove(_sub3));
- assertNull("Should not have been a node present for the removed subscription", getNodeForSubscription(_subList, _sub3));
-
- //We actually expect 3 nodes to remain this time, because the last node cant be removed for thread safety reasons,
- //however a dummy final node can be used as substitute to allow removal of the subscription node.
- assertEquals("Unexpected number of nodes", 2 + 1, countNodes(_subList));
- assertNotNull("Should have been a node present for the subscription", getNodeForSubscription(_subList, _sub1));
- assertNotNull("Should have been a node present for the subscription", getNodeForSubscription(_subList, _sub2));
- }
-
- /**
- * Test that if the subscription not contained in the list is requested to be removed
- * that the removal fails
- */
- public void testRemoveNonExistantNode()
- {
- Subscription sub4 = new MockSubscription();
- assertNull("Should not have been a node present for the subscription", getNodeForSubscription(_subList, sub4));
- assertFalse("Removing subscription node should not have succeeded", _subList.remove(sub4));
- assertEquals("Unexpected number of nodes", 3, countNodes(_subList));
- }
-
- /**
- * Test that if a subscription node which occurs later in the main list than the marked node is
- * removed from the list after the marked node is also removed, then the marker node doesn't
- * serve to retain the subsequent nodes in the list structure (and thus memory) despite their
- * removal.
- */
- public void testDeletedMarkedNodeDoesntLeakSubsequentlyDeletedNodes()
- {
- //get the nodes out the list for the 1st and 3rd subscriptions
- SubscriptionNode sub1Node = getNodeForSubscription(_subList, _sub1);
- assertNotNull("Should have been a node present for the subscription", sub1Node);
- SubscriptionNode sub3Node = getNodeForSubscription(_subList, _sub3);
- assertNotNull("Should have been a node present for the subscription", sub3Node);
-
- //mark the first subscription node
- assertTrue("should have succeeded in updating the marked node",
- _subList.updateMarkedNode(_subList.getMarkedNode(), sub1Node));
-
- //remove the 1st subscription from the list
- assertTrue("Removing subscription node should have succeeded", _subList.remove(_sub1));
- //verify the 1st subscription is no longer the marker node (replaced by a dummy), or in the main list structure
- assertNotSame("Unexpected marker node", sub1Node, _subList.getMarkedNode());
- assertNull("Should not have been a node present in the list structure for the marked-but-removed sub1 node",
- getNodeForSubscription(_subList, _sub1));
-
- //remove the 2nd subscription from the list
- assertTrue("Removing subscription node should have succeeded", _subList.remove(_sub2));
-
- //verify the marker node isn't leaking subsequently removed nodes, by ensuring the very next node
- //in its list structure is now the 3rd subscription (since the 2nd was removed too)
- assertEquals("Unexpected next node", sub3Node, _subList.getMarkedNode().nextNode());
-
- //remove the 3rd and final/tail subscription
- assertTrue("Removing subscription node should have succeeded", _subList.remove(_sub3));
-
- //verify the marker node isn't leaking subsequently removed nodes, by ensuring the very next node
- //in its list structure is now the dummy tail (since the 3rd subscription was removed, and a dummy
- //tail was inserted) and NOT the 3rd sub node.
- assertNotSame("Unexpected next node", sub3Node, _subList.getMarkedNode().nextNode());
- assertTrue("Unexpected next node", _subList.getMarkedNode().nextNode().isDeleted());
- assertNull("Next non-deleted node from the marker should now be the list end, i.e. null", _subList.getMarkedNode().findNext());
- }
-
- /**
- * Test that the marked node 'findNext' behaviour is as expected after a subscription is added
- * to the list following the tail subscription node being removed while it is the marked node.
- * That is, that the new subscriptions node is returned by getMarkedNode().findNext().
- */
- public void testMarkedNodeFindsNewSubscriptionAfterRemovingTailWhilstMarked()
- {
- //get the node out the list for the 3rd subscription
- SubscriptionNode sub3Node = getNodeForSubscription(_subList, _sub3);
- assertNotNull("Should have been a node present for the subscription", sub3Node);
-
- //mark the 3rd subscription node
- assertTrue("should have succeeded in updating the marked node",
- _subList.updateMarkedNode(_subList.getMarkedNode(), sub3Node));
-
- //verify calling findNext on the marked node returns null, i.e. the end of the list has been reached
- assertEquals("Unexpected node after marked node", null, _subList.getMarkedNode().findNext());
-
- //remove the 3rd(marked) subscription from the list
- assertTrue("Removing subscription node should have succeeded", _subList.remove(_sub3));
-
- //add a new 4th subscription to the list
- Subscription sub4 = new MockSubscription();
- _subList.add(sub4);
-
- //get the node out the list for the 4th subscription
- SubscriptionNode sub4Node = getNodeForSubscription(_subList, sub4);
- assertNotNull("Should have been a node present for the subscription", sub4Node);
-
- //verify the marked node (which is now a dummy substitute for the 3rd subscription) returns
- //the 4th subscriptions node as the next non-deleted node.
- assertEquals("Unexpected next node", sub4Node, _subList.getMarkedNode().findNext());
- }
-
- /**
- * Test that setting the marked node to null doesn't cause problems during remove operations
- */
- public void testRemoveWithNullMarkedNode()
- {
- //set the marker to null
- assertTrue("should have succeeded in updating the marked node",
- _subList.updateMarkedNode(_subList.getMarkedNode(), null));
-
- //remove the 1st subscription from the main list
- assertTrue("Removing subscription node should have succeeded", _subList.remove(_sub1));
-
- //verify the 1st subscription is no longer in the main list structure
- assertNull("Should not have been a node present in the main list structure for sub1",
- getNodeForSubscription(_subList, _sub1));
- assertEquals("Unexpected number of nodes", 2, countNodes(_subList));
- }
-
- /**
- * Tests that after the first (non-head) node of the list is marked deleted but has not
- * yet been removed, the iterator still skips it.
- */
- public void testIteratorSkipsFirstDeletedNode()
- {
- //'delete' but dont remove the node for the 1st subscription
- assertTrue("Deleting subscription node should have succeeded",
- getNodeForSubscription(_subList, _sub1).delete());
- assertNotNull("Should still have been a node present for the deleted subscription",
- getNodeForSubscription(_subList, _sub1));
-
- SubscriptionNodeIterator iter = _subList.iterator();
-
- //verify the iterator returns the 2nd subscriptions node
- assertTrue("Iterator should have been able to advance", iter.advance());
- assertEquals("Iterator returned unexpected SubscriptionNode", _sub2, iter.getNode().getSubscription());
-
- //verify the iterator returns the 3rd subscriptions node and not the 2nd.
- assertTrue("Iterator should have been able to advance", iter.advance());
- assertEquals("Iterator returned unexpected SubscriptionNode", _sub3, iter.getNode().getSubscription());
- }
-
- /**
- * Tests that after a central node of the list is marked deleted but has not yet been removed,
- * the iterator still skips it.
- */
- public void testIteratorSkipsCentralDeletedNode()
- {
- //'delete' but dont remove the node for the 2nd subscription
- assertTrue("Deleting subscription node should have succeeded",
- getNodeForSubscription(_subList, _sub2).delete());
- assertNotNull("Should still have been a node present for the deleted subscription",
- getNodeForSubscription(_subList, _sub2));
-
- SubscriptionNodeIterator iter = _subList.iterator();
-
- //verify the iterator returns the 1st subscriptions node
- assertTrue("Iterator should have been able to advance", iter.advance());
- assertEquals("Iterator returned unexpected SubscriptionNode", _sub1, iter.getNode().getSubscription());
-
- //verify the iterator returns the 3rd subscriptions node and not the 2nd.
- assertTrue("Iterator should have been able to advance", iter.advance());
- assertEquals("Iterator returned unexpected SubscriptionNode", _sub3, iter.getNode().getSubscription());
- }
-
- /**
- * Tests that after the last node of the list is marked deleted but has not yet been removed,
- * the iterator still skips it.
- */
- public void testIteratorSkipsDeletedFinalNode()
- {
- //'delete' but dont remove the node for the 3rd subscription
- assertTrue("Deleting subscription node should have succeeded",
- getNodeForSubscription(_subList, _sub3).delete());
- assertNotNull("Should still have been a node present for the deleted 3rd subscription",
- getNodeForSubscription(_subList, _sub3));
-
- SubscriptionNodeIterator iter = _subList.iterator();
-
- //verify the iterator returns the 1st subscriptions node
- assertTrue("Iterator should have been able to advance", iter.advance());
- assertEquals("Iterator returned unexpected SubscriptionNode", _sub1, iter.getNode().getSubscription());
-
- //verify the iterator returns the 2nd subscriptions node
- assertTrue("Iterator should have been able to advance", iter.advance());
- assertEquals("Iterator returned unexpected SubscriptionNode", _sub2, iter.getNode().getSubscription());
-
- //verify the iterator can no longer advance and does not return a subscription node
- assertFalse("Iterator should not have been able to advance", iter.advance());
- assertEquals("Iterator returned unexpected SubscriptionNode", null, iter.getNode());
- }
-}
diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/txn/MockAction.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/txn/MockAction.java
index 15c135ea2c..975e3e91b9 100644
--- a/qpid/java/broker/src/test/java/org/apache/qpid/server/txn/MockAction.java
+++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/txn/MockAction.java
@@ -32,11 +32,13 @@ class MockAction implements Action
private boolean _rollbackFired = false;
private boolean _postCommitFired = false;
+ @Override
public void postCommit()
{
_postCommitFired = true;
}
+ @Override
public void onRollback()
{
_rollbackFired = true;
diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/txn/MockServerMessage.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/txn/MockServerMessage.java
index 422105e410..64c62fd029 100644
--- a/qpid/java/broker/src/test/java/org/apache/qpid/server/txn/MockServerMessage.java
+++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/txn/MockServerMessage.java
@@ -46,56 +46,67 @@ class MockServerMessage implements ServerMessage
this.persistent = persistent;
}
+ @Override
public boolean isPersistent()
{
return persistent;
}
+ @Override
public MessageReference newReference()
{
throw new NotImplementedException();
}
+ @Override
public boolean isImmediate()
{
throw new NotImplementedException();
}
+ @Override
public long getSize()
{
throw new NotImplementedException();
}
+ @Override
public SessionConfig getSessionConfig()
{
throw new NotImplementedException();
}
+ @Override
public String getRoutingKey()
{
throw new NotImplementedException();
}
+ @Override
public AMQMessageHeader getMessageHeader()
{
throw new NotImplementedException();
}
+ @Override
public long getExpiration()
{
throw new NotImplementedException();
}
+ @Override
public int getContent(ByteBuffer buf, int offset)
{
throw new NotImplementedException();
}
+ @Override
public long getArrivalTime()
{
throw new NotImplementedException();
}
+ @Override
public Long getMessageNumber()
{
return 0L;
diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/txn/MockStoreTransaction.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/txn/MockStoreTransaction.java
index ff372532ac..5700bba9f8 100644
--- a/qpid/java/broker/src/test/java/org/apache/qpid/server/txn/MockStoreTransaction.java
+++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/txn/MockStoreTransaction.java
@@ -61,6 +61,7 @@ class MockStoreTransaction implements Transaction
return _state;
}
+ @Override
public void enqueueMessage(TransactionLogResource queue, Long messageId) throws AMQStoreException
{
if (_throwExceptionOnQueueOp)
@@ -82,6 +83,8 @@ class MockStoreTransaction implements Transaction
return _numberOfEnqueuedMessages;
}
+
+ @Override
public void dequeueMessage(TransactionLogResource queue, Long messageId) throws AMQStoreException
{
if (_throwExceptionOnQueueOp)
@@ -92,16 +95,19 @@ class MockStoreTransaction implements Transaction
_numberOfDequeuedMessages++;
}
+ @Override
public void commitTran() throws AMQStoreException
{
_state = TransactionState.COMMITTED;
}
+ @Override
public StoreFuture commitTranAsync() throws AMQStoreException
{
throw new NotImplementedException();
}
+ @Override
public void abortTran() throws AMQStoreException
{
_state = TransactionState.ABORTED;
@@ -111,11 +117,14 @@ class MockStoreTransaction implements Transaction
{
return new TransactionLog()
{
+
+ @Override
public void configureTransactionLog(String name, TransactionLogRecoveryHandler recoveryHandler,
Configuration storeConfiguration, LogSubject logSubject) throws Exception
{
}
-
+
+ @Override
public Transaction newTransaction()
{
storeTransaction.setState(TransactionState.STARTED);
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 ff94942457..925b161118 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
@@ -243,7 +243,7 @@ public class InternalBrokerBaseCase extends QpidTestCase
//Make Message Persistent
properties.setDeliveryMode((byte) 2);
- _headerBody.setProperties(properties);
+ _headerBody.properties = properties;
channel.publishContentHeader(_headerBody);
}
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 8fa820ad95..af8997cf40 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,70 +20,27 @@
*/
package org.apache.qpid.server.util;
-import java.util.Properties;
-
import org.apache.commons.configuration.ConfigurationException;
import org.apache.qpid.server.configuration.ServerConfiguration;
-import org.apache.qpid.server.logging.NullRootMessageLogger;
-import org.apache.qpid.server.logging.actors.BrokerActor;
-import org.apache.qpid.server.logging.actors.CurrentActor;
-import org.apache.qpid.server.configuration.plugins.ConfigurationPlugin;
import org.apache.qpid.server.registry.ApplicationRegistry;
-import org.apache.qpid.server.security.auth.database.PropertiesPrincipalDatabase;
-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.PropertiesPrincipalDatabaseManager;
+
+import java.util.Properties;
+
public class TestApplicationRegistry extends ApplicationRegistry
{
-
public TestApplicationRegistry(ServerConfiguration config) throws ConfigurationException
{
super(config);
}
- @Override
- public void initialise() throws Exception
- {
- CurrentActor.setDefault(new BrokerActor(new NullRootMessageLogger()));
- super.initialise();
- }
-
- /**
- * @see org.apache.qpid.server.registry.ApplicationRegistry#createAuthenticationManager()
- */
- @Override
- protected AuthenticationManager createAuthenticationManager() throws ConfigurationException
+ protected void createDatabaseManager(ServerConfiguration configuration) throws Exception
{
- final Properties users = new Properties();
+ Properties users = new Properties();
users.put("guest","guest");
users.put("admin","admin");
-
- final PropertiesPrincipalDatabase ppd = new PropertiesPrincipalDatabase(users);
-
- AuthenticationManager pdam = new PrincipalDatabaseAuthenticationManager()
- {
-
- /**
- * @see org.apache.qpid.server.security.auth.manager.PrincipalDatabaseAuthenticationManager#configure(org.apache.qpid.server.configuration.plugins.ConfigurationPlugin)
- */
- @Override
- public void configure(ConfigurationPlugin config) throws ConfigurationException
- {
- // We don't pass configuration to this test instance.
- }
-
- @Override
- public void initialise()
- {
- setPrincipalDatabase(ppd);
-
- super.initialise();
- }
- };
-
- pdam.initialise();
-
- return pdam;
+ _databaseManager = new PropertiesPrincipalDatabaseManager("testPasswordFile", users);
}
}
diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/virtualhost/HouseKeepingTaskTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/virtualhost/HouseKeepingTaskTest.java
deleted file mode 100644
index 98bf381712..0000000000
--- a/qpid/java/broker/src/test/java/org/apache/qpid/server/virtualhost/HouseKeepingTaskTest.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.virtualhost;
-
-import java.util.concurrent.CountDownLatch;
-
-import org.apache.qpid.server.logging.LogActor;
-import org.apache.qpid.server.logging.NullRootMessageLogger;
-import org.apache.qpid.server.logging.actors.CurrentActor;
-import org.apache.qpid.server.logging.actors.TestLogActor;
-import org.apache.qpid.test.utils.QpidTestCase;
-
-public class HouseKeepingTaskTest extends QpidTestCase
-{
- /**
- * Tests that the abstract HouseKeepingTask properly cleans up any LogActor
- * it adds to the CurrentActor stack by verifying the CurrentActor set
- * before task execution is the CurrentActor after execution.
- */
- public void testCurrentActorStackBalance() throws Exception
- {
- //create and set a test actor
- LogActor testActor = new TestLogActor(new NullRootMessageLogger());
- CurrentActor.set(testActor);
-
- //verify it is returned correctly before executing a HouseKeepingTask
- assertEquals("Expected LogActor was not returned", testActor, CurrentActor.get());
-
- final CountDownLatch latch = new CountDownLatch(1);
- HouseKeepingTask testTask = new HouseKeepingTask(new MockVirtualHost("HouseKeepingTaskTestVhost"))
- {
- @Override
- public void execute()
- {
- latch.countDown();
- }
- };
-
- //run the test HouseKeepingTask using the current Thread to influence its CurrentActor stack
- testTask.run();
-
- assertEquals("The expected LogActor was not returned, the CurrentActor stack has become unbalanced",
- testActor, CurrentActor.get());
- assertEquals("HouseKeepingTask execute() method was not run", 0, latch.getCount());
-
- //clean up the test actor
- CurrentActor.remove();
- }
-}
diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/virtualhost/MockVirtualHost.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/virtualhost/MockVirtualHost.java
deleted file mode 100644
index 7aa314bf22..0000000000
--- a/qpid/java/broker/src/test/java/org/apache/qpid/server/virtualhost/MockVirtualHost.java
+++ /dev/null
@@ -1,271 +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.virtualhost;
-
-import java.util.UUID;
-
-import org.apache.qpid.server.binding.BindingFactory;
-import org.apache.qpid.server.configuration.BrokerConfig;
-import org.apache.qpid.server.configuration.ConfigStore;
-import org.apache.qpid.server.configuration.ConfiguredObject;
-import org.apache.qpid.server.configuration.VirtualHostConfig;
-import org.apache.qpid.server.configuration.VirtualHostConfigType;
-import org.apache.qpid.server.configuration.VirtualHostConfiguration;
-import org.apache.qpid.server.connection.IConnectionRegistry;
-import org.apache.qpid.server.exchange.ExchangeFactory;
-import org.apache.qpid.server.exchange.ExchangeRegistry;
-import org.apache.qpid.server.federation.BrokerLink;
-import org.apache.qpid.server.management.ManagedObject;
-import org.apache.qpid.server.queue.QueueRegistry;
-import org.apache.qpid.server.registry.IApplicationRegistry;
-import org.apache.qpid.server.security.SecurityManager;
-import org.apache.qpid.server.security.auth.manager.AuthenticationManager;
-import org.apache.qpid.server.stats.StatisticsCounter;
-import org.apache.qpid.server.store.DurableConfigurationStore;
-import org.apache.qpid.server.store.MessageStore;
-import org.apache.qpid.server.store.TransactionLog;
-
-public class MockVirtualHost implements VirtualHost
-{
- private String _name;
-
- public MockVirtualHost(String name)
- {
- _name = name;
- }
-
- public void close()
- {
-
- }
-
- public void createBrokerConnection(String transport, String host, int port,
- String vhost, boolean durable, String authMechanism,
- String username, String password)
- {
-
- }
-
- public IApplicationRegistry getApplicationRegistry()
- {
- return null;
- }
-
- public AuthenticationManager getAuthenticationManager()
- {
- return null;
- }
-
- public BindingFactory getBindingFactory()
- {
- return null;
- }
-
- public UUID getBrokerId()
- {
- return null;
- }
-
- public ConfigStore getConfigStore()
- {
- return null;
- }
-
- public VirtualHostConfiguration getConfiguration()
- {
- return null;
- }
-
- public IConnectionRegistry getConnectionRegistry()
- {
- return null;
- }
-
- public DurableConfigurationStore getDurableConfigurationStore()
- {
- return null;
- }
-
- public ExchangeFactory getExchangeFactory()
- {
- return null;
- }
-
- public ExchangeRegistry getExchangeRegistry()
- {
- return null;
- }
-
- public int getHouseKeepingActiveCount()
- {
- return 0;
- }
-
- public long getHouseKeepingCompletedTaskCount()
- {
- return 0;
- }
-
- public int getHouseKeepingPoolSize()
- {
- return 0;
- }
-
- public long getHouseKeepingTaskCount()
- {
- return 0;
- }
-
- public ManagedObject getManagedObject()
- {
- return null;
- }
-
- public MessageStore getMessageStore()
- {
- return null;
- }
-
- public String getName()
- {
- return _name;
- }
-
- public QueueRegistry getQueueRegistry()
- {
- return null;
- }
-
- public SecurityManager getSecurityManager()
- {
- return null;
- }
-
- public TransactionLog getTransactionLog()
- {
- return null;
- }
-
- public void removeBrokerConnection(BrokerLink brokerLink)
- {
-
- }
-
- public void scheduleHouseKeepingTask(long period, HouseKeepingTask task)
- {
-
- }
-
- public void setHouseKeepingPoolSize(int newSize)
- {
-
- }
-
- public BrokerConfig getBroker()
- {
- return null;
- }
-
- public String getFederationTag()
- {
- return null;
- }
-
- public void setBroker(BrokerConfig brokerConfig)
- {
-
- }
-
- public VirtualHostConfigType getConfigType()
- {
- return null;
- }
-
- public long getCreateTime()
- {
- return 0;
- }
-
- public UUID getId()
- {
- return null;
- }
-
- public ConfiguredObject<VirtualHostConfigType, VirtualHostConfig> getParent()
- {
- return null;
- }
-
- public boolean isDurable()
- {
- return false;
- }
-
- public StatisticsCounter getDataDeliveryStatistics()
- {
- return null;
- }
-
- public StatisticsCounter getDataReceiptStatistics()
- {
- return null;
- }
-
- public StatisticsCounter getMessageDeliveryStatistics()
- {
- return null;
- }
-
- public StatisticsCounter getMessageReceiptStatistics()
- {
- return null;
- }
-
- public void initialiseStatistics()
- {
-
- }
-
- public boolean isStatisticsEnabled()
- {
- return false;
- }
-
- public void registerMessageDelivered(long messageSize)
- {
-
- }
-
- public void registerMessageReceived(long messageSize, long timestamp)
- {
-
- }
-
- public void resetStatistics()
- {
-
- }
-
- public void setStatisticsEnabled(boolean enabled)
- {
-
- }
-} \ No newline at end of file
diff --git a/qpid/java/broker/src/velocity/java/org/apache/qpid/server/logging/GenerateLogMessages.java b/qpid/java/broker/src/velocity/java/org/apache/qpid/server/logging/GenerateLogMessages.java
index a39799a6b6..902b86f80b 100644
--- a/qpid/java/broker/src/velocity/java/org/apache/qpid/server/logging/GenerateLogMessages.java
+++ b/qpid/java/broker/src/velocity/java/org/apache/qpid/server/logging/GenerateLogMessages.java
@@ -481,7 +481,7 @@ public class GenerateLogMessages
// Only check the text inside the braces '{}'
int typeIndexEnd = parametersString[index].indexOf("}", typeIndex);
String typeString = parametersString[index].substring(typeIndex, typeIndexEnd);
- if (typeString.contains("number") || typeString.contains("choice"))
+ if (typeString.contains("number"))
{
type = "Number";
}
diff --git a/qpid/java/build.deps b/qpid/java/build.deps
index cfbd122527..aebd381bbc 100644
--- a/qpid/java/build.deps
+++ b/qpid/java/build.deps
@@ -17,6 +17,8 @@
# under the License.
#
+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
@@ -25,43 +27,88 @@ 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
derby-db=lib/derby-10.6.1.0.jar
geronimo-jms=lib/geronimo-jms_1.1_spec-1.0.jar
junit=lib/junit-3.8.1.jar
+junit4=lib/junit-4.4.jar
+
+jline=lib/jline-0.9.94.jar
log4j=lib/log4j-1.2.12.jar
-mina-core=lib/mina-core-1.1.7.jar
-mina-filter-ssl=lib/mina-filter-ssl-1.1.7.jar
+mina-core=lib/mina-core-1.0.1.jar
+mina-filter-ssl=lib/mina-filter-ssl-1.0.1.jar
slf4j-api=lib/slf4j-api-1.6.1.jar
slf4j-log4j=lib/slf4j-log4j12-1.6.1.jar
xalan=lib/xalan-2.7.0.jar
+muse-core=lib/muse-core-2.2.0.jar
+muse-platform-mini=lib/muse-platform-mini-2.2.0.jar
+muse-util=lib/muse-util-2.2.0.jar
+muse-util-qname=lib/muse-util-qname-2.2.0.jar
+muse-util-xml=lib/muse-util-xml-2.2.0.jar
+muse-wsa-soap=lib/muse-wsa-soap-2.2.0.jar
+muse-wsdm-muws-adv-api=lib/muse-wsdm-muws-adv-api-2.2.0.jar
+muse-wsdm-muws-adv-impl=lib/muse-wsdm-muws-adv-impl-2.2.0.jar
+muse-wsdm-muws-api=lib/muse-wsdm-muws-api-2.2.0.jar
+muse-wsdm-muws-impl=lib/muse-wsdm-muws-impl-2.2.0.jar
+muse-wsdm-wef-api=lib/muse-wsdm-wef-api-2.2.0.jar
+muse-wsdm-wef-impl=lib/muse-wsdm-wef-impl-2.2.0.jar
+muse-wsn-api=lib/muse-wsn-api-2.2.0.jar
+muse-wsn-impl=lib/muse-wsn-impl-2.2.0.jar
+muse-wsrf-api=lib/muse-wsrf-api-2.2.0.jar
+muse-wsrf-impl=lib/muse-wsrf-impl-2.2.0.jar
+muse-wsrf-rmd=lib/muse-wsrf-rmd-2.2.0.jar
+muse-wsx-api=lib/muse-wsx-api-2.2.0.jar
+muse-wsx-impl=lib/muse-wsx-impl-2.2.0.jar
+wsdl4j=lib/wsdl4j-1.6.1.jar
+xercesImpl=lib/xercesImpl-2.8.1.jar
+xml-apis=lib/xml-apis-1.3.03.jar
+javassist=lib/javassist.jar
jetty=lib/jetty-6.1.14.jar
jetty-util=lib/jetty-util-6.1.14.jar
jetty-servlet-tester=lib/jetty-servlet-tester-6.1.14.jar
+jetty-bootstrap=lib/start.jar
+jsp-api=lib/jsp-api-2.1.jar
+jsp-impl=lib/jsp-2.1.jar
+core-lib=lib/core-3.1.1.jar
servlet-api=lib/servlet-api.jar
+muse.libs = ${muse-core} ${muse-platform-mini} ${muse-util} ${muse-util-qname} \
+${muse-util-xml} ${muse-wsa-soap} ${muse-wsdm-muws-adv-api} ${muse-wsdm-muws-adv-impl} \
+${muse-wsdm-muws-api} ${muse-wsdm-muws-impl} ${muse-wsdm-wef-api} ${muse-wsdm-wef-impl} \
+${muse-wsn-api} ${muse-wsn-impl} ${muse-wsrf-api} ${muse-wsrf-impl} ${muse-wsrf-rmd} \
+${muse-wsx-api} ${muse-wsx-impl} ${wsdl4j} ${xercesImpl} ${xml-apis} ${jetty} ${jetty-util} ${jetty-bootstrap}
+
+jsp.libs = ${jsp-api} ${jsp-impl} ${core-lib}
+
osgi-core=lib/org.osgi.core-1.0.0.jar
felix-framework=lib/org.apache.felix.framework-2.0.5.jar
+geronimo-servlet=lib/geronimo-servlet_2.5_spec-1.2.jar
felix.libs=${osgi-core} ${felix-framework}
commons-configuration.libs = ${commons-beanutils-core} ${commons-digester} \
${commons-codec} ${commons-lang} ${commons-collections} ${commons-configuration}
-common.libs=${slf4j-api} ${mina-core} ${mina-filter-ssl}
+common.libs=${slf4j-api} ${backport-util-concurrent} ${mina-core} ${mina-filter-ssl}
client.libs=${geronimo-jms}
tools.libs=${commons-configuration.libs} ${log4j}
broker.libs=${commons-cli} ${commons-logging} ${log4j} ${slf4j-log4j} \
${xalan} ${felix.libs} ${derby-db} ${commons-configuration.libs}
-broker-plugins.libs=${felix.libs} ${log4j} ${commons-configuration.libs}
+broker-plugins.libs=${felix.libs} ${log4j} ${commons-configuration.libs}
+management-client.libs=${jsp.libs} ${log4j} ${slf4j-log4j} ${slf4j-api} \
+ ${commons-pool} ${geronimo-servlet} ${muse.libs} ${javassist} ${xalan}
+
+management-agent.libs=${commons-logging}
+management-console.libs=${commons-logging}
junit-toolkit.libs=${log4j} ${junit} ${slf4j-api}
test.libs=${slf4j-log4j} ${junit-toolkit.libs}
@@ -128,6 +175,9 @@ management-eclipse-plugin.platform-libs=${ecl-equinox-launcher-win32-win32-x86}
management-eclipse-plugin.libs=${management-eclipse-plugin.core-libs} ${management-eclipse-plugin.platform-libs}
+
+management-tools-qpid-cli.libs=${jline} ${commons-configuration.libs}
+
common.test.libs=${test.libs}
broker.test.libs=${test.libs}
client.test.libs=${test.libs}
@@ -139,5 +189,9 @@ systests.libs=${test.libs}
broker-plugins.test.libs=${test.libs}
broker-plugins-experimental-info.test.libs=${test.libs} ${servlet-api} ${jetty} ${jetty-util} ${jetty-servlet-tester}
+management-client.test.libs=${muse.libs} ${test.libs} ${log4j} ${javassist} ${geronimo-servlet} ${commons-pool}
+management-console.test.libs=${junit4} ${slf4j-log4j} ${log4j}
+management-agent.test.libs=${junit}
management-eclipse-plugin.test.libs=${systests.libs}
+management-tools-qpid-cli.test.libs=${junit4} ${slf4j-log4j} ${log4j}
management-common.test.libs=${test.libs}
diff --git a/qpid/java/build.xml b/qpid/java/build.xml
index b8441af3a5..9031166d76 100644
--- a/qpid/java/build.xml
+++ b/qpid/java/build.xml
@@ -22,17 +22,18 @@
<import file="common.xml"/>
+
<findSubProjects name="broker-plugins" dir="broker-plugins"/>
- <findSubProjects name="client-plugins" dir="client-plugins" erroronmissingdir="false"/>
- <findSubProjects name="management" dir="management" excludes="common,example"/>
+ <findSubProjects name="management" dir="management" excludes="common,example,tools/qpid-cli"/>
<property name="modules.core" value="junit-toolkit common management/common broker client tools"/>
<property name="modules.examples" value="client/example management/example"/>
<property name="modules.tests" value="systests perftests integrationtests testkit"/>
<property name="modules.management" value="${management}"/>
- <property name="modules.plugin" value="${broker-plugins} ${client-plugins}"/>
+ <property name="modules.plugin" value="${broker-plugins}"/>
+ <property name="modules.management.tools" value="management/tools/qpid-cli"/>
<property name="modules" value="${modules.core} ${modules.examples}
- ${modules.management} ${modules.tests} ${modules.plugin}"/>
+ ${modules.management} ${modules.management.tools} ${modules.tests} ${modules.plugin}"/>
<property name="qpid.jar" location="${build.lib}/qpid-all.jar"/>
<basename property="qpid.jar.name" file="${qpid.jar}"/>
@@ -92,10 +93,6 @@
<fail if="failed" message="TEST SUITE FAILED"/>
</target>
-
- <target name="report-module" description="generate junitreport for modules">
- <iterate target="report-module"/>
- </target>
<target name="jar" description="create module jars">
<iterate target="jar"/>
@@ -216,18 +213,7 @@
<include name="**/*.ser"/>
</fileset>
</cobertura-merge>
- <cobertura-report format="xml"
- destdir="${build.coveragereport}"
- datafile="${build.coveragereport}/cobertura.ser"
- >
- <fileset dir="${project.root}/common/src/main/java" includes="**/*.java" />
- <fileset dir="${project.root}/build/scratch/common/src" includes="**/*.java" />
- <fileset dir="${project.root}/broker/src/main/java" includes="**/*.java" />
- <fileset dir="${project.root}/build/scratch/broker/src" includes="**/*.java" />
- <fileset dir="${project.root}/client/src/main/java" includes="**/*.java" />
- <fileset dir="${project.root}/build/scratch/client/src" includes="**/*.java" />
- </cobertura-report>
- <cobertura-report format="html"
+ <cobertura-report format="html"
destdir="${build.coveragereport}"
datafile="${build.coveragereport}/cobertura.ser"
>
@@ -291,7 +277,4 @@
</findbugs>
</target>
- <target name="eclipse" description="build eclipse project and classpath files">
- <iterate target="eclipse"/>
- </target>
</project>
diff --git a/qpid/java/client/README.txt b/qpid/java/client/README.txt
index b9cde71db3..57a98cc978 100644
--- a/qpid/java/client/README.txt
+++ b/qpid/java/client/README.txt
@@ -24,7 +24,7 @@ run more easily.
E.g, in order to run the Hello example, you would add the client+example library
files to the java classpath and launch the example like follows:
-java -cp "lib/qpid-all.jar:example/lib/qpid-client-example-<version>.jar" \
+java -cp "lib/qpid-all.jar:example/lib/qpid-client-examples-<version>.jar" \
org.apache.qpid.example.Hello
NOTE: The client uses the SL4FJ API for its logging. You must supply a logging
diff --git a/qpid/java/client/example/src/main/java/org/apache/qpid/example/pubsub/ConnectionSetup.java b/qpid/java/client/example/src/main/java/org/apache/qpid/example/pubsub/ConnectionSetup.java
index 0734704e59..c4edd9034f 100644
--- a/qpid/java/client/example/src/main/java/org/apache/qpid/example/pubsub/ConnectionSetup.java
+++ b/qpid/java/client/example/src/main/java/org/apache/qpid/example/pubsub/ConnectionSetup.java
@@ -33,6 +33,7 @@ import java.util.Properties;
* It is equivalent to a PropertyFile of value:
*
* connectionfactory.local=amqp://guest:guest@clientid/test?brokerlist='localhost'
+ * connectionfactory.vm=amqp://guest:guest@clientid/test?brokerlist='vm://:1'
*
* queue.queue=example.MyQueue
* topic.topic=example.hierarical.topic
@@ -49,7 +50,7 @@ public class ConnectionSetup
final static String QUEUE_NAME = "example.MyQueue";
public static final String TOPIC_JNDI_NAME = "topic";
- final static String TOPIC_NAME = "usa.news";
+ final static String TOPIC_NAME = "example.hierarical.topic";
private Context _ctx;
@@ -60,6 +61,7 @@ public class ConnectionSetup
Properties properties = new Properties();
properties.put(Context.INITIAL_CONTEXT_FACTORY, INITIAL_CONTEXT_FACTORY);
properties.put("connectionfactory." + CONNECTION_JNDI_NAME, CONNECTION_NAME);
+ properties.put("connectionfactory." + "vm", "amqp://guest:guest@clientid/test?brokerlist='vm://:1'");
properties.put("queue." + QUEUE_JNDI_NAME, QUEUE_NAME);
properties.put("topic." + TOPIC_JNDI_NAME, TOPIC_NAME);
diff --git a/qpid/java/client/example/src/main/java/org/apache/qpid/example/pubsub/Publisher.java b/qpid/java/client/example/src/main/java/org/apache/qpid/example/pubsub/Publisher.java
index ac3829d49e..dd936e429f 100644
--- a/qpid/java/client/example/src/main/java/org/apache/qpid/example/pubsub/Publisher.java
+++ b/qpid/java/client/example/src/main/java/org/apache/qpid/example/pubsub/Publisher.java
@@ -71,7 +71,7 @@ public class Publisher extends Client
public static void main(String[] args)
{
- String destination = args.length > 2 ? args[1] : "usa.news";
+ String destination = args.length > 2 ? args[1] : null;
int msgCount = args.length > 2 ? Integer.parseInt(args[2]) : 100;
diff --git a/qpid/java/client/example/src/main/java/org/apache/qpid/example/transport/ExistingSocketConnectorDemo.java b/qpid/java/client/example/src/main/java/org/apache/qpid/example/transport/ExistingSocketConnectorDemo.java
new file mode 100644
index 0000000000..d7eb138523
--- /dev/null
+++ b/qpid/java/client/example/src/main/java/org/apache/qpid/example/transport/ExistingSocketConnectorDemo.java
@@ -0,0 +1,171 @@
+/*
+ *
+ * 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.example.transport;
+
+import org.apache.qpid.AMQException;
+import org.apache.qpid.client.AMQConnection;
+import org.apache.qpid.client.transport.TransportConnection;
+import org.apache.qpid.jms.ConnectionListener;
+import org.apache.qpid.url.URLSyntaxException;
+
+import javax.jms.Connection;
+import javax.jms.JMSException;
+import javax.jms.Message;
+import javax.jms.MessageConsumer;
+import javax.jms.MessageProducer;
+import javax.jms.Session;
+import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.net.Socket;
+import java.nio.channels.SocketChannel;
+import java.util.UUID;
+
+/**
+ * This is a simple application that demonstrates how you can use the Qpid AMQP interfaces to use existing sockets as
+ * the transport for the Client API.
+ *
+ * The Demo here runs twice:
+ * 1. Just to show a simple publish and receive.
+ * 2. To demonstrate how to use existing sockets and utilise the underlying client failover mechnaism.
+ */
+public class ExistingSocketConnectorDemo implements ConnectionListener
+{
+ private static boolean DEMO_FAILOVER = false;
+
+ public static void main(String[] args) throws IOException, URLSyntaxException, AMQException, JMSException
+ {
+ System.out.println("Testing socket connection to localhost:5672.");
+
+ new ExistingSocketConnectorDemo();
+
+ System.out.println("Testing socket connection failover between localhost:5672 and localhost:5673.");
+
+ DEMO_FAILOVER = true;
+
+ new ExistingSocketConnectorDemo();
+ }
+
+ Connection _connection;
+ MessageProducer _producer;
+ Session _session;
+
+ String Socket1_ID = UUID.randomUUID().toString();
+ String Socket2_ID = UUID.randomUUID().toString();
+
+
+
+ /** Here we can see the broker we are connecting to is set to be 'socket:///' signifying we will provide the socket. */
+ public final String CONNECTION = "amqp://guest:guest@id/test?brokerlist='socket://" + Socket1_ID + ";socket://" + Socket2_ID + "'";
+
+
+ public ExistingSocketConnectorDemo() throws IOException, URLSyntaxException, AMQException, JMSException
+ {
+
+ Socket socket = SocketChannel.open().socket();
+ socket.connect(new InetSocketAddress("localhost", 5672));
+
+ TransportConnection.registerOpenSocket(Socket1_ID, socket);
+
+
+ _connection = new AMQConnection(CONNECTION);
+
+ _session = _connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
+
+ MessageConsumer consumer = _session.createConsumer(_session.createQueue("Queue"));
+
+ _producer = _session.createProducer(_session.createQueue("Queue"));
+
+ _connection.start();
+
+ if (!DEMO_FAILOVER)
+ {
+ _producer.send(_session.createTextMessage("Simple Test"));
+ }
+ else
+ {
+ // Using the Qpid interfaces we can set a listener that allows us to demonstrate failover
+ ((AMQConnection) _connection).setConnectionListener(this);
+
+ System.out.println("Testing failover: Please ensure second broker running on localhost:5673 and shutdown broker on 5672.");
+ }
+
+ //We do a blocking receive here so that we can demonstrate failover.
+ Message message = consumer.receive();
+
+ System.out.println("Recevied :" + message);
+
+ _connection.close();
+ }
+
+ // ConnectionListener Interface
+
+ public void bytesSent(long count)
+ {
+ //not used in this example
+ }
+ public void bytesReceived(long count)
+ {
+ //not used in this example
+ }
+
+ public boolean preFailover(boolean redirect)
+ {
+ /**
+ * This method is called before the underlying client library starts to reconnect. This gives us the opportunity
+ * to set a new socket for the failover to occur on.
+ */
+ try
+ {
+ Socket socket = SocketChannel.open().socket();
+
+ socket.connect(new InetSocketAddress("localhost", 5673));
+
+ // This is the new method to pass in an open socket for the connection to use.
+ TransportConnection.registerOpenSocket(Socket2_ID, socket);
+ }
+ catch (IOException e)
+ {
+ e.printStackTrace();
+ return false;
+ }
+ return true;
+ }
+
+ public boolean preResubscribe()
+ {
+ //not used in this example - but must return true to allow the resubscription of existing clients.
+ return true;
+ }
+
+ public void failoverComplete()
+ {
+ // Now that failover has completed we can send a message that the receiving thread will pick up
+ try
+ {
+ _producer.send(_session.createTextMessage("Simple Failover Test"));
+ }
+ catch (JMSException e)
+ {
+ e.printStackTrace();
+ }
+ }
+}
diff --git a/qpid/java/client/src/main/java/client.bnd b/qpid/java/client/src/main/java/client.bnd
index 98696dc7d8..0ddd163d4f 100755
--- a/qpid/java/client/src/main/java/client.bnd
+++ b/qpid/java/client/src/main/java/client.bnd
@@ -17,7 +17,7 @@
# under the License.
#
-ver: 0.13.0
+ver: 0.9.0
Bundle-SymbolicName: qpid-client
Bundle-Version: ${ver}
diff --git a/qpid/java/client/src/main/java/org/apache/mina/transport/socket/nio/ExistingSocketConnector.java b/qpid/java/client/src/main/java/org/apache/mina/transport/socket/nio/ExistingSocketConnector.java
new file mode 100644
index 0000000000..98716c0c3c
--- /dev/null
+++ b/qpid/java/client/src/main/java/org/apache/mina/transport/socket/nio/ExistingSocketConnector.java
@@ -0,0 +1,478 @@
+/*
+ * 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.mina.transport.socket.nio;
+
+import edu.emory.mathcs.backport.java.util.concurrent.Executor;
+import org.apache.mina.common.ConnectFuture;
+import org.apache.mina.common.ExceptionMonitor;
+import org.apache.mina.common.IoConnector;
+import org.apache.mina.common.IoConnectorConfig;
+import org.apache.mina.common.IoHandler;
+import org.apache.mina.common.IoServiceConfig;
+import org.apache.mina.common.support.BaseIoConnector;
+import org.apache.mina.common.support.DefaultConnectFuture;
+import org.apache.mina.util.NamePreservingRunnable;
+import org.apache.mina.util.NewThreadExecutor;
+import org.apache.mina.util.Queue;
+
+import java.io.IOException;
+import java.net.ConnectException;
+import java.net.Socket;
+import java.net.SocketAddress;
+import java.nio.channels.SelectionKey;
+import java.nio.channels.Selector;
+import java.nio.channels.SocketChannel;
+import java.util.Iterator;
+import java.util.Set;
+
+/**
+ * {@link IoConnector} for socket transport (TCP/IP).
+ *
+ * @author The Apache Directory Project (mina-dev@directory.apache.org)
+ * @version $Rev: 627427 $, $Date: 2008-02-13 14:39:10 +0000 (Wed, 13 Feb 2008) $
+ */
+public class ExistingSocketConnector extends BaseIoConnector
+{
+ /** @noinspection StaticNonFinalField */
+ private static volatile int nextId = 0;
+
+ private final Object lock = new Object();
+ private final int id = nextId++;
+ private final String threadName = "SocketConnector-" + id;
+ private SocketConnectorConfig defaultConfig = new SocketConnectorConfig();
+ private final Queue connectQueue = new Queue();
+ private final SocketIoProcessor[] ioProcessors;
+ private final int processorCount;
+ private final Executor executor;
+
+ /** @noinspection FieldAccessedSynchronizedAndUnsynchronized */
+ private Selector selector;
+ private Worker worker;
+ private int processorDistributor = 0;
+ private int workerTimeout = 60; // 1 min.
+ private Socket _openSocket = null;
+
+ /** Create a connector with a single processing thread using a NewThreadExecutor */
+ public ExistingSocketConnector()
+ {
+ this(1, new NewThreadExecutor());
+ }
+
+ /**
+ * Create a connector with the desired number of processing threads
+ *
+ * @param processorCount Number of processing threads
+ * @param executor Executor to use for launching threads
+ */
+ public ExistingSocketConnector(int processorCount, Executor executor)
+ {
+ if (processorCount < 1)
+ {
+ throw new IllegalArgumentException("Must have at least one processor");
+ }
+
+ this.executor = executor;
+ this.processorCount = processorCount;
+ ioProcessors = new SocketIoProcessor[processorCount];
+
+ for (int i = 0; i < processorCount; i++)
+ {
+ ioProcessors[i] = new SocketIoProcessor("SocketConnectorIoProcessor-" + id + "." + i, executor);
+ }
+ }
+
+ /**
+ * How many seconds to keep the connection thread alive between connection requests
+ *
+ * @return Number of seconds to keep connection thread alive
+ */
+ public int getWorkerTimeout()
+ {
+ return workerTimeout;
+ }
+
+ /**
+ * Set how many seconds the connection worker thread should remain alive once idle before terminating itself.
+ *
+ * @param workerTimeout Number of seconds to keep thread alive. Must be >=0
+ */
+ public void setWorkerTimeout(int workerTimeout)
+ {
+ if (workerTimeout < 0)
+ {
+ throw new IllegalArgumentException("Must be >= 0");
+ }
+ this.workerTimeout = workerTimeout;
+ }
+
+ public ConnectFuture connect(SocketAddress address, IoHandler handler, IoServiceConfig config)
+ {
+ return connect(address, null, handler, config);
+ }
+
+ public ConnectFuture connect(SocketAddress address, SocketAddress localAddress,
+ IoHandler handler, IoServiceConfig config)
+ {
+ /** Changes here from the Mina OpenSocketConnector.
+ * Ignoreing all address as they are not needed */
+
+ if (handler == null)
+ {
+ throw new NullPointerException("handler");
+ }
+
+
+ if (config == null)
+ {
+ config = getDefaultConfig();
+ }
+
+ if (_openSocket == null)
+ {
+ throw new IllegalArgumentException("Specifed Socket not active");
+ }
+
+ boolean success = false;
+
+ try
+ {
+ DefaultConnectFuture future = new DefaultConnectFuture();
+ newSession(_openSocket, handler, config, future);
+ success = true;
+ return future;
+ }
+ catch (IOException e)
+ {
+ return DefaultConnectFuture.newFailedFuture(e);
+ }
+ finally
+ {
+ if (!success && _openSocket != null)
+ {
+ try
+ {
+ _openSocket.close();
+ }
+ catch (IOException e)
+ {
+ ExceptionMonitor.getInstance().exceptionCaught(e);
+ }
+ }
+ }
+ }
+
+ public IoServiceConfig getDefaultConfig()
+ {
+ return defaultConfig;
+ }
+
+ /**
+ * Sets the config this connector will use by default.
+ *
+ * @param defaultConfig the default config.
+ *
+ * @throws NullPointerException if the specified value is <code>null</code>.
+ */
+ public void setDefaultConfig(SocketConnectorConfig defaultConfig)
+ {
+ if (defaultConfig == null)
+ {
+ throw new NullPointerException("defaultConfig");
+ }
+ this.defaultConfig = defaultConfig;
+ }
+
+ private synchronized void startupWorker() throws IOException
+ {
+ if (worker == null)
+ {
+ selector = Selector.open();
+ worker = new Worker();
+ executor.execute(new NamePreservingRunnable(worker));
+ }
+ }
+
+ private void registerNew()
+ {
+ if (connectQueue.isEmpty())
+ {
+ return;
+ }
+
+ for (; ;)
+ {
+ ConnectionRequest req;
+ synchronized (connectQueue)
+ {
+ req = (ConnectionRequest) connectQueue.pop();
+ }
+
+ if (req == null)
+ {
+ break;
+ }
+
+ SocketChannel ch = req.channel;
+ try
+ {
+ ch.register(selector, SelectionKey.OP_CONNECT, req);
+ }
+ catch (IOException e)
+ {
+ req.setException(e);
+ }
+ }
+ }
+
+ private void processSessions(Set keys)
+ {
+ Iterator it = keys.iterator();
+
+ while (it.hasNext())
+ {
+ SelectionKey key = (SelectionKey) it.next();
+
+ if (!key.isConnectable())
+ {
+ continue;
+ }
+
+ SocketChannel ch = (SocketChannel) key.channel();
+ ConnectionRequest entry = (ConnectionRequest) key.attachment();
+
+ boolean success = false;
+ try
+ {
+ ch.finishConnect();
+ newSession(ch, entry.handler, entry.config, entry);
+ success = true;
+ }
+ catch (Throwable e)
+ {
+ entry.setException(e);
+ }
+ finally
+ {
+ key.cancel();
+ if (!success)
+ {
+ try
+ {
+ ch.close();
+ }
+ catch (IOException e)
+ {
+ ExceptionMonitor.getInstance().exceptionCaught(e);
+ }
+ }
+ }
+ }
+
+ keys.clear();
+ }
+
+ private void processTimedOutSessions(Set keys)
+ {
+ long currentTime = System.currentTimeMillis();
+ Iterator it = keys.iterator();
+
+ while (it.hasNext())
+ {
+ SelectionKey key = (SelectionKey) it.next();
+
+ if (!key.isValid())
+ {
+ continue;
+ }
+
+ ConnectionRequest entry = (ConnectionRequest) key.attachment();
+
+ if (currentTime >= entry.deadline)
+ {
+ entry.setException(new ConnectException());
+ try
+ {
+ key.channel().close();
+ }
+ catch (IOException e)
+ {
+ ExceptionMonitor.getInstance().exceptionCaught(e);
+ }
+ finally
+ {
+ key.cancel();
+ }
+ }
+ }
+ }
+
+ private void newSession(Socket socket, IoHandler handler, IoServiceConfig config, ConnectFuture connectFuture)
+ throws IOException
+ {
+ SocketSessionImpl session = new SocketSessionImpl(this,
+ nextProcessor(),
+ getListeners(),
+ config,
+ socket.getChannel(),
+ handler,
+ socket.getRemoteSocketAddress());
+
+ newSession(session, config, connectFuture);
+ }
+
+ private void newSession(SocketChannel ch, IoHandler handler, IoServiceConfig config, ConnectFuture connectFuture)
+ throws IOException
+
+ {
+ SocketSessionImpl session = new SocketSessionImpl(this,
+ nextProcessor(),
+ getListeners(),
+ config,
+ ch,
+ handler,
+ ch.socket().getRemoteSocketAddress());
+
+ newSession(session, config, connectFuture);
+ }
+
+ private void newSession(SocketSessionImpl session, IoServiceConfig config, ConnectFuture connectFuture)
+ throws IOException
+ {
+ try
+ {
+ getFilterChainBuilder().buildFilterChain(session.getFilterChain());
+ config.getFilterChainBuilder().buildFilterChain(session.getFilterChain());
+ config.getThreadModel().buildFilterChain(session.getFilterChain());
+ }
+ catch (Throwable e)
+ {
+ throw (IOException) new IOException("Failed to create a session.").initCause(e);
+ }
+ session.getIoProcessor().addNew(session);
+ connectFuture.setSession(session);
+ }
+
+ private SocketIoProcessor nextProcessor()
+ {
+ return ioProcessors[processorDistributor++ % processorCount];
+ }
+
+ public void setOpenSocket(Socket openSocket)
+ {
+ _openSocket = openSocket;
+ }
+
+ private class Worker implements Runnable
+ {
+ private long lastActive = System.currentTimeMillis();
+
+ public void run()
+ {
+ Thread.currentThread().setName(ExistingSocketConnector.this.threadName);
+
+ for (; ;)
+ {
+ try
+ {
+ int nKeys = selector.select(1000);
+
+ registerNew();
+
+ if (nKeys > 0)
+ {
+ processSessions(selector.selectedKeys());
+ }
+
+ processTimedOutSessions(selector.keys());
+
+ if (selector.keys().isEmpty())
+ {
+ if (System.currentTimeMillis() - lastActive > workerTimeout * 1000L)
+ {
+ synchronized (lock)
+ {
+ if (selector.keys().isEmpty() &&
+ connectQueue.isEmpty())
+ {
+ worker = null;
+ try
+ {
+ selector.close();
+ }
+ catch (IOException e)
+ {
+ ExceptionMonitor.getInstance().exceptionCaught(e);
+ }
+ finally
+ {
+ selector = null;
+ }
+ break;
+ }
+ }
+ }
+ }
+ else
+ {
+ lastActive = System.currentTimeMillis();
+ }
+ }
+ catch (IOException e)
+ {
+ ExceptionMonitor.getInstance().exceptionCaught(e);
+
+ try
+ {
+ Thread.sleep(1000);
+ }
+ catch (InterruptedException e1)
+ {
+ ExceptionMonitor.getInstance().exceptionCaught(e1);
+ }
+ }
+ }
+ }
+ }
+
+ private class ConnectionRequest extends DefaultConnectFuture
+ {
+ private final SocketChannel channel;
+ private final long deadline;
+ private final IoHandler handler;
+ private final IoServiceConfig config;
+
+ private ConnectionRequest(SocketChannel channel, IoHandler handler, IoServiceConfig config)
+ {
+ this.channel = channel;
+ long timeout;
+ if (config instanceof IoConnectorConfig)
+ {
+ timeout = ((IoConnectorConfig) config).getConnectTimeoutMillis();
+ }
+ else
+ {
+ timeout = ((IoConnectorConfig) getDefaultConfig()).getConnectTimeoutMillis();
+ }
+ this.deadline = System.currentTimeMillis() + timeout;
+ this.handler = handler;
+ this.config = config;
+ }
+ }
+}
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/AMQAnyDestination.java b/qpid/java/client/src/main/java/org/apache/qpid/client/AMQAnyDestination.java
index 999b22299c..a201f7d61e 100644
--- a/qpid/java/client/src/main/java/org/apache/qpid/client/AMQAnyDestination.java
+++ b/qpid/java/client/src/main/java/org/apache/qpid/client/AMQAnyDestination.java
@@ -72,17 +72,6 @@ public class AMQAnyDestination extends AMQDestination implements Queue, Topic
public String getTopicName() throws JMSException
{
- if (getRoutingKey() != null)
- {
- return getRoutingKey().asString();
- }
- else if (getSubject() != null)
- {
- return getSubject();
- }
- else
- {
- return null;
- }
+ return super.getRoutingKey().toString();
}
}
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/AMQBrokerDetails.java b/qpid/java/client/src/main/java/org/apache/qpid/client/AMQBrokerDetails.java
index c8576bf00d..ee52cd50af 100644
--- a/qpid/java/client/src/main/java/org/apache/qpid/client/AMQBrokerDetails.java
+++ b/qpid/java/client/src/main/java/org/apache/qpid/client/AMQBrokerDetails.java
@@ -56,7 +56,9 @@ public class AMQBrokerDetails implements BrokerDetails
if (transport != null)
{
//todo this list of valid transports should be enumerated somewhere
- if (!(transport.equalsIgnoreCase(BrokerDetails.TCP)))
+ if ((!(transport.equalsIgnoreCase(BrokerDetails.VM) ||
+ transport.equalsIgnoreCase(BrokerDetails.TCP) ||
+ transport.equalsIgnoreCase(BrokerDetails.SOCKET))))
{
if (transport.equalsIgnoreCase("localhost"))
{
@@ -103,21 +105,6 @@ public class AMQBrokerDetails implements BrokerDetails
if (host == null)
{
host = "";
-
- String auth = connection.getAuthority();
- if (auth != null)
- {
- // contains both host & port myhost:5672
- if (auth.contains(":"))
- {
- host = auth.substring(0,auth.indexOf(":"));
- }
- else
- {
- host = auth;
- }
- }
-
}
setHost(host);
@@ -180,7 +167,10 @@ public class AMQBrokerDetails implements BrokerDetails
}
else
{
- setPort(port);
+ if (!_transport.equalsIgnoreCase(SOCKET))
+ {
+ setPort(port);
+ }
}
String queryString = connection.getQuery();
@@ -296,9 +286,17 @@ public class AMQBrokerDetails implements BrokerDetails
sb.append(_transport);
sb.append("://");
- sb.append(_host);
- sb.append(':');
- sb.append(_port);
+
+ if (!(_transport.equalsIgnoreCase(VM)))
+ {
+ sb.append(_host);
+ }
+
+ if (!(_transport.equalsIgnoreCase(SOCKET)))
+ {
+ sb.append(':');
+ sb.append(_port);
+ }
sb.append(printOptionsURL());
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 4a62f443f1..ab59fee020 100644
--- a/qpid/java/client/src/main/java/org/apache/qpid/client/AMQConnection.java
+++ b/qpid/java/client/src/main/java/org/apache/qpid/client/AMQConnection.java
@@ -111,7 +111,7 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect
/** Maps from session id (Integer) to AMQSession instance */
private final ChannelToSessionMap _sessions = new ChannelToSessionMap();
- private final String _clientName;
+ private String _clientName;
/** The user name to use for authentication */
private String _username;
@@ -126,7 +126,7 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect
private ConnectionListener _connectionListener;
- private final ConnectionURL _connectionURL;
+ private ConnectionURL _connectionURL;
/**
* Whether this connection is started, i.e. whether messages are flowing to consumers. It has no meaning for message
@@ -173,8 +173,8 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect
//Indicates the sync publish options (persistent|all)
//By default it's async publish
private String _syncPublish = "";
-
- // Indicates whether to use the old map message format or the
+
+ // Indicates whether to use the old map message format or the
// new amqp-0-10 encoded format.
private boolean _useLegacyMapMessageFormat;
@@ -257,11 +257,6 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect
*/
public AMQConnection(ConnectionURL connectionURL, SSLConfiguration sslConfig) throws AMQException
{
- if (connectionURL == null)
- {
- throw new IllegalArgumentException("Connection must be specified");
- }
-
// set this connection maxPrefetch
if (connectionURL.getOption(ConnectionURL.OPTIONS_MAXPREFETCH) != null)
{
@@ -269,7 +264,7 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect
}
else
{
- // use the default value set for all connections
+ // use the defaul value set for all connections
_maxPrefetch = Integer.parseInt(System.getProperties().getProperty(ClientProperties.MAX_PREFETCH_PROP_NAME,
ClientProperties.MAX_PREFETCH_DEFAULT));
}
@@ -283,7 +278,7 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect
}
else
{
- // use the default value set for all connections
+ // use the defaul value set for all connections
_syncPersistence = Boolean.getBoolean(ClientProperties.SYNC_PERSISTENT_PROP_NAME);
if (_syncPersistence)
{
@@ -298,7 +293,7 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect
}
else
{
- // use the default value set for all connections
+ // use the defaul value set for all connections
_syncAck = Boolean.getBoolean(ClientProperties.SYNC_ACK_PROP_NAME);
}
@@ -311,7 +306,7 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect
// use the default value set for all connections
_syncPublish = System.getProperty((ClientProperties.SYNC_PUBLISH_PROP_NAME),_syncPublish);
}
-
+
if (connectionURL.getOption(ConnectionURL.OPTIONS_USE_LEGACY_MAP_MESSAGE_FORMAT) != null)
{
_useLegacyMapMessageFormat = Boolean.parseBoolean(
@@ -322,16 +317,16 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect
// use the default value set for all connections
_useLegacyMapMessageFormat = Boolean.getBoolean(ClientProperties.USE_LEGACY_MAP_MESSAGE_FORMAT);
}
-
+
String amqpVersion = System.getProperty((ClientProperties.AMQP_VERSION), "0-10");
_logger.debug("AMQP version " + amqpVersion);
-
+
_failoverPolicy = new FailoverPolicy(connectionURL, this);
BrokerDetails brokerDetails = _failoverPolicy.getCurrentBrokerDetails();
- if ("0-8".equals(amqpVersion))
+ if (brokerDetails.getTransport().equals(BrokerDetails.VM) || "0-8".equals(amqpVersion))
{
_delegate = new AMQConnectionDelegate_8_0(this);
- }
+ }
else if ("0-9".equals(amqpVersion))
{
_delegate = new AMQConnectionDelegate_0_9(this);
@@ -351,6 +346,11 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect
}
_sslConfiguration = sslConfig;
+ if (connectionURL == null)
+ {
+ throw new IllegalArgumentException("Connection must be specified");
+ }
+
_connectionURL = connectionURL;
_clientName = connectionURL.getClientName();
@@ -418,7 +418,6 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect
brokerDetails = _failoverPolicy.getNextBrokerDetails();
}
}
- verifyClientID();
if (_logger.isDebugEnabled())
{
@@ -505,7 +504,7 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect
Class partypes[] = new Class[1];
partypes[0] = AMQConnection.class;
_delegate = (AMQConnectionDelegate) c.getConstructor(partypes).newInstance(this);
- //Update our session to use this new protocol version
+ //Update our session to use this new protocol version
_protocolHandler.getProtocolSession().setProtocolVersion(_delegate.getProtocolVersion());
}
@@ -536,6 +535,14 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect
}
}
+ protected AMQConnection(String username, String password, String clientName, String virtualHost)
+ {
+ _clientName = clientName;
+ _username = username;
+ _password = password;
+ setVirtualHost(virtualHost);
+ }
+
private void setVirtualHost(String virtualHost)
{
if (virtualHost != null && virtualHost.startsWith("/"))
@@ -689,6 +696,20 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect
}
}
+ private void reopenChannel(int channelId, int prefetchHigh, int prefetchLow, boolean transacted)
+ throws AMQException, FailoverException
+ {
+ try
+ {
+ createChannelOverWire(channelId, prefetchHigh, prefetchLow, transacted);
+ }
+ catch (AMQException e)
+ {
+ deregisterSession(channelId);
+ throw new AMQException(null, "Error reopening channel " + channelId + " after failover: " + e, e);
+ }
+ }
+
public void setFailoverPolicy(FailoverPolicy policy)
{
_failoverPolicy = policy;
@@ -1075,7 +1096,7 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect
{
_username = id;
}
-
+
public String getPassword()
{
return _password;
@@ -1251,7 +1272,7 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect
{
je.setLinkedException((Exception) cause);
}
-
+
je.initCause(cause);
}
@@ -1284,7 +1305,7 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect
{
_logger.info("Not a hard-error connection not closing: " + cause);
}
-
+
// deliver the exception if there is a listener
if (_exceptionListener != null)
{
@@ -1294,7 +1315,7 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect
{
_logger.error("Throwable Received but no listener set: " + cause);
}
-
+
// if we are closing the connection, close sessions first
if (closer)
{
@@ -1351,20 +1372,6 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect
return buf.toString();
}
- /**
- * Returns connection url.
- * @return connection url
- */
- public ConnectionURL getConnectionURL()
- {
- return _connectionURL;
- }
-
- /**
- * Returns stringified connection url. This url is suitable only for display
- * as {@link AMQConnectionURL#toString()} converts any password to asterisks.
- * @return connection url
- */
public String toURL()
{
return _connectionURL.toString();
@@ -1435,18 +1442,7 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect
{
return _delegate.getProtocolVersion();
}
-
- public String getBrokerUUID()
- {
- if(getProtocolVersion().equals(ProtocolVersion.v0_10))
- {
- return ((AMQConnectionDelegate_0_10)_delegate).getUUID();
- }
- else
- {
- return null;
- }
- }
+
public boolean isFailingOver()
{
return (_protocolHandler.getFailoverLatch() != null);
@@ -1489,24 +1485,9 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect
{
return _sessions.getNextChannelId();
}
-
+
public boolean isUseLegacyMapMessageFormat()
{
return _useLegacyMapMessageFormat;
}
-
- private void verifyClientID() throws AMQException
- {
- if (Boolean.getBoolean(ClientProperties.QPID_VERIFY_CLIENT_ID))
- {
- try
- {
- _delegate.verifyClientID();
- }
- catch(JMSException e)
- {
- throw new AMQException(AMQConstant.ALREADY_EXISTS,"ClientID must be unique",e);
- }
- }
- }
}
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/AMQConnectionDelegate.java b/qpid/java/client/src/main/java/org/apache/qpid/client/AMQConnectionDelegate.java
index 5acdaaa185..9560bd5c7c 100644
--- a/qpid/java/client/src/main/java/org/apache/qpid/client/AMQConnectionDelegate.java
+++ b/qpid/java/client/src/main/java/org/apache/qpid/client/AMQConnectionDelegate.java
@@ -57,12 +57,10 @@ public interface AMQConnectionDelegate
void closeConnection(long timeout) throws JMSException, AMQException;
<T, E extends Exception> T executeRetrySupport(FailoverProtectedOperation<T,E> operation) throws E;
-
+
int getMaxChannelID();
int getMinChannelID();
ProtocolVersion getProtocolVersion();
-
- void verifyClientID() throws JMSException;
}
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 cb531d4fca..b0bd8f8e97 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
@@ -47,7 +47,6 @@ import org.apache.qpid.transport.ConnectionException;
import org.apache.qpid.transport.ConnectionListener;
import org.apache.qpid.transport.ConnectionSettings;
import org.apache.qpid.transport.ProtocolVersionException;
-import org.apache.qpid.transport.SessionDetachCode;
import org.apache.qpid.transport.TransportException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -58,11 +57,7 @@ public class AMQConnectionDelegate_0_10 implements AMQConnectionDelegate, Connec
* This class logger.
*/
private static final Logger _logger = LoggerFactory.getLogger(AMQConnectionDelegate_0_10.class);
-
- /**
- * The name of the UUID property
- */
- private static final String UUID_NAME = "qpid.federation_tag";
+
/**
* The AMQ Connection.
*/
@@ -74,12 +69,6 @@ public class AMQConnectionDelegate_0_10 implements AMQConnectionDelegate, Connec
org.apache.qpid.transport.Connection _qpidConnection;
private ConnectionException exception = null;
- static
- {
- // Register any configured SASL client factories.
- org.apache.qpid.client.security.DynamicSaslRegistrar.registerSaslProviders();
- }
-
//--- constructor
public AMQConnectionDelegate_0_10(AMQConnection conn)
{
@@ -91,14 +80,7 @@ public class AMQConnectionDelegate_0_10 implements AMQConnectionDelegate, Connec
/**
* create a Session and start it if required.
*/
-
public Session createSession(boolean transacted, int acknowledgeMode, int prefetchHigh, int prefetchLow)
- throws JMSException
- {
- return createSession(transacted,acknowledgeMode,prefetchHigh,prefetchLow,null);
- }
-
- public Session createSession(boolean transacted, int acknowledgeMode, int prefetchHigh, int prefetchLow, String name)
throws JMSException
{
_conn.checkNotClosed();
@@ -113,7 +95,7 @@ public class AMQConnectionDelegate_0_10 implements AMQConnectionDelegate, Connec
try
{
session = new AMQSession_0_10(_qpidConnection, _conn, channelId, transacted, acknowledgeMode, prefetchHigh,
- prefetchLow,name);
+ prefetchLow);
_conn.registerSession(channelId, session);
if (_conn._started)
{
@@ -229,8 +211,6 @@ public class AMQConnectionDelegate_0_10 implements AMQConnectionDelegate, Connec
public void resubscribeSessions() throws JMSException, AMQException, FailoverException
{
- _logger.info("Resuming connection");
- getQpidConnection().resume();
List<AMQSession> sessions = new ArrayList<AMQSession>(_conn.getSessions().values());
_logger.info(String.format("Resubscribing sessions = %s sessions.size=%d", sessions, sessions.size()));
for (AMQSession s : sessions)
@@ -347,11 +327,6 @@ public class AMQConnectionDelegate_0_10 implements AMQConnectionDelegate, Connec
return ProtocolVersion.v0_10;
}
- public String getUUID()
- {
- return (String)_qpidConnection.getServerProperties().get(UUID_NAME);
- }
-
private void retriveConnectionSettings(ConnectionSettings conSettings, BrokerDetails brokerDetail)
{
@@ -466,31 +441,12 @@ public class AMQConnectionDelegate_0_10 implements AMQConnectionDelegate, Connec
else
{
heartbeat = Integer.getInteger(ClientProperties.HEARTBEAT,ClientProperties.HEARTBEAT_DEFAULT);
- }
+ }
return heartbeat;
}
-
+
protected org.apache.qpid.transport.Connection getQpidConnection()
{
return _qpidConnection;
}
-
- public void verifyClientID() throws JMSException
- {
- int prefetch = (int)_conn.getMaxPrefetch();
- AMQSession_0_10 ssn = (AMQSession_0_10)createSession(false, 1,prefetch,prefetch,_conn.getClientID());
- org.apache.qpid.transport.Session ssn_0_10 = ssn.getQpidSession();
- try
- {
- ssn_0_10.awaitOpen();
- }
- catch(Exception e)
- {
- if (ssn_0_10.getDetachCode() != null &&
- ssn_0_10.getDetachCode() == SessionDetachCode.SESSION_BUSY)
- {
- throw new JMSException("ClientID must be unique");
- }
- }
- }
}
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/AMQConnectionDelegate_8_0.java b/qpid/java/client/src/main/java/org/apache/qpid/client/AMQConnectionDelegate_8_0.java
index 0cd1d49224..40b332d216 100644
--- a/qpid/java/client/src/main/java/org/apache/qpid/client/AMQConnectionDelegate_8_0.java
+++ b/qpid/java/client/src/main/java/org/apache/qpid/client/AMQConnectionDelegate_8_0.java
@@ -39,6 +39,7 @@ import org.apache.qpid.client.failover.FailoverRetrySupport;
import org.apache.qpid.client.protocol.AMQProtocolSession;
import org.apache.qpid.client.state.AMQState;
import org.apache.qpid.client.state.StateWaiter;
+import org.apache.qpid.client.transport.TransportConnection;
import org.apache.qpid.framing.BasicQosBody;
import org.apache.qpid.framing.BasicQosOkBody;
import org.apache.qpid.framing.ChannelOpenBody;
@@ -48,11 +49,6 @@ import org.apache.qpid.framing.TxSelectBody;
import org.apache.qpid.framing.TxSelectOkBody;
import org.apache.qpid.jms.BrokerDetails;
import org.apache.qpid.jms.ChannelLimitReachedException;
-import org.apache.qpid.ssl.SSLContextFactory;
-import org.apache.qpid.transport.ConnectionSettings;
-import org.apache.qpid.transport.network.NetworkConnection;
-import org.apache.qpid.transport.network.OutgoingNetworkTransport;
-import org.apache.qpid.transport.network.Transport;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -93,21 +89,15 @@ public class AMQConnectionDelegate_8_0 implements AMQConnectionDelegate
StateWaiter waiter = _conn._protocolHandler.createWaiter(openOrClosedStates);
- ConnectionSettings settings = new ConnectionSettings();
- settings.setHost(brokerDetail.getHost());
- settings.setPort(brokerDetail.getPort());
- settings.setProtocol(brokerDetail.getTransport());
-
- SSLConfiguration sslConfig = _conn.getSSLConfiguration();
- SSLContextFactory sslFactory = null;
- if (sslConfig != null)
+ // TODO: use system property thingy for this
+ if (System.getProperty("UseTransportIo", "false").equals("false"))
{
- sslFactory = new SSLContextFactory(sslConfig.getKeystorePath(), sslConfig.getKeystorePassword(), sslConfig.getCertType());
+ TransportConnection.getInstance(brokerDetail).connect(_conn._protocolHandler, brokerDetail);
+ }
+ else
+ {
+ _conn.getProtocolHandler().createIoTransportSession(brokerDetail);
}
-
- OutgoingNetworkTransport transport = Transport.getOutgoingTransportInstance(getProtocolVersion());
- NetworkConnection network = transport.connect(settings, _conn._protocolHandler, sslFactory);
- _conn._protocolHandler.setNetworkConnection(network);
_conn._protocolHandler.getProtocolSession().init();
// this blocks until the connection has been set up or when an error
// has prevented the connection being set up
@@ -332,9 +322,4 @@ public class AMQConnectionDelegate_8_0 implements AMQConnectionDelegate
{
return ProtocolVersion.v8_0;
}
-
- public void verifyClientID() throws JMSException
- {
- // NOOP
- }
}
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/AMQConnectionURL.java b/qpid/java/client/src/main/java/org/apache/qpid/client/AMQConnectionURL.java
index f9f50d9150..93b4c51a8f 100644
--- a/qpid/java/client/src/main/java/org/apache/qpid/client/AMQConnectionURL.java
+++ b/qpid/java/client/src/main/java/org/apache/qpid/client/AMQConnectionURL.java
@@ -27,14 +27,18 @@ import java.util.Map;
import org.apache.qpid.client.url.URLParser;
import org.apache.qpid.framing.AMQShortString;
+import org.apache.qpid.framing.ProtocolVersion;
import org.apache.qpid.jms.BrokerDetails;
import org.apache.qpid.jms.ConnectionURL;
import org.apache.qpid.url.URLHelper;
import org.apache.qpid.url.URLSyntaxException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
public class AMQConnectionURL implements ConnectionURL
{
-
+ private static final Logger _logger = LoggerFactory.getLogger(AMQConnectionURL.class);
+
private String _url;
private String _failoverMethod;
private Map<String, String> _failoverOptions;
@@ -291,4 +295,17 @@ public class AMQConnectionURL implements ConnectionURL
return sb.toString();
}
+
+ public static void main(String[] args) throws URLSyntaxException
+ {
+ String url2 =
+ "amqp://ritchiem:bob@temp/testHost?brokerlist='tcp://localhost:5672;tcp://fancyserver:3000/',failover='roundrobin'";
+ // "amqp://user:pass@clientid/virtualhost?brokerlist='tcp://host:1?option1=\'value\',option2=\'value\';vm://:3?option1=\'value\'',failover='method?option1=\'value\',option2='value''";
+
+ ConnectionURL connectionurl2 = new AMQConnectionURL(url2);
+
+ System.out.println(url2);
+ System.out.println(connectionurl2);
+
+ }
}
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/AMQDestination.java b/qpid/java/client/src/main/java/org/apache/qpid/client/AMQDestination.java
index 3ef32fb008..eb9682a3cf 100644
--- a/qpid/java/client/src/main/java/org/apache/qpid/client/AMQDestination.java
+++ b/qpid/java/client/src/main/java/org/apache/qpid/client/AMQDestination.java
@@ -21,6 +21,8 @@
package org.apache.qpid.client;
import java.net.URISyntaxException;
+import java.util.ArrayList;
+import java.util.List;
import java.util.Map;
import javax.jms.Destination;
@@ -32,6 +34,8 @@ import javax.naming.StringRefAddr;
import org.apache.qpid.client.messaging.address.AddressHelper;
import org.apache.qpid.client.messaging.address.Link;
import org.apache.qpid.client.messaging.address.Node;
+import org.apache.qpid.client.messaging.address.QpidExchangeOptions;
+import org.apache.qpid.client.messaging.address.QpidQueueOptions;
import org.apache.qpid.configuration.ClientProperties;
import org.apache.qpid.exchange.ExchangeDefaults;
import org.apache.qpid.framing.AMQShortString;
@@ -74,6 +78,11 @@ public abstract class AMQDestination implements Destination, Referenceable
private boolean _exchangeExistsChecked;
+ private byte[] _byteEncoding;
+ private static final int IS_DURABLE_MASK = 0x1;
+ private static final int IS_EXCLUSIVE_MASK = 0x2;
+ private static final int IS_AUTODELETE_MASK = 0x4;
+
public static final int QUEUE_TYPE = 1;
public static final int TOPIC_TYPE = 2;
public static final int UNKNOWN_TYPE = 3;
@@ -314,11 +323,7 @@ public abstract class AMQDestination implements Destination, Referenceable
{
if(_urlAsShortString == null)
{
- if (_url == null)
- {
- toURL();
- }
- _urlAsShortString = new AMQShortString(_url);
+ toURL();
}
return _urlAsShortString;
}
@@ -365,6 +370,7 @@ public abstract class AMQDestination implements Destination, Referenceable
// calculated URL now out of date
_url = null;
_urlAsShortString = null;
+ _byteEncoding = null;
}
public AMQShortString getRoutingKey()
@@ -502,10 +508,59 @@ public abstract class AMQDestination implements Destination, Referenceable
sb.deleteCharAt(sb.length() - 1);
url = sb.toString();
_url = url;
+ _urlAsShortString = new AMQShortString(url);
}
return url;
}
+ public byte[] toByteEncoding()
+ {
+ byte[] encoding = _byteEncoding;
+ if(encoding == null)
+ {
+ int size = _exchangeClass.length() + 1 +
+ _exchangeName.length() + 1 +
+ 0 + // in place of the destination name
+ (_queueName == null ? 0 : _queueName.length()) + 1 +
+ 1;
+ encoding = new byte[size];
+ int pos = 0;
+
+ pos = _exchangeClass.writeToByteArray(encoding, pos);
+ pos = _exchangeName.writeToByteArray(encoding, pos);
+
+ encoding[pos++] = (byte)0;
+
+ if(_queueName == null)
+ {
+ encoding[pos++] = (byte)0;
+ }
+ else
+ {
+ pos = _queueName.writeToByteArray(encoding,pos);
+ }
+ byte options = 0;
+ if(_isDurable)
+ {
+ options |= IS_DURABLE_MASK;
+ }
+ if(_isExclusive)
+ {
+ options |= IS_EXCLUSIVE_MASK;
+ }
+ if(_isAutoDelete)
+ {
+ options |= IS_AUTODELETE_MASK;
+ }
+ encoding[pos] = options;
+
+
+ _byteEncoding = encoding;
+
+ }
+ return encoding;
+ }
+
public boolean equals(Object o)
{
if (this == o)
@@ -559,6 +614,53 @@ public abstract class AMQDestination implements Destination, Referenceable
null); // factory location
}
+
+ public static Destination createDestination(byte[] byteEncodedDestination)
+ {
+ AMQShortString exchangeClass;
+ AMQShortString exchangeName;
+ AMQShortString routingKey;
+ AMQShortString queueName;
+ boolean isDurable;
+ boolean isExclusive;
+ boolean isAutoDelete;
+
+ int pos = 0;
+ exchangeClass = AMQShortString.readFromByteArray(byteEncodedDestination, pos);
+ pos+= exchangeClass.length() + 1;
+ exchangeName = AMQShortString.readFromByteArray(byteEncodedDestination, pos);
+ pos+= exchangeName.length() + 1;
+ routingKey = AMQShortString.readFromByteArray(byteEncodedDestination, pos);
+ pos+= (routingKey == null ? 0 : routingKey.length()) + 1;
+ queueName = AMQShortString.readFromByteArray(byteEncodedDestination, pos);
+ pos+= (queueName == null ? 0 : queueName.length()) + 1;
+ int options = byteEncodedDestination[pos];
+ isDurable = (options & IS_DURABLE_MASK) != 0;
+ isExclusive = (options & IS_EXCLUSIVE_MASK) != 0;
+ isAutoDelete = (options & IS_AUTODELETE_MASK) != 0;
+
+ if (exchangeClass.equals(ExchangeDefaults.DIRECT_EXCHANGE_CLASS))
+ {
+ return new AMQQueue(exchangeName,routingKey,queueName,isExclusive,isAutoDelete,isDurable);
+ }
+ else if (exchangeClass.equals(ExchangeDefaults.TOPIC_EXCHANGE_CLASS))
+ {
+ return new AMQTopic(exchangeName,routingKey,isAutoDelete,queueName,isDurable);
+ }
+ else if (exchangeClass.equals(ExchangeDefaults.HEADERS_EXCHANGE_CLASS))
+ {
+ return new AMQHeadersExchange(routingKey);
+ }
+ else
+ {
+ return new AMQAnyDestination(exchangeName,exchangeClass,
+ routingKey,isExclusive,
+ isAutoDelete,queueName,
+ isDurable, new AMQShortString[0]);
+ }
+
+ }
+
public static Destination createDestination(BindingURL binding)
{
AMQShortString type = binding.getExchangeClass();
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/AMQSession.java b/qpid/java/client/src/main/java/org/apache/qpid/client/AMQSession.java
index 25562cfff7..1f940b62f0 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
@@ -567,8 +567,6 @@ public abstract class AMQSession<C extends BasicMessageConsumer, P extends Basic
close(-1);
}
- public abstract AMQException getLastException();
-
public void checkNotClosed() throws JMSException
{
try
@@ -577,20 +575,16 @@ public abstract class AMQSession<C extends BasicMessageConsumer, P extends Basic
}
catch (IllegalStateException ise)
{
- AMQException ex = getLastException();
- if (ex != null)
- {
- IllegalStateException ssnClosed = new IllegalStateException(
- "Session has been closed", ex.getErrorCode().toString());
+ // if the Connection has closed then we should throw any exception that has occurred that we were not waiting for
+ AMQStateManager manager = _connection.getProtocolHandler().getStateManager();
- ssnClosed.setLinkedException(ex);
- ssnClosed.initCause(ex);
- throw ssnClosed;
- }
- else
+ if (manager.getCurrentState().equals(AMQState.CONNECTION_CLOSED) && manager.getLastException() != null)
{
- throw ise;
+ ise.setLinkedException(manager.getLastException());
+ ise.initCause(ise.getLinkedException());
}
+
+ throw ise;
}
}
@@ -1049,29 +1043,8 @@ public abstract class AMQSession<C extends BasicMessageConsumer, P extends Basic
throws JMSException
{
checkNotClosed();
- Topic origTopic = checkValidTopic(topic, true);
-
+ AMQTopic origTopic = checkValidTopic(topic, true);
AMQTopic dest = AMQTopic.createDurableTopic(origTopic, name, _connection);
- if (dest.getDestSyntax() == DestSyntax.ADDR &&
- !dest.isAddressResolved())
- {
- try
- {
- handleAddressBasedDestination(dest,false,true);
- if (dest.getAddressType() != AMQDestination.TOPIC_TYPE)
- {
- throw new JMSException("Durable subscribers can only be created for Topics");
- }
- dest.getSourceNode().setDurable(true);
- }
- catch(AMQException e)
- {
- JMSException ex = new JMSException("Error when verifying destination");
- ex.initCause(e);
- ex.setLinkedException(e);
- throw ex;
- }
- }
String messageSelector = ((selector == null) || (selector.trim().length() == 0)) ? null : selector;
@@ -1083,9 +1056,15 @@ public abstract class AMQSession<C extends BasicMessageConsumer, P extends Basic
// Not subscribed to this name in the current session
if (subscriber == null)
{
- // After the address is resolved routing key will not be null.
- AMQShortString topicName = dest.getRoutingKey();
-
+ AMQShortString topicName;
+ if (topic instanceof AMQTopic)
+ {
+ topicName = ((AMQTopic) topic).getRoutingKey();
+ } else
+ {
+ topicName = new AMQShortString(topic.getTopicName());
+ }
+
if (_strictAMQP)
{
if (_strictAMQPFATAL)
@@ -1246,6 +1225,7 @@ public abstract class AMQSession<C extends BasicMessageConsumer, P extends Basic
else
{
AMQQueue queue = new AMQQueue(queueName);
+ queue.setCreate(AddressOption.ALWAYS);
return queue;
}
@@ -1327,8 +1307,8 @@ public abstract class AMQSession<C extends BasicMessageConsumer, P extends Basic
public QueueReceiver createQueueReceiver(Destination destination) throws JMSException
{
checkValidDestination(destination);
- Queue dest = validateQueue(destination);
- C consumer = (C) createConsumer(dest);
+ AMQQueue dest = (AMQQueue) destination;
+ C consumer = (C) createConsumer(destination);
return new QueueReceiverAdaptor(dest, consumer);
}
@@ -1346,8 +1326,8 @@ public abstract class AMQSession<C extends BasicMessageConsumer, P extends Basic
public QueueReceiver createQueueReceiver(Destination destination, String messageSelector) throws JMSException
{
checkValidDestination(destination);
- Queue dest = validateQueue(destination);
- C consumer = (C) createConsumer(dest, messageSelector);
+ AMQQueue dest = (AMQQueue) destination;
+ C consumer = (C) createConsumer(destination, messageSelector);
return new QueueReceiverAdaptor(dest, consumer);
}
@@ -1364,7 +1344,7 @@ public abstract class AMQSession<C extends BasicMessageConsumer, P extends Basic
public QueueReceiver createReceiver(Queue queue) throws JMSException
{
checkNotClosed();
- Queue dest = validateQueue(queue);
+ AMQQueue dest = (AMQQueue) queue;
C consumer = (C) createConsumer(dest);
return new QueueReceiverAdaptor(dest, consumer);
@@ -1383,23 +1363,11 @@ public abstract class AMQSession<C extends BasicMessageConsumer, P extends Basic
public QueueReceiver createReceiver(Queue queue, String messageSelector) throws JMSException
{
checkNotClosed();
- Queue dest = validateQueue(queue);
+ AMQQueue dest = (AMQQueue) queue;
C consumer = (C) createConsumer(dest, messageSelector);
return new QueueReceiverAdaptor(dest, consumer);
}
-
- private Queue validateQueue(Destination dest) throws InvalidDestinationException
- {
- if (dest instanceof AMQDestination && dest instanceof javax.jms.Queue)
- {
- return (Queue)dest;
- }
- else
- {
- throw new InvalidDestinationException("The destination object used is not from this provider or of type javax.jms.Queue");
- }
- }
public QueueSender createSender(Queue queue) throws JMSException
{
@@ -1440,7 +1408,7 @@ public abstract class AMQSession<C extends BasicMessageConsumer, P extends Basic
public TopicSubscriber createSubscriber(Topic topic) throws JMSException
{
checkNotClosed();
- Topic dest = checkValidTopic(topic);
+ AMQTopic dest = checkValidTopic(topic);
// AMQTopic dest = new AMQTopic(topic.getTopicName());
return new TopicSubscriberAdaptor(dest, (C) createExclusiveConsumer(dest));
@@ -1460,7 +1428,7 @@ public abstract class AMQSession<C extends BasicMessageConsumer, P extends Basic
public TopicSubscriber createSubscriber(Topic topic, String messageSelector, boolean noLocal) throws JMSException
{
checkNotClosed();
- Topic dest = checkValidTopic(topic);
+ AMQTopic dest = checkValidTopic(topic);
// AMQTopic dest = new AMQTopic(topic.getTopicName());
return new TopicSubscriberAdaptor(dest, (C) createExclusiveConsumer(dest, messageSelector, noLocal));
@@ -2427,7 +2395,7 @@ public abstract class AMQSession<C extends BasicMessageConsumer, P extends Basic
/*
* I could have combined the last 3 methods, but this way it improves readability
*/
- protected Topic checkValidTopic(Topic topic, boolean durable) throws JMSException
+ protected AMQTopic checkValidTopic(Topic topic, boolean durable) throws JMSException
{
if (topic == null)
{
@@ -2446,17 +2414,17 @@ public abstract class AMQSession<C extends BasicMessageConsumer, P extends Basic
("Cannot create a durable subscription with a temporary topic: " + topic);
}
- if (!(topic instanceof AMQDestination && topic instanceof javax.jms.Topic))
+ if (!(topic instanceof AMQTopic))
{
throw new javax.jms.InvalidDestinationException(
"Cannot create a subscription on topic created for another JMS Provider, class of topic provided is: "
+ topic.getClass().getName());
}
- return topic;
+ return (AMQTopic) topic;
}
- protected Topic checkValidTopic(Topic topic) throws JMSException
+ protected AMQTopic checkValidTopic(Topic topic) throws JMSException
{
return checkValidTopic(topic, false);
}
@@ -2851,7 +2819,6 @@ public abstract class AMQSession<C extends BasicMessageConsumer, P extends Basic
{
declareQueue(amqd, protocolHandler, consumer.isNoLocal(), nowait);
}
- bindQueue(amqd.getAMQQueueName(), amqd.getRoutingKey(), consumer.getArguments(), amqd.getExchangeName(), amqd, nowait);
}
AMQShortString queueName = amqd.getAMQQueueName();
@@ -2859,6 +2826,8 @@ public abstract class AMQSession<C extends BasicMessageConsumer, P extends Basic
// store the consumer queue name
consumer.setQueuename(queueName);
+ 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)
{
@@ -3481,9 +3450,4 @@ public abstract class AMQSession<C extends BasicMessageConsumer, P extends Basic
{
return _closing.get()|| _connection.isClosing();
}
-
- public boolean isDeclareExchanges()
- {
- return DECLARE_EXCHANGES;
- }
}
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 75d96d67af..517a7a5ce8 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
@@ -47,8 +47,6 @@ import org.apache.qpid.client.message.AMQMessageDelegateFactory;
import org.apache.qpid.client.message.FieldTableSupport;
import org.apache.qpid.client.message.MessageFactoryRegistry;
import org.apache.qpid.client.message.UnprocessedMessage_0_10;
-import org.apache.qpid.client.messaging.address.Link;
-import org.apache.qpid.client.messaging.address.Link.Reliability;
import org.apache.qpid.client.messaging.address.Node.ExchangeNode;
import org.apache.qpid.client.messaging.address.Node.QueueNode;
import org.apache.qpid.client.protocol.AMQProtocolHandler;
@@ -58,7 +56,6 @@ import org.apache.qpid.framing.FieldTable;
import org.apache.qpid.protocol.AMQConstant;
import org.apache.qpid.transport.ExchangeBoundResult;
import org.apache.qpid.transport.ExchangeQueryResult;
-import org.apache.qpid.transport.ExecutionErrorCode;
import org.apache.qpid.transport.ExecutionException;
import org.apache.qpid.transport.MessageAcceptMode;
import org.apache.qpid.transport.MessageAcquireMode;
@@ -159,20 +156,13 @@ public class AMQSession_0_10 extends AMQSession<BasicMessageConsumer_0_10, Basic
*/
AMQSession_0_10(org.apache.qpid.transport.Connection qpidConnection, AMQConnection con, int channelId,
boolean transacted, int acknowledgeMode, MessageFactoryRegistry messageFactoryRegistry,
- int defaultPrefetchHighMark, int defaultPrefetchLowMark,String name)
+ int defaultPrefetchHighMark, int defaultPrefetchLowMark)
{
super(con, channelId, transacted, acknowledgeMode, messageFactoryRegistry, defaultPrefetchHighMark,
defaultPrefetchLowMark);
_qpidConnection = qpidConnection;
- if (name == null)
- {
- _qpidSession = _qpidConnection.createSession(1);
- }
- else
- {
- _qpidSession = _qpidConnection.createSession(name,1);
- }
+ _qpidSession = _qpidConnection.createSession(1);
_qpidSession.setSessionListener(this);
if (_transacted)
{
@@ -199,12 +189,11 @@ public class AMQSession_0_10 extends AMQSession<BasicMessageConsumer_0_10, Basic
* @param qpidConnection The connection
*/
AMQSession_0_10(org.apache.qpid.transport.Connection qpidConnection, AMQConnection con, int channelId,
- boolean transacted, int acknowledgeMode, int defaultPrefetchHigh, int defaultPrefetchLow,
- String name)
+ boolean transacted, int acknowledgeMode, int defaultPrefetchHigh, int defaultPrefetchLow)
{
this(qpidConnection, con, channelId, transacted, acknowledgeMode, MessageFactoryRegistry.newDefaultRegistry(),
- defaultPrefetchHigh, defaultPrefetchLow,name);
+ defaultPrefetchHigh, defaultPrefetchLow);
}
private void addUnacked(int id)
@@ -325,7 +314,7 @@ public class AMQSession_0_10 extends AMQSession<BasicMessageConsumer_0_10, Basic
public void sendQueueBind(final AMQShortString queueName, final AMQShortString routingKey,
final FieldTable arguments, final AMQShortString exchangeName,
final AMQDestination destination, final boolean nowait)
- throws AMQException
+ throws AMQException, FailoverException
{
if (destination.getDestSyntax() == DestSyntax.BURL)
{
@@ -611,16 +600,10 @@ public class AMQSession_0_10 extends AMQSession<BasicMessageConsumer_0_10, Basic
(Map<? extends String, ? extends Object>) consumer.getDestination().getLink().getSubscription().getArgs());
}
- boolean acceptModeNone = getAcknowledgeMode() == NO_ACKNOWLEDGE;
-
- if (consumer.getDestination().getLink() != null)
- {
- acceptModeNone = consumer.getDestination().getLink().getReliability() == Link.Reliability.UNRELIABLE;
- }
getQpidSession().messageSubscribe
(queueName.toString(), String.valueOf(tag),
- acceptModeNone ? MessageAcceptMode.NONE : MessageAcceptMode.EXPLICIT,
+ getAcknowledgeMode() == NO_ACKNOWLEDGE ? MessageAcceptMode.NONE : MessageAcceptMode.EXPLICIT,
preAcquire ? MessageAcquireMode.PRE_ACQUIRED : MessageAcquireMode.NOT_ACQUIRED, null, 0, arguments,
consumer.isExclusive() ? Option.EXCLUSIVE : Option.NONE);
}
@@ -784,7 +767,7 @@ public class AMQSession_0_10 extends AMQSession<BasicMessageConsumer_0_10, Basic
else
{
QueueNode node = (QueueNode)amqd.getSourceNode();
- getQpidSession().queueDeclare(queueName.toString(), node.getAlternateExchange() ,
+ getQpidSession().queueDeclare(queueName.toString(), "" ,
node.getDeclareArgs(),
node.isAutoDelete() ? Option.AUTO_DELETE : Option.NONE,
node.isDurable() ? Option.DURABLE : Option.NONE,
@@ -921,26 +904,7 @@ public class AMQSession_0_10 extends AMQSession<BasicMessageConsumer_0_10, Basic
setCurrentException(exc);
}
- public void closed(Session ssn)
- {
- try
- {
- super.closed(null);
- if (flushTask != null)
- {
- flushTask.cancel();
- flushTask = null;
- }
- } catch (Exception e)
- {
- _logger.error("Error closing JMS session", e);
- }
- }
-
- public AMQException getLastException()
- {
- return getCurrentException();
- }
+ public void closed(Session ssn) {}
protected AMQShortString declareQueue(final AMQDestination amqd, final AMQProtocolHandler protocolHandler,
final boolean noLocal, final boolean nowait)
@@ -1056,9 +1020,11 @@ public class AMQSession_0_10 extends AMQSession<BasicMessageConsumer_0_10, Basic
code = ee.getErrorCode().getValue();
}
AMQException amqe = new AMQException(AMQConstant.getConstant(code), se.getMessage(), se.getCause());
+
+ _connection.exceptionReceived(amqe);
+
_currentException = amqe;
}
- _connection.exceptionReceived(_currentException);
}
public AMQMessageDelegateFactory getMessageDelegateFactory()
@@ -1102,37 +1068,22 @@ public class AMQSession_0_10 extends AMQSession<BasicMessageConsumer_0_10, Basic
return match;
}
- public boolean isQueueExist(AMQDestination dest,QueueNode node,boolean assertNode) throws AMQException
+ public boolean isQueueExist(AMQDestination dest,QueueNode node,boolean assertNode)
{
boolean match = true;
- try
+ QueueQueryResult result = getQpidSession().queueQuery(dest.getAddressName(), Option.NONE).get();
+ match = dest.getAddressName().equals(result.getQueue());
+
+ if (match && assertNode)
{
- QueueQueryResult result = getQpidSession().queueQuery(dest.getAddressName(), Option.NONE).get();
- match = dest.getAddressName().equals(result.getQueue());
-
- if (match && assertNode)
- {
- match = (result.getDurable() == node.isDurable()) &&
- (result.getAutoDelete() == node.isAutoDelete()) &&
- (result.getExclusive() == node.isExclusive()) &&
- (matchProps(result.getArguments(),node.getDeclareArgs()));
- }
- else if (match)
- {
- // should I use the queried details to update the local data structure.
- }
+ match = (result.getDurable() == node.isDurable()) &&
+ (result.getAutoDelete() == node.isAutoDelete()) &&
+ (result.getExclusive() == node.isExclusive()) &&
+ (matchProps(result.getArguments(),node.getDeclareArgs()));
}
- catch(SessionException e)
+ else if (match)
{
- if (e.getException().getErrorCode() == ExecutionErrorCode.RESOURCE_DELETED)
- {
- match = false;
- }
- else
- {
- throw new AMQException(AMQConstant.getConstant(e.getException().getErrorCode().getValue()),
- "Error querying queue",e);
- }
+ // should I use the queried details to update the local data structure.
}
return match;
@@ -1198,22 +1149,6 @@ public class AMQSession_0_10 extends AMQSession<BasicMessageConsumer_0_10, Basic
int type = resolveAddressType(dest);
- if (type == AMQDestination.QUEUE_TYPE &&
- dest.getLink().getReliability() == Reliability.UNSPECIFIED)
- {
- dest.getLink().setReliability(Reliability.AT_LEAST_ONCE);
- }
- else if (type == AMQDestination.TOPIC_TYPE &&
- dest.getLink().getReliability() == Reliability.UNSPECIFIED)
- {
- dest.getLink().setReliability(Reliability.UNRELIABLE);
- }
- else if (type == AMQDestination.TOPIC_TYPE &&
- dest.getLink().getReliability() == Reliability.AT_LEAST_ONCE)
- {
- throw new AMQException("AT-LEAST-ONCE is not yet supported for Topics");
- }
-
switch (type)
{
case AMQDestination.QUEUE_TYPE:
@@ -1227,8 +1162,6 @@ public class AMQSession_0_10 extends AMQSession<BasicMessageConsumer_0_10, Basic
{
setLegacyFiledsForQueueType(dest);
send0_10QueueDeclare(dest,null,false,noWait);
- sendQueueBind(dest.getAMQQueueName(), dest.getRoutingKey(),
- null,dest.getExchangeName(),dest, false);
break;
}
}
@@ -1337,8 +1270,6 @@ public class AMQSession_0_10 extends AMQSession<BasicMessageConsumer_0_10, Basic
dest.getQueueName(),// should have one by now
dest.getSubject(),
Collections.<String,Object>emptyMap()));
- sendQueueBind(dest.getAMQQueueName(), dest.getRoutingKey(),
- null,dest.getExchangeName(),dest, false);
}
public void setLegacyFiledsForQueueType(AMQDestination dest)
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 c010e4c7ed..f41b1c94fa 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
@@ -38,7 +38,6 @@ import org.apache.qpid.client.message.ReturnMessage;
import org.apache.qpid.client.message.UnprocessedMessage;
import org.apache.qpid.client.protocol.AMQProtocolHandler;
import org.apache.qpid.client.state.AMQState;
-import org.apache.qpid.client.state.AMQStateManager;
import org.apache.qpid.client.state.listener.SpecificMethodFrameListener;
import org.apache.qpid.common.AMQPFilterTypes;
import org.apache.qpid.framing.AMQFrame;
@@ -585,35 +584,4 @@ public final class AMQSession_0_8 extends AMQSession<BasicMessageConsumer_0_8, B
queueName == null ? null : new AMQShortString(queueName),
bindingKey == null ? null : new AMQShortString(bindingKey));
}
-
-
- public AMQException getLastException()
- {
- // if the Connection has closed then we should throw any exception that
- // has occurred that we were not waiting for
- AMQStateManager manager = _connection.getProtocolHandler()
- .getStateManager();
-
- Exception e = manager.getLastException();
- if (manager.getCurrentState().equals(AMQState.CONNECTION_CLOSED)
- && e != null)
- {
- if (e instanceof AMQException)
- {
- return (AMQException) e;
- }
- else
- {
- AMQException amqe = new AMQException(AMQConstant
- .getConstant(AMQConstant.INTERNAL_ERROR.getCode()),
- e.getMessage(), e.getCause());
- return amqe;
- }
- }
- else
- {
- return null;
- }
- }
-
}
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/AMQTopic.java b/qpid/java/client/src/main/java/org/apache/qpid/client/AMQTopic.java
index 780dbcafc2..6217cb534a 100644
--- a/qpid/java/client/src/main/java/org/apache/qpid/client/AMQTopic.java
+++ b/qpid/java/client/src/main/java/org/apache/qpid/client/AMQTopic.java
@@ -22,7 +22,6 @@ package org.apache.qpid.client;
import java.net.URISyntaxException;
-import javax.jms.InvalidDestinationException;
import javax.jms.JMSException;
import javax.jms.Topic;
@@ -96,47 +95,39 @@ public class AMQTopic extends AMQDestination implements Topic
super(exchangeName, exchangeClass, routingKey, isExclusive, isAutoDelete, queueName, isDurable,bindingKeys);
}
- public static AMQTopic createDurableTopic(Topic topic, String subscriptionName, AMQConnection connection)
+ public static AMQTopic createDurableTopic(AMQTopic topic, String subscriptionName, AMQConnection connection)
throws JMSException
{
- if (topic instanceof AMQDestination && topic instanceof javax.jms.Topic)
+ if (topic.getDestSyntax() == DestSyntax.ADDR)
{
- AMQDestination qpidTopic = (AMQDestination)topic;
- if (qpidTopic.getDestSyntax() == DestSyntax.ADDR)
+ try
{
- try
- {
- AMQTopic t = new AMQTopic(qpidTopic.getAddress());
- AMQShortString queueName = getDurableTopicQueueName(subscriptionName, connection);
- // link is never null if dest was created using an address string.
- t.getLink().setName(queueName.asString());
- t.getSourceNode().setAutoDelete(false);
- t.getSourceNode().setDurable(true);
-
- // The legacy fields are also populated just in case.
- t.setQueueName(queueName);
- t.setAutoDelete(false);
- t.setDurable(true);
- return t;
- }
- catch(Exception e)
- {
- JMSException ex = new JMSException("Error creating durable topic");
- ex.initCause(e);
- ex.setLinkedException(e);
- throw ex;
- }
+ AMQTopic t = new AMQTopic(topic.getAddress());
+ AMQShortString queueName = getDurableTopicQueueName(subscriptionName, connection);
+ // link is never null if dest was created using an address string.
+ t.getLink().setName(queueName.asString());
+ t.getSourceNode().setAutoDelete(false);
+ t.getSourceNode().setDurable(true);
+
+ // The legacy fields are also populated just in case.
+ t.setQueueName(queueName);
+ t.setAutoDelete(false);
+ t.setDurable(true);
+ return t;
}
- else
+ catch(Exception e)
{
- return new AMQTopic(qpidTopic.getExchangeName(), qpidTopic.getRoutingKey(), false,
- getDurableTopicQueueName(subscriptionName, connection),
- true);
+ JMSException ex = new JMSException("Error creating durable topic");
+ ex.initCause(e);
+ ex.setLinkedException(e);
+ throw ex;
}
}
else
{
- throw new InvalidDestinationException("The destination object used is not from this provider or of type javax.jms.Topic");
+ return new AMQTopic(topic.getExchangeName(), topic.getRoutingKey(), false,
+ getDurableTopicQueueName(subscriptionName, connection),
+ true);
}
}
@@ -147,17 +138,13 @@ public class AMQTopic extends AMQDestination implements Topic
public String getTopicName() throws JMSException
{
- if (getRoutingKey() != null)
+ if (super.getRoutingKey() == null && super.getSubject() != null)
{
- return getRoutingKey().asString();
- }
- else if (getSubject() != null)
- {
- return getSubject();
+ return super.getSubject();
}
else
{
- return null;
+ return super.getRoutingKey().toString();
}
}
@@ -176,18 +163,12 @@ public class AMQTopic extends AMQDestination implements Topic
public AMQShortString getRoutingKey()
{
- if (super.getRoutingKey() != null)
- {
- return super.getRoutingKey();
- }
- else if (getSubject() != null)
+ if (super.getRoutingKey() == null && super.getSubject() != null)
{
- return new AMQShortString(getSubject());
+ return new AMQShortString(super.getSubject());
}
else
{
- setRoutingKey(new AMQShortString(""));
- setSubject("");
return super.getRoutingKey();
}
}
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 5d32863f2f..0a78403268 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
@@ -571,7 +571,6 @@ public abstract class BasicMessageConsumer<U> extends Closeable implements Messa
if (!_session.isClosed() || _session.isClosing())
{
sendCancel();
- cleanupQueue();
}
}
catch (AMQException e)
@@ -609,8 +608,6 @@ public abstract class BasicMessageConsumer<U> extends Closeable implements Messa
}
abstract void sendCancel() throws AMQException, FailoverException;
-
- abstract void cleanupQueue() throws AMQException, FailoverException;
/**
* Called when you need to invalidate a consumer. Used for example when failover has occurred and the client has
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 964c238946..b5f3501e5a 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
@@ -19,11 +19,8 @@ package org.apache.qpid.client;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.apache.qpid.client.AMQDestination.AddressOption;
import org.apache.qpid.client.AMQDestination.DestSyntax;
-import org.apache.qpid.client.failover.FailoverException;
import org.apache.qpid.client.message.*;
-import org.apache.qpid.client.messaging.address.Node.QueueNode;
import org.apache.qpid.client.protocol.AMQProtocolHandler;
import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.framing.FieldTable;
@@ -512,18 +509,4 @@ public class BasicMessageConsumer_0_10 extends BasicMessageConsumer<UnprocessedM
return _exclusive;
}
}
-
- void cleanupQueue() throws AMQException, FailoverException
- {
- AMQDestination dest = this.getDestination();
- if (dest != null && dest.getDestSyntax() == AMQDestination.DestSyntax.ADDR)
- {
- if (dest.getDelete() == AddressOption.ALWAYS ||
- dest.getDelete() == AddressOption.RECEIVER )
- {
- ((AMQSession_0_10) getSession()).getQpidSession().queueDelete(
- this.getDestination().getQueueName());
- }
- }
- }
}
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 00acd5e866..cdbf57769d 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
@@ -88,8 +88,4 @@ public class BasicMessageConsumer_0_8 extends BasicMessageConsumer<UnprocessedMe
return receive();
}
- void cleanupQueue() throws AMQException, FailoverException
- {
-
- }
}
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 5821fee7ff..53c0457120 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
@@ -19,7 +19,6 @@ package org.apache.qpid.client;
import static org.apache.qpid.transport.Option.NONE;
import static org.apache.qpid.transport.Option.SYNC;
-import static org.apache.qpid.transport.Option.UNRELIABLE;
import java.nio.ByteBuffer;
import java.util.HashMap;
@@ -31,13 +30,9 @@ import javax.jms.JMSException;
import javax.jms.Message;
import org.apache.qpid.AMQException;
-import org.apache.qpid.client.AMQDestination.AddressOption;
import org.apache.qpid.client.AMQDestination.DestSyntax;
import org.apache.qpid.client.message.AMQMessageDelegate_0_10;
import org.apache.qpid.client.message.AbstractJMSMessage;
-import org.apache.qpid.client.message.QpidMessageProperties;
-import org.apache.qpid.client.messaging.address.Link.Reliability;
-import org.apache.qpid.client.messaging.address.Node.QueueNode;
import org.apache.qpid.client.protocol.AMQProtocolHandler;
import org.apache.qpid.transport.DeliveryProperties;
import org.apache.qpid.transport.Header;
@@ -73,15 +68,12 @@ public class BasicMessageProducer_0_10 extends BasicMessageProducer
{
if (destination.getDestSyntax() == DestSyntax.BURL)
{
- if (getSession().isDeclareExchanges())
- {
- String name = destination.getExchangeName().toString();
- ((AMQSession_0_10) getSession()).getQpidSession().exchangeDeclare
- (name,
- destination.getExchangeClass().toString(),
- null, null,
- name.startsWith("amq.") ? Option.PASSIVE : Option.NONE);
- }
+ String name = destination.getExchangeName().toString();
+ ((AMQSession_0_10) getSession()).getQpidSession().exchangeDeclare
+ (name,
+ destination.getExchangeClass().toString(),
+ null, null,
+ name.startsWith("amq.") ? Option.PASSIVE : Option.NONE);
}
else
{
@@ -179,7 +171,7 @@ public class BasicMessageProducer_0_10 extends BasicMessageProducer
if (destination.getDestSyntax() == AMQDestination.DestSyntax.ADDR &&
(destination.getSubject() != null ||
- (messageProps.getApplicationHeaders() != null && messageProps.getApplicationHeaders().get(QpidMessageProperties.QPID_SUBJECT) != null))
+ (messageProps.getApplicationHeaders() != null && messageProps.getApplicationHeaders().get("qpid.subject") != null))
)
{
Map<String,Object> appProps = messageProps.getApplicationHeaders();
@@ -189,16 +181,16 @@ public class BasicMessageProducer_0_10 extends BasicMessageProducer
messageProps.setApplicationHeaders(appProps);
}
- if (appProps.get(QpidMessageProperties.QPID_SUBJECT) == null)
+ if (appProps.get("qpid.subject") == null)
{
// use default subject in address string
- appProps.put(QpidMessageProperties.QPID_SUBJECT,destination.getSubject());
+ appProps.put("qpid.subject",destination.getSubject());
}
- if (destination.getAddressType() == AMQDestination.TOPIC_TYPE)
+ if (destination.getTargetNode().getType() == AMQDestination.TOPIC_TYPE)
{
deliveryProp.setRoutingKey((String)
- messageProps.getApplicationHeaders().get(QpidMessageProperties.QPID_SUBJECT));
+ messageProps.getApplicationHeaders().get("qpid.subject"));
}
}
@@ -218,9 +210,6 @@ public class BasicMessageProducer_0_10 extends BasicMessageProducer
deliveryMode == DeliveryMode.PERSISTENT)
);
- boolean unreliable = (destination.getDestSyntax() == DestSyntax.ADDR) &&
- (destination.getLink().getReliability() == Reliability.UNRELIABLE);
-
org.apache.mina.common.ByteBuffer data = message.getData();
ByteBuffer buffer = data == null ? ByteBuffer.allocate(0) : data.buf().slice();
@@ -228,7 +217,7 @@ public class BasicMessageProducer_0_10 extends BasicMessageProducer
MessageAcceptMode.NONE,
MessageAcquireMode.PRE_ACQUIRED,
new Header(deliveryProp, messageProps),
- buffer, sync ? SYNC : NONE, unreliable ? UNRELIABLE : NONE);
+ buffer, sync ? SYNC : NONE);
if (sync)
{
ssn.sync();
@@ -250,21 +239,5 @@ public class BasicMessageProducer_0_10 extends BasicMessageProducer
{
return _session.isQueueBound(destination);
}
-
- @Override
- public void close()
- {
- super.close();
- AMQDestination dest = _destination;
- if (dest != null && dest.getDestSyntax() == AMQDestination.DestSyntax.ADDR)
- {
- if (dest.getDelete() == AddressOption.ALWAYS ||
- dest.getDelete() == AddressOption.SENDER )
- {
- ((AMQSession_0_10) getSession()).getQpidSession().queueDelete(
- _destination.getQueueName());
- }
- }
- }
}
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/ChannelToSessionMap.java b/qpid/java/client/src/main/java/org/apache/qpid/client/ChannelToSessionMap.java
index 2fdb35de49..2b7e3d44da 100644
--- a/qpid/java/client/src/main/java/org/apache/qpid/client/ChannelToSessionMap.java
+++ b/qpid/java/client/src/main/java/org/apache/qpid/client/ChannelToSessionMap.java
@@ -1,23 +1,3 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
- */
package org.apache.qpid.client;
import java.util.ArrayList;
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/CustomJMSXProperty.java b/qpid/java/client/src/main/java/org/apache/qpid/client/CustomJMSXProperty.java
index e81e754da2..7cc548915c 100644
--- a/qpid/java/client/src/main/java/org/apache/qpid/client/CustomJMSXProperty.java
+++ b/qpid/java/client/src/main/java/org/apache/qpid/client/CustomJMSXProperty.java
@@ -23,7 +23,6 @@ package org.apache.qpid.client;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
-import java.util.List;
import org.apache.qpid.framing.AMQShortString;
@@ -35,18 +34,6 @@ public enum CustomJMSXProperty
JMSXGroupSeq,
JMSXUserID;
- private static List<String> _names;
-
- static
- {
- CustomJMSXProperty[] properties = values();
- _names = new ArrayList<String>(properties.length);
- for(CustomJMSXProperty property : properties)
- {
- _names.add(property.toString());
- }
-
- }
private final AMQShortString _nameAsShortString;
@@ -60,8 +47,20 @@ public enum CustomJMSXProperty
return _nameAsShortString;
}
- public static Enumeration asEnumeration()
+ private static Enumeration _names;
+
+ public static synchronized Enumeration asEnumeration()
{
- return Collections.enumeration(_names);
+ if(_names == null)
+ {
+ CustomJMSXProperty[] properties = values();
+ ArrayList<String> nameList = new ArrayList<String>(properties.length);
+ for(CustomJMSXProperty property : properties)
+ {
+ nameList.add(property.toString());
+ }
+ _names = Collections.enumeration(nameList);
+ }
+ return _names;
}
}
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/QpidConnectionMetaData.java b/qpid/java/client/src/main/java/org/apache/qpid/client/QpidConnectionMetaData.java
index 5cf767ac35..3bb5707417 100644
--- a/qpid/java/client/src/main/java/org/apache/qpid/client/QpidConnectionMetaData.java
+++ b/qpid/java/client/src/main/java/org/apache/qpid/client/QpidConnectionMetaData.java
@@ -30,11 +30,9 @@ import org.apache.qpid.common.QpidProperties;
public class QpidConnectionMetaData implements ConnectionMetaData
{
- private AMQConnection con;
QpidConnectionMetaData(AMQConnection conn)
{
- this.con = conn;
}
public int getJMSMajorVersion() throws JMSException
@@ -64,12 +62,12 @@ public class QpidConnectionMetaData implements ConnectionMetaData
public int getProviderMajorVersion() throws JMSException
{
- return con.getProtocolVersion().getMajorVersion();
+ return 0;
}
public int getProviderMinorVersion() throws JMSException
{
- return con.getProtocolVersion().getMinorVersion();
+ return 8;
}
public String getProviderVersion() throws JMSException
@@ -80,7 +78,8 @@ public class QpidConnectionMetaData implements ConnectionMetaData
private String getProtocolVersion()
{
- return con.getProtocolVersion().toString();
+ // TODO - Implement based on connection negotiated protocol
+ return "0.8";
}
public String getBrokerVersion()
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/QueueSenderAdapter.java b/qpid/java/client/src/main/java/org/apache/qpid/client/QueueSenderAdapter.java
index 295c6a4091..27783bcacf 100644
--- a/qpid/java/client/src/main/java/org/apache/qpid/client/QueueSenderAdapter.java
+++ b/qpid/java/client/src/main/java/org/apache/qpid/client/QueueSenderAdapter.java
@@ -50,25 +50,25 @@ public class QueueSenderAdapter implements QueueSender
public void send(Message msg) throws JMSException
{
- checkQueuePreConditions(_queue);
+ checkPreConditions();
_delegate.send(msg);
}
public void send(Queue queue, Message msg) throws JMSException
{
- checkQueuePreConditions(queue);
+ checkPreConditions(queue);
_delegate.send(queue, msg);
}
public void publish(Message msg, int deliveryMode, int priority, long timeToLive) throws JMSException
{
- checkQueuePreConditions(_queue);
+ checkPreConditions();
_delegate.send(msg, deliveryMode, priority, timeToLive);
}
public void send(Queue queue, Message msg, int deliveryMode, int priority, long timeToLive) throws JMSException
{
- checkQueuePreConditions(queue);
+ checkPreConditions(queue);
_delegate.send(queue, msg, deliveryMode, priority, timeToLive);
}
@@ -122,19 +122,19 @@ public class QueueSenderAdapter implements QueueSender
public void send(Destination dest, Message msg) throws JMSException
{
- checkQueuePreConditions((Queue) dest);
+ checkPreConditions((Queue) dest);
_delegate.send(dest, msg);
}
public void send(Message msg, int deliveryMode, int priority, long timeToLive) throws JMSException
{
- checkQueuePreConditions(_queue);
+ checkPreConditions();
_delegate.send(msg, deliveryMode, priority, timeToLive);
}
public void send(Destination dest, Message msg, int deliveryMode, int priority, long timeToLive) throws JMSException
{
- checkQueuePreConditions((Queue) dest);
+ checkPreConditions((Queue) dest);
_delegate.send(dest, msg, deliveryMode, priority, timeToLive);
}
@@ -170,6 +170,11 @@ public class QueueSenderAdapter implements QueueSender
private void checkPreConditions() throws JMSException
{
+ checkPreConditions(_queue);
+ }
+
+ private void checkPreConditions(Queue queue) throws JMSException
+ {
if (closed)
{
throw new javax.jms.IllegalStateException("Publisher is closed");
@@ -181,43 +186,39 @@ public class QueueSenderAdapter implements QueueSender
{
throw new javax.jms.IllegalStateException("Invalid Session");
}
- }
- private void checkQueuePreConditions(Queue queue) throws JMSException
- {
- checkPreConditions() ;
-
- if (queue == null)
- {
- throw new UnsupportedOperationException("Queue is null.");
- }
-
- if (!(queue instanceof AMQDestination))
- {
- throw new InvalidDestinationException("Queue: " + queue + " is not a valid Qpid queue");
- }
-
- AMQDestination destination = (AMQDestination) queue;
- if (!destination.isCheckedForQueueBinding() && checkQueueBeforePublish())
- {
- if (_delegate.getSession().isStrictAMQP())
- {
- _delegate._logger.warn("AMQP does not support destination validation before publish, ");
- destination.setCheckedForQueueBinding(true);
- }
- else
- {
- if (_delegate.isBound(destination))
- {
- destination.setCheckedForQueueBinding(true);
- }
- else
- {
- throw new InvalidDestinationException("Queue: " + queue
- + " is not a valid destination (no bindings on server");
- }
- }
- }
+ if (queue == null)
+ {
+ throw new UnsupportedOperationException("Queue is null.");
+ }
+
+ if (!(queue instanceof AMQDestination))
+ {
+ throw new InvalidDestinationException("Queue: " + queue + " is not a valid Qpid queue");
+ }
+
+ AMQDestination destination = (AMQDestination) queue;
+ if (!destination.isCheckedForQueueBinding() && checkQueueBeforePublish())
+ {
+
+ if (_delegate.getSession().isStrictAMQP())
+ {
+ _delegate._logger.warn("AMQP does not support destination validation before publish, ");
+ destination.setCheckedForQueueBinding(true);
+ }
+ else
+ {
+ if (_delegate.isBound(destination))
+ {
+ destination.setCheckedForQueueBinding(true);
+ }
+ else
+ {
+ throw new InvalidDestinationException("Queue: " + queue
+ + " is not a valid destination (no bindings on server");
+ }
+ }
+ }
}
private boolean checkQueueBeforePublish()
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/XAResourceImpl.java b/qpid/java/client/src/main/java/org/apache/qpid/client/XAResourceImpl.java
index 5b94b342eb..8a75082202 100644
--- a/qpid/java/client/src/main/java/org/apache/qpid/client/XAResourceImpl.java
+++ b/qpid/java/client/src/main/java/org/apache/qpid/client/XAResourceImpl.java
@@ -21,14 +21,10 @@ import javax.transaction.xa.XAException;
import javax.transaction.xa.XAResource;
import javax.transaction.xa.Xid;
+import org.apache.qpid.AMQInvalidArgumentException;
import org.apache.qpid.dtx.XidImpl;
-import org.apache.qpid.transport.DtxXaStatus;
-import org.apache.qpid.transport.ExecutionErrorCode;
-import org.apache.qpid.transport.Future;
-import org.apache.qpid.transport.Option;
-import org.apache.qpid.transport.RecoverResult;
-import org.apache.qpid.transport.SessionException;
-import org.apache.qpid.transport.XaResult;
+import org.apache.qpid.transport.*;
+
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -215,28 +211,9 @@ public class XAResourceImpl implements XAResource
* @throws XAException An error has occurred. Possible exception values are XAER_RMERR, XAER_RMFAIL.
*/
public boolean isSameRM(XAResource xaResource) throws XAException
- {
- if(this == xaResource)
- {
- return true;
- }
- if(!(xaResource instanceof XAResourceImpl))
- {
- return false;
- }
-
- XAResourceImpl other = (XAResourceImpl)xaResource;
-
- String myUUID = ((AMQSession_0_10)_xaSession).getAMQConnection().getBrokerUUID();
- String otherUUID = ((AMQSession_0_10)other._xaSession).getAMQConnection().getBrokerUUID();
-
- if(_logger.isDebugEnabled())
- {
- _logger.debug("Comparing my UUID " + myUUID + " with other UUID " + otherUUID);
- }
-
- return (myUUID != null && otherUUID != null && myUUID.equals(otherUUID));
-
+ {
+ // TODO : get the server identity of xaResource and compare it with our own one
+ return false;
}
/**
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/XASessionImpl.java b/qpid/java/client/src/main/java/org/apache/qpid/client/XASessionImpl.java
index 6b9121811d..354b67cd35 100644
--- a/qpid/java/client/src/main/java/org/apache/qpid/client/XASessionImpl.java
+++ b/qpid/java/client/src/main/java/org/apache/qpid/client/XASessionImpl.java
@@ -52,7 +52,7 @@ public class XASessionImpl extends AMQSession_0_10 implements XASession, XATopic
{
super(qpidConnection, con, channelId, false, // this is not a transacted session
Session.AUTO_ACKNOWLEDGE, // the ack mode is transacted
- MessageFactoryRegistry.newDefaultRegistry(), defaultPrefetchHigh, defaultPrefetchLow,null);
+ MessageFactoryRegistry.newDefaultRegistry(), defaultPrefetchHigh, defaultPrefetchLow);
createSession();
_xaResource = new XAResourceImpl(this);
}
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/handler/ConnectionStartMethodHandler.java b/qpid/java/client/src/main/java/org/apache/qpid/client/handler/ConnectionStartMethodHandler.java
index 2b49bb8f81..c81ad6422f 100644
--- a/qpid/java/client/src/main/java/org/apache/qpid/client/handler/ConnectionStartMethodHandler.java
+++ b/qpid/java/client/src/main/java/org/apache/qpid/client/handler/ConnectionStartMethodHandler.java
@@ -226,7 +226,7 @@ public class ConnectionStartMethodHandler implements StateAwareMethodListener<Co
{
Object instance = mechanismClass.newInstance();
AMQCallbackHandler cbh = (AMQCallbackHandler) instance;
- cbh.initialise(protocolSession.getAMQConnection().getConnectionURL());
+ cbh.initialise(protocolSession);
return cbh;
}
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/message/AMQMessageDelegate_0_10.java b/qpid/java/client/src/main/java/org/apache/qpid/client/message/AMQMessageDelegate_0_10.java
index 182b7b65d8..92e61984d2 100644
--- a/qpid/java/client/src/main/java/org/apache/qpid/client/message/AMQMessageDelegate_0_10.java
+++ b/qpid/java/client/src/main/java/org/apache/qpid/client/message/AMQMessageDelegate_0_10.java
@@ -22,12 +22,10 @@
package org.apache.qpid.client.message;
import java.lang.ref.SoftReference;
-import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
-import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
@@ -634,16 +632,6 @@ public class AMQMessageDelegate_0_10 extends AbstractAMQMessageDelegate
{
return new String(_messageProps.getUserId());
}
- else if (QpidMessageProperties.AMQP_0_10_APP_ID.equals(propertyName) &&
- _messageProps.getAppId() != null)
- {
- return new String(_messageProps.getAppId());
- }
- else if (QpidMessageProperties.AMQP_0_10_ROUTING_KEY.equals(propertyName) &&
- _deliveryProps.getRoutingKey() != null)
- {
- return _deliveryProps.getRoutingKey();
- }
else
{
checkPropertyName(propertyName);
@@ -682,19 +670,7 @@ public class AMQMessageDelegate_0_10 extends AbstractAMQMessageDelegate
public Enumeration getPropertyNames() throws JMSException
{
- List<String> props = new ArrayList<String>();
- Map<String, Object> propertyMap = getApplicationHeaders();
- for (String prop: getApplicationHeaders().keySet())
- {
- Object value = propertyMap.get(prop);
- if (value instanceof Boolean || value instanceof Number
- || value instanceof String)
- {
- props.add(prop);
- }
- }
-
- return java.util.Collections.enumeration(props);
+ return java.util.Collections.enumeration(getApplicationHeaders().keySet());
}
public void setBooleanProperty(String propertyName, boolean b) throws JMSException
@@ -750,14 +726,7 @@ public class AMQMessageDelegate_0_10 extends AbstractAMQMessageDelegate
{
checkPropertyName(propertyName);
checkWritableProperties();
- if (QpidMessageProperties.AMQP_0_10_APP_ID.equals(propertyName))
- {
- _messageProps.setAppId(value.getBytes());
- }
- else
- {
- setApplicationHeader(propertyName, value);
- }
+ setApplicationHeader(propertyName, value);
}
private static final Set<Class> ALLOWED = new HashSet();
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/message/AMQPEncodedMapMessage.java b/qpid/java/client/src/main/java/org/apache/qpid/client/message/AMQPEncodedMapMessage.java
index 7f735e0722..6e22292ee0 100644
--- a/qpid/java/client/src/main/java/org/apache/qpid/client/message/AMQPEncodedMapMessage.java
+++ b/qpid/java/client/src/main/java/org/apache/qpid/client/message/AMQPEncodedMapMessage.java
@@ -23,7 +23,6 @@ package org.apache.qpid.client.message;
import java.util.List;
import java.util.Map;
-import java.util.UUID;
import javax.jms.JMSException;
import javax.jms.MessageFormatException;
@@ -66,7 +65,7 @@ public class AMQPEncodedMapMessage extends JMSMapMessage
if ((value instanceof Boolean) || (value instanceof Byte) || (value instanceof Short) || (value instanceof Integer)
|| (value instanceof Long) || (value instanceof Character) || (value instanceof Float)
|| (value instanceof Double) || (value instanceof String) || (value instanceof byte[])
- || (value instanceof List) || (value instanceof Map) || (value instanceof UUID) || (value == null))
+ || (value instanceof List) || (value instanceof Map) || (value == null))
{
_map.put(propName, value);
}
@@ -110,7 +109,7 @@ public class AMQPEncodedMapMessage extends JMSMapMessage
}
// for testing
- public Map<String,Object> getMap()
+ Map<String,Object> getMap()
{
return _map;
}
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/message/AbstractJMSMessageFactory.java b/qpid/java/client/src/main/java/org/apache/qpid/client/message/AbstractJMSMessageFactory.java
index 40c1df0c5d..e719c9a4b2 100644
--- a/qpid/java/client/src/main/java/org/apache/qpid/client/message/AbstractJMSMessageFactory.java
+++ b/qpid/java/client/src/main/java/org/apache/qpid/client/message/AbstractJMSMessageFactory.java
@@ -99,7 +99,7 @@ public abstract class AbstractJMSMessageFactory implements MessageFactory
}
AMQMessageDelegate delegate = new AMQMessageDelegate_0_8(messageNbr,
- (BasicContentHeaderProperties) contentHeader.getProperties(),
+ (BasicContentHeaderProperties) contentHeader.properties,
exchange, routingKey);
return createMessage(delegate, data);
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 cdb75fc9a9..4e4061cf4d 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
@@ -104,7 +104,7 @@ public class MessageFactoryRegistry
AMQShortString routingKey, ContentHeaderBody contentHeader, List bodies)
throws AMQException, JMSException
{
- BasicContentHeaderProperties properties = (BasicContentHeaderProperties) contentHeader.getProperties();
+ BasicContentHeaderProperties properties = (BasicContentHeaderProperties) contentHeader.properties;
// Get the message content type. This may be null for pure AMQP messages, but will always be set for JMS over
// AMQP. When the type is null, it can only be assumed that the message is a byte message.
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/message/QpidMessageProperties.java b/qpid/java/client/src/main/java/org/apache/qpid/client/message/QpidMessageProperties.java
deleted file mode 100644
index b30afafa35..0000000000
--- a/qpid/java/client/src/main/java/org/apache/qpid/client/message/QpidMessageProperties.java
+++ /dev/null
@@ -1,34 +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.client.message;
-
-/**
- * Place holder for Qpid specific message properties
- */
-public class QpidMessageProperties
-{
-
- public static final String QPID_SUBJECT = "qpid.subject";
-
- // AMQP 0-10 related properties
- public static final String AMQP_0_10_APP_ID = "x-amqp-0-10.app-id";
- public static final String AMQP_0_10_ROUTING_KEY = "x-amqp-0-10.routing-key";
-}
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/messaging/address/AddressHelper.java b/qpid/java/client/src/main/java/org/apache/qpid/client/messaging/address/AddressHelper.java
index 368ec60525..00503cc650 100644
--- a/qpid/java/client/src/main/java/org/apache/qpid/client/messaging/address/AddressHelper.java
+++ b/qpid/java/client/src/main/java/org/apache/qpid/client/messaging/address/AddressHelper.java
@@ -27,7 +27,6 @@ import java.util.Map;
import org.apache.qpid.client.AMQDestination;
import org.apache.qpid.client.AMQDestination.Binding;
-import org.apache.qpid.client.messaging.address.Link.Reliability;
import org.apache.qpid.client.messaging.address.Link.Subscription;
import org.apache.qpid.client.messaging.address.Node.ExchangeNode;
import org.apache.qpid.client.messaging.address.Node.QueueNode;
@@ -55,7 +54,7 @@ public class AddressHelper
public static final String EXCLUSIVE = "exclusive";
public static final String AUTO_DELETE = "auto-delete";
public static final String TYPE = "type";
- public static final String ALT_EXCHANGE = "alternate-exchange";
+ public static final String ALT_EXCHANGE = "alt-exchange";
public static final String BINDINGS = "bindings";
public static final String BROWSE = "browse";
public static final String MODE = "mode";
@@ -232,9 +231,14 @@ public class AddressHelper
private boolean getDurability(Map map)
{
- Accessor access = new MapAccessor(map);
- Boolean result = access.getBoolean(DURABLE);
- return (result == null) ? false : result.booleanValue();
+ if (map != null && map.get(DURABLE) != null)
+ {
+ return Boolean.parseBoolean((String)map.get(DURABLE));
+ }
+ else
+ {
+ return false;
+ }
}
/**
@@ -258,7 +262,7 @@ public class AddressHelper
}
}
- public Link getLink() throws Exception
+ public Link getLink()
{
Link link = new Link();
link.setSubscription(new Subscription());
@@ -268,25 +272,6 @@ public class AddressHelper
: linkProps.getBoolean(DURABLE));
link.setName(linkProps.getString(NAME));
- String reliability = linkProps.getString(RELIABILITY);
- if ( reliability != null)
- {
- if (reliability.equalsIgnoreCase("unreliable"))
- {
- link.setReliability(Reliability.UNRELIABLE);
- }
- else if (reliability.equalsIgnoreCase("at-least-once"))
- {
- link.setReliability(Reliability.AT_LEAST_ONCE);
- }
- else
- {
- throw new Exception("The reliability mode '" +
- reliability + "' is not yet supported");
- }
-
- }
-
if (((Map) address.getOptions().get(LINK)).get(CAPACITY) instanceof Map)
{
MapAccessor capacityProps = new MapAccessor(
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/messaging/address/Link.java b/qpid/java/client/src/main/java/org/apache/qpid/client/messaging/address/Link.java
index 5f97d625b4..a7d19d1bd5 100644
--- a/qpid/java/client/src/main/java/org/apache/qpid/client/messaging/address/Link.java
+++ b/qpid/java/client/src/main/java/org/apache/qpid/client/messaging/address/Link.java
@@ -20,8 +20,6 @@
*/
package org.apache.qpid.client.messaging.address;
-import static org.apache.qpid.client.messaging.address.Link.Reliability.UNSPECIFIED;
-
import java.util.HashMap;
import java.util.Map;
@@ -31,8 +29,6 @@ public class Link
{
public enum FilterType { SQL92, XQUERY, SUBJECT }
- public enum Reliability { UNRELIABLE, AT_MOST_ONCE, AT_LEAST_ONCE, EXACTLY_ONCE, UNSPECIFIED }
-
protected String name;
protected String _filter;
protected FilterType _filterType = FilterType.SUBJECT;
@@ -42,18 +38,7 @@ public class Link
protected int _producerCapacity = 0;
protected Node node;
protected Subscription subscription;
- protected Reliability reliability = UNSPECIFIED;
- public Reliability getReliability()
- {
- return reliability;
- }
-
- public void setReliability(Reliability reliability)
- {
- this.reliability = reliability;
- }
-
public Node getNode()
{
return node;
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/protocol/AMQProtocolHandler.java b/qpid/java/client/src/main/java/org/apache/qpid/client/protocol/AMQProtocolHandler.java
index 34c6468629..eb5af119b2 100644
--- a/qpid/java/client/src/main/java/org/apache/qpid/client/protocol/AMQProtocolHandler.java
+++ b/qpid/java/client/src/main/java/org/apache/qpid/client/protocol/AMQProtocolHandler.java
@@ -57,6 +57,7 @@ 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.jms.BrokerDetails;
import org.apache.qpid.pool.Job;
import org.apache.qpid.pool.ReferenceCountingExecutorService;
import org.apache.qpid.protocol.AMQConstant;
@@ -64,9 +65,8 @@ import org.apache.qpid.protocol.AMQMethodEvent;
import org.apache.qpid.protocol.AMQMethodListener;
import org.apache.qpid.protocol.ProtocolEngine;
import org.apache.qpid.thread.Threading;
-import org.apache.qpid.transport.Sender;
-import org.apache.qpid.transport.network.NetworkConnection;
-import org.apache.qpid.transport.network.NetworkTransport;
+import org.apache.qpid.transport.NetworkDriver;
+import org.apache.qpid.transport.network.io.IoTransport;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -172,13 +172,11 @@ public class AMQProtocolHandler implements ProtocolEngine
private Job _readJob;
private Job _writeJob;
private ReferenceCountingExecutorService _poolReference = ReferenceCountingExecutorService.getInstance();
+ private NetworkDriver _networkDriver;
private ProtocolVersion _suggestedProtocolVersion;
private long _writtenBytes;
private long _readBytes;
- private NetworkTransport _transport;
- private NetworkConnection _network;
- private Sender<ByteBuffer> _sender;
/**
* Creates a new protocol handler, associated with the specified client connection instance.
@@ -213,6 +211,21 @@ public class AMQProtocolHandler implements ProtocolEngine
}
/**
+ * Called when we want to create a new IoTransport session
+ * @param brokerDetail
+ */
+ public void createIoTransportSession(BrokerDetails brokerDetail)
+ {
+ _protocolSession = new AMQProtocolSession(this, _connection);
+ _stateManager.setProtocolSession(_protocolSession);
+ IoTransport.connect_0_9(getProtocolSession(),
+ brokerDetail.getHost(),
+ brokerDetail.getPort(),
+ brokerDetail.getBooleanProperty(BrokerDetails.OPTIONS_SSL));
+ _protocolSession.init();
+ }
+
+ /**
* Called when the network connection is closed. This can happen, either because the client explicitly requested
* that the connection be closed, in which case nothing is done, or because the connection died. In the case
* where the connection died, an attempt to failover automatically to a new connection may be started. The failover
@@ -302,7 +315,7 @@ public class AMQProtocolHandler implements ProtocolEngine
// failover:
HeartbeatDiagnostics.timeout();
_logger.warn("Timed out while waiting for heartbeat from peer.");
- _network.close();
+ _networkDriver.close();
}
public void writerIdle()
@@ -324,7 +337,7 @@ public class AMQProtocolHandler implements ProtocolEngine
{
_logger.info("Exception caught therefore going to attempt failover: " + cause, cause);
// this will attempt failover
- _network.close();
+ _networkDriver.close();
closed();
}
else
@@ -576,7 +589,7 @@ public class AMQProtocolHandler implements ProtocolEngine
{
public void run()
{
- _sender.send(buf);
+ _networkDriver.send(buf);
}
});
if (PROTOCOL_DEBUG)
@@ -597,7 +610,7 @@ public class AMQProtocolHandler implements ProtocolEngine
if (wait)
{
- _sender.flush();
+ _networkDriver.flush();
}
}
@@ -711,7 +724,7 @@ public class AMQProtocolHandler implements ProtocolEngine
try
{
syncWrite(frame, ConnectionCloseOkBody.class, timeout);
- _network.close();
+ _networkDriver.close();
closed();
}
catch (AMQTimeoutException e)
@@ -831,18 +844,17 @@ public class AMQProtocolHandler implements ProtocolEngine
public SocketAddress getRemoteAddress()
{
- return _network.getRemoteAddress();
+ return _networkDriver.getRemoteAddress();
}
public SocketAddress getLocalAddress()
{
- return _network.getLocalAddress();
+ return _networkDriver.getLocalAddress();
}
- public void setNetworkConnection(NetworkConnection network)
+ public void setNetworkDriver(NetworkDriver driver)
{
- _network = network;
- _sender = network.getSender();
+ _networkDriver = driver;
}
/** @param delay delay in seconds (not ms) */
@@ -850,15 +862,15 @@ public class AMQProtocolHandler implements ProtocolEngine
{
if (delay > 0)
{
- _network.setMaxWriteIdle(delay);
- _network.setMaxReadIdle(HeartbeatConfig.CONFIG.getTimeout(delay));
+ getNetworkDriver().setMaxWriteIdle(delay);
+ getNetworkDriver().setMaxReadIdle(HeartbeatConfig.CONFIG.getTimeout(delay));
HeartbeatDiagnostics.init(delay, HeartbeatConfig.CONFIG.getTimeout(delay));
}
}
- public NetworkConnection getNetworkConnection()
+ public NetworkDriver getNetworkDriver()
{
- return _network;
+ return _networkDriver;
}
public ProtocolVersion getSuggestedProtocolVersion()
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/protocol/AMQProtocolSession.java b/qpid/java/client/src/main/java/org/apache/qpid/client/protocol/AMQProtocolSession.java
index 5b7d272506..7976760696 100644
--- a/qpid/java/client/src/main/java/org/apache/qpid/client/protocol/AMQProtocolSession.java
+++ b/qpid/java/client/src/main/java/org/apache/qpid/client/protocol/AMQProtocolSession.java
@@ -148,6 +148,16 @@ public class AMQProtocolSession implements AMQVersionAwareProtocolSession
return getAMQConnection().getVirtualHost();
}
+ public String getUsername()
+ {
+ return getAMQConnection().getUsername();
+ }
+
+ public String getPassword()
+ {
+ return getAMQConnection().getPassword();
+ }
+
public SaslClient getSaslClient()
{
return _saslClient;
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/security/AMQCallbackHandler.java b/qpid/java/client/src/main/java/org/apache/qpid/client/security/AMQCallbackHandler.java
index 67dd1a58b6..fbca444208 100644
--- a/qpid/java/client/src/main/java/org/apache/qpid/client/security/AMQCallbackHandler.java
+++ b/qpid/java/client/src/main/java/org/apache/qpid/client/security/AMQCallbackHandler.java
@@ -22,9 +22,9 @@ package org.apache.qpid.client.security;
import javax.security.auth.callback.CallbackHandler;
-import org.apache.qpid.jms.ConnectionURL;
+import org.apache.qpid.client.protocol.AMQProtocolSession;
public interface AMQCallbackHandler extends CallbackHandler
{
- void initialise(ConnectionURL connectionURL);
+ void initialise(AMQProtocolSession protocolSession);
}
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/security/DynamicSaslRegistrar.properties b/qpid/java/client/src/main/java/org/apache/qpid/client/security/DynamicSaslRegistrar.properties
index b903208927..1bff43142b 100644
--- a/qpid/java/client/src/main/java/org/apache/qpid/client/security/DynamicSaslRegistrar.properties
+++ b/qpid/java/client/src/main/java/org/apache/qpid/client/security/DynamicSaslRegistrar.properties
@@ -18,4 +18,3 @@
#
AMQPLAIN=org.apache.qpid.client.security.amqplain.AmqPlainSaslClientFactory
CRAM-MD5-HASHED=org.apache.qpid.client.security.crammd5hashed.CRAMMD5HashedSaslClientFactory
-ANONYMOUS=org.apache.qpid.client.security.anonymous.AnonymousSaslClientFactory
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/security/UsernameHashedPasswordCallbackHandler.java b/qpid/java/client/src/main/java/org/apache/qpid/client/security/UsernameHashedPasswordCallbackHandler.java
index 6ec83f0a23..66176dac3c 100644
--- a/qpid/java/client/src/main/java/org/apache/qpid/client/security/UsernameHashedPasswordCallbackHandler.java
+++ b/qpid/java/client/src/main/java/org/apache/qpid/client/security/UsernameHashedPasswordCallbackHandler.java
@@ -20,29 +20,30 @@
*/
package org.apache.qpid.client.security;
-import java.io.IOException;
-import java.io.UnsupportedEncodingException;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
+import org.apache.qpid.client.protocol.AMQProtocolSession;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.NameCallback;
import javax.security.auth.callback.PasswordCallback;
import javax.security.auth.callback.UnsupportedCallbackException;
-import org.apache.qpid.jms.ConnectionURL;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
public class UsernameHashedPasswordCallbackHandler implements AMQCallbackHandler
{
- private ConnectionURL _connectionURL;
+ private static final Logger _logger = LoggerFactory.getLogger(UsernameHashedPasswordCallbackHandler.class);
- /**
- * @see org.apache.qpid.client.security.AMQCallbackHandler#initialise(org.apache.qpid.jms.ConnectionURL)
- */
- @Override
- public void initialise(ConnectionURL connectionURL)
+ private AMQProtocolSession _protocolSession;
+
+ public void initialise(AMQProtocolSession protocolSession)
{
- _connectionURL = connectionURL;
+ _protocolSession = protocolSession;
}
public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException
@@ -52,13 +53,13 @@ public class UsernameHashedPasswordCallbackHandler implements AMQCallbackHandler
Callback cb = callbacks[i];
if (cb instanceof NameCallback)
{
- ((NameCallback) cb).setName(_connectionURL.getUsername());
+ ((NameCallback) cb).setName(_protocolSession.getUsername());
}
else if (cb instanceof PasswordCallback)
{
try
{
- ((PasswordCallback) cb).setPassword(getHash(_connectionURL.getPassword()));
+ ((PasswordCallback) cb).setPassword(getHash(_protocolSession.getPassword()));
}
catch (NoSuchAlgorithmException e)
{
@@ -98,5 +99,4 @@ public class UsernameHashedPasswordCallbackHandler implements AMQCallbackHandler
return hash;
}
-
}
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/security/UsernamePasswordCallbackHandler.java b/qpid/java/client/src/main/java/org/apache/qpid/client/security/UsernamePasswordCallbackHandler.java
index ad088722c8..c50c62710f 100644
--- a/qpid/java/client/src/main/java/org/apache/qpid/client/security/UsernamePasswordCallbackHandler.java
+++ b/qpid/java/client/src/main/java/org/apache/qpid/client/security/UsernamePasswordCallbackHandler.java
@@ -27,19 +27,15 @@ import javax.security.auth.callback.NameCallback;
import javax.security.auth.callback.PasswordCallback;
import javax.security.auth.callback.UnsupportedCallbackException;
-import org.apache.qpid.jms.ConnectionURL;
+import org.apache.qpid.client.protocol.AMQProtocolSession;
public class UsernamePasswordCallbackHandler implements AMQCallbackHandler
{
- private ConnectionURL _connectionURL;
+ private AMQProtocolSession _protocolSession;
- /**
- * @see org.apache.qpid.client.security.AMQCallbackHandler#initialise(org.apache.qpid.jms.ConnectionURL)
- */
- @Override
- public void initialise(final ConnectionURL connectionURL)
+ public void initialise(AMQProtocolSession protocolSession)
{
- _connectionURL = connectionURL;
+ _protocolSession = protocolSession;
}
public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException
@@ -49,11 +45,11 @@ public class UsernamePasswordCallbackHandler implements AMQCallbackHandler
Callback cb = callbacks[i];
if (cb instanceof NameCallback)
{
- ((NameCallback)cb).setName(_connectionURL.getUsername());
+ ((NameCallback)cb).setName(_protocolSession.getUsername());
}
else if (cb instanceof PasswordCallback)
{
- ((PasswordCallback)cb).setPassword(_connectionURL.getPassword().toCharArray());
+ ((PasswordCallback)cb).setPassword(_protocolSession.getPassword().toCharArray());
}
else
{
@@ -61,5 +57,4 @@ public class UsernamePasswordCallbackHandler implements AMQCallbackHandler
}
}
}
-
}
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/security/anonymous/AnonymousSaslClient.java b/qpid/java/client/src/main/java/org/apache/qpid/client/security/anonymous/AnonymousSaslClient.java
deleted file mode 100644
index 0f56b2ef6c..0000000000
--- a/qpid/java/client/src/main/java/org/apache/qpid/client/security/anonymous/AnonymousSaslClient.java
+++ /dev/null
@@ -1,52 +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.client.security.anonymous;
-
-import javax.security.sasl.SaslClient;
-import javax.security.sasl.SaslException;
-
-public class AnonymousSaslClient implements SaslClient
-{
- public String getMechanismName() {
- return "ANONYMOUS";
- }
- public boolean hasInitialResponse() {
- return true;
- }
- public byte[] evaluateChallenge(byte[] challenge) throws SaslException {
- return new byte[0];
- }
- public boolean isComplete() {
- return true;
- }
- public byte[] unwrap(byte[] incoming, int offset, int len) throws SaslException
- {
- throw new IllegalStateException("No security layer supported");
- }
- public byte[] wrap(byte[] outgoing, int offset, int len) throws SaslException
- {
- throw new IllegalStateException("No security layer supported");
- }
- public Object getNegotiatedProperty(String propName) {
- return null;
- }
- public void dispose() throws SaslException {}
-}
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/security/anonymous/AnonymousSaslClientFactory.java b/qpid/java/client/src/main/java/org/apache/qpid/client/security/anonymous/AnonymousSaslClientFactory.java
deleted file mode 100644
index de698f87c6..0000000000
--- a/qpid/java/client/src/main/java/org/apache/qpid/client/security/anonymous/AnonymousSaslClientFactory.java
+++ /dev/null
@@ -1,52 +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.client.security.anonymous;
-
-import java.util.Arrays;
-import java.util.Map;
-
-import javax.security.sasl.Sasl;
-import javax.security.sasl.SaslClient;
-import javax.security.sasl.SaslClientFactory;
-import javax.security.sasl.SaslException;
-import javax.security.auth.callback.CallbackHandler;
-
-public class AnonymousSaslClientFactory implements SaslClientFactory
-{
- public SaslClient createSaslClient(String[] mechanisms, String authId,
- String protocol, String server,
- Map props, CallbackHandler cbh) throws SaslException
- {
- if (Arrays.asList(mechanisms).contains("ANONYMOUS")) {
- return new AnonymousSaslClient();
- } else {
- return null;
- }
- }
- public String[] getMechanismNames(Map props)
- {
- if (props == null || props.isEmpty()) {
- return new String[]{"ANONYMOUS"};
- } else {
- return new String[0];
- }
- }
-}
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/transport/SocketTransportConnection.java b/qpid/java/client/src/main/java/org/apache/qpid/client/transport/SocketTransportConnection.java
new file mode 100644
index 0000000000..1ac8f62e32
--- /dev/null
+++ b/qpid/java/client/src/main/java/org/apache/qpid/client/transport/SocketTransportConnection.java
@@ -0,0 +1,90 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.client.transport;
+
+import java.io.IOException;
+import java.net.InetSocketAddress;
+
+import org.apache.mina.common.ByteBuffer;
+import org.apache.mina.common.IoConnector;
+import org.apache.mina.common.SimpleByteBufferAllocator;
+import org.apache.qpid.client.SSLConfiguration;
+import org.apache.qpid.client.protocol.AMQProtocolHandler;
+import org.apache.qpid.jms.BrokerDetails;
+import org.apache.qpid.ssl.SSLContextFactory;
+import org.apache.qpid.transport.network.mina.MINANetworkDriver;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class SocketTransportConnection implements ITransportConnection
+{
+ private static final Logger _logger = LoggerFactory.getLogger(SocketTransportConnection.class);
+ private static final int DEFAULT_BUFFER_SIZE = 32 * 1024;
+
+ private SocketConnectorFactory _socketConnectorFactory;
+
+ static interface SocketConnectorFactory
+ {
+ IoConnector newSocketConnector();
+ }
+
+ public SocketTransportConnection(SocketConnectorFactory socketConnectorFactory)
+ {
+ _socketConnectorFactory = socketConnectorFactory;
+ }
+
+ public void connect(AMQProtocolHandler protocolHandler, BrokerDetails brokerDetail) throws IOException
+ {
+ ByteBuffer.setUseDirectBuffers(Boolean.getBoolean("amqj.enableDirectBuffers"));
+
+ // 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 (!Boolean.getBoolean("amqj.enablePooledAllocator"))
+ {
+ _logger.info("Using SimpleByteBufferAllocator");
+ ByteBuffer.setAllocator(new SimpleByteBufferAllocator());
+ }
+
+ final IoConnector ioConnector = _socketConnectorFactory.newSocketConnector();
+ final InetSocketAddress address;
+
+ if (brokerDetail.getTransport().equals(BrokerDetails.SOCKET))
+ {
+ address = null;
+ }
+ else
+ {
+ address = new InetSocketAddress(brokerDetail.getHost(), brokerDetail.getPort());
+ _logger.info("Attempting connection to " + address);
+ }
+
+ SSLConfiguration sslConfig = protocolHandler.getConnection().getSSLConfiguration();
+ SSLContextFactory sslFactory = null;
+ if (sslConfig != null)
+ {
+ sslFactory = new SSLContextFactory(sslConfig.getKeystorePath(), sslConfig.getKeystorePassword(), sslConfig.getCertType());
+ }
+
+ MINANetworkDriver driver = new MINANetworkDriver(ioConnector);
+ driver.open(brokerDetail.getPort(), address.getAddress(), protocolHandler, null, sslFactory);
+ protocolHandler.setNetworkDriver(driver);
+ }
+}
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/transport/TransportConnection.java b/qpid/java/client/src/main/java/org/apache/qpid/client/transport/TransportConnection.java
new file mode 100644
index 0000000000..aef3a563af
--- /dev/null
+++ b/qpid/java/client/src/main/java/org/apache/qpid/client/transport/TransportConnection.java
@@ -0,0 +1,351 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.client.transport;
+
+import java.io.IOException;
+import java.net.Socket;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.apache.mina.common.IoConnector;
+import org.apache.mina.common.IoHandlerAdapter;
+import org.apache.mina.common.IoServiceConfig;
+import org.apache.mina.transport.socket.nio.ExistingSocketConnector;
+import org.apache.mina.transport.socket.nio.MultiThreadSocketConnector;
+import org.apache.mina.transport.socket.nio.SocketConnector;
+import org.apache.mina.transport.vmpipe.VmPipeAcceptor;
+import org.apache.mina.transport.vmpipe.VmPipeAddress;
+import org.apache.qpid.client.vmbroker.AMQVMBrokerCreationException;
+import org.apache.qpid.jms.BrokerDetails;
+import org.apache.qpid.protocol.ProtocolEngineFactory;
+import org.apache.qpid.thread.QpidThreadExecutor;
+import org.apache.qpid.transport.network.mina.MINANetworkDriver;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * The TransportConnection is a helper class responsible for connecting to an AMQ server. It sets up the underlying
+ * connector, which currently always uses TCP/IP sockets. It creates the "protocol handler" which deals with MINA
+ * protocol events. <p/> Could be extended in future to support different transport types by turning this into concrete
+ * class/interface combo.
+ */
+public class TransportConnection
+{
+ private static ITransportConnection _instance;
+
+ private static final Map _inVmPipeAddress = new HashMap();
+ private static VmPipeAcceptor _acceptor;
+ private static int _currentInstance = -1;
+ private static int _currentVMPort = -1;
+
+ private static final int TCP = 0;
+ private static final int VM = 1;
+ private static final int SOCKET = 2;
+
+ private static Logger _logger = LoggerFactory.getLogger(TransportConnection.class);
+
+ private static final String DEFAULT_QPID_SERVER = "org.apache.qpid.server.protocol.AMQProtocolEngineFactory";
+
+ private static Map<String, Socket> _openSocketRegister = new ConcurrentHashMap<String, Socket>();
+
+ public static void registerOpenSocket(String socketID, Socket openSocket)
+ {
+ _openSocketRegister.put(socketID, openSocket);
+ }
+
+ public static Socket removeOpenSocket(String socketID)
+ {
+ return _openSocketRegister.remove(socketID);
+ }
+
+ public static synchronized ITransportConnection getInstance(final BrokerDetails details) throws AMQTransportConnectionException
+ {
+ int transport = getTransport(details.getTransport());
+
+ if (transport == -1)
+ {
+ throw new AMQNoTransportForProtocolException(details, null, null);
+ }
+
+ switch (transport)
+ {
+ case SOCKET:
+ return new SocketTransportConnection(new SocketTransportConnection.SocketConnectorFactory()
+ {
+ public IoConnector newSocketConnector()
+ {
+ ExistingSocketConnector connector = new ExistingSocketConnector(1,new QpidThreadExecutor());
+
+ Socket socket = TransportConnection.removeOpenSocket(details.getHost());
+
+ if (socket != null)
+ {
+ _logger.info("Using existing Socket:" + socket);
+
+ ((ExistingSocketConnector) connector).setOpenSocket(socket);
+ }
+ else
+ {
+ throw new IllegalArgumentException("Active Socket must be provided for broker " +
+ "with 'socket://<SocketID>' transport:" + details);
+ }
+ return connector;
+ }
+ });
+ case TCP:
+ return new SocketTransportConnection(new SocketTransportConnection.SocketConnectorFactory()
+ {
+ public IoConnector newSocketConnector()
+ {
+ SocketConnector result;
+ // FIXME - this needs to be sorted to use the new Mina MultiThread SA.
+ if (Boolean.getBoolean("qpidnio"))
+ {
+ _logger.warn("Using Qpid MultiThreaded NIO - " + (System.getProperties().containsKey("qpidnio")
+ ? "Qpid NIO is new default"
+ : "Sysproperty 'qpidnio' is set"));
+ result = new MultiThreadSocketConnector(1, new QpidThreadExecutor());
+ }
+ else
+ {
+ _logger.info("Using Mina NIO");
+ result = new SocketConnector(1, new QpidThreadExecutor()); // non-blocking connector
+ }
+ // Don't have the connector's worker thread wait around for other connections (we only use
+ // one SocketConnector per connection at the moment anyway). This allows short-running
+ // clients (like unit tests) to complete quickly.
+ result.setWorkerTimeout(0);
+ return result;
+ }
+ });
+ case VM:
+ {
+ return getVMTransport(details, Boolean.getBoolean("amqj.AutoCreateVMBroker"));
+ }
+ default:
+ throw new AMQNoTransportForProtocolException(details, "Transport not recognised:" + transport, null);
+ }
+ }
+
+ private static int getTransport(String transport)
+ {
+ if (transport.equals(BrokerDetails.SOCKET))
+ {
+ return SOCKET;
+ }
+
+ if (transport.equals(BrokerDetails.TCP))
+ {
+ return TCP;
+ }
+
+ if (transport.equals(BrokerDetails.VM))
+ {
+ return VM;
+ }
+
+ return -1;
+ }
+
+ private static ITransportConnection getVMTransport(BrokerDetails details, boolean AutoCreate)
+ throws AMQVMBrokerCreationException
+ {
+ int port = details.getPort();
+
+ synchronized (_inVmPipeAddress)
+ {
+ if (!_inVmPipeAddress.containsKey(port))
+ {
+ if (AutoCreate)
+ {
+ _logger.warn("Auto Creating InVM Broker on port:" + port);
+ createVMBroker(port);
+ }
+ else
+ {
+ throw new AMQVMBrokerCreationException(null, port, "VM Broker on port " + port
+ + " does not exist. Auto create disabled.", null);
+ }
+ }
+ }
+
+ return new VmPipeTransportConnection(port);
+ }
+
+ public static void createVMBroker(int port) throws AMQVMBrokerCreationException
+ {
+ synchronized(TransportConnection.class)
+ {
+ if (_acceptor == null)
+ {
+ _acceptor = new VmPipeAcceptor();
+
+ IoServiceConfig config = _acceptor.getDefaultConfig();
+ }
+ }
+ synchronized (_inVmPipeAddress)
+ {
+
+ if (!_inVmPipeAddress.containsKey(port))
+ {
+ _logger.info("Creating InVM Qpid.AMQP listening on port " + port);
+ IoHandlerAdapter provider = null;
+ try
+ {
+ VmPipeAddress pipe = new VmPipeAddress(port);
+
+ provider = createBrokerInstance(port);
+
+ _acceptor.bind(pipe, provider);
+
+ _inVmPipeAddress.put(port, pipe);
+ _logger.info("Created InVM Qpid.AMQP listening on port " + port);
+ }
+ catch (IOException e)
+ {
+ _logger.error("Got IOException.", e);
+
+ // Try and unbind provider
+ try
+ {
+ VmPipeAddress pipe = new VmPipeAddress(port);
+
+ try
+ {
+ _acceptor.unbind(pipe);
+ }
+ catch (Exception ignore)
+ {
+ // ignore
+ }
+
+ if (provider == null)
+ {
+ provider = createBrokerInstance(port);
+ }
+
+ _acceptor.bind(pipe, provider);
+ _inVmPipeAddress.put(port, pipe);
+ _logger.info("Created InVM Qpid.AMQP listening on port " + port);
+ }
+ catch (IOException justUseFirstException)
+ {
+ String because;
+ if (e.getCause() == null)
+ {
+ because = e.toString();
+ }
+ else
+ {
+ because = e.getCause().toString();
+ }
+
+ throw new AMQVMBrokerCreationException(null, port, because + " Stopped binding of InVM Qpid.AMQP", e);
+ }
+ }
+
+ }
+ else
+ {
+ _logger.info("InVM Qpid.AMQP on port " + port + " already exits.");
+ }
+ }
+ }
+
+ private static IoHandlerAdapter createBrokerInstance(int port) throws AMQVMBrokerCreationException
+ {
+ String protocolProviderClass = System.getProperty("amqj.protocolprovider.class", DEFAULT_QPID_SERVER);
+ _logger.info("Creating Qpid protocol provider: " + protocolProviderClass);
+
+ // can't use introspection to get Provider as it is a server class.
+ // need to go straight to IoHandlerAdapter but that requries the queues and exchange from the ApplicationRegistry which we can't access.
+
+ // get right constructor and pass in instancec ID - "port"
+ IoHandlerAdapter provider;
+ try
+ {
+ Class[] cnstr = {Integer.class};
+ Object[] params = {port};
+
+ provider = new MINANetworkDriver();
+ ProtocolEngineFactory engineFactory = (ProtocolEngineFactory) Class.forName(protocolProviderClass).getConstructor(cnstr).newInstance(params);
+ ((MINANetworkDriver) provider).setProtocolEngineFactory(engineFactory, true);
+ // Give the broker a second to create
+ _logger.info("Created VMBroker Instance:" + port);
+ }
+ catch (Exception e)
+ {
+ _logger.info("Unable to create InVM Qpid.AMQP on port " + port + ". Because: " + e.getCause());
+ String because;
+ if (e.getCause() == null)
+ {
+ because = e.toString();
+ }
+ else
+ {
+ because = e.getCause().toString();
+ }
+
+ AMQVMBrokerCreationException amqbce =
+ new AMQVMBrokerCreationException(null, port, because + " Stopped InVM Qpid.AMQP creation", e);
+ throw amqbce;
+ }
+
+ return provider;
+ }
+
+ public static void killAllVMBrokers()
+ {
+ _logger.info("Killing all VM Brokers");
+ synchronized(TransportConnection.class)
+ {
+ if (_acceptor != null)
+ {
+ _acceptor.unbindAll();
+ }
+ synchronized (_inVmPipeAddress)
+ {
+ _inVmPipeAddress.clear();
+ }
+ _acceptor = null;
+ }
+ _currentInstance = -1;
+ _currentVMPort = -1;
+ }
+
+ public static void killVMBroker(int port)
+ {
+ synchronized (_inVmPipeAddress)
+ {
+ VmPipeAddress pipe = (VmPipeAddress) _inVmPipeAddress.get(port);
+ if (pipe != null)
+ {
+ _logger.info("Killing VM Broker:" + port);
+ _inVmPipeAddress.remove(port);
+ // This does need to be sychronized as otherwise mina can hang
+ // if a new connection is made
+ _acceptor.unbind(pipe);
+ }
+ }
+ }
+
+}
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/transport/VmPipeTransportConnection.java b/qpid/java/client/src/main/java/org/apache/qpid/client/transport/VmPipeTransportConnection.java
new file mode 100644
index 0000000000..87cc2e7a5a
--- /dev/null
+++ b/qpid/java/client/src/main/java/org/apache/qpid/client/transport/VmPipeTransportConnection.java
@@ -0,0 +1,63 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.client.transport;
+
+import java.io.IOException;
+
+import org.apache.mina.common.ConnectFuture;
+import org.apache.mina.transport.vmpipe.QpidVmPipeConnector;
+import org.apache.mina.transport.vmpipe.VmPipeAddress;
+import org.apache.mina.transport.vmpipe.VmPipeConnector;
+import org.apache.qpid.client.protocol.AMQProtocolHandler;
+import org.apache.qpid.jms.BrokerDetails;
+import org.apache.qpid.transport.network.mina.MINANetworkDriver;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class VmPipeTransportConnection implements ITransportConnection
+{
+ private static final Logger _logger = LoggerFactory.getLogger(VmPipeTransportConnection.class);
+
+ private int _port;
+
+ private MINANetworkDriver _networkDriver;
+
+ public VmPipeTransportConnection(int port)
+ {
+ _port = port;
+ }
+
+ public void connect(AMQProtocolHandler protocolHandler, BrokerDetails brokerDetail) throws IOException
+ {
+ final VmPipeConnector ioConnector = new QpidVmPipeConnector();
+
+ final VmPipeAddress address = new VmPipeAddress(_port);
+ _logger.info("Attempting connection to " + address);
+ _networkDriver = new MINANetworkDriver(ioConnector, protocolHandler);
+ protocolHandler.setNetworkDriver(_networkDriver);
+ ConnectFuture future = ioConnector.connect(address, _networkDriver);
+ // wait for connection to complete
+ future.join();
+ // we call getSession which throws an IOException if there has been an error connecting
+ future.getSession();
+ _networkDriver.setProtocolEngine(protocolHandler);
+ }
+}
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 03167561ef..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
@@ -45,7 +45,7 @@ public class URLParser
private void parseURL(String fullURL) throws URLSyntaxException
{
// Connection URL format
- // amqp://[user:pass@][clientid]/virtualhost?brokerlist='tcp://host:port?option=\'value\',option=\'value\';tcp://host:port?option=\'value\'',failover='method?option=\'value\',option='value''"
+ // amqp://[user:pass@][clientid]/virtualhost?brokerlist='tcp://host:port?option=\'value\',option=\'value\';vm://:3/virtualpath?option=\'value\'',failover='method?option=\'value\',option='value''"
// Options are of course optional except for requiring a single broker in the broker list.
try
{
@@ -195,7 +195,7 @@ public class URLParser
{
String brokerlist = _url.getOptions().get(AMQConnectionURL.OPTIONS_BROKERLIST);
- // brokerlist tcp://host:port?option='value',option='value';tcp://host:port/virtualpath?option='value'
+ // brokerlist tcp://host:port?option='value',option='value';vm://:3/virtualpath?option='value'
StringTokenizer st = new StringTokenizer(brokerlist, "" + URLHelper.BROKER_SEPARATOR);
while (st.hasMoreTokens())
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/vmbroker/AMQVMBrokerCreationException.java b/qpid/java/client/src/main/java/org/apache/qpid/client/vmbroker/AMQVMBrokerCreationException.java
new file mode 100644
index 0000000000..dc0d9b8c78
--- /dev/null
+++ b/qpid/java/client/src/main/java/org/apache/qpid/client/vmbroker/AMQVMBrokerCreationException.java
@@ -0,0 +1,60 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.client.vmbroker;
+
+import org.apache.qpid.client.transport.AMQTransportConnectionException;
+import org.apache.qpid.protocol.AMQConstant;
+
+/**
+ * AMQVMBrokerCreationException represents failure to create an in VM broker on the vm transport medium.
+ *
+ * <p/><table id="crc"><caption>CRC Card</caption>
+ * <tr><th> Responsibilities <th> Collaborations
+ * <tr><td> Represent failure to create an in VM broker.
+ * </table>
+ *
+ * @todo Error code never used. This is not an AMQException.
+ */
+public class AMQVMBrokerCreationException extends AMQTransportConnectionException
+{
+ private int _port;
+
+ /**
+ * @param port
+ *
+ * @deprecated
+ */
+ public AMQVMBrokerCreationException(int port)
+ {
+ this(null, port, "Unable to create vm broker", null);
+ }
+
+ public AMQVMBrokerCreationException(AMQConstant errorCode, int port, String message, Throwable cause)
+ {
+ super(errorCode, message, cause);
+ _port = port;
+ }
+
+ public String toString()
+ {
+ return super.toString() + " on port " + _port;
+ }
+}
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/filter/PropertyExpression.java b/qpid/java/client/src/main/java/org/apache/qpid/filter/PropertyExpression.java
index 574a1b3888..b7b6bd57bc 100644
--- a/qpid/java/client/src/main/java/org/apache/qpid/filter/PropertyExpression.java
+++ b/qpid/java/client/src/main/java/org/apache/qpid/filter/PropertyExpression.java
@@ -19,7 +19,6 @@ package org.apache.qpid.filter;
import java.util.HashMap;
-import javax.jms.DeliveryMode;
import javax.jms.JMSException;
import org.apache.qpid.AMQInternalException;
@@ -33,7 +32,7 @@ import org.slf4j.LoggerFactory;
public class PropertyExpression implements Expression
{
// Constants - defined the same as JMS
- private static enum JMSDeliveryMode { NON_PERSISTENT, PERSISTENT }
+ private static final int NON_PERSISTENT = 1;
private static final int DEFAULT_PRIORITY = 4;
private static final Logger _logger = LoggerFactory.getLogger(PropertyExpression.class);
@@ -80,24 +79,22 @@ public class PropertyExpression implements Expression
{
public Object evaluate(AbstractJMSMessage message)
{
-
- JMSDeliveryMode mode = JMSDeliveryMode.NON_PERSISTENT;
try
{
- mode = message.getJMSDeliveryMode() == DeliveryMode.PERSISTENT ?
- JMSDeliveryMode.PERSISTENT : JMSDeliveryMode.NON_PERSISTENT;
-
+ int mode = message.getJMSDeliveryMode();
if (_logger.isDebugEnabled())
{
_logger.debug("JMSDeliveryMode is :" + mode);
}
+
+ return mode;
}
catch (JMSException e)
{
_logger.warn("Error evaluating property",e);
}
- return mode.toString();
+ return NON_PERSISTENT;
}
});
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/jms/BrokerDetails.java b/qpid/java/client/src/main/java/org/apache/qpid/jms/BrokerDetails.java
index 4db6a11e4d..6d81f728c9 100644
--- a/qpid/java/client/src/main/java/org/apache/qpid/jms/BrokerDetails.java
+++ b/qpid/java/client/src/main/java/org/apache/qpid/jms/BrokerDetails.java
@@ -52,7 +52,9 @@ public interface BrokerDetails
public static final int DEFAULT_PORT = 5672;
+ public static final String SOCKET = "socket";
public static final String TCP = "tcp";
+ public static final String VM = "vm";
public static final String DEFAULT_TRANSPORT = TCP;
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 26641982d7..0e8ca60686 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
@@ -27,7 +27,7 @@ import java.util.List;
/**
Connection URL format
- amqp://[user:pass@][clientid]/virtualhost?brokerlist='tcp://host:port?option=\'value\'&option=\'value\';tcp://host:port/virtualpath?option=\'value\''&failover='method?option=\'value\'&option='value''"
+ amqp://[user:pass@][clientid]/virtualhost?brokerlist='tcp://host:port?option=\'value\'&option=\'value\';vm://:3/virtualpath?option=\'value\''&failover='method?option=\'value\'&option='value''"
Options are of course optional except for requiring a single broker in the broker list.
The option seperator is defined to be either '&' or ','
*/
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/jms/FailoverPolicy.java b/qpid/java/client/src/main/java/org/apache/qpid/jms/FailoverPolicy.java
index 56abf03c81..7cdcd32306 100644
--- a/qpid/java/client/src/main/java/org/apache/qpid/jms/FailoverPolicy.java
+++ b/qpid/java/client/src/main/java/org/apache/qpid/jms/FailoverPolicy.java
@@ -20,6 +20,7 @@
*/
package org.apache.qpid.jms;
+import org.apache.qpid.client.AMQConnection;
import org.apache.qpid.jms.failover.FailoverExchangeMethod;
import org.apache.qpid.jms.failover.FailoverMethod;
import org.apache.qpid.jms.failover.FailoverRoundRobinServers;
@@ -50,7 +51,7 @@ public class FailoverPolicy
private long _lastMethodTime;
private long _lastFailTime;
- public FailoverPolicy(ConnectionURL connectionDetails, Connection conn)
+ public FailoverPolicy(ConnectionURL connectionDetails, AMQConnection conn)
{
FailoverMethod method;
@@ -82,7 +83,7 @@ public class FailoverPolicy
*/
if (failoverMethod.equals(FailoverMethod.SINGLE_BROKER))
{
- method = new FailoverSingleServer(connectionDetails);
+ method = new FailoverRoundRobinServers(connectionDetails);
}
else
{
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 ef30f2adbc..9e6000c472 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
@@ -32,9 +32,9 @@ import javax.jms.Session;
import org.apache.qpid.client.AMQAnyDestination;
import org.apache.qpid.client.AMQBrokerDetails;
+import org.apache.qpid.client.AMQConnection;
import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.jms.BrokerDetails;
-import org.apache.qpid.jms.Connection;
import org.apache.qpid.jms.ConnectionURL;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -58,7 +58,7 @@ public class FailoverExchangeMethod implements FailoverMethod, MessageListener
private static final Logger _logger = LoggerFactory.getLogger(FailoverExchangeMethod.class);
/** This is not safe to use until attainConnection is called */
- private Connection _conn;
+ private AMQConnection _conn;
/** Protects the broker list when modifications happens */
private Object _brokerListLock = new Object();
@@ -80,7 +80,7 @@ public class FailoverExchangeMethod implements FailoverMethod, MessageListener
/** Denotes the number of failed attempts **/
private int _failedAttemps = 0;
- public FailoverExchangeMethod(ConnectionURL connectionDetails, Connection conn)
+ public FailoverExchangeMethod(ConnectionURL connectionDetails, AMQConnection conn)
{
_connectionDetails = connectionDetails;
_originalBrokerDetail = _connectionDetails.getBrokerDetails(0);
diff --git a/qpid/java/client/src/test/java/org/apache/mina/transport/vmpipe/support/VmPipeIdleStatusChecker.java b/qpid/java/client/src/test/java/org/apache/mina/transport/vmpipe/support/VmPipeIdleStatusChecker.java
new file mode 100644
index 0000000000..5323ad28bf
--- /dev/null
+++ b/qpid/java/client/src/test/java/org/apache/mina/transport/vmpipe/support/VmPipeIdleStatusChecker.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.mina.transport.vmpipe.support;
+
+import org.apache.mina.common.IdleStatus;
+
+import java.util.HashMap;
+import java.util.IdentityHashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+/**
+ * This file is a patch to override MINA, because of the IdentityHashMap bug. Workaround to be supplied in MINA 1.0.7.
+ * This patched file will be removed once upgraded onto a newer MINA.
+ *
+ * Dectects idle sessions and fires <tt>sessionIdle</tt> events to them.
+ *
+ * @author The Apache Directory Project (mina-dev@directory.apache.org)
+ */
+public class VmPipeIdleStatusChecker
+{
+ private static final VmPipeIdleStatusChecker INSTANCE = new VmPipeIdleStatusChecker();
+
+ public static VmPipeIdleStatusChecker getInstance()
+ {
+ return INSTANCE;
+ }
+
+ private final Map sessions = new HashMap(); // will use as a set
+
+ private final Worker worker = new Worker();
+
+ private VmPipeIdleStatusChecker()
+ {
+ worker.start();
+ }
+
+ public void addSession(VmPipeSessionImpl session)
+ {
+ synchronized (sessions)
+ {
+ sessions.put(session, session);
+ }
+ }
+
+ private class Worker extends Thread
+ {
+ private Worker()
+ {
+ super("VmPipeIdleStatusChecker");
+ setDaemon(true);
+ }
+
+ public void run()
+ {
+ for (;;)
+ {
+ try
+ {
+ Thread.sleep(1000);
+ }
+ catch (InterruptedException e)
+ { }
+
+ long currentTime = System.currentTimeMillis();
+
+ synchronized (sessions)
+ {
+ Iterator it = sessions.keySet().iterator();
+ while (it.hasNext())
+ {
+ VmPipeSessionImpl session = (VmPipeSessionImpl) it.next();
+ if (!session.isConnected())
+ {
+ it.remove();
+ }
+ else
+ {
+ notifyIdleSession(session, currentTime);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ private void notifyIdleSession(VmPipeSessionImpl session, long currentTime)
+ {
+ notifyIdleSession0(session, currentTime, session.getIdleTimeInMillis(IdleStatus.BOTH_IDLE), IdleStatus.BOTH_IDLE,
+ Math.max(session.getLastIoTime(), session.getLastIdleTime(IdleStatus.BOTH_IDLE)));
+ notifyIdleSession0(session, currentTime, session.getIdleTimeInMillis(IdleStatus.READER_IDLE), IdleStatus.READER_IDLE,
+ Math.max(session.getLastReadTime(), session.getLastIdleTime(IdleStatus.READER_IDLE)));
+ notifyIdleSession0(session, currentTime, session.getIdleTimeInMillis(IdleStatus.WRITER_IDLE), IdleStatus.WRITER_IDLE,
+ Math.max(session.getLastWriteTime(), session.getLastIdleTime(IdleStatus.WRITER_IDLE)));
+ }
+
+ private void notifyIdleSession0(VmPipeSessionImpl session, long currentTime, long idleTime, IdleStatus status,
+ long lastIoTime)
+ {
+ if ((idleTime > 0) && (lastIoTime != 0) && ((currentTime - lastIoTime) >= idleTime))
+ {
+ session.increaseIdleCount(status);
+ session.getFilterChain().fireSessionIdle(session, status);
+ }
+ }
+
+}
diff --git a/qpid/java/client/src/test/java/org/apache/qpid/client/MockAMQConnection.java b/qpid/java/client/src/test/java/org/apache/qpid/client/MockAMQConnection.java
index 5972bf3fae..da44822ec3 100644
--- a/qpid/java/client/src/test/java/org/apache/qpid/client/MockAMQConnection.java
+++ b/qpid/java/client/src/test/java/org/apache/qpid/client/MockAMQConnection.java
@@ -79,6 +79,11 @@ public class MockAMQConnection extends AMQConnection
super(connectionURL, sslConfig);
}
+ protected MockAMQConnection(String username, String password, String clientName, String virtualHost)
+ {
+ super(username, password, clientName, virtualHost);
+ }
+
@Override
public ProtocolVersion makeBrokerConnection(BrokerDetails brokerDetail) throws IOException
{
diff --git a/qpid/java/client/src/test/java/org/apache/qpid/client/protocol/AMQProtocolHandlerTest.java b/qpid/java/client/src/test/java/org/apache/qpid/client/protocol/AMQProtocolHandlerTest.java
index e159ceb148..f520a21ba0 100644
--- a/qpid/java/client/src/test/java/org/apache/qpid/client/protocol/AMQProtocolHandlerTest.java
+++ b/qpid/java/client/src/test/java/org/apache/qpid/client/protocol/AMQProtocolHandlerTest.java
@@ -20,24 +20,23 @@
*/
package org.apache.qpid.client.protocol;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-
import junit.framework.TestCase;
-
-import org.apache.qpid.AMQException;
-import org.apache.qpid.client.AMQAuthenticationException;
-import org.apache.qpid.client.MockAMQConnection;
-import org.apache.qpid.client.state.AMQState;
-import org.apache.qpid.framing.AMQBody;
import org.apache.qpid.framing.AMQFrame;
+import org.apache.qpid.framing.AMQBody;
import org.apache.qpid.framing.AMQMethodBody;
import org.apache.qpid.framing.amqp_8_0.BasicRecoverOkBodyImpl;
+import org.apache.qpid.AMQException;
import org.apache.qpid.protocol.AMQConstant;
-import org.apache.qpid.transport.TestNetworkConnection;
+import org.apache.qpid.transport.TestNetworkDriver;
+import org.apache.qpid.client.MockAMQConnection;
+import org.apache.qpid.client.AMQAuthenticationException;
+import org.apache.qpid.client.state.AMQState;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
/**
* This is a test address QPID-1431 where frame listeners would fail to be notified of an incomming exception.
*
@@ -73,8 +72,8 @@ public class AMQProtocolHandlerTest extends TestCase
public void setUp() throws Exception
{
//Create a new ProtocolHandler with a fake connection.
- _handler = new AMQProtocolHandler(new MockAMQConnection("amqp://guest:guest@client/test?brokerlist='tcp://localhost:1'"));
- _handler.setNetworkConnection(new TestNetworkConnection());
+ _handler = new AMQProtocolHandler(new MockAMQConnection("amqp://guest:guest@client/test?brokerlist='vm://:1'"));
+ _handler.setNetworkDriver(new TestNetworkDriver());
AMQBody body = BasicRecoverOkBodyImpl.getFactory().newInstance(null, 1);
_blockFrame = new AMQFrame(0, body);
diff --git a/qpid/java/client/src/test/java/org/apache/qpid/client/security/UsernameHashedPasswordCallbackHandlerTest.java b/qpid/java/client/src/test/java/org/apache/qpid/client/security/UsernameHashedPasswordCallbackHandlerTest.java
deleted file mode 100644
index 9e23f722eb..0000000000
--- a/qpid/java/client/src/test/java/org/apache/qpid/client/security/UsernameHashedPasswordCallbackHandlerTest.java
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
- */
-package org.apache.qpid.client.security;
-
-import java.security.MessageDigest;
-import java.util.Arrays;
-
-import javax.security.auth.callback.Callback;
-import javax.security.auth.callback.NameCallback;
-import javax.security.auth.callback.PasswordCallback;
-
-import junit.framework.TestCase;
-
-import org.apache.qpid.client.AMQConnection;
-import org.apache.qpid.client.AMQConnectionURL;
-import org.apache.qpid.client.MockAMQConnection;
-import org.apache.qpid.client.protocol.AMQProtocolHandler;
-import org.apache.qpid.client.protocol.AMQProtocolSession;
-
-/**
- * Unit tests for the UsernameHashPasswordCallbackHandler. This callback handler is
- * used by the CRAM-MD5-HASHED SASL mechanism.
- *
- */
-public class UsernameHashedPasswordCallbackHandlerTest extends TestCase
-{
- private AMQCallbackHandler _callbackHandler = new UsernameHashedPasswordCallbackHandler(); // Class under test
- private static final String PROMPT_UNUSED = "unused";
-
- @Override
- protected void setUp() throws Exception
- {
- super.setUp();
-
- final String url = "amqp://username:password@client/test?brokerlist='tcp://localhost:1'";
- _callbackHandler.initialise(new AMQConnectionURL(url));
- }
-
- /**
- * Tests that the callback handler can correctly retrieve the username from the connection url.
- */
- public void testNameCallback() throws Exception
- {
- final String expectedName = "username";
- NameCallback nameCallback = new NameCallback(PROMPT_UNUSED);
-
- assertNull("Unexpected name before test", nameCallback.getName());
- _callbackHandler.handle(new Callback[] {nameCallback});
- assertEquals("Unexpected name", expectedName, nameCallback.getName());
- }
-
- /**
- * Tests that the callback handler can correctly retrieve the password from the connection url
- * and calculate a MD5.
- */
- public void testDigestedPasswordCallback() throws Exception
- {
- final char[] expectedPasswordDigested = getHashPassword("password");
-
- PasswordCallback passwordCallback = new PasswordCallback(PROMPT_UNUSED, false);
- assertNull("Unexpected password before test", passwordCallback.getPassword());
- _callbackHandler.handle(new Callback[] {passwordCallback});
- assertTrue("Unexpected password", Arrays.equals(expectedPasswordDigested, passwordCallback.getPassword()));
- }
-
- private char[] getHashPassword(final String password) throws Exception
- {
- MessageDigest md5Digester = MessageDigest.getInstance("MD5");
- final byte[] digest = md5Digester.digest(password.getBytes("UTF-8"));
-
- char[] hash = new char[digest.length];
-
- int index = 0;
- for (byte b : digest)
- {
- hash[index++] = (char) b;
- }
-
- return hash;
- }
-}
diff --git a/qpid/java/client/src/test/java/org/apache/qpid/client/security/UsernamePasswordCallbackHandlerTest.java b/qpid/java/client/src/test/java/org/apache/qpid/client/security/UsernamePasswordCallbackHandlerTest.java
deleted file mode 100644
index 83ddfd72fa..0000000000
--- a/qpid/java/client/src/test/java/org/apache/qpid/client/security/UsernamePasswordCallbackHandlerTest.java
+++ /dev/null
@@ -1,78 +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.client.security;
-
-import javax.security.auth.callback.Callback;
-import javax.security.auth.callback.NameCallback;
-import javax.security.auth.callback.PasswordCallback;
-
-import junit.framework.TestCase;
-
-import org.apache.qpid.client.AMQConnection;
-import org.apache.qpid.client.AMQConnectionURL;
-import org.apache.qpid.client.MockAMQConnection;
-import org.apache.qpid.client.protocol.AMQProtocolHandler;
-import org.apache.qpid.client.protocol.AMQProtocolSession;
-
-/**
- * Unit tests for the UsernamePasswordCallbackHandler.
- *
- */
-public class UsernamePasswordCallbackHandlerTest extends TestCase
-{
- private AMQCallbackHandler _callbackHandler = new UsernamePasswordCallbackHandler(); // Class under test
- private static final String PROMPT_UNUSED = "unused";
-
- @Override
- protected void setUp() throws Exception
- {
- super.setUp();
-
- final String url = "amqp://username:password@client/test?brokerlist='tcp://localhost:1'";
-
- _callbackHandler.initialise(new AMQConnectionURL(url));
- }
-
- /**
- * Tests that the callback handler can correctly retrieve the username from the connection url.
- */
- public void testNameCallback() throws Exception
- {
- final String expectedName = "username";
- NameCallback nameCallback = new NameCallback(PROMPT_UNUSED);
-
- assertNull("Unexpected name before test", nameCallback.getName());
- _callbackHandler.handle(new Callback[] {nameCallback});
- assertEquals("Unexpected name", expectedName, nameCallback.getName());
- }
-
- /**
- * Tests that the callback handler can correctly retrieve the password from the connection url.
- */
- public void testPasswordCallback() throws Exception
- {
- final String expectedPassword = "password";
- PasswordCallback passwordCallback = new PasswordCallback(PROMPT_UNUSED, false);
- assertNull("Unexpected password before test", passwordCallback.getPassword());
- _callbackHandler.handle(new Callback[] {passwordCallback});
- assertEquals("Unexpected password", expectedPassword, new String(passwordCallback.getPassword()));
- }
-}
diff --git a/qpid/java/client/src/test/java/org/apache/qpid/jms/FailoverPolicyTest.java b/qpid/java/client/src/test/java/org/apache/qpid/jms/FailoverPolicyTest.java
deleted file mode 100644
index 438995aedc..0000000000
--- a/qpid/java/client/src/test/java/org/apache/qpid/jms/FailoverPolicyTest.java
+++ /dev/null
@@ -1,338 +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.jms;
-
-import javax.jms.ConnectionConsumer;
-import javax.jms.ConnectionMetaData;
-import javax.jms.Destination;
-import javax.jms.ExceptionListener;
-import javax.jms.JMSException;
-import javax.jms.ServerSessionPool;
-import javax.jms.Topic;
-
-import org.apache.qpid.client.AMQConnectionURL;
-import org.apache.qpid.jms.failover.FailoverExchangeMethod;
-import org.apache.qpid.jms.failover.FailoverMethod;
-import org.apache.qpid.jms.failover.FailoverRoundRobinServers;
-import org.apache.qpid.jms.failover.FailoverSingleServer;
-import org.apache.qpid.jms.failover.NoFailover;
-
-import junit.framework.TestCase;
-
-/**
- * Tests the ability of FailoverPolicy to instantiate the correct FailoverMethod.
- *
- * This test presently does <i>not</i> test {@link FailoverPolicy#FailoverPolicy(FailoverMethod) or
- * {@link FailoverPolicy#addMethod(FailoverMethod)} as it appears that this functionality
- * is no longer in use.
- *
- */
-public class FailoverPolicyTest extends TestCase
-{
- private FailoverPolicy _failoverPolicy = null; // class under test
- private String _url;
- private Connection _connection = null;
- private ConnectionURL _connectionUrl = null;
-
- /**
- * Tests single server method is selected for a brokerlist with one broker when
- * the failover option is not specified.
- */
- public void testBrokerListWithOneBrokerDefaultsToSingleServerPolicy() throws Exception
- {
- _url = "amqp://user:pass@clientid/test?brokerlist='tcp://localhost:5672'";
- _connectionUrl = new AMQConnectionURL(_url);
- _connection = createStubConnection();
-
- _failoverPolicy = new FailoverPolicy(_connectionUrl, _connection);
-
- assertTrue("Unexpected failover method", _failoverPolicy.getCurrentMethod() instanceof FailoverSingleServer);
- }
-
- /**
- * Tests round robin method is selected for a brokerlist with two brokers when
- * the failover option is not specified.
- */
- public void testBrokerListWithTwoBrokersDefaultsToRoundRobinPolicy() throws Exception
- {
- _url = "amqp://user:pass@clientid/test?brokerlist='tcp://localhost:5672;tcp://localhost:5673'";
- _connectionUrl = new AMQConnectionURL(_url);
- _connection = createStubConnection();
-
- _failoverPolicy = new FailoverPolicy(_connectionUrl, _connection);
-
- assertTrue("Unexpected failover method", _failoverPolicy.getCurrentMethod() instanceof FailoverRoundRobinServers);
- }
-
- /**
- * Tests single server method is selected for a brokerlist with one broker when
- * the failover option passed as 'singlebroker'.
- */
- public void testExplictFailoverOptionSingleBroker() throws Exception
- {
- _url = "amqp://user:pass@clientid/test?brokerlist='tcp://localhost:5672'&failover='singlebroker'";
- _connectionUrl = new AMQConnectionURL(_url);
- _connection = createStubConnection();
-
- _failoverPolicy = new FailoverPolicy(_connectionUrl, _connection);
-
- assertTrue("Unexpected failover method", _failoverPolicy.getCurrentMethod() instanceof FailoverSingleServer);
- }
-
- /**
- * Tests round robin method is selected for a brokerlist with two brokers when
- * the failover option passed as 'roundrobin'.
- */
- public void testExplictFailoverOptionRoundrobin() throws Exception
- {
- _url = "amqp://user:pass@clientid/test?brokerlist='tcp://localhost:5672;tcp://localhost:5673'&failover='roundrobin'";
- _connectionUrl = new AMQConnectionURL(_url);
- _connection = createStubConnection();
-
- _failoverPolicy = new FailoverPolicy(_connectionUrl, _connection);
-
- assertTrue("Unexpected failover method", _failoverPolicy.getCurrentMethod() instanceof FailoverRoundRobinServers);
- }
-
- /**
- * Tests no failover method is selected for a brokerlist with one broker when
- * the failover option passed as 'nofailover'.
- */
- public void testExplictFailoverOptionNofailover() throws Exception
- {
- _url = "amqp://user:pass@clientid/test?brokerlist='tcp://localhost:5672'&failover='nofailover'";
- _connectionUrl = new AMQConnectionURL(_url);
- _connection = createStubConnection();
-
- _failoverPolicy = new FailoverPolicy(_connectionUrl, _connection);
-
- assertTrue("Unexpected failover method", _failoverPolicy.getCurrentMethod() instanceof NoFailover);
- }
-
- /**
- * Tests failover exchange method is selected for a brokerlist with one broker when
- * the failover option passed as 'failover_exchange'.
- */
- public void testExplictFailoverOptionFailoverExchange() throws Exception
- {
- _url = "amqp://user:pass@clientid/test?brokerlist='tcp://localhost:5672'&failover='failover_exchange'";
- _connectionUrl = new AMQConnectionURL(_url);
- _connection = createStubConnection();
-
- _failoverPolicy = new FailoverPolicy(_connectionUrl, _connection);
-
- assertTrue("Unexpected failover method", _failoverPolicy.getCurrentMethod() instanceof FailoverExchangeMethod);
- }
-
- /**
- * Tests that a custom method can be selected for a brokerlist with one brokers when
- * the failover option passed as a qualified class-name.
- */
- public void testExplictFailoverOptionDynamicallyLoadedFailoverMethod() throws Exception
- {
- _url = "amqp://user:pass@clientid/test?brokerlist='tcp://localhost:5672'&failover='org.apache.qpid.jms.FailoverPolicyTest$MyFailoverMethod'";
- _connectionUrl = new AMQConnectionURL(_url);
- _connection = createStubConnection();
-
- _failoverPolicy = new FailoverPolicy(_connectionUrl, _connection);
-
- assertTrue("Unexpected failover method", _failoverPolicy.getCurrentMethod() instanceof MyFailoverMethod);
- }
-
- /**
- * Tests that an unknown method caused an exception.
- */
- public void testUnknownFailoverMethod() throws Exception
- {
- _url = "amqp://user:pass@clientid/test?brokerlist='tcp://localhost:5672'&failover='unknown'";
- _connectionUrl = new AMQConnectionURL(_url);
- _connection = createStubConnection();
-
- try
- {
- new FailoverPolicy(_connectionUrl, _connection);
- fail("Exception not thrown");
- }
- catch(IllegalArgumentException iae)
- {
- // PASS
- }
- }
-
- private Connection createStubConnection()
- {
- return new Connection()
- {
-
- @Override
- public Session createSession(boolean transacted,
- int acknowledgeMode, int prefetch) throws JMSException
- {
- return null;
- }
-
- @Override
- public Session createSession(boolean transacted,
- int acknowledgeMode, int prefetchHigh, int prefetchLow)
- throws JMSException
- {
- return null;
- }
-
- @Override
- public ConnectionListener getConnectionListener()
- {
- return null;
- }
-
- @Override
- public long getMaximumChannelCount() throws JMSException
- {
- return 0;
- }
-
- @Override
- public void setConnectionListener(ConnectionListener listener)
- {
- }
-
- @Override
- public void close() throws JMSException
- {
- }
-
- @Override
- public ConnectionConsumer createConnectionConsumer(
- Destination arg0, String arg1, ServerSessionPool arg2,
- int arg3) throws JMSException
- {
- return null;
- }
-
- @Override
- public ConnectionConsumer createDurableConnectionConsumer(
- Topic arg0, String arg1, String arg2,
- ServerSessionPool arg3, int arg4) throws JMSException
- {
- return null;
- }
-
- @Override
- public javax.jms.Session createSession(boolean arg0, int arg1)
- throws JMSException
- {
- return null;
- }
-
- @Override
- public String getClientID() throws JMSException
- {
- return null;
- }
-
- @Override
- public ExceptionListener getExceptionListener() throws JMSException
- {
- return null;
- }
-
- @Override
- public ConnectionMetaData getMetaData() throws JMSException
- {
- return null;
- }
-
- @Override
- public void setClientID(String arg0) throws JMSException
- {
- }
-
- @Override
- public void setExceptionListener(ExceptionListener arg0)
- throws JMSException
- {
- }
-
- @Override
- public void start() throws JMSException
- {
- }
-
- @Override
- public void stop() throws JMSException
- {
- }
- };
- }
-
- // Class used to test the ability of FailoverPolicy to load an implementation.
- static class MyFailoverMethod implements FailoverMethod
- {
- public MyFailoverMethod(ConnectionURL connectionDetails)
- {
- }
-
- @Override
- public void attainedConnection()
- {
- }
-
- @Override
- public boolean failoverAllowed()
- {
- return false;
- }
-
- @Override
- public BrokerDetails getCurrentBrokerDetails()
- {
- return null;
- }
-
- @Override
- public BrokerDetails getNextBrokerDetails()
- {
- return null;
- }
-
- @Override
- public String methodName()
- {
- return null;
- }
-
- @Override
- public void reset()
- {
- }
-
- @Override
- public void setBroker(BrokerDetails broker)
- {
- }
-
- @Override
- public void setRetries(int maxRetries)
- {
- }
- }
-
-}
diff --git a/qpid/java/client/src/test/java/org/apache/qpid/test/unit/client/BrokerDetails/BrokerDetailsTest.java b/qpid/java/client/src/test/java/org/apache/qpid/test/unit/client/BrokerDetails/BrokerDetailsTest.java
index 9095f94960..1b27ff6300 100644
--- a/qpid/java/client/src/test/java/org/apache/qpid/test/unit/client/BrokerDetails/BrokerDetailsTest.java
+++ b/qpid/java/client/src/test/java/org/apache/qpid/test/unit/client/BrokerDetails/BrokerDetailsTest.java
@@ -43,6 +43,15 @@ public class BrokerDetailsTest extends TestCase
assertTrue(broker.getProperty("immediatedelivery").equals("true"));
}
+ public void testVMBroker() throws URLSyntaxException
+ {
+ String url = "vm://:2";
+
+ AMQBrokerDetails broker = new AMQBrokerDetails(url);
+ assertTrue(broker.getTransport().equals("vm"));
+ assertEquals(broker.getPort(), 2);
+ }
+
public void testTransportsDefaultToTCP() throws URLSyntaxException
{
String url = "localhost:5672";
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 4624b36fea..2be3720c20 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
@@ -300,6 +300,53 @@ public class ConnectionURLTest extends TestCase
assertTrue(connectionurl.getOption("immediatedelivery").equals("true"));
}
+ public void testSinglevmURL() throws URLSyntaxException
+ {
+ String url = "amqp://guest:guest@/test?brokerlist='vm://:2'";
+
+ ConnectionURL connectionurl = new AMQConnectionURL(url);
+
+ assertTrue(connectionurl.getFailoverMethod() == null);
+ assertTrue(connectionurl.getUsername().equals("guest"));
+ assertTrue(connectionurl.getPassword().equals("guest"));
+ assertTrue(connectionurl.getVirtualHost().equals("/test"));
+
+ assertTrue(connectionurl.getBrokerCount() == 1);
+
+ BrokerDetails service = connectionurl.getBrokerDetails(0);
+
+ assertTrue(service.getTransport().equals("vm"));
+ assertTrue(service.getHost().equals(""));
+ assertTrue(service.getPort() == 2);
+
+ }
+
+ public void testFailoverVMURL() throws URLSyntaxException
+ {
+ String url = "amqp://ritchiem:bob@/test?brokerlist='vm://:2;vm://:3',failover='roundrobin'";
+
+ ConnectionURL connectionurl = new AMQConnectionURL(url);
+
+ assertTrue(connectionurl.getFailoverMethod().equals("roundrobin"));
+ assertTrue(connectionurl.getUsername().equals("ritchiem"));
+ assertTrue(connectionurl.getPassword().equals("bob"));
+ assertTrue(connectionurl.getVirtualHost().equals("/test"));
+
+ assertTrue(connectionurl.getBrokerCount() == 2);
+
+ BrokerDetails service = connectionurl.getBrokerDetails(0);
+
+ assertTrue(service.getTransport().equals("vm"));
+ assertTrue(service.getHost().equals(""));
+ assertTrue(service.getPort() == 2);
+
+ service = connectionurl.getBrokerDetails(1);
+ assertTrue(service.getTransport().equals("vm"));
+ assertTrue(service.getHost().equals(""));
+ assertTrue(service.getPort() == 3);
+ }
+
+
public void testNoVirtualHostURL()
{
String url = "amqp://user@?brokerlist='tcp://localhost:5672'";
@@ -440,6 +487,27 @@ public class ConnectionURLTest extends TestCase
}
+ public void testSocketProtocol() throws URLSyntaxException
+ {
+ String url = "amqp://guest:guest@id/test" + "?brokerlist='socket://VM-Unique-socketID'";
+
+ try
+ {
+ AMQConnectionURL curl = new AMQConnectionURL(url);
+ assertNotNull(curl);
+ assertEquals(1, curl.getBrokerCount());
+ assertNotNull(curl.getBrokerDetails(0));
+ assertEquals(BrokerDetails.SOCKET, curl.getBrokerDetails(0).getTransport());
+ assertEquals("VM-Unique-socketID", curl.getBrokerDetails(0).getHost());
+ assertEquals("URL does not toString as expected",
+ url.replace(":guest", ":********"), curl.toString());
+ }
+ catch (URLSyntaxException e)
+ {
+ fail(e.getMessage());
+ }
+ }
+
public void testSingleTransportMultiOptionOnBrokerURL() throws URLSyntaxException
{
String url = "amqp://guest:guest@/test?brokerlist='tcp://localhost:5672?foo='jim'&bar='bob'&fred='jimmy'',routingkey='jim',timeout='200',immediatedelivery='true'";
@@ -481,37 +549,6 @@ public class ConnectionURLTest extends TestCase
assertTrue("String representation should contain options and values", url.toString().contains("maxprefetch='12345'"));
}
- public void testHostNamesWithUnderScore() throws URLSyntaxException
- {
- String url = "amqp://guest:guest@clientid/test?brokerlist='tcp://under_score:6672'";
-
- ConnectionURL connectionurl = new AMQConnectionURL(url);
-
- assertTrue(connectionurl.getUsername().equals("guest"));
- assertTrue(connectionurl.getPassword().equals("guest"));
- assertTrue(connectionurl.getVirtualHost().equals("/test"));
-
- assertTrue(connectionurl.getBrokerCount() == 1);
- BrokerDetails service = connectionurl.getBrokerDetails(0);
- assertTrue(service.getTransport().equals("tcp"));
- assertTrue(service.getHost().equals("under_score"));
- assertTrue(service.getPort() == 6672);
-
- url = "amqp://guest:guest@clientid/test?brokerlist='tcp://under_score'";
-
- connectionurl = new AMQConnectionURL(url);
-
- assertTrue(connectionurl.getUsername().equals("guest"));
- assertTrue(connectionurl.getPassword().equals("guest"));
- assertTrue(connectionurl.getVirtualHost().equals("/test"));
-
- assertTrue(connectionurl.getBrokerCount() == 1);
- service = connectionurl.getBrokerDetails(0);
- assertTrue(service.getTransport().equals("tcp"));
- assertTrue(service.getHost().equals("under_score"));
- assertTrue(service.getPort() == 5672);
- }
-
public static junit.framework.Test suite()
{
return new junit.framework.TestSuite(ConnectionURLTest.class);
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 4637c6e505..47c0359b94 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
@@ -195,10 +195,4 @@ public class TestAMQSession extends AMQSession<BasicMessageConsumer_0_8, BasicMe
{
return false;
}
-
- @Override
- public AMQException getLastException()
- {
- return null;
- }
}
diff --git a/qpid/java/common.xml b/qpid/java/common.xml
index f503a5c7da..066859b29f 100644
--- a/qpid/java/common.xml
+++ b/qpid/java/common.xml
@@ -23,9 +23,7 @@
<dirname property="project.root" file="${ant.file.common}"/>
<property name="project.name" value="qpid"/>
- <property name="project.version" value="0.13"/>
- <property name="project.url" value="http://qpid.apache.org"/>
- <property name="project.groupid" value="org.apache.qpid"/>
+ <property name="project.version" value="0.9"/>
<property name="project.namever" value="${project.name}-${project.version}"/>
<property name="resources" location="${project.root}/resources"/>
@@ -65,11 +63,6 @@
<property name="mllib.dir" value="${project.root}/../python" />
<property name="findbugs.dir" value="${project.root}/lib/findbugs" />
- <!-- properties used to control Ant Eclipse for Eclipse classpath/project files etc -->
- <property name="eclipse.updatealways" value="false"/>
- <property name="eclipse.compilercompliance" value="5.0"/>
- <property name="eclipse.container" value="JVM 1.5"/>
-
<path id="cobertura.classpath">
<fileset dir="${cobertura.dir}">
<include name="cobertura.jar" />
@@ -78,7 +71,6 @@
</path>
<property name="maven.local.repo" value="${build.scratch}/maven-local-repo"/>
- <property name="maven.settings.xml" value="${project.root}/maven-settings.xml"/>
<property name="maven.unique.version" value="false"/>
<property name="maven.snapshot" value="true"/>
<condition property="maven.version.suffix" value="" else="-SNAPSHOT">
@@ -116,10 +108,9 @@
<attribute name="dir"/>
<attribute name="name"/>
<attribute name="excludes" default=""/>
- <attribute name="erroronmissingdir" default="true"/>
<sequential>
- <dirset id="@{dir}.refid" dir="@{dir}" excludes="@{excludes}" erroronmissingdir="@{erroronmissingdir}">
+ <dirset id="@{dir}.refid" dir="@{dir}" excludes="@{excludes}">
<present targetdir="@{dir}">
<mapper type="glob" from="*" to="*/build.xml" />
</present>
@@ -133,6 +124,8 @@
</sequential>
</macrodef>
+
+
<macrodef name="jython">
<attribute name="path"/>
<element name="args"/>
@@ -329,20 +322,6 @@
results directory:
${build.results}
-
- ant eclipse
-
- Generates project and classpath files for the Eclispe IDE. Requires that
- the Ant Eclipse task (http://ant-eclipse.sourceforge.net/) has been installed
- in $ANT_HOME/lib.
-
- The following system properties will be passed to the task. These can be usefully
- overridden from the command line.
-
- eclipse.updatealways - forces Eclipse files to be regenerated even if they are newer then the build.xml (default ${eclipse.updatealways}).
- eclipse.container - controls the Eclipse container (default ${eclipse.container}).
- eclipse.compilercompliance" - controls the Eclipse compiler compliance (default ${eclipse.compilercompliance}).
-
</echo>
</target>
diff --git a/qpid/java/common/src/main/java/common.bnd b/qpid/java/common/src/main/java/common.bnd
index f12fbf9273..ef56ecec9e 100755
--- a/qpid/java/common/src/main/java/common.bnd
+++ b/qpid/java/common/src/main/java/common.bnd
@@ -17,7 +17,7 @@
# under the License.
#
-ver: 0.13.0
+ver: 0.9.0
Bundle-SymbolicName: qpid-common
Bundle-Version: ${ver}
diff --git a/qpid/java/common/src/main/java/org/apache/mina/common/FixedSizeByteBufferAllocator.java b/qpid/java/common/src/main/java/org/apache/mina/common/FixedSizeByteBufferAllocator.java
new file mode 100644
index 0000000000..0c311b6645
--- /dev/null
+++ b/qpid/java/common/src/main/java/org/apache/mina/common/FixedSizeByteBufferAllocator.java
@@ -0,0 +1,467 @@
+package org.apache.mina.common;
+
+import org.apache.mina.common.ByteBuffer;
+
+import java.nio.*;
+
+/*
+*
+* 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.
+*
+*/
+public class FixedSizeByteBufferAllocator implements ByteBufferAllocator
+{
+
+
+ private static final int MINIMUM_CAPACITY = 1;
+
+ public FixedSizeByteBufferAllocator ()
+ {
+ }
+
+ public ByteBuffer allocate( int capacity, boolean direct )
+ {
+ java.nio.ByteBuffer nioBuffer;
+ if( direct )
+ {
+ nioBuffer = java.nio.ByteBuffer.allocateDirect( capacity );
+ }
+ else
+ {
+ nioBuffer = java.nio.ByteBuffer.allocate( capacity );
+ }
+ return new FixedSizeByteBuffer( nioBuffer );
+ }
+
+ public ByteBuffer wrap( java.nio.ByteBuffer nioBuffer )
+ {
+ return new FixedSizeByteBuffer( nioBuffer );
+ }
+
+ public void dispose()
+ {
+ }
+
+
+
+ private static final class FixedSizeByteBuffer extends ByteBuffer
+ {
+ private java.nio.ByteBuffer buf;
+ private int mark = -1;
+
+
+ protected FixedSizeByteBuffer( java.nio.ByteBuffer buf )
+ {
+ this.buf = buf;
+ buf.order( ByteOrder.BIG_ENDIAN );
+ }
+
+ public synchronized void acquire()
+ {
+ }
+
+ public void release()
+ {
+ }
+
+ public java.nio.ByteBuffer buf()
+ {
+ return buf;
+ }
+
+ public boolean isPooled()
+ {
+ return false;
+ }
+
+ public void setPooled( boolean pooled )
+ {
+ }
+
+ public ByteBuffer duplicate() {
+ return new FixedSizeByteBuffer( this.buf.duplicate() );
+ }
+
+ public ByteBuffer slice() {
+ return new FixedSizeByteBuffer( this.buf.slice() );
+ }
+
+ public ByteBuffer asReadOnlyBuffer() {
+ return new FixedSizeByteBuffer( this.buf.asReadOnlyBuffer() );
+ }
+
+ public byte[] array()
+ {
+ return buf.array();
+ }
+
+ public int arrayOffset()
+ {
+ return buf.arrayOffset();
+ }
+
+ public boolean isDirect()
+ {
+ return buf.isDirect();
+ }
+
+ public boolean isReadOnly()
+ {
+ return buf.isReadOnly();
+ }
+
+ public int capacity()
+ {
+ return buf.capacity();
+ }
+
+ public ByteBuffer capacity( int newCapacity )
+ {
+ if( newCapacity > capacity() )
+ {
+ throw new IllegalArgumentException();
+ }
+
+ return this;
+ }
+
+
+
+ public boolean isAutoExpand()
+ {
+ return false;
+ }
+
+ public ByteBuffer setAutoExpand( boolean autoExpand )
+ {
+ if(autoExpand) throw new IllegalArgumentException();
+ else return this;
+ }
+
+ public ByteBuffer expand( int pos, int expectedRemaining )
+ {
+ int end = pos + expectedRemaining;
+ if( end > capacity() )
+ {
+ // The buffer needs expansion.
+ capacity( end );
+ }
+
+ if( end > limit() )
+ {
+ // We call limit() directly to prevent StackOverflowError
+ buf.limit( end );
+ }
+ return this;
+ }
+
+ public int position()
+ {
+ return buf.position();
+ }
+
+ public ByteBuffer position( int newPosition )
+ {
+
+ buf.position( newPosition );
+ if( mark > newPosition )
+ {
+ mark = -1;
+ }
+ return this;
+ }
+
+ public int limit()
+ {
+ return buf.limit();
+ }
+
+ public ByteBuffer limit( int newLimit )
+ {
+ buf.limit( newLimit );
+ if( mark > newLimit )
+ {
+ mark = -1;
+ }
+ return this;
+ }
+
+ public ByteBuffer mark()
+ {
+ buf.mark();
+ mark = position();
+ return this;
+ }
+
+ public int markValue()
+ {
+ return mark;
+ }
+
+ public ByteBuffer reset()
+ {
+ buf.reset();
+ return this;
+ }
+
+ public ByteBuffer clear()
+ {
+ buf.clear();
+ mark = -1;
+ return this;
+ }
+
+ public ByteBuffer flip()
+ {
+ buf.flip();
+ mark = -1;
+ return this;
+ }
+
+ public ByteBuffer rewind()
+ {
+ buf.rewind();
+ mark = -1;
+ return this;
+ }
+
+ public byte get()
+ {
+ return buf.get();
+ }
+
+ public ByteBuffer put( byte b )
+ {
+ buf.put( b );
+ return this;
+ }
+
+ public byte get( int index )
+ {
+ return buf.get( index );
+ }
+
+ public ByteBuffer put( int index, byte b )
+ {
+ buf.put( index, b );
+ return this;
+ }
+
+ public ByteBuffer get( byte[] dst, int offset, int length )
+ {
+ buf.get( dst, offset, length );
+ return this;
+ }
+
+ public ByteBuffer put( java.nio.ByteBuffer src )
+ {
+ buf.put( src );
+ return this;
+ }
+
+ public ByteBuffer put( byte[] src, int offset, int length )
+ {
+ buf.put( src, offset, length );
+ return this;
+ }
+
+ public ByteBuffer compact()
+ {
+ buf.compact();
+ mark = -1;
+ return this;
+ }
+
+ public ByteOrder order()
+ {
+ return buf.order();
+ }
+
+ public ByteBuffer order( ByteOrder bo )
+ {
+ buf.order( bo );
+ return this;
+ }
+
+ public char getChar()
+ {
+ return buf.getChar();
+ }
+
+ public ByteBuffer putChar( char value )
+ {
+ buf.putChar( value );
+ return this;
+ }
+
+ public char getChar( int index )
+ {
+ return buf.getChar( index );
+ }
+
+ public ByteBuffer putChar( int index, char value )
+ {
+ buf.putChar( index, value );
+ return this;
+ }
+
+ public CharBuffer asCharBuffer()
+ {
+ return buf.asCharBuffer();
+ }
+
+ public short getShort()
+ {
+ return buf.getShort();
+ }
+
+ public ByteBuffer putShort( short value )
+ {
+ buf.putShort( value );
+ return this;
+ }
+
+ public short getShort( int index )
+ {
+ return buf.getShort( index );
+ }
+
+ public ByteBuffer putShort( int index, short value )
+ {
+ buf.putShort( index, value );
+ return this;
+ }
+
+ public ShortBuffer asShortBuffer()
+ {
+ return buf.asShortBuffer();
+ }
+
+ public int getInt()
+ {
+ return buf.getInt();
+ }
+
+ public ByteBuffer putInt( int value )
+ {
+ buf.putInt( value );
+ return this;
+ }
+
+ public int getInt( int index )
+ {
+ return buf.getInt( index );
+ }
+
+ public ByteBuffer putInt( int index, int value )
+ {
+ buf.putInt( index, value );
+ return this;
+ }
+
+ public IntBuffer asIntBuffer()
+ {
+ return buf.asIntBuffer();
+ }
+
+ public long getLong()
+ {
+ return buf.getLong();
+ }
+
+ public ByteBuffer putLong( long value )
+ {
+ buf.putLong( value );
+ return this;
+ }
+
+ public long getLong( int index )
+ {
+ return buf.getLong( index );
+ }
+
+ public ByteBuffer putLong( int index, long value )
+ {
+ buf.putLong( index, value );
+ return this;
+ }
+
+ public LongBuffer asLongBuffer()
+ {
+ return buf.asLongBuffer();
+ }
+
+ public float getFloat()
+ {
+ return buf.getFloat();
+ }
+
+ public ByteBuffer putFloat( float value )
+ {
+ buf.putFloat( value );
+ return this;
+ }
+
+ public float getFloat( int index )
+ {
+ return buf.getFloat( index );
+ }
+
+ public ByteBuffer putFloat( int index, float value )
+ {
+ buf.putFloat( index, value );
+ return this;
+ }
+
+ public FloatBuffer asFloatBuffer()
+ {
+ return buf.asFloatBuffer();
+ }
+
+ public double getDouble()
+ {
+ return buf.getDouble();
+ }
+
+ public ByteBuffer putDouble( double value )
+ {
+ buf.putDouble( value );
+ return this;
+ }
+
+ public double getDouble( int index )
+ {
+ return buf.getDouble( index );
+ }
+
+ public ByteBuffer putDouble( int index, double value )
+ {
+ buf.putDouble( index, value );
+ return this;
+ }
+
+ public DoubleBuffer asDoubleBuffer()
+ {
+ return buf.asDoubleBuffer();
+ }
+
+
+ }
+
+
+}
diff --git a/qpid/java/common/src/main/java/org/apache/mina/common/support/DefaultIoFuture.java b/qpid/java/common/src/main/java/org/apache/mina/common/support/DefaultIoFuture.java
new file mode 100644
index 0000000000..4fd28c4eb5
--- /dev/null
+++ b/qpid/java/common/src/main/java/org/apache/mina/common/support/DefaultIoFuture.java
@@ -0,0 +1,227 @@
+/*
+ * 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.mina.common.support;
+
+import org.apache.mina.common.IoFuture;
+import org.apache.mina.common.IoSession;
+import org.apache.mina.common.IoFutureListener;
+
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Iterator;
+
+/**
+ * A default implementation of {@link org.apache.mina.common.IoFuture}.
+ *
+ * @author The Apache Directory Project (mina-dev@directory.apache.org)
+ */
+public class DefaultIoFuture implements IoFuture
+{
+ private final IoSession session;
+ private final Object lock;
+ private List listeners;
+ private Object result;
+ private boolean ready;
+
+
+ /**
+ * Creates a new instance.
+ *
+ * @param session an {@link IoSession} which is associated with this future
+ */
+ public DefaultIoFuture( IoSession session )
+ {
+ this.session = session;
+ this.lock = this;
+ }
+
+ /**
+ * Creates a new instance which uses the specified object as a lock.
+ */
+ public DefaultIoFuture( IoSession session, Object lock )
+ {
+ if( lock == null )
+ {
+ throw new NullPointerException( "lock" );
+ }
+ this.session = session;
+ this.lock = lock;
+ }
+
+ public IoSession getSession()
+ {
+ return session;
+ }
+
+ public Object getLock()
+ {
+ return lock;
+ }
+
+ public void join()
+ {
+ synchronized( lock )
+ {
+ while( !ready )
+ {
+ try
+ {
+ lock.wait();
+ }
+ catch( InterruptedException e )
+ {
+ }
+ }
+ }
+ }
+
+ public boolean join( long timeoutInMillis )
+ {
+ long startTime = ( timeoutInMillis <= 0 ) ? 0 : System
+ .currentTimeMillis();
+ long waitTime = timeoutInMillis;
+
+ synchronized( lock )
+ {
+ if( ready )
+ {
+ return ready;
+ }
+ else if( waitTime <= 0 )
+ {
+ return ready;
+ }
+
+ for( ;; )
+ {
+ try
+ {
+ lock.wait( waitTime );
+ }
+ catch( InterruptedException e )
+ {
+ }
+
+ if( ready )
+ return true;
+ else
+ {
+ waitTime = timeoutInMillis - ( System.currentTimeMillis() - startTime );
+ if( waitTime <= 0 )
+ {
+ return ready;
+ }
+ }
+ }
+ }
+ }
+
+ public boolean isReady()
+ {
+ synchronized( lock )
+ {
+ return ready;
+ }
+ }
+
+ /**
+ * Sets the result of the asynchronous operation, and mark it as finished.
+ */
+ protected void setValue( Object newValue )
+ {
+ synchronized( lock )
+ {
+ // Allow only once.
+ if( ready )
+ {
+ return;
+ }
+
+ result = newValue;
+ ready = true;
+ lock.notifyAll();
+
+ notifyListeners();
+ }
+ }
+
+ /**
+ * Returns the result of the asynchronous operation.
+ */
+ protected Object getValue()
+ {
+ synchronized( lock )
+ {
+ return result;
+ }
+ }
+
+ public void addListener( IoFutureListener listener )
+ {
+ if( listener == null )
+ {
+ throw new NullPointerException( "listener" );
+ }
+
+ synchronized( lock )
+ {
+ if(listeners == null)
+ {
+ listeners = new ArrayList();
+ }
+ listeners.add( listener );
+ if( ready )
+ {
+ listener.operationComplete( this );
+ }
+ }
+ }
+
+ public void removeListener( IoFutureListener listener )
+ {
+ if( listener == null )
+ {
+ throw new NullPointerException( "listener" );
+ }
+
+ synchronized( lock )
+ {
+ listeners.remove( listener );
+ }
+ }
+
+ private void notifyListeners()
+ {
+ synchronized( lock )
+ {
+
+ if(listeners != null)
+ {
+
+ for( Iterator i = listeners.iterator(); i.hasNext(); ) {
+ ( ( IoFutureListener ) i.next() ).operationComplete( this );
+ }
+ }
+ }
+ }
+}
+
+
+
diff --git a/qpid/java/common/src/main/java/org/apache/mina/common/support/IoServiceListenerSupport.java b/qpid/java/common/src/main/java/org/apache/mina/common/support/IoServiceListenerSupport.java
new file mode 100644
index 0000000000..5723ffbaa9
--- /dev/null
+++ b/qpid/java/common/src/main/java/org/apache/mina/common/support/IoServiceListenerSupport.java
@@ -0,0 +1,351 @@
+/*
+ * 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.mina.common.support;
+
+import java.net.SocketAddress;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.CountDownLatch;
+
+import org.apache.mina.common.IoAcceptorConfig;
+import org.apache.mina.common.IoConnector;
+import org.apache.mina.common.IoFuture;
+import org.apache.mina.common.IoFutureListener;
+import org.apache.mina.common.IoHandler;
+import org.apache.mina.common.IoService;
+import org.apache.mina.common.IoServiceConfig;
+import org.apache.mina.common.IoServiceListener;
+import org.apache.mina.common.IoSession;
+import org.apache.mina.util.IdentityHashSet;
+
+/**
+ * A helper which provides addition and removal of {@link IoServiceListener}s and firing
+ * events.
+ *
+ * @author The Apache Directory Project (mina-dev@directory.apache.org)
+ * @version $Rev: 446526 $, $Date: 2006-09-15 01:44:11 -0400 (Fri, 15 Sep 2006) $
+ */
+public class IoServiceListenerSupport
+{
+ /**
+ * A list of {@link IoServiceListener}s.
+ */
+ private final List listeners = new ArrayList();
+
+ /**
+ * Tracks managed <tt>serviceAddress</tt>es.
+ */
+ private final Set managedServiceAddresses = new HashSet();
+
+ /**
+ * Tracks managed sesssions with <tt>serviceAddress</tt> as a key.
+ */
+ private final Map managedSessions = new HashMap();
+
+ /**
+ * Creates a new instance.
+ */
+ public IoServiceListenerSupport()
+ {
+ }
+
+ /**
+ * Adds a new listener.
+ */
+ public void add( IoServiceListener listener )
+ {
+ synchronized( listeners )
+ {
+ listeners.add( listener );
+ }
+ }
+
+ /**
+ * Removes an existing listener.
+ */
+ public void remove( IoServiceListener listener )
+ {
+ synchronized( listeners )
+ {
+ listeners.remove( listener );
+ }
+ }
+
+ public Set getManagedServiceAddresses()
+ {
+ return Collections.unmodifiableSet( managedServiceAddresses );
+ }
+
+ public boolean isManaged( SocketAddress serviceAddress )
+ {
+ synchronized( managedServiceAddresses )
+ {
+ return managedServiceAddresses.contains( serviceAddress );
+ }
+ }
+
+ public Set getManagedSessions( SocketAddress serviceAddress )
+ {
+ Set sessions;
+ synchronized( managedSessions )
+ {
+ sessions = ( Set ) managedSessions.get( serviceAddress );
+ if( sessions == null )
+ {
+ sessions = new IdentityHashSet();
+ }
+ }
+
+ synchronized( sessions )
+ {
+ return new IdentityHashSet( sessions );
+ }
+ }
+
+ /**
+ * Calls {@link IoServiceListener#serviceActivated(IoService, SocketAddress, IoHandler, IoServiceConfig)}
+ * for all registered listeners.
+ */
+ public void fireServiceActivated(
+ IoService service, SocketAddress serviceAddress,
+ IoHandler handler, IoServiceConfig config )
+ {
+ synchronized( managedServiceAddresses )
+ {
+ if( !managedServiceAddresses.add( serviceAddress ) )
+ {
+ return;
+ }
+ }
+
+ synchronized( listeners )
+ {
+ for( Iterator i = listeners.iterator(); i.hasNext(); )
+ {
+ ( ( IoServiceListener ) i.next() ).serviceActivated(
+ service, serviceAddress, handler, config );
+ }
+ }
+ }
+
+ /**
+ * Calls {@link IoServiceListener#serviceDeactivated(IoService, SocketAddress, IoHandler, IoServiceConfig)}
+ * for all registered listeners.
+ */
+ public synchronized void fireServiceDeactivated(
+ IoService service, SocketAddress serviceAddress,
+ IoHandler handler, IoServiceConfig config )
+ {
+ synchronized( managedServiceAddresses )
+ {
+ if( !managedServiceAddresses.remove( serviceAddress ) )
+ {
+ return;
+ }
+ }
+
+ try
+ {
+ synchronized( listeners )
+ {
+ for( Iterator i = listeners.iterator(); i.hasNext(); )
+ {
+ ( ( IoServiceListener ) i.next() ).serviceDeactivated(
+ service, serviceAddress, handler, config );
+ }
+ }
+ }
+ finally
+ {
+ disconnectSessions( serviceAddress, config );
+ }
+ }
+
+
+ /**
+ * Calls {@link IoServiceListener#sessionCreated(IoSession)} for all registered listeners.
+ */
+ public void fireSessionCreated( IoSession session )
+ {
+ SocketAddress serviceAddress = session.getServiceAddress();
+
+ // Get the session set.
+ boolean firstSession = false;
+ Set sessions;
+ synchronized( managedSessions )
+ {
+ sessions = ( Set ) managedSessions.get( serviceAddress );
+ if( sessions == null )
+ {
+ sessions = new IdentityHashSet();
+ managedSessions.put( serviceAddress, sessions );
+ firstSession = true;
+ }
+ }
+
+ // If already registered, ignore.
+ synchronized( sessions )
+ {
+ if ( !sessions.add( session ) )
+ {
+ return;
+ }
+ }
+
+ // If the first connector session, fire a virtual service activation event.
+ if( session.getService() instanceof IoConnector && firstSession )
+ {
+ fireServiceActivated(
+ session.getService(), session.getServiceAddress(),
+ session.getHandler(), session.getServiceConfig() );
+ }
+
+ // Fire session events.
+ session.getFilterChain().fireSessionCreated( session );
+ session.getFilterChain().fireSessionOpened( session);
+
+ // Fire listener events.
+ synchronized( listeners )
+ {
+ for( Iterator i = listeners.iterator(); i.hasNext(); )
+ {
+ ( ( IoServiceListener ) i.next() ).sessionCreated( session );
+ }
+ }
+ }
+
+ /**
+ * Calls {@link IoServiceListener#sessionDestroyed(IoSession)} for all registered listeners.
+ */
+ public void fireSessionDestroyed( IoSession session )
+ {
+ SocketAddress serviceAddress = session.getServiceAddress();
+
+ // Get the session set.
+ Set sessions;
+ boolean lastSession = false;
+ synchronized( managedSessions )
+ {
+ sessions = ( Set ) managedSessions.get( serviceAddress );
+ // Ignore if unknown.
+ if( sessions == null )
+ {
+ return;
+ }
+
+ // Try to remove the remaining empty seession set after removal.
+ synchronized( sessions )
+ {
+ sessions.remove( session );
+ if( sessions.isEmpty() )
+ {
+ managedSessions.remove( serviceAddress );
+ lastSession = true;
+ }
+ }
+ }
+
+ // Fire session events.
+ session.getFilterChain().fireSessionClosed( session );
+
+ // Fire listener events.
+ try
+ {
+ synchronized( listeners )
+ {
+ for( Iterator i = listeners.iterator(); i.hasNext(); )
+ {
+ ( ( IoServiceListener ) i.next() ).sessionDestroyed( session );
+ }
+ }
+ }
+ finally
+ {
+ // Fire a virtual service deactivation event for the last session of the connector.
+ //TODO double-check that this is *STILL* the last session. May not be the case
+ if( session.getService() instanceof IoConnector && lastSession )
+ {
+ fireServiceDeactivated(
+ session.getService(), session.getServiceAddress(),
+ session.getHandler(), session.getServiceConfig() );
+ }
+ }
+ }
+
+ private void disconnectSessions( SocketAddress serviceAddress, IoServiceConfig config )
+ {
+ if( !( config instanceof IoAcceptorConfig ) )
+ {
+ return;
+ }
+
+ if( !( ( IoAcceptorConfig ) config ).isDisconnectOnUnbind() )
+ {
+ return;
+ }
+
+ Set sessions;
+ synchronized( managedSessions )
+ {
+ sessions = ( Set ) managedSessions.get( serviceAddress );
+ }
+
+ if( sessions == null )
+ {
+ return;
+ }
+
+ Set sessionsCopy;
+
+ // Create a copy to avoid ConcurrentModificationException
+ synchronized( sessions )
+ {
+ sessionsCopy = new IdentityHashSet( sessions );
+ }
+
+ final CountDownLatch latch = new CountDownLatch(sessionsCopy.size());
+
+ for( Iterator i = sessionsCopy.iterator(); i.hasNext(); )
+ {
+ ( ( IoSession ) i.next() ).close().addListener( new IoFutureListener()
+ {
+ public void operationComplete( IoFuture future )
+ {
+ latch.countDown();
+ }
+ } );
+ }
+
+ try
+ {
+ latch.await();
+ }
+ catch( InterruptedException ie )
+ {
+ // Ignored
+ }
+ }
+}
diff --git a/qpid/java/common/src/main/java/org/apache/mina/filter/WriteBufferFullExeception.java b/qpid/java/common/src/main/java/org/apache/mina/filter/WriteBufferFullExeception.java
new file mode 100644
index 0000000000..47f19aa76d
--- /dev/null
+++ b/qpid/java/common/src/main/java/org/apache/mina/filter/WriteBufferFullExeception.java
@@ -0,0 +1,48 @@
+package org.apache.mina.filter;
+
+import org.apache.mina.common.IoFilter;/*
+ *
+ * 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.
+ *
+ */
+
+public class WriteBufferFullExeception extends RuntimeException
+{
+ private IoFilter.WriteRequest _writeRequest;
+
+ public WriteBufferFullExeception()
+ {
+ this(null);
+ }
+
+ public WriteBufferFullExeception(IoFilter.WriteRequest writeRequest)
+ {
+ _writeRequest = writeRequest;
+ }
+
+
+ public void setWriteRequest(IoFilter.WriteRequest writeRequest)
+ {
+ _writeRequest = writeRequest;
+ }
+
+ public IoFilter.WriteRequest getWriteRequest()
+ {
+ return _writeRequest;
+ }
+}
diff --git a/qpid/java/common/src/main/java/org/apache/mina/filter/WriteBufferLimitFilterBuilder.java b/qpid/java/common/src/main/java/org/apache/mina/filter/WriteBufferLimitFilterBuilder.java
new file mode 100644
index 0000000000..4e9db9071a
--- /dev/null
+++ b/qpid/java/common/src/main/java/org/apache/mina/filter/WriteBufferLimitFilterBuilder.java
@@ -0,0 +1,272 @@
+/*
+ * 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.mina.filter;
+
+import org.apache.mina.common.ByteBuffer;
+import org.apache.mina.common.DefaultIoFilterChainBuilder;
+import org.apache.mina.common.IoFilterAdapter;
+import org.apache.mina.common.IoFilterChain;
+import org.apache.mina.common.IoSession;
+import org.apache.mina.filter.executor.ExecutorFilter;
+
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * This filter will turn the asynchronous filterWrite method in to a blocking send when there are more than
+ * the prescribed number of messages awaiting filterWrite. It should be used in conjunction with the
+ * {@link ReadThrottleFilterBuilder} on a server as the blocking writes will allow the read thread to
+ * cause an Out of Memory exception due to a back log of unprocessed messages.
+ *
+ * This is should only be viewed as a temporary work around for DIRMINA-302.
+ *
+ * A true solution should not be implemented as a filter as this issue will always occur. On a machine
+ * where the network is slower than the local producer.
+ *
+ * Suggested improvement is to allow implementation of policices on what to do when buffer is full.
+ *
+ * They could be:
+ * Block - As this does
+ * Wait on a given Future - to drain more of the queue.. in essence this filter with high/low watermarks
+ * Throw Exception - through the client filterWrite() method to allow them to get immediate feedback on buffer state
+ *
+ * <p/>
+ * <p>Usage:
+ * <p/>
+ * <pre><code>
+ * DefaultFilterChainBuilder builder = ...
+ * WriteBufferLimitFilterBuilder filter = new WriteBufferLimitFilterBuilder();
+ * filter.attach( builder );
+ * </code></pre>
+ * <p/>
+ * or
+ * <p/>
+ * <pre><code>
+ * IoFilterChain chain = ...
+ * WriteBufferLimitFilterBuilder filter = new WriteBufferLimitFilterBuilder();
+ * filter.attach( chain );
+ * </code></pre>
+ *
+ * @author The Apache Directory Project (mina-dev@directory.apache.org)
+ * @version $Rev: 619823 $, $Date: 2008-02-08 10:09:37 +0000 (Fri, 08 Feb 2008) $
+ */
+public class WriteBufferLimitFilterBuilder
+{
+ public static final String PENDING_SIZE = WriteBufferLimitFilterBuilder.class.getName() + ".pendingSize";
+
+ private static int DEFAULT_CONNECTION_BUFFER_MESSAGE_COUNT = 5000;
+
+ private volatile boolean throwNotBlock = false;
+
+ private volatile int maximumConnectionBufferCount;
+ private volatile long maximumConnectionBufferSize;
+
+ private final Object _blockLock = new Object();
+
+ private int _blockWaiters = 0;
+
+
+ public WriteBufferLimitFilterBuilder()
+ {
+ this(DEFAULT_CONNECTION_BUFFER_MESSAGE_COUNT);
+ }
+
+ public WriteBufferLimitFilterBuilder(int maxWriteBufferSize)
+ {
+ setMaximumConnectionBufferCount(maxWriteBufferSize);
+ }
+
+
+ /**
+ * Set the maximum amount pending items in the writeQueue for a given session.
+ * Changing the value will only take effect when new data is received for a
+ * connection, including existing connections. Default value is 5000 msgs.
+ *
+ * @param maximumConnectionBufferCount New buffer size. Must be > 0
+ */
+ public void setMaximumConnectionBufferCount(int maximumConnectionBufferCount)
+ {
+ this.maximumConnectionBufferCount = maximumConnectionBufferCount;
+ this.maximumConnectionBufferSize = 0;
+ }
+
+ public void setMaximumConnectionBufferSize(long maximumConnectionBufferSize)
+ {
+ this.maximumConnectionBufferSize = maximumConnectionBufferSize;
+ this.maximumConnectionBufferCount = 0;
+ }
+
+ /**
+ * Attach this filter to the specified filter chain. It will search for the ThreadPoolFilter, and attach itself
+ * before and after that filter.
+ *
+ * @param chain {@link IoFilterChain} to attach self to.
+ */
+ public void attach(IoFilterChain chain)
+ {
+ String name = getThreadPoolFilterEntryName(chain.getAll());
+
+ chain.addBefore(name, getClass().getName() + ".sendlimit", new SendLimit());
+ }
+
+ /**
+ * Attach this filter to the specified builder. It will search for the
+ * {@link ExecutorFilter}, and attach itself before and after that filter.
+ *
+ * @param builder {@link DefaultIoFilterChainBuilder} to attach self to.
+ */
+ public void attach(DefaultIoFilterChainBuilder builder)
+ {
+ String name = getThreadPoolFilterEntryName(builder.getAll());
+
+ builder.addBefore(name, getClass().getName() + ".sendlimit", new SendLimit());
+ }
+
+ private String getThreadPoolFilterEntryName(List entries)
+ {
+ Iterator i = entries.iterator();
+
+ while (i.hasNext())
+ {
+ IoFilterChain.Entry entry = (IoFilterChain.Entry) i.next();
+
+ if (entry.getFilter().getClass().isAssignableFrom(ExecutorFilter.class))
+ {
+ return entry.getName();
+ }
+ }
+
+ throw new IllegalStateException("Chain does not contain a ExecutorFilter");
+ }
+
+
+ public class SendLimit extends IoFilterAdapter
+ {
+ public void filterWrite(NextFilter nextFilter, IoSession session, WriteRequest writeRequest) throws Exception
+ {
+ try
+ {
+ waitTillSendAllowed(session);
+ }
+ catch (WriteBufferFullExeception wbfe)
+ {
+ nextFilter.exceptionCaught(session, wbfe);
+ }
+
+ if (writeRequest.getMessage() instanceof ByteBuffer)
+ {
+ increasePendingWriteSize(session, (ByteBuffer) writeRequest.getMessage());
+ }
+
+ nextFilter.filterWrite(session, writeRequest);
+ }
+
+ private void increasePendingWriteSize(IoSession session, ByteBuffer message)
+ {
+ synchronized (session)
+ {
+ Long pendingSize = getScheduledWriteBytes(session) + message.remaining();
+ session.setAttribute(PENDING_SIZE, pendingSize);
+ }
+ }
+
+ private boolean sendAllowed(IoSession session)
+ {
+ if (session.isClosing())
+ {
+ return true;
+ }
+
+ int lmswm = maximumConnectionBufferCount;
+ long lmswb = maximumConnectionBufferSize;
+
+ return (lmswm == 0 || session.getScheduledWriteRequests() < lmswm)
+ && (lmswb == 0 || getScheduledWriteBytes(session) < lmswb);
+ }
+
+ private long getScheduledWriteBytes(IoSession session)
+ {
+ synchronized (session)
+ {
+ Long i = (Long) session.getAttribute(PENDING_SIZE);
+ return null == i ? 0 : i;
+ }
+ }
+
+ private void waitTillSendAllowed(IoSession session)
+ {
+ synchronized (_blockLock)
+ {
+ if (throwNotBlock)
+ {
+ throw new WriteBufferFullExeception();
+ }
+
+ _blockWaiters++;
+
+ while (!sendAllowed(session))
+ {
+ try
+ {
+ _blockLock.wait();
+ }
+ catch (InterruptedException e)
+ {
+ // Ignore.
+ }
+ }
+ _blockWaiters--;
+ }
+ }
+
+ public void messageSent(NextFilter nextFilter, IoSession session, Object message) throws Exception
+ {
+ if (message instanceof ByteBuffer)
+ {
+ decrementPendingWriteSize(session, (ByteBuffer) message);
+ }
+ notifyWaitingWriters();
+ nextFilter.messageSent(session, message);
+ }
+
+ private void decrementPendingWriteSize(IoSession session, ByteBuffer message)
+ {
+ synchronized (session)
+ {
+ session.setAttribute(PENDING_SIZE, getScheduledWriteBytes(session) - message.remaining());
+ }
+ }
+
+ private void notifyWaitingWriters()
+ {
+ synchronized (_blockLock)
+ {
+ if (_blockWaiters != 0)
+ {
+ _blockLock.notifyAll();
+ }
+ }
+
+ }
+
+ }//SentLimit
+
+
+}
diff --git a/qpid/java/common/src/main/java/org/apache/mina/filter/codec/OurCumulativeProtocolDecoder.java b/qpid/java/common/src/main/java/org/apache/mina/filter/codec/OurCumulativeProtocolDecoder.java
new file mode 100644
index 0000000000..3f7e206cb4
--- /dev/null
+++ b/qpid/java/common/src/main/java/org/apache/mina/filter/codec/OurCumulativeProtocolDecoder.java
@@ -0,0 +1,197 @@
+/*
+ * 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.mina.filter.codec;
+
+import org.apache.mina.common.ByteBuffer;
+import org.apache.mina.common.IoSession;
+
+/**
+ * A {@link ProtocolDecoder} that cumulates the content of received
+ * buffers to a <em>cumulative buffer</em> to help users implement decoders.
+ * <p>
+ * If the received {@link ByteBuffer} is only a part of a message.
+ * decoders should cumulate received buffers to make a message complete or
+ * to postpone decoding until more buffers arrive.
+ * <p>
+ * Here is an example decoder that decodes CRLF terminated lines into
+ * <code>Command</code> objects:
+ * <pre>
+ * public class CRLFTerminatedCommandLineDecoder
+ * extends CumulativeProtocolDecoder {
+ *
+ * private Command parseCommand(ByteBuffer in) {
+ * // Convert the bytes in the specified buffer to a
+ * // Command object.
+ * ...
+ * }
+ *
+ * protected boolean doDecode(IoSession session, ByteBuffer in,
+ * ProtocolDecoderOutput out)
+ * throws Exception {
+ *
+ * // Remember the initial position.
+ * int start = in.position();
+ *
+ * // Now find the first CRLF in the buffer.
+ * byte previous = 0;
+ * while (in.hasRemaining()) {
+ * byte current = in.get();
+ *
+ * if (previous == '\r' && current == '\n') {
+ * // Remember the current position and limit.
+ * int position = in.position();
+ * int limit = in.limit();
+ * try {
+ * in.position(start);
+ * in.limit(position);
+ * // The bytes between in.position() and in.limit()
+ * // now contain a full CRLF terminated line.
+ * out.write(parseCommand(in.slice()));
+ * } finally {
+ * // Set the position to point right after the
+ * // detected line and set the limit to the old
+ * // one.
+ * in.position(position);
+ * in.limit(limit);
+ * }
+ * // Decoded one line; CumulativeProtocolDecoder will
+ * // call me again until I return false. So just
+ * // return true until there are no more lines in the
+ * // buffer.
+ * return true;
+ * }
+ *
+ * previous = current;
+ * }
+ *
+ * // Could not find CRLF in the buffer. Reset the initial
+ * // position to the one we recorded above.
+ * in.position(start);
+ *
+ * return false;
+ * }
+ * }
+ * </pre>
+ *
+ * @author The Apache Directory Project (mina-dev@directory.apache.org)
+ * @version $Rev: 619823 $, $Date: 2008-02-08 10:09:37 +0000 (Fri, 08 Feb 2008) $
+ */
+public abstract class OurCumulativeProtocolDecoder extends ProtocolDecoderAdapter {
+
+ private static final String BUFFER = OurCumulativeProtocolDecoder.class
+ .getName()
+ + ".Buffer";
+
+ /**
+ * Creates a new instance.
+ */
+ protected OurCumulativeProtocolDecoder() {
+ }
+
+ /**
+ * Cumulates content of <tt>in</tt> into internal buffer and forwards
+ * decoding request to {@link #doDecode(IoSession, ByteBuffer, ProtocolDecoderOutput)}.
+ * <tt>doDecode()</tt> is invoked repeatedly until it returns <tt>false</tt>
+ * and the cumulative buffer is NOT compacted after decoding ends.
+ *
+ * @throws IllegalStateException if your <tt>doDecode()</tt> returned
+ * <tt>true</tt> not consuming the cumulative buffer.
+ */
+ public void decode(IoSession session, ByteBuffer in,
+ ProtocolDecoderOutput out) throws Exception {
+ boolean usingSessionBuffer = true;
+ ByteBuffer buf = (ByteBuffer) session.getAttribute(BUFFER);
+ // If we have a session buffer, append data to that; otherwise
+ // use the buffer read from the network directly.
+ if (buf != null) {
+ buf.put(in);
+ buf.flip();
+ } else {
+ buf = in;
+ usingSessionBuffer = false;
+ }
+
+ for (;;) {
+ int oldPos = buf.position();
+ boolean decoded = doDecode(session, buf, out);
+ if (decoded) {
+ if (buf.position() == oldPos) {
+ throw new IllegalStateException(
+ "doDecode() can't return true when buffer is not consumed.");
+ }
+
+ if (!buf.hasRemaining()) {
+ break;
+ }
+ } else {
+ break;
+ }
+ }
+
+
+ // if there is any data left that cannot be decoded, we store
+ // it in a buffer in the session and next time this decoder is
+ // invoked the session buffer gets appended to
+ if (buf.hasRemaining()) {
+ storeRemainingInSession(buf, session);
+ } else {
+ if (usingSessionBuffer)
+ removeSessionBuffer(session);
+ }
+ }
+
+ /**
+ * Implement this method to consume the specified cumulative buffer and
+ * decode its content into message(s).
+ *
+ * @param in the cumulative buffer
+ * @return <tt>true</tt> if and only if there's more to decode in the buffer
+ * and you want to have <tt>doDecode</tt> method invoked again.
+ * Return <tt>false</tt> if remaining data is not enough to decode,
+ * then this method will be invoked again when more data is cumulated.
+ * @throws Exception if cannot decode <tt>in</tt>.
+ */
+ protected abstract boolean doDecode(IoSession session, ByteBuffer in,
+ ProtocolDecoderOutput out) throws Exception;
+
+ /**
+ * Releases the cumulative buffer used by the specified <tt>session</tt>.
+ * Please don't forget to call <tt>super.dispose( session )</tt> when
+ * you override this method.
+ */
+ public void dispose(IoSession session) throws Exception {
+ removeSessionBuffer(session);
+ }
+
+ private void removeSessionBuffer(IoSession session) {
+ ByteBuffer buf = (ByteBuffer) session.removeAttribute(BUFFER);
+ if (buf != null) {
+ buf.release();
+ }
+ }
+
+ private void storeRemainingInSession(ByteBuffer buf, IoSession session) {
+ ByteBuffer remainingBuf = ByteBuffer.allocate(buf.capacity());
+ remainingBuf.setAutoExpand(true);
+ remainingBuf.order(buf.order());
+ remainingBuf.put(buf);
+ session.setAttribute(BUFFER, remainingBuf);
+ }
+}
diff --git a/qpid/java/common/src/main/java/org/apache/mina/filter/codec/QpidProtocolCodecFilter.java b/qpid/java/common/src/main/java/org/apache/mina/filter/codec/QpidProtocolCodecFilter.java
new file mode 100644
index 0000000000..b8c6f29720
--- /dev/null
+++ b/qpid/java/common/src/main/java/org/apache/mina/filter/codec/QpidProtocolCodecFilter.java
@@ -0,0 +1,440 @@
+package org.apache.mina.filter.codec;
+
+
+/*
+*
+* 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 org.apache.mina.common.*;
+import org.apache.mina.common.support.DefaultWriteFuture;
+import org.apache.mina.filter.codec.support.SimpleProtocolDecoderOutput;
+import org.apache.mina.util.SessionLog;
+import org.apache.mina.util.Queue;
+
+
+public class QpidProtocolCodecFilter extends IoFilterAdapter
+{
+ public static final String ENCODER = QpidProtocolCodecFilter.class.getName() + ".encoder";
+ public static final String DECODER = QpidProtocolCodecFilter.class.getName() + ".decoder";
+
+ private static final Class[] EMPTY_PARAMS = new Class[0];
+ private static final ByteBuffer EMPTY_BUFFER = ByteBuffer.wrap( new byte[0] );
+
+ private final ProtocolCodecFactory factory;
+
+ public QpidProtocolCodecFilter( ProtocolCodecFactory factory )
+ {
+ if( factory == null )
+ {
+ throw new NullPointerException( "factory" );
+ }
+ this.factory = factory;
+ }
+
+ public QpidProtocolCodecFilter( final ProtocolEncoder encoder, final ProtocolDecoder decoder )
+ {
+ if( encoder == null )
+ {
+ throw new NullPointerException( "encoder" );
+ }
+ if( decoder == null )
+ {
+ throw new NullPointerException( "decoder" );
+ }
+
+ this.factory = new ProtocolCodecFactory()
+ {
+ public ProtocolEncoder getEncoder()
+ {
+ return encoder;
+ }
+
+ public ProtocolDecoder getDecoder()
+ {
+ return decoder;
+ }
+ };
+ }
+
+ public QpidProtocolCodecFilter( final Class encoderClass, final Class decoderClass )
+ {
+ if( encoderClass == null )
+ {
+ throw new NullPointerException( "encoderClass" );
+ }
+ if( decoderClass == null )
+ {
+ throw new NullPointerException( "decoderClass" );
+ }
+ if( !ProtocolEncoder.class.isAssignableFrom( encoderClass ) )
+ {
+ throw new IllegalArgumentException( "encoderClass: " + encoderClass.getName() );
+ }
+ if( !ProtocolDecoder.class.isAssignableFrom( decoderClass ) )
+ {
+ throw new IllegalArgumentException( "decoderClass: " + decoderClass.getName() );
+ }
+ try
+ {
+ encoderClass.getConstructor( EMPTY_PARAMS );
+ }
+ catch( NoSuchMethodException e )
+ {
+ throw new IllegalArgumentException( "encoderClass doesn't have a public default constructor." );
+ }
+ try
+ {
+ decoderClass.getConstructor( EMPTY_PARAMS );
+ }
+ catch( NoSuchMethodException e )
+ {
+ throw new IllegalArgumentException( "decoderClass doesn't have a public default constructor." );
+ }
+
+ this.factory = new ProtocolCodecFactory()
+ {
+ public ProtocolEncoder getEncoder() throws Exception
+ {
+ return ( ProtocolEncoder ) encoderClass.newInstance();
+ }
+
+ public ProtocolDecoder getDecoder() throws Exception
+ {
+ return ( ProtocolDecoder ) decoderClass.newInstance();
+ }
+ };
+ }
+
+ public void onPreAdd( IoFilterChain parent, String name, IoFilter.NextFilter nextFilter ) throws Exception
+ {
+ if( parent.contains( ProtocolCodecFilter.class ) )
+ {
+ throw new IllegalStateException( "A filter chain cannot contain more than one QpidProtocolCodecFilter." );
+ }
+ }
+
+ public void messageReceived( IoFilter.NextFilter nextFilter, IoSession session, Object message ) throws Exception
+ {
+ if( !( message instanceof ByteBuffer ) )
+ {
+ nextFilter.messageReceived( session, message );
+ return;
+ }
+
+ ByteBuffer in = ( ByteBuffer ) message;
+ ProtocolDecoder decoder = getDecoder( session );
+ ProtocolDecoderOutput decoderOut = getDecoderOut( session, nextFilter );
+
+ try
+ {
+ decoder.decode( session, in, decoderOut );
+ }
+ catch( Throwable t )
+ {
+ ProtocolDecoderException pde;
+ if( t instanceof ProtocolDecoderException )
+ {
+ pde = ( ProtocolDecoderException ) t;
+ }
+ else
+ {
+ pde = new ProtocolDecoderException( t );
+ }
+ pde.setHexdump( in.getHexDump() );
+ throw pde;
+ }
+ finally
+ {
+ // Dispose the decoder if this session is connectionless.
+ if( session.getTransportType().isConnectionless() )
+ {
+ disposeDecoder( session );
+ }
+
+ // Release the read buffer.
+ in.release();
+
+ decoderOut.flush();
+ }
+ }
+
+ public void messageSent( IoFilter.NextFilter nextFilter, IoSession session, Object message ) throws Exception
+ {
+ if( message instanceof HiddenByteBuffer )
+ {
+ return;
+ }
+
+ if( !( message instanceof MessageByteBuffer ) )
+ {
+ nextFilter.messageSent( session, message );
+ return;
+ }
+
+ nextFilter.messageSent( session, ( ( MessageByteBuffer ) message ).message );
+ }
+
+ public void filterWrite( IoFilter.NextFilter nextFilter, IoSession session, IoFilter.WriteRequest writeRequest ) throws Exception
+ {
+ Object message = writeRequest.getMessage();
+ if( message instanceof ByteBuffer )
+ {
+ nextFilter.filterWrite( session, writeRequest );
+ return;
+ }
+
+ ProtocolEncoder encoder = getEncoder( session );
+ ProtocolEncoderOutputImpl encoderOut = getEncoderOut( session, nextFilter, writeRequest );
+
+ try
+ {
+ encoder.encode( session, message, encoderOut );
+ encoderOut.flush();
+ nextFilter.filterWrite(
+ session,
+ new IoFilter.WriteRequest(
+ new MessageByteBuffer( writeRequest.getMessage() ),
+ writeRequest.getFuture(), writeRequest.getDestination() ) );
+ }
+ catch( Throwable t )
+ {
+ ProtocolEncoderException pee;
+ if( t instanceof ProtocolEncoderException )
+ {
+ pee = ( ProtocolEncoderException ) t;
+ }
+ else
+ {
+ pee = new ProtocolEncoderException( t );
+ }
+ throw pee;
+ }
+ finally
+ {
+ // Dispose the encoder if this session is connectionless.
+ if( session.getTransportType().isConnectionless() )
+ {
+ disposeEncoder( session );
+ }
+ }
+ }
+
+ public void sessionClosed( IoFilter.NextFilter nextFilter, IoSession session ) throws Exception
+ {
+ // Call finishDecode() first when a connection is closed.
+ ProtocolDecoder decoder = getDecoder( session );
+ ProtocolDecoderOutput decoderOut = getDecoderOut( session, nextFilter );
+ try
+ {
+ decoder.finishDecode( session, decoderOut );
+ }
+ catch( Throwable t )
+ {
+ ProtocolDecoderException pde;
+ if( t instanceof ProtocolDecoderException )
+ {
+ pde = ( ProtocolDecoderException ) t;
+ }
+ else
+ {
+ pde = new ProtocolDecoderException( t );
+ }
+ throw pde;
+ }
+ finally
+ {
+ // Dispose all.
+ disposeEncoder( session );
+ disposeDecoder( session );
+
+ decoderOut.flush();
+ }
+
+ nextFilter.sessionClosed( session );
+ }
+
+ private ProtocolEncoder getEncoder( IoSession session ) throws Exception
+ {
+ ProtocolEncoder encoder = ( ProtocolEncoder ) session.getAttribute( ENCODER );
+ if( encoder == null )
+ {
+ encoder = factory.getEncoder();
+ session.setAttribute( ENCODER, encoder );
+ }
+ return encoder;
+ }
+
+ private ProtocolEncoderOutputImpl getEncoderOut( IoSession session, IoFilter.NextFilter nextFilter, IoFilter.WriteRequest writeRequest )
+ {
+ return new ProtocolEncoderOutputImpl( session, nextFilter, writeRequest );
+ }
+
+ private ProtocolDecoder getDecoder( IoSession session ) throws Exception
+ {
+ ProtocolDecoder decoder = ( ProtocolDecoder ) session.getAttribute( DECODER );
+ if( decoder == null )
+ {
+ decoder = factory.getDecoder();
+ session.setAttribute( DECODER, decoder );
+ }
+ return decoder;
+ }
+
+ private ProtocolDecoderOutput getDecoderOut( IoSession session, IoFilter.NextFilter nextFilter )
+ {
+ return new SimpleProtocolDecoderOutput( session, nextFilter );
+ }
+
+ private void disposeEncoder( IoSession session )
+ {
+ ProtocolEncoder encoder = ( ProtocolEncoder ) session.removeAttribute( ENCODER );
+ if( encoder == null )
+ {
+ return;
+ }
+
+ try
+ {
+ encoder.dispose( session );
+ }
+ catch( Throwable t )
+ {
+ SessionLog.warn(
+ session,
+ "Failed to dispose: " + encoder.getClass().getName() +
+ " (" + encoder + ')' );
+ }
+ }
+
+ private void disposeDecoder( IoSession session )
+ {
+ ProtocolDecoder decoder = ( ProtocolDecoder ) session.removeAttribute( DECODER );
+ if( decoder == null )
+ {
+ return;
+ }
+
+ try
+ {
+ decoder.dispose( session );
+ }
+ catch( Throwable t )
+ {
+ SessionLog.warn(
+ session,
+ "Falied to dispose: " + decoder.getClass().getName() +
+ " (" + decoder + ')' );
+ }
+ }
+
+ private static class HiddenByteBuffer extends ByteBufferProxy
+ {
+ private HiddenByteBuffer( ByteBuffer buf )
+ {
+ super( buf );
+ }
+ }
+
+ private static class MessageByteBuffer extends ByteBufferProxy
+ {
+ private final Object message;
+
+ private MessageByteBuffer( Object message )
+ {
+ super( EMPTY_BUFFER );
+ this.message = message;
+ }
+
+ public void acquire()
+ {
+ // no-op since we are wraping a zero-byte buffer, this instance is to just curry the message
+ }
+
+ public void release()
+ {
+ // no-op since we are wraping a zero-byte buffer, this instance is to just curry the message
+ }
+ }
+
+ private static class ProtocolEncoderOutputImpl implements ProtocolEncoderOutput
+ {
+ private ByteBuffer buffer;
+
+ private final IoSession session;
+ private final IoFilter.NextFilter nextFilter;
+ private final IoFilter.WriteRequest writeRequest;
+
+ public ProtocolEncoderOutputImpl( IoSession session, IoFilter.NextFilter nextFilter, IoFilter.WriteRequest writeRequest )
+ {
+ this.session = session;
+ this.nextFilter = nextFilter;
+ this.writeRequest = writeRequest;
+ }
+
+
+
+ public void write( ByteBuffer buf )
+ {
+ if(buffer != null)
+ {
+ flush();
+ }
+ buffer = buf;
+ }
+
+ public void mergeAll()
+ {
+ }
+
+ public WriteFuture flush()
+ {
+ WriteFuture future = null;
+ if( buffer == null )
+ {
+ return null;
+ }
+ else
+ {
+ ByteBuffer buf = buffer;
+ // Flush only when the buffer has remaining.
+ if( buf.hasRemaining() )
+ {
+ future = doFlush( buf );
+ }
+
+ }
+
+ return future;
+ }
+
+
+ protected WriteFuture doFlush( ByteBuffer buf )
+ {
+ WriteFuture future = new DefaultWriteFuture( session );
+ nextFilter.filterWrite(
+ session,
+ new IoFilter.WriteRequest(
+ buf,
+ future, writeRequest.getDestination() ) );
+ return future;
+ }
+ }
+}
+
diff --git a/qpid/java/common/src/main/java/org/apache/mina/transport/socket/nio/MultiThreadSocketAcceptor.java b/qpid/java/common/src/main/java/org/apache/mina/transport/socket/nio/MultiThreadSocketAcceptor.java
new file mode 100644
index 0000000000..e5360d32e0
--- /dev/null
+++ b/qpid/java/common/src/main/java/org/apache/mina/transport/socket/nio/MultiThreadSocketAcceptor.java
@@ -0,0 +1,547 @@
+/*
+ * 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.mina.transport.socket.nio;
+
+import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.net.SocketAddress;
+import java.nio.channels.SelectionKey;
+import java.nio.channels.Selector;
+import java.nio.channels.ServerSocketChannel;
+import java.nio.channels.SocketChannel;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.mina.common.ExceptionMonitor;
+import org.apache.mina.common.IoAcceptor;
+import org.apache.mina.common.IoHandler;
+import org.apache.mina.common.IoServiceConfig;
+import org.apache.mina.common.support.BaseIoAcceptor;
+import org.apache.mina.util.Queue;
+import org.apache.mina.util.NewThreadExecutor;
+import org.apache.mina.util.NamePreservingRunnable;
+import edu.emory.mathcs.backport.java.util.concurrent.Executor;
+
+/**
+ * {@link IoAcceptor} for socket transport (TCP/IP).
+ *
+ * @author The Apache Directory Project (mina-dev@directory.apache.org)
+ * @version $Rev: 619823 $, $Date: 2008-02-08 10:09:37 +0000 (Fri, 08 Feb 2008) $
+ */
+public class MultiThreadSocketAcceptor extends SocketAcceptor
+{
+ /**
+ * @noinspection StaticNonFinalField
+ */
+ private static volatile int nextId = 0;
+
+ private final Executor executor;
+ private final Object lock = new Object();
+ private final int id = nextId ++;
+ private final String threadName = "SocketAcceptor-" + id;
+ private final Map channels = new HashMap();
+
+ private final Queue registerQueue = new Queue();
+ private final Queue cancelQueue = new Queue();
+
+ private final MultiThreadSocketIoProcessor[] ioProcessors;
+ private final int processorCount;
+
+ /**
+ * @noinspection FieldAccessedSynchronizedAndUnsynchronized
+ */
+ private Selector selector;
+ private Worker worker;
+ private int processorDistributor = 0;
+
+ /**
+ * Create an acceptor with a single processing thread using a NewThreadExecutor
+ */
+ public MultiThreadSocketAcceptor()
+ {
+ this( 1, new NewThreadExecutor() );
+ }
+
+ /**
+ * Create an acceptor with the desired number of processing threads
+ *
+ * @param processorCount Number of processing threads
+ * @param executor Executor to use for launching threads
+ */
+ public MultiThreadSocketAcceptor( int processorCount, Executor executor )
+ {
+ if( processorCount < 1 )
+ {
+ throw new IllegalArgumentException( "Must have at least one processor" );
+ }
+
+ this.executor = executor;
+ this.processorCount = processorCount;
+ ioProcessors = new MultiThreadSocketIoProcessor[processorCount];
+
+ for( int i = 0; i < processorCount; i++ )
+ {
+ ioProcessors[i] = new MultiThreadSocketIoProcessor( "SocketAcceptorIoProcessor-" + id + "." + i, executor );
+ }
+ }
+
+
+ /**
+ * Binds to the specified <code>address</code> and handles incoming connections with the specified
+ * <code>handler</code>. Backlog value is configured to the value of <code>backlog</code> property.
+ *
+ * @throws IOException if failed to bind
+ */
+ public void bind( SocketAddress address, IoHandler handler, IoServiceConfig config ) throws IOException
+ {
+ if( handler == null )
+ {
+ throw new NullPointerException( "handler" );
+ }
+
+ if( address != null && !( address instanceof InetSocketAddress ) )
+ {
+ throw new IllegalArgumentException( "Unexpected address type: " + address.getClass() );
+ }
+
+ if( config == null )
+ {
+ config = getDefaultConfig();
+ }
+
+ RegistrationRequest request = new RegistrationRequest( address, handler, config );
+
+ synchronized( registerQueue )
+ {
+ registerQueue.push( request );
+ }
+
+ startupWorker();
+
+ selector.wakeup();
+
+ synchronized( request )
+ {
+ while( !request.done )
+ {
+ try
+ {
+ request.wait();
+ }
+ catch( InterruptedException e )
+ {
+ ExceptionMonitor.getInstance().exceptionCaught( e );
+ }
+ }
+ }
+
+ if( request.exception != null )
+ {
+ throw request.exception;
+ }
+ }
+
+
+ private synchronized void startupWorker() throws IOException
+ {
+ synchronized( lock )
+ {
+ if( worker == null )
+ {
+ selector = Selector.open();
+ worker = new Worker();
+
+ executor.execute( new NamePreservingRunnable( worker ) );
+ }
+ }
+ }
+
+ public void unbind( SocketAddress address )
+ {
+ if( address == null )
+ {
+ throw new NullPointerException( "address" );
+ }
+
+ CancellationRequest request = new CancellationRequest( address );
+
+ try
+ {
+ startupWorker();
+ }
+ catch( IOException e )
+ {
+ // IOException is thrown only when Worker thread is not
+ // running and failed to open a selector. We simply throw
+ // IllegalArgumentException here because we can simply
+ // conclude that nothing is bound to the selector.
+ throw new IllegalArgumentException( "Address not bound: " + address );
+ }
+
+ synchronized( cancelQueue )
+ {
+ cancelQueue.push( request );
+ }
+
+ selector.wakeup();
+
+ synchronized( request )
+ {
+ while( !request.done )
+ {
+ try
+ {
+ request.wait();
+ }
+ catch( InterruptedException e )
+ {
+ ExceptionMonitor.getInstance().exceptionCaught( e );
+ }
+ }
+ }
+
+ if( request.exception != null )
+ {
+ request.exception.fillInStackTrace();
+
+ throw request.exception;
+ }
+ }
+
+
+ private class Worker implements Runnable
+ {
+ public void run()
+ {
+ Thread.currentThread().setName(MultiThreadSocketAcceptor.this.threadName );
+
+ for( ; ; )
+ {
+ try
+ {
+ int nKeys = selector.select();
+
+ registerNew();
+
+ if( nKeys > 0 )
+ {
+ processSessions( selector.selectedKeys() );
+ }
+
+ cancelKeys();
+
+ if( selector.keys().isEmpty() )
+ {
+ synchronized( lock )
+ {
+ if( selector.keys().isEmpty() &&
+ registerQueue.isEmpty() &&
+ cancelQueue.isEmpty() )
+ {
+ worker = null;
+ try
+ {
+ selector.close();
+ }
+ catch( IOException e )
+ {
+ ExceptionMonitor.getInstance().exceptionCaught( e );
+ }
+ finally
+ {
+ selector = null;
+ }
+ break;
+ }
+ }
+ }
+ }
+ catch( IOException e )
+ {
+ ExceptionMonitor.getInstance().exceptionCaught( e );
+
+ try
+ {
+ Thread.sleep( 1000 );
+ }
+ catch( InterruptedException e1 )
+ {
+ ExceptionMonitor.getInstance().exceptionCaught( e1 );
+ }
+ }
+ }
+ }
+
+ private void processSessions( Set keys ) throws IOException
+ {
+ Iterator it = keys.iterator();
+ while( it.hasNext() )
+ {
+ SelectionKey key = ( SelectionKey ) it.next();
+
+ it.remove();
+
+ if( !key.isAcceptable() )
+ {
+ continue;
+ }
+
+ ServerSocketChannel ssc = ( ServerSocketChannel ) key.channel();
+
+ SocketChannel ch = ssc.accept();
+
+ if( ch == null )
+ {
+ continue;
+ }
+
+ boolean success = false;
+ try
+ {
+
+ RegistrationRequest req = ( RegistrationRequest ) key.attachment();
+
+ MultiThreadSocketSessionImpl session = new MultiThreadSocketSessionImpl(
+ MultiThreadSocketAcceptor.this, nextProcessor(), getListeners(),
+ req.config, ch, req.handler, req.address );
+
+ // New Interface
+// SocketSessionImpl session = new SocketSessionImpl(
+// SocketAcceptor.this, nextProcessor(), getListeners(),
+// req.config, ch, req.handler, req.address );
+
+
+ getFilterChainBuilder().buildFilterChain( session.getFilterChain() );
+ req.config.getFilterChainBuilder().buildFilterChain( session.getFilterChain() );
+ req.config.getThreadModel().buildFilterChain( session.getFilterChain() );
+ session.getIoProcessor().addNew( session );
+ success = true;
+ }
+ catch( Throwable t )
+ {
+ ExceptionMonitor.getInstance().exceptionCaught( t );
+ }
+ finally
+ {
+ if( !success )
+ {
+ ch.close();
+ }
+ }
+ }
+ }
+ }
+
+ private MultiThreadSocketIoProcessor nextProcessor()
+ {
+ return ioProcessors[processorDistributor++ % processorCount];
+ }
+
+
+ private void registerNew()
+ {
+ if( registerQueue.isEmpty() )
+ {
+ return;
+ }
+
+ for( ; ; )
+ {
+ RegistrationRequest req;
+
+ synchronized( registerQueue )
+ {
+ req = ( RegistrationRequest ) registerQueue.pop();
+ }
+
+ if( req == null )
+ {
+ break;
+ }
+
+ ServerSocketChannel ssc = null;
+
+ try
+ {
+ ssc = ServerSocketChannel.open();
+ ssc.configureBlocking( false );
+
+ // Configure the server socket,
+ SocketAcceptorConfig cfg;
+ if( req.config instanceof SocketAcceptorConfig )
+ {
+ cfg = ( SocketAcceptorConfig ) req.config;
+ }
+ else
+ {
+ cfg = ( SocketAcceptorConfig ) getDefaultConfig();
+ }
+
+ ssc.socket().setReuseAddress( cfg.isReuseAddress() );
+ ssc.socket().setReceiveBufferSize(
+ ( ( SocketSessionConfig ) cfg.getSessionConfig() ).getReceiveBufferSize() );
+
+ // and bind.
+ ssc.socket().bind( req.address, cfg.getBacklog() );
+ if( req.address == null || req.address.getPort() == 0 )
+ {
+ req.address = ( InetSocketAddress ) ssc.socket().getLocalSocketAddress();
+ }
+ ssc.register( selector, SelectionKey.OP_ACCEPT, req );
+
+ synchronized( channels )
+ {
+ channels.put( req.address, ssc );
+ }
+
+ getListeners().fireServiceActivated(
+ this, req.address, req.handler, req.config );
+ }
+ catch( IOException e )
+ {
+ req.exception = e;
+ }
+ finally
+ {
+ synchronized( req )
+ {
+ req.done = true;
+
+ req.notifyAll();
+ }
+
+ if( ssc != null && req.exception != null )
+ {
+ try
+ {
+ ssc.close();
+ }
+ catch( IOException e )
+ {
+ ExceptionMonitor.getInstance().exceptionCaught( e );
+ }
+ }
+ }
+ }
+ }
+
+
+ private void cancelKeys()
+ {
+ if( cancelQueue.isEmpty() )
+ {
+ return;
+ }
+
+ for( ; ; )
+ {
+ CancellationRequest request;
+
+ synchronized( cancelQueue )
+ {
+ request = ( CancellationRequest ) cancelQueue.pop();
+ }
+
+ if( request == null )
+ {
+ break;
+ }
+
+ ServerSocketChannel ssc;
+ synchronized( channels )
+ {
+ ssc = ( ServerSocketChannel ) channels.remove( request.address );
+ }
+
+ // close the channel
+ try
+ {
+ if( ssc == null )
+ {
+ request.exception = new IllegalArgumentException( "Address not bound: " + request.address );
+ }
+ else
+ {
+ SelectionKey key = ssc.keyFor( selector );
+ request.registrationRequest = ( RegistrationRequest ) key.attachment();
+ key.cancel();
+
+ selector.wakeup(); // wake up again to trigger thread death
+
+ ssc.close();
+ }
+ }
+ catch( IOException e )
+ {
+ ExceptionMonitor.getInstance().exceptionCaught( e );
+ }
+ finally
+ {
+ synchronized( request )
+ {
+ request.done = true;
+ request.notifyAll();
+ }
+
+ if( request.exception == null )
+ {
+ getListeners().fireServiceDeactivated(
+ this, request.address,
+ request.registrationRequest.handler,
+ request.registrationRequest.config );
+ }
+ }
+ }
+ }
+
+ private static class RegistrationRequest
+ {
+ private InetSocketAddress address;
+ private final IoHandler handler;
+ private final IoServiceConfig config;
+ private IOException exception;
+ private boolean done;
+
+ private RegistrationRequest( SocketAddress address, IoHandler handler, IoServiceConfig config )
+ {
+ this.address = ( InetSocketAddress ) address;
+ this.handler = handler;
+ this.config = config;
+ }
+ }
+
+
+ private static class CancellationRequest
+ {
+ private final SocketAddress address;
+ private boolean done;
+ private RegistrationRequest registrationRequest;
+ private RuntimeException exception;
+
+ private CancellationRequest( SocketAddress address )
+ {
+ this.address = address;
+ }
+ }
+}
diff --git a/qpid/java/common/src/main/java/org/apache/mina/transport/socket/nio/MultiThreadSocketConnector.java b/qpid/java/common/src/main/java/org/apache/mina/transport/socket/nio/MultiThreadSocketConnector.java
new file mode 100644
index 0000000000..7344f70078
--- /dev/null
+++ b/qpid/java/common/src/main/java/org/apache/mina/transport/socket/nio/MultiThreadSocketConnector.java
@@ -0,0 +1,486 @@
+/*
+ * 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.mina.transport.socket.nio;
+
+import edu.emory.mathcs.backport.java.util.concurrent.Executor;
+import org.apache.mina.common.ConnectFuture;
+import org.apache.mina.common.ExceptionMonitor;
+import org.apache.mina.common.IoConnector;
+import org.apache.mina.common.IoConnectorConfig;
+import org.apache.mina.common.IoHandler;
+import org.apache.mina.common.IoServiceConfig;
+import org.apache.mina.common.support.AbstractIoFilterChain;
+import org.apache.mina.common.support.DefaultConnectFuture;
+import org.apache.mina.util.NamePreservingRunnable;
+import org.apache.mina.util.NewThreadExecutor;
+import org.apache.mina.util.Queue;
+
+import java.io.IOException;
+import java.net.ConnectException;
+import java.net.InetSocketAddress;
+import java.net.SocketAddress;
+import java.nio.channels.SelectionKey;
+import java.nio.channels.Selector;
+import java.nio.channels.SocketChannel;
+import java.util.Iterator;
+import java.util.Set;
+
+/**
+ * {@link IoConnector} for socket transport (TCP/IP).
+ *
+ * @author The Apache Directory Project (mina-dev@directory.apache.org)
+ * @version $Rev: 619823 $, $Date: 2008-02-08 10:09:37 +0000 (Fri, 08 Feb 2008) $
+ */
+public class MultiThreadSocketConnector extends SocketConnector
+{
+ /** @noinspection StaticNonFinalField */
+ private static volatile int nextId = 0;
+
+ private final Object lock = new Object();
+ private final int id = nextId++;
+ private final String threadName = "SocketConnector-" + id;
+
+ private final Queue connectQueue = new Queue();
+ private final MultiThreadSocketIoProcessor[] ioProcessors;
+ private final int processorCount;
+ private final Executor executor;
+
+ /** @noinspection FieldAccessedSynchronizedAndUnsynchronized */
+ private Selector selector;
+ private Worker worker;
+ private int processorDistributor = 0;
+ private int workerTimeout = 60; // 1 min.
+
+ /** Create a connector with a single processing thread using a NewThreadExecutor */
+ public MultiThreadSocketConnector()
+ {
+ this(1, new NewThreadExecutor());
+ }
+
+ /**
+ * Create a connector with the desired number of processing threads
+ *
+ * @param processorCount Number of processing threads
+ * @param executor Executor to use for launching threads
+ */
+ public MultiThreadSocketConnector(int processorCount, Executor executor)
+ {
+ if (processorCount < 1)
+ {
+ throw new IllegalArgumentException("Must have at least one processor");
+ }
+
+ this.executor = executor;
+ this.processorCount = processorCount;
+ ioProcessors = new MultiThreadSocketIoProcessor[processorCount];
+
+ for (int i = 0; i < processorCount; i++)
+ {
+ ioProcessors[i] = new MultiThreadSocketIoProcessor("SocketConnectorIoProcessor-" + id + "." + i, executor);
+ }
+ }
+
+ /**
+ * How many seconds to keep the connection thread alive between connection requests
+ *
+ * @return Number of seconds to keep connection thread alive
+ */
+ public int getWorkerTimeout()
+ {
+ return workerTimeout;
+ }
+
+ /**
+ * Set how many seconds the connection worker thread should remain alive once idle before terminating itself.
+ *
+ * @param workerTimeout Number of seconds to keep thread alive. Must be >=0
+ */
+ public void setWorkerTimeout(int workerTimeout)
+ {
+ if (workerTimeout < 0)
+ {
+ throw new IllegalArgumentException("Must be >= 0");
+ }
+ this.workerTimeout = workerTimeout;
+ }
+
+ public ConnectFuture connect(SocketAddress address, IoHandler handler, IoServiceConfig config)
+ {
+ return connect(address, null, handler, config);
+ }
+
+ public ConnectFuture connect(SocketAddress address, SocketAddress localAddress,
+ IoHandler handler, IoServiceConfig config)
+ {
+ if (address == null)
+ {
+ throw new NullPointerException("address");
+ }
+ if (handler == null)
+ {
+ throw new NullPointerException("handler");
+ }
+
+ if (!(address instanceof InetSocketAddress))
+ {
+ throw new IllegalArgumentException("Unexpected address type: "
+ + address.getClass());
+ }
+
+ if (localAddress != null && !(localAddress instanceof InetSocketAddress))
+ {
+ throw new IllegalArgumentException("Unexpected local address type: "
+ + localAddress.getClass());
+ }
+
+ if (config == null)
+ {
+ config = getDefaultConfig();
+ }
+
+ SocketChannel ch = null;
+ boolean success = false;
+ try
+ {
+ ch = SocketChannel.open();
+ ch.socket().setReuseAddress(true);
+ if (localAddress != null)
+ {
+ ch.socket().bind(localAddress);
+ }
+
+ ch.configureBlocking(false);
+
+ if (ch.connect(address))
+ {
+ DefaultConnectFuture future = new DefaultConnectFuture();
+ newSession(ch, handler, config, future);
+ success = true;
+ return future;
+ }
+
+ success = true;
+ }
+ catch (IOException e)
+ {
+ return DefaultConnectFuture.newFailedFuture(e);
+ }
+ finally
+ {
+ if (!success && ch != null)
+ {
+ try
+ {
+ ch.close();
+ }
+ catch (IOException e)
+ {
+ ExceptionMonitor.getInstance().exceptionCaught(e);
+ }
+ }
+ }
+
+ ConnectionRequest request = new ConnectionRequest(ch, handler, config);
+ synchronized (lock)
+ {
+ try
+ {
+ startupWorker();
+ }
+ catch (IOException e)
+ {
+ try
+ {
+ ch.close();
+ }
+ catch (IOException e2)
+ {
+ ExceptionMonitor.getInstance().exceptionCaught(e2);
+ }
+
+ return DefaultConnectFuture.newFailedFuture(e);
+ }
+ }
+
+ synchronized (connectQueue)
+ {
+ connectQueue.push(request);
+ }
+ selector.wakeup();
+
+ return request;
+ }
+
+ private synchronized void startupWorker() throws IOException
+ {
+ if (worker == null)
+ {
+ selector = Selector.open();
+ worker = new Worker();
+ executor.execute(new NamePreservingRunnable(worker));
+ }
+ }
+
+ private void registerNew()
+ {
+ if (connectQueue.isEmpty())
+ {
+ return;
+ }
+
+ for (; ;)
+ {
+ ConnectionRequest req;
+ synchronized (connectQueue)
+ {
+ req = (ConnectionRequest) connectQueue.pop();
+ }
+
+ if (req == null)
+ {
+ break;
+ }
+
+ SocketChannel ch = req.channel;
+ try
+ {
+ ch.register(selector, SelectionKey.OP_CONNECT, req);
+ }
+ catch (IOException e)
+ {
+ req.setException(e);
+ }
+ }
+ }
+
+ private void processSessions(Set keys)
+ {
+ Iterator it = keys.iterator();
+
+ while (it.hasNext())
+ {
+ SelectionKey key = (SelectionKey) it.next();
+
+ if (!key.isConnectable())
+ {
+ continue;
+ }
+
+ SocketChannel ch = (SocketChannel) key.channel();
+ ConnectionRequest entry = (ConnectionRequest) key.attachment();
+
+ boolean success = false;
+ try
+ {
+ ch.finishConnect();
+ newSession(ch, entry.handler, entry.config, entry);
+ success = true;
+ }
+ catch (Throwable e)
+ {
+ entry.setException(e);
+ }
+ finally
+ {
+ key.cancel();
+ if (!success)
+ {
+ try
+ {
+ ch.close();
+ }
+ catch (IOException e)
+ {
+ ExceptionMonitor.getInstance().exceptionCaught(e);
+ }
+ }
+ }
+ }
+
+ keys.clear();
+ }
+
+ private void processTimedOutSessions(Set keys)
+ {
+ long currentTime = System.currentTimeMillis();
+ Iterator it = keys.iterator();
+
+ while (it.hasNext())
+ {
+ SelectionKey key = (SelectionKey) it.next();
+
+ if (!key.isValid())
+ {
+ continue;
+ }
+
+ ConnectionRequest entry = (ConnectionRequest) key.attachment();
+
+ if (currentTime >= entry.deadline)
+ {
+ entry.setException(new ConnectException());
+ try
+ {
+ key.channel().close();
+ }
+ catch (IOException e)
+ {
+ ExceptionMonitor.getInstance().exceptionCaught(e);
+ }
+ finally
+ {
+ key.cancel();
+ }
+ }
+ }
+ }
+
+ private void newSession(SocketChannel ch, IoHandler handler, IoServiceConfig config, ConnectFuture connectFuture)
+ throws IOException
+ {
+ MultiThreadSocketSessionImpl session =
+ new MultiThreadSocketSessionImpl(this, nextProcessor(), getListeners(),
+ config, ch, handler, ch.socket().getRemoteSocketAddress());
+
+ //new interface
+// SocketSessionImpl session = new SocketSessionImpl(
+// this, nextProcessor(), getListeners(),
+// config, ch, handler, ch.socket().getRemoteSocketAddress() );
+ try
+ {
+ getFilterChainBuilder().buildFilterChain(session.getFilterChain());
+ config.getFilterChainBuilder().buildFilterChain(session.getFilterChain());
+ config.getThreadModel().buildFilterChain(session.getFilterChain());
+ }
+ catch (Throwable e)
+ {
+ throw (IOException) new IOException("Failed to create a session.").initCause(e);
+ }
+
+ // Set the ConnectFuture of the specified session, which will be
+ // removed and notified by AbstractIoFilterChain eventually.
+ session.setAttribute( AbstractIoFilterChain.CONNECT_FUTURE, connectFuture );
+
+ // Forward the remaining process to the SocketIoProcessor.
+ session.getIoProcessor().addNew(session);
+ }
+
+ private MultiThreadSocketIoProcessor nextProcessor()
+ {
+ return ioProcessors[processorDistributor++ % processorCount];
+ }
+
+ private class Worker implements Runnable
+ {
+ private long lastActive = System.currentTimeMillis();
+
+ public void run()
+ {
+ Thread.currentThread().setName(MultiThreadSocketConnector.this.threadName);
+
+ for (; ;)
+ {
+ try
+ {
+ int nKeys = selector.select(1000);
+
+ registerNew();
+
+ if (nKeys > 0)
+ {
+ processSessions(selector.selectedKeys());
+ }
+
+ processTimedOutSessions(selector.keys());
+
+ if (selector.keys().isEmpty())
+ {
+ if (System.currentTimeMillis() - lastActive > workerTimeout * 1000L)
+ {
+ synchronized (lock)
+ {
+ if (selector.keys().isEmpty() &&
+ connectQueue.isEmpty())
+ {
+ worker = null;
+ try
+ {
+ selector.close();
+ }
+ catch (IOException e)
+ {
+ ExceptionMonitor.getInstance().exceptionCaught(e);
+ }
+ finally
+ {
+ selector = null;
+ }
+ break;
+ }
+ }
+ }
+ }
+ else
+ {
+ lastActive = System.currentTimeMillis();
+ }
+ }
+ catch (IOException e)
+ {
+ ExceptionMonitor.getInstance().exceptionCaught(e);
+
+ try
+ {
+ Thread.sleep(1000);
+ }
+ catch (InterruptedException e1)
+ {
+ ExceptionMonitor.getInstance().exceptionCaught(e1);
+ }
+ }
+ }
+ }
+ }
+
+ private class ConnectionRequest extends DefaultConnectFuture
+ {
+ private final SocketChannel channel;
+ private final long deadline;
+ private final IoHandler handler;
+ private final IoServiceConfig config;
+
+ private ConnectionRequest(SocketChannel channel, IoHandler handler, IoServiceConfig config)
+ {
+ this.channel = channel;
+ long timeout;
+ if (config instanceof IoConnectorConfig)
+ {
+ timeout = ((IoConnectorConfig) config).getConnectTimeoutMillis();
+ }
+ else
+ {
+ timeout = ((IoConnectorConfig) getDefaultConfig()).getConnectTimeoutMillis();
+ }
+ this.deadline = System.currentTimeMillis() + timeout;
+ this.handler = handler;
+ this.config = config;
+ }
+ }
+}
diff --git a/qpid/java/common/src/main/java/org/apache/mina/transport/socket/nio/MultiThreadSocketFilterChain.java b/qpid/java/common/src/main/java/org/apache/mina/transport/socket/nio/MultiThreadSocketFilterChain.java
new file mode 100644
index 0000000000..67b8c8d820
--- /dev/null
+++ b/qpid/java/common/src/main/java/org/apache/mina/transport/socket/nio/MultiThreadSocketFilterChain.java
@@ -0,0 +1,67 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.mina.transport.socket.nio;
+
+import java.io.IOException;
+
+import org.apache.mina.common.ByteBuffer;
+import org.apache.mina.common.IoFilterChain;
+import org.apache.mina.common.IoSession;
+import org.apache.mina.common.IoFilter.WriteRequest;
+import org.apache.mina.common.support.AbstractIoFilterChain;
+import org.apache.mina.util.Queue;
+
+/**
+ * An {@link IoFilterChain} for socket transport (TCP/IP).
+ *
+ * @author The Apache Directory Project (mina-dev@directory.apache.org)
+ */
+class MultiThreadSocketFilterChain extends AbstractIoFilterChain {
+
+ MultiThreadSocketFilterChain( IoSession parent )
+ {
+ super( parent );
+ }
+
+ protected void doWrite( IoSession session, WriteRequest writeRequest )
+ {
+ MultiThreadSocketSessionImpl s = (MultiThreadSocketSessionImpl) session;
+ Queue writeRequestQueue = s.getWriteRequestQueue();
+
+ // SocketIoProcessor.doFlush() will reset it after write is finished
+ // because the buffer will be passed with messageSent event.
+ ( ( ByteBuffer ) writeRequest.getMessage() ).mark();
+ synchronized( writeRequestQueue )
+ {
+ writeRequestQueue.push( writeRequest );
+ if( writeRequestQueue.size() == 1 && session.getTrafficMask().isWritable() )
+ {
+ // Notify SocketIoProcessor only when writeRequestQueue was empty.
+ s.getIoProcessor().flush( s );
+ }
+ }
+ }
+
+ protected void doClose( IoSession session ) throws IOException
+ {
+ MultiThreadSocketSessionImpl s = (MultiThreadSocketSessionImpl) session;
+ s.getIoProcessor().remove( s );
+ }
+}
diff --git a/qpid/java/common/src/main/java/org/apache/mina/transport/socket/nio/MultiThreadSocketIoProcessor.java b/qpid/java/common/src/main/java/org/apache/mina/transport/socket/nio/MultiThreadSocketIoProcessor.java
new file mode 100644
index 0000000000..c23ad8686f
--- /dev/null
+++ b/qpid/java/common/src/main/java/org/apache/mina/transport/socket/nio/MultiThreadSocketIoProcessor.java
@@ -0,0 +1,1026 @@
+/*
+ * 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.mina.transport.socket.nio;
+
+import edu.emory.mathcs.backport.java.util.concurrent.Executor;
+import edu.emory.mathcs.backport.java.util.concurrent.locks.ReentrantLock;
+import org.apache.mina.common.ByteBuffer;
+import org.apache.mina.common.ExceptionMonitor;
+import org.apache.mina.common.IdleStatus;
+import org.apache.mina.common.IoFilter.WriteRequest;
+import org.apache.mina.common.WriteTimeoutException;
+import org.apache.mina.util.IdentityHashSet;
+import org.apache.mina.util.NamePreservingRunnable;
+import org.apache.mina.util.Queue;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.IOException;
+import java.nio.channels.SelectionKey;
+import java.nio.channels.Selector;
+import java.nio.channels.SocketChannel;
+import java.util.Iterator;
+import java.util.Set;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.LinkedBlockingQueue;
+
+/**
+ * Performs all I/O operations for sockets which is connected or bound. This class is used by MINA internally.
+ *
+ * @author The Apache Directory Project (mina-dev@directory.apache.org)
+ * @version $Rev: 619823 $, $Date: 2008-02-08 10:09:37 +0000 (Fri, 08 Feb 2008) $,
+ */
+class MultiThreadSocketIoProcessor extends SocketIoProcessor
+{
+ Logger _logger = LoggerFactory.getLogger(MultiThreadSocketIoProcessor.class);
+ Logger _loggerRead = LoggerFactory.getLogger(MultiThreadSocketIoProcessor.class + ".Reader");
+ Logger _loggerWrite = LoggerFactory.getLogger(MultiThreadSocketIoProcessor.class + ".Writer");
+
+ private static final long SELECTOR_TIMEOUT = 1000L;
+
+ private int MAX_READ_BYTES_PER_SESSION = 524288; //512K
+ private int MAX_FLUSH_BYTES_PER_SESSION = 524288; //512K
+
+ private final Object readLock = new Object();
+ private final Object writeLock = new Object();
+
+ private final String threadName;
+ private final Executor executor;
+
+ private ReentrantLock trafficMaskUpdateLock = new ReentrantLock();
+
+ /** @noinspection FieldAccessedSynchronizedAndUnsynchronized */
+ private volatile Selector selector, writeSelector;
+
+ private final Queue newSessions = new Queue();
+ private final Queue removingSessions = new Queue();
+ private final BlockingQueue flushingSessions = new LinkedBlockingQueue();
+ private final IdentityHashSet flushingSessionsSet = new IdentityHashSet();
+
+ private final Queue trafficControllingSessions = new Queue();
+
+ private ReadWorker readWorker;
+ private WriteWorker writeWorker;
+ private long lastIdleReadCheckTime = System.currentTimeMillis();
+ private long lastIdleWriteCheckTime = System.currentTimeMillis();
+
+ MultiThreadSocketIoProcessor(String threadName, Executor executor)
+ {
+ super(threadName, executor);
+ this.threadName = threadName;
+ this.executor = executor;
+ }
+
+ void addNew(SocketSessionImpl session) throws IOException
+ {
+ synchronized (newSessions)
+ {
+ newSessions.push(session);
+ }
+
+ startupWorker();
+
+ selector.wakeup();
+ writeSelector.wakeup();
+ }
+
+ void remove(SocketSessionImpl session) throws IOException
+ {
+ scheduleRemove(session);
+ startupWorker();
+ selector.wakeup();
+ }
+
+ private void startupWorker() throws IOException
+ {
+ synchronized (readLock)
+ {
+ if (readWorker == null)
+ {
+ selector = Selector.open();
+ readWorker = new ReadWorker();
+ executor.execute(new NamePreservingRunnable(readWorker));
+ }
+ }
+
+ synchronized (writeLock)
+ {
+ if (writeWorker == null)
+ {
+ writeSelector = Selector.open();
+ writeWorker = new WriteWorker();
+ executor.execute(new NamePreservingRunnable(writeWorker));
+ }
+ }
+
+ }
+
+ void flush(SocketSessionImpl session)
+ {
+ scheduleFlush(session);
+ Selector selector = this.writeSelector;
+
+ if (selector != null)
+ {
+ selector.wakeup();
+ }
+ }
+
+ void updateTrafficMask(SocketSessionImpl session)
+ {
+ scheduleTrafficControl(session);
+ Selector selector = this.selector;
+ if (selector != null)
+ {
+ selector.wakeup();
+ }
+ }
+
+ private void scheduleRemove(SocketSessionImpl session)
+ {
+ synchronized (removingSessions)
+ {
+ removingSessions.push(session);
+ }
+ }
+
+ private void scheduleFlush(SocketSessionImpl session)
+ {
+ synchronized (flushingSessionsSet)
+ {
+ //if flushingSessions grows to contain Integer.MAX_VALUE sessions
+ // then this will fail.
+ if (flushingSessionsSet.add(session))
+ {
+ flushingSessions.offer(session);
+ }
+ }
+ }
+
+ private void scheduleTrafficControl(SocketSessionImpl session)
+ {
+ synchronized (trafficControllingSessions)
+ {
+ trafficControllingSessions.push(session);
+ }
+ }
+
+ private void doAddNewReader() throws InterruptedException
+ {
+ if (newSessions.isEmpty())
+ {
+ return;
+ }
+
+ for (; ;)
+ {
+ MultiThreadSocketSessionImpl session;
+
+ synchronized (newSessions)
+ {
+ session = (MultiThreadSocketSessionImpl) newSessions.peek();
+ }
+
+ if (session == null)
+ {
+ break;
+ }
+
+ SocketChannel ch = session.getChannel();
+
+
+ try
+ {
+
+ ch.configureBlocking(false);
+ session.setSelectionKey(ch.register(selector,
+ SelectionKey.OP_READ,
+ session));
+
+ //System.out.println("ReadDebug:"+"Awaiting Registration");
+ session.awaitRegistration();
+ sessionCreated(session);
+ }
+ catch (IOException e)
+ {
+ // Clear the AbstractIoFilterChain.CONNECT_FUTURE attribute
+ // and call ConnectFuture.setException().
+ session.getFilterChain().fireExceptionCaught(session, e);
+ }
+ }
+ }
+
+
+ private void doAddNewWrite() throws InterruptedException
+ {
+ if (newSessions.isEmpty())
+ {
+ return;
+ }
+
+ for (; ;)
+ {
+ MultiThreadSocketSessionImpl session;
+
+ synchronized (newSessions)
+ {
+ session = (MultiThreadSocketSessionImpl) newSessions.peek();
+ }
+
+ if (session == null)
+ {
+ break;
+ }
+
+ SocketChannel ch = session.getChannel();
+
+ try
+ {
+ ch.configureBlocking(false);
+ synchronized (flushingSessionsSet)
+ {
+ flushingSessionsSet.add(session);
+ }
+
+ session.setWriteSelectionKey(ch.register(writeSelector,
+ SelectionKey.OP_WRITE,
+ session));
+
+ //System.out.println("WriteDebug:"+"Awaiting Registration");
+ session.awaitRegistration();
+ sessionCreated(session);
+ }
+ catch (IOException e)
+ {
+
+ // Clear the AbstractIoFilterChain.CONNECT_FUTURE attribute
+ // and call ConnectFuture.setException().
+ session.getFilterChain().fireExceptionCaught(session, e);
+ }
+ }
+ }
+
+
+ private void sessionCreated(SocketSessionImpl sessionParam) throws InterruptedException
+ {
+ MultiThreadSocketSessionImpl session = (MultiThreadSocketSessionImpl) sessionParam;
+ synchronized (newSessions)
+ {
+ if (!session.created())
+ {
+ _logger.debug("Popping new session");
+ newSessions.pop();
+
+ // AbstractIoFilterChain.CONNECT_FUTURE is cleared inside here
+ // in AbstractIoFilterChain.fireSessionOpened().
+ session.getServiceListeners().fireSessionCreated(session);
+
+ session.doneCreation();
+ }
+ }
+ }
+
+ private void doRemove()
+ {
+ if (removingSessions.isEmpty())
+ {
+ return;
+ }
+
+ for (; ;)
+ {
+ MultiThreadSocketSessionImpl session;
+
+ synchronized (removingSessions)
+ {
+ session = (MultiThreadSocketSessionImpl) removingSessions.pop();
+ }
+
+ if (session == null)
+ {
+ break;
+ }
+
+ SocketChannel ch = session.getChannel();
+ SelectionKey key = session.getReadSelectionKey();
+ SelectionKey writeKey = session.getWriteSelectionKey();
+
+ // Retry later if session is not yet fully initialized.
+ // (In case that Session.close() is called before addSession() is processed)
+ if (key == null || writeKey == null)
+ {
+ scheduleRemove(session);
+ break;
+ }
+ // skip if channel is already closed
+ if (!key.isValid() || !writeKey.isValid())
+ {
+ continue;
+ }
+
+ try
+ {
+ //System.out.println("ReadDebug:"+"Removing Session: " + System.identityHashCode(session));
+ synchronized (readLock)
+ {
+ key.cancel();
+ }
+ synchronized (writeLock)
+ {
+ writeKey.cancel();
+ }
+ ch.close();
+ }
+ catch (IOException e)
+ {
+ session.getFilterChain().fireExceptionCaught(session, e);
+ }
+ finally
+ {
+ releaseWriteBuffers(session);
+ session.getServiceListeners().fireSessionDestroyed(session);
+ }
+ }
+ }
+
+ private void processRead(Set selectedKeys)
+ {
+ Iterator it = selectedKeys.iterator();
+
+ while (it.hasNext())
+ {
+ SelectionKey key = (SelectionKey) it.next();
+ MultiThreadSocketSessionImpl session = (MultiThreadSocketSessionImpl) key.attachment();
+
+ synchronized (readLock)
+ {
+ if (key.isValid() && key.isReadable() && session.getTrafficMask().isReadable())
+ {
+ read(session);
+ }
+ }
+
+ }
+
+ selectedKeys.clear();
+ }
+
+ private void processWrite(Set selectedKeys)
+ {
+ Iterator it = selectedKeys.iterator();
+
+ while (it.hasNext())
+ {
+ SelectionKey key = (SelectionKey) it.next();
+ SocketSessionImpl session = (SocketSessionImpl) key.attachment();
+
+ synchronized (writeLock)
+ {
+ if (key.isValid() && key.isWritable() && session.getTrafficMask().isWritable())
+ {
+
+ // Clear OP_WRITE
+ key.interestOps(key.interestOps() & (~SelectionKey.OP_WRITE));
+
+ synchronized (flushingSessionsSet)
+ {
+ flushingSessions.offer(session);
+ }
+ }
+ }
+ }
+
+ selectedKeys.clear();
+ }
+
+ private void read(SocketSessionImpl session)
+ {
+
+ //if (_loggerWrite.isDebugEnabled())
+ {
+ //System.out.println("WriteDebug:"+"Starting read for Session:" + System.identityHashCode(session));
+ }
+
+ int totalReadBytes = 0;
+
+ while (totalReadBytes <= MAX_READ_BYTES_PER_SESSION)
+ {
+ ByteBuffer buf = ByteBuffer.allocate(session.getReadBufferSize());
+ SocketChannel ch = session.getChannel();
+
+ try
+ {
+ buf.clear();
+
+ int readBytes = 0;
+ int ret;
+
+ try
+ {
+ while ((ret = ch.read(buf.buf())) > 0)
+ {
+ readBytes += ret;
+ totalReadBytes += ret;
+ }
+ }
+ finally
+ {
+ buf.flip();
+ }
+
+
+ if (readBytes > 0)
+ {
+ session.increaseReadBytes(readBytes);
+
+ session.getFilterChain().fireMessageReceived(session, buf);
+ buf = null;
+ }
+
+ if (ret <= 0)
+ {
+ if (ret == 0)
+ {
+ if (readBytes == session.getReadBufferSize())
+ {
+ continue;
+ }
+ }
+ else
+ {
+ scheduleRemove(session);
+ }
+
+ break;
+ }
+ }
+ catch (Throwable e)
+ {
+ if (e instanceof IOException)
+ {
+ scheduleRemove(session);
+ }
+ session.getFilterChain().fireExceptionCaught(session, e);
+
+ //Stop Reading this session.
+ return;
+ }
+ finally
+ {
+ if (buf != null)
+ {
+ buf.release();
+ }
+ }
+ }//for
+
+ // if (_loggerWrite.isDebugEnabled())
+ {
+ //System.out.println("WriteDebug:"+"Read for Session:" + System.identityHashCode(session) + " got: " + totalReadBytes);
+ }
+ }
+
+
+ private void notifyReadIdleness()
+ {
+ // process idle sessions
+ long currentTime = System.currentTimeMillis();
+ if ((currentTime - lastIdleReadCheckTime) >= 1000)
+ {
+ lastIdleReadCheckTime = currentTime;
+ Set keys = selector.keys();
+ if (keys != null)
+ {
+ for (Iterator it = keys.iterator(); it.hasNext();)
+ {
+ SelectionKey key = (SelectionKey) it.next();
+ SocketSessionImpl session = (SocketSessionImpl) key.attachment();
+ notifyReadIdleness(session, currentTime);
+ }
+ }
+ }
+ }
+
+ private void notifyWriteIdleness()
+ {
+ // process idle sessions
+ long currentTime = System.currentTimeMillis();
+ if ((currentTime - lastIdleWriteCheckTime) >= 1000)
+ {
+ lastIdleWriteCheckTime = currentTime;
+ Set keys = writeSelector.keys();
+ if (keys != null)
+ {
+ for (Iterator it = keys.iterator(); it.hasNext();)
+ {
+ SelectionKey key = (SelectionKey) it.next();
+ SocketSessionImpl session = (SocketSessionImpl) key.attachment();
+ notifyWriteIdleness(session, currentTime);
+ }
+ }
+ }
+ }
+
+ private void notifyReadIdleness(SocketSessionImpl session, long currentTime)
+ {
+ notifyIdleness0(
+ session, currentTime,
+ session.getIdleTimeInMillis(IdleStatus.BOTH_IDLE),
+ IdleStatus.BOTH_IDLE,
+ Math.max(session.getLastIoTime(), session.getLastIdleTime(IdleStatus.BOTH_IDLE)));
+ notifyIdleness0(
+ session, currentTime,
+ session.getIdleTimeInMillis(IdleStatus.READER_IDLE),
+ IdleStatus.READER_IDLE,
+ Math.max(session.getLastReadTime(), session.getLastIdleTime(IdleStatus.READER_IDLE)));
+
+ notifyWriteTimeout(session, currentTime, session
+ .getWriteTimeoutInMillis(), session.getLastWriteTime());
+ }
+
+ private void notifyWriteIdleness(SocketSessionImpl session, long currentTime)
+ {
+ notifyIdleness0(
+ session, currentTime,
+ session.getIdleTimeInMillis(IdleStatus.BOTH_IDLE),
+ IdleStatus.BOTH_IDLE,
+ Math.max(session.getLastIoTime(), session.getLastIdleTime(IdleStatus.BOTH_IDLE)));
+ notifyIdleness0(
+ session, currentTime,
+ session.getIdleTimeInMillis(IdleStatus.WRITER_IDLE),
+ IdleStatus.WRITER_IDLE,
+ Math.max(session.getLastWriteTime(), session.getLastIdleTime(IdleStatus.WRITER_IDLE)));
+
+ notifyWriteTimeout(session, currentTime, session
+ .getWriteTimeoutInMillis(), session.getLastWriteTime());
+ }
+
+ private void notifyIdleness0(SocketSessionImpl session, long currentTime,
+ long idleTime, IdleStatus status,
+ long lastIoTime)
+ {
+ if (idleTime > 0 && lastIoTime != 0
+ && (currentTime - lastIoTime) >= idleTime)
+ {
+ session.increaseIdleCount(status);
+ session.getFilterChain().fireSessionIdle(session, status);
+ }
+ }
+
+ private void notifyWriteTimeout(SocketSessionImpl session,
+ long currentTime,
+ long writeTimeout, long lastIoTime)
+ {
+
+ MultiThreadSocketSessionImpl sesh = (MultiThreadSocketSessionImpl) session;
+ SelectionKey key = sesh.getWriteSelectionKey();
+
+ synchronized (writeLock)
+ {
+ if (writeTimeout > 0
+ && (currentTime - lastIoTime) >= writeTimeout
+ && key != null && key.isValid()
+ && (key.interestOps() & SelectionKey.OP_WRITE) != 0)
+ {
+ session.getFilterChain().fireExceptionCaught(session, new WriteTimeoutException());
+ }
+ }
+ }
+
+ private SocketSessionImpl getNextFlushingSession()
+ {
+ return (SocketSessionImpl) flushingSessions.poll();
+ }
+
+ private void releaseSession(SocketSessionImpl session)
+ {
+ synchronized (session.getWriteRequestQueue())
+ {
+ synchronized (flushingSessionsSet)
+ {
+ if (session.getScheduledWriteRequests() > 0)
+ {
+ if (_loggerWrite.isDebugEnabled())
+ {
+ //System.out.println("WriteDebug:"+"Reflush" + System.identityHashCode(session));
+ }
+ flushingSessions.offer(session);
+ }
+ else
+ {
+ if (_loggerWrite.isDebugEnabled())
+ {
+ //System.out.println("WriteDebug:"+"Releasing session " + System.identityHashCode(session));
+ }
+ flushingSessionsSet.remove(session);
+ }
+ }
+ }
+ }
+
+ private void releaseWriteBuffers(SocketSessionImpl session)
+ {
+ Queue writeRequestQueue = session.getWriteRequestQueue();
+ WriteRequest req;
+
+ //Should this be synchronized?
+ synchronized (writeRequestQueue)
+ {
+ while ((req = (WriteRequest) writeRequestQueue.pop()) != null)
+ {
+ try
+ {
+ ((ByteBuffer) req.getMessage()).release();
+ }
+ catch (IllegalStateException e)
+ {
+ session.getFilterChain().fireExceptionCaught(session, e);
+ }
+ finally
+ {
+ req.getFuture().setWritten(false);
+ }
+ }
+ }
+ }
+
+ private void doFlush()
+ {
+ MultiThreadSocketSessionImpl session;
+
+ while ((session = (MultiThreadSocketSessionImpl) getNextFlushingSession()) != null)
+ {
+ if (!session.isConnected())
+ {
+ releaseWriteBuffers(session);
+ releaseSession(session);
+ continue;
+ }
+
+ SelectionKey key = session.getWriteSelectionKey();
+ // Retry later if session is not yet fully initialized.
+ // (In case that Session.write() is called before addSession() is processed)
+ if (key == null)
+ {
+ scheduleFlush(session);
+ releaseSession(session);
+ continue;
+ }
+ // skip if channel is already closed
+ if (!key.isValid())
+ {
+ releaseSession(session);
+ continue;
+ }
+
+ try
+ {
+ if (doFlush(session))
+ {
+ releaseSession(session);
+ }
+ }
+ catch (IOException e)
+ {
+ releaseSession(session);
+ scheduleRemove(session);
+ session.getFilterChain().fireExceptionCaught(session, e);
+ }
+
+ }
+
+ }
+
+ private boolean doFlush(SocketSessionImpl sessionParam) throws IOException
+ {
+ MultiThreadSocketSessionImpl session = (MultiThreadSocketSessionImpl) sessionParam;
+ // Clear OP_WRITE
+ SelectionKey key = session.getWriteSelectionKey();
+ synchronized (writeLock)
+ {
+ key.interestOps(key.interestOps() & (~SelectionKey.OP_WRITE));
+ }
+ SocketChannel ch = session.getChannel();
+ Queue writeRequestQueue = session.getWriteRequestQueue();
+
+ long totalFlushedBytes = 0;
+ while (true)
+ {
+ WriteRequest req;
+
+ synchronized (writeRequestQueue)
+ {
+ req = (WriteRequest) writeRequestQueue.first();
+ }
+
+ if (req == null)
+ {
+ break;
+ }
+
+ ByteBuffer buf = (ByteBuffer) req.getMessage();
+ if (buf.remaining() == 0)
+ {
+ synchronized (writeRequestQueue)
+ {
+ writeRequestQueue.pop();
+ }
+
+ session.increaseWrittenMessages();
+
+ buf.reset();
+ session.getFilterChain().fireMessageSent(session, req);
+ continue;
+ }
+
+
+ int writtenBytes = 0;
+
+ // Reported as DIRMINA-362
+ //note: todo: fixme: Not sure it is important but if we see NoyYetConnected exceptions or 100% CPU in the kernel then this is it.
+ if (key.isWritable())
+ {
+ writtenBytes = ch.write(buf.buf());
+ totalFlushedBytes += writtenBytes;
+ }
+
+ if (writtenBytes > 0)
+ {
+ session.increaseWrittenBytes(writtenBytes);
+ }
+
+ if (buf.hasRemaining() || (totalFlushedBytes <= MAX_FLUSH_BYTES_PER_SESSION))
+ {
+ // Kernel buffer is full
+ synchronized (writeLock)
+ {
+ key.interestOps(key.interestOps() | SelectionKey.OP_WRITE);
+ }
+ if (_loggerWrite.isDebugEnabled())
+ {
+ //System.out.println("WriteDebug:"+"Written BF: " + (session.getWrittenBytes() - totalFlushedBytes) + " bytes");
+ }
+ return false;
+ }
+ }
+
+ if (_loggerWrite.isDebugEnabled())
+ {
+ //System.out.println("WriteDebug:"+"Written : " + (session.getWrittenBytes() - totalFlushedBytes) + " bytes");
+ }
+ return true;
+ }
+
+ private void doUpdateTrafficMask()
+ {
+ if (trafficControllingSessions.isEmpty() || trafficMaskUpdateLock.isLocked())
+ {
+ return;
+ }
+
+ // Synchronize over entire operation as this method should be called
+ // from both read and write thread and we don't want the order of the
+ // updates to get changed.
+ trafficMaskUpdateLock.lock();
+ try
+ {
+ for (; ;)
+ {
+ MultiThreadSocketSessionImpl session;
+
+ session = (MultiThreadSocketSessionImpl) trafficControllingSessions.pop();
+
+ if (session == null)
+ {
+ break;
+ }
+
+ SelectionKey key = session.getReadSelectionKey();
+ // Retry later if session is not yet fully initialized.
+ // (In case that Session.suspend??() or session.resume??() is
+ // called before addSession() is processed)
+ if (key == null)
+ {
+ scheduleTrafficControl(session);
+ break;
+ }
+ // skip if channel is already closed
+ if (!key.isValid())
+ {
+ continue;
+ }
+
+ // The normal is OP_READ and, if there are write requests in the
+ // session's write queue, set OP_WRITE to trigger flushing.
+
+ //Sset to Read and Write if there is nothing then the cost
+ // is one loop through the flusher.
+ int ops = SelectionKey.OP_READ;
+
+ // Now mask the preferred ops with the mask of the current session
+ int mask = session.getTrafficMask().getInterestOps();
+ synchronized (readLock)
+ {
+ key.interestOps(ops & mask);
+ }
+ //Change key to the WriteSelection Key
+ key = session.getWriteSelectionKey();
+ if (key != null && key.isValid())
+ {
+ Queue writeRequestQueue = session.getWriteRequestQueue();
+ synchronized (writeRequestQueue)
+ {
+ if (!writeRequestQueue.isEmpty())
+ {
+ ops = SelectionKey.OP_WRITE;
+ synchronized (writeLock)
+ {
+ key.interestOps(ops & mask);
+ }
+ }
+ }
+ }
+ }
+ }
+ finally
+ {
+ trafficMaskUpdateLock.unlock();
+ }
+
+ }
+
+ private class WriteWorker implements Runnable
+ {
+
+ public void run()
+ {
+ Thread.currentThread().setName(MultiThreadSocketIoProcessor.this.threadName + "Writer");
+
+ //System.out.println("WriteDebug:"+"Startup");
+ for (; ;)
+ {
+ try
+ {
+ int nKeys = writeSelector.select(SELECTOR_TIMEOUT);
+
+ doAddNewWrite();
+ doUpdateTrafficMask();
+
+ if (nKeys > 0)
+ {
+ //System.out.println("WriteDebug:"+nKeys + " keys from writeselector");
+ processWrite(writeSelector.selectedKeys());
+ }
+ else
+ {
+ //System.out.println("WriteDebug:"+"No keys from writeselector");
+ }
+
+ doRemove();
+ notifyWriteIdleness();
+
+ if (flushingSessionsSet.size() > 0)
+ {
+ doFlush();
+ }
+
+ if (writeSelector.keys().isEmpty())
+ {
+ synchronized (writeLock)
+ {
+
+ if (writeSelector.keys().isEmpty() && newSessions.isEmpty())
+ {
+ writeWorker = null;
+ try
+ {
+ writeSelector.close();
+ }
+ catch (IOException e)
+ {
+ ExceptionMonitor.getInstance().exceptionCaught(e);
+ }
+ finally
+ {
+ writeSelector = null;
+ }
+
+ break;
+ }
+ }
+ }
+
+ }
+ catch (Throwable t)
+ {
+ ExceptionMonitor.getInstance().exceptionCaught(t);
+
+ try
+ {
+ Thread.sleep(1000);
+ }
+ catch (InterruptedException e1)
+ {
+ ExceptionMonitor.getInstance().exceptionCaught(e1);
+ }
+ }
+ }
+ //System.out.println("WriteDebug:"+"Shutdown");
+ }
+
+ }
+
+ private class ReadWorker implements Runnable
+ {
+
+ public void run()
+ {
+ Thread.currentThread().setName(MultiThreadSocketIoProcessor.this.threadName + "Reader");
+
+ //System.out.println("ReadDebug:"+"Startup");
+ for (; ;)
+ {
+ try
+ {
+ int nKeys = selector.select(SELECTOR_TIMEOUT);
+
+ doAddNewReader();
+ doUpdateTrafficMask();
+
+ if (nKeys > 0)
+ {
+ //System.out.println("ReadDebug:"+nKeys + " keys from selector");
+
+ processRead(selector.selectedKeys());
+ }
+ else
+ {
+ //System.out.println("ReadDebug:"+"No keys from selector");
+ }
+
+
+ doRemove();
+ notifyReadIdleness();
+
+ if (selector.keys().isEmpty())
+ {
+
+ synchronized (readLock)
+ {
+ if (selector.keys().isEmpty() && newSessions.isEmpty())
+ {
+ readWorker = null;
+ try
+ {
+ selector.close();
+ }
+ catch (IOException e)
+ {
+ ExceptionMonitor.getInstance().exceptionCaught(e);
+ }
+ finally
+ {
+ selector = null;
+ }
+
+ break;
+ }
+ }
+ }
+ }
+ catch (Throwable t)
+ {
+ ExceptionMonitor.getInstance().exceptionCaught(t);
+
+ try
+ {
+ Thread.sleep(1000);
+ }
+ catch (InterruptedException e1)
+ {
+ ExceptionMonitor.getInstance().exceptionCaught(e1);
+ }
+ }
+ }
+ //System.out.println("ReadDebug:"+"Shutdown");
+ }
+
+ }
+}
diff --git a/qpid/java/common/src/main/java/org/apache/mina/transport/socket/nio/MultiThreadSocketSessionConfigImpl.java b/qpid/java/common/src/main/java/org/apache/mina/transport/socket/nio/MultiThreadSocketSessionConfigImpl.java
new file mode 100644
index 0000000000..043d4800b6
--- /dev/null
+++ b/qpid/java/common/src/main/java/org/apache/mina/transport/socket/nio/MultiThreadSocketSessionConfigImpl.java
@@ -0,0 +1,240 @@
+/*
+ * 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.mina.transport.socket.nio;
+
+import org.apache.mina.common.ExceptionMonitor;
+import org.apache.mina.common.IoConnectorConfig;
+import org.apache.mina.common.support.BaseIoSessionConfig;
+
+import java.io.IOException;
+import java.net.Socket;
+import java.net.SocketException;
+
+/**
+ * An {@link IoConnectorConfig} for {@link SocketConnector}.
+ *
+ * @author The Apache Directory Project (mina-dev@directory.apache.org)
+ * @version $Rev: 619823 $, $Date: 2008-02-08 10:09:37 +0000 (Fri, 08 Feb 2008) $
+ */
+public class MultiThreadSocketSessionConfigImpl extends org.apache.mina.transport.socket.nio.SocketSessionConfigImpl
+{
+ private static boolean SET_RECEIVE_BUFFER_SIZE_AVAILABLE = false;
+ private static boolean SET_SEND_BUFFER_SIZE_AVAILABLE = false;
+ private static boolean GET_TRAFFIC_CLASS_AVAILABLE = false;
+ private static boolean SET_TRAFFIC_CLASS_AVAILABLE = false;
+
+ private static boolean DEFAULT_REUSE_ADDRESS;
+ private static int DEFAULT_RECEIVE_BUFFER_SIZE;
+ private static int DEFAULT_SEND_BUFFER_SIZE;
+ private static int DEFAULT_TRAFFIC_CLASS;
+ private static boolean DEFAULT_KEEP_ALIVE;
+ private static boolean DEFAULT_OOB_INLINE;
+ private static int DEFAULT_SO_LINGER;
+ private static boolean DEFAULT_TCP_NO_DELAY;
+
+ static
+ {
+ initialize();
+ }
+
+ private static void initialize()
+ {
+ Socket socket = null;
+
+ socket = new Socket();
+
+ try
+ {
+ DEFAULT_REUSE_ADDRESS = socket.getReuseAddress();
+ DEFAULT_RECEIVE_BUFFER_SIZE = socket.getReceiveBufferSize();
+ DEFAULT_SEND_BUFFER_SIZE = socket.getSendBufferSize();
+ DEFAULT_KEEP_ALIVE = socket.getKeepAlive();
+ DEFAULT_OOB_INLINE = socket.getOOBInline();
+ DEFAULT_SO_LINGER = socket.getSoLinger();
+ DEFAULT_TCP_NO_DELAY = socket.getTcpNoDelay();
+
+ // Check if setReceiveBufferSize is supported.
+ try
+ {
+ socket.setReceiveBufferSize(DEFAULT_RECEIVE_BUFFER_SIZE);
+ SET_RECEIVE_BUFFER_SIZE_AVAILABLE = true;
+ }
+ catch( SocketException e )
+ {
+ SET_RECEIVE_BUFFER_SIZE_AVAILABLE = false;
+ }
+
+ // Check if setSendBufferSize is supported.
+ try
+ {
+ socket.setSendBufferSize(DEFAULT_SEND_BUFFER_SIZE);
+ SET_SEND_BUFFER_SIZE_AVAILABLE = true;
+ }
+ catch( SocketException e )
+ {
+ SET_SEND_BUFFER_SIZE_AVAILABLE = false;
+ }
+
+ // Check if getTrafficClass is supported.
+ try
+ {
+ DEFAULT_TRAFFIC_CLASS = socket.getTrafficClass();
+ GET_TRAFFIC_CLASS_AVAILABLE = true;
+ }
+ catch( SocketException e )
+ {
+ GET_TRAFFIC_CLASS_AVAILABLE = false;
+ DEFAULT_TRAFFIC_CLASS = 0;
+ }
+ }
+ catch( SocketException e )
+ {
+ throw new ExceptionInInitializerError(e);
+ }
+ finally
+ {
+ if( socket != null )
+ {
+ try
+ {
+ socket.close();
+ }
+ catch( IOException e )
+ {
+ ExceptionMonitor.getInstance().exceptionCaught(e);
+ }
+ }
+ }
+ }
+
+ public static boolean isSetReceiveBufferSizeAvailable() {
+ return SET_RECEIVE_BUFFER_SIZE_AVAILABLE;
+ }
+
+ public static boolean isSetSendBufferSizeAvailable() {
+ return SET_SEND_BUFFER_SIZE_AVAILABLE;
+ }
+
+ public static boolean isGetTrafficClassAvailable() {
+ return GET_TRAFFIC_CLASS_AVAILABLE;
+ }
+
+ public static boolean isSetTrafficClassAvailable() {
+ return SET_TRAFFIC_CLASS_AVAILABLE;
+ }
+
+ private boolean reuseAddress = DEFAULT_REUSE_ADDRESS;
+ private int receiveBufferSize = DEFAULT_RECEIVE_BUFFER_SIZE;
+ private int sendBufferSize = DEFAULT_SEND_BUFFER_SIZE;
+ private int trafficClass = DEFAULT_TRAFFIC_CLASS;
+ private boolean keepAlive = DEFAULT_KEEP_ALIVE;
+ private boolean oobInline = DEFAULT_OOB_INLINE;
+ private int soLinger = DEFAULT_SO_LINGER;
+ private boolean tcpNoDelay = DEFAULT_TCP_NO_DELAY;
+
+ /**
+ * Creates a new instance.
+ */
+ MultiThreadSocketSessionConfigImpl()
+ {
+ }
+
+ public boolean isReuseAddress()
+ {
+ return reuseAddress;
+ }
+
+ public void setReuseAddress( boolean reuseAddress )
+ {
+ this.reuseAddress = reuseAddress;
+ }
+
+ public int getReceiveBufferSize()
+ {
+ return receiveBufferSize;
+ }
+
+ public void setReceiveBufferSize( int receiveBufferSize )
+ {
+ this.receiveBufferSize = receiveBufferSize;
+ }
+
+ public int getSendBufferSize()
+ {
+ return sendBufferSize;
+ }
+
+ public void setSendBufferSize( int sendBufferSize )
+ {
+ this.sendBufferSize = sendBufferSize;
+ }
+
+ public int getTrafficClass()
+ {
+ return trafficClass;
+ }
+
+ public void setTrafficClass( int trafficClass )
+ {
+ this.trafficClass = trafficClass;
+ }
+
+ public boolean isKeepAlive()
+ {
+ return keepAlive;
+ }
+
+ public void setKeepAlive( boolean keepAlive )
+ {
+ this.keepAlive = keepAlive;
+ }
+
+ public boolean isOobInline()
+ {
+ return oobInline;
+ }
+
+ public void setOobInline( boolean oobInline )
+ {
+ this.oobInline = oobInline;
+ }
+
+ public int getSoLinger()
+ {
+ return soLinger;
+ }
+
+ public void setSoLinger( int soLinger )
+ {
+ this.soLinger = soLinger;
+ }
+
+ public boolean isTcpNoDelay()
+ {
+ return tcpNoDelay;
+ }
+
+ public void setTcpNoDelay( boolean tcpNoDelay )
+ {
+ this.tcpNoDelay = tcpNoDelay;
+ }
+
+
+}
diff --git a/qpid/java/common/src/main/java/org/apache/mina/transport/socket/nio/MultiThreadSocketSessionImpl.java b/qpid/java/common/src/main/java/org/apache/mina/transport/socket/nio/MultiThreadSocketSessionImpl.java
new file mode 100644
index 0000000000..be4a2d289d
--- /dev/null
+++ b/qpid/java/common/src/main/java/org/apache/mina/transport/socket/nio/MultiThreadSocketSessionImpl.java
@@ -0,0 +1,488 @@
+/*
+ * 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.mina.transport.socket.nio;
+
+import org.apache.mina.common.IoFilter.WriteRequest;
+import org.apache.mina.common.IoFilterChain;
+import org.apache.mina.common.IoHandler;
+import org.apache.mina.common.IoService;
+import org.apache.mina.common.IoServiceConfig;
+import org.apache.mina.common.IoSession;
+import org.apache.mina.common.IoSessionConfig;
+import org.apache.mina.common.RuntimeIOException;
+import org.apache.mina.common.TransportType;
+import org.apache.mina.common.support.BaseIoSessionConfig;
+import org.apache.mina.common.support.IoServiceListenerSupport;
+import org.apache.mina.util.Queue;
+
+import java.net.SocketAddress;
+import java.net.SocketException;
+import java.nio.channels.SelectionKey;
+import java.nio.channels.SocketChannel;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+/**
+ * An {@link IoSession} for socket transport (TCP/IP).
+ *
+ * @author The Apache Directory Project (mina-dev@directory.apache.org)
+ * @version $Rev: 619823 $, $Date: 2008-02-08 10:09:37 +0000 (Fri, 08 Feb 2008) $
+ */
+class MultiThreadSocketSessionImpl extends SocketSessionImpl
+{
+ private final IoService manager;
+ private final IoServiceConfig serviceConfig;
+ private final SocketSessionConfig config = new SessionConfigImpl();
+ private final MultiThreadSocketIoProcessor ioProcessor;
+ private final MultiThreadSocketFilterChain filterChain;
+ private final SocketChannel ch;
+ private final Queue writeRequestQueue;
+ private final IoHandler handler;
+ private final SocketAddress remoteAddress;
+ private final SocketAddress localAddress;
+ private final SocketAddress serviceAddress;
+ private final IoServiceListenerSupport serviceListeners;
+ private SelectionKey readKey, writeKey;
+ private int readBufferSize;
+ private CountDownLatch registeredReadyLatch = new CountDownLatch(2);
+ private AtomicBoolean created = new AtomicBoolean(false);
+
+ /**
+ * Creates a new instance.
+ */
+ MultiThreadSocketSessionImpl( IoService manager,
+ SocketIoProcessor ioProcessor,
+ IoServiceListenerSupport listeners,
+ IoServiceConfig serviceConfig,
+ SocketChannel ch,
+ IoHandler defaultHandler,
+ SocketAddress serviceAddress )
+ {
+ super(manager, ioProcessor, listeners, serviceConfig, ch,defaultHandler,serviceAddress);
+ this.manager = manager;
+ this.serviceListeners = listeners;
+ this.ioProcessor = (MultiThreadSocketIoProcessor) ioProcessor;
+ this.filterChain = new MultiThreadSocketFilterChain(this);
+ this.ch = ch;
+ this.writeRequestQueue = new Queue();
+ this.handler = defaultHandler;
+ this.remoteAddress = ch.socket().getRemoteSocketAddress();
+ this.localAddress = ch.socket().getLocalSocketAddress();
+ this.serviceAddress = serviceAddress;
+ this.serviceConfig = serviceConfig;
+
+ // Apply the initial session settings
+ IoSessionConfig sessionConfig = serviceConfig.getSessionConfig();
+ if( sessionConfig instanceof SocketSessionConfig )
+ {
+ SocketSessionConfig cfg = ( SocketSessionConfig ) sessionConfig;
+ this.config.setKeepAlive( cfg.isKeepAlive() );
+ this.config.setOobInline( cfg.isOobInline() );
+ this.config.setReceiveBufferSize( cfg.getReceiveBufferSize() );
+ this.readBufferSize = cfg.getReceiveBufferSize();
+ this.config.setReuseAddress( cfg.isReuseAddress() );
+ this.config.setSendBufferSize( cfg.getSendBufferSize() );
+ this.config.setSoLinger( cfg.getSoLinger() );
+ this.config.setTcpNoDelay( cfg.isTcpNoDelay() );
+
+ if( this.config.getTrafficClass() != cfg.getTrafficClass() )
+ {
+ this.config.setTrafficClass( cfg.getTrafficClass() );
+ }
+ }
+ }
+
+ void awaitRegistration() throws InterruptedException
+ {
+ registeredReadyLatch.countDown();
+
+ registeredReadyLatch.await();
+ }
+
+ boolean created() throws InterruptedException
+ {
+ return created.get();
+ }
+
+ void doneCreation()
+ {
+ created.getAndSet(true);
+ }
+
+ public IoService getService()
+ {
+ return manager;
+ }
+
+ public IoServiceConfig getServiceConfig()
+ {
+ return serviceConfig;
+ }
+
+ public IoSessionConfig getConfig()
+ {
+ return config;
+ }
+
+ SocketIoProcessor getIoProcessor()
+ {
+ return ioProcessor;
+ }
+
+ public IoFilterChain getFilterChain()
+ {
+ return filterChain;
+ }
+
+ SocketChannel getChannel()
+ {
+ return ch;
+ }
+
+ IoServiceListenerSupport getServiceListeners()
+ {
+ return serviceListeners;
+ }
+
+ SelectionKey getSelectionKey()
+ {
+ return readKey;
+ }
+
+ SelectionKey getReadSelectionKey()
+ {
+ return readKey;
+ }
+
+ SelectionKey getWriteSelectionKey()
+ {
+ return writeKey;
+ }
+
+ void setSelectionKey(SelectionKey key)
+ {
+ this.readKey = key;
+ }
+
+ void setWriteSelectionKey(SelectionKey key)
+ {
+ this.writeKey = key;
+ }
+
+ public IoHandler getHandler()
+ {
+ return handler;
+ }
+
+ protected void close0()
+ {
+ filterChain.fireFilterClose( this );
+ }
+
+ Queue getWriteRequestQueue()
+ {
+ return writeRequestQueue;
+ }
+
+ /**
+ @return int Number of write scheduled write requests
+ @deprecated
+ */
+ public int getScheduledWriteMessages()
+ {
+ return getScheduledWriteRequests();
+ }
+
+ public int getScheduledWriteRequests()
+ {
+ synchronized( writeRequestQueue )
+ {
+ return writeRequestQueue.size();
+ }
+ }
+
+ public int getScheduledWriteBytes()
+ {
+ synchronized( writeRequestQueue )
+ {
+ return writeRequestQueue.byteSize();
+ }
+ }
+
+ protected void write0( WriteRequest writeRequest )
+ {
+ filterChain.fireFilterWrite( this, writeRequest );
+ }
+
+ public TransportType getTransportType()
+ {
+ return TransportType.SOCKET;
+ }
+
+ public SocketAddress getRemoteAddress()
+ {
+ //This is what I had previously
+// return ch.socket().getRemoteSocketAddress();
+ return remoteAddress;
+ }
+
+ public SocketAddress getLocalAddress()
+ {
+ //This is what I had previously
+// return ch.socket().getLocalSocketAddress();
+ return localAddress;
+ }
+
+ public SocketAddress getServiceAddress()
+ {
+ return serviceAddress;
+ }
+
+ protected void updateTrafficMask()
+ {
+ this.ioProcessor.updateTrafficMask( this );
+ }
+
+ int getReadBufferSize()
+ {
+ return readBufferSize;
+ }
+
+ private class SessionConfigImpl extends BaseIoSessionConfig implements SocketSessionConfig
+ {
+ public boolean isKeepAlive()
+ {
+ try
+ {
+ return ch.socket().getKeepAlive();
+ }
+ catch( SocketException e )
+ {
+ throw new RuntimeIOException( e );
+ }
+ }
+
+ public void setKeepAlive( boolean on )
+ {
+ try
+ {
+ ch.socket().setKeepAlive( on );
+ }
+ catch( SocketException e )
+ {
+ throw new RuntimeIOException( e );
+ }
+ }
+
+ public boolean isOobInline()
+ {
+ try
+ {
+ return ch.socket().getOOBInline();
+ }
+ catch( SocketException e )
+ {
+ throw new RuntimeIOException( e );
+ }
+ }
+
+ public void setOobInline( boolean on )
+ {
+ try
+ {
+ ch.socket().setOOBInline( on );
+ }
+ catch( SocketException e )
+ {
+ throw new RuntimeIOException( e );
+ }
+ }
+
+ public boolean isReuseAddress()
+ {
+ try
+ {
+ return ch.socket().getReuseAddress();
+ }
+ catch( SocketException e )
+ {
+ throw new RuntimeIOException( e );
+ }
+ }
+
+ public void setReuseAddress( boolean on )
+ {
+ try
+ {
+ ch.socket().setReuseAddress( on );
+ }
+ catch( SocketException e )
+ {
+ throw new RuntimeIOException( e );
+ }
+ }
+
+ public int getSoLinger()
+ {
+ try
+ {
+ return ch.socket().getSoLinger();
+ }
+ catch( SocketException e )
+ {
+ throw new RuntimeIOException( e );
+ }
+ }
+
+ public void setSoLinger( int linger )
+ {
+ try
+ {
+ if( linger < 0 )
+ {
+ ch.socket().setSoLinger( false, 0 );
+ }
+ else
+ {
+ ch.socket().setSoLinger( true, linger );
+ }
+ }
+ catch( SocketException e )
+ {
+ throw new RuntimeIOException( e );
+ }
+ }
+
+ public boolean isTcpNoDelay()
+ {
+ try
+ {
+ return ch.socket().getTcpNoDelay();
+ }
+ catch( SocketException e )
+ {
+ throw new RuntimeIOException( e );
+ }
+ }
+
+ public void setTcpNoDelay( boolean on )
+ {
+ try
+ {
+ ch.socket().setTcpNoDelay( on );
+ }
+ catch( SocketException e )
+ {
+ throw new RuntimeIOException( e );
+ }
+ }
+
+ public int getTrafficClass()
+ {
+ if( SocketSessionConfigImpl.isGetTrafficClassAvailable() )
+ {
+ try
+ {
+ return ch.socket().getTrafficClass();
+ }
+ catch( SocketException e )
+ {
+ // Throw an exception only when setTrafficClass is also available.
+ if( SocketSessionConfigImpl.isSetTrafficClassAvailable() )
+ {
+ throw new RuntimeIOException( e );
+ }
+ }
+ }
+
+ return 0;
+ }
+
+ public void setTrafficClass( int tc )
+ {
+ if( SocketSessionConfigImpl.isSetTrafficClassAvailable() )
+ {
+ try
+ {
+ ch.socket().setTrafficClass( tc );
+ }
+ catch( SocketException e )
+ {
+ throw new RuntimeIOException( e );
+ }
+ }
+ }
+
+ public int getSendBufferSize()
+ {
+ try
+ {
+ return ch.socket().getSendBufferSize();
+ }
+ catch( SocketException e )
+ {
+ throw new RuntimeIOException( e );
+ }
+ }
+
+ public void setSendBufferSize( int size )
+ {
+ if( SocketSessionConfigImpl.isSetSendBufferSizeAvailable() )
+ {
+ try
+ {
+ ch.socket().setSendBufferSize( size );
+ }
+ catch( SocketException e )
+ {
+ throw new RuntimeIOException( e );
+ }
+ }
+ }
+
+ public int getReceiveBufferSize()
+ {
+ try
+ {
+ return ch.socket().getReceiveBufferSize();
+ }
+ catch( SocketException e )
+ {
+ throw new RuntimeIOException( e );
+ }
+ }
+
+ public void setReceiveBufferSize( int size )
+ {
+ if( SocketSessionConfigImpl.isSetReceiveBufferSizeAvailable() )
+ {
+ try
+ {
+ ch.socket().setReceiveBufferSize( size );
+ MultiThreadSocketSessionImpl.this.readBufferSize = size;
+ }
+ catch( SocketException e )
+ {
+ throw new RuntimeIOException( e );
+ }
+ }
+ }
+ }
+}
diff --git a/qpid/java/common/src/main/java/org/apache/mina/transport/vmpipe/QpidVmPipeConnector.java b/qpid/java/common/src/main/java/org/apache/mina/transport/vmpipe/QpidVmPipeConnector.java
new file mode 100644
index 0000000000..a23e546af5
--- /dev/null
+++ b/qpid/java/common/src/main/java/org/apache/mina/transport/vmpipe/QpidVmPipeConnector.java
@@ -0,0 +1,151 @@
+/*
+ * 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.mina.transport.vmpipe;
+
+import java.io.IOException;
+import java.net.SocketAddress;
+
+import org.apache.mina.common.ConnectFuture;
+import org.apache.mina.common.ExceptionMonitor;
+import org.apache.mina.common.IoFilterChain;
+import org.apache.mina.common.IoHandler;
+import org.apache.mina.common.IoServiceConfig;
+import org.apache.mina.common.IoSessionConfig;
+import org.apache.mina.common.support.AbstractIoFilterChain;
+import org.apache.mina.common.support.BaseIoConnector;
+import org.apache.mina.common.support.BaseIoConnectorConfig;
+import org.apache.mina.common.support.BaseIoSessionConfig;
+import org.apache.mina.common.support.DefaultConnectFuture;
+import org.apache.mina.transport.vmpipe.support.VmPipe;
+import org.apache.mina.transport.vmpipe.support.VmPipeIdleStatusChecker;
+import org.apache.mina.transport.vmpipe.support.VmPipeSessionImpl;
+import org.apache.mina.util.AnonymousSocketAddress;
+
+/**
+ * Connects to {@link IoHandler}s which is bound on the specified
+ * {@link VmPipeAddress}.
+ *
+ * @author The Apache Directory Project (mina-dev@directory.apache.org)
+ * @version $Rev: 619823 $, $Date: 2008-02-08 10:09:37 +0000 (Fri, 08 Feb 2008) $
+ */
+public class QpidVmPipeConnector extends VmPipeConnector
+{
+ private static final IoSessionConfig CONFIG = new BaseIoSessionConfig() {};
+ private final IoServiceConfig defaultConfig = new BaseIoConnectorConfig()
+ {
+ public IoSessionConfig getSessionConfig()
+ {
+ return CONFIG;
+ }
+ };
+
+ /**
+ * Creates a new instance.
+ */
+ public QpidVmPipeConnector()
+ {
+ }
+
+ public ConnectFuture connect( SocketAddress address, IoHandler handler, IoServiceConfig config )
+ {
+ return connect( address, null, handler, config );
+ }
+
+ public ConnectFuture connect( SocketAddress address, SocketAddress localAddress, IoHandler handler, IoServiceConfig config )
+ {
+ if( address == null )
+ throw new NullPointerException( "address" );
+ if( handler == null )
+ throw new NullPointerException( "handler" );
+ if( ! ( address instanceof VmPipeAddress ) )
+ throw new IllegalArgumentException(
+ "address must be VmPipeAddress." );
+
+ if( config == null )
+ {
+ config = getDefaultConfig();
+ }
+
+ VmPipe entry = ( VmPipe ) VmPipeAcceptor.boundHandlers.get( address );
+ if( entry == null )
+ {
+ return DefaultConnectFuture.newFailedFuture(
+ new IOException( "Endpoint unavailable: " + address ) );
+ }
+
+ DefaultConnectFuture future = new DefaultConnectFuture();
+ VmPipeSessionImpl localSession =
+ new VmPipeSessionImpl(
+ this,
+ config,
+ getListeners(),
+ new Object(), // lock
+ new AnonymousSocketAddress(),
+ handler,
+ entry );
+
+ // initialize acceptor session
+ VmPipeSessionImpl remoteSession = localSession.getRemoteSession();
+ try
+ {
+ IoFilterChain filterChain = remoteSession.getFilterChain();
+ entry.getAcceptor().getFilterChainBuilder().buildFilterChain( filterChain );
+ entry.getConfig().getFilterChainBuilder().buildFilterChain( filterChain );
+ entry.getConfig().getThreadModel().buildFilterChain( filterChain );
+
+ // The following sentences don't throw any exceptions.
+ entry.getListeners().fireSessionCreated( remoteSession );
+ VmPipeIdleStatusChecker.getInstance().addSession( remoteSession );
+ }
+ catch( Throwable t )
+ {
+ ExceptionMonitor.getInstance().exceptionCaught( t );
+ remoteSession.close();
+ }
+
+
+ // initialize connector session
+ try
+ {
+ IoFilterChain filterChain = localSession.getFilterChain();
+ this.getFilterChainBuilder().buildFilterChain( filterChain );
+ config.getFilterChainBuilder().buildFilterChain( filterChain );
+ config.getThreadModel().buildFilterChain( filterChain );
+
+ // The following sentences don't throw any exceptions.
+ localSession.setAttribute( AbstractIoFilterChain.CONNECT_FUTURE, future );
+ getListeners().fireSessionCreated( localSession );
+ VmPipeIdleStatusChecker.getInstance().addSession( localSession);
+ }
+ catch( Throwable t )
+ {
+ future.setException( t );
+ }
+
+
+
+ return future;
+ }
+
+ public IoServiceConfig getDefaultConfig()
+ {
+ return defaultConfig;
+ }
+} \ No newline at end of file
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/AMQChannelException.java b/qpid/java/common/src/main/java/org/apache/qpid/AMQChannelException.java
index 2f6290b55a..ef9420ba87 100644
--- a/qpid/java/common/src/main/java/org/apache/qpid/AMQChannelException.java
+++ b/qpid/java/common/src/main/java/org/apache/qpid/AMQChannelException.java
@@ -54,7 +54,6 @@ public class AMQChannelException extends AMQException
public AMQFrame getCloseFrame(int channel)
{
MethodRegistry reg = MethodRegistry.getMethodRegistry(new ProtocolVersion(major,minor));
- return new AMQFrame(channel, reg.createChannelCloseBody(getErrorCode() == null ? AMQConstant.INTERNAL_ERROR.getCode() : getErrorCode().getCode(), getMessageAsShortString(),_classId,_methodId));
+ return new AMQFrame(channel, reg.createChannelCloseBody(getErrorCode() == null ? AMQConstant.INTERNAL_ERROR.getCode() : getErrorCode().getCode(), new AMQShortString(getMessage()),_classId,_methodId));
}
-
}
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/AMQConnectionException.java b/qpid/java/common/src/main/java/org/apache/qpid/AMQConnectionException.java
index ca9c9f9dc4..8ef6facef1 100644
--- a/qpid/java/common/src/main/java/org/apache/qpid/AMQConnectionException.java
+++ b/qpid/java/common/src/main/java/org/apache/qpid/AMQConnectionException.java
@@ -62,10 +62,9 @@ public class AMQConnectionException extends AMQException
MethodRegistry reg = MethodRegistry.getMethodRegistry(new ProtocolVersion(major,minor));
return new AMQFrame(0,
reg.createConnectionCloseBody(getErrorCode().getCode(),
- getMessageAsShortString(),
+ new AMQShortString(getMessage()),
_classId,
_methodId));
}
-
}
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/AMQException.java b/qpid/java/common/src/main/java/org/apache/qpid/AMQException.java
index 86d439d269..b0c6fccc9e 100644
--- a/qpid/java/common/src/main/java/org/apache/qpid/AMQException.java
+++ b/qpid/java/common/src/main/java/org/apache/qpid/AMQException.java
@@ -20,7 +20,6 @@
*/
package org.apache.qpid;
-import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.protocol.AMQConstant;
/**
@@ -122,19 +121,4 @@ public class AMQException extends Exception
return newAMQE;
}
-
- /**
- * Truncates the exception message to 255 characters if its length exceeds 255.
- *
- * @return exception message
- */
- public AMQShortString getMessageAsShortString()
- {
- String message = getMessage();
- if (message != null && message.length() > AMQShortString.MAX_LENGTH)
- {
- message = message.substring(0, AMQShortString.MAX_LENGTH - 3) + "...";
- }
- return new AMQShortString(message);
- }
}
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/ToyBroker.java b/qpid/java/common/src/main/java/org/apache/qpid/ToyBroker.java
new file mode 100644
index 0000000000..5423bbb68f
--- /dev/null
+++ b/qpid/java/common/src/main/java/org/apache/qpid/ToyBroker.java
@@ -0,0 +1,208 @@
+/*
+ *
+ * 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;
+
+import org.apache.qpid.transport.*;
+import org.apache.qpid.transport.network.mina.MinaHandler;
+
+import static org.apache.qpid.transport.util.Functions.str;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.LinkedBlockingQueue;
+
+
+/**
+ * ToyBroker
+ *
+ * @author Rafael H. Schloming
+ */
+
+class ToyBroker extends SessionDelegate
+{
+
+ private ToyExchange exchange;
+ private Map<String,Consumer> consumers = new ConcurrentHashMap<String,Consumer>();
+
+ public ToyBroker(ToyExchange exchange)
+ {
+ this.exchange = exchange;
+ }
+
+ public void messageAcquire(Session context, MessageAcquire struct)
+ {
+ System.out.println("\n==================> messageAcquire " );
+ context.executionResult((int) struct.getId(), new Acquired(struct.getTransfers()));
+ }
+
+ @Override public void queueDeclare(Session ssn, QueueDeclare qd)
+ {
+ exchange.createQueue(qd.getQueue());
+ System.out.println("\n==================> declared queue: " + qd.getQueue() + "\n");
+ }
+
+ @Override public void exchangeBind(Session ssn, ExchangeBind qb)
+ {
+ exchange.bindQueue(qb.getExchange(), qb.getBindingKey(),qb.getQueue());
+ System.out.println("\n==================> bound queue: " + qb.getQueue() + " with binding key " + qb.getBindingKey() + "\n");
+ }
+
+ @Override public void queueQuery(Session ssn, QueueQuery qq)
+ {
+ QueueQueryResult result = new QueueQueryResult().queue(qq.getQueue());
+ ssn.executionResult((int) qq.getId(), result);
+ }
+
+ @Override public void messageSubscribe(Session ssn, MessageSubscribe ms)
+ {
+ Consumer c = new Consumer();
+ c._queueName = ms.getQueue();
+ consumers.put(ms.getDestination(),c);
+ System.out.println("\n==================> message subscribe : " + ms.getDestination() + " queue: " + ms.getQueue() + "\n");
+ }
+
+ @Override public void messageFlow(Session ssn,MessageFlow struct)
+ {
+ Consumer c = consumers.get(struct.getDestination());
+ c._credit = struct.getValue();
+ System.out.println("\n==================> message flow : " + struct.getDestination() + " credit: " + struct.getValue() + "\n");
+ }
+
+ @Override public void messageFlush(Session ssn,MessageFlush struct)
+ {
+ System.out.println("\n==================> message flush for consumer : " + struct.getDestination() + "\n");
+ checkAndSendMessagesToConsumer(ssn,struct.getDestination());
+ }
+
+ @Override public void messageTransfer(Session ssn, MessageTransfer xfr)
+ {
+ String dest = xfr.getDestination();
+ System.out.println("received transfer " + dest);
+ Header header = xfr.getHeader();
+ DeliveryProperties props = header.get(DeliveryProperties.class);
+ if (props != null)
+ {
+ System.out.println("received headers routing_key " + props.getRoutingKey());
+ }
+
+ MessageProperties mp = header.get(MessageProperties.class);
+ System.out.println("MP: " + mp);
+ if (mp != null)
+ {
+ System.out.println(mp.getApplicationHeaders());
+ }
+
+ if (exchange.route(dest,props == null ? null : props.getRoutingKey(),xfr))
+ {
+ System.out.println("queued " + xfr);
+ dispatchMessages(ssn);
+ }
+ else
+ {
+
+ if (props == null || !props.getDiscardUnroutable())
+ {
+ RangeSet ranges = new RangeSet();
+ ranges.add(xfr.getId());
+ ssn.messageReject(ranges, MessageRejectCode.UNROUTABLE,
+ "no such destination");
+ }
+ }
+ ssn.processed(xfr);
+ }
+
+ private void transferMessageToPeer(Session ssn,String dest, MessageTransfer m)
+ {
+ System.out.println("\n==================> Transfering message to: " +dest + "\n");
+ ssn.messageTransfer(m.getDestination(), MessageAcceptMode.EXPLICIT,
+ MessageAcquireMode.PRE_ACQUIRED,
+ m.getHeader(), m.getBody());
+ }
+
+ private void dispatchMessages(Session ssn)
+ {
+ for (String dest: consumers.keySet())
+ {
+ checkAndSendMessagesToConsumer(ssn,dest);
+ }
+ }
+
+ private void checkAndSendMessagesToConsumer(Session ssn,String dest)
+ {
+ Consumer c = consumers.get(dest);
+ LinkedBlockingQueue<MessageTransfer> queue = exchange.getQueue(c._queueName);
+ MessageTransfer m = queue.poll();
+ while (m != null && c._credit>0)
+ {
+ transferMessageToPeer(ssn,dest,m);
+ c._credit--;
+ m = queue.poll();
+ }
+ }
+
+ // ugly, but who cares :)
+ // assumes unit is always no of messages, not bytes
+ // assumes it's credit mode and not window
+ private static class Consumer
+ {
+ long _credit;
+ String _queueName;
+ }
+
+ private static final class ToyBrokerSession extends Session
+ {
+
+ public ToyBrokerSession(Connection connection, Binary name, long expiry, ToyExchange exchange)
+ {
+ super(connection, new ToyBroker(exchange), name, expiry);
+ }
+ }
+
+ public static final void main(String[] args) throws IOException
+ {
+ final ToyExchange exchange = new ToyExchange();
+ ConnectionDelegate delegate = new ServerDelegate()
+ {
+ @Override
+ public void init(Connection conn, ProtocolHeader hdr)
+ {
+ conn.setSessionFactory(new Connection.SessionFactory()
+ {
+ public Session newSession(Connection conn, Binary name, long expiry)
+ {
+ return new ToyBrokerSession(conn, name, expiry, exchange);
+ }
+ });
+
+ super.init(conn, hdr); //To change body of overridden methods use File | Settings | File Templates.
+ }
+
+ };
+
+ MinaHandler.accept("0.0.0.0", 5672, delegate);
+ }
+
+}
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
new file mode 100644
index 0000000000..5b2db10613
--- /dev/null
+++ b/qpid/java/common/src/main/java/org/apache/qpid/ToyClient.java
@@ -0,0 +1,108 @@
+/*
+ *
+ * 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;
+
+import java.nio.*;
+import java.util.*;
+
+import org.apache.qpid.transport.*;
+import org.apache.qpid.transport.network.mina.MinaHandler;
+
+
+/**
+ * ToyClient
+ *
+ * @author Rafael H. Schloming
+ */
+
+class ToyClient implements SessionListener
+{
+ public void opened(Session ssn) {}
+
+ public void resumed(Session ssn) {}
+
+ public void exception(Session ssn, SessionException exc)
+ {
+ exc.printStackTrace();
+ }
+
+ public void message(Session ssn, MessageTransfer xfr)
+ {
+ System.out.println("msg: " + xfr);
+ }
+
+ public void closed(Session ssn) {}
+
+ public static final void main(String[] args)
+ {
+ Connection conn = new Connection();
+ conn.connect("0.0.0.0", 5672, null, "guest", "guest", false);
+ Session ssn = conn.createSession();
+ ssn.setSessionListener(new ToyClient());
+
+ ssn.queueDeclare("asdf", null, null);
+ ssn.sync();
+
+ Map<String,Object> nested = new LinkedHashMap<String,Object>();
+ nested.put("list", Arrays.asList("one", "two", "three"));
+ Map<String,Object> map = new LinkedHashMap<String,Object>();
+
+ map.put("str", "this is a string");
+
+ map.put("+int", 3);
+ map.put("-int", -3);
+ map.put("maxint", Integer.MAX_VALUE);
+ map.put("minint", Integer.MIN_VALUE);
+
+ map.put("+short", (short) 1);
+ map.put("-short", (short) -1);
+ map.put("maxshort", (short) Short.MAX_VALUE);
+ map.put("minshort", (short) Short.MIN_VALUE);
+
+ map.put("float", (float) 3.3);
+ map.put("double", 4.9);
+ map.put("char", 'c');
+
+ map.put("table", nested);
+ map.put("list", Arrays.asList(1, 2, 3));
+ map.put("binary", new byte[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10});
+
+ ssn.messageTransfer("asdf", MessageAcceptMode.EXPLICIT,
+ MessageAcquireMode.PRE_ACQUIRED,
+ new Header(new DeliveryProperties(),
+ new MessageProperties()
+ .setApplicationHeaders(map)),
+ "this is the data");
+
+ ssn.messageTransfer("fdsa", MessageAcceptMode.EXPLICIT,
+ MessageAcquireMode.PRE_ACQUIRED,
+ null,
+ "this should be rejected");
+ ssn.sync();
+
+ Future<QueueQueryResult> future = ssn.queueQuery("asdf");
+ System.out.println(future.get().getQueue());
+ ssn.sync();
+ ssn.close();
+ conn.close();
+ }
+
+}
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/ToyExchange.java b/qpid/java/common/src/main/java/org/apache/qpid/ToyExchange.java
new file mode 100644
index 0000000000..da6aed9629
--- /dev/null
+++ b/qpid/java/common/src/main/java/org/apache/qpid/ToyExchange.java
@@ -0,0 +1,154 @@
+package org.apache.qpid;
+/*
+ *
+ * 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 java.util.ArrayList;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.qpid.transport.MessageTransfer;
+
+
+public class ToyExchange
+{
+ final static String DIRECT = "amq.direct";
+ final static String TOPIC = "amq.topic";
+
+ private Map<String,List<LinkedBlockingQueue<MessageTransfer>>> directEx = new HashMap<String,List<LinkedBlockingQueue<MessageTransfer>>>();
+ private Map<String,List<LinkedBlockingQueue<MessageTransfer>>> topicEx = new HashMap<String,List<LinkedBlockingQueue<MessageTransfer>>>();
+ private Map<String,LinkedBlockingQueue<MessageTransfer>> queues = new HashMap<String,LinkedBlockingQueue<MessageTransfer>>();
+
+ public void createQueue(String name)
+ {
+ queues.put(name, new LinkedBlockingQueue<MessageTransfer>());
+ }
+
+ public LinkedBlockingQueue<MessageTransfer> getQueue(String name)
+ {
+ return queues.get(name);
+ }
+
+ public void bindQueue(String type,String binding,String queueName)
+ {
+ LinkedBlockingQueue<MessageTransfer> queue = queues.get(queueName);
+ binding = normalizeKey(binding);
+ if(DIRECT.equals(type))
+ {
+
+ if (directEx.containsKey(binding))
+ {
+ List<LinkedBlockingQueue<MessageTransfer>> list = directEx.get(binding);
+ list.add(queue);
+ }
+ else
+ {
+ List<LinkedBlockingQueue<MessageTransfer>> list = new LinkedList<LinkedBlockingQueue<MessageTransfer>>();
+ list.add(queue);
+ directEx.put(binding,list);
+ }
+ }
+ else
+ {
+ if (topicEx.containsKey(binding))
+ {
+ List<LinkedBlockingQueue<MessageTransfer>> list = topicEx.get(binding);
+ list.add(queue);
+ }
+ else
+ {
+ List<LinkedBlockingQueue<MessageTransfer>> list = new LinkedList<LinkedBlockingQueue<MessageTransfer>>();
+ list.add(queue);
+ topicEx.put(binding,list);
+ }
+ }
+ }
+
+ public boolean route(String dest, String routingKey, MessageTransfer msg)
+ {
+ List<LinkedBlockingQueue<MessageTransfer>> queues;
+ if(DIRECT.equals(dest))
+ {
+ queues = directEx.get(routingKey);
+ }
+ else
+ {
+ queues = matchWildCard(routingKey);
+ }
+ if(queues != null && queues.size()>0)
+ {
+ System.out.println("Message stored in " + queues.size() + " queues");
+ storeMessage(msg,queues);
+ return true;
+ }
+ else
+ {
+ System.out.println("Message unroutable " + msg);
+ return false;
+ }
+ }
+
+ private String normalizeKey(String routingKey)
+ {
+ if(routingKey.indexOf(".*")>1)
+ {
+ return routingKey.substring(0,routingKey.indexOf(".*"));
+ }
+ else
+ {
+ return routingKey;
+ }
+ }
+
+ private List<LinkedBlockingQueue<MessageTransfer>> matchWildCard(String routingKey)
+ {
+ List<LinkedBlockingQueue<MessageTransfer>> selected = new ArrayList<LinkedBlockingQueue<MessageTransfer>>();
+
+ for(String key: topicEx.keySet())
+ {
+ Pattern p = Pattern.compile(key);
+ Matcher m = p.matcher(routingKey);
+ if (m.find())
+ {
+ for(LinkedBlockingQueue<MessageTransfer> queue : topicEx.get(key))
+ {
+ selected.add(queue);
+ }
+ }
+ }
+
+ return selected;
+ }
+
+ private void storeMessage(MessageTransfer msg,List<LinkedBlockingQueue<MessageTransfer>> selected)
+ {
+ for(LinkedBlockingQueue<MessageTransfer> queue : selected)
+ {
+ queue.offer(msg);
+ }
+ }
+
+}
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/configuration/ClientProperties.java b/qpid/java/common/src/main/java/org/apache/qpid/configuration/ClientProperties.java
index 36f9a1ae2d..0dd21238a7 100644
--- a/qpid/java/common/src/main/java/org/apache/qpid/configuration/ClientProperties.java
+++ b/qpid/java/common/src/main/java/org/apache/qpid/configuration/ClientProperties.java
@@ -23,7 +23,7 @@ package org.apache.qpid.configuration;
*/
public class ClientProperties
{
-
+
/**
* Currently with Qpid it is not possible to change the client ID.
* If one is not specified upon connection construction, an id is generated automatically.
@@ -68,40 +68,67 @@ public class ClientProperties
* by the broker in TuneOK it will be used as the heartbeat interval.
* If not a warning will be printed and the max value specified for
* heartbeat in TuneOK will be used
- *
+ *
* The default idle timeout is set to 120 secs
*/
public static final String IDLE_TIMEOUT_PROP_NAME = "idle_timeout";
public static final long DEFAULT_IDLE_TIMEOUT = 120000;
-
+
public static final String HEARTBEAT = "qpid.heartbeat";
public static final int HEARTBEAT_DEFAULT = 120;
-
+
/**
* This value will be used to determine the default destination syntax type.
* Currently the two types are Binding URL (java only) and the Addressing format (used by
- * all clients).
+ * all clients).
*/
public static final String DEST_SYNTAX = "qpid.dest_syntax";
-
+
public static final String USE_LEGACY_MAP_MESSAGE_FORMAT = "qpid.use_legacy_map_message";
- public static final String AMQP_VERSION = "qpid.amqp.version";
+ /**
+ * ==========================================================
+ * Those properties are used when the io size should be bounded
+ * ==========================================================
+ */
- public static final String QPID_VERIFY_CLIENT_ID = "qpid.verify_client_id";
+ /**
+ * When set to true the io layer throttle down producers and consumers
+ * when written or read messages are accumulating and exceeding a certain size.
+ * This is especially useful when a the producer rate is greater than the network
+ * speed.
+ * type: boolean
+ */
+ public static final String PROTECTIO_PROP_NAME = "protectio";
- private static ClientProperties _instance = new ClientProperties();
+ //=== The following properties are only used when the previous one is true.
+ /**
+ * Max size of read messages that can be stored within the MINA layer
+ * type: int
+ */
+ public static final String READ_BUFFER_LIMIT_PROP_NAME = "qpid.read.buffer.limit";
+ public static final String READ_BUFFER_LIMIT_DEFAULT = "262144";
+ /**
+ * Max size of written messages that can be stored within the MINA layer
+ * type: int
+ */
+ public static final String WRITE_BUFFER_LIMIT_PROP_NAME = "qpid.read.buffer.limit";
+ public static final String WRITE_BUFFER_LIMIT_DEFAULT = "262144";
+ public static final String AMQP_VERSION = "qpid.amqp.version";
+
+ private static ClientProperties _instance = new ClientProperties();
+
/*
- public static final QpidProperty<Boolean> IGNORE_SET_CLIENTID_PROP_NAME =
+ public static final QpidProperty<Boolean> IGNORE_SET_CLIENTID_PROP_NAME =
QpidProperty.booleanProperty(false,"qpid.ignore_set_client_id","ignore_setclientID");
-
+
public static final QpidProperty<Boolean> SYNC_PERSISTENT_PROP_NAME =
QpidProperty.booleanProperty(false,"qpid.sync_persistence","sync_persistence");
-
-
+
+
public static final QpidProperty<Integer> MAX_PREFETCH_PROP_NAME =
QpidProperty.intProperty(500,"qpid.max_prefetch","max_prefetch"); */
-
-
+
+
}
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/framing/AMQShortString.java b/qpid/java/common/src/main/java/org/apache/qpid/framing/AMQShortString.java
index 2b9e2ffaba..39a9beb9e8 100644
--- a/qpid/java/common/src/main/java/org/apache/qpid/framing/AMQShortString.java
+++ b/qpid/java/common/src/main/java/org/apache/qpid/framing/AMQShortString.java
@@ -37,10 +37,6 @@ import java.lang.ref.WeakReference;
*/
public final class AMQShortString implements CharSequence, Comparable<AMQShortString>
{
- /**
- * The maximum number of octets in AMQ short string as defined in AMQP specification
- */
- public static final int MAX_LENGTH = 255;
private static final byte MINUS = (byte)'-';
private static final byte ZERO = (byte) '0';
@@ -122,19 +118,22 @@ public final class AMQShortString implements CharSequence, Comparable<AMQShortSt
public AMQShortString(byte[] data)
{
- if (data == null)
- {
- throw new NullPointerException("Cannot create AMQShortString with null data[]");
- }
- if (data.length > MAX_LENGTH)
- {
- throw new IllegalArgumentException("Cannot create AMQShortString with number of octets over 255!");
- }
+
_data = data.clone();
_length = data.length;
_offset = 0;
}
+ public AMQShortString(byte[] data, int pos)
+ {
+ final int size = data[pos++];
+ final byte[] dataCopy = new byte[size];
+ System.arraycopy(data,pos,dataCopy,0,size);
+ _length = size;
+ _data = dataCopy;
+ _offset = 0;
+ }
+
public AMQShortString(String data)
{
this((data == null) ? EMPTY_CHAR_ARRAY : data.toCharArray());
@@ -147,12 +146,7 @@ public final class AMQShortString implements CharSequence, Comparable<AMQShortSt
{
throw new NullPointerException("Cannot create AMQShortString with null char[]");
}
- // the current implementation of 0.8/0.9.x short string encoding
- // supports only ASCII characters
- if (data.length> MAX_LENGTH)
- {
- throw new IllegalArgumentException("Cannot create AMQShortString with number of octets over 255!");
- }
+
final int length = data.length;
final byte[] stringBytes = new byte[length];
int hash = 0;
@@ -171,17 +165,6 @@ public final class AMQShortString implements CharSequence, Comparable<AMQShortSt
public AMQShortString(CharSequence charSequence)
{
- if (charSequence == null)
- {
- // it should be possible to create short string for null data
- charSequence = "";
- }
- // the current implementation of 0.8/0.9.x short string encoding
- // supports only ASCII characters
- if (charSequence.length() > MAX_LENGTH)
- {
- throw new IllegalArgumentException("Cannot create AMQShortString with number of octets over 255!");
- }
final int length = charSequence.length();
final byte[] stringBytes = new byte[length];
int hash = 0;
@@ -201,10 +184,6 @@ public final class AMQShortString implements CharSequence, Comparable<AMQShortSt
private AMQShortString(ByteBuffer data, final int length)
{
- if (length > MAX_LENGTH)
- {
- throw new IllegalArgumentException("Cannot create AMQShortString with number of octets over 255!");
- }
if(data.isDirect() || data.isReadOnly())
{
byte[] dataBytes = new byte[length];
@@ -226,17 +205,8 @@ public final class AMQShortString implements CharSequence, Comparable<AMQShortSt
private AMQShortString(final byte[] data, final int from, final int to)
{
- if (data == null)
- {
- throw new NullPointerException("Cannot create AMQShortString with null data[]");
- }
- int length = to - from;
- if (length > MAX_LENGTH)
- {
- throw new IllegalArgumentException("Cannot create AMQShortString with number of octets over 255!");
- }
_offset = from;
- _length = length;
+ _length = to - from;
_data = data;
}
@@ -275,6 +245,29 @@ public final class AMQShortString implements CharSequence, Comparable<AMQShortSt
return new CharSubSequence(start, end);
}
+ public int writeToByteArray(byte[] encoding, int pos)
+ {
+ final int size = length();
+ encoding[pos++] = (byte) size;
+ System.arraycopy(_data,_offset,encoding,pos,size);
+ return pos+size;
+ }
+
+ public static AMQShortString readFromByteArray(byte[] byteEncodedDestination, int pos)
+ {
+
+
+ final AMQShortString shortString = new AMQShortString(byteEncodedDestination, pos);
+ if(shortString.length() == 0)
+ {
+ return null;
+ }
+ else
+ {
+ return shortString;
+ }
+ }
+
public static AMQShortString readFromBuffer(ByteBuffer buffer)
{
final short length = buffer.getUnsigned();
@@ -697,10 +690,6 @@ public final class AMQShortString implements CharSequence, Comparable<AMQShortSt
size += term.length();
}
- if (size > MAX_LENGTH)
- {
- throw new IllegalArgumentException("Cannot create AMQShortString with number of octets over 255!");
- }
byte[] data = new byte[size];
int pos = 0;
final byte[] delimData = delim._data;
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/framing/ContentHeaderBody.java b/qpid/java/common/src/main/java/org/apache/qpid/framing/ContentHeaderBody.java
index 30db3b8be7..83e5a7e341 100644
--- a/qpid/java/common/src/main/java/org/apache/qpid/framing/ContentHeaderBody.java
+++ b/qpid/java/common/src/main/java/org/apache/qpid/framing/ContentHeaderBody.java
@@ -36,7 +36,7 @@ public class ContentHeaderBody implements AMQBody
public long bodySize;
/** must never be null */
- private ContentHeaderProperties properties;
+ public ContentHeaderProperties properties;
public ContentHeaderBody()
{
@@ -128,14 +128,4 @@ public class ContentHeaderBody implements AMQBody
{
return new AMQFrame(channelId, body);
}
-
- public ContentHeaderProperties getProperties()
- {
- return properties;
- }
-
- public void setProperties(ContentHeaderProperties props)
- {
- properties = props;
- }
}
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/protocol/ProtocolEngine.java b/qpid/java/common/src/main/java/org/apache/qpid/protocol/ProtocolEngine.java
index 48a3df734a..31953ea6ab 100644
--- a/qpid/java/common/src/main/java/org/apache/qpid/protocol/ProtocolEngine.java
+++ b/qpid/java/common/src/main/java/org/apache/qpid/protocol/ProtocolEngine.java
@@ -22,6 +22,8 @@ package org.apache.qpid.protocol;
import java.net.SocketAddress;
+import org.apache.qpid.framing.AMQDataBlock;
+import org.apache.qpid.transport.NetworkDriver;
import org.apache.qpid.transport.Receiver;
/**
@@ -30,6 +32,9 @@ import org.apache.qpid.transport.Receiver;
*/
public interface ProtocolEngine extends Receiver<java.nio.ByteBuffer>
{
+ // Sets the network driver providing data for this ProtocolEngine
+ void setNetworkDriver (NetworkDriver driver);
+
// Returns the remote address of the NetworkDriver
SocketAddress getRemoteAddress();
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/protocol/ProtocolEngineFactory.java b/qpid/java/common/src/main/java/org/apache/qpid/protocol/ProtocolEngineFactory.java
index 4e40b78440..9df84eef90 100644
--- a/qpid/java/common/src/main/java/org/apache/qpid/protocol/ProtocolEngineFactory.java
+++ b/qpid/java/common/src/main/java/org/apache/qpid/protocol/ProtocolEngineFactory.java
@@ -20,12 +20,12 @@
*/
package org.apache.qpid.protocol;
-import org.apache.qpid.transport.network.NetworkConnection;
+import org.apache.qpid.transport.NetworkDriver;
public interface ProtocolEngineFactory
{
// Returns a new instance of a ProtocolEngine
- ProtocolEngine newProtocolEngine(NetworkConnection network);
+ ProtocolEngine newProtocolEngine(NetworkDriver networkDriver);
} \ No newline at end of file
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/thread/QpidThreadExecutor.java b/qpid/java/common/src/main/java/org/apache/qpid/thread/QpidThreadExecutor.java
index 30010a2d89..38f60c04fe 100644
--- a/qpid/java/common/src/main/java/org/apache/qpid/thread/QpidThreadExecutor.java
+++ b/qpid/java/common/src/main/java/org/apache/qpid/thread/QpidThreadExecutor.java
@@ -23,7 +23,7 @@ package org.apache.qpid.thread;
import org.apache.qpid.thread.Threading;
-import java.util.concurrent.Executor;
+import edu.emory.mathcs.backport.java.util.concurrent.Executor;
public class QpidThreadExecutor implements Executor
{
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/transport/ClientDelegate.java b/qpid/java/common/src/main/java/org/apache/qpid/transport/ClientDelegate.java
index c8b7ad2a5e..0d9f8c0b28 100644
--- a/qpid/java/common/src/main/java/org/apache/qpid/transport/ClientDelegate.java
+++ b/qpid/java/common/src/main/java/org/apache/qpid/transport/ClientDelegate.java
@@ -247,7 +247,7 @@ public class ClientDelegate extends ConnectionDelegate
int i = heartbeat;
if (i == 0)
{
- log.info("Idle timeout is 0 sec. Heartbeats are disabled.");
+ log.warn("Idle timeout is zero. Heartbeats are disabled");
return 0; // heartbeats are disabled.
}
else if (i >= min && i <= max)
@@ -256,8 +256,8 @@ public class ClientDelegate extends ConnectionDelegate
}
else
{
- log.info("The broker does not support the configured connection idle timeout of %s sec," +
- " using the brokers max supported value of %s sec instead.", i,max);
+ log.warn("Ignoring the idle timeout %s set by the connection," +
+ " using the brokers max value %s", i,max);
return max;
}
}
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 7d17397b2d..e5e10c0e07 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
@@ -25,10 +25,9 @@ import static org.apache.qpid.transport.Connection.State.CLOSING;
import static org.apache.qpid.transport.Connection.State.NEW;
import static org.apache.qpid.transport.Connection.State.OPEN;
import static org.apache.qpid.transport.Connection.State.OPENING;
+import static org.apache.qpid.transport.Connection.State.RESUMING;
-import java.nio.ByteBuffer;
import java.util.ArrayList;
-import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
@@ -40,13 +39,6 @@ import java.util.concurrent.atomic.AtomicLong;
import javax.security.sasl.SaslClient;
import javax.security.sasl.SaslServer;
-import org.apache.qpid.framing.ProtocolVersion;
-import org.apache.qpid.transport.network.Assembler;
-import org.apache.qpid.transport.network.Disassembler;
-import org.apache.qpid.transport.network.InputHandler;
-import org.apache.qpid.transport.network.NetworkConnection;
-import org.apache.qpid.transport.network.OutgoingNetworkTransport;
-import org.apache.qpid.transport.network.Transport;
import org.apache.qpid.transport.network.security.SecurityLayer;
import org.apache.qpid.transport.util.Logger;
import org.apache.qpid.transport.util.Waiter;
@@ -120,6 +112,7 @@ public class Connection extends ConnectionInvoker
private SaslServer saslServer;
private SaslClient saslClient;
private int idleTimeout = 0;
+ private String _authorizationID;
private Map<String,Object> _serverProperties;
private String userID;
private ConnectionSettings conSettings;
@@ -241,14 +234,13 @@ public class Connection extends ConnectionInvoker
state = OPENING;
userID = settings.getUsername();
delegate = new ClientDelegate(settings);
-
- securityLayer = new SecurityLayer(this);
-
- OutgoingNetworkTransport transport = Transport.getOutgoingTransportInstance(ProtocolVersion.v0_10);
- Receiver<ByteBuffer> receiver = securityLayer.receiver(new InputHandler(new Assembler(this)));
- NetworkConnection network = transport.connect(settings, receiver, null);
- sender = new Disassembler(securityLayer.sender(network.getSender()), settings.getMaxFrameSize());
-
+
+ TransportBuilder transport = new TransportBuilder();
+ transport.init(this);
+ this.sender = transport.buildSenderPipe();
+ transport.buildReceiverPipe(this);
+ this.securityLayer = transport.getSecurityLayer();
+
send(new ProtocolHeader(1, 0, 10));
Waiter w = new Waiter(lock, timeout);
@@ -474,12 +466,11 @@ public class Connection extends ConnectionInvoker
{
synchronized (lock)
{
- List <Binary> transactedSessions = new ArrayList();
for (Session ssn : sessions.values())
{
if (ssn.isTransacted())
- {
- transactedSessions.add(ssn.getName());
+ {
+ removeSession(ssn);
ssn.setState(Session.State.CLOSED);
}
else
@@ -489,11 +480,6 @@ public class Connection extends ConnectionInvoker
ssn.resume();
}
}
-
- for (Binary ssn_name : transactedSessions)
- {
- sessions.remove(ssn_name);
- }
setState(OPEN);
}
}
@@ -659,6 +645,16 @@ public class Connection extends ConnectionInvoker
return idleTimeout;
}
+ public void setAuthorizationID(String authorizationID)
+ {
+ _authorizationID = authorizationID;
+ }
+
+ public String getAuthorizationID()
+ {
+ return _authorizationID;
+ }
+
public String getUserID()
{
return userID;
@@ -699,8 +695,4 @@ public class Connection extends ConnectionInvoker
return connectionLost.get();
}
- protected Collection<Session> getChannels()
- {
- return channels.values();
- }
}
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/transport/ConnectionDelegate.java b/qpid/java/common/src/main/java/org/apache/qpid/transport/ConnectionDelegate.java
index f183c1e241..88dd2d6afa 100644
--- a/qpid/java/common/src/main/java/org/apache/qpid/transport/ConnectionDelegate.java
+++ b/qpid/java/common/src/main/java/org/apache/qpid/transport/ConnectionDelegate.java
@@ -95,7 +95,6 @@ public abstract class ConnectionDelegate
Session ssn = conn.getSession(dtc.getChannel());
if (ssn != null)
{
- ssn.setDetachCode(dtc.getCode());
conn.unmap(ssn);
ssn.closed();
}
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/transport/ConnectionSettings.java b/qpid/java/common/src/main/java/org/apache/qpid/transport/ConnectionSettings.java
index 2074c77a5b..08678b213b 100644
--- a/qpid/java/common/src/main/java/org/apache/qpid/transport/ConnectionSettings.java
+++ b/qpid/java/common/src/main/java/org/apache/qpid/transport/ConnectionSettings.java
@@ -30,8 +30,6 @@ import java.util.Map;
*/
public class ConnectionSettings
{
- public static final String WILDCARD_ADDRESS = "*";
-
String protocol = "tcp";
String host = "localhost";
String vhost;
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/transport/NetworkDriver.java b/qpid/java/common/src/main/java/org/apache/qpid/transport/NetworkDriver.java
new file mode 100644
index 0000000000..86af97bf7e
--- /dev/null
+++ b/qpid/java/common/src/main/java/org/apache/qpid/transport/NetworkDriver.java
@@ -0,0 +1,63 @@
+/*
+ *
+ * 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;
+
+import java.net.BindException;
+import java.net.InetAddress;
+import java.net.SocketAddress;
+
+import org.apache.qpid.protocol.ProtocolEngine;
+import org.apache.qpid.protocol.ProtocolEngineFactory;
+import org.apache.qpid.ssl.SSLContextFactory;
+
+public interface NetworkDriver extends Sender<java.nio.ByteBuffer>
+{
+ // Creates a NetworkDriver which attempts to connect to destination on port and attaches the ProtocolEngine to
+ // it using the SSLContextFactory if provided
+ void open(int port, InetAddress destination, ProtocolEngine engine,
+ NetworkDriverConfiguration config, SSLContextFactory sslFactory)
+ throws OpenException;
+
+ // listens for incoming connections on the specified ports and address and creates a new NetworkDriver which
+ // processes incoming connections with ProtocolEngines and SSLEngines created from the factories
+ // (in the case of an SSLContextFactory, if provided)
+ void bind (int port, InetAddress[] addresses, ProtocolEngineFactory protocolFactory,
+ NetworkDriverConfiguration config, SSLContextFactory sslFactory) throws BindException;
+
+ // Returns the remote address of the underlying socket
+ SocketAddress getRemoteAddress();
+
+ // Returns the local address of the underlying socket
+ SocketAddress getLocalAddress();
+
+ /**
+ * The length of time after which the ProtocolEngines readIdle() method should be called if no data has been
+ * read in seconds
+ */
+ void setMaxReadIdle(int idleTime);
+
+ /**
+ * The length of time after which the ProtocolEngines writeIdle() method should be called if no data has been
+ * written in seconds
+ */
+ void setMaxWriteIdle(int idleTime);
+
+} \ No newline at end of file
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/transport/NetworkDriverConfiguration.java b/qpid/java/common/src/main/java/org/apache/qpid/transport/NetworkDriverConfiguration.java
new file mode 100644
index 0000000000..c38afe5dd5
--- /dev/null
+++ b/qpid/java/common/src/main/java/org/apache/qpid/transport/NetworkDriverConfiguration.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.transport;
+
+/**
+ * This interface provides a means for NetworkDrivers to configure TCP options such as incoming and outgoing
+ * buffer sizes and set particular options on the socket. NetworkDrivers should honour the values returned
+ * from here if the underlying implementation supports them.
+ */
+public interface NetworkDriverConfiguration
+{
+ // Taken from Socket
+ Boolean getKeepAlive();
+ Boolean getOOBInline();
+ Boolean getReuseAddress();
+ Integer getSoLinger(); // null means off
+ Integer getSoTimeout();
+ Boolean getTcpNoDelay();
+ Integer getTrafficClass();
+
+ // The amount of memory in bytes to allocate to the incoming buffer
+ Integer getReceiveBufferSize();
+
+ // The amount of memory in bytes to allocate to the outgoing buffer
+ Integer getSendBufferSize();
+}
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/transport/NetworkTransportConfiguration.java b/qpid/java/common/src/main/java/org/apache/qpid/transport/NetworkTransportConfiguration.java
deleted file mode 100644
index 8d3f7a779a..0000000000
--- a/qpid/java/common/src/main/java/org/apache/qpid/transport/NetworkTransportConfiguration.java
+++ /dev/null
@@ -1,46 +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.transport;
-
-/**
- * This interface provides a means for NetworkDrivers to configure TCP options such as incoming and outgoing
- * buffer sizes and set particular options on the socket. NetworkDrivers should honour the values returned
- * from here if the underlying implementation supports them.
- */
-public interface NetworkTransportConfiguration
-{
- // Taken from Socket
- Boolean getTcpNoDelay();
-
- // The amount of memory in bytes to allocate to the incoming buffer
- Integer getReceiveBufferSize();
-
- // The amount of memory in bytes to allocate to the outgoing buffer
- Integer getSendBufferSize();
-
- Integer getPort();
-
- String getHost();
-
- String getTransport();
-
- Integer getConnectorProcessors();
-}
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/transport/ServerDelegate.java b/qpid/java/common/src/main/java/org/apache/qpid/transport/ServerDelegate.java
index 11af86f412..f21df251da 100644
--- a/qpid/java/common/src/main/java/org/apache/qpid/transport/ServerDelegate.java
+++ b/qpid/java/common/src/main/java/org/apache/qpid/transport/ServerDelegate.java
@@ -75,7 +75,10 @@ public class ServerDelegate extends ConnectionDelegate
if (mechanism == null || mechanism.length() == 0)
{
- tuneAuthorizedConnection(conn);
+ conn.connectionTune
+ (getChannelMax(),
+ org.apache.qpid.transport.network.ConnectionBinding.MAX_FRAME_SIZE,
+ 0, getHeartbeatMax());
return;
}
@@ -94,7 +97,8 @@ public class ServerDelegate extends ConnectionDelegate
}
catch (SaslException e)
{
- connectionAuthFailed(conn, e);
+ conn.exception(e);
+ conn.connectionClose(ConnectionCloseCode.CONNECTION_FORCED, e.getMessage());
}
}
@@ -105,52 +109,33 @@ public class ServerDelegate extends ConnectionDelegate
return ss;
}
- protected void secure(final SaslServer ss, final Connection conn, final byte[] response)
+ private void secure(Connection conn, byte[] response)
{
+ SaslServer ss = conn.getSaslServer();
try
{
byte[] challenge = ss.evaluateResponse(response);
if (ss.isComplete())
{
ss.dispose();
- tuneAuthorizedConnection(conn);
+ conn.connectionTune
+ (getChannelMax(),
+ org.apache.qpid.transport.network.ConnectionBinding.MAX_FRAME_SIZE,
+ 0, getHeartbeatMax());
+ conn.setAuthorizationID(ss.getAuthorizationID());
}
else
{
- connectionAuthContinue(conn, challenge);
+ conn.connectionSecure(challenge);
}
}
catch (SaslException e)
{
- connectionAuthFailed(conn, e);
+ conn.exception(e);
+ conn.connectionClose(ConnectionCloseCode.CONNECTION_FORCED, e.getMessage());
}
}
- protected void connectionAuthFailed(final Connection conn, Exception e)
- {
- conn.exception(e);
- conn.connectionClose(ConnectionCloseCode.CONNECTION_FORCED, e.getMessage());
- }
-
- protected void connectionAuthContinue(final Connection conn, byte[] challenge)
- {
- conn.connectionSecure(challenge);
- }
-
- protected void tuneAuthorizedConnection(final Connection conn)
- {
- conn.connectionTune
- (getChannelMax(),
- org.apache.qpid.transport.network.ConnectionBinding.MAX_FRAME_SIZE,
- 0, getHeartbeatMax());
- }
-
- protected void secure(final Connection conn, final byte[] response)
- {
- final SaslServer ss = conn.getSaslServer();
- secure(ss, conn, response);
- }
-
protected int getHeartbeatMax()
{
return 0xFFFF;
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 e0c6cb29d3..214d4534c1 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
@@ -42,10 +42,7 @@ import static org.apache.qpid.util.Serial.max;
import static org.apache.qpid.util.Strings.toUTF8;
import java.nio.ByteBuffer;
-import java.util.ArrayList;
-import java.util.Arrays;
import java.util.HashMap;
-import java.util.List;
import java.util.Map;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
@@ -120,9 +117,7 @@ public class Session extends SessionInvoker
private Thread resumer = null;
private boolean transacted = false;
- private SessionDetachCode detachCode;
- private final Object stateLock = new Object();
-
+
protected Session(Connection connection, Binary name, long expiry)
{
this(connection, new SessionDelegate(), name, expiry);
@@ -267,32 +262,7 @@ public class Session extends SessionInvoker
}
else if (m instanceof MessageTransfer)
{
- MessageTransfer xfr = (MessageTransfer)m;
-
- if (xfr.getHeader() != null)
- {
- if (xfr.getHeader().get(DeliveryProperties.class) != null)
- {
- xfr.getHeader().get(DeliveryProperties.class).setRedelivered(true);
- }
- else
- {
- Struct[] structs = xfr.getHeader().getStructs();
- DeliveryProperties deliveryProps = new DeliveryProperties();
- deliveryProps.setRedelivered(true);
-
- List<Struct> list = Arrays.asList(structs);
- list.add(deliveryProps);
- xfr.setHeader(new Header(list));
- }
-
- }
- else
- {
- DeliveryProperties deliveryProps = new DeliveryProperties();
- deliveryProps.setRedelivered(true);
- xfr.setHeader(new Header(deliveryProps));
- }
+ ((MessageTransfer)m).getHeader().get(DeliveryProperties.class).setRedelivered(true);
}
sessionCommandPoint(m.getId(), 0);
send(m);
@@ -452,10 +422,7 @@ public class Session extends SessionInvoker
{
return;
}
- if (copy.size() > 0)
- {
- sessionCompleted(copy, options);
- }
+ sessionCompleted(copy, options);
}
}
@@ -694,12 +661,7 @@ public class Session extends SessionInvoker
{
sessionCommandPoint(0, 0);
}
-
- boolean replayTransfer = !closing && !transacted &&
- m instanceof MessageTransfer &&
- ! m.isUnreliable();
-
- if ((replayTransfer) || m.hasCompletionListener())
+ if ((!closing && !transacted && m instanceof MessageTransfer) || m.hasCompletionListener())
{
commands[mod(next, commands.length)] = m;
commandBytes += m.getBodySize();
@@ -1033,8 +995,7 @@ public class Session extends SessionInvoker
if(state == CLOSED)
{
- connection.removeSession(this);
- listener.closed(this);
+ connection.removeSession(this);
}
}
@@ -1047,54 +1008,13 @@ public class Session extends SessionInvoker
{
return String.format("ssn:%s", name);
}
-
+
public void setTransacted(boolean b) {
this.transacted = b;
}
-
+
public boolean isTransacted(){
return transacted;
}
-
- public void setDetachCode(SessionDetachCode dtc)
- {
- this.detachCode = dtc;
- }
-
- public SessionDetachCode getDetachCode()
- {
- return this.detachCode;
- }
-
- public void awaitOpen()
- {
- switch (state)
- {
- case NEW:
- synchronized(stateLock)
- {
- Waiter w = new Waiter(stateLock, timeout);
- while (w.hasTime() && state == NEW)
- {
- w.await();
- }
- }
-
- if (state != OPEN)
- {
- throw new SessionException("Timed out waiting for Session to open");
- }
- case DETACHED:
- case CLOSING:
- case CLOSED:
- throw new SessionException("Session closed");
- default :
- break;
- }
- }
-
- public Object getStateLock()
- {
- return stateLock;
- }
+
}
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/transport/SessionDelegate.java b/qpid/java/common/src/main/java/org/apache/qpid/transport/SessionDelegate.java
index 3341149e5f..5d8e4d5565 100644
--- a/qpid/java/common/src/main/java/org/apache/qpid/transport/SessionDelegate.java
+++ b/qpid/java/common/src/main/java/org/apache/qpid/transport/SessionDelegate.java
@@ -76,10 +76,6 @@ public class SessionDelegate
@Override public void sessionAttached(Session ssn, SessionAttached atc)
{
ssn.setState(Session.State.OPEN);
- synchronized (ssn.getStateLock())
- {
- ssn.getStateLock().notifyAll();
- }
}
@Override public void sessionTimeout(Session ssn, SessionTimeout t)
@@ -206,19 +202,11 @@ public class SessionDelegate
public void closed(Session session)
{
- log.debug("CLOSED: [%s]", session);
- synchronized (session.getStateLock())
- {
- session.getStateLock().notifyAll();
- }
+ log.warn("CLOSED: [%s]", session);
}
public void detached(Session session)
{
- log.debug("DETACHED: [%s]", session);
- synchronized (session.getStateLock())
- {
- session.getStateLock().notifyAll();
- }
+ log.warn("DETACHED: [%s]", session);
}
}
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/transport/SocketConnectorFactory.java b/qpid/java/common/src/main/java/org/apache/qpid/transport/SocketConnectorFactory.java
deleted file mode 100644
index 2c7652abeb..0000000000
--- a/qpid/java/common/src/main/java/org/apache/qpid/transport/SocketConnectorFactory.java
+++ /dev/null
@@ -1,8 +0,0 @@
-package org.apache.qpid.transport;
-
-import org.apache.mina.common.IoConnector;
-
-public interface SocketConnectorFactory
-{
- IoConnector newConnector();
-} \ No newline at end of file
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/transport/TransportBuilder.java b/qpid/java/common/src/main/java/org/apache/qpid/transport/TransportBuilder.java
new file mode 100644
index 0000000000..c08909c6e4
--- /dev/null
+++ b/qpid/java/common/src/main/java/org/apache/qpid/transport/TransportBuilder.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.transport;
+
+import java.nio.ByteBuffer;
+
+import org.apache.qpid.transport.network.Assembler;
+import org.apache.qpid.transport.network.Disassembler;
+import org.apache.qpid.transport.network.InputHandler;
+import org.apache.qpid.transport.network.NetworkTransport;
+import org.apache.qpid.transport.network.Transport;
+import org.apache.qpid.transport.network.security.SecurityLayer;
+
+public class TransportBuilder
+{
+ private Connection con;
+ private ConnectionSettings settings;
+ private NetworkTransport transport;
+ private SecurityLayer securityLayer = new SecurityLayer();
+
+ public void init(Connection con) throws TransportException
+ {
+ this.con = con;
+ this.settings = con.getConnectionSettings();
+ transport = Transport.getTransport();
+ transport.init(settings);
+ securityLayer.init(con);
+ }
+
+ public Sender<ProtocolEvent> buildSenderPipe()
+ {
+ ConnectionSettings settings = con.getConnectionSettings();
+
+ // Io layer
+ Sender<ByteBuffer> sender = transport.sender();
+
+ // Security layer
+ sender = securityLayer.sender(sender);
+
+ Disassembler dis = new Disassembler(sender, settings.getMaxFrameSize());
+ return dis;
+ }
+
+ public void buildReceiverPipe(Receiver<ProtocolEvent> delegate)
+ {
+ Receiver<ByteBuffer> receiver = new InputHandler(new Assembler(delegate));
+
+ // Security layer
+ receiver = securityLayer.receiver(receiver);
+
+ //Io layer
+ transport.receiver(receiver);
+ }
+
+ public SecurityLayer getSecurityLayer()
+ {
+ return securityLayer;
+ }
+
+} \ No newline at end of file
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/transport/codec/AbstractEncoder.java b/qpid/java/common/src/main/java/org/apache/qpid/transport/codec/AbstractEncoder.java
index 0ccfcfcb70..908d14a307 100644
--- a/qpid/java/common/src/main/java/org/apache/qpid/transport/codec/AbstractEncoder.java
+++ b/qpid/java/common/src/main/java/org/apache/qpid/transport/codec/AbstractEncoder.java
@@ -63,7 +63,6 @@ abstract class AbstractEncoder implements Encoder
ENCODINGS.put(Double.class, Type.DOUBLE);
ENCODINGS.put(Character.class, Type.CHAR);
ENCODINGS.put(byte[].class, Type.VBIN32);
- ENCODINGS.put(UUID.class, Type.UUID);
}
private final Map<String,byte[]> str8cache = new LinkedHashMap<String,byte[]>()
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/transport/network/IncomingNetworkTransport.java b/qpid/java/common/src/main/java/org/apache/qpid/transport/network/IncomingNetworkTransport.java
deleted file mode 100644
index 7099916c33..0000000000
--- a/qpid/java/common/src/main/java/org/apache/qpid/transport/network/IncomingNetworkTransport.java
+++ /dev/null
@@ -1,30 +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.transport.network;
-
-import org.apache.qpid.protocol.ProtocolEngineFactory;
-import org.apache.qpid.ssl.SSLContextFactory;
-import org.apache.qpid.transport.NetworkTransportConfiguration;
-
-public interface IncomingNetworkTransport extends NetworkTransport
-{
- public void accept(NetworkTransportConfiguration config, ProtocolEngineFactory factory, SSLContextFactory sslFactory);
-} \ No newline at end of file
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/transport/network/NetworkConnection.java b/qpid/java/common/src/main/java/org/apache/qpid/transport/network/NetworkConnection.java
deleted file mode 100644
index 1f69973b96..0000000000
--- a/qpid/java/common/src/main/java/org/apache/qpid/transport/network/NetworkConnection.java
+++ /dev/null
@@ -1,47 +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.transport.network;
-
-import java.net.SocketAddress;
-import java.nio.ByteBuffer;
-
-import org.apache.qpid.transport.Sender;
-
-public interface NetworkConnection
-{
- Sender<ByteBuffer> getSender();
-
- void close();
-
- /**
- * Returns the remote address of the underlying socket.
- */
- SocketAddress getRemoteAddress();
-
- /**
- * Returns the local address of the underlying socket.
- */
- SocketAddress getLocalAddress();
-
- void setMaxWriteIdle(int sec);
-
- void setMaxReadIdle(int sec);
-} \ No newline at end of file
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/transport/network/NetworkTransport.java b/qpid/java/common/src/main/java/org/apache/qpid/transport/network/NetworkTransport.java
index 4610c2351e..5e12d7e7c6 100644
--- a/qpid/java/common/src/main/java/org/apache/qpid/transport/network/NetworkTransport.java
+++ b/qpid/java/common/src/main/java/org/apache/qpid/transport/network/NetworkTransport.java
@@ -20,13 +20,19 @@
*/
package org.apache.qpid.transport.network;
-/**
- * A network transport is responsible for the establishment of network connections.
- * NetworkTransport implementations are pluggable via the {@link Transport} class.
- */
+import java.nio.ByteBuffer;
+
+import org.apache.qpid.transport.Receiver;
+import org.apache.qpid.transport.Sender;
+import org.apache.qpid.transport.ConnectionSettings;
+
public interface NetworkTransport
{
+ public void init(ConnectionSettings settings);
+
+ public Sender<ByteBuffer> sender();
+
+ public void receiver(Receiver<ByteBuffer> delegate);
+
public void close();
-
- public NetworkConnection getConnection();
-}
+} \ No newline at end of file
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/transport/network/OutgoingNetworkTransport.java b/qpid/java/common/src/main/java/org/apache/qpid/transport/network/OutgoingNetworkTransport.java
deleted file mode 100644
index ff86ba481f..0000000000
--- a/qpid/java/common/src/main/java/org/apache/qpid/transport/network/OutgoingNetworkTransport.java
+++ /dev/null
@@ -1,32 +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.transport.network;
-
-import java.nio.ByteBuffer;
-
-import org.apache.qpid.ssl.SSLContextFactory;
-import org.apache.qpid.transport.ConnectionSettings;
-import org.apache.qpid.transport.Receiver;
-
-public interface OutgoingNetworkTransport extends NetworkTransport
-{
- public NetworkConnection connect(ConnectionSettings settings, Receiver<ByteBuffer> delegate, SSLContextFactory sslFactory);
-} \ No newline at end of file
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/transport/network/Transport.java b/qpid/java/common/src/main/java/org/apache/qpid/transport/network/Transport.java
index 2c10a30f10..f0bf04d04f 100644
--- a/qpid/java/common/src/main/java/org/apache/qpid/transport/network/Transport.java
+++ b/qpid/java/common/src/main/java/org/apache/qpid/transport/network/Transport.java
@@ -1,5 +1,5 @@
/*
- *
+ *
* 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
@@ -7,129 +7,50 @@
* 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.network;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
+package org.apache.qpid.transport.network;
-import org.apache.qpid.framing.ProtocolVersion;
import org.apache.qpid.transport.TransportException;
public class Transport
-{
- public static final String QPID_TRANSPORT_PROPNAME = "qpid.transport";
- public static final String QPID_TRANSPORT_V0_8_PROPNAME = "qpid.transport.v0_8";
- public static final String QPID_TRANSPORT_V0_9_PROPNAME = "qpid.transport.v0_9";
- public static final String QPID_TRANSPORT_V0_9_1_PROPNAME = "qpid.transport.v0_9_1";
- public static final String QPID_TRANSPORT_V0_10_PROPNAME = "qpid.transport.v0_10";
- public static final String QPID_BROKER_TRANSPORT_PROPNAME = "qpid.broker.transport";
-
- // Can't reference the class directly here, as this would preclude the ability to bundle transports separately.
- private static final String MINA_TRANSPORT_CLASSNAME = "org.apache.qpid.transport.network.mina.MinaNetworkTransport";
- private static final String IO_TRANSPORT_CLASSNAME = "org.apache.qpid.transport.network.io.IoNetworkTransport";
-
- public static final String TCP = "tcp";
-
- private final static Map<ProtocolVersion,String> OUTGOING_PROTOCOL_TO_IMPLDEFAULTS_MAP;
-
- static
- {
- final Map<ProtocolVersion,String> map = new HashMap<ProtocolVersion, String>();
- map.put(ProtocolVersion.v8_0, MINA_TRANSPORT_CLASSNAME);
- map.put(ProtocolVersion.v0_9, MINA_TRANSPORT_CLASSNAME);
- map.put(ProtocolVersion.v0_91, MINA_TRANSPORT_CLASSNAME);
- map.put(ProtocolVersion.v0_10, IO_TRANSPORT_CLASSNAME);
-
- OUTGOING_PROTOCOL_TO_IMPLDEFAULTS_MAP = Collections.unmodifiableMap(map);
- }
-
- public static IncomingNetworkTransport getIncomingTransportInstance()
+{
+ private final static Class<?> transportClass;
+
+ static
{
- return (IncomingNetworkTransport) loadTransportClass(
- System.getProperty(QPID_BROKER_TRANSPORT_PROPNAME, MINA_TRANSPORT_CLASSNAME));
- }
-
- public static OutgoingNetworkTransport getOutgoingTransportInstance(
- final ProtocolVersion protocolVersion)
- {
-
- final String overrride = getOverrideClassNameFromSystemProperty(protocolVersion);
- final String networkTransportClassName;
- if (overrride != null)
- {
- networkTransportClassName = overrride;
- }
- else
- {
- networkTransportClassName = OUTGOING_PROTOCOL_TO_IMPLDEFAULTS_MAP.get(protocolVersion);
- }
-
- return (OutgoingNetworkTransport) loadTransportClass(networkTransportClassName);
- }
-
- private static NetworkTransport loadTransportClass(final String networkTransportClassName)
- {
- if (networkTransportClassName == null)
- {
- throw new IllegalArgumentException("transport class name must not be null");
- }
-
try
{
- final Class<?> clazz = Class.forName(networkTransportClassName);
- return (NetworkTransport) clazz.newInstance();
+ transportClass =
+ Class.forName(System.getProperty("qpid.transport",
+ "org.apache.qpid.transport.network.io.IoNetworkTransport"));
+
}
- catch (InstantiationException e)
+ catch(Exception e)
{
- throw new TransportException("Unable to instantiate transport class " + networkTransportClassName, e);
- }
- catch (IllegalAccessException e)
- {
- throw new TransportException("Access exception " + networkTransportClassName, e);
- }
- catch (ClassNotFoundException e)
- {
- throw new TransportException("Unable to load transport class " + networkTransportClassName, e);
+ throw new Error("Error occured while loading Qpid Transport",e);
}
}
-
- private static String getOverrideClassNameFromSystemProperty(final ProtocolVersion protocolVersion)
+
+ public static NetworkTransport getTransport() throws TransportException
{
- final String protocolSpecificSystemProperty;
-
- if (ProtocolVersion.v0_10.equals(protocolVersion))
- {
- protocolSpecificSystemProperty = QPID_TRANSPORT_V0_10_PROPNAME;
- }
- else if (ProtocolVersion.v0_91.equals(protocolVersion))
- {
- protocolSpecificSystemProperty = QPID_TRANSPORT_V0_9_1_PROPNAME;
- }
- else if (ProtocolVersion.v0_9.equals(protocolVersion))
- {
- protocolSpecificSystemProperty = QPID_TRANSPORT_V0_9_PROPNAME;
- }
- else if (ProtocolVersion.v8_0.equals(protocolVersion))
+ try
{
- protocolSpecificSystemProperty = QPID_TRANSPORT_V0_8_PROPNAME;
+ return (NetworkTransport)transportClass.newInstance();
}
- else
+ catch (Exception e)
{
- throw new IllegalArgumentException("Unknown ProtocolVersion " + protocolVersion);
+ throw new TransportException("Error while creating a new transport instance",e);
}
-
- return System.getProperty(protocolSpecificSystemProperty, System.getProperty(QPID_TRANSPORT_PROPNAME));
}
-}
+} \ No newline at end of file
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/transport/network/io/InputHandler_0_9.java b/qpid/java/common/src/main/java/org/apache/qpid/transport/network/io/InputHandler_0_9.java
new file mode 100644
index 0000000000..ecc5f6d07c
--- /dev/null
+++ b/qpid/java/common/src/main/java/org/apache/qpid/transport/network/io/InputHandler_0_9.java
@@ -0,0 +1,130 @@
+package org.apache.qpid.transport.network.io;
+/*
+ *
+ * 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 java.nio.ByteBuffer;
+
+import org.apache.qpid.AMQException;
+import org.apache.qpid.framing.AMQFrame;
+import org.apache.qpid.framing.AMQFrameDecodingException;
+import org.apache.qpid.framing.AMQMethodBody;
+import org.apache.qpid.framing.AMQMethodBodyFactory;
+import org.apache.qpid.framing.BodyFactory;
+import org.apache.qpid.framing.ContentBody;
+import org.apache.qpid.framing.ContentBodyFactory;
+import org.apache.qpid.framing.ContentHeaderBody;
+import org.apache.qpid.framing.ContentHeaderBodyFactory;
+import org.apache.qpid.framing.HeartbeatBody;
+import org.apache.qpid.framing.HeartbeatBodyFactory;
+import org.apache.qpid.framing.MethodRegistry;
+import org.apache.qpid.protocol.AMQVersionAwareProtocolSession;
+import org.apache.qpid.transport.Receiver;
+
+public class InputHandler_0_9 implements Receiver<ByteBuffer>
+{
+
+ private AMQVersionAwareProtocolSession _session;
+ private MethodRegistry _registry;
+ private BodyFactory bodyFactory;
+ private static final BodyFactory[] _bodiesSupported = new BodyFactory[Byte.MAX_VALUE];
+
+ static
+ {
+ _bodiesSupported[ContentHeaderBody.TYPE] = ContentHeaderBodyFactory.getInstance();
+ _bodiesSupported[ContentBody.TYPE] = ContentBodyFactory.getInstance();
+ _bodiesSupported[HeartbeatBody.TYPE] = new HeartbeatBodyFactory();
+ }
+
+ public InputHandler_0_9(AMQVersionAwareProtocolSession session)
+ {
+ _session = session;
+ _registry = _session.getMethodRegistry();
+ }
+
+ public void closed()
+ {
+ // AS FIXME: implement
+ }
+
+ public void exception(Throwable t)
+ {
+ // TODO: propogate exception to things
+ t.printStackTrace();
+ }
+
+ public void received(ByteBuffer buf)
+ {
+ org.apache.mina.common.ByteBuffer in = org.apache.mina.common.ByteBuffer.wrap(buf);
+ try
+ {
+ final byte type = in.get();
+ if (type == AMQMethodBody.TYPE)
+ {
+ bodyFactory = new AMQMethodBodyFactory(_session);
+ }
+ else
+ {
+ bodyFactory = _bodiesSupported[type];
+ }
+
+ if (bodyFactory == null)
+ {
+ throw new AMQFrameDecodingException(null, "Unsupported frame type: " + type, null);
+ }
+
+ final int channel = in.getUnsignedShort();
+ final long bodySize = in.getUnsignedInt();
+
+ // bodySize can be zero
+ if ((channel < 0) || (bodySize < 0))
+ {
+ throw new AMQFrameDecodingException(null, "Undecodable frame: type = " + type + " channel = " + channel
+ + " bodySize = " + bodySize, null);
+ }
+
+ AMQFrame frame = new AMQFrame(in, channel, bodySize, bodyFactory);
+
+ byte marker = in.get();
+ if ((marker & 0xFF) != 0xCE)
+ {
+ throw new AMQFrameDecodingException(null, "End of frame marker not found. Read " + marker + " length=" + bodySize
+ + " type=" + type, null);
+ }
+
+ try
+ {
+ frame.getBodyFrame().handle(frame.getChannel(), _session);
+ }
+ catch (AMQException e)
+ {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+ catch (AMQFrameDecodingException e)
+ {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+
+}
diff --git a/qpid/java/common/src/test/java/org/apache/qpid/transport/network/io/IoAcceptor.java b/qpid/java/common/src/main/java/org/apache/qpid/transport/network/io/IoAcceptor.java
index 8530240dcc..8530240dcc 100644
--- a/qpid/java/common/src/test/java/org/apache/qpid/transport/network/io/IoAcceptor.java
+++ b/qpid/java/common/src/main/java/org/apache/qpid/transport/network/io/IoAcceptor.java
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/transport/network/io/IoContext.java b/qpid/java/common/src/main/java/org/apache/qpid/transport/network/io/IoContext.java
new file mode 100644
index 0000000000..69b3a0ce45
--- /dev/null
+++ b/qpid/java/common/src/main/java/org/apache/qpid/transport/network/io/IoContext.java
@@ -0,0 +1,35 @@
+/*
+ *
+ * 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.network.io;
+
+import java.net.Socket;
+import java.nio.ByteBuffer;
+
+import org.apache.qpid.transport.Sender;
+
+public interface IoContext
+{
+ Sender<ByteBuffer> getSender();
+
+ IoReceiver getReceiver();
+
+ Socket getSocket();
+}
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/transport/network/io/IoNetworkConnection.java b/qpid/java/common/src/main/java/org/apache/qpid/transport/network/io/IoNetworkConnection.java
deleted file mode 100644
index cca1fc46c9..0000000000
--- a/qpid/java/common/src/main/java/org/apache/qpid/transport/network/io/IoNetworkConnection.java
+++ /dev/null
@@ -1,93 +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.transport.network.io;
-
-import java.net.Socket;
-import java.net.SocketAddress;
-import java.nio.ByteBuffer;
-
-import org.apache.qpid.transport.Receiver;
-import org.apache.qpid.transport.Sender;
-import org.apache.qpid.transport.network.NetworkConnection;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class IoNetworkConnection implements NetworkConnection
-{
- private static final Logger LOGGER = LoggerFactory.getLogger(IoNetworkConnection.class);
- private final Socket _socket;
- private final long _timeout;
- private final IoSender _ioSender;
- private final IoReceiver _ioReceiver;
-
- public IoNetworkConnection(Socket socket, Receiver<ByteBuffer> delegate,
- int sendBufferSize, int receiveBufferSize, long timeout)
- {
- _socket = socket;
- _timeout = timeout;
-
- _ioReceiver = new IoReceiver(_socket, delegate, receiveBufferSize,_timeout);
- _ioSender = new IoSender(_socket, 2 * sendBufferSize, _timeout);
- _ioSender.registerCloseListener(_ioReceiver);
-
- _ioReceiver.initiate();
- _ioSender.initiate();
- }
-
- public Sender<ByteBuffer> getSender()
- {
- return _ioSender;
- }
-
- public void close()
- {
- try
- {
- _ioSender.close();
- }
- finally
- {
- _ioReceiver.close(false);
- }
- }
-
- public SocketAddress getRemoteAddress()
- {
- return _socket.getRemoteSocketAddress();
- }
-
- public SocketAddress getLocalAddress()
- {
- return _socket.getLocalSocketAddress();
- }
-
- public void setMaxWriteIdle(int sec)
- {
- // TODO implement support for setting heartbeating config in this way
- // Currently a socket timeout is used in IoSender
- }
-
- public void setMaxReadIdle(int sec)
- {
- // TODO implement support for setting heartbeating config in this way
- // Currently a socket timeout is used in IoSender
- }
-}
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/transport/network/io/IoNetworkTransport.java b/qpid/java/common/src/main/java/org/apache/qpid/transport/network/io/IoNetworkTransport.java
index d611ab1cf3..dd6a37eca2 100644
--- a/qpid/java/common/src/main/java/org/apache/qpid/transport/network/io/IoNetworkTransport.java
+++ b/qpid/java/common/src/main/java/org/apache/qpid/transport/network/io/IoNetworkTransport.java
@@ -27,15 +27,14 @@ import java.net.Socket;
import java.net.SocketException;
import java.nio.ByteBuffer;
-import org.apache.qpid.ssl.SSLContextFactory;
import org.apache.qpid.transport.ConnectionSettings;
import org.apache.qpid.transport.Receiver;
+import org.apache.qpid.transport.Sender;
import org.apache.qpid.transport.TransportException;
-import org.apache.qpid.transport.network.NetworkConnection;
-import org.apache.qpid.transport.network.OutgoingNetworkTransport;
+import org.apache.qpid.transport.network.NetworkTransport;
import org.apache.qpid.transport.util.Logger;
-public class IoNetworkTransport implements OutgoingNetworkTransport
+public class IoNetworkTransport implements NetworkTransport, IoContext
{
static
{
@@ -45,31 +44,34 @@ public class IoNetworkTransport implements OutgoingNetworkTransport
(Boolean.getBoolean("amqj.enableDirectBuffers"));
}
- private static final Logger LOGGER = Logger.get(IoNetworkTransport.class);
+ private static final Logger log = Logger.get(IoNetworkTransport.class);
- private Socket _socket;
- private IoNetworkConnection _connection;
- private long _timeout = 60000;
+ private Socket socket;
+ private Sender<ByteBuffer> sender;
+ private IoReceiver receiver;
+ private long timeout = 60000;
+ private ConnectionSettings settings;
- public NetworkConnection connect(ConnectionSettings settings, Receiver<ByteBuffer> delegate, SSLContextFactory sslFactory)
+ public void init(ConnectionSettings settings)
{
- int sendBufferSize = settings.getWriteBufferSize();
- int receiveBufferSize = settings.getReadBufferSize();
-
try
{
- _socket = new Socket();
- _socket.setReuseAddress(true);
- _socket.setTcpNoDelay(settings.isTcpNodelay());
- _socket.setSendBufferSize(sendBufferSize);
- _socket.setReceiveBufferSize(receiveBufferSize);
+ this.settings = settings;
+ InetAddress address = InetAddress.getByName(settings.getHost());
+ socket = new Socket();
+ socket.setReuseAddress(true);
+ socket.setTcpNoDelay(settings.isTcpNodelay());
- LOGGER.debug("SO_RCVBUF : %s", _socket.getReceiveBufferSize());
- LOGGER.debug("SO_SNDBUF : %s", _socket.getSendBufferSize());
+ log.debug("default-SO_RCVBUF : %s", socket.getReceiveBufferSize());
+ log.debug("default-SO_SNDBUF : %s", socket.getSendBufferSize());
- InetAddress address = InetAddress.getByName(settings.getHost());
+ socket.setSendBufferSize(settings.getWriteBufferSize());
+ socket.setReceiveBufferSize(settings.getReadBufferSize());
- _socket.connect(new InetSocketAddress(address, settings.getPort()));
+ log.debug("new-SO_RCVBUF : %s", socket.getReceiveBufferSize());
+ log.debug("new-SO_SNDBUF : %s", socket.getSendBufferSize());
+
+ socket.connect(new InetSocketAddress(address, settings.getPort()));
}
catch (SocketException e)
{
@@ -79,35 +81,36 @@ public class IoNetworkTransport implements OutgoingNetworkTransport
{
throw new TransportException("Error connecting to broker", e);
}
+ }
- try
- {
- _connection = new IoNetworkConnection(_socket, delegate, sendBufferSize, receiveBufferSize, _timeout);
- }
- catch(Exception e)
- {
- try
- {
- _socket.close();
- }
- catch(IOException ioe)
- {
- //ignored, throw based on original exception
- }
-
- throw new TransportException("Error creating network connection", e);
- }
+ public void receiver(Receiver<ByteBuffer> delegate)
+ {
+ receiver = new IoReceiver(this, delegate,
+ 2*settings.getReadBufferSize() , timeout);
+ }
- return _connection;
+ public Sender<ByteBuffer> sender()
+ {
+ return new IoSender(this, 2*settings.getWriteBufferSize(), timeout);
}
public void close()
{
- _connection.close();
+
+ }
+
+ public Sender<ByteBuffer> getSender()
+ {
+ return sender;
+ }
+
+ public IoReceiver getReceiver()
+ {
+ return receiver;
}
- public NetworkConnection getConnection()
+ public Socket getSocket()
{
- return _connection;
+ return socket;
}
}
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/transport/network/io/IoReceiver.java b/qpid/java/common/src/main/java/org/apache/qpid/transport/network/io/IoReceiver.java
index fea87fc350..19a683d505 100644
--- a/qpid/java/common/src/main/java/org/apache/qpid/transport/network/io/IoReceiver.java
+++ b/qpid/java/common/src/main/java/org/apache/qpid/transport/network/io/IoReceiver.java
@@ -20,7 +20,6 @@
*/
package org.apache.qpid.transport.network.io;
-import org.apache.qpid.common.Closeable;
import org.apache.qpid.thread.Threading;
import org.apache.qpid.transport.Receiver;
import org.apache.qpid.transport.TransportException;
@@ -38,54 +37,43 @@ import java.util.concurrent.atomic.AtomicBoolean;
*
*/
-final class IoReceiver implements Runnable, Closeable
+final class IoReceiver implements Runnable
{
private static final Logger log = Logger.get(IoReceiver.class);
+ private final IoContext ioCtx;
private final Receiver<ByteBuffer> receiver;
private final int bufferSize;
private final Socket socket;
private final long timeout;
private final AtomicBoolean closed = new AtomicBoolean(false);
private final Thread receiverThread;
- private static final boolean shutdownBroken;
- static
- {
- String osName = System.getProperty("os.name");
- shutdownBroken = osName == null ? false : osName.matches("(?i).*windows.*");
- }
+ private final boolean shutdownBroken =
+ ((String) System.getProperties().get("os.name")).matches("(?i).*windows.*");
- public IoReceiver(Socket socket, Receiver<ByteBuffer> receiver, int bufferSize, long timeout)
+ public IoReceiver(IoContext ioCtx, Receiver<ByteBuffer> receiver,
+ int bufferSize, long timeout)
{
+ this.ioCtx = ioCtx;
this.receiver = receiver;
this.bufferSize = bufferSize;
- this.socket = socket;
+ this.socket = ioCtx.getSocket();
this.timeout = timeout;
try
{
- //Create but deliberately don't start the thread.
receiverThread = Threading.getThreadFactory().createThread(this);
}
catch(Exception e)
{
- throw new RuntimeException("Error creating IOReceiver thread",e);
+ throw new Error("Error creating IOReceiver thread",e);
}
receiverThread.setDaemon(true);
receiverThread.setName(String.format("IoReceiver - %s", socket.getRemoteSocketAddress()));
- }
-
- public void initiate()
- {
receiverThread.start();
}
- public void close()
- {
- close(false);
- }
-
void close(boolean block)
{
if (!closed.getAndSet(true))
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/transport/network/io/IoSender.java b/qpid/java/common/src/main/java/org/apache/qpid/transport/network/io/IoSender.java
index 1bb515624c..66b97e8225 100644
--- a/qpid/java/common/src/main/java/org/apache/qpid/transport/network/io/IoSender.java
+++ b/qpid/java/common/src/main/java/org/apache/qpid/transport/network/io/IoSender.java
@@ -24,11 +24,8 @@ import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;
import java.nio.ByteBuffer;
-import java.util.ArrayList;
-import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
-import org.apache.qpid.common.Closeable;
import org.apache.qpid.thread.Threading;
import org.apache.qpid.transport.Sender;
import org.apache.qpid.transport.SenderException;
@@ -46,6 +43,7 @@ public final class IoSender implements Runnable, Sender<ByteBuffer>
// we can test other cases as well
private final static int START = Integer.MAX_VALUE - 10;
+ private final IoContext ioCtx;
private final long timeout;
private final Socket socket;
private final OutputStream out;
@@ -58,13 +56,14 @@ public final class IoSender implements Runnable, Sender<ByteBuffer>
private final Object notEmpty = new Object();
private final AtomicBoolean closed = new AtomicBoolean(false);
private final Thread senderThread;
- private final List<Closeable> _listeners = new ArrayList<Closeable>();
private volatile Throwable exception = null;
- public IoSender(Socket socket, int bufferSize, long timeout)
+
+ public IoSender(IoContext ioCtx, int bufferSize, long timeout)
{
- this.socket = socket;
+ this.ioCtx = ioCtx;
+ this.socket = ioCtx.getSocket();
this.buffer = new byte[pof2(bufferSize)]; // buffer size must be a power of 2
this.timeout = timeout;
@@ -79,7 +78,6 @@ public final class IoSender implements Runnable, Sender<ByteBuffer>
try
{
- //Create but deliberately don't start the thread.
senderThread = Threading.getThreadFactory().createThread(this);
}
catch(Exception e)
@@ -89,10 +87,6 @@ public final class IoSender implements Runnable, Sender<ByteBuffer>
senderThread.setDaemon(true);
senderThread.setName(String.format("IoSender - %s", socket.getRemoteSocketAddress()));
- }
-
- public void initiate()
- {
senderThread.start();
}
@@ -210,20 +204,16 @@ public final class IoSender implements Runnable, Sender<ByteBuffer>
senderThread.join(timeout);
if (senderThread.isAlive())
{
- log.error("join timed out");
throw new SenderException("join timed out");
}
}
+ ioCtx.getReceiver().close(false);
}
catch (InterruptedException e)
{
- log.error("interrupted whilst waiting for sender thread to stop");
throw new SenderException(e);
}
- finally
- {
- closeListeners();
- }
+
if (reportException && exception != null)
{
throw new SenderException(exception);
@@ -231,28 +221,6 @@ public final class IoSender implements Runnable, Sender<ByteBuffer>
}
}
- private void closeListeners()
- {
- Exception ex = null;
- for(Closeable listener : _listeners)
- {
- try
- {
- listener.close();
- }
- catch(Exception e)
- {
- log.error("Exception closing listener: " + e.getMessage());
- ex = e;
- }
- }
-
- if (ex != null)
- {
- throw new SenderException(ex.getMessage(), ex);
- }
- }
-
public void run()
{
final int size = buffer.length;
@@ -336,9 +304,4 @@ public final class IoSender implements Runnable, Sender<ByteBuffer>
throw new SenderException(e);
}
}
-
- public void registerCloseListener(Closeable listener)
- {
- _listeners.add(listener);
- }
}
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/transport/network/io/IoTransport.java b/qpid/java/common/src/main/java/org/apache/qpid/transport/network/io/IoTransport.java
new file mode 100644
index 0000000000..bfdbb34978
--- /dev/null
+++ b/qpid/java/common/src/main/java/org/apache/qpid/transport/network/io/IoTransport.java
@@ -0,0 +1,231 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.qpid.transport.network.io;
+
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.Socket;
+import java.net.SocketException;
+import java.nio.ByteBuffer;
+
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLEngine;
+
+import org.apache.qpid.protocol.AMQVersionAwareProtocolSession;
+import org.apache.qpid.ssl.SSLContextFactory;
+import org.apache.qpid.transport.Binding;
+import org.apache.qpid.transport.Connection;
+import org.apache.qpid.transport.ConnectionDelegate;
+import org.apache.qpid.transport.Receiver;
+import org.apache.qpid.transport.Sender;
+import org.apache.qpid.transport.TransportException;
+import org.apache.qpid.transport.network.ConnectionBinding;
+import org.apache.qpid.transport.network.security.ssl.SSLReceiver;
+import org.apache.qpid.transport.network.security.ssl.SSLSender;
+import org.apache.qpid.transport.util.Logger;
+
+/**
+ * This class provides a socket based transport using the java.io
+ * classes.
+ *
+ * The following params are configurable via JVM arguments
+ * TCP_NO_DELAY - amqj.tcpNoDelay
+ * SO_RCVBUF - amqj.receiveBufferSize
+ * SO_SNDBUF - amqj.sendBufferSize
+ */
+public final class IoTransport<E> implements IoContext
+{
+
+ static
+ {
+ org.apache.mina.common.ByteBuffer.setAllocator
+ (new org.apache.mina.common.SimpleByteBufferAllocator());
+ org.apache.mina.common.ByteBuffer.setUseDirectBuffers
+ (Boolean.getBoolean("amqj.enableDirectBuffers"));
+ }
+
+ private static final Logger log = Logger.get(IoTransport.class);
+
+ private static int DEFAULT_READ_WRITE_BUFFER_SIZE = 64 * 1024;
+ private static int readBufferSize = Integer.getInteger
+ ("amqj.receiveBufferSize", DEFAULT_READ_WRITE_BUFFER_SIZE);
+ private static int writeBufferSize = Integer.getInteger
+ ("amqj.sendBufferSize", DEFAULT_READ_WRITE_BUFFER_SIZE);
+
+ private Socket socket;
+ private Sender<ByteBuffer> sender;
+ private E endpoint;
+ private IoReceiver receiver;
+ private long timeout = 60000;
+
+ IoTransport(Socket socket, Binding<E,ByteBuffer> binding, boolean ssl)
+ {
+ this.socket = socket;
+
+ if (ssl)
+ {
+ SSLEngine engine = null;
+ SSLContext sslCtx;
+ try
+ {
+ sslCtx = createSSLContext();
+ }
+ catch (Exception e)
+ {
+ throw new TransportException("Error creating SSL Context", e);
+ }
+
+ try
+ {
+ engine = sslCtx.createSSLEngine();
+ engine.setUseClientMode(true);
+ }
+ catch(Exception e)
+ {
+ throw new TransportException("Error creating SSL Engine", e);
+ }
+
+ this.sender = new SSLSender(engine,new IoSender(this, 2*writeBufferSize, timeout));
+ this.endpoint = binding.endpoint(sender);
+ this.receiver = new IoReceiver(this, new SSLReceiver(engine,binding.receiver(endpoint),(SSLSender)sender),
+ 2*readBufferSize, timeout);
+
+ log.info("SSL Sender and Receiver initiated");
+ }
+ else
+ {
+ this.sender = new IoSender(this, 2*writeBufferSize, timeout);
+ this.endpoint = binding.endpoint(sender);
+ this.receiver = new IoReceiver(this, binding.receiver(endpoint),
+ 2*readBufferSize, timeout);
+ }
+ }
+
+ public Sender<ByteBuffer> getSender()
+ {
+ return sender;
+ }
+
+ public IoReceiver getReceiver()
+ {
+ return receiver;
+ }
+
+ public Socket getSocket()
+ {
+ return socket;
+ }
+
+ public static final <E> E connect(String host, int port,
+ Binding<E,ByteBuffer> binding,
+ boolean ssl)
+ {
+ Socket socket = createSocket(host, port);
+ IoTransport<E> transport = new IoTransport<E>(socket, binding,ssl);
+ return transport.endpoint;
+ }
+
+ public static final Connection connect(String host, int port,
+ ConnectionDelegate delegate,
+ boolean ssl)
+ {
+ return connect(host, port, ConnectionBinding.get(delegate),ssl);
+ }
+
+ public static void connect_0_9(AMQVersionAwareProtocolSession session, String host, int port, boolean ssl)
+ {
+ connect(host, port, new Binding_0_9(session),ssl);
+ }
+
+ private static class Binding_0_9
+ implements Binding<AMQVersionAwareProtocolSession,ByteBuffer>
+ {
+
+ private AMQVersionAwareProtocolSession session;
+
+ Binding_0_9(AMQVersionAwareProtocolSession session)
+ {
+ this.session = session;
+ }
+
+ public AMQVersionAwareProtocolSession endpoint(Sender<ByteBuffer> sender)
+ {
+ session.setSender(sender);
+ return session;
+ }
+
+ public Receiver<ByteBuffer> receiver(AMQVersionAwareProtocolSession ssn)
+ {
+ return new InputHandler_0_9(ssn);
+ }
+
+ }
+
+ private static Socket createSocket(String host, int port)
+ {
+ try
+ {
+ InetAddress address = InetAddress.getByName(host);
+ Socket socket = new Socket();
+ socket.setReuseAddress(true);
+ socket.setTcpNoDelay(Boolean.getBoolean("amqj.tcpNoDelay"));
+
+ log.debug("default-SO_RCVBUF : %s", socket.getReceiveBufferSize());
+ log.debug("default-SO_SNDBUF : %s", socket.getSendBufferSize());
+
+ socket.setSendBufferSize(writeBufferSize);
+ socket.setReceiveBufferSize(readBufferSize);
+
+ log.debug("new-SO_RCVBUF : %s", socket.getReceiveBufferSize());
+ log.debug("new-SO_SNDBUF : %s", socket.getSendBufferSize());
+
+ socket.connect(new InetSocketAddress(address, port));
+ return socket;
+ }
+ catch (SocketException e)
+ {
+ throw new TransportException("Error connecting to broker", e);
+ }
+ catch (IOException e)
+ {
+ throw new TransportException("Error connecting to broker", e);
+ }
+ }
+
+ private SSLContext createSSLContext() throws Exception
+ {
+ String trustStorePath = System.getProperty("javax.net.ssl.trustStore");
+ String trustStorePassword = System.getProperty("javax.net.ssl.trustStorePassword");
+ String trustStoreCertType = System.getProperty("qpid.ssl.trustStoreCertType","SunX509");
+
+ String keyStorePath = System.getProperty("javax.net.ssl.keyStore",trustStorePath);
+ String keyStorePassword = System.getProperty("javax.net.ssl.keyStorePassword",trustStorePassword);
+ String keyStoreCertType = System.getProperty("qpid.ssl.keyStoreCertType","SunX509");
+
+ SSLContextFactory sslContextFactory = new SSLContextFactory(trustStorePath,trustStorePassword,
+ trustStoreCertType,keyStorePath,
+ keyStorePassword,keyStoreCertType);
+
+ return sslContextFactory.buildServerContext();
+
+ }
+
+}
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/transport/network/mina/MINANetworkDriver.java b/qpid/java/common/src/main/java/org/apache/qpid/transport/network/mina/MINANetworkDriver.java
new file mode 100644
index 0000000000..0f2c0d0226
--- /dev/null
+++ b/qpid/java/common/src/main/java/org/apache/qpid/transport/network/mina/MINANetworkDriver.java
@@ -0,0 +1,435 @@
+/*
+ *
+ * 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.network.mina;
+
+import org.apache.mina.common.ConnectFuture;
+import org.apache.mina.common.ExecutorThreadModel;
+import org.apache.mina.common.IdleStatus;
+import org.apache.mina.common.IoAcceptor;
+import org.apache.mina.common.IoConnector;
+import org.apache.mina.common.IoFilterChain;
+import org.apache.mina.common.IoHandlerAdapter;
+import org.apache.mina.common.IoSession;
+import org.apache.mina.common.SimpleByteBufferAllocator;
+import org.apache.mina.common.WriteFuture;
+import org.apache.mina.filter.ReadThrottleFilterBuilder;
+import org.apache.mina.filter.SSLFilter;
+import org.apache.mina.filter.WriteBufferLimitFilterBuilder;
+import org.apache.mina.filter.executor.ExecutorFilter;
+import org.apache.mina.transport.socket.nio.MultiThreadSocketConnector;
+import org.apache.mina.transport.socket.nio.SocketAcceptorConfig;
+import org.apache.mina.transport.socket.nio.SocketConnector;
+import org.apache.mina.transport.socket.nio.SocketConnectorConfig;
+import org.apache.mina.transport.socket.nio.SocketSessionConfig;
+import org.apache.mina.util.NewThreadExecutor;
+import org.apache.mina.util.SessionUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.apache.qpid.protocol.ProtocolEngine;
+import org.apache.qpid.protocol.ProtocolEngineFactory;
+import org.apache.qpid.ssl.SSLContextFactory;
+import org.apache.qpid.thread.QpidThreadExecutor;
+import org.apache.qpid.transport.NetworkDriver;
+import org.apache.qpid.transport.NetworkDriverConfiguration;
+import org.apache.qpid.transport.OpenException;
+
+import java.io.IOException;
+import java.net.BindException;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.SocketAddress;
+import java.nio.ByteBuffer;
+
+public class MINANetworkDriver extends IoHandlerAdapter implements NetworkDriver
+{
+
+ private static final int DEFAULT_BUFFER_SIZE = 32 * 1024;
+
+ ProtocolEngine _protocolEngine;
+ private boolean _useNIO = false;
+ private int _processors = 4;
+ private boolean _executorPool = false;
+ private SSLContextFactory _sslFactory = null;
+ private IoConnector _socketConnector;
+ private IoAcceptor _acceptor;
+ private IoSession _ioSession;
+ private ProtocolEngineFactory _factory;
+ private boolean _protectIO;
+ private NetworkDriverConfiguration _config;
+ private Throwable _lastException;
+ private boolean _acceptingConnections = false;
+
+ private WriteFuture _lastWriteFuture;
+
+ private static final Logger _logger = LoggerFactory.getLogger(MINANetworkDriver.class);
+
+ static
+ {
+ org.apache.mina.common.ByteBuffer.setUseDirectBuffers(Boolean.getBoolean("amqj.enableDirectBuffers"));
+
+ //override the MINA defaults to prevent use of the PooledByteBufferAllocator
+ org.apache.mina.common.ByteBuffer.setAllocator(new SimpleByteBufferAllocator());
+ }
+
+ public MINANetworkDriver(boolean useNIO, int processors, boolean executorPool, boolean protectIO)
+ {
+ _useNIO = useNIO;
+ _processors = processors;
+ _executorPool = executorPool;
+ _protectIO = protectIO;
+ }
+
+ public MINANetworkDriver(boolean useNIO, int processors, boolean executorPool, boolean protectIO,
+ ProtocolEngine protocolEngine, IoSession session)
+ {
+ _useNIO = useNIO;
+ _processors = processors;
+ _executorPool = executorPool;
+ _protectIO = protectIO;
+ _protocolEngine = protocolEngine;
+ _ioSession = session;
+ _ioSession.setAttachment(_protocolEngine);
+ }
+
+ public MINANetworkDriver()
+ {
+
+ }
+
+ public MINANetworkDriver(IoConnector ioConnector)
+ {
+ _socketConnector = ioConnector;
+ }
+
+ public MINANetworkDriver(IoConnector ioConnector, ProtocolEngine engine)
+ {
+ _socketConnector = ioConnector;
+ _protocolEngine = engine;
+ }
+
+ public void bind(int port, InetAddress[] addresses, ProtocolEngineFactory factory,
+ NetworkDriverConfiguration config, SSLContextFactory sslFactory) throws BindException
+ {
+
+ _factory = factory;
+ _config = config;
+
+ if (_useNIO)
+ {
+ _acceptor = new org.apache.mina.transport.socket.nio.MultiThreadSocketAcceptor(_processors,
+ new NewThreadExecutor());
+ }
+ else
+ {
+ _acceptor = new org.apache.mina.transport.socket.nio.SocketAcceptor(_processors, new NewThreadExecutor());
+ }
+
+ SocketAcceptorConfig sconfig = (SocketAcceptorConfig) _acceptor.getDefaultConfig();
+ sconfig.setThreadModel(ExecutorThreadModel.getInstance("MINANetworkDriver(Acceptor)"));
+ SocketSessionConfig sc = (SocketSessionConfig) sconfig.getSessionConfig();
+
+ if (config != null)
+ {
+ sc.setReceiveBufferSize(config.getReceiveBufferSize());
+ sc.setSendBufferSize(config.getSendBufferSize());
+ sc.setTcpNoDelay(config.getTcpNoDelay());
+ }
+
+ if (sslFactory != null)
+ {
+ _sslFactory = sslFactory;
+ }
+
+ if (addresses != null && addresses.length > 0)
+ {
+ for (InetAddress addr : addresses)
+ {
+ try
+ {
+ _acceptor.bind(new InetSocketAddress(addr, port), this, sconfig);
+ }
+ catch (IOException e)
+ {
+ throw new BindException(String.format("Could not bind to %1s:%2s", addr, port));
+ }
+ }
+ }
+ else
+ {
+ try
+ {
+ _acceptor.bind(new InetSocketAddress(port), this, sconfig);
+ }
+ catch (IOException e)
+ {
+ throw new BindException(String.format("Could not bind to *:%1s", port));
+ }
+ }
+ _acceptingConnections = true;
+ }
+
+ public SocketAddress getRemoteAddress()
+ {
+ return _ioSession.getRemoteAddress();
+ }
+
+ public SocketAddress getLocalAddress()
+ {
+ return _ioSession.getLocalAddress();
+ }
+
+
+ public void open(int port, InetAddress destination, ProtocolEngine engine, NetworkDriverConfiguration config,
+ SSLContextFactory sslFactory) throws OpenException
+ {
+ if (sslFactory != null)
+ {
+ _sslFactory = sslFactory;
+ }
+
+ if (_useNIO)
+ {
+ _socketConnector = new MultiThreadSocketConnector(1, new QpidThreadExecutor());
+ }
+ else
+ {
+ _socketConnector = new SocketConnector(1, new QpidThreadExecutor()); // non-blocking
+ // connector
+ }
+
+ SocketConnectorConfig cfg = (SocketConnectorConfig) _socketConnector.getDefaultConfig();
+ String s = "";
+ StackTraceElement[] trace = Thread.currentThread().getStackTrace();
+ for(StackTraceElement elt : trace)
+ {
+ if(elt.getClassName().contains("Test"))
+ {
+ s = elt.getClassName();
+ break;
+ }
+ }
+ cfg.setThreadModel(ExecutorThreadModel.getInstance("MINANetworkDriver(Client)-"+s));
+
+ SocketSessionConfig scfg = (SocketSessionConfig) cfg.getSessionConfig();
+ scfg.setTcpNoDelay((config != null) ? config.getTcpNoDelay() : true);
+ scfg.setSendBufferSize((config != null) ? config.getSendBufferSize() : DEFAULT_BUFFER_SIZE);
+ scfg.setReceiveBufferSize((config != null) ? config.getReceiveBufferSize() : DEFAULT_BUFFER_SIZE);
+
+ // Don't have the connector's worker thread wait around for other
+ // connections (we only use
+ // one SocketConnector per connection at the moment anyway). This allows
+ // short-running
+ // clients (like unit tests) to complete quickly.
+ if (_socketConnector instanceof SocketConnector)
+ {
+ ((SocketConnector) _socketConnector).setWorkerTimeout(0);
+ }
+
+ ConnectFuture future = _socketConnector.connect(new InetSocketAddress(destination, port), this, cfg);
+ future.join();
+ if (!future.isConnected())
+ {
+ throw new OpenException("Could not open connection", _lastException);
+ }
+ _ioSession = future.getSession();
+ _ioSession.setAttachment(engine);
+ engine.setNetworkDriver(this);
+ _protocolEngine = engine;
+ }
+
+ public void setMaxReadIdle(int idleTime)
+ {
+ _ioSession.setIdleTime(IdleStatus.READER_IDLE, idleTime);
+ }
+
+ public void setMaxWriteIdle(int idleTime)
+ {
+ _ioSession.setIdleTime(IdleStatus.WRITER_IDLE, idleTime);
+ }
+
+ public void close()
+ {
+ if (_lastWriteFuture != null)
+ {
+ _lastWriteFuture.join();
+ }
+ if (_acceptor != null)
+ {
+ _acceptor.unbindAll();
+ }
+ if (_ioSession != null)
+ {
+ _ioSession.close();
+ }
+ }
+
+ public void flush()
+ {
+ if (_lastWriteFuture != null)
+ {
+ _lastWriteFuture.join();
+ }
+ }
+
+ public void send(ByteBuffer msg)
+ {
+ org.apache.mina.common.ByteBuffer minaBuf = org.apache.mina.common.ByteBuffer.allocate(msg.capacity());
+ minaBuf.put(msg);
+ minaBuf.flip();
+ _lastWriteFuture = _ioSession.write(minaBuf);
+ }
+
+ public void setIdleTimeout(int i)
+ {
+ // MINA doesn't support setting SO_TIMEOUT
+ }
+
+ public void exceptionCaught(IoSession protocolSession, Throwable throwable) throws Exception
+ {
+ if (_protocolEngine != null)
+ {
+ _protocolEngine.exception(throwable);
+ }
+ else
+ {
+ _logger.error("Exception thrown and no ProtocolEngine to handle it", throwable);
+ }
+ _lastException = throwable;
+ }
+
+ /**
+ * Invoked when a message is received on a particular protocol session. Note
+ * that a protocol session is directly tied to a particular physical
+ * connection.
+ *
+ * @param protocolSession
+ * the protocol session that received the message
+ * @param message
+ * the message itself (i.e. a decoded frame)
+ *
+ * @throws Exception
+ * if the message cannot be processed
+ */
+ public void messageReceived(IoSession protocolSession, Object message) throws Exception
+ {
+ if (message instanceof org.apache.mina.common.ByteBuffer)
+ {
+ ((ProtocolEngine) protocolSession.getAttachment()).received(((org.apache.mina.common.ByteBuffer) message).buf());
+ }
+ else
+ {
+ throw new IllegalStateException("Handed unhandled message. message.class = " + message.getClass() + " message = " + message);
+ }
+ }
+
+ public void sessionClosed(IoSession protocolSession) throws Exception
+ {
+ ((ProtocolEngine) protocolSession.getAttachment()).closed();
+ }
+
+ public void sessionCreated(IoSession protocolSession) throws Exception
+ {
+ // Configure the session with SSL if necessary
+ SessionUtil.initialize(protocolSession);
+ if (_executorPool)
+ {
+ if (_sslFactory != null)
+ {
+ protocolSession.getFilterChain().addAfter("AsynchronousReadFilter", "sslFilter",
+ new SSLFilter(_sslFactory.buildServerContext()));
+ }
+ }
+ else
+ {
+ if (_sslFactory != null)
+ {
+ protocolSession.getFilterChain().addBefore("protocolFilter", "sslFilter",
+ new SSLFilter(_sslFactory.buildServerContext()));
+ }
+ }
+ // Do we want to have read/write buffer limits?
+ if (_protectIO)
+ {
+ //Add IO Protection Filters
+ IoFilterChain chain = protocolSession.getFilterChain();
+
+ protocolSession.getFilterChain().addLast("tempExecutorFilterForFilterBuilder", new ExecutorFilter());
+
+ ReadThrottleFilterBuilder readfilter = new ReadThrottleFilterBuilder();
+ readfilter.setMaximumConnectionBufferSize(_config.getReceiveBufferSize());
+ readfilter.attach(chain);
+
+ WriteBufferLimitFilterBuilder writefilter = new WriteBufferLimitFilterBuilder();
+ writefilter.setMaximumConnectionBufferSize(_config.getSendBufferSize());
+ writefilter.attach(chain);
+
+ protocolSession.getFilterChain().remove("tempExecutorFilterForFilterBuilder");
+ }
+
+ if (_ioSession == null)
+ {
+ _ioSession = protocolSession;
+ }
+
+ if (_acceptingConnections)
+ {
+ // Set up the protocol engine
+ ProtocolEngine protocolEngine = _factory.newProtocolEngine(this);
+ MINANetworkDriver newDriver = new MINANetworkDriver(_useNIO, _processors, _executorPool, _protectIO, protocolEngine, protocolSession);
+ protocolEngine.setNetworkDriver(newDriver);
+ }
+ }
+
+ public void sessionIdle(IoSession session, IdleStatus status) throws Exception
+ {
+ if (IdleStatus.WRITER_IDLE.equals(status))
+ {
+ ((ProtocolEngine) session.getAttachment()).writerIdle();
+ }
+ else if (IdleStatus.READER_IDLE.equals(status))
+ {
+ ((ProtocolEngine) session.getAttachment()).readerIdle();
+ }
+ }
+
+ private ProtocolEngine getProtocolEngine()
+ {
+ return _protocolEngine;
+ }
+
+ public void setProtocolEngineFactory(ProtocolEngineFactory engineFactory, boolean acceptingConnections)
+ {
+ _factory = engineFactory;
+ _acceptingConnections = acceptingConnections;
+ }
+
+ public void setProtocolEngine(ProtocolEngine protocolEngine)
+ {
+ _protocolEngine = protocolEngine;
+ if (_ioSession != null)
+ {
+ _ioSession.setAttachment(protocolEngine);
+ }
+ }
+
+}
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/transport/network/mina/MinaHandler.java b/qpid/java/common/src/main/java/org/apache/qpid/transport/network/mina/MinaHandler.java
new file mode 100644
index 0000000000..b89eed48b0
--- /dev/null
+++ b/qpid/java/common/src/main/java/org/apache/qpid/transport/network/mina/MinaHandler.java
@@ -0,0 +1,274 @@
+/*
+ *
+ * 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.network.mina;
+
+import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.net.SocketAddress;
+
+import org.apache.mina.common.*;
+
+import org.apache.mina.transport.socket.nio.SocketAcceptor;
+import org.apache.mina.transport.socket.nio.SocketSessionConfig;
+import org.apache.mina.transport.socket.nio.SocketConnector;
+import org.apache.mina.filter.ReadThrottleFilterBuilder;
+import org.apache.mina.filter.WriteBufferLimitFilterBuilder;
+import org.apache.mina.filter.executor.ExecutorFilter;
+
+import org.apache.qpid.transport.Binding;
+import org.apache.qpid.transport.Connection;
+import org.apache.qpid.transport.ConnectionDelegate;
+import org.apache.qpid.transport.Receiver;
+import org.apache.qpid.transport.Sender;
+import org.apache.qpid.transport.network.ConnectionBinding;
+
+import org.apache.qpid.transport.util.Logger;
+
+import org.apache.qpid.transport.network.Assembler;
+import org.apache.qpid.transport.network.Disassembler;
+import org.apache.qpid.transport.network.InputHandler;
+
+import static org.apache.qpid.transport.util.Functions.*;
+
+/**
+ * MinaHandler
+ *
+ * @author Rafael H. Schloming
+ */
+//RA making this public until we sort out the package issues
+public class MinaHandler<E> implements IoHandler
+{
+ /** Default buffer size for pending messages reads */
+ private static final String DEFAULT_READ_BUFFER_LIMIT = "262144";
+ /** Default buffer size for pending messages writes */
+ private static final String DEFAULT_WRITE_BUFFER_LIMIT = "262144";
+ private static final int MAX_RCVBUF = 64*1024;
+
+ private static final Logger log = Logger.get(MinaHandler.class);
+
+ static
+ {
+ ByteBuffer.setAllocator(new SimpleByteBufferAllocator());
+ ByteBuffer.setUseDirectBuffers(Boolean.getBoolean("amqj.enableDirectBuffers"));
+ }
+
+ private final Binding<E,java.nio.ByteBuffer> binding;
+
+ private MinaHandler(Binding<E,java.nio.ByteBuffer> binding)
+ {
+ this.binding = binding;
+ }
+
+ public void messageReceived(IoSession ssn, Object obj)
+ {
+ Attachment<E> attachment = (Attachment<E>) ssn.getAttachment();
+ ByteBuffer buf = (ByteBuffer) obj;
+ try
+ {
+ attachment.receiver.received(buf.buf());
+ }
+ catch (Throwable t)
+ {
+ log.error(t, "exception handling buffer %s", str(buf.buf()));
+ throw new RuntimeException(t);
+ }
+ }
+
+ public void messageSent(IoSession ssn, Object obj)
+ {
+ // do nothing
+ }
+
+ public void exceptionCaught(IoSession ssn, Throwable e)
+ {
+ Attachment<E> attachment = (Attachment<E>) ssn.getAttachment();
+ attachment.receiver.exception(e);
+ }
+
+ /**
+ * Invoked by MINA when a MINA session for a new connection is created. This method sets up the filter chain on the
+ * session, which filters the events handled by this handler. The filter chain consists of, handing off events
+ * to an optional protectio
+ *
+ * @param session The MINA session.
+ * @throws Exception Any underlying exceptions are allowed to fall through to MINA.
+ */
+ public void sessionCreated(IoSession session) throws Exception
+ {
+ log.debug("Protocol session created for session " + System.identityHashCode(session));
+
+ if (Boolean.getBoolean("protectio"))
+ {
+ try
+ {
+ //Add IO Protection Filters
+ IoFilterChain chain = session.getFilterChain();
+
+ session.getFilterChain().addLast("tempExecutorFilterForFilterBuilder", new ExecutorFilter());
+
+ ReadThrottleFilterBuilder readfilter = new ReadThrottleFilterBuilder();
+ readfilter.setMaximumConnectionBufferSize(
+ Integer.parseInt(System.getProperty("qpid.read.buffer.limit", DEFAULT_READ_BUFFER_LIMIT)));
+ readfilter.attach(chain);
+
+ WriteBufferLimitFilterBuilder writefilter = new WriteBufferLimitFilterBuilder();
+ writefilter.setMaximumConnectionBufferSize(
+ Integer.parseInt(System.getProperty("qpid.write.buffer.limit", DEFAULT_WRITE_BUFFER_LIMIT)));
+ writefilter.attach(chain);
+ session.getFilterChain().remove("tempExecutorFilterForFilterBuilder");
+
+ log.info("Using IO Read/Write Filter Protection");
+ }
+ catch (Exception e)
+ {
+ log.error("Unable to attach IO Read/Write Filter Protection :" + e.getMessage());
+ }
+ }
+ }
+
+ public void sessionOpened(final IoSession ssn)
+ {
+ log.debug("opened: %s", this);
+ E endpoint = binding.endpoint(new MinaSender(ssn));
+ Attachment<E> attachment =
+ new Attachment<E>(endpoint, binding.receiver(endpoint));
+
+ // We need to synchronize and notify here because the MINA
+ // connect future returns the session prior to the attachment
+ // being set. This is arguably a bug in MINA.
+ synchronized (ssn)
+ {
+ ssn.setAttachment(attachment);
+ ssn.notifyAll();
+ }
+ }
+
+ public void sessionClosed(IoSession ssn)
+ {
+ log.debug("closed: %s", ssn);
+ Attachment<E> attachment = (Attachment<E>) ssn.getAttachment();
+ attachment.receiver.closed();
+ ssn.setAttachment(null);
+ }
+
+ public void sessionIdle(IoSession ssn, IdleStatus status)
+ {
+ // do nothing
+ }
+
+ private static class Attachment<E>
+ {
+
+ E endpoint;
+ Receiver<java.nio.ByteBuffer> receiver;
+
+ Attachment(E endpoint, Receiver<java.nio.ByteBuffer> receiver)
+ {
+ this.endpoint = endpoint;
+ this.receiver = receiver;
+ }
+ }
+
+ public static final void accept(String host, int port,
+ Binding<?,java.nio.ByteBuffer> binding)
+ throws IOException
+ {
+ accept(new InetSocketAddress(host, port), binding);
+ }
+
+ public static final <E> void accept(SocketAddress address,
+ Binding<E,java.nio.ByteBuffer> binding)
+ throws IOException
+ {
+ IoAcceptor acceptor = new SocketAcceptor();
+ acceptor.bind(address, new MinaHandler<E>(binding));
+ }
+
+ public static final <E> E connect(String host, int port,
+ Binding<E,java.nio.ByteBuffer> binding)
+ {
+ return connect(new InetSocketAddress(host, port), binding);
+ }
+
+ public static final <E> E connect(SocketAddress address,
+ Binding<E,java.nio.ByteBuffer> binding)
+ {
+ MinaHandler<E> handler = new MinaHandler<E>(binding);
+ SocketConnector connector = new SocketConnector();
+ IoServiceConfig acceptorConfig = connector.getDefaultConfig();
+ acceptorConfig.setThreadModel(ThreadModel.MANUAL);
+ SocketSessionConfig scfg = (SocketSessionConfig) acceptorConfig.getSessionConfig();
+ scfg.setTcpNoDelay(Boolean.getBoolean("amqj.tcpNoDelay"));
+ Integer sendBufferSize = Integer.getInteger("amqj.sendBufferSize");
+ if (sendBufferSize != null && sendBufferSize > 0)
+ {
+ scfg.setSendBufferSize(sendBufferSize);
+ }
+ Integer receiveBufferSize = Integer.getInteger("amqj.receiveBufferSize");
+ if (receiveBufferSize != null && receiveBufferSize > 0)
+ {
+ scfg.setReceiveBufferSize(receiveBufferSize);
+ }
+ else if (scfg.getReceiveBufferSize() > MAX_RCVBUF)
+ {
+ scfg.setReceiveBufferSize(MAX_RCVBUF);
+ }
+ connector.setWorkerTimeout(0);
+ ConnectFuture cf = connector.connect(address, handler);
+ cf.join();
+ IoSession ssn = cf.getSession();
+
+ // We need to synchronize and wait here because the MINA
+ // connect future returns the session prior to the attachment
+ // being set. This is arguably a bug in MINA.
+ synchronized (ssn)
+ {
+ while (ssn.getAttachment() == null)
+ {
+ try
+ {
+ ssn.wait();
+ }
+ catch (InterruptedException e)
+ {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+
+ Attachment<E> attachment = (Attachment<E>) ssn.getAttachment();
+ return attachment.endpoint;
+ }
+
+ public static final void accept(String host, int port,
+ ConnectionDelegate delegate)
+ throws IOException
+ {
+ accept(host, port, ConnectionBinding.get(delegate));
+ }
+
+ public static final Connection connect(String host, int port,
+ ConnectionDelegate delegate)
+ {
+ return connect(host, port, ConnectionBinding.get(delegate));
+ }
+
+}
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/transport/network/mina/MinaNetworkConnection.java b/qpid/java/common/src/main/java/org/apache/qpid/transport/network/mina/MinaNetworkConnection.java
deleted file mode 100644
index 0f433f6eeb..0000000000
--- a/qpid/java/common/src/main/java/org/apache/qpid/transport/network/mina/MinaNetworkConnection.java
+++ /dev/null
@@ -1,81 +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.transport.network.mina;
-
-import java.net.SocketAddress;
-import java.nio.ByteBuffer;
-
-import org.apache.mina.common.IdleStatus;
-import org.apache.mina.common.IoSession;
-import org.apache.qpid.transport.Sender;
-import org.apache.qpid.transport.network.NetworkConnection;
-
-public class MinaNetworkConnection implements NetworkConnection
-{
- private IoSession _session;
- private Sender<ByteBuffer> _sender;
-
- public MinaNetworkConnection(IoSession session)
- {
- _session = session;
- _sender = new MinaSender(_session);
- }
-
- public Sender<ByteBuffer> getSender()
- {
- return _sender;
- }
-
- public void close()
- {
- _session.close();
- }
-
- public SocketAddress getRemoteAddress()
- {
- return _session.getRemoteAddress();
- }
-
- public SocketAddress getLocalAddress()
- {
- return _session.getLocalAddress();
- }
-
- public long getReadBytes()
- {
- return _session.getReadBytes();
- }
-
- public long getWrittenBytes()
- {
- return _session.getWrittenBytes();
- }
-
- public void setMaxWriteIdle(int sec)
- {
- _session.setIdleTime(IdleStatus.WRITER_IDLE, sec);
- }
-
- public void setMaxReadIdle(int sec)
- {
- _session.setIdleTime(IdleStatus.READER_IDLE, sec);
- }
-}
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/transport/network/mina/MinaNetworkHandler.java b/qpid/java/common/src/main/java/org/apache/qpid/transport/network/mina/MinaNetworkHandler.java
deleted file mode 100644
index c00187480c..0000000000
--- a/qpid/java/common/src/main/java/org/apache/qpid/transport/network/mina/MinaNetworkHandler.java
+++ /dev/null
@@ -1,149 +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.transport.network.mina;
-
-import org.apache.mina.common.ByteBuffer;
-import org.apache.mina.common.IdleStatus;
-import org.apache.mina.common.IoHandlerAdapter;
-import org.apache.mina.common.IoSession;
-import org.apache.mina.common.SimpleByteBufferAllocator;
-import org.apache.mina.filter.SSLFilter;
-import org.apache.mina.util.SessionUtil;
-import org.apache.qpid.protocol.ProtocolEngine;
-import org.apache.qpid.protocol.ProtocolEngineFactory;
-import org.apache.qpid.ssl.SSLContextFactory;
-import org.apache.qpid.transport.network.NetworkConnection;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class MinaNetworkHandler extends IoHandlerAdapter
-{
- private static final Logger LOGGER = LoggerFactory.getLogger(MinaNetworkHandler.class);
-
- private ProtocolEngineFactory _factory;
- private SSLContextFactory _sslFactory = null;
-
- static
- {
- boolean directBuffers = Boolean.getBoolean("amqj.enableDirectBuffers");
- LOGGER.debug("Using " + (directBuffers ? "direct" : "heap") + " buffers");
- ByteBuffer.setUseDirectBuffers(directBuffers);
-
- //override the MINA defaults to prevent use of the PooledByteBufferAllocator
- ByteBuffer.setAllocator(new SimpleByteBufferAllocator());
- }
-
- public MinaNetworkHandler(SSLContextFactory sslFactory, ProtocolEngineFactory factory)
- {
- _sslFactory = sslFactory;
- _factory = factory;
- }
-
- public MinaNetworkHandler(SSLContextFactory sslFactory)
- {
- this(sslFactory, null);
- }
-
- public void messageReceived(IoSession session, Object message)
- {
- ProtocolEngine engine = (ProtocolEngine) session.getAttachment();
- ByteBuffer buf = (ByteBuffer) message;
- try
- {
- engine.received(buf.buf());
- }
- catch (RuntimeException re)
- {
- engine.exception(re);
- }
- }
-
- public void exceptionCaught(IoSession ioSession, Throwable throwable) throws Exception
- {
- ProtocolEngine engine = (ProtocolEngine) ioSession.getAttachment();
- if(engine != null)
- {
- LOGGER.error("Exception caught by Mina", throwable);
- engine.exception(throwable);
- }
- else
- {
- LOGGER.error("Exception caught by Mina but without protocol engine to handle it", throwable);
- }
- }
-
- public void sessionCreated(IoSession ioSession) throws Exception
- {
- if(LOGGER.isDebugEnabled())
- {
- LOGGER.debug("Created session: " + ioSession.getRemoteAddress());
- }
-
- SessionUtil.initialize(ioSession);
-
- if (_sslFactory != null)
- {
- ioSession.getFilterChain().addBefore("protocolFilter", "sslFilter",
- new SSLFilter(_sslFactory.buildServerContext()));
- }
-
- if (_factory != null)
- {
- NetworkConnection netConn = new MinaNetworkConnection(ioSession);
-
- ProtocolEngine engine = _factory.newProtocolEngine(netConn);
- ioSession.setAttachment(engine);
- }
- }
-
- public void sessionClosed(IoSession ioSession) throws Exception
- {
- if(LOGGER.isDebugEnabled())
- {
- LOGGER.debug("closed: " + ioSession.getRemoteAddress());
- }
-
- ProtocolEngine engine = (ProtocolEngine) ioSession.getAttachment();
- if(engine != null)
- {
- engine.closed();
- }
- else
- {
- LOGGER.error("Unable to close ProtocolEngine as none was present");
- }
- }
-
-
- public void sessionIdle(IoSession session, IdleStatus status) throws Exception
- {
- if (IdleStatus.WRITER_IDLE.equals(status))
- {
- ((ProtocolEngine) session.getAttachment()).writerIdle();
- }
- else if (IdleStatus.READER_IDLE.equals(status))
- {
- ((ProtocolEngine) session.getAttachment()).readerIdle();
- }
- }
-
-}
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/transport/network/mina/MinaNetworkTransport.java b/qpid/java/common/src/main/java/org/apache/qpid/transport/network/mina/MinaNetworkTransport.java
deleted file mode 100644
index d0367b82f4..0000000000
--- a/qpid/java/common/src/main/java/org/apache/qpid/transport/network/mina/MinaNetworkTransport.java
+++ /dev/null
@@ -1,219 +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.transport.network.mina;
-
-import static org.apache.qpid.transport.ConnectionSettings.WILDCARD_ADDRESS;
-
-import java.io.IOException;
-import java.net.InetSocketAddress;
-import java.net.SocketAddress;
-
-import org.apache.mina.common.ConnectFuture;
-import org.apache.mina.common.ExecutorThreadModel;
-import org.apache.mina.common.IoConnector;
-import org.apache.mina.common.IoSession;
-import org.apache.mina.transport.socket.nio.SocketAcceptor;
-import org.apache.mina.transport.socket.nio.SocketAcceptorConfig;
-import org.apache.mina.transport.socket.nio.SocketConnector;
-import org.apache.mina.transport.socket.nio.SocketConnectorConfig;
-import org.apache.mina.transport.socket.nio.SocketSessionConfig;
-import org.apache.mina.util.NewThreadExecutor;
-
-import org.apache.qpid.protocol.ProtocolEngineFactory;
-import org.apache.qpid.ssl.SSLContextFactory;
-import org.apache.qpid.thread.QpidThreadExecutor;
-import org.apache.qpid.transport.ConnectionSettings;
-import org.apache.qpid.transport.NetworkTransportConfiguration;
-import org.apache.qpid.transport.Receiver;
-import org.apache.qpid.transport.SocketConnectorFactory;
-import org.apache.qpid.transport.TransportException;
-import org.apache.qpid.transport.network.IncomingNetworkTransport;
-import org.apache.qpid.transport.network.NetworkConnection;
-import org.apache.qpid.transport.network.OutgoingNetworkTransport;
-import org.apache.qpid.transport.network.Transport;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class MinaNetworkTransport implements OutgoingNetworkTransport, IncomingNetworkTransport
-{
- private static final int UNKNOWN = -1;
- private static final int TCP = 0;
-
- public NetworkConnection _connection;
- private SocketAcceptor _acceptor;
- private InetSocketAddress _address;
-
- public NetworkConnection connect(ConnectionSettings settings,
- Receiver<java.nio.ByteBuffer> delegate, SSLContextFactory sslFactory)
- {
- int transport = getTransport(settings.getProtocol());
-
- IoConnectorCreator stc;
- switch(transport)
- {
- case TCP:
- stc = new IoConnectorCreator(new SocketConnectorFactory()
- {
- public IoConnector newConnector()
- {
- return new SocketConnector(1, new QpidThreadExecutor()); // non-blocking connector
- }
- });
- _connection = stc.connect(delegate, settings, sslFactory);
- break;
- case UNKNOWN:
- default:
- throw new TransportException("Unknown protocol: " + settings.getProtocol());
- }
-
- return _connection;
- }
-
- private static int getTransport(String transport)
- {
- if (transport.equals(Transport.TCP))
- {
- return TCP;
- }
-
- return UNKNOWN;
- }
-
- public void close()
- {
- if(_connection != null)
- {
- _connection.close();
- }
- if (_acceptor != null)
- {
- _acceptor.unbindAll();
- }
- }
-
- public NetworkConnection getConnection()
- {
- return _connection;
- }
-
- public void accept(final NetworkTransportConfiguration config, final ProtocolEngineFactory factory,
- final SSLContextFactory sslFactory)
- {
- int processors = config.getConnectorProcessors();
-
- if (Transport.TCP.equalsIgnoreCase(config.getTransport()))
- {
- _acceptor = new SocketAcceptor(processors, new NewThreadExecutor());
-
- SocketAcceptorConfig sconfig = (SocketAcceptorConfig) _acceptor.getDefaultConfig();
- sconfig.setThreadModel(ExecutorThreadModel.getInstance("MinaNetworkTransport(Acceptor)"));
- SocketSessionConfig sc = (SocketSessionConfig) sconfig.getSessionConfig();
- sc.setTcpNoDelay(config.getTcpNoDelay());
- sc.setSendBufferSize(config.getSendBufferSize());
- sc.setReceiveBufferSize(config.getReceiveBufferSize());
-
- if (config.getHost().equals(WILDCARD_ADDRESS))
- {
- _address = new InetSocketAddress(config.getPort());
- }
- else
- {
- _address = new InetSocketAddress(config.getHost(), config.getPort());
- }
- }
- else
- {
- throw new TransportException("Unknown transport: " + config.getTransport());
- }
-
- try
- {
- _acceptor.bind(_address, new MinaNetworkHandler(sslFactory, factory));
- }
- catch (IOException e)
- {
- throw new TransportException("Could not bind to " + _address, e);
- }
- }
-
-
- private static class IoConnectorCreator
- {
- private static final Logger LOGGER = LoggerFactory.getLogger(IoConnectorCreator.class);
-
- private static final int CLIENT_DEFAULT_BUFFER_SIZE = 32 * 1024;
-
- private SocketConnectorFactory _ioConnectorFactory;
-
- public IoConnectorCreator(SocketConnectorFactory socketConnectorFactory)
- {
- _ioConnectorFactory = socketConnectorFactory;
- }
-
- public NetworkConnection connect(Receiver<java.nio.ByteBuffer> receiver, ConnectionSettings settings, SSLContextFactory sslFactory)
- {
- final IoConnector ioConnector = _ioConnectorFactory.newConnector();
- final SocketAddress address;
- final String protocol = settings.getProtocol();
- final int port = settings.getPort();
-
- if (Transport.TCP.equalsIgnoreCase(protocol))
- {
- address = new InetSocketAddress(settings.getHost(), port);
- }
- else
- {
- throw new TransportException("Unknown transport: " + protocol);
- }
-
- LOGGER.info("Attempting connection to " + address);
-
- if (ioConnector instanceof SocketConnector)
- {
- SocketConnectorConfig cfg = (SocketConnectorConfig) ioConnector.getDefaultConfig();
- cfg.setThreadModel(ExecutorThreadModel.getInstance("MinaNetworkTransport(Client)"));
-
- SocketSessionConfig scfg = (SocketSessionConfig) cfg.getSessionConfig();
- scfg.setTcpNoDelay(true);
- scfg.setSendBufferSize(CLIENT_DEFAULT_BUFFER_SIZE);
- scfg.setReceiveBufferSize(CLIENT_DEFAULT_BUFFER_SIZE);
-
- // Don't have the connector's worker thread wait around for other
- // connections (we only use one SocketConnector per connection
- // at the moment anyway). This allows short-running
- // clients (like unit tests) to complete quickly.
- ((SocketConnector) ioConnector).setWorkerTimeout(0);
- }
-
- ConnectFuture future = ioConnector.connect(address, new MinaNetworkHandler(sslFactory), ioConnector.getDefaultConfig());
- future.join();
- if (!future.isConnected())
- {
- throw new TransportException("Could not open connection");
- }
-
- IoSession session = future.getSession();
- session.setAttachment(receiver);
-
- return new MinaNetworkConnection(session);
- }
- }
-}
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/transport/network/mina/MinaSender.java b/qpid/java/common/src/main/java/org/apache/qpid/transport/network/mina/MinaSender.java
index be114e2fa1..22b9c5e784 100644
--- a/qpid/java/common/src/main/java/org/apache/qpid/transport/network/mina/MinaSender.java
+++ b/qpid/java/common/src/main/java/org/apache/qpid/transport/network/mina/MinaSender.java
@@ -25,55 +25,66 @@ import org.apache.mina.common.CloseFuture;
import org.apache.mina.common.IoSession;
import org.apache.mina.common.WriteFuture;
import org.apache.qpid.transport.Sender;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import org.apache.qpid.transport.TransportException;
+
/**
* MinaSender
*/
+
public class MinaSender implements Sender<java.nio.ByteBuffer>
{
- private static final Logger _log = LoggerFactory.getLogger(MinaSender.class);
-
- private final IoSession _session;
- private WriteFuture _lastWrite;
+ private static final int TIMEOUT = 2 * 60 * 1000;
+
+ private final IoSession session;
+ private WriteFuture lastWrite = null;
public MinaSender(IoSession session)
{
- _session = session;
+ this.session = session;
}
- public synchronized void send(java.nio.ByteBuffer msg)
+ public void send(java.nio.ByteBuffer buf)
{
- _log.debug("sending data:");
- ByteBuffer mina = ByteBuffer.allocate(msg.limit());
- mina.put(msg);
- mina.flip();
- _lastWrite = _session.write(mina);
- _log.debug("sent data:");
- }
+ if (session.isClosing())
+ {
+ throw new TransportException("attempted to write to a closed socket");
+ }
- public synchronized void flush()
- {
- if (_lastWrite != null)
+ synchronized (this)
{
- _lastWrite.join();
+ lastWrite = session.write(ByteBuffer.wrap(buf));
}
}
- public void close()
+ public void flush()
{
- // MINA will sometimes throw away in-progress writes when you ask it to close
- flush();
- CloseFuture closed = _session.close();
+ // pass
+ }
+
+ public synchronized void close()
+ {
+ // MINA will sometimes throw away in-progress writes when you
+ // ask it to close
+ synchronized (this)
+ {
+ if (lastWrite != null)
+ {
+ lastWrite.join();
+ }
+ }
+ CloseFuture closed = session.close();
closed.join();
}
public void setIdleTimeout(int i)
{
- //TODO:
- //We are instead using the setMax[Read|Write]IdleTime methods in
- //MinaNetworkConnection for this. Should remove this method from
- //sender interface, but currently being used by IoSender for 0-10.
+ //noop
}
+
+ public long getIdleTimeout()
+ {
+ return 0;
+ }
+
}
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/transport/network/nio/NioHandler.java b/qpid/java/common/src/main/java/org/apache/qpid/transport/network/nio/NioHandler.java
new file mode 100644
index 0000000000..84e66c25bd
--- /dev/null
+++ b/qpid/java/common/src/main/java/org/apache/qpid/transport/network/nio/NioHandler.java
@@ -0,0 +1,135 @@
+package org.apache.qpid.transport.network.nio;
+/*
+ *
+ * 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 java.io.IOException;
+import java.net.InetSocketAddress;
+import java.net.SocketAddress;
+import java.net.SocketException;
+import java.nio.ByteBuffer;
+import java.nio.channels.SocketChannel;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.apache.qpid.transport.Connection;
+import org.apache.qpid.transport.ConnectionDelegate;
+import org.apache.qpid.transport.Receiver;
+import org.apache.qpid.transport.network.Assembler;
+import org.apache.qpid.transport.network.Disassembler;
+import org.apache.qpid.transport.network.InputHandler;
+
+public class NioHandler implements Runnable
+{
+ private Receiver<ByteBuffer> _receiver;
+ private SocketChannel _ch;
+ private ByteBuffer _readBuf;
+ private static Map<Long,NioSender> _handlers = new ConcurrentHashMap<Long,NioSender>();
+
+ private NioHandler(){}
+
+ public static final Connection connect(String host, int port,
+ ConnectionDelegate delegate)
+ {
+ NioHandler handler = new NioHandler();
+ return handler.connectInternal(host,port,delegate);
+ }
+
+ private Connection connectInternal(String host, int port,
+ ConnectionDelegate delegate)
+ {
+ try
+ {
+ SocketAddress address = new InetSocketAddress(host,port);
+ _ch = SocketChannel.open();
+ _ch.socket().setReuseAddress(true);
+ _ch.configureBlocking(true);
+ _ch.socket().setTcpNoDelay(true);
+ if (address != null)
+ {
+ _ch.socket().connect(address);
+ }
+ while (_ch.isConnectionPending())
+ {
+
+ }
+
+ }
+ catch (SocketException e)
+ {
+
+ e.printStackTrace();
+ }
+ catch (IOException e)
+ {
+ e.printStackTrace();
+ }
+
+ NioSender sender = new NioSender(_ch);
+ Connection con = new Connection();
+ con.setSender(new Disassembler(sender, 64*1024 - 1));
+ con.setConnectionDelegate(delegate);
+
+ _handlers.put(con.getConnectionId(),sender);
+
+ _receiver = new InputHandler(new Assembler(con), InputHandler.State.FRAME_HDR);
+
+ Thread t = new Thread(this);
+ t.start();
+
+ return con;
+ }
+
+ public void run()
+ {
+ _readBuf = ByteBuffer.allocate(512);
+ long read = 0;
+ while(_ch.isConnected() && _ch.isOpen())
+ {
+ try
+ {
+ read = _ch.read(_readBuf);
+ if (read > 0)
+ {
+ _readBuf.flip();
+ ByteBuffer b = ByteBuffer.allocate(_readBuf.remaining());
+ b.put(_readBuf);
+ b.flip();
+ _readBuf.clear();
+ _receiver.received(b);
+ }
+ }
+ catch(Exception e)
+ {
+ e.printStackTrace();
+ }
+ }
+
+ //throw new EOFException("The underlying socket/channel has closed");
+ }
+
+ public static void startBatchingFrames(int connectionId)
+ {
+ NioSender sender = _handlers.get(connectionId);
+ sender.setStartBatching();
+ }
+
+
+}
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/transport/network/nio/NioSender.java b/qpid/java/common/src/main/java/org/apache/qpid/transport/network/nio/NioSender.java
new file mode 100644
index 0000000000..2fa875f279
--- /dev/null
+++ b/qpid/java/common/src/main/java/org/apache/qpid/transport/network/nio/NioSender.java
@@ -0,0 +1,126 @@
+package org.apache.qpid.transport.network.nio;
+/*
+ *
+ * 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 java.nio.ByteBuffer;
+import java.nio.channels.SocketChannel;
+
+import org.apache.qpid.transport.Sender;
+
+public class NioSender implements Sender<java.nio.ByteBuffer>
+{
+ private final Object lock = new Object();
+ private SocketChannel _ch;
+ private boolean _batch = false;
+ private ByteBuffer _batcher;
+
+ public NioSender(SocketChannel ch)
+ {
+ this._ch = ch;
+ }
+
+ public void send(java.nio.ByteBuffer buf)
+ {
+ if (_batch)
+ {
+ //System.out.println(_batcher.position() + " , " + buf.remaining() + " , " + buf.position() + ","+_batcher.capacity());
+ if (_batcher.position() + buf.remaining() >= _batcher.capacity())
+ {
+ _batcher.flip();
+ write(_batcher);
+ _batcher.clear();
+ if (buf.remaining() > _batcher.capacity())
+ {
+ write(buf);
+ }
+ else
+ {
+ _batcher.put(buf);
+ }
+ }
+ else
+ {
+ _batcher.put(buf);
+ }
+ }
+ else
+ {
+ write(buf);
+ }
+ }
+
+ public void flush()
+ {
+ // pass
+ }
+
+ private void write(java.nio.ByteBuffer buf)
+ {
+ synchronized (lock)
+ {
+ if( _ch.isConnected() && _ch.isOpen())
+ {
+ try
+ {
+ _ch.write(buf);
+ }
+ catch(Exception e)
+ {
+ e.fillInStackTrace();
+ }
+ }
+ else
+ {
+ throw new RuntimeException("Trying to write on a closed socket");
+ }
+
+ }
+ }
+
+ public void setStartBatching()
+ {
+ _batch = true;
+ _batcher = ByteBuffer.allocate(1024);
+ }
+
+ public void close()
+ {
+ // MINA will sometimes throw away in-progress writes when you
+ // ask it to close
+ synchronized (lock)
+ {
+ try
+ {
+ _ch.close();
+ }
+ catch(Exception e)
+ {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ public void setIdleTimeout(int i)
+ {
+ //noop
+ }
+}
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/transport/network/security/SecurityLayer.java b/qpid/java/common/src/main/java/org/apache/qpid/transport/network/security/SecurityLayer.java
index 69e4b52edb..3f0966903d 100644
--- a/qpid/java/common/src/main/java/org/apache/qpid/transport/network/security/SecurityLayer.java
+++ b/qpid/java/common/src/main/java/org/apache/qpid/transport/network/security/SecurityLayer.java
@@ -43,8 +43,8 @@ public class SecurityLayer
Connection con;
SSLSecurityLayer sslLayer;
SASLSecurityLayer saslLayer;
-
- public SecurityLayer(Connection con)
+
+ public void init(Connection con) throws TransportException
{
this.con = con;
this.settings = con.getConnectionSettings();
@@ -55,9 +55,10 @@ public class SecurityLayer
if (settings.isUseSASLEncryption())
{
saslLayer = new SASLSecurityLayer();
- }
+ }
+
}
-
+
public Sender<ByteBuffer> sender(Sender<ByteBuffer> delegate)
{
Sender<ByteBuffer> sender = delegate;
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/transport/network/security/sasl/SASLSender.java b/qpid/java/common/src/main/java/org/apache/qpid/transport/network/security/sasl/SASLSender.java
index 2d9e4e9a7e..27255f79f6 100644
--- a/qpid/java/common/src/main/java/org/apache/qpid/transport/network/security/sasl/SASLSender.java
+++ b/qpid/java/common/src/main/java/org/apache/qpid/transport/network/security/sasl/SASLSender.java
@@ -43,7 +43,8 @@ public class SASLSender extends SASLEncryptor implements Sender<ByteBuffer> {
this.delegate = delegate;
log.debug("SASL Sender enabled");
}
-
+
+ @Override
public void close()
{
@@ -64,11 +65,13 @@ public class SASLSender extends SASLEncryptor implements Sender<ByteBuffer> {
}
}
+ @Override
public void flush()
{
delegate.flush();
}
+ @Override
public void send(ByteBuffer buf)
{
if (closed.get())
@@ -105,6 +108,7 @@ public class SASLSender extends SASLEncryptor implements Sender<ByteBuffer> {
}
}
+ @Override
public void setIdleTimeout(int i)
{
delegate.setIdleTimeout(i);
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/transport/network/security/ssl/QpidClientX509KeyManager.java b/qpid/java/common/src/main/java/org/apache/qpid/transport/network/security/ssl/QpidClientX509KeyManager.java
index 0dd86d4560..14f28f8828 100644
--- a/qpid/java/common/src/main/java/org/apache/qpid/transport/network/security/ssl/QpidClientX509KeyManager.java
+++ b/qpid/java/common/src/main/java/org/apache/qpid/transport/network/security/ssl/QpidClientX509KeyManager.java
@@ -48,45 +48,51 @@ public class QpidClientX509KeyManager extends X509ExtendedKeyManager
kmf.init(ks, keyStorePassword.toCharArray());
this.delegate = (X509ExtendedKeyManager)kmf.getKeyManagers()[0];
}
-
+
+ @Override
public String chooseClientAlias(String[] keyType, Principal[] issuers, Socket socket)
{
log.debug("chooseClientAlias:Returning alias " + alias);
return alias;
}
+ @Override
public String chooseServerAlias(String keyType, Principal[] issuers, Socket socket)
{
return delegate.chooseServerAlias(keyType, issuers, socket);
}
+ @Override
public X509Certificate[] getCertificateChain(String alias)
{
return delegate.getCertificateChain(alias);
}
+ @Override
public String[] getClientAliases(String keyType, Principal[] issuers)
{
log.debug("getClientAliases:Returning alias " + alias);
return new String[]{alias};
}
+ @Override
public PrivateKey getPrivateKey(String alias)
{
return delegate.getPrivateKey(alias);
}
+ @Override
public String[] getServerAliases(String keyType, Principal[] issuers)
{
return delegate.getServerAliases(keyType, issuers);
}
-
+
public String chooseEngineClientAlias(String[] keyType, Principal[] issuers, SSLEngine engine)
{
log.debug("chooseEngineClientAlias:Returning alias " + alias);
return alias;
}
-
+
public String chooseEngineServerAlias(String keyType, Principal[] issuers, SSLEngine engine)
{
return delegate.chooseEngineServerAlias(keyType, issuers, engine);
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/url/URLHelper.java b/qpid/java/common/src/main/java/org/apache/qpid/url/URLHelper.java
index e261860bf3..6f21c327e7 100644
--- a/qpid/java/common/src/main/java/org/apache/qpid/url/URLHelper.java
+++ b/qpid/java/common/src/main/java/org/apache/qpid/url/URLHelper.java
@@ -31,6 +31,9 @@ public class URLHelper
public static void parseOptions(Map<String, String> optionMap, String options) throws URLSyntaxException
{
+ // options looks like this
+ // brokerlist='tcp://host:port?option='value',option='value';vm://:3/virtualpath?option='value'',failover='method?option='value',option='value''
+
if ((options == null) || (options.indexOf('=') == -1))
{
return;
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 ac8e3da3c2..516204fbd3 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
@@ -143,9 +143,8 @@ public class FileUtils
}
/**
- * Either opens the specified filename as an input stream or either the filesystem or classpath,
- * or uses the default resource loaded using the specified class loader, if opening the file fails
- * or no file name is specified.
+ * Either opens the specified filename as an input stream, or uses the default resource loaded using the
+ * specified class loader, if opening the file fails or no file name is specified.
*
* @param filename The name of the file to open.
* @param defaultResource The name of the default resource on the classpath if the file cannot be opened.
@@ -157,28 +156,28 @@ public class FileUtils
{
InputStream is = null;
+ // Flag to indicate whether the default resource should be used. By default this is true, so that the default
+ // is used when opening the file fails.
+ boolean useDefault = true;
+
// Try to open the file if one was specified.
if (filename != null)
{
- // try on filesystem
try
{
is = new BufferedInputStream(new FileInputStream(new File(filename)));
+
+ // Clear the default flag because the file was succesfully opened.
+ useDefault = false;
}
catch (FileNotFoundException e)
{
- is = null;
- }
-
- if (is == null)
- {
- // failed on filesystem, so try on classpath
- is = cl.getResourceAsStream(filename);
+ // Ignore this exception, the default will be used instead.
}
}
// Load the default resource if a file was not specified, or if opening the file failed.
- if (is == null)
+ if (useDefault)
{
is = cl.getResourceAsStream(defaultResource);
}
@@ -340,7 +339,7 @@ public class FileUtils
}
//else we have a source directory
- if (!dst.isDirectory() && !dst.mkdirs())
+ if (!dst.isDirectory() && !dst.mkdir())
{
throw new UnableToCopyException("Unable to create destination directory");
}
diff --git a/qpid/java/common/src/test/java/org/apache/mina/SocketIOTest/IOWriterClient.java b/qpid/java/common/src/test/java/org/apache/mina/SocketIOTest/IOWriterClient.java
new file mode 100644
index 0000000000..b93dc46741
--- /dev/null
+++ b/qpid/java/common/src/test/java/org/apache/mina/SocketIOTest/IOWriterClient.java
@@ -0,0 +1,396 @@
+/*
+ *
+ * Copyright (c) 2006 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.mina.SocketIOTest;
+
+import org.apache.mina.common.ByteBuffer;
+import org.apache.mina.common.CloseFuture;
+import org.apache.mina.common.ConnectFuture;
+import org.apache.mina.common.IoConnector;
+import org.apache.mina.common.IoFilterChain;
+import org.apache.mina.common.IoHandlerAdapter;
+import org.apache.mina.common.IoSession;
+import org.apache.mina.common.SimpleByteBufferAllocator;
+import org.apache.mina.filter.ReadThrottleFilterBuilder;
+import org.apache.mina.filter.WriteBufferLimitFilterBuilder;
+import org.apache.mina.transport.socket.nio.SocketSessionConfig;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.util.concurrent.CountDownLatch;
+
+public class IOWriterClient implements Runnable
+{
+ private static final Logger _logger = LoggerFactory.getLogger(IOWriterClient.class);
+
+ public static int DEFAULT_TEST_SIZE = 2;
+
+ private IoSession _session;
+
+ private long _startTime;
+
+ private long[] _chunkTimes;
+
+ public int _chunkCount = 200000;
+
+ private int _chunkSize = 1024;
+
+ private CountDownLatch _notifier;
+
+ private int _maximumWriteQueueLength;
+
+ static public int _PORT = IOWriterServer._PORT;
+
+ public void run()
+ {
+ _logger.info("Starting to send " + _chunkCount + " buffers of " + _chunkSize + "B");
+ _startTime = System.currentTimeMillis();
+ _notifier = new CountDownLatch(1);
+
+ for (int i = 0; i < _chunkCount; i++)
+ {
+ ByteBuffer buf = ByteBuffer.allocate(_chunkSize, false);
+ byte check = (byte) (i % 128);
+ buf.put(check);
+ buf.fill((byte) 88, buf.remaining());
+ buf.flip();
+
+ _session.write(buf);
+ }
+
+ long _sentall = System.currentTimeMillis();
+ long _receivedall = _sentall;
+ try
+ {
+ _logger.info("All buffers sent; waiting for receipt from server");
+ _notifier.await();
+ _receivedall = System.currentTimeMillis();
+ }
+ catch (InterruptedException e)
+ {
+ //Ignore
+ }
+ _logger.info("Completed");
+ _logger.info("Total time waiting for server after last write: " + (_receivedall - _sentall));
+
+ long totalTime = System.currentTimeMillis() - _startTime;
+
+ _logger.info("Total time: " + totalTime);
+ _logger.info("MB per second: " + (int) ((1.0 * _chunkSize * _chunkCount) / totalTime));
+ long lastChunkTime = _startTime;
+ double average = 0;
+ for (int i = 0; i < _chunkTimes.length; i++)
+ {
+ if (i == 0)
+ {
+ average = _chunkTimes[i] - _startTime;
+ }
+ else
+ {
+ long delta = _chunkTimes[i] - lastChunkTime;
+ if (delta != 0)
+ {
+ average = (average + delta) / 2;
+ }
+ }
+ lastChunkTime = _chunkTimes[i];
+ }
+ _logger.info("Average chunk time: " + average + "ms");
+ _logger.info("Maximum WriteRequestQueue size: " + _maximumWriteQueueLength);
+
+ CloseFuture cf = _session.close();
+ _logger.info("Closing session");
+ cf.join();
+ }
+
+ private class WriterHandler extends IoHandlerAdapter
+ {
+ private int _chunksReceived = 0;
+
+ private int _partialBytesRead = 0;
+
+ private byte _partialCheckNumber;
+
+ private int _totalBytesReceived = 0;
+
+ private int _receivedCount = 0;
+ private int _sentCount = 0;
+ private static final String DEFAULT_READ_BUFFER = "262144";
+ private static final String DEFAULT_WRITE_BUFFER = "262144";
+
+ public void sessionCreated(IoSession session) throws Exception
+ {
+ IoFilterChain chain = session.getFilterChain();
+
+ ReadThrottleFilterBuilder readfilter = new ReadThrottleFilterBuilder();
+ readfilter.setMaximumConnectionBufferSize(Integer.parseInt(System.getProperty("qpid.read.buffer.limit", DEFAULT_READ_BUFFER)));
+ readfilter.attach(chain);
+
+ WriteBufferLimitFilterBuilder writefilter = new WriteBufferLimitFilterBuilder();
+
+ writefilter.setMaximumConnectionBufferSize(Integer.parseInt(System.getProperty("qpid.write.buffer.limit", DEFAULT_WRITE_BUFFER)));
+
+ writefilter.attach(chain);
+ }
+
+ public void messageSent(IoSession session, Object message) throws Exception
+ {
+ _maximumWriteQueueLength = Math.max(session.getScheduledWriteRequests(), _maximumWriteQueueLength);
+
+ if (_logger.isDebugEnabled())
+ {
+ ++_sentCount;
+ if (_sentCount % 1000 == 0)
+ {
+ _logger.debug("Sent count " + _sentCount + ":WQueue" + session.getScheduledWriteRequests());
+
+ }
+ }
+ }
+
+ public void messageReceived(IoSession session, Object message) throws Exception
+ {
+ if (_logger.isDebugEnabled())
+ {
+ ++_receivedCount;
+
+ if (_receivedCount % 1000 == 0)
+ {
+ _logger.debug("Receieved count " + _receivedCount);
+ }
+ }
+
+ ByteBuffer result = (ByteBuffer) message;
+ _totalBytesReceived += result.remaining();
+ int size = result.remaining();
+ long now = System.currentTimeMillis();
+ if (_partialBytesRead > 0)
+ {
+ int offset = _chunkSize - _partialBytesRead;
+ if (size >= offset)
+ {
+ _chunkTimes[_chunksReceived++] = now;
+ result.position(offset);
+ }
+ else
+ {
+ // have not read even one chunk, including the previous partial bytes
+ _partialBytesRead += size;
+ return;
+ }
+ }
+
+
+ int chunkCount = result.remaining() / _chunkSize;
+
+ for (int i = 0; i < chunkCount; i++)
+ {
+ _chunkTimes[_chunksReceived++] = now;
+ byte check = result.get();
+ _logger.debug("Check number " + check + " read");
+ if (check != (byte) ((_chunksReceived - 1) % 128))
+ {
+ _logger.error("Check number " + check + " read when expected " + (_chunksReceived % 128));
+ }
+ _logger.debug("Chunk times recorded");
+
+ try
+ {
+ result.skip(_chunkSize - 1);
+ }
+ catch (IllegalArgumentException e)
+ {
+ _logger.error("Position was: " + result.position());
+ _logger.error("Tried to skip to: " + (_chunkSize * i));
+ _logger.error("limit was; " + result.limit());
+ }
+ }
+ _logger.debug("Chunks received now " + _chunksReceived);
+ _logger.debug("Bytes received: " + _totalBytesReceived);
+ _partialBytesRead = result.remaining();
+
+ if (_partialBytesRead > 0)
+ {
+ _partialCheckNumber = result.get();
+ }
+
+
+ if (_chunksReceived >= _chunkCount)
+ {
+ _notifier.countDown();
+ }
+
+ }
+
+ public void exceptionCaught(IoSession session, Throwable cause) throws Exception
+ {
+ _logger.error("Error: " + cause, cause);
+ }
+ }
+
+ public void startWriter() throws IOException, InterruptedException
+ {
+
+ _maximumWriteQueueLength = 0;
+
+ IoConnector ioConnector = null;
+
+ if (Boolean.getBoolean("multinio"))
+ {
+ _logger.warn("Using MultiThread NIO");
+ ioConnector = new org.apache.mina.transport.socket.nio.MultiThreadSocketConnector();
+ }
+ else
+ {
+ _logger.warn("Using MINA NIO");
+ ioConnector = new org.apache.mina.transport.socket.nio.SocketConnector();
+ }
+
+ SocketSessionConfig scfg = (SocketSessionConfig) ioConnector.getDefaultConfig().getSessionConfig();
+ scfg.setTcpNoDelay(true);
+ scfg.setSendBufferSize(32768);
+ scfg.setReceiveBufferSize(32768);
+
+ ByteBuffer.setAllocator(new SimpleByteBufferAllocator());
+
+
+ final InetSocketAddress address = new InetSocketAddress("localhost", _PORT);
+ _logger.info("Attempting connection to " + address);
+
+ //Old mina style
+// ioConnector.setHandler(new WriterHandler());
+// ConnectFuture future = ioConnector.connect(address);
+ ConnectFuture future = ioConnector.connect(address, new WriterHandler());
+ // wait for connection to complete
+ future.join();
+ _logger.info("Connection completed");
+ // we call getSession which throws an IOException if there has been an error connecting
+ _session = future.getSession();
+
+ _chunkTimes = new long[_chunkCount];
+ Thread t = new Thread(this);
+ t.start();
+ t.join();
+ _logger.info("Test Complete");
+ }
+
+
+ public void test1k() throws IOException, InterruptedException
+ {
+ _logger.info("Starting 1k test");
+ _chunkSize = 1024;
+ startWriter();
+ }
+
+
+ public void test2k() throws IOException, InterruptedException
+ {
+ _logger.info("Starting 2k test");
+ _chunkSize = 2048;
+ startWriter();
+ }
+
+
+ public void test4k() throws IOException, InterruptedException
+ {
+ _logger.info("Starting 4k test");
+ _chunkSize = 4096;
+ startWriter();
+ }
+
+
+ public void test8k() throws IOException, InterruptedException
+ {
+ _logger.info("Starting 8k test");
+ _chunkSize = 8192;
+ startWriter();
+ }
+
+
+ public void test16k() throws IOException, InterruptedException
+ {
+ _logger.info("Starting 16k test");
+ _chunkSize = 16384;
+ startWriter();
+ }
+
+
+ public void test32k() throws IOException, InterruptedException
+ {
+ _logger.info("Starting 32k test");
+ _chunkSize = 32768;
+ startWriter();
+ }
+
+
+ public static int getIntArg(String[] args, int index, int defaultValue)
+ {
+ if (args.length > index)
+ {
+ try
+ {
+ return Integer.parseInt(args[index]);
+ }
+ catch (NumberFormatException e)
+ {
+ //Do nothing
+ }
+ }
+ return defaultValue;
+ }
+
+ public static void main(String[] args) throws IOException, InterruptedException
+ {
+ _PORT = getIntArg(args, 0, _PORT);
+
+ int test = getIntArg(args, 1, DEFAULT_TEST_SIZE);
+
+ IOWriterClient w = new IOWriterClient();
+ w._chunkCount = getIntArg(args, 2, w._chunkCount);
+ switch (test)
+ {
+ case 0:
+ w.test1k();
+ w.test2k();
+ w.test4k();
+ w.test8k();
+ w.test16k();
+ w.test32k();
+ break;
+ case 1:
+ w.test1k();
+ break;
+ case 2:
+ w.test2k();
+ break;
+ case 4:
+ w.test4k();
+ break;
+ case 8:
+ w.test8k();
+ break;
+ case 16:
+ w.test16k();
+ break;
+ case 32:
+ w.test32k();
+ break;
+ }
+ }
+}
diff --git a/qpid/java/common/src/test/java/org/apache/mina/SocketIOTest/IOWriterServer.java b/qpid/java/common/src/test/java/org/apache/mina/SocketIOTest/IOWriterServer.java
new file mode 100644
index 0000000000..423e98c67b
--- /dev/null
+++ b/qpid/java/common/src/test/java/org/apache/mina/SocketIOTest/IOWriterServer.java
@@ -0,0 +1,157 @@
+/*
+ *
+ * Copyright (c) 2006 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.mina.SocketIOTest;
+
+import org.apache.mina.common.ByteBuffer;
+import org.apache.mina.common.IoAcceptor;
+import org.apache.mina.common.IoFilterChain;
+import org.apache.mina.common.IoHandlerAdapter;
+import org.apache.mina.common.IoSession;
+import org.apache.mina.common.SimpleByteBufferAllocator;
+import org.apache.mina.filter.ReadThrottleFilterBuilder;
+import org.apache.mina.filter.WriteBufferLimitFilterBuilder;
+import org.apache.mina.transport.socket.nio.SocketSessionConfig;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.IOException;
+import java.net.InetSocketAddress;
+
+/** Tests MINA socket performance. This acceptor simply reads data from the network and writes it back again. */
+public class IOWriterServer
+{
+ private static final Logger _logger = LoggerFactory.getLogger(IOWriterServer.class);
+
+ static public int _PORT = 9999;
+
+ private static final String DEFAULT_READ_BUFFER = "262144";
+ private static final String DEFAULT_WRITE_BUFFER = "262144";
+
+
+ private static class TestHandler extends IoHandlerAdapter
+ {
+ private int _sentCount = 0;
+
+ private int _bytesSent = 0;
+
+ private int _receivedCount = 0;
+
+ public void sessionCreated(IoSession ioSession) throws java.lang.Exception
+ {
+ IoFilterChain chain = ioSession.getFilterChain();
+
+ ReadThrottleFilterBuilder readfilter = new ReadThrottleFilterBuilder();
+ readfilter.setMaximumConnectionBufferSize(Integer.parseInt(System.getProperty("qpid.read.buffer.limit", DEFAULT_READ_BUFFER)));
+ readfilter.attach(chain);
+
+ WriteBufferLimitFilterBuilder writefilter = new WriteBufferLimitFilterBuilder();
+
+ writefilter.setMaximumConnectionBufferSize(Integer.parseInt(System.getProperty("qpid.write.buffer.limit", DEFAULT_WRITE_BUFFER)));
+
+ writefilter.attach(chain);
+
+ }
+
+ public void messageReceived(IoSession session, Object message) throws Exception
+ {
+ ((ByteBuffer) message).acquire();
+ session.write(message);
+
+ if (_logger.isDebugEnabled())
+ {
+ _bytesSent += ((ByteBuffer) message).remaining();
+
+ _sentCount++;
+
+ if (_sentCount % 1000 == 0)
+ {
+ _logger.debug("Bytes sent: " + _bytesSent);
+ }
+ }
+ }
+
+ public void messageSent(IoSession session, Object message) throws Exception
+ {
+ if (_logger.isDebugEnabled())
+ {
+ ++_receivedCount;
+
+ if (_receivedCount % 1000 == 0)
+ {
+ _logger.debug("Receieved count " + _receivedCount);
+ }
+ }
+ }
+
+ public void exceptionCaught(IoSession session, Throwable cause) throws Exception
+ {
+ _logger.error("Error: " + cause, cause);
+ }
+ }
+
+ public void startAcceptor() throws IOException
+ {
+ IoAcceptor acceptor;
+ if (Boolean.getBoolean("multinio"))
+ {
+ _logger.warn("Using MultiThread NIO");
+ acceptor = new org.apache.mina.transport.socket.nio.MultiThreadSocketAcceptor();
+ }
+ else
+ {
+ _logger.warn("Using MINA NIO");
+ acceptor = new org.apache.mina.transport.socket.nio.SocketAcceptor();
+ }
+
+
+ SocketSessionConfig sc = (SocketSessionConfig) acceptor.getDefaultConfig().getSessionConfig();
+ sc.setTcpNoDelay(true);
+ sc.setSendBufferSize(32768);
+ sc.setReceiveBufferSize(32768);
+
+ ByteBuffer.setAllocator(new SimpleByteBufferAllocator());
+
+ //The old mina style
+// acceptor.setLocalAddress(new InetSocketAddress(_PORT));
+// acceptor.setHandler(new TestHandler());
+// acceptor.bind();
+ acceptor.bind(new InetSocketAddress(_PORT), new TestHandler());
+
+ _logger.info("Bound on port " + _PORT + ":" + _logger.isDebugEnabled());
+ _logger.debug("debug on");
+ }
+
+ public static void main(String[] args) throws IOException
+ {
+
+ if (args.length > 0)
+ {
+ try
+ {
+ _PORT = Integer.parseInt(args[0]);
+ }
+ catch (NumberFormatException e)
+ {
+ //IGNORE so use default port 9999;
+ }
+ }
+
+ IOWriterServer a = new IOWriterServer();
+ a.startAcceptor();
+ }
+}
diff --git a/qpid/java/common/src/test/java/org/apache/qpid/AMQExceptionTest.java b/qpid/java/common/src/test/java/org/apache/qpid/AMQExceptionTest.java
index f65427e583..ef6cd41492 100644
--- a/qpid/java/common/src/test/java/org/apache/qpid/AMQExceptionTest.java
+++ b/qpid/java/common/src/test/java/org/apache/qpid/AMQExceptionTest.java
@@ -23,7 +23,6 @@ package org.apache.qpid;
import junit.framework.TestCase;
import org.apache.qpid.protocol.AMQConstant;
import org.apache.qpid.framing.AMQFrameDecodingException;
-import org.apache.qpid.framing.AMQShortString;
/**
* This test is to ensure that when an AMQException is rethrown that the specified exception is correctly wrapped up.
@@ -92,18 +91,6 @@ public class AMQExceptionTest extends TestCase
return amqe;
}
- public void testGetMessageAsString()
- {
- StringBuilder sb = new StringBuilder();
- for (int i = 0; i < 25; i++)
- {
- sb.append("message [" + i + "]");
- }
- AMQException e = new AMQException(AMQConstant.INTERNAL_ERROR, sb.toString(), null);
- AMQShortString message = e.getMessageAsShortString();
- assertEquals(sb.substring(0, AMQShortString.MAX_LENGTH - 3) + "...", message.toString());
- }
-
/**
* Private class that extends AMQException but does not have a default exception.
*/
diff --git a/qpid/java/common/src/test/java/org/apache/qpid/framing/AMQShortStringTest.java b/qpid/java/common/src/test/java/org/apache/qpid/framing/AMQShortStringTest.java
index 9a805d87b3..92e7ce0a80 100644
--- a/qpid/java/common/src/test/java/org/apache/qpid/framing/AMQShortStringTest.java
+++ b/qpid/java/common/src/test/java/org/apache/qpid/framing/AMQShortStringTest.java
@@ -20,10 +20,6 @@
package org.apache.qpid.framing;
-import java.io.UnsupportedEncodingException;
-import java.util.ArrayList;
-import java.util.List;
-
import junit.framework.TestCase;
public class AMQShortStringTest extends TestCase
{
@@ -109,215 +105,5 @@ public class AMQShortStringTest extends TestCase
assertFalse(new AMQShortString("A").equals(new AMQShortString("a")));
}
- /**
- * Test method for
- * {@link org.apache.qpid.framing.AMQShortString#AMQShortString(byte[])}.
- */
- public void testCreateAMQShortStringByteArray()
- {
- byte[] bytes = null;
- try
- {
- bytes = "test".getBytes("UTF-8");
- }
- catch (UnsupportedEncodingException e)
- {
- fail("UTF-8 encoding is not supported anymore by JVM:" + e.getMessage());
- }
- AMQShortString string = new AMQShortString(bytes);
- assertEquals("constructed amq short string length differs from expected", 4, string.length());
- assertTrue("constructed amq short string differs from expected", string.equals("test"));
- }
-
- /**
- * Test method for
- * {@link org.apache.qpid.framing.AMQShortString#AMQShortString(java.lang.String)}
- * <p>
- * Tests short string construction from string with length less than 255.
- */
- public void testCreateAMQShortStringString()
- {
- AMQShortString string = new AMQShortString("test");
- assertEquals("constructed amq short string length differs from expected", 4, string.length());
- assertTrue("constructed amq short string differs from expected", string.equals("test"));
- }
-
- /**
- * Test method for
- * {@link org.apache.qpid.framing.AMQShortString#AMQShortString(char[])}.
- * <p>
- * Tests short string construction from char array with length less than 255.
- */
- public void testCreateAMQShortStringCharArray()
- {
- char[] chars = "test".toCharArray();
- AMQShortString string = new AMQShortString(chars);
- assertEquals("constructed amq short string length differs from expected", 4, string.length());
- assertTrue("constructed amq short string differs from expected", string.equals("test"));
- }
-
- /**
- * Test method for
- * {@link org.apache.qpid.framing.AMQShortString#AMQShortString(java.lang.CharSequence)}
- * <p>
- * Tests short string construction from char sequence with length less than 255.
- */
- public void testCreateAMQShortStringCharSequence()
- {
- AMQShortString string = new AMQShortString((CharSequence) "test");
- assertEquals("constructed amq short string length differs from expected", 4, string.length());
- assertTrue("constructed amq short string differs from expected", string.equals("test"));
- }
-
- /**
- * Test method for
- * {@link org.apache.qpid.framing.AMQShortString#AMQShortString(byte[])}.
- * <p>
- * Tests an attempt to create an AMQP short string from byte array with length over 255.
- */
- public void testCreateAMQShortStringByteArrayOver255()
- {
- String test = buildString('a', 256);
- byte[] bytes = null;
- try
- {
- bytes = test.getBytes("UTF-8");
- }
- catch (UnsupportedEncodingException e)
- {
- fail("UTF-8 encoding is not supported anymore by JVM:" + e.getMessage());
- }
- try
- {
- new AMQShortString(bytes);
- fail("It should not be possible to create AMQShortString with length over 255");
- }
- catch (IllegalArgumentException e)
- {
- assertEquals("Exception message differs from expected",
- "Cannot create AMQShortString with number of octets over 255!", e.getMessage());
- }
- }
-
- /**
- * Test method for
- * {@link org.apache.qpid.framing.AMQShortString#AMQShortString(java.lang.String)}
- * <p>
- * Tests an attempt to create an AMQP short string from string with length over 255
- */
- public void testCreateAMQShortStringStringOver255()
- {
- String test = buildString('a', 256);
- try
- {
- new AMQShortString(test);
- fail("It should not be possible to create AMQShortString with length over 255");
- }
- catch (IllegalArgumentException e)
- {
- assertEquals("Exception message differs from expected",
- "Cannot create AMQShortString with number of octets over 255!", e.getMessage());
- }
- }
-
- /**
- * Test method for
- * {@link org.apache.qpid.framing.AMQShortString#AMQShortString(char[])}.
- * <p>
- * Tests an attempt to create an AMQP short string from char array with length over 255.
- */
- public void testCreateAMQShortStringCharArrayOver255()
- {
- String test = buildString('a', 256);
- char[] chars = test.toCharArray();
- try
- {
- new AMQShortString(chars);
- fail("It should not be possible to create AMQShortString with length over 255");
- }
- catch (IllegalArgumentException e)
- {
- assertEquals("Exception message differs from expected",
- "Cannot create AMQShortString with number of octets over 255!", e.getMessage());
- }
- }
-
- /**
- * Test method for
- * {@link org.apache.qpid.framing.AMQShortString#AMQShortString(java.lang.CharSequence)}
- * <p>
- * Tests an attempt to create an AMQP short string from char sequence with length over 255.
- */
- public void testCreateAMQShortStringCharSequenceOver255()
- {
- String test = buildString('a', 256);
- try
- {
- new AMQShortString((CharSequence) test);
- fail("It should not be possible to create AMQShortString with length over 255");
- }
- catch (IllegalArgumentException e)
- {
- assertEquals("Exception message differs from expected",
- "Cannot create AMQShortString with number of octets over 255!", e.getMessage());
- }
- }
-
- /**
- * Tests joining of short strings into a short string with length over 255.
- */
- public void testJoinOverflow()
- {
- List<AMQShortString> data = new ArrayList<AMQShortString>();
- for (int i = 0; i < 25; i++)
- {
- data.add(new AMQShortString("test data!"));
- }
- try
- {
- AMQShortString.join(data, new AMQShortString(" "));
- fail("It should not be possible to create AMQShortString with length over 255");
- }
- catch (IllegalArgumentException e)
- {
- assertEquals("Exception message differs from expected",
- "Cannot create AMQShortString with number of octets over 255!", e.getMessage());
- }
- }
-
- /**
- * Tests joining of short strings into a short string with length less than 255.
- */
- public void testJoin()
- {
- StringBuilder expected = new StringBuilder();
- List<AMQShortString> data = new ArrayList<AMQShortString>();
- data.add(new AMQShortString("test data 1"));
- expected.append("test data 1");
- data.add(new AMQShortString("test data 2"));
- expected.append(" test data 2");
- AMQShortString result = AMQShortString.join(data, new AMQShortString(" "));
- assertEquals("join result differs from expected", expected.toString(), result.asString());
- }
-
- /**
- * A helper method to generate a string with given length containing given
- * character
- *
- * @param ch
- * char to build string with
- * @param length
- * target string length
- * @return string
- */
- private String buildString(char ch, int length)
- {
- StringBuilder sb = new StringBuilder();
- for (int i = 0; i < length; i++)
- {
- sb.append(ch);
- }
- return sb.toString();
- }
}
diff --git a/qpid/java/common/src/test/java/org/apache/qpid/test/utils/QpidTestCase.java b/qpid/java/common/src/test/java/org/apache/qpid/test/utils/QpidTestCase.java
index 89542e8125..8b470d555e 100644
--- a/qpid/java/common/src/test/java/org/apache/qpid/test/utils/QpidTestCase.java
+++ b/qpid/java/common/src/test/java/org/apache/qpid/test/utils/QpidTestCase.java
@@ -25,22 +25,17 @@ import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
-import java.util.HashMap;
import java.util.List;
-import java.util.Map;
import junit.framework.TestCase;
import junit.framework.TestResult;
import org.apache.log4j.Logger;
-import org.apache.mina.util.AvailablePortFinder;
public class QpidTestCase extends TestCase
{
protected static final Logger _logger = Logger.getLogger(QpidTestCase.class);
- private final Map<String, String> _propertiesSetForTest = new HashMap<String, String>();
-
/**
* Some tests are excluded when the property test.excludes is set to true.
* An exclusion list is either a file (prop test.excludesfile) which contains one test name
@@ -132,54 +127,4 @@ public class QpidTestCase extends TestCase
return storeClass != null ? storeClass : MEMORY_STORE_CLASS_NAME ;
}
-
- public int findFreePort()
- {
- return AvailablePortFinder.getNextAvailable(10000);
- }
-
- /**
- * Set a System property for duration of this test only. The tearDown will
- * guarantee to reset the property to its previous value after the test
- * completes.
- *
- * @param property The property to set
- * @param value the value to set it to.
- */
- protected void setTestSystemProperty(String property, String value)
- {
- if (!_propertiesSetForTest.containsKey(property))
- {
- // Record the current value so we can revert it later.
- _propertiesSetForTest.put(property, System.getProperty(property));
- }
-
- System.setProperty(property, value);
- }
-
- /**
- * Restore the System property values that were set by this test run.
- */
- protected void revertTestSystemProperties()
- {
- for (String key : _propertiesSetForTest.keySet())
- {
- String value = _propertiesSetForTest.get(key);
- if (value != null)
- {
- System.setProperty(key, value);
- }
- else
- {
- System.clearProperty(key);
- }
- }
-
- _propertiesSetForTest.clear();
- }
-
- protected void tearDown() throws java.lang.Exception
- {
- revertTestSystemProperties();
- }
}
diff --git a/qpid/java/common/src/test/java/org/apache/qpid/transport/MockSender.java b/qpid/java/common/src/test/java/org/apache/qpid/transport/MockSender.java
deleted file mode 100644
index 4b38b7318a..0000000000
--- a/qpid/java/common/src/test/java/org/apache/qpid/transport/MockSender.java
+++ /dev/null
@@ -1,47 +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.transport;
-
-import java.nio.ByteBuffer;
-
-public class MockSender implements Sender<ByteBuffer>
-{
-
- public void setIdleTimeout(int i)
- {
-
- }
-
- public void send(ByteBuffer msg)
- {
-
- }
-
- public void flush()
- {
-
- }
-
- public void close()
- {
-
- }
-}
diff --git a/qpid/java/common/src/test/java/org/apache/qpid/transport/TestNetworkConnection.java b/qpid/java/common/src/test/java/org/apache/qpid/transport/TestNetworkConnection.java
deleted file mode 100644
index 8686c17414..0000000000
--- a/qpid/java/common/src/test/java/org/apache/qpid/transport/TestNetworkConnection.java
+++ /dev/null
@@ -1,138 +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.transport;
-
-import java.net.BindException;
-import java.net.InetAddress;
-import java.net.InetSocketAddress;
-import java.net.SocketAddress;
-import java.nio.ByteBuffer;
-
-import org.apache.qpid.protocol.ProtocolEngine;
-import org.apache.qpid.protocol.ProtocolEngineFactory;
-import org.apache.qpid.ssl.SSLContextFactory;
-import org.apache.qpid.transport.network.NetworkConnection;
-
-/**
- * Test implementation of IoSession, which is required for some tests. Methods not being used are not implemented,
- * so if this class is being used and some methods are to be used, then please update those.
- */
-public class TestNetworkConnection implements NetworkConnection
-{
- private String _remoteHost = "127.0.0.1";
- private String _localHost = "127.0.0.1";
- private int _port = 1;
- private SocketAddress _localAddress = null;
- private SocketAddress _remoteAddress = null;
- private final MockSender _sender;
-
- public TestNetworkConnection()
- {
- _sender = new MockSender();
- }
-
- public void bind(int port, InetAddress[] addresses, ProtocolEngineFactory protocolFactory,
- NetworkTransportConfiguration config, SSLContextFactory sslFactory) throws BindException
- {
-
- }
-
- public SocketAddress getLocalAddress()
- {
- return (_localAddress != null) ? _localAddress : new InetSocketAddress(_localHost, _port);
- }
-
- public SocketAddress getRemoteAddress()
- {
- return (_remoteAddress != null) ? _remoteAddress : new InetSocketAddress(_remoteHost, _port);
- }
-
- public void open(int port, InetAddress destination, ProtocolEngine engine, NetworkTransportConfiguration config,
- SSLContextFactory sslFactory) throws OpenException
- {
-
- }
-
- public void setMaxReadIdle(int idleTime)
- {
-
- }
-
- public void setMaxWriteIdle(int idleTime)
- {
-
- }
-
- public void close()
- {
-
- }
-
- public void flush()
- {
-
- }
-
- public void send(ByteBuffer msg)
- {
-
- }
-
- public void setIdleTimeout(int i)
- {
-
- }
-
- public void setPort(int port)
- {
- _port = port;
- }
-
- public int getPort()
- {
- return _port;
- }
-
- public void setLocalHost(String host)
- {
- _localHost = host;
- }
-
- public void setRemoteHost(String host)
- {
- _remoteHost = host;
- }
-
- public void setLocalAddress(SocketAddress address)
- {
- _localAddress = address;
- }
-
- public void setRemoteAddress(SocketAddress address)
- {
- _remoteAddress = address;
- }
-
- public Sender<ByteBuffer> getSender()
- {
- return _sender;
- }
-}
diff --git a/qpid/java/common/src/test/java/org/apache/qpid/transport/TestNetworkDriver.java b/qpid/java/common/src/test/java/org/apache/qpid/transport/TestNetworkDriver.java
new file mode 100644
index 0000000000..957a7190ee
--- /dev/null
+++ b/qpid/java/common/src/test/java/org/apache/qpid/transport/TestNetworkDriver.java
@@ -0,0 +1,133 @@
+/*
+ *
+ * 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;
+
+import java.net.BindException;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.SocketAddress;
+import java.nio.ByteBuffer;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+import org.apache.qpid.protocol.ProtocolEngine;
+import org.apache.qpid.protocol.ProtocolEngineFactory;
+import org.apache.qpid.ssl.SSLContextFactory;
+
+/**
+ * Test implementation of IoSession, which is required for some tests. Methods not being used are not implemented,
+ * so if this class is being used and some methods are to be used, then please update those.
+ */
+public class TestNetworkDriver implements NetworkDriver
+{
+ private final ConcurrentMap attributes = new ConcurrentHashMap();
+ private String _remoteHost = "127.0.0.1";
+ private String _localHost = "127.0.0.1";
+ private int _port = 1;
+ private SocketAddress _localAddress = null;
+ private SocketAddress _remoteAddress = null;
+
+ public TestNetworkDriver()
+ {
+ }
+
+ public void bind(int port, InetAddress[] addresses, ProtocolEngineFactory protocolFactory,
+ NetworkDriverConfiguration config, SSLContextFactory sslFactory) throws BindException
+ {
+
+ }
+
+ public SocketAddress getLocalAddress()
+ {
+ return (_localAddress != null) ? _localAddress : new InetSocketAddress(_localHost, _port);
+ }
+
+ public SocketAddress getRemoteAddress()
+ {
+ return (_remoteAddress != null) ? _remoteAddress : new InetSocketAddress(_remoteHost, _port);
+ }
+
+ public void open(int port, InetAddress destination, ProtocolEngine engine, NetworkDriverConfiguration config,
+ SSLContextFactory sslFactory) throws OpenException
+ {
+
+ }
+
+ public void setMaxReadIdle(int idleTime)
+ {
+
+ }
+
+ public void setMaxWriteIdle(int idleTime)
+ {
+
+ }
+
+ public void close()
+ {
+
+ }
+
+ public void flush()
+ {
+
+ }
+
+ public void send(ByteBuffer msg)
+ {
+
+ }
+
+ public void setIdleTimeout(int i)
+ {
+
+ }
+
+ public void setPort(int port)
+ {
+ _port = port;
+ }
+
+ public int getPort()
+ {
+ return _port;
+ }
+
+ public void setLocalHost(String host)
+ {
+ _localHost = host;
+ }
+
+ public void setRemoteHost(String host)
+ {
+ _remoteHost = host;
+ }
+
+ public void setLocalAddress(SocketAddress address)
+ {
+ _localAddress = address;
+ }
+
+ public void setRemoteAddress(SocketAddress address)
+ {
+ _remoteAddress = address;
+ }
+}
diff --git a/qpid/java/common/src/test/java/org/apache/qpid/transport/network/TransportTest.java b/qpid/java/common/src/test/java/org/apache/qpid/transport/network/TransportTest.java
deleted file mode 100644
index 4e504c69eb..0000000000
--- a/qpid/java/common/src/test/java/org/apache/qpid/transport/network/TransportTest.java
+++ /dev/null
@@ -1,157 +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.transport.network;
-
-
-import java.nio.ByteBuffer;
-
-import org.apache.qpid.framing.ProtocolVersion;
-import org.apache.qpid.protocol.ProtocolEngineFactory;
-import org.apache.qpid.ssl.SSLContextFactory;
-import org.apache.qpid.test.utils.QpidTestCase;
-import org.apache.qpid.transport.ConnectionSettings;
-import org.apache.qpid.transport.NetworkTransportConfiguration;
-import org.apache.qpid.transport.Receiver;
-import org.apache.qpid.transport.TransportException;
-import org.apache.qpid.transport.network.io.IoNetworkTransport;
-import org.apache.qpid.transport.network.mina.MinaNetworkTransport;
-
-public class TransportTest extends QpidTestCase
-{
-
-
-
- public void testDefaultGetOutgoingTransportForv0_8() throws Exception
- {
- final OutgoingNetworkTransport networkTransport = Transport.getOutgoingTransportInstance(ProtocolVersion.v8_0);
- assertNotNull(networkTransport);
- assertTrue(networkTransport instanceof MinaNetworkTransport);
- }
-
- public void testGloballyOverriddenOutgoingTransportForv0_8() throws Exception
- {
- setTestSystemProperty(Transport.QPID_TRANSPORT_PROPNAME, TestOutgoingNetworkTransport.class.getName());
-
- final OutgoingNetworkTransport networkTransport = Transport.getOutgoingTransportInstance(ProtocolVersion.v8_0);
- assertNotNull(networkTransport);
- assertTrue(networkTransport instanceof TestOutgoingNetworkTransport);
- }
-
- public void testProtocolSpecificOverriddenOutgoingTransportForv0_8() throws Exception
- {
- setTestSystemProperty(Transport.QPID_TRANSPORT_V0_8_PROPNAME, TestOutgoingNetworkTransport.class.getName());
-
- final OutgoingNetworkTransport networkTransport = Transport.getOutgoingTransportInstance(ProtocolVersion.v8_0);
- assertNotNull(networkTransport);
- assertTrue(networkTransport instanceof TestOutgoingNetworkTransport);
- }
-
- public void testDefaultGetOutgoingTransportForv0_10() throws Exception
- {
- final OutgoingNetworkTransport networkTransport = Transport.getOutgoingTransportInstance(ProtocolVersion.v0_10);
- assertNotNull(networkTransport);
- assertTrue(networkTransport instanceof IoNetworkTransport);
- }
-
- public void testDefaultGetIncomingTransport() throws Exception
- {
- final IncomingNetworkTransport networkTransport = Transport.getIncomingTransportInstance();
- assertNotNull(networkTransport);
- assertTrue(networkTransport instanceof MinaNetworkTransport);
- }
-
- public void testOverriddenGetIncomingTransport() throws Exception
- {
- setTestSystemProperty(Transport.QPID_BROKER_TRANSPORT_PROPNAME, TestIncomingNetworkTransport.class.getName());
-
- final IncomingNetworkTransport networkTransport = Transport.getIncomingTransportInstance();
- assertNotNull(networkTransport);
- assertTrue(networkTransport instanceof TestIncomingNetworkTransport);
- }
-
- public void testInvalidOutgoingTransportClassName() throws Exception
- {
- setTestSystemProperty(Transport.QPID_TRANSPORT_PROPNAME, "invalid");
-
- try
- {
- Transport.getOutgoingTransportInstance(ProtocolVersion.v0_10);
- fail("Should have failed to load the invalid class");
- }
- catch(TransportException te)
- {
- //expected, ignore
- }
- }
-
- public void testInvalidOutgoingTransportProtocolVersion() throws Exception
- {
- try
- {
- Transport.getOutgoingTransportInstance(new ProtocolVersion((byte)0, (byte)0));
- fail("Should have failed to load the transport for invalid protocol version");
- }
- catch(IllegalArgumentException iae)
- {
- //expected, ignore
- }
- }
-
- public static class TestOutgoingNetworkTransport implements OutgoingNetworkTransport
- {
-
- public void close()
- {
- throw new UnsupportedOperationException();
- }
-
- public NetworkConnection getConnection()
- {
- throw new UnsupportedOperationException();
- }
-
- public NetworkConnection connect(ConnectionSettings settings,
- Receiver<ByteBuffer> delegate, SSLContextFactory sslFactory)
- {
- throw new UnsupportedOperationException();
- }
- }
-
- public static class TestIncomingNetworkTransport implements IncomingNetworkTransport
- {
-
- public void close()
- {
- throw new UnsupportedOperationException();
- }
-
- public NetworkConnection getConnection()
- {
- throw new UnsupportedOperationException();
- }
-
- public void accept(NetworkTransportConfiguration config,
- ProtocolEngineFactory factory, SSLContextFactory sslFactory)
- {
- throw new UnsupportedOperationException();
- }
- }
-}
diff --git a/qpid/java/common/src/test/java/org/apache/qpid/transport/network/io/IoTransport.java b/qpid/java/common/src/test/java/org/apache/qpid/transport/network/io/IoTransport.java
deleted file mode 100644
index 796a845593..0000000000
--- a/qpid/java/common/src/test/java/org/apache/qpid/transport/network/io/IoTransport.java
+++ /dev/null
@@ -1,165 +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.transport.network.io;
-
-import java.net.Socket;
-import java.nio.ByteBuffer;
-
-import javax.net.ssl.SSLContext;
-import javax.net.ssl.SSLEngine;
-
-import org.apache.qpid.ssl.SSLContextFactory;
-import org.apache.qpid.transport.Binding;
-import org.apache.qpid.transport.Sender;
-import org.apache.qpid.transport.TransportException;
-import org.apache.qpid.transport.network.security.ssl.SSLReceiver;
-import org.apache.qpid.transport.network.security.ssl.SSLSender;
-import org.apache.qpid.transport.util.Logger;
-
-/**
- * This class provides a socket based transport using the java.io
- * classes.
- *
- * The following params are configurable via JVM arguments
- * TCP_NO_DELAY - amqj.tcpNoDelay
- * SO_RCVBUF - amqj.receiveBufferSize
- * SO_SNDBUF - amqj.sendBufferSize
- */
-public final class IoTransport<E>
-{
-
- static
- {
- org.apache.mina.common.ByteBuffer.setAllocator
- (new org.apache.mina.common.SimpleByteBufferAllocator());
- org.apache.mina.common.ByteBuffer.setUseDirectBuffers
- (Boolean.getBoolean("amqj.enableDirectBuffers"));
- }
-
- private static final Logger log = Logger.get(IoTransport.class);
-
- private static int DEFAULT_READ_WRITE_BUFFER_SIZE = 64 * 1024;
- private static int readBufferSize = Integer.getInteger
- ("amqj.receiveBufferSize", DEFAULT_READ_WRITE_BUFFER_SIZE);
- private static int writeBufferSize = Integer.getInteger
- ("amqj.sendBufferSize", DEFAULT_READ_WRITE_BUFFER_SIZE);
-
- private Socket socket;
- private Sender<ByteBuffer> sender;
- private E endpoint;
- private IoReceiver receiver;
- private long timeout = 60000;
-
- IoTransport(Socket socket, Binding<E,ByteBuffer> binding, boolean ssl)
- {
- this.socket = socket;
-
- if (ssl)
- {
- setupSSLTransport(socket, binding);
- }
- else
- {
- setupTransport(socket, binding);
- }
- }
-
- private void setupTransport(Socket socket, Binding<E, ByteBuffer> binding)
- {
- IoSender ios = new IoSender(socket, 2*writeBufferSize, timeout);
- ios.initiate();
-
- this.sender = ios;
- this.endpoint = binding.endpoint(sender);
- this.receiver = new IoReceiver(socket, binding.receiver(endpoint),
- 2*readBufferSize, timeout);
- this.receiver.initiate();
-
- ios.registerCloseListener(this.receiver);
- }
-
- private void setupSSLTransport(Socket socket, Binding<E, ByteBuffer> binding)
- {
- SSLEngine engine = null;
- SSLContext sslCtx;
- try
- {
- sslCtx = createSSLContext();
- }
- catch (Exception e)
- {
- throw new TransportException("Error creating SSL Context", e);
- }
-
- try
- {
- engine = sslCtx.createSSLEngine();
- engine.setUseClientMode(true);
- }
- catch(Exception e)
- {
- throw new TransportException("Error creating SSL Engine", e);
- }
- IoSender ios = new IoSender(socket, 2*writeBufferSize, timeout);
- ios.initiate();
- this.sender = new SSLSender(engine,ios);
- this.endpoint = binding.endpoint(sender);
- this.receiver = new IoReceiver(socket, new SSLReceiver(engine,binding.receiver(endpoint),(SSLSender)sender),
- 2*readBufferSize, timeout);
- this.receiver.initiate();
- ios.registerCloseListener(this.receiver);
-
- log.info("SSL Sender and Receiver initiated");
- }
-
- public Sender<ByteBuffer> getSender()
- {
- return sender;
- }
-
- public IoReceiver getReceiver()
- {
- return receiver;
- }
-
- public Socket getSocket()
- {
- return socket;
- }
-
- private SSLContext createSSLContext() throws Exception
- {
- String trustStorePath = System.getProperty("javax.net.ssl.trustStore");
- String trustStorePassword = System.getProperty("javax.net.ssl.trustStorePassword");
- String trustStoreCertType = System.getProperty("qpid.ssl.trustStoreCertType","SunX509");
-
- String keyStorePath = System.getProperty("javax.net.ssl.keyStore",trustStorePath);
- String keyStorePassword = System.getProperty("javax.net.ssl.keyStorePassword",trustStorePassword);
- String keyStoreCertType = System.getProperty("qpid.ssl.keyStoreCertType","SunX509");
-
- SSLContextFactory sslContextFactory = new SSLContextFactory(trustStorePath,trustStorePassword,
- trustStoreCertType,keyStorePath,
- keyStorePassword,keyStoreCertType);
-
- return sslContextFactory.buildServerContext();
-
- }
-
-}
diff --git a/qpid/java/common/src/test/java/org/apache/qpid/transport/network/mina/MINANetworkDriverTest.java b/qpid/java/common/src/test/java/org/apache/qpid/transport/network/mina/MINANetworkDriverTest.java
new file mode 100644
index 0000000000..fc8e689ca4
--- /dev/null
+++ b/qpid/java/common/src/test/java/org/apache/qpid/transport/network/mina/MINANetworkDriverTest.java
@@ -0,0 +1,494 @@
+/*
+ *
+ * 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.network.mina;
+
+import java.net.BindException;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.SocketAddress;
+import java.net.UnknownHostException;
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+import junit.framework.TestCase;
+
+import org.apache.qpid.framing.AMQDataBlock;
+import org.apache.qpid.protocol.ProtocolEngine;
+import org.apache.qpid.protocol.ProtocolEngineFactory;
+import org.apache.qpid.transport.NetworkDriver;
+import org.apache.qpid.transport.OpenException;
+
+public class MINANetworkDriverTest extends TestCase
+{
+
+ private static final String TEST_DATA = "YHALOTHAR";
+ private static int TEST_PORT = 2323;
+ private NetworkDriver _server;
+ private NetworkDriver _client;
+ private CountingProtocolEngine _countingEngine; // Keeps a count of how many bytes it's read
+ private Exception _thrownEx;
+
+ @Override
+ public void setUp()
+ {
+ _server = new MINANetworkDriver();
+ _client = new MINANetworkDriver();
+ _thrownEx = null;
+ _countingEngine = new CountingProtocolEngine();
+ // increment the port to prevent tests clashing with each other when
+ // the port is in TIMED_WAIT state.
+ TEST_PORT++;
+ }
+
+ @Override
+ public void tearDown()
+ {
+ if (_server != null)
+ {
+ _server.close();
+ }
+
+ if (_client != null)
+ {
+ _client.close();
+ }
+ }
+
+ /**
+ * Tests that a socket can't be opened if a driver hasn't been bound
+ * to the port and can be opened if a driver has been bound.
+ * @throws BindException
+ * @throws UnknownHostException
+ * @throws OpenException
+ */
+ public void testBindOpen() throws BindException, UnknownHostException, OpenException
+ {
+ try
+ {
+ _client.open(TEST_PORT, InetAddress.getLocalHost(), _countingEngine, null, null);
+ }
+ catch (OpenException e)
+ {
+ _thrownEx = e;
+ }
+
+ assertNotNull("Open should have failed since no engine bound", _thrownEx);
+
+ _server.bind(TEST_PORT, null, new EchoProtocolEngineSingletonFactory(), null, null);
+
+ _client.open(TEST_PORT, InetAddress.getLocalHost(), _countingEngine, null, null);
+ }
+
+ /**
+ * Tests that a socket can't be opened after a bound NetworkDriver has been closed
+ * @throws BindException
+ * @throws UnknownHostException
+ * @throws OpenException
+ */
+ public void testBindOpenCloseOpen() throws BindException, UnknownHostException, OpenException
+ {
+ _server.bind(TEST_PORT, null, new EchoProtocolEngineSingletonFactory(), null, null);
+ _client.open(TEST_PORT, InetAddress.getLocalHost(), _countingEngine, null, null);
+ _client.close();
+ _server.close();
+
+ try
+ {
+ _client.open(TEST_PORT, InetAddress.getLocalHost(), _countingEngine, null, null);
+ }
+ catch (OpenException e)
+ {
+ _thrownEx = e;
+ }
+ assertNotNull("Open should have failed", _thrownEx);
+ }
+
+ /**
+ * Checks that the right exception is thrown when binding a NetworkDriver to an already
+ * existing socket.
+ */
+ public void testBindPortInUse()
+ {
+ try
+ {
+ _server.bind(TEST_PORT, null, new EchoProtocolEngineSingletonFactory(), null, null);
+ }
+ catch (BindException e)
+ {
+ fail("First bind should not fail");
+ }
+
+ try
+ {
+ _client.bind(TEST_PORT, null, new EchoProtocolEngineSingletonFactory(), null, null);
+ }
+ catch (BindException e)
+ {
+ _thrownEx = e;
+ }
+ assertNotNull("Second bind should throw BindException", _thrownEx);
+ }
+
+ /**
+ * tests that bytes sent on a network driver are received at the other end
+ *
+ * @throws UnknownHostException
+ * @throws OpenException
+ * @throws InterruptedException
+ * @throws BindException
+ */
+ public void testSend() throws UnknownHostException, OpenException, InterruptedException, BindException
+ {
+ // Open a connection from a counting engine to an echo engine
+ _server.bind(TEST_PORT, null, new EchoProtocolEngineSingletonFactory(), null, null);
+ _client.open(TEST_PORT, InetAddress.getLocalHost(), _countingEngine, null, null);
+
+ // Tell the counting engine how much data we're sending
+ _countingEngine.setNewLatch(TEST_DATA.getBytes().length);
+
+ // Send the data and wait for up to 2 seconds to get it back
+ _client.send(ByteBuffer.wrap(TEST_DATA.getBytes()));
+ _countingEngine.getLatch().await(2, TimeUnit.SECONDS);
+
+ // Check what we got
+ assertEquals("Wrong amount of data recieved", TEST_DATA.getBytes().length, _countingEngine.getReadBytes());
+ }
+
+ /**
+ * Opens a connection with a low read idle and check that it gets triggered
+ * @throws BindException
+ * @throws OpenException
+ * @throws UnknownHostException
+ *
+ */
+ public void testSetReadIdle() throws BindException, UnknownHostException, OpenException
+ {
+ // Open a connection from a counting engine to an echo engine
+ _server.bind(TEST_PORT, null, new EchoProtocolEngineSingletonFactory(), null, null);
+ _client.open(TEST_PORT, InetAddress.getLocalHost(), _countingEngine, null, null);
+ assertFalse("Reader should not have been idle", _countingEngine.getReaderHasBeenIdle());
+ _client.setMaxReadIdle(1);
+ sleepForAtLeast(1500);
+ assertTrue("Reader should have been idle", _countingEngine.getReaderHasBeenIdle());
+ }
+
+ /**
+ * Opens a connection with a low write idle and check that it gets triggered
+ * @throws BindException
+ * @throws OpenException
+ * @throws UnknownHostException
+ *
+ */
+ public void testSetWriteIdle() throws BindException, UnknownHostException, OpenException
+ {
+ // Open a connection from a counting engine to an echo engine
+ _server.bind(TEST_PORT, null, new EchoProtocolEngineSingletonFactory(), null, null);
+ _client.open(TEST_PORT, InetAddress.getLocalHost(), _countingEngine, null, null);
+ assertFalse("Reader should not have been idle", _countingEngine.getWriterHasBeenIdle());
+ _client.setMaxWriteIdle(1);
+ sleepForAtLeast(1500);
+ assertTrue("Reader should have been idle", _countingEngine.getWriterHasBeenIdle());
+ }
+
+
+ /**
+ * Creates and then closes a connection from client to server and checks that the server
+ * has its closed() method called. Then creates a new client and closes the server to check
+ * that the client has its closed() method called.
+ * @throws BindException
+ * @throws UnknownHostException
+ * @throws OpenException
+ */
+ public void testClosed() throws BindException, UnknownHostException, OpenException
+ {
+ // Open a connection from a counting engine to an echo engine
+ EchoProtocolEngineSingletonFactory factory = new EchoProtocolEngineSingletonFactory();
+ _server.bind(TEST_PORT, null, factory, null, null);
+ _client.open(TEST_PORT, InetAddress.getLocalHost(), _countingEngine, null, null);
+ EchoProtocolEngine serverEngine = null;
+ while (serverEngine == null)
+ {
+ serverEngine = factory.getEngine();
+ if (serverEngine == null)
+ {
+ try
+ {
+ Thread.sleep(10);
+ }
+ catch (InterruptedException e)
+ {
+ }
+ }
+ }
+ assertFalse("Server should not have been closed", serverEngine.getClosed());
+ serverEngine.setNewLatch(1);
+ _client.close();
+ try
+ {
+ serverEngine.getLatch().await(2, TimeUnit.SECONDS);
+ }
+ catch (InterruptedException e)
+ {
+ }
+ assertTrue("Server should have been closed", serverEngine.getClosed());
+
+ _client.open(TEST_PORT, InetAddress.getLocalHost(), _countingEngine, null, null);
+ _countingEngine.setClosed(false);
+ assertFalse("Client should not have been closed", _countingEngine.getClosed());
+ _countingEngine.setNewLatch(1);
+ _server.close();
+ try
+ {
+ _countingEngine.getLatch().await(2, TimeUnit.SECONDS);
+ }
+ catch (InterruptedException e)
+ {
+ }
+ assertTrue("Client should have been closed", _countingEngine.getClosed());
+ }
+
+ /**
+ * Create a connection and instruct the client to throw an exception when it gets some data
+ * and that the latch gets counted down.
+ * @throws BindException
+ * @throws UnknownHostException
+ * @throws OpenException
+ * @throws InterruptedException
+ */
+ public void testExceptionCaught() throws BindException, UnknownHostException, OpenException, InterruptedException
+ {
+ _server.bind(TEST_PORT, null, new EchoProtocolEngineSingletonFactory(), null, null);
+ _client.open(TEST_PORT, InetAddress.getLocalHost(), _countingEngine, null, null);
+
+
+ assertEquals("Exception should not have been thrown", 1,
+ _countingEngine.getExceptionLatch().getCount());
+ _countingEngine.setErrorOnNextRead(true);
+ _countingEngine.setNewLatch(TEST_DATA.getBytes().length);
+ _client.send(ByteBuffer.wrap(TEST_DATA.getBytes()));
+ _countingEngine.getExceptionLatch().await(2, TimeUnit.SECONDS);
+ assertEquals("Exception should have been thrown", 0,
+ _countingEngine.getExceptionLatch().getCount());
+ }
+
+ /**
+ * Opens a connection and checks that the remote address is the one that was asked for
+ * @throws BindException
+ * @throws UnknownHostException
+ * @throws OpenException
+ */
+ public void testGetRemoteAddress() throws BindException, UnknownHostException, OpenException
+ {
+ _server.bind(TEST_PORT, null, new EchoProtocolEngineSingletonFactory(), null, null);
+ _client.open(TEST_PORT, InetAddress.getLocalHost(), _countingEngine, null, null);
+ assertEquals(new InetSocketAddress(InetAddress.getLocalHost(), TEST_PORT),
+ _client.getRemoteAddress());
+ }
+
+ private class EchoProtocolEngineSingletonFactory implements ProtocolEngineFactory
+ {
+ EchoProtocolEngine _engine = null;
+
+ public ProtocolEngine newProtocolEngine(NetworkDriver driver)
+ {
+ if (_engine == null)
+ {
+ _engine = new EchoProtocolEngine();
+ _engine.setNetworkDriver(driver);
+ }
+ return getEngine();
+ }
+
+ public EchoProtocolEngine getEngine()
+ {
+ return _engine;
+ }
+ }
+
+ public class CountingProtocolEngine implements ProtocolEngine
+ {
+
+ protected NetworkDriver _driver;
+ public ArrayList<ByteBuffer> _receivedBytes = new ArrayList<ByteBuffer>();
+ private int _readBytes;
+ private CountDownLatch _latch = new CountDownLatch(0);
+ private boolean _readerHasBeenIdle;
+ private boolean _writerHasBeenIdle;
+ private boolean _closed = false;
+ private boolean _nextReadErrors = false;
+ private CountDownLatch _exceptionLatch = new CountDownLatch(1);
+
+ public void closed()
+ {
+ setClosed(true);
+ _latch.countDown();
+ }
+
+ public void setErrorOnNextRead(boolean b)
+ {
+ _nextReadErrors = b;
+ }
+
+ public void setNewLatch(int length)
+ {
+ _latch = new CountDownLatch(length);
+ }
+
+ public long getReadBytes()
+ {
+ return _readBytes;
+ }
+
+ public SocketAddress getRemoteAddress()
+ {
+ if (_driver != null)
+ {
+ return _driver.getRemoteAddress();
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ public SocketAddress getLocalAddress()
+ {
+ if (_driver != null)
+ {
+ return _driver.getLocalAddress();
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ public long getWrittenBytes()
+ {
+ return 0;
+ }
+
+ public void readerIdle()
+ {
+ _readerHasBeenIdle = true;
+ }
+
+ public void setNetworkDriver(NetworkDriver driver)
+ {
+ _driver = driver;
+ }
+
+ public void writeFrame(AMQDataBlock frame)
+ {
+
+ }
+
+ public void writerIdle()
+ {
+ _writerHasBeenIdle = true;
+ }
+
+ public void exception(Throwable t)
+ {
+ _exceptionLatch.countDown();
+ }
+
+ public CountDownLatch getExceptionLatch()
+ {
+ return _exceptionLatch;
+ }
+
+ public void received(ByteBuffer msg)
+ {
+ // increment read bytes and count down the latch for that many
+ int bytes = msg.remaining();
+ _readBytes += bytes;
+ for (int i = 0; i < bytes; i++)
+ {
+ _latch.countDown();
+ }
+
+ // Throw an error if we've been asked too, but we can still count
+ if (_nextReadErrors)
+ {
+ throw new RuntimeException("Was asked to error");
+ }
+ }
+
+ public CountDownLatch getLatch()
+ {
+ return _latch;
+ }
+
+ public boolean getWriterHasBeenIdle()
+ {
+ return _writerHasBeenIdle;
+ }
+
+ public boolean getReaderHasBeenIdle()
+ {
+ return _readerHasBeenIdle;
+ }
+
+ public void setClosed(boolean _closed)
+ {
+ this._closed = _closed;
+ }
+
+ public boolean getClosed()
+ {
+ return _closed;
+ }
+
+ }
+
+ private class EchoProtocolEngine extends CountingProtocolEngine
+ {
+
+ public void received(ByteBuffer msg)
+ {
+ super.received(msg);
+ msg.rewind();
+ _driver.send(msg);
+ }
+ }
+
+ public static void sleepForAtLeast(long period)
+ {
+ long start = System.currentTimeMillis();
+ long timeLeft = period;
+ while (timeLeft > 0)
+ {
+ try
+ {
+ Thread.sleep(timeLeft);
+ }
+ catch (InterruptedException e)
+ {
+ // Ignore it
+ }
+ timeLeft = period - (System.currentTimeMillis() - start);
+ }
+ }
+} \ No newline at end of file
diff --git a/qpid/java/common/src/test/java/org/apache/qpid/transport/network/mina/MinaNetworkHandlerTest.java b/qpid/java/common/src/test/java/org/apache/qpid/transport/network/mina/MinaNetworkHandlerTest.java
deleted file mode 100644
index 1a1b5af805..0000000000
--- a/qpid/java/common/src/test/java/org/apache/qpid/transport/network/mina/MinaNetworkHandlerTest.java
+++ /dev/null
@@ -1,534 +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.transport.network.mina;
-
-import static org.apache.qpid.transport.ConnectionSettings.WILDCARD_ADDRESS;
-
-import java.net.InetAddress;
-import java.net.InetSocketAddress;
-import java.net.SocketAddress;
-import java.nio.ByteBuffer;
-import java.util.ArrayList;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-
-import org.apache.qpid.framing.AMQDataBlock;
-import org.apache.qpid.protocol.ProtocolEngine;
-import org.apache.qpid.protocol.ProtocolEngineFactory;
-import org.apache.qpid.test.utils.QpidTestCase;
-import org.apache.qpid.transport.ConnectionSettings;
-import org.apache.qpid.transport.NetworkTransportConfiguration;
-import org.apache.qpid.transport.TransportException;
-import org.apache.qpid.transport.network.IncomingNetworkTransport;
-import org.apache.qpid.transport.network.NetworkConnection;
-import org.apache.qpid.transport.network.OutgoingNetworkTransport;
-import org.apache.qpid.transport.network.Transport;
-
-public class MinaNetworkHandlerTest extends QpidTestCase
-{
-
- private static final String TEST_DATA = "YHALOTHAR";
- private int _testPort;
- private IncomingNetworkTransport _server;
- private OutgoingNetworkTransport _client;
- private CountingProtocolEngine _countingEngine; // Keeps a count of how many bytes it's read
- private Exception _thrownEx;
- private ConnectionSettings _clientSettings;
- private NetworkConnection _network;
- private TestNetworkTransportConfiguration _brokerSettings;
-
- @Override
- public void setUp() throws Exception
- {
- String host = InetAddress.getLocalHost().getHostName();
- _testPort = findFreePort();
-
- _clientSettings = new ConnectionSettings();
- _clientSettings.setHost(host);
- _clientSettings.setPort(_testPort);
-
- _brokerSettings = new TestNetworkTransportConfiguration(_testPort, host);
-
- _server = new MinaNetworkTransport();
- _client = new MinaNetworkTransport();
- _thrownEx = null;
- _countingEngine = new CountingProtocolEngine();
- }
-
- @Override
- public void tearDown()
- {
- if (_server != null)
- {
- _server.close();
- }
-
- if (_client != null)
- {
- _client.close();
- }
- }
-
- /**
- * Tests that a socket can't be opened if a driver hasn't been bound
- * to the port and can be opened if a driver has been bound.
- */
- public void testBindOpen() throws Exception
- {
- try
- {
- _client.connect(_clientSettings, _countingEngine, null);
- }
- catch (TransportException e)
- {
- _thrownEx = e;
- }
-
- assertNotNull("Open should have failed since no engine bound", _thrownEx);
-
- _server.accept(_brokerSettings, null, null);
-
- _client.connect(_clientSettings, _countingEngine, null);
- }
-
- /**
- * Tests that a socket can't be opened after a bound NetworkDriver has been closed
- */
- public void testBindOpenCloseOpen() throws Exception
- {
- _server.accept(_brokerSettings, new EchoProtocolEngineSingletonFactory(), null);
- _client.connect(_clientSettings, _countingEngine, null);
- _client.close();
- _server.close();
-
- try
- {
- _client.connect(_clientSettings, _countingEngine, null);
- }
- catch (TransportException e)
- {
- _thrownEx = e;
- }
- assertNotNull("Open should have failed", _thrownEx);
- }
-
- /**
- * Checks that the right exception is thrown when binding a NetworkDriver to an already
- * existing socket.
- */
- public void testBindPortInUse()
- {
- try
- {
- _server.accept(_brokerSettings, new EchoProtocolEngineSingletonFactory(), null);
- }
- catch (TransportException e)
- {
- fail("First bind should not fail");
- }
-
- try
- {
- IncomingNetworkTransport second = new MinaNetworkTransport();
- second.accept(_brokerSettings, new EchoProtocolEngineSingletonFactory(), null);
- }
- catch (TransportException e)
- {
- _thrownEx = e;
- }
- assertNotNull("Second bind should throw BindException", _thrownEx);
- }
-
- /**
- * Tests that binding to the wildcard address succeeds and a client can
- * connect via localhost.
- */
- public void testWildcardBind() throws Exception
- {
- TestNetworkTransportConfiguration serverSettings =
- new TestNetworkTransportConfiguration(_testPort, WILDCARD_ADDRESS);
-
- _server.accept(serverSettings, null, null);
-
- try
- {
- _client.connect(_clientSettings, _countingEngine, null);
- }
- catch (TransportException e)
- {
- fail("Open should have succeeded since we used a wildcard bind");
- }
- }
-
- /**
- * tests that bytes sent on a network driver are received at the other end
- */
- public void testSend() throws Exception
- {
- // Open a connection from a counting engine to an echo engine
- _server.accept(_brokerSettings, new EchoProtocolEngineSingletonFactory(), null);
- _network = _client.connect(_clientSettings, _countingEngine, null);
-
- // Tell the counting engine how much data we're sending
- _countingEngine.setNewLatch(TEST_DATA.getBytes().length);
-
- // Send the data and wait for up to 2 seconds to get it back
- _network.getSender().send(ByteBuffer.wrap(TEST_DATA.getBytes()));
- _countingEngine.getLatch().await(2, TimeUnit.SECONDS);
-
- // Check what we got
- assertEquals("Wrong amount of data recieved", TEST_DATA.getBytes().length, _countingEngine.getReadBytes());
- }
-
- /**
- * Opens a connection with a low read idle and check that it gets triggered
- *
- */
- public void testSetReadIdle() throws Exception
- {
- // Open a connection from a counting engine to an echo engine
- _server.accept(_brokerSettings, new EchoProtocolEngineSingletonFactory(), null);
- _network = _client.connect(_clientSettings, _countingEngine, null);
- assertFalse("Reader should not have been idle", _countingEngine.getReaderHasBeenIdle());
- _network.setMaxReadIdle(1);
- sleepForAtLeast(1500);
- assertTrue("Reader should have been idle", _countingEngine.getReaderHasBeenIdle());
- }
-
- /**
- * Opens a connection with a low write idle and check that it gets triggered
- *
- */
- public void testSetWriteIdle() throws Exception
- {
- // Open a connection from a counting engine to an echo engine
- _server.accept(_brokerSettings, new EchoProtocolEngineSingletonFactory(), null);
- _network = _client.connect(_clientSettings, _countingEngine, null);
- assertFalse("Reader should not have been idle", _countingEngine.getWriterHasBeenIdle());
- _network.setMaxWriteIdle(1);
- sleepForAtLeast(1500);
- assertTrue("Reader should have been idle", _countingEngine.getWriterHasBeenIdle());
- }
-
-
- /**
- * Creates and then closes a connection from client to server and checks that the server
- * has its closed() method called. Then creates a new client and closes the server to check
- * that the client has its closed() method called.
- */
- public void testClosed() throws Exception
- {
- // Open a connection from a counting engine to an echo engine
- EchoProtocolEngineSingletonFactory factory = new EchoProtocolEngineSingletonFactory();
- _server.accept(_brokerSettings, factory, null);
- _network = _client.connect(_clientSettings, _countingEngine, null);
- EchoProtocolEngine serverEngine = null;
- while (serverEngine == null)
- {
- serverEngine = factory.getEngine();
- if (serverEngine == null)
- {
- try
- {
- Thread.sleep(10);
- }
- catch (InterruptedException e)
- {
- }
- }
- }
- assertFalse("Server should not have been closed", serverEngine.getClosed());
- serverEngine.setNewLatch(1);
- _client.close();
- try
- {
- serverEngine.getLatch().await(2, TimeUnit.SECONDS);
- }
- catch (InterruptedException e)
- {
- }
- assertTrue("Server should have been closed", serverEngine.getClosed());
-
- _client.connect(_clientSettings, _countingEngine, null);
- _countingEngine.setClosed(false);
- assertFalse("Client should not have been closed", _countingEngine.getClosed());
- _countingEngine.setNewLatch(1);
- _server.close();
- try
- {
- _countingEngine.getLatch().await(2, TimeUnit.SECONDS);
- }
- catch (InterruptedException e)
- {
- }
- assertTrue("Client should have been closed", _countingEngine.getClosed());
- }
-
- /**
- * Create a connection and instruct the client to throw an exception when it gets some data
- * and that the latch gets counted down.
- */
- public void testExceptionCaught() throws Exception
- {
- _server.accept(_brokerSettings, new EchoProtocolEngineSingletonFactory(), null);
- _network = _client.connect(_clientSettings, _countingEngine, null);
-
-
- assertEquals("Exception should not have been thrown", 1,
- _countingEngine.getExceptionLatch().getCount());
- _countingEngine.setErrorOnNextRead(true);
- _countingEngine.setNewLatch(TEST_DATA.getBytes().length);
- _network.getSender().send(ByteBuffer.wrap(TEST_DATA.getBytes()));
- _countingEngine.getExceptionLatch().await(2, TimeUnit.SECONDS);
- assertEquals("Exception should have been thrown", 0,
- _countingEngine.getExceptionLatch().getCount());
- }
-
- /**
- * Opens a connection and checks that the remote address is the one that was asked for
- */
- public void testGetRemoteAddress() throws Exception
- {
- _server.accept(_brokerSettings, new EchoProtocolEngineSingletonFactory(), null);
- _network = _client.connect(_clientSettings, _countingEngine, null);
- assertEquals(new InetSocketAddress(InetAddress.getLocalHost(), _testPort),
- _network.getRemoteAddress());
- }
-
- private class EchoProtocolEngineSingletonFactory implements ProtocolEngineFactory
- {
- private EchoProtocolEngine _engine = null;
-
- public ProtocolEngine newProtocolEngine(NetworkConnection network)
- {
- if (_engine == null)
- {
- _engine = new EchoProtocolEngine(network);
- }
- return getEngine();
- }
-
- public EchoProtocolEngine getEngine()
- {
- return _engine;
- }
- }
-
- public class CountingProtocolEngine implements ProtocolEngine
- {
- public ArrayList<ByteBuffer> _receivedBytes = new ArrayList<ByteBuffer>();
- private int _readBytes;
- private CountDownLatch _latch = new CountDownLatch(0);
- private boolean _readerHasBeenIdle;
- private boolean _writerHasBeenIdle;
- private boolean _closed = false;
- private boolean _nextReadErrors = false;
- private CountDownLatch _exceptionLatch = new CountDownLatch(1);
-
- public void closed()
- {
- setClosed(true);
- _latch.countDown();
- }
-
- public void setErrorOnNextRead(boolean b)
- {
- _nextReadErrors = b;
- }
-
- public void setNewLatch(int length)
- {
- _latch = new CountDownLatch(length);
- }
-
- public long getReadBytes()
- {
- return _readBytes;
- }
-
- public SocketAddress getRemoteAddress()
- {
- return _network.getRemoteAddress();
- }
-
- public SocketAddress getLocalAddress()
- {
- return _network.getLocalAddress();
- }
-
- public long getWrittenBytes()
- {
- return 0;
- }
-
- public void readerIdle()
- {
- _readerHasBeenIdle = true;
- }
-
- public void writeFrame(AMQDataBlock frame)
- {
-
- }
-
- public void writerIdle()
- {
- _writerHasBeenIdle = true;
- }
-
- public void exception(Throwable t)
- {
- _exceptionLatch.countDown();
- }
-
- public CountDownLatch getExceptionLatch()
- {
- return _exceptionLatch;
- }
-
- public void received(ByteBuffer msg)
- {
- // increment read bytes and count down the latch for that many
- int bytes = msg.remaining();
- _readBytes += bytes;
- for (int i = 0; i < bytes; i++)
- {
- _latch.countDown();
- }
-
- // Throw an error if we've been asked too, but we can still count
- if (_nextReadErrors)
- {
- throw new RuntimeException("Was asked to error");
- }
- }
-
- public CountDownLatch getLatch()
- {
- return _latch;
- }
-
- public boolean getWriterHasBeenIdle()
- {
- return _writerHasBeenIdle;
- }
-
- public boolean getReaderHasBeenIdle()
- {
- return _readerHasBeenIdle;
- }
-
- public void setClosed(boolean _closed)
- {
- this._closed = _closed;
- }
-
- public boolean getClosed()
- {
- return _closed;
- }
-
- }
-
- private class EchoProtocolEngine extends CountingProtocolEngine
- {
- private NetworkConnection _echoNetwork;
-
- public EchoProtocolEngine(NetworkConnection network)
- {
- _echoNetwork = network;
- }
-
- public void received(ByteBuffer msg)
- {
- super.received(msg);
- msg.rewind();
- _echoNetwork.getSender().send(msg);
- }
- }
-
- public static void sleepForAtLeast(long period)
- {
- long start = System.currentTimeMillis();
- long timeLeft = period;
- while (timeLeft > 0)
- {
- try
- {
- Thread.sleep(timeLeft);
- }
- catch (InterruptedException e)
- {
- // Ignore it
- }
- timeLeft = period - (System.currentTimeMillis() - start);
- }
- }
-
- private static class TestNetworkTransportConfiguration implements NetworkTransportConfiguration
- {
- private int _port;
- private String _host;
-
- public TestNetworkTransportConfiguration(final int port, final String host)
- {
- _port = port;
- _host = host;
- }
-
- public Boolean getTcpNoDelay()
- {
- return true;
- }
-
- public Integer getReceiveBufferSize()
- {
- return 32768;
- }
-
- public Integer getSendBufferSize()
- {
- return 32768;
- }
-
- public Integer getPort()
- {
- return _port;
- }
-
- public String getHost()
- {
- return _host;
- }
-
- public String getTransport()
- {
- return Transport.TCP;
- }
-
- public Integer getConnectorProcessors()
- {
- return 4;
- }
-
- }
-} \ No newline at end of file
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 d6767eb9c0..7eba5f092e 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
@@ -27,9 +27,7 @@ import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
-import java.io.InputStream;
import java.util.List;
-import java.util.Properties;
public class FileUtilsTest extends TestCase
{
@@ -184,20 +182,6 @@ public class FileUtilsTest extends TestCase
}
}
-
- /**
- * Helper method to create a temporary file with test content.
- *
- * @param test_data The data to store in the file
- *
- * @return The File reference
- */
- private File createTestFileInTmpDir(final String testData) throws Exception
- {
- final File tmpFile = File.createTempFile("test", "tmp");
-
- return createTestFile(tmpFile.getCanonicalPath(), testData);
- }
/**
* Helper method to create a test file with a string content
*
@@ -318,74 +302,8 @@ public class FileUtilsTest extends TestCase
// expected path
}
}
-
- /**
- * Tests that openFileOrDefaultResource can open a file on the filesystem.
- *
- */
- public void testOpenFileOrDefaultResourceOpensFileOnFileSystem() throws Exception
- {
- final File testFile = createTestFileInTmpDir("src=tmpfile");
- final String filenameOnFilesystem = testFile.getCanonicalPath();
- final String defaultResource = "org/apache/qpid/util/default.properties";
-
-
- final InputStream is = FileUtils.openFileOrDefaultResource(filenameOnFilesystem, defaultResource, this.getClass().getClassLoader());
- assertNotNull("Stream must not be null", is);
- final Properties p = new Properties();
- p.load(is);
- assertEquals("tmpfile", p.getProperty("src"));
- }
/**
- * Tests that openFileOrDefaultResource can open a file on the classpath.
- *
- */
- public void testOpenFileOrDefaultResourceOpensFileOnClasspath() throws Exception
- {
- final String mydefaultsResource = "org/apache/qpid/util/mydefaults.properties";
- final String defaultResource = "org/apache/qpid/util/default.properties";
-
-
- final InputStream is = FileUtils.openFileOrDefaultResource(mydefaultsResource, defaultResource, this.getClass().getClassLoader());
- assertNotNull("Stream must not be null", is);
- final Properties p = new Properties();
- p.load(is);
- assertEquals("mydefaults", p.getProperty("src"));
- }
-
- /**
- * Tests that openFileOrDefaultResource returns the default resource when file cannot be found.
- */
- public void testOpenFileOrDefaultResourceOpensDefaultResource() throws Exception
- {
- final File fileThatDoesNotExist = new File("/does/not/exist.properties");
- assertFalse("Test must not exist", fileThatDoesNotExist.exists());
-
- final String defaultResource = "org/apache/qpid/util/default.properties";
-
- final InputStream is = FileUtils.openFileOrDefaultResource(fileThatDoesNotExist.getCanonicalPath(), defaultResource, this.getClass().getClassLoader());
- assertNotNull("Stream must not be null", is);
- Properties p = new Properties();
- p.load(is);
- assertEquals("default.properties", p.getProperty("src"));
- }
-
- /**
- * Tests that openFileOrDefaultResource returns null if neither the file nor
- * the default resource can be found..
- */
- public void testOpenFileOrDefaultResourceReturnsNullWhenNeitherCanBeFound() throws Exception
- {
-
- final String mydefaultsResource = "org/apache/qpid/util/doesnotexisteiether.properties";
- final String defaultResource = "org/apache/qpid/util/doesnotexisteiether.properties";
-
- final InputStream is = FileUtils.openFileOrDefaultResource(mydefaultsResource, defaultResource, this.getClass().getClassLoader());
- assertNull("Stream must be null", is);
- }
-
- /**
* Given two lists of File arrays ensure they are the same length and all entries in Before are in After
*
* @param filesBefore File[]
diff --git a/qpid/java/common/src/test/java/org/apache/qpid/util/default.properties b/qpid/java/common/src/test/java/org/apache/qpid/util/default.properties
deleted file mode 100644
index cb522ea9a7..0000000000
--- a/qpid/java/common/src/test/java/org/apache/qpid/util/default.properties
+++ /dev/null
@@ -1,2 +0,0 @@
-# Used by FileUtilsTests
-src=default.properties \ No newline at end of file
diff --git a/qpid/java/common/src/test/java/org/apache/qpid/util/mydefaults.properties b/qpid/java/common/src/test/java/org/apache/qpid/util/mydefaults.properties
deleted file mode 100644
index 6a49d927d0..0000000000
--- a/qpid/java/common/src/test/java/org/apache/qpid/util/mydefaults.properties
+++ /dev/null
@@ -1,2 +0,0 @@
-# Used by FileUtilsTests
-src=mydefaults \ No newline at end of file
diff --git a/qpid/java/ivy.xml b/qpid/java/ivy.xml
deleted file mode 100644
index 1399db5248..0000000000
--- a/qpid/java/ivy.xml
+++ /dev/null
@@ -1,39 +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.
--->
-<ivy-module version="2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:noNamespaceSchemaLocation="http://ant.apache.org/ivy/schemas/ivy.xsd">
-
- <info organisation="org/apache" module="qpid" revision="0.13"/>
-
- <publications xmlns:e="urn:ant.apache.org:ivy-extras">
- <artifact name="qpid-client" type="pom" ext="pom"/>
- <artifact name="qpid-client" type="pom.asc" ext="pom.asc"/>
- <artifact name="qpid-client" type="jar" ext="jar"/>
- <artifact name="qpid-client" type="jar.asc" ext="jar.asc"/>
- <artifact name="qpid-client" type="source" ext="jar" e:classifier="sources"/>
- <artifact name="qpid-client" type="source.asc" ext="jar.asc" e:classifier="sources"/>
- <artifact name="qpid-common" type="pom" ext="pom"/>
- <artifact name="qpid-common" type="pom.asc" ext="pom.asc"/>
- <artifact name="qpid-common" type="jar" ext="jar"/>
- <artifact name="qpid-common" type="jar.asc" ext="jar.asc"/>
- <artifact name="qpid-common" type="source" ext="jar" e:classifier="sources"/>
- <artifact name="qpid-common" type="source.asc" ext="jar.asc" e:classifier="sources"/>
- </publications>
-
- <dependencies/>
-</ivy-module>
diff --git a/qpid/java/ivysettings-nexus.xml b/qpid/java/ivysettings-nexus.xml
deleted file mode 100644
index 1d9c393e23..0000000000
--- a/qpid/java/ivysettings-nexus.xml
+++ /dev/null
@@ -1,30 +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.
--->
-<ivysettings>
- <credentials host="${nexus.host}" realm="Sonatype Nexus Repository Manager" username="${nexus.user}" passwd="${nexus.password}"/>
- <caches defaultCacheDir="${user.home}/.ivy2/cache"/>
- <resolvers>
- <ibiblio name="public" m2compatible="true"/>
- <url name="nexus">
- <artifact pattern="${nexus.upload.url}/[organisation]/[module]/[artifact]/[revision]/[artifact]-[revision](-[classifier]).[ext]" />
- </url>
- </resolvers>
- <modules>
- <module organisation="${nexus.organisation}" name="qpid" resolver="nexus"/>
- </modules>
- <settings defaultResolver="public"/>
-</ivysettings>
diff --git a/qpid/java/lib/backport-util-concurrent-2.2.jar b/qpid/java/lib/backport-util-concurrent-2.2.jar
new file mode 100644
index 0000000000..20a16877bd
--- /dev/null
+++ b/qpid/java/lib/backport-util-concurrent-2.2.jar
Binary files differ
diff --git a/qpid/java/lib/commons-pool-1.4.jar b/qpid/java/lib/commons-pool-1.4.jar
new file mode 100644
index 0000000000..d6bc185450
--- /dev/null
+++ b/qpid/java/lib/commons-pool-1.4.jar
Binary files differ
diff --git a/qpid/java/lib/core-3.1.1.jar b/qpid/java/lib/core-3.1.1.jar
new file mode 100644
index 0000000000..ae0b635867
--- /dev/null
+++ b/qpid/java/lib/core-3.1.1.jar
Binary files differ
diff --git a/qpid/java/lib/geronimo-servlet_2.5_spec-1.2.jar b/qpid/java/lib/geronimo-servlet_2.5_spec-1.2.jar
new file mode 100644
index 0000000000..00a2010036
--- /dev/null
+++ b/qpid/java/lib/geronimo-servlet_2.5_spec-1.2.jar
Binary files differ
diff --git a/qpid/java/lib/ivy/README.txt b/qpid/java/lib/ivy/README.txt
deleted file mode 100644
index f8a01f39b4..0000000000
--- a/qpid/java/lib/ivy/README.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-Folder used to store Ivy libs for use in publishing Maven artifacts.
-
-Ivy must be downloaded and extracted into this directory if it is not available in the Ant lib dir.
-
-File may be downloaded in 2 ways:
-1. By running the following command from the qpid/java dir:
- ant -buildfile upload.xml download-ivy
-2. Manually download and extract via http://ant.apache.org/ivy.
-
-Note for method 1 you may also have to set proxy server settings in advance, eg:
-export ANT_OPTS="-Dhttp.proxyHost=<hostname> -Dhttp.proxyPort=<port>"
diff --git a/qpid/java/lib/javassist.jar b/qpid/java/lib/javassist.jar
new file mode 100644
index 0000000000..a6bde77812
--- /dev/null
+++ b/qpid/java/lib/javassist.jar
Binary files differ
diff --git a/qpid/java/lib/jline-0.9.94.jar b/qpid/java/lib/jline-0.9.94.jar
new file mode 100644
index 0000000000..dafca7c46e
--- /dev/null
+++ b/qpid/java/lib/jline-0.9.94.jar
Binary files differ
diff --git a/qpid/java/lib/jsp-2.1.jar b/qpid/java/lib/jsp-2.1.jar
new file mode 100644
index 0000000000..bfdb566c13
--- /dev/null
+++ b/qpid/java/lib/jsp-2.1.jar
Binary files differ
diff --git a/qpid/java/lib/jsp-api-2.1.jar b/qpid/java/lib/jsp-api-2.1.jar
new file mode 100644
index 0000000000..ac3a7a8f7e
--- /dev/null
+++ b/qpid/java/lib/jsp-api-2.1.jar
Binary files differ
diff --git a/qpid/java/lib/junit-4.4.jar b/qpid/java/lib/junit-4.4.jar
new file mode 100644
index 0000000000..649b0b327f
--- /dev/null
+++ b/qpid/java/lib/junit-4.4.jar
Binary files differ
diff --git a/qpid/java/lib/mina-core-1.0.1.jar b/qpid/java/lib/mina-core-1.0.1.jar
new file mode 100755
index 0000000000..f12067aa90
--- /dev/null
+++ b/qpid/java/lib/mina-core-1.0.1.jar
Binary files differ
diff --git a/qpid/java/lib/mina-core-1.1.7.jar b/qpid/java/lib/mina-core-1.1.7.jar
deleted file mode 100644
index a5fc451cc7..0000000000
--- a/qpid/java/lib/mina-core-1.1.7.jar
+++ /dev/null
Binary files differ
diff --git a/qpid/java/lib/mina-filter-ssl-1.0.1.jar b/qpid/java/lib/mina-filter-ssl-1.0.1.jar
new file mode 100755
index 0000000000..53738e6498
--- /dev/null
+++ b/qpid/java/lib/mina-filter-ssl-1.0.1.jar
Binary files differ
diff --git a/qpid/java/lib/mina-filter-ssl-1.1.7.jar b/qpid/java/lib/mina-filter-ssl-1.1.7.jar
deleted file mode 100644
index 40bdc919e1..0000000000
--- a/qpid/java/lib/mina-filter-ssl-1.1.7.jar
+++ /dev/null
Binary files differ
diff --git a/qpid/java/lib/muse-core-2.2.0.jar b/qpid/java/lib/muse-core-2.2.0.jar
new file mode 100644
index 0000000000..674ec26f58
--- /dev/null
+++ b/qpid/java/lib/muse-core-2.2.0.jar
Binary files differ
diff --git a/qpid/java/lib/muse-platform-mini-2.2.0.jar b/qpid/java/lib/muse-platform-mini-2.2.0.jar
new file mode 100644
index 0000000000..1782083231
--- /dev/null
+++ b/qpid/java/lib/muse-platform-mini-2.2.0.jar
Binary files differ
diff --git a/qpid/java/lib/muse-util-2.2.0.jar b/qpid/java/lib/muse-util-2.2.0.jar
new file mode 100644
index 0000000000..8bb7348180
--- /dev/null
+++ b/qpid/java/lib/muse-util-2.2.0.jar
Binary files differ
diff --git a/qpid/java/lib/muse-util-qname-2.2.0.jar b/qpid/java/lib/muse-util-qname-2.2.0.jar
new file mode 100644
index 0000000000..af0c76ece4
--- /dev/null
+++ b/qpid/java/lib/muse-util-qname-2.2.0.jar
Binary files differ
diff --git a/qpid/java/lib/muse-util-xml-2.2.0.jar b/qpid/java/lib/muse-util-xml-2.2.0.jar
new file mode 100644
index 0000000000..016b303c62
--- /dev/null
+++ b/qpid/java/lib/muse-util-xml-2.2.0.jar
Binary files differ
diff --git a/qpid/java/lib/muse-wsa-soap-2.2.0.jar b/qpid/java/lib/muse-wsa-soap-2.2.0.jar
new file mode 100644
index 0000000000..f83322beac
--- /dev/null
+++ b/qpid/java/lib/muse-wsa-soap-2.2.0.jar
Binary files differ
diff --git a/qpid/java/lib/muse-wsdm-muws-adv-api-2.2.0.jar b/qpid/java/lib/muse-wsdm-muws-adv-api-2.2.0.jar
new file mode 100644
index 0000000000..ba3bf4aa40
--- /dev/null
+++ b/qpid/java/lib/muse-wsdm-muws-adv-api-2.2.0.jar
Binary files differ
diff --git a/qpid/java/lib/muse-wsdm-muws-adv-impl-2.2.0.jar b/qpid/java/lib/muse-wsdm-muws-adv-impl-2.2.0.jar
new file mode 100644
index 0000000000..780a20f474
--- /dev/null
+++ b/qpid/java/lib/muse-wsdm-muws-adv-impl-2.2.0.jar
Binary files differ
diff --git a/qpid/java/lib/muse-wsdm-muws-api-2.2.0.jar b/qpid/java/lib/muse-wsdm-muws-api-2.2.0.jar
new file mode 100644
index 0000000000..2a0cab200a
--- /dev/null
+++ b/qpid/java/lib/muse-wsdm-muws-api-2.2.0.jar
Binary files differ
diff --git a/qpid/java/lib/muse-wsdm-muws-impl-2.2.0.jar b/qpid/java/lib/muse-wsdm-muws-impl-2.2.0.jar
new file mode 100644
index 0000000000..a9954bb27e
--- /dev/null
+++ b/qpid/java/lib/muse-wsdm-muws-impl-2.2.0.jar
Binary files differ
diff --git a/qpid/java/lib/muse-wsdm-wef-api-2.2.0.jar b/qpid/java/lib/muse-wsdm-wef-api-2.2.0.jar
new file mode 100644
index 0000000000..e9206b2eb3
--- /dev/null
+++ b/qpid/java/lib/muse-wsdm-wef-api-2.2.0.jar
Binary files differ
diff --git a/qpid/java/lib/muse-wsdm-wef-impl-2.2.0.jar b/qpid/java/lib/muse-wsdm-wef-impl-2.2.0.jar
new file mode 100644
index 0000000000..12856123b1
--- /dev/null
+++ b/qpid/java/lib/muse-wsdm-wef-impl-2.2.0.jar
Binary files differ
diff --git a/qpid/java/lib/muse-wsn-api-2.2.0.jar b/qpid/java/lib/muse-wsn-api-2.2.0.jar
new file mode 100644
index 0000000000..72b70a043d
--- /dev/null
+++ b/qpid/java/lib/muse-wsn-api-2.2.0.jar
Binary files differ
diff --git a/qpid/java/lib/muse-wsn-impl-2.2.0.jar b/qpid/java/lib/muse-wsn-impl-2.2.0.jar
new file mode 100644
index 0000000000..615f2a5f62
--- /dev/null
+++ b/qpid/java/lib/muse-wsn-impl-2.2.0.jar
Binary files differ
diff --git a/qpid/java/lib/muse-wsrf-api-2.2.0.jar b/qpid/java/lib/muse-wsrf-api-2.2.0.jar
new file mode 100644
index 0000000000..efa36e9fbc
--- /dev/null
+++ b/qpid/java/lib/muse-wsrf-api-2.2.0.jar
Binary files differ
diff --git a/qpid/java/lib/muse-wsrf-impl-2.2.0.jar b/qpid/java/lib/muse-wsrf-impl-2.2.0.jar
new file mode 100644
index 0000000000..a19b1e7149
--- /dev/null
+++ b/qpid/java/lib/muse-wsrf-impl-2.2.0.jar
Binary files differ
diff --git a/qpid/java/lib/muse-wsrf-rmd-2.2.0.jar b/qpid/java/lib/muse-wsrf-rmd-2.2.0.jar
new file mode 100644
index 0000000000..e03676cad8
--- /dev/null
+++ b/qpid/java/lib/muse-wsrf-rmd-2.2.0.jar
Binary files differ
diff --git a/qpid/java/lib/muse-wsx-api-2.2.0.jar b/qpid/java/lib/muse-wsx-api-2.2.0.jar
new file mode 100644
index 0000000000..1533d8dc59
--- /dev/null
+++ b/qpid/java/lib/muse-wsx-api-2.2.0.jar
Binary files differ
diff --git a/qpid/java/lib/muse-wsx-impl-2.2.0.jar b/qpid/java/lib/muse-wsx-impl-2.2.0.jar
new file mode 100644
index 0000000000..9ce78ef0b7
--- /dev/null
+++ b/qpid/java/lib/muse-wsx-impl-2.2.0.jar
Binary files differ
diff --git a/qpid/java/lib/poms/backport-util-concurrent-2.2.xml b/qpid/java/lib/poms/backport-util-concurrent-2.2.xml
new file mode 100644
index 0000000000..6df4cfca40
--- /dev/null
+++ b/qpid/java/lib/poms/backport-util-concurrent-2.2.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<dep>
+ <groupId>backport-util-concurrent</groupId>
+ <artifactId>backport-util-concurrent</artifactId>
+ <version>2.2</version>
+</dep>
diff --git a/qpid/java/lib/poms/mina-core-1.0.1.xml b/qpid/java/lib/poms/mina-core-1.0.1.xml
new file mode 100644
index 0000000000..87fb96999f
--- /dev/null
+++ b/qpid/java/lib/poms/mina-core-1.0.1.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<dep>
+ <groupId>org.apache.mina</groupId>
+ <artifactId>mina-core</artifactId>
+ <version>1.0.1</version>
+</dep>
diff --git a/qpid/java/lib/poms/mina-core-1.1.7.xml b/qpid/java/lib/poms/mina-core-1.1.7.xml
deleted file mode 100644
index eee6108082..0000000000
--- a/qpid/java/lib/poms/mina-core-1.1.7.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0"?>
-<!--
- Licensed to the Apache Software Foundation (ASF) under one or more
- contributor license agreements. See the NOTICE file distributed with
- this work for additional information regarding copyright ownership.
- The ASF licenses this file to You under the Apache License, Version 2.0
- (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<dep>
- <groupId>org.apache.mina</groupId>
- <artifactId>mina-core</artifactId>
- <version>1.1.7</version>
-</dep>
diff --git a/qpid/java/lib/poms/mina-filter-ssl-1.0.1.xml b/qpid/java/lib/poms/mina-filter-ssl-1.0.1.xml
new file mode 100644
index 0000000000..ae41d7ed63
--- /dev/null
+++ b/qpid/java/lib/poms/mina-filter-ssl-1.0.1.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<dep>
+ <groupId>org.apache.mina</groupId>
+ <artifactId>mina-filter-ssl</artifactId>
+ <version>1.0.1</version>
+</dep>
diff --git a/qpid/java/lib/poms/mina-filter-ssl-1.1.7.xml b/qpid/java/lib/poms/mina-filter-ssl-1.1.7.xml
deleted file mode 100644
index 52daba7eed..0000000000
--- a/qpid/java/lib/poms/mina-filter-ssl-1.1.7.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0"?>
-<!--
- Licensed to the Apache Software Foundation (ASF) under one or more
- contributor license agreements. See the NOTICE file distributed with
- this work for additional information regarding copyright ownership.
- The ASF licenses this file to You under the Apache License, Version 2.0
- (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<dep>
- <groupId>org.apache.mina</groupId>
- <artifactId>mina-filter-ssl</artifactId>
- <version>1.1.7</version>
-</dep>
diff --git a/qpid/java/lib/start.jar b/qpid/java/lib/start.jar
new file mode 100644
index 0000000000..63685df7cc
--- /dev/null
+++ b/qpid/java/lib/start.jar
Binary files differ
diff --git a/qpid/java/lib/wsdl4j-1.6.1.jar b/qpid/java/lib/wsdl4j-1.6.1.jar
new file mode 100644
index 0000000000..67a35fcbaa
--- /dev/null
+++ b/qpid/java/lib/wsdl4j-1.6.1.jar
Binary files differ
diff --git a/qpid/java/lib/xercesImpl-2.8.1.jar b/qpid/java/lib/xercesImpl-2.8.1.jar
new file mode 100644
index 0000000000..3b351f6e2b
--- /dev/null
+++ b/qpid/java/lib/xercesImpl-2.8.1.jar
Binary files differ
diff --git a/qpid/java/lib/xml-apis-1.3.03.jar b/qpid/java/lib/xml-apis-1.3.03.jar
new file mode 100644
index 0000000000..b338fb6693
--- /dev/null
+++ b/qpid/java/lib/xml-apis-1.3.03.jar
Binary files differ
diff --git a/qpid/java/management/agent/build.xml b/qpid/java/management/agent/build.xml
new file mode 100644
index 0000000000..a410c74c1f
--- /dev/null
+++ b/qpid/java/management/agent/build.xml
@@ -0,0 +1,27 @@
+<!--
+ -
+ - Licensed to the Apache Software Foundation (ASF) under one
+ - or more contributor license agreements. See the NOTICE file
+ - distributed with this work for additional information
+ - regarding copyright ownership. The ASF licenses this file
+ - to you under the Apache License, Version 2.0 (the
+ - "License"); you may not use this file except in compliance
+ - with the License. You may obtain a copy of the License at
+ -
+ - http://www.apache.org/licenses/LICENSE-2.0
+ -
+ - Unless required by applicable law or agreed to in writing,
+ - software distributed under the License is distributed on an
+ - "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ - KIND, either express or implied. See the License for the
+ - specific language governing permissions and limitations
+ - under the License.
+ -
+ -->
+<project name="QMF Agent" default="build">
+
+ <property name="module.depends" value="common client"/>
+
+ <import file="../../module.xml"/>
+
+</project>
diff --git a/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/Agent.java b/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/Agent.java
new file mode 100644
index 0000000000..b1a4a8c93e
--- /dev/null
+++ b/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/Agent.java
@@ -0,0 +1,706 @@
+/*
+ *
+ * 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.agent;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.Hashtable;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+import javax.jms.BytesMessage;
+import javax.jms.Destination;
+import javax.jms.JMSException;
+import javax.jms.Message;
+import javax.jms.MessageConsumer;
+import javax.jms.MessageListener;
+import javax.jms.MessageProducer;
+import javax.jms.Queue;
+import javax.jms.Session;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.qpid.agent.binding.BindingContext;
+import org.apache.qpid.agent.binding.BindingUtils;
+import org.apache.qpid.agent.binding.ClassBinding;
+import org.apache.qpid.agent.binding.BindingException;
+import org.apache.qpid.agent.binding.MethodBinding;
+import org.apache.qpid.agent.binding.ParameterBinding;
+import org.apache.qpid.agent.binding.PropertyBinding;
+import org.apache.qpid.agent.binding.TypeBinding;
+import org.apache.qpid.client.AMQConnection;
+import org.apache.qpid.transport.codec.BBDecoder;
+import org.apache.qpid.transport.codec.BBEncoder;
+import org.apache.qpid.transport.codec.Decoder;
+
+/**
+ * The main class for interacting with the QMF bus. Objects which are to be
+ * managed can be registered with the agent, as can classes to be exposed via
+ * the schema.
+ */
+public class Agent implements MessageListener
+{
+ // The following are settings to configure the Agent
+ protected AMQConnection connection;
+ protected boolean sessionTransacted = false;
+ protected int acknowledgeMode = Session.AUTO_ACKNOWLEDGE;
+ protected String label;
+ protected UUID systemId;
+ // this list holds the objects until the agent is started
+ protected List managedObjects = new ArrayList();
+ protected List registeredClasses = new ArrayList();
+ // The following instance variables are not
+ // able to be set by the end user.
+ protected Session session;
+ protected MessageProducer prod;
+ protected MessageConsumer cons;
+ protected Queue reply;
+ protected BindingContext bctx = new BindingContext();
+ protected Map<Long, ManagedObject> objects = new Hashtable<Long, ManagedObject>();
+ protected long bbank;
+ protected long abank;
+ protected static final Log log = LogFactory.getLog(Agent.class);
+ protected volatile boolean inside = false;
+ protected ClassLoader classLoader = null;
+
+ public Agent()
+ {
+ systemId = UUID.randomUUID();
+ log.debug(String.format("Agent with uid %s created", systemId
+ .toString()));
+ }
+
+ public Agent(String label, UUID systemId)
+ {
+ this.systemId = systemId;
+ this.label = label;
+ log.debug(String.format("Agent with name %s and uid %s created", label,
+ systemId.toString()));
+ }
+
+ public void register(ManagedObject managedObject)
+ {
+ Class managedClass = managedObject.getObjectClass();
+ long id = managedObject.getId();
+ ClassBinding cb = bctx.register(managedClass);
+ managedObject.setManagedClassName(cb.getName());
+ managedObject.setManagedPackageName(cb.getPackage());
+ log.debug(String.format(
+ "Added managed object id '%d' for package '%s' class '%s'", id,
+ managedObject.getManagedPackageName(), managedObject
+ .getManagedClassName()));
+ objects.put(id, managedObject);
+ managedObjects.add(managedObject);
+ }
+
+ public void registerClass(Class cls)
+ {
+ bctx.register(cls);
+ if (!registeredClasses.contains(cls))
+ {
+ registeredClasses.add(cls);
+ }
+ }
+
+ /**
+ * Stops the agents connection to the bus
+ */
+ public void stop()
+ {
+ try
+ {
+ cons.close();
+ prod.close();
+ connection.stop();
+ connection.close();
+ session.close();
+ } catch (JMSException e)
+ {
+ log.error("Exception:", e);
+ }
+ }
+
+ /**
+ * Starts up the agent. Many bean containers may call this by default which
+ * aids in deployment
+ */
+ public void start()
+ {
+ log.debug(String.format("Agent with uid %s and name %s starting",
+ systemId.toString(), label));
+ for (Object clsName : registeredClasses.toArray())
+ {
+ try
+ {
+ Class cls = null;
+ if (String.class.isAssignableFrom(clsName.getClass()))
+ {
+ cls = getClass(clsName.toString());
+ } else
+ {
+ cls = (Class) clsName;
+ }
+ this.registerClass(cls);
+ } catch (Exception e)
+ {
+ log.error("Could not register class " + clsName);
+ }
+ }
+ for (Object obj : managedObjects.toArray())
+ {
+ this.register((ManagedObject) obj);
+ }
+ try
+ {
+ session = connection.createSession(sessionTransacted,
+ acknowledgeMode);
+ reply = session
+ .createQueue(String
+ .format(
+ "direct://amq.direct//%s-%s?exclusive='True'&autodelete='True'",
+ label, systemId));
+ cons = session.createConsumer(reply);
+ cons.setMessageListener(this);
+ prod = session.createProducer(null);
+ } catch (JMSException e)
+ {
+ throw new AgentException(e);
+ }
+ attachRequest(label, systemId);
+ try
+ {
+ connection.start();
+ } catch (JMSException e)
+ {
+ throw new AgentException(e);
+ }
+ }
+
+ /**
+ * Send an event object to the bus
+ */
+ public void raiseEvent(Object value, EventSeverity sev)
+ {
+ log.debug(String.format("Sending event of class %s with Severity %s",
+ value.getClass(), sev.ordinal()));
+ BBEncoder enc = this.init('e');
+ ClassBinding cb = bctx.getClassBinding(value.getClass());
+ String pkg = cb.getPackage();
+ String cls = cb.getName();
+ enc.writeStr8(pkg);
+ enc.writeStr8(cls);
+ enc.writeBin128(cb.getSchemaHash());
+ long now = System.currentTimeMillis() * 1000000;
+ enc.writeInt64(now);
+ enc.writeUint8((short) sev.ordinal());
+ for (PropertyBinding p : cb.getProperties())
+ {
+ p.getType().encode(enc, BindingUtils.get(p, value));
+ }
+ send(
+ String.format("console.event.%d.%d.%s.%s", bbank, abank, pkg,
+ cls), enc);
+ }
+
+ public void onMessage(Message message)
+ {
+ if (inside)
+ {
+ new Throwable().printStackTrace();
+ }
+ inside = true;
+ Decoder dec = readBody(message);
+ Destination replyTo;
+ try
+ {
+ replyTo = message.getJMSReplyTo();
+ } catch (JMSException e)
+ {
+ throw new AgentException(e);
+ }
+ byte[] magic = dec.readBytes(3);
+ if (magic[0] != 'A' || magic[1] != 'M' || magic[2] != '2')
+ {
+ throw new AgentException("bad magic: " + new String(magic));
+ }
+ short op = dec.readUint8();
+ long seq = dec.readUint32();
+ log.debug("Message recieved: " + (char) op);
+ switch (op)
+ {
+ case 'a':
+ this.handleAgentAttach(seq, replyTo, dec);
+ break;
+ case 'G':
+ this.handleGetQuery(seq, replyTo, dec);
+ break;
+ case 'M':
+ this.handleMethodRequest(seq, replyTo, dec);
+ break;
+ case 'S':
+ this.handleSchemaRequest(seq, replyTo, dec);
+ break;
+ case 'x':
+ // TODO
+ break;
+ default:
+ throw new IllegalArgumentException("opcode: " + ((char) op));
+ }
+ inside = false;
+ }
+
+ protected ClassBinding getClassBinding(ManagedObject mobj)
+ {
+ return bctx.getClassBinding(mobj.getObjectClass());
+ }
+
+ private byte[] ensure(int capacity, byte[] body, int size)
+ {
+ if (capacity > body.length)
+ {
+ byte[] copy = new byte[capacity];
+ System.arraycopy(body, 0, copy, 0, size);
+ body = copy;
+ }
+ return body;
+ }
+
+ private Decoder readBody(Message message)
+ {
+ BytesMessage msg = (BytesMessage) message;
+ BBDecoder dec = new BBDecoder();
+ byte[] buf = new byte[1024];
+ byte[] body = new byte[1024];
+ int size = 0;
+ int n;
+ try
+ {
+ while ((n = msg.readBytes(buf)) > 0)
+ {
+ body = ensure(size + n, body, size);
+ System.arraycopy(buf, 0, body, size, n);
+ size += n;
+ }
+ } catch (JMSException e)
+ {
+ throw new AgentException(e);
+ }
+ dec.init(ByteBuffer.wrap(body, 0, size));
+ return dec;
+ }
+
+ protected void handleAgentAttach(long seq, Destination replyTo, Decoder dec)
+ {
+ log.debug("Agent Attach Message");
+ bbank = dec.readUint32();
+ abank = dec.readUint32();
+ try
+ {
+ MessageConsumer mc = session
+ .createConsumer(session
+ .createQueue(String
+ .format(
+ "management://qpid.management//%s-%s?routingkey='agent.%d.%d'&exclusive='True'&autodelete='True'",
+ label, systemId, bbank, abank)));
+ mc.setMessageListener(this);
+ } catch (JMSException e)
+ {
+ throw new AgentException(e);
+ }
+ for (String packageName : bctx.getPackages())
+ {
+ packageIndication(packageName);
+ }
+ for (ClassBinding cb : bctx.getAllBindings())
+ {
+ classIndication(cb);
+ }
+ for (ManagedObject mo : objects.values())
+ {
+ content('i', seq, null, mo);
+ }
+ }
+
+ protected void handleMethodRequest(long seq, Destination replyTo,
+ Decoder dec)
+ {
+ dec.readUint64(); // first part of object-id
+ long id = dec.readUint64();
+ ManagedObject mo = objects.get(id);
+ if (mo == null)
+ {
+ methodResponse(seq, replyTo, 1, String.format(
+ "no such object: 0x%x", id));
+ } else
+ {
+ dec.readStr8(); // pkg
+ dec.readStr8(); // cls
+ dec.readBin128(); // hash
+ String mname = dec.readStr8();
+ ClassBinding cls = getClassBinding(mo);
+ MethodBinding method = cls.getMethod(mname);
+ if (method == null)
+ {
+ methodResponse(seq, replyTo, 2, String.format(
+ "no such method: %s", mname));
+ } else
+ {
+ log.trace("Handle method: " + method.getName());
+ List<ParameterBinding> params = method.getInParameters();
+ Object[] args = new Object[params.size()];
+ int idx = 0;
+ for (ParameterBinding p : params)
+ {
+ TypeBinding typeBinding = p.getType();
+ log
+ .trace(String
+ .format(
+ "Decoding parameter with type %s ref package %s ref class %s ",
+ typeBinding.getCode(), typeBinding
+ .getRefPackage(),
+ typeBinding.getRefClass()));
+ args[idx++] = typeBinding.decode(dec);
+ log.trace("Done");
+ }
+ try
+ {
+ Object[] result = mo.invoke(method, args);
+ methodResponse(seq, replyTo, 0, null, method, result);
+ } catch (BindingException ex)
+ {
+ log
+ .error(
+ String
+ .format(
+ "An exception occured invoking method %s. Stack trace sent to console.",
+ method.getName()), ex);
+ StringWriter str = new StringWriter();
+ PrintWriter writer = new PrintWriter(str);
+ ex.printStackTrace(writer);
+ writer.flush();
+ methodResponse(seq, replyTo, 7, str.toString());
+ }
+ log.trace("Done with method: " + method.getName());
+ }
+ }
+ }
+
+ protected void handleGetQuery(long seq, Destination replyTo, Decoder dec)
+ {
+ Map<String, Object> data = dec.readMap();
+ if (data.containsKey("_objectid"))
+ {
+ long objId = (Long) data.get("_objectid");
+ log.debug("Get Request message for object id " + objId);
+ ManagedObject mo = objects.get(objId);
+ if (mo == null)
+ {
+ methodResponse(seq, replyTo, 1, String.format(
+ "no such object: 0x%x", objId));
+ } else
+ {
+ content('g', seq, replyTo, mo);
+ }
+ } else if (data.containsKey("_class"))
+ {
+ String className = (String) data.get("_class");
+ String packageName = (String) data.get("_package");
+ log.debug(String.format(
+ "Get Request message for package '%s' class '%s'",
+ packageName, className));
+ for (ManagedObject mo : objects.values())
+ {
+ if (mo.getManagedClassName().equals(className))
+ {
+ if ((packageName == null) || packageName.equals("")
+ || packageName.equals(mo.getManagedPackageName()))
+ {
+ content('g', seq, replyTo, mo);
+ }
+ }
+ }
+ } else
+ {
+ for (ManagedObject mo : objects.values())
+ {
+ content('g', seq, replyTo, mo);
+ }
+ }
+ complete(seq, replyTo);
+ }
+
+ protected void handleSchemaRequest(long seq, Destination replyTo,
+ Decoder dec)
+ {
+ String pkg = dec.readStr8();
+ String cls = dec.readStr8();
+ log.debug(String.format(
+ "SchemaRequest message for package '%s' class '%s'", pkg, cls));
+ ClassBinding cb = bctx.getClassBinding(pkg, cls);
+ if (cb == null)
+ {
+ throw new AgentException("no such class: " + pkg + ", " + cls);
+ }
+ schemaResponse(seq, cb);
+ }
+
+ protected BBEncoder init(char opcode)
+ {
+ return init(opcode, 0);
+ }
+
+ protected BBEncoder init(char opcode, long sequence)
+ {
+ BBEncoder enc = new BBEncoder(1024);
+ enc.init();
+ enc.writeUint8((short) 'A');
+ enc.writeUint8((short) 'M');
+ enc.writeUint8((short) '2');
+ enc.writeUint8((short) opcode);
+ enc.writeUint32(sequence);
+ return enc;
+ }
+
+ protected void send(BBEncoder enc)
+ {
+ send("broker", enc);
+ }
+
+ protected void send(Destination dest, BBEncoder enc)
+ {
+ try
+ {
+ byte[] buf = new byte[1024];
+ BytesMessage msg = session.createBytesMessage();
+ ByteBuffer slice = enc.segment();
+ while (slice.hasRemaining())
+ {
+ int n = Math.min(buf.length, slice.remaining());
+ slice.get(buf, 0, n);
+ msg.writeBytes(buf, 0, n);
+ }
+ msg.setJMSReplyTo(reply);
+ // ???: I assume this is thread safe.
+ prod.send(dest, msg);
+ } catch (JMSException e)
+ {
+ throw new AgentException(e);
+ }
+ }
+
+ protected void send(String routingKey, BBEncoder enc)
+ {
+ try
+ {
+ send(session
+ .createQueue("management://qpid.management//?routingkey='"
+ + routingKey + "'"), enc);
+ } catch (JMSException e)
+ {
+ throw new AgentException(e);
+ }
+ }
+
+ protected void attachRequest(String label, UUID systemId)
+ {
+ BBEncoder enc = init('A');
+ enc.writeStr8(label);
+ enc.writeUuid(systemId);
+ enc.writeUint32(0);
+ enc.writeUint32(0);
+ send(enc);
+ }
+
+ protected void packageIndication(String pkg)
+ {
+ BBEncoder enc = init('p');
+ enc.writeStr8(pkg);
+ send(enc);
+ }
+
+ protected void classIndication(ClassBinding cb)
+ {
+ BBEncoder enc = init('q');
+ enc.writeUint8(cb.getKind());
+ enc.writeStr8(cb.getPackage());
+ enc.writeStr8(cb.getName());
+ enc.writeBin128(cb.getSchemaHash()); // schema hash?
+ send(enc);
+ }
+
+ protected void schemaResponse(long seq, ClassBinding cb)
+ {
+ BBEncoder enc = init('s', seq);
+ cb.encode(enc);
+ send(enc);
+ }
+
+ protected void content(char c, long seq, Destination dest, ManagedObject mo)
+ {
+ BBEncoder enc = init(c, seq);
+ ClassBinding cb = getClassBinding(mo);
+ String pkg = cb.getPackage();
+ String cls = cb.getName();
+ enc.writeStr8(pkg);
+ enc.writeStr8(cls);
+ enc.writeBin128(cb.getSchemaHash());
+ long now = System.currentTimeMillis() * 1000000;
+ enc.writeUint64(now);
+ enc.writeUint64(now);
+ enc.writeUint64(0);
+ enc.writeUint64(0x0000FFFFFFFFFFFFL & ((bbank << 28) | abank));
+ enc.writeUint64(mo.getId());
+ for (PropertyBinding p : cb.getProperties())
+ {
+ p.getType().encode(enc, mo.get(p));
+ }
+ if (dest == null)
+ {
+ send(String.format("console.obj.%d.%d.%s.%s", bbank, abank, pkg,
+ cls), enc);
+ } else
+ {
+ send(dest, enc);
+ }
+ }
+
+ protected void complete(long seq, Destination dest)
+ {
+ BBEncoder enc = init('z', seq);
+ enc.writeUint32(0);
+ enc.writeStr8("");
+ send(dest, enc);
+ }
+
+ protected void methodResponse(long seq, Destination dest, int status,
+ String text)
+ {
+ methodResponse(seq, dest, status, text, null, null);
+ }
+
+ protected void methodResponse(long seq, Destination dest, int status,
+ String text, MethodBinding method, Object[] result)
+ {
+ BBEncoder enc = init('m', seq);
+ enc.writeUint32(status);
+ enc.writeStr16(text == null ? "" : text);
+ if (method != null)
+ {
+ int idx = 0;
+ for (ParameterBinding p : method.getOutParameters())
+ {
+ p.getType().encode(enc, result[idx++]);
+ }
+ }
+ send(dest, enc);
+ }
+
+ protected Class getClass(String className)
+ {
+ try
+ {
+ if (classLoader != null)
+ {
+ return classLoader.loadClass(className);
+ } else
+ {
+ return Class.forName(className);
+ }
+ } catch (ClassNotFoundException e)
+ {
+ throw new AgentException(String.format(
+ "No class named %s was found", className), e);
+ }
+ }
+
+ public String getLabel()
+ {
+ return label;
+ }
+
+ public void setLabel(String label)
+ {
+ this.label = label;
+ }
+
+ public AMQConnection getConnection()
+ {
+ return connection;
+ }
+
+ public void setConnection(AMQConnection connection)
+ {
+ this.connection = connection;
+ }
+
+ public boolean isSessionTransacted()
+ {
+ return sessionTransacted;
+ }
+
+ public void setSessionTransacted(boolean sessionTransacted)
+ {
+ this.sessionTransacted = sessionTransacted;
+ }
+
+ public void setManagedObjects(List objectList)
+ {
+ this.managedObjects = objectList;
+ }
+
+ public List getManagedObjects()
+ {
+ return managedObjects;
+ }
+
+ public void setRegisteredClasses(List objectList)
+ {
+ this.registeredClasses = objectList;
+ }
+
+ public List getRegisteredClasses()
+ {
+ return this.registeredClasses;
+ }
+
+ public static void main(String[] args) throws Exception
+ {
+ String broker = args[0];
+ String name = args[1];
+ String url = String.format(
+ "amqp://guest:guest@/?brokerlist='tcp://%s'", broker);
+ AMQConnection conn = new AMQConnection(url);
+ Agent agent = new Agent(name, UUID.randomUUID());
+ agent.setConnection(conn);
+ for (int i = 2; i < args.length; i++)
+ {
+ Class<?> cls = Class.forName(args[i]);
+ agent.register(new ManagedPOJO(cls.newInstance()));
+ }
+ agent.start();
+ while (true)
+ {
+ Thread.sleep(1000);
+ }
+ }
+}
diff --git a/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/AgentException.java b/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/AgentException.java
new file mode 100644
index 0000000000..410cad2d8c
--- /dev/null
+++ b/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/AgentException.java
@@ -0,0 +1,45 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.agent;
+
+/**
+ * AgentException
+ *
+ */
+public class AgentException extends RuntimeException
+{
+ private static final long serialVersionUID = 1L;
+
+ public AgentException(String msg)
+ {
+ super(msg);
+ }
+
+ public AgentException(Throwable t)
+ {
+ super(t);
+ }
+
+ public AgentException(String msg, Throwable t)
+ {
+ super(msg, t);
+ }
+}
diff --git a/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/EventSeverity.java b/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/EventSeverity.java
new file mode 100644
index 0000000000..28735286c4
--- /dev/null
+++ b/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/EventSeverity.java
@@ -0,0 +1,27 @@
+package org.apache.qpid.agent;
+/*
+ *
+ * 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.
+ *
+ */
+
+
+public enum EventSeverity
+{
+ EMERGENCY, ALERT, CRIT, ERROR, WARN, NOTICE, INFO, DEBUG
+}
diff --git a/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/ManagedEJB.java b/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/ManagedEJB.java
new file mode 100644
index 0000000000..60efb1e284
--- /dev/null
+++ b/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/ManagedEJB.java
@@ -0,0 +1,138 @@
+/*
+ *
+ * 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.agent;
+
+import javax.naming.InitialContext;
+import javax.naming.NamingException;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.qpid.agent.binding.BindingUtils;
+import org.apache.qpid.agent.binding.MethodBinding;
+import org.apache.qpid.agent.binding.PropertyBinding;
+
+/**
+ * Wrapper classe for adding EJBS which are to be managed by the QMF Agent. The
+ * jndi location and the public interface to exposed are used to generate the
+ * schema.
+ */
+public class ManagedEJB extends ManagedObjectBase
+{
+ private Log log = LogFactory.getLog(ManagedEJB.class);
+ protected String className;
+ protected String jndiLocation;
+ protected ClassLoader classLoader;
+
+ protected Object getEJB()
+ {
+ ClassLoader previousCL = Thread.currentThread().getContextClassLoader();
+ try
+ {
+ if (classLoader != null)
+ {
+ Thread.currentThread().setContextClassLoader(classLoader);
+ }
+ InitialContext ctx = new InitialContext();
+ return ctx.lookup(jndiLocation);
+ } catch (NamingException e)
+ {
+ throw new AgentException("Error looking up EJB at " + jndiLocation,
+ e);
+ } finally
+ {
+ Thread.currentThread().setContextClassLoader(previousCL);
+ }
+ }
+
+ @Override
+ public Object get(PropertyBinding property)
+ {
+ return BindingUtils.get(property, this.getEJB());
+ }
+
+ @Override
+ public long getId()
+ {
+ return System.identityHashCode(this);
+ }
+
+ @Override
+ public Class getObjectClass()
+ {
+ try
+ {
+ if (classLoader != null)
+ {
+ log.debug("Using the classloader");
+ return classLoader.loadClass(className);
+ } else
+ {
+ return Class.forName(className);
+ }
+ } catch (ClassNotFoundException e)
+ {
+ throw new AgentException(String.format(
+ "No class named %s was found", className), e);
+ }
+ }
+
+ @Override
+ public Object[] invoke(MethodBinding method, Object... args)
+ {
+ return BindingUtils.invoke(method, this.getEJB(), args);
+ }
+
+ @Override
+ public void set(PropertyBinding property, Object value)
+ {
+ BindingUtils.set(property, value, this.getEJB());
+ }
+
+ public String getClassName()
+ {
+ return className;
+ }
+
+ public void setClassName(String className)
+ {
+ this.className = className;
+ }
+
+ public String getJndiLocation()
+ {
+ return jndiLocation;
+ }
+
+ public void setJndiLocation(String jndiLocation)
+ {
+ this.jndiLocation = jndiLocation;
+ }
+
+ public ClassLoader getClassLoader()
+ {
+ return classLoader;
+ }
+
+ public void setClassLoader(ClassLoader cloader)
+ {
+ this.classLoader = cloader;
+ }
+}
diff --git a/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/ManagedObject.java b/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/ManagedObject.java
new file mode 100644
index 0000000000..aa3bbf3894
--- /dev/null
+++ b/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/ManagedObject.java
@@ -0,0 +1,52 @@
+/*
+ *
+ * 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.agent;
+
+import org.apache.qpid.agent.binding.MethodBinding;
+import org.apache.qpid.agent.binding.PropertyBinding;
+
+/**
+ * Objects which are to be managed and controlled by the QMF Agent.
+ */
+public interface ManagedObject
+{
+ public abstract long getId();
+
+ public abstract Class getObjectClass();
+
+ public abstract Object get(PropertyBinding property);
+
+ public abstract void set(PropertyBinding property, Object value);
+
+ public abstract Object[] invoke(MethodBinding method, Object... args);
+
+ public abstract String getName();
+
+ public abstract void setName(String name);
+
+ public String getManagedClassName();
+
+ public String getManagedPackageName();
+
+ public void setManagedClassName(String aName);
+
+ public void setManagedPackageName(String aName);
+}
diff --git a/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/ManagedObjectBase.java b/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/ManagedObjectBase.java
new file mode 100644
index 0000000000..51789ae11f
--- /dev/null
+++ b/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/ManagedObjectBase.java
@@ -0,0 +1,72 @@
+/*
+ *
+ * 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.agent;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.qpid.agent.binding.MethodBinding;
+import org.apache.qpid.agent.binding.PropertyBinding;
+
+public abstract class ManagedObjectBase implements ManagedObject
+{
+ private static Log log = LogFactory.getLog(ManagedObjectBase.class);
+ protected String name;
+ protected String managedClassName;
+ protected String managedPackageName;
+
+ public abstract long getId();
+
+ public abstract Object get(PropertyBinding property);
+
+ public abstract void set(PropertyBinding property, Object value);
+
+ public abstract Object[] invoke(MethodBinding method, Object... args);
+
+ public String getName()
+ {
+ return name;
+ }
+
+ public void setName(String name)
+ {
+ this.name = name;
+ }
+
+ public String getManagedClassName()
+ {
+ return managedClassName;
+ }
+
+ public void setManagedClassName(String managedClassName)
+ {
+ this.managedClassName = managedClassName;
+ }
+
+ public String getManagedPackageName()
+ {
+ return managedPackageName;
+ }
+
+ public void setManagedPackageName(String managedPackageName)
+ {
+ this.managedPackageName = managedPackageName;
+ }
+}
diff --git a/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/ManagedPOJO.java b/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/ManagedPOJO.java
new file mode 100644
index 0000000000..94d9b9d0a8
--- /dev/null
+++ b/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/ManagedPOJO.java
@@ -0,0 +1,90 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.agent;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.qpid.agent.binding.BindingUtils;
+import org.apache.qpid.agent.binding.MethodBinding;
+import org.apache.qpid.agent.binding.PropertyBinding;
+
+/**
+ * Wrapper classe for adding POJOS which are to be managed by the QMF Agent.
+ */
+public class ManagedPOJO extends ManagedObjectBase implements ManagedObject
+{
+ private Log log = LogFactory.getLog(ManagedPOJO.class);
+ private Object managed;
+
+ public ManagedPOJO()
+ {
+ super();
+ }
+
+ public ManagedPOJO(Object managed)
+ {
+ super();
+ this.setManaged(managed);
+ }
+
+ @Override
+ public long getId()
+ {
+ if (managed == null)
+ {
+ throw new AgentException("The managed object is null");
+ }
+ return System.identityHashCode(managed);
+ }
+
+ public Class getObjectClass()
+ {
+ return managed.getClass();
+ }
+
+ public Object getManaged()
+ {
+ return managed;
+ }
+
+ public void setManaged(Object managed)
+ {
+ this.managed = managed;
+ }
+
+ @Override
+ public Object get(PropertyBinding property)
+ {
+ return BindingUtils.get(property, managed);
+ }
+
+ @Override
+ public Object[] invoke(MethodBinding method, Object... args)
+ {
+ return BindingUtils.invoke(method, managed, args);
+ }
+
+ @Override
+ public void set(PropertyBinding property, Object value)
+ {
+ BindingUtils.set(property, value, managed);
+ }
+}
diff --git a/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/annotations/QMFAgent.java b/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/annotations/QMFAgent.java
new file mode 100644
index 0000000000..b9fcf40fc1
--- /dev/null
+++ b/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/annotations/QMFAgent.java
@@ -0,0 +1,34 @@
+/*
+ *
+ * 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.agent.annotations;
+
+import java.lang.annotation.Target;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+@Target(ElementType.FIELD)
+@Retention(RUNTIME)
+@Documented
+public @interface QMFAgent
+{
+}
diff --git a/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/annotations/QMFEvent.java b/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/annotations/QMFEvent.java
new file mode 100644
index 0000000000..314f2a7e68
--- /dev/null
+++ b/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/annotations/QMFEvent.java
@@ -0,0 +1,42 @@
+/*
+ *
+ * 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.agent.annotations;
+
+import static java.lang.annotation.ElementType.TYPE;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+/**
+ * Tells the QMF Agent that this object will be passed as a QMF event. This will
+ * cause only properties to be sent across the wire.
+ */
+@Target(TYPE)
+@Retention(RUNTIME)
+@Documented
+public @interface QMFEvent
+{
+ String eventName();
+
+ String packageName();
+}
diff --git a/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/annotations/QMFHide.java b/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/annotations/QMFHide.java
new file mode 100644
index 0000000000..db6cb0412f
--- /dev/null
+++ b/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/annotations/QMFHide.java
@@ -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.
+ *
+ */
+package org.apache.qpid.agent.annotations;
+
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+/**
+ * Causes the property which is annotated to not be added to the QMF schema when
+ * it is built.
+ */
+@Target(ElementType.METHOD)
+@Retention(RUNTIME)
+@Documented
+public @interface QMFHide
+{
+}
diff --git a/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/annotations/QMFObject.java b/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/annotations/QMFObject.java
new file mode 100644
index 0000000000..7d1713cdbe
--- /dev/null
+++ b/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/annotations/QMFObject.java
@@ -0,0 +1,42 @@
+/*
+ *
+ * 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.agent.annotations;
+
+import static java.lang.annotation.ElementType.TYPE;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+/**
+ * Tells the QMF Agent that this object will be a managed object. This will
+ * allow users to query for it, as well as invoke methods on it.
+ */
+@Target(TYPE)
+@Retention(RUNTIME)
+@Documented
+public @interface QMFObject
+{
+ String className();
+
+ String packageName();
+}
diff --git a/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/annotations/QMFProperty.java b/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/annotations/QMFProperty.java
new file mode 100644
index 0000000000..f309fa95b5
--- /dev/null
+++ b/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/annotations/QMFProperty.java
@@ -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.
+ *
+ */
+package org.apache.qpid.agent.annotations;
+
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+/**
+ * Controls the QMF schema which is generated for this property.
+ */
+@Target(ElementType.FIELD)
+@Retention(RUNTIME)
+@Documented
+public @interface QMFProperty
+{
+ boolean optional() default false;
+}
diff --git a/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/annotations/QMFSeeAlso.java b/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/annotations/QMFSeeAlso.java
new file mode 100644
index 0000000000..bb9b87805d
--- /dev/null
+++ b/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/annotations/QMFSeeAlso.java
@@ -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.
+ *
+ */
+package org.apache.qpid.agent.annotations;
+
+import static java.lang.annotation.ElementType.TYPE;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+/**
+ * Augements the schema generation process to look for known subclasses of a
+ * type. Modeled after the JAXB @XMLSeeAlso.
+ */
+@Target(TYPE)
+@Retention(RUNTIME)
+@Documented
+public @interface QMFSeeAlso
+{
+ Class[] value();
+}
diff --git a/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/annotations/QMFType.java b/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/annotations/QMFType.java
new file mode 100644
index 0000000000..8da1e15124
--- /dev/null
+++ b/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/annotations/QMFType.java
@@ -0,0 +1,42 @@
+/*
+ *
+ * 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.agent.annotations;
+
+import static java.lang.annotation.ElementType.TYPE;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+/**
+ * Tells the QMF Agent that this object will be a type only This will cause only
+ * properties to be sent across the wire.
+ */
+@Target(TYPE)
+@Retention(RUNTIME)
+@Documented
+public @interface QMFType
+{
+ String className();
+
+ String packageName();
+}
diff --git a/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/binding/BindingContext.java b/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/binding/BindingContext.java
new file mode 100644
index 0000000000..a60178e8b9
--- /dev/null
+++ b/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/binding/BindingContext.java
@@ -0,0 +1,213 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.agent.binding;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Hashtable;
+import java.util.List;
+import java.util.Map;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.qpid.agent.annotations.QMFEvent;
+import org.apache.qpid.agent.annotations.QMFObject;
+import org.apache.qpid.agent.annotations.QMFSeeAlso;
+import org.apache.qpid.agent.annotations.QMFType;
+
+/**
+ * Contains the mappings from java classes to QMF schema and back. There is one
+ * context per agent, and it contains all the metadata.
+ */
+public class BindingContext
+{
+ private static Log log = LogFactory.getLog(BindingContext.class);
+ private Map<Key, ClassBinding> classes = new Hashtable<Key, ClassBinding>();
+ private ArrayList<String> packages = new ArrayList<String>();
+
+ static class Key
+ {
+ String packageName = "";
+ String className = "";
+ boolean object = false;
+
+ @Override
+ public int hashCode()
+ {
+ return (packageName + "." + className).hashCode();
+ }
+
+ @Override
+ public boolean equals(Object obj)
+ {
+ return (obj instanceof Key
+ && (((Key) obj).packageName.equals(packageName)) && (((Key) obj).className
+ .equals(className)));
+ }
+ }
+
+ public BindingContext()
+ {
+ Key key = new Key();
+ key.className = "Object";
+ key.packageName = "org.apache.qmf";
+ key.object = false;
+ ClassBinding cb = new ClassBinding("org.apache.qmf", "Object",
+ Object.class, false, this);
+ classes.put(key, cb);
+ packages.add("org.apache.qmf");
+ }
+
+ public ClassBinding getClassBinding(Class clazz)
+ {
+ return classes.get(getClassKey(clazz));
+ }
+
+ public ClassBinding getClassBinding(String packageName, String className)
+ {
+ Key key = new Key();
+ key.packageName = packageName;
+ key.className = className;
+ return classes.get(key);
+ }
+
+ public ClassBinding register(Class cls)
+ {
+ String name = cls.getName();
+ ClassBinding cb = getClassBinding(cls);
+ if (cb == null)
+ {
+ Key key = getClassKey(cls);
+ // Create and store the internal representations
+ if (cls.isEnum())
+ {
+ cb = new EnumBinding(key.packageName, key.className, cls,
+ key.object, this);
+ } else
+ {
+ cb = new ClassBinding(key.packageName, key.className, cls,
+ key.object, this);
+ }
+ log.debug(String.format(
+ "Added class binding '%s' in package %s for class %s'",
+ key.className, key.packageName, cls.getCanonicalName()));
+ classes.put(key, cb);
+ if (!packages.contains(key.packageName))
+ {
+ packages.add(key.packageName);
+ }
+ // Parse the methods after adding the class to avoid recursion
+ cb.parse();
+ // See if there are other classes which should be looked at
+ QMFSeeAlso seeAlso = (QMFSeeAlso) cls
+ .getAnnotation(QMFSeeAlso.class);
+ if (seeAlso != null)
+ {
+ for (Class seeAlsoCls : seeAlso.value())
+ {
+ this.register(seeAlsoCls);
+ }
+ }
+ }
+ return cb;
+ }
+
+ public TypeBinding getTypeBinding(Class cls)
+ {
+ // Look for a built in type
+ TypeBinding type = QMFTypeBinding.forClass(cls);
+ // Have we seen it before?
+ if (type == null)
+ {
+ type = this.getClassBinding(cls);
+ }
+ if ((type == null) && List.class.isAssignableFrom(cls))
+ {
+ type = new ListBinding(this, cls);
+ }
+ if ((type == null) && Map.class.isAssignableFrom(cls))
+ {
+ type = new MapBinding(this, cls);
+ }
+ // Add it, but since we have not seen it before do not expose methods
+ if (type == null)
+ {
+ type = this.register(cls);
+ }
+ return type;
+ }
+
+ // FIXME: Need to store these keys off so we dont create alot of objects
+ protected Key getClassKey(Class cls)
+ {
+ Key key = new Key();
+ QMFObject objAnnotation = (QMFObject) cls
+ .getAnnotation(QMFObject.class);
+ if (objAnnotation != null)
+ {
+ key.className = objAnnotation.className();
+ key.packageName = objAnnotation.packageName();
+ key.object = true;
+ } else
+ {
+ QMFType typeAnnotation = (QMFType) cls.getAnnotation(QMFType.class);
+ if (typeAnnotation != null)
+ {
+ key.className = typeAnnotation.className();
+ key.packageName = typeAnnotation.packageName();
+ } else
+ {
+ QMFEvent eventAnnotation = (QMFEvent) cls
+ .getAnnotation(QMFEvent.class);
+ if (eventAnnotation != null)
+ {
+ key.className = eventAnnotation.eventName();
+ key.packageName = eventAnnotation.packageName();
+ } else
+ {
+ // If this is Object, we return the fake
+ // object value
+ if (cls == Object.class)
+ {
+ key.className = "Object";
+ key.packageName = "org.apache.qmf";
+ } else
+ {
+ String name = cls.getName();
+ int lastDot = name.lastIndexOf('.');
+ key.className = name.substring(lastDot + 1);
+ key.packageName = name.substring(0, lastDot);
+ }
+ }
+ }
+ }
+ return key;
+ }
+
+ public ArrayList<String> getPackages()
+ {
+ return packages;
+ }
+
+ public Collection<ClassBinding> getAllBindings()
+ {
+ return classes.values();
+ }
+}
diff --git a/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/binding/BindingException.java b/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/binding/BindingException.java
new file mode 100644
index 0000000000..f8e436290c
--- /dev/null
+++ b/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/binding/BindingException.java
@@ -0,0 +1,50 @@
+/*
+ *
+ * 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.agent.binding;
+
+/**
+ * ManagedException
+ *
+ */
+public class BindingException extends RuntimeException
+{
+ private static final long serialVersionUID = -7350845525748113340L;
+
+ public BindingException(Throwable t)
+ {
+ super(t);
+ }
+
+ public BindingException()
+ {
+ super();
+ }
+
+ public BindingException(String message, Throwable cause)
+ {
+ super(message, cause);
+ }
+
+ public BindingException(String message)
+ {
+ super(message);
+ }
+}
diff --git a/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/binding/BindingUtils.java b/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/binding/BindingUtils.java
new file mode 100644
index 0000000000..14f3fda0f1
--- /dev/null
+++ b/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/binding/BindingUtils.java
@@ -0,0 +1,137 @@
+/*
+ *
+ * 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.agent.binding;
+
+import java.beans.BeanInfo;
+import java.beans.Introspector;
+import java.beans.PropertyDescriptor;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.List;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+public class BindingUtils
+{
+ private static Log log = LogFactory.getLog(BindingUtils.class);
+
+ public static Object get(PropertyBinding property, Object managed)
+ {
+ String name = property.getName();
+ return get(name, managed);
+ }
+
+ public static void set(PropertyBinding property, Object value,
+ Object managed)
+ {
+ String name = property.getName();
+ TypeBinding type = property.getType();
+ try
+ {
+ Method meth = managed.getClass().getMethod(accessor("set", name),
+ type.getJavaClass());
+ meth.invoke(managed, value);
+ } catch (NoSuchMethodException e)
+ {
+ throw new BindingException(e);
+ } catch (IllegalAccessException e)
+ {
+ throw new BindingException(e);
+ } catch (InvocationTargetException e)
+ {
+ throw new BindingException(e.getTargetException());
+ }
+ }
+
+ public static Object[] invoke(MethodBinding method, Object managed,
+ Object... args)
+ {
+ log.debug(String.format("Invoking %s on %s", method.getName(), managed
+ .getClass()));
+ List<ParameterBinding> in = method.getInParameters();
+ List<ParameterBinding> out = method.getOutParameters();
+ Class<?>[] classes = new Class<?>[in.size()];
+ int idx = 0;
+ for (ParameterBinding p : in)
+ {
+ classes[idx++] = p.getType().getJavaClass();
+ }
+ Object result;
+ try
+ {
+ Method meth = managed.getClass().getMethod(method.getName(),
+ classes);
+ result = meth.invoke(managed, args);
+ } catch (NoSuchMethodException e)
+ {
+ throw new BindingException(e);
+ } catch (IllegalAccessException e)
+ {
+ throw new BindingException(e);
+ } catch (InvocationTargetException e)
+ {
+ throw new BindingException(e.getTargetException());
+ }
+ Object[] results = new Object[out.size()];
+ // XXX: need better way to distinguish this case
+ if (out.size() == 1 && out.get(0).getName().equals("result"))
+ {
+ results[0] = result;
+ } else
+ {
+ for (int i = 0; i < results.length; i++)
+ {
+ results[i] = get(out.get(i).getName(), result);
+ }
+ }
+ return results;
+ }
+
+ public static String accessor(String pfx, String property)
+ {
+ return pfx + Character.toUpperCase(property.charAt(0))
+ + property.substring(1);
+ }
+
+ public static Object get(String name, Object obj)
+ {
+ Object returnValue = null;
+ try
+ {
+ BeanInfo info = Introspector.getBeanInfo(obj.getClass());
+ PropertyDescriptor[] pds = info.getPropertyDescriptors();
+ for (PropertyDescriptor pd : pds)
+ {
+ if (pd.getName().equals(name))
+ {
+ Method getMethod = pd.getReadMethod();
+ returnValue = getMethod.invoke(obj);
+ break;
+ }
+ }
+ } catch (Exception e)
+ {
+ throw new BindingException(e);
+ }
+ return returnValue;
+ }
+}
diff --git a/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/binding/ClassBinding.java b/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/binding/ClassBinding.java
new file mode 100644
index 0000000000..469939a52f
--- /dev/null
+++ b/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/binding/ClassBinding.java
@@ -0,0 +1,601 @@
+/*
+ *
+ * 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.agent.binding;
+
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.qpid.agent.annotations.QMFEvent;
+import org.apache.qpid.agent.annotations.QMFObject;
+import org.apache.qpid.agent.annotations.QMFProperty;
+import org.apache.qpid.agent.annotations.QMFSeeAlso;
+import org.apache.qpid.agent.annotations.QMFType;
+import org.apache.qpid.agent.annotations.QMFHide;
+import org.apache.qpid.transport.codec.Decoder;
+import org.apache.qpid.transport.codec.Encoder;
+
+/**
+ * Binding information from a custom java class to a QMF schema
+ */
+public class ClassBinding implements TypeBinding
+{
+ private static final Log log = LogFactory.getLog(ClassBinding.class);
+
+ private static enum MethodType
+ {
+ READ_ONLY, READ_WRITE, METHOD, IGNORE
+ }
+
+ protected boolean exposeBehaviour = true;
+ protected String pkg;
+ protected BindingContext bctx;
+ protected String name;
+ protected ArrayList<PropertyBinding> properties = new ArrayList<PropertyBinding>();
+ protected ArrayList<MethodBinding> methods = new ArrayList<MethodBinding>();
+ protected Map<String, MethodBinding> methodsByName = new HashMap<String, MethodBinding>();
+ protected Class javaClass;
+ protected short kind = 1;
+ protected byte hash[] = null;
+ protected ClassBinding superType = null;
+
+ public ClassBinding(String pkg, String name, Class cls,
+ boolean exposeBehaviour, BindingContext bctx)
+ {
+ this.pkg = pkg;
+ this.name = name;
+ this.bctx = bctx;
+ this.javaClass = cls;
+ this.exposeBehaviour = exposeBehaviour;
+ }
+
+ protected MethodType classify(Class<?> cls, Method m)
+ {
+ String name = m.getName();
+ MethodType returnValue = MethodType.METHOD;
+ String propPrefixes[] =
+ { "get", "is" };
+ for (String prefix : propPrefixes)
+ {
+ if (name.startsWith(prefix) && m.getParameterTypes().length == 0)
+ {
+ try
+ {
+ Class<?> type = m.getReturnType();
+ Method setter = cls.getMethod("set"
+ + name.substring(prefix.length()), type);
+ returnValue = MethodType.READ_WRITE;
+ } catch (NoSuchMethodException e)
+ {
+ returnValue = MethodType.READ_ONLY;
+ }
+ break;
+ }
+ }
+ return returnValue;
+ }
+
+ protected String property(Method m)
+ {
+ String name = m.getName();
+ String propPrefixes[] =
+ { "get", "is" };
+ for (String prefix : propPrefixes)
+ {
+ if (name.startsWith(prefix) && m.getParameterTypes().length == 0)
+ {
+ String sfx = name.substring(prefix.length());
+ return Character.toLowerCase(sfx.charAt(0)) + sfx.substring(1);
+ }
+ }
+ // If we got here, it is n invalid property
+ throw new IllegalArgumentException("" + m);
+ }
+
+ protected ArrayList<Method> getMethods(Class cls)
+ {
+ ArrayList returnValue = new ArrayList();
+ ArrayList nameList = new ArrayList();
+ if ((cls != null) && (!cls.equals(Object.class)))
+ {
+ for (Method m : cls.getDeclaredMethods())
+ {
+ if (m.getAnnotation(QMFHide.class) == null)
+ // && (!Modifier.isAbstract(m.getModifiers())))
+ {
+ returnValue.add(m);
+ nameList.add(m.getName());
+ }
+ }
+ // Look at the superclass, if it is also a
+ // QMF object then stop.
+ if (!this.hasQMFSupertype(cls))
+ {
+ for (Method m : this.getMethods(cls.getSuperclass()))
+ {
+ if (!nameList.contains(m.getName()))
+ {
+ returnValue.add(m);
+ nameList.add(m.getName());
+ }
+ }
+ }
+ }
+ return returnValue;
+ }
+
+ protected boolean hasQMFSupertype(Class cls)
+ {
+ boolean returnValue = false;
+ Class superType = cls.getSuperclass();
+ if (superType != null)
+ {
+ if ((superType.getAnnotation(QMFObject.class) != null)
+ || (superType.getAnnotation(QMFType.class) != null)
+ || (superType.getAnnotation(QMFSeeAlso.class) != null)
+ || (superType.getAnnotation(QMFEvent.class) != null))
+ {
+ returnValue = true;
+ }
+ }
+ return returnValue;
+ }
+
+ protected boolean isOptional(Method m, TypeBinding type)
+ {
+ boolean returnValue = false;
+ // Look for the annotaiton first
+ QMFProperty ann = m.getAnnotation(QMFProperty.class);
+ if (ann != null)
+ {
+ returnValue = ann.optional();
+ } else
+ {
+ returnValue = type.optionalDefault();
+ }
+ return returnValue;
+ }
+
+ public ClassBinding parse()
+ {
+ log.debug(String.format(
+ "Parsing class binding '%s' for package '%s' from class %s",
+ name, pkg, javaClass.getName()));
+ for (Method m : this.getMethods(javaClass))
+ {
+ String mname = m.getName();
+ Class<?> type = m.getReturnType();
+ switch (classify(javaClass, m))
+ {
+ case READ_ONLY:
+ TypeBinding tb = bctx.getTypeBinding(type);
+ boolean optional = isOptional(m, tb);
+ properties.add(new PropertyBinding(property(m), tb,
+ PropertyBinding.READ_ONLY, optional));
+ break;
+ case READ_WRITE:
+ TypeBinding tbnd = bctx.getTypeBinding(type);
+ boolean opt = isOptional(m, tbnd);
+ properties.add(new PropertyBinding(property(m), tbnd,
+ PropertyBinding.READ_WRITE, opt));
+ break;
+ case METHOD:
+ // Only expose methods if told to
+ if (exposeBehaviour)
+ {
+ List<ParameterBinding> params = new ArrayList<ParameterBinding>();
+ int arg = 0;
+ for (Class pcls : m.getParameterTypes())
+ {
+ params.add(new ParameterBinding("arg" + arg++, bctx
+ .getTypeBinding(pcls), true, false));
+ }
+ if (type != void.class)
+ {
+ params.add(new ParameterBinding("result", bctx
+ .getTypeBinding(type), false, true));
+ }
+ methods.add(new MethodBinding(mname, params));
+ }
+ break;
+ case IGNORE:
+ break;
+ }
+ }
+ for (MethodBinding m : methods)
+ {
+ methodsByName.put(m.getName(), m);
+ }
+ QMFEvent eventAnnotation = (QMFEvent) javaClass
+ .getAnnotation(QMFEvent.class);
+ if (eventAnnotation != null)
+ {
+ kind = 2; // Event Type
+ }
+ // if (this.hasQMFSupertype(javaClass)) {
+ if ((javaClass.getSuperclass() != Object.class)
+ && (javaClass.getSuperclass() != null))
+ {
+ superType = bctx.register(javaClass.getSuperclass());
+ }
+ return this;
+ }
+
+ public String getPackage()
+ {
+ return pkg;
+ }
+
+ public String getName()
+ {
+ return name;
+ }
+
+ public List<PropertyBinding> getProperties()
+ {
+ return properties;
+ }
+
+ public List<PropertyBinding> getAllProperties()
+ {
+ if (this.superType == null)
+ {
+ return properties;
+ } else
+ {
+ List<PropertyBinding> newList = new ArrayList<PropertyBinding>(
+ properties);
+ for (PropertyBinding p : superType.getAllProperties())
+ {
+ if (!newList.contains(p))
+ {
+ newList.add(p);
+ }
+ }
+ return newList;
+ }
+ }
+
+ public List<MethodBinding> getMethods()
+ {
+ return methods;
+ }
+
+ public MethodBinding getMethod(String name)
+ {
+ return methodsByName.get(name);
+ }
+
+ // Use this format
+ // bytes value
+ // 0-3 package name
+ // 4-7 class name
+ // 8-11 property signature hash
+ // 12-15 method signature hash
+ // FIXME: Hash codes seem to mess things up
+ public byte[] getSchemaHash()
+ {
+ if (null == hash)
+ {
+ hash = new byte[16];
+ StringBuilder blder = new StringBuilder();
+ int packageHash = pkg.hashCode();
+ int classHash = name.hashCode();
+ int propertyHash = 0;
+ int methodHash = 0;
+ for (PropertyBinding p : properties)
+ {
+ blder.append(p.getName()).append(":").append(
+ p.getType().getCode()).append(":")
+ .append(p.getAccess()).append(":").append(
+ p.isOptional());
+ }
+ propertyHash = blder.toString().hashCode();
+ blder = new StringBuilder();
+ for (MethodBinding m : methods)
+ {
+ blder.append(m.getName());
+ for (ParameterBinding p : m.getParameters())
+ {
+ String direction = p.isIn() ? "in" : "out";
+ blder.append(":").append(p.getName()).append(":").append(
+ direction).append(":")
+ .append(p.getType().getCode());
+ }
+ }
+ methodHash = blder.toString().hashCode();
+ hash[0] = (byte) (packageHash >> 24);
+ hash[1] = (byte) (packageHash >> 16);
+ hash[2] = (byte) (packageHash >> 8);
+ hash[3] = (byte) (packageHash);
+ hash[4] = (byte) (classHash >> 24);
+ hash[5] = (byte) (classHash >> 16);
+ hash[6] = (byte) (classHash >> 8);
+ hash[7] = (byte) (classHash);
+ hash[8] = (byte) (propertyHash >> 24);
+ hash[9] = (byte) (propertyHash >> 16);
+ hash[10] = (byte) (propertyHash >> 8);
+ hash[11] = (byte) (propertyHash);
+ hash[12] = (byte) (methodHash >> 24);
+ hash[13] = (byte) (methodHash >> 16);
+ hash[14] = (byte) (methodHash >> 8);
+ hash[15] = (byte) (methodHash);
+ }
+ return hash;
+ }
+
+ public void encode(Encoder enc)
+ {
+ log.debug(String.format("encoding %s %s with superclass %s", this
+ .getRefClass(), this.getRefPackage(), superType));
+ enc.writeUint8(kind); // kind
+ enc.writeStr8(pkg);
+ enc.writeStr8(name);
+ enc.writeBin128(this.getSchemaHash()); // schema hash
+ // Send true (1) if we have a super-type
+ //if (superType == null)
+ //{
+ // enc.writeUint8((short) 0);
+ //} else
+ //{
+ // enc.writeUint8((short) 1);
+ //}
+ enc.writeUint16(properties.size());
+ // Events do not have the method size sent
+ if (kind == 1)
+ {
+ enc.writeUint16(0);
+ enc.writeUint16(methods.size());
+ }
+ // Add the super type information if we have it
+ //if (superType != null)
+ //{
+ // enc.writeStr8(superType.pkg);
+ // enc.writeStr8(superType.name);
+ // enc.writeBin128(superType.getSchemaHash()); // schema hash
+ //}
+ for (PropertyBinding p : properties)
+ {
+ log.trace("encoding property " + p.getName());
+ p.encode(enc);
+ }
+ for (MethodBinding m : methods)
+ {
+ m.encode(enc);
+ }
+ }
+
+ // Type Binding functions
+ public short getCode()
+ {
+ return (short) 20;
+ }
+
+ public Class<?> getJavaClass()
+ {
+ return javaClass;
+ }
+
+ public Object decode(Decoder dec)
+ {
+ // FIXME This only works with POJOs
+ short typeCode = dec.readUint8();
+ log.trace("Type code: " + typeCode);
+ if (typeCode == 20)
+ {
+ String packageName = dec.readStr8();
+ String className = dec.readStr8();
+ log
+ .debug(String
+ .format(
+ "Decoding an object for package %s class %s with bindings for %s %s",
+ packageName, className, this.pkg, this.name));
+ byte schemaHash[] = dec.readBin128();
+ // Check to see that this is me, and not a subclass
+ if (packageName.equals(this.pkg) && className.equals(this.name))
+ {
+ return decodeWithNoHeaders(dec);
+ } else
+ {
+ ClassBinding mcls = bctx
+ .getClassBinding(packageName, className);
+ return mcls.decodeWithNoHeaders(dec);
+ }
+ } else
+ {
+ TypeBinding tb = QMFTypeBinding.getType(typeCode);
+ return tb.decode(dec);
+ }
+ }
+
+ protected Object decodeWithNoHeaders(Decoder dec)
+ {
+ Object instance = null;
+ try
+ {
+ log.trace("Creating a new instance of " + this.javaClass.getName());
+ instance = this.javaClass.newInstance();
+ } catch (Exception e)
+ {
+ log.error("Could not instantiate object of class"
+ + this.javaClass.getName());
+ throw new BindingException(e);
+ }
+ List<String> excludes = this.processPresenceMasks(dec);
+ for (PropertyBinding p : getAllProperties())
+ {
+ if (!excludes.contains(p.getName()))
+ {
+ Object value = p.getType().decode(dec);
+ BindingUtils.set(p, value, instance);
+ }
+ }
+ return instance;
+ }
+
+ protected List<String> processPresenceMasks(Decoder dec)
+ {
+ List<String> excludes = new ArrayList<String>();
+ short bit = 0;
+ short mask = 0;
+ for (PropertyBinding prop : properties)
+ {
+ if (prop.isOptional())
+ {
+ if (bit == 0)
+ {
+ mask = dec.readUint8();
+ bit = 1;
+ }
+ if ((mask & bit) == 0)
+ {
+ log.trace("Going in exclude " + prop.getName());
+ excludes.add(prop.getName());
+ }
+ bit *= 2;
+ if (bit == 256)
+ {
+ bit = 0;
+ }
+ }
+ }
+ return excludes;
+ }
+
+ public void encode(Encoder enc, Object value)
+ {
+ // if the object is null, assume this is the
+ // correct class
+ if (value == null || (value.getClass().equals(this.javaClass)))
+ {
+ String pkg = getPackage();
+ String cls = getName();
+ log.debug(String.format("Encoding class %s:%s", pkg, cls));
+ enc.writeUint8(this.getCode());
+ enc.writeStr8(pkg);
+ enc.writeStr8(cls);
+ enc.writeBin128(this.getSchemaHash());
+ short bit = 0;
+ short mask = 0;
+ if (value != null)
+ {
+ // Encode the property presence masks first.
+ // if this is not an event
+ if (!isEvent())
+ {
+ for (PropertyBinding p : getAllProperties())
+ {
+ if (p.isOptional())
+ {
+ Object pValue = BindingUtils.get(p, value);
+ if (bit == 0)
+ bit = 1;
+ if (pValue != null)
+ {
+ mask |= bit;
+ }
+ if (bit == 128)
+ {
+ enc.writeUint8(mask);
+ bit = 0;
+ mask = 0;
+ } else
+ {
+ bit = (short) (bit << 1);
+ }
+ }
+ }
+ if (bit != 0)
+ {
+ enc.writeUint8(mask);
+ }
+ }
+ // Now put the actual properties
+ for (PropertyBinding p : getAllProperties())
+ {
+ Object pValue = BindingUtils.get(p, value);
+ if (!p.isOptional() || !(pValue == null))
+ {
+ log.trace(String.format("Encoding property %s", p
+ .getName()));
+ p.getType().encode(enc, pValue);
+ }
+ }
+ }
+ log.debug(String.format("Done with %s:%s", pkg, cls));
+ } else
+ {
+ TypeBinding tb = bctx.getTypeBinding(value.getClass());
+ if (tb == null)
+ {
+ throw new BindingException(String.format(
+ "No class named %s defined for this context ", value
+ .getClass()));
+ } else
+ {
+ if (tb.isNative())
+ {
+ enc.writeUint8(tb.getCode());
+ }
+ tb.encode(enc, value);
+ }
+ }
+ }
+
+ public boolean isNative()
+ {
+ return false;
+ }
+
+ public boolean optionalDefault()
+ {
+ return true;
+ }
+
+ public String getRefClass()
+ {
+ return this.name;
+ }
+
+ public String getRefPackage()
+ {
+ return this.pkg;
+ }
+
+ public short getKind()
+ {
+ return kind;
+ }
+
+ public boolean isEvent()
+ {
+ return kind == 2;
+ }
+
+ public void setKind(short kind)
+ {
+ this.kind = kind;
+ }
+}
diff --git a/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/binding/EnumBinding.java b/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/binding/EnumBinding.java
new file mode 100644
index 0000000000..dcb619b736
--- /dev/null
+++ b/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/binding/EnumBinding.java
@@ -0,0 +1,108 @@
+/*
+ *
+ * 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.agent.binding;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.qpid.transport.codec.Decoder;
+import org.apache.qpid.transport.codec.Encoder;
+
+/**
+ * Binding information from a java enum to a QMF schema
+ */
+public class EnumBinding extends ClassBinding
+{
+ private static Log log = LogFactory.getLog(EnumBinding.class);
+
+ public EnumBinding(String pkg, String name, Class cls,
+ boolean exposeBehaviour, BindingContext bctx)
+ {
+ super(pkg, name, cls, exposeBehaviour, bctx);
+ }
+
+ @Override
+ public void encode(Encoder enc)
+ {
+ enc.writeUint8((short) 1); // kind
+ enc.writeStr8(pkg);
+ enc.writeStr8(name);
+ enc.writeBin128(new byte[16]); // schema hash
+ // FIXME Is there a way to send the valid types?
+ }
+
+ @Override
+ public void encode(Encoder enc, Object value)
+ {
+ if (value != null)
+ {
+ enc.writeStr16(value.toString());
+ } else
+ {
+ enc.writeStr16("");
+ }
+ }
+
+ @Override
+ public Object decode(Decoder dec)
+ {
+ // FIXME This only works with POJOs
+ Object instance = null;
+ String value = null;
+ try
+ {
+ value = dec.readStr16();
+ if ((value != null) && (!value.isEmpty()))
+ {
+ instance = Enum.valueOf((Class<Enum>) this.getJavaClass(),
+ value);
+ }
+ } catch (Exception e)
+ {
+ log.error(String.format(
+ "Could not create an enum of type %s with value %s",
+ this.javaClass.getName(), value));
+ throw new BindingException(e);
+ }
+ return instance;
+ }
+
+ // Make this look like a String
+ @Override
+ public short getCode()
+ {
+ return (short) 7;
+ }
+
+ @Override
+ public EnumBinding parse()
+ {
+ log.debug(String.format(
+ "Parsing enum binding '%s' for package '%s' from class %s",
+ name, pkg, javaClass.getName()));
+ return this;
+ }
+
+ @Override
+ public boolean optionalDefault()
+ {
+ return false;
+ }
+}
diff --git a/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/binding/ListBinding.java b/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/binding/ListBinding.java
new file mode 100644
index 0000000000..a3658a812c
--- /dev/null
+++ b/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/binding/ListBinding.java
@@ -0,0 +1,131 @@
+/*
+ *
+ * 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.agent.binding;
+
+import java.nio.ByteBuffer;
+import java.util.List;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.qpid.transport.codec.BBDecoder;
+import org.apache.qpid.transport.codec.BBEncoder;
+import org.apache.qpid.transport.codec.Decoder;
+import org.apache.qpid.transport.codec.Encoder;
+
+/**
+ * Binding information from a java list to a QMF schema.
+ */
+public class ListBinding implements TypeBinding
+{
+ private static Log log = LogFactory.getLog(ListBinding.class);
+ protected BindingContext bctx;
+ protected Class javaClass;
+
+ public ListBinding(BindingContext bctx, Class javaClass)
+ {
+ this.bctx = bctx;
+ this.javaClass = javaClass;
+ }
+
+ public void encode(Encoder enc, Object value)
+ {
+ List list = (List) value;
+ BBEncoder newEncoder = new BBEncoder(10);
+ if (list != null)
+ {
+ newEncoder.writeUint32(list.size());
+ for (Object obj : list)
+ {
+ TypeBinding type = bctx.getTypeBinding(obj.getClass());
+ newEncoder.writeUint8(type.getCode());
+ type.encode(newEncoder, obj);
+ }
+ } else
+ {
+ newEncoder.writeUint32(0);
+ }
+ enc.writeVbin32(newEncoder.buffer().array());
+ }
+
+ public Object decode(Decoder dec)
+ {
+ List list = null;
+ try
+ {
+ list = (List) javaClass.newInstance();
+ } catch (Exception e)
+ {
+ throw new BindingException(
+ "Could not create a List implementation for "
+ + javaClass.getName(), e);
+ }
+ BBDecoder newDecoder = new BBDecoder();
+ newDecoder.init(ByteBuffer.wrap(dec.readVbin32()));
+ long count = newDecoder.readUint32();
+ while (count > 0)
+ {
+ short typeCode = newDecoder.readUint8();
+ TypeBinding type = QMFTypeBinding.getType(typeCode);
+ if (type == null)
+ {
+ type = bctx.getTypeBinding(Object.class);
+ }
+ list.add(type.decode(newDecoder));
+ count -= 1;
+ }
+ return list;
+ }
+
+ // QMF List Type
+ public short getCode()
+ {
+ return (short) 21;
+ }
+
+ @Override
+ public Class<?> getJavaClass()
+ {
+ return javaClass;
+ }
+
+ @Override
+ public String getRefClass()
+ {
+ return null;
+ }
+
+ @Override
+ public String getRefPackage()
+ {
+ return null;
+ }
+
+ @Override
+ public boolean isNative()
+ {
+ return true;
+ }
+
+ public boolean optionalDefault()
+ {
+ return false;
+ }
+}
diff --git a/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/binding/MapBinding.java b/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/binding/MapBinding.java
new file mode 100644
index 0000000000..02d562a59a
--- /dev/null
+++ b/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/binding/MapBinding.java
@@ -0,0 +1,95 @@
+/*
+ *
+ * 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.agent.binding;
+
+import java.nio.ByteBuffer;
+import java.util.HashMap;
+import java.util.Map;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.qpid.transport.codec.BBDecoder;
+import org.apache.qpid.transport.codec.BBEncoder;
+import org.apache.qpid.transport.codec.Decoder;
+import org.apache.qpid.transport.codec.Encoder;
+
+/**
+ * Binding information from a java Map to a QMF schema.
+ */
+public class MapBinding implements TypeBinding
+{
+ private static Log log = LogFactory.getLog(MapBinding.class);
+ protected BindingContext bctx;
+ protected Class javaClass;
+
+ public MapBinding(BindingContext bctx, Class javaClass)
+ {
+ this.bctx = bctx;
+ this.javaClass = javaClass;
+ }
+
+ @SuppressWarnings("unchecked")
+ public void encode(Encoder enc, Object value)
+ {
+ Map map = (Map) value;
+ enc.writeMap(map);
+ }
+
+ public Object decode(Decoder dec)
+ {
+ Map map = dec.readMap();
+ return map;
+ }
+
+ // QMF List Type
+ public short getCode()
+ {
+ return (short) 15;
+ }
+
+ @Override
+ public Class<?> getJavaClass()
+ {
+ return javaClass;
+ }
+
+ @Override
+ public String getRefClass()
+ {
+ return null;
+ }
+
+ @Override
+ public String getRefPackage()
+ {
+ return null;
+ }
+
+ @Override
+ public boolean isNative()
+ {
+ return true;
+ }
+
+ public boolean optionalDefault()
+ {
+ return false;
+ }
+}
diff --git a/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/binding/MethodBinding.java b/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/binding/MethodBinding.java
new file mode 100644
index 0000000000..fc05c7393a
--- /dev/null
+++ b/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/binding/MethodBinding.java
@@ -0,0 +1,91 @@
+/*
+ *
+ * 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.agent.binding;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.qpid.transport.codec.Encoder;
+
+/**
+ * Metadata for mapping a method to a QMF schema
+ */
+public class MethodBinding
+{
+ private final String name;
+ private final List<ParameterBinding> parameters;
+ private final List<ParameterBinding> inParameters = new ArrayList<ParameterBinding>();
+ private final List<ParameterBinding> outParameters = new ArrayList<ParameterBinding>();
+ private Log log = LogFactory.getLog(MethodBinding.class);
+
+ public MethodBinding(String name, List<ParameterBinding> parameters)
+ {
+ this.name = name;
+ this.parameters = parameters;
+ for (ParameterBinding p : parameters)
+ {
+ if (p.isIn())
+ {
+ inParameters.add(p);
+ }
+ if (p.isOut())
+ {
+ outParameters.add(p);
+ }
+ }
+ }
+
+ public String getName()
+ {
+ return name;
+ }
+
+ public List<ParameterBinding> getParameters()
+ {
+ return parameters;
+ }
+
+ public List<ParameterBinding> getInParameters()
+ {
+ return inParameters;
+ }
+
+ public List<ParameterBinding> getOutParameters()
+ {
+ return outParameters;
+ }
+
+ void encode(Encoder enc)
+ {
+ Map map = new HashMap();
+ map.put("name", name);
+ map.put("argCount", parameters.size());
+ enc.writeMap(map);
+ for (ParameterBinding p : parameters)
+ {
+ p.encode(enc);
+ }
+ }
+}
diff --git a/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/binding/ParameterBinding.java b/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/binding/ParameterBinding.java
new file mode 100644
index 0000000000..7362976e0e
--- /dev/null
+++ b/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/binding/ParameterBinding.java
@@ -0,0 +1,121 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.agent.binding;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.qpid.transport.codec.Encoder;
+
+/**
+ * Metadata for mapping a method argument to a QMF schema
+ */
+public class ParameterBinding
+{
+ private final String name;
+ private final TypeBinding type;
+ private final boolean in;
+ private final boolean out;
+
+ public ParameterBinding(String name, TypeBinding type, boolean in,
+ boolean out)
+ {
+ this.name = name;
+ this.type = type;
+ this.in = in;
+ this.out = out;
+ }
+
+ public String getName()
+ {
+ return name;
+ }
+
+ public TypeBinding getType()
+ {
+ return type;
+ }
+
+ public boolean isIn()
+ {
+ return in;
+ }
+
+ public boolean isOut()
+ {
+ return out;
+ }
+
+ void encode(Encoder enc)
+ {
+ Map map = new HashMap();
+ map.put("name", name);
+ map.put("type", type.getCode());
+ map.put("dir", (in ? "I" : "") + (out ? "O" : ""));
+ if (!type.isNative())
+ {
+ map.put("refClass", type.getRefClass());
+ map.put("refPackage", type.getRefPackage());
+ }
+ enc.writeMap(map);
+ }
+
+ @Override
+ public int hashCode()
+ {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + (in ? 1231 : 1237);
+ result = prime * result + ((name == null) ? 0 : name.hashCode());
+ result = prime * result + (out ? 1231 : 1237);
+ result = prime * result + ((type == null) ? 0 : type.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj)
+ {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ ParameterBinding other = (ParameterBinding) obj;
+ if (in != other.in)
+ return false;
+ if (name == null)
+ {
+ if (other.name != null)
+ return false;
+ } else if (!name.equals(other.name))
+ return false;
+ if (out != other.out)
+ return false;
+ if (type == null)
+ {
+ if (other.type != null)
+ return false;
+ } else if (!type.equals(other.type))
+ return false;
+ return true;
+ }
+}
diff --git a/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/binding/PropertyBinding.java b/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/binding/PropertyBinding.java
new file mode 100644
index 0000000000..604d66c818
--- /dev/null
+++ b/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/binding/PropertyBinding.java
@@ -0,0 +1,131 @@
+/*
+ *
+ * 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.agent.binding;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.qpid.transport.codec.Encoder;
+
+/**
+ * Metadata for mapping a java property (getter/setter) to a QMF schema
+ */
+public class PropertyBinding
+{
+ private static Log log = LogFactory.getLog(PropertyBinding.class);
+ public final static int READ_CREATE = 1;
+ public final static int READ_WRITE = 2;
+ public final static int READ_ONLY = 3;
+ private String name;
+ private TypeBinding type;
+ private int accessType;
+ private boolean optional;
+
+ public PropertyBinding(String name, TypeBinding type, int accessType,
+ boolean optional)
+ {
+ this.name = name;
+ this.type = type;
+ this.accessType = accessType;
+ this.optional = optional;
+ }
+
+ @Override
+ public int hashCode()
+ {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + accessType;
+ result = prime * result + ((name == null) ? 0 : name.hashCode());
+ result = prime * result + ((type == null) ? 0 : type.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj)
+ {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ PropertyBinding other = (PropertyBinding) obj;
+ if (accessType != other.accessType)
+ return false;
+ if (name == null)
+ {
+ if (other.name != null)
+ return false;
+ } else if (!name.equals(other.name))
+ return false;
+ if (type == null)
+ {
+ if (other.type != null)
+ return false;
+ } else if (!type.equals(other.type))
+ return false;
+ return true;
+ }
+
+ public String getName()
+ {
+ return name;
+ }
+
+ public TypeBinding getType()
+ {
+ return type;
+ }
+
+ public int getAccess()
+ {
+ return accessType;
+ }
+
+ public boolean isIndex()
+ {
+ return false;
+ }
+
+ public boolean isOptional()
+ {
+ return optional;
+ }
+
+ void encode(Encoder enc)
+ {
+ Map map = new HashMap();
+ map.put("name", name);
+ map.put("type", type.getCode());
+ map.put("access", getAccess());
+ map.put("index", isIndex() ? 1 : 0);
+ map.put("optional", isOptional() ? 1 : 0);
+ if (!type.isNative())
+ {
+ map.put("refClass", type.getRefClass());
+ map.put("refPackage", type.getRefPackage());
+ }
+ enc.writeMap(map);
+ }
+}
diff --git a/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/binding/QMFTypeBinding.java b/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/binding/QMFTypeBinding.java
new file mode 100644
index 0000000000..11ccf1b1a7
--- /dev/null
+++ b/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/binding/QMFTypeBinding.java
@@ -0,0 +1,465 @@
+/*
+ *
+ * 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.agent.binding;
+
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
+
+import org.apache.qpid.transport.codec.Decoder;
+import org.apache.qpid.transport.codec.Encoder;
+
+/**
+ * Basic type mappings for QMF schema
+ */
+public abstract class QMFTypeBinding implements TypeBinding
+{
+ private static final Map<Class<?>, QMFTypeBinding> TYPES = new HashMap<Class<?>, QMFTypeBinding>();
+ private static final Map<Short, QMFTypeBinding> TYPES_BY_CODE = new HashMap<Short, QMFTypeBinding>();
+ static
+ {
+ new QMFTypeBinding(null, (short) 1)
+ {
+ @Override
+ public Object decode(Decoder dec)
+ {
+ return Short.valueOf(dec.readUint8());
+ }
+
+ @Override
+ public void encode(Encoder enc, Object value)
+ {
+ enc.writeUint8(((Number) value).shortValue());
+ }
+ };
+ new QMFTypeBinding(null, (short) 2)
+ {
+ @Override
+ public Object decode(Decoder dec)
+ {
+ return Integer.valueOf(dec.readUint16());
+ }
+
+ @Override
+ public void encode(Encoder enc, Object value)
+ {
+ enc.writeUint16(((Number) value).intValue());
+ }
+ };
+ new QMFTypeBinding(null, (short) 3)
+ {
+ @Override
+ public Object decode(Decoder dec)
+ {
+ return Long.valueOf(dec.readUint32());
+ }
+
+ @Override
+ public void encode(Encoder enc, Object value)
+ {
+ enc.writeUint32(((Number) value).longValue());
+ }
+ };
+ new QMFTypeBinding(null, (short) 4)
+ {
+ @Override
+ public Object decode(Decoder dec)
+ {
+ return Long.valueOf(dec.readUint64());
+ }
+
+ @Override
+ public void encode(Encoder enc, Object value)
+ {
+ enc.writeUint64(((Number) value).longValue());
+ }
+ };
+ new QMFTypeBinding(null, (short) 6) // short string
+ {
+ @Override
+ public Object decode(Decoder dec)
+ {
+ return dec.readStr8();
+ }
+
+ @Override
+ public void encode(Encoder enc, Object value)
+ {
+ if (null == value)
+ value = "";
+ enc.writeStr8((String) value);
+ }
+ };
+ new QMFTypeBinding(String.class, (short) 7) // long string
+ {
+ @Override
+ public Object decode(Decoder dec)
+ {
+ return dec.readStr16();
+ }
+
+ @Override
+ public void encode(Encoder enc, Object value)
+ {
+ if (null == value)
+ value = "";
+ enc.writeStr16((String) value);
+ }
+ };
+ new QMFTypeBinding(Date.class, (short) 8)
+ {
+ @Override
+ public Object decode(Decoder dec)
+ {
+ return new Date(dec.readDatetime());
+ }
+
+ @Override
+ public void encode(Encoder enc, Object value)
+ {
+ enc.writeDatetime(((Date) value).getTime());
+ }
+ };
+ new QMFTypeBinding(Boolean.class, (short) 11)
+ {
+ @Override
+ public Object decode(Decoder dec)
+ {
+ return Boolean.valueOf(dec.readUint8() != 0);
+ }
+
+ @Override
+ public void encode(Encoder enc, Object value)
+ {
+ if (((Boolean) value).booleanValue())
+ {
+ enc.writeUint8((short) 1);
+ } else
+ {
+ enc.writeUint8((short) 0);
+ }
+ }
+
+ @Override
+ public short[] alternateTypes()
+ {
+ short[] types =
+ { 5 };
+ return types;
+ }
+ };
+ new QMFTypeBinding(boolean.class, (short) 11)
+ {
+ @Override
+ public Object decode(Decoder dec)
+ {
+ return dec.readUint8() != 0;
+ }
+
+ @Override
+ public void encode(Encoder enc, Object value)
+ {
+ if (((Boolean) value).booleanValue())
+ {
+ enc.writeUint8((short) 1);
+ } else
+ {
+ enc.writeUint8((short) 0);
+ }
+ }
+ };
+ new QMFTypeBinding(Float.class, (short) 12)
+ {
+ @Override
+ public Object decode(Decoder dec)
+ {
+ return Float.valueOf(dec.readFloat());
+ }
+
+ @Override
+ public void encode(Encoder enc, Object value)
+ {
+ enc.writeFloat(((Number) value).floatValue());
+ }
+ };
+ new QMFTypeBinding(float.class, (short) 12)
+ {
+ @Override
+ public Object decode(Decoder dec)
+ {
+ return dec.readFloat();
+ }
+
+ @Override
+ public void encode(Encoder enc, Object value)
+ {
+ enc.writeFloat(((Number) value).floatValue());
+ }
+ };
+ new QMFTypeBinding(Double.class, (short) 13)
+ {
+ @Override
+ public Object decode(Decoder dec)
+ {
+ return Double.valueOf(dec.readDouble());
+ }
+
+ @Override
+ public void encode(Encoder enc, Object value)
+ {
+ enc.writeDouble(((Number) value).doubleValue());
+ }
+ };
+ new QMFTypeBinding(double.class, (short) 13)
+ {
+ @Override
+ public Object decode(Decoder dec)
+ {
+ return dec.readDouble();
+ }
+
+ @Override
+ public void encode(Encoder enc, Object value)
+ {
+ enc.writeDouble(((Number) value).doubleValue());
+ }
+ };
+ new QMFTypeBinding(UUID.class, (short) 14)
+ {
+ @Override
+ public Object decode(Decoder dec)
+ {
+ return dec.readUuid();
+ }
+
+ @Override
+ public void encode(Encoder enc, Object value)
+ {
+ enc.writeUuid((UUID) value);
+ }
+ };
+ new QMFTypeBinding(byte.class, (short) 16)
+ {
+ @Override
+ public Object decode(Decoder dec)
+ {
+ return dec.readInt8();
+ }
+
+ @Override
+ public void encode(Encoder enc, Object value)
+ {
+ enc.writeInt8(((Number) value).byteValue());
+ }
+ };
+ new QMFTypeBinding(Short.class, (short) 17)
+ {
+ @Override
+ public Object decode(Decoder dec)
+ {
+ return Short.valueOf(dec.readInt16());
+ }
+
+ @Override
+ public void encode(Encoder enc, Object value)
+ {
+ enc.writeInt16(((Number) value).shortValue());
+ }
+ };
+ new QMFTypeBinding(short.class, (short) 17)
+ {
+ @Override
+ public Object decode(Decoder dec)
+ {
+ return dec.readInt16();
+ }
+
+ @Override
+ public void encode(Encoder enc, Object value)
+ {
+ enc.writeInt16(((Number) value).shortValue());
+ }
+ };
+ new QMFTypeBinding(Integer.class, (short) 18)
+ {
+ @Override
+ public Object decode(Decoder dec)
+ {
+ return Integer.valueOf(dec.readInt32());
+ }
+
+ @Override
+ public void encode(Encoder enc, Object value)
+ {
+ enc.writeInt32(((Number) value).intValue());
+ }
+ };
+ new QMFTypeBinding(int.class, (short) 18)
+ {
+ @Override
+ public Object decode(Decoder dec)
+ {
+ return dec.readInt32();
+ }
+
+ @Override
+ public void encode(Encoder enc, Object value)
+ {
+ enc.writeInt32(((Number) value).intValue());
+ }
+ };
+ new QMFTypeBinding(Long.class, (short) 19)
+ {
+ @Override
+ public Object decode(Decoder dec)
+ {
+ return Long.valueOf(dec.readInt64());
+ }
+
+ @Override
+ public void encode(Encoder enc, Object value)
+ {
+ enc.writeInt64(((Number) value).longValue());
+ }
+ };
+ new QMFTypeBinding(long.class, (short) 19)
+ {
+ @Override
+ public Object decode(Decoder dec)
+ {
+ return dec.readInt64();
+ }
+
+ @Override
+ public void encode(Encoder enc, Object value)
+ {
+ enc.writeInt64(((Number) value).longValue());
+ }
+ };
+ }
+
+ public static final QMFTypeBinding forClass(Class<?> cls)
+ {
+ QMFTypeBinding t = TYPES.get(cls);
+ return t;
+ }
+
+ public static final boolean isBound(Class<?> cls)
+ {
+ return TYPES.containsKey(cls);
+ }
+
+ public static QMFTypeBinding getType(short code)
+ {
+ return TYPES_BY_CODE.get(code);
+ }
+
+ private final Class<?> cls;
+ private final short code;
+
+ private QMFTypeBinding(Class<?> cls, short code)
+ {
+ this.cls = cls;
+ this.code = code;
+ if (cls != null)
+ {
+ TYPES.put(cls, this);
+ }
+ TYPES_BY_CODE.put(code, this);
+ for (short type : this.alternateTypes())
+ {
+ TYPES_BY_CODE.put(type, this);
+ }
+ }
+
+ public Class<?> getJavaClass()
+ {
+ return cls;
+ }
+
+ public short getCode()
+ {
+ return code;
+ }
+
+ public boolean isNative()
+ {
+ return true;
+ }
+
+ public boolean optionalDefault()
+ {
+ return false;
+ }
+
+ public String getRefClass()
+ {
+ return null;
+ }
+
+ public String getRefPackage()
+ {
+ return null;
+ }
+
+ public abstract Object decode(Decoder dec);
+
+ public abstract void encode(Encoder enc, Object value);
+
+ public short[] alternateTypes()
+ {
+ short[] types =
+ {};
+ return types;
+ }
+
+ @Override
+ public int hashCode()
+ {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((cls == null) ? 0 : cls.hashCode());
+ result = prime * result + code;
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj)
+ {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ QMFTypeBinding other = (QMFTypeBinding) obj;
+ if (cls == null)
+ {
+ if (other.cls != null)
+ return false;
+ } else if (!cls.equals(other.cls))
+ return false;
+ if (code != other.code)
+ return false;
+ return true;
+ }
+}
diff --git a/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/binding/TypeBinding.java b/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/binding/TypeBinding.java
new file mode 100644
index 0000000000..97ec943bfd
--- /dev/null
+++ b/qpid/java/management/agent/src/main/java/org/apache/qpid/agent/binding/TypeBinding.java
@@ -0,0 +1,46 @@
+/*
+ *
+ * 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.agent.binding;
+
+import org.apache.qpid.transport.codec.Decoder;
+import org.apache.qpid.transport.codec.Encoder;
+
+/**
+ * Binding between Java Type and QMF type
+ */
+public interface TypeBinding
+{
+ public Object decode(Decoder dec);
+
+ public void encode(Encoder enc, Object value);
+
+ public Class<?> getJavaClass();
+
+ public short getCode();
+
+ public boolean isNative();
+
+ public String getRefClass();
+
+ public String getRefPackage();
+
+ public boolean optionalDefault();
+}
diff --git a/qpid/java/management/agent/src/test/java/org/apache/qpid/agent/Crumpet.java b/qpid/java/management/agent/src/test/java/org/apache/qpid/agent/Crumpet.java
new file mode 100644
index 0000000000..67095c809b
--- /dev/null
+++ b/qpid/java/management/agent/src/test/java/org/apache/qpid/agent/Crumpet.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.agent;
+
+import java.util.ArrayList;
+
+import org.apache.qpid.agent.annotations.QMFSeeAlso;
+import org.apache.qpid.agent.annotations.QMFType;
+
+/**
+ * Crumpet
+ *
+ */
+@QMFType(className = "Crumpet", packageName = "org.apache.test")
+@QMFSeeAlso(
+{ Pikelet.class })
+public class Crumpet
+{
+ private String foo = "fooValue";
+ private String bar = "barValue";
+ private ArrayList<String> ingredients = new ArrayList<String>();
+
+ public String getFoo()
+ {
+ return foo;
+ }
+
+ public void setFoo(String foo)
+ {
+ this.foo = foo;
+ }
+
+ public String getBar()
+ {
+ return bar;
+ }
+
+ public void setBar(String bar)
+ {
+ this.bar = bar;
+ }
+
+ public ArrayList<String> getIngredients()
+ {
+ return ingredients;
+ }
+
+ public void setIngredients(ArrayList<String> ingredients)
+ {
+ this.ingredients = ingredients;
+ }
+}
diff --git a/qpid/java/management/agent/src/test/java/org/apache/qpid/agent/Muppet.java b/qpid/java/management/agent/src/test/java/org/apache/qpid/agent/Muppet.java
new file mode 100644
index 0000000000..f039ab9baa
--- /dev/null
+++ b/qpid/java/management/agent/src/test/java/org/apache/qpid/agent/Muppet.java
@@ -0,0 +1,113 @@
+/*
+ *
+ * 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.agent;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.qpid.agent.annotations.QMFObject;
+
+@QMFObject(className = "Muppet", packageName = "org.apache.test")
+public class Muppet extends Puppet
+{
+ private Log log = LogFactory.getLog(Muppet.class);
+
+ public String getSomething()
+ {
+ return "something";
+ }
+
+ public void doSomething(String str)
+ {
+ log.debug(String.format("doSomething: %s", str));
+ }
+
+ public String returnSomething()
+ {
+ log.debug("returning something");
+ return "asdf";
+ }
+
+ public Crumpet gimmieCrumpet(String asdf, int n, float f, Map foo)
+ {
+ log.debug(String
+ .format("mmm, crumpet: %s, %s, %s, %s", asdf, n, f, foo));
+ Crumpet crumpet = new Crumpet();
+ crumpet.getIngredients().add("Butter");
+ crumpet.getIngredients().add("Salt");
+ crumpet.getIngredients().add("Flour");
+ return crumpet;
+ }
+
+ public Crumpet gimmieCrumpet2()
+ {
+ Pikelet pik = new Pikelet();
+ pik.getIngredients().add("Butter");
+ pik.getIngredients().add("Salt");
+ pik.getIngredients().add("Eggs");
+ pik.getCrumpets().put("Crumpet1",
+ this.gimmieCrumpet("2121", 1, 1, null));
+ return pik;
+ }
+
+ public List gimmeLotsOfCrumpets()
+ {
+ log.debug("Asking for lots of Crumpets");
+ ArrayList<Crumpet> returnValue = new ArrayList<Crumpet>();
+ Crumpet crumpet = new Crumpet();
+ crumpet.getIngredients().add("Chocolate");
+ returnValue.add(crumpet);
+ crumpet = new Crumpet();
+ crumpet.getIngredients().add("Pecans");
+ returnValue.add(crumpet);
+ crumpet = new Pikelet();
+ crumpet.getIngredients().add("Poached Eggs");
+ returnValue.add(crumpet);
+ return returnValue;
+ }
+
+ public int divideByZero()
+ {
+ return 1 / 0;
+ }
+
+ public Crumpet takeCrumpet(Crumpet newCrumpet)
+ {
+ log.debug(String.format("I gots me a crumpet: foo: '%s' bar: '%s'",
+ newCrumpet.getFoo(), newCrumpet.getBar()));
+ log.debug("My crumpet's class is " + newCrumpet.getClass().getName());
+ for (String ingredient : newCrumpet.getIngredients())
+ {
+ log.debug("My crumpet is made of " + ingredient);
+ }
+ return newCrumpet;
+ }
+
+ public Object takeSomething(Object obj)
+ {
+ log.debug(String.format("I gots me a something: '%s'", obj.getClass()
+ .getName()));
+ return obj;
+ }
+}
diff --git a/qpid/java/management/agent/src/test/java/org/apache/qpid/agent/Pikelet.java b/qpid/java/management/agent/src/test/java/org/apache/qpid/agent/Pikelet.java
new file mode 100644
index 0000000000..f820fa6258
--- /dev/null
+++ b/qpid/java/management/agent/src/test/java/org/apache/qpid/agent/Pikelet.java
@@ -0,0 +1,52 @@
+/*
+ *
+ * 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.agent;
+
+import java.util.HashMap;
+
+import org.apache.qpid.agent.annotations.QMFType;
+
+@QMFType(className = "Pikelet", packageName = "org.apache.test")
+public class Pikelet extends Crumpet
+{
+ protected String shape;
+ HashMap<String, Crumpet> crumpets = new HashMap<String, Crumpet>();
+
+ public String getShape()
+ {
+ return shape;
+ }
+
+ public void setShape(String shape)
+ {
+ this.shape = shape;
+ }
+
+ public HashMap<String, Crumpet> getCrumpets()
+ {
+ return crumpets;
+ }
+
+ public void setCrumpets(HashMap<String, Crumpet> crumpets)
+ {
+ this.crumpets = crumpets;
+ }
+}
diff --git a/qpid/java/management/agent/src/test/java/org/apache/qpid/agent/Puppet.java b/qpid/java/management/agent/src/test/java/org/apache/qpid/agent/Puppet.java
new file mode 100644
index 0000000000..bfd34840f8
--- /dev/null
+++ b/qpid/java/management/agent/src/test/java/org/apache/qpid/agent/Puppet.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.agent;
+
+public class Puppet
+{
+ public int countStrings()
+ {
+ return 4;
+ }
+}
diff --git a/qpid/java/management/client/README.txt b/qpid/java/management/client/README.txt
new file mode 100644
index 0000000000..ecd61da75e
--- /dev/null
+++ b/qpid/java/management/client/README.txt
@@ -0,0 +1,42 @@
+QMan - Qpid JMX & WS-DM Management Bridge
+---------------------------------------------------------
+
+Documentation
+--------------
+All of our user documentation for QMan module can be accessed on our wiki at:
+
+http://cwiki.apache.org/qpid/qman-qpid-management-bridge.html
+
+This includes a Getting Started and User Guide as well as detailed developer documentation.
+However, here's a VERY quick guide to running QMan, once you have installed it somewhere !
+
+Running
+------------------
+
+Once you installed QMan, under the root folder you should have the following structure
+
+- bin (folder) : contains startup & shutdown scripts;
+- app (folder) : contains the web application module;
+- etc (folder) : contains configuration files;
+- examples (folder) : contains examples (and a nested README as well)
+- lib (folder) : contains dependency libraries;
+- log (folder) : this is the default log folder.
+
+To run QMan,
+
+1) edit the $QMAN_HOME/etc/qman-config.xml file and configure broker connection data (host,port, username, etc...)
+2) under the $QMAN_HOME/bin directory run :
+
+> ./qman-wsdm-start.sh
+
+now, under $QMAN_HOME/log directory you should see two files :
+
+1) server.log : contains web server log messages;
+2) qman.log : contains qman log messages;
+
+Administration
+-----------------------
+
+After QMan has been started successfully you can browse its administration console pointing your browser to :
+
+http://<host>:<port>/qman/console
diff --git a/qpid/java/management/client/bin/qman-jmx.cmd b/qpid/java/management/client/bin/qman-jmx.cmd
new file mode 100644
index 0000000000..c04241494d
--- /dev/null
+++ b/qpid/java/management/client/bin/qman-jmx.cmd
@@ -0,0 +1,78 @@
+@echo off
+
+@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 This script is used to initialize environment to start QMan JMX Adapter.
+@rem It uses several environment variables described below.
+@rem You can edit this file according to your environment or (reccommended) set their
+@rem values outside this script.
+@rem
+@rem It sets (or retrieve from the environment if defined) the following variables:
+@rem
+@rem QMAN_HOME - The home directory of your QMan installation.
+@rem JAVA_HOME - Location of the version of Java runtime used to start QMan.
+@rem QMAN_CONFIG_FILE - Location of the QMan configuration file.
+@rem **************************************************************************
+
+cls
+
+:CHECK JVM
+set JAVA=%JAVA_HOME%\bin\java
+set JAVA_OPTS=-Xms128m -Xmx512m
+
+if not "%JAVA_HOME%" == "" goto CONFIGURE AND START
+
+set JAVA=java
+
+echo.
+echo WARNING : JAVA_HOME is not set so unexpected results may occur.
+echo Please set JAVA_HOME to the directory of your local JDK / JRE to avoid this message.
+
+:CONFIGURE AND START
+
+if "%QMAN_HOME%" == "" SET QMAN_HOME=..
+if "%QMAN_CONFIG_FILE%" == "" SET QMAN_CONFIG_FILE=%QMAN_HOME%\etc\qman-config.xml
+
+SET QMAN_LIBS=%QMAN_HOME%\lib
+SET QMAN_CLASSPATH=%QMAN_HOME%\etc
+
+setlocal ENABLEDELAYEDEXPANSION
+
+FOR /R %QMAN_LIBS% %%G IN (*.jar) DO set QMAN_CLASSPATH=!QMAN_CLASSPATH!;%%G
+
+:START
+echo ===============================================================================
+echo.
+echo QMan JMX Bridge Bootstrap Environment
+echo --------------------------------------------------
+echo.
+echo QMan HOME : %QMAN_HOME%
+echo.
+echo Java executable : %JAVA%
+echo.
+echo Java Opts : %JAVA_OPTS%
+echo.
+echo Configuration file : %QMAN_CONFIG_FILE%
+echo.
+echo Bootstrap classpath : %QMAN_CLASSPATH%
+echo.
+echo ===============================================================================
+echo.
+
+"%JAVA%" %JAVA_OPTS% -Dcom.sun.management.jmxremote -Dqman-config=%QMAN_CONFIG_FILE% -classpath "%QMAN_CLASSPATH%" org.apache.qpid.management.domain.services.QMan \ No newline at end of file
diff --git a/qpid/java/management/client/bin/qman-jmx.sh b/qpid/java/management/client/bin/qman-jmx.sh
new file mode 100644
index 0000000000..1003117128
--- /dev/null
+++ b/qpid/java/management/client/bin/qman-jmx.sh
@@ -0,0 +1,76 @@
+#!/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.
+#
+# *************************************************************************
+# This script is used to initialize environment to start QMan JMX Adapter.
+# It uses several environment variables described below.
+# You can edit this file according to your environment or (reccommended) set their
+# values outside this script.
+#
+# It sets (or retrieve from the environment if defined) the following variables:
+#
+# QMAN_HOME - The home directory of your QMan installation.
+# JAVA_HOME - Location of the version of Java runtime used to start QMan.
+# QMAN_CONFIG_FILE - Location of the QMan configuration file.
+# **************************************************************************
+
+clear
+
+JAVA=$JAVA_HOME/bin/java
+JAVA_OPTS="-Xms128m -Xmx512m"
+
+if [ "$JAVA_HOME" = "" ] ; then
+ echo "JAVA_HOME is not set. Unexpected results may occur."
+ echo "Set JAVA_HOME to the directory of your local JDK to avoid this message."
+ JAVA=java
+fi
+
+if [ "$QMAN_HOME" = "" ] ; then
+ QMAN_HOME=..
+fi
+
+if [ "$QMAN_CONFIG_FILE" = "" ] ; then
+ QMAN_CONFIG_FILE=$QMAN_HOME/etc/qman-config.xml
+fi
+
+if [ "$QMAN_LIBS" = "" ] ; then
+ QMAN_LIBS=$QMAN_HOME/lib
+fi
+QMAN_CLASSPATH=`find $QMAN_LIBS | tr '\n' ":"`
+QMAN_CLASSPATH=$QMAN_HOME/etc:$QMAN_CLASSPATH
+
+echo "==============================================================================="
+echo ""
+echo "QMan JMX Bridge Bootstrap Environment"
+echo "--------------------------------------------------"
+echo ""
+echo "QMan HOME : $QMAN_HOME"
+echo ""
+echo "Java executable : $JAVA"
+echo ""
+echo "Java Opts : $JAVA_OPTS"
+echo ""
+echo "Configuration file : $QMAN_CONFIG_FILE"
+echo ""
+echo "Bootstrap classpath : $QMAN_CLASSPATH"
+echo ""
+echo "==============================================================================="
+echo ""
+
+"$JAVA" $JAVA_OPTS -cp $QMAN_CLASSPATH -Dcom.sun.management.jmxremote -Dqman-config=$QMAN_CONFIG_FILE org.apache.qpid.management.domain.services.QMan
diff --git a/qpid/java/management/client/bin/qman-wsdm-start.cmd b/qpid/java/management/client/bin/qman-wsdm-start.cmd
new file mode 100644
index 0000000000..ec8321c6b8
--- /dev/null
+++ b/qpid/java/management/client/bin/qman-wsdm-start.cmd
@@ -0,0 +1,88 @@
+@echo off
+
+@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 This script is used to initialize environment to start QMan WS-DM Adapter.
+@rem It uses several environment variables described below.
+@rem You can edit this file according to your environment or (reccommended) set their
+@rem values outside this script.
+@rem
+@rem It sets (or retrieve from the environment if defined) the following variables:
+@rem
+@rem QMAN_HOME - The home directory of your QMan installation.
+@rem JAVA_HOME - Location of the version of Java runtime used to start QMan.
+@rem QMAN_WSDM_ADAPTER_PORT - The TCP port that QMan will use to listen for incoming connections.
+@rem QMAN_WSDM_ADAPTER_HOST - The IP address or DNS name QMan will use to listen for incoming connections
+@rem QMAN_CONFIG_FILE - Location of the QMan configuration file.
+@rem **************************************************************************
+
+set JAVA=%JAVA_HOME%\bin\java
+set JAVA_OPTS=-Xms128m -Xmx512m
+SET CLASSPATH=
+
+if not "%JAVA_HOME%" == "" goto CONFIGURE AND START
+set JAVA=java
+
+echo JAVA_HOME is not set. Unexpected results may occur.
+echo Set JAVA_HOME to the directory of your local JDK to avoid this message.
+
+:CONFIGURE AND START
+
+if "%QMAN_HOME%" == "" SET QMAN_HOME=..
+if "%QMAN_WSDM_ADAPTER_PORT%" == "" SET QMAN_WSDM_ADAPTER_PORT=8080
+if "%QMAN_WSDM_ADAPTER_HOST%" == "" SET QMAN_WSDM_ADAPTER_HOST=%COMPUTERNAME%
+if "%QMAN_CONFIG_FILE%" == "" SET QMAN_CONFIG_FILE=%QMAN_HOME%\etc\qman-config.xml
+
+SET ADMIN_PORT=8079
+SET ADMIN_KEY=gazzax
+SET QMAN_LIBS=%QMAN_HOME%\lib
+SET JETTY_CONFIG_FILE=%QMAN_HOME%\etc\jetty.xml
+
+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%\geronimo-servlet_2.5_spec-1.2.jar
+SET CLASSPATH=%CLASSPATH%;%QMAN_LIBS%\slf4j-api-1.6.1.jar
+SET CLASSPATH=%CLASSPATH%;%QMAN_LIBS%\slf4j-log4j12-1.6.1.jar
+SET CLASSPATH=%CLASSPATH%;%QMAN_LIBS%\log4j-1.2.12.jar
+
+echo ===============================================================================
+echo.
+echo QMan WS-DM Bridge Bootstrap Environment
+echo ------------------------------------------------------
+echo.
+echo QMan HOME: %QMAN_HOME%
+echo.
+echo Java executable : %JAVA%
+echo.
+echo QMan configuration file : %QMAN_CONFIG_FILE%
+echo.
+echo Web Server configuration file : %JETTY_CONFIG_FILE%
+echo.
+echo Web Server HTTP port : %QMAN_WSDM_ADAPTER_PORT%
+echo.
+echo Web Server Admin port : %ADMIN_PORT%
+echo.
+echo Bootstrap classpath : %CLASSPATH%
+echo.
+echo ===============================================================================
+echo.
+
+%JAVA% -cp %CLASSPATH% -DQMAN_HOME=%QMAN_HOME% -Djetty.home=%QMAN_HOME% -Dqman.host=%QMAN_WSDM_ADAPTER_HOST% -Dqman.port=%QMAN_WSDM_ADAPTER_PORT% -DSTOP.PORT=%ADMIN_PORT% -DSTOP.KEY=%ADMIN_KEY% -Dqman-config=%QMAN_CONFIG_FILE% org.mortbay.start.Main %JETTY_CONFIG_FILE%
diff --git a/qpid/java/management/client/bin/qman-wsdm-start.sh b/qpid/java/management/client/bin/qman-wsdm-start.sh
new file mode 100644
index 0000000000..0024890527
--- /dev/null
+++ b/qpid/java/management/client/bin/qman-wsdm-start.sh
@@ -0,0 +1,89 @@
+#!/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.
+#
+# *************************************************************************
+# This script is used to initialize environment to start QMan WS-DM Adapter.
+# It uses several environment variables described below.
+# You can edit this file according to your environment or (reccommended) set their
+# values outside this script.
+#
+# It sets (or retrieve from the environment if defined) the following variables:
+#
+# QMAN_HOME - The home directory of your QMan installation.
+# JAVA_HOME - Location of the version of Java runtime used to start QMan.
+# QMAN_WSDM_ADAPTER_PORT - The TCP port that QMan will use to listen for incoming connections.
+# QMAN_WSDM_ADAPTER_HOST - The IP address or DNS name QMan will use to listen for incoming connections
+# QMAN_CONFIG_FILE - Location of the QMan configuration file.
+# **************************************************************************
+
+JAVA=$JAVA_HOME/bin/java
+JAVA_OPTS="-Xms128m -Xmx512m"
+
+if [ "$JAVA_HOME" = "" ] ; then
+ echo "JAVA_HOME is not set. Unexpected results may occur."
+ echo "Set JAVA_HOME to the directory of your local JDK to avoid this message."
+ JAVA=java
+fi
+if [ "$QMAN_HOME" = "" ] ; then
+ QMAN_HOME=..
+fi
+if [ "$QMAN_WSDM_ADAPTER_PORT" = "" ] ; then
+ QMAN_WSDM_ADAPTER_PORT=8080
+fi
+if [ "$QMAN_WSDM_ADAPTER_HOST" = "" ] ; then
+ QMAN_WSDM_ADAPTER_HOST=$HOSTNAME
+fi
+if [ "$QMAN_CONFIG_FILE" = "" ] ; then
+ QMAN_CONFIG_FILE=$QMAN_HOME/etc/qman-config.xml
+fi
+
+ADMIN_PORT=8079
+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/geronimo-servlet_2.5_spec-1.2.jar:$QMAN_LIBS/slf4j-api-1.6.1.jar:$QMAN_LIBS/slf4j-log4j12-1.6.1.jar:$QMAN_LIBS/log4j-1.2.12.jar
+
+echo "==============================================================================="
+echo""
+echo "QMan WS-DM Bridge Bootstrap Environment"
+echo "------------------------------------------------------"
+echo""
+echo "QMan HOME: $QMAN_HOME"
+echo""
+echo "Java executable : $JAVA"
+echo""
+echo "Java Opts : $JAVA_OPTS"
+echo""
+echo "Configuration file : $QMAN_CONFIG_FILE"
+echo""
+echo "Web Server Configuration File : $JETTY_CONFIG_FILE"
+echo""
+echo "Web Server HTTP port : $QMAN_WSDM_ADAPTER_PORT"
+echo""
+echo "Web Server HTTP host : $QMAN_WSDM_ADAPTER_HOST"
+echo""
+echo "Web Server Admin port : $ADMIN_PORT"
+echo""
+echo "Bootstrap classpath : $QMAN_CLASSPATH"
+echo""
+echo "==============================================================================="
+echo""
+
+"$JAVA" $JAVA_OPTS -cp $QMAN_CLASSPATH -DQMAN_HOME=$QMAN_HOME -Djetty.home=$QMAN_HOME -Dqman.host=$QMAN_WSDM_ADAPTER_HOST -Dqman.port=$QMAN_WSDM_ADAPTER_PORT -DSTOP.PORT=$ADMIN_PORT -DSTOP.KEY=$ADMIN_KEY -Dqman-config=$QMAN_CONFIG_FILE org.mortbay.start.Main $JETTY_CONFIG_FILE
diff --git a/qpid/java/management/client/bin/qman-wsdm-stop.cmd b/qpid/java/management/client/bin/qman-wsdm-stop.cmd
new file mode 100644
index 0000000000..6449c70227
--- /dev/null
+++ b/qpid/java/management/client/bin/qman-wsdm-stop.cmd
@@ -0,0 +1,37 @@
+@echo off
+
+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.
+
+set JAVA=%JAVA_HOME%\bin\java
+
+if not "%JAVA_HOME%" == "" goto CONFIGURE AND START
+
+set JAVA=java
+
+echo JAVA_HOME is not set. Unexpected results may occur.
+echo Set JAVA_HOME to the directory of your local JDK to avoid this message.
+
+:CONFIGURE AND START
+
+if "%QMAN_HOME%" == "" SET QMAN_HOME=..
+SET ADMIN_PORT=8079
+SET ADMIN_KEY=gazzax
+
+"%JAVA%" -DSTOP.PORT=%ADMIN_PORT% -DSTOP.KEY=%ADMIN_KEY% -jar %QMAN_HOME%\lib\start.jar --stop
+
+echo QMan WS-DM Adapter shut down successfully. \ No newline at end of file
diff --git a/qpid/java/management/client/bin/qman-wsdm-stop.sh b/qpid/java/management/client/bin/qman-wsdm-stop.sh
new file mode 100644
index 0000000000..0de9a995ef
--- /dev/null
+++ b/qpid/java/management/client/bin/qman-wsdm-stop.sh
@@ -0,0 +1,38 @@
+#!/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.
+#
+
+JAVA=$JAVA_HOME/bin/java
+
+if [ "$JAVA_HOME" = "" ] ; then
+ echo "JAVA_HOME is not set. Unexpected results may occur."
+ echo "Set JAVA_HOME to the directory of your local JDK to avoid this message."
+ JAVA=java
+fi
+
+if [ "$QMAN_HOME" = "" ] ; then
+ QMAN_HOME=..
+fi
+
+ADMIN_PORT=8079
+ADMIN_KEY=gazzax
+
+"$JAVA" -DSTOP.PORT=$ADMIN_PORT -DSTOP.KEY=$ADMIN_KEY -jar $QMAN_HOME/lib/start.jar --stop
+
+echo "QMan WS-DM Adapter shut down successfully." \ No newline at end of file
diff --git a/qpid/java/management/client/build.xml b/qpid/java/management/client/build.xml
new file mode 100644
index 0000000000..415840f70d
--- /dev/null
+++ b/qpid/java/management/client/build.xml
@@ -0,0 +1,213 @@
+<!--
+ -
+ - Licensed to the Apache Software Foundation (ASF) under one
+ - or more contributor license agreements. See the NOTICE file
+ - distributed with this work for additional information
+ - regarding copyright ownership. The ASF licenses this file
+ - to you under the Apache License, Version 2.0 (the
+ - "License"); you may not use this file except in compliance
+ - with the License. You may obtain a copy of the License at
+ -
+ - http://www.apache.org/licenses/LICENSE-2.0
+ -
+ - Unless required by applicable law or agreed to in writing,
+ - software distributed under the License is distributed on an
+ - "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ - KIND, either express or implied. See the License for the
+ - specific language governing permissions and limitations
+ - under the License.
+ -
+ -->
+<project name="QMan - Qpid JMX / WS-DM Adapter" default="build">
+
+ <property name="module.depends" value="client common"/>
+ <property name="module.test.depends" value="client common"/>
+
+ <import file="../../module.xml"/>
+
+ <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"/>
+ <property name="classes.folder" value="${web-inf.folder}${file.separator}classes"/>
+ <property name="examples.folder" value="${module.build}${file.separator}examples"/>
+
+ <target name="release-bin-other">
+ <mkdir dir="${module.release}${file.separator}log"/>
+ <mkdir dir="${module.release}${file.separator}examples"/>
+ <mkdir dir="${module.release}${file.separator}examples${file.separator}sample_messages"/>
+
+ </target>
+
+ <target name="release-bin" depends="release-bin-tasks"/>
+
+ <target name="resources-release" description="copy resources into module release">
+ <copy todir="${module.release}" failonerror="false" flatten="true">
+ <fileset dir="${resources}" excludes="META-INF">
+ <exclude name="META-INF"/>
+ <exclude name="README.txt"/>
+ </fileset>
+ <fileset file="${module.build}${file.separator}README.txt"/>
+ </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}">
+ <not><filename name="**/*javassist*"/></not>
+ <not><filename name="**/*xml-api*"/></not>
+ <not><filename name="**/*xerces*"/></not>
+ <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">
+ <fileset file="${module.jar}"/>
+ <fileset dir="${build.lib}" includes="${module.depends.jars}"/>
+ </copy>
+ <mkdir dir="${module.release}${file.separator}app${file.separator}qman"/>
+ <copy todir="${module.release}${file.separator}app${file.separator}qman" failonerror="true">
+ <fileset dir="${web.module}" includes="*/**"/>
+ </copy>
+ <mkdir dir="${module.release}${file.separator}examples"/>
+ <copy todir="${module.release}${file.separator}examples">
+ <fileset dir="${examples.folder}"/>
+ </copy>
+ </target>
+
+ <target name="prepare-wsdm-module">
+ <mkdir dir="${web.module}"/>
+ <mkdir dir="${web-inf.folder}"/>
+ <mkdir dir="${classes.folder}"/>
+ <copy file=".${file.separator}web.xml" todir="${web-inf.folder}" verbose="false"/>
+ <copy todir="${classes.folder}" verbose="false">
+ <fileset dir="${module.classes}">
+ <include name="wsdl/**"/>
+ <include name="muse.xml"/>
+ <include name="router-entries/**"/>
+ </fileset>
+ </copy>
+ <copy todir="${web-inf.folder}">
+ <fileset dir="${build}" includes="${module.libs}">
+ <exclude name="lib/jetty*.jar"/>
+ <exclude name="lib/start*.jar"/>
+ </fileset>
+ </copy>
+ <copy todir="${web-inf.folder}${file.separator}lib">
+ <fileset dir="${build}/lib">
+ <include name="qpid-client-*.jar"/>
+ <include name="qpid-common-*.jar"/>
+ <include name="qpid-management-client-*.jar"/>
+ <exclude name="qpid-client-example*.jar"/>
+ <exclude name="qpid-client-tests*.jar"/>
+ <exclude name="qpid-common-tests*.jar"/>
+ <exclude name="qpid-management-client-tests*.jar"/>
+ </fileset>
+ </copy>
+ <copy todir="${web.module}">
+ <fileset dir="${module.src}${file.separator}..${file.separator}..${file.separator}..${file.separator}console">
+ <include name="*/**"/>
+ </fileset>
+ </copy>
+ </target>
+ <target name="jar.manifest" depends="compile" if="module.manifest">
+ <jar destfile="${module.jar}" manifest="${module.manifest}">
+ <fileset dir="${module.classes}" casesensitive="yes">
+ <include name="**/**"/>
+ <exclude name="wsdl/**"/>
+ <exclude name="muse.xml"/>
+ <exclude name="router-entries/**"/>
+ </fileset>
+ </jar>
+ </target>
+ <target name="jar.nomanifest" depends="compile" unless="module.manifest">
+ <jar destfile="${module.jar}">
+ <metainf dir="${project.root}${file.separator}resources/" />
+ <fileset dir="${module.classes}" casesensitive="yes">
+ <include name="**/**"/>
+ <exclude name="wsdl/**"/>
+ <exclude name="muse.xml"/>
+ <exclude name="router-entries/**"/>
+ </fileset>
+ </jar>
+ </target>
+ <target name="postbuild" depends="prepare-wsdm-module,copy-examples-to-build,copy-README-to-build" description="Build WS-DM module"/>
+
+ <path id="module.test.path">
+ <pathelement path="${module.test.classes}" />
+ <path refid="module.test.libs"/>
+ <fileset dir="${build}/lib">
+ <include name="qpid-client-*.jar"/>
+ <include name="qpid-common-*.jar"/>
+ <include name="qpid-management-client-*.jar"/>
+ <exclude name="qpid-client-example*.jar"/>
+ <exclude name="qpid-client-tests*.jar"/>
+ <exclude name="qpid-common-tests*.jar"/>
+ <exclude name="qpid-management-client-tests*.jar"/>
+ </fileset>
+ </path>
+
+ <target name="copy-README-to-build">
+ <copy todir="${module.build}">
+ <fileset dir="${module.src}${file.separator}..${file.separator}..${file.separator}..">
+ <include name="README.txt"/>
+ </fileset>
+ </copy>
+ </target>
+
+ <target name="copy-examples-to-build">
+ <mkdir dir="${examples.folder}${file.separator}src"/>
+ <mkdir dir="${examples.folder}${file.separator}sample_messages"/>
+ <copy todir="${examples.folder}">
+ <fileset dir="${module.src}${file.separator}..${file.separator}..${file.separator}example">
+ <include name="README.txt"/>
+ </fileset>
+ </copy>
+ <copy todir="${examples.folder}${file.separator}src">
+ <fileset dir="${module.src}${file.separator}..${file.separator}..${file.separator}example">
+ <include name="**/*.java"/>
+ <exclude name="**/*.out.*"/>
+ </fileset>
+ </copy>
+ <copy todir="${examples.folder}${file.separator}sample_messages">
+ <fileset dir="${module.src}${file.separator}..${file.separator}..${file.separator}example" >
+ <exclude name="**/*.java"/>
+ <exclude name="**/README.txt"/>
+ <include name="**/*.out.*"/>
+ </fileset>
+ </copy>
+ </target>
+
+ <target name="test" depends="build,compile-tests" if="module.test.src.exists" unless="${dontruntest}" description="execute unit tests">
+ <delete file="${module.failed}"/>
+ <echo message="Using profile:${profile}" level="info"/>
+ <junit fork="${test.fork}" maxmemory="1024M" reloading="no"
+ haltonfailure="${haltonfailure}" haltonerror="${haltonerror}"
+ failureproperty="test.failures" printsummary="on" timeout="600000" >
+
+ <jvmarg value="${jvm.args}"/>
+ <sysproperty key="qman.war" value="${web.module}"/>
+
+ <formatter type="plain"/>
+ <formatter type="xml"/>
+
+ <classpath refid="module.test.path"/>
+
+ <batchtest fork="${test.fork}" todir="${module.results}">
+ <fileset dir="${module.test.src}" excludes="${module.test.excludes}">
+ <include name="**/${test}.java"/>
+ </fileset>
+ </batchtest>
+ </junit>
+ <antcall target="touch-failed"/>
+ <condition property="failed">
+ <and>
+ <isfalse value="${test.failures.ignore}"/>
+ <available file="${module.failed}"/>
+ </and>
+ </condition>
+ <fail if="failed" message="TEST SUITE FAILED"/>
+ </target>
+</project>
diff --git a/qpid/java/management/client/console/brokers_management.jsp b/qpid/java/management/client/console/brokers_management.jsp
new file mode 100644
index 0000000000..f307006ac1
--- /dev/null
+++ b/qpid/java/management/client/console/brokers_management.jsp
@@ -0,0 +1,209 @@
+<!--
+
+ 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.
+
+-->
+
+<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
+<%@ taglib uri='http://java.sun.com/jsp/jstl/core' prefix='c'%>
+<%@page import="org.apache.qpid.management.web.action.BrokerModel"%>
+<%@page import="java.util.Set"%>
+<%@page import="javax.management.ObjectName"%>
+<%@page import="org.apache.qpid.management.Names"%>
+<%@page import="java.util.List"%>
+<%@page import="java.util.*"%>
+<%@page import="java.net.URI"%>
+<%@page import="javax.xml.namespace.QName"%>
+<%@page import="org.w3c.dom.Element"%>
+<html>
+ <head>
+ <link rel="stylesheet" href="<%=request.getContextPath()%>/images/style.css" type="text/css" />
+ <title>QMan Administration Console</title>
+ </head>
+ <body>
+ <div id="page" align="center">
+ <jsp:include page="/fragments/header.jsp">
+ <jsp:param name="title" value="Brokers Management"/>
+ </jsp:include>
+
+ <div id="content" align="center">
+ <jsp:include page="/fragments/menu.jsp"/>
+
+ <div id="contenttext">
+ <div class="panel" align="justify">
+ <span class="bodytext">
+ <table width="100%">
+ <tr>
+ <td valign="top">
+ <fieldset>
+ <legend>Connected Brokers</legend>
+ <table width="100%" cellspacing="1">
+ <tr>
+ <th nowrap="nowrap" align="center">Host</th>
+ <th nowrap="nowrap" align="center" >Port</th>
+ <th nowrap="nowrap" align="center">Virtual Host</th>
+ <th nowrap="nowrap" align="center">Username</th>
+ <th nowrap="nowrap" align="center">Initial Pool Capacity</th>
+ <th nowrap="nowrap" align="center">Max Pool Capacity</th>
+ <th nowrap="nowrap" align="center">Max Wait Timeout</th>
+ </tr>
+ <c:forEach var="broker" items="${model}" varStatus="rowCounter">
+ <c:choose>
+ <c:when test="${rowCounter.count % 2 == 0}">
+ <c:set var="bgcolor" scope="page" value="EAEAEA"/>
+ </c:when>
+ <c:otherwise>
+ <c:set var="bgcolor" scope="page" value="FFFFFF"/>
+ </c:otherwise>
+ </c:choose>
+ <tr>
+ <td nowrap style="font-size: xx-small; font-weight: bold;" bgcolor="${bgcolor}"><c:out value="${broker.host}"/></td>
+ <td nowrap style="font-size: xx-small; font-weight: bold;" bgcolor="${bgcolor}"><c:out value="${broker.port}"/></td>
+ <td style="font-size: xx-small; font-weight: bold;" bgcolor="${bgcolor}"><c:out value="${broker.virtualHost}"/></td>
+ <td style="font-size: xx-small; font-weight: bold;" bgcolor="${bgcolor}"><c:out value="${broker.username}"/></td>
+ <td style="font-size: xx-small; font-weight: bold;" bgcolor="${bgcolor}"><c:out value="${broker.initialPoolCapacity}"/></td>
+ <td style="font-size: xx-small; font-weight: bold;" bgcolor="${bgcolor}"><c:out value="${broker.maxPoolCapacity}"/></td>
+ <td style="font-size: xx-small; font-weight: bold;" bgcolor="${bgcolor}"><c:out value="${broker.maxWaitTimeout}"/></td>
+ </tr>
+ </c:forEach>
+ </table>
+ </fieldset>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <form name="form" action="<%=request.getContextPath()%>/brokers_management" method="post">
+ <fieldset>
+ <legend>New Broker Connection Data</legend>
+ <table>
+ <tr>
+ <td>
+ Host :
+ </td>
+ <td>
+ <input type="text" name="host"/>
+ </td>
+ <td style="font-size: x-small;">
+ The hostname where the broker is running.
+ </td>
+ </tr>
+ <tr>
+ <td>
+ Port :
+ </td>
+ <td>
+ <input type="text" name="port"/>
+ </td>
+ <td style="font-size: x-small;">
+ The port number where the broker is running.
+ </td>
+ </tr>
+ <tr>
+ <td>
+ Virtual Host :
+ </td>
+ <td>
+ <input type="text" name="virtualHost"/>
+ </td>
+ <td style="font-size: x-small;">
+ The virtual host name.
+ </td>
+ </tr>
+ <tr>
+ <td>
+ Username :
+ </td>
+ <td>
+ <input type="text" name="username"/>
+ </td>
+ <td style="font-size: x-small;">
+ The username used for estabilish connection with broker.
+ </td>
+ </tr>
+ <tr>
+ <td>
+ Password :
+ </td>
+ <td>
+ <input type="text" name="password"/>
+ </td>
+ <td style="font-size: x-small;">
+ The password used for estabilish connection with broker.
+ </td>
+ </tr>
+ <tr>
+ <td>
+ Initial Pool Capacity :
+ </td>
+ <td>
+ <input type="text" name="initialCapacity"/>
+ </td>
+ <td style="font-size: x-small;">
+ The number of connections that must be immediately opened.
+ </td>
+ </tr>
+ <tr>
+ <td>
+ Max Pool Capacity :
+ </td>
+ <td>
+ <input type="text" name="maxCapacity"/>
+ </td>
+ <td style="font-size: x-small;">
+ The maximum number of open connections.
+ </td>
+ </tr>
+ <tr>
+ <td>
+ Max Wait Timeout :
+ </td>
+ <td>
+ <input type="text" name="maxWaitTimeout"/>
+ </td>
+ <td style="font-size: x-small;">
+ The maximum amount of time that a client will wait for obtaining a connection.
+ </td>
+ </tr>
+ <tr>
+ <td colspan="3" align="center">
+ <input type="submit" value="Connect"/>
+ </td>
+ </tr>
+ </table>
+ </fieldset>
+ </td>
+ </form>
+ </tr>
+ <tr>
+ <td nowrap style="font-size: x-small; font-weight: bold; color=red;">
+ <ul>
+ <c:forEach var="errorMessage" items="${errors}">
+ <li><span style="font-size: medium; font-weight: bold; color:red;">${errorMessage}</span></li>
+ </c:forEach>
+ </ul>
+ </td>
+ </tr>
+
+ </table>
+ </span>
+ </div>
+ </div>
+ </div>
+ </div>
+ </body>
+</html>
diff --git a/qpid/java/management/client/console/console.jsp b/qpid/java/management/client/console/console.jsp
new file mode 100644
index 0000000000..d1a207fe32
--- /dev/null
+++ b/qpid/java/management/client/console/console.jsp
@@ -0,0 +1,122 @@
+<!--
+
+ 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.
+
+-->
+
+<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
+<%@ taglib uri='http://java.sun.com/jsp/jstl/core' prefix='c'%>
+<html>
+ <head>
+ <link rel="stylesheet" href="<%=request.getContextPath()%>/images/style.css" type="text/css" />
+ <title>QMan Administration Console</title>
+ </head>
+ <body>
+ <div id="page" align="center">
+ <jsp:include page="/fragments/header.jsp">
+ <jsp:param name="title" value="System Overview"/>
+ </jsp:include>
+
+ <div id="content" align="center">
+ <jsp:include page="/fragments/menu.jsp"/>
+
+ <div id="contenttext">
+ <div class="panel" align="justify" style="height:500px; overflow-y:auto;">
+ <span class="bodytext">
+ <table width="100%" border="0">
+ <tr>
+ <td valign="top" nowrap align="center">
+ <fieldset>
+ <legend>QMan</legend>
+ <table cellspacing="2">
+ <tr><td style="color: #006633; font-size: xx-small; font-weight:bold;" align="center">Version</td></tr>
+ <tr><td style="font-size: xx-small;" align="center">${requestScope.model.version}</td></tr>
+ <tr><td><br /></td></tr>
+ <tr><td style="color: #006633; font-size: xx-small; font-weight:bold" align="center">Version Name</td></tr>
+ <tr><td style="font-size: xx-small;" align="center">${requestScope.model.versionName}</td></tr>
+ <tr><td><br /></td></tr>
+ <tr><td style="color: #006633; font-size: xx-small; font-weight:bold" align="center">Start Date</td></tr>
+ <tr>
+ <td style="font-size: xx-small;" align="center">
+ <fmt:formatDate
+ value="${requestScope.model.startDate}"
+ pattern="MM/dd/yyyy hh:mm:ss"/>
+ </td>
+ </tr>
+ <tr><td><br /></td></tr>
+ <tr><td style="color: #006633; font-size: xx-small; font-weight:bold" align="center">Host</td></tr>
+ <tr><td style="font-size: xx-small;" align="center">${requestScope.model.host}</td></tr>
+ <tr><td><br /></td></tr>
+ <tr><td style="color: #006633; font-size: xx-small; font-weight:bold" align="center">Port</td></tr>
+ <tr><td style="font-size: xx-small;" align="center">${requestScope.model.port}</td></tr>
+ </table>
+ </fieldset>
+ <fieldset>
+ <legend>Operating System</legend>
+ <table cellspacing="2">
+ <tr><td style="color: #006633; font-size: xx-small; font-weight:bold;" align="center">Name</td></tr>
+ <tr><td style="font-size: xx-small;" align="center">${requestScope.model.osName}</td></tr>
+ <tr><td><br /></td></tr>
+ <tr><td style="color: #006633; font-size: xx-small; font-weight:bold" align="center">Version</td></tr>
+ <tr><td style="font-size: xx-small;" align="center">${requestScope.model.osVersion}</td></tr>
+ <tr><td><br /></td></tr>
+ <tr><td style="color: #006633; font-size: xx-small; font-weight:bold" align="center">Arch</td></tr>
+ <tr><td style="font-size: xx-small;" align="center">${requestScope.model.archName}</td></tr>
+ <tr><td><br /></td></tr>
+ <tr><td style="color: #006633; font-size: xx-small; font-weight:bold" align="center">Processors</td></tr>
+ <tr><td style="font-size: xx-small;" align="center">${requestScope.model.processors}</td></tr>
+ </table>
+ </fieldset>
+ </td>
+ <td valign="top">
+ <fieldset>
+ <legend>JVM Environment</legend>
+ <table cellspacing="5">
+ <tr>
+ <td valign="top">
+ <h4 style="color: #006633; font-size: xx-small">Boot Classpath :
+ <p/>
+ <c:forEach var="entry" items="${model.bootClasspath}">
+ <c:out value="${entry}"/>;
+ <br/>
+ </c:forEach>
+ </h4>
+ </td>
+ <td valign="top">
+ <h4 style="color: #006633; font-size: xx-small">
+ Input Arguments :
+ <p/>
+ <c:forEach var="argument" items="${model.inputArguments}">
+ <c:out value="${argument}"/>;
+ <br/>
+ </c:forEach>
+ </h4>
+ </td>
+ </tr>
+ </table>
+ </fieldset>
+ </td>
+ </tr>
+ </table>
+ </span>
+ </div>
+ </div>
+ </div>
+ </div>
+ </body>
+</html>
diff --git a/qpid/java/management/client/console/error_page.jsp b/qpid/java/management/client/console/error_page.jsp
new file mode 100644
index 0000000000..73d2f9edc3
--- /dev/null
+++ b/qpid/java/management/client/console/error_page.jsp
@@ -0,0 +1,59 @@
+<!--
+
+ 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.
+
+-->
+
+<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
+<%@ taglib uri='http://java.sun.com/jsp/jstl/core' prefix='c'%>
+<html>
+ <head>
+ <link rel="stylesheet" href="<%=request.getContextPath()%>/images/style.css" type="text/css" />
+ <title>QMan Administration Console</title>
+ </head>
+ <body>
+ <div id="page" align="center">
+ <jsp:include page="/fragments/header.jsp">
+ <jsp:param name="title" value="Error Page"/>
+ </jsp:include>
+
+ <div id="content" align="center">
+ <jsp:include page="/fragments/menu.jsp"/>
+
+ <div id="contenttext">
+ <div class="panel" align="justify" style="height:500px; overflow-y:auto;">
+ <span class="bodytext">
+ <table width="100%">
+ <tr><td nowrap style="font-weight: bold;">
+ We are not able to satify your request because an error has happened.
+ <br>Message : ${errorMessage}
+ </td></tr>
+ <tr><td nowrap style="font-size: xx-small; font-weight: bold;">
+ <c:forEach var="stackTrace" items="${exception.stackTrace}">
+ ${stackTrace}
+ <br>
+ </c:forEach>
+ </td></tr>
+ </table>
+ </span>
+ </div>
+ </div>
+ </div>
+ </div>
+ </body>
+</html>
diff --git a/qpid/java/management/client/console/fragments/header.jsp b/qpid/java/management/client/console/fragments/header.jsp
new file mode 100644
index 0000000000..b401fee7a0
--- /dev/null
+++ b/qpid/java/management/client/console/fragments/header.jsp
@@ -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.
+
+-->
+
+<div id="header" align="center">
+ <div id="pagetitle">
+ <div id="asf-header" align="left">
+ <table width="100%">
+ <tr>
+ <td align="left"><img src="images/qpid-logo.png" height="100" width="200" /></td>
+ <td align="right"><img src="images/asf-logo.png" height="69" width="225" /></td>
+ </tr>
+ </table>
+ </div>
+ <div id="title" class="titletext" align="right">
+ <span class="bluetitle"><%=request.getParameter("title")%></span>
+ </div>
+ </div>
+</div>
diff --git a/qpid/java/management/client/console/fragments/menu.jsp b/qpid/java/management/client/console/fragments/menu.jsp
new file mode 100644
index 0000000000..6924fd5d43
--- /dev/null
+++ b/qpid/java/management/client/console/fragments/menu.jsp
@@ -0,0 +1,31 @@
+<!--
+
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+
+-->
+
+<div id="menu" align="center">
+ <div id="linksmenu" align="left">
+ <a href="<%=request.getContextPath()%>/console"> &nbsp; &gt; System Overview</a>
+ <a href="<%=request.getContextPath()%>/brokers_management">&nbsp; &gt; Brokers Management</a>
+ <a href="<%=request.getContextPath()%>/resources_management">&nbsp; &gt; Resources Management</a>
+ <a>&nbsp; &gt; Subscriptions Management</a>
+ <a>&nbsp; &gt; System Health</a>
+ <a href="<%=request.getContextPath()%>/logging_configuration">&nbsp; &gt; Logging Configuration</a>
+ </div>
+</div>
diff --git a/qpid/java/management/client/console/images/asf-logo.png b/qpid/java/management/client/console/images/asf-logo.png
new file mode 100644
index 0000000000..d824fab768
--- /dev/null
+++ b/qpid/java/management/client/console/images/asf-logo.png
Binary files differ
diff --git a/qpid/java/management/client/console/images/menu.gif b/qpid/java/management/client/console/images/menu.gif
new file mode 100644
index 0000000000..9946e8e231
--- /dev/null
+++ b/qpid/java/management/client/console/images/menu.gif
Binary files differ
diff --git a/qpid/java/management/client/console/images/menuleft.gif b/qpid/java/management/client/console/images/menuleft.gif
new file mode 100644
index 0000000000..f986ecfc27
--- /dev/null
+++ b/qpid/java/management/client/console/images/menuleft.gif
Binary files differ
diff --git a/qpid/java/management/client/console/images/menuright.gif b/qpid/java/management/client/console/images/menuright.gif
new file mode 100644
index 0000000000..afdd8bd04b
--- /dev/null
+++ b/qpid/java/management/client/console/images/menuright.gif
Binary files differ
diff --git a/qpid/java/management/client/console/images/qpid-logo.png b/qpid/java/management/client/console/images/qpid-logo.png
new file mode 100644
index 0000000000..5f4ccc3081
--- /dev/null
+++ b/qpid/java/management/client/console/images/qpid-logo.png
Binary files differ
diff --git a/qpid/java/management/client/console/images/style.css b/qpid/java/management/client/console/images/style.css
new file mode 100644
index 0000000000..a32682fa2f
--- /dev/null
+++ b/qpid/java/management/client/console/images/style.css
@@ -0,0 +1,202 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+body
+{
+ margin-left: 0px;
+ margin-top: 0px;
+ margin-right: 0px;
+ margin-bottom: 0px;
+}
+
+tr th {
+ padding: 4px 8px 4px 8px;
+ background: #5E7796;
+ border: 1px solid #CCC;
+ color:#b8ce83;
+ font-size: smaller;
+}
+
+fieldset
+{
+ font-size: xx-small;
+}
+
+#header
+{
+ width:1024px;
+}
+
+#content
+{
+ width:1024px;
+}
+
+#contenttext
+{
+ float:left; width:824px;
+ background-color:#FFFFFF;
+ border-left:solid 1px #999999; border-right:solid 1px #999999;
+ border-bottom:solid 1px #999999; border-top:dotted 1px #CCCCCC;
+ min-height:360px;
+}
+
+#asf-header
+{
+ float:left;
+ width:1007px;
+ height:110px;
+ background-color:#FFFFFF;
+ border-right:solid 1px #999999;
+ border-left:solid 1px #999999;
+}
+
+#pagetitle
+{
+ position:relative;
+ float:left;
+ width:1024px;
+ height:110px;
+ background-color:#FFFFFF;
+}
+
+#title
+{
+ position:absolute;
+ right:20px;
+ bottom:0px;
+ width:1008px;
+}
+
+#menu
+{
+ float:left; width: 190px; margin: 0 0 0 -7px;
+}
+
+.panel{
+ padding:12px;
+ margin: 5px;
+ padding:10px;
+}
+
+.bodytext {
+ font: 0.7em Tahoma, sans-serif;
+ color: #666666;
+}
+
+.titletext {
+ font: 0.7em Tahoma, sans-serif;
+ font-size:36px;
+ font-weight:bold;
+ color: #CCCCCC;
+}
+
+.orangelogotext {
+ font: 0.7em Tahoma, sans-serif;
+ font-size:36px;
+ font-weight:bold;
+ color:#FF9900;
+}
+.orangetitle {
+ font: 0.7em Tahoma, sans-serif;
+ font-size:24px;
+ font-weight:bold;
+ color:#FF9900;
+}
+
+.bluetitle {
+ font: 0.7em Tahoma, sans-serif;
+ font-size:24px;
+ font-weight:bold;
+ color:#369;
+}
+
+#linksmenu a{
+ float:right;
+ width:183px;
+ height:20px;
+ background-color:#5E7796;
+ border-left:solid 1px #FFFFFF;
+ border-bottom:solid 1px #FFFFFF;
+ font: 0.7em Tahoma, sans-serif;
+ font-size: 11px;
+ font-weight:bold;
+ color: #FFFFFF;
+ text-decoration:none;
+ padding-top:5px;
+}
+#linksmenu a:hover
+{
+ background-color:#336;
+}
+
+
+#wsdmmenu
+{
+ float:left;
+ position: relative;
+ width: 600px;
+ font-size:75%;
+ margin: 0 0 0px 5px;
+ line-height:normal;
+}
+
+#wsdmmenu ul
+{
+ margin:0;
+ padding:0px 0px 0 0px;
+ list-style: none;
+}
+
+#wsdmmenu li
+{
+ display:inline;
+ margin:0;
+ padding:0;
+}
+
+#wsdmmenu a {
+ float:left;
+ background: url(menuleft.gif) no-repeat left top;
+ margin:0;
+ padding:0 0 0 4px;
+ text-decoration:none;
+}
+
+#wsdmmenu a span {
+ float:left;
+ display:block;
+ background: url(menuright.gif) no-repeat right top;
+ padding:5px 15px 4px 6px;
+ color:#888;
+}
+
+#wsdmmenu a span {float:none;}
+
+#wsdmmenu a:hover
+{
+ background-position:0% -42px;
+}
+
+#wsdmmenu a:hover span
+{
+ background-position:100% -42px;
+}
diff --git a/qpid/java/management/client/console/jmx_perspective.jsp b/qpid/java/management/client/console/jmx_perspective.jsp
new file mode 100644
index 0000000000..5d276a0edc
--- /dev/null
+++ b/qpid/java/management/client/console/jmx_perspective.jsp
@@ -0,0 +1,157 @@
+<!--
+
+ 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.
+
+-->
+
+<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
+<%@ taglib uri='http://java.sun.com/jsp/jstl/core' prefix='c'%>
+<%@page import="org.apache.qpid.management.web.action.BrokerModel"%>
+<%@page import="java.util.Set"%>
+<%@page import="javax.management.ObjectName"%>
+<%@page import="org.apache.qpid.management.Names"%>
+<%@page import="java.util.List"%>
+<html>
+ <head>
+ <link rel="stylesheet" href="<%=request.getContextPath()%>/images/style.css" type="text/css" />
+ <title>QMan Administration Console</title>
+ </head>
+ <body>
+ <div id="page" align="center">
+ <jsp:include page="/fragments/header.jsp">
+ <jsp:param name="title" value="Resource Management - JMX Perspective"/>
+ </jsp:include>
+
+ <div id="content" align="center">
+ <jsp:include page="/fragments/menu.jsp"/>
+
+ <div id="contenttext">
+ <div id="wsdmmenu" align="left">
+ <ul>
+ <li><a href="<%=request.getContextPath()%>/jmx_perspective?resourceId=${resourceId}"><span>JMX</span></a></li>
+ <li><a href="<%=request.getContextPath()%>/wsdm_properties_perspective?resourceId=${resourceId}"><span>WS-DM</span></a></li>
+ </ul>
+ </div>
+ <br />
+ <div class="panel" align="justify">
+ <span class="bodytext">
+ <table width="100%">
+ <tr>
+ <td valign="top" colspan="2">
+ <fieldset>
+ <legend>ObjectName</legend>
+ <ul>
+ <c:forEach var="property" items="${nameAttributes}">
+ <li>
+ <c:out value="${property}"/>
+ </li>
+ </c:forEach>
+ </ul>
+ </fieldset>
+ </td>
+ </tr>
+ <tr>
+ <td valign="top">
+ <fieldset>
+ <legend>Attributes</legend>
+ <table width="100%" cellspacing="1">
+ <tr>
+ <th>Name</th>
+ <th>Type</th>
+ <th>Value</th>
+ <th>Access</th>
+ </tr>
+ <c:forEach var="attribute" items="${metadata.attributes}" varStatus="rowCounter">
+ <c:choose>
+ <c:when test="${rowCounter.count % 2 == 0}">
+ <c:set var="bgcolor" scope="page" value="EAEAEA"/>
+ </c:when>
+ <c:otherwise>
+ <c:set var="bgcolor" scope="page" value="FFFFFF"/>
+ </c:otherwise>
+ </c:choose>
+ <c:choose>
+ <c:when test="${attribute.writable}">
+ <c:set var="access" scope="page" value="RW"/>
+ </c:when>
+ <c:otherwise>
+ <c:set var="access" scope="page" value="RO"/>
+ </c:otherwise>
+ </c:choose>
+ <tr>
+ <td nowrap style="font-size: xx-small; font-weight: bold;" bgcolor="${bgcolor}"><c:out value="${attribute.name}"/></td>
+ <td nowrap style="font-size: xx-small; font-weight: bold;" bgcolor="${bgcolor}"><c:out value="${attribute.type}"/></td>
+ <td style="font-size: xx-small; font-weight: bold;" bgcolor="${bgcolor}"><c:out value="${attributes[attribute.name]}"/></td>
+ <td nowrap style="font-size: xx-small; font-weight: bold;" bgcolor="${bgcolor}"><c:out value="${access}"/></td>
+ </tr>
+ </c:forEach>
+ </table>
+ </fieldset>
+ </td>
+ <td valign="top">
+ <fieldset>
+ <legend>Operations</legend>
+ <table width="100%" cellspacing="0">
+ <tr>
+ <th>Name</th>
+ <th>Arguments</th>
+ </tr>
+
+ <c:forEach var="operation" items="${metadata.operations}" varStatus="rowCounter">
+ <c:choose>
+ <c:when test="${rowCounter.count % 2 == 0}">
+ <c:set var="bgcolor" scope="page" value="EAEAEA"/>
+ </c:when>
+ <c:otherwise>
+ <c:set var="bgcolor" scope="page" value="FFFFFF"/>
+ </c:otherwise>
+ </c:choose>
+ <tr>
+ <td nowrap style="font-size: xx-small; font-weight: bold;" bgcolor="${bgcolor}"><c:out value="${operation.name}"/></td>
+ <td nowrap style="font-size: xx-small; font-weight: bold;" bgcolor="${bgcolor}">
+ <ul>
+ <c:forEach var="argument" items="${operation.signature}">
+ <li>
+ <c:out value="${argument.name}"/> (<c:out value="${argument.type}"/>)
+ </li>
+ </c:forEach>
+ </ul>
+ </td>
+ </tr>
+ </c:forEach>
+ </fieldset>
+ </td>
+ </tr>
+ </table>
+ </span>
+ </div>
+ </div>
+
+
+
+
+
+
+
+
+
+
+ </div>
+ </div>
+ </body>
+</html>
diff --git a/qpid/java/management/client/console/logging_configuration.jsp b/qpid/java/management/client/console/logging_configuration.jsp
new file mode 100644
index 0000000000..89f10567fa
--- /dev/null
+++ b/qpid/java/management/client/console/logging_configuration.jsp
@@ -0,0 +1,241 @@
+<!--
+
+ 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.
+
+-->
+
+<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
+<%@ taglib uri='http://java.sun.com/jsp/jstl/core' prefix='c'%>
+<html>
+ <head>
+ <link rel="stylesheet" href="<%=request.getContextPath()%>/images/style.css" type="text/css" />
+ <title>QMan Administration Console</title>
+ </head>
+ <body>
+ <div id="page" align="center">
+ <jsp:include page="/fragments/header.jsp">
+ <jsp:param name="title" value="Logging Configuration"/>
+ </jsp:include>
+
+ <div id="content" align="center">
+ <jsp:include page="/fragments/menu.jsp"/>
+
+ <div id="contenttext">
+ <div class="panel" align="justify" style="height:500px; overflow-y:auto;">
+ <span class="bodytext">
+ <form method="post" name="form" action="<%=request.getContextPath() %>/logging_configuration">
+ <table>
+ <tr>
+ <td>
+ <fieldset>
+ <legend>WSDL & RDM Debugger</legend>
+ <table>
+ <tr>
+ <td>
+ <c:choose>
+ <c:when test="${wsdlDebugEnabled}">
+ <c:set var="checked" scope="page" value="checked"/>
+ </c:when>
+ <c:otherwise>
+ <c:set var="checked" scope="page" value=""/>
+ </c:otherwise>
+ </c:choose>
+ <input type="checkbox" ${checked} name="wsdlDebugEnabled" />
+ </td>
+ <td nowrap style="font-size: x-small;">
+ When this flag is checked all WSDL and RMD messages are written on log file (or console depending on your configuration.)
+ </td>
+ </tr>
+ </table>
+ </fieldset>
+ </td>
+ </tr>
+
+ <tr>
+ <td>
+ <fieldset>
+ <legend>SOAP Messages Debugger</legend>
+ <table>
+
+ <tr>
+ <td>
+ <c:choose>
+ <c:when test="${soapDebugEnabled}">
+ <c:set var="checked" scope="page" value="checked"/>
+ </c:when>
+ <c:otherwise>
+ <c:set var="checked" scope="page" value=""/>
+ </c:otherwise>
+ </c:choose>
+ <input ${checked} type="checkbox" name="soapDebugEnabled"/>
+ </td>
+ <td nowrap style="font-size: x-small;">
+ When this flag is checked all SOAP messages (requests & responses) are written on log file (or console depending on your configuration.)
+ </td>
+ </tr>
+ </table>
+ </fieldset>
+ </td>
+ </tr>
+
+ <tr>
+ <td>
+ <fieldset>
+ <legend>QMan Logger Level</legend>
+ <table>
+ <tr>
+ <td>
+ <c:choose>
+ <c:when test="${qmanLogLevel == 'DEBUG'}">
+ <c:set var="qmanDebug" scope="page" value="selected='true'"/>
+ </c:when>
+ <c:otherwise>
+ <c:set var="qmanDebug" scope="page" value=""/>
+ </c:otherwise>
+ </c:choose>
+ <c:choose>
+ <c:when test="${qmanLogLevel == 'INFO'}">
+ <c:set var="qmanInfo" scope="page" value="selected='true'"/>
+ </c:when>
+ <c:otherwise>
+ <c:set var="qmanInfo" scope="page" value=""/>
+ </c:otherwise>
+ </c:choose>
+ <c:choose>
+ <c:when test="${qmanLogLevel == 'WARN'}">
+ <c:set var="qmanWarn" scope="page" value="selected='true'"/>
+ </c:when>
+ <c:otherwise>
+ <c:set var="qmanWarn" scope="page" value=""/>
+ </c:otherwise>
+ </c:choose>
+ <c:choose>
+ <c:when test="${qmanLogLevel == 'ERROR'}">
+ <c:set var="qmanError" scope="page" value="selected='true'"/>
+ </c:when>
+ <c:otherwise>
+ <c:set var="qmanError" scope="page" value=""/>
+ </c:otherwise>
+ </c:choose>
+ <c:choose>
+ <c:when test="${qmanLogLevel == 'FATAL'}">
+ <c:set var="qmanFatal" scope="page" value="selected='true'"/>
+ </c:when>
+ <c:otherwise>
+ <c:set var="qmanFatal" scope="page" value=""/>
+ </c:otherwise>
+ </c:choose>
+
+ <select name="qmanLogLevel">
+ <option ${qmanDebug} value="DEBUG">DEBUG</option>
+ <option ${qmanWarn} value="WARN">WARNING</option>
+ <option ${qmanInfo} value="INFO">INFO</option>
+ <option ${qmanError} value="ERROR">ERROR</option>
+ <option ${qmanFatal} value="FATAL">FATAL</option>
+ </select>
+ </td>
+ <td nowrap style="font-size: x-small;">
+ This is the current priority level set for QMan module (and sub-modules). Note that a WARNING level is recomended in production.
+ </td>
+ </tr>
+ </table>
+ </fieldset>
+ </td>
+ </tr>
+
+ <tr>
+ <td>
+ <fieldset>
+ <legend>Web Server Logger Level</legend>
+ <table>
+
+ <tr>
+ <td>
+ <c:choose>
+ <c:when test="${webServerLogLevel == 'DEBUG'}">
+ <c:set var="webServerDebug" scope="page" value="selected='true'"/>
+ </c:when>
+ <c:otherwise>
+ <c:set var="webServerDebug" scope="page" value=""/>
+ </c:otherwise>
+ </c:choose>
+ <c:choose>
+ <c:when test="${webServerLogLevel == 'INFO'}">
+ <c:set var="webServerInfo" scope="page" value="selected='true'"/>
+ </c:when>
+ <c:otherwise>
+ <c:set var="webServerInfo" scope="page" value=""/>
+ </c:otherwise>
+ </c:choose>
+ <c:choose>
+ <c:when test="${webServerLogLevel == 'WARN'}">
+ <c:set var="webServerWarn" scope="page" value="selected='true'"/>
+ </c:when>
+ <c:otherwise>
+ <c:set var="webServerWarn" scope="page" value=""/>
+ </c:otherwise>
+ </c:choose>
+ <c:choose>
+ <c:when test="${webServerLogLevel == 'ERROR'}">
+ <c:set var="webServerError" scope="page" value="selected='true'"/>
+ </c:when>
+ <c:otherwise>
+ <c:set var="webServerError" scope="page" value=""/>
+ </c:otherwise>
+ </c:choose>
+ <c:choose>
+ <c:when test="${webServerLogLevel == 'FATAL'}">
+ <c:set var="webServerFatal" scope="page" value="selected='true'"/>
+ </c:when>
+ <c:otherwise>
+ <c:set var="webServerFatal" scope="page" value=""/>
+ </c:otherwise>
+ </c:choose>
+
+ <select name="webServerLogLevel">
+ <option ${webServerDebug} value="DEBUG" >DEBUG</option>
+ <option ${webServerWarn} value="WARN">WARNING</option>
+ <option ${webServerInfo} value="INFO">INFO</option>
+ <option ${webServerError} value="ERROR">ERROR</option>
+ <option ${webServerFatak} value="FATAL">FATAL</option>
+ </select>
+ </td>
+ <td nowrap style="font-size: x-small; ">
+ This is the current priority level set for QMan module (and sub-modules). Note that a WARNING level is recomended in production.
+ </td>
+ </tr>
+ </table>
+ </fieldset>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <input type="submit" value="Submit" title="Submit"/>
+ </td>
+ </tr>
+ </table>
+ <br/></br>
+ <span style="fony-size: medium; color: red; font-weight: bold">Note that in general a DEBUG level is not reccommended in production (especially for WSDL and SOAP debugger).</span>
+ </form>
+ </span>
+ </div>
+ </div>
+ </div>
+ </div>
+ </body>
+</html>
diff --git a/qpid/java/management/client/console/resources_management.jsp b/qpid/java/management/client/console/resources_management.jsp
new file mode 100644
index 0000000000..4a6f9efed6
--- /dev/null
+++ b/qpid/java/management/client/console/resources_management.jsp
@@ -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.
+
+-->
+
+<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
+<%@ taglib uri='http://java.sun.com/jsp/jstl/core' prefix='c'%>
+<%@page import="org.apache.qpid.management.web.action.BrokerModel"%>
+<%@page import="java.util.Set"%>
+<%@page import="javax.management.ObjectName"%>
+<%@page import="org.apache.qpid.management.Names"%>
+<%@page import="java.util.List"%>
+
+<%
+ BrokerModel model = (BrokerModel) request.getAttribute("model");
+%>
+<html>
+ <head>
+ <link rel="stylesheet" href="<%=request.getContextPath()%>/images/style.css" type="text/css" />
+ <title>QMan Administration Console</title>
+ </head>
+ <body>
+ <div id="page" align="center">
+ <jsp:include page="/fragments/header.jsp">
+ <jsp:param name="title" value="Resources Management"/>
+ </jsp:include>
+
+ <div id="content" align="center">
+ <jsp:include page="/fragments/menu.jsp"/>
+
+
+ <div id="contenttext">
+ <div id="wsdmmenu" align="left">
+ <ul>
+ <% if (model != null) {%>
+ <li><a href="#"><span>${model.id}</span></a></li>
+ <%} %>
+ </ul>
+ </div>
+ <br />
+ <div class="panel" align="justify" style="height:500px; overflow-y:auto;">
+ <span class="bodytext">
+ <table width="100%" border="0" cellpadding="1" cellspacing="2">
+<%
+ if (model != null ){
+ Set<String> categoryNames = model.getCategoryNames();
+ for(String categoryName : categoryNames)
+ {
+ List<ObjectName> categoryObjects = model.getCategory(categoryName);
+%>
+ <tr>
+ <td valign="top" nowrap align="left">
+ <fieldset>
+ <legend><%=categoryName%></legend>
+ <h4 style="color: #006633; font-size: xx-small">
+ <ul>
+ <%
+ for (ObjectName objectName : categoryObjects)
+ {%>
+
+ <li>
+ <a href="<%=request.getContextPath()%>/jmx_perspective?resourceId=<%=objectName%>">
+ <%=objectName.getKeyProperty(Names.OBJECT_ID)%>
+ </a>
+ </li>
+ <%
+ }
+ %>
+ </ul>
+ </fieldset>
+ </td>
+ </tr>
+<%
+ }
+ } else {
+%>
+<table><tr>
+<td nowrap style="font-weight: bold;" >Sorry, but it seems that QMan is not connected with any broker...</td>
+</tr>
+</table>
+<%
+ }
+%>
+ </table>
+ </span>
+ </div>
+ </div>
+ </body>
+</html>
diff --git a/qpid/java/management/client/console/tbd.jsp b/qpid/java/management/client/console/tbd.jsp
new file mode 100644
index 0000000000..3c1c87a7b0
--- /dev/null
+++ b/qpid/java/management/client/console/tbd.jsp
@@ -0,0 +1,48 @@
+<!--
+
+ 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.
+
+-->
+
+<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
+<%@ taglib uri='http://java.sun.com/jsp/jstl/core' prefix='c'%>
+<html>
+ <head>
+ <link rel="stylesheet" href="<%=request.getContextPath()%>/images/style.css" type="text/css" />
+ <title>QMan Administration Console</title>
+ </head>
+ <body>
+ <div id="page" align="center">
+ <jsp:include page="/fragments/header.jsp">
+ <jsp:param name="title" value="TBD"/>
+ </jsp:include>
+
+ <div id="content" align="center">
+ <jsp:include page="/fragments/menu.jsp"/>
+
+ <div id="contenttext">
+ <div class="panel" align="justify" style="height:500px; overflow-y:auto;">
+ <span class="bodytext">
+ Sorry, this feature is not yet available!
+ </span>
+ </div>
+ </div>
+ </div>
+ </div>
+ </body>
+</html>
diff --git a/qpid/java/management/client/console/wsdm_operations_perspective.jsp b/qpid/java/management/client/console/wsdm_operations_perspective.jsp
new file mode 100644
index 0000000000..50f67c4492
--- /dev/null
+++ b/qpid/java/management/client/console/wsdm_operations_perspective.jsp
@@ -0,0 +1,174 @@
+<!--
+
+ 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.
+
+-->
+
+<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
+<%@ taglib uri='http://java.sun.com/jsp/jstl/core' prefix='c'%>
+<%@page import="org.apache.qpid.management.web.action.BrokerModel"%>
+<%@page import="java.util.Set"%>
+<%@page import="javax.management.ObjectName"%>
+<%@page import="org.apache.qpid.management.Names"%>
+<%@page import="java.util.*"%>
+<%
+ Map<String,String> java2Xml = new HashMap<String,String>();
+java2Xml.put(UUID.class.getName(),"qman:uuid");
+java2Xml.put(Long.class.getName(),"xsd:long");
+java2Xml.put(long.class.getName(),"xsd:long");
+java2Xml.put(Boolean.class.getName(),"xsd:boolean");
+java2Xml.put(boolean.class.getName(),"xsd:boolean");
+java2Xml.put(Double.class.getName(),"xsd:double");
+java2Xml.put(double.class.getName(),"xsd:double");
+java2Xml.put(Float.class.getName(),"xsd:float");
+java2Xml.put(float.class.getName(),"xsd:float");
+java2Xml.put(Integer.class.getName(),"xsd:integer");
+java2Xml.put(int.class.getName(),"xsd:integer");
+java2Xml.put(Short.class.getName(),"xsd:short");
+java2Xml.put(short.class.getName(),"xsd:short");
+java2Xml.put(String.class.getName(),"xsd:string");
+java2Xml.put(URI.class.getName(),"xsd:anyURI");
+java2Xml.put(Date.class.getName(),"xsd:dateTime");
+java2Xml.put(QName.class.getName(),"xsd:QName");
+java2Xml.put(Element.class.getName(),"xsd:element");
+java2Xml.put(byte[].class.getName(),"xsd:base64Binary");
+java2Xml.put(Long[].class.getName(),"qman:arrayOfLong");
+java2Xml.put(long[].class.getName(),"qman:arrayOfLong");
+java2Xml.put(Boolean[].class.getName(),"qman:arrayOfBoolean");
+java2Xml.put(boolean[].class.getName(),"qman:arrayOfBoolean");
+java2Xml.put(Double[].class.getName(),"qman:arrayOfDouble");
+java2Xml.put(double[].class.getName(),"qman:arrayOfDouble");
+java2Xml.put(Float[].class.getName(),"qman:arrayOfFloat");
+java2Xml.put(float[].class.getName(),"qman:arrayOfFloat");
+java2Xml.put(Integer[].class.getName(),"qman:arrayOfInteger");
+java2Xml.put(int[].class.getName(),"qman:arrayOfInteger");
+java2Xml.put(Short[].class.getName(),"qman:arrayOfShort");
+java2Xml.put(short[].class.getName(),"qman:arrayOfShort");
+java2Xml.put(String[].class.getName(),"qman:arrayOfString");
+java2Xml.put(URI[].class.getName(),"qman:arrayOfURI");
+java2Xml.put(Date[].class.getName(),"qman:arrayOfDate");
+java2Xml.put(Map.class.getName(),"qman:map");
+java2Xml.put(HashMap.class.getName(),"qman:map");
+
+pageContext.setAttribute("types",java2Xml);
+%>
+<%@page import="java.net.URI"%>
+<%@page import="javax.xml.namespace.QName"%>
+<%@page import="org.w3c.dom.Element"%>
+<html>
+ <head>
+ <link rel="stylesheet" href="<%=request.getContextPath()%>/images/style.css" type="text/css" />
+ <title>QMan Administration Console</title>
+ </head>
+ <body>
+ <div id="page" align="center">
+ <jsp:include page="/fragments/header.jsp">
+ <jsp:param name="title" value="Resource Management - WS-DM Operations Perspective"/>
+ </jsp:include>
+
+ <div id="content" align="center">
+ <jsp:include page="/fragments/menu.jsp"/>
+
+ <div id="contenttext">
+ <div id="wsdmmenu" align="left">
+ <ul>
+ <li><a href="<%=request.getContextPath()%>/jmx_perspective?resourceId=${resourceId}"><span>JMX</span></a></li>
+ <li><a href="<%=request.getContextPath()%>/wsdm_properties_perspective?wsresourceId=${resourceId}"><span>WS-DM</span></a></li>
+ </ul>
+ </div>
+ <br />
+ <div class="panel" align="justify">
+ <span class="bodytext">
+ <table width="100%">
+ <tr>
+ <td valign="top" colspan="2">
+ <fieldset>
+ <legend>Resource ID</legend>
+ <ul>
+ <c:forEach var="property" items="${nameAttributes}">
+ <li>
+ <c:out value="${property}"/>
+ </li>
+ </c:forEach>
+ </ul>
+ </fieldset>
+ </td>
+ </tr>
+ <tr>
+ <td valign="top">
+ <div id="wsdmmenu" align="left" style="font-size: small;">
+ <ul>
+ <li><a href="<%=request.getContextPath()%>/wsdm_properties_perspective?resourceId=${resourceId}"><span>Properties</span></a></li>
+ <li><a href="<%=request.getContextPath()%>/wsdm_operations_perspective?resourceId=${resourceId}""><span>Operations</span></a></li>
+ <li><a href="<%=request.getContextPath()%>/wsdm_wsdl_perspective?resourceId=${resourceId}""><span>WSDL</span></a></li>
+ <li><a href="<%=request.getContextPath()%>/wsdm_rmd_perspective?resourceId=${resourceId}""><span>RDM</span></a></li>
+ </ul>
+ </div>
+ </td>
+ </tr>
+ <tr>
+ <td valign="top">
+ <fieldset>
+ <legend>Attributes</legend>
+ <table width="100%" cellspacing="1">
+ <tr>
+ <th nowrap="nowrap" align="center">Name</th>
+ <th nowrap="nowrap" align="center">Arguments</th>
+ <th nowrap="nowrap" align="center">Faults</th>
+ </tr>
+ <c:forEach var="operation" items="${metadata.operations}" varStatus="rowCounter">
+ <c:choose>
+ <c:when test="${rowCounter.count % 2 == 0}">
+ <c:set var="bgcolor" scope="page" value="EAEAEA"/>
+ </c:when>
+ <c:otherwise>
+ <c:set var="bgcolor" scope="page" value="FFFFFF"/>
+ </c:otherwise>
+ </c:choose>
+ <tr>
+ <td nowrap style="font-size: xx-small; font-weight: bold;" bgcolor="${bgcolor}"><c:out value="${operation.name}"/></td>
+ <td nowrap style="font-size: xx-small; font-weight: bold;" bgcolor="${bgcolor}">
+ <ul>
+ <c:forEach var="argument" items="${operation.signature}">
+ <li>
+ <c:out value="${argument.name}"/> (<c:out value="${types[argument.type]}"/>)
+ </li>
+ </c:forEach>
+ </ul>
+ </td>
+ <td nowrap style="font-size: xx-small; font-weight: bold;" bgcolor="${bgcolor}">
+ <ul>
+ <li>qman:EntityInstanceNotFoundFault</li>
+ <li>qman:OperationInvocationFault</li>
+ <li>qman:QManFault</li>
+ </ul>
+ </td>
+ </tr>
+ </c:forEach>
+ </table>
+ </fieldset>
+ </td>
+ </tr>
+ </table>
+ </span>
+ </div>
+ </div>
+ </div>
+ </div>
+ </body>
+</html>
diff --git a/qpid/java/management/client/console/wsdm_properties_perspective.jsp b/qpid/java/management/client/console/wsdm_properties_perspective.jsp
new file mode 100644
index 0000000000..7769abc71c
--- /dev/null
+++ b/qpid/java/management/client/console/wsdm_properties_perspective.jsp
@@ -0,0 +1,218 @@
+<!--
+
+ 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.
+
+-->
+
+<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
+<%@ taglib uri='http://java.sun.com/jsp/jstl/core' prefix='c'%>
+<%@page import="org.apache.qpid.management.web.action.BrokerModel"%>
+<%@page import="java.util.Set"%>
+<%@page import="javax.management.ObjectName"%>
+<%@page import="org.apache.qpid.management.Names"%>
+<%@page import="java.util.List"%>
+<%@page import="java.util.*"%>
+
+<%
+ Map<String,String> java2Xml = new HashMap<String,String>();
+java2Xml.put(UUID.class.getName(),"qman:uuid");
+java2Xml.put(Long.class.getName(),"xsd:long");
+java2Xml.put(long.class.getName(),"xsd:long");
+java2Xml.put(Boolean.class.getName(),"xsd:boolean");
+java2Xml.put(boolean.class.getName(),"xsd:boolean");
+java2Xml.put(Double.class.getName(),"xsd:double");
+java2Xml.put(double.class.getName(),"xsd:double");
+java2Xml.put(Float.class.getName(),"xsd:float");
+java2Xml.put(float.class.getName(),"xsd:float");
+java2Xml.put(Integer.class.getName(),"xsd:integer");
+java2Xml.put(int.class.getName(),"xsd:integer");
+java2Xml.put(Short.class.getName(),"xsd:short");
+java2Xml.put(short.class.getName(),"xsd:short");
+java2Xml.put(String.class.getName(),"xsd:string");
+java2Xml.put(URI.class.getName(),"xsd:anyURI");
+java2Xml.put(Date.class.getName(),"xsd:dateTime");
+java2Xml.put(QName.class.getName(),"xsd:QName");
+java2Xml.put(Element.class.getName(),"xsd:element");
+java2Xml.put(byte[].class.getName(),"xsd:base64Binary");
+java2Xml.put(Long[].class.getName(),"qman:arrayOfLong");
+java2Xml.put(long[].class.getName(),"qman:arrayOfLong");
+java2Xml.put(Boolean[].class.getName(),"qman:arrayOfBoolean");
+java2Xml.put(boolean[].class.getName(),"qman:arrayOfBoolean");
+java2Xml.put(Double[].class.getName(),"qman:arrayOfDouble");
+java2Xml.put(double[].class.getName(),"qman:arrayOfDouble");
+java2Xml.put(Float[].class.getName(),"qman:arrayOfFloat");
+java2Xml.put(float[].class.getName(),"qman:arrayOfFloat");
+java2Xml.put(Integer[].class.getName(),"qman:arrayOfInteger");
+java2Xml.put(int[].class.getName(),"qman:arrayOfInteger");
+java2Xml.put(Short[].class.getName(),"qman:arrayOfShort");
+java2Xml.put(short[].class.getName(),"qman:arrayOfShort");
+java2Xml.put(String[].class.getName(),"qman:arrayOfString");
+java2Xml.put(URI[].class.getName(),"qman:arrayOfURI");
+java2Xml.put(Date[].class.getName(),"qman:arrayOfDate");
+java2Xml.put(Map.class.getName(),"qman:map");
+java2Xml.put(HashMap.class.getName(),"qman:map");
+
+pageContext.setAttribute("types",java2Xml);
+%>
+<%@page import="java.net.URI"%>
+<%@page import="javax.xml.namespace.QName"%>
+<%@page import="org.w3c.dom.Element"%>
+<html>
+ <head>
+ <link rel="stylesheet" href="<%=request.getContextPath()%>/images/style.css" type="text/css" />
+ <title>QMan Administration Console</title>
+ </head>
+ <body>
+ <div id="page" align="center">
+ <jsp:include page="/fragments/header.jsp">
+ <jsp:param name="title" value="Resource Management - WS-DM Properties Perspective"/>
+ </jsp:include>
+
+ <div id="content" align="center">
+ <jsp:include page="/fragments/menu.jsp"/>
+
+ <div id="contenttext">
+ <div id="wsdmmenu" align="left">
+ <ul>
+ <li><a href="<%=request.getContextPath()%>/jmx_perspective?resourceId=${resourceId}"><span>JMX</span></a></li>
+ <li><a href="<%=request.getContextPath()%>/wsdm_properties_perspective?resourceId=${resourceId}"><span>WS-DM</span></a></li>
+ </ul>
+ </div>
+ <br />
+ <div class="panel" align="justify">
+ <span class="bodytext">
+ <table width="100%">
+ <tr>
+ <td valign="top" colspan="2">
+ <fieldset>
+ <legend>Resource ID</legend>
+ <ul>
+ <c:forEach var="property" items="${nameAttributes}">
+ <li>
+ <c:out value="${property}"/>
+ </li>
+ </c:forEach>
+ </ul>
+ </fieldset>
+ </td>
+ </tr>
+ <tr>
+ <td valign="top">
+ <div id="wsdmmenu" align="left" style="font-size: small;">
+ <ul>
+ <li><a href="<%=request.getContextPath()%>/wsdm_properties_perspective?resourceId=${resourceId}"><span>Properties</span></a></li>
+ <li><a href="<%=request.getContextPath()%>/wsdm_operations_perspective?resourceId=${resourceId}""><span>Operations</span></a></li>
+ <li><a href="<%=request.getContextPath()%>/wsdm_wsdl_perspective?resourceId=${resourceId}""><span>WSDL</span></a></li>
+ <li><a href="<%=request.getContextPath()%>/wsdm_rmd_perspective?resourceId=${resourceId}""><span>RDM</span></a></li>
+ </ul>
+ </div>
+ </td>
+ </tr>
+ <tr>
+ <td valign="top">
+ <fieldset>
+ <legend>Attributes</legend>
+ <table width="100%" cellspacing="1">
+ <tr>
+ <th nowrap="nowrap" align="center">Name</th>
+ <th nowrap="nowrap" align="center" >Type</th>
+ <th nowrap="nowrap" align="center">Value</th>
+ <th nowrap="nowrap" align="center">Mutable</th>
+ <th nowrap="nowrap" align="center">Access</th>
+ <th nowrap="nowrap" align="center">Valid Values</th>
+ <th nowrap="nowrap" align="center">Static Values</th>
+ <th nowrap="nowrap" align="center">Initial Values</th>
+ </tr>
+ <c:forEach var="attribute" items="${metadata.attributes}" varStatus="rowCounter">
+ <c:choose>
+ <c:when test="${rowCounter.count % 2 == 0}">
+ <c:set var="bgcolor" scope="page" value="EAEAEA"/>
+ </c:when>
+ <c:otherwise>
+ <c:set var="bgcolor" scope="page" value="FFFFFF"/>
+ </c:otherwise>
+ </c:choose>
+ <c:choose>
+ <c:when test="${attribute.writable}">
+ <c:set var="access" scope="page" value="RW"/>
+ </c:when>
+ <c:otherwise>
+ <c:set var="access" scope="page" value="RO"/>
+ </c:otherwise>
+ </c:choose>
+ <tr>
+ <td nowrap style="font-size: xx-small; font-weight: bold;" bgcolor="${bgcolor}"><c:out value="${attribute.name}"/></td>
+ <td nowrap style="font-size: xx-small; font-weight: bold;" bgcolor="${bgcolor}"><c:out value="${types[attribute.type]}"/></td>
+ <td style="font-size: xx-small; font-weight: bold;" bgcolor="${bgcolor}"><c:out value="${attributes[attribute.name]}"/></td>
+ <td nowrap style="font-size: xx-small; font-weight: bold;" bgcolor="${bgcolor}">
+ &radic;
+ <%--
+ <c:out value="${attribute.mutable}"/>
+ --%>
+ </td>
+ <td nowrap style="font-size: xx-small; font-weight: bold;" bgcolor="${bgcolor}"><c:out value="${access}"/></td>
+ <td nowrap style="font-size: xx-small; font-weight: bold;" bgcolor="${bgcolor}">
+ N.A.
+<%--
+ <ul>
+ <c:forEach var="value" items="${attribute.validValues}">
+ <li>
+ <c:out value="${value}"/>
+ </li>
+ </c:forEach>
+ </ul>
+--%>
+ </td>
+ <td nowrap style="font-size: xx-small; font-weight: bold;" bgcolor="${bgcolor}">
+ N.A.
+<%--
+ <ul>
+ <c:forEach var="value" items="${attribute.staticValues}">
+ <li>
+ <c:out value="${value}"/>
+ </li>
+ </c:forEach>
+ </ul>
+--%>
+ </td>
+ <td nowrap style="font-size: xx-small; font-weight: bold;" bgcolor="${bgcolor}">
+ N.A.
+<%--
+ <ul>
+ <c:forEach var="value" items="${attribute.initialValues}">
+ <li>
+ <c:out value="${value}"/>
+ </li>
+ </c:forEach>
+ </ul>
+--%>
+ </td>
+ </tr>
+ </c:forEach>
+ </table>
+ </fieldset>
+ </td>
+ </tr>
+ </table>
+ </span>
+ </div>
+ </div>
+ </div>
+ </div>
+ </body>
+</html>
diff --git a/qpid/java/management/client/console/wsdm_rmd_perspective.jsp b/qpid/java/management/client/console/wsdm_rmd_perspective.jsp
new file mode 100644
index 0000000000..083732668b
--- /dev/null
+++ b/qpid/java/management/client/console/wsdm_rmd_perspective.jsp
@@ -0,0 +1,99 @@
+<!--
+
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+
+-->
+
+<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
+<%@ taglib uri='http://java.sun.com/jsp/jstl/core' prefix="c"%>
+<%@ taglib uri="http://java.sun.com/jsp/jstl/xml" prefix="x"%>
+
+<%@page import="org.apache.qpid.management.web.action.BrokerModel"%>
+<%@page import="java.util.Set"%>
+<%@page import="javax.management.ObjectName"%>
+<%@page import="org.apache.qpid.management.Names"%>
+<%@page import="java.util.*"%>
+<%@page import="java.net.URI"%>
+<%@page import="javax.xml.namespace.QName"%>
+<%@page import="org.w3c.dom.Element"%>
+<html>
+ <head>
+ <link rel="stylesheet" href="<%=request.getContextPath()%>/images/style.css" type="text/css" />
+ <title>QMan Administration Console</title>
+ </head>
+ <body>
+ <div id="page" align="center">
+ <jsp:include page="/fragments/header.jsp">
+ <jsp:param name="title" value="Resource Management - WS-DM RMD Perspective"/>
+ </jsp:include>
+
+ <div id="content" align="center">
+ <jsp:include page="/fragments/menu.jsp"/>
+
+ <div id="contenttext">
+ <div id="wsdmmenu" align="left">
+ <ul>
+ <li><a href="<%=request.getContextPath()%>/jmx_perspective?resourceId=${resourceId}"><span>JMX</span></a></li>
+ <li><a href="<%=request.getContextPath()%>/wsdm_properties_perspective?wsresourceId=${resourceId}"><span>WS-DM</span></a></li>
+ </ul>
+ </div>
+ <br />
+ <div class="panel" align="justify">
+ <span class="bodytext">
+ <table width="100%">
+ <tr>
+ <td valign="top" colspan="2">
+ <fieldset>
+ <legend>Resource ID</legend>
+ <ul>
+ <c:forEach var="property" items="${nameAttributes}">
+ <li>
+ <c:out value="${property}"/>
+ </li>
+ </c:forEach>
+ </ul>
+ </fieldset>
+ </td>
+ </tr>
+ <tr>
+ <td valign="top">
+ <div id="wsdmmenu" align="left" style="font-size: small;">
+ <ul>
+ <li><a href="<%=request.getContextPath()%>/wsdm_properties_perspective?resourceId=${resourceId}"><span>Properties</span></a></li>
+ <li><a href="<%=request.getContextPath()%>/wsdm_operations_perspective?resourceId=${resourceId}""><span>Operations</span></a></li>
+ <li><a href="<%=request.getContextPath()%>/wsdm_wsdl_perspective?resourceId=${resourceId}""><span>WSDL</span></a></li>
+ <li><a href="<%=request.getContextPath()%>/wsdm_rmd_perspective?resourceId=${resourceId}""><span>RDM</span></a></li>
+ </ul>
+ </div>
+ </td>
+ </tr>
+ <tr>
+ <td valign="top">
+ <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>
+ </table>
+ </span>
+ </div>
+ </div>
+ </div>
+ </div>
+ </body>
+</html>
diff --git a/qpid/java/management/client/console/wsdm_wsdl_perspective.jsp b/qpid/java/management/client/console/wsdm_wsdl_perspective.jsp
new file mode 100644
index 0000000000..0674c51a97
--- /dev/null
+++ b/qpid/java/management/client/console/wsdm_wsdl_perspective.jsp
@@ -0,0 +1,99 @@
+<!--
+
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+
+-->
+
+<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
+<%@ taglib uri='http://java.sun.com/jsp/jstl/core' prefix="c"%>
+<%@ taglib uri="http://java.sun.com/jsp/jstl/xml" prefix="x"%>
+
+<%@page import="org.apache.qpid.management.web.action.BrokerModel"%>
+<%@page import="java.util.Set"%>
+<%@page import="javax.management.ObjectName"%>
+<%@page import="org.apache.qpid.management.Names"%>
+<%@page import="java.util.*"%>
+<%@page import="java.net.URI"%>
+<%@page import="javax.xml.namespace.QName"%>
+<%@page import="org.w3c.dom.Element"%>
+<html>
+ <head>
+ <link rel="stylesheet" href="<%=request.getContextPath()%>/images/style.css" type="text/css" />
+ <title>QMan Administration Console</title>
+ </head>
+ <body>
+ <div id="page" align="center">
+ <jsp:include page="/fragments/header.jsp">
+ <jsp:param name="title" value="Resource Management - WS-DM WSDL Perspective"/>
+ </jsp:include>
+
+ <div id="content" align="center">
+ <jsp:include page="/fragments/menu.jsp"/>
+
+ <div id="contenttext">
+ <div id="wsdmmenu" align="left">
+ <ul>
+ <li><a href="<%=request.getContextPath()%>/jmx_perspective?resourceId=${resourceId}"><span>JMX</span></a></li>
+ <li><a href="<%=request.getContextPath()%>/wsdm_properties_perspective?resourceId=${resourceId}"><span>WS-DM</span></a></li>
+ </ul>
+ </div>
+ <br />
+ <div class="panel" align="justify">
+ <span class="bodytext">
+ <table width="100%">
+ <tr>
+ <td valign="top" colspan="2">
+ <fieldset>
+ <legend>Resource ID</legend>
+ <ul>
+ <c:forEach var="property" items="${nameAttributes}">
+ <li style="color : black;">
+ <c:out value="${property}"/>
+ </li>
+ </c:forEach>
+ </ul>
+ </fieldset>
+ </td>
+ </tr>
+ <tr>
+ <td valign="top">
+ <div id="wsdmmenu" align="left" style="font-size: small;">
+ <ul>
+ <li><a href="<%=request.getContextPath()%>/wsdm_properties_perspective?resourceId=${resourceId}"><span>Properties</span></a></li>
+ <li><a href="<%=request.getContextPath()%>/wsdm_operations_perspective?resourceId=${resourceId}""><span>Operations</span></a></li>
+ <li><a href="<%=request.getContextPath()%>/wsdm_wsdl_perspective?resourceId=${resourceId}""><span>WSDL</span></a></li>
+ <li><a href="<%=request.getContextPath()%>/wsdm_rmd_perspective?resourceId=${resourceId}""><span>RDM</span></a></li>
+ </ul>
+ </div>
+ </td>
+ </tr>
+ <tr>
+ <td valign="top">
+ <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>
+ </table>
+ </span>
+ </div>
+ </div>
+ </div>
+ </div>
+ </body>
+</html>
diff --git a/qpid/java/management/client/doc/man/qman-jmx b/qpid/java/management/client/doc/man/qman-jmx
new file mode 100644
index 0000000000..064c00eae5
--- /dev/null
+++ b/qpid/java/management/client/doc/man/qman-jmx
@@ -0,0 +1,17 @@
+.TH qman-jmx
+.SH NAME
+qman-jmx is a Management bridge that exposes one (or several) Qpid broker domain model as MBeans that are accessible through the Java Management Extensions (JMX). Once you run qman you need to start a JMX Console such as JConsole to browse the MBeans exposed by Q-Man.
+.SH SYNOPSIS
+qman
+.SH DESCRIPTION
+For more information on customizing qman-jmx for your own environment please read http://cwiki.apache.org/confluence/display/qpid/Qman+Tool
+.SH Configuration
+.SS Classpath
+By default qman jars will be loaded from /usr/share/java. If you want to load from an alternative location you could specify it using QPID_LIB_PATH var.
+.SS Config file
+qman can be configured to connect to one or more brokers at startup by adding brokers in
+.I /etc/qman-config.xml
+If you want to load qman with qman-config.xml from a different location, you can specify it using QPID_CONFIG_FILE var.
+.SS log4j configuration
+qman expects qman.log4j file to be in the classpath. By default it will be put in
+.I /usr/share/java
diff --git a/qpid/java/management/client/etc/jetty.xml b/qpid/java/management/client/etc/jetty.xml
new file mode 100644
index 0000000000..975053a518
--- /dev/null
+++ b/qpid/java/management/client/etc/jetty.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0"?>
+<!--
+
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+
+-->
+
+<!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN" "http://jetty.mortbay.org/configure.dtd">
+<Configure id="Server" class="org.mortbay.jetty.Server">
+ <Set name="StopAtShutdown">true</Set>
+ <Set name="Connectors">
+ <Array type="org.mortbay.jetty.Connector">
+ <Item>
+ <New
+ class="org.mortbay.jetty.nio.SelectChannelConnector">
+ <Set name="port">
+ <SystemProperty name="qman.port" default="8080" />
+ </Set>
+ <Set name="host">
+ <SystemProperty name="qman.host" default="localhost" />
+ </Set>
+ </New>
+ </Item>
+ </Array>
+ </Set>
+ <Set name="handler">
+ <New class="org.mortbay.jetty.webapp.WebAppContext">
+ <Set name="contextPath">/qman</Set>
+ <Set name="war"><SystemProperty name="QMAN_HOME" default=".." />/app/qman</Set>
+ </New>
+ </Set>
+</Configure>
diff --git a/qpid/java/management/client/etc/qman-config.xml b/qpid/java/management/client/etc/qman-config.xml
new file mode 100644
index 0000000000..cdc840e967
--- /dev/null
+++ b/qpid/java/management/client/etc/qman-config.xml
@@ -0,0 +1,68 @@
+<!--
+ -
+ - Licensed to the Apache Software Foundation (ASF) under one
+ - or more contributor license agreements. See the NOTICE file
+ - distributed with this work for additional information
+ - regarding copyright ownership. The ASF licenses this file
+ - to you under the Apache License, Version 2.0 (the
+ - "License"); you may not use this file except in compliance
+ - with the License. You may obtain a copy of the License at
+ -
+ - http://www.apache.org/licenses/LICENSE-2.0
+ -
+ - Unless required by applicable law or agreed to in writing,
+ - software distributed under the License is distributed on an
+ - "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ - KIND, either express or implied. See the License for the
+ - specific language governing permissions and limitations
+ - under the License.
+ -
+ -->
+<configuration>
+
+<!--
+Default configuration for QMan has no broker settings;
+that is, there's no broker configured at startup.
+If you want to connect with a running broker when QMan starts up,
+you can do that uncommenting and editing the template reported below.
+-->
+<!-- <brokers>
+ <broker>
+ <host>localhost</host>
+ <port>5672</port>
+ <virtual-host>test</virtual-host>
+ <user>guest</user>
+ <password>guest</password>
+ <max-pool-capacity>4</max-pool-capacity>
+ <initial-pool-capacity>0</initial-pool-capacity>
+ <max-wait-timeout>-1</max-wait-timeout>
+ </broker>
+ <broker>
+ <host>localhost</host>
+ <port>5672</port>
+ <virtual-host>test</virtual-host>
+ <user>guest</user>
+ <password>guest</password>
+ <max-pool-capacity>4</max-pool-capacity>
+ <initial-pool-capacity>0</initial-pool-capacity>
+ <max-wait-timeout>-1</max-wait-timeout>
+ </broker>
+ </brokers>
+ -->
+ <!-- Internal worked manager configuration-->
+ <work-manager>
+ <!-- The size of the worker thread pool -->
+ <pool-capacity>5</pool-capacity>
+
+ <!-- Maximum size of the worker thread pool -->
+ <max-pool-capacity>15</max-pool-capacity>
+
+ <!--
+ when the current number of threads is greater than
+ the pool-capacity, this is the maximum time that excess threads
+ can be in an idle state (without any task assigned) before terminating.
+ The value is expressed is milliseconds.
+ -->
+ <keep-alive-time>5000</keep-alive-time>
+ </work-manager>
+</configuration>
diff --git a/qpid/java/management/client/etc/qman-config.xsd b/qpid/java/management/client/etc/qman-config.xsd
new file mode 100644
index 0000000000..38282c63d1
--- /dev/null
+++ b/qpid/java/management/client/etc/qman-config.xsd
@@ -0,0 +1,63 @@
+<!--
+ -
+ - 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.
+ -
+-->
+<?xml version="1.0" encoding="UTF-8"?>
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
+ <xsd:element name="broker">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element ref="host" minOccurs="1" maxOccurs="1"/>
+ <xsd:element ref="port" minOccurs="1" maxOccurs="1"/>
+ <xsd:element ref="virtual-host" minOccurs="1" maxOccurs="1"/>
+ <xsd:element ref="user" minOccurs="1" maxOccurs="1"/>
+ <xsd:element ref="password" minOccurs="1" maxOccurs="1"/>
+ <xsd:element ref="max-pool-capacity" minOccurs="1" maxOccurs="1"/>
+ <xsd:element ref="initial-pool-capacity" minOccurs="1" maxOccurs="1"/>
+ <xsd:element ref="max-wait-timeout" minOccurs="1" maxOccurs="1"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:element name="brokers">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element ref="broker" maxOccurs="unbounded" />
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:element name="configuration">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element ref="brokers" maxOccurs="1" />
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:element name="host" type="xsd:string"/>
+ <xsd:element name="initial-pool-capacity" type="xsd:integer"/>
+ <xsd:element name="max-pool-capacity" type="xsd:integer"/>
+ <xsd:element name="max-wait-timeout" type="xsd:integer"/>
+ <xsd:element name="password" type="xsd:string"/>
+ <xsd:element name="port" type="xsd:integer"/>
+ <xsd:element name="user" type="xsd:string"/>
+ <xsd:element name="virtual-host"type="xsd:string"/>
+
+</schema> \ No newline at end of file
diff --git a/qpid/java/management/client/etc/qman.log4j b/qpid/java/management/client/etc/qman.log4j
new file mode 100644
index 0000000000..bf6f940a6c
--- /dev/null
+++ b/qpid/java/management/client/etc/qman.log4j
@@ -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.
+#
+log4j.rootLogger=${root.logging.level}
+
+log4j.logger.org.apache.qpid=ERROR, console
+log4j.additivity.org.apache.qpid=false
+
+log4j.logger.org.apache.qpid.management.client=DEBUG, console
+
+log4j.appender.console=org.apache.log4j.ConsoleAppender
+log4j.appender.console.Threshold=error
+log4j.appender.console.layout=org.apache.log4j.PatternLayout
+log4j.appender.console.layout.ConversionPattern=%t %d %p [%c{4}] %m%n
diff --git a/qpid/java/management/client/src/example/ConnectWithBroker.out.ok b/qpid/java/management/client/src/example/ConnectWithBroker.out.ok
new file mode 100644
index 0000000000..33af477b98
--- /dev/null
+++ b/qpid/java/management/client/src/example/ConnectWithBroker.out.ok
@@ -0,0 +1,81 @@
+ ConnectWithBrokerExample
+-------------------------------------------------------------------
+
+This example shows how to connect QMan with a broker using
+the adapter interface.
+
+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://amqp.apache.org/qpid/management/qman/Connect</wsa:Action>
+ <wsa:MessageID xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:48bf9a1b-f814-7391-b5cf-d163de4ac068</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>
+ <qman:Connect xmlns:qman="http://amqp.apache.org/qpid/management/qman">
+ <qman:host>sofia.gazzax.com</qman:host>
+ <qman:port>5672</qman:port>
+ <qman:username>test</qman:username>
+ <qman:password>a.gazzarini</qman:password>
+ <qman:virtualHost>p1ssw9rd</qman:virtualHost>
+ <qman:initialPoolCapacity>1</qman:initialPoolCapacity>
+ <qman:maxPoolCapacity>4</qman:maxPoolCapacity>
+ <qman:maxWaitTimeout>2000</qman:maxWaitTimeout>
+ </qman:Connect>
+ </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://www.w3.org/2005/08/addressing/fault</wsa:Action>
+ <wsa:MessageID xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:220bfe54-d5f4-4a04-794c-0f5d99a64567</wsa:MessageID>
+ <wsa:RelatesTo RelationshipType="wsa:Reply" xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:48bf9a1b-f814-7391-b5cf-d163de4ac068</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>
+ <soap:Fault>
+ <soap:Code xmlns:qman="http://amqp.apache.org/qpid/management/qman">
+ <soap:Value>qman:QMan</soap:Value>
+ </soap:Code>
+ <soap:Reason>
+ <soap:Text>Unable to connect with the requested broker. Underlying exception message was null</soap:Text>
+ </soap:Reason>
+ <soap:Detail>
+ <qman:OperationInvocationFault xmlns:qman="http://amqp.apache.org/qpid/management/qman">
+ <wsrf-bf:Timestamp xmlns:wsrf-bf="http://docs.oasis-open.org/wsrf/bf-2">2009-02-17T10:37:08+01:00</wsrf-bf:Timestamp>
+ <wsrf-bf:OriginatorReference xmlns:wsrf-bf="http://docs.oasis-open.org/wsrf/bf-2">
+ <wsa:ReferenceParameters xmlns:wsa="http://www.w3.org/2005/08/addressing"/>
+ <wsa:Address xmlns:wsa="http://www.w3.org/2005/08/addressing">http://romagazzarini:8080/qman/services/adapter</wsa:Address>
+ </wsrf-bf:OriginatorReference>
+ <qman:host>sofia.gazzax.com</qman:host>
+ <qman:port>5672</qman:port>
+ <qman:username>test</qman:username>
+ <qman:virtualHost>p1ssw9rd</qman:virtualHost>
+ </qman:OperationInvocationFault>
+ </soap:Detail>
+ </soap:Fault>
+ </soap:Body>
+</soap:Envelope>
+
+-----------------------EXAMPLE FAILURE-----------
+Not well-defined exception was detected while
+running the example.
+org.apache.muse.ws.addressing.soap.SoapFault: Unable to connect with the requested broker. Underlying exception message was null
+ at org.apache.muse.core.AbstractResourceClient.invoke(AbstractResourceClient.java:298)
+ at org.apache.muse.core.AbstractResourceClient.invoke(AbstractResourceClient.java:232)
+ at org.apache.muse.core.AbstractResourceClient.invoke(AbstractResourceClient.java:211)
+ at org.apache.qpid.management.example.ConnectWithBrokerExample.executeExample(ConnectWithBrokerExample.java:146)
+ at org.apache.qpid.management.example.ConnectWithBrokerExample.execute(ConnectWithBrokerExample.java:97)
+ at org.apache.qpid.management.example.ConnectWithBrokerExample.main(ConnectWithBrokerExample.java:201)
+--------------------------------------------------------
diff --git a/qpid/java/management/client/src/example/GetMultipleResourceProperties.out.ok b/qpid/java/management/client/src/example/GetMultipleResourceProperties.out.ok
new file mode 100644
index 0000000000..005841488d
--- /dev/null
+++ b/qpid/java/management/client/src/example/GetMultipleResourceProperties.out.ok
@@ -0,0 +1,262 @@
+ GetMultipleResourcePropertiesExample
+-------------------------------------------------------------------
+
+This example shows how to get properties from a
+WS-Resource using one request.
+First of all a request is send to WS-DM in order to get
+all registered WS-Resources.
+If the returned list is not empty then a GetMetadataRequest
+to the first child.
+The result metadata descriptor contains all property names of
+the target WS-Resource.
+Those names are then used for retrieving the corresponding values
+using the GetMultipleResourceProperties request.
+
+-------------------------------------------------------------------
+
+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://localhost:8080/qman/services/adapter</wsa:To>
+ <wsa:Action xmlns:wsa="http://www.w3.org/2005/08/addressing">http://docs.oasis-open.org/wsrf/rpw-2/GetResourceProperty/GetResourcePropertyRequest</wsa:Action>
+ <wsa:MessageID xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:1a72feb1-7d76-1014-66d7-cd03aeff3525</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>
+ <wsrf-rp:GetResourceProperty
+ xmlns:wsrf-rp="http://docs.oasis-open.org/wsrf/rp-2" xmlns:wsrf-sg="http://docs.oasis-open.org/wsrf/sg-2">wsrf-sg:Entry</wsrf-rp:GetResourceProperty>
+ </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/wsrf/rpw-2/GetResourceProperty/GetResourcePropertyResponse</wsa:Action>
+ <wsa:MessageID xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:783956b1-4de7-f4b6-5421-536f5f310b9a</wsa:MessageID>
+ <wsa:RelatesTo RelationshipType="wsa:Reply" xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:1a72feb1-7d76-1014-66d7-cd03aeff3525</wsa:RelatesTo>
+ <wsa:From xmlns:wsa="http://www.w3.org/2005/08/addressing">
+ <wsa:Address>http://localhost:8080/qman/services/adapter</wsa:Address>
+ </wsa:From>
+ </soap:Header>
+ <soap:Body>
+ <wsrf-rp:GetResourcePropertyResponse xmlns:wsrf-rp="http://docs.oasis-open.org/wsrf/rp-2">
+ <wsrf-sg:Entry xmlns:wsrf-sg="http://docs.oasis-open.org/wsrf/sg-2">
+ <wsrf-sg:ServiceGroupEntryEPR>
+ <wsa:Address xmlns:wsa="http://www.w3.org/2005/08/addressing">http://localhost:8080/qman/services/ServiceGroupEntry</wsa:Address>
+ <wsa:ReferenceParameters xmlns:wsa="http://www.w3.org/2005/08/addressing">
+ <muse-wsa:ResourceId xmlns:muse-wsa="http://ws.apache.org/muse/addressing">uuid:b220e2bd-0370-da4e-fc71-5e283954d319</muse-wsa:ResourceId>
+ </wsa:ReferenceParameters>
+ </wsrf-sg:ServiceGroupEntryEPR>
+ <wsrf-sg:MemberServiceEPR>
+ <wsa:Address xmlns:wsa="http://www.w3.org/2005/08/addressing">http://localhost:8080/qman/services/QManWsResource</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">Q-MAN: brokerID=8e069b14-40ba-4d48-a2cb-b9f2bef2d404,class=queue,name=1232953394537,objectId=781f4ad7-4c96-4caa-b69d-291461cdb1fc,package=org.apache.qpid</qman-wsa:ResourceId>
+ </wsa:ReferenceParameters>
+ </wsrf-sg:MemberServiceEPR>
+ <wsrf-sg:Content/>
+ </wsrf-sg:Entry>
+ </wsrf-rp:GetResourcePropertyResponse>
+ </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://localhost:8080/qman/services/QManWsResource</wsa:To>
+ <wsa:Action xmlns:wsa="http://www.w3.org/2005/08/addressing">http://schemas.xmlsoap.org/ws/2004/09/mex/GetMetadata</wsa:Action>
+ <wsa:MessageID xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:588288c9-8bb7-04e9-e7bf-7be1e2fe41fb</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">Q-MAN: brokerID=8e069b14-40ba-4d48-a2cb-b9f2bef2d404,class=queue,name=1232953394537,objectId=781f4ad7-4c96-4caa-b69d-291461cdb1fc,package=org.apache.qpid</qman-wsa:ResourceId>
+ </soap:Header>
+ <soap:Body>
+ <qman:GetMetadata xmlns:qman="http://schemas.xmlsoap.org/ws/2004/09/mex">
+ <qman:Dialect>http://docs.oasis-open.org/wsrf/rmd-1</qman:Dialect>
+ </qman:GetMetadata>
+ </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://schemas.xmlsoap.org/ws/2004/09/mex/GetMetadataResponse</wsa:Action>
+ <wsa:MessageID xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:77c5520b-d450-5a8a-7e2b-22a1079392f2</wsa:MessageID>
+ <wsa:RelatesTo RelationshipType="wsa:Reply" xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:588288c9-8bb7-04e9-e7bf-7be1e2fe41fb</wsa:RelatesTo>
+ <wsa:From xmlns:wsa="http://www.w3.org/2005/08/addressing">
+ <wsa:Address>http://localhost:8080/qman/services/QManWsResource</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">Q-MAN: brokerID=8e069b14-40ba-4d48-a2cb-b9f2bef2d404,class=queue,name=1232953394537,objectId=781f4ad7-4c96-4caa-b69d-291461cdb1fc,package=org.apache.qpid</qman-wsa:ResourceId>
+ </wsa:ReferenceParameters>
+ </wsa:From>
+ </soap:Header>
+ <soap:Body>
+ <wsx:Metadata xmlns:wsx="http://schemas.xmlsoap.org/ws/2004/09/mex">
+ <wsx:MetadataSection>
+ <wsrmd:MetadataDescriptor
+ interface="qman:QManWsResourcePortType"
+ name="QManWsResourceMetadata"
+ wsdlLocation="http://docs.oasis-open.org/wsrf/rmd-1 QManWsResource.wsdl"
+ xmlns:qman="http://amqp.apache.org/qpid/management/qman" xmlns:wsrmd="http://docs.oasis-open.org/wsrf/rmd-1">
+ <wsrmd:Property modifiability="read-write"
+ mutability="mutable" name="qman:MgmtPubInterval" xmlns:qman="http://amqp.apache.org/qpid/management/qman">
+ <wsrmd:ValidValues/>
+ <wsrmd:StaticValues/>
+ <wsrmd:InitialValues/>
+ </wsrmd:Property>
+ <wsrmd:Property modifiability="read-only"
+ mutability="mutable" name="qman:Name" xmlns:qman="http://amqp.apache.org/qpid/management/qman">
+ <wsrmd:ValidValues/>
+ <wsrmd:StaticValues/>
+ <wsrmd:InitialValues/>
+ </wsrmd:Property>
+ <wsrmd:Property modifiability="read-only"
+ mutability="mutable" name="wsrl:TerminationTime" xmlns:wsrl="http://docs.oasis-open.org/wsrf/rl-2">
+ <wsrmd:ValidValues/>
+ <wsrmd:StaticValues/>
+ <wsrmd:InitialValues/>
+ </wsrmd:Property>
+ <wsrmd:Property modifiability="read-only"
+ mutability="mutable"
+ name="qman:MsgTotalEnqueues" xmlns:qman="http://amqp.apache.org/qpid/management/qman">
+ <wsrmd:ValidValues/>
+ <wsrmd:StaticValues/>
+ <wsrmd:InitialValues/>
+ </wsrmd:Property>
+ <wsrmd:Property modifiability="read-only"
+ mutability="mutable" name="qman:Arguments" xmlns:qman="http://amqp.apache.org/qpid/management/qman">
+ <wsrmd:ValidValues/>
+ <wsrmd:StaticValues/>
+ <wsrmd:InitialValues/>
+ </wsrmd:Property>
+ <wsrmd:Property modifiability="read-only"
+ mutability="mutable" name="qman:VhostRef" xmlns:qman="http://amqp.apache.org/qpid/management/qman">
+ <wsrmd:ValidValues/>
+ <wsrmd:StaticValues/>
+ <wsrmd:InitialValues/>
+ </wsrmd:Property>
+ <wsrmd:Property modifiability="read-only"
+ mutability="mutable" name="wsrl:CurrentTime" xmlns:wsrl="http://docs.oasis-open.org/wsrf/rl-2">
+ <wsrmd:ValidValues/>
+ <wsrmd:StaticValues/>
+ <wsrmd:InitialValues/>
+ </wsrmd:Property>
+ <wsrmd:Property modifiability="read-write"
+ mutability="mutable" name="qman:ExpireTime" xmlns:qman="http://amqp.apache.org/qpid/management/qman">
+ <wsrmd:ValidValues/>
+ <wsrmd:StaticValues/>
+ <wsrmd:InitialValues/>
+ </wsrmd:Property>
+ <wsrmd:Property modifiability="read-only"
+ mutability="mutable" name="qman:Durable" xmlns:qman="http://amqp.apache.org/qpid/management/qman">
+ <wsrmd:ValidValues/>
+ <wsrmd:StaticValues/>
+ <wsrmd:InitialValues/>
+ </wsrmd:Property>
+ <wsrmd:Property modifiability="read-only"
+ mutability="mutable" name="qman:ConsumerCount" xmlns:qman="http://amqp.apache.org/qpid/management/qman">
+ <wsrmd:ValidValues/>
+ <wsrmd:StaticValues/>
+ <wsrmd:InitialValues/>
+ </wsrmd:Property>
+ <wsrmd:Property modifiability="read-write"
+ mutability="mutable" name="qman:Type" xmlns:qman="http://amqp.apache.org/qpid/management/qman">
+ <wsrmd:ValidValues/>
+ <wsrmd:StaticValues/>
+ <wsrmd:InitialValues/>
+ </wsrmd:Property>
+ </wsrmd:MetadataDescriptor>
+ </wsx:MetadataSection>
+ </wsx:Metadata>
+ </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://localhost:8080/qman/services/QManWsResource</wsa:To>
+ <wsa:Action xmlns:wsa="http://www.w3.org/2005/08/addressing">http://docs.oasis-open.org/wsrf/rpw-2/GetMultipleResourceProperties/GetMultipleResourcePropertiesRequest</wsa:Action>
+ <wsa:MessageID xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:783fc044-58a9-e780-a2ba-5b2ac0454985</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">Q-MAN: brokerID=8e069b14-40ba-4d48-a2cb-b9f2bef2d404,class=queue,name=1232953394537,objectId=781f4ad7-4c96-4caa-b69d-291461cdb1fc,package=org.apache.qpid</qman-wsa:ResourceId>
+ </soap:Header>
+ <soap:Body>
+ <wsrf-rp:GetMultipleResourceProperties xmlns:wsrf-rp="http://docs.oasis-open.org/wsrf/rp-2">
+ <wsrf-rp:ResourceProperty xmlns:qman="http://amqp.apache.org/qpid/management/qman">qman:MgmtPubInterval</wsrf-rp:ResourceProperty>
+ <wsrf-rp:ResourceProperty xmlns:qman="http://amqp.apache.org/qpid/management/qman">qman:Name</wsrf-rp:ResourceProperty>
+ <wsrf-rp:ResourceProperty xmlns:qman="http://amqp.apache.org/qpid/management/qman">qman:MsgTotalEnqueues</wsrf-rp:ResourceProperty>
+ <wsrf-rp:ResourceProperty xmlns:qman="http://amqp.apache.org/qpid/management/qman">qman:Arguments</wsrf-rp:ResourceProperty>
+ <wsrf-rp:ResourceProperty xmlns:qman="http://amqp.apache.org/qpid/management/qman">qman:VhostRef</wsrf-rp:ResourceProperty>
+ <wsrf-rp:ResourceProperty xmlns:qman="http://amqp.apache.org/qpid/management/qman">qman:ExpireTime</wsrf-rp:ResourceProperty>
+ <wsrf-rp:ResourceProperty xmlns:qman="http://amqp.apache.org/qpid/management/qman">qman:Durable</wsrf-rp:ResourceProperty>
+ <wsrf-rp:ResourceProperty xmlns:qman="http://amqp.apache.org/qpid/management/qman">qman:ConsumerCount</wsrf-rp:ResourceProperty>
+ <wsrf-rp:ResourceProperty xmlns:qman="http://amqp.apache.org/qpid/management/qman">qman:Type</wsrf-rp:ResourceProperty>
+ </wsrf-rp:GetMultipleResourceProperties>
+ </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/wsrf/rpw-2/GetMultipleResourceProperties/GetMultipleResourcePropertiesResponse</wsa:Action>
+ <wsa:MessageID xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:9a2d76dd-52ba-ac7c-74cf-4acd99708529</wsa:MessageID>
+ <wsa:RelatesTo RelationshipType="wsa:Reply" xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:783fc044-58a9-e780-a2ba-5b2ac0454985</wsa:RelatesTo>
+ <wsa:From xmlns:wsa="http://www.w3.org/2005/08/addressing">
+ <wsa:Address>http://localhost:8080/qman/services/QManWsResource</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">Q-MAN: brokerID=8e069b14-40ba-4d48-a2cb-b9f2bef2d404,class=queue,name=1232953394537,objectId=781f4ad7-4c96-4caa-b69d-291461cdb1fc,package=org.apache.qpid</qman-wsa:ResourceId>
+ </wsa:ReferenceParameters>
+ </wsa:From>
+ </soap:Header>
+ <soap:Body>
+ <wsrf-rp:GetMultipleResourcePropertiesResponse xmlns:wsrf-rp="http://docs.oasis-open.org/wsrf/rp-2">
+ <qman:MgmtPubInterval xmlns:qman="http://amqp.apache.org/qpid/management/qman">32767</qman:MgmtPubInterval>
+ <qman:Name xmlns:qman="http://amqp.apache.org/qpid/management/qman">Initial Name</qman:Name>
+ <qman:MsgTotalEnqueues xmlns:qman="http://amqp.apache.org/qpid/management/qman">9223372036854775797</qman:MsgTotalEnqueues>
+ <qman:Arguments
+ xmlns:qman="http://amqp.apache.org/qpid/management/qman" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <qman:entry>
+ <qman:key>Key3</qman:key>
+ <qman:value xsi:type="xsd:integer">2147483647</qman:value>
+ </qman:entry>
+ <qman:entry>
+ <qman:key>Key4</qman:key>
+ <qman:value xsi:type="xsd:float">3.4028235E38</qman:value>
+ </qman:entry>
+ <qman:entry>
+ <qman:key>Key1</qman:key>
+ <qman:value xsi:type="xsd:string">aStringValue</qman:value>
+ </qman:entry>
+ <qman:entry>
+ <qman:key>Key2</qman:key>
+ <qman:value xsi:type="xsd:long">-9223372036854775808</qman:value>
+ </qman:entry>
+ </qman:Arguments>
+ <qman:VhostRef xmlns:qman="http://amqp.apache.org/qpid/management/qman">2deef1b3-d2c6-49f3-a8de-51f6a75a1a6b</qman:VhostRef>
+ <qman:ExpireTime xmlns:qman="http://amqp.apache.org/qpid/management/qman">9223372036854775807</qman:ExpireTime>
+ <qman:Durable xmlns:qman="http://amqp.apache.org/qpid/management/qman">true</qman:Durable>
+ <qman:ConsumerCount xmlns:qman="http://amqp.apache.org/qpid/management/qman">-2147483638</qman:ConsumerCount>
+ </wsrf-rp:GetMultipleResourcePropertiesResponse>
+ </soap:Body>
+</soap:Envelope> \ No newline at end of file
diff --git a/qpid/java/management/client/src/example/GetQManResourceMembers.out.ko b/qpid/java/management/client/src/example/GetQManResourceMembers.out.ko
new file mode 100644
index 0000000000..d6b733e430
--- /dev/null
+++ b/qpid/java/management/client/src/example/GetQManResourceMembers.out.ko
@@ -0,0 +1,54 @@
+ GetQManResourceMembersExample Example
+-------------------------------------------------------------------
+
+This example shows the usage of WS-DM
+GetResourcePropertyRequest / Response on a
+Group service.
+The target resource is the WS-DM Adapter itself
+and the requested property is "ws-rp:Entry".
+WS-DM Adapter is a special WS-Resource (is a Group)
+that acts as the main entry point for retrieving
+all other managed resources.
+So clients that want to deal with QMan WS-Resources
+must first get resource identifiers sending
+a GetResourcePropertyRequest to WS-DM Adapter
+with "ws-rp:Entry" as target target property.
+
+-------------------------------------------------------------------
+
+[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://192.38.73.2:8080/qman/services/adapter</wsa:To>
+ <wsa:Action xmlns:wsa="http://www.w3.org/2005/08/addressing">http://docs.oasis-open.org/wsrf/rpw-2/GetResourceProperty/GetResourcePropertyRequest</wsa:Action>
+ <wsa:MessageID xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:796bab33-ed59-3432-4e2c-1fadde465a25</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>
+ <wsrf-rp:GetResourceProperty
+ xmlns:wsrf-rp="http://docs.oasis-open.org/wsrf/rp-2" xmlns:wsrf-sg="http://docs.oasis-open.org/wsrf/sg-2">wsrf-sg:Entry</wsrf-rp:GetResourceProperty>
+ </soap:Body>
+</soap:Envelope>
+
+-----------------------EXAMPLE FAILURE----------------------
+org.apache.muse.ws.addressing.soap.SoapFault: No route to host: connect
+ at org.apache.muse.core.AbstractResourceClient.invoke(AbstractResourceClient.java:298)
+ at org.apache.muse.core.AbstractResourceClient.invoke(AbstractResourceClient.java:254)
+ at org.apache.muse.ws.resource.remote.WsResourceClient.getResourceProperty(WsResourceClient.java:138)
+ at org.apache.muse.ws.resource.sg.remote.ServiceGroupClient.getMembers(ServiceGroupClient.java:110)
+ at org.apache.qpid.management.example.GetQManResourceMembersExample.execute(GetQManResourceMembersExample.java:61)
+ at org.apache.qpid.management.example.GetQManResourceMembersExample.main(GetQManResourceMembersExample.java:133)
+
+
+#########################################################################################
+
+WARNING! Unable to run this sample : port number must be a number.
+-------------------------------------------------------------
+Expected command line args for this sample are :
+
+1) host : ip or host name where QMan is running.
+2) port : port number where QMan is running.
+------------------------------------------------------------ \ No newline at end of file
diff --git a/qpid/java/management/client/src/example/GetQManResourceMembers.out.ok b/qpid/java/management/client/src/example/GetQManResourceMembers.out.ok
new file mode 100644
index 0000000000..dd75e1e490
--- /dev/null
+++ b/qpid/java/management/client/src/example/GetQManResourceMembers.out.ok
@@ -0,0 +1,55 @@
+ GetQManResourceMembersExample Example
+-------------------------------------------------------------------
+
+This example shows the usage of WS-DM
+GetResourcePropertyRequest / Response on a
+Group service.
+The target resource is the WS-DM Adapter itself
+and the requested property is "ws-rp:Entry".
+WS-DM Adapter is a special WS-Resource (is a Group)
+that acts as the main entry point for retrieving
+all other managed resources.
+So clients that want to deal with QMan WS-Resources
+must first get resource identifiers sending
+a GetResourcePropertyRequest to WS-DM Adapter
+with "ws-rp:Entry" as target target property.
+
+-------------------------------------------------------------------
+
+[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/wsrf/rpw-2/GetResourceProperty/GetResourcePropertyRequest</wsa:Action>
+ <wsa:MessageID xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:024c678b-1fab-cb6a-0992-30027817fb92</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>
+ <wsrf-rp:GetResourceProperty
+ xmlns:wsrf-rp="http://docs.oasis-open.org/wsrf/rp-2" xmlns:wsrf-sg="http://docs.oasis-open.org/wsrf/sg-2">wsrf-sg:Entry</wsrf-rp:GetResourceProperty>
+ </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/wsrf/rpw-2/GetResourceProperty/GetResourcePropertyResponse</wsa:Action>
+ <wsa:MessageID xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:90b0e421-6467-a72e-a8f4-cdedb80460b6</wsa:MessageID>
+ <wsa:RelatesTo RelationshipType="wsa:Reply" xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:024c678b-1fab-cb6a-0992-30027817fb92</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>
+ <wsrf-rp:GetResourcePropertyResponse xmlns:wsrf-rp="http://docs.oasis-open.org/wsrf/rp-2"/>
+ </soap:Body>
+</soap:Envelope>
+
+--------------------------------------------------------------------------
+QMan has at the moment 0 registered resources.
+-------------------------------------------------------------------------- \ No newline at end of file
diff --git a/qpid/java/management/client/src/example/GetResourceMetadataDescriptor.out.ok b/qpid/java/management/client/src/example/GetResourceMetadataDescriptor.out.ok
new file mode 100644
index 0000000000..a259259228
--- /dev/null
+++ b/qpid/java/management/client/src/example/GetResourceMetadataDescriptor.out.ok
@@ -0,0 +1,188 @@
+ GetResourceMetadataDescriptorExample
+-------------------------------------------------------------------
+
+The example shows how to get metadata from a
+WS-Resource.
+A QMan WS-Resource has different kinds of metadata.
+(see below)
+User who wants to receive metadata of a WS-Resource
+must send a GetMetadataRequesta specifying the
+associated dialect.
+Supported metadata that could be requested are :
+
+- WSDL : in this case dialect is "http://schemas.xmlsoap.org/wsdl/";
+- RDM (Resource Metadata Descriptor) : in this case dialect is "http://docs.oasis-open.org/wsrf/rmd-1 ".
+
+Note that this examples focuses on RDM Metadata only;
+another one is dedicated to WSDL.
+-------------------------------------------------------------------
+
+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://localhost:8080/qman/services/adapter</wsa:To>
+ <wsa:Action xmlns:wsa="http://www.w3.org/2005/08/addressing">http://docs.oasis-open.org/wsrf/rpw-2/GetResourceProperty/GetResourcePropertyRequest</wsa:Action>
+ <wsa:MessageID xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:cdcf747a-e5fc-3762-1748-87cc2eefb18b</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>
+ <wsrf-rp:GetResourceProperty
+ xmlns:wsrf-rp="http://docs.oasis-open.org/wsrf/rp-2" xmlns:wsrf-sg="http://docs.oasis-open.org/wsrf/sg-2">wsrf-sg:Entry</wsrf-rp:GetResourceProperty>
+ </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/wsrf/rpw-2/GetResourceProperty/GetResourcePropertyResponse</wsa:Action>
+ <wsa:MessageID xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:1d0d091b-8867-d765-7cc8-4898851cd783</wsa:MessageID>
+ <wsa:RelatesTo RelationshipType="wsa:Reply" xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:cdcf747a-e5fc-3762-1748-87cc2eefb18b</wsa:RelatesTo>
+ <wsa:From xmlns:wsa="http://www.w3.org/2005/08/addressing">
+ <wsa:Address>http://localhost:8080/qman/services/adapter</wsa:Address>
+ </wsa:From>
+ </soap:Header>
+ <soap:Body>
+ <wsrf-rp:GetResourcePropertyResponse xmlns:wsrf-rp="http://docs.oasis-open.org/wsrf/rp-2">
+ <wsrf-sg:Entry xmlns:wsrf-sg="http://docs.oasis-open.org/wsrf/sg-2">
+ <wsrf-sg:ServiceGroupEntryEPR>
+ <wsa:Address xmlns:wsa="http://www.w3.org/2005/08/addressing">http://localhost:8080/qman/services/ServiceGroupEntry</wsa:Address>
+ <wsa:ReferenceParameters xmlns:wsa="http://www.w3.org/2005/08/addressing">
+ <muse-wsa:ResourceId xmlns:muse-wsa="http://ws.apache.org/muse/addressing">uuid:3a2ee31e-49ed-e30a-c985-0fe49c182a75</muse-wsa:ResourceId>
+ </wsa:ReferenceParameters>
+ </wsrf-sg:ServiceGroupEntryEPR>
+ <wsrf-sg:MemberServiceEPR>
+ <wsa:Address xmlns:wsa="http://www.w3.org/2005/08/addressing">http://localhost:8080/qman/services/QManWsResource</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">Q-MAN: brokerID=cbe0cada-e8ee-424c-945b-f6c42df7b011,class=queue,name=1232952196269,objectId=e2857418-b873-47b7-ab30-441ae9376529,package=org.apache.qpid</qman-wsa:ResourceId>
+ </wsa:ReferenceParameters>
+ </wsrf-sg:MemberServiceEPR>
+ <wsrf-sg:Content/>
+ </wsrf-sg:Entry>
+ </wsrf-rp:GetResourcePropertyResponse>
+ </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://localhost:8080/qman/services/QManWsResource</wsa:To>
+ <wsa:Action xmlns:wsa="http://www.w3.org/2005/08/addressing">http://schemas.xmlsoap.org/ws/2004/09/mex/GetMetadata</wsa:Action>
+ <wsa:MessageID xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:ba2435fc-9172-69d8-f4be-34f7f45b26ff</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">Q-MAN: brokerID=cbe0cada-e8ee-424c-945b-f6c42df7b011,class=queue,name=1232952196269,objectId=e2857418-b873-47b7-ab30-441ae9376529,package=org.apache.qpid</qman-wsa:ResourceId>
+ </soap:Header>
+ <soap:Body>
+ <qman:GetMetadata xmlns:qman="http://schemas.xmlsoap.org/ws/2004/09/mex">
+ <qman:Dialect>http://docs.oasis-open.org/wsrf/rmd-1</qman:Dialect>
+ </qman:GetMetadata>
+ </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://schemas.xmlsoap.org/ws/2004/09/mex/GetMetadataResponse</wsa:Action>
+ <wsa:MessageID xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:ceb6eb90-4910-01a9-c138-6029e6bb0836</wsa:MessageID>
+ <wsa:RelatesTo RelationshipType="wsa:Reply" xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:ba2435fc-9172-69d8-f4be-34f7f45b26ff</wsa:RelatesTo>
+ <wsa:From xmlns:wsa="http://www.w3.org/2005/08/addressing">
+ <wsa:Address>http://localhost:8080/qman/services/QManWsResource</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">Q-MAN: brokerID=cbe0cada-e8ee-424c-945b-f6c42df7b011,class=queue,name=1232952196269,objectId=e2857418-b873-47b7-ab30-441ae9376529,package=org.apache.qpid</qman-wsa:ResourceId>
+ </wsa:ReferenceParameters>
+ </wsa:From>
+ </soap:Header>
+ <soap:Body>
+ <wsx:Metadata xmlns:wsx="http://schemas.xmlsoap.org/ws/2004/09/mex">
+ <wsx:MetadataSection>
+ <wsrmd:MetadataDescriptor
+ interface="qman:QManWsResourcePortType"
+ name="QManWsResourceMetadata"
+ wsdlLocation="http://docs.oasis-open.org/wsrf/rmd-1 QManWsResource.wsdl"
+ xmlns:qman="http://amqp.apache.org/qpid/management/qman" xmlns:wsrmd="http://docs.oasis-open.org/wsrf/rmd-1">
+ <wsrmd:Property modifiability="read-write"
+ mutability="mutable" name="qman:MgmtPubInterval" xmlns:qman="http://amqp.apache.org/qpid/management/qman">
+ <wsrmd:ValidValues/>
+ <wsrmd:StaticValues/>
+ <wsrmd:InitialValues/>
+ </wsrmd:Property>
+ <wsrmd:Property modifiability="read-only"
+ mutability="mutable" name="qman:Name" xmlns:qman="http://amqp.apache.org/qpid/management/qman">
+ <wsrmd:ValidValues/>
+ <wsrmd:StaticValues/>
+ <wsrmd:InitialValues/>
+ </wsrmd:Property>
+ <wsrmd:Property modifiability="read-only"
+ mutability="mutable" name="wsrl:TerminationTime" xmlns:wsrl="http://docs.oasis-open.org/wsrf/rl-2">
+ <wsrmd:ValidValues/>
+ <wsrmd:StaticValues/>
+ <wsrmd:InitialValues/>
+ </wsrmd:Property>
+ <wsrmd:Property modifiability="read-only"
+ mutability="mutable"
+ name="qman:MsgTotalEnqueues" xmlns:qman="http://amqp.apache.org/qpid/management/qman">
+ <wsrmd:ValidValues/>
+ <wsrmd:StaticValues/>
+ <wsrmd:InitialValues/>
+ </wsrmd:Property>
+ <wsrmd:Property modifiability="read-only"
+ mutability="mutable" name="qman:Arguments" xmlns:qman="http://amqp.apache.org/qpid/management/qman">
+ <wsrmd:ValidValues/>
+ <wsrmd:StaticValues/>
+ <wsrmd:InitialValues/>
+ </wsrmd:Property>
+ <wsrmd:Property modifiability="read-only"
+ mutability="mutable" name="qman:VhostRef" xmlns:qman="http://amqp.apache.org/qpid/management/qman">
+ <wsrmd:ValidValues/>
+ <wsrmd:StaticValues/>
+ <wsrmd:InitialValues/>
+ </wsrmd:Property>
+ <wsrmd:Property modifiability="read-only"
+ mutability="mutable" name="wsrl:CurrentTime" xmlns:wsrl="http://docs.oasis-open.org/wsrf/rl-2">
+ <wsrmd:ValidValues/>
+ <wsrmd:StaticValues/>
+ <wsrmd:InitialValues/>
+ </wsrmd:Property>
+ <wsrmd:Property modifiability="read-write"
+ mutability="mutable" name="qman:ExpireTime" xmlns:qman="http://amqp.apache.org/qpid/management/qman">
+ <wsrmd:ValidValues/>
+ <wsrmd:StaticValues/>
+ <wsrmd:InitialValues/>
+ </wsrmd:Property>
+ <wsrmd:Property modifiability="read-only"
+ mutability="mutable" name="qman:Durable" xmlns:qman="http://amqp.apache.org/qpid/management/qman">
+ <wsrmd:ValidValues/>
+ <wsrmd:StaticValues/>
+ <wsrmd:InitialValues/>
+ </wsrmd:Property>
+ <wsrmd:Property modifiability="read-only"
+ mutability="mutable" name="qman:ConsumerCount" xmlns:qman="http://amqp.apache.org/qpid/management/qman">
+ <wsrmd:ValidValues/>
+ <wsrmd:StaticValues/>
+ <wsrmd:InitialValues/>
+ </wsrmd:Property>
+ <wsrmd:Property modifiability="read-write"
+ mutability="mutable" name="qman:Type" xmlns:qman="http://amqp.apache.org/qpid/management/qman">
+ <wsrmd:ValidValues/>
+ <wsrmd:StaticValues/>
+ <wsrmd:InitialValues/>
+ </wsrmd:Property>
+ </wsrmd:MetadataDescriptor>
+ </wsx:MetadataSection>
+ </wsx:Metadata>
+ </soap:Body>
+</soap:Envelope> \ No newline at end of file
diff --git a/qpid/java/management/client/src/example/GetResourcePropertyDocument.out.ok b/qpid/java/management/client/src/example/GetResourcePropertyDocument.out.ok
new file mode 100644
index 0000000000..9d6312f2f3
--- /dev/null
+++ b/qpid/java/management/client/src/example/GetResourcePropertyDocument.out.ok
@@ -0,0 +1,138 @@
+ GetResourcePropertyDocument
+-------------------------------------------------------------------
+
+This example shows how to get the whole property
+document from a WS-Resource.
+Resource property document represents a particular
+composed structural view of the resource properties
+of the WS-Resource.
+First of all a request is send to WS-DM in order to get
+all registered WS-Resources.
+the target WS-Resource.
+If the returned list is not empty then a
+GetResourcePropertyDocumentRequest is sent to the first child.
+
+-------------------------------------------------------------------
+
+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://localhost:8080/qman/services/adapter</wsa:To>
+ <wsa:Action xmlns:wsa="http://www.w3.org/2005/08/addressing">http://docs.oasis-open.org/wsrf/rpw-2/GetResourceProperty/GetResourcePropertyRequest</wsa:Action>
+ <wsa:MessageID xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:50aa09f5-44e7-8bd3-7f24-49b8f0b9bf0d</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>
+ <wsrf-rp:GetResourceProperty
+ xmlns:wsrf-rp="http://docs.oasis-open.org/wsrf/rp-2" xmlns:wsrf-sg="http://docs.oasis-open.org/wsrf/sg-2">wsrf-sg:Entry</wsrf-rp:GetResourceProperty>
+ </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/wsrf/rpw-2/GetResourceProperty/GetResourcePropertyResponse</wsa:Action>
+ <wsa:MessageID xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:f71342ad-2185-fdb3-393a-e9a98305effd</wsa:MessageID>
+ <wsa:RelatesTo RelationshipType="wsa:Reply" xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:50aa09f5-44e7-8bd3-7f24-49b8f0b9bf0d</wsa:RelatesTo>
+ <wsa:From xmlns:wsa="http://www.w3.org/2005/08/addressing">
+ <wsa:Address>http://localhost:8080/qman/services/adapter</wsa:Address>
+ </wsa:From>
+ </soap:Header>
+ <soap:Body>
+ <wsrf-rp:GetResourcePropertyResponse xmlns:wsrf-rp="http://docs.oasis-open.org/wsrf/rp-2">
+ <wsrf-sg:Entry xmlns:wsrf-sg="http://docs.oasis-open.org/wsrf/sg-2">
+ <wsrf-sg:ServiceGroupEntryEPR>
+ <wsa:Address xmlns:wsa="http://www.w3.org/2005/08/addressing">http://localhost:8080/qman/services/ServiceGroupEntry</wsa:Address>
+ <wsa:ReferenceParameters xmlns:wsa="http://www.w3.org/2005/08/addressing">
+ <muse-wsa:ResourceId xmlns:muse-wsa="http://ws.apache.org/muse/addressing">uuid:b220e2bd-0370-da4e-fc71-5e283954d319</muse-wsa:ResourceId>
+ </wsa:ReferenceParameters>
+ </wsrf-sg:ServiceGroupEntryEPR>
+ <wsrf-sg:MemberServiceEPR>
+ <wsa:Address xmlns:wsa="http://www.w3.org/2005/08/addressing">http://localhost:8080/qman/services/QManWsResource</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">Q-MAN: brokerID=8e069b14-40ba-4d48-a2cb-b9f2bef2d404,class=queue,name=1232953394537,objectId=781f4ad7-4c96-4caa-b69d-291461cdb1fc,package=org.apache.qpid</qman-wsa:ResourceId>
+ </wsa:ReferenceParameters>
+ </wsrf-sg:MemberServiceEPR>
+ <wsrf-sg:Content/>
+ </wsrf-sg:Entry>
+ </wsrf-rp:GetResourcePropertyResponse>
+ </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://localhost:8080/qman/services/QManWsResource</wsa:To>
+ <wsa:Action xmlns:wsa="http://www.w3.org/2005/08/addressing">http://docs.oasis-open.org/wsrf/rpw-2/GetResourcePropertyDocument/GetResourcePropertyDocumentRequest</wsa:Action>
+ <wsa:MessageID xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:e035946b-c3f5-1b24-e94a-61c674ce07b9</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">Q-MAN: brokerID=8e069b14-40ba-4d48-a2cb-b9f2bef2d404,class=queue,name=1232953394537,objectId=781f4ad7-4c96-4caa-b69d-291461cdb1fc,package=org.apache.qpid</qman-wsa:ResourceId>
+ </soap:Header>
+ <soap:Body>
+ <wsrf-rp:GetResourcePropertyDocument xmlns:wsrf-rp="http://docs.oasis-open.org/wsrf/rp-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/wsrf/rpw-2/GetResourcePropertyDocument/GetResourcePropertyDocumentResponse</wsa:Action>
+ <wsa:MessageID xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:dafe12e4-c0a9-f872-cf1e-2a41bc291b2e</wsa:MessageID>
+ <wsa:RelatesTo RelationshipType="wsa:Reply" xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:e035946b-c3f5-1b24-e94a-61c674ce07b9</wsa:RelatesTo>
+ <wsa:From xmlns:wsa="http://www.w3.org/2005/08/addressing">
+ <wsa:Address>http://localhost:8080/qman/services/QManWsResource</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">Q-MAN: brokerID=8e069b14-40ba-4d48-a2cb-b9f2bef2d404,class=queue,name=1232953394537,objectId=781f4ad7-4c96-4caa-b69d-291461cdb1fc,package=org.apache.qpid</qman-wsa:ResourceId>
+ </wsa:ReferenceParameters>
+ </wsa:From>
+ </soap:Header>
+ <soap:Body>
+ <wsrf-rp:GetResourcePropertyDocumentResponse xmlns:wsrf-rp="http://docs.oasis-open.org/wsrf/rp-2">
+ <qman:QManWsResourceProperties xmlns:qman="http://amqp.apache.org/qpid/management/qman">
+ <qman:MgmtPubInterval>32767</qman:MgmtPubInterval>
+ <wsrf-rp:QueryExpressionDialect>http://www.w3.org/TR/1999/REC-xpath-19991116</wsrf-rp:QueryExpressionDialect>
+ <qman:Name>Initial Name</qman:Name>
+ <wsrf-rl:TerminationTime xmlns:wsrf-rl="http://docs.oasis-open.org/wsrf/rl-2"/>
+ <qman:MsgTotalEnqueues>9223372036854775797</qman:MsgTotalEnqueues>
+ <qman:Arguments xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <qman:entry>
+ <qman:key>Key3</qman:key>
+ <qman:value xsi:type="xsd:integer">2147483647</qman:value>
+ </qman:entry>
+ <qman:entry>
+ <qman:key>Key4</qman:key>
+ <qman:value xsi:type="xsd:float">3.4028235E38</qman:value>
+ </qman:entry>
+ <qman:entry>
+ <qman:key>Key1</qman:key>
+ <qman:value xsi:type="xsd:string">aStringValue</qman:value>
+ </qman:entry>
+ <qman:entry>
+ <qman:key>Key2</qman:key>
+ <qman:value xsi:type="xsd:long">-9223372036854775808</qman:value>
+ </qman:entry>
+ </qman:Arguments>
+ <qman:VhostRef>2deef1b3-d2c6-49f3-a8de-51f6a75a1a6b</qman:VhostRef>
+ <wsrf-rl:CurrentTime xmlns:wsrf-rl="http://docs.oasis-open.org/wsrf/rl-2">1232956293823</wsrf-rl:CurrentTime>
+ <qman:ExpireTime>9223372036854775807</qman:ExpireTime>
+ <qman:Durable>true</qman:Durable>
+ <qman:ConsumerCount>-2147483638</qman:ConsumerCount>
+ </qman:QManWsResourceProperties>
+ </wsrf-rp:GetResourcePropertyDocumentResponse>
+ </soap:Body>
+</soap:Envelope> \ No newline at end of file
diff --git a/qpid/java/management/client/src/example/GetResourcePropertyRequest.out.ok b/qpid/java/management/client/src/example/GetResourcePropertyRequest.out.ok
new file mode 100644
index 0000000000..4fa0ab3b8d
--- /dev/null
+++ b/qpid/java/management/client/src/example/GetResourcePropertyRequest.out.ok
@@ -0,0 +1,588 @@
+ GetResourcePropertyExample
+-------------------------------------------------------------------
+
+This example shows how to get the property value
+from a WS-Resource.
+First of all a request is send to WS-DM in order to get
+all registered WS-Resources.
+If the returned list is not empty then a GetMetadataRequest
+to the first child.
+The result metadata descriptor contains all properties of
+the target WS-Resource.
+For each of them a GetResourcePropertyRequest is sent
+ in order to get its value.
+
+-------------------------------------------------------------------
+
+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://localhost:8080/qman/services/adapter</wsa:To>
+ <wsa:Action xmlns:wsa="http://www.w3.org/2005/08/addressing">http://docs.oasis-open.org/wsrf/rpw-2/GetResourceProperty/GetResourcePropertyRequest</wsa:Action>
+ <wsa:MessageID xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:e581b9cb-04a9-a87f-7763-dcf227ed7f8b</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>
+ <wsrf-rp:GetResourceProperty
+ xmlns:wsrf-rp="http://docs.oasis-open.org/wsrf/rp-2" xmlns:wsrf-sg="http://docs.oasis-open.org/wsrf/sg-2">wsrf-sg:Entry</wsrf-rp:GetResourceProperty>
+ </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/wsrf/rpw-2/GetResourceProperty/GetResourcePropertyResponse</wsa:Action>
+ <wsa:MessageID xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:27bab9a7-89aa-16a1-966b-c0aa19d3b352</wsa:MessageID>
+ <wsa:RelatesTo RelationshipType="wsa:Reply" xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:e581b9cb-04a9-a87f-7763-dcf227ed7f8b</wsa:RelatesTo>
+ <wsa:From xmlns:wsa="http://www.w3.org/2005/08/addressing">
+ <wsa:Address>http://localhost:8080/qman/services/adapter</wsa:Address>
+ </wsa:From>
+ </soap:Header>
+ <soap:Body>
+ <wsrf-rp:GetResourcePropertyResponse xmlns:wsrf-rp="http://docs.oasis-open.org/wsrf/rp-2">
+ <wsrf-sg:Entry xmlns:wsrf-sg="http://docs.oasis-open.org/wsrf/sg-2">
+ <wsrf-sg:ServiceGroupEntryEPR>
+ <wsa:Address xmlns:wsa="http://www.w3.org/2005/08/addressing">http://localhost:8080/qman/services/ServiceGroupEntry</wsa:Address>
+ <wsa:ReferenceParameters xmlns:wsa="http://www.w3.org/2005/08/addressing">
+ <muse-wsa:ResourceId xmlns:muse-wsa="http://ws.apache.org/muse/addressing">uuid:b220e2bd-0370-da4e-fc71-5e283954d319</muse-wsa:ResourceId>
+ </wsa:ReferenceParameters>
+ </wsrf-sg:ServiceGroupEntryEPR>
+ <wsrf-sg:MemberServiceEPR>
+ <wsa:Address xmlns:wsa="http://www.w3.org/2005/08/addressing">http://localhost:8080/qman/services/QManWsResource</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">Q-MAN: brokerID=8e069b14-40ba-4d48-a2cb-b9f2bef2d404,class=queue,name=1232953394537,objectId=781f4ad7-4c96-4caa-b69d-291461cdb1fc,package=org.apache.qpid</qman-wsa:ResourceId>
+ </wsa:ReferenceParameters>
+ </wsrf-sg:MemberServiceEPR>
+ <wsrf-sg:Content/>
+ </wsrf-sg:Entry>
+ </wsrf-rp:GetResourcePropertyResponse>
+ </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://localhost:8080/qman/services/QManWsResource</wsa:To>
+ <wsa:Action xmlns:wsa="http://www.w3.org/2005/08/addressing">http://schemas.xmlsoap.org/ws/2004/09/mex/GetMetadata</wsa:Action>
+ <wsa:MessageID xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:c5efae22-bc2f-ccdd-477c-621d4e49cd77</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">Q-MAN: brokerID=8e069b14-40ba-4d48-a2cb-b9f2bef2d404,class=queue,name=1232953394537,objectId=781f4ad7-4c96-4caa-b69d-291461cdb1fc,package=org.apache.qpid</qman-wsa:ResourceId>
+ </soap:Header>
+ <soap:Body>
+ <qman:GetMetadata xmlns:qman="http://schemas.xmlsoap.org/ws/2004/09/mex">
+ <qman:Dialect>http://docs.oasis-open.org/wsrf/rmd-1</qman:Dialect>
+ </qman:GetMetadata>
+ </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://schemas.xmlsoap.org/ws/2004/09/mex/GetMetadataResponse</wsa:Action>
+ <wsa:MessageID xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:4d933676-fb60-3fae-d7b9-39324a8661fc</wsa:MessageID>
+ <wsa:RelatesTo RelationshipType="wsa:Reply" xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:c5efae22-bc2f-ccdd-477c-621d4e49cd77</wsa:RelatesTo>
+ <wsa:From xmlns:wsa="http://www.w3.org/2005/08/addressing">
+ <wsa:Address>http://localhost:8080/qman/services/QManWsResource</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">Q-MAN: brokerID=8e069b14-40ba-4d48-a2cb-b9f2bef2d404,class=queue,name=1232953394537,objectId=781f4ad7-4c96-4caa-b69d-291461cdb1fc,package=org.apache.qpid</qman-wsa:ResourceId>
+ </wsa:ReferenceParameters>
+ </wsa:From>
+ </soap:Header>
+ <soap:Body>
+ <wsx:Metadata xmlns:wsx="http://schemas.xmlsoap.org/ws/2004/09/mex">
+ <wsx:MetadataSection>
+ <wsrmd:MetadataDescriptor
+ interface="qman:QManWsResourcePortType"
+ name="QManWsResourceMetadata"
+ wsdlLocation="http://docs.oasis-open.org/wsrf/rmd-1 QManWsResource.wsdl"
+ xmlns:qman="http://amqp.apache.org/qpid/management/qman" xmlns:wsrmd="http://docs.oasis-open.org/wsrf/rmd-1">
+ <wsrmd:Property modifiability="read-write"
+ mutability="mutable" name="qman:MgmtPubInterval" xmlns:qman="http://amqp.apache.org/qpid/management/qman">
+ <wsrmd:ValidValues/>
+ <wsrmd:StaticValues/>
+ <wsrmd:InitialValues/>
+ </wsrmd:Property>
+ <wsrmd:Property modifiability="read-only"
+ mutability="mutable" name="qman:Name" xmlns:qman="http://amqp.apache.org/qpid/management/qman">
+ <wsrmd:ValidValues/>
+ <wsrmd:StaticValues/>
+ <wsrmd:InitialValues/>
+ </wsrmd:Property>
+ <wsrmd:Property modifiability="read-only"
+ mutability="mutable" name="wsrl:TerminationTime" xmlns:wsrl="http://docs.oasis-open.org/wsrf/rl-2">
+ <wsrmd:ValidValues/>
+ <wsrmd:StaticValues/>
+ <wsrmd:InitialValues/>
+ </wsrmd:Property>
+ <wsrmd:Property modifiability="read-only"
+ mutability="mutable"
+ name="qman:MsgTotalEnqueues" xmlns:qman="http://amqp.apache.org/qpid/management/qman">
+ <wsrmd:ValidValues/>
+ <wsrmd:StaticValues/>
+ <wsrmd:InitialValues/>
+ </wsrmd:Property>
+ <wsrmd:Property modifiability="read-only"
+ mutability="mutable" name="qman:Arguments" xmlns:qman="http://amqp.apache.org/qpid/management/qman">
+ <wsrmd:ValidValues/>
+ <wsrmd:StaticValues/>
+ <wsrmd:InitialValues/>
+ </wsrmd:Property>
+ <wsrmd:Property modifiability="read-only"
+ mutability="mutable" name="qman:VhostRef" xmlns:qman="http://amqp.apache.org/qpid/management/qman">
+ <wsrmd:ValidValues/>
+ <wsrmd:StaticValues/>
+ <wsrmd:InitialValues/>
+ </wsrmd:Property>
+ <wsrmd:Property modifiability="read-only"
+ mutability="mutable" name="wsrl:CurrentTime" xmlns:wsrl="http://docs.oasis-open.org/wsrf/rl-2">
+ <wsrmd:ValidValues/>
+ <wsrmd:StaticValues/>
+ <wsrmd:InitialValues/>
+ </wsrmd:Property>
+ <wsrmd:Property modifiability="read-write"
+ mutability="mutable" name="qman:ExpireTime" xmlns:qman="http://amqp.apache.org/qpid/management/qman">
+ <wsrmd:ValidValues/>
+ <wsrmd:StaticValues/>
+ <wsrmd:InitialValues/>
+ </wsrmd:Property>
+ <wsrmd:Property modifiability="read-only"
+ mutability="mutable" name="qman:Durable" xmlns:qman="http://amqp.apache.org/qpid/management/qman">
+ <wsrmd:ValidValues/>
+ <wsrmd:StaticValues/>
+ <wsrmd:InitialValues/>
+ </wsrmd:Property>
+ <wsrmd:Property modifiability="read-only"
+ mutability="mutable" name="qman:ConsumerCount" xmlns:qman="http://amqp.apache.org/qpid/management/qman">
+ <wsrmd:ValidValues/>
+ <wsrmd:StaticValues/>
+ <wsrmd:InitialValues/>
+ </wsrmd:Property>
+ <wsrmd:Property modifiability="read-write"
+ mutability="mutable" name="qman:Type" xmlns:qman="http://amqp.apache.org/qpid/management/qman">
+ <wsrmd:ValidValues/>
+ <wsrmd:StaticValues/>
+ <wsrmd:InitialValues/>
+ </wsrmd:Property>
+ </wsrmd:MetadataDescriptor>
+ </wsx:MetadataSection>
+ </wsx:Metadata>
+ </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://localhost:8080/qman/services/QManWsResource</wsa:To>
+ <wsa:Action xmlns:wsa="http://www.w3.org/2005/08/addressing">http://docs.oasis-open.org/wsrf/rpw-2/GetResourceProperty/GetResourcePropertyRequest</wsa:Action>
+ <wsa:MessageID xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:83c13239-3e37-853d-776d-3dac2729117b</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">Q-MAN: brokerID=8e069b14-40ba-4d48-a2cb-b9f2bef2d404,class=queue,name=1232953394537,objectId=781f4ad7-4c96-4caa-b69d-291461cdb1fc,package=org.apache.qpid</qman-wsa:ResourceId>
+ </soap:Header>
+ <soap:Body>
+ <wsrf-rp:GetResourceProperty
+ xmlns:wsrf-rp="http://docs.oasis-open.org/wsrf/rp-2" xmlns:qman="http://amqp.apache.org/qpid/management/qman">qman:MgmtPubInterval</wsrf-rp:GetResourceProperty>
+ </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/wsrf/rpw-2/GetResourceProperty/GetResourcePropertyResponse</wsa:Action>
+ <wsa:MessageID xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:0beb3927-6420-9877-f163-4288ea1560da</wsa:MessageID>
+ <wsa:RelatesTo RelationshipType="wsa:Reply" xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:83c13239-3e37-853d-776d-3dac2729117b</wsa:RelatesTo>
+ <wsa:From xmlns:wsa="http://www.w3.org/2005/08/addressing">
+ <wsa:Address>http://localhost:8080/qman/services/QManWsResource</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">Q-MAN: brokerID=8e069b14-40ba-4d48-a2cb-b9f2bef2d404,class=queue,name=1232953394537,objectId=781f4ad7-4c96-4caa-b69d-291461cdb1fc,package=org.apache.qpid</qman-wsa:ResourceId>
+ </wsa:ReferenceParameters>
+ </wsa:From>
+ </soap:Header>
+ <soap:Body>
+ <wsrf-rp:GetResourcePropertyResponse xmlns:wsrf-rp="http://docs.oasis-open.org/wsrf/rp-2">
+ <qman:MgmtPubInterval xmlns:qman="http://amqp.apache.org/qpid/management/qman">32767</qman:MgmtPubInterval>
+ </wsrf-rp:GetResourcePropertyResponse>
+ </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://localhost:8080/qman/services/QManWsResource</wsa:To>
+ <wsa:Action xmlns:wsa="http://www.w3.org/2005/08/addressing">http://docs.oasis-open.org/wsrf/rpw-2/GetResourceProperty/GetResourcePropertyRequest</wsa:Action>
+ <wsa:MessageID xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:30b678da-f1fa-8120-7660-9eb86ebb76b7</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">Q-MAN: brokerID=8e069b14-40ba-4d48-a2cb-b9f2bef2d404,class=queue,name=1232953394537,objectId=781f4ad7-4c96-4caa-b69d-291461cdb1fc,package=org.apache.qpid</qman-wsa:ResourceId>
+ </soap:Header>
+ <soap:Body>
+ <wsrf-rp:GetResourceProperty
+ xmlns:wsrf-rp="http://docs.oasis-open.org/wsrf/rp-2" xmlns:qman="http://amqp.apache.org/qpid/management/qman">qman:Name</wsrf-rp:GetResourceProperty>
+ </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/wsrf/rpw-2/GetResourceProperty/GetResourcePropertyResponse</wsa:Action>
+ <wsa:MessageID xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:8343b104-1a82-212a-c84a-460cbc223327</wsa:MessageID>
+ <wsa:RelatesTo RelationshipType="wsa:Reply" xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:30b678da-f1fa-8120-7660-9eb86ebb76b7</wsa:RelatesTo>
+ <wsa:From xmlns:wsa="http://www.w3.org/2005/08/addressing">
+ <wsa:Address>http://localhost:8080/qman/services/QManWsResource</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">Q-MAN: brokerID=8e069b14-40ba-4d48-a2cb-b9f2bef2d404,class=queue,name=1232953394537,objectId=781f4ad7-4c96-4caa-b69d-291461cdb1fc,package=org.apache.qpid</qman-wsa:ResourceId>
+ </wsa:ReferenceParameters>
+ </wsa:From>
+ </soap:Header>
+ <soap:Body>
+ <wsrf-rp:GetResourcePropertyResponse xmlns:wsrf-rp="http://docs.oasis-open.org/wsrf/rp-2">
+ <qman:Name xmlns:qman="http://amqp.apache.org/qpid/management/qman">Initial Name</qman:Name>
+ </wsrf-rp:GetResourcePropertyResponse>
+ </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://localhost:8080/qman/services/QManWsResource</wsa:To>
+ <wsa:Action xmlns:wsa="http://www.w3.org/2005/08/addressing">http://docs.oasis-open.org/wsrf/rpw-2/GetResourceProperty/GetResourcePropertyRequest</wsa:Action>
+ <wsa:MessageID xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:795eaebd-dd48-75b0-18b3-a7e3c1fd4d5a</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">Q-MAN: brokerID=8e069b14-40ba-4d48-a2cb-b9f2bef2d404,class=queue,name=1232953394537,objectId=781f4ad7-4c96-4caa-b69d-291461cdb1fc,package=org.apache.qpid</qman-wsa:ResourceId>
+ </soap:Header>
+ <soap:Body>
+ <wsrf-rp:GetResourceProperty
+ xmlns:wsrf-rp="http://docs.oasis-open.org/wsrf/rp-2" xmlns:qman="http://amqp.apache.org/qpid/management/qman">qman:MsgTotalEnqueues</wsrf-rp:GetResourceProperty>
+ </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/wsrf/rpw-2/GetResourceProperty/GetResourcePropertyResponse</wsa:Action>
+ <wsa:MessageID xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:b6b91fd1-762b-3ae4-76c3-fe206c93b76d</wsa:MessageID>
+ <wsa:RelatesTo RelationshipType="wsa:Reply" xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:795eaebd-dd48-75b0-18b3-a7e3c1fd4d5a</wsa:RelatesTo>
+ <wsa:From xmlns:wsa="http://www.w3.org/2005/08/addressing">
+ <wsa:Address>http://localhost:8080/qman/services/QManWsResource</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">Q-MAN: brokerID=8e069b14-40ba-4d48-a2cb-b9f2bef2d404,class=queue,name=1232953394537,objectId=781f4ad7-4c96-4caa-b69d-291461cdb1fc,package=org.apache.qpid</qman-wsa:ResourceId>
+ </wsa:ReferenceParameters>
+ </wsa:From>
+ </soap:Header>
+ <soap:Body>
+ <wsrf-rp:GetResourcePropertyResponse xmlns:wsrf-rp="http://docs.oasis-open.org/wsrf/rp-2">
+ <qman:MsgTotalEnqueues xmlns:qman="http://amqp.apache.org/qpid/management/qman">9223372036854775797</qman:MsgTotalEnqueues>
+ </wsrf-rp:GetResourcePropertyResponse>
+ </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://localhost:8080/qman/services/QManWsResource</wsa:To>
+ <wsa:Action xmlns:wsa="http://www.w3.org/2005/08/addressing">http://docs.oasis-open.org/wsrf/rpw-2/GetResourceProperty/GetResourcePropertyRequest</wsa:Action>
+ <wsa:MessageID xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:f57f0179-a31b-8607-668b-c2602838c363</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">Q-MAN: brokerID=8e069b14-40ba-4d48-a2cb-b9f2bef2d404,class=queue,name=1232953394537,objectId=781f4ad7-4c96-4caa-b69d-291461cdb1fc,package=org.apache.qpid</qman-wsa:ResourceId>
+ </soap:Header>
+ <soap:Body>
+ <wsrf-rp:GetResourceProperty
+ xmlns:wsrf-rp="http://docs.oasis-open.org/wsrf/rp-2" xmlns:qman="http://amqp.apache.org/qpid/management/qman">qman:Arguments</wsrf-rp:GetResourceProperty>
+ </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/wsrf/rpw-2/GetResourceProperty/GetResourcePropertyResponse</wsa:Action>
+ <wsa:MessageID xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:fc07cbe4-a19a-6374-c985-49fa525d3e90</wsa:MessageID>
+ <wsa:RelatesTo RelationshipType="wsa:Reply" xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:f57f0179-a31b-8607-668b-c2602838c363</wsa:RelatesTo>
+ <wsa:From xmlns:wsa="http://www.w3.org/2005/08/addressing">
+ <wsa:Address>http://localhost:8080/qman/services/QManWsResource</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">Q-MAN: brokerID=8e069b14-40ba-4d48-a2cb-b9f2bef2d404,class=queue,name=1232953394537,objectId=781f4ad7-4c96-4caa-b69d-291461cdb1fc,package=org.apache.qpid</qman-wsa:ResourceId>
+ </wsa:ReferenceParameters>
+ </wsa:From>
+ </soap:Header>
+ <soap:Body>
+ <wsrf-rp:GetResourcePropertyResponse xmlns:wsrf-rp="http://docs.oasis-open.org/wsrf/rp-2">
+ <qman:Arguments
+ xmlns:qman="http://amqp.apache.org/qpid/management/qman" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <qman:entry>
+ <qman:key>Key3</qman:key>
+ <qman:value xsi:type="xsd:integer">2147483647</qman:value>
+ </qman:entry>
+ <qman:entry>
+ <qman:key>Key4</qman:key>
+ <qman:value xsi:type="xsd:float">3.4028235E38</qman:value>
+ </qman:entry>
+ <qman:entry>
+ <qman:key>Key1</qman:key>
+ <qman:value xsi:type="xsd:string">aStringValue</qman:value>
+ </qman:entry>
+ <qman:entry>
+ <qman:key>Key2</qman:key>
+ <qman:value xsi:type="xsd:long">-9223372036854775808</qman:value>
+ </qman:entry>
+ </qman:Arguments>
+ </wsrf-rp:GetResourcePropertyResponse>
+ </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://localhost:8080/qman/services/QManWsResource</wsa:To>
+ <wsa:Action xmlns:wsa="http://www.w3.org/2005/08/addressing">http://docs.oasis-open.org/wsrf/rpw-2/GetResourceProperty/GetResourcePropertyRequest</wsa:Action>
+ <wsa:MessageID xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:5d735040-95d1-7c87-7ac9-b4a5700e0ab9</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">Q-MAN: brokerID=8e069b14-40ba-4d48-a2cb-b9f2bef2d404,class=queue,name=1232953394537,objectId=781f4ad7-4c96-4caa-b69d-291461cdb1fc,package=org.apache.qpid</qman-wsa:ResourceId>
+ </soap:Header>
+ <soap:Body>
+ <wsrf-rp:GetResourceProperty
+ xmlns:wsrf-rp="http://docs.oasis-open.org/wsrf/rp-2" xmlns:qman="http://amqp.apache.org/qpid/management/qman">qman:VhostRef</wsrf-rp:GetResourceProperty>
+ </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/wsrf/rpw-2/GetResourceProperty/GetResourcePropertyResponse</wsa:Action>
+ <wsa:MessageID xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:cdfe639c-357b-d55b-fe7d-4a203d46465c</wsa:MessageID>
+ <wsa:RelatesTo RelationshipType="wsa:Reply" xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:5d735040-95d1-7c87-7ac9-b4a5700e0ab9</wsa:RelatesTo>
+ <wsa:From xmlns:wsa="http://www.w3.org/2005/08/addressing">
+ <wsa:Address>http://localhost:8080/qman/services/QManWsResource</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">Q-MAN: brokerID=8e069b14-40ba-4d48-a2cb-b9f2bef2d404,class=queue,name=1232953394537,objectId=781f4ad7-4c96-4caa-b69d-291461cdb1fc,package=org.apache.qpid</qman-wsa:ResourceId>
+ </wsa:ReferenceParameters>
+ </wsa:From>
+ </soap:Header>
+ <soap:Body>
+ <wsrf-rp:GetResourcePropertyResponse xmlns:wsrf-rp="http://docs.oasis-open.org/wsrf/rp-2">
+ <qman:VhostRef xmlns:qman="http://amqp.apache.org/qpid/management/qman">2deef1b3-d2c6-49f3-a8de-51f6a75a1a6b</qman:VhostRef>
+ </wsrf-rp:GetResourcePropertyResponse>
+ </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://localhost:8080/qman/services/QManWsResource</wsa:To>
+ <wsa:Action xmlns:wsa="http://www.w3.org/2005/08/addressing">http://docs.oasis-open.org/wsrf/rpw-2/GetResourceProperty/GetResourcePropertyRequest</wsa:Action>
+ <wsa:MessageID xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:e3fde856-57f5-a96f-a382-5e0f4206a6fe</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">Q-MAN: brokerID=8e069b14-40ba-4d48-a2cb-b9f2bef2d404,class=queue,name=1232953394537,objectId=781f4ad7-4c96-4caa-b69d-291461cdb1fc,package=org.apache.qpid</qman-wsa:ResourceId>
+ </soap:Header>
+ <soap:Body>
+ <wsrf-rp:GetResourceProperty
+ xmlns:wsrf-rp="http://docs.oasis-open.org/wsrf/rp-2" xmlns:qman="http://amqp.apache.org/qpid/management/qman">qman:ExpireTime</wsrf-rp:GetResourceProperty>
+ </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/wsrf/rpw-2/GetResourceProperty/GetResourcePropertyResponse</wsa:Action>
+ <wsa:MessageID xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:fa290c54-bac1-62d6-701e-3b8ec2eaf817</wsa:MessageID>
+ <wsa:RelatesTo RelationshipType="wsa:Reply" xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:e3fde856-57f5-a96f-a382-5e0f4206a6fe</wsa:RelatesTo>
+ <wsa:From xmlns:wsa="http://www.w3.org/2005/08/addressing">
+ <wsa:Address>http://localhost:8080/qman/services/QManWsResource</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">Q-MAN: brokerID=8e069b14-40ba-4d48-a2cb-b9f2bef2d404,class=queue,name=1232953394537,objectId=781f4ad7-4c96-4caa-b69d-291461cdb1fc,package=org.apache.qpid</qman-wsa:ResourceId>
+ </wsa:ReferenceParameters>
+ </wsa:From>
+ </soap:Header>
+ <soap:Body>
+ <wsrf-rp:GetResourcePropertyResponse xmlns:wsrf-rp="http://docs.oasis-open.org/wsrf/rp-2">
+ <qman:ExpireTime xmlns:qman="http://amqp.apache.org/qpid/management/qman">9223372036854775807</qman:ExpireTime>
+ </wsrf-rp:GetResourcePropertyResponse>
+ </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://localhost:8080/qman/services/QManWsResource</wsa:To>
+ <wsa:Action xmlns:wsa="http://www.w3.org/2005/08/addressing">http://docs.oasis-open.org/wsrf/rpw-2/GetResourceProperty/GetResourcePropertyRequest</wsa:Action>
+ <wsa:MessageID xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:092dd5d9-c443-428c-813c-13428058b08c</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">Q-MAN: brokerID=8e069b14-40ba-4d48-a2cb-b9f2bef2d404,class=queue,name=1232953394537,objectId=781f4ad7-4c96-4caa-b69d-291461cdb1fc,package=org.apache.qpid</qman-wsa:ResourceId>
+ </soap:Header>
+ <soap:Body>
+ <wsrf-rp:GetResourceProperty
+ xmlns:wsrf-rp="http://docs.oasis-open.org/wsrf/rp-2" xmlns:qman="http://amqp.apache.org/qpid/management/qman">qman:Durable</wsrf-rp:GetResourceProperty>
+ </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/wsrf/rpw-2/GetResourceProperty/GetResourcePropertyResponse</wsa:Action>
+ <wsa:MessageID xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:1053800e-345c-abed-e352-f524c1d24afa</wsa:MessageID>
+ <wsa:RelatesTo RelationshipType="wsa:Reply" xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:092dd5d9-c443-428c-813c-13428058b08c</wsa:RelatesTo>
+ <wsa:From xmlns:wsa="http://www.w3.org/2005/08/addressing">
+ <wsa:Address>http://localhost:8080/qman/services/QManWsResource</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">Q-MAN: brokerID=8e069b14-40ba-4d48-a2cb-b9f2bef2d404,class=queue,name=1232953394537,objectId=781f4ad7-4c96-4caa-b69d-291461cdb1fc,package=org.apache.qpid</qman-wsa:ResourceId>
+ </wsa:ReferenceParameters>
+ </wsa:From>
+ </soap:Header>
+ <soap:Body>
+ <wsrf-rp:GetResourcePropertyResponse xmlns:wsrf-rp="http://docs.oasis-open.org/wsrf/rp-2">
+ <qman:Durable xmlns:qman="http://amqp.apache.org/qpid/management/qman">true</qman:Durable>
+ </wsrf-rp:GetResourcePropertyResponse>
+ </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://localhost:8080/qman/services/QManWsResource</wsa:To>
+ <wsa:Action xmlns:wsa="http://www.w3.org/2005/08/addressing">http://docs.oasis-open.org/wsrf/rpw-2/GetResourceProperty/GetResourcePropertyRequest</wsa:Action>
+ <wsa:MessageID xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:bc291be9-b1d1-f668-f3c5-29647e78d6bf</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">Q-MAN: brokerID=8e069b14-40ba-4d48-a2cb-b9f2bef2d404,class=queue,name=1232953394537,objectId=781f4ad7-4c96-4caa-b69d-291461cdb1fc,package=org.apache.qpid</qman-wsa:ResourceId>
+ </soap:Header>
+ <soap:Body>
+ <wsrf-rp:GetResourceProperty
+ xmlns:wsrf-rp="http://docs.oasis-open.org/wsrf/rp-2" xmlns:qman="http://amqp.apache.org/qpid/management/qman">qman:ConsumerCount</wsrf-rp:GetResourceProperty>
+ </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/wsrf/rpw-2/GetResourceProperty/GetResourcePropertyResponse</wsa:Action>
+ <wsa:MessageID xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:7467dddf-033e-f540-241f-76ce81c0ebeb</wsa:MessageID>
+ <wsa:RelatesTo RelationshipType="wsa:Reply" xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:bc291be9-b1d1-f668-f3c5-29647e78d6bf</wsa:RelatesTo>
+ <wsa:From xmlns:wsa="http://www.w3.org/2005/08/addressing">
+ <wsa:Address>http://localhost:8080/qman/services/QManWsResource</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">Q-MAN: brokerID=8e069b14-40ba-4d48-a2cb-b9f2bef2d404,class=queue,name=1232953394537,objectId=781f4ad7-4c96-4caa-b69d-291461cdb1fc,package=org.apache.qpid</qman-wsa:ResourceId>
+ </wsa:ReferenceParameters>
+ </wsa:From>
+ </soap:Header>
+ <soap:Body>
+ <wsrf-rp:GetResourcePropertyResponse xmlns:wsrf-rp="http://docs.oasis-open.org/wsrf/rp-2">
+ <qman:ConsumerCount xmlns:qman="http://amqp.apache.org/qpid/management/qman">-2147483638</qman:ConsumerCount>
+ </wsrf-rp:GetResourcePropertyResponse>
+ </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://localhost:8080/qman/services/QManWsResource</wsa:To>
+ <wsa:Action xmlns:wsa="http://www.w3.org/2005/08/addressing">http://docs.oasis-open.org/wsrf/rpw-2/GetResourceProperty/GetResourcePropertyRequest</wsa:Action>
+ <wsa:MessageID xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:92783239-777c-27fa-cec2-ee3afecf5c32</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">Q-MAN: brokerID=8e069b14-40ba-4d48-a2cb-b9f2bef2d404,class=queue,name=1232953394537,objectId=781f4ad7-4c96-4caa-b69d-291461cdb1fc,package=org.apache.qpid</qman-wsa:ResourceId>
+ </soap:Header>
+ <soap:Body>
+ <wsrf-rp:GetResourceProperty
+ xmlns:wsrf-rp="http://docs.oasis-open.org/wsrf/rp-2" xmlns:qman="http://amqp.apache.org/qpid/management/qman">qman:Type</wsrf-rp:GetResourceProperty>
+ </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/wsrf/rpw-2/GetResourceProperty/GetResourcePropertyResponse</wsa:Action>
+ <wsa:MessageID xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:af8168b4-6c13-c736-b521-f2b410541dd0</wsa:MessageID>
+ <wsa:RelatesTo RelationshipType="wsa:Reply" xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:92783239-777c-27fa-cec2-ee3afecf5c32</wsa:RelatesTo>
+ <wsa:From xmlns:wsa="http://www.w3.org/2005/08/addressing">
+ <wsa:Address>http://localhost:8080/qman/services/QManWsResource</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">Q-MAN: brokerID=8e069b14-40ba-4d48-a2cb-b9f2bef2d404,class=queue,name=1232953394537,objectId=781f4ad7-4c96-4caa-b69d-291461cdb1fc,package=org.apache.qpid</qman-wsa:ResourceId>
+ </wsa:ReferenceParameters>
+ </wsa:From>
+ </soap:Header>
+ <soap:Body>
+ <wsrf-rp:GetResourcePropertyResponse xmlns:wsrf-rp="http://docs.oasis-open.org/wsrf/rp-2"/>
+ </soap:Body>
+</soap:Envelope> \ No newline at end of file
diff --git a/qpid/java/management/client/src/example/GetWsdlMetadata.out.ko.no.resources b/qpid/java/management/client/src/example/GetWsdlMetadata.out.ko.no.resources
new file mode 100644
index 0000000000..6e727261f9
--- /dev/null
+++ b/qpid/java/management/client/src/example/GetWsdlMetadata.out.ko.no.resources
@@ -0,0 +1,58 @@
+ GetWSDLMetadataExample
+-------------------------------------------------------------------
+
+This example shows the usage of WS-DM
+GetResourcePropertyRequest / Response on a
+Group service.
+The target resource is the WS-DM Adapter itself
+and the requested property is "ws-rp:Entry".
+WS-DM Adapter is a special WS-Resource (is a Group)
+that acts as the main entry point for retrieving
+all other managed resources.
+So clients that want to deal with QMan WS-Resources
+must first get resource identifiers sending
+a GetResourcePropertyRequest to WS-DM Adapter
+with "ws-rp:Entry" as target target property.
+
+-------------------------------------------------------------------
+
+[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://localhost:8080/qman/services/adapter</wsa:To>
+ <wsa:Action xmlns:wsa="http://www.w3.org/2005/08/addressing">http://docs.oasis-open.org/wsrf/rpw-2/GetResourceProperty/GetResourcePropertyRequest</wsa:Action>
+ <wsa:MessageID xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:7f801eff-c528-91e8-33eb-3d1dd164bce7</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>
+ <wsrf-rp:GetResourceProperty
+ xmlns:wsrf-rp="http://docs.oasis-open.org/wsrf/rp-2" xmlns:wsrf-sg="http://docs.oasis-open.org/wsrf/sg-2">wsrf-sg:Entry</wsrf-rp:GetResourceProperty>
+ </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/wsrf/rpw-2/GetResourceProperty/GetResourcePropertyResponse</wsa:Action>
+ <wsa:MessageID xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:86a34968-38aa-83e8-47dd-8e86ffd8ac06</wsa:MessageID>
+ <wsa:RelatesTo RelationshipType="wsa:Reply" xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:7f801eff-c528-91e8-33eb-3d1dd164bce7</wsa:RelatesTo>
+ <wsa:From xmlns:wsa="http://www.w3.org/2005/08/addressing">
+ <wsa:Address>http://localhost:8080/qman/services/adapter</wsa:Address>
+ </wsa:From>
+ </soap:Header>
+ <soap:Body>
+ <wsrf-rp:GetResourcePropertyResponse xmlns:wsrf-rp="http://docs.oasis-open.org/wsrf/rp-2"/>
+ </soap:Body>
+</soap:Envelope>
+
+----------------------------WARNING---------------------------
+Cannot proceed with the example... it seems
+that there are no managed WS-Resources on QMan.
+Please check QMan in order to see that it is really
+connected with a broker.
+-------------------------------------------------------------------
diff --git a/qpid/java/management/client/src/example/GetWsdlMetadata.out.ok b/qpid/java/management/client/src/example/GetWsdlMetadata.out.ok
new file mode 100644
index 0000000000..16a4c1e07e
--- /dev/null
+++ b/qpid/java/management/client/src/example/GetWsdlMetadata.out.ok
@@ -0,0 +1,1968 @@
+ GetWSDLMetadataExample
+-------------------------------------------------------------------
+
+This example shows the usage of WS-DM
+GetResourcePropertyRequest / Response on a
+Group service.
+The target resource is the WS-DM Adapter itself
+and the requested property is "ws-rp:Entry".
+WS-DM Adapter is a special WS-Resource (is a Group)
+that acts as the main entry point for retrieving
+all other managed resources.
+So clients that want to deal with QMan WS-Resources
+must first get resource identifiers sending
+a GetResourcePropertyRequest to WS-DM Adapter
+with "ws-rp:Entry" as target target property.
+
+-------------------------------------------------------------------
+
+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://localhost:8080/qman/services/adapter</wsa:To>
+ <wsa:Action xmlns:wsa="http://www.w3.org/2005/08/addressing">http://docs.oasis-open.org/wsrf/rpw-2/GetResourceProperty/GetResourcePropertyRequest</wsa:Action>
+ <wsa:MessageID xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:ec4d0c03-3174-e39d-4a36-8f109056865b</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>
+ <wsrf-rp:GetResourceProperty
+ xmlns:wsrf-rp="http://docs.oasis-open.org/wsrf/rp-2" xmlns:wsrf-sg="http://docs.oasis-open.org/wsrf/sg-2">wsrf-sg:Entry</wsrf-rp:GetResourceProperty>
+ </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/wsrf/rpw-2/GetResourceProperty/GetResourcePropertyResponse</wsa:Action>
+ <wsa:MessageID xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:0f47d614-565e-5360-8dcc-ea8e4771e4dd</wsa:MessageID>
+ <wsa:RelatesTo RelationshipType="wsa:Reply" xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:ec4d0c03-3174-e39d-4a36-8f109056865b</wsa:RelatesTo>
+ <wsa:From xmlns:wsa="http://www.w3.org/2005/08/addressing">
+ <wsa:Address>http://localhost:8080/qman/services/adapter</wsa:Address>
+ </wsa:From>
+ </soap:Header>
+ <soap:Body>
+ <wsrf-rp:GetResourcePropertyResponse xmlns:wsrf-rp="http://docs.oasis-open.org/wsrf/rp-2">
+ <wsrf-sg:Entry xmlns:wsrf-sg="http://docs.oasis-open.org/wsrf/sg-2">
+ <wsrf-sg:ServiceGroupEntryEPR>
+ <wsa:Address xmlns:wsa="http://www.w3.org/2005/08/addressing">http://localhost:8080/qman/services/ServiceGroupEntry</wsa:Address>
+ <wsa:ReferenceParameters xmlns:wsa="http://www.w3.org/2005/08/addressing">
+ <muse-wsa:ResourceId xmlns:muse-wsa="http://ws.apache.org/muse/addressing">uuid:1d01b4ee-7d23-3a30-342e-62fc49984fe6</muse-wsa:ResourceId>
+ </wsa:ReferenceParameters>
+ </wsrf-sg:ServiceGroupEntryEPR>
+ <wsrf-sg:MemberServiceEPR>
+ <wsa:Address xmlns:wsa="http://www.w3.org/2005/08/addressing">http://localhost:8080/qman/services/QManWsResource</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">Q-MAN: brokerID=d5b32f44-5164-4e59-8f1d-a6f8c0a8a748,class=queue,name=1232872843214,objectId=a3759467-bede-476d-8dde-169f1a652191,package=org.apache.qpid</qman-wsa:ResourceId>
+ </wsa:ReferenceParameters>
+ </wsrf-sg:MemberServiceEPR>
+ <wsrf-sg:Content/>
+ </wsrf-sg:Entry>
+ </wsrf-rp:GetResourcePropertyResponse>
+ </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://localhost:8080/qman/services/QManWsResource</wsa:To>
+ <wsa:Action xmlns:wsa="http://www.w3.org/2005/08/addressing">http://schemas.xmlsoap.org/ws/2004/09/mex/GetMetadata</wsa:Action>
+ <wsa:MessageID xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:0cdb5112-09e0-ac39-06ba-393843f06e42</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">Q-MAN: brokerID=d5b32f44-5164-4e59-8f1d-a6f8c0a8a748,class=queue,name=1232872843214,objectId=a3759467-bede-476d-8dde-169f1a652191,package=org.apache.qpid</qman-wsa:ResourceId>
+ </soap:Header>
+ <soap:Body>
+ <qman:GetMetadata xmlns:qman="http://schemas.xmlsoap.org/ws/2004/09/mex">
+ <qman:Dialect>http://schemas.xmlsoap.org/wsdl/</qman:Dialect>
+ </qman:GetMetadata>
+ </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://schemas.xmlsoap.org/ws/2004/09/mex/GetMetadataResponse</wsa:Action>
+ <wsa:MessageID xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:980617c8-e3a0-ebf1-8f5a-2b43d3d6d416</wsa:MessageID>
+ <wsa:RelatesTo RelationshipType="wsa:Reply" xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:0cdb5112-09e0-ac39-06ba-393843f06e42</wsa:RelatesTo>
+ <wsa:From xmlns:wsa="http://www.w3.org/2005/08/addressing">
+ <wsa:Address>http://localhost:8080/qman/services/QManWsResource</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">Q-MAN: brokerID=d5b32f44-5164-4e59-8f1d-a6f8c0a8a748,class=queue,name=1232872843214,objectId=a3759467-bede-476d-8dde-169f1a652191,package=org.apache.qpid</qman-wsa:ResourceId>
+ </wsa:ReferenceParameters>
+ </wsa:From>
+ </soap:Header>
+ <soap:Body>
+ <wsx:Metadata xmlns:wsx="http://schemas.xmlsoap.org/ws/2004/09/mex">
+ <wsx:MetadataSection>
+ <wsdl:definitions name="QManWsResource"
+ targetNamespace="http://amqp.apache.org/qpid/management/qman"
+ xmlns="http://schemas.xmlsoap.org/wsdl/"
+ xmlns:qman="http://amqp.apache.org/qpid/management/qman"
+ xmlns:wsa="http://www.w3.org/2005/08/addressing"
+ xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
+ xmlns:wsdl-soap="http://schemas.xmlsoap.org/wsdl/soap/"
+ xmlns:wsrf-bf="http://docs.oasis-open.org/wsrf/bf-2"
+ xmlns:wsrf-r="http://docs.oasis-open.org/wsrf/r-2"
+ xmlns:wsrf-rl="http://docs.oasis-open.org/wsrf/rl-2"
+ xmlns:wsrf-rp="http://docs.oasis-open.org/wsrf/rp-2"
+ xmlns:wsrmd="http://docs.oasis-open.org/wsrf/rmd-1"
+ xmlns:wsx="http://schemas.xmlsoap.org/ws/2004/09/mex" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
+ <wsdl:types>
+ <xsd:schema attributeFormDefault="unqualified"
+ elementFormDefault="qualified"
+ targetNamespace="http://www.w3.org/2005/08/addressing"
+ xmlns:tns="http://www.w3.org/2005/08/addressing" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+ <xs:element name="EndpointReference"
+ type="tns:EndpointReferenceType" xmlns:xs="http://www.w3.org/2001/XMLSchema"/>
+ <xs:complexType mixed="false"
+ name="EndpointReferenceType" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+ <xs:sequence>
+ <xs:element name="Address" type="tns:AttributedURIType"/>
+ <xs:element minOccurs="0"
+ name="ReferenceParameters" type="tns:ReferenceParametersType"/>
+ <xs:element minOccurs="0" ref="tns:Metadata"/>
+ <xs:any maxOccurs="unbounded"
+ minOccurs="0"
+ namespace="##other" processContents="lax"/>
+ </xs:sequence>
+ <xs:anyAttribute namespace="##other" processContents="lax"/>
+ </xs:complexType>
+ <xs:complexType mixed="false"
+ name="ReferenceParametersType" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+ <xs:sequence>
+ <xs:any maxOccurs="unbounded"
+ minOccurs="0" namespace="##any" processContents="lax"/>
+ </xs:sequence>
+ <xs:anyAttribute namespace="##other" processContents="lax"/>
+ </xs:complexType>
+ <xs:element name="Metadata"
+ type="tns:MetadataType" xmlns:xs="http://www.w3.org/2001/XMLSchema"/>
+ <xs:complexType mixed="false"
+ name="MetadataType" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+ <xs:sequence>
+ <xs:any maxOccurs="unbounded"
+ minOccurs="0" namespace="##any" processContents="lax"/>
+ </xs:sequence>
+ <xs:anyAttribute namespace="##other" processContents="lax"/>
+ </xs:complexType>
+ <xs:element name="MessageID"
+ type="tns:AttributedURIType" xmlns:xs="http://www.w3.org/2001/XMLSchema"/>
+ <xs:element name="RelatesTo"
+ type="tns:RelatesToType" xmlns:xs="http://www.w3.org/2001/XMLSchema"/>
+ <xs:complexType mixed="false"
+ name="RelatesToType" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+ <xs:simpleContent>
+ <xs:extension base="xs:anyURI">
+ <xs:attribute
+ default="http://www.w3.org/2005/08/addressing/reply"
+ name="RelationshipType"
+ type="tns:RelationshipTypeOpenEnum" use="optional"/>
+ <xs:anyAttribute
+ namespace="##other" processContents="lax"/>
+ </xs:extension>
+ </xs:simpleContent>
+ </xs:complexType>
+ <xs:simpleType
+ name="RelationshipTypeOpenEnum" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+ <xs:union memberTypes="tns:RelationshipType xs:anyURI"/>
+ </xs:simpleType>
+ <xs:simpleType name="RelationshipType" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+ <xs:restriction base="xs:anyURI">
+ <xs:enumeration value="http://www.w3.org/2005/08/addressing/reply"/>
+ </xs:restriction>
+ </xs:simpleType>
+ <xs:element name="ReplyTo"
+ type="tns:EndpointReferenceType" xmlns:xs="http://www.w3.org/2001/XMLSchema"/>
+ <xs:element name="From"
+ type="tns:EndpointReferenceType" xmlns:xs="http://www.w3.org/2001/XMLSchema"/>
+ <xs:element name="FaultTo"
+ type="tns:EndpointReferenceType" xmlns:xs="http://www.w3.org/2001/XMLSchema"/>
+ <xs:element name="To"
+ type="tns:AttributedURIType" xmlns:xs="http://www.w3.org/2001/XMLSchema"/>
+ <xs:element name="Action"
+ type="tns:AttributedURIType" xmlns:xs="http://www.w3.org/2001/XMLSchema"/>
+ <xs:complexType mixed="false"
+ name="AttributedURIType" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+ <xs:simpleContent>
+ <xs:extension base="xs:anyURI">
+ <xs:anyAttribute
+ namespace="##other" processContents="lax"/>
+ </xs:extension>
+ </xs:simpleContent>
+ </xs:complexType>
+ <xs:attribute name="IsReferenceParameter"
+ type="xs:boolean" xmlns:xs="http://www.w3.org/2001/XMLSchema"/>
+ <xs:simpleType name="FaultCodesOpenEnumType" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+ <xs:union memberTypes="tns:FaultCodesType xs:QName"/>
+ </xs:simpleType>
+ <xs:simpleType name="FaultCodesType" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+ <xs:restriction base="xs:QName">
+ <xs:enumeration value="tns:InvalidAddressingHeader"/>
+ <xs:enumeration value="tns:InvalidAddress"/>
+ <xs:enumeration value="tns:InvalidEPR"/>
+ <xs:enumeration value="tns:InvalidCardinality"/>
+ <xs:enumeration value="tns:MissingAddressInEPR"/>
+ <xs:enumeration value="tns:DuplicateMessageID"/>
+ <xs:enumeration value="tns:ActionMismatch"/>
+ <xs:enumeration value="tns:MessageAddressingHeaderRequired"/>
+ <xs:enumeration value="tns:DestinationUnreachable"/>
+ <xs:enumeration value="tns:ActionNotSupported"/>
+ <xs:enumeration value="tns:EndpointUnavailable"/>
+ </xs:restriction>
+ </xs:simpleType>
+ <xs:element name="RetryAfter"
+ type="tns:AttributedUnsignedLongType" xmlns:xs="http://www.w3.org/2001/XMLSchema"/>
+ <xs:complexType mixed="false"
+ name="AttributedUnsignedLongType" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+ <xs:simpleContent>
+ <xs:extension base="xs:unsignedLong">
+ <xs:anyAttribute
+ namespace="##other" processContents="lax"/>
+ </xs:extension>
+ </xs:simpleContent>
+ </xs:complexType>
+ <xs:element name="ProblemHeaderQName"
+ type="tns:AttributedQNameType" xmlns:xs="http://www.w3.org/2001/XMLSchema"/>
+ <xs:complexType mixed="false"
+ name="AttributedQNameType" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+ <xs:simpleContent>
+ <xs:extension base="xs:QName">
+ <xs:anyAttribute
+ namespace="##other" processContents="lax"/>
+ </xs:extension>
+ </xs:simpleContent>
+ </xs:complexType>
+ <xs:element name="ProblemHeader"
+ type="tns:AttributedAnyType" xmlns:xs="http://www.w3.org/2001/XMLSchema"/>
+ <xs:complexType mixed="false"
+ name="AttributedAnyType" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+ <xs:sequence>
+ <xs:any maxOccurs="1" minOccurs="1"
+ namespace="##any" processContents="lax"/>
+ </xs:sequence>
+ <xs:anyAttribute namespace="##other" processContents="lax"/>
+ </xs:complexType>
+ <xs:element name="ProblemIRI"
+ type="tns:AttributedURIType" xmlns:xs="http://www.w3.org/2001/XMLSchema"/>
+ <xs:element name="ProblemAction"
+ type="tns:ProblemActionType" xmlns:xs="http://www.w3.org/2001/XMLSchema"/>
+ <xs:complexType mixed="false"
+ name="ProblemActionType" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+ <xs:sequence>
+ <xs:element minOccurs="0" ref="tns:Action"/>
+ <xs:element minOccurs="0"
+ name="SoapAction" type="xs:anyURI"/>
+ </xs:sequence>
+ <xs:anyAttribute namespace="##other" processContents="lax"/>
+ </xs:complexType>
+ </xsd:schema>
+ <xsd:schema elementFormDefault="qualified"
+ targetNamespace="http://schemas.xmlsoap.org/ws/2004/09/mex"
+ xmlns:tns="http://schemas.xmlsoap.org/ws/2004/09/mex"
+ xmlns:wsa="http://www.w3.org/2005/08/addressing" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+ <xs:import
+ namespace="http://www.w3.org/2005/08/addressing" xmlns:xs="http://www.w3.org/2001/XMLSchema"/>
+ <xs:element name="GetMetadata" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element minOccurs="0" ref="tns:Dialect"/>
+ <xs:element minOccurs="0" ref="tns:Identifier"/>
+ </xs:sequence>
+ <xs:anyAttribute namespace="##other" processContents="lax"/>
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="Dialect" type="xs:anyURI" xmlns:xs="http://www.w3.org/2001/XMLSchema"/>
+ <xs:element name="Identifier"
+ type="xs:anyURI" xmlns:xs="http://www.w3.org/2001/XMLSchema"/>
+ <xs:element name="Metadata" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element
+ maxOccurs="unbounded"
+ minOccurs="0" ref="tns:MetadataSection"/>
+ </xs:sequence>
+ <xs:anyAttribute namespace="##other" processContents="lax"/>
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="MetadataSection" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+ <xs:complexType>
+ <xs:choice>
+ <xs:any maxOccurs="unbounded"
+ minOccurs="0"
+ namespace="##other" processContents="lax"/>
+ <xs:element ref="tns:MetadataReference"/>
+ <xs:element ref="tns:Location"/>
+ </xs:choice>
+ <xs:attribute name="Dialect"
+ type="xs:anyURI" use="required"/>
+ <xs:attribute name="Identifier" type="xs:anyURI"/>
+ <xs:anyAttribute namespace="##other" processContents="lax"/>
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="MetadataReference"
+ type="wsa:EndpointReferenceType" xmlns:xs="http://www.w3.org/2001/XMLSchema"/>
+ <xs:element name="Location" type="xs:anyURI" xmlns:xs="http://www.w3.org/2001/XMLSchema"/>
+ <xs:complexType name="AnyXmlType" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+ <xs:sequence>
+ <xs:any namespace="##any" processContents="lax"/>
+ </xs:sequence>
+ <xs:anyAttribute namespace="##any" processContents="lax"/>
+ </xs:complexType>
+ </xsd:schema>
+ <xsd:schema attributeFormDefault="unqualified"
+ elementFormDefault="qualified"
+ targetNamespace="http://docs.oasis-open.org/wsrf/rl-2"
+ xmlns="http://www.w3.org/2001/XMLSchema"
+ xmlns:wsrf-bf="http://docs.oasis-open.org/wsrf/bf-2"
+ xmlns:wsrf-rl="http://docs.oasis-open.org/wsrf/rl-2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <xsd:import namespace="http://docs.oasis-open.org/wsrf/bf-2"/>
+ <xsd:element name="CurrentTime">
+ <xsd:complexType>
+ <xsd:simpleContent>
+ <xsd:extension base="xsd:dateTime">
+ <xsd:anyAttribute
+ namespace="##other" processContents="lax"/>
+ </xsd:extension>
+ </xsd:simpleContent>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="TerminationTime" nillable="true">
+ <xsd:complexType>
+ <xsd:simpleContent>
+ <xsd:extension base="xsd:dateTime">
+ <xsd:anyAttribute
+ namespace="##other" processContents="lax"/>
+ </xsd:extension>
+ </xsd:simpleContent>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="ScheduledResourceTerminationRP">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element maxOccurs="1"
+ minOccurs="1" ref="wsrf-rl:CurrentTime"/>
+ <xsd:element maxOccurs="1"
+ minOccurs="1" ref="wsrf-rl:TerminationTime"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="Destroy">
+ <xsd:complexType/>
+ </xsd:element>
+ <xsd:element name="DestroyResponse">
+ <xsd:complexType/>
+ </xsd:element>
+ <xsd:complexType name="ResourceNotDestroyedFaultType">
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType"/>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:element
+ name="ResourceNotDestroyedFault" type="wsrf-rl:ResourceNotDestroyedFaultType"/>
+ <xsd:element name="SetTerminationTime">
+ <xsd:complexType>
+ <xsd:choice>
+ <xsd:element
+ name="RequestedTerminationTime"
+ nillable="true" type="xsd:dateTime"/>
+ <xsd:element
+ name="RequestedLifetimeDuration" type="xsd:duration"/>
+ </xsd:choice>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="SetTerminationTimeResponse">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element
+ name="NewTerminationTime"
+ nillable="true" type="xsd:dateTime"/>
+ <xsd:element name="CurrentTime" type="xsd:dateTime"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:complexType name="UnableToSetTerminationTimeFaultType">
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType"/>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:element
+ name="UnableToSetTerminationTimeFault" type="wsrf-rl:UnableToSetTerminationTimeFaultType"/>
+ <xsd:complexType name="TerminationTimeChangeRejectedFaultType">
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType"/>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:element
+ name="TerminationTimeChangeRejectedFault" type="wsrf-rl:TerminationTimeChangeRejectedFaultType"/>
+ <xsd:element name="TerminationNotification">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element maxOccurs="1"
+ minOccurs="1"
+ name="TerminationTime"
+ nillable="true" type="xsd:dateTime"/>
+ <xsd:element maxOccurs="1"
+ minOccurs="0"
+ name="TerminationReason" type="xsd:anyType"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:schema>
+ <xsd:schema attributeFormDefault="unqualified"
+ elementFormDefault="qualified"
+ targetNamespace="http://docs.oasis-open.org/wsrf/rp-2"
+ xmlns:wsrf-bf="http://docs.oasis-open.org/wsrf/bf-2" xmlns:wsrf-rp="http://docs.oasis-open.org/wsrf/rp-2">
+ <xsd:import namespace="http://docs.oasis-open.org/wsrf/bf-2"/>
+ <xsd:element name="QueryExpressionDialect" type="xsd:anyURI"/>
+ <xsd:element name="QueryExpressionRPDocument">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element
+ maxOccurs="unbounded"
+ minOccurs="0" ref="wsrf-rp:QueryExpressionDialect"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:attribute name="ResourceProperties" type="xsd:QName"/>
+ <xsd:complexType name="ResourcePropertyValueChangeNotificationType">
+ <xsd:sequence>
+ <xsd:element maxOccurs="1"
+ minOccurs="0" name="OldValues" nillable="true">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:any
+ maxOccurs="unbounded" minOccurs="1"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element maxOccurs="1"
+ minOccurs="1" name="NewValues" nillable="true">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:any
+ maxOccurs="unbounded" minOccurs="1"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:element
+ name="ResourcePropertyValueChangeNotification" type="wsrf-rp:ResourcePropertyValueChangeNotificationType"/>
+ <xsd:complexType mixed="true" name="QueryExpressionType">
+ <xsd:sequence>
+ <xsd:any maxOccurs="1" minOccurs="0" processContents="lax"/>
+ </xsd:sequence>
+ <xsd:attribute name="Dialect" type="xsd:anyURI"/>
+ </xsd:complexType>
+ <xsd:element name="QueryExpression" type="wsrf-rp:QueryExpressionType"/>
+ <xsd:element name="GetResourcePropertyDocument">
+ <xsd:complexType/>
+ </xsd:element>
+ <xsd:element name="GetResourcePropertyDocumentResponse">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:any maxOccurs="1" minOccurs="1"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="GetResourceProperty" type="xsd:QName"/>
+ <xsd:element name="GetResourcePropertyResponse">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:any maxOccurs="unbounded" minOccurs="0"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:complexType name="InvalidResourcePropertyQNameFaultType">
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType"/>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:element
+ name="InvalidResourcePropertyQNameFault" type="wsrf-rp:InvalidResourcePropertyQNameFaultType"/>
+ <xsd:element name="GetMultipleResourceProperties">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element
+ maxOccurs="unbounded"
+ minOccurs="1"
+ name="ResourceProperty" type="xsd:QName"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="GetMultipleResourcePropertiesResponse">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:any maxOccurs="unbounded" minOccurs="0"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="PutResourcePropertyDocument">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:any maxOccurs="1" minOccurs="1"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="PutResourcePropertyDocumentResponse">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:any maxOccurs="1" minOccurs="0"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:complexType name="ResourcePropertyChangeFailureType">
+ <xsd:sequence>
+ <xsd:element maxOccurs="1"
+ minOccurs="0" name="CurrentValue">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:any
+ maxOccurs="unbounded" minOccurs="1"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element maxOccurs="1"
+ minOccurs="0" name="RequestedValue">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:any
+ maxOccurs="unbounded" minOccurs="1"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:sequence>
+ <xsd:attribute name="Restored" type="xsd:boolean"/>
+ </xsd:complexType>
+ <xsd:complexType name="UnableToPutResourcePropertyDocumentFaultType">
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType">
+ <xsd:sequence>
+ <xsd:element
+ name="ResourcePropertyChangeFailure" type="wsrf-rp:ResourcePropertyChangeFailureType"/>
+ </xsd:sequence>
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:element
+ name="UnableToPutResourcePropertyDocumentFault" type="wsrf-rp:UnableToPutResourcePropertyDocumentFaultType"/>
+ <xsd:complexType name="InsertType">
+ <xsd:sequence>
+ <xsd:any maxOccurs="unbounded"
+ minOccurs="1" processContents="lax"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:element name="Insert" type="wsrf-rp:InsertType"/>
+ <xsd:complexType name="UpdateType">
+ <xsd:sequence>
+ <xsd:any maxOccurs="unbounded"
+ minOccurs="1" processContents="lax"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:element name="Update" type="wsrf-rp:UpdateType"/>
+ <xsd:complexType name="DeleteType">
+ <xsd:attribute name="ResourceProperty"
+ type="xsd:QName" use="required"/>
+ </xsd:complexType>
+ <xsd:element name="Delete" type="wsrf-rp:DeleteType"/>
+ <xsd:element name="SetResourceProperties">
+ <xsd:complexType>
+ <xsd:choice maxOccurs="unbounded" minOccurs="1">
+ <xsd:element ref="wsrf-rp:Insert"/>
+ <xsd:element ref="wsrf-rp:Update"/>
+ <xsd:element ref="wsrf-rp:Delete"/>
+ </xsd:choice>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="SetResourcePropertiesResponse">
+ <xsd:complexType/>
+ </xsd:element>
+ <xsd:complexType name="InvalidModificationFaultType">
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType">
+ <xsd:sequence>
+ <xsd:element
+ name="ResourcePropertyChangeFailure" type="wsrf-rp:ResourcePropertyChangeFailureType"/>
+ </xsd:sequence>
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:element name="InvalidModificationFault" type="wsrf-rp:InvalidModificationFaultType"/>
+ <xsd:complexType name="UnableToModifyResourcePropertyFaultType">
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType">
+ <xsd:sequence>
+ <xsd:element
+ name="ResourcePropertyChangeFailure" type="wsrf-rp:ResourcePropertyChangeFailureType"/>
+ </xsd:sequence>
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:element
+ name="UnableToModifyResourcePropertyFault" type="wsrf-rp:UnableToModifyResourcePropertyFaultType"/>
+ <xsd:complexType name="SetResourcePropertyRequestFailedFaultType">
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType">
+ <xsd:sequence>
+ <xsd:element
+ name="ResourcePropertyChangeFailure" type="wsrf-rp:ResourcePropertyChangeFailureType"/>
+ </xsd:sequence>
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:element
+ name="SetResourcePropertyRequestFailedFault" type="wsrf-rp:SetResourcePropertyRequestFailedFaultType"/>
+ <xsd:complexType name="InsertResourcePropertiesRequestFailedFaultType">
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType">
+ <xsd:sequence>
+ <xsd:element
+ name="ResourcePropertyChangeFailure" type="wsrf-rp:ResourcePropertyChangeFailureType"/>
+ </xsd:sequence>
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:element
+ name="InsertResourcePropertiesRequestFailedFault" type="wsrf-rp:InsertResourcePropertiesRequestFailedFaultType"/>
+ <xsd:complexType name="UpdateResourcePropertiesRequestFailedFaultType">
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType">
+ <xsd:sequence>
+ <xsd:element
+ name="ResourcePropertyChangeFailure" type="wsrf-rp:ResourcePropertyChangeFailureType"/>
+ </xsd:sequence>
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:element
+ name="UpdateResourcePropertiesRequestFailedFault" type="wsrf-rp:UpdateResourcePropertiesRequestFailedFaultType"/>
+ <xsd:complexType name="DeleteResourcePropertiesRequestFailedFaultType">
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType">
+ <xsd:sequence>
+ <xsd:element
+ name="ResourcePropertyChangeFailure" type="wsrf-rp:ResourcePropertyChangeFailureType"/>
+ </xsd:sequence>
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:element
+ name="DeleteResourcePropertiesRequestFailedFault" type="wsrf-rp:DeleteResourcePropertiesRequestFailedFaultType"/>
+ <xsd:element name="InsertResourceProperties">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element ref="wsrf-rp:Insert"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="InsertResourcePropertiesResponse">
+ <xsd:complexType/>
+ </xsd:element>
+ <xsd:element name="UpdateResourceProperties">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element ref="wsrf-rp:Update"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="UpdateResourcePropertiesResponse">
+ <xsd:complexType/>
+ </xsd:element>
+ <xsd:element name="DeleteResourceProperties">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element ref="wsrf-rp:Delete"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="DeleteResourcePropertiesResponse">
+ <xsd:complexType/>
+ </xsd:element>
+ <xsd:element name="QueryResourceProperties">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element maxOccurs="1"
+ minOccurs="1" ref="wsrf-rp:QueryExpression"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="QueryResourcePropertiesResponse">
+ <xsd:complexType>
+ <xsd:complexContent mixed="true">
+ <xsd:restriction base="xsd:anyType">
+ <xsd:sequence>
+ <xsd:any
+ maxOccurs="unbounded"
+ minOccurs="1" processContents="lax"/>
+ </xsd:sequence>
+ </xsd:restriction>
+ </xsd:complexContent>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:complexType name="UnknownQueryExpressionDialectFaultType">
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType"/>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:element
+ name="UnknownQueryExpressionDialectFault" type="wsrf-rp:UnknownQueryExpressionDialectFaultType"/>
+ <xsd:complexType name="InvalidQueryExpressionFaultType">
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType"/>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:element
+ name="InvalidQueryExpressionFault" type="wsrf-rp:InvalidQueryExpressionFaultType"/>
+ <xsd:complexType name="QueryEvaluationErrorFaultType">
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType"/>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:element
+ name="QueryEvaluationErrorFault" type="wsrf-rp:QueryEvaluationErrorFaultType"/>
+ </xsd:schema>
+ <xsd:schema attributeFormDefault="unqualified"
+ elementFormDefault="qualified"
+ targetNamespace="http://docs.oasis-open.org/wsrf/r-2"
+ xmlns:wsrf-bf="http://docs.oasis-open.org/wsrf/bf-2"
+ xmlns:wsrf-r="http://docs.oasis-open.org/wsrf/r-2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <xsd:import namespace="http://docs.oasis-open.org/wsrf/bf-2"/>
+ <xsd:complexType name="ResourceUnknownFaultType">
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType"/>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:element name="ResourceUnknownFault" type="wsrf-r:ResourceUnknownFaultType"/>
+ <xsd:complexType name="ResourceUnavailableFaultType">
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType"/>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:element name="ResourceUnavailableFault" type="wsrf-r:ResourceUnavailableFaultType"/>
+ </xsd:schema>
+ <xsd:schema elementFormDefault="qualified"
+ targetNamespace="http://docs.oasis-open.org/wsrf/rmd-1"
+ xmlns="http://www.w3.org/2001/XMLSchema"
+ xmlns:wsa="http://www.w3.org/2005/08/addressing"
+ xmlns:wsrf-rp="http://docs.oasis-open.org/wsrf/rp-2" xmlns:wsrmd="http://docs.oasis-open.org/wsrf/rmd-1">
+ <xsd:import namespace="http://docs.oasis-open.org/wsrf/rp-2"/>
+ <xsd:import namespace="http://www.w3.org/2005/08/addressing"/>
+ <xsd:simpleType name="PairsOfURIType">
+ <xsd:list itemType="xsd:anyURI"/>
+ </xsd:simpleType>
+ <xsd:attribute name="Descriptor" type="xsd:QName"/>
+ <xsd:attribute name="DescriptorLocation" type="xsd:anyURI"/>
+ <xsd:complexType mixed="true" name="DocumentationType">
+ <xsd:sequence>
+ <xsd:any maxOccurs="unbounded"
+ minOccurs="0" namespace="##any" processContents="lax"/>
+ </xsd:sequence>
+ <xsd:anyAttribute/>
+ </xsd:complexType>
+ <xsd:complexType name="DocumentedType">
+ <xsd:sequence>
+ <xsd:element maxOccurs="1"
+ minOccurs="0"
+ name="documentation" type="wsrmd:DocumentationType"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:complexType name="DefinitionsType">
+ <xsd:complexContent>
+ <xsd:extension base="wsrmd:DocumentedType">
+ <xsd:sequence>
+ <xsd:element
+ maxOccurs="unbounded"
+ minOccurs="0" ref="wsrmd:MetadataDescriptor"/>
+ <xsd:any
+ maxOccurs="unbounded"
+ minOccurs="0"
+ namespace="##other" processContents="lax"/>
+ </xsd:sequence>
+ <xsd:attribute
+ name="targetNamespace"
+ type="xsd:anyURI" use="required"/>
+ <xsd:anyAttribute
+ namespace="##other" processContents="lax"/>
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:element name="Definitions" type="wsrmd:DefinitionsType">
+ <xsd:key name="MetadataDescriptor">
+ <xsd:annotation>
+ <xsd:documentation>
+ To form a QName, the name of any MetadataDescriptor must be
+ unique within a Definitions element.
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:selector xpath="wsrmd:MetadataDescriptor"/>
+ <xsd:field xpath="@name"/>
+ </xsd:key>
+ </xsd:element>
+ <xsd:complexType name="MetadataDescriptorType">
+ <xsd:complexContent>
+ <xsd:extension base="wsrmd:DocumentedType">
+ <xsd:sequence>
+ <xsd:element
+ maxOccurs="unbounded"
+ minOccurs="0" ref="wsrmd:Property"/>
+ <xsd:any
+ maxOccurs="unbounded"
+ minOccurs="0"
+ namespace="##other" processContents="lax"/>
+ </xsd:sequence>
+ <xsd:attribute name="name"
+ type="xsd:NCName" use="required"/>
+ <xsd:attribute name="interface"
+ type="xsd:QName" use="required"/>
+ <xsd:attribute
+ name="wsdlLocation" type="wsrmd:PairsOfURIType"/>
+ <xsd:anyAttribute
+ namespace="##other" processContents="lax"/>
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:element name="MetadataDescriptor" type="wsrmd:MetadataDescriptorType"/>
+ <xsd:complexType name="PropertyType">
+ <xsd:complexContent>
+ <xsd:extension base="wsrmd:DocumentedType">
+ <xsd:sequence>
+ <xsd:choice>
+ <xsd:element
+ maxOccurs="1"
+ minOccurs="0" ref="wsrmd:ValidValues"/>
+ <xsd:element
+ maxOccurs="1"
+ minOccurs="0" ref="wsrmd:ValidValueRange"/>
+ </xsd:choice>
+ <xsd:element maxOccurs="1"
+ minOccurs="0" ref="wsrmd:StaticValues"/>
+ <xsd:any
+ maxOccurs="unbounded"
+ minOccurs="0"
+ namespace="##other" processContents="lax"/>
+ </xsd:sequence>
+ <xsd:attribute name="name"
+ type="xsd:QName" use="required"/>
+ <xsd:attribute name="mutability" type="wsrmd:MutabilityType"/>
+ <xsd:attribute
+ name="modifiability" type="wsrmd:ModifiabilityType"/>
+ <xsd:attribute default="false"
+ name="subscribability" type="xsd:boolean"/>
+ <xsd:anyAttribute
+ namespace="##other" processContents="lax"/>
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:element name="Property" type="wsrmd:PropertyType"/>
+ <xsd:simpleType name="MutabilityType">
+ <xsd:restriction base="xsd:string">
+ <xsd:enumeration value="constant"/>
+ <xsd:enumeration value="appendable"/>
+ <xsd:enumeration value="mutable"/>
+ </xsd:restriction>
+ </xsd:simpleType>
+ <xsd:simpleType name="ModifiabilityType">
+ <xsd:restriction base="xsd:string">
+ <xsd:enumeration value="read-only"/>
+ <xsd:enumeration value="read-write"/>
+ </xsd:restriction>
+ </xsd:simpleType>
+ <xsd:complexType mixed="true" name="ValidValuesType">
+ <xsd:sequence>
+ <xsd:element maxOccurs="1"
+ minOccurs="0"
+ name="documentation" type="wsrmd:DocumentationType"/>
+ <xsd:any maxOccurs="unbounded"
+ minOccurs="0"
+ namespace="##other" processContents="lax"/>
+ </xsd:sequence>
+ <xsd:anyAttribute namespace="##other" processContents="lax"/>
+ </xsd:complexType>
+ <xsd:element name="ValidValues" type="wsrmd:ValidValuesType"/>
+ <xsd:complexType mixed="true" name="ValidValueRangeType">
+ <xsd:sequence>
+ <xsd:element maxOccurs="1"
+ minOccurs="0"
+ name="documentation" type="wsrmd:DocumentationType"/>
+ <xsd:any maxOccurs="unbounded"
+ minOccurs="0"
+ namespace="##other" processContents="lax"/>
+ </xsd:sequence>
+ <xsd:attribute name="lowerBound" type="xsd:anySimpleType"/>
+ <xsd:attribute name="upperBound" type="xsd:anySimpleType"/>
+ <xsd:anyAttribute namespace="##other" processContents="lax"/>
+ </xsd:complexType>
+ <xsd:element name="ValidValueRange" type="wsrmd:ValidValueRangeType"/>
+ <xsd:complexType mixed="true" name="StaticValuesType">
+ <xsd:sequence>
+ <xsd:element maxOccurs="1"
+ minOccurs="0"
+ name="documentation" type="wsrmd:DocumentationType"/>
+ <xsd:any maxOccurs="unbounded"
+ minOccurs="0"
+ namespace="##other" processContents="lax"/>
+ </xsd:sequence>
+ <xsd:anyAttribute namespace="##other" processContents="lax"/>
+ </xsd:complexType>
+ <xsd:element name="StaticValues" type="wsrmd:StaticValuesType"/>
+ <xsd:complexType mixed="true" name="InitialValuesType">
+ <xsd:sequence>
+ <xsd:element maxOccurs="1"
+ minOccurs="0"
+ name="documentation" type="wsrmd:DocumentationType"/>
+ <xsd:any maxOccurs="unbounded"
+ minOccurs="0"
+ namespace="##other" processContents="lax"/>
+ </xsd:sequence>
+ <xsd:anyAttribute namespace="##other" processContents="lax"/>
+ </xsd:complexType>
+ <xsd:element name="InitialValues" type="wsrmd:InitialValuesType"/>
+ <xsd:complexType name="MetadataDescriptorReferenceType">
+ <xsd:complexContent>
+ <xsd:extension base="wsa:EndpointReferenceType"/>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:element
+ name="MetadataDescriptorReference" type="wsrmd:MetadataDescriptorReferenceType"/>
+ <xsd:element name="MetadataResourceRP" type="wsrmd:DefinitionsType"/>
+ </xsd:schema>
+ <xsd:schema elementFormDefault="qualified" targetNamespace="http://amqp.apache.org/qpid/management/qman">
+ <xsd:import namespace="http://docs.oasis-open.org/wsrf/rl-2"/>
+ <xsd:import namespace="http://docs.oasis-open.org/wsrf/rp-2"/>
+ <xsd:import namespace="http://docs.oasis-open.org/wsrf/bf-2"/>
+ <xsd:element name="QManWsResourceProperties">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element ref="wsrf-rl:CurrentTime"/>
+ <xsd:element ref="wsrf-rl:TerminationTime"/>
+ <xsd:element
+ maxOccurs="unbounded"
+ minOccurs="0" ref="wsrf-rp:QueryExpressionDialect"/>
+ <xsd:element ref="qman:Name"/>
+ <xsd:element ref="qman:Type"/>
+ <xsd:element ref="qman:Arguments"/>
+ <xsd:element ref="qman:VhostRef"/>
+ <xsd:element ref="qman:Durable"/>
+ <xsd:element ref="qman:MsgTotalEnqueues"/>
+ <xsd:element ref="qman:ConsumerCount"/>
+ <xsd:element ref="qman:ExpireTime"/>
+ <xsd:element ref="qman:MgmtPubInterval"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="QManFault">
+ <xsd:complexType>
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType"/>
+ </xsd:complexContent>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="MethodInvocationFault">
+ <xsd:complexType>
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType"/>
+ </xsd:complexContent>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="EntityInstanceNotFoundFault">
+ <xsd:complexType>
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType"/>
+ </xsd:complexContent>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="MalformedEntityNameFault">
+ <xsd:complexType>
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType"/>
+ </xsd:complexContent>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="NoSuchAttributeFault">
+ <xsd:complexType>
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType"/>
+ </xsd:complexContent>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:complexType name="result">
+ <xsd:sequence>
+ <xsd:element name="statusCode" type="xsd:long"/>
+ <xsd:element name="statusText" type="xsd:string"/>
+ <xsd:complexType name="outputParameters">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element
+ maxOccurs="unbounded"
+ minOccurs="0" name="entry">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:name
+ name="key" type="xsd:string"/>
+ <xsd:element
+ name="value" type="xsd:anyType"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:complexType>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:element name="Name" type="xsd:string"/>
+ <xsd:element name="Type" type="xsd:string"/>
+ <xsd:complexType name="map">
+ <xsd:sequence>
+ <xsd:element maxOccurs="unbounded"
+ minOccurs="0" name="entry">
+ <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:element name="Arguments" type="qman:map"/>
+ <xsd:complexType name="uuid">
+ <xsd:sequence>
+ <xsd:element name="uuid" type="xsd:string"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:element name="VhostRef" type="qman:uuid"/>
+ <xsd:element name="Durable" type="xsd:boolean"/>
+ <xsd:element name="MsgTotalEnqueues" type="xsd:long"/>
+ <xsd:element name="ConsumerCount" type="xsd:integer"/>
+ <xsd:element name="ExpireTime" type="xsd:dateTime"/>
+ <xsd:element name="MgmtPubInterval" type="xsd:short"/>
+ <xsd:element
+ name="echoWithSimpleTypesRequest" type="qman:echoWithSimpleTypesRequest"/>
+ <xsd:element
+ name="echoWithSimpleTypesResponse" type="qman:echoWithSimpleTypesResponse"/>
+ <xsd:complexType name="echoWithSimpleTypesRequest">
+ <xsd:sequence>
+ <xsd:element name="p1" type="xsd:long"/>
+ <xsd:element name="p2" type="xsd:boolean"/>
+ <xsd:element name="p3" type="xsd:double"/>
+ <xsd:element name="p4" type="xsd:float"/>
+ <xsd:element name="p5" type="xsd:integer"/>
+ <xsd:element name="p6" type="xsd:short"/>
+ <xsd:element name="p7" type="xsd:string"/>
+ <xsd:element name="p8" type="xsd:anyURI"/>
+ <xsd:element name="p9" type="xsd:dateTime"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:complexType name="echoWithSimpleTypesResponse">
+ <xsd:sequence>
+ <xsd:element name="result" type="qman:result"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:element name="echoWithArraysRequest" type="qman:echoWithArraysRequest"/>
+ <xsd:element name="echoWithArraysResponse" type="qman:echoWithArraysResponse"/>
+ <xsd:complexType name="arrayOfLong">
+ <xsd:sequence>
+ <xsd:element name="entry" type="xsd:long"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:complexType name="arrayOfBoolean">
+ <xsd:sequence>
+ <xsd:element name="entry" type="xsd:boolean"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:complexType name="arrayOfDouble">
+ <xsd:sequence>
+ <xsd:element name="entry" type="xsd:double"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:complexType name="arrayOfFloat">
+ <xsd:sequence>
+ <xsd:element name="entry" type="xsd:float"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:complexType name="arrayOfInteger">
+ <xsd:sequence>
+ <xsd:element name="entry" type="xsd:integer"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:complexType name="arrayOfShort">
+ <xsd:sequence>
+ <xsd:element name="entry" type="xsd:short"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:complexType name="arrayOfString">
+ <xsd:sequence>
+ <xsd:element name="entry" type="xsd:string"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:complexType name="arrayOfURI">
+ <xsd:sequence>
+ <xsd:element name="entry" type="xsd:anyURI"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:complexType name="arrayOfDate">
+ <xsd:sequence>
+ <xsd:element name="entry" type="xsd:dateTime"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:complexType name="echoWithArraysRequest">
+ <xsd:sequence>
+ <xsd:element name="p1" type="qman:arrayOfLong"/>
+ <xsd:element name="p2" type="qman:arrayOfBoolean"/>
+ <xsd:element name="p3" type="qman:arrayOfDouble"/>
+ <xsd:element name="p4" type="qman:arrayOfFloat"/>
+ <xsd:element name="p5" type="qman:arrayOfInteger"/>
+ <xsd:element name="p6" type="qman:arrayOfShort"/>
+ <xsd:element name="p7" type="qman:arrayOfString"/>
+ <xsd:element name="p8" type="qman:arrayOfURI"/>
+ <xsd:element name="p9" type="qman:arrayOfDate"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:complexType name="echoWithArraysResponse">
+ <xsd:sequence>
+ <xsd:element name="result" type="qman:result"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:element
+ name="echoWithSimpleTypeArraysRequest" type="qman:echoWithSimpleTypeArraysRequest"/>
+ <xsd:element
+ name="echoWithSimpleTypeArraysResponse" type="qman:echoWithSimpleTypeArraysResponse"/>
+ <xsd:complexType name="arrayOfLong">
+ <xsd:sequence>
+ <xsd:element name="entry" type="xsd:long"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:complexType name="arrayOfBoolean">
+ <xsd:sequence>
+ <xsd:element name="entry" type="xsd:boolean"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:complexType name="arrayOfDouble">
+ <xsd:sequence>
+ <xsd:element name="entry" type="xsd:double"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:complexType name="arrayOfFloat">
+ <xsd:sequence>
+ <xsd:element name="entry" type="xsd:float"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:complexType name="arrayOfInt">
+ <xsd:sequence>
+ <xsd:element name="entry" type="xsd:integer"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:complexType name="arrayOfShort">
+ <xsd:sequence>
+ <xsd:element name="entry" type="xsd:short"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:complexType name="echoWithSimpleTypeArraysRequest">
+ <xsd:sequence>
+ <xsd:element name="p1" type="qman:arrayOfLong"/>
+ <xsd:element name="p2" type="qman:arrayOfBoolean"/>
+ <xsd:element name="p3" type="qman:arrayOfDouble"/>
+ <xsd:element name="p4" type="qman:arrayOfFloat"/>
+ <xsd:element name="p5" type="qman:arrayOfInt"/>
+ <xsd:element name="p6" type="qman:arrayOfShort"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:complexType name="echoWithSimpleTypeArraysResponse">
+ <xsd:sequence>
+ <xsd:element name="result" type="qman:result"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:element name="echoWithByteArrayRequest" type="qman:echoWithByteArrayRequest"/>
+ <xsd:element
+ name="echoWithByteArrayResponse" type="qman:echoWithByteArrayResponse"/>
+ <xsd:complexType name="arrayOfByte">
+ <xsd:sequence>
+ <xsd:element name="entry" type=""/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:complexType name="echoWithByteArrayRequest">
+ <xsd:sequence>
+ <xsd:element name="p1" type="qman:arrayOfByte"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:complexType name="echoWithByteArrayResponse">
+ <xsd:sequence>
+ <xsd:element name="result" type="qman:result"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:element
+ name="voidWithoutArgumentsRequest" type="qman:voidWithoutArgumentsRequest"/>
+ <xsd:element
+ name="voidWithoutArgumentsResponse" type="qman:voidWithoutArgumentsResponse"/>
+ <xsd:complexType name="voidWithoutArgumentsRequest">
+ <xsd:sequence/>
+ </xsd:complexType>
+ <xsd:complexType name="voidWithoutArgumentsResponse">
+ <xsd:sequence>
+ <xsd:element name="result" type="qman:result"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:element name="throwsExceptionRequest" type="qman:throwsExceptionRequest"/>
+ <xsd:element name="throwsExceptionResponse" type="qman:throwsExceptionResponse"/>
+ <xsd:complexType name="throwsExceptionRequest">
+ <xsd:sequence/>
+ </xsd:complexType>
+ <xsd:complexType name="throwsExceptionResponse">
+ <xsd:sequence>
+ <xsd:element name="result" type="qman:result"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:element name="echoWithUUIDRequest" type="qman:echoWithUUIDRequest"/>
+ <xsd:element name="echoWithUUIDResponse" type="qman:echoWithUUIDResponse"/>
+ <xsd:complexType name="echoWithUUIDRequest">
+ <xsd:sequence>
+ <xsd:element name="p1" type="qman:uuid"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:complexType name="echoWithUUIDResponse">
+ <xsd:sequence>
+ <xsd:element name="result" type="qman:result"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:element name="echoWithMapRequest" type="qman:echoWithMapRequest"/>
+ <xsd:element name="echoWithMapResponse" type="qman:echoWithMapResponse"/>
+ <xsd:complexType name="echoWithMapRequest">
+ <xsd:sequence>
+ <xsd:element name="p1" type="qman:map"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:complexType name="echoWithMapResponse">
+ <xsd:sequence>
+ <xsd:element name="result" type="qman:result"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:schema>
+ <xsd:schema attributeFormDefault="unqualified"
+ elementFormDefault="qualified"
+ targetNamespace="http://docs.oasis-open.org/wsrf/bf-2"
+ xmlns="http://www.w3.org/2001/XMLSchema"
+ xmlns:wsa="http://www.w3.org/2005/08/addressing"
+ xmlns:wsrf-bf="http://docs.oasis-open.org/wsrf/bf-2"
+ xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <xsd:import namespace="http://www.w3.org/2005/08/addressing"/>
+ <xsd:import namespace="http://www.w3.org/XML/1998/namespace">
+ <xsd:annotation>
+ <xsd:documentation>
+ Get access to the xml: attribute groups for xml:lang as declared on 'schema'
+ and 'documentation' below
+ </xsd:documentation>
+ </xsd:annotation>
+ </xsd:import>
+ <xsd:element name="BaseFault" type="wsrf-bf:BaseFaultType"/>
+ <xsd:complexType name="BaseFaultType">
+ <xsd:sequence>
+ <xsd:any maxOccurs="unbounded"
+ minOccurs="0"
+ namespace="##other" processContents="lax"/>
+ <xsd:element maxOccurs="1"
+ minOccurs="1" name="Timestamp" type="xsd:dateTime"/>
+ <xsd:element maxOccurs="1"
+ minOccurs="0" name="Originator" type="wsa:EndpointReferenceType"/>
+ <xsd:element maxOccurs="1"
+ minOccurs="0" name="ErrorCode">
+ <xsd:complexType>
+ <xsd:complexContent mixed="true">
+ <xsd:extension base="xsd:anyType">
+ <xsd:attribute
+ name="dialect"
+ type="xsd:anyURI" use="required"/>
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element maxOccurs="unbounded"
+ minOccurs="0" name="Description">
+ <xsd:complexType>
+ <xsd:simpleContent>
+ <xsd:extension base="xsd:string">
+ <xsd:attribute
+ ref="xml:lang" use="optional"/>
+ </xsd:extension>
+ </xsd:simpleContent>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element maxOccurs="1"
+ minOccurs="0" name="FaultCause">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:any maxOccurs="1"
+ minOccurs="1"
+ namespace="##other" processContents="lax"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:sequence>
+ <xsd:anyAttribute namespace="##other" processContents="lax"/>
+ </xsd:complexType>
+ </xsd:schema>
+ <xs:schema
+ targetNamespace="http://www.w3.org/XML/1998/namespace"
+ xml:lang="en" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+ <xs:attribute name="lang" type="xs:language"/>
+ <xs:attribute default="preserve" name="space">
+ <xs:simpleType>
+ <xs:restriction base="xs:NCName">
+ <xs:enumeration value="default"/>
+ <xs:enumeration value="preserve"/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:attribute>
+ <xs:attribute name="base" type="xs:anyURI"/>
+ <xs:attributeGroup name="specialAttrs">
+ <xs:attribute ref="xml:base"/>
+ <xs:attribute ref="xml:lang"/>
+ <xs:attribute ref="xml:space"/>
+ </xs:attributeGroup>
+ </xs:schema>
+ </wsdl:types>
+ <wsdl:message name="GetMetadataMsg">
+ <wsdl:part element="wsx:GetMetadata" name="GetMetadataMsg"/>
+ </wsdl:message>
+ <wsdl:message name="GetMetadataResponseMsg">
+ <wsdl:part element="wsx:Metadata" name="GetMetadataResponseMsg"/>
+ </wsdl:message>
+ <wsdl:message name="DestroyRequest">
+ <wsdl:part element="wsrf-rl:Destroy" name="DestroyRequest"/>
+ </wsdl:message>
+ <wsdl:message name="DestroyResponse">
+ <wsdl:part element="wsrf-rl:DestroyResponse" name="DestroyResponse"/>
+ </wsdl:message>
+ <wsdl:message name="ResourceNotDestroyedFault">
+ <wsdl:part
+ element="wsrf-rl:ResourceNotDestroyedFault" name="ResourceNotDestroyedFault"/>
+ </wsdl:message>
+ <wsdl:message name="ResourceUnknownFault">
+ <wsdl:part element="wsrf-r:ResourceUnknownFault" name="ResourceUnknownFault"/>
+ </wsdl:message>
+ <wsdl:message name="ResourceUnavailableFault">
+ <wsdl:part
+ element="wsrf-r:ResourceUnavailableFault" name="ResourceUnavailableFault"/>
+ </wsdl:message>
+ <wsdl:message name="SetTerminationTimeRequest">
+ <wsdl:part element="wsrf-rl:SetTerminationTime" name="SetTerminationTimeRequest"/>
+ </wsdl:message>
+ <wsdl:message name="SetTerminationTimeResponse">
+ <wsdl:part
+ element="wsrf-rl:SetTerminationTimeResponse" name="SetTerminationTimeResponse"/>
+ </wsdl:message>
+ <wsdl:message name="UnableToSetTerminationTimeFault">
+ <wsdl:part
+ element="wsrf-rl:UnableToSetTerminationTimeFault" name="UnableToSetTerminationTimeFault"/>
+ </wsdl:message>
+ <wsdl:message name="TerminationTimeChangeRejectedFault">
+ <wsdl:part
+ element="wsrf-rl:TerminationTimeChangeRejectedFault" name="TerminationTimeChangeRejectedFault"/>
+ </wsdl:message>
+ <wsdl:message name="GetResourcePropertyDocumentRequest">
+ <wsdl:part
+ element="wsrf-rp:GetResourcePropertyDocument" name="GetResourcePropertyDocumentRequest"/>
+ </wsdl:message>
+ <wsdl:message name="GetResourcePropertyDocumentResponse">
+ <wsdl:part
+ element="wsrf-rp:GetResourcePropertyDocumentResponse" name="GetResourcePropertyDocumentResponse"/>
+ </wsdl:message>
+ <wsdl:message name="GetResourcePropertyRequest">
+ <wsdl:part element="wsrf-rp:GetResourceProperty" name="GetResourcePropertyRequest"/>
+ </wsdl:message>
+ <wsdl:message name="GetResourcePropertyResponse">
+ <wsdl:part
+ element="wsrf-rp:GetResourcePropertyResponse" name="GetResourcePropertyResponse"/>
+ </wsdl:message>
+ <wsdl:message name="InvalidResourcePropertyQNameFault">
+ <wsdl:part
+ element="wsrf-rp:InvalidResourcePropertyQNameFault" name="InvalidResourcePropertyQNameFault"/>
+ </wsdl:message>
+ <wsdl:message name="GetMultipleResourcePropertiesRequest">
+ <wsdl:part
+ element="wsrf-rp:GetMultipleResourceProperties" name="GetMultipleResourcePropertiesRequest"/>
+ </wsdl:message>
+ <wsdl:message name="GetMultipleResourcePropertiesResponse">
+ <wsdl:part
+ element="wsrf-rp:GetMultipleResourcePropertiesResponse" name="GetMultipleResourcePropertiesResponse"/>
+ </wsdl:message>
+ <wsdl:message name="QueryResourcePropertiesRequest">
+ <wsdl:part
+ element="wsrf-rp:QueryResourceProperties" name="QueryResourcePropertiesRequest"/>
+ </wsdl:message>
+ <wsdl:message name="QueryResourcePropertiesResponse">
+ <wsdl:part
+ element="wsrf-rp:QueryResourcePropertiesResponse" name="QueryResourcePropertiesResponse"/>
+ </wsdl:message>
+ <wsdl:message name="UnknownQueryExpressionDialectFault">
+ <wsdl:part
+ element="wsrf-rp:UnknownQueryExpressionDialectFault" name="UnknownQueryExpressionDialectFault"/>
+ </wsdl:message>
+ <wsdl:message name="InvalidQueryExpressionFault">
+ <wsdl:part
+ element="wsrf-rp:InvalidQueryExpressionFault" name="InvalidQueryExpressionFault"/>
+ </wsdl:message>
+ <wsdl:message name="QueryEvaluationErrorFault">
+ <wsdl:part
+ element="wsrf-rp:QueryEvaluationErrorFault" name="QueryEvaluationErrorFault"/>
+ </wsdl:message>
+ <wsdl:message name="SetResourcePropertiesRequest">
+ <wsdl:part
+ element="wsrf-rp:SetResourceProperties" name="SetResourcePropertiesRequest"/>
+ </wsdl:message>
+ <wsdl:message name="SetResourcePropertiesResponse">
+ <wsdl:part
+ element="wsrf-rp:SetResourcePropertiesResponse" name="SetResourcePropertiesResponse"/>
+ </wsdl:message>
+ <wsdl:message name="InvalidModificationFault">
+ <wsdl:part
+ element="wsrf-rp:InvalidModificationFault" name="InvalidModificationFault"/>
+ </wsdl:message>
+ <wsdl:message name="UnableToModifyResourcePropertyFault">
+ <wsdl:part
+ element="wsrf-rp:UnableToModifyResourcePropertyFault" name="UnableToModifyResourcePropertyFault"/>
+ </wsdl:message>
+ <wsdl:message name="SetResourcePropertyRequestFailedFault">
+ <wsdl:part
+ element="wsrf-rp:SetResourcePropertyRequestFailedFault" name="SetResourcePropertyRequestFailedFault"/>
+ </wsdl:message>
+ <wsdl:portType name="QManWsResourcePortType"
+ wsrf-rp:ResourceProperties="qman:QManWsResourceProperties"
+ wsrmd:Descriptor="QManWsResourceMetadata" wsrmd:DescriptorLocation="QManWsResource.rmd">
+ <wsdl:operation name="GetMetadata">
+ <wsdl:input message="qman:GetMetadataMsg"
+ name="GetMetadataMsg" wsa:Action="http://schemas.xmlsoap.org/ws/2004/09/mex/GetMetadata"/>
+ <wsdl:output
+ message="qman:GetMetadataResponseMsg"
+ name="GetMetadataResponseMsg" wsa:Action="http://schemas.xmlsoap.org/ws/2004/09/mex/GetMetadataResponse"/>
+ </wsdl:operation>
+ <wsdl:operation name="Destroy">
+ <wsdl:input message="qman:DestroyRequest"
+ name="DestroyRequest" wsa:Action="http://docs.oasis-open.org/wsrf/rlw-2/ImmediateResourceTermination/DestroyRequest"/>
+ <wsdl:output message="qman:DestroyResponse"
+ name="DestroyResponse" wsa:Action="http://docs.oasis-open.org/wsrf/rlw-2/ImmediateResourceTermination/DestroyResponse"/>
+ <wsdl:fault
+ message="qman:ResourceNotDestroyedFault" name="ResourceNotDestroyedFault"/>
+ <wsdl:fault
+ message="qman:ResourceUnknownFault" name="ResourceUnknownFault"/>
+ <wsdl:fault
+ message="qman:ResourceUnavailableFault" name="ResourceUnavailableFault"/>
+ </wsdl:operation>
+ <wsdl:operation name="SetTerminationTime">
+ <wsdl:input
+ message="qman:SetTerminationTimeRequest"
+ name="SetTerminationTimeRequest" wsa:Action="http://docs.oasis-open.org/wsrf/rlw-2/ScheduledResourceTermination/SetTerminationTimeRequest"/>
+ <wsdl:output
+ message="qman:SetTerminationTimeResponse"
+ name="SetTerminationTimeResponse" wsa:Action="http://docs.oasis-open.org/wsrf/rlw-2/ScheduledResourceTermination/SetTerminationTimeResponse"/>
+ <wsdl:fault
+ message="qman:UnableToSetTerminationTimeFault" name="UnableToSetTerminationTimeFault"/>
+ <wsdl:fault
+ message="qman:ResourceUnknownFault" name="ResourceUnknownFault"/>
+ <wsdl:fault
+ message="qman:ResourceUnavailableFault" name="ResourceUnavailableFault"/>
+ <wsdl:fault
+ message="qman:TerminationTimeChangeRejectedFault" name="TerminationTimeChangeRejectedFault"/>
+ </wsdl:operation>
+ <wsdl:operation name="GetResourcePropertyDocument">
+ <wsdl:input
+ message="qman:GetResourcePropertyDocumentRequest"
+ name="GetResourcePropertyDocumentRequest" wsa:Action="http://docs.oasis-open.org/wsrf/rpw-2/GetResourcePropertyDocument/GetResourcePropertyDocumentRequest"/>
+ <wsdl:output
+ message="qman:GetResourcePropertyDocumentResponse"
+ name="GetResourcePropertyDocumentResponse" wsa:Action="http://docs.oasis-open.org/wsrf/rpw-2/GetResourcePropertyDocument/GetResourcePropertyDocumentResponse"/>
+ <wsdl:fault
+ message="qman:ResourceUnknownFault" name="ResourceUnknownFault"/>
+ <wsdl:fault
+ message="qman:ResourceUnavailableFault" name="ResourceUnavailableFault"/>
+ </wsdl:operation>
+ <wsdl:operation name="GetResourceProperty">
+ <wsdl:input
+ message="qman:GetResourcePropertyRequest"
+ name="GetResourcePropertyRequest" wsa:Action="http://docs.oasis-open.org/wsrf/rpw-2/GetResourceProperty/GetResourcePropertyRequest"/>
+ <wsdl:output
+ message="qman:GetResourcePropertyResponse"
+ name="GetResourcePropertyResponse" wsa:Action="http://docs.oasis-open.org/wsrf/rpw-2/GetResourceProperty/GetResourcePropertyResponse"/>
+ <wsdl:fault
+ message="qman:ResourceUnknownFault" name="ResourceUnknownFault"/>
+ <wsdl:fault
+ message="qman:ResourceUnavailableFault" name="ResourceUnavailableFault"/>
+ <wsdl:fault
+ message="qman:InvalidResourcePropertyQNameFault" name="InvalidResourcePropertyQNameFault"/>
+ </wsdl:operation>
+ <wsdl:operation name="GetMultipleResourceProperties">
+ <wsdl:input
+ message="qman:GetMultipleResourcePropertiesRequest"
+ name="GetMultipleResourcePropertiesRequest" wsa:Action="http://docs.oasis-open.org/wsrf/rpw-2/GetMultipleResourceProperties/GetMultipleResourcePropertiesRequest"/>
+ <wsdl:output
+ message="qman:GetMultipleResourcePropertiesResponse"
+ name="GetMultipleResourcePropertiesResponse" wsa:Action="http://docs.oasis-open.org/wsrf/rpw-2/GetMultipleResourceProperties/GetMultipleResourcePropertiesResponse"/>
+ <wsdl:fault
+ message="qman:ResourceUnknownFault" name="ResourceUnknownFault"/>
+ <wsdl:fault
+ message="qman:ResourceUnavailableFault" name="ResourceUnavailableFault"/>
+ <wsdl:fault
+ message="qman:InvalidResourcePropertyQNameFault" name="InvalidResourcePropertyQNameFault"/>
+ </wsdl:operation>
+ <wsdl:operation name="QueryResourceProperties">
+ <wsdl:input
+ message="qman:QueryResourcePropertiesRequest"
+ name="QueryResourcePropertiesRequest" wsa:Action="http://docs.oasis-open.org/wsrf/rpw-2/QueryResourceProperties/QueryResourcePropertiesRequest"/>
+ <wsdl:output
+ message="qman:QueryResourcePropertiesResponse"
+ name="QueryResourcePropertiesResponse" wsa:Action="http://docs.oasis-open.org/wsrf/rpw-2/QueryResourceProperties/QueryResourcePropertiesResponse"/>
+ <wsdl:fault
+ message="qman:ResourceUnknownFault" name="ResourceUnknownFault"/>
+ <wsdl:fault
+ message="qman:ResourceUnavailableFault" name="ResourceUnavailableFault"/>
+ <wsdl:fault
+ message="qman:UnknownQueryExpressionDialectFault" name="UnknownQueryExpressionDialectFault"/>
+ <wsdl:fault
+ message="qman:InvalidQueryExpressionFault" name="InvalidQueryExpressionFault"/>
+ <wsdl:fault
+ message="qman:QueryEvaluationErrorFault" name="QueryEvaluationErrorFault"/>
+ </wsdl:operation>
+ <wsdl:operation name="SetResourceProperties">
+ <wsdl:input
+ message="qman:SetResourcePropertiesRequest"
+ name="SetResourcePropertiesRequest" wsa:Action="http://docs.oasis-open.org/wsrf/rpw-2/SetResourceProperties/SetResourcePropertiesRequest"/>
+ <wsdl:output
+ message="qman:SetResourcePropertiesResponse"
+ name="SetResourcePropertiesResponse" wsa:Action="http://docs.oasis-open.org/wsrf/rpw-2/SetResourceProperties/SetResourcePropertiesResponse"/>
+ <wsdl:fault
+ message="qman:ResourceUnknownFault" name="ResourceUnknownFault"/>
+ <wsdl:fault
+ message="qman:ResourceUnavailableFault" name="ResourceUnavailableFault"/>
+ <wsdl:fault
+ message="qman:InvalidModificationFault" name="InvalidModificationFault"/>
+ <wsdl:fault
+ message="qman:UnableToModifyResourcePropertyFault" name="UnableToModifyResourcePropertyFault"/>
+ <wsdl:fault
+ message="qman:InvalidResourcePropertyQNameFault" name="InvalidResourcePropertyQNameFault"/>
+ <wsdl:fault
+ message="qman:SetResourcePropertyRequestFailedFault" name="SetResourcePropertyRequestFailedFault"/>
+ </wsdl:operation>
+ <wsdl:operation name="echoWithSimpleTypes">
+ <wsdl:input
+ message="qman:echoWithSimpleTypesRequestMessage"
+ name="echoWithSimpleTypesRequest" wsa:action="http://amqp.apache.org/qpid/management/qman/echoWithSimpleTypes"/>
+ <wsdl:output
+ message="qman:echoWithSimpleTypesResponseMessage"
+ name="echoWithSimpleTypesResponse" wsa:action="http://amqp.apache.org/qpid/management/qman/echoWithSimpleTypesResponse"/>
+ </wsdl:operation>
+ <wsdl:operation name="echoWithArrays">
+ <wsdl:input
+ message="qman:echoWithArraysRequestMessage"
+ name="echoWithArraysRequest" wsa:action="http://amqp.apache.org/qpid/management/qman/echoWithArrays"/>
+ <wsdl:output
+ message="qman:echoWithArraysResponseMessage"
+ name="echoWithArraysResponse" wsa:action="http://amqp.apache.org/qpid/management/qman/echoWithArraysResponse"/>
+ </wsdl:operation>
+ <wsdl:operation name="echoWithSimpleTypeArrays">
+ <wsdl:input
+ message="qman:echoWithSimpleTypeArraysRequestMessage"
+ name="echoWithSimpleTypeArraysRequest" wsa:action="http://amqp.apache.org/qpid/management/qman/echoWithSimpleTypeArrays"/>
+ <wsdl:output
+ message="qman:echoWithSimpleTypeArraysResponseMessage"
+ name="echoWithSimpleTypeArraysResponse" wsa:action="http://amqp.apache.org/qpid/management/qman/echoWithSimpleTypeArraysResponse"/>
+ </wsdl:operation>
+ <wsdl:operation name="echoWithByteArray">
+ <wsdl:input
+ message="qman:echoWithByteArrayRequestMessage"
+ name="echoWithByteArrayRequest" wsa:action="http://amqp.apache.org/qpid/management/qman/echoWithByteArray"/>
+ <wsdl:output
+ message="qman:echoWithByteArrayResponseMessage"
+ name="echoWithByteArrayResponse" wsa:action="http://amqp.apache.org/qpid/management/qman/echoWithByteArrayResponse"/>
+ </wsdl:operation>
+ <wsdl:operation name="voidWithoutArguments">
+ <wsdl:input
+ message="qman:voidWithoutArgumentsRequestMessage"
+ name="voidWithoutArgumentsRequest" wsa:action="http://amqp.apache.org/qpid/management/qman/voidWithoutArguments"/>
+ <wsdl:output
+ message="qman:voidWithoutArgumentsResponseMessage"
+ name="voidWithoutArgumentsResponse" wsa:action="http://amqp.apache.org/qpid/management/qman/voidWithoutArgumentsResponse"/>
+ </wsdl:operation>
+ <wsdl:operation name="throwsException">
+ <wsdl:input
+ message="qman:throwsExceptionRequestMessage"
+ name="throwsExceptionRequest" wsa:action="http://amqp.apache.org/qpid/management/qman/throwsException"/>
+ <wsdl:output
+ message="qman:throwsExceptionResponseMessage"
+ name="throwsExceptionResponse" wsa:action="http://amqp.apache.org/qpid/management/qman/throwsExceptionResponse"/>
+ </wsdl:operation>
+ <wsdl:operation name="echoWithUUID">
+ <wsdl:input
+ message="qman:echoWithUUIDRequestMessage"
+ name="echoWithUUIDRequest" wsa:action="http://amqp.apache.org/qpid/management/qman/echoWithUUID"/>
+ <wsdl:output
+ message="qman:echoWithUUIDResponseMessage"
+ name="echoWithUUIDResponse" wsa:action="http://amqp.apache.org/qpid/management/qman/echoWithUUIDResponse"/>
+ </wsdl:operation>
+ <wsdl:operation name="echoWithMap">
+ <wsdl:input
+ message="qman:echoWithMapRequestMessage"
+ name="echoWithMapRequest" wsa:action="http://amqp.apache.org/qpid/management/qman/echoWithMap"/>
+ <wsdl:output
+ message="qman:echoWithMapResponseMessage"
+ name="echoWithMapResponse" wsa:action="http://amqp.apache.org/qpid/management/qman/echoWithMapResponse"/>
+ </wsdl:operation>
+ </wsdl:portType>
+ <wsdl:binding name="QManWsResourceBinding" type="qman:QManWsResourcePortType">
+ <wsdl-soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
+ <wsdl:operation name="GetMetadata">
+ <wsdl-soap:operation soapAction="GetMetadata"/>
+ <wsdl:input>
+ <wsdl-soap:body
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" use="literal"/>
+ </wsdl:input>
+ <wsdl:output>
+ <wsdl-soap:body
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+ <wsdl:operation name="Destroy">
+ <wsdl-soap:operation soapAction="Destroy"/>
+ <wsdl:input name="DestroyRequest">
+ <wsdl-soap:body
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" use="literal"/>
+ </wsdl:input>
+ <wsdl:output name="DestroyResponse">
+ <wsdl-soap:body
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" use="literal"/>
+ </wsdl:output>
+ <wsdl:fault name="ResourceNotDestroyedFault">
+ <wsdl-soap:fault
+ name="ResourceNotDestroyedFault" use="literal"/>
+ </wsdl:fault>
+ <wsdl:fault name="ResourceUnknownFault">
+ <wsdl-soap:fault
+ name="ResourceUnknownFault" use="literal"/>
+ </wsdl:fault>
+ <wsdl:fault name="ResourceUnavailableFault">
+ <wsdl-soap:fault
+ name="ResourceUnavailableFault" use="literal"/>
+ </wsdl:fault>
+ </wsdl:operation>
+ <wsdl:operation name="SetTerminationTime">
+ <wsdl-soap:operation soapAction="SetTerminationTime"/>
+ <wsdl:input name="SetTerminationTimeRequest">
+ <wsdl-soap:body
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" use="literal"/>
+ </wsdl:input>
+ <wsdl:output name="SetTerminationTimeResponse">
+ <wsdl-soap:body
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" use="literal"/>
+ </wsdl:output>
+ <wsdl:fault name="UnableToSetTerminationTimeFault">
+ <wsdl-soap:fault
+ name="UnableToSetTerminationTimeFault" use="literal"/>
+ </wsdl:fault>
+ <wsdl:fault name="ResourceUnknownFault">
+ <wsdl-soap:fault
+ name="ResourceUnknownFault" use="literal"/>
+ </wsdl:fault>
+ <wsdl:fault name="ResourceUnavailableFault">
+ <wsdl-soap:fault
+ name="ResourceUnavailableFault" use="literal"/>
+ </wsdl:fault>
+ <wsdl:fault name="TerminationTimeChangeRejectedFault">
+ <wsdl-soap:fault
+ name="TerminationTimeChangeRejectedFault" use="literal"/>
+ </wsdl:fault>
+ </wsdl:operation>
+ <wsdl:operation name="GetResourcePropertyDocument">
+ <wsdl-soap:operation soapAction="GetResourcePropertyDocument"/>
+ <wsdl:input name="GetResourcePropertyDocumentRequest">
+ <wsdl-soap:body
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" use="literal"/>
+ </wsdl:input>
+ <wsdl:output name="GetResourcePropertyDocumentResponse">
+ <wsdl-soap:body
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" use="literal"/>
+ </wsdl:output>
+ <wsdl:fault name="ResourceUnknownFault">
+ <wsdl-soap:fault
+ name="ResourceUnknownFault" use="literal"/>
+ </wsdl:fault>
+ <wsdl:fault name="ResourceUnavailableFault">
+ <wsdl-soap:fault
+ name="ResourceUnavailableFault" use="literal"/>
+ </wsdl:fault>
+ </wsdl:operation>
+ <wsdl:operation name="GetResourceProperty">
+ <wsdl-soap:operation soapAction="GetResourceProperty"/>
+ <wsdl:input name="GetResourcePropertyRequest">
+ <wsdl-soap:body
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" use="literal"/>
+ </wsdl:input>
+ <wsdl:output name="GetResourcePropertyResponse">
+ <wsdl-soap:body
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" use="literal"/>
+ </wsdl:output>
+ <wsdl:fault name="ResourceUnknownFault">
+ <wsdl-soap:fault
+ name="ResourceUnknownFault" use="literal"/>
+ </wsdl:fault>
+ <wsdl:fault name="ResourceUnavailableFault">
+ <wsdl-soap:fault
+ name="ResourceUnavailableFault" use="literal"/>
+ </wsdl:fault>
+ <wsdl:fault name="InvalidResourcePropertyQNameFault">
+ <wsdl-soap:fault
+ name="InvalidResourcePropertyQNameFault" use="literal"/>
+ </wsdl:fault>
+ </wsdl:operation>
+ <wsdl:operation name="GetMultipleResourceProperties">
+ <wsdl-soap:operation soapAction="GetMultipleResourceProperties"/>
+ <wsdl:input name="GetMultipleResourcePropertiesRequest">
+ <wsdl-soap:body
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" use="literal"/>
+ </wsdl:input>
+ <wsdl:output name="GetMultipleResourcePropertiesResponse">
+ <wsdl-soap:body
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" use="literal"/>
+ </wsdl:output>
+ <wsdl:fault name="ResourceUnknownFault">
+ <wsdl-soap:fault
+ name="ResourceUnknownFault" use="literal"/>
+ </wsdl:fault>
+ <wsdl:fault name="ResourceUnavailableFault">
+ <wsdl-soap:fault
+ name="ResourceUnavailableFault" use="literal"/>
+ </wsdl:fault>
+ <wsdl:fault name="InvalidResourcePropertyQNameFault">
+ <wsdl-soap:fault
+ name="InvalidResourcePropertyQNameFault" use="literal"/>
+ </wsdl:fault>
+ </wsdl:operation>
+ <wsdl:operation name="QueryResourceProperties">
+ <wsdl-soap:operation soapAction="QueryResourceProperties"/>
+ <wsdl:input name="QueryResourcePropertiesRequest">
+ <wsdl-soap:body
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" use="literal"/>
+ </wsdl:input>
+ <wsdl:output name="QueryResourcePropertiesResponse">
+ <wsdl-soap:body
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" use="literal"/>
+ </wsdl:output>
+ <wsdl:fault name="ResourceUnknownFault">
+ <wsdl-soap:fault
+ name="ResourceUnknownFault" use="literal"/>
+ </wsdl:fault>
+ <wsdl:fault name="ResourceUnavailableFault">
+ <wsdl-soap:fault
+ name="ResourceUnavailableFault" use="literal"/>
+ </wsdl:fault>
+ <wsdl:fault name="UnknownQueryExpressionDialectFault">
+ <wsdl-soap:fault
+ name="UnknownQueryExpressionDialectFault" use="literal"/>
+ </wsdl:fault>
+ <wsdl:fault name="InvalidQueryExpressionFault">
+ <wsdl-soap:fault
+ name="InvalidQueryExpressionFault" use="literal"/>
+ </wsdl:fault>
+ <wsdl:fault name="QueryEvaluationErrorFault">
+ <wsdl-soap:fault
+ name="QueryEvaluationErrorFault" use="literal"/>
+ </wsdl:fault>
+ </wsdl:operation>
+ <wsdl:operation name="SetResourceProperties">
+ <wsdl-soap:operation soapAction="http://oasis.org/SetResourceProperties"/>
+ <wsdl:input name="SetResourcePropertiesRequest">
+ <wsdl-soap:body
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" use="literal"/>
+ </wsdl:input>
+ <wsdl:output name="SetResourcePropertiesResponse">
+ <wsdl-soap:body
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" use="literal"/>
+ </wsdl:output>
+ <wsdl:fault name="ResourceUnknownFault">
+ <wsdl-soap:fault
+ name="ResourceUnknownFault" use="literal"/>
+ </wsdl:fault>
+ <wsdl:fault name="ResourceUnavailableFault">
+ <wsdl-soap:fault
+ name="ResourceUnavailableFault" use="literal"/>
+ </wsdl:fault>
+ <wsdl:fault name="InvalidModificationFault">
+ <wsdl-soap:fault
+ name="InvalidModificationFault" use="literal"/>
+ </wsdl:fault>
+ <wsdl:fault name="UnableToModifyResourcePropertyFault">
+ <wsdl-soap:fault
+ name="UnableToModifyResourcePropertyFault" use="literal"/>
+ </wsdl:fault>
+ <wsdl:fault name="InvalidResourcePropertyQNameFault">
+ <wsdl-soap:fault
+ name="InvalidResourcePropertyQNameFault" use="literal"/>
+ </wsdl:fault>
+ <wsdl:fault name="SetResourcePropertyRequestFailedFault">
+ <wsdl-soap:fault
+ name="SetResourcePropertyRequestFailedFault" use="literal"/>
+ </wsdl:fault>
+ </wsdl:operation>
+ <wsdl:operation name="GetMetadata">
+ <wsdl-soap:operation soapAction="http://ws.apache.org/muse/test/wsrf/GetMetadata"/>
+ <wsdl:input name="GetMetadataMsg">
+ <wsdl-soap:body
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" use="literal"/>
+ </wsdl:input>
+ <wsdl:output name="GetMetadataResponseMsg">
+ <wsdl-soap:body
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+ <wsdl:operation name="echoWithSimpleTypes">
+ <wsdl-soap:operation soapAction="http://amqp.apache.org/qpid/management/qman/echoWithSimpleTypes"/>
+ <wsdl:input>
+ <wsdl-soap:body use="literal"/>
+ </wsdl:input>
+ <wsdl:output>
+ <wsdl-soap:body use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+ <wsdl:operation name="echoWithArrays">
+ <wsdl-soap:operation soapAction="http://amqp.apache.org/qpid/management/qman/echoWithArrays"/>
+ <wsdl:input>
+ <wsdl-soap:body use="literal"/>
+ </wsdl:input>
+ <wsdl:output>
+ <wsdl-soap:body use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+ <wsdl:operation name="echoWithSimpleTypeArrays">
+ <wsdl-soap:operation soapAction="http://amqp.apache.org/qpid/management/qman/echoWithSimpleTypeArrays"/>
+ <wsdl:input>
+ <wsdl-soap:body use="literal"/>
+ </wsdl:input>
+ <wsdl:output>
+ <wsdl-soap:body use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+ <wsdl:operation name="echoWithByteArray">
+ <wsdl-soap:operation soapAction="http://amqp.apache.org/qpid/management/qman/echoWithByteArray"/>
+ <wsdl:input>
+ <wsdl-soap:body use="literal"/>
+ </wsdl:input>
+ <wsdl:output>
+ <wsdl-soap:body use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+ <wsdl:operation name="voidWithoutArguments">
+ <wsdl-soap:operation soapAction="http://amqp.apache.org/qpid/management/qman/voidWithoutArguments"/>
+ <wsdl:input>
+ <wsdl-soap:body use="literal"/>
+ </wsdl:input>
+ <wsdl:output>
+ <wsdl-soap:body use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+ <wsdl:operation name="throwsException">
+ <wsdl-soap:operation soapAction="http://amqp.apache.org/qpid/management/qman/throwsException"/>
+ <wsdl:input>
+ <wsdl-soap:body use="literal"/>
+ </wsdl:input>
+ <wsdl:output>
+ <wsdl-soap:body use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+ <wsdl:operation name="echoWithUUID">
+ <wsdl-soap:operation soapAction="http://amqp.apache.org/qpid/management/qman/echoWithUUID"/>
+ <wsdl:input>
+ <wsdl-soap:body use="literal"/>
+ </wsdl:input>
+ <wsdl:output>
+ <wsdl-soap:body use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+ <wsdl:operation name="echoWithMap">
+ <wsdl-soap:operation soapAction="http://amqp.apache.org/qpid/management/qman/echoWithMap"/>
+ <wsdl:input>
+ <wsdl-soap:body use="literal"/>
+ </wsdl:input>
+ <wsdl:output>
+ <wsdl-soap:body use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+ </wsdl:binding>
+ <wsdl:service name="QManWsResourceService">
+ <wsdl:port binding="qman:QManWsResourceBinding" name="QManWsResourcePort">
+ <wsdl-soap:address location="http://romagazzarini:8080/qman/services/QManWsResource"/>
+ </wsdl:port>
+ </wsdl:service>
+ <message name="echoWithSimpleTypesRequestMessage">
+ <wsdl:part
+ element="qman:echoWithSimpleTypesRequest" name="echoWithSimpleTypesRequest"/>
+ </message>
+ <wsdl:message name="echoWithSimpleTypesResponseMessage">
+ <wsdl:part
+ element="qman:echoWithSimpleTypesResponse" name="echoWithSimpleTypesResponse"/>
+ </wsdl:message>
+ <message name="echoWithArraysRequestMessage">
+ <wsdl:part element="qman:echoWithArraysRequest" name="echoWithArraysRequest"/>
+ </message>
+ <wsdl:message name="echoWithArraysResponseMessage">
+ <wsdl:part element="qman:echoWithArraysResponse" name="echoWithArraysResponse"/>
+ </wsdl:message>
+ <message name="echoWithSimpleTypeArraysRequestMessage">
+ <wsdl:part
+ element="qman:echoWithSimpleTypeArraysRequest" name="echoWithSimpleTypeArraysRequest"/>
+ </message>
+ <wsdl:message name="echoWithSimpleTypeArraysResponseMessage">
+ <wsdl:part
+ element="qman:echoWithSimpleTypeArraysResponse" name="echoWithSimpleTypeArraysResponse"/>
+ </wsdl:message>
+ <message name="echoWithByteArrayRequestMessage">
+ <wsdl:part
+ element="qman:echoWithByteArrayRequest" name="echoWithByteArrayRequest"/>
+ </message>
+ <wsdl:message name="echoWithByteArrayResponseMessage">
+ <wsdl:part
+ element="qman:echoWithByteArrayResponse" name="echoWithByteArrayResponse"/>
+ </wsdl:message>
+ <message name="voidWithoutArgumentsRequestMessage">
+ <wsdl:part
+ element="qman:voidWithoutArgumentsRequest" name="voidWithoutArgumentsRequest"/>
+ </message>
+ <wsdl:message name="voidWithoutArgumentsResponseMessage">
+ <wsdl:part
+ element="qman:voidWithoutArgumentsResponse" name="voidWithoutArgumentsResponse"/>
+ </wsdl:message>
+ <message name="throwsExceptionRequestMessage">
+ <wsdl:part element="qman:throwsExceptionRequest" name="throwsExceptionRequest"/>
+ </message>
+ <wsdl:message name="throwsExceptionResponseMessage">
+ <wsdl:part
+ element="qman:throwsExceptionResponse" name="throwsExceptionResponse"/>
+ </wsdl:message>
+ <message name="echoWithUUIDRequestMessage">
+ <wsdl:part element="qman:echoWithUUIDRequest" name="echoWithUUIDRequest"/>
+ </message>
+ <wsdl:message name="echoWithUUIDResponseMessage">
+ <wsdl:part element="qman:echoWithUUIDResponse" name="echoWithUUIDResponse"/>
+ </wsdl:message>
+ <message name="echoWithMapRequestMessage">
+ <wsdl:part element="qman:echoWithMapRequest" name="echoWithMapRequest"/>
+ </message>
+ <wsdl:message name="echoWithMapResponseMessage">
+ <wsdl:part element="qman:echoWithMapResponse" name="echoWithMapResponse"/>
+ </wsdl:message>
+ </wsdl:definitions>
+ </wsx:MetadataSection>
+ </wsx:Metadata>
+ </soap:Body>
+</soap:Envelope> \ No newline at end of file
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/README.txt b/qpid/java/management/client/src/example/README.txt
new file mode 100644
index 0000000000..5365a416e5
--- /dev/null
+++ b/qpid/java/management/client/src/example/README.txt
@@ -0,0 +1,69 @@
+*** QMan WS-DM examples ***
+
+1) DESCRIPTION
+This set of examples shows QMan WS-DM interface capabilities.
+Each example is articulated in the following way.
+First the name of the example class with a brief description about that is printed out. For example :
+
+ GetWSDLMetadataExample
+-------------------------------------------------------------------
+
+This example shows the usage of WS-DM
+GetResourcePropertyRequest / Response on a
+Group service.
+The target resource is the WS-DM Adapter itself
+and the requested property is "ws-rp:Entry".
+WS-DM Adapter is a special WS-Resource (is a Group)
+that acts as the main entry point for retrieving
+all other managed resources.
+So clients that want to deal with QMan WS-Resources
+must first get resource identifiers sending
+a GetResourcePropertyRequest to WS-DM Adapter
+with "ws-rp:Entry" as target target property.
+
+-------------------------------------------------------------------
+
+Type enter to proceed.
+
+When you're ready type enter to proceed. Now the example runs and all the exchanged
+SOAP messages are printed out on the screen.
+If you want, we shipped (under sample_messages folder) several files containing those messages.
+
+A general note concerning examples...they are all written using java language so what you see is the
+"java" usage of WS-DM client API.
+The most important thing that you should keep in mind is that what is expected (on QMan side) is a SOAP WS-DM
+compliant message so on top of that you don't need to use those java API but feel free to produce those messages
+in your preferred way (by hand or using another programming language).
+
+Another thing : the examples contain a lot of code duplication because each of them is took as independent as possible.
+The general idea is that you open an example source file and in the executeExample(...) method you should have a quick
+idea of how things are working.
+Also, as mentioned before, we provided, under the sample_messages folder, the messages that are part of each example conversation.
+Remember : these messages are important, not the way / language you use to produce them.
+
+2) HOW TO RUN
+
+2.1) Java
+You need JDK 1.5 or higher in order to run and / or compile the examples.
+
+2.2) Dependencies
+You need to set / update the CLASSPATH environment variable with libraries found under $QMAN_HOME/app/qman/WEB-INF/lib.
+After that you should be able to run one the shipped examples:
+
+> java org.apache.qpid.management.example.GetMultipleResourcePropertiesExample <qman_host> <qman_port>
+> java org.apache.qpid.management.example.GetQManResourceMembersExample <qman_host> <qman_port>
+> java org.apache.qpid.management.example.GetResourceMetadataDescriptorExample <qman_host> <qman_port>
+> java org.apache.qpid.management.example.GetResourcePropertyDocumentExample <qman_host> <qman_port>
+> java org.apache.qpid.management.example.GetResourcePropertyExample <qman_host> <qman_port>
+> java org.apache.qpid.management.example.GetWSDLMetadataExample <qman_host> <qman_port>
+> java org.apache.qpid.management.example.SetResourcePropertyExample <qman_host> <qman_port>
+
+Where
+<qman_host> is the host (ip or hostname) where QMan is running;
+<qman_port> is the port number where QMan is running;
+
+2.3) Qpid
+You must have a running C++ broker with management enabled.
+
+2.4) QMan
+You must have QMan WS-DM up, running and connected with the broker above. \ No newline at end of file
diff --git a/qpid/java/management/client/src/example/SetResourcePropertiesRequest.out.ok b/qpid/java/management/client/src/example/SetResourcePropertiesRequest.out.ok
new file mode 100644
index 0000000000..1f346afa4e
--- /dev/null
+++ b/qpid/java/management/client/src/example/SetResourcePropertiesRequest.out.ok
@@ -0,0 +1,2316 @@
+ SetResourcePropertyExample
+-------------------------------------------------------------------
+
+This example shows how to change the state of a WS-Resource.
+That means a SetResourcePropertyRequest is sent to that
+WS-Resource.
+First of all a request is send to WS-DM in order to get all
+registered WS-Resources.
+If the returned list is not empty then two GetMetadataRequests
+(one for WSDL and one for RDM) are sent to the first child.
+The result metadata descriptors are used for determine :
+
+1) WS-Resource property names;
+2) Modifiability (read-only, read-write
+3) Datatype;
+-------------------------------------------------------------------
+
+So a SetResourcePropertyRequest can be sent in order
+to change the WS-Resource state.
+The example is looking for a property that has one of the
+following datatype :
+
+1) String (xsd:string)
+2) Long (xsd:long)
+3) Integer (xsd:integer or xsd:int)
+4) Double (xsd:double)
+5) Float (xsd:float)
+6) Short (xsd:short)
+
+After the update / insert request has been sent, a
+GetResourcePropertiesRequest is made again
+in order to see if the state has changed correctly.
+
+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://localhost:8080/qman/services/QManWsResource</wsa:To>
+ <wsa:Action xmlns:wsa="http://www.w3.org/2005/08/addressing">http://schemas.xmlsoap.org/ws/2004/09/mex/GetMetadata</wsa:Action>
+ <wsa:MessageID xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:d026718c-2724-d3bf-fd5b-3c6bf4cd5a8c</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">Q-MAN: brokerID=0ef67394-e34a-4bff-b0bf-88cf359ba1a0,class=queue,name=1232966356552,objectId=894cddd3-b893-4e2f-94d2-2489f72cbdd6,package=org.apache.qpid</qman-wsa:ResourceId>
+ </soap:Header>
+ <soap:Body>
+ <qman:GetMetadata xmlns:qman="http://schemas.xmlsoap.org/ws/2004/09/mex">
+ <qman:Dialect>http://docs.oasis-open.org/wsrf/rmd-1</qman:Dialect>
+ </qman:GetMetadata>
+ </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://schemas.xmlsoap.org/ws/2004/09/mex/GetMetadataResponse</wsa:Action>
+ <wsa:MessageID xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:dba8d7ab-83a6-16e1-03cc-48edc672a325</wsa:MessageID>
+ <wsa:RelatesTo RelationshipType="wsa:Reply" xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:d026718c-2724-d3bf-fd5b-3c6bf4cd5a8c</wsa:RelatesTo>
+ <wsa:From xmlns:wsa="http://www.w3.org/2005/08/addressing">
+ <wsa:Address>http://localhost:8080/qman/services/QManWsResource</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">Q-MAN: brokerID=0ef67394-e34a-4bff-b0bf-88cf359ba1a0,class=queue,name=1232966356552,objectId=894cddd3-b893-4e2f-94d2-2489f72cbdd6,package=org.apache.qpid</qman-wsa:ResourceId>
+ </wsa:ReferenceParameters>
+ </wsa:From>
+ </soap:Header>
+ <soap:Body>
+ <wsx:Metadata xmlns:wsx="http://schemas.xmlsoap.org/ws/2004/09/mex">
+ <wsx:MetadataSection>
+ <wsrmd:MetadataDescriptor
+ interface="qman:QManWsResourcePortType"
+ name="QManWsResourceMetadata"
+ wsdlLocation="http://docs.oasis-open.org/wsrf/rmd-1 QManWsResource.wsdl"
+ xmlns:qman="http://amqp.apache.org/qpid/management/qman" xmlns:wsrmd="http://docs.oasis-open.org/wsrf/rmd-1">
+ <wsrmd:Property modifiability="read-write"
+ mutability="mutable" name="qman:MgmtPubInterval" xmlns:qman="http://amqp.apache.org/qpid/management/qman">
+ <wsrmd:ValidValues/>
+ <wsrmd:StaticValues/>
+ <wsrmd:InitialValues/>
+ </wsrmd:Property>
+ <wsrmd:Property modifiability="read-only"
+ mutability="mutable" name="qman:Name" xmlns:qman="http://amqp.apache.org/qpid/management/qman">
+ <wsrmd:ValidValues/>
+ <wsrmd:StaticValues/>
+ <wsrmd:InitialValues/>
+ </wsrmd:Property>
+ <wsrmd:Property modifiability="read-only"
+ mutability="mutable" name="wsrl:TerminationTime" xmlns:wsrl="http://docs.oasis-open.org/wsrf/rl-2">
+ <wsrmd:ValidValues/>
+ <wsrmd:StaticValues/>
+ <wsrmd:InitialValues/>
+ </wsrmd:Property>
+ <wsrmd:Property modifiability="read-only"
+ mutability="mutable"
+ name="qman:MsgTotalEnqueues" xmlns:qman="http://amqp.apache.org/qpid/management/qman">
+ <wsrmd:ValidValues/>
+ <wsrmd:StaticValues/>
+ <wsrmd:InitialValues/>
+ </wsrmd:Property>
+ <wsrmd:Property modifiability="read-only"
+ mutability="mutable" name="qman:Arguments" xmlns:qman="http://amqp.apache.org/qpid/management/qman">
+ <wsrmd:ValidValues/>
+ <wsrmd:StaticValues/>
+ <wsrmd:InitialValues/>
+ </wsrmd:Property>
+ <wsrmd:Property modifiability="read-only"
+ mutability="mutable" name="qman:VhostRef" xmlns:qman="http://amqp.apache.org/qpid/management/qman">
+ <wsrmd:ValidValues/>
+ <wsrmd:StaticValues/>
+ <wsrmd:InitialValues/>
+ </wsrmd:Property>
+ <wsrmd:Property modifiability="read-only"
+ mutability="mutable" name="wsrl:CurrentTime" xmlns:wsrl="http://docs.oasis-open.org/wsrf/rl-2">
+ <wsrmd:ValidValues/>
+ <wsrmd:StaticValues/>
+ <wsrmd:InitialValues/>
+ </wsrmd:Property>
+ <wsrmd:Property modifiability="read-write"
+ mutability="mutable" name="qman:ExpireTime" xmlns:qman="http://amqp.apache.org/qpid/management/qman">
+ <wsrmd:ValidValues/>
+ <wsrmd:StaticValues/>
+ <wsrmd:InitialValues/>
+ </wsrmd:Property>
+ <wsrmd:Property modifiability="read-only"
+ mutability="mutable" name="qman:Durable" xmlns:qman="http://amqp.apache.org/qpid/management/qman">
+ <wsrmd:ValidValues/>
+ <wsrmd:StaticValues/>
+ <wsrmd:InitialValues/>
+ </wsrmd:Property>
+ <wsrmd:Property modifiability="read-only"
+ mutability="mutable" name="qman:ConsumerCount" xmlns:qman="http://amqp.apache.org/qpid/management/qman">
+ <wsrmd:ValidValues/>
+ <wsrmd:StaticValues/>
+ <wsrmd:InitialValues/>
+ </wsrmd:Property>
+ <wsrmd:Property modifiability="read-write"
+ mutability="mutable" name="qman:Type" xmlns:qman="http://amqp.apache.org/qpid/management/qman">
+ <wsrmd:ValidValues/>
+ <wsrmd:StaticValues/>
+ <wsrmd:InitialValues/>
+ </wsrmd:Property>
+ </wsrmd:MetadataDescriptor>
+ </wsx:MetadataSection>
+ </wsx:Metadata>
+ </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://localhost:8080/qman/services/QManWsResource</wsa:To>
+ <wsa:Action xmlns:wsa="http://www.w3.org/2005/08/addressing">http://schemas.xmlsoap.org/ws/2004/09/mex/GetMetadata</wsa:Action>
+ <wsa:MessageID xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:11581af1-04af-05cd-7215-103cad6a316c</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">Q-MAN: brokerID=0ef67394-e34a-4bff-b0bf-88cf359ba1a0,class=queue,name=1232966356552,objectId=894cddd3-b893-4e2f-94d2-2489f72cbdd6,package=org.apache.qpid</qman-wsa:ResourceId>
+ </soap:Header>
+ <soap:Body>
+ <qman:GetMetadata xmlns:qman="http://schemas.xmlsoap.org/ws/2004/09/mex">
+ <qman:Dialect>http://schemas.xmlsoap.org/wsdl/</qman:Dialect>
+ </qman:GetMetadata>
+ </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://schemas.xmlsoap.org/ws/2004/09/mex/GetMetadataResponse</wsa:Action>
+ <wsa:MessageID xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:785964d4-9a81-784f-d68a-60de63223094</wsa:MessageID>
+ <wsa:RelatesTo RelationshipType="wsa:Reply" xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:11581af1-04af-05cd-7215-103cad6a316c</wsa:RelatesTo>
+ <wsa:From xmlns:wsa="http://www.w3.org/2005/08/addressing">
+ <wsa:Address>http://localhost:8080/qman/services/QManWsResource</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">Q-MAN: brokerID=0ef67394-e34a-4bff-b0bf-88cf359ba1a0,class=queue,name=1232966356552,objectId=894cddd3-b893-4e2f-94d2-2489f72cbdd6,package=org.apache.qpid</qman-wsa:ResourceId>
+ </wsa:ReferenceParameters>
+ </wsa:From>
+ </soap:Header>
+ <soap:Body>
+ <wsx:Metadata xmlns:wsx="http://schemas.xmlsoap.org/ws/2004/09/mex">
+ <wsx:MetadataSection>
+ <wsdl:definitions name="QManWsResource"
+ targetNamespace="http://amqp.apache.org/qpid/management/qman"
+ xmlns="http://schemas.xmlsoap.org/wsdl/"
+ xmlns:qman="http://amqp.apache.org/qpid/management/qman"
+ xmlns:wsa="http://www.w3.org/2005/08/addressing"
+ xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
+ xmlns:wsdl-soap="http://schemas.xmlsoap.org/wsdl/soap/"
+ xmlns:wsrf-bf="http://docs.oasis-open.org/wsrf/bf-2"
+ xmlns:wsrf-r="http://docs.oasis-open.org/wsrf/r-2"
+ xmlns:wsrf-rl="http://docs.oasis-open.org/wsrf/rl-2"
+ xmlns:wsrf-rp="http://docs.oasis-open.org/wsrf/rp-2"
+ xmlns:wsrmd="http://docs.oasis-open.org/wsrf/rmd-1"
+ xmlns:wsx="http://schemas.xmlsoap.org/ws/2004/09/mex" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
+ <wsdl:types>
+ <xsd:schema attributeFormDefault="unqualified"
+ elementFormDefault="qualified"
+ targetNamespace="http://www.w3.org/2005/08/addressing"
+ xmlns:tns="http://www.w3.org/2005/08/addressing" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+ <xs:element name="EndpointReference"
+ type="tns:EndpointReferenceType" xmlns:xs="http://www.w3.org/2001/XMLSchema"/>
+ <xs:complexType mixed="false"
+ name="EndpointReferenceType" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+ <xs:sequence>
+ <xs:element name="Address" type="tns:AttributedURIType"/>
+ <xs:element minOccurs="0"
+ name="ReferenceParameters" type="tns:ReferenceParametersType"/>
+ <xs:element minOccurs="0" ref="tns:Metadata"/>
+ <xs:any maxOccurs="unbounded"
+ minOccurs="0"
+ namespace="##other" processContents="lax"/>
+ </xs:sequence>
+ <xs:anyAttribute namespace="##other" processContents="lax"/>
+ </xs:complexType>
+ <xs:complexType mixed="false"
+ name="ReferenceParametersType" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+ <xs:sequence>
+ <xs:any maxOccurs="unbounded"
+ minOccurs="0" namespace="##any" processContents="lax"/>
+ </xs:sequence>
+ <xs:anyAttribute namespace="##other" processContents="lax"/>
+ </xs:complexType>
+ <xs:element name="Metadata"
+ type="tns:MetadataType" xmlns:xs="http://www.w3.org/2001/XMLSchema"/>
+ <xs:complexType mixed="false"
+ name="MetadataType" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+ <xs:sequence>
+ <xs:any maxOccurs="unbounded"
+ minOccurs="0" namespace="##any" processContents="lax"/>
+ </xs:sequence>
+ <xs:anyAttribute namespace="##other" processContents="lax"/>
+ </xs:complexType>
+ <xs:element name="MessageID"
+ type="tns:AttributedURIType" xmlns:xs="http://www.w3.org/2001/XMLSchema"/>
+ <xs:element name="RelatesTo"
+ type="tns:RelatesToType" xmlns:xs="http://www.w3.org/2001/XMLSchema"/>
+ <xs:complexType mixed="false"
+ name="RelatesToType" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+ <xs:simpleContent>
+ <xs:extension base="xs:anyURI">
+ <xs:attribute
+ default="http://www.w3.org/2005/08/addressing/reply"
+ name="RelationshipType"
+ type="tns:RelationshipTypeOpenEnum" use="optional"/>
+ <xs:anyAttribute
+ namespace="##other" processContents="lax"/>
+ </xs:extension>
+ </xs:simpleContent>
+ </xs:complexType>
+ <xs:simpleType
+ name="RelationshipTypeOpenEnum" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+ <xs:union memberTypes="tns:RelationshipType xs:anyURI"/>
+ </xs:simpleType>
+ <xs:simpleType name="RelationshipType" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+ <xs:restriction base="xs:anyURI">
+ <xs:enumeration value="http://www.w3.org/2005/08/addressing/reply"/>
+ </xs:restriction>
+ </xs:simpleType>
+ <xs:element name="ReplyTo"
+ type="tns:EndpointReferenceType" xmlns:xs="http://www.w3.org/2001/XMLSchema"/>
+ <xs:element name="From"
+ type="tns:EndpointReferenceType" xmlns:xs="http://www.w3.org/2001/XMLSchema"/>
+ <xs:element name="FaultTo"
+ type="tns:EndpointReferenceType" xmlns:xs="http://www.w3.org/2001/XMLSchema"/>
+ <xs:element name="To"
+ type="tns:AttributedURIType" xmlns:xs="http://www.w3.org/2001/XMLSchema"/>
+ <xs:element name="Action"
+ type="tns:AttributedURIType" xmlns:xs="http://www.w3.org/2001/XMLSchema"/>
+ <xs:complexType mixed="false"
+ name="AttributedURIType" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+ <xs:simpleContent>
+ <xs:extension base="xs:anyURI">
+ <xs:anyAttribute
+ namespace="##other" processContents="lax"/>
+ </xs:extension>
+ </xs:simpleContent>
+ </xs:complexType>
+ <xs:attribute name="IsReferenceParameter"
+ type="xs:boolean" xmlns:xs="http://www.w3.org/2001/XMLSchema"/>
+ <xs:simpleType name="FaultCodesOpenEnumType" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+ <xs:union memberTypes="tns:FaultCodesType xs:QName"/>
+ </xs:simpleType>
+ <xs:simpleType name="FaultCodesType" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+ <xs:restriction base="xs:QName">
+ <xs:enumeration value="tns:InvalidAddressingHeader"/>
+ <xs:enumeration value="tns:InvalidAddress"/>
+ <xs:enumeration value="tns:InvalidEPR"/>
+ <xs:enumeration value="tns:InvalidCardinality"/>
+ <xs:enumeration value="tns:MissingAddressInEPR"/>
+ <xs:enumeration value="tns:DuplicateMessageID"/>
+ <xs:enumeration value="tns:ActionMismatch"/>
+ <xs:enumeration value="tns:MessageAddressingHeaderRequired"/>
+ <xs:enumeration value="tns:DestinationUnreachable"/>
+ <xs:enumeration value="tns:ActionNotSupported"/>
+ <xs:enumeration value="tns:EndpointUnavailable"/>
+ </xs:restriction>
+ </xs:simpleType>
+ <xs:element name="RetryAfter"
+ type="tns:AttributedUnsignedLongType" xmlns:xs="http://www.w3.org/2001/XMLSchema"/>
+ <xs:complexType mixed="false"
+ name="AttributedUnsignedLongType" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+ <xs:simpleContent>
+ <xs:extension base="xs:unsignedLong">
+ <xs:anyAttribute
+ namespace="##other" processContents="lax"/>
+ </xs:extension>
+ </xs:simpleContent>
+ </xs:complexType>
+ <xs:element name="ProblemHeaderQName"
+ type="tns:AttributedQNameType" xmlns:xs="http://www.w3.org/2001/XMLSchema"/>
+ <xs:complexType mixed="false"
+ name="AttributedQNameType" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+ <xs:simpleContent>
+ <xs:extension base="xs:QName">
+ <xs:anyAttribute
+ namespace="##other" processContents="lax"/>
+ </xs:extension>
+ </xs:simpleContent>
+ </xs:complexType>
+ <xs:element name="ProblemHeader"
+ type="tns:AttributedAnyType" xmlns:xs="http://www.w3.org/2001/XMLSchema"/>
+ <xs:complexType mixed="false"
+ name="AttributedAnyType" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+ <xs:sequence>
+ <xs:any maxOccurs="1" minOccurs="1"
+ namespace="##any" processContents="lax"/>
+ </xs:sequence>
+ <xs:anyAttribute namespace="##other" processContents="lax"/>
+ </xs:complexType>
+ <xs:element name="ProblemIRI"
+ type="tns:AttributedURIType" xmlns:xs="http://www.w3.org/2001/XMLSchema"/>
+ <xs:element name="ProblemAction"
+ type="tns:ProblemActionType" xmlns:xs="http://www.w3.org/2001/XMLSchema"/>
+ <xs:complexType mixed="false"
+ name="ProblemActionType" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+ <xs:sequence>
+ <xs:element minOccurs="0" ref="tns:Action"/>
+ <xs:element minOccurs="0"
+ name="SoapAction" type="xs:anyURI"/>
+ </xs:sequence>
+ <xs:anyAttribute namespace="##other" processContents="lax"/>
+ </xs:complexType>
+ </xsd:schema>
+ <xsd:schema elementFormDefault="qualified"
+ targetNamespace="http://schemas.xmlsoap.org/ws/2004/09/mex"
+ xmlns:tns="http://schemas.xmlsoap.org/ws/2004/09/mex"
+ xmlns:wsa="http://www.w3.org/2005/08/addressing" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+ <xs:import
+ namespace="http://www.w3.org/2005/08/addressing" xmlns:xs="http://www.w3.org/2001/XMLSchema"/>
+ <xs:element name="GetMetadata" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element minOccurs="0" ref="tns:Dialect"/>
+ <xs:element minOccurs="0" ref="tns:Identifier"/>
+ </xs:sequence>
+ <xs:anyAttribute namespace="##other" processContents="lax"/>
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="Dialect" type="xs:anyURI" xmlns:xs="http://www.w3.org/2001/XMLSchema"/>
+ <xs:element name="Identifier"
+ type="xs:anyURI" xmlns:xs="http://www.w3.org/2001/XMLSchema"/>
+ <xs:element name="Metadata" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element
+ maxOccurs="unbounded"
+ minOccurs="0" ref="tns:MetadataSection"/>
+ </xs:sequence>
+ <xs:anyAttribute namespace="##other" processContents="lax"/>
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="MetadataSection" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+ <xs:complexType>
+ <xs:choice>
+ <xs:any maxOccurs="unbounded"
+ minOccurs="0"
+ namespace="##other" processContents="lax"/>
+ <xs:element ref="tns:MetadataReference"/>
+ <xs:element ref="tns:Location"/>
+ </xs:choice>
+ <xs:attribute name="Dialect"
+ type="xs:anyURI" use="required"/>
+ <xs:attribute name="Identifier" type="xs:anyURI"/>
+ <xs:anyAttribute namespace="##other" processContents="lax"/>
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="MetadataReference"
+ type="wsa:EndpointReferenceType" xmlns:xs="http://www.w3.org/2001/XMLSchema"/>
+ <xs:element name="Location" type="xs:anyURI" xmlns:xs="http://www.w3.org/2001/XMLSchema"/>
+ <xs:complexType name="AnyXmlType" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+ <xs:sequence>
+ <xs:any namespace="##any" processContents="lax"/>
+ </xs:sequence>
+ <xs:anyAttribute namespace="##any" processContents="lax"/>
+ </xs:complexType>
+ </xsd:schema>
+ <xsd:schema attributeFormDefault="unqualified"
+ elementFormDefault="qualified"
+ targetNamespace="http://docs.oasis-open.org/wsrf/rl-2"
+ xmlns="http://www.w3.org/2001/XMLSchema"
+ xmlns:wsrf-bf="http://docs.oasis-open.org/wsrf/bf-2"
+ xmlns:wsrf-rl="http://docs.oasis-open.org/wsrf/rl-2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <xsd:import namespace="http://docs.oasis-open.org/wsrf/bf-2"/>
+ <xsd:element name="CurrentTime">
+ <xsd:complexType>
+ <xsd:simpleContent>
+ <xsd:extension base="xsd:dateTime">
+ <xsd:anyAttribute
+ namespace="##other" processContents="lax"/>
+ </xsd:extension>
+ </xsd:simpleContent>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="TerminationTime" nillable="true">
+ <xsd:complexType>
+ <xsd:simpleContent>
+ <xsd:extension base="xsd:dateTime">
+ <xsd:anyAttribute
+ namespace="##other" processContents="lax"/>
+ </xsd:extension>
+ </xsd:simpleContent>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="ScheduledResourceTerminationRP">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element maxOccurs="1"
+ minOccurs="1" ref="wsrf-rl:CurrentTime"/>
+ <xsd:element maxOccurs="1"
+ minOccurs="1" ref="wsrf-rl:TerminationTime"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="Destroy">
+ <xsd:complexType/>
+ </xsd:element>
+ <xsd:element name="DestroyResponse">
+ <xsd:complexType/>
+ </xsd:element>
+ <xsd:complexType name="ResourceNotDestroyedFaultType">
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType"/>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:element
+ name="ResourceNotDestroyedFault" type="wsrf-rl:ResourceNotDestroyedFaultType"/>
+ <xsd:element name="SetTerminationTime">
+ <xsd:complexType>
+ <xsd:choice>
+ <xsd:element
+ name="RequestedTerminationTime"
+ nillable="true" type="xsd:dateTime"/>
+ <xsd:element
+ name="RequestedLifetimeDuration" type="xsd:duration"/>
+ </xsd:choice>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="SetTerminationTimeResponse">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element
+ name="NewTerminationTime"
+ nillable="true" type="xsd:dateTime"/>
+ <xsd:element name="CurrentTime" type="xsd:dateTime"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:complexType name="UnableToSetTerminationTimeFaultType">
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType"/>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:element
+ name="UnableToSetTerminationTimeFault" type="wsrf-rl:UnableToSetTerminationTimeFaultType"/>
+ <xsd:complexType name="TerminationTimeChangeRejectedFaultType">
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType"/>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:element
+ name="TerminationTimeChangeRejectedFault" type="wsrf-rl:TerminationTimeChangeRejectedFaultType"/>
+ <xsd:element name="TerminationNotification">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element maxOccurs="1"
+ minOccurs="1"
+ name="TerminationTime"
+ nillable="true" type="xsd:dateTime"/>
+ <xsd:element maxOccurs="1"
+ minOccurs="0"
+ name="TerminationReason" type="xsd:anyType"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:schema>
+ <xsd:schema attributeFormDefault="unqualified"
+ elementFormDefault="qualified"
+ targetNamespace="http://docs.oasis-open.org/wsrf/rp-2"
+ xmlns:wsrf-bf="http://docs.oasis-open.org/wsrf/bf-2" xmlns:wsrf-rp="http://docs.oasis-open.org/wsrf/rp-2">
+ <xsd:import namespace="http://docs.oasis-open.org/wsrf/bf-2"/>
+ <xsd:element name="QueryExpressionDialect" type="xsd:anyURI"/>
+ <xsd:element name="QueryExpressionRPDocument">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element
+ maxOccurs="unbounded"
+ minOccurs="0" ref="wsrf-rp:QueryExpressionDialect"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:attribute name="ResourceProperties" type="xsd:QName"/>
+ <xsd:complexType name="ResourcePropertyValueChangeNotificationType">
+ <xsd:sequence>
+ <xsd:element maxOccurs="1"
+ minOccurs="0" name="OldValues" nillable="true">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:any
+ maxOccurs="unbounded" minOccurs="1"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element maxOccurs="1"
+ minOccurs="1" name="NewValues" nillable="true">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:any
+ maxOccurs="unbounded" minOccurs="1"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:element
+ name="ResourcePropertyValueChangeNotification" type="wsrf-rp:ResourcePropertyValueChangeNotificationType"/>
+ <xsd:complexType mixed="true" name="QueryExpressionType">
+ <xsd:sequence>
+ <xsd:any maxOccurs="1" minOccurs="0" processContents="lax"/>
+ </xsd:sequence>
+ <xsd:attribute name="Dialect" type="xsd:anyURI"/>
+ </xsd:complexType>
+ <xsd:element name="QueryExpression" type="wsrf-rp:QueryExpressionType"/>
+ <xsd:element name="GetResourcePropertyDocument">
+ <xsd:complexType/>
+ </xsd:element>
+ <xsd:element name="GetResourcePropertyDocumentResponse">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:any maxOccurs="1" minOccurs="1"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="GetResourceProperty" type="xsd:QName"/>
+ <xsd:element name="GetResourcePropertyResponse">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:any maxOccurs="unbounded" minOccurs="0"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:complexType name="InvalidResourcePropertyQNameFaultType">
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType"/>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:element
+ name="InvalidResourcePropertyQNameFault" type="wsrf-rp:InvalidResourcePropertyQNameFaultType"/>
+ <xsd:element name="GetMultipleResourceProperties">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element
+ maxOccurs="unbounded"
+ minOccurs="1"
+ name="ResourceProperty" type="xsd:QName"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="GetMultipleResourcePropertiesResponse">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:any maxOccurs="unbounded" minOccurs="0"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="PutResourcePropertyDocument">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:any maxOccurs="1" minOccurs="1"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="PutResourcePropertyDocumentResponse">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:any maxOccurs="1" minOccurs="0"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:complexType name="ResourcePropertyChangeFailureType">
+ <xsd:sequence>
+ <xsd:element maxOccurs="1"
+ minOccurs="0" name="CurrentValue">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:any
+ maxOccurs="unbounded" minOccurs="1"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element maxOccurs="1"
+ minOccurs="0" name="RequestedValue">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:any
+ maxOccurs="unbounded" minOccurs="1"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:sequence>
+ <xsd:attribute name="Restored" type="xsd:boolean"/>
+ </xsd:complexType>
+ <xsd:complexType name="UnableToPutResourcePropertyDocumentFaultType">
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType">
+ <xsd:sequence>
+ <xsd:element
+ name="ResourcePropertyChangeFailure" type="wsrf-rp:ResourcePropertyChangeFailureType"/>
+ </xsd:sequence>
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:element
+ name="UnableToPutResourcePropertyDocumentFault" type="wsrf-rp:UnableToPutResourcePropertyDocumentFaultType"/>
+ <xsd:complexType name="InsertType">
+ <xsd:sequence>
+ <xsd:any maxOccurs="unbounded"
+ minOccurs="1" processContents="lax"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:element name="Insert" type="wsrf-rp:InsertType"/>
+ <xsd:complexType name="UpdateType">
+ <xsd:sequence>
+ <xsd:any maxOccurs="unbounded"
+ minOccurs="1" processContents="lax"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:element name="Update" type="wsrf-rp:UpdateType"/>
+ <xsd:complexType name="DeleteType">
+ <xsd:attribute name="ResourceProperty"
+ type="xsd:QName" use="required"/>
+ </xsd:complexType>
+ <xsd:element name="Delete" type="wsrf-rp:DeleteType"/>
+ <xsd:element name="SetResourceProperties">
+ <xsd:complexType>
+ <xsd:choice maxOccurs="unbounded" minOccurs="1">
+ <xsd:element ref="wsrf-rp:Insert"/>
+ <xsd:element ref="wsrf-rp:Update"/>
+ <xsd:element ref="wsrf-rp:Delete"/>
+ </xsd:choice>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="SetResourcePropertiesResponse">
+ <xsd:complexType/>
+ </xsd:element>
+ <xsd:complexType name="InvalidModificationFaultType">
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType">
+ <xsd:sequence>
+ <xsd:element
+ name="ResourcePropertyChangeFailure" type="wsrf-rp:ResourcePropertyChangeFailureType"/>
+ </xsd:sequence>
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:element name="InvalidModificationFault" type="wsrf-rp:InvalidModificationFaultType"/>
+ <xsd:complexType name="UnableToModifyResourcePropertyFaultType">
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType">
+ <xsd:sequence>
+ <xsd:element
+ name="ResourcePropertyChangeFailure" type="wsrf-rp:ResourcePropertyChangeFailureType"/>
+ </xsd:sequence>
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:element
+ name="UnableToModifyResourcePropertyFault" type="wsrf-rp:UnableToModifyResourcePropertyFaultType"/>
+ <xsd:complexType name="SetResourcePropertyRequestFailedFaultType">
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType">
+ <xsd:sequence>
+ <xsd:element
+ name="ResourcePropertyChangeFailure" type="wsrf-rp:ResourcePropertyChangeFailureType"/>
+ </xsd:sequence>
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:element
+ name="SetResourcePropertyRequestFailedFault" type="wsrf-rp:SetResourcePropertyRequestFailedFaultType"/>
+ <xsd:complexType name="InsertResourcePropertiesRequestFailedFaultType">
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType">
+ <xsd:sequence>
+ <xsd:element
+ name="ResourcePropertyChangeFailure" type="wsrf-rp:ResourcePropertyChangeFailureType"/>
+ </xsd:sequence>
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:element
+ name="InsertResourcePropertiesRequestFailedFault" type="wsrf-rp:InsertResourcePropertiesRequestFailedFaultType"/>
+ <xsd:complexType name="UpdateResourcePropertiesRequestFailedFaultType">
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType">
+ <xsd:sequence>
+ <xsd:element
+ name="ResourcePropertyChangeFailure" type="wsrf-rp:ResourcePropertyChangeFailureType"/>
+ </xsd:sequence>
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:element
+ name="UpdateResourcePropertiesRequestFailedFault" type="wsrf-rp:UpdateResourcePropertiesRequestFailedFaultType"/>
+ <xsd:complexType name="DeleteResourcePropertiesRequestFailedFaultType">
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType">
+ <xsd:sequence>
+ <xsd:element
+ name="ResourcePropertyChangeFailure" type="wsrf-rp:ResourcePropertyChangeFailureType"/>
+ </xsd:sequence>
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:element
+ name="DeleteResourcePropertiesRequestFailedFault" type="wsrf-rp:DeleteResourcePropertiesRequestFailedFaultType"/>
+ <xsd:element name="InsertResourceProperties">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element ref="wsrf-rp:Insert"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="InsertResourcePropertiesResponse">
+ <xsd:complexType/>
+ </xsd:element>
+ <xsd:element name="UpdateResourceProperties">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element ref="wsrf-rp:Update"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="UpdateResourcePropertiesResponse">
+ <xsd:complexType/>
+ </xsd:element>
+ <xsd:element name="DeleteResourceProperties">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element ref="wsrf-rp:Delete"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="DeleteResourcePropertiesResponse">
+ <xsd:complexType/>
+ </xsd:element>
+ <xsd:element name="QueryResourceProperties">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element maxOccurs="1"
+ minOccurs="1" ref="wsrf-rp:QueryExpression"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="QueryResourcePropertiesResponse">
+ <xsd:complexType>
+ <xsd:complexContent mixed="true">
+ <xsd:restriction base="xsd:anyType">
+ <xsd:sequence>
+ <xsd:any
+ maxOccurs="unbounded"
+ minOccurs="1" processContents="lax"/>
+ </xsd:sequence>
+ </xsd:restriction>
+ </xsd:complexContent>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:complexType name="UnknownQueryExpressionDialectFaultType">
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType"/>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:element
+ name="UnknownQueryExpressionDialectFault" type="wsrf-rp:UnknownQueryExpressionDialectFaultType"/>
+ <xsd:complexType name="InvalidQueryExpressionFaultType">
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType"/>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:element
+ name="InvalidQueryExpressionFault" type="wsrf-rp:InvalidQueryExpressionFaultType"/>
+ <xsd:complexType name="QueryEvaluationErrorFaultType">
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType"/>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:element
+ name="QueryEvaluationErrorFault" type="wsrf-rp:QueryEvaluationErrorFaultType"/>
+ </xsd:schema>
+ <xsd:schema attributeFormDefault="unqualified"
+ elementFormDefault="qualified"
+ targetNamespace="http://docs.oasis-open.org/wsrf/r-2"
+ xmlns:wsrf-bf="http://docs.oasis-open.org/wsrf/bf-2"
+ xmlns:wsrf-r="http://docs.oasis-open.org/wsrf/r-2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <xsd:import namespace="http://docs.oasis-open.org/wsrf/bf-2"/>
+ <xsd:complexType name="ResourceUnknownFaultType">
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType"/>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:element name="ResourceUnknownFault" type="wsrf-r:ResourceUnknownFaultType"/>
+ <xsd:complexType name="ResourceUnavailableFaultType">
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType"/>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:element name="ResourceUnavailableFault" type="wsrf-r:ResourceUnavailableFaultType"/>
+ </xsd:schema>
+ <xsd:schema elementFormDefault="qualified"
+ targetNamespace="http://docs.oasis-open.org/wsrf/rmd-1"
+ xmlns="http://www.w3.org/2001/XMLSchema"
+ xmlns:wsa="http://www.w3.org/2005/08/addressing"
+ xmlns:wsrf-rp="http://docs.oasis-open.org/wsrf/rp-2" xmlns:wsrmd="http://docs.oasis-open.org/wsrf/rmd-1">
+ <xsd:import namespace="http://docs.oasis-open.org/wsrf/rp-2"/>
+ <xsd:import namespace="http://www.w3.org/2005/08/addressing"/>
+ <xsd:simpleType name="PairsOfURIType">
+ <xsd:list itemType="xsd:anyURI"/>
+ </xsd:simpleType>
+ <xsd:attribute name="Descriptor" type="xsd:QName"/>
+ <xsd:attribute name="DescriptorLocation" type="xsd:anyURI"/>
+ <xsd:complexType mixed="true" name="DocumentationType">
+ <xsd:sequence>
+ <xsd:any maxOccurs="unbounded"
+ minOccurs="0" namespace="##any" processContents="lax"/>
+ </xsd:sequence>
+ <xsd:anyAttribute/>
+ </xsd:complexType>
+ <xsd:complexType name="DocumentedType">
+ <xsd:sequence>
+ <xsd:element maxOccurs="1"
+ minOccurs="0"
+ name="documentation" type="wsrmd:DocumentationType"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:complexType name="DefinitionsType">
+ <xsd:complexContent>
+ <xsd:extension base="wsrmd:DocumentedType">
+ <xsd:sequence>
+ <xsd:element
+ maxOccurs="unbounded"
+ minOccurs="0" ref="wsrmd:MetadataDescriptor"/>
+ <xsd:any
+ maxOccurs="unbounded"
+ minOccurs="0"
+ namespace="##other" processContents="lax"/>
+ </xsd:sequence>
+ <xsd:attribute
+ name="targetNamespace"
+ type="xsd:anyURI" use="required"/>
+ <xsd:anyAttribute
+ namespace="##other" processContents="lax"/>
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:element name="Definitions" type="wsrmd:DefinitionsType">
+ <xsd:key name="MetadataDescriptor">
+ <xsd:annotation>
+ <xsd:documentation>
+ To form a QName, the name of any MetadataDescriptor must be
+ unique within a Definitions element.
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:selector xpath="wsrmd:MetadataDescriptor"/>
+ <xsd:field xpath="@name"/>
+ </xsd:key>
+ </xsd:element>
+ <xsd:complexType name="MetadataDescriptorType">
+ <xsd:complexContent>
+ <xsd:extension base="wsrmd:DocumentedType">
+ <xsd:sequence>
+ <xsd:element
+ maxOccurs="unbounded"
+ minOccurs="0" ref="wsrmd:Property"/>
+ <xsd:any
+ maxOccurs="unbounded"
+ minOccurs="0"
+ namespace="##other" processContents="lax"/>
+ </xsd:sequence>
+ <xsd:attribute name="name"
+ type="xsd:NCName" use="required"/>
+ <xsd:attribute name="interface"
+ type="xsd:QName" use="required"/>
+ <xsd:attribute
+ name="wsdlLocation" type="wsrmd:PairsOfURIType"/>
+ <xsd:anyAttribute
+ namespace="##other" processContents="lax"/>
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:element name="MetadataDescriptor" type="wsrmd:MetadataDescriptorType"/>
+ <xsd:complexType name="PropertyType">
+ <xsd:complexContent>
+ <xsd:extension base="wsrmd:DocumentedType">
+ <xsd:sequence>
+ <xsd:choice>
+ <xsd:element
+ maxOccurs="1"
+ minOccurs="0" ref="wsrmd:ValidValues"/>
+ <xsd:element
+ maxOccurs="1"
+ minOccurs="0" ref="wsrmd:ValidValueRange"/>
+ </xsd:choice>
+ <xsd:element maxOccurs="1"
+ minOccurs="0" ref="wsrmd:StaticValues"/>
+ <xsd:any
+ maxOccurs="unbounded"
+ minOccurs="0"
+ namespace="##other" processContents="lax"/>
+ </xsd:sequence>
+ <xsd:attribute name="name"
+ type="xsd:QName" use="required"/>
+ <xsd:attribute name="mutability" type="wsrmd:MutabilityType"/>
+ <xsd:attribute
+ name="modifiability" type="wsrmd:ModifiabilityType"/>
+ <xsd:attribute default="false"
+ name="subscribability" type="xsd:boolean"/>
+ <xsd:anyAttribute
+ namespace="##other" processContents="lax"/>
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:element name="Property" type="wsrmd:PropertyType"/>
+ <xsd:simpleType name="MutabilityType">
+ <xsd:restriction base="xsd:string">
+ <xsd:enumeration value="constant"/>
+ <xsd:enumeration value="appendable"/>
+ <xsd:enumeration value="mutable"/>
+ </xsd:restriction>
+ </xsd:simpleType>
+ <xsd:simpleType name="ModifiabilityType">
+ <xsd:restriction base="xsd:string">
+ <xsd:enumeration value="read-only"/>
+ <xsd:enumeration value="read-write"/>
+ </xsd:restriction>
+ </xsd:simpleType>
+ <xsd:complexType mixed="true" name="ValidValuesType">
+ <xsd:sequence>
+ <xsd:element maxOccurs="1"
+ minOccurs="0"
+ name="documentation" type="wsrmd:DocumentationType"/>
+ <xsd:any maxOccurs="unbounded"
+ minOccurs="0"
+ namespace="##other" processContents="lax"/>
+ </xsd:sequence>
+ <xsd:anyAttribute namespace="##other" processContents="lax"/>
+ </xsd:complexType>
+ <xsd:element name="ValidValues" type="wsrmd:ValidValuesType"/>
+ <xsd:complexType mixed="true" name="ValidValueRangeType">
+ <xsd:sequence>
+ <xsd:element maxOccurs="1"
+ minOccurs="0"
+ name="documentation" type="wsrmd:DocumentationType"/>
+ <xsd:any maxOccurs="unbounded"
+ minOccurs="0"
+ namespace="##other" processContents="lax"/>
+ </xsd:sequence>
+ <xsd:attribute name="lowerBound" type="xsd:anySimpleType"/>
+ <xsd:attribute name="upperBound" type="xsd:anySimpleType"/>
+ <xsd:anyAttribute namespace="##other" processContents="lax"/>
+ </xsd:complexType>
+ <xsd:element name="ValidValueRange" type="wsrmd:ValidValueRangeType"/>
+ <xsd:complexType mixed="true" name="StaticValuesType">
+ <xsd:sequence>
+ <xsd:element maxOccurs="1"
+ minOccurs="0"
+ name="documentation" type="wsrmd:DocumentationType"/>
+ <xsd:any maxOccurs="unbounded"
+ minOccurs="0"
+ namespace="##other" processContents="lax"/>
+ </xsd:sequence>
+ <xsd:anyAttribute namespace="##other" processContents="lax"/>
+ </xsd:complexType>
+ <xsd:element name="StaticValues" type="wsrmd:StaticValuesType"/>
+ <xsd:complexType mixed="true" name="InitialValuesType">
+ <xsd:sequence>
+ <xsd:element maxOccurs="1"
+ minOccurs="0"
+ name="documentation" type="wsrmd:DocumentationType"/>
+ <xsd:any maxOccurs="unbounded"
+ minOccurs="0"
+ namespace="##other" processContents="lax"/>
+ </xsd:sequence>
+ <xsd:anyAttribute namespace="##other" processContents="lax"/>
+ </xsd:complexType>
+ <xsd:element name="InitialValues" type="wsrmd:InitialValuesType"/>
+ <xsd:complexType name="MetadataDescriptorReferenceType">
+ <xsd:complexContent>
+ <xsd:extension base="wsa:EndpointReferenceType"/>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:element
+ name="MetadataDescriptorReference" type="wsrmd:MetadataDescriptorReferenceType"/>
+ <xsd:element name="MetadataResourceRP" type="wsrmd:DefinitionsType"/>
+ </xsd:schema>
+ <xsd:schema elementFormDefault="qualified" targetNamespace="http://amqp.apache.org/qpid/management/qman">
+ <xsd:import namespace="http://docs.oasis-open.org/wsrf/rl-2"/>
+ <xsd:import namespace="http://docs.oasis-open.org/wsrf/rp-2"/>
+ <xsd:import namespace="http://docs.oasis-open.org/wsrf/bf-2"/>
+ <xsd:element name="QManWsResourceProperties">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element ref="wsrf-rl:CurrentTime"/>
+ <xsd:element ref="wsrf-rl:TerminationTime"/>
+ <xsd:element
+ maxOccurs="unbounded"
+ minOccurs="0" ref="wsrf-rp:QueryExpressionDialect"/>
+ <xsd:element ref="qman:Name"/>
+ <xsd:element ref="qman:Type"/>
+ <xsd:element ref="qman:Arguments"/>
+ <xsd:element ref="qman:VhostRef"/>
+ <xsd:element ref="qman:Durable"/>
+ <xsd:element ref="qman:MsgTotalEnqueues"/>
+ <xsd:element ref="qman:ConsumerCount"/>
+ <xsd:element ref="qman:ExpireTime"/>
+ <xsd:element ref="qman:MgmtPubInterval"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="QManFault">
+ <xsd:complexType>
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType"/>
+ </xsd:complexContent>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="MethodInvocationFault">
+ <xsd:complexType>
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType"/>
+ </xsd:complexContent>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="EntityInstanceNotFoundFault">
+ <xsd:complexType>
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType"/>
+ </xsd:complexContent>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="MalformedEntityNameFault">
+ <xsd:complexType>
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType"/>
+ </xsd:complexContent>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="NoSuchAttributeFault">
+ <xsd:complexType>
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType"/>
+ </xsd:complexContent>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:complexType name="result">
+ <xsd:sequence>
+ <xsd:element name="statusCode" type="xsd:long"/>
+ <xsd:element name="statusText" type="xsd:string"/>
+ <xsd:complexType name="outputParameters">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element
+ maxOccurs="unbounded"
+ minOccurs="0" name="entry">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:name
+ name="key" type="xsd:string"/>
+ <xsd:element
+ name="value" type="xsd:anyType"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:complexType>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:element name="Name" type="xsd:string"/>
+ <xsd:element name="Type" type="xsd:string"/>
+ <xsd:complexType name="map">
+ <xsd:sequence>
+ <xsd:element maxOccurs="unbounded"
+ minOccurs="0" name="entry">
+ <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:element name="Arguments" type="qman:map"/>
+ <xsd:complexType name="uuid">
+ <xsd:sequence>
+ <xsd:element name="uuid" type="xsd:string"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:element name="VhostRef" type="qman:uuid"/>
+ <xsd:element name="Durable" type="xsd:boolean"/>
+ <xsd:element name="MsgTotalEnqueues" type="xsd:long"/>
+ <xsd:element name="ConsumerCount" type="xsd:integer"/>
+ <xsd:element name="ExpireTime" type="xsd:dateTime"/>
+ <xsd:element name="MgmtPubInterval" type="xsd:short"/>
+ <xsd:element
+ name="echoWithSimpleTypesRequest" type="qman:echoWithSimpleTypesRequest"/>
+ <xsd:element
+ name="echoWithSimpleTypesResponse" type="qman:echoWithSimpleTypesResponse"/>
+ <xsd:complexType name="echoWithSimpleTypesRequest">
+ <xsd:sequence>
+ <xsd:element name="p1" type="xsd:long"/>
+ <xsd:element name="p2" type="xsd:boolean"/>
+ <xsd:element name="p3" type="xsd:double"/>
+ <xsd:element name="p4" type="xsd:float"/>
+ <xsd:element name="p5" type="xsd:integer"/>
+ <xsd:element name="p6" type="xsd:short"/>
+ <xsd:element name="p7" type="xsd:string"/>
+ <xsd:element name="p8" type="xsd:anyURI"/>
+ <xsd:element name="p9" type="xsd:dateTime"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:complexType name="echoWithSimpleTypesResponse">
+ <xsd:sequence>
+ <xsd:element name="result" type="qman:result"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:element name="echoWithArraysRequest" type="qman:echoWithArraysRequest"/>
+ <xsd:element name="echoWithArraysResponse" type="qman:echoWithArraysResponse"/>
+ <xsd:complexType name="arrayOfLong">
+ <xsd:sequence>
+ <xsd:element name="entry" type="xsd:long"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:complexType name="arrayOfBoolean">
+ <xsd:sequence>
+ <xsd:element name="entry" type="xsd:boolean"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:complexType name="arrayOfDouble">
+ <xsd:sequence>
+ <xsd:element name="entry" type="xsd:double"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:complexType name="arrayOfFloat">
+ <xsd:sequence>
+ <xsd:element name="entry" type="xsd:float"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:complexType name="arrayOfInteger">
+ <xsd:sequence>
+ <xsd:element name="entry" type="xsd:integer"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:complexType name="arrayOfShort">
+ <xsd:sequence>
+ <xsd:element name="entry" type="xsd:short"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:complexType name="arrayOfString">
+ <xsd:sequence>
+ <xsd:element name="entry" type="xsd:string"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:complexType name="arrayOfURI">
+ <xsd:sequence>
+ <xsd:element name="entry" type="xsd:anyURI"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:complexType name="arrayOfDate">
+ <xsd:sequence>
+ <xsd:element name="entry" type="xsd:dateTime"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:complexType name="echoWithArraysRequest">
+ <xsd:sequence>
+ <xsd:element name="p1" type="qman:arrayOfLong"/>
+ <xsd:element name="p2" type="qman:arrayOfBoolean"/>
+ <xsd:element name="p3" type="qman:arrayOfDouble"/>
+ <xsd:element name="p4" type="qman:arrayOfFloat"/>
+ <xsd:element name="p5" type="qman:arrayOfInteger"/>
+ <xsd:element name="p6" type="qman:arrayOfShort"/>
+ <xsd:element name="p7" type="qman:arrayOfString"/>
+ <xsd:element name="p8" type="qman:arrayOfURI"/>
+ <xsd:element name="p9" type="qman:arrayOfDate"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:complexType name="echoWithArraysResponse">
+ <xsd:sequence>
+ <xsd:element name="result" type="qman:result"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:element
+ name="echoWithSimpleTypeArraysRequest" type="qman:echoWithSimpleTypeArraysRequest"/>
+ <xsd:element
+ name="echoWithSimpleTypeArraysResponse" type="qman:echoWithSimpleTypeArraysResponse"/>
+ <xsd:complexType name="arrayOfLong">
+ <xsd:sequence>
+ <xsd:element name="entry" type="xsd:long"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:complexType name="arrayOfBoolean">
+ <xsd:sequence>
+ <xsd:element name="entry" type="xsd:boolean"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:complexType name="arrayOfDouble">
+ <xsd:sequence>
+ <xsd:element name="entry" type="xsd:double"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:complexType name="arrayOfFloat">
+ <xsd:sequence>
+ <xsd:element name="entry" type="xsd:float"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:complexType name="arrayOfInt">
+ <xsd:sequence>
+ <xsd:element name="entry" type="xsd:integer"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:complexType name="arrayOfShort">
+ <xsd:sequence>
+ <xsd:element name="entry" type="xsd:short"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:complexType name="echoWithSimpleTypeArraysRequest">
+ <xsd:sequence>
+ <xsd:element name="p1" type="qman:arrayOfLong"/>
+ <xsd:element name="p2" type="qman:arrayOfBoolean"/>
+ <xsd:element name="p3" type="qman:arrayOfDouble"/>
+ <xsd:element name="p4" type="qman:arrayOfFloat"/>
+ <xsd:element name="p5" type="qman:arrayOfInt"/>
+ <xsd:element name="p6" type="qman:arrayOfShort"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:complexType name="echoWithSimpleTypeArraysResponse">
+ <xsd:sequence>
+ <xsd:element name="result" type="qman:result"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:element name="echoWithByteArrayRequest" type="qman:echoWithByteArrayRequest"/>
+ <xsd:element
+ name="echoWithByteArrayResponse" type="qman:echoWithByteArrayResponse"/>
+ <xsd:complexType name="arrayOfByte">
+ <xsd:sequence>
+ <xsd:element name="entry" type=""/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:complexType name="echoWithByteArrayRequest">
+ <xsd:sequence>
+ <xsd:element name="p1" type="qman:arrayOfByte"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:complexType name="echoWithByteArrayResponse">
+ <xsd:sequence>
+ <xsd:element name="result" type="qman:result"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:element
+ name="voidWithoutArgumentsRequest" type="qman:voidWithoutArgumentsRequest"/>
+ <xsd:element
+ name="voidWithoutArgumentsResponse" type="qman:voidWithoutArgumentsResponse"/>
+ <xsd:complexType name="voidWithoutArgumentsRequest">
+ <xsd:sequence/>
+ </xsd:complexType>
+ <xsd:complexType name="voidWithoutArgumentsResponse">
+ <xsd:sequence>
+ <xsd:element name="result" type="qman:result"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:element name="throwsExceptionRequest" type="qman:throwsExceptionRequest"/>
+ <xsd:element name="throwsExceptionResponse" type="qman:throwsExceptionResponse"/>
+ <xsd:complexType name="throwsExceptionRequest">
+ <xsd:sequence/>
+ </xsd:complexType>
+ <xsd:complexType name="throwsExceptionResponse">
+ <xsd:sequence>
+ <xsd:element name="result" type="qman:result"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:element name="echoWithUUIDRequest" type="qman:echoWithUUIDRequest"/>
+ <xsd:element name="echoWithUUIDResponse" type="qman:echoWithUUIDResponse"/>
+ <xsd:complexType name="echoWithUUIDRequest">
+ <xsd:sequence>
+ <xsd:element name="p1" type="qman:uuid"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:complexType name="echoWithUUIDResponse">
+ <xsd:sequence>
+ <xsd:element name="result" type="qman:result"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:element name="echoWithMapRequest" type="qman:echoWithMapRequest"/>
+ <xsd:element name="echoWithMapResponse" type="qman:echoWithMapResponse"/>
+ <xsd:complexType name="echoWithMapRequest">
+ <xsd:sequence>
+ <xsd:element name="p1" type="qman:map"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:complexType name="echoWithMapResponse">
+ <xsd:sequence>
+ <xsd:element name="result" type="qman:result"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:schema>
+ <xsd:schema attributeFormDefault="unqualified"
+ elementFormDefault="qualified"
+ targetNamespace="http://docs.oasis-open.org/wsrf/bf-2"
+ xmlns="http://www.w3.org/2001/XMLSchema"
+ xmlns:wsa="http://www.w3.org/2005/08/addressing"
+ xmlns:wsrf-bf="http://docs.oasis-open.org/wsrf/bf-2"
+ xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <xsd:import namespace="http://www.w3.org/2005/08/addressing"/>
+ <xsd:import namespace="http://www.w3.org/XML/1998/namespace">
+ <xsd:annotation>
+ <xsd:documentation>
+ Get access to the xml: attribute groups for xml:lang as declared on 'schema'
+ and 'documentation' below
+ </xsd:documentation>
+ </xsd:annotation>
+ </xsd:import>
+ <xsd:element name="BaseFault" type="wsrf-bf:BaseFaultType"/>
+ <xsd:complexType name="BaseFaultType">
+ <xsd:sequence>
+ <xsd:any maxOccurs="unbounded"
+ minOccurs="0"
+ namespace="##other" processContents="lax"/>
+ <xsd:element maxOccurs="1"
+ minOccurs="1" name="Timestamp" type="xsd:dateTime"/>
+ <xsd:element maxOccurs="1"
+ minOccurs="0" name="Originator" type="wsa:EndpointReferenceType"/>
+ <xsd:element maxOccurs="1"
+ minOccurs="0" name="ErrorCode">
+ <xsd:complexType>
+ <xsd:complexContent mixed="true">
+ <xsd:extension base="xsd:anyType">
+ <xsd:attribute
+ name="dialect"
+ type="xsd:anyURI" use="required"/>
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element maxOccurs="unbounded"
+ minOccurs="0" name="Description">
+ <xsd:complexType>
+ <xsd:simpleContent>
+ <xsd:extension base="xsd:string">
+ <xsd:attribute
+ ref="xml:lang" use="optional"/>
+ </xsd:extension>
+ </xsd:simpleContent>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element maxOccurs="1"
+ minOccurs="0" name="FaultCause">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:any maxOccurs="1"
+ minOccurs="1"
+ namespace="##other" processContents="lax"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:sequence>
+ <xsd:anyAttribute namespace="##other" processContents="lax"/>
+ </xsd:complexType>
+ </xsd:schema>
+ <xs:schema
+ targetNamespace="http://www.w3.org/XML/1998/namespace"
+ xml:lang="en" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+ <xs:attribute name="lang" type="xs:language"/>
+ <xs:attribute default="preserve" name="space">
+ <xs:simpleType>
+ <xs:restriction base="xs:NCName">
+ <xs:enumeration value="default"/>
+ <xs:enumeration value="preserve"/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:attribute>
+ <xs:attribute name="base" type="xs:anyURI"/>
+ <xs:attributeGroup name="specialAttrs">
+ <xs:attribute ref="xml:base"/>
+ <xs:attribute ref="xml:lang"/>
+ <xs:attribute ref="xml:space"/>
+ </xs:attributeGroup>
+ </xs:schema>
+ </wsdl:types>
+ <wsdl:message name="GetMetadataMsg">
+ <wsdl:part element="wsx:GetMetadata" name="GetMetadataMsg"/>
+ </wsdl:message>
+ <wsdl:message name="GetMetadataResponseMsg">
+ <wsdl:part element="wsx:Metadata" name="GetMetadataResponseMsg"/>
+ </wsdl:message>
+ <wsdl:message name="DestroyRequest">
+ <wsdl:part element="wsrf-rl:Destroy" name="DestroyRequest"/>
+ </wsdl:message>
+ <wsdl:message name="DestroyResponse">
+ <wsdl:part element="wsrf-rl:DestroyResponse" name="DestroyResponse"/>
+ </wsdl:message>
+ <wsdl:message name="ResourceNotDestroyedFault">
+ <wsdl:part
+ element="wsrf-rl:ResourceNotDestroyedFault" name="ResourceNotDestroyedFault"/>
+ </wsdl:message>
+ <wsdl:message name="ResourceUnknownFault">
+ <wsdl:part element="wsrf-r:ResourceUnknownFault" name="ResourceUnknownFault"/>
+ </wsdl:message>
+ <wsdl:message name="ResourceUnavailableFault">
+ <wsdl:part
+ element="wsrf-r:ResourceUnavailableFault" name="ResourceUnavailableFault"/>
+ </wsdl:message>
+ <wsdl:message name="SetTerminationTimeRequest">
+ <wsdl:part element="wsrf-rl:SetTerminationTime" name="SetTerminationTimeRequest"/>
+ </wsdl:message>
+ <wsdl:message name="SetTerminationTimeResponse">
+ <wsdl:part
+ element="wsrf-rl:SetTerminationTimeResponse" name="SetTerminationTimeResponse"/>
+ </wsdl:message>
+ <wsdl:message name="UnableToSetTerminationTimeFault">
+ <wsdl:part
+ element="wsrf-rl:UnableToSetTerminationTimeFault" name="UnableToSetTerminationTimeFault"/>
+ </wsdl:message>
+ <wsdl:message name="TerminationTimeChangeRejectedFault">
+ <wsdl:part
+ element="wsrf-rl:TerminationTimeChangeRejectedFault" name="TerminationTimeChangeRejectedFault"/>
+ </wsdl:message>
+ <wsdl:message name="GetResourcePropertyDocumentRequest">
+ <wsdl:part
+ element="wsrf-rp:GetResourcePropertyDocument" name="GetResourcePropertyDocumentRequest"/>
+ </wsdl:message>
+ <wsdl:message name="GetResourcePropertyDocumentResponse">
+ <wsdl:part
+ element="wsrf-rp:GetResourcePropertyDocumentResponse" name="GetResourcePropertyDocumentResponse"/>
+ </wsdl:message>
+ <wsdl:message name="GetResourcePropertyRequest">
+ <wsdl:part element="wsrf-rp:GetResourceProperty" name="GetResourcePropertyRequest"/>
+ </wsdl:message>
+ <wsdl:message name="GetResourcePropertyResponse">
+ <wsdl:part
+ element="wsrf-rp:GetResourcePropertyResponse" name="GetResourcePropertyResponse"/>
+ </wsdl:message>
+ <wsdl:message name="InvalidResourcePropertyQNameFault">
+ <wsdl:part
+ element="wsrf-rp:InvalidResourcePropertyQNameFault" name="InvalidResourcePropertyQNameFault"/>
+ </wsdl:message>
+ <wsdl:message name="GetMultipleResourcePropertiesRequest">
+ <wsdl:part
+ element="wsrf-rp:GetMultipleResourceProperties" name="GetMultipleResourcePropertiesRequest"/>
+ </wsdl:message>
+ <wsdl:message name="GetMultipleResourcePropertiesResponse">
+ <wsdl:part
+ element="wsrf-rp:GetMultipleResourcePropertiesResponse" name="GetMultipleResourcePropertiesResponse"/>
+ </wsdl:message>
+ <wsdl:message name="QueryResourcePropertiesRequest">
+ <wsdl:part
+ element="wsrf-rp:QueryResourceProperties" name="QueryResourcePropertiesRequest"/>
+ </wsdl:message>
+ <wsdl:message name="QueryResourcePropertiesResponse">
+ <wsdl:part
+ element="wsrf-rp:QueryResourcePropertiesResponse" name="QueryResourcePropertiesResponse"/>
+ </wsdl:message>
+ <wsdl:message name="UnknownQueryExpressionDialectFault">
+ <wsdl:part
+ element="wsrf-rp:UnknownQueryExpressionDialectFault" name="UnknownQueryExpressionDialectFault"/>
+ </wsdl:message>
+ <wsdl:message name="InvalidQueryExpressionFault">
+ <wsdl:part
+ element="wsrf-rp:InvalidQueryExpressionFault" name="InvalidQueryExpressionFault"/>
+ </wsdl:message>
+ <wsdl:message name="QueryEvaluationErrorFault">
+ <wsdl:part
+ element="wsrf-rp:QueryEvaluationErrorFault" name="QueryEvaluationErrorFault"/>
+ </wsdl:message>
+ <wsdl:message name="SetResourcePropertiesRequest">
+ <wsdl:part
+ element="wsrf-rp:SetResourceProperties" name="SetResourcePropertiesRequest"/>
+ </wsdl:message>
+ <wsdl:message name="SetResourcePropertiesResponse">
+ <wsdl:part
+ element="wsrf-rp:SetResourcePropertiesResponse" name="SetResourcePropertiesResponse"/>
+ </wsdl:message>
+ <wsdl:message name="InvalidModificationFault">
+ <wsdl:part
+ element="wsrf-rp:InvalidModificationFault" name="InvalidModificationFault"/>
+ </wsdl:message>
+ <wsdl:message name="UnableToModifyResourcePropertyFault">
+ <wsdl:part
+ element="wsrf-rp:UnableToModifyResourcePropertyFault" name="UnableToModifyResourcePropertyFault"/>
+ </wsdl:message>
+ <wsdl:message name="SetResourcePropertyRequestFailedFault">
+ <wsdl:part
+ element="wsrf-rp:SetResourcePropertyRequestFailedFault" name="SetResourcePropertyRequestFailedFault"/>
+ </wsdl:message>
+ <wsdl:portType name="QManWsResourcePortType"
+ wsrf-rp:ResourceProperties="qman:QManWsResourceProperties"
+ wsrmd:Descriptor="QManWsResourceMetadata" wsrmd:DescriptorLocation="QManWsResource.rmd">
+ <wsdl:operation name="GetMetadata">
+ <wsdl:input message="qman:GetMetadataMsg"
+ name="GetMetadataMsg" wsa:Action="http://schemas.xmlsoap.org/ws/2004/09/mex/GetMetadata"/>
+ <wsdl:output
+ message="qman:GetMetadataResponseMsg"
+ name="GetMetadataResponseMsg" wsa:Action="http://schemas.xmlsoap.org/ws/2004/09/mex/GetMetadataResponse"/>
+ </wsdl:operation>
+ <wsdl:operation name="Destroy">
+ <wsdl:input message="qman:DestroyRequest"
+ name="DestroyRequest" wsa:Action="http://docs.oasis-open.org/wsrf/rlw-2/ImmediateResourceTermination/DestroyRequest"/>
+ <wsdl:output message="qman:DestroyResponse"
+ name="DestroyResponse" wsa:Action="http://docs.oasis-open.org/wsrf/rlw-2/ImmediateResourceTermination/DestroyResponse"/>
+ <wsdl:fault
+ message="qman:ResourceNotDestroyedFault" name="ResourceNotDestroyedFault"/>
+ <wsdl:fault
+ message="qman:ResourceUnknownFault" name="ResourceUnknownFault"/>
+ <wsdl:fault
+ message="qman:ResourceUnavailableFault" name="ResourceUnavailableFault"/>
+ </wsdl:operation>
+ <wsdl:operation name="SetTerminationTime">
+ <wsdl:input
+ message="qman:SetTerminationTimeRequest"
+ name="SetTerminationTimeRequest" wsa:Action="http://docs.oasis-open.org/wsrf/rlw-2/ScheduledResourceTermination/SetTerminationTimeRequest"/>
+ <wsdl:output
+ message="qman:SetTerminationTimeResponse"
+ name="SetTerminationTimeResponse" wsa:Action="http://docs.oasis-open.org/wsrf/rlw-2/ScheduledResourceTermination/SetTerminationTimeResponse"/>
+ <wsdl:fault
+ message="qman:UnableToSetTerminationTimeFault" name="UnableToSetTerminationTimeFault"/>
+ <wsdl:fault
+ message="qman:ResourceUnknownFault" name="ResourceUnknownFault"/>
+ <wsdl:fault
+ message="qman:ResourceUnavailableFault" name="ResourceUnavailableFault"/>
+ <wsdl:fault
+ message="qman:TerminationTimeChangeRejectedFault" name="TerminationTimeChangeRejectedFault"/>
+ </wsdl:operation>
+ <wsdl:operation name="GetResourcePropertyDocument">
+ <wsdl:input
+ message="qman:GetResourcePropertyDocumentRequest"
+ name="GetResourcePropertyDocumentRequest" wsa:Action="http://docs.oasis-open.org/wsrf/rpw-2/GetResourcePropertyDocument/GetResourcePropertyDocumentRequest"/>
+ <wsdl:output
+ message="qman:GetResourcePropertyDocumentResponse"
+ name="GetResourcePropertyDocumentResponse" wsa:Action="http://docs.oasis-open.org/wsrf/rpw-2/GetResourcePropertyDocument/GetResourcePropertyDocumentResponse"/>
+ <wsdl:fault
+ message="qman:ResourceUnknownFault" name="ResourceUnknownFault"/>
+ <wsdl:fault
+ message="qman:ResourceUnavailableFault" name="ResourceUnavailableFault"/>
+ </wsdl:operation>
+ <wsdl:operation name="GetResourceProperty">
+ <wsdl:input
+ message="qman:GetResourcePropertyRequest"
+ name="GetResourcePropertyRequest" wsa:Action="http://docs.oasis-open.org/wsrf/rpw-2/GetResourceProperty/GetResourcePropertyRequest"/>
+ <wsdl:output
+ message="qman:GetResourcePropertyResponse"
+ name="GetResourcePropertyResponse" wsa:Action="http://docs.oasis-open.org/wsrf/rpw-2/GetResourceProperty/GetResourcePropertyResponse"/>
+ <wsdl:fault
+ message="qman:ResourceUnknownFault" name="ResourceUnknownFault"/>
+ <wsdl:fault
+ message="qman:ResourceUnavailableFault" name="ResourceUnavailableFault"/>
+ <wsdl:fault
+ message="qman:InvalidResourcePropertyQNameFault" name="InvalidResourcePropertyQNameFault"/>
+ </wsdl:operation>
+ <wsdl:operation name="GetMultipleResourceProperties">
+ <wsdl:input
+ message="qman:GetMultipleResourcePropertiesRequest"
+ name="GetMultipleResourcePropertiesRequest" wsa:Action="http://docs.oasis-open.org/wsrf/rpw-2/GetMultipleResourceProperties/GetMultipleResourcePropertiesRequest"/>
+ <wsdl:output
+ message="qman:GetMultipleResourcePropertiesResponse"
+ name="GetMultipleResourcePropertiesResponse" wsa:Action="http://docs.oasis-open.org/wsrf/rpw-2/GetMultipleResourceProperties/GetMultipleResourcePropertiesResponse"/>
+ <wsdl:fault
+ message="qman:ResourceUnknownFault" name="ResourceUnknownFault"/>
+ <wsdl:fault
+ message="qman:ResourceUnavailableFault" name="ResourceUnavailableFault"/>
+ <wsdl:fault
+ message="qman:InvalidResourcePropertyQNameFault" name="InvalidResourcePropertyQNameFault"/>
+ </wsdl:operation>
+ <wsdl:operation name="QueryResourceProperties">
+ <wsdl:input
+ message="qman:QueryResourcePropertiesRequest"
+ name="QueryResourcePropertiesRequest" wsa:Action="http://docs.oasis-open.org/wsrf/rpw-2/QueryResourceProperties/QueryResourcePropertiesRequest"/>
+ <wsdl:output
+ message="qman:QueryResourcePropertiesResponse"
+ name="QueryResourcePropertiesResponse" wsa:Action="http://docs.oasis-open.org/wsrf/rpw-2/QueryResourceProperties/QueryResourcePropertiesResponse"/>
+ <wsdl:fault
+ message="qman:ResourceUnknownFault" name="ResourceUnknownFault"/>
+ <wsdl:fault
+ message="qman:ResourceUnavailableFault" name="ResourceUnavailableFault"/>
+ <wsdl:fault
+ message="qman:UnknownQueryExpressionDialectFault" name="UnknownQueryExpressionDialectFault"/>
+ <wsdl:fault
+ message="qman:InvalidQueryExpressionFault" name="InvalidQueryExpressionFault"/>
+ <wsdl:fault
+ message="qman:QueryEvaluationErrorFault" name="QueryEvaluationErrorFault"/>
+ </wsdl:operation>
+ <wsdl:operation name="SetResourceProperties">
+ <wsdl:input
+ message="qman:SetResourcePropertiesRequest"
+ name="SetResourcePropertiesRequest" wsa:Action="http://docs.oasis-open.org/wsrf/rpw-2/SetResourceProperties/SetResourcePropertiesRequest"/>
+ <wsdl:output
+ message="qman:SetResourcePropertiesResponse"
+ name="SetResourcePropertiesResponse" wsa:Action="http://docs.oasis-open.org/wsrf/rpw-2/SetResourceProperties/SetResourcePropertiesResponse"/>
+ <wsdl:fault
+ message="qman:ResourceUnknownFault" name="ResourceUnknownFault"/>
+ <wsdl:fault
+ message="qman:ResourceUnavailableFault" name="ResourceUnavailableFault"/>
+ <wsdl:fault
+ message="qman:InvalidModificationFault" name="InvalidModificationFault"/>
+ <wsdl:fault
+ message="qman:UnableToModifyResourcePropertyFault" name="UnableToModifyResourcePropertyFault"/>
+ <wsdl:fault
+ message="qman:InvalidResourcePropertyQNameFault" name="InvalidResourcePropertyQNameFault"/>
+ <wsdl:fault
+ message="qman:SetResourcePropertyRequestFailedFault" name="SetResourcePropertyRequestFailedFault"/>
+ </wsdl:operation>
+ <wsdl:operation name="echoWithSimpleTypes">
+ <wsdl:input
+ message="qman:echoWithSimpleTypesRequestMessage"
+ name="echoWithSimpleTypesRequest" wsa:action="http://amqp.apache.org/qpid/management/qman/echoWithSimpleTypes"/>
+ <wsdl:output
+ message="qman:echoWithSimpleTypesResponseMessage"
+ name="echoWithSimpleTypesResponse" wsa:action="http://amqp.apache.org/qpid/management/qman/echoWithSimpleTypesResponse"/>
+ </wsdl:operation>
+ <wsdl:operation name="echoWithArrays">
+ <wsdl:input
+ message="qman:echoWithArraysRequestMessage"
+ name="echoWithArraysRequest" wsa:action="http://amqp.apache.org/qpid/management/qman/echoWithArrays"/>
+ <wsdl:output
+ message="qman:echoWithArraysResponseMessage"
+ name="echoWithArraysResponse" wsa:action="http://amqp.apache.org/qpid/management/qman/echoWithArraysResponse"/>
+ </wsdl:operation>
+ <wsdl:operation name="echoWithSimpleTypeArrays">
+ <wsdl:input
+ message="qman:echoWithSimpleTypeArraysRequestMessage"
+ name="echoWithSimpleTypeArraysRequest" wsa:action="http://amqp.apache.org/qpid/management/qman/echoWithSimpleTypeArrays"/>
+ <wsdl:output
+ message="qman:echoWithSimpleTypeArraysResponseMessage"
+ name="echoWithSimpleTypeArraysResponse" wsa:action="http://amqp.apache.org/qpid/management/qman/echoWithSimpleTypeArraysResponse"/>
+ </wsdl:operation>
+ <wsdl:operation name="echoWithByteArray">
+ <wsdl:input
+ message="qman:echoWithByteArrayRequestMessage"
+ name="echoWithByteArrayRequest" wsa:action="http://amqp.apache.org/qpid/management/qman/echoWithByteArray"/>
+ <wsdl:output
+ message="qman:echoWithByteArrayResponseMessage"
+ name="echoWithByteArrayResponse" wsa:action="http://amqp.apache.org/qpid/management/qman/echoWithByteArrayResponse"/>
+ </wsdl:operation>
+ <wsdl:operation name="voidWithoutArguments">
+ <wsdl:input
+ message="qman:voidWithoutArgumentsRequestMessage"
+ name="voidWithoutArgumentsRequest" wsa:action="http://amqp.apache.org/qpid/management/qman/voidWithoutArguments"/>
+ <wsdl:output
+ message="qman:voidWithoutArgumentsResponseMessage"
+ name="voidWithoutArgumentsResponse" wsa:action="http://amqp.apache.org/qpid/management/qman/voidWithoutArgumentsResponse"/>
+ </wsdl:operation>
+ <wsdl:operation name="throwsException">
+ <wsdl:input
+ message="qman:throwsExceptionRequestMessage"
+ name="throwsExceptionRequest" wsa:action="http://amqp.apache.org/qpid/management/qman/throwsException"/>
+ <wsdl:output
+ message="qman:throwsExceptionResponseMessage"
+ name="throwsExceptionResponse" wsa:action="http://amqp.apache.org/qpid/management/qman/throwsExceptionResponse"/>
+ </wsdl:operation>
+ <wsdl:operation name="echoWithUUID">
+ <wsdl:input
+ message="qman:echoWithUUIDRequestMessage"
+ name="echoWithUUIDRequest" wsa:action="http://amqp.apache.org/qpid/management/qman/echoWithUUID"/>
+ <wsdl:output
+ message="qman:echoWithUUIDResponseMessage"
+ name="echoWithUUIDResponse" wsa:action="http://amqp.apache.org/qpid/management/qman/echoWithUUIDResponse"/>
+ </wsdl:operation>
+ <wsdl:operation name="echoWithMap">
+ <wsdl:input
+ message="qman:echoWithMapRequestMessage"
+ name="echoWithMapRequest" wsa:action="http://amqp.apache.org/qpid/management/qman/echoWithMap"/>
+ <wsdl:output
+ message="qman:echoWithMapResponseMessage"
+ name="echoWithMapResponse" wsa:action="http://amqp.apache.org/qpid/management/qman/echoWithMapResponse"/>
+ </wsdl:operation>
+ </wsdl:portType>
+ <wsdl:binding name="QManWsResourceBinding" type="qman:QManWsResourcePortType">
+ <wsdl-soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
+ <wsdl:operation name="GetMetadata">
+ <wsdl-soap:operation soapAction="GetMetadata"/>
+ <wsdl:input>
+ <wsdl-soap:body
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" use="literal"/>
+ </wsdl:input>
+ <wsdl:output>
+ <wsdl-soap:body
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+ <wsdl:operation name="Destroy">
+ <wsdl-soap:operation soapAction="Destroy"/>
+ <wsdl:input name="DestroyRequest">
+ <wsdl-soap:body
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" use="literal"/>
+ </wsdl:input>
+ <wsdl:output name="DestroyResponse">
+ <wsdl-soap:body
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" use="literal"/>
+ </wsdl:output>
+ <wsdl:fault name="ResourceNotDestroyedFault">
+ <wsdl-soap:fault
+ name="ResourceNotDestroyedFault" use="literal"/>
+ </wsdl:fault>
+ <wsdl:fault name="ResourceUnknownFault">
+ <wsdl-soap:fault
+ name="ResourceUnknownFault" use="literal"/>
+ </wsdl:fault>
+ <wsdl:fault name="ResourceUnavailableFault">
+ <wsdl-soap:fault
+ name="ResourceUnavailableFault" use="literal"/>
+ </wsdl:fault>
+ </wsdl:operation>
+ <wsdl:operation name="SetTerminationTime">
+ <wsdl-soap:operation soapAction="SetTerminationTime"/>
+ <wsdl:input name="SetTerminationTimeRequest">
+ <wsdl-soap:body
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" use="literal"/>
+ </wsdl:input>
+ <wsdl:output name="SetTerminationTimeResponse">
+ <wsdl-soap:body
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" use="literal"/>
+ </wsdl:output>
+ <wsdl:fault name="UnableToSetTerminationTimeFault">
+ <wsdl-soap:fault
+ name="UnableToSetTerminationTimeFault" use="literal"/>
+ </wsdl:fault>
+ <wsdl:fault name="ResourceUnknownFault">
+ <wsdl-soap:fault
+ name="ResourceUnknownFault" use="literal"/>
+ </wsdl:fault>
+ <wsdl:fault name="ResourceUnavailableFault">
+ <wsdl-soap:fault
+ name="ResourceUnavailableFault" use="literal"/>
+ </wsdl:fault>
+ <wsdl:fault name="TerminationTimeChangeRejectedFault">
+ <wsdl-soap:fault
+ name="TerminationTimeChangeRejectedFault" use="literal"/>
+ </wsdl:fault>
+ </wsdl:operation>
+ <wsdl:operation name="GetResourcePropertyDocument">
+ <wsdl-soap:operation soapAction="GetResourcePropertyDocument"/>
+ <wsdl:input name="GetResourcePropertyDocumentRequest">
+ <wsdl-soap:body
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" use="literal"/>
+ </wsdl:input>
+ <wsdl:output name="GetResourcePropertyDocumentResponse">
+ <wsdl-soap:body
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" use="literal"/>
+ </wsdl:output>
+ <wsdl:fault name="ResourceUnknownFault">
+ <wsdl-soap:fault
+ name="ResourceUnknownFault" use="literal"/>
+ </wsdl:fault>
+ <wsdl:fault name="ResourceUnavailableFault">
+ <wsdl-soap:fault
+ name="ResourceUnavailableFault" use="literal"/>
+ </wsdl:fault>
+ </wsdl:operation>
+ <wsdl:operation name="GetResourceProperty">
+ <wsdl-soap:operation soapAction="GetResourceProperty"/>
+ <wsdl:input name="GetResourcePropertyRequest">
+ <wsdl-soap:body
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" use="literal"/>
+ </wsdl:input>
+ <wsdl:output name="GetResourcePropertyResponse">
+ <wsdl-soap:body
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" use="literal"/>
+ </wsdl:output>
+ <wsdl:fault name="ResourceUnknownFault">
+ <wsdl-soap:fault
+ name="ResourceUnknownFault" use="literal"/>
+ </wsdl:fault>
+ <wsdl:fault name="ResourceUnavailableFault">
+ <wsdl-soap:fault
+ name="ResourceUnavailableFault" use="literal"/>
+ </wsdl:fault>
+ <wsdl:fault name="InvalidResourcePropertyQNameFault">
+ <wsdl-soap:fault
+ name="InvalidResourcePropertyQNameFault" use="literal"/>
+ </wsdl:fault>
+ </wsdl:operation>
+ <wsdl:operation name="GetMultipleResourceProperties">
+ <wsdl-soap:operation soapAction="GetMultipleResourceProperties"/>
+ <wsdl:input name="GetMultipleResourcePropertiesRequest">
+ <wsdl-soap:body
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" use="literal"/>
+ </wsdl:input>
+ <wsdl:output name="GetMultipleResourcePropertiesResponse">
+ <wsdl-soap:body
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" use="literal"/>
+ </wsdl:output>
+ <wsdl:fault name="ResourceUnknownFault">
+ <wsdl-soap:fault
+ name="ResourceUnknownFault" use="literal"/>
+ </wsdl:fault>
+ <wsdl:fault name="ResourceUnavailableFault">
+ <wsdl-soap:fault
+ name="ResourceUnavailableFault" use="literal"/>
+ </wsdl:fault>
+ <wsdl:fault name="InvalidResourcePropertyQNameFault">
+ <wsdl-soap:fault
+ name="InvalidResourcePropertyQNameFault" use="literal"/>
+ </wsdl:fault>
+ </wsdl:operation>
+ <wsdl:operation name="QueryResourceProperties">
+ <wsdl-soap:operation soapAction="QueryResourceProperties"/>
+ <wsdl:input name="QueryResourcePropertiesRequest">
+ <wsdl-soap:body
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" use="literal"/>
+ </wsdl:input>
+ <wsdl:output name="QueryResourcePropertiesResponse">
+ <wsdl-soap:body
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" use="literal"/>
+ </wsdl:output>
+ <wsdl:fault name="ResourceUnknownFault">
+ <wsdl-soap:fault
+ name="ResourceUnknownFault" use="literal"/>
+ </wsdl:fault>
+ <wsdl:fault name="ResourceUnavailableFault">
+ <wsdl-soap:fault
+ name="ResourceUnavailableFault" use="literal"/>
+ </wsdl:fault>
+ <wsdl:fault name="UnknownQueryExpressionDialectFault">
+ <wsdl-soap:fault
+ name="UnknownQueryExpressionDialectFault" use="literal"/>
+ </wsdl:fault>
+ <wsdl:fault name="InvalidQueryExpressionFault">
+ <wsdl-soap:fault
+ name="InvalidQueryExpressionFault" use="literal"/>
+ </wsdl:fault>
+ <wsdl:fault name="QueryEvaluationErrorFault">
+ <wsdl-soap:fault
+ name="QueryEvaluationErrorFault" use="literal"/>
+ </wsdl:fault>
+ </wsdl:operation>
+ <wsdl:operation name="SetResourceProperties">
+ <wsdl-soap:operation soapAction="http://oasis.org/SetResourceProperties"/>
+ <wsdl:input name="SetResourcePropertiesRequest">
+ <wsdl-soap:body
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" use="literal"/>
+ </wsdl:input>
+ <wsdl:output name="SetResourcePropertiesResponse">
+ <wsdl-soap:body
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" use="literal"/>
+ </wsdl:output>
+ <wsdl:fault name="ResourceUnknownFault">
+ <wsdl-soap:fault
+ name="ResourceUnknownFault" use="literal"/>
+ </wsdl:fault>
+ <wsdl:fault name="ResourceUnavailableFault">
+ <wsdl-soap:fault
+ name="ResourceUnavailableFault" use="literal"/>
+ </wsdl:fault>
+ <wsdl:fault name="InvalidModificationFault">
+ <wsdl-soap:fault
+ name="InvalidModificationFault" use="literal"/>
+ </wsdl:fault>
+ <wsdl:fault name="UnableToModifyResourcePropertyFault">
+ <wsdl-soap:fault
+ name="UnableToModifyResourcePropertyFault" use="literal"/>
+ </wsdl:fault>
+ <wsdl:fault name="InvalidResourcePropertyQNameFault">
+ <wsdl-soap:fault
+ name="InvalidResourcePropertyQNameFault" use="literal"/>
+ </wsdl:fault>
+ <wsdl:fault name="SetResourcePropertyRequestFailedFault">
+ <wsdl-soap:fault
+ name="SetResourcePropertyRequestFailedFault" use="literal"/>
+ </wsdl:fault>
+ </wsdl:operation>
+ <wsdl:operation name="GetMetadata">
+ <wsdl-soap:operation soapAction="http://ws.apache.org/muse/test/wsrf/GetMetadata"/>
+ <wsdl:input name="GetMetadataMsg">
+ <wsdl-soap:body
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" use="literal"/>
+ </wsdl:input>
+ <wsdl:output name="GetMetadataResponseMsg">
+ <wsdl-soap:body
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+ <wsdl:operation name="echoWithSimpleTypes">
+ <wsdl-soap:operation soapAction="http://amqp.apache.org/qpid/management/qman/echoWithSimpleTypes"/>
+ <wsdl:input>
+ <wsdl-soap:body use="literal"/>
+ </wsdl:input>
+ <wsdl:output>
+ <wsdl-soap:body use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+ <wsdl:operation name="echoWithArrays">
+ <wsdl-soap:operation soapAction="http://amqp.apache.org/qpid/management/qman/echoWithArrays"/>
+ <wsdl:input>
+ <wsdl-soap:body use="literal"/>
+ </wsdl:input>
+ <wsdl:output>
+ <wsdl-soap:body use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+ <wsdl:operation name="echoWithSimpleTypeArrays">
+ <wsdl-soap:operation soapAction="http://amqp.apache.org/qpid/management/qman/echoWithSimpleTypeArrays"/>
+ <wsdl:input>
+ <wsdl-soap:body use="literal"/>
+ </wsdl:input>
+ <wsdl:output>
+ <wsdl-soap:body use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+ <wsdl:operation name="echoWithByteArray">
+ <wsdl-soap:operation soapAction="http://amqp.apache.org/qpid/management/qman/echoWithByteArray"/>
+ <wsdl:input>
+ <wsdl-soap:body use="literal"/>
+ </wsdl:input>
+ <wsdl:output>
+ <wsdl-soap:body use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+ <wsdl:operation name="voidWithoutArguments">
+ <wsdl-soap:operation soapAction="http://amqp.apache.org/qpid/management/qman/voidWithoutArguments"/>
+ <wsdl:input>
+ <wsdl-soap:body use="literal"/>
+ </wsdl:input>
+ <wsdl:output>
+ <wsdl-soap:body use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+ <wsdl:operation name="throwsException">
+ <wsdl-soap:operation soapAction="http://amqp.apache.org/qpid/management/qman/throwsException"/>
+ <wsdl:input>
+ <wsdl-soap:body use="literal"/>
+ </wsdl:input>
+ <wsdl:output>
+ <wsdl-soap:body use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+ <wsdl:operation name="echoWithUUID">
+ <wsdl-soap:operation soapAction="http://amqp.apache.org/qpid/management/qman/echoWithUUID"/>
+ <wsdl:input>
+ <wsdl-soap:body use="literal"/>
+ </wsdl:input>
+ <wsdl:output>
+ <wsdl-soap:body use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+ <wsdl:operation name="echoWithMap">
+ <wsdl-soap:operation soapAction="http://amqp.apache.org/qpid/management/qman/echoWithMap"/>
+ <wsdl:input>
+ <wsdl-soap:body use="literal"/>
+ </wsdl:input>
+ <wsdl:output>
+ <wsdl-soap:body use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+ </wsdl:binding>
+ <wsdl:service name="QManWsResourceService">
+ <wsdl:port binding="qman:QManWsResourceBinding" name="QManWsResourcePort">
+ <wsdl-soap:address location="http://romagazzarini:8080/qman/services/QManWsResource"/>
+ </wsdl:port>
+ </wsdl:service>
+ <message name="echoWithSimpleTypesRequestMessage">
+ <wsdl:part
+ element="qman:echoWithSimpleTypesRequest" name="echoWithSimpleTypesRequest"/>
+ </message>
+ <wsdl:message name="echoWithSimpleTypesResponseMessage">
+ <wsdl:part
+ element="qman:echoWithSimpleTypesResponse" name="echoWithSimpleTypesResponse"/>
+ </wsdl:message>
+ <message name="echoWithArraysRequestMessage">
+ <wsdl:part element="qman:echoWithArraysRequest" name="echoWithArraysRequest"/>
+ </message>
+ <wsdl:message name="echoWithArraysResponseMessage">
+ <wsdl:part element="qman:echoWithArraysResponse" name="echoWithArraysResponse"/>
+ </wsdl:message>
+ <message name="echoWithSimpleTypeArraysRequestMessage">
+ <wsdl:part
+ element="qman:echoWithSimpleTypeArraysRequest" name="echoWithSimpleTypeArraysRequest"/>
+ </message>
+ <wsdl:message name="echoWithSimpleTypeArraysResponseMessage">
+ <wsdl:part
+ element="qman:echoWithSimpleTypeArraysResponse" name="echoWithSimpleTypeArraysResponse"/>
+ </wsdl:message>
+ <message name="echoWithByteArrayRequestMessage">
+ <wsdl:part
+ element="qman:echoWithByteArrayRequest" name="echoWithByteArrayRequest"/>
+ </message>
+ <wsdl:message name="echoWithByteArrayResponseMessage">
+ <wsdl:part
+ element="qman:echoWithByteArrayResponse" name="echoWithByteArrayResponse"/>
+ </wsdl:message>
+ <message name="voidWithoutArgumentsRequestMessage">
+ <wsdl:part
+ element="qman:voidWithoutArgumentsRequest" name="voidWithoutArgumentsRequest"/>
+ </message>
+ <wsdl:message name="voidWithoutArgumentsResponseMessage">
+ <wsdl:part
+ element="qman:voidWithoutArgumentsResponse" name="voidWithoutArgumentsResponse"/>
+ </wsdl:message>
+ <message name="throwsExceptionRequestMessage">
+ <wsdl:part element="qman:throwsExceptionRequest" name="throwsExceptionRequest"/>
+ </message>
+ <wsdl:message name="throwsExceptionResponseMessage">
+ <wsdl:part
+ element="qman:throwsExceptionResponse" name="throwsExceptionResponse"/>
+ </wsdl:message>
+ <message name="echoWithUUIDRequestMessage">
+ <wsdl:part element="qman:echoWithUUIDRequest" name="echoWithUUIDRequest"/>
+ </message>
+ <wsdl:message name="echoWithUUIDResponseMessage">
+ <wsdl:part element="qman:echoWithUUIDResponse" name="echoWithUUIDResponse"/>
+ </wsdl:message>
+ <message name="echoWithMapRequestMessage">
+ <wsdl:part element="qman:echoWithMapRequest" name="echoWithMapRequest"/>
+ </message>
+ <wsdl:message name="echoWithMapResponseMessage">
+ <wsdl:part element="qman:echoWithMapResponse" name="echoWithMapResponse"/>
+ </wsdl:message>
+ </wsdl:definitions>
+ </wsx:MetadataSection>
+ </wsx:Metadata>
+ </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://localhost:8080/qman/services/QManWsResource</wsa:To>
+ <wsa:Action xmlns:wsa="http://www.w3.org/2005/08/addressing">http://docs.oasis-open.org/wsrf/rpw-2/GetResourceProperty/GetResourcePropertyRequest</wsa:Action>
+ <wsa:MessageID xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:103f564f-7008-8456-042f-095a092444f9</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">Q-MAN: brokerID=0ef67394-e34a-4bff-b0bf-88cf359ba1a0,class=queue,name=1232966356552,objectId=894cddd3-b893-4e2f-94d2-2489f72cbdd6,package=org.apache.qpid</qman-wsa:ResourceId>
+ </soap:Header>
+ <soap:Body>
+ <wsrf-rp:GetResourceProperty
+ xmlns:wsrf-rp="http://docs.oasis-open.org/wsrf/rp-2" xmlns:qman="http://amqp.apache.org/qpid/management/qman">qman:MgmtPubInterval</wsrf-rp:GetResourceProperty>
+ </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/wsrf/rpw-2/GetResourceProperty/GetResourcePropertyResponse</wsa:Action>
+ <wsa:MessageID xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:b78625a8-af2f-b542-8001-d7e81d3de1c9</wsa:MessageID>
+ <wsa:RelatesTo RelationshipType="wsa:Reply" xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:103f564f-7008-8456-042f-095a092444f9</wsa:RelatesTo>
+ <wsa:From xmlns:wsa="http://www.w3.org/2005/08/addressing">
+ <wsa:Address>http://localhost:8080/qman/services/QManWsResource</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">Q-MAN: brokerID=0ef67394-e34a-4bff-b0bf-88cf359ba1a0,class=queue,name=1232966356552,objectId=894cddd3-b893-4e2f-94d2-2489f72cbdd6,package=org.apache.qpid</qman-wsa:ResourceId>
+ </wsa:ReferenceParameters>
+ </wsa:From>
+ </soap:Header>
+ <soap:Body>
+ <wsrf-rp:GetResourcePropertyResponse xmlns:wsrf-rp="http://docs.oasis-open.org/wsrf/rp-2">
+ <qman:MgmtPubInterval xmlns:qman="http://amqp.apache.org/qpid/management/qman">32767</qman:MgmtPubInterval>
+ </wsrf-rp:GetResourcePropertyResponse>
+ </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://localhost:8080/qman/services/QManWsResource</wsa:To>
+ <wsa:Action xmlns:wsa="http://www.w3.org/2005/08/addressing">http://docs.oasis-open.org/wsrf/rpw-2/SetResourceProperties/SetResourcePropertiesRequest</wsa:Action>
+ <wsa:MessageID xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:0b80a9ca-9e02-1d6b-c0e0-8ceb8560ee6e</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">Q-MAN: brokerID=0ef67394-e34a-4bff-b0bf-88cf359ba1a0,class=queue,name=1232966356552,objectId=894cddd3-b893-4e2f-94d2-2489f72cbdd6,package=org.apache.qpid</qman-wsa:ResourceId>
+ </soap:Header>
+ <soap:Body>
+ <wsrf-rp:SetResourceProperties xmlns:wsrf-rp="http://docs.oasis-open.org/wsrf/rp-2">
+ <wsrf-rp:Update>
+ <qman:MgmtPubInterval xmlns:qman="http://amqp.apache.org/qpid/management/qman">12</qman:MgmtPubInterval>
+ </wsrf-rp:Update>
+ </wsrf-rp:SetResourceProperties>
+ </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/wsrf/rpw-2/SetResourceProperties/SetResourcePropertiesResponse</wsa:Action>
+ <wsa:MessageID xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:ae67ff51-e1c1-f2c3-5243-d54905f3907b</wsa:MessageID>
+ <wsa:RelatesTo RelationshipType="wsa:Reply" xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:0b80a9ca-9e02-1d6b-c0e0-8ceb8560ee6e</wsa:RelatesTo>
+ <wsa:From xmlns:wsa="http://www.w3.org/2005/08/addressing">
+ <wsa:Address>http://localhost:8080/qman/services/QManWsResource</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">Q-MAN: brokerID=0ef67394-e34a-4bff-b0bf-88cf359ba1a0,class=queue,name=1232966356552,objectId=894cddd3-b893-4e2f-94d2-2489f72cbdd6,package=org.apache.qpid</qman-wsa:ResourceId>
+ </wsa:ReferenceParameters>
+ </wsa:From>
+ </soap:Header>
+ <soap:Body>
+ <wsrf-rp:SetResourcePropertiesResponse xmlns:wsrf-rp="http://docs.oasis-open.org/wsrf/rp-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://localhost:8080/qman/services/QManWsResource</wsa:To>
+ <wsa:Action xmlns:wsa="http://www.w3.org/2005/08/addressing">http://docs.oasis-open.org/wsrf/rpw-2/GetResourceProperty/GetResourcePropertyRequest</wsa:Action>
+ <wsa:MessageID xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:0dca61e4-072f-3091-0f38-9a967f14666a</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">Q-MAN: brokerID=0ef67394-e34a-4bff-b0bf-88cf359ba1a0,class=queue,name=1232966356552,objectId=894cddd3-b893-4e2f-94d2-2489f72cbdd6,package=org.apache.qpid</qman-wsa:ResourceId>
+ </soap:Header>
+ <soap:Body>
+ <wsrf-rp:GetResourceProperty
+ xmlns:wsrf-rp="http://docs.oasis-open.org/wsrf/rp-2" xmlns:qman="http://amqp.apache.org/qpid/management/qman">qman:MgmtPubInterval</wsrf-rp:GetResourceProperty>
+ </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/wsrf/rpw-2/GetResourceProperty/GetResourcePropertyResponse</wsa:Action>
+ <wsa:MessageID xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:84399474-c5b1-8738-f410-fd86face1599</wsa:MessageID>
+ <wsa:RelatesTo RelationshipType="wsa:Reply" xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:0dca61e4-072f-3091-0f38-9a967f14666a</wsa:RelatesTo>
+ <wsa:From xmlns:wsa="http://www.w3.org/2005/08/addressing">
+ <wsa:Address>http://localhost:8080/qman/services/QManWsResource</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">Q-MAN: brokerID=0ef67394-e34a-4bff-b0bf-88cf359ba1a0,class=queue,name=1232966356552,objectId=894cddd3-b893-4e2f-94d2-2489f72cbdd6,package=org.apache.qpid</qman-wsa:ResourceId>
+ </wsa:ReferenceParameters>
+ </wsa:From>
+ </soap:Header>
+ <soap:Body>
+ <wsrf-rp:GetResourcePropertyResponse xmlns:wsrf-rp="http://docs.oasis-open.org/wsrf/rp-2">
+ <qman:MgmtPubInterval xmlns:qman="http://amqp.apache.org/qpid/management/qman">12</qman:MgmtPubInterval>
+ </wsrf-rp:GetResourcePropertyResponse>
+ </soap:Body>
+</soap:Envelope>
+
+----------------------------------------------------------------------------------
+Resource has been correctly updated.
+----------------------------------------------------------------------------------
+[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://localhost:8080/qman/services/QManWsResource</wsa:To>
+ <wsa:Action xmlns:wsa="http://www.w3.org/2005/08/addressing">http://docs.oasis-open.org/wsrf/rpw-2/GetResourceProperty/GetResourcePropertyRequest</wsa:Action>
+ <wsa:MessageID xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:8be37e48-b3a5-0e4a-aea3-eda3aad58418</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">Q-MAN: brokerID=0ef67394-e34a-4bff-b0bf-88cf359ba1a0,class=queue,name=1232966356552,objectId=894cddd3-b893-4e2f-94d2-2489f72cbdd6,package=org.apache.qpid</qman-wsa:ResourceId>
+ </soap:Header>
+ <soap:Body>
+ <wsrf-rp:GetResourceProperty
+ xmlns:wsrf-rp="http://docs.oasis-open.org/wsrf/rp-2" xmlns:qman="http://amqp.apache.org/qpid/management/qman">qman:Type</wsrf-rp:GetResourceProperty>
+ </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/wsrf/rpw-2/GetResourceProperty/GetResourcePropertyResponse</wsa:Action>
+ <wsa:MessageID xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:b92c8851-d071-204f-6506-3706694cf32e</wsa:MessageID>
+ <wsa:RelatesTo RelationshipType="wsa:Reply" xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:8be37e48-b3a5-0e4a-aea3-eda3aad58418</wsa:RelatesTo>
+ <wsa:From xmlns:wsa="http://www.w3.org/2005/08/addressing">
+ <wsa:Address>http://localhost:8080/qman/services/QManWsResource</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">Q-MAN: brokerID=0ef67394-e34a-4bff-b0bf-88cf359ba1a0,class=queue,name=1232966356552,objectId=894cddd3-b893-4e2f-94d2-2489f72cbdd6,package=org.apache.qpid</qman-wsa:ResourceId>
+ </wsa:ReferenceParameters>
+ </wsa:From>
+ </soap:Header>
+ <soap:Body>
+ <wsrf-rp:GetResourcePropertyResponse xmlns:wsrf-rp="http://docs.oasis-open.org/wsrf/rp-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://localhost:8080/qman/services/QManWsResource</wsa:To>
+ <wsa:Action xmlns:wsa="http://www.w3.org/2005/08/addressing">http://docs.oasis-open.org/wsrf/rpw-2/SetResourceProperties/SetResourcePropertiesRequest</wsa:Action>
+ <wsa:MessageID xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:7917abf6-5c85-7e25-4515-b7f60cd32c39</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">Q-MAN: brokerID=0ef67394-e34a-4bff-b0bf-88cf359ba1a0,class=queue,name=1232966356552,objectId=894cddd3-b893-4e2f-94d2-2489f72cbdd6,package=org.apache.qpid</qman-wsa:ResourceId>
+ </soap:Header>
+ <soap:Body>
+ <wsrf-rp:SetResourceProperties xmlns:wsrf-rp="http://docs.oasis-open.org/wsrf/rp-2">
+ <wsrf-rp:Insert>
+ <qman:Type xmlns:qman="http://amqp.apache.org/qpid/management/qman">This is a string.</qman:Type>
+ </wsrf-rp:Insert>
+ </wsrf-rp:SetResourceProperties>
+ </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/wsrf/rpw-2/SetResourceProperties/SetResourcePropertiesResponse</wsa:Action>
+ <wsa:MessageID xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:0b895a1f-39e5-8739-d9d7-390c5f2eb445</wsa:MessageID>
+ <wsa:RelatesTo RelationshipType="wsa:Reply" xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:7917abf6-5c85-7e25-4515-b7f60cd32c39</wsa:RelatesTo>
+ <wsa:From xmlns:wsa="http://www.w3.org/2005/08/addressing">
+ <wsa:Address>http://localhost:8080/qman/services/QManWsResource</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">Q-MAN: brokerID=0ef67394-e34a-4bff-b0bf-88cf359ba1a0,class=queue,name=1232966356552,objectId=894cddd3-b893-4e2f-94d2-2489f72cbdd6,package=org.apache.qpid</qman-wsa:ResourceId>
+ </wsa:ReferenceParameters>
+ </wsa:From>
+ </soap:Header>
+ <soap:Body>
+ <wsrf-rp:SetResourcePropertiesResponse xmlns:wsrf-rp="http://docs.oasis-open.org/wsrf/rp-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://localhost:8080/qman/services/QManWsResource</wsa:To>
+ <wsa:Action xmlns:wsa="http://www.w3.org/2005/08/addressing">http://docs.oasis-open.org/wsrf/rpw-2/GetResourceProperty/GetResourcePropertyRequest</wsa:Action>
+ <wsa:MessageID xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:930f39a4-0114-03bd-9921-105579fb4213</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">Q-MAN: brokerID=0ef67394-e34a-4bff-b0bf-88cf359ba1a0,class=queue,name=1232966356552,objectId=894cddd3-b893-4e2f-94d2-2489f72cbdd6,package=org.apache.qpid</qman-wsa:ResourceId>
+ </soap:Header>
+ <soap:Body>
+ <wsrf-rp:GetResourceProperty
+ xmlns:wsrf-rp="http://docs.oasis-open.org/wsrf/rp-2" xmlns:qman="http://amqp.apache.org/qpid/management/qman">qman:Type</wsrf-rp:GetResourceProperty>
+ </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/wsrf/rpw-2/GetResourceProperty/GetResourcePropertyResponse</wsa:Action>
+ <wsa:MessageID xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:3d3f04ab-3171-da69-08b5-2e74927ee981</wsa:MessageID>
+ <wsa:RelatesTo RelationshipType="wsa:Reply" xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:930f39a4-0114-03bd-9921-105579fb4213</wsa:RelatesTo>
+ <wsa:From xmlns:wsa="http://www.w3.org/2005/08/addressing">
+ <wsa:Address>http://localhost:8080/qman/services/QManWsResource</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">Q-MAN: brokerID=0ef67394-e34a-4bff-b0bf-88cf359ba1a0,class=queue,name=1232966356552,objectId=894cddd3-b893-4e2f-94d2-2489f72cbdd6,package=org.apache.qpid</qman-wsa:ResourceId>
+ </wsa:ReferenceParameters>
+ </wsa:From>
+ </soap:Header>
+ <soap:Body>
+ <wsrf-rp:GetResourcePropertyResponse xmlns:wsrf-rp="http://docs.oasis-open.org/wsrf/rp-2">
+ <qman:Type xmlns:qman="http://amqp.apache.org/qpid/management/qman">This is a string.</qman:Type>
+ </wsrf-rp:GetResourcePropertyResponse>
+ </soap:Body>
+</soap:Envelope>
+
+----------------------------------------------------------------------------------
+Resource has been correctly updated.
+----------------------------------------------------------------------------------
diff --git a/qpid/java/management/client/src/example/org/apache/qpid/management/example/AbstractQManExample.java b/qpid/java/management/client/src/example/org/apache/qpid/management/example/AbstractQManExample.java
new file mode 100644
index 0000000000..ffa96635a8
--- /dev/null
+++ b/qpid/java/management/client/src/example/org/apache/qpid/management/example/AbstractQManExample.java
@@ -0,0 +1,140 @@
+/*
+ *
+ * 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.io.IOException;
+import java.net.URI;
+
+import org.apache.muse.ws.addressing.EndpointReference;
+
+/**
+ * Common interface for all QMan related examples.
+ *
+ * @author Andrea Gazzarini
+ */
+public abstract class AbstractQManExample
+{
+ final static String LINE_SEPARATOR = System.getProperty("line.separator","\n");
+ protected final static String PREFIX = "qman";
+
+ /**
+ * Prints out the expected command line of this sample and after that exits.
+ */
+ static void printUsageAndExit(String reason)
+ {
+ StringBuilder builder = new StringBuilder();
+ builder.append("WARNING! Unable to run this sample : ")
+ .append(reason)
+ .append(LINE_SEPARATOR)
+ .append("-------------------------------------------------------------")
+ .append(LINE_SEPARATOR)
+ .append("Expected command line args for this sample are :")
+ .append(LINE_SEPARATOR)
+ .append(LINE_SEPARATOR)
+ .append("1) host : ip or host name where QMan is running.")
+ .append(LINE_SEPARATOR)
+ .append("2) port : port number where QMan is running.")
+ .append(LINE_SEPARATOR)
+ .append("------------------------------------------------------------");
+ System.out.println(builder);
+ System.exit(1);
+ }
+
+ /**
+ * Prints out a description of this example.
+ */
+ abstract void printOutExampleDescription();
+
+ /**
+ * Executes this example.
+ * Note that this is just a template method used to avoid code duplication
+ * (printOutExampleDescription() line) so in order to see how the example
+ * works you should have a look at the concrete implementation of
+ * executeExample(String host, int port).
+ *
+ * @param host the host where QMan is running.
+ * @param port the port where QMan is running.
+ */
+ void execute(String [] arguments)
+ {
+ if (arguments.length != 2){
+ printUsageAndExit("invalid command line was given.");
+ }
+
+ try
+ {
+ // 1) Parses command line arguments...
+ String host = arguments[0];
+ int port = Integer.parseInt(arguments[1]);
+
+ printOutExampleDescription();
+
+ waitForUserInput("Type enter to proceed...");
+
+ executeExample(host, port);
+
+ } catch(NumberFormatException exception)
+ {
+ printUsageAndExit("port number must be a number.");
+ } catch(Exception exception)
+ {
+ System.out.println("-----------------------EXAMPLE FAILURE-----------");
+ System.out.println("Not well-defined exception was detected while");
+ System.out.println("running the example.");
+ exception.printStackTrace(System.out);
+ System.out.println("--------------------------------------------------------");
+ }
+ }
+
+ protected void waitForUserInput(String message) throws IOException {
+ System.out.println(message);
+ System.in.read();
+ }
+
+ /**
+ * Each concrete implementor must define here how the example works.
+ * So, on top of that, user who wants to see how to use a specific feature
+ * should have a look at the concrete implementation of this method..
+ *
+ * @param host the host where QMan is running.
+ * @param port the port where QMan is running.
+ * @throws Exception when the example fails (not at application level).
+ */
+ void executeExample(String host, int port) throws Exception{};
+
+ /**
+ * Returns the endpoint reference of the adapter service.
+ *
+ * @param host ip or host name where the service is running.
+ * @param port the port number of the server where the service is running.
+ * @return the endpoint reference of the adapter service.
+ */
+ EndpointReference getAdapterEndpointReference(String host, int port)
+ {
+ URI address = URI.create(
+ "http://"+
+ host+
+ ":"+
+ port+
+ "/qman/services/adapter");
+ return new EndpointReference(address);
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/example/org/apache/qpid/management/example/ConnectWithBrokerExample.java b/qpid/java/management/client/src/example/org/apache/qpid/management/example/ConnectWithBrokerExample.java
new file mode 100644
index 0000000000..153f0f66d5
--- /dev/null
+++ b/qpid/java/management/client/src/example/org/apache/qpid/management/example/ConnectWithBrokerExample.java
@@ -0,0 +1,240 @@
+/*
+ *
+ * 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 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;
+
+/**
+ * This example shows how to connect QMan with a broker using the adapter interface.
+ * As you can see the interface is very simple and requests you the following parameters :
+ *
+ * <ul>
+ * <li>hostname : the host (hostname or ip) where the broker is running;</li>
+ * <li>port : the port number of the running broker;</li>
+ * <li>virtual host : the name of the virtual host;</li>
+ * <li>username : the username that will be used for estabilshing connection.</li>
+ * <li>password : the password that will be used for estabilshing connection.</li>
+ * <li>initial pool capacity : the initial size of broker connection pool. </li>
+ * <li>maximum pool capacity : the max allowed size of broker connection pool.</li>
+ * <li>maximum wait timeout : the max wait timeout for retrieving connections.</li>
+ * </ul>
+ *
+ * @author Andrea Gazzarini
+ */
+public class ConnectWithBrokerExample extends AbstractQManExample
+{
+
+ /**
+ * Executes the connect example.
+ * Although not specified explicitly, the input array MUST contains in the following order :
+ *
+ * <ul>
+ * <li>host : the hostname where QMan is running;</li>
+ * <li>port : the port number where QMan is running;</li>
+ * <li>qpid host : the host name where QPid is running;</li>
+ * <li>qpid port : the port number where Qpid is running;</li>
+ * <li>virtual host : the virtual host name;</li>
+ * <li>username : the username that will be used for estabilshing connection.</li>
+ * <li>password : the password that will be used for estabilshing connection.</li>
+ * <li>initial pool capacity : the initial size of broker connection pool. </li>
+ * <li>maximum pool capacity : the max allowed size of broker connection pool.</li>
+ * <li>maximum wait timeout : the max wait timeout for retrieving connections.</li>
+ * </ul>
+ *
+ * Note that this example differs from the others (and therefore is overriding the execute() method) because
+ * in this case we are not using the "standard" WSRF interface but instead an additional custom
+ * "operation" on a WS-Resource.
+ *
+ * @param arguments the commadn line arguments.
+ */
+ void execute(String [] arguments)
+ {
+ if (arguments.length != 10){
+ printUsageAndExit("invalid command line was given.");
+ }
+
+ try
+ {
+ // 1) Parses command line arguments...
+ String host = arguments[0];
+ int port = Integer.parseInt(arguments[1]);
+ String qpidHost = arguments[2];
+ int qpidPort = Integer.parseInt(arguments[3]);
+ String virtualHost = arguments[4];
+ String username = arguments[5];
+ String password = arguments[6];
+ int initPoolCapacity = Integer.parseInt(arguments[7]);
+ int maxPoolCapacity = Integer.parseInt(arguments[8]);
+ long maxWaitTimeout = Long.parseLong(arguments[9]);
+
+ printOutExampleDescription();
+
+ waitForUserInput("Type enter to proceed...");
+
+ executeExample(
+ host,
+ port,
+ qpidHost,
+ qpidPort,
+ virtualHost,
+ username,
+ password,
+ initPoolCapacity,
+ maxPoolCapacity,
+ maxWaitTimeout);
+
+ } catch(NumberFormatException exception)
+ {
+ printUsageAndExit("Unable to run the example. Please ensure that all numeric values are correctly supplied.");
+ } catch(Exception exception)
+ {
+ System.out.println("-----------------------EXAMPLE FAILURE-----------");
+ System.out.println("Not well-defined exception was detected while");
+ System.out.println("running the example.");
+ exception.printStackTrace(System.out);
+ System.out.println("--------------------------------------------------------");
+ }
+ }
+
+ /**
+ * Connects QMan with a broker.
+ *
+ *@param host the hostname where QMan is running;
+ *@param port the port number where QMan is running;
+ *@param qpidHost the host name where QPid is running;
+ *@param qpidPort the port number where Qpid is running;
+ *@param virtualHost the virtual host name;
+ *@param username the username that will be used for estabilshing connection.
+ *@param password the password that will be used for estabilshing connection.
+ *@param initPoolCapacity the initial size of broker connection pool.
+ *@param maxPoolCapacity the max allowed size of broker connection pool.
+ *@param maxWaitTimeout the max wait timeout for retrieving connections.
+ *
+ * @throws Exception when the example fails (not at application level).
+ */
+ void executeExample(String host, int port, String qpidHost, int qpidPort, String virtualHost, String username, String password, int initPoolCapacity, int maxPoolCapacity, long maxWaitTimeout) throws Exception
+ {
+ // 1) Creates an endpoint reference of the adapter service...
+ EndpointReference adapterEndpointReference = getAdapterEndpointReference(host, port);
+ WsResourceClient adapterClient = new WsResourceClient(adapterEndpointReference);
+ adapterClient.setTrace(true);
+
+ // 2) Creates the Adapter service client...
+ adapterClient.invoke(
+ getProxyHandler(),
+ new Object[]{
+ qpidHost,
+ qpidPort,
+ username,
+ password,
+ virtualHost,
+ initPoolCapacity,
+ maxPoolCapacity,
+ maxWaitTimeout});
+ }
+
+ /**
+ * Prints out a description of this example.
+ */
+ void printOutExampleDescription()
+ {
+ System.out.println(" "+getClass().getSimpleName()+" ");
+ System.out.println("-------------------------------------------------------------------");
+ System.out.println();
+ System.out.println("This example shows how to connect QMan with a broker using");
+ System.out.println("the adapter interface.");
+ System.out.println();
+ }
+
+ /**
+ * A proxy handler is a module needed in order to make a capability
+ * service invocation.
+ * It contains logic to serialize and deserialize request, response, input and
+ * output parameters during a web service invocation.
+ *
+ * @return a proxy handler.
+ */
+ private ProxyHandler getProxyHandler()
+ {
+ ProxyHandler handler = new ReflectionProxyHandler();
+ handler.setAction("http://amqp.apache.org/qpid/management/qman/Connect");
+ handler.setRequestName(new QName("http://amqp.apache.org/qpid/management/qman", "Connect", PREFIX));
+ handler.setRequestParameterNames(new QName[]{
+ new QName("http://amqp.apache.org/qpid/management/qman", "host", PREFIX),
+ new QName("http://amqp.apache.org/qpid/management/qman", "port", PREFIX),
+ new QName("http://amqp.apache.org/qpid/management/qman", "username", PREFIX),
+ new QName("http://amqp.apache.org/qpid/management/qman", "password", PREFIX),
+ new QName("http://amqp.apache.org/qpid/management/qman", "virtualHost", PREFIX),
+ new QName("http://amqp.apache.org/qpid/management/qman", "initialPoolCapacity", PREFIX),
+ new QName("http://amqp.apache.org/qpid/management/qman", "maxPoolCapacity", PREFIX),
+ new QName("http://amqp.apache.org/qpid/management/qman", "maxWaitTimeout", PREFIX)});
+ handler.setResponseName(new QName("http://amqp.apache.org/qpid/management/qman", "ConnectResponse", PREFIX));
+ handler.setReturnType(null);
+ return handler;
+ }
+
+ public static void main(String[] arguments)
+ {
+ new ConnectWithBrokerExample().execute(arguments);
+ }
+
+ static void printUsageAndExit(String reason)
+ {
+ StringBuilder builder = new StringBuilder();
+ builder.append("WARNING! Unable to run this sample : ")
+ .append(reason)
+ .append(LINE_SEPARATOR)
+ .append("-------------------------------------------------------------")
+ .append(LINE_SEPARATOR)
+ .append("Expected command line args for this sample are :")
+ .append(LINE_SEPARATOR)
+ .append(LINE_SEPARATOR)
+ .append("1) host : ip or host name where QMan is running.")
+ .append(LINE_SEPARATOR)
+ .append("2) port : port number where QMan is running.")
+ .append(LINE_SEPARATOR)
+ .append("3) qpid host : port number where Qpid is running.")
+ .append(LINE_SEPARATOR)
+ .append("4) qpid port : port number where Qpid is running.")
+ .append(LINE_SEPARATOR)
+ .append("5) virtual host : virtual host name.")
+ .append(LINE_SEPARATOR)
+ .append("6) username : port number where QMan is running.")
+ .append(LINE_SEPARATOR)
+ .append("7) password : port number where QMan is running.")
+ .append(LINE_SEPARATOR)
+ .append("8) initial pool capacity : port number where QMan is running.")
+ .append(LINE_SEPARATOR)
+ .append("9) max pool capacity : port number where QMan is running.")
+ .append(LINE_SEPARATOR)
+ .append("10) max wait timeout : port number where QMan is running.")
+ .append(LINE_SEPARATOR)
+
+ .append("------------------------------------------------------------");
+ System.out.println(builder);
+ System.exit(1);
+ }
+} \ No newline at end of file
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
new file mode 100644
index 0000000000..42587d78ff
--- /dev/null
+++ b/qpid/java/management/client/src/example/org/apache/qpid/management/example/ConsumerAndProducerExample.java
@@ -0,0 +1,293 @@
+/*
+ *
+ * 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 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;
+
+/**
+ * This example is demonstrating a WS-Notification scenario
+ * when (for simplicity) QMan is at the same time consumer
+ * and producer.
+ *
+ * Basically we have (on producer side) two topics : one for
+ * lifecycle events of object instance (objects created & removed)
+ * and another one for lifecycle of event (events created).
+ *
+ * On consumer side there are many options that you can use in
+ * order to made a sunscription :
+ *
+ * <ul>
+ * <li>you could be an observer of all messages (all topics);</li>
+ * <li>you could be an observer of one specific topic;</li>
+ * <li>
+ * you could be an observer of all messages that match
+ * a condition expressed in XPath;
+ * </li>
+ * </ul>
+ *
+ * All those options are provided with or withour a termination time.
+ * A subscription with a termination time will have a predefined expiry
+ * date while if there's no termination the subscription will never expire.
+ *
+ * @author Andrea Gazzarini
+ *
+ */
+public class ConsumerAndProducerExample 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);
+
+ // Example 1 : all messages on all topics without termination time.
+ subscribeAllMessagesWithoutTerminationTime(producerEPR,consumerEPR);
+
+ // Example 2 : all messages on all topics with termination time.
+ subscribeAllMessagesWithTerminationTime(producerEPR,consumerEPR);
+
+ // Example 3: Topic filter without termination time.
+ topicSubscriptionWithoutTerminationTime(producerEPR,consumerEPR);
+
+ // Example 4: Topic filter with termination time.
+ topicSubscriptionWithTerminationTime(producerEPR,consumerEPR);
+
+ // Example 5: a MessageFilter is installed in order to listen only for connection events
+ // (connections created or removed). The subscription never expire.
+ allMessagesWithMessageFilterWithoutTerminationTime(producerEPR,consumerEPR);
+
+ // 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.
+ *
+ * @param producer the producer endpoint reference.
+ * @param consumer the consumer endpoint reference .
+ * @throws SoapFault when the subscription cannot be made.
+ */
+ private void subscribeAllMessagesWithoutTerminationTime(EndpointReference producer, EndpointReference consumer) throws SoapFault
+ {
+ NotificationProducerClient producerClient = new NotificationProducerClient(producer);
+ producerClient.setTrace(true);
+
+ producerClient.subscribe(
+ consumer, // Consumer Endpoint reference
+ null, // Filter, if null that means "all messages"
+ null); // Termination Time : if null the subscription will never expire.
+ }
+
+ /**
+ * Makes a subscription on all topics / all messages with 10 seconds as termination time.
+ * The subscription will expire 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 subscribeAllMessagesWithTerminationTime(EndpointReference producer, EndpointReference consumer) throws SoapFault
+ {
+ NotificationProducerClient producerClient = new NotificationProducerClient(producer);
+ producerClient.setTrace(true);
+
+ producerClient.subscribe(
+ consumer, // Consumer Endpoint reference
+ null, // Filter, if null that means "all messages"
+ new Date(System.currentTimeMillis() + 10000)); // Termination Time
+ }
+
+ /**
+ * Makes a subscription on a specifc topic without an expiry date.
+ * Only messages published on the given topic will be delivered to the given consumer.
+ *
+ * @param producer the producer endpoint reference.
+ * @param consumer the consumer endpoint reference .
+ * @throws SoapFault when the subscription cannot be made.
+ */
+ private void topicSubscriptionWithoutTerminationTime(EndpointReference producer, EndpointReference consumer) throws SoapFault
+ {
+ NotificationProducerClient producerClient = new NotificationProducerClient(producer);
+ producerClient.setTrace(true);
+
+ TopicFilter filter = new TopicFilter(Names.EVENTS_LIFECYLE_TOPIC_NAME);
+
+ producerClient.subscribe(
+ consumer, // Consumer Endpoint reference
+ filter, // Topic Filter
+ null); // Termination Time : if null the subscription will never expire.
+ }
+
+ /**
+ * 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 topicSubscriptionWithTerminationTime(EndpointReference producer, EndpointReference consumer) throws SoapFault
+ {
+ NotificationProducerClient producerClient = new NotificationProducerClient(producer);
+ producerClient.setTrace(true);
+
+ TopicFilter filter = new TopicFilter(Names.EVENTS_LIFECYLE_TOPIC_NAME);
+
+ producerClient.subscribe(
+ consumer, // Consumer Endpoint reference
+ filter, // Topic Filter
+ new Date(System.currentTimeMillis() + 10000)); // Termination Time
+ }
+
+ /**
+ * Makes a subscription on all topics with a message filter without an expiry date.
+ *
+ * @param producer the producer endpoint reference.
+ * @param consumer the consumer endpoint reference .
+ * @throws SoapFault when the subscription cannot be made.
+ */
+ private void allMessagesWithMessageFilterWithoutTerminationTime(EndpointReference producer, EndpointReference consumer) throws SoapFault
+ {
+ NotificationProducerClient producerClient = new NotificationProducerClient(producer);
+ producerClient.setTrace(true);
+
+ // Applying this filter will result in a subscription that wll be notified only when a "connection"
+ // object is created or removed
+ MessagePatternFilter filter= 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
+
+ producerClient.subscribe(
+ consumer, // Consumer Endpoint reference
+ filter, // Message Filter
+ null); // Termination Time : if null the subscription will never expire.
+ }
+
+ /**
+ * Makes a subscription on all topics with a message filter and an expiry date.
+ *
+ * @param producer the producer endpoint reference.
+ * @param consumer the consumer endpoint reference .
+ * @throws SoapFault when the subscription cannot be made.
+ */
+ private void allMessagesWithMessageFilterAndTerminationTime(EndpointReference producer, EndpointReference consumer) throws SoapFault
+ {
+ NotificationProducerClient producerClient = new NotificationProducerClient(producer);
+ producerClient.setTrace(true);
+
+ // Applying this filter will result in a subscription that wll be notified only when a "connection"
+ // object is created or removed
+ MessagePatternFilter filter= 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
+
+ producerClient.subscribe(
+ consumer, // Consumer Endpoint reference
+ filter, // Message Filter
+ 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()
+ {
+ 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("Basically we have (on producer side) two topics : one for");
+ System.out.println("lifecycle events of object instance (objects created & removed) ");
+ System.out.println("and another one for lifecycle of event (events created).");
+ System.out.println();
+ System.out.println("On consumer side there are many options that you can use in");
+ System.out.println("order to made a sunscription :");
+ System.out.println();
+ System.out.println("- you could be an observer of all messages (all topics);");
+ System.out.println("- you could be an observer of one specific topic;");
+ System.out.println("- you could be an observer of all messages that match a condition expressed in XPath;");
+ System.out.println();
+ System.out.println("All those options are provided with or withour a termination time.");
+ 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/GetMultipleResourcePropertiesExample.java b/qpid/java/management/client/src/example/org/apache/qpid/management/example/GetMultipleResourcePropertiesExample.java
new file mode 100644
index 0000000000..413222a79d
--- /dev/null
+++ b/qpid/java/management/client/src/example/org/apache/qpid/management/example/GetMultipleResourcePropertiesExample.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.management.example;
+
+import java.util.ArrayList;
+import java.util.List;
+
+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.EndpointReference;
+import org.apache.muse.ws.resource.remote.WsResourceClient;
+import org.apache.muse.ws.resource.sg.remote.ServiceGroupClient;
+import org.w3c.dom.Element;
+
+/**
+ * This example shows how to get properties from a WS-Resource using one request.
+ * First of all a request is send to WS-DM in order to get all registered WS-Resources.
+ * If the returned list is not empty then a GetMetadataRequest is sent to the
+ * first child.
+ * The result metadata descriptor contains all properties names of the target WS-Resource.
+ * Those names are then used for retrieving the corresponding values.
+ *
+ * @author Andrea Gazzarini
+ */
+public class GetMultipleResourcePropertiesExample extends AbstractQManExample
+{
+
+ /**
+ * First of all a request is send to WS-DM in order to get all registered WS-Resources.
+ * If the returned list is not empty then a GetMetadataRequest is sent to the
+ * first child.
+ * The result metadata descriptor contains all properties names of the target WS-Resource.
+ * Those names are then used for retrieving the corresponding values.
+ *
+ * @param host the host where QMan is running.
+ * @param port the port where QMan is running.
+ * @throws Exception when the example fails (not at application level).
+ */
+ void executeExample(String host, int port) throws Exception
+ {
+
+ // 1) Creates an endpoint reference of the adapter service...
+ EndpointReference adapterEndpointReference = getAdapterEndpointReference(host, port);
+
+ // 2) Creates the Adapter service client...
+ ServiceGroupClient adapterClient = new ServiceGroupClient(adapterEndpointReference);
+ adapterClient.setTrace(true);
+
+ // 3) Retrieves the all registered members (QMan WS-Resources)
+ WsResourceClient [] resources = adapterClient.getMembers();
+
+ // Sanity check : we cannot proceed if there are no WS-Resources.
+ if (resources.length == 0)
+ {
+ System.out.println("----------------------------WARNING---------------------------");
+ System.out.println("Cannot proceed with the example... it seems");
+ System.out.println("that there are no managed WS-Resources on QMan.");
+ System.out.println("Please check QMan in order to see that it is really");
+ System.out.println("connected with a broker.");
+ System.out.println("-------------------------------------------------------------------");
+ System.exit(0);
+ }
+
+ // 4) Creates a proxy handler for service invocation.
+ ProxyHandler metadataProxyHandler = createProxyHandler();
+
+ // 5) ..and invokes the GetMetadata on the first member.
+ WsResourceClient wsResourceClient = resources[0];
+ wsResourceClient.setTrace(true);
+
+ // Dialect is RDM for this example
+ String dialect = "http://docs.oasis-open.org/wsrf/rmd-1";
+ Object [] inputParameters = {dialect};
+
+ // RDM is the first element of the returned array.
+ // The first element is a wsx:Metadata containing all resource properties.
+ Element [] metadata = (Element[]) wsResourceClient.invoke(metadataProxyHandler, inputParameters);
+ Element resourceMetadataDescriptor = metadata[0];
+
+ // 6) using XPath navigates xml in order to get the list of all properties.
+ Element [] properties = XmlUtils.findInSubTree(
+ resourceMetadataDescriptor,
+ new QName("http://docs.oasis-open.org/wsrf/rmd-1","Property","wsrmd"));
+ List<QName> names = new ArrayList<QName>();
+
+ for (Element property : properties)
+ {
+
+ String attributeName = property.getAttribute("name"); // = qman:<Attribute Name>
+
+ // For this example we are only interested on qman namespace related properties...
+ if (attributeName.startsWith("qman"))
+ {
+ String attributeNameWithoutPrefix = attributeName.replaceFirst("qman:", ""); // = <Attribute Name>
+
+ names.add(new QName(
+ "http://amqp.apache.org/qpid/management/qman",
+ attributeNameWithoutPrefix,
+ "qman"));
+ }
+ }
+
+ QName [] qnames = names.toArray(new QName[names.size()]);
+
+ // 7) Send a GetMultipleResourcePropertiesRequest.
+ // We do nothing with the returned value(s) because it / they
+ // has / have already printed out (wsResourceClient.setTrace(true))
+ @SuppressWarnings("unused")
+ Element [] values = wsResourceClient.getMultipleResourceProperties(qnames);
+ }
+
+ /**
+ * Prints out a description of this example.
+ */
+ void printOutExampleDescription()
+ {
+ System.out.println(" "+getClass().getSimpleName()+" ");
+ System.out.println("-------------------------------------------------------------------");
+ System.out.println();
+ System.out.println("This example shows how to get properties from a");
+ System.out.println("WS-Resource using one request. ");
+ System.out.println("First of all a request is send to WS-DM in order to get");
+ System.out.println("all registered WS-Resources.");
+ System.out.println("If the returned list is not empty then a GetMetadataRequest");
+ System.out.println("to the first child.");
+ System.out.println("The result metadata descriptor contains all property names of");
+ System.out.println("the target WS-Resource.");
+ System.out.println("Those names are then used for retrieving the corresponding values");
+ System.out.println("using the GetMultipleResourceProperties request.");
+ System.out.println();
+ System.out.println("-------------------------------------------------------------------");
+ System.out.println();
+ }
+
+ /**
+ * A proxy handler is a module needed in order to make a capability
+ * service invocation.
+ * It contains logic to serialize and deserialize request, response, input and
+ * output parameters during a web service invocation.
+ *
+ * @return a proxy handler.
+ */
+ private ProxyHandler createProxyHandler()
+ {
+ ProxyHandler handler = new ReflectionProxyHandler();
+ handler.setAction("http://schemas.xmlsoap.org/ws/2004/09/mex/GetMetadata");
+ handler.setRequestName(new QName("http://schemas.xmlsoap.org/ws/2004/09/mex", "GetMetadata", PREFIX));
+ handler.setRequestParameterNames(new QName[]{new QName("http://schemas.xmlsoap.org/ws/2004/09/mex", "Dialect", PREFIX)});
+ handler.setResponseName(new QName("http://schemas.xmlsoap.org/ws/2004/09/mex", "Metadata", PREFIX));
+ handler.setReturnType(Element[].class);
+ return handler;
+ }
+
+ public static void main(String[] arguments)
+ {
+ new GetMultipleResourcePropertiesExample().execute(arguments);
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/example/org/apache/qpid/management/example/GetQManResourceMembersExample.java b/qpid/java/management/client/src/example/org/apache/qpid/management/example/GetQManResourceMembersExample.java
new file mode 100644
index 0000000000..f74a44ab57
--- /dev/null
+++ b/qpid/java/management/client/src/example/org/apache/qpid/management/example/GetQManResourceMembersExample.java
@@ -0,0 +1,93 @@
+/*
+ *
+ * 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 org.apache.muse.ws.addressing.EndpointReference;
+import org.apache.muse.ws.resource.remote.WsResourceClient;
+import org.apache.muse.ws.resource.sg.remote.ServiceGroupClient;
+
+/**
+ * An example demonstrating the usage of GetResourcePropertyRequest/Response on
+ * the WS-DM Adapter.
+ *
+ * @author Andrea Gazzarini
+ */
+public class GetQManResourceMembersExample extends AbstractQManExample
+{
+ /**
+ * Looks for memebers of QMan group requesting ws-rp:Entry property to
+ * WS-DM Adapter resource service.
+ *
+ * @param host the host where QMan is running.
+ * @param port the port where QMan is running.
+ * @throws Exception when the example fails (not at application level).
+ */
+ void executeExample(String host, int port) throws Exception
+ {
+ // 1) Creates an endpoint reference of the adapter service...
+ EndpointReference serviceEndpointReference = getAdapterEndpointReference(host, port);
+
+ // 2) Creates the Service client...
+ ServiceGroupClient adapterClient = new ServiceGroupClient(serviceEndpointReference);
+ adapterClient.setTrace(true);
+
+ // 3) Invokes the service.
+ WsResourceClient [] resources = adapterClient.getMembers();
+
+ String result = (resources.length != 0)
+ ? ("QMan has at the moment "+resources.length+" registered resources.")
+ : "It seems that there are no managed resource on QMan side...";
+
+ System.out.println("--------------------------------------------------------------------------");
+ System.out.println(result);
+ System.out.println("--------------------------------------------------------------------------");
+ }
+
+ /**
+ * Prints out a description of this example.
+ */
+ void printOutExampleDescription()
+ {
+ System.out.println(" "+getClass().getSimpleName()+" ");
+ System.out.println("-------------------------------------------------------------------");
+ System.out.println();
+ System.out.println("This example shows the usage of WS-DM ");
+ System.out.println("GetResourcePropertyRequest / Response on a ");
+ System.out.println("Group service.");
+ System.out.println("The target resource is the WS-DM Adapter itself ");
+ System.out.println("and the requested property is \"wsrf-sg:Entry\".");
+ System.out.println("WS-DM Adapter is a special WS-Resource (is a Group)");
+ System.out.println("that acts as the main entry point for retrieving");
+ System.out.println("all other managed resources.");
+ System.out.println("So clients that want to deal with QMan WS-Resources");
+ System.out.println("must first get resource identifiers sending");
+ System.out.println("a GetResourcePropertyRequest to WS-DM Adapter ");
+ System.out.println("with \"wsrf-sg:Entry\" as target target property.");
+ System.out.println();
+ System.out.println("-------------------------------------------------------------------");
+ System.out.println();
+ }
+
+ public static void main(String[] arguments)
+ {
+ new GetQManResourceMembersExample().execute(arguments);
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/example/org/apache/qpid/management/example/GetResourceMetadataDescriptorExample.java b/qpid/java/management/client/src/example/org/apache/qpid/management/example/GetResourceMetadataDescriptorExample.java
new file mode 100644
index 0000000000..84befc01e4
--- /dev/null
+++ b/qpid/java/management/client/src/example/org/apache/qpid/management/example/GetResourceMetadataDescriptorExample.java
@@ -0,0 +1,156 @@
+/*
+ *
+ * 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 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.muse.ws.resource.sg.remote.ServiceGroupClient;
+import org.w3c.dom.Element;
+
+/**
+ * This example shows how to get metadata from a WS-Resource.
+ * The service supports different kinds of metadata.
+ * User who wants to receive metadata of a WS-Resource must
+ * send a GetMetadataRequesta specifying the requested dialect.
+ *
+ * Supported metadata that could be requested are
+ *
+ * <ul>
+ * <li>
+ * WSDL : requested using "http://schemas.xmlsoap.org/wsdl/" as dialect..
+ * <li>
+ * <li>
+ * RDM (Resource Metadata Descriptor) : requested using "http://docs.oasis-open.org/wsrf/rmd-1 "as dialect.
+ * </li>
+ * </ul>
+ *
+ * Note that this example focuses on RDM Metadata only; another example is dedicated to WSDL.
+ *
+ * @author Andrea Gazzarini
+ */
+public class GetResourceMetadataDescriptorExample extends AbstractQManExample
+{
+
+ /**
+ * First, sends a request to WS-DM Adapter in order to get the list of managed resources.
+ * If the list is not empty, then takes the first member and sends it a GetMetadataRequest
+ * in order to get its RDM.
+ *
+ * @param host the host where QMan is running.
+ * @param port the port where QMan is running.
+ * @throws Exception when the example fails (not at application level).
+ */
+ void executeExample(String host, int port) throws Exception
+ {
+
+ // 1) Creates an endpoint reference of the adapter service...
+ EndpointReference adapterEndpointReference = getAdapterEndpointReference(host, port);
+
+ // 2) Creates the Adapter service client...
+ ServiceGroupClient adapterClient = new ServiceGroupClient(adapterEndpointReference);
+ adapterClient.setTrace(true);
+
+ // 3) Retrieves the all registered members (QMan WS-Resources)
+ WsResourceClient [] resources = adapterClient.getMembers();
+
+ // Sanity check : we cannot proceed if there are no WS-Resources.
+ if (resources.length == 0)
+ {
+ System.out.println("----------------------------WARNING---------------------------");
+ System.out.println("Cannot proceed with the example... it seems");
+ System.out.println("that there are no managed WS-Resources on QMan.");
+ System.out.println("Please check QMan in order to see that it is really");
+ System.out.println("connected with a broker.");
+ System.out.println("-------------------------------------------------------------------");
+ System.exit(0);
+ }
+
+ // 4) Creates a proxy handler for service invocation.
+ ProxyHandler metadataProxyHandler = createProxyHandler();
+
+ // 5) ..and invokes the GetMetadata on the first member.
+ WsResourceClient firstMember = resources[0];
+ firstMember.setTrace(true);
+
+ // Dialect is RDM for this example
+ String dialect = "http://docs.oasis-open.org/wsrf/rmd-1";
+ Object [] inputParameters = {dialect};
+
+ // WSDL is the first element of the returned array. We don't need to print out it here
+ // because at this point it should have been already printed out (line 96 : firstMember.setTrace(true))
+ @SuppressWarnings("unused")
+ Element [] metadata = (Element[]) firstMember.invoke(metadataProxyHandler, inputParameters);
+ }
+
+ /**
+ * Prints out a description of this example.
+ */
+ void printOutExampleDescription()
+ {
+ System.out.println(" "+getClass().getSimpleName()+" ");
+ System.out.println("-------------------------------------------------------------------");
+ System.out.println();
+ System.out.println("The example shows how to get metadata from a");
+ System.out.println("WS-Resource.");
+ System.out.println("A QMan WS-Resource has different kinds of metadata.");
+ System.out.println("(see below)");
+ System.out.println("User who wants to receive metadata of a WS-Resource");
+ System.out.println("must send a GetMetadataRequesta specifying the");
+ System.out.println("associated dialect.");
+ System.out.println("Supported metadata that could be requested are : ");
+ System.out.println();
+ System.out.println("- WSDL : in this case dialect is \"http://schemas.xmlsoap.org/wsdl/\";");
+ System.out.println("- RDM (Resource Metadata Descriptor) : in this case dialect is \"http://docs.oasis-open.org/wsrf/rmd-1 \".");
+ System.out.println();
+ System.out.println("Note that this examples focuses on RDM Metadata only;");
+ System.out.println("another one is dedicated to WSDL.");
+ System.out.println("-------------------------------------------------------------------");
+ System.out.println();
+ }
+
+ /**
+ * A proxy handler is a module needed in order to make a capability
+ * service invocation.
+ * It contains logic to serialize and deserialize request, response, input and
+ * output parameters during a web service invocation.
+ *
+ * @return a proxy handler.
+ */
+ private ProxyHandler createProxyHandler()
+ {
+ ProxyHandler handler = new ReflectionProxyHandler();
+ handler.setAction("http://schemas.xmlsoap.org/ws/2004/09/mex/GetMetadata");
+ handler.setRequestName(new QName("http://schemas.xmlsoap.org/ws/2004/09/mex", "GetMetadata", PREFIX));
+ handler.setRequestParameterNames(new QName[]{new QName("http://schemas.xmlsoap.org/ws/2004/09/mex", "Dialect", PREFIX)});
+ handler.setResponseName(new QName("http://schemas.xmlsoap.org/ws/2004/09/mex", "Metadata", PREFIX));
+ handler.setReturnType(Element[].class);
+ return handler;
+ }
+
+ public static void main(String[] arguments)
+ {
+ new GetResourceMetadataDescriptorExample().execute(arguments);
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/example/org/apache/qpid/management/example/GetResourcePropertyDocumentExample.java b/qpid/java/management/client/src/example/org/apache/qpid/management/example/GetResourcePropertyDocumentExample.java
new file mode 100644
index 0000000000..56ce81358d
--- /dev/null
+++ b/qpid/java/management/client/src/example/org/apache/qpid/management/example/GetResourcePropertyDocumentExample.java
@@ -0,0 +1,111 @@
+/*
+ *
+ * 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 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.w3c.dom.Element;
+
+/**
+ * This example shows how to get the whole property document from a WS-Resource.
+ * Resource property document represents a particular composed structural view of
+ * the resource properties of the WS-Resource.
+ * Let's say that It is a way to get all-in-once the state of the WS-Resource.
+ *
+ * First of all a request is send to WS-DM in order to get all registered WS-Resources.
+ * If the returned list is not empty then a GetResourcePropertyDocumentRequest is
+ * sent to the first child.
+ *
+ * @author Andrea Gazzarini
+ */
+public class GetResourcePropertyDocumentExample extends AbstractQManExample
+{
+
+ /**
+ * First of all a request is send to WS-DM in order to get all registered WS-Resources.
+ * If the returned list is not empty then a GetResourcePropertyDocumentRequest is
+ * sent to the first child.
+ *
+ * @param host the host where QMan is running.
+ * @param port the port where QMan is running.
+ * @throws Exception when the example fails (not at application level).
+ */
+ void executeExample(String host, int port) throws Exception
+ {
+
+ // 1) Creates an endpoint reference of the adapter service...
+ EndpointReference adapterEndpointReference = getAdapterEndpointReference(host, port);
+
+ // 2) Creates the Adapter service client...
+ ServiceGroupClient adapterClient = new ServiceGroupClient(adapterEndpointReference);
+ adapterClient.setTrace(true);
+
+ // 3) Retrieves the all registered members (QMan WS-Resources)
+ WsResourceClient [] resources = adapterClient.getMembers();
+
+ // Sanity check : we cannot proceed if there are no WS-Resources.
+ if (resources.length == 0)
+ {
+ System.out.println("----------------------------WARNING---------------------------");
+ System.out.println("Cannot proceed with the example... it seems");
+ System.out.println("that there are no managed WS-Resources on QMan.");
+ System.out.println("Please check QMan in order to see that it is really");
+ System.out.println("connected with a broker.");
+ System.out.println("-------------------------------------------------------------------");
+ System.exit(0);
+ }
+
+ // 4) ..and invokes the GetMetadata on the first member.
+ WsResourceClient wsResourceClient = resources[0];
+ wsResourceClient.setTrace(true);
+
+ @SuppressWarnings("unused")
+ Element resourcePropertyDocument = wsResourceClient.getResourcePropertyDocument();
+ }
+ /**
+ * Prints out a description of this example.
+ */
+ void printOutExampleDescription()
+ {
+ System.out.println(" "+getClass().getSimpleName()+" ");
+ System.out.println("-------------------------------------------------------------------");
+ System.out.println();
+ System.out.println("This example shows how to get the whole property");
+ System.out.println("document from a WS-Resource.");
+ System.out.println("Resource property document represents a particular ");
+ System.out.println("composed structural view of the resource properties");
+ System.out.println("of the WS-Resource.");
+ System.out.println("First of all a request is send to WS-DM in order to get");
+ System.out.println("all registered WS-Resources.");
+ System.out.println("the target WS-Resource.");
+ System.out.println("If the returned list is not empty then a");
+ System.out.println("GetResourcePropertyDocumentRequest is sent to the first child.");
+ System.out.println();
+ System.out.println("-------------------------------------------------------------------");
+ System.out.println();
+ }
+
+ public static void main(String[] arguments)
+ {
+ new GetResourcePropertyDocumentExample().execute(arguments);
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/example/org/apache/qpid/management/example/GetResourcePropertyExample.java b/qpid/java/management/client/src/example/org/apache/qpid/management/example/GetResourcePropertyExample.java
new file mode 100644
index 0000000000..28ed1c7925
--- /dev/null
+++ b/qpid/java/management/client/src/example/org/apache/qpid/management/example/GetResourcePropertyExample.java
@@ -0,0 +1,172 @@
+/*
+ *
+ * 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 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.EndpointReference;
+import org.apache.muse.ws.resource.remote.WsResourceClient;
+import org.apache.muse.ws.resource.sg.remote.ServiceGroupClient;
+import org.w3c.dom.Element;
+
+/**
+ * This example shows how to get the property value from a WS-Resource.
+ * First of all a request is send to WS-DM in order to get all registered WS-Resources.
+ * If the returned list is not empty then a GetMetadataRequest is sent to the
+ * first child.
+ * The result metadata descriptor contains all properties of the target WS-Resource.
+ * For each of them a GetResourcePropertyRequest is sent in order to get its value.
+ *
+ * @author Andrea Gazzarini
+ */
+public class GetResourcePropertyExample extends AbstractQManExample
+{
+
+ /**
+ * First, sends a request to WS-DM Adapter in order to get the list of managed resources.
+ * If the list is not empty, then takes the first member and sends it a GetMetadataRequest
+ * in order to get its WSDL.
+ * After that, for each property contained in ResourceMetadataDescriptorm (RDM) a
+ * GetResourcePropertyRequest is sent in order to get its value.
+ *
+ * @param host the host where QMan is running.
+ * @param port the port where QMan is running.
+ * @throws Exception when the example fails (not at application level).
+ */
+ void executeExample(String host, int port) throws Exception
+ {
+
+ // 1) Creates an endpoint reference of the adapter service...
+ EndpointReference adapterEndpointReference = getAdapterEndpointReference(host, port);
+
+ // 2) Creates the Adapter service client...
+ ServiceGroupClient adapterClient = new ServiceGroupClient(adapterEndpointReference);
+ adapterClient.setTrace(true);
+
+ // 3) Retrieves the all registered members (QMan WS-Resources)
+ WsResourceClient [] resources = adapterClient.getMembers();
+
+ // Sanity check : we cannot proceed if there are no WS-Resources.
+ if (resources.length == 0)
+ {
+ System.out.println("----------------------------WARNING---------------------------");
+ System.out.println("Cannot proceed with the example... it seems");
+ System.out.println("that there are no managed WS-Resources on QMan.");
+ System.out.println("Please check QMan in order to see that it is really");
+ System.out.println("connected with a broker.");
+ System.out.println("-------------------------------------------------------------------");
+ System.exit(0);
+ }
+
+ // 4) Creates a proxy handler for service invocation.
+ ProxyHandler metadataProxyHandler = createProxyHandler();
+
+ // 5) ..and invokes the GetMetadata on the first member.
+ WsResourceClient wsResourceClient = resources[0];
+ wsResourceClient.setTrace(true);
+
+ // Dialect is RDM for this example
+ String dialect = "http://docs.oasis-open.org/wsrf/rmd-1";
+ Object [] inputParameters = {dialect};
+
+ // RDM is the first element of the returned array.
+ // The first element is a wsx:Metadata containing all resource properties.
+ Element [] metadata = (Element[]) wsResourceClient.invoke(metadataProxyHandler, inputParameters);
+ Element resourceMetadataDescriptor = metadata[0];
+
+ // 6) using XPath navigates xml in order to get the list of all properties.
+ Element [] properties = XmlUtils.findInSubTree(
+ resourceMetadataDescriptor,
+ new QName("http://docs.oasis-open.org/wsrf/rmd-1","Property","wsrmd"));
+
+ for (Element property : properties)
+ {
+
+ String attributeName = property.getAttribute("name"); // = qman:<Attribute Name>
+
+ // For this example we are only interested on qman namespace related properties...
+ if (attributeName.startsWith("qman"))
+ {
+ String attributeNameWithoutPrefix = attributeName.replaceFirst("qman:", ""); // = <Attribute Name>
+
+ // 7) Send a GetResourcePropertyRequest for the given attribute.
+ // We do nothing with the returned value(s) because it / they
+ // has / have already printed out (wsResourceClient.setTrace(true))
+ @SuppressWarnings("unused")
+ Element [] values = wsResourceClient.getResourceProperty(
+ new QName(
+ "http://amqp.apache.org/qpid/management/qman",
+ attributeNameWithoutPrefix,
+ "qman"));
+ }
+ }
+ }
+
+ /**
+ * Prints out a description of this example.
+ */
+ void printOutExampleDescription()
+ {
+ System.out.println(" "+getClass().getSimpleName()+" ");
+ System.out.println("-------------------------------------------------------------------");
+ System.out.println();
+ System.out.println("This example shows how to get the property value");
+ System.out.println("from a WS-Resource.");
+ System.out.println("First of all a request is send to WS-DM in order to get");
+ System.out.println("all registered WS-Resources.");
+ System.out.println("If the returned list is not empty then a GetMetadataRequest");
+ System.out.println("to the first child.");
+ System.out.println("The result metadata descriptor contains all properties of");
+ System.out.println("the target WS-Resource.");
+ System.out.println("For each of them a GetResourcePropertyRequest is sent");
+ System.out.println(" in order to get its value.");
+ System.out.println();
+ System.out.println("-------------------------------------------------------------------");
+ System.out.println();
+ }
+
+ /**
+ * A proxy handler is a module needed in order to make a capability
+ * service invocation.
+ * It contains logic to serialize and deserialize request, response, input and
+ * output parameters during a web service invocation.
+ *
+ * @return a proxy handler.
+ */
+ private ProxyHandler createProxyHandler()
+ {
+ ProxyHandler handler = new ReflectionProxyHandler();
+ handler.setAction("http://schemas.xmlsoap.org/ws/2004/09/mex/GetMetadata");
+ handler.setRequestName(new QName("http://schemas.xmlsoap.org/ws/2004/09/mex", "GetMetadata", PREFIX));
+ handler.setRequestParameterNames(new QName[]{new QName("http://schemas.xmlsoap.org/ws/2004/09/mex", "Dialect", PREFIX)});
+ handler.setResponseName(new QName("http://schemas.xmlsoap.org/ws/2004/09/mex", "Metadata", PREFIX));
+ handler.setReturnType(Element[].class);
+ return handler;
+ }
+
+ public static void main(String[] arguments)
+ {
+ new GetResourcePropertyExample().execute(arguments);
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/example/org/apache/qpid/management/example/GetWSDLMetadataExample.java b/qpid/java/management/client/src/example/org/apache/qpid/management/example/GetWSDLMetadataExample.java
new file mode 100644
index 0000000000..ecda6e8fb1
--- /dev/null
+++ b/qpid/java/management/client/src/example/org/apache/qpid/management/example/GetWSDLMetadataExample.java
@@ -0,0 +1,156 @@
+/*
+ *
+ * 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 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.muse.ws.resource.sg.remote.ServiceGroupClient;
+import org.w3c.dom.Element;
+
+/**
+ * This example shows how to get metadata from a WS-Resource.
+ * The service supports different kinds of metadata.
+ * User who wants to receive metadata of a WS-Resource must
+ * send a GetMetadataRequesta specifying the requested dialect.
+ *
+ * Supported metadata that could be requested are
+ *
+ * <ul>
+ * <li>
+ * WSDL : requested using "http://schemas.xmlsoap.org/wsdl/" as dialect..
+ * <li>
+ * <li>
+ * RDM (Resource Metadata Descriptor) : requested using "http://docs.oasis-open.org/wsrf/rmd-1 "as dialect.
+ * </li>
+ * </ul>
+ *
+ * Note that this example focuses on WSDL Metadata only; another example is dedicated to RDM.
+ *
+ * @author Andrea Gazzarini
+ */
+public class GetWSDLMetadataExample extends AbstractQManExample
+{
+
+ /**
+ * First, sends a request to WS-DM Adapter in order to get the list of managed resources.
+ * If the list is not empty, then takes the first member and sends it a GetMetadataRequest
+ * in order to get its WSDL.
+ *
+ * @param host the host where QMan is running.
+ * @param port the port where QMan is running.
+ * @throws Exception when the example fails (not at application level).
+ */
+ void executeExample(String host, int port) throws Exception
+ {
+
+ // 1) Creates an endpoint reference of the adapter service...
+ EndpointReference adapterEndpointReference = getAdapterEndpointReference(host, port);
+
+ // 2) Creates the Adapter service client...
+ ServiceGroupClient adapterClient = new ServiceGroupClient(adapterEndpointReference);
+ adapterClient.setTrace(true);
+
+ // 3) Retrieves the all registered members (QMan WS-Resources)
+ WsResourceClient [] resources = adapterClient.getMembers();
+
+ // Sanity check : we cannot proceed if there are no WS-Resources.
+ if (resources.length == 0)
+ {
+ System.out.println("----------------------------WARNING---------------------------");
+ System.out.println("Cannot proceed with the example... it seems");
+ System.out.println("that there are no managed WS-Resources on QMan.");
+ System.out.println("Please check QMan in order to see that it is really");
+ System.out.println("connected with a broker.");
+ System.out.println("-------------------------------------------------------------------");
+ System.exit(0);
+ }
+
+ // 4) Creates a proxy handler for service invocation.
+ ProxyHandler metadataProxyHandler = createProxyHandler();
+
+ // 5) ..and invokes the GetMetadata on the first member.
+ WsResourceClient firstMember = resources[0];
+ firstMember.setTrace(true);
+
+ // Dialect is WSDL for this example
+ String dialect = "http://schemas.xmlsoap.org/wsdl/";
+ Object [] inputParameters = {dialect};
+
+ // WSDL is the first element of the returned array. We don't need to print out it here
+ // because at this point it should have been already printed out (line 96 : firstMember.setTrace(true))
+ @SuppressWarnings("unused")
+ Element [] metadata = (Element[]) firstMember.invoke(metadataProxyHandler, inputParameters);
+ }
+
+ /**
+ * Prints out a description of this example.
+ */
+ void printOutExampleDescription()
+ {
+ System.out.println(" "+getClass().getSimpleName()+" ");
+ System.out.println("-------------------------------------------------------------------");
+ System.out.println();
+ System.out.println("The example shows how to get metadata from a");
+ System.out.println("WS-Resource.");
+ System.out.println("A QMan WS-Resource has different kinds of metadata.");
+ System.out.println("(see below)");
+ System.out.println("User who wants to receive metadata of a WS-Resource");
+ System.out.println("must send a GetMetadataRequesta specifying the");
+ System.out.println("associated dialect.");
+ System.out.println("Supported metadata that could be requested are : ");
+ System.out.println();
+ System.out.println("- WSDL : in this case dialect is \"http://schemas.xmlsoap.org/wsdl/\";");
+ System.out.println("- RDM (Resource Metadata Descriptor) : in this case dialect is \"http://docs.oasis-open.org/wsrf/rmd-1 \".");
+ System.out.println();
+ System.out.println("Note that this examples focuses on WSDL Metadata only;");
+ System.out.println("another one is dedicated to RDM.");
+ System.out.println("-------------------------------------------------------------------");
+ System.out.println();
+ }
+
+ /**
+ * A proxy handler is a module needed in order to make a capability
+ * service invocation.
+ * It contains logic to serialize and deserialize request, response, input and
+ * output parameters during a web service invocation.
+ *
+ * @return a proxy handler.
+ */
+ private ProxyHandler createProxyHandler()
+ {
+ ProxyHandler handler = new ReflectionProxyHandler();
+ handler.setAction("http://schemas.xmlsoap.org/ws/2004/09/mex/GetMetadata");
+ handler.setRequestName(new QName("http://schemas.xmlsoap.org/ws/2004/09/mex", "GetMetadata", PREFIX));
+ handler.setRequestParameterNames(new QName[]{new QName("http://schemas.xmlsoap.org/ws/2004/09/mex", "Dialect", PREFIX)});
+ handler.setResponseName(new QName("http://schemas.xmlsoap.org/ws/2004/09/mex", "Metadata", PREFIX));
+ handler.setReturnType(Element[].class);
+ return handler;
+ }
+
+ public static void main(String[] arguments)
+ {
+ new GetWSDLMetadataExample().execute(arguments);
+ }
+} \ No newline at end of file
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/example/org/apache/qpid/management/example/SetResourcePropertyExample.java b/qpid/java/management/client/src/example/org/apache/qpid/management/example/SetResourcePropertyExample.java
new file mode 100644
index 0000000000..8aed3101ff
--- /dev/null
+++ b/qpid/java/management/client/src/example/org/apache/qpid/management/example/SetResourcePropertyExample.java
@@ -0,0 +1,306 @@
+/*
+ *
+ * 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.lang.reflect.Array;
+import java.util.HashMap;
+import java.util.Map;
+
+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.EndpointReference;
+import org.apache.muse.ws.resource.remote.WsResourceClient;
+import org.apache.muse.ws.resource.sg.remote.ServiceGroupClient;
+import org.w3c.dom.Element;
+
+/**
+ * This example shows how to change the state of a WS-Resource. That means
+ * a SetResourcePropertyRequest is sent to that WS-Resource.
+ * First of all a request is send to WS-DM in order to get all registered WS-Resources.
+ * If the returned list is not empty then two GetMetadataRequests are sent to the
+ * first child (one for WSDL and one for RDM).
+ * The result metadata descriptors are the used to determine :
+ *
+ * <br> What are names of WS-Resouce properties
+ * <br> Their modifiability (read-only or read-write)
+ * <br> Their type
+ *
+ * So a SetResourcePropertyRequest can be sent in order to change the WS-Resource state.
+ * The example is looking for a property that has one of the following datatype :
+ *
+ * <ul>
+ * <li>String</li>
+ * <li>Long</li>
+ * <li>Integer</li>
+ * <li>Short</li>
+ * <li>Double</li>
+ * <li>Float</li>
+ * </ul>
+ *
+ * After the update / insert request has been sent, a GetResourcePropertiesRequest is made
+ * again in order to see if the state has changed correctly.
+ *
+ * @author Andrea Gazzarini
+ */
+public class SetResourcePropertyExample extends AbstractQManExample
+{
+ /**
+ * First of all a request is send to WS-DM in order to get all registered WS-Resources.
+ * If the returned list is not empty then two GetMetadataRequests are sent to the
+ * first child (one for WSDL and one for RDM).
+ * The result metadata descriptors are the used to determine :
+ *
+ * <br> What are names of WS-Resouce properties
+ * <br> Their modifiability (read-only or read-write)
+ * <br> Their type
+ *
+ * So a SetResourcePropertyRequest can be sent in order to change the WS-Resource state.
+ * The example is looking for a property that has one of the following datatype :
+ *
+ * <ul>
+ * <li>String</li>
+ * <li>Long</li>
+ * <li>Integer</li>
+ * <li>Short</li>
+ * <li>Double</li>
+ * <li>Float</li>
+ * </ul>
+ *
+ * After the update / insert request has been sent, a GetResourcePropertiesRequest is made
+ * again in order to see if the state has changed correctly.
+ *
+ * @param host the host where QMan is running.
+ * @param port the port where QMan is running.
+ * @throws Exception when the example fails (not at application level).
+ */
+ void executeExample(String host, int port) throws Exception
+ {
+ // 1) Creates an endpoint reference of the adapter service...
+ EndpointReference adapterEndpointReference = getAdapterEndpointReference(host, port);
+
+ // 2) Creates the Adapter service client...
+ ServiceGroupClient adapterClient = new ServiceGroupClient(adapterEndpointReference);
+ adapterClient.setTrace(false);
+
+ // 3) Retrieves the all registered members (QMan WS-Resources)
+ WsResourceClient [] resources = adapterClient.getMembers();
+
+ // Sanity check : we cannot proceed if there are no WS-Resources.
+ if (resources.length == 0)
+ {
+ System.out.println("----------------------------WARNING---------------------------");
+ System.out.println("Cannot proceed with the example... it seems");
+ System.out.println("that there are no managed WS-Resources on QMan.");
+ System.out.println("Please check QMan in order to see that it is really");
+ System.out.println("connected with a broker.");
+ System.out.println("-------------------------------------------------------------------");
+ System.exit(0);
+ }
+
+ // 4) Creates a proxy handler for service invocation.
+ ProxyHandler metadataProxyHandler = createProxyHandler();
+
+ // 5) ..and invokes the GetMetadata on the first member.
+ WsResourceClient wsResourceClient = resources[0];
+ wsResourceClient.setTrace(true);
+
+ // Resource Metadata Descriptor
+ String dialect = "http://docs.oasis-open.org/wsrf/rmd-1";
+ Object [] inputParameters = {dialect};
+
+ // RDM is the first element of the returned array.
+ // The first element is a wsx:Metadata containing all resource properties.
+ Element [] metadata = (Element[]) wsResourceClient.invoke(metadataProxyHandler, inputParameters);
+ Element resourceMetadataDescriptor = metadata[0];
+
+ // 6) Now we need WSDL in order to catch datatypes
+ dialect = "http://schemas.xmlsoap.org/wsdl/";
+ inputParameters = new Object[]{dialect};
+ metadata = (Element[]) wsResourceClient.invoke(metadataProxyHandler, inputParameters);
+ Element wsdl = metadata[0];
+
+ //7) Defines sample values used for update property.
+ Map<String, Object> sampleValues = new HashMap<String, Object>();
+ sampleValues.put("xsd:string","This is a string.");
+ sampleValues.put("xsd:integer",new Integer(12345));
+ sampleValues.put("xsd:int",new Integer(54321));
+ sampleValues.put("xsd:long",new Integer(12345));
+ sampleValues.put("xsd:double",new Double(12345.6d));
+ sampleValues.put("xsd:float",new Float(123.4f));
+ sampleValues.put("xsd:short",new Short((short)12));
+
+ // 8) using XPath navigates xml in order to get the list of all properties.
+ Element [] properties = XmlUtils.findInSubTree(
+ resourceMetadataDescriptor,
+ new QName("http://docs.oasis-open.org/wsrf/rmd-1","Property","wsrmd"));
+
+ Element [] wsdlElements = XmlUtils.findInSubTree(
+ wsdl,
+ new QName("http://www.w3.org/2001/XMLSchema","element","xsd"));
+
+ // Did we find at least one writable property?
+ boolean atLeastOnePropertyHasBeenFound = false;
+
+ for (Element property : properties)
+ {
+ // Sanity check : if the property is read-only then proceed with next
+ // property.
+ if (!"read-write".equals(property.getAttribute("modifiability")))
+ {
+ continue;
+ }
+
+ String attributeName = property.getAttribute("name"); // = qman:<Attribute Name>
+
+ // For this example we are only interested on qman namespace related properties...
+ if (attributeName.startsWith("qman"))
+ {
+ String attributeNameWithoutPrefix = attributeName.replaceFirst("qman:", ""); // = <Attribute Name>
+
+ for (Element wsdlElement : wsdlElements)
+ {
+ String name = wsdlElement.getAttribute("name");
+ String type = wsdlElement.getAttribute("type");
+ if ((name != null) && (attributeNameWithoutPrefix.equals(name)) && (type != null))
+ {
+ Object newValue = sampleValues.get(type);
+ if (newValue != null)
+ {
+ atLeastOnePropertyHasBeenFound = true;
+
+ inputParameters = new Object[] {newValue};
+
+ // 9) Makes a GetResourcePropertiesRequest in order to get the current value.
+ QName propertyQName = new QName(
+ "http://amqp.apache.org/qpid/management/qman",
+ name,
+ "qman");
+
+ // The returned value is really an array because property shoudl be a multi-value property.
+ // So in order to get its value we need to extract the first value.
+ Object currentValue = wsResourceClient.getPropertyAsObject(propertyQName,newValue.getClass());
+
+ // 10a) If the property is not set (value is null) then an "Insert" request must be sent.
+ if (currentValue == null || Array.getLength(currentValue) == 0)
+ {
+ wsResourceClient.insertResourceProperty(propertyQName,inputParameters);
+ }
+ // 10b) If the property is not null then an "Update" request must be sent.
+ else
+ {
+ wsResourceClient.updateResourceProperty(propertyQName,inputParameters);
+ }
+
+ // 11) Let's query again the resource using GetResourceProperties in order to ensure the
+ // previous property has been properly updated.
+ currentValue = wsResourceClient.getPropertyAsObject(propertyQName,newValue.getClass());
+
+ String resultMessage = (newValue.equals(Array.get(currentValue, 0)))
+ ? "Resource has been correctly updated."
+ : "Something was wrong : resource seems not to be properly updated.";
+
+ System.out.println("----------------------------------------------------------------------------------");
+ System.out.println(resultMessage);
+ System.out.println("----------------------------------------------------------------------------------");
+
+ // Let's stop...one property is enough for this example :)
+ break;
+ }
+ }
+ }
+ if (!atLeastOnePropertyHasBeenFound)
+ {
+ System.out.println("----------------------------------------------------------------------------------");
+ System.out.println("WARNING : This example wasn't able to run because no writable ");
+ System.out.println("property has been found on the target WS-Resource.");
+ System.out.println("----------------------------------------------------------------------------------");
+ }
+ }
+ }
+ }
+
+ /**
+ * Prints out a description of this example.
+ */
+ void printOutExampleDescription()
+ {
+ System.out.println(" "+getClass().getSimpleName()+" ");
+ System.out.println("-------------------------------------------------------------------");
+ System.out.println();
+ System.out.println("This example shows how to change the state of a WS-Resource.");
+ System.out.println("That means a SetResourcePropertyRequest is sent to that");
+ System.out.println("WS-Resource.");
+ System.out.println("First of all a request is send to WS-DM in order to get all");
+ System.out.println("registered WS-Resources.");
+ System.out.println("If the returned list is not empty then two GetMetadataRequests");
+ System.out.println("(one for WSDL and one for RDM) are sent to the first child.");
+ System.out.println("The result metadata descriptors are used for determine :");
+ System.out.println();
+ System.out.println("1) WS-Resource property names;");
+ System.out.println("2) Modifiability (read-only, read-write");
+ System.out.println("3) Datatype;");
+ System.out.println("-------------------------------------------------------------------");
+ System.out.println();
+ System.out.println("So a SetResourcePropertyRequest can be sent in order");
+ System.out.println("to change the WS-Resource state.");
+ System.out.println("The example is looking for a property that has one of the");
+ System.out.println("following datatype :");
+ System.out.println();
+ System.out.println("1) String (xsd:string)");
+ System.out.println("2) Long (xsd:long)");
+ System.out.println("3) Integer (xsd:integer or xsd:int)");
+ System.out.println("4) Double (xsd:double)");
+ System.out.println("5) Float (xsd:float)");
+ System.out.println("6) Short (xsd:short)");
+ System.out.println();
+ System.out.println("After the update / insert request has been sent, a ");
+ System.out.println("GetResourcePropertiesRequest is made again");
+ System.out.println("in order to see if the state has changed correctly.");
+ System.out.println();
+ }
+
+ /**
+ * A proxy handler is a module needed in order to make a capability
+ * service invocation.
+ * It contains logic to serialize and deserialize request, response, input and
+ * output parameters during a web service invocation.
+ *
+ * @return a proxy handler.
+ */
+ private ProxyHandler createProxyHandler()
+ {
+ ProxyHandler handler = new ReflectionProxyHandler();
+ handler.setAction("http://schemas.xmlsoap.org/ws/2004/09/mex/GetMetadata");
+ handler.setRequestName(new QName("http://schemas.xmlsoap.org/ws/2004/09/mex", "GetMetadata", PREFIX));
+ handler.setRequestParameterNames(new QName[]{new QName("http://schemas.xmlsoap.org/ws/2004/09/mex", "Dialect", PREFIX)});
+ handler.setResponseName(new QName("http://schemas.xmlsoap.org/ws/2004/09/mex", "Metadata", PREFIX));
+ handler.setReturnType(Element[].class);
+ return handler;
+ }
+
+ public static void main(String[] arguments)
+ {
+ new SetResourcePropertyExample().execute(arguments);
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/muse.xml b/qpid/java/management/client/src/main/java/muse.xml
new file mode 100644
index 0000000000..29a1c02e0c
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/muse.xml
@@ -0,0 +1,209 @@
+<?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.
+
+-->
+
+<muse xmlns="http://ws.apache.org/muse/descriptor"
+ xmlns:wsrf-sgw="http://docs.oasis-open.org/wsrf/sgw-2"
+ xmlns:qman="http://amqp.apache.org/qpid/management/qman"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://ws.apache.org/muse/descriptor muse-descriptor.xsd">
+ <custom-serializer>
+ <java-serializable-type>java.lang.Object</java-serializable-type>
+ <java-serializer-class>org.apache.qpid.management.wsdm.muse.serializer.ObjectSerializer</java-serializer-class>
+ </custom-serializer>
+ <custom-serializer>
+ <java-serializable-type>java.util.Map</java-serializable-type>
+ <java-serializer-class>org.apache.qpid.management.wsdm.muse.serializer.MapSerializer</java-serializer-class>
+ </custom-serializer>
+ <custom-serializer>
+ <java-serializable-type>java.util.HashMap</java-serializable-type>
+ <java-serializer-class>org.apache.qpid.management.wsdm.muse.serializer.MapSerializer</java-serializer-class>
+ </custom-serializer>
+ <custom-serializer>
+ <java-serializable-type>java.util.UUID</java-serializable-type>
+ <java-serializer-class>org.apache.qpid.management.wsdm.muse.serializer.UUIDSerializer</java-serializer-class>
+ </custom-serializer>
+ <custom-serializer>
+ <java-serializable-type>org.apache.qpid.management.wsdm.capabilities.Result</java-serializable-type>
+ <java-serializer-class>org.apache.qpid.management.wsdm.muse.serializer.InvocationResultSerializer</java-serializer-class>
+ </custom-serializer>
+ <custom-serializer>
+ <java-serializable-type>java.util.Date</java-serializable-type>
+ <java-serializer-class>org.apache.qpid.management.wsdm.muse.serializer.DateSerializer</java-serializer-class>
+ </custom-serializer>
+ <router>
+ <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>
+ </logging>
+ <persistence>
+ <java-persistence-class>org.apache.muse.core.routing.RouterFilePersistence</java-persistence-class>
+ <persistence-location>router-entries</persistence-location>
+ </persistence>
+ </router>
+ <resource-type use-router-persistence="true">
+ <context-path>consumer</context-path>
+ <wsdl>
+ <wsdl-file>wsdl/WS-BaseNotification-1_3.wsdl</wsdl-file>
+ <wsdl-port-type xmlns:wsntw="http://docs.oasis-open.org/wsn/bw-2">wsntw:NotificationConsumer</wsdl-port-type>
+ </wsdl>
+ <java-id-factory-class>org.apache.qpid.management.wsdm.common.QManResourceIdFactory</java-id-factory-class>
+ <java-resource-class>org.apache.muse.core.SimpleResource</java-resource-class>
+ <capability>
+ <capability-uri>http://docs.oasis-open.org/wsn/bw-2/NotificationConsumer</capability-uri>
+ <java-capability-class>org.apache.muse.ws.notification.impl.SimpleNotificationConsumer</java-capability-class>
+ </capability>
+ <capability>
+ <capability-uri>http://amqp.apache.org/qpid/management/qman/consumer</capability-uri>
+ <java-capability-class>org.apache.qpid.management.wsdm.capabilities.ConsumerCapability</java-capability-class>
+ </capability>
+ </resource-type>
+ <resource-type>
+ <context-path>SubscriptionManager</context-path>
+ <wsdl>
+ <wsdl-file>wsdl/WS-BaseNotification-1_3.wsdl</wsdl-file>
+ <wsdl-port-type xmlns:wsntw="http://docs.oasis-open.org/wsn/bw-2">wsntw:SubscriptionManager</wsdl-port-type>
+ </wsdl>
+ <java-id-factory-class>org.apache.qpid.management.wsdm.common.QManResourceIdFactory</java-id-factory-class>
+ <java-resource-class>org.apache.muse.ws.resource.impl.SimpleWsResource</java-resource-class>
+ <capability>
+ <capability-uri>http://schemas.xmlsoap.org/ws/2004/09/mex/GetMetadata</capability-uri>
+ <java-capability-class>org.apache.muse.ws.metadata.impl.SimpleMetadataExchange</java-capability-class>
+ </capability>
+ <capability>
+ <capability-uri>http://docs.oasis-open.org/wsrf/rpw-2/Get</capability-uri>
+ <java-capability-class>org.apache.muse.ws.resource.properties.get.impl.SimpleGetCapability</java-capability-class>
+ </capability>
+ <capability>
+ <capability-uri>http://docs.oasis-open.org/wsn/bw-2/SubscriptionManager</capability-uri>
+ <java-capability-class>org.apache.muse.ws.notification.impl.SimpleSubscriptionManager</java-capability-class>
+ <init-param>
+ <param-name>trace-notifications</param-name>
+ <param-value>true</param-value>
+ </init-param>
+ </capability>
+ <capability>
+ <capability-uri>http://docs.oasis-open.org/wsrf/rlw-2/ImmediateResourceTermination</capability-uri>
+ <java-capability-class>org.apache.muse.ws.resource.lifetime.impl.SimpleImmediateTermination</java-capability-class>
+ </capability>
+ <capability>
+ <capability-uri>http://docs.oasis-open.org/wsrf/rlw-2/ScheduledResourceTermination</capability-uri>
+ <java-capability-class>org.apache.muse.ws.resource.lifetime.impl.SimpleScheduledTermination</java-capability-class>
+ </capability>
+ <init-param>
+ <param-name>validate-wsrp-schema</param-name>
+ <param-value>false</param-value>
+ </init-param>
+ </resource-type>
+ <resource-type use-router-persistence="true">
+ <context-path>adapter</context-path>
+ <wsdl>
+ <wsdl-file>wsdl/QManAdapter.wsdl</wsdl-file>
+ <wsdl-port-type xmlns:qman="http://amqp.apache.org/qpid/management/qman">qman:QManAdapterPortType</wsdl-port-type>
+ </wsdl>
+ <java-id-factory-class>org.apache.qpid.management.wsdm.common.QManResourceIdFactory</java-id-factory-class>
+ <java-resource-class>org.apache.muse.ws.resource.impl.SimpleWsResource</java-resource-class>
+ <capability>
+ <capability-uri >http://amqp.apache.org/qpid/management/qman</capability-uri>
+ <java-capability-class>org.apache.qpid.management.wsdm.capabilities.QManAdapterCapability</java-capability-class>
+ </capability>
+ <capability>
+ <capability-uri>http://schemas.xmlsoap.org/ws/2004/09/mex/GetMetadata</capability-uri>
+ <java-capability-class>org.apache.muse.ws.metadata.impl.SimpleMetadataExchange</java-capability-class>
+ </capability>
+ <capability>
+ <capability-uri>http://docs.oasis-open.org/wsrf/rpw-2/Get</capability-uri>
+ <java-capability-class>org.apache.muse.ws.resource.properties.get.impl.SimpleGetCapability</java-capability-class>
+ </capability>
+ <capability>
+ <capability-uri>http://docs.oasis-open.org/wsrf/rpw-2/Query</capability-uri>
+ <java-capability-class>org.apache.muse.ws.resource.properties.query.impl.SimpleQueryCapability</java-capability-class>
+ </capability>
+ <capability>
+ <capability-uri>http://docs.oasis-open.org/wsrf/sgw-2/ServiceGroup</capability-uri>
+ <java-capability-class>org.apache.muse.ws.resource.sg.impl.SimpleServiceGroup</java-capability-class>
+ </capability>
+ <capability>
+ <capability-uri>http://docs.oasis-open.org/wsn/bw-2/NotificationProducer</capability-uri>
+ <java-capability-class>org.apache.muse.ws.notification.impl.SimpleNotificationProducer</java-capability-class>
+ </capability>
+ <init-param>
+ <param-name>validate-wsrp-schema</param-name>
+ <param-value>false</param-value>
+ </init-param>
+ </resource-type>
+ <resource-type>
+ <context-path>QManWsResource</context-path>
+ <wsdl>
+ <!-- Note that this is not a complete WSDL. It is just a base template where resource specific capabilities wll be added. -->
+ <wsdl-file>wsdl/QManWsResource.wsdl</wsdl-file>
+ <wsdl-port-type xmlns:qman="http://amqp.apache.org/qpid/management/qman">qman:QManWsResourcePortType</wsdl-port-type>
+ </wsdl>
+ <java-id-factory-class>org.apache.qpid.management.wsdm.common.ObjectNameIdFactory</java-id-factory-class>
+ <java-resource-class>org.apache.qpid.management.wsdm.muse.resources.QManWsResource</java-resource-class>
+ <capability>
+ <capability-uri>http://schemas.xmlsoap.org/ws/2004/09/mex/GetMetadata</capability-uri>
+ <java-capability-class>org.apache.qpid.management.wsdm.capabilities.QManMetadataExchangeCapability</java-capability-class>
+ </capability>
+ <capability>
+ <capability-uri>http://docs.oasis-open.org/wsrf/rpw-2/Get</capability-uri>
+ <java-capability-class>org.apache.muse.ws.resource.properties.get.impl.SimpleGetCapability</java-capability-class>
+ </capability>
+ <capability>
+ <capability-uri>http://docs.oasis-open.org/wsrf/rpw-2/Query</capability-uri>
+ <java-capability-class>org.apache.muse.ws.resource.properties.query.impl.SimpleQueryCapability</java-capability-class>
+ </capability>
+ <capability>
+ <capability-uri>http://docs.oasis-open.org/wsrf/rpw-2/Set</capability-uri>
+ <java-capability-class>org.apache.muse.ws.resource.properties.set.impl.SimpleSetCapability</java-capability-class>
+ </capability>
+ <capability>
+ <capability-uri>http://docs.oasis-open.org/wsrf/rpw-2/Put</capability-uri>
+ <java-capability-class>org.apache.muse.ws.resource.properties.set.impl.SimpleSetCapability</java-capability-class>
+ </capability>
+ </resource-type>
+ <resource-type>
+ <context-path>ServiceGroupEntry</context-path>
+ <wsdl>
+ <wsdl-file>/wsdl/WS-ServiceGroupEntry-1_2.wsdl</wsdl-file>
+ <wsdl-port-type>wsrf-sgw:ServiceGroupEntryPortType</wsdl-port-type>
+ </wsdl>
+ <java-id-factory-class>org.apache.qpid.management.wsdm.common.QManResourceIdFactory</java-id-factory-class>
+ <java-resource-class>org.apache.muse.ws.resource.impl.SimpleWsResource</java-resource-class>
+ <capability>
+ <capability-uri>http://schemas.xmlsoap.org/ws/2004/09/mex/GetMetadata</capability-uri>
+ <java-capability-class>org.apache.muse.ws.metadata.impl.SimpleMetadataExchange</java-capability-class>
+ </capability>
+ <capability>
+ <capability-uri>http://docs.oasis-open.org/wsrf/rpw-2/Get</capability-uri>
+ <java-capability-class>org.apache.muse.ws.resource.properties.get.impl.SimpleGetCapability</java-capability-class>
+ </capability>
+ <capability>
+ <capability-uri>http://docs.oasis-open.org/wsrf/sgw-2/ServiceGroupEntry</capability-uri>
+ <java-capability-class>org.apache.muse.ws.resource.sg.impl.SimpleEntry</java-capability-class>
+ </capability>
+ <init-param>
+ <param-name>validate-wsrp-schema</param-name>
+ <param-value>false</param-value>
+ </init-param>
+ </resource-type>
+</muse>
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
new file mode 100644
index 0000000000..4f84128fb3
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/Messages.java
@@ -0,0 +1,175 @@
+/*
+*
+ * 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;
+
+/**
+ * Enumerative interfaces containing all QMan messages.
+ *
+ * @author Andrea Gazzarini
+ */
+public interface Messages
+{
+ // MESSAGES
+ String EVENT_SEVERITY_ATTRIBUTE_DESCRIPTION = "Severity level for this event.";
+ String EVENT_TIMESTAMP_ATTRIBUTE_DESCRIPTION = "Current timestamp of this event.";
+ String ACTION_NOT_SUPPORTED="Action %s not supported by resource %s.";
+
+ // INFO
+ String QMAN_000001_STARTING_QMAN = "<QMAN-000001> : Starting Q-Man...";
+ String QMAN_000002_READING_CONFIGURATION = "<QMAN-000002> : Reading Q-Man configuration...";
+ String QMAN_000003_CREATING_MANAGEMENT_CLIENTS = "<QMAN-000003> : Creating management client(s)...";
+ String QMAN_000004_MANAGEMENT_CLIENT_CONNECTED = "<QMAN-000004> : Management client for broker %s successfully connected.";
+ String QMAN_000005_TYPE_MAPPING_CONFIGURED = "<QMAN-000005> : Type mapping : code = %s associated to %s (validator class is %s)";
+ String QMAN_000006_ACCESS_MODE_MAPPING_CONFIGURED = "<QMAN-000006> : Access Mode mapping : code = %s associated to %s";
+ String QMAN_000007_MANAGEMENT_HANDLER_MAPPING_CONFIGURED = "<QMAN-000007> : Management Queue Message Handler Mapping : opcode = %s associated with %s";
+ String QMAN_000008_METHOD_REPLY_HANDLER_MAPPING_CONFIGURED = "<QMAN-000008> : Method-Reply Queue Message Handler Mapping : opcode = %s associated with %s";
+ String QMAN_000009_BROKER_DATA_CONFIGURED = "<QMAN-000009> : Broker configuration %s: %s";
+ String QMAN_000010_INCOMING_SCHEMA = "<QMAN-000010> : Incoming schema for %s::%s.%s";
+ String QMAN_000011_SHUTDOWN_INITIATED = "<QMAN-000011> : The shutdown sequence has been initiated for management client connected with broker %s";
+ String QMAN_000012_MANAGEMENT_CLIENT_SHUT_DOWN = "<QMAN-000012> : Management client connected with broker %s shut down successfully.";
+ String QMAN_000013_METHOD_REPLY_CONSUMER_INSTALLED = "<QMAN-000013> : Method-reply queue consumer has been successfully installed and bound on broker %s.";
+ String QMAN_000014_MANAGEMENT_CONSUMER_INSTALLED ="<QMAN-000014> : Management queue consumer has been successfully installed and bound on broker %s.";
+ String QMAN_000015_MANAGEMENT_QUEUE_DECLARED = "<QMAN-000015> : Management queue with name %s has been successfully declared and bound on broker %s.";
+ String QMAN_000016_METHOD_REPLY_QUEUE_DECLARED = "<QMAN-000016> : Method-reply queue with name %s has been successfully declared and bound on broker %s.";
+ String QMAN_000017_CONSUMER_HAS_BEEN_REMOVED = "<QMAN-000017> : Consumer %s has been removed from broker %s.";
+ String QMAN_000018_QUEUE_UNDECLARED = "<QMAN-000018> : Queue %s has been removed from broker %s.";
+ String QMAN_000019_QMAN_STARTED = "<QMAN-000019> : Q-Man open for e-business.";
+ String QMAN_000020_SHUTTING_DOWN_QMAN = "<QMAN-000020> : Shutting down Q-Man...";
+ String QMAN_000021_SHUT_DOWN = "<QMAN-000021> : Q-Man shut down.";
+ String QMAN_000022_NO_BROKER_CONFIGURED = "<QMAN-000022> : Q-Man has no configured broker : in order to connect with a running one use Q-Man Administration interface.";
+ String QMAN_000023_QMAN_REGISTERED_AS_MBEAN = "<QMAN-000023> : Q-Man service is now available on MBeanServer.";
+
+ String QMAN_000026_WSDM_ADAPTER_STARTS = "<QMAN-000026> : Initializing WS-DM Adapter Environment...";
+ String QMAN_000027_WSDM_ADAPTER_STARTED = "<QMAN-000027> : WS-DM Adapter ready for incoming requests.";
+ String QMAN_000028_TEST_MODULE_NOT_FOUND = "<QMAN-000028> : Qpid emulator not found. Test notifications are disabled.";
+ String QMAN_000029_DEFAULT_URI = "<QMAN-000029> : Default URI will be set to %s";
+ String QMAN_000030_RESOURCE_HAS_BEEN_CREATED = "<QMAN-000030> : New resource instance has been created and registered. Resource id is %s";
+ String QMAN_000031_RESOURCE_HAS_BEEN_REMOVED = "<QMAN-000031> : WS-Resource %s has been removed";
+ String QMAN_000032_EVENTS_LIFECYCLE_TOPIC_HAS_BEEN_CREATED = "<QMAN-000032> : Events lifecycle topic has been created with name %s";
+ String QMAN_000033_OBJECTS_LIFECYCLE_TOPIC_HAS_BEEN_CREATED = "<QMAN-000033> : Objects lifecycle topic has been created with name %s";
+ String QMAN_000034_UNCLASSIFIED_LIFECYCLE_TOPIC_HAS_BEEN_CREATED = "<QMAN-000034> : Unclassified object types lifecycle topic has been created with name %s";
+ String QMAN_000035_WORK_MANAGER_POOL_SIZE = "<QMAN-000035> : Work Manager thread pool size : %s";
+ String QMAN_000036_WORK_MANAGER_MAX_POOL_SIZE = "<QMAN-000036> : Work Manager thread pool max size : %s";
+ String QMAN_000037_WORK_MANAGER_KEEP_ALIVE_TIME = "<QMAN-000035> : Work Manager keep alive time : %s";
+
+ // DEBUG
+ String QMAN_200001_INCOMING_MESSAGE_HAS_BEEN_RECEIVED = "<QMAN-200001> : New incoming message has been received. Message content is %s";
+ String QMAN_200002_OPCODE_HANDLER_ASSOCIATION = "<QMAN-200002> : \"%s\" opcode is associated to handler %s";
+ String QMAN_200003_MESSAGE_FORWARDING = "<QMAN-200003> : Incoming message with \"%s\" as opcode will be forwarded to %s for processing.";
+ String QMAN_200004_MANAGEMENT_QUEUE_NAME = "<QMAN-200004> : Management queue name : %s";
+ String QMAN_200005_METHOD_REPLY_QUEUE_NAME = "<QMAN-200005> : Method-reply queue name : %s";
+ String QMAN_200006_QPID_CONNECTION_RELEASED = "<QMAN-200006> : Connection %s returned to the pool.";
+ String QMAN_200007_TEST_CONNECTION_ON_RESERVE = "<QMAN-200007> : Test connection on reserve. Is valid? %s";
+ String QMAN_200008_CONNECTION_DESTROYED = "<QMAN-200008> : Connection has been destroyed.";
+ String QMAN_200009_CONNECTION_DESTROY_FAILURE = "<QMAN-200009> : Unable to destroy a connection object.";
+ String QMAN_200010_EVENT_MBEAN_REGISTERED = "<QMAN-200010> : Event instance %s::%s::%s successfully registered with MBean Server with name %s";
+ String QMAN_200011_OBJECT_MBEAN_REGISTERED = "<QMAN-200011> : Object instance %s::%s::%s:%s successfully registered with MBean Server with name %s";
+ String QMAN_200012_OBJECT_MBEAN_UNREGISTERED = "<QMAN-200012> : Object instance %s::%s::%s:%s successfully unregistered from MBean Server. Name was %s";
+ String QMAN_200013_ARGUMENT_VALUE_ENCODED = "<QMAN-200013> : Encoded value %S for argument %s. Type is %s";
+ String QMAN_200014_INCOMING_INSTRUMENTATION_DATA = "<QMAN-200014> : Incoming instrumentation data for %s::%s.%s.%s";
+ String QMAN_200015_INCOMING_CONFIGURATION_DATA = "<QMAN-200015> : Incoming configuration data for %s::%s.%s.%s";
+ String QMAN_200016_PROPERTY_DEFINITION_HAS_BEEN_BUILT = "<QMAN-200016> : Property definition for %s::%s.%s has been built.";
+ String QMAN_200017_STATISTIC_DEFINITION_HAS_BEEN_BUILT = "<QMAN-200017> : Statistic definition for %s::%s.%s has been built.";
+ String QMAN_200018_OPTIONAL_PROPERTIES_INFO = "<QMAN-200018> : Class %s::%s.%s has %s optional properties.";
+ String QMAN_200019_EVENT_ARGUMENT_DEFINITION_HAS_BEEN_BUILT = "<QMAN-200019> : Event argument definition for %s::%s.%s has been built.";
+ String QMAN_200020_ENTITY_DEFINITION_HAS_BEEN_BUILT = "<QMAN-200020> : Entity definition has been built (without schema) for %s::%s.%s";
+ String QMAN_200021_INCOMING_EVENT_DATA = "<QMAN-200021> : Incoming data for event %s::%s.%s";
+ String QMAN_200022_VALIDATOR_INSTALLED = "<QMAN-200022> : Validator %s for type %s successfully installed.";
+ String QMAN_200023_VALIDATOR_NOT_FOUND = "<QMAN-200023> : No validator was found for type %s. The default (empty) validator will be used.";
+ String QMAN_200024_MANAGEMENT_MESSAGE_HAS_BEEN_SENT = "<QMAN-200024> : Message has been sent to management exchange. Message content : %s";
+ String QMAN_200025_SUBSCRIPTION_DECLARED = "<QMAN-200025> : New subscription between queue %s and destination %s has been declared.";
+ String QMAN_200026_SUBSCRIPTION_REMOVED = "<QMAN-200026> : Subscription named %s has been removed from remote broker.";
+ String QMAN_200027_QUEUE_DECLARED = "<QMAN-200027> : New queue with name %s has been declared.";
+ String QMAN_200028_QUEUE_REMOVED= "<QMAN-200028> : New queue with name %s has been undeclared.";
+ String QMAN_200029_BINDING_DECLARED = "<QMAN-200029> : New binding with %s as routing key has been declared between queue %s and exchange %s.";
+ String QMAN_200030_BINDING_REMOVED = "<QMAN-200030> : Binding with %s as routing key has been removed between queue %s and exchange %s.";
+ String QMAN_200031_COMPOUND_MESSAGE_CONTAINS = "<QMAN-200031> : Incoming compound message contains %s message(s).";
+ String QMAN_200032_COMMAND_MESSAGE_ROUTING_KEY = "<QMAN-200032> : Command message routing key : %s";
+ String QMAN_200033_CAPABILITY_CLASS_HAS_BEEN_ADDED = "<QMAN-200033> : Capability has been added to this resource. Class is %s while URI is %s.";
+ String QMAN_200034_RMD_NAME = "<QMAN-200034> : Resource Metadata Descriptor name is %s.";
+ String QMAN_200035_RMD_PATH = "<QMAN-200035> : Resource Metadata Descriptor path is %s.";
+ String QMAN_200036_ADDITIONAL_RMD_PROPERTY = "<QMAN-200036> : Additional RMD property : %s";
+ String QMAN_200037_RMD = "<QMAN-200037> : Resource Metadata Descriptor : %s";
+ String QMAN_200038_WSRP = "<QMAN-200038> : WS Resource Properties fragment : %s";
+ String QMAN_200039_DEBUG_JMX_NOTIFICATION = "<QMAN-200039> : %s";
+ String QMAN_200040_WS_ARTIFACTS_CACHED = "<QMAN-200040> : WS Artifacts has been stored on cache with the following id : %s";
+ String QMAN_200041_INCOMING_OBJECT_NAME_AND_DERIVED_KEY = "<QMAN-200041> : Incoming object name : %s, derived search key : %s";
+ String QMAN_200042_REMOVING_RESOURCE = "<QMAN-200042> : WS-Resource %s is going to be removed";
+ String QMAN_200043_GENERATED_ACCESSOR_METHOD = "<QMAN-200043> : Generated accessor method for %s : %s";
+ String QMAN_200044_GENERATED_METHOD = "<QMAN-200044> : Generated method for %s : %s";
+
+ // WARNING
+ String QMAN_300001_MESSAGE_DISCARDED = "<QMAN-300001> : No handler has been configured for processing messages with \"%s\" as opcode. Message will be discarded.";
+ String QMAN_300002_UNKNOWN_SEQUENCE_NUMBER = "<QMAN-300002> : Unable to deal with incoming message because it contains a unknown sequence number (%s).";
+ String QMAN_300003_BROKER_ALREADY_CONNECTED = "<QMAN-300003> : Unable to enlist given broker connection data : QMan is already connected with broker %s";
+ String QMAN_300004_INVALID_CONFIGURATION_FILE = "<QMAN-300004> : The given configuration file (%s) is not valid (it doesn't exist or cannot be read)";
+ String QMAN_300005_QEMU_INITIALIZATION_FAILURE = "<QMAN-300005> : Unable to initialize QEmu module and therefore emulation won't be enabled...";
+
+ String QMAN_300006_OS_MBEAN_FAILURE = "<QMAN-300006> : Unable to retrieve Operating System properties. No values will be displayed for underlying Operation System.";
+ String QMAN_300007_RUNTIME_MBEAN_FAILURE = "<QMAN-300007> : Unable to retrieve Runtime Environment properties. No values will be displayed.";
+
+ // ERROR
+ String QMAN_100001_BAD_MAGIC_NUMBER_FAILURE = "<QMAN-100001> : Message processing failure : incoming message contains a bad magic number (%s) and therefore will be discaded.";
+ String QMAN_100002_MESSAGE_READ_FAILURE = "<QMAN-100002> : Message I/O failure : unable to read byte message content and therefore it will be discarded.";
+ String QMAN_100003_MESSAGE_PROCESS_FAILURE = "<QMAN-100003> : Message processing failure : unknown exception; see logs for more details.";
+ String QMAN_100004_HANDLER_INITIALIZATION_FAILURE = "<QMAN-100004> : Message handler configured for opcode %s thrown an exception in initialization and therefore will be discarded.";
+ String QMAN_100005_CLASS_SCHEMA_PROCESSING_FAILURE = "<QMAN-100005> : Q-Man was unable to process the schema response message.";
+ String QMAN_100006_EVENT_SCHEMA_PROCESSING_FAILURE = "<QMAN-100006> : Q-Man was unable to process the schema response message.";
+ String QMAN_100007_UNABLE_TO_CONNECT_WITH_BROKER = "<QMAN-100007> : Unable to connect with broker located on %s. This broker will be ignored.";
+
+
+ String QMAN_100010_METHOD_INVOCATION_RESULT_FAILURE = "<QMAN-100010> : an exception occurred while storing the result of a method invocation. Sequence number was %s";
+ String QMAN_100011_UNKNOWN_CLASS_KIND = "<QMAN-100011> : Unknwon class kind : %s).";
+ String QMAN_100012_SCHEMA_MESSAGE_PROCESSING_FAILURE = "<QMAN-100012> : Q-Man was unable to process the schema response message.";
+ String QMAN_100013_MBEAN_REGISTRATION_FAILURE = "<QMAN-100013> : Unable to unregister object instance %s.";
+ String QMAN_100014_ATTRIBUTE_DECODING_FAILURE = "<QMAN-100014> : Unable to decode value for attribute %s";
+ String QMAN_100015_UNABLE_TO_SEND_SCHEMA_REQUEST = "<QMAN-100015> : Unable to send a schema request schema for %s.%s";
+ String QMAN_100016_UNABLE_TO_DECODE_FEATURE_VALUE = "<QMAN-100016> : Unable to decode value for %s::%s::%s";
+ String QMAN_100017_UNABLE_TO_CONNECT = "<QMAN-100017>: Cannot connect to broker %s on %s";
+ String QMAN_100018_UNABLE_TO_STARTUP_CORRECTLY = "<QMAN-100018> : Q-Man was unable to startup correctly : see logs for further details.";
+ String QMAN_100019_REQ_OR_RES_MALFORMED = "<QMAN-100019> : Unexpected exception occurred on WSDM adapter layer : probably request or response was malformed.";
+ String QMAN_100020_ACTION_NOT_SUPPORTED = "<QMAN-100020> : "+ACTION_NOT_SUPPORTED;
+ String QMAN_100021_RMD_BUID_FAILURE = "<QMAN-100021> : Unable to build RDM for resource %s.";
+
+ String QMAN_100023_BUILD_WS_ARTIFACTS_FAILURE = "<QMAN-100023> : Unable to build WS artifacts.";
+ String QMAN_100024_CAPABILITY_INSTANTIATION_FAILURE = "<QMAN-100024> : Unable to instantiate generated capability class for %s.";
+ String QMAN_100025_WSRF_FAILURE = "<QMAN-100025> : Resource manager raised an exception while creating capability for %s.";
+ String QMAN_100026_SOAP_ADDRESS_REPLACEMENT_FAILURE = "<QMAN-100026> : Exception occurred while replacing the placeholder soap address with resource actual location.";
+ String QMAN_100027_RESOURCE_SHUTDOWN_FAILURE = "<QMAN-100027> : Shutdown failure while destroying resource %s.";
+ String QMAN_100029_MALFORMED_RESOURCE_URI_FAILURE = "<QMAN-100029> : Unable to define URI for QMan resources using \"%s\". It violates RFC 2396";
+ String QMAN_100030_JMX_CORE_STARTUP_FAILURE = "<QMAN-100030> : QMan JMX core Unexpected failure while starting up.";
+ String QMAN_100031_WS_RESOURCE_ALREADY_INITIALIZED = "<QMAN-100031> : Bad request has been received on this WS-Resource : Initialization is not possible because the resource has already been initialized.";
+ String QMAN_100032_WS_RESOURCE_NOT_YET_INITIALIZED = "<QMAN-100032> : Bad request has been received on this WS-Resource : Shutdown is not possible because the resource hasn't yet been initialized.";
+ String QMAN_100033_WS_RESOURCE_ALREADY_SHUTDOWN = "<QMAN-100033> : Bad request has been received on this WS-Resource : Shutdown is not possible because the resource has already been shutdown.";
+ String QMAN_100034_WSDL_SCHEMA_SECTION_NOT_FOUND = "<QMAN-100034> : Unable to get via XPath the schema section in WSDL.";
+ String QMAN_100035_RESOURCE_CAPABILITY_INVOCATION_FAILURE = "<QMAN-100035> : Resource thrown a failure while invoking a capability operation.";
+ String QMAN_100036_TOPIC_DECLARATION_FAILURE = "<QMAN-100036> : WS-DM Adapter was unable to declare events and / or objects lifecycle topic(s). As conseguence of that, QMan won't be able to correctly emit lifecycle notifications.";
+
+ // NEW
+ String QMAN_100035_GET_ATTRIBUTE_FAILURE = "<QMAN-100035> : Get Attribute invocation failure for attribute %s, resource %s.";
+ String QMAN_100036_SET_ATTRIBUTE_FAILURE = "<QMAN-100036> : Set Attribute invocation failure for attribute %s, resource %s.";
+ 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
new file mode 100644
index 0000000000..b60867d9ff
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/Names.java
@@ -0,0 +1,216 @@
+/*
+ *
+ * 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;
+
+import javax.management.ObjectName;
+import javax.xml.namespace.QName;
+
+/**
+ * Enumeration of literal strings to avoid code duplication.
+ */
+public abstract class Names
+{
+ public static final String MANAGEMENT_EXCHANGE = "qpid.management";
+ public static final String MANAGEMENT_ROUTING_KEY = "console.#";
+
+ public static final String MANAGEMENT_QUEUE_PREFIX = "management.";
+ public static final String METHOD_REPLY_QUEUE_PREFIX = "reply.";
+
+ public static final String AMQ_DIRECT_QUEUE = "amq.direct";
+ public static final String AGENT_ROUTING_KEY_PREFIX = "agent.";
+ public static final String AGENT_ROUTING_KEY = AGENT_ROUTING_KEY_PREFIX+"1.0";
+
+ public static final String APPLICATION_NAME ="Q-Man";
+
+ // Attributes
+ public static final String PACKAGE = "package";
+ public static final String CLASS = "class";
+ public static final String EVENT = "event";
+ public static final String OBJECT_ID="objectId";
+ public static final String BROKER_ID = "brokerId";
+ public static final String DOMAIN_NAME = "Q-MAN";
+
+ public static final String ARG_COUNT_PARAM_NAME = "argCount";
+ public static final String DEFAULT_PARAM_NAME ="default";
+
+ public static final String NUMBER_VALIDATOR = "org.apache.qpid.management.domain.model.QpidProperty$NumberValidator";
+ public static final String STRING_VALIDATOR = "org.apache.qpid.management.domain.model.QpidProperty$StringValidator";
+
+ public static final String QMAN_CONFIG_OPTION_NAME = "qman-config";
+
+ public static final String ADD_BROKER_OPERATION_NAME = "addBroker";
+
+ public static final String NOT_AVAILABLE = "N.A.";
+
+ public static final ObjectName QPID_EMULATOR_OBJECT_NAME;
+ static
+ {
+ try
+ {
+ QPID_EMULATOR_OBJECT_NAME = new ObjectName(
+ new StringBuilder()
+ .append(DOMAIN_NAME)
+ .append(':')
+ .append("Name=Qpid,Type=Emulator")
+ .toString());
+ } catch(Exception exception)
+ {
+ throw new ExceptionInInitializerError(exception);
+ }
+ }
+
+ public static final ObjectName QMAN_OBJECT_NAME;
+ static
+ {
+ try
+ {
+ QMAN_OBJECT_NAME = new ObjectName(
+ new StringBuilder()
+ .append(DOMAIN_NAME)
+ .append(':')
+ .append("Name=QMan,Type=Service")
+ .toString());
+ } catch(Exception exception)
+ {
+ throw new ExceptionInInitializerError(exception);
+ }
+ }
+
+ // WSDM Stuff
+ public static final String NAMESPACE_URI = "http://amqp.apache.org/qpid/management/qman";
+ public final static String PREFIX = "qman";
+
+ public static final String ADDRESSING_URI = "http://amqp.apache.org/qpid/management/qman/addressing";
+ public static final String ADDRESSING_PREFIX = "qman-wsa";
+
+ public static final QName RESOURCE_ID_QNAME = new QName(
+ ADDRESSING_URI,
+ "ResourceId",
+ ADDRESSING_PREFIX);
+
+ public static final QName RES_ID_QNAME = new QName(
+ NAMESPACE_URI,
+ "ResourceId",
+ PREFIX);
+
+ public static final QName RESOURCE_QNAME = new QName(
+ NAMESPACE_URI,
+ "Resource",
+ PREFIX);
+
+ public static final QName LIFECYCLE_EVENT_QNAME = new QName(
+ NAMESPACE_URI,
+ "LifeCycleEvent",
+ PREFIX);
+
+ public static final QName PACKAGE_NAME_QNAME = new QName(
+ NAMESPACE_URI,
+ "PackageName",
+ PREFIX);
+
+ public static final QName ENTITY_NAME_QNAME = new QName(
+ NAMESPACE_URI,
+ "Name",
+ PREFIX);
+
+ public static final String TIMEMILLIS_ATTRIBUTE_NAME="TimeMillis";
+
+ public final static String QMAN_RESOURCE_NAME = "QManWsResource";
+
+ public final static String VALIDATE_WSRP_PARAM = "validate-wsrp-schema";
+
+ public static final String WEB_APP_CLASSES_FOLDER = "/WEB-INF/classes";
+
+
+ public final static QName QMAN_RESOURCE_PORT_TYPE_NAME = new QName(
+ Names.NAMESPACE_URI,
+ "QManWsResourcePortType",
+ Names.PREFIX);
+
+ public final static QName QMAN_STATUS_TEXT_NAME = new QName(
+ Names.NAMESPACE_URI,
+ "Message",
+ Names.PREFIX);
+
+ public final static QName QMAN_STATUS_CODE_NAME = new QName(
+ Names.NAMESPACE_URI,
+ "ReturnCode",
+ Names.PREFIX);
+
+ public final static QName QMAN_STATUS_ATTRIBUTE_NAME= new QName(
+ Names.NAMESPACE_URI,
+ "AttributeName",
+ Names.PREFIX);
+
+ public final static QName OBJECTS_LIFECYLE_TOPIC_NAME= new QName(
+ Names.NAMESPACE_URI,
+ "ObjectsLifeCycleTopic",
+ Names.PREFIX);
+
+ public final static QName EVENTS_LIFECYLE_TOPIC_NAME= new QName(
+ Names.NAMESPACE_URI,
+ "EventsLifeCycleTopic",
+ Names.PREFIX);
+
+ public final static QName HOST_QNAME = new QName(
+ Names.NAMESPACE_URI,
+ "host",
+ Names.PREFIX);
+
+ public final static QName PORT_QNAME = new QName(
+ Names.NAMESPACE_URI,
+ "port",
+ Names.PREFIX);
+
+ public final static QName USERNAME_QNAME= new QName(
+ Names.NAMESPACE_URI,
+ "username",
+ Names.PREFIX);
+
+ public final static QName VIRTUAL_HOST_QNAME= new QName(
+ Names.NAMESPACE_URI,
+ "virtualHost",
+ Names.PREFIX);
+
+ public final static QName UNKNOWN_OBJECT_TYPE_LIFECYLE_TOPIC_NAME= new QName(
+ Names.NAMESPACE_URI,
+ "UnclassifiedLifeCycleTopic",
+ Names.PREFIX);
+
+
+ public final static String NAME_ATTRIBUTE = "name";
+ public final static String MODIFIABILITY = "modifiability";
+ public final static String READ_WRITE = "read-write";
+ public final static String READ_ONLY = "read-only";
+ public final static String MUTABILITY = "mutability";
+ public final static String MUTABLE = "mutable";
+
+ public final static String ENTRY = "entry";
+ public final static String KEY = "key";
+ public final static String VALUE = "value";
+ public final static String TYPE = "type";
+ public final static String XSI_TYPE = "xsi:"+TYPE;
+
+ public final static String ADAPTER_HOST_PROPERTY_NAME = "qman.host";
+ public final static String ADAPTER_PORT_PROPERTY_NAME = "qman.port";
+
+
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/Protocol.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/Protocol.java
new file mode 100644
index 0000000000..c1b1ceb5b4
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/Protocol.java
@@ -0,0 +1,52 @@
+/*
+ *
+ * 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;
+
+/**
+ * Protocol defined constants.
+ *
+ * @author Andrea Gazzarini
+ */
+public interface Protocol
+{
+ String MAGIC_NUMBER = "AM2";
+
+ char SCHEMA_REQUEST_OPCODE = 'S';
+ char SCHEMA_RESPONSE_OPCODE = Character.toLowerCase(SCHEMA_REQUEST_OPCODE);
+
+ char OPERATION_INVOCATION_REQUEST_OPCODE = 'M';
+ char OPERATION_INVOCATION_RESPONSE_OPCODE = Character.toLowerCase(OPERATION_INVOCATION_REQUEST_OPCODE);
+
+ char INSTRUMENTATION_CONTENT_RESPONSE_OPCODE = 'i';
+ char CONFIGURATION_CONTENT_RESPONSE_OPCDE = 'c';
+ char EVENT_CONTENT_RESPONSE_OPCDE = 'e';
+ char INSTR_AND_CONFIG_CONTENT_RESPONSE_OPCODE = 'g';
+
+ char HEARTBEAT_INDICATION_RESPONSE_OPCODE = 'h';
+
+ int CLASS = 1;
+ int EVENT = 2;
+
+ String DEFAULT_QMAN_HOSTNAME = "localhost";
+ int DEFAULT_QMAN_PORT_NUMBER = 8080;
+
+ String DEFAULT_ENDPOINT_URI = "http://localhost:8080/qman/services/adapter";
+}
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/BrokerAlreadyConnectedException.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/BrokerAlreadyConnectedException.java
new file mode 100644
index 0000000000..f23bf9d25e
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/BrokerAlreadyConnectedException.java
@@ -0,0 +1,53 @@
+/*
+*
+ * 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;
+
+/**
+ * Thrown when an attempt is made in order to connect QMan with an already connected broker.
+ *
+ * @author Andrea Gazzarini
+ */
+public class BrokerAlreadyConnectedException extends Exception {
+
+ private static final long serialVersionUID = -5082431738056504669L;
+
+ private BrokerConnectionData _connectionData;
+
+ /**
+ * Builds a new exception with the given data.
+ *
+ * @param connectionData the broker connection data.
+ */
+ public BrokerAlreadyConnectedException(BrokerConnectionData connectionData) {
+ this._connectionData = connectionData;
+ }
+
+ /**
+ * Returns the connection data of the connected broker.
+ *
+ * @return the connection data of the connected broker.
+ */
+ public BrokerConnectionData getBrokerConnectionData()
+ {
+ return _connectionData;
+ }
+}
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/BrokerConnectionData.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/BrokerConnectionData.java
new file mode 100644
index 0000000000..a64659b17c
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/BrokerConnectionData.java
@@ -0,0 +1,280 @@
+/*
+ *
+ * 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;
+
+/**
+ * Value object which is holding connection data for a specific broker.
+ *
+ * @author Andrea Gazzarini
+ */
+public class BrokerConnectionData
+{
+ private String _host;
+ private int _port;
+ private String _virtualHost;
+ private String _username;
+ private String _password;
+ private int _maxPoolCapacity;
+ private int _initialPoolCapacity;
+ private long _maxWaitTimeout;
+
+ /**
+ * Builds a connection data with the given parameters.
+ *
+ * @param host the hostname where the broker is running.
+ * @param port the port where the broker is running.
+ * @param username the username for connecting with the broker.
+ * @param password the password for connecting with the broker.
+ * @param virtualHost the virtual host.
+ * @param initialPoolCapacity the number of connections that must be immediately opened.
+ * @param maxPoolCapacity the maximum number of opened connection.
+ * @param maxWaitTimeout the maximum amount of time that a client will wait for obtaining a connection.
+ */
+ public BrokerConnectionData(
+ String host,
+ int port,
+ String virtualHost,
+ String username,
+ String password,
+ int initialPoolCapacity,
+ int maxPoolCapacity,
+ long waitTimeout) {
+
+ this._host = host;
+ this._port = port;
+ this._virtualHost = virtualHost;
+ this._username = username;
+ this._password = password;
+ _maxPoolCapacity = maxPoolCapacity;
+ _initialPoolCapacity = initialPoolCapacity;
+ _maxWaitTimeout = waitTimeout;
+ }
+
+ /**
+ * Builds a new empty broker connection data object.
+ */
+ BrokerConnectionData()
+ {
+ }
+
+ /**
+ * Sets the value of host property for this connection data.
+ *
+ * @param host the host name.
+ */
+ void setHost (String host)
+ {
+ this._host = host;
+ }
+
+ /**
+ * Sets the value of port property for this connection data.
+ *
+ * @param port the port.
+ */
+ void setPort (String port)
+ {
+ this._port = Integer.parseInt(port);
+ }
+
+ /**
+ * Sets the value of virtual host property for this connection data.
+ *
+ * @param virtualHost the virtual host.
+ */
+ void setVirtualHost (String virtualHost)
+ {
+ this._virtualHost = virtualHost;
+ }
+
+ /**
+ * Sets the value of username property for this connection data.
+ *
+ * @param username the username.
+ */
+ void setUsername(String username)
+ {
+ this._username = username;
+ }
+
+ /**
+ * Sets the value of password property for this connection data.
+ *
+ * @param password the password.
+ */
+ void setPassword(String password)
+ {
+ this._password = password;
+ }
+
+ /**
+ * Returns the value of the host property.
+ *
+ * @return the value of the host property.
+ */
+ public String getHost ()
+ {
+ return _host;
+ }
+
+ /**
+ * Returns the value of the port property.
+ *
+ * @return the value of the port property.
+ */
+ public int getPort ()
+ {
+ return _port;
+ }
+
+ /**
+ * Returns the value of the virtual host property.
+ *
+ * @return the value of the virtual host property.
+ */
+ public String getVirtualHost ()
+ {
+ return _virtualHost;
+ }
+
+ /**
+ * Returns the value of the username property.
+ *
+ * @return the value of the username property.
+ */
+ public String getUsername ()
+ {
+ return _username;
+ }
+
+ /**
+ * Returns the value of the password property.
+ *
+ * @return the value of the password property.
+ */
+ public String getPassword ()
+ {
+ return _password;
+ }
+
+ // sofia:5663@pippo/sung1
+ @Override
+ public String toString ()
+ {
+ return new StringBuilder()
+ .append(_host)
+ .append(':')
+ .append(_port)
+ .append('@')
+ .append(_virtualHost)
+ .toString();
+ }
+
+ /**
+ * Sets the max number of allowed connections that can be opened.
+ *
+ * @param value the max number of allowed connections that can be opened.
+ * @throws NumberFormatException if the given value is not a valid integer.
+ */
+ public void setMaxPoolCapacity (String value)
+ {
+ _maxPoolCapacity = Integer.parseInt(value);
+ }
+
+ /**
+ * Sets the max wait timeout for retrieving an available connections from the pool.
+ *
+ * @param value the max wait timeout for retrieving an available connections from the pool..
+ * @throws NumberFormatException if the given value is not a valid long.
+ */
+ public void setMaxWaitTimeout (String value)
+ {
+ this._maxWaitTimeout = Long.parseLong(value);
+ }
+
+ /**
+ * Returns the max number of allowed connections that can be opened.
+ *
+ * @return the max number of allowed connections that can be opened.
+ */
+ public int getMaxPoolCapacity ()
+ {
+ return _maxPoolCapacity;
+ }
+
+ /**
+ * Returns the max wait timeout for retrieving an available connections from the pool.
+ *
+ * @return the max wait timeout for retrieving an available connections from the pool.
+ */
+ public long getMaxWaitTimeout ()
+ {
+ return _maxWaitTimeout;
+ }
+
+ /**
+ * Sets the initial connection pool capacity.
+ *
+ * @param capacity the initial connection pool capacity.
+ */
+ public void setInitialPoolCapacity (String capacity)
+ {
+ _initialPoolCapacity = Integer.parseInt(capacity);
+ }
+
+ /**
+ * Returns the initial connection pool capacity.
+ *
+ * @return the initial connection pool capacity.
+ */
+ public int getInitialPoolCapacity ()
+ {
+ return _initialPoolCapacity;
+ }
+
+ @Override
+ public boolean equals(Object object)
+ {
+ if(object instanceof BrokerConnectionData)
+ {
+ try
+ {
+ BrokerConnectionData connectionData = (BrokerConnectionData) object;
+ return (_host.equals(connectionData._host) )
+ && (_port == connectionData._port)
+ && (_virtualHost.equals(connectionData._virtualHost));
+ }
+ catch (Exception exception)
+ {
+ return false;
+ }
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ @Override
+ public int hashCode() {
+ return _host.hashCode()+_port+_virtualHost.hashCode();
+ }
+}
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/BrokerConnectionDataParser.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/BrokerConnectionDataParser.java
new file mode 100644
index 0000000000..39981dc7cb
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/BrokerConnectionDataParser.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.management.configuration;
+
+import java.util.UUID;
+
+import org.apache.qpid.management.Messages;
+import org.apache.qpid.transport.util.Logger;
+
+/**
+ * Parser used for building broker connection data settings.
+ * The corresponding section on the configuration file is :
+ *
+ <broker>
+ <host>192.168.148.131</host>
+ <port>5672</port>
+ <virtual-host>test</virtual-host>
+ <user>guest</user>
+ <password>guest</password>
+ <max-pool-capacity>4</max-pool-capacity>
+ <initial-pool-capacity>4</initial-pool-capacity>
+ <max-wait-timeout>-1</max-wait-timeout>
+ </broker>
+ *
+ * @author Andrea Gazzarini
+ */
+class BrokerConnectionDataParser implements IParser
+{
+ private final static Logger LOGGER = Logger.get(Configuration.class);
+ private BrokerConnectionData _connectionData = new BrokerConnectionData();
+ private String _currentValue;
+
+ /**
+ * Callback : the given value is the text content of the current node.
+ */
+ public void setCurrrentAttributeValue (String value)
+ {
+ this._currentValue = value;
+ }
+
+ /**
+ * Callback: each time the end of an element is reached this method is called.
+ * It's here that the built mapping is injected into the configuration.
+ * <broker>
+ <host>192.168.61.130</host>
+ <port>5673</port>
+ <virtual-host>test</virtual-host>
+ <user>andrea</user>
+ <password>andrea</password>
+ </broker>
+ */
+ public void setCurrentAttributeName (String name)
+ {
+ switch (Tag.get(name))
+ {
+ case HOST:
+ {
+ _connectionData.setHost(_currentValue);
+ break;
+ }
+ case PORT :
+ {
+ _connectionData.setPort(_currentValue);
+ break;
+ }
+ case VIRTUAL_HOST:
+ {
+ _connectionData.setVirtualHost(_currentValue);
+ break;
+ }
+ case USER :
+ {
+ _connectionData.setUsername(_currentValue);
+ break;
+ }
+ case MAX_POOL_CAPACITY:
+ {
+ _connectionData.setMaxPoolCapacity (_currentValue);
+ break;
+ }
+ case INITIAL_POOL_CAPACITY:
+ {
+ _connectionData.setInitialPoolCapacity(_currentValue);
+ break;
+ }
+ case MAX_WAIT_TIMEOUT:
+ {
+ _connectionData.setMaxWaitTimeout(_currentValue);
+ break;
+ }
+ case PASSWORD:
+ {
+ _connectionData.setPassword(_currentValue);
+ break;
+ }
+ case BROKER:
+ {
+ try
+ {
+ Configuration.getInstance().addBrokerConnectionData(getUUId(),_connectionData);
+ } catch(Exception exception)
+ {
+ LOGGER.error(exception, Messages.QMAN_100007_UNABLE_TO_CONNECT_WITH_BROKER, _connectionData);
+ }
+ _connectionData = new BrokerConnectionData();
+ break;
+ }
+ }
+ }
+
+ /**
+ * Gets an uuid in order to associate current connection data with a broker.
+ * @return
+ */
+ UUID getUUId(){
+ return UUID.randomUUID();
+ }
+}
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/BrokerConnectionException.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/BrokerConnectionException.java
new file mode 100644
index 0000000000..9294cf740e
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/BrokerConnectionException.java
@@ -0,0 +1,42 @@
+/*
+*
+ * 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;
+
+/**
+ * Thrown when a connection to a broker cannot be estabilished.
+ *
+ * @author Andrea Gazzarini
+ */
+public class BrokerConnectionException extends Exception
+{
+ private static final long serialVersionUID = 8170112238862494025L;
+
+ /**
+ * Builds a new exception with the given cause.
+ *
+ * @param cause the exception cause.
+ */
+ BrokerConnectionException(Throwable cause)
+ {
+ super(cause);
+ }
+}
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
new file mode 100644
index 0000000000..ab90ec294b
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/Configuration.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.management.configuration;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+import java.util.UUID;
+import java.util.Map.Entry;
+
+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;
+import org.apache.qpid.transport.ReplyTo;
+import org.apache.qpid.transport.util.Logger;
+
+/**
+ * Qpid Management bridge configuration.
+ * Basically iy is a singleton that is holding all the configurtion data loaded at startup.
+ */
+public final class Configuration
+{
+ private final static Logger LOGGER = Logger.get(Configuration.class);
+ private static Configuration INSTANCE = new Configuration();
+
+ // Work Manager default settings
+ private int _poolSize = 5;
+ private int _maxPoolSize = 15;
+ private long _keepAliveTime = 5000;
+
+ Map<Integer, Type> _typeMappings = new HashMap<Integer,Type>();
+ Map<Integer,AccessMode> _accessModes = new HashMap<Integer, AccessMode>();
+ Map<Type,String> _validators = new HashMap<Type, String>();
+
+ Map<UUID,BrokerConnectionData> _brokerConnectionInfos = new HashMap<UUID, BrokerConnectionData>();
+
+ Map<Character, IMessageHandler> _managementQueueHandlers = new HashMap<Character, IMessageHandler>();
+ Map<Character, IMessageHandler> _methodReplyQueueHandlers = new HashMap<Character, IMessageHandler>();
+
+ private String _managementQueueName;
+ private String _methodReplyQueueName;
+
+ private Header _headerForCommandMessages;
+ private DeliveryProperties _deliveryProperties = new DeliveryProperties();
+ private MessageProperties _messageProperties = new MessageProperties();
+
+ // Private constructor.
+ private Configuration()
+ {
+ defineQueueNames();
+
+ createHeaderForCommandMessages();
+
+ addAccessModeMappings();
+
+ addTypeMappings();
+ }
+
+
+ /**
+ * Returns the singleton instance.
+ *
+ * @return the singleton instance.
+ */
+ public static Configuration getInstance ()
+ {
+ return INSTANCE;
+ }
+
+ /**
+ * Returns true if this configuration has at least
+ * one broker configured.
+ *
+ * @return true if this configuration has at least one
+ * broker configured.
+ */
+ public boolean hasOneOrMoreBrokersDefined()
+ {
+ return !_brokerConnectionInfos.isEmpty();
+ }
+
+ /**
+ * Returns the type associated to the given code.
+ *
+ * @param code the code used as search criteria.
+ * @return the type associated to the given code.
+ * @throws UnknownTypeCodeException when the given code is not associated to any type.
+ */
+ public Type getType(int code) throws UnknownTypeCodeException
+ {
+ Type result = _typeMappings.get(code);
+ if (result == null)
+ {
+ throw new UnknownTypeCodeException(code);
+ }
+ return result;
+ }
+
+ /**
+ * Returns the access mode associated to the given code.
+ *
+ * @param code the code used as search criteria.
+ * @return the access mode associated to the given code.
+ * @throws UnknownAccessCodeException when the given code is not associated to any access mode.
+ */
+ public AccessMode getAccessMode(int code) throws UnknownAccessCodeException
+ {
+ AccessMode result = _accessModes.get(code);
+ if (result == null)
+ {
+ throw new UnknownAccessCodeException(code);
+ }
+ return result;
+ }
+
+ /**
+ * Returns the validator class name associated to the given type.
+ *
+ * @param type the type.
+ * @return the validator class name associated to the given type.
+ */
+ public String getValidatorClassName (Type type)
+ {
+ return _validators.get(type);
+ }
+
+ /**
+ * Gets from this configuration the list of known broker (I mean, only their connection data).
+ *
+ * @return the list of known broker
+ */
+ public Set<Entry<UUID, BrokerConnectionData>> getConnectionInfos(){
+ return _brokerConnectionInfos.entrySet();
+ }
+
+ /**
+ * Gets from this configuration the connection data of the broker associated with the given id.
+ *
+ * @param brokerId the broker identifier.
+ * @return the connection data of the broker associated with the given id.
+ * @throws UnknownBrokerException when the given id is not associated with any broker.
+ */
+ public BrokerConnectionData getBrokerConnectionData (UUID brokerId) throws UnknownBrokerException
+ {
+ BrokerConnectionData connectionData = _brokerConnectionInfos.get(brokerId);
+ if (connectionData == null)
+ {
+ throw new UnknownBrokerException(brokerId);
+ }
+ return _brokerConnectionInfos.get(brokerId);
+ }
+
+ /**
+ * Returns the name of the management queue.
+ *
+ * @return the name of the management queue.
+ */
+ public String getManagementQueueName() {
+ return _managementQueueName;
+ }
+
+ /**
+ * Returns the name of the method-reply queue.
+ *
+ * @return the name of the method-reply queue.
+ */
+ public String getMethodReplyQueueName() {
+ return _methodReplyQueueName;
+ }
+
+ /**
+ * Returns a map containing all the configured management message handlers.
+ * A management message handler it is a basically a processor for a management queue incoming message associated
+ * with a specific opcode.
+ *
+ * @return a map containing all the configured management message handlers.
+ */
+ public Map<Character, IMessageHandler> getManagementQueueHandlers()
+ {
+ return _managementQueueHandlers;
+ }
+
+ /**
+ * Returns a map containing all the configured method-reply message handlers.
+ * A management message handler it is a basically a processor for a method-reply queue incoming message associated
+ * with a specific opcode.
+ *
+ * @return a map containing all the configured method-reply message handlers.
+ */
+ public Map<Character, IMessageHandler> getMethodReplyQueueHandlers()
+ {
+ return _methodReplyQueueHandlers;
+ }
+
+ /**
+ * Returns the message header used for sending command message on management queue.
+ *
+ * @return the message header used for sending command message on management queue.
+ */
+ public Header getCommandMessageHeader ()
+ {
+ return _headerForCommandMessages;
+ }
+
+ /**
+ * Returns the command message properties.
+ *
+ * @return the command message properties.
+ */
+ public MessageProperties getCommandMessageProperties ()
+ {
+ return _messageProperties;
+ }
+
+ /**
+ * Returns the command message delivery properties.
+ *
+ * @return the command message delivery properties.
+ */
+ public DeliveryProperties getCommandDeliveryProperties ()
+ {
+ return _deliveryProperties;
+ }
+
+ /**
+ * Adds a new type mapping to this configuration.
+ *
+ * @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(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);
+ }
+
+
+ /**
+ * 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 code the code that will be associated with the access mode,
+ * @param accessMode the accessMode.
+ */
+ void addAccessModeMapping(int code, AccessMode accessMode){
+ _accessModes.put(code, accessMode);
+
+ LOGGER.info(Messages.QMAN_000006_ACCESS_MODE_MAPPING_CONFIGURED, code,accessMode);
+ }
+
+ /**
+ * Adds a new management message handler to this configuration.
+ * The incoming mapping object will contains an opcode and the class (as a string) of the message handler that will be used
+ * for processing incoming messages with that opcode.
+ *
+ * @param mapping the message handler mapping.
+ */
+ void addManagementMessageHandlerMapping (MessageHandlerMapping mapping)
+ {
+ Character opcode = mapping.getOpcode();
+ IMessageHandler handler = mapping.getMessageHandler();
+ _managementQueueHandlers.put(opcode, handler);
+
+ LOGGER.info(Messages.QMAN_000007_MANAGEMENT_HANDLER_MAPPING_CONFIGURED, opcode,handler.getClass().getName());
+ }
+
+ /**
+ * Adds a new method-reply message handler to this configuration.
+ * The incoming mapping object will contains an opcode and the class (as a string) of the message handler that will be used
+ * for processing incoming messages with that opcode.
+ *
+ * @param mapping the message handler mapping.
+ */
+ void addMethodReplyMessageHandlerMapping (MessageHandlerMapping mapping)
+ {
+ Character opcode = mapping.getOpcode();
+ IMessageHandler handler = mapping.getMessageHandler();
+ _methodReplyQueueHandlers.put(opcode, handler);
+
+ LOGGER.info(Messages.QMAN_000008_METHOD_REPLY_HANDLER_MAPPING_CONFIGURED, opcode,handler.getClass().getName());
+ }
+
+ /**
+ * Adds to this configuration a new broker connection data.
+ *
+ * @param brokerId the broker identifier.
+ * @param connectionData the connection data.
+ * @throws BrokerAlreadyConnectedException when the broker is already connected.
+ * @throws BrokerConnectionException when a connection cannot be estabilished.
+ */
+ void addBrokerConnectionData (UUID brokerId, BrokerConnectionData connectionData) throws BrokerAlreadyConnectedException, BrokerConnectionException
+ {
+ if (_brokerConnectionInfos.containsValue(connectionData))
+ {
+ throw new BrokerAlreadyConnectedException(connectionData);
+ }
+
+ try
+ {
+ QpidDatasource.getInstance().addConnectionPool(brokerId, connectionData);
+ _brokerConnectionInfos.put(brokerId,connectionData);
+
+ LOGGER.info(Messages.QMAN_000009_BROKER_DATA_CONFIGURED,brokerId,connectionData);
+ } catch(Exception exception)
+ {
+ throw new BrokerConnectionException(exception);
+ }
+
+ }
+
+ /**
+ * Header for command messages is created once because it only contains static values.
+ */
+ private void createHeaderForCommandMessages ()
+ {
+ ReplyTo replyTo=new ReplyTo();
+ replyTo.setRoutingKey(_methodReplyQueueName);
+ _messageProperties.setReplyTo(replyTo);
+ _deliveryProperties.setRoutingKey(Names.AGENT_ROUTING_KEY);
+ _headerForCommandMessages = new Header(_deliveryProperties, _messageProperties);
+ }
+
+ /**
+ * Creates the name of the queues used by this service.
+ * This is done because if a broker should be managed by one or more management client, then each of them
+ * must have its own channels to communicate with.
+ */
+ private void defineQueueNames()
+ {
+ UUID uuid = UUID.randomUUID();
+ _managementQueueName = Names.MANAGEMENT_QUEUE_PREFIX+uuid;
+ _methodReplyQueueName = Names.METHOD_REPLY_QUEUE_PREFIX+uuid;
+
+ LOGGER.debug(Messages.QMAN_200004_MANAGEMENT_QUEUE_NAME,_managementQueueName);
+ LOGGER.debug(Messages.QMAN_200005_METHOD_REPLY_QUEUE_NAME,_methodReplyQueueName);
+ }
+
+ /**
+ * Returns the worker manager thread pool size.
+ *
+ * @return the worker manager thread pool size.
+ */
+ public int getWorkerManagerPoolSize()
+ {
+ return _poolSize;
+ }
+
+ /**
+ * Sets the size of the worker manager thread pool.
+ *
+ * @param poolSize the size of the worker manager thread pool.
+ */
+ void setWorkerManagerPoolSize(int poolSize)
+ {
+ this._poolSize = poolSize;
+ }
+
+ /**
+ * Returns the maximum size of the worker manager
+ * thread pool size.
+ *
+ * @return the max size of the worker manager thread pool.
+ */
+ public int getWorkerManagerMaxPoolSize()
+ {
+ return _maxPoolSize;
+ }
+
+ /**
+ * Sets the maximum size of the worker manager
+ * thread pool size.
+ *
+ * @param maxPoolSize the max size of the worker manager thread pool.
+ */
+ void setWorkerManagerMaxPoolSize(int maxPoolSize)
+ {
+ this._maxPoolSize = maxPoolSize;
+ }
+
+ /**
+ * Returns the max amount of time that an excess thread
+ * can be idle before purging from the pool.
+ *
+ * @return the max keep alive time.
+ */
+ public long getWorkerManagerKeepAliveTime()
+ {
+ return _keepAliveTime;
+ }
+
+ /**
+ * Sets the max amount of time that an excess thread
+ * can be idle before purging from the pool.
+ *
+ * @param keepAliveTime the max keep alive time.
+ */
+ void setWorkerManagerKeepAliveTime(long keepAliveTime)
+ {
+ 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/ConfigurationException.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/ConfigurationException.java
new file mode 100644
index 0000000000..6eed515e11
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/ConfigurationException.java
@@ -0,0 +1,51 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.management.configuration;
+
+/**
+ * Thrown when a problem is encountered during building the configuration.
+ *
+ * @author Andrea Gazzarini
+ */
+public class ConfigurationException extends Exception
+{
+ private static final long serialVersionUID = 8238481177714286259L;
+
+ public ConfigurationException(String msg)
+ {
+ super(msg);
+ }
+
+ /**
+ * Builds a new ConfigurationException with the given cause.
+ *
+ * @param exception the exception cause.
+ */
+ public ConfigurationException(Exception exception)
+ {
+ super(exception);
+ }
+
+ public ConfigurationException(String msg,Exception exception)
+ {
+ super(msg,exception);
+ }
+} \ 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
new file mode 100644
index 0000000000..fe44c6aff7
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/Configurator.java
@@ -0,0 +1,240 @@
+/*
+ *
+ * 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 java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.InputStreamReader;
+import java.util.UUID;
+
+import javax.xml.parsers.SAXParser;
+import javax.xml.parsers.SAXParserFactory;
+
+import org.apache.qpid.management.Messages;
+import org.apache.qpid.management.Names;
+import org.apache.qpid.management.Protocol;
+import org.apache.qpid.management.domain.handler.impl.ConfigurationMessageHandler;
+import org.apache.qpid.management.domain.handler.impl.EventContentMessageHandler;
+import org.apache.qpid.management.domain.handler.impl.HeartBeatIndicationMessageHandler;
+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.transport.util.Logger;
+import org.xml.sax.Attributes;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+import org.xml.sax.helpers.DefaultHandler;
+
+/**
+ * Director used for coordinating the build process of configuration.
+ * This is the only component which has a read-write permission on Configuration object.
+ */
+public class Configurator extends DefaultHandler
+{
+ private final static Logger LOGGER = Logger.get(Configurator.class);
+
+ /**
+ * Default (empty) parser used when there's no need to process data (non relevant elements).
+ */
+ final static IParser DEFAULT_PARSER = new IParser() {
+
+ public void setCurrrentAttributeValue (String value)
+ {
+ }
+
+ public void setCurrentAttributeName (String name)
+ {
+ }
+ };
+
+ IParser _brokerConfigurationParser = new BrokerConnectionDataParser();
+ IParser _workerManagerConfigurationParser = new WorkerManagerConfigurationParser();
+ IParser _currentParser = DEFAULT_PARSER;
+
+ /**
+ * Delegates the processing to the current parser.
+ */
+ @Override
+ public void characters (char[] ch, int start, int length) throws SAXException
+ {
+ String value = new String(ch,start,length).trim();
+ if (value.length() != 0) {
+ _currentParser.setCurrrentAttributeValue(value);
+ }
+ }
+
+ /**
+ * Here is defined what parser needs to be used for processing the current data.
+ */
+ @Override
+ public void startElement (String uri, String localName, String name, Attributes attributes) throws SAXException
+ {
+ switch(Tag.get(name))
+ {
+ case BROKERS :
+ {
+ _currentParser = _brokerConfigurationParser;
+ break;
+ }
+ case WORK_MANAGER :
+ {
+ _currentParser = _workerManagerConfigurationParser;
+ break;
+ }
+ }
+ }
+
+ @Override
+ public void endElement (String uri, String localName, String name) throws SAXException
+ {
+ _currentParser.setCurrentAttributeName(name);
+ }
+
+ /**
+ * Builds whole configuration.
+ *
+ * @throws ConfigurationException when the build fails.
+ */
+ public void configure() throws ConfigurationException
+ {
+ BufferedReader reader = null;
+ try
+ {
+ String initialConfigFileName = System.getProperty(Names.QMAN_CONFIG_OPTION_NAME);
+ if (initialConfigFileName != null && initialConfigFileName.trim().length() != 0)
+ {
+ File initialConfigurationFile = new File(initialConfigFileName);
+ if (initialConfigurationFile.canRead())
+ {
+ SAXParser parser = SAXParserFactory.newInstance().newSAXParser();
+ reader = new BufferedReader(
+ new InputStreamReader(
+ new FileInputStream(initialConfigFileName)));
+ InputSource source = new InputSource(reader);
+ parser.parse(source, this);
+ } else {
+ LOGGER.warn(
+ Messages.QMAN_300004_INVALID_CONFIGURATION_FILE,
+ initialConfigFileName);
+ }
+ }
+
+ addMandatoryManagementMessageHandlers();
+ addMandatoryMethodReplyMessageHandlers();
+ } catch (Exception exception)
+ {
+ throw new ConfigurationException(exception);
+ } finally
+ {
+ try
+ {
+ reader.close();
+ } catch (Exception ignore)
+ {
+ }
+ }
+ }
+
+ /**
+ * Creates and return a value object (BrokerConnectionData) with the given parameters.
+ * Note that that object will be stored on configuration and it could be used to set a connection with the broker.
+ * This happens when the "initialPoolCapacity" is greater than 0 : in this case the caller is indicatinf that it wants to open
+ * one or more connections immediately at startup and therefore Q-Man will try to do that.
+ *
+ * @param host the hostname where the broker is running.
+ * @param port the port where the broker is running.
+ * @param username the username for connecting with the broker.
+ * @param password the password for connecting with the broker.
+ * @param virtualHost the virtual host.
+ * @param initialPoolCapacity the number of the connection that must be immediately opened.
+ * @param maxPoolCapacity the maximum number of opened connection.
+ * @param maxWaitTimeout the maximum amount of time that a client will wait for obtaining a connection.
+ * @return the value object containing the data above.
+ * @throws BrokerAlreadyConnectedException when the broker is already connected.
+ * @throws BrokerConnectionException when a connection cannot be estabilished.
+ */
+ public BrokerConnectionData createAndReturnBrokerConnectionData(
+ UUID brokerId,
+ String host,
+ int port,
+ String username,
+ String password,
+ String virtualHost,
+ int initialPoolCapacity,
+ int maxPoolCapacity,
+ long maxWaitTimeout) throws BrokerAlreadyConnectedException, BrokerConnectionException
+ {
+ BrokerConnectionData data = new BrokerConnectionData(
+ host,
+ port,
+ virtualHost,
+ username,
+ password,
+ initialPoolCapacity,
+ maxPoolCapacity,
+ maxWaitTimeout);
+ Configuration.getInstance().addBrokerConnectionData(brokerId, data);
+ return data;
+ }
+
+ /**
+ * Configures the mandatory management message handlers.
+ */
+ void addMandatoryMethodReplyMessageHandlers ()
+ {
+ Configuration.getInstance().addMethodReplyMessageHandlerMapping(
+ new MessageHandlerMapping(
+ Protocol.OPERATION_INVOCATION_RESPONSE_OPCODE,
+ new MethodResponseMessageHandler()));
+
+ Configuration.getInstance().addMethodReplyMessageHandlerMapping(
+ new MessageHandlerMapping(
+ Protocol.SCHEMA_RESPONSE_OPCODE,
+ new SchemaResponseMessageHandler()));
+ }
+
+ /**
+ * Configures the mandatory management message handlers.
+ */
+ void addMandatoryManagementMessageHandlers ()
+ {
+ Configuration.getInstance().addManagementMessageHandlerMapping(
+ new MessageHandlerMapping(
+ Protocol.INSTRUMENTATION_CONTENT_RESPONSE_OPCODE,
+ new InstrumentationMessageHandler()));
+
+ Configuration.getInstance().addManagementMessageHandlerMapping(
+ new MessageHandlerMapping(
+ Protocol.CONFIGURATION_CONTENT_RESPONSE_OPCDE,
+ new ConfigurationMessageHandler()));
+
+ Configuration.getInstance().addManagementMessageHandlerMapping(
+ new MessageHandlerMapping(
+ Protocol.EVENT_CONTENT_RESPONSE_OPCDE,
+ new EventContentMessageHandler()));
+
+ Configuration.getInstance().addManagementMessageHandlerMapping(
+ new MessageHandlerMapping(
+ Protocol.HEARTBEAT_INDICATION_RESPONSE_OPCODE,
+ new HeartBeatIndicationMessageHandler()));
+ }
+}
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/IParser.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/IParser.java
new file mode 100644
index 0000000000..a221686765
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/IParser.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.configuration;
+
+/**
+ * Interface definition for configuration parser
+ * Concrete implementors are responsible for parsing a specific XML part of configuration data.
+ *
+ * @author Andrea Gazzarini
+ */
+interface IParser
+{
+ /**
+ * Main director callback : Sets the name of the current attribute.
+ *
+ * @param name the name of the current attribute.
+ */
+ void setCurrentAttributeName(String name);
+
+ /**
+ * Main director callback : sets the value of the current attribute.
+ *
+ * @param value the value of the current attribute.
+ */
+ void setCurrrentAttributeValue(String value);
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/MessageHandlerMapping.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/MessageHandlerMapping.java
new file mode 100644
index 0000000000..b02fb789cc
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/MessageHandlerMapping.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.management.configuration;
+
+import org.apache.qpid.management.domain.handler.base.IMessageHandler;
+
+/**
+ * Message Handler mapping used for associating an opcode with a message handler.
+ */
+class MessageHandlerMapping
+{
+ private final Character _opcode;
+ private final IMessageHandler _handler;
+
+ /**
+ * Builds a new mapping with the given opcode and handler class.
+ *
+ * @param opcode the opcode.
+ * @param handlerClass the handler class.
+ */
+ MessageHandlerMapping(Character opcode, IMessageHandler handler)
+ {
+ this._opcode = opcode;
+ this._handler = handler;
+ }
+
+ /**
+ * Returns the opcode of this mapping.
+ *
+ * @return the code of this mapping.
+ */
+ Character getOpcode ()
+ {
+ return _opcode;
+ }
+
+ /**
+ * Returns the message handler for this mapping.
+ *
+ * @return the message handler for this mapping.
+ */
+ IMessageHandler getMessageHandler()
+ {
+ return _handler;
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/QpidDatasource.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/QpidDatasource.java
new file mode 100644
index 0000000000..569a65a782
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/QpidDatasource.java
@@ -0,0 +1,249 @@
+/*
+ *
+ * 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 java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
+
+import org.apache.commons.pool.BasePoolableObjectFactory;
+import org.apache.commons.pool.ObjectPool;
+import org.apache.commons.pool.impl.GenericObjectPool;
+import org.apache.commons.pool.impl.GenericObjectPoolFactory;
+import org.apache.qpid.management.Messages;
+import org.apache.qpid.transport.Connection;
+import org.apache.qpid.transport.ConnectionException;
+import org.apache.qpid.transport.util.Logger;
+
+/**
+ * Qpid datasource.
+ * Basically it is a connection pool manager used for optimizing broker connections usage.
+ *
+ * @author Andrea Gazzarini
+ */
+public final class QpidDatasource
+{
+ private final static Logger LOGGER = Logger.get(QpidDatasource.class);
+
+ /**
+ * A connection decorator used for adding pool interaction behaviour to an existing connection.
+ *
+ * @author Andrea Gazzarini
+ */
+ class PooledConnection extends Connection
+ {
+ private final UUID _brokerId;
+ private boolean _valid;
+
+ /**
+ * Builds a new decorator with the given connection.
+ *
+ * @param brokerId the broker identifier.
+ */
+ private PooledConnection(UUID brokerId)
+ {
+ this._brokerId = brokerId;
+ _valid = true;
+ }
+
+ /**
+ * Returns true if the underlying connection is still valid and can be used.
+ *
+ * @return true if the underlying connection is still valid and can be used.
+ */
+ boolean isValid()
+ {
+ return _valid;
+ }
+
+ void reallyClose()
+ {
+ super.close();
+ }
+
+ /**
+ * Returns the connection to the pool. That is, marks this connections as available.
+ * After that, this connection will be available for further operations.
+ */
+ public void close()
+ {
+ try
+ {
+ pools.get(_brokerId).returnObject(this);
+
+ LOGGER.debug(Messages.QMAN_200006_QPID_CONNECTION_RELEASED, this);
+ }
+ catch (Exception e)
+ {
+ throw new ConnectionException(e);
+ }
+ }
+
+ public void exception(Throwable t)
+ {
+ //super.exception(t);
+ _valid = false;
+ }
+ }
+
+ /**
+ * This is the connection factory, that is, the factory used to manage the lifecycle (create, validate & destroy) of
+ * the broker connection(s).
+ *
+ * @author Andrea Gazzarini
+ */
+ class QpidConnectionFactory extends BasePoolableObjectFactory
+ {
+ private final BrokerConnectionData _connectionData;
+ private final UUID _brokerId;
+
+ /**
+ * Builds a new connection factory with the given parameters.
+ *
+ * @param brokerId the broker identifier.
+ * @param connectionData the connecton data.
+ */
+ private QpidConnectionFactory(UUID brokerId, BrokerConnectionData connectionData)
+ {
+ this._connectionData = connectionData;
+ this._brokerId = brokerId;
+ }
+
+ /**
+ * Creates a new underlying connection.
+ */
+ @Override
+ public Connection makeObject () throws Exception
+ {
+ PooledConnection connection = new PooledConnection(_brokerId);
+ connection.connect(
+ _connectionData.getHost(),
+ _connectionData.getPort(),
+ _connectionData.getVirtualHost(),
+ _connectionData.getUsername(),
+ _connectionData.getPassword(),
+ false);
+ return connection;
+ }
+
+ /**
+ * Validates the underlying connection.
+ */
+ @Override
+ public boolean validateObject (Object obj)
+ {
+ PooledConnection connection = (PooledConnection) obj;
+ boolean isValid = connection.isValid();
+
+ LOGGER.debug(Messages.QMAN_200007_TEST_CONNECTION_ON_RESERVE,isValid);
+
+ return isValid;
+ }
+
+ /**
+ * Closes the underlying connection.
+ */
+ @Override
+ public void destroyObject (Object obj) throws Exception
+ {
+ try
+ {
+ PooledConnection connection = (PooledConnection) obj;
+ connection.reallyClose();
+
+ LOGGER.debug(Messages.QMAN_200008_CONNECTION_DESTROYED);
+ } catch (Exception exception)
+ {
+ LOGGER.debug(exception, Messages.QMAN_200009_CONNECTION_DESTROY_FAILURE);
+ }
+ }
+ }
+
+ // Singleton instance.
+ private static QpidDatasource instance = new QpidDatasource();
+
+ // Each entry contains a connection pool for a specific broker.
+ private Map<UUID, ObjectPool> pools = new HashMap<UUID, ObjectPool>();
+
+ // Private constructor.
+ private QpidDatasource()
+ {
+ }
+
+ /**
+ * Gets an available connection from the pool of the given broker.
+ *
+ * @param brokerId the broker identifier.
+ * @return a valid connection to the broker associated with the given identifier.
+ */
+ public Connection getConnection(UUID brokerId) throws Exception
+ {
+ return (Connection) pools.get(brokerId).borrowObject();
+ }
+
+ /**
+ * Entry point method for retrieving the singleton instance of this datasource.
+ *
+ * @return the qpid datasource singleton instance.
+ */
+ public static QpidDatasource getInstance()
+ {
+ return instance;
+ }
+
+ /**
+ * Adds a connection pool to this datasource.
+ *
+ * @param brokerId the broker identifier that will be associated with the new connection pool.
+ * @param connectionData the broker connection data.
+ * @throws Exception when the pool cannot be created.
+ */
+ void addConnectionPool(UUID brokerId,BrokerConnectionData connectionData) throws Exception
+ {
+ GenericObjectPoolFactory factory = new GenericObjectPoolFactory(
+ new QpidConnectionFactory(brokerId,connectionData),
+ connectionData.getMaxPoolCapacity(),
+ GenericObjectPool.WHEN_EXHAUSTED_BLOCK,
+ connectionData.getMaxWaitTimeout(),-1,
+ true,
+ false);
+
+ ObjectPool pool = factory.createPool();
+
+ // Open connections at startup according to initial capacity param value.
+ int howManyConnectionAtStartup = connectionData.getInitialPoolCapacity();
+ Object [] openStartupList = new Object[howManyConnectionAtStartup];
+
+ // Open...
+ for (int index = 0; index < howManyConnectionAtStartup; index++)
+ {
+ openStartupList[index] = pool.borrowObject();
+ }
+
+ // ...and immediately return them to pool. In this way the pooled connection has been opened.
+ for (int index = 0; index < howManyConnectionAtStartup; index++)
+ {
+ pool.returnObject(openStartupList[index]);
+ }
+
+ pools.put(brokerId,pool);
+ }
+}
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/Tag.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/Tag.java
new file mode 100644
index 0000000000..c2b6e1e27d
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/Tag.java
@@ -0,0 +1,54 @@
+/*
+*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+package org.apache.qpid.management.configuration;
+
+/**
+ * Configuration Tag catalogue.
+ *
+ * @author Andrea Gazzarini
+ */
+public enum Tag {
+ CONFIGURATION { @Override public String toString() { return "configuration"; }},
+ BROKER { @Override public String toString() { return "broker"; }},
+ HOST { @Override public String toString() { return "host"; }},
+ PORT { @Override public String toString() { return "port"; }},
+ MAX_POOL_CAPACITY { @Override public String toString() { return "max-pool-capacity"; }},
+ MAX_WAIT_TIMEOUT { @Override public String toString() { return "max-wait-timeout"; }},
+ INITIAL_POOL_CAPACITY { @Override public String toString() { return "initial-pool-capacity"; }},
+ VIRTUAL_HOST { @Override public String toString() { return "virtual-host"; }},
+ USER { @Override public String toString() { return "user"; }},
+ PASSWORD { @Override public String toString() { return "password"; }},
+ BROKERS { @Override public String toString() { return "brokers"; }},
+ WORK_MANAGER { @Override public String toString() { return "work-manager"; }},
+ POOL_CAPACITY { @Override public String toString() { return "pool-capacity"; }},
+ KEEP_ALIVE_TIME { @Override public String toString() { return "keep-alive-time"; }};
+
+ /**
+ * Returns the enum entry associated to the given tag name.
+ *
+ * @param name the name of tag.
+ * @return the enum entry associated to the given tag name.
+ */
+ public static Tag get(String name) {
+ return valueOf(name.replaceAll("-", "_").toUpperCase());
+ }
+}
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/UnknownAccessCodeException.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/UnknownAccessCodeException.java
new file mode 100644
index 0000000000..b7f1c0a7ec
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/UnknownAccessCodeException.java
@@ -0,0 +1,53 @@
+/*
+ *
+ * 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;
+
+/**
+ * Thrown when no access mode is found in configuration associated to the given code.
+ *
+ * @author Andrea Gazzarini
+ */
+public class UnknownAccessCodeException extends Exception
+{
+ private static final long serialVersionUID = 2350963503092509119L;
+ private final int _code;
+
+ /**
+ * Builds a new UnknownAccessCodeException with the given code.
+ *
+ * @param code the access code.
+ */
+ UnknownAccessCodeException(int code)
+ {
+ super(String.valueOf(code));
+ this._code = code;
+ }
+
+ /**
+ * Returns the unknown code.
+ *
+ * @return the unknown code.
+ */
+ public int getCode ()
+ {
+ return _code;
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/UnknownBrokerException.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/UnknownBrokerException.java
new file mode 100644
index 0000000000..5b08e09c24
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/UnknownBrokerException.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.management.configuration;
+
+import java.util.UUID;
+
+/**
+ * Thrown when someone requests connection data for an unknown broker.
+ *
+ * @author Andrea Gazzarini
+ */
+public class UnknownBrokerException extends Exception
+{
+ private static final long serialVersionUID = 4965395428832158924L;
+
+ /**
+ * Builds a new UnknownBrokerException with the given broker id.
+ *
+ * @param brokerId the broker identifier.
+ */
+ UnknownBrokerException(UUID brokerId)
+ {
+ super(String.valueOf(brokerId));
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/UnknownTypeCodeException.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/UnknownTypeCodeException.java
new file mode 100644
index 0000000000..57005d21e5
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/UnknownTypeCodeException.java
@@ -0,0 +1,53 @@
+/*
+ *
+ * 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;
+
+/**
+ * Thrown when no type is found in configuration associated to the given code.
+ *
+ * @author Andrea Gazzarini
+ */
+public class UnknownTypeCodeException extends Exception
+{
+ private static final long serialVersionUID = 5440934037645111591L;
+ private int _code;
+
+ /**
+ * Builds a new UnknownTypeCodeException with the given code.
+ *
+ * @param code the access code.
+ */
+ UnknownTypeCodeException(int code)
+ {
+ super(String.valueOf(code));
+ this._code = code;
+ }
+
+ /**
+ * Returns the unknown code.
+ *
+ * @return the unknown code.
+ */
+ public int getCode ()
+ {
+ return _code;
+ }
+}
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/WorkerManagerConfigurationParser.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/WorkerManagerConfigurationParser.java
new file mode 100644
index 0000000000..4e68b54b12
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/WorkerManagerConfigurationParser.java
@@ -0,0 +1,109 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.management.configuration;
+
+import java.util.UUID;
+
+import org.apache.qpid.management.Messages;
+import org.apache.qpid.transport.util.Logger;
+
+/**
+ * Parser used for building worker manager settings.
+ * The corresponding section of the configuration file is :
+ *
+ <work-manager>
+ <pool-capacity>5</pool-capacity>
+ <max-pool-capacity>15</max-pool-capacity>
+ <keep-alive-time>5000</keep-alive-time>
+ </work-manager>
+
+ *
+ * @author Andrea Gazzarini
+ */
+class WorkerManagerConfigurationParser implements IParser
+{
+ private final static Logger LOGGER = Logger.get(Configuration.class);
+ private String _currentValue;
+
+ private String _poolSizeAsString;
+ private String _maxPoolSizeAsString;
+ private String _keepAliveTimeAsString;
+
+ /**
+ * Callback : the given value is the text content of the current node.
+ */
+ public void setCurrrentAttributeValue (String value)
+ {
+ this._currentValue = value;
+ }
+
+ /**
+ * Callback: each time the end of an element is reached
+ * this method is called.
+ */
+ public void setCurrentAttributeName (String name)
+ {
+ switch (Tag.get(name))
+ {
+ case POOL_CAPACITY:
+ {
+ _poolSizeAsString = _currentValue.trim();
+ break;
+ }
+ case MAX_POOL_CAPACITY :
+ {
+ _maxPoolSizeAsString = _currentValue;
+ break;
+ }
+ case KEEP_ALIVE_TIME:
+ {
+ _keepAliveTimeAsString = _currentValue;
+ break;
+ }
+ case WORK_MANAGER:
+ {
+ Configuration configuration = Configuration.getInstance();
+ try
+ {
+ configuration.setWorkerManagerPoolSize(Integer.parseInt(_poolSizeAsString));
+ configuration.setWorkerManagerMaxPoolSize(Integer.parseInt(_maxPoolSizeAsString));
+ configuration.setWorkerManagerKeepAliveTime(Long.parseLong(_keepAliveTimeAsString));
+ } catch(Exception exception)
+ {
+ LOGGER.error(Messages.QMAN_100039_UNABLE_TO_CONFIGURE_PROPERLY_WORKER_MANAGER);
+ } finally {
+ LOGGER.info(Messages.QMAN_000035_WORK_MANAGER_POOL_SIZE,configuration.getWorkerManagerPoolSize());
+ LOGGER.info(Messages.QMAN_000036_WORK_MANAGER_MAX_POOL_SIZE,configuration.getWorkerManagerMaxPoolSize());
+ LOGGER.info(Messages.QMAN_000037_WORK_MANAGER_KEEP_ALIVE_TIME,configuration.getWorkerManagerKeepAliveTime());
+ }
+ break;
+ }
+ }
+ }
+
+ /**
+ * Gets an uuid in order to associate current connection data with a broker.
+ * @return
+ */
+ UUID getUUId(){
+ return UUID.randomUUID();
+ }
+}
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/base/BaseMessageHandler.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/base/BaseMessageHandler.java
new file mode 100644
index 0000000000..798e835ff4
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/base/BaseMessageHandler.java
@@ -0,0 +1,54 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.management.domain.handler.base;
+
+import org.apache.qpid.management.domain.model.DomainModel;
+import org.apache.qpid.transport.util.Logger;
+
+/**
+ * Base class for all message handlers.
+ * A message handler is an handler for a specific type of message.
+ * Message type is defined by the opcode.
+ *
+ * @author Andrea Gazzarini
+ */
+public abstract class BaseMessageHandler implements IMessageHandler
+{
+ /**
+ * Logger used for logging.
+ */
+ protected final Logger _logger = Logger.get(getClass());
+
+ /**
+ * Managed broker domain model.
+ */
+ protected DomainModel _domainModel;
+
+ /**
+ * Sets the broker domain model.
+ *
+ * @param domainModel the broker domain model.
+ */
+ public void setDomainModel(DomainModel domainModel)
+ {
+ this._domainModel = domainModel;
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/base/ContentIndicationMessageHandler.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/base/ContentIndicationMessageHandler.java
new file mode 100644
index 0000000000..be000e9a05
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/base/ContentIndicationMessageHandler.java
@@ -0,0 +1,114 @@
+/*
+ *
+ * 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.domain.handler.base;
+
+import org.apache.qpid.management.domain.model.type.Binary;
+import org.apache.qpid.transport.codec.Decoder;
+
+/**
+ * Base class for content indication message handlers.
+ *
+ * @author Andrea Gazzarini
+ */
+public abstract class ContentIndicationMessageHandler extends BaseMessageHandler
+{
+ /**
+ * Processes the income message.
+ *
+ * @param decoder the decoder used to parse the message.
+ * @param sequenceNumber the sequence number of the message.
+ */
+ public final void process (Decoder decoder, int sequenceNumber)
+ {
+ String packageName = decoder.readStr8();
+ String className = decoder.readStr8();
+ Binary classHash = new Binary(decoder.readBin128());
+
+ long timeStampOfCurrentSample = decoder.readDatetime();
+ long timeObjectWasCreated = decoder.readDatetime();
+ long timeObjectWasDeleted = decoder.readDatetime();
+
+ Binary objectId = new Binary(decoder.readBin128());
+
+ if (objectHasBeenRemoved(timeObjectWasDeleted, timeStampOfCurrentSample))
+ {
+ removeObjectInstance(packageName,className,classHash,objectId);
+ } else
+ {
+ updateDomainModel(
+ packageName,
+ className,
+ classHash,
+ objectId,
+ timeStampOfCurrentSample,
+ timeObjectWasCreated,
+ timeObjectWasDeleted,
+ decoder.readReaminingBytes());
+ }
+ }
+
+ /**
+ * Removes an object instance from the domain model.
+ *
+ * @param packageName the package name.
+ * @param className the class name.
+ * @param classHash the class hash.
+ * @param objectId the object identifier.
+ */
+ void removeObjectInstance(String packageName, String className,Binary classHash, Binary objectId)
+ {
+ _domainModel.removeObjectInstance(packageName,className,classHash,objectId);
+ }
+
+ /**
+ * Checks if the timestamps contained in the message indicate that the object has been removed.
+ *
+ * @param deletionTimestamp time object was deleted.
+ * @param now timestamp of the current message.
+ * @return true if the object has been removed, false otherwise.
+ */
+ boolean objectHasBeenRemoved(long deletionTimestamp, long now) {
+ return (deletionTimestamp != 0) && (now > deletionTimestamp);
+ }
+
+ /**
+ * Updates domain model with the incoming data.
+ * This is a template method that each concrete subclass must implement in order to update the domain model
+ * with the incoming data.
+ *
+ * @param packageName the name of the package.
+ * @param className the name of the class.
+ * @param objectId the object identifier.
+ * @param timeStampOfCurrentSample timestamp of current sample.
+ * @param timeObjectWasCreated time object was created.
+ * @param timeObjectWasDeleted time object was deleted.
+ * @param contentData object instance incoming data.
+ */
+ protected abstract void updateDomainModel(
+ String packageName,
+ String className,
+ Binary classHash,
+ Binary objectId,
+ long timeStampOfCurrentSample,
+ long timeObjectWasCreated,
+ long timeObjectWasDeleted,
+ byte []contentData );
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/base/IMessageHandler.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/base/IMessageHandler.java
new file mode 100644
index 0000000000..c120334d30
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/base/IMessageHandler.java
@@ -0,0 +1,52 @@
+/*
+ *
+ * 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.domain.handler.base;
+
+import org.apache.qpid.management.domain.model.DomainModel;
+import org.apache.qpid.transport.codec.Decoder;
+
+/**
+ * Interface definition for a processor able to deal with a specific message.
+ * The concrete implementor must define what has to be done with the supplied (incoming) stream and the sequence
+ * number.
+ *
+ * @author Andrea Gazzarini.
+ */
+public interface IMessageHandler
+{
+ /**
+ * Processes the (incoming) stream message.
+ * Note that the main controller (the component that is controlling this handler) has already read the magic number and
+ * the sequence number so here concrete implementors must start from that point (that is, just after the sequence
+ * number).
+ *
+ * @param decoder the stream decoder.
+ * @param sequenceNumber the sequence number of the message.
+ */
+ void process (Decoder decoder, int sequenceNumber);
+
+ /**
+ * Injects the domain model into this handler.
+ *
+ * @param domainModel the domain model.
+ */
+ void setDomainModel(DomainModel domainModel);
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/impl/ConfigurationMessageHandler.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/impl/ConfigurationMessageHandler.java
new file mode 100644
index 0000000000..3158138172
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/impl/ConfigurationMessageHandler.java
@@ -0,0 +1,57 @@
+/*
+ *
+ * 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.domain.handler.impl;
+
+import org.apache.qpid.management.domain.handler.base.ContentIndicationMessageHandler;
+import org.apache.qpid.management.domain.model.type.Binary;
+
+/**
+ * Schema Response message handler.
+ * This handler is responsible to process 'c'(opcode) messages sent by the management broker.
+ *
+ * @author Andrea Gazzarini
+ */
+public class ConfigurationMessageHandler extends ContentIndicationMessageHandler
+{
+ /**
+ * Broker domain model is going to be updated with incoming configuration data.
+ *
+ * @param packageName the name of the package.
+ * @param className the name of the class.
+ * @param objectId the object identifier.
+ * @param timeStampOfCurrentSample the timestamp of incoming data.
+ * @param timeObjectWasCreated time object was created.
+ * @param timeObjectWasDeleted time object was deleted.
+ */
+ @Override
+ protected void updateDomainModel (
+ String packageName,
+ String className,
+ Binary classHash,
+ Binary objectId,
+ long timeStampOfCurrentSample,
+ long timeObjectWasCreated,
+ long timeObjectWasDeleted,
+ byte[] contentData)
+ {
+ _domainModel.addConfigurationRawData(packageName,className,classHash,objectId,contentData);
+ }
+ }
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/impl/EventContentMessageHandler.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/impl/EventContentMessageHandler.java
new file mode 100644
index 0000000000..0a590d2836
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/impl/EventContentMessageHandler.java
@@ -0,0 +1,51 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.management.domain.handler.impl;
+
+import org.apache.qpid.management.domain.handler.base.BaseMessageHandler;
+import org.apache.qpid.management.domain.model.type.Binary;
+import org.apache.qpid.transport.codec.Decoder;
+
+/**
+ * Base class for content indication message handlers.
+ *
+ * @author Andrea Gazzarini
+ */
+public class EventContentMessageHandler extends BaseMessageHandler
+{
+ /**
+ * Processes the income message.
+ *
+ * @param decoder the decoder used to parse the message.
+ * @param sequenceNumber the sequence number of the message.
+ */
+ public final void process (Decoder decoder, int sequenceNumber)
+ {
+ String packageName = decoder.readStr8();
+ String eventName = decoder.readStr8();
+ Binary eventHash = new Binary(decoder.readBin128());
+ long timeStampOfCurrentSample = decoder.readDatetime();
+ int severity = decoder.readUint8();
+ byte[] argumentsData = decoder.readReaminingBytes();
+
+ _domainModel.addEventRawData(packageName, eventName, eventHash, argumentsData,timeStampOfCurrentSample,severity);
+ }
+}
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/impl/HeartBeatIndicationMessageHandler.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/impl/HeartBeatIndicationMessageHandler.java
new file mode 100644
index 0000000000..08c4f1bc5d
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/impl/HeartBeatIndicationMessageHandler.java
@@ -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.
+ *
+ */
+
+package org.apache.qpid.management.domain.handler.impl;
+
+import org.apache.qpid.management.domain.handler.base.BaseMessageHandler;
+import org.apache.qpid.transport.codec.Decoder;
+
+/**
+ * This is the handler responsible for processing the heartbeat indication response messages.
+ * At the moment it simply updates the last refresh update timestamp of the domain model.
+ *
+ * @author Andrea Gazzarini.
+ */
+public class HeartBeatIndicationMessageHandler extends BaseMessageHandler
+{
+ public void process(Decoder decoder, int sequenceNumber)
+ {
+ _domainModel.updateLastRefreshDate();
+ }
+}
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/impl/IMethodInvocationListener.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/impl/IMethodInvocationListener.java
new file mode 100644
index 0000000000..4ce64dd339
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/impl/IMethodInvocationListener.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.management.domain.handler.impl;
+
+import java.util.EventListener;
+
+import org.apache.qpid.management.domain.model.InvocationEvent;
+
+/**
+ * Listener interface used to denote a component interested in method invocation events.
+ *
+ * @author Andrea Gazzarini
+ */
+public interface IMethodInvocationListener extends EventListener
+{
+ /**
+ * An operation is going to be invoked on a specific object instance.
+ * This lets this listener to be informed about the imminent invocation.
+ *
+ * @param event the invocation event.
+ */
+ void operationIsGoingToBeInvoked(InvocationEvent event);
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/impl/InstrumentationMessageHandler.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/impl/InstrumentationMessageHandler.java
new file mode 100644
index 0000000000..e86a44f829
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/impl/InstrumentationMessageHandler.java
@@ -0,0 +1,57 @@
+/*
+ *
+ * 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.domain.handler.impl;
+
+import org.apache.qpid.management.domain.handler.base.ContentIndicationMessageHandler;
+import org.apache.qpid.management.domain.model.type.Binary;
+
+/**
+ * Schema Response message handler.
+ * This handler is responsible to process 'i'(opcode) messages sent by the management broker.
+ *
+ * @author Andrea Gazzarini
+ */
+public class InstrumentationMessageHandler extends ContentIndicationMessageHandler
+{
+ /**
+ * Broker domain model is going to be updated with incoming instrumentation data.
+ *
+ * @param packageName the name of the package.
+ * @param className the name of the class.
+ * @param objectId the object identifier.
+ * @param timeStampOfCurrentSample the timestamp of incoming data.
+ * @param timeObjectWasCreated time object was created.
+ * @param timeObjectWasDeleted time object was deleted.
+ */
+ @Override
+ protected void updateDomainModel (
+ String packageName,
+ String className,
+ Binary classHash,
+ Binary objectId,
+ long timeStampOfCurrentSample,
+ long timeObjectWasCreated,
+ long timeObjectWasDeleted,
+ byte[] contentData)
+ {
+ _domainModel.addInstrumentationRawData(packageName,className,classHash,objectId,contentData);
+ }
+ }
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/impl/InvocationResult.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/impl/InvocationResult.java
new file mode 100644
index 0000000000..019fce5a50
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/impl/InvocationResult.java
@@ -0,0 +1,157 @@
+/*
+ *
+ * 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.domain.handler.impl;
+
+import java.io.Serializable;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import org.apache.qpid.management.domain.services.MethodInvocationException;
+
+/**
+ * Value object used for storing an invocation method result.
+ * This is done in order to accomplish multiple return value requirement.
+ * As we know, it's not possible to do that only with method signature and therefore this value object / struct is used.
+ *
+ * @author Andrea Gazzarini
+ */
+public class InvocationResult implements Serializable
+{
+ private static final long serialVersionUID = 2062662997326399693L;
+
+ private final long _returnCode;
+ private final String _statusText;
+ private final byte [] _outputAndBidirectionalArgumentValues;
+ private Map<String, Object> _outputSection;
+
+ /**
+ * Builds an invocation result with the given status code and status text.
+ *
+ * @param statusCode the status code.
+ * @param statusText the status text.
+ */
+ InvocationResult(long statusCode, String statusText,byte [] outputAndBidirectionalArgumentValues)
+ {
+ this._returnCode = statusCode;
+ this._statusText = statusText;
+ this._outputAndBidirectionalArgumentValues = outputAndBidirectionalArgumentValues;
+ }
+
+ /**
+ * Checks if this result contains an error return code.
+ *
+ * @return true if this result object contains an error return code.
+ */
+ public boolean isException ()
+ {
+ return _returnCode != 0;
+ }
+
+ /**
+ * Simply throws a new MethodInvocationException.
+ * Usually this method is called in conjunction with the isException() method in order to raise an exception if
+ * the wrapped return code means that there was an error.
+ *
+ * @throws MethodInvocationException always.
+ */
+ public void createAndThrowException() throws MethodInvocationException
+ {
+ throw new MethodInvocationException(_returnCode, _statusText);
+ }
+
+ @Override
+ public String toString ()
+ {
+ StringBuilder builder = new StringBuilder()
+ .append("Status code : ")
+ .append(_returnCode)
+ .append(",")
+ .append("Status Text : ")
+ .append(_statusText);
+ if (_outputSection != null && !_outputSection.isEmpty())
+ {
+ builder.append(". Parameters : ");
+ for (Entry<String, Object> outputEntry : _outputSection.entrySet())
+ {
+ builder.append(outputEntry.getKey()).append('=').append(outputEntry.getValue());
+ builder.append(',');
+ }
+ }
+ return builder.toString();
+ }
+
+ /**
+ * Returns the return code of this invocation result.
+ *
+ * @return the return code of this invocation result.
+ */
+ public long getReturnCode ()
+ {
+ return _returnCode;
+ }
+
+ /**
+ * Contains the status text of this invocation result.
+ *
+ * @return the status text of this invocation result.
+ */
+ public String getStatusText ()
+ {
+ return _statusText;
+ }
+
+ /**
+ * Returns the output and bidirectional argument values in raw format (byte [])
+ *
+ * @return the output and bidirectional argument values in raw format (byte [])
+ */
+ public byte [] getOutputAndBidirectionalArgumentValues()
+ {
+ return _outputAndBidirectionalArgumentValues;
+ }
+
+ /**
+ * Sets the output section (decoded) of this invocation result.
+ * When an incoming message arrives, the output section (output and bidirectional argument values) are
+ * initially stored in raw format.
+ * After that, their values need to be converted.
+ * The final result is a map containing (for each Output or Input/Output parameter) the name of the argument as key
+ * and its value as value.
+ *
+ * @param output a map containing outptu and bidirectional values (not in schema order).
+ */
+ public void setOutputSection (Map<String, Object> outputSection)
+ {
+ this._outputSection = outputSection;
+ }
+
+ /**
+ * Returns the output section of this invocation result.
+ * The output section consists in output and bidirectional argument values.
+ * Note that the order of the arguments is not guaranteed.
+ *
+ * @param outputSection the output section of this invocation result;
+ */
+ public Map<String, Object> getOutputSection ()
+ {
+ return _outputSection;
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/impl/MethodOrEventDataTransferObject.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/impl/MethodOrEventDataTransferObject.java
new file mode 100644
index 0000000000..bc6a77d804
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/impl/MethodOrEventDataTransferObject.java
@@ -0,0 +1,68 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.management.domain.handler.impl;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Simple transfer object used for holding method / event definition data.
+ *
+ * @author Andrea Gazzarini
+ */
+public class MethodOrEventDataTransferObject
+{
+ private final Map<String, Object> _definition;
+ private List<Map<String, Object>> _argumentDefinitions;
+
+ /**
+ * Builds a new trasfer object with the given parameters.
+ *
+ * @param definition the method definition.
+ * @param argumentDefinitions the arguments definitions.
+ */
+ public MethodOrEventDataTransferObject(
+ Map<String, Object> definition,
+ List<Map<String, Object>> argumentDefinitions)
+ {
+ this._definition = definition;
+ this._argumentDefinitions = argumentDefinitions;
+ }
+
+ /**
+ * Returns the method definition.
+ *
+ * @return the method definition.
+ */
+ public Map<String, Object> getDefinition() {
+ return _definition;
+ }
+
+ /**
+ * Returns the arguemnts definitions.
+ *
+ * @return the arguemnts definitions.
+ */
+ public List<Map<String, Object>> getArgumentsDefinitions()
+ {
+ return _argumentDefinitions;
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/impl/MethodResponseMessageHandler.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/impl/MethodResponseMessageHandler.java
new file mode 100644
index 0000000000..9c99eb09aa
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/impl/MethodResponseMessageHandler.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.management.domain.handler.impl;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.BlockingQueue;
+
+import org.apache.qpid.management.Messages;
+import org.apache.qpid.management.domain.handler.base.BaseMessageHandler;
+import org.apache.qpid.management.domain.model.DomainModel;
+import org.apache.qpid.management.domain.model.InvocationEvent;
+import org.apache.qpid.transport.codec.Decoder;
+import org.apache.qpid.transport.util.Logger;
+
+/**
+ * Message handler for method response messages.
+ * This handler is installed on domain model as a method invocation result listener.
+ * When a method is going to be invoked this listener is notified with the exchange channel that will be used between it and
+ * the event (method invocation) source object.
+ *
+ * @author Andrea Gazzarini
+ *
+ */
+public class MethodResponseMessageHandler extends BaseMessageHandler
+{
+ private final static Logger LOGGER = Logger.get(MethodResponseMessageHandler.class);
+
+ private Map<Integer, BlockingQueue<InvocationResult>> _exchangeChannels = new HashMap<Integer, BlockingQueue<InvocationResult>>();
+
+ /**
+ * This is the listener installed on domain model for method invocations.
+ */
+ private final IMethodInvocationListener methodInvocationListener = new IMethodInvocationListener()
+ {
+ /**
+ * Event source callback.
+ * A method is going to be invoked and this method lets this listener take the exchange channel that will be used
+ * with the event source for synchronous communication.
+ *
+ * @param event the operation invocation event.
+ */
+ public void operationIsGoingToBeInvoked (InvocationEvent event)
+ {
+ _exchangeChannels.put(event.getSequenceNumber(), event.getExchangeChannel());
+ }
+ };
+
+ /**
+ * Processes the incoming message.
+ *
+ * @param decoder the decoder used for parsing incoming data.
+ * @param sequenceNumber the sequence number of the incoming message.
+ */
+ public void process (Decoder decoder, int sequenceNumber)
+ {
+ InvocationResult result = new InvocationResult(decoder.readUint32(), decoder.readStr16(),decoder.readReaminingBytes());
+ BlockingQueue<InvocationResult> exchangeChannel = _exchangeChannels.remove(sequenceNumber);
+ if (exchangeChannel != null)
+ {
+ try
+ {
+ exchangeChannel.put(result);
+ } catch (InterruptedException exception)
+ {
+ LOGGER.error(exception,Messages.QMAN_100010_METHOD_INVOCATION_RESULT_FAILURE,sequenceNumber);
+ }
+ } else
+ {
+ LOGGER.warn(
+ "Unable to deal with incoming message because it contains a unknown sequence number (%s).",
+ sequenceNumber);
+ }
+ }
+
+ /**
+ * Sets the domain model on this handler.
+ * In addiction, this handler registers a method invocation listener on the domain model.
+ *
+ * @param domainModel the managed broker domain model.
+ */
+ @Override
+ public void setDomainModel (DomainModel domainModel)
+ {
+ super.setDomainModel(domainModel);
+ domainModel.setMethodInvocationListener(methodInvocationListener);
+ }
+}
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/impl/QpidDomainObject.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/impl/QpidDomainObject.java
new file mode 100644
index 0000000000..8456b2f8ac
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/impl/QpidDomainObject.java
@@ -0,0 +1,314 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.management.domain.handler.impl;
+
+import java.net.URI;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
+
+import org.apache.qpid.management.domain.services.MethodInvocationException;
+
+/**
+ * This is a sample entity used on QMan test case.
+ *
+ * @author Andrea Gazzarini
+ */
+public class QpidDomainObject implements QpidDomainObjectMBean
+{
+ private UUID _vhostRef;
+ private String _name;
+ private Boolean _durable;
+ private Map<String, Object> _arguments;
+ private Long _msgTotalEnqueues;
+ private Integer _consumerCount;
+ private Short _mgmtPubInterval;
+ private Date _expireTime;
+ private String _type;
+ private byte [] _byteArray;
+
+ /**
+ * Builds a new QpidDomainObject with default values for
+ * its properties.
+ */
+ public QpidDomainObject()
+ {
+ _vhostRef = UUID.randomUUID();
+ _name = "Initial Name";
+ _durable = Boolean.TRUE;
+ _arguments = new HashMap<String, Object>();
+ _arguments.put("Key1", "aStringValue");
+ _arguments.put("Key2", Long.MIN_VALUE);
+ _arguments.put("Key3", Integer.MAX_VALUE);
+ _arguments.put("Key4", Double.MIN_VALUE);
+ _arguments.put("Key4", Float.MAX_VALUE);
+
+ _msgTotalEnqueues = Long.MAX_VALUE-10;
+ _consumerCount = Integer.MIN_VALUE+10;
+ _mgmtPubInterval = Short.MAX_VALUE;
+ _expireTime = new Date(Long.MAX_VALUE);
+ _byteArray = new byte[]{1,2,3,5,6,7,8,7,56};
+ }
+
+ /**
+ * A method that is throwing an exception, everytime.
+ *
+ * @throws Exception each time the method is called.
+ */
+ public void throwsException() throws Exception
+ {
+ throw new MethodInvocationException(-1,"KO");
+ }
+
+ /**
+ * Sample echo method that return an empty result object.
+ * That is, an object with only status code / text valorized
+ * (no output parameters).
+ *
+ * @return an empty result object.
+ */
+ public InvocationResult voidWithoutArguments()
+ {
+ return new InvocationResult(0,"OK,null",null);
+ }
+
+ /**
+ * Echo method that accepts and returns primitive type arrays.
+ *
+ * @param longs an array of long.
+ * @param booleans an array of boolean.
+ * @param doubles an array of double.
+ * @param floats an array of float.
+ * @param integers an array of int.
+ * @param shorts an array of short.
+ * @return a result object with the same input parameters (as output parameters).
+ */
+ public InvocationResult echoWithSimpleTypeArrays(
+ long [] longs,
+ boolean [] booleans,
+ double [] doubles,
+ float [] floats,
+ int [] integers,
+ short [] shorts)
+ {
+ InvocationResult result = new InvocationResult(0,"OK",null);
+ Map<String, Object> outputParameters = new HashMap<String, Object>();
+ outputParameters.put(long.class.getName(), longs);
+ outputParameters.put(boolean.class.getName(), booleans);
+ outputParameters.put(double.class.getName(), doubles);
+ outputParameters.put(float.class.getName(), floats);
+ outputParameters.put(int.class.getName(), integers);
+ outputParameters.put(short.class.getName(), shorts);
+ result.setOutputSection(outputParameters);
+ return result;
+ }
+
+ /**
+ * Echo method that accepts and returns wrapper types.
+ *
+ * @param aLong a java.lang.Long
+ * @param aBoolean a java.lang.Boolean
+ * @param aDouble a java.lang.Double
+ * @param aFloat a java.lang.Float
+ * @param anInteger a java.lang.Integer
+ * @param aShort a java.lang.Short
+ * @param aString a java.lang.String
+ * @param anURI a java.net.URI
+ * @param aDate a java.util.Date
+ * @return a result object with the same given parameters (as output parameters)
+ */
+ public InvocationResult echoWithSimpleTypes(
+ Long aLong,
+ Boolean aBoolean,
+ Double aDouble,
+ Float aFloat,
+ Integer anInteger,
+ Short aShort,
+ String aString,
+ URI anURI,
+ Date aDate)
+ {
+ InvocationResult result = new InvocationResult(0,"OK",null);
+ Map<String, Object> outputParameters = new HashMap<String, Object>();
+ outputParameters.put("p1", aLong);
+ outputParameters.put("p2", aBoolean);
+ outputParameters.put("p3", aDouble);
+ outputParameters.put("p4", aFloat);
+ outputParameters.put("p5", anInteger);
+ outputParameters.put("p6", aShort);
+ outputParameters.put("p7", aString);
+ outputParameters.put("p8", anURI);
+ outputParameters.put("p9", aDate);
+ result.setOutputSection(outputParameters);
+ return result;
+ }
+
+ /**
+ * Echo method that accepts and returns wrapper type arrays .
+ *
+ * @param longs an array of java.lang.Long
+ * @param booleans an array of java.lang.Boolean
+ * @param doubles an array of java.lang.Double
+ * @param floats an array of java.lang.Float
+ * @param integers an array of java.lang.Integer
+ * @param shorts an array of java.lang.Short
+ * @param strings an array of java.lang.String
+ * @param uris an array of java.net.URI
+ * @param dates an array of java.util.Date
+ * @return a result object with the same input parameters (as output parameters).
+ */
+ public InvocationResult echoWithArrays(
+ Long [] longs,
+ Boolean [] booleans,
+ Double [] doubles,
+ Float [] floats,
+ Integer [] integers,
+ Short [] shorts,
+ String [] strings,
+ URI [] uris,
+ Date [] dates)
+ {
+ InvocationResult result = new InvocationResult(0,"OK",null);
+ Map<String, Object> outputParameters = new HashMap<String, Object>();
+ outputParameters.put(Long.class.getName(), longs);
+ outputParameters.put(Boolean.class.getName(), booleans);
+ outputParameters.put(Double.class.getName(), doubles);
+ outputParameters.put(Float.class.getName(), floats);
+ outputParameters.put(Integer.class.getName(), integers);
+ outputParameters.put(Short.class.getName(), shorts);
+ outputParameters.put(String.class.getName(), strings);
+ outputParameters.put(URI.class.getName(), uris);
+ outputParameters.put(Date.class.getName(), dates);
+ result.setOutputSection(outputParameters);
+ return result;
+ }
+
+ /**
+ * Echo method that accepts and returns a byte array.
+ *
+ * @param byteArray a byte array
+ * @return a result containing the input byte array (as output parameter)
+ */
+ public InvocationResult echoWithByteArray(byte [] byteArray)
+ {
+ InvocationResult result = new InvocationResult(0,"OK",null);
+ Map<String, Object> outputParameters = new HashMap<String, Object>();
+ outputParameters.put(byte[].class.getName(),byteArray);
+ result.setOutputSection(outputParameters);
+ return result;
+ }
+
+ /**
+ * Echo method that accepts and returns an UUID.
+ *
+ * @param uuid a java.util.UUID.
+ * @return a result containing the input UUID (as output parameter)
+ */
+ public InvocationResult echoWithUUID(UUID uuid)
+ {
+ InvocationResult result = new InvocationResult(0,"OK",null);
+ Map<String, Object> outputParameters = new HashMap<String, Object>();
+ outputParameters.put("uuid",uuid);
+ result.setOutputSection(outputParameters);
+ return result;
+ }
+
+ /**
+ * Echo method that accepts and returns a Map.
+ *
+ * @param map a java.util.Map.
+ * @return a result containing the input Map (as output parameter)
+ */
+ public InvocationResult echoWithMap(Map<String,Object> map)
+ {
+ InvocationResult result = new InvocationResult(0,"OK",null);
+ Map<String, Object> outputParameters = new HashMap<String, Object>();
+ outputParameters.put("map",map);
+ result.setOutputSection(outputParameters);
+ return result;
+ }
+
+ public UUID getVhostRef()
+ {
+ return _vhostRef;
+ }
+
+ public String getName()
+ {
+ return _name;
+ }
+
+ public Boolean getDurable()
+ {
+ return _durable;
+ }
+
+ public Map<String, Object> getArguments()
+ {
+ return _arguments;
+ }
+
+ public Long getMsgTotalEnqueues()
+ {
+ return _msgTotalEnqueues;
+ }
+
+ public Integer getConsumerCount()
+ {
+ return _consumerCount;
+ }
+
+ public Date getExpireTime()
+ {
+ return _expireTime;
+ }
+
+ public Short getMgmtPubInterval()
+ {
+ return _mgmtPubInterval;
+ }
+
+ public void setExpireTime(Date expireTime)
+ {
+ this._expireTime = expireTime;
+ }
+
+ public void setMgmtPubInterval(Short value)
+ {
+ this._mgmtPubInterval = value;
+ }
+
+ public void setType(String type)
+ {
+ this._type = type;
+ }
+
+ public String getType()
+ {
+ return _type;
+ }
+
+ public byte[] getByteArray()
+ {
+ return _byteArray;
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/impl/QpidDomainObjectMBean.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/impl/QpidDomainObjectMBean.java
new file mode 100644
index 0000000000..da585a9f43
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/impl/QpidDomainObjectMBean.java
@@ -0,0 +1,234 @@
+/*
+ *
+ * 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.domain.handler.impl;
+
+import java.net.URI;
+import java.util.Date;
+import java.util.Map;
+import java.util.UUID;
+
+/**
+ * Management interface for Qpid domain object.
+ *
+ * @author Andrea Gazzarini
+ */
+public interface QpidDomainObjectMBean
+{
+ /**
+ * A method that is throwing an exception, everytime.
+ *
+ * @throws Exception each time the method is called.
+ */
+ void throwsException() throws Exception;
+
+ /**
+ * Sample echo method that return an empty result object.
+ * That is, an object with only status code / text valorized
+ * (no output parameters).
+ *
+ * @return an empty result object.
+ */
+ InvocationResult voidWithoutArguments();
+
+ /**
+ * Echo method that accepts and returns wrapper types.
+ *
+ * @param aLong a java.lang.Long
+ * @param aBoolean a java.lang.Boolean
+ * @param aDouble a java.lang.Double
+ * @param aFloat a java.lang.Float
+ * @param anInteger a java.lang.Integer
+ * @param aShort a java.lang.Short
+ * @param aString a java.lang.String
+ * @param anURI a java.net.URI
+ * @param aDate a java.util.Date
+ * @return a result object with the same given parameters (as output parameters)
+ */
+ InvocationResult echoWithSimpleTypes(
+ Long aLong,
+ Boolean aBoolean,
+ Double aDouble,
+ Float aFloat,
+ Integer anInteger,
+ Short aShort,
+ String aString,
+ URI anURI,
+ Date aDate);
+
+ /**
+ * Echo method that accepts and returns wrapper type arrays .
+ *
+ * @param longs an array of java.lang.Long
+ * @param booleans an array of java.lang.Boolean
+ * @param doubles an array of java.lang.Double
+ * @param floats an array of java.lang.Float
+ * @param integers an array of java.lang.Integer
+ * @param shorts an array of java.lang.Short
+ * @param strings an array of java.lang.String
+ * @param uris an array of java.net.URI
+ * @param dates an array of java.util.Date
+ * @return a result object with the same input parameters (as output parameters).
+ */
+ InvocationResult echoWithArrays(
+ Long [] longs,
+ Boolean [] booleans,
+ Double [] doubles,
+ Float [] floats,
+ Integer [] integers,
+ Short [] shorts,
+ String [] strings,
+ URI [] uris,
+ Date [] dates);
+
+ /**
+ * Echo method that accepts and returns primitive type arrays.
+ *
+ * @param longs an array of long.
+ * @param booleans an array of boolean.
+ * @param doubles an array of double.
+ * @param floats an array of float.
+ * @param integers an array of int.
+ * @param shorts an array of short.
+ * @return a result object with the same input parameters (as output parameters).
+ */
+ InvocationResult echoWithSimpleTypeArrays(
+ long [] longs,
+ boolean [] booleans,
+ double [] doubles,
+ float [] floats,
+ int [] integers,
+ short [] shorts);
+
+ /**
+ * Echo method that accepts and returns a byte array.
+ *
+ * @param byteArray a byte array
+ * @return a result containing the input byte array (as output parameter)
+ */
+ InvocationResult echoWithByteArray(byte [] byteArray);
+
+ /**
+ * Echo method that accepts and returns an UUID.
+ *
+ * @param uuid a java.util.UUID.
+ * @return a result containing the input UUID (as output parameter)
+ */
+ InvocationResult echoWithUUID(UUID uuid);
+
+ /**
+ * Echo method that accepts and returns a Map.
+ *
+ * @param map a java.util.Map.
+ * @return a result containing the input Map (as output parameter)
+ */
+ InvocationResult echoWithMap(Map<String,Object> map);
+
+ /**
+ * Returns the VHostRef property value.
+ *
+ * @return the VHostRef property value.
+ */
+ UUID getVhostRef();
+
+ /**
+ * Returns the name property value.
+ *
+ * @return the name property value.
+ */
+ String getName();
+
+ /**
+ * Returns the durable property value.
+ *
+ * @return the durable property value.
+ */
+ Boolean getDurable();
+
+ /**
+ * Returns the arguments property value.
+ *
+ * @return the arguments property value.
+ */
+ Map<String, Object> getArguments();
+
+ /**
+ * Returns the msgTotalEnqueues property value.
+ *
+ * @return the msgTotalEnqueues property value.
+ */
+ Long getMsgTotalEnqueues();
+
+ /**
+ * Returns the consumerCount property value.
+ *
+ * @return the consumerCount property value.
+ */
+ Integer getConsumerCount();
+
+ /**
+ * Returns the mgmtPubInterval property value.
+ *
+ * @return the mgmtPubInterval property value.
+ */
+ Short getMgmtPubInterval();
+
+ /**
+ * Sets the mgmtPubInterval property value.
+ *
+ * @param the mgmtPubInterval property value.
+ */
+ void setMgmtPubInterval(Short mgmtPubInterval);
+
+ /**
+ * Returns the expireTime property value.
+ *
+ * @return the expireTime property value.
+ */
+ Date getExpireTime();
+
+ /**
+ * Sets the expireTime property value.
+ *
+ * @return the expireTime property value.
+ */
+ void setExpireTime(Date expireTime);
+
+ /**
+ * Returns the type property value.
+ *
+ * @return the type property value.
+ */
+ void setType(String type);
+
+ /**
+ * Sets the type property value.
+ *
+ * @return the type property value.
+ */
+ String getType();
+
+// /**
+// * Returns the byteArray property value.
+// *
+// * @return the byteArray property value.
+// */
+// byte[] getByteArray();
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/impl/SchemaResponseMessageHandler.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/impl/SchemaResponseMessageHandler.java
new file mode 100644
index 0000000000..4564acc9d0
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/impl/SchemaResponseMessageHandler.java
@@ -0,0 +1,217 @@
+/*
+ *
+ * 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.domain.handler.impl;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.qpid.management.Messages;
+import org.apache.qpid.management.Names;
+import org.apache.qpid.management.Protocol;
+import org.apache.qpid.management.domain.handler.base.BaseMessageHandler;
+import org.apache.qpid.management.domain.model.type.Binary;
+import org.apache.qpid.transport.codec.Decoder;
+
+/**
+ * Schema Response message handler.
+ * This handler is responsible to process 'S'(opcode) messages sent by the management broker containing the full
+ * schema details for a class.
+ *
+ * @author Andrea Gazzarini
+ */
+public class SchemaResponseMessageHandler extends BaseMessageHandler
+{
+ /**
+ * Behavioural interface for classes that are responsible to deal with schema messages.
+ *
+ * @author Andrea Gazzarini
+ */
+ interface IProcessor
+ {
+ /**
+ * Processes the incoming message using the given decoder.
+ *
+ * @param decoder the decoder used for dealing with incoming message.
+ */
+ void process(Decoder decoder);
+ }
+
+ /**
+ * Processor responsible to deal with class schema related messages.
+ */
+ final IProcessor _classSchemaProcessor = new IProcessor()
+ {
+ public void process(Decoder decoder)
+ {
+ try
+ {
+ String packageName = decoder.readStr8();
+ String className = decoder.readStr8();
+
+ Binary schemaHash = new Binary(decoder.readBin128());
+
+ int howManyProperties = decoder.readUint16();
+ int howManyStatistics = decoder.readUint16();
+ int howManyMethods = decoder.readUint16();
+
+ _domainModel.addSchema(
+ packageName,
+ className,
+ schemaHash,
+ getAttributes(decoder, howManyProperties),
+ getAttributes(decoder, howManyStatistics),
+ getMethods(decoder, howManyMethods));
+ } catch(Exception exception)
+ {
+ _logger.error(exception,Messages.QMAN_100005_CLASS_SCHEMA_PROCESSING_FAILURE);
+ }
+ }
+ };
+
+ /**
+ * Processor responsible to deal with class event related messages.
+ */
+ final IProcessor _eventSchemaProcessor = new IProcessor()
+ {
+ public void process(Decoder decoder)
+ {
+ try
+ {
+ String packageName = decoder.readStr8();
+ String className = decoder.readStr8();
+ Binary hash = new Binary(decoder.readBin128());
+ int howManyArguments = decoder.readUint16();
+
+ _domainModel.addEventSchema(
+ packageName,
+ className,
+ hash,
+ getAttributes(decoder, howManyArguments));
+ } catch(Exception exception)
+ {
+ _logger.error(exception,Messages.QMAN_100006_EVENT_SCHEMA_PROCESSING_FAILURE);
+ }
+ }
+ };
+
+ /**
+ * Processes an incoming schema response.
+ * This will be used for building the corresponding class definition.
+ *
+ * @param decoder the decoder used for parsing the incoming stream.
+ * @param sequenceNumber the sequence number of the incoming message.
+ */
+ public void process (Decoder decoder, int sequenceNumber)
+ {
+ try
+ {
+ int classKind = decoder.readUint8();
+ switch(classKind)
+ {
+ case Protocol.CLASS :
+ {
+ _classSchemaProcessor.process(decoder);
+ break;
+ }
+ case Protocol.EVENT :
+ {
+ _eventSchemaProcessor.process(decoder);
+ break;
+ }
+ default :
+ {
+ _logger.error(Messages.QMAN_100011_UNKNOWN_CLASS_KIND,classKind);
+ }
+ }
+ } catch(Exception exception)
+ {
+ _logger.error(exception,Messages.QMAN_100012_SCHEMA_MESSAGE_PROCESSING_FAILURE);
+ }
+ }
+
+ /**
+ * Reads from the incoming message stream the properties definitions.
+ *
+ * @param decoder the decoder used for decode incoming data.
+ * @param howManyProperties the number of properties to read.
+ * @return a list of maps. Each map contains a property definition.
+ */
+ List<Map<String, Object>> getAttributes(Decoder decoder,int howMany)
+ {
+ List<Map<String, Object>> result = new ArrayList<Map<String, Object>>(howMany);
+ for (int i = 0; i < howMany; i++ )
+ {
+ result.add(decoder.readMap());
+ }
+ return result;
+ }
+
+ /**
+ * Reads the methods definitions from the incoming message stream.
+ *
+ * @param decoder the decoder used for decode incoming data.
+ * @param howManyMethods the number of methods to read.
+ * @return a list method definitions.
+ */
+ List<MethodOrEventDataTransferObject> getMethods(Decoder decoder, int howManyMethods)
+ {
+ List<MethodOrEventDataTransferObject> result = new ArrayList<MethodOrEventDataTransferObject>(howManyMethods);
+ for (int i = 0; i < howManyMethods; i++)
+ {
+ Map<String,Object> method = decoder.readMap();
+ int howManyArguments = (Integer) method.get(Names.ARG_COUNT_PARAM_NAME);
+
+ List<Map<String,Object>> arguments = new ArrayList<Map<String,Object>>(howManyArguments);
+ for (int argIndex = 0; argIndex < howManyArguments; argIndex++)
+ {
+ arguments.add(decoder.readMap());
+ }
+ result.add(new MethodOrEventDataTransferObject(method,arguments));
+ }
+ return result;
+ }
+
+ /**
+ * Reads the events definitions from the incoming message stream.
+ *
+ * @param decoder the decoder used for decode incoming data.
+ * @param howManyEvents the number of events to read.
+ * @return a list event definitions.
+ */
+ List<MethodOrEventDataTransferObject> getEvents(Decoder decoder, int howManyEvents)
+ {
+ List<MethodOrEventDataTransferObject> result = new ArrayList<MethodOrEventDataTransferObject>(howManyEvents);
+ for (int i = 0; i < howManyEvents; i++)
+ {
+ Map<String,Object> method = decoder.readMap();
+ int howManyArguments = (Integer) method.get(Names.ARG_COUNT_PARAM_NAME);
+
+ List<Map<String,Object>> arguments = new ArrayList<Map<String,Object>>(howManyArguments);
+ for (int argIndex = 0; argIndex < howManyArguments; argIndex++)
+ {
+ arguments.add(decoder.readMap());
+ }
+ result.add(new MethodOrEventDataTransferObject(method,arguments));
+ }
+ return result;
+ }
+ }
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/AccessMode.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/AccessMode.java
new file mode 100644
index 0000000000..6d1426c122
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/AccessMode.java
@@ -0,0 +1,33 @@
+/*
+ *
+ * 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.domain.model;
+
+/**
+ * Enumeration for Access modes.
+ *
+ * @author Andrea Gazzarini
+ */
+public enum AccessMode
+{
+ RC { @Override public String toString() { return "Read-Create"; }},
+ RO { @Override public String toString() { return "Read-Only"; }},
+ RW { @Override public String toString() { return "Read-Write"; }}
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/Direction.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/Direction.java
new file mode 100644
index 0000000000..8166c35eb6
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/Direction.java
@@ -0,0 +1,33 @@
+/*
+ *
+ * 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.domain.model;
+
+/**
+ * Enumeration of allowed method argument direction codes.
+ *
+ * @author Andrea Gazzarini
+ */
+public enum Direction
+{
+ I{ @Override public String toString() { return "Input"; }},
+ O{ @Override public String toString() { return "Output"; }},
+ IO{ @Override public String toString() { return "Input-Output"; }};
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/DomainModel.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/DomainModel.java
new file mode 100644
index 0000000000..5a0ebaf1f7
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/DomainModel.java
@@ -0,0 +1,239 @@
+/*
+ *
+ * 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.domain.model;
+
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+
+import org.apache.qpid.management.domain.handler.impl.IMethodInvocationListener;
+import org.apache.qpid.management.domain.handler.impl.MethodOrEventDataTransferObject;
+import org.apache.qpid.management.domain.model.type.Binary;
+
+/**
+ * Broker domain model.
+ * This is the local representation of a remote broker domain model.
+ *
+ * @author Andrea Gazzarini
+ */
+public class DomainModel
+{
+ private final UUID _id;
+
+ /** Here the known packages of the remote broker are stored. */
+ Map<String,QpidPackage> _packages = new HashMap<String, QpidPackage>();
+
+ private Date _lastRefreshDate = new Date();
+
+ private IMethodInvocationListener _methodInvocationListener;
+
+ /**
+ * Builds a new domain model with the given broker identifier.
+ *
+ * @param brokerId the broker identifier.
+ */
+ public DomainModel(UUID brokerId)
+ {
+ this._id = brokerId;
+ }
+
+ /**
+ * Returns the identifier of the broker associated with this domain model.
+ *
+ * @return the identifier of the broker associated with this domain model.
+ */
+ public UUID getBrokerId()
+ {
+ return _id;
+ }
+
+ /**
+ * Adds the specified schema to this domain model.
+ *
+ * @param packageName the package name.
+ * @param className the class name.
+ * @param classHash the class schema hash.
+ * @param properties the class properties.
+ * @param statistics the class statistics.
+ * @param methods the class methods.
+ * @throws UnableToBuildFeatureException
+ */
+ public void addSchema(
+ String packageName,
+ String className,
+ Binary classHash,
+ List<Map<String, Object>> properties,
+ List<Map<String, Object>> statistics,
+ List<MethodOrEventDataTransferObject> methods) throws UnableToBuildFeatureException
+ {
+ QpidPackage qpidPackage = getPackageByName(packageName);
+ qpidPackage.addClassDefinition(className,classHash,properties,statistics,methods);
+ }
+
+ /**
+ * Updates the last refresh date.
+ */
+ public void updateLastRefreshDate()
+ {
+ this._lastRefreshDate = new Date();
+ }
+
+ /**
+ * Returns the last refresh date.
+ *
+ * @return the last refresh date.
+ */
+ public Date getLastRefreshDate()
+ {
+ return _lastRefreshDate;
+ }
+
+ /**
+ * Adds the specified schema to this domain model.
+ *
+ * @param packageName the package name.
+ * @param className the class name.
+ * @param classHash the class schema hash.
+ * @param properties the class properties.
+ * @param statistics the class statistics.
+ * @param methods the class methods.
+ * @throws UnableToBuildFeatureException
+ */
+ public void addEventSchema(
+ String packageName,
+ String className,
+ Binary classHash,
+ List<Map<String, Object>> arguments) throws UnableToBuildFeatureException
+ {
+ QpidPackage qpidPackage = getPackageByName(packageName);
+ qpidPackage.addEventDefinition(className,classHash,arguments);
+ }
+
+ /**
+ * Gets the package with the specified name.
+ * Note that if the package doesn't exist a new one will be created and returned.
+ *
+ * @param packageName the name of the package.
+ * @return the package.
+ */
+ QpidPackage getPackageByName (String packageName)
+ {
+ QpidPackage qpidPackage = _packages.get(packageName);
+ if (qpidPackage == null)
+ {
+ qpidPackage = new QpidPackage(packageName,this);
+ _packages.put(packageName, qpidPackage);
+ }
+ return qpidPackage;
+ }
+
+ /**
+ * Returns true if a package with the specified name already exists on this domain model.
+ *
+ * @param packageName the name of the package.
+ * @return true if the package exists, false otherwise.
+ */
+ boolean containsPackage (String packageName)
+ {
+ return _packages.containsKey(packageName);
+ }
+
+ /**
+ * Adds the given instrumentation data (raw format) to this domain model.
+ * Note that this data is belonging to a specific object instance.
+ *
+ * @param packageName the name of the ower package.
+ * @param className the name of the owner class.
+ * @param classHash the schema hash for this class.
+ * @param objectId the object instance identifier.
+ * @param rawData the instrumentation data.
+ */
+ public void addInstrumentationRawData (String packageName, String className,Binary classHash, Binary objectId, byte[] rawData)
+ {
+ QpidPackage qpidPackage = getPackageByName(packageName);
+ qpidPackage.setObjectInstanceInstrumentationRawData(className,classHash,objectId,rawData);
+ }
+
+ public void addEventRawData (
+ String packageName,
+ String eventName,
+ Binary eventHash,
+ byte[] rawData,
+ long currentTimestamp,
+ int severity)
+ {
+ QpidPackage qpidPackage = getPackageByName(packageName);
+ qpidPackage.setEventInstanceRawData(eventName,eventHash,rawData,currentTimestamp,severity);
+ }
+
+ /**
+ * Adds the given configuration data (raw format) to this domain model.
+ * Note that this data is belonging to a specific object instance.
+ *
+ * @param packageName the name of the ower package.
+ * @param className the name of the owner class.
+ * @param classHash the schema hash for this class.
+ * @param objectId the object instance identifier.
+ * @param rawData the configuration data.
+ */
+ public void addConfigurationRawData (String packageName, String className, Binary classHash,Binary objectId, byte[] rawData)
+ {
+ QpidPackage qpidPackage = getPackageByName(packageName);
+ qpidPackage.setObjectInstanceConfigurationRawData(className,classHash,objectId,rawData);
+ }
+
+ /**
+ * Removes the object instance associated to the given parameters.
+ *
+ * @param packageName the owner package.
+ * @param className the class definition of the object instance.
+ * @param classHash the class hash
+ * @param objectId the object identifier.
+ */
+ public void removeObjectInstance (String packageName, String className, Binary classHash, Binary objectId)
+ {
+ QpidPackage qpidPackage = getPackageByName(packageName);
+ qpidPackage.removeObjectInstance(className, classHash, objectId);
+ }
+
+ /**
+ * Releases all the resources kept by domain model entitiies.
+ */
+ public void releaseResources()
+ {
+ for (QpidPackage qpidPackage : _packages.values())
+ {
+ qpidPackage.releaseResources();
+ }
+ }
+
+ public void setMethodInvocationListener(IMethodInvocationListener listener)
+ {
+ this._methodInvocationListener = listener;
+ }
+
+ IMethodInvocationListener getMethodInvocationListener ()
+ {
+ return _methodInvocationListener;
+ }
+}
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/IValidator.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/IValidator.java
new file mode 100644
index 0000000000..1ede559145
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/IValidator.java
@@ -0,0 +1,38 @@
+/*
+ *
+ * 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.domain.model;
+
+/**
+ * Interface definition for attribute validators.
+ *
+ * @author Andrea Gazzarini
+ */
+interface IValidator
+{
+ /**
+ * Validates the given value according to the rules definied by this validator.
+ *
+ * @param value the value be checked.
+ *
+ * @throws ValidationException when the value is violating validator's rules.
+ */
+ void validate(Object value) throws ValidationException;
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/InvocationEvent.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/InvocationEvent.java
new file mode 100644
index 0000000000..d84a018346
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/InvocationEvent.java
@@ -0,0 +1,76 @@
+/*
+ *
+ * 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.domain.model;
+
+import java.util.EventObject;
+import java.util.concurrent.BlockingQueue;
+
+import org.apache.qpid.management.domain.handler.impl.InvocationResult;
+
+/**
+ * Operation invocation event.
+ * This encapsulates all the information that a method invocation listener needs to know about an operation which is
+ * going to be invoked.
+ *
+ * @author Andrea Gazzarini
+ */
+public class InvocationEvent extends EventObject
+{
+ private static final long serialVersionUID = 240229490753008597L;
+
+ private final int _sequenceNumber;
+ private final BlockingQueue<InvocationResult> _exchangeChannel;
+
+ /**
+ * Builds a new invocation event with the given data.
+ *
+ * @param source the event source.
+ * @param sequenceNumber the sequence number of the method invocation.
+ * @param exchangeChannel the exchange channel for synchronous communication.
+ */
+ InvocationEvent(Object source, int sequenceNumber, BlockingQueue<InvocationResult> exchangeChannel)
+ {
+ super(source);
+ this._sequenceNumber = sequenceNumber;
+ this._exchangeChannel = exchangeChannel;
+ }
+
+ /**
+ * Returns the sequence number that will be / has been used for method invocation.
+ *
+ * @return the sequence number that will be / has been used for method invocation.
+ */
+ public int getSequenceNumber()
+ {
+ return _sequenceNumber;
+ }
+
+ /**
+ * Returns the exchange channel that will be used between event source and event listener for synchronous
+ * communication.
+ *
+ * @return the exchange channel that will be used for synchronous communication.
+ */
+ public BlockingQueue<InvocationResult> getExchangeChannel()
+ {
+ return _exchangeChannel;
+ }
+} \ No newline at end of file
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
new file mode 100644
index 0000000000..657d7e6210
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/JmxService.java
@@ -0,0 +1,410 @@
+/*
+ *
+ * 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.domain.model;
+
+import java.lang.management.ManagementFactory;
+import java.util.Set;
+import java.util.UUID;
+
+import javax.management.MBeanException;
+import javax.management.MBeanServer;
+import javax.management.MalformedObjectNameException;
+import javax.management.ObjectName;
+
+import org.apache.qpid.management.Messages;
+import org.apache.qpid.management.Names;
+import org.apache.qpid.management.domain.model.QpidClass.QManManagedObject;
+import org.apache.qpid.management.domain.model.QpidEvent.QManManagedEvent;
+import org.apache.qpid.management.domain.model.type.Binary;
+import org.apache.qpid.management.domain.services.QMan;
+import org.apache.qpid.transport.util.Logger;
+
+/**
+ * A simple facade used to perform operations on Mbean server.
+ */
+public class JmxService
+{
+ private final static Logger LOGGER = Logger.get(JmxService.class);
+ MBeanServer _mxServer = ManagementFactory.getPlatformMBeanServer();
+
+ /**
+ * Registers QMan with the MBeanServer.
+ * After that QMan management interface will be JMX-exposed.
+ *
+ * @param qman QMan
+ * @throws MBeanException when some error occurs during registration.
+ */
+ public void registerQManService(QMan qman) throws MBeanException
+ {
+ if (!_mxServer.isRegistered(Names.QMAN_OBJECT_NAME))
+ {
+ try {
+ _mxServer.registerMBean(qman, Names.QMAN_OBJECT_NAME);
+ } catch (Exception exception) {
+ throw new MBeanException(exception);
+ }
+ }
+ }
+
+ /**
+ * Registers an event instance with MBean server.
+ *
+ * @param eventInstance the mben event instance
+ * @param brokerId the broker identifier.
+ * @param packageName the package name.
+ * @param eventClassName the event class name.
+ * @return the object name used for registration.
+ */
+ ObjectName registerEventInstance(
+ QManManagedEvent eventInstance,
+ UUID brokerId,
+ String packageName,
+ String eventClassName)
+ {
+ ObjectName name = createEventName(brokerId, packageName, eventClassName);
+ if (!_mxServer.isRegistered(name))
+ {
+ try
+ {
+ _mxServer.registerMBean(eventInstance, name);
+
+ LOGGER.debug(
+ Messages.QMAN_200010_EVENT_MBEAN_REGISTERED,
+ brokerId,
+ packageName,
+ eventClassName,
+ name);
+ } catch (Exception exception)
+ {
+ throw new RuntimeException(exception);
+ }
+ }
+ return name;
+}
+
+ /**
+ * Registers a pre-existing object instance as an MBean with the MBean
+ * server.
+ *
+ * @param instance the object instance.
+ * @param brokerId the broker identifier.
+ * @param packageName the name of the package containing this instance.
+ * @param className the name of the owner class of this instance.
+ * @param objectId the object instance identifier.
+ * @return the object name used for registration.
+ */
+ ObjectName registerObjectInstance(
+ QManManagedObject instance,
+ UUID brokerId,
+ String packageName,
+ String className,
+ Binary objectId)
+ {
+ ObjectName name = createObjectName(brokerId, packageName, className, objectId);
+ if (!_mxServer.isRegistered(name))
+ {
+ try
+ {
+ _mxServer.registerMBean(instance, name);
+
+ LOGGER.debug(
+ Messages.QMAN_200011_OBJECT_MBEAN_REGISTERED,
+ brokerId,
+ packageName,
+ className,
+ objectId,
+ name);
+ } catch (Exception exception)
+ {
+ throw new RuntimeException(exception);
+ }
+ }
+ return name;
+ }
+
+ /**
+ * Removes / unregisters a managed object instance from the MBean Server.
+ *
+ * @param brokerId the broker identifier.
+ * @param packageName the name of the package containing this instance.
+ * @param className the name of the owner class of this instance.
+ * @param objectId the object instance identifier.
+ * @return obejctName the obejct name used for deregistration.
+ */
+ ObjectName unregisterObjectInstance(
+ UUID brokerId,
+ String packageName,
+ String className,
+ Binary objectId)
+ {
+ ObjectName name = createObjectName(brokerId, packageName, className, objectId);
+ if (_mxServer.isRegistered(name))
+ {
+ try
+ {
+ _mxServer.unregisterMBean(name);
+
+ LOGGER.debug(
+ Messages.QMAN_200012_OBJECT_MBEAN_UNREGISTERED,
+ brokerId,
+ packageName,
+ className,
+ objectId,
+ name);
+ } catch (Exception exception)
+ {
+ LOGGER.error(exception,Messages.QMAN_100013_MBEAN_REGISTRATION_FAILURE,name);
+ }
+ }
+ return name;
+ }
+
+ /**
+ * Removes (unregister) all events from MBean Server.
+ */
+ void unregisterEvents()
+ {
+ for (ObjectName name : getEventMBeans())
+ {
+ try
+ {
+ _mxServer.unregisterMBean(name);
+ } catch(Exception ignore)
+ {
+ }
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ Set<ObjectName> getEventMBeans()
+ {
+ return _mxServer.queryNames(createEventSearchName(),null);
+ }
+
+ /**
+ * Removes (unregister) all object instances from MBean Server.
+ */
+ @SuppressWarnings("unchecked")
+ void unregisterObjectInstances()
+ {
+ Set<ObjectName> names = _mxServer.queryNames(createObjectInstanceSearchName(),null);
+ for (ObjectName name : names)
+ {
+ try
+ {
+ _mxServer.unregisterMBean(name);
+ } catch(Exception ignore)
+ {
+ }
+ }
+ }
+
+ /**
+ * Factory method for ObjectNames.
+ *
+ * @param brokerId the broker identifier.
+ * @param packageName the name of the package containing this instance.
+ * @param className the name of the owner class of this instance.
+ * @param objectId the object instance identifier.
+ * @return the object name built according to the given parameters.
+ */
+ private ObjectName createObjectName(UUID brokerId, String packageName, String className, Binary objectId)
+ {
+ String asString = new StringBuilder()
+ .append(Names.DOMAIN_NAME)
+ .append(':')
+ .append(Names.BROKER_ID)
+ .append('=')
+ .append(brokerId)
+ .append(",type=Object,")
+ .append(Names.PACKAGE)
+ .append('=')
+ .append(packageName)
+ .append(',')
+ .append(Names.CLASS)
+ .append('=')
+ .append(className)
+ .append(',')
+ .append(Names.OBJECT_ID)
+ .append('=')
+ .append(objectId)
+ .toString();
+ try
+ {
+ return new ObjectName(asString);
+ } catch (MalformedObjectNameException exception)
+ {
+ throw new RuntimeException(exception);
+ }
+ }
+
+ /**
+ * Creates an object name that will be used for searching all registered events.
+ *
+ * @return the object name that will be used for searching all registered events.
+ */
+ ObjectName createEventSearchName()
+ {
+ String asString = new StringBuilder()
+ .append(Names.DOMAIN_NAME)
+ .append(':')
+ .append('*')
+ .append(",type=Event")
+ .toString();
+ try
+ {
+ return new ObjectName(asString);
+ } catch (MalformedObjectNameException exception)
+ {
+ throw new RuntimeException(exception);
+ }
+ }
+
+ /**
+ * Creates an object name that will be used for searching all registered events.
+ *
+ * @return the object name that will be used for searching all registered events.
+ */
+ ObjectName createClassDefinitionSearchName()
+ {
+ String asString = new StringBuilder()
+ .append(Names.DOMAIN_NAME)
+ .append(":Category=Schema,*")
+ .toString();
+ try
+ {
+ return new ObjectName(asString);
+ } catch (MalformedObjectNameException exception)
+ {
+ throw new RuntimeException(exception);
+ }
+ }
+
+ /**
+ * Creates an object name that will be used for searching all registered object instances.
+ *
+ * @return the object name that will be used for searching all registered object instances.
+ */
+ private ObjectName createObjectInstanceSearchName()
+ {
+ String asString = new StringBuilder()
+ .append(Names.DOMAIN_NAME)
+ .append(':')
+ .append('*')
+ .append(",type=Object")
+ .toString();
+ try
+ {
+ return new ObjectName(asString);
+ } catch (MalformedObjectNameException exception)
+ {
+ throw new RuntimeException(exception);
+ }
+ }
+
+ /**
+ * Factory method for ObjectNames.
+ *
+ * @param brokerId the broker identifier.
+ * @param packageName the name of the package containing this instance.
+ * @param className the name of the owner class of this instance.
+ * @return the object name built according to the given parameters.
+ */
+ private ObjectName createEventName(UUID brokerId, String packageName, String className)
+ {
+ String asString = new StringBuilder()
+ .append(Names.DOMAIN_NAME)
+ .append(':')
+ .append(Names.BROKER_ID)
+ .append('=')
+ .append(brokerId)
+ .append(",type=Event,")
+ .append(Names.PACKAGE)
+ .append('=')
+ .append(packageName)
+ .append(',')
+ .append(Names.CLASS)
+ .append('=')
+ .append(className)
+ .append(',')
+ .append(Names.OBJECT_ID)
+ .append('=')
+ .append(UUID.randomUUID())
+ .toString();
+ try
+ {
+ return new ObjectName(asString);
+ } catch (MalformedObjectNameException exception)
+ {
+ throw new RuntimeException(exception);
+ }
+ }
+
+ ObjectName createEntityDefinitionName(String packageName, String className, String type)
+ {
+ String asString = new StringBuilder()
+ .append(Names.DOMAIN_NAME)
+ .append(':')
+ .append("Category=Schema,Type=")
+ .append(type)
+ .append(",package=")
+ .append(packageName)
+ .append(",name=")
+ .append(className)
+ .toString();
+ try
+ {
+ return new ObjectName(asString);
+ } catch (MalformedObjectNameException exception)
+ {
+ throw new RuntimeException(exception);
+ }
+ }
+
+ public void registerEntityDefinition(ObjectName name, QpidEntity entity,String packageName, String className)
+ {
+ try
+ {
+ if (!_mxServer.isRegistered(name))
+ _mxServer.registerMBean(entity, name);
+ _mxServer.addNotificationListener(name, Names.QMAN_OBJECT_NAME, null, null);
+ } catch(Exception exception)
+ {
+ throw new RuntimeException(exception);
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ public void unregisterClassDefinitions()
+ {
+ Set<ObjectName> names = _mxServer.queryNames(createClassDefinitionSearchName(),null);
+ for (ObjectName name : names)
+ {
+ try
+ {
+ _mxServer.unregisterMBean(name);
+ } catch(Exception ignore)
+ {
+ }
+ }
+
+ }
+}
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/MissingFeatureAttributesException.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/MissingFeatureAttributesException.java
new file mode 100644
index 0000000000..160054059b
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/MissingFeatureAttributesException.java
@@ -0,0 +1,35 @@
+/*
+ *
+ * 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.domain.model;
+
+import java.util.List;
+
+import org.apache.qpid.management.domain.model.QpidFeatureBuilder.Attribute;
+
+public class MissingFeatureAttributesException extends UnableToBuildFeatureException
+{
+ private static final long serialVersionUID = 671471705085787235L;
+
+ public MissingFeatureAttributesException(List<Attribute> missingAttributeList)
+ {
+ super(String.valueOf(missingAttributeList));
+ }
+}
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidArgument.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidArgument.java
new file mode 100644
index 0000000000..e126fcb8f5
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidArgument.java
@@ -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.
+ *
+ */
+package org.apache.qpid.management.domain.model;
+
+import org.apache.qpid.management.Messages;
+import org.apache.qpid.transport.codec.Encoder;
+import org.apache.qpid.transport.util.Logger;
+
+/**
+ * An argument is the formal definition of a parameter belonging to a specific method / operation.
+ */
+class QpidArgument extends QpidProperty
+{
+ private final static Logger LOGGER = Logger.get(QpidArgument.class);
+
+ private Object _defaultValue;
+
+ private Direction _direction;
+
+ /**
+ * Sets the direction of this argument.
+ *
+ * @param the direction of this argument.
+ */
+ public void setDirection(String code)
+ {
+ this._direction = Direction.valueOf(code);
+ }
+
+ /**
+ * Returns the direction of this argument.
+ *
+ * @return the direction of this argument.
+ */
+ public Direction getDirection()
+ {
+ return _direction;
+ }
+
+ /**
+ * Sets the default value of this argument.
+ *
+ * @param defaultValue the default value of this argument.
+ */
+ public void setDefaultValue(Object defaultValue)
+ {
+ this._defaultValue = defaultValue;
+ }
+
+ /**
+ * Returns the default value of this argument.
+ *
+ * @return the default value of this argument.
+ */
+ public Object getDefaultValue()
+ {
+ return _defaultValue;
+ }
+
+ /**
+ * Returns true if this is an Input argument.
+ *
+ * @return true if this is an Input argument.
+ */
+ public boolean isInput()
+ {
+ return _direction != Direction.O;
+ }
+
+ @Override
+ public String toString ()
+ {
+ return new StringBuilder()
+ .append(getJavaType().getName())
+ .append(' ')
+ .append(_name)
+ .append("(")
+ .append(_direction)
+ .append(")")
+ .toString();
+ }
+
+ /**
+ * Encodes the given value according to this argument type & definition.
+ *
+ * @param value the value to be encoded.
+ * @param encoder the encoder.
+ */
+ public void encode(Object value,Encoder encoder)
+ {
+ _type.encode(value, encoder);
+ LOGGER.debug(Messages.QMAN_200013_ARGUMENT_VALUE_ENCODED,value,_name,_type);
+ }
+
+ /**
+ * Decodes the value for this argument according to its type & definition.
+ *
+ * @param decoder the decoder
+ * @return the decoded value of this argument.
+ */
+ public Object decode(org.apache.qpid.transport.codec.Decoder decoder)
+ {
+ return _type.decode(decoder);
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidAttribute.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidAttribute.java
new file mode 100644
index 0000000000..6712a14075
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidAttribute.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.domain.model;
+
+import org.apache.qpid.management.Messages;
+import org.apache.qpid.management.domain.model.type.Type;
+import org.apache.qpid.transport.codec.Decoder;
+import org.apache.qpid.transport.util.Logger;
+
+/**
+ * Layer supertype for qpid properties and statistics.
+ *
+ * @author Andrea Gazzarini
+ */
+class QpidAttribute extends QpidFeature
+{
+ private final static Logger LOGGER = Logger.get(QpidAttribute.class);
+
+ /** feature type */
+ protected Type _type;
+
+ /** feature unit */
+ protected String _unit;
+
+ /**
+ * Returns the units used for numeric values (i.e. seconds, bytes, etc.)
+ *
+ * @return the units used for numeric values (i.e. seconds, bytes, etc.)
+ */
+ String getUnit ()
+ {
+ return _unit;
+ }
+
+ /**
+ * Sets the unit for this property.
+ *
+ * @param unit the unit of this property.
+ */
+ void setUnit (String unit)
+ {
+ this._unit = unit;
+ }
+
+ /**
+ * Returns the java type (class) of this feature.
+ *
+ * @return the java type (class) of this feature.
+ */
+ Class<?> getJavaType ()
+ {
+ return _type.getJavaType();
+ }
+
+ /**
+ * Sets the type of this feature.
+ *
+ * @param type the type of this feature.
+ */
+ void setType (Type type)
+ {
+ this._type = type;
+ }
+
+ /**
+ * Gets the value of this feature according to its type definition.
+ *
+ * @param decoder the decoder used to extract the value.
+ * @return the value of this feature according to its type definition
+ */
+ Object decodeValue(Decoder decoder)
+ {
+ try {
+ return _type.decode(decoder);
+ } catch(RuntimeException exception)
+ {
+ LOGGER.error(exception,Messages.QMAN_100014_ATTRIBUTE_DECODING_FAILURE,this);
+ throw exception;
+ }
+ }
+
+ @Override
+ public String toString ()
+ {
+ return super.toString()+",type="+_type;
+ }
+}
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidClass.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidClass.java
new file mode 100644
index 0000000000..667e600668
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidClass.java
@@ -0,0 +1,833 @@
+/*
+ *
+ * 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.domain.model;
+
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+import java.util.Map.Entry;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.SynchronousQueue;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+
+import javax.management.Attribute;
+import javax.management.AttributeList;
+import javax.management.AttributeNotFoundException;
+import javax.management.InvalidAttributeValueException;
+import javax.management.MBeanAttributeInfo;
+import javax.management.MBeanException;
+import javax.management.MBeanInfo;
+import javax.management.MBeanOperationInfo;
+import javax.management.MBeanRegistration;
+import javax.management.MBeanServer;
+import javax.management.ObjectName;
+import javax.management.ReflectionException;
+import javax.management.RuntimeOperationsException;
+
+import org.apache.qpid.management.Messages;
+import org.apache.qpid.management.Names;
+import org.apache.qpid.management.domain.handler.impl.IMethodInvocationListener;
+import org.apache.qpid.management.domain.handler.impl.InvocationResult;
+import org.apache.qpid.management.domain.handler.impl.MethodOrEventDataTransferObject;
+import org.apache.qpid.management.domain.model.type.Binary;
+import org.apache.qpid.management.domain.services.SequenceNumberGenerator;
+import org.apache.qpid.management.jmx.EntityLifecycleNotification;
+import org.apache.qpid.management.jmx.OperationHasBeenInvokedNotification;
+import org.apache.qpid.transport.codec.BBDecoder;
+import org.apache.qpid.transport.util.Logger;
+
+/**
+ * Qpid Class definition.
+ * A type definition for a manageable object.
+ * This class is also responsible to manage incoming obejct instance data (configuration & instrumentation).
+ * How can we handle data before schema is injected into this class? simply we must retain that data in raw format.
+ * This class has 3 states :
+ * 1) first state is when schema is not yet injected. In this case the incoming object data is retained as is (in raw format)
+ * and a schema request is sent;
+ * 2) second state is when schema has been requested but not yet injected. The incoming object data is still retained as is
+ * (in raw format)
+ * 3) third state is when schema is injected. Each injection of data will result in an update / create / delete of
+ * the corresponding object instance. In addition, the first time the state change, the old retained raw data is cnverted in
+ * object instance(s).
+ */
+class QpidClass extends QpidEntity implements QpidClassMBean
+{
+ /**
+ * State interface for this class definition.
+ * Each state is responsible to handle the injection of the data and / or schema.
+ *
+ * @author Andrea Gazzarini
+ */
+ interface State
+ {
+ /**
+ * Adds configuration data for the object instance associated to the given object identifier.
+ *
+ * @param objectId the object identifier.
+ * @param rawData the raw configuration data.
+ */
+ void addInstrumentationData (Binary objectId, byte[] rawData);
+
+ /**
+ * Adds instrumentation data for the object instance associated to the given object identifier.
+ *
+ * @param objectId the object identifier.
+ * @param rawData the raw instrumentation data.
+ */
+ void addConfigurationData (Binary objectId, byte[] rawData);
+
+ /**
+ * Inject the schema into this class definition.
+ *
+ * @param propertyDefinitions
+ * @param statisticDefinitions
+ * @param methodDefinitions
+ * @throws UnableToBuildFeatureException when it's not possibile to parse schema and build the class definition.
+ */
+ public void setSchema (
+ List<Map<String, Object>> propertyDefinitions,
+ List<Map<String, Object>> statisticDefinitions,
+ List<MethodOrEventDataTransferObject> methodDefinitions) throws UnableToBuildFeatureException;
+ };
+
+ /**
+ * This is the initial state of every qpid class.
+ * The class definition instance is created but its schema has not been injected.
+ * Incoming configuration & instrumentation data will be stored in raw format because we don't know how to
+ * parse it until the schema arrives.
+ * In addition, this state is responsible (when data arrives) to request its schema.
+ */
+ final State _schemaNotRequested = new State() {
+
+ /**
+ * Stores the incoming data in raw format and request the schema for this class.
+ * After that a transition to the next state is made.
+ *
+ * @param objectId the object instance identifier.
+ * @param rawData incoming configuration data.
+ */
+ public synchronized void addConfigurationData (Binary objectId, byte[] rawData)
+ {
+ try
+ {
+ requestSchema();
+ _state = _schemaRequestedButNotYetInjected;
+ } catch (Exception exception)
+ {
+ _logger.error(
+ exception,
+ Messages.QMAN_100015_UNABLE_TO_SEND_SCHEMA_REQUEST,
+ _parent.getName(),
+ _name);
+ } finally {
+ QManManagedObject instance = getObjectInstance(objectId,false);
+ instance._rawConfigurationData.add(rawData);
+ }
+ }
+
+ /**
+ * Stores the incoming data in raw format and request the schema for this class.
+ * After that a transition to the next state is made.
+ *
+ * @param objectId the object instance identifier.
+ * @param rawData incoming instrumentation data.
+ */
+ public synchronized void addInstrumentationData (Binary objectId, byte[] rawData)
+ {
+ try
+ {
+ requestSchema();
+ _state = _schemaRequestedButNotYetInjected;
+ } catch (Exception e)
+ {
+ _logger.error(
+ Messages.QMAN_100015_UNABLE_TO_SEND_SCHEMA_REQUEST,
+ _parent.getName(),
+ _name);
+ } finally {
+ QManManagedObject instance = getObjectInstance(objectId,false);
+ instance._rawConfigurationData.add(rawData);
+ }
+ }
+
+ /**
+ * This method only throws an illegal state exception because when a schema arrives
+ * this state is no longer valid.
+ */
+ public void setSchema (
+ List<Map<String, Object>> propertyDefinitions,
+ List<Map<String, Object>> statisticDefinitions,
+ List<MethodOrEventDataTransferObject> methodDefinitions) throws UnableToBuildFeatureException
+ {
+ throw new IllegalStateException("When a schema arrives it's not possible for this class to be in this state.");
+ }
+ };
+
+ /**
+ * This is the first state of this class definition : the schema is not yet injected so each injection of object data will be
+ * retained in raw format.
+ */
+ final State _schemaRequestedButNotYetInjected = new State()
+ {
+ /**
+ * Stores the incoming data in raw format.
+ *
+ * @param objectId the object instance identifier.
+ * @param rawData incoming configuration data.
+ */
+ public void addConfigurationData (Binary objectId, byte[] rawData)
+ {
+ QManManagedObject instance = getObjectInstance(objectId,false);
+ instance._rawConfigurationData.add(rawData);
+ }
+
+ /**
+ * Stores the incoming data in raw format.
+ *
+ * @param objectId the object instance identifier.
+ * @param rawData incoming instrumentation data.
+ */
+ public void addInstrumentationData (Binary objectId, byte[] rawData)
+ {
+ QManManagedObject instance = getObjectInstance(objectId,false);
+ instance._rawInstrumentationData.add(rawData);
+ }
+
+ /**
+ * When a schema is injected into this defintiion the following should happen :
+ * 1) the incoming schema is parsed and the class definition is built;
+ * 2) the retained raw data is converted into object instance(s)
+ * 3) the internal state of this class changes;
+ *
+ * If someting is wrong during that process the schema is not built and the state don't change.
+ */
+ public synchronized void setSchema (
+ List<Map<String, Object>> propertyDefinitions,
+ List<Map<String, Object>> statisticDefinitions,
+ List<MethodOrEventDataTransferObject> methodDefinitions) throws UnableToBuildFeatureException
+ {
+
+ MBeanAttributeInfo [] attributesMetadata = new MBeanAttributeInfo[propertyDefinitions.size()+statisticDefinitions.size()];
+ MBeanOperationInfo [] operationsMetadata = new MBeanOperationInfo[methodDefinitions.size()];
+
+ buildAttributes(propertyDefinitions,statisticDefinitions,attributesMetadata);
+ buildMethods(methodDefinitions,operationsMetadata);
+
+ _metadata = new MBeanInfo(_name,_name,attributesMetadata,null,operationsMetadata,null);
+
+ EntityLifecycleNotification notification = new EntityLifecycleNotification(
+ EntityLifecycleNotification.SCHEMA_INJECTED_NOTIFICATION_TYPE,
+ _parent.getName(),
+ _name,
+ Names.CLASS,
+ _objectName);
+
+ sendNotification(notification);
+
+ // Converting stored object instances into JMX MBean and removing raw instance data.
+ for (Entry<Binary, QManManagedObject> instanceEntry : _objectInstances.entrySet())
+ {
+ Binary objectId = instanceEntry.getKey();
+ QManManagedObject instance = instanceEntry.getValue();
+
+ for (Iterator<byte[]> iterator = instance._rawInstrumentationData.iterator(); iterator.hasNext();)
+ {
+ updateInstanceWithInstrumentationData(instance,iterator.next());
+ iterator.remove();
+ }
+
+ for (Iterator<byte[]> iterator = instance._rawConfigurationData.iterator(); iterator.hasNext();)
+ {
+ updateInstanceWithConfigurationData(instance, iterator.next());
+ iterator.remove();
+ }
+
+ registerMBean(instance,_parent.getOwnerId(),_parent.getName(),_name,objectId);
+ }
+ _state = _schemaInjected;
+
+ }
+ };
+
+ /**
+ * After a schema is built into this definition this is the current state of the class.
+ */
+ final State _schemaInjected = new State()
+ {
+ /**
+ * Updates the configuration state of the object instance associates with the given object identifier.
+ *
+ * @param objectId the object identifier.
+ * @param rawData the configuration data (raw format).
+ */
+ public void addConfigurationData (Binary objectId, byte[] rawData)
+ {
+ QManManagedObject instance = getObjectInstance(objectId,true);
+ updateInstanceWithConfigurationData(instance, rawData);
+ }
+
+ /**
+ * Updates the instrumentation state of the object instance associates with the given object identifier.
+ *
+ * @param objectId the object identifier.
+ * @param rawData the instrumentation data (raw format).
+ */
+ public void addInstrumentationData (Binary objectId, byte[] rawData)
+ {
+ QManManagedObject instance = getObjectInstance(objectId,true);
+ updateInstanceWithInstrumentationData(instance, rawData);
+ }
+
+ /**
+ * Never called when the class definition has this state.
+ */
+ public void setSchema (
+ List<Map<String, Object>> propertyDefinitions,
+ List<Map<String, Object>> statisticDefinitions,
+ List<MethodOrEventDataTransferObject> methodDefinitions) throws UnableToBuildFeatureException
+ {
+ throw new IllegalStateException("When a schema arrives it's not possible for this class to be in this state.");
+ }
+ };
+
+ /**
+ * MBean used for representing remote broker object instances.
+ * This is the core component of the QMan domain model
+ */
+ class QManManagedObject extends QManManagedEntity implements MBeanRegistration
+ {
+ private Binary _objectId;
+
+ // Arrays used for storing raw data before this mbean is registered to mbean server.
+ List<byte[]> _rawInstrumentationData = new ArrayList<byte[]>();
+ List<byte[]> _rawConfigurationData = new ArrayList<byte[]>();
+
+ /**
+ * Builds a new managed object with the given object identifier.
+ *
+ * @param objectId the object identifier.
+ */
+ QManManagedObject(Binary objectId)
+ {
+ this._objectId = objectId;
+ }
+
+ /**
+ * Returns the value of the given attribute.s
+ *
+ * @throws AttributeNotFoundException when no attribute is found with the given name.
+ */
+ public Object getAttribute (String attributeName) throws AttributeNotFoundException, MBeanException, ReflectionException
+ {
+ if (attributeName == null)
+ {
+ throw new RuntimeOperationsException(new IllegalArgumentException("attribute name must not be null"));
+ }
+
+ if (_properties.containsKey(attributeName) || _statistics.containsKey(attributeName))
+ {
+ return _attributes.get(attributeName);
+ } else
+ {
+ throw new AttributeNotFoundException(attributeName);
+ }
+ }
+
+ /**
+ * Executes an operation on this object instance.
+ *
+ * @param actionName the name of the method.
+ * @param params the method parameters
+ * @param signature the method signature.
+ */
+ public Object invoke (String actionName, Object[] params, String[] signature) throws MBeanException,ReflectionException
+ {
+ OperationHasBeenInvokedNotification notification = null;
+ try
+ {
+ QpidMethod method = _methods.get(actionName);
+ if (method != null)
+ {
+ try
+ {
+ method.validate(params);
+ InvocationResult result = invokeMethod(_objectId, method, params);
+ notification = new OperationHasBeenInvokedNotification(actionName,params,signature,result);
+ return result;
+ } catch (Exception ex)
+ {
+ MBeanException exception = new MBeanException(ex);
+ notification = new OperationHasBeenInvokedNotification(actionName,params,signature,exception);
+ throw exception;
+ }
+ } else
+ {
+ ReflectionException exception = new ReflectionException(new NoSuchMethodException(actionName));
+ notification = new OperationHasBeenInvokedNotification(actionName,params,signature,exception);
+ throw exception;
+ }
+ } finally
+ {
+ sendNotification(notification);
+ }
+ }
+
+ /**
+ * Sets the value of the given attribute on this object instance.
+ *
+ * @param attribute contains the new value of the attribute.
+ * @throws AttributeNotFoundException when the given attribute is not found on this object instance.
+ * @throws InvalidAttributeValueException when the given value is violating one attribute invariant.
+ */
+ public void setAttribute (Attribute attribute) throws AttributeNotFoundException,
+ InvalidAttributeValueException, MBeanException, ReflectionException
+ {
+ QpidProperty property = _properties.get(attribute.getName());
+ try
+ {
+ property.validate(attribute.getValue());
+ } catch(ValidationException exception)
+ {
+ throw new InvalidAttributeValueException(exception.getMessage());
+ }
+ throw new RuntimeException("Not yet implemented.");
+ }
+
+ /**
+ * Sets the values of several attributes of this MBean.
+ *
+ * @param attributes a list of attributes: The identification of the attributes to be set and the values they are to be set to.
+ * @return The list of attributes that were set, with their new values.
+ */
+ public AttributeList setAttributes (AttributeList attributes)
+ {
+ throw new RuntimeException("Not yet implemented.");
+ }
+
+ /**
+ * MBean server callback after deregistration.
+ */
+ public void postDeregister ()
+ {
+ }
+
+ /**
+ * After the object is registered the raw data is set to null.
+ * This is done because we no longer need this data : it has already been
+ * injected into this object instance.
+ *
+ * @param registrationDone a flag indicating if the instance has been registered to mbean server.
+ */
+ public void postRegister (Boolean registrationDone)
+ {
+ if (registrationDone)
+ {
+ _rawConfigurationData = null;
+ _rawInstrumentationData = null;
+ }
+ }
+
+ /**
+ * MBean server callback before deregistration.
+ */
+ public void preDeregister () throws Exception
+ {
+ }
+
+ /**
+ * MBean server callback before registration.
+ */
+ public ObjectName preRegister (MBeanServer server, ObjectName name) throws Exception
+ {
+ return name;
+ }
+ }
+
+ Map<String, QpidProperty> _properties = new HashMap<String, QpidProperty>();
+ Map<String, QpidStatistic> _statistics = new HashMap<String, QpidStatistic>();
+ private Map<String, QpidMethod> _methods = new HashMap<String, QpidMethod>();
+
+ private List<QpidProperty> _schemaOrderedProperties = new ArrayList<QpidProperty>();
+ private List<QpidStatistic> _schemaOrderedStatistics= new ArrayList<QpidStatistic>();
+
+ private int _howManyPresenceBitMasks;
+ private BlockingQueue<InvocationResult> _exchangeChannelForMethodInvocations;
+ private final IMethodInvocationListener _methodInvocationListener;
+
+ Map<Binary, QManManagedObject> _objectInstances = new HashMap<Binary, QManManagedObject>();
+ State _state = _schemaNotRequested;;
+
+ private final static class Log
+ {
+ private final static Logger LOGGER = Logger.get(QpidClass.class);
+ final static void logMethodInvocationResult(InvocationResult result)
+ {
+ if (LOGGER.isDebugEnabled())
+ {
+ LOGGER.debug(String.valueOf(result));
+ }
+ }
+ }
+
+ /**
+ * Builds a new class with the given name and package as parent.
+ *
+ * @param className the name of the class.
+ * @param hash the class schema hash.
+ * @param parentPackage the parent of this class.
+ */
+ QpidClass(String className, Binary hash, QpidPackage parentPackage)
+ {
+ super(className,hash, parentPackage,Names.CLASS);
+ this._methodInvocationListener = _parent.getMethodInvocationListener();
+ this._exchangeChannelForMethodInvocations = new SynchronousQueue<InvocationResult>();
+ }
+
+ /**
+ * Adds the configuration data for the object instance associated to the given object identifier.
+ *
+ * @param objectId the object identifier.
+ * @param rawData the raw configuration data.
+ */
+ void addInstrumentationData (Binary objectId, byte[] rawData)
+ {
+ _logger.debug(
+ Messages.QMAN_200014_INCOMING_INSTRUMENTATION_DATA,
+ _parent.getOwnerId(),
+ _parent.getName(),
+ _name,
+ objectId);
+ _state.addInstrumentationData(objectId, rawData);
+ }
+
+ /**
+ * Adds the instrumentation data for the object instance associated to the given object identifier.
+ *
+ * @param objectId the object identifier.
+ * @param rawData the raw instrumentation data.
+ */
+ void addConfigurationData (Binary objectId, byte[] rawData)
+ {
+ _logger.debug(
+ Messages.QMAN_200015_INCOMING_CONFIGURATION_DATA,
+ _parent.getOwnerId(),
+ _parent.getName(),
+ _name,
+ objectId);
+ _state.addConfigurationData(objectId, rawData);
+ }
+
+ /**
+ * Sets the schema for this class definition.
+ * A schema is basically a metadata description of all properties, statistics, methods and events of this class.
+ *
+ * @param propertyDefinitions properties metadata.
+ * @param statisticDefinitions statistics metadata.
+ * @param methodDefinitions methods metadata.
+ * @throws UnableToBuildFeatureException when some error occurs while parsing the incoming schema.
+ */
+ void setSchema (
+ List<Map<String, Object>> propertyDefinitions,
+ List<Map<String, Object>> statisticDefinitions,
+ List<MethodOrEventDataTransferObject> methodDefinitions) throws UnableToBuildFeatureException
+ {
+ _logger.info(Messages.QMAN_000010_INCOMING_SCHEMA,_parent.getOwnerId(),_parent.getName(),_name);
+ _state.setSchema(propertyDefinitions, statisticDefinitions, methodDefinitions);
+ }
+
+ /**
+ * Internal method used for building attributes definitions.
+ *
+ * @param props the map contained in the properties schema.
+ * @param stats the map contained in the statistics schema.
+ * @param attributes the management metadata for attributes.
+ * @throws UnableToBuildFeatureException when it's not possibile to build one attribute definition.
+ */
+ void buildAttributes (
+ List<Map<String, Object>> props,
+ List<Map<String, Object>> stats,
+ MBeanAttributeInfo[] attributes) throws UnableToBuildFeatureException
+ {
+ int index = 0;
+ int howManyOptionalProperties = 0;
+
+ for (Map<String, Object> propertyDefinition : props)
+ {
+ QpidFeatureBuilder builder = QpidFeatureBuilder.createPropertyBuilder(propertyDefinition);
+ builder.build();
+
+ QpidProperty property = (QpidProperty) builder.getQpidFeature();
+
+ howManyOptionalProperties += (property.isOptional()) ? 1 : 0;
+
+ _properties.put(property.getName(),property);
+ _schemaOrderedProperties.add(property);
+ attributes[index++]=(MBeanAttributeInfo) builder.getManagementFeature();
+
+ _logger.debug(
+ Messages.QMAN_200016_PROPERTY_DEFINITION_HAS_BEEN_BUILT,
+ _parent.getName(),
+ _name,
+ property);
+ }
+
+ _howManyPresenceBitMasks = (int)Math.ceil((double)howManyOptionalProperties / 8);
+
+ _logger.debug(
+ Messages.QMAN_200018_OPTIONAL_PROPERTIES_INFO,
+ _parent.getOwnerId(),
+ _parent.getName(),
+ _name,
+ _howManyPresenceBitMasks);
+
+ for (Map<String, Object> statisticDefinition : stats)
+ {
+ QpidFeatureBuilder builder = QpidFeatureBuilder.createStatisticBuilder(statisticDefinition);
+ builder.build();
+ QpidStatistic statistic = (QpidStatistic) builder.getQpidFeature();
+
+ _statistics.put(statistic.getName(),statistic);
+ _schemaOrderedStatistics.add(statistic);
+ attributes[index++]=(MBeanAttributeInfo) builder.getManagementFeature();
+
+ _logger.debug(
+ Messages.QMAN_200017_STATISTIC_DEFINITION_HAS_BEEN_BUILT,
+ _parent.getName(),
+ _name,
+ statistic);
+ }
+ }
+
+ /**
+ * Returns the object instance associated to the given identifier.
+ * Note that if the identifier is not associated to any obejct instance, a new one will be created.
+ *
+ * @param objectId the object identifier.
+ * @param registration a flag indicating whenever the (new ) instance must be registered with MBean server.
+ * @return the object instance associated to the given identifier.
+ */
+ QManManagedObject getObjectInstance(Binary objectId, boolean registration)
+ {
+ QManManagedObject objectInstance = _objectInstances.get(objectId);
+ if (objectInstance == null)
+ {
+ objectInstance = new QManManagedObject(objectId);
+ _objectInstances.put(objectId, objectInstance);
+ if (registration)
+ {
+ registerMBean(objectInstance,_parent.getOwnerId(),_parent.getName(),_name,objectId);
+ }
+ }
+ return objectInstance;
+ }
+
+ /**
+ * Internal method used for building method defintiions.
+ *
+ * @param definitions the properties map contained in the incoming schema.
+ * @param operationsMetadata
+ * @throws UnableToBuildFeatureException when it's not possibile to build one or more definitions.
+ */
+ void buildMethods (List<MethodOrEventDataTransferObject> definitions, MBeanOperationInfo[] operationsMetadata) throws UnableToBuildFeatureException
+ {
+ int index = 0;
+ for (MethodOrEventDataTransferObject definition: definitions)
+ {
+ QpidFeatureBuilder builder = QpidFeatureBuilder.createMethodBuilder(definition);
+ builder.build();
+ operationsMetadata [index++]= (MBeanOperationInfo) builder.getManagementFeature();
+ QpidMethod method = (QpidMethod) builder.getQpidFeature();
+ _methods.put(method.getName(),method);
+ }
+ }
+
+ /**
+ * Header (opcode='M')
+ * ObjectId of target object (128 bits)
+ * Package name (str8)
+ * Class name (str8)
+ * Class hash (bin128)
+ * Method name (str8) [as defined in the schema]
+ * Now encode all input ("I") and i/o (IO) arguments in the order in which they are defined in the schema.
+ * (i.e. make one pass over the argument list and encode arguments that are either input or inptu/output).
+
+ * @param objectId
+ * @param method
+ * @param parameters
+ * @throws Exception
+ */
+ private InvocationResult invokeMethod(Binary objectId,QpidMethod method,Object [] parameters) throws Exception
+ {
+ try
+ {
+ _service.connect();
+
+ int sequenceNumber = SequenceNumberGenerator.getNextSequenceNumber();
+ _methodInvocationListener.operationIsGoingToBeInvoked(new InvocationEvent(this,sequenceNumber,_exchangeChannelForMethodInvocations));
+ _service.invoke(_parent.getName(), _name, _hash,objectId,parameters, method,sequenceNumber,objectId.getBankId(),objectId.getBrokerId());
+
+ InvocationResult result = _exchangeChannelForMethodInvocations.poll(5000,TimeUnit.MILLISECONDS);
+
+ if (result == null)
+ {
+ throw new TimeoutException();
+ }
+
+ Map<String, Object> output = method.decodeParameters(result.getOutputAndBidirectionalArgumentValues());
+ result.setOutputSection(output);
+
+ Log.logMethodInvocationResult(result);
+
+ if (result.isException())
+ {
+ result.createAndThrowException();
+ }
+ return result;
+ } finally
+ {
+ _service.close();
+ }
+ }
+
+ /**
+ * Updates the given obejct instance with the given incoming configuration data.
+ *
+ * @param instance the managed object instance.
+ * @param rawData the incoming configuration data which contains new values for instance properties.
+ */
+ void updateInstanceWithConfigurationData(QManManagedObject instance,byte [] rawData)
+ {
+ BBDecoder decoder = new BBDecoder();
+ decoder.init(ByteBuffer.wrap(rawData));
+
+ byte [] presenceBitMasks = decoder.readBytes(_howManyPresenceBitMasks);
+ for (QpidProperty property : _schemaOrderedProperties)
+ {
+ try {
+ Object value = property.decodeValue(decoder,presenceBitMasks);
+ instance.createOrReplaceAttributeValue(property.getName(),value);
+ } catch(Exception ignore) {
+ _logger.error(Messages.QMAN_100016_UNABLE_TO_DECODE_FEATURE_VALUE, _parent.getName(),_name,property.getName());
+ }
+ }
+ }
+
+ /**
+ * Updates the given object instance with the given incoming instrumentation data.
+ *
+ * @param instance the managed object instance.
+ * @param rawData the incoming instrumentation data which contains new values for instance properties.
+ */
+ void updateInstanceWithInstrumentationData(QManManagedObject instance,byte [] rawData)
+ {
+ BBDecoder decoder = new BBDecoder();
+ decoder.init(ByteBuffer.wrap(rawData));
+
+ for (QpidStatistic statistic : _schemaOrderedStatistics)
+ {
+ try {
+ Object value = statistic.decodeValue(decoder);
+ instance.createOrReplaceAttributeValue(statistic.getName(),value);
+ } catch(Exception ignore) {
+ _logger.error(Messages.QMAN_100016_UNABLE_TO_DECODE_FEATURE_VALUE, _parent.getName(),_name,statistic.getName());
+ }
+ }
+ }
+
+ @Override
+ public String toString ()
+ {
+ return new StringBuilder()
+ .append(_parent.getOwnerId())
+ .append("::")
+ .append(_parent.getName())
+ .append('.')
+ .append(_name)
+ .toString();
+ }
+
+ /**
+ * Removes the object instance associated to the given identifier.
+ *
+ * @param objectId the object identifier.
+ */
+ void removeObjectInstance (Binary objectId)
+ {
+ QManManagedObject toBeRemoved = _objectInstances.remove(objectId);
+ if (toBeRemoved != null)
+ {
+ ObjectName objectName = JMX_SERVICE.unregisterObjectInstance(_parent.getOwnerId(),_parent.getName(),_name,toBeRemoved._objectId);
+
+ EntityLifecycleNotification notification = new EntityLifecycleNotification(
+ EntityLifecycleNotification.INSTANCE_REMOVED_NOTIFICATION_TYPE,
+ _parent.getName(),
+ _name,
+ Names.CLASS,
+ objectName);
+
+ sendNotification(notification);
+ }
+ }
+
+ /**
+ * Deregisters all the object instances and release all previously acquired resources.
+ */
+ void releaseResources ()
+ {
+ _objectInstances.clear();
+ JMX_SERVICE.unregisterObjectInstances();
+ JMX_SERVICE.unregisterClassDefinitions();
+ _service.close();
+ }
+
+ /**
+ * Compose method used for registering mbean instance.
+ *
+ * @param instance the mbean instance.
+ * @param brokerId the broker identifier.
+ * @param packageName the package name.
+ * @param className the class name.
+ * @param objectId the object identifier.
+ */
+ private void registerMBean(
+ QManManagedObject instance,
+ UUID brokerId,
+ String packageName,
+ String className,
+ Binary objectId)
+ {
+ ObjectName objectName = JMX_SERVICE.registerObjectInstance(instance,_parent.getOwnerId(),_parent.getName(),_name,objectId);
+
+ EntityLifecycleNotification notification = new EntityLifecycleNotification(
+ EntityLifecycleNotification.INSTANCE_ADDED_NOTIFICATION_TYPE,
+ packageName,
+ className,
+ Names.CLASS,
+ objectName);
+
+ sendNotification(notification);
+ }
+}
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidClassMBean.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidClassMBean.java
new file mode 100644
index 0000000000..eeb4e0e2d8
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidClassMBean.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.management.domain.model;
+
+/**
+ * Management interface for Qpid entity class..
+ */
+public interface QpidClassMBean
+{
+ /**
+ * Retruns the name of the class.
+ *
+ * @return the name of the class.
+ */
+ String getName();
+
+ /**
+ * Returns the name of the package.
+ *
+ * @return the name of the package.
+ */
+ String getPackageName();
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidEntity.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidEntity.java
new file mode 100644
index 0000000000..ea0acb5fd1
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidEntity.java
@@ -0,0 +1,184 @@
+package org.apache.qpid.management.domain.model;
+/*
+ *
+ * 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 java.util.HashMap;
+import java.util.Map;
+
+import javax.management.Attribute;
+import javax.management.AttributeList;
+import javax.management.DynamicMBean;
+import javax.management.MBeanInfo;
+import javax.management.NotificationBroadcasterSupport;
+import javax.management.ObjectName;
+import javax.management.RuntimeOperationsException;
+
+import org.apache.qpid.management.Messages;
+import org.apache.qpid.management.Names;
+import org.apache.qpid.management.domain.model.type.Binary;
+import org.apache.qpid.management.domain.services.QpidService;
+import org.apache.qpid.management.jmx.EntityLifecycleNotification;
+import org.apache.qpid.transport.util.Logger;
+
+/**
+ * Layer supertype for QMan entities.
+ */
+public abstract class QpidEntity extends NotificationBroadcasterSupport
+{
+ /**
+ * Layer supertype for QMan managed bean entities.
+ */
+ abstract class QManManagedEntity implements DynamicMBean
+ {
+ // After mbean is registered with the MBean server this collection holds the mbean attribute values.
+ Map<String,Object> _attributes = new HashMap<String, Object>();
+
+ /**
+ * Creates or replace the given attribute.
+ * Note that this is not part of the management interface of this object instance and therefore will be accessible only
+ * from within this class.
+ * It is used to update directly the object attributes bypassing jmx interface.
+ *
+ * @param attributeName the name of the attribute.
+ * @param property newValue the new value of the attribute.
+ */
+ void createOrReplaceAttributeValue(String attributeName, Object newValue)
+ {
+ _attributes.put(attributeName, newValue);
+ }
+
+ /**
+ * Get the values of several attributes of the Dynamic MBean.
+ *
+ * @param attributes A list of the attributes to be retrieved.
+ *
+ * @return The list of attributes retrieved.
+ */
+ public AttributeList getAttributes (String[] attributes)
+ {
+ if (attributes == null)
+ {
+ throw new RuntimeOperationsException(new IllegalArgumentException("Attributes array must not be null"));
+ }
+
+ AttributeList result = new AttributeList(attributes.length);
+ for (int i = 0; i < attributes.length; i++)
+ {
+ String attributeName = attributes[i];
+ try
+ {
+ result.add(new Attribute(attributeName,getAttribute(attributeName)));
+ } catch(Exception exception)
+ {
+ // Already logged.
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Returns metadata for this object instance.
+ */
+ // Developer Note : note that this metadata is a member of the outer class definition : in that way we create
+ // that metadata only once and then it will be shared between all object instances (it's a readonly object)
+ public MBeanInfo getMBeanInfo ()
+ {
+ return _metadata;
+ }
+ };
+
+ final Logger _logger = Logger.get(getClass());
+ final static JmxService JMX_SERVICE = new JmxService();
+
+ final String _name;
+ final Binary _hash;
+
+ final QpidPackage _parent;
+ MBeanInfo _metadata;
+ final QpidService _service;
+
+ protected ObjectName _objectName;
+
+ private final String _type;
+
+ /**
+ * Builds a new class with the given name and package as parent.
+ *
+ * @param className the name of the class.
+ * @param hash the class schema hash.
+ * @param parentPackage the parent of this class.
+ */
+ QpidEntity(String className, Binary hash, QpidPackage parentPackage,String type)
+ {
+ this._name = className;
+ this._parent = parentPackage;
+ this._hash = hash;
+ this._type = type;
+ this._service = new QpidService(_parent.getOwnerId());
+
+ _logger.debug(
+ Messages.QMAN_200020_ENTITY_DEFINITION_HAS_BEEN_BUILT,
+ _parent.getOwnerId(),
+ _parent.getName(),
+ _name);
+ }
+
+ public String getName()
+ {
+ return _name;
+ }
+
+ public String getPackageName()
+ {
+ return _parent.getName();
+ }
+
+ /**
+ * Internal method used to send a schema request for this entity.
+ *
+ * @throws Exception when the request cannot be sent.
+ */
+ void requestSchema() throws Exception
+ {
+
+ _objectName = JMX_SERVICE.createEntityDefinitionName(_parent.getName(), _name,_type);
+ JMX_SERVICE.registerEntityDefinition(_objectName,this,_parent.getName(),_name);
+
+ try
+ {
+ _service.connect();
+ _service.requestSchema(_parent.getName(), _name, _hash);
+ _service.sync();
+ } finally
+ {
+ _service.close();
+ }
+
+ EntityLifecycleNotification notification = new EntityLifecycleNotification(
+ EntityLifecycleNotification.SCHEMA_REQUESTED_NOTIFICATION_TYPE,
+ _parent.getName(),
+ _name,
+ Names.CLASS,
+ _objectName);
+ sendNotification(notification);
+ }
+}
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidEvent.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidEvent.java
new file mode 100644
index 0000000000..31d8d01fc9
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidEvent.java
@@ -0,0 +1,493 @@
+/*
+ *
+ * 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.domain.model;
+
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+
+import javax.management.Attribute;
+import javax.management.AttributeList;
+import javax.management.AttributeNotFoundException;
+import javax.management.InvalidAttributeValueException;
+import javax.management.MBeanAttributeInfo;
+import javax.management.MBeanException;
+import javax.management.MBeanInfo;
+import javax.management.ObjectName;
+import javax.management.ReflectionException;
+import javax.management.RuntimeOperationsException;
+
+import org.apache.qpid.management.Messages;
+import org.apache.qpid.management.Names;
+import org.apache.qpid.management.domain.model.type.Binary;
+import org.apache.qpid.management.jmx.EntityLifecycleNotification;
+import org.apache.qpid.transport.codec.BBDecoder;
+
+/**
+ * Qpid event definition.
+ */
+class QpidEvent extends QpidEntity implements QpidEventMBean
+{
+
+ /**
+ * State interface for this event definition.
+ * Each state is responsible to handle the injection of the data and / or schema.
+ */
+ interface State
+ {
+ /**
+ * Adds the given data for the object instance associated to the given object identifier.
+ *
+ * @param rawData the raw configuration data.
+ */
+ void addNewEventData (byte[] rawData, long currentTimestamp, int severity);
+
+ /**
+ * Inject the schema into this class definition.
+ *
+ * @param propertyDefinitions
+ * @param statisticDefinitions
+ * @param methodDefinitions
+ * @throws UnableToBuildFeatureException when it's not possibile to parse schema and build the class definition.
+ */
+ public void setSchema (List<Map<String, Object>> agumentDefinitions) throws UnableToBuildFeatureException;
+ };
+
+
+ /**
+ * This is the initial state of every qpid class.
+ * The class definition instance is created but its schema has not been injected.
+ * Incoming configuration & instrumentation data will be stored in raw format because we don't know how to
+ * parse it until the schema arrives.
+ * In addition, this state is responsible (when data arrives) to request its schema.
+ */
+ final State _schemaNotRequested = new State() {
+
+ /**
+ * Stores the incoming data in raw format and request the schema for this class.
+ * After that a transition to the next state is made.
+ *
+ * @param objectId the object instance identifier.
+ * @param rawData incoming configuration data.
+ */
+ public synchronized void addNewEventData (byte[] rawData, long currentTimestamp, int severity)
+ {
+ try
+ {
+ requestSchema();
+ _state = _schemaRequestedButNotYetInjected;
+ } catch (Exception exception)
+ {
+ _logger.error(
+ exception,
+ Messages.QMAN_100015_UNABLE_TO_SEND_SCHEMA_REQUEST,
+ _parent.getName(),
+ _name);
+ } finally {
+ createEventInstance(rawData,currentTimestamp,severity);
+ }
+ }
+
+ /**
+ * This method only throws an illegal state exception because when a schema arrives
+ * this state is no longer valid.
+ */
+ public void setSchema (List<Map<String, Object>> agumentDefinitions) throws UnableToBuildFeatureException
+ {
+ throw new IllegalStateException("When a schema arrives it's not possible for this event to be in this state.");
+ }
+ };
+
+ /**
+ * This is the first state of this class definition : the schema is not yet injected so each injection of object data will be
+ * retained in raw format.
+ */
+ final State _schemaRequestedButNotYetInjected = new State()
+ {
+ /**
+ * Stores the incoming data in raw format and request the schema for this class.
+ * After that a transition to the next state is made.
+ *
+ * @param objectId the object instance identifier.
+ * @param rawData incoming configuration data.
+ */
+ public synchronized void addNewEventData (byte[] rawData,long currentTimestamp, int severity)
+ {
+ createEventInstance(rawData,currentTimestamp, severity);
+ }
+
+ /**
+ * When a schema is injected into this defintiion the following should happen :
+ * 1) the incoming schema is parsed and the class definition is built;
+ * 2) the retained raw data is converted into object instance(s)
+ * 3) the internal state of this class changes;
+ *
+ * If someting is wrong during that process the schema is not built and the state don't change.
+ */
+ public synchronized void setSchema (List<Map<String, Object>> argumentDefinitions) throws UnableToBuildFeatureException
+ {
+ MBeanAttributeInfo [] attributesMetadata = new MBeanAttributeInfo[argumentDefinitions.size()+2];
+
+ buildArguments(argumentDefinitions, attributesMetadata);
+
+ _metadata = new MBeanInfo(_name,_name,attributesMetadata,null,null,null);
+
+ // Converting stored object instances into JMX MBean and removing raw instance data.
+ for (QManManagedEvent instance : _eventInstances)
+ {
+ updateEventInstanceWithData(instance);
+ registerEventInstance(instance,_parent.getOwnerId(),_parent.getName(),_name);
+ }
+ _state = _schemaInjected;
+
+ EntityLifecycleNotification notification = new EntityLifecycleNotification(
+ EntityLifecycleNotification.SCHEMA_INJECTED_NOTIFICATION_TYPE,
+ _parent.getName(),
+ _name,
+ Names.EVENT,
+ _objectName);
+
+ sendNotification(notification);
+ }
+ };
+
+ /**
+ * After a schema is built into this definition this is the current state of the class.
+ */
+ final State _schemaInjected = new State()
+ {
+ /**
+ * Updates the configuration state of the object instance associates with the given object identifier.
+ *
+ * @param objectId the object identifier.
+ * @param rawData the configuration data (raw format).
+ */
+ public void addNewEventData (byte[] rawData,long currentTimestamp, int severity)
+ {
+ QManManagedEvent instance = createEventInstance(rawData,currentTimestamp, severity);
+ updateEventInstanceWithData(instance);
+ registerEventInstance(instance,_parent.getOwnerId(),_parent.getName(),_name);
+ }
+
+ /**
+ * Never called when the class definition has this state.
+ */
+ public void setSchema (List<Map<String, Object>> agumentDefinitions) throws UnableToBuildFeatureException
+ {
+ // N.A. : Schema is already injected.
+ }
+ };
+
+ /**
+ * MBean used for representing remote broker object instances.
+ * This is the core component of the QMan domain model
+ *
+ * @author Andrea Gazzarini
+ */
+ class QManManagedEvent extends QManManagedEntity
+ {
+
+
+ // Arrays used for storing raw data before this mbean is registered to mbean server.
+ final byte[] _rawEventData;
+ final long _timestamp;
+ final int _severity;
+
+ /**
+ * Builds a new managed object with the given object identifier.
+ *
+ * @param objectId the object identifier.
+ */
+ private QManManagedEvent(byte [] data, long timestamp, int severity)
+ {
+ this._rawEventData = data;
+ this._timestamp = timestamp;
+ this._severity = severity;
+ _attributes.put(SEVERITY_ATTR_NAME, _severity);
+ _attributes.put(TIMESTAMP_ATTR_NAME, new Date(_timestamp));
+ }
+
+ /**
+ * Returns the value of the given attribute.s
+ *
+ * @throws AttributeNotFoundException when no attribute is found with the given name.
+ */
+ public Object getAttribute (String attributeName) throws AttributeNotFoundException, MBeanException, ReflectionException
+ {
+ if (attributeName == null)
+ {
+ throw new RuntimeOperationsException(new IllegalArgumentException("Attribute name must not be null."));
+ }
+
+ if (_arguments.containsKey(attributeName) || SEVERITY_ATTR_NAME.equals(attributeName) || TIMESTAMP_ATTR_NAME.equals(attributeName))
+ {
+ return _attributes.get(attributeName);
+ } else
+ {
+ throw new AttributeNotFoundException(attributeName);
+ }
+ }
+
+ /**
+ * Executes an operation on this object instance.
+ *
+ * @param actionName the name of the method.
+ * @param params the method parameters
+ * @param signature the method signature.
+ */
+ public Object invoke (String actionName, Object[] params, String[] signature) throws MBeanException,ReflectionException
+ {
+ throw new ReflectionException(new NoSuchMethodException(actionName));
+ }
+
+ /**
+ * Sets the value of the given attribute on this object instance.
+ *
+ * @param attribute contains the new value of the attribute.
+ * @throws AttributeNotFoundException when the given attribute is not found on this object instance.
+ * @throws InvalidAttributeValueException when the given value is violating one attribute invariant.
+ */
+ public void setAttribute (Attribute attribute) throws AttributeNotFoundException,
+ InvalidAttributeValueException, MBeanException, ReflectionException
+ {
+ throw new ReflectionException(new NoSuchMethodException());
+ }
+
+ /**
+ * Sets the values of several attributes of this MBean.
+ *
+ * @param attributes a list of attributes: The identification of the attributes to be set and the values they are to be set to.
+ * @return The list of attributes that were set, with their new values.
+ */
+ public AttributeList setAttributes (AttributeList attributes)
+ {
+ throw new RuntimeException();
+ }
+ }
+
+ final static String SEVERITY_ATTR_NAME = "Severity";
+ final static String TIMESTAMP_ATTR_NAME = "Date";
+
+ private List<QpidProperty> _schemaOrderedArguments = new ArrayList<QpidProperty>();
+
+ Map<String, QpidProperty> _arguments = new HashMap<String, QpidProperty>();
+ List<QManManagedEvent> _eventInstances = new LinkedList<QManManagedEvent>();
+ State _state = _schemaNotRequested;;
+
+ /**
+ * Builds a new class with the given name and package as parent.
+ *
+ * @param className the name of the class.
+ * @param hash the class schema hash.
+ * @param parentPackage the parent of this class.
+ */
+ QpidEvent(String eventClassName, Binary hash, QpidPackage parentPackage)
+ {
+ super(eventClassName,hash,parentPackage,Names.EVENT);
+ }
+
+ /**
+ * Adds the configuration data for the object instance associated to the given object identifier.
+ *
+ * @param objectId the object identifier.
+ * @param rawData the raw configuration data.
+ */
+ void addEventData (byte[] rawData, long currentTimestamp, int severity)
+ {
+ _logger.debug(
+ Messages.QMAN_200021_INCOMING_EVENT_DATA,
+ _parent.getOwnerId(),
+ _parent.getName(),
+ _name);
+ _state.addNewEventData(rawData, currentTimestamp, severity);
+ }
+
+ /**
+ * Sets the schema for this class definition.
+ * A schema is basically a metadata description of all properties, statistics, methods and events of this class.
+ *
+ * @param propertyDefinitions properties metadata.
+ * @param statisticDefinitions statistics metadata.
+ * @param methodDefinitions methods metadata.
+ * @throws UnableToBuildFeatureException when some error occurs while parsing the incoming schema.
+ */
+ void setSchema (List<Map<String, Object>> argumentDefinitions) throws UnableToBuildFeatureException
+ {
+ _logger.info(Messages.QMAN_000010_INCOMING_SCHEMA,_parent.getOwnerId(),_parent.getName(),_name);
+ _state.setSchema(argumentDefinitions);
+ }
+
+ /**
+ * Internal method used for building attributes definitions.
+ *
+ * @param props the map contained in the properties schema.
+ * @param stats the map contained in the statistics schema.
+ * @param attributes the management metadata for attributes.
+ * @throws UnableToBuildFeatureException when it's not possibile to build one attribute definition.
+ */
+ void buildArguments (
+ List<Map<String, Object>> arguments,MBeanAttributeInfo[] attributes) throws UnableToBuildFeatureException
+ {
+ int index = 0;
+
+ for (Map<String, Object> argumentDefinition : arguments)
+ {
+ // Force metadata attributes. It is needed because arguments are "similar" to properties but they
+ // aren't properties and then they haven't optional, index and access metadata attributes
+ // (mandatory for build a property definition).
+ argumentDefinition.put(QpidFeatureBuilder.Attribute.optional.name(),0);
+ argumentDefinition.put(QpidFeatureBuilder.Attribute.index.name(),1);
+ argumentDefinition.put(QpidFeatureBuilder.Attribute.access.name(),3);
+
+ QpidFeatureBuilder builder = QpidFeatureBuilder.createPropertyBuilder(argumentDefinition);
+ builder.build();
+
+ QpidProperty argument = (QpidProperty) builder.getQpidFeature();
+
+ _arguments.put(argument.getName(),argument);
+ _schemaOrderedArguments.add(argument);
+ attributes[index++]=(MBeanAttributeInfo) builder.getManagementFeature();
+
+ _logger.debug(
+ Messages.QMAN_200019_EVENT_ARGUMENT_DEFINITION_HAS_BEEN_BUILT,
+ _parent.getName(),
+ _name,
+ argument);
+ }
+
+ attributes[index++] = new MBeanAttributeInfo(
+ SEVERITY_ATTR_NAME,
+ Integer.class.getName(),
+ Messages.EVENT_SEVERITY_ATTRIBUTE_DESCRIPTION,
+ true,
+ false,
+ false);
+
+ attributes[index++] = new MBeanAttributeInfo(
+ TIMESTAMP_ATTR_NAME,
+ Date.class.getName(),
+ Messages.EVENT_TIMESTAMP_ATTRIBUTE_DESCRIPTION,
+ true,
+ false,
+ false);
+ }
+
+ /**
+ * Returns the object instance associated to the given identifier.
+ * Note that if the identifier is not associated to any obejct instance, a new one will be created.
+ *
+ * @param objectId the object identifier.
+ * @param registration a flag indicating whenever the (new ) instance must be registered with MBean server.
+ * @return the object instance associated to the given identifier.
+ */
+ QManManagedEvent createEventInstance(byte [] data, long timestamp, int severity)
+ {
+ QManManagedEvent eventInstance = new QManManagedEvent(data, timestamp, severity);
+ _eventInstances.add(eventInstance);
+ return eventInstance;
+ }
+
+ /**
+ * Updates the given obejct instance with the given incoming configuration data.
+ *
+ * @param instance the managed object instance.
+ * @param rawData the incoming configuration data which contains new values for instance properties.
+ */
+ void updateEventInstanceWithData(QManManagedEvent instance)
+ {
+ BBDecoder decoder = new BBDecoder();
+ decoder.init(ByteBuffer.wrap(instance._rawEventData));
+
+ for (QpidProperty property : _schemaOrderedArguments)
+ {
+ try {
+ Object value = property.decodeValue(decoder);
+ instance.createOrReplaceAttributeValue(property.getName(),value);
+ } catch(Exception ignore) {
+ _logger.error(Messages.QMAN_100016_UNABLE_TO_DECODE_FEATURE_VALUE, _parent.getName(),_name,property.getName());
+ }
+ }
+ }
+
+ @Override
+ public String toString ()
+ {
+ return new StringBuilder()
+ .append(_parent.getOwnerId())
+ .append("::")
+ .append(_parent.getName())
+ .append(".")
+ .append(_name)
+ .toString();
+ }
+
+ /**
+ * Deregisters all the object instances and release all previously acquired resources.
+ */
+ void releaseResources ()
+ {
+ _eventInstances.clear();
+ JMX_SERVICE.unregisterEvents();
+ JMX_SERVICE.unregisterClassDefinitions();
+ _service.close();
+ }
+
+ /**
+ * Checks if this event definition contains event instance(s).
+ *
+ * @return true if there is one or more managed instances.
+ */
+ boolean hasNoInstances()
+ {
+ return _eventInstances.isEmpty();
+ }
+
+ /**
+ * Compose method used for registering an mbean (event) instance.
+ *
+ * @param instance the mbean event.
+ * @param brokerId the broker identifier.
+ * @param packageName the package name.
+ * @param eventClassName the event class name.
+ */
+ private void registerEventInstance(
+ QManManagedEvent instance,
+ UUID brokerId,
+ String packageName,
+ String eventClassName)
+ {
+ ObjectName objectName = JMX_SERVICE.registerEventInstance(instance,brokerId,packageName,eventClassName);
+
+ EntityLifecycleNotification notification = new EntityLifecycleNotification(
+ EntityLifecycleNotification.INSTANCE_ADDED_NOTIFICATION_TYPE,
+ packageName,
+ eventClassName,
+ Names.EVENT,
+ objectName);
+
+ sendNotification(notification);
+ }
+}
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidEventMBean.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidEventMBean.java
new file mode 100644
index 0000000000..35ba62e02c
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidEventMBean.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.management.domain.model;
+
+/**
+ * Management interface for Qpid entity class..
+ */
+public interface QpidEventMBean
+{
+ /**
+ * Retruns the name of the event.
+ *
+ * @return the name of the event.
+ */
+ String getName();
+
+ /**
+ * Returns the name of the package.
+ *
+ * @return the name of the package.
+ */
+ String getPackageName();
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidFeature.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidFeature.java
new file mode 100644
index 0000000000..3262448bd4
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidFeature.java
@@ -0,0 +1,86 @@
+/*
+ *
+ * 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.domain.model;
+
+/**
+ * Layer Supertype for all qpid management features.
+ */
+abstract class QpidFeature
+{
+ /** The name of the feature. */
+ protected String _name;
+
+ /**
+ * The description of the feature.
+ */
+ protected String _description;
+
+ /**
+ * Returns the description of this feature.
+ *
+ * @return the description of this feature.
+ */
+ String getDescription ()
+ {
+ return _description;
+ }
+
+ /**
+ * Sets the description for this feature.
+ *
+ * @param description the description for this feature.
+ */
+ void setDescription (String description)
+ {
+ this._description = description;
+ }
+
+ /**
+ * Returns the name of the feature.
+ *
+ * @return the name of the feature.
+ */
+ public String getName ()
+ {
+ return _name;
+ }
+
+ /**
+ * Sets the name for this feature.
+ *
+ * @param name the name of this feature.
+ */
+ void setName (String name)
+ {
+ this._name = name;
+ }
+
+ /**
+ * Returns the name of the feature.
+ *
+ * @return the name of the feature.
+ */
+ @Override
+ public String toString ()
+ {
+ return _name;
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidFeatureBuilder.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidFeatureBuilder.java
new file mode 100644
index 0000000000..d0862c15ca
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidFeatureBuilder.java
@@ -0,0 +1,454 @@
+/*
+ *
+ * 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.domain.model;
+
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import javax.management.MBeanAttributeInfo;
+import javax.management.MBeanFeatureInfo;
+import javax.management.MBeanOperationInfo;
+import javax.management.MBeanParameterInfo;
+
+import org.apache.qpid.management.configuration.Configuration;
+import org.apache.qpid.management.configuration.UnknownTypeCodeException;
+import org.apache.qpid.management.domain.handler.impl.MethodOrEventDataTransferObject;
+import org.apache.qpid.management.Names;
+
+/**
+ * A builder used to parse incoming schema message and therefore to build a feature (property, statistic, method, event)
+ * definition.
+ * In order to set up the correct state for this builder, clients must create an instance of this class
+ * The product of the builder will be a QpidFeature and a JMX Managemtn feature used for describing that feature in a
+ * JMX environment. So, for example, for building a property definition client code should be :
+ *
+ * <br>- QpidFeatureBuilder builder = QpidFeature.createPropertyBuilder(...);
+ * <br>- builder.build();
+ * <br>- QpidProperty property = (QpidProperty) builder.getQpidFeature();
+ * <br>- MBeanAttributeInfo managementAttributeInfo = (MBeanAttributeInfo)builder.getManagementFeature();
+ *
+ * <br>N.B.: a builder instance is not supposed to be reused. One instance for one feature!
+ *
+ * @author Andrea Gazzarini
+ */
+class QpidFeatureBuilder
+{
+
+ static enum Attribute {
+ name,type,access,index,optional,unit,min,max,maxlen,desc,dir,argCount;
+ };
+
+ private List<Attribute> _mandatoryAttributes = new ArrayList<Attribute>();
+
+ /**
+ * Builder state for this class.
+ * Each concrete implementor is a builder for a specific feature.
+ * using the appropriate factory method.
+ *
+ * @author Andrea Gazzarini
+ */
+ interface State {
+ void build() throws UnableToBuildFeatureException;
+ }
+
+ /**
+ * Builder used for building property definition.
+ */
+ final State _propertyBuilder = new State() {
+
+ /**
+ * Builds a property definition as well a management attribute feature.
+ */
+ public void build () throws UnableToBuildFeatureException
+ {
+ QpidProperty property = new QpidProperty();
+ try {
+ int optionalIndex = 0;
+ for (Entry<String, Object> propertyAttribute : _featureDefinition.entrySet())
+ {
+ Attribute attribute = Attribute.valueOf(propertyAttribute.getKey());
+ switch(attribute)
+ {
+ case name :
+ {
+ property.setName(String.valueOf(propertyAttribute.getValue()));
+ break;
+ }
+ case access :
+ {
+ int code = (Integer)propertyAttribute.getValue();
+ property.setAccessMode(Configuration.getInstance().getAccessMode(code));
+ break;
+ }
+ case unit :
+ {
+ property.setUnit(String.valueOf(propertyAttribute.getValue()));
+ break;
+ }
+ case min :
+ {
+ property.setMinValue((Integer)propertyAttribute.getValue());
+ break;
+ }
+ case max :
+ {
+ property.setMaxValue((Integer)propertyAttribute.getValue());
+ break;
+ }
+ case maxlen :
+ {
+ property.setMaxLength((Integer)propertyAttribute.getValue());
+ break;
+ }
+ case desc :
+ {
+ property.setDescription(String.valueOf(propertyAttribute.getValue()));
+ break;
+ }
+ case type :
+ {
+ int code = (Integer) propertyAttribute.getValue();
+ property.setType(Configuration.getInstance().getType(code));
+ break;
+ }
+ case index :
+ {
+ break;
+ }
+ case optional :
+ {
+ int code = (Integer) propertyAttribute.getValue();
+ if (code == 1)
+ {
+ property.markAsOptional(optionalIndex);
+ optionalIndex++;
+ }
+ break;
+ }
+ }
+ _mandatoryAttributes.remove(attribute);
+ }
+ } catch(Exception exception)
+ {
+ throw new UnableToBuildFeatureException(exception,property.getName());
+ }
+
+ if (!_mandatoryAttributes.isEmpty())
+ {
+ throw new MissingFeatureAttributesException(_mandatoryAttributes);
+ }
+
+ _managementFeatureInfo = new MBeanAttributeInfo(
+ property.getName(),
+ property.getJavaType().getName(),
+ property.getDescription(),
+ true,
+ property.getAccessMode()==AccessMode.RW,
+ false);
+ _qpidFeature = property;
+ }
+ };
+
+ final State _statisticBuilder = new State()
+ {
+ public void build () throws UnableToBuildFeatureException
+ {
+ QpidStatistic statistic = new QpidStatistic();
+ try
+ {
+ for (Entry<String, Object> statisticAttribute : _featureDefinition.entrySet())
+ {
+ Attribute attribute = Attribute.valueOf(statisticAttribute.getKey());
+ switch(attribute)
+ {
+ case name :
+ {
+ statistic.setName(String.valueOf(statisticAttribute.getValue()));
+ break;
+ }
+ case unit :
+ {
+ statistic.setUnit(String.valueOf(statisticAttribute.getValue()));
+ break;
+ }
+ case desc :
+ {
+ statistic.setDescription(String.valueOf(statisticAttribute.getValue()));
+ break;
+ }
+ case type :
+ {
+ int code = (Integer) statisticAttribute.getValue();
+ statistic.setType(Configuration.getInstance().getType(code));
+ break;
+ }
+ }
+ _mandatoryAttributes.remove(attribute);
+ }
+ } catch(Exception exception)
+ {
+ throw new UnableToBuildFeatureException(exception,statistic.getName());
+ }
+
+ if (!_mandatoryAttributes.isEmpty())
+ {
+ throw new MissingFeatureAttributesException(_mandatoryAttributes);
+ }
+
+ _managementFeatureInfo = new MBeanAttributeInfo(
+ statistic.getName(),
+ statistic.getJavaType().getName(),
+ statistic.getDescription(),
+ true,
+ false,
+ false);
+ _qpidFeature = statistic;
+ }
+ };
+
+ /**
+ * Builder used for building a statistic definition.
+ */
+ final State _argumentBuilder = new State()
+ {
+ /**
+ * Builds a property definition as well a management attribute feature.
+ */
+ public void build () throws UnableToBuildFeatureException
+ {
+ QpidArgument argument = new QpidArgument();
+ for (Entry<String, Object> argumentAttribute : _featureDefinition.entrySet())
+ {
+ String key = argumentAttribute.getKey();
+ if (Names.DEFAULT_PARAM_NAME.equals(key))
+ {
+ argument.setDefaultValue(argumentAttribute.getValue());
+ } else {
+ Attribute attribute = Attribute.valueOf(key);
+ switch (attribute)
+ {
+ case name :
+ {
+ argument.setName((String)argumentAttribute.getValue());
+ break;
+ }
+ case desc :
+ {
+ argument.setDescription((String)argumentAttribute.getValue());
+ break;
+ }
+ case type :
+ {
+ try
+ {
+ argument.setType(Configuration.getInstance().getType((Integer)argumentAttribute.getValue()));
+ break;
+ } catch(UnknownTypeCodeException exception)
+ {
+ throw new UnableToBuildFeatureException(exception,argument.getName());
+ }
+ }
+ case dir :
+ {
+ argument.setDirection((String)argumentAttribute.getValue());
+ break;
+ }
+ case unit :
+ {
+ argument.setUnit((String)argumentAttribute.getValue());
+ break;
+
+ }
+ }
+ }
+ }
+
+ if (!_mandatoryAttributes.isEmpty())
+ {
+ throw new MissingFeatureAttributesException(_mandatoryAttributes);
+ }
+
+ _qpidFeature = argument;
+ _managementFeatureInfo = new MBeanParameterInfo(
+ argument.getName(),
+ argument.getJavaType().getName(),
+ argument.getDescription());
+ }
+ };
+
+ final State _methodBuilder = new State()
+ {
+ public void build () throws UnableToBuildFeatureException
+ {
+ Map<String,Object> definition = _methodOrEventDefinition.getDefinition();
+ String name = (String)definition.get(Attribute.name.name());
+ if (name == null)
+ {
+ throw new MissingFeatureAttributesException(_mandatoryAttributes);
+ }
+
+ QpidMethod method = new QpidMethod((String)definition.get(Attribute.name.name()),(String) definition.get(Attribute.desc.name()));
+
+ List<Map<String,Object>> args = _methodOrEventDefinition.getArgumentsDefinitions();
+
+ List<MBeanParameterInfo> signature = new LinkedList<MBeanParameterInfo>();
+
+ for (Map<String,Object> argumentDefinition : args)
+ {
+ QpidFeatureBuilder builder = QpidFeatureBuilder.createArgumentBuilder(argumentDefinition);
+ builder.build();
+
+ QpidArgument argument = (QpidArgument) builder.getQpidFeature();
+ method.addArgument(argument);
+ if (argument.isInput())
+ {
+ signature.add((MBeanParameterInfo) builder.getManagementFeature());
+ }
+ }
+
+ _qpidFeature = method;
+ _managementFeatureInfo = new MBeanOperationInfo(
+ method.getName(),
+ method.getDescription(),
+ (MBeanParameterInfo[])signature.toArray(new MBeanParameterInfo[signature.size()]),
+ void.class.getName(),
+ MBeanOperationInfo.ACTION);
+ }
+ };
+
+ final State _eventBuilder = new State()
+ {
+ public void build () throws UnableToBuildFeatureException
+ {
+ }
+ };
+
+ private MBeanFeatureInfo _managementFeatureInfo;
+ private QpidFeature _qpidFeature;
+ private final Map <String, Object> _featureDefinition;
+ private final MethodOrEventDataTransferObject _methodOrEventDefinition;
+ private State _state;
+
+ static QpidFeatureBuilder createPropertyBuilder(Map<String, Object> propertyDefinition)
+ {
+ QpidFeatureBuilder result = new QpidFeatureBuilder(propertyDefinition);
+ result._state = result._propertyBuilder;
+ result._mandatoryAttributes.add(Attribute.name);
+ result._mandatoryAttributes.add(Attribute.access);
+ result._mandatoryAttributes.add(Attribute.type);
+ result._mandatoryAttributes.add(Attribute.optional);
+ result._mandatoryAttributes.add(Attribute.index);
+ return result;
+ }
+
+ static QpidFeatureBuilder createStatisticBuilder(Map<String, Object> statisticDefinition)
+ {
+ QpidFeatureBuilder result = new QpidFeatureBuilder(statisticDefinition);
+ result._state = result._statisticBuilder;
+ result._mandatoryAttributes.add(Attribute.name);
+ result._mandatoryAttributes.add(Attribute.type);
+ return result;
+ }
+
+ static QpidFeatureBuilder createEventBuilder(Map<String, Object> eventDefinition)
+ {
+ QpidFeatureBuilder result = new QpidFeatureBuilder(eventDefinition);
+ result._state = result._eventBuilder;
+ return result;
+ }
+
+ static QpidFeatureBuilder createMethodBuilder(MethodOrEventDataTransferObject methodDefinition)
+ {
+ QpidFeatureBuilder result = new QpidFeatureBuilder(methodDefinition);
+ result._state = result._methodBuilder;
+ result._mandatoryAttributes.add(Attribute.name);
+ return result;
+ }
+
+ private static QpidFeatureBuilder createArgumentBuilder(Map<String, Object> argumentDefinition)
+ {
+ QpidFeatureBuilder result = new QpidFeatureBuilder(argumentDefinition);
+ result._state = result._argumentBuilder;
+ return result;
+ }
+
+
+ /**
+ * Builds new builder with the given data.
+ * This constructor is used for building properties, statistics and arguments.
+ *
+ * @param definition the feature definition data.
+ */
+ private QpidFeatureBuilder(Map<String, Object> definition)
+ {
+ this._featureDefinition = definition;
+ this._methodOrEventDefinition = null;
+ }
+
+ /**
+ * Builds new builder with the given data.
+ * This constructor is used for building properties, statistics and arguments.
+ *
+ * @param definition the feature definition data.
+ */
+ private QpidFeatureBuilder(MethodOrEventDataTransferObject definition)
+ {
+ this._featureDefinition = null;
+ this._methodOrEventDefinition = definition;
+ }
+
+ /**
+ * Returns the just built qpid feature.
+ *
+ * @return the qpid feature.
+ */
+ QpidFeature getQpidFeature()
+ {
+ return _qpidFeature;
+ }
+
+ /**
+ * Return the jmx metadata for the built feature.
+ *
+ * @return the jmx metadata for the built feature.
+ */
+ MBeanFeatureInfo getManagementFeature()
+ {
+ return _managementFeatureInfo;
+ }
+
+ void build() throws UnableToBuildFeatureException
+ {
+ try
+ {
+ _state.build();
+ } catch(UnableToBuildFeatureException exception)
+ {
+ throw exception;
+ } catch(Exception exception)
+ {
+ throw new UnableToBuildFeatureException(exception,"Feature name is not available for debugging.");
+ }
+ }
+}
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidMethod.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidMethod.java
new file mode 100644
index 0000000000..7824ecc9a4
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidMethod.java
@@ -0,0 +1,147 @@
+/*
+ *
+ * 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.domain.model;
+
+import java.nio.ByteBuffer;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.qpid.transport.codec.BBDecoder;
+import org.apache.qpid.transport.codec.Encoder;
+
+
+/**
+ * Qpid method definition.
+ * An entity describing an invocation that can be made on a managed object instance.
+ *
+ * @author Andrea Gazzarini
+ */
+public class QpidMethod extends QpidFeature
+{
+ /** Argument list */
+ List<QpidArgument> arguments = new LinkedList<QpidArgument>();
+
+ /**
+ * Builds a new qpid method definition with the given name and description.
+ *
+ * @param name the method name.
+ * @param description the method description.
+ */
+ QpidMethod(String name, String description)
+ {
+ this._name = name;
+ this._description = description;
+ }
+
+ /**
+ * Adds an argument to this method.
+ *
+ * @param argument the new argument to be added.
+ */
+ void addArgument(QpidArgument argument)
+ {
+ arguments.add(argument);
+ }
+
+ /**
+ * Returns a string representation of this method.
+ * The result format is <method name>(argType1 argName1 (Direction), argType2 argName2 (Direction), etc...)
+ *
+ * @return a string representation of this method.
+ */
+ @Override
+ public String toString ()
+ {
+ StringBuilder builder = new StringBuilder()
+ .append(_name)
+ .append('(');
+
+ for (QpidArgument argument : arguments)
+ {
+ builder.append(argument).append(',');
+ }
+
+ builder.append(')');
+ return builder.toString();
+ }
+
+ /**
+ * Encodes the given parameter values according to this method arguments definitions.
+ * Note that only Input/Output and Input parameters are encoded.
+ *
+ * @param parameters the parameters values.
+ * @param encoder the encoder used for encoding.
+ */
+ public void encodeParameters (Object[] parameters, Encoder encoder)
+ {
+ int index = 0;
+ for (QpidArgument argument : arguments)
+ {
+ if (argument.getDirection() != Direction.O)
+ {
+ argument.encode(parameters[index++],encoder);
+ }
+ }
+ }
+
+ /**
+ * Decodes the given input raw according to this method arguments definitions.
+ * Note that only Input/Output and Output parameters are encoded.
+ *
+ * @param parameters the parameters values.
+ * @param encoder the encoder used for encoding.
+ */
+ public Map<String, Object> decodeParameters (byte [] values)
+ {
+ BBDecoder decoder = new BBDecoder();
+ decoder.init(ByteBuffer.wrap(values));
+ Map<String, Object> result = new HashMap<String, Object>();
+
+ for (QpidArgument argument : arguments)
+ {
+ if (argument.getDirection() != Direction.I)
+ {
+ result.put(argument.getName(),argument.decode(decoder));
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Validates the given array of parameters against the constraint defined on this method's arguments.
+ *
+ * @param parameters the parameters (values) to be validated.
+ * @throws ValidationException when one of the supplied values is violating some constraint.
+ */
+ public void validate (Object[] parameters) throws ValidationException
+ {
+ int index = 0;
+ for (QpidArgument argument : arguments)
+ {
+ if (argument.getDirection() != Direction.O)
+ {
+ argument.validate(parameters[index++]);
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidPackage.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidPackage.java
new file mode 100644
index 0000000000..c25a5d7d1c
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidPackage.java
@@ -0,0 +1,286 @@
+/*
+ *
+ * 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.domain.model;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+
+import org.apache.qpid.management.domain.handler.impl.IMethodInvocationListener;
+import org.apache.qpid.management.domain.handler.impl.MethodOrEventDataTransferObject;
+import org.apache.qpid.management.domain.model.type.Binary;
+
+/**
+ * Qpid package definition.
+ * A grouping of class definitions that are related to a single software component.
+ * The package concept is used to extend the management schema beyond just the QPID software components.
+ * The name is prefixed with "Qpid" for avoiding name conficts with java.lang.Package.
+ *
+ * @author Andrea Gazzarini
+ */
+final class QpidPackage
+{
+ /**
+ * Qpid class identity.
+ * Each qpid class is uniquely identifier by its name and schema-hash.
+ * The schema hash is an MD5 checksum of the schema for a class.
+ * It is there so we can support the case where two different versions of the same class are present at the same time.
+ *
+ * @author Andrea Gazzarini
+ */
+ class QpidClassIdentity {
+ final String name;
+ final Binary hash;
+
+ /**
+ * Builds a new class identity with the given name and hash.
+ *
+ * @param name the class name.
+ * @param hash is an MD5 checksum of the schema of this outer class.
+ */
+ QpidClassIdentity(String name,Binary hash) {
+ this.name = name;
+ this.hash = hash;
+ }
+
+ @Override
+ public int hashCode ()
+ {
+ return name.hashCode()+hash.hashCode();
+ }
+
+ @Override
+ public boolean equals (Object obj)
+ {
+ if(obj instanceof QpidClassIdentity)
+ {
+ QpidClassIdentity identity = (QpidClassIdentity) obj;
+ return name.equals(identity.name) && hash.equals(identity.hash);
+ }
+ else
+ {
+ return false;
+ }
+ }
+ }
+
+ private String _name;
+ private DomainModel _parent;
+ private Map<QpidClassIdentity, QpidClass> _classes = new HashMap<QpidClassIdentity, QpidClass>();
+ private Map<QpidClassIdentity, QpidEvent> _events = new HashMap<QpidClassIdentity, QpidEvent>();
+
+ /**
+ * Builds a new package with the supplied name.
+ *
+ * @param name the name of the package.
+ */
+ QpidPackage(String name, DomainModel parent)
+ {
+ this._name = name;
+ this._parent = parent;
+ }
+
+ /**
+ * Returns the identifier of the broker which contains this package.
+ * @return
+ */
+ UUID getOwnerId()
+ {
+ return _parent.getBrokerId();
+ }
+
+ /**
+ * Returns the name of this package.
+ *
+ * @return the name of this package.
+ */
+ String getName ()
+ {
+ return _name;
+ }
+
+ /**
+ * Adds a class definition to this package.
+ * The class will be added only if its definition doesn't already exists.
+ *
+ * @param className the name of the class.
+ * @param classHash the class schema hash.
+ * @param properties the properties of the class.
+ * @param statistics the statistics of the class.
+ * @param methods the methods of the class.
+ * @param events the events of the class.
+ *
+ * @throws UnableToBuildFeatureException when the class definition cannot be built due to a feature build failure.
+ */
+ void addClassDefinition (
+ String className,
+ Binary classHash,
+ List<Map<String, Object>> properties,
+ List<Map<String, Object>> statistics,
+ List<MethodOrEventDataTransferObject> methods) throws UnableToBuildFeatureException
+ {
+ getQpidClass(className,classHash,true).setSchema(properties,statistics,methods);
+ }
+
+ void addEventDefinition (
+ String eventClassName,
+ Binary classHash,
+ List<Map<String, Object>> arguments) throws UnableToBuildFeatureException
+ {
+ getQpidEvent(eventClassName,classHash,true).setSchema(arguments);
+ }
+
+ /**
+ * Returns true if this package contains the given class definition.
+ *
+ * @param className the name of the class.
+ * @return true if this package contains the class definition, false otherwise.
+ */
+ boolean alreadyContainsClassDefinition (String className, Binary hash)
+ {
+ return _classes.containsKey(new QpidClassIdentity(className,hash));
+ }
+
+ /**
+ * Injects into a class the given object instance instrumentation data.
+ *
+ * @param className the of the class the injected object data belongs to.
+ * @param objectId the object identifier.
+ * @param rawData the instrumentation data (in raw format).
+ */
+ void setObjectInstanceInstrumentationRawData (String className, Binary classHash,Binary objectId, byte[] rawData)
+ {
+ getQpidClass(className, classHash,true).addInstrumentationData(objectId,rawData);
+ }
+
+ /**
+ * Injects into a class the given object instance configuration data.
+ *
+ * @param className the of the class the injected object data belongs to.
+ * @param objectId the object identifier.
+ * @param rawData the configuration data (in raw format).
+ */
+ void setObjectInstanceConfigurationRawData (String className,Binary classHash, Binary objectId, byte[] rawData)
+ {
+ getQpidClass(className,classHash,true).addConfigurationData(objectId,rawData);
+ }
+
+ void setEventInstanceRawData (String eventName,Binary eventHash, byte[] rawData,long currentTimestamp,int severity)
+ {
+ getQpidEvent(eventName,eventHash,true).addEventData(rawData, currentTimestamp, severity);
+ }
+
+ /**
+ * Returns the definition of the class with given name.
+ *
+ * @param className the name of the class.
+ * @param hash the class hash.
+ * @param store a flag indicating if a just created class must be stored or not.
+ * @return the definition of the class with given name.
+ */
+ QpidClass getQpidClass(String className, Binary hash, boolean store)
+ {
+ QpidClassIdentity identity = new QpidClassIdentity(className,hash);
+ QpidClass classDefinition = _classes.get(identity);
+ if (classDefinition == null)
+ {
+ classDefinition = new QpidClass(className, hash,this);
+ if (store)
+ {
+ _classes.put(identity,classDefinition);
+ }
+ }
+ return classDefinition;
+ }
+
+ /**
+ * Returns the definition of the class with given name.
+ *
+ * @param className the name of the class.
+ * @param hash the class hash.
+ * @param store a flag indicating if a just created class must be stored or not.
+ * @return the definition of the class with given name.
+ */
+ QpidEvent getQpidEvent(String className, Binary hash, boolean store)
+ {
+ QpidClassIdentity identity = new QpidClassIdentity(className,hash);
+ QpidEvent eventDefinition = _events.get(identity);
+ if (eventDefinition == null)
+ {
+ eventDefinition = new QpidEvent(className, hash,this);
+ if (store)
+ {
+ _events.put(identity,eventDefinition);
+ }
+ }
+ return eventDefinition;
+ }
+
+ /**
+ * Returns a string representation of this class.
+ * That is, this method returns the simple name (not FQN) of this class.
+ */
+ @Override
+ public String toString ()
+ {
+ return _name;
+ }
+
+ /**
+ * Removes the object instance associated to the given parameters.
+ *
+ * @param className the class definition of the object instance.
+ * @param classHash the class hash
+ * @param objectId the object identifier.
+ */
+ void removeObjectInstance (String className, Binary classHash, Binary objectId)
+ {
+ QpidClass qpidClass = getQpidClass(className,classHash,false);
+ qpidClass.removeObjectInstance(objectId);
+ }
+
+ /**
+ * Releases all previously acquired resources of this package.
+ */
+ void releaseResources ()
+ {
+ for (QpidClass qpidClass : _classes.values())
+ {
+ qpidClass.releaseResources();
+ }
+
+ for (QpidEvent qpidEvent: _events.values())
+ {
+ qpidEvent.releaseResources();
+ }
+ }
+
+ /**
+ * Returns the method invocation listener of the corresponing parent domain model.
+ *
+ * @return the method invocation listener of the corresponing parent domain model.
+ */
+ IMethodInvocationListener getMethodInvocationListener ()
+ {
+ return _parent.getMethodInvocationListener();
+ }
+}
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidProperty.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidProperty.java
new file mode 100644
index 0000000000..089b00c71c
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidProperty.java
@@ -0,0 +1,295 @@
+/*
+ *
+ * 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.domain.model;
+
+import java.lang.reflect.Constructor;
+
+import org.apache.qpid.management.Messages;
+import org.apache.qpid.management.configuration.Configuration;
+import org.apache.qpid.management.domain.model.type.Type;
+import org.apache.qpid.transport.util.Logger;
+
+/**
+ * Qpid property definition.
+ *
+ * @author Andrea Gazzarini
+ */
+class QpidProperty extends QpidAttribute
+{
+ private final static Logger LOGGER = Logger.get(QpidProperty.class);
+
+ private final static int [] MASKS = {1,2,4,8,16,32,64,128};
+
+ /**
+ * Decoder interface used for decoding incomng values for this property.
+ *
+ * @author Andrea Gazzarini
+ */
+ interface Decoder
+ {
+ Object decodeValue(org.apache.qpid.transport.codec.Decoder decoder,byte [] presenceBitMasks);
+ }
+
+ /**
+ * Decoder used for decoding incoming values for this optional property.
+ */
+ final Decoder _optionalPropertyDecoder = new Decoder() {
+
+ public Object decodeValue (org.apache.qpid.transport.codec.Decoder decoder, byte[] presenceBitMasks)
+ {
+ return ((presenceBitMasks[_optionalIndex/8] & MASKS[_maskIndex]) != 0)
+ ? QpidProperty.this.decodeValue(decoder)
+ : null;
+ }
+ };
+
+ /**
+ * Decoder used for decoding incoming values for this mandatory property.
+ */
+ final Decoder _mandatoryPropertyDecoder = new Decoder() {
+
+ public Object decodeValue (org.apache.qpid.transport.codec.Decoder decoder, byte[] presenceBitMasks)
+ {
+ return QpidProperty.this.decodeValue(decoder);
+ }
+ };
+
+
+ /**
+ * Null object used to perform a dummy validation.
+ * This is the default validator installed at creation time.
+ */
+ final static IValidator EMPTY_VALIDATOR = new IValidator()
+ {
+ public void validate (Object value) throws ValidationException
+ {
+ // Nothing to do here.
+ }
+ };
+
+ /**
+ * Validator responsible for validating strings.
+ * At the moment the only constraint that should be applied to a string feature is the "max length"
+ */
+ class StringValidator implements IValidator
+ {
+ public void validate (Object value) throws ValidationException
+ {
+ if ((_maxLength != Integer.MIN_VALUE) && (value != null)){
+ int length = value.toString().length();
+ if (length > _maxLength) {
+ throw new ValidationException(
+ ValidationException.MAX_LENGTH,
+ _maxLength,
+ _name,
+ length);
+ }
+ }
+ }
+ };
+
+ /**
+ * Validator responsible for validating numbers.
+ */
+ class NumberValidator implements IValidator
+ {
+ public void validate (Object value) throws ValidationException
+ {
+ if (value != null) {
+ double numericValue = ((Number)value).doubleValue();
+ if (_minValue != Integer.MIN_VALUE && numericValue < _minValue) {
+ throw new ValidationException(
+ ValidationException.MIN_VALUE,
+ _minValue,
+ _name,
+ numericValue);
+ }
+
+ if (_maxValue != Integer.MIN_VALUE && numericValue > _maxValue) {
+ throw new ValidationException(
+ ValidationException.MAX_VALUE,
+ _maxValue,
+ _name,
+ numericValue);
+ }
+ }
+ }
+ };
+
+ private AccessMode _accessMode;
+ private int _minValue = Integer.MIN_VALUE;
+ private int _maxValue = Integer.MIN_VALUE;
+ private int _maxLength = Integer.MIN_VALUE;
+
+ private int _optionalIndex;
+ private int _maskIndex;
+
+ Decoder _decoder = _mandatoryPropertyDecoder;
+
+ private IValidator _validator = EMPTY_VALIDATOR;
+
+ /**
+ * Validates the given value according to the current validator.
+ * It delegates the validation to the current installed validator.
+ *
+ * @param value the value of this qpid property.
+ * @throws ValidationException when the given value is violating the current validator constraints.
+ */
+ void validate(Object value) throws ValidationException {
+ _validator.validate(value);
+ }
+
+ /**
+ * Sets the type of this property.
+ * In addition this method tries to detect if a validator has been associated with the type.
+ * If no validator is found then the default validator will be used; that is : no validator will be performed on this
+ * property.
+ *
+ * @param type the type of this property.
+ */
+ void setType (Type type)
+ {
+ super.setType(type);
+ try {
+ Class<?> validatorClass = Class.forName(Configuration.getInstance().getValidatorClassName(type));
+ Constructor<?> validatorConstructor = validatorClass.getDeclaredConstructor(QpidProperty.class);
+ _validator = (IValidator) validatorConstructor.newInstance(this);
+ LOGGER.debug(Messages.QMAN_200022_VALIDATOR_INSTALLED ,validatorClass.getName(), type);
+ } catch(Exception exception) {
+ _validator = EMPTY_VALIDATOR;
+ LOGGER.debug(Messages.QMAN_200023_VALIDATOR_NOT_FOUND , type);
+ }
+ }
+
+ /**
+ * Gets the value of this property according to its type definition.
+ *
+ * @param decoder the decoder used to extract the value.
+ * @return the value of this feature according to its type definition
+ */
+ Object decodeValue(org.apache.qpid.transport.codec.Decoder decoder,byte [] presenceBitMasks)
+ {
+ return _decoder.decodeValue(decoder, presenceBitMasks);
+ }
+
+ /**
+ * Sets access mode for this property.
+ *
+ * @param accessMode the access mode for this property.
+ */
+ void setAccessMode (AccessMode accessMode)
+ {
+ this._accessMode = accessMode;
+ }
+
+ /**
+ * Gets the minimum allowed value for this property.
+ *
+ * @return the minimum allowed value for this property.
+ */
+ int getMinValue ()
+ {
+ return _minValue;
+ }
+
+ /**
+ * Sets the minimum allowed value for this property.
+ *
+ * @param minValue the minimum allowed value for this property.
+ */
+ void setMinValue (int minValue)
+ {
+ this._minValue = minValue;
+ }
+
+ /**
+ * Gets the maximum allowed value for this property.
+ *
+ * @return the maximum allowed value for this property.
+ */
+ int getMaxValue ()
+ {
+ return _maxValue;
+ }
+
+ /**
+ * Sets the masimum allowed value for this property.
+ *
+ * @param maxValue the maximum allowed value for this property.
+ */
+ void setMaxValue (int maxValue)
+ {
+ this._maxValue = maxValue;
+ }
+
+ /**
+ * Gets the max length value for this property.
+ *
+ * @return the max length value for this property.
+ */
+ int getMaxLength ()
+ {
+ return _maxLength;
+ }
+
+ /**
+ * Sets the max length value for this property.
+ *
+ * @param maxLength the max length value for this property.
+ */
+ void setMaxLength (int maxLength)
+ {
+ this._maxLength = maxLength;
+ }
+
+ /**
+ * Gets the description of this property.
+ *
+ * @return the description of this property.
+ */
+ AccessMode getAccessMode ()
+ {
+ return _accessMode;
+ }
+
+ /**
+ * Marks this property as optional.
+ *
+ * @param optional the optional attribute value for this property.
+ * @param index the index of this optional property
+ */
+ void markAsOptional (int index)
+ {
+ this._optionalIndex = index;
+ this._maskIndex = (_optionalIndex >= 8) ? _optionalIndex-8 : _optionalIndex;
+ _decoder = _optionalPropertyDecoder;
+ }
+
+ /**
+ * Returns true if this property is marked as optional.
+ *
+ * @return true if this property is marked as optional, false otherwise.
+ */
+ boolean isOptional ()
+ {
+ return _decoder == _optionalPropertyDecoder;
+ }
+}
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidStatistic.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidStatistic.java
new file mode 100644
index 0000000000..37a652c098
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidStatistic.java
@@ -0,0 +1,34 @@
+/*
+ *
+ * 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.domain.model;
+
+/**
+ * Qpid statistic definition.
+ *
+ * A statistic is a typed member of a class which represents an instrumentation attribute of the class.
+ * Statistics are always read-only in nature and tend to change rapidly.
+ *
+ * @author Andrea Gazzarini
+ */
+class QpidStatistic extends QpidAttribute
+{
+ // EMPTY CLASS : Statistic metadata are all defined in superclasses.
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/UnableToBuildFeatureException.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/UnableToBuildFeatureException.java
new file mode 100644
index 0000000000..fc4506779b
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/UnableToBuildFeatureException.java
@@ -0,0 +1,51 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.management.domain.model;
+
+/**
+ * Thrown when a feature (property, statistic, method or event) definition cannot be built due to schema parsing errors.
+ *
+ * @author Andrea Gazzarini
+ */
+public class UnableToBuildFeatureException extends Exception
+{
+ private static final long serialVersionUID = 5180111828887602836L;
+
+ /**
+ * Builds a new UnableToBuildFeatureException with the specified cause.
+ *
+ * @param exception the exception cause.
+ */
+ UnableToBuildFeatureException(Exception exception, String featureName)
+ {
+ super( (featureName != null) ? featureName : "Feature name is not available for debugging purposes." ,exception);
+ }
+
+ /**
+ * Builds a new UnableToBuildFeatureException with the specified message.
+ *
+ * @param message the detail message.
+ */
+ UnableToBuildFeatureException(String message)
+ {
+ super(message);
+ }
+}
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/ValidationException.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/ValidationException.java
new file mode 100644
index 0000000000..3b117e5b9d
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/ValidationException.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.domain.model;
+
+/**
+ * Thrown when an attempt is made in order to update / change the state of an object and a constraint on that state
+ * is violated.
+ *
+ * @author Andrea Gazzarini
+ */
+public class ValidationException extends Exception
+{
+ private static final long serialVersionUID = -5218828669655586205L;
+
+ public final static String MAX_LENGTH = "Max Length";
+ public final static String MAX_VALUE = "Max Value";
+ public final static String MIN_VALUE = "Min Value";
+
+ private final String _featureName;
+ private final Object _featureValue;
+
+ private final Number _constraintValue;
+ private final String _constraintName;
+
+ /**
+ * Builds a new validation exception with the specified parameters.
+ *
+ * @param constraintName the name of the violated constraint.
+ * @param constraintValue the value of the violated constraint.
+ * @param featureName the name of the violating feature.
+ * @param featureValue the value of the violating feature.
+ */
+ ValidationException(String constraintName,Number constraintValue, String featureName,Object featureValue)
+ {
+ super(String.format(
+ "Property constraint violation : " +
+ "%s allowed for property %s is %s but received value was %s",
+ constraintName,
+ featureName,
+ constraintValue,
+ featureValue));
+ this._constraintName = constraintName;
+ this._constraintValue = constraintValue;
+ this._featureName = featureName;
+ this._featureValue = featureValue;
+ }
+
+ /**
+ * Returns the value of the violating feature.
+ *
+ * @return the value of the violating feature.
+ */
+ public Object getFeatureValue ()
+ {
+ return _featureValue;
+ }
+
+ /**
+ * Returns the name of the violating feature.
+ *
+ * @return the name of the violating feature.
+ */
+ public String getFeatureName()
+ {
+ return _featureName;
+ }
+
+ /**
+ * Returns the value of the violated constraint.
+ *
+ * @return the value of the violated constraint.
+ */
+ public Number getConstraintValue ()
+ {
+ return _constraintValue;
+ }
+
+ /**
+ * Returns the name of the violated constraint.
+ *
+ * @return the name of the violated constraint.
+ */
+ public String getConstraintName ()
+ {
+ return _constraintName;
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/AbsTime.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/AbsTime.java
new file mode 100644
index 0000000000..28f5f70c04
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/AbsTime.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.domain.model.type;
+
+import org.apache.qpid.transport.codec.Decoder;
+import org.apache.qpid.transport.codec.Encoder;
+
+public class AbsTime extends Type
+{
+ public AbsTime()
+ {
+ super(Long.class);
+ }
+
+ @Override
+ public Object decode (Decoder decoder)
+ {
+ return decoder.readInt64();
+ }
+
+ @Override
+ public void encode (Object value, Encoder encoder)
+ {
+ encoder.writeInt64((Long)value);
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Binary.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Binary.java
new file mode 100644
index 0000000000..95cb03b04b
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Binary.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.domain.model.type;
+
+import java.io.Serializable;
+import java.util.Arrays;
+import java.util.UUID;
+
+import org.apache.qpid.transport.codec.Encoder;
+
+/**
+ * It is a simple wrapper for a byte array (for example a 128bin).
+ * It is used to let QMan deal with an object instead of an array.
+ *
+ * @author Andrea Gazzarini
+ */
+public final class Binary implements Serializable
+{
+ private static final long serialVersionUID = -6865585077320637567L;
+
+ // Marker internal (empty) interface
+ private interface State extends Serializable{}
+
+ /**
+ * Internal state of this object used to denote the situation when the hashcode() method has never been called.
+ * After the hashcode has been computed this class switches the state of the outer object to the next state.
+ */
+ State hashCodeNotYetComputed = new State()
+ {
+ private static final long serialVersionUID = 221632033761266959L;
+
+ @Override
+ public int hashCode ()
+ {
+ hashCode = Arrays.hashCode(_bytes);
+ state = hashCodeAlreadyComputed;
+ return hashCode;
+ }
+ };
+
+ /**
+ * Internal state of this object used to denote the situation where the hashcode() method has already been computed.
+ * Simply it returns the just computed value for the hashcode.
+ */
+ State hashCodeAlreadyComputed = new State()
+ {
+ private static final long serialVersionUID = 221632033761266959L;
+
+ @Override
+ public int hashCode ()
+ {
+ return hashCode;
+ }
+ };
+
+ private final UUID uuid;
+ private final byte [] _bytes;
+ private long _first;
+ private int hashCode;
+
+ /** Current state (hashcode computation). */
+ State state = hashCodeNotYetComputed;
+
+ /**
+ * Builds a new binary with the given byte array.
+ *
+ * @param bytes the wrapped data.
+ */
+ public Binary(byte [] bytes)
+ {
+ this._bytes = bytes;
+ byte [] array = new byte [8];
+ System.arraycopy(_bytes, 0, array, 0, 8);
+ _first = unpack64(array);
+ uuid = UUID.randomUUID();
+ }
+
+ @Override
+ public int hashCode ()
+ {
+ return state.hashCode();
+ }
+
+ @Override
+ public boolean equals (Object obj)
+ {
+ if(obj instanceof Binary)
+ {
+ try
+ {
+ Binary binary = (Binary)obj;
+ return Arrays.equals(_bytes, binary._bytes);
+ } catch (Exception exception)
+ {
+ return false;
+ }
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ /**
+ * Encodes the content (wrapped byte array) of this instance using the given encoder.
+ *
+ * @param encoder the encoder used to encode instance content.
+ */
+ public void encode(Encoder encoder)
+ {
+ encoder.writeBin128(_bytes);
+ }
+
+ @Override
+ public String toString ()
+ {
+ return uuid.toString();
+ }
+
+ /**
+ * Returns the bank identifier derived from this object identifier.
+ *
+ * @return the bank identifier derived from this object identifier.
+ */
+ public long getBankId()
+ {
+ return _first & 0x000000000FFFFFFF;
+ }
+
+ /**
+ * Returns the broker identifier derived from this object identifier.
+ *
+ * @return the broker identifier derived from this object identifier.
+ */
+ public long getBrokerId()
+ {
+ return (_first & 281474708275200L) >> 28;
+ }
+
+ public final long unpack64(byte data[]) {
+ return (
+ ((long) (data[0] & 0xff) << 56) |
+ ((long)(data[1] & 0xff) << 48) |
+ ((long)(data[2] & 0xff) << 40) |
+ ((long)(data[3] & 0xff) << 32) |
+ ((long)(data[4] & 0xff) << 24) |
+ ((long)(data[5] & 0xff) << 16) |
+ ((long)(data[6] & 0xff) << 8) |
+ (long) data[7] & 0xff);
+ }
+}
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Boolean.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Boolean.java
new file mode 100644
index 0000000000..c339b870ac
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Boolean.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.domain.model.type;
+
+import org.apache.qpid.transport.codec.Decoder;
+import org.apache.qpid.transport.codec.Encoder;
+
+public class Boolean extends Type
+{
+ public Boolean()
+ {
+ super(java.lang.Boolean.class);
+ }
+
+ @Override
+ public Object decode (Decoder decoder)
+ {
+ return (decoder.readUint8() == 1);
+ }
+
+ @Override
+ public void encode (Object value, Encoder encoder)
+ {
+ encoder.writeUint8( ((java.lang.Boolean)value) ? (short)1 : 0 );
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/DeltaTime.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/DeltaTime.java
new file mode 100644
index 0000000000..a788e2f8e1
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/DeltaTime.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.domain.model.type;
+
+import org.apache.qpid.transport.codec.Decoder;
+import org.apache.qpid.transport.codec.Encoder;
+
+public class DeltaTime extends Type
+{
+ public DeltaTime()
+ {
+ super(Long.class);
+ }
+
+ @Override
+ public Object decode (Decoder decoder)
+ {
+ return decoder.readUint64();
+ }
+
+ @Override
+ public void encode (Object value, Encoder encoder)
+ {
+ encoder.writeUint64((Long)value);
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Double.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Double.java
new file mode 100644
index 0000000000..d36af3d3df
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Double.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.domain.model.type;
+
+import org.apache.qpid.transport.codec.Decoder;
+import org.apache.qpid.transport.codec.Encoder;
+
+public class Double extends Type
+{
+ public Double()
+ {
+ super(java.lang.Double.class);
+ }
+
+ @Override
+ public Object decode(Decoder decoder)
+ {
+ return decoder.readDouble();
+ }
+
+ @Override
+ public void encode(Object value, Encoder encoder)
+ {
+ encoder.writeDouble((java.lang.Double)value);
+ }
+}
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Float.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Float.java
new file mode 100644
index 0000000000..cb1f6e78a7
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Float.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.domain.model.type;
+
+import org.apache.qpid.transport.codec.Decoder;
+import org.apache.qpid.transport.codec.Encoder;
+
+public class Float extends Type
+{
+ public Float()
+ {
+ super(java.lang.Float.class);
+ }
+
+ @Override
+ public Object decode(Decoder decoder)
+ {
+ return decoder.readFloat();
+ }
+
+ @Override
+ public void encode(Object value, Encoder encoder)
+ {
+ encoder.writeFloat((java.lang.Float)value);
+ }
+}
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Int16.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Int16.java
new file mode 100644
index 0000000000..f4685f0295
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Int16.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.domain.model.type;
+
+import org.apache.qpid.transport.codec.Decoder;
+import org.apache.qpid.transport.codec.Encoder;
+
+public class Int16 extends Type
+{
+ public Int16()
+ {
+ super(Short.class);
+ }
+
+ @Override
+ public Object decode (Decoder decoder)
+ {
+ return decoder.readInt16();
+ }
+
+ @Override
+ public void encode (Object value, Encoder encoder)
+ {
+ encoder.writeInt16((Short)value);
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Int32.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Int32.java
new file mode 100644
index 0000000000..ae5be90a2d
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Int32.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.domain.model.type;
+
+import org.apache.qpid.transport.codec.Decoder;
+import org.apache.qpid.transport.codec.Encoder;
+
+public class Int32 extends Type
+{
+ public Int32()
+ {
+ super(Integer.class);
+ }
+
+ @Override
+ public Object decode (Decoder decoder)
+ {
+ return decoder.readInt32();
+ }
+
+ @Override
+ public void encode (Object value, Encoder encoder)
+ {
+ encoder.writeInt32((Integer)value);
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Int64.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Int64.java
new file mode 100644
index 0000000000..f76818344e
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Int64.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.domain.model.type;
+
+import org.apache.qpid.transport.codec.Decoder;
+import org.apache.qpid.transport.codec.Encoder;
+
+public class Int64 extends Type
+{
+ public Int64()
+ {
+ super(Long.class);
+ }
+
+ @Override
+ public Object decode (Decoder decoder)
+ {
+ return decoder.readInt64();
+ }
+
+ @Override
+ public void encode (Object value, Encoder encoder)
+ {
+ encoder.writeInt64((Long)value);
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Int8.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Int8.java
new file mode 100644
index 0000000000..6f7c3b24d0
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Int8.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.domain.model.type;
+
+import org.apache.qpid.transport.codec.Decoder;
+import org.apache.qpid.transport.codec.Encoder;
+
+public class Int8 extends Type
+{
+ public Int8()
+ {
+ super(Byte.class);
+ }
+
+ @Override
+ public Object decode (Decoder decoder)
+ {
+ return decoder.readInt8();
+ }
+
+ @Override
+ public void encode (Object value, Encoder encoder)
+ {
+ encoder.writeInt8((Byte)value);
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Map.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Map.java
new file mode 100644
index 0000000000..ef5bc7a484
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Map.java
@@ -0,0 +1,45 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.management.domain.model.type;
+
+import org.apache.qpid.transport.codec.Decoder;
+import org.apache.qpid.transport.codec.Encoder;
+
+public class Map extends Type
+{
+ public Map()
+ {
+ super(java.util.Map.class);
+ }
+
+ @Override
+ public Object decode (Decoder decoder)
+ {
+ return decoder.readMap();
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public void encode (Object value, Encoder encoder)
+ {
+ encoder.writeMap((java.util.Map<String, Object>)value);
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/ObjectReference.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/ObjectReference.java
new file mode 100644
index 0000000000..13e1b68d26
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/ObjectReference.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.domain.model.type;
+
+import org.apache.qpid.transport.codec.Decoder;
+import org.apache.qpid.transport.codec.Encoder;
+
+public class ObjectReference extends Type
+{
+ public ObjectReference()
+ {
+ super(byte[].class);
+ }
+
+ @Override
+ public Object decode (Decoder decoder)
+ {
+ return decoder.readBin128();
+ }
+
+ @Override
+ public void encode (Object value, Encoder encoder)
+ {
+ ((Binary)value).encode(encoder);
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Str16.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Str16.java
new file mode 100644
index 0000000000..42829ce176
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Str16.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.domain.model.type;
+
+import org.apache.qpid.transport.codec.Decoder;
+import org.apache.qpid.transport.codec.Encoder;
+
+public class Str16 extends Type
+{
+ public Str16()
+ {
+ super(String.class);
+ }
+
+ @Override
+ public Object decode (Decoder decoder)
+ {
+ return decoder.readStr16();
+ }
+
+ @Override
+ public void encode (Object value, Encoder encoder)
+ {
+ encoder.writeStr16((String)value);
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Str8.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Str8.java
new file mode 100644
index 0000000000..f9b747ce6d
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Str8.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.domain.model.type;
+
+import org.apache.qpid.transport.codec.Decoder;
+import org.apache.qpid.transport.codec.Encoder;
+
+public class Str8 extends Type
+{
+ public Str8()
+ {
+ super(String.class);
+ }
+
+ @Override
+ public Object decode (Decoder decoder)
+ {
+ return decoder.readStr8();
+ }
+
+ @Override
+ public void encode (Object value, Encoder encoder)
+ {
+ encoder.writeStr8((String)value);
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Type.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Type.java
new file mode 100644
index 0000000000..7f92ec82b0
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Type.java
@@ -0,0 +1,101 @@
+/*
+ *
+ * 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.domain.model.type;
+
+import org.apache.qpid.transport.codec.Decoder;
+import org.apache.qpid.transport.codec.Encoder;
+
+/**
+ * Layer supertype for all management "types".
+ *
+ * @author Andrea Gazzarini
+ */
+public abstract class Type
+{
+ /** Java representation of this type. */
+ protected final Class<?> javaType;
+
+ /**
+ * Builds a new management type wiich wraps the given java type.
+ *
+ * @param javaType the java type.
+ */
+ Type(Class<?> javaType)
+ {
+ this.javaType = javaType;
+ }
+
+ /**
+ * Returns the wrapped java type.
+ *
+ * @return the wrapped java type.
+ */
+ public Class<?> getJavaType ()
+ {
+ return javaType;
+ }
+
+ /**
+ * Each concrete subclass must define here how to decode incoming data according.
+ *
+ * @param decoder the decoder used to extract data.
+ * @return the "typed" value.
+ *
+ */
+ public abstract Object decode(Decoder decoder);
+
+ /**
+ * Returns a string representation of this type.
+ *
+ * @return a string representation of this type.
+ */
+ @Override
+ public String toString ()
+ {
+ return new StringBuilder(getClass().getName())
+ .append(" (wraps ")
+ .append(javaType.getName())
+ .append(')').toString();
+ }
+
+ /**
+ * Identity for types is based on wrapped java type identity.
+ */
+ @Override
+ public boolean equals (Object obj)
+ {
+ return (obj instanceof Type) && getJavaType() == ((Type)obj).getJavaType();
+ }
+
+ @Override
+ public int hashCode ()
+ {
+ return getJavaType().hashCode();
+ }
+
+ /**
+ * Encodes the given values according to this type definition.
+ *
+ * @param value the value to be encoded.
+ * @param encoder the encoder.
+ */
+ public abstract void encode (Object value,Encoder encoder);
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Uint16.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Uint16.java
new file mode 100644
index 0000000000..2d3edd41ea
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Uint16.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.domain.model.type;
+
+import org.apache.qpid.transport.codec.Decoder;
+import org.apache.qpid.transport.codec.Encoder;
+
+public class Uint16 extends Type
+{
+ public Uint16()
+ {
+ super(Integer.class);
+ }
+
+ @Override
+ public Object decode (Decoder decoder)
+ {
+ return new Integer(decoder.readUint16());
+ }
+
+ @Override
+ public void encode (Object value, Encoder encoder)
+ {
+ encoder.writeUint16((Integer)value);
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Uint32.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Uint32.java
new file mode 100644
index 0000000000..c5fb981bb0
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Uint32.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.domain.model.type;
+
+import org.apache.qpid.transport.codec.Decoder;
+import org.apache.qpid.transport.codec.Encoder;
+
+public class Uint32 extends Type
+{
+ public Uint32()
+ {
+ super(Long.class);
+ }
+
+ @Override
+ public Object decode (Decoder decoder)
+ {
+ return new Long(decoder.readUint32());
+ }
+
+ @Override
+ public void encode (Object value, Encoder encoder)
+ {
+ encoder.writeUint32((Long)value);
+ }
+}
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Uint64.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Uint64.java
new file mode 100644
index 0000000000..9182f883bf
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Uint64.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.domain.model.type;
+
+import org.apache.qpid.transport.codec.Decoder;
+import org.apache.qpid.transport.codec.Encoder;
+
+public class Uint64 extends Type
+{
+ public Uint64()
+ {
+ super(Long.class);
+ }
+
+ @Override
+ public Object decode (Decoder decoder)
+ {
+ return new Long(decoder.readUint64());
+ }
+
+ @Override
+ public void encode (Object value, Encoder encoder)
+ {
+ encoder.writeUint64((Long)value);
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Uint8.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Uint8.java
new file mode 100644
index 0000000000..ab7e78856c
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Uint8.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.domain.model.type;
+
+import org.apache.qpid.transport.codec.Decoder;
+import org.apache.qpid.transport.codec.Encoder;
+
+public class Uint8 extends Type
+{
+ public Uint8()
+ {
+ super(Short.class);
+ }
+
+ @Override
+ public Object decode (Decoder decoder)
+ {
+ return new Short(decoder.readUint8());
+ }
+
+ @Override
+ public void encode (Object value, Encoder encoder)
+ {
+ encoder.writeUint8((Short)value);
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Uuid.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Uuid.java
new file mode 100644
index 0000000000..1b3be954d6
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Uuid.java
@@ -0,0 +1,46 @@
+/*
+ *
+ * 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.domain.model.type;
+
+import java.util.UUID;
+
+import org.apache.qpid.transport.codec.Decoder;
+import org.apache.qpid.transport.codec.Encoder;
+
+public class Uuid extends Type
+{
+ public Uuid()
+ {
+ super(UUID.class);
+ }
+
+ @Override
+ public Object decode (Decoder decoder)
+ {
+ return decoder.readUuid();
+ }
+
+ @Override
+ public void encode (Object value, Encoder encoder)
+ {
+ encoder.writeUuid((UUID)value);
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/services/BrokerMessageListener.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/services/BrokerMessageListener.java
new file mode 100644
index 0000000000..fc9819fce4
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/services/BrokerMessageListener.java
@@ -0,0 +1,183 @@
+/*
+ *
+ * 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.domain.services;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import org.apache.qpid.api.Message;
+import org.apache.qpid.management.Messages;
+import org.apache.qpid.management.Protocol;
+import org.apache.qpid.management.domain.handler.base.IMessageHandler;
+import org.apache.qpid.management.domain.model.DomainModel;
+import org.apache.qpid.nclient.util.MessageListener;
+import org.apache.qpid.transport.codec.BBDecoder;
+import org.apache.qpid.transport.util.Logger;
+
+/**
+ * Message listener used for processing incoming messages.
+ * So it is installed as a consumer on a specific channel and when a new message arrives:
+ *
+ * 1) Performs a sanity check on the message (magic number, sequence number)
+ * 2) Extracts the opcode and looks for one message handler associated with that opcode.
+ * 3) If a message handler is found the delegates the message processing; otherwise a log message is written to indicate
+ * that the message will be skipped.
+ *
+ * @author Andrea Gazzarini
+ */
+class BrokerMessageListener implements MessageListener
+{
+ private final static Logger LOGGER = Logger.get(BrokerMessageListener.class);
+
+ private static class Log
+ {
+ // Debugs the content of the incoming message.
+ static void debugIncomingMessage(ByteBuffer message)
+ {
+ if (LOGGER.isDebugEnabled())
+ {
+ LOGGER.debug(Messages.QMAN_200001_INCOMING_MESSAGE_HAS_BEEN_RECEIVED, Arrays.toString(message.array()));
+ }
+ }
+
+ // Debugs all the configured handlers.
+ static void debugConfiguredHandlers (Map<Character, IMessageHandler> _handlers)
+ {
+ if (LOGGER.isDebugEnabled())
+ {
+ for (Entry<Character, IMessageHandler> entry : _handlers.entrySet())
+ {
+ LOGGER.debug(Messages.QMAN_200002_OPCODE_HANDLER_ASSOCIATION,entry.getKey(),entry.getValue());
+ }
+ }
+ }
+ }
+
+ Map<Character, IMessageHandler> _handlers = new HashMap<Character, IMessageHandler>();
+ private DomainModel _domainModel;
+
+ /**
+ * Builds a new message listener with the given broker domain model.
+ *
+ * @param model the managed broker domain model.
+ */
+ BrokerMessageListener(DomainModel model)
+ {
+ this._domainModel = model;
+ }
+
+ /**
+ * When a new message arrives this method is called.
+ * 1) Performs a sanity check on the message (magic number, sequence number)
+ * 2) Extracts the opcode and looks for one message handler associated with that opcode.
+ * 3) If a message handler is found the delegates the message processing; otherwise a log message is written to indicate
+ * that the message will be skipped.
+ *
+ * @param message the incoming message.
+ */
+ public void onMessage (Message compoundMessage)
+ {
+ try
+ {
+ MessageTokenizer tokenizer = new MessageTokenizer(compoundMessage);
+ while (tokenizer.hasMoreElements())
+ {
+ dispatch(tokenizer.nextElement());
+ }
+ } catch(IOException exception)
+ {
+ LOGGER.error(exception,Messages.QMAN_100002_MESSAGE_READ_FAILURE);
+ } catch(Exception exception)
+ {
+ LOGGER.error(exception,Messages.QMAN_100003_MESSAGE_PROCESS_FAILURE);
+ }
+ }
+
+ /**
+ * Configures a new handler with this listener.
+ * After that, each time a message arrives with the specified opcode, this handler will be responsible for
+ * processing.
+ * Note that calling this method will switch this listener to a WORKING state.
+ *
+ * @param opcode the operation code.
+ * @param handler the message handler.
+ */
+ void setHandlers(Map<Character, IMessageHandler> handlers)
+ {
+ for (Entry<Character, IMessageHandler> entry : handlers.entrySet())
+ {
+ char opcode = entry.getKey();
+ IMessageHandler handler = entry.getValue();
+ try
+ {
+ handler.setDomainModel(_domainModel);
+ _handlers.put(opcode, handler);
+ } catch (Exception exception) {
+ LOGGER.error(exception,
+ Messages.QMAN_100004_HANDLER_INITIALIZATION_FAILURE,
+ opcode);
+ }
+ }
+ }
+
+
+
+ /**
+ * Dispatches the given message to the appropriate handler.
+ *
+ * @param message
+ * the incoming message.
+ * @throws IOException
+ * when the message content cannot be read.
+ */
+ private void dispatch(Message message) throws IOException
+ {
+ ByteBuffer buffer = message.readData();
+
+ String magicNumber = new String(new byte[] {buffer.get(),buffer.get(),buffer.get()});
+ if (!Protocol.MAGIC_NUMBER.equals(magicNumber))
+ {
+ LOGGER.error(Messages.QMAN_100001_BAD_MAGIC_NUMBER_FAILURE,magicNumber);
+ return;
+ }
+
+ char opcode = (char)buffer.get();
+
+ IMessageHandler handler = _handlers.get(opcode);
+ if (handler != null)
+ {
+ BBDecoder decoder = new BBDecoder();
+ decoder.init(buffer);
+
+ LOGGER.debug(Messages.QMAN_200003_MESSAGE_FORWARDING,opcode,handler);
+
+ handler.process(decoder,decoder.readSequenceNo());
+ } else
+ {
+ LOGGER.warn(Messages.QMAN_300001_MESSAGE_DISCARDED,opcode);
+ Log.debugConfiguredHandlers(_handlers);
+ }
+ }
+}
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/services/ManagementClient.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/services/ManagementClient.java
new file mode 100644
index 0000000000..a6f5ab90cc
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/services/ManagementClient.java
@@ -0,0 +1,249 @@
+/*
+ *
+ * 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.domain.services;
+
+import java.util.UUID;
+
+import org.apache.qpid.management.Messages;
+import org.apache.qpid.management.Names;
+import org.apache.qpid.management.configuration.BrokerConnectionData;
+import org.apache.qpid.management.configuration.Configuration;
+import org.apache.qpid.management.domain.model.DomainModel;
+import org.apache.qpid.transport.util.Logger;
+
+/**
+ * This is the Object representation of a management client.
+ * According to specification : "A software component that is separate from the messaging broker, connected to the
+ * management broker via an AMQP connection, which allows any software component to be managed remotely by QPID."
+ *
+ * @author Andrea Gazzarini
+ */
+public final class ManagementClient
+{
+ private final static Logger LOGGER = Logger.get(ManagementClient.class);
+
+ private final String _managementQueueName;
+ private final String _methodReplyQueueName;
+
+ private DomainModel _domainModel;
+ private QpidService _service;
+
+ private final BrokerConnectionData _connectionData;
+
+ /**
+ * Builds a new <code>ManagementClient</code> with the given identifier and connection data.
+ *
+ * @param brokerId the broker identifier.
+ * @param connectionData the broker connection data (host, port, etc...)
+ */
+ ManagementClient(UUID brokerId,BrokerConnectionData connectionData)
+ {
+ _connectionData = connectionData;
+ _service = new QpidService(brokerId);
+ _domainModel = new DomainModel(brokerId);
+ _managementQueueName = Configuration.getInstance().getManagementQueueName();
+ _methodReplyQueueName = Configuration.getInstance().getMethodReplyQueueName();
+ }
+
+ @Override
+ public String toString()
+ {
+ return _connectionData.toString();
+ }
+
+ /**
+ * Returns the connection data associated with this management client.
+ *
+ * @return the connection data associated with this management client.
+ */
+ public BrokerConnectionData getBrokerConnectionData()
+ {
+ return _connectionData;
+ }
+
+ /**
+ * Establishing initial communication Between Client and Broker.
+ * According to specification :
+ * "Communication is established between the management client and management agent using normal AMQP procedures.
+ * The client creates a connection to the broker and then establishes a session with its corresponding channel.
+ * Two private queues are then declared.
+ * A management queue is declared and bound to the qpid.management exchange with "mgmt.#" as routing key; in that
+ * way all management-related messages sent to the exchange will be received by this client.
+ * When a client successfully binds to the qpid.management exchange, the management agent schedules a schema
+ * broadcast to be sent to the exchange.
+ * The agent will publish, via the exchange, a description of the schema for all manageable objects in its control. That
+ * schema is therefore received by this service and it will be part of service's domain model."
+ *
+ * @throws StartupFailureException when this management client cannot perform startup operations due to an error.
+ */
+ void estabilishFirstConnectionWithBroker() throws StartupFailureException{
+ try {
+ connectWithBroker();
+
+ createAndBindMethodReplyQueue();
+ createAndBindManagementQueue();
+
+ registerConsumerOnManagementQueue();
+ registerConsumerOnMethodReplyQueue();
+
+ synchronize();
+ } catch(Exception exception)
+ {
+ try {
+ _service.close();
+ } catch(Exception ignore)
+ {
+ }
+ throw new StartupFailureException(exception);
+ }
+ }
+
+ /**
+ * Shutdown procedure for this management client.
+ */
+ void shutdown ()
+ {
+ LOGGER.info(Messages.QMAN_000011_SHUTDOWN_INITIATED,_domainModel.getBrokerId());
+
+ removeMethodReplyConsumer();
+ destroyAndUnbingMethodReplyQueue();
+
+ removeManagementConsumer();
+ destroyAndUnbingManagementQueue();
+
+ _domainModel.releaseResources();
+
+ _service.close();
+
+ LOGGER.info(Messages.QMAN_000012_MANAGEMENT_CLIENT_SHUT_DOWN,_domainModel.getBrokerId());
+ }
+
+ /**
+ * Registers a consumer (that is, a listener) on the method-reply queue.
+ */
+ private void registerConsumerOnMethodReplyQueue ()
+ {
+ BrokerMessageListener methodReplyChannelListener = new BrokerMessageListener(_domainModel);
+ methodReplyChannelListener.setHandlers(Configuration.getInstance().getMethodReplyQueueHandlers());
+ _service.createSubscription(_methodReplyQueueName, _methodReplyQueueName, methodReplyChannelListener);
+
+ LOGGER.info(Messages.QMAN_000013_METHOD_REPLY_CONSUMER_INSTALLED, _domainModel.getBrokerId());
+ }
+
+ /**
+ * Registers a consumer (listener) on the management queue.
+ */
+ private void registerConsumerOnManagementQueue ()
+ {
+ BrokerMessageListener managementChannelListener = new BrokerMessageListener(_domainModel);
+ managementChannelListener.setHandlers(Configuration.getInstance().getManagementQueueHandlers());
+ _service.createSubscription(_managementQueueName, _managementQueueName, managementChannelListener);
+
+ LOGGER.info(Messages.QMAN_000014_MANAGEMENT_CONSUMER_INSTALLED, _domainModel.getBrokerId());
+ }
+
+ /**
+ * Declares a management queue and bound it to the "qpid.management" exchange with "mgmt.#" as routing key;
+ */
+ private void createAndBindManagementQueue ()
+ {
+ _service.declareQueue(_managementQueueName);
+ _service.declareBinding(
+ _managementQueueName,
+ Names.MANAGEMENT_EXCHANGE,
+ Names.MANAGEMENT_ROUTING_KEY);
+
+ LOGGER.info(Messages.QMAN_000015_MANAGEMENT_QUEUE_DECLARED,_managementQueueName,_domainModel.getBrokerId());
+ }
+
+ /**
+ * Declares a private queue for receiving method replies (after method invocations).
+ * This queue is bound to the amq.direct exchange using a routing key equal to the name of the queue.
+ */
+ private void createAndBindMethodReplyQueue ()
+ {
+ _service.declareQueue(_methodReplyQueueName);
+ _service.declareBinding(_methodReplyQueueName, Names.AMQ_DIRECT_QUEUE, _methodReplyQueueName);
+
+ LOGGER.info(Messages.QMAN_000016_METHOD_REPLY_QUEUE_DECLARED,_methodReplyQueueName, _domainModel.getBrokerId());
+ }
+
+ /**
+ * Removes the method-reply queue consumer.
+ */
+ private void removeMethodReplyConsumer()
+ {
+ _service.removeSubscription(_methodReplyQueueName);
+
+ LOGGER.info(Messages.QMAN_000017_CONSUMER_HAS_BEEN_REMOVED,_methodReplyQueueName,_domainModel.getBrokerId());
+ }
+
+ /**
+ * Unbind the method reply queue and after that destroy it from remote broker.
+ */
+ private void destroyAndUnbingMethodReplyQueue()
+ {
+ _service.declareUnbinding(_methodReplyQueueName, Names.AMQ_DIRECT_QUEUE, _methodReplyQueueName);
+ _service.deleteQueue(_methodReplyQueueName);
+
+ LOGGER.info(Messages.QMAN_000018_QUEUE_UNDECLARED,_methodReplyQueueName,_domainModel.getBrokerId());
+ }
+
+ /**
+ * Removes the management queue consumer.
+ */
+ private void removeManagementConsumer()
+ {
+ _service.removeSubscription(_managementQueueName);
+
+ LOGGER.info(Messages.QMAN_000017_CONSUMER_HAS_BEEN_REMOVED,_managementQueueName,_domainModel.getBrokerId());
+ }
+
+ /**
+ * Unbind the management queue and after that destroy it from remote broker.
+ */
+ private void destroyAndUnbingManagementQueue()
+ {
+ _service.declareUnbinding(_managementQueueName, Names.MANAGEMENT_EXCHANGE, Names.MANAGEMENT_ROUTING_KEY);
+ _service.deleteQueue(_managementQueueName);
+
+ LOGGER.info(Messages.QMAN_000018_QUEUE_UNDECLARED, _managementQueueName,_domainModel.getBrokerId());
+ }
+
+ /**
+ * Connects this client with the broker.
+ *
+ * @throws QpidException when it's not possibile to connect with the broker.
+ */
+ private void connectWithBroker() throws Exception
+ {
+ _service.connect();
+ }
+
+ /**
+ * All the Management client commands are asynchronous.
+ * Synchronous behavior is achieved through invoking the sync method.
+ */
+ private void synchronize()
+ {
+ _service.sync();
+ }
+}
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/services/MessageTokenizer.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/services/MessageTokenizer.java
new file mode 100644
index 0000000000..9275255517
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/services/MessageTokenizer.java
@@ -0,0 +1,152 @@
+/*
+*
+ * 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.domain.services;
+
+import java.io.IOException;
+import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.LinkedList;
+
+import org.apache.qpid.api.Message;
+import org.apache.qpid.management.Messages;
+import org.apache.qpid.management.Protocol;
+import org.apache.qpid.nclient.util.ByteBufferMessage;
+import org.apache.qpid.transport.codec.BBDecoder;
+import org.apache.qpid.transport.util.Logger;
+
+/**
+ * The message tokenizer class allows a multi message listener to break a
+ * message into tokens where each token is itself a valid AMQP message.
+ *
+ * @author Andrea Gazzarini
+ * @see QPID-1368
+ */
+class MessageTokenizer implements Enumeration<Message>
+{
+ private final static Logger LOGGER = Logger.get(MessageTokenizer.class);
+
+ static byte [] MAGIC_NUMBER_BYTES;
+
+ private LinkedList<Message> _messages = new LinkedList<Message>();
+ private Iterator<Message> _iterator;
+
+ static
+ {
+ try
+ {
+ MAGIC_NUMBER_BYTES = Protocol.MAGIC_NUMBER.getBytes("UTF-8");
+ } catch(Exception exception)
+ {
+ throw new ExceptionInInitializerError(exception);
+ }
+ }
+
+ /**
+ * Builds a new Message tokenizer with the given message.
+ * Note that if the given message is not a "compound" message this tokenizer will producer only one token;
+ * That is, the token is a message equals to the given message.
+ *
+ * @param compoundMessage the compound message
+ * @throws IOException when it's not possible to read the given message content.
+ */
+ MessageTokenizer(Message compoundMessage) throws IOException
+ {
+ build(compoundMessage);
+ }
+
+ public boolean hasMoreElements()
+ {
+ return _iterator.hasNext();
+ }
+
+ public Message nextElement()
+ {
+ return _iterator.next();
+ }
+
+ /**
+ * Retruns the number of the tokens produced by this tokenizer.
+ *
+ * @return the number of the tokens produced by this tokenizer.
+ */
+ public int countTokens()
+ {
+ return _messages.size();
+ }
+
+ // Internal methods used for splitting the multi message byte array.
+ int indexOf(byte[] source, int startIndex)
+ {
+ int currentSourceIndex;
+ int currentExampleIndex;
+
+ if (startIndex + 3 > source.length)
+ return -1;
+
+ for (currentSourceIndex = startIndex; currentSourceIndex <= source.length - 3; currentSourceIndex++)
+ {
+ for (currentExampleIndex = 0; currentExampleIndex < 3; currentExampleIndex++)
+ {
+ if (source[currentSourceIndex + currentExampleIndex] != MAGIC_NUMBER_BYTES[currentExampleIndex])
+ break;
+ }
+
+ if (currentExampleIndex == 3)
+ return currentSourceIndex;
+ }
+ return -1;
+ }
+
+ // Internal method used for building the tokens.
+ private void build(Message compoundMessage) throws IOException
+ {
+ int startIndex = 0;
+ int indexOfMagicNumber = 0;
+
+ BBDecoder decoder = new BBDecoder();
+ decoder.init(compoundMessage.readData());
+ byte [] source = decoder.readReaminingBytes();
+
+ int howManyTokens = 1;
+
+ while ((indexOfMagicNumber = indexOf(source, startIndex+1)) != -1)
+ {
+ addMessageToken(source, startIndex, (indexOfMagicNumber-startIndex));
+ startIndex = indexOfMagicNumber;
+ howManyTokens++;
+ }
+ addMessageToken(source, startIndex, (source.length-startIndex));
+ _iterator = _messages.iterator();
+
+ LOGGER.debug(Messages.QMAN_200031_COMPOUND_MESSAGE_CONTAINS,howManyTokens);
+ };
+
+ // Builds & adds a new "message" token
+ private void addMessageToken(byte [] source,int startIndex,int length) throws IOException
+ {
+ byte [] messageData = new byte[length];
+ System.arraycopy(source, startIndex, messageData, 0, messageData.length);
+ Message message = new ByteBufferMessage();
+ message.appendData(messageData);
+ _messages.add(message);
+ }
+}
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/services/MethodInvocationException.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/services/MethodInvocationException.java
new file mode 100644
index 0000000000..26fd8eee24
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/services/MethodInvocationException.java
@@ -0,0 +1,50 @@
+/*
+ *
+ * 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.domain.services;
+
+public class MethodInvocationException extends Exception
+{
+ private static final long serialVersionUID = -7772343434879470351L;
+ private final long _returnCode;
+ private final String _statusText;
+
+ public MethodInvocationException(long code, String text)
+ {
+ this._returnCode = code;
+ this._statusText = text;
+ }
+
+ @Override
+ public String getMessage ()
+ {
+ return String.format("Return code : \"%s, reason : \"%s\"",_returnCode,_statusText);
+ }
+
+ public long getReturnCode ()
+ {
+ return _returnCode;
+ }
+
+ public String getStatusText ()
+ {
+ return _statusText;
+ }
+} \ No newline at end of file
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
new file mode 100644
index 0000000000..c4c0ce5e74
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/services/QMan.java
@@ -0,0 +1,412 @@
+/*
+ *
+ * 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.domain.services;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+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;
+import javax.management.DynamicMBean;
+import javax.management.MBeanException;
+import javax.management.MBeanInfo;
+import javax.management.MBeanOperationInfo;
+import javax.management.MBeanParameterInfo;
+import javax.management.Notification;
+import javax.management.NotificationBroadcasterSupport;
+import javax.management.NotificationListener;
+import javax.management.ReflectionException;
+
+import org.apache.log4j.xml.DOMConfigurator;
+import org.apache.qpid.management.Messages;
+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;
+
+/**
+ * Main entry point for starting Q-Man application.
+ */
+public class QMan extends NotificationBroadcasterSupport implements DynamicMBean, NotificationListener
+{
+ private final static Logger LOGGER = Logger.get(QMan.class);
+ private final List<ManagementClient> managementClients = new ArrayList<ManagementClient>();
+
+ private Configurator _configurator = new Configurator();
+ private ThreadPoolExecutor _workManager;
+
+ /**
+ * Starts QMan.
+ * @throws StartupFailureException when it's not possible to proceed with startup.
+ */
+ public void start() throws StartupFailureException
+ {
+ LOGGER.info(Messages.QMAN_000001_STARTING_QMAN);
+ LOGGER.info(Messages.QMAN_000002_READING_CONFIGURATION);
+
+ try
+ {
+ registerQManService();
+
+ _configurator.configure();
+
+ configureWorkManager();
+
+ LOGGER.info(Messages.QMAN_000019_QMAN_STARTED);
+ } catch(Exception exception) {
+ LOGGER.error(exception,Messages.QMAN_100018_UNABLE_TO_STARTUP_CORRECTLY );
+ throw new StartupFailureException(exception);
+ }
+ }
+
+ /**
+ * Connects Q-Man with a broker defined by the given parameter.
+ *
+ * @param host the hostname where the broker is running.
+ * @param port the port where the broker is running.
+ * @param username the username for connecting with the broker.
+ * @param password the password for connecting with the broker.
+ * @param virtualHost the virtual host.
+ * @param initialPoolCapacity the number of the connection that must be immediately opened.
+ * @param maxPoolCapacity the maximum number of opened connection.
+ * @param maxWaitTimeout the maximum amount of time that a client will wait for obtaining a connection.
+ * @throws MBeanException when it's not possible to connect with the broker.
+ */
+ public void addBroker(
+ String host,
+ int port,
+ String username,
+ String password,
+ String virtualHost,
+ int initialPoolCapacity,
+ int maxPoolCapacity,
+ long maxWaitTimeout) throws BrokerAlreadyConnectedException, BrokerConnectionException
+ {
+ Configurator configurator = new Configurator();
+ try {
+ UUID brokerId = UUID.randomUUID();
+ BrokerConnectionData data = configurator.createAndReturnBrokerConnectionData(
+ brokerId,
+ host,
+ port,
+ username,
+ password,
+ virtualHost,
+ initialPoolCapacity,
+ maxPoolCapacity,
+ maxWaitTimeout);
+ createManagementClient(brokerId, data);
+ } catch (BrokerAlreadyConnectedException exception)
+ {
+ LOGGER.warn(Messages.QMAN_300003_BROKER_ALREADY_CONNECTED, exception.getBrokerConnectionData());
+ throw exception;
+ }
+ }
+
+ /**
+ * Stop Qman
+ */
+ public void stop()
+ {
+ LOGGER.info(Messages.QMAN_000020_SHUTTING_DOWN_QMAN);
+ try
+ {
+ for (ManagementClient client : managementClients)
+ {
+ client.shutdown();
+ }
+ } catch(Exception exception)
+ {
+ }
+ 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.
+ *
+ * @param configurator the configurator to be injected.
+ */
+ public void setConfigurator(Configurator configurator){
+ this._configurator = configurator;
+ }
+
+ /**
+ * Main method used for starting Q-Man.
+ *
+ * @param args the command line arguments.
+ */
+ public static void main (String[] args)
+ {
+ if (args.length == 1)
+ {
+ String logFileName = args[0];
+ DOMConfigurator.configureAndWatch(logFileName,5000);
+ }
+
+ final QMan qman = new QMan();
+
+ Thread hook = new Thread()
+ {
+ @Override
+ public void run ()
+ {
+ qman.stop();
+ }
+ };
+
+ Runtime.getRuntime().addShutdownHook(hook);
+ try
+ {
+ qman.start();
+
+ System.out.println("Type \"q\" to quit.");
+ BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
+ while ( !"q".equals(reader.readLine()) )
+ {
+
+ }
+ Runtime.getRuntime().removeShutdownHook(hook);
+ qman.stop();
+ System.exit(-1);
+ } catch (StartupFailureException exception)
+ {
+ qman.stop();
+ System.exit(-1);
+ } catch (IOException exception)
+ {
+ System.exit(-1);
+ }
+ }
+
+ /**
+ * Not implemented for this MBean.
+ */
+ public Object getAttribute(String attribute)
+ {
+ return null;
+ }
+
+ /**
+ * Not implemented for this MBean.
+ */
+ public AttributeList getAttributes(String[] attributes)
+ {
+ return null;
+ }
+
+ /**
+ * Returns the metadata for this MBean
+ *
+ * @return the metadata for this MBean
+ */
+ public MBeanInfo getMBeanInfo()
+ {
+ MBeanParameterInfo parameters [] = new MBeanParameterInfo[8];
+
+ parameters[0] = new MBeanParameterInfo(
+ "host",
+ String.class.getName(),
+ "The IP address or DNS name that Qpid Broker uses to listen for incoming connections.");
+ parameters[1] = new MBeanParameterInfo(
+ "port",
+ int.class.getName(),
+ "The port number that Qpid Broker uses to listen for incoming connections.");
+ parameters[2] = new MBeanParameterInfo(
+ "username",
+ String.class.getName(),
+ "The Qpid account name used in the physical connection.");
+ parameters[3] = new MBeanParameterInfo(
+ "password",
+ String.class.getName(),
+ "The Qpid account password used in the physical connection.");
+ parameters[4]= new MBeanParameterInfo(
+ "virtualHost",
+ String.class.getName(),
+ "The virtualHost name.");
+ parameters[5]= new MBeanParameterInfo(
+ "initialPoolCapacity",
+ int.class.getName(),
+ "The number of physical connections (between 0 and a positive 32-bit integer) to create when creating the (Qpid) connection pool.");
+ parameters[6]= new MBeanParameterInfo(
+ "maxPoolCapacity",
+ int.class.getName(),
+ "The maximum number of physical database connections (between 0 and a positive 32-bit integer) that the (Qpid) connection pool can contain. ");
+ parameters[7]= new MBeanParameterInfo(
+ "maxWaitTimeout",
+ long.class.getName(),
+ "The maximum amount of time to wait for an idle connection.A value of -1 indicates an illimted amount of time (i.e. forever)");
+
+ MBeanOperationInfo operation = new MBeanOperationInfo(
+ "addBroker",
+ "Connects QMan with a broker.",
+ parameters,
+ void.class.getName(),
+ MBeanOperationInfo.ACTION);
+
+ MBeanInfo mbean = new MBeanInfo(
+ QMan.class.getName(),
+ "QMan Management & Administration interface.",
+ null,
+ null,
+ new MBeanOperationInfo[]{operation},
+ null);
+
+ return mbean;
+ }
+
+ /**
+ * Invokes an operation on QMan (MBean).
+ *
+ * @param actionName the operation name.
+ * @param params the operation parameters.
+ * @param signature the operation signature.
+ * @return the result of the invocation (if the operation is not void);
+ * @exception MBeanException Wraps a <CODE>java.lang.Exception</CODE> thrown by the MBean's invoked method.
+ * @exception ReflectionException Wraps a <CODE>java.lang.Exception</CODE> thrown while trying to invoke the method
+ */
+ public Object invoke(String actionName, Object[] params, String[] signature) throws MBeanException, ReflectionException
+ {
+ if (Names.ADD_BROKER_OPERATION_NAME.equals(actionName))
+ {
+ try
+ {
+ addBroker(
+ (String)params[0],
+ (Integer)params[1],
+ (String)params[2],
+ (String)params[3],
+ (String)params[4],
+ (Integer)params[5],
+ (Integer)params[6],
+ (Long)params[7]);
+ } catch(Exception exception)
+ {
+ throw new MBeanException(exception);
+ }
+ } else
+ {
+ throw new ReflectionException(new NoSuchMethodException(actionName));
+ }
+ return null;
+ }
+
+ /**
+ * Not implemented for this MBean.
+ */
+ public void setAttribute(Attribute attribute)
+ {
+ }
+
+ /**
+ * Not implemented for this MBean.
+ */
+ public AttributeList setAttributes(AttributeList attributes)
+ {
+ return null;
+ }
+
+ /**
+ * 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(final Notification notification, Object handback)
+ {
+ _workManager.execute(new Runnable(){
+ public void run()
+ {
+ sendNotification(notification);
+ }
+ });
+ }
+
+ /**
+ * Registers QMan as an MBean on MBeanServer.
+ *
+ * @throws MBeanException when it's not possible to proceeed with registration.
+ */
+ private void registerQManService() throws MBeanException
+ {
+ JmxService service = new JmxService();
+ service.registerQManService(this);
+
+ LOGGER.info(Messages.QMAN_000023_QMAN_REGISTERED_AS_MBEAN);
+ }
+
+ /**
+ * Configures work manager component.
+ */
+ 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
new file mode 100644
index 0000000000..bd7d305184
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/services/QpidService.java
@@ -0,0 +1,361 @@
+/*
+ *
+ * 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.domain.services;
+
+import java.io.IOException;
+import java.util.Map;
+import java.util.UUID;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.apache.qpid.api.Message;
+import org.apache.qpid.management.Messages;
+import org.apache.qpid.management.Names;
+import org.apache.qpid.management.configuration.QpidDatasource;
+import org.apache.qpid.management.domain.model.QpidMethod;
+import org.apache.qpid.management.domain.model.type.Binary;
+import org.apache.qpid.management.messages.MethodInvocationRequestMessage;
+import org.apache.qpid.management.messages.SchemaRequestMessage;
+import org.apache.qpid.nclient.util.MessageListener;
+import org.apache.qpid.nclient.util.MessagePartListenerAdapter;
+import org.apache.qpid.transport.Connection;
+import org.apache.qpid.transport.MessageAcceptMode;
+import org.apache.qpid.transport.MessageAcquireMode;
+import org.apache.qpid.transport.MessageCreditUnit;
+import org.apache.qpid.transport.MessageTransfer;
+import org.apache.qpid.transport.Option;
+import org.apache.qpid.transport.Session;
+import org.apache.qpid.transport.SessionException;
+import org.apache.qpid.transport.SessionListener;
+import org.apache.qpid.transport.util.Logger;
+
+/**
+ * Qpid Broker facade.
+ *
+ * @author Andrea Gazzarini
+ */
+public class QpidService implements SessionListener
+{
+ private final static Logger LOGGER = Logger.get(QpidService.class);
+
+ private UUID _brokerId;
+ private Connection _connection;
+ private Session _session;
+ private Map<String,MessagePartListenerAdapter> _listeners;
+
+ /**
+ * Builds a new service with the given connection data.
+ *
+ * @param connectionData the connection data of the broker.
+ */
+ public QpidService(UUID brokerId)
+ {
+ this._brokerId = brokerId;
+ }
+
+ /**
+ * Estabilishes a connection with the broker.
+ *
+ * @throws QpidException in case of connection failure.
+ */
+ public void connect() throws Exception
+ {
+ _connection = QpidDatasource.getInstance().getConnection(_brokerId);
+ _listeners = new ConcurrentHashMap<String,MessagePartListenerAdapter>();
+ _session = _connection.createSession(0);
+ _session.setSessionListener(this);
+ }
+
+ public void opened(Session ssn) {}
+
+ public void resumed(Session ssn) {}
+
+ public void message(Session ssn, MessageTransfer xfr)
+ {
+ MessagePartListenerAdapter l = _listeners.get(xfr.getDestination());
+ if (l == null)
+ {
+ LOGGER.error("unhandled message: %s", xfr);
+ }
+ else
+ {
+ l.messageTransfer(xfr);
+ }
+ }
+
+
+ public void exception(Session ssn, SessionException exc)
+ {
+
+ }
+
+ public void closed(Session ssn) {}
+
+ /**
+ * All the previously entered outstanding commands are asynchronous.
+ * Synchronous behavior is achieved through invoking this method.
+ */
+ public void sync()
+ {
+ _session.sync();
+ }
+
+ /**
+ * Closes communication with broker.
+ */
+ public void close()
+ {
+ try
+ {
+ _session.close();
+ _session = null;
+ _listeners = null;
+ } catch (Exception e)
+ {
+ }
+ try
+ {
+ _connection.close();
+ _connection = null;
+ } catch (Exception e)
+ {
+ }
+ }
+
+ /**
+ * Associate a message listener with a destination therefore creating a new subscription.
+ *
+ * @param queueName The name of the queue that the subscriber is receiving messages from.
+ * @param destinationName the name of the destination, or delivery tag, for the subscriber.
+ * @param listener the listener for this destination.
+ *
+ * @see Session#messageSubscribe(String, String, short, short, org.apache.qpid.nclient.MessagePartListener, java.util.Map, org.apache.qpid.transport.Option...)
+ */
+ public void createSubscription(String queueName, String destinationName, MessageListener listener)
+ {
+ _listeners.put(destinationName, new MessagePartListenerAdapter(listener));
+ _session.messageSubscribe
+ (queueName,
+ destinationName,
+ MessageAcceptMode.NONE,
+ MessageAcquireMode.PRE_ACQUIRED,
+ null, 0, null);
+
+ _session.messageFlow(destinationName, MessageCreditUnit.BYTE, Session.UNLIMITED_CREDIT);
+ _session.messageFlow(destinationName, MessageCreditUnit.MESSAGE, Session.UNLIMITED_CREDIT);
+
+ LOGGER.debug(Messages.QMAN_200025_SUBSCRIPTION_DECLARED,queueName,destinationName);
+ }
+
+ /**
+ * Removes a previously declared consumer from the broker.
+ *
+ * @param destinationName the name of the destination, or delivery tag, for the subscriber.
+ * @see Session#messageCancel(String, Option...)
+ */
+ public void removeSubscription(String destinationName)
+ {
+ _session.messageCancel(destinationName);
+ LOGGER.debug(Messages.QMAN_200026_SUBSCRIPTION_REMOVED,destinationName);
+ }
+
+ /**
+ * Declares a queue on the broker with the given name.
+ *
+ * @param queueName the name of the declared queue.
+ * @see Session#queueDeclare(String, String, java.util.Map, Option...)
+ */
+ public void declareQueue(String queueName)
+ {
+ _session.queueDeclare(queueName, null, null);
+ LOGGER.debug(Messages.QMAN_200027_QUEUE_DECLARED,queueName);
+ }
+
+ /**
+ * Removes the queue with the given name from the broker.
+ *
+ * @param queueName the name of the queue.
+ * @see Session#queueDelete(String, Option...)
+ */
+ public void deleteQueue(String queueName)
+ {
+ _session.queueDelete(queueName);
+ LOGGER.debug(Messages.QMAN_200028_QUEUE_REMOVED,queueName);
+ }
+
+ /**
+ * Binds (on the broker) a queue with an exchange.
+ *
+ * @param queueName the name of the queue to bind.
+ * @param exchangeName the exchange name.
+ * @param routingKey the routing key used for the binding.
+ * @see Session#exchangeBind(String, String, String, java.util.Map, Option...)
+ */
+ public void declareBinding(String queueName, String exchangeName, String routingKey)
+ {
+ _session.exchangeBind(queueName, exchangeName, routingKey, null);
+ LOGGER.debug(Messages.QMAN_200029_BINDING_DECLARED,routingKey,queueName,exchangeName);
+ }
+
+ /**
+ * Removes a previously declare binding between an exchange and a queue.
+ *
+ * @param queueName the name of the queue.
+ * @param exchangeName the name of the exchange.
+ * @param routingKey the routing key used for binding.
+ */
+ public void declareUnbinding(String queueName, String exchangeName, String routingKey)
+ {
+ _session.exchangeUnbind(queueName, exchangeName, routingKey);
+ LOGGER.debug(Messages.QMAN_200030_BINDING_REMOVED,routingKey,queueName,exchangeName);
+ }
+
+ /**
+ * Sends a command message with the given data on the management queue.
+ *
+ * @param messageData the command message content.
+ */
+
+ /**
+ * Requests a schema for the given package.class.hash.
+ *
+ * @param packageName the package name.
+ * @param className the class name.
+ * @param schemaHash the schema hash.
+ * @throws IOException when the schema request cannot be sent.
+ */
+ public void requestSchema(final String packageName, final String className, final Binary schemaHash) throws IOException
+ {
+ Message message = new SchemaRequestMessage()
+ {
+ @Override
+ protected String className ()
+ {
+ return className;
+ }
+
+ @Override
+ protected String packageName ()
+ {
+ return packageName;
+ }
+
+ @Override
+ protected Binary schemaHash ()
+ {
+ return schemaHash;
+ }
+ };
+
+ sendMessage(message);
+ }
+
+ /**
+ * Invokes an operation on a broker object instance.
+ *
+ * @param packageName the package name.
+ * @param className the class name.
+ * @param schemaHash the schema hash of the corresponding class.
+ * @param objectId the object instance identifier.
+ * @param parameters the parameters for this invocation.
+ * @param method the method (definition) invoked.
+ * @param bankId the object bank identifier.
+ * @param brokerId the broker identifier.
+ * @return the sequence number used for this message.
+ * @throws MethodInvocationException when the invoked method returns an error code.
+ * @throws UnableToComplyException when it wasn't possibile to invoke the requested operation.
+ */
+ public void invoke(
+ final String packageName,
+ final String className,
+ final Binary schemaHash,
+ final Binary objectId,
+ final Object[] parameters,
+ final QpidMethod method,
+ final int sequenceNumber,
+ final long bankId,
+ final long brokerId) throws MethodInvocationException, UnableToComplyException
+ {
+ Message message = new MethodInvocationRequestMessage(bankId, brokerId)
+ {
+
+ @Override
+ protected int sequenceNumber ()
+ {
+ return sequenceNumber;
+ }
+
+ protected Binary objectId() {
+ return objectId;
+ }
+
+ protected String packageName()
+ {
+ return packageName;
+ }
+
+ protected String className()
+ {
+ return className;
+ }
+
+ @Override
+ protected QpidMethod method ()
+ {
+ return method;
+ }
+
+ @Override
+ protected Object[] parameters ()
+ {
+ return parameters;
+ }
+
+ @Override
+ protected Binary schemaHash ()
+ {
+ return schemaHash;
+ }
+ };
+
+ try {
+ sendMessage(message);
+ sync();
+ } catch(Exception exception) {
+ throw new UnableToComplyException(exception);
+ }
+ }
+
+ /**
+ * Sends a command message.
+ *
+ * @param message the command message.
+ * @throws IOException when the message cannot be sent.
+ */
+ public void sendMessage(Message message) throws IOException
+ {
+ _session.messageTransfer(
+ Names.MANAGEMENT_EXCHANGE,
+ MessageAcceptMode.EXPLICIT,
+ MessageAcquireMode.PRE_ACQUIRED,
+ message.getHeader(),
+ message.readData());
+ }
+}
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/services/SequenceNumberGenerator.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/services/SequenceNumberGenerator.java
new file mode 100644
index 0000000000..e6d99971cd
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/services/SequenceNumberGenerator.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.management.domain.services;
+
+/**
+ * Sequence number generator utility class.
+ *
+ * @author Andrea Gazzarini
+ */
+public class SequenceNumberGenerator
+{
+ private static int sequenceNumber;
+
+ /**
+ * Returns a valid sequence number.
+ *
+ * @return a sequence number.
+ */
+ public static synchronized int getNextSequenceNumber()
+ {
+ return sequenceNumber++;
+ }
+}
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/services/StartupFailureException.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/services/StartupFailureException.java
new file mode 100644
index 0000000000..9da8832624
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/services/StartupFailureException.java
@@ -0,0 +1,42 @@
+/*
+ *
+ * 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.domain.services;
+
+/**
+ * Thrown in case of service startup failure.
+ * For example the configuration file couldn't be read because is not well-formed.
+ *
+ * @author Andrea Gazzarini.
+ */
+public class StartupFailureException extends Exception
+{
+ private static final long serialVersionUID = -4102037574602857703L;
+
+ /**
+ * Builds a new StartupFailureException with the given exception.
+ *
+ * @param exception the exception cause.
+ */
+ public StartupFailureException(Exception exception)
+ {
+ super(exception);
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/services/UnableToComplyException.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/services/UnableToComplyException.java
new file mode 100644
index 0000000000..2ab9a41e75
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/services/UnableToComplyException.java
@@ -0,0 +1,31 @@
+/*
+ *
+ * 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.domain.services;
+
+public class UnableToComplyException extends Exception
+{
+ public UnableToComplyException(Exception exception)
+ {
+ super(exception);
+ }
+
+ private static final long serialVersionUID = -3071434478559509435L;
+}
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/jmx/EntityLifecycleNotification.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/jmx/EntityLifecycleNotification.java
new file mode 100644
index 0000000000..d7f9d8d6f0
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/jmx/EntityLifecycleNotification.java
@@ -0,0 +1,147 @@
+/*
+ *
+ * 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.jmx;
+
+import javax.management.Notification;
+import javax.management.ObjectName;
+
+import org.apache.qpid.management.Names;
+import org.apache.qpid.management.domain.services.SequenceNumberGenerator;
+
+/**
+ * Q-Man JMX entity lifecycle notification.
+ * A notification is sent to interested listener by Q-Man on the following scenarios :
+ *
+ * <br> - A schema (class / event) has been requested (Schema request);
+ * <br> - A schema (class / event) has been injected (Schema response);
+ * <br> - A schema cannot be parsed (probably it is malformed);
+ * <br> - An object instance has been created (Instrumentation / Configuration response);
+ * <br> - An event instance has been created (Instrumentation / Configuration response);
+ * <br> - An object instance has been removed (Instrumentation / Configuration response);
+ *
+ * @author Andrea Gazzarini
+ */
+public class EntityLifecycleNotification extends Notification
+{
+ private static final long serialVersionUID = -7755773156742412161L;
+
+ public static final String SCHEMA_INJECTED_NOTIFICATION_TYPE = "org.apache.qpid.management.lifecycle.entity.schema.injected";
+ public static final String SCHEMA_REQUESTED_NOTIFICATION_TYPE = "org.apache.qpid.management.lifecycle.entity.schema.requested";
+ public static final String MALFORMED_SCHEMA_NOTIFICATION_TYPE = "org.apache.qpid.management.lifecycle.error.schema";
+
+ public static final String INSTANCE_ADDED_NOTIFICATION_TYPE = "qman.lifecycle.entity.instance.created";
+ public static final String INSTANCE_REMOVED_NOTIFICATION_TYPE = "qman.lifecycle.entity.instance.removed";
+
+ private String _packageName = Names.NOT_AVAILABLE;
+ private String _className = Names.NOT_AVAILABLE;
+ private String _classKind = Names.NOT_AVAILABLE;
+
+ private ObjectName _objectName;
+
+ /**
+ * Builds a new notification with the given parameters.
+ *
+ * @param type the notification type.
+ * @param sequenceNumber the sequence number.
+ * @param packageName the package name.
+ * @param className the class name.
+ * @param classKind the class kind (i.e. class or event)
+ * @param objectName the object name of the affected mbean.
+ */
+ public EntityLifecycleNotification(
+ String type,
+ String packageName,
+ String className,
+ String classKind,
+ ObjectName objectName)
+ {
+ super(
+ type,
+ Names.APPLICATION_NAME,
+ SequenceNumberGenerator.getNextSequenceNumber());
+
+ this._className = className;
+ this._packageName = packageName;
+ this._classKind = classKind;
+ this._objectName = objectName;
+ }
+
+ /**
+ * Returns the package name of object contained in this notification.
+ *
+ * @return the package name of object contained in this notification.
+ */
+ public String getPackageName()
+ {
+ return _packageName;
+ }
+
+ /**
+ * Returns the class name of object contained in this notification.
+ *
+ * @return the class name of object contained in this notification.
+ */
+ public String getClassName()
+ {
+ return _className;
+ }
+
+ /**
+ * Returns the class kind of object contained in this notification.
+ *
+ * @return the class kind of object contained in this notification.
+ * @see Names#CLASS
+ * @see Names#EVENT
+ */
+ public String getClassKind()
+ {
+ return _classKind;
+ }
+
+ /**
+ * Returns the object name of object contained in this notification.
+ *
+ * @return the object name of object contained in this notification.
+ */
+ public ObjectName getObjectName()
+ {
+ return _objectName;
+ }
+
+ /**
+ * Returns a string representation of this notification.
+ *
+ * @return a string representation of this notification.
+ */
+ @Override
+ public String toString()
+ {
+ return new StringBuilder()
+ .append(getType())
+ .append(':')
+ .append(_packageName)
+ .append('.')
+ .append(_className)
+ .append('@')
+ .append(_objectName)
+ .toString();
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/jmx/OperationHasBeenInvokedNotification.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/jmx/OperationHasBeenInvokedNotification.java
new file mode 100644
index 0000000000..dec29c1b93
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/jmx/OperationHasBeenInvokedNotification.java
@@ -0,0 +1,168 @@
+/*
+ *
+ * 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.jmx;
+
+import javax.management.Notification;
+
+import org.apache.qpid.management.Names;
+import org.apache.qpid.management.domain.handler.impl.InvocationResult;
+import org.apache.qpid.management.domain.services.SequenceNumberGenerator;
+
+/**
+ * Q-Man JMX method invocation notification.
+ * This kind of notification is sent to interested listener by Q-Man when
+ * a method has been invoked (Method invocation request)
+ *
+ * @author Andrea Gazzarini
+ */
+public class OperationHasBeenInvokedNotification extends Notification
+{
+ private static final long serialVersionUID = -7755773156742412161L;
+ public static final String NOTIFICATION_TYPE = "org.apache.qpid.management.operation.invoked";
+
+ private final String _operationName;
+ private final Object [] _parameters;
+ private final String [] _signature;
+ private final Exception _exception;
+ private final InvocationResult _result;
+
+ /**
+ * Builds a new notification with the given parameters.
+ *
+ * @param type the notification type.
+ * @param operationName the operation name.
+ * @param params the operation parameters.
+ * @param signature the operation signature.
+ * @param exception the exception raised by the invocation.
+ */
+ public OperationHasBeenInvokedNotification(
+ String operationName,
+ Object[] parameters,
+ String [] signature,
+ Exception exception)
+ {
+ super(
+ NOTIFICATION_TYPE,
+ Names.APPLICATION_NAME,
+ SequenceNumberGenerator.getNextSequenceNumber());
+
+ this._operationName= operationName;
+ this._parameters = parameters;
+ this._signature = signature;
+ this._result = null;
+ this._exception = exception;
+ }
+
+ /**
+ * Builds a new notification with the given parameters.
+ *
+ * @param type the notification type.
+ * @param operationName the operation name.
+ * @param params the operation parameters.
+ * @param signature the operation signature.
+ * @param objectName the target mbean object name.
+ * @param result the invocation result.
+ */
+ public OperationHasBeenInvokedNotification(
+ String operationName,
+ Object[] parameters,
+ String [] signature,
+ InvocationResult result)
+ {
+ super(
+ NOTIFICATION_TYPE,
+ Names.APPLICATION_NAME,
+ SequenceNumberGenerator.getNextSequenceNumber());
+
+ this._operationName= operationName;
+ this._parameters = parameters;
+ this._signature = signature;
+ this._result = result;
+ this._exception = null;
+ }
+
+ /**
+ * Returns the exception raised by this notification
+ * referred operation.
+ *
+ * @return the exception raised by this notification referred operation.
+ */
+ public Exception getException()
+ {
+ return _exception;
+ }
+
+ /**
+ * Returns the exception raised by this notification
+ * referred operation.
+ *
+ * @return the exception raised by this notification referred operation.
+ */
+ public InvocationResult getResult()
+ {
+ return _result;
+ }
+
+ /**
+ * Returns the operation name.
+ *
+ * @return the operation name.
+ */
+ public String getOperationName()
+ {
+ return _operationName;
+ }
+
+ /**
+ * Returns the parameters used in method invocation.
+ *
+ * @return the parameters used in method invocation.
+ */
+ public Object [] getParameters()
+ {
+ return _parameters;
+ }
+
+ /**
+ * Returns the signature of the invoked operation.
+ *
+ * @return the signature of the invoked operation.
+ */
+ public String [] getSignature()
+ {
+ return _signature;
+ }
+
+ /**
+ * Returns a string representation of this notification.
+ *
+ * @return a string representation of this notification.
+ */
+ @Override
+ public String toString()
+ {
+ return new StringBuilder()
+ .append(getType())
+ .append(':')
+ .append(_operationName)
+ .toString();
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/messages/ManagementMessage.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/messages/ManagementMessage.java
new file mode 100644
index 0000000000..2fa20fb456
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/messages/ManagementMessage.java
@@ -0,0 +1,189 @@
+/*
+ *
+ * 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.messages;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+
+import org.apache.qpid.api.Message;
+import org.apache.qpid.management.configuration.Configuration;
+import org.apache.qpid.management.domain.services.SequenceNumberGenerator;
+import org.apache.qpid.transport.DeliveryProperties;
+import org.apache.qpid.transport.Header;
+import org.apache.qpid.transport.MessageProperties;
+import org.apache.qpid.transport.codec.BBEncoder;
+
+/**
+ * Message implementation used for specific management purposes.
+ *
+ * @author Andrea Gazzarini
+ */
+public abstract class ManagementMessage implements Message
+{
+ /**
+ * Strategy interface for building / getting data.
+ *
+ * @author Andrea Gazzarini
+ */
+ private interface IDataBuilderStrategy
+ {
+ ByteBuffer getData();
+ };
+
+ /**
+ * Strategy used for retrieving raw data from this message when it has been already encoded.
+ */
+ IDataBuilderStrategy READING = new IDataBuilderStrategy()
+ {
+ public ByteBuffer getData() {
+ return _data;
+ };
+ };
+
+ /**
+ * Strategy used for retrieving raw data from this message when it hasn't been already encoded.
+ */
+ IDataBuilderStrategy ACCUMULATING = new IDataBuilderStrategy()
+ {
+ public ByteBuffer getData() {
+ _codec.writeInt8((byte)opcode());
+ _codec.writeSequenceNo(sequenceNumber());
+
+ specificMessageEncoding();
+
+ _data =_codec.segment();
+ _reader = READING;
+ return _data;
+ }
+ };
+
+ protected BBEncoder _codec;
+ protected ByteBuffer _data;
+ private int _messageTransferId;
+ private IDataBuilderStrategy _reader = ACCUMULATING;
+
+ /**
+ * Builds an empty management message.
+ */
+ ManagementMessage()
+ {
+ _codec = new BBEncoder(100);
+ _codec.writeMagicNumber();
+ }
+
+ /**
+ * Returns the sequence number that will be used for this message.
+ *
+ * @return the sequence number that will be used for this message.
+ */
+ protected int sequenceNumber ()
+ {
+ return SequenceNumberGenerator.getNextSequenceNumber();
+ }
+
+ /**
+ * Returns the opcode that will be used for this message.
+ *
+ * @return the opcode that will be used for this message.
+ */
+ abstract char opcode ();
+
+ /**
+ * Returns the delivery properties of this message.
+ *
+ * @return the delivery properties of this message.
+ */
+ public DeliveryProperties getDeliveryProperties ()
+ {
+ return Configuration.getInstance().getCommandDeliveryProperties();
+ }
+
+ /**
+ * Returns the header of this message.
+ *
+ * @return the header of this message.
+ */
+ public Header getHeader ()
+ {
+ return Configuration.getInstance().getCommandMessageHeader();
+ }
+
+ /**
+ * Returns the messages header properties of this message.
+ *
+ * @return the message header properties of this message.
+ */
+ public MessageProperties getMessageProperties ()
+ {
+ return Configuration.getInstance().getCommandMessageProperties();
+ }
+
+ /**
+ * Returns the transfer Id of this message.
+ *
+ * @return the transfer Id of this message.
+ */
+ public int getMessageTransferId ()
+ {
+ return _messageTransferId;
+ }
+
+ /**
+ * Returns the encoded data of this message.
+ *
+ * @return the encoded data of this message.
+ */
+ public ByteBuffer readData () throws IOException
+ {
+ return _reader.getData();
+ }
+
+ /**
+ * Sets the header for this message.
+ *
+ * @param header the new message header.
+ */
+ public void setHeader (Header header)
+ {
+ // N.A. at the moment.
+ }
+
+ public void appendData (byte[] src) throws IOException
+ {
+ }
+
+ public void appendData (ByteBuffer src) throws IOException
+ {
+ }
+
+ public void clearData ()
+ {
+ }
+
+ public void readData (byte[] target) throws IOException
+ {
+ }
+
+ /**
+ * Concrete subclasses (message implementations) must define here their specific data encoding.
+ */
+ abstract void specificMessageEncoding();
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/messages/MethodInvocationRequestMessage.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/messages/MethodInvocationRequestMessage.java
new file mode 100644
index 0000000000..99916085d6
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/messages/MethodInvocationRequestMessage.java
@@ -0,0 +1,161 @@
+/*
+ *
+ * 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.messages;
+
+import org.apache.qpid.management.Messages;
+import org.apache.qpid.management.Names;
+import org.apache.qpid.management.Protocol;
+import org.apache.qpid.management.configuration.Configuration;
+import org.apache.qpid.management.domain.model.QpidMethod;
+import org.apache.qpid.management.domain.model.type.Binary;
+import org.apache.qpid.transport.DeliveryProperties;
+import org.apache.qpid.transport.Header;
+import org.apache.qpid.transport.MessageProperties;
+import org.apache.qpid.transport.ReplyTo;
+import org.apache.qpid.transport.util.Logger;
+
+/**
+ * Abstract representation of a method invocation request message.
+ * Concrete subclasses must supply the values needed to build & encode the message.
+ *
+ * @author Andrea Gazzarini
+ */
+public abstract class MethodInvocationRequestMessage extends ManagementMessage
+{
+ private final static Logger LOGGER = Logger.get(MethodInvocationRequestMessage.class);
+
+ private DeliveryProperties _deliveryProperties;
+ private MessageProperties _messageProperties;
+ private Header _header;
+
+ /**
+ * Builds a new method invocation request message with the given target identifiers.
+ *
+ * @param bankId the bank identifier.
+ * @param brokerId the broker identifier.
+ */
+ public MethodInvocationRequestMessage(long bankId, long brokerId)
+ {
+ ReplyTo replyTo=new ReplyTo();
+ replyTo.setRoutingKey(Configuration.getInstance().getMethodReplyQueueName());
+ _messageProperties = new MessageProperties();
+ _messageProperties.setReplyTo(replyTo);
+
+ String routingKey = String.format(Names.AGENT_ROUTING_KEY_PREFIX+"%s.%s", brokerId,bankId);
+
+ LOGGER.debug(Messages.QMAN_200032_COMMAND_MESSAGE_ROUTING_KEY, routingKey);
+
+ _deliveryProperties = new DeliveryProperties();
+ _deliveryProperties.setRoutingKey(routingKey);
+ _header = new Header(_deliveryProperties, _messageProperties);
+ }
+
+ @Override
+ char opcode ()
+ {
+ return Protocol.OPERATION_INVOCATION_REQUEST_OPCODE;
+ }
+
+ /**
+ * Returns the package name.
+ *
+ * @return the package name.
+ */
+ protected abstract String packageName();
+
+ /**
+ * Returns the class name.
+ *
+ * @return the class name.
+ */
+ protected abstract String className();
+
+ /**
+ * Returns the schema hash.
+ *
+ * @return the schema hash.
+ */
+ protected abstract Binary schemaHash();
+
+ /**
+ * Returns the object identifier.
+ *
+ * @return the object identifier.
+ */
+ protected abstract Binary objectId();
+
+ /**
+ * Returns the method to be invoked.
+ *
+ * @return the method to be invoked.
+ */
+ protected abstract QpidMethod method();
+
+ /**
+ * Returns the parameters used for method invocation.
+ *
+ * @return the parameters used for method invocation.
+ */
+ protected abstract Object[] parameters();
+
+ /**
+ * Returns the delivery properties of this message.
+ *
+ * @return the delivery properties of this message.
+ */
+ public DeliveryProperties getDeliveryProperties ()
+ {
+ return _deliveryProperties;
+ }
+
+ /**
+ * Returns the header of this message.
+ *
+ * @return the header of this message.
+ */
+ public Header getHeader ()
+ {
+ return _header;
+ }
+
+ /**
+ * Returns the messages header properties of this message.
+ *
+ * @return the message header properties of this message.
+ */
+ public MessageProperties getMessageProperties ()
+ {
+ return _messageProperties;
+ }
+
+ @Override
+ void specificMessageEncoding ()
+ {
+ objectId().encode(_codec);
+ _codec.writeStr8(packageName());
+ _codec.writeStr8(className());
+ schemaHash().encode(_codec);
+
+ QpidMethod method = method();
+ _codec.writeStr8(method.getName());
+ method.encodeParameters(parameters(), _codec);
+ }
+}
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/messages/SchemaRequestMessage.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/messages/SchemaRequestMessage.java
new file mode 100644
index 0000000000..9df1733649
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/messages/SchemaRequestMessage.java
@@ -0,0 +1,68 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.management.messages;
+
+import org.apache.qpid.management.Protocol;
+import org.apache.qpid.management.domain.model.type.Binary;
+
+/**
+ * Abstract representation of a schema request message.
+ * Concrete subclasses must supply the values needed to build & encode the message.
+ *
+ * @author Andrea Gazzarini
+ */
+public abstract class SchemaRequestMessage extends ManagementMessage
+{
+ @Override
+ char opcode ()
+ {
+ return Protocol.SCHEMA_REQUEST_OPCODE;
+ }
+
+ /**
+ * Returns the package name.
+ *
+ * @return the package name.
+ */
+ protected abstract String packageName();
+
+ /**
+ * Returns the class name.
+ *
+ * @return the class name.
+ */
+ protected abstract String className();
+
+ /**
+ * Returns the schema hash.
+ *
+ * @return the schema hash.
+ */
+ protected abstract Binary schemaHash();
+
+ @Override
+ final void specificMessageEncoding ()
+ {
+ _codec.writeStr8(packageName());
+ _codec.writeStr8(className());
+ schemaHash().encode(_codec);
+ }
+}
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/servlet/ConnectQManToBroker.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/servlet/ConnectQManToBroker.java
new file mode 100644
index 0000000000..8f73098e20
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/servlet/ConnectQManToBroker.java
@@ -0,0 +1,89 @@
+/*
+ *
+ * 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.servlet;
+
+import java.util.UUID;
+import java.util.Map.Entry;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.muse.core.platform.mini.MiniServlet;
+import org.apache.qpid.management.Messages;
+import org.apache.qpid.management.Names;
+import org.apache.qpid.management.configuration.BrokerConnectionData;
+import org.apache.qpid.management.configuration.Configuration;
+import org.apache.qpid.management.domain.services.QMan;
+import org.apache.qpid.transport.util.Logger;
+
+/**
+ * When QMan is started and a configuration file is given
+ * (via system property) with initial broker connection data(s),
+ * this servlet simply sends connect command(s) to QMan in order
+ * to estabilish the connection(s) to the requested broker(s).
+ *
+ * @author Andrea Gazzarini
+ */
+public class ConnectQManToBroker extends MiniServlet
+{
+ private static final long serialVersionUID = 6149614872902682208L;
+ private final static Logger LOGGER = Logger.get(ConnectQManToBroker.class);
+
+ /**
+ * Send one or more initial "connect" command(s) to QMan in order
+ * to estabilish a connection with broker found on the configuration file..
+ * Note that this is done only if that configuration file is given (via system
+ * property) and it is valid.
+ */
+ public void init()
+ {
+ Configuration configuration = Configuration.getInstance();
+ if (configuration.hasOneOrMoreBrokersDefined())
+ {
+ QMan qman = (QMan)getServletContext().getAttribute(Names.APPLICATION_NAME);
+
+ LOGGER.info(Messages.QMAN_000003_CREATING_MANAGEMENT_CLIENTS);
+ for (Entry<UUID, BrokerConnectionData> entry : Configuration.getInstance().getConnectionInfos())
+ {
+ qman.createManagementClient(entry.getKey(), entry.getValue());
+ }
+ } else
+ {
+ LOGGER.info(Messages.QMAN_000022_NO_BROKER_CONFIGURED);
+ }
+ }
+
+ /**
+ * This is a startup module only so an override of the default servlet
+ * behaviour must be done in order to prevent incoming http
+ * requests processing.
+ *
+ * @param request the http request.
+ * @param response the http response.
+ * @throws ServletException each time this method is called.
+ */
+ @Override
+ public void service(HttpServletRequest request, HttpServletResponse response) throws ServletException
+ {
+ throw new ServletException();
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/servlet/QManLifeCycleManager.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/servlet/QManLifeCycleManager.java
new file mode 100644
index 0000000000..edd6804e68
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/servlet/QManLifeCycleManager.java
@@ -0,0 +1,79 @@
+/*
+ *
+ * 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.servlet;
+
+import javax.servlet.ServletContext;
+import javax.servlet.ServletContextEvent;
+import javax.servlet.ServletContextListener;
+
+import org.apache.qpid.management.Messages;
+import org.apache.qpid.management.Names;
+import org.apache.qpid.management.domain.services.QMan;
+import org.apache.qpid.management.domain.services.StartupFailureException;
+import org.apache.qpid.transport.util.Logger;
+
+/**
+ * QMan JMX lifecycle manager.
+ * Provides lifecycle management of QMan JMX core including startup and shutdown.
+ *
+ * @author Andrea Gazzarini
+ */
+public class QManLifeCycleManager implements ServletContextListener
+{
+ private final static Logger LOGGER = Logger.get(QManLifeCycleManager.class);
+
+ /**
+ * Starts QMan JMX Core.
+ *
+ * @param event the application context event.
+ */
+ public void contextInitialized(ServletContextEvent event)
+ {
+ try
+ {
+ QMan qman = new QMan();
+ qman.start();
+ event.getServletContext().setAttribute(
+ Names.APPLICATION_NAME,
+ qman);
+ } catch (StartupFailureException exception)
+ {
+ LOGGER.error(
+ exception,
+ Messages.QMAN_100030_JMX_CORE_STARTUP_FAILURE);
+ }
+ }
+
+ /**
+ * Sutdown QMan JMX Core.
+ *
+ * @param event the application context event.
+ */
+ public void contextDestroyed(ServletContextEvent event)
+ {
+ ServletContext context = event.getServletContext();
+
+ QMan qman = (QMan) context.getAttribute(Names.APPLICATION_NAME);
+ qman.stop();
+
+ context.removeAttribute(Names.APPLICATION_NAME);
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/servlet/WSDMAdapter.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/servlet/WSDMAdapter.java
new file mode 100644
index 0000000000..c6fcde08c4
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/servlet/WSDMAdapter.java
@@ -0,0 +1,109 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.management.servlet;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.muse.util.xml.XmlUtils;
+import org.apache.qpid.management.Messages;
+import org.apache.qpid.management.wsdm.muse.engine.WSDMAdapterIsolationLayer;
+import org.apache.qpid.qman.debug.XmlDebugger;
+import org.apache.qpid.transport.util.Logger;
+import org.w3c.dom.Document;
+import org.xml.sax.SAXException;
+
+/**
+ * QMan Adapter facade.
+ * This is the main requestor entry point of the WS-DM connector / adapter.
+ * All WSDM requests will be handled (at higher level) by this servlet.
+ *
+ * @author Andrea Gazzarini
+ */
+public class WSDMAdapter extends HttpServlet
+{
+ private static final long serialVersionUID = 6149614872902682208L;
+ private final static Logger LOGGER = Logger.get(WSDMAdapter.class);
+ private WSDMAdapterIsolationLayer _isolationLayer;
+
+ @Override
+ public void init() throws ServletException {
+ LOGGER.debug(Messages.QMAN_000026_WSDM_ADAPTER_STARTS);
+
+ _isolationLayer = new WSDMAdapterIsolationLayer(getServletContext());
+ _isolationLayer.initialize();
+
+ LOGGER.debug(Messages.QMAN_000027_WSDM_ADAPTER_STARTED);
+
+ }
+
+ /**
+ * Accepts http requests containing a soap envelope (request) and therefore
+ * acts as the main entry point of whole WS process.
+ *
+ * @param request the http request.
+ * @param response the http response.
+ * @throws ServletException in case of application failure.
+ * @throws IOException in case of generic I/O failure.
+ */
+ @Override
+ protected void doPost(HttpServletRequest request,HttpServletResponse response) throws ServletException,IOException
+ {
+ PrintWriter writer = response.getWriter();
+
+ Document soapEnvelopeRequest = null;
+ String soapEnvelopeResposeAsString = null;
+
+ try
+ {
+ soapEnvelopeRequest = XmlUtils.createDocument(request.getInputStream());
+
+ Document soapEnvelopeResponse = _isolationLayer.handleRequest(soapEnvelopeRequest);
+ soapEnvelopeResposeAsString = XmlUtils.toString(soapEnvelopeResponse,false,true);
+
+ response.setContentType("text/xml");
+
+ writer.write(soapEnvelopeResposeAsString);
+ } catch (SAXException exception)
+ {
+ LOGGER.error(
+ exception,
+ Messages.QMAN_100019_REQ_OR_RES_MALFORMED);
+ throw new ServletException(exception);
+ } finally {
+ writer.flush();
+
+ XmlDebugger.debug(soapEnvelopeRequest);
+ try {
+ XmlDebugger.debug(soapEnvelopeResposeAsString);
+ } catch(Exception exception) {
+ LOGGER.error(
+ exception,
+ Messages.QMAN_100019_REQ_OR_RES_MALFORMED);
+ }
+ }
+ }
+} \ No newline at end of file
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
new file mode 100644
index 0000000000..09b7309b96
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/web/action/BrokerModel.java
@@ -0,0 +1,100 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.management.web.action;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+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;
+
+ /**
+ * 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);
+ String className = name.getKeyProperty(Names.CLASS);
+ if (className != null)
+ {
+ String fqn = packageName+"."+className;
+
+ List<ObjectName> objects = _objectsByType.get(fqn);
+ if (objects == null)
+ {
+ objects = new ArrayList<ObjectName>();
+ _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;
+ }
+
+ /**
+ * 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;
+ }
+
+ public Set<String> getCategoryNames()
+ {
+ return _objectsByType.keySet();
+ }
+
+ public List<ObjectName> getCategory(String name)
+ {
+ return _objectsByType.get(name);
+ }
+
+ public int getCategoryCount()
+ {
+ 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
new file mode 100644
index 0000000000..509c86c08b
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/web/action/BrokersManagementAction.java
@@ -0,0 +1,204 @@
+/*
+ *
+ * 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.web.action;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.List;
+
+import javax.servlet.RequestDispatcher;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+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.domain.services.ManagementClient;
+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.
+ * </ul>
+ *
+ * @author Andrea Gazzarini
+ */
+public class BrokersManagementAction extends HttpServlet
+{
+ private static final long serialVersionUID = -2411413147821629363L;
+
+ /**
+ * 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
+ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
+ {
+ try
+ {
+ QMan qman = (QMan)getServletContext().getAttribute(Names.APPLICATION_NAME);
+ List<ManagementClient> managementClients = qman.getManagementClients();
+
+ List<BrokerConnectionData> brokers = new ArrayList<BrokerConnectionData>(managementClients.size());
+
+ if (!managementClients.isEmpty())
+ {
+ for (ManagementClient managementClient : managementClients)
+ {
+ brokers.add(managementClient.getBrokerConnectionData());
+ }
+ request.setAttribute("model", brokers);
+ }
+
+ RequestDispatcher dispatcher = request.getRequestDispatcher("/brokers_management.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");
+ dispatcher.forward(request,response);
+ }
+ }
+
+ /**
+ * 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
+ protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
+ {
+ try
+ {
+ QMan qman = (QMan)getServletContext().getAttribute(Names.APPLICATION_NAME);
+
+ String host = request.getParameter("host");
+ String portString = request.getParameter("port");
+ String virtualHost = request.getParameter("virtualHost");
+ String username = request.getParameter("username");
+ String password = request.getParameter("password");
+
+ String initialCapacityString = request.getParameter("initialCapacity");
+ String maxCapacityString = request.getParameter("maxCapacity");
+ String maxWaitTimeoutString = request.getParameter("maxWaitTimeout");
+
+ List<String> errors = new LinkedList<String>();
+ int port = 0;
+ int initialPoolCapacity = 0;
+ int maxPoolCapacity = 0;
+ long maxWaitTimeout = 0;
+
+ if(host== null || host.trim().length()==0)
+ {
+ errors.add("Invalid value for \"host\" attribute. Must be not null.");
+ }
+
+ if(virtualHost == null || virtualHost.trim().length()==0)
+ {
+ errors.add("Invalid value for \"virtualHost\" attribute. Must be not null.");
+ }
+
+ 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
+ {
+ 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
+ {
+ 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
+ {
+ maxWaitTimeout = Long.parseLong(maxWaitTimeoutString);
+ } catch(Exception exception)
+ {
+ errors.add("Invalid value for \"Max Wait Timeout\" attribute. Must be not null and must be a number.");
+ }
+
+ request.setAttribute("errors", errors);
+
+ if (errors.isEmpty())
+ {
+ qman.addBroker(
+ host,
+ port,
+ username,
+ password,
+ virtualHost,
+ initialPoolCapacity,
+ maxPoolCapacity,
+ maxWaitTimeout);
+ }
+ doGet(request, response);
+ }catch(BrokerAlreadyConnectedException exception)
+ {
+ request.setAttribute("errorMessage","Supplied data refers to an already connected broker...");
+ RequestDispatcher dispatcher = request.getRequestDispatcher("/brokers_management.jsp");
+ dispatcher.forward(request,response);
+ }
+ catch(BrokerConnectionException exception)
+ {
+ request.setAttribute("errorMessage","Unable to connect with the requested broker...");
+ RequestDispatcher dispatcher = request.getRequestDispatcher("/brokers_management.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");
+ dispatcher.forward(request,response);
+ }
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/web/action/ConsoleAction.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/web/action/ConsoleAction.java
new file mode 100644
index 0000000000..ee098882f1
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/web/action/ConsoleAction.java
@@ -0,0 +1,117 @@
+/*
+ *
+ * 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.web.action;
+
+import java.io.File;
+import java.io.IOException;
+import java.lang.management.ManagementFactory;
+import java.lang.management.OperatingSystemMXBean;
+import java.lang.management.RuntimeMXBean;
+import java.util.Date;
+
+import javax.servlet.RequestDispatcher;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.qpid.management.Messages;
+import org.apache.qpid.management.Names;
+import org.apache.qpid.transport.util.Logger;
+
+/**
+ * This action is the controller responsible to prepare data for the home
+ * page (System Overview) of QMan admin console.
+ *
+ * @author Andrea Gazzarini
+ */
+public class ConsoleAction extends HttpServlet
+{
+ private static final long serialVersionUID = -2411413147821629363L;
+
+ private static final Logger LOGGER = Logger.get(ConsoleAction.class);
+
+ private Date _startDate;
+
+ /**
+ * Initializes this controller.
+ * Simply it computes the start date of the application.
+ */
+ @Override
+ public void init()
+ {
+ _startDate = new Date();
+ }
+
+ /**
+ * Prepares data for System Overview admin console page and forward that data to that page.
+ *
+ * @throws ServletException when this controller is not able to forward to the appropriate view page.
+ * @throws IOException when this controller is not able to forward to the appropriate view page.
+ */
+ @Override
+ protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
+ {
+ ConsoleModel model = new ConsoleModel();
+ model.setVersion("1.0");
+ model.setVersionName("Sofia");
+ model.setStartDate(_startDate);
+ model.setHost(System.getProperty(Names.ADAPTER_HOST_PROPERTY_NAME, "localhost"));
+ model.setPort(Integer.parseInt(System.getProperty(Names.ADAPTER_PORT_PROPERTY_NAME, "8080")));
+
+ try
+ {
+ OperatingSystemMXBean operatingSystem = ManagementFactory.getOperatingSystemMXBean();
+ model.setOsName(operatingSystem.getName());
+ model.setProcessors(operatingSystem.getAvailableProcessors());
+ model.setOsVersion(operatingSystem.getVersion());
+ model.setArchName(operatingSystem.getArch());
+ } catch(Exception exception)
+ {
+ LOGGER.warn(exception,Messages.QMAN_300006_OS_MBEAN_FAILURE);
+ model.setOsName("N.A.");
+ model.setProcessors(null);
+ model.setOsVersion("N.A.");
+ model.setArchName("N.A.");
+ }
+
+ try
+ {
+ RuntimeMXBean runtime = ManagementFactory.getRuntimeMXBean();
+
+ String bootClasspath = runtime.getBootClassPath();
+ model.setBootClasspath(bootClasspath.split(File.pathSeparator));
+
+ String classpath = runtime.getClassPath();
+ model.setClasspath(classpath.split(File.pathSeparator));
+
+ model.setInputArguments(runtime.getInputArguments().toArray(new String[]{}));
+ } catch(Exception exception)
+ {
+ LOGGER.warn(exception,Messages.QMAN_300007_RUNTIME_MBEAN_FAILURE);
+ }
+
+ request.setAttribute("model", model);
+
+ RequestDispatcher dispatcher = request.getRequestDispatcher("/console.jsp");
+ dispatcher.forward(request,response);
+ }
+}
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/web/action/ConsoleModel.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/web/action/ConsoleModel.java
new file mode 100644
index 0000000000..ac0e1d2bbd
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/web/action/ConsoleModel.java
@@ -0,0 +1,158 @@
+/*
+ *
+ * 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.web.action;
+
+import java.io.Serializable;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * Console Model.
+ * It is a simple Data Transfer Object encapsulating all information about QMan
+ * console (System Overview)
+ *
+ * @author Andrea Gazzarini
+ */
+public class ConsoleModel implements Serializable
+{
+ private static final long serialVersionUID = -7676132151242738376L;
+ private String _version;
+ private String _versionName;
+ private Date _startDate;
+ private String _host;
+ private int _port;
+
+ private String _osName;
+ private String _osVersion;
+ private String _archName;
+ private Integer _processors;
+
+ private String [] _bootClasspath;
+ private String [] _classpath;
+ private String [] _inputArguments;
+ private String [] _systemProperties;
+
+ public String getVersion()
+ {
+ return _version;
+ }
+ public void setVersion(String version)
+ {
+ this._version = version;
+ }
+ public String getVersionName()
+ {
+ return _versionName;
+ }
+ public void setVersionName(String versionName)
+ {
+ this._versionName = versionName;
+ }
+ public Date getStartDate()
+ {
+ return _startDate;
+ }
+ public void setStartDate(Date startDate)
+ {
+ this._startDate = startDate;
+ }
+ public String getHost()
+ {
+ return _host;
+ }
+ public void setHost(String host)
+ {
+ this._host = host;
+ }
+ public int getPort()
+ {
+ return _port;
+ }
+ public void setPort(int port)
+ {
+ this._port = port;
+ }
+ public String getOsName()
+ {
+ return _osName;
+ }
+ public void setOsName(String osName)
+ {
+ this._osName = osName;
+ }
+ public String getOsVersion()
+ {
+ return _osVersion;
+ }
+ public void setOsVersion(String osVersion)
+ {
+ this._osVersion = osVersion;
+ }
+ public String getArchName()
+ {
+ return _archName;
+ }
+ public void setArchName(String archName)
+ {
+ this._archName = archName;
+ }
+ public Integer getProcessors()
+ {
+ return _processors;
+ }
+ public void setProcessors(Integer processors)
+ {
+ this._processors = processors;
+ }
+ public List<String> getBootClasspath()
+ {
+ return Arrays.asList(_bootClasspath);
+ }
+ public void setBootClasspath(String [] bootClasspath)
+ {
+ this._bootClasspath = bootClasspath;
+ }
+ public String [] getClasspath()
+ {
+ return _classpath;
+ }
+ public void setClasspath(String [] classpath)
+ {
+ this._classpath = classpath;
+ }
+ public String [] getInputArguments()
+ {
+ return _inputArguments;
+ }
+ public void setInputArguments(String [] inputArguments)
+ {
+ this._inputArguments = inputArguments;
+ }
+ public String [] getSystemProperties()
+ {
+ return _systemProperties;
+ }
+ public void setSystemProperties(String [] systemProperties)
+ {
+ this._systemProperties = systemProperties;
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/web/action/JmxPerspectiveAction.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/web/action/JmxPerspectiveAction.java
new file mode 100644
index 0000000000..59777cc9c8
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/web/action/JmxPerspectiveAction.java
@@ -0,0 +1,189 @@
+/*
+ *
+ * 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.web.action;
+
+import java.io.IOException;
+import java.lang.management.ManagementFactory;
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Map.Entry;
+
+import javax.management.MBeanAttributeInfo;
+import javax.management.MBeanInfo;
+import javax.management.MBeanServer;
+import javax.management.MalformedObjectNameException;
+import javax.management.ObjectName;
+import javax.servlet.RequestDispatcher;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+/**
+ * This controller is responsible to provide a jmx perspective of a specific resource.
+ * That means that this controller is querying the Platform MBean server in order to
+ * get metadata for the requested mbean.
+ *
+ * After that metadata will be forwarded to the appropriate view page and therefore
+ * will be shown on the Admin console.
+ *
+ * @author Andrea Gazzarini
+ */
+public class JmxPerspectiveAction extends HttpServlet
+{
+ private static final long serialVersionUID = -2411413147821629363L;
+
+ /**
+ * Adapter interface for converting objects on html strings.
+ *
+ * @author Andrea Gazzarini.
+ */
+ interface JavaToHtmlAdapter
+ {
+ /**
+ * Returns an HTML string representation of the given object.
+ *
+ * @param javaObject the object that needs to be converted.
+ * @return an html string containing value of the given object.
+ */
+ String toHtml(Object javaObject);
+ }
+
+ /**
+ * Adapter implementation for Map (and subclasses).
+ */
+ private JavaToHtmlAdapter mapAdapter = new JavaToHtmlAdapter()
+ {
+ @SuppressWarnings("unchecked")
+ public String toHtml(Object javaObject)
+ {
+ Map<String,Object> value = (Map<String, Object>) javaObject;
+
+ // Sanity check : if the map is empty or null there's no need to
+ // do any convertion
+ if (value == null || value.isEmpty())
+ {
+ return "(empty)";
+ }
+
+ StringBuilder builder = new StringBuilder("<ul>");
+ for (Entry<String, Object> entry : value.entrySet())
+ {
+ builder
+ .append("<li>")
+ .append(entry.getKey())
+ .append(" = ")
+ .append(entry.getValue());
+ }
+ builder.append("</ul>");
+ return builder.toString();
+ }
+ };
+
+ private Map<String, JavaToHtmlAdapter> _adapters = new HashMap<String, JavaToHtmlAdapter>();
+
+ @Override
+ public void init() throws ServletException
+ {
+ _adapters.put(Map.class.getName(), mapAdapter);
+ _adapters.put(HashMap.class.getName(),mapAdapter);
+ _adapters.put(Properties.class.getName(),mapAdapter);
+ _adapters.put(Hashtable.class.getName(),mapAdapter);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
+ {
+ String resourceId = null;
+ try
+ {
+ resourceId = request.getParameter("resourceId");
+
+ ObjectName objectName = new ObjectName(resourceId);
+ String [] keyProperties = objectName.getKeyPropertyListString().split(",");
+
+ MBeanServer server = ManagementFactory.getPlatformMBeanServer();
+
+ MBeanInfo metadata = server.getMBeanInfo(objectName);
+
+ Map<String, String> attributes = getAttributes(server, objectName,metadata.getAttributes());
+
+ request.setAttribute("resourceId", objectName);
+ request.setAttribute("metadata",metadata);
+ request.setAttribute("nameAttributes",keyProperties);
+ request.setAttribute("attributes",attributes);
+
+ RequestDispatcher dispatcher = request.getRequestDispatcher("/jmx_perspective.jsp");
+ dispatcher.forward(request,response);
+ } catch(MalformedObjectNameException exception)
+ {
+ request.setAttribute("errorMessage","Malformed Resource ID : supplied value is "+resourceId);
+ request.setAttribute("exception",exception);
+ RequestDispatcher dispatcher = request.getRequestDispatcher("/error_page.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");
+ dispatcher.forward(request,response);
+ }
+ }
+
+ /**
+ * Starting from an mbean metadata, this method retrieves all the attributes
+ * from the corresponding MBean Server.
+ *
+ * @param server the mbean server where the target mbean is registered.
+ * @param name the name of the target mbean.
+ * @param metadata the metadata of mbean.
+ * @return a map containing all attributes of the given mbean.
+ * @throws Exception when it's not possible to retrieve attributes.
+ */
+ private Map<String, String> getAttributes(MBeanServer server, ObjectName name, MBeanAttributeInfo [] metadata) throws Exception
+ {
+ Map<String,String> result = new HashMap<String, String>(metadata.length);
+ for (MBeanAttributeInfo attribute : metadata)
+ {
+ Object value = server.getAttribute(name, attribute.getName());
+ result.put(attribute.getName(),getAdaptedValue(attribute.getType(), value));
+ }
+ return result;
+ }
+
+ /**
+ * Converts the given attribute value in a html string format.
+ *
+ * @param type the java type of the given attribute value.
+ * @param value the attribute value.
+ * @return a html string format of the given value.
+ */
+ private String getAdaptedValue(String type, Object value)
+ {
+ JavaToHtmlAdapter adapter = _adapters.get(type);
+ return (adapter != null) ? adapter.toHtml(value) : String.valueOf(value);
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/web/action/LoggingConfigurationAction.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/web/action/LoggingConfigurationAction.java
new file mode 100644
index 0000000000..aefd4ca8dd
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/web/action/LoggingConfigurationAction.java
@@ -0,0 +1,114 @@
+/*
+ *
+ * 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.web.action;
+
+import java.io.IOException;
+
+import javax.servlet.RequestDispatcher;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.log4j.Level;
+import org.apache.log4j.Logger;
+import org.apache.qpid.qman.debug.WsdlDebugger;
+import org.apache.qpid.qman.debug.XmlDebugger;
+
+/**
+ * Logging configuration controller.
+ * Accepts input parameters from admin console and configure the underlying
+ * logging subsystem at runtime.
+ *
+ * @author Andrea Gazzarini
+ */
+public class LoggingConfigurationAction extends HttpServlet
+{
+ private static final long serialVersionUID = 633352305870632824L;
+
+ private final static String WSDL_DEBUG_ENABLED_PARAM = "wsdlDebugEnabled";
+ private final static String SOAP_DEBUG_ENABLED_PARAM = "soapDebugEnabled";
+ private final static String WEB_SERVER_LOG_LEVEL_PARAM = "webServerLogLevel";
+ private final static String QMAN_LOG_LEVEL_PARAM = "qmanLogLevel";
+
+ private final static String WEB_SERVER_PACKAGE = "org.mortbay";
+ private final static String QMAN_PACKAGE = "org.qpid.apache.management";
+
+ /**
+ * Retrieves current logging configuration and forward those data to the logging configuration view page.
+ * In this way that page will be able to display the current logging settings.
+ *
+ * @param request the http request.
+ * @param response the http response.
+ * @throws ServletException when this controller is not able to forward to the appropriate view page.
+ * @throws IOException when this controller is not able to forward to the appropriate view page.
+ */
+ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
+ {
+ Level messageDebuggerLogLevel = Logger.getLogger(XmlDebugger.class).getEffectiveLevel();
+ Level wsdlDebuggerLogLevel = Logger.getLogger(WsdlDebugger.class).getEffectiveLevel();
+ Level webServerLogLevel = Logger.getLogger(WEB_SERVER_PACKAGE).getEffectiveLevel();
+ Level qmanLogLevel = Logger.getLogger(QMAN_PACKAGE).getEffectiveLevel();
+
+ request.setAttribute(WSDL_DEBUG_ENABLED_PARAM,wsdlDebuggerLogLevel.equals(Level.DEBUG));
+ request.setAttribute(SOAP_DEBUG_ENABLED_PARAM,messageDebuggerLogLevel.equals(Level.DEBUG));
+ request.setAttribute(WEB_SERVER_LOG_LEVEL_PARAM,webServerLogLevel);
+ request.setAttribute(QMAN_LOG_LEVEL_PARAM,qmanLogLevel);
+
+ RequestDispatcher dispatcher = request.getRequestDispatcher("/logging_configuration.jsp");
+ dispatcher.forward(request, response);
+ }
+
+ /**
+ * Accepts user data coming from admin console and use it for configure the underlying logging
+ * subsystem.
+ *
+ * @param request the http request.
+ * @param response the http response.
+ * @throws ServletException when this controller is not able to forward to the appropriate view page.
+ * @throws IOException when this controller is not able to forward to the appropriate view page.
+ */
+ @Override
+ protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
+ {
+ String wsdlDebugEnabled = request.getParameter(WSDL_DEBUG_ENABLED_PARAM);
+ String soapDebugEnabled = request.getParameter(SOAP_DEBUG_ENABLED_PARAM);
+
+ String qmanLevel = request.getParameter(QMAN_LOG_LEVEL_PARAM);
+ String serverLevel = request.getParameter(WEB_SERVER_LOG_LEVEL_PARAM);
+
+ Logger.getLogger(WEB_SERVER_PACKAGE).setLevel(Level.toLevel(serverLevel));
+ Logger.getLogger(QMAN_PACKAGE).setLevel(Level.toLevel(qmanLevel));
+
+ Logger.getLogger(WsdlDebugger.class).setLevel(
+ "on".equals(wsdlDebugEnabled)
+ ? Level.DEBUG
+ : Level.INFO);
+
+ Logger.getLogger(XmlDebugger.class).setLevel(
+ "on".equals(soapDebugEnabled)
+ ? Level.DEBUG
+ : Level.INFO);
+
+ doGet(request, response);
+ }
+}
+ \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/web/action/ResourcesManagementAction.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/web/action/ResourcesManagementAction.java
new file mode 100644
index 0000000000..f1a55be6bf
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/web/action/ResourcesManagementAction.java
@@ -0,0 +1,91 @@
+/*
+ *
+ * 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.web.action;
+
+import java.io.IOException;
+import java.lang.management.ManagementFactory;
+import java.util.List;
+import java.util.Set;
+
+import javax.management.MBeanServer;
+import javax.management.MalformedObjectNameException;
+import javax.management.ObjectName;
+import javax.servlet.RequestDispatcher;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.qpid.management.Names;
+import org.apache.qpid.management.domain.services.ManagementClient;
+import org.apache.qpid.management.domain.services.QMan;
+
+/**
+ * This controller retrieves from QMan all the registered resources and organize
+ * that data in a model that is then forwarded to the appropriate view page.
+ *
+ * TODO : In the corresponding view page only one broker is displayed.
+ * A query should be made on QMan mbean in order to retrieve all connected broker and therefore
+ * a model for each of them should be created.
+ * In the corresponding weg page there should be a "tab" for each broker. Each tab should show only
+ * the objects belonging to that broker.
+ *
+ * @author Andrea Gazzarini
+ */
+public class ResourcesManagementAction extends HttpServlet
+{
+ private static final long serialVersionUID = -2411413147821629363L;
+
+ @SuppressWarnings("unchecked")
+ @Override
+ protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
+ {
+ try
+ {
+ QMan qman = (QMan)getServletContext().getAttribute(Names.APPLICATION_NAME);
+ List<ManagementClient> managementClient = qman.getManagementClients();
+
+ if (!managementClient.isEmpty())
+ {
+ BrokerModel model = new BrokerModel();
+ model.setId(managementClient.toString());
+
+ MBeanServer mxServer = ManagementFactory.getPlatformMBeanServer();
+ Set<ObjectName> objectNames = mxServer.queryNames(new ObjectName("Q-MAN:*"), null);
+ for (ObjectName objectName : objectNames)
+ {
+ model.addObject(objectName);
+ }
+
+ request.setAttribute("model", model);
+ }
+
+ RequestDispatcher dispatcher = request.getRequestDispatcher("/resources_management.jsp");
+ dispatcher.forward(request,response);
+ } catch(MalformedObjectNameException 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");
+ dispatcher.forward(request,response);
+ }
+ }
+}
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/web/action/WsdmOperationsPerspectiveAction.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/web/action/WsdmOperationsPerspectiveAction.java
new file mode 100644
index 0000000000..ca5b3285b0
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/web/action/WsdmOperationsPerspectiveAction.java
@@ -0,0 +1,191 @@
+/*
+ *
+ * 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.web.action;
+
+import java.io.IOException;
+import java.lang.management.ManagementFactory;
+import java.net.URI;
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Map.Entry;
+
+import javax.management.MBeanAttributeInfo;
+import javax.management.MBeanInfo;
+import javax.management.MBeanServer;
+import javax.management.ObjectName;
+import javax.servlet.RequestDispatcher;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+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.qpid.management.Names;
+import org.w3c.dom.Element;
+
+/**
+ * This controller is responsible to retirve operations metadata from a WS-Resource.
+ * That metadat will be forwarded and used by the corresponding view page.
+ *
+ * TODO : This is not really showing WS metadata. Insted JMX metadata is used here.
+ *
+ * @author Andrea Gazzarini
+ *
+ */
+public class WsdmOperationsPerspectiveAction extends HttpServlet
+{
+ private static final long serialVersionUID = -2411413147821629363L;
+
+ private ProxyHandler proxyHandler;
+
+ interface JavaToHtmlAdapter
+ {
+ String toHtml(Object javaObject);
+ }
+
+ private URI resourceUri;
+
+ private JavaToHtmlAdapter mapAdapter = new JavaToHtmlAdapter()
+ {
+ @SuppressWarnings("unchecked")
+ public String toHtml(Object javaObject)
+ {
+ Map<String,Object> value = (Map<String, Object>) javaObject;
+
+ if (value == null || value.isEmpty())
+ {
+ return "(empty)";
+ }
+
+ StringBuilder builder = new StringBuilder();
+ builder.append("<ul>");
+ for (Entry<String, Object> entry : value.entrySet())
+ {
+ builder
+ .append("<li>")
+ .append(entry.getKey())
+ .append(" = ")
+ .append(entry.getValue());
+ }
+ builder.append("</ul>");
+ return builder.toString();
+ }
+ };
+
+ private Map<String, JavaToHtmlAdapter> adapters = new HashMap<String, JavaToHtmlAdapter>();
+
+ @Override
+ public void init() throws ServletException
+ {
+ adapters.put(Map.class.getName(), mapAdapter);
+ adapters.put(HashMap.class.getName(),mapAdapter);
+ adapters.put(Properties.class.getName(),mapAdapter);
+ adapters.put(Hashtable.class.getName(),mapAdapter);
+
+ 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.setReturnType(Element[].class);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
+ {
+ try
+ {
+ String resourceId = request.getParameter("resourceId");
+ ObjectName objectName = new ObjectName(resourceId);
+ String wsdmResourceId = objectName.getKeyProperty(Names.OBJECT_ID);
+
+ EndpointReference resourceEndpointReference = new EndpointReference(getURI(request));
+ resourceEndpointReference.addParameter(
+ Names.RESOURCE_ID_QNAME,
+ wsdmResourceId);
+
+// WsResourceClient resourceClient = new WsResourceClient(resourceEndpointReference);
+// Element wsdl = ((Element[])resourceClient.invoke(proxyHandler,WSDL_DIALECT))[0];
+// Element rmd = ((Element[])resourceClient.invoke(proxyHandler,RMD_DIALECT))[0];
+
+ String [] keyProperties = objectName.getKeyPropertyListString().split(",");
+ MBeanServer server = ManagementFactory.getPlatformMBeanServer();
+
+ MBeanInfo metadata = server.getMBeanInfo(objectName);
+
+ Map<String, String> attributes = getAttributes(server, objectName,metadata.getAttributes());
+
+ request.setAttribute("resourceId", resourceId);
+ request.setAttribute("metadata",metadata);
+ request.setAttribute("nameAttributes",keyProperties);
+ request.setAttribute("attributes",attributes);
+
+ RequestDispatcher dispatcher = request.getRequestDispatcher("/wsdm_operations_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");
+ dispatcher.forward(request,response);
+ }
+ }
+
+ private URI getURI(HttpServletRequest request)
+ {
+ if (resourceUri == null)
+ {
+ StringBuilder builder = new StringBuilder();
+ builder
+ .append(request.getProtocol())
+ .append("//")
+ .append(request.getServerName())
+ .append(":")
+ .append(request.getServerPort())
+ .append("/qman/services/QManWsResource");
+ resourceUri = URI.create(builder.toString());
+ }
+ return resourceUri;
+ }
+
+ private Map<String, String> getAttributes(MBeanServer server, ObjectName name, MBeanAttributeInfo [] metadata) throws Exception
+ {
+ Map<String,String> result = new HashMap<String, String>(metadata.length);
+ for (MBeanAttributeInfo attribute : metadata)
+ {
+ Object value = server.getAttribute(name, attribute.getName());
+ result.put(attribute.getName(),getAdaptedValue(attribute.getType(), value));
+ }
+ return result;
+ }
+
+ private String getAdaptedValue(String type, Object value)
+ {
+ JavaToHtmlAdapter adapter = adapters.get(type);
+ return (adapter != null) ? adapter.toHtml(value) : String.valueOf(value);
+ }
+} \ No newline at end of file
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
new file mode 100644
index 0000000000..e3a8eb50d7
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/web/action/WsdmPropertiesPerspectiveAction.java
@@ -0,0 +1,185 @@
+/*
+ *
+ * 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.web.action;
+
+import java.io.IOException;
+import java.lang.management.ManagementFactory;
+import java.net.URI;
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Map.Entry;
+
+import javax.management.MBeanAttributeInfo;
+import javax.management.MBeanInfo;
+import javax.management.MBeanServer;
+import javax.management.ObjectName;
+import javax.servlet.RequestDispatcher;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+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.qpid.management.Names;
+import org.w3c.dom.Element;
+
+public class WsdmPropertiesPerspectiveAction extends HttpServlet
+{
+ private static final long serialVersionUID = -2411413147821629363L;
+
+ private ProxyHandler proxyHandler;
+
+ interface JavaToHtmlAdapter
+ {
+ String toHtml(Object javaObject);
+ }
+
+ private URI resourceUri;
+
+ private JavaToHtmlAdapter mapAdapter = new JavaToHtmlAdapter()
+ {
+ @SuppressWarnings("unchecked")
+ public String toHtml(Object javaObject)
+ {
+ Map<String,Object> value = (Map<String, Object>) javaObject;
+
+ if (value == null || value.isEmpty())
+ {
+ return "(empty)";
+ }
+
+ StringBuilder builder = new StringBuilder();
+ builder.append("<ul>");
+ for (Entry<String, Object> entry : value.entrySet())
+ {
+ builder
+ .append("<li>")
+ .append(entry.getKey())
+ .append(" = ")
+ .append(entry.getValue());
+ }
+ builder.append("</ul>");
+ return builder.toString();
+ }
+ };
+
+ private Map<String, JavaToHtmlAdapter> adapters = new HashMap<String, JavaToHtmlAdapter>();
+
+ @Override
+ public void init() throws ServletException
+ {
+ adapters.put(Map.class.getName(), mapAdapter);
+ adapters.put(HashMap.class.getName(),mapAdapter);
+ adapters.put(Properties.class.getName(),mapAdapter);
+ adapters.put(Hashtable.class.getName(),mapAdapter);
+
+ 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.setReturnType(Element[].class);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
+ {
+ 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 wsdl = ((Element[])resourceClient.invoke(proxyHandler,WSDL_DIALECT))[0];
+// Element rmd = ((Element[])resourceClient.invoke(proxyHandler,RMD_DIALECT))[0];
+
+ String [] keyProperties = objectName.getKeyPropertyListString().split(",");
+
+
+ MBeanServer server = ManagementFactory.getPlatformMBeanServer();
+
+ MBeanInfo metadata = server.getMBeanInfo(objectName);
+
+ Map<String, String> attributes = getAttributes(server, objectName,metadata.getAttributes());
+
+ request.setAttribute("resourceId", resourceId);
+ request.setAttribute("metadata",metadata);
+ request.setAttribute("nameAttributes",keyProperties);
+ request.setAttribute("attributes",attributes);
+
+ RequestDispatcher dispatcher = request.getRequestDispatcher("/wsdm_properties_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");
+ dispatcher.forward(request,response);
+ }
+ }
+
+ private URI getURI(HttpServletRequest request)
+ {
+ if (resourceUri == null)
+ {
+ StringBuilder builder = new StringBuilder();
+ builder
+ .append(request.getProtocol())
+ .append("//")
+ .append(request.getServerName())
+ .append(":")
+ .append(request.getServerPort())
+ .append("/qman/services/QManWsResource");
+ resourceUri = URI.create(builder.toString());
+ }
+ return resourceUri;
+ }
+
+ private Map<String, String> getAttributes(MBeanServer server, ObjectName name, MBeanAttributeInfo [] metadata) throws Exception
+ {
+ Map<String,String> result = new HashMap<String, String>(metadata.length);
+ for (MBeanAttributeInfo attribute : metadata)
+ {
+ Object value = server.getAttribute(name, attribute.getName());
+ result.put(attribute.getName(),getAdaptedValue(attribute.getType(), value));
+ }
+ return result;
+ }
+
+ private String getAdaptedValue(String type, Object value)
+ {
+ JavaToHtmlAdapter adapter = adapters.get(type);
+ return (adapter != null) ? adapter.toHtml(value) : String.valueOf(value);
+ }
+} \ No newline at end of file
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
new file mode 100644
index 0000000000..b4c488e97c
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/web/action/WsdmRmdPerspectiveAction.java
@@ -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.
+ *
+ */
+package org.apache.qpid.management.web.action;
+
+import java.io.IOException;
+import java.net.URI;
+
+import javax.management.ObjectName;
+import javax.servlet.RequestDispatcher;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+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.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;
+
+public class WsdmRmdPerspectiveAction extends HttpServlet
+{
+ private static final long serialVersionUID = -2411413147821629363L;
+ private static final Object [] RMD_DIALECT = new Object[]{WsrmdConstants.NAMESPACE_URI};
+
+ private ProxyHandler proxyHandler;
+
+ private URI resourceUri;
+
+ @Override
+ public void init() throws ServletException
+ {
+ proxyHandler = new ReflectionProxyHandler();
+ 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);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
+ {
+ 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,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");
+ dispatcher.forward(request,response);
+ }
+ }
+
+ private URI getURI(HttpServletRequest request)
+ {
+ if (resourceUri == null)
+ {
+ StringBuilder builder = new StringBuilder();
+ builder
+ .append("http://")
+ .append(request.getServerName())
+ .append(":")
+ .append(request.getServerPort())
+ .append("/qman/services/QManWsResource");
+ resourceUri = URI.create(builder.toString());
+ }
+ return resourceUri;
+ }
+} \ No newline at end of file
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
new file mode 100644
index 0000000000..77a5237037
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/web/action/WsdmWsdlPerspectiveAction.java
@@ -0,0 +1,140 @@
+/*
+ *
+ * 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.web.action;
+
+import java.io.IOException;
+import java.net.URI;
+
+import javax.management.ObjectName;
+import javax.servlet.RequestDispatcher;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+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.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;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+public class WsdmWsdlPerspectiveAction extends HttpServlet
+{
+ private static final long serialVersionUID = -2411413147821629363L;
+ private static final Object [] WSDL_DIALECT = new Object[]{WsxConstants.WSDL_DIALECT};
+
+ private ProxyHandler proxyHandler;
+
+ private URI resourceUri;
+
+ @Override
+ public void init() throws ServletException
+ {
+ proxyHandler = new ReflectionProxyHandler();
+ 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);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
+ {
+ 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 wsdl = ((Element[])resourceClient.invoke(proxyHandler,WSDL_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(definitions);
+
+ String [] keyProperties = objectName.getKeyPropertyListString().split(",");
+
+ request.setAttribute("resourceId", resourceId);
+ request.setAttribute("nameAttributes",keyProperties);
+ request.setAttribute("wsdl",output);
+ RequestDispatcher dispatcher = request.getRequestDispatcher("/wsdm_wsdl_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");
+ dispatcher.forward(request,response);
+ }
+ }
+
+ private URI getURI(HttpServletRequest request)
+ {
+ if (resourceUri == null)
+ {
+ StringBuilder builder = new StringBuilder();
+ builder
+ .append("http://")
+ .append(request.getServerName())
+ .append(":")
+ .append(request.getServerPort())
+ .append("/qman/services/QManWsResource");
+ resourceUri = URI.create(builder.toString());
+ }
+ return resourceUri;
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/QEmu.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/QEmu.java
new file mode 100644
index 0000000000..79a387e80c
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/QEmu.java
@@ -0,0 +1,130 @@
+/*
+ *
+ * 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.management.MBeanRegistration;
+import javax.management.MBeanServer;
+import javax.management.NotificationBroadcasterSupport;
+import javax.management.ObjectName;
+
+import org.apache.qpid.management.Names;
+import org.apache.qpid.management.domain.handler.impl.QpidDomainObject;
+import org.apache.qpid.management.domain.handler.impl.QpidDomainObjectMBean;
+import org.apache.qpid.management.jmx.EntityLifecycleNotification;
+
+/**
+ * QEmu is basically an instance creator that is installed separately
+ * as part of QMan test cases & examples.
+ * Reason for that is to emulate object creation (queues, exchanges, etc...)
+ * without having Qpid broker connected and therefore controlling the
+ * total number of the instances that are created.
+ *
+ * @author Andrea Gazzarini
+ */
+public class QEmu extends NotificationBroadcasterSupport implements QEmuMBean, MBeanRegistration{
+
+ private MBeanServer _mxServer;
+ private final static String PACKAGE_NAME= "org.apache.qpid";
+ private final static String QUEUE = "queue";
+
+ /**
+ * Unregisters a Queue MBean with MBeanServer.
+ *
+ * @param objectName the name of the MBean that must unregistered.
+ * @throws Exception when the creation or the registration fails.
+ */
+ public void unregister(ObjectName objectName) throws Exception
+ {
+ _mxServer.unregisterMBean(objectName);
+
+ sendNotification(
+ EntityLifecycleNotification.INSTANCE_REMOVED_NOTIFICATION_TYPE,
+ objectName);
+ }
+
+ /**
+ * Creates and registers a Queue MBean with MBeanServer.
+ *
+ * @param objectName the name of the queue MBean.
+ * @throws Exception when the creation or the registration fails.
+ */
+ public void createQueue(ObjectName objectName) throws Exception
+ {
+ QpidDomainObjectMBean queue = new QpidDomainObject();
+ _mxServer.registerMBean(queue, objectName);
+
+ sendNotification(
+ EntityLifecycleNotification.INSTANCE_ADDED_NOTIFICATION_TYPE,
+ objectName);
+ }
+
+ /**
+ * Sends a notification about a lifecycle event of the mbean associated
+ * with the given object.
+ *
+ * @param type the event (notification) type.
+ * @param name the name of the event source.
+ */
+ private void sendNotification(String type,ObjectName name)
+ {
+ sendNotification(
+ new EntityLifecycleNotification(
+ type,
+ PACKAGE_NAME,
+ QUEUE,
+ Names.CLASS,
+ name));
+ }
+
+ /**
+ * Not implemented for this class.
+ */
+ public void postDeregister()
+ {
+ // N.A.
+ }
+
+ /**
+ * Not implemented for this class.
+ */
+ public void postRegister(Boolean registrationDone)
+ {
+ // N.A.
+ }
+
+ /**
+ * Not implemented for this class.
+ */
+ public void preDeregister()
+ {
+ // N.A.
+ }
+
+ /**
+ * MBean server callback.
+ * Stores the value of the owner MBeanServer.
+ */
+ public ObjectName preRegister(MBeanServer server, ObjectName name)
+ {
+ this._mxServer = server;
+ return name;
+ }
+} \ No newline at end of file
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
new file mode 100644
index 0000000000..47aa4ea681
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/QEmuInitializer.java
@@ -0,0 +1,95 @@
+/*
+ *
+ * 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 javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.qpid.management.Messages;
+import org.apache.qpid.management.Names;
+import org.apache.qpid.transport.util.Logger;
+
+/**
+ * QPid Emulator Initializer.
+ * This component is basically responsible to create and initialize
+ * an emulator module used for simulate object instances creation.
+ *
+ * @author Andrea Gazzarini
+ */
+public class QEmuInitializer extends HttpServlet
+{
+ private static final long serialVersionUID = 6149614872902682208L;
+ private final static Logger LOGGER = Logger.get(QEmuInitializer.class);
+
+ /**
+ * QEmu initialization method.
+ *
+ * @throws ServletException when the module cannot be initialized.
+ */
+ public void init() throws ServletException
+ {
+ try
+ {
+ ManagementFactory.getPlatformMBeanServer().registerMBean(
+ new QEmu(),
+ Names.QPID_EMULATOR_OBJECT_NAME);
+ } catch(Exception exception)
+ {
+ LOGGER.warn(
+ exception,
+ Messages.QMAN_300005_QEMU_INITIALIZATION_FAILURE);
+ throw new ServletException(exception);
+ }
+ }
+
+ /**
+ * This is a startup module only so an override of the
+ * default servlet behaviour must be done in order to
+ * prevent incoming http requests processing.
+ *
+ * @param request the http request.
+ * @param response the http response.
+ * @throws ServletException each time this method is called.
+ */
+ @Override
+ public void service(HttpServletRequest request,HttpServletResponse response) throws ServletException
+ {
+ throw new ServletException();
+ }
+
+ /**
+ * Unregister QPid emulator.
+ */
+ public void destroy()
+ {
+ try
+ {
+ ManagementFactory.getPlatformMBeanServer().unregisterMBean(
+ Names.QPID_EMULATOR_OBJECT_NAME);
+ } catch (Exception exception)
+ {
+ }
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/QEmuMBean.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/QEmuMBean.java
new file mode 100644
index 0000000000..f22e7ff12d
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/QEmuMBean.java
@@ -0,0 +1,48 @@
+/*
+ *
+ * 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.management.ObjectName;
+
+/**
+ * Management interface for QEmu.
+ *
+ * @author Andrea Gazzarini
+ * @see QEmu
+ */
+public interface QEmuMBean
+{
+ /**
+ * Creates and registers a Queue MBean with MBeanServer.
+ *
+ * @param objectName the name of the queue MBean.
+ * @throws Exception when the creation or the registration fails.
+ */
+ void createQueue(ObjectName name) throws Exception;
+
+ /**
+ * Unregisters a Queue MBean with MBeanServer.
+ *
+ * @param objectName the name of the MBean that must unregistered.
+ * @throws Exception when the creation or the registration fails.
+ */
+ void unregister(ObjectName name) throws Exception;
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/ArtifactsNotAvailableException.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/ArtifactsNotAvailableException.java
new file mode 100644
index 0000000000..eef70b5544
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/ArtifactsNotAvailableException.java
@@ -0,0 +1,76 @@
+/*
+ *
+ * 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.management.ObjectName;
+
+/**
+ * Thrown when the artifacts related to a specific resource cannot be built.
+ *
+ * @author Andrea Gazzarini
+ */
+public class ArtifactsNotAvailableException extends Exception
+{
+ private static final long serialVersionUID = -9010460152421791926L;
+
+ private final WsArtifacts _artifacts;
+ private final ObjectName _objectName;
+
+ /**
+ * Builds a new exception with the given arguments.
+ *
+ * @param artifacts the artifacts built.
+ * @param cause the exception cause.
+ * @param objectName the object name of the corresponding JMX entity.
+ */
+ public ArtifactsNotAvailableException(
+ WsArtifacts artifacts,
+ Throwable cause,
+ ObjectName objectName)
+ {
+ super(cause);
+ this._artifacts = artifacts;
+ this._objectName = objectName;
+ }
+
+ /**
+ * Returns a message that indicates which artifacts were built.
+ *
+ * @return a message that indicates which artifacts were built.
+ */
+ @Override
+ public String getMessage()
+ {
+ StringBuilder builder = new StringBuilder();
+ if (_artifacts == null)
+ {
+ return super.getMessage();
+ }
+
+ builder.append("Built artifacts for ")
+ .append(_objectName)
+ .append(" : ")
+ .append( (_artifacts.getWsdl() != null) ? "WSDL," : "")
+ .append( (_artifacts.getCapabilityClass() != null) ? "Capability Class," : "")
+ .append( (_artifacts.getResourceMetadataDescriptor() != null) ? "Resource Metadata Descriptor," : "");
+ return builder.toString();
+ }
+}
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/BuilderException.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/BuilderException.java
new file mode 100644
index 0000000000..f3c8077d46
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/BuilderException.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.management.wsdm.capabilities;
+
+/**
+ * Thrown when a WSRF artifact (either WSDL or capability) cannot be built.
+ *
+ * @author Andrea Gazzarini
+ */
+public class BuilderException extends Exception
+{
+ private static final long serialVersionUID = -8267818907567906262L;
+
+ /**
+ * Builds a new exception with the given cause.
+ *
+ * @param cause the exception cause.
+ */
+ public BuilderException(Exception cause)
+ {
+ super(cause);
+ }
+} \ No newline at end of file
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
new file mode 100644
index 0000000000..bde98092a0
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/ConsumerCapability.java
@@ -0,0 +1,68 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.management.wsdm.capabilities;
+
+import org.apache.muse.core.AbstractCapability;
+import org.apache.muse.ws.addressing.soap.SoapFault;
+import org.apache.muse.ws.notification.NotificationConsumer;
+import org.apache.muse.ws.notification.NotificationMessage;
+import org.apache.muse.ws.notification.NotificationMessageListener;
+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
+ */
+public class ConsumerCapability extends AbstractCapability implements NotificationMessageListener
+{
+ /**
+ * Initializes this capability and register itself as message listener.
+ *
+ * @throws SoapFault when the initialization fails.
+ */
+ public void initializeCompleted() throws SoapFault
+ {
+ super.initializeCompleted();
+
+ NotificationConsumer wsn = (NotificationConsumer)getResource().getCapability(WsnConstants.CONSUMER_URI);
+ wsn.addMessageListener(this);
+ }
+
+ /**
+ * Returns true if this consumer can accepts the message.
+ *
+ * @return true;
+ */
+ public boolean accepts(NotificationMessage message)
+ {
+ return true;
+ }
+
+ /**
+ * On Message callback.
+ */
+ public void process(NotificationMessage message)
+ {
+ }
+} \ No newline at end of file
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
new file mode 100644
index 0000000000..370cf3086d
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/DummyCapabilityBuilder.java
@@ -0,0 +1,86 @@
+/*
+ *
+ * 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.management.MBeanAttributeInfo;
+import javax.management.MBeanOperationInfo;
+import javax.management.ObjectName;
+
+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
+{
+ /**
+ * Director callback.
+ * Do nothing here (see class comments above.)
+ */
+ public void begin(ObjectName objectName)
+ {
+ }
+
+ /**
+ * Director callback.
+ * Do nothing here (see class comments above.)
+ */
+ public void endAttributes()
+ {
+ }
+
+ /**
+ * Director callback.
+ * Do nothing here (see class comments above.)
+ */
+ public void endOperations()
+ {
+ }
+
+ /**
+ * Director callback.
+ * Do nothing here (see class comments above.)
+ */
+ public void onAttribute(MBeanAttributeInfo attributeMetadata)
+ {
+ }
+
+ /**
+ * 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)
+ {
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/IArtifactBuilder.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/IArtifactBuilder.java
new file mode 100644
index 0000000000..70b9b0e009
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/IArtifactBuilder.java
@@ -0,0 +1,82 @@
+/*
+ *
+ * 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.management.MBeanAttributeInfo;
+import javax.management.MBeanOperationInfo;
+import javax.management.ObjectName;
+
+import org.apache.muse.core.Environment;
+
+/**
+ * Defines behaviour needed by WS-DM artifact builders.
+ * Each concrete implementor must provide its own parser
+ * implementation of the given JMX data.
+ *
+ * @author Andrea Gazzarini
+ */
+public interface IArtifactBuilder
+{
+ /**
+ * The build process begin and the given parameter is the
+ * object name of the corresponding JMX entity.
+ *
+ * @throws BuilderException when the initialization fails.
+ */
+ void begin(ObjectName objectName) throws BuilderException;
+
+ /**
+ * Processes an attribute (its metadata) of the current MBean.
+ *
+ * @param attributeMetadata the attribute metadata.
+ * @throws BuilderException when the builder cannot parse the given metadata.
+ */
+ void onAttribute(MBeanAttributeInfo attributeMetadata) throws BuilderException;
+
+ /**
+ * Processes an operation (its metadata) of the current MBean.
+ *
+ * @param operationMetadata the operation metadata.
+ * @throws BuilderException when the builder cannot parse the given metadata.
+ */
+ void onOperation(MBeanOperationInfo operationMetadata) throws BuilderException;
+
+ /**
+ * Ends of the attributes section.
+ *
+ * @throws BuilderException when the builder encounter a problem during this phase..
+ */
+ void endAttributes() throws BuilderException;
+
+ /**
+ * Ends of the operations section.
+ *
+ * @throws BuilderException when the builder encounter a problem during this phase..
+ */
+ void endOperations() throws BuilderException;
+
+ /**
+ * Injects the adapter enviroment on this builder.
+ *
+ * @param environment the adapter environment.
+ */
+ void setEnvironment(Environment environment);
+} \ No newline at end of file
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
new file mode 100644
index 0000000000..37ecc0c031
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/MBeanCapability.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.capabilities;
+
+import java.lang.management.ManagementFactory;
+
+import javax.management.Attribute;
+import javax.management.AttributeNotFoundException;
+import javax.management.InstanceNotFoundException;
+import javax.management.MBeanException;
+import javax.management.MBeanServer;
+import javax.management.ObjectName;
+
+import org.apache.muse.ws.resource.impl.AbstractWsResourceCapability;
+import org.apache.qpid.management.Messages;
+import org.apache.qpid.management.domain.handler.impl.InvocationResult;
+import org.apache.qpid.management.domain.services.MethodInvocationException;
+import org.apache.qpid.management.wsdm.common.EntityInstanceNotFoundFault;
+import org.apache.qpid.management.wsdm.common.MethodInvocationFault;
+import org.apache.qpid.management.wsdm.common.NoSuchAttributeFault;
+import org.apache.qpid.management.wsdm.common.QManFault;
+import org.apache.qpid.transport.util.Logger;
+
+/**
+ * Abstract capability used for centralize common
+ * behaviour of the QMan resource(s) related capabilities.
+ *
+ * @author Andrea Gazzarini
+ */
+public abstract class MBeanCapability extends AbstractWsResourceCapability
+{
+ private static final Logger LOGGER = Logger.get(MBeanCapability.class);
+
+ protected final MBeanServer _mxServer;
+ protected ObjectName _objectName;
+
+ /**
+ * Builds a new capability related to the given object name.
+ *
+ * @param objectName the name of the target object of this capability.
+ */
+ public MBeanCapability()
+ {
+ _mxServer = ManagementFactory.getPlatformMBeanServer();
+ }
+
+ /**
+ * Injects on this capability the object name of the target mbean.
+ *
+ * @param objectName the object name of the target mbean.
+ */
+ void setResourceObjectName(ObjectName objectName)
+ {
+ this._objectName = objectName;
+ }
+
+ /**
+ * Returns the attribute value of a QMan managed object instance.
+ *
+ * @param attributeName the name of the attribute to be requested.
+ * @return the value for the requested attribute.
+ * @throws NoSuchAttributeFault when the requested attribute cannot be found
+ * on the given entity instance.
+ * @throws EntityInstanceNotFoundFault when the requested entity instance cannot
+ * be found.
+ * @throws QManFault in case of internal system failure.
+ */
+ Object getAttribute(String attributeName) throws NoSuchAttributeFault, EntityInstanceNotFoundFault, QManFault
+ {
+ try
+ {
+ return _mxServer.getAttribute(_objectName, attributeName);
+ } catch (AttributeNotFoundException exception)
+ {
+ throw new NoSuchAttributeFault(
+ getWsResource().getEndpointReference(),
+ attributeName);
+ } catch (InstanceNotFoundException exception)
+ {
+ throw new EntityInstanceNotFoundFault(
+ getWsResource().getEndpointReference(),
+ _objectName);
+ } catch (Exception exception)
+ {
+ LOGGER.error(
+ Messages.QMAN_100035_GET_ATTRIBUTE_FAILURE,
+ attributeName,
+ _objectName);
+ throw new QManFault(
+ getWsResource().getEndpointReference(),
+ exception);
+ }
+ }
+
+ /**
+ * Sets the value for the given attribute on this MBean (proxy).
+ *
+ * @param objectName
+ * the object name of the target instance (excluding the domain
+ * name).
+ * @param attributeName
+ * the name of the attribute to be requested.
+ * @param value
+ * the value for the requested attribute.
+ * @throws NoSuchAttributeFault
+ * when the requested attribute cannot be found on the given
+ * entity instance.
+ * @throws EntityInstanceNotFoundFault
+ * when the requested entity instance cannot be found.
+ * @throws QManFault
+ * in case of internal system failure.
+ */
+ void setAttribute(String attributeName, Object value) throws NoSuchAttributeFault, EntityInstanceNotFoundFault, QManFault
+ {
+ try
+ {
+ _mxServer.setAttribute(_objectName, new Attribute(attributeName,value));
+ } catch (AttributeNotFoundException exception)
+ {
+ throw new NoSuchAttributeFault(
+ getWsResource().getEndpointReference(),
+ attributeName);
+ } catch (InstanceNotFoundException exception)
+ {
+ throw new EntityInstanceNotFoundFault(
+ getWsResource().getEndpointReference(),
+ _objectName);
+ } catch (Exception exception)
+ {
+ LOGGER.error(
+ Messages.QMAN_100036_SET_ATTRIBUTE_FAILURE,
+ attributeName,
+ _objectName);
+ throw new QManFault(
+ getWsResource().getEndpointReference(),
+ exception);
+ }
+ }
+
+ /**
+ * Invokes the requested operation on target JMX resource.
+ *
+ * @param operationName the name of the operation to be invoked.
+ * @param params parameters used for operation invocation.
+ * @param signature the operation / method signature.
+ * @throws EntityInstanceNotFoundFault
+ * when the target MBean doesn't exist on Management server.
+ * @throws MethodInvocationFault
+ * when the invocation of the requested operation raises an exception.
+ * @throws QManFault
+ * in case of not-well known failure.
+ */
+ Result invoke(String operationName, Object [] params, String [] signature) throws EntityInstanceNotFoundFault, MethodInvocationFault,QManFault
+ {
+ try
+ {
+ InvocationResult output = (InvocationResult) _mxServer
+ .invoke(
+ _objectName,
+ operationName,
+ params,
+ signature);
+
+ return new Result(output.getOutputSection());
+
+ } catch (InstanceNotFoundException exception)
+ {
+ throw new EntityInstanceNotFoundFault(
+ getWsResource().getEndpointReference(),
+ _objectName);
+ } catch (MBeanException exception)
+ {
+ if (exception.getTargetException() instanceof MethodInvocationException)
+ {
+ MethodInvocationException failure = (MethodInvocationException) exception.getTargetException();
+ throw new MethodInvocationFault(
+ getWsResource().getEndpointReference(),
+ operationName,
+ failure.getStatusText(),
+ failure.getReturnCode());
+ } else {
+ LOGGER.error(
+ Messages.QMAN_100037_INVOKE_OPERATION_FAILURE,
+ operationName,
+ _objectName);
+ throw new QManFault(
+ getWsResource().getEndpointReference(),
+ exception);
+ }
+ }catch(Exception exception)
+ {
+ LOGGER.error(
+ Messages.QMAN_100037_INVOKE_OPERATION_FAILURE,
+ operationName,
+ _objectName);
+ throw new QManFault(
+ getWsResource().getEndpointReference(),
+ exception);
+ }
+ }
+} \ No newline at end of file
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
new file mode 100644
index 0000000000..ea67bdf9e1
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/MBeanCapabilityBuilder.java
@@ -0,0 +1,549 @@
+/*
+ *
+ * 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 javassist.CannotCompileException;
+import javassist.ClassClassPath;
+import javassist.ClassPool;
+import javassist.CtClass;
+import javassist.CtField;
+import javassist.CtMethod;
+import javassist.CtNewMethod;
+
+import javax.management.MBeanAttributeInfo;
+import javax.management.MBeanOperationInfo;
+import javax.management.MBeanParameterInfo;
+import javax.management.ObjectName;
+import javax.xml.namespace.QName;
+
+import org.apache.muse.core.Environment;
+import org.apache.qpid.management.Messages;
+import org.apache.qpid.management.Names;
+import org.apache.qpid.management.wsdm.common.EntityInstanceNotFoundFault;
+import org.apache.qpid.management.wsdm.common.MethodInvocationFault;
+import org.apache.qpid.management.wsdm.common.NoSuchAttributeFault;
+import org.apache.qpid.management.wsdm.common.QManFault;
+import org.apache.qpid.transport.util.Logger;
+
+/**
+ * Builder for capability class that will implements the interface
+ * and the behaviour of the underlying JMX Entity.
+ * The product of this builder (capability class) will be used for create a new instance
+ * of the corresponding capability. It will be the "adapter" between WS-Resource and
+ * JMX MBean.
+ *
+ * @author Andrea Gazzarini
+ */
+public class MBeanCapabilityBuilder implements IArtifactBuilder{
+
+ private final static String GET_PROPERTY_NAMES_METHOD_COMMON_PART = "public QName[] getPropertyNames() { return ";
+ private final static String GET_PROPERTY_NAMES_METHOD_WITH_ARRAY = GET_PROPERTY_NAMES_METHOD_COMMON_PART+" PROPERTIES;}";
+ private final static String GET_PROPERTY_NAMES_METHOD_WITH_EMPTY_ARRAY = GET_PROPERTY_NAMES_METHOD_COMMON_PART+" new QName[0];}";
+ private final static Logger LOGGER = Logger.get(MBeanCapabilityBuilder.class);
+
+ /**
+ * Handler interface definining operation needed to be
+ * peformed (by a concrete implementor) when the "endAttributes"
+ * director callback happens.
+ *
+ * @author Andrea Gazzarini
+ */
+ interface EndAttributesHandler {
+
+ /**
+ * Concrete implementor must define in this method what
+ * needs to be done when the corresponding director callback
+ * happens (@see {@link MBeanCapabilityBuilder#endAttributes()}
+ *
+ * @throws BuilderException when a failure is raised inside the concrete implementation.
+ */
+ void endAttributes() throws BuilderException;
+ };
+
+ /**
+ * This is the concrete implementation of the internal interface EndAttributesHandler
+ * that is activated when this builder detects the presence of at least one property on the
+ * capability class.
+ */
+ final EndAttributesHandler _atLeastThereIsOneProperty = new EndAttributesHandler() {
+
+ /**
+ * Creates the QName array instance member and the corresponding
+ * accessor getPropertyNames().
+ *
+ * @throws BuilderException when the member above cannot be added to the capability class.
+ */
+ public void endAttributes() throws BuilderException
+ {
+ try
+ {
+ _properties.deleteCharAt(_properties.length()-1);
+ _properties.append("};");
+
+ CtField properties = CtField.make(_properties.toString(), _capabilityClassDefinition);
+
+ _capabilityClassDefinition.addField(properties);
+
+ CtMethod getPropertyNames = CtNewMethod.make(
+ GET_PROPERTY_NAMES_METHOD_WITH_ARRAY,
+ _capabilityClassDefinition);
+ _capabilityClassDefinition.addMethod(getPropertyNames);
+ } catch(Exception exception)
+ {
+ throw new BuilderException(exception);
+ }
+ }
+ };
+
+ /**
+ * This is the concrete implementation of the internal interface EndAttributesHandler
+ * that is activated when this builder detects that there are no properties defined for
+ * the capability class.
+ */
+ final EndAttributesHandler _noPropertyHasBeenDefined= new EndAttributesHandler()
+ {
+ /**
+ * Creates the getPropertyNames() that simply returns an empty QName array.
+ *
+ * @throws BuilderException when the member above cannot be added to the capability class.
+ */
+ public void endAttributes() throws BuilderException
+ {
+ try
+ {
+ CtMethod getPropertyNames = CtNewMethod.make(
+ GET_PROPERTY_NAMES_METHOD_WITH_EMPTY_ARRAY,
+ _capabilityClassDefinition);
+ _capabilityClassDefinition.addMethod(getPropertyNames);
+ } catch(Exception exception)
+ {
+ throw new BuilderException(exception);
+ }
+ }
+ };
+
+ /**
+ * This is the active state for this builder when the requested class has never been
+ * built.
+ */
+ IArtifactBuilder _classNotAvailable = new IArtifactBuilder()
+ {
+
+ /**
+ * Build process begins.
+ * The given object name is used to build a minimal definition of the product class.
+ *
+ * @param objectName the name of the JMX entity.
+ * @throws BuilderException when the initial definiton of the capability cannot be created.
+ */
+ public void begin(ObjectName objectName) throws BuilderException
+ {
+ String className = objectName.getKeyProperty(Names.CLASS);
+ ClassPool pool = ClassPool.getDefault();
+ pool.insertClassPath(new ClassClassPath(MBeanCapabilityBuilder.class));
+ pool.importPackage(QName.class.getPackage().getName());
+ pool.importPackage(ObjectName.class.getPackage().getName());
+ pool.importPackage(QManFault.class.getPackage().getName());
+ pool.importPackage(Names.class.getPackage().getName());
+ pool.importPackage(Result.class.getPackage().getName());
+ pool.importPackage(NoSuchAttributeFault.class.getPackage().getName());
+ pool.importPackage(EntityInstanceNotFoundFault.class.getPackage().getName());
+ pool.importPackage(MethodInvocationFault.class.getPackage().getName());
+
+ _capabilityClassDefinition = pool.makeClass("org.apache.qpid.management.wsdm.capabilities."+className);
+ try
+ {
+ _capabilityClassDefinition.setSuperclass(pool.get(MBeanCapability.class.getName()));
+ } catch(Exception exception)
+ {
+ throw new BuilderException(exception);
+ }
+ }
+
+ /**
+ * 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();
+ }
+
+ @SuppressWarnings("unchecked")
+ public void endOperations() throws BuilderException
+ {
+ try
+ {
+ _capabilityClass = _capabilityClassDefinition.toClass(
+ QManAdapterCapability.class.getClassLoader(),
+ QManAdapterCapability.class.getProtectionDomain());
+ } catch (Exception exception)
+ {
+ throw new BuilderException(exception);
+ }
+ }
+
+ /**
+ * Director callback.
+ * Attrbute metadata notification. With this callback the director informs this builder that the
+ * currently processed MBean has an attribute with the given metadata.
+ * This builder uses this information in order to add a property and the corresponding accessors
+ * to the capability class that is going to be built.
+ *
+ * @throws BuilderException bytecode manipulation / creation failure.
+ */
+ public void onAttribute(MBeanAttributeInfo attribute) throws BuilderException
+ {
+ String name = attribute.getName();
+ String type = attribute.getType();
+
+ try
+ {
+ type = Class.forName(type).getCanonicalName();
+
+ addPropertyMemberInstance(type, name);
+
+ String nameForAccessors = getNameForAccessors(name);
+
+ if (attribute.isReadable())
+ {
+ String accessor = generateGetter(type, nameForAccessors,name);
+ CtMethod getter = CtNewMethod.make(accessor,_capabilityClassDefinition);
+ _capabilityClassDefinition.addMethod(getter);
+ appendToPropertiesArray(name);
+
+ LOGGER.debug(
+ Messages.QMAN_200043_GENERATED_ACCESSOR_METHOD,
+ _objectName,
+ accessor);
+ }
+
+ if (attribute.isWritable())
+ {
+ String accessor = generateSetter(type, nameForAccessors,name);
+ CtMethod setter = CtNewMethod.make(accessor,_capabilityClassDefinition);
+ _capabilityClassDefinition.addMethod(setter);
+
+ LOGGER.debug(
+ Messages.QMAN_200043_GENERATED_ACCESSOR_METHOD,
+ _objectName,
+ accessor);
+ }
+ } catch(Exception exception)
+ {
+ throw new BuilderException(exception);
+ }
+ }
+
+ public void onOperation(MBeanOperationInfo operation) throws BuilderException
+ {
+ StringBuilder method = new StringBuilder();
+ try
+ {
+ method
+ .append("public Result ")
+ .append(operation.getName())
+ .append("( ");
+
+ for (MBeanParameterInfo parameter: operation.getSignature())
+ {
+ method
+ .append(Class.forName(parameter.getType()).getCanonicalName())
+ .append(' ')
+ .append(parameter.getName())
+ .append(',');
+ }
+
+ method.deleteCharAt(method.length()-1);
+ method.append(") throws EntityInstanceNotFoundFault, MethodInvocationFault,QManFault { return invoke(")
+ .append("\"").append(operation.getName()).append("\"")
+ .append(", new Object[]{ ");
+
+ for (MBeanParameterInfo parameter: operation.getSignature())
+ {
+ method.append(parameter.getName())
+ .append(',');
+ }
+
+ method.deleteCharAt(method.length()-1);
+ method.append("}, new String[]{ ");
+
+ for (MBeanParameterInfo parameter: operation.getSignature())
+ {
+ method
+ .append("\"")
+ .append(parameter.getType())
+ .append("\",");
+ }
+ method.deleteCharAt(method.length()-1);
+ method.append("}); }");
+
+ String methodAsString = method.toString();
+ methodAsString = methodAsString.replace("new Object[]{}","null");
+ methodAsString = methodAsString.replace("new String[]{}","null");
+
+ CtMethod definition = CtNewMethod.make(methodAsString,_capabilityClassDefinition);
+ _capabilityClassDefinition.addMethod(definition);
+ } catch(Exception exception)
+ {
+ throw new BuilderException(exception);
+ } finally {
+ if (LOGGER.isDebugEnabled())
+ {
+ LOGGER.debug(
+ Messages.QMAN_200044_GENERATED_METHOD,
+ _objectName,
+ method.toString());
+ }
+ }
+ }
+
+ public void setEnvironment(Environment environment)
+ {
+ // Nothing to do here...
+ }
+ };
+
+ StringBuilder _properties = new StringBuilder("private static final QName[] PROPERTIES = new QName[]{ ");
+ private Class<MBeanCapability> _capabilityClass;
+ CtClass _capabilityClassDefinition;
+ EndAttributesHandler _endAttributeHandler = _noPropertyHasBeenDefined;
+
+ private ObjectName _objectName;
+
+ IArtifactBuilder _state;
+
+ /**
+ * Director callback.
+ * Attrbute metadata notification. With this callback the director informs this builder that the
+ * currently processed MBean has an attribute with the given metadata.
+ * This builder uses this information in order to add a property and the corresponding accessors
+ * to the capability class that is going to be built.
+ *
+ * @throws BuilderException bytecode manipulation / creation failure.
+ */
+ public void onAttribute(MBeanAttributeInfo attribute) throws BuilderException
+ {
+ _state.onAttribute(attribute);
+ }
+
+ /**
+ * First callback : this method is called at the begin of the director process.
+ * Contains builder initialization code.
+ *
+ * @param objectName the name of the target JMX entity of this capability.
+ * @throws BuilderException when the initialization fails.
+ */
+ @SuppressWarnings("unchecked")
+ public void begin(ObjectName objectName) throws BuilderException
+ {
+ try
+ {
+ this._objectName = objectName;
+ String className = objectName.getKeyProperty(Names.CLASS);
+ _capabilityClass = (Class<MBeanCapability>) Class.forName("org.apache.qpid.management.wsdm.capabilities."+className);
+ _state = new DummyCapabilityBuilder();
+ } catch (ClassNotFoundException exception)
+ {
+ _state = _classNotAvailable;
+ }
+
+ _state.begin(objectName);
+ }
+
+ /**
+ * Director callback.
+ * Operation metadata notification. With this callback the director informs this builder that the
+ * currently processed MBean has an operation with the given metadata.
+ * This builder uses this information in order to add a method to the capability class that is
+ * going to be built.
+ *
+ * For example, let's suppose that an operation like that is detected on the MBean :
+ *
+ * public void purge(int request)
+ *
+ * then the capability will be enrichied with the following method :
+ *
+ * public void purge(int request) throws QManFault {
+ * invoke(
+ * "purge",
+ * new Object[]{request},
+ * new String[]{int.class.getName()});
+ * }
+ *
+ * @throws BuilderException bytecode manipulation / creation failure.
+ */
+ public void onOperation(MBeanOperationInfo operation) throws BuilderException
+ {
+ _state.onOperation(operation);
+ }
+
+ /**
+ * Returns the capability class (the product of this builder).
+ *
+ * @return the capability class (the product of this builder).
+ */
+ Class<MBeanCapability> getCapabilityClass()
+ {
+ return _capabilityClass;
+ }
+
+ /**
+ * Determines what needs to be done when all attributes
+ * metadata has been notified to this builder.
+ * Capability class must have an array member with all defined
+ * properties and a getter method that returns it.
+ * In this method those two members are declared (obviously only
+ * if this capability has at least one property).
+ *
+ * @throws BuilderException when something fails during this phase.
+ */
+ public void endAttributes() throws BuilderException
+ {
+ _state.endAttributes();
+ }
+
+ /**
+ * Director callback.
+ * This method is notified when all operations metadata has been
+ * notified to this builder.
+ * This is the place where the capability class is created, defined and loaded by the JVM.
+ *
+ * @throws BuilderException issues on this method are basically class loading related.
+ */
+ @SuppressWarnings("unchecked")
+ public void endOperations() throws BuilderException
+ {
+ _state.endOperations();
+ }
+
+ /**
+ * Injects the module environment on this builder.
+ *
+ * @param environment the module environment.
+ */
+ public void setEnvironment(Environment environment)
+ {
+ // Nothing to do here...
+ }
+
+ /**
+ * Generates the get accessor method for the given property.
+ *
+ * @param type the type of the property.
+ * @param name the name of the property with the first letter capitalized.
+ * @param plainName the plain name of the property.
+ * @return the getter method (as a string).
+ */
+ String generateGetter(String type, String name,String plainName)
+ {
+ return new StringBuilder()
+ .append("public ")
+ .append(type)
+ .append(' ')
+ .append("get")
+ .append(name)
+ .append("() throws NoSuchAttributeFault,EntityInstanceNotFoundFault,QManFault { return (")
+ .append(type)
+ .append(") getAttribute(\"")
+ .append(plainName)
+ .append("\"); }")
+ .toString();
+ }
+
+ /**
+ * Generates the set accessor method for the given property.
+ *
+ * @param type the type of the property.
+ * @param name the name of the property with the first letter capitalized.
+ * @param plainName the plain name of the property.
+ * @return the setter method (as a string).
+ */
+ String generateSetter(String type, String name, String plainName)
+ {
+ return new StringBuilder()
+ .append("public void ")
+ .append("set")
+ .append(name)
+ .append("(")
+ .append(type)
+ .append(" newValue) throws NoSuchAttributeFault,EntityInstanceNotFoundFault,QManFault {")
+ .append(" setAttribute(\"")
+ .append(plainName)
+ .append("\", newValue); }")
+ .toString();
+ }
+
+ /**
+ * Appends the given attribute name to the properties array declared as an
+ * instance member of the capability class.
+ *
+ * @param attributeName the name of the attribute.
+ */
+ private void appendToPropertiesArray(String attributeName)
+ {
+ _properties.append("new QName(Names.NAMESPACE_URI, \"")
+ .append(attributeName)
+ .append("\", Names.PREFIX),");
+
+ _endAttributeHandler = _atLeastThereIsOneProperty;
+ }
+
+ /**
+ * Adds a new property member instance to the capability class.
+ *
+ * @param type the type of the property.
+ * @param name the name of the property.
+ * @throws CannotCompileException when the property cannot be added.
+ */
+ private void addPropertyMemberInstance(String type, String name) throws CannotCompileException
+ {
+ StringBuilder buffer = new StringBuilder()
+ .append("private ")
+ .append(type)
+ .append(' ')
+ .append(name)
+ .append(';');
+
+ CtField field= CtField.make(buffer.toString(),_capabilityClassDefinition);
+ _capabilityClassDefinition.addField(field);
+ }
+
+ /**
+ * Returns a name that will be used in accessor methods.
+ * That name will differ from the given one because the first letter will be capitalized.
+ * For example, if the given name is "name" the return value will be "Name".
+ *
+ * @param name the plain name of the attribute.
+ * @return a capitalized version of the given name to be used in accessors.
+ */
+ String getNameForAccessors(String name)
+ {
+ return
+ Character.toUpperCase(name.charAt(0)) +
+ name.substring(1);
+ }
+
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/QManAdapterCapability.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/QManAdapterCapability.java
new file mode 100644
index 0000000000..414f37a746
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/QManAdapterCapability.java
@@ -0,0 +1,557 @@
+/*
+ *
+ * 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 java.lang.management.ManagementFactory;
+import java.lang.reflect.Method;
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.ArrayBlockingQueue;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+
+import javax.management.InstanceNotFoundException;
+import javax.management.MBeanServer;
+import javax.management.Notification;
+import javax.management.NotificationFilter;
+import javax.management.NotificationListener;
+import javax.management.ObjectName;
+import javax.xml.namespace.QName;
+
+import org.apache.muse.core.AbstractCapability;
+import org.apache.muse.core.Resource;
+import org.apache.muse.core.ResourceManager;
+import org.apache.muse.core.routing.MessageHandler;
+import org.apache.muse.core.serializer.SerializerRegistry;
+import org.apache.muse.ws.addressing.EndpointReference;
+import org.apache.muse.ws.addressing.soap.SoapFault;
+import org.apache.muse.ws.notification.NotificationProducer;
+import org.apache.muse.ws.notification.WsnConstants;
+import org.apache.qpid.management.Messages;
+import org.apache.qpid.management.Names;
+import org.apache.qpid.management.configuration.Configuration;
+import org.apache.qpid.management.jmx.EntityLifecycleNotification;
+import org.apache.qpid.management.wsdm.common.ThreadSessionManager;
+import org.apache.qpid.management.wsdm.common.UnableToConnectWithBrokerFault;
+import org.apache.qpid.management.wsdm.muse.engine.WSDMAdapterEnvironment;
+import org.apache.qpid.management.wsdm.muse.serializer.ByteArraySerializer;
+import org.apache.qpid.management.wsdm.notifications.LifeCycleEvent;
+import org.apache.qpid.transport.util.Logger;
+
+/**
+ * QMan Adapter capability.
+ * Basically it acts as a lifecycle manager of all ws resource that correspond to entities on JMX side.
+ *
+ * @author Andrea Gazzarini
+*/
+@SuppressWarnings("serial")
+public class QManAdapterCapability extends AbstractCapability
+{
+ private final static Logger LOGGER = Logger.get(QManAdapterCapability.class);
+
+ private MBeanServer _mxServer;
+ private WsArtifactsFactory _artifactsFactory;
+ private URI _resourceURI;
+ private NotificationProducer _publisherCapability;
+ private ThreadPoolExecutor _workManager;
+ private Map<String, QName> _lifeCycleTopics = new HashMap<String, QName>();
+
+ /**
+ * Runnable wrapper used for sending asynchronous
+ * notifications.
+ *
+ * @author Andrea Gazzarini
+ */
+ private final class AsynchNotificationTask implements Runnable
+ {
+ private final QName topicName;
+ private final LifeCycleEvent event;
+
+ AsynchNotificationTask(QName tName, LifeCycleEvent evt)
+ {
+ topicName = tName;
+ event = evt;
+ }
+
+ public void run()
+ {
+ try
+ {
+ _publisherCapability.publish(topicName,event);
+ } catch (SoapFault exception)
+ {
+ LOGGER.error(
+ exception,
+ Messages.QMAN_100038_UNABLE_TO_SEND_WS_NOTIFICATION);
+ }
+ }
+ };
+
+ /**
+ * NotificationFilter for "create" only events.
+ */
+ private final NotificationFilter _filterForNewInstances = new NotificationFilter(){
+
+ /**
+ * Returns true when the notification is related to a creation of a new instance.
+ *
+ * @return true when the notification is related to a creation of a new instance.
+ */
+ public boolean isNotificationEnabled(Notification notification)
+ {
+ return EntityLifecycleNotification.INSTANCE_ADDED_NOTIFICATION_TYPE.equals(notification.getType());
+ }
+
+ };
+
+ /**
+ * NotificationFilter for "remove" only events.
+ */
+ private final NotificationFilter _filterForRemovedInstances = new NotificationFilter(){
+
+ /**
+ * Returns true when the notification is related to a deletion of an existing instance.
+ *
+ * @return true when the notification is related to a deletion of an existing instance.
+ */
+ public boolean isNotificationEnabled(Notification notification)
+ {
+ return EntityLifecycleNotification.INSTANCE_REMOVED_NOTIFICATION_TYPE.equals(notification.getType());
+ }
+ };
+
+ /**
+ * This listener handles "create" mbean events and therefore provides procedure to create and initialize
+ * corresponding ws resources.
+ */
+ private final NotificationListener _listenerForNewInstances = new NotificationListener()
+ {
+ /**
+ * Handles JMX "create" notification type.
+ *
+ * @param notification the entity lifecycle notification.
+ * @param data user data associated with the incoming notifiication : it is not used at the moment.
+ */
+ public void handleNotification(Notification notification, Object data)
+ {
+ ObjectName eventSourceName = null;
+ try
+ {
+ EntityLifecycleNotification lifecycleNotification = (EntityLifecycleNotification) notification;
+ eventSourceName = lifecycleNotification.getObjectName();
+
+ ThreadSessionManager.getInstance().getSession().setObjectName(eventSourceName);
+
+ LOGGER.debug(Messages.QMAN_200039_DEBUG_JMX_NOTIFICATION, notification);
+
+ ResourceManager resourceManager = getResource().getResourceManager();
+ Resource resource = resourceManager.createResource(Names.QMAN_RESOURCE_NAME);
+
+ WsArtifacts artifacts = _artifactsFactory.getArtifactsFor(resource,eventSourceName);
+ MBeanCapability capability = _artifactsFactory.createCapability(
+ artifacts.getCapabilityClass(),
+ eventSourceName);
+
+ ThreadSessionManager.getInstance().getSession().setWsdlDocument(artifacts.getWsdl());
+ ThreadSessionManager.getInstance().getSession().setResourceMetadataDescriptor(artifacts.getResourceMetadataDescriptor());
+
+ resource.setWsdlPortType(Names.QMAN_RESOURCE_PORT_TYPE_NAME);
+ capability.setCapabilityURI(Names.NAMESPACE_URI+"/"+capability.getClass().getSimpleName());
+ capability.setMessageHandlers(createMessageHandlers(capability));
+
+ resource.addCapability(capability);
+ resource.initialize();
+ resourceManager.addResource(resource.getEndpointReference(), resource);
+
+ LOGGER.info(
+ Messages.QMAN_000030_RESOURCE_HAS_BEEN_CREATED,
+ eventSourceName);
+
+ AsynchNotificationTask asynchNotificationTask = new AsynchNotificationTask(
+ getTopicName(lifecycleNotification.getClassKind()),
+ LifeCycleEvent.newCreateEvent(
+ eventSourceName.getKeyProperty(Names.OBJECT_ID),
+ lifecycleNotification.getPackageName(),
+ lifecycleNotification.getClassName()));
+
+ _workManager.execute(asynchNotificationTask);
+
+ } catch (ArtifactsNotAvailableException exception)
+ {
+ LOGGER.error(
+ exception,
+ Messages.QMAN_100023_BUILD_WS_ARTIFACTS_FAILURE);
+ } catch (IllegalAccessException exception)
+ {
+ LOGGER.error(
+ exception,
+ Messages.QMAN_100024_CAPABILITY_INSTANTIATION_FAILURE,
+ eventSourceName);
+ } catch (InstantiationException exception)
+ {
+ LOGGER.error(
+ exception,
+ Messages.QMAN_100024_CAPABILITY_INSTANTIATION_FAILURE,
+ eventSourceName);
+ } catch (SoapFault exception)
+ {
+ LOGGER.error(
+ exception,Messages.QMAN_100025_WSRF_FAILURE,
+ eventSourceName);
+ } catch (Exception exception)
+ {
+ LOGGER.error(
+ exception,
+ Messages.QMAN_100025_WSRF_FAILURE,
+ eventSourceName);
+ }
+ }
+ };
+
+ /**
+ * This listener handles "remove" mbean events and therefore provides procedure to shutdown and remove
+ * corresponding ws resources.
+ */
+ private final NotificationListener _listenerForRemovedInstances = new NotificationListener()
+ {
+ /**
+ * Handles JMX "remove" notification type.
+ *
+ * @param notification the entity lifecycle notification.
+ * @param data user data associated with the incoming notifiication : it is not used at the moment.
+ */
+ public void handleNotification(Notification notification, Object data)
+ {
+ EntityLifecycleNotification lifecycleNotification = (EntityLifecycleNotification) notification;
+ ObjectName eventSourceName = lifecycleNotification.getObjectName();
+
+ LOGGER.debug(Messages.QMAN_200042_REMOVING_RESOURCE, eventSourceName);
+
+ EndpointReference endpointPointReference = new EndpointReference(_resourceURI);
+ endpointPointReference.addParameter(
+ Names.RESOURCE_ID_QNAME,
+ eventSourceName.getKeyProperty(Names.OBJECT_ID));
+
+ ResourceManager resourceManager = getResource().getResourceManager();
+ try
+ {
+ Resource resource = resourceManager.getResource(endpointPointReference);
+ resource.shutdown();
+
+ LOGGER.info(
+ Messages.QMAN_000031_RESOURCE_HAS_BEEN_REMOVED,
+ eventSourceName);
+
+ AsynchNotificationTask asynchNotificationTask = new AsynchNotificationTask(
+ getTopicName(lifecycleNotification.getClassKind()),
+ LifeCycleEvent.newRemoveEvent(
+ eventSourceName.getKeyProperty(Names.OBJECT_ID),
+ lifecycleNotification.getPackageName(),
+ lifecycleNotification.getClassName()));
+
+ _workManager.execute(asynchNotificationTask);
+
+ }
+ catch(Exception exception)
+ {
+ LOGGER.error(
+ exception,
+ Messages.QMAN_100027_RESOURCE_SHUTDOWN_FAILURE,
+ eventSourceName);
+ }
+ }
+ };
+
+ /**
+ * Initializes this capability.
+ *
+ * @throws SoapFault when the initialization fails..
+ */
+ @Override
+ public void initialize() throws SoapFault
+ {
+ super.initialize();
+
+ registerByteArraySerializer();
+
+ createLifeCycleTopics();
+
+ initializeWorkManager();
+
+ createQManResourceURI();
+
+ _mxServer = ManagementFactory.getPlatformMBeanServer();
+ _artifactsFactory = new WsArtifactsFactory(getEnvironment(),_mxServer);
+
+ registerQManLifecycleListeners();
+ }
+
+ /**
+ * Connects QMan with a broker with the given connection data.
+ *
+ * @param host the host where the broker is running.
+ * @param port the port number where the broker is running.
+ * @param username username for estabilshing connection.
+ * @param password password for estabilshing connection.
+ * @param virtualHost the virtualHost name.
+ * @param initialPoolCapacity the initial size of broker connection pool.
+ * @param maxPoolCapacity the max allowed size of broker connection pool.
+ * @param maxWaitTimeout the max wait timeout for retrieving connections.
+ * @throws SoapFault when the connection with broker cannot be estabilished.
+ */
+ @SuppressWarnings("unchecked")
+ public void connect(
+ String host,
+ int port,
+ String username,
+ String password,
+ String virtualHost,
+ int initialPoolCapacity,
+ int maxPoolCapacity,
+ long maxWaitTimeout) throws SoapFault
+ {
+ try
+ {
+ _mxServer.invoke(
+ Names.QMAN_OBJECT_NAME,
+ "addBroker",
+ new Object[]{host,port,username,password,virtualHost,initialPoolCapacity,maxPoolCapacity,maxWaitTimeout},
+ new String[]{
+ String.class.getName(),
+ int.class.getName(),
+ String.class.getName(),
+ String.class.getName(),
+ String.class.getName(),
+ int.class.getName(),
+ int.class.getName(),
+ long.class.getName()});
+ } catch(Exception exception)
+ {
+ LOGGER.error(Messages.QMAN_100017_UNABLE_TO_CONNECT,host,port);
+ throw new UnableToConnectWithBrokerFault(
+ getResource().getEndpointReference(),
+ host,
+ port,
+ username,
+ virtualHost,
+ exception.getMessage());
+ }
+ }
+
+ /**
+ * Creates the message handlers for the given capability.
+ *
+ * @param capability the QMan capability.
+ * @return a collection with message handlers for the given capability.
+ */
+ protected Collection<MessageHandler> createMessageHandlers(MBeanCapability capability)
+ {
+ Collection<MessageHandler> handlers = new ArrayList<MessageHandler>();
+
+ for (Method method : capability.getClass().getDeclaredMethods())
+ {
+ String name = method.getName();
+
+ QName requestName = new QName(
+ Names.NAMESPACE_URI,
+ name,
+ Names.PREFIX);
+
+ QName returnValueName = new QName(
+ Names.NAMESPACE_URI,
+ name+"Response",
+ Names.PREFIX);
+
+ String actionURI = Names.NAMESPACE_URI+"/"+name;
+
+ MessageHandler handler = new QManMessageHandler(
+ actionURI,
+ requestName,
+ returnValueName);
+
+ handler.setMethod(method);
+ handlers.add(handler);
+ }
+ return handlers;
+ }
+
+ /**
+ * Returns the publisher capability associated with the owner resource.
+ *
+ * @return the publisher capability associated with the owner resource.
+ */
+ NotificationProducer getPublisherCapability()
+ {
+ return (NotificationProducer) getResource().getCapability(WsnConstants.PRODUCER_URI);
+ }
+
+ /**
+ * Creates events & objects lifecycle topic that will be used to publish lifecycle event
+ * messages..
+ */
+ void createLifeCycleTopics()
+ {
+ try
+ {
+ _publisherCapability = getPublisherCapability();
+
+ _publisherCapability.addTopic(Names.EVENTS_LIFECYLE_TOPIC_NAME);
+ _lifeCycleTopics.put(Names.EVENT,Names.EVENTS_LIFECYLE_TOPIC_NAME);
+
+ LOGGER.info(
+ Messages.QMAN_000032_EVENTS_LIFECYCLE_TOPIC_HAS_BEEN_CREATED,
+ Names.OBJECTS_LIFECYLE_TOPIC_NAME);
+
+ _publisherCapability.addTopic(Names.OBJECTS_LIFECYLE_TOPIC_NAME);
+ _lifeCycleTopics.put(Names.CLASS,Names.OBJECTS_LIFECYLE_TOPIC_NAME);
+
+ LOGGER.info(
+ Messages.QMAN_000033_OBJECTS_LIFECYCLE_TOPIC_HAS_BEEN_CREATED,
+ Names.OBJECTS_LIFECYLE_TOPIC_NAME);
+
+ _publisherCapability.addTopic(Names.UNKNOWN_OBJECT_TYPE_LIFECYLE_TOPIC_NAME);
+ LOGGER.info(
+ Messages.QMAN_000034_UNCLASSIFIED_LIFECYCLE_TOPIC_HAS_BEEN_CREATED,
+ Names.OBJECTS_LIFECYLE_TOPIC_NAME);
+ } catch(Exception exception)
+ {
+ LOGGER.error(exception, Messages.QMAN_100036_TOPIC_DECLARATION_FAILURE);
+ }
+ }
+
+ /**
+ * Starting from an object type (i.e. event or class) returns the name of the
+ * corresponding topic where the lifecycle message must be published.
+ * Note that if the given object type is unknown then the "Unclassified Object Types" topic
+ * will be returned (and therefore the message will be published there).
+ *
+ * @param objectType the type of the object.
+ * @return the name of the topic associated with the given object type.
+ */
+ QName getTopicName(String objectType)
+ {
+ QName topicName = _lifeCycleTopics.get(objectType);
+ return (topicName != null)
+ ? topicName
+ : Names.UNKNOWN_OBJECT_TYPE_LIFECYLE_TOPIC_NAME;
+ }
+
+ /**
+ * Workaround : it seems that is not possibile to declare a serializer
+ * for a byte array using muse descriptor...
+ * What is the stringified name of the class?
+ * byte[].getClass().getName() is [B but is not working (ClassNotFound).
+ * So, at the end, this is hard-coded here!
+ */
+ private void registerByteArraySerializer()
+ {
+ SerializerRegistry.getInstance().registerSerializer(
+ byte[].class,
+ new ByteArraySerializer());
+ }
+
+ /**
+ * Creates the URI that will be later used to identify a QMan WS-Resource.
+ * Note that the resources that will be created are identified also with their resource id.
+ * Briefly we could say that this is the soap:address of the WS-Resource definition.
+ *
+ * @throws SoapFault when the URI cannot be built (probably it is malformed).
+ */
+ private void createQManResourceURI() throws SoapFault
+ {
+ WSDMAdapterEnvironment environment = (WSDMAdapterEnvironment) getEnvironment();
+ String resourceURI = environment.getDefaultURIPrefix()+Names.QMAN_RESOURCE_NAME;
+ try
+ {
+ _resourceURI = URI.create(resourceURI);
+
+ } catch(IllegalArgumentException exception)
+ {
+ LOGGER.info(
+ exception,
+ Messages.QMAN_100029_MALFORMED_RESOURCE_URI_FAILURE,
+ resourceURI);
+ throw new SoapFault(exception);
+ }
+ }
+
+ /**
+ * Initializes the work manager used for asynchronous notifications.
+ */
+ private void initializeWorkManager()
+ {
+ Configuration configuration = Configuration.getInstance();
+ _workManager = new ThreadPoolExecutor(
+ configuration.getWorkerManagerPoolSize(),
+ configuration.getWorkerManagerMaxPoolSize(),
+ configuration.getWorkerManagerKeepAliveTime(),
+ TimeUnit.MILLISECONDS,
+ new ArrayBlockingQueue<Runnable>(30));
+ }
+
+ /**
+ * This adapter capability needs to be an event listener of QMan JMX core
+ * in order to detect relevant lifecycle events and therefore create WS artifacts & notification(s).
+ *
+ * @throws SoapFault when it's not possible to register event listener : is QMan running?
+ */
+ @SuppressWarnings("serial")
+ private void registerQManLifecycleListeners() throws SoapFault
+ {
+ try
+ {
+ _mxServer.addNotificationListener(
+ Names.QMAN_OBJECT_NAME,
+ _listenerForNewInstances,
+ _filterForNewInstances,
+ null);
+
+ _mxServer.addNotificationListener(
+ Names.QMAN_OBJECT_NAME,
+ _listenerForRemovedInstances,
+ _filterForRemovedInstances,
+ null);
+
+ try
+ {
+ _mxServer.addNotificationListener(
+ Names.QPID_EMULATOR_OBJECT_NAME,
+ _listenerForNewInstances,
+ _filterForNewInstances, null);
+
+ _mxServer.addNotificationListener(
+ Names.QPID_EMULATOR_OBJECT_NAME,
+ _listenerForRemovedInstances,
+ _filterForRemovedInstances, null);
+
+ } catch (Exception exception)
+ {
+ LOGGER.info(Messages.QMAN_000028_TEST_MODULE_NOT_FOUND);
+ }
+ } catch(InstanceNotFoundException exception)
+ {
+ throw new SoapFault(exception);
+ }
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/QManMessageHandler.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/QManMessageHandler.java
new file mode 100644
index 0000000000..95f54ef5b5
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/QManMessageHandler.java
@@ -0,0 +1,104 @@
+/*
+ *
+ * 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 java.lang.reflect.Method;
+
+import javax.xml.namespace.QName;
+
+import org.apache.muse.core.routing.ReflectionMessageHandler;
+import org.apache.muse.core.serializer.Serializer;
+import org.apache.muse.core.serializer.SerializerRegistry;
+import org.apache.muse.util.xml.XmlUtils;
+import org.apache.muse.ws.addressing.soap.SoapFault;
+import org.apache.qpid.management.wsdm.muse.serializer.ByteArraySerializer;
+import org.w3c.dom.Element;
+
+/**
+ * JMXConnectionListener_example custom implementation of Muse message handler to properly deal with
+ * byte arrays.
+ *
+ * @author Andrea Gazzarini
+ */
+public class QManMessageHandler extends ReflectionMessageHandler
+{
+
+ /**
+ * Builds a new message handler with the given arguments.
+ *
+ * @param actionURI the action URI.
+ * @param requestQName the qname of the incoming request.
+ * @param returnValueName the qname of the result value.
+ */
+ public QManMessageHandler(String actionURI, QName requestQName,
+ QName returnValueName)
+ {
+ super(actionURI, requestQName, returnValueName);
+ }
+
+ /**
+ * Transforms the given xml element in the corresponding
+ * object representation.
+ *
+ * @throws SoapFaul when unmarshal operation fails.
+ */
+ @SuppressWarnings("unchecked")
+ public Object[] fromXML(Element xml) throws SoapFault
+ {
+ Method method = getMethod();
+
+ if (xml == null )
+ {
+ return EMPTY_REQUEST;
+ }
+
+ Class[] parameters = method.getParameterTypes();
+ Object[] objects = new Object[parameters.length];
+
+ Element[] elements = XmlUtils.getAllElements(xml);
+
+ if (parameters.length == 1 && elements.length == 0)
+ {
+ elements = new Element[]{ xml };
+ }
+
+ if (elements.length != parameters.length)
+ {
+ throw new SoapFault("IncorrectParams");
+ }
+
+ SerializerRegistry registry = SerializerRegistry.getInstance();
+
+ for (int i = 0; i < elements.length; ++i)
+ {
+ Class clazz = parameters[i];
+ if (clazz == byte[].class)
+ {
+ objects[i] = new ByteArraySerializer().fromXML(elements[i]);
+ } else
+ {
+ Serializer ser = registry.getSerializer(parameters[i]);
+ objects[i] = ser.fromXML(elements[i]);
+ }
+ }
+ return objects;
+ }
+} \ No newline at end of file
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
new file mode 100644
index 0000000000..d6255d0bed
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/QManMetadataExchangeCapability.java
@@ -0,0 +1,99 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.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;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+/**
+ * QMan resource metadata exchange.
+ * We cannot resuse the preexisting classes directly because the wsdl of the service instance
+ * is retrieved using a file path.
+ * Since the owner resource (QManWsResource) is dynamic (I mean, its interface is dynamic), the corresponding
+ * WSDL cannot defined at compile time but needs some changes when the resource is created.
+ * As part of that, the WSDL template found under wsdl folder is modified with the additional properties of the given
+ * resource. The metadata exchange capability must include those properties too.
+ *
+ * Note that this capability is appliable only to a QManWsResource.
+ *
+ * @author Andrea Gazzarini
+ */
+public class QManMetadataExchangeCapability extends WsrfMetadataExchange
+{
+ /**
+ * Returns the WSDL associated with the owner of this capability.
+ *
+ * @return the WSDL associated with the owner of this capability.
+ */
+ @Override
+ protected Element getWSDL()
+ {
+ QManWsResource resource = (QManWsResource) getResource();
+
+ Document wsdlDoc = resource.getWsdl();
+ Element wsdl = XmlUtils.getFirstElement(wsdlDoc);
+
+ WsdlUtils.removeWsdlReferences(wsdl);
+ WsdlUtils.removeSchemaReferences(wsdl);
+
+ 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
new file mode 100644
index 0000000000..a00d2665ae
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/Result.java
@@ -0,0 +1,57 @@
+/*
+ *
+ * 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 java.util.*;
+
+/**
+ * Data Transfer Object that encapsulates the result of a method invocation.
+ * This is the object that will be marshalled in XML and will contain the result of a method
+ * invocation (status code & text).
+ *
+ * @author Andrea Gazzarini
+ */
+public final class Result
+{
+ private final Map<String,Object> _outputParameters;
+
+ /**
+ * Builds a new result DTO with the given parameters.
+ *
+ * @param statusCode the return code.
+ * @param statusText the status message.
+ * @param outputParameters the output parameters.
+ */
+ public Result(Map<String, Object> outputParameters)
+ {
+ this._outputParameters = outputParameters;
+ }
+
+ /**
+ * Returns the output parameterss.
+ *
+ * @return the output parameterss.
+ */
+ public Map<String, Object> getOutputParameters()
+ {
+ return _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
new file mode 100644
index 0000000000..c1678eb43f
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/RmdBuilder.java
@@ -0,0 +1,135 @@
+/*
+ *
+ * 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 java.util.ArrayList;
+import java.util.List;
+
+import javax.management.MBeanAttributeInfo;
+import javax.management.MBeanOperationInfo;
+import javax.management.ObjectName;
+
+import org.apache.muse.core.Environment;
+import org.apache.muse.util.xml.XmlUtils;
+import org.apache.muse.ws.resource.metadata.WsrmdConstants;
+import org.apache.qpid.management.Names;
+import org.apache.qpid.qman.debug.WsdlDebugger;
+import org.w3c.dom.Element;
+
+/**
+ * Resource Metadata Descriptor Builder.
+ * It is used for build the metadata descriptor for properties of the
+ * incoming jmx object.
+ *
+ * @author Andrea Gazzarini
+ */
+class RmdBuilder implements IArtifactBuilder
+{
+ private List<Element> _metadataDescriptor = new ArrayList<Element>();
+
+ ObjectName _objectName;
+
+ /**
+ * Nothing to be done here on this builder.
+ * Simply logs a message indicating the target object name.
+ *
+ * @param objectName the jmx name of the object that is going to be processed.
+ */
+ public void begin(ObjectName objectName)
+ {
+ this._objectName = objectName;
+ }
+
+ /**
+ * Nothing to be done here on this builder.
+ *
+ * @throws BuilderException never.
+ */
+ public void endAttributes()
+ {
+ // N.A. for this builder.
+ }
+
+ /**
+ * Nothing to be done here on this builder.
+ *
+ * @throws BuilderException never.
+ */
+ public void endOperations()
+ {
+ // N.A. for this builder.
+ }
+
+ /**
+ * Process a single attribute metadata.
+ * An attribute (that is, a property) represented by the corresponding incoming
+ * attribute metadata will generate an wsrmd:Property xml element with the constraints
+ * (initial values, static values, allowed values) contained on the metadata.
+ *
+ * @param attributeMetadata the attribute (jmx) metadata.
+ */
+ public void onAttribute(MBeanAttributeInfo attributeMetadata)
+ {
+ Element property = XmlUtils.createElement(WsrmdConstants.PROPERTY_QNAME);
+ property.setAttribute(Names.NAME_ATTRIBUTE, Names.PREFIX+":"+attributeMetadata.getName());
+ property.setAttribute(Names.MODIFIABILITY,
+ attributeMetadata.isWritable()
+ ? Names.READ_WRITE
+ : Names.READ_ONLY);
+ property.setAttribute(Names.MUTABILITY,Names.MUTABLE);
+
+ WsdlDebugger.debug(_objectName, property);
+
+ _metadataDescriptor.add(property);
+ }
+
+ /**
+ * Nothing to be done here on this builder.
+ *
+ * @throws BuilderException never.
+ */
+ public void onOperation(MBeanOperationInfo operation)
+ {
+ // N.A. for this builder
+ }
+
+ /**
+ * Nothing to be done here on this builder.
+ *
+ * @throws BuilderException never.
+ */
+ public void setEnvironment(Environment environment)
+ {
+ // N.A. for this builder
+ }
+
+ /**
+ * Nothing to be done here on this builder.
+ *
+ * @throws BuilderException never.
+ */
+ public Element[] getResourceMetadataDescriptor()
+ {
+ 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
new file mode 100644
index 0000000000..35a919c295
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/WSDMArtifactsDirector.java
@@ -0,0 +1,196 @@
+/*
+ *
+ * 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.management.MBeanAttributeInfo;
+import javax.management.MBeanInfo;
+import javax.management.MBeanOperationInfo;
+import javax.management.ObjectName;
+
+import org.apache.muse.core.Environment;
+import org.apache.muse.core.Resource;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+/**
+ * Director used for coordinate the building process of WS-DM artifacts.
+ *
+ * @author Andrea Gazzarini
+ */
+final class WSDMArtifactsDirector
+{
+ private final ObjectName _eventSourceObjectName;
+ private final MBeanInfo _metadata;
+
+ private final MBeanCapabilityBuilder _capabilityBuilder;
+ private final WsdlBuilder _wsdlBuilder;
+ private final RmdBuilder _rmdBuilder;
+
+ /**
+ * Builds a new director with the given objectname and (jmx) metadata.
+ *
+ * @param eventSourceObjectName the object name of the event source mbean.
+ * @param metadata the jmx metadata of the corresponding mbean.
+ */
+ WSDMArtifactsDirector(ObjectName eventSourceObjectName, MBeanInfo metadata)
+ {
+ this._eventSourceObjectName = eventSourceObjectName;
+ this._metadata = metadata;
+
+ _wsdlBuilder = new WsdlBuilder();
+ _capabilityBuilder = new MBeanCapabilityBuilder();
+ _rmdBuilder = new RmdBuilder();
+ }
+
+ /**
+ * Starts the build process of this director.
+ * This method acts as a facade of the whole build process.
+ *
+ * @throws BuilderException when one step of the build process fails.
+ */
+ void direct() throws BuilderException
+ {
+ processObjectName();
+ processAttributes();
+ endAttributes();
+ processOperations();
+ endOperations();
+ }
+
+ /**
+ * Notifiies builder that all the operations metadata have been transmitted.
+ *
+ * @throws BuilderException when one builder raises an exception during this operation.
+ */
+ private void endOperations() throws BuilderException
+ {
+ _capabilityBuilder.endOperations();
+ _wsdlBuilder.endOperations();
+ _rmdBuilder.endOperations();
+ }
+
+ /**
+ * Notifiies builder that all the attributes metadata have been transmitted.
+ *
+ * @throws BuilderException when one builder raises an exception during this operation.
+ */
+ private void endAttributes() throws BuilderException
+ {
+ _capabilityBuilder.endAttributes();
+ _wsdlBuilder.endAttributes();
+ _rmdBuilder.endAttributes();
+ }
+
+ /**
+ * Injects event source object name on all builders.
+ *
+ * @throws BuilderException when one builder raises an exception during this operation.
+ */
+ void processObjectName() throws BuilderException
+ {
+ _capabilityBuilder.begin(_eventSourceObjectName);
+ _wsdlBuilder.begin(_eventSourceObjectName);
+ _rmdBuilder.begin(_eventSourceObjectName);
+ }
+
+ /**
+ * Injects attributes metadata on all builders.
+ *
+ * @throws BuilderException when one builder raises an exception during this operation.
+ */
+ void processAttributes() throws BuilderException
+ {
+ for (MBeanAttributeInfo attribute : _metadata.getAttributes())
+ {
+ _capabilityBuilder.onAttribute(attribute);
+ _wsdlBuilder.onAttribute(attribute);
+ _rmdBuilder.onAttribute(attribute);
+ }
+ }
+
+ /**
+ * Injects operations metadata on all builders.
+ *
+ * @throws BuilderException when one builder raises an exception during this operation.
+ */
+ void processOperations() throws BuilderException
+ {
+ for (MBeanOperationInfo operation : _metadata.getOperations())
+ {
+ _capabilityBuilder.onOperation(operation);
+ _wsdlBuilder.onOperation(operation);
+ }
+ }
+
+ /**
+ * Returns the capabilty class.
+ *
+ * @return the capability class.
+ */
+ Class<MBeanCapability> getCapabilityClass()
+ {
+ return _capabilityBuilder.getCapabilityClass();
+ }
+
+ /**
+ * Returns the wsdl.
+ *
+ * @return the wsdl.
+ */
+ Document getWsdl()
+ {
+ return _wsdlBuilder.getWsdl();
+ }
+
+ /**
+ * Returns the resource metadata descriptor containing metadata (rules, constraints, etc)
+ * for the current resource.
+ * The returned object is an array of Element and each of them maps a resource property.
+ *
+ * @return the resource metadata descriptor (as an array of Element).
+ */
+ Element [] getResourceMetadataDescriptor()
+ {
+ return _rmdBuilder.getResourceMetadataDescriptor();
+ }
+
+ /**
+ * Injects the environment on this director.
+ *
+ * @param environment the QMan environment.
+ */
+ void setEnvironment(Environment environment)
+ {
+ _wsdlBuilder.setEnvironment(environment);
+ _capabilityBuilder.setEnvironment(environment);
+ _rmdBuilder.setEnvironment(environment);
+ }
+
+ /**
+ * Injectcs the ws resource on this director.
+ *
+ * @param resource the ws 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/WsArtifacts.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/WsArtifacts.java
new file mode 100644
index 0000000000..ac4636b9c9
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/WsArtifacts.java
@@ -0,0 +1,93 @@
+/*
+ *
+ * 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 org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+/**
+ * Web Service Artifacts.
+ * Basically it acts as a container for all artifacts built when a new WS-Resource is created.
+ * With WS artifacts we mean :
+ *
+ * <ul>
+ * <li>Capability class (which encapsulate the WS-DM capability concern)</li>
+ * <li>WS Resource Metadata Descriptor (RMD)</li>
+ * <li>Web Service Description (WSDL)</li>
+ * </ul>
+ *
+ * @author Andrea Gazzarini
+ */
+class WsArtifacts {
+
+ private final Class<MBeanCapability>_capabilityClass;
+ private final Element[] _resourceMetadataDescriptor;
+ private final Document _wsdl;
+
+ /**
+ * Builds a new artifacts container with the given artifacts.
+ *
+ * @param capabilityClass the capability class.
+ * @param resourceMetadataDescriptor the resource metadata descriptor.
+ * @param wsdl the wsdl.
+ */
+ public WsArtifacts(
+ Class<MBeanCapability> capabilityClass,
+ Element[] resourceMetadataDescriptor,
+ Document wsdl)
+ {
+ this._capabilityClass = capabilityClass;
+ this._resourceMetadataDescriptor = resourceMetadataDescriptor;
+ this._wsdl = wsdl;
+ }
+
+ /**
+ * Returns the capability class.
+ *
+ * @return the capability class.
+ */
+ Class<MBeanCapability> getCapabilityClass()
+ {
+ return _capabilityClass;
+ }
+
+ /**
+ * Returns the resource metadata descriptor.
+ * It is not a whole document but each property metadata is described in a
+ * separated element so the returned object is an array of elements.
+ *
+ * @return the resource metadata descriptor.
+ */
+ Element[] getResourceMetadataDescriptor()
+ {
+ return _resourceMetadataDescriptor;
+ }
+
+ /**
+ * Returns the web service description.
+ *
+ * @return the web service description (WSDL).
+ */
+ Document getWsdl()
+ {
+ return _wsdl;
+ }
+} \ 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
new file mode 100644
index 0000000000..94505d28f7
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/WsArtifactsFactory.java
@@ -0,0 +1,140 @@
+/*
+ *
+ * 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 java.util.HashMap;
+import java.util.Hashtable;
+import java.util.Map;
+
+import javax.management.MBeanInfo;
+import javax.management.MBeanServer;
+import javax.management.ObjectName;
+
+import org.apache.muse.core.Environment;
+import org.apache.muse.core.Resource;
+import org.apache.qpid.management.Messages;
+import org.apache.qpid.management.Names;
+import org.apache.qpid.transport.util.Logger;
+
+/**
+ * Manager for all WS-* related artifacts.
+ * Basically it is a factory ehnanced with a _cache mechanism so each created resource
+ * (WSDL, capability class, descriptor) is created and its reference is returned when requested
+ * again.
+ *
+ * @author Andrea Gazzarini
+ */
+class WsArtifactsFactory
+{
+ private final static Logger LOGGER = Logger.get(WsArtifactsFactory.class);
+
+ private final MBeanServer _mxServer;
+ private final Environment _environment;
+ private Map<ObjectName, WsArtifacts> _cache;
+
+ /**
+ * Builds a new factory with the given environment and mbean server.
+ *
+ * @param environment the builder environment.
+ * @param mxServer the management server.
+ */
+ public WsArtifactsFactory(Environment environment, MBeanServer mxServer)
+ {
+ this._environment = environment;
+ this._mxServer = mxServer;
+ this._cache = new HashMap<ObjectName, WsArtifacts>();
+ }
+
+ /**
+ * Returns the WS artifacts corresponding with the given resource.
+ *
+ * @param resource the WS resource.
+ * @param objectName the resource identifier (name).
+ * @return the WS artifacts corresponding with the given resource.
+ * @throws ArtifactsNotAvailableException when some problem occurs during artifacts generation.
+ */
+ @SuppressWarnings("unchecked")
+ WsArtifacts getArtifactsFor(Resource resource, ObjectName objectName) throws ArtifactsNotAvailableException
+ {
+ WsArtifacts result = null;
+ try
+ {
+ Hashtable<String, String> keyProperties = objectName.getKeyPropertyList();
+ keyProperties.remove(Names.NAME_ATTRIBUTE);
+ keyProperties.remove(Names.OBJECT_ID);
+
+ ObjectName searchKey = ObjectName.getInstance(objectName.getDomain(),keyProperties);
+
+ LOGGER.debug(
+ Messages.QMAN_200041_INCOMING_OBJECT_NAME_AND_DERIVED_KEY,
+ objectName,
+ searchKey);
+
+ result = _cache.get(searchKey);
+ if (result == null)
+ {
+ MBeanInfo metadata = _mxServer.getMBeanInfo(objectName);
+
+ WSDMArtifactsDirector director = new WSDMArtifactsDirector(objectName,metadata);
+ director.setEnvironment(_environment);
+ director.setResource(resource);
+ director.direct();
+
+ result = new WsArtifacts(
+ director.getCapabilityClass(),
+ director.getResourceMetadataDescriptor(),
+ director.getWsdl());
+
+ _cache.put(searchKey, result);
+
+ LOGGER.debug(
+ Messages.QMAN_200040_WS_ARTIFACTS_CACHED,
+ searchKey);
+ }
+
+ return result;
+ } catch(Exception exception)
+ {
+ throw new ArtifactsNotAvailableException(
+ result,
+ exception,
+ objectName);
+ }
+ }
+
+ /**
+ * Utility method for create concrete instance of the given capability class.
+ *
+ * @param capabilityClass the capability class.
+ * @param objectName the object name that will act as the target for this capability invocations.
+ * @return an initialized instance of the given capability class.
+ * @throws InstantiationException when the class cannot be instantiated.
+ * @throws IllegalAccessException when this method does not have access to
+ * the definition of the capability class.
+ */
+ MBeanCapability createCapability(Class<MBeanCapability> capabilityClass, ObjectName objectName)
+ throws InstantiationException, IllegalAccessException
+ {
+ MBeanCapability capability = capabilityClass.newInstance();
+ capability.setResourceObjectName(objectName);
+ return capability;
+ }
+} \ No newline at end of file
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
new file mode 100644
index 0000000000..6bfccda1ce
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/WsdlBuilder.java
@@ -0,0 +1,460 @@
+/*
+ *
+ * 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 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.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;
+import org.apache.xpath.XPathAPI;
+import org.w3c.dom.Attr;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+/**
+ * TO BE IMPROVED USING JAXB!!
+ *
+ * @author Andrea Gazzarini
+ */
+class WsdlBuilder implements IArtifactBuilder,Constants {
+
+ private final static Logger LOGGER = Logger.get(WsdlBuilder.class);
+
+ private WSDMAdapterEnvironment _environment;
+ private Document _document;
+ private Element schema;
+ private Element _wsrpProperties;
+ private ObjectSerializer _serializer;
+ private ObjectName _objectName;
+ 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
+ {
+ 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_ATTRIBUTE,
+ Names.PREFIX+":"+attributeName);
+
+ _wsrpProperties.appendChild(propertyRef);
+ } catch(Exception exception)
+ {
+ throw new BuilderException(exception);
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ private Element defineSchemaFor(String type, String attributeName) throws Exception
+ {
+ Element propertyDeclaration = XmlUtils.createElement(_document, XSD_ELEMENT_QNAME);
+ String xmlType = null;
+ if (type.equals(Map.class.getName()))
+ {
+ xmlType="qman:map";
+ } else if (UUID.class.getName().equals(type))
+ {
+ xmlType = "qman:uuid";
+ } else if (type.startsWith("["))
+ {
+ Class arrayClass = Class.forName(type);
+ Class clazz = ReflectUtils.getClassFromArrayClass(arrayClass);
+ String arrayType = arrayClass.getSimpleName().replace("[]", "").trim();
+ arrayType = Character.toUpperCase(arrayType.charAt(0))+arrayType.substring(1);
+ if (!arrayTypesAlreadyDeclared.containsKey(type))
+ {
+ _arrayComplexType.setAttribute(NAME_ATTRIBUTE, "arrayOf"+arrayType);
+ _nestedArrayType.setAttribute(TYPE_ATTRIBUTE, _serializer.getXmlType(clazz));
+ schema.appendChild(_arrayComplexType);
+ arrayTypesAlreadyDeclared.put(type, arrayType);
+ }
+ xmlType = "qman:arrayOf"+arrayTypesAlreadyDeclared.get(type);
+ }
+ 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;
+ this._serializer = (ObjectSerializer) SerializerRegistry.getInstance().getSerializer(Object.class);
+
+ createWsrpPropertiesElement();
+
+ createReusableArrayComplextType();
+
+ replaceDummyServiceLocationOnWsdl();
+
+ createSchemaElement();
+ }
+
+ public void onOperation(MBeanOperationInfo operationMetadata) throws BuilderException
+ {
+ // SCHEMA SECTION
+ /*
+ <xs:element name='purgeRequest' type='qman:purgeRequest' />
+
+ <xs:element name='purgeResponse' type='qman:purgeResponse' />
+
+ <xs:complexType name='purgeRequest'>
+ <xs:sequence>
+ <xs:element name='arg0' type='xs:int' />
+ <xs:element minOccurs='0' name='arg1' type='qman:hashMap' />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:element name='hashMap'>
+ <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>
+
+ <xs:complexType name='purgeResponse'>
+ <xs:sequence />
+ </xs:complexType>
+ */
+
+ try
+ {
+ // <xsd:element xmlns="" name="purgeRequest" type="qman:purgeRequest"/>
+
+ Element methodRequestElement= _document.createElement("xsd:element");
+ String methodNameRequest = operationMetadata.getName()+"Request";
+ methodRequestElement.setAttribute("name", methodNameRequest);
+ methodRequestElement.setAttribute("type", "qman:"+methodNameRequest);
+
+ // <xs:element name='purgeResponse' type='qman:purgeResponse' />
+// Element methodResponseElement= _document.createElement("xsd:element");
+ String methodNameResponse= operationMetadata.getName()+"Response";
+// methodResponseElement.setAttribute("name", methodNameResponse);
+// methodResponseElement.setAttribute("type", "qman:result");//+methodNameResponse);
+
+ schema.appendChild(methodRequestElement);
+// schema.appendChild(methodResponseElement);
+
+ /*
+ <xs:complexType name='purgeRequest'>
+ <xs:sequence>
+ <xs:element name='arg0' type='xs:int' />
+ <xs:element minOccurs='0' name='arg1' type='qman:hashMap' />
+ </xs:sequence>
+ </xs:complexType>
+
+ */
+
+ Element methodNameRequestComplexType = _document.createElement("xsd:complexType");
+ methodNameRequestComplexType.setAttribute("name", methodNameRequest);
+ Element methodNameRequestComplexTypeSequence = _document.createElement("xsd:sequence");
+
+ for(MBeanParameterInfo parameter : operationMetadata.getSignature())
+ {
+ methodNameRequestComplexTypeSequence.appendChild(defineSchemaFor(parameter.getType(), parameter.getName()));
+ }
+
+ methodNameRequestComplexType.appendChild(methodNameRequestComplexTypeSequence);
+ schema.appendChild(methodNameRequestComplexType);
+
+ /*
+ <message name="purgeResponseMessage">
+ <part element='qman:purgeResponse' name='purgeResponse'></part>
+ </message>
+
+ <message name='purgeRequestMessage'>
+ <part element="qman:purgeRequest" name='purgeRequest'></part>
+ </message>
+ */
+ Element definitions = (Element) XPathAPI.selectSingleNode(_document, "/wsdl:definitions");
+
+ String requestMessageName = methodNameRequest+"Message";
+ String responseMessageName = methodNameResponse+"Message";
+
+ Element requestMessage = _document.createElement("message");
+ requestMessage.setAttribute("name", requestMessageName);
+ Element requestPart = _document.createElement("wsdl:part");
+ requestPart.setAttribute("element", "qman:"+methodNameRequest);
+ requestPart.setAttribute("name", methodNameRequest);
+ requestMessage.appendChild(requestPart);
+
+ Element responseMessage = _document.createElement("wsdl:message");
+ responseMessage.setAttribute("name", responseMessageName);
+ Element responsePart = _document.createElement("wsdl:part");
+ responsePart.setAttribute("element", "qman:result");//+methodNameResponse);
+ responsePart.setAttribute("name", methodNameResponse);
+ responseMessage.appendChild(responsePart);
+
+ definitions.appendChild(requestMessage);
+ definitions.appendChild(responseMessage);
+
+
+ /*
+ <operation name='purge'>
+ <input message="qman:purgeRequestMessage">
+ </input>
+ <output message='qman:purgeResponseMessage'>
+ </output>
+ </operation>
+ */
+ Element portType = (Element) XPathAPI.selectSingleNode(_document, "/wsdl:definitions/wsdl:portType");
+ Element operation = _document.createElement("wsdl:operation");
+ operation.setAttribute("name", operationMetadata.getName());
+
+ Element input = _document.createElement("wsdl:input");
+ input.setAttribute("message", "qman:"+requestMessageName);
+ input.setAttribute("name", methodNameRequest);
+ input.setAttribute("wsa:action", Names.NAMESPACE_URI+"/"+operationMetadata.getName());
+
+ //name="SetResourcePropertiesRequest" wsa:Action="http://docs.oasis-open.org/wsrf/rpw-2/SetResourceProperties/SetResourcePropertiesRequest"/>
+
+ operation.appendChild(input);
+
+ Element output = _document.createElement("wsdl:output");
+ output.setAttribute("message", "qman:"+responseMessageName);
+ output.setAttribute("name", methodNameResponse);
+ output.setAttribute("wsa:action", Names.NAMESPACE_URI+"/"+methodNameResponse);
+
+ operation.appendChild(output);
+
+ portType.appendChild(operation);
+
+ /*
+ <operation name='purge'>
+ <soap:operation soapAction='purge' />
+ <input>
+ <soap:body use='literal' />
+ </input>
+ <output>
+ <soap:body use='literal' />
+ </output>
+ </operation>
+ */
+ Element binding = (Element) XPathAPI.selectSingleNode(_document, "/wsdl:definitions/wsdl:binding");
+ Element bindingOperation = _document.createElement("wsdl:operation");
+ bindingOperation.setAttribute("name", operationMetadata.getName());
+
+ Element soapOperation = _document.createElement("wsdl-soap:operation");
+ soapOperation.setAttribute("soapAction", Names.NAMESPACE_URI+"/"+operationMetadata.getName());
+
+ Element bindingInput = _document.createElement("wsdl:input");
+ Element bodyIn = _document.createElement("wsdl-soap:body");
+ bodyIn.setAttribute("use", "literal");
+
+ Element bindingOutput = _document.createElement("wsdl:output");
+ Element bodyOut = _document.createElement("wsdl-soap:body");
+ bodyOut.setAttribute("use", "literal");
+
+ bindingOutput.appendChild(bodyOut);
+ bindingInput.appendChild(bodyIn);
+
+ bindingOperation.appendChild(soapOperation);
+ bindingOperation.appendChild(bindingInput);
+ bindingOperation.appendChild(bindingOutput);
+
+ binding.appendChild(bindingOperation);
+ } catch(Exception exception)
+ {
+ throw new BuilderException(exception);
+ }
+ }
+
+ /**
+ * 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 = (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
new file mode 100644
index 0000000000..116d74727a
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/common/EntityInstanceNotFoundFault.java
@@ -0,0 +1,58 @@
+/*
+ *
+ * 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.common;
+
+import javax.management.ObjectName;
+import javax.xml.namespace.QName;
+
+import org.apache.muse.ws.addressing.EndpointReference;
+import org.apache.qpid.management.Names;
+
+/**
+ * Thrown when some operation has been requested on an entity and the entity hasn't been found
+ * on the managed domain.
+ *
+ * @author Andrea Gazzarini
+ */
+public class EntityInstanceNotFoundFault extends QManFault
+{
+ private static final long serialVersionUID = -3772811863214553615L;
+
+ private final static QName EXCEPTION_QNAME = new QName(
+ Names.NAMESPACE_URI,
+ "EntityInstanceNotFoundFault",
+ Names.PREFIX);
+
+ /**
+ * Builds a new exception with the given endpoint reference and the object name of the entity
+ * that wasn't found.
+ *
+ * @param endpointReference the origin endpoint reference of this exception.
+ * @param targetEntityName the object name of the not found entity.
+ */
+ public EntityInstanceNotFoundFault(EndpointReference endpointReference, ObjectName targetEntityName)
+ {
+ 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/MethodInvocationFault.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/common/MethodInvocationFault.java
new file mode 100644
index 0000000000..f24c2bfd46
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/common/MethodInvocationFault.java
@@ -0,0 +1,79 @@
+/*
+ *
+ * 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.common;
+
+import javax.xml.namespace.QName;
+
+import org.apache.muse.util.xml.XmlUtils;
+import org.apache.muse.ws.addressing.EndpointReference;
+import org.apache.qpid.management.Names;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+/**
+ * This is the exception encapsulating the fault that will be thrown in case of
+ * method invocation failure.
+ *
+ * @author Andrea Gazzarini
+ */
+public class MethodInvocationFault extends QManFault
+{
+ private static final long serialVersionUID = 5977379710882983474L;
+
+ private String _message;
+ private long _returnCode;
+
+ /**
+ * Builds a new exception with the given endpoint reference and method invocation exception.
+ * This constructor will be used when the invocation thrown the MethodInvocationException.
+ *
+ * @param endpointReference the endpoint reference.
+ * @param methodName the name of the method.
+ * @param message the explanatio message.
+ * @param returnCode the a mnemonic code associated with the failure.
+ */
+ public MethodInvocationFault(
+ EndpointReference endpointReference,
+ String methodName,
+ String message,
+ long returnCode)
+ {
+ super(
+ endpointReference,
+ new QName(
+ Names.NAMESPACE_URI,
+ "OperationInvocationFault",
+ Names.PREFIX),
+ String.format("OPERATION \"%s\" FAILURE. See detail section for further details.",methodName));
+ this._message = message;
+ this._returnCode = returnCode;
+ }
+
+ @Override
+ public Element getDetail()
+ {
+ Element detail = super.getDetail();
+ Document owner = detail.getOwnerDocument();
+ detail.appendChild(XmlUtils.createElement(owner, Names.QMAN_STATUS_TEXT_NAME,_message));
+ detail.appendChild(XmlUtils.createElement(owner, Names.QMAN_STATUS_CODE_NAME,_returnCode));
+ return detail;
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/common/NoSuchAttributeFault.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/common/NoSuchAttributeFault.java
new file mode 100644
index 0000000000..e9f37f8afb
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/common/NoSuchAttributeFault.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.management.wsdm.common;
+
+import javax.xml.namespace.QName;
+
+import org.apache.muse.util.xml.XmlUtils;
+import org.apache.muse.ws.addressing.EndpointReference;
+import org.apache.qpid.management.Names;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+/**
+ * This is the exception encapsulating the fault that will be thrown when a requested
+ * attribute is not found on the target ws resource.
+ *
+ * @author Andrea Gazzarini
+ */
+public class NoSuchAttributeFault extends QManFault
+{
+ private static final long serialVersionUID = 5977379710882983474L;
+
+ private String _attributeName;
+
+ /**
+ * Builds a new exception with the given endpoint reference, JMX object name
+ * and attribute that hasn't been found.
+ *
+ * @param endpointReference the endpoint reference.
+ * @param attributeName the name of the attribute that hasn't been found.
+ */
+ public NoSuchAttributeFault(EndpointReference endpointReference, String attributeName)
+ {
+ super(
+ endpointReference,
+ new QName(
+ Names.NAMESPACE_URI,
+ "NoSuchAttributeFault",
+ Names.PREFIX),
+ "Attribute not found on this WS-Resource.");
+ _attributeName = attributeName;
+ }
+
+ @Override
+ public Element getDetail()
+ {
+ Element detail = super.getDetail();
+ Document owner = detail.getOwnerDocument();
+ detail.appendChild(XmlUtils.createElement(owner, Names.QMAN_STATUS_ATTRIBUTE_NAME,_attributeName));
+ return detail;
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/common/ObjectNameIdFactory.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/common/ObjectNameIdFactory.java
new file mode 100644
index 0000000000..eb7eee9547
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/common/ObjectNameIdFactory.java
@@ -0,0 +1,61 @@
+/*
+ *
+ * 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.common;
+
+import javax.management.ObjectName;
+import javax.xml.namespace.QName;
+
+import org.apache.muse.core.routing.ResourceIdFactory;
+import org.apache.qpid.management.Names;
+
+/**
+ * ResourceIdFactory implementation that is using an objectName as
+ * resource identifier.
+ * This is done in order to make a relationship between an MBean (which is part of the
+ * JMX core domain model) and a WS-Resource (the same entity as is represented on WS-DM adapter side).
+ *
+ * @author Andrea Gazzarini
+ */
+public class ObjectNameIdFactory implements ResourceIdFactory
+{
+ /**
+ * Returns the name of the identifier element.
+ *
+ * @return the name of the identifier element.
+ */
+ public QName getIdentifierName()
+ {
+ return Names.RESOURCE_ID_QNAME;
+ }
+
+ /**
+ * Returns the object name used as a resource identifier.
+ * Developer note : this factory is highly coupled with ThreadSessionManager stuff because
+ * the object name that will be used as identifier is supposed to be in the thread session.
+ *
+ * @return the object name used as a resource identifier.
+ */
+ public String getNextIdentifier()
+ {
+ ObjectName objectName = ThreadSessionManager.getInstance().getSession().getObjectName();
+ return objectName.getKeyProperty(Names.OBJECT_ID);
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/common/QManFault.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/common/QManFault.java
new file mode 100644
index 0000000000..0a52c2ba65
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/common/QManFault.java
@@ -0,0 +1,72 @@
+/*
+ *
+ * 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.common;
+
+import javax.xml.namespace.QName;
+
+import org.apache.muse.ws.addressing.EndpointReference;
+import org.apache.muse.ws.resource.basefaults.BaseFault;
+import org.apache.qpid.management.Names;
+
+/**
+ * Base class for QMan thrown faults.
+ * This should be thrown to denote a situation where a not-well cause could be determined.
+ */
+public class QManFault extends BaseFault
+{
+ private static final long serialVersionUID = 5977379710882983474L;
+ private final static QName SERVICE = new QName(
+ Names.NAMESPACE_URI,
+ "QMan",
+ Names.PREFIX);
+
+ private final static QName EXCEPTION_QNAME = new QName(
+ Names.NAMESPACE_URI,
+ "QManFault",
+ Names.PREFIX);
+
+ /**
+ * Builds a new exception with the given endpoint reference and the exception cause.
+ *
+ * @param endpointReference the endpoint reference.
+ * @param cause the exception cause.
+ */
+ public QManFault(EndpointReference endpointReference, Exception cause)
+ {
+ super(EXCEPTION_QNAME,cause.getMessage());
+ setCode(SERVICE);
+ setOriginReference(endpointReference);
+ }
+
+ /**
+ * Builds a new exception with the given endpoint reference, qname and detail message.
+ *
+ * @param endpointReference the endpoint reference.
+ * @param qname the qname of this exception.
+ * @param message the detail message of this exception.
+ */
+ public QManFault(EndpointReference endpointReference, QName qname, String message)
+ {
+ super(qname,message);
+ setOriginReference(endpointReference);
+ setCode(SERVICE);
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/common/QManResourceIdFactory.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/common/QManResourceIdFactory.java
new file mode 100644
index 0000000000..1a34971c6a
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/common/QManResourceIdFactory.java
@@ -0,0 +1,57 @@
+/*
+ *
+ * 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.common;
+
+import java.util.UUID;
+
+import javax.xml.namespace.QName;
+
+import org.apache.muse.core.routing.ResourceIdFactory;
+import org.apache.qpid.management.Names;
+
+/**
+ * A simple implementation of resource id factory that uses a UUID as resource
+ * identifier.
+ *
+ * @author Andrea Gazzarini
+ */
+public class QManResourceIdFactory implements ResourceIdFactory
+{
+ /**
+ * Returns the identifier name for id element.
+ *
+ * @return the identifier name for id element.
+ */
+ public QName getIdentifierName()
+ {
+ return Names.RESOURCE_ID_QNAME;
+ }
+
+ /**
+ * Returns the next valid identifier.
+ *
+ * @return the next valid identifier.
+ */
+ public String getNextIdentifier()
+ {
+ return UUID.randomUUID().toString();
+ }
+} \ 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
new file mode 100644
index 0000000000..588879b951
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/common/ThreadSession.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.common;
+
+import javax.management.ObjectName;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+/**
+ * Thread-scoped session.
+ *
+ * @author Andrea Gazzarini
+ */
+public class ThreadSession
+{
+ private ObjectName _objectName;
+ private Document _wsdl;
+ private Element [] _wsrmdProperties;
+
+ /**
+ * Empty constructor.
+ */
+ ThreadSession()
+ {
+ }
+
+ /**
+ * Gets the object name associated with this thread session.
+ *
+ * @return the object name associated with this thread session.
+ */
+ public ObjectName getObjectName()
+ {
+ return _objectName;
+ }
+
+ /**
+ * Sets the object name on this thread session.
+ *
+ * @param the object name of this thread session..
+ */
+ public void setObjectName(ObjectName objectName)
+ {
+ this._objectName = objectName;
+ }
+
+ /**
+ * Sets the WSDL document on this thread session.
+ *
+ * @param the WSDL document of this thread session..
+ */
+ public void setWsdlDocument(Document wsdlDoc)
+ {
+ this._wsdl = wsdlDoc;
+ }
+
+ /**
+ * Gets the WSDL document associated with this thread session.
+ *
+ * @return the WSDL document associated with this thread session.
+ */
+ public Document getWsdlDocument()
+ {
+ return _wsdl;
+ }
+
+ /**
+ * Gets the RDM elements associated with this thread session.
+ *
+ * @return the RDM elements associated with this thread session.
+ */
+ public Element[] getResourceMetadataDescriptor()
+ {
+ return _wsrmdProperties;
+ }
+
+ /**
+ * Sets the WSDL elements on this thread session.
+ *
+ * @param the WSDL elements of this thread session..
+ */
+ public void setResourceMetadataDescriptor(Element[] 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/common/ThreadSessionManager.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/common/ThreadSessionManager.java
new file mode 100644
index 0000000000..6a081bfec4
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/common/ThreadSessionManager.java
@@ -0,0 +1,68 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.management.wsdm.common;
+
+/**
+ * Thread session manager used to handle thread-scoped sessions.
+ *
+ * @author Andrea Gazzarini
+ */
+public final class ThreadSessionManager
+{
+ private static ThreadSessionManager instance = new ThreadSessionManager();
+
+ private ThreadLocal<ThreadSession> sessions;
+
+ /**
+ * Builds and initializes a new manager.
+ */
+ private ThreadSessionManager()
+ {
+ this.sessions = new ThreadLocal<ThreadSession>();
+ }
+
+ /**
+ * Returns the singleton instance of this manager.
+ *
+ * @return the singleton instance of this manager.
+ */
+ public static ThreadSessionManager getInstance()
+ {
+ return instance;
+ }
+
+ /**
+ * Returns (or create and returns) the session associated with the
+ * current thread.
+ *
+ * @return the thread session.
+ */
+ public ThreadSession getSession()
+ {
+ ThreadSession session = (ThreadSession) sessions.get();
+ if (session == null)
+ {
+ session = new ThreadSession();
+ sessions.set(session);
+ }
+ return session;
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/common/UnableToConnectWithBrokerFault.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/common/UnableToConnectWithBrokerFault.java
new file mode 100644
index 0000000000..55365b4051
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/common/UnableToConnectWithBrokerFault.java
@@ -0,0 +1,86 @@
+/*
+ *
+ * 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.common;
+
+import javax.xml.namespace.QName;
+
+import org.apache.muse.util.xml.XmlUtils;
+import org.apache.muse.ws.addressing.EndpointReference;
+import org.apache.qpid.management.Names;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+/**
+ * This is the exception encapsulating the fault that will be thrown in case of
+ * broker connection failure.
+ *
+ * @author Andrea Gazzarini
+ */
+public class UnableToConnectWithBrokerFault extends QManFault
+{
+ private static final long serialVersionUID = 5977379710882983474L;
+
+ private String _host;
+ private int _port;
+ private String _username;
+ private String _virtualHostName;
+
+ /**
+ * Builds a new exception with the given endpoint reference and connection data.
+ *
+ * @param host the requested qpid host.
+ * @param port the requested qpid port.
+ * @param username the username used for estabilishing connection.
+ * @param virtualHostName the name of the target virtual host..
+ */
+ public UnableToConnectWithBrokerFault(
+ EndpointReference endpointReference,
+ String host,
+ int port,
+ String username,
+ String virtualHostName,
+ String message)
+ {
+ super(
+ endpointReference,
+ new QName(
+ Names.NAMESPACE_URI,
+ "UnableToConnectFault",
+ Names.PREFIX),
+ String.format("Unable to connect with the requested broker. Underlying exception message was %s",message));
+ this._host = host;
+ this._port = port;
+ this._username = username;
+ this._virtualHostName = virtualHostName;
+ }
+
+ @Override
+ public Element getDetail()
+ {
+ Element detail = super.getDetail();
+ Document owner = detail.getOwnerDocument();
+ detail.appendChild(XmlUtils.createElement(owner, Names.HOST_QNAME,_host));
+ detail.appendChild(XmlUtils.createElement(owner, Names.PORT_QNAME,_port));
+ detail.appendChild(XmlUtils.createElement(owner, Names.USERNAME_QNAME,_username));
+ detail.appendChild(XmlUtils.createElement(owner, Names.VIRTUAL_HOST_QNAME,_virtualHostName));
+ return detail;
+ }
+} \ 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
new file mode 100644
index 0000000000..e4d0f25adc
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/muse/engine/WSDMAdapterEnvironment.java
@@ -0,0 +1,118 @@
+package org.apache.qpid.management.wsdm.muse.engine;
+/*
+ *
+ * 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 java.io.File;
+import java.net.URI;
+
+import javax.servlet.ServletContext;
+
+import org.apache.muse.core.AbstractEnvironment;
+import org.apache.muse.util.FileUtils;
+import org.apache.muse.ws.addressing.EndpointReference;
+import org.apache.qpid.management.Messages;
+import org.apache.qpid.management.Names;
+import org.apache.qpid.management.Protocol;
+import org.apache.qpid.transport.util.Logger;
+
+/**
+ * QMan Adapter enviroment implementation.
+ *
+ * @author Andrea Gazzarini
+ */
+public class WSDMAdapterEnvironment extends AbstractEnvironment
+{
+ private final static Logger LOGGER = Logger.get(WSDMAdapterEnvironment.class);
+ private final File _realDirectory;
+ private final ServletContext _servletContext;
+
+ /**
+ * Builds a new qman environment with the given application context.
+ *
+ * @param servletContext the application context.
+ */
+ public WSDMAdapterEnvironment(ServletContext servletContext)
+ {
+ this._servletContext = servletContext;
+ String realDirectoryPath = servletContext.getRealPath(Names.WEB_APP_CLASSES_FOLDER);
+
+ _realDirectory = (realDirectoryPath != null)
+ ? new File(realDirectoryPath)
+ : FileUtils.CURRENT_DIR;
+
+ String defaultURI = getDefaultURIPrefix()+"adapter";
+ setDefaultURI(defaultURI);
+
+ LOGGER.info(Messages.QMAN_000029_DEFAULT_URI, defaultURI);
+ }
+
+ /**
+ * Returns the endpoint created starting by this application default URI.
+ *
+ * @return the endpoint created starting by this application default URI.
+ */
+ public EndpointReference getDeploymentEPR()
+ {
+ return new EndpointReference(URI.create(getDefaultURI()));
+ }
+
+ /**
+ * Returns the application classes folder.
+ *
+ * @return the application classes folder.
+ */
+ public File getRealDirectory()
+ {
+ return _realDirectory;
+ }
+
+ /**
+ * Returns the default endpoint reference URI.
+ *
+ * @return the default endpoint reference URI.
+ */
+ public String getDefaultURIPrefix()
+ {
+ return new StringBuilder()
+ .append("http://")
+ .append(System.getProperty(
+ Names.ADAPTER_HOST_PROPERTY_NAME,
+ Protocol.DEFAULT_QMAN_HOSTNAME))
+ .append(":")
+ .append(System.getProperty(
+ Names.ADAPTER_PORT_PROPERTY_NAME,
+ String.valueOf(Protocol.DEFAULT_QMAN_PORT_NUMBER)))
+ .append(_servletContext.getContextPath())
+ .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();
+ }
+}
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/muse/engine/WSDMAdapterIsolationLayer.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/muse/engine/WSDMAdapterIsolationLayer.java
new file mode 100644
index 0000000000..e9a74bf60c
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/muse/engine/WSDMAdapterIsolationLayer.java
@@ -0,0 +1,57 @@
+package org.apache.qpid.management.wsdm.muse.engine;
+/*
+ *
+ * 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 javax.servlet.ServletContext;
+
+import org.apache.muse.core.Environment;
+import org.apache.muse.core.platform.mini.MiniIsolationLayer;
+
+/**
+ * QMan specific implementation of the Apache Muse isolation layer.
+ * If you are a Muse expert you were wondering why don't we use the muse default implementation...
+ * well,
+ *
+ * @author Andrea Gazzarini
+ */
+public class WSDMAdapterIsolationLayer extends MiniIsolationLayer
+{
+ /**
+ * Builds a new isolation layer with the given application context.
+ *
+ * @param initialContext the application context.
+ */
+ public WSDMAdapterIsolationLayer(ServletContext initialContext)
+ {
+ super(null, initialContext);
+ }
+
+ /**
+ * WSDMAdapterEnvironment factory method.
+ *
+ * @return the environment.
+ */
+ protected Environment createEnvironment()
+ {
+ return new WSDMAdapterEnvironment(getInitialContext());
+ }
+}
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/muse/resources/QManWsResource.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/muse/resources/QManWsResource.java
new file mode 100644
index 0000000000..c16c156b73
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/muse/resources/QManWsResource.java
@@ -0,0 +1,762 @@
+/*
+ *
+ * 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.muse.resources;
+
+import java.lang.reflect.Method;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import javax.xml.namespace.QName;
+
+import org.apache.muse.core.Capability;
+import org.apache.muse.core.Environment;
+import org.apache.muse.core.ResourceManager;
+import org.apache.muse.core.routing.MessageHandler;
+import org.apache.muse.util.xml.XmlUtils;
+import org.apache.muse.ws.addressing.EndpointReference;
+import org.apache.muse.ws.addressing.WsaConstants;
+import org.apache.muse.ws.addressing.soap.SoapConstants;
+import org.apache.muse.ws.addressing.soap.SoapFault;
+import org.apache.muse.ws.addressing.soap.SoapUtils;
+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.impl.SimpleMetadataDescriptor;
+import org.apache.muse.ws.resource.metadata.impl.WsrmdUtils;
+import org.apache.muse.ws.resource.properties.ResourcePropertyCollection;
+import org.apache.muse.ws.resource.properties.impl.SimpleResourcePropertyCollection;
+import org.apache.muse.ws.resource.properties.impl.WsrpUtils;
+import org.apache.muse.ws.resource.properties.schema.ResourcePropertiesSchema;
+import org.apache.muse.ws.resource.properties.schema.impl.SimpleResourcePropertiesSchema;
+import org.apache.muse.ws.wsdl.WsdlUtils;
+import org.apache.qpid.management.Messages;
+import org.apache.qpid.management.wsdm.common.ThreadSessionManager;
+import org.apache.qpid.transport.util.Logger;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+/**
+ * QMan WS resource.
+ * We could say that this is a QMan manageable entity under the
+ * WS-DM perspective.
+ *
+ * @author Andrea Gazzarini
+ */
+@SuppressWarnings("unchecked")
+public class QManWsResource implements WsResource
+{
+ private final static Logger LOGGER = Logger.get(QManWsResource.class);
+
+ /**
+ * Internal state of this resource.
+ *
+ * @author Andrea Gazzarini
+ */
+ interface State
+ {
+ /**
+ * Provides initialization of this resource.
+ *
+ * @throws SoapFault when the initialization fails.
+ */
+ void initialize() throws SoapFault;
+
+ /**
+ * Returns true if this resource has been initialized.
+ *
+ * @return true if this resource has been initialized.
+ */
+ boolean hasBeenInitialized();
+
+ /**
+ * Returns true if this resource has been shutdown.
+ *
+ * @return true if this resource has been shutdown.
+ */
+ boolean hasBeenShutdown();
+
+ /**
+ * Shuts down this resource.
+ *
+ * @throws SoapFault when the shutdown procedure fails.
+ */
+ void shutdown() throws SoapFault;
+ }
+
+ private final State _hasBeenShutdown = new State()
+ {
+ /**
+ * Return false because this resource has been shutdown so therefore
+ * initialization occurred.
+ *
+ * @return true;
+ */
+ public boolean hasBeenInitialized()
+ {
+ return true;
+ }
+
+ /**
+ * Returns true because this state indicates that resource has been shutdown.
+ *
+ * @return true.
+ */
+ public boolean hasBeenShutdown()
+ {
+ return true;
+ }
+
+ /**
+ * Since this resource has been shutdown the initialization
+ * cannot be performed again.
+ * As conseguence of that this method throws an exception.
+ *
+ * @throws SoapFault each time this method is called.
+ */
+ public void initialize() throws SoapFault
+ {
+ LOGGER.error(Messages.QMAN_100031_WS_RESOURCE_ALREADY_INITIALIZED);
+ throw new SoapFault(Messages.QMAN_100031_WS_RESOURCE_ALREADY_INITIALIZED);
+ }
+
+ public void shutdown() throws SoapFault
+ {
+ LOGGER.error(Messages.QMAN_100033_WS_RESOURCE_ALREADY_SHUTDOWN);
+ throw new SoapFault(Messages.QMAN_100033_WS_RESOURCE_ALREADY_SHUTDOWN);
+ }
+ };
+
+ private final State _hasBeenInitialized = new State()
+ {
+ /**
+ * Returns true because this is the state where a resource is when it
+ * has been initialized.
+ *
+ * @return true.
+ */
+ public boolean hasBeenInitialized()
+ {
+ return true;
+ }
+
+ /**
+ * Returns false because this resource has been initialized but no shutdown request
+ * has been received.
+ *
+ * @return false.
+ */
+ public boolean hasBeenShutdown()
+ {
+ return false;
+ }
+
+ /**
+ * A resource in this state cannot be initialized again so if this method is called an
+ * exception is thrown.
+ *
+ * @throws SoapFault each time this method is called.
+ */
+ public void initialize() throws SoapFault
+ {
+ LOGGER.error(Messages.QMAN_100031_WS_RESOURCE_ALREADY_INITIALIZED);
+ throw new SoapFault(Messages.QMAN_100031_WS_RESOURCE_ALREADY_INITIALIZED);
+ }
+
+ /**
+ * Shuts down this resource.
+ *
+ * @throws SoapFault when the shutdown procedure fails.
+ */
+ public void shutdown() throws SoapFault
+ {
+ shutdownCapabilities();
+
+ ResourceManager manager = getResourceManager();
+
+ if (manager.getResource(_enpointReference) != null)
+ {
+ manager.removeResource(_enpointReference);
+ }
+
+ _currentState = _hasBeenShutdown;
+ }
+ };
+
+ /**
+ * The initial state of this resource.
+ * As the name suggests, it is not yet initialized.
+ */
+ private final State _notYetInitialized = new State()
+ {
+ /**
+ * Provides initialization of this resource.
+ *
+ * @throws SoapFault when the initialization fails.
+ */
+ public void initialize() throws SoapFault
+ {
+ _properties = new SimpleResourcePropertyCollection();
+ _wsdl = ThreadSessionManager.getInstance().getSession().getWsdlDocument();
+
+ ResourcePropertiesSchema schema = createPropertiesSchema(_wsdl);
+ _properties.setSchema(schema);
+
+ MetadataDescriptor metadata = createMetadataDescriptor(_wsdl);
+ _properties.setMetadata(metadata);
+
+ initializeCapabilities();
+
+ _properties.applyMetadata();
+
+ // Resource intialization completed : Let's make a state change.
+ _currentState = _hasBeenInitialized;
+ }
+
+ /**
+ * Shuts down this resource.
+ *
+ * @throws SoapFault when the shutdown procedure fails. */
+ public void shutdown() throws SoapFault
+ {
+ LOGGER.error(Messages.QMAN_100032_WS_RESOURCE_NOT_YET_INITIALIZED);
+ throw new SoapFault(Messages.QMAN_100032_WS_RESOURCE_NOT_YET_INITIALIZED);
+ }
+
+ /**
+ * Returns false because this state indicates that
+ * the resource has not yet been initialized.
+ *
+ * @return false;
+ */
+ public boolean hasBeenInitialized()
+ {
+ return false;
+ }
+
+ /**
+ * Returns false because the resource, when is in this state
+ * hasn't been initialized and as conseguence of that hasn't
+ * been shutdonm.
+ *
+ * @return false;
+ */
+ public boolean hasBeenShutdown()
+ {
+ return false;
+ }
+ };
+
+ private Map<String,Capability> _capabilitiesByAction = new HashMap<String, Capability>();
+ private Map<String, Capability> _capabilitiesByURI = new LinkedHashMap<String, Capability>();
+
+ private String _contextPath;
+ private Environment _environment;
+ private EndpointReference _enpointReference;
+
+ private State _currentState = _notYetInitialized;
+
+ private ResourceManager _resourceManager;
+ private ResourcePropertyCollection _properties;
+
+ private Map<String,String> _initParameters = Collections.EMPTY_MAP;
+
+ // Workaround : muse is using and hardcoded java.util.logging.Logger but we should use
+ // SLF4j so this is the original implementatation that won't never be used (on QMan classes)
+ private java.util.logging.Logger _logger;
+
+ private Document _wsdl;
+ private String _wsdlPath;
+ private QName _wsdlPortType;
+
+ /**
+ * Adds the given capability to this resource.
+ *
+ * @param capability the capability to be added.
+ */
+ public void addCapability(Capability capability)
+ {
+ capability.setResource(this);
+ capability.setLog(getLog());
+ capability.setEnvironment(getEnvironment());
+
+ String uri = capability.getCapabilityURI();
+ _capabilitiesByURI.put(uri, capability);
+
+ LOGGER.debug(
+ Messages.QMAN_200033_CAPABILITY_CLASS_HAS_BEEN_ADDED,
+ capability.getClass(),
+ uri);
+ }
+
+ /**
+ * Returns the capability associated with the given URI.
+ *
+ * @return the capability associated with the given URI.
+ */
+ public Capability getCapability(String capabilityURI)
+ {
+ return _capabilitiesByURI.get(capabilityURI);
+ }
+
+ /**
+ * Returns a collection with all registered capability URIs.
+ *
+ * @return a collection with all registered capability URIs.
+ */
+ public final Collection getCapabilityURIs()
+ {
+ return Collections.unmodifiableSet(_capabilitiesByURI.keySet());
+ }
+
+ /**
+ * Returns the context path of this resource.
+ *
+ * @return the context path of this resource.
+ */
+ public final String getContextPath()
+ {
+ return _contextPath;
+ }
+
+ /**
+ * Returns the endpoint reference of this resource.
+ *
+ * @return the endpoint reference of this resource.
+ */
+ public EndpointReference getEndpointReference()
+ {
+ return _enpointReference;
+ }
+
+ /**
+ * Returns the enviroment associated with this resource.
+ *
+ * @return the enviroment associated with this resource.
+ */
+ public final Environment getEnvironment()
+ {
+ return _environment;
+ }
+
+ /**
+ * Returns the initialization parameter of this resource associated with
+ * the given name.
+ *
+ * @param name the init parameter name.
+ * @return the initialization parameter associated with the given name.
+ */
+ public final String getInitializationParameter(String name)
+ {
+ return (String)getInitializationParameters().get(name);
+ }
+
+ /**
+ * Returns the map containing all init parameters of this resource.
+ *
+ * @return the map containing all init parameters of this resource.
+ */
+ public final Map<String,String> getInitializationParameters()
+ {
+ return _initParameters;
+ }
+
+ /**
+ * N.A. This resource uses QMan logging instead of plain java.util.logger
+ * implementation.
+ */
+ public final java.util.logging.Logger getLog()
+ {
+ return _logger;
+ }
+
+ /**
+ * Returns the resource manager associated with this resource.
+ *
+ * @return the resource manager associated with this resource.
+ */
+ public ResourceManager getResourceManager()
+ {
+ return _resourceManager;
+ }
+
+ /**
+ * Returns the wsdl (relative) path of this resource.
+ *
+ * @return the wsdl (relative) path of this resource.
+ */
+ public String getWsdlPath()
+ {
+ return _wsdlPath;
+ }
+
+ /**
+ * Returns the port type of this resource.
+ *
+ * @return the port type of this resource.
+ */
+ public final QName getWsdlPortType()
+ {
+ return _wsdlPortType;
+ }
+
+ /**
+ * Returns true if this resource has been initialized, false otherwise.
+ *
+ * @return true if this resource has been initialized, false otherwise.
+ */
+ public final boolean hasBeenInitialized()
+ {
+ return _currentState.hasBeenInitialized();
+ }
+
+ /**
+ * Returns true if this resource has been shutdown, false otherwise.
+ *
+ * @return true if this resource has been shutdown, false otherwise.
+ */
+ public final boolean hasBeenShutdown()
+ {
+ return _currentState.hasBeenShutdown();
+ }
+
+ /**
+ * Checks if a capability with the given URI is available for this resource.
+ *
+ * @return true if a capability with the given URI is available for this resource, false otherwise.
+ */
+ public final boolean hasCapability(String capabilityURI)
+ {
+ return getCapability(capabilityURI) != null;
+ }
+
+ /**
+ * Returns the collection containing all properties of this resource.
+ *
+ * @return the collection containing all properties of this resource.
+ */
+ public final ResourcePropertyCollection getPropertyCollection()
+ {
+ return _properties;
+ }
+
+ /**
+ * Return the WSDL document of this resource.
+ *
+ * @return the WSDL document of this resource.
+ */
+ public Document getWsdl()
+ {
+ return _wsdl;
+ }
+
+ /**
+ * Initializes this resources.
+ * Note that the what needs to be done depends on the current state of this
+ * resource.
+ *
+ * @throws SoapFault when the initialization fails.
+ */
+ public void initialize() throws SoapFault
+ {
+ _currentState.initialize();
+ }
+
+ /**
+ * Invokes the action specified in the given soap request on this resource.
+ *
+ * @param requestBody the SOAP body.
+ * @return the result of the invocation as org.w3c.dom.Element
+ */
+ public Element invoke(Element requestBody)
+ {
+ String action = _environment.getAddressingContext().getAction();
+ Capability capability = getCapabilityForAction(action);
+
+ // Sanity check : is there a capability for the given action?
+ if (capability == null)
+ {
+ SoapFault wsaFault = new SoapFault(
+ String.format(
+ Messages.ACTION_NOT_SUPPORTED,
+ action,getContextPath()));
+
+ wsaFault.setCode(SoapConstants.SENDER_QNAME);
+ wsaFault.setSubCode(WsaConstants.ACTION_NOT_SUPPORTED_FAULT_QNAME);
+
+ Element detail = XmlUtils.createElement(WsaConstants.PROBLEM_ACTION_QNAME);
+ XmlUtils.setElement(detail, WsaConstants.ACTION_QNAME, action);
+ wsaFault.setDetail(detail);
+
+ LOGGER.error(
+ Messages.QMAN_100020_ACTION_NOT_SUPPORTED,
+ action,
+ getContextPath());
+
+ return wsaFault.toXML();
+ }
+
+ MessageHandler handler = capability.getMessageHandler(action);
+ Method method = handler.getMethod();
+
+ try
+ {
+ Object[]parameters = handler.fromXML(requestBody);
+ Object result = method.invoke(capability, parameters);
+ return handler.toXML(result);
+ }
+ catch (Throwable throwable)
+ {
+ LOGGER.error(
+ throwable,
+ Messages.QMAN_100037_INVOKE_OPERATION_FAILURE);
+
+ SoapFault response = SoapUtils.convertToFault(
+ (throwable.getCause()!= null)
+ ? throwable.getCause()
+ : throwable);
+ return response.toXML();
+ }
+ }
+
+ /**
+ * Sets the context path of this resource.
+ *
+ * @param contextPath the context path of this resource.
+ */
+ public final void setContextPath(String contextPath)
+ {
+ _contextPath = contextPath;
+ }
+
+ /**
+ * Sets the endpoint reference of this resource.
+ *
+ * @param endpointReference the endpoint reference of this resource.
+ */
+ public final void setEndpointReference(EndpointReference endpointReference)
+ {
+ if (_enpointReference != null && hasBeenInitialized())
+ throw new RuntimeException(("ExistingResourceEPR"));
+
+ _enpointReference = endpointReference;
+ }
+
+ /**
+ * Sets the context environment of this resource.
+ *
+ * @param environment the context environment of this resource.
+ */
+ public final void setEnvironment(Environment environment)
+ {
+ _environment = environment;
+ }
+
+ /**
+ * Sets the initialization parameters of this resource.
+ *
+ * @param parameters the init parameters of this resource.
+ */
+ public final void setInitializationParameters(Map parameters)
+ {
+ _initParameters = (parameters != null)
+ ? parameters
+ : Collections.EMPTY_MAP;
+ }
+
+ /**
+ * N.A. for this resource. QMan logging mechanism is used for that.
+ */
+ public final void setLog(java.util.logging.Logger log)
+ {
+ _logger = log;
+ }
+
+ /**
+ * Sets the resource manager owner of this resource.
+ *
+ * @param manager the resource manager of this resource.
+ */
+ public void setResourceManager(ResourceManager manager)
+ {
+ _resourceManager = manager;
+ }
+
+ /**
+ * Sets the WSDL (relative) path of this resource.
+ *
+ * @param wsdlPath the WSDL (relative) path of this resource.
+ */
+ public final void setWsdlPath(String wsdlPath)
+ {
+ this._wsdlPath = wsdlPath;
+ }
+
+ /**
+ * Sets the port type of this resource.
+ *
+ * @param wsdlPortType the port type of this resource.
+ */
+ public final void setWsdlPortType(QName wsdlPortType)
+ {
+ _wsdlPortType = wsdlPortType;
+ }
+
+ /**
+ * Shutdown procedure for this resource.
+ *
+ * @throws SoapFault when the shutdown procedure fails.
+ */
+ public synchronized void shutdown() throws SoapFault
+ {
+ _currentState.shutdown();
+ }
+
+ /**
+ * Returns a string representation of this resource.
+ * Basically the resource endpoint reference (as a string) is returned.
+ *
+ * @return the resource endpoint reference (as a string) is returned.
+ */
+ public String toString()
+ {
+ return getEndpointReference().toString();
+ }
+
+ /**
+ * Initializes capabilities of this resource.
+ *
+ * @throws SoapFault when at least one capability fails to initialize.
+ */
+ private void initializeCapabilities() throws SoapFault
+ {
+ for (Entry<String, Capability> entry : _capabilitiesByURI.entrySet())
+ {
+ Capability capability = entry.getValue();
+ capability.initialize();
+
+ for (Object action : capability.getActions())
+ {
+ _capabilitiesByAction.put((String)action, capability);
+ }
+
+ capability.initializeCompleted();
+ }
+ }
+
+ /**
+ * Shutdown procedure for all registered capabilities of this resource.
+ *
+ * @throws SoapFault when at least one capability shutdown fails.
+ */
+ private void shutdownCapabilities() throws SoapFault
+ {
+ for (Entry<String,Capability> entry : _capabilitiesByURI.entrySet())
+ {
+ Capability capabilty = entry.getValue();
+ capabilty.prepareShutdown();
+ capabilty.shutdown();
+ }
+ }
+
+ /**
+ * Creates a metadata descriptor for this resource.
+ *
+ * @param wsdl the WSDL document.
+ * @return a metadata descriptor for this resource.
+ * @throws SoapFault when it's not possible build the descriptor.
+ */
+ private MetadataDescriptor createMetadataDescriptor(Document wsdl) throws SoapFault
+ {
+ try
+ {
+ Element portTypeXML = WsdlUtils.getPortType(wsdl, getWsdlPortType());
+
+ String rmdName = XmlUtils.getAttribute(
+ portTypeXML,
+ WsrmdConstants.DESCRIPTOR_ATTR_QNAME);
+
+ String rmdPath = XmlUtils.getAttribute(
+ portTypeXML,
+ WsrmdConstants.DESCRIPTOR_LOCATION_ATTR_QNAME);
+
+ LOGGER.debug(Messages.QMAN_200034_RMD_NAME, rmdName);
+ LOGGER.debug(Messages.QMAN_200035_RMD_PATH, rmdPath);
+
+ Environment env = getEnvironment();
+ String path = env.createRelativePath(getWsdlPath(), rmdPath);
+ Document rmdDoc = env.getDocument(path);
+
+ Element[] additionalProperties =
+ ThreadSessionManager
+ .getInstance()
+ .getSession()
+ .getResourceMetadataDescriptor();
+
+ Element metadataDescriptor = WsrmdUtils.getMetadataDescriptor(rmdDoc, rmdName);
+
+ for (Element element : additionalProperties)
+ {
+
+// rmdDoc.importNode(element, true);
+ Element adopted = (Element) rmdDoc.importNode(element,false);
+ metadataDescriptor.appendChild(adopted);
+ }
+
+ return new SimpleMetadataDescriptor(metadataDescriptor);
+ }
+ catch(Exception exception)
+ {
+ LOGGER.error(
+ exception,
+ Messages.QMAN_100021_RMD_BUID_FAILURE,
+ getContextPath());
+ throw new SoapFault(exception);
+ }
+ }
+
+ /**
+ * Returns the capability associated with the given action.
+ *
+ * @param action the wsa:action of the requested capability.
+ * @return the capability associated with the given action.
+ */
+ private Capability getCapabilityForAction(String action)
+ {
+ return (Capability)_capabilitiesByAction.get(action);
+ }
+
+ /**
+ * Creates a WSRP document representing schema properties for this resource.
+ *
+ * @param wsdl the DOM document holding the resource's WSDL.
+ * @return the WSRP document schema.
+ */
+ private ResourcePropertiesSchema createPropertiesSchema(Document wsdl)
+ {
+ QName wsrpName = WsrpUtils.getPropertiesName(wsdl, getWsdlPortType());
+ Element wsrpDoc = WsdlUtils.getElementDeclaration(wsdl, wsrpName);
+ return new SimpleResourcePropertiesSchema(wsrpName, wsrpDoc);
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/muse/serializer/ByteArraySerializer.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/muse/serializer/ByteArraySerializer.java
new file mode 100644
index 0000000000..a064542658
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/muse/serializer/ByteArraySerializer.java
@@ -0,0 +1,83 @@
+/*
+ *
+ * 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.muse.serializer;
+
+import javax.xml.XMLConstants;
+import javax.xml.namespace.QName;
+
+import org.apache.muse.core.serializer.Serializer;
+import org.apache.muse.util.xml.XmlUtils;
+import org.apache.muse.ws.addressing.soap.SoapFault;
+import org.apache.xerces.impl.dv.util.Base64;
+import org.w3c.dom.Element;
+
+/**
+ * Implementation of Muse Serializer for byte array type.
+ *
+ * @author Andrea Gazzarini
+ */
+public class ByteArraySerializer implements Serializer {
+
+ /**
+ * Return a byte array representation of the given xml element.
+ *
+ * @param xml the element to unmarshal.
+ * @throws SoapFault when the unmarshalling fails.
+ */
+ public Object fromXML(Element xml) throws SoapFault
+ {
+ try
+ {
+ return Base64.decode(xml.getTextContent());
+ } catch (Exception exception)
+ {
+ throw new SoapFault(exception);
+ }
+ }
+
+ /**
+ * Returns the java type associated to this class.
+ *
+ * @return the java type associated to this class.
+ */
+ public Class<?> getSerializableType()
+ {
+ return byte[].class;
+ }
+
+ /**
+ * Return an xml representation of the given byte array with the given name.
+ *
+ * @param object the byte array to marshal.
+ * @param qname the qualified (xml) name of the object to use in xml representation.
+ * @return the xml representation of the byte array.
+ * @throws SoapFault when the marshalling fails.
+ */
+ public Element toXML(Object object, QName qname) throws SoapFault
+ {
+ Element element = XmlUtils.createElement(
+ qname,
+ Base64.encode((byte[]) object));
+ element.setAttribute("xmlns:xsi", XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI);
+ element.setAttribute("xsi:type","xsd:base64Binary");
+ return element;
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/muse/serializer/DateSerializer.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/muse/serializer/DateSerializer.java
new file mode 100644
index 0000000000..60350ccc31
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/muse/serializer/DateSerializer.java
@@ -0,0 +1,75 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.management.wsdm.muse.serializer;
+
+import java.util.Date;
+
+import javax.xml.namespace.QName;
+
+import org.apache.muse.core.serializer.Serializer;
+import org.apache.muse.util.xml.XmlUtils;
+import org.apache.muse.ws.addressing.soap.SoapFault;
+import org.w3c.dom.Element;
+
+/**
+ * Implementation of Muse Serializer for Date type.
+ * Note that Muse already ships a serializer but the formatter used on that class
+ * is losing precision betweem marshal / unmarshal operations.
+ *
+ * @author Andrea Gazzarini
+ */
+public class DateSerializer implements Serializer
+{
+ /**
+ * Return a Date representation of the given xml element.
+ *
+ * @param xml the element to unmarshal.
+ * @throws SoapFault when the unmarshalling fails.
+ */
+ public Object fromXML(Element elementData) throws SoapFault
+ {
+ return new Date(Long.parseLong(elementData.getTextContent()));
+ }
+
+ /**
+ * Returns the java type associated to this class.
+ *
+ * @return the java type associated to this class.
+ */
+ public Class<?> getSerializableType()
+ {
+ return Date.class;
+ }
+
+ /**
+ * Return an xml representation of the given UUID with the given name.
+ *
+ * @param object the UUID to marshal.
+ * @param qname the qualified (xml) name of the object to use in xml representation.
+ * @return the xml representation of the UUID.
+ * @throws SoapFault when the marshalling fails.
+ */
+ public Element toXML(Object obj, QName qname) throws SoapFault
+ {
+ Date date = (Date) obj;
+ return XmlUtils.createElement(qname, String.valueOf(date.getTime()));
+ }
+} \ 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
new file mode 100644
index 0000000000..b819d52ad1
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/muse/serializer/InvocationResultSerializer.java
@@ -0,0 +1,85 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.management.wsdm.muse.serializer;
+
+import java.util.Map;
+
+import javax.xml.namespace.QName;
+
+import org.apache.muse.core.serializer.Serializer;
+import org.apache.muse.core.serializer.SerializerRegistry;
+import org.apache.muse.util.xml.XmlUtils;
+import org.apache.muse.ws.addressing.soap.SoapFault;
+import org.apache.qpid.management.wsdm.capabilities.Result;
+import org.w3c.dom.Element;
+
+/**
+ * Implementation of Muse Serializer for Result type.
+ *
+ * @author Andrea Gazzarini
+ */
+public class InvocationResultSerializer implements Serializer
+{
+ private Serializer _mapSerializer = SerializerRegistry.getInstance().getSerializer(Map.class);
+
+ /**
+ * Return a UUID representation of the given xml element.
+ *
+ * @param xml the element to unmarshal.
+ * @throws SoapFault when the unmarshalling fails.
+ */
+ @SuppressWarnings("unchecked")
+ public Object fromXML(Element elementData) throws SoapFault
+ {
+ Element outputParameters = XmlUtils.getFirstElement(elementData);
+ return new Result((Map<String, Object>) _mapSerializer.fromXML(outputParameters));
+ }
+
+ /**
+ * Returns the java type associated to this class.
+ *
+ * @return the java type associated to this class.
+ */
+ public Class<?> getSerializableType()
+ {
+ return Result.class;
+ }
+
+ /**
+ * Return an xml representation of the given UUID with the given name.
+ *
+ * @param object the UUID to marshal.
+ * @param qname the qualified (xml) name of the object to use in xml representation.
+ * @return the xml representation of the UUID.
+ * @throws SoapFault when the marshalling fails.
+ */
+ public Element toXML(Object obj, QName qname) throws SoapFault
+ {
+ Result result = (Result) obj;
+ Element root = XmlUtils.createElement(qname);
+ if (result.getOutputParameters() != null)
+ {
+ Element outputSection = SerializerRegistry.getInstance().getSerializer(Map.class).toXML(result.getOutputParameters(), new QName("outputParameters"));
+ root.appendChild(outputSection);
+ }
+ 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
new file mode 100644
index 0000000000..07e1dfdc56
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/muse/serializer/MapSerializer.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.muse.serializer;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import javax.xml.XMLConstants;
+import javax.xml.namespace.QName;
+
+import org.apache.muse.core.serializer.Serializer;
+import org.apache.muse.core.serializer.SerializerRegistry;
+import org.apache.muse.util.xml.XmlUtils;
+import org.apache.muse.ws.addressing.soap.SoapFault;
+import org.apache.qpid.management.Names;
+import org.w3c.dom.Element;
+
+/**
+ * Implementation of Muse Serializer for Map type.
+ *
+ * <amspam>
+ * <entry>
+ * <key>
+ * <value>
+ * </entry>
+ * </amsasm>
+ *
+ * @author Andrea Gazzarini
+ */
+public class MapSerializer implements Serializer
+{
+
+ ByteArraySerializer _byteArraySerializer = new ByteArraySerializer();
+ Serializer _objectSerializer = SerializerRegistry.getInstance().getSerializer(Object.class);
+ Serializer _stringSerializer = SerializerRegistry.getInstance().getSerializer(String.class);
+
+ /**
+ * Return a map representation of the given xml element.
+ *
+ * @param xml the element to unmarshal.
+ * @throws SoapFault when the unmarshalling fails.
+ */
+ public Object fromXML(Element xml) throws SoapFault
+ {
+ Map<Object,Object> result = new HashMap<Object,Object>();
+
+ if (xml != null)
+ {
+ Element[] children = XmlUtils.getAllElements(xml);
+ Serializer objectDeserializer = SerializerRegistry.getInstance().getSerializer(Object.class);
+
+ for (Element entry : children)
+ {
+ Element[] keysAndValues = XmlUtils.getAllElements(entry);
+ Object key = null;
+ Object value = null;
+ for (Element element : keysAndValues)
+ {
+ 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);
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Returns the java type associated to this class.
+ *
+ * @return the java type associated to this class.
+ */
+ public Class<?> getSerializableType()
+ {
+ return Map.class;
+ }
+
+ /**
+ * Return an xml representation of the given Map with the given name.
+ *
+ * @param object the Map to marshal.
+ * @param qname the qualified (xml) name of the object to use in xml representation.
+ * @return the xml representation of the given Map.
+ * @throws SoapFault when the marshalling fails.
+ */
+ public Element toXML(Object obj, QName qname) throws SoapFault
+ {
+
+ Map<?, ?> data = (Map<?, ?>) obj;
+
+ QName entryQName = new QName(qname.getNamespaceURI(),Names.ENTRY,qname.getPrefix());
+ QName keyQName = new QName(qname.getNamespaceURI(),Names.KEY,qname.getPrefix());
+ QName valueQName = new QName(qname.getNamespaceURI(),Names.VALUE,qname.getPrefix());
+
+ Element root = XmlUtils.createElement(qname);
+ root.setAttribute("xmlns:xsi", XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI);
+ for (Entry<?, ?> mapEntry: data.entrySet())
+ {
+ Element entry = XmlUtils.createElement(entryQName);
+ entry.appendChild(_stringSerializer.toXML(mapEntry.getKey(), keyQName));
+ if (mapEntry.getValue().getClass() == byte[].class) {
+ entry.appendChild(_byteArraySerializer.toXML(mapEntry.getValue(), valueQName));
+ } else {
+ entry.appendChild(_objectSerializer.toXML(mapEntry.getValue(), valueQName));
+ }
+ root.appendChild(entry);
+ }
+ 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/ObjectSerializer.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/muse/serializer/ObjectSerializer.java
new file mode 100644
index 0000000000..ff0c69cdda
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/muse/serializer/ObjectSerializer.java
@@ -0,0 +1,202 @@
+/*
+ *
+ * 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.muse.serializer;
+
+import java.net.URI;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
+
+import javax.xml.XMLConstants;
+import javax.xml.namespace.QName;
+
+import org.apache.muse.core.serializer.Serializer;
+import org.apache.muse.core.serializer.SerializerRegistry;
+import org.apache.muse.ws.addressing.soap.SoapFault;
+import org.apache.qpid.management.Names;
+import org.w3c.dom.Attr;
+import org.w3c.dom.Element;
+
+/**
+ * Generic Serializer for objects.
+ * It is a general-purpose serializer used for encoding Object values.
+ */
+public class ObjectSerializer implements Serializer
+{
+ /**
+ * Mapping between xsd and java types.
+ */
+ private Map<String, Class<?>> xml2Java = new HashMap<String, Class<?>>();
+ {
+ xml2Java.put("xsd:long", Long.class);
+ xml2Java.put("xsd:boolean",Boolean.class);
+ xml2Java.put("xsd:double",Double.class);
+ xml2Java.put("xsd:float",Float.class);
+ xml2Java.put("xsd:integer",Integer.class);
+ xml2Java.put("xsd:int",Integer.class);
+ xml2Java.put("xsd:short",Short.class);
+ xml2Java.put("xsd:string",String.class);
+ xml2Java.put("xsd:anyURI",URI.class);
+ xml2Java.put("xsd:dateTime",Date.class);
+ xml2Java.put("xsd:QName",QName.class);
+ xml2Java.put("xsd:element",Element.class);
+ xml2Java.put("xsd:base64Binary",byte[].class);
+ xml2Java.put("qman:arrayOfLong",Long[].class);
+ xml2Java.put("qman:arrayOfBoolean",Boolean[].class);
+ xml2Java.put("qman:arrayOfDouble",Double[].class);
+ xml2Java.put("qman:arrayOfFloat",Float[].class);
+ xml2Java.put("qman:arrayOfInteger",Integer[].class);
+ xml2Java.put("qman:arrayOfShort",Short[].class);
+ xml2Java.put("qman:arrayOfString",String[].class);
+ xml2Java.put("qman:arrayOfURI",URI[].class);
+ xml2Java.put("qman:arrayOfDate",Date[].class);
+ xml2Java.put("qman:uuid",UUID.class);
+ xml2Java.put("qman:map",Map.class);
+ xml2Java.put("qman:map",HashMap.class);
+ }
+
+ private Map<Class<?>, String> java2Xml = new HashMap<Class<?>, String>();
+ {
+ java2Xml.put(UUID.class,"qman:uuid");
+ java2Xml.put(Long.class,"xsd:long");
+ java2Xml.put(long.class,"xsd:long");
+ java2Xml.put(Boolean.class,"xsd:boolean");
+ java2Xml.put(boolean.class,"xsd:boolean");
+ java2Xml.put(Double.class,"xsd:double");
+ java2Xml.put(double.class,"xsd:double");
+ java2Xml.put(Float.class,"xsd:float");
+ java2Xml.put(float.class,"xsd:float");
+ java2Xml.put(Integer.class,"xsd:integer");
+ java2Xml.put(int.class,"xsd:integer");
+ java2Xml.put(Short.class,"xsd:short");
+ java2Xml.put(short.class,"xsd:short");
+ java2Xml.put(String.class,"xsd:string");
+ java2Xml.put(URI.class,"xsd:anyURI");
+ java2Xml.put(Date.class,"xsd:dateTime");
+ java2Xml.put(QName.class,"xsd:QName");
+ java2Xml.put(Element.class,"xsd:element");
+ java2Xml.put(byte[].class,"xsd:base64Binary");
+ java2Xml.put(Long[].class,"qman:arrayOfLong");
+ java2Xml.put(long[].class,"qman:arrayOfLong");
+ java2Xml.put(Boolean[].class,"qman:arrayOfBoolean");
+ java2Xml.put(boolean[].class,"qman:arrayOfBoolean");
+ java2Xml.put(Double[].class,"qman:arrayOfDouble");
+ java2Xml.put(double[].class,"qman:arrayOfDouble");
+ java2Xml.put(Float[].class,"qman:arrayOfFloat");
+ java2Xml.put(float[].class,"qman:arrayOfFloat");
+ java2Xml.put(Integer[].class,"qman:arrayOfInteger");
+ java2Xml.put(int[].class,"qman:arrayOfInteger");
+ java2Xml.put(Short[].class,"qman:arrayOfShort");
+ java2Xml.put(short[].class,"qman:arrayOfShort");
+ java2Xml.put(String[].class,"qman:arrayOfString");
+ java2Xml.put(URI[].class,"qman:arrayOfURI");
+ java2Xml.put(Date[].class,"qman:arrayOfDate");
+ java2Xml.put(Map.class,"qman:map");
+ java2Xml.put(HashMap.class,"qman:map");
+ }
+
+ /**
+ * Converts the incoming element into the appropriate Java type.
+ * The method will fail if :
+ *
+ * <br>1) The element has no xsi:type attribute;
+ * <br>2) The xsi:type attribute has no corresponding java type on this serializer mappings.
+ *
+ * @param elementData the xml element containing data to be unmarshalled.l
+ * @return the java object as result of xml element unmarshalling.
+ * @throws SoapFault when the marshalling fails.
+ */
+ public Object fromXML(Element elementData) throws SoapFault
+ {
+ Attr typeAttribute = elementData.getAttributeNodeNS(
+ XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI,
+ Names.TYPE);
+
+ if (typeAttribute == null)
+ {
+ throw new SoapFault(
+ "No type attribute was found for the current element. " +
+ "If you are using this serializer, in order to unmarshal the" +
+ " opportune type the xsi:type must be specified.");
+ }
+
+ Class<?> clazz = xml2Java.get(typeAttribute.getValue());
+
+ if (clazz == null)
+ {
+ throw new SoapFault(
+ String.format(
+ "No corresponding class was found on this serializer mappings for xsi:type %s.",
+ typeAttribute));
+ }
+
+ if (clazz == byte[].class) {
+ return new ByteArraySerializer().fromXML(elementData);
+ }
+
+ return SerializerRegistry.getInstance().getSerializer(clazz).fromXML(elementData);
+ }
+
+ /**
+ * As this serializer is supposed to deal with generic object types, this method returns Object.class.
+ *
+ * @return Object.class
+ */
+ public Class<?> getSerializableType()
+ {
+ return Object.class;
+ }
+
+ /**
+ * Converts the given object (with the given qname) in XML format.
+ * This method fails if there's no corresponding xml type for the given runtime type of the input object.
+ *
+ * @param obj the object to be marshalled.
+ * @param qname the qualified name that will be used in encoding.
+ */
+ public Element toXML(Object obj, QName qname) throws SoapFault
+ {
+ Class<?> clazz = obj.getClass();
+
+ Element result = null;
+
+ if (clazz == byte[].class) {
+ result = new ByteArraySerializer().toXML(obj,qname);
+ }
+ else {
+ result = SerializerRegistry.getInstance().getSerializer(clazz).toXML(obj,qname);
+ }
+ result.setAttribute(Names.XSI_TYPE, java2Xml.get(clazz));
+ return result;
+ }
+
+ /**
+ * Returns the xml type associated with the given class.
+ *
+ * @param clazz the class.
+ * @return the xml type associated with the given class.
+ */
+ public String getXmlType(Class<?> clazz)
+ {
+ return java2Xml.get(clazz);
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/muse/serializer/UUIDSerializer.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/muse/serializer/UUIDSerializer.java
new file mode 100644
index 0000000000..408a8de6cf
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/muse/serializer/UUIDSerializer.java
@@ -0,0 +1,72 @@
+/*
+ *
+ * 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.muse.serializer;
+
+import java.util.UUID;
+
+import javax.xml.namespace.QName;
+
+import org.apache.muse.core.serializer.Serializer;
+import org.apache.muse.util.xml.XmlUtils;
+import org.apache.muse.ws.addressing.soap.SoapFault;
+import org.w3c.dom.Element;
+
+/**
+ * Implementation of Muse Serializer for UUID type.
+ *
+ * @author Andrea Gazzarini
+ */
+public class UUIDSerializer implements Serializer
+{
+ /**
+ * Return a UUID representation of the given xml element.
+ *
+ * @param xml the element to unmarshal.
+ * @throws SoapFault when the unmarshalling fails.
+ */
+ public Object fromXML(Element elementData) throws SoapFault
+ {
+ return UUID.fromString(elementData.getTextContent());
+ }
+
+ /**
+ * Returns the java type associated to this class.
+ *
+ * @return the java type associated to this class.
+ */
+ public Class<?> getSerializableType()
+ {
+ return UUID.class;
+ }
+
+ /**
+ * Return an xml representation of the given UUID with the given name.
+ *
+ * @param object the UUID to marshal.
+ * @param qname the qualified (xml) name of the object to use in xml representation.
+ * @return the xml representation of the UUID.
+ * @throws SoapFault when the marshalling fails.
+ */
+ public Element toXML(Object obj, QName qname) throws SoapFault
+ {
+ return XmlUtils.createElement(qname, String.valueOf(obj));
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/notifications/LifeCycleEvent.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/notifications/LifeCycleEvent.java
new file mode 100644
index 0000000000..9284a62461
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/notifications/LifeCycleEvent.java
@@ -0,0 +1,149 @@
+/*
+ *
+ * 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.notifications;
+
+import org.apache.muse.util.xml.XmlSerializable;
+import org.apache.muse.util.xml.XmlUtils;
+import org.apache.qpid.management.Names;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+/**
+ * Object representation of a QMan entity lifecycle event notification.
+ * Note that with entity we mean both object(s) and event(s).
+ *
+ * At the moment there are only two types of lifecycle events : CREATE and REMOVE.
+ * The first one if fired when a new instance (event or object) is created, while the second
+ * one is fired when an object instance (events are transient objects so they are not destroyed)
+ * is removed.
+ *
+ * Developer Note : The marshal & unmarshal ops could be handled using JAXB but
+ * we are not sure about the running environment (JAXB libs were included only
+ * starting from 1.6)
+ *
+ * This is the event XML representation :
+ *
+ * <LifecycleEvent Type="created" timemillis="">
+ <Resource>
+ <ResourceId>16038bd5-b62b-4e86-9833-7560ed57b474</id>
+ <Package>org.qpid.apache.broker</package>
+ <Name>session</name>
+ </Resource>
+ </lifecycle-event>
+
+ * @author Andrea Gazzarini
+ */
+public class LifeCycleEvent implements XmlSerializable
+{
+ private final String _resourceId;
+ private final String _packageName;
+ private final String _name;
+
+ private final LifeCycleEventType _type;
+
+ /**
+ * Builds a new event with the given data.
+ *
+ * @param resourceId resource identifier.
+ * @param packageName resource package name.
+ * @param name resource name.
+ * @param type event type.
+ */
+ private LifeCycleEvent(String resourceId, String packageName, String name, LifeCycleEventType type)
+ {
+ this._resourceId = resourceId;
+ this._packageName = packageName;
+ this._name = name;
+ this._type = type;
+ }
+
+ /**
+ * Factory method for a new "CREATE" event.
+ * Builds a new "CREATE" event with the given data.
+ *
+ * @param resourceId resource identifier.
+ * @param packageName resource package name.
+ * @param name resource name.
+ */
+ public static LifeCycleEvent newCreateEvent(String resourceId, String packageName, String name)
+ {
+ return new LifeCycleEvent(resourceId, packageName, name, LifeCycleEventType.CREATED);
+ }
+
+ /**
+ * Factory method for a new "REMOVE" event.
+ * Builds a new "REMOVE" event with the given data.
+ *
+ * @param resourceId resource identifier.
+ * @param packageName resource package name.
+ * @param name resource name.
+ */
+ public static LifeCycleEvent newRemoveEvent(String resourceId, String packageName, String name)
+ {
+ return new LifeCycleEvent(resourceId, packageName, name, LifeCycleEventType.REMOVED);
+ }
+
+ /**
+ * Returns an XML representation of this event.
+ *
+ * @return an XML representation of this event.
+ */
+ public Element toXML()
+ {
+ return toXML(XmlUtils.EMPTY_DOC);
+ }
+
+ /**
+ * Returns an XML representation of this event using the given
+ * input document as owner.
+ *
+ * @return an XML representation of this event.
+ */
+ public Element toXML(Document factory)
+ {
+ Element lifeCycleEvent = XmlUtils.createElement(factory, Names.LIFECYCLE_EVENT_QNAME);
+
+ lifeCycleEvent.setAttribute(
+ "Type",
+ _type.toString());
+
+ lifeCycleEvent.setAttribute(
+ Names.TIMEMILLIS_ATTRIBUTE_NAME,
+ String.valueOf(System.currentTimeMillis()));
+
+ Element resource = XmlUtils.createElement(factory, Names.RESOURCE_QNAME);
+ lifeCycleEvent.appendChild(resource);
+
+ Element id = XmlUtils.createElement(factory, Names.RES_ID_QNAME);
+ id.setTextContent(_resourceId);
+ resource.appendChild(id);
+
+ Element packageName = XmlUtils.createElement(factory, Names.PACKAGE_NAME_QNAME);
+ packageName.setTextContent(_packageName);
+ resource.appendChild(packageName);
+
+ Element name = XmlUtils.createElement(factory, Names.ENTITY_NAME_QNAME);
+ name.setTextContent(_name);
+ resource.appendChild(name);
+
+ return lifeCycleEvent;
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/notifications/LifeCycleEventType.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/notifications/LifeCycleEventType.java
new file mode 100644
index 0000000000..9ce7bfc743
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/notifications/LifeCycleEventType.java
@@ -0,0 +1,34 @@
+/*
+ *
+ * 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.notifications;
+
+/**
+ * Event type enumeration.
+ * Event type are used as part of event WS-Notifications in order to inform
+ * the interested listeners about the lifecycle of a QMan managed entity (object or event instance).
+ *
+ * @author Andrea Gazzarini
+ */
+public enum LifeCycleEventType
+{
+ CREATED,
+ REMOVED;
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/qman/debug/WsdlDebugger.java b/qpid/java/management/client/src/main/java/org/apache/qpid/qman/debug/WsdlDebugger.java
new file mode 100644
index 0000000000..398a69817b
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/qman/debug/WsdlDebugger.java
@@ -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.
+ *
+ */
+package org.apache.qpid.qman.debug;
+
+import javax.management.ObjectName;
+
+import org.apache.muse.util.xml.XmlUtils;
+import org.apache.qpid.transport.util.Logger;
+import org.w3c.dom.Node;
+
+/**
+ * Utility class used for debbugging WSDL documents
+ *
+ * @author Andrea Gazzarini
+ */
+public class WsdlDebugger {
+ public final static Logger LOGGER = Logger.get(WsdlDebugger.class);
+
+ /**
+ * Prints out to log the given node.
+ *
+ * @param node the xml node to be printed out.
+ */
+ public static void debug(ObjectName resourceId, Node node)
+ {
+ if (LOGGER.isDebugEnabled())
+ {
+ LOGGER.debug(resourceId+" : "+XmlUtils.toString(node, false,true));
+ }
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/qman/debug/XmlDebugger.java b/qpid/java/management/client/src/main/java/org/apache/qpid/qman/debug/XmlDebugger.java
new file mode 100644
index 0000000000..600bb51858
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/qman/debug/XmlDebugger.java
@@ -0,0 +1,92 @@
+/*
+ *
+ * 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.qman.debug;
+
+import javax.management.ObjectName;
+
+import org.apache.muse.util.xml.XmlUtils;
+import org.apache.qpid.transport.util.Logger;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+
+/**
+ * Utility class used for debbugging XML messages
+ *
+ * @author Andrea Gazzarini
+ */
+public class XmlDebugger {
+ public final static Logger LOGGER = Logger.get(XmlDebugger.class);
+
+ /**
+ * Prints out to log the given node.
+ *
+ * @param node the xml node to be printed out.
+ */
+ public static void debug(Node node)
+ {
+ if (LOGGER.isDebugEnabled())
+ {
+ LOGGER.debug(XmlUtils.toString(node, false,true));
+ }
+ }
+
+ /**
+ * Prints out to log the given node.
+ *
+ * @param node the xml node to be printed out.
+ */
+ public static void debug(ObjectName resourceId, Node node)
+ {
+ if (LOGGER.isDebugEnabled())
+ {
+ LOGGER.debug(resourceId+" : "+XmlUtils.toString(node, false,true));
+ }
+ }
+
+
+ /**
+ * Prints out to log the given element array.
+ *
+ * @param elements the element array to be printed out.
+ */
+ public static void debug(Element [] elements)
+ {
+ if (LOGGER.isDebugEnabled())
+ {
+ StringBuilder builder = new StringBuilder();
+ for (Element element : elements) {
+ builder.append(XmlUtils.toString(element,false,true));
+ builder.append(System.getProperty("line.separator"));
+ }
+ LOGGER.debug(builder.toString());
+ }
+ }
+
+ /**
+ * Prints out to log the given node.
+ *
+ * @param node the xml node to be printed out.
+ */
+ public static void debug(String node)
+ {
+ LOGGER.debug(node);
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/router-entries/adapter/resource-instance-1.xml b/qpid/java/management/client/src/main/java/router-entries/adapter/resource-instance-1.xml
new file mode 100644
index 0000000000..062791fa3f
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/router-entries/adapter/resource-instance-1.xml
@@ -0,0 +1,23 @@
+<?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.
+
+-->
+
+<wsa:ReferenceParameters xmlns:wsa="http://www.w3.org/2005/08/addressing"/>
diff --git a/qpid/java/management/client/src/main/java/router-entries/consumer/resource-instance-1.xml b/qpid/java/management/client/src/main/java/router-entries/consumer/resource-instance-1.xml
new file mode 100644
index 0000000000..062791fa3f
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/router-entries/consumer/resource-instance-1.xml
@@ -0,0 +1,23 @@
+<?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.
+
+-->
+
+<wsa:ReferenceParameters xmlns:wsa="http://www.w3.org/2005/08/addressing"/>
diff --git a/qpid/java/management/client/src/main/java/wsdl/QManAdapter.rmd b/qpid/java/management/client/src/main/java/wsdl/QManAdapter.rmd
new file mode 100644
index 0000000000..31e921a06b
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/wsdl/QManAdapter.rmd
@@ -0,0 +1,27 @@
+<?xml version="1.0"?>
+<Definitions xmlns="http://docs.oasis-open.org/wsrf/rmd-1">
+ <MetadataDescriptor
+ xmlns:wsrf-sg="http://docs.oasis-open.org/wsrf/sg-2"
+ xmlns:wsrf-rp="http://docs.oasis-open.org/wsrf/rp-2"
+ xmlns:wsrl="http://docs.oasis-open.org/wsrf/rl-2"
+ xmlns:wsnt="http://docs.oasis-open.org/wsn/b-2"
+ xmlns:wst="http://docs.oasis-open.org/wsn/t-1"
+ xmlns:muws1="http://docs.oasis-open.org/wsdm/muws1-2.xsd"
+ xmlns:muws2="http://docs.oasis-open.org/wsdm/muws2-2.xsd"
+ xmlns:qman="http://amqp.apache.org/qpid/management/qman"
+ name="WsDmAdapterMetadata"
+ interface="qman:QManAdapterPortType"
+ wsdlLocation="http://amqp.apache.org/qpid/management/qman QManAdapter.wsdl">
+ <Property name="wsrf-sg:MembershipContentRule" modifiability="read-only" mutability="mutable">
+ <StaticValues>
+ <wsrf-sg:MembershipContentRule MemberInterface="qman:QManWsResourcePortType"/>
+ </StaticValues>
+ </Property>
+ <Property name="wsrf-sg:Entry" modifiability="read-only" mutability="mutable" />
+ <Property name="wsrf-rp:QueryExpressionDialect" modifiability="read-only" mutability="constant" />
+ <Property name="wsnt:FixedTopicSet" modifiability="read-only" mutability="constant" />
+ <Property name="wst:TopicSet" modifiability="read-only" mutability="mutable" />
+ <Property name="wsnt:TopicExpression" modifiability="read-only" mutability="mutable" />
+ <Property name="wsnt:TopicExpressionDialect" modifiability="read-only" mutability="mutable" />
+ </MetadataDescriptor>
+</Definitions>
diff --git a/qpid/java/management/client/src/main/java/wsdl/QManAdapter.wsdl b/qpid/java/management/client/src/main/java/wsdl/QManAdapter.wsdl
new file mode 100644
index 0000000000..4b26862604
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/wsdl/QManAdapter.wsdl
@@ -0,0 +1,694 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<wsdl:definitions
+ targetNamespace="http://amqp.apache.org/qpid/management/qman"
+ xmlns:qman="http://amqp.apache.org/qpid/management/qman"
+ xmlns="http://schemas.xmlsoap.org/wsdl/"
+ xmlns:wsa="http://www.w3.org/2005/08/addressing"
+ xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
+ xmlns:wsdl-soap="http://schemas.xmlsoap.org/wsdl/soap/"
+ xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ xmlns:wsx="http://schemas.xmlsoap.org/ws/2004/09/mex"
+ xmlns:wsrf-r="http://docs.oasis-open.org/wsrf/r-2"
+ xmlns:wsrf-rl="http://docs.oasis-open.org/wsrf/rl-2"
+ xmlns:wsrf-bf="http://docs.oasis-open.org/wsrf/bf-2"
+ xmlns:wsrf-rp="http://docs.oasis-open.org/wsrf/rp-2"
+ xmlns:wsrf-sg="http://docs.oasis-open.org/wsrf/sg-2"
+ xmlns:wsrf-sgw="http://docs.oasis-open.org/wsrf/sgw-2"
+ xmlns:wsnt="http://docs.oasis-open.org/wsn/b-2"
+ xmlns:wsntw="http://docs.oasis-open.org/wsn/bw-2"
+ xmlns:wst="http://docs.oasis-open.org/wsn/t-1"
+ xmlns:wsrmd="http://docs.oasis-open.org/wsrf/rmd-1"
+ xmlns:muws1="http://docs.oasis-open.org/wsdm/muws1-2.xsd"
+ xmlns:muws2="http://docs.oasis-open.org/wsdm/muws2-2.xsd"
+ name="QManAdapter" >
+ <wsdl:types>
+ <xsd:schema elementFormDefault="qualified" targetNamespace="http://docs.oasis-open.org/wsrf/bf-2">
+ <xsd:include schemaLocation="WS-BaseFaults-1_2.xsd" />
+ </xsd:schema>
+ <xsd:schema elementFormDefault="qualified" targetNamespace="http://docs.oasis-open.org/wsrf/rp-2">
+ <xsd:include schemaLocation="WS-ResourceProperties-1_2.xsd" />
+ </xsd:schema>
+ <xsd:schema elementFormDefault="qualified" targetNamespace="http://docs.oasis-open.org/wsrf/r-2">
+ <xsd:include schemaLocation="WS-Resource-1_2.xsd" />
+ </xsd:schema>
+ <xsd:schema elementFormDefault="qualified" targetNamespace="http://www.w3.org/2005/08/addressing">
+ <xsd:include schemaLocation="WS-Addressing-2005_08.xsd"/>
+ </xsd:schema>
+ <xsd:schema elementFormDefault="qualified" targetNamespace="http://schemas.xmlsoap.org/ws/2004/09/mex">
+ <xsd:include schemaLocation="WS-MetadataExchange-2004_09.xsd"/>
+ </xsd:schema>
+ <xsd:schema elementFormDefault="qualified" targetNamespace="http://docs.oasis-open.org/wsrf/sg-2">
+ <xsd:include schemaLocation="WS-ServiceGroup-1_2.xsd" />
+ </xsd:schema>
+ <xsd:schema elementFormDefault="qualified" targetNamespace="http://docs.oasis-open.org/wsdm/muws1-2.xsd">
+ <xsd:include schemaLocation="WSDM-MUWS-Part1-1_1.xsd" />
+ </xsd:schema>
+ <xsd:schema elementFormDefault="qualified" targetNamespace="http://docs.oasis-open.org/wsdm/muws2-2.xsd">
+ <xsd:include schemaLocation="WSDM-MUWS-Part2-1_1.xsd" />
+ </xsd:schema>
+ <xsd:schema elementFormDefault="qualified" targetNamespace="http://docs.oasis-open.org/wsn/b-2">
+ <xsd:include schemaLocation="WS-BaseNotification-1_3.xsd" />
+ </xsd:schema>
+ <xsd:schema elementFormDefault="qualified" targetNamespace="http://docs.oasis-open.org/wsn/t-1">
+ <xsd:include schemaLocation="WS-Topics-1_3.xsd" />
+ </xsd:schema>
+ <xsd:schema targetNamespace="http://amqp.apache.org/qpid/management/qman">
+ <xsd:import namespace="http://docs.oasis-open.org/wsrf/bf-2" schemaLocation="WS-BaseFaults-1_2.xsd"/>
+ <xsd:import namespace="http://docs.oasis-open.org/wsrf/sg-2" schemaLocation="WS-ServiceGroup-1_2.xsd"/>
+ <xsd:import namespace="http://docs.oasis-open.org/wsrf/rp-2" schemaLocation="WS-ResourceProperties-1_2.xsd"/>
+ <xsd:import namespace="http://docs.oasis-open.org/wsn/b-2" schemaLocation="WS-BaseNotification-1_3.xsd"/>
+ <xsd:import namespace="http://docs.oasis-open.org/wsn/t-1" schemaLocation="WS-Topics-1_3.xsd"/>
+ <xsd:element name="WsDmAdapterResourceProperties">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element ref="wsrf-sg:Entry"/>
+ <xsd:element ref="wsrf-sg:MembershipContentRule"/>
+ <xsd:element ref="wsrf-rp:QueryExpressionDialect" minOccurs="0" maxOccurs="unbounded" />
+ <xsd:element ref="wsnt:FixedTopicSet" />
+ <xsd:element ref="wst:TopicSet" minOccurs="0" />
+ <xsd:element ref="wsnt:TopicExpression" minOccurs="0" maxOccurs="unbounded" />
+ <xsd:element ref="wsnt:TopicExpressionDialect" minOccurs="0" maxOccurs="unbounded" />
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:element name="OperationInvocationFault">
+ <xsd:complexType>
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType"/>
+ </xsd:complexContent>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="EntityInstanceNotFoundFault">
+ <xsd:complexType>
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType"/>
+ </xsd:complexContent>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="MalformedEntityNameFault">
+ <xsd:complexType>
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType"/>
+ </xsd:complexContent>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="NoSuchAttributeFault">
+ <xsd:complexType>
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType"/>
+ </xsd:complexContent>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="Connect">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="host" type="xsd:string" minOccurs="1" nillable="false"/>
+ <xsd:element name="port" type="xsd:integer" minOccurs="1" nillable="false"/>
+ <xsd:element name="username" type="xsd:string" minOccurs="1" nillable="false"/>
+ <xsd:element name="password" type="xsd:string" minOccurs="1" nillable="false"/>
+ <xsd:element name="virtualHost" type="xsd:string" minOccurs="1" nillable="false"/>
+ <xsd:element name="initialPoolCapacity" type="xsd:integer" minOccurs="1" nillable="false"/>
+ <xsd:element name="maxPoolCapacity" type="xsd:integer" minOccurs="1" nillable="false"/>
+ <xsd:element name="maxWaitTimeout" type="xsd:long" minOccurs="1" nillable="false"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="ConnectResponse"/>
+ </xsd:schema>
+ </wsdl:types>
+
+ <wsdl:message name="SubscribeRequest">
+ <wsdl:part name="SubscribeRequest" element="wsnt:Subscribe" />
+ </wsdl:message>
+
+ <wsdl:message name="SubscribeResponse">
+ <wsdl:part name="SubscribeResponse"
+ element="wsnt:SubscribeResponse" />
+ </wsdl:message>
+
+ <wsdl:message name="SubscribeCreationFailedFault">
+ <wsdl:part name="SubscribeCreationFailedFault"
+ element="wsnt:SubscribeCreationFailedFault" />
+ </wsdl:message>
+
+ <wsdl:message name="TopicExpressionDialectUnknownFault">
+ <wsdl:part name="TopicExpressionDialectUnknownFault"
+ element="wsnt:TopicExpressionDialectUnknownFault" />
+ </wsdl:message>
+
+ <wsdl:message name="InvalidFilterFault">
+ <wsdl:part name="InvalidFilterFault"
+ element="wsnt:InvalidFilterFault" />
+ </wsdl:message>
+
+ <wsdl:message name="InvalidProducerPropertiesExpressionFault">
+ <wsdl:part name="InvalidProducerPropertiesExpressionFault"
+ element="wsnt:InvalidProducerPropertiesExpressionFault" />
+ </wsdl:message>
+
+ <wsdl:message name="InvalidMessageContentExpressionFault">
+ <wsdl:part name="InvalidMessageContentExpressionFault"
+ element="wsnt:InvalidMessageContentExpressionFault" />
+ </wsdl:message>
+
+ <wsdl:message name="UnrecognizedPolicyRequestFault">
+ <wsdl:part name="UnrecognizedPolicyRequestFault"
+ element="wsnt:UnrecognizedPolicyRequestFault" />
+ </wsdl:message>
+
+ <wsdl:message name="UnsupportedPolicyRequestFault">
+ <wsdl:part name="UnsupportedPolicyRequestFault"
+ element="wsnt:UnsupportedPolicyRequestFault" />
+ </wsdl:message>
+
+ <wsdl:message name="NotifyMessageNotSupportedFault">
+ <wsdl:part name="NotifyMessageNotSupportedFault"
+ element="wsnt:NotifyMessageNotSupportedFault" />
+ </wsdl:message>
+
+ <wsdl:message name="UnacceptableInitialTerminationTimeFault">
+ <wsdl:part name="UnacceptableInitialTerminationTimeFault"
+ element="wsnt:UnacceptableInitialTerminationTimeFault" />
+ </wsdl:message>
+
+ <!-- ========== NotificationProducer::GetCurrentMessage ===========
+ GetCurrentMessage(topicExpression)
+ returns: a NotificationMessage (xsd:any)
+ -->
+ <wsdl:message name="GetCurrentMessageRequest">
+ <wsdl:part name="GetCurrentMessageRequest"
+ element="wsnt:GetCurrentMessage" />
+ </wsdl:message>
+
+ <wsdl:message name="GetCurrentMessageResponse">
+ <wsdl:part name="GetCurrentMessageResponse"
+ element="wsnt:GetCurrentMessageResponse" />
+ </wsdl:message>
+
+ <wsdl:message name="InvalidTopicExpressionFault">
+ <wsdl:part name="InvalidTopicExpressionFault"
+ element="wsnt:InvalidTopicExpressionFault" />
+ </wsdl:message>
+
+ <wsdl:message name="TopicNotSupportedFault">
+ <wsdl:part name="TopicNotSupportedFault"
+ element="wsnt:TopicNotSupportedFault" />
+ </wsdl:message>
+
+ <wsdl:message name="MultipleTopicsSpecifiedFault">
+ <wsdl:part name="MultipleTopicsSpecifiedFault"
+ element="wsnt:MultipleTopicsSpecifiedFault" />
+ </wsdl:message>
+
+ <wsdl:message name="NoCurrentMessageOnTopicFault">
+ <wsdl:part name="NoCurrentMessageOnTopicFault"
+ element="wsnt:NoCurrentMessageOnTopicFault" />
+ </wsdl:message>
+
+
+
+ <wsdl:message name="OperationInvocationFaultMessage">
+ <wsdl:part name="OperationInvocationFault" element="qman:OperationInvocationFault" />
+ </wsdl:message>
+ <wsdl:message name="EntityInstanceNotFoundFaultMessage">
+ <wsdl:part name="EntityInstanceNotFound" element="qman:EntityInstanceNotFoundFault" />
+ </wsdl:message>
+ <wsdl:message name="MalformedEntityNameFaultMessage">
+ <wsdl:part name="MalformedEntityName" element="qman:MalformedEntityNameFault" />
+ </wsdl:message>
+ <wsdl:message name="NoSuchAttributeFaultMessage">
+ <wsdl:part name="NoSuchAttributeFault" element="qman:NoSuchAttributeFault" />
+ </wsdl:message>
+ <wsdl:message name="ConnectRequestMessage">
+ <wsdl:part name="ConnectRequest" element="qman:Connect" />
+ </wsdl:message>
+ <wsdl:message name="ConnectResponseMessage">
+ <wsdl:part name="ConnectResponse" element="qman:ConnectResponse" />
+ </wsdl:message>
+ <wsdl:message name="InvalidResourcePropertyQNameFault">
+ <wsdl:part name="InvalidResourcePropertyQNameFault" element="wsrf-rp:InvalidResourcePropertyQNameFault" />
+ </wsdl:message>
+ <wsdl:message name="ResourceUnknownFault">
+ <wsdl:part name="ResourceUnknownFault" element="wsrf-r:ResourceUnknownFault" />
+ </wsdl:message>
+ <wsdl:message name="ResourceUnavailableFault">
+ <wsdl:part name="ResourceUnavailableFault" element="wsrf-r:ResourceUnavailableFault" />
+ </wsdl:message>
+ <wsdl:message name="GetResourcePropertyDocumentRequest">
+ <wsdl:part name="GetResourcePropertyDocumentRequest" element="wsrf-rp:GetResourcePropertyDocument"/>
+ </wsdl:message>
+ <wsdl:message name="GetResourcePropertyDocumentResponse">
+ <wsdl:part name="GetResourcePropertyDocumentResponse" element="wsrf-rp:GetResourcePropertyDocumentResponse"/>
+ </wsdl:message>
+ <wsdl:message name="GetMultipleResourcePropertiesRequest">
+ <wsdl:part name="GetMultipleResourcePropertiesRequest" element="wsrf-rp:GetMultipleResourceProperties" />
+ </wsdl:message>
+ <wsdl:message name="GetMultipleResourcePropertiesResponse">
+ <wsdl:part name="GetMultipleResourcePropertiesResponse" element="wsrf-rp:GetMultipleResourcePropertiesResponse" />
+ </wsdl:message>
+ <wsdl:message name="GetResourcePropertyRequest">
+ <wsdl:part name="GetResourcePropertyRequest" element="wsrf-rp:GetResourceProperty" />
+ </wsdl:message>
+ <wsdl:message name="GetResourcePropertyResponse">
+ <wsdl:part name="GetResourcePropertyResponse" element="wsrf-rp:GetResourcePropertyResponse" />
+ </wsdl:message>
+ <wsdl:message name="GetMetadataRequestMessage">
+ <wsdl:part name="GetMetadataMsg" element="wsx:GetMetadata" />
+ </wsdl:message>
+ <wsdl:message name="GetMetadataResponseMessage">
+ <wsdl:part name="GetMetadataResponseMsg" element="wsx:Metadata" />
+ </wsdl:message>
+ <wsdl:message name="QueryResourcePropertiesRequest">
+ <wsdl:part name="QueryResourcePropertiesRequest" element="wsrf-rp:QueryResourceProperties" />
+ </wsdl:message>
+ <wsdl:message name="QueryResourcePropertiesResponse">
+ <wsdl:part name="QueryResourcePropertiesResponse" element="wsrf-rp:QueryResourcePropertiesResponse" />
+ </wsdl:message>
+ <wsdl:message name="UnknownQueryExpressionDialectFault">
+ <wsdl:part name="UnknownQueryExpressionDialectFault" element="wsrf-rp:UnknownQueryExpressionDialectFault" />
+ </wsdl:message>
+ <wsdl:message name="InvalidQueryExpressionFault">
+ <wsdl:part name="InvalidQueryExpressionFault" element="wsrf-rp:InvalidQueryExpressionFault" />
+ </wsdl:message>
+ <wsdl:message name="QueryEvaluationErrorFault">
+ <wsdl:part name="QueryEvaluationErrorFault" element="wsrf-rp:QueryEvaluationErrorFault" />
+ </wsdl:message>
+ <wsdl:portType
+ name="QManAdapterPortType"
+ wsrf-rp:ResourceProperties="qman:WsDmAdapterResourceProperties"
+ wsrmd:Descriptor="WsDmAdapterMetadata" wsrmd:DescriptorLocation="QManAdapter.rmd">
+
+ <wsdl:operation name="Subscribe">
+ <wsdl:input
+ wsa:Action="http://docs.oasis-open.org/wsn/bw-2/NotificationProducer/SubscribeRequest"
+ message="qman:SubscribeRequest" />
+ <wsdl:output
+ wsa:Action="http://docs.oasis-open.org/wsn/bw-2/NotificationProducer/SubscribeResponse"
+ message="qman:SubscribeResponse" />
+ <wsdl:fault name="ResourceUnknownFault"
+ message="qman:ResourceUnknownFault" />
+ <wsdl:fault name="InvalidFilterFault"
+ message="qman:InvalidFilterFault" />
+ <wsdl:fault name="TopicExpressionDialectUnknownFault"
+ message="qman:TopicExpressionDialectUnknownFault" />
+ <wsdl:fault name="InvalidTopicExpressionFault"
+ message="qman:InvalidTopicExpressionFault" />
+ <wsdl:fault name="TopicNotSupportedFault"
+ message="qman:TopicNotSupportedFault" />
+ <wsdl:fault name="InvalidProducerPropertiesExpressionFault"
+ message="qman:InvalidProducerPropertiesExpressionFault" />
+ <wsdl:fault name="InvalidMessageContentExpressionFault"
+ message="qman:InvalidMessageContentExpressionFault" />
+ <wsdl:fault name="UnacceptableInitialTerminationTimeFault"
+ message="qman:UnacceptableInitialTerminationTimeFault" />
+ <wsdl:fault name="UnrecognizedPolicyRequestFault"
+ message="qman:UnrecognizedPolicyRequestFault" />
+ <wsdl:fault name="UnsupportedPolicyRequestFault"
+ message="qman:UnsupportedPolicyRequestFault" />
+ <wsdl:fault name="NotifyMessageNotSupportedFault"
+ message="qman:NotifyMessageNotSupportedFault" />
+ <wsdl:fault name="SubscribeCreationFailedFault"
+ message="qman:SubscribeCreationFailedFault" />
+ </wsdl:operation>
+ <wsdl:operation name="GetCurrentMessage">
+ <wsdl:input
+ wsa:Action="http://docs.oasis-open.org/wsn/bw-2/NotificationProducer/GetCurrentMessageRequest"
+ message="qman:GetCurrentMessageRequest" />
+ <wsdl:output
+ wsa:Action="http://docs.oasis-open.org/wsn/bw-2/NotificationProducer/GetCurrentMessageResponse"
+ message="qman:GetCurrentMessageResponse" />
+ <wsdl:fault name="ResourceUnknownFault"
+ message="qman:ResourceUnknownFault" />
+ <wsdl:fault name="TopicExpressionDialectUnknownFault"
+ message="qman:TopicExpressionDialectUnknownFault" />
+ <wsdl:fault name="InvalidTopicExpressionFault"
+ message="qman:InvalidTopicExpressionFault" />
+ <wsdl:fault name="TopicNotSupportedFault"
+ message="qman:TopicNotSupportedFault" />
+ <wsdl:fault name="NoCurrentMessageOnTopicFault"
+ message="qman:NoCurrentMessageOnTopicFault" />
+ <wsdl:fault name="MultipleTopicsSpecifiedFault"
+ message="qman:MultipleTopicsSpecifiedFault" />
+ </wsdl:operation>
+
+ <wsdl:operation name="QueryResourceProperties">
+ <wsdl:input
+ wsa:Action="http://docs.oasis-open.org/wsrf/rpw-2/QueryResourceProperties/QueryResourcePropertiesRequest"
+ name="QueryResourcePropertiesRequest"
+ message="qman:QueryResourcePropertiesRequest" />
+ <wsdl:output
+ wsa:Action="http://docs.oasis-open.org/wsrf/rpw-2/QueryResourceProperties/QueryResourcePropertiesResponse"
+ name="QueryResourcePropertiesResponse"
+ message="qman:QueryResourcePropertiesResponse" />
+ <wsdl:fault name="ResourceUnknownFault" message="qman:ResourceUnknownFault"/>
+ <wsdl:fault name="ResourceUnavailableFault" message="qman:ResourceUnavailableFault"/>
+ <wsdl:fault name="UnknownQueryExpressionDialectFault" message="qman:UnknownQueryExpressionDialectFault"/>
+ <wsdl:fault name="InvalidQueryExpressionFault" message="qman:InvalidQueryExpressionFault"/>
+ <wsdl:fault name="QueryEvaluationErrorFault" message="qman:QueryEvaluationErrorFault" />
+ </wsdl:operation>
+ <wsdl:operation name="Connect">
+ <wsdl:documentation>
+ Connects QMan with a new broker.
+ </wsdl:documentation>
+ <wsdl:input
+ wsa:Action="http://amqp.apache.org/qpid/management/qman/Connect"
+ name="ConnectRequestInput"
+ message="qman:ConnectRequestMessage" />
+ <wsdl:output
+ wsa:Action="http://amqp.apache.org/qpid/management/qman/ConnectResponse"
+ name="ConnectResponseOutput"
+ message="qman:ConnectResponseMessage" />
+ </wsdl:operation>
+ <wsdl:operation name="GetMultipleResourceProperties">
+ <wsdl:documentation>
+ Returns an array containing values for the requested properties.
+ Note that using this method it's possibile to retrieve only the value of the QManService properties.
+ That is : this method is not supposed to be used for retrieve attributes of the QMan managed entities. For that, the GetManagedEntityAttributeValue must be used.</wsdl:documentation>
+ <wsdl:input
+ wsa:Action="http://docs.oasis-open.org/wsrf/rpw-2/GetMultipleResourceProperties/GetMultipleResourcePropertiesRequest"
+ name="GetMultipleResourcePropertiesRequest"
+ message="qman:GetMultipleResourcePropertiesRequest" />
+ <wsdl:output
+ wsa:Action="http://docs.oasis-open.org/wsrf/rpw-2/GetMultipleResourceProperties/GetMultipleResourcePropertiesResponse"
+ name="GetMultipleResourcePropertiesResponse"
+ message="qman:GetMultipleResourcePropertiesResponse" />
+ <wsdl:fault name="ResourceUnknownFault" message="qman:ResourceUnknownFault"/>
+ <wsdl:fault name="ResourceUnavailableFault" message="qman:ResourceUnavailableFault"/>
+ <wsdl:fault name="InvalidResourcePropertyQNameFault" message="qman:InvalidResourcePropertyQNameFault" />
+ </wsdl:operation>
+ <wsdl:operation name="GetResourcePropertyDocument">
+ <wsdl:documentation>
+ Returns resource's entire WS-RP document, with the most up-to-date values of all properties. Note that using this method it's possibile to retrieve only the value of the QManService properties.
+ That is : this method is not supposed to be used for retrieve attributes of the QMan managed entities. For that, the GetManagedEntityAttributeValue must be used.</wsdl:documentation>
+ <wsdl:input
+ wsa:Action="http://docs.oasis-open.org/wsrf/rpw-2/GetResourcePropertyDocument/GetResourcePropertyDocumentRequest"
+ name="GetResourcePropertyDocumentRequest"
+ message="qman:GetResourcePropertyDocumentRequest"/>
+ <wsdl:output
+ wsa:Action="http://docs.oasis-open.org/wsrf/rpw-2/GetResourcePropertyDocument/GetResourcePropertyDocumentResponse"
+ name="GetResourcePropertyDocumentResponse"
+ message="qman:GetResourcePropertyDocumentResponse"/>
+ <wsdl:fault name="ResourceUnknownFault" message="qman:ResourceUnknownFault"/>
+ <wsdl:fault name="ResourceUnavailableFault" message="qman:ResourceUnavailableFault"/>
+ </wsdl:operation>
+ <wsdl:operation name="GetResourceProperty">
+ <wsdl:documentation>
+ Returns the value of the given property. Note that using this method it's possibile to retrieve only the value of the QManService properties.
+ That is : this method is not supposed to be used for retrieve attributes of the QMan managed entities. For that, the GetManagedEntityAttributeValue must be used.
+ </wsdl:documentation>
+ <wsdl:input
+ wsa:Action="http://docs.oasis-open.org/wsrf/rpw-2/GetResourceProperty/GetResourcePropertyRequest"
+ name="GetResourcePropertyRequest"
+ message="qman:GetResourcePropertyRequest" />
+ <wsdl:output
+ wsa:Action="http://docs.oasis-open.org/wsrf/rpw-2/GetResourceProperty/GetResourcePropertyResponse"
+ name="GetResourcePropertyResponse"
+ message="qman:GetResourcePropertyResponse" />
+ <wsdl:fault name="ResourceUnknownFault" message="qman:ResourceUnknownFault"/>
+ <wsdl:fault name="ResourceUnavailableFault" message="qman:ResourceUnavailableFault"/>
+ <wsdl:fault name="InvalidResourcePropertyQNameFault" message="qman:InvalidResourcePropertyQNameFault" />
+ </wsdl:operation>
+ <wsdl:operation name="GetMetadata">
+ <wsdl:documentation>
+ Implementation of the WS-MetadataExchange GetMetadata port type. Note that the only supported metadata type (dialect) is WSDL.
+ </wsdl:documentation>
+ <wsdl:input
+ wsa:Action="http://schemas.xmlsoap.org/ws/2004/09/mex/GetMetadata"
+ name="GetMetadataMsg"
+ message="qman:GetMetadataRequestMessage"/>
+ <wsdl:output
+ wsa:Action="http://schemas.xmlsoap.org/ws/2004/09/mex/GetMetadataResponse"
+ name="GetMetadataResponseMsg"
+ message="qman:GetMetadataResponseMessage"/>
+ </wsdl:operation>
+ </wsdl:portType>
+ <wsdl:binding name="QManAdapterBinding" type="qman:QManAdapterPortType">
+ <wsdl-soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http" />
+ <wsdl:operation name="Subscribe">
+ <wsdl-soap:operation
+ soapAction="http://ws.apache.org/muse/test/wsrf/Subscribe" />
+ <wsdl:input>
+ <wsdl-soap:body use="literal"
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+ </wsdl:input>
+ <wsdl:output>
+ <wsdl-soap:body use="literal"
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+ </wsdl:output>
+ <wsdl:fault name="ResourceUnknownFault">
+ <wsdl-soap:fault
+ namespace="http://ws.apache.org/muse/test/wsrf" use="encoded"
+ name="ResourceUnknownFault" />
+ </wsdl:fault>
+ <wsdl:fault name="InvalidFilterFault">
+ <wsdl-soap:fault
+ namespace="http://ws.apache.org/muse/test/wsrf" use="encoded"
+ name="InvalidFilterFault" />
+ </wsdl:fault>
+ <wsdl:fault name="TopicExpressionDialectUnknownFault">
+ <wsdl-soap:fault
+ namespace="http://ws.apache.org/muse/test/wsrf" use="encoded"
+ name="TopicExpressionDialectUnknownFault" />
+ </wsdl:fault>
+ <wsdl:fault name="InvalidTopicExpressionFault">
+ <wsdl-soap:fault
+ namespace="http://ws.apache.org/muse/test/wsrf" use="encoded"
+ name="InvalidTopicExpressionFault" />
+ </wsdl:fault>
+ <wsdl:fault name="TopicNotSupportedFault">
+ <wsdl-soap:fault
+ namespace="http://ws.apache.org/muse/test/wsrf" use="encoded"
+ name="TopicNotSupportedFault" />
+ </wsdl:fault>
+ <wsdl:fault
+ name="InvalidProducerPropertiesExpressionFault">
+ <wsdl-soap:fault
+ namespace="http://ws.apache.org/muse/test/wsrf" use="encoded"
+ name="InvalidProducerPropertiesExpressionFault" />
+ </wsdl:fault>
+ <wsdl:fault name="InvalidMessageContentExpressionFault">
+ <wsdl-soap:fault
+ namespace="http://ws.apache.org/muse/test/wsrf" use="encoded"
+ name="InvalidMessageContentExpressionFault" />
+ </wsdl:fault>
+ <wsdl:fault
+ name="UnacceptableInitialTerminationTimeFault">
+ <wsdl-soap:fault
+ namespace="http://ws.apache.org/muse/test/wsrf" use="encoded"
+ name="UnacceptableInitialTerminationTimeFault" />
+ </wsdl:fault>
+ <wsdl:fault name="UnrecognizedPolicyRequestFault">
+ <wsdl-soap:fault
+ namespace="http://ws.apache.org/muse/test/wsrf" use="encoded"
+ name="UnrecognizedPolicyRequestFault" />
+ </wsdl:fault>
+ <wsdl:fault name="UnsupportedPolicyRequestFault">
+ <wsdl-soap:fault
+ namespace="http://ws.apache.org/muse/test/wsrf" use="encoded"
+ name="UnsupportedPolicyRequestFault" />
+ </wsdl:fault>
+ <wsdl:fault name="NotifyMessageNotSupportedFault">
+ <wsdl-soap:fault
+ namespace="http://ws.apache.org/muse/test/wsrf" use="encoded"
+ name="NotifyMessageNotSupportedFault" />
+ </wsdl:fault>
+ <wsdl:fault name="SubscribeCreationFailedFault">
+ <wsdl-soap:fault
+ namespace="http://ws.apache.org/muse/test/wsrf" use="encoded"
+ name="SubscribeCreationFailedFault" />
+ </wsdl:fault>
+ </wsdl:operation>
+ <wsdl:operation name="GetCurrentMessage">
+ <wsdl-soap:operation
+ soapAction="http://ws.apache.org/muse/test/wsrf/GetCurrentMessage" />
+ <wsdl:input>
+ <wsdl-soap:body use="literal"
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+ </wsdl:input>
+ <wsdl:output>
+ <wsdl-soap:body use="literal"
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+ </wsdl:output>
+ <wsdl:fault name="ResourceUnknownFault">
+ <wsdl-soap:fault
+ namespace="http://ws.apache.org/muse/test/wsrf" use="encoded"
+ name="ResourceUnknownFault" />
+ </wsdl:fault>
+ <wsdl:fault name="TopicExpressionDialectUnknownFault">
+ <wsdl-soap:fault
+ namespace="http://ws.apache.org/muse/test/wsrf" use="encoded"
+ name="TopicExpressionDialectUnknownFault" />
+ </wsdl:fault>
+ <wsdl:fault name="InvalidTopicExpressionFault">
+ <wsdl-soap:fault
+ namespace="http://ws.apache.org/muse/test/wsrf" use="encoded"
+ name="InvalidTopicExpressionFault" />
+ </wsdl:fault>
+ <wsdl:fault name="TopicNotSupportedFault">
+ <wsdl-soap:fault
+ namespace="http://ws.apache.org/muse/test/wsrf" use="encoded"
+ name="TopicNotSupportedFault" />
+ </wsdl:fault>
+ <wsdl:fault name="NoCurrentMessageOnTopicFault">
+ <wsdl-soap:fault
+ namespace="http://ws.apache.org/muse/test/wsrf" use="encoded"
+ name="NoCurrentMessageOnTopicFault" />
+ </wsdl:fault>
+ <wsdl:fault name="MultipleTopicsSpecifiedFault">
+ <wsdl-soap:fault
+ namespace="http://ws.apache.org/muse/test/wsrf" use="encoded"
+ name="MultipleTopicsSpecifiedFault" />
+ </wsdl:fault>
+ </wsdl:operation>
+
+ <wsdl:operation name="QueryResourceProperties">
+ <wsdl-soap:operation soapAction="QueryResourceProperties"/>
+ <wsdl:input name="QueryResourcePropertiesRequest">
+ <wsdl-soap:body
+ use="encoded"
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+ </wsdl:input>
+ <wsdl:output name="QueryResourcePropertiesResponse">
+ <wsdl-soap:body
+ use="encoded"
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+ </wsdl:output>
+ <wsdl:fault name="ResourceUnknownFault">
+ <wsdl-soap:fault
+ use="encoded"
+ name="ResourceUnknownFault"/>
+ </wsdl:fault>
+ <wsdl:fault name="ResourceUnavailableFault">
+ <wsdl-soap:fault
+ use="encoded"
+ name="ResourceUnavailableFault"/>
+ </wsdl:fault>
+ <wsdl:fault name="UnknownQueryExpressionDialectFault">
+ <wsdl-soap:fault
+ use="encoded"
+ name="UnknownQueryExpressionDialectFault"/>
+ </wsdl:fault>
+ <wsdl:fault name="InvalidQueryExpressionFault">
+ <wsdl-soap:fault
+ use="encoded"
+ name="InvalidQueryExpressionFault"/>
+ </wsdl:fault>
+ <wsdl:fault name="QueryEvaluationErrorFault">
+ <wsdl-soap:fault
+ use="encoded"
+ name="QueryEvaluationErrorFault"/>
+ </wsdl:fault>
+ </wsdl:operation>
+ <wsdl:operation name="Connect">
+ <wsdl-soap:operation soapAction="Connect" />
+ <wsdl:input>
+ <wsdl-soap:body
+ use="literal"
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
+ </wsdl:input>
+ <wsdl:output>
+ <wsdl-soap:body
+ use="literal"
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
+ </wsdl:output>
+ </wsdl:operation>
+ <wsdl:operation name="GetMultipleResourceProperties">
+ <wsdl-soap:operation soapAction="GetMultipleResourceProperties"/>
+ <wsdl:input name="GetMultipleResourcePropertiesRequest">
+ <wsdl-soap:body
+ use="literal"
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+ </wsdl:input>
+ <wsdl:output name="GetMultipleResourcePropertiesResponse">
+ <wsdl-soap:body
+ use="literal"
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+ </wsdl:output>
+ <wsdl:fault name="ResourceUnknownFault">
+ <wsdl-soap:fault
+ use="literal"
+ name="ResourceUnknownFault"/>
+ </wsdl:fault>
+ <wsdl:fault name="ResourceUnavailableFault">
+ <wsdl-soap:fault
+ use="literal"
+ name="ResourceUnavailableFault"/>
+ </wsdl:fault>
+ <wsdl:fault name="InvalidResourcePropertyQNameFault">
+ <wsdl-soap:fault
+ use="literal"
+ name="InvalidResourcePropertyQNameFault"/>
+ </wsdl:fault>
+ </wsdl:operation>
+ <wsdl:operation name="GetResourcePropertyDocument">
+ <wsdl-soap:operation soapAction="GetResourcePropertyDocument"/>
+ <wsdl:input name="GetResourcePropertyDocumentRequest">
+ <wsdl-soap:body
+ use="literal"
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+ </wsdl:input>
+ <wsdl:output name="GetResourcePropertyDocumentResponse">
+ <wsdl-soap:body
+ use="literal"
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+ </wsdl:output>
+ <wsdl:fault name="ResourceUnknownFault">
+ <wsdl-soap:fault
+ use="literal"
+ name="ResourceUnknownFault"/>
+ </wsdl:fault>
+ <wsdl:fault name="ResourceUnavailableFault">
+ <wsdl-soap:fault
+ use="literal"
+ name="ResourceUnavailableFault"/>
+ </wsdl:fault>
+ </wsdl:operation>
+ <wsdl:operation name="GetResourceProperty">
+ <wsdl-soap:operation soapAction="GetResourceProperty"/>
+ <wsdl:input name="GetResourcePropertyRequest">
+ <wsdl-soap:body
+ use="literal"
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+ </wsdl:input>
+ <wsdl:output name="GetResourcePropertyResponse">
+ <wsdl-soap:body
+ use="literal"
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+ </wsdl:output>
+ <wsdl:fault name="ResourceUnknownFault">
+ <wsdl-soap:fault
+ use="literal"
+ name="ResourceUnknownFault"/>
+ </wsdl:fault>
+ <wsdl:fault name="ResourceUnavailableFault">
+ <wsdl-soap:fault
+ use="literal"
+ name="ResourceUnavailableFault"/>
+ </wsdl:fault>
+ <wsdl:fault name="InvalidResourcePropertyQNameFault">
+ <wsdl-soap:fault
+ use="literal"
+ name="InvalidResourcePropertyQNameFault"/>
+ </wsdl:fault>
+ </wsdl:operation>
+ <wsdl:operation name="GetMetadata">
+ <wsdl-soap:operation soapAction="GetMetadata" />
+ <wsdl:input>
+ <wsdl-soap:body
+ use="literal"
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
+ </wsdl:input>
+ <wsdl:output>
+ <wsdl-soap:body
+ use="literal"
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
+ </wsdl:output>
+ </wsdl:operation>
+ </wsdl:binding>
+ <wsdl:service name="QManAdapterService">
+ <wsdl:port name="QManAdapterPort" binding="qman:QManAdapterBinding">
+ <wsdl-soap:address location="http://romagazzarini:8080/qman/services/adapter"/>
+ </wsdl:port>
+ </wsdl:service>
+</wsdl:definitions> \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/wsdl/QManWsResource.rmd b/qpid/java/management/client/src/main/java/wsdl/QManWsResource.rmd
new file mode 100644
index 0000000000..c4944440e0
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/wsdl/QManWsResource.rmd
@@ -0,0 +1,17 @@
+<?xml version="1.0"?>
+<Definitions xmlns="http://docs.oasis-open.org/wsrf/rmd-1" >
+ <MetadataDescriptor
+ xmlns:wsrf-rp="http://docs.oasis-open.org/wsrf/rp-2"
+ xmlns:wsrl="http://docs.oasis-open.org/wsrf/rl-2"
+ xmlns:wsnt="http://docs.oasis-open.org/wsn/b-2"
+ xmlns:wst="http://docs.oasis-open.org/wsn/t-1"
+ xmlns:muws1="http://docs.oasis-open.org/wsdm/muws1-2.xsd"
+ xmlns:muws2="http://docs.oasis-open.org/wsdm/muws2-2.xsd"
+ xmlns:qman="http://amqp.apache.org/qpid/management/qman"
+ name="QManWsResourceMetadata"
+ interface="qman:QManWsResourcePortType"
+ wsdlLocation="http://ws.apache.org/muse/test/wsrf QManWsResource.wsdl" >
+ <Property name="wsrf-rp:QueryExpressionDialect" modifiability="read-only" mutability="constant" />
+ </MetadataDescriptor>
+
+</Definitions> \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/wsdl/QManWsResource.wsdl b/qpid/java/management/client/src/main/java/wsdl/QManWsResource.wsdl
new file mode 100644
index 0000000000..16169c9b78
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/wsdl/QManWsResource.wsdl
@@ -0,0 +1,507 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<wsdl:definitions
+ targetNamespace="http://amqp.apache.org/qpid/management/qman"
+ xmlns:qman="http://amqp.apache.org/qpid/management/qman"
+ xmlns="http://schemas.xmlsoap.org/wsdl/"
+ xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ xmlns:wsx="http://schemas.xmlsoap.org/ws/2004/09/mex"
+ xmlns:wsa="http://www.w3.org/2005/08/addressing"
+ xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
+ xmlns:wsrmd="http://docs.oasis-open.org/wsrf/rmd-1"
+ xmlns:wsrf-r="http://docs.oasis-open.org/wsrf/r-2"
+ xmlns:wsrf-rl="http://docs.oasis-open.org/wsrf/rl-2"
+ xmlns:wsrf-bf="http://docs.oasis-open.org/wsrf/bf-2"
+ xmlns:wsrf-rp="http://docs.oasis-open.org/wsrf/rp-2"
+ xmlns:wsdl-soap="http://schemas.xmlsoap.org/wsdl/soap/"
+ name="QManWsResource">
+ <wsdl:types>
+ <xsd:schema
+ elementFormDefault="qualified"
+ targetNamespace="http://www.w3.org/2005/08/addressing">
+ <xsd:include schemaLocation="WS-Addressing-2005_08.xsd"/>
+ </xsd:schema>
+ <xsd:schema
+ elementFormDefault="qualified"
+ targetNamespace="http://schemas.xmlsoap.org/ws/2004/09/mex">
+ <xsd:include schemaLocation="WS-MetadataExchange-2004_09.xsd"/>
+ </xsd:schema>
+ <xsd:schema
+ elementFormDefault="qualified"
+ targetNamespace="http://docs.oasis-open.org/wsrf/rl-2">
+ <xsd:include schemaLocation="WS-ResourceLifetime-1_2.xsd" />
+ </xsd:schema>
+ <xsd:schema
+ elementFormDefault="qualified"
+ targetNamespace="http://docs.oasis-open.org/wsrf/rp-2">
+ <xsd:include schemaLocation="WS-ResourceProperties-1_2.xsd" />
+ </xsd:schema>
+ <xsd:schema
+ elementFormDefault="qualified"
+ targetNamespace="http://docs.oasis-open.org/wsrf/r-2">
+ <xsd:include schemaLocation="WS-Resource-1_2.xsd" />
+ </xsd:schema>
+ <xsd:schema
+ elementFormDefault="qualified"
+ targetNamespace="http://docs.oasis-open.org/wsrf/rmd-1">
+ <xsd:include schemaLocation="WS-ResourceMetadataDescriptor-CD-01.xsd" />
+ </xsd:schema>
+ <xsd:schema
+ elementFormDefault="qualified"
+ targetNamespace="http://amqp.apache.org/qpid/management/qman">
+ <xsd:import namespace="http://docs.oasis-open.org/wsrf/rl-2" schemaLocation="WS-ResourceLifetime-1_2.xsd"/>
+ <xsd:import namespace="http://docs.oasis-open.org/wsrf/rp-2" schemaLocation="WS-ResourceProperties-1_2.xsd"/>
+ <xsd:import namespace="http://docs.oasis-open.org/wsrf/bf-2" schemaLocation="WS-BaseFaults-1_2.xsd"/>
+ <xsd:element name="QManWsResourceProperties">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element ref="wsrf-rp:QueryExpressionDialect" minOccurs="0" maxOccurs="unbounded" />
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="QManFault">
+ <xsd:complexType>
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType"/>
+ </xsd:complexContent>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="MethodInvocationFault">
+ <xsd:complexType>
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType"/>
+ </xsd:complexContent>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="EntityInstanceNotFoundFault">
+ <xsd:complexType>
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType"/>
+ </xsd:complexContent>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="MalformedEntityNameFault">
+ <xsd:complexType>
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType"/>
+ </xsd:complexContent>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="NoSuchAttributeFault">
+ <xsd:complexType>
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType"/>
+ </xsd:complexContent>
+ </xsd:complexType>
+ </xsd:element>
+
+ <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" />
+ </wsdl:message>
+ <wsdl:message name="GetMetadataResponseMsg">
+ <wsdl:part name="GetMetadataResponseMsg" element="wsx:Metadata" />
+ </wsdl:message>
+ <wsdl:message name="DestroyRequest">
+ <wsdl:part name="DestroyRequest" element="wsrf-rl:Destroy" />
+ </wsdl:message>
+ <wsdl:message name="DestroyResponse">
+ <wsdl:part name="DestroyResponse" element="wsrf-rl:DestroyResponse" />
+ </wsdl:message>
+ <wsdl:message name="ResourceNotDestroyedFault">
+ <wsdl:part name="ResourceNotDestroyedFault" element="wsrf-rl:ResourceNotDestroyedFault" />
+ </wsdl:message>
+ <wsdl:message name="ResourceUnknownFault">
+ <wsdl:part name="ResourceUnknownFault" element="wsrf-r:ResourceUnknownFault" />
+ </wsdl:message>
+ <wsdl:message name="ResourceUnavailableFault">
+ <wsdl:part name="ResourceUnavailableFault" element="wsrf-r:ResourceUnavailableFault" />
+ </wsdl:message>
+ <wsdl:message name="UnableToPutResourcePropertyDocumentFault">
+ <wsdl:part name="UnableToPutResourcePropertyDocumentFault" element="wsrf-rp:UnableToPutResourcePropertyDocumentFault" />
+ </wsdl:message>
+ <wsdl:message name="PutResourcePropertyDocumentRequest">
+ <wsdl:part name="PutResourcePropertyDocumentRequest" element="wsrf-rp:PutResourcePropertyDocument"/>
+ </wsdl:message>
+ <wsdl:message name="PutResourcePropertyDocumentResponse">
+ <wsdl:part name="PutResourcePropertyDocumentResponse" element="wsrf-rp:PutResourcePropertyDocumentResponse"/>
+ </wsdl:message>
+ <wsdl:message name="GetResourcePropertyDocumentRequest">
+ <wsdl:part name="GetResourcePropertyDocumentRequest" element="wsrf-rp:GetResourcePropertyDocument"/>
+ </wsdl:message>
+ <wsdl:message name="GetResourcePropertyDocumentResponse">
+ <wsdl:part name="GetResourcePropertyDocumentResponse" element="wsrf-rp:GetResourcePropertyDocumentResponse"/>
+ </wsdl:message>
+ <wsdl:message name="GetResourcePropertyRequest">
+ <wsdl:part name="GetResourcePropertyRequest" element="wsrf-rp:GetResourceProperty" />
+ </wsdl:message>
+ <wsdl:message name="GetResourcePropertyResponse">
+ <wsdl:part name="GetResourcePropertyResponse" element="wsrf-rp:GetResourcePropertyResponse" />
+ </wsdl:message>
+ <wsdl:message name="InvalidResourcePropertyQNameFault">
+ <wsdl:part name="InvalidResourcePropertyQNameFault" element="wsrf-rp:InvalidResourcePropertyQNameFault" />
+ </wsdl:message>
+ <wsdl:message name="GetMultipleResourcePropertiesRequest">
+ <wsdl:part name="GetMultipleResourcePropertiesRequest" element="wsrf-rp:GetMultipleResourceProperties" />
+ </wsdl:message>
+ <wsdl:message name="GetMultipleResourcePropertiesResponse">
+ <wsdl:part name="GetMultipleResourcePropertiesResponse" element="wsrf-rp:GetMultipleResourcePropertiesResponse" />
+ </wsdl:message>
+ <wsdl:message name="QueryResourcePropertiesRequest">
+ <wsdl:part name="QueryResourcePropertiesRequest" element="wsrf-rp:QueryResourceProperties" />
+ </wsdl:message>
+ <wsdl:message name="QueryResourcePropertiesResponse">
+ <wsdl:part name="QueryResourcePropertiesResponse" element="wsrf-rp:QueryResourcePropertiesResponse" />
+ </wsdl:message>
+ <wsdl:message name="UnknownQueryExpressionDialectFault">
+ <wsdl:part name="UnknownQueryExpressionDialectFault" element="wsrf-rp:UnknownQueryExpressionDialectFault" />
+ </wsdl:message>
+ <wsdl:message name="InvalidQueryExpressionFault">
+ <wsdl:part name="InvalidQueryExpressionFault" element="wsrf-rp:InvalidQueryExpressionFault" />
+ </wsdl:message>
+ <wsdl:message name="QueryEvaluationErrorFault">
+ <wsdl:part name="QueryEvaluationErrorFault" element="wsrf-rp:QueryEvaluationErrorFault" />
+ </wsdl:message>
+ <wsdl:message name="SetResourcePropertiesRequest">
+ <wsdl:part name="SetResourcePropertiesRequest" element="wsrf-rp:SetResourceProperties" />
+ </wsdl:message>
+ <wsdl:message name="SetResourcePropertiesResponse">
+ <wsdl:part name="SetResourcePropertiesResponse" element="wsrf-rp:SetResourcePropertiesResponse" />
+ </wsdl:message>
+ <wsdl:message name="InvalidModificationFault">
+ <wsdl:part name="InvalidModificationFault" element="wsrf-rp:InvalidModificationFault" />
+ </wsdl:message>
+ <wsdl:message name="UnableToModifyResourcePropertyFault">
+ <wsdl:part name="UnableToModifyResourcePropertyFault" element="wsrf-rp:UnableToModifyResourcePropertyFault" />
+ </wsdl:message>
+ <wsdl:message name="SetResourcePropertyRequestFailedFault">
+ <wsdl:part name="SetResourcePropertyRequestFailedFault" element="wsrf-rp:SetResourcePropertyRequestFailedFault" />
+ </wsdl:message>
+ <wsdl:portType
+ name="QManWsResourcePortType"
+ wsrf-rp:ResourceProperties="qman:QManWsResourceProperties"
+ wsrmd:Descriptor="QManWsResourceMetadata"
+ wsrmd:DescriptorLocation="QManWsResource.rmd">
+ <wsdl:operation name="GetMetadata">
+ <wsdl:input
+ wsa:Action="http://schemas.xmlsoap.org/ws/2004/09/mex/GetMetadata"
+ name="GetMetadataMsg"
+ message="qman:GetMetadataMsg"/>
+ <wsdl:output
+ wsa:Action="http://schemas.xmlsoap.org/ws/2004/09/mex/GetMetadataResponse"
+ name="GetMetadataResponseMsg"
+ message="qman:GetMetadataResponseMsg"/>
+ </wsdl:operation>
+ <wsdl:operation name="GetResourcePropertyDocument">
+ <wsdl:input
+ wsa:Action="http://docs.oasis-open.org/wsrf/rpw-2/GetResourcePropertyDocument/GetResourcePropertyDocumentRequest"
+ name="GetResourcePropertyDocumentRequest"
+ message="qman:GetResourcePropertyDocumentRequest"/>
+ <wsdl:output
+ wsa:Action="http://docs.oasis-open.org/wsrf/rpw-2/GetResourcePropertyDocument/GetResourcePropertyDocumentResponse"
+ name="GetResourcePropertyDocumentResponse"
+ message="qman:GetResourcePropertyDocumentResponse"/>
+ <wsdl:fault name="ResourceUnknownFault" message="qman:ResourceUnknownFault"/>
+ <wsdl:fault name="ResourceUnavailableFault" message="qman:ResourceUnavailableFault"/>
+ </wsdl:operation>
+ <wsdl:operation name="PutResourcePropertyDocument">
+ <wsdl:input
+ wsa:Action="http://docs.oasis-open.org/wsrf/rpw-2/PutResourcePropertyDocument/PutResourcePropertyDocumentRequest"
+ name="PutResourcePropertyDocumentRequest"
+ message="qman:PutResourcePropertyDocumentRequest"/>
+ <wsdl:output
+ wsa:Action="http://docs.oasis-open.org/wsrf/rpw-2/PutResourcePropertyDocument/PutResourcePropertyDocumentResponse"
+ name="PutResourcePropertyDocumentResponse"
+ message="qman:PutResourcePropertyDocumentResponse"/>
+ <wsdl:fault name="ResourceUnknownFault" message="qman:ResourceUnknownFault"/>
+ <wsdl:fault name="ResourceUnavailableFault" message="qman:ResourceUnavailableFault"/>
+ <wsdl:fault name="UnableToPutResourcePropertyDocumentFault" message="qman:UnableToPutResourcePropertyDocumentFault"/>
+ </wsdl:operation>
+ <wsdl:operation name="GetResourceProperty">
+ <wsdl:input
+ wsa:Action="http://docs.oasis-open.org/wsrf/rpw-2/GetResourceProperty/GetResourcePropertyRequest"
+ name="GetResourcePropertyRequest"
+ message="qman:GetResourcePropertyRequest" />
+ <wsdl:output
+ wsa:Action="http://docs.oasis-open.org/wsrf/rpw-2/GetResourceProperty/GetResourcePropertyResponse"
+ name="GetResourcePropertyResponse"
+ message="qman:GetResourcePropertyResponse" />
+ <wsdl:fault name="ResourceUnknownFault" message="qman:ResourceUnknownFault"/>
+ <wsdl:fault name="ResourceUnavailableFault" message="qman:ResourceUnavailableFault"/>
+ <wsdl:fault name="InvalidResourcePropertyQNameFault" message="qman:InvalidResourcePropertyQNameFault" />
+ </wsdl:operation>
+ <wsdl:operation name="GetMultipleResourceProperties">
+ <wsdl:input
+ wsa:Action="http://docs.oasis-open.org/wsrf/rpw-2/GetMultipleResourceProperties/GetMultipleResourcePropertiesRequest"
+ name="GetMultipleResourcePropertiesRequest"
+ message="qman:GetMultipleResourcePropertiesRequest" />
+ <wsdl:output
+ wsa:Action="http://docs.oasis-open.org/wsrf/rpw-2/GetMultipleResourceProperties/GetMultipleResourcePropertiesResponse"
+ name="GetMultipleResourcePropertiesResponse"
+ message="qman:GetMultipleResourcePropertiesResponse" />
+ <wsdl:fault name="ResourceUnknownFault" message="qman:ResourceUnknownFault"/>
+ <wsdl:fault name="ResourceUnavailableFault" message="qman:ResourceUnavailableFault"/>
+ <wsdl:fault name="InvalidResourcePropertyQNameFault" message="qman:InvalidResourcePropertyQNameFault" />
+ </wsdl:operation>
+ <wsdl:operation name="QueryResourceProperties">
+ <wsdl:input
+ wsa:Action="http://docs.oasis-open.org/wsrf/rpw-2/QueryResourceProperties/QueryResourcePropertiesRequest"
+ name="QueryResourcePropertiesRequest"
+ message="qman:QueryResourcePropertiesRequest" />
+ <wsdl:output
+ wsa:Action="http://docs.oasis-open.org/wsrf/rpw-2/QueryResourceProperties/QueryResourcePropertiesResponse"
+ name="QueryResourcePropertiesResponse"
+ message="qman:QueryResourcePropertiesResponse" />
+ <wsdl:fault name="ResourceUnknownFault" message="qman:ResourceUnknownFault"/>
+ <wsdl:fault name="ResourceUnavailableFault" message="qman:ResourceUnavailableFault"/>
+ <wsdl:fault name="UnknownQueryExpressionDialectFault" message="qman:UnknownQueryExpressionDialectFault"/>
+ <wsdl:fault name="InvalidQueryExpressionFault" message="qman:InvalidQueryExpressionFault"/>
+ <wsdl:fault name="QueryEvaluationErrorFault" message="qman:QueryEvaluationErrorFault" />
+ </wsdl:operation>
+ <wsdl:operation name="SetResourceProperties">
+ <wsdl:input
+ wsa:Action="http://docs.oasis-open.org/wsrf/rpw-2/SetResourceProperties/SetResourcePropertiesRequest"
+ name="SetResourcePropertiesRequest"
+ message="qman:SetResourcePropertiesRequest" />
+ <wsdl:output
+ wsa:Action="http://docs.oasis-open.org/wsrf/rpw-2/SetResourceProperties/SetResourcePropertiesResponse"
+ name="SetResourcePropertiesResponse"
+ message="qman:SetResourcePropertiesResponse" />
+ <wsdl:fault name="ResourceUnknownFault" message="qman:ResourceUnknownFault"/>
+ <wsdl:fault name="ResourceUnavailableFault" message="qman:ResourceUnavailableFault"/>
+ <wsdl:fault name="InvalidModificationFault" message="qman:InvalidModificationFault" />
+ <wsdl:fault name="UnableToModifyResourcePropertyFault" message="qman:UnableToModifyResourcePropertyFault" />
+ <wsdl:fault name="InvalidResourcePropertyQNameFault" message="qman:InvalidResourcePropertyQNameFault" />
+ <wsdl:fault name="SetResourcePropertyRequestFailedFault" message="qman:SetResourcePropertyRequestFailedFault" />
+ </wsdl:operation>
+ </wsdl:portType>
+ <wsdl:binding name="QManWsResourceBinding" type="qman:QManWsResourcePortType">
+ <wsdl-soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http" />
+ <wsdl:operation name="GetMetadata">
+ <wsdl-soap:operation soapAction="GetMetadata" />
+ <wsdl:input>
+ <wsdl-soap:body
+ use="literal"
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
+ </wsdl:input>
+ <wsdl:output>
+ <wsdl-soap:body
+ use="literal"
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
+ </wsdl:output>
+ </wsdl:operation>
+ <wsdl:operation name="PutResourcePropertyDocument">
+ <wsdl-soap:operation soapAction="PutResourcePropertyDocument"/>
+ <wsdl:input name="PutResourcePropertyDocumentRequest">
+ <wsdl-soap:body
+ use="literal"
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+ </wsdl:input>
+ <wsdl:output name="PutResourcePropertyDocumentResponse">
+ <wsdl-soap:body
+ use="literal"
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+ </wsdl:output>
+ <wsdl:fault name="ResourceUnknownFault">
+ <wsdl-soap:fault
+ use="literal"
+ name="ResourceUnknownFault"/>
+ </wsdl:fault>
+ <wsdl:fault name="ResourceUnavailableFault">
+ <wsdl-soap:fault
+ use="literal"
+ name="ResourceUnavailableFault"/>
+ </wsdl:fault>
+ <wsdl:fault name="UnableToPutResourcePropertyDocumentFault">
+ <wsdl-soap:fault
+ use="literal"
+ name="UnableToPutResourcePropertyDocumentFault"/>
+ </wsdl:fault>
+ </wsdl:operation>
+ <wsdl:operation name="GetResourcePropertyDocument">
+ <wsdl-soap:operation soapAction="GetResourcePropertyDocument"/>
+ <wsdl:input name="GetResourcePropertyDocumentRequest">
+ <wsdl-soap:body
+ use="literal"
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+ </wsdl:input><wsdl:output name="GetResourcePropertyDocumentResponse">
+ <wsdl-soap:body
+ use="literal"
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+ </wsdl:output>
+ <wsdl:fault name="ResourceUnknownFault">
+ <wsdl-soap:fault
+ use="literal"
+ name="ResourceUnknownFault"/>
+ </wsdl:fault>
+ <wsdl:fault name="ResourceUnavailableFault">
+ <wsdl-soap:fault
+ use="literal"
+ name="ResourceUnavailableFault"/>
+ </wsdl:fault>
+ </wsdl:operation>
+ <wsdl:operation name="GetResourceProperty">
+ <wsdl-soap:operation soapAction="GetResourceProperty"/>
+ <wsdl:input name="GetResourcePropertyRequest">
+ <wsdl-soap:body
+ use="literal"
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+ </wsdl:input><wsdl:output name="GetResourcePropertyResponse">
+ <wsdl-soap:body
+ use="literal"
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+ </wsdl:output>
+ <wsdl:fault name="ResourceUnknownFault">
+ <wsdl-soap:fault
+ use="literal"
+ name="ResourceUnknownFault"/>
+ </wsdl:fault>
+ <wsdl:fault name="ResourceUnavailableFault">
+ <wsdl-soap:fault
+ use="literal"
+ name="ResourceUnavailableFault"/>
+ </wsdl:fault>
+ <wsdl:fault name="InvalidResourcePropertyQNameFault">
+ <wsdl-soap:fault
+ use="literal"
+ name="InvalidResourcePropertyQNameFault"/>
+ </wsdl:fault>
+ </wsdl:operation>
+ <wsdl:operation name="GetMultipleResourceProperties">
+ <wsdl-soap:operation soapAction="GetMultipleResourceProperties"/>
+ <wsdl:input name="GetMultipleResourcePropertiesRequest">
+ <wsdl-soap:body
+ use="literal"
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+ </wsdl:input><wsdl:output name="GetMultipleResourcePropertiesResponse">
+ <wsdl-soap:body
+ use="literal"
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+ </wsdl:output>
+ <wsdl:fault name="ResourceUnknownFault">
+ <wsdl-soap:fault
+ use="literal"
+ name="ResourceUnknownFault"/>
+ </wsdl:fault>
+ <wsdl:fault name="ResourceUnavailableFault">
+ <wsdl-soap:fault
+ use="literal"
+ name="ResourceUnavailableFault"/>
+ </wsdl:fault>
+ <wsdl:fault name="InvalidResourcePropertyQNameFault">
+ <wsdl-soap:fault
+ use="literal"
+ name="InvalidResourcePropertyQNameFault"/>
+ </wsdl:fault>
+ </wsdl:operation>
+ <wsdl:operation name="QueryResourceProperties">
+ <wsdl-soap:operation soapAction="QueryResourceProperties"/>
+ <wsdl:input name="QueryResourcePropertiesRequest">
+ <wsdl-soap:body
+ use="literal"
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+ </wsdl:input><wsdl:output name="QueryResourcePropertiesResponse">
+ <wsdl-soap:body
+ use="literal"
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+ </wsdl:output>
+ <wsdl:fault name="ResourceUnknownFault">
+ <wsdl-soap:fault
+ use="literal"
+ name="ResourceUnknownFault"/>
+ </wsdl:fault>
+ <wsdl:fault name="ResourceUnavailableFault">
+ <wsdl-soap:fault
+ use="literal"
+ name="ResourceUnavailableFault"/>
+ </wsdl:fault>
+ <wsdl:fault name="UnknownQueryExpressionDialectFault">
+ <wsdl-soap:fault
+ use="literal"
+ name="UnknownQueryExpressionDialectFault"/>
+ </wsdl:fault>
+ <wsdl:fault name="InvalidQueryExpressionFault">
+ <wsdl-soap:fault
+ use="literal"
+ name="InvalidQueryExpressionFault"/>
+ </wsdl:fault>
+ <wsdl:fault name="QueryEvaluationErrorFault">
+ <wsdl-soap:fault
+ use="literal"
+ name="QueryEvaluationErrorFault"/>
+ </wsdl:fault>
+ </wsdl:operation>
+ <wsdl:operation name="SetResourceProperties">
+ <wsdl-soap:operation soapAction="http://oasis.org/SetResourceProperties"/>
+ <wsdl:input name="SetResourcePropertiesRequest">
+ <wsdl-soap:body
+ use="literal"
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+ </wsdl:input><wsdl:output name="SetResourcePropertiesResponse">
+ <wsdl-soap:body
+ use="literal"
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+ </wsdl:output>
+ <wsdl:fault name="ResourceUnknownFault">
+ <wsdl-soap:fault
+ use="literal"
+ name="ResourceUnknownFault"/>
+ </wsdl:fault>
+ <wsdl:fault name="ResourceUnavailableFault">
+ <wsdl-soap:fault
+ use="literal"
+ name="ResourceUnavailableFault"/>
+ </wsdl:fault>
+ <wsdl:fault name="InvalidModificationFault">
+ <wsdl-soap:fault
+ use="literal"
+ name="InvalidModificationFault"/>
+ </wsdl:fault>
+ <wsdl:fault name="UnableToModifyResourcePropertyFault">
+ <wsdl-soap:fault
+ use="literal"
+ name="UnableToModifyResourcePropertyFault"/>
+ </wsdl:fault>
+ <wsdl:fault name="InvalidResourcePropertyQNameFault">
+ <wsdl-soap:fault
+ use="literal"
+ name="InvalidResourcePropertyQNameFault"/>
+ </wsdl:fault>
+ <wsdl:fault name="SetResourcePropertyRequestFailedFault">
+ <wsdl-soap:fault
+ use="literal"
+ name="SetResourcePropertyRequestFailedFault"/>
+ </wsdl:fault>
+ </wsdl:operation>
+ </wsdl:binding>
+ <wsdl:service name="QManWsResourceService">
+ <wsdl:port name="QManWsResourcePort" binding="qman:QManWsResourceBinding">
+ <wsdl-soap:address location="http://localhost:8080/qman/services/QManWsResource"/>
+ </wsdl:port>
+ </wsdl:service>
+</wsdl:definitions> \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/wsdl/SOAP-Envelope-1_2.xsd b/qpid/java/management/client/src/main/java/wsdl/SOAP-Envelope-1_2.xsd
new file mode 100644
index 0000000000..ab38b1b7f2
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/wsdl/SOAP-Envelope-1_2.xsd
@@ -0,0 +1,181 @@
+<?xml version="1.0"?>
+<!--
+
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+
+-->
+
+
+<!-- Schema defined in the SOAP Version 1.2 Part 1 specification
+ Proposed Recommendation:
+ http://www.w3.org/TR/2003/PR-soap12-part1-20030507/
+ $Id: SOAP-Envelope-1_2.xsd,v 1.1 2006/05/07 19:09:15 danjemiolo Exp $
+
+ Copyright (C)2003 W3C(R) (MIT, ERCIM, Keio), All Rights Reserved.
+ W3C viability, trademark, document use and software licensing rules
+ apply.
+ http://www.w3.org/Consortium/Legal/
+
+ This document is governed by the W3C Software License [1] as
+ described in the FAQ [2].
+
+ [1] http://www.w3.org/Consortium/Legal/copyright-software-19980720
+ [2] http://www.w3.org/Consortium/Legal/IPR-FAQ-20000620.html#DTD
+-->
+
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
+ xmlns:tns="http://www.w3.org/2003/05/soap-envelope"
+ targetNamespace="http://www.w3.org/2003/05/soap-envelope"
+ elementFormDefault="qualified">
+
+ <xs:import namespace="http://www.w3.org/XML/1998/namespace"
+ schemaLocation="XML-Namespace-1998.xsd"/>
+
+ <!-- Envelope, header and body -->
+ <xs:element name="Envelope" type="tns:Envelope"/>
+ <xs:complexType name="Envelope">
+ <xs:sequence>
+ <xs:element ref="tns:Header" minOccurs="0"/>
+ <xs:element ref="tns:Body" minOccurs="1"/>
+ </xs:sequence>
+ <xs:anyAttribute namespace="##other" processContents="lax"/>
+ </xs:complexType>
+
+ <xs:element name="Header" type="tns:Header"/>
+ <xs:complexType name="Header">
+ <xs:annotation>
+ <xs:documentation>
+ Elements replacing the wildcard MUST be namespace qualified, but can be in the targetNamespace
+ </xs:documentation>
+ </xs:annotation>
+ <xs:sequence>
+ <xs:any namespace="##any" processContents="lax" minOccurs="0" maxOccurs="unbounded"/>
+ </xs:sequence>
+ <xs:anyAttribute namespace="##other" processContents="lax"/>
+ </xs:complexType>
+
+ <xs:element name="Body" type="tns:Body"/>
+ <xs:complexType name="Body">
+ <xs:sequence>
+ <xs:any namespace="##any" processContents="lax" minOccurs="0" maxOccurs="unbounded"/>
+ </xs:sequence>
+ <xs:anyAttribute namespace="##other" processContents="lax"/>
+ </xs:complexType>
+
+ <!-- Global Attributes. The following attributes are intended to be
+ usable via qualified attribute names on any complex type referencing
+ them. -->
+ <xs:attribute name="mustUnderstand" type="xs:boolean" default="0"/>
+ <xs:attribute name="relay" type="xs:boolean" default="0"/>
+ <xs:attribute name="role" type="xs:anyURI"/>
+
+ <!-- 'encodingStyle' indicates any canonicalization conventions
+ followed in the contents of the containing element. For example, the
+ value 'http://www.w3.org/2003/05/soap-encoding' indicates the pattern
+ described in the last call working draft of SOAP Version 1.2 Part 2:
+ Adjuncts -->
+
+ <xs:attribute name="encodingStyle" type="xs:anyURI"/>
+
+ <xs:element name="Fault" type="tns:Fault"/>
+ <xs:complexType name="Fault" final="extension">
+ <xs:annotation>
+ <xs:documentation>
+ Fault reporting structure
+ </xs:documentation>
+ </xs:annotation>
+ <xs:sequence>
+ <xs:element name="Code" type="tns:faultcode"/>
+ <xs:element name="Reason" type="tns:faultreason"/>
+ <xs:element name="Node" type="xs:anyURI" minOccurs="0"/>
+ <xs:element name="Role" type="xs:anyURI" minOccurs="0"/>
+ <xs:element name="Detail" type="tns:detail" minOccurs="0"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="faultreason">
+ <xs:sequence>
+ <xs:element name="Text" type="tns:reasontext"
+ minOccurs="1" maxOccurs="unbounded"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="reasontext">
+ <xs:simpleContent>
+ <xs:extension base="xs:string">
+ <xs:attribute ref="xml:lang" use="required"/>
+ </xs:extension>
+ </xs:simpleContent>
+ </xs:complexType>
+
+ <xs:complexType name="faultcode">
+ <xs:sequence>
+ <xs:element name="Value"
+ type="tns:faultcodeEnum"/>
+ <xs:element name="Subcode"
+ type="tns:subcode"
+ minOccurs="0"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:simpleType name="faultcodeEnum">
+ <xs:restriction base="xs:QName">
+ <xs:enumeration value="tns:DataEncodingUnknown"/>
+ <xs:enumeration value="tns:MustUnderstand"/>
+ <xs:enumeration value="tns:Receiver"/>
+ <xs:enumeration value="tns:Sender"/>
+ <xs:enumeration value="tns:VersionMismatch"/>
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:complexType name="subcode">
+ <xs:sequence>
+ <xs:element name="Value"
+ type="xs:QName"/>
+ <xs:element name="Subcode"
+ type="tns:subcode"
+ minOccurs="0"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="detail">
+ <xs:sequence>
+ <xs:any namespace="##any" processContents="lax" minOccurs="0" maxOccurs="unbounded"/>
+ </xs:sequence>
+ <xs:anyAttribute namespace="##other" processContents="lax"/>
+ </xs:complexType>
+
+ <!-- Global element declaration and complex type definition for header entry returned due to a mustUnderstand fault -->
+ <xs:element name="NotUnderstood" type="tns:NotUnderstoodType"/>
+ <xs:complexType name="NotUnderstoodType">
+ <xs:attribute name="qname" type="xs:QName" use="required"/>
+ </xs:complexType>
+
+ <!-- Global element and associated types for managing version transition as described in Appendix A of the SOAP Version 1.2 Part 1 Last Call Working Draft -->
+ <xs:complexType name="SupportedEnvType">
+ <xs:attribute name="qname" type="xs:QName" use="required"/>
+ </xs:complexType>
+
+ <xs:element name="Upgrade" type="tns:UpgradeType"/>
+ <xs:complexType name="UpgradeType">
+ <xs:sequence>
+ <xs:element name="SupportedEnvelope" type="tns:SupportedEnvType" minOccurs="1" maxOccurs="unbounded"/>
+ </xs:sequence>
+ </xs:complexType>
+
+</xs:schema>
diff --git a/qpid/java/management/client/src/main/java/wsdl/WS-Addressing-2005_08.xsd b/qpid/java/management/client/src/main/java/wsdl/WS-Addressing-2005_08.xsd
new file mode 100644
index 0000000000..04b4a688b3
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/wsdl/WS-Addressing-2005_08.xsd
@@ -0,0 +1,169 @@
+<?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.
+
+-->
+
+<xs:schema
+ targetNamespace="http://www.w3.org/2005/08/addressing"
+ xmlns:xs="http://www.w3.org/2001/XMLSchema"
+ xmlns:tns="http://www.w3.org/2005/08/addressing"
+ elementFormDefault="qualified"
+ attributeFormDefault="unqualified">
+
+ <!-- Constructs from the WS-Addressing Core -->
+
+ <xs:element name="EndpointReference"
+ type="tns:EndpointReferenceType" />
+ <xs:complexType name="EndpointReferenceType" mixed="false">
+ <xs:sequence>
+ <xs:element name="Address" type="tns:AttributedURIType" />
+ <xs:element name="ReferenceParameters"
+ type="tns:ReferenceParametersType" minOccurs="0" />
+ <xs:element ref="tns:Metadata" minOccurs="0" />
+ <xs:any namespace="##other" processContents="lax"
+ minOccurs="0" maxOccurs="unbounded" />
+ </xs:sequence>
+ <xs:anyAttribute namespace="##other" processContents="lax" />
+ </xs:complexType>
+
+ <xs:complexType name="ReferenceParametersType" mixed="false">
+ <xs:sequence>
+ <xs:any namespace="##any" processContents="lax"
+ minOccurs="0" maxOccurs="unbounded" />
+ </xs:sequence>
+ <xs:anyAttribute namespace="##other" processContents="lax" />
+ </xs:complexType>
+
+ <xs:element name="Metadata" type="tns:MetadataType" />
+ <xs:complexType name="MetadataType" mixed="false">
+ <xs:sequence>
+ <xs:any namespace="##any" processContents="lax"
+ minOccurs="0" maxOccurs="unbounded" />
+ </xs:sequence>
+ <xs:anyAttribute namespace="##other" processContents="lax" />
+ </xs:complexType>
+
+ <xs:element name="MessageID" type="tns:AttributedURIType" />
+ <xs:element name="RelatesTo" type="tns:RelatesToType" />
+ <xs:complexType name="RelatesToType" mixed="false">
+ <xs:simpleContent>
+ <xs:extension base="xs:anyURI">
+ <xs:attribute name="RelationshipType"
+ type="tns:RelationshipTypeOpenEnum" use="optional"
+ default="http://www.w3.org/2005/08/addressing/reply" />
+ <xs:anyAttribute namespace="##other"
+ processContents="lax" />
+ </xs:extension>
+ </xs:simpleContent>
+ </xs:complexType>
+
+ <xs:simpleType name="RelationshipTypeOpenEnum">
+ <xs:union memberTypes="tns:RelationshipType xs:anyURI" />
+ </xs:simpleType>
+
+ <xs:simpleType name="RelationshipType">
+ <xs:restriction base="xs:anyURI">
+ <xs:enumeration
+ value="http://www.w3.org/2005/08/addressing/reply" />
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:element name="ReplyTo" type="tns:EndpointReferenceType" />
+ <xs:element name="From" type="tns:EndpointReferenceType" />
+ <xs:element name="FaultTo" type="tns:EndpointReferenceType" />
+ <xs:element name="To" type="tns:AttributedURIType" />
+ <xs:element name="Action" type="tns:AttributedURIType" />
+
+ <xs:complexType name="AttributedURIType" mixed="false">
+ <xs:simpleContent>
+ <xs:extension base="xs:anyURI">
+ <xs:anyAttribute namespace="##other"
+ processContents="lax" />
+ </xs:extension>
+ </xs:simpleContent>
+ </xs:complexType>
+
+ <!-- Constructs from the WS-Addressing SOAP binding -->
+
+ <xs:attribute name="IsReferenceParameter" type="xs:boolean" />
+
+ <xs:simpleType name="FaultCodesOpenEnumType">
+ <xs:union memberTypes="tns:FaultCodesType xs:QName" />
+ </xs:simpleType>
+
+ <xs:simpleType name="FaultCodesType">
+ <xs:restriction base="xs:QName">
+ <xs:enumeration value="tns:InvalidAddressingHeader" />
+ <xs:enumeration value="tns:InvalidAddress" />
+ <xs:enumeration value="tns:InvalidEPR" />
+ <xs:enumeration value="tns:InvalidCardinality" />
+ <xs:enumeration value="tns:MissingAddressInEPR" />
+ <xs:enumeration value="tns:DuplicateMessageID" />
+ <xs:enumeration value="tns:ActionMismatch" />
+ <xs:enumeration value="tns:MessageAddressingHeaderRequired" />
+ <xs:enumeration value="tns:DestinationUnreachable" />
+ <xs:enumeration value="tns:ActionNotSupported" />
+ <xs:enumeration value="tns:EndpointUnavailable" />
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:element name="RetryAfter" type="tns:AttributedUnsignedLongType" />
+ <xs:complexType name="AttributedUnsignedLongType" mixed="false">
+ <xs:simpleContent>
+ <xs:extension base="xs:unsignedLong">
+ <xs:anyAttribute namespace="##other"
+ processContents="lax" />
+ </xs:extension>
+ </xs:simpleContent>
+ </xs:complexType>
+
+ <xs:element name="ProblemHeaderQName"
+ type="tns:AttributedQNameType" />
+ <xs:complexType name="AttributedQNameType" mixed="false">
+ <xs:simpleContent>
+ <xs:extension base="xs:QName">
+ <xs:anyAttribute namespace="##other"
+ processContents="lax" />
+ </xs:extension>
+ </xs:simpleContent>
+ </xs:complexType>
+
+ <xs:element name="ProblemHeader" type="tns:AttributedAnyType" />
+ <xs:complexType name="AttributedAnyType" mixed="false">
+ <xs:sequence>
+ <xs:any namespace="##any" processContents="lax"
+ minOccurs="1" maxOccurs="1" />
+ </xs:sequence>
+ <xs:anyAttribute namespace="##other" processContents="lax" />
+ </xs:complexType>
+
+ <xs:element name="ProblemIRI" type="tns:AttributedURIType" />
+
+ <xs:element name="ProblemAction" type="tns:ProblemActionType" />
+ <xs:complexType name="ProblemActionType" mixed="false">
+ <xs:sequence>
+ <xs:element ref="tns:Action" minOccurs="0" />
+ <xs:element name="SoapAction" minOccurs="0"
+ type="xs:anyURI" />
+ </xs:sequence>
+ <xs:anyAttribute namespace="##other" processContents="lax" />
+ </xs:complexType>
+
+</xs:schema>
diff --git a/qpid/java/management/client/src/main/java/wsdl/WS-BaseFaults-1_2.xsd b/qpid/java/management/client/src/main/java/wsdl/WS-BaseFaults-1_2.xsd
new file mode 100644
index 0000000000..665797e486
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/wsdl/WS-BaseFaults-1_2.xsd
@@ -0,0 +1,84 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ OASIS takes no position regarding the validity or scope of any intellectual property or other rights that might be claimed to pertain to the implementation or use of the technology described in this document or the extent to which any license under such rights might or might not be available; neither does it represent that it has made any effort to identify any such rights. Information on OASIS's procedures with respect to rights in OASIS specifications can be found at the OASIS website. Copies of claims of rights made available for publication and any assurances of licenses to be made available, or the result of an attempt made to obtain a general license or permission for the use of such proprietary rights by implementers or users of this specification, can be obtained from the OASIS Executive Director.
+
+OASIS invites any interested party to bring to its attention any copyrights, patents or patent applications, or other proprietary rights which may cover technology that may be required to implement this specification. Please address the information to the OASIS Executive Director.
+
+Copyright (C) OASIS Open (2005). All Rights Reserved.
+
+This document and translations of it may be copied and furnished to others, and derivative works that comment on or otherwise explain it or assist in its implementation may be prepared, copied, published and distributed, in whole or in part, without restriction of any kind, provided that the above copyright notice and this paragraph are included on all such copies and derivative works. However, this document itself may not be modified in any way, such as by removing the copyright notice or references to OASIS, except as needed for the purpose of developing OASIS specifications, in which case the procedures for copyrights defined in the OASIS Intellectual Property Rights document must be followed, or as required to translate it into languages other than English.
+
+The limited permissions granted above are perpetual and will not be revoked by OASIS or its successors or assigns.
+
+This document and the information contained herein is provided on an "AS IS" basis and OASIS DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+-->
+
+<xsd:schema
+ xmlns="http://www.w3.org/2001/XMLSchema"
+ xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:wsa="http://www.w3.org/2005/08/addressing"
+ xmlns:wsrf-bf=
+ "http://docs.oasis-open.org/wsrf/bf-2"
+ elementFormDefault="qualified" attributeFormDefault="unqualified"
+ targetNamespace=
+ "http://docs.oasis-open.org/wsrf/bf-2">
+ <xsd:import
+ namespace="http://www.w3.org/2005/08/addressing"
+ schemaLocation="WS-Addressing-2005_08.xsd"/>
+
+ <xsd:import namespace="http://www.w3.org/XML/1998/namespace"
+ schemaLocation="XML-Namespace-1998.xsd">
+ <xsd:annotation>
+ <xsd:documentation>
+ Get access to the xml: attribute groups for xml:lang as declared on 'schema'
+ and 'documentation' below
+ </xsd:documentation>
+ </xsd:annotation>
+ </xsd:import>
+<!-- ====================== BaseFault Types ======================= -->
+
+ <xsd:element name="BaseFault" type="wsrf-bf:BaseFaultType"/>
+
+ <xsd:complexType name="BaseFaultType">
+ <xsd:sequence>
+ <xsd:any namespace="##other" processContents="lax"
+ minOccurs="0" maxOccurs="unbounded"/>
+ <xsd:element name="Timestamp" type="xsd:dateTime"
+ minOccurs="1" maxOccurs="1"/>
+ <xsd:element name="Originator" type="wsa:EndpointReferenceType"
+ minOccurs="0" maxOccurs="1"/>
+ <xsd:element name="ErrorCode"
+ minOccurs="0" maxOccurs="1">
+ <xsd:complexType>
+ <xsd:complexContent mixed="true">
+ <xsd:extension base="xsd:anyType">
+ <xsd:attribute name="dialect" type="xsd:anyURI"
+ use="required"/>
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:element name="Description"
+ minOccurs="0" maxOccurs="unbounded">
+ <xsd:complexType>
+ <xsd:simpleContent>
+ <xsd:extension base="xsd:string">
+ <xsd:attribute ref="xml:lang" use="optional"/>
+ </xsd:extension>
+ </xsd:simpleContent>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="FaultCause" minOccurs="0" maxOccurs="1">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:any namespace="##other" processContents="lax"
+ minOccurs="1" maxOccurs="1"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:sequence>
+ <xsd:anyAttribute namespace="##other" processContents="lax"/>
+ </xsd:complexType>
+</xsd:schema>
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
new file mode 100644
index 0000000000..d53bf60f3a
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/wsdl/WS-BaseNotification-1_3.wsdl
@@ -0,0 +1,449 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+
+OASIS takes no position regarding the validity or scope of any intellectual property or other rights that might be claimed to pertain to the implementation or use of the technology described in this document or the extent to which any license under such rights might or might not be available; neither does it represent that it has made any effort to identify any such rights. Information on OASIS's procedures with respect to rights in OASIS specifications can be found at the OASIS website. Copies of claims of rights made available for publication and any assurances of licenses to be made available, or the result of an attempt made to obtain a general license or permission for the use of such proprietary rights by implementors or users of this specification, can be obtained from the OASIS Executive Director.
+
+OASIS invites any interested party to bring to its attention any copyrights, patents or patent applications, or other proprietary rights which may cover technology that may be required to implement this specification. Please address the information to the OASIS Executive Director.
+
+Copyright (C) OASIS Open (2004-2005). All Rights Reserved.
+
+This document and translations of it may be copied and furnished to others, and derivative works that comment on or otherwise explain it or assist in its implementation may be prepared, copied, published and distributed, in whole or in part, without restriction of any kind, provided that the above copyright notice and this paragraph are included on all such copies and derivative works. However, this document itself may not be modified in any way, such as by removing the copyright notice or references to OASIS, except as needed for the purpose of developing OASIS specifications, in which case the procedures for copyrights defined in the OASIS Intellectual Property Rights document must be followed, or as required to translate it into languages other than English.
+
+The limited permissions granted above are perpetual and will not be revoked by OASIS or its successors or assigns.
+
+This document and the information contained herein is provided on an "AS IS" basis and OASIS DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+
+-->
+<wsdl:definitions name="WS-BaseNotification"
+ targetNamespace="http://docs.oasis-open.org/wsn/bw-2"
+ xmlns:wsntw="http://docs.oasis-open.org/wsn/bw-2"
+ xmlns:wsnt="http://docs.oasis-open.org/wsn/b-2"
+ xmlns:wsa="http://www.w3.org/2005/08/addressing"
+ xmlns:wsrf-rw="http://docs.oasis-open.org/wsrf/rw-2"
+ xmlns:wsrf-rlw="http://docs.oasis-open.org/wsrf/rlw-2"
+ xmlns:wsrf-rp="http://docs.oasis-open.org/wsrf/rp-2"
+ xmlns:wsrf-rpw="http://docs.oasis-open.org/wsrf/rpw-2"
+ xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">
+
+<!-- ========================== Imports =========================== -->
+ <wsdl:import
+ namespace="http://docs.oasis-open.org/wsrf/rw-2"
+ location="WS-Resource-1_2.wsdl"/>
+
+ <wsdl:import
+ namespace="http://docs.oasis-open.org/wsrf/rlw-2"
+ location="WS-ResourceLifetime-1_2.wsdl"/>
+
+ <wsdl:import
+ namespace="http://docs.oasis-open.org/wsrf/rpw-2"
+ location="WS-ResourceProperties-1_2.wsdl"/>
+
+<!-- ===================== Types Definitions ====================== -->
+ <wsdl:types>
+ <xsd:schema>
+ <xsd:import
+ namespace="http://docs.oasis-open.org/wsn/b-2"
+ schemaLocation="WS-BaseNotification-1_3.xsd"/>
+ <xsd:import
+ namespace="http://docs.oasis-open.org/wsrf/rp-2"
+ schemaLocation="WS-ResourceProperties-1_2.xsd"/>
+ </xsd:schema>
+ </wsdl:types>
+
+<!-- ================ NotificationConsumer::Notify ================
+ Notify(
+ NotificationMessage
+ (SubscriptionReference, TopicExpression, ProducerReference,
+ Message)*
+ returns: n/a (one way)
+-->
+ <wsdl:message name="Notify">
+ <wsdl:part name="Notify" element="wsnt:Notify"/>
+ </wsdl:message>
+
+<!-- ============== NotificationProducer::Subscribe ===============
+ Subscribe(
+ (ConsumerEndpointReference, [Filter], [SubscriptionPolicy],
+ [InitialTerminationTime])
+ returns: WS-Resource qualified EPR to a Subscription
+-->
+ <wsdl:message name="SubscribeRequest" >
+ <wsdl:part name="SubscribeRequest"
+ element="wsnt:Subscribe"/>
+ </wsdl:message>
+
+ <wsdl:message name="SubscribeResponse">
+ <wsdl:part name="SubscribeResponse"
+ element="wsnt:SubscribeResponse"/>
+ </wsdl:message>
+
+ <wsdl:message name="SubscribeCreationFailedFault">
+ <wsdl:part name="SubscribeCreationFailedFault"
+ element="wsnt:SubscribeCreationFailedFault" />
+ </wsdl:message>
+
+ <wsdl:message name="TopicExpressionDialectUnknownFault">
+ <wsdl:part name="TopicExpressionDialectUnknownFault"
+ element="wsnt:TopicExpressionDialectUnknownFault" />
+ </wsdl:message>
+
+ <wsdl:message name="InvalidFilterFault">
+ <wsdl:part name="InvalidFilterFault"
+ element="wsnt:InvalidFilterFault" />
+ </wsdl:message>
+
+ <wsdl:message name="InvalidProducerPropertiesExpressionFault">
+ <wsdl:part name="InvalidProducerPropertiesExpressionFault"
+ element="wsnt:InvalidProducerPropertiesExpressionFault" />
+ </wsdl:message>
+
+ <wsdl:message name="InvalidMessageContentExpressionFault">
+ <wsdl:part name="InvalidMessageContentExpressionFault"
+ element="wsnt:InvalidMessageContentExpressionFault" />
+ </wsdl:message>
+
+ <wsdl:message name="UnrecognizedPolicyRequestFault">
+ <wsdl:part name="UnrecognizedPolicyRequestFault"
+ element="wsnt:UnrecognizedPolicyRequestFault" />
+ </wsdl:message>
+
+ <wsdl:message name="UnsupportedPolicyRequestFault">
+ <wsdl:part name="UnsupportedPolicyRequestFault"
+ element="wsnt:UnsupportedPolicyRequestFault" />
+ </wsdl:message>
+
+ <wsdl:message name="NotifyMessageNotSupportedFault">
+ <wsdl:part name="NotifyMessageNotSupportedFault"
+ element="wsnt:NotifyMessageNotSupportedFault" />
+ </wsdl:message>
+
+ <wsdl:message name="UnacceptableInitialTerminationTimeFault">
+ <wsdl:part name="UnacceptableInitialTerminationTimeFault"
+ element="wsnt:UnacceptableInitialTerminationTimeFault"/>
+ </wsdl:message>
+
+<!-- ========== NotificationProducer::GetCurrentMessage ===========
+ GetCurrentMessage(topicExpression)
+ returns: a NotificationMessage (xsd:any)
+-->
+ <wsdl:message name="GetCurrentMessageRequest">
+ <wsdl:part name="GetCurrentMessageRequest"
+ element="wsnt:GetCurrentMessage"/>
+ </wsdl:message>
+
+ <wsdl:message name="GetCurrentMessageResponse">
+ <wsdl:part name="GetCurrentMessageResponse"
+ element="wsnt:GetCurrentMessageResponse"/>
+ </wsdl:message>
+
+ <wsdl:message name="InvalidTopicExpressionFault">
+ <wsdl:part name="InvalidTopicExpressionFault"
+ element="wsnt:InvalidTopicExpressionFault" />
+ </wsdl:message>
+
+ <wsdl:message name="TopicNotSupportedFault">
+ <wsdl:part name="TopicNotSupportedFault"
+ element="wsnt:TopicNotSupportedFault" />
+ </wsdl:message>
+
+ <wsdl:message name="MultipleTopicsSpecifiedFault">
+ <wsdl:part name="MultipleTopicsSpecifiedFault"
+ element="wsnt:MultipleTopicsSpecifiedFault" />
+ </wsdl:message>
+
+ <wsdl:message name="NoCurrentMessageOnTopicFault">
+ <wsdl:part name="NoCurrentMessageOnTopicFault"
+ element="wsnt:NoCurrentMessageOnTopicFault" />
+ </wsdl:message>
+
+<!-- ========== PullPoint::GetMessages ===========
+ GetMessages(MaximumNumber)
+ returns: NotificationMessage list
+-->
+ <wsdl:message name="GetMessagesRequest">
+ <wsdl:part name="GetMessagesRequest"
+ element="wsnt:GetMessages"/>
+ </wsdl:message>
+
+ <wsdl:message name="GetMessagesResponse">
+ <wsdl:part name="GetMessagesResponse"
+ element="wsnt:GetMessagesResponse"/>
+ </wsdl:message>
+
+<!-- ========== PullPoint::DestroyPullPoint ===========
+ DestroyPullPoint()
+ returns: void
+-->
+ <wsdl:message name="DestroyPullPointRequest">
+ <wsdl:part name="DestroyPullPointRequest"
+ element="wsnt:DestroyPullPoint"/>
+ </wsdl:message>
+
+ <wsdl:message name="DestroyPullPointResponse">
+ <wsdl:part name="DestroyPullPointResponse"
+ element="wsnt:DestroyPullPointResponse"/>
+ </wsdl:message>
+
+ <wsdl:message name="UnableToDestroyPullPointFault">
+ <wsdl:part name="UnableToDestroyPullPointFault"
+ element="wsnt:UnableToDestroyPullPointFault"/>
+ </wsdl:message>
+
+<!-- ========== PullPoint::CreatePullPoint ===========
+ CreatePullPoint()
+ returns: PullPoint (wsa:EndpointReference)
+-->
+ <wsdl:message name="CreatePullPointRequest">
+ <wsdl:part name="CreatePullPointRequest"
+ element="wsnt:CreatePullPoint"/>
+ </wsdl:message>
+
+ <wsdl:message name="CreatePullPointResponse">
+ <wsdl:part name="CreatePullPointResponse"
+ element="wsnt:CreatePullPointResponse"/>
+ </wsdl:message>
+
+ <wsdl:message name="UnableToCreatePullPointFault">
+ <wsdl:part name="UnableToCreatePullPointFault"
+ element="wsnt:UnableToCreatePullPointFault"/>
+ </wsdl:message>
+
+<!-- ================ SubscriptionManager::Renew ==================
+ Renew( Duration | AbsoluteTime)
+ returns: (New Termination Time [CurrentTime])
+-->
+ <wsdl:message name="RenewRequest">
+ <wsdl:part name="RenewRequest"
+ element="wsnt:Renew"/>
+ </wsdl:message>
+
+ <wsdl:message name="RenewResponse">
+ <wsdl:part name="RenewResponse"
+ element="wsnt:RenewResponse"/>
+ </wsdl:message>
+
+ <wsdl:message name="UnacceptableTerminationTimeFault">
+ <wsdl:part name="UnacceptableTerminationTimeFault"
+ element="wsnt:UnacceptableTerminationTimeFault" />
+ </wsdl:message>
+
+<!-- ============== SubscriptionManager::Unsubscribe ===============
+ Unsubscribe()
+ returns: empty
+-->
+ <wsdl:message name="UnsubscribeRequest">
+ <wsdl:part name="UnsubscribeRequest"
+ element="wsnt:Unsubscribe"/>
+ </wsdl:message>
+
+ <wsdl:message name="UnsubscribeResponse">
+ <wsdl:part name="UnsubscribeResponse"
+ element="wsnt:UnsubscribeResponse"/>
+ </wsdl:message>
+
+ <wsdl:message name="UnableToDestroySubscriptionFault">
+ <wsdl:part name="UnableToDestroySubscriptionFault"
+ element="wsnt:UnableToDestroySubscriptionFault" />
+ </wsdl:message>
+
+<!-- ========== SubscriptionManager::PauseSubscription ============
+ PauseSubscription()
+ returns: empty
+-->
+ <wsdl:message name="PauseSubscriptionRequest">
+ <wsdl:part name="PauseSubscriptionRequest"
+ element="wsnt:PauseSubscription"/>
+ </wsdl:message>
+
+ <wsdl:message name="PauseSubscriptionResponse">
+ <wsdl:part name="PauseSubscriptionResponse"
+ element="wsnt:PauseSubscriptionResponse"/>
+ </wsdl:message>
+
+ <wsdl:message name="PauseFailedFault">
+ <wsdl:part name="PauseFailedFault"
+ element="wsnt:PauseFailedFault" />
+ </wsdl:message>
+
+<!-- ========= SubscriptionManager::ResumeSubscription ============
+ ResumeSubscription()
+ returns: empty
+-->
+ <wsdl:message name="ResumeSubscriptionRequest">
+ <wsdl:part name="ResumeSubscriptionRequest"
+ element="wsnt:ResumeSubscription"/>
+ </wsdl:message>
+
+ <wsdl:message name="ResumeSubscriptionResponse">
+ <wsdl:part name="ResumeSubscriptionResponse"
+ element="wsnt:ResumeSubscriptionResponse"/>
+ </wsdl:message>
+
+ <wsdl:message name="ResumeFailedFault">
+ <wsdl:part name="ResumeFailedFault"
+ element="wsnt:ResumeFailedFault" />
+ </wsdl:message>
+
+<!-- =================== PortType Definitions ===================== -->
+<!-- ========= NotificationConsumer PortType Definition =========== -->
+ <wsdl:portType name="NotificationConsumer">
+ <wsdl:operation name="Notify">
+ <wsdl:input wsa:Action="http://docs.oasis-open.org/wsn/bw-2/NotificationConsumer/NotifyRequest" message="wsntw:Notify" />
+ </wsdl:operation>
+ </wsdl:portType>
+
+<!-- ========= NotificationProducer PortType Definition =========== -->
+ <wsdl:portType name="NotificationProducer">
+ <wsdl:operation name="Subscribe">
+ <wsdl:input wsa:Action="http://docs.oasis-open.org/wsn/bw-2/NotificationProducer/SubscribeRequest"
+ message="wsntw:SubscribeRequest" />
+ <wsdl:output wsa:Action="http://docs.oasis-open.org/wsn/bw-2/NotificationProducer/SubscribeResponse"
+ message="wsntw:SubscribeResponse" />
+ <wsdl:fault name="ResourceUnknownFault"
+ message="wsrf-rw:ResourceUnknownFault" />
+ <wsdl:fault name="InvalidFilterFault"
+ message="wsntw:InvalidFilterFault"/>
+ <wsdl:fault name="TopicExpressionDialectUnknownFault"
+ message="wsntw:TopicExpressionDialectUnknownFault"/>
+ <wsdl:fault name="InvalidTopicExpressionFault"
+ message="wsntw:InvalidTopicExpressionFault" />
+ <wsdl:fault name="TopicNotSupportedFault"
+ message="wsntw:TopicNotSupportedFault" />
+ <wsdl:fault name="InvalidProducerPropertiesExpressionFault"
+ message="wsntw:InvalidProducerPropertiesExpressionFault"/>
+ <wsdl:fault name="InvalidMessageContentExpressionFault"
+ message="wsntw:InvalidMessageContentExpressionFault"/>
+ <wsdl:fault name="UnacceptableInitialTerminationTimeFault"
+ message="wsntw:UnacceptableInitialTerminationTimeFault"/>
+ <wsdl:fault name="UnrecognizedPolicyRequestFault"
+ message="wsntw:UnrecognizedPolicyRequestFault"/>
+ <wsdl:fault name="UnsupportedPolicyRequestFault"
+ message="wsntw:UnsupportedPolicyRequestFault"/>
+ <wsdl:fault name="NotifyMessageNotSupportedFault"
+ message="wsntw:NotifyMessageNotSupportedFault"/>
+ <wsdl:fault name="SubscribeCreationFailedFault"
+ message="wsntw:SubscribeCreationFailedFault"/>
+ </wsdl:operation>
+
+ <wsdl:operation name="GetCurrentMessage">
+ <wsdl:input wsa:Action="http://docs.oasis-open.org/wsn/bw-2/NotificationProducer/GetCurrentMessageRequest"
+ message="wsntw:GetCurrentMessageRequest"/>
+ <wsdl:output wsa:Action="http://docs.oasis-open.org/wsn/bw-2/NotificationProducer/GetCurrentMessageResponse"
+ message="wsntw:GetCurrentMessageResponse"/>
+ <wsdl:fault name="ResourceUnknownFault"
+ message="wsrf-rw:ResourceUnknownFault" />
+ <wsdl:fault name="TopicExpressionDialectUnknownFault"
+ message="wsntw:TopicExpressionDialectUnknownFault"/>
+ <wsdl:fault name="InvalidTopicExpressionFault"
+ message="wsntw:InvalidTopicExpressionFault" />
+ <wsdl:fault name="TopicNotSupportedFault"
+ message="wsntw:TopicNotSupportedFault" />
+ <wsdl:fault name="NoCurrentMessageOnTopicFault"
+ message="wsntw:NoCurrentMessageOnTopicFault" />
+ <wsdl:fault name="MultipleTopicsSpecifiedFault"
+ message="wsntw:MultipleTopicsSpecifiedFault" />
+ </wsdl:operation>
+ </wsdl:portType>
+
+<!-- ========== PullPoint PortType Definition ===================== -->
+ <wsdl:portType name="PullPoint">
+ <wsdl:operation name="GetMessages">
+ <wsdl:input name="GetMessagesRequest"
+ message="wsntw:GetMessagesRequest" />
+ <wsdl:output name="GetMessagesResponse"
+ message="wsntw:GetMessagesResponse" />
+ <wsdl:fault name="ResourceUnknownFault"
+ message="wsrf-rw:ResourceUnknownFault" />
+ </wsdl:operation>
+
+ <wsdl:operation name="Notify">
+ <wsdl:input message="wsntw:Notify"/>
+ </wsdl:operation>
+ </wsdl:portType>
+
+<!-- ========== CreatePullPoint PortType Definition =============== -->
+ <wsdl:portType name="CreatePullPoint">
+ <wsdl:operation name="CreatePullPoint">
+ <wsdl:input name="CreatePullPointRequest"
+ message="wsntw:CreatePullPointRequest" />
+ <wsdl:output name="CreatePullPointResponse"
+ message="wsntw:CreatePullPointResponse" />
+ <wsdl:fault name="UnableToCreatePullPointFault"
+ message="wsntw:UnableToCreatePullPointFault" />
+ </wsdl:operation>
+ </wsdl:portType>
+
+<!-- ========== SubscriptionManager PortType Definition =========== -->
+ <wsdl:portType name="SubscriptionManager"
+ wsrf-rp:ResourceProperties="wsnt:SubscriptionManagerRP">
+
+ <wsdl:operation name="Destroy">
+ <wsdl:input wsa:Action="http://docs.oasis-open.org/wsrf/rlw-2/ImmediateResourceTermination/DestroyRequest"
+ name="DestroyRequest" message="wsrf-rlw:DestroyRequest" />
+ <wsdl:output wsa:Action="http://docs.oasis-open.org/wsrf/rlw-2/ImmediateResourceTermination/DestroyResponse"
+ name="DestroyResponse" message="wsrf-rlw:DestroyResponse" />
+ <wsdl:fault name="ResourceNotDestroyedFault" message="wsrf-rlw:ResourceNotDestroyedFault" />
+ <wsdl:fault name="ResourceUnknownFault" message="wsrf-rw:ResourceUnknownFault" />
+ <wsdl:fault name="ResourceUnavailableFault" message="wsrf-rw:ResourceUnavailableFault"/>
+ </wsdl:operation>
+ <wsdl:operation name="SetTerminationTime">
+ <wsdl:input wsa:Action="http://docs.oasis-open.org/wsrf/rlw-2/ScheduledResourceTermination/SetTerminationTimeRequest"
+ name="SetTerminationTimeRequest" message="wsrf-rlw:SetTerminationTimeRequest" />
+ <wsdl:output wsa:Action="http://docs.oasis-open.org/wsrf/rlw-2/ScheduledResourceTermination/SetTerminationTimeResponse"
+ name="SetTerminationTimeResponse" message="wsrf-rlw:SetTerminationTimeResponse" />
+ <wsdl:fault name="UnableToSetTerminationTimeFault" message="wsrf-rlw:UnableToSetTerminationTimeFault" />
+ <wsdl:fault name="ResourceUnknownFault" message="wsrf-rw:ResourceUnknownFault" />
+ <wsdl:fault name="ResourceUnavailableFault" message="wsrf-rw:ResourceUnavailableFault"/>
+ <wsdl:fault name="TerminationTimeChangeRejectedFault" message="wsrf-rlw:TerminationTimeChangeRejectedFault" />
+ </wsdl:operation>
+ <wsdl:operation name="GetResourcePropertyDocument">
+ <wsdl:input wsa:Action="http://docs.oasis-open.org/wsrf/rpw-2/GetResourcePropertyDocument/GetResourcePropertyDocumentRequest"
+ name="GetResourcePropertyDocumentRequest" message="wsrf-rpw:GetResourcePropertyDocumentRequest"/>
+ <wsdl:output wsa:Action="http://docs.oasis-open.org/wsrf/rpw-2/GetResourcePropertyDocument/GetResourcePropertyDocumentResponse"
+ name="GetResourcePropertyDocumentResponse" message="wsrf-rpw:GetResourcePropertyDocumentResponse"/>
+ <wsdl:fault name="ResourceUnknownFault" message="wsrf-rw:ResourceUnknownFault"/>
+ <wsdl:fault name="ResourceUnavailableFault" message="wsrf-rw:ResourceUnavailableFault"/>
+ </wsdl:operation>
+ <wsdl:operation name="GetResourceProperty">
+ <wsdl:input wsa:Action="http://docs.oasis-open.org/wsrf/rpw-2/GetResourceProperty/GetResourcePropertyRequest"
+ name="GetResourcePropertyRequest" message="wsrf-rpw:GetResourcePropertyRequest" />
+ <wsdl:output wsa:Action="http://docs.oasis-open.org/wsrf/rpw-2/GetResourceProperty/GetResourcePropertyResponse"
+ name="GetResourcePropertyResponse" message="wsrf-rpw:GetResourcePropertyResponse" />
+ <wsdl:fault name="ResourceUnknownFault" message="wsrf-rw:ResourceUnknownFault"/>
+ <wsdl:fault name="ResourceUnavailableFault" message="wsrf-rw:ResourceUnavailableFault"/>
+ <wsdl:fault name="InvalidResourcePropertyQNameFault" message="wsrf-rpw:InvalidResourcePropertyQNameFault" />
+ </wsdl:operation>
+ <wsdl:operation name="GetMultipleResourceProperties">
+ <wsdl:input wsa:Action="http://docs.oasis-open.org/wsrf/rpw-2/GetMultipleResourceProperties/GetMultipleResourcePropertiesRequest"
+ name="GetMultipleResourcePropertiesRequest" message="wsrf-rpw:GetMultipleResourcePropertiesRequest" />
+ <wsdl:output wsa:Action="http://docs.oasis-open.org/wsrf/rpw-2/GetMultipleResourceProperties/GetMultipleResourcePropertiesResponse"
+ name="GetMultipleResourcePropertiesResponse" message="wsrf-rpw:GetMultipleResourcePropertiesResponse" />
+ <wsdl:fault name="ResourceUnknownFault" message="wsrf-rw:ResourceUnknownFault"/>
+ <wsdl:fault name="ResourceUnavailableFault" message="wsrf-rw:ResourceUnavailableFault"/>
+ <wsdl:fault name="InvalidResourcePropertyQNameFault" message="wsrf-rpw:InvalidResourcePropertyQNameFault" />
+ </wsdl:operation>
+
+<!-- </wsdl:portType>
+
+ <wsdl:portType name="PausableSubscriptionManager">
+-->
+ <!-- === PausableSubscriptionManager specific operations === -->
+ <wsdl:operation name="PauseSubscription">
+ <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" 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"
+ message="wsntw:ResumeFailedFault" />
+ </wsdl:operation>
+ </wsdl:portType>
+</wsdl:definitions> \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/wsdl/WS-BaseNotification-1_3.xsd b/qpid/java/management/client/src/main/java/wsdl/WS-BaseNotification-1_3.xsd
new file mode 100644
index 0000000000..9e10282759
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/wsdl/WS-BaseNotification-1_3.xsd
@@ -0,0 +1,577 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+OASIS takes no position regarding the validity or scope of any intellectual property or other rights that might be claimed to pertain to the implementation or use of the technology described in this document or the extent to which any license under such rights might or might not be available; neither does it represent that it has made any effort to identify any such rights. Information on OASIS's procedures with respect to rights in OASIS specifications can be found at the OASIS website. Copies of claims of rights made available for publication and any assurances of licenses to be made available, or the result of an attempt made to obtain a general license or permission for the use of such proprietary rights by implementors or users of this specification, can be obtained from the OASIS Executive Director.
+
+OASIS invites any interested party to bring to its attention any copyrights, patents or patent applications, or other proprietary rights which may cover technology that may be required to implement this specification. Please address the information to the OASIS Executive Director.
+
+Copyright (C) OASIS Open (2004-2005). All Rights Reserved.
+
+This document and translations of it may be copied and furnished to others, and derivative works that comment on or otherwise explain it or assist in its implementation may be prepared, copied, published and distributed, in whole or in part, without restriction of any kind, provided that the above copyright notice and this paragraph are included on all such copies and derivative works. However, this document itself may not be modified in any way, such as by removing the copyright notice or references to OASIS, except as needed for the purpose of developing OASIS specifications, in which case the procedures for copyrights defined in the OASIS Intellectual Property Rights document must be followed, or as required to translate it into languages other than English.
+
+The limited permissions granted above are perpetual and will not be revoked by OASIS or its successors or assigns.
+
+This document and the information contained herein is provided on an "AS IS" basis and OASIS DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+
+-->
+
+<xsd:schema
+ targetNamespace="http://docs.oasis-open.org/wsn/b-2"
+ xmlns="http://docs.oasis-open.org/wsn/b-2"
+ xmlns:wsnt="http://docs.oasis-open.org/wsn/b-2"
+ xmlns:wsa="http://www.w3.org/2005/08/addressing"
+ xmlns:wsrf-bf="http://docs.oasis-open.org/wsrf/bf-2"
+ xmlns:wsrf-rl="http://docs.oasis-open.org/wsrf/rl-2"
+ xmlns:wstop="http://docs.oasis-open.org/wsn/t-1"
+xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ elementFormDefault="qualified" attributeFormDefault="unqualified">
+
+<!-- ======================== Imports ============================ -->
+
+ <xsd:import namespace="http://www.w3.org/2005/08/addressing"
+ schemaLocation="WS-Addressing-2005_08.xsd"
+ />
+
+ <xsd:import namespace="http://docs.oasis-open.org/wsrf/bf-2"
+ schemaLocation="WS-BaseFaults-1_2.xsd"
+ />
+
+ <xsd:import namespace="http://docs.oasis-open.org/wsrf/rl-2"
+ schemaLocation="WS-ResourceLifetime-1_2.xsd"
+ />
+ <xsd:import namespace="http://docs.oasis-open.org/wsn/t-1"
+ schemaLocation="WS-Topics-1_3.xsd"
+ />
+
+<!-- ===================== Misc. Helper Types ===================== -->
+
+ <xsd:complexType name="QueryExpressionType" mixed="true">
+ <xsd:sequence>
+ <xsd:any minOccurs="0" maxOccurs="1" processContents="lax" />
+ </xsd:sequence>
+ <xsd:attribute name="Dialect" type="xsd:anyURI" use="required"/>
+ </xsd:complexType>
+
+ <xsd:complexType name="TopicExpressionType" mixed="true">
+ <xsd:sequence>
+ <xsd:any minOccurs="0" maxOccurs="1" processContents="lax" />
+ </xsd:sequence>
+ <xsd:attribute name="Dialect" type="xsd:anyURI" use="required" />
+ <xsd:anyAttribute/>
+ </xsd:complexType>
+
+ <xsd:complexType name="FilterType">
+ <xsd:sequence>
+ <xsd:any minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ </xsd:complexType>
+
+ <xsd:complexType name="SubscriptionPolicyType">
+ <xsd:sequence>
+ <xsd:any minOccurs="0" maxOccurs="unbounded" processContents="lax"/>
+ </xsd:sequence>
+ </xsd:complexType>
+
+<!-- =============== Resource Property Related =================== -->
+<!-- ======== Resource Properties for NotificationProducer ======== -->
+ <xsd:element name="TopicExpression" type="wsnt:TopicExpressionType"/>
+ <xsd:element name="FixedTopicSet" type="xsd:boolean" default="true"/>
+ <xsd:element name="TopicExpressionDialect" type="xsd:anyURI"/>
+
+ <xsd:element name="NotificationProducerRP">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element ref="wsnt:TopicExpression"
+ minOccurs="0" maxOccurs="unbounded" />
+ <xsd:element ref="wsnt:FixedTopicSet"
+ minOccurs="0" maxOccurs="1" />
+ <xsd:element ref="wsnt:TopicExpressionDialect"
+ minOccurs="0" maxOccurs="unbounded" />
+ <xsd:element ref="wstop:TopicSet"
+ minOccurs="0" maxOccurs="1" />
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+
+<!-- ======== Resource Properties for SubscriptionManager ========= -->
+ <xsd:element name="ConsumerReference"
+ type="wsa:EndpointReferenceType" />
+ <xsd:element name="Filter" type="wsnt:FilterType" />
+ <xsd:element name="SubscriptionPolicy" type="wsnt:SubscriptionPolicyType" />
+
+
+ <xsd:element name="CreationTime" type="xsd:dateTime" />
+
+ <xsd:element name="SubscriptionManagerRP" >
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element ref="wsnt:ConsumerReference"
+ minOccurs="1" maxOccurs="1" />
+ <xsd:element ref="wsnt:Filter"
+ minOccurs="0" maxOccurs="1" />
+ <xsd:element ref="wsnt:SubscriptionPolicy"
+ minOccurs="0" maxOccurs="1" />
+ <xsd:element ref="wsnt:CreationTime"
+ minOccurs="0" maxOccurs="1" />
+ <xsd:element ref="wsrf-rl:CurrentTime"/>
+ <xsd:element ref="wsrf-rl:TerminationTime"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+
+<!-- ================= Notification Metadata ===================== -->
+ <xsd:element name="SubscriptionReference"
+ type="wsa:EndpointReferenceType" />
+ <xsd:element name="Topic"
+ type="wsnt:TopicExpressionType" />
+ <xsd:element name="ProducerReference"
+ type="wsa:EndpointReferenceType" />
+
+<!-- ================== Message Helper Types ===================== -->
+ <xsd:complexType name="NotificationMessageHolderType" >
+ <xsd:sequence>
+ <xsd:element ref="wsnt:SubscriptionReference"
+ minOccurs="0" maxOccurs="1" />
+ <xsd:element ref="wsnt:Topic"
+ minOccurs="0" maxOccurs="1" />
+ <xsd:element ref="wsnt:ProducerReference"
+ minOccurs="0" maxOccurs="1" />
+ <xsd:element name="Message">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:any namespace="##any" processContents="lax"
+ minOccurs="1" maxOccurs="1"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:element name="NotificationMessage"
+ type="wsnt:NotificationMessageHolderType"/>
+
+<!-- ========== Message Types for NotificationConsumer =========== -->
+ <xsd:element name="Notify" >
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element ref="wsnt:NotificationMessage"
+ minOccurs="1" maxOccurs="unbounded" />
+ <xsd:any namespace="##other" processContents="lax"
+ minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+
+<!-- ========== Message Types for NotificationProducer =========== -->
+
+ <xsd:simpleType name="AbsoluteOrRelativeTimeType">
+ <xsd:union memberTypes="xsd:dateTime xsd:duration" />
+ </xsd:simpleType>
+
+ <xsd:element name="CurrentTime" type="xsd:dateTime" />
+
+ <xsd:element name="TerminationTime"
+ nillable="true" type="xsd:dateTime" />
+
+ <xsd:element name="ProducerProperties"
+ type="wsnt:QueryExpressionType" />
+
+ <xsd:element name="MessageContent"
+ type="wsnt:QueryExpressionType" />
+
+ <xsd:element name="UseRaw"><xsd:complexType/></xsd:element>
+
+ <xsd:element name="Subscribe" >
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="ConsumerReference"
+ type="wsa:EndpointReferenceType"
+ minOccurs="1" maxOccurs="1" />
+ <xsd:element name="Filter"
+ type="wsnt:FilterType"
+ minOccurs="0" maxOccurs="1" />
+ <xsd:element name="InitialTerminationTime"
+ type="wsnt:AbsoluteOrRelativeTimeType"
+ nillable="true"
+ minOccurs="0" maxOccurs="1" />
+ <xsd:element name="SubscriptionPolicy"
+ minOccurs="0" maxOccurs="1">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:any namespace="##any" processContents="lax"
+ minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:any namespace="##other" processContents="lax"
+ minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:element name="SubscribeResponse">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="SubscriptionReference"
+ type="wsa:EndpointReferenceType"
+ minOccurs="1" maxOccurs="1" />
+ <xsd:element ref="wsnt:CurrentTime"
+ minOccurs="0" maxOccurs="1" />
+ <xsd:element ref="wsnt:TerminationTime"
+ minOccurs="0" maxOccurs="1" />
+ <xsd:any namespace="##other" processContents="lax"
+ minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:element name="GetCurrentMessage">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="Topic"
+ type="wsnt:TopicExpressionType" />
+ <xsd:any namespace="##other" processContents="lax"
+ minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:element name="GetCurrentMessageResponse">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:any namespace="##other" processContents="lax"
+ minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:complexType name="SubscribeCreationFailedFaultType">
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType"/>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:element name="SubscribeCreationFailedFault"
+ type="wsnt:SubscribeCreationFailedFaultType"/>
+
+ <xsd:complexType name="InvalidFilterFaultType">
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType">
+ <xsd:sequence>
+ <xsd:element name="UnknownFilter" type="xsd:QName"
+ minOccurs="1" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:element name="InvalidFilterFault"
+ type="wsnt:InvalidFilterFaultType"/>
+
+ <xsd:complexType name="TopicExpressionDialectUnknownFaultType">
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType"/>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:element name="TopicExpressionDialectUnknownFault"
+ type="wsnt:TopicExpressionDialectUnknownFaultType"/>
+
+ <xsd:complexType name="InvalidTopicExpressionFaultType">
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType"/>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:element name="InvalidTopicExpressionFault"
+ type="wsnt:InvalidTopicExpressionFaultType"/>
+
+ <xsd:complexType name="TopicNotSupportedFaultType">
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType"/>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:element name="TopicNotSupportedFault"
+ type="wsnt:TopicNotSupportedFaultType"/>
+
+ <xsd:complexType name="MultipleTopicsSpecifiedFaultType">
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType"/>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:element name="MultipleTopicsSpecifiedFault"
+ type="wsnt:MultipleTopicsSpecifiedFaultType"/>
+
+ <xsd:complexType name="InvalidProducerPropertiesExpressionFaultType">
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType"/>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:element name="InvalidProducerPropertiesExpressionFault"
+ type="wsnt:InvalidProducerPropertiesExpressionFaultType"/>
+
+ <xsd:complexType name="InvalidMessageContentExpressionFaultType">
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType"/>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:element name="InvalidMessageContentExpressionFault"
+ type="wsnt:InvalidMessageContentExpressionFaultType"/>
+
+ <xsd:complexType name="UnrecognizedPolicyRequestFaultType">
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType">
+ <xsd:sequence>
+ <xsd:element name="UnrecognizedPolicy" type="xsd:QName"
+ minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:element name="UnrecognizedPolicyRequestFault"
+ type="wsnt:UnrecognizedPolicyRequestFaultType"/>
+
+ <xsd:complexType name="UnsupportedPolicyRequestFaultType">
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType">
+ <xsd:sequence>
+ <xsd:element name="UnsupportedPolicy" type="xsd:QName"
+ minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:element name="UnsupportedPolicyRequestFault"
+ type="wsnt:UnsupportedPolicyRequestFaultType"/>
+
+ <xsd:complexType name="NotifyMessageNotSupportedFaultType">
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType"/>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:element name="NotifyMessageNotSupportedFault"
+ type="wsnt:NotifyMessageNotSupportedFaultType"/>
+
+ <xsd:complexType name="UnacceptableInitialTerminationTimeFaultType">
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType">
+ <xsd:sequence>
+ <xsd:element name="MinimumTime" type="xsd:dateTime"/>
+ <xsd:element name="MaximumTime" type="xsd:dateTime"
+ minOccurs="0"/>
+ </xsd:sequence>
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:element name="UnacceptableInitialTerminationTimeFault"
+ type="wsnt:UnacceptableInitialTerminationTimeFaultType"/>
+
+ <xsd:complexType name="NoCurrentMessageOnTopicFaultType">
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType"/>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:element name="NoCurrentMessageOnTopicFault"
+ type="wsnt:NoCurrentMessageOnTopicFaultType"/>
+
+<!-- ======== Message Types for PullPoint ======================== -->
+ <xsd:element name="GetMessages">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="MaximumNumber"
+ type="xsd:nonNegativeInteger"/>
+ <xsd:any namespace="##other" processContents="lax"
+ minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ <xsd:anyAttribute/>
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:element name="GetMessagesResponse">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element ref="wsnt:NotificationMessage"
+ minOccurs="0" maxOccurs="unbounded" />
+ <xsd:any namespace="##other" processContents="lax"
+ minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ <xsd:anyAttribute/>
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:element name="DestroyPullPoint">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:any namespace="##other" processContents="lax"
+ minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ <xsd:anyAttribute/>
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:element name="DestroyPullPointResponse">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:any namespace="##other" processContents="lax"
+ minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ <xsd:anyAttribute/>
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:complexType name="UnableToDestroyPullPointFaultType">
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType"/>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:element name="UnableToDestroyPullPointFault"
+ type="wsnt:UnableToDestroyPullPointFaultType"/>
+
+<!-- ======== Message Types for Create PullPoint ================= -->
+ <xsd:element name="CreatePullPoint">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:any namespace="##other" processContents="lax"
+ minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ <xsd:anyAttribute/>
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:element name="CreatePullPointResponse">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="PullPoint"
+ type="wsa:EndpointReferenceType"/>
+ <xsd:any namespace="##other" processContents="lax"
+ minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ <xsd:anyAttribute/>
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:complexType name="UnableToCreatePullPointFaultType">
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType"/>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:element name="UnableToCreatePullPointFault"
+ type="wsnt:UnableToCreatePullPointFaultType"/>
+
+<!-- ======== Message Types for Base SubscriptionManager ========= -->
+ <xsd:element name="Renew">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="TerminationTime"
+ type="wsnt:AbsoluteOrRelativeTimeType"
+ nillable="true"
+ minOccurs="1" maxOccurs="1" />
+ <xsd:any namespace="##other" processContents="lax"
+ minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:element name="RenewResponse">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element ref="wsnt:TerminationTime"
+ minOccurs="1" maxOccurs="1" />
+ <xsd:element ref="wsnt:CurrentTime"
+ minOccurs="0" maxOccurs="1" />
+ <xsd:any namespace="##other" processContents="lax"
+ minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:complexType name="UnacceptableTerminationTimeFaultType">
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType">
+ <xsd:sequence>
+ <xsd:element name="MinimumTime" type="xsd:dateTime"/>
+ <xsd:element name="MaximumTime" type="xsd:dateTime"
+ minOccurs="0"/>
+ </xsd:sequence>
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:element name="UnacceptableTerminationTimeFault"
+ type="wsnt:UnacceptableTerminationTimeFaultType"/>
+
+ <xsd:element name="Unsubscribe">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:any namespace="##other" processContents="lax"
+ minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:element name="UnsubscribeResponse">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:any namespace="##other" processContents="lax"
+ minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:complexType name="UnableToDestroySubscriptionFaultType">
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType"/>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:element name="UnableToDestroySubscriptionFault"
+ type="wsnt:UnableToDestroySubscriptionFaultType"/>
+
+<!-- ====== Message Types for Pausable SubscriptionManager ======= -->
+
+ <xsd:element name="PauseSubscription">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:any namespace="##other" processContents="lax"
+ minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:element name="PauseSubscriptionResponse" >
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:any namespace="##other" processContents="lax"
+ minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:element name="ResumeSubscription">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:any namespace="##other" processContents="lax"
+ minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:element name="ResumeSubscriptionResponse">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:any namespace="##other" processContents="lax"
+ minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:complexType name="PauseFailedFaultType">
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType"/>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:element name="PauseFailedFault"
+ type="wsnt:PauseFailedFaultType"/>
+
+ <xsd:complexType name="ResumeFailedFaultType">
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType"/>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:element name="ResumeFailedFault"
+ type="wsnt:ResumeFailedFaultType"/>
+
+</xsd:schema> \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/wsdl/WS-MetadataExchange-2004_09.xsd b/qpid/java/management/client/src/main/java/wsdl/WS-MetadataExchange-2004_09.xsd
new file mode 100644
index 0000000000..4cef35b510
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/wsdl/WS-MetadataExchange-2004_09.xsd
@@ -0,0 +1,134 @@
+<?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.
+
+-->
+
+<!--
+(c) 2004 BEA Systems Inc., Computer Associates International, Inc.,
+International Business Machines Corporation, Microsoft Corporation,
+Inc., SAP AG, Sun Microsystems, and webMethods. All rights reserved.
+
+Permission to copy and display the WS-MetadataExchange Specification
+(the "Specification"), in any medium without fee or royalty is hereby
+granted, provided that you include the following on ALL copies of the
+Specification that you make:
+
+1. A link or URL to the Specification at this location.
+2. The copyright notice as shown in the Specification.
+
+BEA Systems, Computer Associates, IBM, Microsoft, SAP, Sun, and
+webMethods (collectively, the "Authors") each agree to grant you a
+license, under royalty-free and otherwise reasonable,
+non-discriminatory terms and conditions, to their respective essential
+patent claims that they deem necessary to implement the
+WS-MetadataExchange Specification.
+
+THE SPECIFICATION IS PROVIDED "AS IS," AND THE AUTHORS MAKE NO
+REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, INCLUDING, BUT NOT
+LIMITED TO, WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE, NON-INFRINGEMENT, OR TITLE; THAT THE CONTENTS OF THE
+SPECIFICATION ARE SUITABLE FOR ANY PURPOSE; NOR THAT THE
+IMPLEMENTATION OF SUCH CONTENTS WILL NOT INFRINGE ANY THIRD PARTY
+PATENTS, COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS.
+
+THE AUTHORS WILL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL,
+INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF OR RELATING TO ANY
+USE OR DISTRIBUTION OF THE SPECIFICATIONS.
+
+The name and trademarks of the Authors may NOT be used in any manner,
+including advertising or publicity pertaining to the Specifications or
+their contents without specific, written prior permission. Title to
+copyright in the Specifications will at all times remain with the
+Authors.
+
+No other rights are granted by implication, estoppel or otherwise.
+-->
+
+<xs:schema
+ targetNamespace="http://schemas.xmlsoap.org/ws/2004/09/mex"
+ xmlns:tns="http://schemas.xmlsoap.org/ws/2004/09/mex"
+ xmlns:wsa="http://www.w3.org/2005/08/addressing"
+ xmlns:xs="http://www.w3.org/2001/XMLSchema"
+ elementFormDefault="qualified" >
+
+ <xs:import
+ namespace="http://www.w3.org/2005/08/addressing"
+ schemaLocation="WS-Addressing-2005_08.xsd" />
+
+ <!-- Get Metadata request -->
+ <xs:element name='GetMetadata' >
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element ref='tns:Dialect' minOccurs='0' />
+ <xs:element ref='tns:Identifier' minOccurs='0' />
+ </xs:sequence>
+ <xs:anyAttribute namespace='##other' processContents='lax' />
+ </xs:complexType>
+ </xs:element>
+
+ <xs:element name='Dialect' type='xs:anyURI' />
+ <xs:element name='Identifier' type='xs:anyURI' />
+
+ <!-- Get Metadata response -->
+ <xs:element name='Metadata' >
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element ref='tns:MetadataSection'
+ minOccurs='0'
+ maxOccurs='unbounded' />
+ </xs:sequence>
+ <xs:anyAttribute namespace='##other' processContents='lax' />
+ </xs:complexType>
+ </xs:element>
+
+ <xs:element name='MetadataSection' >
+ <xs:complexType>
+ <xs:choice>
+ <xs:any namespace='##other'
+ processContents='lax'
+ minOccurs='0'
+ maxOccurs='unbounded' />
+ <xs:element ref='tns:MetadataReference' />
+ <xs:element ref='tns:Location' />
+ </xs:choice>
+ <xs:attribute name='Dialect' type='xs:anyURI' use='required' />
+ <xs:attribute name='Identifier' type='xs:anyURI' />
+ <xs:anyAttribute namespace='##other' processContents='lax' />
+ </xs:complexType>
+ </xs:element>
+
+ <xs:element name='MetadataReference'
+ type='wsa:EndpointReferenceType' />
+
+ <xs:element name='Location'
+ type='xs:anyURI' />
+
+ <!-- count(/s:Envelope/s:Body/*) = 0 for Get request -->
+
+ <!-- Get Response returns xs:any -->
+
+ <xs:complexType name='AnyXmlType' >
+ <xs:sequence>
+ <xs:any namespace='##any' processContents='lax' />
+ </xs:sequence>
+ <xs:anyAttribute namespace='##any' processContents='lax' />
+ </xs:complexType>
+
+</xs:schema>
diff --git a/qpid/java/management/client/src/main/java/wsdl/WS-Resource-1_2.wsdl b/qpid/java/management/client/src/main/java/wsdl/WS-Resource-1_2.wsdl
new file mode 100644
index 0000000000..ed1c309211
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/wsdl/WS-Resource-1_2.wsdl
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+OASIS takes no position regarding the validity or scope of any intellectual property or other rights that might be claimed to pertain to the implementation or use of the technology described in this document or the extent to which any license under such rights might or might not be available; neither does it represent that it has made any effort to identify any such rights. Information on OASIS's procedures with respect to rights in OASIS specifications can be found at the OASIS website. Copies of claims of rights made available for publication and any assurances of licenses to be made available, or the result of an attempt made to obtain a general license or permission for the use of such proprietary rights by implementors or users of this specification, can be obtained from the OASIS Executive Director.
+
+OASIS invites any interested party to bring to its attention any copyrights, patents or patent applications, or other proprietary rights which may cover technology that may be required to implement this specification. Please address the information to the OASIS Executive Director.
+
+Copyright (C) OASIS Open (2005). All Rights Reserved.
+
+This document and translations of it may be copied and furnished to others, and derivative works that comment on or otherwise explain it or assist in its implementation may be prepared, copied, published and distributed, in whole or in part, without restriction of any kind, provided that the above copyright notice and this paragraph are included on all such copies and derivative works. However, this document itself may not be modified in any way, such as by removing the copyright notice or references to OASIS, except as needed for the purpose of developing OASIS specifications, in which case the procedures for copyrights defined in the OASIS Intellectual Property Rights document must be followed, or as required to translate it into languages other than English.
+
+The limited permissions granted above are perpetual and will not be revoked by OASIS or its successors or assigns.
+
+This document and the information contained herein is provided on an "AS IS" basis and OASIS DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+
+-->
+
+<wsdl:definitions name="WS-Resource"
+ xmlns="http://schemas.xmlsoap.org/wsdl/"
+ xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
+ xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ xmlns:wsrf-r="http://docs.oasis-open.org/wsrf/r-2"
+ xmlns:wsrf-rw="http://docs.oasis-open.org/wsrf/rw-2"
+ targetNamespace="http://docs.oasis-open.org/wsrf/rw-2"
+>
+
+<!-- ===================== Types Definitions ====================== -->
+ <wsdl:types>
+ <xsd:schema
+ xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ targetNamespace="http://docs.oasis-open.org/wsrf/rw-2"
+ elementFormDefault="qualified"
+ attributeFormDefault="unqualified">
+
+ <xsd:import
+ namespace="http://docs.oasis-open.org/wsrf/r-2"
+ schemaLocation="WS-Resource-1_2.xsd"
+ />
+
+ </xsd:schema>
+ </wsdl:types>
+
+<!-- ================= WS-Resource faults ========================= -->
+ <wsdl:message name="ResourceUnknownFault">
+ <part name="ResourceUnknownFault"
+ element="wsrf-r:ResourceUnknownFault" />
+ </wsdl:message>
+
+ <wsdl:message name="ResourceUnavailableFault">
+ <part name="ResourceUnavailableFault"
+ element="wsrf-r:ResourceUnavailableFault" />
+ </wsdl:message>
+
+</wsdl:definitions>
+
diff --git a/qpid/java/management/client/src/main/java/wsdl/WS-Resource-1_2.xsd b/qpid/java/management/client/src/main/java/wsdl/WS-Resource-1_2.xsd
new file mode 100644
index 0000000000..5d50284a33
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/wsdl/WS-Resource-1_2.xsd
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+OASIS takes no position regarding the validity or scope of any intellectual property or other rights that might be claimed to pertain to the implementation or use of the technology described in this document or the extent to which any license under such rights might or might not be available; neither does it represent that it has made any effort to identify any such rights. Information on OASIS's procedures with respect to rights in OASIS specifications can be found at the OASIS website. Copies of claims of rights made available for publication and any assurances of licenses to be made available, or the result of an attempt made to obtain a general license or permission for the use of such proprietary rights by implementors or users of this specification, can be obtained from the OASIS Executive Director.
+
+OASIS invites any interested party to bring to its attention any copyrights, patents or patent applications, or other proprietary rights which may cover technology that may be required to implement this specification. Please address the information to the OASIS Executive Director.
+
+Copyright (C) OASIS Open (2005). All Rights Reserved.
+
+This document and translations of it may be copied and furnished to others, and derivative works that comment on or otherwise explain it or assist in its implementation may be prepared, copied, published and distributed, in whole or in part, without restriction of any kind, provided that the above copyright notice and this paragraph are included on all such copies and derivative works. However, this document itself may not be modified in any way, such as by removing the copyright notice or references to OASIS, except as needed for the purpose of developing OASIS specifications, in which case the procedures for copyrights defined in the OASIS Intellectual Property Rights document must be followed, or as required to translate it into languages other than English.
+
+The limited permissions granted above are perpetual and will not be revoked by OASIS or its successors or assigns.
+
+This document and the information contained herein is provided on an "AS IS" basis and OASIS DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+
+-->
+<xsd:schema
+ xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ xmlns:wsrf-r="http://docs.oasis-open.org/wsrf/r-2"
+ xmlns:wsrf-bf="http://docs.oasis-open.org/wsrf/bf-2"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ elementFormDefault="qualified" attributeFormDefault="unqualified"
+ targetNamespace="http://docs.oasis-open.org/wsrf/r-2"
+>
+
+ <xsd:import
+ namespace="http://docs.oasis-open.org/wsrf/bf-2"
+ schemaLocation="WS-BaseFaults-1_2.xsd" />
+
+<!-- ====================== WS-Resource fault types ============= -->
+
+ <xsd:complexType name="ResourceUnknownFaultType">
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType"/>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:element name="ResourceUnknownFault"
+ type="wsrf-r:ResourceUnknownFaultType"/>
+
+ <xsd:complexType name="ResourceUnavailableFaultType">
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType"/>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:element name="ResourceUnavailableFault"
+ type="wsrf-r:ResourceUnavailableFaultType"/>
+</xsd:schema>
+
diff --git a/qpid/java/management/client/src/main/java/wsdl/WS-ResourceLifetime-1_2.wsdl b/qpid/java/management/client/src/main/java/wsdl/WS-ResourceLifetime-1_2.wsdl
new file mode 100644
index 0000000000..adea5800fc
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/wsdl/WS-ResourceLifetime-1_2.wsdl
@@ -0,0 +1,83 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ OASIS takes no position regarding the validity or scope of any intellectual property or other rights that might be claimed to pertain to the implementation or use of the technology described in this document or the extent to which any license under such rights might or might not be available; neither does it represent that it has made any effort to identify any such rights. Information on OASIS's procedures with respect to rights in OASIS specifications can be found at the OASIS website. Copies of claims of rights made available for publication and any assurances of licenses to be made available, or the result of an attempt made to obtain a general license or permission for the use of such proprietary rights by implementors or users of this specification, can be obtained from the OASIS Executive Director.
+
+ OASIS invites any interested party to bring to its attention any copyrights, patents or patent applications, or other proprietary rights which may cover technology that may be required to implement this specification. Please address the information to the OASIS Executive Director.
+
+ Copyright (C) OASIS Open (2005). All Rights Reserved.
+
+ This document and translations of it may be copied and furnished to others, and derivative works that comment on or otherwise explain it or assist in its implementation may be prepared, copied, published and distributed, in whole or in part, without restriction of any kind, provided that the above copyright notice and this paragraph are included on all such copies and derivative works. However, this document itself may not be modified in any way, such as by removing the copyright notice or references to OASIS, except as needed for the purpose of developing OASIS specifications, in which case the procedures for copyrights defined in the OASIS Intellectual Property Rights document must be followed, or as required to translate it into languages other than English.
+
+ The limited permissions granted above are perpetual and will not be revoked by OASIS or its successors or assigns.
+
+ This document and the information contained herein is provided on an "AS IS" basis and OASIS DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+
+-->
+<wsdl:definitions name="WS-ResourceLifetime"
+targetNamespace="http://docs.oasis-open.org/wsrf/rlw-2"
+xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
+xmlns:wsrf-bf="http://docs.oasis-open.org/wsrf/bf-2"
+xmlns:wsrf-rl="http://docs.oasis-open.org/wsrf/rl-2"
+xmlns:wsrf-rlw="http://docs.oasis-open.org/wsrf/rlw-2"
+xmlns:wsrf-rp="http://docs.oasis-open.org/wsrf/rp-2"
+xmlns:wsrf-rw="http://docs.oasis-open.org/wsrf/rw-2"
+xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/">
+
+ <wsdl:import namespace="http://docs.oasis-open.org/wsrf/rw-2"
+ location="WS-Resource-1_2.wsdl"/>
+ <wsdl:types>
+ <xsd:schema attributeFormDefault="unqualified"
+ elementFormDefault="qualified"
+ xmlns="http://www.w3.org/2001/XMLSchema">
+ <xsd:import namespace="http://docs.oasis-open.org/wsrf/rl-2"
+ schemaLocation="WS-ResourceLifetime-1_2.xsd" />
+ </xsd:schema>
+ </wsdl:types>
+
+ <wsdl:message name="SetTerminationTimeRequest">
+ <wsdl:part element="wsrf-rl:SetTerminationTime" name="SetTerminationTimeRequest" />
+ </wsdl:message>
+ <wsdl:message name="SetTerminationTimeResponse">
+ <wsdl:part element="wsrf-rl:SetTerminationTimeResponse" name="SetTerminationTimeResponse" />
+ </wsdl:message>
+
+ <wsdl:message name="DestroyRequest">
+ <wsdl:part element="wsrf-rl:Destroy" name="DestroyRequest" />
+ </wsdl:message>
+ <wsdl:message name="DestroyResponse">
+ <wsdl:part element="wsrf-rl:DestroyResponse" name="DestroyResponse" />
+ </wsdl:message>
+ <wsdl:message name="ResourceNotDestroyedFault">
+ <wsdl:part element="wsrf-rl:ResourceNotDestroyedFault" name="ResourceNotDestroyedFault" />
+ </wsdl:message>
+
+ <wsdl:message name="UnableToSetTerminationTimeFault">
+ <wsdl:part element="wsrf-rl:UnableToSetTerminationTimeFault" name="UnableToSetTerminationTimeFault" />
+ </wsdl:message>
+ <wsdl:message name="TerminationTimeChangeRejectedFault">
+ <wsdl:part element="wsrf-rl:TerminationTimeChangeRejectedFault" name="TerminationTimeChangeRejectedFault" />
+ </wsdl:message>
+ <wsdl:portType name="ImmediateResourceTermination">
+ <wsdl:operation name="Destroy">
+ <wsdl:input name="DestroyRequest" message="wsrf-rlw:DestroyRequest" />
+
+ <wsdl:output name="DestroyResponse" message="wsrf-rlw:DestroyResponse" />
+ <wsdl:fault message="wsrf-rlw:ResourceNotDestroyedFault" name="ResourceNotDestroyedFault" />
+ <wsdl:fault name="ResourceUnknownFault" message="wsrf-rw:ResourceUnknownFault" />
+ <wsdl:fault name="ResourceUnavailableFault" message="wsrf-rw:ResourceUnavailableFault"/>
+ </wsdl:operation>
+ </wsdl:portType>
+ <wsdl:portType name="ScheduledResourceTermination"
+ wsrf-rp:ResourceProperties="wsrf-rl:ScheduledResourceTerminationRP">
+ <wsdl:operation name="SetTerminationTime">
+ <wsdl:input name="SetTerminationTimeRequest" message="wsrf-rlw:SetTerminationTimeRequest" />
+ <wsdl:output name="SetTerminationTimeResponse" message="wsrf-rlw:SetTerminationTimeResponse" />
+
+ <wsdl:fault message="wsrf-rlw:UnableToSetTerminationTimeFault" name="UnableToSetTerminationTimeFault" />
+ <wsdl:fault name="ResourceUnknownFault" message="wsrf-rw:ResourceUnknownFault" />
+ <wsdl:fault name="ResourceUnavailableFault" message="wsrf-rw:ResourceUnavailableFault"/>
+ <wsdl:fault message="wsrf-rlw:TerminationTimeChangeRejectedFault" name="TerminationTimeChangeRejectedFault" />
+ </wsdl:operation>
+ </wsdl:portType>
+</wsdl:definitions> \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/wsdl/WS-ResourceLifetime-1_2.xsd b/qpid/java/management/client/src/main/java/wsdl/WS-ResourceLifetime-1_2.xsd
new file mode 100644
index 0000000000..3338faf191
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/wsdl/WS-ResourceLifetime-1_2.xsd
@@ -0,0 +1,130 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ OASIS takes no position regarding the validity or scope of any intellectual property or other rights that might be claimed to pertain to the implementation or use of the technology described in this document or the extent to which any license under such rights might or might not be available; neither does it represent that it has made any effort to identify any such rights. Information on OASIS's procedures with respect to rights in OASIS specifications can be found at the OASIS website. Copies of claims of rights made available for publication and any assurances of licenses to be made available, or the result of an attempt made to obtain a general license or permission for the use of such proprietary rights by implementors or users of this specification, can be obtained from the OASIS Executive Director.
+
+ OASIS invites any interested party to bring to its attention any copyrights, patents or patent applications, or other proprietary rights which may cover technology that may be required to implement this specification. Please address the information to the OASIS Executive Director.
+
+ Copyright (C) OASIS Open (2005). All Rights Reserved.
+
+ This document and translations of it may be copied and furnished to others, and derivative works that comment on or otherwise explain it or assist in its implementation may be prepared, copied, published and distributed, in whole or in part, without restriction of any kind, provided that the above copyright notice and this paragraph are included on all such copies and derivative works. However, this document itself may not be modified in any way, such as by removing the copyright notice or references to OASIS, except as needed for the purpose of developing OASIS specifications, in which case the procedures for copyrights defined in the OASIS Intellectual Property Rights document must be followed, or as required to translate it into languages other than English.
+
+ The limited permissions granted above are perpetual and will not be revoked by OASIS or its successors or assigns.
+
+ This document and the information contained herein is provided on an "AS IS" basis and OASIS DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+
+-->
+
+
+<xsd:schema
+xmlns="http://www.w3.org/2001/XMLSchema"
+xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+xmlns:wsrf-rl="http://docs.oasis-open.org/wsrf/rl-2"
+xmlns:wsrf-bf="http://docs.oasis-open.org/wsrf/bf-2"
+elementFormDefault="qualified" attributeFormDefault="unqualified"
+targetNamespace="http://docs.oasis-open.org/wsrf/rl-2">
+
+ <xsd:import namespace="http://docs.oasis-open.org/wsrf/bf-2"
+ schemaLocation="WS-BaseFaults-1_2.xsd" />
+ <!--
+ =============== Resource Property Related ===================
+ -->
+ <!--
+ ==== Resource Properties for ScheduledResourceTermination ====
+ -->
+
+ <xsd:element name="CurrentTime" >
+ <xsd:complexType>
+ <xsd:simpleContent>
+ <xsd:extension base="xsd:dateTime" >
+ <xsd:anyAttribute namespace="##other" processContents="lax"/>
+ </xsd:extension>
+ </xsd:simpleContent>
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:element name="TerminationTime" nillable="true">
+ <xsd:complexType>
+ <xsd:simpleContent>
+ <xsd:extension base="xsd:dateTime" >
+ <xsd:anyAttribute namespace="##other" processContents="lax"/>
+ </xsd:extension>
+ </xsd:simpleContent>
+ </xsd:complexType>
+ </xsd:element>
+
+
+ <!-- ==== Resource Properties for ScheduledResourceTermination ==== -->
+ <xsd:element name="ScheduledResourceTerminationRP">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element maxOccurs="1" minOccurs="1" ref="wsrf-rl:CurrentTime" />
+ <xsd:element maxOccurs="1" minOccurs="1" ref="wsrf-rl:TerminationTime" />
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+
+ <!-- ====== Message Types for ImmediateResourceTermination ======= -->
+ <xsd:element name="Destroy">
+ <xsd:complexType />
+ </xsd:element>
+
+ <xsd:element name="DestroyResponse">
+ <xsd:complexType />
+ </xsd:element>
+
+ <xsd:complexType name="ResourceNotDestroyedFaultType">
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType" />
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:element name="ResourceNotDestroyedFault" type="wsrf-rl:ResourceNotDestroyedFaultType" />
+ <!-- ====== Message Types for ScheduledResourceTermination ======= -->
+ <xsd:element name="SetTerminationTime">
+ <xsd:complexType>
+ <xsd:choice>
+ <xsd:element name="RequestedTerminationTime" nillable="true" type="xsd:dateTime" />
+ <xsd:element name="RequestedLifetimeDuration" type="xsd:duration" />
+ </xsd:choice>
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:element name="SetTerminationTimeResponse">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="NewTerminationTime" nillable="true" type="xsd:dateTime" />
+ <xsd:element name="CurrentTime" type="xsd:dateTime" />
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:complexType name="UnableToSetTerminationTimeFaultType">
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType" />
+ </xsd:complexContent>
+ </xsd:complexType>
+
+ <xsd:element name="UnableToSetTerminationTimeFault" type="wsrf-rl:UnableToSetTerminationTimeFaultType" />
+ <xsd:complexType name="TerminationTimeChangeRejectedFaultType">
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType" />
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:element name="TerminationTimeChangeRejectedFault" type="wsrf-rl:TerminationTimeChangeRejectedFaultType" />
+
+
+ <!--
+ ============= Notification Message Related ==================
+ -->
+ <xsd:element name="TerminationNotification">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="TerminationTime" type="xsd:dateTime" minOccurs="1" maxOccurs="1" nillable="true" />
+ <xsd:element name="TerminationReason" type="xsd:anyType" minOccurs="0" maxOccurs="1" />
+ </xsd:sequence>
+
+ </xsd:complexType>
+ </xsd:element>
+
+
+</xsd:schema> \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/wsdl/WS-ResourceMetadataDescriptor-CD-01.xsd b/qpid/java/management/client/src/main/java/wsdl/WS-ResourceMetadataDescriptor-CD-01.xsd
new file mode 100644
index 0000000000..2c5952264b
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/wsdl/WS-ResourceMetadataDescriptor-CD-01.xsd
@@ -0,0 +1,325 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+
+OASIS takes no position regarding the validity or scope of any intellectual property or other rights that might be claimed to pertain to the implementation or use of the technology described in this document or the extent to which any license under such rights might or might not be available; neither does it represent that it has made any effort to identify any such rights. Information on OASIS's procedures with respect to rights in OASIS specifications can be found at the OASIS website. Copies of claims of rights made available for publication and any assurances of licenses to be made available, or the result of an attempt made to obtain a general license or permission for the use of such proprietary rights by implementors or users of this specification, can be obtained from the OASIS Executive Director.
+
+OASIS invites any interested party to bring to its attention any copyrights, patents or patent applications, or other proprietary rights which may cover technology that may be required to implement this specification. Please address the information to the OASIS Executive Director.
+
+Copyright (C) OASIS Open (2005-2006). All Rights Reserved.
+
+This document and translations of it may be copied and furnished to others, and derivative works that comment on or otherwise explain it or assist in its implementation may be prepared, copied, published and distributed, in whole or in part, without restriction of any kind, provided that the above copyright notice and this paragraph are included on all such copies and derivative works. However, this document itself may not be modified in any way, such as by removing the copyright notice or references to OASIS, except as needed for the purpose of developing OASIS specifications, in which case the procedures for copyrights defined in the OASIS Intellectual Property Rights document must be followed, or as required to translate it into languages other than English.
+
+The limited permissions granted above are perpetual and will not be revoked by OASIS or its successors or assigns.
+
+This document and the information contained herein is provided on an "AS IS" basis and OASIS DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+
+
+-->
+
+<xsd:schema
+ xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ xmlns="http://www.w3.org/2001/XMLSchema"
+ xmlns:wsa="http://www.w3.org/2005/08/addressing"
+ xmlns:wsrf-rp="http://docs.oasis-open.org/wsrf/rp-2"
+ targetNamespace="http://docs.oasis-open.org/wsrf/rmd-1"
+ xmlns:wsrmd="http://docs.oasis-open.org/wsrf/rmd-1"
+ elementFormDefault="qualified">
+
+ <xsd:import
+ namespace="http://docs.oasis-open.org/wsrf/rp-2"
+ schemaLocation="WS-ResourceProperties-1_2.xsd" />
+
+ <xsd:import
+ namespace="http://www.w3.org/2005/08/addressing"
+ schemaLocation="WS-Addressing-2005_08.xsd" />
+
+
+
+<!-- ======================== Utility Types ======================= -->
+ <xsd:simpleType name="PairsOfURIType">
+ <xsd:list itemType="xsd:anyURI" />
+ </xsd:simpleType>
+
+<!-- ================ PortType Attribute Extensions ================ -->
+ <xsd:attribute name="Descriptor" type="xsd:QName" />
+
+ <xsd:attribute name="DescriptorLocation" type="xsd:anyURI" />
+
+<!-- ================= Documentation Component ==================== -->
+ <xsd:complexType name="DocumentationType" mixed="true" >
+ <xsd:sequence>
+ <xsd:any namespace="##any"
+ minOccurs="0" maxOccurs="unbounded"
+ processContents="lax" />
+ </xsd:sequence>
+ <xsd:anyAttribute/>
+ </xsd:complexType>
+
+ <xsd:complexType name="DocumentedType">
+ <xsd:sequence>
+ <xsd:element name="documentation" type="wsrmd:DocumentationType"
+ minOccurs="0" maxOccurs="1" />
+ </xsd:sequence>
+ </xsd:complexType>
+
+<!-- ================== Definitions Component ===================== -->
+<!--
+ <Definitions
+ targetNamespace="xsd:anyURI"
+ {anyAttribute}* >
+
+ <documentation />?
+ <MetadataDescriptor /> *
+ {any}*
+
+</Definitions>
+ -->
+
+ <xsd:complexType name= "DefinitionsType" >
+ <xsd:complexContent>
+ <xsd:extension base="wsrmd:DocumentedType">
+ <xsd:sequence>
+ <xsd:element ref="wsrmd:MetadataDescriptor"
+ minOccurs="0" maxOccurs="unbounded" />
+ <xsd:any namespace="##other"
+ minOccurs="0" maxOccurs="unbounded"
+ processContents="lax" />
+ </xsd:sequence>
+ <xsd:attribute name="targetNamespace"
+ type="xsd:anyURI" use="required"/>
+ <xsd:anyAttribute namespace="##other" processContents="lax"/>
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+
+ <xsd:element name="Definitions" type="wsrmd:DefinitionsType" >
+ <xsd:key name="MetadataDescriptor">
+ <xsd:annotation>
+ <xsd:documentation>
+ To form a QName, the name of any MetadataDescriptor must be
+ unique within a Definitions element.
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:selector xpath="wsrmd:MetadataDescriptor" />
+ <xsd:field xpath="@name" />
+ </xsd:key>
+ </xsd:element>
+
+<!-- =============== MetadataDescriptor Component =================== -->
+<!--
+<MetadataDescriptor
+ name="xsd:NCName"
+ interface="xsd:QName"
+ wsdlLocation="list of xsd:anyURI"?
+ {anyAttribute}* >
+
+ <documentation />?
+ <Property /> *
+ {any}*
+
+</MetadataDescriptor>
+-->
+
+ <xsd:complexType name= "MetadataDescriptorType" >
+ <xsd:complexContent>
+ <xsd:extension base="wsrmd:DocumentedType">
+ <xsd:sequence>
+ <xsd:element ref="wsrmd:Property"
+ minOccurs="0" maxOccurs="unbounded" />
+ <xsd:any namespace="##other"
+ minOccurs="0" maxOccurs="unbounded"
+ processContents="lax" />
+ </xsd:sequence>
+ <xsd:attribute name="name"
+ type="xsd:NCName" use="required"/>
+ <xsd:attribute name="interface"
+ type="xsd:QName" use="required"/>
+ <xsd:attribute name="wsdlLocation"
+ type="wsrmd:PairsOfURIType" />
+ <xsd:anyAttribute namespace="##other" processContents="lax"/>
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+
+ <xsd:element name="MetadataDescriptor"
+ type="wsrmd:MetadataDescriptorType" />
+
+<!-- ==================== Property Component ====================== -->
+<!--
+<Property
+ name="xsd:QName"
+ mutability="[constant|appendable|mutable]" ?
+ modifiability="[read-only|read-write]" ?
+ subscribability="xs:boolean" ?
+ {anyAttribute}* >
+
+ <documentation />?
+ [ <ValidValues> {any}* </ValidValues> |
+ <ValidValueRange lowerBound=’xsd:simpleType’
+ upperBound=’xsd:simpleType’>
+ </ValidValueRange> ] ?
+ <StaticValues> {any}* </StaticValues> ?
+
+ {any} *
+
+</Property>
+-->
+ <xsd:complexType name= "PropertyType" >
+ <xsd:complexContent>
+ <xsd:extension base="wsrmd:DocumentedType">
+ <xsd:sequence>
+ <xsd:choice>
+ <xsd:element ref="wsrmd:ValidValues"
+ minOccurs="0" maxOccurs="1" />
+ <xsd:element ref="wsrmd:ValidValueRange"
+ minOccurs="0" maxOccurs="1" />
+ </xsd:choice>
+ <xsd:element ref="wsrmd:StaticValues"
+ minOccurs="0" maxOccurs="1" />
+ <xsd:any namespace="##other"
+ minOccurs="0" maxOccurs="unbounded"
+ processContents="lax" />
+ </xsd:sequence>
+ <xsd:attribute name="name"
+ type="xsd:QName" use="required"/>
+ <xsd:attribute name="mutability"
+ type="wsrmd:MutabilityType" />
+ <xsd:attribute name="modifiability"
+ type="wsrmd:ModifiabilityType" />
+ <xsd:attribute name="subscribability" type="xsd:boolean" default="false" />
+ <xsd:anyAttribute namespace="##other" processContents="lax"/>
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+
+ <xsd:element name="Property" type="wsrmd:PropertyType" />
+
+ <xsd:simpleType name="MutabilityType">
+ <xsd:restriction base="xsd:string" >
+ <xsd:enumeration value="constant" />
+ <xsd:enumeration value="appendable" />
+ <xsd:enumeration value="mutable" />
+ </xsd:restriction>
+ </xsd:simpleType>
+
+ <xsd:simpleType name="ModifiabilityType">
+ <xsd:restriction base="xsd:string" >
+ <xsd:enumeration value="read-only" />
+ <xsd:enumeration value="read-write" />
+ </xsd:restriction>
+ </xsd:simpleType>
+
+<!-- ================= Valid Values Component ===================== -->
+<!--
+<ValidValues
+ {anyAttribute}* >
+ <documentation />?
+ {any}*
+</ValidValues>
+-->
+ <xsd:complexType name= "ValidValuesType" mixed="true">
+ <xsd:sequence>
+ <xsd:element name="documentation" type="wsrmd:DocumentationType"
+ minOccurs="0" maxOccurs="1" />
+
+ <xsd:any namespace="##other"
+ minOccurs="0" maxOccurs="unbounded"
+ processContents="lax" />
+ </xsd:sequence>
+ <xsd:anyAttribute namespace="##other" processContents="lax"/>
+ </xsd:complexType>
+
+ <xsd:element name="ValidValues" type="wsrmd:ValidValuesType" />
+
+<!-- ================= Valid Range Component ===================== -->
+<!--
+<ValidValueRange
+ lowerBound="xs:anySimpleType" ? upperBound="xs:anySimpleType" ?
+ {anyAttribute}* >
+ <documentation />?
+ {any}*
+</ValidValueRange>
+-->
+ <xsd:complexType name= "ValidValueRangeType" mixed="true">
+ <xsd:sequence>
+ <xsd:element name="documentation" type="wsrmd:DocumentationType"
+ minOccurs="0" maxOccurs="1" />
+
+ <xsd:any namespace="##other"
+ minOccurs="0" maxOccurs="unbounded"
+ processContents="lax" />
+ </xsd:sequence>
+ <xsd:attribute name="lowerBound" type="xsd:anySimpleType" />
+ <xsd:attribute name="upperBound" type="xsd:anySimpleType" />
+ <xsd:anyAttribute namespace="##other" processContents="lax"/>
+ </xsd:complexType>
+
+ <xsd:element name="ValidValueRange" type="wsrmd:ValidValueRangeType" />
+
+<!-- ================ Static Values Component ===================== -->
+<!--
+<StaticValues
+ {anyAttribute}* >
+ <documentation />?
+ {any}*
+</StaticValues>
+-->
+ <xsd:complexType name= "StaticValuesType" mixed="true">
+ <xsd:sequence>
+ <xsd:element name="documentation" type="wsrmd:DocumentationType"
+ minOccurs="0" maxOccurs="1" />
+
+ <xsd:any namespace="##other"
+ minOccurs="0" maxOccurs="unbounded"
+ processContents="lax" />
+ </xsd:sequence>
+ <xsd:anyAttribute namespace="##other" processContents="lax"/>
+ </xsd:complexType>
+
+ <xsd:element name="StaticValues" type="wsrmd:StaticValuesType" />
+
+<!-- ================ Initial Values Component ==================== -->
+<!--
+<InitialValues
+ {anyAttribute}* >
+ <documentation />?
+ {any}*
+</InitialValues>
+-->
+ <xsd:complexType name= "InitialValuesType" mixed="true">
+ <xsd:sequence>
+ <xsd:element name="documentation" type="wsrmd:DocumentationType"
+ minOccurs="0" maxOccurs="1" />
+
+ <xsd:any namespace="##other"
+ minOccurs="0" maxOccurs="unbounded"
+ processContents="lax" />
+ </xsd:sequence>
+ <xsd:anyAttribute namespace="##other" processContents="lax"/>
+ </xsd:complexType>
+
+ <xsd:element name="InitialValues" type="wsrmd:InitialValuesType" />
+
+
+<!-- =========== MetadataDescriptorReference RP GED =============== -->
+ <xsd:complexType name="MetadataDescriptorReferenceType">
+ <xsd:complexContent>
+ <xsd:extension base="wsa:EndpointReferenceType"/>
+ </xsd:complexContent>
+ </xsd:complexType>
+
+ <xsd:element name="MetadataDescriptorReference"
+ type="wsrmd:MetadataDescriptorReferenceType" />
+
+<!--
+
+Metadata Resource RP Doc
+
+This defines one property - MetadataDescriptor - which must have a cardinality of one.
+
+-->
+
+ <xsd:element name="MetadataResourceRP" type="wsrmd:DefinitionsType"/>
+
+</xsd:schema>
diff --git a/qpid/java/management/client/src/main/java/wsdl/WS-ResourceProperties-1_2.wsdl b/qpid/java/management/client/src/main/java/wsdl/WS-ResourceProperties-1_2.wsdl
new file mode 100644
index 0000000000..5d9d7562f4
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/wsdl/WS-ResourceProperties-1_2.wsdl
@@ -0,0 +1,395 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+
+OASIS takes no position regarding the validity or scope of any intellectual property or other rights that might be claimed to pertain to the implementation or use of the technology described in this document or the extent to which any license under such rights might or might not be available; neither does it represent that it has made any effort to identify any such rights. Information on OASIS's procedures with respect to rights in OASIS specifications can be found at the OASIS website. Copies of claims of rights made available for publication and any assurances of licenses to be made available, or the result of an attempt made to obtain a general license or permission for the use of such proprietary rights by implementors or users of this specification, can be obtained from the OASIS Executive Director.
+
+OASIS invites any interested party to bring to its attention any copyrights, patents or patent applications, or other proprietary rights which may cover technology that may be required to implement this specification. Please address the information to the OASIS Executive Director.
+
+Copyright (C) OASIS Open (2005). All Rights Reserved.
+
+This document and translations of it may be copied and furnished to others, and derivative works that comment on or otherwise explain it or assist in its implementation may be prepared, copied, published and distributed, in whole or in part, without restriction of any kind, provided that the above copyright notice and this paragraph are included on all such copies and derivative works. However, this document itself may not be modified in any way, such as by removing the copyright notice or references to OASIS, except as needed for the purpose of developing OASIS specifications, in which case the procedures for copyrights defined in the OASIS Intellectual Property Rights document must be followed, or as required to translate it into languages other than English.
+
+The limited permissions granted above are perpetual and will not be revoked by OASIS or its successors or assigns.
+
+This document and the information contained herein is provided on an "AS IS" basis and OASIS DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+
+-->
+
+<wsdl:definitions name="WS-ResourceProperties"
+ xmlns="http://schemas.xmlsoap.org/wsdl/"
+ xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
+ xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ xmlns:wsa="http://www.w3.org/2005/08/addressing"
+ xmlns:wsrf-bf="http://docs.oasis-open.org/wsrf/bf-2"
+ xmlns:wsrf-rp="http://docs.oasis-open.org/wsrf/rp-2"
+ xmlns:wsrf-rpw="http://docs.oasis-open.org/wsrf/rpw-2"
+ xmlns:wsrf-rw="http://docs.oasis-open.org/wsrf/rw-2"
+ targetNamespace="http://docs.oasis-open.org/wsrf/rpw-2"
+>
+
+<!-- ========================== Imports ========================== -->
+
+ <wsdl:import
+ namespace="http://docs.oasis-open.org/wsrf/rw-2"
+ location="WS-Resource-1_2.wsdl" />
+
+<!-- ===================== Types Definitions ====================== -->
+ <wsdl:types>
+ <xsd:schema>
+ <xsd:import
+ namespace="http://docs.oasis-open.org/wsrf/rp-2"
+ schemaLocation="WS-ResourceProperties-1_2.xsd" />
+ </xsd:schema>
+ </wsdl:types>
+
+<!-- ================== GetResourcePropertyDocument ===============
+ GetResourcePropertyDocument()
+ returns: any
+-->
+ <wsdl:message name="GetResourcePropertyDocumentRequest">
+ <wsdl:part name="GetResourcePropertyDocumentRequest"
+ element="wsrf-rp:GetResourcePropertyDocument"/>
+ </wsdl:message>
+
+ <wsdl:message name="GetResourcePropertyDocumentResponse">
+ <wsdl:part name="GetResourcePropertyDocumentResponse"
+ element="wsrf-rp:GetResourcePropertyDocumentResponse"/>
+ </wsdl:message>
+
+<!-- ===================== GetResourceProperty ====================
+ GetResourceProperty(QName)
+ returns: any
+-->
+ <wsdl:message name="GetResourcePropertyRequest">
+ <wsdl:part name="GetResourcePropertyRequest"
+ element="wsrf-rp:GetResourceProperty" />
+ </wsdl:message>
+
+ <wsdl:message name="GetResourcePropertyResponse">
+ <wsdl:part name="GetResourcePropertyResponse"
+ element="wsrf-rp:GetResourcePropertyResponse" />
+ </wsdl:message>
+
+ <wsdl:message name="InvalidResourcePropertyQNameFault">
+ <part name="InvalidResourcePropertyQNameFault"
+ element="wsrf-rp:InvalidResourcePropertyQNameFault" />
+ </wsdl:message>
+
+<!-- ==============GetMultipleResourceProperties ==================
+ GetMultipleResourceProperties(list of QName)
+ returns: sequence of any
+-->
+ <wsdl:message name="GetMultipleResourcePropertiesRequest">
+ <wsdl:part name="GetMultipleResourcePropertiesRequest"
+ element="wsrf-rp:GetMultipleResourceProperties" />
+ </wsdl:message>
+
+ <wsdl:message name="GetMultipleResourcePropertiesResponse">
+ <wsdl:part name="GetMultipleResourcePropertiesResponse"
+ element="wsrf-rp:GetMultipleResourcePropertiesResponse" />
+ </wsdl:message>
+<!-- ================== PutResourcePropertyDocument ===============
+ PutResourcePropertyDocument(any)
+ returns: any?
+-->
+ <wsdl:message name="PutResourcePropertyDocumentRequest">
+ <wsdl:part name="PutResourcePropertyDocumentRequest"
+ element="wsrf-rp:PutResourcePropertyDocument"/>
+ </wsdl:message>
+
+ <wsdl:message name="PutResourcePropertyDocumentResponse">
+ <wsdl:part name="PutResourcePropertyDocumentResponse"
+ element="wsrf-rp:PutResourcePropertyDocumentResponse"/>
+ </wsdl:message>
+
+ <wsdl:message name="UnableToPutResourcePropertyDocumentFault">
+ <part name="UnableToPutResourcePropertyDocumentFault"
+ element="wsrf-rp:UnableToPutResourcePropertyDocumentFault" />
+ </wsdl:message>
+
+<!-- ================= SetResourceProperties ======================
+ SetResourceProperties(
+ { insert (any)* |
+ update (any)* |
+ delete@QName } +
+ )
+ returns: empty
+-->
+ <wsdl:message name="SetResourcePropertiesRequest">
+ <wsdl:part name="SetResourcePropertiesRequest"
+ element="wsrf-rp:SetResourceProperties" />
+ </wsdl:message>
+
+ <wsdl:message name="SetResourcePropertiesResponse">
+ <wsdl:part name="SetResourcePropertiesResponse"
+ element="wsrf-rp:SetResourcePropertiesResponse" />
+ </wsdl:message>
+
+ <wsdl:message name="InvalidModificationFault">
+ <part name="InvalidModificationFault"
+ element="wsrf-rp:InvalidModificationFault" />
+ </wsdl:message>
+
+ <wsdl:message name="UnableToModifyResourcePropertyFault">
+ <part name="UnableToModifyResourcePropertyFault"
+ element="wsrf-rp:UnableToModifyResourcePropertyFault" />
+ </wsdl:message>
+
+ <wsdl:message name="SetResourcePropertyRequestFailedFault">
+ <part name="SetResourcePropertyRequestFailedFault"
+ element="wsrf-rp:SetResourcePropertyRequestFailedFault" />
+ </wsdl:message>
+
+<!-- =============== InsertResourceProperties =====================
+ InsertResourceProperties((any)* )
+ returns: empty
+-->
+ <wsdl:message name="InsertResourcePropertiesRequest">
+ <wsdl:part name="InsertResourcePropertiesRequest"
+ element="wsrf-rp:InsertResourceProperties" />
+ </wsdl:message>
+
+ <wsdl:message name="InsertResourcePropertiesResponse">
+ <wsdl:part name="InsertResourcePropertiesResponse"
+ element="wsrf-rp:InsertResourcePropertiesResponse" />
+ </wsdl:message>
+
+ <wsdl:message name="InsertResourcePropertiesRequestFailedFault">
+ <part name="InsertResourcePropertiesRequestFailedFault"
+ element="wsrf-rp:InsertResourcePropertiesRequestFailedFault" />
+ </wsdl:message>
+
+<!-- =============== UpdateResourceProperties =====================
+ UpdateResourceProperties((any)* )
+ returns: empty
+-->
+ <wsdl:message name="UpdateResourcePropertiesRequest">
+ <wsdl:part name="UpdateResourcePropertiesRequest"
+ element="wsrf-rp:UpdateResourceProperties" />
+ </wsdl:message>
+
+ <wsdl:message name="UpdateResourcePropertiesResponse">
+ <wsdl:part name="UpdateResourcePropertiesResponse"
+ element="wsrf-rp:UpdateResourcePropertiesResponse" />
+ </wsdl:message>
+
+ <wsdl:message name="UpdateResourcePropertiesRequestFailedFault">
+ <part name="UpdateResourcePropertiesRequestFailedFault"
+ element="wsrf-rp:UpdateResourcePropertiesRequestFailedFault" />
+ </wsdl:message>
+
+<!-- =============== DeleteResourceProperties =====================
+ DeleteResourceProperties( ResourceProperty )
+ returns: empty
+-->
+ <wsdl:message name="DeleteResourcePropertiesRequest">
+ <wsdl:part name="DeleteResourcePropertiesRequest"
+ element="wsrf-rp:DeleteResourceProperties" />
+ </wsdl:message>
+
+ <wsdl:message name="DeleteResourcePropertiesResponse">
+ <wsdl:part name="DeleteResourcePropertiesResponse"
+ element="wsrf-rp:DeleteResourcePropertiesResponse" />
+ </wsdl:message>
+
+ <wsdl:message name="DeleteResourcePropertiesRequestFailedFault">
+ <part name="DeleteResourcePropertiesRequestFailedFault"
+ element="wsrf-rp:DeleteResourcePropertiesRequestFailedFault" />
+ </wsdl:message>
+
+<!-- ================ QueryResourceProperties =====================
+ QueryResourceProperties(QueryExpression)
+ returns: any
+-->
+ <wsdl:message name="QueryResourcePropertiesRequest">
+ <wsdl:part name="QueryResourcePropertiesRequest"
+ element="wsrf-rp:QueryResourceProperties" />
+ </wsdl:message>
+
+ <wsdl:message name="QueryResourcePropertiesResponse">
+ <wsdl:part name="QueryResourcePropertiesResponse"
+ element="wsrf-rp:QueryResourcePropertiesResponse" />
+ </wsdl:message>
+
+ <wsdl:message name="UnknownQueryExpressionDialectFault">
+ <part name="UnknownQueryExpressionDialectFault"
+ element="wsrf-rp:UnknownQueryExpressionDialectFault" />
+ </wsdl:message>
+
+ <wsdl:message name="InvalidQueryExpressionFault">
+ <part name="InvalidQueryExpressionFault"
+ element="wsrf-rp:InvalidQueryExpressionFault" />
+ </wsdl:message>
+
+ <wsdl:message name="QueryEvaluationErrorFault">
+ <part name="QueryEvaluationErrorFault"
+ element="wsrf-rp:QueryEvaluationErrorFault" />
+ </wsdl:message>
+
+<!-- =================== PortType Definitions ===================== -->
+ <wsdl:portType name="GetResourcePropertyDocument">
+ <wsdl:operation name="GetResourcePropertyDocument">
+ <wsdl:input name="GetResourcePropertyDocumentRequest"
+ message="wsrf-rpw:GetResourcePropertyDocumentRequest"/>
+ <wsdl:output name="GetResourcePropertyDocumentResponse"
+ message="wsrf-rpw:GetResourcePropertyDocumentResponse"/>
+ <wsdl:fault name="ResourceUnknownFault"
+ message="wsrf-rw:ResourceUnknownFault"/>
+ <wsdl:fault name="ResourceUnavailableFault"
+ message="wsrf-rw:ResourceUnavailableFault"/>
+ </wsdl:operation>
+ </wsdl:portType>
+
+ <wsdl:portType name="GetResourceProperty">
+ <wsdl:operation name="GetResourceProperty">
+ <wsdl:input name="GetResourcePropertyRequest"
+ message="wsrf-rpw:GetResourcePropertyRequest" />
+ <wsdl:output name="GetResourcePropertyResponse"
+ message="wsrf-rpw:GetResourcePropertyResponse" />
+ <wsdl:fault name="ResourceUnknownFault"
+ message="wsrf-rw:ResourceUnknownFault"/>
+ <wsdl:fault name="ResourceUnavailableFault"
+ message="wsrf-rw:ResourceUnavailableFault"/>
+ <wsdl:fault name="InvalidResourcePropertyQNameFault"
+ message="wsrf-rpw:InvalidResourcePropertyQNameFault" />
+ </wsdl:operation>
+ </wsdl:portType>
+
+ <wsdl:portType name="GetMultipleResourceProperties">
+ <wsdl:operation name="GetMultipleResourceProperties">
+ <wsdl:input name="GetMultipleResourcePropertiesRequest"
+ message="wsrf-rpw:GetMultipleResourcePropertiesRequest" />
+ <wsdl:output name="GetMultipleResourcePropertiesResponse"
+ message="wsrf-rpw:GetMultipleResourcePropertiesResponse" />
+ <wsdl:fault name="ResourceUnknownFault"
+ message="wsrf-rw:ResourceUnknownFault"/>
+ <wsdl:fault name="ResourceUnavailableFault"
+ message="wsrf-rw:ResourceUnavailableFault"/>
+ <wsdl:fault name="InvalidResourcePropertyQNameFault"
+ message="wsrf-rpw:InvalidResourcePropertyQNameFault" />
+ </wsdl:operation>
+ </wsdl:portType>
+
+ <wsdl:portType name="PutResourcePropertyDocument">
+ <wsdl:operation name="PutResourcePropertyDocument">
+ <wsdl:input name="PutResourcePropertyDocumentRequest"
+ message="wsrf-rpw:PutResourcePropertyDocumentRequest" />
+ <wsdl:output name="PutResourcePropertyDocumentResponse"
+ message="wsrf-rpw:PutResourcePropertyDocumentResponse" />
+ <wsdl:fault name="ResourceUnknownFault"
+ message="wsrf-rw:ResourceUnknownFault"/>
+ <wsdl:fault name="ResourceUnavailableFault"
+ message="wsrf-rw:ResourceUnavailableFault"/>
+ <wsdl:fault name="UnableToPutResourcePropertyDocumentFault"
+ message="wsrf-rpw:UnableToPutResourcePropertyDocumentFault" />
+ </wsdl:operation>
+ </wsdl:portType>
+
+ <wsdl:portType name="SetResourceProperties">
+ <wsdl:operation name="SetResourceProperties">
+ <wsdl:input name="SetResourcePropertiesRequest"
+ message="wsrf-rpw:SetResourcePropertiesRequest" />
+ <wsdl:output name="SetResourcePropertiesResponse"
+ message="wsrf-rpw:SetResourcePropertiesResponse" />
+ <wsdl:fault name="ResourceUnknownFault"
+ message="wsrf-rw:ResourceUnknownFault"/>
+ <wsdl:fault name="ResourceUnavailableFault"
+ message="wsrf-rw:ResourceUnavailableFault"/>
+ <wsdl:fault name="InvalidModificationFault"
+ message="wsrf-rpw:InvalidModificationFault" />
+ <wsdl:fault name="UnableToModifyResourcePropertyFault"
+ message="wsrf-rpw:UnableToModifyResourcePropertyFault" />
+ <wsdl:fault name="InvalidResourcePropertyQNameFault"
+ message="wsrf-rpw:InvalidResourcePropertyQNameFault" />
+ <wsdl:fault name="SetResourcePropertyRequestFailedFault"
+ message="wsrf-rpw:SetResourcePropertyRequestFailedFault" />
+ </wsdl:operation>
+ </wsdl:portType>
+
+ <wsdl:portType name="InsertResourceProperties">
+ <wsdl:operation name="InsertResourceProperties">
+ <wsdl:input name="InsertResourcePropertiesRequest"
+ message="wsrf-rpw:InsertResourcePropertiesRequest" />
+ <wsdl:output name="InsertResourcePropertiesResponse"
+ message="wsrf-rpw:InsertResourcePropertiesResponse" />
+ <wsdl:fault name="ResourceUnknownFault"
+ message="wsrf-rw:ResourceUnknownFault"/>
+ <wsdl:fault name="ResourceUnavailableFault"
+ message="wsrf-rw:ResourceUnavailableFault"/>
+ <wsdl:fault name="InvalidModificationFault"
+ message="wsrf-rpw:InvalidModificationFault" />
+ <wsdl:fault name="UnableToModifyResourcePropertyFault"
+ message="wsrf-rpw:UnableToModifyResourcePropertyFault" />
+ <wsdl:fault name="InvalidResourcePropertyQNameFault"
+ message="wsrf-rpw:InvalidResourcePropertyQNameFault" />
+ <wsdl:fault name="InsertResourcePropertiesRequestFailedFault"
+ message="wsrf-rpw:InsertResourcePropertiesRequestFailedFault" />
+ </wsdl:operation>
+ </wsdl:portType>
+
+ <wsdl:portType name="UpdateResourceProperties">
+ <wsdl:operation name="UpdateResourceProperties">
+ <wsdl:input name="UpdateResourcePropertiesRequest"
+ message="wsrf-rpw:UpdateResourcePropertiesRequest" />
+ <wsdl:output name="UpdateResourcePropertiesResponse"
+ message="wsrf-rpw:UpdateResourcePropertiesResponse" />
+ <wsdl:fault name="ResourceUnknownFault"
+ message="wsrf-rw:ResourceUnknownFault"/>
+ <wsdl:fault name="ResourceUnavailableFault"
+ message="wsrf-rw:ResourceUnavailableFault"/>
+ <wsdl:fault name="InvalidModificationFault"
+ message="wsrf-rpw:InvalidModificationFault" />
+ <wsdl:fault name="UnableToModifyResourcePropertyFault"
+ message="wsrf-rpw:UnableToModifyResourcePropertyFault" />
+ <wsdl:fault name="InvalidResourcePropertyQNameFault"
+ message="wsrf-rpw:InvalidResourcePropertyQNameFault" />
+ <wsdl:fault name="UpdateResourcePropertiesRequestFailedFault"
+ message="wsrf-rpw:UpdateResourcePropertiesRequestFailedFault" />
+ </wsdl:operation>
+ </wsdl:portType>
+
+ <wsdl:portType name="DeleteResourceProperties">
+ <wsdl:operation name="DeleteResourceProperties">
+ <wsdl:input name="DeleteResourcePropertiesRequest"
+ message="wsrf-rpw:DeleteResourcePropertiesRequest" />
+ <wsdl:output name="DeleteResourcePropertiesResponse"
+ message="wsrf-rpw:DeleteResourcePropertiesResponse" />
+ <wsdl:fault name="ResourceUnknownFault"
+ message="wsrf-rw:ResourceUnknownFault"/>
+ <wsdl:fault name="ResourceUnavailableFault"
+ message="wsrf-rw:ResourceUnavailableFault"/>
+ <wsdl:fault name="InvalidModificationFault"
+ message="wsrf-rpw:InvalidModificationFault" />
+ <wsdl:fault name="UnableToModifyResourcePropertyFault"
+ message="wsrf-rpw:UnableToModifyResourcePropertyFault" />
+ <wsdl:fault name="InvalidResourcePropertyQNameFault"
+ message="wsrf-rpw:InvalidResourcePropertyQNameFault" />
+ <wsdl:fault name="DeleteResourcePropertiesRequestFailedFault"
+ message="wsrf-rpw:DeleteResourcePropertiesRequestFailedFault" />
+ </wsdl:operation>
+ </wsdl:portType>
+
+<wsdl:portType name="QueryResourceProperties"
+ wsrf-rp:ResourceProperties="wsrf-rp:QueryExpressionRPDocument">
+ <wsdl:operation name="QueryResourceProperties">
+ <wsdl:input name="QueryResourcePropertiesRequest"
+ message="wsrf-rpw:QueryResourcePropertiesRequest" />
+ <wsdl:output name="QueryResourcePropertiesResponse"
+ message="wsrf-rpw:QueryResourcePropertiesResponse" />
+ <wsdl:fault name="ResourceUnknownFault"
+ message="wsrf-rw:ResourceUnknownFault"/>
+ <wsdl:fault name="ResourceUnavailableFault"
+ message="wsrf-rw:ResourceUnavailableFault"/>
+ <wsdl:fault name="InvalidResourcePropertyQNameFault"
+ message="wsrf-rpw:InvalidResourcePropertyQNameFault" />
+ <wsdl:fault name="UnknownQueryExpressionDialectFault"
+ message="wsrf-rpw:UnknownQueryExpressionDialectFault" />
+ <wsdl:fault name="InvalidQueryExpressionFault"
+ message="wsrf-rpw:InvalidQueryExpressionFault" />
+ <wsdl:fault name="QueryEvaluationErrorFault"
+ message="wsrf-rpw:QueryEvaluationErrorFault" />
+ </wsdl:operation>
+
+ </wsdl:portType>
+
+</wsdl:definitions> \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/wsdl/WS-ResourceProperties-1_2.xsd b/qpid/java/management/client/src/main/java/wsdl/WS-ResourceProperties-1_2.xsd
new file mode 100644
index 0000000000..c408b36db1
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/wsdl/WS-ResourceProperties-1_2.xsd
@@ -0,0 +1,394 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+OASIS takes no position regarding the validity or scope of any intellectual property or other rights that might be claimed to pertain to the implementation or use of the technology described in this document or the extent to which any license under such rights might or might not be available; neither does it represent that it has made any effort to identify any such rights. Information on OASIS's procedures with respect to rights in OASIS specifications can be found at the OASIS website. Copies of claims of rights made available for publication and any assurances of licenses to be made available, or the result of an attempt made to obtain a general license or permission for the use of such proprietary rights by implementors or users of this specification, can be obtained from the OASIS Executive Director.
+
+OASIS invites any interested party to bring to its attention any copyrights, patents or patent applications, or other proprietary rights which may cover technology that may be required to implement this specification. Please address the information to the OASIS Executive Director.
+
+Copyright (C) OASIS Open (2005). All Rights Reserved.
+
+This document and translations of it may be copied and furnished to others, and derivative works that comment on or otherwise explain it or assist in its implementation may be prepared, copied, published and distributed, in whole or in part, without restriction of any kind, provided that the above copyright notice and this paragraph are included on all such copies and derivative works. However, this document itself may not be modified in any way, such as by removing the copyright notice or references to OASIS, except as needed for the purpose of developing OASIS specifications, in which case the procedures for copyrights defined in the OASIS Intellectual Property Rights document must be followed, or as required to translate it into languages other than English.
+
+The limited permissions granted above are perpetual and will not be revoked by OASIS or its successors or assigns.
+
+This document and the information contained herein is provided on an "AS IS" basis and OASIS DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+
+-->
+<xsd:schema
+ xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ xmlns:wsrf-rp="http://docs.oasis-open.org/wsrf/rp-2"
+ xmlns:wsrf-bf="http://docs.oasis-open.org/wsrf/bf-2"
+ elementFormDefault="qualified" attributeFormDefault="unqualified"
+ targetNamespace="http://docs.oasis-open.org/wsrf/rp-2"
+>
+ <xsd:import
+ namespace="http://docs.oasis-open.org/wsrf/bf-2"
+ schemaLocation="WS-BaseFaults-1_2.xsd"
+ />
+<!-- =============== Resource Property Related =================== -->
+<!-- ====== Resource Properties for QueryResourceProperties ======= -->
+ <xsd:element name="QueryExpressionDialect" type="xsd:anyURI"/>
+
+ <xsd:element name="QueryExpressionRPDocument">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element ref="wsrf-rp:QueryExpressionDialect"
+ minOccurs="0" maxOccurs="unbounded" />
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+
+<!-- ======= Global Attribute Declaration for WSDL 1.1 portType==== -->
+ <xsd:attribute name="ResourceProperties" type="xsd:QName" />
+
+<!-- = Notification Message for ResourceProperties value change === -->
+ <xsd:complexType name="ResourcePropertyValueChangeNotificationType">
+ <xsd:sequence>
+ <xsd:element name="OldValues" nillable="true"
+ minOccurs="0" maxOccurs="1" >
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:any minOccurs="1" maxOccurs="unbounded" />
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="NewValues" nillable="true"
+ minOccurs="1" maxOccurs="1" >
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:any minOccurs="1" maxOccurs="unbounded" />
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:sequence>
+ </xsd:complexType>
+
+ <xsd:element name="ResourcePropertyValueChangeNotification"
+ type="wsrf-rp:ResourcePropertyValueChangeNotificationType" />
+
+ <xsd:complexType name="QueryExpressionType" mixed="true">
+ <xsd:sequence>
+ <xsd:any minOccurs="0" maxOccurs="1" processContents="lax" />
+ </xsd:sequence>
+ <xsd:attribute name="Dialect" type="xsd:anyURI" />
+ </xsd:complexType>
+
+ <xsd:element name="QueryExpression" type="wsrf-rp:QueryExpressionType" />
+
+<!-- ======= Message Types for GetResourcePropertyDocument ======= -->
+
+ <xsd:element name="GetResourcePropertyDocument">
+ <xsd:complexType/>
+ </xsd:element>
+
+ <xsd:element name="GetResourcePropertyDocumentResponse">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:any minOccurs="1" maxOccurs="1"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+
+<!-- ========== Message Types for GetResourceProperty ============ -->
+
+ <xsd:element name="GetResourceProperty"
+ type="xsd:QName" />
+
+ <xsd:element name="GetResourcePropertyResponse" >
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:any minOccurs="0" maxOccurs="unbounded" />
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:complexType name="InvalidResourcePropertyQNameFaultType">
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType"/>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:element name="InvalidResourcePropertyQNameFault"
+ type="wsrf-rp:InvalidResourcePropertyQNameFaultType"/>
+
+<!-- ====== Message Types for GetMultipleResourceProperties ======= -->
+ <xsd:element name="GetMultipleResourceProperties">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="ResourceProperty" type="xsd:QName"
+ minOccurs="1" maxOccurs="unbounded" />
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:element name="GetMultipleResourcePropertiesResponse">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:any minOccurs="0" maxOccurs="unbounded" />
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+
+<!-- ========== Message Types for PutResourceProperty ============ -->
+
+ <xsd:element name="PutResourcePropertyDocument">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:any minOccurs="1" maxOccurs="1"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:element name="PutResourcePropertyDocumentResponse">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:any minOccurs="0" maxOccurs="1"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:complexType name="ResourcePropertyChangeFailureType">
+ <xsd:sequence>
+ <xsd:element name="CurrentValue" minOccurs="0" maxOccurs="1">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:any minOccurs="1" maxOccurs="unbounded" />
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="RequestedValue" minOccurs="0" maxOccurs="1">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:any minOccurs="1" maxOccurs="unbounded" />
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:sequence>
+ <xsd:attribute name="Restored" type="xsd:boolean"/>
+ </xsd:complexType>
+
+ <xsd:complexType
+ name="UnableToPutResourcePropertyDocumentFaultType">
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType">
+ <xsd:sequence>
+ <xsd:element name="ResourcePropertyChangeFailure" type=
+ "wsrf-rp:ResourcePropertyChangeFailureType"/>
+ </xsd:sequence>
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:element name="UnableToPutResourcePropertyDocumentFault"
+ type=
+ "wsrf-rp:UnableToPutResourcePropertyDocumentFaultType"/>
+
+<!-- ========= Message Types for SetResourceProperties =========== -->
+
+ <xsd:complexType name="InsertType">
+ <xsd:sequence>
+ <xsd:any processContents="lax"
+ minOccurs="1" maxOccurs="unbounded" />
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:element name="Insert" type="wsrf-rp:InsertType"/>
+
+ <xsd:complexType name="UpdateType">
+ <xsd:sequence>
+ <xsd:any processContents="lax"
+ minOccurs="1" maxOccurs="unbounded" />
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:element name="Update" type="wsrf-rp:UpdateType"/>
+
+ <xsd:complexType name="DeleteType">
+ <xsd:attribute name="ResourceProperty"
+ type="xsd:QName" use="required" />
+ </xsd:complexType>
+ <xsd:element name="Delete" type="wsrf-rp:DeleteType"/>
+
+ <xsd:element name="SetResourceProperties">
+ <xsd:complexType>
+ <xsd:choice minOccurs="1" maxOccurs="unbounded">
+ <xsd:element ref="wsrf-rp:Insert"/>
+ <xsd:element ref="wsrf-rp:Update"/>
+ <xsd:element ref="wsrf-rp:Delete"/>
+ </xsd:choice>
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:element name="SetResourcePropertiesResponse" >
+ <xsd:complexType />
+ </xsd:element>
+
+ <xsd:complexType
+ name="InvalidModificationFaultType">
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType">
+ <xsd:sequence>
+ <xsd:element name="ResourcePropertyChangeFailure" type=
+ "wsrf-rp:ResourcePropertyChangeFailureType"/>
+ </xsd:sequence>
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:element name=
+ "InvalidModificationFault"
+ type=
+ "wsrf-rp:InvalidModificationFaultType"/>
+
+ <xsd:complexType name="UnableToModifyResourcePropertyFaultType">
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType">
+ <xsd:sequence>
+ <xsd:element name="ResourcePropertyChangeFailure" type=
+ "wsrf-rp:ResourcePropertyChangeFailureType"/>
+ </xsd:sequence>
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:element name="UnableToModifyResourcePropertyFault"
+ type="wsrf-rp:UnableToModifyResourcePropertyFaultType"/>
+
+ <xsd:complexType name="SetResourcePropertyRequestFailedFaultType">
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType">
+ <xsd:sequence>
+ <xsd:element name="ResourcePropertyChangeFailure" type=
+ "wsrf-rp:ResourcePropertyChangeFailureType"/>
+ </xsd:sequence>
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:element name="SetResourcePropertyRequestFailedFault"
+ type=
+ "wsrf-rp:SetResourcePropertyRequestFailedFaultType"/>
+
+ <xsd:complexType name="InsertResourcePropertiesRequestFailedFaultType">
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType">
+ <xsd:sequence>
+ <xsd:element name="ResourcePropertyChangeFailure" type=
+ "wsrf-rp:ResourcePropertyChangeFailureType"/>
+ </xsd:sequence>
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:element name="InsertResourcePropertiesRequestFailedFault"
+ type=
+ "wsrf-rp:InsertResourcePropertiesRequestFailedFaultType"/>
+
+ <xsd:complexType name="UpdateResourcePropertiesRequestFailedFaultType">
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType">
+ <xsd:sequence>
+ <xsd:element name="ResourcePropertyChangeFailure" type=
+ "wsrf-rp:ResourcePropertyChangeFailureType"/>
+ </xsd:sequence>
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:element
+ name="UpdateResourcePropertiesRequestFailedFault"
+ type="wsrf-rp:UpdateResourcePropertiesRequestFailedFaultType"/>
+
+ <xsd:complexType name="DeleteResourcePropertiesRequestFailedFaultType">
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType">
+ <xsd:sequence>
+ <xsd:element name="ResourcePropertyChangeFailure" type=
+ "wsrf-rp:ResourcePropertyChangeFailureType"/>
+ </xsd:sequence>
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:element
+ name="DeleteResourcePropertiesRequestFailedFault"
+ type="wsrf-rp:DeleteResourcePropertiesRequestFailedFaultType"/>
+
+<!-- ======== Message Types for InsertResourceProperties ========== -->
+ <xsd:element name="InsertResourceProperties">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element ref="wsrf-rp:Insert"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:element name="InsertResourcePropertiesResponse" >
+ <xsd:complexType />
+ </xsd:element>
+
+<!-- ======== Message Types for UpdateResourceProperties ========== -->
+ <xsd:element name="UpdateResourceProperties">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element ref="wsrf-rp:Update"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:element name="UpdateResourcePropertiesResponse" >
+ <xsd:complexType />
+ </xsd:element>
+
+<!-- ======== Message Types for DeleteResourceProperties ========== -->
+ <xsd:element name="DeleteResourceProperties">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element ref="wsrf-rp:Delete"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:element name="DeleteResourcePropertiesResponse" >
+ <xsd:complexType />
+ </xsd:element>
+
+<!-- ========= Message Types for QueryResourceProperties ========== -->
+
+ <xsd:element name="QueryResourceProperties" >
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element ref="wsrf-rp:QueryExpression"
+ minOccurs="1" maxOccurs="1"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:element name="QueryResourcePropertiesResponse" >
+ <xsd:complexType>
+ <xsd:complexContent mixed="true">
+ <xsd:restriction base="xsd:anyType">
+ <xsd:sequence>
+ <xsd:any processContents="lax"
+ minOccurs="1" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ </xsd:restriction>
+ </xsd:complexContent>
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:complexType name="UnknownQueryExpressionDialectFaultType">
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType"/>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:element name="UnknownQueryExpressionDialectFault"
+ type="wsrf-rp:UnknownQueryExpressionDialectFaultType"/>
+
+ <xsd:complexType name="InvalidQueryExpressionFaultType">
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType"/>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:element name="InvalidQueryExpressionFault"
+ type="wsrf-rp:InvalidQueryExpressionFaultType"/>
+
+ <xsd:complexType name="QueryEvaluationErrorFaultType">
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType"/>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:element name="QueryEvaluationErrorFault"
+ type="wsrf-rp:QueryEvaluationErrorFaultType"/>
+
+</xsd:schema> \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/wsdl/WS-ServiceGroup-1_2.wsdl b/qpid/java/management/client/src/main/java/wsdl/WS-ServiceGroup-1_2.wsdl
new file mode 100644
index 0000000000..a75cd59728
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/wsdl/WS-ServiceGroup-1_2.wsdl
@@ -0,0 +1,269 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<wsdl:definitions
+ targetNamespace="http://docs.oasis-open.org/wsrf/sgw-2"
+ xmlns:tns="http://docs.oasis-open.org/wsrf/sgw-2"
+ xmlns:wsrf-sg="http://docs.oasis-open.org/wsrf/sg-2"
+ xmlns:wsrf-sgw="http://docs.oasis-open.org/wsrf/sgw-2"
+ xmlns="http://schemas.xmlsoap.org/wsdl/"
+ xmlns:wsa="http://www.w3.org/2005/08/addressing"
+ xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
+ xmlns:wsdl-soap="http://schemas.xmlsoap.org/wsdl/soap/"
+ xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ xmlns:wsx="http://schemas.xmlsoap.org/ws/2004/09/mex"
+ xmlns:wsrf-r="http://docs.oasis-open.org/wsrf/r-2"
+ xmlns:wsrf-rl="http://docs.oasis-open.org/wsrf/rl-2"
+ xmlns:wsrf-bf="http://docs.oasis-open.org/wsrf/bf-2"
+ xmlns:wsrf-rp="http://docs.oasis-open.org/wsrf/rp-2"
+ name="ServiceGroup">
+ <wsdl:types>
+ <xsd:schema
+ elementFormDefault="qualified"
+ targetNamespace="http://schemas.xmlsoap.org/ws/2004/09/mex">
+ <xsd:include schemaLocation="WS-MetadataExchange-2004_09.xsd"/>
+ </xsd:schema>
+ <xsd:schema
+ elementFormDefault="qualified"
+ targetNamespace="http://docs.oasis-open.org/wsrf/rp-2">
+ <xsd:include schemaLocation="WS-ResourceProperties-1_2.xsd" />
+ </xsd:schema>
+ <xsd:schema
+ elementFormDefault="qualified"
+ targetNamespace="http://docs.oasis-open.org/wsrf/r-2">
+ <xsd:include schemaLocation="WS-Resource-1_2.xsd" />
+ </xsd:schema>
+ <xsd:schema
+ elementFormDefault="qualified"
+ targetNamespace="http://docs.oasis-open.org/wsrf/sg-2">
+ <xsd:include schemaLocation="WS-ServiceGroup-1_2.xsd" />
+ </xsd:schema>
+ </wsdl:types>
+ <wsdl:message name="GetMetadataMsg">
+ <wsdl:part name="GetMetadataMsg" element="wsx:GetMetadata" />
+ </wsdl:message>
+ <wsdl:message name="GetMetadataResponseMsg">
+ <wsdl:part name="GetMetadataResponseMsg" element="wsx:Metadata" />
+ </wsdl:message>
+ <wsdl:message name="ResourceUnknownFault">
+ <wsdl:part name="ResourceUnknownFault" element="wsrf-r:ResourceUnknownFault" />
+ </wsdl:message>
+ <wsdl:message name="ResourceUnavailableFault">
+ <wsdl:part name="ResourceUnavailableFault" element="wsrf-r:ResourceUnavailableFault" />
+ </wsdl:message>
+ <wsdl:message name="GetResourcePropertyDocumentRequest">
+ <wsdl:part name="GetResourcePropertyDocumentRequest" element="wsrf-rp:GetResourcePropertyDocument"/>
+ </wsdl:message>
+ <wsdl:message name="GetResourcePropertyDocumentResponse">
+ <wsdl:part name="GetResourcePropertyDocumentResponse" element="wsrf-rp:GetResourcePropertyDocumentResponse"/>
+ </wsdl:message>
+ <wsdl:message name="GetResourcePropertyRequest">
+ <wsdl:part name="GetResourcePropertyRequest" element="wsrf-rp:GetResourceProperty" />
+ </wsdl:message>
+ <wsdl:message name="GetResourcePropertyResponse">
+ <wsdl:part name="GetResourcePropertyResponse" element="wsrf-rp:GetResourcePropertyResponse" />
+ </wsdl:message>
+ <wsdl:message name="InvalidResourcePropertyQNameFault">
+ <wsdl:part name="InvalidResourcePropertyQNameFault" element="wsrf-rp:InvalidResourcePropertyQNameFault" />
+ </wsdl:message>
+ <wsdl:message name="GetMultipleResourcePropertiesRequest">
+ <wsdl:part name="GetMultipleResourcePropertiesRequest" element="wsrf-rp:GetMultipleResourceProperties" />
+ </wsdl:message>
+ <wsdl:message name="GetMultipleResourcePropertiesResponse">
+ <wsdl:part name="GetMultipleResourcePropertiesResponse" element="wsrf-rp:GetMultipleResourcePropertiesResponse" />
+ </wsdl:message>
+ <wsdl:message name="QueryResourcePropertiesRequest">
+ <wsdl:part name="QueryResourcePropertiesRequest" element="wsrf-rp:QueryResourceProperties" />
+ </wsdl:message>
+ <wsdl:message name="QueryResourcePropertiesResponse">
+ <wsdl:part name="QueryResourcePropertiesResponse" element="wsrf-rp:QueryResourcePropertiesResponse" />
+ </wsdl:message>
+ <wsdl:message name="UnknownQueryExpressionDialectFault">
+ <wsdl:part name="UnknownQueryExpressionDialectFault" element="wsrf-rp:UnknownQueryExpressionDialectFault" />
+ </wsdl:message>
+ <wsdl:message name="InvalidQueryExpressionFault">
+ <wsdl:part name="InvalidQueryExpressionFault" element="wsrf-rp:InvalidQueryExpressionFault" />
+ </wsdl:message>
+ <wsdl:message name="QueryEvaluationErrorFault">
+ <wsdl:part name="QueryEvaluationErrorFault" element="wsrf-rp:QueryEvaluationErrorFault" />
+ </wsdl:message>
+ <wsdl:portType
+ name="ServiceGroupPortType"
+ wsrf-rp:ResourceProperties="wsrf-sg:ServiceGroupRP">
+ <wsdl:operation name="GetMetadata">
+ <wsdl:input wsa:Action="http://schemas.xmlsoap.org/ws/2004/09/mex/GetMetadata"
+ name="GetMetadataMsg" message="tns:GetMetadataMsg"/>
+ <wsdl:output wsa:Action="http://schemas.xmlsoap.org/ws/2004/09/mex/GetMetadataResponse"
+ name="GetMetadataResponseMsg" message="tns:GetMetadataResponseMsg"/>
+ </wsdl:operation>
+ <wsdl:operation name="GetResourcePropertyDocument">
+ <wsdl:input wsa:Action="http://docs.oasis-open.org/wsrf/rpw-2/GetResourcePropertyDocument/GetResourcePropertyDocumentRequest"
+ name="GetResourcePropertyDocumentRequest" message="tns:GetResourcePropertyDocumentRequest"/>
+ <wsdl:output wsa:Action="http://docs.oasis-open.org/wsrf/rpw-2/GetResourcePropertyDocument/GetResourcePropertyDocumentResponse"
+ name="GetResourcePropertyDocumentResponse" message="tns:GetResourcePropertyDocumentResponse"/>
+ <wsdl:fault name="ResourceUnknownFault" message="tns:ResourceUnknownFault"/>
+ <wsdl:fault name="ResourceUnavailableFault" message="tns:ResourceUnavailableFault"/>
+ </wsdl:operation>
+ <wsdl:operation name="GetResourceProperty">
+ <wsdl:input wsa:Action="http://docs.oasis-open.org/wsrf/rpw-2/GetResourceProperty/GetResourcePropertyRequest"
+ name="GetResourcePropertyRequest" message="tns:GetResourcePropertyRequest" />
+ <wsdl:output wsa:Action="http://docs.oasis-open.org/wsrf/rpw-2/GetResourceProperty/GetResourcePropertyResponse"
+ name="GetResourcePropertyResponse" message="tns:GetResourcePropertyResponse" />
+ <wsdl:fault name="ResourceUnknownFault" message="tns:ResourceUnknownFault"/>
+ <wsdl:fault name="ResourceUnavailableFault" message="tns:ResourceUnavailableFault"/>
+ <wsdl:fault name="InvalidResourcePropertyQNameFault" message="tns:InvalidResourcePropertyQNameFault" />
+ </wsdl:operation>
+ <wsdl:operation name="GetMultipleResourceProperties">
+ <wsdl:input wsa:Action="http://docs.oasis-open.org/wsrf/rpw-2/GetMultipleResourceProperties/GetMultipleResourcePropertiesRequest"
+ name="GetMultipleResourcePropertiesRequest" message="tns:GetMultipleResourcePropertiesRequest" />
+ <wsdl:output wsa:Action="http://docs.oasis-open.org/wsrf/rpw-2/GetMultipleResourceProperties/GetMultipleResourcePropertiesResponse"
+ name="GetMultipleResourcePropertiesResponse" message="tns:GetMultipleResourcePropertiesResponse" />
+ <wsdl:fault name="ResourceUnknownFault" message="tns:ResourceUnknownFault"/>
+ <wsdl:fault name="ResourceUnavailableFault" message="tns:ResourceUnavailableFault"/>
+ <wsdl:fault name="InvalidResourcePropertyQNameFault" message="tns:InvalidResourcePropertyQNameFault" />
+ </wsdl:operation>
+ <wsdl:operation name="QueryResourceProperties">
+ <wsdl:input wsa:Action="http://docs.oasis-open.org/wsrf/rpw-2/QueryResourceProperties/QueryResourcePropertiesRequest"
+ name="QueryResourcePropertiesRequest" message="tns:QueryResourcePropertiesRequest" />
+ <wsdl:output wsa:Action="http://docs.oasis-open.org/wsrf/rpw-2/QueryResourceProperties/QueryResourcePropertiesResponse"
+ name="QueryResourcePropertiesResponse" message="tns:QueryResourcePropertiesResponse" />
+ <wsdl:fault name="ResourceUnknownFault" message="tns:ResourceUnknownFault"/>
+ <wsdl:fault name="ResourceUnavailableFault" message="tns:ResourceUnavailableFault"/>
+ <wsdl:fault name="UnknownQueryExpressionDialectFault" message="tns:UnknownQueryExpressionDialectFault"/>
+ <wsdl:fault name="InvalidQueryExpressionFault" message="tns:InvalidQueryExpressionFault"/>
+ <wsdl:fault name="QueryEvaluationErrorFault" message="tns:QueryEvaluationErrorFault" />
+ </wsdl:operation>
+ </wsdl:portType>
+ <wsdl:binding name="ServiceGroupBinding" type="tns:ServiceGroupPortType">
+ <wsdl-soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http" />
+ <wsdl:operation name="GetMetadata">
+ <wsdl-soap:operation soapAction="GetMetadata" />
+ <wsdl:input>
+ <wsdl-soap:body
+ use="encoded"
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
+ </wsdl:input>
+ <wsdl:output>
+ <wsdl-soap:body
+ use="encoded"
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
+ </wsdl:output>
+ </wsdl:operation>
+ <wsdl:operation name="GetResourcePropertyDocument">
+ <wsdl-soap:operation soapAction="GetResourcePropertyDocument"/>
+ <wsdl:input name="GetResourcePropertyDocumentRequest">
+ <wsdl-soap:body
+ use="encoded"
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+ </wsdl:input><wsdl:output name="GetResourcePropertyDocumentResponse">
+ <wsdl-soap:body
+ use="encoded"
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+ </wsdl:output>
+ <wsdl:fault name="ResourceUnknownFault">
+ <wsdl-soap:fault
+ use="encoded"
+ name="ResourceUnknownFault"/>
+ </wsdl:fault>
+ <wsdl:fault name="ResourceUnavailableFault">
+ <wsdl-soap:fault
+ use="encoded"
+ name="ResourceUnavailableFault"/>
+ </wsdl:fault>
+ </wsdl:operation>
+ <wsdl:operation name="GetResourceProperty">
+ <wsdl-soap:operation soapAction="GetResourceProperty"/>
+ <wsdl:input name="GetResourcePropertyRequest">
+ <wsdl-soap:body
+ use="encoded"
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+ </wsdl:input><wsdl:output name="GetResourcePropertyResponse">
+ <wsdl-soap:body
+ use="encoded"
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+ </wsdl:output>
+ <wsdl:fault name="ResourceUnknownFault">
+ <wsdl-soap:fault
+ use="encoded"
+ name="ResourceUnknownFault"/>
+ </wsdl:fault>
+ <wsdl:fault name="ResourceUnavailableFault">
+ <wsdl-soap:fault
+ use="encoded"
+ name="ResourceUnavailableFault"/>
+ </wsdl:fault>
+ <wsdl:fault name="InvalidResourcePropertyQNameFault">
+ <wsdl-soap:fault
+ use="encoded"
+ name="InvalidResourcePropertyQNameFault"/>
+ </wsdl:fault>
+ </wsdl:operation>
+ <wsdl:operation name="GetMultipleResourceProperties">
+ <wsdl-soap:operation soapAction="GetMultipleResourceProperties"/>
+ <wsdl:input name="GetMultipleResourcePropertiesRequest">
+ <wsdl-soap:body
+ use="encoded"
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+ </wsdl:input><wsdl:output name="GetMultipleResourcePropertiesResponse">
+ <wsdl-soap:body
+ use="encoded"
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+ </wsdl:output>
+ <wsdl:fault name="ResourceUnknownFault">
+ <wsdl-soap:fault
+ use="encoded"
+ name="ResourceUnknownFault"/>
+ </wsdl:fault>
+ <wsdl:fault name="ResourceUnavailableFault">
+ <wsdl-soap:fault
+ use="encoded"
+ name="ResourceUnavailableFault"/>
+ </wsdl:fault>
+ <wsdl:fault name="InvalidResourcePropertyQNameFault">
+ <wsdl-soap:fault
+ use="encoded"
+ name="InvalidResourcePropertyQNameFault"/>
+ </wsdl:fault>
+ </wsdl:operation>
+ <wsdl:operation name="QueryResourceProperties">
+ <wsdl-soap:operation soapAction="QueryResourceProperties"/>
+ <wsdl:input name="QueryResourcePropertiesRequest">
+ <wsdl-soap:body
+ use="encoded"
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+ </wsdl:input><wsdl:output name="QueryResourcePropertiesResponse">
+ <wsdl-soap:body
+ use="encoded"
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+ </wsdl:output>
+ <wsdl:fault name="ResourceUnknownFault">
+ <wsdl-soap:fault
+ use="encoded"
+ name="ResourceUnknownFault"/>
+ </wsdl:fault>
+ <wsdl:fault name="ResourceUnavailableFault">
+ <wsdl-soap:fault
+ use="encoded"
+ name="ResourceUnavailableFault"/>
+ </wsdl:fault>
+ <wsdl:fault name="UnknownQueryExpressionDialectFault">
+ <wsdl-soap:fault
+ use="encoded"
+ name="UnknownQueryExpressionDialectFault"/>
+ </wsdl:fault>
+ <wsdl:fault name="InvalidQueryExpressionFault">
+ <wsdl-soap:fault
+ use="encoded"
+ name="InvalidQueryExpressionFault"/>
+ </wsdl:fault>
+ <wsdl:fault name="QueryEvaluationErrorFault">
+ <wsdl-soap:fault
+ use="encoded"
+ name="QueryEvaluationErrorFault"/>
+ </wsdl:fault>
+ </wsdl:operation>
+ </wsdl:binding>
+ <wsdl:service name="ServiceGroupService">
+ <wsdl:port name="ServiceGroupPort" binding="tns:ServiceGroupBinding">
+ <wsdl-soap:address location="http://localhost:8080/wsrf/services/ServiceGroup"/>
+ </wsdl:port>
+ </wsdl:service>
+</wsdl:definitions>
diff --git a/qpid/java/management/client/src/main/java/wsdl/WS-ServiceGroup-1_2.xsd b/qpid/java/management/client/src/main/java/wsdl/WS-ServiceGroup-1_2.xsd
new file mode 100644
index 0000000000..87238f90e5
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/wsdl/WS-ServiceGroup-1_2.xsd
@@ -0,0 +1,233 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+OASIS takes no position regarding the validity or scope of any intellectual property or other rights that might be claimed to pertain to the implementation or use of the technology described in this document or the extent to which any license under such rights might or might not be available; neither does it represent that it has made any effort to identify any such rights. Information on OASIS's procedures with respect to rights in OASIS specifications can be found at the OASIS website. Copies of claims of rights made available for publication and any assurances of licenses to be made available, or the result of an attempt made to obtain a general license or permission for the use of such proprietary rights by implementors or users of this specification, can be obtained from the OASIS Executive Director.
+
+OASIS invites any interested party to bring to its attention any copyrights, patents or patent applications, or other proprietary rights which may cover technology that may be required to implement this specification. Please address the information to the OASIS Executive Director.
+
+Copyright (C) OASIS Open (2005). All Rights Reserved.
+
+This document and translations of it may be copied and furnished to others, and derivative works that comment on or otherwise explain it or assist in its implementation may be prepared, copied, published and distributed, in whole or in part, without restriction of any kind, provided that the above copyright notice and this paragraph are included on all such copies and derivative works. However, this document itself may not be modified in any way, such as by removing the copyright notice or references to OASIS, except as needed for the purpose of developing OASIS specifications, in which case the procedures for copyrights defined in the OASIS Intellectual Property Rights document must be followed, or as required to translate it into languages other than English.
+
+The limited permissions granted above are perpetual and will not be revoked by OASIS or its successors or assigns.
+
+This document and the information contained herein is provided on an "AS IS" basis and OASIS DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+
+-->
+<xsd:schema
+ xmlns="http://www.w3.org/2001/XMLSchema"
+ xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:wsrf-bf="http://docs.oasis-open.org/wsrf/bf-2"
+ xmlns:wsrf-rp="http://docs.oasis-open.org/wsrf/rp-2"
+ xmlns:wsrf-sg="http://docs.oasis-open.org/wsrf/sg-2"
+ xmlns:wsa="http://www.w3.org/2005/08/addressing"
+ elementFormDefault="qualified"
+ attributeFormDefault="unqualified"
+ targetNamespace="http://docs.oasis-open.org/wsrf/sg-2" >
+<!-- ======================== Imports ============================ -->
+
+ <xsd:import
+ namespace="http://www.w3.org/2005/08/addressing"
+ schemaLocation="WS-Addressing-2005_08.xsd"/>
+ <xsd:import
+ namespace="http://docs.oasis-open.org/wsrf/bf-2"
+ schemaLocation="WS-BaseFaults-1_2.xsd" />
+ <xsd:import
+ namespace="http://docs.oasis-open.org/wsrf/rp-2"
+ schemaLocation="WS-ResourceProperties-1_2.xsd" />
+
+<!-- =============== Resource Property Related =================== -->
+<!-- ============ Resource Properties for ServiceGroup ============ -->
+ <xsd:simpleType name="AbsoluteOrRelativeTimeType">
+ <xsd:union memberTypes="xsd:dateTime xsd:duration"/>
+ </xsd:simpleType>
+
+ <xsd:simpleType name="ContentElementsType">
+ <xsd:list itemType="xsd:QName"/>
+ </xsd:simpleType>
+
+ <xsd:simpleType name="MemberInterfacesType">
+ <xsd:list itemType="xsd:QName"/>
+ </xsd:simpleType>
+
+ <xsd:element name="MembershipContentRule">
+ <xsd:complexType>
+ <xsd:attribute name="MemberInterfaces"
+ type="wsrf-sg:MemberInterfacesType"/>
+ <xsd:attribute name="ContentElements"
+ type="wsrf-sg:ContentElementsType"
+ use="required"/>
+ <xsd:anyAttribute namespace="##other"
+ processContents="lax"/>
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:complexType name="RPDocType">
+ <xsd:sequence>
+ <xsd:any namespace="##any" processContents="lax"
+ minOccurs="1" maxOccurs="1" />
+ </xsd:sequence>
+ <xsd:anyAttribute namespace="##other"
+ processContents="lax"/>
+ </xsd:complexType>
+
+ <xsd:complexType name="ContentType">
+ <xsd:sequence>
+ <xsd:element name="RPDoc"
+ type="wsrf-sg:RPDocType"
+ minOccurs="0" maxOccurs="1" />
+ </xsd:sequence>
+ <xsd:anyAttribute namespace="##other"
+ processContents="lax"/>
+ </xsd:complexType>
+
+ <xsd:complexType name="EntryType">
+ <xsd:sequence>
+ <xsd:element name="ServiceGroupEntryEPR"
+ type="wsa:EndpointReferenceType"
+ minOccurs="1" maxOccurs="1"
+ nillable="true"/>
+ <xsd:element name="MemberServiceEPR"
+ type="wsa:EndpointReferenceType"
+ minOccurs="0" maxOccurs="1"/>
+ <xsd:element ref="wsrf-sg:Content"
+ minOccurs="0" maxOccurs="1"/>
+ </xsd:sequence>
+ <xsd:anyAttribute namespace="##other" processContents="lax"/>
+ </xsd:complexType>
+
+<!-- ========== Resource Properties for ServiceGroupEntry ========= -->
+
+ <xsd:element name="Entry"
+ type="wsrf-sg:EntryType"/>
+
+ <xsd:element name="Content"
+ type="wsrf-sg:ContentType"/>
+
+ <xsd:element name="MemberEPR"
+ type="wsa:EndpointReferenceType"/>
+
+ <xsd:element name="ServiceGroupEPR"
+ type="wsa:EndpointReferenceType"/>
+
+<!-- =============== Resource Property Related =================== -->
+<!-- ============ Resource Properties for ServiceGroup ============ -->
+ <xsd:element name="ServiceGroupRP">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element ref="wsrf-rp:QueryExpressionDialect"
+ minOccurs="0" maxOccurs="unbounded"/>
+ <xsd:element ref="wsrf-sg:MembershipContentRule"
+ minOccurs="0" maxOccurs="unbounded"/>
+ <xsd:element ref="wsrf-sg:Entry"
+ minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+
+<!-- ========== Resource Properties for ServiceGroupEntry ========= -->
+ <xsd:element name="ServiceGroupEntryRP">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element ref="wsrf-sg:ServiceGroupEPR"
+ minOccurs="1" maxOccurs="1"/>
+ <xsd:element ref="wsrf-sg:MemberEPR"
+ minOccurs="0" maxOccurs="1"/>
+ <xsd:element ref="wsrf-sg:Content"
+ minOccurs="0" maxOccurs="1"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+
+<!-- ================= Message Specific Types ==================== -->
+<!-- ======== Message Types for ServiceGroupRegistration ========= -->
+ <xsd:element name="Add">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="MemberEPR"
+ type="wsa:EndpointReferenceType" />
+ <xsd:element ref="wsrf-sg:Content" />
+ <xsd:element name="InitialTerminationTime"
+ type="wsrf-sg:AbsoluteOrRelativeTimeType"
+ minOccurs="0" maxOccurs="1" />
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:element name="AddResponse">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="ServiceGroupEntryReference"
+ type="wsa:EndpointReferenceType"
+ minOccurs="1" maxOccurs="1" />
+ <xsd:element name="TerminationTime"
+ nillable="true"
+ type="xsd:dateTime"
+ minOccurs="1" maxOccurs="1" />
+ <xsd:element name="CurrentTime"
+ type="xsd:dateTime"
+ minOccurs="1" maxOccurs="1" />
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:complexType name="ContentCreationFailedFaultType">
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType"/>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:element name="ContentCreationFailedFault"
+ type="wsrf-sg:ContentCreationFailedFaultType"/>
+
+ <xsd:complexType name="UnsupportedMemberInterfaceFaultType">
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType"/>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:element name="UnsupportedMemberInterfaceFault"
+ type="wsrf-sg:UnsupportedMemberInterfaceFaultType"/>
+
+ <xsd:complexType name="AddRefusedFaultType">
+ <xsd:complexContent>
+ <xsd:extension base="wsrf-bf:BaseFaultType"/>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:element name="AddRefusedFault"
+ type="wsrf-sg:AddRefusedFaultType"/>
+
+<!-- = Messages Related to ServiceGroup Change Notification ======= -->
+ <xsd:complexType name="ServiceGroupModificationNotificationType">
+ <xsd:sequence>
+ <xsd:element name="ServiceGroupEntryEPR"
+ type="wsa:EndpointReferenceType"
+ minOccurs="1" maxOccurs="1"
+ nillable="true"/>
+ <xsd:element name="MemberServiceEPR"
+ type="wsa:EndpointReferenceType"
+ minOccurs="0" maxOccurs="1"/>
+ <xsd:element ref="wsrf-sg:Content"
+ minOccurs="0" maxOccurs="1"/>
+ </xsd:sequence>
+ </xsd:complexType>
+
+ <xsd:complexType name="ServiceGroupRemovalNotificationType">
+ <xsd:complexContent>
+ <xsd:extension
+ base="wsrf-sg:ServiceGroupModificationNotificationType">
+ <xsd:sequence>
+ <xsd:element name="Reason"
+ type="xsd:string"
+ minOccurs="0" maxOccurs="1"/>
+ </xsd:sequence>
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+
+ <xsd:element name="EntryAdditionNotification"
+ type="wsrf-sg:ServiceGroupModificationNotificationType" />
+
+ <xsd:element name="EntryRemovalNotification"
+ type="wsrf-sg:ServiceGroupRemovalNotificationType" />
+
+</xsd:schema>
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
new file mode 100644
index 0000000000..379382c18d
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/wsdl/WS-ServiceGroupEntry-1_2.wsdl
@@ -0,0 +1,206 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<wsdl:definitions
+ targetNamespace="http://docs.oasis-open.org/wsrf/sgw-2"
+ xmlns:tns="http://docs.oasis-open.org/wsrf/sgw-2"
+ xmlns:wsrf-sg="http://docs.oasis-open.org/wsrf/sg-2"
+ xmlns:wsrf-sgw="http://docs.oasis-open.org/wsrf/sgw-2"
+ xmlns="http://schemas.xmlsoap.org/wsdl/"
+ xmlns:wsa="http://www.w3.org/2005/08/addressing"
+ xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
+ xmlns:wsdl-soap="http://schemas.xmlsoap.org/wsdl/soap/"
+ xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ xmlns:wsx="http://schemas.xmlsoap.org/ws/2004/09/mex"
+ xmlns:wsrf-r="http://docs.oasis-open.org/wsrf/r-2"
+ xmlns:wsrf-rl="http://docs.oasis-open.org/wsrf/rl-2"
+ xmlns:wsrf-bf="http://docs.oasis-open.org/wsrf/bf-2"
+ xmlns:wsrf-rp="http://docs.oasis-open.org/wsrf/rp-2"
+ name="ServiceGroupEntry">
+ <wsdl:types>
+ <xsd:schema
+ elementFormDefault="qualified"
+ targetNamespace="http://schemas.xmlsoap.org/ws/2004/09/mex">
+ <xsd:include schemaLocation="WS-MetadataExchange-2004_09.xsd"/>
+ </xsd:schema>
+ <xsd:schema
+ elementFormDefault="qualified"
+ targetNamespace="http://docs.oasis-open.org/wsrf/rp-2">
+ <xsd:include schemaLocation="WS-ResourceProperties-1_2.xsd" />
+ </xsd:schema>
+ <xsd:schema
+ elementFormDefault="qualified"
+ targetNamespace="http://docs.oasis-open.org/wsrf/r-2">
+ <xsd:include schemaLocation="WS-Resource-1_2.xsd" />
+ </xsd:schema>
+ <xsd:schema
+ elementFormDefault="qualified"
+ targetNamespace="http://docs.oasis-open.org/wsrf/sg-2">
+ <xsd:include schemaLocation="WS-ServiceGroup-1_2.xsd" />
+ </xsd:schema>
+ </wsdl:types>
+ <wsdl:message name="GetMetadataMsg">
+ <wsdl:part name="GetMetadataMsg" element="wsx:GetMetadata" />
+ </wsdl:message>
+ <wsdl:message name="GetMetadataResponseMsg">
+ <wsdl:part name="GetMetadataResponseMsg" element="wsx:Metadata" />
+ </wsdl:message>
+ <wsdl:message name="ResourceUnknownFault">
+ <wsdl:part name="ResourceUnknownFault" element="wsrf-r:ResourceUnknownFault" />
+ </wsdl:message>
+ <wsdl:message name="ResourceUnavailableFault">
+ <wsdl:part name="ResourceUnavailableFault" element="wsrf-r:ResourceUnavailableFault" />
+ </wsdl:message>
+ <wsdl:message name="GetResourcePropertyDocumentRequest">
+ <wsdl:part name="GetResourcePropertyDocumentRequest" element="wsrf-rp:GetResourcePropertyDocument"/>
+ </wsdl:message>
+ <wsdl:message name="GetResourcePropertyDocumentResponse">
+ <wsdl:part name="GetResourcePropertyDocumentResponse" element="wsrf-rp:GetResourcePropertyDocumentResponse"/>
+ </wsdl:message>
+ <wsdl:message name="GetResourcePropertyRequest">
+ <wsdl:part name="GetResourcePropertyRequest" element="wsrf-rp:GetResourceProperty" />
+ </wsdl:message>
+ <wsdl:message name="GetResourcePropertyResponse">
+ <wsdl:part name="GetResourcePropertyResponse" element="wsrf-rp:GetResourcePropertyResponse" />
+ </wsdl:message>
+ <wsdl:message name="InvalidResourcePropertyQNameFault">
+ <wsdl:part name="InvalidResourcePropertyQNameFault" element="wsrf-rp:InvalidResourcePropertyQNameFault" />
+ </wsdl:message>
+ <wsdl:message name="GetMultipleResourcePropertiesRequest">
+ <wsdl:part name="GetMultipleResourcePropertiesRequest" element="wsrf-rp:GetMultipleResourceProperties" />
+ </wsdl:message>
+ <wsdl:message name="GetMultipleResourcePropertiesResponse">
+ <wsdl:part name="GetMultipleResourcePropertiesResponse" element="wsrf-rp:GetMultipleResourcePropertiesResponse" />
+ </wsdl:message>
+ <wsdl:portType
+ name="ServiceGroupEntryPortType"
+ wsrf-rp:ResourceProperties="wsrf-sg:ServiceGroupEntryRP">
+ <wsdl:operation name="GetMetadata">
+ <wsdl:input wsa:Action="http://schemas.xmlsoap.org/ws/2004/09/mex/GetMetadata"
+ name="GetMetadataMsg" message="tns:GetMetadataMsg"/>
+ <wsdl:output wsa:Action="http://schemas.xmlsoap.org/ws/2004/09/mex/GetMetadataResponse"
+ name="GetMetadataResponseMsg" message="tns:GetMetadataResponseMsg"/>
+ </wsdl:operation>
+ <wsdl:operation name="GetResourcePropertyDocument">
+ <wsdl:input wsa:Action="http://docs.oasis-open.org/wsrf/rpw-2/GetResourcePropertyDocument/GetResourcePropertyDocumentRequest"
+ name="GetResourcePropertyDocumentRequest" message="tns:GetResourcePropertyDocumentRequest"/>
+ <wsdl:output wsa:Action="http://docs.oasis-open.org/wsrf/rpw-2/GetResourcePropertyDocument/GetResourcePropertyDocumentResponse"
+ name="GetResourcePropertyDocumentResponse" message="tns:GetResourcePropertyDocumentResponse"/>
+ <wsdl:fault name="ResourceUnknownFault" message="tns:ResourceUnknownFault"/>
+ <wsdl:fault name="ResourceUnavailableFault" message="tns:ResourceUnavailableFault"/>
+ </wsdl:operation>
+ <wsdl:operation name="GetResourceProperty">
+ <wsdl:input wsa:Action="http://docs.oasis-open.org/wsrf/rpw-2/GetResourceProperty/GetResourcePropertyRequest"
+ name="GetResourcePropertyRequest" message="tns:GetResourcePropertyRequest" />
+ <wsdl:output wsa:Action="http://docs.oasis-open.org/wsrf/rpw-2/GetResourceProperty/GetResourcePropertyResponse"
+ name="GetResourcePropertyResponse" message="tns:GetResourcePropertyResponse" />
+ <wsdl:fault name="ResourceUnknownFault" message="tns:ResourceUnknownFault"/>
+ <wsdl:fault name="ResourceUnavailableFault" message="tns:ResourceUnavailableFault"/>
+ <wsdl:fault name="InvalidResourcePropertyQNameFault" message="tns:InvalidResourcePropertyQNameFault" />
+ </wsdl:operation>
+ <wsdl:operation name="GetMultipleResourceProperties">
+ <wsdl:input wsa:Action="http://docs.oasis-open.org/wsrf/rpw-2/GetMultipleResourceProperties/GetMultipleResourcePropertiesRequest"
+ name="GetMultipleResourcePropertiesRequest" message="tns:GetMultipleResourcePropertiesRequest" />
+ <wsdl:output wsa:Action="http://docs.oasis-open.org/wsrf/rpw-2/GetMultipleResourceProperties/GetMultipleResourcePropertiesResponse"
+ name="GetMultipleResourcePropertiesResponse" message="tns:GetMultipleResourcePropertiesResponse" />
+ <wsdl:fault name="ResourceUnknownFault" message="tns:ResourceUnknownFault"/>
+ <wsdl:fault name="ResourceUnavailableFault" message="tns:ResourceUnavailableFault"/>
+ <wsdl:fault name="InvalidResourcePropertyQNameFault" message="tns:InvalidResourcePropertyQNameFault" />
+ </wsdl:operation>
+ </wsdl:portType>
+ <wsdl:binding name="ServiceGroupEntryBinding" type="tns:ServiceGroupEntryPortType">
+ <wsdl-soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http" />
+ <wsdl:operation name="GetMetadata">
+ <wsdl-soap:operation soapAction="GetMetadata" />
+ <wsdl:input>
+ <wsdl-soap:body
+ use="encoded"
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
+ </wsdl:input>
+ <wsdl:output>
+ <wsdl-soap:body
+ use="encoded"
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
+ </wsdl:output>
+ </wsdl:operation>
+ <wsdl:operation name="GetResourcePropertyDocument">
+ <wsdl-soap:operation soapAction="GetResourcePropertyDocument"/>
+ <wsdl:input name="GetResourcePropertyDocumentRequest">
+ <wsdl-soap:body
+ use="encoded"
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+ </wsdl:input><wsdl:output name="GetResourcePropertyDocumentResponse">
+ <wsdl-soap:body
+ use="encoded"
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+ </wsdl:output>
+ <wsdl:fault name="ResourceUnknownFault">
+ <wsdl-soap:fault
+ use="encoded"
+ name="ResourceUnknownFault"/>
+ </wsdl:fault>
+ <wsdl:fault name="ResourceUnavailableFault">
+ <wsdl-soap:fault
+ use="encoded"
+ name="ResourceUnavailableFault"/>
+ </wsdl:fault>
+ </wsdl:operation>
+ <wsdl:operation name="GetResourceProperty">
+ <wsdl-soap:operation soapAction="GetResourceProperty"/>
+ <wsdl:input name="GetResourcePropertyRequest">
+ <wsdl-soap:body
+ use="encoded"
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+ </wsdl:input><wsdl:output name="GetResourcePropertyResponse">
+ <wsdl-soap:body
+ use="encoded"
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+ </wsdl:output>
+ <wsdl:fault name="ResourceUnknownFault">
+ <wsdl-soap:fault
+ use="encoded"
+ name="ResourceUnknownFault"/>
+ </wsdl:fault>
+ <wsdl:fault name="ResourceUnavailableFault">
+ <wsdl-soap:fault
+ use="encoded"
+ name="ResourceUnavailableFault"/>
+ </wsdl:fault>
+ <wsdl:fault name="InvalidResourcePropertyQNameFault">
+ <wsdl-soap:fault
+ use="encoded"
+ name="InvalidResourcePropertyQNameFault"/>
+ </wsdl:fault>
+ </wsdl:operation>
+ <wsdl:operation name="GetMultipleResourceProperties">
+ <wsdl-soap:operation soapAction="GetMultipleResourceProperties"/>
+ <wsdl:input name="GetMultipleResourcePropertiesRequest">
+ <wsdl-soap:body
+ use="encoded"
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+ </wsdl:input><wsdl:output name="GetMultipleResourcePropertiesResponse">
+ <wsdl-soap:body
+ use="encoded"
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+ </wsdl:output>
+ <wsdl:fault name="ResourceUnknownFault">
+ <wsdl-soap:fault
+ use="encoded"
+ name="ResourceUnknownFault"/>
+ </wsdl:fault>
+ <wsdl:fault name="ResourceUnavailableFault">
+ <wsdl-soap:fault
+ use="encoded"
+ name="ResourceUnavailableFault"/>
+ </wsdl:fault>
+ <wsdl:fault name="InvalidResourcePropertyQNameFault">
+ <wsdl-soap:fault
+ use="encoded"
+ name="InvalidResourcePropertyQNameFault"/>
+ </wsdl:fault>
+ </wsdl:operation>
+ </wsdl:binding>
+ <wsdl:service name="ServiceGroupEntryService">
+ <wsdl:port name="ServiceGroupEntryPort" binding="tns:ServiceGroupEntryBinding">
+ <wsdl-soap:address location="http://localhost:8080/wsrf/services/ServiceGroupEntry"/>
+ </wsdl:port>
+ </wsdl:service>
+</wsdl:definitions>
diff --git a/qpid/java/management/client/src/main/java/wsdl/WS-Topics-1_3.xsd b/qpid/java/management/client/src/main/java/wsdl/WS-Topics-1_3.xsd
new file mode 100644
index 0000000000..df98513131
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/wsdl/WS-Topics-1_3.xsd
@@ -0,0 +1,185 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+OASIS takes no position regarding the validity or scope of any intellectual property or other rights that might be claimed to pertain to the implementation or use of the technology described in this document or the extent to which any license under such rights might or might not be available; neither does it represent that it has made any effort to identify any such rights. Information on OASIS's procedures with respect to rights in OASIS specifications can be found at the OASIS website. Copies of claims of rights made available for publication and any assurances of licenses to be made available, or the result of an attempt made to obtain a general license or permission for the use of such proprietary rights by implementors or users of this specification, can be obtained from the OASIS Executive Director.
+
+OASIS invites any interested party to bring to its attention any copyrights, patents or patent applications, or other proprietary rights which may cover technology that may be required to implement this specification. Please address the information to the OASIS Executive Director.
+
+Copyright (C) OASIS Open (2004-2005). All Rights Reserved.
+
+This document and translations of it may be copied and furnished to others, and derivative works that comment on or otherwise explain it or assist in its implementation may be prepared, copied, published and distributed, in whole or in part, without restriction of any kind, provided that the above copyright notice and this paragraph are included on all such copies and derivative works. However, this document itself may not be modified in any way, such as by removing the copyright notice or references to OASIS, except as needed for the purpose of developing OASIS specifications, in which case the procedures for copyrights defined in the OASIS Intellectual Property Rights document must be followed, or as required to translate it into languages other than English.
+
+The limited permissions granted above are perpetual and will not be revoked by OASIS or its successors or assigns.
+
+This document and the information contained herein is provided on an "AS IS" basis and OASIS DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+
+-->
+
+
+<xsd:schema
+ xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ xmlns:wstop = "http://docs.oasis-open.org/wsn/t-1"
+ targetNamespace = "http://docs.oasis-open.org/wsn/t-1"
+ elementFormDefault="qualified" attributeFormDefault="unqualified">
+
+<!-- =============== utility type definitions ==================== -->
+ <xsd:complexType name="Documentation" mixed="true">
+ <xsd:sequence>
+ <xsd:any processContents="lax" minOccurs="0"
+ maxOccurs="unbounded" namespace="##any"/>
+ </xsd:sequence>
+ </xsd:complexType>
+
+ <xsd:complexType name="ExtensibleDocumented" abstract="true"
+ mixed="false">
+ <xsd:sequence>
+ <xsd:element name="documentation" type="wstop:Documentation"
+ minOccurs="0" />
+ </xsd:sequence>
+ <xsd:anyAttribute namespace="##other" processContents="lax" />
+</xsd:complexType>
+
+<xsd:complexType name="QueryExpressionType" mixed="true">
+ <xsd:sequence>
+ <xsd:any minOccurs="0" maxOccurs="1" processContents="lax" />
+ </xsd:sequence>
+ <xsd:attribute name="Dialect" type="xsd:anyURI" use="required"/>
+</xsd:complexType>
+
+<!-- ================== Topic-Namespace Related ================ -->
+ <xsd:complexType name="TopicNamespaceType">
+ <xsd:complexContent>
+ <xsd:extension base="wstop:ExtensibleDocumented">
+ <xsd:sequence>
+ <xsd:element name="Topic"
+ minOccurs="0" maxOccurs="unbounded">
+ <xsd:complexType>
+ <xsd:complexContent>
+ <xsd:extension base="wstop:TopicType">
+ <xsd:attribute name="parent" type="wstop:ConcreteTopicExpression" />
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:any namespace="##other"
+ minOccurs="0" maxOccurs="unbounded"
+ processContents="lax"/>
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:NCName"/>
+ <xsd:attribute name="targetNamespace" type="xsd:anyURI"
+ use="required"/>
+ <xsd:attribute name="final" type="xsd:boolean"
+ default="false"/>
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+
+ <xsd:element name="TopicNamespace" type="wstop:TopicNamespaceType">
+ <xsd:unique name="rootTopicUniqueness">
+ <xsd:selector xpath="wstop:Topic"/>
+ <xsd:field xpath="@name"/>
+ </xsd:unique>
+ </xsd:element>
+
+ <xsd:attribute name="topicNamespaceLocation" type="xsd:anyURI"/>
+
+
+
+<!-- ===================== Topic Related ========================= -->
+
+ <xsd:complexType name="TopicType">
+ <xsd:complexContent>
+ <xsd:extension base="wstop:ExtensibleDocumented">
+ <xsd:sequence>
+ <xsd:element name="MessagePattern"
+ type="wstop:QueryExpressionType"
+ minOccurs="0" maxOccurs="1" />
+ <xsd:element name="Topic" type="wstop:TopicType"
+ minOccurs="0" maxOccurs="unbounded">
+ <xsd:unique name="childTopicUniqueness">
+ <xsd:selector xpath="wstop:topic"/>
+ <xsd:field xpath="@name"/>
+ </xsd:unique>
+ </xsd:element>
+ <xsd:any namespace="##other" minOccurs="0"
+ maxOccurs="unbounded"/>
+ </xsd:sequence>
+ <xsd:attribute name="name" use="required" type="xsd:NCName"/>
+ <xsd:attribute name="messageTypes">
+ <xsd:simpleType>
+ <xsd:list itemType="xsd:QName"/>
+ </xsd:simpleType>
+ </xsd:attribute>
+ <xsd:attribute name="final" type="xsd:boolean"
+ default="false"/>
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+
+<!-- ================ Topic Set Related =================== -->
+
+ <xsd:complexType name="TopicSetType">
+ <xsd:complexContent>
+ <xsd:extension base="wstop:ExtensibleDocumented">
+ <xsd:sequence>
+ <xsd:any namespace="##other"
+ minOccurs="0" maxOccurs="unbounded"
+ processContents="lax"/>
+ </xsd:sequence>
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+
+ <xsd:element name="TopicSet" type="wstop:TopicSetType"/>
+<xsd:attribute name="topic" type="xsd:boolean" default="false"/>
+
+<!-- ================ Topic Expression Related =================== -->
+
+ <xsd:simpleType name="FullTopicExpression">
+ <xsd:restriction base="xsd:token">
+ <xsd:annotation>
+ <xsd:documentation>
+ TopicPathExpression ::= TopicPath ( '|' TopicPath )*
+ TopicPath ::= RootTopic ChildTopicExpression*
+ RootTopic ::= NamespacePrefix? ('//')? (NCName | '*')
+ NamespacePrefix ::= NCName ':'
+ ChildTopicExpression ::= '/' '/'? (QName | NCName | '*'| '.')
+
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:pattern value=
+ "([\i-[:]][\c-[:]]*:)?(//)?([\i-[:]][\c-[:]]*|\*)((/|//)(([\i-[:]][\c-[:]]*:)?[\i-[:]][\c-[:]]*|\*|[.]))*(\|([\i-[:]][\c-[:]]*:)?(//)?([\i-[:]][\c-[:]]*|\*)((/|//)(([\i-[:]][\c-[:]]*:)?[\i-[:]][\c-[:]]*|\*|[.]))*)*">
+ </xsd:pattern>
+ </xsd:restriction>
+ </xsd:simpleType>
+
+ <xsd:simpleType name="ConcreteTopicExpression">
+ <xsd:restriction base="xsd:token">
+ <xsd:annotation>
+ <xsd:documentation>
+ The pattern allows strings matching the following EBNF:
+ ConcreteTopicPath ::= RootTopic ChildTopic*
+ RootTopic ::= QName
+ ChildTopic ::= '/' (QName | NCName)
+
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:pattern value=
+"(([\i-[:]][\c-[:]]*:)?[\i-[:]][\c-[:]]*)(/([\i-[:]][\c-[:]]*:)?[\i-[:]][\c-[:]]*)*" >
+ </xsd:pattern>
+ </xsd:restriction>
+ </xsd:simpleType>
+
+ <xsd:simpleType name="SimpleTopicExpression">
+ <xsd:restriction base="xsd:QName">
+ <xsd:annotation>
+ <xsd:documentation>
+ The pattern allows strings matching the following EBNF:
+ RootTopic ::= QName
+
+ </xsd:documentation>
+ </xsd:annotation>
+ </xsd:restriction>
+ </xsd:simpleType>
+
+</xsd:schema> \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/wsdl/WSDM-MUWS-Part1-1_1.xsd b/qpid/java/management/client/src/main/java/wsdl/WSDM-MUWS-Part1-1_1.xsd
new file mode 100644
index 0000000000..c24e97a9ce
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/wsdl/WSDM-MUWS-Part1-1_1.xsd
@@ -0,0 +1,114 @@
+<?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.
+
+-->
+
+<xs:schema
+ targetNamespace="http://docs.oasis-open.org/wsdm/muws1-2.xsd"
+ xmlns:muws1="http://docs.oasis-open.org/wsdm/muws1-2.xsd"
+ xmlns:wsa="http://www.w3.org/2005/08/addressing"
+ xmlns:xs="http://www.w3.org/2001/XMLSchema"
+ elementFormDefault="qualified" attributeFormDefault="unqualified">
+
+ <xs:import namespace="http://www.w3.org/2005/08/addressing"
+ schemaLocation="WS-Addressing-2005_08.xsd"/>
+
+
+ <xs:element name="ResourceId" type="xs:anyURI"/>
+ <xs:element name="ManageabilityCapability" type="xs:anyURI"/>
+
+
+ <xs:complexType name="CorrelatablePropertiesType">
+ <xs:sequence>
+ <xs:any minOccurs="0" maxOccurs="unbounded"
+ namespace="##other" processContents="lax"/>
+ </xs:sequence>
+ <xs:attribute name="Dialect" type="xs:anyURI"/>
+ <xs:attribute name="NegativeAssertionPossible" type="xs:boolean"/>
+ <xs:anyAttribute namespace="##other"/>
+ </xs:complexType>
+
+ <xs:element name="CorrelatableProperties"
+ type="muws1:CorrelatablePropertiesType"/>
+
+
+ <xs:complexType name="ComponentAddressType">
+ <xs:sequence>
+ <xs:any namespace="##any" processContents="lax"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="ComponentType">
+ <xs:sequence>
+ <xs:element name="ResourceId" type="xs:anyURI"
+ minOccurs="0"/>
+ <xs:element name="ComponentAddress"
+ type="muws1:ComponentAddressType"
+ minOccurs="0" maxOccurs="unbounded"/>
+ <xs:any minOccurs="0" maxOccurs="unbounded"
+ namespace="##other" processContents="lax"/>
+ </xs:sequence>
+ <xs:anyAttribute namespace="##other"/>
+ </xs:complexType>
+
+
+ <xs:complexType name="ManagementEventType">
+ <xs:sequence>
+ <xs:element name="EventId" type="xs:anyURI"/>
+ <xs:element name="SourceComponent" type="muws1:ComponentType"/>
+ <xs:element name="ReporterComponent" type="muws1:ComponentType"
+ minOccurs="0"/>
+ <xs:any minOccurs="0" maxOccurs="unbounded"
+ namespace="##other" processContents="lax"/>
+ </xs:sequence>
+ <xs:attribute name="ReportTime" type="xs:dateTime" use="optional"/>
+ <xs:anyAttribute namespace="##other"/>
+ </xs:complexType>
+
+ <xs:element name="ManagementEvent"
+ type="muws1:ManagementEventType"/>
+
+ <xs:element name="ManageabilityEndpointReference"
+ type="wsa:EndpointReferenceType"/>
+
+
+<!--
+ SCHEMA COPY Material
+Copy and paste element references below into the schema of a resource properties document.
+These references are provide to insure that the correct minOccurs/maxOccurs attributes are specified in a resource property document schema.
+
+NOTE: You must import the MUWS Part 1 schema namespace (MUWS1).
+
+ ** Identity Properties **
+ <xs:element ref="muws1:ResourceId"/>
+
+
+ ** ManageabilityCharacteristics Properties **
+ <xs:element ref="muws1:ManageabilityCapability"
+ minOccurs="0" maxOccurs="unbounded"/>
+
+ ** Correlatable Properties **
+ <xs:element ref="muws1:CorrelatableProperties"
+ minOccurs="0" maxOccurs="unbounded"/>
+
+-->
+
+</xs:schema>
+
diff --git a/qpid/java/management/client/src/main/java/wsdl/WSDM-MUWS-Part2-1_1.xsd b/qpid/java/management/client/src/main/java/wsdl/WSDM-MUWS-Part2-1_1.xsd
new file mode 100644
index 0000000000..5ea0954734
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/wsdl/WSDM-MUWS-Part2-1_1.xsd
@@ -0,0 +1,677 @@
+<?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.
+
+-->
+
+<xs:schema targetNamespace="http://docs.oasis-open.org/wsdm/muws2-2.xsd"
+ xmlns:muws2="http://docs.oasis-open.org/wsdm/muws2-2.xsd"
+ xmlns:muws1="http://docs.oasis-open.org/wsdm/muws1-2.xsd"
+ xmlns:wsa="http://www.w3.org/2005/08/addressing"
+ xmlns:xs="http://www.w3.org/2001/XMLSchema"
+ elementFormDefault="qualified" attributeFormDefault="unqualified">
+ <xs:import namespace="http://docs.oasis-open.org/wsdm/muws1-2.xsd"
+ schemaLocation="WSDM-MUWS-Part1-1_1.xsd" />
+ <xs:import namespace="http://www.w3.org/2005/08/addressing"
+ schemaLocation="WS-Addressing-2005_08.xsd" />
+ <xs:import namespace="http://www.w3.org/XML/1998/namespace"
+ schemaLocation="XML-Namespace-1998.xsd" />
+ <xs:complexType name="LangString">
+ <xs:simpleContent>
+ <xs:extension base="xs:string">
+ <xs:attribute ref="xml:lang" use="required" />
+ <xs:anyAttribute namespace="##other" />
+ </xs:extension>
+ </xs:simpleContent>
+ </xs:complexType>
+ <!-- Begin properties for the Description capability -->
+ <xs:element name="Caption" type="muws2:LangString" />
+ <xs:element name="Description" type="muws2:LangString" />
+ <xs:element name="Version" type="xs:string" />
+ <!-- End properties for the Description capability -->
+ <xs:complexType name="CategoryType">
+ <xs:sequence>
+ <xs:any minOccurs="0" namespace="##any"
+ processContents="lax" />
+ </xs:sequence>
+ </xs:complexType>
+ <xs:complexType name="StateType">
+ <xs:complexContent>
+ <xs:extension base="muws2:CategoryType" />
+ </xs:complexContent>
+ </xs:complexType>
+ <xs:element name="State" type="muws2:StateType" />
+ <xs:element name="EnteredState" type="muws2:StateType" />
+ <xs:element name="PreviousState" type="muws2:StateType" />
+ <xs:complexType name="StateTransitionType">
+ <xs:sequence>
+ <xs:element ref="muws2:EnteredState" />
+ <xs:element ref="muws2:PreviousState" minOccurs="0" />
+ <xs:any minOccurs="0" maxOccurs="unbounded"
+ namespace="##other" processContents="lax" />
+ </xs:sequence>
+ <xs:attribute name="TransitionIdentifier" type="xs:anyURI"
+ use="optional" />
+ <xs:attribute name="Time" type="xs:dateTime" use="required" />
+ <xs:anyAttribute namespace="##other" />
+ </xs:complexType>
+ <xs:element name="StateTransition" type="muws2:StateTransitionType" />
+ <!-- Begin properties for the OperationalStatus capability -->
+ <xs:element name="OperationalStatus">
+ <xs:simpleType>
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="Available" />
+ <xs:enumeration value="PartiallyAvailable" />
+ <xs:enumeration value="Unavailable" />
+ <xs:enumeration value="Unknown" />
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:element>
+ <!-- End properties for the OperationalStatus capability -->
+ <xs:attributeGroup name="MetricAttributes">
+ <xs:attribute name="ResetAt" type="xs:dateTime" />
+ <xs:attribute name="LastUpdated" type="xs:dateTime" />
+ <xs:attribute name="Duration" type="xs:duration" />
+ </xs:attributeGroup>
+ <!-- Begin properties for the Metrics capability -->
+ <xs:element name="CurrentTime" type="xs:dateTime" />
+ <!-- End properties for the Metrics capability -->
+ <xs:complexType name="RelationshipTypeType">
+ <xs:complexContent>
+ <xs:extension base="muws2:CategoryType" />
+ </xs:complexContent>
+ </xs:complexType>
+ <xs:element name="Self">
+ <xs:complexType />
+ </xs:element>
+ <xs:complexType name="RelationshipParticipantType">
+ <xs:sequence>
+ <xs:element ref="muws2:Self" minOccurs="0" />
+ <xs:element ref="muws1:ManageabilityEndpointReference"
+ minOccurs="0" maxOccurs="unbounded" />
+ <xs:element ref="wsa:EndpointReference" minOccurs="0"
+ maxOccurs="unbounded" />
+ <xs:element ref="muws1:ResourceId" minOccurs="0" />
+ <xs:element name="Role" type="xs:anyURI" />
+ <xs:any minOccurs="0" maxOccurs="unbounded"
+ namespace="##other" processContents="lax" />
+ </xs:sequence>
+ <xs:anyAttribute namespace="##other" />
+ </xs:complexType>
+ <!-- Begin properties for the RelationshipResource capability -->
+ <xs:element name="Name" type="xs:string" />
+ <xs:element name="Type" type="muws2:RelationshipTypeType" />
+ <xs:element name="Participant"
+ type="muws2:RelationshipParticipantType" />
+ <!-- End properties for the RelationshipResource capability -->
+ <xs:complexType name="RelationshipType">
+ <xs:sequence>
+ <xs:element ref="muws2:Name" minOccurs="0" />
+ <xs:element ref="muws2:Type" />
+ <xs:element ref="muws2:Participant" minOccurs="2"
+ maxOccurs="unbounded" />
+ <xs:element name="AccessEndpointReference"
+ type="wsa:EndpointReferenceType" minOccurs="0" />
+ <xs:any minOccurs="0" maxOccurs="unbounded"
+ namespace="##other" processContents="lax" />
+ </xs:sequence>
+ <xs:anyAttribute namespace="##other" />
+ </xs:complexType>
+ <!-- Begin properties for the Relationship capability -->
+ <xs:element name="Relationship" type="muws2:RelationshipType" />
+ <!-- End properties for the Relationship capability -->
+ <xs:element name="RelationshipCreatedNotification">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element ref="muws2:Relationship" />
+ <xs:any minOccurs="0" maxOccurs="unbounded"
+ namespace="##other" processContents="lax" />
+ </xs:sequence>
+ <xs:anyAttribute namespace="##other" />
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="RelationshipDeletedNotification">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element ref="muws2:Relationship" />
+ <xs:any minOccurs="0" maxOccurs="unbounded"
+ namespace="##other" processContents="lax" />
+ </xs:sequence>
+ <xs:anyAttribute namespace="##other" />
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="QueryRelationshipsByType">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element name="RequestedType" type="xs:QName" />
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="QueryRelationshipsByTypeResponse">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element ref="muws2:Relationship" minOccurs="0"
+ maxOccurs="unbounded" />
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="CreationNotification">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element ref="muws1:ManageabilityEndpointReference"
+ minOccurs="0" maxOccurs="unbounded" />
+ </xs:sequence>
+ <xs:anyAttribute namespace="##other" />
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="DestructionNotification">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element ref="muws1:ResourceId" minOccurs="0" />
+ </xs:sequence>
+ <xs:anyAttribute namespace="##other" />
+ </xs:complexType>
+ </xs:element>
+ <xs:complexType name="SituationCategoryType">
+ <xs:complexContent>
+ <xs:extension base="muws2:CategoryType" />
+ </xs:complexContent>
+ </xs:complexType>
+ <xs:complexType name="SubstitutableMsgType">
+ <xs:sequence>
+ <xs:element name="Value" type="xs:anySimpleType"
+ minOccurs="0" maxOccurs="unbounded" />
+ </xs:sequence>
+ <xs:attribute name="MsgId" type="xs:string" use="required" />
+ <xs:attribute name="MsgIdType" type="xs:anyURI" use="required" />
+ </xs:complexType>
+ <xs:complexType name="SituationType">
+ <xs:sequence>
+ <xs:element name="SituationCategory"
+ type="muws2:SituationCategoryType" />
+ <xs:element name="SuccessDisposition" minOccurs="0">
+ <xs:simpleType>
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="Successful" />
+ <xs:enumeration value="Unsuccessful" />
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:element>
+ <xs:element name="SituationTime" type="xs:dateTime" />
+ <xs:element name="Priority" type="xs:short" minOccurs="0" />
+ <xs:element name="Severity" type="xs:short" minOccurs="0" />
+ <xs:element name="Message" type="muws2:LangString"
+ minOccurs="0" />
+ <xs:element name="SubstitutableMsg"
+ type="muws2:SubstitutableMsgType" minOccurs="0" />
+ </xs:sequence>
+ </xs:complexType>
+ <xs:element name="Situation" type="muws2:SituationType" />
+ <xs:complexType name="EventCorrelationPropertiesType">
+ <xs:sequence>
+ <xs:element name="repeatCount" minOccurs="0"
+ maxOccurs="1">
+ <xs:simpleType>
+ <xs:restriction base="xs:short">
+ <xs:minInclusive value="0" />
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:element>
+ <xs:element name="elapsedTime" minOccurs="0"
+ maxOccurs="1">
+ <xs:simpleType>
+ <xs:restriction base="xs:long">
+ <xs:minInclusive value="0" />
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:element>
+ </xs:sequence>
+ <xs:attribute name="sequenceNumber" type="xs:unsignedLong" />
+ </xs:complexType>
+ <xs:element name="EventCorrelationProperties"
+ type="muws2:EventCorrelationPropertiesType" />
+ <xs:complexType name="MsgCatalogInformationType">
+ <xs:sequence>
+ <xs:element name="msgCatalog" type="xs:anyURI"
+ minOccurs="1" />
+ <xs:element name="msgCatalogType" type="xs:anyURI"
+ minOccurs="0" />
+ </xs:sequence>
+ </xs:complexType>
+ <xs:element name="MsgCatalogInformation"
+ type="muws2:MsgCatalogInformationType" />
+ <!-- ##### Metadata description elements ##### -->
+ <xs:element name="Capability" type="xs:anyURI" />
+ <xs:complexType name="DialectableExpressionType" mixed="true">
+ <xs:sequence>
+ <xs:any namespace="##other" processContents="lax"
+ minOccurs="0" maxOccurs="unbounded" />
+ </xs:sequence>
+ <xs:attribute name="Dialect" type="xs:anyURI" use="required" />
+ <xs:anyAttribute namespace="##other" />
+ </xs:complexType>
+ <xs:element name="ValidWhile"
+ type="muws2:DialectableExpressionType" />
+ <xs:element name="Units" type="xs:string" />
+ <xs:element name="ChangeType">
+ <xs:simpleType>
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="Counter" />
+ <xs:enumeration value="Gauge" />
+ <xs:enumeration value="Unknown" />
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:element>
+ <xs:element name="TimeScope">
+ <xs:simpleType>
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="Interval" />
+ <xs:enumeration value="PointInTime" />
+ <xs:enumeration value="SinceReset" />
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:element>
+ <xs:element name="GatheringTime">
+ <xs:simpleType>
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="OnChange" />
+ <xs:enumeration value="Periodic" />
+ <xs:enumeration value="OnDemand" />
+ <xs:enumeration value="Unknown" />
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:element>
+ <xs:element name="CalculationInterval" type="xs:duration" />
+ <xs:element name="MetricGroup" type="xs:anyURI" />
+ <xs:element name="PostCondition"
+ type="muws2:DialectableExpressionType" />
+ <!-- ========= StartSituation ============ -->
+ <xs:element name="StartSituation">
+ <xs:complexType>
+ <xs:complexContent>
+ <xs:restriction base="muws2:SituationCategoryType" />
+ </xs:complexContent>
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="StartInitiated">
+ <xs:complexType>
+ <xs:complexContent>
+ <xs:restriction base="muws2:SituationCategoryType">
+ <xs:sequence>
+ <xs:element ref="muws2:StartSituation" />
+ </xs:sequence>
+ </xs:restriction>
+ </xs:complexContent>
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="RestartInitiated">
+ <xs:complexType>
+ <xs:complexContent>
+ <xs:restriction base="muws2:SituationCategoryType">
+ <xs:sequence>
+ <xs:element ref="muws2:StartSituation" />
+ </xs:sequence>
+ </xs:restriction>
+ </xs:complexContent>
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="StartCompleted">
+ <xs:complexType>
+ <xs:complexContent>
+ <xs:restriction base="muws2:SituationCategoryType">
+ <xs:sequence>
+ <xs:element ref="muws2:StartSituation" />
+ </xs:sequence>
+ </xs:restriction>
+ </xs:complexContent>
+ </xs:complexType>
+ </xs:element>
+ <!-- ========= StopSituation ============ -->
+ <xs:element name="StopSituation">
+ <xs:complexType>
+ <xs:complexContent>
+ <xs:restriction base="muws2:SituationCategoryType" />
+ </xs:complexContent>
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="StopInitiated">
+ <xs:complexType>
+ <xs:complexContent>
+ <xs:restriction base="muws2:SituationCategoryType">
+ <xs:sequence>
+ <xs:element ref="muws2:StopSituation" />
+ </xs:sequence>
+ </xs:restriction>
+ </xs:complexContent>
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="AbortInitiated">
+ <xs:complexType>
+ <xs:complexContent>
+ <xs:restriction base="muws2:SituationCategoryType">
+ <xs:sequence>
+ <xs:element ref="muws2:StopSituation" />
+ </xs:sequence>
+ </xs:restriction>
+ </xs:complexContent>
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="PauseInitiated">
+ <xs:complexType>
+ <xs:complexContent>
+ <xs:restriction base="muws2:SituationCategoryType">
+ <xs:sequence>
+ <xs:element ref="muws2:StopSituation" />
+ </xs:sequence>
+ </xs:restriction>
+ </xs:complexContent>
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="StopCompleted">
+ <xs:complexType>
+ <xs:complexContent>
+ <xs:restriction base="muws2:SituationCategoryType">
+ <xs:sequence>
+ <xs:element ref="muws2:StopSituation" />
+ </xs:sequence>
+ </xs:restriction>
+ </xs:complexContent>
+ </xs:complexType>
+ </xs:element>
+ <!-- ========= RequestSituation ============ -->
+ <xs:element name="RequestSituation">
+ <xs:complexType>
+ <xs:complexContent>
+ <xs:restriction base="muws2:SituationCategoryType" />
+ </xs:complexContent>
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="RequestInitiated">
+ <xs:complexType>
+ <xs:complexContent>
+ <xs:restriction base="muws2:SituationCategoryType">
+ <xs:sequence>
+ <xs:element ref="muws2:RequestSituation" />
+ </xs:sequence>
+ </xs:restriction>
+ </xs:complexContent>
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="RequestCompleted">
+ <xs:complexType>
+ <xs:complexContent>
+ <xs:restriction base="muws2:SituationCategoryType">
+ <xs:sequence>
+ <xs:element ref="muws2:RequestSituation" />
+ </xs:sequence>
+ </xs:restriction>
+ </xs:complexContent>
+ </xs:complexType>
+ </xs:element>
+ <!-- ========= DestroySituation ============ -->
+ <xs:element name="DestroySituation">
+ <xs:complexType>
+ <xs:complexContent>
+ <xs:restriction base="muws2:SituationCategoryType" />
+ </xs:complexContent>
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="DestroyInitiated">
+ <xs:complexType>
+ <xs:complexContent>
+ <xs:restriction base="muws2:SituationCategoryType">
+ <xs:sequence>
+ <xs:element ref="muws2:DestroySituation" />
+ </xs:sequence>
+ </xs:restriction>
+ </xs:complexContent>
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="DestroyCompleted">
+ <xs:complexType>
+ <xs:complexContent>
+ <xs:restriction base="muws2:SituationCategoryType">
+ <xs:sequence>
+ <xs:element ref="muws2:DestroySituation" />
+ </xs:sequence>
+ </xs:restriction>
+ </xs:complexContent>
+ </xs:complexType>
+ </xs:element>
+ <!-- ========= CreateSituation ============ -->
+ <xs:element name="CreateSituation">
+ <xs:complexType>
+ <xs:complexContent>
+ <xs:restriction base="muws2:SituationCategoryType" />
+ </xs:complexContent>
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="CreateInitiated">
+ <xs:complexType>
+ <xs:complexContent>
+ <xs:restriction base="muws2:SituationCategoryType">
+ <xs:sequence>
+ <xs:element ref="muws2:CreateSituation" />
+ </xs:sequence>
+ </xs:restriction>
+ </xs:complexContent>
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="CreateCompleted">
+ <xs:complexType>
+ <xs:complexContent>
+ <xs:restriction base="muws2:SituationCategoryType">
+ <xs:sequence>
+ <xs:element ref="muws2:CreateSituation" />
+ </xs:sequence>
+ </xs:restriction>
+ </xs:complexContent>
+ </xs:complexType>
+ </xs:element>
+ <!-- ========= ConnectSituation ============ -->
+ <xs:element name="ConnectSituation">
+ <xs:complexType>
+ <xs:complexContent>
+ <xs:restriction base="muws2:SituationCategoryType" />
+ </xs:complexContent>
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="ConnectInitiated">
+ <xs:complexType>
+ <xs:complexContent>
+ <xs:restriction base="muws2:SituationCategoryType">
+ <xs:sequence>
+ <xs:element ref="muws2:ConnectSituation" />
+ </xs:sequence>
+ </xs:restriction>
+ </xs:complexContent>
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="ReconnectInitiated">
+ <xs:complexType>
+ <xs:complexContent>
+ <xs:restriction base="muws2:SituationCategoryType">
+ <xs:sequence>
+ <xs:element ref="muws2:ConnectSituation" />
+ </xs:sequence>
+ </xs:restriction>
+ </xs:complexContent>
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="ConnectCompleted">
+ <xs:complexType>
+ <xs:complexContent>
+ <xs:restriction base="muws2:SituationCategoryType">
+ <xs:sequence>
+ <xs:element ref="muws2:ConnectSituation" />
+ </xs:sequence>
+ </xs:restriction>
+ </xs:complexContent>
+ </xs:complexType>
+ </xs:element>
+ <!-- ========= ReportSituation ============ -->
+ <xs:element name="ReportSituation">
+ <xs:complexType>
+ <xs:complexContent>
+ <xs:restriction base="muws2:SituationCategoryType" />
+ </xs:complexContent>
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="PerformanceReport">
+ <xs:complexType>
+ <xs:complexContent>
+ <xs:restriction base="muws2:SituationCategoryType">
+ <xs:sequence>
+ <xs:element ref="muws2:ReportSituation" />
+ </xs:sequence>
+ </xs:restriction>
+ </xs:complexContent>
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="SecurityReport">
+ <xs:complexType>
+ <xs:complexContent>
+ <xs:restriction base="muws2:SituationCategoryType">
+ <xs:sequence>
+ <xs:element ref="muws2:ReportSituation" />
+ </xs:sequence>
+ </xs:restriction>
+ </xs:complexContent>
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="HeartbeatReport">
+ <xs:complexType>
+ <xs:complexContent>
+ <xs:restriction base="muws2:SituationCategoryType">
+ <xs:sequence>
+ <xs:element ref="muws2:ReportSituation" />
+ </xs:sequence>
+ </xs:restriction>
+ </xs:complexContent>
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="StatusReport">
+ <xs:complexType>
+ <xs:complexContent>
+ <xs:restriction base="muws2:SituationCategoryType">
+ <xs:sequence>
+ <xs:element ref="muws2:ReportSituation" />
+ </xs:sequence>
+ </xs:restriction>
+ </xs:complexContent>
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="TraceReport">
+ <xs:complexType>
+ <xs:complexContent>
+ <xs:restriction base="muws2:SituationCategoryType">
+ <xs:sequence>
+ <xs:element ref="muws2:ReportSituation" />
+ </xs:sequence>
+ </xs:restriction>
+ </xs:complexContent>
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="DebugReport">
+ <xs:complexType>
+ <xs:complexContent>
+ <xs:restriction base="muws2:SituationCategoryType">
+ <xs:sequence>
+ <xs:element ref="muws2:ReportSituation" />
+ </xs:sequence>
+ </xs:restriction>
+ </xs:complexContent>
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="LogReport">
+ <xs:complexType>
+ <xs:complexContent>
+ <xs:restriction base="muws2:SituationCategoryType">
+ <xs:sequence>
+ <xs:element ref="muws2:ReportSituation" />
+ </xs:sequence>
+ </xs:restriction>
+ </xs:complexContent>
+ </xs:complexType>
+ </xs:element>
+ <!-- ========= AvailabilitySituation ============ -->
+ <xs:element name="AvailabilitySituation">
+ <xs:complexType>
+ <xs:complexContent>
+ <xs:restriction base="muws2:SituationCategoryType" />
+ </xs:complexContent>
+ </xs:complexType>
+ </xs:element>
+ <!-- ========= CapabilitySituation ============ -->
+ <xs:element name="CapabilitySituation">
+ <xs:complexType>
+ <xs:complexContent>
+ <xs:restriction base="muws2:SituationCategoryType" />
+ </xs:complexContent>
+ </xs:complexType>
+ </xs:element>
+ <!-- ========= ConfigureSituation ============ -->
+ <xs:element name="ConfigureSituation">
+ <xs:complexType>
+ <xs:complexContent>
+ <xs:restriction base="muws2:SituationCategoryType" />
+ </xs:complexContent>
+ </xs:complexType>
+ </xs:element>
+ <!-- ========= OtherSituation ============ -->
+ <xs:element name="OtherSituation">
+ <xs:complexType>
+ <xs:complexContent>
+ <xs:restriction base="muws2:SituationCategoryType" />
+ </xs:complexContent>
+ </xs:complexType>
+ </xs:element>
+ <!--
+ SCHEMA COPY Material
+ Copy and paste element references below into the schema of a resource properties document.
+ These references insure that the correct minOccurs/maxOccurs attributes are specified in a resource property document schema.
+
+ NOTE: You must import the MUWS Part 2 schema namespace (MUWS2).
+
+ ** Description Properties **
+ <xs:element ref="muws2:Caption"
+ minOccurs="0" maxOccurs="unbounded"/>
+ <xs:element ref="muws2:Description"
+ minOccurs="0" maxOccurs="unbounded"/>
+ <xs:element ref="muws2:Version"
+ minOccurs="0"/>
+
+ ** Operational Status **
+ <xs:element ref="muws2:OperationalStatus"/>
+
+ ** Metrics **
+ <xs:element ref="muws2:CurrentTime"/>
+
+ ** Relationship **
+ <xs:element ref="muws2:Relationship"
+ minOccurs="0" maxOccurs="unbounded"/>
+
+ ** Relationship Resource **
+ <xs:element ref="muws2:Name" minOccurs="0"/>
+ <xs:element ref="muws2:Type"/>
+ <xs:element ref="muws2:Participant"
+ minOccurs="2" maxOccurs="unbounded"/>
+
+ -->
+</xs:schema>
diff --git a/qpid/java/management/client/src/main/java/wsdl/WsResource.rmd b/qpid/java/management/client/src/main/java/wsdl/WsResource.rmd
new file mode 100644
index 0000000000..b15f7eca1c
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/wsdl/WsResource.rmd
@@ -0,0 +1,14 @@
+<?xml version="1.0"?>
+<Definitions xmlns="http://docs.oasis-open.org/wsrf/rmd-1" >
+
+ <MetadataDescriptor xmlns:wsrl="http://docs.oasis-open.org/wsrf/rl-2"
+ xmlns:qman="http://amqp.apache.org/qpid/management/qman" name="QManWsResourceMetadata"
+ interface="qman:QManWsResourcePortType"
+ wsdlLocation="http://ws.apache.org/muse/test/wsrf QManWsResource.wsdl" >
+
+ <Property name="wsrl:CurrentTime" modifiability="read-only" mutability="mutable" />
+
+ <Property name="wsrl:TerminationTime" modifiability="read-only" mutability="mutable" />
+ </MetadataDescriptor>
+
+</Definitions> \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/wsdl/WsResourceFactory.wsdl b/qpid/java/management/client/src/main/java/wsdl/WsResourceFactory.wsdl
new file mode 100644
index 0000000000..83a7e5ad8c
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/wsdl/WsResourceFactory.wsdl
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<wsdl:definitions
+ targetNamespace="http://ws.apache.org/muse/test/wsrf"
+ xmlns:tns="http://ws.apache.org/muse/test/wsrf"
+ xmlns="http://schemas.xmlsoap.org/wsdl/"
+ xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
+ xmlns:wsdl-soap="http://schemas.xmlsoap.org/wsdl/soap/"
+ xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ name="WsResourceFactory">
+ <wsdl:types>
+ </wsdl:types>
+ <wsdl:portType name="WsResourceFactoryPortType" >
+ </wsdl:portType>
+ <wsdl:binding name="WsResourceFactoryBinding" type="tns:WsResourceFactoryPortType">
+ <wsdl-soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http" />
+ </wsdl:binding>
+ <wsdl:service name="WsResourceFactoryService">
+ <wsdl:port name="WsResourceFactoryPort" binding="tns:WsResourceFactoryBinding">
+ <wsdl-soap:address location="http://romagazzarini:8080/wsrf/services/WsResourceFactory"/>
+ </wsdl:port>
+ </wsdl:service>
+</wsdl:definitions>
diff --git a/qpid/java/management/client/src/main/java/wsdl/XML-Namespace-1998.xsd b/qpid/java/management/client/src/main/java/wsdl/XML-Namespace-1998.xsd
new file mode 100644
index 0000000000..f51b67f78f
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/wsdl/XML-Namespace-1998.xsd
@@ -0,0 +1,46 @@
+<?xml version='1.0'?>
+<!--
+
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+
+-->
+
+<xs:schema targetNamespace="http://www.w3.org/XML/1998/namespace" xmlns:xs="http://www.w3.org/2001/XMLSchema" xml:lang="en">
+
+ <xs:attribute name="lang" type="xs:language">
+ </xs:attribute>
+
+ <xs:attribute name="space" default="preserve">
+ <xs:simpleType>
+ <xs:restriction base="xs:NCName">
+ <xs:enumeration value="default"/>
+ <xs:enumeration value="preserve"/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:attribute>
+
+ <xs:attribute name="base" type="xs:anyURI">
+ </xs:attribute>
+
+ <xs:attributeGroup name="specialAttrs">
+ <xs:attribute ref="xml:base"/>
+ <xs:attribute ref="xml:lang"/>
+ <xs:attribute ref="xml:space"/>
+ </xs:attributeGroup>
+
+</xs:schema>
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
new file mode 100644
index 0000000000..9abcd08eef
--- /dev/null
+++ b/qpid/java/management/client/src/test/java/org/apache/qpid/management/TestConstants.java
@@ -0,0 +1,67 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.management;
+
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+
+import org.apache.qpid.management.domain.handler.impl.MethodOrEventDataTransferObject;
+import org.apache.qpid.management.domain.model.DomainModel;
+import org.apache.qpid.management.domain.model.type.Binary;
+
+/**
+ * Collects all literal constants used in test cases.
+ */
+public interface TestConstants
+{
+ UUID BROKER_ID = UUID.randomUUID();
+ Binary OBJECT_ID = new Binary(new byte []{1,2,3,2,1,1,2,3});
+
+ DomainModel DOMAIN_MODEL = new DomainModel(BROKER_ID);
+
+ String AGE_ATTRIBUTE_NAME = "age";
+ String AGE_ATTRIBUTE_DESCRIPTION = "The age of a person.";
+ String SURNAME_ATTRIBUTE_NAME = "surname";
+ String SURNAME_ATTRIBUTE_DESCRIPTION = "The surname of a person.";
+ Integer _1 = new Integer(1);
+
+ byte [] TEST_RAW_DATA= new byte []{1,4,5,7,8,9,4,44};
+ long NOW = System.currentTimeMillis();
+ int SEVERITY = _1;
+
+ String QPID_PACKAGE_NAME = "qpid";
+ String EXCHANGE_CLASS_NAME = "exchange";
+ String BIND_EVENT_NAME = "bind";
+ Binary HASH = new Binary(new byte []{1,2,3,4,5,6,7,8,9});
+ int VALID_CODE = _1;
+
+ List<Map<String, Object>> EMPTY_PROPERTIES_SCHEMA = new LinkedList<Map<String,Object>>();
+ List<Map<String, Object>> EMPTY_STATISTICS_SCHEMA = new LinkedList<Map<String,Object>>();
+ List<MethodOrEventDataTransferObject> EMPTY_METHODS_SCHEMA = new LinkedList<MethodOrEventDataTransferObject>();
+ List<Map<String, Object>> EMPTY_ARGUMENTS_SCHEMA = new LinkedList<Map<String,Object>>();
+ int _0 = 0;
+ int SAMPLE_ACCESS_CODE = 1;
+ String YEARS = "years";
+ int SAMPLE_MIN_VALUE = 1;
+ 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
new file mode 100644
index 0000000000..72bd45f70f
--- /dev/null
+++ b/qpid/java/management/client/src/test/java/org/apache/qpid/management/configuration/ConfigurationTest.java
@@ -0,0 +1,181 @@
+/*
+ *
+ * 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 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;
+
+/**
+ * Test case for Configuration singleton.
+ */
+public class ConfigurationTest extends TestCase
+{
+ /**
+ * Tests the singleton behaviour of the configuration object.
+ */
+ public void testSingleton()
+ {
+ assertSame(Configuration.getInstance(),Configuration.getInstance());
+ }
+
+ /**
+ * Tests the execution of getType() method when a unknown code is supplied.
+ *
+ * <br>precondition : the requested type doesn't exist on the configuration.
+ * <br>postcondition : an exception is thrown indicating the failure.
+ */
+ public void testGetTypeKO()
+ {
+ try
+ {
+ Configuration.getInstance().getType(TestConstants.VALID_CODE*10001);
+ fail("If an unknwon code is supplied an exception must be thrown.");
+ } catch (UnknownTypeCodeException expected)
+ {
+ assertEquals(TestConstants.VALID_CODE*10001,expected.getCode());
+ }
+ }
+
+ /**
+ * Tests the execution of getAccessMode() method when a unknown code is supplied.
+ *
+ * <br>precondition : the requested access mode doesn't exist on the configuration.
+ * <br>postcondition : an exception is thrown indicating the failure.
+ */
+ public void testGetAccessModeKO()
+ {
+ try
+ {
+ Configuration.getInstance().getAccessMode(TestConstants.VALID_CODE*1528);
+ fail("If an unknwon code is supplied an exception must be thrown.");
+ } catch (UnknownAccessCodeException expected)
+ {
+ assertEquals(TestConstants.VALID_CODE*1528,expected.getCode());
+ }
+ }
+
+ /**
+ * Tests the execution of the getBrokerConnectionData when a valid broker id is supplied.
+ *
+ * <br>precondition : on configuration a connection data is stored and associated with the supplied id.
+ * <br>postcondition : the requested connection data is returned and no exception is thrown.
+ */
+ public void testGetBrokerConnectionDataOK() throws Exception
+ {
+ BrokerConnectionData connectionData = new BrokerConnectionData();
+ connectionData.setHost("host");
+ connectionData.setPort("7001");
+ connectionData.setInitialPoolCapacity("0");
+ connectionData.setMaxPoolCapacity("10");
+ connectionData.setMaxWaitTimeout("1");
+ Configuration.getInstance().addBrokerConnectionData(TestConstants.BROKER_ID, connectionData);
+
+ BrokerConnectionData result = Configuration.getInstance().getBrokerConnectionData(TestConstants.BROKER_ID);
+ assertSame(connectionData, result);
+ }
+
+ /**
+ * Tests the execution of the getBrokerConnectionData when a unknown broker id is supplied.
+ *
+ * <br>precondition : on configuration there's no connection data associated with the supplied id.
+ * <br>postcondition : an exception is thrown indicating the failure.
+ */
+ public void testGetBrokerConnectionDataKO_withUnknownBrokerId()
+ {
+ UUID brokerId = UUID.randomUUID();
+ try
+ {
+ Configuration.getInstance().getBrokerConnectionData(brokerId);
+ fail("If an unknown broker id is supplied then an exception must be thrown.");
+ } catch(UnknownBrokerException expected)
+ {
+ assertEquals(brokerId.toString(),expected.getMessage());
+ }
+ }
+
+ /**
+ * Tests the execution of the getBrokerConnectionData when a null id is supplied.
+ *
+ * <br>precondition : a null broker is given.
+ * <br>postcondition : an exception is thrown indicating the failure.
+ */
+ public void testGetBrokerConnectionDataKO_withNullBrokerId()
+ {
+ try
+ {
+ Configuration.getInstance().getBrokerConnectionData(null);
+ fail("If a null broker id is supplied then an exception must be thrown.");
+ } catch(UnknownBrokerException expected)
+ {
+ }
+ }
+
+ /**
+ * Tests the behaviour of the getManagementQueueHandlers() method.
+ *
+ * <br>precondition: 2 management handlers are in stored configuration
+ * <br>postcondition : 2 management handlers are returned.
+ */
+ public void testGetManagementQueueHandlersOk()
+ {
+ IMessageHandler instrMessageHandler = new InstrumentationMessageHandler();
+ IMessageHandler configMessageHandler = new ConfigurationMessageHandler();
+
+ MessageHandlerMapping instrMapping = new MessageHandlerMapping('i',instrMessageHandler);
+ MessageHandlerMapping configMapping = new MessageHandlerMapping('c',configMessageHandler);
+
+ Configuration.getInstance().addManagementMessageHandlerMapping(instrMapping);
+ Configuration.getInstance().addManagementMessageHandlerMapping(configMapping);
+
+ Map<Character, IMessageHandler> handlerMappings = Configuration.getInstance().getManagementQueueHandlers();
+
+ assertEquals(2,handlerMappings.size());
+ assertEquals(instrMessageHandler,handlerMappings.get(instrMapping.getOpcode()));
+ assertEquals(configMessageHandler,handlerMappings.get(configMapping.getOpcode()));
+ }
+
+ /**
+ * Tests the behaviour of the getManagementQueueHandlers() method.
+ *
+ * <br>precondition: 2 management handlers are in stored configuration
+ * <br>postcondition : 2 management handlers are returned.
+ */
+ public void testGetMethodReplyQueueHandlersOk()
+ {
+ IMessageHandler schemaMessageHandler = new SchemaResponseMessageHandler();
+
+ MessageHandlerMapping schemaMapping = new MessageHandlerMapping('s',schemaMessageHandler);
+
+ Configuration.getInstance().addMethodReplyMessageHandlerMapping(schemaMapping);
+
+ Map<Character, IMessageHandler> handlerMappings = Configuration.getInstance().getMethodReplyQueueHandlers();
+
+ assertEquals(schemaMessageHandler,handlerMappings.get(schemaMapping.getOpcode()));
+ }
+}
diff --git a/qpid/java/management/client/src/test/java/org/apache/qpid/management/configuration/ConfiguratorTest.java b/qpid/java/management/client/src/test/java/org/apache/qpid/management/configuration/ConfiguratorTest.java
new file mode 100644
index 0000000000..1e464bf6ae
--- /dev/null
+++ b/qpid/java/management/client/src/test/java/org/apache/qpid/management/configuration/ConfiguratorTest.java
@@ -0,0 +1,163 @@
+/*
+ *
+ * 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 java.util.Map;
+import java.util.UUID;
+
+import junit.framework.TestCase;
+
+import org.apache.qpid.management.Protocol;
+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.EventContentMessageHandler;
+import org.apache.qpid.management.domain.handler.impl.HeartBeatIndicationMessageHandler;
+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.xml.sax.SAXException;
+
+/**
+ * Test case for configurator.
+ *
+ * @author Andrea Gazzarini
+ *
+ */
+public class ConfiguratorTest extends TestCase
+{
+ /**
+ * Tests the execution of the configure() method when no configuration file is given.
+ *
+ * <br>precondition : configuration file option is not set
+ * <br>postcondition : no exception is thrown, the configuration is holding no broker data and the predefined mappings are
+ * stored in configuration.
+ */
+ public void testConfigureOK_WithNoConfigurationFile() throws Exception
+ {
+ Configurator configurator = new Configurator();
+ configurator.configure();
+ Configuration configuration = Configuration.getInstance();
+
+ assertEquals(new Uint8(), configuration.getType(1));
+ assertEquals(new Uint16(), configuration.getType(2));
+ assertEquals(new Uint32(), configuration.getType(3));
+ assertEquals(new Uint64(), configuration.getType(4));
+ assertEquals(new Str8(), configuration.getType(6));
+ assertEquals(new Str16(), configuration.getType(7));
+ assertEquals(new AbsTime(), configuration.getType(8));
+ assertEquals(new DeltaTime(), configuration.getType(9));
+ assertEquals(new ObjectReference(), configuration.getType(10));
+ assertEquals(new org.apache.qpid.management.domain.model.type.Boolean(), configuration.getType(11));
+ assertEquals(new org.apache.qpid.management.domain.model.type.Uuid(), configuration.getType(14));
+ assertEquals(new org.apache.qpid.management.domain.model.type.Map(), configuration.getType(15));
+
+ assertEquals(AccessMode.RC,configuration.getAccessMode(1));
+ assertEquals(AccessMode.RW,configuration.getAccessMode(2));
+ assertEquals(AccessMode.RO,configuration.getAccessMode(3));
+
+ Map<Character, IMessageHandler> managementHandlers = configuration.getManagementQueueHandlers();
+ assertEquals(4,managementHandlers.size());
+ assertEquals(
+ InstrumentationMessageHandler.class,
+ managementHandlers.get(Protocol.INSTRUMENTATION_CONTENT_RESPONSE_OPCODE).getClass());
+
+ assertEquals(
+ ConfigurationMessageHandler.class,
+ managementHandlers.get(Protocol.CONFIGURATION_CONTENT_RESPONSE_OPCDE).getClass());
+
+ assertEquals(
+ EventContentMessageHandler.class,
+ managementHandlers.get(Protocol.EVENT_CONTENT_RESPONSE_OPCDE).getClass());
+
+ assertEquals(
+ HeartBeatIndicationMessageHandler.class,
+ managementHandlers.get(Protocol.HEARTBEAT_INDICATION_RESPONSE_OPCODE).getClass());
+
+ Map<Character, IMessageHandler> methodReplyHandlers = configuration.getMethodReplyQueueHandlers();
+ assertEquals(2, methodReplyHandlers.size());
+
+ assertEquals(
+ MethodResponseMessageHandler.class,
+ methodReplyHandlers.get(Protocol.OPERATION_INVOCATION_RESPONSE_OPCODE).getClass());
+
+ assertEquals(
+ SchemaResponseMessageHandler.class,
+ methodReplyHandlers.get(Protocol.SCHEMA_RESPONSE_OPCODE).getClass());
+ }
+
+ /**
+ * Tests the changes of the configurator internal state while configuration file is parsed.
+ *
+ * <br>precondition: N.A.
+ * <br>postcondition: N.A.
+ */
+ public void testDirectorParsing() throws SAXException{
+ Configurator configurator = new Configurator();
+
+ assertSame(Configurator.DEFAULT_PARSER,configurator._currentParser);
+
+ configurator.startElement(null, null, Tag.BROKERS.toString(), null);
+ assertSame(configurator._brokerConfigurationParser,configurator._currentParser);
+ }
+
+ /**
+ * It's not possibile to add twice the same broker connection data.
+ * Is so an exception must be thrown indicating that the given broker is already connected.
+ *
+ * <br>precondition : the given data identifies an already connected broker.
+ * <br>postcondition : an exception is thrown indicating the failure.
+ */
+ public void testAddTwoIdenticalBrokers() throws ConfigurationException, BrokerConnectionException
+ {
+ Configurator configurator = new Configurator();
+ configurator.configure();
+
+ BrokerConnectionData data = new BrokerConnectionData("sofia.gazzax.com",5672,"virtualHost","user","pwd",1,4,-1);
+
+ Configuration.getInstance()._brokerConnectionInfos.put(UUID.randomUUID(),data);
+
+ try {
+ configurator.createAndReturnBrokerConnectionData(
+ UUID.randomUUID(),
+ data.getHost(),
+ data.getPort(),
+ "anotherUser",
+ "anotherPassword",
+ data.getVirtualHost(),
+ 33,
+ 12,
+ 1000);
+ fail("If a broker is added twice an exception must be thrown.");
+ } catch (BrokerAlreadyConnectedException expected) {
+ assertEquals(data,expected.getBrokerConnectionData());
+ }
+ }
+}
diff --git a/qpid/java/management/client/src/test/java/org/apache/qpid/management/configuration/MappingParsersTest.java b/qpid/java/management/client/src/test/java/org/apache/qpid/management/configuration/MappingParsersTest.java
new file mode 100644
index 0000000000..af261024bd
--- /dev/null
+++ b/qpid/java/management/client/src/test/java/org/apache/qpid/management/configuration/MappingParsersTest.java
@@ -0,0 +1,79 @@
+/*
+ *
+ * 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 java.util.UUID;
+
+import junit.framework.TestCase;
+
+import org.apache.qpid.management.TestConstants;
+
+/**
+ * Test case for mapping parsers.
+ *
+ * @author Andrea Gazzarini.
+ */
+public class MappingParsersTest extends TestCase
+{
+ /**
+ * Tests the execution of the broker connection data mapping parser.
+ *
+ * <br>precondition: A broker connection datamapping is built by the parser;
+ * <br>postcondition: the corresponding connection data is available on the configuration.
+ */
+ public void testBrokerConnectionDataParser() throws UnknownBrokerException
+ {
+ String host = "127.0.0.1";
+ String port = "7001";
+ String virtualHost = "test";
+ String username = "username_guest";
+ String password ="password_guest";
+
+ BrokerConnectionDataParser parser = new BrokerConnectionDataParser()
+ {
+ @Override
+ UUID getUUId ()
+ {
+ return TestConstants.BROKER_ID;
+ }
+ };
+
+ parser.setCurrrentAttributeValue(host);
+ parser.setCurrentAttributeName(Tag.HOST.toString());
+ parser.setCurrrentAttributeValue(port);
+ parser.setCurrentAttributeName(Tag.PORT.toString());
+ parser.setCurrrentAttributeValue(virtualHost);
+ parser.setCurrentAttributeName(Tag.VIRTUAL_HOST.toString());
+ parser.setCurrrentAttributeValue(username);
+ parser.setCurrentAttributeName(Tag.USER.toString());
+ parser.setCurrrentAttributeValue(password);
+ parser.setCurrentAttributeName(Tag.PASSWORD.toString());
+ parser.setCurrentAttributeName(Tag.BROKER.toString());
+
+ BrokerConnectionData result = Configuration.getInstance().getBrokerConnectionData(TestConstants.BROKER_ID);
+
+ assertEquals(host,result.getHost());
+ assertEquals(Integer.parseInt(port),result.getPort());
+ assertEquals(virtualHost,result.getVirtualHost());
+ assertEquals(username,result.getUsername());
+ assertEquals(password,result.getPassword());
+ }
+}
diff --git a/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/handler/base/ContentIndicationMessageHandlerTest.java b/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/handler/base/ContentIndicationMessageHandlerTest.java
new file mode 100644
index 0000000000..d6b51b64fc
--- /dev/null
+++ b/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/handler/base/ContentIndicationMessageHandlerTest.java
@@ -0,0 +1,59 @@
+/*
+ *
+ * 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.domain.handler.base;
+
+import junit.framework.TestCase;
+
+import org.apache.qpid.management.domain.model.type.Binary;
+
+/**
+ * Test case for Content indication message handler (base class).
+ *
+ * @author Andrea Gazzarini
+ */
+public class ContentIndicationMessageHandlerTest extends TestCase
+{
+ /**
+ * Tests the behaviour of the objectHasBeenRemoved method().
+ */
+ public void testObjectHasBeenRemoved()
+ {
+ ContentIndicationMessageHandler mockHandler = new ContentIndicationMessageHandler()
+ {
+ @Override
+ protected void updateDomainModel (String packageName, String className, Binary classHash, Binary objectId,
+ long timeStampOfCurrentSample, long timeObjectWasCreated, long timeObjectWasDeleted, byte[] contentData)
+ {
+ }
+ };
+
+ long deletionTimestamp = 0;
+ long now = System.currentTimeMillis();
+
+ assertFalse(mockHandler.objectHasBeenRemoved(deletionTimestamp, now));
+
+ deletionTimestamp = now + 1000;
+ assertFalse(mockHandler.objectHasBeenRemoved(deletionTimestamp, now));
+
+ deletionTimestamp = now - 1000;
+ assertTrue(mockHandler.objectHasBeenRemoved(deletionTimestamp, now));
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/BaseDomainModelTestCase.java b/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/BaseDomainModelTestCase.java
new file mode 100644
index 0000000000..c528392a93
--- /dev/null
+++ b/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/BaseDomainModelTestCase.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.domain.model;
+
+import org.apache.qpid.management.configuration.Configurator;
+
+import junit.framework.TestCase;
+
+/**
+ * Layer supertype for all domain model related test cases.
+ *
+ * @author Andrea Gazzarini
+ */
+public abstract class BaseDomainModelTestCase extends TestCase
+{
+ /**
+ * Set up fixture for this test case.
+ * In order to execute tests on domain model we need to build the configuration.
+ */
+ @Override
+ protected void setUp () throws Exception
+ {
+ Configurator configurator = new Configurator();
+ configurator.configure();
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/BaseQpidFeatureBuilderTestCase.java b/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/BaseQpidFeatureBuilderTestCase.java
new file mode 100644
index 0000000000..3d3783eb04
--- /dev/null
+++ b/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/BaseQpidFeatureBuilderTestCase.java
@@ -0,0 +1,96 @@
+/*
+ *
+ * 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.domain.model;
+
+import static org.apache.qpid.management.domain.model.QpidFeatureBuilder.Attribute.desc;
+import static org.apache.qpid.management.domain.model.QpidFeatureBuilder.Attribute.name;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import junit.framework.TestCase;
+
+import org.apache.qpid.management.configuration.Configurator;
+import org.apache.qpid.management.domain.model.QpidFeatureBuilder.Attribute;
+
+/**
+ * Layer supertype for feature builder test cases.
+ *
+ * @author Andrea Gazzarini
+ */
+public abstract class BaseQpidFeatureBuilderTestCase extends TestCase
+{
+ protected final static String NAME = "aName";
+
+ protected final static String DESCRIPTION = "A description.";
+
+ protected Map <String,Object> _featureDefinition;
+ protected QpidFeatureBuilder _builder;
+
+ /**
+ * Set up fixture for all concrete builder test cases.
+ */
+ @Override
+ protected void setUp () throws Exception
+ {
+ Configurator configurator = new Configurator();
+ configurator.configure();
+ _featureDefinition = new HashMap<String, Object>();
+ _featureDefinition.put(name.name(),NAME);
+ _featureDefinition.put(desc.name(), DESCRIPTION);
+ }
+
+ // Internal test used to avoid code duplication.
+ protected void internalTestForMissingMandatoryAttribute(Attribute ...toBeRemoved)
+ {
+ try
+ {
+ for (Attribute attribute : toBeRemoved)
+ {
+ _featureDefinition.remove(attribute.name());
+ }
+ _builder.build();
+ fail("If a mandatory attribute is missing an exception must be thrown!");
+ } catch (UnableToBuildFeatureException expected)
+ {
+ assertTrue(expected instanceof MissingFeatureAttributesException);
+ for (Attribute attribute : toBeRemoved)
+ {
+ assertTrue(expected.getMessage().contains(attribute.name()));
+ }
+ }
+ }
+
+ // Internal test used to avoid code duplication.
+ protected void internalTestForMissingOptionalAttribute(Attribute ...toBeRemoved) throws UnableToBuildFeatureException
+ {
+ for (Attribute attribute : toBeRemoved)
+ {
+ _featureDefinition.remove(attribute.name());
+ }
+ _builder.build();
+
+ assertNotNull(_builder.getQpidFeature());
+ assertNotNull(_builder.getManagementFeature());
+ }
+
+
+}
diff --git a/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/DomainModelTest.java b/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/DomainModelTest.java
new file mode 100644
index 0000000000..578fa36bc7
--- /dev/null
+++ b/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/DomainModelTest.java
@@ -0,0 +1,55 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.management.domain.model;
+
+import java.util.UUID;
+
+import org.apache.qpid.management.TestConstants;
+
+/**
+ * Test case for domain model entity.
+ *
+ * @author Andrea Gazzarini
+ */
+public class DomainModelTest extends BaseDomainModelTestCase
+{
+ private DomainModel _model;
+
+ @Override
+ protected void setUp () throws Exception
+ {
+ _model = new DomainModel(UUID.randomUUID());
+ }
+
+ /**
+ * Tests the execution of the getPackage() method.
+ */
+ public void testGetPackage()
+ {
+ assertFalse(_model.containsPackage(TestConstants.QPID_PACKAGE_NAME));
+
+ QpidPackage qpidPackage = _model.getPackageByName(TestConstants.QPID_PACKAGE_NAME);
+ assertEquals(TestConstants.QPID_PACKAGE_NAME,qpidPackage.getName());
+
+ QpidPackage theSameAsPreviousOne = _model.getPackageByName(TestConstants.QPID_PACKAGE_NAME);
+ assertSame(qpidPackage, theSameAsPreviousOne);
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/OptionalPropertiesTest.java b/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/OptionalPropertiesTest.java
new file mode 100644
index 0000000000..553c1c21de
--- /dev/null
+++ b/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/OptionalPropertiesTest.java
@@ -0,0 +1,187 @@
+/*
+ *
+ * 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.domain.model;
+
+import java.nio.ByteBuffer;
+import java.util.LinkedList;
+import java.util.List;
+
+import junit.framework.TestCase;
+
+import org.apache.qpid.management.domain.model.type.Uint64;
+import org.apache.qpid.transport.codec.BBDecoder;
+
+public class OptionalPropertiesTest extends TestCase
+{
+ public void testDecoderStateChange()
+ {
+ QpidProperty property = new QpidProperty();
+ assertSame(
+ "Default decoder for properties is the one for mandatory properties.",
+ property._mandatoryPropertyDecoder,
+ property._decoder);
+
+ property.markAsOptional(1);
+ assertSame(
+ "After a property has been marked as optional the corresponding decoder must be installed.",
+ property._optionalPropertyDecoder,
+ property._decoder);
+ }
+
+ /**
+ * Tests the execution of the decode() method when the current property is optional but in the presence bitmask
+ * there's no the corresponding bit set.
+ *
+ * <br>precondition : property is optional and corresponding presence bit is not set.
+ * <br>postcondition : result must be null.
+ */
+ public void testDecodeValueWithOptionalPropertyAndMissingValue()
+ {
+ byte [] presenceBytes = {2};
+
+ QpidProperty property = new QpidProperty();
+
+ // We don't need a decoder so in order to be sure that it won't be invoked set it to null.
+ BBDecoder nullDecoder = null;
+
+ for (int i = 0; i < 8; i++)
+ {
+ // Property number 1 is declaring a value so skip it!
+ if (i != 1)
+ {
+ property.markAsOptional(i);
+ assertNull(property.decodeValue(nullDecoder, presenceBytes));
+ }
+ }
+ }
+
+ /**
+ * Tests the execution of the decode() method when the current property is optional but in the presence bitmask
+ * there's no the corresponding bit set.
+ *
+ * <br>precondition : property is optional and corresponding presence bit is not set.
+ * <br>postcondition : result must be null.
+ */
+ public void testDecodeValueWithOptionalPropertyAndDeclaredValue()
+ {
+ byte [] presenceBytes = {4};
+ Long _44 = new Long(44);
+
+ QpidProperty property = new QpidProperty();
+ property.setType(new Uint64());
+ property.markAsOptional(2);
+
+ ByteBuffer buffer = ByteBuffer.allocate(8);
+ buffer.putLong(_44);
+ buffer.rewind();
+ BBDecoder decoder = new BBDecoder();
+
+ decoder.init(buffer);
+ assertEquals(_44,property.decodeValue(decoder, presenceBytes));
+ }
+
+ /**
+ * Tests the execution of the decode() method with a real scenario where there are mandatory and optional
+ * properties.
+ */
+ public void testDecodeValueWithOptionalAndMandatoryProperties()
+ {
+ // With this bitset :
+ //
+ // 1th opt property is null;
+ // 2th opt property is null;
+ // 3th opt property is not null;
+ // 4th opt property is null;
+ // 5th opt propertyis null;
+ // 6th opt property is null;
+ // 7th opt property is null;
+ // 8th opt property is not null;
+ byte [] presenceBytes = {4,1};
+
+ List<QpidProperty> properties = new LinkedList<QpidProperty>();
+
+ properties.add(createProperty(false, -1));
+ properties.add(createProperty(false, -1));
+ properties.add(createProperty(true, 0));
+ properties.add(createProperty(false, -1));
+ properties.add(createProperty(false, -1));
+ properties.add(createProperty(true, 1));
+ properties.add(createProperty(false, -1));
+ properties.add(createProperty(false, -1));
+ properties.add(createProperty(true, 2));
+ properties.add(createProperty(true, 3));
+ properties.add(createProperty(true, 4));
+ properties.add(createProperty(true, 5));
+ properties.add(createProperty(true, 6));
+ properties.add(createProperty(true, 7));
+ properties.add(createProperty(false, -1));
+ properties.add(createProperty(true, 8));
+
+ Long expectedResults [] = {
+ 1L, // p1
+ 22L, // p2
+ null, // p3
+ 232L, // p4
+ 211L, // p5
+ null, // p6
+ 232L, // p7
+ 211L, // p8
+ 999L, // p9
+ null, // p10
+ null, // p11
+ null, // p12
+ null, // p13
+ null, // p14
+ 626L, // p15
+ 969L // p16
+ };
+
+
+ ByteBuffer buffer = ByteBuffer.allocate(expectedResults.length * 8);
+ for (Long expected : expectedResults)
+ {
+ if (expected != null)
+ {
+ buffer.putLong(expected);
+ }
+ }
+ buffer.rewind();
+ BBDecoder decoder = new BBDecoder();
+
+ decoder.init(buffer);
+ int index = 0;
+ for (QpidProperty property : properties)
+ {
+ assertEquals(expectedResults[index++],property.decodeValue(decoder, presenceBytes));
+ }
+ }
+
+ private QpidProperty createProperty(boolean isOptional, int optionalIndex)
+ {
+ QpidProperty property = new QpidProperty();
+ property.setType(new Uint64());
+ if (isOptional)
+ {
+ property.markAsOptional(optionalIndex);
+ }
+ return property;
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/QpidClassTest.java b/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/QpidClassTest.java
new file mode 100644
index 0000000000..9d6e176912
--- /dev/null
+++ b/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/QpidClassTest.java
@@ -0,0 +1,408 @@
+/*
+*
+ * 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.domain.model;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+import javax.management.MBeanAttributeInfo;
+import javax.management.MBeanInfo;
+
+import junit.framework.TestCase;
+
+import org.apache.qpid.management.TestConstants;
+import org.apache.qpid.management.configuration.ConfigurationException;
+import org.apache.qpid.management.configuration.Configurator;
+import org.apache.qpid.management.domain.handler.impl.MethodOrEventDataTransferObject;
+import org.apache.qpid.management.domain.model.QpidClass.QManManagedObject;
+
+/**
+ * Test case for Qpid Class.
+ *
+ * @author Andrea Gazzarini
+ */
+public class QpidClassTest extends TestCase
+{
+ private QpidClass _class;
+ private QpidPackage _package;
+
+ @Override
+ protected void setUp () throws ConfigurationException
+ {
+ Configurator configurator = new Configurator();
+ configurator.configure();
+ _package = new QpidPackage(TestConstants.QPID_PACKAGE_NAME,TestConstants.DOMAIN_MODEL);
+ _class = new QpidClass(TestConstants.EXCHANGE_CLASS_NAME,TestConstants.HASH,_package);
+ }
+
+ /**
+ * Tests the execution of the getObjectInstance() method.
+ * Basically it tests the addition of a new object instance.
+ *
+ * <br>precondition: class has no object instances.
+ * <br>precondition : class contains the added object instance.
+ */
+ public void testGetObjectInstance()
+ {
+ assertFalse (
+ "Nobody set instance #"+TestConstants.OBJECT_ID+" into this class so why is it there?",
+ _class._objectInstances.containsKey(TestConstants.OBJECT_ID));
+
+ QManManagedObject instance = _class.getObjectInstance(TestConstants.OBJECT_ID, false);
+
+ assertTrue (
+ "Now the instance #"+TestConstants.OBJECT_ID+" should be there...",
+ _class._objectInstances.containsKey(TestConstants.OBJECT_ID));
+
+ assertEquals(instance,_class.getObjectInstance(TestConstants.OBJECT_ID, false));
+ }
+
+ /**
+ * Tests the injection of instrumentation and configuration data (related to a specific object instance) before the
+ * schema is installed.
+ *
+ * <br>precondition : the schema hasn't yet installed on this class.
+ * <br>postcondition : incoming configuration & instrumentation data is stored into the corresponding object instance.
+ */
+ public void testAddInstrumentationAndConfigurationDataBeforeSchemaInstallation()
+ {
+ _class._state = _class._schemaRequestedButNotYetInjected;
+ QManManagedObject objectInstance = _class.getObjectInstance(TestConstants.OBJECT_ID,false);
+
+ assertTrue(
+ "This object instance is a new one so how is it possible that it has already instrumentation data? ",
+ objectInstance._rawInstrumentationData.isEmpty());
+ assertTrue(
+ "This object instance is a new one so how is it possible that it has already configuration data? ",
+ objectInstance._rawConfigurationData.isEmpty());
+
+ byte [] dummyConfigurationData = {1,2,3,4,5,6,7,8};
+ byte [] dummyInstrumentationData = {11,21,31,41,51,61,71,81};
+
+ _class.addConfigurationData(TestConstants.OBJECT_ID, dummyConfigurationData);
+ _class.addInstrumentationData(TestConstants.OBJECT_ID, dummyInstrumentationData);
+
+ assertEquals("Now configuration data should be there...",1,objectInstance._rawConfigurationData.size());
+ assertEquals("Now instrumentation data should be there...",1,objectInstance._rawInstrumentationData.size());
+
+ assertTrue(
+ "Object instance configuration data should be the previously set...",
+ Arrays.equals(objectInstance._rawConfigurationData.get(0),
+ dummyConfigurationData));
+
+ assertTrue(
+ "Object instance instrumentation data should be the previously set...",
+ Arrays.equals(objectInstance._rawInstrumentationData.get(0),
+ dummyInstrumentationData));
+ }
+
+ /**
+ * Tests the internal state change of a class definition.
+ */
+ public void testStateChange() throws UnableToBuildFeatureException
+ {
+ _class = new QpidClass(TestConstants.EXCHANGE_CLASS_NAME,TestConstants.HASH,_package)
+ {
+ @Override
+ void requestSchema() throws Exception {
+ _state = _schemaRequestedButNotYetInjected;
+ }
+
+ @Override
+ void setSchema(List<Map<String, Object>> propertyDefinitions,
+ List<Map<String, Object>> statisticDefinitions,
+ List<MethodOrEventDataTransferObject> methodDefinitions) throws UnableToBuildFeatureException {
+ _state = _schemaInjected;
+ }
+ };
+
+ assertSame(
+ "Initial state doesn't match.",
+ _class._schemaNotRequested,
+ _class._state);
+
+ _class.addConfigurationData(TestConstants.OBJECT_ID, TestConstants.TEST_RAW_DATA);
+ _class.addInstrumentationData(TestConstants.OBJECT_ID, TestConstants.TEST_RAW_DATA);
+
+ assertSame(
+ "Request schema has been requested but not yet injected. The current state is not indicating that!",
+ _class._schemaRequestedButNotYetInjected,
+ _class._state);
+
+ _class.setSchema(
+ TestConstants.EMPTY_PROPERTIES_SCHEMA,
+ TestConstants.EMPTY_STATISTICS_SCHEMA,
+ new LinkedList<MethodOrEventDataTransferObject>());
+
+ assertSame(
+ "Request schema has been injected. The current state is not indicating that!",
+ _class._schemaInjected,
+ _class._state);
+ }
+
+ /**
+ * Tests the injection of a valid schema on a QpidClass.
+ *
+ * <br>precondition : a valid arguments is injected on the qpid class.
+ * <br>postcondition : class definition is built successfully.
+ */
+ public void testSchemaInjectionOk() throws UnableToBuildFeatureException
+ {
+ _class = new QpidClass(TestConstants.EXCHANGE_CLASS_NAME,TestConstants.HASH,_package)
+ {
+ @Override
+ void requestSchema() throws Exception
+ {
+ // DO NOTHING : QMan is not running and therefore the schema will be manually injected.
+ }
+
+ @Override
+ void updateInstanceWithConfigurationData(QManManagedObject instance, byte[] rawData)
+ {
+ // DO NOTHING Given raw data is not valid so it cannot be converted.
+ }
+ };
+
+ // Incoming configuration data : that will fire the schema request and a state change
+ // from schema-not-requested to schema-requested-but-not-injected
+ _class.addConfigurationData(TestConstants.OBJECT_ID, TestConstants.TEST_RAW_DATA);
+
+ // I must be sure that what is obvious for me it's obvious for QMan... :)
+ assertSame(
+ "Request schema has been requested but not yet injected. The current state is not indicating that!",
+ _class._schemaRequestedButNotYetInjected,
+ _class._state);
+
+ List<Map<String,Object>> propertyDefinitions = new ArrayList<Map<String,Object>>(2);
+ propertyDefinitions.add(
+ createProperty(
+ TestConstants.AGE_ATTRIBUTE_NAME,
+ 1,
+ TestConstants.YEARS,
+ TestConstants.SAMPLE_MIN_VALUE,
+ TestConstants.SAMPLE_MAX_VALUE,
+ null,
+ TestConstants.AGE_ATTRIBUTE_DESCRIPTION,
+ TestConstants._1,
+ false,
+ TestConstants._0));
+
+ propertyDefinitions.add(
+ createProperty(
+ TestConstants.SURNAME_ATTRIBUTE_NAME,
+ TestConstants.SAMPLE_ACCESS_CODE,
+ null,
+ null,
+ null,
+ TestConstants.SAMPLE_MAX_VALUE,
+ TestConstants.SURNAME_ATTRIBUTE_DESCRIPTION,
+ TestConstants._1,
+ true,
+ TestConstants._1));
+
+ _class.setSchema(propertyDefinitions, TestConstants.EMPTY_STATISTICS_SCHEMA, TestConstants.EMPTY_METHODS_SCHEMA);
+
+ assertEquals(2,_class._properties.size());
+
+ QpidProperty property = _class._properties.get(TestConstants.AGE_ATTRIBUTE_NAME);
+ assertEquals(TestConstants.AGE_ATTRIBUTE_NAME,property.getName());
+ assertEquals(AccessMode.RC,property.getAccessMode());
+ assertEquals(TestConstants.YEARS,property.getUnit());
+ assertEquals(TestConstants.SAMPLE_MIN_VALUE,property.getMinValue());
+ assertEquals(TestConstants.SAMPLE_MAX_VALUE,property.getMaxValue());
+ assertEquals(Integer.MIN_VALUE,property.getMaxLength());
+ assertEquals(TestConstants.AGE_ATTRIBUTE_DESCRIPTION,property.getDescription());
+ assertEquals(Short.class,property.getJavaType());
+ assertFalse(property.isOptional());
+
+ property = _class._properties.get(TestConstants.SURNAME_ATTRIBUTE_NAME);
+ assertEquals(TestConstants.SURNAME_ATTRIBUTE_NAME,property.getName());
+ assertEquals(AccessMode.RC,property.getAccessMode());
+ assertNull(property.getUnit());
+ assertEquals(Integer.MIN_VALUE,property.getMinValue());
+ assertEquals(Integer.MIN_VALUE,property.getMaxValue());
+ assertEquals(TestConstants.SAMPLE_MAX_VALUE,property.getMaxLength());
+ assertEquals(TestConstants.SURNAME_ATTRIBUTE_DESCRIPTION,property.getDescription());
+ assertEquals(Short.class,property.getJavaType());
+ assertTrue(property.isOptional());
+
+ MBeanInfo mbeanInfo = _class._metadata;
+ assertEquals(TestConstants.EXCHANGE_CLASS_NAME,mbeanInfo.getClassName());
+
+ MBeanAttributeInfo [] attributes = mbeanInfo.getAttributes();
+ assertEquals(2,attributes.length);
+
+ MBeanAttributeInfo attribute = attributes[0];
+ assertEquals(TestConstants.AGE_ATTRIBUTE_NAME,attribute.getName());
+ assertEquals(TestConstants.AGE_ATTRIBUTE_DESCRIPTION,attribute.getDescription());
+ assertFalse(attribute.isWritable());
+ assertTrue(attribute.isReadable());
+ assertEquals(Short.class.getName(),attribute.getType());
+
+ attribute = attributes[1];
+ assertEquals(TestConstants.SURNAME_ATTRIBUTE_NAME,attribute.getName());
+ assertEquals(TestConstants.SURNAME_ATTRIBUTE_DESCRIPTION,attribute.getDescription());
+ assertFalse(attribute.isWritable());
+ assertTrue(attribute.isReadable());
+ assertEquals(Short.class.getName(),attribute.getType());
+ }
+
+ /**
+ * Tests the behaviour of the class when a schema request can't be made.
+ *
+ * <br>precondition : class must be in "schema-not-requested" state when incoming data arrives.
+ * <br>postcondition : no exception is thrown and no state transition happens.
+ */
+ public void testStateChange_withRequestSchemaFailure()
+ {
+ _class= new QpidClass(TestConstants.EXCHANGE_CLASS_NAME,TestConstants.HASH,_package)
+ {
+ @Override
+ void requestSchema() throws Exception {
+ throw new Exception();
+ }
+
+ @Override
+ void setSchema(
+ List<Map<String, Object>> propertyDefinitions,
+ List<Map<String, Object>> statisticDefinitions,
+ List<MethodOrEventDataTransferObject> methodDefinitions) throws UnableToBuildFeatureException
+ {
+ }
+ };
+
+ assertSame(
+ "Initial state must be schema-not-requested.",
+ _class._schemaNotRequested,
+ _class._state);
+
+ _class.addInstrumentationData(TestConstants.OBJECT_ID, TestConstants.TEST_RAW_DATA);
+
+ assertSame(
+ "Current state must be still schema-not-requested.",
+ _class._schemaNotRequested,
+ _class._state);
+ }
+
+ /**
+ * Tests the behaviour of the class when a schema injection fails.
+ *
+ * <br>precondition : class must be in "schema-not-requested" state when incoming data arrives.
+ * <br>postcondition : an exception is thrown and no state transition happens.
+ */
+ public void testStateChange_withSchemaInjectionFailure()
+ {
+ _class = new QpidClass(TestConstants.EXCHANGE_CLASS_NAME,TestConstants.HASH,_package)
+ {
+ @Override
+ void requestSchema() throws Exception
+ {
+ // DO NOTHING.
+ }
+
+ @Override
+ void setSchema(List<Map<String, Object>> propertyDefinitions,
+ List<Map<String, Object>> statisticDefinitions,
+ List<MethodOrEventDataTransferObject> methodDefinitions)
+ throws UnableToBuildFeatureException
+ {
+ throw new UnableToBuildFeatureException("");
+ }
+ };
+
+ assertSame(
+ "Initial state must be schema-not-requested.",
+ _class._schemaNotRequested,
+ _class._state);
+
+ _class.addInstrumentationData(TestConstants.OBJECT_ID, TestConstants.TEST_RAW_DATA);
+
+ assertSame(
+ "Request schema has been requested but not yet injected. The current state is not indicating that!",
+ _class._schemaRequestedButNotYetInjected,
+ _class._state);
+
+ try {
+ _class.setSchema(
+ TestConstants.EMPTY_PROPERTIES_SCHEMA,
+ TestConstants.EMPTY_STATISTICS_SCHEMA,
+ TestConstants.EMPTY_METHODS_SCHEMA);
+ fail("If we are here something was wrong becuase the setSchema() of this event is throwing an exception...");
+ } catch (UnableToBuildFeatureException expected) {
+ assertSame(
+ "Request schema has been requested but not yet injected. The current state is not indicating that!",
+ _class._schemaRequestedButNotYetInjected,
+ _class._state);
+ }
+ }
+
+ private Map<String,Object> createProperty(
+ String name,
+ Integer accessCode,
+ String unit,
+ Integer min,
+ Integer max,
+ Integer maxLength,
+ String description,
+ Integer type,
+ boolean optional,
+ Integer index)
+ {
+ Map <String,Object> result = new HashMap<String, Object>();
+ result.put(QpidFeatureBuilder.Attribute.name.name(),name);
+ result.put(QpidFeatureBuilder.Attribute.access.name(), accessCode);
+
+ if (unit != null)
+ {
+ result.put(QpidFeatureBuilder.Attribute.unit.name(),unit);
+ }
+
+ if (min != null)
+ {
+ result.put(QpidFeatureBuilder.Attribute.min.name(), min);
+ }
+
+ if (max != null)
+ {
+ result.put(QpidFeatureBuilder.Attribute.max.name(),max);
+ }
+
+ if (maxLength != null)
+ {
+ result.put(QpidFeatureBuilder.Attribute.maxlen.name(),maxLength);
+ }
+
+ result.put(QpidFeatureBuilder.Attribute.desc.name(), description);
+ result.put(QpidFeatureBuilder.Attribute.type.name(), type);
+ result.put(QpidFeatureBuilder.Attribute.optional.name(),optional ? 1 : 0);
+
+ if (index != null)
+ {
+ result.put(QpidFeatureBuilder.Attribute.index.name(), index);
+ }
+ return result;
+ }
+}
diff --git a/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/QpidEventTest.java b/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/QpidEventTest.java
new file mode 100644
index 0000000000..4b36d9e5cc
--- /dev/null
+++ b/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/QpidEventTest.java
@@ -0,0 +1,293 @@
+/*
+ *
+ * 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.domain.model;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.management.InstanceNotFoundException;
+import javax.management.MBeanException;
+import javax.management.ObjectName;
+import javax.management.ReflectionException;
+
+import junit.framework.TestCase;
+
+import org.apache.qpid.management.TestConstants;
+import org.apache.qpid.management.configuration.ConfigurationException;
+import org.apache.qpid.management.configuration.Configurator;
+import org.apache.qpid.management.domain.model.QpidEvent.QManManagedEvent;
+
+/**
+ * Test case for qpid class entity.
+ *
+ * @author Andrea Gazzarini
+ */
+public class QpidEventTest extends TestCase
+{
+ private QpidEvent _event;
+ private QpidPackage _qpidPackage;
+
+ @Override
+ protected void setUp () throws Exception
+ {
+ _qpidPackage = new QpidPackage(TestConstants.QPID_PACKAGE_NAME,TestConstants.DOMAIN_MODEL);
+ _event = new QpidEvent(TestConstants.BIND_EVENT_NAME,TestConstants.HASH,_qpidPackage);
+ }
+
+ /**
+ * Tests the execution of the createEventInstance() method.
+ * Basically it tests the addition of a new event instance.
+ *
+ * <br>precondition: event deifinition has no object instances.
+ * <br>precondition : event definition contains the new object instance.
+ */
+ public void testCreateEventInstance()
+ {
+ assertTrue(
+ "A just created event should be empty. I mean there shouldn't be event instances inside.",
+ _event.hasNoInstances());
+
+ QManManagedEvent instance = createEventInstance();
+
+ assertFalse (
+ "Now a new instance should be there...",
+ _event.hasNoInstances());
+
+ assertEquals(TestConstants.TEST_RAW_DATA,instance._rawEventData);
+ assertEquals(TestConstants.NOW,instance._timestamp);
+ assertEquals(TestConstants.SEVERITY, instance._severity);
+ }
+
+ /**
+ * Tests the internal state change of an event definition.
+ */
+ public void testStateChange() throws UnableToBuildFeatureException
+ {
+ // Let's override this class because this is not an online tests and therefore
+ // QMan is not supposed to be up.
+ _event = new QpidEvent(TestConstants.BIND_EVENT_NAME,TestConstants.HASH,_qpidPackage)
+ {
+ @Override
+ void requestSchema() throws Exception {
+ // Do Nothing.
+ }
+
+ @Override
+ void setSchema(List<Map<String, Object>> argumentDefinitions)throws UnableToBuildFeatureException {
+ _state = _schemaInjected;
+ }
+ };
+
+ assertSame(
+ "Initial state doesn't match.",
+ _event._schemaNotRequested,
+ _event._state);
+
+ _event.addEventData(TestConstants.TEST_RAW_DATA, TestConstants.NOW, TestConstants.SEVERITY);
+
+ assertSame(
+ "Request schema has been requested but not yet injected. The current state is not indicating that!",
+ _event._schemaRequestedButNotYetInjected,
+ _event._state);
+
+ _event.setSchema(TestConstants.EMPTY_ARGUMENTS_SCHEMA);
+
+ assertSame(
+ "Request schema has been injected. The current state is not indicating that!",
+ _event._schemaInjected,
+ _event._state);
+ }
+
+ /**
+ * Tests the injection of a valid schema on a QpidEvent.
+ *
+ * <br>precondition : a valid arguments is injected on the qpid event.
+ * <br>postcondition : event definition is built successfully.
+ */
+ public void testSchemaInjectionOK() throws UnableToBuildFeatureException, ConfigurationException, InstanceNotFoundException, MBeanException, ReflectionException
+ {
+ _event = new QpidEvent(TestConstants.BIND_EVENT_NAME,TestConstants.HASH,_qpidPackage)
+ {
+ @Override
+ void requestSchema() throws Exception
+ {
+ // DO NOTHING : QMan is not running and therefore the schema will be manually injected.
+ }
+
+ @Override
+ void updateEventInstanceWithData(QManManagedEvent instance)
+ {
+ // DO NOTHING : otherwise we should supply a valid raw data to be converted. ;-)
+ }
+ };
+
+ Configurator configurator = new Configurator();
+ configurator.configure();
+
+ List<Map<String,Object>> arguments = new ArrayList<Map<String, Object>>();
+ arguments.add(createArgument(TestConstants.AGE_ATTRIBUTE_NAME, TestConstants.AGE_ATTRIBUTE_DESCRIPTION));
+ arguments.add(createArgument(TestConstants.SURNAME_ATTRIBUTE_NAME, TestConstants.SURNAME_ATTRIBUTE_DESCRIPTION));
+
+ // Incoming data : that will fire the schema request and a state change from schema-not-requested to schema-requested-but-not-injected
+ _event.addEventData(TestConstants.TEST_RAW_DATA, TestConstants.NOW, TestConstants.SEVERITY);
+
+ // I must be sure that what is obvious for me it's obvious for QMan... :)
+ assertSame(
+ "Request schema has been requested but not yet injected. The current state is not indicating that!",
+ _event._schemaRequestedButNotYetInjected,
+ _event._state);
+
+ // Inject schema
+ _event.setSchema(arguments);
+
+ // Arguments must be 2 + 2 (severity)
+ assertEquals(2,_event._arguments.size());
+
+ QpidProperty argument = _event._arguments.get(TestConstants.AGE_ATTRIBUTE_NAME);
+ assertEquals(TestConstants.AGE_ATTRIBUTE_NAME,argument.getName());
+ assertEquals(AccessMode.RO,argument.getAccessMode());
+ assertEquals(TestConstants.AGE_ATTRIBUTE_DESCRIPTION,argument.getDescription());
+ assertEquals(Short.class,argument.getJavaType());
+ assertFalse(argument.isOptional());
+
+ argument = _event._arguments.get(TestConstants.SURNAME_ATTRIBUTE_NAME);
+ assertEquals(TestConstants.SURNAME_ATTRIBUTE_NAME,argument.getName());
+ assertEquals(AccessMode.RO,argument.getAccessMode());
+ assertEquals(TestConstants.SURNAME_ATTRIBUTE_DESCRIPTION,argument.getDescription());
+ assertEquals(Short.class,argument.getJavaType());
+ assertFalse(argument.isOptional());
+
+ assertEquals(1,_event._eventInstances.size());
+
+ JmxService service = new JmxService();
+ Set<ObjectName> objectNames = service.getEventMBeans();
+
+ assertEquals(1,objectNames.size());
+ }
+
+ /**
+ * Tests the behaviour of the event class when a schema request can't be made.
+ *
+ * <br>precondition : event must be in "schema-not-requested" state when incoming data arrives.
+ * <br>postcondition : no exception is thrown and no state transition happens.
+ */
+ public void testStateChange_withRequestSchemaFailure()
+ {
+ _event = new QpidEvent(TestConstants.BIND_EVENT_NAME,TestConstants.HASH,_qpidPackage)
+ {
+ @Override
+ void requestSchema() throws Exception {
+ throw new Exception();
+ }
+
+ @Override
+ void setSchema(List<Map<String, Object>> argumentDefinitions)throws UnableToBuildFeatureException {
+ _state = _schemaInjected;
+ }
+ };
+
+ assertSame(
+ "Initial state must be schema-not-requested.",
+ _event._schemaNotRequested,
+ _event._state);
+
+ _event.addEventData(TestConstants.TEST_RAW_DATA, TestConstants.NOW, TestConstants.SEVERITY);
+
+ assertSame(
+ "Current state must be still schema-not-requested.",
+ _event._schemaNotRequested,
+ _event._state);
+ }
+
+ /**
+ * Tests the behaviour of the event class when a schema injection fails.
+ *
+ * <br>precondition : event must be in "schema-not-requested" state when incoming data arrives.
+ * <br>postcondition : an exception is thrown and no state transition happens.
+ */
+ public void testStateChange_withSchemaInjectionFailure()
+ {
+ _event = new QpidEvent(TestConstants.BIND_EVENT_NAME,TestConstants.HASH,_qpidPackage)
+ {
+ @Override
+ void requestSchema() throws Exception {
+ // DO NOTHING.
+ }
+
+ @Override
+ void setSchema(List<Map<String, Object>> argumentDefinitions)throws UnableToBuildFeatureException {
+ throw new UnableToBuildFeatureException("");
+ }
+ };
+
+ assertSame(
+ "Initial state must be schema-not-requested.",
+ _event._schemaNotRequested,
+ _event._state);
+
+ _event.addEventData(TestConstants.TEST_RAW_DATA, TestConstants.NOW, TestConstants.SEVERITY);
+
+ assertSame(
+ "Request schema has been requested but not yet injected. The current state is not indicating that!",
+ _event._schemaRequestedButNotYetInjected,
+ _event._state);
+
+ try {
+ _event.setSchema(TestConstants.EMPTY_ARGUMENTS_SCHEMA);
+ fail("If we are here something was wrong becuase the setSchema() of this event is throwing an exception...");
+ } catch (UnableToBuildFeatureException expected) {
+ assertSame(
+ "Request schema has been requested but not yet injected. The current state is not indicating that!",
+ _event._schemaRequestedButNotYetInjected,
+ _event._state);
+ }
+ }
+
+ /**
+ * Factory method for qpid managed event instances.
+ *
+ * @return a new QpidManagedEvent with test data inside.
+ */
+ private QManManagedEvent createEventInstance()
+ {
+ return _event.createEventInstance(
+ TestConstants.TEST_RAW_DATA,
+ TestConstants.NOW,
+ TestConstants.SEVERITY);
+ }
+
+ /**
+ * Factory method for event argument.
+ *
+ * @return a new argument metadata.
+ */
+ private Map<String,Object> createArgument(String name,String desc)
+ {
+ Map <String,Object> argument = new HashMap<String, Object>();
+ argument.put(QpidFeatureBuilder.Attribute.name.name(),name);
+ argument.put(QpidFeatureBuilder.Attribute.desc.name(), desc);
+ argument.put(QpidFeatureBuilder.Attribute.type.name(), TestConstants._1);
+ return argument;
+ }
+}
diff --git a/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/QpidMethodBuilderTest.java b/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/QpidMethodBuilderTest.java
new file mode 100644
index 0000000000..06dc35b0b1
--- /dev/null
+++ b/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/QpidMethodBuilderTest.java
@@ -0,0 +1,147 @@
+/*
+ *
+ * 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.domain.model;
+
+import static org.apache.qpid.management.domain.model.QpidFeatureBuilder.Attribute.dir;
+import static org.apache.qpid.management.domain.model.QpidFeatureBuilder.Attribute.name;
+import static org.apache.qpid.management.domain.model.QpidFeatureBuilder.Attribute.type;
+import static org.apache.qpid.management.domain.model.QpidFeatureBuilder.Attribute.unit;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.management.MBeanOperationInfo;
+
+import org.apache.qpid.management.Names;
+import org.apache.qpid.management.domain.handler.impl.MethodOrEventDataTransferObject;
+import org.apache.qpid.management.domain.model.QpidFeatureBuilder.Attribute;
+
+/**
+ * Test case for Qpid Statistic builder.
+ *
+ * @author Andrea Gazzarini
+ */
+public class QpidMethodBuilderTest extends BaseQpidFeatureBuilderTestCase
+{
+ private final static Integer ARG_COUNT = 3;
+ private MethodOrEventDataTransferObject _methodDefinition;
+
+ private List<Map<String,Object>> _argumentsDefinitons = new ArrayList<Map<String, Object>>();
+
+ @Override
+ protected void setUp () throws Exception
+ {
+ super.setUp();
+ _featureDefinition.put(Names.ARG_COUNT_PARAM_NAME, ARG_COUNT);
+
+ Map<String,Object> arg1 = new HashMap<String,Object>();
+ arg1.put(name.name(), "arg1");
+ arg1.put(type.name(),1);
+ arg1.put(dir.name(),Direction.I.name());
+ arg1.put(unit.name(), "bytes");
+
+ Map<String,Object> arg2 = new HashMap<String,Object>();
+ arg2.put(name.name(), "arg2");
+ arg2.put(type.name(),1);
+ arg2.put(dir.name(),Direction.O.name());
+ arg2.put(unit.name(), "bytes");
+
+ Map<String,Object> arg3 = new HashMap<String,Object>();
+ arg3.put(name.name(), "arg3");
+ arg3.put(type.name(),1);
+ arg3.put(dir.name(),Direction.IO.name());
+ arg3.put(unit.name(), "bytes");
+
+ /*
+ dir yes no yes Direction code for method arguments
+ unit yes yes yes Units for numeric values (i.e. seconds, bytes, etc.)
+ min yes no yes Minimum value for numerics
+ max yes no yes Maximum value for numerics
+ maxlen yes no yes Maximum length for strings
+ desc yes yes yes Description of the argument
+ default yes no yes Default value for the argument
+ */
+ _argumentsDefinitons.add(arg1);
+ _argumentsDefinitons.add(arg2);
+
+ _methodDefinition = new MethodOrEventDataTransferObject(_featureDefinition,_argumentsDefinitons);
+ _builder = QpidFeatureBuilder.createMethodBuilder(_methodDefinition);
+ }
+
+ /**
+ * Tests the build process for a statistic when the definition map doesn't contains type attribute.
+ *
+ * <br>precondition: definition map doesn't contains type attribute.
+ * <br>postcondition : an exception should be thrown indicating the failure. That exception must contain the name of the
+ * missing attribute.
+ */
+ public void testMethodBuilderKO_WithMissingName()
+ {
+ internalTestForMissingMandatoryAttribute(Attribute.name);
+ }
+
+ /**
+ * Tests the build process for a statistic when the definition map doesn't contain type, name, index & optional attributes.
+ *
+ * <br>precondition: definition map doesn't contain type, name, index & optional attributes.
+ * <br>postcondition : an exception should be thrown indicating the failure. That exception must contain the name of the
+ * missing attributes.
+ */
+ public void testMethodBuilderOK_WithMissingUnit() throws UnableToBuildFeatureException
+ {
+ internalTestForMissingOptionalAttribute(Attribute.unit);
+ }
+
+ /**
+ * Tests the build process for a statistic when the definition map doesn't unit attribute.
+ * Note that this attribute is optional and therefore the build must succeed.
+ *
+ * <br>precondition: definition map doesn't contain unit attribute.
+ * <br>postcondition : no exception is thrown and the statistic is built.
+ */
+ public void testMethodBuilderOK_WithMissingDescription() throws UnableToBuildFeatureException
+ {
+ internalTestForMissingOptionalAttribute(Attribute.desc);
+ }
+
+ /**
+ * Tests the build process for a statistic when the definition map contains valid values.
+ *
+ * <br>precondition : the statistic definiton map contains valid values.
+ * <br>postcondition : no exception is thrown and the statistisc is built as expected.
+ */
+ public void testMethodBuilderOK() throws UnableToBuildFeatureException
+ {
+ _builder.build();
+
+ QpidMethod method = (QpidMethod) _builder.getQpidFeature();
+ MBeanOperationInfo info = (MBeanOperationInfo) _builder.getManagementFeature();
+
+ assertEquals(NAME,method.getName());
+
+ assertEquals(DESCRIPTION,method.getDescription());
+
+ assertEquals(method.getDescription(),info.getDescription());
+ assertEquals(method.getName(),info.getName());
+ }
+}
diff --git a/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/QpidNumberPropertyTest.java b/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/QpidNumberPropertyTest.java
new file mode 100644
index 0000000000..374011d150
--- /dev/null
+++ b/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/QpidNumberPropertyTest.java
@@ -0,0 +1,171 @@
+/*
+ *
+ * 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.domain.model;
+
+import junit.framework.TestCase;
+
+import org.apache.qpid.management.configuration.Configurator;
+import org.apache.qpid.management.domain.model.type.Uint8;
+
+public class QpidNumberPropertyTest extends TestCase
+{
+ private QpidProperty _property;
+ private Long _value = 55432L;
+
+ @Override
+ protected void setUp () throws Exception
+ {
+ Configurator configurator = new Configurator();
+ configurator.configure();
+ _property = new QpidProperty();
+ _property.setName("average");
+ _property.setAccessMode(AccessMode.RW);
+ _property.setType(new Uint8());
+ }
+
+ /**
+ * Tests the validation of a qpid property when the type is a number and no constraint has been set.
+ *
+ * <br>precondition : property type is a string, no constraint has been set.
+ * <br>postcondition : no exception is thrown and the validation succeeds.
+ */
+ public void testValidationWithoutConstraints() {
+ try
+ {
+ _property.validate(_value);
+ } catch (ValidationException notExpected)
+ {
+ fail("If no constraint has been set on this property why the validation is failing?");
+ }
+ }
+
+ /**
+ * Tests the validation of a qpid property when the type is a number and a max value constraint has been set.
+ *
+ * <br>precondition : property type is a number, max value has been set and property value is greater than max value.
+ * <br>postcondition : an exception is thrown indicating the validation failure.
+ */
+ public void testValidationKO_withMaxValue() {
+ int maxValue = (int)(_value-1);
+ _property.setMaxValue(maxValue);
+
+ try
+ {
+ _property.validate(_value);
+ fail("The given value is violating the installed constraint so an exception must be thrown.");
+ } catch (ValidationException expected)
+ {
+ assertEquals(ValidationException.MAX_VALUE,expected.getConstraintName());
+ assertEquals(maxValue,expected.getConstraintValue());
+ assertEquals((double)_value,expected.getFeatureValue());
+ assertEquals(_property.getName(),expected.getFeatureName());
+ }
+ }
+
+ /**
+ * Tests the validation of a qpid property when the type is a number and a min value constraint has been set.
+ *
+ * <br>precondition : property type is a number, min value has been set and property value is lesser than min value.
+ * <br>postcondition : an exception is thrown indicating the validation failure.
+ */
+ public void testValidationKO_withMinValue() {
+ int minValue = (int)(_value+1);
+ _property.setMinValue(minValue);
+
+ try
+ {
+ _property.validate(_value);
+ fail("The given value is violating the installed constraint so an exception must be thrown.");
+ } catch (ValidationException expected)
+ {
+ assertEquals(ValidationException.MIN_VALUE,expected.getConstraintName());
+ assertEquals(minValue,expected.getConstraintValue());
+ assertEquals((double)_value,expected.getFeatureValue());
+ assertEquals(_property.getName(),expected.getFeatureName());
+ }
+ }
+
+
+ /**
+ * Tests the validation of a qpid property when the number is a string and the property value is null.
+ *
+ * <br>precondition : property type is a number and property value is null..
+ * <br>postcondition : no exception is thrown. That is : the validation succeeds.
+ */
+ public void testValidationOK_withNullValue() {
+ try
+ {
+ _property.validate(null);
+ } catch (ValidationException notExpected)
+ {
+ fail("No constraint has been violated so validate() shouldn't raise an exception.");
+ }
+
+ _property.setMinValue(1);
+ _property.setMaxValue(10);
+
+ try
+ {
+ _property.validate(null);
+ } catch (ValidationException notExpected)
+ {
+ fail("No constraint has been violated so validate() shouldn't raise an exception.");
+ }
+ }
+
+ /**
+ * Tests the validation of a qpid property when the type is a number and a max / min constraints have been set.
+ *
+ * <br>precondition : property type is a number, max / min constraint have been set and property value is wrong.
+ * <br>postcondition : an exception is thrown indicating the validation failure.
+ */
+ public void testValidationOK_withMinAndMaxConstraint() {
+ int minValue = (int)(_value+1);
+ int maxValue = (int)(_value-1);
+ _property.setMinValue(minValue);
+ _property.setMaxValue(maxValue);
+
+ try
+ {
+ _property.validate(_value);
+ fail("The given value is violating the installed constraint so an exception must be thrown.");
+ } catch (ValidationException expected)
+ {
+ assertEquals(ValidationException.MIN_VALUE,expected.getConstraintName());
+ assertEquals(minValue,expected.getConstraintValue());
+ assertEquals((double)_value,expected.getFeatureValue());
+ assertEquals(_property.getName(),expected.getFeatureName());
+ }
+
+ _property.setMinValue(0);
+ try
+ {
+ _property.validate(_value);
+ fail("The given value is violating the installed constraint so an exception must be thrown.");
+ } catch (ValidationException expected)
+ {
+ assertEquals(ValidationException.MAX_VALUE,expected.getConstraintName());
+ assertEquals(maxValue,expected.getConstraintValue());
+ assertEquals((double)_value,expected.getFeatureValue());
+ assertEquals(_property.getName(),expected.getFeatureName());
+ }
+ }
+}
diff --git a/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/QpidPackageTest.java b/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/QpidPackageTest.java
new file mode 100644
index 0000000000..b7eb9055ba
--- /dev/null
+++ b/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/QpidPackageTest.java
@@ -0,0 +1,53 @@
+/*
+ *
+ * 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.domain.model;
+
+import org.apache.qpid.management.TestConstants;
+
+/**
+ * Test case for Qpid package entity.
+ *
+ * @author Andrea Gazzarini
+ */
+public class QpidPackageTest extends BaseDomainModelTestCase
+{
+ private QpidPackage _qpidPackage;
+
+ @Override
+ protected void setUp () throws Exception
+ {
+ _qpidPackage = new QpidPackage(TestConstants.QPID_PACKAGE_NAME, TestConstants.DOMAIN_MODEL);
+ }
+
+ /**
+ * Tests the association of a new class with a qpid package.
+ *
+ * <br>precondition : the package is not associated with any class.
+ * <br>postcondition : the package is now associated with the given class.
+ */
+ public void testAddClass() throws UnableToBuildFeatureException {
+ assertFalse(_qpidPackage.alreadyContainsClassDefinition(TestConstants.EXCHANGE_CLASS_NAME, TestConstants.HASH));
+
+ _qpidPackage.getQpidClass(TestConstants.EXCHANGE_CLASS_NAME, TestConstants.HASH, true);
+
+ assertTrue(_qpidPackage.alreadyContainsClassDefinition(TestConstants.EXCHANGE_CLASS_NAME, TestConstants.HASH));
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/QpidPropertyBuilderTest.java b/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/QpidPropertyBuilderTest.java
new file mode 100644
index 0000000000..8ad177645c
--- /dev/null
+++ b/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/QpidPropertyBuilderTest.java
@@ -0,0 +1,269 @@
+/*
+ *
+ * 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.domain.model;
+
+import static org.apache.qpid.management.domain.model.QpidFeatureBuilder.Attribute.access;
+import static org.apache.qpid.management.domain.model.QpidFeatureBuilder.Attribute.index;
+import static org.apache.qpid.management.domain.model.QpidFeatureBuilder.Attribute.max;
+import static org.apache.qpid.management.domain.model.QpidFeatureBuilder.Attribute.min;
+import static org.apache.qpid.management.domain.model.QpidFeatureBuilder.Attribute.optional;
+import static org.apache.qpid.management.domain.model.QpidFeatureBuilder.Attribute.type;
+import static org.apache.qpid.management.domain.model.QpidFeatureBuilder.Attribute.unit;
+
+import javax.management.MBeanAttributeInfo;
+
+import org.apache.qpid.management.configuration.UnknownTypeCodeException;
+import org.apache.qpid.management.domain.model.QpidFeatureBuilder.Attribute;
+
+/**
+ * Test case for Qpid Property builder.
+ *
+ * @author Andrea Gazzarini
+ */
+public class QpidPropertyBuilderTest extends BaseQpidFeatureBuilderTestCase
+{
+ private final static Integer MIN = 0;
+ private final static Integer MAX = 120;
+ private final static String UNIT = "bytes";
+
+ private Integer _access;
+
+ @Override
+ protected void setUp () throws Exception
+ {
+ super.setUp();
+
+ _access = 1;
+ _featureDefinition.put(access.name(), _access);
+ _featureDefinition.put(unit.name(),UNIT);
+ _featureDefinition.put(min.name(), MIN);
+ _featureDefinition.put(max.name(),MAX);
+
+ _featureDefinition.put(type.name(), 1);
+ _featureDefinition.put(optional.name(),0);
+ _featureDefinition.put(index.name(), 0);
+
+ _builder = QpidFeatureBuilder.createPropertyBuilder(_featureDefinition);
+ }
+
+ /**
+ * Tests the build process for a statistic when the definition map contains an unknown type code.
+ *
+ * <br>precondition : the statistic definiton map contains an unknown type code.
+ * <br>postcondition : an exception is thrown indicating the failure.
+ */
+ public void testStatisticBuilderKO_WithUnknownType()
+ {
+ int unknownTypeCode =999;
+ try
+ {
+ _featureDefinition.put(type.name(), unknownTypeCode);
+ _builder.build();
+ fail("An unknown type code should raise an exception to indicate a failure.");
+ } catch (UnableToBuildFeatureException expected)
+ {
+ assertEquals(unknownTypeCode,((UnknownTypeCodeException)expected.getCause()).getCode());
+ }
+ }
+
+ /**
+ * Tests the build process for a statistic when the definition map contains a null value for a metadata attribute.
+ *
+ * <br>precondition : the statistic definiton map contains a null value for a metadata attribute.
+ * <br>postcondition : an exception is thrown indicating the failure.
+ */
+ public void testMethodBuilderKO_WithNullMetadataValue()
+ {
+ try
+ {
+ _featureDefinition.put(type.name(), null);
+ _builder.build();
+ fail("An null value for a metadata attribute should raise an exception to indicate a failure.");
+ } catch (UnableToBuildFeatureException expected)
+ {
+ assertTrue(expected.getCause() instanceof NullPointerException);
+ }
+ }
+
+ /**
+ * Tests the build process for a property when the definition map contains an invalid metadata type.
+ *
+ * <br>precondition : the property definiton map contains a wrong type for a metadata attribute.
+ * <br>postcondition : an exception is thrown indicating the failure.
+ */
+ public void testPropertyBuilderKO_WithClassCastException()
+ {
+ try
+ {
+ _featureDefinition.put(access.name(), new String("a"));
+ _builder.build();
+ fail("A wrong metadata attribute type should raise an exception to indicate a failure.");
+ } catch (UnableToBuildFeatureException expected)
+ {
+ assertTrue(expected.getCause() instanceof ClassCastException);
+ }
+ }
+
+ /**
+ * Tests the build process for a property when the definition map contains an unknown type code.
+ *
+ * <br>precondition : the property definiton map contains an unknown type code.
+ * <br>postcondition : an exception is thrown indicating the failure.
+ */
+ public void testPropertyBuilderKO_WithUnknownType()
+ {
+ int unknownTypeCode = 999;
+ try
+ {
+ _featureDefinition.put(type.name(), unknownTypeCode);
+ _builder.build();
+ fail("An unknown type code should raise an exception to indicate a failure.");
+ } catch (UnableToBuildFeatureException expected)
+ {
+ assertEquals(unknownTypeCode,((UnknownTypeCodeException)expected.getCause()).getCode());
+ }
+ }
+
+ /**
+ * Tests the build process for a property when the definition map doesn't contains type attribute.
+ *
+ * <br>precondition: definition map doesn't contains type attribute.
+ * <br>postcondition : an exception should be thrown indicating the failure. That exception must contain the name of the
+ * missing attribute.
+ */
+ public void testPropertyBuilderKO_WithMissingType()
+ {
+ internalTestForMissingMandatoryAttribute(Attribute.type);
+ }
+
+ /**
+ * Tests the build process for a property when the definition map doesn't contain type & name attributes.
+ *
+ * <br>precondition: definition map doesn't contain type & name attributes.
+ * <br>postcondition : an exception should be thrown indicating the failure. That exception must contain the name of the
+ * missing attributes.
+ */
+ public void testPropertyBuilderKO_WithMissingTypeAndName()
+ {
+ internalTestForMissingMandatoryAttribute(Attribute.type, Attribute.name);
+ }
+
+ /**
+ * Tests the build process for a property when the definition map doesn't contain type & name & index attributes.
+ *
+ * <br>precondition: definition map doesn't contain type & name & index attributes.
+ * <br>postcondition : an exception should be thrown indicating the failure. That exception must contain the name of the
+ * missing attributes.
+ */
+ public void testPropertyBuilderKO_WithMissingTypeAndNameAndIndex()
+ {
+ internalTestForMissingMandatoryAttribute(Attribute.type, Attribute.name,Attribute.index);
+ }
+
+ /**
+ * Tests the build process for a property when the definition map doesn't contain type, name, index & optional attributes.
+ *
+ * <br>precondition: definition map doesn't contain type, name, index & optional attributes.
+ * <br>postcondition : an exception should be thrown indicating the failure. That exception must contain the name of the
+ * missing attributes.
+ */
+ public void testPropertyBuilderKO_WithMissingTypeAndNameAndIndexAndOptional()
+ {
+ internalTestForMissingMandatoryAttribute(Attribute.type, Attribute.name,Attribute.index,Attribute.optional);
+ }
+
+ /**
+ * Tests the build process for a property when the definition map doesn't contain type, name, index, optional and access
+ * attributes.
+ *
+ * <br>precondition: definition map doesn't contain type, name, index, optional and access attributes.
+ * <br>postcondition : an exception should be thrown indicating the failure. That exception must contain the name of the
+ * missing attributes.
+ */
+ public void testPropertyBuilderKO_WithMissingTypeAndNameAndIndexAndOptionalAndAccess()
+ {
+ internalTestForMissingMandatoryAttribute(Attribute.type, Attribute.name,Attribute.index,Attribute.optional,Attribute.access);
+ }
+
+ /**
+ * Tests the build process for a property when the definition map doesn't unit attribute.
+ * Note that this attribute is optional and therefore the build must succeed.
+ *
+ * <br>precondition: definition map doesn't contain unit attribute.
+ * <br>postcondition : no exception is thrown and the property is built.
+ */
+ public void testBuilderOK_WithMissingUnit() throws UnableToBuildFeatureException
+ {
+ internalTestForMissingOptionalAttribute(Attribute.unit);
+ }
+
+ /**
+ * Tests the build process for a property when the definition map doesn't min and max attributes.
+ * Note that those attributes are optional and therefore the build must succeed.
+ *
+ * <br>precondition: definition map doesn't contain min and max attributes.
+ * <br>postcondition : no exception is thrown and the property is built.
+ */
+ public void testBuilderOK_WithMissingMinAndMax() throws UnableToBuildFeatureException
+ {
+ internalTestForMissingOptionalAttribute(Attribute.min,Attribute.max);
+ }
+
+ /**
+ * Tests the build process for a property when the definition map doesn't description attribute.
+ * Note that this attribute is optional and therefore the build must succeed.
+ *
+ * <br>precondition: definition map doesn't contain description attribute.
+ * <br>postcondition : no exception is thrown and the property is built.
+ */
+ public void testBuilderOK_WithMissingDescription() throws UnableToBuildFeatureException
+ {
+ internalTestForMissingOptionalAttribute(Attribute.desc);
+ }
+
+ /**
+ * Tests the build process for a property when the definition map contains valid values.
+ *
+ * <br>precondition : the property definiton map contains valid values.
+ * <br>postcondition : no exception is thrown and the property is built as expected.
+ */
+ public void testPropertyBuilderOK() throws UnableToBuildFeatureException
+ {
+ _builder.build();
+
+ QpidProperty property = (QpidProperty) _builder.getQpidFeature();
+ MBeanAttributeInfo info = (MBeanAttributeInfo) _builder.getManagementFeature();
+
+ assertEquals(NAME,property.getName());
+ assertEquals(AccessMode.RC,property.getAccessMode());
+ assertEquals(UNIT,property.getUnit());
+ assertEquals(MIN.intValue(),property.getMinValue());
+ assertEquals(MAX.intValue(),property.getMaxValue());
+ assertEquals(Integer.MIN_VALUE,property.getMaxLength());
+ assertEquals(DESCRIPTION,property.getDescription());
+ assertEquals(Short.class,property.getJavaType());
+ assertFalse(property.isOptional());
+
+ assertEquals(property.getDescription(),info.getDescription());
+ assertEquals(property.getName(),info.getName());
+ assertEquals(property.getJavaType().getName(),info.getType());
+ }
+}
diff --git a/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/QpidStatisticBuilderTest.java b/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/QpidStatisticBuilderTest.java
new file mode 100644
index 0000000000..b7a8540b2d
--- /dev/null
+++ b/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/QpidStatisticBuilderTest.java
@@ -0,0 +1,159 @@
+/*
+ *
+ * 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.domain.model;
+
+import static org.apache.qpid.management.domain.model.QpidFeatureBuilder.Attribute.type;
+import static org.apache.qpid.management.domain.model.QpidFeatureBuilder.Attribute.unit;
+
+import javax.management.MBeanAttributeInfo;
+
+import org.apache.qpid.management.configuration.UnknownTypeCodeException;
+import org.apache.qpid.management.domain.model.QpidFeatureBuilder.Attribute;
+
+/**
+ * Test case for Qpid Statistic builder.
+ *
+ * @author Andrea Gazzarini
+ */
+public class QpidStatisticBuilderTest extends BaseQpidFeatureBuilderTestCase
+{
+ private final static String UNIT = "bytes";
+
+ @Override
+ protected void setUp () throws Exception
+ {
+ super.setUp();
+ _featureDefinition.put(unit.name(),UNIT);
+ _featureDefinition.put(type.name(), 1);
+
+ _builder = QpidFeatureBuilder.createStatisticBuilder(_featureDefinition);
+ }
+
+ /**
+ * Tests the build process for a statistic when the definition map contains an unknown type code.
+ *
+ * <br>precondition : the statistic definiton map contains an unknown type code.
+ * <br>postcondition : an exception is thrown indicating the failure.
+ */
+ public void testStatisticBuilderKO_WithUnknownType()
+ {
+ int unknownTypeCode = 999;
+ try
+ {
+ _featureDefinition.put(type.name(), unknownTypeCode);
+ _builder.build();
+ fail("An unknown type code should raise an exception to indicate a failure.");
+ } catch (UnableToBuildFeatureException expected)
+ {
+ assertEquals(unknownTypeCode,((UnknownTypeCodeException)expected.getCause()).getCode());
+ }
+ }
+
+ /**
+ * Tests the build process for a statistic when the definition map contains a null value for a metadata attribute.
+ *
+ * <br>precondition : the statistic definiton map contains a null value for a metadata attribute.
+ * <br>postcondition : an exception is thrown indicating the failure.
+ */
+ public void testMethodBuilderKO_WithNullMetadataValue()
+ {
+ try
+ {
+ _featureDefinition.put(type.name(), null);
+ _builder.build();
+ fail("An null value for a metadata attribute should raise an exception to indicate a failure.");
+ } catch (UnableToBuildFeatureException expected)
+ {
+ assertTrue(expected.getCause() instanceof NullPointerException);
+ }
+ }
+
+ /**
+ * Tests the build process for a statistic when the definition map doesn't contains type attribute.
+ *
+ * <br>precondition: definition map doesn't contains type attribute.
+ * <br>postcondition : an exception should be thrown indicating the failure. That exception must contain the name of the
+ * missing attribute.
+ */
+ public void testStatisticBuilderKO_WithMissingType()
+ {
+ internalTestForMissingMandatoryAttribute(Attribute.type);
+ }
+
+ /**
+ * Tests the build process for a statistic when the definition map doesn't contain type & name attributes.
+ *
+ * <br>precondition: definition map doesn't contain type & name attributes.
+ * <br>postcondition : an exception should be thrown indicating the failure. That exception must contain the name of the
+ * missing attributes.
+ */
+ public void testStatisticBuilderKO_WithMissingTypeAndName()
+ {
+ internalTestForMissingMandatoryAttribute(Attribute.type, Attribute.name);
+ }
+
+ /**
+ * Tests the build process for a statistic when the definition map doesn't contain type, name, index & optional attributes.
+ *
+ * <br>precondition: definition map doesn't contain type, name, index & optional attributes.
+ * <br>postcondition : an exception should be thrown indicating the failure. That exception must contain the name of the
+ * missing attributes.
+ */
+ public void testStatisticBuilderOK_WithMissingUnit() throws UnableToBuildFeatureException
+ {
+ internalTestForMissingOptionalAttribute(Attribute.unit);
+ }
+
+ /**
+ * Tests the build process for a statistic when the definition map doesn't unit attribute.
+ * Note that this attribute is optional and therefore the build must succeed.
+ *
+ * <br>precondition: definition map doesn't contain unit attribute.
+ * <br>postcondition : no exception is thrown and the statistic is built.
+ */
+ public void testBuilderOK_WithMissingDescription() throws UnableToBuildFeatureException
+ {
+ internalTestForMissingOptionalAttribute(Attribute.desc);
+ }
+
+ /**
+ * Tests the build process for a statistic when the definition map contains valid values.
+ *
+ * <br>precondition : the statistic definiton map contains valid values.
+ * <br>postcondition : no exception is thrown and the statistisc is built as expected.
+ */
+ public void testStatisticBuilderOK() throws UnableToBuildFeatureException
+ {
+ _builder.build();
+
+ QpidStatistic statistic= (QpidStatistic) _builder.getQpidFeature();
+ MBeanAttributeInfo info = (MBeanAttributeInfo) _builder.getManagementFeature();
+
+ assertEquals(NAME,statistic.getName());
+ assertEquals(UNIT,statistic.getUnit());
+ assertEquals(DESCRIPTION,statistic.getDescription());
+ assertEquals(Short.class,statistic.getJavaType());
+
+ assertEquals(statistic.getDescription(),info.getDescription());
+ assertEquals(statistic.getName(),info.getName());
+ assertEquals(statistic.getJavaType().getName(),info.getType());
+ }
+}
diff --git a/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/QpidStringPropertyTest.java b/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/QpidStringPropertyTest.java
new file mode 100644
index 0000000000..8aeb7c8550
--- /dev/null
+++ b/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/QpidStringPropertyTest.java
@@ -0,0 +1,127 @@
+/*
+ *
+ * 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.domain.model;
+
+import junit.framework.TestCase;
+
+import org.apache.qpid.management.configuration.Configurator;
+import org.apache.qpid.management.domain.model.type.Str16;
+
+public class QpidStringPropertyTest extends TestCase
+{
+ private QpidProperty _property;
+ private final String _5LettersString = "12345";
+
+ @Override
+ protected void setUp () throws Exception
+ {
+ Configurator configurator = new Configurator();
+ configurator.configure();
+ _property = new QpidProperty();
+ _property.setName("name");
+ _property.setAccessMode(AccessMode.RW);
+ _property.setType(new Str16());
+ }
+
+ /**
+ * Tests the validation of a qpid property when the type is a string and a max length constraint hasn't been set.
+ *
+ * <br>precondition : property type is a string, max length hasn't been set.
+ * <br>postcondition : no exception is thrown. That is : the validation succeeds.
+ */
+ public void testValidationWithoutMaxLength() {
+ try
+ {
+ _property.validate(_5LettersString);
+ } catch (ValidationException notExpected)
+ {
+ fail("No max length has been set on property so validation must succeed.");
+ }
+ }
+
+ /**
+ * Tests the validation of a qpid property when the type is a string and a max length constraint has been set.
+ *
+ * <br>precondition : property type is a string, max length has been set and property value is longer than max length.
+ * <br>postcondition : an exception is thrown indicating the validation failure.
+ */
+ public void testValidationKO_withMaxLength() {
+ int maxLength = 2;
+ _property.setMaxLength(maxLength);
+
+ try
+ {
+ _property.validate(_5LettersString);
+ fail("No max length has been set on property so validation must proceed.");
+ } catch (ValidationException expected)
+ {
+ assertEquals(ValidationException.MAX_LENGTH,expected.getConstraintName());
+ assertEquals(maxLength,expected.getConstraintValue());
+ assertEquals(_5LettersString.length(),expected.getFeatureValue());
+ assertEquals(_property.getName(),expected.getFeatureName());
+ }
+ }
+
+ /**
+ * Tests the validation of a qpid property when the type is a string and the property value is null.
+ *
+ * <br>precondition : property type is a string and property value is null..
+ * <br>postcondition : no exception is thrown. That is : the validation succeeds.
+ */
+ public void testValidationOK_withNullValue() {
+ try
+ {
+ _property.validate(null);
+ } catch (ValidationException notExpected)
+ {
+ fail("No constraint has been violated so validate() shouldn't raise an exception.");
+ }
+
+ _property.setMaxLength(1);
+
+ try
+ {
+ _property.validate(null);
+ } catch (ValidationException notExpected)
+ {
+ fail("No constraint has been violated so validate() shouldn't raise an exception.");
+ }
+ }
+
+ /**
+ * Tests the validation of a qpid property when the type is a string and a max length constraint has been set.
+ *
+ * <br>precondition : property type is a string, max length has been set and property value is not violating that.
+ * <br>postcondition : no exception is thrown. That is : the validation succeeds.
+ */
+ public void testValidationOK_withMaxLength() {
+ int maxLength = (_5LettersString.length()+1);
+ _property.setMaxLength(maxLength);
+
+ try
+ {
+ _property.validate(_5LettersString);
+ } catch (ValidationException notExpected)
+ {
+ fail("No constraint has been violated so validate() shouldn't raise an exception.");
+ }
+ }
+}
diff --git a/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/type/BinaryTest.java b/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/type/BinaryTest.java
new file mode 100644
index 0000000000..6636c08710
--- /dev/null
+++ b/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/type/BinaryTest.java
@@ -0,0 +1,59 @@
+/*
+ *
+ * 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.domain.model.type;
+
+import junit.framework.TestCase;
+
+/**
+ * Test case for "Binary" type.
+ *
+ * @author Andrea Gazzarini
+ */
+public class BinaryTest extends TestCase
+{
+ /**
+ * Tests the lazy & once hash code computation behaviour of the binary type.
+ */
+ public void testHashCodeComputation(){
+ Binary binary = new Binary(new byte[]{1,2,3,4,5,6,7,6,3,3});
+ assertSame(binary.state,binary.hashCodeNotYetComputed);
+
+ int firstResult = binary.hashCode();
+ assertSame(binary.state,binary.hashCodeAlreadyComputed);
+
+ int secondResult = binary.hashCode();
+ assertSame(binary.state,binary.hashCodeAlreadyComputed);
+ assertEquals(firstResult,secondResult);
+ }
+
+ /**
+ * Tests the equals() method of the binary class.
+ * Two binary must be equals only if they contain the same array (that is, two arrays with the same size & content)
+ */
+ public void testIdentity() {
+ Binary binary = new Binary(new byte[]{1,2,3,4,5,6,7,6,3,3});
+ Binary theSame= new Binary(new byte[]{1,2,3,4,5,6,7,6,3,3});
+ Binary aDifferentOne = new Binary(new byte[]{4,2,3,3,4,4,5,3,3,2});
+
+ assertTrue(binary.equals(theSame));
+ assertFalse(binary.equals(aDifferentOne));
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/services/BrokerMessageListenerTest.java b/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/services/BrokerMessageListenerTest.java
new file mode 100644
index 0000000000..805c039a6f
--- /dev/null
+++ b/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/services/BrokerMessageListenerTest.java
@@ -0,0 +1,241 @@
+/*
+ *
+ * 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.domain.services;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Random;
+
+import junit.framework.TestCase;
+
+import org.apache.qpid.api.Message;
+import org.apache.qpid.management.TestConstants;
+import org.apache.qpid.management.domain.handler.base.IMessageHandler;
+import org.apache.qpid.management.domain.model.DomainModel;
+import org.apache.qpid.nclient.util.ByteBufferMessage;
+import org.apache.qpid.transport.codec.Decoder;
+
+/**
+ * Test case for Broker Message Listener.
+ *
+ * @author Andrea Gazzarini
+ */
+public class BrokerMessageListenerTest extends TestCase
+{
+ // An empty message handler user for test.
+ private IMessageHandler _emptyMessageHandler = new IMessageHandler()
+ {
+ public void process (Decoder decoder, int sequenceNumber)
+ {
+ }
+ public void setDomainModel (DomainModel domainModel)
+ {
+ }
+ };
+
+ // Another empty message handler user for test.
+ private IMessageHandler _anotherEmptyMessageHandler = new IMessageHandler()
+ {
+ public void process (Decoder decoder, int sequenceNumber)
+ {
+ }
+ public void setDomainModel (DomainModel domainModel)
+ {
+ }
+ };
+
+ private Map<Character,IMessageHandler> _handlers = new HashMap<Character, IMessageHandler>();
+ private BrokerMessageListener _listener;
+ private final char opcode1 = 'x';
+ private final char opcode2 = 'y';
+
+
+ @Override
+ protected void setUp () throws Exception
+ {
+ DomainModel domainModel = new DomainModel(TestConstants.BROKER_ID);
+ _listener = new BrokerMessageListener(domainModel);
+
+ _handlers.put(opcode1, _emptyMessageHandler);
+ _handlers.put(opcode2, _anotherEmptyMessageHandler);
+ }
+
+ /**
+ * Tests the installation of message handlers on a broker message listener.
+ *
+ * <br>precondition : no message handler has been installed on message listener.
+ * <br>postcondition : two message handlers are installed on message listener.
+ */
+ public void testSetHandlersOK()
+ {
+ assertTrue(
+ "No handler has yet been installed so how is it possible that the handlers map is not empty?",
+ _listener._handlers.isEmpty());
+
+ _listener.setHandlers(_handlers);
+
+ assertEquals("Now we should have two handlers configured.",2,_listener._handlers.size());
+ assertSame(_listener._handlers.get(opcode1),_emptyMessageHandler);
+ assertSame(_listener._handlers.get(opcode2),_anotherEmptyMessageHandler);
+ }
+
+ /**
+ * Tests the installation of message handlers on a broker message listener.
+ * Specifically it tries to install three message handlers and one of them is throwing an exception at installation time.
+ *
+ * <br>precondition : no message handler has been installed on message listener.
+ * <br>postcondition : two message handlers are installed on message listener. (the one that thrown exception has been
+ * discarded).
+ */
+ public void testSetHandlerOK()
+ {
+ IMessageHandler wrongMessageHandler = new IMessageHandler()
+ {
+
+ public void process (Decoder decoder, int sequenceNumber)
+ {
+ }
+
+ public void setDomainModel (DomainModel domainModel)
+ {
+ throw new RuntimeException();
+ }
+ };
+
+ char opcodeForWrongHandler = 'k';
+
+ assertTrue(
+ "No handler has yet been installed so how is it possible that the handlers map is not empty?",
+ _listener._handlers.isEmpty());
+
+ _handlers.put(opcodeForWrongHandler,wrongMessageHandler);
+
+ _listener.setHandlers(_handlers);
+
+ assertEquals("Now we should have two handlers configured.",2,_listener._handlers.size());
+ assertSame(_listener._handlers.get(opcode1),_emptyMessageHandler);
+ assertSame(_listener._handlers.get(opcode2),_anotherEmptyMessageHandler);
+ assertNull(_listener._handlers.get(opcodeForWrongHandler));
+ }
+
+ /**
+ * Tests the execution of the onMessage() method when a message with a bad magic number is received.
+ *
+ * <br>precondition : a message with a bad magic number is received.
+ * <br>postcondition : the processing of the incoming message is skipped and therefore no handler will be called.
+ */
+ public void testOnMessageKO_withBadMagicNumber() throws IOException
+ {
+ IMessageHandler neverCallMe = new IMessageHandler()
+ {
+
+ public void process (Decoder decoder, int sequenceNumber)
+ {
+ fail("This test shouldn't never arrive at this point...");
+ }
+
+ public void setDomainModel (DomainModel domainModel)
+ {
+ }
+ };
+
+ String opcodeForNeverCallMeHandler = "w";
+
+ _handlers.put('w',neverCallMe);
+ _listener.setHandlers(_handlers);
+
+ Message message = new ByteBufferMessage();
+ message.appendData( ("AMG"+opcodeForNeverCallMeHandler).getBytes());
+
+ _listener.onMessage(message);
+ }
+
+ /**
+ * Tests the execution of the onMessage() method when the incoming message is a compound message.
+ *
+ * <br>precondition : the incoming message is a compound message.
+ * <br>postcondition : each tokenized message is forwarded to the appropriate handler.
+ */
+ public void testOnMessageOK_WithCompoundMessage() throws Exception
+ {
+ final Map<Character,IMessageHandler> handlersMap = new HashMap<Character,IMessageHandler>();
+ char [] opcodes = {'a','b','c','d','e'};
+
+ class MockMessageHandler implements IMessageHandler
+ {
+ private final char _opcode;
+
+ public MockMessageHandler(char opcode)
+ {
+ this._opcode = opcode;
+ }
+
+ public void process (Decoder decoder, int sequenceNumber)
+ {
+ handlersMap.remove(_opcode);
+ }
+
+ public void setDomainModel (DomainModel domainModel)
+ {
+ // Do nothing here. It's just a mock handler.
+ }
+ };
+
+ for (char opcode : opcodes)
+ {
+ handlersMap.put(opcode, new MockMessageHandler(opcode));
+ }
+
+ // Removes previously injected handlers (i.e. x & y)
+ _listener._handlers.clear();
+ _listener.setHandlers(handlersMap);
+
+ Message compoundMessage = createCompoundMessage(opcodes);
+ _listener.onMessage(compoundMessage);
+
+ assertTrue(handlersMap.isEmpty());
+ }
+
+ // Creates a (non valid) compound message.
+ private Message createCompoundMessage(char[] opcodes) throws IOException {
+ byte [] compoundMessageData = new byte [12 * opcodes.length];
+ Random randomizer = new Random();
+ int position = 0;
+
+ for (char opcode : opcodes) {
+ System.arraycopy(MessageTokenizer.MAGIC_NUMBER_BYTES, 0, compoundMessageData, position, MessageTokenizer.MAGIC_NUMBER_BYTES.length);
+ position+=MessageTokenizer.MAGIC_NUMBER_BYTES.length;
+
+ compoundMessageData[position++] = (byte)opcode;
+
+ for (int c = 4; c < 12; c++)
+ {
+ byte aByte = (byte)randomizer.nextInt(127);
+ compoundMessageData[position++] = aByte;
+ }
+ }
+
+ Message compoundMessage = new ByteBufferMessage();
+ compoundMessage.appendData(compoundMessageData);
+ return compoundMessage;
+ }
+}
diff --git a/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/services/MessageTokenizerTest.java b/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/services/MessageTokenizerTest.java
new file mode 100644
index 0000000000..55b8b17f9d
--- /dev/null
+++ b/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/services/MessageTokenizerTest.java
@@ -0,0 +1,140 @@
+/*
+*
+ * 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.domain.services;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.util.*;
+
+import junit.framework.TestCase;
+
+import org.apache.qpid.api.Message;
+import org.apache.qpid.nclient.util.ByteBufferMessage;
+import org.apache.qpid.transport.codec.BBDecoder;
+
+/**
+ * Tests case for messaeg tokenizer.
+ *
+ * @author Andrea Gazzarini
+ */
+public class MessageTokenizerTest extends TestCase {
+
+ /**
+ * Tests the execution of the message tokenizer when the given message is not a valid AMQP message.
+ *
+ * <br>precondition : the incoming message is not a valid AMQP message.
+ * <br>postcondition : no exception is thrown and there will be exactly one token with the given message.
+ */
+ public void testOK_WithNoMessage() throws IOException{
+ byte [] noMessage = {2,10,120,23,23,23,4,10,11,12,2,1,3,-22};
+
+ Message multiMessage = new ByteBufferMessage();
+ multiMessage.appendData(noMessage);
+ MessageTokenizer tokenizer = new MessageTokenizer(multiMessage);
+
+ assertEquals(1, tokenizer.countTokens());
+ assertEquals(tokenizer.nextElement(),noMessage);
+ assertFalse(tokenizer.hasMoreElements());
+ }
+
+ /**
+ * Tests the execution of the message tokenizer when the given message contains only one message.
+ *
+ * <br>precondition : the incoming message contains only one message.
+ * <br>postcondition : no exception is thrown and there will be exactly one token with the given message.
+ */
+ public void testOK_WithOneMessage() throws IOException{
+ byte [] oneEncodedMessage = {'A','M','2',23,23,23,4,10,11,12,2,1,3,-22};
+
+ Message multiMessage = new ByteBufferMessage();
+ multiMessage.appendData(oneEncodedMessage);
+ MessageTokenizer tokenizer = new MessageTokenizer(multiMessage);
+
+ assertEquals(1, tokenizer.countTokens());
+ assertEquals(tokenizer.nextElement(),oneEncodedMessage);
+ assertFalse(tokenizer.hasMoreElements());
+ }
+
+ /**
+ * Tests the execution of the message tokenizer when the given message contains a random number of messages.
+ *
+ * <br>precondition : the incoming message contains a random number of messages.
+ * <br>postcondition : no exception is thrown and each built token is a valid message starting with right header.
+ */
+ public void testOK_WithRandomNUmberOfMessages() throws IOException{
+ Random randomizer = new Random();
+
+ int howManyLoops = randomizer.nextInt(10000);
+ howManyLoops = (howManyLoops == 0) ? 10 : howManyLoops;
+ byte [] compoundMessageData = new byte [12 * howManyLoops];
+
+ List<byte []> messages = new ArrayList<byte[]>(howManyLoops);
+
+ int position = 0;
+ for (int i = 0; i < howManyLoops; i++)
+ {
+ byte [] message = new byte[12];
+ System.arraycopy(MessageTokenizer.MAGIC_NUMBER_BYTES, 0, compoundMessageData, position, MessageTokenizer.MAGIC_NUMBER_BYTES.length);
+ System.arraycopy(MessageTokenizer.MAGIC_NUMBER_BYTES, 0, message, 0, MessageTokenizer.MAGIC_NUMBER_BYTES.length);
+ position+=MessageTokenizer.MAGIC_NUMBER_BYTES.length;
+
+ for (int c = 3; c < 12; c++)
+ {
+ byte aByte = (byte)randomizer.nextInt(127);
+ aByte = (aByte == 77) ? (byte)c : aByte;
+ compoundMessageData[position++] = aByte;
+ message[c] = aByte;
+ }
+ messages.add(message);
+ }
+
+ Message multiMessage = new ByteBufferMessage();
+ multiMessage.appendData(compoundMessageData);
+ MessageTokenizer tokenizer = new MessageTokenizer(multiMessage);
+
+ int howManyTokens = tokenizer.countTokens();
+ assertEquals(howManyLoops, howManyTokens);
+
+ int index = 0;
+ while (tokenizer.hasMoreElements())
+ {
+ assertEquals(tokenizer.nextElement(),messages.get(index++));
+ }
+
+ assertEquals((index),howManyTokens);
+ }
+
+ /**
+ * Internal method used for comparison of two messages.
+ *
+ * @param message the token message just built by the tokenizer.
+ * @param expected the expected result.
+ */
+ private void assertEquals(Message message, byte [] expected) throws IOException
+ {
+ ByteBuffer messageContent = message.readData();
+ BBDecoder decoder = new BBDecoder();
+ decoder.init(messageContent);
+ byte [] content = decoder.readReaminingBytes();
+ assertTrue(Arrays.equals(content, expected));
+ }
+}
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/EnhancedReflectionProxyHandler.java b/qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/EnhancedReflectionProxyHandler.java
new file mode 100644
index 0000000000..615d744546
--- /dev/null
+++ b/qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/EnhancedReflectionProxyHandler.java
@@ -0,0 +1,72 @@
+/*
+ *
+ * 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.ReflectionProxyHandler;
+import org.apache.muse.util.xml.XmlUtils;
+import org.apache.muse.ws.addressing.soap.SoapFault;
+import org.apache.qpid.management.wsdm.muse.serializer.ByteArraySerializer;
+import org.w3c.dom.Element;
+
+/**
+ * Custom implementation of Muse ReflectionProxyHandler
+ * that uses a base64 serializer for byte arrays.
+ * Note that this proxy handler is only needed for tests because it provides
+ * client side Base64 serializer capability.
+ * In a concrete scenario we don't mind what instrument the client is using in order to
+ * propertly serialize byte arrays.
+ *
+ * @author Andrea Gazzarini
+ */
+public class EnhancedReflectionProxyHandler extends ReflectionProxyHandler
+{
+ @Override
+ protected Element serialize(Object obj, QName qname) throws SoapFault
+ {
+ if (obj == null)
+ {
+ return XmlUtils.createElement(qname);
+ }
+
+ if (obj.getClass() == byte[].class)
+ {
+ return new ByteArraySerializer().toXML(obj, qname);
+ } else
+ {
+ return super.serialize(obj, qname);
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ protected Object deserialize(Element xml, Class theClass) throws SoapFault
+ {
+ if (theClass == byte[].class)
+ {
+ return new ByteArraySerializer().fromXML(xml);
+ } else
+ {
+ return super.deserialize(xml, theClass);
+ }
+ }
+} \ 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/ServerThread.java b/qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/ServerThread.java
new file mode 100644
index 0000000000..6574c278ff
--- /dev/null
+++ b/qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/ServerThread.java
@@ -0,0 +1,118 @@
+/*
+ *
+ * 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.io.File;
+
+import org.apache.qpid.management.Names;
+import org.mortbay.component.LifeCycle.Listener;
+import org.mortbay.jetty.Connector;
+import org.mortbay.jetty.Server;
+import org.mortbay.jetty.nio.SelectChannelConnector;
+import org.mortbay.jetty.webapp.WebAppContext;
+import org.mortbay.start.Monitor;
+
+/**
+ * Web Server startup thread.
+ * It is used on adapter test case in order to start the embedded
+ * web server as a separated thread.
+ *
+ * @author Andrea Gazzarini
+ */
+class ServerThread extends Thread
+{
+ private final Listener _lifecycleListener;
+ private Server _server;
+
+ private SelectChannelConnector _connector;
+
+ /**
+ * Builds a new server thread with the given lifecycle listener.
+ *
+ * @param listener the lifecycle listener.
+ */
+ ServerThread(Listener listener)
+ {
+ this._lifecycleListener = listener;
+ }
+
+ /**
+ * Starts the server.
+ */
+ @Override
+ public void run()
+ {
+ try
+ {
+ Monitor.monitor();
+ _server = new Server();
+ _server.setStopAtShutdown(true);
+
+ _connector=new SelectChannelConnector();
+ _connector.setPort(Integer.parseInt(System.getProperty(Names.ADAPTER_PORT_PROPERTY_NAME)));
+ _connector.setHost(System.getProperty(Names.ADAPTER_HOST_PROPERTY_NAME));
+
+
+ _server.setConnectors(new Connector[]{_connector});
+
+ WebAppContext webapp = new WebAppContext();
+ webapp.setContextPath("/qman");
+
+ // Additional web application descriptor containing test components.
+ webapp.setDefaultsDescriptor("/org/apache/qpid/management/wsdm/web.xml");
+
+ String webApplicationPath = System.getProperty("qman.war");
+ File rootFolderPath = (webApplicationPath != null) ? new File(webApplicationPath) : new File(".");
+
+ webapp.setWar(rootFolderPath.toURI().toURL().toExternalForm());
+ webapp.addLifeCycleListener(_lifecycleListener);
+ _server.setHandler(webapp);
+ _server.start();
+ System.setProperty(Names.ADAPTER_PORT_PROPERTY_NAME,String.valueOf( _connector.getLocalPort()));
+ _server.join();
+
+ } catch(Exception exception)
+ {
+ throw new RuntimeException(exception);
+ }
+ }
+
+ /**
+ * Shutdown the server.
+ *
+ * @throws Exception when a problem is encountered during shutdown.
+ */
+ void shutdown() throws Exception
+ {
+ _server.stop();
+ }
+
+ /**
+ * Returns the port number where the server is running.
+ *
+ * @return the port number where the server is running.
+ */
+ int getPort()
+ {
+ return _connector.getLocalPort();
+ }
+
+}
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/WebApplicationLifeCycleListener.java b/qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/WebApplicationLifeCycleListener.java
new file mode 100644
index 0000000000..91c646467e
--- /dev/null
+++ b/qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/WebApplicationLifeCycleListener.java
@@ -0,0 +1,61 @@
+/*
+ *
+ * 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 org.mortbay.component.LifeCycle;
+import org.mortbay.component.LifeCycle.Listener;
+
+/**
+ * Adapter class used to provide an empty (base) implementation of
+ * Lifecycle listener interface.
+ *
+ * Adapter test case needs to be informed about the lifecycle of the
+ * deployed QMan application. Only when its deployment is completed the test
+ * case can run successfully.
+ *
+ * So, following the same logic of Swng event model, this is an adapter that provides
+ * empty implementation of the listener interface (see for example MouseAdapter
+ * for mouse events listener)
+ *
+ * @author Andrea Gazzarini
+ */
+public class WebApplicationLifeCycleListener implements Listener
+{
+ public void lifeCycleFailure(LifeCycle event, Throwable cause)
+ {
+ }
+
+ public void lifeCycleStarted(LifeCycle event)
+ {
+ }
+
+ public void lifeCycleStarting(LifeCycle event)
+ {
+ }
+
+ public void lifeCycleStopped(LifeCycle event)
+ {
+ }
+
+ public void lifeCycleStopping(LifeCycle event)
+ {
+ }
+} \ No newline at end of file
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
new file mode 100644
index 0000000000..f12288c91d
--- /dev/null
+++ b/qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/WsDmAdapterTest.java
@@ -0,0 +1,156 @@
+/*
+ *
+ * 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.io.IOException;
+import java.net.ServerSocket;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
+
+import org.apache.muse.core.serializer.SerializerRegistry;
+import org.apache.qpid.management.Names;
+import org.apache.qpid.management.Protocol;
+import org.apache.qpid.management.wsdm.capabilities.Result;
+import org.apache.qpid.management.wsdm.muse.serializer.DateSerializer;
+import org.apache.qpid.management.wsdm.muse.serializer.InvocationResultSerializer;
+import org.apache.qpid.management.wsdm.muse.serializer.MapSerializer;
+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 junit.extensions.TestSetup;
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+public class WsDmAdapterTest
+{
+
+ /**
+ * Test case wide set up.
+ * Provides Server startup & shutdown global procedure.
+ *
+ * @author Andrea Gazzarini
+ */
+ private static class WsDmAdapterTestSetup extends TestSetup
+ {
+ private Object _serverMonitor = new Object();
+
+ Listener listener = new WebApplicationLifeCycleListener()
+ {
+ public void lifeCycleStarted(LifeCycle event)
+ {
+ synchronized (_serverMonitor)
+ {
+ _serverMonitor.notify();
+ }
+ }
+ };
+
+ private ServerThread _server;
+
+ /**
+ * Builds a new test setup with for the given test.
+ *
+ * @param test the decorated test.
+ */
+ public WsDmAdapterTestSetup(Test test)
+ {
+ super(test);
+ }
+
+ /**
+ * Starts up Web server.
+ *
+ * @throws Exception when the server startup fails.
+ */
+ @Override
+ protected void setUp() throws Exception
+ {
+ SerializerRegistry.getInstance().registerSerializer(Object.class, new ObjectSerializer());
+ SerializerRegistry.getInstance().registerSerializer(Date.class, new DateSerializer());
+ SerializerRegistry.getInstance().registerSerializer(Map.class, new MapSerializer());
+ SerializerRegistry.getInstance().registerSerializer(HashMap.class, new MapSerializer());
+ SerializerRegistry.getInstance().registerSerializer(UUID.class, new UUIDSerializer());
+ SerializerRegistry.getInstance().registerSerializer(Result.class, new InvocationResultSerializer());
+
+ System.setProperty(
+ Names.ADAPTER_HOST_PROPERTY_NAME,
+ Protocol.DEFAULT_QMAN_HOSTNAME);
+
+ System.setProperty(
+ Names.ADAPTER_PORT_PROPERTY_NAME,
+ String.valueOf(getFreePort()));
+
+ _server = new ServerThread(listener);
+ _server.start();
+
+ synchronized(_serverMonitor) {
+ _serverMonitor.wait();
+ Thread.sleep(2000);
+ }
+ }
+
+ @Override
+ protected void tearDown() throws Exception
+ {
+ _server.shutdown();
+ }
+ };
+
+ /**
+ * Gets the test suite composition.
+ *
+ * @return the test suite composition.
+ */
+ public static Test suite()
+ {
+ 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);
+ }
+
+ /**
+ * Finds a free port that will be used to run the embedded
+ * web server.
+ *
+ * @return a free port that will be used to run the
+ * embedded web server.
+ */
+ private static int getFreePort() throws IOException {
+ ServerSocket server = null;
+ try
+ {
+ server = new ServerSocket(0);
+ return server.getLocalPort();
+ } finally
+ {
+ server.close();
+ }
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/capabilities/MBeanCapabilityBuilderTest.java b/qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/capabilities/MBeanCapabilityBuilderTest.java
new file mode 100644
index 0000000000..68c9930ecd
--- /dev/null
+++ b/qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/capabilities/MBeanCapabilityBuilderTest.java
@@ -0,0 +1,335 @@
+/*
+ *
+ * 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 java.lang.management.ManagementFactory;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import javassist.CtClass;
+import javassist.CtMethod;
+
+import javax.management.MBeanAttributeInfo;
+import javax.management.MBeanInfo;
+import javax.management.MBeanOperationInfo;
+import javax.management.MBeanParameterInfo;
+import javax.management.MBeanServer;
+import javax.management.ObjectName;
+import javax.xml.namespace.QName;
+
+import junit.framework.TestCase;
+
+import org.apache.qpid.management.domain.handler.impl.QpidDomainObject;
+import org.apache.qpid.management.wsdm.common.EntityInstanceNotFoundFault;
+import org.apache.qpid.management.wsdm.common.MethodInvocationFault;
+import org.apache.qpid.management.wsdm.common.NoSuchAttributeFault;
+import org.apache.qpid.management.wsdm.common.QManFault;
+
+/**
+ * Test case for MBean capability builder.
+ *
+ * @author Andrea Gazzarini
+ */
+public class MBeanCapabilityBuilderTest extends TestCase
+{
+
+ /**
+ * Management interface for an mbean that has no properties and no
+ * methods.
+ *
+ * @author Andrea Gazzarini
+ */
+ public interface NoPropertiesNoMethodsMBean
+ {
+ }
+
+ /**
+ * Implementation of the managenent interface described above.
+ *
+ * @author Andrea Gazzarini
+ */
+ public class NoPropertiesNoMethods implements NoPropertiesNoMethodsMBean
+ {
+ }
+
+ private MBeanCapabilityBuilder _builder;
+ private ObjectName _objectName;
+
+ /**
+ * Set up fixture for this test case.
+ */
+ protected void setUp() throws Exception
+ {
+ _builder = new MBeanCapabilityBuilder();
+ _objectName = new ObjectName("Test:Name=aName,class=DomainObject");
+ }
+
+ /**
+ * Tests that state change that occcurs on the begin() method when the requested
+ * class has not been defined.
+ */
+ public void testBegin_withClassNotYetDefined() throws Exception
+ {
+ _builder.begin(_objectName);
+ assertEquals(_builder._state,_builder._classNotAvailable);
+ }
+
+ /**
+ * Tests that state change that occcurs on the begin() method when the requested
+ * class has not been defined.
+ */
+ public void testBegin_withClassAlreadyDefined() throws Exception
+ {
+ _objectName = new ObjectName("Test:Name=aString,class=MBeanCapabilityBuilder");
+ _builder.begin(_objectName);
+
+ assertTrue(_builder._state instanceof DummyCapabilityBuilder);
+ assertSame(_builder._endAttributeHandler, _builder._noPropertyHasBeenDefined);
+ }
+
+ /**
+ * Tests the generateGetter method().
+ */
+ public void testGenerateGetter()
+ {
+ String name ="MyProperty";
+ String type = Long.class.getName();
+ String expected =
+ "public "+
+ type+
+ " get"+
+ name+
+ "() throws NoSuchAttributeFault,EntityInstanceNotFoundFault,QManFault { return ("+
+ type+
+ ") getAttribute(\""+
+ name+
+ "\"); }";
+
+ String result = _builder.generateGetter(type, name,name);
+ assertEquals(expected,result);
+ }
+
+ /**
+ * Tests the generateGetter method().
+ */
+ public void testGenerateSetter()
+ {
+ String name ="MyProperty";
+ String type = Long.class.getName();
+ String expected =
+ "public void setMyProperty("+
+ type+
+ " newValue) throws NoSuchAttributeFault,EntityInstanceNotFoundFault,QManFault { setAttribute(\""+
+ name+
+ "\", newValue); }";
+
+ String result = _builder.generateSetter(type, name,name);
+ assertEquals(expected,result);
+ }
+
+ /**
+ * Tests buils of a capability that has no properties and methods
+ *
+ * <br>precondition : the incoming entity definition is empty (no properties and no methods)
+ * <br>postcondition : the capability class is built successfully and has no props and methods.
+ * The getPropertyNames returns an empty QName array.
+ */
+ public void testOK_WithNoPropertiesNoMethods() throws Exception {
+
+ ObjectName name = new ObjectName("Test:Name=NoPropertiesNoMethods");
+
+ MBeanServer server = ManagementFactory.getPlatformMBeanServer();
+ server.registerMBean(new NoPropertiesNoMethods(), name);
+
+ _builder.begin(name);
+ _builder.endAttributes();
+ _builder.endOperations();
+ Class<MBeanCapability> capabilityClass = _builder.getCapabilityClass();
+
+ Field[] fields = capabilityClass.getDeclaredFields();
+ Method [] methods = capabilityClass.getDeclaredMethods();
+
+ assertEquals(Arrays.toString(fields),0,fields.length);
+ assertEquals(Arrays.toString(methods),1,methods.length);
+
+ Method getPropertyNames = methods[0];
+ assertEquals("getPropertyNames",getPropertyNames.getName());
+
+
+ MBeanCapability capability = capabilityClass.newInstance();
+ QName [] properties = (QName[]) getPropertyNames.invoke(capability);
+ assertEquals(0,properties.length);
+ }
+
+ /**
+ * Tests the whole execution of the builder.
+ */
+ @SuppressWarnings("unchecked")
+ public void testBuildOK() throws Exception
+ {
+ MBeanServer server = ManagementFactory.getPlatformMBeanServer();
+ QpidDomainObject mbean = new QpidDomainObject();
+ server.registerMBean(mbean, _objectName);
+
+ _builder.begin(_objectName);
+
+ CtClass definition = _builder._capabilityClassDefinition;
+ assertEquals(
+ MBeanCapability.class.getName(),
+ definition.getSuperclass().getName());
+
+ MBeanInfo metadata = server.getMBeanInfo(_objectName);
+
+ for (MBeanAttributeInfo attribute : metadata.getAttributes())
+ {
+ _builder.onAttribute(attribute);
+ checkAttribute(attribute, definition);
+
+ assertSame(
+ _builder._endAttributeHandler,
+ _builder._atLeastThereIsOneProperty);
+ }
+
+ for (MBeanOperationInfo operation : metadata.getOperations())
+ {
+ _builder.onOperation(operation);
+ checkOperation(operation,definition);
+ }
+
+ _builder.endAttributes();
+ _builder.endOperations();
+
+ assertNotNull(_builder.getCapabilityClass());
+ }
+
+ /**
+ * Checks an operation / method after that it has been declared on
+ * capability definition.
+ *
+ * @param operation the (JMX) operation metadata.
+ * @param definition the capability class definition.
+ * @throws Exception when something goes wrong during introspection.
+ */
+ private void checkOperation(MBeanOperationInfo operation, CtClass definition) throws Exception
+ {
+ CtMethod method = definition.getDeclaredMethod(operation.getName());
+ assertNotNull(method);
+
+ checkExceptionTypes(
+ method.getExceptionTypes(),
+ new String[]{
+ QManFault.class.getName(),
+ EntityInstanceNotFoundFault.class.getName(),
+ MethodInvocationFault.class.getName()});
+
+ assertEquals(Result.class.getName(),method.getReturnType().getName());
+
+ CtClass [] parameterTypes = method.getParameterTypes();
+ MBeanParameterInfo [] parameterMetadata = operation.getSignature();
+
+ assertEquals(parameterTypes.length, parameterMetadata.length);
+ for (int i = 0; i < parameterMetadata.length; i++)
+ {
+ assertEquals(
+ parameterTypes[i].getName(),
+ Class.forName(parameterMetadata[i].getType()).getCanonicalName());
+ }
+ }
+
+ /**
+ * Checks the exception types associated with a method.
+ *
+ * @param exceptionTypes the exception types actually thrown.
+ * @param expectedExceptionNames the expected exception types (as strings).
+ */
+ private void checkExceptionTypes(CtClass [] exceptionTypes, String [] expectedExceptionNames)
+ {
+ List<String> exceptionNames = new ArrayList<String>(exceptionTypes.length);
+ for (CtClass exception : exceptionTypes)
+ {
+ exceptionNames.add(exception.getName());
+ }
+
+ for (String expectedExceptionName : expectedExceptionNames)
+ {
+ exceptionNames.remove(expectedExceptionName);
+ }
+
+ assertTrue(exceptionNames.isEmpty());
+ }
+
+ /**
+ * Checks an attribute after that it has been declared on capability definition.
+ *
+ * @param attribute the (JMX) attribute metadata.
+ * @param definition the capability class definition.
+ * @throws Exception when something goes wrong during introspection.
+ */
+ private void checkAttribute(MBeanAttributeInfo attribute, CtClass definition) throws Exception
+ {
+ String name = _builder.getNameForAccessors(attribute.getName());
+
+ String newPropertyDeclaration =
+ new StringBuilder("new QName(Names.NAMESPACE_URI, \"")
+ .append(attribute.getName())
+ .append("\", Names.PREFIX),")
+ .toString();
+ assertTrue(_builder._properties.indexOf(newPropertyDeclaration) != -1);
+
+ if (attribute.isReadable())
+ {
+ CtMethod getter = definition.getDeclaredMethod("get"+name);
+ assertNotNull(getter);
+
+ checkExceptionTypes(
+ getter.getExceptionTypes(),
+ new String[]{
+ QManFault.class.getName(),
+ NoSuchAttributeFault.class.getName(),
+ EntityInstanceNotFoundFault.class.getName()});
+
+ assertEquals(0,getter.getParameterTypes().length);
+ assertEquals(attribute.getType(),getter.getReturnType().getName());
+ }
+
+ if (attribute.isWritable())
+ {
+ CtMethod setter = definition.getDeclaredMethod("set"+name);
+ assertNotNull(setter);
+
+ checkExceptionTypes(
+ setter.getExceptionTypes(),
+ new String[]{
+ QManFault.class.getName(),
+ NoSuchAttributeFault.class.getName(),
+ EntityInstanceNotFoundFault.class.getName()});
+
+ CtClass [] parameterTypes = setter.getParameterTypes();
+
+ assertEquals(1,parameterTypes.length);
+ assertEquals(attribute.getType(),parameterTypes[0].getName());
+ assertEquals(void.class.getName(),setter.getReturnType().getName());
+ }
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/capabilities/MBeanCapabilityTest.java b/qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/capabilities/MBeanCapabilityTest.java
new file mode 100644
index 0000000000..a9a6491209
--- /dev/null
+++ b/qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/capabilities/MBeanCapabilityTest.java
@@ -0,0 +1,204 @@
+/*
+ *
+ * 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 java.lang.management.ManagementFactory;
+import java.net.URI;
+
+import javax.management.ObjectName;
+
+import junit.framework.TestCase;
+
+import org.apache.muse.ws.addressing.EndpointReference;
+import org.apache.muse.ws.resource.WsResource;
+import org.apache.muse.ws.resource.impl.SimpleWsResource;
+import org.apache.qpid.management.domain.handler.impl.QpidDomainObject;
+import org.apache.qpid.management.wsdm.common.EntityInstanceNotFoundFault;
+import org.apache.qpid.management.wsdm.common.NoSuchAttributeFault;
+import org.apache.qpid.management.wsdm.common.QManFault;
+
+/**
+ * Test case for MBeanCapability supertype layer..
+ *
+ * @author Andrea Gazzarini
+ */
+public class MBeanCapabilityTest extends TestCase
+{
+ private final String _typeAttributeName = "Type";
+ private final String _newTypeValue = "DomainObject";
+
+ private ObjectName _objectName;
+ private ObjectName _unknownObjectName;
+
+ private MBeanCapability _capability;
+
+ @Override
+ protected void setUp() throws Exception
+ {
+ _objectName = new ObjectName("Test:Name=aName");
+ _unknownObjectName = new ObjectName("Test:Type=unknown");
+
+ _capability = new MBeanCapability(){
+ @Override
+ public WsResource getWsResource()
+ {
+ return new SimpleWsResource(){
+ @Override
+ public EndpointReference getEndpointReference()
+ {
+ return new EndpointReference(URI.create("http://qpid.apache.org/qman"));
+ }
+ };
+ }
+ };
+ _capability.setResourceObjectName(_objectName);
+ ManagementFactory.getPlatformMBeanServer().registerMBean(new QpidDomainObject(), _objectName);
+ }
+
+ /**
+ * Tests the execution of the getAttribute() and setAttribute() method.
+ *
+ * <br>precondition : the mbean is registered and a _capability is associated with it.
+ * <br>postcondition : the set value of the requested attribute is correctly returned.
+ */
+ public void testGetAndSetAttributeOK() throws Exception
+ {
+ Object name = _capability.getAttribute(_typeAttributeName);
+ assertNull("Name has an initial value of null so how is possibile that is not null?",name);
+
+ _capability.setAttribute(_typeAttributeName,_newTypeValue);
+
+ name = _capability.getAttribute(_typeAttributeName);
+ assertEquals("Now the name attribute must be set to \""+_newTypeValue+"\"",_newTypeValue,name);
+ }
+
+ /**
+ * Tests the execution of the getAttribute() and setAttribte() methods when an unknown attribute is given..
+ *
+ * <br>precondition : the mbean is registered, a _capability is associated with it and the requested attribute doesn't exist.
+ * <br>postcondition : an exception is thrown indicating the failure.
+ */
+ public void testNoSuchAttributeFault() throws Exception
+ {
+ // I suppose that we shouldn't have an attribute with this name...
+ String unknownAttribute = String.valueOf(System.currentTimeMillis());
+
+ try
+ {
+ _capability.getAttribute(unknownAttribute);
+ fail("An exception must be thrown here in order to indicate that the attribute is unknown.");
+ } catch(NoSuchAttributeFault expected)
+ {
+ }
+
+ try
+ {
+ _capability.setAttribute(unknownAttribute,null);
+ fail("An exception must be thrown here in order to indicate that the attribute is unknown.");
+ } catch(NoSuchAttributeFault expected)
+ {
+ }
+ }
+
+ /**
+ * Tests the execution of the setAttribute,getAttribute and invoke methods when the target mbean
+ * doesn't exists.
+ *
+ * <br>precondition : the object name associated with the capability is not pointing to an existent MBean.
+ * <br>postcondition : an exception is thrown indicating the failure.
+ */
+ public void testEntityInstanceNotFoundFault() throws Exception
+ {
+ _capability.setResourceObjectName(_unknownObjectName);
+
+ try
+ {
+ _capability.getAttribute(_typeAttributeName);
+ fail("An exception must be thrown here in order to indicate that the attribute is unknown.");
+ } catch(EntityInstanceNotFoundFault expected)
+ {
+ }
+
+ try
+ {
+ _capability.setAttribute(_typeAttributeName,_newTypeValue);
+ fail("An exception must be thrown here in order to indicate that the attribute is unknown.");
+ } catch(EntityInstanceNotFoundFault expected)
+ {
+ }
+
+ try
+ {
+ _capability.invoke("operationName", null,null);
+ fail("An exception must be thrown here in order to indicate that the attribute is unknown.");
+ } catch(EntityInstanceNotFoundFault expected)
+ {
+ }
+ }
+
+ /**
+ * Tests the execution of the setAttribute,getAttribute and invoke methods when an unknown / unexpected
+ * exception is thrown.
+ *
+ * <br>precondition : the mbean is registered and a capability is associated with it. Something
+ * unexpected happens during method invocation.
+ * <br>postcondition : an exception is thrown indicating the failure.
+ */
+ public void testQManFault() throws Exception
+ {
+ // Emulate a RuntimeException (which is the best example of uncaught exception... :) )
+ _capability.setResourceObjectName(null);
+
+ try
+ {
+ _capability.getAttribute(_typeAttributeName);
+ fail("An exception must be thrown here in order to indicate that the attribute is unknown.");
+ } catch(QManFault expected)
+ {
+ }
+
+ try
+ {
+ _capability.setAttribute(_typeAttributeName,_newTypeValue);
+ fail("An exception must be thrown here in order to indicate that the attribute is unknown.");
+ } catch(QManFault expected)
+ {
+ }
+
+ try
+ {
+ _capability.invoke("operationName", null,null);
+ fail("An exception must be thrown here in order to indicate that the attribute is unknown.");
+ } catch(QManFault expected)
+ {
+ }
+ }
+
+
+ /**
+ * Shutdown procedure for this test case.
+ */
+ @Override
+ protected void tearDown() throws Exception
+ {
+ ManagementFactory.getPlatformMBeanServer().unregisterMBean(_objectName);
+ }
+}
diff --git a/qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/capabilities/QManAdapterCapabilityTest.java b/qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/capabilities/QManAdapterCapabilityTest.java
new file mode 100644
index 0000000000..648c7b2f60
--- /dev/null
+++ b/qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/capabilities/QManAdapterCapabilityTest.java
@@ -0,0 +1,81 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.management.wsdm.capabilities;
+
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+
+import org.apache.muse.ws.notification.NotificationProducer;
+import org.apache.qpid.management.Names;
+
+import junit.framework.TestCase;
+
+/**
+ * Test case for QMan adapter capability.
+ *
+ * @author Andrea Gazzarini
+ */
+public class QManAdapterCapabilityTest extends TestCase
+{
+ /**
+ * Tests the execution of the getTopicName() method.
+ *
+ * <br>precondition : an object type is given to the method (null is allowed).
+ * <br>postcondition : according to getTopicName() specs, the name of the
+ * topic associated with the given object type must be returned.
+ */
+ public void testGetTopicName()
+ {
+ final InvocationHandler invocationHandler = new InvocationHandler(){
+
+ public Object invoke(Object proxy, Method method, Object[] args)
+ {
+ return null;
+ }
+ };
+
+ QManAdapterCapability capability = new QManAdapterCapability(){
+ @Override
+ NotificationProducer getPublisherCapability()
+ {
+ return (NotificationProducer) Proxy.newProxyInstance(
+ getClass().getClassLoader(),
+ new Class[]{NotificationProducer.class},
+ invocationHandler);
+ }
+ };
+
+ capability.createLifeCycleTopics();
+
+ assertEquals(
+ Names.EVENTS_LIFECYLE_TOPIC_NAME,
+ capability.getTopicName(Names.EVENT));
+
+ assertEquals(
+ Names.OBJECTS_LIFECYLE_TOPIC_NAME,
+ capability.getTopicName(Names.CLASS));
+
+ assertEquals(
+ Names.UNKNOWN_OBJECT_TYPE_LIFECYLE_TOPIC_NAME,
+ capability.getTopicName("This is an unknown object Type @#!--!!@#"));
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/capabilities/RmdBuilderTest.java b/qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/capabilities/RmdBuilderTest.java
new file mode 100644
index 0000000000..77cda1c2c1
--- /dev/null
+++ b/qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/capabilities/RmdBuilderTest.java
@@ -0,0 +1,110 @@
+/*
+ *
+ * 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 java.lang.management.ManagementFactory;
+
+import javax.management.MBeanAttributeInfo;
+import javax.management.MBeanInfo;
+import javax.management.MBeanServer;
+import javax.management.ObjectName;
+
+import org.apache.qpid.management.Names;
+import org.apache.qpid.management.domain.handler.impl.QpidDomainObject;
+import org.w3c.dom.Element;
+
+import junit.framework.TestCase;
+
+/**
+ * Test case for Resource Metadata Descriptor Builder.
+ *
+ * @author Andrea Gazzarini
+ */
+public class RmdBuilderTest extends TestCase
+{
+ private MBeanInfo _metadata;
+ private RmdBuilder _builder;
+ private ObjectName _objectName;
+
+ @Override
+ protected void setUp() throws Exception
+ {
+ MBeanServer server = ManagementFactory.getPlatformMBeanServer();
+ _objectName = new ObjectName("Test:Name=QpidDomainObject");
+
+ server.registerMBean(new QpidDomainObject(), _objectName);
+ _metadata = server.getMBeanInfo(_objectName);
+
+ _builder = new RmdBuilder();
+ _builder.begin(_objectName);
+
+ assertEquals(_objectName,_builder._objectName);
+ }
+
+ /**
+ * Tests the execution of the onOperation() method.
+ */
+ public void testOnOperation() throws Exception
+ {
+ MBeanAttributeInfo [] attributes = _metadata.getAttributes();
+ for (MBeanAttributeInfo attribute : attributes)
+ {
+ _builder.onAttribute(attribute);
+ }
+
+ Element [] rmd = _builder.getResourceMetadataDescriptor();
+
+ assertEquals(attributes.length,rmd.length);
+
+ for (MBeanAttributeInfo attribute: _metadata.getAttributes())
+ {
+ Element propertyMetadataDescriptor = getPropertyMetadatDescriptor(attribute.getName(), rmd);
+
+ String modifiability = propertyMetadataDescriptor.getAttribute(Names.MODIFIABILITY);
+ String expectedValue =
+ attribute.isWritable()
+ ? Names.READ_WRITE
+ : Names.READ_ONLY;
+ assertEquals(expectedValue,modifiability);
+ }
+ }
+
+ /**
+ * Returns the property metadata descriptor associated with the given attribute name.
+ *
+ * @param name the attribute name.
+ * @param rmd the resource metadata descriptor.
+ * @return the property metadata descriptor associated with the given attribute name.
+ * @throws RuntimeException if metadata for the given attribute is not found.
+ */
+ private Element getPropertyMetadatDescriptor(String name, Element [] rmd)
+ {
+ for (Element propertyMetadataDescriptor : rmd)
+ {
+ if ((Names.PREFIX+":"+name).equals(
+ propertyMetadataDescriptor.getAttribute(Names.NAME_ATTRIBUTE)))
+ {
+ return propertyMetadataDescriptor;
+ }
+ }
+ throw new RuntimeException("Property MetadataDescriptor not found for attribute "+name);
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/web.xml b/qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/web.xml
new file mode 100644
index 0000000000..df273bd841
--- /dev/null
+++ b/qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/web.xml
@@ -0,0 +1,32 @@
+<?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.
+
+-->
+
+<web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
+ <servlet>
+ <display-name>Qpid emulator startip</display-name>
+ <servlet-name>QEmu</servlet-name>
+ <servlet-class>org.apache.qpid.management.wsdm.QEmuInitializer</servlet-class>
+ <load-on-startup>1</load-on-startup>
+ </servlet>
+</web-app>
diff --git a/qpid/java/management/client/web.xml b/qpid/java/management/client/web.xml
new file mode 100644
index 0000000000..881fc82f46
--- /dev/null
+++ b/qpid/java/management/client/web.xml
@@ -0,0 +1,149 @@
+<?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.
+
+-->
+
+<web-app id="qman" version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
+ <description>
+ Q-Man is a Management bridge that exposes one (or several) Qpid
+ broker domain model as MBeans that are accessible through the
+ Java Management Extensions (JMX) and / or WS-DM.
+ </description>
+ <display-name>QManEE</display-name>
+ <listener>
+ <description>
+ Provides lifecycle management for QMan module.
+ </description>
+ <display-name>QMan Lifecycle manager</display-name>
+ <listener-class>org.apache.qpid.management.servlet.QManLifeCycleManager</listener-class>
+ </listener>
+ <servlet>
+ <display-name>QMan Proxy Servlet</display-name>
+ <servlet-name>Proxy</servlet-name>
+ <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>
+ <description>
+ Connects QMAn to one or more brokers depending from what is
+ specified on the given (via system property) configuration
+ file.
+ </description>
+ <display-name>Connect QMan to Broker</display-name>
+ <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-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>
+ </servlet-mapping>
+ <servlet-mapping>
+ <servlet-name>Proxy</servlet-name>
+ <url-pattern>/services/*</url-pattern>
+ </servlet-mapping>
+ <login-config>
+ <auth-method>BASIC</auth-method>
+ </login-config>
+</web-app>
diff --git a/qpid/java/management/common/src/main/java/management-common.bnd b/qpid/java/management/common/src/main/java/management-common.bnd
index 5c39329f2f..cb28d309a6 100644
--- a/qpid/java/management/common/src/main/java/management-common.bnd
+++ b/qpid/java/management/common/src/main/java/management-common.bnd
@@ -17,7 +17,7 @@
# under the License.
#
-ver: 0.13.0
+ver: 0.9.0
Bundle-SymbolicName: qpid-management-common
Bundle-Version: ${ver}
diff --git a/qpid/java/management/common/src/main/java/org/apache/qpid/management/common/mbeans/ManagedBroker.java b/qpid/java/management/common/src/main/java/org/apache/qpid/management/common/mbeans/ManagedBroker.java
index b5c80a4fed..c0e7293611 100644
--- a/qpid/java/management/common/src/main/java/org/apache/qpid/management/common/mbeans/ManagedBroker.java
+++ b/qpid/java/management/common/src/main/java/org/apache/qpid/management/common/mbeans/ManagedBroker.java
@@ -36,8 +36,8 @@ import org.apache.qpid.management.common.mbeans.annotations.MBeanOperationParame
* The ManagedBroker is the management interface to expose management
* features of the Broker.
*
- * @version Qpid JMX API 2.2
- * @since Qpid JMX API 1.3
+ * @author Bhupendra Bhardwaj
+ * @version 0.1
*/
public interface ManagedBroker
{
@@ -131,118 +131,4 @@ public interface ManagedBroker
impact= MBeanOperationInfo.ACTION)
void deleteQueue(@MBeanOperationParameter(name= ManagedQueue.TYPE, description="Queue Name")String queueName)
throws IOException, JMException, MBeanException;
-
- /**
- * Resets all message and data statistics for the virtual host.
- *
- * @since Qpid JMX API 2.2
- */
- @MBeanOperation(name="resetStatistics",
- description="Resets all message and data statistics for the virtual host",
- impact= MBeanOperationInfo.ACTION)
- void resetStatistics() throws Exception;
-
- /**
- * Peak rate of messages delivered per second for the virtual host.
- *
- * @since Qpid JMX API 2.2
- */
- @MBeanAttribute(name="PeakMessageDeliveryRate", description=TYPE + " Peak Message Delivery Rate")
- double getPeakMessageDeliveryRate();
-
- /**
- * Peak rate of bytes delivered per second for the virtual host.
- *
- * @since Qpid JMX API 2.2
- */
- @MBeanAttribute(name="PeakDataDeliveryRate", description=TYPE + " Peak Data Delivery Rate")
- double getPeakDataDeliveryRate();
-
- /**
- * Rate of messages delivered per second for the virtual host.
- *
- * @since Qpid JMX API 2.2
- */
- @MBeanAttribute(name="MessageDeliveryRate", description=TYPE + " Message Delivery Rate")
- double getMessageDeliveryRate();
-
- /**
- * Rate of bytes delivered per second for the virtual host.
- *
- * @since Qpid JMX API 2.2
- */
- @MBeanAttribute(name="DataDeliveryRate", description=TYPE + " Data Delivery Rate")
- double getDataDeliveryRate();
-
- /**
- * Total count of messages delivered for the virtual host.
- *
- * @since Qpid JMX API 2.2
- */
- @MBeanAttribute(name="TotalMessagesDelivered", description=TYPE + " Total Messages Delivered")
- long getTotalMessagesDelivered();
-
- /**
- * Total count of bytes for the virtual host.
- *
- * @since Qpid JMX API 2.2
- */
- @MBeanAttribute(name="TotalDataDelivered", description=TYPE + " Total Data Delivered")
- long getTotalDataDelivered();
-
- /**
- * Peak rate of messages received per second for the virtual host.
- *
- * @since Qpid JMX API 2.2
- */
- @MBeanAttribute(name="PeakMessageReceiptRate", description=TYPE + " Peak Message Receipt Rate")
- double getPeakMessageReceiptRate();
-
- /**
- * Peak rate of bytes received per second for the virtual host.
- *
- * @since Qpid JMX API 2.2
- */
- @MBeanAttribute(name="PeakDataReceiptRate", description=TYPE + " Peak Data Receipt Rate")
- double getPeakDataReceiptRate();
-
- /**
- * Rate of messages received per second for the virtual host.
- *
- * @since Qpid JMX API 2.2
- */
- @MBeanAttribute(name="MessageReceiptRate", description=TYPE + " Message Receipt Rate")
- double getMessageReceiptRate();
-
- /**
- * Rate of bytes received per second for the virtual host.
- *
- * @since Qpid JMX API 2.2
- */
- @MBeanAttribute(name="DataReceiptRate", description=TYPE + " Data Receipt Rate")
- double getDataReceiptRate();
-
- /**
- * Total count of messages received for the virtual host.
- *
- * @since Qpid JMX API 2.2
- */
- @MBeanAttribute(name="TotalMessagesReceived", description=TYPE + " Total Messages Received")
- long getTotalMessagesReceived();
-
- /**
- * Total count of bytes received for the virtual host.
- *
- * @since Qpid JMX API 2.2
- */
- @MBeanAttribute(name="TotalDataReceived", description=TYPE + " Total Data Received")
- long getTotalDataReceived();
-
- /**
- * Is statistics collection enabled for this connection.
- *
- * @since Qpid JMX API 2.2
- */
- @MBeanAttribute(name="StatisticsEnabled", description=TYPE + " Statistics Enabled")
- boolean isStatisticsEnabled();
}
diff --git a/qpid/java/management/common/src/main/java/org/apache/qpid/management/common/mbeans/ManagedConnection.java b/qpid/java/management/common/src/main/java/org/apache/qpid/management/common/mbeans/ManagedConnection.java
index d16db65d5d..d6b79d1dde 100644
--- a/qpid/java/management/common/src/main/java/org/apache/qpid/management/common/mbeans/ManagedConnection.java
+++ b/qpid/java/management/common/src/main/java/org/apache/qpid/management/common/mbeans/ManagedConnection.java
@@ -37,9 +37,8 @@ import org.apache.qpid.management.common.mbeans.annotations.MBeanOperationParame
/**
* The management interface exposed to allow management of Connections.
- *
- * @version Qpid JMX API 2.2
- * @since Qpid JMX API 1.3
+ * @author Bhupendra Bhardwaj
+ * @version 0.1
*/
public interface ManagedConnection
{
@@ -146,126 +145,4 @@ public interface ManagedConnection
description="Closes this connection and all related channels",
impact= MBeanOperationInfo.ACTION)
void closeConnection() throws Exception;
-
- /**
- * Resets message and data statistics for this connection.
- *
- * @since Qpid JMX API 2.2
- */
- @MBeanOperation(name="resetStatistics",
- description="Resets message and data statistics for this connection",
- impact= MBeanOperationInfo.ACTION)
- void resetStatistics() throws Exception;
-
- /**
- * Peak rate of messages delivered per second for the virtual host.
- *
- * @since Qpid JMX API 2.2
- */
- @MBeanAttribute(name="PeakMessageDeliveryRate", description=TYPE + " Peak Message Delivery Rate")
- double getPeakMessageDeliveryRate();
-
- /**
- * Peak rate of bytes delivered per second for the virtual host.
- *
- * @since Qpid JMX API 2.2
- */
- @MBeanAttribute(name="PeakDataDeliveryRate", description=TYPE + " Peak Data Delivery Rate")
- double getPeakDataDeliveryRate();
-
- /**
- * Rate of messages delivered per second for the virtual host.
- *
- * @since Qpid JMX API 2.2
- */
- @MBeanAttribute(name="MessageDeliveryRate", description=TYPE + " Message Delivery Rate")
- double getMessageDeliveryRate();
-
- /**
- * Rate of bytes delivered per second for the virtual host.
- *
- * @since Qpid JMX API 2.2
- */
- @MBeanAttribute(name="DataDeliveryRate", description=TYPE + " Data Delivery Rate")
- double getDataDeliveryRate();
-
- /**
- * Total count of messages delivered for the virtual host.
- *
- * @since Qpid JMX API 2.2
- */
- @MBeanAttribute(name="TotalMessagesDelivered", description=TYPE + " Total Messages Delivered")
- long getTotalMessagesDelivered();
-
- /**
- * Total count of bytes for the virtual host.
- *
- * @since Qpid JMX API 2.2
- */
- @MBeanAttribute(name="TotalDataDelivered", description=TYPE + " Total Data Delivered")
- long getTotalDataDelivered();
-
- /**
- * Peak rate of messages received per second for this connection.
- *
- * @since Qpid JMX API 2.2
- */
- @MBeanAttribute(name="PeakMessageReceiptRate", description=TYPE + " Peak Message Receipt Rate")
- double getPeakMessageReceiptRate();
-
- /**
- * Peak rate of bytes received per second for this connection.
- *
- * @since Qpid JMX API 2.2
- */
- @MBeanAttribute(name="PeakDataReceiptRate", description=TYPE + " Peak Data Receipt Rate")
- double getPeakDataReceiptRate();
-
- /**
- * Rate of messages received per second for this connection.
- *
- * @since Qpid JMX API 2.2
- */
- @MBeanAttribute(name="MessageReceiptRate", description=TYPE + " Message Receipt Rate")
- double getMessageReceiptRate();
-
- /**
- * Rate of bytes received per second for this connection.
- *
- * @since Qpid JMX API 2.2
- */
- @MBeanAttribute(name="DataReceiptRate", description=TYPE + " Data Receipt Rate")
- double getDataReceiptRate();
-
- /**
- * Total count of messages received for this connection.
- *
- * @since Qpid JMX API 2.2
- */
- @MBeanAttribute(name="TotalMessagesReceived", description=TYPE + " Total Messages Received")
- long getTotalMessagesReceived();
-
- /**
- * Total count of bytes received for this connection.
- *
- * @since Qpid JMX API 2.2
- */
- @MBeanAttribute(name="TotalDataReceived", description=TYPE + " Total Data Received")
- long getTotalDataReceived();
-
- /**
- * Is statistics collection enabled for this connection.
- *
- * @since Qpid JMX API 2.2
- */
- @MBeanAttribute(name="StatisticsEnabled", description=TYPE + " Statistics Enabled")
- boolean isStatisticsEnabled();
-
- /**
- * Sets statistics collection enabled/disabled for this connection.
- *
- * @param enabled
- * @since Qpid JMX API 2.2
- */
- void setStatisticsEnabled(boolean enabled);
}
diff --git a/qpid/java/management/common/src/main/java/org/apache/qpid/management/common/mbeans/ServerInformation.java b/qpid/java/management/common/src/main/java/org/apache/qpid/management/common/mbeans/ServerInformation.java
index 12ae69571e..618403fdca 100644
--- a/qpid/java/management/common/src/main/java/org/apache/qpid/management/common/mbeans/ServerInformation.java
+++ b/qpid/java/management/common/src/main/java/org/apache/qpid/management/common/mbeans/ServerInformation.java
@@ -22,15 +22,10 @@ package org.apache.qpid.management.common.mbeans;
import java.io.IOException;
-import javax.management.MBeanOperationInfo;
-
import org.apache.qpid.management.common.mbeans.annotations.MBeanAttribute;
-import org.apache.qpid.management.common.mbeans.annotations.MBeanOperation;
/**
* Interface for the ServerInformation MBean
- *
- * @version Qpid JMX API 2.3
* @since Qpid JMX API 1.3
*/
public interface ServerInformation
@@ -47,7 +42,7 @@ public interface ServerInformation
* Qpid JMX API 1.1 can be assumed.
*/
int QPID_JMX_API_MAJOR_VERSION = 2;
- int QPID_JMX_API_MINOR_VERSION = 3;
+ int QPID_JMX_API_MINOR_VERSION = 0;
/**
@@ -85,118 +80,4 @@ public interface ServerInformation
@MBeanAttribute(name="ProductVersion",
description = "The product version string")
String getProductVersion() throws IOException;
-
- /**
- * Resets all message and data statistics for the broker.
- *
- * @since Qpid JMX API 2.2
- */
- @MBeanOperation(name="resetStatistics",
- description="Resets all message and data statistics for the broker",
- impact= MBeanOperationInfo.ACTION)
- void resetStatistics() throws Exception;
-
- /**
- * Peak rate of messages delivered per second for the virtual host.
- *
- * @since Qpid JMX API 2.2
- */
- @MBeanAttribute(name="PeakMessageDeliveryRate", description=TYPE + " Peak Message Delivery Rate")
- double getPeakMessageDeliveryRate();
-
- /**
- * Peak rate of bytes delivered per second for the broker.
- *
- * @since Qpid JMX API 2.2
- */
- @MBeanAttribute(name="PeakDataDeliveryRate", description=TYPE + " Peak Data Delivery Rate")
- double getPeakDataDeliveryRate();
-
- /**
- * Rate of messages delivered per second for the broker.
- *
- * @since Qpid JMX API 2.2
- */
- @MBeanAttribute(name="MessageDeliveryRate", description=TYPE + " Message Delivery Rate")
- double getMessageDeliveryRate();
-
- /**
- * Rate of bytes delivered per second for the broker.
- *
- * @since Qpid JMX API 2.2
- */
- @MBeanAttribute(name="DataDeliveryRate", description=TYPE + " Data Delivery Rate")
- double getDataDeliveryRate();
-
- /**
- * Total count of messages delivered for the broker.
- *
- * @since Qpid JMX API 2.2
- */
- @MBeanAttribute(name="TotalMessagesDelivered", description=TYPE + " Total Messages Delivered")
- long getTotalMessagesDelivered();
-
- /**
- * Total count of bytes for the broker.
- *
- * @since Qpid JMX API 2.2
- */
- @MBeanAttribute(name="TotalDataDelivered", description=TYPE + " Total Data Delivered")
- long getTotalDataDelivered();
-
- /**
- * Peak rate of messages received per second for the broker.
- *
- * @since Qpid JMX API 2.2
- */
- @MBeanAttribute(name="PeakMessageReceiptRate", description=TYPE + " Peak Message Receipt Rate")
- double getPeakMessageReceiptRate();
-
- /**
- * Peak rate of bytes received per second for the broker.
- *
- * @since Qpid JMX API 2.2
- */
- @MBeanAttribute(name="PeakDataReceiptRate", description=TYPE + " Peak Data Receipt Rate")
- double getPeakDataReceiptRate();
-
- /**
- * Rate of messages received per second for the broker.
- *
- * @since Qpid JMX API 2.2
- */
- @MBeanAttribute(name="MessageReceiptRate", description=TYPE + " Message Receipt Rate")
- double getMessageReceiptRate();
-
- /**
- * Rate of bytes received per second for the broker.
- *
- * @since Qpid JMX API 2.2
- */
- @MBeanAttribute(name="DataReceiptRate", description=TYPE + " Data Receipt Rate")
- double getDataReceiptRate();
-
- /**
- * Total count of messages received for the broker.
- *
- * @since Qpid JMX API 2.2
- */
- @MBeanAttribute(name="TotalMessagesReceived", description=TYPE + " Total Messages Received")
- long getTotalMessagesReceived();
-
- /**
- * Total count of bytes received for the broker.
- *
- * @since Qpid JMX API 2.2
- */
- @MBeanAttribute(name="TotalDataReceived", description=TYPE + " Total Data Received")
- long getTotalDataReceived();
-
- /**
- * Is statistics collection enabled for this connection.
- *
- * @since Qpid JMX API 2.2
- */
- @MBeanAttribute(name="StatisticsEnabled", description=TYPE + " Statistics Enabled")
- boolean isStatisticsEnabled();
}
diff --git a/qpid/java/management/common/src/main/java/org/apache/qpid/management/common/mbeans/UserManagement.java b/qpid/java/management/common/src/main/java/org/apache/qpid/management/common/mbeans/UserManagement.java
index 1a82c58ee9..2bd00d5802 100644
--- a/qpid/java/management/common/src/main/java/org/apache/qpid/management/common/mbeans/UserManagement.java
+++ b/qpid/java/management/common/src/main/java/org/apache/qpid/management/common/mbeans/UserManagement.java
@@ -38,21 +38,38 @@ public interface UserManagement
//TabularType and contained CompositeType key/description information.
//For compatibility reasons, DONT MODIFY the existing key values if expanding the set.
String USERNAME = "Username";
- String RIGHTS_READ_ONLY = "read"; // item deprecated
- String RIGHTS_READ_WRITE = "write"; // item deprecated
- String RIGHTS_ADMIN = "admin"; // item deprecated
-
+ String RIGHTS_READ_ONLY = "read";
+ String RIGHTS_READ_WRITE = "write";
+ String RIGHTS_ADMIN = "admin";
List<String> COMPOSITE_ITEM_NAMES = Collections.unmodifiableList(Arrays.asList(USERNAME, RIGHTS_READ_ONLY, RIGHTS_READ_WRITE, RIGHTS_ADMIN));
List<String> COMPOSITE_ITEM_DESCRIPTIONS = Collections.unmodifiableList(
Arrays.asList("Broker Login username",
- "Item no longer used",
- "Item no longer used",
- "Item no longer used"));
-
+ "Management Console Read Permission",
+ "Management Console Write Permission",
+ "Management Console Admin Permission"));
List<String> TABULAR_UNIQUE_INDEX = Collections.unmodifiableList(Arrays.asList(USERNAME));
//********** Operations *****************//
/**
+ * set password for user.
+ *
+ * Since Qpid JMX API 1.2 this operation expects plain text passwords to be provided. Prior to this, MD5 hashed passwords were supplied.
+ *
+ * @deprecated since Qpid JMX API 1.7
+ *
+ * @param username The username to create
+ * @param password The password for the user
+ *
+ * @return The result of the operation
+ */
+ @Deprecated
+ @MBeanOperation(name = "setPassword", description = "Set password for user.",
+ impact = MBeanOperationInfo.ACTION)
+ boolean setPassword(@MBeanOperationParameter(name = "username", description = "Username")String username,
+ //NOTE: parameter name was changed to 'passwd' in Qpid JMX API 1.7 to protect against older, incompatible management clients
+ @MBeanOperationParameter(name = "passwd", description = "Password")char[] password);
+
+ /**
* Set password for a given user.
*
* @since Qpid JMX API 1.7
@@ -66,21 +83,69 @@ public interface UserManagement
impact = MBeanOperationInfo.ACTION)
boolean setPassword(@MBeanOperationParameter(name = "username", description = "Username")String username,
@MBeanOperationParameter(name = "password", description = "Password")String password);
+
+ /**
+ * set rights for users with given details
+ *
+ * @param username The username to create
+ * @param read The set of permission to give the new user
+ * @param write The set of permission to give the new user
+ * @param admin The set of permission to give the new user
+ *
+ * @return The result of the operation
+ */
+ @MBeanOperation(name = "setRights", description = "Set access rights for user.",
+ impact = MBeanOperationInfo.ACTION)
+ boolean setRights(@MBeanOperationParameter(name = "username", description = "Username")String username,
+ @MBeanOperationParameter(name = "read", description = "Administration read")boolean read,
+ @MBeanOperationParameter(name = "readAndWrite", description = "Administration write")boolean write,
+ @MBeanOperationParameter(name = "admin", description = "Administration rights")boolean admin);
+
+ /**
+ * Create users with given details
+ *
+ * Since Qpid JMX API 1.2 this operation expects plain text passwords to be provided. Prior to this, MD5 hashed passwords were supplied.
+ *
+ * @deprecated since Qpid JMX API 1.7
+ *
+ * @param username The username to create
+ * @param password The password for the user
+ * @param read The set of permission to give the new user
+ * @param write The set of permission to give the new user
+ * @param admin The set of permission to give the new user
+ *
+ * @return The result of the operation
+ */
+ @Deprecated
+ @MBeanOperation(name = "createUser", description = "Create new user from system.",
+ impact = MBeanOperationInfo.ACTION)
+ boolean createUser(@MBeanOperationParameter(name = "username", description = "Username")String username,
+ //NOTE: parameter name was changed to 'passwd' in Qpid JMX API 1.7 to protect against older, incompatible management clients
+ @MBeanOperationParameter(name = "passwd", description = "Password")char[] password,
+ @MBeanOperationParameter(name = "read", description = "Administration read")boolean read,
+ @MBeanOperationParameter(name = "readAndWrite", description = "Administration write")boolean write,
+ @MBeanOperationParameter(name = "admin", description = "Administration rights")boolean admin);
/**
* Create users with given details.
*
- * @since Qpid JMX API 2.3 / 1.12
+ * @since Qpid JMX API 1.7
*
* @param username The username to create
* @param password The password for the user
+ * @param read The set of permission to give the new user
+ * @param write The set of permission to give the new user
+ * @param admin The set of permission to give the new user
*
- * @return true if the user was created successfully, or false otherwise
+ * @return The result of the operation
*/
@MBeanOperation(name = "createUser", description = "Create a new user.",
impact = MBeanOperationInfo.ACTION)
boolean createUser(@MBeanOperationParameter(name = "username", description = "Username")String username,
- @MBeanOperationParameter(name = "password", description = "Password")String password);
+ @MBeanOperationParameter(name = "password", description = "Password")String password,
+ @MBeanOperationParameter(name = "read", description = "Administration read")boolean read,
+ @MBeanOperationParameter(name = "readAndWrite", description = "Administration write")boolean write,
+ @MBeanOperationParameter(name = "admin", description = "Administration rights")boolean admin);
/**
* View users returns all the users that are currently available to the system.
@@ -95,11 +160,9 @@ public interface UserManagement
/**
- * Reload the user data
+ * Reload the date from disk
*
- * Since Qpid JMX API 2.3 / 1.12 this operation reloads only the password data.
- * Since Qpid JMX API 1.2 but prior to 2.3 / 1.12 this operation reloads the password and authorisation files.
- * Prior to 1.2, only the authorisation file was reloaded.
+ * Since Qpid JMX API 1.2 this operation reloads the password and authorisation files. Prior to this, only the authorisation file was reloaded.
*
* @return The result of the operation
*/
@@ -109,13 +172,10 @@ public interface UserManagement
/**
* View users returns all the users that are currently available to the system.
- *
- * Since Qpid JMX API 2.3 / 1.12 the items that corresponded to read, write and admin flags
- * are deprecated and always return false.
*
* @return a table of users data (Username, read, write, admin)
*/
- @MBeanOperation(name = "viewUsers", description = "All users that are currently available to the system.",
+ @MBeanOperation(name = "viewUsers", description = "All users with access rights to the system.",
impact = MBeanOperationInfo.INFO)
TabularData viewUsers();
diff --git a/qpid/java/management/console/build.xml b/qpid/java/management/console/build.xml
new file mode 100644
index 0000000000..8f23030b44
--- /dev/null
+++ b/qpid/java/management/console/build.xml
@@ -0,0 +1,27 @@
+<!--
+ -
+ - Licensed to the Apache Software Foundation (ASF) under one
+ - or more contributor license agreements. See the NOTICE file
+ - distributed with this work for additional information
+ - regarding copyright ownership. The ASF licenses this file
+ - to you under the Apache License, Version 2.0 (the
+ - "License"); you may not use this file except in compliance
+ - with the License. You may obtain a copy of the License at
+ -
+ - http://www.apache.org/licenses/LICENSE-2.0
+ -
+ - Unless required by applicable law or agreed to in writing,
+ - software distributed under the License is distributed on an
+ - "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ - KIND, either express or implied. See the License for the
+ - specific language governing permissions and limitations
+ - under the License.
+ -
+ -->
+<project name="QMF Console" default="build">
+
+ <property name="module.depends" value="common client"/>
+
+ <import file="../../module.xml"/>
+
+</project>
diff --git a/qpid/java/management/console/src/main/java/org/apache/qpid/console/AbstractConsole.java b/qpid/java/management/console/src/main/java/org/apache/qpid/console/AbstractConsole.java
new file mode 100644
index 0000000000..d95003b1cc
--- /dev/null
+++ b/qpid/java/management/console/src/main/java/org/apache/qpid/console/AbstractConsole.java
@@ -0,0 +1,81 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.console;
+
+public class AbstractConsole implements Console
+{
+ public AbstractConsole()
+ {
+ }
+
+ public void agentRemoved(Agent agent)
+ {
+ }
+
+ public void brokerConnected(Broker broker)
+ {
+ }
+
+ public void brokerDisconnected(Broker broker)
+ {
+ }
+
+ public void brokerInformation(Broker broker)
+ {
+ }
+
+ public void eventRecieved(Broker broker, QMFEvent anEvent)
+ {
+ }
+
+ public void hearbeatRecieved(Agent agent, long timestamp)
+ {
+ }
+
+ public void methodResponse(Broker broker, long seq, MethodResult response)
+ {
+ }
+
+ public void newAgent(Agent agent)
+ {
+ }
+
+ public void newClass(short kind, ClassKey key)
+ {
+ }
+
+ public void newPackage(String packageName)
+ {
+ }
+
+ public void objectProperties(Broker broker, QMFObject obj)
+ {
+ }
+
+ public void objectStatistics(Broker broker, QMFObject obj)
+ {
+ }
+
+ public Class typeMapping(ClassKey key)
+ {
+ return QMFObject.class;
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/console/src/main/java/org/apache/qpid/console/Agent.java b/qpid/java/management/console/src/main/java/org/apache/qpid/console/Agent.java
new file mode 100644
index 0000000000..e1887d82ea
--- /dev/null
+++ b/qpid/java/management/console/src/main/java/org/apache/qpid/console/Agent.java
@@ -0,0 +1,116 @@
+/*
+ *
+ * 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.console;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class Agent
+{
+ private static Logger log = LoggerFactory.getLogger(Agent.class);
+
+ public static String AgentKey(long AgentBank, long BrokerBank)
+ {
+ return String.format("%s:%s", AgentBank, BrokerBank);
+ }
+
+ public static long getAgentBank(String routingKey)
+ {
+ String delim = ".";
+ return Long.parseLong(routingKey.split(java.util.regex.Pattern
+ .quote(delim))[3]);
+ }
+
+ public static long getBrokerBank(String routingKey)
+ {
+ String delim = ".";
+ return Long.parseLong(routingKey.split(java.util.regex.Pattern
+ .quote(delim))[2]);
+ }
+
+ public static String routingCode(long AgentBank, long BrokerBank)
+ {
+ return String.format("agent.%s.%s", BrokerBank, AgentBank);
+ }
+
+ private long agentBank;
+ private Broker broker;
+ private long brokerBank;
+ private String label;
+
+ public Agent(Broker broker, long agentBank, String label)
+ {
+ this.setBroker(broker);
+ this.setBrokerBank(broker.brokerBank());
+ this.setAgentBank(agentBank);
+ this.setlabel(label);
+ }
+
+ public final String agentKey()
+ {
+ return Agent.AgentKey(getAgentBank(), getBrokerBank());
+ }
+
+ public final long getAgentBank()
+ {
+ return agentBank;
+ }
+
+ public final Broker getBroker()
+ {
+ return broker;
+ }
+
+ public final long getBrokerBank()
+ {
+ return brokerBank;
+ }
+
+ public final String getlabel()
+ {
+ return label;
+ }
+
+ public final String routingCode()
+ {
+ return Agent.routingCode(getAgentBank(), getBrokerBank());
+ }
+
+ public final void setAgentBank(long value)
+ {
+ agentBank = value;
+ }
+
+ public final void setBroker(Broker value)
+ {
+ broker = value;
+ }
+
+ public final void setBrokerBank(long value)
+ {
+ brokerBank = value;
+ }
+
+ public final void setlabel(String value)
+ {
+ label = value;
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/console/src/main/java/org/apache/qpid/console/Broker.java b/qpid/java/management/console/src/main/java/org/apache/qpid/console/Broker.java
new file mode 100644
index 0000000000..16c77449f1
--- /dev/null
+++ b/qpid/java/management/console/src/main/java/org/apache/qpid/console/Broker.java
@@ -0,0 +1,504 @@
+/*
+ *
+ * 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.console;
+
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.UUID;
+
+import javax.jms.BytesMessage;
+import javax.jms.JMSException;
+import javax.jms.Message;
+import javax.jms.MessageListener;
+import javax.jms.MessageConsumer;
+import javax.jms.MessageProducer;
+import javax.jms.Queue;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.apache.qpid.client.AMQConnection;
+import org.apache.qpid.transport.codec.BBDecoder;
+import org.apache.qpid.transport.codec.BBEncoder;
+import org.apache.qpid.transport.codec.Decoder;
+import org.apache.qpid.transport.codec.Encoder;
+
+public class Broker implements MessageListener
+{
+ class HeaderInfo
+ {
+ boolean valid;
+ long sequence;
+ char opcode;
+
+ public String toString()
+ {
+ return String.format("%s Header with opcode %s and sequence %s",
+ (valid ? "Valid" : "Invalid"), opcode, sequence);
+ }
+ }
+
+ private static Logger log = LoggerFactory.getLogger(Broker.class);
+ public static final int SYNC_TIME = 60000;
+ // JMS Stuff
+ private javax.jms.Session session;
+ boolean sessionTransacted = false;
+ private String replyName;
+ private String topicName;
+ private MessageProducer prod;
+ private ArrayList<MessageConsumer> consumers = new ArrayList<MessageConsumer>();
+ private Queue reply;
+ private Queue topic;
+ private int acknowledgeMode = javax.jms.Session.AUTO_ACKNOWLEDGE;
+ // QMF Stuff
+ AMQConnection connection;
+ public String url;
+ public java.util.HashMap<String, Agent> Agents = new java.util.HashMap<String, Agent>();
+ private Session consoleSession;
+ private boolean connected = false;
+ private boolean syncInFlight = false;
+ private boolean topicBound = false;
+ private int reqsOutstanding = 0;
+ private Object lockObject = new Object();
+ UUID brokerId = UUID.randomUUID();
+
+ public Broker(org.apache.qpid.console.Session session, String url)
+ {
+ log.debug("Creating a new Broker for url " + url);
+ this.url = url;
+ consoleSession = session;
+ this.tryToConnect();
+ }
+
+ public int brokerBank()
+ {
+ return 1;
+ }
+
+ protected HeaderInfo CheckHeader(Decoder decoder)
+ {
+ HeaderInfo returnValue = new HeaderInfo();
+ returnValue.opcode = 'x';
+ returnValue.sequence = -1;
+ returnValue.valid = false;
+ if (decoder.hasRemaining())
+ {
+ char character = (char) decoder.readUint8();
+ if (character != 'A')
+ {
+ return returnValue;
+ }
+ character = (char) decoder.readUint8();
+ if (character != 'M')
+ {
+ return returnValue;
+ }
+ character = (char) decoder.readUint8();
+ if (character != '2')
+ {
+ return returnValue;
+ }
+ returnValue.valid = true;
+ returnValue.opcode = (char) decoder.readUint8();
+ returnValue.sequence = decoder.readUint32();
+ }
+ return returnValue;
+ }
+
+ public Encoder createEncoder(char opcode, long sequence)
+ {
+ return setHeader(new BBEncoder(1024), opcode, sequence);
+ }
+
+ public Message createMessage(Encoder enc)
+ {
+ try
+ {
+ byte[] buf = new byte[1024];
+ BBEncoder bbenc = (BBEncoder) enc;
+ BytesMessage msg = session.createBytesMessage();
+ ByteBuffer slice = bbenc.buffer();
+ while (slice.hasRemaining())
+ {
+ int n = Math.min(buf.length, slice.remaining());
+ slice.get(buf, 0, n);
+ msg.writeBytes(buf, 0, n);
+ }
+ return msg;
+ } catch (JMSException e)
+ {
+ throw new ConsoleException(e);
+ }
+ }
+
+ public void decrementOutstanding()
+ {
+ synchronized (lockObject)
+ {
+ this.reqsOutstanding -= 1;
+ if ((reqsOutstanding == 0) & !topicBound)
+ {
+ for (String key : consoleSession.bindingKeys())
+ {
+ try
+ {
+ // this.clientSession.exchangeBind(topicName,
+ // "qpid.mannagement", key) ;
+ log.debug("Setting Topic Binding " + key);
+ // topicName = "management://qpid.management//" + key;
+ String rk = String.format("&routingkey='%s'", key);
+ Queue aQueue = session.createQueue(topicName + rk);
+ MessageConsumer cons = session.createConsumer(aQueue);
+ cons.setMessageListener(this);
+ consumers.add(cons);
+ } catch (JMSException e)
+ {
+ throw new ConsoleException(e);
+ }
+ }
+ topicBound = true;
+ }
+ if ((reqsOutstanding == 0) & syncInFlight)
+ {
+ syncInFlight = false;
+ lockObject.notifyAll();
+ }
+ }
+ }
+
+ private byte[] ensure(int capacity, byte[] body, int size)
+ {
+ if (capacity > body.length)
+ {
+ byte[] copy = new byte[capacity];
+ System.arraycopy(body, 0, copy, 0, size);
+ body = copy;
+ }
+ return body;
+ }
+
+ protected void finalize()
+ {
+ if (connected)
+ {
+ this.shutdown();
+ }
+ }
+
+ public boolean getSyncInFlight()
+ {
+ return syncInFlight;
+ }
+
+ public void incrementOutstanding()
+ {
+ synchronized (lockObject)
+ {
+ this.reqsOutstanding += 1;
+ }
+ }
+
+ public boolean isConnected()
+ {
+ return connected;
+ }
+
+ public void onMessage(Message msg)
+ {
+ Decoder decoder = readBody(msg);
+ HeaderInfo headerInfo = this.CheckHeader(decoder);
+ // log.debug(headerInfo.toString());
+ while (headerInfo.valid)
+ {
+ long seq = headerInfo.sequence;
+ switch (headerInfo.opcode)
+ {
+ case 'b':
+ consoleSession.handleBrokerResponse(this, decoder, seq);
+ break;
+ case 'p':
+ consoleSession.handlePackageIndicator(this, decoder, seq);
+ break;
+ case 'z':
+ consoleSession.handleCommandComplete(this, decoder, seq);
+ break;
+ case 'q':
+ consoleSession.handleClassIndicator(this, decoder, seq);
+ break;
+ case 'm':
+ consoleSession.handleMethodResponse(this, decoder, seq);
+ break;
+ case 'h':
+ consoleSession
+ .handleHeartbeatIndicator(this, decoder, seq, msg);
+ break;
+ case 'e':
+ consoleSession.handleEventIndicator(this, decoder, seq);
+ break;
+ case 's':
+ consoleSession.handleSchemaResponse(this, decoder, seq);
+ break;
+ case 'c':
+ consoleSession.handleContentIndicator(this, decoder, seq, true,
+ false);
+ break;
+ case 'i':
+ consoleSession.handleContentIndicator(this, decoder, seq,
+ false, true);
+ break;
+ case 'g':
+ consoleSession.handleContentIndicator(this, decoder, seq, true,
+ true);
+ break;
+ default:
+ log.error("Invalid message type recieved with opcode "
+ + headerInfo.opcode);
+ break;
+ }
+ headerInfo = this.CheckHeader(decoder);
+ }
+ }
+
+ private Decoder readBody(Message message)
+ {
+ BytesMessage msg = (BytesMessage) message;
+ BBDecoder dec = new BBDecoder();
+ byte[] buf = new byte[1024];
+ byte[] body = new byte[1024];
+ int size = 0;
+ int n;
+ try
+ {
+ while ((n = msg.readBytes(buf)) > 0)
+ {
+ body = ensure(size + n, body, size);
+ System.arraycopy(buf, 0, body, size, n);
+ size += n;
+ }
+ } catch (JMSException e)
+ {
+ throw new ConsoleException(e);
+ }
+ dec.init(ByteBuffer.wrap(body, 0, size));
+ return dec;
+ }
+
+ public void send(Encoder enc)
+ {
+ this.send(this.createMessage(enc), "broker");
+ }
+
+ public void send(Message msg)
+ {
+ this.send(msg, "broker", -1);
+ }
+
+ public void send(Message msg, String routingKey)
+ {
+ this.send(msg, routingKey, -1);
+ }
+
+ public void send(Message msg, String routingKey, int ttl)
+ {
+ synchronized (lockObject)
+ {
+ try
+ {
+ log.debug(String.format("Sending message to routing key '%s'",
+ routingKey));
+ String destName = String.format(
+ "management://qpid.management//?routingkey='%s'",
+ routingKey);
+ log.debug(destName);
+ Queue dest = session.createQueue(destName);
+ // Queue jmsReply = session
+ // createQueue("direct://amq.direct//?routingkey='reply-"
+ // + brokerId + "'");
+ if (ttl != -1)
+ {
+ msg.setJMSExpiration(ttl);
+ }
+ msg.setJMSReplyTo(reply);
+ prod.send(dest, msg);
+ } catch (Exception e)
+ {
+ throw new ConsoleException(e);
+ }
+ }
+ }
+
+ protected Encoder setHeader(Encoder enc, char opcode, long sequence)
+ {
+ enc.writeUint8((short) 'A');
+ enc.writeUint8((short) 'M');
+ enc.writeUint8((short) '2');
+ enc.writeUint8((short) opcode);
+ enc.writeUint32(sequence);
+ return enc;
+ }
+
+ public void setSyncInFlight(boolean inFlight)
+ {
+ synchronized (lockObject)
+ {
+ syncInFlight = inFlight;
+ lockObject.notifyAll();
+ }
+ }
+
+ public void shutdown()
+ {
+ if (connected)
+ {
+ this.waitForStable();
+ try
+ {
+ session.close();
+ for (MessageConsumer cons : consumers)
+ {
+ cons.close();
+ }
+ connection.close();
+ } catch (Exception e)
+ {
+ throw new ConsoleException(e);
+ } finally
+ {
+ this.connected = false;
+ }
+ }
+ }
+
+ protected void tryToConnect()
+ {
+ try
+ {
+ reqsOutstanding = 1;
+ Agent newAgent = new Agent(this, 0, "BrokerAgent");
+ Agents.put(newAgent.agentKey(), newAgent);
+ connection = new AMQConnection(url);
+ session = connection.createSession(sessionTransacted,
+ acknowledgeMode);
+ replyName = String
+ .format(
+ "direct://amq.direct//reply-%s?exclusive='True'&autodelete='True'",
+ brokerId);
+ topicName = String
+ .format(
+ "management://qpid.management//topic-%s?exclusive='True'&autodelete='True'",
+ brokerId);
+ reply = session.createQueue(replyName);
+ MessageConsumer cons = session.createConsumer(reply);
+ cons.setMessageListener(this);
+ consumers.add(cons);
+ prod = session.createProducer(null);
+ topic = session.createQueue(topicName);
+ cons = session.createConsumer(topic);
+ cons.setMessageListener(this);
+ consumers.add(cons);
+ connection.start();
+ // Rest of the topic is bound later. Start er up
+ } catch (Exception e)
+ {
+ throw new ConsoleException(e);
+ }
+ connected = true;
+ consoleSession.handleBrokerConnect(this);
+ Encoder Encoder = createEncoder('B', 0);
+ this.send(Encoder);
+ }
+
+ public void updateAgent(QMFObject obj)
+ {
+ long agentBank = (Long) obj.getProperty("agentBank");
+ long brokerBank = (Long) obj.getProperty("brokerBank");
+ String key = Agent.AgentKey(agentBank, brokerBank);
+ if (obj.isDeleted())
+ {
+ if (Agents.containsKey(key))
+ {
+ Agent agent = Agents.get(key);
+ Agents.remove(key);
+ consoleSession.handleAgentRemoved(agent);
+ }
+ } else
+ {
+ if (!Agents.containsKey(key))
+ {
+ Agent newAgent = new Agent(this, agentBank, (String) obj
+ .getProperty("label"));
+ Agents.put(key, newAgent);
+ consoleSession.handleNewAgent(newAgent);
+ }
+ }
+ }
+
+ public void waitForStable()
+ {
+ synchronized (lockObject)
+ {
+ if (connected)
+ {
+ long start = System.currentTimeMillis();
+ syncInFlight = true;
+ while (reqsOutstanding != 0)
+ {
+ log.debug("Waiting to recieve messages");
+ try
+ {
+ lockObject.wait(SYNC_TIME);
+ } catch (Exception e)
+ {
+ throw new ConsoleException(e);
+ }
+ long duration = System.currentTimeMillis() - start;
+ if (duration > SYNC_TIME)
+ {
+ throw new ConsoleException(
+ "Timeout waiting for Broker to Sync");
+ }
+ }
+ }
+ }
+ }
+
+ public void waitForSync(int timeout)
+ {
+ synchronized (lockObject)
+ {
+ long start = System.currentTimeMillis();
+ while (syncInFlight)
+ {
+ try
+ {
+ lockObject.wait(SYNC_TIME);
+ } catch (Exception e)
+ {
+ throw new ConsoleException(e);
+ }
+ }
+ long duration = System.currentTimeMillis() - start;
+ if (duration > timeout)
+ {
+ throw new ConsoleException("Timeout waiting for Broker to Sync");
+ }
+ }
+ }
+}
diff --git a/qpid/java/management/console/src/main/java/org/apache/qpid/console/ClassKey.java b/qpid/java/management/console/src/main/java/org/apache/qpid/console/ClassKey.java
new file mode 100644
index 0000000000..1fbf4c7f3d
--- /dev/null
+++ b/qpid/java/management/console/src/main/java/org/apache/qpid/console/ClassKey.java
@@ -0,0 +1,146 @@
+/*
+ *
+ * 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.console;
+
+import org.apache.qpid.transport.codec.Decoder;
+import org.apache.qpid.transport.codec.Encoder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class ClassKey
+{
+ private static final Logger log = LoggerFactory.getLogger(ClassKey.class);
+ private String packageName;
+ private String className;
+ private long[] hash = new long[4];
+
+ public ClassKey(Decoder dec)
+ {
+ setPackageName(dec.readStr8());
+ setClassName(dec.readStr8());
+ hash[0] = dec.readUint32();
+ hash[1] = dec.readUint32();
+ hash[2] = dec.readUint32();
+ hash[3] = dec.readUint32();
+ }
+
+ public ClassKey(String keyString)
+ {
+ String delims = "[*:*(*)]";
+ String[] parts = keyString.split(delims);
+ if (parts.length < 3)
+ {
+ throw new ConsoleException(
+ "Invalid class key format. Format should be package:class(bytes)");
+ }
+ setPackageName(parts[0]);
+ setClassName(parts[1]);
+ delims = "-";
+ String[] bytes = parts[2].split(delims);
+ if (bytes.length != 4)
+ {
+ throw new ConsoleException(
+ "Invalid class key format. Bytes should be in the format HEX-HEX-HEX-HEX");
+ }
+ hash[0] = Long.parseLong(bytes[0], 16);
+ hash[1] = Long.parseLong(bytes[1], 16);
+ hash[2] = Long.parseLong(bytes[2], 16);
+ hash[3] = Long.parseLong(bytes[3], 16);
+ }
+
+ public void encode(Encoder enc)
+ {
+ enc.writeStr8(getPackageName());
+ enc.writeStr8(getClassName());
+ enc.writeUint32(hash[0]);
+ enc.writeUint32(hash[1]);
+ enc.writeUint32(hash[2]);
+ enc.writeUint32(hash[3]);
+ }
+
+ @Override
+ public boolean equals(Object obj)
+ {
+ if(obj instanceof ClassKey && obj.getClass().equals(this.getClass()))
+ {
+ ClassKey other = (ClassKey) obj;
+ return (other.getKeyString().equals(this.getKeyString()));
+ } else
+ {
+ return false;
+ }
+ }
+
+ public final String getClassName()
+ {
+ return className;
+ }
+
+ public long[] getHash()
+ {
+ return hash;
+ }
+
+ public String getHashString()
+ {
+ return String.format("%08x-%08x-%08x-%08x", hash[0], hash[1], hash[2],
+ hash[3]);
+ }
+
+ public String getKeyString()
+ {
+ String hashString = this.getHashString();
+ return String.format("%s:%s(%s)", getPackageName(), getClassName(),
+ hashString);
+ }
+
+ public String getPackageName()
+ {
+ return packageName;
+ }
+
+ @Override
+ public int hashCode()
+ {
+ return getKeyString().hashCode();
+ }
+
+ public void setClassName(String value)
+ {
+ className = value;
+ }
+
+ public void setHash(long[] hash)
+ {
+ this.hash = hash;
+ }
+
+ public void setPackageName(String value)
+ {
+ packageName = value;
+ }
+
+ @Override
+ public String toString()
+ {
+ return String.format("ClassKey: %s", getKeyString());
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/console/src/main/java/org/apache/qpid/console/Console.java b/qpid/java/management/console/src/main/java/org/apache/qpid/console/Console.java
new file mode 100644
index 0000000000..11b381032a
--- /dev/null
+++ b/qpid/java/management/console/src/main/java/org/apache/qpid/console/Console.java
@@ -0,0 +1,51 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.console;
+
+public interface Console
+{
+ void agentRemoved(Agent agent);
+
+ void brokerConnected(Broker broker);
+
+ void brokerDisconnected(Broker broker);
+
+ void brokerInformation(Broker broker);
+
+ void eventRecieved(Broker broker, QMFEvent anEvent);
+
+ void hearbeatRecieved(Agent agent, long timestamp);
+
+ void methodResponse(Broker broker, long seq, MethodResult response);
+
+ void newAgent(Agent agent);
+
+ void newClass(short kind, ClassKey key);
+
+ void newPackage(String packageName);
+
+ void objectProperties(Broker broker, QMFObject obj);
+
+ void objectStatistics(Broker broker, QMFObject obj);
+
+ @SuppressWarnings("unchecked")
+ Class typeMapping(ClassKey key);
+} \ No newline at end of file
diff --git a/qpid/java/management/console/src/main/java/org/apache/qpid/console/ConsoleException.java b/qpid/java/management/console/src/main/java/org/apache/qpid/console/ConsoleException.java
new file mode 100644
index 0000000000..3176da70a6
--- /dev/null
+++ b/qpid/java/management/console/src/main/java/org/apache/qpid/console/ConsoleException.java
@@ -0,0 +1,48 @@
+/*
+ *
+ * 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.console;
+
+import java.lang.RuntimeException;
+
+public class ConsoleException extends RuntimeException
+{
+ private static final long serialVersionUID = 1L;
+
+ public ConsoleException()
+ {
+ super();
+ }
+
+ public ConsoleException(String message)
+ {
+ super(message);
+ }
+
+ public ConsoleException(String message, Throwable cause)
+ {
+ super(message, cause);
+ }
+
+ public ConsoleException(Throwable cause)
+ {
+ super(cause);
+ }
+}
diff --git a/qpid/java/management/console/src/main/java/org/apache/qpid/console/EventSeverity.java b/qpid/java/management/console/src/main/java/org/apache/qpid/console/EventSeverity.java
new file mode 100644
index 0000000000..d40d41b196
--- /dev/null
+++ b/qpid/java/management/console/src/main/java/org/apache/qpid/console/EventSeverity.java
@@ -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.
+ *
+ */
+package org.apache.qpid.console;
+
+public enum EventSeverity
+{
+ EMER(0), ALERT(1), CRIT(2), ERROR(3), WARN(4), NOTIC(5), INFO(6), DEBUG(7);
+ private int intValue;
+
+ private EventSeverity(int value)
+ {
+ intValue = value;
+ }
+
+ public int getValue()
+ {
+ return intValue;
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/console/src/main/java/org/apache/qpid/console/MethodResult.java b/qpid/java/management/console/src/main/java/org/apache/qpid/console/MethodResult.java
new file mode 100644
index 0000000000..34980b50e1
--- /dev/null
+++ b/qpid/java/management/console/src/main/java/org/apache/qpid/console/MethodResult.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.console;
+
+import java.util.HashMap;
+
+public class MethodResult
+{
+ private long returnCode;
+ private String text;
+ protected java.util.HashMap<String, Object> returnValues;
+
+ public MethodResult(long aCode, String aMsg,
+ java.util.HashMap<String, Object> args)
+ {
+ setReturnCode(aCode);
+ setText(aMsg);
+ returnValues = args;
+ }
+
+ public long getReturnCode()
+ {
+ return returnCode;
+ }
+
+ public Object getReturnValue(String name)
+ {
+ Object returnValue = null;
+ if (returnValues.containsKey(name))
+ {
+ returnValue = returnValues.get(name);
+ }
+ return returnValue;
+ }
+
+ public HashMap<String, Object> getReturnValues()
+ {
+ return returnValues;
+ }
+
+ public String getText()
+ {
+ return text;
+ }
+
+ public void setReturnCode(long value)
+ {
+ returnCode = value;
+ }
+
+ public void setText(String value)
+ {
+ text = value;
+ }
+
+ @Override
+ public String toString()
+ {
+ String returnString = "";
+ for (java.util.Map.Entry<String, Object> pair : returnValues.entrySet())
+ {
+ returnString = returnString
+ + String.format("(Key: '%s' Value: '%s')", pair.getKey(),
+ pair.getValue());
+ }
+ return String.format(
+ "MethodResult: ReturnCode=%s, Text=%s Values=[%s]",
+ getReturnCode(), getText(), returnString);
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/console/src/main/java/org/apache/qpid/console/ObjectID.java b/qpid/java/management/console/src/main/java/org/apache/qpid/console/ObjectID.java
new file mode 100644
index 0000000000..6cf5301de5
--- /dev/null
+++ b/qpid/java/management/console/src/main/java/org/apache/qpid/console/ObjectID.java
@@ -0,0 +1,93 @@
+/*
+ *
+ * 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.console;
+
+import org.apache.qpid.transport.codec.*;
+
+public class ObjectID
+{
+ protected long first;
+ protected long second;
+
+ public ObjectID()
+ {
+ }
+
+ public ObjectID(Decoder dec)
+ {
+ first = dec.readUint64();
+ second = dec.readUint64();
+ }
+
+ public ObjectID(long first, long second)
+ {
+ this.first = first;
+ this.second = second;
+ }
+
+ public long agentBank()
+ {
+ return (this.first & 0x000000000FFFFFFF);
+ }
+
+ public long brokerBank()
+ {
+ return (this.first & 0x0000FFFFF0000000L) >> 28;
+ }
+
+ public void encode(Encoder enc)
+ {
+ enc.writeUint64(first);
+ enc.writeUint64(second);
+ }
+
+ public long flags()
+ {
+ return (this.first & 0xF000000000000000L) >> 60;
+ }
+
+ public boolean isDurable()
+ {
+ return sequence() == 0;
+ }
+
+ public long objectNum()
+ {
+ return second;
+ }
+
+ public String routingCode()
+ {
+ return Agent.routingCode(agentBank(), brokerBank());
+ }
+
+ public long sequence()
+ {
+ return (this.first & 0x0FFF000000000000L) >> 48;
+ }
+
+ @Override
+ public String toString()
+ {
+ return "" + flags() + "-" + sequence() + "-" + brokerBank() + "-"
+ + agentBank() + "-" + objectNum();
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/console/src/main/java/org/apache/qpid/console/QMFEvent.java b/qpid/java/management/console/src/main/java/org/apache/qpid/console/QMFEvent.java
new file mode 100644
index 0000000000..116387acfc
--- /dev/null
+++ b/qpid/java/management/console/src/main/java/org/apache/qpid/console/QMFEvent.java
@@ -0,0 +1,108 @@
+/*
+ *
+ * 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.console;
+
+import java.util.HashMap;
+
+import org.apache.qpid.transport.codec.*;
+
+public class QMFEvent
+{
+ private java.util.HashMap<String, Object> arguments;
+ private ClassKey classKey;
+ private Session session;
+ private EventSeverity severity;
+ // FIXME time?
+ private long timestamp;
+
+ public QMFEvent(Session session, Decoder dec)
+ {
+ setSession(session);
+ setClassKey(new ClassKey(dec));
+ setTimestamp(dec.readInt64());
+ setSeverity(EventSeverity.values()[dec.readUint8()]);
+ SchemaClass sClass = getSession().getSchema(getClassKey());
+ setArguments(new java.util.HashMap<String, Object>());
+ if (sClass != null)
+ {
+ for (SchemaArgument arg : sClass.arguments)
+ {
+ getArguments().put(arg.getName(),
+ getSession().decodeValue(dec, arg.getType()));
+ }
+ }
+ }
+
+ public final Object GetArgument(String argName)
+ {
+ return getArguments().get(argName);
+ }
+
+ public final HashMap<String, Object> getArguments()
+ {
+ return arguments;
+ }
+
+ public final ClassKey getClassKey()
+ {
+ return classKey;
+ }
+
+ public final Session getSession()
+ {
+ return session;
+ }
+
+ public final EventSeverity getSeverity()
+ {
+ return severity;
+ }
+
+ public final long getTimestamp()
+ {
+ return timestamp;
+ }
+
+ public final void setArguments(java.util.HashMap<String, Object> value)
+ {
+ arguments = value;
+ }
+
+ public final void setClassKey(ClassKey value)
+ {
+ classKey = value;
+ }
+
+ public final void setSession(Session value)
+ {
+ session = value;
+ }
+
+ public final void setSeverity(EventSeverity value)
+ {
+ severity = value;
+ }
+
+ public final void setTimestamp(long value)
+ {
+ timestamp = value;
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/console/src/main/java/org/apache/qpid/console/QMFObject.java b/qpid/java/management/console/src/main/java/org/apache/qpid/console/QMFObject.java
new file mode 100644
index 0000000000..1919bac411
--- /dev/null
+++ b/qpid/java/management/console/src/main/java/org/apache/qpid/console/QMFObject.java
@@ -0,0 +1,423 @@
+/*
+ *
+ * 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.console;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.Map.Entry;
+
+import org.apache.qpid.transport.codec.Decoder;
+import org.apache.qpid.transport.codec.Encoder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import edu.emory.mathcs.backport.java.util.Arrays;
+
+public class QMFObject
+{
+ private static Logger log = LoggerFactory.getLogger(QMFObject.class);
+ protected SchemaClass schema;
+ private java.util.Date createTime;
+ private java.util.Date currentTime;
+ private java.util.Date deleteTime;
+ private ObjectID objectID;
+ private Session session;
+ private boolean managed;
+ public java.util.HashMap<String, Object> properties = new java.util.HashMap<String, Object>();
+ public java.util.HashMap<String, Object> statistics = new java.util.HashMap<String, Object>();
+
+ // This constructor is the "naked" constructor which creates
+ // an object without a session or a schema. It is used by
+ // subclasses which are auto generated
+ public QMFObject()
+ {
+ }
+
+ public QMFObject(QMFObject source)
+ {
+ this.setSession(source.getSession());
+ this.setSchema(source.getSchema());
+ this.managed = source.managed;
+ this.setCurrentTime(source.getCurrentTime());
+ this.setCreateTime(source.getCreateTime());
+ this.setDeleteTime(source.getDeleteTime());
+ this.setObjectID(source.getObjectID());
+ this.properties = source.properties;
+ this.statistics = source.statistics;
+ }
+
+ // This constructor is used by a session make object call to
+ // create a blank object from a schema.
+ public QMFObject(Session session, SchemaClass schema,
+ boolean hasProperties, boolean hasStats, boolean isManaged)
+ {
+ setSession(session);
+ setSchema(schema);
+ managed = isManaged;
+ if (hasProperties)
+ {
+ for (SchemaProperty prop : getSchema().getAllProperties())
+ {
+ Object propValue = null;
+ if (!prop.getOptional())
+ {
+ propValue = Util.defaultValue(prop.getType());
+ }
+ this.setProperty(prop.getName(), propValue);
+ }
+ }
+ if (hasStats)
+ {
+ for (SchemaStatistic stat : getSchema().statistics)
+ {
+ setStatistic(stat.getName(), Util.defaultValue(stat.getType()));
+ }
+ }
+ }
+
+ // This constructor is used by the session to create an object based on a
+ // data
+ // stream by the agent.
+ public QMFObject(Session session, SchemaClass schema, Decoder dec,
+ boolean hasProperties, boolean hasStats, boolean isManaged)
+ {
+ setSession(session);
+ setSchema(schema);
+ managed = isManaged;
+ if (managed)
+ {
+ // FIXME DateTime or Uint64??
+ setCurrentTime(new java.util.Date(dec.readDatetime()));
+ setCreateTime(new java.util.Date(dec.readDatetime()));
+ setDeleteTime(new java.util.Date(dec.readDatetime()));
+ setObjectID(new ObjectID(dec));
+ }
+ if (hasProperties)
+ {
+ java.util.ArrayList<String> excluded = processPresenceMasks(dec,
+ getSchema());
+ for (SchemaProperty prop : getSchema().getAllProperties())
+ {
+ if (excluded.contains(prop.getName()))
+ {
+ // log.Debug(String.Format("Setting Property Default {0}",
+ // prop.Name)) ;
+ safeAddProperty(prop.getName(), null);
+ } else
+ {
+ // log.Debug(String.Format("Setting Property {0}",
+ // prop.Name)) ;
+ safeAddProperty(prop.getName(), session.decodeValue(dec,
+ prop.getType()));
+ }
+ }
+ }
+ if (hasStats)
+ {
+ for (SchemaStatistic stat : getSchema().getAllStatistics())
+ {
+ // log.Debug(String.Format("Setting Statistic {0}", stat.Name))
+ // ;
+ statistics.put(stat.getName(), session.decodeValue(dec, stat
+ .getType()));
+ }
+ }
+ }
+
+ public final long agentBank()
+ {
+ return getObjectID().agentBank();
+ }
+
+ public final long brokerBank()
+ {
+ return getObjectID().brokerBank();
+ }
+
+ public final void encode(Encoder enc)
+ {
+ int mask = 0;
+ int bit = 0;
+ java.util.ArrayList<SchemaProperty> propsToEncode = new java.util.ArrayList<SchemaProperty>();
+ log.debug(String.format("Encoding class %s:%s", getSchema()
+ .getPackageName(), getSchema().getClassName()));
+ enc.writeUint8((short) 20);
+ getSchema().getKey().encode(enc);
+ for (SchemaProperty prop : getSchema().getAllProperties())
+ {
+ if (prop.getOptional())
+ {
+ if (bit == 0)
+ {
+ bit = 1;
+ }
+ if ((properties.containsKey(prop.getName()))
+ && (properties.get(prop.getName()) != null))
+ {
+ mask |= bit;
+ propsToEncode.add(prop);
+ } else
+ {
+ }
+ bit = bit << 1;
+ if (bit == 256)
+ {
+ bit = 0;
+ enc.writeUint8((short) mask);
+ mask = 0;
+ }
+ } else
+ {
+ propsToEncode.add(prop);
+ }
+ }
+ if (bit != 0)
+ {
+ enc.writeUint8((short) mask);
+ }
+ for (SchemaProperty prop : propsToEncode)
+ {
+ Object obj = properties.get(prop.getName());
+ // log.Debug(String.Format("Encoding property {0}", prop.Name)) ;
+ getSession().encodeValue(enc, prop.getType(), obj);
+ }
+ for (SchemaStatistic stat : getSchema().statistics)
+ {
+ Object obj = statistics.get(stat.getName());
+ getSession().encodeValue(enc, stat.getType(), obj);
+ }
+ log.debug("Done");
+ }
+
+ public final Date getCreateTime()
+ {
+ return createTime;
+ }
+
+ public final Date getCurrentTime()
+ {
+ return currentTime;
+ }
+
+ public final Date getDeleteTime()
+ {
+ return deleteTime;
+ }
+
+ protected final ArrayList<SchemaMethod> getMethods()
+ {
+ return getSchema().getAllMethods();
+ }
+
+ public final ObjectID getObjectID()
+ {
+ return objectID;
+ }
+
+ public final Object getProperty(String attributeName)
+ {
+ return properties.get(attributeName);
+ }
+
+ public SchemaClass getSchema()
+ {
+ return schema;
+ }
+
+ public final Session getSession()
+ {
+ return session;
+ }
+
+ protected final MethodResult internalInvokeMethod(String name,
+ List<Object> args, boolean synchronous, int timeToLive)
+ {
+ if (!managed)
+ {
+ throw new ConsoleException("Object is not Managed");
+ }
+ if (getSchema().getMethod(name) == null)
+ {
+ throw new ConsoleException(String.format(
+ "Method named '%s' does not exist", name));
+ }
+ return getSession().invokeMethod(this, name, args, synchronous,
+ timeToLive);
+ }
+
+ public final MethodResult invokeMethod(String name, boolean synchronous,
+ int timeToLive, Object... args)
+ {
+ return this.internalInvokeMethod(name, Arrays.asList(args),
+ synchronous, timeToLive);
+ }
+
+ public final MethodResult invokeMethod(String name, boolean synchronous,
+ Object... args)
+ {
+ return this.internalInvokeMethod(name, Arrays.asList(args),
+ synchronous, Broker.SYNC_TIME);
+ }
+
+ public final MethodResult invokeMethod(String name, int timeToLive,
+ Object... args)
+ {
+ return this.internalInvokeMethod(name, Arrays.asList(args), true,
+ timeToLive);
+ }
+
+ public final MethodResult invokeMethod(String name, Object... args)
+ {
+ return this.internalInvokeMethod(name, Arrays.asList(args), true,
+ Broker.SYNC_TIME);
+ }
+
+ public final boolean isDeleted()
+ {
+ return !getDeleteTime().equals(new java.util.Date(0));
+ }
+
+ protected final ArrayList<String> processPresenceMasks(Decoder dec,
+ SchemaClass schema)
+ {
+ java.util.ArrayList<String> excludes = new java.util.ArrayList<String>();
+ short bit = 0;
+ short mask = 0;
+ for (SchemaProperty prop : getSchema().getAllProperties())
+ {
+ if (prop.getOptional())
+ {
+ // log.Debug(String.Format("Property named {0} is optional",
+ // prop.Name)) ;
+ if (bit == 0)
+ {
+ mask = dec.readUint8();
+ bit = 1;
+ }
+ if ((mask & bit) == 0)
+ {
+ // log.Debug(String.Format("Property named {0} is not present",
+ // prop.Name)) ;
+ excludes.add(prop.getName());
+ }
+ bit *= 2;
+ if (bit == 256)
+ {
+ bit = 0;
+ }
+ }
+ }
+ return excludes;
+ }
+
+ public final String routingKey()
+ {
+ return getObjectID().routingCode();
+ }
+
+ protected final void safeAddProperty(String propName, Object value)
+ {
+ if (properties.containsKey(propName))
+ {
+ properties.put(propName, value);
+ } else
+ {
+ properties.put(propName, value);
+ }
+ }
+
+ public final void setCreateTime(java.util.Date value)
+ {
+ createTime = value;
+ }
+
+ public final void setCurrentTime(java.util.Date value)
+ {
+ currentTime = value;
+ }
+
+ public final void setDeleteTime(java.util.Date value)
+ {
+ deleteTime = value;
+ }
+
+ public final void setObjectID(ObjectID value)
+ {
+ objectID = value;
+ }
+
+ public final void setProperty(String attributeName, Object newValue)
+ {
+ properties.put(attributeName, newValue);
+ }
+
+ public void setSchema(SchemaClass value)
+ {
+ schema = value;
+ }
+
+ public final void setSession(Session value)
+ {
+ session = value;
+ }
+
+ protected final void setStatistic(String attributeName, Object newValue)
+ {
+ statistics.put(attributeName, newValue);
+ }
+
+ @Override
+ public String toString()
+ {
+ String propertyString = "";
+ for (Entry<String, Object> pair : properties.entrySet())
+ {
+ propertyString = propertyString
+ + String.format("(Name: '%0$s' Value: '%1$s')", pair
+ .getKey(), pair.getValue());
+ }
+ String statsString = "";
+ for (Entry<String, Object> sPair : statistics.entrySet())
+ {
+ statsString = statsString
+ + String.format("(Name: '%0$s' Value: '%1$s')", sPair
+ .getKey(), sPair.getValue());
+ }
+ if (managed)
+ {
+ return String
+ .format(
+ "Managed QMFObject %0$s:%1$s(%2$s) Properties: [%3$s] Statistics: [%4$s])",
+ getSchema().getPackageName(), getSchema()
+ .getClassName(), getObjectID(),
+ propertyString, statsString);
+ } else
+ {
+ return String
+ .format(
+ "QMFObject %0$s:%1$s Properties: [%2$s] Statistics: [%3$s]",
+ getSchema().getPackageName(), getSchema()
+ .getClassName(), propertyString,
+ statsString);
+ }
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/console/src/main/java/org/apache/qpid/console/SchemaArgument.java b/qpid/java/management/console/src/main/java/org/apache/qpid/console/SchemaArgument.java
new file mode 100644
index 0000000000..7e83b1b447
--- /dev/null
+++ b/qpid/java/management/console/src/main/java/org/apache/qpid/console/SchemaArgument.java
@@ -0,0 +1,65 @@
+/*
+ *
+ * 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.console;
+
+import java.util.Map;
+
+import org.apache.qpid.transport.codec.Decoder;
+
+public class SchemaArgument extends SchemaVariable
+{
+ private String direction;
+
+ public SchemaArgument(Decoder dec, boolean methodArg)
+ {
+ Map<String, Object> map = dec.readMap();
+ super.populateData(map);
+ if (map.containsKey("dir"))
+ {
+ setDirection((String) map.get("dir"));
+ }
+ }
+
+ public String getDirection()
+ {
+ return direction;
+ }
+
+ public boolean isBidirectional()
+ {
+ return getDirection().equals("IO");
+ }
+
+ public boolean isInput()
+ {
+ return getDirection().equals("I") | getDirection().equals("IO");
+ }
+
+ public boolean isOutput()
+ {
+ return getDirection().equals("O") | getDirection().equals("IO");
+ }
+
+ public void setDirection(String value)
+ {
+ direction = value;
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/console/src/main/java/org/apache/qpid/console/SchemaClass.java b/qpid/java/management/console/src/main/java/org/apache/qpid/console/SchemaClass.java
new file mode 100644
index 0000000000..311d81cc8e
--- /dev/null
+++ b/qpid/java/management/console/src/main/java/org/apache/qpid/console/SchemaClass.java
@@ -0,0 +1,251 @@
+/*
+ *
+ * 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.console;//
+
+import java.util.ArrayList;
+
+import org.apache.qpid.transport.codec.*;
+
+public class SchemaClass
+{
+ public static final int CLASS_KIND_EVENT = 2;
+ public static final int CLASS_KIND_TABLE = 1;
+ public ArrayList<SchemaArgument> arguments = new ArrayList<SchemaArgument>();
+ private ClassKey classKey;
+ private int kind;
+ private Session session;
+ private ClassKey superType;
+ public ArrayList<SchemaMethod> methods = new ArrayList<SchemaMethod>();
+ public ArrayList<SchemaProperty> properties = new ArrayList<SchemaProperty>();
+ public ArrayList<SchemaStatistic> statistics = new ArrayList<SchemaStatistic>();
+
+ public SchemaClass(int kind, ClassKey key, Decoder dec, Session session)
+ {
+ // System.Console.WriteLine(key.ClassName) ;
+ setKind(kind);
+ setSession(session);
+ this.setKey(key);
+ boolean hasSupertype = false; //dec.readUint8() != 0;
+ if (kind == CLASS_KIND_TABLE)
+ {
+ int propCount = dec.readUint16();
+ int statCount = dec.readUint16();
+ int methodCount = dec.readUint16();
+ if (hasSupertype)
+ {
+ setSuperType(new ClassKey(dec));
+ }
+ for (int x = 0; x < propCount; x++)
+ {
+ properties.add(new SchemaProperty(dec));
+ }
+ for (int x = 0; x < statCount; x++)
+ {
+ statistics.add(new SchemaStatistic(dec));
+ }
+ for (int x = 0; x < methodCount; x++)
+ {
+ methods.add(new SchemaMethod(dec));
+ }
+ }
+ if (kind == CLASS_KIND_EVENT)
+ {
+ int argCount = dec.readUint16();
+ if (hasSupertype)
+ {
+ setSuperType(new ClassKey(dec));
+ }
+ for (int x = 0; x < argCount; x++)
+ {
+ arguments.add(new SchemaArgument(dec, false));
+ }
+ }
+ }
+
+ public ArrayList<SchemaMethod> getAllMethods()
+ {
+ if (getSuperType() == null)
+ {
+ return methods;
+ } else
+ {
+ ArrayList<SchemaMethod> allMethods = new ArrayList<SchemaMethod>(
+ methods);
+ allMethods.addAll(getSession().getSchema(getSuperType())
+ .getAllMethods());
+ return allMethods;
+ }
+ }
+
+ public ArrayList<SchemaProperty> getAllProperties()
+ {
+ if (getSuperType() == null)
+ {
+ return properties;
+ } else
+ {
+ ArrayList<SchemaProperty> allProperties = new ArrayList<SchemaProperty>(
+ properties);
+ allProperties.addAll(getSession().getSchema(getSuperType())
+ .getAllProperties());
+ return allProperties;
+ }
+ }
+
+ public ArrayList<SchemaStatistic> getAllStatistics()
+ {
+ if (getSuperType() == null)
+ {
+ return statistics;
+ } else
+ {
+ ArrayList<SchemaStatistic> allStats = new ArrayList<SchemaStatistic>(
+ statistics);
+ allStats.addAll(getSession().getSchema(getSuperType())
+ .getAllStatistics());
+ return allStats;
+ }
+ }
+
+ public String getClassKeyString()
+ {
+ return getKey().getKeyString();
+ }
+
+ public String getClassName()
+ {
+ return getKey().getClassName();
+ }
+
+ public ClassKey getKey()
+ {
+ return classKey;
+ }
+
+ public int getKind()
+ {
+ return kind;
+ }
+
+ public SchemaMethod getMethod(String name)
+ {
+ SchemaMethod returnValue = null;
+ for (SchemaMethod method : methods)
+ {
+ if (method.getName().equals(name))
+ {
+ returnValue = method;
+ break;
+ }
+ }
+ return returnValue;
+ }
+
+ public String getPackageName()
+ {
+ return getKey().getPackageName();
+ }
+
+ protected Session getSession()
+ {
+ return session;
+ }
+
+ public ClassKey getSuperType()
+ {
+ return superType;
+ }
+
+ public boolean hasSuperType()
+ {
+ return getSuperType() != null;
+ }
+
+ public void setKey(ClassKey value)
+ {
+ classKey = value;
+ }
+
+ public void setKind(int value)
+ {
+ kind = value;
+ }
+
+ protected void setSession(Session value)
+ {
+ session = value;
+ }
+
+ public void setSuperType(ClassKey value)
+ {
+ superType = value;
+ }
+
+ public ArrayList<SchemaProperty> getProperties()
+ {
+ return properties;
+ }
+
+ public void setProperties(ArrayList<SchemaProperty> properties)
+ {
+ this.properties = properties;
+ }
+
+ public ArrayList<SchemaMethod> getMethods()
+ {
+ return methods;
+ }
+
+ public void setMethods(ArrayList<SchemaMethod> methods)
+ {
+ this.methods = methods;
+ }
+
+ public ArrayList<SchemaStatistic> getStatistics()
+ {
+ return statistics;
+ }
+
+ public void setStatistics(ArrayList<SchemaStatistic> statistics)
+ {
+ this.statistics = statistics;
+ }
+
+ public ArrayList<SchemaArgument> getArguments()
+ {
+ return arguments;
+ }
+
+ public void setArguments(ArrayList<SchemaArgument> arguments)
+ {
+ this.arguments = arguments;
+ }
+
+ public ClassKey getClassKey()
+ {
+ return classKey;
+ }
+
+ public void setClassKey(ClassKey classKey)
+ {
+ this.classKey = classKey;
+ }
+}
diff --git a/qpid/java/management/console/src/main/java/org/apache/qpid/console/SchemaMethod.java b/qpid/java/management/console/src/main/java/org/apache/qpid/console/SchemaMethod.java
new file mode 100644
index 0000000000..1c20ae55bb
--- /dev/null
+++ b/qpid/java/management/console/src/main/java/org/apache/qpid/console/SchemaMethod.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.console;//
+
+import java.util.ArrayList;
+import java.util.Map;
+
+import org.apache.qpid.transport.codec.*;
+
+public class SchemaMethod
+{
+ public ArrayList<SchemaArgument> Arguments = new ArrayList<SchemaArgument>();
+ private int m_ArgCount;
+ private int m_BidirectionalArgCount;
+ private String m_Description;
+ private int m_InputArgCount;
+ private String m_Name;
+ private int m_OutputArgCount;
+
+ public SchemaMethod(Decoder dec)
+ {
+ Map<String, Object> map = dec.readMap();
+ setName((String) map.get("name"));
+ setArgCount((Integer) map.get("argCount"));
+ if (map.containsKey("desc"))
+ {
+ setDescription((String) map.get("desc"));
+ }
+ for (int x = 0; x < getArgCount(); x++)
+ {
+ SchemaArgument arg = new SchemaArgument(dec, true);
+ Arguments.add(arg);
+ if (arg.isInput())
+ {
+ setInputArgCount(getInputArgCount() + 1);
+ }
+ if (arg.isOutput())
+ {
+ setOutputArgCount(getOutputArgCount() + 1);
+ }
+ if (arg.isBidirectional())
+ {
+ setBidirectionalArgCount(getBidirectionalArgCount() + 1);
+ }
+ }
+ }
+
+ public final int getArgCount()
+ {
+ return m_ArgCount;
+ }
+
+ public final int getBidirectionalArgCount()
+ {
+ return m_BidirectionalArgCount;
+ }
+
+ public final String getDescription()
+ {
+ return m_Description;
+ }
+
+ public final int getInputArgCount()
+ {
+ return m_InputArgCount;
+ }
+
+ public final String getName()
+ {
+ return m_Name;
+ }
+
+ public final int getOutputArgCount()
+ {
+ return m_OutputArgCount;
+ }
+
+ public final void setArgCount(int value)
+ {
+ m_ArgCount = value;
+ }
+
+ public final void setBidirectionalArgCount(int value)
+ {
+ m_BidirectionalArgCount = value;
+ }
+
+ public final void setDescription(String value)
+ {
+ m_Description = value;
+ }
+
+ public final void setInputArgCount(int value)
+ {
+ m_InputArgCount = value;
+ }
+
+ public final void setName(String value)
+ {
+ m_Name = value;
+ }
+
+ public final void setOutputArgCount(int value)
+ {
+ m_OutputArgCount = value;
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/console/src/main/java/org/apache/qpid/console/SchemaProperty.java b/qpid/java/management/console/src/main/java/org/apache/qpid/console/SchemaProperty.java
new file mode 100644
index 0000000000..8e278ff70d
--- /dev/null
+++ b/qpid/java/management/console/src/main/java/org/apache/qpid/console/SchemaProperty.java
@@ -0,0 +1,81 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.console;
+
+import java.util.Map;
+
+import org.apache.qpid.transport.codec.*;
+
+public class SchemaProperty extends SchemaVariable
+{
+ private int access;
+ private boolean index;
+ private boolean optional;
+
+ public SchemaProperty(Decoder dec)
+ {
+ Map<String, Object> map = dec.readMap();
+ super.populateData(map);
+ setName((String) map.get("name"));
+ if (map.containsKey("optional"))
+ {
+ setOptional((Integer) map.get("optional") != 0);
+ }
+ if (map.containsKey("index"))
+ {
+ setIndex((Integer) map.get("index") != 0);
+ }
+ if (map.containsKey("access"))
+ {
+ setAccess((Integer) map.get("access"));
+ }
+ }
+
+ public int getAccess()
+ {
+ return access;
+ }
+
+ public boolean getIndex()
+ {
+ return index;
+ }
+
+ public boolean getOptional()
+ {
+ return optional;
+ }
+
+ public void setAccess(int value)
+ {
+ access = value;
+ }
+
+ public void setIndex(boolean value)
+ {
+ index = value;
+ }
+
+ public void setOptional(boolean value)
+ {
+ optional = value;
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/console/src/main/java/org/apache/qpid/console/SchemaStatistic.java b/qpid/java/management/console/src/main/java/org/apache/qpid/console/SchemaStatistic.java
new file mode 100644
index 0000000000..18bce86423
--- /dev/null
+++ b/qpid/java/management/console/src/main/java/org/apache/qpid/console/SchemaStatistic.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.console;//
+
+import java.util.Map;
+
+import org.apache.qpid.transport.codec.*;
+
+public class SchemaStatistic
+{
+ private String description;
+ private String name;
+ private short type;
+ private String unit;
+
+ public SchemaStatistic(Decoder dec)
+ {
+ Map<String, Object> map = dec.readMap();
+ setName((String) map.get("name"));
+ setType(Short.parseShort("" + map.get("type")));
+ if (map.containsKey("unit"))
+ {
+ setUnit((String) map.get("unit"));
+ }
+ if (map.containsKey("description"))
+ {
+ setDescription((String) map.get("description"));
+ }
+ }
+
+ public String getDescription()
+ {
+ return description;
+ }
+
+ public String getName()
+ {
+ return name;
+ }
+
+ public short getType()
+ {
+ return type;
+ }
+
+ public String getUnit()
+ {
+ return unit;
+ }
+
+ public void setDescription(String value)
+ {
+ description = value;
+ }
+
+ public void setName(String value)
+ {
+ name = value;
+ }
+
+ public void setType(short value)
+ {
+ type = value;
+ }
+
+ public void setUnit(String value)
+ {
+ unit = value;
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/console/src/main/java/org/apache/qpid/console/SchemaVariable.java b/qpid/java/management/console/src/main/java/org/apache/qpid/console/SchemaVariable.java
new file mode 100644
index 0000000000..483a17d0de
--- /dev/null
+++ b/qpid/java/management/console/src/main/java/org/apache/qpid/console/SchemaVariable.java
@@ -0,0 +1,185 @@
+/*
+ *
+ * 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.console;
+
+import java.util.Map;
+
+public abstract class SchemaVariable
+{
+ private String defaultVariable;
+ private String description;
+ private Integer max;
+ private Integer maxLength;
+ private Integer min;
+ private String name;
+ private String refClass;
+ private String refPackage;
+ private short type;
+ private String unit;
+
+ public SchemaVariable()
+ {
+ }
+
+ public String getDefault()
+ {
+ return defaultVariable;
+ }
+
+ public String getDescription()
+ {
+ return description;
+ }
+
+ public Integer getMax()
+ {
+ return max;
+ }
+
+ public Integer getMaxLength()
+ {
+ return maxLength;
+ }
+
+ public Integer getMin()
+ {
+ return min;
+ }
+
+ public String getName()
+ {
+ return name;
+ }
+
+ public String getRefClass()
+ {
+ return refClass;
+ }
+
+ public String getRefPackage()
+ {
+ return refPackage;
+ }
+
+ public short getType()
+ {
+ return type;
+ }
+
+ public String getUnit()
+ {
+ return unit;
+ }
+
+ protected void populateData(Map<String, Object> map)
+ {
+ if (map.containsKey("name"))
+ {
+ setName((String) map.get("name"));
+ }
+ if (map.containsKey("type"))
+ {
+ setType(Short.parseShort(("" + map.get("type"))));
+ }
+ if (map.containsKey("unit"))
+ {
+ setUnit((String) map.get("unit"));
+ }
+ if (map.containsKey("min"))
+ {
+ setMin((Integer) map.get("min"));
+ }
+ if (map.containsKey("max"))
+ {
+ setMax((Integer) map.get("max"));
+ }
+ if (map.containsKey("maxlen"))
+ {
+ setMaxLength((Integer) map.get("maxlen"));
+ }
+ if (map.containsKey("description"))
+ {
+ setDescription((String) map.get("description"));
+ }
+ if (map.containsKey("refClass"))
+ {
+ setRefClass((String) map.get("refClass"));
+ }
+ if (map.containsKey("refPackage"))
+ {
+ setRefPackage((String) map.get("refPackage"));
+ }
+ if (map.containsKey("Default"))
+ {
+ setDefault((String) map.get("default"));
+ }
+ }
+
+ public void setDefault(String value)
+ {
+ defaultVariable = value;
+ }
+
+ public void setDescription(String value)
+ {
+ description = value;
+ }
+
+ public void setMax(Integer value)
+ {
+ max = value;
+ }
+
+ public void setMaxLength(Integer value)
+ {
+ maxLength = value;
+ }
+
+ public void setMin(Integer value)
+ {
+ min = value;
+ }
+
+ public void setName(String value)
+ {
+ name = value;
+ }
+
+ public void setRefClass(String value)
+ {
+ refClass = value;
+ }
+
+ public void setRefPackage(String value)
+ {
+ refPackage = value;
+ }
+
+ public void setType(short value)
+ {
+ type = value;
+ }
+
+ public void setUnit(String value)
+ {
+ unit = value;
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/console/src/main/java/org/apache/qpid/console/SequenceManager.java b/qpid/java/management/console/src/main/java/org/apache/qpid/console/SequenceManager.java
new file mode 100644
index 0000000000..4c5fcc7355
--- /dev/null
+++ b/qpid/java/management/console/src/main/java/org/apache/qpid/console/SequenceManager.java
@@ -0,0 +1,57 @@
+/*
+ *
+ * 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.console;
+
+import java.util.HashMap;
+
+public class SequenceManager
+{
+ private long sequence = 0;
+ private HashMap<Long, Object> pending = new HashMap<Long, Object>();
+ private Object lockObject = new Object();
+
+ public SequenceManager()
+ {
+ }
+
+ public Object release(long seq)
+ {
+ Object returnValue = null;
+ synchronized (lockObject)
+ {
+ returnValue = pending.get(seq);
+ pending.remove(seq);
+ }
+ return returnValue;
+ }
+
+ public long reserve(Object data)
+ {
+ long returnValue = 0;
+ synchronized (lockObject)
+ {
+ returnValue = sequence;
+ sequence += 1;
+ pending.put(returnValue, data);
+ }
+ return returnValue;
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/console/src/main/java/org/apache/qpid/console/Session.java b/qpid/java/management/console/src/main/java/org/apache/qpid/console/Session.java
new file mode 100644
index 0000000000..a590a95546
--- /dev/null
+++ b/qpid/java/management/console/src/main/java/org/apache/qpid/console/Session.java
@@ -0,0 +1,980 @@
+/*
+ *
+ * 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.console;//
+
+import java.lang.reflect.Constructor;
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+import javax.jms.Message;
+
+import org.apache.qpid.transport.codec.BBDecoder;
+import org.apache.qpid.transport.codec.BBEncoder;
+import org.apache.qpid.transport.codec.Decoder;
+import org.apache.qpid.transport.codec.Encoder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class Session
+{
+ private static Logger log = LoggerFactory.getLogger(Session.class);
+ public static final int CONTEXT_SYNC = 1;
+ public static final int CONTEXT_STARTUP = 2;
+ public static final int CONTEXT_MULTIGET = 3;
+ public static final int DEFAULT_GET_WAIT_TIME = 60000;
+ public boolean recieveObjects = true;
+ public boolean recieveEvents = true;
+ public boolean recieveHeartbeat = true;
+ public boolean userBindings = false;
+ public Console console;
+ protected HashMap<String, HashMap<String, SchemaClass>> packages = new HashMap<String, HashMap<String, SchemaClass>>();
+ protected ArrayList<Broker> brokers = new ArrayList<Broker>();
+ protected SequenceManager sequenceManager = new SequenceManager();
+ protected Object lockObject = new Object();
+ protected ArrayList<Long> syncSequenceList = new ArrayList<Long>();
+ protected ArrayList<QMFObject> getResult;
+ protected Object syncResult;
+
+ public Session()
+ {
+ }
+
+ public Session(Console console)
+ {
+ this.console = console;
+ }
+
+ public void addBroker(String url)
+ {
+ Broker broker = new Broker(this, url);
+ brokers.add(broker);
+ java.util.HashMap<String, Object> args = new java.util.HashMap<String, Object>();
+ args.put("_class", "agent");
+ args.put("_broker", broker);
+ this.getObjects(args);
+ }
+
+ public ArrayList<String> bindingKeys()
+ {
+ ArrayList<String> bindings = new ArrayList<String>();
+ bindings.add("schema.#");
+ if (recieveObjects && recieveEvents && recieveHeartbeat && !userBindings)
+ {
+ bindings.add("console.#");
+ } else
+ {
+ if (recieveObjects && !userBindings)
+ {
+ bindings.add("console.obj.#");
+ } else
+ {
+ bindings.add("console.obj.*.*.org.apache.qpid.broker.agent");
+ }
+ if (recieveEvents)
+ {
+ bindings.add("console.event.#");
+ }
+ if (recieveHeartbeat)
+ {
+ bindings.add("console.heartbeat.#");
+ }
+ }
+ return bindings;
+ }
+
+ public void close()
+ {
+ for (Broker broker : brokers.toArray(new Broker[0]))
+ {
+ this.removeBroker(broker);
+ }
+ }
+
+ protected QMFObject createQMFObject(SchemaClass schema,
+ boolean hasProperties, boolean hasStats, boolean isManaged)
+ {
+ Class realClass = QMFObject.class;
+ if (console != null)
+ {
+ realClass = console.typeMapping(schema.getKey());
+ }
+ Class[] types = new Class[]
+ { Session.class, SchemaClass.class, boolean.class, boolean.class,
+ boolean.class };
+ Object[] args = new Object[]
+ { this, schema, hasProperties, hasStats, isManaged };
+ try
+ {
+ Constructor ci = realClass.getConstructor(types);
+ return (QMFObject) ci.newInstance(args);
+ } catch (Exception e)
+ {
+ throw new ConsoleException(e);
+ }
+ }
+
+ protected QMFObject createQMFObject(SchemaClass schema, Decoder dec,
+ boolean hasProperties, boolean hasStats, boolean isManaged)
+ {
+ Class realClass = QMFObject.class;
+ if (console != null)
+ {
+ realClass = console.typeMapping(schema.getKey());
+ }
+ Class[] types = new Class[]
+ { Session.class, SchemaClass.class, Decoder.class, boolean.class,
+ boolean.class, boolean.class };
+ Object[] args = new Object[]
+ { this, schema, dec, hasProperties, hasStats, isManaged };
+ try
+ {
+ log.debug("" + realClass);
+ Constructor ci = realClass.getConstructor(types);
+ return (QMFObject) ci.newInstance(args);
+ } catch (Exception e)
+ {
+ throw new ConsoleException(e);
+ }
+ }
+
+ public Object decodeValue(Decoder dec, short type)
+ {
+ switch (type)
+ {
+ case 1: // U8
+ return dec.readUint8();
+ case 2: // U16
+ return dec.readUint16();
+ case 3: // U32
+ return dec.readUint32();
+ case 4: // U64
+ return dec.readUint64();
+ case 6: // SSTR
+ return dec.readStr8();
+ case 7: // LSTR
+ return dec.readStr16();
+ case 8: // ABSTIME
+ return dec.readDatetime();
+ case 9: // DELTATIME
+ return dec.readUint32();
+ case 10: // ref
+ return new ObjectID(dec);
+ case 11: // bool
+ return dec.readUint8() != 0;
+ case 12: // float
+ return dec.readFloat();
+ case 13: // double
+ return dec.readDouble();
+ case 14: // UUID
+ return dec.readUuid();
+ case 15: // Ftable
+ return dec.readMap();
+ case 16: // int8
+ return dec.readInt8();
+ case 17: // int16
+ return dec.readInt16();
+ case 18: // int32
+ return dec.readInt32();
+ case 19: // int64
+ return dec.readInt64();
+ case 20: // Object
+ // Peek into the inner type code, make sure
+ // it is actually an object
+ Object returnValue = null;
+ short innerTypeCode = dec.readUint8();
+ if (innerTypeCode != 20)
+ {
+ returnValue = this.decodeValue(dec, innerTypeCode);
+ } else
+ {
+ ClassKey classKey = new ClassKey(dec);
+ synchronized (lockObject)
+ {
+ SchemaClass sClass = getSchema(classKey);
+ if (sClass != null)
+ {
+ returnValue = this.createQMFObject(sClass, dec, true,
+ true, false);
+ }
+ }
+ }
+ return returnValue;
+ case 21: // List
+ BBDecoder lDec = new BBDecoder();
+ lDec.init(ByteBuffer.wrap(dec.readVbin32()));
+ long count = lDec.readUint32();
+ ArrayList<Object> newList = new ArrayList<Object>();
+ while (count > 0)
+ {
+ short innerType = lDec.readUint8();
+ newList.add(this.decodeValue(lDec, innerType));
+ count -= 1;
+ }
+ return newList;
+ case 22: // Array
+ BBDecoder aDec = new BBDecoder();
+ aDec.init(ByteBuffer.wrap(dec.readVbin32()));
+ long cnt = aDec.readUint32();
+ short innerType = aDec.readUint8();
+ ArrayList<Object> aList = new ArrayList<Object>();
+ while (cnt > 0)
+ {
+ aList.add(this.decodeValue(aDec, innerType));
+ cnt -= 1;
+ }
+ return aList;
+ default:
+ throw new ConsoleException(String.format("Invalid Type Code: %s",
+ type));
+ }
+ }
+
+ public void encodeValue(Encoder enc, short type, Object val)
+ {
+ try
+ {
+ switch (type)
+ {
+ case 1: // U8
+ enc.writeUint8(((Short) val).shortValue());
+ break;
+ case 2: // U16
+ enc.writeUint16(((Integer) val).intValue());
+ break;
+ case 3: // U32
+ enc.writeUint32(((Integer) val).longValue());
+ break;
+ case 4: // U64
+ enc.writeUint64(((Long) val).longValue());
+ break;
+ case 6: // SSTR
+ enc.writeStr8((String) val);
+ break;
+ case 7: // LSTR
+ enc.writeStr16((String) val);
+ break;
+ case 8: // ABSTIME
+ enc.writeDatetime(((Long) val).longValue());
+ break;
+ case 9: // DELTATIME
+ enc.writeUint32(((Long) val).longValue());
+ break;
+ case 10: // ref
+ ((ObjectID) val).encode(enc);
+ break;
+ case 11:
+ if (((Boolean) val).booleanValue())
+ {
+ enc.writeUint8((short) 1);
+ } else
+ {
+ enc.writeUint8((short) 0);
+ }
+ break;
+ case 12: // FLOAT
+ enc.writeFloat(((Float) val).floatValue());
+ break;
+ case 13: // DOUBLE
+ enc.writeDouble(((Double) val).doubleValue());
+ break;
+ case 14: // UUID
+ enc.writeUuid((UUID) val);
+ break;
+ case 15: // Ftable
+ enc.writeMap((HashMap) val);
+ break;
+ case 16: // int8
+ enc.writeInt8((Byte) val);
+ break;
+ case 17: // int16
+ enc.writeInt16((Short) val);
+ break;
+ case 18: // int32
+ enc.writeInt32((Integer) val);
+ break;
+ case 19: // int64
+ enc.writeInt64((Long) val);
+ break;
+ case 20: // Object
+ // Check that the object has a session, if not
+ // take ownership of it
+ QMFObject qObj = (QMFObject) val;
+ if (qObj.getSession() == null)
+ {
+ qObj.setSession(this);
+ }
+ qObj.encode(enc);
+ break;
+ case 21: // List
+ ArrayList<Object> items = (ArrayList<Object>) val;
+ BBEncoder lEnc = new BBEncoder(1);
+ lEnc.init();
+ lEnc.writeUint32(items.size());
+ for (Object obj : items)
+ {
+ short innerType = Util.qmfType(obj);
+ lEnc.writeUint8(innerType);
+ this.encodeValue(lEnc, innerType, obj);
+ }
+ enc.writeVbin32(lEnc.segment().array());
+ break;
+ case 22: // Array
+ ArrayList<Object> aItems = (ArrayList<Object>) val;
+ BBEncoder aEnc = new BBEncoder(1);
+ aEnc.init();
+ long aCount = aItems.size();
+ aEnc.writeUint32(aCount);
+ if (aCount > 0)
+ {
+ Object anObj = aItems.get(0);
+ short innerType = Util.qmfType(anObj);
+ aEnc.writeUint8(innerType);
+ for (Object obj : aItems)
+ {
+ this.encodeValue(aEnc, innerType, obj);
+ }
+ }
+ enc.writeVbin32(aEnc.segment().array());
+ break;
+ default:
+ throw new ConsoleException(String.format(
+ "Invalid Type Code: %s", type));
+ }
+ } catch (ClassCastException e)
+ {
+ String msg = String.format(
+ "Class cast exception for typecode %s, type %s ", type, val
+ .getClass());
+ log.error(msg);
+ throw new ConsoleException(msg + type, e);
+ }
+ }
+
+ public Broker getBroker(long BrokerBank)
+ {
+ Broker returnValue = null;
+ for (Broker broker : brokers)
+ {
+ if (broker.brokerBank() == BrokerBank)
+ {
+ returnValue = broker;
+ break;
+ }
+ }
+ return returnValue;
+ }
+
+ public ArrayList<ClassKey> getClasses(String packageName)
+ {
+ ArrayList<ClassKey> returnValue = new ArrayList<ClassKey>();
+ this.waitForStable();
+ if (packages.containsKey(packageName))
+ {
+ for (SchemaClass sClass : packages.get(packageName).values())
+ {
+ returnValue.add(sClass.getKey());
+ }
+ }
+ return returnValue;
+ }
+
+ public ArrayList<QMFObject> getObjects(
+ java.util.HashMap<String, Object> args)
+ {
+ ArrayList<Broker> brokerList = null;
+ ArrayList<Agent> agentList = new ArrayList<Agent>();
+ if (args.containsKey("_broker"))
+ {
+ brokerList = new ArrayList<Broker>();
+ brokerList.add((Broker) args.get("_broker"));
+ } else
+ {
+ brokerList = this.brokers;
+ }
+ for (Broker broker : brokerList)
+ {
+ broker.waitForStable();
+ }
+ if (args.containsKey("_agent"))
+ {
+ Agent agent = (Agent) args.get("_agent");
+ if (brokerList.contains(agent.getBroker()))
+ {
+ agentList.add(agent);
+ } else
+ {
+ throw new ConsoleException(
+ "Agent is not managed by this console or the supplied broker");
+ }
+ } else
+ {
+ if (args.containsKey("_objectId"))
+ {
+ ObjectID oid = (ObjectID) args.get("_objectId");
+ for (Broker broker : brokers)
+ {
+ for (Agent agent : broker.Agents.values())
+ {
+ if ((agent.getAgentBank() == oid.agentBank())
+ && (agent.getBrokerBank() == oid.brokerBank()))
+ {
+ agentList.add(agent);
+ }
+ }
+ }
+ } else
+ {
+ for (Broker broker : brokerList)
+ {
+ for (Agent agent : broker.Agents.values())
+ {
+ if (agent.getBroker().isConnected())
+ {
+ agentList.add(agent);
+ }
+ }
+ }
+ }
+ }
+ getResult = new ArrayList<QMFObject>();
+ if (agentList.size() > 0)
+ {
+ // FIXME Add a bunch of other suff too
+ for (Agent agent : agentList)
+ {
+ HashMap<String, Object> getParameters = new HashMap<String, Object>();
+ Broker broker = agent.getBroker();
+ long seq = -1;
+ synchronized (lockObject)
+ {
+ seq = sequenceManager.reserve(Session.CONTEXT_MULTIGET);
+ syncSequenceList.add(seq);
+ }
+ String packageName = (String) args.get("_package");
+ String className = (String) args.get("_class");
+ ClassKey key = (ClassKey) args.get("_key");
+ Object sClass = args.get("_schema");
+ Object oid = args.get("_objectID");
+ long[] hash = (long[]) args.get("_hash");
+ if ((className == null) && (oid == null))
+ {
+ throw new ConsoleException(
+ "No class supplied, use '_schema', '_key', '_class', or '_objectId' argument");
+ }
+ if (oid != null)
+ {
+ getParameters.put("_objectID", oid);
+ } else
+ {
+ if (sClass != null)
+ {
+ key = (key != null) ? key : ((SchemaClass) sClass)
+ .getKey();
+ }
+ if (key != null)
+ {
+ className = (className != null) ? className : key
+ .getClassName();
+ packageName = (packageName != null) ? packageName : key
+ .getPackageName();
+ hash = (hash != null) ? hash : key.getHash();
+ }
+ if (packageName != null)
+ {
+ getParameters.put("_package", packageName);
+ }
+ if (className != null)
+ {
+ getParameters.put("_class", className);
+ }
+ if (hash != null)
+ {
+ getParameters.put("_hash", hash);
+ }
+ for (java.util.Map.Entry<String, Object> pair : args
+ .entrySet())
+ {
+ if (!pair.getKey().startsWith("_"))
+ {
+ getParameters.put(pair.getKey(), pair.getValue());
+ }
+ }
+ }
+ Encoder enc = broker.createEncoder('G', seq);
+ enc.writeMap(getParameters);
+ String routingKey = agent.routingCode();
+ Message msg = broker.createMessage(enc);
+ log.debug("Get Object Keys: ");
+ for (String pKey : getParameters.keySet())
+ {
+ log.debug(String.format("\tKey: '%s' Value: '%s'", pKey,
+ getParameters.get(pKey)));
+ }
+ broker.send(msg, routingKey);
+ }
+ int waittime = DEFAULT_GET_WAIT_TIME;
+ boolean timeout = false;
+ if (args.containsKey("_timeout"))
+ {
+ waittime = (Integer) args.get("_timeout");
+ }
+ long start = System.currentTimeMillis();
+ synchronized (lockObject)
+ {
+ // FIXME ERROR
+ while (syncSequenceList.size() > 0)
+ {
+ try
+ {
+ lockObject.wait(waittime);
+ } catch (InterruptedException e)
+ {
+ throw new ConsoleException(e);
+ }
+ long duration = System.currentTimeMillis() - start;
+ if (duration > waittime)
+ {
+ for (long pendingSeq : syncSequenceList)
+ {
+ sequenceManager.release(pendingSeq);
+ }
+ syncSequenceList.clear();
+ timeout = true;
+ }
+ }
+ }
+ // FIXME Add the error logic
+ if ((getResult.isEmpty()) && timeout)
+ {
+ throw new ConsoleException("Get Request timed out");
+ }
+ }
+ return getResult;
+ }
+
+ public ArrayList<String> getPackages()
+ {
+ this.waitForStable();
+ ArrayList<String> returnValue = new ArrayList<String>();
+ for (String name : packages.keySet())
+ {
+ returnValue.add(name);
+ }
+ return returnValue;
+ }
+
+ public SchemaClass getSchema(ClassKey key)
+ {
+ return getSchema(key, true);
+ }
+
+ protected SchemaClass getSchema(ClassKey key, boolean waitForStable)
+ {
+ if (waitForStable)
+ {
+ this.waitForStable();
+ }
+ SchemaClass returnValue = null;
+ returnValue = packages.get(key.getPackageName())
+ .get(key.getKeyString());
+ return returnValue;
+ }
+
+ public void handleAgentRemoved(Agent agent)
+ {
+ if (console != null)
+ {
+ console.agentRemoved(agent);
+ }
+ }
+
+ public void handleBrokerConnect(Broker broker)
+ {
+ if (console != null)
+ {
+ console.brokerConnected(broker);
+ }
+ }
+
+ public void handleBrokerDisconnect(Broker broker)
+ {
+ if (console != null)
+ {
+ console.brokerDisconnected(broker);
+ }
+ }
+
+ public void handleBrokerResponse(Broker broker, Decoder decoder,
+ long sequence)
+ {
+ if (console != null)
+ {
+ console.brokerInformation(broker);
+ }
+ long seq = sequenceManager.reserve(CONTEXT_STARTUP);
+ Encoder encoder = broker.createEncoder('P', seq);
+ broker.send(encoder);
+ }
+
+ public void handleClassIndicator(Broker broker, Decoder decoder,
+ long sequence)
+ {
+ short kind = decoder.readUint8();
+ ClassKey classKey = new ClassKey(decoder);
+ boolean unknown = false;
+ synchronized (lockObject)
+ {
+ if (packages.containsKey(classKey.getPackageName()))
+ {
+ if (!packages.get(classKey.getPackageName()).containsKey(
+ classKey.getKeyString()))
+ {
+ unknown = true;
+ }
+ }
+ }
+ if (unknown)
+ {
+ broker.incrementOutstanding();
+ long seq = sequenceManager.reserve(Session.CONTEXT_STARTUP);
+ Encoder enc = broker.createEncoder('S', seq);
+ classKey.encode(enc);
+ broker.send(enc);
+ }
+ }
+
+ public void handleCommandComplete(Broker broker, Decoder decoder,
+ long sequence)
+ {
+ long code = decoder.readUint32();
+ String text = decoder.readStr8();
+ Object context = this.sequenceManager.release(sequence);
+ if (context.equals(CONTEXT_STARTUP))
+ {
+ broker.decrementOutstanding();
+ } else
+ {
+ if ((context.equals(CONTEXT_SYNC)) && broker.getSyncInFlight())
+ {
+ broker.setSyncInFlight(false);
+ } else
+ {
+ if (context.equals(CONTEXT_MULTIGET)
+ && syncSequenceList.contains(sequence))
+ {
+ synchronized (lockObject)
+ {
+ syncSequenceList.remove(sequence);
+ if (syncSequenceList.isEmpty())
+ {
+ lockObject.notifyAll();
+ }
+ }
+ }
+ }
+ }
+ }
+
+ public void handleContentIndicator(Broker broker, Decoder decoder,
+ long sequence, boolean hasProperties, boolean hasStatistics)
+ {
+ ClassKey key = new ClassKey(decoder);
+ SchemaClass sClass = null;
+ ;
+ synchronized (lockObject)
+ {
+ sClass = getSchema(key, false);
+ }
+ if (sClass != null)
+ {
+ QMFObject obj = this.createQMFObject(sClass, decoder,
+ hasProperties, hasStatistics, true);
+ if (key.getPackageName().equals("org.apache.qpid.broker")
+ && key.getClassName().equals("agent") && hasProperties)
+ {
+ broker.updateAgent(obj);
+ }
+ synchronized (lockObject)
+ {
+ if (syncSequenceList.contains(sequence))
+ {
+ if (!obj.isDeleted() && this.selectMatch(obj))
+ {
+ getResult.add(obj);
+ }
+ }
+ }
+ if (console != null)
+ {
+ if (hasProperties)
+ {
+ console.objectProperties(broker, obj);
+ }
+ if (hasStatistics)
+ {
+ console.objectStatistics(broker, obj);
+ }
+ }
+ }
+ }
+
+ public void handleEventIndicator(Broker broker, Decoder decoder,
+ long sequence)
+ {
+ if (console != null)
+ {
+ QMFEvent newEvent = new QMFEvent(this, decoder);
+ console.eventRecieved(broker, newEvent);
+ }
+ }
+
+ public void handleHeartbeatIndicator(Broker broker, Decoder decoder,
+ long sequence, Message msg)
+ {
+ if (console != null)
+ {
+ long brokerBank = 1;
+ long agentBank = 0;
+ try
+ {
+ // FIXME HOW DO WE GET THE ROUTING KEY
+ // String routingKey = msg.DeliveryProperties.getRoutingKey();
+ String routingKey = null;
+ if (routingKey != null)
+ {
+ agentBank = Agent.getBrokerBank(routingKey);
+ brokerBank = Agent.getBrokerBank(routingKey);
+ }
+ } catch (Throwable e)
+ {
+ log.warn("Internal QPID error", e);
+ }
+ String agentKey = Agent.AgentKey(agentBank, brokerBank);
+ long timestamp = decoder.readUint64();
+ if (broker.Agents.containsKey(agentKey))
+ {
+ Agent agent = broker.Agents.get(agentKey);
+ console.hearbeatRecieved(agent, timestamp);
+ }
+ }
+ }
+
+ public void handleMethodResponse(Broker broker, Decoder decoder,
+ long sequence)
+ {
+ long code = decoder.readUint32();
+ String text = decoder.readStr16();
+ java.util.HashMap<String, Object> outArgs = new java.util.HashMap<String, Object>();
+ Object obj = sequenceManager.release(sequence);
+ if (obj == null)
+ {
+ return;
+ }
+ Object[] pair = (Object[]) obj;
+ if (code == 0)
+ {
+ for (SchemaArgument arg : ((SchemaMethod) pair[0]).Arguments)
+ {
+ if (arg.isOutput())
+ {
+ outArgs.put(arg.getName(), this.decodeValue(decoder, arg
+ .getType()));
+ }
+ }
+ }
+ MethodResult result = new MethodResult(code, text, outArgs);
+ if ((Boolean) pair[1])
+ {
+ this.syncResult = result;
+ broker.setSyncInFlight(false);
+ }
+ if (console != null)
+ {
+ console.methodResponse(broker, sequence, result);
+ }
+ }
+
+ // Callback Methods
+ public void handleNewAgent(Agent agent)
+ {
+ if (console != null)
+ {
+ console.newAgent(agent);
+ }
+ }
+
+ public void handlePackageIndicator(Broker broker, Decoder decoder,
+ long sequence)
+ {
+ String packageName = decoder.readStr8();
+ boolean notify = false;
+ if (!packages.containsKey(packageName))
+ {
+ synchronized (lockObject)
+ {
+ packages.put(packageName,
+ new java.util.HashMap<String, SchemaClass>());
+ notify = true;
+ }
+ }
+ if (notify && console != null)
+ {
+ console.newPackage(packageName);
+ }
+ broker.incrementOutstanding();
+ long seq = sequenceManager.reserve(Session.CONTEXT_STARTUP);
+ Encoder enc = broker.createEncoder('Q', seq);
+ enc.writeStr8(packageName);
+ broker.send(enc);
+ }
+
+ public void handleSchemaResponse(Broker broker, Decoder decoder,
+ long sequence)
+ {
+ short kind = decoder.readUint8();
+ ClassKey classKey = new ClassKey(decoder);
+ SchemaClass sClass = new SchemaClass(kind, classKey, decoder, this);
+ synchronized (lockObject)
+ {
+ java.util.HashMap<String, SchemaClass> classMappings = packages
+ .get(sClass.getPackageName());
+ classMappings.remove(sClass.getClassKeyString());
+ classMappings.put(sClass.getClassKeyString(), sClass);
+ log.debug(classKey.toString());
+ }
+ sequenceManager.release(sequence);
+ broker.decrementOutstanding();
+ if (console != null)
+ {
+ this.console.newClass(kind, classKey);
+ }
+ }
+
+ public MethodResult invokeMethod(QMFObject obj, String name,
+ List<Object> args, boolean synchronous, int timeToLive)
+ {
+ Broker aBroker = this.getBroker(obj.brokerBank());
+ long seq = this.sendMethodRequest(obj, aBroker, name, args,
+ synchronous, timeToLive);
+ if (seq != 0)
+ {
+ if (!synchronous)
+ {
+ return null;
+ }
+ try
+ {
+ aBroker.waitForSync(timeToLive);
+ } catch (Throwable e)
+ {
+ sequenceManager.release(seq);
+ throw new ConsoleException(e);
+ }
+ // FIXME missing error logic in the broker
+ return (MethodResult) syncResult;
+ }
+ return null;
+ }
+
+ public QMFObject makeObject(ClassKey key)
+ {
+ SchemaClass sClass = this.getSchema(key);
+ if (sClass == null)
+ {
+ throw new ConsoleException("No schema found for class "
+ + key.toString());
+ }
+ return this.createQMFObject(sClass, true, true, false);
+ }
+
+ public QMFObject makeObject(String keyString)
+ {
+ return this.makeObject(new ClassKey(keyString));
+ }
+
+ public void removeBroker(Broker broker)
+ {
+ if (brokers.contains(broker))
+ {
+ brokers.remove(broker);
+ }
+ broker.shutdown();
+ }
+
+ public boolean selectMatch(QMFObject obj)
+ {
+ return true;
+ }
+
+ protected long sendMethodRequest(QMFObject obj, Broker aBroker,
+ String name, List<Object> args, boolean synchronous, int timeToLive)
+ {
+ SchemaMethod method = obj.getSchema().getMethod(name);
+ if (args == null)
+ {
+ args = new ArrayList<Object>();
+ }
+ long seq = 0;
+ if (method != null)
+ {
+ Object[] pair =
+ { method, synchronous };
+ seq = sequenceManager.reserve(pair);
+ Encoder enc = aBroker.createEncoder('M', seq);
+ obj.getObjectID().encode(enc);
+ obj.getSchema().getKey().encode(enc);
+ enc.writeStr8(name);
+ if (args.size() < method.getInputArgCount())
+ {
+ throw new ConsoleException(String.format(
+ "Incorrect number of arguments: expected %s, got %s",
+ method.getInputArgCount(), args.size()));
+ }
+ int argIndex = 0;
+ for (SchemaArgument arg : method.Arguments)
+ {
+ if (arg.isInput())
+ {
+ this.encodeValue(enc, arg.getType(), args.get(argIndex));
+ argIndex += 1;
+ }
+ }
+ Message msg = aBroker.createMessage(enc);
+ if (synchronous)
+ {
+ aBroker.setSyncInFlight(true);
+ }
+ aBroker.send(msg, obj.routingKey(), timeToLive);
+ }
+ return seq;
+ }
+
+ protected void waitForStable()
+ {
+ for (Broker broker : brokers)
+ {
+ broker.waitForStable();
+ }
+ }
+}
diff --git a/qpid/java/management/console/src/main/java/org/apache/qpid/console/Util.java b/qpid/java/management/console/src/main/java/org/apache/qpid/console/Util.java
new file mode 100644
index 0000000000..a9e4d68601
--- /dev/null
+++ b/qpid/java/management/console/src/main/java/org/apache/qpid/console/Util.java
@@ -0,0 +1,184 @@
+/*
+ *
+ * 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.console;
+
+import java.nio.charset.Charset;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.UUID;
+
+public class Util
+{
+ private static HashMap<Class, Short> ENCODINGS = new HashMap<Class, Short>();
+ static
+ {
+ ENCODINGS.put(String.class, (short) 7);
+ ENCODINGS.put(Short.class, (short) 1);
+ ENCODINGS.put(Float.class, (short) 13);
+ ENCODINGS.put(QMFObject.class, (short) 20);
+ ENCODINGS.put(Integer.class, (short) 17);
+ ENCODINGS.put(Long.class, (short) 18);
+ ENCODINGS.put(ArrayList.class, (short) 21);
+ }
+
+ public static String accessName(int type)
+ {
+ switch (type)
+ {
+ // case 0: return "UNKNOWN" ;
+ case 1:
+ return "RC";
+ case 2:
+ return "RW";
+ case 3:
+ return "RO";
+ }
+ throw new ConsoleException(String.format("Invalid Access Code: %s",
+ type));
+ }
+
+ public static String byteString(byte[] bytes)
+ {
+ return new String(bytes, Charset.forName("UTF-8"));
+ }
+
+ public static Object defaultValue(short type)
+ {
+ switch (type)
+ {
+ // case 0: return "UNKNOWN" ;
+ case 1:
+ return 0;
+ case 2:
+ return 0;
+ case 3:
+ return 0l;
+ case 4:
+ return 0l;
+ case 5:
+ return false;
+ case 6:
+ return "";
+ case 7:
+ return "";
+ case 8:
+ return 0l;
+ case 9:
+ return 0l;
+ case 10:
+ return new ObjectID();
+ case 11:
+ return false;
+ case 12:
+ return 0f;
+ case 13:
+ return 0d;
+ case 14:
+ return new UUID(0, 0);
+ case 15:
+ return new HashMap<String, Object>();
+ case 16:
+ return 0;
+ case 17:
+ return 0;
+ case 18:
+ return 0l;
+ case 19:
+ return 0l;
+ case 20:
+ return null;
+ case 21:
+ return new java.util.ArrayList<Object>();
+ case 22:
+ return new java.util.ArrayList<Object>();
+ }
+ throw new ConsoleException(String.format("Invalid Type Code: %s", type));
+ }
+
+ public static short qmfType(Object obj)
+ {
+ if (ENCODINGS.containsKey(obj.getClass()))
+ {
+ return ENCODINGS.get(obj.getClass());
+ } else
+ {
+ throw new ConsoleException(String.format("Unkown Type of %s", obj
+ .getClass()));
+ }
+ }
+
+ public static String typeName(short type)
+ {
+ switch (type)
+ {
+ // case 0: return "UNKNOWN" ;
+ case 1:
+ return "uint8";
+ case 2:
+ return "uint16";
+ case 3:
+ return "uint32";
+ case 4:
+ return "uint64";
+ case 5:
+ return "bool";
+ case 6:
+ return "short-string";
+ case 7:
+ return "long-string";
+ case 8:
+ return "abs-time";
+ case 9:
+ return "delta-time";
+ case 10:
+ return "reference";
+ case 11:
+ return "boolean";
+ case 12:
+ return "float";
+ case 13:
+ return "double";
+ case 14:
+ return "uuid";
+ case 15:
+ return "field-table";
+ case 16:
+ return "int8";
+ case 17:
+ return "int16";
+ case 18:
+ return "int32";
+ case 19:
+ return "int64";
+ case 20:
+ return "object";
+ case 21:
+ return "list";
+ case 22:
+ return "array";
+ }
+ throw new ConsoleException(String.format("Invalid Type Code: %s", type));
+ }
+
+ protected Util()
+ {
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/console/src/main/java/org/apache/qpid/console/XMLUtil.java b/qpid/java/management/console/src/main/java/org/apache/qpid/console/XMLUtil.java
new file mode 100644
index 0000000000..dcbcb5b6b6
--- /dev/null
+++ b/qpid/java/management/console/src/main/java/org/apache/qpid/console/XMLUtil.java
@@ -0,0 +1,155 @@
+package org.apache.qpid.console;
+/*
+ *
+ * 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.
+ *
+ */
+
+
+public class XMLUtil
+{
+ public static String commonAttributes(SchemaVariable var)
+ {
+ String returnString = "";
+ if (var.getDescription() != null)
+ {
+ returnString = returnString
+ + String.format(" desc='%s'", var.getDescription());
+ }
+ if (var.getRefPackage() != null)
+ {
+ returnString = returnString
+ + String.format(" refPackage='%s'", var.getRefPackage());
+ }
+ if (var.getRefClass() != null)
+ {
+ returnString = returnString
+ + String.format(" refClass='%s'", var.getRefClass());
+ }
+ if (var.getUnit() != null)
+ {
+ returnString = returnString
+ + String.format(" unit='%s'", var.getUnit());
+ }
+ if (var.getMin() != null)
+ {
+ returnString = returnString
+ + String.format(" min='%s'", var.getMin());
+ }
+ if (var.getMax() != null)
+ {
+ returnString = returnString
+ + String.format(" max='%s'", var.getMax());
+ }
+ if (var.getMaxLength() != null)
+ {
+ returnString = returnString
+ + String.format(" maxLength='%s'", var.getMaxLength());
+ }
+ return returnString;
+ }
+
+ public static String schemaXML(Session sess, String packageName)
+ {
+ String returnValue = String.format("<schema package='%s'>\n",
+ packageName);
+ for (ClassKey key : sess.getClasses(packageName))
+ {
+ SchemaClass schema = sess.getSchema(key);
+ if (schema.getKind() == 1)
+ {
+ if (schema.getSuperType() == null)
+ {
+ returnValue += String.format(
+ "\t<class name='%s' hash='%s'>\n", key
+ .getClassName(), key.getHashString());
+ } else
+ {
+ returnValue += String.format(
+ "\t<class name='%s' hash='%s' extends='%s'>\n", key
+ .getClassName(), key.getHashString(),
+ schema.getSuperType().getKeyString());
+ }
+ for (SchemaProperty prop : schema.getProperties())
+ {
+ Object[] attributes = new Object[5];
+ attributes[0] = prop.getName();
+ attributes[1] = Util.typeName(prop.getType());
+ attributes[2] = Util.accessName(prop.getAccess());
+ attributes[3] = prop.getOptional() ? "True" : "False ";
+ attributes[4] = XMLUtil.commonAttributes(prop);
+ returnValue += String
+ .format(
+ "\t\t<property name='%s' type='%s' access='%s' optional='%s'%s/>\n",
+ attributes);
+ }
+ for (SchemaMethod meth : schema.getMethods())
+ {
+ returnValue += String.format("\t\t<method name='%s'/>\n",
+ meth.getName());
+ for (SchemaArgument arg : meth.Arguments)
+ {
+ Object[] attributes = new Object[4];
+ attributes[0] = arg.getName();
+ attributes[1] = arg.getDirection();
+ attributes[2] = Util.typeName(arg.getType());
+ attributes[3] = XMLUtil.commonAttributes(arg);
+ returnValue += String
+ .format(
+ "\t\t\t<arg name='%s' dir='%s' type='%s'%s/>\n",
+ attributes);
+ }
+ returnValue += String.format("\t\t</method>\n");
+ }
+ returnValue += String.format("\t</class>\n");
+ } else
+ {
+ returnValue += String.format("\t<event name='%s' hash='%s'>\n",
+ key.getClassName(), key.getHashString());
+ for (SchemaArgument arg : schema.getArguments())
+ {
+ Object[] attributes = new Object[4];
+ attributes[0] = arg.getName();
+ attributes[1] = Util.typeName(arg.getType());
+ attributes[2] = XMLUtil.commonAttributes(arg);
+ returnValue += String.format(
+ "\t\t\t<arg name='%s' type='%s'%s/>\n", attributes);
+ }
+ returnValue += String.format("\t</event>\n");
+ }
+ }
+ returnValue += String.format("</schema>\n");
+ return returnValue;
+ }
+
+ public static String schemaXML(Session sess, String[] packageNames)
+ {
+ String returnValue = "<schemas>\n";
+ for (String pack : packageNames)
+ {
+ returnValue += XMLUtil.schemaXML(sess, pack);
+ returnValue += "\n";
+ }
+ returnValue += "</schemas>\n";
+ return returnValue;
+ }
+
+ protected XMLUtil()
+ {
+ }
+}
diff --git a/qpid/java/management/console/src/test/java/org/apache/qpid/console/ClassKeyTest.java b/qpid/java/management/console/src/test/java/org/apache/qpid/console/ClassKeyTest.java
new file mode 100644
index 0000000000..dc16aaac5b
--- /dev/null
+++ b/qpid/java/management/console/src/test/java/org/apache/qpid/console/ClassKeyTest.java
@@ -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.
+ *
+ */
+package org.apache.qpid.console;
+
+import junit.framework.TestCase;
+
+public class ClassKeyTest extends TestCase
+{
+ public void testCreation()
+ {
+ ClassKey key = new ClassKey(
+ "some.package:Class(00000001-00000002-00000003-00000004)");
+ assertEquals("some.package", key.getPackageName());
+ assertEquals("Class", key.getClassName());
+ assertEquals("00000001-00000002-00000003-00000004", key.getHashString());
+ assertEquals(1, key.getHash()[0]);
+ assertEquals(2, key.getHash()[1]);
+ assertEquals(3, key.getHash()[2]);
+ assertEquals(4, key.getHash()[3]);
+ }
+}
diff --git a/qpid/java/management/eclipse-plugin/META-INF/MANIFEST.MF b/qpid/java/management/eclipse-plugin/META-INF/MANIFEST.MF
index 0df308dff1..124fe1e767 100644
--- a/qpid/java/management/eclipse-plugin/META-INF/MANIFEST.MF
+++ b/qpid/java/management/eclipse-plugin/META-INF/MANIFEST.MF
@@ -3,7 +3,7 @@ Bundle-License: http://www.apache.org/licenses/LICENSE-2.0.txt
Bundle-ManifestVersion: 2
Bundle-Name: Qpid JMX Management Console Plug-in
Bundle-SymbolicName: org.apache.qpid.management.ui; singleton:=true
-Bundle-Version: 0.13.0
+Bundle-Version: 0.9.0
Bundle-Activator: org.apache.qpid.management.ui.Activator
Bundle-Vendor: Apache Software Foundation
Bundle-Localization: plugin
diff --git a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ApplicationRegistry.java b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ApplicationRegistry.java
index 4a59176374..20cfec3758 100644
--- a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ApplicationRegistry.java
+++ b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ApplicationRegistry.java
@@ -47,7 +47,7 @@ public abstract class ApplicationRegistry
//max supported broker management interface supported by this release of the management console
public static final int SUPPORTED_QPID_JMX_API_MAJOR_VERSION = 2;
- public static final int SUPPORTED_QPID_JMX_API_MINOR_VERSION = 3;
+ public static final int SUPPORTED_QPID_JMX_API_MINOR_VERSION = 0;
public static final String DATA_DIR = System.getProperty("user.home") + File.separator + ".qpidmc";
diff --git a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/JMXManagedObject.java b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/JMXManagedObject.java
index a8fb864cf6..3561e16098 100644
--- a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/JMXManagedObject.java
+++ b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/JMXManagedObject.java
@@ -21,7 +21,6 @@
package org.apache.qpid.management.ui.jmx;
import java.util.HashMap;
-import java.util.Map;
import javax.management.ObjectName;
@@ -32,36 +31,14 @@ public class JMXManagedObject extends ManagedBean
{
private ObjectName _objName;
+ @SuppressWarnings("unchecked")
public JMXManagedObject(ObjectName objName)
{
super();
this._objName = objName;
setUniqueName(_objName.toString());
- setDomain(_objName.getDomain());
-
- HashMap<String,String> props = new HashMap<String,String>(_objName.getKeyPropertyList());
-
- for(Map.Entry<String,String> entry : props.entrySet())
- {
- String value = entry.getValue();
-
- if(value != null)
- {
- try
- {
- //if the name is quoted in the ObjectName, unquote it
- value = ObjectName.unquote(value);
- entry.setValue(value);
- }
- catch(IllegalArgumentException e)
- {
- //ignore, this just means the name is not quoted
- //and can be left unchanged
- }
- }
- }
-
- super.setProperties(props);
+ setDomain(_objName.getDomain());
+ super.setProperties(new HashMap(_objName.getKeyPropertyList()));
}
public ObjectName getObjectName()
diff --git a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/model/NotificationObject.java b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/model/NotificationObject.java
index 35cc9f6e27..e42b3c53b6 100644
--- a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/model/NotificationObject.java
+++ b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/model/NotificationObject.java
@@ -61,7 +61,7 @@ public class NotificationObject
{
if (_source instanceof ObjectName)
{
- return unquote(((ObjectName)_source).getKeyProperty("name"));
+ return ((ObjectName)_source).getKeyProperty("name");
}
return null;
@@ -71,31 +71,12 @@ public class NotificationObject
{
if (_source instanceof ObjectName)
{
- return unquote(((ObjectName)_source).getKeyProperty(VIRTUAL_HOST));
+ return ((ObjectName)_source).getKeyProperty(VIRTUAL_HOST);
}
return null;
}
-
- private String unquote(String value)
- {
- if(value != null)
- {
- try
- {
- //if the value is quoted in the ObjectName, unquote it
- value = ObjectName.unquote(value);
- }
- catch(IllegalArgumentException e)
- {
- //ignore, this just means the value is not quoted
- //and can be left unchanged
- }
- }
-
- return value;
- }
-
+
public String getMessage()
{
return _message;
diff --git a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/MBeanTabFolderFactory.java b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/MBeanTabFolderFactory.java
index 527fc67be3..1fef89d6b5 100644
--- a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/MBeanTabFolderFactory.java
+++ b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/MBeanTabFolderFactory.java
@@ -131,8 +131,6 @@ public class MBeanTabFolderFactory
}
break;
case VHOST_MANAGER:
- createAttributesTab(tabFolder, mbean);
-
tab = new TabItem(tabFolder, SWT.NONE);
tab.setText("Operations");
controller = new VHostTabControl(tabFolder, mbean, mbsc);
diff --git a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/users/LegacySupportingUserManagement.java b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/users/LegacySupportingUserManagement.java
deleted file mode 100644
index 0fc94a5972..0000000000
--- a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/users/LegacySupportingUserManagement.java
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
- */
-package org.apache.qpid.management.ui.views.users;
-
-import javax.management.MBeanOperationInfo;
-
-import org.apache.qpid.management.common.mbeans.UserManagement;
-import org.apache.qpid.management.common.mbeans.annotations.MBeanOperation;
-import org.apache.qpid.management.common.mbeans.annotations.MBeanOperationParameter;
-
-/**
- * UserManagement interface extension to provide the method signatures
- * for old UserManagement methods no longer supported by the broker.
- *
- * This interface is used only for the creation of MBean proxy objects
- * within the management console, for backwards compatibility with
- * functionality in older broker versions.
- */
-public interface LegacySupportingUserManagement extends UserManagement
-{
- /**
- * set password for user.
- *
- * Since Qpid JMX API 1.2 this operation expects plain text passwords to be provided. Prior to this, MD5 hashed passwords were supplied.
- *
- * @deprecated since Qpid JMX API 1.7
- *
- * @param username The username for which the password is to be set
- * @param password The password for the user
- *
- * @return The result of the operation
- */
- @Deprecated
- @MBeanOperation(name = "setPassword", description = "Set password for user.",
- impact = MBeanOperationInfo.ACTION)
- boolean setPassword(@MBeanOperationParameter(name = "username", description = "Username")String username,
- //NOTE: parameter name was changed to 'passwd' in Qpid JMX API 1.7 to protect against older, incompatible management clients
- @MBeanOperationParameter(name = "passwd", description = "Password")char[] password);
-
- /**
- * Set rights for users with given details.
- * Since Qpid JMX API 2.3 all invocations will cause an exception to be thrown
- * as access rights can no longer be maintain via this interface.
- *
- * @deprecated since Qpid JMX API 2.3 / 1.12
- *
- * @param username The username to create
- * @param read The set of permission to give the new user
- * @param write The set of permission to give the new user
- * @param admin The set of permission to give the new user
- *
- * @return The result of the operation
- */
- @Deprecated
- @MBeanOperation(name = "setRights", description = "Set access rights for user.",
- impact = MBeanOperationInfo.ACTION)
- boolean setRights(@MBeanOperationParameter(name = "username", description = "Username")String username,
- @MBeanOperationParameter(name = "read", description = "Administration read")boolean read,
- @MBeanOperationParameter(name = "readAndWrite", description = "Administration write")boolean write,
- @MBeanOperationParameter(name = "admin", description = "Administration rights")boolean admin);
-
- /**
- * Create users with given details.
- * Since Qpid JMX API 2.3 if the user passes true for parameters read, write, or admin, a
- * exception will be thrown as access rights can no longer be maintain via this interface.
- *
- * Since Qpid JMX API 1.2 this operation expects plain text passwords to be provided. Prior to this, MD5 hashed passwords were supplied.
- *
- * @deprecated since Qpid JMX API 1.7
- *
- * @param username The username to create
- * @param password The password for the user
- * @param read The set of permission to give the new user
- * @param write The set of permission to give the new user
- * @param admin The set of permission to give the new user
- *
- * @return true if the user was created successfully, or false otherwise
- */
- @Deprecated
- @MBeanOperation(name = "createUser", description = "Create new user from system.",
- impact = MBeanOperationInfo.ACTION)
- boolean createUser(@MBeanOperationParameter(name = "username", description = "Username")String username,
- //NOTE: parameter name was changed to 'passwd' in Qpid JMX API 1.7 to protect against older, incompatible management clients
- @MBeanOperationParameter(name = "passwd", description = "Password")char[] password,
- @MBeanOperationParameter(name = "read", description = "Administration read")boolean read,
- @MBeanOperationParameter(name = "readAndWrite", description = "Administration write")boolean write,
- @MBeanOperationParameter(name = "admin", description = "Administration rights")boolean admin);
-
- /**
- * Create users with given details.
- * Since Qpid JMX API 2.3 if the user passes true for parameters read, write, or admin, a
- * exception will be thrown as access rights can no longer be maintain via this interface.
- *
- * @deprecated since Qpid JMX API 2.3 / 1.12
- * @since Qpid JMX API 1.7
- *
- * @param username The username to create
- * @param password The password for the user
- * @param read The set of permission to give the new user
- * @param write The set of permission to give the new user
- * @param admin The set of permission to give the new user
- *
- * @return true if the user was created successfully, or false otherwise
- */
- @Deprecated
- @MBeanOperation(name = "createUser", description = "Create a new user.",
- impact = MBeanOperationInfo.ACTION)
- boolean createUser(@MBeanOperationParameter(name = "username", description = "Username")String username,
- @MBeanOperationParameter(name = "password", description = "Password")String password,
- @MBeanOperationParameter(name = "read", description = "Administration read")boolean read,
- @MBeanOperationParameter(name = "readAndWrite", description = "Administration write")boolean write,
- @MBeanOperationParameter(name = "admin", description = "Administration rights")boolean admin);
-
-}
diff --git a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/users/UserManagementTabControl.java b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/users/UserManagementTabControl.java
index 2c540bf982..fdcc25d337 100644
--- a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/users/UserManagementTabControl.java
+++ b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/users/UserManagementTabControl.java
@@ -37,6 +37,7 @@ import javax.management.openmbean.TabularDataSupport;
import org.apache.qpid.management.ui.ApiVersion;
import org.apache.qpid.management.ui.ApplicationRegistry;
import org.apache.qpid.management.ui.ManagedBean;
+import org.apache.qpid.management.common.mbeans.UserManagement;
import org.apache.qpid.management.ui.jmx.JMXManagedObject;
import org.apache.qpid.management.ui.jmx.MBeanUtility;
import org.apache.qpid.management.ui.views.TabControl;
@@ -82,7 +83,7 @@ public class UserManagementTabControl extends TabControl
private TableViewer _tableViewer = null;
private TabularDataSupport _userDetails = null;
- private LegacySupportingUserManagement _ummb;
+ private UserManagement _ummb;
private ApiVersion _ApiVersion;
public UserManagementTabControl(TabFolder tabFolder, JMXManagedObject mbean, MBeanServerConnection mbsc)
@@ -90,9 +91,9 @@ public class UserManagementTabControl extends TabControl
super(tabFolder);
_mbean = mbean;
_ApiVersion = ApplicationRegistry.getServerRegistry(mbean).getManagementApiVersion();
- _ummb = (LegacySupportingUserManagement)
+ _ummb = (UserManagement)
MBeanServerInvocationHandler.newProxyInstance(mbsc, mbean.getObjectName(),
- LegacySupportingUserManagement.class, false);
+ UserManagement.class, false);
_toolkit = new FormToolkit(_tabFolder.getDisplay());
_form = _toolkit.createScrolledForm(_tabFolder);
_form.getBody().setLayout(new GridLayout());
@@ -170,13 +171,6 @@ public class UserManagementTabControl extends TabControl
String[] titles = { "Username", "JMX Management Rights" };
int[] bounds = { 310, 200 };
- if(!settingManagementRightsSupported())
- {
- //Since Qpid JMX API 2.3 / 1.12 only Username is used
- titles = new String[]{ "Username"};
- bounds = new int[]{ 310 };
- }
-
for (int i = 0; i < titles.length; i++)
{
final int index = i;
@@ -220,16 +214,7 @@ public class UserManagementTabControl extends TabControl
Composite buttonsComposite = _toolkit.createComposite(tableComposite);
gridData = new GridData(SWT.FILL, SWT.TOP, false, false);
- if(!settingManagementRightsSupported())
- {
- //The 'Set Rights' button is not shown from Qpid JMX API 2.3 / 1.12
- //onward, provide less space
- gridData.heightHint = 135;
- }
- else
- {
- gridData.heightHint = 165;
- }
+ gridData.heightHint = 165;
buttonsComposite.setLayoutData(gridData);
buttonsComposite.setLayout(new GridLayout());
@@ -307,14 +292,14 @@ public class UserManagementTabControl extends TabControl
if (returnValue == InputDialog.OK)
{
- char[] passwordArray = id.getValue().toCharArray();
+ char[] password = id.getValue().toCharArray();
// Qpid JMX API 1.1 and below expects the password to be sent as a hashed value.
if (_ApiVersion.lessThanOrEqualTo(1,1))
{
try
{
- passwordArray = ViewUtility.getHash(id.getValue());
+ password = ViewUtility.getHash(id.getValue());
}
catch (Exception hashException)
{
@@ -327,18 +312,7 @@ public class UserManagementTabControl extends TabControl
try
{
- boolean result;
-
- //For Qpid JMX API >=1.7 use String based method instead of older char[] based method.
- if(_ApiVersion.greaterThanOrEqualTo(1, 7))
- {
- result = _ummb.setPassword(user, id.getValue());
- }
- else
- {
- result = _ummb.setPassword(user, passwordArray);
- }
-
+ boolean result = _ummb.setPassword(user, password);
ViewUtility.operationResultFeedback(result, "Updated user password", "Failed to update user password");
}
catch(Exception e2)
@@ -350,34 +324,25 @@ public class UserManagementTabControl extends TabControl
}
}
});
-
- final Button setRightsButton;
- if(!settingManagementRightsSupported())
- {
- //The 'Set Rights' button is not used from Qpid JMX API 2.3 / 1.12 onward
- setRightsButton = null;
- }
- else
+
+ final Button setRightsButton = _toolkit.createButton(buttonsComposite, "Set Rights ...", SWT.PUSH);
+ gridData = new GridData(SWT.CENTER, SWT.BOTTOM, false, false);
+ gridData.widthHint = 125;
+ setRightsButton.setLayoutData(gridData);
+ setRightsButton.setEnabled(false);
+ setRightsButton.addSelectionListener(new SelectionAdapter()
{
- setRightsButton = _toolkit.createButton(buttonsComposite, "Set Rights ...", SWT.PUSH);
- gridData = new GridData(SWT.CENTER, SWT.BOTTOM, false, false);
- gridData.widthHint = 125;
- setRightsButton.setLayoutData(gridData);
- setRightsButton.setEnabled(false);
- setRightsButton.addSelectionListener(new SelectionAdapter()
+ public void widgetSelected(SelectionEvent e)
{
- public void widgetSelected(SelectionEvent e)
- {
- int selectionIndex = _table.getSelectionIndex();
+ int selectionIndex = _table.getSelectionIndex();
- if (selectionIndex != -1)
- {
- setRights(setRightsButton.getShell());
- }
+ if (selectionIndex != -1)
+ {
+ setRights(setRightsButton.getShell());
}
- });
- }
-
+ }
+ });
+
_tableViewer.addSelectionChangedListener(new ISelectionChangedListener(){
public void selectionChanged(SelectionChangedEvent evt)
{
@@ -386,20 +351,14 @@ public class UserManagementTabControl extends TabControl
if (selectionIndex == -1)
{
deleteUsersButton.setEnabled(false);
+ setRightsButton.setEnabled(false);
setPasswordButton.setEnabled(false);
- if(setRightsButton != null)
- {
- setRightsButton.setEnabled(false);
- }
return;
}
else
{
deleteUsersButton.setEnabled(true);
- if(setRightsButton != null)
- {
- setRightsButton.setEnabled(true);
- }
+ setRightsButton.setEnabled(true);
}
if (_table.getSelectionCount() > 1)
@@ -427,17 +386,11 @@ public class UserManagementTabControl extends TabControl
//this only reloaded the JMX rights file before Qpid JMX API 1.2
_toolkit.createLabel(miscGroup, " Loads the current management rights file from disk");
}
- else if(settingManagementRightsSupported())
- {
- //from Qpid JMX API 1.2 to 2.3 / 1.12 it also reloads the password file
- _toolkit.createLabel(miscGroup, " Loads the current password and management rights files from disk");
- }
else
{
- //since Qpid JMX API 2.3 / 1.12 it only reloads the password file
- _toolkit.createLabel(miscGroup, " Loads the current password data");
+ //since Qpid JMX API 1.2 it also reloads the password file
+ _toolkit.createLabel(miscGroup, " Loads the current password and management rights files from disk");
}
-
reloadUserDetails.addSelectionListener(new SelectionAdapter()
{
public void widgetSelected(SelectionEvent e)
@@ -500,7 +453,7 @@ public class UserManagementTabControl extends TabControl
{
case 0 : // username column
return (String) ((CompositeData) element).get(USERNAME);
- case 1 : // rights column (used for API < 2.3 / 1.12)
+ case 1 : // rights column
return classifyUserRights((CompositeData) element);
default :
return "-";
@@ -557,11 +510,11 @@ public class UserManagementTabControl extends TabControl
int comparison = 0;
switch(column)
{
- case 0: //username column
+ case 0:
comparison = String.valueOf(user1.get(USERNAME)).compareTo(
String.valueOf(user2.get(USERNAME)));
break;
- case 1: // rights column (used for API < 2.3 / 1.12)
+ case 1:
comparison = classifyUserRights(user1).compareTo(classifyUserRights(user2));
break;
default:
@@ -602,12 +555,7 @@ public class UserManagementTabControl extends TabControl
private void setRights(final Shell parent)
{
- if(!settingManagementRightsSupported())
- {
- throw new UnsupportedOperationException("Setting management rights" +
- " is not supported using this version of the broker management API: " + (_ApiVersion));
- }
-
+
int selectionIndex = _table.getSelectionIndex();
if (selectionIndex == -1)
@@ -751,13 +699,6 @@ public class UserManagementTabControl extends TabControl
shell.open();
}
-
- protected boolean settingManagementRightsSupported()
- {
- //setting management access rights was supported until Qpid JMX API 1.12 / 2.3
- return _ApiVersion.lessThan(1,12) ||
- (_ApiVersion.greaterThanOrEqualTo(2, 0) && _ApiVersion.lessThan(2,3));
- }
private void addUser(final Shell parent)
{
@@ -765,8 +706,7 @@ public class UserManagementTabControl extends TabControl
Composite usernameComposite = _toolkit.createComposite(shell, SWT.NONE);
usernameComposite.setBackground(shell.getBackground());
- GridData usernameCompGridData = new GridData(SWT.FILL, SWT.TOP, true, false);
- usernameComposite.setLayoutData(usernameCompGridData);
+ usernameComposite.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
usernameComposite.setLayout(new GridLayout(2,false));
_toolkit.createLabel(usernameComposite,"Username:").setBackground(shell.getBackground());
@@ -775,45 +715,28 @@ public class UserManagementTabControl extends TabControl
Composite passwordComposite = _toolkit.createComposite(shell, SWT.NONE);
passwordComposite.setBackground(shell.getBackground());
- GridData passwordCompGridData = new GridData(SWT.FILL, SWT.TOP, true, false);
- passwordComposite.setLayoutData(passwordCompGridData);
+ passwordComposite.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
passwordComposite.setLayout(new GridLayout(2,false));
_toolkit.createLabel(passwordComposite,"Password:").setBackground(shell.getBackground());
final Text passwordText = new Text(passwordComposite, SWT.BORDER | SWT.PASSWORD);
passwordText.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
+
+ Group buttonGroup = new Group(shell, SWT.NONE);
+ buttonGroup.setText("JMX Management Rights");
+ buttonGroup.setBackground(shell.getBackground());
+ buttonGroup.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
+ buttonGroup.setLayout(new GridLayout(4,false));
- final Button readButton;
- final Button writeButton;
- final Button adminButton;
- if(settingManagementRightsSupported())
- {
- Group buttonGroup = new Group(shell, SWT.NONE);
- buttonGroup.setText("JMX Management Rights");
- buttonGroup.setBackground(shell.getBackground());
- buttonGroup.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
- buttonGroup.setLayout(new GridLayout(4,false));
-
- final Button noneButton = new Button(buttonGroup, SWT.RADIO);
- noneButton.setText("No Access");
- noneButton.setSelection(true);
- readButton = new Button(buttonGroup, SWT.RADIO);
- readButton.setText("Read Only");
- writeButton = new Button(buttonGroup, SWT.RADIO);
- writeButton.setText("Read + Write");
- adminButton = new Button(buttonGroup, SWT.RADIO);
- adminButton.setText("Admin");
- }
- else
- {
- readButton = null;
- writeButton = null;
- adminButton = null;
- //The lack of rights settings will cause the dialog to,
- //shrink so add width hints to the other components
- passwordCompGridData.widthHint = 350;
- usernameCompGridData.widthHint = 350;
- }
+ final Button noneButton = new Button(buttonGroup, SWT.RADIO);
+ noneButton.setText("No Access");
+ noneButton.setSelection(true);
+ final Button readButton = new Button(buttonGroup, SWT.RADIO);
+ readButton.setText("Read Only");
+ final Button writeButton = new Button(buttonGroup, SWT.RADIO);
+ writeButton.setText("Read + Write");
+ final Button adminButton = new Button(buttonGroup, SWT.RADIO);
+ adminButton.setText("Admin");
Composite okCancelButtonsComp = _toolkit.createComposite(shell);
okCancelButtonsComp.setBackground(shell.getBackground());
@@ -861,36 +784,22 @@ public class UserManagementTabControl extends TabControl
return;
}
}
-
- //read the access rights selections if required
- boolean read = false;
- boolean write = false;
- boolean admin = false;
- if(settingManagementRightsSupported())
- {
- read = readButton.getSelection();
- write = writeButton.getSelection();
- admin = adminButton.getSelection();
- }
+
+ boolean read = readButton.getSelection();
+ boolean write = writeButton.getSelection();
+ boolean admin = adminButton.getSelection();
shell.dispose();
try
{
boolean result = false;
-
- if (!settingManagementRightsSupported())
- {
- // If we have Qpid JMX API 2.3 / 1.12 or above, use newer createUser method without rights parameters.
- result = _ummb.createUser(username, password);
- }
- else if (_ApiVersion.greaterThanOrEqualTo(1,7))
+ // If we have Qpid JMX API 1.7 or above, use newer createUser method with String based password.
+ if (_ApiVersion.greaterThanOrEqualTo(1,7))
{
- // If we have Qpid JMX API 1.7 or above, use newer createUser method with String based password.
result = _ummb.createUser(username, password, read, write, admin);
}
else
{
- // Else we have Qpid JMX API 1.6 or below, use older createUser method with char[] based password.
result = _ummb.createUser(username, passwordChars, read, write, admin);
}
diff --git a/qpid/java/management/tools/qpid-cli/Guide.txt b/qpid/java/management/tools/qpid-cli/Guide.txt
new file mode 100644
index 0000000000..db841ebaa1
--- /dev/null
+++ b/qpid/java/management/tools/qpid-cli/Guide.txt
@@ -0,0 +1,143 @@
+
+ * How to connect with the Broker *
+ ---------------------------------
+
+Before you come in to this state you have to build the source or you
+can get the binary and extract then set the QPID_CLI environment
+variable to the main directory of the source or binary,then only you
+are in a position to start working with management console. First
+check whether the broker is up and running. In order to simply connect
+with the broker you can run the qpid-cli script which required
+arguments.
+
+${QPID_CLI}/bin/qpid-cli -h [HostName of IP of the broker ] -p [Port
+of the broker]
+
+Default values for arguments -h [localhost] -p [8999]
+
+ * One Shot mode *
+ -----------------
+
+With one shot mode you can run interactive mode commands for one time
+and disconnect with the broker.This feature is useful when you want to
+run particular command in the management console using a script which
+is running in the normal console.What you have to do is you have to
+give the command you want to run with the qpid-cli script running
+command.
+
+Ex 1: $QPID_CLI/bin/qpid-cli queue list -- This will list the queue
+objects and disconnect.
+
+Ex 2: $QPID_CLI/bin/qpid-cli queue view -n ping - This will display
+information about all the message in the queue with the name of ping
+
+Likewise you can run any command in one shot mode and get the output
+for one time.
+
+ * Report Generation Mode *
+ -------------------------
+
+If you want to generate reports you can do it by defining your
+required information using a property file. There's a sample property
+file in the parent directory and you can have a look and get an idea
+about that.You can generate reports by giving a time interval in the
+property file. In order to start the daemon mode you have to run the
+qpid-cli script with the option : -r by giving the path for your
+property file.
+
+Ex: $QPID_CLI/bin/qpid-cli -r ../report.property
+
+You should specify a property file in order to run the daemon mode and
+get information repeatedly.
+
+ * Interactive mode with number of command *
+ -------------------------------------------
+
+This is the mode you get when you run the qpid-cli script without the
+one shot mode and without the daemon mode with [-r] option.Once you
+connect with the broker it display you a prompt [qpid-admin-$], then
+you can run several commands to can perform following tasks.
+
+For all the commands object type is command and most important command
+so you can use this option value without giving the option letter by
+giving that option value at the beginning of the command.
+
+Ex: [list -o queue ] can use this command like this dropping -o option
+[queue list]
+Ex: [list -o queue -n ping] = [queue list -n ping]
+
+ * Data displaying commands *
+ ----------------------------
+
+This is the set of commands which display the information about
+broker.
+
+list :
+------
+list information about the given object type with limited
+number of attributes and you can use number of command options to get
+different useful behaviors with the list command.You can get the
+complete description about the command by running the command like
+this.[list -h].
+
+info :
+------
+list all the attributes of a given object type. This command
+works very similar way to list command. You can use -h option for help
+and get complete description of the info command.
+
+view :
+------
+view information about the content of the message in the queue
+object. In order to run this command you have to specify the object
+type at the beginning.You can give how many message informations you
+want to view from the top of the queue by using -t option.
+
+Ex : queue view -n message_queue -t 5
+[list the message info for top 5 messages in queue message_queue]
+
+viewcontent :
+-------------
+view the content of the a given message in the
+queue. You have to give the messageId as a parameter with -id option
+letters.
+
+Ex: queue viewcontent -n message_queue -id 12
+[list the content encoding and Mimetype of the message with the
+messageId for the give message which is in the queue message_queue]
+
+ * Data modification commands *
+ ------------------------------
+
+This is a set of commands which allow users to deal with messages in
+queues.Users can delete messages from a give queue and user's can move
+one message from one queue to another queue.
+
+delete :
+--------
+Using this command user can delete a give message from a given
+queue you can specify how many messages you want to delete from the
+queue from the top of the queue by using -t option.If user does not
+give how many messages to delete from the top of the queue program is
+going to delete all the messages from the queue after giving a prompt
+to confirm the deletion.
+
+Ex: queue delete -n message_queue -t 3
+[Delete top three messages in the queue message_queue ]
+
+move :
+------
+This command allow user to move number of messages from one
+queue to another queue. First you have to specify from which queue you
+want to move messages by using -n1 and -v1 option letters(-n1 queue
+name/ -v1 virtual host).Then you have to use -n2 option to give the
+target queue name and then you have to give From messageId and To
+messageId using -fmid and -tmid option letters to specify the messages
+range you want to do the move operation.
+
+Ex: queue move -n1 message_queue -n2 ping -fmid 13 -tmid 15
+[This will move messages with the messageId range of 13-15 from queue
+message_queue to queue ping.
+
+
+
diff --git a/qpid/java/management/tools/qpid-cli/LICENSE b/qpid/java/management/tools/qpid-cli/LICENSE
new file mode 100644
index 0000000000..c6432e459f
--- /dev/null
+++ b/qpid/java/management/tools/qpid-cli/LICENSE
@@ -0,0 +1,225 @@
+=========================================================================
+== Apache License ==
+=========================================================================
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+
+=============================================================================
+== JLine (BSD) License
+=============================================================================
+Copyright (c) 2008, Apache Software Foundation
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
+ * Neither the name of the <ORGANIZATION> nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+
+
+
+
diff --git a/qpid/java/management/tools/qpid-cli/NOTICE b/qpid/java/management/tools/qpid-cli/NOTICE
new file mode 100644
index 0000000000..f1d9e54095
--- /dev/null
+++ b/qpid/java/management/tools/qpid-cli/NOTICE
@@ -0,0 +1,12 @@
+Apache Qpid
+Copyright 2006-2008 Apache Software Foundation
+This product includes software developed at
+Apache Software Foundation (http://www.apache.org/)
+
+Handling console input is provided bye the Jline library package,
+JLine is a Java library for handling console input. It is similar
+in functionality to BSD editline and GNU readline.Original software is
+available from
+
+http://jline.sourceforge.net/index.html
+
diff --git a/qpid/java/management/tools/qpid-cli/README.txt b/qpid/java/management/tools/qpid-cli/README.txt
new file mode 100644
index 0000000000..6db439aad0
--- /dev/null
+++ b/qpid/java/management/tools/qpid-cli/README.txt
@@ -0,0 +1,64 @@
+README
+n======
+
+INSTALL
+=======
+ source
+ ======
+ 1.Set the environment variable QPID_HOME to the root directory of the repository or the release.
+
+ 2.Run these command to build the source
+
+ ant compile OR run the ant build in the parent directory(main ant script)
+
+ 3.To launch the CLI run the script in bin folder with appropriate parameters.
+
+ ex:
+
+ Linux $QPID_HOME/bin/qpid-cli -h 10.8.100.122 -p 8334
+ Windows %QPID_HOME%/bin/qpid-cli.bat -h 10.8.100.122 -p 8334
+
+ -h hostname (default localhost)
+ -p broker port (default 8999)
+
+ binary
+ ======
+ 1.Set the environment variable QPID_HOME to the root directory of the repository or the release.
+
+ 2.To launch the CLI run the script in bin folder with appropriate parameters.
+
+ ex:
+
+ Linux $QPID_HOME/bin/qpid-cli -h 10.8.100.122 -p 8334
+ Windows %QPID_HOME%/bin/qpid-cli.bat -h 10.8.100.122 -p 8334
+
+ -h hostname (default localhost)
+ -p broker port (default 8999)
+
+ 3. No test cases are included in the binary version.
+
+TESTING
+=======
+
+1.Test source is located in the test directory.If you want to run the tests please start the
+Qpid java broker and run following ant targets.
+
+ ant compile-tests This compile all the test sources
+ ant test This runs all the test cases
+2.If you want to test with a remote broker please use the source release and change the constants in ConnectionConstants.java
+class.(Default values are BROKER_HOSTNAME="localhost" BROKER_PORT="8999")
+
+For more informations please visit the project home page.
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/qpid/java/management/tools/qpid-cli/bin/qpid-cli b/qpid/java/management/tools/qpid-cli/bin/qpid-cli
new file mode 100755
index 0000000000..0efb49dddd
--- /dev/null
+++ b/qpid/java/management/tools/qpid-cli/bin/qpid-cli
@@ -0,0 +1,35 @@
+#!/bin/bash
+#
+# License 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 [ -z "$QPID_HOME" ]; then
+ export QPID_HOME=$(dirname $(dirname $(readlink -f $0)))
+ export PATH=${PATH}:${QPID_HOME}/bin
+fi
+
+# Set classpath to include Qpid jar with all required jars in manifest
+QPID_LIBS=$QPID_HOME/lib/qpid-all.jar
+
+# Set other variables used by the qpid-run script before calling
+export JAVA=java \
+ JAVA_VM=-server \
+ JAVA_MEM=-Xmx1024m \
+ QPID_CLASSPATH=$QPID_LIBS
+
+. qpid-run org.apache.qpid.CommandLineInterpreter "$@"
diff --git a/qpid/java/management/tools/qpid-cli/bin/qpid-cli.bat b/qpid/java/management/tools/qpid-cli/bin/qpid-cli.bat
new file mode 100755
index 0000000000..452ddb65ee
--- /dev/null
+++ b/qpid/java/management/tools/qpid-cli/bin/qpid-cli.bat
@@ -0,0 +1,28 @@
+@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
+set CLASSPATH=%CLASSPATH%;%QPID_HOME%/lib/jline-0.9.94.jar
+set CLASSPATH=%CLASSPATH%;%QPID_HOME%/lib/junit-4.4.jar
+set CLASSPATH=%CLASSPATH%;%QPID_HOME%/lib/qpid-cli-1.0.jar
+set CLASSPATH=%CLASSPATH%;%QPID_HOME%/lib/qpid-management-common-M4.jar
+set CLASSPATH=%CLASSPATH%;%QPID_HOME%/management/tools/qpid-cli/main/classes/
+java -classpath %CLASSPATH% org.apache.qpid.CommandLineInterpreter %1
+
+
+
+
diff --git a/qpid/java/management/tools/qpid-cli/build.xml b/qpid/java/management/tools/qpid-cli/build.xml
new file mode 100644
index 0000000000..7026cd2fd2
--- /dev/null
+++ b/qpid/java/management/tools/qpid-cli/build.xml
@@ -0,0 +1,31 @@
+<!--
+ -
+ - Licensed to the Apache Software Foundation (ASF) under one
+ - or more contributor license agreements. See the NOTICE file
+ - distributed with this work for additional information
+ - regarding copyright ownership. The ASF licenses this file
+ - to you under the Apache License, Version 2.0 (the
+ - "License"); you may not use this file except in compliance
+ - with the License. You may obtain a copy of the License at
+ -
+ - http://www.apache.org/licenses/LICENSE-2.0
+ -
+ - Unless required by applicable law or agreed to in writing,
+ - software distributed under the License is distributed on an
+ - "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ - KIND, either express or implied. See the License for the
+ - specific language governing permissions and limitations
+ - under the License.
+ -
+ -->
+<project name="qpid-cli">
+
+ <property name="module.depends" value="common management/common" />
+ <property name="module.test.depends" value="common client" />
+ <property name="module.src" value="src" />
+ <!-- Disable tests as per QPID-1342 -->
+ <!--property name="module.test.src" value="test" /-->
+
+ <import file="../../../module.xml"/>
+
+</project>
diff --git a/qpid/java/management/tools/qpid-cli/report.property b/qpid/java/management/tools/qpid-cli/report.property
new file mode 100644
index 0000000000..46734d52a8
--- /dev/null
+++ b/qpid/java/management/tools/qpid-cli/report.property
@@ -0,0 +1,26 @@
+#
+# 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.
+#
+
+object=queue
+column=Name,MessageCount,ActiveConsumerCount,Durable
+filter.name=ping
+filter.virtualhost=test
+output=csv
+seperator=|
+interval=1
diff --git a/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/Command.java b/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/Command.java
new file mode 100644
index 0000000000..eadc87186f
--- /dev/null
+++ b/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/Command.java
@@ -0,0 +1,33 @@
+/*
+ *
+ * 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;
+
+public interface Command
+{
+ public void execute();
+
+ public void printusage();
+
+ public String optionchecker(String string);
+
+ public boolean checkoptionsetting(String string);
+
+}
diff --git a/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/CommandExecutionEngine.java b/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/CommandExecutionEngine.java
new file mode 100644
index 0000000000..69f261b4ba
--- /dev/null
+++ b/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/CommandExecutionEngine.java
@@ -0,0 +1,76 @@
+/*
+ *
+ * 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;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.qpid.utils.JMXinfo;
+
+public class CommandExecutionEngine
+{
+ private static Map<String, Class<? extends Command>> _commands = new HashMap<String, Class<? extends Command>>();
+ private Command currentcommand = null;
+ private String commandname = null;
+ private JMXinfo info = null;
+
+ public CommandExecutionEngine(JMXinfo info)
+ {
+ this.info = info;
+ this.commandname = info.getCommandLineOptionParser().getcommandname();
+ }
+
+ public boolean CommandSelector() throws Exception
+ {
+ Class<? extends Command> commandClass = _commands.get(this.commandname);
+ if (commandClass != null)
+ {
+ Class<?> parameterTypes = JMXinfo.class;
+ currentcommand = (Command) commandClass.getConstructor(parameterTypes).newInstance(info);
+ }
+ else
+ {
+ usage();
+ return false;
+ }
+ return true;
+ }
+
+ public static void addCommand(String name, Class<? extends Command> newCommand)
+ {
+ _commands.put(name, newCommand);
+ }
+
+ public static Map<String, Class<? extends Command>> getCommands()
+ {
+ return _commands;
+ }
+
+ public void runcommand()
+ {
+ currentcommand.execute();
+ }
+
+ public void usage()
+ {
+ System.out.println(commandname + ":Command not found");
+ }
+}
diff --git a/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/CommandLineInterpreter.java b/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/CommandLineInterpreter.java
new file mode 100644
index 0000000000..d8e76172bc
--- /dev/null
+++ b/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/CommandLineInterpreter.java
@@ -0,0 +1,263 @@
+/*
+ *
+ * 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;
+
+import java.io.PrintWriter;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.StringTokenizer;
+
+import javax.management.MBeanServerConnection;
+import javax.management.remote.JMXConnector;
+
+import jline.ArgumentCompletor;
+import jline.ConsoleReader;
+import jline.SimpleCompletor;
+
+import org.apache.qpid.commands.Commanddelete;
+import org.apache.qpid.commands.Commandget;
+import org.apache.qpid.commands.Commandhelp;
+import org.apache.qpid.commands.Commandinfo;
+import org.apache.qpid.commands.Commandlist;
+import org.apache.qpid.commands.Commandmove;
+import org.apache.qpid.commands.Commandset;
+import org.apache.qpid.commands.Commandview;
+import org.apache.qpid.commands.Commandviewcontent;
+import org.apache.qpid.utils.CommandLineOptionParser;
+import org.apache.qpid.utils.JMXConfiguration;
+import org.apache.qpid.utils.JMXinfo;
+
+public class CommandLineInterpreter
+{
+ private static final String OBJECT_VIRTUALHOST = "virtualhost";
+ private static final String OBJECT_USERMANAGEMENT = "usermanagement";
+ private static final String OBJECT_CONNECTION = "connection";
+ private static final String OBJECT_EXCHANGE = "exchange";
+ private static final String OBJECT_QUEUE = "queue";
+ private static final String COMMAND_QUIT = "quit";
+ private static final String COMMAND_EXIT = "exit";
+
+ public static void main(String[] args)
+ {
+ Connector conn = null;
+ try
+ {
+ // Create an RMI connector client and
+ // connect it to the RMI connector server
+
+ /*
+ * checking the commandline options and parse them in to config
+ * method
+ */
+ JMXConnector jmxc = null;
+ MBeanServerConnection mbsc = null;
+ ConsoleReader reader = new ConsoleReader();
+ reader.setBellEnabled(false);
+ CommandLineOptionParser commandlineoptionparser = null;
+
+ if ((args == null) || (args.length) == 0)
+ {
+ Usage();
+ }
+ /*
+ * here special constructor is calling, when parsing options,in here
+ * first option value is starting from minus sign so this is handle
+ * by a special constructor
+ */
+ else
+ {
+ if (args[0].startsWith("-"))
+ {
+ commandlineoptionparser = new CommandLineOptionParser(args, args[0]); // if
+ // user
+ // specify
+ // any
+ // argument
+ // with
+ // the
+ // qpid-cli
+ // script
+ }
+ }
+
+ registerCommands();
+
+ /* Connecting with the broker */
+ try
+ {
+ if (commandlineoptionparser == null)
+ commandlineoptionparser = new CommandLineOptionParser(args);
+
+ JMXConfiguration config = new JMXConfiguration(commandlineoptionparser.getAlloptions());
+ conn = ConnectorFactory.getConnector(config.gethostname(), config.getport(), config.getUsername(),
+ config.getPassword());
+ jmxc = conn.getConnector();
+ mbsc = conn.getMBeanServerConnection();
+ if (config.checkoptionsetting("r", commandlineoptionparser.getAlloptions()))
+ {
+ JMXinfo info = new JMXinfo(jmxc, commandlineoptionparser, mbsc);
+ ReportGenerator reportgen = new ReportGenerator(config.optionchecker("r", commandlineoptionparser
+ .getAlloptions()), info);
+ reportgen.loadproperties();
+ reportgen.run();
+ }
+ /*
+ * This implementation is for the people who are using the
+ * interactive mode for one shot this run the user given command
+ * and exit
+ */
+ for (int i = 0; i < args.length; i++)
+ {
+ if (CommandExecutionEngine.getCommands().keySet().contains(args[i]))
+ {
+ oneshotmode(args, commandlineoptionparser, jmxc, mbsc);
+ return;
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ connectionrefuse(ex);
+ return;
+ }
+ /* In this point connection has been established */
+ String line;
+ String[] command;
+
+ /* prividing GNU readline features using Jline library */
+ PrintWriter out = new PrintWriter(System.out);
+ SimpleCompletor completer = new SimpleCompletor(new String[] {
+ COMMAND_EXIT, COMMAND_QUIT, OBJECT_QUEUE, OBJECT_EXCHANGE, OBJECT_CONNECTION,
+ OBJECT_USERMANAGEMENT, OBJECT_VIRTUALHOST});
+ for (String commandName : CommandExecutionEngine.getCommands().keySet())
+ {
+ completer.addCandidateString(commandName);
+ }
+ reader.addCompletor(new ArgumentCompletor(completer));
+ while ((line = reader.readLine("qpid-admin-$ ")) != null)
+ {
+ out.flush();
+ if (removeSpaces(line).equalsIgnoreCase(COMMAND_QUIT) || removeSpaces(line).equalsIgnoreCase(COMMAND_EXIT))
+ break;
+ else if (line.length() == 0)
+ continue;
+ else
+ {
+ command = line.split("\\s+");
+ commandlineoptionparser = new CommandLineOptionParser(command);
+ JMXinfo info = new JMXinfo(jmxc, commandlineoptionparser, mbsc);
+ CommandExecutionEngine engine = new CommandExecutionEngine(info);
+ if (engine.CommandSelector())
+ engine.runcommand();
+ }
+ }
+
+ conn.getConnector().close();
+ }
+ catch (Exception ex)
+ {
+ ex.printStackTrace();
+ }
+ }
+
+ private static void registerCommands()
+ {
+ CommandExecutionEngine.addCommand(Commanddelete.COMMAND_NAME, Commanddelete.class);
+ CommandExecutionEngine.addCommand(Commandget.COMMAND_NAME, Commandget.class);
+ CommandExecutionEngine.addCommand(Commandhelp.COMMAND_NAME, Commandhelp.class);
+ CommandExecutionEngine.addCommand(Commandinfo.COMMAND_NAME, Commandinfo.class);
+ CommandExecutionEngine.addCommand(Commandlist.COMMAND_NAME, Commandlist.class);
+ CommandExecutionEngine.addCommand(Commandmove.COMMAND_NAME, Commandmove.class);
+ CommandExecutionEngine.addCommand(Commandset.COMMAND_NAME, Commandset.class);
+ CommandExecutionEngine.addCommand(Commandview.COMMAND_NAME, Commandview.class);
+ CommandExecutionEngine.addCommand(Commandviewcontent.COMMAND_NAME, Commandviewcontent.class);
+ }
+
+ private static void Usage()
+ {
+ System.out.println("Connecting to localhost Qpid java broker...");
+ }
+
+ private static String removeSpaces(String s)
+ {
+ StringTokenizer st = new StringTokenizer(s, " ", false);
+ String t = "";
+ while (st.hasMoreElements())
+ t += st.nextElement();
+ return t;
+ }
+
+ private static void connectionrefuse(Exception e)
+ {
+ String message = e.getLocalizedMessage();
+ if (e instanceof SecurityException)
+ {
+ message = " authentication failed, please check username and password";
+ }
+ else
+ {
+ Throwable cause = e.getCause();
+ while (cause != null)
+ {
+ message = cause.getMessage();
+ cause = cause.getCause();
+ }
+ }
+
+ System.out.println("Cannot connect with the broker: " + message);
+ }
+
+ public static String[] oneshotmode(String[] args, CommandLineOptionParser commandlineoptionparser,
+ JMXConnector jmxc, MBeanServerConnection mbsc) throws Exception
+ {
+ int check = 0;
+ String[] temp;
+ for (int i = 0; i < args.length; i++)
+ {
+
+ if (args[i].compareTo("-h") == 0)
+ check++;
+ else if (args[i].compareTo("-p") == 0)
+ check++;
+ }
+ for (int i = 0; i < (args.length - 2 * check); i++)
+ { // mulitply by 2 because have to remove the option letter with the
+ // option value//
+ args[i] = args[i + check * 2];
+ }
+
+ commandlineoptionparser = new CommandLineOptionParser(args); // change
+ // the args
+ // string
+ // array
+ // which
+ // works as
+ // interactive
+ // mode//
+ JMXinfo info = new JMXinfo(jmxc, commandlineoptionparser, mbsc);
+ CommandExecutionEngine engine = new CommandExecutionEngine(info);
+ if (engine.CommandSelector())
+ engine.runcommand();
+ return args;
+
+ }
+}
diff --git a/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/Connector.java b/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/Connector.java
new file mode 100644
index 0000000000..2b887077c3
--- /dev/null
+++ b/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/Connector.java
@@ -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.
+ *
+ */
+package org.apache.qpid;
+
+import javax.management.MBeanServerConnection;
+import javax.management.remote.JMXConnector;
+
+public class Connector
+{
+ private JMXConnector jmxc = null;
+ private MBeanServerConnection mbsc = null;
+
+ public Connector(JMXConnector jmxc, MBeanServerConnection mbsc)
+ {
+
+ this.jmxc = jmxc;
+ this.mbsc = mbsc;
+
+ }
+
+ public JMXConnector getConnector()
+ {
+ return jmxc;
+ }
+
+ public MBeanServerConnection getMBeanServerConnection()
+ {
+ return mbsc;
+ }
+
+}
diff --git a/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/ConnectorFactory.java b/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/ConnectorFactory.java
new file mode 100644
index 0000000000..84ba94c5c4
--- /dev/null
+++ b/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/ConnectorFactory.java
@@ -0,0 +1,50 @@
+/*
+ *
+ * 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;
+
+import javax.management.MBeanServerConnection;
+import javax.management.remote.JMXConnector;
+
+import org.apache.qpid.management.common.JMXConnnectionFactory;
+
+public class ConnectorFactory
+{
+
+ private static final long TIMEOUT = 30 * 1000;
+
+ public static Connector getConnector(String host, String port, String username, String password) throws Exception
+ {
+
+ JMXConnector jmxc = null;
+ MBeanServerConnection mbsc = null;
+ try
+ {
+ jmxc = JMXConnnectionFactory.getJMXConnection(TIMEOUT, host, Integer.parseInt(port), username, password);
+ mbsc = jmxc.getMBeanServerConnection();
+ }
+ catch (NumberFormatException e)
+ {
+ System.out.println("Illegal port entered:" + port);
+ System.exit(1);
+ }
+ return new Connector(jmxc, mbsc);
+ }
+}
diff --git a/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/ReportGenerator.java b/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/ReportGenerator.java
new file mode 100644
index 0000000000..9d14f78b42
--- /dev/null
+++ b/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/ReportGenerator.java
@@ -0,0 +1,195 @@
+/*
+ *
+ * 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;
+
+import org.apache.qpid.commands.objects.*;
+import org.apache.qpid.utils.JMXinfo;
+
+import javax.management.MBeanServerConnection;
+import java.util.*;
+import java.io.FileInputStream;
+import java.io.IOException;
+
+public class ReportGenerator implements Runnable
+{
+
+ String[] propertyname = { "object", "column", "filter.name", "filter.virtualhost", "output", "seperator",
+ "interval" };
+ String[] propertyvalue = null;
+ String propertyfilepath = null;
+ String[] columnvalue = null;
+ List<String> columns = null;
+ Properties props = null;
+ JMXinfo info = null;
+ int interval = 10;
+
+ public void run()
+ {
+ for (;;) // creating infinite loop
+ {
+ generatereport();
+ try
+ {
+ Thread.sleep((long)this.interval * 60000L);
+ }
+ catch (Exception ex)
+ {
+ ex.printStackTrace();
+ }
+ }
+ }
+
+ public ReportGenerator(String propfile, JMXinfo info)
+ {
+ this.propertyfilepath = propfile;
+ props = new Properties();
+ propertyvalue = new String[propertyname.length];
+ this.info = info;
+ columns = new ArrayList<String>();
+ }
+
+ public void loadproperties() // get all the property file values and set the
+ // columen values//
+ {
+ try
+ {
+
+ props.load(new FileInputStream(this.propertyfilepath));
+ for (int i = 0; i < propertyname.length; i++)
+ {
+ propertyvalue[i] = props.getProperty(propertyname[i]);
+ }
+ this.setcolumnvalues();
+ this.setinterval();
+ }
+
+ // catch exception in case properties file does not exist
+
+ catch (IOException e)
+ {
+ System.out.println("Oooops Give property file is not exist");
+ }
+ }
+
+ public void generatereport()
+ {
+ this.listobjects(propertyvalue[0]);
+ }
+
+ private void setcolumnvalues()
+ {
+ columnvalue = propertyvalue[1].split(",");
+ for (int i = 0; i < columnvalue.length; i++)
+ {
+ columns.add(columnvalue[i]);
+ }
+ }
+
+ private void setinterval()
+ {
+ this.interval = (new Integer(propertyvalue[6])).intValue();
+ }
+
+ private void listobjects(String option_value)
+ {
+ /*
+ * pring usage if use is not give the correct option letter or no
+ * options
+ */
+ if (option_value == null)
+ {
+ // System.out.println("testing");
+ return;
+ }
+ MBeanServerConnection mbsc = info.getmbserverconnector();
+ Set set = null;
+ ObjectNames objname = null;
+
+ try
+ {
+ if (option_value.compareToIgnoreCase("queue") == 0 || option_value.compareToIgnoreCase("queues") == 0)
+ {
+ objname = new QueueObject(mbsc);
+
+ }
+ else if (option_value.compareToIgnoreCase("Virtualhosts") == 0
+ || option_value.compareToIgnoreCase("Virtualhost") == 0)
+ {
+ objname = new VirtualHostObject(mbsc);
+ // this.name = option_value;
+ }
+ else if (option_value.compareToIgnoreCase("Exchange") == 0
+ || option_value.compareToIgnoreCase("Exchanges") == 0)
+ {
+ objname = new ExchangeObject(mbsc);
+ // this.name = option_value;
+ }
+ else if (option_value.compareToIgnoreCase("Connection") == 0
+ || option_value.compareToIgnoreCase("Connections") == 0)
+ {
+ objname = new ConnectionObject(mbsc);
+ // this.name = option_value;
+ }
+ else if (option_value.compareToIgnoreCase("all") == 0)
+ {
+ objname = new AllObjects(mbsc);
+ // this.name = option_value;
+ }
+ else if (option_value.compareToIgnoreCase("Usermanagement") == 0
+ || option_value.compareToIgnoreCase("Usermanagmenets") == 0)
+ {
+ objname = new UserManagementObject(mbsc);
+ // this.name = option_value;
+ }
+ else
+ {
+ printusage();
+ echo("Wrong objectName");
+ return;
+ }
+ objname.setQueryString(this.propertyvalue[0], this.propertyvalue[2], this.propertyvalue[3]);
+ objname.returnObjects();
+ if (objname.getSet().size() != 0)
+ {
+ objname.reportgenerator(this.propertyvalue[4], this.propertyvalue[5], columns);
+ }
+ else
+ {
+ printusage();
+ }
+ }
+ catch (Exception ex)
+ {
+ ex.printStackTrace();
+ }
+
+ }
+
+ public void echo(String str)
+ {
+ System.out.println(str);
+ }
+
+ public void printusage()
+ {
+ System.out.println("Wrong option or wrong option value");
+ }
+}
diff --git a/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/CommandImpl.java b/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/CommandImpl.java
new file mode 100644
index 0000000000..6fdae4c0a6
--- /dev/null
+++ b/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/CommandImpl.java
@@ -0,0 +1,153 @@
+/*
+ *
+ * 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.commands;
+
+import java.util.Map;
+
+import org.apache.qpid.Command;
+import org.apache.qpid.utils.CommandLineOption;
+import org.apache.qpid.utils.JMXinfo;
+
+public abstract class CommandImpl implements Command
+{
+ protected JMXinfo info = null;
+
+ private String name;
+ private String virtualhost = null;
+ private String object = null;
+
+ private String outputformat = null;
+ private String seperator = ",";
+
+ public CommandImpl(JMXinfo info)
+ {
+ this.info = info;
+ }
+
+ public CommandImpl()
+ {
+
+ }
+
+ protected void setName(String name)
+ {
+ this.name = name;
+ }
+
+ public String getName()
+ {
+ return this.name;
+ }
+
+ protected boolean hasName()
+ {
+ if (this.name == null)
+ return false;
+
+ else
+ return true;
+ }
+
+ protected void setObject(String object)
+ {
+ this.object = object;
+ }
+
+ public String getObject()
+ {
+ return this.object;
+ }
+
+ protected void setOutputFormat(String outputformat)
+ {
+ this.outputformat = outputformat;
+ }
+
+ protected String getOutputFormat()
+ {
+ return outputformat;
+ }
+
+ protected void setSeperator(String seperator)
+ {
+ this.seperator = seperator;
+ }
+
+ protected String getSeperator()
+ {
+ return seperator;
+ }
+
+ protected void setVirtualhost(String virtualhost)
+ {
+ this.virtualhost = virtualhost;
+ }
+
+ public String getVirtualhost()
+ {
+ return this.virtualhost;
+ }
+
+ public String optionchecker(String option_letter)
+ {
+ Map map = info.getCommandLineOptionParser().getAlloptions();
+ if (map == null)
+ return null;
+ CommandLineOption option = (CommandLineOption) map.get(option_letter);
+ if (option == null)
+ return null;
+ String value = option.getOptionValue();
+ return value;
+ }
+
+ public boolean checkoptionsetting(String option_letter)
+ {
+ Map map = info.getCommandLineOptionParser().getAlloptions();
+ if (map == null)
+ return false;
+ CommandLineOption option = (CommandLineOption) map.get(option_letter);
+ if (option == null)
+ return false;
+ String value = option.getOptionType();
+
+ if (value != null)
+ return true;
+ else
+ return false;
+ }
+
+ public void echo(String str)
+ {
+ System.out.println(str);
+ }
+
+ public void unrecognizeoption()
+ {
+ echo("list: Unrecognized option");
+ echo("Try --help for more information");
+ }
+
+ public abstract void execute();
+
+ public abstract void printusage();
+
+}
diff --git a/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/Commanddelete.java b/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/Commanddelete.java
new file mode 100644
index 0000000000..cdbb8f1d4f
--- /dev/null
+++ b/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/Commanddelete.java
@@ -0,0 +1,199 @@
+/*
+ *
+ * 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.commands;
+
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+import java.util.Iterator;
+import java.util.Set;
+import java.util.StringTokenizer;
+
+import javax.management.MBeanServerConnection;
+import javax.management.ObjectName;
+
+import org.apache.qpid.commands.objects.QueueObject;
+import org.apache.qpid.utils.JMXinfo;
+
+public class Commanddelete extends CommandImpl
+{
+ private int number = 0;
+ private QueueObject objname;
+ private MBeanServerConnection mbsc;
+ private String method1, method2;
+ private ObjectName queue;
+ public static final String COMMAND_NAME = "delete";
+
+ public Commanddelete(JMXinfo info)
+ {
+ super(info);
+ this.mbsc = info.getmbserverconnector();
+ this.objname = new QueueObject(mbsc);
+ this.method1 = "deleteMessageFromTop";
+ this.method2 = "clearQueue";
+
+ }
+
+ public void deletemessages()
+ {
+ Set set = null;
+ objname.setQueryString(this.getObject(), this.getName(), this.getVirtualhost());
+ set = objname.returnObjects();
+
+ if (objname.getSet().size() != 0)
+ {
+ Iterator it = set.iterator();
+ this.queue = (ObjectName) it.next();
+ try
+ {
+ if (this.number == 0)
+ {
+ echo("");
+ System.out.print("Do you want to delete all the messages from the Queue [Y/N] :");
+ InputStreamReader isr = new InputStreamReader(System.in);
+ BufferedReader br = new BufferedReader(isr);
+ String s = br.readLine();
+ echo(s);
+ if (s.compareToIgnoreCase("y") == 0)
+ this.mbsc.invoke(queue, this.method2, null, null);
+ else
+ return;
+ }
+ else if (objname.getmessagecount(this.queue) < this.number)
+ {
+ echo("Given number is Greater than the Queue Depth");
+ return;
+ }
+ else
+ {
+ for (int i = 0; i < this.number; i++)
+ {
+ this.mbsc.invoke(queue, this.method1, null, null);
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ ex.printStackTrace();
+ }
+
+ }
+ else
+ {
+ if (hasName())
+ {
+
+ echo("The Queue you have specified is not in the current broker");
+ echo("");
+ }
+ else
+ {
+ printusage();
+ }
+ }
+ }
+
+ public void execute()
+ {
+ /*
+ * In here you it's easy to handle any number of otpions which are going
+ * to add with the list command which works with main option object or o
+ */
+
+ if (checkoptionsetting("object") || checkoptionsetting("o"))
+ {
+ String object = optionchecker("object");
+ if (object == null)
+ {
+ object = optionchecker("o");
+ }
+ if (object.compareToIgnoreCase("queue") == 0)
+ setObject(object);
+ else
+ {
+ unrecognizeoption();
+ echo("This command is only applicable for delete command so please start with queue");
+ }
+ if (checkoptionsetting("name") || checkoptionsetting("n"))
+ {
+ String name = optionchecker("name");
+ if (name == null)
+ name = optionchecker("n");
+
+ setName(name);
+ }
+ if (checkoptionsetting("virtualhost") || checkoptionsetting("v"))
+ {
+ String vhost = optionchecker("virtualhost");
+ if (vhost == null)
+ vhost = optionchecker("v");
+ setVirtualhost(vhost);
+ }
+ if (checkoptionsetting("top") || checkoptionsetting("t"))
+ {
+ String number = optionchecker("top");
+ if (number == null)
+ number = optionchecker("t");
+
+ setnumber(removeSpaces(number));
+ }
+ this.deletemessages();
+ }
+ else if (checkoptionsetting("h") || checkoptionsetting("help"))
+ printusage();
+ else
+ unrecognizeoption();
+ }
+
+ public void printusage()
+ {
+ echo("");
+ echo("Usage:delete [OPTION] ... [OBJECT TYPE]...\n");
+ echo("Delete the top most messages from the given queue object\n");
+ echo("To specify the desired queue you have to give the virtualhost name and the queue name with following commands\n");
+ echo("Where possible options include:\n");
+ echo(" -v --virtualhost Give the virtuallhost name of the desired queue");
+ echo(" -n --name Give the queue name of the desired queue you want to do the delete operation");
+ echo(" -t --top Give how many number of messages you want to delete from the top (Default = all the messages will be deleted");
+ echo(" -h --help Display the help and back to the qpid-cli prompt\n");
+
+ }
+
+ private void setnumber(String number)
+ {
+ Integer i = new Integer(number);
+ this.number = i.intValue();
+ }
+
+ public int getnumber()
+ {
+ return this.number;
+ }
+
+ private static String removeSpaces(String s)
+ {
+ StringTokenizer st = new StringTokenizer(s, " ", false);
+ String t = "";
+ while (st.hasMoreElements())
+ t += st.nextElement();
+ return t;
+ }
+}
diff --git a/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/Commandget.java b/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/Commandget.java
new file mode 100644
index 0000000000..cb67edeb34
--- /dev/null
+++ b/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/Commandget.java
@@ -0,0 +1,211 @@
+/*
+ *
+ * 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.commands;
+
+import org.apache.qpid.commands.objects.ObjectNames;
+import org.apache.qpid.commands.objects.QueueObject;
+import org.apache.qpid.utils.JMXinfo;
+
+import javax.management.MBeanServerConnection;
+import javax.management.ObjectName;
+import java.util.Set;
+
+public class Commandget extends CommandImpl
+{
+
+ private String _attributeName;
+ private String _value;
+ public static final String COMMAND_NAME = "get";
+
+ public Commandget(JMXinfo info)
+ {
+ super(info);
+ }
+
+ private void getAttribute(String option_value)
+ {
+ if (option_value == null)
+ {
+ printusage();
+ return;
+ }
+ MBeanServerConnection mbsc = info.getmbserverconnector();
+ Set set = null;
+ ObjectNames objname = null;
+
+ try
+ {
+ if (option_value.compareToIgnoreCase("queue") == 0 || option_value.compareToIgnoreCase("queues") == 0)
+ {
+ objname = new QueueObject(mbsc);
+ }
+ else
+ {
+ printusage();
+ echo("Wrong objectName");
+ return;
+ }
+
+ if (_attributeName == null)
+ {
+ echo("attribute name not specified. See --help for details");
+ return;
+ }
+
+ objname.setQueryString(this.getObject(), this.getName(), this.getVirtualhost());
+ objname.returnObjects();
+
+ if (objname.getSet().size() != 1)
+ {
+ echo("Your query returned more than one object to set was this intended?\n" + objname.getQueryString());
+ }
+ else if (objname.getSet().size() == 1)
+ {
+ ObjectName object = (ObjectName) objname.getSet().iterator().next();
+
+ Object value = objname.getAttribute(object, _attributeName);
+
+ echo(value.toString());
+ }
+ else
+ {
+ if (hasName())
+ {
+
+ echo("You might be querying wrong " + this.getObject() + " name with --name or -n option ");
+ echo("");
+ echo("No " + this.getObject() + "Type Objects might not in the broker currently");
+ echo("");
+ }
+ else
+ {
+ printusage();
+ }
+ }
+
+ }
+ catch (Exception ex)
+ {
+ ex.printStackTrace();
+ }
+
+ }
+
+ public void execute()
+ {
+ /*
+ * In here you it's easy to handle any number of otpions which are going
+ * to add with the list command which works with main option object or o
+ */
+ if (checkoptionsetting("output"))
+ {
+ setOutputFormat(optionchecker("output"));
+ if (checkoptionsetting("separator"))
+ {
+ setSeperator(optionchecker("separator"));
+ }
+ }
+ if (checkoptionsetting("object") || checkoptionsetting("o"))
+ {
+ String object = optionchecker("object");
+ if (object == null)
+ {
+ object = optionchecker("o");
+ }
+ setObject(object);
+
+ if (checkoptionsetting("name") || checkoptionsetting("n"))
+ {
+ String name = optionchecker("name");
+ if (name == null)
+ {
+ name = optionchecker("n");
+ }
+
+ setName(name);
+ }
+
+ if (checkoptionsetting("attribute") || checkoptionsetting("a"))
+ {
+ String name = optionchecker("attribute");
+ if (name == null)
+ {
+ name = optionchecker("a");
+ }
+
+ setAttributeName(name);
+ }
+ if (checkoptionsetting("virtualhost") || checkoptionsetting("v"))
+ {
+ String vhost = optionchecker("virtualhost");
+ if (vhost == null)
+ {
+ vhost = optionchecker("v");
+ }
+ setVirtualhost(vhost);
+ }
+ getAttribute(this.getObject());
+ }
+ else if (checkoptionsetting("h") || checkoptionsetting("help"))
+ {
+ printusage();
+ }
+ else
+ {
+ unrecognizeoption();
+ }
+ }
+
+ private void setAttributeName(String name)
+ {
+ this._attributeName = name;
+ }
+
+ public void printusage()
+ {
+ echo("");
+ echo("Usage:set [OPTION] ... [OBJECT TYPE]...\n");
+ echo("List the information about the given object\n");
+ echo("Where possible options include:\n");
+ echo(" -o --object type of objects which you want to list\n");
+ echo(" ex: < list -o queue > : lists all the queues created in the java broker\n");
+ echo(" For now list command is supporting following object typse \n");
+ echo(" Queue Connection VirtualHost UserMangement Exchange");
+ echo(" Or You can specify object type by giving it at the beginning");
+ echo(" rather giving it as a argument");
+ echo(" Ex:< queue list > this command is equal to list -o queue \n");
+ echo(" -v --virtualhost After specifying the object type you can filter output with this option");
+ echo(" list objects with the given virtualhost which will help to find ");
+ echo(" identical queue objects with -n option");
+ echo(" ex: queue list -v develop ment");
+ echo(" -n --name After specifying what type of objects you want to monitor you can filter");
+ echo(" the output using -n option by specifying the name of the object you want ");
+ echo(" to monitor exactly");
+ echo(" ex: <list -o queue -n ping> : list all the queue objects having queue name");
+ echo(" of ping");
+ echo(" ex: <queue list -n ping -v development> list all the queue objects with name ");
+ echo(" of ping and virtualhost of developement \n");
+ echo(" -a --attribute ");
+ echo(" -h --help Display the help and back to the qpid-cli prompt\n");
+
+ }
+}
diff --git a/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/Commandhelp.java b/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/Commandhelp.java
new file mode 100644
index 0000000000..502ac89f74
--- /dev/null
+++ b/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/Commandhelp.java
@@ -0,0 +1,56 @@
+/*
+ *
+ * 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.commands;
+
+import org.apache.qpid.utils.JMXinfo;
+
+public class Commandhelp extends CommandImpl
+{
+
+ public static final String COMMAND_NAME = "help";
+
+ public Commandhelp(JMXinfo info)
+ {
+ }
+
+ public void execute()
+ {
+ printusage();
+ }
+
+ public void printusage()
+ {
+ echo("");
+ echo("Current version of qpid CLI is supporting following commands");
+ echo("");
+ echo("[list] This command is listing limited information about a given type of object");
+ echo(" For more information about list command run `list --help`");
+ echo("[info] This command is listing All the information about a given type of object");
+ echo(" For more information about list command run `info --help`");
+
+ echo("");
+ echo("[exit] This command is disconnect the connection with the Qpid Java broker and go back to normal propmt");
+ echo("[quit] This command is disconnect the connection with the Qpid Java broker and go back to normal propmt");
+ echo("");
+ }
+
+}
diff --git a/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/Commandinfo.java b/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/Commandinfo.java
new file mode 100644
index 0000000000..7094a8fc7f
--- /dev/null
+++ b/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/Commandinfo.java
@@ -0,0 +1,206 @@
+/*
+ *
+ * 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.commands;
+
+import java.util.Set;
+
+import javax.management.MBeanServerConnection;
+
+import org.apache.qpid.commands.objects.AllObjects;
+import org.apache.qpid.commands.objects.ConnectionObject;
+import org.apache.qpid.commands.objects.ExchangeObject;
+import org.apache.qpid.commands.objects.ObjectNames;
+import org.apache.qpid.commands.objects.QueueObject;
+import org.apache.qpid.commands.objects.UserManagementObject;
+import org.apache.qpid.commands.objects.VirtualHostObject;
+import org.apache.qpid.utils.JMXinfo;
+
+public class Commandinfo extends CommandImpl
+{
+
+ public static final String COMMAND_NAME = "info";
+
+ public Commandinfo(JMXinfo info)
+ {
+ super(info);
+ }
+
+ private void listobjects(String option_value)
+ {
+ /*
+ * pring usage if use is not give the correct option letter or no
+ * options
+ */
+ if (option_value == null)
+ {
+ // System.out.println("testing");
+ printusage();
+ return;
+ }
+ MBeanServerConnection mbsc = info.getmbserverconnector();
+ Set set = null;
+ ObjectNames objname = null;
+
+ try
+ {
+ if (option_value.compareToIgnoreCase("queue") == 0 || option_value.compareToIgnoreCase("queues") == 0)
+ {
+ objname = new QueueObject(mbsc);
+
+ }
+ else if (option_value.compareToIgnoreCase("Virtualhosts") == 0
+ || option_value.compareToIgnoreCase("Virtualhost") == 0)
+ {
+ objname = new VirtualHostObject(mbsc);
+ // this.name = option_value;
+ }
+ else if (option_value.compareToIgnoreCase("Exchange") == 0
+ || option_value.compareToIgnoreCase("Exchanges") == 0)
+ {
+ objname = new ExchangeObject(mbsc);
+ // this.name = option_value;
+ }
+ else if (option_value.compareToIgnoreCase("Connection") == 0
+ || option_value.compareToIgnoreCase("Connections") == 0)
+ {
+ objname = new ConnectionObject(mbsc);
+ // this.name = option_value;
+ }
+ else if (option_value.compareToIgnoreCase("all") == 0)
+ {
+ objname = new AllObjects(mbsc);
+ // this.name = option_value;
+ }
+ else if (option_value.compareToIgnoreCase("Usermanagement") == 0
+ || option_value.compareToIgnoreCase("Usermanagmenets") == 0)
+ {
+ objname = new UserManagementObject(mbsc);
+ // this.name = option_value;
+ }
+ else
+ {
+ printusage();
+ echo("Wrong objectName");
+ return;
+ }
+ objname.setQueryString(this.getObject(), this.getName(), this.getVirtualhost());
+ objname.returnObjects();
+ if (objname.getSet().size() != 0)
+ {
+ objname.displayinfo(this.getOutputFormat(), this.getSeperator());
+
+ }
+ else
+ {
+ if (hasName())
+ {
+
+ echo("You might querying wrong " + this.getObject() + " name with --name or -n option ");
+ echo("");
+ echo("No "+this.getObject() + "Type Objects might not be in the broker currently");
+ echo("");
+ }
+ else
+ {
+ printusage();
+ }
+ }
+
+ }
+ catch (Exception ex)
+ {
+ ex.printStackTrace();
+ }
+
+ }
+
+ public void execute()
+ {
+ /*
+ * In here you it's easy to handle any number of otpions which are going
+ * to add with the list command which works with main option object or o
+ */
+ if (checkoptionsetting("output"))
+ {
+ setOutputFormat(optionchecker("output"));
+ if (checkoptionsetting("separator"))
+ setSeperator(optionchecker("separator"));
+ }
+ if (checkoptionsetting("object") || checkoptionsetting("o"))
+ {
+ String object = optionchecker("object");
+ if (object == null)
+ {
+ object = optionchecker("o");
+ }
+ setObject(object);
+ if (checkoptionsetting("name") || checkoptionsetting("n"))
+ {
+ String name = optionchecker("name");
+ if (name == null)
+ name = optionchecker("n");
+
+ setName(name);
+ }
+ if (checkoptionsetting("virtualhost") || checkoptionsetting("v"))
+ {
+ String vhost = optionchecker("virtualhost");
+ if (vhost == null)
+ vhost = optionchecker("v");
+ setVirtualhost(vhost);
+ }
+ listobjects(this.getObject());
+ }
+ else if (checkoptionsetting("h") || checkoptionsetting("help"))
+ printusage();
+ else
+ unrecognizeoption();
+ }
+
+ public void printusage()
+ {
+ echo("");
+ echo("Usage:info [OPTION] ... [OBJECT TYPE]...\n");
+ echo("Give ALL the information about the given object\n");
+ echo("Where possible options include:\n");
+ echo(" -o --object type of objects which you want to list\n");
+ echo(" ex: < list -o queue > : lists all the queues created in the java broker\n");
+ echo(" For now list command is supporting following object typse \n");
+ echo(" Queue Connection VirtualHost UserMangement Exchange");
+ echo(" Or You can specify object type by giving it at the beginning rather giving ");
+ echo(" it as a argument");
+ echo(" Ex:< queue info > this command is equal to <info -o queue> command \n");
+ echo(" -v --virtualhost After specifying the object type you can filter output with this option");
+ echo(" list objects with the given virtualhost which will help to find identical");
+ echo(" queue objects with -n option");
+ echo(" ex: queue info -v developement");
+ echo(" -output Specify which output format you want to get the ouput");
+ echo(" Although the option is there current version supports only for CSV output format");
+ echo(" -separator This option use with output option to specify which separator you want to get the CSV output (default seperator is comma");
+ echo(" -h --help Display the help and back to the qpid-cli prompt\n");
+ echo(" -n --name After specifying what type of objects you want to monitor you can filter");
+ echo(" the output using -n option by specifying the name of the object you want");
+ echo(" to monitor exactly");
+ echo(" ex: <queue info -n ping> : Give all the information about queue objects ");
+ echo(" having queue name of ping\n");
+ }
+}
diff --git a/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/Commandlist.java b/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/Commandlist.java
new file mode 100644
index 0000000000..68ee593ba0
--- /dev/null
+++ b/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/Commandlist.java
@@ -0,0 +1,232 @@
+/*
+ *
+ * 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.commands;
+
+import java.util.Set;
+
+import javax.management.MBeanServerConnection;
+
+import org.apache.qpid.commands.objects.AllObjects;
+import org.apache.qpid.commands.objects.ConnectionObject;
+import org.apache.qpid.commands.objects.ExchangeObject;
+import org.apache.qpid.commands.objects.ObjectNames;
+import org.apache.qpid.commands.objects.QueueObject;
+import org.apache.qpid.commands.objects.UserManagementObject;
+import org.apache.qpid.commands.objects.VirtualHostObject;
+import org.apache.qpid.utils.JMXinfo;
+
+public class Commandlist extends CommandImpl
+{
+
+ public static final String COMMAND_NAME = "list";
+
+ public Commandlist(JMXinfo info)
+ {
+ super(info);
+ }
+
+ private void listobjects(String option_value)
+ {
+ /*
+ * pring usage if use is not give the correct option letter or no
+ * options
+ */
+ if (option_value == null)
+ {
+ // System.out.println("testing");
+ printusage();
+ return;
+ }
+ MBeanServerConnection mbsc = info.getmbserverconnector();
+ Set set = null;
+ ObjectNames objname = null;
+
+ try
+ {
+ if (option_value.compareToIgnoreCase("queue") == 0 || option_value.compareToIgnoreCase("queues") == 0)
+ {
+ objname = new QueueObject(mbsc);
+
+ }
+ else if (option_value.compareToIgnoreCase("Virtualhosts") == 0
+ || option_value.compareToIgnoreCase("Virtualhost") == 0)
+ {
+ objname = new VirtualHostObject(mbsc);
+ // this.name = option_value;
+ }
+ else if (option_value.compareToIgnoreCase("Exchange") == 0
+ || option_value.compareToIgnoreCase("Exchanges") == 0)
+ {
+ objname = new ExchangeObject(mbsc);
+ // this.name = option_value;
+ }
+ else if (option_value.compareToIgnoreCase("Connection") == 0
+ || option_value.compareToIgnoreCase("Connections") == 0)
+ {
+ objname = new ConnectionObject(mbsc);
+ // this.name = option_value;
+ }
+ else if (option_value.compareToIgnoreCase("all") == 0)
+ {
+ objname = new AllObjects(mbsc);
+ // this.name = option_value;
+ }
+ else if (option_value.compareToIgnoreCase("Usermanagement") == 0
+ || option_value.compareToIgnoreCase("Usermanagmenets") == 0)
+ {
+ objname = new UserManagementObject(mbsc);
+ // this.name = option_value;
+ }
+ else
+ {
+ printusage();
+ echo("Wrong objectName");
+ return;
+ }
+ objname.setQueryString(this.getObject(), this.getName(), this.getVirtualhost());
+ objname.returnObjects();
+ if (objname.getSet().size() != 0)
+ {
+ if (this.getObject().compareToIgnoreCase("queue") == 0
+ || this.getObject().compareToIgnoreCase("queues") == 0)
+ objname.displayqueues(this.getOutputFormat(), this.getSeperator());
+ else
+ objname.displayobjects(this.getOutputFormat(), this.getSeperator());
+ }
+ else
+ {
+ if (hasName())
+ {
+
+ echo("You might quering wrong " + this.getObject() + " name with --name or -n option ");
+ echo("");
+ echo(this.getObject() + "Type Objects might not in the broker currently");
+ echo("");
+ }
+ else
+ {
+ printusage();
+ }
+ }
+
+ }
+ catch (Exception ex)
+ {
+ ex.printStackTrace();
+ }
+
+ }
+
+ public void listdomains()
+ {
+ MBeanServerConnection mbsc = info.getmbserverconnector();
+ try
+ {
+ String[] domains = mbsc.getDomains();
+ echo("DOMAINS");
+ for (int i = 0; i < domains.length; i++)
+ echo("\tDomain[" + i + "] = " + domains[i]);
+
+ }
+ catch (Exception ex)
+ {
+ ex.printStackTrace();
+ }
+ }
+
+ public void execute()
+ {
+ /*
+ * In here you it's easy to handle any number of otpions which are going
+ * to add with the list command which works with main option object or o
+ */
+ if (checkoptionsetting("output"))
+ {
+ setOutputFormat(optionchecker("output"));
+ if (checkoptionsetting("separator"))
+ setSeperator(optionchecker("separator"));
+ }
+ if (checkoptionsetting("object") || checkoptionsetting("o"))
+ {
+ String object = optionchecker("object");
+ if (object == null)
+ {
+ object = optionchecker("o");
+ }
+ setObject(object);
+ if (checkoptionsetting("name") || checkoptionsetting("n"))
+ {
+ String name = optionchecker("name");
+ if (name == null)
+ name = optionchecker("n");
+
+ setName(name);
+ }
+ if (checkoptionsetting("virtualhost") || checkoptionsetting("v"))
+ {
+ String vhost = optionchecker("virtualhost");
+ if (vhost == null)
+ vhost = optionchecker("v");
+ setVirtualhost(vhost);
+ }
+ listobjects(this.getObject());
+ }
+ else if (checkoptionsetting("domain") || checkoptionsetting("d"))
+ listdomains();
+ else if (checkoptionsetting("h") || checkoptionsetting("help"))
+ printusage();
+ else
+ unrecognizeoption();
+ }
+
+ public void printusage()
+ {
+ echo("");
+ echo("Usage:list [OPTION] ... [OBJECT TYPE]...\n");
+ echo("List the information about the given object\n");
+ echo("Where possible options include:\n");
+ echo(" -o --object type of objects which you want to list\n");
+ echo(" ex: < list -o queue > : lists all the queues created in the java broker\n");
+ echo(" For now list command is supporting following object typse \n");
+ echo(" Queue Connection VirtualHost UserMangement Exchange");
+ echo(" Or You can specify object type by giving it at the beginning");
+ echo(" rather giving it as a argument");
+ echo(" Ex:< queue list > this command is equal to list -o queue \n");
+ echo(" -d --domain list all the domains of objects available for remote monitoring\n");
+ echo(" -v --virtualhost After specifying the object type you can filter output with this option");
+ echo(" list objects with the given virtualhost which will help to find ");
+ echo(" identical queue objects with -n option");
+ echo(" ex: queue list -v develop ment");
+ echo(" -output Specify which output format you want to get the ouput");
+ echo(" Although the option is there current version supports only for CSV output format");
+ echo(" -separator This option use with output option to specify which separator you want to get the CSV output (default seperator is comma");
+ echo(" -h --help Display the help and back to the qpid-cli prompt\n");
+ echo(" -n --name After specifying what type of objects you want to monitor you can filter");
+ echo(" the output using -n option by specifying the name of the object you want ");
+ echo(" to monitor exactly");
+ echo(" ex: <list -o queue -n ping> : list all the queue objects having queue name");
+ echo(" of ping");
+ echo(" ex: <queue list -n ping -v development> list all the queue objects with name ");
+ echo(" of ping and virtualhost of developement \n");
+
+ }
+}
diff --git a/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/Commandmove.java b/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/Commandmove.java
new file mode 100644
index 0000000000..6d1803409b
--- /dev/null
+++ b/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/Commandmove.java
@@ -0,0 +1,259 @@
+/*
+ *
+ * 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.commands;
+
+import java.util.Iterator;
+import java.util.Set;
+import java.util.StringTokenizer;
+
+import javax.management.MBeanServerConnection;
+import javax.management.ObjectName;
+
+import org.apache.qpid.commands.objects.QueueObject;
+import org.apache.qpid.utils.JMXinfo;
+
+public class Commandmove extends CommandImpl
+{
+
+ public static final String COMMAND_NAME = "move";
+
+ private String name1 = null, name2 = null, vhost1 = null, vhost2 = null, method1 = null, method2 = null; // target
+ // and
+ // starting
+ // queue
+ // specifications
+ // happen
+ // with
+ // these
+ // options
+ private QueueObject queue1;
+ private MBeanServerConnection mbsc;
+ private ObjectName queue;
+ private int fmid = 0, tmid = 0;
+
+ public Commandmove(JMXinfo info)
+ {
+ super(info);
+
+ this.mbsc = info.getmbserverconnector();
+ this.queue1 = new QueueObject(mbsc);
+ this.method1 = "moveMessages";
+ this.method2 = "getMessagesOnTheQueue";
+
+ }
+
+ public void movemessages()
+ {
+ Set set = null;
+ queue1.setQueryString(this.getObject(), this.name1, this.vhost1);
+ set = queue1.returnObjects();
+ if (queue1.getSet().size() != 0)
+ { // find the queue
+ Iterator it = set.iterator();
+ this.queue = (ObjectName) it.next();
+ }
+ else
+ {
+ if (isname1() || isname2())
+ { // if the specified queue is not there in the broker
+
+ echo("The Queue you have specified is not in the current broker");
+ echo("");
+ }
+ else
+ {
+ printusage();
+ }
+ }
+ try
+ {
+ Object[] params1 = { getfmid(), gettmid(), this.name2 };
+ String[] signature1 = { new String("long"), new String("long"), new String("java.lang.String") };
+ this.mbsc.invoke(this.queue, this.method1, params1, signature1);
+
+ }
+ catch (Exception ex)
+ {
+ ex.printStackTrace();
+ echo("Given messageId's might be wrong please run the view command and check messageId's you have given\n");
+ echo("From MessageId should be greater than 0 and should less than To messageId");
+ }
+
+ }
+
+ public void execute()
+ {
+ /*
+ * In here you it's easy to handle any number of otpions which are going
+ * to add with the list command which works with main option object or o
+ */
+
+ if (checkoptionsetting("object") || checkoptionsetting("o"))
+ {
+ String object = optionchecker("object");
+ if (object == null)
+ {
+ object = optionchecker("o");
+ }
+ if (object.compareToIgnoreCase("queue") == 0)
+ setObject(object);
+ else
+ {
+ unrecognizeoption();
+ echo("This command is only applicable for queue command so please start with queue");
+ }
+ if (checkoptionsetting("n2") && checkoptionsetting("n1"))
+ {
+ setname1(optionchecker("n1"));
+ setname2(optionchecker("n2"));
+ }
+ else
+ {
+ echo("You have to specify both n1 and n2 option value to move a message"); /*
+ * when
+ * user
+ * forget
+ * to
+ * specify
+ * target
+ * or
+ * starting
+ * queue
+ * name
+ */
+ return;
+ }
+
+ if (checkoptionsetting("v1"))
+ {
+
+ setvhost1(optionchecker("v1"));
+ }
+ if (checkoptionsetting("tmid") && checkoptionsetting("fmid"))
+ {
+ String tmid = optionchecker("tmid");
+ String fmid = optionchecker("fmid");
+
+ settomessageIdandfrommessageId(removeSpaces(tmid), removeSpaces(fmid));
+ }
+ else
+ {
+ echo("You have to set from MessageId and to MessageId in order to move messages between queues");
+ echo("To view MessageId's use <view> command with -n and -v options");
+ return;
+ }
+ this.movemessages();
+
+ }
+ else if (checkoptionsetting("h") || checkoptionsetting("help"))
+ printusage();
+ else
+ unrecognizeoption();
+ }
+
+ public void printusage()
+ {
+ echo("");
+ echo("Usage:move [OPTION] ... [OBJECT TYPE]...\n");
+ echo("Move the top most messages from the given queue object to the given destination object\n");
+ echo("To specify the desired queues you have to give the virtualhost name and the queue name with following commands\n");
+ echo("Where possible options include:\n");
+ echo(" -v1 Give the virtuallhost name from which queue you want to move messages");
+ echo(" -n1 Give the queue name which you want to move messages from");
+ echo(" -n2 Give the queue name of the destination queue");
+ echo(" -tmid Give From MessageId you want to move from the Queue");
+ echo(" -fmid Give To MessageId you want to move from the Queue");
+ echo(" -h --help Display the help and back to the qpid-cli prompt\n");
+
+ }
+
+ private void setname1(String name)
+ {
+ this.name1 = name;
+ }
+
+ private void setname2(String name)
+ {
+ this.name2 = name;
+ }
+
+ private boolean isname1()
+ {
+ if (this.name1 == null)
+ return false;
+
+ else
+ return true;
+ }
+
+ private boolean isname2()
+ {
+ if (this.name2 == null)
+ return false;
+
+ else
+ return true;
+ }
+
+ private void setvhost1(String vhost)
+ {
+ this.vhost1 = vhost;
+ }
+
+ private static String removeSpaces(String s)
+ {
+ StringTokenizer st = new StringTokenizer(s, " ", false);
+ String t = "";
+ while (st.hasMoreElements())
+ t += st.nextElement();
+ return t;
+ }
+
+ private void settomessageIdandfrommessageId(String tmid, String fmid)
+ {
+ Integer i = new Integer(tmid);
+ Integer j = new Integer(fmid);
+ this.tmid = i.intValue();
+ this.fmid = j.intValue();
+ }
+
+ public int gettmid()
+ {
+ return this.tmid;
+ }
+
+ public int getfmid()
+ {
+ return this.fmid;
+ }
+
+ public String getname1()
+ {
+ return this.name1;
+ }
+
+ public String getname2()
+ {
+ return this.name2;
+ }
+
+}
diff --git a/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/Commandset.java b/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/Commandset.java
new file mode 100644
index 0000000000..e70b7b17ad
--- /dev/null
+++ b/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/Commandset.java
@@ -0,0 +1,260 @@
+/*
+ *
+ * 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.commands;
+
+import org.apache.qpid.commands.objects.ObjectNames;
+import org.apache.qpid.commands.objects.QueueObject;
+import org.apache.qpid.utils.JMXinfo;
+
+import javax.management.Attribute;
+import javax.management.MBeanServerConnection;
+import javax.management.ObjectName;
+import java.util.Set;
+
+public class Commandset extends CommandImpl
+{
+ private String _attributeName;
+ private String _value;
+ public static final String COMMAND_NAME = "set";
+
+ public Commandset(JMXinfo info)
+ {
+ super(info);
+ }
+
+ private void setAttribute(String option_value)
+ {
+ /*
+ * print usage if use is not give the correct option letter or no
+ * options
+ */
+ if (option_value == null)
+ {
+ printusage();
+ return;
+ }
+ MBeanServerConnection mbsc = info.getmbserverconnector();
+ Set set = null;
+ ObjectNames objname = null;
+
+ try
+ {
+ if (option_value.compareToIgnoreCase("queue") == 0 || option_value.compareToIgnoreCase("queues") == 0)
+ {
+ objname = new QueueObject(mbsc);
+ }
+ else
+ {
+ printusage();
+ echo("Wrong objectName");
+ return;
+ }
+
+ if (_attributeName == null)
+ {
+ echo("attribute name not specified. See --help for details");
+ return;
+ }
+
+ if (_value == null)
+ {
+ echo("new value not specified. See --help for details");
+ return;
+ }
+
+ objname.setQueryString(this.getObject(), this.getName(), this.getVirtualhost());
+ objname.returnObjects();
+
+ if (objname.getSet().size() != 1)
+ {
+ echo("Your query returned more than one object to set was this intended?" + objname.getQueryString());
+ }
+ else if (objname.getSet().size() == 1)
+ {
+ ObjectName object = (ObjectName) objname.getSet().iterator().next();
+
+ Object value = objname.getAttribute(object, _attributeName);
+
+ Object attributeValue = _value;
+
+ try
+ {
+ if (value instanceof Integer)
+ {
+ attributeValue = Integer.valueOf(_value);
+ }
+ else if (value instanceof Long)
+ {
+ attributeValue = Long.valueOf(_value);
+ }
+ }
+ catch (NumberFormatException nfe)
+ {
+ echo("Value(" + _attributeName + ") should be of type " + value.getClass().getName());
+ return;
+ }
+
+ Attribute attribute = new Attribute(_attributeName, attributeValue);
+
+ objname.setAttribute(object, attribute);
+ }
+ else
+ {
+ if (hasName())
+ {
+
+ echo("You might be querying wrong " + this.getObject() + " name with --name or -n option ");
+ echo("");
+ echo("No " + this.getObject() + "Type Objects might not in the broker currently");
+ echo("");
+ }
+ else
+ {
+ printusage();
+ }
+ }
+
+ }
+ catch (Exception ex)
+ {
+ ex.printStackTrace();
+ }
+
+ }
+
+ public void execute()
+ {
+ /*
+ * In here you it's easy to handle any number of otpions which are going
+ * to add with the list command which works with main option object or o
+ */
+ if (checkoptionsetting("output"))
+ {
+ setOutputFormat(optionchecker("output"));
+ if (checkoptionsetting("separator"))
+ {
+ setSeperator(optionchecker("separator"));
+ }
+ }
+ if (checkoptionsetting("object") || checkoptionsetting("o"))
+ {
+ String object = optionchecker("object");
+ if (object == null)
+ {
+ object = optionchecker("o");
+ }
+ setObject(object);
+
+ if (checkoptionsetting("name") || checkoptionsetting("n"))
+ {
+ String name = optionchecker("name");
+ if (name == null)
+ {
+ name = optionchecker("n");
+ }
+
+ setName(name);
+ }
+
+ if (checkoptionsetting("attribute") || checkoptionsetting("a"))
+ {
+ String name = optionchecker("attribute");
+ if (name == null)
+ {
+ name = optionchecker("a");
+ }
+
+ setAttributeName(name);
+ }
+
+ if (checkoptionsetting("set") || checkoptionsetting("s"))
+ {
+ String value = optionchecker("set");
+ if (value == null)
+ {
+ value = optionchecker("s");
+ }
+
+ setAttributeValue(value);
+ }
+
+ if (checkoptionsetting("virtualhost") || checkoptionsetting("v"))
+ {
+ String vhost = optionchecker("virtualhost");
+ if (vhost == null)
+ {
+ vhost = optionchecker("v");
+ }
+ setVirtualhost(vhost);
+ }
+ setAttribute(this.getObject());
+ }
+ else if (checkoptionsetting("h") || checkoptionsetting("help"))
+ {
+ printusage();
+ }
+ else
+ {
+ unrecognizeoption();
+ }
+ }
+
+ private void setAttributeValue(String value)
+ {
+ _value = value;
+ }
+
+ private void setAttributeName(String name)
+ {
+ this._attributeName = name;
+ }
+
+ public void printusage()
+ {
+ echo("");
+ echo("Usage:set [OPTION] ... [OBJECT TYPE]...\n");
+ echo("List the information about the given object\n");
+ echo("Where possible options include:\n");
+ echo(" -o --object type of objects which you want to list\n");
+ echo(" ex: < list -o queue > : lists all the queues created in the java broker\n");
+ echo(" For now list command is supporting following object typse \n");
+ echo(" Queue Connection VirtualHost UserMangement Exchange");
+ echo(" Or You can specify object type by giving it at the beginning");
+ echo(" rather giving it as a argument");
+ echo(" Ex:< queue list > this command is equal to list -o queue \n");
+ echo(" -v --virtualhost After specifying the object type you can filter output with this option");
+ echo(" list objects with the given virtualhost which will help to find ");
+ echo(" identical queue objects with -n option");
+ echo(" ex: queue list -v develop ment");
+ echo(" -n --name After specifying what type of objects you want to monitor you can filter");
+ echo(" the output using -n option by specifying the name of the object you want ");
+ echo(" to monitor exactly");
+ echo(" ex: <list -o queue -n ping> : list all the queue objects having queue name");
+ echo(" of ping");
+ echo(" ex: <queue list -n ping -v development> list all the queue objects with name ");
+ echo(" of ping and virtualhost of developement \n");
+ echo(" -a --attribute ");
+ echo(" -h --help Display the help and back to the qpid-cli prompt\n");
+
+ }
+
+}
diff --git a/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/Commandview.java b/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/Commandview.java
new file mode 100644
index 0000000000..e3bcc7e543
--- /dev/null
+++ b/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/Commandview.java
@@ -0,0 +1,255 @@
+/*
+ *
+ * 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.commands;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.StringTokenizer;
+
+import javax.management.MBeanServerConnection;
+import javax.management.ObjectName;
+import javax.management.openmbean.CompositeData;
+import javax.management.openmbean.TabularDataSupport;
+
+import org.apache.qpid.commands.objects.QueueObject;
+import org.apache.qpid.utils.JMXinfo;
+
+public class Commandview extends CommandImpl
+{
+
+ public static final String COMMAND_NAME = "view";
+
+ private int number = 0;
+ private QueueObject objname;
+ private MBeanServerConnection mbsc;
+ private String method1;
+ private ObjectName queue;
+
+ public Commandview(JMXinfo info)
+ {
+ super(info);
+ this.mbsc = info.getmbserverconnector();
+ this.objname = new QueueObject(mbsc);
+ this.method1 = "viewMessages";
+
+ }
+
+ public void viewmessages()
+ {
+ objname.setQueryString(this.getObject(), this.getName(), this.getVirtualhost());
+ Set set = objname.returnObjects();
+ String header = "", temp_header = "", message_data = "", outline = "";
+
+ if (objname.getSet().size() != 0)
+ {
+ Iterator it = set.iterator();
+ this.queue = (ObjectName) it.next();
+ try
+ {
+ if (objname.getmessagecount(this.queue) == 0)
+ {
+ echo("Selected Queue doesn't contain any messages");
+ return;
+ }
+ if (this.number == 0)
+ this.number = objname.getmessagecount(this.queue);
+
+ if (objname.getmessagecount(this.queue) < this.number)
+ {
+ echo("Given number is Greater than the Queue Depth");
+ return;
+ }
+ else
+ {
+ Object[] params = { 1, this.number };
+ String[] signature = { new String("int"), new String("int") };
+ TabularDataSupport data = (TabularDataSupport) this.mbsc.invoke(queue, this.method1, params,
+ signature);
+
+ Set entrySet = data.entrySet();
+ ArrayList<Map.Entry> list = new ArrayList<Map.Entry>(entrySet);
+ if (list.size() != 0)
+ {// no data}
+ for (int i = 0; i < list.size(); i++)
+ {
+ CompositeData compositedata = (CompositeData) (list.get(i)).getValue();
+ List<String> itemNames = new ArrayList<String>(compositedata.getCompositeType().keySet());
+ if (i == 0) // display the table headers
+ {
+ for (int j = 0; j < itemNames.size(); j++)
+ {
+ temp_header = "";
+ if (j != 1) // skipping header information
+ {
+ temp_header = itemNames.get(j);
+ while (temp_header.length() < 15)
+ temp_header = " " + temp_header;
+
+ header = header + temp_header + "|";
+ }
+ else
+ continue;
+ }
+ echo(header);
+ while (outline.length() < header.length())
+ outline = outline + "-";
+ echo(outline);
+ }
+
+ for (int j = 0; j < itemNames.size(); j++)
+ {
+ temp_header = "";
+ if (j != 1)
+ {
+ temp_header = String.valueOf(compositedata.get(itemNames.get(j)));
+ while (temp_header.length() < 15)
+ temp_header = " " + temp_header;
+ message_data = message_data + temp_header + "|";
+ }
+ else
+ // header information is not displaying
+ // unless user specify header information is
+ // needed
+ continue;
+
+ }
+ echo(message_data);
+ header = "";
+ message_data = "";
+ }
+ }
+ else
+ {
+ System.out.println("No Data to Display");
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ ex.printStackTrace();
+ }
+
+ }
+ else
+ {
+ if (hasName())
+ {
+
+ echo("The Queue you have specified is not in the current broker");
+ echo("");
+ }
+ else
+ {
+ printusage();
+ }
+ }
+ }
+
+ public void execute()
+ {
+ /*
+ * In here you it's easy to handle any number of otpions which are going
+ * to add with the list command which works with main option object or o
+ */
+
+ if (checkoptionsetting("object") || checkoptionsetting("o"))
+ {
+ String object = optionchecker("object");
+ if (object == null)
+ {
+ object = optionchecker("o");
+ }
+ if (object.compareToIgnoreCase("queue") == 0)
+ setObject(object);
+ else
+ {
+ unrecognizeoption();
+ echo("This command is only applicable for delete command so please start with queue");
+ }
+ if (checkoptionsetting("name") || checkoptionsetting("n"))
+ {
+ String name = optionchecker("name");
+ if (name == null)
+ name = optionchecker("n");
+
+ setName(name);
+ }
+ if (checkoptionsetting("virtualhost") || checkoptionsetting("v"))
+ {
+ String vhost = optionchecker("virtualhost");
+ if (vhost == null)
+ vhost = optionchecker("v");
+ setVirtualhost(vhost);
+ }
+ if (checkoptionsetting("top") || checkoptionsetting("t"))
+ {
+ String number = optionchecker("top");
+ if (number == null)
+ number = optionchecker("t");
+
+ setnumber(removeSpaces(number));
+ }
+ this.viewmessages();
+ }
+ else if (checkoptionsetting("h") || checkoptionsetting("help"))
+ printusage();
+ else
+ unrecognizeoption();
+ }
+
+ public void printusage()
+ {
+ echo("");
+ echo("Usage:view [OPTION] ... [OBJECT TYPE]...\n");
+ echo("view the information about given number of messages from the given queue object\n");
+ echo("To specify the desired queue you have to give the virtualhost name and the queue name with following commands\n");
+ echo("Where possible options include:\n");
+ echo(" -v --virtualhost Give the virtuallhost name of the desired queue");
+ echo(" -n --name Give the queue name of the desired queue you want to view messages");
+ echo(" -t --top Give how many number of messages you want to delete from the top (Default = all the messages will be deleted");
+ echo(" -h --help Display the help and back to the qpid-cli prompt\n");
+
+ }
+
+ private void setnumber(String number)
+ {
+ Integer i = new Integer(number);
+ this.number = i.intValue();
+ }
+
+ private static String removeSpaces(String s)
+ {
+ StringTokenizer st = new StringTokenizer(s, " ", false);
+ String t = "";
+ while (st.hasMoreElements())
+ t += st.nextElement();
+ return t;
+ }
+
+ public int getnumber()
+ {
+ return number;
+ }
+}
diff --git a/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/Commandviewcontent.java b/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/Commandviewcontent.java
new file mode 100644
index 0000000000..d1ae1c1893
--- /dev/null
+++ b/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/Commandviewcontent.java
@@ -0,0 +1,248 @@
+/*
+ *
+ * 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.commands;
+
+import java.nio.charset.Charset;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+import java.util.StringTokenizer;
+
+import javax.management.MBeanServerConnection;
+import javax.management.ObjectName;
+import javax.management.openmbean.CompositeData;
+
+import org.apache.qpid.commands.objects.QueueObject;
+import org.apache.qpid.utils.JMXinfo;
+
+public class Commandviewcontent extends CommandImpl
+{
+
+ public static final String COMMAND_NAME = "viewcontent";
+
+ private long number = 0;
+ private QueueObject objname;
+ private MBeanServerConnection mbsc;
+ private String method1;
+ private ObjectName queue;
+
+ public Commandviewcontent(JMXinfo info)
+ {
+ super(info);
+ this.mbsc = info.getmbserverconnector();
+ this.objname = new QueueObject(mbsc);
+ this.method1 = "viewMessageContent";
+
+ }
+
+ public void viewcontent()
+ {
+ objname.setQueryString(getObject(), getName(), getVirtualhost());
+ Set set = objname.returnObjects();
+ String temp_header = "", header = "", message_data = "", encoding = null;
+
+ if (objname.getSet().size() != 0)
+ {
+ Iterator it = set.iterator();
+ this.queue = (ObjectName) it.next();
+ try
+ {
+ if (objname.getmessagecount(this.queue) == 0)
+ {
+ echo("Selected Queue doesn't contain any messages");
+ return;
+ }
+ if (this.number == 0)
+ {
+ echo("You haven't selected a MessageId Please use -id and give a message id");
+ echo("Or run view command with same arguemnts to view messageId list for the queue");
+ }
+ else
+ {
+ Object[] params = { this.number };
+ String[] signature = { new String("long") };
+ CompositeData data = (CompositeData) this.mbsc.invoke(queue, this.method1, params, signature);
+ List<String> itemNames = new ArrayList<String>(data.getCompositeType().keySet());
+ for (int j = 0; j < itemNames.size(); j++)
+ {
+ temp_header = "";
+ temp_header = itemNames.get(j);
+ while (temp_header.length() < 15)
+ temp_header = " " + temp_header;
+
+ header = header + temp_header + "|";
+ }
+ echo(header);
+ encoding = String.valueOf(data.get(itemNames.get(2))); // set
+ // the
+ // encoding
+ // at
+ // the
+ // beginning
+ // because
+ // encoding
+ // comes
+ // later
+ // in
+ // the
+ // loop
+ if (encoding == null || encoding.length() == 0)
+ {
+ encoding = Charset.defaultCharset().name();
+
+ }
+ for (int j = 0; j < itemNames.size(); j++)
+ {
+ temp_header = "";
+ if (j != 1)
+ {
+ temp_header = String.valueOf(data.get(itemNames.get(j)));
+ while (temp_header.length() < 15)
+ temp_header = " " + temp_header;
+ }
+ else
+ {
+ Byte[] arrayItems = (Byte[]) data.get(itemNames.get(j));
+ byte[] byteArray = new byte[arrayItems.length];
+ for (int i = 0; i < arrayItems.length; i++)
+ {
+ byteArray[i] = arrayItems[i];
+ temp_header = new String(byteArray, encoding);
+ while (temp_header.length() < 15)
+ temp_header = " " + temp_header;
+ }
+ }
+ message_data = message_data + temp_header + "|";
+
+ }
+ echo(message_data);
+ }
+ }
+ catch (Exception ex)
+ {
+ echo("Given MessageId is invalid, There's no message with the given messageId");
+ ex.printStackTrace();
+ return;
+ }
+
+ }
+ else
+ {
+ if (hasName())
+ {
+
+ echo("The Queue you have specified is not in the current broker");
+ echo("");
+ }
+ else
+ {
+ printusage();
+ }
+ }
+ }
+
+ public void execute()
+ {
+ /*
+ * In here you it's easy to handle any number of otpions which are going
+ * to add with the list command which works with main option object or o
+ */
+
+ if (checkoptionsetting("object") || checkoptionsetting("o"))
+ {
+ String object = optionchecker("object");
+ if (object == null)
+ {
+ object = optionchecker("o");
+ }
+ if (object.compareToIgnoreCase("queue") == 0)
+ setObject(object);
+ else
+ {
+ unrecognizeoption();
+ echo("This command is only applicable for delete command so please start with queue");
+ }
+ if (checkoptionsetting("name") || checkoptionsetting("n"))
+ {
+ String name = optionchecker("name");
+ if (name == null)
+ name = optionchecker("n");
+
+ setName(name);
+ }
+ if (checkoptionsetting("virtualhost") || checkoptionsetting("v"))
+ {
+ String vhost = optionchecker("virtualhost");
+ if (vhost == null)
+ vhost = optionchecker("v");
+ setVirtualhost(vhost);
+ }
+ if (checkoptionsetting("messageid") || checkoptionsetting("id"))
+ {
+ String number = optionchecker("id");
+ if (number == null)
+ number = optionchecker("id");
+
+ setnumber(removeSpaces(number));
+ }
+ this.viewcontent();
+ }
+ else if (checkoptionsetting("h") || checkoptionsetting("help"))
+ printusage();
+ else
+ unrecognizeoption();
+ }
+
+ public void printusage()
+ {
+ echo("");
+ echo("Usage:viewcontent [OPTION] ... [OBJECT TYPE]...\n");
+ echo("view the information about given number of messages from the given queue object\n");
+ echo("To specify the desired queue you have to give the virtualhost name and the queue name with following commands\n");
+ echo("Where possible options include:\n");
+ echo(" -v --virtualhost Give the virtuallhost name of the desired queue");
+ echo(" -n --name Give the queue name of the desired queue you want to view messages");
+ echo(" -id Give the messageId of the required message you want to view the content");
+ echo(" -h --help Display the help and back to the qpid-cli prompt\n");
+
+ }
+
+ private void setnumber(String number)
+ {
+ this.number = Long.valueOf(number);
+ }
+
+ private static String removeSpaces(String s)
+ {
+ StringTokenizer st = new StringTokenizer(s, " ", false);
+ String t = "";
+ while (st.hasMoreElements())
+ t += st.nextElement();
+ return t;
+ }
+
+ public long getnumber()
+ {
+ return this.number;
+ }
+
+}
diff --git a/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/objects/AllObjects.java b/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/objects/AllObjects.java
new file mode 100644
index 0000000000..8b2099f3e0
--- /dev/null
+++ b/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/objects/AllObjects.java
@@ -0,0 +1,38 @@
+/*
+ *
+ * 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.commands.objects;
+
+import javax.management.MBeanServerConnection;
+
+public class AllObjects extends ObjectNames
+{
+
+ public AllObjects(MBeanServerConnection mbsc)
+ {
+ super(mbsc);
+ }
+
+ public void setQueryString(String object, String name)
+ {
+ querystring = "org.apache.qpid:*";
+ }
+}
diff --git a/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/objects/ConnectionObject.java b/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/objects/ConnectionObject.java
new file mode 100644
index 0000000000..2746b2016f
--- /dev/null
+++ b/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/objects/ConnectionObject.java
@@ -0,0 +1,46 @@
+/*
+ *
+ * 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.commands.objects;
+
+import javax.management.MBeanServerConnection;
+
+public class ConnectionObject extends ObjectNames
+{
+ public ConnectionObject(MBeanServerConnection mbsc)
+ {
+ /* calling parent classes constructor */
+ super(mbsc);
+ }
+
+ public void setQueryString(String object, String name, String vhost)
+ {
+ if (name != null && vhost == null)
+ querystring = "org.apache.qpid:type=Connection,name=" + name + ",*";
+ else if (name != null && vhost != null)
+ querystring = "org.apache.qpid:type=Connection,VirtualHost=" + vhost + ",name=" + name + ",*";
+ else if (name == null && vhost != null)
+ querystring = "org.apache.qpid:type=Connection,VirtualHost=" + vhost + ",*";
+ else
+ querystring = "org.apache.qpid:type=Connection,*";
+
+ }
+}
diff --git a/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/objects/ExchangeObject.java b/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/objects/ExchangeObject.java
new file mode 100644
index 0000000000..96d7e6e5dc
--- /dev/null
+++ b/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/objects/ExchangeObject.java
@@ -0,0 +1,45 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+package org.apache.qpid.commands.objects;
+
+import javax.management.MBeanServerConnection;
+
+public class ExchangeObject extends ObjectNames
+{
+ public ExchangeObject(MBeanServerConnection mbsc)
+ {
+ super(mbsc);
+ }
+
+ public void setQueryString(String object, String name, String vhost)
+ {
+ if (name != null && vhost == null)
+ querystring = "org.apache.qpid:type=VirtualHost.Exchange,name=" + name + ",*";
+ else if (name != null && vhost != null)
+ querystring = "org.apache.qpid:type=VirtualHost.Exchange,VirtualHost=" + vhost + ",name=" + name + ",*";
+ else if (name == null && vhost != null)
+ querystring = "org.apache.qpid:type=VirtualHost.Exchange,VirtualHost=" + vhost + ",*";
+ else
+ querystring = "org.apache.qpid:type=VirtualHost.Exchange,*";
+
+ }
+}
diff --git a/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/objects/ObjectNames.java b/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/objects/ObjectNames.java
new file mode 100644
index 0000000000..1432f18018
--- /dev/null
+++ b/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/objects/ObjectNames.java
@@ -0,0 +1,591 @@
+/*
+ *
+ * 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.commands.objects;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.management.Attribute;
+import javax.management.MBeanAttributeInfo;
+import javax.management.MBeanInfo;
+import javax.management.MBeanServerConnection;
+import javax.management.ObjectName;
+
+import org.apache.qpid.management.common.mbeans.ManagedQueue;
+
+public class ObjectNames
+{
+ public String querystring = null;
+ public MBeanServerConnection mbsc;
+ public Set<ObjectName> set = null;
+ public String attributes = "";
+ public String attributevalues = "";// = null;
+
+ private static final Map<String,Integer> QUEUE_ATTRIBUTES = new HashMap<String,Integer>();
+ static
+ {
+ QUEUE_ATTRIBUTES.put(ManagedQueue.ATTR_NAME, 1);
+ QUEUE_ATTRIBUTES.put(ManagedQueue.ATTR_DURABLE, 2);
+ QUEUE_ATTRIBUTES.put(ManagedQueue.ATTR_ACTIVE_CONSUMER_COUNT, 3);
+ QUEUE_ATTRIBUTES.put(ManagedQueue.ATTR_MSG_COUNT, 4);
+ QUEUE_ATTRIBUTES.put(ManagedQueue.ATTR_RCVD_MSG_COUNT, 5);
+ }
+
+ public ObjectNames(MBeanServerConnection mbsc)
+ {
+ this.mbsc = mbsc;
+ }
+
+ public Set<ObjectName> returnObjects()
+ {
+ try
+ {
+ set = mbsc.queryNames(new ObjectName(querystring), null);
+ }
+ catch (Exception ex)
+ {
+ ex.printStackTrace();
+ }
+ return set;
+ }
+
+ public void echo(String str)
+ {
+ System.out.println(str);
+ }
+
+ /* display appropriate objects according to the ojbect type */
+
+ public void displayobjects(String output, String seperator)
+ {
+ Iterator it = set.iterator();
+ String line = "";
+ String temp2 = "";
+ int iterator = 0;
+ try
+ {
+ do
+ {
+ ObjectName temp_object = null;
+ if (it.hasNext())
+ {
+ temp_object = (ObjectName) it.next();
+ if (temp_object == null)
+ System.out.println("null test");
+ }
+ // echo(temp_object.getCanonicalKeyPropertyListString());
+ MBeanInfo bean_info = mbsc.getMBeanInfo(temp_object);
+ MBeanAttributeInfo[] attr_info = bean_info.getAttributes();
+ if (attr_info == null)
+ {
+ echo(temp_object.toString());
+ String temp = "";
+ while (temp_object.toString().length() > temp.length())
+ temp = "=" + temp;
+ if (output == null)
+ echo(temp);
+
+ }
+ else
+ {
+ for (MBeanAttributeInfo attr : attr_info)
+ {
+ Object toWrite = null;
+
+ try
+ {
+ String temp1 = attr.getName();
+ if (output == null)
+ {
+ while (temp1.length() < 15)
+ temp1 = " " + temp1;
+ attributes = attributes + temp1 + "|";
+ }
+ else if (output.compareToIgnoreCase("csv") == 0)
+ attributes = attributes + temp1 + seperator;
+ else
+ {
+ echo("Wrong output format current version is supporting only for CSV");
+ return;
+ }
+ }
+ catch (Exception x)
+ {
+ x.printStackTrace();
+ }
+ }
+ if (attributes.equalsIgnoreCase(""))
+ {
+ echo(temp_object.toString());
+ String temp = "";
+ while (temp_object.toString().length() > temp.length())
+ temp = "=" + temp;
+ echo(temp);
+ echo("There are no attributes for this object Type");
+ continue;
+ }
+ for (MBeanAttributeInfo attr : attr_info)
+ {
+ Object toWrite = null;
+ temp2 = null;
+ try
+ {
+ toWrite = mbsc.getAttribute(temp_object, attr.getName());
+ }
+ catch (Exception x)
+ {
+ temp2 = "-";
+ }
+ if (toWrite != null)
+ temp2 = toWrite.toString();
+ else
+ temp2 = "-";
+ if (output == null)
+ {
+
+ while (temp2.length() < 15)
+ temp2 = " " + temp2;
+
+ attributevalues = attributevalues + temp2 + "|";
+ }
+ else if (output.compareToIgnoreCase("csv") == 0)
+ attributevalues = attributevalues + temp2 + seperator;
+
+ // echo(temp1 + " " + temp2 + " " + temp3);
+
+ }
+ }
+ iterator++;
+ if (iterator == 1)
+ {
+ echo(attributes);
+ for (int i = 0; i < attributes.length(); i++)
+ line = line + "-";
+ if (output == null)
+ echo(line);
+ }
+ echo(attributevalues);
+ line = "";
+ attributes = "";
+ attributevalues = "";
+ } while (it.hasNext());
+ }
+ catch (Exception ex)
+ {
+ ex.printStackTrace();
+ }
+
+ }
+
+ public void reportgenerator(String output, String seperator, List<String> column)
+ {
+ Iterator it = set.iterator();
+ String line = "";
+ String temp2 = "";
+ int iterator = 0;
+ try
+ {
+ do
+ {
+ ObjectName temp_object = null;
+ if (it.hasNext())
+ {
+ temp_object = (ObjectName) it.next();
+ if (temp_object == null)
+ System.out.println("null test");
+ }
+ // echo(temp_object.getCanonicalKeyPropertyListString());
+ MBeanInfo bean_info = mbsc.getMBeanInfo(temp_object);
+ MBeanAttributeInfo[] attr_info = bean_info.getAttributes();
+ if (attr_info == null)
+ {
+ echo(temp_object.toString());
+ String temp = "";
+ while (temp_object.toString().length() > temp.length())
+ temp = "=" + temp;
+ if (output == null)
+ echo(temp);
+
+ }
+ else
+ {
+ for (MBeanAttributeInfo attr : attr_info)
+ {
+ Object toWrite = null;
+
+ try
+ {
+ String temp1 = attr.getName();
+ if (column.contains(temp1))
+ {
+ if (output == null)
+ {
+ while (temp1.length() < 15)
+ temp1 = " " + temp1;
+ attributes = attributes + temp1 + "|";
+ }
+ else if (output.compareToIgnoreCase("csv") == 0)
+ attributes = attributes + temp1 + seperator;
+ else
+ {
+ echo("Wrong output format current version is supporting only for CSV");
+ return;
+ }
+ }
+ }
+ catch (Exception x)
+ {
+ x.printStackTrace();
+ }
+ }
+ if (attributes.equalsIgnoreCase(""))
+ {
+ echo(temp_object.toString());
+ String temp = "";
+ while (temp_object.toString().length() > temp.length())
+ temp = "=" + temp;
+ echo(temp);
+ echo("There are no attributes for this object Type");
+ return;
+ }
+ for (MBeanAttributeInfo attr : attr_info)
+ {
+ Object toWrite = null;
+ temp2 = null;
+ if (column.contains(attr.getName()))
+ {
+ try
+ {
+ toWrite = mbsc.getAttribute(temp_object, attr.getName());
+ }
+ catch (Exception x)
+ {
+ temp2 = "-";
+ }
+ if (toWrite != null)
+ temp2 = toWrite.toString();
+ else
+ temp2 = "-";
+ if (output == null)
+ {
+
+ while (temp2.length() < 15)
+ temp2 = " " + temp2;
+
+ attributevalues = attributevalues + temp2 + "|";
+ }
+ else if (output.compareToIgnoreCase("csv") == 0)
+ attributevalues = attributevalues + temp2 + seperator;
+
+ // echo(temp1 + " " + temp2 + " " + temp3);
+
+ }
+
+ }
+ }
+ iterator++;
+ if (iterator == 1)
+ {
+ echo(attributes);
+ for (int i = 0; i < attributes.length(); i++)
+ line = line + "-";
+ if (output == null)
+ echo(line);
+ }
+ echo(attributevalues);
+ line = "";
+ attributes = "";
+ attributevalues = "";
+ } while (it.hasNext());
+ }
+ catch (Exception ex)
+ {
+ ex.printStackTrace();
+ }
+
+ }
+
+ public void displayqueues(String output, String seperator)
+ {
+ Iterator it = set.iterator();
+ String line = "";
+ int iterator = 0;
+ String temp1 = "";
+ String temp2 = "";
+ try
+ {
+ do
+ {
+ ObjectName temp_object = null;
+ if (it.hasNext())
+ {
+ temp_object = (ObjectName) it.next();
+ }
+ // echo(temp_object.getCanonicalKeyPropertyListString());
+ MBeanInfo bean_info = mbsc.getMBeanInfo(temp_object);
+ MBeanAttributeInfo[] attr_info = bean_info.getAttributes();
+ if (attr_info == null)
+ {
+ echo(temp_object.toString());
+ String temp = "";
+ while (temp_object.toString().length() > temp.length())
+ temp = "=" + temp;
+ if (output == null)
+ echo(temp);
+
+ }
+ else
+ {
+ for (MBeanAttributeInfo attr : attr_info)
+ {
+ Object toWrite = null;
+ Integer attr_count = QUEUE_ATTRIBUTES.get(attr.getName());
+
+ if(attr_count == null)
+ {
+ continue;
+ }
+
+ try
+ {
+ toWrite = mbsc.getAttribute(temp_object, attr.getName());
+ if (output == null)
+ {
+ switch (attr_count)
+ {
+ case 1:
+ case 2:
+ temp1 = attr.getName();
+ while (temp1.length() < 10)
+ temp1 = " " + temp1;
+ attributes = attributes + temp1 + "|";
+ temp2 = toWrite.toString();
+ while (temp2.length() < 10)
+ temp2 = " " + temp2;
+ attributevalues = attributevalues + temp2 + "|";
+ break;
+ case 3:
+ temp1 = attr.getName();
+ while (temp1.length() < 20)
+ temp1 = " " + temp1;
+ attributes = attributes + temp1 + "|";
+ temp2 = toWrite.toString();
+ while (temp2.length() < 20)
+ temp2 = " " + temp2;
+ attributevalues = attributevalues + temp2 + "|";
+ break;
+ case 4:
+ temp1 = attr.getName();
+ while (temp1.length() < 13)
+ temp1 = " " + temp1;
+ attributes = attributes + temp1 + "|";
+ temp2 = toWrite.toString();
+ while (temp2.length() < 13)
+ temp2 = " " + temp2;
+ attributevalues = attributevalues + temp2 + "|";
+ break;
+ case 5:
+ temp1 = attr.getName();
+ while (temp1.length() < 20)
+ temp1 = " " + temp1;
+ attributes = attributes + temp1 + "|";
+ temp2 = toWrite.toString();
+ while (temp2.length() < 20)
+ temp2 = " " + temp2;
+ attributevalues = attributevalues + temp2 + "|";
+ break;
+ }
+ }
+ else if (output.compareToIgnoreCase("csv") == 0)
+ {
+ temp1 = attr.getName();
+ attributes = attributes + temp1 + seperator;
+ temp2 = toWrite.toString();
+ attributevalues = attributevalues + temp2 + seperator;
+ }
+ else
+ {
+ echo("Wrong output format specified currently CLI supports only csv output format");
+ return;
+ }
+
+ }
+ catch (Exception x)
+ {
+ x.printStackTrace();
+ }
+
+ }
+ }
+ iterator++;
+ if (iterator == 1)
+ {
+ for (int i = 0; i < attributes.length(); i++)
+ line = line + "-";
+ if (output == null)
+ echo(line);
+ echo(attributes);
+ if (output == null)
+ echo(line);
+ }
+ echo(attributevalues);
+ line = "";
+ attributes = "";
+ attributevalues = "";
+ } while (it.hasNext());
+ }
+ catch (Exception ex)
+ {
+ ex.printStackTrace();
+ }
+ }
+
+ public void displayinfo(String output, String seperator)
+ {
+ Iterator it = set.iterator();
+ String temp1, temp2 = "";
+ try
+ {
+ do
+ {
+
+ ObjectName temp_object = null;
+ if (it.hasNext())
+ {
+ temp_object = (ObjectName) it.next();
+ }
+ // echo(temp_object.getCanonicalKeyPropertyListString());
+ MBeanInfo bean_info = mbsc.getMBeanInfo(temp_object);
+ MBeanAttributeInfo[] attr_info = bean_info.getAttributes();
+ if (attr_info == null)
+ {
+ echo(temp_object.toString());
+ String temp = "";
+ while (temp_object.toString().length() > temp.length())
+ temp = "=" + temp;
+ echo(temp);
+
+ }
+ else
+ {
+ echo(temp_object.toString());
+ String temp = "";
+ while (temp_object.toString().length() > temp.length())
+ temp = "=" + temp;
+ echo(temp);
+
+ for (MBeanAttributeInfo attr : attr_info)
+ {
+ Object toWrite = null;
+
+ try
+ {
+ toWrite = mbsc.getAttribute(temp_object, attr.getName());
+ }
+ catch (Exception x)
+ {
+ temp2 = "-";
+ }
+ temp1 = attr.getName();
+ if (toWrite != null)
+ temp2 = toWrite.toString();
+
+ if (output == null)
+ {
+ while (temp1.length() < 35)
+ temp1 = " " + temp1;
+
+ while (temp2.length() < 35)
+ temp2 = " " + temp2;
+ echo(temp1 + " " + temp2);
+ }
+ else if (output.compareToIgnoreCase("csv") == 0)
+ echo(temp1 + seperator + temp2);
+ else
+ {
+ echo("Wrong output format specified currently CLI supports only csv output format");
+ return;
+ }
+ }
+ echo("");
+ echo("");
+
+ }
+ } while (it.hasNext());
+ }
+ catch (Exception ex)
+ {
+ ex.printStackTrace();
+ }
+
+ }
+
+ public void setQueryString(String object, String name, String vhost)
+ {
+
+ }
+
+ public void setQueryStringforinfo(String object, String name, String virtualhost)
+ {
+
+ }
+
+ public String getQueryString()
+ {
+ return querystring;
+ }
+
+ public Set getSet()
+ {
+ return set;
+ }
+
+ public Object getAttribute(ObjectName object, String attribute)
+ {
+ try
+ {
+ return mbsc.getAttribute(object, attribute);
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+
+ return null;
+ }
+
+ public void setAttribute(ObjectName object, Attribute attribute)
+ {
+ try
+ {
+ mbsc.setAttribute(object, attribute);
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+ }
+
+}
diff --git a/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/objects/QueueObject.java b/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/objects/QueueObject.java
new file mode 100644
index 0000000000..fcf0464ced
--- /dev/null
+++ b/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/objects/QueueObject.java
@@ -0,0 +1,67 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+package org.apache.qpid.commands.objects;
+
+import javax.management.MBeanServerConnection;
+import javax.management.ObjectName;
+
+import org.apache.qpid.management.common.mbeans.ManagedQueue;
+
+public class QueueObject extends ObjectNames
+{
+ public QueueObject(MBeanServerConnection mbsc)
+ {
+ super(mbsc);
+ }
+
+ public void setQueryString(String object, String name, String vhost)
+ {
+ if (name != null && vhost == null)
+ querystring = "org.apache.qpid:type=VirtualHost.Queue,name=" + name + ",*";
+ else if (name != null && vhost != null)
+ querystring = "org.apache.qpid:type=VirtualHost.Queue,VirtualHost=" + vhost + ",name=" + name + ",*";
+ else if (name == null && vhost != null)
+ querystring = "org.apache.qpid:type=VirtualHost.Queue,VirtualHost=" + vhost + ",*";
+ else
+ querystring = "org.apache.qpid:type=VirtualHost.Queue,*";
+ }
+
+ public int getmessagecount(ObjectName queue)
+ {
+ Number depth = null;
+
+ try
+ {
+ depth = (Number) mbsc.getAttribute(queue, ManagedQueue.ATTR_MSG_COUNT);
+
+ }
+ catch (Exception ex)
+ {
+ ex.printStackTrace();
+ }
+ if (depth != null)
+ return depth.intValue();
+ else
+ return -1;
+ }
+
+}
diff --git a/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/objects/UserManagementObject.java b/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/objects/UserManagementObject.java
new file mode 100644
index 0000000000..fd5bc0ca72
--- /dev/null
+++ b/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/objects/UserManagementObject.java
@@ -0,0 +1,38 @@
+/*
+ *
+ * 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.commands.objects;
+
+import javax.management.MBeanServerConnection;
+
+public class UserManagementObject extends ObjectNames
+{
+ public UserManagementObject(MBeanServerConnection mbsc)
+ {
+ super(mbsc);
+ }
+
+ public void setQueryString(String object, String name, String vhost)
+ {
+ querystring = "org.apache.qpid:type=UserManagement,*";
+ }
+
+}
diff --git a/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/objects/VirtualHostObject.java b/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/objects/VirtualHostObject.java
new file mode 100644
index 0000000000..77f8b66ac0
--- /dev/null
+++ b/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/commands/objects/VirtualHostObject.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.commands.objects;
+
+import javax.management.MBeanServerConnection;
+
+public class VirtualHostObject extends ObjectNames
+{
+
+ public VirtualHostObject(MBeanServerConnection mbsc)
+ {
+ super(mbsc);
+ }
+
+ public void setQueryString(String object, String name, String vhost)
+ {
+ if (name != null && vhost == null)
+ querystring = "org.apache.qpid:type=VirtualHost.VirtualHostManager,name=" + name + ",*";
+ else if (name != null && vhost != null)
+ querystring = "org.apache.qpid:type=VirtualHost.VirtualHostManager,VirtualHost=" + vhost + ",name=" + name
+ + ",*";
+ else if (name == null && vhost != null)
+ querystring = "org.apache.qpid:type=VirtualHost.VirtualHostManager,VirtualHost=" + vhost + ",*";
+ else
+ querystring = "org.apache.qpid:type=VirtualHost.VirtualHostManager,*";
+
+ }
+}
diff --git a/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/utils/CommandLineOption.java b/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/utils/CommandLineOption.java
new file mode 100644
index 0000000000..a443d6f789
--- /dev/null
+++ b/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/utils/CommandLineOption.java
@@ -0,0 +1,104 @@
+/*
+ *
+ * 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.utils;
+
+import java.util.ArrayList;
+
+public class CommandLineOption implements CommandLineOptionConstants
+{
+ private String type;
+ private ArrayList optionValues;
+
+ public CommandLineOption(String type, String[] values)
+ {
+ setOptionType(type);
+ ArrayList arrayList = new ArrayList(values.length);
+ for (int i = 0; i < values.length; i++)
+ {
+ arrayList.add(values[i]);
+ }
+ this.optionValues = arrayList;
+ }
+
+ private void setOptionType(String type)
+ {
+ // cater for the long options first
+ if (type.startsWith("--"))
+ {
+ type = type.replaceFirst("--", "");
+ }
+ if (type.startsWith("-"))
+ {
+ type = type.replaceFirst("-", "");
+ }
+
+ // we do not change the case of the option!
+
+ this.type = type;
+ }
+
+ /**
+ * @param type
+ */
+ public CommandLineOption(String type, ArrayList values)
+ {
+ setOptionType(type);
+
+ if (null != values)
+ {
+ this.optionValues = values;
+ }
+ }
+
+ /**
+ * @return Returns the type.
+ * @see CommandLineOptionConstants
+ */
+ public String getOptionType()
+ {
+ return type;
+ }
+
+ /**
+ * @return Returns the optionValues.
+ */
+ public String getOptionValue()
+ {
+ if ((optionValues != null) && (optionValues.size() > 0))
+ {
+ return (String) optionValues.get(0);
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ /**
+ * @return Returns the optionValues.
+ */
+ public ArrayList getOptionValues()
+ {
+ return optionValues;
+ }
+
+}
diff --git a/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/utils/CommandLineOptionConstants.java b/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/utils/CommandLineOptionConstants.java
new file mode 100644
index 0000000000..be82dbfcaa
--- /dev/null
+++ b/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/utils/CommandLineOptionConstants.java
@@ -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.
+ *
+ */
+
+package org.apache.qpid.utils;
+
+public interface CommandLineOptionConstants
+{
+ static interface JMXCommandLineOptionConstants
+ {
+ String HOST_OPTION = "h";
+ String PORT_OPTION = "p";
+ String INTERVAL_OPTION = "i";
+ String REPORT_OPTION = "r";
+ String USER_OPTION = "u";
+ String PASSWORD_OPTION = "w";
+
+ }
+
+}
diff --git a/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/utils/CommandLineOptionParser.java b/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/utils/CommandLineOptionParser.java
new file mode 100644
index 0000000000..fbf87bac01
--- /dev/null
+++ b/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/utils/CommandLineOptionParser.java
@@ -0,0 +1,231 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+package org.apache.qpid.utils;
+
+import java.util.Map;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.StringTokenizer;
+
+public class CommandLineOptionParser
+{
+ private static int STARTED = 0;
+ private static int NEW_OPTION = 1;
+ private static int SUB_PARAM_OF_OPTION = 2;
+
+ private Map commandlineoption;
+ private String commandname;
+
+ public CommandLineOptionParser(Map commandlineoptions)
+ {
+ this.commandlineoption = commandlineoptions;
+ }
+
+ public CommandLineOptionParser(String[] args)
+ {
+ /* check whether user just type the enter key */
+ this.commandlineoption = this.parse(args);
+
+ }
+
+ public CommandLineOptionParser(String[] args, String first)
+ {
+ this.commandname = first;
+ this.commandlineoption = this.parsefirst(args);
+ }
+
+ public Map parse(String[] args)
+ {
+ Map commandLineOptions = new HashMap();
+
+ if (0 == args.length)
+ {
+ return commandLineOptions;
+ }
+ else if (1 == args.length)
+ {
+ commandname = args[0];
+ return commandLineOptions;
+ }
+ /* when user is not giving the command line option with a "=" */
+ // if (!args[2].startsWith("-"))
+ // return commandLineOptions;
+ // State 0 means started
+ // State 1 means earlier one was a new -option
+ // State 2 means earlier one was a sub param of a -option
+ int state = STARTED;
+ ArrayList optionBundle = null;
+ String optionType = null;
+ CommandLineOption commandLineOption;
+ String newcommand = "";
+ String[] newargs;
+ int j;
+ if (args[1].compareTo("list") == 0 || args[1].compareTo("info") == 0 || args[1].compareTo("delete") == 0
+ || args[1].compareTo("move") == 0 || args[1].compareTo("view") == 0
+ || args[1].compareTo("viewcontent") == 0)
+ {
+ String object = args[0];
+ for (j = 0; j < (args.length - 1); j++)
+ {
+ newcommand = newcommand + args[j + 1] + " ";
+ }
+ newcommand = newcommand + "-o " + object;
+ newargs = newcommand.split(" ");
+ args = newargs;
+ }
+ else if (!args[1].startsWith("-")) // if user give command like list
+ // queue or something without minus
+ // argument
+ return commandLineOptions; // for the second wordxi
+
+ commandname = args[0];
+ for (int i = 0; i < args.length; i++)
+ {
+ if (args[i].startsWith("-"))
+ {
+ if (STARTED == state)
+ {
+ // fresh one
+ state = NEW_OPTION;
+ optionType = args[i];
+ }
+ else if (SUB_PARAM_OF_OPTION == state || NEW_OPTION == state)
+ {
+ // new one but old one should be saved
+ commandLineOption = new CommandLineOption(optionType, optionBundle);
+ commandLineOptions.put(commandLineOption.getOptionType(), commandLineOption);
+ state = NEW_OPTION;
+ optionType = args[i];
+ optionBundle = null;
+
+ }
+ }
+ else
+ {
+ if (NEW_OPTION == state)
+ {
+ optionBundle = new ArrayList();
+ optionBundle.add(args[i]);
+ state = SUB_PARAM_OF_OPTION;
+
+ }
+ else if (SUB_PARAM_OF_OPTION == state)
+ {
+ optionBundle.add(args[i]);
+ }
+
+ }
+ }
+ commandLineOption = new CommandLineOption(optionType, optionBundle);
+ commandLineOptions.put(commandLineOption.getOptionType(), commandLineOption);
+ return commandLineOptions;
+
+ }
+
+ public Map parsefirst(String[] args)
+ {
+ Map commandLineOptions = new HashMap();
+ if (0 == args.length)
+ {
+ return commandLineOptions;
+ }
+ else if (1 == args.length)
+ {
+ return commandLineOptions;
+ }
+ /* when user is not giving the command line option with a "=" */
+ // if (!args[2].startsWith("-"))
+ // return commandLineOptions;
+ // State 0 means started
+ // State 1 means earlier one was a new -option
+ // State 2 means earlier one was a sub param of a -option
+ int state = STARTED;
+ ArrayList optionBundle = null;
+ String optionType = null;
+ CommandLineOption commandLineOption;
+ String newcommand = "";
+ String[] newargs;
+ int j;
+
+ for (int i = 0; i < args.length; i++)
+ {
+ if (args[i].startsWith("-"))
+ {
+ if (STARTED == state)
+ {
+ // fresh one
+ state = NEW_OPTION;
+ optionType = args[i];
+ }
+ else if (SUB_PARAM_OF_OPTION == state || NEW_OPTION == state)
+ {
+ // new one but old one should be saved
+ commandLineOption = new CommandLineOption(optionType, optionBundle);
+ commandLineOptions.put(commandLineOption.getOptionType(), commandLineOption);
+ state = NEW_OPTION;
+ optionType = args[i];
+ optionBundle = null;
+
+ }
+ }
+ else
+ {
+ if (NEW_OPTION == state)
+ {
+ optionBundle = new ArrayList();
+ optionBundle.add(args[i]);
+ state = SUB_PARAM_OF_OPTION;
+
+ }
+ else if (SUB_PARAM_OF_OPTION == state)
+ {
+ optionBundle.add(args[i]);
+ }
+
+ }
+ }
+ commandLineOption = new CommandLineOption(optionType, optionBundle);
+ commandLineOptions.put(commandLineOption.getOptionType(), commandLineOption);
+ return commandLineOptions;
+
+ }
+
+ public Map getAlloptions()
+ {
+ return this.commandlineoption;
+ }
+
+ public String getcommandname()
+ {
+ return this.commandname;
+ }
+
+ private static String removeSpaces(String s)
+ {
+ StringTokenizer st = new StringTokenizer(s, " ", false);
+ String t = "";
+ while (st.hasMoreElements())
+ t += st.nextElement();
+ return t;
+ }
+
+}
diff --git a/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/utils/JMXConfigProperty.java b/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/utils/JMXConfigProperty.java
new file mode 100644
index 0000000000..55240054a9
--- /dev/null
+++ b/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/utils/JMXConfigProperty.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.utils;
+
+public class JMXConfigProperty
+{
+
+ private static final String DEFAULT_HOST_NAME = "localhost";
+ private static final String DEFAULT_PORT = "8999";
+ private static final String DEFAULT_INTERVAL = "4000";
+}
diff --git a/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/utils/JMXConfiguration.java b/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/utils/JMXConfiguration.java
new file mode 100644
index 0000000000..76aab11e25
--- /dev/null
+++ b/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/utils/JMXConfiguration.java
@@ -0,0 +1,182 @@
+/*
+ *
+ * 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.utils;
+
+import java.util.Map;
+
+public class JMXConfiguration
+{
+ private String hostname = "localhost";
+ private String port = "8999";
+ private String interval = "40000";
+ private String outputpath = ".";
+ private String report_file = "report.output";
+ private boolean isreport_mode = false;
+ private String username = null;
+ private String password = null;
+
+ public JMXConfiguration(Map map)
+ {
+ if (checkoptionsetting(CommandLineOptionConstants.JMXCommandLineOptionConstants.HOST_OPTION, map))
+ {
+ this.hostname = optionchecker(CommandLineOptionConstants.JMXCommandLineOptionConstants.HOST_OPTION, map);
+ }
+ if (checkoptionsetting(CommandLineOptionConstants.JMXCommandLineOptionConstants.PORT_OPTION, map))
+ {
+ this.port = optionchecker(CommandLineOptionConstants.JMXCommandLineOptionConstants.PORT_OPTION, map);
+ }
+ if (checkoptionsetting(CommandLineOptionConstants.JMXCommandLineOptionConstants.REPORT_OPTION, map))
+ {
+
+ this.report_file = optionchecker(CommandLineOptionConstants.JMXCommandLineOptionConstants.REPORT_OPTION,
+ map);
+ }
+ if (checkoptionsetting(CommandLineOptionConstants.JMXCommandLineOptionConstants.USER_OPTION, map))
+ {
+
+ this.setUsername(optionchecker(CommandLineOptionConstants.JMXCommandLineOptionConstants.USER_OPTION, map));
+ }
+
+ if (checkoptionsetting(CommandLineOptionConstants.JMXCommandLineOptionConstants.PASSWORD_OPTION, map))
+ {
+ this.setPassword(optionchecker(CommandLineOptionConstants.JMXCommandLineOptionConstants.PASSWORD_OPTION,
+ map));
+ }
+
+ }
+
+ public void sethostname(String hostname)
+ {
+ this.hostname = hostname;
+ }
+
+ public void setport(String port)
+ {
+ this.port = port;
+ }
+
+ public void setinterval(String interval)
+ {
+ this.interval = interval;
+ }
+
+ public void setoutputpath(String output)
+ {
+ this.outputpath = output;
+ }
+
+ public String gethostname()
+ {
+ return this.hostname;
+ }
+
+ public String getport()
+ {
+ return this.port;
+ }
+
+ public String getinterval()
+ {
+ return this.interval;
+ }
+
+ public String getoutputpath()
+ {
+ return this.outputpath;
+ }
+
+ public CommandLineOption loadoption(String option, Map options)
+ {
+ CommandLineOption op = null;
+ if (option != null)
+ {
+ op = (CommandLineOption) options.get(option);
+
+ }
+ return op;
+
+ }
+
+ public void setreportfile(String reportfile)
+ {
+ this.report_file = reportfile;
+ this.isreport_mode = true;
+
+ }
+
+ public boolean isreportmode()
+ {
+ return this.isreport_mode;
+ }
+
+ public String getreportfile()
+ {
+ return this.report_file;
+ }
+
+ public String optionchecker(String option_letter, Map map)
+ {
+
+ if (map == null)
+ return null;
+ CommandLineOption option = (CommandLineOption) map.get(option_letter);
+ if (option == null)
+ return null;
+ String value = option.getOptionValue();
+ return value;
+ }
+
+ public boolean checkoptionsetting(String option_letter, Map map)
+ {
+ if (map == null)
+ return false;
+ CommandLineOption option = (CommandLineOption) map.get(option_letter);
+ if (option == null)
+ return false;
+ String value = option.getOptionType();
+
+ if (value != null)
+ return true;
+ else
+ return false;
+ }
+
+ public void setUsername(String username)
+ {
+ this.username = username;
+ }
+
+ public String getUsername()
+ {
+ return username;
+ }
+
+ public void setPassword(String password)
+ {
+ this.password = password;
+ }
+
+ public String getPassword()
+ {
+ return password;
+ }
+
+}
diff --git a/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/utils/JMXinfo.java b/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/utils/JMXinfo.java
new file mode 100644
index 0000000000..09de4a248f
--- /dev/null
+++ b/qpid/java/management/tools/qpid-cli/src/org/apache/qpid/utils/JMXinfo.java
@@ -0,0 +1,53 @@
+/*
+ *
+ * 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.utils;
+
+import javax.management.remote.JMXConnector;
+import javax.management.MBeanServerConnection;
+
+public class JMXinfo
+{
+ private JMXConnector jmxconnector;
+ private CommandLineOptionParser input;
+ private MBeanServerConnection mbserverconnector;
+
+ public JMXinfo(JMXConnector jmxc, CommandLineOptionParser input, MBeanServerConnection mbsc)
+ {
+ this.jmxconnector = jmxc;
+ this.input = input;
+ this.mbserverconnector = mbsc;
+ }
+
+ public JMXConnector getjmxconnectot()
+ {
+ return jmxconnector;
+ }
+
+ public CommandLineOptionParser getCommandLineOptionParser()
+ {
+ return input;
+ }
+
+ public MBeanServerConnection getmbserverconnector()
+ {
+ return mbserverconnector;
+ }
+}
diff --git a/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/AllTest.java b/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/AllTest.java
new file mode 100644
index 0000000000..d9758245cd
--- /dev/null
+++ b/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/AllTest.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;
+
+import org.junit.runner.RunWith;
+import org.junit.runners.Suite;
+import org.apache.qpid.commands.*;
+import org.apache.qpid.commands.objects.*;
+import org.apache.qpid.utils.TestCommandLineOption;
+import org.apache.qpid.utils.TestCommandLineOptionParser;
+import org.apache.qpid.utils.TestJMXConfiguration;
+
+@RunWith(Suite.class)
+@Suite.SuiteClasses( { TestCommand.class, TestCommandExecutionEngine.class, TestCommandLineOption.class,
+ TestCommandLineOptionParser.class, TestConnector.class, TestJMXConfiguration.class, TestAllObject.class,
+ TestConnectionObject.class, TestExchangeObject.class, TestQueueObject.class, TestVirtualHostObject.class,
+ TestUserManagementObject.class, TestCommanddelete.class, TestCommandlist.class, TestCommandinfo.class,
+ TestCommandmove.class, TestCommandview.class, TestCommandviewcontent.class, TestCommandLineInterpreter.class
+
+})
+public class AllTest
+{
+}
diff --git a/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/ConnectionConstants.java b/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/ConnectionConstants.java
new file mode 100644
index 0000000000..90163460ce
--- /dev/null
+++ b/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/ConnectionConstants.java
@@ -0,0 +1,30 @@
+/*
+ *
+ * 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;
+
+public interface ConnectionConstants
+{
+ String BROKER_HOSTNAME = "localhost";
+ String BROKER_PORT = "8999";
+ String USERNAME = "guest";
+ String PASSWORD = "guest";
+}
diff --git a/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/TestCommandExecutionEngine.java b/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/TestCommandExecutionEngine.java
new file mode 100644
index 0000000000..6889e8faad
--- /dev/null
+++ b/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/TestCommandExecutionEngine.java
@@ -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.
+ *
+ */
+package org.apache.qpid;
+
+import java.io.IOException;
+
+import org.apache.qpid.utils.CommandLineOptionParser;
+import org.apache.qpid.utils.JMXinfo;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+public class TestCommandExecutionEngine
+{
+ String line;
+ String[] command;
+ CommandLineOptionParser commandlineoptionparser;
+ JMXinfo info;
+ CommandExecutionEngine engine;
+ Connector connector;
+
+ @Before
+ public void setup() throws Exception
+ {
+
+ connector = ConnectorFactory.getConnector(ConnectionConstants.BROKER_HOSTNAME, ConnectionConstants.BROKER_PORT,
+ ConnectionConstants.USERNAME, ConnectionConstants.PASSWORD);
+
+ }
+
+ @Test
+ public void TestCommandSelector() throws Exception
+ {
+ line = "list -o queue";
+ command = line.split(" ");
+ commandlineoptionparser = new CommandLineOptionParser(command);
+ info = new JMXinfo(connector.getConnector(), commandlineoptionparser, connector.getMBeanServerConnection());
+ engine = new CommandExecutionEngine(info);
+ Assert.assertEquals(engine.CommandSelector(), true);
+ }
+
+ @After
+ public void cleanup()
+ {
+ try
+ {
+ connector.getConnector().close();
+ }
+ catch (IOException e)
+ {
+ e.printStackTrace();
+ }
+ }
+}
diff --git a/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/TestCommandLineInterpreter.java b/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/TestCommandLineInterpreter.java
new file mode 100644
index 0000000000..07344598bf
--- /dev/null
+++ b/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/TestCommandLineInterpreter.java
@@ -0,0 +1,80 @@
+/*
+ *
+ * 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;
+
+import javax.management.MBeanServerConnection;
+import javax.management.remote.JMXConnector;
+
+import org.apache.qpid.utils.CommandLineOptionParser;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+public class TestCommandLineInterpreter
+{
+
+ // CommandLineInterpreter test = new CommandLineInterpreter();
+ /*
+ * In this class there are only methodes which are displaying data on
+ * console so no test can be written
+ */
+ String command = "-h " + ConnectionConstants.BROKER_HOSTNAME + " -p " + ConnectionConstants.BROKER_PORT
+ + " info -o queue -n ping -v test";
+ Connector conn = null;
+ JMXConnector jmxc = null;
+ MBeanServerConnection mbsc = null;
+ CommandLineOptionParser parser = null;
+
+ String[] args = null;
+
+ @Before
+ public void startup() throws Exception
+ {
+ args = command.split(" ");
+ // System.out.println(args[0]);
+ conn = ConnectorFactory.getConnector(ConnectionConstants.BROKER_HOSTNAME, ConnectionConstants.BROKER_PORT,
+ ConnectionConstants.USERNAME, ConnectionConstants.PASSWORD);
+ jmxc = conn.getConnector();
+ mbsc = conn.getMBeanServerConnection();
+ parser = new CommandLineOptionParser(args, args[0]);
+
+ }
+
+ @Test
+ public void TestSetQueryString() throws Exception
+ {
+ CommandLineInterpreter.oneshotmode(args, parser, jmxc, mbsc);
+ Assert.assertEquals(args[0], "info");
+ Assert.assertEquals(args[1], "-o");
+ Assert.assertEquals(args[2], "queue");
+ Assert.assertEquals(args[3], "-n");
+ Assert.assertEquals(args[4], "ping");
+ Assert.assertEquals(args[5], "-v");
+ Assert.assertEquals(args[6], "test");
+ }
+
+ @After
+ public void cleanup()
+ {
+
+ }
+}
diff --git a/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/TestConnector.java b/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/TestConnector.java
new file mode 100644
index 0000000000..ea450b5caa
--- /dev/null
+++ b/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/TestConnector.java
@@ -0,0 +1,79 @@
+/*
+ *
+ * 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;
+
+import java.io.IOException;
+
+import javax.management.MBeanServerConnection;
+import javax.management.remote.JMXConnector;
+import javax.management.remote.JMXServiceURL;
+
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+public class TestConnector
+{
+ Connector test;
+ JMXServiceURL svc_url;
+ JMXConnector connector;
+ MBeanServerConnection mbsc;
+
+ @Before
+ public void setup() throws Exception
+ {
+ test = ConnectorFactory.getConnector(ConnectionConstants.BROKER_HOSTNAME, ConnectionConstants.BROKER_PORT,
+ ConnectionConstants.USERNAME, ConnectionConstants.PASSWORD);
+ String url = "service:jmx:rmi:///jndi/rmi://localhost:8999/jmxrmi";
+
+ }
+
+ @Test
+ public void testGetConnector()
+ {
+ Assert.assertEquals(test.getConnector(), test.getConnector());
+ }
+
+ @Test
+ public void testGetMBeanServerConnection()
+ {
+ Assert.assertEquals(test.getMBeanServerConnection(), test.getMBeanServerConnection());
+ }
+
+ @After
+ public void cleanup()
+ {
+ try
+ {
+
+ test.getConnector().close();
+ test = null;
+ }
+ catch (IOException e)
+ {
+ e.printStackTrace(); // To change body of catch statement use File |
+ // Settings | File Templates.
+ }
+ test = null;
+ }
+
+}
diff --git a/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/TestReportGenerator.java b/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/TestReportGenerator.java
new file mode 100644
index 0000000000..c14f4bb1bb
--- /dev/null
+++ b/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/TestReportGenerator.java
@@ -0,0 +1,26 @@
+/*
+ *
+ * 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;
+
+public class TestReportGenerator
+{
+
+}
diff --git a/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/commands/TestCommand.java b/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/commands/TestCommand.java
new file mode 100644
index 0000000000..085d7220e9
--- /dev/null
+++ b/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/commands/TestCommand.java
@@ -0,0 +1,79 @@
+/*
+ *
+ * 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.commands;
+
+import javax.management.MBeanServerConnection;
+
+import org.apache.qpid.Command;
+import org.apache.qpid.ConnectionConstants;
+import org.apache.qpid.Connector;
+import org.apache.qpid.ConnectorFactory;
+import org.apache.qpid.utils.CommandLineOptionParser;
+import org.apache.qpid.utils.JMXinfo;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+public class TestCommand
+{
+ String command = "list -o queue";
+ String[] list;
+ Connector test;
+ MBeanServerConnection mbsc;
+ JMXinfo info;
+ CommandLineOptionParser parser;
+ Command cmd;
+
+ @Before
+ public void setup() throws Exception
+ {
+ list = command.split(" ");
+ parser = new CommandLineOptionParser(list);
+ test = ConnectorFactory.getConnector(ConnectionConstants.BROKER_HOSTNAME, ConnectionConstants.BROKER_PORT,
+ ConnectionConstants.USERNAME, ConnectionConstants.PASSWORD);
+ info = new JMXinfo(test.getConnector(), parser, test.getMBeanServerConnection());
+ cmd = new Commandinfo(info);
+
+ }
+
+ @Test
+ public void TestOptionChecker()
+ {
+ Assert.assertEquals(cmd.optionchecker("o"), "queue");
+ }
+
+ @Test
+ public void TestCheckOptionSetting()
+ {
+ Assert.assertEquals(cmd.checkoptionsetting("o"), true);
+ Assert.assertEquals(cmd.checkoptionsetting("p"), false);
+ }
+
+ @After
+ public void cleanup()
+ {
+ parser = null;
+ test = null;
+ info = null;
+ cmd = null;
+ }
+}
diff --git a/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/commands/TestCommanddelete.java b/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/commands/TestCommanddelete.java
new file mode 100644
index 0000000000..60249c6940
--- /dev/null
+++ b/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/commands/TestCommanddelete.java
@@ -0,0 +1,79 @@
+/*
+ *
+ * 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.commands;
+
+import org.junit.After;
+import org.junit.Test;
+import org.junit.Before;
+import org.junit.Assert;
+import org.apache.qpid.ConnectorFactory;
+import org.apache.qpid.Connector;
+import org.apache.qpid.ConnectionConstants;
+import org.apache.qpid.utils.JMXinfo;
+import org.apache.qpid.utils.CommandLineOptionParser;
+
+import javax.management.remote.JMXConnector;
+import javax.management.MBeanServerConnection;
+
+public class TestCommanddelete
+{
+ JMXinfo info = null;
+ String command = "delete -o queue -n ping -v test -t 1";
+ Commanddelete delete = null;
+ Connector conn;
+
+ @Before
+ public void startup() throws Exception
+ {
+ conn = ConnectorFactory.getConnector(ConnectionConstants.BROKER_HOSTNAME, ConnectionConstants.BROKER_PORT,
+ ConnectionConstants.USERNAME, ConnectionConstants.PASSWORD);
+ JMXConnector jmxc = conn.getConnector();
+ MBeanServerConnection mbsc = conn.getMBeanServerConnection();
+ CommandLineOptionParser parser = new CommandLineOptionParser(command.split(" "));
+ info = new JMXinfo(jmxc, parser, mbsc);
+ delete = new Commanddelete(info);
+
+ }
+
+ @Test
+ public void TestSetQueryString()
+ {
+ delete.execute();
+ Assert.assertEquals(delete.getObject(), "queue");
+ Assert.assertEquals(delete.getVirtualhost(), "test");
+ Assert.assertEquals(delete.getName(), "ping");
+ Assert.assertEquals(delete.getnumber(), 1);
+
+ }
+
+ @After
+ public void cleanup()
+ {
+ try
+ {
+ conn.getConnector().close();
+ }
+ catch (Exception ex)
+ {
+ ex.printStackTrace();
+ }
+ }
+}
diff --git a/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/commands/TestCommandinfo.java b/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/commands/TestCommandinfo.java
new file mode 100644
index 0000000000..24263eea73
--- /dev/null
+++ b/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/commands/TestCommandinfo.java
@@ -0,0 +1,77 @@
+/*
+ *
+ * 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.commands;
+
+import org.apache.qpid.utils.JMXinfo;
+import org.apache.qpid.utils.CommandLineOptionParser;
+import org.apache.qpid.Connector;
+import org.apache.qpid.ConnectorFactory;
+import org.apache.qpid.ConnectionConstants;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.Assert;
+import org.junit.After;
+
+import javax.management.remote.JMXConnector;
+import javax.management.MBeanServerConnection;
+
+public class TestCommandinfo
+{
+ JMXinfo info = null;
+ String command = "info -o queue -n ping -v test";
+ CommandImpl infocommand = null;
+ Connector conn = null;
+
+ @Before
+ public void startup() throws Exception
+ {
+ conn = ConnectorFactory.getConnector(ConnectionConstants.BROKER_HOSTNAME, ConnectionConstants.BROKER_PORT,
+ ConnectionConstants.USERNAME, ConnectionConstants.PASSWORD);
+ JMXConnector jmxc = conn.getConnector();
+ MBeanServerConnection mbsc = conn.getMBeanServerConnection();
+ CommandLineOptionParser parser = new CommandLineOptionParser(command.split(" "));
+ info = new JMXinfo(jmxc, parser, mbsc);
+ infocommand = new Commandinfo(info);
+
+ }
+
+ @Test
+ public void TestSetQueryString()
+ {
+ infocommand.execute();
+ Assert.assertEquals(infocommand.getObject(), "queue");
+ Assert.assertEquals(infocommand.getVirtualhost(), "test");
+ Assert.assertEquals(infocommand.getName(), "ping");
+ }
+
+ @After
+ public void cleanup()
+ {
+ try
+ {
+ conn.getConnector().close();
+ }
+ catch (Exception ex)
+ {
+ ex.printStackTrace();
+ }
+ }
+}
diff --git a/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/commands/TestCommandlist.java b/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/commands/TestCommandlist.java
new file mode 100644
index 0000000000..ac759889fd
--- /dev/null
+++ b/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/commands/TestCommandlist.java
@@ -0,0 +1,82 @@
+/*
+ *
+ * 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.commands;
+
+import javax.management.MBeanServerConnection;
+import javax.management.remote.JMXConnector;
+
+import org.apache.qpid.ConnectionConstants;
+import org.apache.qpid.Connector;
+import org.apache.qpid.ConnectorFactory;
+import org.apache.qpid.utils.CommandLineOptionParser;
+import org.apache.qpid.utils.JMXinfo;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+public class TestCommandlist
+{
+ /*
+ * All the methods in Commandlist doesn't have any arguments and no return
+ * type.
+ */
+ JMXinfo info = null;
+ String command = "list -o queue -n ping -v test";
+ Commandlist list = null;
+ Connector conn = null;
+
+ @Before
+ public void startup() throws Exception
+ {
+ conn = ConnectorFactory.getConnector(ConnectionConstants.BROKER_HOSTNAME, ConnectionConstants.BROKER_PORT,
+ ConnectionConstants.USERNAME, ConnectionConstants.PASSWORD);
+ JMXConnector jmxc = conn.getConnector();
+ MBeanServerConnection mbsc = conn.getMBeanServerConnection();
+ CommandLineOptionParser parser = new CommandLineOptionParser(command.split(" "));
+ info = new JMXinfo(jmxc, parser, mbsc);
+ list = new Commandlist(info);
+
+ }
+
+ @Test
+ public void TestSetQueryString()
+ {
+ list.execute();
+ Assert.assertEquals(list.getObject(), "queue");
+ Assert.assertEquals(list.getVirtualhost(), "test");
+ Assert.assertEquals(list.getName(), "ping");
+ }
+
+ @After
+ public void cleanup()
+ {
+ try
+ {
+ conn.getConnector().close();
+ }
+ catch (Exception ex)
+ {
+ ex.printStackTrace();
+ }
+ }
+
+}
diff --git a/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/commands/TestCommandmove.java b/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/commands/TestCommandmove.java
new file mode 100644
index 0000000000..3ff7890662
--- /dev/null
+++ b/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/commands/TestCommandmove.java
@@ -0,0 +1,80 @@
+/*
+ *
+ * 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.commands;
+
+import org.apache.qpid.ConnectionConstants;
+import org.apache.qpid.Connector;
+import org.apache.qpid.ConnectorFactory;
+import org.apache.qpid.utils.CommandLineOptionParser;
+import org.apache.qpid.utils.JMXinfo;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.After;
+import org.junit.Assert;
+
+import javax.management.remote.JMXConnector;
+import javax.management.MBeanServerConnection;
+
+public class TestCommandmove
+{
+ JMXinfo info = null;
+ String command = "move -o queue -n1 ping -v1 test -n2 message_queue -fmid 10 -tmid 12";
+ Commandmove move = null;
+ Connector conn = null;
+
+ @Before
+ public void startup() throws Exception
+ {
+ conn = ConnectorFactory.getConnector(ConnectionConstants.BROKER_HOSTNAME, ConnectionConstants.BROKER_PORT,
+ ConnectionConstants.USERNAME, ConnectionConstants.PASSWORD);
+ JMXConnector jmxc = conn.getConnector();
+ MBeanServerConnection mbsc = conn.getMBeanServerConnection();
+ CommandLineOptionParser parser = new CommandLineOptionParser(command.split(" "));
+ info = new JMXinfo(jmxc, parser, mbsc);
+ move = new Commandmove(info);
+
+ }
+
+ @Test
+ public void TestSetQueryString()
+ {
+ move.execute();
+ Assert.assertEquals(move.getObject(), "queue");
+ Assert.assertEquals(move.getVirtualhost(), "test");
+ Assert.assertEquals(move.getname1(), "ping");
+ Assert.assertEquals(move.getname2(), "message_queue");
+ Assert.assertEquals(move.getfmid(), 10);
+ Assert.assertEquals(move.gettmid(), 12);
+ }
+
+ @After
+ public void cleanup()
+ {
+ try
+ {
+ conn.getConnector().close();
+ }
+ catch (Exception ex)
+ {
+ ex.printStackTrace();
+ }
+ }
+}
diff --git a/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/commands/TestCommandview.java b/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/commands/TestCommandview.java
new file mode 100644
index 0000000000..f46b8626b8
--- /dev/null
+++ b/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/commands/TestCommandview.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.commands;
+
+import org.apache.qpid.ConnectionConstants;
+import org.apache.qpid.ConnectorFactory;
+import org.apache.qpid.Connector;
+import org.apache.qpid.utils.CommandLineOptionParser;
+import org.apache.qpid.utils.JMXinfo;
+import org.junit.Test;
+import org.junit.Before;
+import org.junit.After;
+import org.junit.Assert;
+
+import javax.management.MBeanServerConnection;
+import javax.management.remote.JMXConnector;
+
+public class TestCommandview
+{
+ JMXinfo info = null;
+ String command = "view -o queue -n ping -v test -t 10";
+ Commandview view = null;
+ Connector conn = null;
+
+ @Before
+ public void startup() throws Exception
+ {
+ conn = ConnectorFactory.getConnector(ConnectionConstants.BROKER_HOSTNAME, ConnectionConstants.BROKER_PORT,
+ ConnectionConstants.USERNAME, ConnectionConstants.PASSWORD);
+ JMXConnector jmxc = conn.getConnector();
+ MBeanServerConnection mbsc = conn.getMBeanServerConnection();
+ CommandLineOptionParser parser = new CommandLineOptionParser(command.split(" "));
+ info = new JMXinfo(jmxc, parser, mbsc);
+ view = new Commandview(info);
+ }
+
+ @Test
+ public void TestSetQueryString()
+ {
+ view.execute();
+ Assert.assertEquals(view.getObject(), "queue");
+ Assert.assertEquals(view.getVirtualhost(), "test");
+ Assert.assertEquals(view.getName(), "ping");
+ Assert.assertEquals(view.getnumber(), 10);
+
+ }
+
+ @After
+ public void cleanup()
+ {
+ try
+ {
+ conn.getConnector().close();
+ }
+ catch (Exception ex)
+ {
+ ex.printStackTrace();
+ }
+ }
+}
diff --git a/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/commands/TestCommandviewcontent.java b/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/commands/TestCommandviewcontent.java
new file mode 100644
index 0000000000..f4a8f22aff
--- /dev/null
+++ b/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/commands/TestCommandviewcontent.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.commands;
+
+import org.apache.qpid.utils.JMXinfo;
+import org.apache.qpid.utils.CommandLineOptionParser;
+import org.apache.qpid.Connector;
+import org.apache.qpid.ConnectorFactory;
+import org.apache.qpid.ConnectionConstants;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.After;
+import org.junit.Assert;
+
+import javax.management.remote.JMXConnector;
+import javax.management.MBeanServerConnection;
+
+public class TestCommandviewcontent
+{
+ JMXinfo info = null;
+ String command = "viewcontent -o queue -n ping -v test -id 10";
+ Commandviewcontent viewcontent = null;
+ Connector conn = null;
+
+ @Before
+ public void startup() throws Exception
+ {
+ conn = ConnectorFactory.getConnector(ConnectionConstants.BROKER_HOSTNAME, ConnectionConstants.BROKER_PORT,
+ ConnectionConstants.USERNAME, ConnectionConstants.PASSWORD);
+ JMXConnector jmxc = conn.getConnector();
+ MBeanServerConnection mbsc = conn.getMBeanServerConnection();
+ CommandLineOptionParser parser = new CommandLineOptionParser(command.split(" "));
+ info = new JMXinfo(jmxc, parser, mbsc);
+ viewcontent = new Commandviewcontent(info);
+
+ }
+
+ @Test
+ public void TestSetQueryString()
+ {
+ viewcontent.execute();
+ Assert.assertEquals(viewcontent.getObject(), "queue");
+ Assert.assertEquals(viewcontent.getnumber(), 10);
+ Assert.assertEquals(viewcontent.getName(), "ping");
+ Assert.assertEquals(viewcontent.getVirtualhost(), "test");
+ }
+
+ @After
+ public void cleanup()
+ {
+ try
+ {
+ conn.getConnector().close();
+ }
+ catch (Exception ex)
+ {
+ ex.printStackTrace();
+ }
+ }
+}
diff --git a/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/commands/objects/TestAllObject.java b/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/commands/objects/TestAllObject.java
new file mode 100644
index 0000000000..af993e9205
--- /dev/null
+++ b/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/commands/objects/TestAllObject.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.commands.objects;
+
+import javax.management.MBeanServerConnection;
+
+import org.apache.qpid.ConnectionConstants;
+import org.apache.qpid.Connector;
+import org.apache.qpid.ConnectorFactory;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+public class TestAllObject {
+ Connector conn;
+ MBeanServerConnection mbsc;
+ AllObjects test;
+ String test1,test2;
+
+ @Before
+ public void startup() throws Exception
+ {
+ conn = ConnectorFactory.getConnector(ConnectionConstants.BROKER_HOSTNAME,ConnectionConstants.BROKER_PORT, ConnectionConstants.USERNAME, ConnectionConstants.PASSWORD);
+ mbsc = conn.getMBeanServerConnection();
+ test = new AllObjects(mbsc);
+ test1 = "empty input1";
+ test2 = "empty input2";
+
+
+ }
+ @Test
+ public void TestSetQueryString()
+ {
+ test.setQueryString(test1,test2);
+ Assert.assertEquals(test.querystring,"org.apache.qpid:*");
+
+ }
+
+ @After
+ public void cleanup()
+ {
+ try{
+ conn.getConnector().close();
+ }catch(Exception ex)
+ {
+ ex.printStackTrace();
+ }
+
+ }
+}
diff --git a/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/commands/objects/TestConnectionObject.java b/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/commands/objects/TestConnectionObject.java
new file mode 100644
index 0000000000..f91a519108
--- /dev/null
+++ b/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/commands/objects/TestConnectionObject.java
@@ -0,0 +1,83 @@
+/*
+ *
+ * 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.commands.objects;
+
+import javax.management.MBeanServerConnection;
+
+import org.apache.qpid.ConnectionConstants;
+import org.apache.qpid.Connector;
+import org.apache.qpid.ConnectorFactory;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+public class TestConnectionObject
+{
+ Connector conn;
+ MBeanServerConnection mbsc;
+ ConnectionObject test;
+ String test1, test2, test3;
+
+ @Before
+ public void startup() throws Exception
+ {
+ conn = ConnectorFactory.getConnector(ConnectionConstants.BROKER_HOSTNAME, ConnectionConstants.BROKER_PORT,
+ ConnectionConstants.USERNAME, ConnectionConstants.PASSWORD);
+ mbsc = conn.getMBeanServerConnection();
+ test = new ConnectionObject(mbsc);
+ test1 = "ping";
+ test2 = "test";
+ test3 = "object";
+
+ }
+
+ @Test
+ public void TestSetQueryString()
+ {
+ test.setQueryString(test3, test1, null);
+ Assert.assertEquals(test.querystring, "org.apache.qpid:type=Connection,name=ping,*");
+ test.querystring = null;
+ test.setQueryString(test3, null, test2);
+ Assert.assertEquals(test.querystring, "org.apache.qpid:type=Connection,VirtualHost=test,*");
+ test.querystring = null;
+ test.setQueryString(test3, test1, test2);
+ Assert.assertEquals(test.querystring, "org.apache.qpid:type=Connection,VirtualHost=test,name=ping,*");
+ test.querystring = null;
+ test.setQueryString(test3, null, null);
+ Assert.assertEquals(test.querystring, "org.apache.qpid:type=Connection,*");
+
+ }
+
+ @After
+ public void cleanup()
+ {
+ try
+ {
+ conn.getConnector().close();
+ }
+ catch (Exception ex)
+ {
+ ex.printStackTrace();
+ }
+
+ }
+}
diff --git a/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/commands/objects/TestExchangeObject.java b/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/commands/objects/TestExchangeObject.java
new file mode 100644
index 0000000000..5ffbe9854f
--- /dev/null
+++ b/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/commands/objects/TestExchangeObject.java
@@ -0,0 +1,83 @@
+/*
+ *
+ * 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.commands.objects;
+
+import javax.management.MBeanServerConnection;
+
+import org.apache.qpid.ConnectionConstants;
+import org.apache.qpid.Connector;
+import org.apache.qpid.ConnectorFactory;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+public class TestExchangeObject
+{
+ Connector conn;
+ MBeanServerConnection mbsc;
+ ExchangeObject test;
+ String test1, test2, test3;
+
+ @Before
+ public void startup() throws Exception
+ {
+ conn = ConnectorFactory.getConnector(ConnectionConstants.BROKER_HOSTNAME, ConnectionConstants.BROKER_PORT,
+ ConnectionConstants.USERNAME, ConnectionConstants.PASSWORD);
+ mbsc = conn.getMBeanServerConnection();
+ test = new ExchangeObject(mbsc);
+ test1 = "ping";
+ test2 = "test";
+ test3 = "object";
+
+ }
+
+ @Test
+ public void TestSetQueryString()
+ {
+ test.setQueryString(test3, test1, null);
+ // System.out.println(test.querystring);
+ // System.out.println("org.apache.qpid:type=VitualHost.Exchange,name=ping,*");
+ Assert.assertEquals(test.querystring, "org.apache.qpid:type=VirtualHost.Exchange,name=ping,*");
+ test.querystring = null;
+ test.setQueryString(test3, null, test2);
+ Assert.assertEquals(test.querystring, "org.apache.qpid:type=VirtualHost.Exchange,VirtualHost=test,*");
+ test.querystring = null;
+ test.setQueryString(test3, test1, test2);
+ Assert.assertEquals(test.querystring, "org.apache.qpid:type=VirtualHost.Exchange,VirtualHost=test,name=ping,*");
+ test.querystring = null;
+ test.setQueryString(test3, null, null);
+ }
+
+ @After
+ public void cleanup()
+ {
+ try
+ {
+ conn.getConnector().close();
+ }
+ catch (Exception ex)
+ {
+ ex.printStackTrace();
+ }
+
+ }
+}
diff --git a/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/commands/objects/TestObjectNames.java b/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/commands/objects/TestObjectNames.java
new file mode 100644
index 0000000000..600c567368
--- /dev/null
+++ b/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/commands/objects/TestObjectNames.java
@@ -0,0 +1,26 @@
+/*
+ *
+ * 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.commands.objects;
+
+public class TestObjectNames
+{
+
+}
diff --git a/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/commands/objects/TestQueueObject.java b/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/commands/objects/TestQueueObject.java
new file mode 100644
index 0000000000..fb7f42e1ae
--- /dev/null
+++ b/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/commands/objects/TestQueueObject.java
@@ -0,0 +1,83 @@
+/*
+ *
+ * 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.commands.objects;
+
+import javax.management.MBeanServerConnection;
+
+import org.apache.qpid.ConnectionConstants;
+import org.apache.qpid.Connector;
+import org.apache.qpid.ConnectorFactory;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+public class TestQueueObject
+{
+ Connector conn;
+ MBeanServerConnection mbsc;
+ QueueObject test;
+ String test1, test2, test3;
+
+ @Before
+ public void startup() throws Exception
+ {
+ conn = ConnectorFactory.getConnector(ConnectionConstants.BROKER_HOSTNAME, ConnectionConstants.BROKER_PORT,
+ ConnectionConstants.USERNAME, ConnectionConstants.PASSWORD);
+ mbsc = conn.getMBeanServerConnection();
+ test = new QueueObject(mbsc);
+ test1 = "ping";
+ test2 = "test";
+ test3 = "object";
+
+ }
+
+ @Test
+ public void TestSetQueryString()
+ {
+ test.setQueryString(test3, test1, null);
+ Assert.assertEquals(test.querystring, "org.apache.qpid:type=VirtualHost.Queue,name=ping,*");
+ test.querystring = null;
+ test.setQueryString(test3, null, test2);
+ Assert.assertEquals(test.querystring, "org.apache.qpid:type=VirtualHost.Queue,VirtualHost=test,*");
+ test.querystring = null;
+ test.setQueryString(test3, test1, test2);
+ Assert.assertEquals(test.querystring, "org.apache.qpid:type=VirtualHost.Queue,VirtualHost=test,name=ping,*");
+ test.querystring = null;
+ test.setQueryString(test3, null, null);
+ Assert.assertEquals(test.querystring, "org.apache.qpid:type=VirtualHost.Queue,*");
+
+ }
+
+ @After
+ public void cleanup()
+ {
+ try
+ {
+ conn.getConnector().close();
+ }
+ catch (Exception ex)
+ {
+ ex.printStackTrace();
+ }
+
+ }
+}
diff --git a/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/commands/objects/TestUserManagementObject.java b/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/commands/objects/TestUserManagementObject.java
new file mode 100644
index 0000000000..863bf62311
--- /dev/null
+++ b/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/commands/objects/TestUserManagementObject.java
@@ -0,0 +1,74 @@
+/*
+ *
+ * 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.commands.objects;
+
+import javax.management.MBeanServerConnection;
+
+import org.apache.qpid.ConnectionConstants;
+import org.apache.qpid.Connector;
+import org.apache.qpid.ConnectorFactory;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+public class TestUserManagementObject
+{
+ Connector conn;
+ MBeanServerConnection mbsc;
+ UserManagementObject test;
+ String test1, test2, test3;
+
+ @Before
+ public void startup() throws Exception
+ {
+ conn = ConnectorFactory.getConnector(ConnectionConstants.BROKER_HOSTNAME, ConnectionConstants.BROKER_PORT,
+ ConnectionConstants.USERNAME, ConnectionConstants.PASSWORD);
+ mbsc = conn.getMBeanServerConnection();
+ test = new UserManagementObject(mbsc);
+ test1 = "ping";
+ test2 = "test";
+ test3 = "object";
+
+ }
+
+ @Test
+ public void TestSetQueryString()
+ {
+ test.setQueryString(test3, test1, test2);
+ Assert.assertEquals(test.querystring, "org.apache.qpid:type=UserManagement,*");
+
+ }
+
+ @After
+ public void cleanup()
+ {
+ try
+ {
+ conn.getConnector().close();
+ }
+ catch (Exception ex)
+ {
+ ex.printStackTrace();
+ }
+
+ }
+}
diff --git a/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/commands/objects/TestVirtualHostObject.java b/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/commands/objects/TestVirtualHostObject.java
new file mode 100644
index 0000000000..29c4db30a5
--- /dev/null
+++ b/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/commands/objects/TestVirtualHostObject.java
@@ -0,0 +1,84 @@
+/*
+ *
+ * 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.commands.objects;
+
+import javax.management.MBeanServerConnection;
+
+import org.apache.qpid.ConnectionConstants;
+import org.apache.qpid.Connector;
+import org.apache.qpid.ConnectorFactory;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+public class TestVirtualHostObject
+{
+ Connector conn;
+ MBeanServerConnection mbsc;
+ VirtualHostObject test;
+ String test1, test2, test3;
+
+ @Before
+ public void startup() throws Exception
+ {
+ conn = ConnectorFactory.getConnector(ConnectionConstants.BROKER_HOSTNAME, ConnectionConstants.BROKER_PORT,
+ ConnectionConstants.USERNAME, ConnectionConstants.PASSWORD);
+ mbsc = conn.getMBeanServerConnection();
+ test = new VirtualHostObject(mbsc);
+ test1 = "ping";
+ test2 = "test";
+ test3 = "object";
+
+ }
+
+ @Test
+ public void TestSetQueryString()
+ {
+ test.setQueryString(test3, test1, null);
+ Assert.assertEquals(test.querystring, "org.apache.qpid:type=VirtualHost.VirtualHostManager,name=ping,*");
+ test.querystring = null;
+ test.setQueryString(test3, null, test2);
+ Assert.assertEquals(test.querystring, "org.apache.qpid:type=VirtualHost.VirtualHostManager,VirtualHost=test,*");
+ test.querystring = null;
+ test.setQueryString(test3, test1, test2);
+ Assert.assertEquals(test.querystring,
+ "org.apache.qpid:type=VirtualHost.VirtualHostManager,VirtualHost=test,name=ping,*");
+ test.querystring = null;
+ test.setQueryString(test3, null, null);
+ Assert.assertEquals(test.querystring, "org.apache.qpid:type=VirtualHost.VirtualHostManager,*");
+
+ }
+
+ @After
+ public void cleanup()
+ {
+ try
+ {
+ conn.getConnector().close();
+ }
+ catch (Exception ex)
+ {
+ ex.printStackTrace();
+ }
+
+ }
+}
diff --git a/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/utils/TestCommandLineOption.java b/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/utils/TestCommandLineOption.java
new file mode 100644
index 0000000000..e2a03f52ad
--- /dev/null
+++ b/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/utils/TestCommandLineOption.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.utils;
+
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+public class TestCommandLineOption
+{
+ String input1;
+ String input2;
+ String options;
+ String[] list;
+ CommandLineOption option;
+
+ @Before
+ public void setup()
+ {
+ input1 = "-h";
+ input2 = "--help";
+ options = "localhost testing";
+ list = options.split(" ");
+ option = new CommandLineOption(input1, list);
+
+ }
+
+ @Test
+ public void TestGetOptinValue()
+ {
+ Assert.assertEquals(option.getOptionValue(), "localhost");
+ }
+
+ @Test
+ public void TestGetOptionType()
+ {
+ Assert.assertEquals(option.getOptionType(), "h");
+ }
+
+ @After
+ public void cleanup()
+ {
+ option = null;
+ }
+}
diff --git a/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/utils/TestCommandLineOptionParser.java b/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/utils/TestCommandLineOptionParser.java
new file mode 100644
index 0000000000..964c350fc5
--- /dev/null
+++ b/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/utils/TestCommandLineOptionParser.java
@@ -0,0 +1,79 @@
+/*
+ *
+ * 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.utils;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+public class TestCommandLineOptionParser
+{
+ CommandLineOptionParser parser;
+ String[] input;
+ CommandLineOption option1;
+ CommandLineOption option2;
+ ArrayList list1;
+ ArrayList list2;
+
+ @Before
+ public void setup()
+ {
+ String temp = "run -h localhost -p 23232";
+ input = temp.split(" ");
+ parser = new CommandLineOptionParser(input);
+ list1 = new ArrayList();
+ list2 = new ArrayList();
+ }
+
+ @Test
+ public void TestParse()
+ {
+ Map hash = new HashMap();
+
+ list1.add("localhost");
+ list2.add("23232");
+ option1 = new CommandLineOption("h", list1);
+ option2 = new CommandLineOption("p", list2);
+ hash.put("h", option1);
+ hash.put("p", option2);
+ option1 = (CommandLineOption) parser.parse(input).get("h");
+ Assert.assertEquals(option1.getOptionType(), "h");
+ Assert.assertEquals(option1.getOptionValue(), "localhost");
+ option1 = (CommandLineOption) parser.parse(input).get("p");
+ Assert.assertEquals(option1.getOptionType(), "p");
+ Assert.assertEquals(option1.getOptionValue(), "23232");
+ Assert.assertEquals(parser.parse(input).size(), hash.size());
+ }
+
+ @After
+ public void cleanup()
+ {
+ parser = null;
+ option1 = null;
+ option2 = null;
+
+ }
+}
diff --git a/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/utils/TestJMXConfigProperty.java b/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/utils/TestJMXConfigProperty.java
new file mode 100644
index 0000000000..20234d1153
--- /dev/null
+++ b/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/utils/TestJMXConfigProperty.java
@@ -0,0 +1,26 @@
+/*
+ *
+ * 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.utils;
+
+public class TestJMXConfigProperty
+{
+
+}
diff --git a/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/utils/TestJMXConfiguration.java b/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/utils/TestJMXConfiguration.java
new file mode 100644
index 0000000000..40cde00953
--- /dev/null
+++ b/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/utils/TestJMXConfiguration.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.utils;
+
+import java.util.ArrayList;
+
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+public class TestJMXConfiguration
+{
+ CommandLineOptionParser clop;
+ JMXConfiguration jmc;
+ CommandLineOption option;
+ String[] input;
+
+ @Before
+ public void setup()
+ {
+ String temp = "command -h 127.0.0.1 -p 1234";
+ input = temp.split(" ");
+ clop = new CommandLineOptionParser(input);
+ jmc = new JMXConfiguration(clop.getAlloptions());
+ }
+
+ @Test
+ public void TestLoadOption()
+ {
+ ArrayList list = new ArrayList();
+ list.add("127.0.0.1");
+ option = new CommandLineOption("-h", list);
+ CommandLineOption expect = jmc.loadoption("h", clop.getAlloptions());
+ Assert.assertEquals(expect.getOptionType(), option.getOptionType());
+ Assert.assertEquals(expect.getOptionValue(), option.getOptionValue());
+ }
+
+ @After
+ public void cleanup()
+ {
+ clop = null;
+ jmc = null;
+ option = null;
+ }
+}
diff --git a/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/utils/TestJMXinfo.java b/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/utils/TestJMXinfo.java
new file mode 100644
index 0000000000..aae39bcb37
--- /dev/null
+++ b/qpid/java/management/tools/qpid-cli/test/org/apache/qpid/utils/TestJMXinfo.java
@@ -0,0 +1,30 @@
+/*
+ *
+ * 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.utils;
+
+public class TestJMXinfo
+{
+ /*
+ * this class is having only three simple getter methods. Therefore no
+ * testcases
+ */
+}
diff --git a/qpid/java/maven-settings.xml b/qpid/java/maven-settings.xml
deleted file mode 100644
index 985f39b6f1..0000000000
--- a/qpid/java/maven-settings.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-<settings>
-</settings>
diff --git a/qpid/java/module.xml b/qpid/java/module.xml
index c7819febf4..d3954a1544 100644
--- a/qpid/java/module.xml
+++ b/qpid/java/module.xml
@@ -66,8 +66,6 @@
<property name="module.release.bz2" location="${module.release}/${module.namever}.tar.bz2"/>
<property name="module.genpom.args" value=""/>
- <property name="maven.remote.repo" value="file://${module.release.base}/maven"/>
-
<property name="broker.log.prefix" value="BROKER: "/>
<property name="broker.log.interleave" value="true"/>
@@ -77,7 +75,6 @@
<property name="module.coverage" location="${module.build}/coverage"/>
<property name="cobertura.datafile" location="${module.instrumented}/cobetura.ser"/>
-
<available property="module.test.src.exists" file="${module.test.src}"/>
<available property="module.etc.exists" file="${module.etc}"/>
<available property="module.bin.exists" file="${module.bin}"/>
@@ -223,8 +220,8 @@
<arg line='"${project.root}/genpom"'/>
<arg line='-s "${project.root}/lib/poms"'/>
<arg line='-o "${build.scratch}/qpid-${module.name}.pom"'/>
- <arg line="-u ${project.url}"/>
- <arg line="-g ${project.groupid}"/>
+ <arg line="-u http://qpid.apache.org"/>
+ <arg line="-g org.apache.qpid"/>
<arg line="-v ${project.version}${maven.version.suffix}"/>
<arg line="-p qpid"/>
<arg line='-m "${module.depends}"'/>
@@ -240,14 +237,14 @@
<artifact:pom id="module.pom" file="${build.scratch}/qpid-${module.name}.pom"/>
- <artifact:install file="${module.jar}" pomRefId="module.pom" settingsFile="${maven.settings.xml}">
+ <artifact:install file="${module.jar}" pomRefId="module.pom">
<localRepository path="${maven.local.repo}"/>
</artifact:install>
- <artifact:deploy file="${module.jar}" pomRefId="module.pom" uniqueVersion="${maven.unique.version}" settingsFile="${maven.settings.xml}">
+ <artifact:deploy file="${module.jar}" pomRefId="module.pom" uniqueVersion="${maven.unique.version}">
<attach file="${module.source.jar}" classifier="sources"/>
<localRepository path="${maven.local.repo}"/>
- <remoteRepository url="${maven.remote.repo}"/>
+ <remoteRepository url="file://${module.release.base}/maven"/>
</artifact:deploy>
</target>
@@ -295,7 +292,7 @@
</target>
- <property name="profile" value="java-mms.0-10"/>
+ <property name="profile" value="default"/>
<property name="testprofile.file" value="${test.profiles}/${profile}.testprofile"/>
<available file="${testprofile.file}" property="testprofile.file.present"/>
@@ -303,14 +300,15 @@
<property file="${testprofile.file}" prefix="preload"/>
<property name="preload.include" value=""/>
- <property name="profiles" value="${preload.include} ${profile}"/>
+ <condition property="profiles"
+ value="${preload.include} ${profile}"
+ else="default ${preload.include} ${profile}">
+ <equals arg1="${profile}" arg2="default"/>
+ </condition>
<map property="_profile_files" value="${profiles}" join=" ">
<globmapper from="*" to="*.testprofile"/>
</map>
-
- <delete file="${build.scratch}/test-${profile}.properties" quiet="true"/>
<concat destfile="${build.scratch}/test-${profile}.properties" force="no" fixlastline="yes">
- <filelist dir="${test.profiles}" files="testprofile.defaults"/>
<filelist dir="${test.profiles}" files="${_profile_files}"/>
</concat>
<property file="${build.scratch}/test-${profile}.properties"/>
@@ -319,13 +317,12 @@
<globmapper from="*" to="${test.profiles}/*"/>
</map>
+
<condition property="dontruntest" value="dontruntest" else="runtest">
<contains substring="${module.name}" string="${exclude.modules}" />
</condition>
<property name="jvm.args" value=""/>
- <property name="broker.existing.qpid.work" value=""/>
-
<target name="test" depends="build,compile-tests" if="module.test.src.exists"
unless="${dontruntest}" description="execute unit tests">
@@ -346,6 +343,14 @@
<sysproperty key="log4j.configuration" value="${log4j.configuration}"/>
<sysproperty key="java.naming.factory.initial" value="${java.naming.factory.initial}"/>
<sysproperty key="java.naming.provider.url" value="${java.naming.provider.url}"/>
+ <sysproperty key="broker" value="${broker}"/>
+ <sysproperty key="broker.clean" value="${broker.clean}"/>
+ <sysproperty key="broker.clean.between.tests" value="${broker.clean.between.tests}"/>
+ <sysproperty key="broker.persistent" value="${broker.persistent}"/>
+ <sysproperty key="broker.version" value="${broker.version}"/>
+ <sysproperty key="broker.ready" value="${broker.ready}" />
+ <sysproperty key="broker.stopped" value="${broker.stopped}" />
+ <sysproperty key="broker.config" value="${broker.config}" />
<sysproperty key="messagestore.class.name" value="${messagestore.class.name}" />
<sysproperty key="test.output" value="${module.results}"/>
<sysproperty key="qpid.amqp.version" value="${qpid.amqp.version}"/>
@@ -396,15 +401,6 @@
</target>
- <target name="report-module" description="generate junit reports for each module">
- <junitreport todir="${module.results}">
- <fileset dir="${module.results}">
- <include name="TEST-*.xml"/>
- </fileset>
- <report format="frames" todir="${module.results}/report/html"/>
- </junitreport>
- </target>
-
<target name="touch-failed" if="test.failures">
<touch file="${module.failed}"/>
<touch file="${build.failed}"/>
@@ -651,6 +647,9 @@
<fileset dir="${module.classes}">
<include name="**/*.class"/>
</fileset>
+ <fileset dir="${module.test.classes}">
+ <include name="**/*.class"/>
+ </fileset>
</cobertura-instrument>
</target>
@@ -815,84 +814,4 @@ qpid.name=${project.name}
<touch file="${velocity.timestamp}" />
</target>
- <target name="eclipse" depends="eclipse-setup,eclipse-project,eclipse-source-only,eclipse-source-and-test"/>
-
- <target name="eclipse-setup">
- <taskdef name="eclipse" classname="prantl.ant.eclipse.EclipseTask" />
-
- <!-- Build set of directories representing the dependencies -->
-
- <dirset id="eclipse.required.projectdirs.path" dir="${project.root}" includes="${module.depends} ${module.test.depends} neverBeEmpty">
- <!-- Select only those projects from module.depends that contain a build.xml. This serves to exclude dependencies that
- don't become Eclipse projects e.g. broker-plugins and common-tests -->
- <present targetdir="${project.root}">
- <mapper type="glob" from="*" to="*/build.xml"/>
- </present>
- </dirset>
-
- <!-- Convert from the set of directories into Eclipse project names proceeded by forward slashes -->
-
- <pathconvert property="eclipse.required.projectnames" refid="eclipse.required.projectdirs.path" pathsep=" " dirsep="-">
- <map from="${project.root}${file.separator}" to=''/>
- </pathconvert>
- <map property="eclipse.required.slashedprojectnames" value="${eclipse.required.projectnames}" join="${path.separator}">
- <globmapper from="*" to="/*"/>
- </map>
-
- <echo message="Ant module dependencies : ${module.depends} ${module.test.depends} converted to Eclipse required project(s): ${eclipse.required.slashedprojectnames}"/>
- <path id="eclipse.required.slashedprojectnames.path">
- <pathelement path="${eclipse.required.slashedprojectnames}"/>
- </path>
- </target>
-
- <!-- Create the Eclipse .project -->
- <target name="eclipse-project">
- <eclipse updatealways="${eclipse.updatealways}">
- <project name="${module.name}"/>
-
- <!-- If the Eclipse task were to ever support the generation of
- linked resources, we would configure it to generate
- the following:
-
- scratch_src -> ${module.precompiled}
-
- in each project. This would avoid the 'linked sources'
- manual step documented on the Wiki.
- -->
- </eclipse>
- </target>
-
- <!-- Create the Eclipse .classpath -->
- <target name="eclipse-source-only" unless="module.test.src.exists">
- <eclipse updatealways="${eclipse.updatealways}">
- <settings>
- <jdtcore compilercompliance="${eclipse.compilercompliance}" />
- </settings>
- <classpath>
- <container path="${eclipse.container}" />
- <source path="${module.src}" />
- <source pathref="eclipse.required.slashedprojectnames.path" />
- <library pathref="module.libs"/>
- <output path="classes" />
- </classpath>
- </eclipse>
- </target>
-
- <!-- Create the Eclipse .classpath -->
- <target name="eclipse-source-and-test" if="module.test.src.exists">
- <eclipse updatealways="${eclipse.updatealways}">
- <settings>
- <jdtcore compilercompliance="${eclipse.compilercompliance}" />
- </settings>
- <classpath>
- <container path="${eclipse.container}" />
- <source path="${module.src}" />
- <source path="${module.test.src}" />
- <source pathref="eclipse.required.slashedprojectnames.path" />
- <library pathref="module.libs"/>
- <library pathref="module.test.libs"/>
- <output path="classes" />
- </classpath>
- </eclipse>
- </target>
</project>
diff --git a/qpid/java/perftests/src/main/java/org/apache/qpid/test/testcases/MessageThroughputPerf.java b/qpid/java/perftests/src/main/java/org/apache/qpid/test/testcases/MessageThroughputPerf.java
new file mode 100644
index 0000000000..e2e97ab6f8
--- /dev/null
+++ b/qpid/java/perftests/src/main/java/org/apache/qpid/test/testcases/MessageThroughputPerf.java
@@ -0,0 +1,207 @@
+/*
+ *
+ * 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.testcases;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+import org.apache.log4j.Logger;
+import org.apache.log4j.NDC;
+
+import org.apache.qpid.test.framework.Assertion;
+import org.apache.qpid.test.framework.Circuit;
+import org.apache.qpid.test.framework.FrameworkBaseCase;
+import org.apache.qpid.test.framework.MessagingTestConfigProperties;
+import org.apache.qpid.test.framework.sequencers.CircuitFactory;
+
+import org.apache.qpid.junit.extensions.TestThreadAware;
+import org.apache.qpid.junit.extensions.TimingController;
+import org.apache.qpid.junit.extensions.TimingControllerAware;
+import org.apache.qpid.junit.extensions.util.ParsedProperties;
+import org.apache.qpid.junit.extensions.util.TestContextProperties;
+
+import java.util.LinkedList;
+
+/**
+ * MessageThroughputPerf runs a test over a {@link Circuit} controlled by the test parameters. It logs timings of
+ * the time required to receive samples consisting of batches of messages.
+ *
+ * <p/><table id="crc"><caption>CRC Card</caption>
+ * <tr><th> Responsibilities <th> Collaborations
+ * <tr><td> Measure message throughput accross a test circuit. <td> {@link Circuit}
+ * </table>
+ *
+ * @todo Check that all of the messages were sent. Check that the receiving end got the same number of messages as
+ * the publishing end.
+ *
+ * @todo Set this up to run with zero sized tests. Size zero means send forever. Continuous sending to be interrupted
+ * by completion of the test duration, or shutdown hook when the user presses Ctrl-C.
+ */
+public class MessageThroughputPerf extends FrameworkBaseCase implements TimingControllerAware, TestThreadAware
+{
+ /** Used for debugging. */
+ private static final Logger log = Logger.getLogger(MessageThroughputPerf.class);
+
+ /** Holds the timing controller, used to log test timings from self-timed tests. */
+ private TimingController timingController;
+
+ /** Thread local to hold the per-thread test setup fields. */
+ ThreadLocal<PerThreadSetup> threadSetup = new ThreadLocal<PerThreadSetup>();
+
+ /**
+ * Creates a new test case with the specified name.
+ *
+ * @param name The test case name.
+ */
+ public MessageThroughputPerf(String name)
+ {
+ super(name);
+ }
+
+ /**
+ * Performs the a basic P2P test case.
+ *
+ * @param numMessages The number of messages to send in the test.
+ */
+ public void testThroughput(int numMessages)
+ {
+ log.debug("public void testThroughput(): called");
+
+ PerThreadSetup setup = threadSetup.get();
+ assertNoFailures(setup.testCircuit.test(numMessages, new LinkedList<Assertion>()));
+ }
+
+ /**
+ * Should provide a translation from the junit method name of a test to its test case name as known to the test
+ * clients that will run the test. The purpose of this is to convert the JUnit method name into the correct test
+ * case name to place into the test invite. For example the method "testP2P" might map onto the interop test case
+ * name "TC2_BasicP2P".
+ *
+ * @param methodName The name of the JUnit test method.
+ *
+ * @return The name of the corresponding interop test case.
+ */
+ public String getTestCaseNameForTestMethod(String methodName)
+ {
+ log.debug("public String getTestCaseNameForTestMethod(String methodName = " + methodName + "): called");
+
+ return "DEFAULT_CIRCUIT_TEST";
+ }
+
+ /**
+ * Used by test runners that can supply a {@link org.apache.qpid.junit.extensions.TimingController} to set the
+ * controller on an aware test.
+ *
+ * @param controller The timing controller.
+ */
+ public void setTimingController(TimingController controller)
+ {
+ timingController = controller;
+ }
+
+ /**
+ * Overrides the parent setUp method so that the in-vm broker creation is not done on a per test basis.
+ *
+ * @throws Exception Any exceptions allowed to fall through and fail the test.
+ */
+ protected void setUp() throws Exception
+ {
+ NDC.push(getName());
+
+ setTestProps(TestContextProperties.getInstance(MessagingTestConfigProperties.defaults));
+ }
+
+ /**
+ * Overrides the parent setUp method so that the in-vm broker clean-up is not done on a per test basis.
+ */
+ protected void tearDown()
+ {
+ NDC.pop();
+ }
+
+ /**
+ * Performs test fixture creation on a per thread basis. This will only be called once for each test thread.
+ */
+ public void threadSetUp()
+ {
+ // Run the test setup tasks. This may create an in-vm broker, if a decorator has injected a task for this.
+ getTaskHandler().runSetupTasks();
+
+ // Get the test parameters, any overrides on the command line will have been applied.
+ ParsedProperties testProps = TestContextProperties.getInstance(MessagingTestConfigProperties.defaults);
+
+ // Customize the test parameters.
+ testProps.setProperty("TEST_NAME", "DEFAULT_CIRCUIT_TEST");
+ testProps.setProperty(MessagingTestConfigProperties.SEND_DESTINATION_NAME_ROOT_PROPNAME, "testqueue");
+
+ // Get the test circuit factory to create test circuits and run the standard test procedure through.
+ CircuitFactory circuitFactory = getCircuitFactory();
+
+ // Create the test circuit. This projects the circuit onto the available test nodes and connects it up.
+ Circuit testCircuit = circuitFactory.createCircuit(null, testProps);
+
+ // Store the test configuration for the thread.
+ PerThreadSetup setup = new PerThreadSetup();
+ setup.testCircuit = testCircuit;
+ threadSetup.set(setup);
+ }
+
+ /**
+ * Called after all threads have completed their setup.
+ */
+ public void postThreadSetUp()
+ {
+ //Nothing to do here, potentially implement preFill as per PingTestPerf.
+ }
+
+ /**
+ * Called when a test thread is destroyed.
+ */
+ public void threadTearDown()
+ {
+ // Run the test teardown tasks. This may destroy the in-vm broker, if a decorator has injected a task for this.
+ getTaskHandler().runSetupTasks();
+ }
+
+ /**
+ * Holds the per-thread test configurations.
+ */
+ protected static class PerThreadSetup
+ {
+ /** Holds the test circuit to run tests on. */
+ Circuit testCircuit;
+ }
+
+ /**
+ * Compiles all the tests in this class into a suite.
+ *
+ * @return The test suite.
+ */
+ public static Test suite()
+ {
+ // Build a new test suite
+ TestSuite suite = new TestSuite("Qpid Throughput Performance Tests");
+
+ suite.addTest(new MessageThroughputPerf("testThroughput"));
+
+ return suite;
+ }
+}
diff --git a/qpid/java/resources/NOTICE b/qpid/java/resources/NOTICE
index add7753a4b..607c1c1580 100644
--- a/qpid/java/resources/NOTICE
+++ b/qpid/java/resources/NOTICE
@@ -10,6 +10,13 @@ available from
http://www.slf4j.org/
+Concurrency utlitity classes are provided by the backport-util-concurrent
+library package, which is open source software, written by
+Dawid Kurzyniec, and copyright by Distributed Computing Laboratory,
+Emory University. The original software is available from
+
+ http://dcl.mathcs.emory.edu/util/backport-util-concurrent/
+
Data compression support is provided by the JZLib library package,
which is open source software, written by JCraft, and copyright
by JCraft. The original software is available from
diff --git a/qpid/java/systests/etc/config-systests-ServerConfigurationTest-New.xml b/qpid/java/systests/etc/config-systests-ServerConfigurationTest-New.xml
new file mode 100644
index 0000000000..d1dce019dd
--- /dev/null
+++ b/qpid/java/systests/etc/config-systests-ServerConfigurationTest-New.xml
@@ -0,0 +1,78 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!--
+ -
+ - 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.
+ -
+ -->
+
+<broker>
+ <work>${QPID_WORK}</work>
+ <conf>${QPID_HOME}/etc</conf>
+ <passwordDir>${conf}</passwordDir>
+ <plugin-directory>${QPID_HOME}/lib/plugins</plugin-directory>
+ <cache-directory>${QPID_WORK}/cache</cache-directory>
+ <connector>
+ <transport>nio</transport>
+ <port>5672</port>
+ <socketReceiveBuffer>32768</socketReceiveBuffer>
+ <socketSendBuffer>32768</socketSendBuffer>
+ </connector>
+ <management>
+ <enabled>false</enabled>
+ <jmxport>8999</jmxport>
+ </management>
+ <advanced>
+ <filterchain enableExecutorPool="true"/>
+ <enablePooledAllocator>false</enablePooledAllocator>
+ <enableDirectBuffers>false</enableDirectBuffers>
+ <framesize>65535</framesize>
+ <compressBufferOnQueue>false</compressBufferOnQueue>
+ </advanced>
+
+ <security>
+ <principal-databases>
+ <principal-database>
+ <name>passwordfile</name>
+ <class>org.apache.qpid.server.security.auth.database.PlainPasswordFilePrincipalDatabase</class>
+ <attributes>
+ <attribute>
+ <name>passwordFile</name>
+ <value>${passwordDir}/passwd</value>
+ </attribute>
+ </attributes>
+ </principal-database>
+ </principal-databases>
+
+ <jmx>
+ <access>${passwordDir}/jmxremote.access</access>
+ <principal-database>passwordfile</principal-database>
+ </jmx>
+ </security>
+
+ <virtualhosts>${conf}/virtualhosts-ServerConfigurationTest-New.xml</virtualhosts>
+
+ <heartbeat>
+ <delay>0</delay>
+ <timeoutFactor>2.0</timeoutFactor>
+ </heartbeat>
+ <queue>
+ <auto_register>true</auto_register>
+ </queue>
+</broker>
+
+
diff --git a/qpid/java/systests/etc/config-systests-ServerConfigurationTest-Old.xml b/qpid/java/systests/etc/config-systests-ServerConfigurationTest-Old.xml
new file mode 100644
index 0000000000..1de0389533
--- /dev/null
+++ b/qpid/java/systests/etc/config-systests-ServerConfigurationTest-Old.xml
@@ -0,0 +1,92 @@
+<?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.
+
+-->
+
+<configuration>
+<work>${QPID_WORK}</work>
+<conf>${QPID_HOME}/etc</conf>
+<passwordDir>${conf}</passwordDir>
+<plugin-directory>${QPID_HOME}/lib/plugins</plugin-directory>
+<cache-directory>${QPID_WORK}/cache</cache-directory>
+<connector>
+<transport>nio</transport>
+<port>5672</port>
+<socketReceiveBuffer>32768</socketReceiveBuffer>
+<socketSendBuffer>32768</socketSendBuffer>
+</connector>
+<management>
+<enabled>false</enabled>
+<jmxport>8999</jmxport>
+</management>
+<advanced>
+<filterchain enableExecutorPool="true"/>
+<enablePooledAllocator>false</enablePooledAllocator>
+<enableDirectBuffers>false</enableDirectBuffers>
+<framesize>65535</framesize>
+<compressBufferOnQueue>false</compressBufferOnQueue>
+</advanced>
+<security>
+<principal-databases>
+<principal-database>
+<name>passwordfile</name>
+<class>org.apache.qpid.server.security.auth.database.PlainPasswordFilePrincipalDatabase</class>
+<attributes>
+<attribute>
+<name>passwordFile</name>
+<value>${passwordDir}/passwd</value>
+</attribute>
+</attributes>
+</principal-database>
+</principal-databases>
+<jmx>
+<access>${passwordDir}/jmxremote.access</access>
+<principal-database>passwordfile</principal-database>
+</jmx>
+</security>
+<virtualhosts>${conf}/virtualhosts-ServerConfigurationTest-New.xml
+<default>dev-only</default>
+<virtualhost>
+<name>dev-only</name>
+<dev-only>
+<store>
+<class>org.apache.qpid.server.store.MemoryMessageStore</class>
+<environment-path>${work}/bdbstore/dev-only-store</environment-path>
+</store>
+<queues>
+<exchange>amq.direct</exchange>
+<maximumQueueDepth>102400</maximumQueueDepth>
+<maximumMessageSize>20480</maximumMessageSize>
+<maximumMessageAge>60000</maximumMessageAge>
+<queue>
+<name>dev-queue</name>
+</queue>
+</queues>
+</dev-only>
+</virtualhost>
+</virtualhosts>
+<heartbeat>
+<delay>0</delay>
+<timeoutFactor>2.0</timeoutFactor>
+</heartbeat>
+<queue>
+<auto_register>true</auto_register>
+</queue>
+</configuration>
diff --git a/qpid/java/systests/etc/config-systests-acl-settings.xml b/qpid/java/systests/etc/config-systests-acl-settings.xml
new file mode 100644
index 0000000000..eebc75f05f
--- /dev/null
+++ b/qpid/java/systests/etc/config-systests-acl-settings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!--
+ -
+ - 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.
+ -
+ -->
+<broker>
+ <virtualhosts>${QPID_HOME}/etc/virtualhosts-systests-acl.xml</virtualhosts>
+</broker>
+
+
diff --git a/qpid/java/systests/etc/config-systests-acl.xml b/qpid/java/systests/etc/config-systests-acl.xml
new file mode 100644
index 0000000000..535108235e
--- /dev/null
+++ b/qpid/java/systests/etc/config-systests-acl.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!--
+ -
+ - 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.
+ -
+ -->
+<configuration>
+ <system/>
+ <override>
+ <xml fileName="${test.config}" optional="true"/>
+ <xml fileName="${QPID_HOME}/etc/config-systests-acl-settings.xml"/>
+ <xml fileName="${QPID_HOME}/etc/config-systests-settings.xml"/>
+ <xml fileName="${QPID_HOME}/etc/config.xml"/>
+ </override>
+</configuration>
diff --git a/qpid/java/systests/etc/config-systests-firewall-2.xml b/qpid/java/systests/etc/config-systests-firewall-2.xml
index f16cce6b85..38ff9ddbb0 100644
--- a/qpid/java/systests/etc/config-systests-firewall-2.xml
+++ b/qpid/java/systests/etc/config-systests-firewall-2.xml
@@ -35,10 +35,17 @@
<keystorePath>/path/to/keystore.ks</keystorePath>
<keystorePassword>keystorepass</keystorePassword>
</ssl>
+ <qpidnio>false</qpidnio>
+ <protectio>
+ <enabled>false</enabled>
+ <readBufferLimitSize>262144</readBufferLimitSize>
+ <writeBufferLimitSize>262144</writeBufferLimitSize>
+ </protectio>
+ <transport>nio</transport>
<port>5672</port>
<sslport>8672</sslport>
- <socketReceiveBuffer>262144</socketReceiveBuffer>
- <socketSendBuffer>262144</socketSendBuffer>
+ <socketReceiveBuffer>32768</socketReceiveBuffer>
+ <socketSendBuffer>32768</socketSendBuffer>
</connector>
<management>
<enabled>false</enabled>
@@ -61,8 +68,10 @@
</advanced>
<security>
- <pd-auth-manager>
+ <principal-databases>
+ <!-- Example use of Base64 encoded MD5 hashes for authentication via CRAM-MD5-Hashed -->
<principal-database>
+ <name>passwordfile</name>
<class>org.apache.qpid.server.security.auth.database.PlainPasswordFilePrincipalDatabase</class>
<attributes>
<attribute>
@@ -71,10 +80,15 @@
</attribute>
</attributes>
</principal-database>
- </pd-auth-manager>
+ </principal-databases>
<msg-auth>false</msg-auth>
+ <jmx>
+ <access>${conf}/jmxremote.access</access>
+ <principal-database>passwordfile</principal-database>
+ </jmx>
+
<firewall default-action="deny"/>
</security>
diff --git a/qpid/java/systests/etc/config-systests-firewall-3.xml b/qpid/java/systests/etc/config-systests-firewall-3.xml
index 71644e4185..6c0ee7ee3c 100644
--- a/qpid/java/systests/etc/config-systests-firewall-3.xml
+++ b/qpid/java/systests/etc/config-systests-firewall-3.xml
@@ -35,10 +35,17 @@
<keystorePath>/path/to/keystore.ks</keystorePath>
<keystorePassword>keystorepass</keystorePassword>
</ssl>
+ <qpidnio>false</qpidnio>
+ <protectio>
+ <enabled>false</enabled>
+ <readBufferLimitSize>262144</readBufferLimitSize>
+ <writeBufferLimitSize>262144</writeBufferLimitSize>
+ </protectio>
+ <transport>nio</transport>
<port>5672</port>
<sslport>8672</sslport>
- <socketReceiveBuffer>262144</socketReceiveBuffer>
- <socketSendBuffer>262144</socketSendBuffer>
+ <socketReceiveBuffer>32768</socketReceiveBuffer>
+ <socketSendBuffer>32768</socketSendBuffer>
</connector>
<management>
<enabled>false</enabled>
@@ -61,8 +68,10 @@
</advanced>
<security>
- <pd-auth-manager>
+ <principal-databases>
+ <!-- Example use of Base64 encoded MD5 hashes for authentication via CRAM-MD5-Hashed -->
<principal-database>
+ <name>passwordfile</name>
<class>org.apache.qpid.server.security.auth.database.PlainPasswordFilePrincipalDatabase</class>
<attributes>
<attribute>
@@ -71,10 +80,15 @@
</attribute>
</attributes>
</principal-database>
- </pd-auth-manager>
+ </principal-databases>
<msg-auth>false</msg-auth>
+ <jmx>
+ <access>${conf}/jmxremote.access</access>
+ <principal-database>passwordfile</principal-database>
+ </jmx>
+
<firewall default-action="deny">
<rule access="allow" network="127.0.0.1"/>
</firewall>
diff --git a/qpid/java/systests/etc/virtualhosts-ServerConfigurationTest-New.xml b/qpid/java/systests/etc/virtualhosts-ServerConfigurationTest-New.xml
new file mode 100644
index 0000000000..1b6845662b
--- /dev/null
+++ b/qpid/java/systests/etc/virtualhosts-ServerConfigurationTest-New.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!--
+ -
+ - 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.
+ -
+ -->
+<virtualhosts>
+ <default>dev-only</default>
+ <virtualhost>
+ <name>dev-only</name>
+ <dev-only>
+ <queues>
+ <exchange>amq.direct</exchange>
+ <!-- Small defaults for development -->
+ <maximumQueueDepth>102400</maximumQueueDepth> <!-- 100k -->
+ <maximumMessageSize>20480</maximumMessageSize> <!-- 20kb -->
+ <maximumMessageAge>60000</maximumMessageAge> <!-- 1 mins -->
+
+ <queue>
+ <name>dev-queue</name>
+ </queue>
+ </queues>
+ <store>
+ <class>org.apache.qpid.server.store.MemoryMessageStore</class>
+ <environment-path>${QPID_WORK}/bdbstore/dev-only-store</environment-path>
+ </store>
+ </dev-only>
+ </virtualhost>
+</virtualhosts>
+ \ No newline at end of file
diff --git a/qpid/java/systests/etc/virtualhosts-systests-acl-settings.xml b/qpid/java/systests/etc/virtualhosts-systests-acl-settings.xml
new file mode 100644
index 0000000000..ffbace569f
--- /dev/null
+++ b/qpid/java/systests/etc/virtualhosts-systests-acl-settings.xml
@@ -0,0 +1,180 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!--
+ -
+ - 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.
+ -
+ -->
+<virtualhosts>
+ <virtualhost>
+ <name>test</name>
+ <test>
+ <queues>
+ <exchange>amq.direct</exchange>
+ <!-- 4Mb -->
+ <maximumQueueDepth>4235264</maximumQueueDepth>
+ <!-- 2Mb -->
+ <maximumMessageSize>2117632</maximumMessageSize>
+ <!-- 10 mins -->
+ <maximumMessageAge>600000</maximumMessageAge>
+ </queues>
+
+
+ <security>
+ <access_control_list>
+ <!-- This section grants pubish rights to an exchange + routing key pair -->
+ <publish>
+ <exchanges>
+ <exchange>
+ <name>amq.direct</name>
+ <routing_keys>
+ <!-- Allow clients to publish requests -->
+ <routing_key>
+ <value>example.RequestQueue</value>
+ <users>
+ <user>client</user>
+ </users>
+ </routing_key>
+
+ <!-- Allow the processor to respond to a client on their Temporary Topic -->
+ <routing_key>
+ <value>tmp_*</value>
+ <users>
+ <user>server</user>
+ </users>
+ </routing_key>
+ <routing_key>
+ <value>TempQueue*</value>
+ <users>
+ <user>server</user>
+ </users>
+ </routing_key>
+ </routing_keys>
+ </exchange>
+ </exchanges>
+ </publish>
+
+ <!-- This section grants users the ability to consume from the broker -->
+ <consume>
+ <queues>
+ <temporary>
+ <users>
+ <user>client</user>
+ </users>
+ </temporary>
+
+ <!-- Only allow the server to consume from the Request Queue-->
+ <queue>
+ <name>example.RequestQueue</name>
+ <users>
+ <user>server</user>
+ </users>
+ </queue>
+
+ <!-- Allow client and server to consume from the kipper Queue-->
+ <queue>
+ <name>clientid:kipper</name>
+ <users>
+ <user>client</user>
+ <user>server</user>
+ </users>
+ </queue>
+ </queues>
+ </consume>
+
+ <!-- This section grants users the ability to create queues and exchanges -->
+ <create>
+ <queues>
+ <temporary>
+ <users>
+ <user>client</user>
+ </users>
+ </temporary>
+
+ <!-- Allow clients to create queue on this exchange-->
+ <queue>
+ <exchanges>
+ <exchange>
+ <name>amq.direct</name>
+ <users>
+ <user>client</user>
+ <user>server</user>
+ </users>
+ </exchange>
+ <exchange>
+ <name>amq.topic</name>
+ <users>
+ <user>client</user>
+ <user>server</user>
+ </users>
+ </exchange>
+ </exchanges>
+ </queue>
+
+ <!-- everyone can create the kipper queue -->
+ <queue>
+ <name>clientid:kipper</name>
+ <users>
+ <user>client</user>
+ <user>server</user>
+ </users>
+ </queue>
+
+ <!-- Allow the server to create the Request Queue-->
+ <queue>
+ <name>example.RequestQueue</name>
+ <users>
+ <user>server</user>
+ </users>
+ </queue>
+ </queues>
+ </create>
+
+ <delete>
+ <queues>
+ <!-- only client can delete the kipper queue -->
+ <queue>
+ <name>clientid:kipper</name>
+ <users>
+ <user>client</user>
+ </users>
+ </queue>
+ </queues>
+ </delete>
+ </access_control_list>
+ </security>
+ </test>
+ </virtualhost>
+
+ <virtualhost>
+ <name>test2</name>
+ <test2>
+ <security>
+ <access_control_list>
+ <!-- This section grants specific users full permissions to all artifacts in this virtualhost -->
+ <access>
+ <users>
+ <user>guest</user>
+ </users>
+ </access>
+ </access_control_list>
+ </security>
+ </test2>
+ </virtualhost>
+</virtualhosts>
+
+
diff --git a/qpid/java/systests/etc/virtualhosts-systests-acl.xml b/qpid/java/systests/etc/virtualhosts-systests-acl.xml
new file mode 100644
index 0000000000..4a56c39de0
--- /dev/null
+++ b/qpid/java/systests/etc/virtualhosts-systests-acl.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!--
+ -
+ - 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.
+ -
+ -->
+<configuration>
+ <system/>
+ <override>
+ <xml fileName="${test.virtualhosts}" optional="true"/>
+ <xml fileName="${QPID_HOME}/etc/virtualhosts-systests-acl-settings.xml"/>
+ <xml fileName="${QPID_HOME}/etc/virtualhosts.xml"/>
+ </override>
+</configuration>
diff --git a/qpid/java/systests/src/main/java/org/apache/mina/transport/vmpipe/support/VmPipeIdleStatusChecker.java b/qpid/java/systests/src/main/java/org/apache/mina/transport/vmpipe/support/VmPipeIdleStatusChecker.java
new file mode 100644
index 0000000000..5323ad28bf
--- /dev/null
+++ b/qpid/java/systests/src/main/java/org/apache/mina/transport/vmpipe/support/VmPipeIdleStatusChecker.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.mina.transport.vmpipe.support;
+
+import org.apache.mina.common.IdleStatus;
+
+import java.util.HashMap;
+import java.util.IdentityHashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+/**
+ * This file is a patch to override MINA, because of the IdentityHashMap bug. Workaround to be supplied in MINA 1.0.7.
+ * This patched file will be removed once upgraded onto a newer MINA.
+ *
+ * Dectects idle sessions and fires <tt>sessionIdle</tt> events to them.
+ *
+ * @author The Apache Directory Project (mina-dev@directory.apache.org)
+ */
+public class VmPipeIdleStatusChecker
+{
+ private static final VmPipeIdleStatusChecker INSTANCE = new VmPipeIdleStatusChecker();
+
+ public static VmPipeIdleStatusChecker getInstance()
+ {
+ return INSTANCE;
+ }
+
+ private final Map sessions = new HashMap(); // will use as a set
+
+ private final Worker worker = new Worker();
+
+ private VmPipeIdleStatusChecker()
+ {
+ worker.start();
+ }
+
+ public void addSession(VmPipeSessionImpl session)
+ {
+ synchronized (sessions)
+ {
+ sessions.put(session, session);
+ }
+ }
+
+ private class Worker extends Thread
+ {
+ private Worker()
+ {
+ super("VmPipeIdleStatusChecker");
+ setDaemon(true);
+ }
+
+ public void run()
+ {
+ for (;;)
+ {
+ try
+ {
+ Thread.sleep(1000);
+ }
+ catch (InterruptedException e)
+ { }
+
+ long currentTime = System.currentTimeMillis();
+
+ synchronized (sessions)
+ {
+ Iterator it = sessions.keySet().iterator();
+ while (it.hasNext())
+ {
+ VmPipeSessionImpl session = (VmPipeSessionImpl) it.next();
+ if (!session.isConnected())
+ {
+ it.remove();
+ }
+ else
+ {
+ notifyIdleSession(session, currentTime);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ private void notifyIdleSession(VmPipeSessionImpl session, long currentTime)
+ {
+ notifyIdleSession0(session, currentTime, session.getIdleTimeInMillis(IdleStatus.BOTH_IDLE), IdleStatus.BOTH_IDLE,
+ Math.max(session.getLastIoTime(), session.getLastIdleTime(IdleStatus.BOTH_IDLE)));
+ notifyIdleSession0(session, currentTime, session.getIdleTimeInMillis(IdleStatus.READER_IDLE), IdleStatus.READER_IDLE,
+ Math.max(session.getLastReadTime(), session.getLastIdleTime(IdleStatus.READER_IDLE)));
+ notifyIdleSession0(session, currentTime, session.getIdleTimeInMillis(IdleStatus.WRITER_IDLE), IdleStatus.WRITER_IDLE,
+ Math.max(session.getLastWriteTime(), session.getLastIdleTime(IdleStatus.WRITER_IDLE)));
+ }
+
+ private void notifyIdleSession0(VmPipeSessionImpl session, long currentTime, long idleTime, IdleStatus status,
+ long lastIoTime)
+ {
+ if ((idleTime > 0) && (lastIoTime != 0) && ((currentTime - lastIoTime) >= idleTime))
+ {
+ session.increaseIdleCount(status);
+ session.getFilterChain().fireSessionIdle(session, status);
+ }
+ }
+
+}
diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/client/AMQQueueDeferredOrderingTest.java b/qpid/java/systests/src/main/java/org/apache/qpid/client/AMQQueueDeferredOrderingTest.java
index 986297bfe1..ca10126aa7 100644
--- a/qpid/java/systests/src/main/java/org/apache/qpid/client/AMQQueueDeferredOrderingTest.java
+++ b/qpid/java/systests/src/main/java/org/apache/qpid/client/AMQQueueDeferredOrderingTest.java
@@ -30,6 +30,7 @@ import javax.jms.TextMessage;
import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.test.utils.QpidBrokerTestCase;
+import org.apache.qpid.client.transport.TransportConnection;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/client/DispatcherTest.java b/qpid/java/systests/src/main/java/org/apache/qpid/client/DispatcherTest.java
index 29a44ecec3..a8a23c2c41 100644
--- a/qpid/java/systests/src/main/java/org/apache/qpid/client/DispatcherTest.java
+++ b/qpid/java/systests/src/main/java/org/apache/qpid/client/DispatcherTest.java
@@ -36,6 +36,7 @@ import javax.jms.Session;
import javax.naming.Context;
import javax.naming.spi.InitialContextFactory;
+import org.apache.qpid.client.transport.TransportConnection;
import org.apache.qpid.jndi.PropertiesFileInitialContextFactory;
import org.apache.qpid.test.utils.QpidBrokerTestCase;
import org.slf4j.Logger;
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
new file mode 100644
index 0000000000..29b4dd82a7
--- /dev/null
+++ b/qpid/java/systests/src/main/java/org/apache/qpid/client/MultipleJCAProviderRegistrationTest.java
@@ -0,0 +1,82 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.client;
+
+import org.apache.qpid.test.utils.QpidBrokerTestCase;
+import org.apache.qpid.server.registry.ConfigurationFileApplicationRegistry;
+import org.apache.qpid.server.registry.ApplicationRegistry;
+import org.apache.qpid.client.transport.TransportConnection;
+
+import java.io.File;
+import java.security.Provider;
+import java.security.Security;
+import java.util.List;
+import java.util.LinkedList;
+
+/**
+ * QPID-1394 : Test to ensure that the client can register their custom JCAProviders after the broker to ensure that
+ * the Qpid custom authentication SASL plugins are used.
+ */
+public class MultipleJCAProviderRegistrationTest extends QpidBrokerTestCase
+{
+
+ public void setUp() throws Exception
+ {
+ _broker = VM;
+
+ super.setUp();
+ }
+
+ public void test() throws Exception
+ {
+ // Get the providers before connection
+ Provider[] providers = Security.getProviders();
+
+ // Force the client to load the providers
+ getConnection();
+
+ Provider[] afterConnectionCreation = Security.getProviders();
+
+ // Find the additions
+ List additions = new LinkedList();
+ for (Provider afterCreation : afterConnectionCreation)
+ {
+ boolean found = false;
+ for (Provider provider : providers)
+ {
+ if (provider == afterCreation)
+ {
+ found=true;
+ break;
+ }
+ }
+
+ // Record added registies
+ if (!found)
+ {
+ additions.add(afterCreation);
+ }
+ }
+
+ assertTrue("Client did not register any providers", additions.size() > 0);
+ }
+
+}
diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/client/message/AMQPEncodedMapMessageTest.java b/qpid/java/systests/src/main/java/org/apache/qpid/client/message/AMQPEncodedMapMessageTest.java
index bf96dae02e..004ce5ea8f 100644
--- a/qpid/java/systests/src/main/java/org/apache/qpid/client/message/AMQPEncodedMapMessageTest.java
+++ b/qpid/java/systests/src/main/java/org/apache/qpid/client/message/AMQPEncodedMapMessageTest.java
@@ -27,7 +27,6 @@ import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
-import java.util.UUID;
import javax.jms.Connection;
import javax.jms.JMSException;
@@ -52,7 +51,6 @@ public class AMQPEncodedMapMessageTest extends QpidBrokerTestCase
private Session _session;
MessageConsumer _consumer;
MessageProducer _producer;
- UUID myUUID = UUID.randomUUID();
public void setUp() throws Exception
{
@@ -121,8 +119,7 @@ public class AMQPEncodedMapMessageTest extends QpidBrokerTestCase
m.setFloat("Float", Integer.MAX_VALUE + 5000);
m.setInt("Int", Integer.MAX_VALUE - 5000);
m.setShort("Short", (short)58);
- m.setString("String", "Hello");
- m.setObject("uuid", myUUID);
+ m.setString("String", "Hello");
_producer.send(m);
AMQPEncodedMapMessage msg = (AMQPEncodedMapMessage)_consumer.receive(RECEIVE_TIMEOUT);
@@ -143,7 +140,6 @@ public class AMQPEncodedMapMessageTest extends QpidBrokerTestCase
assertEquals(Integer.MAX_VALUE - 5000,m.getInt("Int"));
assertEquals((short)58,m.getShort("Short"));
assertEquals("Hello",m.getString("String"));
- assertEquals(myUUID,(UUID)m.getObject("uuid"));
}
@@ -153,11 +149,7 @@ public class AMQPEncodedMapMessageTest extends QpidBrokerTestCase
List<Integer> myList = getList();
- m.setObject("List", myList);
-
- List<UUID> uuidList = new ArrayList<UUID>();
- uuidList.add(myUUID);
- m.setObject("uuid-list", uuidList);
+ m.setObject("List", myList);
_producer.send(m);
AMQPEncodedMapMessage msg = (AMQPEncodedMapMessage)_consumer.receive(RECEIVE_TIMEOUT);
@@ -175,10 +167,6 @@ public class AMQPEncodedMapMessageTest extends QpidBrokerTestCase
assertEquals(i,j.intValue());
i++;
}
-
- List<UUID> list2 = (List<UUID>)msg.getObject("uuid-list");
- assertNotNull("UUID List not received",list2);
- assertEquals(myUUID,list2.get(0));
}
public void testMessageWithMapEntries() throws JMSException
@@ -186,12 +174,8 @@ public class AMQPEncodedMapMessageTest extends QpidBrokerTestCase
MapMessage m = _session.createMapMessage();
Map<String,String> myMap = getMap();
- m.setObject("Map", myMap);
-
- Map<String,UUID> uuidMap = new HashMap<String,UUID>();
- uuidMap.put("uuid", myUUID);
- m.setObject("uuid-map", uuidMap);
+ m.setObject("Map", myMap);
_producer.send(m);
AMQPEncodedMapMessage msg = (AMQPEncodedMapMessage)_consumer.receive(RECEIVE_TIMEOUT);
@@ -207,10 +191,6 @@ public class AMQPEncodedMapMessageTest extends QpidBrokerTestCase
assertEquals("String" + i,map.get("Key" + i));
i++;
}
-
- Map<String,UUID> map2 = (Map<String,UUID>)msg.getObject("uuid-map");
- assertNotNull("Map not received",map2);
- assertEquals(myUUID,map2.get("uuid"));
}
public void testMessageWithNestedListsAndMaps() throws JMSException
diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/jms/xa/XAResourceTest.java b/qpid/java/systests/src/main/java/org/apache/qpid/jms/xa/XAResourceTest.java
deleted file mode 100644
index d7ee203fdf..0000000000
--- a/qpid/java/systests/src/main/java/org/apache/qpid/jms/xa/XAResourceTest.java
+++ /dev/null
@@ -1,116 +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.jms.xa;
-
-import javax.jms.XAConnection;
-import javax.jms.XAConnectionFactory;
-import javax.jms.XASession;
-import javax.transaction.xa.XAResource;
-
-import org.apache.qpid.client.AMQConnectionFactory;
-import org.apache.qpid.jms.ConnectionURL;
-import org.apache.qpid.test.utils.QpidBrokerTestCase;
-import org.apache.qpid.util.FileUtils;
-
-public class XAResourceTest extends QpidBrokerTestCase
-{
-
- private static final String FACTORY_NAME = "default";
- private static final String ALT_FACTORY_NAME = "connection2";
-
- /*
- * Test with multiple XAResources originating from the same connection factory. XAResource(s) will be equal,
- * as they originate from the same session.
- */
- public void testIsSameRMSingleCF() throws Exception
- {
- XAConnectionFactory factory = getConnectionFactory(FACTORY_NAME);
- XAConnection conn = factory.createXAConnection();
- XASession session = conn.createXASession();
- XAResource xaResource1 = session.getXAResource();
- XAResource xaResource2 = session.getXAResource();
-
- assertEquals("XAResource objects not equal", xaResource1, xaResource2);
- assertTrue("isSameRM not true for identical objects", xaResource1.isSameRM(xaResource2));
-
- session.close();
- conn.close();
- }
-
- /*
- * Test with multiple XAResources originating from different connection factory's and different sessions. XAResources will not be
- * equal as they do not originate from the same session. As the UUID from the broker will be the same, isSameRM will be true.
- *
- */
- public void testIsSameRMMultiCF() throws Exception
- {
- startBroker(FAILING_PORT);
- ConnectionURL url = getConnectionFactory(FACTORY_NAME).getConnectionURL();
- XAConnectionFactory factory = new AMQConnectionFactory(url);
- XAConnectionFactory factory2 = new AMQConnectionFactory(url);
- XAConnectionFactory factory3 = getConnectionFactory(ALT_FACTORY_NAME);
-
- XAConnection conn = factory.createXAConnection();
- XAConnection conn2 = factory2.createXAConnection();
- XAConnection conn3 = factory3.createXAConnection();
-
- XASession session = conn.createXASession();
- XASession session2 = conn2.createXASession();
- XASession session3 = conn3.createXASession();
-
- XAResource xaResource1 = session.getXAResource();
- XAResource xaResource2 = session2.getXAResource();
- XAResource xaResource3 = session3.getXAResource();
-
- assertFalse("XAResource objects should not be equal", xaResource1.equals(xaResource2));
- assertTrue("isSameRM not true for identical objects", xaResource1.isSameRM(xaResource2));
- assertFalse("isSameRM true for XA Resources created by two different brokers", xaResource1.isSameRM(xaResource3));
-
- conn.close();
- conn2.close();
- conn3.close();
- }
-
- @Override
- public void stopBroker(int port) throws Exception
- {
- if (isBrokerPresent(port))
- {
- super.stopBroker(port);
- }
- }
-
- @Override
- public void tearDown() throws Exception
- {
- try
- {
- super.tearDown();
- }
- finally
- {
- // Ensure we shutdown any secondary brokers
- stopBroker(FAILING_PORT);
- FileUtils.deleteDirectory(System.getProperty("QPID_WORK") + "/" + getFailingPort());
- }
- }
-
-}
diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/management/jmx/MessageConnectionStatisticsTest.java b/qpid/java/systests/src/main/java/org/apache/qpid/management/jmx/MessageConnectionStatisticsTest.java
deleted file mode 100644
index 9839c6e475..0000000000
--- a/qpid/java/systests/src/main/java/org/apache/qpid/management/jmx/MessageConnectionStatisticsTest.java
+++ /dev/null
@@ -1,102 +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.jmx;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import javax.jms.Connection;
-
-import org.apache.qpid.client.AMQConnection;
-import org.apache.qpid.management.common.mbeans.ManagedBroker;
-import org.apache.qpid.management.common.mbeans.ManagedConnection;
-
-/**
- * Test enabling generation of message statistics on a per-connection basis.
- */
-public class MessageConnectionStatisticsTest extends MessageStatisticsTestCase
-{
- public void configureStatistics() throws Exception
- {
- // no statistics generation configured
- }
-
- /**
- * Test statistics on a single connection
- */
- public void testEnablingStatisticsPerConnection() throws Exception
- {
- ManagedBroker vhost = _jmxUtils.getManagedBroker("test");
-
- sendUsing(_test, 5, 200);
- Thread.sleep(1000);
-
- List<String> addresses = new ArrayList<String>();
- for (ManagedConnection mc : _jmxUtils.getManagedConnections("test"))
- {
- assertEquals("Incorrect connection total", 0, mc.getTotalMessagesReceived());
- assertEquals("Incorrect connection data", 0, mc.getTotalDataReceived());
- assertFalse("Connection statistics should not be enabled", mc.isStatisticsEnabled());
-
- addresses.add(mc.getRemoteAddress());
- }
- assertEquals("Incorrect vhost total", 0, vhost.getTotalMessagesReceived());
- assertEquals("Incorrect vhost data", 0, vhost.getTotalDataReceived());
-
- Connection test = new AMQConnection(_brokerUrl, USER, USER, "clientid", "test");
- test.start();
- for (ManagedConnection mc : _jmxUtils.getManagedConnections("test"))
- {
- if (addresses.contains(mc.getRemoteAddress()))
- {
- continue;
- }
- mc.setStatisticsEnabled(true);
- assertEquals("Incorrect connection total", 0, mc.getTotalMessagesReceived());
- assertEquals("Incorrect connection data", 0, mc.getTotalDataReceived());
- }
-
- sendUsing(test, 5, 200);
- sendUsing(_test, 5, 200);
- Thread.sleep(1000);
-
- for (ManagedConnection mc : _jmxUtils.getManagedConnections("test"))
- {
- if (addresses.contains(mc.getRemoteAddress()))
- {
- assertEquals("Incorrect connection total", 0, mc.getTotalMessagesReceived());
- assertEquals("Incorrect connection data", 0, mc.getTotalDataReceived());
- assertFalse("Connection statistics should not be enabled", mc.isStatisticsEnabled());
- }
- else
- {
- assertEquals("Incorrect connection total", 5, mc.getTotalMessagesReceived());
- assertEquals("Incorrect connection data", 1000, mc.getTotalDataReceived());
- assertTrue("Connection statistics should be enabled", mc.isStatisticsEnabled());
- }
- }
- assertEquals("Incorrect vhost total", 0, vhost.getTotalMessagesReceived());
- assertEquals("Incorrect vhost data", 0, vhost.getTotalDataReceived());
- assertFalse("Vhost statistics should not be enabled", vhost.isStatisticsEnabled());
-
- test.close();
- }
-}
diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/management/jmx/MessageStatisticsConfigurationTest.java b/qpid/java/systests/src/main/java/org/apache/qpid/management/jmx/MessageStatisticsConfigurationTest.java
deleted file mode 100644
index 383c4c00a8..0000000000
--- a/qpid/java/systests/src/main/java/org/apache/qpid/management/jmx/MessageStatisticsConfigurationTest.java
+++ /dev/null
@@ -1,162 +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.jmx;
-
-import org.apache.qpid.management.common.mbeans.ManagedBroker;
-import org.apache.qpid.management.common.mbeans.ManagedConnection;
-
-/**
- * Test enabling generation of message statistics on a per-connection basis.
- */
-public class MessageStatisticsConfigurationTest extends MessageStatisticsTestCase
-{
- public void configureStatistics() throws Exception
- {
- setConfigurationProperty("statistics.generation.broker", Boolean.toString(getName().contains("Broker")));
- setConfigurationProperty("statistics.generation.virtualhosts", Boolean.toString(getName().contains("Virtualhost")));
- setConfigurationProperty("statistics.generation.connections", Boolean.toString(getName().contains("Connection")));
- }
-
- /**
- * Just broker statistics.
- */
- public void testGenerateBrokerStatistics() throws Exception
- {
- sendUsing(_test, 5, 200);
- Thread.sleep(1000);
-
- for (ManagedConnection mc : _jmxUtils.getManagedConnections("test"))
- {
- assertEquals("Incorrect connection total", 0, mc.getTotalMessagesReceived());
- assertEquals("Incorrect connection data", 0, mc.getTotalDataReceived());
- assertFalse("Connection statistics should not be enabled", mc.isStatisticsEnabled());
- }
-
- ManagedBroker vhost = _jmxUtils.getManagedBroker("test");
- assertEquals("Incorrect vhost data", 0, vhost.getTotalMessagesReceived());
- assertEquals("Incorrect vhost data", 0, vhost.getTotalDataReceived());
- assertFalse("Vhost statistics should not be enabled", vhost.isStatisticsEnabled());
-
- assertEquals("Incorrect server total messages", 5, _jmxUtils.getServerInformation().getTotalMessagesReceived());
- assertEquals("Incorrect server total data", 1000, _jmxUtils.getServerInformation().getTotalDataReceived());
- assertTrue("Server statistics should be enabled", _jmxUtils.getServerInformation().isStatisticsEnabled());
- }
-
- /**
- * Just virtualhost statistics.
- */
- public void testGenerateVirtualhostStatistics() throws Exception
- {
- sendUsing(_test, 5, 200);
- Thread.sleep(1000);
-
- for (ManagedConnection mc : _jmxUtils.getManagedConnections("test"))
- {
- assertEquals("Incorrect connection total", 0, mc.getTotalMessagesReceived());
- assertEquals("Incorrect connection data", 0, mc.getTotalDataReceived());
- assertFalse("Connection statistics should not be enabled", mc.isStatisticsEnabled());
- }
-
- ManagedBroker vhost = _jmxUtils.getManagedBroker("test");
- assertEquals("Incorrect vhost data", 5, vhost.getTotalMessagesReceived());
- assertEquals("Incorrect vhost data", 1000, vhost.getTotalDataReceived());
- assertTrue("Vhost statistics should be enabled", vhost.isStatisticsEnabled());
-
- assertEquals("Incorrect server total messages", 0, _jmxUtils.getServerInformation().getTotalMessagesReceived());
- assertEquals("Incorrect server total data", 0, _jmxUtils.getServerInformation().getTotalDataReceived());
- assertFalse("Server statistics should not be enabled", _jmxUtils.getServerInformation().isStatisticsEnabled());
- }
-
- /**
- * Just connection statistics.
- */
- public void testGenerateConnectionStatistics() throws Exception
- {
- sendUsing(_test, 5, 200);
- Thread.sleep(1000);
-
- for (ManagedConnection mc : _jmxUtils.getManagedConnections("test"))
- {
- assertEquals("Incorrect connection total", 5, mc.getTotalMessagesReceived());
- assertEquals("Incorrect connection data", 1000, mc.getTotalDataReceived());
- assertTrue("Connection statistics should be enabled", mc.isStatisticsEnabled());
- }
-
- ManagedBroker vhost = _jmxUtils.getManagedBroker("test");
- assertEquals("Incorrect vhost data", 0, vhost.getTotalMessagesReceived());
- assertEquals("Incorrect vhost data", 0, vhost.getTotalDataReceived());
- assertFalse("Vhost statistics should not be enabled", vhost.isStatisticsEnabled());
-
- assertEquals("Incorrect server total messages", 0, _jmxUtils.getServerInformation().getTotalMessagesReceived());
- assertEquals("Incorrect server total data", 0, _jmxUtils.getServerInformation().getTotalDataReceived());
- assertFalse("Server statistics should not be enabled", _jmxUtils.getServerInformation().isStatisticsEnabled());
- }
-
- /**
- * Both broker and virtualhost statistics.
- */
- public void testGenerateBrokerAndVirtualhostStatistics() throws Exception
- {
- sendUsing(_test, 5, 200);
- Thread.sleep(1000);
-
- for (ManagedConnection mc : _jmxUtils.getManagedConnections("test"))
- {
- assertEquals("Incorrect connection total", 0, mc.getTotalMessagesReceived());
- assertEquals("Incorrect connection data", 0, mc.getTotalDataReceived());
- assertFalse("Connection statistics should not be enabled", mc.isStatisticsEnabled());
- }
-
- ManagedBroker vhost = _jmxUtils.getManagedBroker("test");
- assertEquals("Incorrect vhost data", 5, vhost.getTotalMessagesReceived());
- assertEquals("Incorrect vhost data", 1000, vhost.getTotalDataReceived());
- assertTrue("Vhost statistics should be enabled", vhost.isStatisticsEnabled());
-
- assertEquals("Incorrect server total messages", 5, _jmxUtils.getServerInformation().getTotalMessagesReceived());
- assertEquals("Incorrect server total data", 1000, _jmxUtils.getServerInformation().getTotalDataReceived());
- assertTrue("Server statistics should be enabled", _jmxUtils.getServerInformation().isStatisticsEnabled());
- }
-
- /**
- * Broker, virtualhost and connection statistics.
- */
- public void testGenerateBrokerVirtualhostAndConnectionStatistics() throws Exception
- {
- sendUsing(_test, 5, 200);
- Thread.sleep(1000);
-
- for (ManagedConnection mc : _jmxUtils.getManagedConnections("test"))
- {
- assertEquals("Incorrect connection total", 5, mc.getTotalMessagesReceived());
- assertEquals("Incorrect connection data", 1000, mc.getTotalDataReceived());
- assertTrue("Connection statistics should be enabled", mc.isStatisticsEnabled());
- }
-
- ManagedBroker vhost = _jmxUtils.getManagedBroker("test");
- assertEquals("Incorrect vhost data", 5, vhost.getTotalMessagesReceived());
- assertEquals("Incorrect vhost data", 1000, vhost.getTotalDataReceived());
- assertTrue("Vhost statistics should be enabled", vhost.isStatisticsEnabled());
-
- assertEquals("Incorrect server total messages", 5, _jmxUtils.getServerInformation().getTotalMessagesReceived());
- assertEquals("Incorrect server total data", 1000, _jmxUtils.getServerInformation().getTotalDataReceived());
- assertTrue("Server statistics should be enabled", _jmxUtils.getServerInformation().isStatisticsEnabled());
- }
-}
diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/management/jmx/MessageStatisticsDeliveryTest.java b/qpid/java/systests/src/main/java/org/apache/qpid/management/jmx/MessageStatisticsDeliveryTest.java
deleted file mode 100644
index e657856d0e..0000000000
--- a/qpid/java/systests/src/main/java/org/apache/qpid/management/jmx/MessageStatisticsDeliveryTest.java
+++ /dev/null
@@ -1,110 +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.jmx;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import javax.jms.Connection;
-import javax.jms.Message;
-import javax.jms.MessageConsumer;
-import javax.jms.Session;
-
-import org.apache.qpid.client.AMQConnection;
-import org.apache.qpid.management.common.mbeans.ManagedBroker;
-import org.apache.qpid.management.common.mbeans.ManagedConnection;
-
-/**
- * Test statistics for delivery and receipt.
- */
-public class MessageStatisticsDeliveryTest extends MessageStatisticsTestCase
-{
- public void configureStatistics() throws Exception
- {
- setConfigurationProperty("statistics.generation.broker", "true");
- setConfigurationProperty("statistics.generation.virtualhosts", "true");
- setConfigurationProperty("statistics.generation.connections", "true");
- }
-
- public void testDeliveryAndReceiptStatistics() throws Exception
- {
- ManagedBroker vhost = _jmxUtils.getManagedBroker("test");
-
- sendUsing(_test, 5, 200);
- Thread.sleep(1000);
-
- List<String> addresses = new ArrayList<String>();
- for (ManagedConnection mc : _jmxUtils.getManagedConnections("test"))
- {
- assertEquals("Incorrect connection delivery total", 0, mc.getTotalMessagesDelivered());
- assertEquals("Incorrect connection delivery data", 0, mc.getTotalDataDelivered());
- assertEquals("Incorrect connection receipt total", 5, mc.getTotalMessagesReceived());
- assertEquals("Incorrect connection receipt data", 1000, mc.getTotalDataReceived());
-
- addresses.add(mc.getRemoteAddress());
- }
-
- assertEquals("Incorrect vhost delivery total", 0, vhost.getTotalMessagesDelivered());
- assertEquals("Incorrect vhost delivery data", 0, vhost.getTotalDataDelivered());
- assertEquals("Incorrect vhost receipt total", 5, vhost.getTotalMessagesReceived());
- assertEquals("Incorrect vhost receipt data", 1000, vhost.getTotalDataReceived());
-
- Connection test = new AMQConnection(_brokerUrl, USER, USER, "clientid", "test");
- test.start();
- receiveUsing(test, 5);
-
- for (ManagedConnection mc : _jmxUtils.getManagedConnections("test"))
- {
- if (addresses.contains(mc.getRemoteAddress()))
- {
- assertEquals("Incorrect connection delivery total", 0, mc.getTotalMessagesDelivered());
- assertEquals("Incorrect connection delivery data", 0, mc.getTotalDataDelivered());
- assertEquals("Incorrect connection receipt total", 5, mc.getTotalMessagesReceived());
- assertEquals("Incorrect connection receipt data", 1000, mc.getTotalDataReceived());
- }
- else
- {
- assertEquals("Incorrect connection delivery total", 5, mc.getTotalMessagesDelivered());
- assertEquals("Incorrect connection delivery data", 1000, mc.getTotalDataDelivered());
- assertEquals("Incorrect connection receipt total", 0, mc.getTotalMessagesReceived());
- assertEquals("Incorrect connection receipt data", 0, mc.getTotalDataReceived());
- }
- }
- assertEquals("Incorrect vhost delivery total", 5, vhost.getTotalMessagesDelivered());
- assertEquals("Incorrect vhost delivery data", 1000, vhost.getTotalDataDelivered());
- assertEquals("Incorrect vhost receipt total", 5, vhost.getTotalMessagesReceived());
- assertEquals("Incorrect vhost receipt data", 1000, vhost.getTotalDataReceived());
-
- test.close();
- }
-
- protected void receiveUsing(Connection con, int number) throws Exception
- {
- Session session = con.createSession(false, Session.AUTO_ACKNOWLEDGE);
- createQueue(session);
- MessageConsumer consumer = session.createConsumer(_queue);
- for (int i = 0; i < number; i++)
- {
- Message msg = consumer.receive(100);
- assertNotNull("Message " + i + " was not received", msg);
- }
- }
-}
diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/management/jmx/MessageStatisticsReportingTest.java b/qpid/java/systests/src/main/java/org/apache/qpid/management/jmx/MessageStatisticsReportingTest.java
deleted file mode 100644
index 180440c0d6..0000000000
--- a/qpid/java/systests/src/main/java/org/apache/qpid/management/jmx/MessageStatisticsReportingTest.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.jmx;
-
-import java.util.List;
-
-import org.apache.qpid.util.LogMonitor;
-
-/**
- * Test generation of message statistics reporting.
- */
-public class MessageStatisticsReportingTest extends MessageStatisticsTestCase
-{
- protected LogMonitor _monitor;
-
- public void configureStatistics() throws Exception
- {
- setConfigurationProperty("statistics.generation.broker", "true");
- setConfigurationProperty("statistics.generation.virtualhosts", "true");
-
- if (getName().equals("testEnabledStatisticsReporting"))
- {
- setConfigurationProperty("statistics.reporting.period", "10");
- }
-
- _monitor = new LogMonitor(_outputFile);
- }
-
- /**
- * Test enabling reporting.
- */
- public void testEnabledStatisticsReporting() throws Exception
- {
- sendUsing(_test, 10, 100);
- sendUsing(_dev, 20, 100);
- sendUsing(_local, 15, 100);
-
- Thread.sleep(10 * 1000); // 15s
-
- List<String> brokerStatsData = _monitor.findMatches("BRK-1008");
- List<String> brokerStatsMessages = _monitor.findMatches("BRK-1009");
- List<String> vhostStatsData = _monitor.findMatches("VHT-1003");
- List<String> vhostStatsMessages = _monitor.findMatches("VHT-1004");
-
- assertEquals("Incorrect number of broker data stats log messages", 2, brokerStatsData.size());
- assertEquals("Incorrect number of broker message stats log messages", 2, brokerStatsMessages.size());
- assertEquals("Incorrect number of virtualhost data stats log messages", 6, vhostStatsData.size());
- assertEquals("Incorrect number of virtualhost message stats log messages", 6, vhostStatsMessages.size());
- }
-
- /**
- * Test not enabling reporting.
- */
- public void testNotEnabledStatisticsReporting() throws Exception
- {
- sendUsing(_test, 10, 100);
- sendUsing(_dev, 20, 100);
- sendUsing(_local, 15, 100);
-
- Thread.sleep(10 * 1000); // 15s
-
- List<String> brokerStatsData = _monitor.findMatches("BRK-1008");
- List<String> brokerStatsMessages = _monitor.findMatches("BRK-1009");
- List<String> vhostStatsData = _monitor.findMatches("VHT-1003");
- List<String> vhostStatsMessages = _monitor.findMatches("VHT-1004");
-
- assertEquals("Incorrect number of broker data stats log messages", 0, brokerStatsData.size());
- assertEquals("Incorrect number of broker message stats log messages", 0, brokerStatsMessages.size());
- assertEquals("Incorrect number of virtualhost data stats log messages", 0, vhostStatsData.size());
- assertEquals("Incorrect number of virtualhost message stats log messages", 0, vhostStatsMessages.size());
- }
-}
diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/management/jmx/MessageStatisticsTest.java b/qpid/java/systests/src/main/java/org/apache/qpid/management/jmx/MessageStatisticsTest.java
deleted file mode 100644
index 824ae41b97..0000000000
--- a/qpid/java/systests/src/main/java/org/apache/qpid/management/jmx/MessageStatisticsTest.java
+++ /dev/null
@@ -1,218 +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.jmx;
-
-import javax.jms.Connection;
-
-import org.apache.qpid.client.AMQConnection;
-import org.apache.qpid.management.common.mbeans.ManagedBroker;
-import org.apache.qpid.management.common.mbeans.ManagedConnection;
-
-/**
- * Test generation of message statistics.
- */
-public class MessageStatisticsTest extends MessageStatisticsTestCase
-{
- public void configureStatistics() throws Exception
- {
- setConfigurationProperty("statistics.generation.broker", "true");
- setConfigurationProperty("statistics.generation.virtualhosts", "true");
- setConfigurationProperty("statistics.generation.connections", "true");
- }
-
- /**
- * Test message totals.
- */
- public void testMessageTotals() throws Exception
- {
- sendUsing(_test, 10, 100);
- sendUsing(_dev, 20, 100);
- sendUsing(_local, 5, 100);
- sendUsing(_local, 5, 100);
- sendUsing(_local, 5, 100);
- Thread.sleep(2000);
-
- ManagedBroker test = _jmxUtils.getManagedBroker("test");
- ManagedBroker dev = _jmxUtils.getManagedBroker("development");
- ManagedBroker local = _jmxUtils.getManagedBroker("localhost");
-
- if (!isBroker010())
- {
- long total = 0;
- long data = 0;
- for (ManagedConnection mc : _jmxUtils.getAllManagedConnections())
- {
- total += mc.getTotalMessagesReceived();
- data += mc.getTotalDataReceived();
- }
- assertEquals("Incorrect connection total", 45, total);
- assertEquals("Incorrect connection data", 4500, data);
- }
- assertEquals("Incorrect server total", 45, _jmxUtils.getServerInformation().getTotalMessagesReceived());
- assertEquals("Incorrect server data", 4500, _jmxUtils.getServerInformation().getTotalDataReceived());
-
- if (!isBroker010())
- {
- long testTotal = 0;
- long testData = 0;
- for (ManagedConnection mc : _jmxUtils.getManagedConnections("test"))
- {
- testTotal += mc.getTotalMessagesReceived();
- testData += mc.getTotalDataReceived();
- }
- assertEquals("Incorrect test connection total", 10, testTotal);
- assertEquals("Incorrect test connection data", 1000, testData);
- }
- assertEquals("Incorrect test vhost total", 10, test.getTotalMessagesReceived());
- assertEquals("Incorrect test vhost data", 1000, test.getTotalDataReceived());
-
- if (!isBroker010())
- {
- long devTotal = 0;
- long devData = 0;
- for (ManagedConnection mc : _jmxUtils.getManagedConnections("development"))
- {
- devTotal += mc.getTotalMessagesReceived();
- devData += mc.getTotalDataReceived();
- }
- assertEquals("Incorrect test connection total", 20, devTotal);
- assertEquals("Incorrect test connection data", 2000, devData);
- }
- assertEquals("Incorrect development total", 20, dev.getTotalMessagesReceived());
- assertEquals("Incorrect development data", 2000, dev.getTotalDataReceived());
-
- if (!isBroker010())
- {
- long localTotal = 0;
- long localData = 0;
- for (ManagedConnection mc : _jmxUtils.getManagedConnections("localhost"))
- {
- localTotal += mc.getTotalMessagesReceived();
- localData += mc.getTotalDataReceived();
- }
- assertEquals("Incorrect test connection total", 15, localTotal);
- assertEquals("Incorrect test connection data", 1500, localData);
- }
- assertEquals("Incorrect localhost total", 15, local.getTotalMessagesReceived());
- assertEquals("Incorrect localhost data", 1500, local.getTotalDataReceived());
- }
-
- /**
- * Test message totals when a connection is closed.
- */
- public void testMessageTotalsWithClosedConnections() throws Exception
- {
- Connection temp = new AMQConnection(_brokerUrl, USER, USER, "clientid", "test");
- temp.start();
-
- sendUsing(_test, 10, 100);
- sendUsing(temp, 10, 100);
- sendUsing(_test, 10, 100);
- Thread.sleep(2000);
-
- temp.close();
-
- ManagedBroker test = _jmxUtils.getManagedBroker("test");
-
- if (!isBroker010())
- {
- long total = 0;
- long data = 0;
- for (ManagedConnection mc : _jmxUtils.getAllManagedConnections())
- {
- total += mc.getTotalMessagesReceived();
- data += mc.getTotalDataReceived();
- }
- assertEquals("Incorrect active connection total", 20, total);
- assertEquals("Incorrect active connection data", 2000, data);
- }
- assertEquals("Incorrect server total", 30, _jmxUtils.getServerInformation().getTotalMessagesReceived());
- assertEquals("Incorrect server data", 3000, _jmxUtils.getServerInformation().getTotalDataReceived());
-
- if (!isBroker010())
- {
- long testTotal = 0;
- long testData = 0;
- for (ManagedConnection mc : _jmxUtils.getManagedConnections("test"))
- {
- testTotal += mc.getTotalMessagesReceived();
- testData += mc.getTotalDataReceived();
- }
- assertEquals("Incorrect test active connection total", 20, testTotal);
- assertEquals("Incorrect test active connection data", 20 * 100, testData);
- }
- assertEquals("Incorrect test vhost total", 30, test.getTotalMessagesReceived());
- assertEquals("Incorrect test vhost data", 30 * 100, test.getTotalDataReceived());
- }
-
- /**
- * Test message peak rate generation.
- */
- public void testMessagePeakRates() throws Exception
- {
- sendUsing(_test, 2, 10);
- Thread.sleep(10000);
- sendUsing(_dev, 4, 10);
- Thread.sleep(10000);
-
- ManagedBroker test = _jmxUtils.getManagedBroker("test");
- ManagedBroker dev = _jmxUtils.getManagedBroker("development");
-
- assertApprox("Incorrect test vhost peak messages", 0.2d, 1.0d, test.getPeakMessageReceiptRate());
- assertApprox("Incorrect test vhost peak data", 0.2d, 10.0d, test.getPeakDataReceiptRate());
- assertApprox("Incorrect dev vhost peak messages", 0.2d, 2.0d, dev.getPeakMessageReceiptRate());
- assertApprox("Incorrect dev vhost peak data", 0.2d, 20.0d, dev.getPeakDataReceiptRate());
-
- assertApprox("Incorrect server peak messages", 0.2d, 2.0d, _jmxUtils.getServerInformation().getPeakMessageReceiptRate());
- assertApprox("Incorrect server peak data", 0.2d, 20.0d, _jmxUtils.getServerInformation().getPeakDataReceiptRate());
- }
-
- /**
- * Test message totals when a vhost has its statistics reset
- */
- public void testMessageTotalVhostReset() throws Exception
- {
- sendUsing(_test, 10, 10);
- sendUsing(_dev, 10, 10);
- Thread.sleep(2000);
-
- ManagedBroker test = _jmxUtils.getManagedBroker("test");
- ManagedBroker dev = _jmxUtils.getManagedBroker("development");
-
- assertEquals("Incorrect test vhost total messages", 10, test.getTotalMessagesReceived());
- assertEquals("Incorrect test vhost total data", 100, test.getTotalDataReceived());
- assertEquals("Incorrect dev vhost total messages", 10, dev.getTotalMessagesReceived());
- assertEquals("Incorrect dev vhost total data", 100, dev.getTotalDataReceived());
-
- assertEquals("Incorrect server total messages", 20, _jmxUtils.getServerInformation().getTotalMessagesReceived());
- assertEquals("Incorrect server total data", 200, _jmxUtils.getServerInformation().getTotalDataReceived());
-
- test.resetStatistics();
-
- assertEquals("Incorrect test vhost total messages", 0, test.getTotalMessagesReceived());
- assertEquals("Incorrect test vhost total data", 0, test.getTotalDataReceived());
- assertEquals("Incorrect dev vhost total messages", 10, dev.getTotalMessagesReceived());
- assertEquals("Incorrect dev vhost total data", 100, dev.getTotalDataReceived());
-
- assertEquals("Incorrect server total messages", 20, _jmxUtils.getServerInformation().getTotalMessagesReceived());
- assertEquals("Incorrect server total data", 200, _jmxUtils.getServerInformation().getTotalDataReceived());
- }
-}
diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/management/jmx/MessageStatisticsTestCase.java b/qpid/java/systests/src/main/java/org/apache/qpid/management/jmx/MessageStatisticsTestCase.java
deleted file mode 100644
index a5b3aa283c..0000000000
--- a/qpid/java/systests/src/main/java/org/apache/qpid/management/jmx/MessageStatisticsTestCase.java
+++ /dev/null
@@ -1,128 +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.jmx;
-
-import javax.jms.Connection;
-import javax.jms.Destination;
-import javax.jms.JMSException;
-import javax.jms.MessageProducer;
-import javax.jms.Session;
-import javax.jms.TextMessage;
-
-import org.apache.qpid.AMQException;
-import org.apache.qpid.client.AMQConnection;
-import org.apache.qpid.client.AMQDestination;
-import org.apache.qpid.client.AMQQueue;
-import org.apache.qpid.client.AMQSession;
-import org.apache.qpid.exchange.ExchangeDefaults;
-import org.apache.qpid.framing.AMQShortString;
-import org.apache.qpid.test.utils.JMXTestUtils;
-import org.apache.qpid.test.utils.QpidBrokerTestCase;
-
-/**
- * Test generation of message statistics.
- */
-public abstract class MessageStatisticsTestCase extends QpidBrokerTestCase
-{
- protected static final String USER = "admin";
-
- protected JMXTestUtils _jmxUtils;
- protected Connection _test, _dev, _local;
- protected String _queueName = "statistics";
- protected Destination _queue;
- protected String _brokerUrl;
-
- @Override
- public void setUp() throws Exception
- {
- _jmxUtils = new JMXTestUtils(this, USER, USER);
- _jmxUtils.setUp();
-
- configureStatistics();
-
- super.setUp();
-
- _brokerUrl = getBroker().toString();
- _test = new AMQConnection(_brokerUrl, USER, USER, "clientid", "test");
- _dev = new AMQConnection(_brokerUrl, USER, USER, "clientid", "development");
- _local = new AMQConnection(_brokerUrl, USER, USER, "clientid", "localhost");
-
- _test.start();
- _dev.start();
- _local.start();
-
- _jmxUtils.open();
- }
-
- protected void createQueue(Session session) throws AMQException, JMSException
- {
- _queue = new AMQQueue(ExchangeDefaults.DIRECT_EXCHANGE_NAME, _queueName);
- if (!((AMQSession<?,?>) session).isQueueBound((AMQDestination) _queue))
- {
- ((AMQSession<?,?>) session).createQueue(new AMQShortString(_queueName), false, true, false, null);
- ((AMQSession<?,?>) session).declareAndBind((AMQDestination) new AMQQueue(ExchangeDefaults.DIRECT_EXCHANGE_NAME, _queueName));
- }
- }
-
-
- @Override
- public void tearDown() throws Exception
- {
- _jmxUtils.close();
-
- _test.close();
- _dev.close();
- _local.close();
-
- super.tearDown();
- }
-
- /**
- * Configure statistics generation properties on the broker.
- */
- public abstract void configureStatistics() throws Exception;
-
- protected void sendUsing(Connection con, int number, int size) throws Exception
- {
- Session session = con.createSession(false, Session.AUTO_ACKNOWLEDGE);
- createQueue(session);
- MessageProducer producer = session.createProducer(_queue);
- String content = new String(new byte[size]);
- TextMessage msg = session.createTextMessage(content);
- for (int i = 0; i < number; i++)
- {
- producer.send(msg);
- }
- }
-
- /**
- * Asserts that the actual value is within the expected value plus or
- * minus the given error.
- */
- public void assertApprox(String message, double error, double expected, double actual)
- {
- double min = expected * (1.0d - error);
- double max = expected * (1.0d + error);
- String assertion = String.format("%s: expected %f +/- %d%%, actual %f",
- message, expected, (int) (error * 100.0d), actual);
- assertTrue(assertion, actual > min && actual < max);
- }
-}
diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/server/BrokerStartupTest.java b/qpid/java/systests/src/main/java/org/apache/qpid/server/BrokerStartupTest.java
index 27b4de0a8e..f9227c53ba 100644
--- a/qpid/java/systests/src/main/java/org/apache/qpid/server/BrokerStartupTest.java
+++ b/qpid/java/systests/src/main/java/org/apache/qpid/server/BrokerStartupTest.java
@@ -70,13 +70,13 @@ public class BrokerStartupTest extends AbstractTestLogging
{
// This logging startup code only occurs when you run a Java broker,
// that broker must be started via Main so not an InVM broker.
- if (isJavaBroker() && isExternalBroker() && !isInternalBroker())
+ if (isJavaBroker() && isExternalBroker())
{
//Remove test Log4j config from the commandline
- _brokerCommand = _brokerCommand.substring(0, _brokerCommand.indexOf("-l"));
+ _broker = _broker.substring(0, _broker.indexOf("-l"));
// Add an invalid value
- _brokerCommand += " -l invalid";
+ _broker += " -l invalid";
// The broker has a built in default log4j configuration set up
// so if the the broker cannot load the -l value it will use default
diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/server/configuration/ServerConfigurationFileTest.java b/qpid/java/systests/src/main/java/org/apache/qpid/server/configuration/ServerConfigurationFileTest.java
index 6d379e14d8..d4c550bc08 100644
--- a/qpid/java/systests/src/main/java/org/apache/qpid/server/configuration/ServerConfigurationFileTest.java
+++ b/qpid/java/systests/src/main/java/org/apache/qpid/server/configuration/ServerConfigurationFileTest.java
@@ -61,6 +61,21 @@ public class ServerConfigurationFileTest extends QpidBrokerTestCase
_serverConfig.getConfig().getProperty(property));
}
+ public void testProtectIOEnabled() throws ConfigurationException
+ {
+ validatePropertyDefinedInFile(ServerConfiguration.CONNECTOR_PROTECTIO_ENABLED);
+ }
+
+ public void testProtectIOReadBufferLimitSize() throws ConfigurationException
+ {
+ validatePropertyDefinedInFile(ServerConfiguration.CONNECTOR_PROTECTIO_READ_BUFFER_LIMIT_SIZE);
+ }
+
+ public void testProtectIOWriteBufferLimitSize() throws ConfigurationException
+ {
+ validatePropertyDefinedInFile(ServerConfiguration.CONNECTOR_PROTECTIO_WRITE_BUFFER_LIMIT_SIZE);
+ }
+
public void testStatusUpdates() throws ConfigurationException
{
validatePropertyDefinedInFile(ServerConfiguration.STATUS_UPDATES);
diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/server/exchange/MessagingTestConfigProperties.java b/qpid/java/systests/src/main/java/org/apache/qpid/server/exchange/MessagingTestConfigProperties.java
index 4a92f04b30..2d89d319d7 100644
--- a/qpid/java/systests/src/main/java/org/apache/qpid/server/exchange/MessagingTestConfigProperties.java
+++ b/qpid/java/systests/src/main/java/org/apache/qpid/server/exchange/MessagingTestConfigProperties.java
@@ -83,9 +83,15 @@ public class MessagingTestConfigProperties
/** Holds the name of the default connection factory configuration property. */
public static final String CONNECTION_PROPNAME = "connectionfactory.broker";
+ /** Defeins the default connection configuration. */
+ public static final String CONNECTION_DEFAULT = "amqp://guest:guest@clientid/?brokerlist='vm://:1'";
+
/** Holds the name of the property to get the test broker url from. */
public static final String BROKER_PROPNAME = "qpid.test.broker";
+ /** Holds the default broker url for the test. */
+ public static final String BROKER_DEFAULT = "vm://:1";
+
/** Holds the name of the property to get the test broker virtual path. */
public static final String VIRTUAL_HOST_PROPNAME = "virtualHost";
@@ -268,6 +274,7 @@ public class MessagingTestConfigProperties
static
{
defaults.setPropertyIfNull(INITIAL_CONTEXT_FACTORY_PROPNAME, INITIAL_CONTEXT_FACTORY_DEFAULT);
+ defaults.setPropertyIfNull(CONNECTION_PROPNAME, CONNECTION_DEFAULT);
defaults.setPropertyIfNull(MESSAGE_SIZE_PROPNAME, MESSAGE_SIZE_DEAFULT);
defaults.setPropertyIfNull(PUBLISHER_PRODUCER_BIND_PROPNAME, PUBLISHER_PRODUCER_BIND_DEFAULT);
defaults.setPropertyIfNull(PUBLISHER_CONSUMER_BIND_PROPNAME, PUBLISHER_CONSUMER_BIND_DEFAULT);
@@ -277,6 +284,7 @@ public class MessagingTestConfigProperties
defaults.setPropertyIfNull(RECEIVE_DESTINATION_NAME_ROOT_PROPNAME, RECEIVE_DESTINATION_NAME_ROOT_DEFAULT);
defaults.setPropertyIfNull(PERSISTENT_MODE_PROPNAME, PERSISTENT_MODE_DEFAULT);
defaults.setPropertyIfNull(TRANSACTED_PROPNAME, TRANSACTED_DEFAULT);
+ defaults.setPropertyIfNull(BROKER_PROPNAME, BROKER_DEFAULT);
defaults.setPropertyIfNull(VIRTUAL_HOST_PROPNAME, VIRTUAL_HOST_DEFAULT);
defaults.setPropertyIfNull(RATE_PROPNAME, RATE_DEFAULT);
defaults.setPropertyIfNull(VERBOSE_PROPNAME, VERBOSE_DEFAULT);
diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/server/failover/FailoverMethodTest.java b/qpid/java/systests/src/main/java/org/apache/qpid/server/failover/FailoverMethodTest.java
index 11db513e00..ec222ff03d 100644
--- a/qpid/java/systests/src/main/java/org/apache/qpid/server/failover/FailoverMethodTest.java
+++ b/qpid/java/systests/src/main/java/org/apache/qpid/server/failover/FailoverMethodTest.java
@@ -20,39 +20,58 @@
*/
package org.apache.qpid.server.failover;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-
-import javax.jms.ExceptionListener;
-import javax.jms.JMSException;
+import junit.framework.TestCase;
import org.apache.qpid.AMQDisconnectedException;
import org.apache.qpid.AMQException;
import org.apache.qpid.client.AMQConnection;
import org.apache.qpid.client.AMQConnectionURL;
-import org.apache.qpid.test.utils.QpidBrokerTestCase;
+import org.apache.qpid.client.transport.TransportConnection;
+import org.apache.qpid.client.vmbroker.AMQVMBrokerCreationException;
+import org.apache.qpid.server.registry.ApplicationRegistry;
+import org.apache.qpid.server.util.InternalBrokerBaseCase;
+import org.apache.qpid.url.URLSyntaxException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-public class FailoverMethodTest extends QpidBrokerTestCase implements ExceptionListener
+import javax.jms.ExceptionListener;
+import javax.jms.JMSException;
+import java.util.concurrent.CountDownLatch;
+
+public class FailoverMethodTest extends InternalBrokerBaseCase implements ExceptionListener
{
private CountDownLatch _failoverComplete = new CountDownLatch(1);
protected static final Logger _logger = LoggerFactory.getLogger(FailoverMethodTest.class);
+ @Override
+ public void createBroker() throws Exception
+ {
+ super.createBroker();
+ TransportConnection.createVMBroker(ApplicationRegistry.DEFAULT_INSTANCE);
+ }
+ @Override
+ public void stopBroker()
+ {
+ TransportConnection.killVMBroker(ApplicationRegistry.DEFAULT_INSTANCE);
+ super.stopBroker();
+ }
/**
* Test that the round robin method has the correct delays.
- * The first connection will work but the localhost connection should fail but the duration it takes
+ * The first connection to vm://:1 will work but the localhost connection should fail but the duration it takes
* to report the failure is what is being tested.
*
+ * @throws URLSyntaxException
+ * @throws InterruptedException
+ * @throws JMSException
*/
- public void testFailoverRoundRobinDelay() throws Exception
+ public void testFailoverRoundRobinDelay() throws URLSyntaxException, InterruptedException, JMSException
{
- //note: The first broker has no connect delay and the default 1 retry
+ //note: The VM broker has no connect delay and the default 1 retry
// while the tcp:localhost broker has 3 retries with a 2s connect delay
String connectionString = "amqp://guest:guest@/test?brokerlist=" +
- "'tcp://:" + getPort() +
+ "'vm://:" + ApplicationRegistry.DEFAULT_INSTANCE +
";tcp://localhost:5670?connectdelay='2000',retries='3''";
AMQConnectionURL url = new AMQConnectionURL(connectionString);
@@ -66,9 +85,7 @@ public class FailoverMethodTest extends QpidBrokerTestCase implements ExceptionL
stopBroker();
- _failoverComplete.await(30, TimeUnit.SECONDS);
- assertEquals("failoverLatch was not decremented in given timeframe",
- 0, _failoverComplete.getCount());
+ _failoverComplete.await();
long end = System.currentTimeMillis();
@@ -95,9 +112,10 @@ public class FailoverMethodTest extends QpidBrokerTestCase implements ExceptionL
}
}
- public void testFailoverSingleDelay() throws Exception
+ public void testFailoverSingleDelay() throws URLSyntaxException, AMQVMBrokerCreationException,
+ InterruptedException, JMSException
{
- String connectionString = "amqp://guest:guest@/test?brokerlist='tcp://localhost:" + getPort() + "?connectdelay='2000',retries='3''";
+ String connectionString = "amqp://guest:guest@/test?brokerlist='vm://:1?connectdelay='2000',retries='3''";
AMQConnectionURL url = new AMQConnectionURL(connectionString);
@@ -110,9 +128,7 @@ public class FailoverMethodTest extends QpidBrokerTestCase implements ExceptionL
stopBroker();
- _failoverComplete.await(30, TimeUnit.SECONDS);
- assertEquals("failoverLatch was not decremented in given timeframe",
- 0, _failoverComplete.getCount());
+ _failoverComplete.await();
long end = System.currentTimeMillis();
@@ -144,10 +160,6 @@ public class FailoverMethodTest extends QpidBrokerTestCase implements ExceptionL
_logger.debug("Received AMQDisconnectedException");
_failoverComplete.countDown();
}
- else
- {
- _logger.error("Unexpected underlying exception", e.getLinkedException());
- }
}
/**
@@ -156,37 +168,28 @@ public class FailoverMethodTest extends QpidBrokerTestCase implements ExceptionL
*
* Test validates that there is a connection delay as required on initial
* connection.
+ *
+ * @throws URLSyntaxException
+ * @throws AMQVMBrokerCreationException
+ * @throws InterruptedException
+ * @throws JMSException
*/
- public void testNoFailover() throws Exception
+ public void testNoFailover() throws URLSyntaxException, AMQVMBrokerCreationException,
+ InterruptedException, JMSException
{
- if (!isInternalBroker())
- {
- // QPID-3359
- // These tests always used to be inVM tests, then QPID-2815, with removal of ivVM,
- // converted the test to use QpidBrokerTestCase. However, since then we notice this
- // test fails on slower CI boxes. It turns out the test design is *extremely*
- // sensitive the length of time the broker takes to start up.
- //
- // Making the test a same-VM test to temporarily avoid the issue. In long term, test
- // needs redesigned to avoid the issue.
- return;
- }
-
int CONNECT_DELAY = 2000;
- String connectionString = "amqp://guest:guest@/test?brokerlist='tcp://localhost:" + getPort() + "?connectdelay='" + CONNECT_DELAY + "'," +
+ String connectionString = "amqp://guest:guest@/test?brokerlist='vm://:1?connectdelay='" + CONNECT_DELAY + "'," +
"retries='3'',failover='nofailover'";
-
AMQConnectionURL url = new AMQConnectionURL(connectionString);
- Thread brokerStart = null;
try
{
//Kill initial broker
stopBroker();
//Create a thread to start the broker asynchronously
- brokerStart = new Thread(new Runnable()
+ Thread brokerStart = new Thread(new Runnable()
{
public void run()
{
@@ -195,7 +198,7 @@ public class FailoverMethodTest extends QpidBrokerTestCase implements ExceptionL
//Wait before starting broker
// The wait should allow atleast 1 retries to fail before broker is ready
Thread.sleep(750);
- startBroker();
+ createBroker();
}
catch (Exception e)
{
@@ -209,6 +212,7 @@ public class FailoverMethodTest extends QpidBrokerTestCase implements ExceptionL
brokerStart.start();
long start = System.currentTimeMillis();
+
//Start the connection so it will use the retries
AMQConnection connection = new AMQConnection(url, null);
@@ -224,16 +228,13 @@ public class FailoverMethodTest extends QpidBrokerTestCase implements ExceptionL
//Ensure we collect the brokerStart thread
brokerStart.join();
- brokerStart = null;
start = System.currentTimeMillis();
//Kill connection
stopBroker();
- _failoverComplete.await(30, TimeUnit.SECONDS);
- assertEquals("failoverLatch was not decremented in given timeframe",
- 0, _failoverComplete.getCount());
+ _failoverComplete.await();
end = System.currentTimeMillis();
@@ -248,23 +249,6 @@ public class FailoverMethodTest extends QpidBrokerTestCase implements ExceptionL
{
fail(e.getMessage());
}
- finally
- {
- // Guard against the case where the broker took too long to start
- // and the initial connection failed to be formed.
- if (brokerStart != null)
- {
- brokerStart.join();
- }
- }
- }
-
- public void stopBroker(int port) throws Exception
- {
- if (isBrokerPresent(port))
- {
- super.stopBroker(port);
- }
}
}
diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/server/logging/AlertingTest.java b/qpid/java/systests/src/main/java/org/apache/qpid/server/logging/AlertingTest.java
index 58b2edfee2..05aaf16af1 100644
--- a/qpid/java/systests/src/main/java/org/apache/qpid/server/logging/AlertingTest.java
+++ b/qpid/java/systests/src/main/java/org/apache/qpid/server/logging/AlertingTest.java
@@ -176,7 +176,7 @@ public class AlertingTest extends AbstractTestLogging
startBroker();
- if (isInternalBroker())
+ if (!isExternalBroker())
{
assertEquals("Alert Max Msg Count is not correct", 5, ApplicationRegistry.getInstance().getVirtualHostRegistry().
getVirtualHost(VIRTUALHOST).getQueueRegistry().getQueue(new AMQShortString(_destination.getQueueName())).
diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/server/logging/BrokerLoggingTest.java b/qpid/java/systests/src/main/java/org/apache/qpid/server/logging/BrokerLoggingTest.java
index 9155b84365..8fd2c085c3 100644
--- a/qpid/java/systests/src/main/java/org/apache/qpid/server/logging/BrokerLoggingTest.java
+++ b/qpid/java/systests/src/main/java/org/apache/qpid/server/logging/BrokerLoggingTest.java
@@ -21,8 +21,6 @@
package org.apache.qpid.server.logging;
import junit.framework.AssertionFailedError;
-
-import org.apache.qpid.server.BrokerOptions;
import org.apache.qpid.server.Main;
import org.apache.qpid.transport.ConnectionException;
import org.apache.qpid.util.LogMonitor;
@@ -153,12 +151,12 @@ public class BrokerLoggingTest extends AbstractTestLogging
{
// This logging startup code only occurs when you run a Java broker,
// that broker must be started via Main so not an InVM broker.
- if (isJavaBroker() && isExternalBroker() && !isInternalBroker())
+ if (isJavaBroker() && isExternalBroker())
{
String TESTID = "BRK-1007";
//Remove test Log4j config from the commandline
- _brokerCommand = _brokerCommand.substring(0, _brokerCommand.indexOf("-l"));
+ _broker = _broker.substring(0, _broker.indexOf("-l"));
startBroker();
@@ -205,7 +203,7 @@ public class BrokerLoggingTest extends AbstractTestLogging
1, findMatches(TESTID).size());
//3
- String defaultLog4j = System.getProperty(QPID_HOME) + "/" + BrokerOptions.DEFAULT_LOG_CONFIG_FILE;
+ String defaultLog4j = _configFile.getParent() + "/" + Main.DEFAULT_LOG_CONFIG_FILENAME;
assertTrue("Log4j file(" + defaultLog4j + ") details not correctly logged:" + getMessageString(log),
getMessageString(log).endsWith(defaultLog4j));
@@ -242,11 +240,12 @@ public class BrokerLoggingTest extends AbstractTestLogging
*/
public void testBrokerStartupCustomLog4j() throws Exception
{
- // This logging startup code only occurs when you run a Java broker
+ // This logging startup code only occurs when you run a Java broker,
+ // that broker must be started via Main so not an InVM broker.
if (isJavaBroker() && isExternalBroker())
{
// Get custom -l value used during testing for the broker startup
- String customLog4j = _brokerCommand.substring(_brokerCommand.indexOf("-l") + 2);
+ String customLog4j = _broker.substring(_broker.indexOf("-l") + 2);
String TESTID = "BRK-1007";
diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/server/logging/ChannelLoggingTest.java b/qpid/java/systests/src/main/java/org/apache/qpid/server/logging/ChannelLoggingTest.java
index 1b2ec9c092..02d0d6f334 100644
--- a/qpid/java/systests/src/main/java/org/apache/qpid/server/logging/ChannelLoggingTest.java
+++ b/qpid/java/systests/src/main/java/org/apache/qpid/server/logging/ChannelLoggingTest.java
@@ -77,7 +77,7 @@ public class ChannelLoggingTest extends AbstractTestLogging
validateMessageID("CHN-1001", log);
assertEquals("Incorrect Channel in actor:"+fromActor(log), isBroker010()? 0 : 1, getChannelID(fromActor(log)));
- if (!isBroker010())
+ if (isBroker08())
{
// Wait to ensure that the CHN-1004 message is logged
waitForMessage("CHN-1004");
@@ -89,7 +89,7 @@ public class ChannelLoggingTest extends AbstractTestLogging
log = getLogMessage(results, 0);
// MESSAGE [con:0(guest@anonymous(3273383)/test)/ch:1] CHN-1004 : Prefetch Size (bytes) {0,number} : Count {1,number}
validateMessageID("CHN-1004", log);
- assertEquals("Incorrect Channel in actor:"+fromActor(log), 1, getChannelID(fromActor(log)));
+ assertEquals("Incorrect Channel in actor:"+fromActor(log), isBroker010()? 0 : 1, getChannelID(fromActor(log)));
assertTrue("Prefetch Count not correct",getMessageString(fromMessage(log)).endsWith("Count "+PREFETCH));
}
diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/server/logging/ManagementLoggingTest.java b/qpid/java/systests/src/main/java/org/apache/qpid/server/logging/ManagementLoggingTest.java
index 9feca7279e..595c0d5f35 100644
--- a/qpid/java/systests/src/main/java/org/apache/qpid/server/logging/ManagementLoggingTest.java
+++ b/qpid/java/systests/src/main/java/org/apache/qpid/server/logging/ManagementLoggingTest.java
@@ -76,8 +76,9 @@ public class ManagementLoggingTest extends AbstractTestLogging
*/
public void testManagementStartupEnabled() throws Exception
{
- // This test only works on java brokers
- if (isJavaBroker())
+ // This test only works on external java brokers due to the fact that
+ // Management is disabled on InVM brokers.
+ if (isJavaBroker() && isExternalBroker())
{
startBrokerAndCreateMonitor(true, false);
@@ -129,7 +130,9 @@ public class ManagementLoggingTest extends AbstractTestLogging
*/
public void testManagementStartupDisabled() throws Exception
{
- if (isJavaBroker())
+ // This test only works on external java brokers due to the fact that
+ // Management is disabled on InVM brokers.
+ if (isJavaBroker() && isExternalBroker())
{
startBrokerAndCreateMonitor(false, false);
@@ -188,7 +191,9 @@ public class ManagementLoggingTest extends AbstractTestLogging
*/
public void testManagementStartupRMIEntries() throws Exception
{
- if (isJavaBroker())
+ // This test only works on external java brokers due to the fact that
+ // Management is disabled on InVM brokers.
+ if (isJavaBroker() && isExternalBroker())
{
startBrokerAndCreateMonitor(true, false);
@@ -245,7 +250,9 @@ public class ManagementLoggingTest extends AbstractTestLogging
*/
public void testManagementStartupSSLKeystore() throws Exception
{
- if (isJavaBroker())
+ // This test only works on external java brokers due to the fact that
+ // Management is disabled on InVM brokers.
+ if (isJavaBroker() && isExternalBroker())
{
startBrokerAndCreateMonitor(true, true);
diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/server/persistent/NoLocalAfterRecoveryTest.java b/qpid/java/systests/src/main/java/org/apache/qpid/server/persistent/NoLocalAfterRecoveryTest.java
index 398c83a8d8..a5aec3edce 100644
--- a/qpid/java/systests/src/main/java/org/apache/qpid/server/persistent/NoLocalAfterRecoveryTest.java
+++ b/qpid/java/systests/src/main/java/org/apache/qpid/server/persistent/NoLocalAfterRecoveryTest.java
@@ -78,10 +78,21 @@ public class NoLocalAfterRecoveryTest extends QpidBrokerTestCase implements Conn
BrokerDetails details = _connectionURL.getBrokerDetails(0);
- // This will attempt to failover for 3 seconds.
- // Local testing suggests failover takes 2 seconds
- details.setProperty(BrokerDetails.OPTIONS_RETRY, "10");
- details.setProperty(BrokerDetails.OPTIONS_CONNECT_DELAY, "500");
+ // Due to the problem with SingleServer delaying on all connection
+ // attempts. So using a high retry value.
+ if (_broker.equals(VM))
+ {
+ // Local testing suggests InVM restart takes under a second
+ details.setProperty(BrokerDetails.OPTIONS_RETRY, "5");
+ details.setProperty(BrokerDetails.OPTIONS_CONNECT_DELAY, "200");
+ }
+ else
+ {
+ // This will attempt to failover for 3 seconds.
+ // Local testing suggests failover takes 2 seconds
+ details.setProperty(BrokerDetails.OPTIONS_RETRY, "10");
+ details.setProperty(BrokerDetails.OPTIONS_CONNECT_DELAY, "500");
+ }
super.setUp();
}
diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/server/queue/MultipleTransactedBatchProducerTest.java b/qpid/java/systests/src/main/java/org/apache/qpid/server/queue/MultipleTransactedBatchProducerTest.java
deleted file mode 100644
index 460270e188..0000000000
--- a/qpid/java/systests/src/main/java/org/apache/qpid/server/queue/MultipleTransactedBatchProducerTest.java
+++ /dev/null
@@ -1,246 +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 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.MessageListener;
-import javax.jms.Session;
-
-import org.apache.log4j.Logger;
-import org.apache.qpid.test.utils.QpidBrokerTestCase;
-
-public class MultipleTransactedBatchProducerTest extends QpidBrokerTestCase
-{
- private static final Logger _logger = Logger.getLogger(MultipleTransactedBatchProducerTest.class);
-
- private static final int MESSAGE_COUNT = 1000;
- private static final int BATCH_SIZE = 50;
- private static final int NUM_PRODUCERS = 2;
- private static final int NUM_CONSUMERS = 3;
- private static final Random RANDOM = new Random();
-
- private CountDownLatch _receivedLatch;
- private String _queueName;
-
- private volatile String _failMsg;
-
- public void setUp() throws Exception
- {
- //debug level logging often makes this test pass artificially, turn the level down to info.
- setSystemProperty("amqj.server.logging.level", "INFO");
- _receivedLatch = new CountDownLatch(MESSAGE_COUNT * NUM_PRODUCERS);
- setConfigurationProperty("management.enabled", "true");
- super.setUp();
- _queueName = getTestQueueName();
- _failMsg = null;
- }
-
- /**
- * When there are multiple producers submitting batches of messages to a given
- * queue using transacted sessions, it is highly probable that concurrent
- * enqueue() activity will occur and attempt delivery of their message to the
- * same subscription. In this scenario it is likely that one of the attempts
- * will succeed and the other will result in use of the deliverAsync() method
- * to start a queue Runner and ensure delivery of the message.
- *
- * A defect within the processQueue() method used by the Runner would mean that
- * delivery of these messages may not occur, should the Runner stop before all
- * messages have been processed. Such a defect was discovered and found to be
- * most visible when Selectors are used such that one and only one subscription
- * can/will accept any given message, but multiple subscriptions are present,
- * and one of the earlier subscriptions receives more messages than the others.
- *
- * This test is to validate that the processQueue() method is able to correctly
- * deliver all of the messages present for asynchronous delivery to subscriptions,
- * by utilising multiple batch transacted producers to create the scenario and
- * ensure all messages are received by a consumer.
- */
- public void testMultipleBatchedProducersWithMultipleConsumersUsingSelectors() throws Exception
- {
- String selector1 = ("(\"" + _queueName +"\" % " + NUM_CONSUMERS + ") = 0");
- String selector2 = ("(\"" + _queueName +"\" % " + NUM_CONSUMERS + ") = 1");
- String selector3 = ("(\"" + _queueName +"\" % " + NUM_CONSUMERS + ") = 2");
-
- //create consumers
- Connection conn1 = getConnection();
- conn1.setExceptionListener(new ExceptionHandler("conn1"));
- Session sess1 = conn1.createSession(true, Session.SESSION_TRANSACTED);
- MessageConsumer cons1 = sess1.createConsumer(sess1.createQueue(_queueName), selector1);
- cons1.setMessageListener(new Cons(sess1,"consumer1"));
-
- Connection conn2 = getConnection();
- conn2.setExceptionListener(new ExceptionHandler("conn2"));
- Session sess2 = conn2.createSession(true, Session.SESSION_TRANSACTED);
- MessageConsumer cons2 = sess2.createConsumer(sess2.createQueue(_queueName), selector2);
- cons2.setMessageListener(new Cons(sess2,"consumer2"));
-
- Connection conn3 = getConnection();
- conn3.setExceptionListener(new ExceptionHandler("conn3"));
- Session sess3 = conn3.createSession(true, Session.SESSION_TRANSACTED);
- MessageConsumer cons3 = sess3.createConsumer(sess3.createQueue(_queueName), selector3);
- cons3.setMessageListener(new Cons(sess3,"consumer3"));
-
- conn1.start();
- conn2.start();
- conn3.start();
-
- //create producers
- Connection connA = getConnection();
- connA.setExceptionListener(new ExceptionHandler("connA"));
- Connection connB = getConnection();
- connB.setExceptionListener(new ExceptionHandler("connB"));
- Thread producer1 = new Thread(new ProducerThread(connA, _queueName, "producer1"));
- Thread producer2 = new Thread(new ProducerThread(connB, _queueName, "producer2"));
-
- producer1.start();
- Thread.sleep(10);
- producer2.start();
-
- //await delivery of the messages
- boolean result = _receivedLatch.await(75, TimeUnit.SECONDS);
-
- assertNull("Test failed because: " + String.valueOf(_failMsg), _failMsg);
- assertTrue("Some of the messages were not all recieved in the given timeframe, remaining count was: "+_receivedLatch.getCount(),
- result);
-
- }
-
- @Override
- public Message createNextMessage(Session session, int msgCount) throws JMSException
- {
- Message message = super.createNextMessage(session,msgCount);
-
- //bias at least 50% of the messages to the first consumers selector because
- //the issue presents itself primarily when an earlier subscription completes
- //delivery after the later subscriptions
- int val;
- if (msgCount % 2 == 0)
- {
- val = 0;
- }
- else
- {
- val = RANDOM.nextInt(Integer.MAX_VALUE);
- }
-
- message.setIntProperty(_queueName, val);
-
- return message;
- }
-
- private class Cons implements MessageListener
- {
- private Session _sess;
- private String _desc;
-
- public Cons(Session sess, String desc)
- {
- _sess = sess;
- _desc = desc;
- }
-
- public void onMessage(Message message)
- {
- _receivedLatch.countDown();
- int msgCount = 0;
- int msgID = 0;
- try
- {
- msgCount = message.getIntProperty(INDEX);
- msgID = message.getIntProperty(_queueName);
- }
- catch (JMSException e)
- {
- _logger.error(_desc + " received exception: " + e.getMessage(), e);
- failAsyncTest(e.getMessage());
- }
-
- _logger.info("Consumer received message:"+ msgCount + " with ID: " + msgID);
-
- try
- {
- _sess.commit();
- }
- catch (JMSException e)
- {
- _logger.error(_desc + " received exception: " + e.getMessage(), e);
- failAsyncTest(e.getMessage());
- }
- }
- }
-
- private class ProducerThread implements Runnable
- {
- private Connection _conn;
- private String _dest;
- private String _desc;
-
- public ProducerThread(Connection conn, String dest, String desc)
- {
- _conn = conn;
- _dest = dest;
- _desc = desc;
- }
-
- public void run()
- {
- try
- {
- Session session = _conn.createSession(true, Session.SESSION_TRANSACTED);
- sendMessage(session, session.createQueue(_dest), MESSAGE_COUNT, BATCH_SIZE);
- }
- catch (Exception e)
- {
- _logger.error(_desc + " received exception: " + e.getMessage(), e);
- failAsyncTest(e.getMessage());
- }
- }
- }
-
- private class ExceptionHandler implements javax.jms.ExceptionListener
- {
- private String _desc;
-
- public ExceptionHandler(String description)
- {
- _desc = description;
- }
-
- public void onException(JMSException e)
- {
- _logger.error(_desc + " received exception: " + e.getMessage(), e);
- failAsyncTest(e.getMessage());
- }
- }
-
- private void failAsyncTest(String msg)
- {
- _logger.error("Failing test because: " + msg);
- _failMsg = msg;
- }
-} \ No newline at end of file
diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/server/queue/PriorityTest.java b/qpid/java/systests/src/main/java/org/apache/qpid/server/queue/PriorityTest.java
index 2ce1251eab..6203e8a194 100644
--- a/qpid/java/systests/src/main/java/org/apache/qpid/server/queue/PriorityTest.java
+++ b/qpid/java/systests/src/main/java/org/apache/qpid/server/queue/PriorityTest.java
@@ -23,6 +23,7 @@ package org.apache.qpid.server.queue;
import junit.framework.TestCase;
import junit.framework.Assert;
import org.apache.log4j.Logger;
+import org.apache.qpid.client.transport.TransportConnection;
import org.apache.qpid.client.AMQConnection;
import org.apache.qpid.client.AMQSession;
import org.apache.qpid.client.AMQQueue;
diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/server/security/acl/AbstractACLTestCase.java b/qpid/java/systests/src/main/java/org/apache/qpid/server/security/acl/AbstractACLTestCase.java
index 7f8f71d965..f845ff1214 100644
--- a/qpid/java/systests/src/main/java/org/apache/qpid/server/security/acl/AbstractACLTestCase.java
+++ b/qpid/java/systests/src/main/java/org/apache/qpid/server/security/acl/AbstractACLTestCase.java
@@ -52,6 +52,7 @@ import org.apache.qpid.url.URLSyntaxException;
*
* TODO move the pre broker-startup setup method invocation code to {@link QpidBrokerTestCase}
*
+ * @see SimpleACLTest
* @see ExternalACLTest
* @see ExternalACLFileTest
* @see ExternalACLJMXTest
@@ -64,7 +65,10 @@ public abstract class AbstractACLTestCase extends QpidBrokerTestCase implements
protected CountDownLatch _exceptionReceived;
/** Override this to return the name of the configuration XML file. */
- public abstract String getConfig();
+ public String getConfig()
+ {
+ return "config-systests-acl.xml";
+ }
/** Override this to setup external ACL files for virtual hosts. */
public List<String> getHostList()
diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/server/security/acl/ExternalACLTest.java b/qpid/java/systests/src/main/java/org/apache/qpid/server/security/acl/ExternalACLTest.java
index d1ba725721..4603cc1862 100644
--- a/qpid/java/systests/src/main/java/org/apache/qpid/server/security/acl/ExternalACLTest.java
+++ b/qpid/java/systests/src/main/java/org/apache/qpid/server/security/acl/ExternalACLTest.java
@@ -18,620 +18,11 @@
*/
package org.apache.qpid.server.security.acl;
-import java.io.IOException;
import java.util.Arrays;
import java.util.List;
-import javax.jms.Connection;
-import javax.jms.DeliveryMode;
-import javax.jms.IllegalStateException;
-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.Topic;
-import javax.jms.TopicSubscriber;
-import javax.naming.NamingException;
-
-import org.apache.qpid.AMQException;
-import org.apache.qpid.client.AMQConnection;
-import org.apache.qpid.client.AMQSession;
-import org.apache.qpid.framing.AMQShortString;
-import org.apache.qpid.protocol.AMQConstant;
-import org.apache.qpid.url.URLSyntaxException;
-
-/**
- * Tests the V2 ACLs. The tests perform basic AMQP operations like creating queues or excahnges and publishing and consuming messages, using
- * JMS to contact the broker.
- */
-public class ExternalACLTest extends AbstractACLTestCase
+public class ExternalACLTest extends SimpleACLTest
{
- public void testAccessAuthorizedSuccess() throws AMQException, URLSyntaxException, Exception
- {
- try
- {
- Connection conn = getConnection("test", "client", "guest");
- Session sess = conn.createSession(true, Session.SESSION_TRANSACTED);
- conn.start();
-
- //Do something to show connection is active.
- sess.rollback();
-
- conn.close();
- }
- catch (Exception e)
- {
- fail("Connection was not created due to:" + e);
- }
- }
-
- public void testAccessVhostAuthorisedGuestSuccess() throws IOException, Exception
- {
- //The 'guest' user has no access to the 'test' vhost, as tested below in testAccessNoRights(), and so
- //is unable to perform actions such as connecting (and by extension, creating a queue, and consuming
- //from a queue etc). In order to test the vhost-wide 'access' ACL right, the 'guest' user has been given
- //this right in the 'test2' vhost.
-
- try
- {
- //get a connection to the 'test2' vhost using the guest user and perform various actions.
- Connection conn = getConnection("test2", "guest", "guest");
- Session sess = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
- conn.start();
-
- //create Queues and consumers for each
- Queue namedQueue = sess.createQueue("vhostAccessCreatedQueue" + getTestQueueName());
- Queue tempQueue = sess.createTemporaryQueue();
- MessageConsumer consumer = sess.createConsumer(namedQueue);
- MessageConsumer tempConsumer = sess.createConsumer(tempQueue);
-
- //send a message to each queue (also causing an exchange declare)
- MessageProducer sender = ((AMQSession<?, ?>) sess).createProducer(null);
- ((org.apache.qpid.jms.MessageProducer) sender).send(namedQueue, sess.createTextMessage("test"),
- DeliveryMode.NON_PERSISTENT, 0, 0L, false, false, true);
- ((org.apache.qpid.jms.MessageProducer) sender).send(tempQueue, sess.createTextMessage("test"),
- DeliveryMode.NON_PERSISTENT, 0, 0L, false, false, true);
-
- //consume the messages from the queues
- consumer.receive(2000);
- tempConsumer.receive(2000);
-
- conn.close();
- }
- catch (Exception e)
- {
- fail("Test failed due to:" + e.getMessage());
- }
- }
-
- public void testAccessNoRightsFailure() throws Exception
- {
- try
- {
- Connection conn = getConnection("test", "guest", "guest");
- Session sess = conn.createSession(true, Session.SESSION_TRANSACTED);
- conn.start();
- sess.rollback();
-
- fail("Connection was created.");
- }
- catch (JMSException e)
- {
- // JMSException -> linkedException -> cause = AMQException (403 or 320)
- Exception linkedException = e.getLinkedException();
- assertNotNull("There was no linked exception", linkedException);
- Throwable cause = linkedException.getCause();
- assertNotNull("Cause was null", cause);
- assertTrue("Wrong linked exception type", cause instanceof AMQException);
- AMQConstant errorCode = isBroker010() ? AMQConstant.CONTEXT_IN_USE : AMQConstant.ACCESS_REFUSED;
- assertEquals("Incorrect error code received", errorCode, ((AMQException) cause).getErrorCode());
- }
- }
-
- public void testClientDeleteQueueSuccess() throws Exception
- {
- try
- {
- Connection conn = getConnection("test", "client", "guest");
- Session sess = conn.createSession(true, Session.SESSION_TRANSACTED);
- conn.start();
-
- // create kipper
- Topic kipper = sess.createTopic("kipper");
- TopicSubscriber subscriber = sess.createDurableSubscriber(kipper, "kipper");
-
- subscriber.close();
- sess.unsubscribe("kipper");
-
- //Do something to show connection is active.
- sess.rollback();
- conn.close();
- }
- catch (Exception e)
- {
- fail("Test failed due to:" + e.getMessage());
- }
- }
-
- public void testServerDeleteQueueFailure() throws Exception
- {
- try
- {
- Connection conn = getConnection("test", "server", "guest");
- Session sess = conn.createSession(true, Session.SESSION_TRANSACTED);
- conn.start();
-
- // create kipper
- Topic kipper = sess.createTopic("kipper");
- TopicSubscriber subscriber = sess.createDurableSubscriber(kipper, "kipper");
-
- subscriber.close();
- sess.unsubscribe("kipper");
-
- //Do something to show connection is active.
- sess.rollback();
- conn.close();
- }
- catch (JMSException e)
- {
- // JMSException -> linedException = AMQException.403
- check403Exception(e.getLinkedException());
- }
- }
-
- public void testClientConsumeFromTempQueueSuccess() throws AMQException, URLSyntaxException, Exception
- {
- try
- {
- Connection conn = getConnection("test", "client", "guest");
-
- Session sess = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
-
- conn.start();
-
- sess.createConsumer(sess.createTemporaryQueue());
-
- conn.close();
- }
- catch (Exception e)
- {
- fail("Test failed due to:" + e.getMessage());
- }
- }
-
- public void testClientConsumeFromNamedQueueFailure() throws NamingException, Exception
- {
- try
- {
- Connection conn = getConnection("test", "client", "guest");
-
- Session sess = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
-
- conn.start();
-
- sess.createConsumer(sess.createQueue("IllegalQueue"));
-
- fail("Test failed as consumer was created.");
- }
- catch (JMSException e)
- {
- check403Exception(e.getLinkedException());
- }
- }
-
- public void testClientCreateTemporaryQueueSuccess() throws JMSException, URLSyntaxException, Exception
- {
- try
- {
- Connection conn = getConnection("test", "client", "guest");
-
- Session sess = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
-
- conn.start();
-
- //Create Temporary Queue - can't use the createTempQueue as QueueName is null.
- ((AMQSession<?, ?>) sess).createQueue(new AMQShortString("doesnt_matter_as_autodelete_means_tmp"),
- true, false, false);
-
- conn.close();
- }
- catch (Exception e)
- {
- fail("Test failed due to:" + e.getMessage());
- }
- }
-
- public void testClientCreateNamedQueueFailure() throws NamingException, JMSException, AMQException, Exception
- {
- try
- {
- Connection conn = getConnection("test", "client", "guest");
-
- Session sess = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
-
- conn.start();
-
- //Create a Named Queue
- ((AMQSession<?, ?>) sess).createQueue(new AMQShortString("IllegalQueue"), false, false, false);
-
- fail("Test failed as Queue creation succeded.");
- //conn will be automatically closed
- }
- catch (AMQException e)
- {
- check403Exception(e);
- }
- }
-
- public void testClientPublishUsingTransactionSuccess() throws AMQException, URLSyntaxException, Exception
- {
- try
- {
- Connection conn = getConnection("test", "client", "guest");
-
- Session sess = conn.createSession(true, Session.SESSION_TRANSACTED);
-
- conn.start();
-
- MessageProducer sender = sess.createProducer(sess.createQueue("example.RequestQueue"));
-
- sender.send(sess.createTextMessage("test"));
-
- //Send the message using a transaction as this will allow us to retrieve any errors that occur on the broker.
- sess.commit();
-
- conn.close();
- }
- catch (Exception e)
- {
- fail("Test publish failed:" + e);
- }
- }
-
- public void testClientPublishValidQueueSuccess() throws AMQException, URLSyntaxException, Exception
- {
- try
- {
- Connection conn = getConnection("test", "client", "guest");
-
- Session sess = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
-
- conn.start();
-
- MessageProducer sender = ((AMQSession<?, ?>) sess).createProducer(null);
-
- Queue queue = sess.createQueue("example.RequestQueue");
-
- // Send a message that we will wait to be sent, this should give the broker time to process the msg
- // before we finish this test. Message is set !immed !mand as the queue is invalid so want to test ACLs not
- // queue existence.
- ((org.apache.qpid.jms.MessageProducer) sender).send(queue, sess.createTextMessage("test"),
- DeliveryMode.NON_PERSISTENT, 0, 0L, false, false, true);
-
- conn.close();
- }
- catch (Exception e)
- {
- fail("Test publish failed:" + e);
- }
- }
-
- public void testClientPublishInvalidQueueSuccess() throws AMQException, URLSyntaxException, JMSException, NamingException, Exception
- {
- try
- {
- Connection conn = getConnection("test", "client", "guest");
-
- Session session = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
-
- conn.start();
-
- MessageProducer sender = ((AMQSession<?, ?>) session).createProducer(null);
-
- Queue queue = session.createQueue("Invalid");
-
- // Send a message that we will wait to be sent, this should give the broker time to close the connection
- // before we finish this test. Message is set !immed !mand as the queue is invalid so want to test ACLs not
- // queue existence.
- ((org.apache.qpid.jms.MessageProducer) sender).send(queue, session.createTextMessage("test"),
- DeliveryMode.NON_PERSISTENT, 0, 0L, false, false, true);
-
- // Test the connection with a valid consumer
- // This may fail as the session may be closed before the queue or the consumer created.
- Queue temp = session.createTemporaryQueue();
-
- session.createConsumer(temp).close();
-
- //Connection should now be closed and will throw the exception caused by the above send
- conn.close();
-
- fail("Close is not expected to succeed.");
- }
- catch (IllegalStateException e)
- {
- _logger.info("QPID-2345: Session became closed and we got that error rather than the authentication error.");
- }
- catch (JMSException e)
- {
- check403Exception(e.getLinkedException());
- }
- }
-
- public void testServerConsumeFromNamedQueueValid() throws AMQException, URLSyntaxException, Exception
- {
- try
- {
- Connection conn = getConnection("test", "server", "guest");
-
- Session sess = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
-
- conn.start();
-
- sess.createConsumer(sess.createQueue("example.RequestQueue"));
-
- conn.close();
- }
- catch (Exception e)
- {
- fail("Test failed due to:" + e.getMessage());
- }
- }
-
- public void testServerConsumeFromNamedQueueInvalid() throws AMQException, URLSyntaxException, NamingException, Exception
- {
- try
- {
- Connection conn = getConnection("test", "client", "guest");
-
- Session sess = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
-
- conn.start();
-
- sess.createConsumer(sess.createQueue("Invalid"));
-
- fail("Test failed as consumer was created.");
- }
- catch (JMSException e)
- {
- check403Exception(e.getLinkedException());
- }
- }
-
- public void testServerConsumeFromTemporaryQueue() throws AMQException, URLSyntaxException, NamingException, Exception
- {
- try
- {
- Connection conn = getConnection("test", "server", "guest");
-
- Session sess = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
-
- conn.start();
-
- sess.createConsumer(sess.createTemporaryQueue());
-
- fail("Test failed as consumer was created.");
- }
- catch (JMSException e)
- {
- check403Exception(e.getLinkedException());
- }
- }
-
- public void testServerCreateNamedQueueValid() throws JMSException, URLSyntaxException, Exception
- {
- try
- {
- Connection conn = getConnection("test", "server", "guest");
-
- Session sess = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
-
- conn.start();
-
- //Create Temporary Queue
- ((AMQSession<?, ?>) sess).createQueue(new AMQShortString("example.RequestQueue"), false, false, false);
-
- conn.close();
- }
- catch (Exception e)
- {
- fail("Test failed due to:" + e.getMessage());
- }
- }
-
- public void testServerCreateNamedQueueInvalid() throws JMSException, URLSyntaxException, AMQException, NamingException, Exception
- {
- try
- {
- Connection conn = getConnection("test", "server", "guest");
-
- Session sess = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
-
- conn.start();
-
- //Create a Named Queue
- ((AMQSession<?, ?>) sess).createQueue(new AMQShortString("IllegalQueue"), false, false, false);
-
- fail("Test failed as creation succeded.");
- }
- catch (Exception e)
- {
- check403Exception(e);
- }
- }
-
- public void testServerCreateTemporaryQueueInvalid() throws NamingException, Exception
- {
- try
- {
- Connection conn = getConnection("test", "server", "guest");
- Session session = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
-
- conn.start();
-
- session.createTemporaryQueue();
-
- fail("Test failed as creation succeded.");
- }
- catch (JMSException e)
- {
- check403Exception(e.getLinkedException());
- }
- }
-
- public void testServerCreateAutoDeleteQueueInvalid() throws NamingException, JMSException, AMQException, Exception
- {
- try
- {
- Connection connection = getConnection("test", "server", "guest");
-
- Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
-
- connection.start();
-
- ((AMQSession<?, ?>) session).createQueue(new AMQShortString("again_ensure_auto_delete_queue_for_temporary"),
- true, false, false);
-
- fail("Test failed as creation succeded.");
- }
- catch (Exception e)
- {
- check403Exception(e);
- }
- }
-
- /**
- * This test uses both the cilent and sender to validate that the Server is able to publish to a temporary queue.
- * The reason the client must be involved is that the Server is unable to create its own Temporary Queues.
- *
- * @throws AMQException
- * @throws URLSyntaxException
- * @throws JMSException
- */
- public void testServerPublishUsingTransactionSuccess() throws AMQException, URLSyntaxException, JMSException, NamingException, Exception
- {
- //Set up the Server
- Connection serverConnection = getConnection("test", "server", "guest");
-
- Session serverSession = serverConnection.createSession(true, Session.SESSION_TRANSACTED);
-
- Queue requestQueue = serverSession.createQueue("example.RequestQueue");
-
- MessageConsumer server = serverSession.createConsumer(requestQueue);
-
- serverConnection.start();
-
- //Set up the consumer
- Connection clientConnection = getConnection("test", "client", "guest");
-
- //Send a test mesage
- Session clientSession = clientConnection.createSession(false, Session.AUTO_ACKNOWLEDGE);
-
- Queue responseQueue = clientSession.createTemporaryQueue();
-
- MessageConsumer clientResponse = clientSession.createConsumer(responseQueue);
-
- clientConnection.start();
-
- Message request = clientSession.createTextMessage("Request");
-
- assertNotNull("Response Queue is null", responseQueue);
-
- request.setJMSReplyTo(responseQueue);
-
- clientSession.createProducer(requestQueue).send(request);
-
- try
- {
- Message msg = null;
-
- msg = server.receive(2000);
-
- while (msg != null && !((TextMessage) msg).getText().equals("Request"))
- {
- msg = server.receive(2000);
- }
-
- assertNotNull("Message not received", msg);
-
- assertNotNull("Reply-To is Null", msg.getJMSReplyTo());
-
- MessageProducer sender = serverSession.createProducer(msg.getJMSReplyTo());
-
- sender.send(serverSession.createTextMessage("Response"));
-
- //Send the message using a transaction as this will allow us to retrieve any errors that occur on the broker.
- serverSession.commit();
-
- //Ensure Response is received.
- Message clientResponseMsg = clientResponse.receive(2000);
- assertNotNull("Client did not receive response message,", clientResponseMsg);
- assertEquals("Incorrect message received", "Response", ((TextMessage) clientResponseMsg).getText());
-
- }
- catch (Exception e)
- {
- fail("Test publish failed:" + e);
- }
- finally
- {
- try
- {
- serverConnection.close();
- }
- finally
- {
- clientConnection.close();
- }
- }
- }
-
- public void testServerPublishInvalidQueueSuccess() throws AMQException, URLSyntaxException, JMSException, NamingException, Exception
- {
- try
- {
- Connection conn = getConnection("test", "server", "guest");
-
- ((AMQConnection) conn).setConnectionListener(this);
-
- Session session = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
-
- conn.start();
-
- MessageProducer sender = ((AMQSession<?, ?>) session).createProducer(null);
-
- Queue queue = session.createQueue("Invalid");
-
- // Send a message that we will wait to be sent, this should give the broker time to close the connection
- // before we finish this test. Message is set !immed !mand as the queue is invalid so want to test ACLs not
- // queue existence.
- ((org.apache.qpid.jms.MessageProducer) sender).send(queue, session.createTextMessage("test"),
- DeliveryMode.NON_PERSISTENT, 0, 0L, false, false, true);
-
- // Test the connection with a valid consumer
- // This may not work as the session may be closed before the queue or consumer creation can occur.
- // The correct JMSexception with linked error will only occur when the close method is recevied whilst in
- // the failover safe block
- session.createConsumer(session.createQueue("example.RequestQueue")).close();
-
- //Connection should now be closed and will throw the exception caused by the above send
- conn.close();
-
- fail("Close is not expected to succeed.");
- }
- catch (IllegalStateException e)
- {
- _logger.info("QPID-2345: Session became closed and we got that error rather than the authentication error.");
- }
- catch (JMSException e)
- {
- check403Exception(e.getLinkedException());
- }
- }
-
-
@Override
public String getConfig()
{
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
new file mode 100644
index 0000000000..a50817e659
--- /dev/null
+++ b/qpid/java/systests/src/main/java/org/apache/qpid/server/security/acl/SimpleACLTest.java
@@ -0,0 +1,644 @@
+/*
+ * 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.acl;
+
+import java.io.IOException;
+
+import javax.jms.Connection;
+import javax.jms.DeliveryMode;
+import javax.jms.IllegalStateException;
+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.Topic;
+import javax.jms.TopicSubscriber;
+import javax.naming.NamingException;
+
+import org.apache.qpid.AMQException;
+import org.apache.qpid.client.AMQConnection;
+import org.apache.qpid.client.AMQSession;
+import org.apache.qpid.framing.AMQShortString;
+import org.apache.qpid.protocol.AMQConstant;
+import org.apache.qpid.url.URLSyntaxException;
+
+/**
+ * Basic access control list tests.
+ *
+ * These tests require an access control security plugin to be configured in the broker, and carry out various broker
+ * operations that will succeed or fail depending on the user and virtual host. See the {@code config-systests-acl-setup.xml}
+ * configuration file for the SimpleXML version of the ACLs used by the Java broker only, or the various {@code .txt}
+ * files in the system tests directory for the external version 3 ACL files used by both the Java and C++ brokers.
+ * <p>
+ * This class can be extended and the {@link #getConfig()} method overridden to run the same tests with a different type
+ * of access control mechanism. Extension classes should differ only in the configuration file used, but extra tests can be
+ * added that are specific to a particular configuration.
+ * <p>
+ * The tests perform basic AMQP operations like creating queues or excahnges and publishing and consuming messages, using
+ * JMS to contact the broker.
+ *
+ * @see ExternalACLTest
+ */
+public class SimpleACLTest extends AbstractACLTestCase
+{
+ public void testAccessAuthorizedSuccess() throws AMQException, URLSyntaxException, Exception
+ {
+ try
+ {
+ Connection conn = getConnection("test", "client", "guest");
+ Session sess = conn.createSession(true, Session.SESSION_TRANSACTED);
+ conn.start();
+
+ //Do something to show connection is active.
+ sess.rollback();
+
+ conn.close();
+ }
+ catch (Exception e)
+ {
+ fail("Connection was not created due to:" + e);
+ }
+ }
+
+ public void testAccessVhostAuthorisedGuestSuccess() throws IOException, Exception
+ {
+ //The 'guest' user has no access to the 'test' vhost, as tested below in testAccessNoRights(), and so
+ //is unable to perform actions such as connecting (and by extension, creating a queue, and consuming
+ //from a queue etc). In order to test the vhost-wide 'access' ACL right, the 'guest' user has been given
+ //this right in the 'test2' vhost.
+
+ try
+ {
+ //get a connection to the 'test2' vhost using the guest user and perform various actions.
+ Connection conn = getConnection("test2", "guest", "guest");
+ Session sess = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
+ conn.start();
+
+ //create Queues and consumers for each
+ Queue namedQueue = sess.createQueue("vhostAccessCreatedQueue" + getTestQueueName());
+ Queue tempQueue = sess.createTemporaryQueue();
+ MessageConsumer consumer = sess.createConsumer(namedQueue);
+ MessageConsumer tempConsumer = sess.createConsumer(tempQueue);
+
+ //send a message to each queue (also causing an exchange declare)
+ MessageProducer sender = ((AMQSession<?, ?>) sess).createProducer(null);
+ ((org.apache.qpid.jms.MessageProducer) sender).send(namedQueue, sess.createTextMessage("test"),
+ DeliveryMode.NON_PERSISTENT, 0, 0L, false, false, true);
+ ((org.apache.qpid.jms.MessageProducer) sender).send(tempQueue, sess.createTextMessage("test"),
+ DeliveryMode.NON_PERSISTENT, 0, 0L, false, false, true);
+
+ //consume the messages from the queues
+ consumer.receive(2000);
+ tempConsumer.receive(2000);
+
+ conn.close();
+ }
+ catch (Exception e)
+ {
+ fail("Test failed due to:" + e.getMessage());
+ }
+ }
+
+ public void testAccessNoRightsFailure() throws Exception
+ {
+ try
+ {
+ Connection conn = getConnection("test", "guest", "guest");
+ Session sess = conn.createSession(true, Session.SESSION_TRANSACTED);
+ conn.start();
+ sess.rollback();
+
+ fail("Connection was created.");
+ }
+ catch (JMSException e)
+ {
+ // JMSException -> linkedException -> cause = AMQException (403 or 320)
+ Exception linkedException = e.getLinkedException();
+ assertNotNull("There was no linked exception", linkedException);
+ Throwable cause = linkedException.getCause();
+ assertNotNull("Cause was null", cause);
+ assertTrue("Wrong linked exception type", cause instanceof AMQException);
+ AMQConstant errorCode = isBroker010() ? AMQConstant.CONTEXT_IN_USE : AMQConstant.ACCESS_REFUSED;
+ assertEquals("Incorrect error code received", errorCode, ((AMQException) cause).getErrorCode());
+ }
+ }
+
+ public void testClientDeleteQueueSuccess() throws Exception
+ {
+ try
+ {
+ Connection conn = getConnection("test", "client", "guest");
+ Session sess = conn.createSession(true, Session.SESSION_TRANSACTED);
+ conn.start();
+
+ // create kipper
+ Topic kipper = sess.createTopic("kipper");
+ TopicSubscriber subscriber = sess.createDurableSubscriber(kipper, "kipper");
+
+ subscriber.close();
+ sess.unsubscribe("kipper");
+
+ //Do something to show connection is active.
+ sess.rollback();
+ conn.close();
+ }
+ catch (Exception e)
+ {
+ fail("Test failed due to:" + e.getMessage());
+ }
+ }
+
+ public void testServerDeleteQueueFailure() throws Exception
+ {
+ try
+ {
+ Connection conn = getConnection("test", "server", "guest");
+ Session sess = conn.createSession(true, Session.SESSION_TRANSACTED);
+ conn.start();
+
+ // create kipper
+ Topic kipper = sess.createTopic("kipper");
+ TopicSubscriber subscriber = sess.createDurableSubscriber(kipper, "kipper");
+
+ subscriber.close();
+ sess.unsubscribe("kipper");
+
+ //Do something to show connection is active.
+ sess.rollback();
+ conn.close();
+ }
+ catch (JMSException e)
+ {
+ // JMSException -> linedException = AMQException.403
+ check403Exception(e.getLinkedException());
+ }
+ }
+
+ public void testClientConsumeFromTempQueueSuccess() throws AMQException, URLSyntaxException, Exception
+ {
+ try
+ {
+ Connection conn = getConnection("test", "client", "guest");
+
+ Session sess = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
+
+ conn.start();
+
+ sess.createConsumer(sess.createTemporaryQueue());
+
+ conn.close();
+ }
+ catch (Exception e)
+ {
+ fail("Test failed due to:" + e.getMessage());
+ }
+ }
+
+ public void testClientConsumeFromNamedQueueFailure() throws NamingException, Exception
+ {
+ try
+ {
+ Connection conn = getConnection("test", "client", "guest");
+
+ Session sess = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
+
+ conn.start();
+
+ sess.createConsumer(sess.createQueue("IllegalQueue"));
+
+ fail("Test failed as consumer was created.");
+ }
+ catch (JMSException e)
+ {
+ check403Exception(e.getLinkedException());
+ }
+ }
+
+ public void testClientCreateTemporaryQueueSuccess() throws JMSException, URLSyntaxException, Exception
+ {
+ try
+ {
+ Connection conn = getConnection("test", "client", "guest");
+
+ Session sess = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
+
+ conn.start();
+
+ //Create Temporary Queue - can't use the createTempQueue as QueueName is null.
+ ((AMQSession<?, ?>) sess).createQueue(new AMQShortString("doesnt_matter_as_autodelete_means_tmp"),
+ true, false, false);
+
+ conn.close();
+ }
+ catch (Exception e)
+ {
+ fail("Test failed due to:" + e.getMessage());
+ }
+ }
+
+ public void testClientCreateNamedQueueFailure() throws NamingException, JMSException, AMQException, Exception
+ {
+ try
+ {
+ Connection conn = getConnection("test", "client", "guest");
+
+ Session sess = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
+
+ conn.start();
+
+ //Create a Named Queue
+ ((AMQSession<?, ?>) sess).createQueue(new AMQShortString("IllegalQueue"), false, false, false);
+
+ fail("Test failed as Queue creation succeded.");
+ //conn will be automatically closed
+ }
+ catch (AMQException e)
+ {
+ check403Exception(e);
+ }
+ }
+
+ public void testClientPublishUsingTransactionSuccess() throws AMQException, URLSyntaxException, Exception
+ {
+ try
+ {
+ Connection conn = getConnection("test", "client", "guest");
+
+ Session sess = conn.createSession(true, Session.SESSION_TRANSACTED);
+
+ conn.start();
+
+ MessageProducer sender = sess.createProducer(sess.createQueue("example.RequestQueue"));
+
+ sender.send(sess.createTextMessage("test"));
+
+ //Send the message using a transaction as this will allow us to retrieve any errors that occur on the broker.
+ sess.commit();
+
+ conn.close();
+ }
+ catch (Exception e)
+ {
+ fail("Test publish failed:" + e);
+ }
+ }
+
+ public void testClientPublishValidQueueSuccess() throws AMQException, URLSyntaxException, Exception
+ {
+ try
+ {
+ Connection conn = getConnection("test", "client", "guest");
+
+ Session sess = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
+
+ conn.start();
+
+ MessageProducer sender = ((AMQSession<?, ?>) sess).createProducer(null);
+
+ Queue queue = sess.createQueue("example.RequestQueue");
+
+ // Send a message that we will wait to be sent, this should give the broker time to process the msg
+ // before we finish this test. Message is set !immed !mand as the queue is invalid so want to test ACLs not
+ // queue existence.
+ ((org.apache.qpid.jms.MessageProducer) sender).send(queue, sess.createTextMessage("test"),
+ DeliveryMode.NON_PERSISTENT, 0, 0L, false, false, true);
+
+ conn.close();
+ }
+ catch (Exception e)
+ {
+ fail("Test publish failed:" + e);
+ }
+ }
+
+ public void testClientPublishInvalidQueueSuccess() throws AMQException, URLSyntaxException, JMSException, NamingException, Exception
+ {
+ try
+ {
+ Connection conn = getConnection("test", "client", "guest");
+
+ Session session = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
+
+ conn.start();
+
+ MessageProducer sender = ((AMQSession<?, ?>) session).createProducer(null);
+
+ Queue queue = session.createQueue("Invalid");
+
+ // Send a message that we will wait to be sent, this should give the broker time to close the connection
+ // before we finish this test. Message is set !immed !mand as the queue is invalid so want to test ACLs not
+ // queue existence.
+ ((org.apache.qpid.jms.MessageProducer) sender).send(queue, session.createTextMessage("test"),
+ DeliveryMode.NON_PERSISTENT, 0, 0L, false, false, true);
+
+ // Test the connection with a valid consumer
+ // This may fail as the session may be closed before the queue or the consumer created.
+ Queue temp = session.createTemporaryQueue();
+
+ session.createConsumer(temp).close();
+
+ //Connection should now be closed and will throw the exception caused by the above send
+ conn.close();
+
+ fail("Close is not expected to succeed.");
+ }
+ catch (IllegalStateException e)
+ {
+ _logger.info("QPID-2345: Session became closed and we got that error rather than the authentication error.");
+ }
+ catch (JMSException e)
+ {
+ check403Exception(e.getLinkedException());
+ }
+ }
+
+ public void testServerConsumeFromNamedQueueValid() throws AMQException, URLSyntaxException, Exception
+ {
+ try
+ {
+ Connection conn = getConnection("test", "server", "guest");
+
+ Session sess = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
+
+ conn.start();
+
+ sess.createConsumer(sess.createQueue("example.RequestQueue"));
+
+ conn.close();
+ }
+ catch (Exception e)
+ {
+ fail("Test failed due to:" + e.getMessage());
+ }
+ }
+
+ public void testServerConsumeFromNamedQueueInvalid() throws AMQException, URLSyntaxException, NamingException, Exception
+ {
+ try
+ {
+ Connection conn = getConnection("test", "client", "guest");
+
+ Session sess = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
+
+ conn.start();
+
+ sess.createConsumer(sess.createQueue("Invalid"));
+
+ fail("Test failed as consumer was created.");
+ }
+ catch (JMSException e)
+ {
+ check403Exception(e.getLinkedException());
+ }
+ }
+
+ public void testServerConsumeFromTemporaryQueue() throws AMQException, URLSyntaxException, NamingException, Exception
+ {
+ try
+ {
+ Connection conn = getConnection("test", "server", "guest");
+
+ Session sess = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
+
+ conn.start();
+
+ sess.createConsumer(sess.createTemporaryQueue());
+
+ fail("Test failed as consumer was created.");
+ }
+ catch (JMSException e)
+ {
+ check403Exception(e.getLinkedException());
+ }
+ }
+
+ public void testServerCreateNamedQueueValid() throws JMSException, URLSyntaxException, Exception
+ {
+ try
+ {
+ Connection conn = getConnection("test", "server", "guest");
+
+ Session sess = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
+
+ conn.start();
+
+ //Create Temporary Queue
+ ((AMQSession<?, ?>) sess).createQueue(new AMQShortString("example.RequestQueue"), false, false, false);
+
+ conn.close();
+ }
+ catch (Exception e)
+ {
+ fail("Test failed due to:" + e.getMessage());
+ }
+ }
+
+ public void testServerCreateNamedQueueInvalid() throws JMSException, URLSyntaxException, AMQException, NamingException, Exception
+ {
+ try
+ {
+ Connection conn = getConnection("test", "server", "guest");
+
+ Session sess = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
+
+ conn.start();
+
+ //Create a Named Queue
+ ((AMQSession<?, ?>) sess).createQueue(new AMQShortString("IllegalQueue"), false, false, false);
+
+ fail("Test failed as creation succeded.");
+ }
+ catch (Exception e)
+ {
+ check403Exception(e);
+ }
+ }
+
+ public void testServerCreateTemporaryQueueInvalid() throws NamingException, Exception
+ {
+ try
+ {
+ Connection conn = getConnection("test", "server", "guest");
+ Session session = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
+
+ conn.start();
+
+ session.createTemporaryQueue();
+
+ fail("Test failed as creation succeded.");
+ }
+ catch (JMSException e)
+ {
+ check403Exception(e.getLinkedException());
+ }
+ }
+
+ public void testServerCreateAutoDeleteQueueInvalid() throws NamingException, JMSException, AMQException, Exception
+ {
+ try
+ {
+ Connection connection = getConnection("test", "server", "guest");
+
+ Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
+
+ connection.start();
+
+ ((AMQSession<?, ?>) session).createQueue(new AMQShortString("again_ensure_auto_delete_queue_for_temporary"),
+ true, false, false);
+
+ fail("Test failed as creation succeded.");
+ }
+ catch (Exception e)
+ {
+ check403Exception(e);
+ }
+ }
+
+ /**
+ * This test uses both the cilent and sender to validate that the Server is able to publish to a temporary queue.
+ * The reason the client must be involved is that the Server is unable to create its own Temporary Queues.
+ *
+ * @throws AMQException
+ * @throws URLSyntaxException
+ * @throws JMSException
+ */
+ public void testServerPublishUsingTransactionSuccess() throws AMQException, URLSyntaxException, JMSException, NamingException, Exception
+ {
+ //Set up the Server
+ Connection serverConnection = getConnection("test", "server", "guest");
+
+ Session serverSession = serverConnection.createSession(true, Session.SESSION_TRANSACTED);
+
+ Queue requestQueue = serverSession.createQueue("example.RequestQueue");
+
+ MessageConsumer server = serverSession.createConsumer(requestQueue);
+
+ serverConnection.start();
+
+ //Set up the consumer
+ Connection clientConnection = getConnection("test", "client", "guest");
+
+ //Send a test mesage
+ Session clientSession = clientConnection.createSession(false, Session.AUTO_ACKNOWLEDGE);
+
+ Queue responseQueue = clientSession.createTemporaryQueue();
+
+ MessageConsumer clientResponse = clientSession.createConsumer(responseQueue);
+
+ clientConnection.start();
+
+ Message request = clientSession.createTextMessage("Request");
+
+ assertNotNull("Response Queue is null", responseQueue);
+
+ request.setJMSReplyTo(responseQueue);
+
+ clientSession.createProducer(requestQueue).send(request);
+
+ try
+ {
+ Message msg = null;
+
+ msg = server.receive(2000);
+
+ while (msg != null && !((TextMessage) msg).getText().equals("Request"))
+ {
+ msg = server.receive(2000);
+ }
+
+ assertNotNull("Message not received", msg);
+
+ assertNotNull("Reply-To is Null", msg.getJMSReplyTo());
+
+ MessageProducer sender = serverSession.createProducer(msg.getJMSReplyTo());
+
+ sender.send(serverSession.createTextMessage("Response"));
+
+ //Send the message using a transaction as this will allow us to retrieve any errors that occur on the broker.
+ serverSession.commit();
+
+ //Ensure Response is received.
+ Message clientResponseMsg = clientResponse.receive(2000);
+ assertNotNull("Client did not receive response message,", clientResponseMsg);
+ assertEquals("Incorrect message received", "Response", ((TextMessage) clientResponseMsg).getText());
+
+ }
+ catch (Exception e)
+ {
+ fail("Test publish failed:" + e);
+ }
+ finally
+ {
+ try
+ {
+ serverConnection.close();
+ }
+ finally
+ {
+ clientConnection.close();
+ }
+ }
+ }
+
+ public void testServerPublishInvalidQueueSuccess() throws AMQException, URLSyntaxException, JMSException, NamingException, Exception
+ {
+ try
+ {
+ Connection conn = getConnection("test", "server", "guest");
+
+ ((AMQConnection) conn).setConnectionListener(this);
+
+ Session session = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
+
+ conn.start();
+
+ MessageProducer sender = ((AMQSession<?, ?>) session).createProducer(null);
+
+ Queue queue = session.createQueue("Invalid");
+
+ // Send a message that we will wait to be sent, this should give the broker time to close the connection
+ // before we finish this test. Message is set !immed !mand as the queue is invalid so want to test ACLs not
+ // queue existence.
+ ((org.apache.qpid.jms.MessageProducer) sender).send(queue, session.createTextMessage("test"),
+ DeliveryMode.NON_PERSISTENT, 0, 0L, false, false, true);
+
+ // Test the connection with a valid consumer
+ // This may not work as the session may be closed before the queue or consumer creation can occur.
+ // The correct JMSexception with linked error will only occur when the close method is recevied whilst in
+ // the failover safe block
+ session.createConsumer(session.createQueue("example.RequestQueue")).close();
+
+ //Connection should now be closed and will throw the exception caused by the above send
+ conn.close();
+
+ fail("Close is not expected to succeed.");
+ }
+ catch (IllegalStateException e)
+ {
+ _logger.info("QPID-2345: Session became closed and we got that error rather than the authentication error.");
+ }
+ catch (JMSException e)
+ {
+ check403Exception(e.getLinkedException());
+ }
+ }
+}
diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/server/security/firewall/FirewallConfigTest.java b/qpid/java/systests/src/main/java/org/apache/qpid/server/security/firewall/FirewallConfigTest.java
index 2d99a44532..f40e95885d 100644
--- a/qpid/java/systests/src/main/java/org/apache/qpid/server/security/firewall/FirewallConfigTest.java
+++ b/qpid/java/systests/src/main/java/org/apache/qpid/server/security/firewall/FirewallConfigTest.java
@@ -85,6 +85,12 @@ public class FirewallConfigTest extends QpidBrokerTestCase
public void testVhostAllowBrokerDeny() throws Exception
{
+ if (_broker.equals(VM))
+ {
+ //No point running this test with an InVM broker as the
+ //firewall plugin only functions for TCP connections.
+ return;
+ }
_configFile = new File(System.getProperty("QPID_HOME"), "etc/config-systests-firewall-2.xml");
@@ -119,6 +125,13 @@ public class FirewallConfigTest extends QpidBrokerTestCase
public void testVhostDenyBrokerAllow() throws Exception
{
+ if (_broker.equals(VM))
+ {
+ //No point running this test with an InVM broker as the
+ //firewall plugin only functions for TCP connections.
+ return;
+ }
+
_configFile = new File(System.getProperty("QPID_HOME"), "etc/config-systests-firewall-3.xml");
super.setUp();
@@ -264,6 +277,11 @@ public class FirewallConfigTest extends QpidBrokerTestCase
private void testFirewall(boolean initial, boolean inVhost, Runnable restartOrReload) throws Exception
{
+ if (_broker.equals(VM))
+ {
+ // No point running this test in a vm broker
+ return;
+ }
writeFirewallFile(initial, inVhost);
setConfigurationProperty("management.enabled", String.valueOf(true));
diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/test/client/destination/AddressBasedDestinationTest.java b/qpid/java/systests/src/main/java/org/apache/qpid/test/client/destination/AddressBasedDestinationTest.java
index b5bb74327e..51589c705f 100644
--- a/qpid/java/systests/src/main/java/org/apache/qpid/test/client/destination/AddressBasedDestinationTest.java
+++ b/qpid/java/systests/src/main/java/org/apache/qpid/test/client/destination/AddressBasedDestinationTest.java
@@ -25,37 +25,25 @@ import java.util.Collections;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Map;
-import java.util.Properties;
-
import javax.jms.Connection;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.MessageProducer;
-import javax.jms.Queue;
-import javax.jms.QueueReceiver;
-import javax.jms.QueueSession;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.jms.Topic;
-import javax.jms.TopicSession;
-import javax.jms.TopicSubscriber;
import javax.naming.Context;
-import javax.naming.InitialContext;
import org.apache.qpid.client.AMQAnyDestination;
-import org.apache.qpid.client.AMQConnection;
import org.apache.qpid.client.AMQDestination;
-import org.apache.qpid.client.AMQSession;
import org.apache.qpid.client.AMQSession_0_10;
-import org.apache.qpid.client.message.QpidMessageProperties;
import org.apache.qpid.client.messaging.address.Node.ExchangeNode;
import org.apache.qpid.client.messaging.address.Node.QueueNode;
import org.apache.qpid.jndi.PropertiesFileInitialContextFactory;
import org.apache.qpid.messaging.Address;
import org.apache.qpid.test.utils.QpidBrokerTestCase;
-import org.apache.qpid.transport.ExecutionErrorCode;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -199,7 +187,9 @@ public class AddressBasedDestinationTest extends QpidBrokerTestCase
dest.getAddressName(),dest.getAddressName(), dest.getSourceNode().getDeclareArgs()));
}
-
+
+ // todo add tests for delete options
+
public void testCreateQueue() throws Exception
{
Session jmsSession = _connection.createSession(false,Session.AUTO_ACKNOWLEDGE);
@@ -212,7 +202,7 @@ public class AddressBasedDestinationTest extends QpidBrokerTestCase
"durable: true ," +
"x-declare: " +
"{" +
- "exclusive: true," +
+ "auto-delete: true," +
"arguments: {" +
"'qpid.max_size': 1000," +
"'qpid.max_count': 100" +
@@ -228,9 +218,6 @@ public class AddressBasedDestinationTest extends QpidBrokerTestCase
"}";
AMQDestination dest = new AMQAnyDestination(addr);
MessageConsumer cons = jmsSession.createConsumer(dest);
- cons.close();
-
- // Even if the consumer is closed the queue and the bindings should be intact.
assertTrue("Queue not created as expected",(
(AMQSession_0_10)jmsSession).isQueueExist(dest,(QueueNode)dest.getSourceNode(), true));
@@ -259,44 +246,12 @@ public class AddressBasedDestinationTest extends QpidBrokerTestCase
(AMQSession_0_10)jmsSession).isQueueBound("amq.match",
dest.getAddressName(),null, args));
- MessageProducer prod = jmsSession.createProducer(dest);
- prod.send(jmsSession.createTextMessage("test"));
-
- MessageConsumer cons2 = jmsSession.createConsumer(jmsSession.createQueue("ADDR:my-queue"));
- Message m = cons2.receive(1000);
- assertNotNull("Should receive message sent to my-queue",m);
- assertEquals("The subject set in the message is incorrect","hello",m.getStringProperty(QpidMessageProperties.QPID_SUBJECT));
}
public void testCreateExchange() throws Exception
{
- createExchangeImpl(false, false);
- }
-
- /**
- * Verify creating an exchange via an Address, with supported
- * exchange-declare arguments.
- */
- public void testCreateExchangeWithArgs() throws Exception
- {
- createExchangeImpl(true, false);
- }
-
- /**
- * Verify that when creating an exchange via an Address, if a
- * nonsense argument is specified the broker throws an execution
- * exception back on the session with NOT_IMPLEMENTED status.
- */
- public void testCreateExchangeWithNonsenseArgs() throws Exception
- {
- createExchangeImpl(true, true);
- }
-
- private void createExchangeImpl(final boolean withExchangeArgs,
- final boolean useNonsenseArguments) throws Exception
- {
Session jmsSession = _connection.createSession(false,Session.AUTO_ACKNOWLEDGE);
-
+
String addr = "ADDR:my-exchange/hello; " +
"{ " +
"create: always, " +
@@ -306,36 +261,17 @@ public class AddressBasedDestinationTest extends QpidBrokerTestCase
"x-declare: " +
"{ " +
"type:direct, " +
- "auto-delete: true" +
- createExchangeArgsString(withExchangeArgs, useNonsenseArguments) +
+ "auto-delete: true, " +
+ "arguments: {" +
+ "'qpid.msg_sequence': 1, " +
+ "'qpid.ive': 1" +
+ "}" +
"}" +
"}" +
"}";
AMQDestination dest = new AMQAnyDestination(addr);
-
- MessageConsumer cons;
- try
- {
- cons = jmsSession.createConsumer(dest);
- if(useNonsenseArguments)
- {
- fail("Expected execution exception during exchange declare did not occur");
- }
- }
- catch(JMSException e)
- {
- if(useNonsenseArguments && e.getCause().getMessage().contains(ExecutionErrorCode.NOT_IMPLEMENTED.toString()))
- {
- //expected because we used an argument which the broker doesn't have functionality
- //for. We can't do the rest of the test as a result of the exception, just stop.
- return;
- }
- else
- {
- fail("Unexpected exception whilst creating consumer: " + e);
- }
- }
+ MessageConsumer cons = jmsSession.createConsumer(dest);
assertTrue("Exchange not created as expected",(
(AMQSession_0_10)jmsSession).isExchangeExist(dest, (ExchangeNode)dest.getTargetNode() , true));
@@ -350,66 +286,16 @@ public class AddressBasedDestinationTest extends QpidBrokerTestCase
cons = jmsSession.createConsumer(dest);
}
- private String createExchangeArgsString(final boolean withExchangeArgs,
- final boolean useNonsenseArguments)
- {
- String argsString;
-
- if(withExchangeArgs && useNonsenseArguments)
- {
- argsString = ", arguments: {" +
- "'abcd.1234.wxyz': 1, " +
- "}";
- }
- else if(withExchangeArgs)
- {
- argsString = ", arguments: {" +
- "'qpid.msg_sequence': 1, " +
- "'qpid.ive': 1" +
- "}";
- }
- else
- {
- argsString = "";
- }
-
- return argsString;
- }
-
- public void checkQueueForBindings(Session jmsSession, AMQDestination dest,String headersBinding) throws Exception
- {
- assertTrue("Queue not created as expected",(
- (AMQSession_0_10)jmsSession).isQueueExist(dest,(QueueNode)dest.getSourceNode(), true));
-
- assertTrue("Queue not bound as expected",(
- (AMQSession_0_10)jmsSession).isQueueBound("",
- dest.getAddressName(),dest.getAddressName(), null));
-
- assertTrue("Queue not bound as expected",(
- (AMQSession_0_10)jmsSession).isQueueBound("amq.direct",
- dest.getAddressName(),"test", null));
-
- assertTrue("Queue not bound as expected",(
- (AMQSession_0_10)jmsSession).isQueueBound("amq.topic",
- dest.getAddressName(),"a.#", null));
-
- Address a = Address.parse(headersBinding);
- assertTrue("Queue not bound as expected",(
- (AMQSession_0_10)jmsSession).isQueueBound("amq.match",
- dest.getAddressName(),null, a.getOptions()));
- }
-
- /**
- * Test goal: Verifies that a producer and consumer creation triggers the correct
- * behavior for x-bindings specified in node props.
- */
public void testBindQueueWithArgs() throws Exception
{
+ Session jmsSession = _connection.createSession(false,Session.AUTO_ACKNOWLEDGE);
- Session jmsSession = _connection.createSession(false,Session.AUTO_ACKNOWLEDGE);
String headersBinding = "{exchange: 'amq.match', arguments: {x-match: any, dep: sales, loc: CA}}";
- String addr = "node: " +
+ String addr = "ADDR:my-queue/hello; " +
+ "{ " +
+ "create: always, " +
+ "node: " +
"{" +
"durable: true ," +
"x-declare: " +
@@ -424,14 +310,28 @@ public class AddressBasedDestinationTest extends QpidBrokerTestCase
"}" +
"}";
+ AMQDestination dest = new AMQAnyDestination(addr);
+ MessageConsumer cons = jmsSession.createConsumer(dest);
+
+ assertTrue("Queue not created as expected",(
+ (AMQSession_0_10)jmsSession).isQueueExist(dest,(QueueNode)dest.getSourceNode(), true));
+
+ assertTrue("Queue not bound as expected",(
+ (AMQSession_0_10)jmsSession).isQueueBound("",
+ dest.getAddressName(),dest.getAddressName(), null));
- AMQDestination dest1 = new AMQAnyDestination("ADDR:my-queue/hello; {create: receiver, " +addr);
- MessageConsumer cons = jmsSession.createConsumer(dest1);
- checkQueueForBindings(jmsSession,dest1,headersBinding);
+ assertTrue("Queue not bound as expected",(
+ (AMQSession_0_10)jmsSession).isQueueBound("amq.direct",
+ dest.getAddressName(),"test", null));
+
+ assertTrue("Queue not bound as expected",(
+ (AMQSession_0_10)jmsSession).isQueueBound("amq.topic",
+ dest.getAddressName(),"a.#", null));
- AMQDestination dest2 = new AMQAnyDestination("ADDR:my-queue2/hello; {create: sender, " +addr);
- MessageProducer prod = jmsSession.createProducer(dest2);
- checkQueueForBindings(jmsSession,dest2,headersBinding);
+ Address a = Address.parse(headersBinding);
+ assertTrue("Queue not bound as expected",(
+ (AMQSession_0_10)jmsSession).isQueueBound("amq.match",
+ dest.getAddressName(),null, a.getOptions()));
}
/**
@@ -567,6 +467,39 @@ public class AddressBasedDestinationTest extends QpidBrokerTestCase
}
/**
+ * Test goal: Verifies that and address based destination can be used successfully
+ * as a reply to.
+ */
+ public void testAddressBasedReplyTo() throws Exception
+ {
+ Session jmsSession = _connection.createSession(false,Session.AUTO_ACKNOWLEDGE);
+
+ String addr = "ADDR:amq.direct/x512; {create: receiver, " +
+ "link : {name : 'MY.RESP.QUEUE', " +
+ "x-declare : { auto-delete: true, exclusive: true, " +
+ "arguments : {'qpid.max_size': 1000, 'qpid.policy_type': ring }} } }";
+
+ Destination replyTo = new AMQAnyDestination(addr);
+ Destination dest =new AMQAnyDestination("ADDR:amq.direct/Hello");
+
+ MessageConsumer cons = jmsSession.createConsumer(dest);
+ MessageProducer prod = jmsSession.createProducer(dest);
+ Message m = jmsSession.createTextMessage("Hello");
+ m.setJMSReplyTo(replyTo);
+ prod.send(m);
+
+ Message msg = cons.receive(1000);
+ assertNotNull("consumer should have received the message",msg);
+
+ MessageConsumer replyToCons = jmsSession.createConsumer(replyTo);
+ MessageProducer replyToProd = jmsSession.createProducer(msg.getJMSReplyTo());
+ replyToProd.send(jmsSession.createTextMessage("reply"));
+
+ Message replyToMsg = replyToCons.receive(1000);
+ assertNotNull("The reply to consumer should have got the message",replyToMsg);
+ }
+
+ /**
* Test goal: Verifies that session.createQueue method
* works as expected both with the new and old addressing scheme.
*/
@@ -587,22 +520,7 @@ public class AddressBasedDestinationTest extends QpidBrokerTestCase
cons.close();
// Using the ADDR method
- // default case
queue = ssn.createQueue("ADDR:my-queue2");
- try
- {
- prod = ssn.createProducer(queue);
- fail("The client should throw an exception, since there is no queue present in the broker");
- }
- catch(Exception e)
- {
- String s = "The name 'my-queue2' supplied in the address " +
- "doesn't resolve to an exchange or a queue";
- assertEquals(s,e.getCause().getCause().getMessage());
- }
-
- // explicit create case
- queue = ssn.createQueue("ADDR:my-queue2; {create: sender}");
prod = ssn.createProducer(queue);
cons = ssn.createConsumer(queue);
assertTrue("my-queue2 was not created as expected",(
@@ -629,25 +547,11 @@ public class AddressBasedDestinationTest extends QpidBrokerTestCase
}
/**
- * Test goal: Verifies that session.creatTopic method works as expected
- * both with the new and old addressing scheme.
+ * Test goal: Verifies that session.creatTopic method
+ * works as expected both with the new and old addressing scheme.
*/
public void testSessionCreateTopic() throws Exception
{
- sessionCreateTopicImpl(false);
- }
-
- /**
- * Test goal: Verifies that session.creatTopic method works as expected
- * both with the new and old addressing scheme when adding exchange arguments.
- */
- public void testSessionCreateTopicWithExchangeArgs() throws Exception
- {
- sessionCreateTopicImpl(true);
- }
-
- private void sessionCreateTopicImpl(boolean withExchangeArgs) throws Exception
- {
Session ssn = _connection.createSession(false,Session.AUTO_ACKNOWLEDGE);
// Using the BURL method
@@ -667,7 +571,7 @@ public class AddressBasedDestinationTest extends QpidBrokerTestCase
prod.send(ssn.createTextMessage("test"));
assertNotNull("consumer should receive a message",cons.receive(1000));
cons.close();
-
+
String addr = "ADDR:vehicles/bus; " +
"{ " +
"create: always, " +
@@ -677,8 +581,11 @@ public class AddressBasedDestinationTest extends QpidBrokerTestCase
"x-declare: " +
"{ " +
"type:direct, " +
- "auto-delete: true" +
- createExchangeArgsString(withExchangeArgs, false) +
+ "auto-delete: true, " +
+ "arguments: {" +
+ "'qpid.msg_sequence': 1, " +
+ "'qpid.ive': 1" +
+ "}" +
"}" +
"}, " +
"link: {name : my-topic, " +
@@ -790,7 +697,7 @@ public class AddressBasedDestinationTest extends QpidBrokerTestCase
public void testSubscriptionForSameDestination() throws Exception
{
Session ssn = _connection.createSession(false,Session.AUTO_ACKNOWLEDGE);
- Destination dest = ssn.createTopic("ADDR:amq.topic/foo; {link:{durable:true}}");
+ Destination dest = ssn.createTopic("ADDR:amq.topic/foo");
MessageConsumer consumer1 = ssn.createConsumer(dest);
MessageConsumer consumer2 = ssn.createConsumer(dest);
MessageProducer prod = ssn.createProducer(dest);
@@ -889,297 +796,4 @@ public class AddressBasedDestinationTest extends QpidBrokerTestCase
{
}
}
-
- public void testQueueReceiversAndTopicSubscriber() throws Exception
- {
- Queue queue = new AMQAnyDestination("ADDR:my-queue; {create: always}");
- Topic topic = new AMQAnyDestination("ADDR:amq.topic/test");
-
- QueueSession qSession = ((AMQConnection)_connection).createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
- QueueReceiver receiver = qSession.createReceiver(queue);
-
- TopicSession tSession = ((AMQConnection)_connection).createTopicSession(false, Session.AUTO_ACKNOWLEDGE);
- TopicSubscriber sub = tSession.createSubscriber(topic);
-
- Session ssn = _connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
- MessageProducer prod1 = ssn.createProducer(ssn.createQueue("ADDR:my-queue"));
- prod1.send(ssn.createTextMessage("test1"));
-
- MessageProducer prod2 = ssn.createProducer(ssn.createTopic("ADDR:amq.topic/test"));
- prod2.send(ssn.createTextMessage("test2"));
-
- Message msg1 = receiver.receive();
- assertNotNull(msg1);
- assertEquals("test1",((TextMessage)msg1).getText());
-
- Message msg2 = sub.receive();
- assertNotNull(msg2);
- assertEquals("test2",((TextMessage)msg2).getText());
- }
-
- public void testDurableSubscriber() throws Exception
- {
- Session ssn = _connection.createSession(false,Session.AUTO_ACKNOWLEDGE);
-
- Properties props = new Properties();
- props.setProperty("java.naming.factory.initial", "org.apache.qpid.jndi.PropertiesFileInitialContextFactory");
- props.setProperty("destination.address1", "ADDR:amq.topic");
- props.setProperty("destination.address2", "ADDR:amq.direct/test");
- String addrStr = "ADDR:amq.topic/test; {link:{name: my-topic," +
- "x-bindings:[{key:'NYSE.#'},{key:'NASDAQ.#'},{key:'CNTL.#'}]}}";
- props.setProperty("destination.address3", addrStr);
- props.setProperty("topic.address4", "hello.world");
- addrStr = "ADDR:my_queue; {create:always,link: {x-subscribes:{exclusive: true, arguments: {a:b,x:y}}}}";
- props.setProperty("destination.address5", addrStr);
-
- Context ctx = new InitialContext(props);
-
- for (int i=1; i < 5; i++)
- {
- Topic topic = (Topic) ctx.lookup("address"+i);
- createDurableSubscriber(ctx,ssn,"address"+i,topic);
- }
-
- Topic topic = ssn.createTopic("ADDR:news.us");
- createDurableSubscriber(ctx,ssn,"my-dest",topic);
-
- Topic namedQueue = (Topic) ctx.lookup("address5");
- try
- {
- createDurableSubscriber(ctx,ssn,"my-queue",namedQueue);
- fail("Exception should be thrown. Durable subscribers cannot be created for Queues");
- }
- catch(JMSException e)
- {
- assertEquals("Durable subscribers can only be created for Topics",
- e.getMessage());
- }
- }
-
- private void createDurableSubscriber(Context ctx,Session ssn,String destName,Topic topic) throws Exception
- {
- MessageConsumer cons = ssn.createDurableSubscriber(topic, destName);
- MessageProducer prod = ssn.createProducer(topic);
-
- Message m = ssn.createTextMessage(destName);
- prod.send(m);
- Message msg = cons.receive(1000);
- assertNotNull(msg);
- assertEquals(destName,((TextMessage)msg).getText());
- ssn.unsubscribe(destName);
- }
-
- public void testDeleteOptions() throws Exception
- {
- Session jmsSession = _connection.createSession(false,Session.AUTO_ACKNOWLEDGE);
- MessageConsumer cons;
-
- // default (create never, assert never) -------------------
- // create never --------------------------------------------
- String addr1 = "ADDR:testQueue1;{create: always, delete: always}";
- AMQDestination dest = new AMQAnyDestination(addr1);
- try
- {
- cons = jmsSession.createConsumer(dest);
- cons.close();
- }
- catch(JMSException e)
- {
- fail("Exception should not be thrown. Exception thrown is : " + e);
- }
-
- assertFalse("Queue not deleted as expected",(
- (AMQSession_0_10)jmsSession).isQueueExist(dest,(QueueNode)dest.getSourceNode(), true));
-
-
- String addr2 = "ADDR:testQueue2;{create: always, delete: receiver}";
- dest = new AMQAnyDestination(addr2);
- try
- {
- cons = jmsSession.createConsumer(dest);
- cons.close();
- }
- catch(JMSException e)
- {
- fail("Exception should not be thrown. Exception thrown is : " + e);
- }
-
- assertFalse("Queue not deleted as expected",(
- (AMQSession_0_10)jmsSession).isQueueExist(dest,(QueueNode)dest.getSourceNode(), true));
-
-
- String addr3 = "ADDR:testQueue3;{create: always, delete: sender}";
- dest = new AMQAnyDestination(addr3);
- try
- {
- cons = jmsSession.createConsumer(dest);
- MessageProducer prod = jmsSession.createProducer(dest);
- prod.close();
- }
- catch(JMSException e)
- {
- fail("Exception should not be thrown. Exception thrown is : " + e);
- }
-
- assertFalse("Queue not deleted as expected",(
- (AMQSession_0_10)jmsSession).isQueueExist(dest,(QueueNode)dest.getSourceNode(), true));
-
-
- }
-
- /**
- * Test Goals : 1. Test if the client sets the correct accept mode for unreliable
- * and at-least-once.
- * 2. Test default reliability modes for Queues and Topics.
- * 3. Test if an exception is thrown if exactly-once is used.
- * 4. Test if an exception is thrown if at-least-once is used with topics.
- *
- * Test Strategy: For goal #1 & #2
- * For unreliable and at-least-once the test tries to receives messages
- * in client_ack mode but does not ack the messages.
- * It will then close the session, recreate a new session
- * and will then try to verify the queue depth.
- * For unreliable the messages should have been taken off the queue.
- * For at-least-once the messages should be put back onto the queue.
- *
- */
-
- public void testReliabilityOptions() throws Exception
- {
- String addr1 = "ADDR:testQueue1;{create: always, delete : receiver, link : {reliability : unreliable}}";
- acceptModeTest(addr1,0);
-
- String addr2 = "ADDR:testQueue2;{create: always, delete : receiver, link : {reliability : at-least-once}}";
- acceptModeTest(addr2,2);
-
- // Default accept-mode for topics
- acceptModeTest("ADDR:amq.topic/test",0);
-
- // Default accept-mode for queues
- acceptModeTest("ADDR:testQueue1;{create: always}",2);
-
- String addr3 = "ADDR:testQueue2;{create: always, delete : receiver, link : {reliability : exactly-once}}";
- try
- {
- AMQAnyDestination dest = new AMQAnyDestination(addr3);
- fail("An exception should be thrown indicating it's an unsupported type");
- }
- catch(Exception e)
- {
- assertTrue(e.getCause().getMessage().contains("The reliability mode 'exactly-once' is not yet supported"));
- }
-
- String addr4 = "ADDR:amq.topic/test;{link : {reliability : at-least-once}}";
- try
- {
- AMQAnyDestination dest = new AMQAnyDestination(addr4);
- Session ssn = _connection.createSession(false,Session.CLIENT_ACKNOWLEDGE);
- MessageConsumer cons = ssn.createConsumer(dest);
- fail("An exception should be thrown indicating it's an unsupported combination");
- }
- catch(Exception e)
- {
- assertTrue(e.getCause().getMessage().contains("AT-LEAST-ONCE is not yet supported for Topics"));
- }
- }
-
- private void acceptModeTest(String address, int expectedQueueDepth) throws Exception
- {
- Session ssn = _connection.createSession(false,Session.CLIENT_ACKNOWLEDGE);
- MessageConsumer cons;
- MessageProducer prod;
-
- AMQDestination dest = new AMQAnyDestination(address);
- cons = ssn.createConsumer(dest);
- prod = ssn.createProducer(dest);
-
- for (int i=0; i < expectedQueueDepth; i++)
- {
- prod.send(ssn.createTextMessage("Msg" + i));
- }
-
- for (int i=0; i < expectedQueueDepth; i++)
- {
- Message msg = cons.receive(1000);
- assertNotNull(msg);
- assertEquals("Msg" + i,((TextMessage)msg).getText());
- }
-
- ssn.close();
- ssn = _connection.createSession(false,Session.CLIENT_ACKNOWLEDGE);
- long queueDepth = ((AMQSession) ssn).getQueueDepth(dest);
- assertEquals(expectedQueueDepth,queueDepth);
- cons.close();
- prod.close();
- }
-
- public void testDestinationOnSend() throws Exception
- {
- Session ssn = _connection.createSession(false,Session.CLIENT_ACKNOWLEDGE);
- MessageConsumer cons = ssn.createConsumer(ssn.createTopic("amq.topic/test"));
- MessageProducer prod = ssn.createProducer(null);
-
- Queue queue = ssn.createQueue("amq.topic/test");
- prod.send(queue,ssn.createTextMessage("A"));
-
- Message msg = cons.receive(1000);
- assertNotNull(msg);
- assertEquals("A",((TextMessage)msg).getText());
- prod.close();
- cons.close();
- }
-
- public void testReplyToWithNamelessExchange() throws Exception
- {
- System.setProperty("qpid.declare_exchanges","false");
- replyToTest("ADDR:my-queue;{create: always}");
- System.setProperty("qpid.declare_exchanges","true");
- }
-
- public void testReplyToWithCustomExchange() throws Exception
- {
- replyToTest("ADDR:hello;{create:always,node:{type:topic}}");
- }
-
- private void replyToTest(String replyTo) throws Exception
- {
- Session session = _connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
- Destination replyToDest = AMQDestination.createDestination(replyTo);
- MessageConsumer replyToCons = session.createConsumer(replyToDest);
-
- Destination dest = session.createQueue("amq.direct/test");
-
- MessageConsumer cons = session.createConsumer(dest);
- MessageProducer prod = session.createProducer(dest);
- Message m = session.createTextMessage("test");
- m.setJMSReplyTo(replyToDest);
- prod.send(m);
-
- Message msg = cons.receive();
- MessageProducer prodR = session.createProducer(msg.getJMSReplyTo());
- prodR.send(session.createTextMessage("x"));
-
- Message m1 = replyToCons.receive();
- assertNotNull("The reply to consumer should have received the messsage",m1);
- }
-
- public void testAltExchangeInAddressString() throws Exception
- {
- String addr1 = "ADDR:my-exchange/test; {create: always, node:{type: topic,x-declare:{alternate-exchange:'amq.fanout'}}}";
- Session session = _connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
- String altQueueAddr = "ADDR:my-alt-queue;{create: always, delete: receiver,node:{x-bindings:[{exchange:'amq.fanout'}] }}";
- MessageConsumer cons = session.createConsumer(session.createQueue(altQueueAddr));
-
- MessageProducer prod = session.createProducer(session.createTopic(addr1));
- prod.send(session.createMessage());
- prod.close();
- assertNotNull("The consumer on the queue bound to the alt-exchange should receive the message",cons.receive(1000));
-
- String addr2 = "ADDR:test-queue;{create:sender, delete: sender,node:{type:queue,x-declare:{alternate-exchange:'amq.fanout'}}}";
- prod = session.createProducer(session.createTopic(addr2));
- prod.send(session.createMessage());
- prod.close();
- assertNotNull("The consumer on the queue bound to the alt-exchange should receive the message",cons.receive(1000));
- cons.close();
- }
}
diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/test/client/message/SelectorTest.java b/qpid/java/systests/src/main/java/org/apache/qpid/test/client/message/SelectorTest.java
index b1c8b5682f..49a608190d 100644
--- a/qpid/java/systests/src/main/java/org/apache/qpid/test/client/message/SelectorTest.java
+++ b/qpid/java/systests/src/main/java/org/apache/qpid/test/client/message/SelectorTest.java
@@ -23,7 +23,6 @@ package org.apache.qpid.test.client.message;
import java.util.concurrent.CountDownLatch;
import javax.jms.DeliveryMode;
-import javax.jms.Destination;
import javax.jms.InvalidSelectorException;
import javax.jms.JMSException;
import javax.jms.Message;
@@ -31,7 +30,6 @@ import javax.jms.MessageConsumer;
import javax.jms.MessageListener;
import javax.jms.MessageProducer;
import javax.jms.Session;
-import javax.jms.TextMessage;
import junit.framework.Assert;
@@ -52,6 +50,7 @@ public class SelectorTest extends QpidBrokerTestCase implements MessageListener
private AMQConnection _connection;
private AMQDestination _destination;
private int count;
+ public String _connectionString = "vm://:1";
private static final String INVALID_SELECTOR = "Cost LIKE 5";
CountDownLatch _responseLatch = new CountDownLatch(1);
@@ -281,36 +280,31 @@ public class SelectorTest extends QpidBrokerTestCase implements MessageListener
Assert.assertNotNull("Msg5 should not be null", msg5);
}
- public void testSelectorWithJMSDeliveryMode() throws Exception
+ public static void main(String[] argv) throws Exception
{
- Session session = _connection.createSession(false, Session.SESSION_TRANSACTED);
+ SelectorTest test = new SelectorTest();
+ test._connectionString = (argv.length == 0) ? "localhost:3000" : argv[0];
- Destination dest1 = session.createTopic("test1");
- Destination dest2 = session.createTopic("test2");
-
- MessageProducer prod1 = session.createProducer(dest1);
- MessageProducer prod2 = session.createProducer(dest2);
- MessageConsumer consumer1 = session.createConsumer(dest1,"JMSDeliveryMode = 'PERSISTENT'");
- MessageConsumer consumer2 = session.createConsumer(dest2,"JMSDeliveryMode = 'NON_PERSISTENT'");
-
- Message msg1 = session.createTextMessage("Persistent");
- prod1.send(msg1);
- prod2.send(msg1);
-
- prod1.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
- prod2.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
-
- Message msg2 = session.createTextMessage("Non_Persistent");
- prod1.send(msg2);
- prod2.send(msg2);
-
- TextMessage m1 = (TextMessage)consumer1.receive(1000);
- assertEquals("Consumer1 should receive the persistent message","Persistent",m1.getText());
- assertNull("Consumer1 should not receiver another message",consumer1.receive(1000));
-
- TextMessage m2 = (TextMessage)consumer2.receive(1000);
- assertEquals("Consumer2 should receive the non persistent message","Non_Persistent",m2.getText());
- assertNull("Consumer2 should not receiver another message",consumer2.receive(1000));
+ try
+ {
+ while (true)
+ {
+ if (test._connectionString.contains("vm://:1"))
+ {
+ test.setUp();
+ }
+ test.testUsingOnMessage();
+
+ if (test._connectionString.contains("vm://:1"))
+ {
+ test.tearDown();
+ }
+ }
+ }
+ catch (Exception e)
+ {
+ System.err.println(e.getMessage());
+ e.printStackTrace();
+ }
}
-
}
diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/test/framework/qpid/AMQPFeatureDecorator.java b/qpid/java/systests/src/main/java/org/apache/qpid/test/framework/qpid/AMQPFeatureDecorator.java
new file mode 100644
index 0000000000..c11f75e742
--- /dev/null
+++ b/qpid/java/systests/src/main/java/org/apache/qpid/test/framework/qpid/AMQPFeatureDecorator.java
@@ -0,0 +1,96 @@
+/*
+ *
+ * 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.framework.qpid;
+
+import junit.framework.Test;
+import junit.framework.TestResult;
+
+import org.apache.qpid.test.framework.FrameworkBaseCase;
+import org.apache.qpid.test.framework.LocalAMQPCircuitFactory;
+
+import org.apache.qpid.junit.extensions.WrappedSuiteTestDecorator;
+
+/**
+ * AMQPFeatureDecorator applies decorations to {@link FrameworkBaseCase} tests, so that they may use Qpid/AMQP specific
+ * features, not available through JMS. For example, the immediate and mandatory flags. This decorator replaces the
+ * standard test circuit factory on the base class with one that allows these features to be used.
+ *
+ * <p/><table id="crc"><caption>CRC Card</caption>
+ * <tr><th> Responsibilities <th> Collaborations
+ * <tr><td> Substitute the circuit factory with an AMQP/Qpid specific one.
+ * </table>
+ *
+ * @todo This wrapper substitutes in a LocalAMQPCircuitFactory, which is fine for local tests. For distributed tests
+ * the Fanout or Interop factories are substituted in by their decorators instead. These actually use
+ * distributed circuit static create methods to build the circuits, which should actually be changed to a factory,
+ * so that static methods do not need to be used. The distributed circuit creater delegates the circuit
+ * construction to remote test nodes. This decorator should not be used with distributed tests, or should be made
+ * aware of them, in which case it might ensure that an AMQP feature (implied already by other properties) flag
+ * is passed out to the remote test nodes, and provide a mechansim for them to decorate their circuit creation
+ * with AMQP features too. Add factory substituion/decoration mechansim for test clients, here or in a seperate
+ * class.
+ */
+public class AMQPFeatureDecorator extends WrappedSuiteTestDecorator
+{
+ /** The test suite to run. */
+ private Test test;
+
+ /**
+ * Creates a wrapped test test decorator from another one.
+ *
+ * @param test The test test.
+ */
+ public AMQPFeatureDecorator(WrappedSuiteTestDecorator test)
+ {
+ super(test);
+ this.test = test;
+ }
+
+ /**
+ * Runs the tests with a LocalAMQPCircuitFactory. Only tests that extend FrameworkBaseCase are decorated.
+ *
+ * @param testResult The the results object to monitor the test results with.
+ */
+ public void run(TestResult testResult)
+ {
+ for (Test test : getAllUnderlyingTests())
+ {
+ if (test instanceof FrameworkBaseCase)
+ {
+ FrameworkBaseCase frameworkTest = (FrameworkBaseCase) test;
+ frameworkTest.setCircuitFactory(new LocalAMQPCircuitFactory());
+ }
+ }
+
+ // Run the test.
+ test.run(testResult);
+ }
+
+ /**
+ * Prints the name of the test for debugging purposes.
+ *
+ * @return The name of the test.
+ */
+ public String toString()
+ {
+ return "AMQPFeatureDecorator: [test = \"" + test + "\"]";
+ }
+}
diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/test/framework/qpid/CauseFailureDecorator.java b/qpid/java/systests/src/main/java/org/apache/qpid/test/framework/qpid/CauseFailureDecorator.java
new file mode 100644
index 0000000000..2708253d86
--- /dev/null
+++ b/qpid/java/systests/src/main/java/org/apache/qpid/test/framework/qpid/CauseFailureDecorator.java
@@ -0,0 +1,95 @@
+/*
+ *
+ * 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.framework.qpid;
+
+import junit.framework.Test;
+import junit.framework.TestResult;
+
+import org.apache.qpid.test.framework.BrokerLifecycleAware;
+import org.apache.qpid.test.framework.CauseFailureUserPrompt;
+
+import org.apache.qpid.junit.extensions.WrappedSuiteTestDecorator;
+
+/**
+ * CauseFailureDecorator applies decorations to {@link BrokerLifecycleAware} tests, so that they may use different failure
+ * mechanisms. It is capable of detecting when a test case uses in-vm brokers, and setting up an automatic failure
+ * for those tests, so that the current live broker can be shut-down by test cases. For external brokers, automatic
+ * failure could be implemented, for example by having a kill script. At the moment this sets up the failure to prompt
+ * a user interactively to cause a failure, using {@link CauseFailureUserPrompt}.
+ *
+ * <p/><table id="crc"><caption>CRC Card</caption>
+ * <tr><th> Responsibilities <th> Collaborations
+ * <tr><td> Setup automatic failures for in-vm brokers. <td> {@link CauseFailureInVM}
+ * <tr><td> Setup user generated failures for external brokers. <td> {@link CauseFailureUserPrompt}.
+ * <tr><td>
+ * </table>
+ *
+ * @todo Slight problem in that CauseFailureInVM is Qpid specific, whereas CauseFailureUserPrompt is not. Would like the
+ * failure decorator to be non-qpid specific so that it can test failure of any JMS implementation too. Either pass
+ * in class name of failure mechanism, set it up in the in-vm decorator instead of here but with prompt user as the
+ * default for when the in-vm decorator is not used?
+ */
+public class CauseFailureDecorator extends WrappedSuiteTestDecorator
+{
+ /** The test suite to run. */
+ private Test test;
+
+ /**
+ * Creates a wrapped test test decorator from another one.
+ *
+ * @param test The test test.
+ */
+ public CauseFailureDecorator(WrappedSuiteTestDecorator test)
+ {
+ super(test);
+ this.test = test;
+ }
+
+ /**
+ * Runs the tests with a LocalAMQPCircuitFactory. Only tests that extend FrameworkBaseCase are decorated.
+ *
+ * @param testResult The the results object to monitor the test results with.
+ */
+ public void run(TestResult testResult)
+ {
+ for (Test test : getAllUnderlyingTests())
+ {
+ if (test instanceof BrokerLifecycleAware)
+ {
+ BrokerLifecycleAware failureTest = (BrokerLifecycleAware) test;
+ failureTest.setFailureMechanism(new CauseFailureUserPrompt());
+ }
+ }
+
+ // Run the test.
+ test.run(testResult);
+ }
+
+ /**
+ * Prints the name of the test for debugging purposes.
+ *
+ * @return The name of the test.
+ */
+ public String toString()
+ {
+ return "CauseFailureDecorator: [test = \"" + test + "\"]";
+ }
+}
diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/test/framework/qpid/CauseFailureInVM.java b/qpid/java/systests/src/main/java/org/apache/qpid/test/framework/qpid/CauseFailureInVM.java
new file mode 100644
index 0000000000..3e03ad0872
--- /dev/null
+++ b/qpid/java/systests/src/main/java/org/apache/qpid/test/framework/qpid/CauseFailureInVM.java
@@ -0,0 +1,70 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.test.framework.qpid;
+
+import org.apache.qpid.client.transport.TransportConnection;
+import org.apache.qpid.server.registry.ApplicationRegistry;
+import org.apache.qpid.test.framework.CauseFailure;
+import org.apache.qpid.test.framework.BrokerLifecycleAware;
+
+/**
+ * <p/><table id="crc"><caption>CRC Card</caption>
+ * <tr><th> Responsibilities <th> Collaborations
+ * <tr><td> Cause messaging broker failure on the active in-vm broker.
+ * <td> {@link TransportConnection}, {@link ApplicationRegistry}
+ * </table>
+ */
+public class CauseFailureInVM implements CauseFailure
+{
+ /** Holds the in-vm broker instrumented test case to create failures for. */
+ private BrokerLifecycleAware inVMTest;
+
+ /**
+ * Creates an automated failure mechanism for testing against in-vm brokers. The test to create the mechanism
+ * for is specified, and as this failure is for in-vm brokers, the test must be {@link org.apache.qpid.test.framework.BrokerLifecycleAware}. The test
+ * must also report that it is currently being run against an in-vm broker, and it is a runtime error if it is not,
+ * as the creator of this failure mechanism should already have checked that it is.
+ *
+ * @param inVMTest The test case to create an automated failure mechanism for.
+ */
+ public CauseFailureInVM(BrokerLifecycleAware inVMTest)
+ {
+ // Check that the test is really using in-vm brokers.
+ if (!inVMTest.usingInVmBroker())
+ {
+ throw new RuntimeException(
+ "Cannot create in-vm broker failure mechanism for a test that is not using in-vm brokers.");
+ }
+
+ this.inVMTest = inVMTest;
+ }
+
+ /**
+ * Causes the active message broker to fail.
+ */
+ public void causeFailure()
+ {
+ int liveBroker = inVMTest.getLiveBroker();
+
+ TransportConnection.killVMBroker(liveBroker);
+ ApplicationRegistry.remove(liveBroker);
+ }
+}
diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/test/framework/qpid/InVMBrokerDecorator.java b/qpid/java/systests/src/main/java/org/apache/qpid/test/framework/qpid/InVMBrokerDecorator.java
new file mode 100644
index 0000000000..b92a72a654
--- /dev/null
+++ b/qpid/java/systests/src/main/java/org/apache/qpid/test/framework/qpid/InVMBrokerDecorator.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.framework.qpid;
+
+import junit.framework.Test;
+import junit.framework.TestResult;
+
+import org.apache.qpid.client.transport.TransportConnection;
+import org.apache.qpid.client.vmbroker.AMQVMBrokerCreationException;
+import org.apache.qpid.server.registry.ApplicationRegistry;
+import org.apache.qpid.test.framework.BrokerLifecycleAware;
+import org.apache.qpid.test.framework.FrameworkBaseCase;
+
+import org.apache.qpid.junit.extensions.SetupTaskAware;
+import org.apache.qpid.junit.extensions.WrappedSuiteTestDecorator;
+
+/**
+ * InVMBrokerDecorator is a test decorator, that is activated when running tests against an in-vm broker only. Its
+ * purpose is to automatically create, and close and delete an in-vm broker, during the set-up and tear-down of
+ * each test case. This decorator may only be used in conjunction with tests that extend {@link FrameworkBaseCase}.
+ *
+ * <p/><table id="crc"><caption>CRC Card</caption>
+ * <tr><th> Responsibilities <th> Collaborations
+ * <tr><td> Create/Destroy an in-vm broker on every test run.
+ * </table>
+ *
+ * @todo May need to add a more fine grained injection point for the in-vm broker management, as this acts at the
+ * suite level, rather than the individual test level.
+ *
+ * @todo Management of in-vm brokers for failure testing. Failure test setups may need to set their connection url to
+ * use multiple broker (vm://:1;vm://:2), with fail-over between them. There is round-robin fail-over, but also
+ * retry? A test case using an in-vm broker needs to record which one it is using, so that it can be
+ * killed/restarted.
+ */
+public class InVMBrokerDecorator extends WrappedSuiteTestDecorator
+{
+ /** The test suite to run. */
+ private Test test;
+
+ /**
+ * Creates a wrapped test suite decorator from another one.
+ *
+ * @param test The test suite.
+ */
+ public InVMBrokerDecorator(WrappedSuiteTestDecorator test)
+ {
+ super(test);
+ this.test = test;
+ }
+
+ /**
+ * Runs the tests with in-vm broker creation and clean-up added to the tests task stack.
+ *
+ * @param testResult The the results object to monitor the test results with.
+ */
+ public void run(TestResult testResult)
+ {
+ for (Test test : getAllUnderlyingTests())
+ {
+ // Check that the test to have an in-vm broker setup/teardown task added to it, is actually a framework
+ // test that can handle setup tasks.
+ if ((test instanceof SetupTaskAware))
+ {
+ SetupTaskAware frameworkTest = (SetupTaskAware) test;
+
+ frameworkTest.chainSetupTask(new Runnable()
+ {
+ public void run()
+ {
+ // Ensure that the in-vm broker is created.
+ try
+ {
+ ApplicationRegistry.getInstance(1);
+ TransportConnection.createVMBroker(1);
+ }
+ catch (AMQVMBrokerCreationException e)
+ {
+ throw new RuntimeException("In-VM broker creation failed: " + e.getMessage(), e);
+ }
+ }
+ });
+
+ frameworkTest.chainTearDownTask(new Runnable()
+ {
+ public void run()
+ {
+ // Ensure that the in-vm broker is cleaned up so that the next test starts afresh.
+ TransportConnection.killVMBroker(1);
+ ApplicationRegistry.remove(1);
+ }
+ });
+
+ // Check if the test is aware whether or not it can control the broker life cycle, and if so provide
+ // additional instrumentation for it to control the in-vm broker through.
+ if (test instanceof BrokerLifecycleAware)
+ {
+ BrokerLifecycleAware inVMTest = (BrokerLifecycleAware) test;
+ inVMTest.setInVmBrokers();
+ inVMTest.setLiveBroker(1);
+ inVMTest.setFailureMechanism(new CauseFailureInVM(inVMTest));
+ }
+ }
+ }
+
+ // Run the test.
+ test.run(testResult);
+ }
+
+ /**
+ * Prints the name of the test for debugging purposes.
+ *
+ * @return The name of the test.
+ */
+ public String toString()
+ {
+ return "InVMBrokerDecorator: [test = " + test + "]";
+ }
+}
diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/test/unit/ack/Acknowledge2ConsumersTest.java b/qpid/java/systests/src/main/java/org/apache/qpid/test/unit/ack/Acknowledge2ConsumersTest.java
index 23efb656d2..4b45a96c20 100644
--- a/qpid/java/systests/src/main/java/org/apache/qpid/test/unit/ack/Acknowledge2ConsumersTest.java
+++ b/qpid/java/systests/src/main/java/org/apache/qpid/test/unit/ack/Acknowledge2ConsumersTest.java
@@ -23,7 +23,7 @@ package org.apache.qpid.test.unit.ack;
import org.apache.qpid.client.AMQDestination;
import org.apache.qpid.client.AMQSession;
-import org.apache.qpid.test.utils.QpidBrokerTestCase;
+import org.apache.qpid.test.utils.FailoverBaseCase;
import javax.jms.Connection;
import javax.jms.JMSException;
@@ -32,7 +32,7 @@ import javax.jms.MessageConsumer;
import javax.jms.Queue;
import javax.jms.Session;
-public class Acknowledge2ConsumersTest extends QpidBrokerTestCase
+public class Acknowledge2ConsumersTest extends FailoverBaseCase
{
protected static int NUM_MESSAGES = 100;
protected Connection _con;
diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/test/unit/ack/QuickAcking.java b/qpid/java/systests/src/main/java/org/apache/qpid/test/unit/ack/QuickAcking.java
index 13c78c1e14..6c83136511 100644
--- a/qpid/java/systests/src/main/java/org/apache/qpid/test/unit/ack/QuickAcking.java
+++ b/qpid/java/systests/src/main/java/org/apache/qpid/test/unit/ack/QuickAcking.java
@@ -20,7 +20,7 @@
*/
package org.apache.qpid.test.unit.ack;
-import java.util.concurrent.CountDownLatch;
+import edu.emory.mathcs.backport.java.util.concurrent.CountDownLatch;
import org.apache.qpid.client.AMQConnection;
import org.apache.qpid.jms.ConnectionListener;
import org.apache.qpid.test.utils.QpidBrokerTestCase;
diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/test/unit/basic/MultipleConnectionTest.java b/qpid/java/systests/src/main/java/org/apache/qpid/test/unit/basic/MultipleConnectionTest.java
index 87eae32cf8..3a5f676ca6 100644
--- a/qpid/java/systests/src/main/java/org/apache/qpid/test/unit/basic/MultipleConnectionTest.java
+++ b/qpid/java/systests/src/main/java/org/apache/qpid/test/unit/basic/MultipleConnectionTest.java
@@ -23,6 +23,7 @@ import org.apache.qpid.client.AMQConnection;
import org.apache.qpid.client.AMQDestination;
import org.apache.qpid.client.AMQSession;
import org.apache.qpid.client.AMQTopic;
+import org.apache.qpid.client.transport.TransportConnection;
import org.apache.qpid.exchange.ExchangeDefaults;
import org.apache.qpid.test.utils.QpidBrokerTestCase;
diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/test/unit/client/AMQConnectionTest.java b/qpid/java/systests/src/main/java/org/apache/qpid/test/unit/client/AMQConnectionTest.java
index 481b144caf..292bcd6039 100644
--- a/qpid/java/systests/src/main/java/org/apache/qpid/test/unit/client/AMQConnectionTest.java
+++ b/qpid/java/systests/src/main/java/org/apache/qpid/test/unit/client/AMQConnectionTest.java
@@ -20,6 +20,7 @@
*/
package org.apache.qpid.test.unit.client;
+import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStreamReader;
import java.io.LineNumberReader;
@@ -36,9 +37,11 @@ import javax.jms.MessageConsumer;
import javax.jms.MessageProducer;
import javax.jms.QueueSession;
import javax.jms.Session;
+import javax.jms.TextMessage;
import javax.jms.TopicSession;
import org.apache.qpid.client.AMQConnection;
+import org.apache.qpid.client.AMQConnectionDelegate_0_10;
import org.apache.qpid.client.AMQQueue;
import org.apache.qpid.client.AMQSession;
import org.apache.qpid.client.AMQTopic;
@@ -228,8 +231,7 @@ public class AMQConnectionTest extends QpidBrokerTestCase
}
MessageConsumer consumerB = null;
- // 0-8, 0-9, 0-9-1 prefetch is per session, not consumer.
- if (!isBroker010())
+ if (isBroker08())
{
Session consSessB = _connection.createSession(true, Session.AUTO_ACKNOWLEDGE);
consumerB = consSessB.createConsumer(_queue);
diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/test/unit/client/DynamicQueueExchangeCreateTest.java b/qpid/java/systests/src/main/java/org/apache/qpid/test/unit/client/DynamicQueueExchangeCreateTest.java
index 8577fb5b6a..33575b58aa 100644
--- a/qpid/java/systests/src/main/java/org/apache/qpid/test/unit/client/DynamicQueueExchangeCreateTest.java
+++ b/qpid/java/systests/src/main/java/org/apache/qpid/test/unit/client/DynamicQueueExchangeCreateTest.java
@@ -20,8 +20,6 @@
*/
package org.apache.qpid.test.unit.client;
-import org.apache.qpid.AMQException;
-import org.apache.qpid.protocol.AMQConstant;
import org.apache.qpid.test.utils.QpidBrokerTestCase;
import javax.jms.Connection;
@@ -34,9 +32,11 @@ import javax.jms.Session;
*
* Test to validate that setting the respective qpid.declare_queues,
* qpid.declare_exchanges system properties functions as expected.
+ *
*/
public class DynamicQueueExchangeCreateTest extends QpidBrokerTestCase
{
+
public void testQueueDeclare() throws Exception
{
setSystemProperty("qpid.declare_queues", "false");
@@ -53,8 +53,11 @@ public class DynamicQueueExchangeCreateTest extends QpidBrokerTestCase
fail("JMSException should be thrown as the queue does not exist");
}
catch (JMSException e)
- {
- checkExceptionErrorCode(e, AMQConstant.NOT_FOUND);
+ {
+ assertTrue("Exception should be that the queue does not exist :" +
+ e.getMessage(),
+ e.getMessage().contains("does not exist"));
+
}
}
@@ -76,15 +79,10 @@ public class DynamicQueueExchangeCreateTest extends QpidBrokerTestCase
}
catch (JMSException e)
{
- checkExceptionErrorCode(e, AMQConstant.NOT_FOUND);
+ assertTrue("Exception should be that the exchange does not exist :" +
+ e.getMessage(),
+ e.getMessage().contains("Exchange " + EXCHANGE_TYPE + " does not exist"));
}
}
- private void checkExceptionErrorCode(JMSException original, AMQConstant code)
- {
- Exception linked = original.getLinkedException();
- assertNotNull("Linked exception should have been set", linked);
- assertTrue("Linked exception should be an AMQException", linked instanceof AMQException);
- assertEquals("Error code should be " + code.getCode(), code, ((AMQException) linked).getErrorCode());
- }
}
diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/test/unit/client/channelclose/ChannelCloseOkTest.java b/qpid/java/systests/src/main/java/org/apache/qpid/test/unit/client/channelclose/ChannelCloseOkTest.java
index aae8b1feb9..79e2ff8148 100644
--- a/qpid/java/systests/src/main/java/org/apache/qpid/test/unit/client/channelclose/ChannelCloseOkTest.java
+++ b/qpid/java/systests/src/main/java/org/apache/qpid/test/unit/client/channelclose/ChannelCloseOkTest.java
@@ -24,6 +24,7 @@ import junit.textui.TestRunner;
import org.apache.qpid.client.AMQConnection;
import org.apache.qpid.client.AMQQueue;
+import org.apache.qpid.client.transport.TransportConnection;
import org.apache.qpid.test.utils.QpidBrokerTestCase;
import org.slf4j.Logger;
diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/test/unit/client/channelclose/ChannelCloseTest.java b/qpid/java/systests/src/main/java/org/apache/qpid/test/unit/client/channelclose/ChannelCloseTest.java
index 2e8a2d049d..f0794c9dab 100644
--- a/qpid/java/systests/src/main/java/org/apache/qpid/test/unit/client/channelclose/ChannelCloseTest.java
+++ b/qpid/java/systests/src/main/java/org/apache/qpid/test/unit/client/channelclose/ChannelCloseTest.java
@@ -25,9 +25,11 @@ import org.apache.qpid.test.utils.QpidBrokerTestCase;
import org.apache.qpid.client.AMQConnection;
import org.apache.qpid.client.failover.FailoverException;
import org.apache.qpid.client.protocol.AMQProtocolHandler;
+import org.apache.qpid.client.transport.TransportConnection;
import org.apache.qpid.framing.*;
import org.apache.qpid.jms.ConnectionListener;
import org.apache.qpid.protocol.AMQConstant;
+import org.apache.qpid.url.URLSyntaxException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -47,67 +49,70 @@ public class ChannelCloseTest extends QpidBrokerTestCase implements ExceptionLis
private static final Logger _logger = LoggerFactory.getLogger(ChannelCloseTest.class);
Connection _connection;
+ private String _brokerlist = "vm://:1";
private Session _session;
private static final long SYNC_TIMEOUT = 500;
private int TEST = 0;
- /**
- * Close channel, use chanel with same id ensure error.
- *
- * This test is only valid for non 0-10 connection .
+ /*
+ close channel, use chanel with same id ensure error.
*/
public void testReusingChannelAfterFullClosure() throws Exception
{
- _connection=newConnection();
-
- // Create Producer
- try
+ // this is testing an inVM Connetion conneciton
+ if (isJavaBroker() && !isExternalBroker())
{
- _connection.start();
-
- createChannelAndTest(1);
+ _connection=newConnection();
- // Cause it to close
+ // Create Producer
try
{
- _logger.info("Testing invalid exchange");
- declareExchange(1, "", "name_that_will_lookup_to_null", false);
- fail("Exchange name is empty so this should fail ");
- }
- catch (AMQException e)
- {
- assertEquals("Exchange should not be found", AMQConstant.NOT_FOUND, e.getErrorCode());
- }
+ _connection.start();
- // Check that
- try
- {
- _logger.info("Testing valid exchange should fail");
- declareExchange(1, "topic", "amq.topic", false);
- fail("This should not succeed as the channel should be closed ");
- }
- catch (AMQException e)
- {
- if (_logger.isInfoEnabled())
+ createChannelAndTest(1);
+
+ // Cause it to close
+ try
+ {
+ _logger.info("Testing invalid exchange");
+ declareExchange(1, "", "name_that_will_lookup_to_null", false);
+ fail("Exchange name is empty so this should fail ");
+ }
+ catch (AMQException e)
{
- _logger.info("Exception occured was:" + e.getErrorCode());
+ assertEquals("Exchange should not be found", AMQConstant.NOT_FOUND, e.getErrorCode());
}
- assertEquals("Connection should be closed", AMQConstant.CHANNEL_ERROR, e.getErrorCode());
+ // Check that
+ try
+ {
+ _logger.info("Testing valid exchange should fail");
+ declareExchange(1, "topic", "amq.topic", false);
+ fail("This should not succeed as the channel should be closed ");
+ }
+ catch (AMQException e)
+ {
+ if (_logger.isInfoEnabled())
+ {
+ _logger.info("Exception occured was:" + e.getErrorCode());
+ }
- _connection=newConnection();
- }
+ assertEquals("Connection should be closed", AMQConstant.CHANNEL_ERROR, e.getErrorCode());
- checkSendingMessage();
+ _connection=newConnection();
+ }
- _session.close();
- _connection.close();
+ checkSendingMessage();
- }
- catch (JMSException e)
- {
- e.printStackTrace();
- fail(e.getMessage());
+ _session.close();
+ _connection.close();
+
+ }
+ catch (JMSException e)
+ {
+ e.printStackTrace();
+ fail(e.getMessage());
+ }
}
}
@@ -301,19 +306,27 @@ public class ChannelCloseTest extends QpidBrokerTestCase implements ExceptionLis
private Connection newConnection()
{
- Connection connection = null;
+ AMQConnection connection = null;
try
{
- connection = getConnection();
+ connection = new AMQConnection("amqp://guest:guest@CCTTest/test?brokerlist='" + _brokerlist + "'");
- ((AMQConnection) connection).setConnectionListener(this);
+ connection.setConnectionListener(this);
_session = connection.createSession(false, Session.CLIENT_ACKNOWLEDGE);
connection.start();
}
- catch (Exception e)
+ catch (JMSException e)
+ {
+ fail("Creating new connection when:" + e.getMessage());
+ }
+ catch (AMQException e)
+ {
+ fail("Creating new connection when:" + e.getMessage());
+ }
+ catch (URLSyntaxException e)
{
fail("Creating new connection when:" + e.getMessage());
}
diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/test/unit/client/connection/ConnectionTest.java b/qpid/java/systests/src/main/java/org/apache/qpid/test/unit/client/connection/ConnectionTest.java
index 124e756fad..04fc611cd1 100644
--- a/qpid/java/systests/src/main/java/org/apache/qpid/test/unit/client/connection/ConnectionTest.java
+++ b/qpid/java/systests/src/main/java/org/apache/qpid/test/unit/client/connection/ConnectionTest.java
@@ -20,30 +20,32 @@
*/
package org.apache.qpid.test.unit.client.connection;
-import javax.jms.Connection;
-import javax.jms.QueueSession;
-import javax.jms.TopicSession;
-
import org.apache.qpid.AMQConnectionFailureException;
import org.apache.qpid.AMQException;
import org.apache.qpid.AMQUnresolvedAddressException;
+import org.apache.qpid.server.exchange.Exchange;
+import org.apache.qpid.test.utils.QpidBrokerTestCase;
+import org.apache.qpid.client.AMQAuthenticationException;
import org.apache.qpid.client.AMQConnection;
-import org.apache.qpid.client.AMQConnectionURL;
import org.apache.qpid.client.AMQQueue;
import org.apache.qpid.client.AMQSession;
import org.apache.qpid.client.AMQTopic;
+import org.apache.qpid.client.AMQConnectionURL;
import org.apache.qpid.exchange.ExchangeDefaults;
import org.apache.qpid.framing.AMQShortString;
-import org.apache.qpid.jms.BrokerDetails;
-import org.apache.qpid.jms.ConnectionURL;
import org.apache.qpid.jms.Session;
-import org.apache.qpid.test.utils.QpidBrokerTestCase;
+import org.apache.qpid.jms.ConnectionURL;
+import org.apache.qpid.jms.BrokerDetails;
+
+import javax.jms.Connection;
+import javax.jms.QueueSession;
+import javax.jms.TopicSession;
+import javax.naming.NamingException;
public class ConnectionTest extends QpidBrokerTestCase
{
- String _broker_NotRunning = "tcp://localhost:" + findFreePort();
-
+ String _broker_NotRunning = "vm://:2";
String _broker_BadDNS = "tcp://hg3sgaaw4lgihjs";
public void testSimpleConnection() throws Exception
@@ -85,17 +87,17 @@ public class ConnectionTest extends QpidBrokerTestCase
AMQSession sess = (AMQSession) conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
-
- sess.declareExchange(new AMQShortString("test.direct"),
+
+ sess.declareExchange(new AMQShortString("test.direct"),
ExchangeDefaults.DIRECT_EXCHANGE_CLASS, false);
- sess.declareExchange(new AMQShortString("tmp.direct"),
+ sess.declareExchange(new AMQShortString("tmp.direct"),
ExchangeDefaults.DIRECT_EXCHANGE_CLASS, false);
- sess.declareExchange(new AMQShortString("tmp.topic"),
+ sess.declareExchange(new AMQShortString("tmp.topic"),
ExchangeDefaults.TOPIC_EXCHANGE_CLASS, false);
- sess.declareExchange(new AMQShortString("test.topic"),
+ sess.declareExchange(new AMQShortString("test.topic"),
ExchangeDefaults.TOPIC_EXCHANGE_CLASS, false);
QueueSession queueSession = conn.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
@@ -111,7 +113,7 @@ public class ConnectionTest extends QpidBrokerTestCase
queueSession.close();
TopicSession topicSession = conn.createTopicSession(false, Session.AUTO_ACKNOWLEDGE);
-
+
AMQTopic topic = (AMQTopic) topicSession.createTopic("silly.topic");
assertEquals(topic.getExchangeName().toString(), "test.topic");
@@ -269,7 +271,7 @@ public class ConnectionTest extends QpidBrokerTestCase
}
connection.close();
}
-
+
public void testUnsupportedSASLMechanism() throws Exception
{
BrokerDetails broker = getBroker();
@@ -287,37 +289,11 @@ public class ConnectionTest extends QpidBrokerTestCase
{
assertTrue("Incorrect exception thrown",
e.getMessage().contains("The following SASL mechanisms " +
- "[MY_MECH]" +
+ "[MY_MECH]" +
" specified by the client are not supported by the broker"));
}
}
- public void testClientIDVerification() throws Exception
- {
- System.setProperty("qpid.verify_client_id", "true");
- BrokerDetails broker = getBroker();
- try
- {
- Connection con = new AMQConnection(broker.toString(), "guest", "guest",
- "client_id", "test");
-
- Connection con2 = new AMQConnection(broker.toString(), "guest", "guest",
- "client_id", "test");
-
- fail("The client should throw a ConnectionException stating the" +
- " client ID is not unique");
- }
- catch (Exception e)
- {
- assertTrue("Incorrect exception thrown",
- e.getMessage().contains("ClientID must be unique"));
- }
- finally
- {
- System.setProperty("qpid.verify_client_id", "false");
- }
- }
-
public static junit.framework.Test suite()
{
return new junit.framework.TestSuite(ConnectionTest.class);
diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/test/unit/client/protocol/AMQProtocolSessionTest.java b/qpid/java/systests/src/main/java/org/apache/qpid/test/unit/client/protocol/AMQProtocolSessionTest.java
index 5701b5a1fd..278b9e9c04 100644
--- a/qpid/java/systests/src/main/java/org/apache/qpid/test/unit/client/protocol/AMQProtocolSessionTest.java
+++ b/qpid/java/systests/src/main/java/org/apache/qpid/test/unit/client/protocol/AMQProtocolSessionTest.java
@@ -31,21 +31,21 @@ import org.apache.qpid.client.protocol.AMQProtocolHandler;
import org.apache.qpid.client.protocol.AMQProtocolSession;
import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.test.utils.QpidBrokerTestCase;
-import org.apache.qpid.transport.TestNetworkConnection;
+import org.apache.qpid.transport.TestNetworkDriver;
public class AMQProtocolSessionTest extends QpidBrokerTestCase
{
- private static class TestProtocolSession extends AMQProtocolSession
+ private static class AMQProtSession extends AMQProtocolSession
{
- public TestProtocolSession(AMQProtocolHandler protocolHandler, AMQConnection connection)
+ public AMQProtSession(AMQProtocolHandler protocolHandler, AMQConnection connection)
{
super(protocolHandler,connection);
}
- public TestNetworkConnection getNetworkConnection()
+ public TestNetworkDriver getNetworkDriver()
{
- return (TestNetworkConnection) _protocolHandler.getNetworkConnection();
+ return (TestNetworkDriver) _protocolHandler.getNetworkDriver();
}
public AMQShortString genQueueName()
@@ -54,7 +54,7 @@ public class AMQProtocolSessionTest extends QpidBrokerTestCase
}
}
- private TestProtocolSession _testSession;
+ private AMQProtSession _testSession;
protected void setUp() throws Exception
{
@@ -62,10 +62,10 @@ public class AMQProtocolSessionTest extends QpidBrokerTestCase
AMQConnection con = (AMQConnection) getConnection("guest", "guest");
AMQProtocolHandler protocolHandler = new AMQProtocolHandler(con);
- protocolHandler.setNetworkConnection(new TestNetworkConnection());
-
+ protocolHandler.setNetworkDriver(new TestNetworkDriver());
+
//don't care about the values set here apart from the dummy IoSession
- _testSession = new TestProtocolSession(protocolHandler , con);
+ _testSession = new AMQProtSession(protocolHandler , con);
}
public void testTemporaryQueueWildcard() throws UnknownHostException
@@ -93,9 +93,14 @@ public class AMQProtocolSessionTest extends QpidBrokerTestCase
checkTempQueueName(new InetSocketAddress(InetAddress.getByName("1080:0:0:0:8:800:200C:417A"), 1234), "tmp_1080_0_0_0_8_800_200c_417a_1234_1");
}
+ public void testTemporaryQueuePipe() throws UnknownHostException
+ {
+ checkTempQueueName(new VmPipeAddress(1), "tmp_vm_1_1");
+ }
+
private void checkTempQueueName(SocketAddress address, String queueName)
{
- _testSession.getNetworkConnection().setLocalAddress(address);
+ _testSession.getNetworkDriver().setLocalAddress(address);
assertEquals("Wrong queue name", queueName, _testSession.genQueueName().asString());
}
}
diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/test/unit/close/MessageRequeueTest.java b/qpid/java/systests/src/main/java/org/apache/qpid/test/unit/close/MessageRequeueTest.java
index f5e0ed75d2..de092fc893 100644
--- a/qpid/java/systests/src/main/java/org/apache/qpid/test/unit/close/MessageRequeueTest.java
+++ b/qpid/java/systests/src/main/java/org/apache/qpid/test/unit/close/MessageRequeueTest.java
@@ -50,6 +50,7 @@ public class MessageRequeueTest extends QpidBrokerTestCase
protected final String queue = "direct://amq.direct//message-requeue-test-queue";
protected String payload = "Message:";
+ //protected final String BROKER = "vm://:1";
protected final String BROKER = "tcp://127.0.0.1:5672";
private boolean testReception = true;
@@ -154,8 +155,8 @@ public class MessageRequeueTest extends QpidBrokerTestCase
_logger.info("consumed: " + messagesReceived);
assertEquals("number of consumed messages does not match initial data", (int) numTestMessages, messagesReceived);
- // with 0_10 we can have a delivery tag of 0
- if (!conn.isBroker010())
+ // wit 0_10 we can have a delivery tag of 0
+ if (conn.isBroker08())
{
for (long b : messageLog)
{
@@ -223,7 +224,7 @@ public class MessageRequeueTest extends QpidBrokerTestCase
StringBuilder list = new StringBuilder();
list.append("Failed to receive:");
int failed = 0;
- if (!conn.isBroker010())
+ if (conn.isBroker08())
{
for (long b : receieved)
{
diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/test/unit/ct/DurableSubscriberTest.java b/qpid/java/systests/src/main/java/org/apache/qpid/test/unit/ct/DurableSubscriberTest.java
index 80422cf3e9..989ac98747 100644
--- a/qpid/java/systests/src/main/java/org/apache/qpid/test/unit/ct/DurableSubscriberTest.java
+++ b/qpid/java/systests/src/main/java/org/apache/qpid/test/unit/ct/DurableSubscriberTest.java
@@ -52,7 +52,7 @@ public class DurableSubscriberTest extends QpidBrokerTestCase
*/
public void testDurSubRestoredAfterNonPersistentMessageSent() throws Exception
{
- if (isBrokerStorePersistent())
+ if (isBrokerStorePersistent() || !isBroker08())
{
TopicConnectionFactory factory = getConnectionFactory();
Topic topic = (Topic) getInitialContext().lookup(_topicName);
@@ -116,7 +116,7 @@ public class DurableSubscriberTest extends QpidBrokerTestCase
*/
public void testDurSubRestoresMessageSelector() throws Exception
{
- if (isBrokerStorePersistent())
+ if (isBrokerStorePersistent() || !isBroker08())
{
TopicConnectionFactory factory = getConnectionFactory();
Topic topic = (Topic) getInitialContext().lookup(_topicName);
diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/test/unit/message/JMSPropertiesTest.java b/qpid/java/systests/src/main/java/org/apache/qpid/test/unit/message/JMSPropertiesTest.java
index 97452ad1c8..830421a01f 100644
--- a/qpid/java/systests/src/main/java/org/apache/qpid/test/unit/message/JMSPropertiesTest.java
+++ b/qpid/java/systests/src/main/java/org/apache/qpid/test/unit/message/JMSPropertiesTest.java
@@ -25,14 +25,12 @@ import org.apache.qpid.client.AMQConnection;
import org.apache.qpid.client.AMQQueue;
import org.apache.qpid.client.AMQSession;
import org.apache.qpid.client.message.NonQpidObjectMessage;
-import org.apache.qpid.client.message.QpidMessageProperties;
import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.test.utils.QpidBrokerTestCase;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import javax.jms.Connection;
import javax.jms.Destination;
import javax.jms.Message;
import javax.jms.MessageConsumer;
@@ -41,11 +39,7 @@ import javax.jms.MessageProducer;
import javax.jms.ObjectMessage;
import javax.jms.Queue;
import javax.jms.Session;
-import javax.jms.Topic;
-
import java.util.Enumeration;
-import java.util.HashMap;
-import java.util.Map;
/**
* @author Apache Software Foundation
@@ -169,39 +163,4 @@ public class JMSPropertiesTest extends QpidBrokerTestCase
con.close();
}
- /**
- * Test Goal : Test if custom message properties can be set and retrieved properly with out an error.
- * Also test if unsupported properties are filtered out. See QPID-2930.
- */
- public void testQpidExtensionProperties() throws Exception
- {
- Connection con = getConnection("guest", "guest");
- Session ssn = (AMQSession) con.createSession(false, Session.CLIENT_ACKNOWLEDGE);
- con.start();
-
- Topic topic = ssn.createTopic("test");
- MessageConsumer consumer = ssn.createConsumer(topic);
- MessageProducer prod = ssn.createProducer(topic);
- Message m = ssn.createMessage();
- m.setObjectProperty("foo-bar", "foobar".getBytes());
- m.setObjectProperty(QpidMessageProperties.AMQP_0_10_APP_ID, "my-app-id");
- prod.send(m);
-
- Message msg = consumer.receive(1000);
- assertNotNull(msg);
-
- Enumeration<String> enu = msg.getPropertyNames();
- Map<String,String> map = new HashMap<String,String>();
- while (enu.hasMoreElements())
- {
- String name = enu.nextElement();
- String value = msg.getStringProperty(name);
- map.put(name, value);
- }
-
- assertFalse("Property 'foo-bar' should have been filtered out",map.containsKey("foo-bar"));
- assertEquals("Property "+ QpidMessageProperties.AMQP_0_10_APP_ID + " should be present","my-app-id",msg.getStringProperty(QpidMessageProperties.AMQP_0_10_APP_ID));
- assertEquals("Property "+ QpidMessageProperties.AMQP_0_10_ROUTING_KEY + " should be present","test",msg.getStringProperty(QpidMessageProperties.AMQP_0_10_ROUTING_KEY));
-
- }
}
diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/test/unit/transacted/TransactionTimeoutConfigurationTest.java b/qpid/java/systests/src/main/java/org/apache/qpid/test/unit/transacted/TransactionTimeoutConfigurationTest.java
deleted file mode 100644
index 36bac3b715..0000000000
--- a/qpid/java/systests/src/main/java/org/apache/qpid/test/unit/transacted/TransactionTimeoutConfigurationTest.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
- */
-package org.apache.qpid.test.unit.transacted;
-
-/**
- * This verifies that changing the {@code transactionTimeout} configuration will alter
- * the behaviour of the transaction open and idle logging, and that when the connection
- * will be closed.
- */
-public class TransactionTimeoutConfigurationTest extends TransactionTimeoutTestCase
-{
- @Override
- protected void configure() throws Exception
- {
- // Setup housekeeping every second
- setConfigurationProperty("virtualhosts.virtualhost." + VIRTUALHOST + ".housekeeping.expiredMessageCheckPeriod", "100");
-
- // Set transaction timout properties.
- setConfigurationProperty("virtualhosts.virtualhost." + VIRTUALHOST + ".transactionTimeout.openWarn", "200");
- setConfigurationProperty("virtualhosts.virtualhost." + VIRTUALHOST + ".transactionTimeout.openClose", "1000");
- setConfigurationProperty("virtualhosts.virtualhost." + VIRTUALHOST + ".transactionTimeout.idleWarn", "100");
- setConfigurationProperty("virtualhosts.virtualhost." + VIRTUALHOST + ".transactionTimeout.idleClose", "500");
- }
-
- public void testProducerIdleCommit() throws Exception
- {
- try
- {
- send(5, 0);
-
- sleep(2.0f);
-
- _psession.commit();
- fail("should fail");
- }
- catch (Exception e)
- {
- _exception = e;
- }
-
- monitor(5, 0);
-
- check(IDLE);
- }
-
- public void testProducerOpenCommit() throws Exception
- {
- try
- {
- send(5, 0.3f);
-
- _psession.commit();
- fail("should fail");
- }
- catch (Exception e)
- {
- _exception = e;
- }
-
- monitor(6, 3);
-
- check(OPEN);
- }
-}
diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/test/unit/transacted/TransactionTimeoutDisabledTest.java b/qpid/java/systests/src/main/java/org/apache/qpid/test/unit/transacted/TransactionTimeoutDisabledTest.java
deleted file mode 100644
index 71b89bf911..0000000000
--- a/qpid/java/systests/src/main/java/org/apache/qpid/test/unit/transacted/TransactionTimeoutDisabledTest.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
- */
-package org.apache.qpid.test.unit.transacted;
-
-/**
- * This verifies that the default behaviour is not to time out transactions.
- */
-public class TransactionTimeoutDisabledTest extends TransactionTimeoutTestCase
-{
- @Override
- protected void configure() throws Exception
- {
- // Setup housekeeping every second
- setConfigurationProperty("virtualhosts.virtualhost." + VIRTUALHOST + ".housekeeping.expiredMessageCheckPeriod", "100");
- }
-
- public void testProducerIdleCommit() throws Exception
- {
- try
- {
- send(5, 0);
-
- sleep(2.0f);
-
- _psession.commit();
- }
- catch (Exception e)
- {
- fail("Should have succeeded");
- }
-
- assertTrue("Listener should not have received exception", _caught.getCount() == 1);
-
- monitor(0, 0);
- }
-
- public void testProducerOpenCommit() throws Exception
- {
- try
- {
- send(5, 0.3f);
-
- _psession.commit();
- }
- catch (Exception e)
- {
- fail("Should have succeeded");
- }
-
- assertTrue("Listener should not have received exception", _caught.getCount() == 1);
-
- monitor(0, 0);
- }
-}
diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/test/unit/transacted/TransactionTimeoutTest.java b/qpid/java/systests/src/main/java/org/apache/qpid/test/unit/transacted/TransactionTimeoutTest.java
deleted file mode 100644
index c912d6a323..0000000000
--- a/qpid/java/systests/src/main/java/org/apache/qpid/test/unit/transacted/TransactionTimeoutTest.java
+++ /dev/null
@@ -1,335 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
- */
-package org.apache.qpid.test.unit.transacted;
-
-/**
- * This tests the behaviour of transactional sessions when the {@code transactionTimeout} configuration
- * is set for a virtual host.
- *
- * A producer that is idle for too long or open for too long will have its connection closed and
- * any further operations will fail with a 408 resource timeout exception. Consumers will not
- * be affected by the transaction timeout configuration.
- */
-public class TransactionTimeoutTest extends TransactionTimeoutTestCase
-{
- public void testProducerIdle() throws Exception
- {
- try
- {
- sleep(2.0f);
-
- _psession.commit();
- }
- catch (Exception e)
- {
- fail("Should have succeeded");
- }
-
- assertTrue("Listener should not have received exception", _caught.getCount() == 1);
-
- monitor(0, 0);
- }
-
- public void testProducerIdleCommit() throws Exception
- {
- try
- {
- send(5, 0);
-
- sleep(2.0f);
-
- _psession.commit();
- fail("should fail");
- }
- catch (Exception e)
- {
- _exception = e;
- }
-
- monitor(5, 0);
-
- check(IDLE);
- }
-
- public void testProducerOpenCommit() throws Exception
- {
- try
- {
- send(6, 0.5f);
-
- _psession.commit();
- fail("should fail");
- }
- catch (Exception e)
- {
- _exception = e;
- }
-
- monitor(0, 10);
-
- check(OPEN);
- }
-
- public void testProducerIdleCommitTwice() throws Exception
- {
- try
- {
- send(5, 0);
-
- sleep(1.0f);
-
- _psession.commit();
-
- send(5, 0);
-
- sleep(2.0f);
-
- _psession.commit();
- fail("should fail");
- }
- catch (Exception e)
- {
- _exception = e;
- }
-
- monitor(10, 0);
-
- check(IDLE);
- }
-
- public void testProducerOpenCommitTwice() throws Exception
- {
- try
- {
- send(5, 0);
-
- sleep(1.0f);
-
- _psession.commit();
-
- send(6, 0.5f);
-
- _psession.commit();
- fail("should fail");
- }
- catch (Exception e)
- {
- _exception = e;
- }
-
- // the presistent store generates more idle messages?
- monitor(isBrokerStorePersistent() ? 10 : 5, 10);
-
- check(OPEN);
- }
-
- public void testProducerIdleRollback() throws Exception
- {
- try
- {
- send(5, 0);
-
- sleep(2.0f);
-
- _psession.rollback();
- fail("should fail");
- }
- catch (Exception e)
- {
- _exception = e;
- }
-
- monitor(5, 0);
-
- check(IDLE);
- }
-
- public void testProducerIdleRollbackTwice() throws Exception
- {
- try
- {
- send(5, 0);
-
- sleep(1.0f);
-
- _psession.rollback();
-
- send(5, 0);
-
- sleep(2.0f);
-
- _psession.rollback();
- fail("should fail");
- }
- catch (Exception e)
- {
- _exception = e;
- }
-
- monitor(10, 0);
-
- check(IDLE);
- }
-
- public void testConsumerCommitClose() throws Exception
- {
- try
- {
- send(1, 0);
-
- _psession.commit();
-
- expect(1, 0);
-
- _csession.commit();
-
- sleep(3.0f);
-
- _csession.close();
- }
- catch (Exception e)
- {
- fail("should have succeeded: " + e.getMessage());
- }
-
- assertTrue("Listener should not have received exception", _caught.getCount() == 1);
-
- monitor(0, 0);
- }
-
- public void testConsumerIdleReceiveCommit() throws Exception
- {
- try
- {
- send(1, 0);
-
- _psession.commit();
-
- sleep(2.0f);
-
- expect(1, 0);
-
- sleep(2.0f);
-
- _csession.commit();
- }
- catch (Exception e)
- {
- fail("Should have succeeded");
- }
-
- assertTrue("Listener should not have received exception", _caught.getCount() == 1);
-
- monitor(0, 0);
- }
-
- public void testConsumerIdleCommit() throws Exception
- {
- try
- {
- send(1, 0);
-
- _psession.commit();
-
- expect(1, 0);
-
- sleep(2.0f);
-
- _csession.commit();
- }
- catch (Exception e)
- {
- fail("Should have succeeded");
- }
-
- assertTrue("Listener should not have received exception", _caught.getCount() == 1);
-
- monitor(0, 0);
- }
-
- public void testConsumerIdleRollback() throws Exception
- {
- try
- {
- send(1, 0);
-
- _psession.commit();
-
- expect(1, 0);
-
- sleep(2.0f);
-
- _csession.rollback();
- }
- catch (Exception e)
- {
- fail("Should have succeeded");
- }
-
- assertTrue("Listener should not have received exception", _caught.getCount() == 1);
-
- monitor(0, 0);
- }
-
- public void testConsumerOpenCommit() throws Exception
- {
- try
- {
- send(1, 0);
-
- _psession.commit();
-
- sleep(3.0f);
-
- _csession.commit();
- }
- catch (Exception e)
- {
- fail("Should have succeeded");
- }
-
- assertTrue("Listener should not have received exception", _caught.getCount() == 1);
-
- monitor(0, 0);
- }
-
- public void testConsumerOpenRollback() throws Exception
- {
- try
- {
- send(1, 0);
-
- _psession.commit();
-
- sleep(3.0f);
-
- _csession.rollback();
- }
- catch (Exception e)
- {
- fail("Should have succeeded");
- }
-
- assertTrue("Listener should not have received exception", _caught.getCount() == 1);
-
- monitor(0, 0);
- }
-}
diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/test/unit/transacted/TransactionTimeoutTestCase.java b/qpid/java/systests/src/main/java/org/apache/qpid/test/unit/transacted/TransactionTimeoutTestCase.java
deleted file mode 100644
index 786fc2adb0..0000000000
--- a/qpid/java/systests/src/main/java/org/apache/qpid/test/unit/transacted/TransactionTimeoutTestCase.java
+++ /dev/null
@@ -1,253 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
- */
-package org.apache.qpid.test.unit.transacted;
-
-import java.util.List;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-
-import javax.jms.DeliveryMode;
-import javax.jms.ExceptionListener;
-import javax.jms.JMSException;
-import javax.jms.Message;
-import javax.jms.MessageConsumer;
-import javax.jms.MessageProducer;
-import javax.jms.Queue;
-import javax.jms.TextMessage;
-
-import junit.framework.TestCase;
-
-import org.apache.qpid.AMQException;
-import org.apache.qpid.client.AMQConnection;
-import org.apache.qpid.client.AMQConnectionURL;
-import org.apache.qpid.client.AMQQueue;
-import org.apache.qpid.framing.AMQShortString;
-import org.apache.qpid.jms.ConnectionURL;
-import org.apache.qpid.jms.Session;
-import org.apache.qpid.protocol.AMQConstant;
-import org.apache.qpid.test.utils.QpidBrokerTestCase;
-import org.apache.qpid.util.LogMonitor;
-
-/**
- * The {@link TestCase} for transaction timeout testing.
- */
-public class TransactionTimeoutTestCase extends QpidBrokerTestCase implements ExceptionListener
-{
- public static final String VIRTUALHOST = "test";
- public static final String TEXT = "0123456789abcdefghiforgettherest";
- public static final String CHN_OPEN_TXN = "CHN-1007";
- public static final String CHN_IDLE_TXN = "CHN-1008";
- public static final String IDLE = "Idle";
- public static final String OPEN = "Open";
-
- protected LogMonitor _monitor;
- protected AMQConnection _con;
- protected Session _psession, _csession;
- protected Queue _queue;
- protected MessageConsumer _consumer;
- protected MessageProducer _producer;
- protected CountDownLatch _caught = new CountDownLatch(1);
- protected String _message;
- protected Exception _exception;
- protected AMQConstant _code;
-
- protected void configure() throws Exception
- {
- // Setup housekeeping every second
- setConfigurationProperty("virtualhosts.virtualhost." + VIRTUALHOST + ".housekeeping.expiredMessageCheckPeriod", "100");
-
- /*
- * Set transaction timout properties. The XML in the virtualhosts configuration is as follows:
- *
- * <transactionTimeout>
- * <openWarn>1000</openWarn>
- * <openClose>2000</openClose>
- * <idleWarn>500</idleWarn>
- * <idleClose>1500</idleClose>
- * </transactionTimeout>
- */
- setConfigurationProperty("virtualhosts.virtualhost." + VIRTUALHOST + ".transactionTimeout.openWarn", "1000");
- setConfigurationProperty("virtualhosts.virtualhost." + VIRTUALHOST + ".transactionTimeout.openClose", "2000");
- setConfigurationProperty("virtualhosts.virtualhost." + VIRTUALHOST + ".transactionTimeout.idleWarn", "500");
- setConfigurationProperty("virtualhosts.virtualhost." + VIRTUALHOST + ".transactionTimeout.idleClose", "1000");
- }
-
- protected void setUp() throws Exception
- {
- // Configure timeouts
- configure();
-
- // Monitor log file
- _monitor = new LogMonitor(_outputFile);
-
- // Start broker
- super.setUp();
-
- // Connect to broker
- String broker = ("tcp://localhost:" + DEFAULT_PORT);
- ConnectionURL url = new AMQConnectionURL("amqp://guest:guest@clientid/test?brokerlist='" + broker + "'&maxprefetch='1'");
- _con = (AMQConnection) getConnection(url);
- _con.setExceptionListener(this);
- _con.start();
-
- // Create queue
- Session qsession = _con.createSession(true, Session.SESSION_TRANSACTED);
- AMQShortString queueName = new AMQShortString("test");
- _queue = new AMQQueue(qsession.getDefaultQueueExchangeName(), queueName, queueName, false, true);
- qsession.close();
-
- // Create producer and consumer
- producer();
- consumer();
- }
-
- protected void tearDown() throws Exception
- {
- try
- {
- _con.close();
- }
- finally
- {
- super.tearDown();
- }
- }
-
- /**
- * Create a transacted persistent message producer session.
- */
- protected void producer() throws Exception
- {
- _psession = _con.createSession(true, Session.SESSION_TRANSACTED);
- _producer = _psession.createProducer(_queue);
- _producer.setDeliveryMode(DeliveryMode.PERSISTENT);
- }
-
- /**
- * Create a transacted message consumer session.
- */
- protected void consumer() throws Exception
- {
- _csession = _con.createSession(true, Session.SESSION_TRANSACTED);
- _consumer = _csession.createConsumer(_queue);
- }
-
- /**
- * Send a number of messages to the queue, optionally pausing after each.
- */
- protected void send(int count, float delay) throws Exception
- {
- for (int i = 0; i < count; i++)
- {
- sleep(delay);
- Message msg = _psession.createTextMessage(TEXT);
- msg.setIntProperty("i", i);
- _producer.send(msg);
- }
- }
-
- /**
- * Sleep for a number of seconds.
- */
- protected void sleep(float seconds) throws Exception
- {
- try
- {
- Thread.sleep((long) (seconds * 1000.0f));
- }
- catch (InterruptedException ie)
- {
- throw new RuntimeException("Interrupted");
- }
- }
-
- /**
- * Check for idle and open messages.
- *
- * Either exactly zero messages, or +-2 error accepted around the specified number.
- */
- protected void monitor(int idle, int open) throws Exception
- {
- List<String> idleMsgs = _monitor.findMatches(CHN_IDLE_TXN);
- List<String> openMsgs = _monitor.findMatches(CHN_OPEN_TXN);
-
- String idleErr = "Expected " + idle + " but found " + idleMsgs.size() + " txn idle messages";
- String openErr = "Expected " + open + " but found " + openMsgs.size() + " txn open messages";
-
- if (idle == 0)
- {
- assertTrue(idleErr, idleMsgs.isEmpty());
- }
- else
- {
- assertTrue(idleErr, idleMsgs.size() >= idle - 2 && idleMsgs.size() <= idle + 2);
- }
-
- if (open == 0)
- {
- assertTrue(openErr, openMsgs.isEmpty());
- }
- else
- {
- assertTrue(openErr, openMsgs.size() >= open - 2 && openMsgs.size() <= open + 2);
- }
- }
-
- /**
- * Receive a number of messages, optionally pausing after each.
- */
- protected void expect(int count, float delay) throws Exception
- {
- for (int i = 0; i < count; i++)
- {
- sleep(delay);
- Message msg = _consumer.receive(1000);
- assertNotNull("Message should not be null", msg);
- assertTrue("Message should be a text message", msg instanceof TextMessage);
- assertEquals("Message content does not match expected", TEXT, ((TextMessage) msg).getText());
- assertEquals("Message order is incorrect", i, msg.getIntProperty("i"));
- }
- }
-
- /**
- * Checks that the correct exception was thrown and was received
- * by the listener with a 506 error code.
- */
- protected void check(String reason)throws InterruptedException
- {
- assertTrue("Should have caught exception in listener", _caught.await(1, TimeUnit.SECONDS));
- assertNotNull("Should have thrown exception to client", _exception);
- assertTrue("Exception message should contain '" + reason + "': " + _message, _message.contains(reason + " transaction timed out"));
- assertNotNull("Exception should have an error code", _code);
- assertEquals("Error code should be 506", AMQConstant.RESOURCE_ERROR, _code);
- }
-
- /** @see javax.jms.ExceptionListener#onException(javax.jms.JMSException) */
- public void onException(JMSException jmse)
- {
- _caught.countDown();
- _message = jmse.getLinkedException().getMessage();
- if (jmse.getLinkedException() instanceof AMQException)
- {
- _code = ((AMQException) jmse.getLinkedException()).getErrorCode();
- }
- }
-}
diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/test/utils/BrokerHolder.java b/qpid/java/systests/src/main/java/org/apache/qpid/test/utils/BrokerHolder.java
deleted file mode 100644
index 8345803d56..0000000000
--- a/qpid/java/systests/src/main/java/org/apache/qpid/test/utils/BrokerHolder.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
- */
-package org.apache.qpid.test.utils;
-
-public interface BrokerHolder
-{
- void shutdown();
-}
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 10217585c1..d3b429e315 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
@@ -34,10 +34,24 @@ public class FailoverBaseCase extends QpidBrokerTestCase
{
protected static final Logger _logger = LoggerFactory.getLogger(FailoverBaseCase.class);
+ public static int FAILING_VM_PORT = 2;
+ public static int FAILING_PORT = Integer.parseInt(System.getProperty("test.port.alt"));
public static final long DEFAULT_FAILOVER_TIME = 10000L;
protected int failingPort;
+ protected int getFailingPort()
+ {
+ if (_broker.equals(VM))
+ {
+ return FAILING_VM_PORT;
+ }
+ else
+ {
+ return FAILING_PORT;
+ }
+ }
+
protected void setUp() throws java.lang.Exception
{
super.setUp();
@@ -68,14 +82,6 @@ public class FailoverBaseCase extends QpidBrokerTestCase
return _connectionFactory;
}
- @Override
- public void stopBroker(int port) throws Exception
- {
- if (isBrokerPresent(port))
- {
- super.stopBroker(port);
- }
- }
public void tearDown() throws Exception
{
diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/test/utils/InternalBrokerHolder.java b/qpid/java/systests/src/main/java/org/apache/qpid/test/utils/InternalBrokerHolder.java
deleted file mode 100644
index 340f00fed8..0000000000
--- a/qpid/java/systests/src/main/java/org/apache/qpid/test/utils/InternalBrokerHolder.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
- */
-package org.apache.qpid.test.utils;
-
-import org.apache.log4j.Logger;
-import org.apache.qpid.server.Broker;
-
-public class InternalBrokerHolder implements BrokerHolder
-{
- private static final Logger LOGGER = Logger.getLogger(InternalBrokerHolder.class);
- private final Broker _broker;
-
- public InternalBrokerHolder(final Broker broker)
- {
- if(broker == null)
- {
- throw new IllegalArgumentException("Broker must not be null");
- }
-
- _broker = broker;
- }
-
- public void shutdown()
- {
- LOGGER.info("Shutting down Broker instance");
-
- _broker.shutdown();
-
- LOGGER.info("Broker instance shutdown");
- }
-
-}
diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/test/utils/JMXTestUtils.java b/qpid/java/systests/src/main/java/org/apache/qpid/test/utils/JMXTestUtils.java
index 1fde6c7c73..ff80c91fac 100644
--- a/qpid/java/systests/src/main/java/org/apache/qpid/test/utils/JMXTestUtils.java
+++ b/qpid/java/systests/src/main/java/org/apache/qpid/test/utils/JMXTestUtils.java
@@ -21,8 +21,6 @@
package org.apache.qpid.test.utils;
import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
import java.util.Set;
import javax.management.JMException;
@@ -33,17 +31,14 @@ import javax.management.ObjectName;
import javax.management.MalformedObjectNameException;
import javax.management.remote.JMXConnector;
-import junit.framework.TestCase;
-
import org.apache.commons.configuration.ConfigurationException;
+import org.apache.qpid.commands.objects.AllObjects;
import org.apache.qpid.management.common.JMXConnnectionFactory;
import org.apache.qpid.management.common.mbeans.ManagedBroker;
-import org.apache.qpid.management.common.mbeans.ManagedConnection;
import org.apache.qpid.management.common.mbeans.ManagedExchange;
import org.apache.qpid.management.common.mbeans.LoggingManagement;
import org.apache.qpid.management.common.mbeans.ConfigurationManagement;
import org.apache.qpid.management.common.mbeans.ManagedQueue;
-import org.apache.qpid.management.common.mbeans.ServerInformation;
import org.apache.qpid.management.common.mbeans.UserManagement;
/**
@@ -236,10 +231,10 @@ public class JMXTestUtils
public ObjectName getVirtualHostManagerObjectName(String vhostName)
{
// Get the name of the test manager
- String query = "org.apache.qpid:type=VirtualHost.VirtualHostManager,VirtualHost="
- + ObjectName.quote(vhostName) + ",*";
+ AllObjects allObject = new AllObjects(_mbsc);
+ allObject.querystring = "org.apache.qpid:type=VirtualHost.VirtualHostManager,VirtualHost=" + vhostName + ",*";
- Set<ObjectName> objectNames = queryObjects(query);
+ Set<ObjectName> objectNames = allObject.returnObjects();
_test.assertNotNull("Null ObjectName Set returned", objectNames);
_test.assertEquals("Incorrect number test vhosts returned", 1, objectNames.size());
@@ -263,14 +258,14 @@ public class JMXTestUtils
public ObjectName getQueueObjectName(String virtualHostName, String queue)
{
// Get the name of the test manager
- String query = "org.apache.qpid:type=VirtualHost.Queue,VirtualHost="
- + ObjectName.quote(virtualHostName) + ",name="
- + ObjectName.quote(queue) + ",*";
+ AllObjects allObject = new AllObjects(_mbsc);
+ allObject.querystring = "org.apache.qpid:type=VirtualHost.Queue,VirtualHost=" + virtualHostName + ",name=" + queue + ",*";
- Set<ObjectName> objectNames = queryObjects(query);
+ Set<ObjectName> objectNames = allObject.returnObjects();
_test.assertNotNull("Null ObjectName Set returned", objectNames);
- _test.assertEquals("Incorrect number of queues with name '" + queue + "' returned", 1, objectNames.size());
+ _test.assertEquals("Incorrect number of queues with name '" + allObject.querystring +
+ "' returned", 1, objectNames.size());
// We have verified we have only one value in objectNames so return it
ObjectName objectName = objectNames.iterator().next();
@@ -291,11 +286,10 @@ public class JMXTestUtils
public ObjectName getExchangeObjectName(String virtualHostName, String exchange)
{
// Get the name of the test manager
- String query = "org.apache.qpid:type=VirtualHost.Exchange,VirtualHost="
- + ObjectName.quote(virtualHostName) + ",name="
- + ObjectName.quote(exchange) + ",*";
+ AllObjects allObject = new AllObjects(_mbsc);
+ allObject.querystring = "org.apache.qpid:type=VirtualHost.Exchange,VirtualHost=" + virtualHostName + ",name=" + exchange + ",*";
- Set<ObjectName> objectNames = queryObjects(query);
+ Set<ObjectName> objectNames = allObject.returnObjects();
_test.assertNotNull("Null ObjectName Set returned", objectNames);
_test.assertEquals("Incorrect number of exchange with name '" + exchange + "' returned", 1, objectNames.size());
@@ -307,9 +301,12 @@ public class JMXTestUtils
}
@SuppressWarnings("static-access")
- public <T> T getManagedObject(Class<T> managedClass, String query)
+ public <T> T getManagedObject(Class<T> managedClass, String queryString)
{
- Set<ObjectName> objectNames = queryObjects(query);
+ AllObjects allObject = new AllObjects(_mbsc);
+ allObject.querystring = queryString;
+
+ Set<ObjectName> objectNames = allObject.returnObjects();
_test.assertNotNull("Null ObjectName Set returned", objectNames);
_test.assertEquals("More than one " + managedClass + " returned", 1, objectNames.size());
@@ -324,16 +321,6 @@ public class JMXTestUtils
return MBeanServerInvocationHandler.newProxyInstance(_mbsc, objectName, managedClass, false);
}
- public <T> List<T> getManagedObjectList(Class<T> managedClass, Set<ObjectName> objectNames)
- {
- List<T> objects = new ArrayList<T>();
- for (ObjectName name : objectNames)
- {
- objects.add(getManagedObject(managedClass, name));
- }
- return objects;
- }
-
public ManagedBroker getManagedBroker(String virtualHost)
{
return getManagedObject(ManagedBroker.class, getVirtualHostManagerObjectName(virtualHost));
@@ -368,68 +355,4 @@ public class JMXTestUtils
ObjectName objectName = new ObjectName("org.apache.qpid:type=UserManagement,name=UserManagement");
return getManagedObject(UserManagement.class, objectName);
}
-
- /**
- * Retrive {@link ServerInformation} JMX MBean.
- */
- public ServerInformation getServerInformation()
- {
- // Get the name of the test manager
- String query = "org.apache.qpid:type=ServerInformation,name=ServerInformation,*";
-
- Set<ObjectName> objectNames = queryObjects(query);
-
- TestCase.assertNotNull("Null ObjectName Set returned", objectNames);
- TestCase.assertEquals("Incorrect number of objects returned", 1, objectNames.size());
-
- // We have verified we have only one value in objectNames so return it
- return getManagedObject(ServerInformation.class, objectNames.iterator().next());
- }
-
- /**
- * Retrive all {@link ManagedConnection} objects.
- */
- public List<ManagedConnection> getAllManagedConnections()
- {
- // Get the name of the test manager
- String query = "org.apache.qpid:type=VirtualHost.Connection,VirtualHost=*,name=*";
-
- Set<ObjectName> objectNames = queryObjects(query);
-
- TestCase.assertNotNull("Null ObjectName Set returned", objectNames);
-
- return getManagedObjectList(ManagedConnection.class, objectNames);
- }
-
- /**
- * Retrive all {@link ManagedConnection} objects for a particular virtual host.
- */
- public List<ManagedConnection> getManagedConnections(String vhost)
- {
- // Get the name of the test manager
- String query = "org.apache.qpid:type=VirtualHost.Connection,VirtualHost=" + ObjectName.quote(vhost) + ",name=*";
-
- Set<ObjectName> objectNames = queryObjects(query);
-
- TestCase.assertNotNull("Null ObjectName Set returned", objectNames);
-
- return getManagedObjectList(ManagedConnection.class, objectNames);
- }
-
- /**
- * Returns the Set of ObjectNames returned by the broker for the given query,
- * or null if there is problem while performing the query.
- */
- private Set<ObjectName> queryObjects(String query)
- {
- try
- {
- return _mbsc.queryNames(new ObjectName(query), null);
- }
- catch (Exception e)
- {
- e.printStackTrace();
- return null;
- }
- }
}
diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/test/utils/QpidBrokerTestCase.java b/qpid/java/systests/src/main/java/org/apache/qpid/test/utils/QpidBrokerTestCase.java
index c8ccdf91bb..ae38a75e7a 100644
--- a/qpid/java/systests/src/main/java/org/apache/qpid/test/utils/QpidBrokerTestCase.java
+++ b/qpid/java/systests/src/main/java/org/apache/qpid/test/utils/QpidBrokerTestCase.java
@@ -25,7 +25,6 @@ import java.io.InputStreamReader;
import java.io.LineNumberReader;
import java.io.PrintStream;
import java.net.MalformedURLException;
-import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
@@ -55,20 +54,19 @@ import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.apache.qpid.AMQException;
+import org.apache.qpid.client.AMQConnection;
import org.apache.qpid.client.AMQConnectionFactory;
import org.apache.qpid.client.AMQQueue;
+import org.apache.qpid.client.transport.TransportConnection;
import org.apache.qpid.exchange.ExchangeDefaults;
import org.apache.qpid.jms.BrokerDetails;
import org.apache.qpid.jms.ConnectionURL;
import org.apache.qpid.management.common.mbeans.ConfigurationManagement;
-import org.apache.qpid.server.Broker;
-import org.apache.qpid.server.BrokerOptions;
-import org.apache.qpid.server.ProtocolExclusion;
import org.apache.qpid.server.configuration.ServerConfiguration;
-import org.apache.qpid.server.protocol.AmqpProtocolVersion;
+import org.apache.qpid.server.registry.ApplicationRegistry;
+import org.apache.qpid.server.registry.ConfigurationFileApplicationRegistry;
import org.apache.qpid.server.store.DerbyMessageStore;
import org.apache.qpid.url.URLSyntaxException;
-import org.apache.qpid.util.FileUtils;
import org.apache.qpid.util.LogMonitor;
/**
@@ -76,13 +74,6 @@ import org.apache.qpid.util.LogMonitor;
*/
public class QpidBrokerTestCase extends QpidTestCase
{
-
- public enum BrokerType
- {
- EXTERNAL /** Test case relies on a Broker started independently of the test-suite */,
- INTERNAL /** Test case starts an embedded broker within this JVM */,
- SPAWNED /** Test case spawns a new broker as a separate process */
- }
protected final String QpidHome = System.getProperty("QPID_HOME");
protected File _configFile = new File(System.getProperty("broker.config"));
@@ -91,6 +82,7 @@ public class QpidBrokerTestCase extends QpidTestCase
protected long RECEIVE_TIMEOUT = 1000l;
+ private Map<String, String> _propertiesSetForTestOnly = new HashMap<String, String>();
private Map<String, String> _propertiesSetForBroker = new HashMap<String, String>();
private Map<Logger, Level> _loggerLevelSetForTest = new HashMap<Logger, Level>();
@@ -114,11 +106,9 @@ public class QpidBrokerTestCase extends QpidTestCase
// system properties
private static final String BROKER_LANGUAGE = "broker.language";
- private static final String BROKER_TYPE = "broker.type";
- private static final String BROKER_COMMAND = "broker.command";
+ private static final String BROKER = "broker";
private static final String BROKER_CLEAN = "broker.clean";
private static final String BROKER_CLEAN_BETWEEN_TESTS = "broker.clean.between.tests";
- private static final String BROKER_EXISTING_QPID_WORK = "broker.existing.qpid.work";
private static final String BROKER_VERSION = "broker.version";
protected static final String BROKER_READY = "broker.ready";
private static final String BROKER_STOPPED = "broker.stopped";
@@ -126,30 +116,29 @@ public class QpidBrokerTestCase extends QpidTestCase
private static final String BROKER_LOG_INTERLEAVE = "broker.log.interleave";
private static final String BROKER_LOG_PREFIX = "broker.log.prefix";
private static final String BROKER_PERSITENT = "broker.persistent";
- private static final String BROKER_PROTOCOL_EXCLUDES = "broker.protocol.excludes";
-
// values
protected static final String JAVA = "java";
protected static final String CPP = "cpp";
+ protected static final String VM = "vm";
+ protected static final String EXTERNAL = "external";
+ private static final String VERSION_08 = "0-8";
+ private static final String VERSION_010 = "0-10";
protected static final String QPID_HOME = "QPID_HOME";
public static final int DEFAULT_VM_PORT = 1;
public static final int DEFAULT_PORT = Integer.getInteger("test.port", ServerConfiguration.DEFAULT_PORT);
- public static final int FAILING_PORT = Integer.parseInt(System.getProperty("test.port.alt"));
public static final int DEFAULT_MANAGEMENT_PORT = Integer.getInteger("test.mport", ServerConfiguration.DEFAULT_JMXPORT);
public static final int DEFAULT_SSL_PORT = Integer.getInteger("test.sslport", ServerConfiguration.DEFAULT_SSL_PORT);
protected String _brokerLanguage = System.getProperty(BROKER_LANGUAGE, JAVA);
- protected BrokerType _brokerType = BrokerType.valueOf(System.getProperty(BROKER_TYPE, "").toUpperCase());
- protected String _brokerCommand = System.getProperty(BROKER_COMMAND);
+ protected String _broker = System.getProperty(BROKER, VM);
private String _brokerClean = System.getProperty(BROKER_CLEAN, null);
private Boolean _brokerCleanBetweenTests = Boolean.getBoolean(BROKER_CLEAN_BETWEEN_TESTS);
- private final AmqpProtocolVersion _brokerVersion = AmqpProtocolVersion.valueOf(System.getProperty(BROKER_VERSION, ""));
+ private String _brokerVersion = System.getProperty(BROKER_VERSION, VERSION_08);
protected String _output = System.getProperty(TEST_OUTPUT);
protected Boolean _brokerPersistent = Boolean.getBoolean(BROKER_PERSITENT);
- private String _brokerProtocolExcludes = System.getProperty(BROKER_PROTOCOL_EXCLUDES);
protected static String _brokerLogPrefix = System.getProperty(BROKER_LOG_PREFIX,"BROKER: ");
protected static boolean _interleaveBrokerLog = Boolean.getBoolean(BROKER_LOG_INTERLEAVE);
@@ -158,7 +147,7 @@ public class QpidBrokerTestCase extends QpidTestCase
protected PrintStream _brokerOutputStream;
- protected Map<Integer, BrokerHolder> _brokers = new HashMap<Integer, BrokerHolder>();
+ protected Map<Integer, Process> _brokers = new HashMap<Integer, Process>();
protected InitialContext _initialContext;
protected AMQConnectionFactory _connectionFactory;
@@ -294,16 +283,6 @@ public class QpidBrokerTestCase extends QpidTestCase
fail("Unable to test without config file:" + _configFile);
}
- String existingQpidWorkPath = System.getProperty(BROKER_EXISTING_QPID_WORK);
- if(existingQpidWorkPath != null && !existingQpidWorkPath.equals(""))
- {
- cleanBroker();
-
- File existing = new File(existingQpidWorkPath);
- File qpidWork = new File(getQpidWork(_brokerType, getPort()));
- FileUtils.copyRecursive(existing, qpidWork);
- }
-
startBroker();
}
@@ -404,8 +383,13 @@ public class QpidBrokerTestCase extends QpidTestCase
}
}
+ public void startBroker() throws Exception
+ {
+ startBroker(0);
+ }
+
/**
- * Return the management port in use by the broker on this main port
+ * Return the management portin use by the broker on this main port
*
* @param mainPort the broker's main port.
*
@@ -413,7 +397,7 @@ public class QpidBrokerTestCase extends QpidTestCase
*/
protected int getManagementPort(int mainPort)
{
- return mainPort + (DEFAULT_MANAGEMENT_PORT - DEFAULT_PORT);
+ return mainPort + (DEFAULT_MANAGEMENT_PORT - (_broker.equals(VM) ? DEFAULT_VM_PORT : DEFAULT_PORT));
}
/**
@@ -428,7 +412,11 @@ public class QpidBrokerTestCase extends QpidTestCase
protected int getPort(int port)
{
- if (!_brokerType.equals(BrokerType.EXTERNAL))
+ if (_broker.equals(VM))
+ {
+ return port == 0 ? DEFAULT_VM_PORT : port;
+ }
+ else if (!_broker.equals(EXTERNAL))
{
return port == 0 ? DEFAULT_PORT : port;
}
@@ -440,18 +428,11 @@ public class QpidBrokerTestCase extends QpidTestCase
protected String getBrokerCommand(int port) throws MalformedURLException
{
- final String protocolExcludesList = _brokerProtocolExcludes.replace("@PORT", "" + port);
- return _brokerCommand
+ return _broker
.replace("@PORT", "" + port)
.replace("@SSL_PORT", "" + (port - 1))
.replace("@MPORT", "" + getManagementPort(port))
- .replace("@CONFIG_FILE", _configFile.toString())
- .replace("@EXCLUDES", protocolExcludesList);
- }
-
- public void startBroker() throws Exception
- {
- startBroker(0);
+ .replace("@CONFIG_FILE", _configFile.toString());
}
public void startBroker(int port) throws Exception
@@ -462,38 +443,38 @@ public class QpidBrokerTestCase extends QpidTestCase
saveTestConfiguration();
saveTestVirtualhosts();
- if(_brokers.get(port) != null)
- {
- throw new IllegalStateException("There is already an existing broker running on port " + port);
- }
-
- if (_brokerType.equals(BrokerType.INTERNAL) && !existingInternalBroker())
+ Process process = null;
+ if (_broker.equals(VM))
{
+ setConfigurationProperty("management.jmxport", String.valueOf(getManagementPort(port)));
setConfigurationProperty(ServerConfiguration.MGMT_CUSTOM_REGISTRY_SOCKET, String.valueOf(false));
saveTestConfiguration();
-
- BrokerOptions options = new BrokerOptions();
- options.setConfigFile(_configFile.getAbsolutePath());
- options.addPort(port);
-
- addExcludedPorts(port, options);
-
- options.setJmxPort(getManagementPort(port));
-
- //Set the log config file, relying on the log4j.configuration system property
- //set on the JVM by the JUnit runner task in module.xml.
- options.setLogConfigFile(new URL(System.getProperty("log4j.configuration")).getFile());
-
- Broker broker = new Broker();
- _logger.info("starting internal broker (same JVM)");
- broker.startup(options);
-
- _brokers.put(port, new InternalBrokerHolder(broker));
+
+ // create an in_VM broker
+ final ConfigurationFileApplicationRegistry registry = new ConfigurationFileApplicationRegistry(_configFile);
+ try
+ {
+ ApplicationRegistry.initialise(registry, port);
+ }
+ catch (Exception e)
+ {
+ _logger.error("Broker initialise failed due to:",e);
+ try
+ {
+ registry.close();
+ }
+ catch (Throwable closeE)
+ {
+ closeE.printStackTrace();
+ }
+ throw e;
+ }
+ TransportConnection.createVMBroker(port);
}
- else if (!_brokerType.equals(BrokerType.EXTERNAL))
+ else if (!_broker.equals(EXTERNAL))
{
String cmd = getBrokerCommand(port);
- _logger.info("starting external broker: " + cmd);
+ _logger.info("starting broker: " + cmd);
ProcessBuilder pb = new ProcessBuilder(cmd.split("\\s+"));
pb.redirectErrorStream(true);
@@ -509,7 +490,7 @@ public class QpidBrokerTestCase extends QpidTestCase
// DON'T change PNAME, qpid.stop needs this value.
env.put("QPID_PNAME", "-DPNAME=QPBRKR -DTNAME=\"" + _testName + "\"");
// Add the port to QPID_WORK to ensure unique working dirs for multi broker tests
- env.put("QPID_WORK", getQpidWork(_brokerType, port));
+ env.put("QPID_WORK", System.getProperty("QPID_WORK")+ "/" + port);
// Use the environment variable to set amqj.logging.level for the broker
@@ -561,7 +542,8 @@ public class QpidBrokerTestCase extends QpidTestCase
env.put("QPID_OPTS", QPID_OPTS);
}
}
- Process process = pb.start();;
+
+ process = pb.start();
Piper p = new Piper(process.getInputStream(),
_brokerOutputStream,
@@ -582,7 +564,6 @@ public class QpidBrokerTestCase extends QpidTestCase
try
{
- //test that the broker is still running and hasn't exited unexpectedly
int exit = process.exitValue();
_logger.info("broker aborted: " + exit);
cleanBroker();
@@ -590,58 +571,11 @@ public class QpidBrokerTestCase extends QpidTestCase
}
catch (IllegalThreadStateException e)
{
- // this is expect if the broker started successfully
+ // this is expect if the broker started succesfully
}
-
- _brokers.put(port, new SpawnedBrokerHolder(process));
}
- }
- private void addExcludedPorts(int port, BrokerOptions options)
- {
- final String protocolExcludesList = _brokerProtocolExcludes.replace("@PORT", "" + port);
-
- if (protocolExcludesList.equals(""))
- {
- return;
- }
- final String[] toks = protocolExcludesList.split("\\s");
-
- if(toks.length % 2 != 0)
- {
- throw new IllegalArgumentException("Must be an even number of tokens in '" + protocolExcludesList + "'");
- }
- for (int i = 0; i < toks.length; i=i+2)
- {
- String excludeArg = toks[i];
- final int excludedPort = Integer.parseInt(toks[i+1]);
- options.addExcludedPort(ProtocolExclusion.lookup(excludeArg), excludedPort);
-
- _logger.info("Adding protocol exclusion " + excludeArg + " " + excludedPort);
- }
- }
-
- private boolean existingInternalBroker()
- {
- for(BrokerHolder holder : _brokers.values())
- {
- if(holder instanceof InternalBrokerHolder)
- {
- return true;
- }
- }
-
- return false;
- }
-
- private String getQpidWork(BrokerType broker, int port)
- {
- if (!broker.equals(BrokerType.EXTERNAL))
- {
- return System.getProperty("QPID_WORK")+ "/" + port;
- }
-
- return System.getProperty("QPID_WORK");
+ _brokers.put(port, process);
}
public String getTestConfigFile()
@@ -722,17 +656,20 @@ public class QpidBrokerTestCase extends QpidTestCase
port = getPort(port);
_logger.info("stopping broker: " + getBrokerCommand(port));
- BrokerHolder broker = _brokers.remove(port);
- broker.shutdown();
+ Process process = _brokers.remove(port);
+ if (process != null)
+ {
+ process.destroy();
+ process.waitFor();
+ _logger.info("broker exited: " + process.exitValue());
+ }
+ else if (_broker.equals(VM))
+ {
+ TransportConnection.killVMBroker(port);
+ ApplicationRegistry.remove(port);
+ }
}
- public boolean isBrokerPresent(int port) throws Exception
- {
- port = getPort(port);
-
- return _brokers.containsKey(port);
- }
-
/**
* Attempt to set the Java Broker to use the BDBMessageStore for persistence
* Falling back to the DerbyMessageStore if
@@ -874,14 +811,20 @@ public class QpidBrokerTestCase extends QpidTestCase
}
/**
- * Set a System property for the client (and broker if using the same vm) of this test.
+ * Set a System (-D) property for the external Broker of this test.
*
* @param property The property to set
* @param value the value to set it to.
*/
protected void setTestClientSystemProperty(String property, String value)
{
- setTestSystemProperty(property, value);
+ if (!_propertiesSetForTestOnly.containsKey(property))
+ {
+ // Record the current value so we can revert it later.
+ _propertiesSetForTestOnly.put(property, System.getProperty(property));
+ }
+
+ System.setProperty(property, value);
}
/**
@@ -889,7 +832,20 @@ public class QpidBrokerTestCase extends QpidTestCase
*/
protected void revertSystemProperties()
{
- revertTestSystemProperties();
+ for (String key : _propertiesSetForTestOnly.keySet())
+ {
+ String value = _propertiesSetForTestOnly.get(key);
+ if (value != null)
+ {
+ System.setProperty(key, value);
+ }
+ else
+ {
+ System.clearProperty(key);
+ }
+ }
+
+ _propertiesSetForTestOnly.clear();
// We don't change the current VMs settings for Broker only properties
// so we can just clear this map
@@ -948,17 +904,17 @@ public class QpidBrokerTestCase extends QpidTestCase
*/
public boolean isBroker08()
{
- return _brokerVersion.equals(AmqpProtocolVersion.v0_8);
+ return _brokerVersion.equals(VERSION_08);
}
public boolean isBroker010()
{
- return _brokerVersion.equals(AmqpProtocolVersion.v0_10);
+ return _brokerVersion.equals(VERSION_010);
}
protected boolean isJavaBroker()
{
- return _brokerLanguage.equals("java") || _brokerType.equals("vm");
+ return _brokerLanguage.equals("java") || _broker.equals("vm");
}
protected boolean isCppBroker()
@@ -968,14 +924,9 @@ public class QpidBrokerTestCase extends QpidTestCase
protected boolean isExternalBroker()
{
- return !_brokerType.equals("vm"); //TODO
+ return !_broker.equals("vm");
}
-
- protected boolean isInternalBroker()
- {
- return _brokerType.equals(BrokerType.INTERNAL);
- }
-
+
protected boolean isBrokerStorePersistent()
{
return _brokerPersistent;
@@ -1047,6 +998,11 @@ public class QpidBrokerTestCase extends QpidTestCase
*/
public AMQConnectionFactory getConnectionFactory(String factoryName) throws NamingException
{
+ if (_broker.equals(VM))
+ {
+ factoryName += ".vm";
+ }
+
return (AMQConnectionFactory) getInitialContext().lookup(factoryName);
}
@@ -1087,7 +1043,15 @@ public class QpidBrokerTestCase extends QpidTestCase
public Connection getClientConnection(String username, String password, String id) throws JMSException, URLSyntaxException, AMQException, NamingException
{
_logger.info("get Connection");
- Connection con = getConnectionFactory().createConnection(username, password, id);
+ Connection con;
+ if (_broker.equals(VM))
+ {
+ con = new AMQConnection("vm://:1", username, password, id, "test");
+ }
+ else
+ {
+ con = getConnectionFactory().createConnection(username, password, id);
+ }
//add the connection in the lis of connections
_connections.add(con);
return con;
@@ -1125,8 +1089,7 @@ public class QpidBrokerTestCase extends QpidTestCase
c.close();
}
}
- finally
- {
+ finally{
// Ensure any problems with close does not interfer with property resets
revertSystemProperties();
revertLoggingLevels();
@@ -1227,8 +1190,7 @@ public class QpidBrokerTestCase extends QpidTestCase
MessageProducer producer = session.createProducer(destination);
- int i = offset;
- for (; i < (count + offset); i++)
+ for (int i = offset; i < (count + offset); i++)
{
Message next = createNextMessage(session, i);
@@ -1251,7 +1213,7 @@ public class QpidBrokerTestCase extends QpidTestCase
// we have no batchSize or
// our count is not divible by batchSize.
if (session.getTransacted() &&
- ( batchSize == 0 || (i-1) % batchSize != 0))
+ ( batchSize == 0 || count % batchSize != 0))
{
session.commit();
}
@@ -1346,26 +1308,29 @@ public class QpidBrokerTestCase extends QpidTestCase
*/
public void reloadBrokerSecurityConfig() throws Exception
{
- JMXTestUtils jmxu = new JMXTestUtils(this, "admin" , "admin");
- jmxu.open();
-
- try
+ if (_broker.equals(VM))
{
- ConfigurationManagement configMBean = jmxu.getConfigurationManagement();
- configMBean.reloadSecurityConfiguration();
+ ApplicationRegistry.getInstance().getConfiguration().reparseConfigFileSecuritySections();
}
- finally
+ else
{
- jmxu.close();
- }
-
- LogMonitor _monitor = new LogMonitor(_outputFile);
- assertTrue("The expected server security configuration reload did not occur",
- _monitor.waitForMessage(ServerConfiguration.SECURITY_CONFIG_RELOADED, LOGMONITOR_TIMEOUT));
- }
+ JMXTestUtils jmxu = new JMXTestUtils(this, "admin" , "admin");
+ jmxu.open();
+
+ try
+ {
+ ConfigurationManagement configMBean = jmxu.getConfigurationManagement();
+ configMBean.reloadSecurityConfiguration();
+ }
+ finally
+ {
+ jmxu.close();
+ }
+
+ LogMonitor _monitor = new LogMonitor(_outputFile);
+ assertTrue("The expected server security configuration reload did not occur",
+ _monitor.waitForMessage(ServerConfiguration.SECURITY_CONFIG_RELOADED, LOGMONITOR_TIMEOUT));
- protected int getFailingPort()
- {
- return FAILING_PORT;
+ }
}
}
diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/test/utils/SpawnedBrokerHolder.java b/qpid/java/systests/src/main/java/org/apache/qpid/test/utils/SpawnedBrokerHolder.java
deleted file mode 100644
index 65239bbe02..0000000000
--- a/qpid/java/systests/src/main/java/org/apache/qpid/test/utils/SpawnedBrokerHolder.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
- */
-package org.apache.qpid.test.utils;
-
-import org.apache.log4j.Logger;
-
-public class SpawnedBrokerHolder implements BrokerHolder
-{
- private static final Logger LOGGER = Logger.getLogger(SpawnedBrokerHolder.class);
-
- private final Process _process;
-
- public SpawnedBrokerHolder(final Process process)
- {
- if(process == null)
- {
- throw new IllegalArgumentException("Process must not be null");
- }
-
- _process = process;
- }
-
- public void shutdown()
- {
- LOGGER.info("Destroying broker process");
-
- _process.destroy();
-
- try
- {
- _process.waitFor();
- LOGGER.info("broker exited: " + _process.exitValue());
- }
- catch (InterruptedException e)
- {
- LOGGER.error("Interrupted whilst waiting for process destruction");
- Thread.currentThread().interrupt();
- }
- }
-}
diff --git a/qpid/java/test-profiles/08StandaloneExcludes b/qpid/java/test-profiles/08StandaloneExcludes
new file mode 100644
index 0000000000..b482a14c6d
--- /dev/null
+++ b/qpid/java/test-profiles/08StandaloneExcludes
@@ -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.
+//
+
+//======================================================================
+//Exclude the following from brokers defaulting to the 0-8 protocol
+//======================================================================
+
+// This test requires a broker capable of 0-8/9 and 0-10
+org.apache.qpid.test.client.message.JMSDestinationTest#testReceiveResend
+
+// QPID-2478 test fails when run against broker using 0-8/9
+org.apache.qpid.test.client.message.JMSDestinationTest#testGetDestinationWithCustomExchange
+
+// The new addressing based sytanx is not supported for AMQP 0-8/0-9 versions
+org.apache.qpid.test.client.destination.AddressBasedDestinationTest#*
+org.apache.qpid.test.client.queue.QueuePolicyTest#testRingPolicy
+org.apache.qpid.test.client.queue.QueuePolicyTest#testRejectPolicy
+
+// Those tests are written against the 0.10 path
+org.apache.qpid.test.unit.message.UTF8Test#*
+org.apache.qpid.client.MessageListenerTest#testSynchronousReceiveNoWait
+
+org.apache.qpid.test.unit.client.connection.ConnectionTest#testUnsupportedSASLMechanism
diff --git a/qpid/java/test-profiles/CPPExcludes b/qpid/java/test-profiles/CPPExcludes
index 89cdd792de..e89b09cca2 100755
--- a/qpid/java/test-profiles/CPPExcludes
+++ b/qpid/java/test-profiles/CPPExcludes
@@ -17,9 +17,6 @@
// under the License.
//
-// QPID-3391: the C++ broker does not currently validate the exchange creation arguments
-org.apache.qpid.test.client.destination.AddressBasedDestinationTest#testCreateExchangeWithNonsenseArgs
-
org.apache.qpid.test.unit.client.channelclose.ChannelCloseTest#*
org.apache.qpid.client.ResetMessageListenerTest#*
@@ -168,14 +165,6 @@ org.apache.qpid.server.security.firewall.FirewallConfigTest#*
org.apache.qpid.server.security.firewall.FirewallConfigurationTest#*
org.apache.qpid.server.plugins.PluginTest#*
-// Transacion timeouts not implemented in CPP broker
-org.apache.qpid.test.unit.transacted.TransactionTimeoutDisabledTest#*
-org.apache.qpid.test.unit.transacted.TransactionTimeoutConfigurationTest#*
-org.apache.qpid.test.unit.transacted.TransactionTimeoutTest#*
-
// Java broker only
org.apache.qpid.server.logging.management.LoggingManagementMBeanTest#*
org.apache.qpid.server.management.AMQUserManagementMBeanTest#*
-
-// QPID-3133: On 0-10, the exception listener is currently not invoked when reconnection fails to occurs.
-org.apache.qpid.server.failover.FailoverMethodTest#*
diff --git a/qpid/java/test-profiles/Excludes b/qpid/java/test-profiles/Excludes
index 7e096d3ac8..ff6993fa0b 100644
--- a/qpid/java/test-profiles/Excludes
+++ b/qpid/java/test-profiles/Excludes
@@ -17,6 +17,7 @@
// under the License.
//
+org.apache.qpid.client.MultipleJCAProviderRegistrationTest#test
// 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
@@ -49,3 +50,4 @@ org.apache.qpid.test.unit.ack.AcknowledgeAfterFailoverTest#*
// QPID-2418 : The queue backing the dur sub is not currently deleted at subscription change, so the test will fail.
org.apache.qpid.test.unit.ct.DurableSubscriberTest#testResubscribeWithChangedSelectorAndRestart
+
diff --git a/qpid/java/test-profiles/Java010Excludes b/qpid/java/test-profiles/Java010Excludes
index f8210e2b06..3486d5c70c 100755
--- a/qpid/java/test-profiles/Java010Excludes
+++ b/qpid/java/test-profiles/Java010Excludes
@@ -47,7 +47,6 @@ org.apache.qpid.server.logging.SubscriptionLoggingTest#testSubscriptionSuspend
// 0-10 Broker does not have a JMX connection MBean
org.apache.qpid.management.jmx.ManagementActorLoggingTest#testConnectionCloseViaManagement
-org.apache.qpid.management.jmx.MessageConnectionStatisticsTest#*
// 0-10 has different ideas about clientid and ownership of queues
org.apache.qpid.server.queue.ModelTest#*
@@ -55,6 +54,9 @@ org.apache.qpid.server.queue.ModelTest#*
// 0-10 is not supported by the MethodRegistry
org.apache.qpid.test.unit.close.JavaServerCloseRaceConditionTest#*
+// QPID-2084 : this test needs more work for 0-10
+org.apache.qpid.test.unit.client.DynamicQueueExchangeCreateTest#*
+
//QPID-942 : Implemented Channel.Flow based Producer Side flow control to the Java Broker (not in CPP Broker)
org.apache.qpid.server.queue.ProducerFlowControlTest#*
@@ -72,16 +74,8 @@ org.apache.qpid.test.unit.publish.DirtyTransactedPublishTest#*
org.apache.qpid.test.client.RollbackOrderTest#testOrderingAfterRollbackOnMessage
org.apache.qpid.test.unit.ack.RecoverTest#testRecoverInAutoAckListener
-// This test uses 0-8 channel frames
-org.apache.qpid.test.unit.client.channelclose.ChannelCloseTest#*
-
//Temporarily adding the following until the issues are sorted out.
//Should probably raise JIRAs for them.
+org.apache.qpid.transport.network.mina.MINANetworkDriverTest#*
+org.apache.qpid.test.client.destination.AddressBasedDestinationTest#testCreateExchange
org.apache.qpid.test.client.destination.AddressBasedDestinationTest#testBrowseMode
-
-// QPID-3133: On 0-10, the exception listener is currently not invoked when reconnection fails to occurs.
-org.apache.qpid.server.failover.FailoverMethodTest#*
-
-// QPID-3092: the Java broker does not yet implement exchange creation arguments
-org.apache.qpid.test.client.destination.AddressBasedDestinationTest#testCreateExchangeWithArgs
-org.apache.qpid.test.client.destination.AddressBasedDestinationTest#testSessionCreateTopicWithExchangeArgs
diff --git a/qpid/java/test-profiles/JavaExcludes b/qpid/java/test-profiles/JavaExcludes
index 4be228c7da..c38a250abc 100644
--- a/qpid/java/test-profiles/JavaExcludes
+++ b/qpid/java/test-profiles/JavaExcludes
@@ -19,6 +19,13 @@
// Those tests are not finished
org.apache.qpid.test.testcases.TTLTest#*
+org.apache.qpid.test.testcases.FailoverTest#*
+
+// This is a long running test so should exclude from normal runs
+org.apache.qpid.test.client.failover.FailoverTest#test4MinuteFailover
+
+//QPID-1818 : Client code path does not correctly restore a transacted session after failover.
+org.apache.qpid.server.persistent.NoLocalAfterRecoveryTest#*
// QPID-1823: this takes ages to run
org.apache.qpid.client.SessionCreateTest#*
@@ -45,46 +52,3 @@ org.apache.qpid.transport.ConnectionTest#testResumeNonemptyReplayBuffer
//QPID-2845: The queue policy types used by the C++ broker are not currently supported by the Java broker
org.apache.qpid.test.client.queue.QueuePolicyTest#testRingPolicy
org.apache.qpid.test.client.queue.QueuePolicyTest#testRejectPolicy
-
-///////////////////////////////////////////////////////
-//Moved from JavaStandaloneExcludes when it was removed
-///////////////////////////////////////////////////////
-
-// This is a long running test so should exclude from normal runs
-org.apache.qpid.test.client.failover.FailoverTest#test4MinuteFailover
-
-// Those tests require failover support
-org.apache.qpid.test.client.QueueBrowserAutoAckTest#testFailoverAsQueueBrowserCreated
-org.apache.qpid.test.client.QueueBrowserAutoAckTest#testFailoverWithQueueBrowser
-org.apache.qpid.test.client.QueueBrowserClientAckTest#testFailoverAsQueueBrowserCreated
-org.apache.qpid.test.client.QueueBrowserClientAckTest#testFailoverWithQueueBrowser
-org.apache.qpid.test.client.QueueBrowserDupsOkTest#testFailoverAsQueueBrowserCreated
-org.apache.qpid.test.client.QueueBrowserDupsOkTest#testFailoverWithQueueBrowser
-org.apache.qpid.test.client.QueueBrowserNoAckTest#testFailoverAsQueueBrowserCreated
-org.apache.qpid.test.client.QueueBrowserNoAckTest#testFailoverWithQueueBrowser
-org.apache.qpid.test.client.QueueBrowserPreAckTest#testFailoverAsQueueBrowserCreated
-org.apache.qpid.test.client.QueueBrowserPreAckTest#testFailoverWithQueueBrowser
-org.apache.qpid.test.client.QueueBrowserTransactedTest#testFailoverAsQueueBrowserCreated
-org.apache.qpid.test.client.QueueBrowserTransactedTest#testFailoverWithQueueBrowser
-org.apache.qpid.test.testcases.FailoverTest#*
-org.apache.qpid.test.client.failover.FailoverTest#*
-
-// InVM Broker tests awaiting resolution of QPID-1103
-org.apache.qpid.test.client.timeouts.SyncWaitDelayTest#*
-org.apache.qpid.test.client.timeouts.SyncWaitTimeoutDelayTest#*
-
-// This test currently does not pick up the runtime location of the nonVm queueBacking store.
-org.apache.qpid.test.unit.close.FlowToDiskBackingQueueDeleteTest#*
-
-// This test may use QpidTestCase but it is not using the getConnection and is hardwired to InVM
-org.apache.qpid.test.unit.client.connection.CloseAfterConnectionFailureTest#*
-
-//QPID-1818 : Client code path does not correctly restore a transacted session after failover.
-org.apache.qpid.server.persistent.NoLocalAfterRecoveryTest#*
-
-// This test requires the standard configuration file for validation.
-// Excluding here does not reduce test coverage.
-org.apache.qpid.server.configuration.ServerConfigurationFileTest#*
-
-org.apache.qpid.test.unit.client.connection.ConnectionTest#testClientIDVerification
-org.apache.qpid.jms.xa.XAResourceTest#*
diff --git a/qpid/java/test-profiles/JavaInVMExcludes b/qpid/java/test-profiles/JavaInVMExcludes
new file mode 100644
index 0000000000..7e7da4302e
--- /dev/null
+++ b/qpid/java/test-profiles/JavaInVMExcludes
@@ -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.
+//
+
+//======================================================================
+//Exclude the following tests when running the InVM default test profile
+//======================================================================
+
+// The FirewallPlugin only operates for TCP connections, the tests NO-OP when run InVM
+org.apache.qpid.server.security.firewall.FirewallConfigTest#*
+
+// This test requires a broker capable of 0-8/9 and 0-10
+org.apache.qpid.test.client.message.JMSDestinationTest#testReceiveResend
+
+// QPID-2478 test fails when run against broker using 0-8/9
+org.apache.qpid.test.client.message.JMSDestinationTest#testGetDestinationWithCustomExchange
+
+// related to QPID-2471. Temporarily disabling these tests until I figure out why they are failing with the Java broker.
+org.apache.qpid.test.unit.ack.RecoverTest#testRecoverResendsMsgs
+org.apache.qpid.test.unit.ack.RecoverTest#testRecoverResendsMsgsAckOnEarlier
+org.apache.qpid.test.unit.ack.RecoverTest#testAcknowledgePerConsumer
+
+// related to QPID-2471. These are new test cases and fail with the Java broker.
+org.apache.qpid.test.unit.ack.RecoverTest#testOderingWithAsyncConsumer
+org.apache.qpid.test.unit.ack.RecoverTest#testOderingWithSyncConsumer
+
+//The VM broker does not export the logging management JMX MBean
+org.apache.qpid.server.security.acl.ExternalAdminACLTest#*
diff --git a/qpid/java/test-profiles/JavaPre010Excludes b/qpid/java/test-profiles/JavaPre010Excludes
deleted file mode 100644
index 5d0c82c5d7..0000000000
--- a/qpid/java/test-profiles/JavaPre010Excludes
+++ /dev/null
@@ -1,42 +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.
-//
-
-//======================================================================
-//Exclude the following from brokers using the 0-8/0-9/0-9-1 protocols
-//======================================================================
-
-// This test requires a broker capable of 0-8/0-9/0-9-1 and 0-10 concurrently
-org.apache.qpid.test.client.message.JMSDestinationTest#testReceiveResend
-
-// QPID-2478 test fails when run against broker using 0-8/9
-org.apache.qpid.test.client.message.JMSDestinationTest#testGetDestinationWithCustomExchange
-
-// The new addressing based sytanx is not supported for AMQP 0-8/0-9 versions
-org.apache.qpid.test.client.destination.AddressBasedDestinationTest#*
-org.apache.qpid.test.client.queue.QueuePolicyTest#testRingPolicy
-org.apache.qpid.test.client.queue.QueuePolicyTest#testRejectPolicy
-org.apache.qpid.test.unit.message.JMSPropertiesTest#testApplicationProperties
-
-// Those tests are written against the 0.10 path
-org.apache.qpid.test.unit.message.UTF8Test#*
-org.apache.qpid.client.MessageListenerTest#testSynchronousReceiveNoWait
-
-org.apache.qpid.test.unit.client.connection.ConnectionTest#testUnsupportedSASLMechanism
-
-org.apache.qpid.test.unit.message.JMSPropertiesTest#testQpidExtensionProperties
diff --git a/qpid/java/test-profiles/JavaStandaloneExcludes b/qpid/java/test-profiles/JavaStandaloneExcludes
new file mode 100644
index 0000000000..d208a20d15
--- /dev/null
+++ b/qpid/java/test-profiles/JavaStandaloneExcludes
@@ -0,0 +1,55 @@
+//
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+//
+
+// This is a long running test so should exclude from normal runs
+org.apache.qpid.test.client.failover.FailoverTest#test4MinuteFailover
+
+// Those tests require failover support
+org.apache.qpid.test.client.QueueBrowserAutoAckTest#testFailoverAsQueueBrowserCreated
+org.apache.qpid.test.client.QueueBrowserAutoAckTest#testFailoverWithQueueBrowser
+org.apache.qpid.test.client.QueueBrowserClientAckTest#testFailoverAsQueueBrowserCreated
+org.apache.qpid.test.client.QueueBrowserClientAckTest#testFailoverWithQueueBrowser
+org.apache.qpid.test.client.QueueBrowserDupsOkTest#testFailoverAsQueueBrowserCreated
+org.apache.qpid.test.client.QueueBrowserDupsOkTest#testFailoverWithQueueBrowser
+org.apache.qpid.test.client.QueueBrowserNoAckTest#testFailoverAsQueueBrowserCreated
+org.apache.qpid.test.client.QueueBrowserNoAckTest#testFailoverWithQueueBrowser
+org.apache.qpid.test.client.QueueBrowserPreAckTest#testFailoverAsQueueBrowserCreated
+org.apache.qpid.test.client.QueueBrowserPreAckTest#testFailoverWithQueueBrowser
+org.apache.qpid.test.client.QueueBrowserTransactedTest#testFailoverAsQueueBrowserCreated
+org.apache.qpid.test.client.QueueBrowserTransactedTest#testFailoverWithQueueBrowser
+org.apache.qpid.test.testcases.FailoverTest#*
+org.apache.qpid.test.client.failover.FailoverTest#*
+
+// InVM Broker tests awaiting resolution of QPID-1103
+org.apache.qpid.test.client.timeouts.SyncWaitDelayTest#*
+org.apache.qpid.test.client.timeouts.SyncWaitTimeoutDelayTest#*
+
+// This test currently does not pick up the runtime location of the nonVm queueBacking store.
+org.apache.qpid.test.unit.close.FlowToDiskBackingQueueDeleteTest#*
+
+// This test may use QpidTestCase but it is not using the getConnection and is hardwired to InVM
+org.apache.qpid.test.unit.client.connection.CloseAfterConnectionFailureTest#*
+
+//QPID-1818 : Client code path does not correctly restore a transacted session after failover.
+org.apache.qpid.server.persistent.NoLocalAfterRecoveryTest#*
+
+// This test requires the standard configuration file for validation.
+// Excluding here does not reduce test coverage.
+org.apache.qpid.server.configuration.ServerConfigurationFileTest#*
+
diff --git a/qpid/java/test-profiles/cpp.async.testprofile b/qpid/java/test-profiles/cpp.async.testprofile
index 5357e87687..c3d47f0ce6 100644
--- a/qpid/java/test-profiles/cpp.async.testprofile
+++ b/qpid/java/test-profiles/cpp.async.testprofile
@@ -19,5 +19,3 @@
include=cpp
profile.excludes=CPPPrefetchExcludes
broker.modules=--load-module ${broker.module.store}
-broker.persistent=true
-
diff --git a/qpid/java/test-profiles/cpp.testprofile b/qpid/java/test-profiles/cpp.testprofile
index a2114f82ba..694e22f48c 100644
--- a/qpid/java/test-profiles/cpp.testprofile
+++ b/qpid/java/test-profiles/cpp.testprofile
@@ -16,7 +16,7 @@
# specific language governing permissions and limitations
# under the License.
#
-broker.version=v0_10
+broker.version=0-10
broker.language=cpp
broker.dir=${project.root}/../cpp/src
@@ -32,8 +32,7 @@ broker.stopped=Exception constructed
broker.modules=
broker.args=
-broker.type=spawned
-broker.command=${broker.executable} -p @PORT --data-dir ${build.data}/@PORT -t --auth no --no-module-dir ${broker.modules} ${broker.args}
+broker=${broker.executable} -p @PORT --data-dir ${build.data}/@PORT -t --auth no --no-module-dir ${broker.modules} ${broker.args}
profile.excludes=CPPPrefetchExcludes CPPTransientExcludes
test.excludes=Excludes CPPExcludes ${profile}.excludes ${profile.excludes} cpp.excludes
diff --git a/qpid/java/test-profiles/default.testprofile b/qpid/java/test-profiles/default.testprofile
new file mode 100644
index 0000000000..df8148f787
--- /dev/null
+++ b/qpid/java/test-profiles/default.testprofile
@@ -0,0 +1,61 @@
+#
+# 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.
+#
+java.naming.factory.initial=org.apache.qpid.jndi.PropertiesFileInitialContextFactory
+java.naming.provider.url=${test.profiles}/test-provider.properties
+
+broker.version=0-8
+broker=vm
+broker.clean=${test.profiles}/clean-dir ${build.data} ${project.root}/build/work
+broker.ready=Listening on TCP port
+broker.start=${test.profiles}/start-broker
+broker.kill=${test.profiles}/kill-broker
+broker.config=${project.root}/build/etc/config-systests.xml
+messagestore.class.name=org.apache.qpid.server.store.MemoryMessageStore
+
+max_prefetch=1000
+qpid.dest_syntax=BURL
+
+log=debug
+amqj.logging.level=${log}
+amqj.server.logging.level=${log}
+amqj.protocol.logging.level=${log}
+root.logging.level=warn
+log4j.configuration=file:///${test.profiles}/log4j-test.xml
+log4j.debug=false
+
+# Note test-provider.properties also has variables of same name.
+# Keep in sync
+test.port=15672
+test.mport=18999
+#Note : Management will start open second port on: mport + 100 : 19099
+test.port.ssl=15671
+test.port.alt=25672
+test.port.alt.ssl=25671
+
+test.exclude=true
+profile.excludes=JavaTransientExcludes JavaInVMExcludes 08StandaloneExcludes
+test.excludes=Excludes XAExcludes JavaExcludes ${profile}.excludes ${profile.excludes}
+test.fork=no
+test.mem=512M
+test=*Test
+haltonfailure=no
+haltonerror=no
+exclude.modules=none
+
+profile.clustered=false
diff --git a/qpid/java/test-profiles/java-dby-spawn.0-10.testprofile b/qpid/java/test-profiles/java-dby-spawn.0-10.testprofile
deleted file mode 100644
index f51f5a26ac..0000000000
--- a/qpid/java/test-profiles/java-dby-spawn.0-10.testprofile
+++ /dev/null
@@ -1,30 +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.
-#
-broker.language=java
-broker.version=v0_10
-broker.type=spawned
-broker.command=${project.root}/build/bin/qpid-server -p @PORT -m @MPORT -c @CONFIG_FILE -l ${test.profiles}/log4j-test.xml
-broker.clean=${test.profiles}/clean-dir ${build.data} ${project.root}/build/work
-broker.ready=BRK-1004
-broker.stopped=Exception
-broker.config=${project.root}/build/etc/config-systests-derby.xml
-messagestore.class.name=org.apache.qpid.server.store.DerbyMessageStore
-profile.excludes=JavaPersistentExcludes Java010Excludes
-broker.clean.between.tests=true
-broker.persistent=true
diff --git a/qpid/java/test-profiles/java-dby-spawn.0-9-1.testprofile b/qpid/java/test-profiles/java-dby-spawn.0-9-1.testprofile
deleted file mode 100644
index f79e1f3aad..0000000000
--- a/qpid/java/test-profiles/java-dby-spawn.0-9-1.testprofile
+++ /dev/null
@@ -1,36 +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.
-#
-broker.version=v0_9_1
-broker.language=java
-broker.type=spawned
-broker.command=${project.root}/build/bin/qpid-server -p @PORT -m @MPORT @EXCLUDES -c @CONFIG_FILE -l ${test.profiles}/log4j-test.xml
-broker.clean=${test.profiles}/clean-dir ${build.data} ${project.root}/build/work
-broker.ready=BRK-1004
-broker.stopped=Exception
-broker.config=${project.root}/build/etc/config-systests-derby.xml
-broker.protocol.excludes=--exclude-0-10 @PORT
-messagestore.class.name=org.apache.qpid.server.store.DerbyMessageStore
-profile.excludes=JavaPersistentExcludes JavaPre010Excludes
-broker.clean.between.tests=true
-broker.persistent=true
-#
-# Do not enable. Allow client to attempt 0-10 and negotiate downwards
-#
-#qpid.amqp.version=0-91
-
diff --git a/qpid/java/test-profiles/java-dby.0-10.testprofile b/qpid/java/test-profiles/java-dby.0-10.testprofile
deleted file mode 100644
index 5a7b9b5cdc..0000000000
--- a/qpid/java/test-profiles/java-dby.0-10.testprofile
+++ /dev/null
@@ -1,30 +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.
-#
-broker.language=java
-broker.version=v0_10
-broker.type=internal
-broker.command=${project.root}/build/bin/qpid-server -p @PORT -m @MPORT -c @CONFIG_FILE -l ${test.profiles}/log4j-test.xml
-broker.clean=${test.profiles}/clean-dir ${build.data} ${project.root}/build/work
-broker.ready=BRK-1004
-broker.stopped=Exception
-broker.config=${project.root}/build/etc/config-systests-derby.xml
-messagestore.class.name=org.apache.qpid.server.store.DerbyMessageStore
-profile.excludes=JavaPersistentExcludes Java010Excludes
-broker.clean.between.tests=true
-broker.persistent=true
diff --git a/qpid/java/test-profiles/java-dby.0-9-1.testprofile b/qpid/java/test-profiles/java-dby.0-9-1.testprofile
deleted file mode 100644
index f9700da82d..0000000000
--- a/qpid/java/test-profiles/java-dby.0-9-1.testprofile
+++ /dev/null
@@ -1,36 +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.
-#
-broker.version=v0_9_1
-broker.language=java
-broker.type=internal
-broker.command=${project.root}/build/bin/qpid-server -p @PORT -m @MPORT @EXCLUDES -c @CONFIG_FILE -l ${test.profiles}/log4j-test.xml
-broker.clean=${test.profiles}/clean-dir ${build.data} ${project.root}/build/work
-broker.ready=BRK-1004
-broker.stopped=Exception
-broker.config=${project.root}/build/etc/config-systests-derby.xml
-broker.protocol.excludes=--exclude-0-10 @PORT
-messagestore.class.name=org.apache.qpid.server.store.DerbyMessageStore
-profile.excludes=JavaPersistentExcludes JavaPre010Excludes
-broker.clean.between.tests=true
-broker.persistent=true
-#
-# Do not enable. Allow client to attempt 0-10 and negotiate downwards
-#
-#qpid.amqp.version=0-91
-
diff --git a/qpid/java/test-profiles/java-derby.0.10.testprofile b/qpid/java/test-profiles/java-derby.0.10.testprofile
new file mode 100644
index 0000000000..ca9115d30d
--- /dev/null
+++ b/qpid/java/test-profiles/java-derby.0.10.testprofile
@@ -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.
+#
+broker.language=java
+broker.version=0-10
+broker=${project.root}/build/bin/qpid-server -p @PORT -m @MPORT -c @CONFIG_FILE -l ${test.profiles}/log4j-test.xml
+broker.clean=${test.profiles}/clean-dir ${build.data} ${project.root}/build/work
+broker.ready=BRK-1004
+broker.stopped=Exception
+broker.config=${project.root}/build/etc/config-systests-derby.xml
+messagestore.class.name=org.apache.qpid.server.store.DerbyMessageStore
+profile.excludes=JavaStandaloneExcludes JavaPersistentExcludes Java010Excludes
+broker.clean.between.tests=true
+broker.persistent=true
diff --git a/qpid/java/test-profiles/java-derby.testprofile b/qpid/java/test-profiles/java-derby.testprofile
new file mode 100644
index 0000000000..d22e35f07e
--- /dev/null
+++ b/qpid/java/test-profiles/java-derby.testprofile
@@ -0,0 +1,33 @@
+#
+# 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.
+#
+broker.language=java
+broker=${project.root}/build/bin/qpid-server -p @PORT -m @MPORT --exclude-0-10 @PORT -c @CONFIG_FILE -l ${test.profiles}/log4j-test.xml
+broker.clean=${test.profiles}/clean-dir ${build.data} ${project.root}/build/work
+broker.ready=BRK-1004
+broker.stopped=Exception
+broker.config=${project.root}/build/etc/config-systests-derby.xml
+messagestore.class.name=org.apache.qpid.server.store.DerbyMessageStore
+profile.excludes=JavaStandaloneExcludes JavaPersistentExcludes 08StandaloneExcludes
+broker.clean.between.tests=true
+broker.persistent=true
+#
+# Do not enable. Allow client to attempt 0-10 and negotiate downwards
+#
+#qpid.amqp.version=0-91
+
diff --git a/qpid/java/test-profiles/java-mms-spawn.0-10.testprofile b/qpid/java/test-profiles/java-mms-spawn.0-10.testprofile
deleted file mode 100644
index 4fdac783cc..0000000000
--- a/qpid/java/test-profiles/java-mms-spawn.0-10.testprofile
+++ /dev/null
@@ -1,30 +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.
-#
-broker.version=v0_10
-broker.language=java
-broker.type=spawned
-broker.command=${project.root}/build/bin/qpid-server -p @PORT -m @MPORT -c @CONFIG_FILE -l ${test.profiles}/log4j-test.xml
-broker.clean=${test.profiles}/clean-dir ${build.data} ${project.root}/build/work
-broker.ready=BRK-1004
-broker.stopped=Exception
-#
-# Do not enable. Allow client to attempt 0-10 and negotiate downwards
-#
-#qpid.amqp.version=0-10
-profile.excludes=JavaTransientExcludes Java010Excludes
diff --git a/qpid/java/test-profiles/java-mms-spawn.0-9-1.testprofile b/qpid/java/test-profiles/java-mms-spawn.0-9-1.testprofile
deleted file mode 100644
index f94b93c793..0000000000
--- a/qpid/java/test-profiles/java-mms-spawn.0-9-1.testprofile
+++ /dev/null
@@ -1,31 +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.
-#
-broker.version=v0_9_1
-broker.language=java
-broker.type=spawned
-broker.command=${project.root}/build/bin/qpid-server -p @PORT -m @MPORT @EXCLUDES -c @CONFIG_FILE -l ${test.profiles}/log4j-test.xml
-broker.clean=${test.profiles}/clean-dir ${build.data} ${project.root}/build/work
-broker.ready=BRK-1004
-broker.stopped=Exception
-broker.protocol.excludes=--exclude-0-10 @PORT
-#
-# Do not enable. Allow client to attempt 0-10 and negotiate downwards
-#
-#qpid.amqp.version=0-91
-profile.excludes=JavaTransientExcludes JavaPre010Excludes
diff --git a/qpid/java/test-profiles/java-mms.0-10.testprofile b/qpid/java/test-profiles/java-mms.0-10.testprofile
deleted file mode 100644
index 3ccc6dfd3b..0000000000
--- a/qpid/java/test-profiles/java-mms.0-10.testprofile
+++ /dev/null
@@ -1,27 +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.
-#
-broker.language=java
-broker.version=v0_10
-broker.type=internal
-broker.command=${project.root}/build/bin/qpid-server -p @PORT -m @MPORT -c @CONFIG_FILE -l ${test.profiles}/log4j-test.xml
-broker.clean=${test.profiles}/clean-dir ${build.data} ${project.root}/build/work
-broker.ready=BRK-1004
-broker.stopped=Exception
-
-profile.excludes=JavaTransientExcludes Java010Excludes
diff --git a/qpid/java/test-profiles/java-mms.0-9-1.testprofile b/qpid/java/test-profiles/java-mms.0-9-1.testprofile
deleted file mode 100644
index 45e2fc7162..0000000000
--- a/qpid/java/test-profiles/java-mms.0-9-1.testprofile
+++ /dev/null
@@ -1,32 +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.
-#
-broker.language=java
-broker.version=v0_9_1
-broker.type=internal
-#broker.command only used for the second broker during failover tests in this profile
-broker.command=${project.root}/build/bin/qpid-server -p @PORT -m @MPORT @EXCLUDES -c @CONFIG_FILE -l ${test.profiles}/log4j-test.xml
-broker.clean=${test.profiles}/clean-dir ${build.data} ${project.root}/build/work
-broker.ready=BRK-1004
-broker.stopped=Exception
-broker.protocol.excludes=--exclude-0-10 @PORT
-#
-# Do not enable. Allow client to attempt 0-10 and negotiate downwards
-#
-#qpid.amqp.version=0-91
-profile.excludes=JavaTransientExcludes JavaPre010Excludes
diff --git a/qpid/java/test-profiles/java.0.10.testprofile b/qpid/java/test-profiles/java.0.10.testprofile
new file mode 100644
index 0000000000..fa87b22e92
--- /dev/null
+++ b/qpid/java/test-profiles/java.0.10.testprofile
@@ -0,0 +1,26 @@
+#
+# 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.
+#
+broker.language=java
+broker.version=0-10
+broker=${project.root}/build/bin/qpid-server -p @PORT -m @MPORT -c @CONFIG_FILE -l ${test.profiles}/log4j-test.xml
+broker.clean=${test.profiles}/clean-dir ${build.data} ${project.root}/build/work
+broker.ready=BRK-1004
+broker.stopped=Exception
+
+profile.excludes=JavaTransientExcludes JavaStandaloneExcludes Java010Excludes
diff --git a/qpid/java/test-profiles/java.testprofile b/qpid/java/test-profiles/java.testprofile
new file mode 100644
index 0000000000..c8c776d3e1
--- /dev/null
+++ b/qpid/java/test-profiles/java.testprofile
@@ -0,0 +1,28 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+broker.language=java
+broker=${project.root}/build/bin/qpid-server -p @PORT -m @MPORT --exclude-0-10 @PORT -c @CONFIG_FILE -l ${test.profiles}/log4j-test.xml
+broker.clean=${test.profiles}/clean-dir ${build.data} ${project.root}/build/work
+broker.ready=BRK-1004
+broker.stopped=Exception
+#
+# Do not enable. Allow client to attempt 0-10 and negotiate downwards
+#
+#qpid.amqp.version=0-91
+profile.excludes=JavaTransientExcludes JavaStandaloneExcludes 08StandaloneExcludes
diff --git a/qpid/java/test-profiles/test-provider.properties b/qpid/java/test-profiles/test-provider.properties
index fe27cfcfaf..8cea012c1d 100644
--- a/qpid/java/test-profiles/test-provider.properties
+++ b/qpid/java/test-profiles/test-provider.properties
@@ -30,12 +30,16 @@ test.port.alt.ssl=25671
connectionfactory.default = amqp://username:password@clientid/test?brokerlist='tcp://localhost:${test.port}'
connectionfactory.default.ssl = amqp://username:password@clientid/test?brokerlist='tcp://localhost:${test.port.ssl}?ssl='true''
+connectionfactory.default.vm = amqp://username:password@clientid/test?brokerlist='vm://:1'
connectionfactory.failover = amqp://username:password@clientid/test?brokerlist='tcp://localhost:${test.port.alt};tcp://localhost:${test.port}'&sync_ack='true'&sync_publish='all'&failover='roundrobin?cyclecount='20''
connectionfactory.failover.ssl = amqp://username:password@clientid/test?brokerlist='tcp://localhost:${test.port.alt.ssl}?ssl='true';tcp://localhost:${test.port.ssl}?ssl='true''&sync_ack='true'&sync_publish='all'&failover='roundrobin?cyclecount='20''
+connectionfactory.failover.vm = amqp://username:password@clientid/test?brokerlist='vm://:2;vm://:1'&failover='roundrobin?cyclecount='20''
connectionfactory.connection1 = amqp://username:password@clientid/test?brokerlist='tcp://localhost:${test.port}'
connectionfactory.connection2 = amqp://username:password@clientid/test?brokerlist='tcp://localhost:${test.port.alt}'
+connectionfactory.connection1.vm = amqp://username:password@clientid/test?brokerlist='vm://:1'
+connectionfactory.connection2.vm = amqp://username:password@clientid/test?brokerlist='vm://:2'
queue.MyQueue = example.MyQueue
diff --git a/qpid/java/test-profiles/testprofile.defaults b/qpid/java/test-profiles/testprofile.defaults
deleted file mode 100644
index 35429d3fed..0000000000
--- a/qpid/java/test-profiles/testprofile.defaults
+++ /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.
-#
-java.naming.factory.initial=org.apache.qpid.jndi.PropertiesFileInitialContextFactory
-java.naming.provider.url=${test.profiles}/test-provider.properties
-
-broker.clean=${test.profiles}/clean-dir ${build.data} ${project.root}/build/work
-broker.ready=Listening on TCP port
-broker.config=${project.root}/build/etc/config-systests.xml
-messagestore.class.name=org.apache.qpid.server.store.MemoryMessageStore
-broker.protocol.excludes=
-broker.persistent=false
-
-max_prefetch=1000
-qpid.dest_syntax=BURL
-
-log=debug
-amqj.logging.level=${log}
-amqj.server.logging.level=${log}
-amqj.protocol.logging.level=${log}
-root.logging.level=warn
-log4j.configuration=file:///${test.profiles}/log4j-test.xml
-log4j.debug=false
-
-# Note test-provider.properties also has variables of same name.
-# Keep in sync
-test.port=15672
-test.mport=18999
-#Note : Management will start open second port on: mport + 100 : 19099
-test.port.ssl=15671
-test.port.alt=25672
-test.port.alt.ssl=25671
-
-test.exclude=true
-profile.excludes=
-test.excludes=Excludes XAExcludes JavaExcludes ${profile}.excludes ${profile.excludes}
-test.mem=512M
-test=*Test
-haltonfailure=no
-haltonerror=no
-exclude.modules=none
-
-profile.clustered=false
-
-
diff --git a/qpid/java/tools/bin/Profile-run-from-source b/qpid/java/tools/bin/Profile-run-from-source
deleted file mode 100755
index f8ec45ccff..0000000000
--- a/qpid/java/tools/bin/Profile-run-from-source
+++ /dev/null
@@ -1,71 +0,0 @@
-#
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License. You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied. See the License for the
-# specific language governing permissions and limitations
-# under the License.
-#
-
-# Sets the environment for running the scripts from a source checkout.
-txtbld=$(tput bold) # Bold
-txtrst=$(tput sgr0) # Reset
-txtred=$(tput setaf 1) # red
-txtgreen=$(tput setaf 2) # green
-
-echo "${txtbld}Setting the environment to run qpid java tools from a source checkout${txtrst}"
-
-abs_path()
-{
- D=`dirname "$1"`
- echo "`cd \"$D\" 2>/dev/null && pwd`"
-}
-
-export QPID_CHECKOUT=`abs_path "../../../../"`
-echo "${txtgreen}Using source checkout at $QPID_CHECKOUT${txtrst}"
-
-export PATH=$QPID_CHECKOUT/java/tools/bin:$PATH
-
-if [ "$JAVA" = "" ] ; then
- export JAVA=$(which java)
-fi
-
-#------------- Required for perf_report, qpid-bench & qpid-python-testkit ----------------
-
-export VENDOR_LIB=$QPID_CHECKOUT/java/build/lib
-export CLASSPATH=`find $VENDOR_LIB -name '*.jar' | tr '\n' ':'`
-export LOG_CONFIG="-Dlog4j.configuration=file:///$QPID_CHECKOUT/java/tools/etc/test.log4j"
-
-
-#------------- Required for qpid-python-testkit -----------------------------------------
-
-PYTHONPATH=$QPID_CHECKOUT/python/qpid:$QPID_CHECKOUT/cpp/src/test/brokertest.py:$PYTHONPATH
-export PATH=$QPID_CHECKOUT/python:$PATH
-
-if [ -x $QPID_CHECKOUT/cpp/src/qpidd ]; then
- QPIDD_EXEC=$QPID_CHECKOUT/cpp/src/qpidd
-else
- echo "${txtred}WARNING: Qpid CPP broker executable not found. You will not be able to run qpid-python-testkit${txtrst}"
-fi
-
-if [ -x $QPID_CHECKOUT/cpp/src/.libs/cluster.so ]; then
- CLUSTER_LIB=$QPID_CHECKOUT/cpp/src/.libs/cluster.so
-else
- echo "${txtred}WARNING: Qpid cluster.so not found.You will not be able to run qpid-python-testkit${txtrst}"
-fi
-
-if [ "$STORE_LIB" = "" ] ; then
- echo "${txtred}WARNING: Please point the STORE_LIB variable to the message store module. If not persistence tests will not write messages to disk.${txtrst}"
-fi
-
-export PYTHONPATH QPIDD_EXEC CLUSTER_LIB
diff --git a/qpid/java/tools/bin/check-qpid-java-env b/qpid/java/tools/bin/check-qpid-java-env
deleted file mode 100755
index dedd6e06ea..0000000000
--- a/qpid/java/tools/bin/check-qpid-java-env
+++ /dev/null
@@ -1,38 +0,0 @@
-#!/bin/bash
-#
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License. You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied. See the License for the
-# specific language governing permissions and limitations
-# under the License.
-#
-
-if [ -z "$LOG_CONFIG" ]; then
- echo "Please set the appropriate parameters for logging as it may affect performance. Ex log4j defaults to DEBUG if not configured properly"
- exit -1
-fi
-
-if [ -z "$JAVA_MEM" ]; then
- JAVA_MEM=-Xmx1024m
-fi
-
-if [ -z "$JAVA" ]; then
- echo "Please set the path to the correct java executable to JAVA"
- exit -1
-fi
-
-if [ -z "$CLASSPATH" ]; then
- echo "Please set the $CLASSPATH variable to point to the jar/class files"
- exit -1
-fi
diff --git a/qpid/java/tools/bin/controller b/qpid/java/tools/bin/controller
deleted file mode 100644
index fab8614039..0000000000
--- a/qpid/java/tools/bin/controller
+++ /dev/null
@@ -1,132 +0,0 @@
-#!/bin/sh
-#
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License. You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied. See the License for the
-# specific language governing permissions and limitations
-# under the License.
-#
-
-# This starts the controller for coordinating perf tests/
-
-. check-qpid-java-env
-
-PROGRAM_NAME=controller
-CONSUMER_COUNT=1
-PRODUCER_COUNT=1
-DURATION=-1
-TEST_NAME="TEST_NAME"
-EXTRA_JVM_ARGS=""
-
-TEMP=$(getopt -n $PROGRAM_NAME -o c:p:d:n:a:h --long consumers:,producers:,jvm-args:help -- "$@")
-
-usage()
-{
- printf "\n%s\n" "Usage: controller [option].."
-
- printf "\n%31s\n%52s\n" "-c, --consumer-count=count" "No of consumers participating in the test"
-
- printf "\n%31s\n%52s\n" "-p, --producer-count=count" "No of producers participating in the test"
-
- printf "\n%24s\n%94s\n" "-d, --duration=mins" "The duration of the test in mins. If not specified, it will just run one iteration."
-
- printf "\n%27s\n%32s\n" "-n, --name=<test-name>" "The name of the test."
-
- printf "\n%19s\n%50s\n" "-a, --jvm-args" "Extra jvm arguments you want to specify"
-}
-
-eval set -- "$TEMP"
-while true; do
- case $1 in
- -c|--consumer-count)
- CONSUMER_COUNT="$2"; shift; shift; continue
- ;;
- -p|--producer-count)
- PRODUCER_COUNT="$2"; shift; shift; continue
- ;;
- -d|--duration)
- DURATION="$2"; shift; shift; continue
- ;;
- -n|--name)
- TEST_NAME="$2"; shift; shift; continue
- ;;
- -h|--help)
- usage
- exit 0
- ;;
- -a|--jvm-args)
- EXTRA_JVM_ARGS="$2"; shift; shift; continue
- ;;
- --)
- # no more arguments to parse
- break
- ;;
- *)
- # no more arguments to parse
- break
- ;;
- esac
-done
-
-CONTROLLER_ARGS="-server -Durl=amqp://guest:guest@clientid/testpath?brokerlist='tcp://localhost:5672' -Dprecision=mili -Dprod_count=$PRODUCER_COUNT -Dcons_count=$CONSUMER_COUNT -Dprint_std_dev=true -Dduration=${DURATION}"
-
-
-waitfor() { until grep -a -l "$2" $1 >/dev/null 2>&1 ; do sleep 1 ; done ; }
-cleanup()
-{
- pids=`ps aux | grep java | grep PerfTestController | awk '{print $2}'`
- if [ "$pids" != "" ]; then
- kill -3 $pids
- kill -9 $pids >/dev/null 2>&1
- fi
-}
-
-run_controller()
-{
- TEST_ARGS="$LOG_CONFIG $JAVA_MEM $CONTROLLER_ARGS $EXTRA_JVM_ARGS"
- echo "Running controller with : $TEST_ARGS" > test.out
- $JAVA -cp $CLASSPATH $TEST_ARGS org.apache.qpid.tools.PerfTestController >> test.out &
- waitfor test.out "Controller: Completed the test"
- sleep 2 #give a grace period to shutdown
- print_result $TEST_NAME
-}
-
-print_result()
-{
- prod_rate=`cat test.out | grep "Avg Producer rate" | awk '{print $5}'`
- sys_rate=`cat test.out | grep "System Throughput" | awk '{print $4}'`
- cons_rate=`cat test.out | grep "Avg Consumer rate" | awk '{print $5}'`
- avg_latency=`cat test.out | grep "Avg System Latency" | awk '{print $5}'`
- min_latency=`cat test.out | grep "Min System Latency" | awk '{print $5}'`
- max_latency=`cat test.out | grep "Max System Latency" | awk '{print $5}'`
- std_dev=`cat test.out | grep "Avg System Std Dev" | awk '{print $6}'`
-
- printf "|%-15s|%15.2f|%13.2f|%13.2f|%11.2f|%11.2f|%11.2f|%7.2f|\n" $1 $sys_rate $prod_rate $cons_rate $avg_latency $min_latency $max_latency $std_dev
- echo "--------------------------------------------------------------------------------------------------------"
-}
-
-trap cleanup EXIT
-
-rm -rf *.out
-
-if [ "$DURATION" = -1 ]; then
- echo "Test report on " `date +%F`
- echo "========================================================================================================"
- echo "|Test |System throuput|Producer rate|Consumer Rate|Avg Latency|Min Latency|Max Latency|Std Dev|"
- echo "--------------------------------------------------------------------------------------------------------"
-else
- echo "Test in progress....Tail stats-csv.log to see results being printed for each iteration."
-fi
-
-run_controller
diff --git a/qpid/java/tools/bin/perf-report b/qpid/java/tools/bin/perf-report
deleted file mode 100755
index 7de3f2b602..0000000000
--- a/qpid/java/tools/bin/perf-report
+++ /dev/null
@@ -1,137 +0,0 @@
-#!/bin/sh
-#
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License. You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied. See the License for the
-# specific language governing permissions and limitations
-# under the License.
-#
-
-# This will run the following test cases defined below and produce
-# a report in tabular format.
-
-QUEUE="queue;{create:always,node:{x-declare:{auto-delete:true}}}"
-DURA_QUEUE="dqueue;{create:always,node:{durable:true,x-declare:{auto-delete:true}}}"
-TOPIC="amq.topic/test"
-DURA_TOPIC="amq.topic/test;{create:always,link:{durable:true}}"
-
-COMMON_CONFIG="-server -Durl=amqp://guest:guest@clientid/testpath?brokerlist='tcp://localhost:5672'"
-
-waitfor() { until grep -a -l "$2" $1 >/dev/null 2>&1 ; do sleep 1 ; done ; }
-cleanup()
-{
- pids=`ps aux | grep java | grep Perf | awk '{print $2}'`
- if [ "$pids" != "" ]; then
- kill -3 $pids
- kill -9 $pids >/dev/null 2>&1
- fi
-}
-
-# $1 test name
-# $2 consumer options
-# $3 producer options
-run_testcase()
-{
- sh run-sub $COMMON_CONFIG $2 > sub.out &
- sh run-pub $COMMON_CONFIG $3 > pub.out &
- waitfor pub.out "Controller: Completed the test"
- sleep 2 #give a grace period to shutdown
- print_result $1
- mv pub.out $1.pub.out
- mv sub.out $1.sub.out
-}
-
-print_result()
-{
- prod_rate=`cat pub.out | grep "Avg Producer rate" | awk '{print $5}'`
- sys_rate=`cat pub.out | grep "System Throughput" | awk '{print $4}'`
- cons_rate=`cat pub.out | grep "Avg Consumer rate" | awk '{print $5}'`
- avg_latency=`cat pub.out | grep "Avg System Latency" | awk '{print $5}'`
- min_latency=`cat pub.out | grep "Min System Latency" | awk '{print $5}'`
- max_latency=`cat pub.out | grep "Max System Latency" | awk '{print $5}'`
-
- printf "|%-15s|%15.2f|%13.2f|%13.2f|%11.2f|%11.2f|%11.2f|\n" $1 $sys_rate $prod_rate $cons_rate $avg_latency $min_latency $max_latency
- echo "------------------------------------------------------------------------------------------------"
-}
-
-trap cleanup EXIT
-rm -rf *.out #cleanup old files.
-
-echo "Test report on " `date +%F`
-echo "================================================================================================"
-echo "|Test |System throuput|Producer rate|Consumer Rate|Avg Latency|Min Latency|Max Latency|"
-echo "------------------------------------------------------------------------------------------------"
-
-# The message counts and warmup counts are set to very low values for quick testing of the script.
-# For a real performance run I recommend setting warmup count to 10k and message count in excess of 100k
-# However for transactions, sync_publish and especially small durable transactions (which is quite slow) I recommend
-# setting very low values to start with and experiment while increasing them slowly.
-
-# Test 1 Trans Queue
-run_testcase "Trans_Queue" "-Daddress=$QUEUE" "-Daddress=$QUEUE -Dwarmup_count=1 -Dmsg_count=10"
-
-# Test 2 Dura Queue
-run_testcase "Dura_Queue" "-Daddress=$DURA_QUEUE -Ddurable=true" "-Daddress=$DURA_QUEUE -Ddurable=true -Dwarmup_count=1 -Dmsg_count=10"
-
-# Test 3 Dura Queue Sync
-run_testcase "Dura_Queue_Sync" "-Daddress=$DURA_QUEUE -Ddurable=true" "-Daddress=$DURA_QUEUE -Ddurable=true -Dwarmup_count=1 -Dmsg_count=10 -Dsync_publish=persistent"
-
-# Test 4 Dura Queue Sync Publish and Ack
-run_testcase "Dura_SyncPubAck" "-Daddress=$DURA_QUEUE -Ddurable=true -Dsync_ack=true" "-Daddress=$DURA_QUEUE -Ddurable=true -Dwarmup_count=1 -Dmsg_count=10 -Dsync_publish=persistent"
-
-# Test 5 Topic
-run_testcase "Topic" "-Daddress=$TOPIC" "-Daddress=$TOPIC -Dwarmup_count=1 -Dmsg_count=10"
-
-# Test 6 Durable Topic
-run_testcase "Dura_Topic" "-Daddress=$DURA_TOPIC -Ddurable=true" "-Daddress=$DURA_TOPIC -Ddurable=true -Dwarmup_count=1 -Dmsg_count=10"
-
-# Test 7 Fanout
-run_testcase "Fanout" "-Daddress=amq.fanout" "-Daddress=amq.fanout -Dwarmup_count=1 -Dmsg_count=10"
-
-# Test 8 Small TX
-run_testcase "Small_Txs_2" "-Daddress=$DURA_QUEUE -Ddurable=true -Dtransacted=true -Dtrans_size=1" \
- "-Daddress=$DURA_QUEUE -Ddurable=true -Dwarmup_count=1 -Dmsg_count=10 -Dtransacted=true -Dtrans_size=1"
-
-# Test 9 Large TX
-run_testcase "Large_Txs_1000" "-Daddress=$DURA_QUEUE -Ddurable=true -Dtransacted=true -Dtrans_size=10" \
- "-Daddress=$DURA_QUEUE -Ddurable=true -Dwarmup_count=1 -Dmsg_count=10 -Dtransacted=true -Dtrans_size=10"
-
-# Test 10 256 MSG
-run_testcase "Msg_256b" "-Daddress=$QUEUE" "-Daddress=$QUEUE -Dmsg_size=256 -Dwarmup_count=1 -Dmsg_count=10"
-
-# Test 11 512 MSG
-run_testcase "Msg_512b" "-Daddress=$QUEUE" "-Daddress=$QUEUE -Dmsg_size=512 -Dwarmup_count=1 -Dmsg_count=10"
-
-# Test 12 2048 MSG
-run_testcase "Msg_2048b" "-Daddress=$QUEUE" "-Daddress=$QUEUE -Dmsg_size=2048 -Dwarmup_count=1 -Dmsg_count=10"
-
-# Test 13 Random size MSG
-run_testcase "Random_Msg_Size" "-Daddress=$QUEUE" "-Daddress=$QUEUE -Drandom_msg_size=true -Dwarmup_count=1 -Dmsg_count=10"
-
-# Test 14 Random size MSG Durable
-run_testcase "Rand_Msg_Dura" "-Daddress=$DURA_QUEUE -Ddurable=true" "-Daddress=$DURA_QUEUE -Ddurable=true -Drandom_msg_size=true -Dwarmup_count=1 -Dmsg_count=10"
-
-# Test 15 64K MSG
-run_testcase "Msg_64K" "-Daddress=$QUEUE -Damqj.tcpNoDelay=true" "-Daddress=$QUEUE -Damqj.tcpNoDelay=true -Dmsg_size=64000 -Dwarmup_count=1 -Dmsg_count=10"
-
-# Test 16 Durable 64K MSG
-run_testcase "Msg_Durable_64K" "-Daddress=$DURA_QUEUE -Ddurable=true -Damqj.tcpNoDelay=true" \
- "-Daddress=$DURA_QUEUE -Damqj.tcpNoDelay=true -Dmsg_size=64000 -Ddurable=true -Dwarmup_count=1 -Dmsg_count=10"
-
-# Test 17 500K MSG
-run_testcase "Msg_500K" "-Daddress=$QUEUE -Damqj.tcpNoDelay=true" "-Daddress=$QUEUE -Damqj.tcpNoDelay=true -Dmsg_size=500000 -Dwarmup_count=1 -Dmsg_count=10"
-
-# Test 18 Durable 500K MSG
-run_testcase "Msg_Dura_500K" "-Daddress=$DURA_QUEUE -Damqj.tcpNoDelay=true -Ddurable=true" \
- "-Daddress=$DURA_QUEUE -Damqj.tcpNoDelay=true -Dmsg_size=500000 -Ddurable=true -Dwarmup_count=1 -Dmsg_count=10"
diff --git a/qpid/java/tools/bin/perf_report.sh b/qpid/java/tools/bin/perf_report.sh
new file mode 100755
index 0000000000..e6b4c987e5
--- /dev/null
+++ b/qpid/java/tools/bin/perf_report.sh
@@ -0,0 +1,140 @@
+#!/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.
+#
+
+# This will run the 8 use cases defined below and produce
+# a report in tabular format. Refer to the documentation
+# for more details.
+
+SUB_MEM=-Xmx1024M
+PUB_MEM=-Xmx1024M
+LOG_CONFIG="-Damqj.logging.level=WARN"
+QUEUE="queue;{create:always,node:{x-declare:{auto-delete:true}}}"
+DURA_QUEUE="dqueue;{create:always,node:{durable:true,x-declare:{auto-delete:true}}}"
+TOPIC="amq.topic/test"
+DURA_TOPIC="amq.topic/test;{create:always,link:{durable:true}}"
+
+. setenv.sh
+
+waitfor() { until grep -a -l "$2" $1 >/dev/null 2>&1 ; do sleep 1 ; done ; }
+cleanup()
+{
+ pids=`ps aux | grep java | grep Perf | awk '{print $2}'`
+ if [ "$pids" != "" ]; then
+ kill -3 $pids
+ kill -9 $pids >/dev/null 2>&1
+ fi
+}
+
+# $1 test name
+# $2 consumer options
+# $3 producer options
+run_testcase()
+{
+ sh run_sub.sh $LOG_CONFIG $SUB_MEM $2 > sub.out &
+ waitfor sub.out "Warming up"
+ sh run_pub.sh $LOG_CONFIG $PUB_MEM $3 > pub.out &
+ waitfor sub.out "Completed the test"
+ waitfor pub.out "Consumer has completed the test"
+ sleep 2 #give a grace period to shutdown
+ print_result $1
+}
+
+print_result()
+{
+ prod_rate=`cat pub.out | grep "Producer rate" | awk '{print $3}'`
+ sys_rate=`cat sub.out | grep "System Throughput" | awk '{print $4}'`
+ cons_rate=`cat sub.out | grep "Consumer rate" | awk '{print $4}'`
+ avg_latency=`cat sub.out | grep "Avg Latency" | awk '{print $4}'`
+ min_latency=`cat sub.out | grep "Min Latency" | awk '{print $4}'`
+ max_latency=`cat sub.out | grep "Max Latency" | awk '{print $4}'`
+
+ printf "|%-15s|%15.2f|%13.2f|%13.2f|%11.2f|%11d|%11d|\n" $1 $sys_rate $prod_rate $cons_rate $avg_latency $min_latency $max_latency
+ echo "------------------------------------------------------------------------------------------------"
+}
+
+trap cleanup EXIT
+
+echo "Test report on " `date +%F`
+echo "================================================================================================"
+echo "|Test |System throuput|Producer rate|Consumer Rate|Avg Latency|Min Latency|Max Latency|"
+echo "------------------------------------------------------------------------------------------------"
+
+# The message counts and warmup counts are set to very low values for quick testing of the script.
+# For a real performance run I recommend setting warmup count to 10k and message count in excess of 100k
+# However for transactions, sync_publish and especially small durable transactions (which is quite slow) I recommend
+# setting very low values to start with and experiment while increasing them slowly.
+
+# Test 1 Trans Queue
+#run_testcase "Trans_Queue" "-Daddress=$QUEUE" "-Daddress=$QUEUE -Dwarmup_count=1 -Dmsg_count=10"
+
+# Test 2 Dura Queue
+run_testcase "Dura_Queue" "-Daddress=$DURA_QUEUE -Ddurable=true" "-Daddress=$DURA_QUEUE -Ddurable=true -Dwarmup_count=1 -Dmsg_count=10"
+
+# Test 3 Dura Queue Sync
+run_testcase "Dura_Queue_Sync" "-Daddress=$DURA_QUEUE -Ddurable=true" "-Daddress=$DURA_QUEUE -Ddurable=true -Dwarmup_count=1 -Dmsg_count=10 -Dsync_publish=persistent"
+
+# Test 4 Dura Queue Sync Publish and Ack
+run_testcase "Dura_SyncPubAck" "-Daddress=$DURA_QUEUE -Ddurable=true -Dsync_ack=true" "-Daddress=$DURA_QUEUE -Ddurable=true -Dwarmup_count=1 -Dmsg_count=10 -Dsync_publish=persistent"
+
+# Test 5 Topic
+run_testcase "Topic" "-Daddress=$TOPIC" "-Daddress=$TOPIC -Dwarmup_count=1 -Dmsg_count=10"
+
+# Test 6 Durable Topic
+run_testcase "Dura_Topic" "-Daddress=$DURA_TOPIC -Ddurable=true" "-Daddress=$DURA_TOPIC -Ddurable=true -Dwarmup_count=1 -Dmsg_count=10"
+
+# Test 7 Fanout
+run_testcase "Fanout" "-Daddress=amq.fanout" "-Daddress=amq.fanout -Dwarmup_count=1 -Dmsg_count=10"
+
+# Test 8 Small TX
+run_testcase "Small_Txs_2" "-Daddress=$DURA_QUEUE -Ddurable=true -Dtransacted=true -Dtrans_size=1" \
+ "-Daddress=$DURA_QUEUE -Ddurable=true -Dwarmup_count=1 -Dmsg_count=10 -Dtransacted=true -Dtrans_size=1"
+
+# Test 9 Large TX
+run_testcase "Large_Txs_1000" "-Daddress=$DURA_QUEUE -Ddurable=true -Dtransacted=true -Dtrans_size=10" \
+ "-Daddress=$DURA_QUEUE -Ddurable=true -Dwarmup_count=1 -Dmsg_count=10 -Dtransacted=true -Dtrans_size=10"
+
+# Test 10 256 MSG
+run_testcase "Msg_256b" "-Daddress=$QUEUE" "-Daddress=$QUEUE -Dmsg_size=256 -Dwarmup_count=1 -Dmsg_count=10"
+
+# Test 11 512 MSG
+run_testcase "Msg_512b" "-Daddress=$QUEUE" "-Daddress=$QUEUE -Dmsg_size=512 -Dwarmup_count=1 -Dmsg_count=10"
+
+# Test 12 2048 MSG
+run_testcase "Msg_2048b" "-Daddress=$QUEUE" "-Daddress=$QUEUE -Dmsg_size=2048 -Dwarmup_count=1 -Dmsg_count=10"
+
+# Test 13 Random size MSG
+run_testcase "Random_Msg_Size" "-Daddress=$QUEUE" "-Daddress=$QUEUE -Drandom_msg_size=true -Dwarmup_count=1 -Dmsg_count=10"
+
+# Test 14 Random size MSG Durable
+run_testcase "Rand_Msg_Dura" "-Daddress=$DURA_QUEUE -Ddurable=true" "-Daddress=$DURA_QUEUE -Ddurable=true -Drandom_msg_size=true -Dwarmup_count=1 -Dmsg_count=10"
+
+# Test 15 64K MSG
+run_testcase "Msg_64K" "-Daddress=$QUEUE -Damqj.tcpNoDelay=true" "-Daddress=$QUEUE -Damqj.tcpNoDelay=true -Dmsg_size=64000 -Dwarmup_count=1 -Dmsg_count=10"
+
+# Test 16 Durable 64K MSG
+run_testcase "Msg_Durable_64K" "-Daddress=$DURA_QUEUE -Ddurable=true -Damqj.tcpNoDelay=true" \
+ "-Daddress=$DURA_QUEUE -Damqj.tcpNoDelay=true -Dmsg_size=64000 -Ddurable=true -Dwarmup_count=1 -Dmsg_count=10"
+
+# Test 17 500K MSG
+run_testcase "Msg_500K" "-Daddress=$QUEUE -Damqj.tcpNoDelay=true" "-Daddress=$QUEUE -Damqj.tcpNoDelay=true -Dmsg_size=500000 -Dwarmup_count=1 -Dmsg_count=10"
+
+# Test 18 Durable 500K MSG
+run_testcase "Msg_Dura_500K" "-Daddress=$DURA_QUEUE -Damqj.tcpNoDelay=true -Ddurable=true" \
+ "-Daddress=$DURA_QUEUE -Damqj.tcpNoDelay=true -Dmsg_size=500000 -Ddurable=true -Dwarmup_count=1 -Dmsg_count=10"
diff --git a/qpid/java/tools/bin/qpid-bench b/qpid/java/tools/bin/qpid-bench
index cd894b607f..c982e64efd 100755..100644
--- a/qpid/java/tools/bin/qpid-bench
+++ b/qpid/java/tools/bin/qpid-bench
@@ -18,6 +18,18 @@
# under the License.
#
-. check-qpid-java-env
+if [ -z "$QPID_HOME" ]; then
+ export QPID_HOME=$(dirname $(dirname $(readlink -f $0)))
+ export PATH=${PATH}:${QPID_HOME}/bin
+fi
-$JAVA -cp $CLASSPATH -server $JAVA_MEM $LOG_CONFIG org.apache.qpid.tools.QpidBench "$@"
+# Set classpath to include Qpid jar with all required jars in manifest
+QPID_LIBS=$QPID_HOME/lib/qpid-all.jar
+
+# Set other variables used by the qpid-run script before calling
+export JAVA=java \
+ JAVA_VM=-server \
+ JAVA_MEM=-Xmx1024m \
+ QPID_CLASSPATH=$QPID_LIBS
+
+. qpid-run org.apache.qpid.tools.QpidBench "$@"
diff --git a/qpid/java/tools/bin/qpid-python-testkit b/qpid/java/tools/bin/qpid-python-testkit
index 7233d0d075..cbe7972421 100755
--- a/qpid/java/tools/bin/qpid-python-testkit
+++ b/qpid/java/tools/bin/qpid-python-testkit
@@ -22,12 +22,9 @@
# via the python test runner. The defaults are set for a running
# from an svn checkout
-. check-qpid-java-env
+. ./set-testkit-env.sh
export PYTHONPATH=./:$PYTHONPATH
-echo $PYTHONPATH
-if [ "$OUTDIR" = "" ] ; then
- OUTDIR=$PWD
-fi
-testdir=$OUTDIR/testkit-out-`date +%F-%H-%M-%S`
-qpid-python-test -m testkit -DOUTDIR=$testdir"$@"
+rm -rf $OUTDIR
+qpid-python-test -DOUTDIR=$OUTDIR -m testkit "$@"
+
diff --git a/qpid/java/tools/bin/run-pub b/qpid/java/tools/bin/run-pub
deleted file mode 100755
index 9efe58c4b8..0000000000
--- a/qpid/java/tools/bin/run-pub
+++ /dev/null
@@ -1,28 +0,0 @@
-#!/bin/sh
-#
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License. You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied. See the License for the
-# specific language governing permissions and limitations
-# under the License.
-#
-
-. check-qpid-java-env
-
-JVM_ARGS="$1"
-PROGRAM_ARGS="$2"
-
-echo "JVM ARGS : $JAVA_MEM $JVM_ARGS"
-echo "PROGRAM ARGS : $PROGRAM_ARGS"
-$JAVA -cp $CLASSPATH $LOG_CONFIG $JAVA_MEM $JVM_ARGS org.apache.qpid.tools.PerfProducer $PROGRAM_ARGS
diff --git a/qpid/java/tools/bin/run-sub b/qpid/java/tools/bin/run-sub
deleted file mode 100755
index 8449563f7f..0000000000
--- a/qpid/java/tools/bin/run-sub
+++ /dev/null
@@ -1,32 +0,0 @@
-#!/bin/sh
-#
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License. You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied. See the License for the
-# specific language governing permissions and limitations
-# under the License.
-#
-
-. check-qpid-java-env
-
-echo "All args $@"
-
-JVM_ARGS="$1"
-PROGRAM_ARGS="$2"
-
-echo "JVM ARGS : $JAVA_MEM $JVM_ARGS"
-echo "PROGRAM ARGS : $PROGRAM_ARGS"
-
-$JAVA -cp $CLASSPATH $LOG_CONFIG $JAVA_MEM $JVM_ARGS org.apache.qpid.tools.PerfConsumer $PROGRAM_ARGS
-
diff --git a/qpid/java/tools/bin/run_pub.sh b/qpid/java/tools/bin/run_pub.sh
new file mode 100644
index 0000000000..91b9287dea
--- /dev/null
+++ b/qpid/java/tools/bin/run_pub.sh
@@ -0,0 +1,24 @@
+#!/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.
+#
+
+. $QPID_TEST_HOME/bin/setenv.sh
+
+echo "$@"
+$JAVA_HOME/bin/java -cp $CLASSPATH $@ org.apache.qpid.tools.PerfProducer
diff --git a/qpid/java/tools/bin/run_sub.sh b/qpid/java/tools/bin/run_sub.sh
new file mode 100644
index 0000000000..c9ad2fed74
--- /dev/null
+++ b/qpid/java/tools/bin/run_sub.sh
@@ -0,0 +1,25 @@
+#!/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.
+#
+
+. $QPID_TEST_HOME/bin/setenv.sh
+
+echo "$@"
+$JAVA_HOME/bin/java -cp $CLASSPATH $@ org.apache.qpid.tools.PerfConsumer
+
diff --git a/qpid/java/tools/bin/set-testkit-env.sh b/qpid/java/tools/bin/set-testkit-env.sh
new file mode 100644
index 0000000000..051dad8179
--- /dev/null
+++ b/qpid/java/tools/bin/set-testkit-env.sh
@@ -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.
+#
+
+# If QPIDD_EXEC ..etc is not set, it will first check to see
+# if this is run from a qpid svn check out, if not it will look
+# for installed rpms.
+
+abs_path()
+{
+ D=`dirname "$1"`
+ B=`basename "$1"`
+ echo "`cd \"$D\" 2>/dev/null && pwd || echo \"$D\"`/$B"
+}
+
+# Environment for python tests
+
+if [ -d ../../../python ] ; then
+ PYTHON_DIR=../../../python
+ PYTHONPATH=$PYTHON_DIR:$PYTHON_DIR/qpid
+elif [ -z `echo $PYTHONPATH | awk '$0 ~ /qpid/'` ]; then
+ echo "WARNING: skipping test, no qpid python scripts found ."; exit 0;
+fi
+
+
+if [ "$QPIDD_EXEC" = "" ] ; then
+ if [ -x ../../../cpp/src/qpidd ]; then
+ QPIDD_EXEC=`abs_path "../../../cpp/src/qpidd"`
+ elif [ -n "$(which qpidd)" ] ; then
+ QPIDD_EXEC=$(which qpidd)
+ else
+ echo "WARNING: skipping test, QPIDD_EXEC not set and qpidd not found."; exit 0;
+ fi
+fi
+
+if [ "$CLUSTER_LIB" = "" ] ; then
+ if [ -x ../../../cpp/src/.libs/cluster.so ]; then
+ CLUSTER_LIB=`abs_path "../../../cpp/src/.libs/cluster.so"`
+ elif [ -e /usr/lib64/qpid/daemon/cluster.so ] ; then
+ CLUSTER_LIB="/usr/lib64/qpid/daemon/cluster.so"
+ elif [ -e /usr/lib/qpid/daemon/cluster.so ] ; then
+ CLUSTER_LIB="/usr/lib/qpid/daemon/cluster.so"
+ else
+ echo "WARNING: skipping test, CLUSTER_LIB not set and cluster.so not found."; exit 0;
+ fi
+fi
+
+if [ "$STORE_LIB" = "" ] ; then
+ if [ -e /usr/lib64/qpid/daemon/msgstore.so ] ; then
+ STORE_LIB="/usr/lib64/qpid/daemon/msgstore.so"
+ elif [ -e /usr/lib/qpid/daemon/msgstore.so ] ; then
+ STORE_LIB="/usr/lib/qpid/daemon/msgstore.so"
+ #else
+ # echo "WARNING: skipping test, STORE_LIB not set and msgstore.so not found."; exit 0;
+ fi
+fi
+
+if [ "$QP_CP" = "" ] ; then
+ if [ -d ../../build/lib/ ]; then
+ QP_JAR_PATH=`abs_path "../../build/lib/"`
+ elif [ -d /usr/share/java/qpid-deps ]; then
+ QP_JAR_PATH=`abs_path "/usr/share/java"`
+ else
+ "WARNING: skipping test, QP_CP not set and the Qpid jars are not present."; exit 0;
+ fi
+ QP_CP=`find $QP_JAR_PATH -name '*.jar' | tr '\n' ':'`
+fi
+
+if [ "$OUTDIR" = "" ] ; then
+ OUTDIR=`abs_path "./output"`
+fi
+
+export PYTHONPATH PYTHON_DIR QPIDD_EXEC CLUSTER_LIB QP_CP OUTDIR
diff --git a/qpid/java/tools/bin/setenv.sh b/qpid/java/tools/bin/setenv.sh
new file mode 100644
index 0000000000..24135e711b
--- /dev/null
+++ b/qpid/java/tools/bin/setenv.sh
@@ -0,0 +1,49 @@
+#!/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.
+#
+
+# Compiles the test classes and sets the CLASSPATH
+
+# check for QPID_TEST_HOME
+if [ "$QPID_TEST_HOME" = "" ] ; then
+ echo "ERROR: Please set QPID_TEST_HOME ...."
+ exit 1
+fi
+
+# check for JAVA_HOME
+if [ "$JAVA_HOME" = "" ] ; then
+ echo "ERROR: Please set JAVA_HOME ...."
+ exit 1
+fi
+
+# VENDOR_LIB path needs to be set
+# for Qpid set this to {qpid_checkout}/java/build/lib
+if [ "$VENDOR_LIB" = "" ] ; then
+ echo "ERROR: Please set VENDOR_LIB path in the script ...."
+ exit 1
+fi
+
+
+[ -d $QPID_TEST_HOME/classes ] || mkdir $QPID_TEST_HOME/classes
+
+CLASSPATH=`find $VENDOR_LIB -name *.jar* | tr '\n' ":"`
+$JAVA_HOME/bin/javac -cp $CLASSPATH -d $QPID_TEST_HOME/classes -sourcepath $QPID_TEST_HOME/src `find $QPID_TEST_HOME/src -name '*.java'`
+
+export CLASSPATH=$QPID_TEST_HOME/classes:$CLASSPATH
+
diff --git a/qpid/java/tools/bin/start-consumers b/qpid/java/tools/bin/start-consumers
deleted file mode 100644
index c71fc0c21f..0000000000
--- a/qpid/java/tools/bin/start-consumers
+++ /dev/null
@@ -1,119 +0,0 @@
-#!/bin/sh
-#
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License. You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied. See the License for the
-# specific language governing permissions and limitations
-# under the License.
-#
-
-# This starts the controller for coordinating perf tests/
-
-. check-qpid-java-env
-
-PROGRAM_NAME="start-consumers"
-PROCESS_COUNT=1
-CON_COUNT=1
-MSG_COUNT=10000
-ADDRESS="queue;{create:always}"
-UNIQUE_DEST="false"
-
-EXTRA_JVM_ARGS=" -Dmax_prefetch=500 "
-
-TEST_ID=`echo ${HOSTNAME} | awk -F . '{print $1}'`
-
-TEMP=$(getopt -n $PROGRAM_NAME -o C:P:uc:p:a:s:t:w:h\
- --long connection-count:,process-count:,create-unique-queues-topics,\
-jvm-args:,queue:,topic:,address:,\
-msg-count:,help -- "$@")
-
-usage()
-{
- printf "\n%s\n" "Usage: start-producers [option].."
-
- printf "\n%32s\n%51s\n" "-C, --connection-count=count" "No of consumers participating in the test"
-
- printf "\n%29s\n%51s\n" "-P, --process-count=count" "No of producers participating in the test"
-
- printf "\n%37s\n%105s\n" "-u, --create-unique-queues-topics" "This will create unique queue names and topics based on what you specify for --queue or --topic"
-
- printf "\n%11s\n%55s\n" "--queue" "The Queue you want to publish to. Ex my-queue"
-
- printf "\n%11s\n%84s\n" "--topic" "The Topic you want to publish to in amq.topic exchange. Ex amq.topic/topic"
-
- printf "\n%13s\n%44s\n" "--address" "The address you want to publish to"
-
- printf "\n%25s\n%50s\n" "-c, --msg-count=count" "message count per test (default 500,000)"
-
- printf "\n%18s\n%49s\n" "-a, --jvm-args" "Extra jvm arguments you want to specify"
-}
-
-eval set -- "$TEMP"
-while true; do
- case $1 in
- -C|--connection-count)
- CON_COUNT="$2"; shift; shift; continue
- ;;
- -P|--process-count)
- PROCESS_COUNT="$2"; shift; shift; continue
- ;;
- -u|--create-unique-queues-topics)
- UNIQUE_DEST="true"; shift; continue
- ;;
- --queue)
- ADDRESS="$2;{create: always}"; shift; shift; continue
- ;;
- --topic)
- ADDRESS="amq.topic/$2"; shift; shift; continue
- ;;
- --address)
- ADDRESS="$2"; shift; shift; continue
- ;;
- -h|--help)
- usage
- exit 0
- ;;
- -a|--jvm-args)
- EXTRA_JVM_ARGS="$2"; shift; shift; continue
- ;;
- -c|--msg-count)
- MSG_COUNT="$2"; shift; shift; continue
- ;;
- --)
- # no more arguments to parse
- break
- ;;
- *)
- # no more arguments to parse
- break
- ;;
- esac
-done
-
-CONSUMER_ARGS="-server -Durl=amqp://guest:guest@clientid/testpath?brokerlist='tcp://localhost:5672' -Dprecision=mili -Dcon_count=$CON_COUNT -Dprint_std_dev=true"
-
-start_consumers()
-{
- for ((i=0; i<$PROCESS_COUNT; i++))
- do
- if [ "$UNIQUE_DEST" = "true" ]; then
- sh run-sub "$CONSUMER_ARGS $@" "${TEST_ID}_$i" > ${TEST_ID}_$i.sub.out 2>&1 &
- else
- sh run-sub "$CONSUMER_ARGS $@" > ${TEST_ID}_$i.sub.out 2>&1 &
- fi
- done
-}
-
-start_consumers "-Daddress=$ADDRESS -Duse_unique_dest=$UNIQUE_DEST -Dmsg_count=$MSG_COUNT -Dcon_count=$CON_COUNT $EXTRA_JVM_ARGS"
-
diff --git a/qpid/java/tools/bin/start-producers b/qpid/java/tools/bin/start-producers
deleted file mode 100644
index 7ba0286f7c..0000000000
--- a/qpid/java/tools/bin/start-producers
+++ /dev/null
@@ -1,136 +0,0 @@
-#!/bin/sh
-#
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License. You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied. See the License for the
-# specific language governing permissions and limitations
-# under the License.
-#
-
-# This starts the controller for coordinating perf tests/
-
-. check-qpid-java-env
-
-PROGRAM_NAME="start-producers"
-PROCESS_COUNT=1
-CON_COUNT=1
-MSG_TYPE="bytes"
-WARMUP_MSG_COUNT=1000
-MSG_COUNT=10000
-MSG_SIZE=1024
-ADDRESS="queue;{create:always}"
-UNIQUE_DEST="false"
-
-EXTRA_JVM_ARGS=""
-TEST_ID=`echo ${HOSTNAME} | awk -F . '{print $1}'`
-
-TEMP=$(getopt -n $PROGRAM_NAME -o C:P:uc:p:a:s:t:w:h\
- --long connection-count:,process-count:,create-unique-queues-topics,\
-jvm-args:,queue:,topic:,address:,\
-msg-count:,msg-size:msg-type:,warmup-msg-count,help -- "$@")
-
-usage()
-{
- printf "\n%s\n" "Usage: start-producers [option].."
-
- printf "\n%32s\n%51s\n" "-C, --connection-count=count" "No of consumers participating in the test"
-
- printf "\n%29s\n%51s\n" "-P, --process-count=count" "No of producers participating in the test"
-
- printf "\n%37s\n%105s\n" "-u, --create-unique-queues-topics" "This will create unique queue names and topics based on what you specify for --queue or --topic"
-
- printf "\n%11s\n%55s\n" "--queue" "The Queue you want to publish to. Ex my-queue"
-
- printf "\n%11s\n%84s\n" "--topic" "The Topic you want to publish to in amq.topic exchange. Ex amq.topic/topic"
-
- printf "\n%13s\n%44s\n" "--address" "The address you want to publish to"
-
- printf "\n%23s\n%37s\n" "-s, --msg-size=size" "message size (default 1024)"
-
- printf "\n%25s\n%50s\n" "-c, --msg-count=count" "message count per test (default 500,000)"
-
- printf "\n%18s\n%38s\n" "-t, --msg-type" "{bytes|text} (default bytes)"
-
- printf "\n%26s\n%49s\n" "-w, --warmup-msg-count" "warm up message count (default 100,000)"
-
- printf "\n%18s\n%49s\n" "-a, --jvm-args" "Extra jvm arguments you want to specify"
-}
-
-eval set -- "$TEMP"
-while true; do
- case $1 in
- -C|--connection-count)
- CON_COUNT="$2"; shift; shift; continue
- ;;
- -P|--process-count)
- PROCESS_COUNT="$2"; shift; shift; continue
- ;;
- -u|--create-unique-queues-topics)
- UNIQUE_DEST="true"; shift; continue
- ;;
- --queue)
- ADDRESS="$2;{create: always}"; shift; shift; continue
- ;;
- --topic)
- ADDRESS="amq.topic/$2"; shift; shift; continue
- ;;
- --address)
- ADDRESS="$2"; shift; shift; continue
- ;;
- -h|--help)
- usage
- exit 0
- ;;
- -a|--jvm-args)
- EXTRA_JVM_ARGS="$2"; shift; shift; continue
- ;;
- -s|--msg-size)
- MSG_SIZE="$2"; shift; shift; continue
- ;;
- -c|--msg-count)
- MSG_COUNT="$2"; shift; shift; continue
- ;;
- -t|--msg_type)
- MSG_TYPE="$2"; shift; shift; continue
- ;;
- -w|--warmup-msg-count)
- WARMUP_MSG_COUNT="$2"; shift; shift; continue
- ;;
- --)
- # no more arguments to parse
- break
- ;;
- *)
- # no more arguments to parse
- break
- ;;
- esac
-done
-
-PRODUCER_ARGS="-server -Durl=amqp://guest:guest@clientid/testpath?brokerlist='tcp://localhost:5672' -Dext_controller=true -Dprecision=mili -Dcon_count=$CON_COUNT"
-
-start_producers()
-{
- for ((i=0; i<$PROCESS_COUNT; i++))
- do
- if [ "$UNIQUE_DEST" = "true" ]; then
- sh run-pub "$PRODUCER_ARGS $@" "${TEST_ID}_$i" > ${TEST_ID}_$i.pub.out 2>&1 &
- else
- sh run-pub "$PRODUCER_ARGS $@" > ${TEST_ID}_$i.pub.out 2>&1 &
- fi
- done
-}
-
-start_producers "-Daddress=$ADDRESS -Duse_unique_dest=$UNIQUE_DEST -Dmsg_count=$MSG_COUNT -Dmsg_size=$MSG_SIZE -Dwarmup_count=$WARMUP_MSG_COUNT -Dmsg_type=$MSG_TYPE -Dcon_count=$CON_COUNT $EXTRA_JVM_ARGS"
-
diff --git a/qpid/java/tools/etc/perf-report.gnu b/qpid/java/tools/etc/perf-report.gnu
deleted file mode 100644
index 6d5020efb5..0000000000
--- a/qpid/java/tools/etc/perf-report.gnu
+++ /dev/null
@@ -1,42 +0,0 @@
-set terminal png
-set datafile separator ","
-
-set title "Variation of avg latency between iterations"
-set yrange [10:20]
-set xlabel "Iterations"
-set ylabel "Latency (ms)"
-set output "avg_latency.png"
-plot "stats-csv.log" using 9 title "avg latency" with lines, 14 title "target latency" with lines
-
-
-set title "Variation of max latency between iterations"
-set yrange [0:1000]
-set xlabel "Iterations"
-set ylabel "Latency (ms)"
-set output "max_latency.png"
-plot "stats-csv.log" using 11 title "max latency" with lines,14 title "target latency" with lines,100 title "100 ms" with lines
-
-
-set title "Variation of standard deviation of latency between iterations"
-set yrange [0:20]
-set xlabel "Iterations"
-set ylabel "Standard Deviation"
-set output "std_dev_latency.png"
-plot "stats-csv.log" using 12 title "standard deviation" with lines
-
-
-set title "Variation of system throughput between iterations"
-set yrange [400000:450000]
-set xlabel "Iterations"
-set ylabel "System Throuhgput (msg/sec)"
-set output "system_rate.png"
-plot "stats-csv.log" using 2 title "system throughput" with lines
-
-
-set title "Variation of avg producer & consumer rates between iterations"
-set yrange [6500:7500]
-set xlabel "Iterations"
-set ylabel "Avg Rates (msg/sec)"
-set output "prod_cons_rate.png"
-plot "stats-csv.log" using 6 title "producer rate" with lines,"stats-csv.log" using 3 title "consumer rate" with lines
-
diff --git a/qpid/java/tools/src/main/java/org/apache/qpid/tools/Clock.java b/qpid/java/tools/src/main/java/org/apache/qpid/tools/Clock.java
deleted file mode 100644
index 37369959a8..0000000000
--- a/qpid/java/tools/src/main/java/org/apache/qpid/tools/Clock.java
+++ /dev/null
@@ -1,92 +0,0 @@
-package org.apache.qpid.tools;
-
-/**
- * In the future this will be replaced by a Clock abstraction
- * that can utilize a realtime clock when running in RT Java.
- */
-
-public class Clock
-{
- private static Precision precision;
- private static long offset = -1; // in nano secs
-
- public enum Precision
- {
- NANO_SECS, MILI_SECS;
-
- static Precision getPrecision(String str)
- {
- if ("mili".equalsIgnoreCase(str))
- {
- return MILI_SECS;
- }
- else
- {
- return NANO_SECS;
- }
- }
- };
-
- static
- {
- precision = Precision.getPrecision(System.getProperty("precision","mili"));
- //offset = Long.getLong("offset",-1);
-
- System.out.println("Using precision : " + precision + " and offset " + offset);
- }
-
- public static Precision getPrecision()
- {
- return precision;
- }
-
- public static long getTime()
- {
- if (precision == Precision.NANO_SECS)
- {
- if (offset == -1)
- {
- return System.nanoTime();
- }
- else
- {
- return System.nanoTime() + offset;
- }
- }
- else
- {
- if (offset == -1)
- {
- return System.currentTimeMillis();
- }
- else
- {
- return System.currentTimeMillis() + offset/convertToMiliSecs();
- }
- }
- }
-
- public static long convertToSecs()
- {
- if (precision == Precision.NANO_SECS)
- {
- return 1000000000;
- }
- else
- {
- return 1000;
- }
- }
-
- public static long convertToMiliSecs()
- {
- if (precision == Precision.NANO_SECS)
- {
- return 1000000;
- }
- else
- {
- return 1;
- }
- }
-}
diff --git a/qpid/java/tools/src/main/java/org/apache/qpid/tools/LatencyTest.java b/qpid/java/tools/src/main/java/org/apache/qpid/tools/LatencyTest.java
index 90ee7e28ae..b88b242e6d 100644
--- a/qpid/java/tools/src/main/java/org/apache/qpid/tools/LatencyTest.java
+++ b/qpid/java/tools/src/main/java/org/apache/qpid/tools/LatencyTest.java
@@ -77,7 +77,7 @@ public class LatencyTest extends PerfBase implements MessageListener
public LatencyTest()
{
- super("");
+ super();
warmedUp = lock.newCondition();
testCompleted = lock.newCondition();
// Storing the following two for efficiency
@@ -314,7 +314,7 @@ public class LatencyTest extends PerfBase implements MessageListener
public static void main(String[] args)
{
- final LatencyTest latencyTest = new LatencyTest();
+ final LatencyTest latencyTest = new LatencyTest();
Runnable r = new Runnable()
{
public void run()
@@ -334,16 +334,16 @@ public class LatencyTest extends PerfBase implements MessageListener
}
}
};
-
+
Thread t;
try
{
- t = Threading.getThreadFactory().createThread(r);
+ t = Threading.getThreadFactory().createThread(r);
}
catch(Exception e)
{
throw new Error("Error creating latency test thread",e);
}
- t.start();
+ t.start();
}
-}
+} \ No newline at end of file
diff --git a/qpid/java/tools/src/main/java/org/apache/qpid/tools/PerfBase.java b/qpid/java/tools/src/main/java/org/apache/qpid/tools/PerfBase.java
index 121e94cea1..ac597d17de 100644
--- a/qpid/java/tools/src/main/java/org/apache/qpid/tools/PerfBase.java
+++ b/qpid/java/tools/src/main/java/org/apache/qpid/tools/PerfBase.java
@@ -20,113 +20,36 @@
*/
package org.apache.qpid.tools;
-import java.net.InetAddress;
import java.text.DecimalFormat;
-import java.util.UUID;
+import java.util.Hashtable;
import javax.jms.Connection;
+import javax.jms.ConnectionFactory;
import javax.jms.Destination;
-import javax.jms.MapMessage;
-import javax.jms.MessageConsumer;
-import javax.jms.MessageProducer;
import javax.jms.Session;
+import javax.naming.Context;
+import javax.naming.InitialContext;
import org.apache.qpid.client.AMQAnyDestination;
import org.apache.qpid.client.AMQConnection;
-import org.apache.qpid.client.AMQDestination;
-import org.apache.qpid.client.AMQSession_0_10;
-import org.apache.qpid.framing.AMQShortString;
-import org.apache.qpid.messaging.Address;
public class PerfBase
{
- public final static String CODE = "CODE";
- public final static String ID = "ID";
- public final static String REPLY_ADDR = "REPLY_ADDR";
- public final static String MAX_LATENCY = "MAX_LATENCY";
- public final static String MIN_LATENCY = "MIN_LATENCY";
- public final static String AVG_LATENCY = "AVG_LATENCY";
- public final static String STD_DEV = "STD_DEV";
- public final static String CONS_RATE = "CONS_RATE";
- public final static String PROD_RATE = "PROD_RATE";
- public final static String MSG_COUNT = "MSG_COUNT";
- public final static String TIMESTAMP = "Timestamp";
-
- String CONTROLLER_ADDR = System.getProperty("CONT_ADDR","CONTROLLER;{create: always, node:{x-declare:{auto-delete:true}}}");
-
TestParams params;
Connection con;
Session session;
- Session controllerSession;
Destination dest;
- Destination myControlQueue;
- Destination controllerQueue;
+ Destination feedbackDest;
DecimalFormat df = new DecimalFormat("###.##");
- String id;
- String myControlQueueAddr;
-
- MessageProducer sendToController;
- MessageConsumer receiveFromController;
- String prefix = "";
- enum OPCode {
- REGISTER_CONSUMER, REGISTER_PRODUCER,
- PRODUCER_STARTWARMUP, CONSUMER_STARTWARMUP,
- CONSUMER_READY, PRODUCER_READY,
- PRODUCER_START,
- RECEIVED_END_MSG, CONSUMER_STOP,
- RECEIVED_PRODUCER_STATS, RECEIVED_CONSUMER_STATS,
- CONTINUE_TEST, STOP_TEST
- };
-
- enum MessageType {
- BYTES, TEXT, MAP, OBJECT;
-
- public static MessageType getType(String s) throws Exception
- {
- if ("text".equalsIgnoreCase(s))
- {
- return TEXT;
- }
- else if ("bytes".equalsIgnoreCase(s))
- {
- return BYTES;
- }
- /*else if ("map".equalsIgnoreCase(s))
- {
- return MAP;
- }
- else if ("object".equalsIgnoreCase(s))
- {
- return OBJECT;
- }*/
- else
- {
- throw new Exception("Unsupported message type");
- }
- }
- };
-
- MessageType msgType = MessageType.BYTES;
-
- public PerfBase(String prefix)
+ public PerfBase()
{
params = new TestParams();
- String host = "";
- try
- {
- host = InetAddress.getLocalHost().getHostName();
- }
- catch (Exception e)
- {
- }
- id = host + "-" + UUID.randomUUID().toString();
- this.prefix = prefix;
- this.myControlQueueAddr = id + ";{create: always}";
}
public void setUp() throws Exception
- {
+ {
+
if (params.getHost().equals("") || params.getPort() == -1)
{
con = new AMQConnection(params.getUrl());
@@ -139,78 +62,7 @@ public class PerfBase
session = con.createSession(params.isTransacted(),
params.isTransacted()? Session.SESSION_TRANSACTED:params.getAckMode());
- controllerSession = con.createSession(false, Session.AUTO_ACKNOWLEDGE);
-
- dest = createDestination();
- controllerQueue = new AMQAnyDestination(CONTROLLER_ADDR);
- myControlQueue = session.createQueue(myControlQueueAddr);
- msgType = MessageType.getType(params.getMessageType());
- System.out.println("Using " + msgType + " messages");
-
- sendToController = controllerSession.createProducer(controllerQueue);
- receiveFromController = controllerSession.createConsumer(myControlQueue);
- }
-
- private Destination createDestination() throws Exception
- {
- if (params.isUseUniqueDests())
- {
- System.out.println("Prefix : " + prefix);
- Address addr = Address.parse(params.getAddress());
- AMQAnyDestination temp = new AMQAnyDestination(params.getAddress());
- int type = ((AMQSession_0_10)session).resolveAddressType(temp);
-
- if ( type == AMQDestination.TOPIC_TYPE)
- {
- addr = new Address(addr.getName(),addr.getSubject() + "." + prefix,addr.getOptions());
- System.out.println("Setting subject : " + addr);
- }
- else
- {
- addr = new Address(addr.getName() + "_" + prefix,addr.getSubject(),addr.getOptions());
- System.out.println("Setting name : " + addr);
- }
-
- return new AMQAnyDestination(addr);
- }
- else
- {
- return new AMQAnyDestination(params.getAddress());
- }
- }
-
- public synchronized void sendMessageToController(MapMessage m) throws Exception
- {
- m.setString(ID, id);
- m.setString(REPLY_ADDR,myControlQueueAddr);
- sendToController.send(m);
- }
-
- public void receiveFromController(OPCode expected) throws Exception
- {
- MapMessage m = (MapMessage)receiveFromController.receive();
- OPCode code = OPCode.values()[m.getInt(CODE)];
- System.out.println("Received Code : " + code);
- if (expected != code)
- {
- throw new Exception("Expected OPCode : " + expected + " but received : " + code);
- }
-
- }
-
- public boolean continueTest() throws Exception
- {
- MapMessage m = (MapMessage)receiveFromController.receive();
- OPCode code = OPCode.values()[m.getInt(CODE)];
- System.out.println("Received Code : " + code);
- return (code == OPCode.CONTINUE_TEST);
- }
-
- public void tearDown() throws Exception
- {
- session.close();
- controllerSession.close();
- con.close();
+ dest = new AMQAnyDestination(params.getAddress());
}
public void handleError(Exception e,String msg)
diff --git a/qpid/java/tools/src/main/java/org/apache/qpid/tools/PerfConsumer.java b/qpid/java/tools/src/main/java/org/apache/qpid/tools/PerfConsumer.java
index b63892bb51..0ef0455a64 100644
--- a/qpid/java/tools/src/main/java/org/apache/qpid/tools/PerfConsumer.java
+++ b/qpid/java/tools/src/main/java/org/apache/qpid/tools/PerfConsumer.java
@@ -20,17 +20,13 @@
*/
package org.apache.qpid.tools;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.CountDownLatch;
-
-import javax.jms.MapMessage;
+import javax.jms.Destination;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.MessageListener;
+import javax.jms.MessageProducer;
import javax.jms.TextMessage;
-import org.apache.qpid.client.AMQDestination;
import org.apache.qpid.thread.Threading;
/**
@@ -51,7 +47,7 @@ import org.apache.qpid.thread.Threading;
* b) They are on separate machines that have their time synced via a Time Server
*
* In order to calculate latency the producer inserts a timestamp
- * when the message is sent. The consumer will note the current time the message is
+ * hen the message is sent. The consumer will note the current time the message is
* received and will calculate the latency as follows
* latency = rcvdTime - msg.getJMSTimestamp()
*
@@ -59,9 +55,13 @@ import org.apache.qpid.thread.Threading;
* variance in latencies.
*
* Avg latency is measured by adding all latencies and dividing by the total msgs.
+ * You can also compute this by (rcvdTime - testStartTime)/rcvdMsgCount
*
* Throughput
* ===========
+ * System throughput is calculated as follows
+ * rcvdMsgCount/(rcvdTime - testStartTime)
+ *
* Consumer rate is calculated as
* rcvdMsgCount/(rcvdTime - startTime)
*
@@ -81,160 +81,130 @@ public class PerfConsumer extends PerfBase implements MessageListener
long minLatency = Long.MAX_VALUE;
long totalLatency = 0; // to calculate avg latency.
int rcvdMsgCount = 0;
+ long testStartTime = 0; // to measure system throughput
long startTime = 0; // to measure consumer throughput
long rcvdTime = 0;
boolean transacted = false;
int transSize = 0;
- boolean printStdDev = false;
- List<Long> sample;
-
final Object lock = new Object();
- public PerfConsumer(String prefix)
+ public PerfConsumer()
{
- super(prefix);
- System.out.println("Consumer ID : " + id);
+ super();
}
public void setUp() throws Exception
{
super.setUp();
consumer = session.createConsumer(dest);
- System.out.println("Consumer: " + id + " Receiving messages from : " + ((AMQDestination)dest).getQueueName() + "\n");
// Storing the following two for efficiency
transacted = params.isTransacted();
transSize = params.getTransactionSize();
- printStdDev = params.isPrintStdDev();
- MapMessage m = controllerSession.createMapMessage();
- m.setInt(CODE, OPCode.REGISTER_CONSUMER.ordinal());
- sendMessageToController(m);
}
public void warmup()throws Exception
{
- receiveFromController(OPCode.CONSUMER_STARTWARMUP);
- Message msg = consumer.receive();
- // This is to ensure we drain the queue before we start the actual test.
- while ( msg != null)
+ System.out.println("Warming up......");
+
+ boolean start = false;
+ while (!start)
{
- if (msg.getBooleanProperty("End") == true)
+ Message msg = consumer.receive();
+ if (msg instanceof TextMessage)
{
- // It's more realistic for the consumer to signal this.
- MapMessage m = controllerSession.createMapMessage();
- m.setInt(CODE, OPCode.PRODUCER_READY.ordinal());
- sendMessageToController(m);
+ if (((TextMessage)msg).getText().equals("End"))
+ {
+ start = true;
+ MessageProducer temp = session.createProducer(msg.getJMSReplyTo());
+ temp.send(session.createMessage());
+ if (params.isTransacted())
+ {
+ session.commit();
+ }
+ temp.close();
+ }
}
- msg = consumer.receive(1000);
- }
-
- if (params.isTransacted())
- {
- session.commit();
}
-
- MapMessage m = controllerSession.createMapMessage();
- m.setInt(CODE, OPCode.CONSUMER_READY.ordinal());
- sendMessageToController(m);
- consumer.setMessageListener(this);
}
public void startTest() throws Exception
{
- System.out.println("Consumer: " + id + " Starting test......" + "\n");
- resetCounters();
+ System.out.println("Starting test......");
+ consumer.setMessageListener(this);
}
- public void resetCounters()
+ public void printResults() throws Exception
{
- rcvdMsgCount = 0;
- maxLatency = 0;
- minLatency = Long.MAX_VALUE;
- totalLatency = 0;
- if (printStdDev)
+ synchronized (lock)
{
- sample = null;
- sample = new ArrayList<Long>(params.getMsgCount());
+ lock.wait();
}
- }
-
- public void sendResults() throws Exception
- {
- receiveFromController(OPCode.CONSUMER_STOP);
double avgLatency = (double)totalLatency/(double)rcvdMsgCount;
- double consRate = (double)rcvdMsgCount*Clock.convertToSecs()/(double)(rcvdTime - startTime);
- double stdDev = 0.0;
- if (printStdDev)
- {
- stdDev = calculateStdDev(avgLatency);
- }
- MapMessage m = controllerSession.createMapMessage();
- m.setInt(CODE, OPCode.RECEIVED_CONSUMER_STATS.ordinal());
- m.setDouble(AVG_LATENCY, avgLatency/Clock.convertToMiliSecs());
- m.setDouble(MIN_LATENCY,minLatency/Clock.convertToMiliSecs());
- m.setDouble(MAX_LATENCY,maxLatency/Clock.convertToMiliSecs());
- m.setDouble(STD_DEV, stdDev/Clock.convertToMiliSecs());
- m.setDouble(CONS_RATE, consRate);
- m.setLong(MSG_COUNT, rcvdMsgCount);
- sendMessageToController(m);
-
+ double throughput = ((double)rcvdMsgCount/(double)(rcvdTime - testStartTime))*1000;
+ double consRate = ((double)rcvdMsgCount/(double)(rcvdTime - startTime))*1000;
System.out.println(new StringBuilder("Total Msgs Received : ").append(rcvdMsgCount).toString());
System.out.println(new StringBuilder("Consumer rate : ").
append(df.format(consRate)).
append(" msg/sec").toString());
+ System.out.println(new StringBuilder("System Throughput : ").
+ append(df.format(throughput)).
+ append(" msg/sec").toString());
System.out.println(new StringBuilder("Avg Latency : ").
- append(df.format(avgLatency/Clock.convertToMiliSecs())).
+ append(df.format(avgLatency)).
append(" ms").toString());
System.out.println(new StringBuilder("Min Latency : ").
- append(df.format(minLatency/Clock.convertToMiliSecs())).
+ append(minLatency).
append(" ms").toString());
System.out.println(new StringBuilder("Max Latency : ").
- append(df.format(maxLatency/Clock.convertToMiliSecs())).
+ append(maxLatency).
append(" ms").toString());
- if (printStdDev)
- {
- System.out.println(new StringBuilder("Std Dev : ").
- append(stdDev/Clock.convertToMiliSecs()).toString());
- }
+ System.out.println("Completed the test......\n");
}
- public double calculateStdDev(double mean)
+ public void notifyCompletion(Destination replyTo) throws Exception
{
- double v = 0;
- for (double latency: sample)
+ MessageProducer tmp = session.createProducer(replyTo);
+ Message endMsg = session.createMessage();
+ tmp.send(endMsg);
+ if (params.isTransacted())
{
- v = v + Math.pow((latency-mean), 2);
+ session.commit();
}
- v = v/sample.size();
- return Math.round(Math.sqrt(v));
+ tmp.close();
+ }
+
+ public void tearDown() throws Exception
+ {
+ consumer.close();
+ session.close();
+ con.close();
}
public void onMessage(Message msg)
{
try
{
- // To figure out the decoding overhead of text
- if (msgType == MessageType.TEXT)
+ if (msg instanceof TextMessage && ((TextMessage)msg).getText().equals("End"))
{
- ((TextMessage)msg).getText();
- }
+ notifyCompletion(msg.getJMSReplyTo());
- if (msg.getBooleanProperty("End"))
- {
- MapMessage m = controllerSession.createMapMessage();
- m.setInt(CODE, OPCode.RECEIVED_END_MSG.ordinal());
- sendMessageToController(m);
+ synchronized (lock)
+ {
+ lock.notifyAll();
+ }
}
else
{
- rcvdTime = Clock.getTime();
+ rcvdTime = System.currentTimeMillis();
rcvdMsgCount ++;
if (rcvdMsgCount == 1)
{
startTime = rcvdTime;
+ testStartTime = msg.getJMSTimestamp();
}
if (transacted && (rcvdMsgCount % transSize == 0))
@@ -242,14 +212,10 @@ public class PerfConsumer extends PerfBase implements MessageListener
session.commit();
}
- long latency = rcvdTime - msg.getLongProperty(TIMESTAMP);
+ long latency = rcvdTime - msg.getJMSTimestamp();
maxLatency = Math.max(maxLatency, latency);
minLatency = Math.min(minLatency, latency);
totalLatency = totalLatency + latency;
- if (printStdDev)
- {
- sample.add(latency);
- }
}
}
@@ -260,21 +226,14 @@ public class PerfConsumer extends PerfBase implements MessageListener
}
- public void run()
+ public void test()
{
try
{
setUp();
warmup();
- boolean nextIteration = true;
- while (nextIteration)
- {
- System.out.println("=========================================================\n");
- System.out.println("Consumer: " + id + " starting a new iteration ......\n");
- startTest();
- sendResults();
- nextIteration = continueTest();
- }
+ startTest();
+ printResults();
tearDown();
}
catch(Exception e)
@@ -283,43 +242,26 @@ public class PerfConsumer extends PerfBase implements MessageListener
}
}
- @Override
- public void tearDown() throws Exception
- {
- super.tearDown();
- }
-
- public static void main(String[] args) throws InterruptedException
+ public static void main(String[] args)
{
- String scriptId = (args.length == 1) ? args[0] : "";
- int conCount = Integer.getInteger("con_count",1);
- final CountDownLatch testCompleted = new CountDownLatch(conCount);
- for (int i=0; i < conCount; i++)
+ final PerfConsumer cons = new PerfConsumer();
+ Runnable r = new Runnable()
{
-
- final PerfConsumer cons = new PerfConsumer(scriptId + i);
- Runnable r = new Runnable()
- {
- public void run()
- {
- cons.run();
- testCompleted.countDown();
- }
- };
-
- Thread t;
- try
- {
- t = Threading.getThreadFactory().createThread(r);
- }
- catch(Exception e)
+ public void run()
{
- throw new Error("Error creating consumer thread",e);
+ cons.test();
}
- t.start();
-
+ };
+
+ Thread t;
+ try
+ {
+ t = Threading.getThreadFactory().createThread(r);
+ }
+ catch(Exception e)
+ {
+ throw new Error("Error creating consumer thread",e);
}
- testCompleted.await();
- System.out.println("Consumers have completed the test......\n");
+ t.start();
}
} \ No newline at end of file
diff --git a/qpid/java/tools/src/main/java/org/apache/qpid/tools/PerfProducer.java b/qpid/java/tools/src/main/java/org/apache/qpid/tools/PerfProducer.java
index ac6129ab68..015d1e6205 100644
--- a/qpid/java/tools/src/main/java/org/apache/qpid/tools/PerfProducer.java
+++ b/qpid/java/tools/src/main/java/org/apache/qpid/tools/PerfProducer.java
@@ -23,15 +23,13 @@ package org.apache.qpid.tools;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
-import java.util.concurrent.CountDownLatch;
import javax.jms.BytesMessage;
import javax.jms.DeliveryMode;
-import javax.jms.MapMessage;
import javax.jms.Message;
+import javax.jms.MessageConsumer;
import javax.jms.MessageProducer;
-import org.apache.qpid.client.AMQDestination;
import org.apache.qpid.thread.Threading;
/**
@@ -53,52 +51,38 @@ import org.apache.qpid.thread.Threading;
* System throughput and latencies calculated by the PerfConsumer are more realistic
* numbers.
*
- * Answer by rajith : I agree about in memory buffering affecting rates. But Based on test runs
- * I have done so far, it seems quite useful to compute the producer rate as it gives an
- * indication of how the system behaves. For ex if there is a gap between producer and consumer rates
- * you could clearly see the higher latencies and when producer and consumer rates are very close,
- * latency is good.
- *
*/
public class PerfProducer extends PerfBase
{
- private static long SEC = 60000;
-
MessageProducer producer;
Message msg;
- Object payload;
- List<Object> payloads;
+ byte[] payload;
+ List<byte[]> payloads;
boolean cacheMsg = false;
boolean randomMsgSize = false;
boolean durable = false;
Random random;
int msgSizeRange = 1024;
- boolean rateLimitProducer = false;
- double rateFactor = 0.4;
- double rate = 0.0;
-
- public PerfProducer(String prefix)
+
+ public PerfProducer()
{
- super(prefix);
- System.out.println("Producer ID : " + id);
+ super();
}
public void setUp() throws Exception
{
super.setUp();
- durable = params.isDurable();
- rateLimitProducer = params.getRate() > 0 ? true : false;
- if (rateLimitProducer)
- {
- System.out.println("The test will attempt to limit the producer to " + params.getRate() + " msg/sec");
- }
+ feedbackDest = session.createTemporaryQueue();
+ durable = params.isDurable();
+
// if message caching is enabled we pre create the message
// else we pre create the payload
if (params.isCacheMessage())
{
cacheMsg = true;
- msg = createMessage(createPayload(params.getMsgSize()));
+
+ msg = MessageFactory.createBytesMessage(session, params.getMsgSize());
msg.setJMSDeliveryMode(durable?
DeliveryMode.PERSISTENT :
DeliveryMode.NON_PERSISTENT
@@ -109,52 +93,21 @@ public class PerfProducer extends PerfBase
random = new Random(20080921);
randomMsgSize = true;
msgSizeRange = params.getMsgSize();
- payloads = new ArrayList<Object>(msgSizeRange);
-
+ payloads = new ArrayList<byte[]>(msgSizeRange);
+
for (int i=0; i < msgSizeRange; i++)
{
- payloads.add(createPayload(i));
+ payloads.add(MessageFactory.createMessagePayload(i).getBytes());
}
- }
+ }
else
{
- payload = createPayload(params.getMsgSize());
+ payload = MessageFactory.createMessagePayload(params.getMsgSize()).getBytes();
}
producer = session.createProducer(dest);
- System.out.println("Producer: " + id + " Sending messages to: " + ((AMQDestination)dest).getQueueName());
producer.setDisableMessageID(params.isDisableMessageID());
producer.setDisableMessageTimestamp(params.isDisableTimestamp());
-
- MapMessage m = controllerSession.createMapMessage();
- m.setInt(CODE, OPCode.REGISTER_PRODUCER.ordinal());
- sendMessageToController(m);
- }
-
- Object createPayload(int size)
- {
- if (msgType == MessageType.TEXT)
- {
- return MessageFactory.createMessagePayload(size);
- }
- else
- {
- return MessageFactory.createMessagePayload(size).getBytes();
- }
- }
-
- Message createMessage(Object payload) throws Exception
- {
- if (msgType == MessageType.TEXT)
- {
- return session.createTextMessage((String)payload);
- }
- else
- {
- BytesMessage m = session.createBytesMessage();
- m.writeBytes((byte[])payload);
- return m;
- }
}
protected Message getNextMessage() throws Exception
@@ -164,130 +117,117 @@ public class PerfProducer extends PerfBase
return msg;
}
else
- {
- Message m;
-
+ {
+ msg = session.createBytesMessage();
+
if (!randomMsgSize)
{
- m = createMessage(payload);
+ ((BytesMessage)msg).writeBytes(payload);
}
else
{
- m = createMessage(payloads.get(random.nextInt(msgSizeRange)));
+ ((BytesMessage)msg).writeBytes(payloads.get(random.nextInt(msgSizeRange)));
}
- m.setJMSDeliveryMode(durable?
+ msg.setJMSDeliveryMode(durable?
DeliveryMode.PERSISTENT :
DeliveryMode.NON_PERSISTENT
);
- return m;
+ return msg;
}
}
public void warmup()throws Exception
{
- receiveFromController(OPCode.PRODUCER_STARTWARMUP);
- System.out.println("Producer: " + id + " Warming up......");
+ System.out.println("Warming up......");
+ MessageConsumer tmp = session.createConsumer(feedbackDest);
for (int i=0; i < params.getWarmupCount() -1; i++)
{
producer.send(getNextMessage());
}
- sendEndMessage();
+ Message msg = session.createTextMessage("End");
+ msg.setJMSReplyTo(feedbackDest);
+ producer.send(msg);
+
+ if (params.isTransacted())
+ {
+ session.commit();
+ }
+
+ tmp.receive();
if (params.isTransacted())
{
session.commit();
}
+
+ tmp.close();
}
public void startTest() throws Exception
{
- resetCounters();
- receiveFromController(OPCode.PRODUCER_START);
+ System.out.println("Starting test......");
int count = params.getMsgCount();
boolean transacted = params.isTransacted();
int tranSize = params.getTransactionSize();
- long limit = (long)(params.getRate() * rateFactor); // in msecs
- long timeLimit = (long)(SEC * rateFactor); // in msecs
-
- long start = Clock.getTime(); // defaults to nano secs
- long interval = start;
+ long start = System.currentTimeMillis();
for(int i=0; i < count; i++ )
{
Message msg = getNextMessage();
- msg.setLongProperty(TIMESTAMP, Clock.getTime());
+ msg.setJMSTimestamp(System.currentTimeMillis());
producer.send(msg);
if ( transacted && ((i+1) % tranSize == 0))
{
session.commit();
}
-
- if (rateLimitProducer && i%limit == 0)
- {
- long elapsed = (Clock.getTime() - interval)*Clock.convertToMiliSecs(); // in msecs
- if (elapsed < timeLimit)
- {
- Thread.sleep(elapsed);
- }
- interval = Clock.getTime();
-
- }
- }
- sendEndMessage();
- if ( transacted)
- {
- session.commit();
}
- long time = Clock.getTime() - start;
- rate = (double)count*Clock.convertToSecs()/(double)time;
+ long time = System.currentTimeMillis() - start;
+ double rate = ((double)count/(double)time)*1000;
System.out.println(new StringBuilder("Producer rate: ").
append(df.format(rate)).
append(" msg/sec").
toString());
}
- public void resetCounters()
+ public void waitForCompletion() throws Exception
{
+ MessageConsumer tmp = session.createConsumer(feedbackDest);
+ Message msg = session.createTextMessage("End");
+ msg.setJMSReplyTo(feedbackDest);
+ producer.send(msg);
- }
+ if (params.isTransacted())
+ {
+ session.commit();
+ }
- public void sendEndMessage() throws Exception
- {
- Message msg = session.createMessage();
- msg.setBooleanProperty("End", true);
- producer.send(msg);
- }
+ tmp.receive();
- public void sendResults() throws Exception
- {
- MapMessage msg = controllerSession.createMapMessage();
- msg.setInt(CODE, OPCode.RECEIVED_PRODUCER_STATS.ordinal());
- msg.setDouble(PROD_RATE, rate);
- sendMessageToController(msg);
+ if (params.isTransacted())
+ {
+ session.commit();
+ }
+
+ tmp.close();
+ System.out.println("Consumer has completed the test......");
}
- @Override
public void tearDown() throws Exception
{
- super.tearDown();
+ producer.close();
+ session.close();
+ con.close();
}
- public void run()
+ public void test()
{
try
{
setUp();
warmup();
- boolean nextIteration = true;
- while (nextIteration)
- {
- System.out.println("=========================================================\n");
- System.out.println("Producer: " + id + " starting a new iteration ......\n");
- startTest();
- sendResults();
- nextIteration = continueTest();
- }
+ startTest();
+ waitForCompletion();
tearDown();
}
catch(Exception e)
@@ -296,63 +236,27 @@ public class PerfProducer extends PerfBase
}
}
- public void startControllerIfNeeded()
+
+ public static void main(String[] args)
{
- if (!params.isExternalController())
+ final PerfProducer prod = new PerfProducer();
+ Runnable r = new Runnable()
{
- final PerfTestController controller = new PerfTestController();
- Runnable r = new Runnable()
- {
- public void run()
- {
- controller.run();
- }
- };
-
- Thread t;
- try
+ public void run()
{
- t = Threading.getThreadFactory().createThread(r);
+ prod.test();
}
- catch(Exception e)
- {
- throw new Error("Error creating controller thread",e);
- }
- t.start();
+ };
+
+ Thread t;
+ try
+ {
+ t = Threading.getThreadFactory().createThread(r);
}
- }
-
-
- public static void main(String[] args) throws InterruptedException
- {
- String scriptId = (args.length == 1) ? args[0] : "";
- int conCount = Integer.getInteger("con_count",1);
- final CountDownLatch testCompleted = new CountDownLatch(conCount);
- for (int i=0; i < conCount; i++)
+ catch(Exception e)
{
- final PerfProducer prod = new PerfProducer(scriptId + i);
- prod.startControllerIfNeeded();
- Runnable r = new Runnable()
- {
- public void run()
- {
- prod.run();
- testCompleted.countDown();
- }
- };
-
- Thread t;
- try
- {
- t = Threading.getThreadFactory().createThread(r);
- }
- catch(Exception e)
- {
- throw new Error("Error creating producer thread",e);
- }
- t.start();
+ throw new Error("Error creating producer thread",e);
}
- testCompleted.await();
- System.out.println("Producers have completed the test......");
+ t.start();
}
} \ No newline at end of file
diff --git a/qpid/java/tools/src/main/java/org/apache/qpid/tools/PerfTestController.java b/qpid/java/tools/src/main/java/org/apache/qpid/tools/PerfTestController.java
deleted file mode 100644
index 5c98c645f4..0000000000
--- a/qpid/java/tools/src/main/java/org/apache/qpid/tools/PerfTestController.java
+++ /dev/null
@@ -1,422 +0,0 @@
-package org.apache.qpid.tools;
-
-import java.io.FileWriter;
-import java.util.Collection;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.CountDownLatch;
-
-import javax.jms.MapMessage;
-import javax.jms.Message;
-import javax.jms.MessageConsumer;
-import javax.jms.MessageListener;
-import javax.jms.MessageProducer;
-
-import org.apache.qpid.client.message.AMQPEncodedMapMessage;
-
-/**
- * The Controller coordinates a test run between a number
- * of producers and consumers, configured via -Dprod_count and -Dcons_count.
- *
- * It waits till all the producers and consumers have registered and then
- * conducts a warmup run. Once all consumers and producers have completed
- * the warmup run and is ready, it will conduct the actual test run and
- * collect all stats from the participants and calculates the system
- * throughput, the avg/min/max for producer rates, consumer rates and latency.
- *
- * These stats are then printed to std out.
- * The Controller also prints events to std out to give a running account
- * of the test run in progress. Ex registering of participants, starting warmup ..etc.
- * This allows a scripting tool to monitor the progress.
- *
- * The Controller can be run in two modes.
- * 1. A single test run (default) where it just runs until the message count specified
- * for the producers via -Dmsg_count is sent and received.
- *
- * 2. Time based, configured via -Dduration=x, where x is in mins.
- * In this mode, the Controller repeatedly cycles through the tests (after an initial
- * warmup run) until the desired time is reached. If a test run is in progress
- * and the time is up, it will allow the run the complete.
- *
- * After each iteration, the stats will be printed out in csv format to a separate log file.
- * System throughput is calculated as follows
- * totalMsgCount/(totalTestTime)
- */
-public class PerfTestController extends PerfBase implements MessageListener
-{
- enum TestMode { SINGLE_RUN, TIME_BASED };
-
- TestMode testMode = TestMode.SINGLE_RUN;
-
- long totalTestTime;
-
- private double avgSystemLatency = 0.0;
- private double minSystemLatency = Double.MAX_VALUE;
- private double maxSystemLatency = 0;
- private double avgSystemLatencyStdDev = 0.0;
-
- private double avgSystemConsRate = 0.0;
- private double maxSystemConsRate = 0.0;
- private double minSystemConsRate = Double.MAX_VALUE;
-
- private double avgSystemProdRate = 0.0;
- private double maxSystemProdRate = 0.0;
- private double minSystemProdRate = Double.MAX_VALUE;
-
- private long totalMsgCount = 0;
- private double totalSystemThroughput = 0.0;
-
- private int consumerCount = Integer.getInteger("cons_count", 1);
- private int producerCount = Integer.getInteger("prod_count", 1);
- private int duration = Integer.getInteger("duration", -1); // in mins
- private Map<String,MapMessage> consumers;
- private Map<String,MapMessage> producers;
-
- private CountDownLatch consRegistered;
- private CountDownLatch prodRegistered;
- private CountDownLatch consReady;
- private CountDownLatch prodReady;
- private CountDownLatch receivedEndMsg;
- private CountDownLatch receivedConsStats;
- private CountDownLatch receivedProdStats;
-
- private MessageConsumer consumer;
- private boolean printStdDev = false;
- FileWriter writer;
-
- public PerfTestController()
- {
- super("");
- consumers = new ConcurrentHashMap<String,MapMessage>(consumerCount);
- producers = new ConcurrentHashMap<String,MapMessage>(producerCount);
-
- consRegistered = new CountDownLatch(consumerCount);
- prodRegistered = new CountDownLatch(producerCount);
- consReady = new CountDownLatch(consumerCount);
- prodReady = new CountDownLatch(producerCount);
- printStdDev = params.isPrintStdDev();
- testMode = (duration == -1) ? TestMode.SINGLE_RUN : TestMode.TIME_BASED;
- }
-
- public void setUp() throws Exception
- {
- super.setUp();
- if (testMode == TestMode.TIME_BASED)
- {
- writer = new FileWriter("stats-csv.log");
- }
- consumer = controllerSession.createConsumer(controllerQueue);
- System.out.println("\nController: " + producerCount + " producers are expected");
- System.out.println("Controller: " + consumerCount + " consumers are expected \n");
- consumer.setMessageListener(this);
- consRegistered.await();
- prodRegistered.await();
- System.out.println("\nController: All producers and consumers have registered......\n");
- }
-
- public void warmup() throws Exception
- {
- System.out.println("Controller initiating warm up sequence......");
- sendMessageToNodes(OPCode.CONSUMER_STARTWARMUP,consumers.values());
- sendMessageToNodes(OPCode.PRODUCER_STARTWARMUP,producers.values());
- prodReady.await();
- consReady.await();
- System.out.println("\nController : All producers and consumers are ready to start the test......\n");
- }
-
- public void startTest() throws Exception
- {
- resetCounters();
- System.out.println("\nController Starting test......");
- long start = Clock.getTime();
- sendMessageToNodes(OPCode.PRODUCER_START,producers.values());
- receivedEndMsg.await();
- totalTestTime = Clock.getTime() - start;
- sendMessageToNodes(OPCode.CONSUMER_STOP,consumers.values());
- receivedProdStats.await();
- receivedConsStats.await();
- }
-
- public void resetCounters()
- {
- minSystemLatency = Double.MAX_VALUE;
- maxSystemLatency = 0;
- maxSystemConsRate = 0.0;
- minSystemConsRate = Double.MAX_VALUE;
- maxSystemProdRate = 0.0;
- minSystemProdRate = Double.MAX_VALUE;
-
- totalMsgCount = 0;
-
- receivedConsStats = new CountDownLatch(consumerCount);
- receivedProdStats = new CountDownLatch(producerCount);
- receivedEndMsg = new CountDownLatch(producerCount);
- }
-
- public void calcStats() throws Exception
- {
- double totLatency = 0.0;
- double totStdDev = 0.0;
- double totalConsRate = 0.0;
- double totalProdRate = 0.0;
-
- MapMessage conStat = null; // for error handling
- try
- {
- for (MapMessage m: consumers.values())
- {
- conStat = m;
- minSystemLatency = Math.min(minSystemLatency,m.getDouble(MIN_LATENCY));
- maxSystemLatency = Math.max(maxSystemLatency,m.getDouble(MAX_LATENCY));
- totLatency = totLatency + m.getDouble(AVG_LATENCY);
- totStdDev = totStdDev + m.getDouble(STD_DEV);
-
- minSystemConsRate = Math.min(minSystemConsRate,m.getDouble(CONS_RATE));
- maxSystemConsRate = Math.max(maxSystemConsRate,m.getDouble(CONS_RATE));
- totalConsRate = totalConsRate + m.getDouble(CONS_RATE);
-
- totalMsgCount = totalMsgCount + m.getLong(MSG_COUNT);
- }
- }
- catch(Exception e)
- {
- System.out.println("Error calculating stats from Consumer : " + conStat);
- }
-
-
- MapMessage prodStat = null; // for error handling
- try
- {
- for (MapMessage m: producers.values())
- {
- prodStat = m;
- minSystemProdRate = Math.min(minSystemProdRate,m.getDouble(PROD_RATE));
- maxSystemProdRate = Math.max(maxSystemProdRate,m.getDouble(PROD_RATE));
- totalProdRate = totalProdRate + m.getDouble(PROD_RATE);
- }
- }
- catch(Exception e)
- {
- System.out.println("Error calculating stats from Producer : " + conStat);
- }
-
- avgSystemLatency = totLatency/consumers.size();
- avgSystemLatencyStdDev = totStdDev/consumers.size();
- avgSystemConsRate = totalConsRate/consumers.size();
- avgSystemProdRate = totalProdRate/producers.size();
-
- System.out.println("Total test time : " + totalTestTime + " in " + Clock.getPrecision());
-
- totalSystemThroughput = (totalMsgCount*Clock.convertToSecs()/totalTestTime);
- }
-
- public void printResults() throws Exception
- {
- System.out.println(new StringBuilder("Total Msgs Received : ").append(totalMsgCount).toString());
- System.out.println(new StringBuilder("System Throughput : ").
- append(df.format(totalSystemThroughput)).
- append(" msg/sec").toString());
- System.out.println(new StringBuilder("Avg Consumer rate : ").
- append(df.format(avgSystemConsRate)).
- append(" msg/sec").toString());
- System.out.println(new StringBuilder("Min Consumer rate : ").
- append(df.format(minSystemConsRate)).
- append(" msg/sec").toString());
- System.out.println(new StringBuilder("Max Consumer rate : ").
- append(df.format(maxSystemConsRate)).
- append(" msg/sec").toString());
-
- System.out.println(new StringBuilder("Avg Producer rate : ").
- append(df.format(avgSystemProdRate)).
- append(" msg/sec").toString());
- System.out.println(new StringBuilder("Min Producer rate : ").
- append(df.format(minSystemProdRate)).
- append(" msg/sec").toString());
- System.out.println(new StringBuilder("Max Producer rate : ").
- append(df.format(maxSystemProdRate)).
- append(" msg/sec").toString());
-
- System.out.println(new StringBuilder("Avg System Latency : ").
- append(df.format(avgSystemLatency)).
- append(" ms").toString());
- System.out.println(new StringBuilder("Min System Latency : ").
- append(df.format(minSystemLatency)).
- append(" ms").toString());
- System.out.println(new StringBuilder("Max System Latency : ").
- append(df.format(maxSystemLatency)).
- append(" ms").toString());
- if (printStdDev)
- {
- System.out.println(new StringBuilder("Avg System Std Dev : ").
- append(avgSystemLatencyStdDev));
- }
- }
-
- private synchronized void sendMessageToNodes(OPCode code,Collection<MapMessage> nodes) throws Exception
- {
- System.out.println("\nController: Sending code " + code);
- MessageProducer tmpProd = controllerSession.createProducer(null);
- MapMessage msg = controllerSession.createMapMessage();
- msg.setInt(CODE, code.ordinal());
- for (MapMessage node : nodes)
- {
- if (node.getString(REPLY_ADDR) == null)
- {
- System.out.println("REPLY_ADDR is null " + node);
- }
- else
- {
- System.out.println("Controller: Sending " + code + " to " + node.getString(REPLY_ADDR));
- }
- tmpProd.send(controllerSession.createQueue(node.getString(REPLY_ADDR)), msg);
- }
- }
-
- public void onMessage(Message msg)
- {
- try
- {
- MapMessage m = (MapMessage)msg;
- OPCode code = OPCode.values()[m.getInt(CODE)];
-
- System.out.println("\n---------Controller Received Code : " + code);
- System.out.println("---------Data : " + ((AMQPEncodedMapMessage)m).getMap());
-
- switch (code)
- {
- case REGISTER_CONSUMER :
- if (consRegistered.getCount() == 0)
- {
- System.out.println("Warning : Expected number of consumers have already registered," +
- "ignoring extra consumer");
- break;
- }
- consumers.put(m.getString(ID),m);
- consRegistered.countDown();
- break;
-
- case REGISTER_PRODUCER :
- if (prodRegistered.getCount() == 0)
- {
- System.out.println("Warning : Expected number of producers have already registered," +
- "ignoring extra producer");
- break;
- }
- producers.put(m.getString(ID),m);
- prodRegistered.countDown();
- break;
-
- case CONSUMER_READY :
- consReady.countDown();
- break;
-
- case PRODUCER_READY :
- prodReady.countDown();
- break;
-
- case RECEIVED_END_MSG :
- receivedEndMsg.countDown();
- break;
-
- case RECEIVED_CONSUMER_STATS :
- consumers.put(m.getString(ID),m);
- receivedConsStats.countDown();
- break;
-
- case RECEIVED_PRODUCER_STATS :
- producers.put(m.getString(ID),m);
- receivedProdStats.countDown();
- break;
-
- default:
- throw new Exception("Invalid OPCode " + code);
- }
- }
- catch (Exception e)
- {
- handleError(e,"Error when receiving messages " + msg);
- }
- }
-
- public void run()
- {
- try
- {
- setUp();
- warmup();
- if (testMode == TestMode.SINGLE_RUN)
- {
- startTest();
- calcStats();
- printResults();
- }
- else
- {
- long startTime = Clock.getTime();
- long timeLimit = duration * 60 * 1000; // duration is in mins.
- boolean nextIteration = true;
- while (nextIteration)
- {
- startTest();
- calcStats();
- writeStatsToFile();
- if (Clock.getTime() - startTime < timeLimit)
- {
- sendMessageToNodes(OPCode.CONTINUE_TEST,consumers.values());
- sendMessageToNodes(OPCode.CONTINUE_TEST,producers.values());
- nextIteration = true;
- }
- else
- {
- nextIteration = false;
- }
- }
- }
- tearDown();
-
- }
- catch(Exception e)
- {
- handleError(e,"Error when running test");
- }
- }
-
- @Override
- public void tearDown() throws Exception {
- System.out.println("Controller: Completed the test......\n");
- if (testMode == TestMode.TIME_BASED)
- {
- writer.close();
- }
- sendMessageToNodes(OPCode.STOP_TEST,consumers.values());
- sendMessageToNodes(OPCode.STOP_TEST,producers.values());
- super.tearDown();
- }
-
- public void writeStatsToFile() throws Exception
- {
- writer.append(String.valueOf(totalMsgCount)).append(",");
- writer.append(df.format(totalSystemThroughput)).append(",");
- writer.append(df.format(avgSystemConsRate)).append(",");
- writer.append(df.format(minSystemConsRate)).append(",");
- writer.append(df.format(maxSystemConsRate)).append(",");
- writer.append(df.format(avgSystemProdRate)).append(",");
- writer.append(df.format(minSystemProdRate)).append(",");
- writer.append(df.format(maxSystemProdRate)).append(",");
- writer.append(df.format(avgSystemLatency)).append(",");
- writer.append(df.format(minSystemLatency)).append(",");
- writer.append(df.format(maxSystemLatency));
- if (printStdDev)
- {
- writer.append(",").append(String.valueOf(avgSystemLatencyStdDev));
- }
- writer.append("\n");
- writer.flush();
- }
-
- public static void main(String[] args)
- {
- PerfTestController controller = new PerfTestController();
- controller.run();
- }
-}
diff --git a/qpid/java/tools/src/main/java/org/apache/qpid/tools/TestParams.java b/qpid/java/tools/src/main/java/org/apache/qpid/tools/TestParams.java
index d73be0181b..89d6462a39 100644
--- a/qpid/java/tools/src/main/java/org/apache/qpid/tools/TestParams.java
+++ b/qpid/java/tools/src/main/java/org/apache/qpid/tools/TestParams.java
@@ -25,25 +25,25 @@ import javax.jms.Session;
public class TestParams
{
/*
- * By default the connection URL is used.
+ * By default the connection URL is used.
* This allows a user to easily specify a fully fledged URL any given property.
* Ex. SSL parameters
- *
+ *
* By providing a host & port allows a user to simply override the URL.
* This allows to create multiple clients in test scripts easily,
- * without having to deal with the long URL format.
+ * without having to deal with the long URL format.
*/
private String url = "amqp://guest:guest@clientid/testpath?brokerlist='tcp://localhost:5672'";
-
+
private String host = "";
-
+
private int port = -1;
private String address = "queue; {create : always}";
private int msg_size = 1024;
- private int random_msg_size_start_from = 1;
+ private int msg_type = 1; // not used yet
private boolean cacheMessage = false;
@@ -62,28 +62,19 @@ public class TestParams
private int msg_count = 10;
private int warmup_count = 1;
-
+
private boolean random_msg_size = false;
- private String msgType = "bytes";
-
- private boolean printStdDev = false;
-
- private long rate = -1;
-
- private boolean externalController = false;
-
- private boolean useUniqueDest = false; // useful when using multiple connections.
-
public TestParams()
{
-
+
url = System.getProperty("url",url);
host = System.getProperty("host","");
port = Integer.getInteger("port", -1);
- address = System.getProperty("address",address);
+ address = System.getProperty("address","queue");
msg_size = Integer.getInteger("msg_size", 1024);
+ msg_type = Integer.getInteger("msg_type",1);
cacheMessage = Boolean.getBoolean("cache_msg");
disableMessageID = Boolean.getBoolean("disableMessageID");
disableTimestamp = Boolean.getBoolean("disableTimestamp");
@@ -94,12 +85,6 @@ public class TestParams
msg_count = Integer.getInteger("msg_count",msg_count);
warmup_count = Integer.getInteger("warmup_count",warmup_count);
random_msg_size = Boolean.getBoolean("random_msg_size");
- msgType = System.getProperty("msg_type","bytes");
- printStdDev = Boolean.getBoolean("print_std_dev");
- rate = Long.getLong("rate",-1);
- externalController = Boolean.getBoolean("ext_controller");
- useUniqueDest = Boolean.getBoolean("use_unique_dest");
- random_msg_size_start_from = Integer.getInteger("random_msg_size_start_from", 1);
}
public String getUrl()
@@ -137,9 +122,9 @@ public class TestParams
return msg_size;
}
- public int getRandomMsgSizeStartFrom()
+ public int getMsgType()
{
- return random_msg_size_start_from;
+ return msg_type;
}
public boolean isDurable()
@@ -176,39 +161,10 @@ public class TestParams
{
return disableTimestamp;
}
-
+
public boolean isRandomMsgSize()
{
return random_msg_size;
}
- public String getMessageType()
- {
- return msgType;
- }
-
- public boolean isPrintStdDev()
- {
- return printStdDev;
- }
-
- public long getRate()
- {
- return rate;
- }
-
- public boolean isExternalController()
- {
- return externalController;
- }
-
- public void setAddress(String addr)
- {
- address = addr;
- }
-
- public boolean isUseUniqueDests()
- {
- return useUniqueDest;
- }
}
diff --git a/qpid/java/upload.xml b/qpid/java/upload.xml
deleted file mode 100644
index 9f2fd6819b..0000000000
--- a/qpid/java/upload.xml
+++ /dev/null
@@ -1,90 +0,0 @@
-<?xml version="1.0"?>
-<!--
- Licensed to the Apache Software Foundation (ASF) under one or more
- contributor license agreements. See the NOTICE file distributed with
- this work for additional information regarding copyright ownership.
- The ASF licenses this file to You under the Apache License, Version 2.0
- (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<project name="upload" default="upload" xmlns:ivy="antlib:org.apache.ivy.ant">
- <description>Targets for uploading releases to ASF's Nexus instance</description>
-
- <property name="nexus.organisation" value="org.apache"/>
- <property name="nexus.host" value="repository.apache.org"/>
- <property name="nexus.upload.url" value="https://repository.apache.org/service/local/staging/deploy/maven2"/>
-
- <!-- properties for downloading ivy if required -->
- <property name="ivy.jar.dir" value="lib/ivy" />
- <property name="ivy.install.version" value="2.2.0" />
- <property name="ivy.jar.file" value="${ivy.jar.dir}/ivy-${ivy.install.version}.jar" />
- <property name="ivy.repo.url" value="http://repo1.maven.org/maven2/org/apache/ivy/ivy"/>
-
- <target name="download-ivy">
- <mkdir dir="${ivy.jar.dir}"/>
- <!-- download Ivy from web site so that it can be used without any special installation -->
- <echo message="Downloading ivy..."/>
- <get src="${ivy.repo.url}/${ivy.install.version}/ivy-${ivy.install.version}.jar"
- dest="${ivy.jar.file}" usetimestamp="true"/>
- </target>
-
- <target name="load-ivy">
- <!-- Try to load Ivy from local ivy dir, in case the user has not already dropped it into
- Ant's lib dir (note that the latter copy will always take precedence). Won't
- fail so long as Ivy is in at least one of the locations. -->
- <mkdir dir="${ivy.jar.dir}"/>
- <path id="ivy.lib.path">
- <fileset dir="${ivy.jar.dir}" includes="*.jar"/>
- </path>
- <taskdef resource="org/apache/ivy/ant/antlib.xml"
- uri="antlib:org.apache.ivy.ant" classpathref="ivy.lib.path"/>
- </target>
-
- <!-- check the following properties which must be specified by the user-->
- <target name="check-props-exist" description="check that the required properties have been set">
- <fail unless="nexus.user" message="You must supply the 'nexus.user' property"/>
- <fail unless="nexus.password" message="You must supply the 'nexus.password' property"/>
- <fail unless="maven.artifact.dir" message="You must supply the 'maven.artifact.dir' property"/>
- </target>
-
- <target name="perform-nexus-upload" description="really requires the prepare-upload target to be run first">
- <ivy:configure file="ivysettings-nexus.xml"/>
- <ivy:resolve file="ivy.xml"/>
- <ivy:retrieve/>
- <ivy:deliver/>
- <ivy:publish publishivy="false" resolver="nexus"
- artifactspattern="${maven.artifact.dir}/[organisation]/[module]/[artifact]/[revision]/[artifact]-[revision](-[classifier]).[ext]"/>
- </target>
-
- <target name="upload" depends="load-ivy, check-props-exist, perform-nexus-upload"/>
-
- <target name="help" description="display detailed build documentation">
- <echo>
-Ivy can be leveraged either by installing it in the Ant lib dir yourself,
-or by running the following command in qpid/java to place it in the
-qpid/java/lib/ivy lib folder:
-
- ant -buildfile upload.xml download-ivy
-
-The publishing task should be run once the release process has otherwise
-been completed and the artifacts signed. It can be performed from the
-qpid/java directory with a command as follows:
-
- ant -buildfile upload.xml -Dnexus.user=&lt;apache_username&gt; -Dnexus.password=&lt;password&gt;
- -Dmaven.artifact.dir=&lt;path to maven repo structure from release process&gt;
-
-Note: if you are behind a proxy server it is necessary to give Ant the
-proxy settings by doing something like:
-
-export ANT_OPTS=&quot;-Dhttp.proxyHost=&lt;host&gt; -Dhttp.proxyPort=&lt;port&gt; -Dhttps.proxyHost=&lt;host&gt; -Dhttps.proxyPort=&lt;port&gt;&quot;
- </echo>
- </target>
-</project>
diff --git a/qpid/packaging/windows/INSTALL_NOTES.html b/qpid/packaging/windows/INSTALL_NOTES.html
index f8e109cb36..4aecce697a 100644
--- a/qpid/packaging/windows/INSTALL_NOTES.html
+++ b/qpid/packaging/windows/INSTALL_NOTES.html
@@ -1,11 +1,11 @@
<html>
<head>
-<title>Apache Qpid C++ 0.10 Installation Notes</title>
+<title>Apache Qpid C++ 0.9 Installation Notes</title>
</head>
<body>
-<H1>Apache Qpid C++ 0.10 Installation Notes</H1>
+<H1>Apache Qpid C++ 0.9 Installation Notes</H1>
-<p>Thank you for installing Apache Qpid version 0.10 for Windows.
+<p>Thank you for installing Apache Qpid version 0.9 for Windows.
If the requisite features were installed, you can now run a broker,
use the example programs, and design your own messaging programs while
reading the Qpid C++ API reference documentation.</p>
diff --git a/qpid/packaging/windows/installer.proj b/qpid/packaging/windows/installer.proj
index 5dc16b0bfa..7be5fda472 100644
--- a/qpid/packaging/windows/installer.proj
+++ b/qpid/packaging/windows/installer.proj
@@ -20,7 +20,7 @@
<!--
Packaging script for Apache Qpid on Windows
- Builds the C++, .NET, and WCF components, and packages those along with user
+ Builds the C++ and WCF components, and packages those along with user
documentation and the python pieces needed to generate QMF stuff.
-->
@@ -87,8 +87,7 @@
<ItemGroup>
<WcfProjects Include="$(source_root)\wcf\src\Apache\Qpid\**\*.csproj"/>
- <WcfArtifacts Include="$(source_root)\wcf\src\Apache\Qpid\Channel\bin\Release\Apache.Qpid.Channel.dll"/>
- <WcfArtifacts Include="$(source_root)\wcf\src\Apache\Qpid\Channel\bin\Release\Apache.Qpid.Interop.dll"/>
+ <WcfArtifacts Include="$(source_root)\wcf\src\Apache\Qpid\Channel\bin\Release\*.dll"/>
<WcfExamples Include="$(source_root)\wcf\samples\**\*"
Exclude="$(source_root)\wcf\samples\**\.svn\**"/>
</ItemGroup>
@@ -218,9 +217,9 @@
OutputFile="boost_dlls.wxs" />
<Candle
ToolPath="$(WixToolPath)"
- DefineConstants="qpidc_version=0.13"
+ DefineConstants="qpidc_version=0.9"
InstallerPlatform="x64"
- OutputFile="qpidc-0.13-x64.msi" />
+ OutputFile="qpidc-0.9-x64.msi" />
-->
<Exec
Command="heat dir $(staging_dir)\include\qpid -var var.qpid_headers_dir -dr QpidInclude -gg -cg group_QpidHeaders -out qpid_headers.wxs" />
@@ -230,19 +229,13 @@
<Exec
Command="heat dir $(staging_dir)\bin\boost -var var.boost_dll_dir -dr QpidBin -srd -gg -cg group_BoostDlls -sw5150 -out boost_dlls.wxs" />
<Exec
- Command="heat file $(staging_dir)\examples\README.txt -var var.examples_dir -dr INSTALLLOCATION -gg -cg group_Examples -out examples_README.wxs" />
- <Exec
- Command="heat file $(staging_dir)\examples\examples.sln -var var.examples_dir -dr INSTALLLOCATION -gg -cg group_Examples -out examples_examples.wxs" />
- <Exec
- Command="heat dir $(staging_dir)\examples\messaging -var var.examples_dir -dr INSTALLLOCATION -gg -cg group_Examples -out examples_messaging.wxs" />
- <Exec
- Command="heat dir $(staging_dir)\examples\qmf-console -var var.examples_dir -dr INSTALLLOCATION -gg -cg group_Examples -out examples_qmf-console.wxs" />
+ Command="heat dir $(staging_dir)\examples -var var.examples_dir -dr INSTALLLOCATION -gg -cg group_Examples -out examples.wxs" />
<Exec
Command="heat dir $(staging_dir)\docs\api -var var.api_docs_dir -dr QpidDoc -gg -cg group_APIDocs -out api_docs.wxs" />
<Exec
- Command="candle -dqpidc_version=0.13 -dProgramFiles=$(ProgramFiles) -dstaging_dir=$(staging_dir) -dqpid_headers_dir=$(staging_dir)\include\qpid -dboost_headers_dir=$(staging_dir)\include\boost -dboost_dll_dir=$(staging_dir)\bin\boost -dexamples_dir=$(staging_dir)\examples -dapi_docs_dir=$(staging_dir)\docs\api -ext WiXNetFxExtension qpidc.wxs qpid_headers.wxs boost_headers.wxs boost_dlls.wxs examples.wxs api_docs.wxs -arch $(Architecture)" />
+ Command="candle -dqpidc_version=0.9 -dProgramFiles=$(ProgramFiles) -dstaging_dir=$(staging_dir) -dqpid_headers_dir=$(staging_dir)\include\qpid -dboost_headers_dir=$(staging_dir)\include\boost -dboost_dll_dir=$(staging_dir)\bin\boost -dexamples_dir=$(staging_dir)\examples -dapi_docs_dir=$(staging_dir)\docs\api -ext WiXNetFxExtension qpidc.wxs qpid_headers.wxs boost_headers.wxs boost_dlls.wxs examples.wxs api_docs.wxs -arch $(Architecture)" />
<Exec
- Command="light -ext WiXNetFxExtension -ext WixUtilExtension -ext WixUIExtension -cultures:en-us -out qpidc-0.13-$(Architecture).msi qpidc.wixobj qpid_headers.wixobj boost_headers.wixobj boost_dlls.wixobj examples_README.wixobj examples_examples.wixobj examples_messaging.wixobj examples_qmf-console.wixobj api_docs.wixobj" />
+ Command="light -ext WiXNetFxExtension -ext WixUtilExtension -ext WixUIExtension -cultures:en-us -out qpidc-0.9-$(Architecture).msi qpidc.wixobj qpid_headers.wixobj boost_headers.wixobj boost_dlls.wixobj examples.wixobj api_docs.wixobj" />
</Target>
</Project>
diff --git a/qpid/python/qpid/codec010.py b/qpid/python/qpid/codec010.py
index 94a1cd4263..0846db6bf7 100644
--- a/qpid/python/qpid/codec010.py
+++ b/qpid/python/qpid/codec010.py
@@ -17,7 +17,7 @@
# under the License.
#
-import datetime, string
+import datetime
from packer import Packer
from datatypes import serial, timestamp, RangedSet, Struct, UUID
from ops import Compound, PRIMITIVE, COMPOUND
@@ -241,20 +241,15 @@ class Codec(Packer):
v = sc.read_primitive(type)
result[k] = v
return result
-
- def _write_map_elem(self, k, v):
- type = self.encoding(v)
- sc = StringCodec()
- sc.write_str8(k)
- sc.write_uint8(type.CODE)
- sc.write_primitive(type, v)
- return sc.encoded
-
def write_map(self, m):
sc = StringCodec()
if m is not None:
sc.write_uint32(len(m))
- sc.write(string.joinfields(map(self._write_map_elem, m.keys(), m.values()), ""))
+ for k, v in m.items():
+ type = self.encoding(v)
+ sc.write_str8(k)
+ sc.write_uint8(type.CODE)
+ sc.write_primitive(type, v)
self.write_vbin32(sc.encoded)
def read_array(self):
diff --git a/qpid/python/qpid/messaging/driver.py b/qpid/python/qpid/messaging/driver.py
index 7c21388213..2eb2c1863e 100644
--- a/qpid/python/qpid/messaging/driver.py
+++ b/qpid/python/qpid/messaging/driver.py
@@ -66,7 +66,7 @@ class Attachment:
# XXX
-DURABLE_DEFAULT=False
+DURABLE_DEFAULT=True
# XXX
@@ -526,7 +526,7 @@ class Driver:
rawlog.debug("OPEN[%s]: %s:%s", self.log_id, host, port)
trans = transports.TRANSPORTS.get(self.connection.transport)
if trans:
- self._transport = trans(self.connection, host, port)
+ self._transport = trans(host, port)
else:
raise ConnectError("no such transport: %s" % self.connection.transport)
if self._retrying and self._reconnect_log:
@@ -828,9 +828,8 @@ class Engine:
self._closing = True
def attach(self, ssn):
- if ssn.closed: return
sst = self._attachments.get(ssn)
- if sst is None:
+ if sst is None and not ssn.closed:
for i in xrange(0, self.channel_max):
if not self._sessions.has_key(i):
ch = i
@@ -931,7 +930,6 @@ class Engine:
def resolve_declare(self, sst, lnk, dir, action):
declare = lnk.options.get("create") in ("always", dir)
- assrt = lnk.options.get("assert") in ("always", dir)
def do_resolved(type, subtype):
err = None
if type is None:
@@ -940,12 +938,7 @@ class Engine:
else:
err = NotFound(text="no such queue: %s" % lnk.name)
else:
- if assrt:
- expected = lnk.options.get("node", {}).get("type")
- if expected and type != expected:
- err = AssertionFailed(text="expected %s, got %s" % (expected, type))
- if err is None:
- action(type, subtype)
+ action(type, subtype)
if err:
tgt = lnk.target
diff --git a/qpid/python/qpid/messaging/endpoints.py b/qpid/python/qpid/messaging/endpoints.py
index 338ac70ecf..b8101b76e6 100644
--- a/qpid/python/qpid/messaging/endpoints.py
+++ b/qpid/python/qpid/messaging/endpoints.py
@@ -158,7 +158,6 @@ class Connection(Endpoint):
self.reconnect_log = options.get("reconnect_log", True)
self.address_ttl = options.get("address_ttl", 60)
- self.tcp_nodelay = options.get("tcp_nodelay", False)
self.options = options
@@ -198,7 +197,7 @@ class Connection(Endpoint):
return result
def check_closed(self):
- if not self._connected:
+ if self.closed:
self._condition.gc()
raise ConnectionClosed()
@@ -1007,9 +1006,9 @@ class Receiver(Endpoint, object):
self.draining = True
self._wakeup()
self._ecwait(lambda: not self.draining)
- msg = self.session._get(self, timeout=0)
self._grant()
self._wakeup()
+ msg = self.session._get(self, timeout=0)
if msg is None:
raise Empty()
elif self._capacity not in (0, UNLIMITED.value):
diff --git a/qpid/python/qpid/messaging/transports.py b/qpid/python/qpid/messaging/transports.py
index 7abaae12e8..8133a45604 100644
--- a/qpid/python/qpid/messaging/transports.py
+++ b/qpid/python/qpid/messaging/transports.py
@@ -17,23 +17,18 @@
# under the License.
#
-import socket
from qpid.util import connect
TRANSPORTS = {}
-class SocketTransport:
+class tcp:
- def __init__(self, conn, host, port):
+ def __init__(self, host, port):
self.socket = connect(host, port)
- if conn.tcp_nodelay:
- self.socket.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
def fileno(self):
return self.socket.fileno()
-class tcp(SocketTransport):
-
def reading(self, reading):
return reading
@@ -57,14 +52,17 @@ try:
except ImportError:
pass
else:
- class tls(SocketTransport):
+ class tls:
- def __init__(self, conn, host, port):
- SocketTransport.__init__(self, conn, host, port)
+ def __init__(self, host, port):
+ self.socket = connect(host, port)
self.tls = wrap_socket(self.socket)
self.socket.setblocking(0)
self.state = None
+ def fileno(self):
+ return self.socket.fileno()
+
def reading(self, reading):
if self.state is None:
return reading
diff --git a/qpid/python/qpid/tests/messaging/endpoints.py b/qpid/python/qpid/tests/messaging/endpoints.py
index db5ec03df2..c303ca652a 100644
--- a/qpid/python/qpid/tests/messaging/endpoints.py
+++ b/qpid/python/qpid/tests/messaging/endpoints.py
@@ -46,10 +46,6 @@ class SetupTests(Base):
self.conn.open()
self.ping(self.conn.session())
- def testTcpNodelay(self):
- self.conn = Connection.establish(self.broker, tcp_nodelay=True)
- assert self.conn._driver._transport.socket.getsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY)
-
def testConnectError(self):
try:
# Specifying port 0 yields a bad address on Windows; port 4 is unassigned
@@ -115,8 +111,8 @@ class SetupTests(Base):
class flaky:
- def __init__(self, conn, host, port):
- self.real = real(conn, host, port)
+ def __init__(self, host, port):
+ self.real = real(host, port)
self.sent_count = 0
self.recv_count = 0
@@ -190,9 +186,6 @@ class ConnectionTests(Base):
def setup_connection(self):
return Connection.establish(self.broker, **self.connection_options())
- def testCheckClosed(self):
- assert not self.conn.check_closed()
-
def testSessionAnon(self):
ssn1 = self.conn.session()
ssn2 = self.conn.session()
@@ -255,8 +248,8 @@ class ConnectionTests(Base):
class hangable:
- def __init__(self, conn, host, port):
- self.tcp = TRANSPORTS["tcp"](conn, host, port)
+ def __init__(self, host, port):
+ self.tcp = TRANSPORTS["tcp"](host, port)
self.hung = False
def hang(self):
@@ -1186,16 +1179,6 @@ test-link-bindings-queue; {
snd.send(m)
self.drain(qrcv, expected=msgs)
- def testAssert1(self):
- try:
- snd = self.ssn.sender("amq.topic; {assert: always, node: {type: queue}}")
- assert 0, "assertion failed to trigger"
- except AssertionFailed, e:
- pass
-
- def testAssert2(self):
- snd = self.ssn.sender("amq.topic; {assert: always}")
-
NOSUCH_Q = "this-queue-should-not-exist"
UNPARSEABLE_ADDR = "name/subject; {bad options"
UNLEXABLE_ADDR = "\0x0\0x1\0x2\0x3"
diff --git a/qpid/python/setup.py b/qpid/python/setup.py
index 65cb72854f..9c04421c51 100755
--- a/qpid/python/setup.py
+++ b/qpid/python/setup.py
@@ -298,7 +298,7 @@ class install_lib(_install_lib):
return outfiles + extra
setup(name="qpid-python",
- version="0.13",
+ version="0.9",
author="Apache Qpid",
author_email="dev@qpid.apache.org",
packages=["mllib", "qpid", "qpid.messaging", "qpid.tests",
diff --git a/qpid/ruby/LICENSE.txt b/qpid/ruby/LICENSE.txt
new file mode 100755
index 0000000000..6b0b1270ff
--- /dev/null
+++ b/qpid/ruby/LICENSE.txt
@@ -0,0 +1,203 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
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/NOTICE.txt b/qpid/ruby/NOTICE.txt
new file mode 100644
index 0000000000..fff2bca45c
--- /dev/null
+++ b/qpid/ruby/NOTICE.txt
@@ -0,0 +1,19 @@
+=========================================================================
+== NOTICE file corresponding to the section 4 d of ==
+== the Apache License, Version 2.0, ==
+== in this case for the Apache Qpid distribution. ==
+=========================================================================
+
+This product includes software developed by the Apache Software Foundation
+(http://www.apache.org/).
+
+Please read the LICENSE.txt file present in the root directory of this
+distribution.
+
+
+Aside from contributions to the Apache Qpid project, this software also
+includes (binary only):
+
+ - None at this time.
+
+
diff --git a/qpid/ruby/README.txt b/qpid/ruby/README.txt
new file mode 100644
index 0000000000..330f9c6f61
--- /dev/null
+++ b/qpid/ruby/README.txt
@@ -0,0 +1,26 @@
+= Running hello-world.rb =
+
+The ruby client includes a simple hello-world example that publishes
+and consumes a message. You can find this in the examples
+directory. This example requires a running broker.
+
+You can set RUBYLIB to the directories containing the Qpid ruby
+library and the SASL extension, then run the example from the command
+line. These are found in the ./lib and ./ext/sasl subdirectories.
+
+$ export RUBYLIB=/home/me/qpid/ruby/lib:/home/me/qpid/ruby/ext/sasl
+$ ./hello-world.rb
+#<Qpid::Message:0xb761c378 @headers=[#<struct Struct::Qpid_Message_properties content_length=nil, message_id=nil, correlation_id=nil, reply_to=nil, content_type="text/plain", content_encoding=nil, user_id=nil, app_id=nil, application_headers=nil, st_type=message_properties, id=nil>, #<struct Struct::Qpid_Delivery_properties discard_unroutable=nil, immediate=nil, redelivered=nil, priority=nil, delivery_mode=nil, ttl=nil, timestamp=nil, expiration=nil, exchange="", routing_key="test-queue", resume_id=nil, resume_ttl=nil, st_type=delivery_properties, id=nil>], @body="Hello World!", @id=#<Qpid::Serial:0xb76450fc @value=0>>
+
+Alternatively, you can specify the library paths using $ ruby -I:
+
+$ ruby -I /home/me/qpid/ruby/lib:/home/me/qpid/ruby/ext/sasl hello-world.rb
+#<Qpid::Message:0xb7504a44 @headers=[#<struct Struct::Qpid_Message_properties content_length=nil, message_id=nil, correlation_id=nil, reply_to=nil, content_type="text/plain", content_encoding=nil, user_id=nil, app_id=nil, application_headers=nil, st_type=message_properties, id=nil>, #<struct Struct::Qpid_Delivery_properties discard_unroutable=nil, immediate=nil, redelivered=nil, priority=nil, delivery_mode=nil, ttl=nil, timestamp=nil, expiration=nil, exchange="", routing_key="test-queue", resume_id=nil, resume_ttl=nil, st_type=delivery_properties, id=nil>], @body="Hello World!", @id=#<Qpid::Serial:0xb752d548 @value=0>>
+
+= Running the Tests =
+
+The "tests" directory contains a collection of unit tests for the ruby
+client. These can be run from the 'ruby' directory with the Rakefile
+provided:
+
+$ rake test
diff --git a/qpid/ruby/RELEASE_NOTES b/qpid/ruby/RELEASE_NOTES
new file mode 100644
index 0000000000..90e7297e47
--- /dev/null
+++ b/qpid/ruby/RELEASE_NOTES
@@ -0,0 +1,10 @@
+Apache Qpid Ruby 0.8 Release Notes
+---------------------------------
+
+The Qpid 0.8 release of the ruby client contains support the for AMQP
+0-10 & 0-8 specifications. See:
+
+http://www.amqp.org/confluence/display/AMQP/AMQP+Specification
+
+The README file provided contains some details on installing and using
+the ruby client that is included with this distribution.
diff --git a/qpid/ruby/Rakefile b/qpid/ruby/Rakefile
new file mode 100644
index 0000000000..9b0878813d
--- /dev/null
+++ b/qpid/ruby/Rakefile
@@ -0,0 +1,116 @@
+#
+# 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.
+#
+
+# Rakefile for ruby-rpm -*- ruby -*-
+require 'rake/clean'
+require 'rake/testtask'
+require 'rake/gempackagetask'
+require 'pathname'
+
+PKG_NAME='ruby-qpid'
+PKG_VERSION='0.10.2'
+GEM_NAME='qpid'
+
+EXT_CONF="ext/sasl/extconf.rb"
+MAKEFILE="ext/sasl/Makefile"
+SASL_MODULE="ext/sasl/sasl.so"
+SASL_SRC=SASL_MODULE.gsub(/.so$/, ".c")
+
+#
+# Additional files for clean/clobber
+#
+
+CLEAN.include [ "**/*~", "lib/*/spec_cache", SASL_MODULE, "ext/**/*.o" ]
+
+CLOBBER.include [ "config.save", "ext/**/mkmf.log",
+ MAKEFILE ]
+
+file MAKEFILE => EXT_CONF do |t|
+ Dir::chdir(File::dirname(EXT_CONF)) do
+ unless sh "ruby #{File::basename(EXT_CONF)}"
+ $stderr.puts "Failed to run extconf"
+ break
+ end
+ end
+end
+
+file SASL_MODULE => [ MAKEFILE, SASL_SRC ] do |t|
+ Dir::chdir(File::dirname(EXT_CONF)) do
+ unless sh "make"
+ $stderr.puts "make failed"
+ break
+ end
+ end
+end
+desc "Build the native library and AMQP spec cache"
+task :build => :spec_cache
+
+Rake::TestTask.new(:test) do |t|
+ t.test_files = FileList['tests/*.rb'].exclude("tests/util.rb")
+ t.libs = [ 'lib', 'ext/sasl' ]
+end
+
+Rake::TestTask.new(:"test_0-8") do |t|
+ t.test_files = FileList["tests_0-8/*.rb"]
+ t.libs = [ 'lib', 'ext/sasl' ]
+end
+
+desc "Create cached versions of the AMQP specs"
+task :spec_cache => SASL_MODULE do |t|
+ pid = fork do
+ $:.insert(0, "lib", "ext/sasl")
+ require 'qpid'
+ Qpid::Spec010::load()
+ end
+ Process.wait(pid)
+end
+
+#
+# Packaging
+#
+
+PKG_FILES = FileList[
+ "LICENSE.txt", "NOTICE.txt",
+ "Rakefile", "RELEASE_NOTES",
+ "lib/**/*.rb", "lib/**/*.xml", "lib/**/*.dtd", "lib/*/spec_cache/*.rb*",
+ "tests/**/*", "examples/**", "ext/**/*.[ch]", "ext/**/MANIFEST",
+ "ext/**/extconf.rb"
+]
+
+DIST_FILES = FileList[
+ "pkg/*.tgz", "pkg/*.gem"
+]
+
+SPEC = Gem::Specification.new do |s|
+ s.name = GEM_NAME
+ s.version = PKG_VERSION
+ s.email = "dev@qpid.apache.org"
+ s.homepage = "http://cwiki.apache.org/qpid/"
+ s.summary = "Ruby client for Qpid"
+ s.files = PKG_FILES
+ s.required_ruby_version = '>= 1.8.1'
+ s.description = "Ruby client for Qpid"
+ s.extensions << 'ext/sasl/extconf.rb'
+end
+
+Rake::GemPackageTask.new(SPEC) do |pkg|
+ task pkg.package_dir => [ :spec_cache ]
+ pkg.need_tar = true
+ pkg.need_zip = true
+end
diff --git a/qpid/ruby/examples/hello-world.rb b/qpid/ruby/examples/hello-world.rb
new file mode 100755
index 0000000000..e8ef673316
--- /dev/null
+++ b/qpid/ruby/examples/hello-world.rb
@@ -0,0 +1,61 @@
+#!/usr/bin/ruby
+#
+# 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.
+#
+
+require "qpid"
+require "socket"
+
+broker = if ARGV.length > 0 then ARGV[0] else "localhost" end
+port = if ARGV.length > 1 then ARGV[1].to_i else 5672 end
+if ARGV.length > 2 then
+ puts "usage: hello-world.rb [ <broker> [ <port> ] ]"
+ exit 1
+end
+
+conn = Qpid::Connection.new(TCPSocket.new(broker, port))
+conn.start(10)
+
+ssn = conn.session("test")
+
+# create a queue
+ssn.queue_declare("test-queue")
+
+ssn.exchange_declare("test-exchange", :type => "direct")
+
+# Publish a message
+dp = ssn.delivery_properties(:routing_key => "test-queue")
+mp = ssn.message_properties(:content_type => "text/plain")
+msg = Qpid::Message.new(dp, mp, "Hello World!")
+ssn.message_transfer(:message => msg)
+
+# subscribe to a queue
+ssn.message_subscribe(:destination => "messages", :queue => "test-queue",
+ :accept_mode => ssn.message_accept_mode.none)
+incoming = ssn.incoming("messages")
+
+# start incoming message flow
+incoming.start()
+
+# grab a message from the queue
+p incoming.get(10)
+
+# cancel the subscription and close the session and connection
+ssn.message_cancel(:destination => "messages")
+ssn.close()
+conn.close()
diff --git a/qpid/ruby/examples/qmf-libvirt.rb b/qpid/ruby/examples/qmf-libvirt.rb
new file mode 100644
index 0000000000..492f4fe8d6
--- /dev/null
+++ b/qpid/ruby/examples/qmf-libvirt.rb
@@ -0,0 +1,80 @@
+#!/usr/bin/ruby
+#
+# 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.
+#
+
+require "qpid"
+
+s = Qpid::Qmf::Session.new()
+b = s.add_broker("amqp://localhost:5672")
+
+while true:
+ nodes = s.objects(:class => "node")
+ nodes.each do |node|
+ puts "node: #{node.hostname}"
+ for (key, val) in node.properties
+ puts " property: #{key}, #{val}"
+ end
+
+ # Find any domains that on the current node.
+ domains = s.objects(:class => "domain", 'node' => node.object_id)
+ domains.each do |domain|
+ r = domain.getXMLDesc()
+ puts "status: #{r.status}"
+ if r.status == 0
+ puts "xml description: #{r.description}"
+ puts "length: #{r.description.length}"
+ end
+
+ puts " domain: #{domain.name}, state: #{domain.state}, id: #{domain.id}"
+ for (key, val) in domain.properties
+ puts " property: #{key}, #{val}"
+ end
+ end
+
+ pools = s.objects(:class => "pool", 'node' => node.object_id)
+ pools.each do |pool|
+ puts " pool: #{pool.name}"
+ for (key, val) in pool.properties
+ puts " property: #{key}, #{val}"
+ end
+
+ r = pool.getXMLDesc()
+ puts "status: #{r.status}"
+ puts "text: #{r.text}"
+ if r.status == 0
+ puts "xml description: #{r.description}"
+ puts "length: #{r.description.length}"
+ end
+
+ # Find volumes that are part of the pool.
+ volumes = s.objects(:class => "volume", 'pool' => pool.object_id)
+ volumes.each do |volume|
+ puts " volume: #{volume.name}"
+ for (key, val) in volume.properties
+ puts " property: #{key}, #{val}"
+ end
+ end
+ end
+
+ end
+
+ puts '----------------------------'
+ sleep(5)
+
+end
diff --git a/qpid/ruby/ext/sasl/extconf.rb b/qpid/ruby/ext/sasl/extconf.rb
new file mode 100644
index 0000000000..56841f34e3
--- /dev/null
+++ b/qpid/ruby/ext/sasl/extconf.rb
@@ -0,0 +1,28 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+require 'mkmf'
+
+extension_name = 'sasl'
+have_library("c", "main")
+
+unless have_library("sasl2")
+ raise "Package cyrus-sasl-devel not found"
+end
+
+create_makefile(extension_name)
diff --git a/qpid/ruby/ext/sasl/sasl.c b/qpid/ruby/ext/sasl/sasl.c
new file mode 100644
index 0000000000..2d4e40d30e
--- /dev/null
+++ b/qpid/ruby/ext/sasl/sasl.c
@@ -0,0 +1,472 @@
+/*
+ * 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 <stdio.h>
+#include <unistd.h>
+#include <malloc.h>
+#include <string.h>
+#include <sasl/sasl.h>
+#include <ruby.h>
+
+static VALUE mSasl;
+
+#define INPUT_SIZE 512
+#define MECH_SIZE 32
+
+typedef void* sasl_context_t;
+
+#define QSASL_OK 0
+#define QSASL_CONTINUE 1
+#define QSASL_FAILED 2
+
+typedef struct {
+ char magic[8];
+ sasl_conn_t* conn;
+ sasl_callback_t callbacks[8];
+ char* userName;
+ char* password;
+ char* operUserName;
+ unsigned int minSsf;
+ unsigned int maxSsf;
+ char mechanism[MECH_SIZE];
+ char input[INPUT_SIZE];
+} context_t;
+
+//
+// Resolve forward references
+//
+static VALUE qsasl_free(int, VALUE*, VALUE);
+
+//
+// Validate an input string to ensure that it is either NULL or of reasonable size.
+//
+static int qsasl_valid(char* str)
+{
+ int idx;
+
+ if (str == 0)
+ return 1;
+
+ for (idx = 0; idx < INPUT_SIZE; idx++) {
+ if (str[idx] == '\0')
+ return 1;
+ }
+
+ return 0;
+}
+
+//
+// SASL callback for identity and authentication identity.
+//
+static int qsasl_cb_user(void* _context, int id, const char **result, unsigned *len)
+{
+ context_t* context = (context_t*) _context;
+
+ if (context->userName)
+ *result = context->userName;
+
+ return SASL_OK;
+}
+
+//
+// SASL callback for passwords.
+//
+static int qsasl_cb_password(sasl_conn_t* conn, void* _context, int id, sasl_secret_t **psecret)
+{
+ context_t* context = (context_t*) _context;
+ sasl_secret_t* secret;
+ size_t length;
+
+ if (context->password)
+ length = strlen(context->password);
+ else
+ length = 0;
+
+ secret = (sasl_secret_t*) malloc(sizeof(sasl_secret_t) + length);
+ secret->len = length;
+ if (length)
+ memcpy(secret->data, context->password, length);
+ *psecret = secret;
+
+ return SASL_OK;
+}
+
+//
+// Interactively prompt the user for authentication data.
+//
+static void qsasl_prompt(sasl_context_t _context, sasl_interact_t* interact)
+{
+ context_t* context = (context_t*) _context;
+ char *pass;
+ char *input;
+ char passwdPrompt[100];
+
+ if (interact->id == SASL_CB_PASS) {
+ strncpy(passwdPrompt, interact->prompt, 95);
+ strcat(passwdPrompt, ": ");
+ pass = getpass(passwdPrompt);
+ strncpy(context->input, pass, INPUT_SIZE - 1);
+ context->input[INPUT_SIZE - 1] = '\0';
+ } else {
+ printf(interact->prompt);
+ if (interact->defresult) {
+ printf(" (%s)", interact->defresult);
+ }
+ printf(": ");
+ input = fgets(context->input, INPUT_SIZE, stdin);
+ if (input != context->input) {
+ rb_raise(rb_eRuntimeError, "Unexpected EOF on interactive prompt");
+ }
+ }
+
+ interact->result = context->input;
+ interact->len = strlen(context->input);
+}
+
+//
+// Initialize the SASL client library.
+//
+static VALUE qsasl_client_init()
+{
+ int result;
+
+ result = sasl_client_init(0);
+ if (result != SASL_OK)
+ rb_raise(rb_eRuntimeError,
+ "sasl_client_init failed: %d - %s",
+ result, sasl_errstring(result, -0, 0));
+ return Qnil;
+}
+
+//
+// Allocate a new SASL client context.
+//
+static VALUE qsasl_client_new(int argc, VALUE *argv, VALUE obj)
+{
+ char* mechanism = 0;
+ char* serviceName = 0;
+ char* hostName = 0;
+ char* userName = 0;
+ char* password = 0;
+ unsigned int minSsf = 0;
+ unsigned int maxSsf = 65535;
+
+ int result;
+ int i = 0;
+ context_t *context;
+ sasl_security_properties_t secprops;
+
+ if (argc != 7)
+ rb_raise(rb_eRuntimeError, "Wrong number of arguments");
+
+ if (!NIL_P(argv[0]))
+ mechanism = StringValuePtr(argv[0]);
+ if (!NIL_P(argv[1]))
+ serviceName = StringValuePtr(argv[1]);
+ if (!NIL_P(argv[2]))
+ hostName = StringValuePtr(argv[2]);
+ if (!NIL_P(argv[3]))
+ userName = StringValuePtr(argv[3]);
+ if (!NIL_P(argv[4]))
+ password = StringValuePtr(argv[4]);
+ minSsf = FIX2INT(argv[5]);
+ maxSsf = FIX2INT(argv[6]);
+
+ if (!qsasl_valid(mechanism) || !qsasl_valid(serviceName) ||
+ !qsasl_valid(hostName) || !qsasl_valid(userName) ||
+ !qsasl_valid(password)) {
+ rb_raise(rb_eRuntimeError, "Invalid string argument");
+ }
+
+ context = (context_t*) malloc(sizeof(context_t));
+ memset(context, 0, sizeof(context_t));
+ strcpy(context->magic, "QSASL01");
+
+ context->minSsf = minSsf;
+ context->maxSsf = maxSsf;
+ if (mechanism != 0) {
+ strncpy(context->mechanism, mechanism, MECH_SIZE - 1);
+ context->mechanism[MECH_SIZE - 1] = '\0';
+ }
+
+ context->callbacks[i].id = SASL_CB_GETREALM;
+ context->callbacks[i].proc = 0;
+ context->callbacks[i++].context = 0;
+
+ if (userName != 0 && userName[0] != '\0') {
+ context->userName = (char*) malloc(strlen(userName) + 1);
+ strcpy(context->userName, userName);
+
+ context->callbacks[i].id = SASL_CB_USER;
+ context->callbacks[i].proc = qsasl_cb_user;
+ context->callbacks[i++].context = context;
+
+ context->callbacks[i].id = SASL_CB_AUTHNAME;
+ context->callbacks[i].proc = qsasl_cb_user;
+ context->callbacks[i++].context = context;
+ }
+
+ context->callbacks[i].id = SASL_CB_PASS;
+ if (password != 0 && password[0] != '\0') {
+ context->password = (char*) malloc(strlen(password) + 1);
+ strcpy(context->password, password);
+
+ context->callbacks[i].proc = qsasl_cb_password;
+ } else
+ context->callbacks[i].proc = 0;
+ context->callbacks[i++].context = context;
+
+ context->callbacks[i].id = SASL_CB_LIST_END;
+ context->callbacks[i].proc = 0;
+ context->callbacks[i++].context = 0;
+
+ result = sasl_client_new(serviceName, hostName, 0, 0,
+ context->callbacks, 0, &context->conn);
+
+ if (result != SASL_OK) {
+ context->conn = 0;
+ qsasl_free(1, (VALUE*) &context, Qnil);
+ rb_raise(rb_eRuntimeError, "sasl_client_new failed: %d - %s",
+ result, sasl_errstring(result, 0, 0));
+ }
+
+ secprops.min_ssf = minSsf;
+ secprops.max_ssf = maxSsf;
+ secprops.maxbufsize = 65535;
+ secprops.property_names = 0;
+ secprops.property_values = 0;
+ secprops.security_flags = 0;//TODO: provide means for application to configure these
+
+ result = sasl_setprop(context->conn, SASL_SEC_PROPS, &secprops);
+ if (result != SASL_OK) {
+ qsasl_free(1, (VALUE*) &context, Qnil);
+ rb_raise(rb_eRuntimeError, "sasl_setprop failed: %d - %s",
+ result, sasl_errdetail(context->conn));
+ }
+
+ return (VALUE) context;
+}
+
+//
+// Free a SASL client context.
+//
+static VALUE qsasl_free(int argc, VALUE *argv, VALUE obj)
+{
+ context_t* context;
+
+ if (argc == 1)
+ context = (context_t*) argv[0];
+ else
+ rb_raise(rb_eRuntimeError, "Wrong Number of Arguments");
+
+ if (context->conn)
+ sasl_dispose(&context->conn);
+ if (context->userName)
+ free(context->userName);
+ if (context->password)
+ free(context->password);
+ if (context->operUserName)
+ free(context->operUserName);
+ free(context);
+
+ return Qnil;
+}
+
+//
+// Start the SASL exchange from the client's point of view.
+//
+static VALUE qsasl_client_start(int argc, VALUE *argv, VALUE obj)
+{
+ context_t* context;
+ char* mechList;
+ char* mechToUse;
+ int result;
+ int propResult;
+ const char* response;
+ unsigned int len;
+ sasl_interact_t* interact = 0;
+ const char* chosen;
+ const char* operName;
+
+ if (argc == 2) {
+ context = (context_t*) argv[0];
+ mechList = StringValuePtr(argv[1]);
+ } else
+ rb_raise(rb_eRuntimeError, "Wrong Number of Arguments");
+
+ if (strlen(context->mechanism) == 0)
+ mechToUse = mechList;
+ else
+ mechToUse = context->mechanism;
+
+ do {
+ result = sasl_client_start(context->conn, mechToUse, &interact,
+ &response, &len, &chosen);
+ if (result == SASL_INTERACT) {
+ qsasl_prompt(context, interact);
+ }
+ } while (result == SASL_INTERACT);
+
+ if (result != SASL_OK && result != SASL_CONTINUE)
+ rb_raise(rb_eRuntimeError, "sasl_client_start failed: %d - %s",
+ result, sasl_errdetail(context->conn));
+
+ if (result == SASL_OK) {
+ propResult = sasl_getprop(context->conn, SASL_USERNAME, (const void**) &operName);
+ if (propResult == SASL_OK) {
+ context->operUserName = (char*) malloc(strlen(operName) + 1);
+ strcpy(context->operUserName, operName);
+ }
+ }
+
+ return rb_ary_new3(3, INT2NUM(result), rb_str_new(response, len), rb_str_new2(chosen));
+}
+
+//
+// Take a step in the SASL exchange (only needed for multi-challenge mechanisms).
+//
+static VALUE qsasl_client_step(int argc, VALUE *argv, VALUE obj)
+{
+ context_t* context;
+ VALUE challenge;
+ int result;
+ int propResult;
+ const char* response;
+ const char* operName;
+ unsigned int len;
+ sasl_interact_t* interact = 0;
+
+ if (argc == 2) {
+ context = (context_t*) argv[0];
+ challenge = argv[1];
+ }
+ else
+ rb_raise(rb_eRuntimeError, "Wrong Number of Arguments");
+
+ do {
+ result = sasl_client_step(context->conn,
+ RSTRING(challenge)->ptr, RSTRING(challenge)->len,
+ &interact, &response, &len);
+ if (result == SASL_INTERACT) {
+ qsasl_prompt(context, interact);
+ }
+ } while (result == SASL_INTERACT);
+
+ if (result != SASL_OK && result != SASL_CONTINUE)
+ return QSASL_FAILED;
+
+ if (result == SASL_OK) {
+ propResult = sasl_getprop(context->conn, SASL_USERNAME, (const void**) &operName);
+ if (propResult == SASL_OK) {
+ context->operUserName = (char*) malloc(strlen(operName) + 1);
+ strcpy(context->operUserName, operName);
+ }
+ }
+
+ return rb_ary_new3(2, INT2NUM(result), rb_str_new(response, len));
+}
+
+static VALUE qsasl_user_id(int argc, VALUE *argv, VALUE obj)
+{
+ context_t* context;
+
+ if (argc == 1) {
+ context = (context_t*) argv[0];
+ } else {
+ rb_raise(rb_eRuntimeError, "Wrong Number of Arguments");
+ }
+
+ if (context->operUserName)
+ return rb_str_new2(context->operUserName);
+
+ return Qnil;
+}
+
+//
+// Encode transport data for the security layer.
+//
+static VALUE qsasl_encode(int argc, VALUE *argv, VALUE obj)
+{
+ context_t* context;
+ VALUE clearText;
+ const char* outBuffer;
+ unsigned int outSize;
+ int result;
+
+ if (argc == 2) {
+ context = (context_t*) argv[0];
+ clearText = argv[1];
+ }
+ else
+ rb_raise(rb_eRuntimeError, "Wrong Number of Arguments");
+
+ result = sasl_encode(context->conn,
+ RSTRING(clearText)->ptr, RSTRING(clearText)->len,
+ &outBuffer, &outSize);
+ if (result != SASL_OK)
+ rb_raise(rb_eRuntimeError, "sasl_encode failed: %d - %s",
+ result, sasl_errdetail(context->conn));
+
+ return rb_str_new(outBuffer, outSize);
+}
+
+//
+// Decode transport data for the security layer.
+//
+static VALUE qsasl_decode(int argc, VALUE *argv, VALUE obj)
+{
+ context_t* context;
+ VALUE cipherText;
+ const char* outBuffer;
+ unsigned int outSize;
+ int result;
+
+ if (argc == 2) {
+ context = (context_t*) argv[0];
+ cipherText = argv[1];
+ }
+ else
+ rb_raise(rb_eRuntimeError, "Wrong Number of Arguments");
+
+ result = sasl_decode(context->conn,
+ RSTRING(cipherText)->ptr, RSTRING(cipherText)->len,
+ &outBuffer, &outSize);
+ if (result != SASL_OK)
+ rb_raise(rb_eRuntimeError, "sasl_decode failed: %d - %s",
+ result, sasl_errdetail(context->conn));
+
+ return rb_str_new(outBuffer, outSize);
+}
+
+//
+// Initialize the Sasl module.
+//
+void Init_sasl()
+{
+ mSasl = rb_define_module("Sasl");
+
+ rb_define_module_function(mSasl, "client_init", qsasl_client_init, -1);
+ rb_define_module_function(mSasl, "client_new", qsasl_client_new, -1);
+ rb_define_module_function(mSasl, "free", qsasl_free, -1);
+ rb_define_module_function(mSasl, "client_start", qsasl_client_start, -1);
+ rb_define_module_function(mSasl, "client_step", qsasl_client_step, -1);
+ rb_define_module_function(mSasl, "user_id", qsasl_user_id, -1);
+ rb_define_module_function(mSasl, "encode", qsasl_encode, -1);
+ rb_define_module_function(mSasl, "decode", qsasl_decode, -1);
+}
diff --git a/qpid/ruby/lib/qpid.rb b/qpid/ruby/lib/qpid.rb
new file mode 100644
index 0000000000..1c719e9b1d
--- /dev/null
+++ b/qpid/ruby/lib/qpid.rb
@@ -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.
+#
+
+module Qpid
+ def self.logger
+ @logger ||= {}
+ @logger
+ end
+end
+
+require "qpid/util"
+require "qpid/queue"
+require "qpid/packer"
+require "qpid/framer"
+require "qpid/codec"
+require 'qpid/datatypes'
+require 'qpid/spec010'
+require 'qpid/delegates'
+require 'qpid/invoker'
+require "qpid/assembler"
+require 'qpid/session'
+require "qpid/connection"
+require "qpid/spec"
+require 'qpid/queue'
+require 'qpid/qmf'
diff --git a/qpid/ruby/lib/qpid/assembler.rb b/qpid/ruby/lib/qpid/assembler.rb
new file mode 100644
index 0000000000..b768c3f195
--- /dev/null
+++ b/qpid/ruby/lib/qpid/assembler.rb
@@ -0,0 +1,148 @@
+#
+# 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.
+#
+
+module Qpid
+
+ class << self
+ attr_accessor :asm_logger
+ end
+
+ class Segment
+
+ attr_reader :type, :payload, :track, :channel
+ attr_accessor :id, :offset
+
+ def initialize(first, last, type, track, channel, payload)
+ @id = nil
+ @offset = nil
+ @first = first
+ @last = last
+ @type = type
+ @track = track
+ @channel = channel
+ @payload = payload
+ end
+
+ def first_segment? ; @first ; end
+
+ def last_segment? ; @last ; end
+
+ def decode(spec)
+ segs = spec[:segment_type]
+ choice = segs.enum.choices[type]
+ return method("decode_#{choice.name}").call(spec)
+ end
+
+ def decode_control(spec)
+ sc = StringCodec.new(spec, payload)
+ return sc.read_control()
+ end
+
+ def decode_command(spec)
+ sc = StringCodec.new(spec, payload)
+ hdr, cmd = sc.read_command()
+ cmd.id = id
+ return hdr, cmd
+ end
+
+ def decode_header(spec)
+ sc = StringCodec.new(spec, payload)
+ values = []
+ until sc.encoded.empty?
+ values << sc.read_struct32()
+ end
+ return values
+ end
+
+ def decode_body(spec)
+ payload
+ end
+
+ def append(frame)
+ @payload += frame.payload
+ end
+
+ def to_s
+ f = first_segment? ? 'F' : '.'
+ l = last_segment? ? 'L' : '.'
+ return "%s%s %s %s %s %s" % [f, l, @type,
+ @track, @channel, @payload.inspect]
+ end
+
+ end
+
+ class Assembler < Framer
+
+ def logger; Qpid::asm_logger; end
+
+ def initialize(sock, max_payload = Frame::MAX_PAYLOAD)
+ super(sock)
+ @max_payload = max_payload
+ @fragments = {}
+ end
+
+ def read_segment
+ loop do
+ frame = read_frame
+ key = [frame.channel, frame.track]
+ seg = @fragments[key]
+ unless seg
+ seg = Segment.new(frame.first_segment?,
+ frame.last_segment?,
+ frame.type, frame.track,
+ frame.channel, "")
+ @fragments[key] = seg
+ end
+
+ seg.append(frame)
+
+ if frame.last_frame?
+ @fragments.delete(key)
+ logger.debug("RECV #{seg}") if logger
+ return seg
+ end
+ end
+ end
+
+ def write_segment(segment)
+ remaining = segment.payload
+
+ first = true
+ while first or remaining
+ payload = remaining[0, @max_payload]
+ remaining = remaining[@max_payload, remaining.size]
+
+ flags = 0
+
+ flags |= FIRST_FRM if first
+ flags |= LAST_FRM unless remaining
+ flags |= FIRST_SEG if segment.first_segment?
+ flags |= LAST_SEG if segment.last_segment?
+
+ frame = Frame.new(flags, segment.type, segment.track,
+ segment.channel, payload)
+ write_frame(frame)
+
+ first = false
+ end
+
+ logger.debug("SENT #{segment}") if logger
+ end
+ end
+end
diff --git a/qpid/ruby/lib/qpid/client.rb b/qpid/ruby/lib/qpid/client.rb
new file mode 100644
index 0000000000..ec3d100a9c
--- /dev/null
+++ b/qpid/ruby/lib/qpid/client.rb
@@ -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.
+#
+
+require "thread"
+require "qpid/peer"
+require "qpid/queue"
+
+module Qpid08
+
+ class Client
+ def initialize(host, port, spec, vhost = "/")
+ @host = host
+ @port = port
+ @spec = spec
+ @vhost = vhost
+
+ @mechanism = nil
+ @response = nil
+ @locale = nil
+
+ @queues = {}
+ @mutex = Mutex.new()
+
+ @closed = false
+ @code = nil
+ @started = ConditionVariable.new()
+
+ @conn = Connection.new(@host, @port, @spec)
+ @peer = Peer.new(@conn, ClientDelegate.new(self))
+ end
+
+ attr_reader :mechanism, :response, :locale
+
+ def closed?; @closed end
+ def closed=(value); @closed = value end
+ def code; @code end
+
+ def wait()
+ @mutex.synchronize do
+ @started.wait(@mutex)
+ end
+ raise EOFError.new() if closed?
+ end
+
+ def signal_start()
+ @started.broadcast()
+ end
+
+ def queue(key)
+ @mutex.synchronize do
+ q = @queues[key]
+ if q.nil?
+ q = Queue.new()
+ @queues[key] = q
+ end
+ return q
+ end
+ end
+
+ def start(response, mechanism="AMQPLAIN", locale="en_US")
+ @response = response
+ @mechanism = mechanism
+ @locale = locale
+
+ @conn.connect()
+ @conn.init()
+ @peer.start()
+ wait()
+ channel(0).connection_open(@vhost)
+ end
+
+ def channel(id)
+ return @peer.channel(id)
+ end
+
+ def close(msg = nil)
+ @closed = true
+ @code = msg
+ @peer.close()
+ end
+ end
+
+ class ClientDelegate
+
+ include Delegate
+
+ def initialize(client)
+ @client = client
+ end
+
+ def connection_start(ch, msg)
+ ch.connection_start_ok(:mechanism => @client.mechanism,
+ :response => @client.response,
+ :locale => @client.locale)
+ end
+
+ def connection_tune(ch, msg)
+ ch.connection_tune_ok(*msg.fields)
+ @client.signal_start()
+ end
+
+ def connection_close(ch, msg)
+ puts "CONNECTION CLOSED: #{msg.args.join(", ")}"
+ @client.close(msg)
+ end
+
+ def channel_close(ch, msg)
+ puts "CHANNEL[#{ch.id}] CLOSED: #{msg.args.join(", ")}"
+ ch.channel_close_ok()
+ ch.close()
+ end
+
+ def basic_deliver(ch, msg)
+ queue = @client.queue(msg.consumer_tag)
+ queue << msg
+ end
+
+ end
+
+end
diff --git a/qpid/ruby/lib/qpid/codec.rb b/qpid/ruby/lib/qpid/codec.rb
new file mode 100644
index 0000000000..a3b5d101c4
--- /dev/null
+++ b/qpid/ruby/lib/qpid/codec.rb
@@ -0,0 +1,457 @@
+#
+# 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.
+#
+
+require 'qpid/packer.rb'
+require 'iconv'
+
+module Qpid
+
+ class Codec
+
+ include Qpid::Packer
+
+ attr_reader :spec
+
+ def initialize(spec = "")
+ @spec = spec
+ end
+
+ def write_void(v)
+ unless v.nil?
+ raise Exception.new("void not nil: #{v}")
+ end
+ end
+
+ def read_void
+ return nil
+ end
+
+ def write_bit(b)
+ unless b
+ raise Exception.new("bit is nil: #{b}")
+ end
+ end
+
+ def read_bit
+ return true
+ end
+
+ def read_uint8
+ return unpack("C", 1)
+ end
+
+ def write_uint8(n)
+ return pack("C", n)
+ end
+
+ def read_int8
+ return unpack("c", 1)
+ end
+
+ def write_int8(n)
+ pack("c", n)
+ end
+
+ def read_char
+ return unpack("c", 1)
+ end
+
+ def write_char(c)
+ pack("c")
+ end
+
+ def read_boolean
+ return read_uint8 != 0
+ end
+
+ def write_boolean(b)
+ n = 0
+ n = 1 if b != 0
+ write_uint8(n)
+ end
+
+ def read_uint16
+ return unpack("n", 2)
+ end
+
+ def write_uint16(n)
+ pack("n", n)
+ end
+
+ def read_int16
+ # XXX: holy moly.. pack/unpack doesn't have signed network byte order. Crazy hackery.
+ val = unpack("n", 2)
+ val -= 2 ** 16 if val >= 2 ** 15
+ return val
+ end
+
+ def write_int16(n)
+ # XXX: Magically this one works even though it's not signed.
+ pack("n", n)
+ end
+
+ def read_uint32
+ return unpack("N", 4)
+ end
+
+ def write_uint32(n)
+ pack("N", n)
+ end
+
+ def read_int32
+ # Again no pack/unpack for signed int
+ return unpack("N", 4)
+ end
+
+ def write_int32(n)
+ # FIXME
+ pack("N", n)
+ end
+
+ def read_float
+ return unpack("g", 4)
+ end
+
+ def write_float(n)
+ pack("g", n)
+ end
+
+ def read_sequence_no
+ return read_uint32.to_serial
+ end
+
+ def write_sequence_no(n)
+ write_uint32(n.value)
+ end
+
+ def encode_64bit(num, signed = false)
+ b = []
+
+ if num < 0 && signed
+ num += 2 ** 64
+ end
+
+ (0..7).each do |c|
+ d = 7 - c
+ b[c] = (num & (0xff << d * 8)) >> d * 8
+ end
+ pack('C8', *b)
+ end
+
+
+ def decode_64bit(signed = false)
+ # Silly ruby pack/unpack does not implement 64 bit network byte order
+ # encode/decode.
+ a = unpack('C8', 8)
+ num = 0
+ (0..7).each do |c|
+ d = 7 - c
+ num |= a[c] << 8 * d
+ end
+
+ if signed && num >= 2 ** 63
+ num -= 2 ** 64
+ end
+ return num
+ end
+
+ def read_uint64
+ return decode_64bit
+ end
+
+ def write_uint64(n)
+ encode_64bit(n)
+ end
+
+ def read_int64
+ return decode_64bit(signed = true)
+ end
+
+ def write_int64(n)
+ encode_64bit(n, signed = true)
+ end
+
+ def read_datetime
+ return read_uint64
+ end
+
+ def write_datetime(n)
+ write_uint64(n)
+ end
+
+ def read_double
+ return unpack("G", 8)
+ end
+
+ def write_double(n)
+ pack("G", n)
+ end
+
+ def read_vbin8
+ # XXX
+ return read(read_uint8)
+ end
+
+ def write_vbin8(b)
+ # XXX
+ write_uint8(b.length)
+ write(b)
+ end
+
+ def read_str8
+ # FIXME: Check iconv.. I think this will throw if there are odd characters.
+ return Iconv.conv("ASCII", "UTF-8", read_vbin8)
+ end
+
+ def write_str8(s)
+ write_vbin8(Iconv.conv("UTF-8", "ASCII", s))
+ end
+
+ def read_str16
+ return Iconv.conv("ASCII", "UTF-8", read_vbin16)
+ end
+
+ def write_str16(s)
+ write_vbin16(Iconv.conv("UTF-8", "ASCII", s))
+ end
+
+ def read_vbin16
+ # XXX: Using read method?
+ return read(read_uint16)
+ end
+
+ def write_vbin16(b)
+ write_uint16(b.length)
+ write(b)
+ end
+
+ def read_sequence_set
+ # FIXME: Need datatypes
+ result = RangedSet.new
+ size = read_uint16
+ nranges = size / 8
+ nranges.times do |i|
+ lower = read_sequence_no
+ upper = read_sequence_no
+ result.add(lower, upper)
+ end
+ return result
+ end
+
+ def write_sequence_set(ss)
+ size = 8 * ss.ranges.length
+ write_uint16(size)
+ ss.ranges.each do |range|
+ write_sequence_no(range.lower)
+ write_sequence_no(range.upper)
+ end
+ end
+
+ def read_vbin32
+ return read(read_uint32)
+ end
+
+ def write_vbin32(b)
+ write_uint32(b.length)
+ write(b)
+ end
+
+ def write_map(m)
+ sc = StringCodec.new(@spec)
+ unless m.nil?
+ sc.write_uint32(m.size)
+ m.each do |k, v|
+ unless type = @spec.encoding(v.class)
+ raise Exception.new("no encoding for: #{v.class}")
+ end
+ sc.write_str8(k)
+ sc.write_uint8(type.code)
+ type.encode(sc, v)
+ end
+ end
+ write_vbin32(sc.encoded)
+ end
+
+ def read_map
+ sc = StringCodec.new(@spec, read_vbin32)
+ return nil unless sc.encoded
+ count = sc.read_uint32
+ result = nil
+ if count
+ result = {}
+ until sc.encoded.empty?
+ k = sc.read_str8
+ code = sc.read_uint8
+ type = @spec.types[code]
+ v = type.decode(sc)
+ result[k] = v
+ end
+ end
+ return result
+ end
+
+ def write_array(a)
+ sc = StringCodec.new(@spec)
+ unless a.nil?
+ if a.length > 0
+ type = @spec.encoding(a[0].class)
+ else
+ type = @spec.encoding(nil.class)
+ end
+ sc.write_uint8(type.code)
+ sc.write_uint32(a.size)
+ a.each { |o| type.encode(sc, o) }
+ end
+ write_vbin32(sc.encoded)
+ end
+
+ def read_array
+ sc = StringCodec.new(@spec, read_vbin32)
+ return nil if not sc.encoded
+ type = @spec.types[sc.read_uint8]
+ count = sc.read_uint32
+ result = nil
+ if count
+ result = []
+ count.times { |i| result << (type.decode(sc)) }
+ end
+ return result
+ end
+
+ def write_list(l)
+ sc = StringCodec.new(@spec)
+ unless l.nil?
+ sc.write_uint32(l.length)
+ l.each do |o|
+ type = @spec.encoding(o.class)
+ sc.write_uint8(type.code)
+ type.encode(sc, o)
+ end
+ end
+ write_vbin32(sc.encoded)
+ end
+
+ def read_list
+ sc = StringCodec.new(@spec, read_vbin32)
+ return nil if not sc.encoded
+ count = sc.read_uint32
+ result = nil
+ if count
+ result = []
+ count.times do |i|
+ type = @spec.types[sc.read_uint8]
+ result << type.decode(sc)
+ end
+ end
+ return result
+ end
+
+ def read_struct32
+ size = read_uint32
+ code = read_uint16
+ type = @spec.structs[code]
+ # XXX: BLEH!
+ fields = type.decode_fields(self)
+ return Qpid::struct(type, fields)
+ end
+
+ def write_struct32(value)
+ type = value.st_type
+ sc = StringCodec.new(@spec)
+ sc.write_uint16(type.code)
+ type.encode_fields(sc, value)
+ write_vbin32(sc.encoded)
+ end
+
+ def read_control
+ cntrl = @spec.controls[read_uint16]
+ return Qpid::struct(cntrl, cntrl.decode_fields(self))
+ end
+
+ def write_control(ctrl)
+ type = ctrl.st_type
+ write_uint16(type.code)
+ type.encode_fields(self, ctrl)
+ end
+
+ def read_command
+ type = @spec.commands[read_uint16]
+ hdr = @spec[:header].decode(self)
+ cmd = Qpid::struct(type, type.decode_fields(self))
+ return hdr, cmd
+ end
+
+ def write_command(hdr, cmd)
+ type = cmd.st_type
+ write_uint16(type.code)
+ hdr.st_type.encode(self, hdr)
+ type.encode_fields(self, cmd)
+ end
+
+ def read_size(width)
+ if width > 0
+ return send(:"read_uint#{width * 8}")
+ end
+ end
+
+ def write_size(width, n)
+ if width > 0
+ send(:"write_uint#{width * 8}", n)
+ end
+ end
+
+ def read_uuid
+ return unpack("a16", 16)
+ end
+
+ def write_uuid(s)
+ pack("a16", s)
+ end
+
+ def read_bin128
+ return unpack("a16", 16)
+ end
+
+ def write_bin128(b)
+ pack("a16", b)
+ end
+
+ end
+
+ class StringCodec < Codec
+
+ def initialize(spec, encoded = "")
+ @spec = spec
+ @encoded = encoded
+ end
+
+ attr_reader :encoded
+
+ def write(s)
+ @encoded += s
+ end
+
+ def read(n)
+ return "" if n.nil?
+ result = @encoded[0...n]
+ @encoded = @encoded[n...@encoded.size] || ""
+ return result
+ end
+ end
+end
diff --git a/qpid/ruby/lib/qpid/codec08.rb b/qpid/ruby/lib/qpid/codec08.rb
new file mode 100644
index 0000000000..148dee07bb
--- /dev/null
+++ b/qpid/ruby/lib/qpid/codec08.rb
@@ -0,0 +1,265 @@
+#
+# 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.
+#
+
+module Qpid08
+ # is there a better way to do this?
+ class StringWriter
+
+ def initialize(str = "")
+ @str = str
+ end
+
+ def write(value)
+ @str << value
+ end
+
+ def to_s()
+ return @str
+ end
+
+ end
+
+ class EOF < Exception; end
+
+ class Encoder
+
+ def initialize(out)
+ @out = out
+ @bits = []
+ end
+
+ attr_reader(:out)
+
+ def encode(type, value)
+ send(type, value)
+ end
+
+ def bit(b)
+ @bits << b
+ end
+
+ def octet(o)
+ pack("C", o)
+ end
+
+ def short(s)
+ pack("n", s)
+ end
+
+ def long(l)
+ pack("N", l)
+ end
+
+ def longlong(l)
+ lower = l & 0xffffffff
+ upper = (l & ~0xffffffff) >> 32
+ long(upper)
+ long(lower)
+ end
+
+ def timestamp(l)
+ longlong(l)
+ end
+
+ def shortstr(s)
+ # shortstr is actually octetstr
+ octet(s.length)
+ write(s)
+ end
+
+ def longstr(s)
+ case s
+ when Hash
+ table(s)
+ else
+ long(s.length)
+ write(s)
+ end
+ end
+
+ def table(t)
+ t = {} if t.nil?
+ enc = Encoder.new(StringWriter.new())
+ t.each {|key, value|
+ enc.shortstr(key)
+ # I offer this chicken to the gods of polymorphism. May they
+ # choke on it.
+ case value
+ when String
+ type = :longstr
+ desc = "S"
+ when Numeric
+ type = :long
+ desc = "I"
+ else
+ raise Exception.new("unknown table value: #{value.class}")
+ end
+ enc.write(desc)
+ enc.encode(type, value)
+ }
+ longstr(enc.out.to_s())
+ end
+
+ def write(str)
+ flushbits()
+ @out.write(str)
+ # puts "OUT #{str.inspect()}"
+ end
+
+ def pack(fmt, *args)
+ write(args.pack(fmt))
+ end
+
+ def flush()
+ flushbits()
+ end
+
+ private
+
+ def flushbits()
+ if @bits.empty? then return end
+
+ bytes = []
+ index = 0
+ @bits.each {|b|
+ bytes << 0 if index == 0
+ if b then bytes[-1] |= 1 << index end
+ index = (index + 1) % 8
+ }
+ @bits.clear()
+ bytes.each {|b|
+ octet(b)
+ }
+ end
+
+ end
+
+ class StringReader
+
+ def initialize(str)
+ @str = str
+ @index = 0
+ end
+
+ def read(n)
+ result = @str[@index, n]
+ @index += result.length
+ return result
+ end
+
+ end
+
+ class Decoder
+
+ def initialize(_in)
+ @in = _in
+ @bits = []
+ end
+
+ def decode(type)
+ return send(type)
+ end
+
+ def bit()
+ if @bits.empty?
+ byte = octet()
+ 7.downto(0) {|i|
+ @bits << (byte[i] == 1)
+ }
+ end
+ return @bits.pop()
+ end
+
+ def octet()
+ return unpack("C", 1)
+ end
+
+ def short()
+ return unpack("n", 2)
+ end
+
+ def long()
+ return unpack("N", 4)
+ end
+
+ def longlong()
+ upper = long()
+ lower = long()
+ return upper << 32 | lower
+ end
+
+ def timestamp()
+ return longlong()
+ end
+
+ def shortstr()
+ # shortstr is actually octetstr
+ return read(octet())
+ end
+
+ def longstr()
+ return read(long())
+ end
+
+ def table()
+ dec = Decoder.new(StringReader.new(longstr()))
+ result = {}
+ while true
+ begin
+ key = dec.shortstr()
+ rescue EOF
+ break
+ end
+ desc = dec.read(1)
+ case desc
+ when "S"
+ value = dec.longstr()
+ when "I"
+ value = dec.long()
+ else
+ raise Exception.new("unrecognized descriminator: #{desc.inspect()}")
+ end
+ result[key] = value
+ end
+ return result
+ end
+
+ def read(n)
+ return "" if n == 0
+ result = @in.read(n)
+ if result.nil? or result.empty?
+ raise EOF.new()
+ else
+ # puts " IN #{result.inspect()}"
+ return result
+ end
+ end
+
+ def unpack(fmt, size)
+ result = read(size).unpack(fmt)
+ if result.length == 1
+ return result[0]
+ else
+ return result
+ end
+ end
+
+ end
+
+end
diff --git a/qpid/ruby/lib/qpid/config.rb b/qpid/ruby/lib/qpid/config.rb
new file mode 100644
index 0000000000..b5b79cd309
--- /dev/null
+++ b/qpid/ruby/lib/qpid/config.rb
@@ -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.
+#
+
+module Qpid
+ module Config
+
+ def self.amqp_spec
+ dirs = [File::expand_path(File::join(File::dirname(__FILE__), "specs"))]
+ dirs.each do |d|
+ spec = File::join(d, "amqp.0-10-qpid-errata.xml")
+ return spec if File::exists? spec
+ end
+ end
+
+ end
+end
diff --git a/qpid/ruby/lib/qpid/connection.rb b/qpid/ruby/lib/qpid/connection.rb
new file mode 100644
index 0000000000..d2efbfb263
--- /dev/null
+++ b/qpid/ruby/lib/qpid/connection.rb
@@ -0,0 +1,222 @@
+#
+# 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.
+#
+
+require 'monitor'
+
+module Qpid
+
+ class ChannelBusy< Exception ; end
+
+ class ChannelsBusy < Exception ; end
+
+ class SessionBusy < Exception ; end
+
+ class ConnectionFailed < Exception ; end
+
+ class Timeout < Exception ; end
+
+ class Connection < Assembler
+
+ include MonitorMixin
+
+ attr_reader :spec, :attached, :sessions, :thread
+ attr_accessor :opened, :failed, :close_code, :user_id
+
+ def initialize(sock, args={})
+ super(sock)
+
+ delegate = args[:delegate] || Qpid::Delegate::Client.method(:new)
+ spec = args[:spec] || nil
+
+ @spec = Qpid::Spec010::load(spec)
+ @track = @spec["track"]
+
+ @attached = {}
+ @sessions = {}
+
+ @condition = new_cond
+ @opened = false
+ @failed = false
+ @close_code = [nil, "connection aborted"]
+
+ @thread = nil
+
+ @channel_max = 65535
+ @user_id = nil
+
+ @delegate = delegate.call(self, args)
+ end
+
+ def attach(name, ch, delegate, force=false)
+ synchronize do
+ ssn = @attached[ch.id]
+ if ssn
+ raise ChannelBusy.new(ch, ssn) unless ssn.name == name
+ else
+ ssn = @sessions[name]
+ if ssn.nil?
+ ssn = Session.new(name, @spec, :delegate => delegate)
+ @sessions[name] = ssn
+ elsif ssn.channel
+ if force
+ @attached.delete(ssn.channel.id)
+ ssn.channel = nil
+ else
+ raise SessionBusy.new(ssn)
+ end
+ end
+ @attached[ch.id] = ssn
+ ssn.channel = ch
+ end
+ ch.session = ssn
+ return ssn
+ end
+ end
+
+ def detach(name, ch)
+ synchronize do
+ @attached.delete(ch.id)
+ ssn = @sessions.delete(name)
+ if ssn
+ ssn.channel = nil
+ ssn.closed
+ return ssn
+ end
+ end
+ end
+
+ def session(name, kwargs = {})
+ timeout = kwargs[:timeout]
+ delegate = kwargs[:delegate] || Qpid::Session::Client.method(:new)
+
+ # FIXME: Python has cryptic comment about 'ch 0 ?'
+ channel = (0..@channel_max).detect { |i| ! @attached.key?(i) }
+ raise ChannelsBusy unless channel
+
+ synchronize do
+ ch = Channel.new(self, channel)
+ ssn = attach(name, ch, delegate)
+ ssn.channel.session_attach(name)
+ if ssn.wait_for(timeout) { ssn.channel }
+ return ssn
+ else
+ detach(name, ch)
+ raise Timeout
+ end
+ end
+ end
+
+ def detach_all
+ synchronize do
+ attached.values.each do |ssn|
+ ssn.exceptions << @close_code unless @close_code[0] == 200
+ detach(ssn.name, ssn.channel)
+ end
+ end
+ end
+
+ def start(timeout=nil)
+ @delegate.start
+ @thread = Thread.new { run }
+ @thread[:name] = 'conn'
+ synchronize do
+ unless @condition.wait_for(timeout) { @opened || @failed }
+ raise Timeout
+ end
+ end
+ if @failed
+ raise ConnectionFailed.new(@close_code)
+ end
+ end
+
+ def run
+ # XXX: we don't really have a good way to exit this loop without
+ # getting the other end to kill the socket
+ loop do
+ begin
+ seg = read_segment
+ rescue Qpid::Closed => e
+ detach_all
+ break
+ end
+ @delegate.received(seg)
+ end
+ end
+
+ def close(timeout=nil)
+ return unless @opened
+ Channel.new(self, 0).connection_close(200)
+ synchronize do
+ unless @condition.wait_for(timeout) { ! @opened }
+ raise Timeout
+ end
+ end
+ @thread.join(timeout)
+ @thread = nil
+ end
+
+ def signal
+ synchronize { @condition.signal }
+ end
+
+ def to_s
+ # FIXME: We'd like to report something like HOST:PORT
+ return @sock.to_s
+ end
+
+ class Channel < Invoker
+
+ attr_reader :id, :connection
+ attr_accessor :session
+
+ def initialize(connection, id)
+ @connection = connection
+ @id = id
+ @session = nil
+ end
+
+ def resolve_method(name)
+ inst = @connection.spec[name]
+ if inst.is_a?(Qpid::Spec010::Control)
+ return invocation(:method, inst)
+ else
+ return invocation(:error, nil)
+ end
+ end
+
+ def invoke(type, args)
+ ctl = type.create(*args)
+ sc = StringCodec.new(@connection.spec)
+ sc.write_control(ctl)
+ @connection.write_segment(Segment.new(true, true, type.segment_type,
+ type.track, self.id, sc.encoded))
+
+ log = Qpid::logger["qpid.io.ctl"]
+ log.debug("SENT %s", ctl) if log
+ end
+
+ def to_s
+ return "#{@connection}[#{@id}]"
+ end
+
+ end
+
+ end
+
+end
diff --git a/qpid/ruby/lib/qpid/connection08.rb b/qpid/ruby/lib/qpid/connection08.rb
new file mode 100644
index 0000000000..09a4888cc4
--- /dev/null
+++ b/qpid/ruby/lib/qpid/connection08.rb
@@ -0,0 +1,252 @@
+#
+# 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.
+#
+
+require "socket"
+require "qpid/codec08"
+
+module Qpid08
+
+ class Connection
+
+ def initialize(host, port, spec)
+ @host = host
+ @port = port
+ @spec = spec
+ end
+
+ attr_reader(:host, :port, :spec)
+
+ def connect()
+ @sock = TCPSocket.open(@host, @port)
+ @out = Encoder.new(@sock)
+ @in = Decoder.new(@sock)
+ end
+
+ def init()
+ @out.write("AMQP")
+ [1, 1, @spec.major, @spec.minor].each {|o|
+ @out.octet(o)
+ }
+ end
+
+ def write(frame)
+ # puts "OUT #{frame.inspect()}"
+ @out.octet(@spec.constants[frame.payload.type].id)
+ @out.short(frame.channel)
+ frame.payload.encode(@out)
+ @out.octet(frame_end)
+ end
+
+ def read()
+ type = @spec.constants[@in.octet()].name
+ channel = @in.short()
+ payload = Payload.decode(type, @spec, @in)
+ oct = @in.octet()
+ if oct != frame_end
+ raise Exception.new("framing error: expected #{frame_end}, got #{oct}")
+ end
+ frame = Frame.new(channel, payload)
+ # puts " IN #{frame.inspect}"
+ return frame
+ end
+
+ private
+
+ def frame_end
+ @spec.constants[:"frame_end"].id
+ end
+
+ end
+
+ class Frame
+
+ def initialize(channel, payload)
+ @channel = channel
+ @payload = payload
+ end
+
+ attr_reader(:channel, :payload)
+
+ end
+
+ class Payload
+
+ TYPES = {}
+
+ def Payload.singleton_method_added(name)
+ if name == :type
+ TYPES[type] = self
+ end
+ end
+
+ def Payload.decode(type, spec, dec)
+ klass = TYPES[type]
+ klass.decode(spec, dec)
+ end
+
+ end
+
+ class Method < Payload
+
+ def initialize(method, args)
+ if args.size != method.fields.size
+ raise ArgumentError.new("argument mismatch #{method} #{args}")
+ end
+ @method = method
+ @args = args
+ end
+
+ attr_reader(:method, :args)
+
+ def Method.type; :frame_method end
+
+ def type; Method.type end
+
+ def encode(encoder)
+ buf = StringWriter.new()
+ enc = Encoder.new(buf)
+ enc.short(@method.parent.id)
+ enc.short(@method.id)
+ @method.fields.zip(self.args).each {|f, a|
+ if a.nil?; a = f.default end
+ enc.encode(f.type, a)
+ }
+ enc.flush()
+ encoder.longstr(buf.to_s)
+ end
+
+ def Method.decode(spec, decoder)
+ buf = decoder.longstr()
+ dec = Decoder.new(StringReader.new(buf))
+ klass = spec.classes[dec.short()]
+ meth = klass.methods[dec.short()]
+ args = meth.fields.map {|f| dec.decode(f.type)}
+ return Method.new(meth, args)
+ end
+
+ def inspect(); "#{method.qname}(#{args.join(", ")})" end
+
+ end
+
+ class Header < Payload
+
+ def Header.type; :frame_header end
+
+ def initialize(klass, weight, size, properties)
+ @klass = klass
+ @weight = weight
+ @size = size
+ @properties = properties
+ end
+
+ attr_reader :weight, :size, :properties
+
+ def type; Header.type end
+
+ def encode(encoder)
+ buf = StringWriter.new()
+ enc = Encoder.new(buf)
+ enc.short(@klass.id)
+ enc.short(@weight)
+ enc.longlong(@size)
+
+ # property flags
+ nprops = @klass.fields.size
+ flags = 0
+ 0.upto(nprops - 1) do |i|
+ f = @klass.fields[i]
+ flags <<= 1
+ flags |= 1 unless @properties[f.name].nil?
+ # the last bit indicates more flags
+ if i > 0 and (i % 15) == 0
+ flags <<= 1
+ if nprops > (i + 1)
+ flags |= 1
+ enc.short(flags)
+ flags = 0
+ end
+ end
+ end
+ flags <<= ((16 - (nprops % 15)) % 16)
+ enc.short(flags)
+
+ # properties
+ @klass.fields.each do |f|
+ v = @properties[f.name]
+ enc.encode(f.type, v) unless v.nil?
+ end
+ enc.flush()
+ encoder.longstr(buf.to_s)
+ end
+
+ def Header.decode(spec, decoder)
+ dec = Decoder.new(StringReader.new(decoder.longstr()))
+ klass = spec.classes[dec.short()]
+ weight = dec.short()
+ size = dec.longlong()
+
+ # property flags
+ bits = []
+ while true
+ flags = dec.short()
+ 15.downto(1) do |i|
+ if flags >> i & 0x1 != 0
+ bits << true
+ else
+ bits << false
+ end
+ end
+ break if flags & 0x1 == 0
+ end
+
+ # properties
+ properties = {}
+ bits.zip(klass.fields).each do |b, f|
+ properties[f.name] = dec.decode(f.type) if b
+ end
+ return Header.new(klass, weight, size, properties)
+ end
+
+ def inspect(); "#{@klass.name}(#{@properties.inspect()})" end
+
+ end
+
+ class Body < Payload
+
+ def Body.type; :frame_body end
+
+ def type; Body.type end
+
+ def initialize(content)
+ @content = content
+ end
+
+ attr_reader :content
+
+ def encode(enc)
+ enc.longstr(@content)
+ end
+
+ def Body.decode(spec, dec)
+ return Body.new(dec.longstr())
+ end
+
+ end
+
+end
diff --git a/qpid/ruby/lib/qpid/datatypes.rb b/qpid/ruby/lib/qpid/datatypes.rb
new file mode 100644
index 0000000000..418388c73a
--- /dev/null
+++ b/qpid/ruby/lib/qpid/datatypes.rb
@@ -0,0 +1,353 @@
+#
+# 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.
+#
+
+module Qpid
+
+ def self.struct(type, *args)
+ # FIXME: This is fragile; the last arg could be a hash,
+ # without being hte keywords
+ kwargs = {}
+ kwargs = args.pop if args.any? && args[-1].is_a?(Hash)
+
+ if args.size > type.fields.size
+ raise TypeError,
+ "%s() takes at most %d arguments (%d given)" %
+ [type.name, type.fields.size, args.size]
+ end
+
+ attrs = type.fields.inject({}) do |attrs, field|
+ if args.any?
+ attrs[field.name] = args.shift
+ if kwargs.key?(field.name)
+ raise TypeError,
+ "%s() got multiple values for keyword argument '%s'" %
+ [type.name, field.name]
+ end
+ elsif kwargs.key?(field.name)
+ attrs[field.name] = kwargs.delete(field.name)
+ else
+ attrs[field.name] = field.default
+ end
+ attrs
+ end
+
+ unless kwargs.empty?
+ unexpected = kwargs.keys[0]
+ raise TypeError,
+ "%s() got an unexpected keyword argument '%s'" %
+ [type.name, unexpected]
+ end
+
+ attrs[:st_type] = type
+ attrs[:id] = nil
+
+ name = "Qpid_" + type.name.to_s.capitalize
+ unless ::Struct.const_defined?(name)
+ vars = type.fields.collect { |f| f.name } << :st_type << :id
+ ::Struct.new(name, *vars)
+ end
+ st = ::Struct.const_get(name)
+
+ result = st.new
+ attrs.each { |k, v| result[k] = v }
+ return result
+ end
+
+ class Message
+
+ attr_accessor :headers, :body, :id
+
+ def initialize(*args)
+ @body = nil
+ @headers = nil
+
+ @body = args.pop unless args.empty?
+ @headers = args unless args.empty?
+
+ @id = nil
+ end
+
+ def has(name)
+ return ! get(name).nil?
+ end
+
+ def get(name)
+ if @headers
+ name = name.to_sym
+ @headers.find { |h| h.st_type.name == name }
+ end
+ end
+
+ def set(header)
+ @headers ||= []
+ if h = @headers.find { |h| h.st_type == header.st_type }
+ ind = @headers.index(h)
+ @headers[ind] = header
+ else
+ @headers << header
+ end
+ end
+
+ def clear(name)
+ if @headers
+ name = name.to_sym
+ @headers.delete_if { |h| h.st_type.name == name }
+ end
+ end
+
+ # FIXME: Not sure what to do here
+ # Ruby doesn't have a notion of a evaluable string representation
+ # def __repr__(self):
+ # args = []
+ # if self.headers:
+ # args.extend(map(repr, self.headers))
+ # if self.body:
+ # args.append(repr(self.body))
+ # if self.id is not None:
+ # args.append("id=%s" % self.id)
+ # return "Message(%s)" % ", ".join(args)
+ # end
+ end
+
+ class ::Object
+
+ def to_serial
+ Qpid::Serial.new(self)
+ end
+ end
+
+ class Serial
+
+ include Comparable
+
+ attr_accessor :value
+
+ def initialize(value)
+ @value = value & 0xFFFFFFFF
+ end
+
+ def hash
+ @value.hash
+ end
+
+ def to_serial
+ self
+ end
+
+ def eql?(other)
+ other = other.to_serial
+ value.eql?(other.value)
+ end
+
+ def <=>(other)
+ return 1 if other.nil?
+
+ other = other.to_serial
+
+ delta = (value - other.value) & 0xFFFFFFFF
+ neg = delta & 0x80000000
+ mag = delta & 0x7FFFFFFF
+
+ return (neg>0) ? -mag : mag
+ end
+
+ def +(other)
+ result = other.to_serial
+ result.value += value
+ return result
+ end
+
+ def -(other)
+ result = other.to_serial
+ result.value = value - result.value
+ return result
+ end
+
+ def succ
+ Serial.new(value + 1)
+ end
+
+ # FIXME: Not sure what to do here
+ # Ruby doesn't have a notion of a evaluable string representation
+ # def __repr__(self):
+ # return "serial(%s)" % self.value
+ # end
+
+ def to_s
+ value.to_s
+ end
+
+ end
+
+ # The Python class datatypes.Range is emulated by the standard
+ # Range class with a few additions
+ class ::Range
+
+ alias :lower :begin
+ alias :upper :end
+
+ def touches(r)
+ # XXX: are we doing more checks than we need?
+ return (r.include?(lower - 1) ||
+ r.include?(upper + 1) ||
+ include?(r.lower - 1) ||
+ include?(r.upper + 1) ||
+ r.include?(lower) ||
+ r.include?(upper) ||
+ include?(r.lower) ||
+ include?(r.upper))
+ end
+
+ def span(r)
+ Range.new([lower, r.lower].min, [upper, r.upper].max)
+ end
+
+ def intersect(r)
+ l = [lower, r.lower].max
+ u = [upper, r.upper].min
+ return l > u ? nil : Range.new(l, u)
+ end
+
+ end
+
+ class RangedSet
+
+ include Enumerable
+
+ attr_accessor :ranges
+
+ def initialize(*args)
+ @ranges = []
+ args.each { |n| add(n) }
+ end
+
+ def each(&block)
+ ranges.each { |r| yield(r) }
+ end
+
+ def include?(n)
+ if (n.is_a?(Range))
+ super(n)
+ else
+ ranges.find { |r| r.include?(n) }
+ end
+ end
+
+ def add_range(range)
+ ranges.delete_if do |r|
+ if range.touches(r)
+ range = range.span(r)
+ true
+ else
+ false
+ end
+ end
+ ranges << range
+ end
+
+ def add(lower, upper = nil)
+ upper = lower if upper.nil?
+ add_range(Range.new(lower, upper))
+ end
+
+ def to_s
+ repr = ranges.sort { |a,b| b.lower <=> a.lower }.
+ map { |r| r.to_s }.join(",")
+ "<RangedSet: {#{repr}}"
+ end
+ end
+
+ class Future
+ def initialize(initial=nil, exception=Exception)
+ @value = initial
+ @error = nil
+ @set = Util::Event.new
+ @exception = exception
+ end
+
+ def error(error)
+ @error = error
+ @set.set
+ end
+
+ def set(value)
+ @value = value
+ @set.set
+ end
+
+ def get(timeout=nil)
+ @set.wait(timeout)
+ unless @error.nil?
+ raise @exception.new(@error)
+ end
+ @value
+ end
+ end
+
+ class UUID
+ include Comparable
+
+ attr_accessor :bytes
+
+ def initialize(bytes)
+ @bytes = bytes
+ end
+
+ def <=>(other)
+ if other.respond_to?(:bytes)
+ return bytes <=> other.bytes
+ else
+ raise NotImplementedError
+ end
+ end
+
+ def to_s
+ UUID::format(bytes)
+ end
+
+ # FIXME: Not sure what to do here
+ # Ruby doesn't have a notion of a evaluable string representation
+ # def __repr__(self):
+ # return "UUID(%r)" % str(self)
+ # end
+
+ def self.random_uuid
+ bytes = (1..16).collect { |i| rand(256) }
+
+ # From RFC4122, the version bits are set to 0100
+ bytes[7] &= 0x0F
+ bytes[7] |= 0x40
+
+ # From RFC4122, the top two bits of byte 8 get set to 01
+ bytes[8] &= 0x3F
+ bytes[8] |= 0x80
+ return bytes.pack("C16")
+ end
+
+ def self.uuid4
+ UUID.new(random_uuid)
+ end
+
+ def self.format(s)
+ # Python format !LHHHHL
+ # big-endian, ulong, ushort x 4, ulong
+ "%08x-%04x-%04x-%04x-%04x%08x" % s.unpack("NnnnnN")
+ end
+ end
+end
diff --git a/qpid/ruby/lib/qpid/delegates.rb b/qpid/ruby/lib/qpid/delegates.rb
new file mode 100644
index 0000000000..f779047e05
--- /dev/null
+++ b/qpid/ruby/lib/qpid/delegates.rb
@@ -0,0 +1,237 @@
+#
+# 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.
+#
+
+require 'rbconfig'
+require 'sasl'
+
+module Qpid
+
+ class Delegate
+
+ def initialize(connection, args={})
+ @connection = connection
+ @spec = connection.spec
+ @delegate = args[:delegate] || Qpid::Delegate::Client.method(:new)
+ @control = @spec[:track].enum[:control].value
+ end
+
+ def log ; Qpid::logger["qpid.io.ctl"]; end
+
+ def received(seg)
+ ssn = @connection.attached[seg.channel]
+ unless ssn
+ ch = Qpid::Connection::Channel.new(@connection, seg.channel)
+ else
+ ch = ssn.channel
+ end
+
+ if seg.track == @control
+ ctl = seg.decode(@spec)
+ log.debug("RECV %s", ctl) if log
+ attr = ctl.st_type.name
+ method(attr).call(ch, ctl)
+ elsif ssn.nil?
+ ch.session_detached
+ else
+ ssn.received(seg)
+ end
+ end
+
+ def connection_close(ch, close)
+ @connection.close_code = [close.reply_code, close.reply_text]
+ ch.connection_close_ok
+ @connection.sock.close_write()
+ unless @connection.opened
+ @connection.failed = true
+ @connection.signal
+ end
+ end
+
+ def connection_close_ok(ch, close_ok)
+ @connection.opened = false
+ @connection.signal
+ end
+
+ def session_attach(ch, a)
+ begin
+ @connection.attach(a.name, ch, @delegate, a.force)
+ ch.session_attached(a.name)
+ rescue Qpid::ChannelBusy
+ ch.session_detached(a.name)
+ rescue Qpid::SessionBusy
+ ch.session_detached(a.name)
+ end
+ end
+
+ def session_attached(ch, a)
+ ch.session.signal
+ end
+
+ def session_detach(ch, d)
+ #send back the confirmation of detachment before removing the
+ #channel from the attached set; this avoids needing to hold the
+ #connection lock during the sending of this control and ensures
+ #that if the channel is immediately reused for a new session the
+ #attach request will follow the detached notification.
+ ch.session_detached(d.name)
+ ssn = @connection.detach(d.name, ch)
+ end
+
+ def session_detached(ch, d)
+ @connection.detach(d.name, ch)
+ end
+
+ def session_request_timeout(ch, rt)
+ ch.session_timeout(rt.timeout)
+ end
+
+ def session_command_point(ch, cp)
+ ssn = ch.session
+ ssn.receiver.next_id = cp.command_id
+ ssn.receiver.next_offset = cp.command_offset
+ end
+
+ def session_completed(ch, cmp)
+ ch.session.sender.has_completed(cmp.commands)
+ if cmp.timely_reply
+ ch.session_known_completed(cmp.commands)
+ end
+ ch.session.signal
+ end
+
+ def session_known_completed(ch, kn_cmp)
+ ch.session.receiver.known_completed(kn_cmp.commands)
+ end
+
+ def session_flush(ch, f)
+ rcv = ch.session.receiver
+ if f.expected
+ if rcv.next_id
+ exp = Qpid::RangedSet.new(rcv.next_id)
+ else
+ exp = nil
+ end
+ ch.session_expected(exp)
+ end
+ if f.confirmed
+ ch.session_confirmed(rcv.completed)
+ end
+ if f.completed
+ ch.session_completed(rcv.completed)
+ end
+ end
+
+ class Server < Delegate
+
+ def start
+ @connection.read_header()
+ @connection.write_header(@spec.major, @spec.minor)
+ ch = Qpid::Connection::Channel.new(@connection, 0)
+ ch.connection_start(:mechanisms => ["ANONYMOUS"])
+ ch
+ end
+
+ def connection_start_ok(ch, start_ok)
+ ch.connection_tune(:channel_max => 65535)
+ end
+
+ def connection_tune_ok(ch, tune_ok)
+ nil
+ end
+
+ def connection_open(ch, open)
+ @connection.opened = true
+ ch.connection_open_ok()
+ @connection.signal
+ end
+ end
+
+ class Client < Delegate
+
+ # FIXME: Python uses os.name for platform - we don't have an exact
+ # analog in Ruby
+ PROPERTIES = {"product" => "qpid python client",
+ "version" => "development",
+ "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)
+ super(connection)
+
+ result = Sasl::client_init
+
+ @mechanism= args[:mechanism]
+ @username = args[:username]
+ @password = args[:password]
+ @service = args[:service] || "qpidd"
+ @min_ssf = args[:min_ssf] || 0
+ @max_ssf = args[:max_ssf] || 65535
+
+ @saslConn = Sasl.client_new(@mechanism, @service, args[:host],
+ @username, @password, @min_ssf, @max_ssf)
+ end
+
+ def start
+ @connection.write_header(@spec.major, @spec.minor)
+ @connection.read_header
+ end
+
+ def connection_start(ch, start)
+ mech_list = ""
+ start.mechanisms.each do |m|
+ mech_list += m + " "
+ end
+ begin
+ resp = Sasl.client_start(@saslConn, mech_list)
+ @connection.user_id = Sasl.user_id(@saslConn)
+ ch.connection_start_ok(:client_properties => PROPERTIES,
+ :mechanism => resp[2],
+ :response => resp[1])
+ rescue exception
+ ch.connection_close(:message => $!.message)
+ @connection.failed = true
+ @connection.signal
+ end
+ end
+
+ def connection_secure(ch, secure)
+ resp = Sasl.client_step(@saslConn, secure.challenge)
+ @connection.user_id = Sasl.user_id(@saslConn)
+ ch.connection_secure_ok(:response => resp[1])
+ end
+
+ def connection_tune(ch, tune)
+ ch.connection_tune_ok(:channel_max => tune.channel_max,
+ :max_frame_size => tune.max_frame_size,
+ :heartbeat => 0)
+ ch.connection_open()
+ @connection.security_layer_tx = @saslConn
+ end
+
+ def connection_open_ok(ch, open_ok)
+ @connection.security_layer_rx = @saslConn
+ @connection.opened = true
+ @connection.signal
+ end
+ end
+ end
+end
diff --git a/qpid/ruby/lib/qpid/fields.rb b/qpid/ruby/lib/qpid/fields.rb
new file mode 100644
index 0000000000..cc87d07529
--- /dev/null
+++ b/qpid/ruby/lib/qpid/fields.rb
@@ -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.
+#
+
+class Class
+ def fields(*fields)
+ module_eval {
+ def initialize(*args, &block)
+ args = init_fields(*args)
+
+ if respond_to? :init
+ init(*args) {|*a| yield(*a)}
+ elsif args.any?
+ raise ArgumentError, "extra arguments: #{args.inspect}"
+ end
+ end
+ }
+
+ vars = fields.map {|f| :"@#{f.to_s().chomp("?")}"}
+
+ define_method(:init_fields) {|*args|
+ vars.each {|v|
+ instance_variable_set(v, args.shift())
+ }
+ args
+ }
+
+ vars.each_index {|i|
+ define_method(fields[i]) {
+ instance_variable_get(vars[i])
+ }
+ }
+ end
+end
diff --git a/qpid/ruby/lib/qpid/framer.rb b/qpid/ruby/lib/qpid/framer.rb
new file mode 100644
index 0000000000..d057605383
--- /dev/null
+++ b/qpid/ruby/lib/qpid/framer.rb
@@ -0,0 +1,212 @@
+#
+# 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.
+#
+
+require 'monitor'
+require 'logger'
+require 'sasl'
+
+module Qpid
+
+ FIRST_SEG = 0x08
+ LAST_SEG = 0x04
+ FIRST_FRM = 0x02
+ LAST_FRM = 0x01
+
+ class << self
+ attr_accessor :raw_logger, :frm_logger
+ end
+
+ def self.packed_size(format)
+ # FIXME: This is a total copout to simulate Python's
+ # struct.calcsize
+ ([0]*256).pack(format).size
+ end
+
+ class Frame
+ attr_reader :payload, :track, :flags, :type, :channel
+
+ # HEADER = "!2BHxBH4x"
+ # Python Meaning Ruby
+ # ! big endian (implied by format char)
+ # 2B 2 uchar C2
+ # H unsigned short n
+ # x pad byte x
+ # B uchar C
+ # H unsigned short n
+ # 4x pad byte x4
+ HEADER = "C2nxCnx4"
+ HEADER_SIZE = Qpid::packed_size(HEADER)
+ MAX_PAYLOAD = 65535 - HEADER_SIZE
+
+ def initialize(flags, type, track, channel, payload)
+ if payload.size > MAX_PAYLOAD
+ raise ArgumentError, "max payload size exceeded: #{payload.size}"
+ end
+
+ @flags = flags
+ @type = type
+ @track = track
+ @channel = channel
+ @payload = payload
+ end
+
+ def first_segment? ; FIRST_SEG & @flags > 0 ; end
+
+ def last_segment? ; LAST_SEG & @flags > 0 ; end
+
+ def first_frame? ; FIRST_FRM & @flags > 0 ; end
+
+ def last_frame? ; LAST_FRM & @flags > 0 ; end
+
+ def to_s
+ fs = first_segment? ? 'S' : '.'
+ ls = last_segment? ? 's' : '.'
+ ff = first_frame? ? 'F' : '.'
+ lf = last_frame? ? 'f' : '.'
+
+ return "%s%s%s%s %s %s %s %s" % [fs, ls, ff, lf,
+ @type,
+ @track,
+ @channel,
+ @payload.inspect]
+ end
+ end
+
+ class FramingError < Exception ; end
+
+ class Closed < Exception ; end
+
+ class Framer
+ include Packer
+
+ # Python: "!4s4B"
+ HEADER = "a4C4"
+ HEADER_SIZE = 8
+
+ def raw
+ Qpid::raw_logger
+ end
+
+ def frm
+ Qpid::frm_logger
+ end
+
+ def initialize(sock)
+ @sock = sock
+ @sock.extend(MonitorMixin)
+ @tx_buf = ""
+ @rx_buf = ""
+ @security_layer_tx = nil
+ @security_layer_rx = nil
+ @maxbufsize = 65535
+ end
+
+ attr_reader :sock
+ attr_accessor :security_layer_tx, :security_layer_rx
+
+ def aborted? ; false ; end
+
+ def write(buf)
+ @tx_buf += buf
+ end
+
+ def flush
+ @sock.synchronize do
+ if @security_layer_tx
+ cipher_buf = Sasl.encode(@security_layer_tx, @tx_buf)
+ _write(cipher_buf)
+ else
+ _write(@tx_buf)
+ end
+ @tx_buf = ""
+ frm.debug("FLUSHED") if frm
+ end
+ rescue
+ @sock.close unless @sock.closed?
+ end
+
+ def _write(buf)
+ while buf && buf.size > 0
+ # FIXME: Catch errors
+ n = @sock.write(buf)
+ raw.debug("SENT #{buf[0, n].inspect}") if raw
+ buf[0,n] = ""
+ @sock.flush
+ end
+ end
+
+ def read(n)
+ while @rx_buf.size < n
+ begin
+ s = @sock.recv(@maxbufsize)
+ if @security_layer_rx
+ s = Sasl.decode(@security_layer_rx, s)
+ end
+ rescue IOError => e
+ raise e if @rx_buf != ""
+ @sock.close unless @sock.closed?
+ raise Closed
+ end
+ # FIXME: Catch errors
+ if s.nil? or s.size == 0
+ @sock.close unless @sock.closed?
+ raise Closed
+ end
+ @rx_buf += s
+ raw.debug("RECV #{n}/#{@rx_buf.size} #{s.inspect}") if raw
+ end
+ data = @rx_buf[0, n]
+ @rx_buf = @rx_buf[n, @rx_buf.size - n]
+ return data
+ end
+
+ def read_header
+ unpack(Framer::HEADER, Framer::HEADER_SIZE)
+ end
+
+ def write_header(major, minor)
+ @sock.synchronize do
+ pack(Framer::HEADER, "AMQP", 1, 1, major, minor)
+ flush()
+ end
+ end
+
+ def write_frame(frame)
+ @sock.synchronize do
+ size = frame.payload.size + Frame::HEADER_SIZE
+ track = frame.track & 0x0F
+ pack(Frame::HEADER, frame.flags, frame.type, size, track, frame.channel)
+ write(frame.payload)
+ if frame.last_segment? and frame.last_frame?
+ flush()
+ frm.debug("SENT #{frame}") if frm
+ end
+ end
+ end
+
+ def read_frame
+ flags, type, size, track, channel = unpack(Frame::HEADER, Frame::HEADER_SIZE)
+ raise FramingError if (flags & 0xF0 > 0)
+ payload = read(size - Frame::HEADER_SIZE)
+ frame = Frame.new(flags, type, track, channel, payload)
+ frm.debug("RECV #{frame}") if frm
+ return frame
+ end
+ end
+end
diff --git a/qpid/ruby/lib/qpid/invoker.rb b/qpid/ruby/lib/qpid/invoker.rb
new file mode 100644
index 0000000000..39716ac6c2
--- /dev/null
+++ b/qpid/ruby/lib/qpid/invoker.rb
@@ -0,0 +1,65 @@
+#
+# 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.
+#
+
+class Qpid::Invoker
+
+ # Requires that client defines a invoke method and overrides
+ # resolve_method
+
+ # FIXME: Is it really worth defining methods in method_missing ? We
+ # could just dispatch there directly
+
+ def invc_method(name, resolved)
+ define_singleton_method(name) { |*args| invoke(resolved, args) }
+ # FIXME: the Python code also attaches docs from resolved.pydoc
+ end
+
+ def invc_value(name, resolved)
+ define_singleton_method(name) { | | resolved }
+ end
+
+ def invc_error(name, resolved)
+ msg = "%s instance has no attribute '%s'" % [self.class.name, name]
+ if resolved
+ msg += "\n%s" % resolved
+ end
+ raise NameError, msg
+ end
+
+ def resolve_method(name)
+ invocation(:error, nil)
+ end
+
+ def method_missing(name, *args)
+ disp, resolved = resolve_method(name)
+ disp.call(name, resolved)
+ send(name, *args)
+ end
+
+ def invocation(kind, name = nil)
+ [ method("invc_#{kind}"), name ]
+ end
+
+ private
+ def define_singleton_method(name, &body)
+ singleton_class = class << self; self; end
+ singleton_class.send(:define_method, name, &body)
+ end
+
+end
diff --git a/qpid/ruby/lib/qpid/packer.rb b/qpid/ruby/lib/qpid/packer.rb
new file mode 100644
index 0000000000..ae1be37faf
--- /dev/null
+++ b/qpid/ruby/lib/qpid/packer.rb
@@ -0,0 +1,33 @@
+#
+# 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.
+#
+
+module Qpid
+ module Packer
+ def unpack(fmt, len)
+ raw = read(len)
+ values = raw.unpack(fmt)
+ values = values[0] if values.size == 1
+ return values
+ end
+
+ def pack(fmt, *args)
+ write(args.pack(fmt))
+ end
+ end
+end
diff --git a/qpid/ruby/lib/qpid/peer.rb b/qpid/ruby/lib/qpid/peer.rb
new file mode 100644
index 0000000000..cdb962169b
--- /dev/null
+++ b/qpid/ruby/lib/qpid/peer.rb
@@ -0,0 +1,289 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+require "thread"
+require "qpid/queue"
+require "qpid/connection08"
+require "qpid/fields"
+
+module Qpid08
+
+ Queue = Qpid::Queue
+
+ class Peer
+
+ def initialize(conn, delegate)
+ @conn = conn
+ @delegate = delegate
+ @outgoing = Queue.new()
+ @work = Queue.new()
+ @channels = {}
+ @mutex = Mutex.new()
+ end
+
+ def channel(id)
+ @mutex.synchronize do
+ ch = @channels[id]
+ if ch.nil?
+ ch = Channel.new(id, self, @outgoing, @conn.spec)
+ @channels[id] = ch
+ end
+ return ch
+ end
+ end
+
+ def channel_delete(id)
+ @channels.delete(id)
+ end
+
+ def start()
+ spawn(:writer)
+ spawn(:reader)
+ spawn(:worker)
+ end
+
+ def close()
+ @mutex.synchronize do
+ @channels.each_value do |ch|
+ ch.close()
+ end
+ @outgoing.close()
+ @work.close()
+ end
+ end
+
+ private
+
+ def spawn(method, *args)
+ Thread.new do
+ begin
+ send(method, *args)
+ # is this the standard way to catch any exception?
+ rescue Closed => e
+ puts "#{method} #{e}"
+ rescue Object => e
+ print e
+ e.backtrace.each do |line|
+ print "\n ", line
+ end
+ print "\n"
+ end
+ end
+ end
+
+ def reader()
+ while true
+ frame = @conn.read()
+ ch = channel(frame.channel)
+ ch.dispatch(frame, @work)
+ end
+ end
+
+ def writer()
+ while true
+ @conn.write(@outgoing.get())
+ end
+ end
+
+ def worker()
+ while true
+ dispatch(@work.get())
+ end
+ end
+
+ def dispatch(queue)
+ frame = queue.get()
+ ch = channel(frame.channel)
+ payload = frame.payload
+ if payload.method.content?
+ content = Qpid08::read_content(queue)
+ else
+ content = nil
+ end
+
+ message = Message.new(payload.method, payload.args, content)
+ @delegate.dispatch(ch, message)
+ end
+
+ end
+
+ class Channel
+ def initialize(id, peer, outgoing, spec)
+ @id = id
+ @peer = peer
+ @outgoing = outgoing
+ @spec = spec
+ @incoming = Queue.new()
+ @responses = Queue.new()
+ @queue = nil
+ @closed = false
+ end
+
+ attr_reader :id
+
+ def closed?; @closed end
+
+ def close()
+ return if closed?
+ @peer.channel_delete(@id)
+ @closed = true
+ @incoming.close()
+ @responses.close()
+ end
+
+ def dispatch(frame, work)
+ payload = frame.payload
+ case payload
+ when Method
+ if payload.method.response?
+ @queue = @responses
+ else
+ @queue = @incoming
+ work << @incoming
+ end
+ end
+ @queue << frame
+ end
+
+ def method_missing(name, *args)
+ method = @spec.find_method(name)
+ if method.nil?
+ raise NoMethodError.new("undefined method '#{name}' for #{self}:#{self.class}")
+ end
+
+ if args.size == 1 and args[0].instance_of? Hash
+ kwargs = args[0]
+ invoke_args = method.fields.map do |f|
+ kwargs[f.name]
+ end
+ content = kwargs[:content]
+ else
+ invoke_args = []
+ method.fields.each do |f|
+ if args.any?
+ invoke_args << args.shift()
+ else
+ invoke_args << f.default
+ end
+ end
+ if method.content? and args.any?
+ content = args.shift()
+ else
+ content = nil
+ end
+ if args.any? then raise ArgumentError.new("#{args.size} extr arguments") end
+ end
+ return invoke(method, invoke_args, content)
+ end
+
+ def invoke(method, args, content = nil)
+ raise Closed() if closed?
+ frame = Frame.new(@id, Method.new(method, args))
+ @outgoing << frame
+
+ if method.content?
+ content = Content.new() if content.nil?
+ write_content(method.parent, content, @outgoing)
+ end
+
+ nowait = false
+ f = method.fields[:"nowait"]
+ nowait = args[method.fields.index(f)] unless f.nil?
+
+ unless nowait or method.responses.empty?
+ resp = @responses.get().payload
+ if resp.method.content?
+ content = read_content(@responses)
+ else
+ content = nil
+ end
+ if method.responses.include? resp.method
+ return Message.new(resp.method, resp.args, content)
+ else
+ # XXX: ValueError doesn't actually exist
+ raise ValueError.new(resp)
+ end
+ end
+ end
+
+ def write_content(klass, content, queue)
+ size = content.size
+ header = Frame.new(@id, Header.new(klass, content.weight, size, content.headers))
+ queue << header
+ content.children.each {|child| write_content(klass, child, queue)}
+ queue << Frame.new(@id, Body.new(content.body)) if size > 0
+ end
+
+ end
+
+ def Qpid08.read_content(queue)
+ frame = queue.get()
+ header = frame.payload
+ children = []
+ 1.upto(header.weight) { children << read_content(queue) }
+ size = header.size
+ read = 0
+ buf = ""
+ while read < size
+ body = queue.get()
+ content = body.payload.content
+ buf << content
+ read += content.size
+ end
+ buf.freeze()
+ return Content.new(header.properties.clone(), buf, children)
+ end
+
+ class Content
+ def initialize(headers = {}, body = "", children = [])
+ @headers = headers
+ @body = body
+ @children = children
+ end
+
+ attr_reader :headers, :body, :children
+
+ def size; body.size end
+ def weight; children.size end
+
+ def [](key); @headers[key] end
+ def []=(key, value); @headers[key] = value end
+ end
+
+ class Message
+ fields(:method, :args, :content)
+
+ alias fields args
+
+ def method_missing(name)
+ return args[@method.fields[name].id]
+ end
+
+ def inspect()
+ "#{method.qname}(#{args.join(", ")})"
+ end
+ end
+
+ module Delegate
+ def dispatch(ch, msg)
+ send(msg.method.qname, ch, msg)
+ end
+ end
+
+end
diff --git a/qpid/ruby/lib/qpid/qmf.rb b/qpid/ruby/lib/qpid/qmf.rb
new file mode 100644
index 0000000000..4711d355cd
--- /dev/null
+++ b/qpid/ruby/lib/qpid/qmf.rb
@@ -0,0 +1,1957 @@
+# 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.
+#
+
+# Console API for Qpid Management Framework
+
+require 'socket'
+require 'monitor'
+require 'thread'
+require 'uri'
+require 'time'
+
+module Qpid::Qmf
+
+ # To access the asynchronous operations, a class must be derived from
+ # Console with overrides of any combination of the available methods.
+ class Console
+
+ # Invoked when a connection is established to a broker
+ def broker_connected(broker); end
+
+ # Invoked when the connection to a broker is lost
+ def broker_disconnected(broker); end
+
+ # Invoked when a QMF package is discovered
+ def new_package(name); end
+
+ # Invoked when a new class is discovered. Session.getSchema can be
+ # used to obtain details about the class
+ def new_class(kind, klass_key); end
+
+ # Invoked when a QMF agent is discovered
+ def new_agent(agent); end
+
+ # Invoked when a QMF agent disconects
+ def del_agent(agent); end
+
+ # Invoked when an object is updated
+ def object_props(broker, record); end
+
+ # Invoked when an object is updated
+ def object_stats(broker, record); end
+
+ # Invoked when an event is raised
+ def event(broker, event); end
+
+ # Invoked when an agent heartbeat is received.
+ def heartbeat(agent, timestamp); end
+
+ # Invoked when the connection sequence reaches the point where broker information is available.
+ def broker_info(broker); end
+
+ # Invoked when a method response from an asynchronous method call is received.
+ def method_response(broker, seq, response); end
+ end
+
+ class BrokerURL
+
+ attr_reader :host, :port, :auth_name, :auth_pass
+
+ def initialize(text)
+ uri = URI.parse(text)
+
+ @host = uri.host
+ @port = uri.port ? uri.port : 5672
+ @auth_name = uri.user
+ @auth_pass = uri.password
+
+ return uri
+ end
+
+ def name
+ "#{@host}:#{@port}"
+ end
+
+ def match(host, port)
+ # FIXME: Unlcear what the Python code is actually checking for
+ # here, especially since HOST can resolve to multiple IP's
+ @port == port &&
+ (host == @host || ipaddr(host, port) == ipaddr(@host, @port))
+ end
+
+ private
+ def ipaddr(host, port)
+ s = Socket::getaddrinfo(host, port,
+ Socket::AF_INET, Socket::SOCK_STREAM)
+ s[0][2]
+ end
+ end
+
+ # An instance of the Session class represents a console session running
+ # against one or more QMF brokers. A single instance of Session is
+ # needed to interact with the management framework as a console.
+ class Session
+ CONTEXT_SYNC = 1
+ CONTEXT_STARTUP = 2
+ CONTEXT_MULTIGET = 3
+
+ DEFAULT_GET_WAIT_TIME = 60
+
+ include MonitorMixin
+
+ attr_reader :binding_key_list, :select, :seq_mgr, :console, :packages
+
+ # Initialize a session. If the console argument is provided, the
+ # more advanced asynchronous features are available. If console is
+ # defaulted, the session will operate in a simpler, synchronous
+ # manner. The rcvObjects, rcvEvents, and rcvHeartbeats arguments
+ # are meaningful only if 'console' is provided. They control
+ # whether object updates, events, and agent-heartbeats are
+ # subscribed to. If the console is not interested in receiving one
+ # or more of the above, setting the argument to False will reduce
+ # tha bandwidth used by the API. If manageConnections is set to
+ # True, the Session object will manage connections to the brokers.
+ # This means that if a broker is unreachable, it will retry until a
+ # connection can be established. If a connection is lost, the
+ # Session will attempt to reconnect.
+ #
+ # If manageConnections is set to False, the user is responsible for
+ # handing failures. In this case, an unreachable broker will cause
+ # addBroker to raise an exception. If userBindings is set to False
+ # (the default) and rcvObjects is True, the console will receive
+ # data for all object classes. If userBindings is set to True, the
+ # user must select which classes the console shall receive by
+ # invoking the bindPackage or bindClass methods. This allows the
+ # console to be configured to receive only information that is
+ # relavant to a particular application. If rcvObjects id False,
+ # userBindings has no meaning.
+ #
+ # Accept a hash of parameters, where keys can be :console,
+ # :rcv_objects, :rcv_events, :rcv_heartbeats, :manage_connections,
+ # and :user_bindings
+ def initialize(kwargs = {})
+ super()
+ @console = kwargs[:console] || nil
+ @brokers = []
+ @packages = {}
+ @seq_mgr = SequenceManager.new
+ @cv = new_cond
+ @sync_sequence_list = []
+ @result = []
+ @select = []
+ @error = nil
+ @rcv_objects = kwargs[:rcv_objects] == nil ? true : kwargs[:rcv_objects]
+ @rcv_events = kwargs[:rcv_events] == nil ? true : kwargs[:rcv_events]
+ @rcv_heartbeats = kwargs[:rcv_heartbeats] == nil ? true : kwargs[:rcv_heartbeats]
+ @user_bindings = kwargs[:user_bindings] == nil ? false : kwargs[:user_bindings]
+ unless @console
+ @rcv_objects = false
+ @rcv_events = false
+ @rcv_heartbeats = false
+ end
+ @binding_key_list = binding_keys
+ @manage_connections = kwargs[:manage_connections] || false
+
+ if @user_bindings && ! @rcv_objects
+ raise ArgumentError, "user_bindings can't be set unless rcv_objects is set and a console is provided"
+ end
+
+ end
+
+ def to_s
+ "QMF Console Session Manager (brokers: #{@brokers.size})"
+ end
+
+ def managedConnections?
+ return @manage_connections
+ end
+
+ # Connect to a Qpid broker. Returns an object of type Broker
+ #
+ # To supply a username for authentication, use the URL syntax:
+ #
+ # amqp://username@hostname:port
+ #
+ # If the broker needs a password for the client, an interactive prompt will be
+ # provided to the user.
+ #
+ # To supply a username and a password, use
+ #
+ # amqp://username:password@hostname:port
+ #
+ # The following keyword arguments may be used to control authentication:
+ #
+ # :mechanism - SASL mechanism (i.e. "PLAIN", "GSSAPI", "ANONYMOUS", etc.
+ # - defaults to unspecified (the system chooses for you)
+ # :service - SASL service name (i.e. the kerberos principal of the broker)
+ # - defaults to "qpidd"
+ # :min_ssf - Minimum Security Strength Factor for SASL security layers
+ # - defaults to 0
+ # :max_ssf - Maximum Security Strength Factor for SASL security layers
+ # - defaults to 65535
+ #
+ def add_broker(target = "amqp://localhost", kwargs = {})
+ url = BrokerURL.new(target)
+ broker = Broker.new(self, url.host, url.port, url.auth_name, url.auth_pass, kwargs)
+ unless broker.connected? || @manage_connections
+ raise broker.error
+ end
+
+ @brokers << broker
+ objects(:broker => broker, :class => "agent") unless @manage_connections
+ return broker
+ end
+
+ # Disconnect from a broker. The 'broker' argument is the object
+ # returned from the addBroker call
+ def del_broker(broker)
+ broker.shutdown
+ @brokers.delete(broker)
+ end
+
+ # Get the list of known classes within a QMF package
+ def classes(package_name)
+ list = []
+ @brokers.each { |broker| broker.wait_for_stable }
+ if @packages.include?(package_name)
+ # FIXME What's the actual structure of @packages[package_name]
+ @packages[package_name].each do |key, schema_class|
+ list << schema_class.klass_key
+ end
+ end
+ return list
+ end
+
+ # Get the schema for a QMF class
+ def schema(klass_key)
+ @brokers.each { |broker| broker.wait_for_stable }
+ if @packages.include?(klass_key.package)
+ @packages[klass_key.package][ [klass_key.klass_name, klass_key.hash] ]
+ end
+ end
+
+ def bind_package(package_name)
+ unless @user_bindings && @rcv_objects
+ raise "userBindings option not set for Session"
+ end
+ @brokers.each do |broker|
+ args = { :exchange => "qpid.management",
+ :queue => broker.topic_name,
+ :binding_key => "console.obj.*.*.#{package_name}.#" }
+ broker.amqp_session.exchange_bind(args)
+ end
+ end
+
+ def bind_class(package_name, class_name)
+ unless @user_bindings && @rcv_objects
+ raise "userBindings option not set for Session"
+ end
+ @brokers.each do |broker|
+ args = { :exchange => "qpid.management",
+ :queue => broker.topic_name,
+ :binding_key=> "console.obj.*.*.#{package_name}.#{class_name}.#" }
+ broker.amqp_session.exchange_bind(args)
+ end
+ end
+
+ def bind_class_key(klass_key)
+ unless @user_bindings && @rcv_objects
+ raise "userBindings option not set for Session"
+ end
+ pname, cname, hash = klass_key.to_a()
+ @brokers.each do |broker|
+ args = { :exchange => "qpid.management",
+ :queue => broker.topic_name,
+ :binding_key => "console.obj.*.*.#{pname}.#{cname}.#" }
+ broker.amqp_session.exchange_bind(args)
+ end
+ end
+
+ # Get a list of currently known agents
+ def agents(broker=nil)
+ broker_list = []
+ if broker.nil?
+ broker_list = @brokers.dup
+ else
+ broker_list << broker
+ end
+ broker_list.each { |b| b.wait_for_stable }
+ agent_list = []
+ broker_list.each { |b| agent_list += b.agents }
+ return agent_list
+ end
+
+ # Get a list of objects from QMF agents.
+ # All arguments are passed by name(keyword).
+ #
+ # The class for queried objects may be specified in one of the
+ # following ways:
+ # :schema => <schema> - supply a schema object returned from getSchema.
+ # :key => <key> - supply a klass_key from the list returned by getClasses.
+ # :class => <name> - supply a class name as a string. If the class name exists
+ # in multiple packages, a _package argument may also be supplied.
+ # :object_id = <id> - get the object referenced by the object-id
+ #
+ # If objects should be obtained from only one agent, use the following argument.
+ # Otherwise, the query will go to all agents.
+ #
+ # :agent = <agent> - supply an agent from the list returned by getAgents.
+ #
+ # If the get query is to be restricted to one broker (as opposed to
+ # all connected brokers), add the following argument:
+ #
+ # :broker = <broker> - supply a broker as returned by addBroker.
+ #
+ # The default timeout for this synchronous operation is 60 seconds. To change the timeout,
+ # use the following argument:
+ #
+ # :timeout = <time in seconds>
+ #
+ # If additional arguments are supplied, they are used as property
+ # selectors, as long as their keys are strings. For example, if
+ # the argument "name" => "test" is supplied, only objects whose
+ # "name" property is "test" will be returned in the result.
+ def objects(kwargs)
+ if kwargs.include?(:broker)
+ broker_list = []
+ broker_list << kwargs[:broker]
+ else
+ broker_list = @brokers
+ end
+ broker_list.each { |broker|
+ broker.wait_for_stable
+ if kwargs[:package] != "org.apache.qpid.broker" or kwargs[:class] != "agent"
+ objects(:agent => broker.agent(1,0), :package => "org.apache.qpid.broker", :class => "agent") if broker.connected?
+ end
+ }
+
+ agent_list = []
+ if kwargs.include?(:agent)
+ agent = kwargs[:agent]
+ unless broker_list.include?(agent.broker)
+ raise ArgumentError, "Supplied agent is not accessible through the supplied broker"
+ end
+ agent_list << agent if agent.broker.connected?
+ else
+ if kwargs.include?(:object_id)
+ oid = kwargs[:object_id]
+ broker_list.each { |broker|
+ broker.agents.each { |agent|
+ if oid.broker_bank == agent.broker_bank && oid.agent_bank == agent.agent_bank
+ agent_list << agent if agent.broker.connected?
+ end
+ }
+ }
+ else
+ broker_list.each { |broker|
+ agent_list += broker.agents if broker.connected?
+ }
+ end
+ end
+
+ cname = nil
+ if kwargs.include?(:schema)
+ # FIXME: What kind of object is kwargs[:schema]
+ pname, cname, hash = kwargs[:schema].getKey().to_a
+ elsif kwargs.include?(:key)
+ pname, cname, hash = kwargs[:key].to_a
+ elsif kwargs.include?(:class)
+ pname, cname, hash = [kwargs[:package], kwargs[:class], nil]
+ end
+ if cname.nil? && ! kwargs.include?(:object_id)
+ raise ArgumentError,
+ "No class supplied, use :schema, :key, :class, or :object_id' argument"
+ end
+
+ map = {}
+ @select = []
+ if kwargs.include?(:object_id)
+ map["_objectid"] = kwargs[:object_id].to_s
+ else
+ map["_class"] = cname
+ map["_package"] = pname if pname
+ map["_hash"] = hash if hash
+ kwargs.each do |k,v|
+ @select << [k, v] if k.is_a?(String)
+ end
+ end
+
+ @result = []
+ agent_list.each do |agent|
+ broker = agent.broker
+ send_codec = Qpid::StringCodec.new(broker.conn.spec)
+ seq = nil
+ synchronize do
+ seq = @seq_mgr.reserve(CONTEXT_MULTIGET)
+ @sync_sequence_list << seq
+ end
+ broker.set_header(send_codec, ?G, seq)
+ send_codec.write_map(map)
+ bank_key = "%d.%d" % [broker.broker_bank, agent.agent_bank]
+ smsg = broker.message(send_codec.encoded, "agent.#{bank_key}")
+ broker.emit(smsg)
+ end
+
+ timeout = false
+ if kwargs.include?(:timeout)
+ wait_time = kwargs[:timeout]
+ else
+ wait_time = DEFAULT_GET_WAIT_TIME
+ end
+ synchronize do
+ unless @cv.wait_for(wait_time) { @sync_sequence_list.empty? || @error }
+ @sync_sequence_list.each do |pending_seq|
+ @seq_mgr.release(pending_seq)
+ end
+ @sync_sequence_list = []
+ timeout = true
+ end
+ end
+
+ if @error
+ errorText = @error
+ @error = nil
+ raise errorText
+ end
+
+ if @result.empty? && timeout
+ raise "No agent responded within timeout period"
+ end
+ @result
+ end
+
+ # Return one and only one object or nil.
+ def object(kwargs)
+ objs = objects(kwargs)
+ return objs.length == 1 ? objs[0] : nil
+ end
+
+ # Return the first of potentially many objects.
+ def first_object(kwargs)
+ objs = objects(kwargs)
+ return objs.length > 0 ? objs[0] : nil
+ end
+
+ def set_event_filter(kwargs); end
+
+ def handle_broker_connect(broker); end
+
+ def handle_broker_resp(broker, codec, seq)
+ broker.broker_id = codec.read_uuid
+ @console.broker_info(broker) if @console
+
+ # Send a package request
+ # (effectively inc and dec outstanding by not doing anything)
+ send_codec = Qpid::StringCodec.new(broker.conn.spec)
+ seq = @seq_mgr.reserve(CONTEXT_STARTUP)
+ broker.set_header(send_codec, ?P, seq)
+ smsg = broker.message(send_codec.encoded)
+ broker.emit(smsg)
+ end
+
+ def handle_package_ind(broker, codec, seq)
+ pname = codec.read_str8
+ new_package = false
+ synchronize do
+ new_package = ! @packages.include?(pname)
+ @packages[pname] = {} if new_package
+ end
+ @console.new_package(pname) if @console
+
+ # Send a class request
+ broker.inc_outstanding
+ send_codec = Qpid::StringCodec.new(broker.conn.spec)
+ seq = @seq_mgr.reserve(CONTEXT_STARTUP)
+ broker.set_header(send_codec, ?Q, seq)
+ send_codec.write_str8(pname)
+ smsg = broker.message(send_codec.encoded)
+ broker.emit(smsg)
+ end
+
+ def handle_command_complete(broker, codec, seq)
+ code = codec.read_uint32
+ text = codec.read_str8
+ context = @seq_mgr.release(seq)
+ if context == CONTEXT_STARTUP
+ broker.dec_outstanding
+ elsif context == CONTEXT_SYNC && seq == broker.sync_sequence
+ broker.sync_done
+ elsif context == CONTEXT_MULTIGET && @sync_sequence_list.include?(seq)
+ synchronize do
+ @sync_sequence_list.delete(seq)
+ @cv.signal if @sync_sequence_list.empty?
+ end
+ end
+ end
+
+ def handle_class_ind(broker, codec, seq)
+ kind = codec.read_uint8
+ classKey = ClassKey.new(codec)
+ unknown = false
+
+ synchronize do
+ return unless @packages.include?(classKey.package)
+ unknown = true unless @packages[classKey.package].include?([classKey.klass_name, classKey.hash])
+ end
+
+
+ if unknown
+ # Send a schema request for the unknown class
+ broker.inc_outstanding
+ send_codec = Qpid::StringCodec.new(broker.conn.spec)
+ seq = @seq_mgr.reserve(CONTEXT_STARTUP)
+ broker.set_header(send_codec, ?S, seq)
+ classKey.encode(send_codec)
+ smsg = broker.message(send_codec.encoded)
+ broker.emit(smsg)
+ end
+ end
+
+ def handle_method_resp(broker, codec, seq)
+ code = codec.read_uint32
+ text = codec.read_str16
+ out_args = {}
+ pair = @seq_mgr.release(seq)
+ return unless pair
+ method, synchronous = pair
+ if code == 0
+ method.arguments.each do |arg|
+ if arg.dir.index(?O)
+ out_args[arg.name] = decode_value(codec, arg.type)
+ end
+ end
+ end
+ result = MethodResult.new(code, text, out_args)
+ if synchronous:
+ broker.synchronize do
+ broker.sync_result = MethodResult.new(code, text, out_args)
+ broker.sync_done
+ end
+ else
+ @console.method_response(broker, seq, result) if @console
+ end
+ end
+
+ def handle_heartbeat_ind(broker, codec, seq, msg)
+ if @console
+ broker_bank = 1
+ agent_bank = 0
+ dp = msg.get("delivery_properties")
+ if dp
+ key = dp["routing_key"]
+ key_elements = key.split(".")
+ if key_elements.length == 4
+ broker_bank = key_elements[2].to_i
+ agent_bank = key_elements[3].to_i
+ end
+ end
+ agent = broker.agent(broker_bank, agent_bank)
+ timestamp = codec.read_uint64
+ @console.heartbeat(agent, timestamp) if agent
+ end
+ end
+
+ def handle_event_ind(broker, codec, seq)
+ if @console
+ event = Event.new(self, broker, codec)
+ @console.event(broker, event)
+ end
+ end
+
+ def handle_schema_resp(broker, codec, seq)
+ kind = codec.read_uint8
+ classKey = ClassKey.new(codec)
+ klass = SchemaClass.new(self, kind, classKey, codec)
+ synchronize { @packages[classKey.package][ [classKey.klass_name, classKey.hash] ] = klass }
+
+ @seq_mgr.release(seq)
+ broker.dec_outstanding
+ @console.new_class(kind, classKey) if @console
+ end
+
+ def handle_content_ind(broker, codec, seq, prop=false, stat=false)
+ klass_key = ClassKey.new(codec)
+ pname, cname, hash = klass_key.to_a() ;
+
+ schema = nil
+ synchronize do
+ return unless @packages.include?(klass_key.package)
+ return unless @packages[klass_key.package].include?([klass_key.klass_name, klass_key.hash])
+ schema = @packages[klass_key.package][ [klass_key.klass_name, klass_key.hash] ]
+ end
+
+
+ object = Qpid::Qmf::Object.new(self, broker, schema, codec, prop, stat)
+ if pname == "org.apache.qpid.broker" && cname == "agent" && prop
+ broker.update_agent(object)
+ end
+
+ synchronize do
+ if @sync_sequence_list.include?(seq)
+ if object.timestamps()[2] == 0 && select_match(object)
+ @result << object
+ end
+ return
+ end
+ end
+
+ @console.object_props(broker, object) if @console && @rcv_objects && prop
+ @console.object_stats(broker, object) if @console && @rcv_objects && stat
+ end
+
+ def handle_broker_disconnect(broker); end
+
+ def handle_error(error)
+ synchronize do
+ @error = error if @sync_sequence_list.length > 0
+ @sync_sequence_list = []
+ @cv.signal
+ end
+ end
+
+ # Decode, from the codec, a value based on its typecode
+ def decode_value(codec, typecode)
+ case typecode
+ when 1: data = codec.read_uint8 # U8
+ when 2: data = codec.read_uint16 # U16
+ when 3: data = codec.read_uint32 # U32
+ when 4: data = codec.read_uint64 # U64
+ when 6: data = codec.read_str8 # SSTR
+ when 7: data = codec.read_str16 # LSTR
+ when 8: data = codec.read_int64 # ABSTIME
+ when 9: data = codec.read_uint64 # DELTATIME
+ when 10: data = ObjectId.new(codec) # REF
+ when 11: data = codec.read_uint8 != 0 # BOOL
+ when 12: data = codec.read_float # FLOAT
+ when 13: data = codec.read_double # DOUBLE
+ when 14: data = codec.read_uuid # UUID
+ when 15: data = codec.read_map # FTABLE
+ when 16: data = codec.read_int8 # S8
+ when 17: data = codec.read_int16 # S16
+ when 18: data = codec.read_int32 # S32
+ when 19: data = codec.read_int64 # S64
+ when 20: # Object
+ inner_type_code = codec.read_uint8()
+ if (inner_type_code == 20)
+ classKey = ClassKey.new(codec)
+ innerSchema = schema(classKey)
+ data = Object.new(self, @broker, innerSchema, codec, true, true, false) if innerSchema
+ else
+ data = decode_value(codec, inner_type_code)
+ end
+ when 21:
+ data = []
+ rec_codec = Qpid::StringCodec.new(codec.spec, codec.read_vbin32())
+ count = rec_codec.read_uint32()
+ while count > 0 do
+ type = rec_codec.read_uint8()
+ data << (decode_value(rec_codec,type))
+ count -= 1
+ end
+ when 22:
+ data = []
+ rec_codec = Qpid::StringCodec.new(codec.spec, codec.read_vbin32())
+ count = rec_codec.read_uint32()
+ type = rec_codec.read_uint8()
+ while count > 0 do
+ data << (decode_value(rec_codec,type))
+ count -= 1
+ end
+ else
+ raise ArgumentError, "Invalid type code: #{typecode} - #{typecode.inspect}"
+ end
+ return data
+ end
+
+ ENCODINGS = {
+ String => 6,
+ Fixnum => 18,
+ Bignum => 19,
+ Float => 12,
+ Array => 21,
+ Hash => 15
+ }
+
+ def encoding(object)
+ klass = object.class
+ if ENCODINGS.has_key?(klass)
+ return ENCODINGS[klass]
+ end
+ for base in klass.__bases__
+ result = encoding(base)
+ return result unless result.nil?
+ end
+ end
+
+ # Encode, into the codec, a value based on its typecode
+ def encode_value(codec, value, typecode)
+ # FIXME: Python does a lot of magic type conversions
+ # We just assume that value has the right type; this is safer
+ # than coercing explicitly, since Array::pack will complain
+ # loudly about various type errors
+ case typecode
+ when 1: codec.write_uint8(value) # U8
+ when 2: codec.write_uint16(value) # U16
+ when 3: codec.write_uint32(value) # U32
+ when 4: codec.write_uint64(value) # U64
+ when 6: codec.write_str8(value) # SSTR
+ when 7: codec.write_str16(value) # LSTR
+ when 8: codec.write_int64(value) # ABSTIME
+ when 9: codec.write_uint64(value) # DELTATIME
+ when 10: value.encode(codec) # REF
+ when 11: codec.write_uint8(value ? 1 : 0) # BOOL
+ when 12: codec.write_float(value) # FLOAT
+ when 13: codec.write_double(value) # DOUBLE
+ when 14: codec.write_uuid(value) # UUID
+ when 15: codec.write_map(value) # FTABLE
+ when 16: codec.write_int8(value) # S8
+ when 17: codec.write_int16(value) # S16
+ when 18: codec.write_int32(value) # S32
+ when 19: codec.write_int64(value) # S64
+ when 20: value.encode(codec)
+ when 21: # List
+ send_codec = Qpid::StringCodec.new(codec.spec)
+ encode_value(send_codec, value.size, 3)
+ value.each do v
+ ltype = encoding(v)
+ encode_value(send_codec,ltype,1)
+ encode_value(send_codec,v,ltype)
+ end
+ codec.write_vbin32(send_codec.encoded)
+ when 22: # Array
+ send_codec = Qpid::StringCodec.new(codec.spec)
+ encode_value(send_codec, value.size, 3)
+ if value.size > 0
+ ltype = encoding(value[0])
+ encode_value(send_codec,ltype,1)
+ value.each do v
+ encode_value(send_codec,v,ltype)
+ end
+ end
+ codec.write_vbin32(send_codec.encoded)
+ else
+ raise ValueError, "Invalid type code: %d" % typecode
+ end
+ end
+
+ def display_value(value, typecode)
+ case typecode
+ when 1: return value.to_s
+ when 2: return value.to_s
+ when 3: return value.to_s
+ when 4: return value.to_s
+ when 6: return value.to_s
+ when 7: return value.to_s
+ when 8: return strftime("%c", gmtime(value / 1000000000))
+ when 9: return value.to_s
+ when 10: return value.to_s
+ when 11: return value ? 'T' : 'F'
+ when 12: return value.to_s
+ when 13: return value.to_s
+ when 14: return Qpid::UUID::format(value)
+ when 15: return value.to_s
+ when 16: return value.to_s
+ when 17: return value.to_s
+ when 18: return value.to_s
+ when 19: return value.to_s
+ when 20: return value.to_s
+ when 21: return value.to_s
+ when 22: return value.to_s
+ else
+ raise ValueError, "Invalid type code: %d" % typecode
+ end
+ end
+
+ private
+
+ def binding_keys
+ key_list = []
+ key_list << "schema.#"
+ if @rcv_objects && @rcv_events && @rcv_heartbeats &&
+ ! @user_bindings
+ key_list << "console.#"
+ else
+ if @rcv_objects && ! @user_bindings
+ key_list << "console.obj.#"
+ else
+ key_list << "console.obj.*.*.org.apache.qpid.broker.agent"
+ end
+ key_list << "console.event.#" if @rcv_events
+ key_list << "console.heartbeat.#" if @rcv_heartbeats
+ end
+ return key_list
+ end
+
+ # Check the object against select to check for a match
+ def select_match(object)
+ select.each do |key, value|
+ object.properties.each do |prop, propval|
+ return false if key == prop.name && value != propval
+ end
+ end
+ return true
+ end
+
+ end
+
+ class Package
+ attr_reader :name
+
+ def initialize(name)
+ @name = name
+ end
+ end
+
+ # A ClassKey uniquely identifies a class from the schema.
+ class ClassKey
+ attr_reader :package, :klass_name, :hash
+
+ def initialize(package="", klass_name="", hash=0)
+ if (package.kind_of?(Qpid::Codec))
+ @package = package.read_str8()
+ @klass_name = package.read_str8()
+ @hash = package.read_bin128()
+ else
+ @package = package
+ @klass_name = klass_name
+ @hash = hash
+ end
+ end
+
+ def encode(codec)
+ codec.write_str8(@package)
+ codec.write_str8(@klass_name)
+ codec.write_bin128(@hash)
+ end
+
+ def to_a()
+ return [@package, @klass_name, @hash]
+ end
+
+ def hash_string()
+ "%08x-%08x-%08x-%08x" % hash.unpack("NNNN")
+ end
+
+ def to_s()
+ return "#{@package}:#{@klass_name}(#{hash_string()})"
+ end
+ end
+
+ class SchemaClass
+
+ CLASS_KIND_TABLE = 1
+ CLASS_KIND_EVENT = 2
+
+ attr_reader :klass_key, :arguments, :super_klass_key
+
+ def initialize(session, kind, key, codec)
+ @session = session
+ @kind = kind
+ @klass_key = key
+ @super_klass_key = nil
+ @properties = []
+ @statistics = []
+ @methods = []
+ @arguments = []
+
+ has_supertype = 0 #codec.read_uint8
+ if @kind == CLASS_KIND_TABLE
+ prop_count = codec.read_uint16
+ stat_count = codec.read_uint16
+ method_count = codec.read_uint16
+ if has_supertype == 1
+ @super_klass_key = ClassKey.new(codec)
+ end
+ prop_count.times { |idx|
+ @properties << SchemaProperty.new(codec) }
+ stat_count.times { |idx|
+ @statistics << SchemaStatistic.new(codec) }
+ method_count.times { |idx|
+ @methods<< SchemaMethod.new(codec) }
+ elsif @kind == CLASS_KIND_EVENT
+ arg_count = codec.read_uint16
+ arg_count.times { |idx|
+ sa = SchemaArgument.new(codec, false)
+ @arguments << sa
+ }
+ end
+ end
+
+ def is_table?
+ @kind == CLASS_KIND_TABLE
+ end
+
+ def is_event?
+ @kind == CLASS_KIND_EVENT
+ end
+
+ def properties(include_inherited = true)
+ returnValue = @properties
+ if !@super_klass_key.nil? && include_inherited
+ returnValue = @properties + @session.schema(@super_klass_key).properties
+ end
+ return returnValue
+ end
+
+ def statistics(include_inherited = true)
+ returnValue = @statistics
+ if !@super_klass_key.nil? && include_inherited
+ returnValue = @statistics + @session.schema(@super_klass_key).statistics
+ end
+ return returnValue
+ end
+
+ def methods(include_inherited = true)
+ returnValue = @methods
+ if !@super_klass_key.nil? && include_inherited
+ returnValue = @methods + @session.schema(@super_klass_key).methods
+ end
+ return returnValue
+ end
+
+ def to_s
+ if @kind == CLASS_KIND_TABLE
+ kind_str = "Table"
+ elsif @kind == CLASS_KIND_EVENT
+ kind_str = "Event"
+ else
+ kind_str = "Unsupported"
+ end
+ "#{kind_str} Class: #{klass_key.to_s}"
+ end
+ end
+
+ class SchemaProperty
+
+ attr_reader :name, :type, :access, :index, :optional,
+ :unit, :min, :max, :maxlen, :desc, :refClass, :refPackage
+
+ def initialize(codec)
+ map = codec.read_map
+ @name = map["name"]
+ @type = map["type"]
+ @access = map["access"]
+ @index = map["index"] != 0
+ @optional = map["optional"] != 0
+ @unit = map["unit"]
+ @min = map["min"]
+ @max = map["max"]
+ @maxlen = map["maxlen"]
+ @desc = map["desc"]
+ @refClass = map["refClass"]
+ @refPackage = map["refPackage"]
+ end
+
+ def to_s
+ @name
+ end
+ end
+
+ class SchemaStatistic
+
+ attr_reader :name, :type, :unit, :desc, :refClass, :refPackage
+
+ def initialize(codec)
+ map = codec.read_map
+ @name = map["name"]
+ @type = map["type"]
+ @unit = map["unit"]
+ @desc = map["desc"]
+ @refClass = map["refClass"]
+ @refPackage = map["refPackage"]
+ end
+
+ def to_s
+ @name
+ end
+ end
+
+ class SchemaMethod
+
+ attr_reader :name, :desc, :arguments
+
+ def initialize(codec)
+ map = codec.read_map
+ @name = map["name"]
+ arg_count = map["argCount"]
+ @desc = map["desc"]
+ @arguments = []
+ arg_count.times { |idx|
+ @arguments << SchemaArgument.new(codec, true)
+ }
+ end
+
+ def to_s
+ result = @name + "("
+ first = true
+ result += @arguments.select { |arg| arg.dir.index(?I) }.join(", ")
+ result += ")"
+ return result
+ end
+ end
+
+ class SchemaArgument
+
+ attr_reader :name, :type, :dir, :unit, :min, :max, :maxlen
+ attr_reader :desc, :default, :refClass, :refPackage
+
+ def initialize(codec, method_arg)
+ map = codec.read_map
+ @name = map["name"]
+ @type = map["type"]
+ @dir = map["dir"].upcase if method_arg
+ @unit = map["unit"]
+ @min = map["min"]
+ @max = map["max"]
+ @maxlen = map["maxlen"]
+ @desc = map["desc"]
+ @default = map["default"]
+ @refClass = map["refClass"]
+ @refPackage = map["refPackage"]
+ end
+ end
+
+ # Object that represents QMF object identifiers
+ class ObjectId
+
+ include Comparable
+
+ attr_reader :first, :second
+
+ def initialize(codec, first=0, second=0)
+ if codec
+ @first = codec.read_uint64
+ @second = codec.read_uint64
+ else
+ @first = first
+ @second = second
+ end
+ end
+
+ def <=>(other)
+ return 1 unless other.is_a?(ObjectId)
+ return -1 if first < other.first
+ return 1 if first > other.first
+ return second <=> other.second
+ end
+
+ def to_s
+ "%d-%d-%d-%d-%d" % [flags, sequence, broker_bank, agent_bank, object]
+ end
+
+ def index
+ [first, second]
+ end
+
+ def flags
+ (first & 0xF000000000000000) >> 60
+ end
+
+ def sequence
+ (first & 0x0FFF000000000000) >> 48
+ end
+
+ def broker_bank
+ (first & 0x0000FFFFF0000000) >> 28
+ end
+
+ def agent_bank
+ first & 0x000000000FFFFFFF
+ end
+
+ def object
+ second
+ end
+
+ def durable?
+ sequence == 0
+ end
+
+ def encode(codec)
+ codec.write_uint64(first)
+ codec.write_uint64(second)
+ end
+ end
+
+ class Object
+
+ DEFAULT_METHOD_WAIT_TIME = 60
+
+ attr_reader :object_id, :schema, :properties, :statistics,
+ :current_time, :create_time, :delete_time, :broker
+
+ def initialize(session, broker, schema, codec, prop, stat, managed=true)
+ @session = session
+ @broker = broker
+ @schema = schema
+ if managed
+ @current_time = codec.read_uint64
+ @create_time = codec.read_uint64
+ @delete_time = codec.read_uint64
+ @object_id = ObjectId.new(codec)
+ end
+ @properties = []
+ @statistics = []
+ if prop
+ missing = parse_presence_masks(codec, schema)
+ schema.properties.each do |property|
+ v = nil
+ unless missing.include?(property.name)
+ v = @session.decode_value(codec, property.type)
+ end
+ @properties << [property, v]
+ end
+ end
+
+ if stat
+ schema.statistics.each do |statistic|
+ s = @session.decode_value(codec, statistic.type)
+ @statistics << [statistic, s]
+ end
+ end
+ end
+
+ def klass_key
+ @schema.klass_key
+ end
+
+
+ def methods
+ @schema.methods
+ end
+
+ # Return the current, creation, and deletion times for this object
+ def timestamps
+ return [@current_time, @create_time, @delete_time]
+ end
+
+ # Return a string describing this object's primary key
+ def index
+ @properties.select { |property, value|
+ property.index
+ }.collect { |property,value|
+ @session.display_value(value, property.type) }.join(":")
+ end
+
+ # Replace properties and/or statistics with a newly received update
+ def merge_update(newer)
+ unless object_id == newer.object_id
+ raise "Objects with different object-ids"
+ end
+ @properties = newer.properties unless newer.properties.empty?
+ @statistics = newer.statistics unless newer.statistics.empty?
+ end
+
+ def update
+ obj = @session.object(:object_id => @object_id, :broker => @broker)
+ if obj
+ merge_update(obj)
+ else
+ raise "Underlying object no longer exists."
+ end
+ end
+
+ def to_s
+ @schema.klass_key.to_s
+ end
+
+ # This must be defined because ruby has this (deprecated) method built in.
+ def id
+ method_missing(:id)
+ end
+
+ # Same here..
+ def type
+ method_missing(:type)
+ end
+
+ def name
+ method_missing(:name)
+ end
+
+ def method_missing(name, *args)
+ name = name.to_s
+
+ if method = @schema.methods.find { |method| name == method.name }
+ return invoke(method, name, args)
+ end
+
+ @properties.each do |property, value|
+ return value if name == property.name
+ if name == "_#{property.name}_" && property.type == 10
+ # Dereference references
+ deref = @session.objects(:object_id => value, :broker => @broker)
+ return nil unless deref.size == 1
+ return deref[0]
+ end
+ end
+ @statistics.each do |statistic, value|
+ if name == statistic.name
+ return value
+ end
+ end
+ raise "Type Object has no attribute '#{name}'"
+ end
+
+ def encode(codec)
+ codec.write_uint8(20)
+ @schema.klass_key.encode(codec)
+
+ # emit presence masks for optional properties
+ mask = 0
+ bit = 0
+ schema.properties.each do |property|
+ if prop.optional
+ bit = 1 if bit == 0
+ mask |= bit if value
+ bit = bit << 1
+ if bit == 256
+ bit = 0
+ codec.write_uint8(mask)
+ mask = 0
+ end
+ codec.write_uint8(mask) if bit != 0
+ end
+ end
+
+ # encode properties
+ @properties.each do |property, value|
+ @session.encode_value(codec, value, prop.type) if value
+ end
+
+ # encode statistics
+ @statistics.each do |statistic, value|
+ @session.encode_value(codec, value, stat.type)
+ end
+ end
+
+ private
+
+ def send_method_request(method, name, args, synchronous = false, time_wait = nil)
+ @schema.methods.each do |schema_method|
+ if name == schema_method.name
+ send_codec = Qpid::StringCodec.new(@broker.conn.spec)
+ seq = @session.seq_mgr.reserve([schema_method, synchronous])
+ @broker.set_header(send_codec, ?M, seq)
+ @object_id.encode(send_codec)
+ @schema.klass_key.encode(send_codec)
+ send_codec.write_str8(name)
+
+ formals = method.arguments.select { |arg| arg.dir.index(?I) }
+ count = method.arguments.select { |arg| arg.dir.index(?I) }.size
+ unless formals.size == args.size
+ raise "Incorrect number of arguments: expected #{formals.size}, got #{args.size}"
+ end
+
+ formals.zip(args).each do |formal, actual|
+ @session.encode_value(send_codec, actual, formal.type)
+ end
+
+ ttl = time_wait ? time_wait * 1000 : nil
+ smsg = @broker.message(send_codec.encoded,
+ "agent.#{object_id.broker_bank}.#{object_id.agent_bank}", ttl=ttl)
+ @broker.sync_start if synchronous
+ @broker.emit(smsg)
+
+ return seq
+ end
+ end
+ end
+
+ def invoke(method, name, args)
+ kwargs = args[args.size - 1]
+ sync = true
+ timeout = DEFAULT_METHOD_WAIT_TIME
+
+ if kwargs.class == Hash
+ if kwargs.include?(:timeout)
+ timeout = kwargs[:timeout]
+ end
+
+ if kwargs.include?(:async)
+ sync = !kwargs[:async]
+ end
+ args.pop
+ end
+
+ seq = send_method_request(method, name, args, synchronous = sync)
+ if seq
+ return seq unless sync
+ unless @broker.wait_for_sync_done(timeout)
+ @session.seq_mgr.release(seq)
+ raise "Timed out waiting for method to respond"
+ end
+
+ if @broker.error
+ error_text = @broker.error
+ @broker.error = nil
+ raise error_text
+ end
+
+ return @broker.sync_result
+ end
+ raise "Invalid Method (software defect) [#{name}]"
+ end
+
+ def parse_presence_masks(codec, schema)
+ exclude_list = []
+ bit = 0
+ schema.properties.each do |property|
+ if property.optional
+ if bit == 0
+ mask = codec.read_uint8
+ bit = 1
+ end
+ if (mask & bit) == 0
+ exclude_list << property.name
+ end
+ bit *= 2
+ bit = 0 if bit == 256
+ end
+ end
+ return exclude_list
+ end
+ end
+
+ class MethodResult
+
+ attr_reader :status, :text, :out_args
+
+ def initialize(status, text, out_args)
+ @status = status
+ @text = text
+ @out_args = out_args
+ end
+
+ def method_missing(name)
+ name = name.to_s()
+ if @out_args.include?(name)
+ return @out_args[name]
+ else
+ raise "Unknown method result arg #{name}"
+ end
+ end
+
+ def to_s
+ argsString = ""
+ padding = ""
+ out_args.each do |key,value|
+ argsString += padding
+ padding = " " if padding == ""
+ argsString += key.to_s
+ argsString += " => "
+ argsString += value.to_s()
+ end
+ "MethodResult(Msg: '#{text}' Status: #{status} Return: [#{argsString}])"
+ end
+ end
+
+ class ManagedConnection
+
+ DELAY_MIN = 1
+ DELAY_MAX = 128
+ DELAY_FACTOR = 2
+ include MonitorMixin
+
+ def initialize(broker)
+ super()
+ @broker = broker
+ @cv = new_cond
+ @is_cancelled = false
+ end
+
+ # Main body of the running thread.
+ def start
+ @thread = Thread.new {
+ delay = DELAY_MIN
+ while true
+ begin
+ @broker.try_to_connect
+ synchronize do
+ while !@is_cancelled and @broker.connected?
+ @cv.wait
+ Thread.exit if @is_cancelled
+ delay = DELAY_MIN
+ end
+ end
+
+ rescue
+ delay *= DELAY_FACTOR if delay < DELAY_MAX
+ end
+
+ synchronize do
+ @cv.wait(delay)
+ Thread.exit if @is_cancelled
+ end
+ end
+ }
+ end
+
+ # Tell this thread to stop running and return.
+ def stop
+ synchronize do
+ @is_cancelled = true
+ @cv.signal
+ end
+ end
+
+ # Notify the thread that the connection was lost.
+ def disconnected
+ synchronize do
+ @cv.signal
+ end
+ end
+
+ def join
+ @thread.join
+ end
+ end
+
+ class Broker
+
+ SYNC_TIME = 60
+ @@next_seq = 1
+
+ include MonitorMixin
+
+ attr_accessor :error
+
+ attr_reader :amqp_session_id, :amqp_session, :conn, :broker_bank, :topic_name
+
+ attr_accessor :broker_id, :sync_result
+
+ def initialize(session, host, port, auth_name, auth_pass, kwargs)
+ super()
+
+ # For debugging..
+ Thread.abort_on_exception = true
+
+ @session = session
+ @host = host
+ @port = port
+ @auth_name = auth_name
+ @auth_pass = auth_pass
+ @user_id = nil
+ @auth_mechanism = kwargs[:mechanism]
+ @auth_service = kwargs[:service]
+ @broker_bank = 1
+ @topic_bound = false
+ @cv = new_cond
+ @error = nil
+ @broker_id = nil
+ @is_connected = false
+ @amqp_session_id = "%s.%d.%d" % [Socket.gethostname, Process::pid, @@next_seq]
+ @@next_seq += 1
+ @conn = nil
+ if @session.managedConnections?
+ @thread = ManagedConnection.new(self)
+ @thread.start
+ else
+ @thread = nil
+ try_to_connect
+ end
+ end
+
+ def connected?
+ @is_connected
+ end
+
+ def agent(broker_bank, agent_bank)
+ bank_key = "%d.%d" % [broker_bank, agent_bank]
+ return @agents[bank_key]
+ end
+
+ # Get the list of agents reachable via this broker
+ def agents
+ @agents.values
+ end
+
+ def url
+ "#{@host}:#{@port}"
+ end
+
+ def to_s
+ if connected?
+ "Broker connected at: #{url}"
+ else
+ "Disconnected Broker"
+ end
+ end
+
+ def wait_for_sync_done(timeout=nil)
+ wait_time = timeout ? timeout : SYNC_TIME
+ synchronize do
+ return @cv.wait_for(wait_time) { ! @sync_in_flight || @error }
+ end
+ end
+
+ def wait_for_stable
+ synchronize do
+ return unless connected?
+ return if @reqs_outstanding == 0
+ @sync_in_flight = true
+ unless @cv.wait_for(SYNC_TIME) { @reqs_outstanding == 0 }
+ raise "Timed out waiting for broker to synchronize"
+ end
+ end
+ end
+
+ # Compose the header of a management message
+ def set_header(codec, opcode, seq=0)
+ codec.write_uint8(?A)
+ codec.write_uint8(?M)
+ codec.write_uint8(?2)
+ codec.write_uint8(opcode)
+ codec.write_uint32(seq)
+ end
+
+ def message(body, routing_key="broker", ttl=nil)
+ dp = @amqp_session.delivery_properties
+ dp.routing_key = routing_key
+ dp.ttl = ttl if ttl
+ mp = @amqp_session.message_properties
+ mp.content_type = "x-application/qmf"
+ mp.reply_to = amqp_session.reply_to("amq.direct", @reply_name)
+ #mp.user_id = @user_id if @user_id
+ return Qpid::Message.new(dp, mp, body)
+ end
+
+ def emit(msg, dest="qpid.management")
+ @amqp_session.message_transfer(:destination => dest,
+ :message => msg)
+ end
+
+ def inc_outstanding
+ synchronize { @reqs_outstanding += 1 }
+ end
+
+ def dec_outstanding
+ synchronize do
+ @reqs_outstanding -= 1
+ if @reqs_outstanding == 0 && ! @topic_bound
+ @topic_bound = true
+ @session.binding_key_list.each do |key|
+ args = {
+ :exchange => "qpid.management",
+ :queue => @topic_name,
+ :binding_key => key }
+ @amqp_session.exchange_bind(args)
+ end
+ end
+ if @reqs_outstanding == 0 && @sync_in_flight
+ sync_done
+ end
+ end
+ end
+
+ def sync_start
+ synchronize { @sync_in_flight = true }
+ end
+
+ def sync_done
+ synchronize do
+ @sync_in_flight = false
+ @cv.signal
+ end
+ end
+
+ def update_agent(obj)
+ bank_key = "%d.%d" % [obj.brokerBank, obj.agentBank]
+ if obj.delete_time == 0
+ unless @agents.include?(bank_key)
+ agent = Agent.new(self, obj.agentBank, obj.label)
+ @agents[bank_key] = agent
+ @session.console.new_agent(agent) if @session.console
+ end
+ else
+ agent = @agents.delete(bank_key)
+ @session.console.del_agent(agent) if agent && @session.console
+ end
+ end
+
+ def shutdown
+ if @thread
+ @thread.stop
+ @thread.join
+ end
+ if connected?
+ @amqp_session.incoming("rdest").stop
+ if @session.console
+ @amqp_session.incoming("tdest").stop
+ end
+ @amqp_session.close
+ @is_connected = false
+ end
+ end
+
+ def try_to_connect
+ @agents = {}
+ @agents["1.0"] = Agent.new(self, 0, "BrokerAgent")
+ @topic_bound = false
+ @sync_in_flight = false
+ @sync_request = 0
+ @sync_result = nil
+ @reqs_outstanding = 1
+
+ # FIXME: Need sth for Qpid::Util::connect
+
+ @conn = Qpid::Connection.new(TCPSocket.new(@host, @port),
+ :mechanism => @auth_mechanism,
+ :username => @auth_name,
+ :password => @auth_pass,
+ :host => @host,
+ :service => @auth_service)
+ @conn.start
+ @user_id = @conn.user_id
+ @reply_name = "reply-%s" % amqp_session_id
+ @amqp_session = @conn.session(@amqp_session_id)
+ @amqp_session.auto_sync = true
+
+ @amqp_session.queue_declare(:queue => @reply_name,
+ :exclusive => true,
+ :auto_delete => true)
+
+ @amqp_session.exchange_bind(:exchange => "amq.direct",
+ :queue => @reply_name,
+ :binding_key => @reply_name)
+ @amqp_session.message_subscribe(:queue => @reply_name,
+ :destination => "rdest",
+ :accept_mode => @amqp_session.message_accept_mode.none,
+ :acquire_mode => @amqp_session.message_acquire_mode.pre_acquired)
+ q = @amqp_session.incoming("rdest")
+ q.exc_listen(& method(:exception_cb))
+ q.listen(& method(:reply_cb))
+ @amqp_session.message_set_flow_mode(:destination => "rdest",
+ :flow_mode => 1)
+ @amqp_session.message_flow(:destination => "rdest",
+ :unit => 0,
+ :value => 0xFFFFFFFF)
+ @amqp_session.message_flow(:destination => "rdest",
+ :unit => 1,
+ :value => 0xFFFFFFFF)
+
+ @topic_name = "topic-#{@amqp_session_id}"
+ @amqp_session.queue_declare(:queue => @topic_name,
+ :exclusive => true,
+ :auto_delete => true)
+ @amqp_session.message_subscribe(:queue => @topic_name,
+ :destination => "tdest",
+ :accept_mode => @amqp_session.message_accept_mode.none,
+ :acquire_mode => @amqp_session.message_acquire_mode.pre_acquired)
+ @amqp_session.incoming("tdest").listen(& method(:reply_cb))
+ @amqp_session.message_set_flow_mode(:destination => "tdest",
+ :flow_mode => 1)
+ @amqp_session.message_flow(:destination => "tdest",
+ :unit => 0,
+ :value => 0xFFFFFFFF)
+ @amqp_session.message_flow(:destination => "tdest",
+ :unit => 1,
+ :value => 0xFFFFFFFF)
+
+ @is_connected = true
+ @session.handle_broker_connect(self)
+
+ codec = Qpid::StringCodec.new(@conn.spec)
+ set_header(codec, ?B)
+ msg = message(codec.encoded)
+ emit(msg)
+ end
+
+ private
+
+ # Check the header of a management message and extract the opcode and
+ # class
+ def check_header(codec)
+ begin
+ return [nil, nil] unless codec.read_uint8 == ?A
+ return [nil, nil] unless codec.read_uint8 == ?M
+ return [nil, nil] unless codec.read_uint8 == ?2
+ opcode = codec.read_uint8
+ seq = codec.read_uint32
+ return [opcode, seq]
+ rescue
+ return [nil, nil]
+ end
+ end
+
+ def reply_cb(msg)
+ codec = Qpid::StringCodec.new(@conn.spec, msg.body)
+ loop do
+ opcode, seq = check_header(codec)
+ return unless opcode
+ case opcode
+ when ?b: @session.handle_broker_resp(self, codec, seq)
+ when ?p: @session.handle_package_ind(self, codec, seq)
+ when ?z: @session.handle_command_complete(self, codec, seq)
+ when ?q: @session.handle_class_ind(self, codec, seq)
+ when ?m: @session.handle_method_resp(self, codec, seq)
+ when ?h: @session.handle_heartbeat_ind(self, codec, seq, msg)
+ when ?e: @session.handle_event_ind(self, codec, seq)
+ when ?s: @session.handle_schema_resp(self, codec, seq)
+ when ?c: @session.handle_content_ind(self, codec, seq, true, false)
+ when ?i: @session.handle_content_ind(self, codec, seq, false, true)
+ when ?g: @session.handle_content_ind(self, codec, seq, true, true)
+ else
+ raise "Unexpected opcode #{opcode.inspect}"
+ end
+ end
+ end
+
+ def exception_cb(data)
+ @is_connected = false
+ @error = data
+ synchronize { @cv.signal if @sync_in_flight }
+ @session.handle_error(@error)
+ @session.handle_broker_disconnect(self)
+ @thread.disconnected if @thread
+ end
+ end
+
+ class Agent
+ attr_reader :broker, :agent_bank, :label
+
+ def initialize(broker, agent_bank, label)
+ @broker = broker
+ @agent_bank = agent_bank
+ @label = label
+ end
+
+ def broker_bank
+ @broker.broker_bank
+ end
+
+ def to_s
+ "Agent at bank %d.%d (%s)" % [@broker.broker_bank, @agent_bank, @label]
+ end
+ end
+
+ class Event
+
+ attr_reader :klass_key, :arguments, :timestamp, :name, :schema
+
+ def initialize(session, broker, codec)
+ @session = session
+ @broker = broker
+ @klass_key = ClassKey.new(codec)
+ @timestamp = codec.read_int64
+ @severity = codec.read_uint8
+ @schema = nil
+
+ pname, cname, hash = @klass_key.to_a()
+ session.packages.keys.each do |pname|
+ k = [cname, hash]
+ if session.packages[pname].include?(k)
+ @schema = session.packages[pname][k]
+ @arguments = {}
+ @schema.arguments.each do |arg|
+ v = session.decode_value(codec, arg.type)
+ @arguments[arg.name] = v
+ end
+ end
+ end
+ end
+
+ def to_s
+ return "<uninterpretable>" unless @schema
+ t = Time.at(self.timestamp / 1000000000)
+ out = t.strftime("%c")
+ out += " " + sev_name + " " + @klass_key.package + ":" + @klass_key.klass_name
+ out += " broker=" + @broker.url
+ @schema.arguments.each do |arg|
+ out += " " + arg.name + "=" + @session.display_value(@arguments[arg.name], arg.type)
+ end
+ return out
+ end
+
+ def sev_name
+ case @severity
+ when 0 : return "EMER "
+ when 1 : return "ALERT"
+ when 2 : return "CRIT "
+ when 3 : return "ERROR"
+ when 4 : return "WARN "
+ when 5 : return "NOTIC"
+ when 6 : return "INFO "
+ when 7 : return "DEBUG"
+ else
+ return "INV-%d" % @severity
+ end
+ end
+
+ end
+
+ # Manage sequence numbers for asynchronous method calls
+ class SequenceManager
+ include MonitorMixin
+
+ def initialize
+ super()
+ @sequence = 0
+ @pending = {}
+ end
+
+ # Reserve a unique sequence number
+ def reserve (data)
+ synchronize do
+ result = @sequence
+ @sequence += 1
+ @pending[result] = data
+ return result
+ end
+ end
+
+ # Release a reserved sequence number
+ def release (seq)
+ synchronize { @pending.delete(seq) }
+ end
+ end
+
+ class DebugConsole < Console
+
+ def broker_connected(broker)
+ puts "brokerConnected #{broker}"
+ end
+
+ def broker_disconnected(broker)
+ puts "brokerDisconnected #{broker}"
+ end
+
+ def new_package(name)
+ puts "newPackage #{name}"
+ end
+
+ def new_class(kind, klass_key)
+ puts "newClass #{kind} #{klass_key}"
+ end
+
+ def new_agent(agent)
+ puts "new_agent #{agent}"
+ end
+
+ def del_agent(agent)
+ puts "delAgent #{agent}"
+ end
+
+ def object_props(broker, record)
+ puts "objectProps #{record}"
+ end
+
+ def object_stats(broker, record)
+ puts "objectStats #{record}"
+ end
+
+ def event(broker, event)
+ puts "event #{event}"
+ end
+
+ def heartbeat(agent, timestamp)
+ puts "heartbeat #{agent}"
+ end
+
+ def broker_info(broker)
+ puts "brokerInfo #{broker}"
+ end
+ end
+
+ module XML
+ TYPES = {
+ 1 => "uint8",
+ 2 => "uint16",
+ 3 => "uint32",
+ 4 => "uint64",
+ 5 => "bool",
+ 6 => "short-stirng",
+ 7 => "long-string",
+ 8 => "abs-time",
+ 9 => "delta-time",
+ 10 => "reference",
+ 11 => "boolean",
+ 12 => "float",
+ 13 => "double",
+ 14 => "uuid",
+ 15 => "field-table",
+ 16 => "int8",
+ 17 => "int16",
+ 18 => "int32",
+ 19 => "int64",
+ 20 => "object",
+ 21 => "list",
+ 22 => "array"
+ }
+
+ ACCESS_MODES = {
+ 1 => "RC",
+ 2 => "RW",
+ 3 => "RO"
+ }
+
+ def common_attributes(item)
+ attr_string = ""
+ attr_string << " desc='#{item.desc}'" if item.desc
+ attr_string << " desc='#{item.desc}'" if item.desc
+ attr_string << " refPackage='#{item.refPackage}'" if item.refPackage
+ attr_string << " refClass='#{item.refClass}'" if item.refClass
+ attr_string << " unit='#{item.unit}'" if item.unit
+ attr_string << " min='#{item.min}'" if item.min
+ attr_string << " max='#{item.max}'" if item.max
+ attr_string << " maxlen='#{item.maxlen}'" if item.maxlen
+ return attr_string
+ end
+
+ module_function :common_attributes
+
+ def schema_xml(session, *packages)
+ schema = "<schemas>\n"
+ packages.each do |package|
+ schema << "\t<schema package='#{package}'>\n"
+ session.classes(package).each do |klass_key|
+ klass = session.schema(klass_key)
+ if klass.is_table?
+ if klass.super_klass_key
+ schema << "\t\t<class name='#{klass.klass_key.klass_name}' hash='#{klass.klass_key.hash_string}' extends='#{klass.super_klass_key.to_s}'>\n"
+ else
+ schema << "\t\t<class name='#{klass.klass_key.klass_name}' hash='#{klass.klass_key.hash_string}'>\n"
+ end
+ klass.properties(false).each do |property|
+ schema << "\t\t\t<property name='#{property.name}' type='#{TYPES[property.type]}' access='#{ACCESS_MODES[property.access]}' optional='#{property.optional ? "True" : "False"}'#{common_attributes(property)}/>\n"
+ end
+ klass.methods(false).each do |method|
+ schema << "\t\t\t<method name='#{method.name}'>\n"
+ method.arguments.each do |arg|
+ schema << "\t\t\t\t<arg name='#{arg.name}' dir='#{arg.dir}' type='#{TYPES[arg.type]}'#{common_attributes(arg)}/>\n"
+ end
+ schema << "\t\t\t</method>\n"
+ end
+ schema << "\t\t</class>\n"
+ else
+ schema << "\t\t<event name='#{klass.klass_key.klass_name}' hash='#{klass.klass_key.hash_string}'>\n"
+ klass.arguments.each do |arg|
+ schema << "\t\t\t<arg name='#{arg.name}'type='#{TYPES[arg.type]}'#{common_attributes(arg)}/>\n"
+ end
+ schema << "\t\t</event>\n"
+ end
+ end
+ schema << "\t</package>\n"
+ end
+ schema << "</schema>"
+ end
+
+ module_function :schema_xml
+ end
+
+end
diff --git a/qpid/ruby/lib/qpid/queue.rb b/qpid/ruby/lib/qpid/queue.rb
new file mode 100644
index 0000000000..4150173b53
--- /dev/null
+++ b/qpid/ruby/lib/qpid/queue.rb
@@ -0,0 +1,101 @@
+#
+# 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.
+#
+
+# Augment the standard python multithreaded Queue implementation to add a
+# close() method so that threads blocking on the content of a queue can be
+# notified if the queue is no longer in use.
+
+require 'thread'
+
+# Python nominally uses a bounded queue, but the code never establishes
+# a maximum size; we therefore use Ruby's unbounded queue
+class Qpid::Queue < ::Queue
+
+ DONE = Object.new
+ STOP = Object.new
+
+ def initialize
+ super
+ @error = nil
+ @listener = nil
+ @exc_listener = nil
+ @exc_listener_lock = Monitor.new
+ @thread = nil
+ end
+
+ def close(error = nil)
+ @error = error
+ put(DONE)
+ unless @thread.nil?
+ @thread.join()
+ @thread = nil
+ end
+ end
+
+ def get(block = true, timeout = nil)
+ unless timeout.nil?
+ raise NotImplementedError
+ end
+ result = pop(! block)
+ if result == DONE
+ # this guarantees that any other waiting threads or any future
+ # calls to get will also result in a Qpid::Closed exception
+ put(DONE)
+ raise Qpid::Closed.new(@error)
+ else
+ return result
+ end
+ end
+
+ alias :put :push
+
+ def exc_listen(&block)
+ @exc_listener_lock.synchronize do
+ @exc_listener = block
+ end
+ end
+
+ def listen(&block)
+ if ! block_given? && @thread
+ put(STOP)
+ @thread.join()
+ @thread = nil
+ end
+
+ # FIXME: There is a potential race since we could be changing one
+ # non-nil listener to another
+ @listener = block
+
+ if block_given? && @thread.nil?
+ @thread = Thread.new do
+ loop do
+ begin
+ o = get()
+ break if o == STOP
+ @listener.call(o)
+ rescue Qpid::Closed => e
+ @exc_listener.call(e) if @exc_listener
+ break
+ end
+ end
+ end
+ end
+ end
+
+end
diff --git a/qpid/ruby/lib/qpid/session.rb b/qpid/ruby/lib/qpid/session.rb
new file mode 100644
index 0000000000..d693b722c2
--- /dev/null
+++ b/qpid/ruby/lib/qpid/session.rb
@@ -0,0 +1,458 @@
+#
+# 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.
+#
+
+require 'monitor'
+
+module Qpid
+
+ class Session < Invoker
+
+ def log; Qpid::logger["qpid.io.cmd"]; end
+ def msg; Qpid::logger["qpid.io.msg"]; end
+
+
+ class Exception < RuntimeError; end
+ class Closed < Qpid::Session::Exception; end
+ class Detached < Qpid::Session::Exception; end
+
+
+ INCOMPLETE = Object.new
+
+ def self.client(*args)
+ return Qpid::Client(*args)
+ end
+
+ def self.server(*args)
+ return Server(*args)
+ end
+
+ attr_reader :name, :spec, :auto_sync, :timeout, :channel
+ attr_reader :results, :exceptions
+ attr_accessor :channel, :auto_sync, :send_id, :receiver, :sender
+
+ # FIXME: Pass delegate through a block ?
+ def initialize(name, spec, kwargs = {})
+ auto_sync = true
+ auto_sync = kwargs[:auto_sync] if kwargs.key?(:auto_sync)
+ timeout = kwargs[:timeout] || 10
+ delegate = kwargs[:delegate]
+
+ @name = name
+ @spec = spec
+ @auto_sync = auto_sync
+ @timeout = timeout
+ @invoke_lock = Monitor.new
+ @closing = false
+ @closed = false
+
+ @cond_lock = Monitor.new
+ @condition = @cond_lock.new_cond
+
+ @send_id = true
+ @receiver = Receiver.new(self)
+ @sender = Sender.new(self)
+
+ @lock = Monitor.new
+ @incoming = {}
+ @results = {}
+ @exceptions = []
+
+ @assembly = nil
+
+ @delegate = delegate.call(self) if delegate
+
+ @ctl_seg = spec[:segment_type].enum[:control].value
+ @cmd_seg = spec[:segment_type].enum[:command].value
+ @hdr_seg = spec[:segment_type].enum[:header].value
+ @body_seg = spec[:segment_type].enum[:body].value
+ end
+
+ def incoming(destination)
+ @lock.synchronize do
+ queue = @incoming[destination]
+ unless queue
+ queue = Incoming.new(self, destination)
+ @incoming[destination] = queue
+ end
+ return queue
+ end
+ end
+
+ def error?
+ @exceptions.size > 0
+ end
+
+ def sync(timeout=nil)
+ if channel && Thread.current == channel.connection.thread
+ raise Qpid::Session::Exception, "deadlock detected"
+ end
+ unless @auto_sync
+ execution_sync(:sync => true)
+ end
+ last = @sender.next_id - 1
+ @cond_lock.synchronize do
+ unless @condition.wait_for(timeout) {
+ @sender.completed.include?(last) || error?
+ }
+ raise Qpid::Timeout
+ end
+ end
+ if error?
+ raise Qpid::Session::Exception, @exceptions
+ end
+ end
+
+ def close(timeout=nil)
+ @invoke_lock.synchronize do
+ @closing = true
+ channel.session_detach(name)
+ end
+ @cond_lock.synchronize do
+ unless @condition.wait_for(timeout) { @closed }
+ raise Qpid::Timeout
+ end
+ end
+ end
+
+ def closed
+ @lock.synchronize do
+ return if @closed
+
+ @results.each { |id, f| f.error(exceptions) }
+ @results.clear
+
+ @incoming.values.each { |q| q.close(exceptions) }
+ @closed = true
+ @cond_lock.synchronize { @condition.signal }
+ end
+ end
+
+ def resolve_method(name)
+ o = @spec.children[name]
+ case o
+ when Qpid::Spec010::Command
+ return invocation(:method, o)
+ when Qpid::Spec010::Struct
+ return invocation(:method, o)
+ when Qpid::Spec010::Domain
+ return invocation(:value, o.enum) unless o.enum.nil?
+ end
+
+ matches = @spec.children.select { |x|
+ x.name.to_s.include?(name.to_s)
+ }.collect { |x| x.name.to_s }.sort
+ if matches.size == 0
+ msg = nil
+ elsif matches.size == 1
+ msg = "Did you mean #{matches[0]} ? "
+ else
+ msg = "Did you mean one of #{matches.join(",")} ? "
+ end
+ return invocation(:error, msg)
+ end
+
+ def invoke(type, args)
+ # XXX
+ unless type.respond_to?(:track)
+ return type.create(*args)
+ end
+ @invoke_lock.synchronize do
+ return do_invoke(type, args)
+ end
+ end
+
+ def do_invoke(type, args)
+ raise Qpid::Session::Closed if @closing
+ raise Qpid::Session::Detached unless channel
+
+ # Clumsy simulation of Python's keyword args
+ kwargs = {}
+ if args.size > 0 && args[-1].is_a?(Hash)
+ if args.size > type.fields.size
+ kwargs = args.pop
+ elsif type.fields[args.size - 1].type != @spec[:map]
+ kwargs = args.pop
+ end
+ end
+
+ if type.payload
+ if args.size == type.fields.size + 1
+ message = args.pop
+ else
+ message = kwargs.delete(:message) # XXX Really ?
+ end
+ else
+ message = nil
+ end
+
+ hdr = Qpid::struct(@spec[:header])
+ hdr.sync = @auto_sync || kwargs.delete(:sync)
+
+ cmd = type.create(*args.push(kwargs))
+ sc = Qpid::StringCodec.new(@spec)
+ sc.write_command(hdr, cmd)
+
+ seg = Segment.new(true, (message.nil? ||
+ (message.headers.nil? && message.body.nil?)),
+ type.segment_type, type.track, @channel.id, sc.encoded)
+
+ unless type.result.nil?
+ result = Future.new(exception=Exception)
+ @results[@sender.next_id] = result
+ end
+ emit(seg)
+
+ log.debug("SENT %s %s %s" % [seg.id, hdr, cmd]) if log
+
+ unless message.nil?
+ unless message.headers.nil?
+ sc = Qpid::StringCodec.new(@spec)
+ message.headers.each { |st| sc.write_struct32(st) }
+
+ seg = Segment.new(false, message.body.nil?, @hdr_seg,
+ type.track, @channel.id, sc.encoded)
+ emit(seg)
+ end
+ unless message.body.nil?
+ seg = Segment.new(false, true, @body_seg, type.track,
+ @channel.id, message.body)
+ emit(seg)
+ end
+ msg.debug("SENT %s" % message) if msg
+ end
+
+ if !type.result.nil?
+ return @auto_sync ? result.get(@timeout) : result
+ elsif @auto_sync
+ sync(@timeout)
+ end
+ end
+
+ def received(seg)
+ @receiver.received(seg)
+ if seg.first_segment?
+ raise Qpid::Session::Exception unless @assembly.nil?
+ @assembly = []
+ end
+ @assembly << seg
+ if seg.last_segment?
+ dispatch(@assembly)
+ @assembly = nil
+ end
+ end
+
+ def dispatch(assembly)
+ hdr = nil
+ cmd = nil
+ header = nil
+ body = nil
+ assembly.each do |seg|
+ d = seg.decode(@spec)
+ case seg.type
+ when @cmd_seg
+ hdr, cmd = d
+ when @hdr_seg
+ header = d
+ when @body_seg
+ body = d
+ else
+ raise Qpid::Session::Exception
+ end
+ end
+ log.debug("RECV %s %s %s" % [cmd.id, hdr, cmd]) if log
+
+ if cmd.st_type.payload
+ result = @delegate.send(cmd.st_type.name, cmd, header, body)
+ else
+ result = @delegate.send(cmd.st_type.name, cmd)
+ end
+
+ unless cmd.st_type.result.nil?
+ execution_result(cmd.id, result)
+ end
+
+ if result != INCOMPLETE
+ assembly.each do |seg|
+ @receiver.has_completed(seg)
+ # XXX: don't forget to obey sync for manual completion as well
+ if hdr.sync
+ @channel.session_completed(@receiver.completed)
+ end
+ end
+ end
+ end
+
+ # Python calls this 'send', but that has a special meaning
+ # in Ruby, so we call it 'emit'
+ def emit(seg)
+ @sender.emit(seg)
+ end
+
+ def signal
+ @cond_lock.synchronize { @condition.signal }
+ end
+
+ def wait_for(timeout = nil, &block)
+ @cond_lock.synchronize { @condition.wait_for(timeout, &block) }
+ end
+
+ def to_s
+ "<Session: #{name}, #{channel}>"
+ end
+
+ class Receiver
+
+ attr_reader :completed
+ attr_accessor :next_id, :next_offset
+
+ def initialize(session)
+ @session = session
+ @next_id = nil
+ @next_offset = nil
+ @completed = Qpid::RangedSet.new()
+ end
+
+ def received(seg)
+ if @next_id.nil? || @next_offset.nil?
+ raise Exception, "todo"
+ end
+ seg.id = @next_id
+ seg.offset = @next_offset
+ if seg.last_segment?
+ @next_id += 1
+ @next_offset = 0
+ else
+ @next_offset += seg.payload.size
+ end
+ end
+
+ def has_completed(seg)
+ if seg.id.nil?
+ raise ArgumentError, "cannot complete unidentified segment"
+ end
+ if seg.last_segment?
+ @completed.add(seg.id)
+ end
+ end
+
+ def known_completed(commands)
+ completed = Qpid::RangedSet.new()
+ @completed.ranges.each do |c|
+ unless commands.ranges.find { |kc|
+ kc.contains(c.lower) && kc.contains(c.upper)
+ }
+ completed.add_range(c)
+ end
+ end
+ @completed = completed
+ end
+ end
+
+ class Sender
+
+ def initialize(session)
+ @session = session
+ @next_id = 0.to_serial
+ @next_offset = 0
+ @segments = []
+ @completed = RangedSet.new()
+ end
+
+ attr_reader :next_id, :completed
+
+ def emit(seg)
+ seg.id = @next_id
+ seg.offset = @next_offset
+ if seg.last_segment?
+ @next_id += 1
+ @next_offset = 0
+ else
+ @next_offset += seg.payload.size
+ end
+ @segments << seg
+ if @session.send_id
+ @session.send_id = false
+ @session.channel.session_command_point(seg.id, seg.offset)
+ end
+ @session.channel.connection.write_segment(seg)
+ end
+
+ def has_completed(commands)
+ @segments = @segments.reject { |seg| commands.include?(seg.id) }
+ commands.ranges.each do |range|
+ @completed.add(range.lower, range.upper)
+ end
+ end
+ end
+
+ class Incoming < Qpid::Queue
+
+ def initialize(session, destination)
+ super()
+ @session = session
+ @destination = destination
+ end
+
+ def start
+ @session.message_credit_unit.choices.each do |unit|
+ @session.message_flow(@destination, unit.value, 0xFFFFFFFF)
+ end
+ end
+
+ def stop
+ @session.message_cancel(@destination)
+ listen # Kill the listener
+ end
+ end
+
+ class Delegate
+
+ def initialize(session)
+ @session = session
+ end
+
+ #XXX: do something with incoming accepts
+ def message_accept(ma) nil; end
+
+ def execution_result(er)
+ future = @session.results.delete(er.command_id)
+ future.set(er.value)
+ end
+
+ def execution_exception(ex)
+ @session.exceptions << ex
+ end
+ end
+
+ class Client < Delegate
+
+ def log ; Qpid::logger["qpid.io.msg"]; end
+
+ def message_transfer(cmd, headers, body)
+ m = Qpid::Message.new(body)
+ m.headers = headers
+ m.id = cmd.id
+ messages = @session.incoming(cmd.destination)
+ messages.put(m)
+ log.debug("RECV %s" % m) if log
+ return INCOMPLETE
+ end
+ end
+ end
+end
diff --git a/qpid/ruby/lib/qpid/spec.rb b/qpid/ruby/lib/qpid/spec.rb
new file mode 100644
index 0000000000..b3d70d019d
--- /dev/null
+++ b/qpid/ruby/lib/qpid/spec.rb
@@ -0,0 +1,183 @@
+#
+# 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.
+#
+
+require "set"
+require "rexml/document"
+require "qpid/fields"
+require "qpid/traverse"
+
+module Qpid
+ module Spec
+
+ include REXML
+
+ class Container < Array
+
+ def initialize()
+ @cache = {}
+ end
+
+ def [](key)
+ return @cache[key] if @cache.include?(key)
+ value = do_lookup(key)
+ @cache[key] = value
+ return value
+ end
+
+ def do_lookup(key)
+ case key
+ when String
+ return find {|x| x.name == key.intern()}
+ when Symbol
+ return find {|x| x.name == key}
+ else
+ return slice(key)
+ end
+ end
+
+ def +(other)
+ copy = clone()
+ copy.concat(other)
+ return copy
+ end
+
+ end
+
+ class Reference
+
+ fields(:name)
+
+ def init(&block)
+ @resolver = block
+ end
+
+ def resolve(*args)
+ @resolver.call(*args)
+ end
+
+ end
+
+ class Loader
+
+ def initialize()
+ @stack = []
+ end
+
+ def container()
+ return Container.new()
+ end
+
+ def load(obj)
+ case obj
+ when String
+ elem = @stack[-1]
+ result = container()
+ elem.elements.each(obj) {|e|
+ @index = result.size
+ result << load(e)
+ }
+ @index = nil
+ return result
+ else
+ elem = obj
+ @stack << elem
+ begin
+ result = send(:"load_#{elem.name}")
+ ensure
+ @stack.pop()
+ end
+ return result
+ end
+ end
+
+ def element
+ @stack[-1]
+ end
+
+ def text
+ element.text
+ end
+
+ def attr(name, type = :string, default = nil, path = nil)
+ if path.nil?
+ elem = element
+ else
+ elem = nil
+ element.elements.each(path) {|elem|}
+ if elem.nil?
+ return default
+ end
+ end
+
+ value = elem.attributes[name]
+ value = value.strip() unless value.nil?
+ if value.nil?
+ default
+ else
+ send(:"parse_#{type}", value)
+ end
+ end
+
+ def parse_int(value)
+ if value.nil?
+ return nil
+ else
+ value.to_i(0)
+ end
+ end
+
+ TRUE = ["yes", "true", "1"].to_set
+ FALSE = ["no", "false", "0", nil].to_set
+
+ def parse_bool(value)
+ if TRUE.include?(value)
+ true
+ elsif FALSE.include?(value)
+ false
+ else
+ raise Exception.new("parse error, expecting boolean: #{value}")
+ end
+ end
+
+ def parse_string(value)
+ value.to_s
+ end
+
+ def parse_symbol(value)
+ value.intern() unless value.nil?
+ end
+
+ REPLACE = {" " => "_", "-" => "_"}
+ KEYWORDS = {"global" => "global_", "return" => "return_"}
+
+ def parse_name(value)
+ return if value.nil?
+
+ REPLACE.each do |k, v|
+ value = value.gsub(k, v)
+ end
+
+ value = KEYWORDS[value] if KEYWORDS.has_key? value
+ return value.intern()
+ end
+
+ end
+
+ end
+end
diff --git a/qpid/ruby/lib/qpid/spec010.rb b/qpid/ruby/lib/qpid/spec010.rb
new file mode 100644
index 0000000000..3e54115087
--- /dev/null
+++ b/qpid/ruby/lib/qpid/spec010.rb
@@ -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.
+#
+
+require "qpid/spec"
+require 'pathname'
+require 'fileutils'
+
+module Qpid::Spec010
+
+ include Qpid::Spec
+
+ # XXX: workaround for ruby bug/missfeature
+ Reference = Reference
+ Loader = Loader
+
+ class Spec
+
+ ENCODINGS = {
+ String => "str16",
+ Fixnum => "int64",
+ Bignum => "int64",
+ Float => "float",
+ NilClass => "void",
+ Array => "list",
+ Hash => "map"
+ }
+
+ fields(:major, :minor, :port, :children)
+
+ def init()
+ @controls = {}
+ @commands = {}
+ @structs = {}
+ @types = {}
+ children.each {|c|
+ case c
+ when Control
+ @controls[c.code] = c
+ when Command
+ @commands[c.code] = c
+ when Struct
+ @structs[c.code] = c
+ when Type
+ @types[c.code] = c unless c.code.nil?
+ end
+ }
+ end
+
+ attr_reader :controls, :commands, :structs, :types
+
+ def [](key)
+ return @children[key]
+ end
+
+ def encoding(klass)
+ if ENCODINGS.has_key?(klass)
+ return self[ENCODINGS[klass]]
+ end
+ for base in klass.__bases__
+ result = encoding(base)
+ return result unless result.nil?
+ end
+ end
+
+ def inspect; "spec"; end
+ end
+
+ class Constant
+
+ fields(:name, :value)
+
+ attr :parent, true
+
+ end
+
+ class Type
+
+ fields(:name, :code, :fixed, :variable)
+
+ attr :parent, true
+
+ def present?(value)
+ if @fixed == 0
+ return value
+ else
+ return !value.nil?
+ end
+ end
+
+ def encode(codec, value)
+ codec.send("write_#{name}", value)
+ end
+
+ def decode(codec)
+ return codec.send("read_#{name}")
+ end
+
+ def inspect; name; end
+
+ end
+
+ class Domain < Type
+
+ fields(:name, :type, :enum)
+
+ attr :parent, true
+
+ def encode(codec, value)
+ @type.encode(codec, value)
+ end
+
+ def decode(codec)
+ return @type.decode(codec)
+ end
+
+ end
+
+ class Enum
+ fields(:choices)
+
+ def [](choice)
+ case choice
+ when String
+ choice = choice.to_sym
+ return choices.find { |c| c.name == choice }
+ when Symbol
+ return choices.find { |c| c.name == choice }
+ else
+ return choices.find { |c| c.value == choice }
+ end
+ end
+
+ def method_missing(name, *args)
+ raise ArgumentError.new("wrong number of arguments") unless args.empty?
+ return self[name].value
+ end
+
+ end
+
+ class Choice
+ fields(:name, :value)
+ end
+
+ class Composite
+
+ fields(:name, :code, :size, :pack, :fields)
+
+ attr :parent, true
+
+ # Python calls this 'new', but that has special meaning in Ruby
+ def create(*args)
+ return Qpid::struct(self, *args)
+ end
+
+ def decode(codec)
+ codec.read_size(@size)
+ codec.read_uint16() unless @code.nil?
+ return Qpid::struct(self, self.decode_fields(codec))
+ end
+
+ def decode_fields(codec)
+ flags = 0
+ pack.times {|i| flags |= (codec.read_uint8() << 8*i)}
+
+ result = {}
+
+ fields.each_index {|i|
+ f = @fields[i]
+ if flags & (0x1 << i) != 0
+ result[f.name] = f.type.decode(codec)
+ else
+ result[f.name] = nil
+ end
+ }
+
+ return result
+ end
+
+ def encode(codec, value)
+ sc = Qpid::StringCodec.new(@spec)
+ sc.write_uint16(@code) unless @code.nil?
+ encode_fields(sc, value)
+ codec.write_size(@size, sc.encoded.size)
+ codec.write(sc.encoded)
+ end
+
+ def encode_fields(codec, values)
+ # FIXME: This could be written cleaner using select
+ # instead of flags
+ flags = 0
+ fields.each_index do |i|
+ f = fields[i]
+ flags |= (0x1 << i) if f.type.present?(values[f.name])
+ end
+
+ pack.times { |i| codec.write_uint8((flags >> 8*i) & 0xFF) }
+
+ fields.each_index do |i|
+ f = fields[i]
+ f.type.encode(codec, values[f.name]) if flags & (0x1 << i) != 0
+ end
+ end
+
+ def inspect; name; end
+
+ end
+
+ class Field
+
+ fields(:name, :type, :exceptions)
+
+ def default()
+ return nil
+ end
+
+ end
+
+ class Struct < Composite
+
+ def present?(value)
+ return !value.nil?
+ end
+
+ end
+
+ class Action < Composite; end
+
+ class Control < Action
+
+ def segment_type
+ @parent[:segment_type].enum[:control].value
+ end
+
+ def track
+ @parent[:track].enum[:control].value
+ end
+
+ end
+
+ class Command < Action
+
+ attr_accessor :payload, :result
+
+ def segment_type
+ @parent["segment_type"].enum["command"].value
+ end
+
+ def track
+ @parent["track"].enum["command"].value
+ end
+
+ end
+
+ class Doc
+ fields(:type, :title, :text)
+ end
+
+ class Loader010 < Loader
+
+ def initialize()
+ super()
+ end
+
+ def klass
+ cls = element
+ until cls.nil?
+ break if cls.name == "class"
+ cls = cls.parent
+ end
+ return cls
+ end
+
+ def scope
+ if element.name == "struct"
+ return nil
+ else
+ return class_name
+ end
+ end
+
+ def class_name
+ cls = klass
+ if cls.nil?
+ return nil
+ else
+ return parse_name(cls.attributes["name"].strip)
+ end
+ end
+
+ def class_code
+ cls = klass
+ if cls.nil?
+ return 0
+ else
+ return parse_int(cls.attributes["code"].strip)
+ end
+ end
+
+ def parse_decl(value)
+ name = parse_name(value)
+
+ s = scope
+ if s.nil?
+ return name
+ else
+ return :"#{s}_#{name}"
+ end
+ end
+
+ def parse_code(value)
+ c = parse_int(value)
+ if c.nil?
+ return nil
+ else
+ return c | (class_code << 8)
+ end
+ end
+
+ def parse_type(value)
+ name = parse_name(value.sub(".", "_"))
+ cls = class_name
+ return Reference.new {|spec|
+ candidates = [name]
+ candidates << :"#{cls}_#{name}" unless cls.nil?
+ for c in candidates
+ child = spec[c]
+ break unless child.nil?
+ end
+ if child.nil?
+ raise Exception.new("unresolved type: #{name}")
+ else
+ child
+ end
+}
+ end
+
+ def load_amqp()
+ children = nil
+
+ for s in ["constant", "type", "domain", "struct", "control",
+ "command"]
+ ch = load(s)
+ if children.nil?
+ children = ch
+ else
+ children += ch
+ end
+ children += load("class/#{s}")
+ end
+ children += load("class/command/result/struct")
+ Spec.new(attr("major", :int), attr("minor", :int), attr("port", :int),
+ children)
+ end
+
+ def load_constant()
+ Constant.new(attr("name", :decl), attr("value", :int))
+ end
+
+ def load_type()
+ Type.new(attr("name", :decl), attr("code", :code),
+ attr("fixed-width", :int), attr("variable-width", :int))
+ end
+
+ def load_domain()
+ Domain.new(attr("name", :decl), attr("type", :type), load("enum").first)
+ end
+
+ def load_enum()
+ Enum.new(load("choice"))
+ end
+
+ def load_choice()
+ Choice.new(attr("name", :name), attr("value", :int))
+ end
+
+ def load_field()
+ Field.new(attr("name", :name), attr("type", :type))
+ end
+
+ def load_struct()
+ Struct.new(attr("name", :decl), attr("code", :code), attr("size", :int),
+ attr("pack", :int), load("field"))
+ end
+
+ def load_action(cls)
+ cls.new(attr("name", :decl), attr("code", :code), 0, 2, load("field"))
+ end
+
+ def load_control()
+ load_action(Control)
+ end
+
+ def load_command()
+ result = attr("type", :type, nil, "result")
+ result = attr("name", :type, nil, "result/struct") if result.nil?
+ segs = load("segments")
+ cmd = load_action(Command)
+ cmd.result = result
+ cmd.payload = !segs.empty?
+ return cmd
+ end
+
+ def load_result()
+ true
+ end
+
+ def load_segments()
+ true
+ end
+
+ end
+
+ def self.spec_cache(specfile)
+ File::join(File::dirname(__FILE__), "spec_cache",
+ File::basename(specfile, ".xml") + ".rb_marshal")
+ end
+
+ # XXX: could be shared
+ def self.load(spec = nil)
+ return spec if spec.is_a?(Qpid::Spec010::Spec)
+ if spec.nil?
+ # FIXME: Need to add a packaging setup in here so we know where
+ # the installed spec is going to be.
+ specfile = nil
+ if ENV['AMQP_SPEC']
+ specfile = ENV['AMQP_SPEC']
+ else
+ require "qpid/config"
+ specfile = Qpid::Config.amqp_spec
+ end
+ else
+ specfile = spec
+ end
+
+ specfile_cache = spec_cache(specfile)
+ # FIXME: Check that cache is newer than specfile
+ if File::exist?(specfile_cache)
+ begin
+ spec = File::open(specfile_cache, "r") do |f|
+ Marshal::load(f)
+ end
+ return spec
+ rescue
+ # Ignore, will load from XML
+ end
+ end
+
+ doc = File::open(specfile, "r") { |f| Document.new(f) }
+ spec = Loader010.new().load(doc.root)
+ spec.traverse! do |o|
+ if o.is_a?(Reference)
+ o.resolve(spec)
+ else
+ o
+ end
+ end
+
+ spec.children.each { |c| c.parent = spec }
+
+ begin
+ FileUtils::mkdir_p(File::dirname(specfile_cache))
+ File::open(specfile_cache, "w") { |f| Marshal::dump(spec, f) }
+ rescue
+ # Ignore, we are fine without the cached spec
+ end
+ return spec
+ end
+
+end
diff --git a/qpid/ruby/lib/qpid/spec08.rb b/qpid/ruby/lib/qpid/spec08.rb
new file mode 100644
index 0000000000..902c05c297
--- /dev/null
+++ b/qpid/ruby/lib/qpid/spec08.rb
@@ -0,0 +1,190 @@
+#
+# 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.
+#
+
+require "qpid/spec"
+
+module Qpid08
+
+ module Spec
+
+ include Qpid::Spec
+
+ # XXX: workaround for ruby bug/missfeature
+ Reference = Reference
+
+ class Root
+ fields(:major, :minor, :classes, :constants, :domains)
+
+ def find_method(name)
+ classes.each do |c|
+ c.methods.each do |m|
+ if name == m.qname
+ return m
+ end
+ end
+ end
+
+ return nil
+ end
+ end
+
+ class Constant
+ fields(:name, :id, :type, :docs)
+ end
+
+ class Domain
+ fields(:name, :type)
+ end
+
+ class Class
+ fields(:name, :id, :handler, :fields, :methods, :docs)
+ end
+
+ class Method
+ fields(:name, :id, :content?, :responses, :synchronous?, :fields,
+ :docs)
+
+ def init()
+ @response = false
+ end
+
+ attr :parent, true
+
+ def response?; @response end
+ def response=(b); @response = b end
+
+ def qname
+ :"#{parent.name}_#{name}"
+ end
+ end
+
+ class Field
+ fields(:name, :id, :type, :docs)
+
+ def default
+ case type
+ when :bit then false
+ when :octet, :short, :long, :longlong then 0
+ when :shortstr, :longstr then ""
+ when :table then {}
+ end
+ end
+ end
+
+ class Doc
+ fields(:type, :text)
+ end
+
+ class Container08 < Container
+ def do_lookup(key)
+ case key
+ when Integer
+ return find {|x| x.id == key}
+ else
+ return super(key)
+ end
+ end
+ end
+
+ class Loader08 < Loader
+
+ def container()
+ return Container08.new()
+ end
+
+ def load_amqp()
+ Root.new(attr("major", :int), attr("minor", :int), load("class"),
+ load("constant"), load("domain"))
+ end
+
+ def load_class()
+ Class.new(attr("name", :name), attr("index", :int), attr("handler", :name),
+ load("field"), load("method"), load("doc"))
+ end
+
+ def load_method()
+ Method.new(attr("name", :name), attr("index", :int),
+ attr("content", :bool), load("response"),
+ attr("synchronous", :bool), load("field"), load("docs"))
+ end
+
+ def load_response()
+ name = attr("name", :name)
+ Reference.new {|spec, klass|
+ response = klass.methods[name]
+ if response.nil?
+ raise Exception.new("no such method: #{name}")
+ end
+ response
+ }
+ end
+
+ def load_field()
+ type = attr("type", :name)
+ if type.nil?
+ domain = attr("domain", :name)
+ type = Reference.new {|spec, klass|
+ spec.domains[domain].type
+ }
+ end
+ Field.new(attr("name", :name), @index, type, load("docs"))
+ end
+
+ def load_constant()
+ Constant.new(attr("name", :name), attr("value", :int), attr("class", :name),
+ load("doc"))
+ end
+
+ def load_domain()
+ Domain.new(attr("name", :name), attr("type", :name))
+ end
+
+ def load_doc()
+ Doc.new(attr("type", :symbol), text)
+ end
+
+ end
+
+ def self.load(spec)
+ case spec
+ when String
+ spec = File.new(spec)
+ end
+ doc = Document.new(spec)
+ spec = Loader08.new().load(doc.root)
+ spec.classes.each do |klass|
+ klass.traverse! do |o|
+ case o
+ when Reference
+ o.resolve(spec, klass)
+ else
+ o
+ end
+ end
+ klass.methods.each do |m|
+ m.parent = klass
+ m.responses.each do |r|
+ r.response = true
+ end
+ end
+ end
+ return spec
+ end
+ end
+end
diff --git a/qpid/ruby/lib/qpid/specs/amqp.0-10-qpid-errata.xml b/qpid/ruby/lib/qpid/specs/amqp.0-10-qpid-errata.xml
new file mode 100644
index 0000000000..365928ea4e
--- /dev/null
+++ b/qpid/ruby/lib/qpid/specs/amqp.0-10-qpid-errata.xml
@@ -0,0 +1,6654 @@
+<?xml version="1.0"?>
+
+<!--
+ Copyright Notice
+ ================
+ (c) Copyright Cisco Systems, Credit Suisse, Deutsche Borse Systems, Envoy Technologies, Inc.,
+ Goldman Sachs, IONA Technologies PLC, iMatix Corporation sprl.,JPMorgan Chase Bank Inc. N.A,
+ Novell, Rabbit Technologies Ltd., Red Hat, Inc., TWIST Process Innovations ltd, and 29West Inc.
+ 2006, 2007. All rights reserved.
+
+ License
+ =======
+
+ Cisco Systems, Credit Suisse, Deutsche Borse Systems, Envoy Technologies, Inc.,Goldman Sachs,
+ IONA Technologies PLC, iMatix Corporation sprl.,JPMorgan Chase Bank Inc. N.A, Novell, Rabbit
+ Technologies Ltd., Red Hat, Inc., TWIST Process Innovations ltd, and 29West Inc. (collectively,
+ the "Authors") each hereby grants to you a worldwide, perpetual, royalty-free, nontransferable,
+ nonexclusive license to (i) copy, display, distribute and implement the Advanced Messaging Queue
+ Protocol ("AMQP") Specification and (ii) the Licensed Claims that are held by the Authors, all for
+ the purpose of implementing the Advanced Messaging Queue Protocol Specification. Your license and
+ any rights under this Agreement will terminate immediately without notice from any Author if you
+ bring any claim, suit, demand, or action related to the Advanced Messaging Queue Protocol
+ Specification against any Author. Upon termination, you shall destroy all copies of the Advanced
+ Messaging Queue Protocol Specification in your possession or control.
+
+ As used hereunder, "Licensed Claims" means those claims of a patent or patent application,
+ throughout the world, excluding design patents and design registrations, owned or controlled, or
+ that can be sublicensed without fee and in compliance with the requirements of this Agreement, by
+ an Author or its affiliates now or at any future time and which would necessarily be infringed by
+ implementation of the Advanced Messaging Queue Protocol Specification. A claim is necessarily
+ infringed hereunder only when it is not possible to avoid infringing it because there is no
+ plausible non-infringing alternative for implementing the required portions of the Advanced
+ Messaging Queue Protocol Specification. Notwithstanding the foregoing, Licensed Claims shall not
+ include any claims other than as set forth above even if contained in the same patent as Licensed
+ Claims; or that read solely on any implementations of any portion of the Advanced Messaging Queue
+ Protocol Specification that are not required by the Advanced Messaging Queue Protocol
+ Specification, or that, if licensed, would require a payment of royalties by the licensor to
+ unaffiliated third parties. Moreover, Licensed Claims shall not include (i) any enabling
+ technologies that may be necessary to make or use any Licensed Product but are not themselves
+ expressly set forth in the Advanced Messaging Queue Protocol Specification (e.g., semiconductor
+ manufacturing technology, compiler technology, object oriented technology, networking technology,
+ operating system technology, and the like); or (ii) the implementation of other published
+ standards developed elsewhere and merely referred to in the body of the Advanced Messaging Queue
+ Protocol Specification, or (iii) any Licensed Product and any combinations thereof the purpose or
+ function of which is not required for compliance with the Advanced Messaging Queue Protocol
+ Specification. For purposes of this definition, the Advanced Messaging Queue Protocol
+ Specification shall be deemed to include both architectural and interconnection requirements
+ essential for interoperability and may also include supporting source code artifacts where such
+ architectural, interconnection requirements and source code artifacts are expressly identified as
+ being required or documentation to achieve compliance with the Advanced Messaging Queue Protocol
+ Specification.
+
+ As used hereunder, "Licensed Products" means only those specific portions of products (hardware,
+ software or combinations thereof) that implement and are compliant with all relevant portions of
+ the Advanced Messaging Queue Protocol Specification.
+
+ The following disclaimers, which you hereby also acknowledge as to any use you may make of the
+ Advanced Messaging Queue Protocol Specification:
+
+ THE ADVANCED MESSAGING QUEUE PROTOCOL SPECIFICATION IS PROVIDED "AS IS," AND THE AUTHORS MAKE NO
+ REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, OR TITLE; THAT THE CONTENTS
+ OF THE ADVANCED MESSAGING QUEUE PROTOCOL SPECIFICATION ARE SUITABLE FOR ANY PURPOSE; NOR THAT THE
+ IMPLEMENTATION OF THE ADVANCED MESSAGING QUEUE PROTOCOL SPECIFICATION WILL NOT INFRINGE ANY THIRD
+ PARTY PATENTS, COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS.
+
+ THE AUTHORS WILL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL
+ DAMAGES ARISING OUT OF OR RELATING TO ANY USE, IMPLEMENTATION OR DISTRIBUTION OF THE ADVANCED
+ MESSAGING QUEUE PROTOCOL SPECIFICATION.
+
+ The name and trademarks of the Authors may NOT be used in any manner, including advertising or
+ publicity pertaining to the Advanced Messaging Queue Protocol Specification or its contents
+ without specific, written prior permission. Title to copyright in the Advanced Messaging Queue
+ Protocol Specification will at all times remain with the Authors.
+
+ No other rights are granted by implication, estoppel or otherwise.
+
+ Upon termination of your license or rights under this Agreement, you shall destroy all copies of
+ the Advanced Messaging Queue Protocol Specification in your possession or control.
+
+ Trademarks
+ ==========
+ "JPMorgan", "JPMorgan Chase", "Chase", the JPMorgan Chase logo and the Octagon Symbol are
+ trademarks of JPMorgan Chase & Co.
+
+ IMATIX and the iMatix logo are trademarks of iMatix Corporation sprl.
+
+ IONA, IONA Technologies, and the IONA logos are trademarks of IONA Technologies PLC and/or its
+ subsidiaries.
+
+ LINUX is a trademark of Linus Torvalds. RED HAT and JBOSS are registered trademarks of Red Hat,
+ Inc. in the US and other countries.
+
+ Java, all Java-based trademarks and OpenOffice.org are trademarks of Sun Microsystems, Inc. in the
+ United States, other countries, or both.
+
+ Other company, product, or service names may be trademarks or service marks of others.
+
+ Links to full AMQP specification:
+ =================================
+ http://www.envoytech.org/spec/amq/
+ http://www.iona.com/opensource/amqp/
+ http://www.redhat.com/solutions/specifications/amqp/
+ http://www.twiststandards.org/tiki-index.php?page=AMQ
+ http://www.imatix.com/amqp
+-->
+
+<!--
+ XML Notes
+ =========
+
+ We use entities to indicate repetition; attributes to indicate properties.
+
+ We use the "name" attribute as an identifier, usually within the context of the surrounding
+ entities.
+
+ We use hyphens (minus char '-') to seperate words in names.
+
+ We do not enforce any particular validation mechanism but we support all mechanisms. The protocol
+ definition conforms to a formal grammar that is published seperately in several technologies.
+
+-->
+
+<!DOCTYPE amqp SYSTEM "amqp.0-10.dtd">
+
+<amqp xmlns="http://www.amqp.org/schema/amqp.xsd"
+ major="0" minor="10" port="5672">
+
+ <!--
+ ====================== == type definitions == ======================
+ -->
+
+ <!--
+ 0x00 - 0x0f: Fixed width, 1 octet
+ -->
+
+ <type name="bin8" code="0x00" fixed-width="1" label="octet of unspecified encoding">
+ <doc>
+ The bin8 type consists of exactly one octet of opaque binary data.
+ </doc>
+
+ <doc type="picture" title="Wire Format">
+ 1 OCTET
+ +----------+
+ | bin8 |
+ +----------+
+ </doc>
+
+ <doc type="bnf">
+ bin8 = OCTET
+ </doc>
+ </type>
+
+ <type name="int8" code="0x01" fixed-width="1" label="8-bit signed integral value (-128 - 127)">
+ <doc>
+ The int8 type is a signed integral value encoded using an 8-bit two's complement
+ representation.
+ </doc>
+
+ <doc type="picture" title="Wire Format">
+ 1 OCTET
+ +----------+
+ | int8 |
+ +----------+
+ </doc>
+
+ <doc type="bnf">
+ int8 = OCTET
+ </doc>
+ </type>
+
+ <type name="uint8" code="0x02" fixed-width="1" label="8-bit unsigned integral value (0 - 255)">
+ <doc>
+ The uint8 type is an 8-bit unsigned integral value.
+ </doc>
+
+ <doc type="picture" title="Wire Format">
+ 1 OCTET
+ +---------+
+ | uint8 |
+ +---------+
+ </doc>
+
+ <doc type="bnf">
+ uint8 = OCTET
+ </doc>
+ </type>
+
+ <type name="char" code="0x04" fixed-width="1" label="an iso-8859-15 character">
+ <doc>
+ The char type encodes a single character from the iso-8859-15 character set.
+ </doc>
+
+ <doc type="picture" title="Wire Format">
+ 1 OCTET
+ +----------+
+ | char |
+ +----------+
+ </doc>
+
+ <doc type="bnf">
+ char = OCTET
+ </doc>
+ </type>
+
+ <type name="boolean" code="0x08" fixed-width="1"
+ label="boolean value (zero represents false, nonzero represents true)">
+ <doc>
+ The boolean type is a single octet that encodes a true or false value. If the octet is zero,
+ then the boolean is false. Any other value represents true.
+ </doc>
+
+ <doc type="picture" title="Wire Format">
+ 1 OCTET
+ +---------+
+ | boolean |
+ +---------+
+ </doc>
+
+ <doc type="bnf">
+ boolean = OCTET
+ </doc>
+ </type>
+
+ <!--
+ 0x10 - 0x1f: Fixed width, 2 octets
+ -->
+
+ <type name="bin16" code="0x10" fixed-width="2" label="two octets of unspecified binary encoding">
+ <doc>
+ The bin16 type consists of two consecutive octets of opaque binary data.
+ </doc>
+
+ <doc type="picture" title="Wire Format">
+ 1 OCTET 1 OCTET
+ +-----------+-----------+
+ | octet-one | octet-two |
+ +-----------+-----------+
+ </doc>
+
+ <doc type="bnf">
+ bin16 = 2 OCTET
+ </doc>
+ </type>
+
+ <type name="int16" code="0x11" fixed-width="2" label="16-bit signed integral value">
+ <doc>
+ The int16 type is a signed integral value encoded using a 16-bit two's complement
+ representation in network byte order.
+ </doc>
+
+ <doc type="picture" title="Wire Format">
+ 1 OCTET 1 OCTET
+ +-----------+----------+
+ | high-byte | low-byte |
+ +-----------+----------+
+ </doc>
+
+ <doc type="bnf">
+ int16 = high-byte low-byte
+ high-byte = OCTET
+ low-byte = OCTET
+ </doc>
+ </type>
+
+ <type name="uint16" code="0x12" fixed-width="2" label="16-bit unsigned integer">
+ <doc>
+ The uint16 type is a 16-bit unsigned integral value encoded in network byte order.
+ </doc>
+
+ <doc type="picture" title="Wire Format">
+ 1 OCTET 1 OCTET
+ +-----------+----------+
+ | high-byte | low-byte |
+ +-----------+----------+
+ </doc>
+
+ <doc type="bnf">
+ uint16 = high-byte low-byte
+ high-byte = OCTET
+ low-byte = OCTET
+ </doc>
+ </type>
+
+ <!--
+ 0x20 - 0x2f: Fixed width, 4 octets
+ -->
+
+ <type name="bin32" code="0x20" fixed-width="4" label="four octets of unspecified binary encoding">
+ <doc>
+ The bin32 type consists of 4 consecutive octets of opaque binary data.
+ </doc>
+
+ <doc type="picture" title="Wire Format">
+ 1 OCTET 1 OCTET 1 OCTET 1 OCTET
+ +-----------+-----------+-------------+------------+
+ | octet-one | octet-two | octet-three | octet-four |
+ +-----------+-----------+-------------+------------+
+ </doc>
+
+ <doc type="bnf">
+ bin32 = 4 OCTET
+ </doc>
+ </type>
+
+ <type name="int32" code="0x21" fixed-width="4" label="32-bit signed integral value">
+ <doc>
+ The int32 type is a signed integral value encoded using a 32-bit two's complement
+ representation in network byte order.
+ </doc>
+
+ <doc type="picture" title="Wire Format">
+ 1 OCTET 1 OCTET 1 OCTET 1 OCTET
+ +-----------+------------+----------+----------+
+ | byte-four | byte-three | byte-two | byte-one |
+ +-----------+------------+----------+----------+
+ MSB LSB
+ </doc>
+
+ <doc type="bnf">
+ int32 = byte-four byte-three byte-two byte-one
+ byte-four = OCTET ; most significant byte (MSB)
+ byte-three = OCTET
+ byte-two = OCTET
+ byte-one = OCTET ; least significant byte (LSB)
+ </doc>
+ </type>
+
+ <type name="uint32" code="0x22" fixed-width="4" label="32-bit unsigned integral value">
+ <doc>
+ The uint32 type is a 32-bit unsigned integral value encoded in network byte order.
+ </doc>
+
+ <doc type="picture" title="Wire Format">
+ 1 OCTET 1 OCTET 1 OCTET 1 OCTET
+ +-----------+------------+----------+----------+
+ | byte-four | byte-three | byte-two | byte-one |
+ +-----------+------------+----------+----------+
+ MSB LSB
+ </doc>
+
+ <doc type="bnf">
+ uint32 = byte-four byte-three byte-two byte-one
+ byte-four = OCTET ; most significant byte (MSB)
+ byte-three = OCTET
+ byte-two = OCTET
+ byte-one = OCTET ; least significant byte (LSB)
+ </doc>
+ </type>
+
+ <type name="float" code="0x23" fixed-width="4"
+ label="single precision IEEE 754 32-bit floating point">
+ <doc>
+ The float type encodes a single precision 32-bit floating point number. The format and
+ operations are defined by the IEEE 754 standard for 32-bit floating point numbers.
+ </doc>
+
+ <doc type="picture" title="Wire Format">
+ 4 OCTETs
+ +-----------------------+
+ | float |
+ +-----------------------+
+ IEEE 754 32-bit float
+ </doc>
+
+ <doc type="bnf">
+ float = 4 OCTET ; IEEE 754 32-bit floating point number
+ </doc>
+ </type>
+
+ <type name="char-utf32" code="0x27" fixed-width="4"
+ label="single unicode character in UTF-32 encoding">
+ <doc>
+ The char-utf32 type consists of a single unicode character in the UTF-32 encoding.
+ </doc>
+
+ <doc type="picture" title="Wire Format">
+ 4 OCTETs
+ +------------------+
+ | char-utf32 |
+ +------------------+
+ UTF-32 character
+ </doc>
+
+ <doc type="bnf">
+ char-utf32 = 4 OCTET ; single UTF-32 character
+ </doc>
+ </type>
+
+ <type name="sequence-no" fixed-width="4" label="serial number defined in RFC-1982">
+ <doc>
+ The sequence-no type encodes, in network byte order, a serial number as defined in RFC-1982.
+ The arithmetic, operators, and ranges for numbers of this type are defined by RFC-1982.
+ </doc>
+
+ <doc type="picture" title="Wire Format">
+ 4 OCTETs
+ +------------------------+
+ | sequence-no |
+ +------------------------+
+ RFC-1982 serial number
+ </doc>
+
+ <doc type="bnf">
+ sequence-no = 4 OCTET ; RFC-1982 serial number
+ </doc>
+ </type>
+
+ <!--
+ 0x30 - 0x3f: Fixed width types - 8 octets
+ -->
+
+ <type name="bin64" code="0x30" fixed-width="8"
+ label="eight octets of unspecified binary encoding">
+ <doc>
+ The bin64 type consists of eight consecutive octets of opaque binary data.
+ </doc>
+
+ <doc type="picture" title="Wire Format">
+ 1 OCTET 1 OCTET 1 OCTET 1 OCTET
+ +-----------+-----------+-----+-------------+-------------+
+ | octet-one | octet-two | ... | octet-seven | octet-eight |
+ +-----------+-----------+-----+-------------+-------------+
+ </doc>
+
+ <doc type="bnf">
+ bin64 = 8 OCTET
+ </doc>
+ </type>
+
+ <type name="int64" code="0x31" fixed-width="8" label="64-bit signed integral value">
+ <doc>
+ The int64 type is a signed integral value encoded using a 64-bit two's complement
+ representation in network byte order.
+ </doc>
+
+ <doc type="picture" title="Wire Format">
+ 1 OCTET 1 OCTET 1 OCTET 1 OCTET
+ +------------+------------+-----+----------+----------+
+ | byte-eight | byte-seven | ... | byte-two | byte-one |
+ +------------+------------+-----+----------+----------+
+ MSB LSB
+ </doc>
+
+ <doc type="bnf">
+ int64 = byte-eight byte-seven byte-six byte-five
+ byte-four byte-three byte-two byte-one
+ byte-eight = 1 OCTET ; most significant byte (MSB)
+ byte-seven = 1 OCTET
+ byte-six = 1 OCTET
+ byte-five = 1 OCTET
+ byte-four = 1 OCTET
+ byte-three = 1 OCTET
+ byte-two = 1 OCTET
+ byte-one = 1 OCTET ; least significant byte (LSB)
+ </doc>
+ </type>
+
+ <type name="uint64" code="0x32" fixed-width="8" label="64-bit unsigned integral value">
+ <doc>
+ The uint64 type is a 64-bit unsigned integral value encoded in network byte order.
+ </doc>
+
+ <doc type="picture" title="Wire Format">
+ 1 OCTET 1 OCTET 1 OCTET 1 OCTET
+ +------------+------------+-----+----------+----------+
+ | byte-eight | byte-seven | ... | byte-two | byte-one |
+ +------------+------------+-----+----------+----------+
+ MSB LSB
+ </doc>
+
+ <doc type="bnf">
+ uint64 = byte-eight byte-seven byte-six byte-five
+ byte-four byte-three byte-two byte-one
+ byte-eight = 1 OCTET ; most significant byte (MSB)
+ byte-seven = 1 OCTET
+ byte-six = 1 OCTET
+ byte-five = 1 OCTET
+ byte-four = 1 OCTET
+ byte-three = 1 OCTET
+ byte-two = 1 OCTET
+ byte-one = 1 OCTET ; least significant byte (LSB)
+ </doc>
+ </type>
+
+ <type name="double" code="0x33" fixed-width="8" label="double precision IEEE 754 floating point">
+ <doc>
+ The double type encodes a double precision 64-bit floating point number. The format and
+ operations are defined by the IEEE 754 standard for 64-bit double precision floating point
+ numbers.
+ </doc>
+
+ <doc type="picture" title="Wire Format">
+ 8 OCTETs
+ +-----------------------+
+ | double |
+ +-----------------------+
+ IEEE 754 64-bit float
+ </doc>
+
+ <doc type="bnf">
+ double = 8 OCTET ; double precision IEEE 754 floating point number
+ </doc>
+ </type>
+
+ <type name="datetime" code="0x38" fixed-width="8" label="datetime in 64 bit POSIX time_t format">
+ <doc>
+ The datetime type encodes a date and time using the 64 bit POSIX time_t format.
+ </doc>
+
+ <doc type="picture" title="Wire Format">
+ 8 OCTETs
+ +---------------------+
+ | datetime |
+ +---------------------+
+ posix time_t format
+ </doc>
+
+ <doc type="bnf">
+ datetime = 8 OCTET ; 64 bit posix time_t format
+ </doc>
+ </type>
+
+ <!--
+ 0x40 - 0x4f: Fixed width types - 16 octets
+ -->
+
+ <type name="bin128" code="0x40" fixed-width="16"
+ label="sixteen octets of unspecified binary encoding">
+ <doc>
+ The bin128 type consists of 16 consecutive octets of opaque binary data.
+ </doc>
+
+ <doc type="picture" title="Wire Format">
+ 1 OCTET 1 OCTET 1 OCTET 1 OCTET
+ +-----------+-----------+-----+---------------+---------------+
+ | octet-one | octet-two | ... | octet-fifteen | octet-sixteen |
+ +-----------+-----------+-----+---------------+---------------+
+ </doc>
+
+ <doc type="bnf">
+ bin128 = 16 OCTET
+ </doc>
+ </type>
+
+ <type name="uuid" code="0x48" fixed-width="16" label="UUID (RFC-4122 section 4.1.2) - 16 octets">
+ <doc>
+ The uuid type encodes a universally unique id as defined by RFC-4122. The format and
+ operations for this type can be found in section 4.1.2 of RFC-4122.
+ </doc>
+
+ <doc type="picture" title="Wire Format">
+ 16 OCTETs
+ +---------------+
+ | uuid |
+ +---------------+
+ RFC-4122 UUID
+ </doc>
+
+ <doc type="bnf">
+ uuid = 16 OCTET ; RFC-4122 section 4.1.2
+ </doc>
+ </type>
+
+ <!--
+ 0x50 - 0x5f: Fixed width types - 32 octets
+ -->
+
+ <type name="bin256" code="0x50" fixed-width="32"
+ label="thirty two octets of unspecified binary encoding">
+ <doc>
+ The bin256 type consists of thirty two consecutive octets of opaque binary data.
+ </doc>
+
+ <doc type="picture" title="Wire Format">
+ 1 OCTET 1 OCTET 1 OCTET 1 OCTET
+ +-----------+-----------+-----+------------------+------------------+
+ | octet-one | octet-two | ... | octet-thirty-one | octet-thirty-two |
+ +-----------+-----------+-----+------------------+------------------+
+ </doc>
+
+ <doc type="bnf">
+ bin256 = 32 OCTET
+ </doc>
+ </type>
+
+ <!--
+ 0x60 - 0x6f: Fixed width types - 64 octets
+ -->
+
+ <type name="bin512" code="0x60" fixed-width="64"
+ label="sixty four octets of unspecified binary encoding">
+ <doc>
+ The bin512 type consists of sixty four consecutive octets of opaque binary data.
+ </doc>
+
+ <doc type="picture" title="Wire Format">
+ 1 OCTET 1 OCTET 1 OCTET 1 OCTET
+ +-----------+-----------+-----+-------------------+------------------+
+ | octet-one | octet-two | ... | octet-sixty-three | octet-sixty-four |
+ +-----------+-----------+-----+-------------------+------------------+
+ </doc>
+
+ <doc type="bnf">
+ bin512 = 64 OCTET
+ </doc>
+ </type>
+
+ <!--
+ 0x70 - 0x7f: Fixed width types - 128 octets
+ -->
+
+ <type name="bin1024" code="0x70" fixed-width="128"
+ label="one hundred and twenty eight octets of unspecified binary encoding">
+ <doc>
+ The bin1024 type consists of one hundred and twenty eight octets of opaque binary data.
+ </doc>
+
+ <doc type="picture" title="Wire Format">
+ 1 OCTET 1 OCTET 1 OCTET 1 OCTET
+ +-----------+-----------+-----+------------------------+------------------------+
+ | octet-one | octet-two | ... | octet-one-twenty-seven | octet-one-twenty-eight |
+ +-----------+-----------+-----+------------------------+------------------------+
+ </doc>
+
+ <doc type="bnf">
+ bin1024 = 128 OCTET
+ </doc>
+ </type>
+
+ <!--
+ 0x80 - 0x8f: Variable length - one byte length field (up to 255 octets)
+ -->
+
+ <type name="vbin8" code="0x80" variable-width="1" label="up to 255 octets of opaque binary data">
+ <doc>
+ The vbin8 type encodes up to 255 octets of opaque binary data. The number of octets is first
+ encoded as an 8-bit unsigned integral value. This is followed by the actual data.
+ </doc>
+
+ <doc type="picture" title="Wire Format">
+ 1 OCTET size OCTETs
+ +---------+-------------+
+ | size | octets |
+ +---------+-------------+
+ uint8
+ </doc>
+
+ <doc type="bnf">
+ vbin8 = size octets
+ size = uint8
+ octets = 0*255 OCTET ; size OCTETs
+ </doc>
+ </type>
+
+ <type name="str8-latin" code="0x84" variable-width="1" label="up to 255 iso-8859-15 characters">
+ <doc>
+ The str8-latin type encodes up to 255 octets of iso-8859-15 characters. The number of octets
+ is first encoded as an 8-bit unsigned integral value. This is followed by the actual
+ characters.
+ </doc>
+
+ <doc type="picture" title="Wire Format">
+ 1 OCTET size OCTETs
+ +---------+------------------------+
+ | size | characters |
+ +---------+------------------------+
+ uint16 iso-8859-15 characters
+ </doc>
+
+ <doc type="bnf">
+ str8-latin = size characters
+ size = uint8
+ characters = 0*255 OCTET ; size OCTETs
+ </doc>
+ </type>
+
+ <type name="str8" code="0x85" variable-width="1" label="up to 255 octets worth of UTF-8 unicode">
+ <doc>
+ The str8 type encodes up to 255 octets worth of UTF-8 unicode. The number of octets of unicode
+ is first encoded as an 8-bit unsigned integral value. This is followed by the actual UTF-8
+ unicode. Note that the encoded size refers to the number of octets of unicode, not necessarily
+ the number of characters since the UTF-8 unicode may include multi-byte character sequences.
+ </doc>
+
+ <doc type="picture" title="Wire Format">
+ 1 OCTET size OCTETs
+ +---------+--------------+
+ | size | utf8-unicode |
+ +---------+--------------+
+ uint8
+ </doc>
+
+ <doc type="bnf">
+ str8 = size utf8-unicode
+ size = uint8
+ utf8-unicode = 0*255 OCTET ; size OCTETs
+ </doc>
+ </type>
+
+ <type name="str8-utf16" code="0x86" variable-width="1"
+ label="up to 255 octets worth of UTF-16 unicode">
+ <doc>
+ The str8-utf16 type encodes up to 255 octets worth of UTF-16 unicode. The number of octets of
+ unicode is first encoded as an 8-bit unsigned integral value. This is followed by the actual
+ UTF-16 unicode. Note that the encoded size refers to the number of octets of unicode, not the
+ number of characters since the UTF-16 unicode will include at least two octets per unicode
+ character.
+ </doc>
+
+ <doc type="picture" title="Wire Format">
+ 1 OCTET size OCTETs
+ +---------+---------------+
+ | size | utf16-unicode |
+ +---------+---------------+
+ uint8
+ </doc>
+
+ <doc type="bnf">
+ str8-utf16 = size utf16-unicode
+ size = uint8
+ utf16-unicode = 0*255 OCTET ; size OCTETs
+ </doc>
+ </type>
+
+ <!--
+ 0x90 - 0x9f: Variable length types - two byte length field (up to 65535 octets)
+ -->
+
+ <type name="vbin16" code="0x90" variable-width="2"
+ label="up to 65535 octets of opaque binary data">
+ <doc>
+ The vbin16 type encodes up to 65535 octets of opaque binary data. The number of octets is
+ first encoded as a 16-bit unsigned integral value in network byte order. This is followed by
+ the actual data.
+ </doc>
+
+ <doc type="picture" title="Wire Format">
+ 2 OCTETs size OCTETs
+ +----------+-------------+
+ | size | octets |
+ +----------+-------------+
+ uint16
+ </doc>
+
+ <doc type="bnf">
+ vbin16 = size octets
+ size = uint16
+ octets = 0*65535 OCTET ; size OCTETs
+ </doc>
+ </type>
+
+ <type name="str16-latin" code="0x94" variable-width="2"
+ label="up to 65535 iso-8859-15 characters">
+ <doc>
+ The str16-latin type encodes up to 65535 octets of is-8859-15 characters. The number of octets
+ is first encoded as a 16-bit unsigned integral value in network byte order. This is followed
+ by the actual characters.
+ </doc>
+
+ <doc type="picture" title="Wire Format">
+ 2 OCTETs size OCTETs
+ +----------+------------------------+
+ | size | characters |
+ +----------+------------------------+
+ uint16 iso-8859-15 characters
+ </doc>
+
+ <doc type="bnf">
+ str16-latin = size characters
+ size = uint16
+ characters = 0*65535 OCTET ; size OCTETs
+ </doc>
+ </type>
+
+ <type name="str16" code="0x95" variable-width="2"
+ label="up to 65535 octets worth of UTF-8 unicode">
+ <doc>
+ The str16 type encodes up to 65535 octets worth of UTF-8 unicode. The number of octets is
+ first encoded as a 16-bit unsigned integral value in network byte order. This is followed by
+ the actual UTF-8 unicode. Note that the encoded size refers to the number of octets of
+ unicode, not necessarily the number of unicode characters since the UTF-8 unicode may include
+ multi-byte character sequences.
+ </doc>
+
+ <doc type="picture" title="Wire Format">
+ 2 OCTETs size OCTETs
+ +----------+--------------+
+ | size | utf8-unicode |
+ +----------+--------------+
+ uint16
+ </doc>
+
+ <doc type="bnf">
+ str16 = size utf8-unicode
+ size = uint16
+ utf8-unicode = 0*65535 OCTET ; size OCTETs
+ </doc>
+ </type>
+
+ <type name="str16-utf16" code="0x96" variable-width="2"
+ label="up to 65535 octets worth of UTF-16 unicode">
+ <doc>
+ The str16-utf16 type encodes up to 65535 octets worth of UTF-16 unicode. The number of octets
+ is first encoded as a 16-bit unsigned integral value in network byte order. This is followed
+ by the actual UTF-16 unicode. Note that the encoded size refers to the number of octets of
+ unicode, not the number of unicode characters since the UTF-16 unicode will include at least
+ two octets per unicode character.
+ </doc>
+
+ <doc type="picture" title="Wire Format">
+ 2 OCTETs size OCTETs
+ +----------+---------------+
+ | size | utf16-unicode |
+ +----------+---------------+
+ uint16
+ </doc>
+
+ <doc type="bnf">
+ str16-utf16 = size utf16-unicode
+ size = uint16
+ utf16-unicode = 0*65535 OCTET ; size OCTETs
+ </doc>
+ </type>
+
+ <type name="byte-ranges" variable-width="2" label="byte ranges within a 64-bit payload">
+ <doc>
+ The byte-ranges type encodes up to 65535 octets worth of non-overlapping, non-touching,
+ ascending byte ranges within a 64-bit sequence of bytes. Each range is represented as an
+ inclusive lower and upper bound that identifies all the byte offsets included within a given
+ range.
+ </doc>
+
+ <doc>
+ The number of octets of data is first encoded as a 16-bit unsigned integral value in network
+ byte order. This is then followed by the encoded representation of the ranges included in the
+ set. These MUST be encoded in ascending order, and any two ranges included in a given set MUST
+ NOT include overlapping or touching byte offsets.
+ </doc>
+
+ <doc>
+ Each range is encoded as a pair of 64-bit unsigned integral values in network byte order
+ respectively representing the lower and upper bounds for that range. Note that because each
+ range is exactly 16 octets, the size in octets of the encoded ranges will always be 16 times
+ the number of ranges in the set.
+ </doc>
+
+ <doc type="picture" title="Wire Format">
+ +----= size OCTETs =----+
+ | |
+ 2 OCTETs | 16 OCTETs |
+ +----------+-----+-----------+-----+
+ | size | .../| range |\... |
+ +----------+---/ +-----------+ \---+
+ uint16 / / \ \
+ / / \ \
+ / 8 OCTETs 8 OCTETs \
+ +-----------+-----------+
+ | lower | upper |
+ +-----------+-----------+
+ uint64 uint64
+ </doc>
+
+ <doc type="bnf">
+ byte-ranges = size *range
+ size = uint16
+ range = lower upper
+ lower = uint64
+ upper = uint64
+ </doc>
+ </type>
+
+ <type name="sequence-set" variable-width="2" label="ranged set representation">
+ <doc>
+ The sequence-set type is a set of pairs of RFC-1982 numbers representing a discontinuous range
+ within an RFC-1982 sequence. Each pair represents a closed interval within the list.
+ </doc>
+
+ <doc>
+ Sequence-sets can be represented as lists of pairs of positive 32-bit numbers, each pair
+ representing a closed interval that does not overlap or touch with any other interval in the
+ list. For example, a set containing words 0, 1, 2, 5, 6, and 15 can be represented:
+ </doc>
+
+ <doc type="picture">
+ [(0, 2), (5, 6), (15, 15)]
+ </doc>
+
+ <doc>
+ 1) The list-of-pairs representation is sorted ascending (as defined by RFC 1982
+ (http://www.ietf.org/rfc/rfc1982.txt) ) by the first elements of each pair.
+ </doc>
+
+ <doc>
+ 2) The list-of-pairs is flattened into a list-of-words.
+ </doc>
+
+ <doc>
+ 3) Each word in the list is packed into ascending locations in memory with network byte
+ ordering.
+ </doc>
+
+ <doc>
+ 4) The size in bytes, represented as a 16-bit network-byte-order unsigned value, is prepended.
+ </doc>
+
+ <doc>
+ For instance, the example from above would be encoded:
+ </doc>
+
+ <doc type="picture">
+ [(0, 2), (5, 6), (15, 15)] -- already sorted.
+ [0, 2, 5, 6, 15, 15] -- flattened.
+ 000000000000000200000005000000060000000F0000000F -- bytes in hex
+ 0018000000000000000200000005000000060000000F0000000F -- bytes in hex,
+ length (24) prepended
+ </doc>
+
+ <doc type="picture" title="Wire Format">
+ +----= size OCTETs =----+
+ | |
+ 2 OCTETs | 8 OCTETs |
+ +----------+-----+-----------+-----+
+ | size | .../| range |\... |
+ +----------+---/ +-----------+ \---+
+ uint16 / / \ \
+ / / \ \
+ / / \ \
+ / / \ \
+ / 4 OCTETs 4 OCTETs \
+ +-------------+-------------+
+ | lower | upper |
+ +-------------+-------------+
+ sequence-no sequence-no
+ </doc>
+
+ <doc type="bnf">
+ sequence-set = size *range
+ size = uint16 ; length of variable portion in bytes
+
+ range = lower upper ; inclusive
+ lower = sequence-no
+ upper = sequence-no
+ </doc>
+ </type>
+
+ <!--
+ 0xa0 - 0xaf: Variable length types - four byte length field (up to 4294967295 octets)
+ -->
+
+ <type name="vbin32" code="0xa0" variable-width="4"
+ label="up to 4294967295 octets of opaque binary data">
+ <doc>
+ The vbin32 type encodes up to 4294967295 octets of opaque binary data. The number of octets is
+ first encoded as a 32-bit unsigned integral value in network byte order. This is followed by
+ the actual data.
+ </doc>
+
+ <doc type="picture" title="Wire Format">
+ 4 OCTETs size OCTETs
+ +----------+-------------+
+ | size | octets |
+ +----------+-------------+
+ uint32
+ </doc>
+
+ <doc type="bnf">
+ vbin32 = size octets
+ size = uint32
+ octets = 0*4294967295 OCTET ; size OCTETs
+ </doc>
+ </type>
+
+ <type name="map" code="0xa8" variable-width="4" label="a mapping of keys to typed values">
+ <doc>
+ A map is a set of distinct keys where each key has an associated (type,value) pair. The triple
+ of the key, type, and value, form an entry within a map. Each entry within a given map MUST
+ have a distinct key. A map is encoded as a size in octets, a count of the number of entries,
+ followed by the encoded entries themselves.
+ </doc>
+
+ <doc>
+ An encoded map may contain up to (4294967295 - 4) octets worth of encoded entries. The size is
+ encoded as a 32-bit unsigned integral value in network byte order equal to the number of
+ octets worth of encoded entries plus 4. (The extra 4 octets is added for the entry count.) The
+ size is then followed by the number of entries encoded as a 32-bit unsigned integral value in
+ network byte order. Finally the entries are encoded sequentially.
+ </doc>
+
+ <doc>
+ An entry is encoded as the key, followed by the type, and then the value. The key is always a
+ string encoded as a str8. The type is a single octet that may contain any valid AMQP type
+ code. The value is encoded according to the rules defined by the type code for that entry.
+ </doc>
+
+ <doc type="picture" title="Wire Format">
+ +------------= size OCTETs =-----------+
+ | |
+ 4 OCTETs | 4 OCTETs |
+ +----------+----------+-----+---------------+-----+
+ | size | count | .../| entry |\... |
+ +----------+----------+---/ +---------------+ \---+
+ uint32 uint32 / / \ \
+ / / \ \
+ / / \ \
+ / / \ \
+ / / \ \
+ / k OCTETs 1 OCTET n OCTETs \
+ +-----------+---------+-----------+
+ | key | type | value |
+ +-----------+---------+-----------+
+ str8 *type*
+ </doc>
+
+ <doc type="bnf">
+ map = size count *entry
+
+ size = uint32 ; size of count and entries in octets
+ count = uint32 ; number of entries in the map
+
+ entry = key type value
+ key = str8
+ type = OCTET ; type code of the value
+ value = *OCTET ; the encoded value
+ </doc>
+ </type>
+
+ <type name="list" code="0xa9" variable-width="4" label="a series of consecutive type-value pairs">
+ <doc>
+ A list is an ordered sequence of (type, value) pairs. The (type, value) pair forms an item
+ within the list. The list may contain items of many distinct types. A list is encoded as a
+ size in octets, followed by a count of the number of items, followed by the items themselves
+ encoded in their defined order.
+ </doc>
+
+ <doc>
+ An encoded list may contain up to (4294967295 - 4) octets worth of encoded items. The size is
+ encoded as a 32-bit unsigned integral value in network byte order equal to the number of
+ octets worth of encoded items plus 4. (The extra 4 octets is added for the item count.) The
+ size is then followed by the number of items encoded as a 32-bit unsigned integral value in
+ network byte order. Finally the items are encoded sequentially in their defined order.
+ </doc>
+
+ <doc>
+ An item is encoded as the type followed by the value. The type is a single octet that may
+ contain any valid AMQP type code. The value is encoded according to the rules defined by the
+ type code for that item.
+ </doc>
+
+ <doc type="picture" title="Wire Format">
+ +---------= size OCTETs =---------+
+ | |
+ 4 OCTETs | 4 OCTETs |
+ +----------+----------+-----+----------+-----+
+ | size | count | .../| item |\... |
+ +----------+----------+---/ +----------+ \---+
+ uint32 uint32 / / \ \
+ / / \ \
+ / 1 OCTET n OCTETs \
+ +----------+-----------+
+ | type | value |
+ +----------+-----------+
+ *type*
+ </doc>
+
+ <doc type="bnf">
+ list = size count *item
+
+ size = uint32 ; size of count and items in octets
+ count = uint32 ; number of items in the list
+
+ item = type value
+ type = OCTET ; type code of the value
+ value = *OCTET ; the encoded value
+ </doc>
+ </type>
+
+ <type name="array" code="0xaa" variable-width="4"
+ label="a defined length collection of values of a single type">
+ <doc>
+ An array is an ordered sequence of values of the same type. The array is encoded in as a size
+ in octets, followed by a type code, then a count of the number values in the array, and
+ finally the values encoded in their defined order.
+ </doc>
+
+ <doc>
+ An encoded array may contain up to (4294967295 - 5) octets worth of encoded values. The size
+ is encoded as a 32-bit unsigned integral value in network byte order equal to the number of
+ octets worth of encoded values plus 5. (The extra 5 octets consist of 4 octets for the count
+ of the number of values, and one octet to hold the type code for the items in the array.) The
+ size is then followed by a single octet that may contain any valid AMQP type code. The type
+ code is then followed by the number of values encoded as a 32-bit unsigned integral value in
+ network byte order. Finally the values are encoded sequentially in their defined order
+ according to the rules defined by the type code for the array.
+ </doc>
+
+ <doc type="picture" title="Wire Format">
+ 4 OCTETs 1 OCTET 4 OCTETs (size - 5) OCTETs
+ +----------+---------+----------+-------------------------+
+ | size | type | count | values |
+ +----------+---------+----------+-------------------------+
+ uint32 uint32 *count* encoded *types*
+ </doc>
+
+ <doc type="bnf">
+ array = size type count values
+
+ size = uint32 ; size of type, count, and values in octets
+ type = OCTET ; the type of the encoded values
+ count = uint32 ; number of items in the array
+
+ values = 0*4294967290 OCTET ; (size - 5) OCTETs
+ </doc>
+ </type>
+
+ <type name="struct32" code="0xab" variable-width="4" label="a coded struct with a 32-bit size">
+ <doc>
+ The struct32 type describes any coded struct with a 32-bit (4 octet) size. The type is
+ restricted to be only coded structs with a 32-bit size, consequently the first six octets of
+ any encoded value for this type MUST always contain the size, class-code, and struct-code in
+ that order.
+ </doc>
+
+ <doc>
+ The size is encoded as a 32-bit unsigned integral value in network byte order that is equal to
+ the size of the encoded field-data, packing-flags, class-code, and struct-code. The class-code
+ is a single octet that may be set to any valid class code. The struct-code is a single octet
+ that may be set to any valid struct code within the given class-code.
+ </doc>
+
+ <doc>
+ The first six octets are then followed by the packing flags and encoded field data. The
+ presence and quantity of packing-flags, as well as the specific fields are determined by the
+ struct definition identified with the encoded class-code and struct-code.
+ </doc>
+
+ <doc type="picture" title="Wire Format">
+ 4 OCTETs 1 OCTET 1 OCTET pack-width OCTETs n OCTETs
+ +----------+------------+-------------+-------------------+------------+
+ | size | class-code | struct-code | packing-flags | field-data |
+ +----------+------------+-------------+-------------------+------------+
+ uint32
+
+ n = (size - 2 - pack-width)
+ </doc>
+
+ <doc type="bnf">
+ struct32 = size class-code struct-code packing-flags field-data
+
+ size = uint32
+
+ class-code = OCTET ; zero for top-level structs
+ struct-code = OCTET ; together with class-code identifies the struct
+ ; definition which determines the pack-width and
+ ; fields
+
+ packing-flags = 0*4 OCTET ; pack-width OCTETs
+
+ field-data = *OCTET ; (size - 2 - pack-width) OCTETs
+ </doc>
+ </type>
+
+ <!--
+ 0xb0 - 0xbf: Reserved
+ -->
+
+ <!--
+ 0xc0 - 0xcf:Fixed width types - 5 octets
+ -->
+
+ <type name="bin40" code="0xc0" fixed-width="5" label="five octets of unspecified binary encoding">
+ <doc>
+ The bin40 type consists of five consecutive octets of opaque binary data.
+ </doc>
+
+ <doc type="picture" title="Wire Format">
+ 1 OCTET 1 OCTET 1 OCTET 1 OCTET 1 OCTET
+ +-----------+-----------+-------------+------------+------------+
+ | octet-one | octet-two | octet-three | octet-four | octet-five |
+ +-----------+-----------+-------------+------------+------------+
+ </doc>
+
+ <doc type="bnf">
+ bin40 = 5 OCTET
+ </doc>
+ </type>
+
+ <type name="dec32" code="0xc8" fixed-width="5"
+ label="32-bit decimal value (e.g. for use in financial values)">
+ <doc>
+ The dec32 type is decimal value with a variable number of digits following the decimal point.
+ It is encoded as an 8-bit unsigned integral value representing the number of decimal places.
+ This is followed by the signed integral value encoded using a 32-bit two's complement
+ representation in network byte order.
+ </doc>
+
+ <doc>
+ The former value is referred to as the exponent of the divisor. The latter value is the
+ mantissa. The decimal value is given by: mantissa / 10^exponent.
+ </doc>
+
+ <doc type="picture" title="Wire Format">
+ 1 OCTET 4 OCTETs
+ +----------+----------+
+ | exponent | mantissa |
+ +----------+----------+
+ uint8 int32
+ </doc>
+
+ <doc type="bnf">
+ dec32 = exponent mantissa
+ exponent = uint8
+ mantissa = int32
+ </doc>
+ </type>
+
+ <!--
+ 0xd0 - 0xdf: Fixed width types - 9 octets
+ -->
+
+ <type name="bin72" code="0xd0" fixed-width="9"
+ label="nine octets of unspecified binary encoding">
+ <doc>
+ The bin72 type consists of nine consecutive octets of opaque binary data.
+ </doc>
+
+ <doc type="picture" title="Wire Format">
+ 1 OCTET 1 OCTET 1 OCTET 1 OCTET
+ +-----------+-----------+-----+-------------+------------+
+ | octet-one | octet-two | ... | octet-eight | octet-nine |
+ +-----------+-----------+-----+-------------+------------+
+ </doc>
+
+ <doc type="bnf">
+ bin64 = 9 OCTET
+ </doc>
+ </type>
+
+ <type name="dec64" code="0xd8" fixed-width="9"
+ label="64-bit decimal value (e.g. for use in financial values)">
+ <doc>
+ The dec64 type is decimal value with a variable number of digits following the decimal point.
+ It is encoded as an 8-bit unsigned integral value representing the number of decimal places.
+ This is followed by the signed integral value encoded using a 64-bit two's complement
+ representation in network byte order.
+ </doc>
+
+ <doc>
+ The former value is referred to as the exponent of the divisor. The latter value is the
+ mantissa. The decimal value is given by: mantissa / 10^exponent.
+ </doc>
+
+ <doc type="picture" title="Wire Format">
+ 1 OCTET 8 OCTETs
+ +----------+----------+
+ | exponent | mantissa |
+ +----------+----------+
+ uint8 int64
+ </doc>
+
+ <doc type="bnf">
+ dec64 = exponent mantissa
+ exponent = uint8
+ mantissa = int64
+ </doc>
+ </type>
+
+ <!--
+ 0xe0 - 0xef: Reserved
+ -->
+
+ <!--
+ 0xf0 - 0xff: Zero-length types
+ -->
+
+ <type name="void" code="0xf0" fixed-width="0" label="the void type">
+ <doc>
+ The void type is used within tagged data structures such as maps and lists to indicate an
+ empty value. The void type has no value and is encoded as an empty sequence of octets.
+ </doc>
+ </type>
+
+ <type name="bit" code="0xf1" fixed-width="0" label="presence indicator">
+ <doc>
+ The bit type is used to indicate that a packing flag within a packed struct is being used to
+ represent a boolean value based on the presence of an empty value. The bit type has no value
+ and is encoded as an empty sequence of octets.
+ </doc>
+ </type>
+
+ <!--
+ ======================================================
+ == CONSTANTS
+ ======================================================
+ -->
+
+ <!-- Protocol constants -->
+
+ <constant name="MIN-MAX-FRAME-SIZE" value="4096" label="The minimum size (in bytes) which can be
+ agreed upon as the maximum frame size.">
+ <doc>
+ During the initial connection negotiation, the two peers must agree upon a maximum frame size.
+ This constant defines the minimum value to which the maximum frame size can be set. By
+ defining this value, the peers can guarantee that they can send frames of up to this size
+ until they have agreed a definitive maximum frame size for that connection.
+ </doc>
+ </constant>
+
+ <!--
+ ======================================================
+ == DOMAIN TYPES
+ ======================================================
+ -->
+
+ <!-- Segment types -->
+
+ <domain name="segment-type" type="uint8" label="valid values for the frame type indicator.">
+ <doc>
+ Segments are defined in <xref ref="specification.transport.assemblies_segments_and_frames"/>.
+ The segment domain defines the valid values that may be used for the segment indicator within
+ the frame header.
+ </doc>
+
+ <enum>
+ <choice name="control" value="0">
+ <doc>
+ The frame type indicator for Control segments (see <xref
+ ref="specification.formal_notation.controls"/>).
+ </doc>
+ </choice>
+ <choice name="command" value="1">
+ <doc>
+ The frame type indicator for Command segments (see <xref
+ ref="specification.formal_notation.commands"/>).
+ </doc>
+ </choice>
+ <choice name="header" value="2" >
+ <doc>
+ The frame type indicator for Header segments (see <xref
+ ref="specification.formal_notation.segments.header"/>).
+ </doc>
+ </choice>
+ <choice name="body" value="3" >
+ <doc>
+ The frame type indicator for Body segments (see <xref
+ ref="specification.formal_notation.segments.body"/>).
+ </doc>
+ </choice>
+ </enum>
+ </domain>
+
+ <!-- Tracks -->
+
+ <domain name="track" type="uint8" label="Valid values for transport level tracks">
+ <doc> Tracks are defined in <xref ref="specification.transport.channels_and_tracks"/>. The
+ track domain defines the valid values that may used for the track indicator within the frame
+ header</doc>
+ <enum>
+ <choice name="control" value="0">
+ <doc>
+ The track used for all controls. All controls defined in this specification MUST be sent
+ on track 0.
+ </doc>
+ </choice>
+ <choice name="command" value="1">
+ <doc>
+ The track used for all commands. All commands defined in this specification MUST be sent
+ on track 1.
+ </doc>
+ </choice>
+ </enum>
+ </domain>
+
+
+ <domain name="str16-array" type="array" label="An array of values of type str16.">
+ <doc>
+ An array of values of type str16.
+ </doc>
+ </domain>
+
+
+
+ <!-- == Class: connection ==================================================================== -->
+
+ <class name="connection" code="0x1" label="work with connections">
+ <doc>
+ The connection class provides controls for a client to establish a network connection to a
+ server, and for both peers to operate the connection thereafter.
+ </doc>
+
+ <doc type="grammar">
+ connection = open-connection
+ *use-connection
+ close-connection
+ open-connection = C:protocol-header
+ S:START C:START-OK
+ *challenge
+ S:TUNE C:TUNE-OK
+ C:OPEN S:OPEN-OK | S:REDIRECT
+ challenge = S:SECURE C:SECURE-OK
+ use-connection = *channel
+ close-connection = C:CLOSE S:CLOSE-OK
+ / S:CLOSE C:CLOSE-OK
+ </doc>
+
+ <role name="server" implement="MUST" />
+ <role name="client" implement="MUST" />
+
+ <domain name="close-code" type="uint16" label="code used in the connection.close control to
+ indicate reason for closure">
+ <enum>
+ <choice name="normal" value="200">
+ <doc>
+ The connection closed normally.
+ </doc>
+ </choice>
+
+ <choice name="connection-forced" value="320">
+ <doc>
+ An operator intervened to close the connection for some reason. The client may retry at
+ some later date.
+ </doc>
+ </choice>
+
+ <choice name="invalid-path" value="402">
+ <doc>
+ The client tried to work with an unknown virtual host.
+ </doc>
+ </choice>
+
+ <choice name="framing-error" value="501">
+ <doc>
+ A valid frame header cannot be formed from the incoming byte stream.
+ </doc>
+ </choice>
+ </enum>
+ </domain>
+
+ <domain name="amqp-host-url" type="str16" label="URL for identifying an AMQP Server">
+ <doc>
+ The amqp-url domain defines a format for identifying an AMQP Server. It is used to provide
+ alternate hosts in the case where a client has to reconnect because of failure, or because
+ the server requests the client to do so upon initial connection.
+ </doc>
+ <doc type="bnf"><![CDATA[
+ amqp_url = "amqp:" prot_addr_list
+ prot_addr_list = [prot_addr ","]* prot_addr
+ prot_addr = tcp_prot_addr | tls_prot_addr
+
+ tcp_prot_addr = tcp_id tcp_addr
+ tcp_id = "tcp:" | ""
+ tcp_addr = [host [":" port] ]
+ host = <as per http://www.ietf.org/rfc/rfc3986.txt>
+ port = number]]>
+ </doc>
+ </domain>
+
+ <domain name="amqp-host-array" type="array" label="An array of values of type amqp-host-url">
+ <doc>
+ Used to provide a list of alternate hosts.
+ </doc>
+ </domain>
+
+ <!-- - Control: connection.start - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+ <control name="start" code="0x1" label="start connection negotiation">
+ <doc>
+ This control starts the connection negotiation process by telling the client the supported
+ security mechanisms and locales from which the client can choose.
+ </doc>
+
+ <rule name="protocol-name">
+ <doc>
+ If the server cannot support the protocol specified in the protocol header, it MUST close
+ the socket connection without sending any response control.
+ </doc>
+ <doc type="scenario">
+ The client sends a protocol header containing an invalid protocol name. The server must
+ respond by closing the connection.
+ </doc>
+ </rule>
+
+ <rule name="client-support">
+ <doc>
+ If the client cannot handle the protocol version suggested by the server it MUST close the
+ socket connection.
+ </doc>
+ <doc type="scenario">
+ The server sends a protocol version that is lower than any valid implementation, e.g. 0.1.
+ The client must respond by closing the connection.
+ </doc>
+ </rule>
+
+ <implement role="client" handle="MUST" />
+
+ <response name="start-ok" />
+
+ <field name="server-properties" type="map" label="server properties">
+ <rule name="required-fields">
+ <doc>
+ The properties SHOULD contain at least these fields: "host", specifying the server host
+ name or address, "product", giving the name of the server product, "version", giving the
+ name of the server version, "platform", giving the name of the operating system,
+ "copyright", if appropriate, and "information", giving other general information.
+ </doc>
+ <doc type="scenario">
+ Client connects to server and inspects the server properties. It checks for the presence
+ of the required fields.
+ </doc>
+ </rule>
+ </field>
+
+ <field name="mechanisms" type="str16-array" label="available security mechanisms"
+ required="true">
+ <doc>
+ A list of the security mechanisms that the server supports.
+ </doc>
+ </field>
+
+ <field name="locales" type="str16-array" label="available message locales" required="true">
+ <doc>
+ A list of the message locales that the server supports. The locale defines the language in
+ which the server will send reply texts.
+ </doc>
+
+ <rule name="required-support">
+ <doc>
+ The server MUST support at least the en_US locale.
+ </doc>
+ <doc type="scenario">
+ Client connects to server and inspects the locales field. It checks for the presence of
+ the required locale(s).
+ </doc>
+ </rule>
+ </field>
+ </control>
+
+ <!-- - Control: connection.start-ok - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+ <control name="start-ok" code="0x2" label="select security mechanism and locale">
+ <doc>
+ This control selects a SASL security mechanism.
+ </doc>
+
+ <implement role="server" handle="MUST" />
+
+ <field name="client-properties" type="map" label="client properties">
+ <rule name="required-fields">
+ <!-- This rule is not testable from the client side -->
+ <doc>
+ The properties SHOULD contain at least these fields: "product", giving the name of the
+ client product, "version", giving the name of the client version, "platform", giving the
+ name of the operating system, "copyright", if appropriate, and "information", giving
+ other general information.
+ </doc>
+ </rule>
+ </field>
+
+ <field name="mechanism" type="str8" label="selected security mechanism" required="true">
+ <doc>
+ A single security mechanisms selected by the client, which must be one of those specified
+ by the server.
+ </doc>
+
+ <rule name="security">
+ <doc>
+ The client SHOULD authenticate using the highest-level security profile it can handle
+ from the list provided by the server.
+ </doc>
+ </rule>
+
+ <rule name="validity">
+ <doc>
+ If the mechanism field does not contain one of the security mechanisms proposed by the
+ server in the Start control, the server MUST close the connection without sending any
+ further data.
+ </doc>
+ <doc type="scenario">
+ Client connects to server and sends an invalid security mechanism. The server must
+ respond by closing the connection (a socket close, with no connection close
+ negotiation).
+ </doc>
+ </rule>
+ </field>
+
+ <field name="response" type="vbin32" label="security response data" required="true">
+ <doc>
+ A block of opaque data passed to the security mechanism. The contents of this data are
+ defined by the SASL security mechanism.
+ </doc>
+ </field>
+
+ <field name="locale" type="str8" label="selected message locale" required="true">
+ <doc>
+ A single message locale selected by the client, which must be one of those specified by
+ the server.
+ </doc>
+ </field>
+ </control>
+
+ <!-- - Control: connection.secure - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+ <control name="secure" code="0x3" label="security mechanism challenge">
+ <doc>
+ The SASL protocol works by exchanging challenges and responses until both peers have
+ received sufficient information to authenticate each other. This control challenges the
+ client to provide more information.
+ </doc>
+
+ <implement role="client" handle="MUST" />
+
+ <response name="secure-ok" />
+
+ <field name="challenge" type="vbin32" label="security challenge data" required="true">
+ <doc>
+ Challenge information, a block of opaque binary data passed to the security mechanism.
+ </doc>
+ </field>
+ </control>
+
+ <!-- - Control: connection.secure-ok - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+ <control name="secure-ok" code="0x4" label="security mechanism response">
+ <doc>
+ This control attempts to authenticate, passing a block of SASL data for the security
+ mechanism at the server side.
+ </doc>
+
+ <implement role="server" handle="MUST" />
+
+ <field name="response" type="vbin32" label="security response data" required="true">
+ <doc>
+ A block of opaque data passed to the security mechanism. The contents of this data are
+ defined by the SASL security mechanism.
+ </doc>
+ </field>
+ </control>
+
+ <!-- - Control: connection.tune - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+ <control name="tune" code="0x5" label="propose connection tuning parameters">
+ <doc>
+ This control proposes a set of connection configuration values to the client. The client can
+ accept and/or adjust these.
+ </doc>
+
+ <implement role="client" handle="MUST" />
+
+ <response name="tune-ok" />
+
+ <field name="channel-max" type="uint16" label="proposed maximum channels">
+ <doc>
+ The maximum total number of channels that the server allows per connection. If this is not
+ set it means that the server does not impose a fixed limit, but the number of allowed
+ channels may be limited by available server resources.
+ </doc>
+ </field>
+
+ <field name="max-frame-size" type="uint16" label="proposed maximum frame size">
+ <doc>
+ The largest frame size that the server proposes for the connection. The client can
+ negotiate a lower value. If this is not set means that the server does not impose any
+ specific limit but may reject very large frames if it cannot allocate resources for them.
+ </doc>
+
+ <rule name="minimum">
+ <doc>
+ Until the max-frame-size has been negotiated, both peers MUST accept frames of up to
+ MIN-MAX-FRAME-SIZE octets large, and the minimum negotiated value for max-frame-size is
+ also MIN-MAX-FRAME-SIZE.
+ </doc>
+ <doc type="scenario">
+ Client connects to server and sends a large properties field, creating a frame of
+ MIN-MAX-FRAME-SIZE octets. The server must accept this frame.
+ </doc>
+ </rule>
+ </field>
+
+ <field name="heartbeat-min" type="uint16" label="the minimum supported heartbeat delay">
+ <doc>
+ The minimum delay, in seconds, of the connection heartbeat supported by the server. If
+ this is not set it means the server does not support sending heartbeats.
+ </doc>
+ </field>
+
+ <field name="heartbeat-max" type="uint16" label="the maximum supported heartbeat delay">
+ <doc>
+ The maximum delay, in seconds, of the connection heartbeat supported by the server. If
+ this is not set it means the server has no maximum.
+ </doc>
+
+ <rule name="permitted-range">
+ <doc>
+ The heartbeat-max value must be greater than or equal to the value supplied in the
+ heartbeat-min field.
+ </doc>
+ </rule>
+
+ <rule name="no-heartbeat-min">
+ <doc>
+ If no heartbeat-min is supplied, then the heartbeat-max field MUST remain empty.
+ </doc>
+ </rule>
+ </field>
+ </control>
+
+ <!-- - Control: connection.tune-ok - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+ <control name="tune-ok" code="0x6" label="negotiate connection tuning parameters">
+ <doc>
+ This control sends the client's connection tuning parameters to the server. Certain fields
+ are negotiated, others provide capability information.
+ </doc>
+
+ <implement role="server" handle="MUST" />
+
+ <field name="channel-max" type="uint16" label="negotiated maximum channels" required="true">
+ <doc>
+ The maximum total number of channels that the client will use per connection.
+ </doc>
+
+ <rule name="upper-limit">
+ <doc>
+ If the client specifies a channel max that is higher than the value provided by the
+ server, the server MUST close the connection without attempting a negotiated close. The
+ server may report the error in some fashion to assist implementers.
+ </doc>
+
+ </rule>
+
+ <rule name="available-channels">
+ <doc>
+ If the client agrees to a channel-max of N channels, then the channels available for
+ communication between client and server are precisely the channels numbered 0 to (N-1).
+ </doc>
+ </rule>
+ </field>
+
+ <field name="max-frame-size" type="uint16" label="negotiated maximum frame size">
+ <doc>
+ The largest frame size that the client and server will use for the connection. If it is
+ not set means that the client does not impose any specific limit but may reject very large
+ frames if it cannot allocate resources for them. Note that the max-frame-size limit
+ applies principally to content frames, where large contents can be broken into frames of
+ arbitrary size.
+ </doc>
+
+ <rule name="minimum">
+ <doc>
+ Until the max-frame-size has been negotiated, both peers MUST accept frames of up to
+ MIN-MAX-FRAME-SIZE octets large, and the minimum negotiated value for max-frame-size is
+ also MIN-MAX-FRAME-SIZE.
+ </doc>
+ </rule>
+
+ <rule name="upper-limit">
+ <doc>
+ If the client specifies a max-frame-size that is higher than the value provided by the
+ server, the server MUST close the connection without attempting a negotiated close. The
+ server may report the error in some fashion to assist implementers.
+ </doc>
+ </rule>
+
+ <rule name="max-frame-size">
+ <doc>
+ A peer MUST NOT send frames larger than the agreed-upon size. A peer that receives an
+ oversized frame MUST close the connection with the framing-error close-code.
+ </doc>
+ </rule>
+ </field>
+
+ <field name="heartbeat" type="uint16" label="negotiated heartbeat delay">
+ <doc>
+ The delay, in seconds, of the connection heartbeat chosen by the client. If it is not set
+ it means the client does not want a heartbeat.
+ </doc>
+
+ <rule name="permitted-range">
+ <doc>
+ The chosen heartbeat MUST be in the range supplied by the heartbeat-min and
+ heartbeat-max fields of connection.tune.
+ </doc>
+ </rule>
+
+ <rule name="no-heartbeat-min">
+ <doc>
+ The heartbeat field MUST NOT be set if the heartbeat-min field of connection.tune was
+ not set by the server.
+ </doc>
+ </rule>
+ </field>
+ </control>
+
+ <!-- - Control: connection.open - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+ <control name="open" code="0x7" label="open connection to virtual host">
+ <doc>
+ This control opens a connection to a virtual host, which is a collection of resources, and
+ acts to separate multiple application domains within a server. The server may apply
+ arbitrary limits per virtual host, such as the number of each type of entity that may be
+ used, per connection and/or in total.
+ </doc>
+
+ <implement role="server" handle="MUST" />
+
+ <response name="open-ok" />
+ <response name="redirect" />
+
+ <field name="virtual-host" type="str8" label="virtual host name" required="true">
+ <doc>
+ The name of the virtual host to work with.
+ </doc>
+
+ <rule name="separation">
+ <doc>
+ If the server supports multiple virtual hosts, it MUST enforce a full separation of
+ exchanges, queues, and all associated entities per virtual host. An application,
+ connected to a specific virtual host, MUST NOT be able to access resources of another
+ virtual host.
+ </doc>
+ </rule>
+
+ <rule name="security">
+ <doc>
+ The server SHOULD verify that the client has permission to access the specified virtual
+ host.
+ </doc>
+ </rule>
+ </field>
+
+ <field name="capabilities" type="str16-array" label="required capabilities">
+ <doc>
+ The client can specify zero or more capability names. The server can use this to determine
+ how to process the client's connection request.
+ </doc>
+ </field>
+
+ <field name="insist" type="bit" label="insist on connecting to server">
+ <doc>
+ In a configuration with multiple collaborating servers, the server may respond to a
+ connection.open control with a Connection.Redirect. The insist option tells the server
+ that the client is insisting on a connection to the specified server.
+ </doc>
+ <rule name="behavior">
+ <doc>
+ When the client uses the insist option, the server MUST NOT respond with a
+ Connection.Redirect control. If it cannot accept the client's connection request it
+ should respond by closing the connection with a suitable reply code.
+ </doc>
+ </rule>
+ </field>
+ </control>
+
+ <!-- - Control: connection.open-ok - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+ <control name="open-ok" code="0x8" label="signal that connection is ready">
+ <doc>
+ This control signals to the client that the connection is ready for use.
+ </doc>
+
+ <implement role="client" handle="MUST" />
+
+ <field name="known-hosts" type="amqp-host-array" label="alternate hosts which may be used in
+ the case of failure">
+ <doc>
+ Specifies an array of equivalent or alternative hosts that the server knows about, which
+ will normally include the current server itself. Each entry in the array will be in the
+ form of an IP address or DNS name, optionally followed by a colon and a port number.
+ Clients can cache this information and use it when reconnecting to a server after a
+ failure. This field may be empty.
+ </doc>
+ </field>
+ </control>
+
+ <!-- - Control: connection.redirect - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+ <control name="redirect" code="0x9" label="redirects client to other server">
+ <doc>
+ This control redirects the client to another server, based on the requested virtual host
+ and/or capabilities.
+ </doc>
+
+ <rule name="usage">
+ <doc>
+ When getting the connection.redirect control, the client SHOULD reconnect to the host
+ specified, and if that host is not present, to any of the hosts specified in the
+ known-hosts list.
+ </doc>
+ </rule>
+
+ <implement role="client" handle="MUST" />
+
+ <field name="host" type="amqp-host-url" label="server to connect to" required="true">
+ <doc>
+ Specifies the server to connect to.
+ </doc>
+ </field>
+
+ <field name="known-hosts" type="amqp-host-array" label="alternate hosts to try in case of
+ failure">
+ <doc>
+ An array of equivalent or alternative hosts that the server knows about.
+ </doc>
+ </field>
+ </control>
+
+ <!-- - Control: connection.heartbeat - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+ <control name="heartbeat" code="0xa" label="indicates connection is still alive">
+ <doc>
+ The heartbeat control may be used to generate artificial network traffic when a connection
+ is idle. If a connection is idle for more than twice the negotiated heartbeat delay, the
+ peers MAY be considered disconnected.
+ </doc>
+ <implement role="client" handle="MAY" />
+ <implement role="server" handle="MAY" />
+ </control>
+
+ <!-- - Control: connection.close - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+ <control name="close" code="0xb" label="request a connection close">
+ <doc>
+ This control indicates that the sender wants to close the connection. The reason for close
+ is indicated with the reply-code and reply-text. The channel this control is sent on MAY be
+ used to indicate which channel caused the connection to close.
+ </doc>
+
+ <implement role="client" handle="MUST" />
+ <implement role="server" handle="MUST" />
+
+ <response name="close-ok" />
+
+ <field name="reply-code" type="close-code" label="the numeric reply code"
+ required="true">
+ <doc>
+ Indicates the reason for connection closure.
+ </doc>
+ </field>
+ <field name="reply-text" type="str8" label="the localized reply text">
+ <doc>
+ This text can be logged as an aid to resolving issues.
+ </doc>
+ </field>
+ </control>
+
+ <!-- - Control: connection.close-ok - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+ <control name="close-ok" code="0xc" label="confirm a connection close">
+ <doc>
+ This control confirms a connection.close control and tells the recipient that it is safe to
+ release resources for the connection and close the socket.
+ </doc>
+
+ <rule name="reporting">
+ <doc>
+ A peer that detects a socket closure without having received a Close-Ok handshake control
+ SHOULD log the error.
+ </doc>
+ </rule>
+
+ <implement role="client" handle="MUST" />
+ <implement role="server" handle="MUST" />
+ </control>
+
+ </class>
+
+ <!-- == Class: session ======================================================================= -->
+
+ <class name="session" code="0x2" label="session controls">
+ <doc>
+ A session is a named interaction between two peers. Session names are chosen by the upper
+ layers and may be used indefinitely. The model layer may associate long-lived or durable state
+ with a given session name. The session layer provides transport of commands associated with
+ this interaction.
+ </doc>
+
+ <doc>
+ The controls defined within this class are specified in terms of the "sender" of commands and
+ the "receiver" of commands. Since both client and server send and receive commands, the
+ overall session dialog is symmetric, however the semantics of the session controls are defined
+ in terms of a single sender/receiver pair, and it is assumed that the client and server will
+ each contain both a sender and receiver implementation.
+ </doc>
+
+ <rule name="attachment">
+ <doc>
+ The transport MUST be attached in order to use any control other than "attach", "attached",
+ "detach", or "detached". A peer receiving any other control on a detached transport MUST
+ discard it and send a session.detached with the "not-attached" reason code.
+ </doc>
+ </rule>
+
+ <role name="server" implement="MUST" />
+ <role name="client" implement="MUST" />
+
+ <role name="sender" implement="MUST">
+ <doc>
+ The sender of commands.
+ </doc>
+ </role>
+ <role name="receiver" implement="MUST">
+ <doc>
+ The receiver of commands.
+ </doc>
+ </role>
+
+ <domain name="name" type="vbin16" label="opaque session name">
+ <doc>
+ The session name uniquely identifies an interaction between two peers. It is scoped to a
+ given authentication principal.
+ </doc>
+ </domain>
+
+ <domain name="detach-code" type="uint8" label="reason for detach">
+ <enum>
+ <choice name="normal" value="0">
+ <doc>
+ The session was detached by request.
+ </doc>
+ </choice>
+ <choice name="session-busy" value="1">
+ <doc>
+ The session is currently attached to another transport.
+ </doc>
+ </choice>
+ <choice name="transport-busy" value="2">
+ <doc>
+ The transport is currently attached to another session.
+ </doc>
+ </choice>
+ <choice name="not-attached" value="3">
+ <doc>
+ The transport is not currently attached to any session.
+ </doc>
+ </choice>
+ <choice name="unknown-ids" value="4">
+ <doc>
+ Command data was received prior to any use of the command-point control.
+ </doc>
+ </choice>
+ </enum>
+ </domain>
+
+ <domain name="commands" type="sequence-set" label="identifies a set of commands">
+ </domain>
+
+ <struct name="header" size="1" pack="1">
+ <doc>
+ The session header appears on commands after the class and command id, but prior to command
+ arguments.
+ </doc>
+
+ <field name="sync" type="bit" label="request notification of completion">
+ <doc>
+ Request notification of completion for this command.
+ </doc>
+ </field>
+ </struct>
+
+ <struct name="command-fragment" size="0" pack="0" label="byte-ranges within a set of commands">
+
+ <field name="command-id" type="sequence-no" required="true">
+
+ </field>
+ <field name="byte-ranges" type="byte-ranges" required="true">
+
+ </field>
+ </struct>
+
+ <domain name="command-fragments" type="array" label="an array of values of type
+ command-fragment"/>
+
+ <control name="attach" code="0x1" label="attach to the named session">
+ <doc>
+ Requests that the current transport be attached to the named session. Success or failure
+ will be indicated with an attached or detached response. This control is idempotent.
+ </doc>
+
+ <rule name="one-transport-per-session">
+ <doc>
+ A session MUST NOT be attached to more than one transport at a time.
+ </doc>
+ </rule>
+
+ <rule name="one-session-per-transport">
+ <doc>
+ A transport MUST NOT be attached to more than one session at a time.
+ </doc>
+ </rule>
+
+ <rule name="idempotence">
+ <doc>
+ Attaching a session to its current transport MUST succeed and result in an attached
+ response.
+ </doc>
+ </rule>
+
+ <rule name="scoping">
+ <doc>
+ Attachment to the same session name from distinct authentication principals MUST succeed.
+ </doc>
+ </rule>
+
+ <implement role="server" handle="MUST" />
+ <implement role="client" handle="MAY" />
+
+ <response name="attached"/>
+ <response name="detached"/>
+
+ <field name="name" type="name" label="the session name" required="true">
+ <doc>
+ Identifies the session to be attached to the current transport.
+ </doc>
+ </field>
+
+ <field name="force" type="bit" label="force attachment to a busy session">
+ <doc>
+ If set then a busy session will be forcibly detached from its other transport and
+ reattached to the current transport.
+ </doc>
+ </field>
+ </control>
+
+ <control name="attached" code="0x2" label="confirm attachment to the named session">
+ <doc>
+ Confirms successful attachment of the transport to the named session.
+ </doc>
+
+ <implement role="server" handle="MUST" />
+ <implement role="client" handle="MUST" />
+
+ <field name="name" type="name" label="the session name" required="true">
+ <doc>
+ Identifies the session now attached to the current transport.
+ </doc>
+ </field>
+ </control>
+
+ <control name="detach" code="0x3" label="detach from the named session">
+ <doc>
+ Detaches the current transport from the named session.
+ </doc>
+
+ <implement role="server" handle="MUST" />
+ <implement role="client" handle="MUST" />
+
+ <response name="detached"/>
+
+ <field name="name" type="name" label="the session name" required="true">
+ <doc>
+ Identifies the session to detach.
+ </doc>
+ </field>
+ </control>
+
+ <control name="detached" code="0x4" label="confirm detachment from the named session">
+ <doc>
+ Confirms detachment of the current transport from the named session.
+ </doc>
+
+ <implement role="server" handle="MUST" />
+ <implement role="client" handle="MUST" />
+
+ <field name="name" type="name" label="the session name" required="true">
+ <doc>
+ Identifies the detached session.
+ </doc>
+ </field>
+ <field name="code" type="detach-code" label="the reason for detach" required="true">
+ <doc>
+ Identifies the reason for detaching from the named session.
+ </doc>
+ </field>
+ </control>
+
+ <!--
+ Execution state is the set of confirmed, and completed incoming commands, as well as the set
+ of outgoing in-doubt commands held for replay.
+ -->
+
+ <control name="request-timeout" code="0x5" label="requests the execution timeout be changed">
+ <doc>
+ This control may be sent by either the sender or receiver of commands. It requests that the
+ execution timeout be changed. This is the minimum amount of time that a peer must preserve
+ execution state for a detached session.
+ </doc>
+
+ <rule name="maximum-granted-timeout">
+ <doc>
+ The handler of this request MUST set his timeout to the maximum allowed value less than or
+ equal to the requested timeout, and MUST convey the chosen timeout in the response.
+ </doc>
+ </rule>
+
+ <implement role="sender" handle="MUST" />
+ <implement role="receiver" handle="MUST" />
+
+ <response name="timeout"/>
+
+ <field name="timeout" type="uint32" label="the requested timeout">
+ <doc>
+ The requested timeout for execution state in seconds. If not set, this control requests
+ that execution state is preserved indefinitely.
+ </doc>
+ </field>
+ </control>
+
+ <control name="timeout" code="0x6" label="the granted timeout">
+ <doc>
+ This control may be sent by the either the sender or receiver of commands. It is a
+ one-to-one reply to the request-timeout control that indicates the granted timeout for
+ execution state.
+ </doc>
+
+ <implement role="sender" handle="MUST" />
+ <implement role="receiver" handle="MUST" />
+
+ <field name="timeout" type="uint32" label="the execution timeout">
+ <doc>
+ The timeout for execution state. If not set, then execution state is preserved
+ indefinitely.
+ </doc>
+ </field>
+ </control>
+
+ <control name="command-point" code="0x7"
+ label="the command id and byte offset of subsequent data">
+ <doc>
+ This control is sent by the sender of commands and handled by the receiver of commands. This
+ establishes the sequence numbers associated with all subsequent command data sent from the
+ sender to the receiver. The subsequent command data will be numbered starting with the
+ values supplied in this control and proceeding sequentially. This must be used at least once
+ prior to sending any command data on newly attached transports.
+ </doc>
+
+ <rule name="newly-attached-transports">
+ <doc>
+ If command data is sent on a newly attached transport the session MUST be detached with an
+ "unknown-id" reason-code.
+ </doc>
+ </rule>
+
+ <rule name="zero-offset">
+ <doc>
+ If the offset is zero, the next data frame MUST have the first-frame and first-segment
+ flags set. Violation of this is a framing error.
+ </doc>
+ </rule>
+
+ <rule name="nonzero-offset">
+ <doc>
+ If the offset is nonzero, the next data frame MUST NOT have both the first-frame and
+ first-segment flag set. Violation of this is a framing error.
+ </doc>
+ </rule>
+
+ <implement role="receiver" handle="MUST" />
+
+ <field name="command-id" type="sequence-no" label="the command-id of the next command"
+ required="true"/>
+ <field name="command-offset" type="uint64" label="the byte offset within the command"
+ required="true"/>
+ </control>
+
+ <control name="expected" code="0x8" label="informs the peer of expected commands">
+ <doc>
+ This control is sent by the receiver of commands and handled by the sender of commands. It
+ informs the sender of what commands and command fragments are expected at the receiver.
+ This control is only sent in response to a flush control with the expected flag set. The
+ expected control is never sent spontaneously.
+ </doc>
+
+ <rule name="include-next-command">
+ <doc>
+ The set of expected commands MUST include the next command after the highest seen command.
+ </doc>
+ </rule>
+
+ <rule name="commands-empty-means-new-session">
+ <doc>
+ The set of expected commands MUST have zero elements if and only if the sender holds no
+ execution state for the session (i.e. it is a new session).
+ </doc>
+ </rule>
+
+ <rule name="no-overlaps">
+ <doc>
+ If a command-id appears in the commands field, it MUST NOT appear in the fragments field.
+ </doc>
+ </rule>
+
+ <rule name="minimal-fragments">
+ <doc>
+ When choice is permitted, a command MUST appear in the commands field rather than the
+ fragments field.
+ </doc>
+ </rule>
+
+ <implement role="sender" handle="MUST" />
+
+ <field name="commands" type="commands" label="expected commands" required="true"/>
+ <field name="fragments" type="command-fragments" label="expected fragments" />
+ </control>
+
+ <control name="confirmed" code="0x9" label="notifies of confirmed commands">
+ <doc>
+ This control is sent by the receiver of commands and handled by the sender of commands. This
+ sends the set of commands that will definitely be completed by this peer to the sender. This
+ excludes commands known by the receiver to be considered confirmed or complete at the
+ sender.
+ </doc>
+ <doc>
+ This control must be sent if the partner requests the set of confirmed commands using the
+ session.flush control with the confirmed flag set.
+ </doc>
+ <doc>
+ This control may be sent spontaneously. One reason for separating confirmation from
+ completion is for large persistent messages, where the receipt (and storage to a durable
+ store) of part of the message will result in less data needing to be replayed in the case of
+ transport failure during transmission.
+ </doc>
+ <doc>
+ A simple implementation of an AMQP client or server may be implemented to take no action on
+ receipt of session.confirmed controls, and take action only when receiving
+ session.completed controls.
+ </doc>
+ <doc>
+ A simple implementation of an AMQP client or server may be implemented such that it never
+ spontaneously sends session.confirmed and that when requested for the set of confirmed
+ commands (via the session.flush control) it responds with the same set of commands as it
+ would to when the set of completed commands was requested (trivially all completed commands
+ are confirmed).
+ </doc>
+
+ <rule name="durability">
+ <doc>
+ If a command has durable implications, it MUST NOT be confirmed until the fact of the
+ command has been recorded on durable media.
+ </doc>
+ </rule>
+
+ <rule name="no-overlaps">
+ <doc>
+ If a command-id appears in the commands field, it MUST NOT appear in the fragments field.
+ </doc>
+ </rule>
+
+ <rule name="minimal-fragments">
+ <doc>
+ When choice is permitted, a command MUST appear in the commands field rather than the
+ fragments field.
+ </doc>
+ </rule>
+
+ <implement role="sender" handle="MUST" />
+
+ <field name="commands" type="commands" label="entirely confirmed commands">
+ <rule name="exclude-known-complete">
+ <doc>
+ Command-ids included in prior known-complete replies MUST be excluded from the set of
+ all confirmed commands.
+ </doc>
+ </rule>
+ </field>
+ <field name="fragments" type="command-fragments" label="partially confirmed commands"/>
+ </control>
+
+ <control name="completed" code="0xa" label="notifies of command completion">
+ <doc>
+ This control is sent by the receiver of commands, and handled by the sender of commands. It
+ informs the sender of all commands completed by the receiver. This excludes commands known
+ by the receiver to be considered complete at the sender.
+ </doc>
+
+ <rule name="known-completed-reply">
+ <doc>
+ The sender MUST eventually reply with a known-completed set that covers the completed ids.
+ </doc>
+ </rule>
+
+ <rule name="delayed-reply">
+ <doc>
+ The known-complete reply MAY be delayed at the senders discretion if the timely-reply
+ field is not set.
+ </doc>
+ </rule>
+
+ <rule name="merged-reply">
+ <doc>
+ Multiple replies may be merged by sending a single known-completed that includes the union
+ of the merged command-id sets.
+ </doc>
+ </rule>
+
+ <implement role="sender" handle="MUST" />
+
+ <field name="commands" type="commands" label="completed commands">
+ <doc>
+ The ids of all completed commands. This excludes commands known by the receiver to be
+ considered complete at the sender.
+ </doc>
+
+ <rule name="completed-implies-confirmed">
+ <doc>
+ The sender MUST consider any completed commands to also be confirmed.
+ </doc>
+ </rule>
+
+ <rule name="exclude-known-complete">
+ <doc>
+ Command-ids included in prior known-complete replies MUST be excluded from the set of
+ all completed commands.
+ </doc>
+ </rule>
+ </field>
+ <field name="timely-reply" type="bit">
+ <doc>
+ If set, the sender is no longer free to delay the known-completed reply.
+ </doc>
+ </field>
+ </control>
+
+ <control name="known-completed" code="0xb" label="Inform peer of which commands are known to be
+ completed">
+ <doc>
+ This control is sent by the sender of commands, and handled by the receiver of commands. It
+ is sent in reply to one or more completed controls from the receiver. It informs the
+ receiver that commands are known to be completed by the sender.
+ </doc>
+
+ <rule name="stateless">
+ <doc>
+ The sender need not keep state to generate this reply. It is sufficient to reply to any
+ completed control with an exact echo of the completed ids.
+ </doc>
+ </rule>
+
+ <implement role="receiver" handle="MUST" />
+
+ <field name="commands" type="commands" label="commands known to be complete">
+ <doc>
+ The set of completed commands for one or more session.completed controls.
+ </doc>
+
+ <rule name="known-completed-implies-known-confirmed">
+ <doc>
+ The receiver MUST treat any of the specified commands to be considered by the sender as
+ confirmed as well as completed.
+ </doc>
+ </rule>
+ </field>
+ </control>
+
+ <control name="flush" code="0xc" label="requests a session.completed">
+ <doc>
+ This control is sent by the sender of commands and handled by the receiver of commands. It
+ requests that the receiver produce the indicated command sets. The receiver should issue the
+ indicated sets at the earliest possible opportunity.
+ </doc>
+
+ <implement role="receiver" handle="MUST" />
+
+ <field name="expected" type="bit" label="request notification of expected commands"/>
+ <field name="confirmed" type="bit" label="request notification of confirmed commands"/>
+ <field name="completed" type="bit" label="request notification of completed commands"/>
+ </control>
+
+ <control name="gap" code="0xd" label="indicates missing segments in the stream">
+ <doc>
+ This control is sent by the sender of commands and handled by the receiver of commands. It
+ sends command ranges for which there will be no further data forthcoming. The receiver
+ should proceed with the next available commands that arrive after the gap.
+ </doc>
+
+ <rule name="gap-confirmation-and-completion">
+ <doc>
+ The command-ids covered by a session.gap MUST be added to the completed and confirmed sets
+ by the receiver.
+ </doc>
+ </rule>
+
+ <rule name="aborted-commands">
+ <doc>
+ If a session.gap covers a partially received command, the receiving peer MUST treat the
+ command as aborted.
+ </doc>
+ </rule>
+
+ <rule name="completed-or-confirmed-commands">
+ <doc>
+ If a session.gap covers a completed or confirmed command, the receiving peer MUST continue
+ to treat the command as completed or confirmed.
+ </doc>
+ </rule>
+
+ <implement role="receiver" handle="MUST" />
+
+ <field name="commands" type="commands">
+ <doc>
+ The set of command-ids that are contained in this gap.
+ </doc>
+ </field>
+ </control>
+
+ </class>
+
+ <!-- == Class: execution ===================================================================== -->
+
+ <class name="execution" code="0x3" label="execution commands">
+ <doc>
+ The execution class provides commands that carry execution information about other model level
+ commands.
+ </doc>
+
+ <role name="server" implement="MUST"/>
+ <role name="client" implement="MUST"/>
+
+ <domain name="error-code" type="uint16">
+ <enum>
+ <choice name="unauthorized-access" value="403">
+ <doc>
+ The client attempted to work with a server entity to which it has no access due to
+ security settings.
+ </doc>
+ </choice>
+
+ <choice name="not-found" value="404">
+ <doc>
+ The client attempted to work with a server entity that does not exist.
+ </doc>
+ </choice>
+
+ <choice name="resource-locked" value="405">
+ <doc>
+ The client attempted to work with a server entity to which it has no access because
+ another client is working with it.
+ </doc>
+ </choice>
+
+ <choice name="precondition-failed" value="406">
+ <doc>
+ The client requested a command that was not allowed because some precondition failed.
+ </doc>
+ </choice>
+
+ <choice name="resource-deleted" value="408">
+ <doc>
+ A server entity the client is working with has been deleted.
+ </doc>
+ </choice>
+
+ <choice name="illegal-state" value="409">
+ <doc>
+ The peer sent a command that is not permitted in the current state of the session.
+ </doc>
+ </choice>
+
+ <choice name="command-invalid" value="503">
+ <doc>
+ The command segments could not be decoded.
+ </doc>
+ </choice>
+
+ <choice name="resource-limit-exceeded" value="506">
+ <doc>
+ The client exceeded its resource allocation.
+ </doc>
+ </choice>
+
+ <choice name="not-allowed" value="530">
+ <doc>
+ The peer tried to use a command a manner that is inconsistent with the rules described
+ in the specification.
+ </doc>
+ </choice>
+
+ <choice name="illegal-argument" value="531">
+ <doc>
+ The command argument is malformed, i.e. it does not fall within the specified domain.
+ The illegal-argument exception can be raised on execution of any command which has
+ domain valued fields.
+ </doc>
+ </choice>
+
+ <choice name="not-implemented" value="540">
+ <doc>
+ The peer tried to use functionality that is not implemented in its partner.
+ </doc>
+ </choice>
+
+ <choice name="internal-error" value="541">
+ <doc>
+ The peer could not complete the command because of an internal error. The peer may
+ require intervention by an operator in order to resume normal operations.
+ </doc>
+ </choice>
+
+ <choice name="invalid-argument" value="542">
+ <doc>
+ An invalid argument was passed to a command, and the operation could not
+ proceed. An invalid argument is not illegal (see illegal-argument), i.e. it matches
+ the domain definition; however the particular value is invalid in this context.
+ </doc>
+ </choice>
+ </enum>
+ </domain>
+
+ <!-- - Command: execution.sync - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+ <command name="sync" code="0x1" label="request notification of completion for issued commands">
+ <doc>
+ This command is complete when all prior commands are completed.
+ </doc>
+
+ <implement role="server" handle="MUST"/>
+ <implement role="client" handle="MUST"/>
+ </command>
+
+ <!-- - Command: execution.result - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+ <command name="result" code="0x2" label="carries execution results">
+ <doc>
+ This command carries data resulting from the execution of a command.
+ </doc>
+
+ <implement role="server" handle="MUST"/>
+ <implement role="client" handle="MUST"/>
+
+ <field name="command-id" type="sequence-no" required="true"/>
+ <field name="value" type="struct32"/>
+ </command>
+
+ <!-- - Command: execution.exception - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+ <command name="exception" code="0x3" label="notifies a peer of an execution error">
+ <doc>
+ This command informs a peer of an execution exception. The command-id, when given,
+ correlates the error to a specific command.
+ </doc>
+
+ <implement role="client" handle="MUST"/>
+ <implement role="server" handle="MUST"/>
+
+ <field name="error-code" type="error-code" required="true" label="error code indicating the
+ type of error"/>
+ <field name="command-id" type="sequence-no" label="exceptional command">
+ <doc>
+ The command-id of the command which caused the exception. If the exception was not caused
+ by a specific command, this value is not set.
+ </doc>
+ </field>
+ <field name="class-code" type="uint8" label="the class code of the command whose execution
+ gave rise to the error (if appropriate)"/>
+ <field name="command-code" type="uint8" label="the class code of the command whose execution
+ gave rise to the error (if appropriate)"/>
+ <field name="field-index" type="uint8" label="index of the exceptional field">
+ <doc>
+ The zero based index of the exceptional field within the arguments to the exceptional
+ command. If the exception was not caused by a specific field, this value is not set.
+ </doc>
+ </field>
+ <field name="description" type="str16" label="descriptive text on the exception">
+ <doc>
+ The description provided is implementation defined, but MUST be in the language
+ appropriate for the selected locale. The intention is that this description is suitable
+ for logging or alerting output.
+ </doc>
+ </field>
+ <field name="error-info" type="map" label="map to carry additional information about the
+ error"/>
+
+ </command>
+
+ </class>
+
+ <!-- == Class: message ======================================================================= -->
+
+ <class name="message" code="0x4" label="message transfer">
+ <doc>
+ The message class provides commands that support an industry-standard messaging model.
+ </doc>
+
+ <doc type="picture" title="Transfer States">
+ START:
+
+ The message has yet to be sent to the recipient.
+
+ NOT-ACQUIRED:
+
+ The message has been sent to the recipient, but is not
+ acquired by the recipient.
+
+ ACQUIRED:
+
+ The message has been sent to and acquired by the recipient.
+
+ END:
+
+ The transfer is complete.
+ </doc>
+
+ <doc type="picture" title="State Transitions"><![CDATA[
+ *:TRANSFER (accept-mode=none) *:TRANSFER (acquire-mode=pre-acquired)
+ +---------------------------------START------------------------------------------+
+ | | |
+ | | *:TRANSFER (acquire-mode=not-acquired) |
+ | | |
+ | R:RELEASE \|/ |
+ | +-------------NOT-ACQUIRED<--+ |
+ | | | | | R:ACQUIRE (if unavailable) |
+ | | | +-----+ |
+ | | | |
+ | | | R:ACQUIRE (if available) |
+ | | | |
+ | | \|/ |
+ | | ACQUIRED<-------------------------------------------+
+ | | |
+ | | | R:ACCEPT / R:REJECT / R:RELEASE
+ | | |
+ | | \|/
+ | +------------->END]]>
+ | /|\
+ | |
+ +-------------------------------+
+ </doc>
+
+ <doc type="grammar">
+ message = *:TRANSFER [ R:ACQUIRE ] [ R:ACCEPT / R:REJECT / R:RELEASE ]
+ / *:RESUME
+ / *:SET-FLOW-MODE
+ / *:FLOW
+ / *:STOP
+ / C:SUBSCRIBE
+ / C:CANCEL
+ / C:FLUSH
+ </doc>
+
+ <rule name="persistent-message">
+ <doc>
+ The server SHOULD respect the delivery-mode property of messages and SHOULD make a
+ best-effort to hold persistent messages on a reliable storage mechanism.
+ </doc>
+ <doc type="scenario">
+ Send a persistent message to queue, stop server, restart server and then verify whether
+ message is still present. Assumes that queues are durable. Persistence without durable
+ queues makes no sense.
+ </doc>
+ </rule>
+
+ <rule name="no-persistent-message-discard">
+ <doc>
+ The server MUST NOT discard a persistent message in case of a queue overflow.
+ </doc>
+ <doc type="scenario">
+ Create a queue overflow situation with persistent messages and verify that messages do not
+ get lost (presumably the server will write them to disk).
+ </doc>
+ </rule>
+
+ <rule name="throttling">
+ <doc>
+ The server MAY use the message.flow command to slow or stop a message publisher when
+ necessary.
+ </doc>
+ </rule>
+
+ <rule name="non-persistent-message-overflow">
+ <doc>
+ The server MAY overflow non-persistent messages to persistent storage.
+ </doc>
+ </rule>
+
+ <rule name="non-persistent-message-discard">
+ <doc>
+ The server MAY discard or dead-letter non-persistent messages on a priority basis if the
+ queue size exceeds some configured limit.
+ </doc>
+ </rule>
+
+ <rule name="min-priority-levels">
+ <doc>
+ The server MUST implement at least 2 priority levels for messages, where priorities 0 and
+ 9 are treated as two distinct levels.
+ </doc>
+ </rule>
+
+ <rule name="priority-level-implementation">
+ <doc>
+ The server SHOULD implement distinct priority levels in the following manner:
+ </doc>
+ <doc>
+ If the server implements n distinct priorities then priorities 0 to 5 - ceiling(n/2) should
+ be treated equivalently and should be the lowest effective priority. The priorities 4 +
+ floor(n/2) should be treated equivalently and should be the highest effective priority. The
+ priorities (5 - ceiling(n/2)) to (4 + floor(n/2)) inclusive must be treated as distinct
+ priorities.
+ </doc>
+ <doc>
+ Thus, for example, if 2 distinct priorities are implemented, then levels 0 to 4 are
+ equivalent, and levels 5 to 9 are equivalent and levels 4 and 5 are distinct. If 3 distinct
+ priorities are implements the 0 to 3 are equivalent, 5 to 9 are equivalent and 3, 4 and 5
+ are distinct.
+ </doc>
+ <doc>
+ This scheme ensures that if two priorities are distinct for a server which implements m
+ separate priority levels they are also distinct for a server which implements n different
+ priority levels where n > m.
+ </doc>
+ </rule>
+
+ <rule name="priority-delivery">
+ <doc>
+ The server MUST deliver messages of the same priority in order irrespective of their
+ individual persistence.
+ </doc>
+ <doc type="scenario">
+ Send a set of messages with the same priority but different persistence settings to a queue.
+ Subscribe and verify that messages arrive in same order as originally published.
+ </doc>
+ </rule>
+
+ <role name="server" implement="MUST" />
+ <role name="client" implement="MUST" />
+
+ <domain name="destination" type="str8" label="destination for a message">
+ <doc>
+ Specifies the destination to which the message is to be transferred.
+ </doc>
+ </domain>
+
+ <domain name="accept-mode" type="uint8" label="indicates a confirmation mode">
+ <doc>
+ Controls how the sender of messages is notified of successful transfer.
+ </doc>
+
+ <enum>
+ <choice name="explicit" value="0">
+ <doc>
+ Successful transfer is signaled by message.accept. An acquired message (whether
+ acquisition was implicit as in pre-acquired mode or explicit as in not-acquired mode) is
+ not considered transferred until a message.accept that includes the transfer command is
+ received.
+ </doc>
+ </choice>
+
+ <choice name="none" value="1">
+ <doc>
+ Successful transfer is assumed when accept-mode is "pre-acquired". Messages transferred
+ with an accept-mode of "not-acquired" cannot be acquired when accept-mode is "none".
+ </doc>
+ </choice>
+ </enum>
+ </domain>
+
+ <domain name="acquire-mode" type="uint8" label="indicates the transfer mode">
+ <doc>
+ Indicates whether a transferred message can be considered as automatically acquired or
+ whether an explicit request is necessary in order to acquire it.
+ </doc>
+
+ <enum>
+ <choice name="pre-acquired" value="0">
+ <doc>
+ the message is acquired when the transfer starts
+ </doc>
+ </choice>
+
+ <choice name="not-acquired" value="1">
+ <doc>
+ the message is not acquired when it arrives, and must be explicitly acquired by the
+ recipient
+ </doc>
+ </choice>
+ </enum>
+ </domain>
+
+ <domain name="reject-code" type="uint16" label="reject code for transfer">
+ <doc>
+ Code specifying the reason for a message reject.
+ </doc>
+ <enum>
+ <choice name="unspecified" value="0">
+ <doc>
+ Rejected for an unspecified reason.
+ </doc>
+ </choice>
+ <choice name="unroutable" value="1">
+ <doc>
+ Delivery was attempted but there were no queues which the message could be routed to.
+ </doc>
+ </choice>
+ <choice name="immediate" value="2">
+ <doc>
+ The rejected message had the immediate flag set to true, but at the time of the transfer
+ at least one of the queues to which it was to be routed did not have any subscriber able
+ to take the message.
+ </doc>
+ </choice>
+ </enum>
+ </domain>
+
+ <domain name="resume-id" type="str16">
+ <doc>
+ A resume-id serves to identify partially transferred message content. The id is chosen by
+ the sender, and must be unique to a given user. A resume-id is not expected to be unique
+ across users.
+ </doc>
+ </domain>
+
+ <domain name="delivery-mode" type="uint8"
+ label="indicates whether a message should be treated as transient or durable">
+ <doc>
+
+ Used to set the reliability requirements for a message which is transferred to the server.
+ </doc>
+ <enum>
+ <choice name="non-persistent" value="1">
+ <doc>
+ A non-persistent message may be lost in event of a failure, but the nature of the
+ communication is such that an occasional message loss is tolerable. This is the lowest
+ overhead mode. Non-persistent messages are delivered at most once only.
+ </doc>
+ </choice>
+
+ <choice name="persistent" value="2">
+ <doc>
+ A persistent message is one which must be stored on a persistent medium (usually hard
+ drive) at every stage of delivery so that it will not be lost in event of failure (other
+ than of the medium itself). This is normally accomplished with some additional overhead.
+ A persistent message may be delivered more than once if there is uncertainty about the
+ state of its delivery after a failure and recovery.
+ </doc>
+ </choice>
+ </enum>
+ </domain>
+
+ <domain name="delivery-priority" type="uint8"
+ label="indicates the desired priority to assign to a message transfer">
+ <doc>
+ Used to assign a priority to a message transfer. Priorities range from 0 (lowest) to 9
+ (highest).
+ </doc>
+ <enum>
+ <choice name="lowest" value="0">
+ <doc>
+ Lowest possible priority message.
+ </doc>
+ </choice>
+
+ <choice name="lower" value="1">
+ <doc>
+ Very low priority message
+ </doc>
+ </choice>
+
+ <choice name="low" value="2">
+ <doc>
+ Low priority message.
+ </doc>
+ </choice>
+
+ <choice name="below-average" value="3">
+ <doc>
+ Below average priority message.
+ </doc>
+ </choice>
+
+ <choice name="medium" value="4">
+ <doc>
+ Medium priority message.
+ </doc>
+ </choice>
+
+
+ <choice name="above-average" value="5">
+ <doc>
+ Above average priority message
+ </doc>
+ </choice>
+
+
+ <choice name="high" value="6">
+ <doc>
+ High priority message
+ </doc>
+ </choice>
+
+ <choice name="higher" value="7">
+ <doc>
+ Higher priority message
+ </doc>
+ </choice>
+
+ <choice name="very-high" value="8">
+ <doc>
+ Very high priority message.
+ </doc>
+ </choice>
+
+ <choice name="highest" value="9">
+ <doc>
+ Highest possible priority message.
+ </doc>
+ </choice>
+ </enum>
+ </domain>
+
+ <struct name="delivery-properties" size="4" code="0x1" pack="2">
+ <field name="discard-unroutable" type="bit" label="controls discard of unroutable messages">
+ <doc>
+ If set on a message that is not routable the broker can discard it. If not set, an
+ unroutable message should be handled by reject when accept-mode is explicit; or by routing
+ to the alternate-exchange if defined when accept-mode is none.
+ </doc>
+ </field>
+
+ <field name="immediate" type="bit" label="Consider message unroutable if it cannot be
+ processed immediately">
+ <doc>
+ If the immediate flag is set to true on a message transferred to a Server, then the
+ message should be considered unroutable (and not delivered to any queues) if, for any
+ queue that it is to be routed to according to the standard routing behavior, there is not
+ a subscription on that queue able to receive the message. The treatment of unroutable
+ messages is dependent on the value of the discard-unroutable flag.
+ </doc>
+ <doc>
+ The immediate flag is ignored on transferred to a Client.
+ </doc>
+ </field>
+
+ <field name="redelivered" type="bit" label="redelivery flag">
+ <doc>
+ This boolean flag indicates that the message may have been previously delivered to this
+ or another client.
+ </doc>
+ <doc>
+ If the redelivered flag is set on transfer to a Server, then any delivery of the message
+ from that Server to a Client must also have the redelivered flag set to true.
+ </doc>
+ <rule name="implementation">
+ <doc>
+ The server MUST try to signal redelivered messages when it can. When redelivering a
+ message that was not successfully accepted, the server SHOULD deliver it to the original
+ client if possible.
+ </doc>
+ <doc type="scenario">
+ Create a shared queue and publish a message to the queue. Subscribe using explicit
+ accept-mode, but do not accept the message. Close the session, reconnect, and subscribe
+ to the queue again. The message MUST arrive with the redelivered flag set.
+ </doc>
+ </rule>
+ <rule name="hinting">
+ <doc>
+ The client should not rely on the redelivered field to detect duplicate messages where
+ publishers may themselves produce duplicates. A fully robust client should be able to
+ track duplicate received messages on non-transacted, and locally-transacted sessions.
+ </doc>
+ </rule>
+ </field>
+
+ <field name="priority" type="delivery-priority" label="message priority, 0 to 9"
+ required="true">
+ <doc> Message priority, which can be between 0 and 9. Messages with higher priorities may be
+ delivered before those with lower priorities. </doc>
+ </field>
+
+ <field name="delivery-mode" type="delivery-mode" label="message persistence requirement"
+ required="true">
+ <doc> The delivery mode may be non-persistent or persistent. </doc>
+ </field>
+
+ <field name="ttl" type="uint64" label="time to live in ms">
+ <doc> Duration in milliseconds for which the message should be considered "live". If this is
+ set then a message expiration time will be computed based on the current time plus this
+ value. Messages that live longer than their expiration time will be discarded (or dead
+ lettered).</doc>
+ <rule name="ttl-decrement">
+ <doc>
+ If a message is transferred between brokers before delivery to a final subscriber the
+ ttl should be decremented before peer to peer transfer and both timestamp and expiration
+ should be cleared.
+ </doc>
+ </rule>
+ </field>
+
+ <field name="timestamp" type="datetime" label="message timestamp">
+ <doc>
+ The timestamp is set by the broker on arrival of the message.
+ </doc>
+ </field>
+
+ <field name="expiration" type="datetime" label="message expiration time">
+ <doc>
+ The expiration header assigned by the broker. After receiving the message the broker sets
+ expiration to the sum of the ttl specified in the publish command and the current time.
+ (ttl=expiration - timestamp)
+ </doc>
+ </field>
+
+ <field name="exchange" type="exchange.name" label="originating exchange">
+ <doc>
+ Identifies the exchange specified in the destination field of the message.transfer used to
+ publish the message. This MUST be set by the broker upon receipt of a message.
+ </doc>
+ </field>
+
+ <field name="routing-key" type="str8" label="message routing key">
+ <doc>
+ The value of the key determines to which queue the exchange will send the message. The way
+ in which keys are used to make this routing decision depends on the type of exchange to
+ which the message is sent. For example, a direct exchange will route a message to a queue
+ if that queue is bound to the exchange with a binding-key identical to the routing-key of
+ the message.
+ </doc>
+ </field>
+
+ <field name="resume-id" type="resume-id" label="global id for message transfer">
+ <doc>
+ When a resume-id is provided the recipient MAY use it to retain message data should the
+ session expire while the message transfer is still incomplete.
+ </doc>
+ </field>
+
+ <field name="resume-ttl" type="uint64" label="ttl in ms for interrupted message data">
+ <doc>
+ When a resume-ttl is provided the recipient MAY use it has a guideline for how long to
+ retain the partially complete data when a resume-id is specified. If no resume-id is
+ specified then this value should be ignored.
+ </doc>
+ </field>
+ </struct>
+
+ <struct name="fragment-properties" size="4" code="0x2" pack="2">
+ <doc>
+ These properties permit the transfer of message fragments. These may be used in conjunction
+ with byte level flow control to limit the rate at which large messages are received. Only
+ the first fragment carries the delivery-properties and message-properties.
+
+ Syntactically each fragment appears as a complete message to the lower layers of the
+ protocol, however the model layer is required to treat all the fragments as a single
+ message. For example all fragments must be delivered to the same client. In pre-acquired
+ mode, no message fragments can be delivered by the broker until the entire message has been
+ received.
+ </doc>
+
+ <field name="first" type="bit" default="1">
+ <doc>True if this fragment contains the start of the message, false otherwise.</doc>
+ </field>
+
+ <field name="last" type="bit" default="1">
+ <doc>True if this fragment contains the end of the message, false otherwise.</doc>
+ </field>
+
+ <field name="fragment-size" type="uint64">
+ <doc>This field may optionally contain the size of the fragment.</doc>
+ </field>
+ </struct>
+
+ <struct name="reply-to" size="2" pack="2">
+ <doc>The reply-to domain provides a simple address structure for replying to to a message to a
+ destination within the same virtual-host.</doc>
+ <field name="exchange" type="exchange.name" label="the name of the exchange to reply to"/>
+ <field name="routing-key" type="str8" label="the routing-key to use when replying"/>
+ </struct>
+
+ <struct name="message-properties" size="4" code="0x3" pack="2">
+ <field name="content-length" type="uint64" label="length of the body segment in bytes">
+ <doc>
+ The length of the body segment in bytes.
+ </doc>
+ </field>
+
+ <field name="message-id" type="uuid" label="application message identifier">
+ <doc>
+ Message-id is an optional property of UUID type which uniquely identifies a message within
+ the message system. The message producer is usually responsible for setting the
+ message-id. The server MAY discard a message as a duplicate if the value of the message-id
+ matches that of a previously received message. Duplicate messages MUST still be accepted
+ if transferred with an accept-mode of "explicit".
+ </doc>
+
+ <rule name="unique">
+ <doc>
+ A message-id MUST be unique within a given server instance. A message-id SHOULD be
+ globally unique (i.e. across different systems).
+ </doc>
+ </rule>
+
+ <rule name="immutable">
+ <doc>
+ A message ID is immutable. Once set, a message-id MUST NOT be changed or reassigned,
+ even if the message is replicated, resent or sent to multiple queues.
+ </doc>
+ </rule>
+ </field>
+
+ <field name="correlation-id" type="vbin16" label="application correlation identifier">
+ <doc>
+ This is a client-specific id that may be used to mark or identify messages between
+ clients. The server ignores this field.
+ </doc>
+ </field>
+
+ <field name="reply-to" type="reply-to" label="destination to reply to">
+ <doc>
+ The destination of any message that is sent in reply to this message.
+ </doc>
+ </field>
+
+ <field name="content-type" type="str8" label="MIME content type">
+ <doc>
+ The RFC-2046 MIME type for the message content (such as "text/plain"). This is set by the
+ originating client.
+ </doc>
+ </field>
+
+ <field name="content-encoding" type="str8" label="MIME content encoding">
+ <doc>
+ The encoding for character-based message content. This is set by the originating client.
+ Examples include UTF-8 and ISO-8859-15.
+ </doc>
+ </field>
+
+ <field name="user-id" type="vbin16" label="creating user id">
+ <doc>
+ The identity of the user responsible for producing the message. The client sets this
+ value, and it is authenticated by the broker.
+ </doc>
+
+ <rule name="authentication">
+ <doc>
+ The server MUST produce an unauthorized-access exception if the user-id field is set to
+ a principle for which the client is not authenticated.
+ </doc>
+ </rule>
+ </field>
+
+ <field name="app-id" type="vbin16" label="creating application id">
+ <doc>
+ The identity of the client application responsible for producing the message.
+ </doc>
+ </field>
+
+ <field name="application-headers" type="map" label="application specific headers table">
+ <doc>
+ This is a collection of user-defined headers or properties which may be set by the
+ producing client and retrieved by the consuming client.
+ </doc>
+ </field>
+ </struct>
+
+ <domain name="flow-mode" type="uint8" label="the flow-mode for allocating flow credit">
+ <enum>
+ <choice name="credit" value="0">
+ <doc>
+ Credit based flow control.
+ </doc>
+ </choice>
+
+ <choice name="window" value="1">
+ <doc>
+ Window based flow control.
+ </doc>
+ </choice>
+ </enum>
+ </domain>
+
+ <domain name="credit-unit" type="uint8" label="specifies the unit of credit balance">
+ <enum>
+ <choice name="message" value="0">
+ <doc>Indicates a value specified in messages.</doc>
+ </choice>
+ <choice name="byte" value="1">
+ <doc>Indicates a value specified in bytes.</doc>
+ </choice>
+ </enum>
+ </domain>
+
+ <!-- - Command: message.transfer - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+ <command name="transfer" code="0x1" label="transfer a message">
+ <doc>
+ This command transfers a message between two peers. When a client uses this command to
+ publish a message to a broker, the destination identifies a specific exchange. The message
+ will then be routed to queues as defined by the exchange configuration.
+
+ The client may request a broker to transfer messages to it, from a particular queue, by
+ issuing a subscribe command. The subscribe command specifies the destination that the broker
+ should use for any resulting transfers.
+ </doc>
+
+ <rule name="transactional-publish">
+ <doc>
+ If a transfer to an exchange occurs within a transaction, then it is not available from
+ the queue until the transaction commits. It is not specified whether routing takes place
+ when the transfer is received or when the transaction commits.
+ </doc>
+ </rule>
+
+ <implement role="server" handle="MUST" />
+ <implement role="client" handle="MUST" />
+
+
+ <field name="destination" type="destination" label="message destination">
+ <doc>
+ Specifies the destination to which the message is to be transferred.
+ </doc>
+
+ <rule name="blank-destination">
+ <doc>
+ The server MUST accept a blank destination to mean the default exchange.
+ </doc>
+ </rule>
+
+ <exception name="nonexistent-exchange" error-code="not-found">
+ <doc>
+ If the destination refers to an exchange that does not exist, the peer MUST raise a
+ session exception.
+ </doc>
+ </exception>
+ </field>
+
+ <field name="accept-mode" type="accept-mode" required="true">
+ <doc>
+ Indicates whether message.accept, session.complete, or nothing at all is required to
+ indicate successful transfer of the message.
+ </doc>
+ </field>
+
+ <field name="acquire-mode" type="acquire-mode" required="true">
+ <doc>
+ Indicates whether or not the transferred message has been acquired.
+ </doc>
+ </field>
+
+ <segments>
+ <header>
+ <entry type="delivery-properties"/>
+ <entry type="fragment-properties"/>
+ <entry type="message-properties"/>
+ </header>
+ <body/>
+ </segments>
+ </command>
+
+ <!-- - Command: message.accept - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+ <command name="accept" code="0x2" label="reject a message">
+ <doc>
+ Accepts the message. Once a transfer is accepted, the command-id may no longer be referenced
+ from other commands.
+ </doc>
+
+ <rule name="acquisition">
+ <doc>
+ The recipient MUST have acquired a message in order to accept it.
+ </doc>
+ </rule>
+
+ <implement role="server" handle="MUST" />
+ <implement role="client" handle="MUST" />
+
+ <field name="transfers" type="session.commands" required="true">
+ <doc>
+ Identifies the messages previously transferred that should be accepted.
+ </doc>
+ </field>
+ </command>
+
+ <!-- - Command: message.reject - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+ <command name="reject" code="0x3" label="reject a message">
+ <doc>
+ Indicates that the message transfers are unprocessable in some way. A server may reject a
+ message if it is unroutable. A client may reject a message if it is invalid. A message may
+ be rejected for other reasons as well. Once a transfer is rejected, the command-id may no
+ longer be referenced from other commands.
+ </doc>
+
+ <rule name="alternate-exchange">
+ <doc>
+ When a client rejects a message, the server MUST deliver that message to the
+ alternate-exchange on the queue from which it was delivered. If no alternate-exchange is
+ defined for that queue the broker MAY discard the message.
+ </doc>
+ </rule>
+
+ <rule name="acquisition">
+ <doc>
+ The recipient MUST have acquired a message in order to reject it. If the message is not
+ acquired any reject MUST be ignored.
+ </doc>
+ </rule>
+
+ <implement role="server" handle="MUST" />
+ <implement role="client" handle="MUST" />
+
+ <field name="transfers" type="session.commands" required="true">
+ <doc>
+ Identifies the messages previously transferred that should be rejected.
+ </doc>
+ </field>
+ <field name="code" type="reject-code" required="true">
+ <doc>
+ Code describing the reason for rejection.
+ </doc>
+ </field>
+ <field name="text" type="str8" label="informational text for message reject">
+ <doc>
+ Text describing the reason for rejection.
+ </doc>
+ </field>
+ </command>
+
+ <!-- - Command: message.release - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+ <command name="release" code="0x4" label="release a message">
+ <doc>
+ Release previously transferred messages. When acquired messages are released, they become
+ available for acquisition by any subscriber. Once a transfer is released, the command-id may
+ no longer be referenced from other commands.
+ </doc>
+
+ <rule name="ordering">
+ <doc>
+ Acquired messages that have been released MAY subsequently be delivered out of order.
+ Implementations SHOULD ensure that released messages keep their position with respect to
+ undelivered messages of the same priority.
+ </doc>
+ </rule>
+
+ <implement role="server" handle="MUST" />
+ <implement role="client" handle="MAY" />
+
+ <field name="transfers" type="session.commands" required="true">
+ <doc>
+ Indicates the messages to be released.
+ </doc>
+ </field>
+ <field name="set-redelivered" type="bit" label="mark the released messages as redelivered">
+ <doc>
+ By setting set-redelivered to true, any acquired messages released to a queue with this
+ command will be marked as redelivered on their next transfer from that queue. If this flag
+ is not set, then an acquired message will retain its original redelivered status on the
+ queue. Messages that are not acquired are unaffected by the value of this flag.
+ </doc>
+ </field>
+ </command>
+
+ <!-- - Command: message.acquire - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+ <command name="acquire" code="0x5" label="acquire messages for consumption">
+ <doc>
+ Acquires previously transferred messages for consumption. The acquired ids (if any) are
+ sent via message.acquired.
+ </doc>
+
+ <rule name="one-to-one">
+ <doc>
+ Each acquire MUST produce exactly one message.acquired even if it is empty.
+ </doc>
+ </rule>
+
+ <implement role="server" handle="MUST" />
+
+ <field name="transfers" type="session.commands" required="true">
+ <doc>
+ Indicates the messages to be acquired.
+ </doc>
+ </field>
+
+ <result>
+ <struct name="acquired" size="4" code="0x4" pack="2" label="indicates acquired messages">
+ <doc>
+ Identifies a set of previously transferred messages that have now been acquired.
+ </doc>
+
+ <field name="transfers" type="session.commands" required="true">
+ <doc>
+ Indicates the acquired messages.
+ </doc>
+ </field>
+ </struct>
+ </result>
+ </command>
+
+ <!-- - Command: message.resume - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+ <command name="resume" code="0x6" label="resume an interrupted message transfer">
+ <doc>
+ This command resumes an interrupted transfer. The recipient should return the amount of
+ partially transferred data associated with the given resume-id, or zero if there is no data
+ at all. If a non-zero result is returned, the recipient should expect to receive message
+ fragment(s) containing the remainder of the interrupted message.
+ </doc>
+
+ <implement role="server" handle="MUST" />
+ <implement role="client" handle="MUST" />
+
+ <field name="destination" type="destination">
+ <doc>
+ The destination to which the remaining message fragments are transferred.
+ </doc>
+
+ <exception name="destination-not-found" error-code="not-found">
+ <doc>If the destination does not exist, the recipient MUST close the session.</doc>
+ </exception>
+ </field>
+
+ <field name="resume-id" type="resume-id" required="true">
+ <doc>
+ The name of the transfer being resumed.
+ </doc>
+
+ <rule name="unknown-resume-id">
+ <doc>If the resume-id is not known, the recipient MUST return an offset of zero.</doc>
+ </rule>
+ </field>
+
+ <result>
+ <struct name="message-resume-result" size="4" code="0x5" pack="2">
+ <field name="offset" type="uint64">
+ <doc>
+ Indicates the amount of data already transferred.
+ </doc>
+ </field>
+ </struct>
+ </result>
+ </command>
+
+ <!-- - Command: message.subscribe - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+ <command name="subscribe" code="0x7" label="start a queue subscription">
+ <doc> This command asks the server to start a "subscription", which is a request for messages
+ from a specific queue. Subscriptions last as long as the session they were created on, or
+ until the client cancels them. </doc>
+
+ <rule name="simultaneous-subscriptions">
+ <doc> The server SHOULD support at least 16 subscriptions per queue, and ideally, impose no
+ limit except as defined by available resources. </doc>
+ <doc type="scenario"> Create a queue and create subscriptions on that queue until the server
+ closes the connection. Verify that the number of subscriptions created was at least
+ sixteen and report the total number. </doc>
+ </rule>
+
+ <rule name="default-flow-mode">
+ <doc> The default flow mode for new subscriptions is window-mode. </doc>
+ </rule>
+
+ <exception name="queue-deletion" error-code="resource-deleted">
+ <doc>
+ If the queue for this subscription is deleted, any subscribing sessions MUST be closed.
+ This exception may occur at any time after the subscription has been completed.
+ </doc>
+ </exception>
+
+ <exception name="queue-not-found" error-code="not-found">
+ <doc> If the queue for this subscription does not exist, then the subscribing session MUST
+ be closed. </doc>
+ </exception>
+
+ <rule name="initial-credit">
+ <doc>
+ Immediately after a subscription is created, the initial byte and message credit for that
+ destination is zero.
+ </doc>
+ </rule>
+
+ <implement role="server" handle="MUST"/>
+
+ <field name="queue" type="queue.name" required="true">
+ <doc> Specifies the name of the subscribed queue. </doc>
+ </field>
+
+ <field name="destination" type="destination" label="incoming message destination">
+ <doc> The client specified name for the subscription. This is used as the destination for
+ all messages transferred from this subscription. The destination is scoped to the session.
+ </doc>
+
+ <exception name="unique-subscriber-destination" error-code="not-allowed">
+ <doc> The client MUST NOT specify a destination that refers to an existing subscription on
+ the same session. </doc>
+ <doc type="scenario"> Attempt to create two subscriptions on the same session with the
+ same non-empty destination. </doc>
+ </exception>
+ </field>
+
+ <field name="accept-mode" type="accept-mode" required="true">
+ <doc> The accept-mode to use for messages transferred from this subscription. </doc>
+ </field>
+
+ <field name="acquire-mode" type="acquire-mode" required="true">
+ <doc> The acquire-mode to use for messages transferred from this subscription. </doc>
+ </field>
+
+ <field name="exclusive" type="bit" label="request exclusive access">
+ <doc> Request an exclusive subscription. This prevents other subscribers from subscribing to
+ the queue. </doc>
+
+ <exception name="in-use" error-code="resource-locked">
+ <doc> The server MUST NOT grant an exclusive subscription to a queue that already has
+ subscribers. </doc>
+ <doc type="scenario"> Open two connections to a server, and in one connection create a
+ shared (non-exclusive) queue and then subscribe to the queue. In the second connection
+ attempt to subscribe to the same queue using the exclusive option. </doc>
+ </exception>
+ </field>
+
+ <field name="resume-id" type="resume-id">
+ <doc> Requests that the broker use the supplied resume-id when transferring messages for
+ this subscription. </doc>
+ </field>
+
+ <field name="resume-ttl" type="uint64">
+ <doc> Requested duration in milliseconds for the broker use as resume-ttl when transferring
+ messages for this subscription. </doc>
+ </field>
+
+ <field name="arguments" type="map" label="arguments for vendor extensions">
+ <doc> The syntax and semantics of these arguments depends on the providers implementation.
+ </doc>
+ </field>
+ </command>
+
+ <!-- - Command: message.cancel - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+ <command name="cancel" code="0x8" label="end a queue subscription">
+ <doc>
+ This command cancels a subscription. This does not affect already delivered messages, but it
+ does mean the server will not send any more messages for that subscription. The client may
+ receive an arbitrary number of messages in between sending the cancel command and receiving
+ notification that the cancel command is complete.
+ </doc>
+
+ <rule name="post-cancel-transfer-resolution">
+ <doc>
+ Canceling a subscription MUST NOT affect pending transfers. A transfer made prior to
+ canceling transfers to the destination MUST be able to be accepted, released, acquired, or
+ rejected after the subscription is canceled.
+ </doc>
+ </rule>
+
+ <implement role="server" handle="MUST" />
+
+ <field name="destination" type="destination" required="true">
+ <exception name="subscription-not-found" error-code="not-found">
+ <doc>
+ If the subscription specified by the destination is not found, the server MUST close the
+ session.
+ </doc>
+ </exception>
+ </field>
+ </command>
+
+ <!-- - Command: message.set-flow-mode - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+ <command name="set-flow-mode" code="0x9" label="set the flow control mode">
+ <doc>
+ Sets the mode of flow control used for a given destination to either window or credit based
+ flow control.
+
+ With credit based flow control, the sender of messages continually maintains its current
+ credit balance with the recipient. The credit balance consists of two values, a message
+ count, and a byte count. Whenever message data is sent, both counts must be decremented.
+ If either value reaches zero, the flow of message data must stop. Additional credit is
+ received via the message.flow command.
+
+ The sender MUST NOT send partial assemblies. This means that if there is not enough byte
+ credit available to send a complete message, the sender must either wait or use message
+ fragmentation (see the fragment-properties header struct) to send the first part of the
+ message data in a complete assembly.
+
+ Window based flow control is identical to credit based flow control, however message
+ transfer completion implicitly grants a single unit of message credit, and the size of the
+ message in byte credits for each completed message transfer. Completion of the transfer
+ command with session.completed is the only way credit is implicitly updated; message.accept,
+ message.release, message.reject, tx.commit and tx.rollback have no effect on the outstanding
+ credit balances.
+ </doc>
+
+ <rule name="byte-accounting">
+ <doc>
+ The byte count is decremented by the payload size of each transmitted frame with segment
+ type header or body appearing within a message.transfer command. Note that the payload
+ size is the frame size less the frame header size.
+ </doc>
+ </rule>
+
+ <rule name="mode-switching">
+ <doc>
+ Mode switching may only occur if both the byte and message credit balance are zero. There
+ are three ways for a recipient of messages to be sure that the sender's credit balances
+ are zero:
+
+ 1) The recipient may send a message.stop command to the sender. When the recipient
+ receives notification of completion for the message.stop command, it knows that the
+ sender's credit is zero.
+
+ 2) The recipient may perform the same steps described in (1) with the message.flush
+ command substituted for the message.stop command.
+
+ 3) Immediately after a subscription is created with message.subscribe, the credit for
+ that destination is zero.
+ </doc>
+ </rule>
+
+ <rule name="default-flow-mode">
+ <doc>
+ Prior to receiving an explicit set-flow-mode command, a peer MUST consider the flow-mode
+ to be window.
+ </doc>
+ </rule>
+
+ <implement role="server" handle="MUST" />
+ <implement role="client" handle="MUST" />
+
+ <field name="destination" type="destination"/>
+ <field name="flow-mode" type="flow-mode" required="true">
+ <doc>
+ The new flow control mode.
+ </doc>
+ </field>
+ </command>
+
+ <!-- - Command: message.flow - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+ <command name="flow" code="0xa" label="control message flow">
+ <doc>
+ This command controls the flow of message data to a given destination. It is used by the
+ recipient of messages to dynamically match the incoming rate of message flow to its
+ processing or forwarding capacity. Upon receipt of this command, the sender must add "value"
+ number of the specified unit to the available credit balance for the specified destination.
+ A value of (0xFFFFFFFF) indicates an infinite amount of credit. This disables any limit for
+ the given unit until the credit balance is zeroed with message.stop or message.flush.
+ </doc>
+
+ <!-- throws no-such-destination -->
+
+ <implement role="server" handle="MUST" />
+ <implement role="client" handle="MUST" />
+
+ <field name="destination" type="destination"/>
+ <field name="unit" type="credit-unit" required="true">
+ <doc>
+ The unit of value.
+ </doc>
+ </field>
+ <field name="value" type="uint32">
+ <doc>
+ If the value is not set then this indicates an infinite amount of credit.
+ </doc>
+ </field>
+ </command>
+
+ <!-- - Command: message.flush - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+ <command name="flush" code="0xb" label="force the sending of available messages">
+ <doc>
+ Forces the sender to exhaust his credit supply. The sender's credit will always be zero when
+ this command completes. The command completes when immediately available message data has
+ been transferred, or when the credit supply is exhausted.
+ </doc>
+
+ <implement role="server" handle="MUST" />
+
+ <field name="destination" type="destination"/>
+ </command>
+
+ <!-- - Command: message.stop - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+ <command name="stop" code="0xc" label="stop the sending of messages">
+ <doc>
+ On receipt of this command, a producer of messages MUST set his credit to zero for the given
+ destination. When notifying of completion, credit MUST be zero and no further messages will
+ be sent until such a time as further credit is received.
+ </doc>
+
+ <implement role="server" handle="MUST" />
+ <implement role="client" handle="MUST" />
+
+ <field name="destination" type="destination"/>
+ </command>
+
+ </class>
+
+ <!-- == Class: tx ============================================================================ -->
+
+ <class name="tx" code="0x5" label="work with standard transactions">
+ <doc>
+ Standard transactions provide so-called "1.5 phase commit". We can ensure that work is never
+ lost, but there is a chance of confirmations being lost, so that messages may be resent.
+ Applications that use standard transactions must be able to detect and ignore duplicate
+ messages.
+ </doc>
+
+ <doc type="grammar">
+ tx = C:SELECT
+ / C:COMMIT
+ / C:ROLLBACK
+ </doc>
+
+ <!-- XXX: this isn't really a rule, as stated there is no way for
+ a client library to implement this -->
+ <rule name="duplicate-tracking">
+ <doc>
+ An client using standard transactions SHOULD be able to track all messages received within a
+ reasonable period, and thus detect and reject duplicates of the same message. It SHOULD NOT
+ pass these to the application layer.
+ </doc>
+ </rule>
+
+ <role name="server" implement="SHOULD" />
+
+ <!-- - Command: tx.select - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+ <command name="select" code="0x1" label="select standard transaction mode">
+ <doc>
+ This command sets the session to use standard transactions. The client must use this command
+ exactly once on a session before using the Commit or Rollback commands.
+ </doc>
+
+ <exception name="exactly-once" error-code="illegal-state">
+ <doc>
+ A client MUST NOT select standard transactions on a session that is already transactional.
+ </doc>
+ </exception>
+
+ <exception name="no-dtx" error-code="illegal-state">
+ <doc>
+ A client MUST NOT select standard transactions on a session that is already enlisted in a
+ distributed transaction.
+ </doc>
+ </exception>
+
+ <exception name="explicit-accepts" error-code="not-allowed">
+ <doc>
+ On a session on which tx.select has been issued, a client MUST NOT issue a
+ message.subscribe command with the accept-mode property set to any value other than
+ explicit. Similarly a tx.select MUST NOT be issued on a session on which a there is a non
+ cancelled subscriber with accept-mode of none.
+ </doc>
+ </exception>
+
+ <implement role="server" handle="MUST" />
+ </command>
+
+ <!-- - Command: tx.commit - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+ <command name="commit" code="0x2" label="commit the current transaction">
+ <doc>
+ This command commits all messages published and accepted in the current transaction. A
+ new transaction starts immediately after a commit.
+ </doc>
+ <doc>
+ In more detail, the commit acts on all messages which have been transferred from the Client
+ to the Server, and on all acceptances of messages sent from Server to Client. Since the
+ commit acts on commands sent in the same direction as the commit command itself, there is no
+ ambiguity on the scope of the commands being committed. Further, the commit will not be
+ completed until all preceding commands which it affects have been completed.
+ </doc>
+ <doc>
+ Since transactions act on explicit accept commands, the only valid accept-mode for message
+ subscribers is explicit. For transferring messages from Client to Server (publishing) all
+ accept-modes are permitted.
+ </doc>
+
+ <exception name="select-required" error-code="illegal-state">
+ <doc>
+ A client MUST NOT issue tx.commit on a session that has not been selected for standard
+ transactions with tx.select.
+ </doc>
+ </exception>
+
+
+
+ <implement role="server" handle="MUST" />
+ </command>
+
+ <!-- - Command: tx.rollback - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+ <command name="rollback" code="0x3" label="abandon the current transaction">
+ <doc>
+ This command abandons the current transaction. In particular the transfers from Client to
+ Server (publishes) and accepts of transfers from Server to Client which occurred in the
+ current transaction are discarded. A new transaction starts immediately after a rollback.
+ </doc>
+ <doc>
+ In more detail, when a rollback is issued, any the effects of transfers which occurred from
+ Client to Server are discarded. The Server will issue completion notification for all such
+ transfers prior to the completion of the rollback. Similarly the effects of any
+ message.accept issued from Client to Server prior to the issuance of the tx.rollback will be
+ discarded; and notification of completion for all such commands will be issued before the
+ issuance of the completion for the rollback.
+ </doc>
+ <doc>
+ After the completion of the rollback, the client will still hold the messages which it has
+ not yet accepted (including those for which accepts were previously issued within the
+ transaction); i.e. the messages remain "acquired". If the Client wishes to release those
+ messages back to the Server, then appropriate message.release commands must be issued.
+ </doc>
+
+ <exception name="select-required" error-code="illegal-state">
+ <doc>
+ A client MUST NOT issue tx.rollback on a session that has not been selected for standard
+ transactions with tx.select.
+ </doc>
+ </exception>
+
+ <implement role="server" handle="MUST" />
+ </command>
+
+ </class>
+
+ <!-- == Class: dtx =========================================================================== -->
+
+ <class name="dtx" code="0x6" label="Demarcates dtx branches">
+ <doc>
+ This provides the X-Open XA distributed transaction protocol support. It allows a session
+ to be selected for use with distributed transactions, the transactional boundaries for work on
+ that session to be demarcated and allows the transaction manager to coordinate transaction
+ outcomes.
+ </doc>
+
+ <doc type="grammar">
+ dtx-demarcation = C:SELECT *demarcation
+ demarcation = C:START C:END
+ </doc>
+
+ <doc type="grammar">
+ dtx-coordination = *coordination
+ coordination = command
+ / outcome
+ / recovery
+ command = C:SET-TIMEOUT
+ / C:GET-TIMEOUT
+ outcome = one-phase-commit
+ / one-phase-rollback
+ / two-phase-commit
+ / two-phase-rollback
+ one-phase-commit = C:COMMIT
+ one-phase-rollback = C:ROLLBACK
+ two-phase-commit = C:PREPARE C:COMMIT
+ two-phase-rollback = C:PREPARE C:ROLLBACK
+ recovery = C:RECOVER *recovery-outcome
+ recovery-outcome = one-phase-commit
+ / one-phase-rollback
+ / C:FORGET
+
+ </doc>
+
+ <rule name="transactionality">
+ <doc>
+ Enabling XA transaction support on a session requires that the server MUST manage
+ transactions demarcated by start-end blocks. That is to say that on this XA-enabled session,
+ work undergone within transactional blocks is performed on behalf a transaction branch
+ whereas work performed outside of transactional blocks is NOT transactional.
+ </doc>
+ </rule>
+
+ <role name="server" implement="MAY" />
+ <role name="client" implement="MAY" />
+
+ <!-- XA domains -->
+
+ <domain name="xa-status" type="uint16" label="XA return codes">
+ <enum>
+ <choice name="xa-ok" value="0">
+ <doc>
+ Normal execution completion (no error).
+ </doc>
+ </choice>
+
+ <choice name="xa-rbrollback" value="1">
+ <doc>
+ The rollback was caused for an unspecified reason.
+ </doc>
+ </choice>
+
+ <choice name="xa-rbtimeout" value="2">
+ <doc>
+ A transaction branch took too long.
+ </doc>
+ </choice>
+
+ <choice name="xa-heurhaz" value="3">
+ <doc>
+ The transaction branch may have been heuristically completed.
+ </doc>
+ </choice>
+
+ <choice name="xa-heurcom" value="4">
+ <doc>
+ The transaction branch has been heuristically committed.
+ </doc>
+ </choice>
+
+ <choice name="xa-heurrb" value="5">
+ <doc>
+ The transaction branch has been heuristically rolled back.
+ </doc>
+ </choice>
+
+ <choice name="xa-heurmix" value="6">
+ <doc>
+ The transaction branch has been heuristically committed and rolled back.
+ </doc>
+ </choice>
+
+ <choice name="xa-rdonly" value="7">
+ <doc>
+ The transaction branch was read-only and has been committed.
+ </doc>
+ </choice>
+ </enum>
+ </domain>
+
+ <struct name="xa-result" size="4" code="0x1" pack="2">
+ <field name="status" type="xa-status" required="true"/>
+ </struct>
+
+ <!-- Struct for xid -->
+
+ <struct name="xid" size="4" code="0x4" pack="2" label="dtx branch identifier">
+ <doc>
+ An xid uniquely identifies a transaction branch.
+ </doc>
+
+ <field name="format" type="uint32" label="implementation specific format code"
+ required="true"/>
+ <field name="global-id" type="vbin8" label="global transaction id" required="true"/>
+ <field name="branch-id" type="vbin8" label="branch qualifier" required="true"/>
+ </struct>
+
+ <!-- - Command: dtx.select - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+ <command name="select" code="0x1" label="Select dtx mode">
+ <doc>
+ This command sets the session to use distributed transactions. The client must use this
+ command at least once on a session before using XA demarcation operations.
+ </doc>
+
+ <implement role="server" handle="MAY" />
+ </command>
+
+ <!-- - Command: dtx.start - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+ <command name="start" code="0x2" label="Start a dtx branch">
+ <doc>
+ This command is called when messages should be produced and consumed on behalf a transaction
+ branch identified by xid.
+ </doc>
+
+ <exception name="illegal-state" error-code="illegal-state">
+ <doc>
+ If the command is invoked in an improper context (see class grammar) then the server MUST
+ send a session exception.
+ </doc>
+ </exception>
+
+ <exception name="already-known" error-code="not-allowed">
+ <doc>
+ If neither join nor resume is specified is specified and the transaction branch specified
+ by xid has previously been seen then the server MUST raise an exception.
+ </doc>
+ </exception>
+
+ <exception name="join-and-resume" error-code="not-allowed">
+ <doc>
+ If join and resume are specified then the server MUST raise an exception.
+ </doc>
+ </exception>
+
+ <implement role="server" handle="MAY" />
+
+ <field name="xid" type="xid" label="Transaction xid" required="true">
+ <doc>
+ Specifies the xid of the transaction branch to be started.
+ </doc>
+
+ <exception name="unknown-xid" error-code="not-allowed">
+ <doc>
+ If xid is already known by the broker then the server MUST raise an exception.
+ </doc>
+ </exception>
+ </field>
+
+ <field name="join" type="bit" label="Join with existing xid flag">
+ <doc>
+ Indicate whether this is joining an already associated xid. Indicate that the start
+ applies to joining a transaction previously seen.
+ </doc>
+
+ <exception name="unsupported" error-code="not-implemented">
+ <doc>
+ If the broker does not support join the server MUST raise an exception.
+ </doc>
+ </exception>
+ </field>
+
+ <field name="resume" type="bit" label="Resume flag">
+ <doc>
+ Indicate that the start applies to resuming a suspended transaction branch specified.
+ </doc>
+ </field>
+
+ <result type="xa-result">
+ <doc>
+ This confirms to the client that the transaction branch is started or specify the error
+ condition.
+
+ The value of this field may be one of the following constants:
+
+ xa-ok: Normal execution.
+
+ xa-rbrollback: The broker marked the transaction branch rollback-only for an unspecified
+ reason.
+
+ xa-rbtimeout: The work represented by this transaction branch took too long.
+ </doc>
+ </result>
+ </command>
+
+ <!-- - Command: dtx.end - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+ <command name="end" code="0x3" label="End a dtx branch">
+ <doc>
+ This command is called when the work done on behalf a transaction branch finishes or needs
+ to be suspended.
+ </doc>
+
+ <exception name="illegal-state" error-code="illegal-state">
+ <doc>
+ If the command is invoked in an improper context (see class grammar) then the server MUST
+ raise an exception.
+ </doc>
+ </exception>
+
+ <exception name="suspend-and-fail" error-code="not-allowed">
+ <doc>
+ If suspend and fail are specified then the server MUST raise an exception.
+ </doc>
+ </exception>
+
+ <rule name="success">
+ <doc>
+ If neither fail nor suspend are specified then the portion of work has completed
+ successfully.
+ </doc>
+ </rule>
+
+ <rule name="session-closed">
+ <doc>
+ When a session is closed then the currently associated transaction branches MUST be marked
+ rollback-only.
+ </doc>
+ </rule>
+
+ <implement role="server" handle="MAY" />
+
+ <field name="xid" type="xid" label="Transaction xid" required="true">
+ <doc>
+ Specifies the xid of the transaction branch to be ended.
+ </doc>
+
+ <exception name="not-associated" error-code="illegal-state">
+ <doc>
+ The session MUST be currently associated with the given xid (through an earlier start
+ call with the same xid).
+ </doc>
+ </exception>
+ </field>
+
+ <field name="fail" type="bit" label="Failure flag">
+ <doc>
+ If set, indicates that this portion of work has failed; otherwise this portion of work has
+ completed successfully.
+ </doc>
+
+ <rule name="failure">
+ <doc>
+ An implementation MAY elect to roll a transaction back if this failure notification is
+ received. Should an implementation elect to implement this behavior, and this bit is
+ set, then then the transaction branch SHOULD be marked as rollback-only and the end
+ result SHOULD have the xa-rbrollback status set.
+ </doc>
+ </rule>
+ </field>
+
+ <field name="suspend" type="bit" label="Temporary suspension flag">
+ <doc>
+ Indicates that the transaction branch is temporarily suspended in an incomplete state.
+ </doc>
+
+ <rule name="resume">
+ <doc>
+ The transaction context is in a suspended state and must be resumed via the start
+ command with resume specified.
+ </doc>
+ </rule>
+
+ </field>
+
+ <result type="xa-result">
+ <doc>
+ This command confirms to the client that the transaction branch is ended or specify the
+ error condition.
+
+ The value of this field may be one of the following constants:
+
+ xa-ok: Normal execution.
+
+ xa-rbrollback: The broker marked the transaction branch rollback-only for an unspecified
+ reason. If an implementation chooses to implement rollback-on-failure behavior, then
+ this value should be selected if the dtx.end.fail bit was set.
+
+ xa-rbtimeout: The work represented by this transaction branch took too long.
+ </doc>
+ </result>
+ </command>
+
+ <!-- - Command: dtx.commit - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+ <command name="commit" code="0x4" label="Commit work on dtx branch">
+ <doc>
+ Commit the work done on behalf a transaction branch. This command commits the work
+ associated with xid. Any produced messages are made available and any consumed messages are
+ discarded.
+ </doc>
+
+ <exception name="illegal-state" error-code="illegal-state">
+ <doc>
+ If the command is invoked in an improper context (see class grammar) then the server MUST
+ raise an exception.
+ </doc>
+ </exception>
+
+ <implement role="server" handle="MAY" />
+
+ <field name="xid" type="xid" label="Transaction xid" required="true">
+ <doc>
+ Specifies the xid of the transaction branch to be committed.
+ </doc>
+
+ <exception name="unknown-xid" error-code="not-found">
+ <doc>
+ If xid is unknown (the transaction branch has not been started or has already been
+ ended) then the server MUST raise an exception.
+ </doc>
+ </exception>
+
+ <exception name="not-disassociated" error-code="illegal-state">
+ <doc>
+ If this command is called when xid is still associated with a session then the server
+ MUST raise an exception.
+ </doc>
+ </exception>
+ </field>
+
+ <field name="one-phase" type="bit" label="One-phase optimization flag">
+ <doc>
+ Used to indicate whether one-phase or two-phase commit is used.
+ </doc>
+
+ <exception name="one-phase" error-code="illegal-state">
+ <doc>
+ The one-phase bit MUST be set if a commit is sent without a preceding prepare.
+ </doc>
+ </exception>
+
+ <exception name="two-phase" error-code="illegal-state">
+ <doc>
+ The one-phase bit MUST NOT be set if the commit has been preceded by prepare.
+ </doc>
+ </exception>
+ </field>
+
+ <result type="xa-result">
+ <doc>
+ This confirms to the client that the transaction branch is committed or specify the
+ error condition.
+
+ The value of this field may be one of the following constants:
+
+ xa-ok: Normal execution
+
+ xa-heurhaz: Due to some failure, the work done on behalf of the specified transaction
+ branch may have been heuristically completed.
+
+ xa-heurcom: Due to a heuristic decision, the work done on behalf of the specified
+ transaction branch was committed.
+
+ xa-heurrb: Due to a heuristic decision, the work done on behalf of the specified
+ transaction branch was rolled back.
+
+ xa-heurmix: Due to a heuristic decision, the work done on behalf of the specified
+ transaction branch was partially committed and partially rolled back.
+
+ xa-rbrollback: The broker marked the transaction branch rollback-only for an unspecified
+ reason.
+
+ xa-rbtimeout: The work represented by this transaction branch took too long.
+ </doc>
+ </result>
+ </command>
+
+ <!-- - Command: dtx.forget - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+ <command name="forget" code="0x5" label="Discard dtx branch">
+ <doc>
+ This command is called to forget about a heuristically completed transaction branch.
+ </doc>
+
+ <exception name="illegal-state" error-code="illegal-state">
+ <doc>
+ If the command is invoked in an improper context (see class grammar) then the server MUST
+ raise an exception.
+ </doc>
+ </exception>
+
+ <implement role="server" handle="MAY" />
+
+ <field name="xid" type="xid" label="Transaction xid" required="true">
+ <doc>
+ Specifies the xid of the transaction branch to be forgotten.
+ </doc>
+
+ <exception name="unknown-xid" error-code="not-found">
+ <doc>
+ If xid is unknown (the transaction branch has not been started or has already been
+ ended) then the server MUST raise an exception.
+ </doc>
+ </exception>
+
+ <exception name="not-disassociated" error-code="illegal-state">
+ <doc>
+ If this command is called when xid is still associated with a session then the server
+ MUST raise an exception.
+ </doc>
+ </exception>
+ </field>
+ </command>
+
+ <!-- - Command: dtx.get-timeout - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+ <command name="get-timeout" code="0x6" label="Obtain dtx timeout in seconds">
+ <doc>
+ This command obtains the current transaction timeout value in seconds. If set-timeout was
+ not used prior to invoking this command, the return value is the default timeout; otherwise,
+ the value used in the previous set-timeout call is returned.
+ </doc>
+
+ <implement role="server" handle="MAY" />
+
+ <field name="xid" type="xid" label="Transaction xid" required="true">
+ <doc>
+ Specifies the xid of the transaction branch for getting the timeout.
+ </doc>
+
+ <exception name="unknown-xid" error-code="not-found">
+ <doc>
+ If xid is unknown (the transaction branch has not been started or has already been
+ ended) then the server MUST raise an exception.
+ </doc>
+ </exception>
+ </field>
+
+ <result>
+ <struct name="get-timeout-result" size="4" code="0x2" pack="2">
+ <doc> Returns the value of the timeout last specified through set-timeout. </doc>
+
+ <field name="timeout" type="uint32" label="The current transaction timeout value"
+ required="true">
+ <doc> The current transaction timeout value in seconds. </doc>
+ </field>
+ </struct>
+ </result>
+ </command>
+
+ <!-- - Command: dtx.prepare - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+ <command name="prepare" code="0x7" label="Prepare a dtx branch">
+ <doc>
+ This command prepares for commitment any message produced or consumed on behalf of xid.
+ </doc>
+
+ <exception name="illegal-state" error-code="illegal-state">
+ <doc>
+ If the command is invoked in an improper context (see class grammar) then the server MUST
+ raise an exception.
+ </doc>
+ </exception>
+
+ <rule name="obligation-1">
+ <doc>
+ Once this command successfully returns it is guaranteed that the transaction branch may be
+ either committed or rolled back regardless of failures.
+ </doc>
+ </rule>
+
+ <rule name="obligation-2">
+ <doc>
+ The knowledge of xid cannot be erased before commit or rollback complete the branch.
+ </doc>
+ </rule>
+
+ <implement role="server" handle="MAY" />
+
+ <field name="xid" type="xid" label="Transaction xid" required="true">
+ <doc>
+ Specifies the xid of the transaction branch that can be prepared.
+ </doc>
+
+ <exception name="unknown-xid" error-code="not-found">
+ <doc>
+ If xid is unknown (the transaction branch has not been started or has already been
+ ended) then the server MUST raise an exception.
+ </doc>
+ </exception>
+
+ <exception name="not-disassociated" error-code="illegal-state">
+ <doc>
+ If this command is called when xid is still associated with a session then the server
+ MUST raise an exception.
+ </doc>
+ </exception>
+ </field>
+
+ <result type="xa-result">
+ <doc>
+ This command confirms to the client that the transaction branch is prepared or specify the
+ error condition.
+
+ The value of this field may be one of the following constants:
+
+ xa-ok: Normal execution.
+
+ xa-rdonly: The transaction branch was read-only and has been committed.
+
+ xa-rbrollback: The broker marked the transaction branch rollback-only for an unspecified
+ reason.
+
+ xa-rbtimeout: The work represented by this transaction branch took too long.
+ </doc>
+ </result>
+ </command>
+
+ <!-- - Command: dtx.recover - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+ <command name="recover" code="0x8" label="Get prepared or completed xids">
+ <doc>
+ This command is called to obtain a list of transaction branches that are in a prepared or
+ heuristically completed state.
+ </doc>
+
+ <implement role="server" handle="MAY" />
+
+ <result>
+ <struct name="recover-result" size="4" code="0x3" pack="2">
+ <doc>
+ Returns to the client a table with single item that is a sequence of transaction xids
+ that are in a prepared or heuristically completed state.
+ </doc>
+
+ <field name="in-doubt" type="array" label="array of xids to be recovered" required="true">
+ <doc> Array containing the xids to be recovered (xids that are in a prepared or
+ heuristically completed state). </doc>
+
+ </field>
+ </struct>
+ </result>
+ </command>
+
+ <!-- - Command: dtx.rollback - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+ <command name="rollback" code="0x9" label="Rollback a dtx branch">
+ <doc>
+ This command rolls back the work associated with xid. Any produced messages are discarded
+ and any consumed messages are re-enqueued.
+ </doc>
+
+ <exception name="illegal-state" error-code="illegal-state">
+ <doc>
+ If the command is invoked in an improper context (see class grammar) then the server MUST
+ raise an exception.
+ </doc>
+ </exception>
+
+ <implement role="server" handle="MAY" />
+
+ <field name="xid" type="xid" label="Transaction xid" required="true">
+ <doc>
+ Specifies the xid of the transaction branch that can be rolled back.
+ </doc>
+
+ <exception name="unknown-xid" error-code="not-found">
+ <doc>
+ If xid is unknown (the transaction branch has not been started or has already been
+ ended) then the server MUST raise an exception.
+ </doc>
+ </exception>
+
+ <exception name="not-disassociated" error-code="illegal-state">
+ <doc>
+ If this command is called when xid is still associated with a session then the server
+ MUST raise an exception.
+ </doc>
+ </exception>
+ </field>
+
+ <result type="xa-result">
+ <doc>
+ This command confirms to the client that the transaction branch is rolled back or specify
+ the error condition.
+
+ The value of this field may be one of the following constants:
+
+ xa-ok: Normal execution
+
+ xa-heurhaz: Due to some failure, the work done on behalf of the specified transaction
+ branch may have been heuristically completed.
+
+ xa-heurcom: Due to a heuristic decision, the work done on behalf of the specified
+ transaction branch was committed.
+
+ xa-heurrb: Due to a heuristic decision, the work done on behalf of the specified
+ transaction branch was rolled back.
+
+ xa-heurmix: Due to a heuristic decision, the work done on behalf of the specified
+ transaction branch was partially committed and partially rolled back.
+
+ xa-rbrollback: The broker marked the transaction branch rollback-only for an unspecified
+ reason.
+
+ xa-rbtimeout: The work represented by this transaction branch took too long.
+ </doc>
+ </result>
+ </command>
+
+ <!-- - Command: dtx.set-timeout - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+ <command name="set-timeout" code="0xa" label="Set dtx timeout value">
+ <doc>
+ Sets the specified transaction branch timeout value in seconds.
+ </doc>
+
+ <rule name="effective">
+ <doc>
+ Once set, this timeout value is effective until this command is reinvoked with a different
+ value.
+ </doc>
+ </rule>
+
+ <rule name="reset">
+ <doc>
+ A value of zero resets the timeout value to the default value.
+ </doc>
+ </rule>
+
+ <implement role="server" handle="MAY" />
+
+ <field name="xid" type="xid" label="Transaction xid" required="true">
+ <doc>
+ Specifies the xid of the transaction branch for setting the timeout.
+ </doc>
+
+ <exception name="unknown-xid" error-code="not-found">
+ <doc>
+ If xid is unknown (the transaction branch has not been started or has already been
+ ended) then the server MUST raise an exception.
+ </doc>
+ </exception>
+
+ </field>
+
+ <field name="timeout" type="uint32" label="Dtx timeout in seconds" required="true">
+ <doc>
+ The transaction timeout value in seconds.
+ </doc>
+ </field>
+ </command>
+
+ </class>
+
+ <!-- == Class: exchange ====================================================================== -->
+
+ <class name="exchange" code="0x7" label="work with exchanges">
+ <doc>
+ Exchanges match and distribute messages across queues. Exchanges can be configured in the
+ server or created at runtime.
+ </doc>
+
+ <doc type="grammar">
+ exchange = C:DECLARE
+ / C:DELETE
+ / C:QUERY
+ </doc>
+
+ <rule name="required-types">
+ <doc>
+ The server MUST implement these standard exchange types: fanout, direct.
+ </doc>
+ <doc type="scenario">
+ Client attempts to declare an exchange with each of these standard types.
+ </doc>
+ </rule>
+
+ <rule name="recommended-types">
+ <doc>
+ The server SHOULD implement these standard exchange types: topic, headers.
+ </doc>
+ <doc type="scenario">
+ Client attempts to declare an exchange with each of these standard types.
+ </doc>
+ </rule>
+
+ <rule name="required-instances">
+ <doc>
+ The server MUST, in each virtual host, pre-declare an exchange instance for each standard
+ exchange type that it implements, where the name of the exchange instance, if defined, is
+ "amq." followed by the exchange type name.
+
+ The server MUST, in each virtual host, pre-declare at least two direct exchange instances:
+ one named "amq.direct", the other with no public name that serves as a default exchange for
+ publish commands (such as message.transfer).
+ </doc>
+ <doc type="scenario">
+ Client creates a temporary queue and attempts to bind to each required exchange instance
+ ("amq.fanout", "amq.direct", "amq.topic", and "amq.headers" if those types are defined).
+ </doc>
+ </rule>
+
+ <rule name="default-exchange">
+ <doc>
+ The server MUST pre-declare a direct exchange with no public name to act as the default
+ exchange for content publish commands (such as message.transfer) and for default queue
+ bindings.
+ </doc>
+ <doc type="scenario">
+ Client checks that the default exchange is active by publishing a message with a suitable
+ routing key but without specifying the exchange name, then ensuring that the message arrives
+ in the queue correctly.
+ </doc>
+ </rule>
+
+ <rule name="default-access">
+ <doc>
+ The default exchange MUST NOT be accessible to the client except by specifying an empty
+ exchange name in a content publish command (such as message.transfer). That is, the server
+ must not let clients explicitly bind, unbind, delete, or make any other reference to this
+ exchange.
+ </doc>
+ </rule>
+
+ <rule name="extensions">
+ <doc>
+ The server MAY implement other exchange types as wanted.
+ </doc>
+ </rule>
+
+ <role name="server" implement="MUST" />
+ <role name="client" implement="MUST" />
+
+ <domain name="name" type="str8" label="exchange name">
+ <doc>
+ The exchange name is a client-selected string that identifies the exchange for publish
+ commands. Exchange names may consist of any mixture of digits, letters, and underscores.
+ Exchange names are scoped by the virtual host.
+ </doc>
+ </domain>
+
+ <!-- - Command: exchange.declare - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+ <command name="declare" code="0x1" label="verify exchange exists, create if needed">
+ <doc>
+ This command creates an exchange if it does not already exist, and if the exchange exists,
+ verifies that it is of the correct and expected class.
+ </doc>
+
+ <rule name="minimum">
+ <doc>
+ The server SHOULD support a minimum of 16 exchanges per virtual host and ideally, impose
+ no limit except as defined by available resources.
+ </doc>
+ <doc type="scenario">
+ The client creates as many exchanges as it can until the server reports an error; the
+ number of exchanges successfully created must be at least sixteen.
+ </doc>
+ </rule>
+
+ <implement role="server" handle="MUST" />
+
+ <field name="exchange" type="name" required="true">
+ <exception name="reserved-names" error-code="not-allowed">
+ <doc>
+ Exchange names starting with "amq." are reserved for pre-declared and standardized
+ exchanges. The client MUST NOT attempt to create an exchange starting with "amq.".
+ </doc>
+ </exception>
+
+ <exception name="exchange-name-required" error-code="invalid-argument">
+ <doc>
+ The name of the exchange MUST NOT be a blank or empty string.
+ </doc>
+ </exception>
+ </field>
+
+ <field name="type" type="str8" label="exchange type" required="true">
+ <doc>
+ Each exchange belongs to one of a set of exchange types implemented by the server. The
+ exchange types define the functionality of the exchange - i.e. how messages are routed
+ through it. It is not valid or meaningful to attempt to change the type of an existing
+ exchange.
+ </doc>
+
+ <exception name="typed" error-code="not-allowed">
+ <doc>
+ Exchanges cannot be redeclared with different types. The client MUST NOT attempt to
+ redeclare an existing exchange with a different type than used in the original
+ exchange.declare command.
+ </doc>
+ </exception>
+
+ <exception name="exchange-type-not-found" error-code="not-found">
+ <doc>
+ If the client attempts to create an exchange which the server does not recognize, an
+ exception MUST be sent.
+ </doc>
+ </exception>
+ </field>
+
+ <field name="alternate-exchange" type="name" label= "exchange name for unroutable messages">
+ <doc>
+ In the event that a message cannot be routed, this is the name of the exchange to which
+ the message will be sent. Messages transferred using message.transfer will be routed to
+ the alternate-exchange only if they are sent with the "none" accept-mode, and the
+ discard-unroutable delivery property is set to false, and there is no queue to route to
+ for the given message according to the bindings on this exchange.
+ </doc>
+
+ <rule name="empty-name">
+ <doc>
+ If alternate-exchange is not set (its name is an empty string), unroutable messages
+ that would be sent to the alternate-exchange MUST be dropped silently.
+ </doc>
+ </rule>
+
+ <exception name="pre-existing-exchange" error-code="not-allowed">
+ <doc>
+ If the alternate-exchange is not empty and if the exchange already exists with a
+ different alternate-exchange, then the declaration MUST result in an exception.
+ </doc>
+ </exception>
+
+ <rule name="double-failure">
+ <doc>
+ A message which is being routed to a alternate exchange, MUST NOT be re-routed to a
+ secondary alternate exchange if it fails to route in the primary alternate exchange.
+ After such a failure, the message MUST be dropped. This prevents looping.
+ </doc>
+ </rule>
+ </field>
+
+ <field name="passive" type="bit" label="do not create exchange">
+ <doc>
+ If set, the server will not create the exchange. The client can use this to check whether
+ an exchange exists without modifying the server state.
+ </doc>
+ <exception name="not-found" error-code="not-found">
+ <doc>
+ If set, and the exchange does not already exist, the server MUST raise an exception.
+ </doc>
+ </exception>
+ </field>
+
+ <field name="durable" type="bit" label="request a durable exchange">
+ <doc>
+ If set when creating a new exchange, the exchange will be marked as durable. Durable
+ exchanges remain active when a server restarts. Non-durable exchanges (transient
+ exchanges) are purged if/when a server restarts.
+ </doc>
+
+ <rule name="support">
+ <doc>
+ The server MUST support both durable and transient exchanges.
+ </doc>
+ </rule>
+
+ <rule name="sticky">
+ <doc>
+ The server MUST ignore the durable field if the exchange already exists.
+ </doc>
+ </rule>
+ </field>
+
+ <field name="auto-delete" type="bit" label="auto-delete when unused">
+ <doc>
+ If set, the exchange is deleted automatically when there remain no bindings between the
+ exchange and any queue. Such an exchange will not be automatically deleted until at least
+ one binding has been made to prevent the immediate deletion of the exchange upon creation.
+ </doc>
+ <rule name="sticky">
+ <doc>
+ The server MUST ignore the auto-delete field if the exchange already exists.
+ </doc>
+ </rule>
+ </field>
+
+ <field name="arguments" type="map" label="arguments for declaration">
+ <doc>
+ A set of arguments for the declaration. The syntax and semantics of these arguments
+ depends on the server implementation. This field is ignored if passive is 1.
+ </doc>
+
+ <exception name="unknown-argument" error-code="not-implemented">
+ <doc>
+ If the arguments field contains arguments which are not understood by the server,
+ it MUST raise an exception.
+ </doc>
+ </exception>
+ </field>
+ </command>
+
+ <!-- - Command: exchange.delete - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+ <command name="delete" code="0x2" label="delete an exchange">
+ <doc>
+ This command deletes an exchange. When an exchange is deleted all queue bindings on the
+ exchange are cancelled.
+ </doc>
+
+ <implement role="server" handle="MUST" />
+
+ <field name="exchange" type="name" required="true">
+ <exception name="exists" error-code="not-found">
+ <doc>
+ The client MUST NOT attempt to delete an exchange that does not exist.
+ </doc>
+ </exception>
+
+ <exception name="exchange-name-required" error-code="invalid-argument">
+ <doc>
+ The name of the exchange MUST NOT be a missing or empty string.
+ </doc>
+ </exception>
+
+ <exception name="used-as-alternate" error-code="not-allowed">
+ <doc>
+ An exchange MUST NOT be deleted if it is in use as an alternate-exchange by a queue or
+ by another exchange.
+ </doc>
+ </exception>
+
+ </field>
+
+ <field name="if-unused" type="bit" label="delete only if unused">
+ <doc>
+ If set, the server will only delete the exchange if it has no queue bindings. If the
+ exchange has queue bindings the server does not delete it but raises an exception
+ instead.
+ </doc>
+ <exception name="exchange-in-use" error-code="precondition-failed">
+ <doc>
+ If the exchange has queue bindings, and the if-unused flag is set, the server MUST NOT
+ delete the exchange, but MUST raise and exception.
+ </doc>
+ </exception>
+ </field>
+ </command>
+
+ <!-- - Command: exchange.query - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+ <command name="query" code="0x3" label="request information about an exchange">
+ <doc>
+ This command is used to request information on a particular exchange.
+ </doc>
+
+ <implement role="server" handle="MUST" />
+
+ <field name="name" type="str8" label="the exchange name">
+ <doc>
+ The name of the exchange for which information is requested. If not specified explicitly
+ the default exchange is implied.
+ </doc>
+ </field>
+
+ <result>
+ <struct name="exchange-query-result" size="4" code="0x1" pack="2">
+ <doc>
+ This is sent in response to a query request and conveys information on a particular
+ exchange.
+ </doc>
+
+ <field name="type" type="str8" label="indicate the exchange type">
+ <doc>
+ The type of the exchange. Will be empty if the exchange is not found.
+ </doc>
+ </field>
+
+ <field name="durable" type="bit" label="indicate the durability">
+ <doc>
+ The durability of the exchange, i.e. if set the exchange is durable. Will not be set
+ if the exchange is not found.
+ </doc>
+ </field>
+
+ <field name="not-found" type="bit" label="indicate an unknown exchange">
+ <doc>
+ If set, the exchange for which information was requested is not known.
+ </doc>
+ </field>
+
+ <field name="arguments" type="map" label="other unspecified exchange properties">
+ <doc>
+ A set of properties of the exchange whose syntax and semantics depends on the server
+ implementation. Will be empty if the exchange is not found.
+ </doc>
+ </field>
+ </struct>
+ </result>
+ </command>
+
+ <!-- - Command: exchange.bind - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+ <command name="bind" code="0x4" label="bind queue to an exchange">
+ <doc> This command binds a queue to an exchange. Until a queue is bound it will not receive
+ any messages. In a classic messaging model, store-and-forward queues are bound to a direct
+ exchange and subscription queues are bound to a topic exchange. </doc>
+
+ <rule name="duplicates">
+ <doc>
+ A server MUST ignore duplicate bindings - that is, two or more bind commands with the
+ same exchange, queue, and binding-key - without treating these as an error. The value of
+ the arguments used for the binding MUST NOT be altered by subsequent binding requests.
+ </doc>
+ <doc type="scenario">
+ A client binds a named queue to an exchange. The client then repeats the bind (with
+ identical exchange, queue, and binding-key). The second binding should use a different
+ value for the arguments field.
+ </doc>
+ </rule>
+
+ <rule name="durable-exchange">
+ <doc> Bindings between durable queues and durable exchanges are automatically durable and
+ the server MUST restore such bindings after a server restart. </doc>
+ <doc type="scenario"> A server creates a named durable queue and binds it to a durable
+ exchange. The server is restarted. The client then attempts to use the queue/exchange
+ combination. </doc>
+ </rule>
+
+ <rule name="binding-count">
+ <doc> The server SHOULD support at least 4 bindings per queue, and ideally, impose no limit
+ except as defined by available resources. </doc>
+ <doc type="scenario"> A client creates a named queue and attempts to bind it to 4 different
+ exchanges. </doc>
+ </rule>
+
+ <rule name="multiple-bindings">
+ <doc> Where more than one binding exists between a particular exchange instance and a
+ particular queue instance any given message published to that exchange should be delivered
+ to that queue at most once, regardless of how many distinct bindings match. </doc>
+ <doc type="scenario"> A client creates a named queue and binds it to the same topic exchange
+ at least three times using intersecting binding-keys (for example, "animals.*",
+ "animals.dogs.*", "animal.dogs.chihuahua"). Verify that a message matching all the
+ bindings (using previous example, routing key = "animal.dogs.chihuahua") is delivered once
+ only. </doc>
+ </rule>
+
+ <implement role="server" handle="MUST"/>
+
+ <field name="queue" type="queue.name" required="true">
+ <doc> Specifies the name of the queue to bind. </doc>
+
+ <exception name="empty-queue" error-code="invalid-argument">
+ <doc> A client MUST NOT be allowed to bind a non-existent and unnamed queue (i.e. empty
+ queue name) to an exchange. </doc>
+ <doc type="scenario"> A client attempts to bind with an unnamed (empty) queue name to an
+ exchange. </doc>
+ </exception>
+
+ <exception name="queue-existence" error-code="not-found">
+ <doc> A client MUST NOT be allowed to bind a non-existent queue (i.e. not previously
+ declared) to an exchange. </doc>
+ <doc type="scenario"> A client attempts to bind an undeclared queue name to an exchange.
+ </doc>
+ </exception>
+ </field>
+
+ <field name="exchange" type="name" label="name of the exchange to bind to" required="true">
+ <exception name="exchange-existence" error-code="not-found">
+ <doc> A client MUST NOT be allowed to bind a queue to a non-existent exchange. </doc>
+ <doc type="scenario"> A client attempts to bind a named queue to a undeclared exchange.
+ </doc>
+ </exception>
+
+ <exception name="exchange-name-required" error-code="invalid-argument">
+ <doc> The name of the exchange MUST NOT be a blank or empty string. </doc>
+ </exception>
+ </field>
+
+ <field name="binding-key" type="str8"
+ label="identifies a binding between a given exchange and queue" required="true">
+ <doc> The binding-key uniquely identifies a binding between a given (exchange, queue) pair.
+ Depending on the exchange configuration, the binding key may be matched against the
+ message routing key in order to make routing decisions. The match algorithm depends on the
+ exchange type. Some exchange types may ignore the binding key when making routing
+ decisions. Refer to the specific exchange type documentation. The meaning of an empty
+ binding key depends on the exchange implementation. </doc>
+ </field>
+
+ <field name="arguments" type="map" label="arguments for binding">
+ <doc> A set of arguments for the binding. The syntax and semantics of these arguments
+ depends on the exchange class. </doc>
+
+ <exception name="unknown-argument" error-code="not-implemented">
+ <doc> If the arguments field contains arguments which are not understood by the server, it
+ MUST raise an exception. </doc>
+ </exception>
+ </field>
+ </command>
+
+ <!-- - Command: exchange.unbind - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+ <command name="unbind" code="0x5" label="unbind a queue from an exchange">
+ <doc>
+ This command unbinds a queue from an exchange.
+ </doc>
+
+ <implement role="server" handle="MUST" />
+
+ <field name="queue" type="queue.name" required="true">
+ <doc>
+ Specifies the name of the queue to unbind.
+ </doc>
+ <exception name="non-existent-queue" error-code="not-found">
+ <doc>
+ If the queue does not exist the server MUST raise an exception.
+ </doc>
+ </exception>
+ </field>
+
+ <field name="exchange" type="name" required="true">
+ <doc>
+ The name of the exchange to unbind from.
+ </doc>
+
+ <exception name="non-existent-exchange" error-code="not-found">
+ <doc>
+ If the exchange does not exist the server MUST raise an exception.
+ </doc>
+ </exception>
+
+ <exception name="exchange-name-required" error-code="invalid-argument">
+ <doc>
+ The name of the exchange MUST NOT be a blank or empty string.
+ </doc>
+ </exception>
+ </field>
+
+ <field name="binding-key" type="str8" label="the key of the binding" required="true">
+ <doc>
+ Specifies the binding-key of the binding to unbind.
+ </doc>
+
+ <exception name="non-existent-binding-key" error-code="not-found">
+ <doc>
+ If there is no matching binding-key the server MUST raise an exception.
+ </doc>
+ </exception>
+ </field>
+ </command>
+
+ <!-- - Command: exchange.bound - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+ <command name="bound" code="0x6" label="request information about bindings to an exchange">
+ <doc>
+ This command is used to request information on the bindings to a particular exchange.
+ </doc>
+
+ <implement role="server" handle="MUST" />
+
+ <field name="exchange" type="str8" label="the exchange name">
+ <doc>
+ The name of the exchange for which binding information is being requested. If not
+ specified explicitly the default exchange is implied.
+ </doc>
+ </field>
+
+ <field name="queue" type="str8" label="a queue name" required="true">
+ <doc>
+ If populated then determine whether the given queue is bound to the exchange.
+ </doc>
+ </field>
+
+ <field name="binding-key" type="str8" label="a binding-key">
+ <doc>
+ If populated defines the binding-key of the binding of interest, if not populated the
+ request will ignore the binding-key on bindings when searching for a match.
+ </doc>
+ </field>
+
+ <field name="arguments" type="map" label="a set of binding arguments">
+ <doc>
+ If populated defines the arguments of the binding of interest if not populated the request
+ will ignore the arguments on bindings when searching for a match
+ </doc>
+ </field>
+
+ <result>
+ <struct name="exchange-bound-result" size="4" code="0x2" pack="2">
+ <field name="exchange-not-found" type="bit" label="indicate an unknown exchange">
+ <doc>
+ If set, the exchange for which information was requested is not known.
+ </doc>
+ </field>
+
+ <field name="queue-not-found" type="bit" label="indicate an unknown queue">
+ <doc>
+ If set, the queue specified is not known.
+ </doc>
+ </field>
+
+ <field name="queue-not-matched" type="bit" label="indicate no matching queue">
+ <doc>
+ A bit which if set indicates that no binding was found from the specified exchange to
+ the specified queue.
+ </doc>
+ </field>
+
+ <field name="key-not-matched" type="bit" label="indicate no matching binding-key">
+ <doc>
+ A bit which if set indicates that no binding was found from the specified exchange
+ with the specified binding-key.
+ </doc>
+ </field>
+
+ <field name="args-not-matched" type="bit" label="indicate no matching arguments">
+ <doc>
+ A bit which if set indicates that no binding was found from the specified exchange
+ with the specified arguments.
+ </doc>
+ </field>
+ </struct>
+ </result>
+ </command>
+
+ </class>
+
+ <!-- == Class: queue ========================================================================= -->
+
+ <class name="queue" code="0x8" label="work with queues">
+ <doc>
+ Queues store and forward messages. Queues can be configured in the server or created at
+ runtime. Queues must be attached to at least one exchange in order to receive messages from
+ publishers.
+ </doc>
+
+ <doc type="grammar">
+ queue = C:DECLARE
+ / C:BIND
+ / C:PURGE
+ / C:DELETE
+ / C:QUERY
+ / C:UNBIND
+ </doc>
+
+ <rule name="any-content">
+ <doc>
+ A server MUST allow any content class to be sent to any queue, in any mix, and queue and
+ deliver these content classes independently. Note that all commands that fetch content off
+ queues are specific to a given content class.
+ </doc>
+ <doc type="scenario">
+ Client creates an exchange of each standard type and several queues that it binds to each
+ exchange. It must then successfully send each of the standard content types to each of the
+ available queues.
+ </doc>
+ </rule>
+
+ <role name="server" implement="MUST" />
+ <role name="client" implement="MUST" />
+
+ <domain name="name" type="str8" label="queue name">
+ <doc>
+ The queue name identifies the queue within the virtual host. Queue names must have a length
+ of between 1 and 255 characters inclusive, must start with a digit, letter or underscores
+ ('_') character, and must be otherwise encoded in UTF-8.
+ </doc>
+ </domain>
+
+ <!-- - Command: queue.declare - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+ <command name="declare" code="0x1" label="declare queue">
+ <doc>
+ This command creates or checks a queue. When creating a new queue the client can specify
+ various properties that control the durability of the queue and its contents, and the level
+ of sharing for the queue.
+ </doc>
+
+ <rule name="default-binding">
+ <doc>
+ The server MUST create a default binding for a newly-created queue to the default
+ exchange, which is an exchange of type 'direct' and use the queue name as the binding-key.
+ </doc>
+ <doc type="scenario">
+ Client creates a new queue, and then without explicitly binding it to an exchange,
+ attempts to send a message through the default exchange binding, i.e. publish a message to
+ the empty exchange, with the queue name as binding-key.
+ </doc>
+ </rule>
+
+ <rule name="minimum-queues">
+ <doc>
+ The server SHOULD support a minimum of 256 queues per virtual host and ideally, impose no
+ limit except as defined by available resources.
+ </doc>
+ <doc type="scenario">
+ Client attempts to create as many queues as it can until the server reports an error. The
+ resulting count must at least be 256.
+ </doc>
+ </rule>
+
+ <implement role="server" handle="MUST" />
+
+ <field name="queue" type="name" required="true">
+ <exception name="reserved-prefix" error-code="not-allowed">
+ <doc>
+ Queue names starting with "amq." are reserved for pre-declared and standardized server
+ queues. A client MUST NOT attempt to declare a queue with a name that starts with "amq."
+ and the passive option set to zero.
+ </doc>
+ <doc type="scenario">
+ A client attempts to create a queue with a name starting with "amq." and with the
+ passive option set to zero.
+ </doc>
+ </exception>
+ </field>
+
+ <field name="alternate-exchange" type="exchange.name"
+ label= "exchange name for messages with exceptions">
+ <doc>
+ The alternate-exchange field specifies how messages on this queue should be treated when
+ they are rejected by a subscriber, or when they are orphaned by queue deletion. When
+ present, rejected or orphaned messages MUST be routed to the alternate-exchange. In all
+ cases the messages MUST be removed from the queue.
+ </doc>
+
+ <exception name="pre-existing-exchange" error-code="not-allowed">
+ <doc>
+ If the alternate-exchange is not empty and if the queue already exists with a different
+ alternate-exchange, then the declaration MUST result in an exception.
+ </doc>
+ </exception>
+
+ <exception name="unknown-exchange" error-code="not-found">
+ <doc>
+ if the alternate-exchange does not match the name of any existing exchange on the
+ server, then an exception must be raised.
+ </doc>
+ </exception>
+ </field>
+
+ <field name="passive" type="bit" label="do not create queue">
+ <doc>
+ If set, the server will not create the queue. This field allows the client to assert the
+ presence of a queue without modifying the server state.
+ </doc>
+
+ <exception name="passive" error-code="not-found">
+ <doc>
+ The client MAY ask the server to assert that a queue exists without creating the queue
+ if not. If the queue does not exist, the server treats this as a failure.
+ </doc>
+ <doc type="scenario">
+ Client declares an existing queue with the passive option and expects the command to
+ succeed. Client then attempts to declare a non-existent queue with the passive option,
+ and the server must close the session with the correct exception.
+ </doc>
+ </exception>
+ </field>
+
+ <field name="durable" type="bit" label="request a durable queue">
+ <doc>
+ If set when creating a new queue, the queue will be marked as durable. Durable queues
+ remain active when a server restarts. Non-durable queues (transient queues) are purged
+ if/when a server restarts. Note that durable queues do not necessarily hold persistent
+ messages, although it does not make sense to send persistent messages to a transient
+ queue.
+ </doc>
+
+ <rule name="persistence">
+ <doc>
+ The queue definition MUST survive the server losing all transient memory, e.g. a
+ machine restart.
+ </doc>
+ <doc type="scenario">
+ Client creates a durable queue; server is then restarted. Client then attempts to send
+ message to the queue. The message should be successfully delivered.
+ </doc>
+ </rule>
+
+ <rule name="types">
+ <doc>
+ The server MUST support both durable and transient queues.
+ </doc>
+ <doc type="scenario">
+ A client creates two named queues, one durable and one transient.
+ </doc>
+ </rule>
+
+ <rule name="pre-existence">
+ <doc>
+ The server MUST ignore the durable field if the queue already exists.
+ </doc>
+ <doc type="scenario">
+ A client creates two named queues, one durable and one transient. The client then
+ attempts to declare the two queues using the same names again, but reversing the value
+ of the durable flag in each case. Verify that the queues still exist with the original
+ durable flag values.
+ </doc>
+ </rule>
+ </field>
+
+ <field name="exclusive" type="bit" label="request an exclusive queue">
+ <doc>
+ Exclusive queues can only be used from one session at a time. Once a session
+ declares an exclusive queue, that queue cannot be used by any other session until the
+ declaring session closes.
+ </doc>
+
+ <rule name="types">
+ <doc>
+ The server MUST support both exclusive (private) and non-exclusive (shared) queues.
+ </doc>
+ <doc type="scenario">
+ A client creates two named queues, one exclusive and one non-exclusive.
+ </doc>
+ </rule>
+
+ <exception name="in-use" error-code="resource-locked">
+ <doc>
+ If the server receives a declare, bind, consume or get request for a queue that has been
+ declared as exclusive by an existing client session, it MUST raise an exception.
+ </doc>
+ <doc type="scenario">
+ A client declares an exclusive named queue. A second client on a different session
+ attempts to declare a queue of the same name.
+ </doc>
+ </exception>
+ </field>
+
+ <field name="auto-delete" type="bit" label="auto-delete queue when unused">
+ <doc>
+ If this field is set and the exclusive field is also set, then the queue MUST be deleted
+ when the session closes.
+
+ If this field is set and the exclusive field is not set the queue is deleted when all
+ the consumers have finished using it. Last consumer can be cancelled either explicitly
+ or because its session is closed. If there was no consumer ever on the queue, it won't
+ be deleted.
+ </doc>
+
+ <rule name="pre-existence">
+ <doc>
+ The server MUST ignore the auto-delete field if the queue already exists.
+ </doc>
+ <doc type="scenario">
+ A client creates two named queues, one as auto-delete and one explicit-delete. The
+ client then attempts to declare the two queues using the same names again, but reversing
+ the value of the auto-delete field in each case. Verify that the queues still exist with
+ the original auto-delete flag values.
+ </doc>
+ </rule>
+ </field>
+
+ <field name="arguments" type="map" label="arguments for declaration">
+ <doc>
+ A set of arguments for the declaration. The syntax and semantics of these arguments
+ depends on the server implementation. This field is ignored if passive is 1.
+ </doc>
+
+ <exception name="unknown-argument" error-code="not-implemented">
+ <doc>
+ If the arguments field contains arguments which are not understood by the server,
+ it MUST raise an exception.
+ </doc>
+ </exception>
+ </field>
+ </command>
+
+ <!-- - Command: queue.delete - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+ <command name="delete" code="0x2" label="delete a queue">
+ <doc>
+ This command deletes a queue. When a queue is deleted any pending messages are sent to the
+ alternate-exchange if defined, or discarded if it is not.
+ </doc>
+
+
+ <implement role="server" handle="MUST" />
+
+ <field name="queue" type="name" required="true">
+ <doc>
+ Specifies the name of the queue to delete.
+ </doc>
+
+ <exception name="empty-name" error-code="invalid-argument">
+ <doc>
+ If the queue name in this command is empty, the server MUST raise an exception.
+ </doc>
+ </exception>
+
+ <exception name="queue-exists" error-code="not-found">
+ <doc>
+ The queue must exist. If the client attempts to delete a non-existing queue the server
+ MUST raise an exception.
+ </doc>
+ </exception>
+ </field>
+
+ <field name="if-unused" type="bit" label="delete only if unused">
+ <doc>
+ If set, the server will only delete the queue if it has no consumers. If the queue has
+ consumers the server does does not delete it but raises an exception instead.
+ </doc>
+
+ <exception name="if-unused-flag" error-code="precondition-failed">
+ <doc>
+ The server MUST respect the if-unused flag when deleting a queue.
+ </doc>
+ </exception>
+ </field>
+
+ <field name="if-empty" type="bit" label="delete only if empty">
+ <doc>
+ If set, the server will only delete the queue if it has no messages.
+ </doc>
+ <exception name="not-empty" error-code="precondition-failed">
+ <doc>
+ If the queue is not empty the server MUST raise an exception.
+ </doc>
+ </exception>
+ </field>
+ </command>
+
+ <!-- - Command: queue.purge - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+ <command name="purge" code="0x3" label="purge a queue">
+ <doc>
+ This command removes all messages from a queue. It does not cancel subscribers. Purged
+ messages are deleted without any formal "undo" mechanism.
+ </doc>
+
+ <rule name="empty">
+ <doc>
+ A call to purge MUST result in an empty queue.
+ </doc>
+ </rule>
+
+ <rule name="pending-messages">
+ <doc>
+ The server MUST NOT purge messages that have already been sent to a client but not yet
+ accepted.
+ </doc>
+ </rule>
+
+ <rule name="purge-recovery">
+ <doc>
+ The server MAY implement a purge queue or log that allows system administrators to recover
+ accidentally-purged messages. The server SHOULD NOT keep purged messages in the same
+ storage spaces as the live messages since the volumes of purged messages may get very
+ large.
+ </doc>
+ </rule>
+
+ <implement role="server" handle="MUST" />
+
+ <field name="queue" type="name" required="true">
+ <doc>
+ Specifies the name of the queue to purge.
+ </doc>
+
+ <exception name="empty-name" error-code="invalid-argument">
+ <doc>
+ If the the queue name in this command is empty, the server MUST raise an exception.
+ </doc>
+ </exception>
+
+ <exception name="queue-exists" error-code="not-found">
+ <doc>
+ The queue MUST exist. Attempting to purge a non-existing queue MUST cause an exception.
+ </doc>
+ </exception>
+ </field>
+ </command>
+
+ <!-- - Command: queue.query - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+ <command name="query" code="0x4" label="request information about a queue">
+ <doc>
+ This command requests information about a queue.
+ </doc>
+
+ <implement role="server" handle="MUST" />
+
+ <field name="queue" type="name" label="the queried queue" required="true"/>
+
+ <result>
+ <struct name="queue-query-result" size="4" code="0x1" pack="2">
+ <doc>
+ This is sent in response to queue.query, and conveys the requested information about a
+ queue. If no queue with the specified name exists then none of the fields within the
+ returned result struct will be populated.
+ </doc>
+
+ <field name="queue" type="name" required="true">
+ <doc>
+ Reports the name of the queue.
+ </doc>
+ </field>
+
+ <field name="alternate-exchange" type="exchange.name" />
+
+ <field name="durable" type="bit" />
+
+ <field name="exclusive" type="bit" />
+
+ <field name="auto-delete" type="bit" />
+
+ <field name="arguments" type="map" />
+
+ <field name="message-count" type="uint32" label="number of messages in queue"
+ required="true">
+ <doc> Reports the number of messages in the queue. </doc>
+ </field>
+
+ <field name="subscriber-count" type="uint32" label="number of subscribers"
+ required="true">
+ <doc>
+ Reports the number of subscribers for the queue.
+ </doc>
+ </field>
+ </struct>
+ </result>
+ </command>
+
+ </class>
+
+ <!-- == Class: file ========================================================================== -->
+
+ <class name="file" code="0x9" label="work with file content">
+ <doc>
+ The file class provides commands that support reliable file transfer. File messages have a
+ specific set of properties that are required for interoperability with file transfer
+ applications. File messages and acknowledgements are subject to session transactions. Note
+ that the file class does not provide message browsing commands; these are not compatible with
+ the staging model. Applications that need browsable file transfer should use Message content
+ and the Message class.
+ </doc>
+
+ <doc type="grammar">
+ file = C:QOS S:QOS-OK
+ / C:CONSUME S:CONSUME-OK
+ / C:CANCEL
+ / C:OPEN S:OPEN-OK C:STAGE content
+ / S:OPEN C:OPEN-OK S:STAGE content
+ / C:PUBLISH
+ / S:DELIVER
+ / S:RETURN
+ / C:ACK
+ / C:REJECT
+ </doc>
+
+ <rule name="reliable-storage">
+ <doc>
+ The server MUST make a best-effort to hold file messages on a reliable storage mechanism.
+ </doc>
+ </rule>
+
+ <rule name="no-discard">
+ <doc>
+ The server MUST NOT discard a file message in case of a queue overflow. The server MUST use
+ the Session.Flow command to slow or stop a file message publisher when necessary.
+ </doc>
+ </rule>
+
+ <rule name="priority-levels">
+ <doc>
+ The server MUST implement at least 2 priority levels for file messages, where priorities 0-4
+ and 5-9 are treated as two distinct levels. The server MAY implement up to 10 priority
+ levels.
+ </doc>
+ </rule>
+
+ <rule name="acknowledgement-support">
+ <doc>
+ The server MUST support both automatic and explicit acknowledgements on file content.
+ </doc>
+ </rule>
+
+ <role name="server" implement="MAY" />
+ <role name="client" implement="MAY" />
+
+ <!-- These are the properties for a File content -->
+ <struct name="file-properties" size="4" code="0x1" pack="2">
+ <field name="content-type" type="str8" label="MIME content type" />
+ <field name="content-encoding" type="str8" label="MIME content encoding" />
+ <field name="headers" type="map" label="message header field table" />
+ <field name="priority" type="uint8" label="message priority, 0 to 9" />
+ <field name="reply-to" type="str8" label="destination to reply to" />
+ <field name="message-id" type="str8" label="application message identifier" />
+ <field name="filename" type="str8" label="message filename" />
+ <field name="timestamp" type="datetime" label="message timestamp" />
+ <!-- This field is deprecated pending review -->
+ <field name="cluster-id" type="str8" label="intra-cluster routing identifier" />
+ </struct>
+
+ <domain name="return-code" type="uint16" label="return code from server">
+ <doc>
+ The return code. The AMQP return codes are defined by this enum.
+ </doc>
+ <enum>
+ <choice name="content-too-large" value="311">
+ <doc>
+ The client attempted to transfer content larger than the server could accept.
+ </doc>
+ </choice>
+
+ <choice name="no-route" value="312">
+ <doc>
+ The exchange cannot route a message, most likely due to an invalid routing key. Only
+ when the mandatory flag is set.
+ </doc>
+ </choice>
+
+ <choice name="no-consumers" value="313">
+ <doc>
+ The exchange cannot deliver to a consumer when the immediate flag is set. As a result of
+ pending data on the queue or the absence of any consumers of the queue.
+ </doc>
+ </choice>
+ </enum>
+ </domain>
+
+ <!-- - Command: file.qos - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+ <command name="qos" code="0x1" label="specify quality of service">
+ <doc>
+ This command requests a specific quality of service. The QoS can be specified for the
+ current session or for all sessions on the connection. The particular properties and
+ semantics of a qos command always depend on the content class semantics. Though the qos
+ command could in principle apply to both peers, it is currently meaningful only for the
+ server.
+ </doc>
+
+ <implement role="server" handle="MUST" />
+
+ <response name="qos-ok" />
+
+ <field name="prefetch-size" type="uint32" label="pre-fetch window in octets">
+ <doc>
+ The client can request that messages be sent in advance so that when the client finishes
+ processing a message, the following message is already held locally, rather than needing
+ to be sent within the session. Pre-fetching gives a performance improvement. This field
+ specifies the pre-fetch window size in octets. May be set to zero, meaning "no specific
+ limit". Note that other pre-fetch limits may still apply. The prefetch-size is ignored if
+ the no-ack option is set.
+ </doc>
+ </field>
+
+ <field name="prefetch-count" type="uint16" label="pre-fetch window in messages">
+ <doc>
+ Specifies a pre-fetch window in terms of whole messages. This is compatible with some file
+ API implementations. This field may be used in combination with the prefetch-size field; a
+ message will only be sent in advance if both pre-fetch windows (and those at the session
+ and connection level) allow it. The prefetch-count is ignored if the no-ack option is set.
+ </doc>
+
+ <rule name="prefetch-discretion">
+ <doc>
+ The server MAY send less data in advance than allowed by the client's specified
+ pre-fetch windows but it MUST NOT send more.
+ </doc>
+ </rule>
+ </field>
+
+ <field name="global" type="bit" label="apply to entire connection">
+ <doc>
+ By default the QoS settings apply to the current session only. If this field is set, they
+ are applied to the entire connection.
+ </doc>
+ </field>
+ </command>
+
+ <!-- - Command: file.qos-ok - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+ <command name="qos-ok" code="0x2" label="confirm the requested qos">
+ <doc>
+ This command tells the client that the requested QoS levels could be handled by the server.
+ The requested QoS applies to all active consumers until a new QoS is defined.
+ </doc>
+
+ <implement role="client" handle="MUST" />
+ </command>
+
+ <!-- - Command: file.consume - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+ <command name="consume" code="0x3" label="start a queue consumer">
+ <doc>
+ This command asks the server to start a "consumer", which is a transient request for
+ messages from a specific queue. Consumers last as long as the session they were created on,
+ or until the client cancels them.
+ </doc>
+
+ <rule name="min-consumers">
+ <doc>
+ The server SHOULD support at least 16 consumers per queue, unless the queue was declared
+ as private, and ideally, impose no limit except as defined by available resources.
+ </doc>
+ </rule>
+
+ <implement role="server" handle="MUST" />
+
+ <response name="consume-ok" />
+
+ <field name="queue" type="queue.name">
+ <doc>
+ Specifies the name of the queue to consume from.
+ </doc>
+
+ <exception name="queue-exists-if-empty" error-code="not-allowed">
+ <doc>
+ If the queue name in this command is empty, the server MUST raise an exception.
+ </doc>
+ </exception>
+ </field>
+
+ <field name="consumer-tag" type="str8">
+ <doc>
+ Specifies the identifier for the consumer. The consumer tag is local to a connection, so
+ two clients can use the same consumer tags.
+ </doc>
+
+ <exception name="not-existing-consumer" error-code="not-allowed">
+ <doc>
+ The tag MUST NOT refer to an existing consumer. If the client attempts to create two
+ consumers with the same non-empty tag the server MUST raise an exception.
+ </doc>
+ </exception>
+
+ <exception name="not-empty-consumer-tag" error-code="not-allowed">
+ <doc>
+ The client MUST NOT specify a tag that is empty or blank.
+ </doc>
+ <doc type="scenario">
+ Attempt to create a consumers with an empty tag.
+ </doc>
+ </exception>
+ </field>
+
+ <field name="no-local" type="bit">
+ <doc>If the no-local field is set the server will not send messages to the connection that
+ published them.</doc>
+ </field>
+
+ <field name="no-ack" type="bit" label="no acknowledgement needed">
+ <doc>
+ If this field is set the server does not expect acknowledgements for messages. That is,
+ when a message is delivered to the client the server automatically and silently
+ acknowledges it on behalf of the client. This functionality increases performance but at
+ the cost of reliability. Messages can get lost if a client dies before it can deliver them
+ to the application.
+ </doc>
+ </field>
+
+ <field name="exclusive" type="bit" label="request exclusive access">
+ <doc>
+ Request exclusive consumer access, meaning only this consumer can access the queue.
+ </doc>
+
+ <exception name="in-use" error-code="resource-locked">
+ <doc>
+ If the server cannot grant exclusive access to the queue when asked, - because there are
+ other consumers active - it MUST raise an exception.
+ </doc>
+ </exception>
+ </field>
+
+ <field name="nowait" type="bit" label="do not send a reply command">
+ <doc>
+ If set, the server will not respond to the command. The client should not wait for a reply
+ command. If the server could not complete the command it will raise an exception.
+ </doc>
+ </field>
+
+ <field name="arguments" type="map" label="arguments for consuming">
+ <doc>
+ A set of arguments for the consume. The syntax and semantics of these arguments depends on
+ the providers implementation.
+ </doc>
+ </field>
+ </command>
+
+ <command name="consume-ok" code="0x4" label="confirm a new consumer">
+ <doc>
+ This command provides the client with a consumer tag which it MUST use in commands that work
+ with the consumer.
+ </doc>
+
+ <implement role="client" handle="MUST" />
+
+ <field name="consumer-tag" type="str8">
+ <doc>
+ Holds the consumer tag specified by the client or provided by the server.
+ </doc>
+ </field>
+ </command>
+
+ <!-- - Command: file.cancel - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+ <command name="cancel" code="0x5" label="end a queue consumer">
+ <doc>
+ This command cancels a consumer. This does not affect already delivered messages, but it
+ does mean the server will not send any more messages for that consumer.
+ </doc>
+
+ <implement role="server" handle="MUST" />
+
+ <field name="consumer-tag" type="str8">
+ <doc>
+ the identifier of the consumer to be cancelled.
+ </doc>
+ </field>
+ </command>
+
+ <!-- - Command: file.open - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+ <command name="open" code="0x6" label="request to start staging">
+ <doc>
+ This command requests permission to start staging a message. Staging means sending the
+ message into a temporary area at the recipient end and then delivering the message by
+ referring to this temporary area. Staging is how the protocol handles partial file transfers
+ - if a message is partially staged and the connection breaks, the next time the sender
+ starts to stage it, it can restart from where it left off.
+ </doc>
+
+ <implement role="server" handle="MUST" />
+ <implement role="client" handle="MUST" />
+
+ <response name="open-ok" />
+
+ <field name="identifier" type="str8" label="staging identifier">
+ <doc>
+ This is the staging identifier. This is an arbitrary string chosen by the sender. For
+ staging to work correctly the sender must use the same staging identifier when staging the
+ same message a second time after recovery from a failure. A good choice for the staging
+ identifier would be the SHA1 hash of the message properties data (including the original
+ filename, revised time, etc.).
+ </doc>
+ </field>
+
+ <field name="content-size" type="uint64" label="message content size">
+ <doc>
+ The size of the content in octets. The recipient may use this information to allocate or
+ check available space in advance, to avoid "disk full" errors during staging of very large
+ messages.
+ </doc>
+
+ <rule name="content-size">
+ <doc>
+ The sender MUST accurately fill the content-size field. Zero-length content is
+ permitted.
+ </doc>
+ </rule>
+ </field>
+ </command>
+
+ <!-- - Command: file.open-ok - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+ <command name="open-ok" code="0x7" label="confirm staging ready">
+ <doc>
+ This command confirms that the recipient is ready to accept staged data. If the message was
+ already partially-staged at a previous time the recipient will report the number of octets
+ already staged.
+ </doc>
+
+ <implement role="server" handle="MUST" />
+ <implement role="client" handle="MUST" />
+
+ <response name="stage" />
+
+ <field name="staged-size" type="uint64" label="already staged amount">
+ <doc>
+ The amount of previously-staged content in octets. For a new message this will be zero.
+ </doc>
+
+ <rule name="behavior">
+ <doc>
+ The sender MUST start sending data from this octet offset in the message, counting from
+ zero.
+ </doc>
+ </rule>
+
+ <rule name="staging">
+ <doc>
+ The recipient MAY decide how long to hold partially-staged content and MAY implement
+ staging by always discarding partially-staged content. However if it uses the file
+ content type it MUST support the staging commands.
+ </doc>
+ </rule>
+ </field>
+ </command>
+
+ <!-- - Command: file.stage - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+ <command name="stage" code="0x8" label="stage message content">
+ <doc>
+ This command stages the message, sending the message content to the recipient from the octet
+ offset specified in the Open-Ok command.
+ </doc>
+
+ <implement role="server" handle="MUST" />
+ <implement role="client" handle="MUST" />
+
+ <segments>
+ <header required="true">
+ <entry type="file-properties"/>
+ </header>
+ <body/>
+ </segments>
+ </command>
+
+ <!-- - Command: file.publish - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+ <command name="publish" code="0x9" label="publish a message">
+ <doc>
+ This command publishes a staged file message to a specific exchange. The file message will
+ be routed to queues as defined by the exchange configuration and distributed to any active
+ consumers when the transaction, if any, is committed.
+ </doc>
+
+ <implement role="server" handle="MUST" />
+
+ <field name="exchange" type="exchange.name">
+ <doc>
+ Specifies the name of the exchange to publish to. The exchange name can be empty, meaning
+ the default exchange. If the exchange name is specified, and that exchange does not exist,
+ the server will raise an exception.
+ </doc>
+
+ <rule name="default">
+ <doc>
+ The server MUST accept a blank exchange name to mean the default exchange.
+ </doc>
+ </rule>
+
+ <exception name="refusal" error-code="not-implemented">
+ <doc>
+ The exchange MAY refuse file content in which case it MUST send an exception.
+ </doc>
+ </exception>
+ </field>
+
+ <field name="routing-key" type="str8" label="Message routing key">
+ <doc>
+ Specifies the routing key for the message. The routing key is used for routing messages
+ depending on the exchange configuration.
+ </doc>
+ </field>
+
+ <field name="mandatory" type="bit" label="indicate mandatory routing">
+ <doc>
+ This flag tells the server how to react if the message cannot be routed to a queue. If
+ this flag is set, the server will return an unroutable message with a Return command. If
+ this flag is zero, the server silently drops the message.
+ </doc>
+
+ <rule name="implementation">
+ <doc>
+ The server SHOULD implement the mandatory flag.
+ </doc>
+ </rule>
+ </field>
+
+ <field name="immediate" type="bit" label="request immediate delivery">
+ <doc>
+ This flag tells the server how to react if the message cannot be routed to a queue
+ consumer immediately. If this flag is set, the server will return an undeliverable message
+ with a Return command. If this flag is zero, the server will queue the message, but with
+ no guarantee that it will ever be consumed.
+ </doc>
+
+ <rule name="implementation">
+ <doc>
+ The server SHOULD implement the immediate flag.
+ </doc>
+ </rule>
+ </field>
+
+ <field name="identifier" type="str8" label="staging identifier">
+ <doc>
+ This is the staging identifier of the message to publish. The message must have been
+ staged. Note that a client can send the Publish command asynchronously without waiting for
+ staging to finish.
+ </doc>
+ </field>
+ </command>
+
+ <!-- - Command: file.return - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+ <command name="return" code="0xa" label="return a failed message">
+ <doc>
+ This command returns an undeliverable message that was published with the "immediate" flag
+ set, or an unroutable message published with the "mandatory" flag set. The reply code and
+ text provide information about the reason that the message was undeliverable.
+ </doc>
+
+ <implement role="client" handle="MUST" />
+
+ <field name="reply-code" type="return-code" />
+
+ <field name="reply-text" type="str8" label="The localized reply text.">
+ <doc>
+ This text can be logged as an aid to resolving issues.
+ </doc>
+ </field>
+
+ <field name="exchange" type="exchange.name">
+ <doc>
+ Specifies the name of the exchange that the message was originally published to.
+ </doc>
+ </field>
+
+ <field name="routing-key" type="str8" label="Message routing key">
+ <doc>
+ Specifies the routing key name specified when the message was published.
+ </doc>
+ </field>
+
+ <segments>
+ <header required="true">
+ <entry type="file-properties"/>
+ </header>
+ <body/>
+ </segments>
+ </command>
+
+ <!-- - Command: file.deliver - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+ <command name="deliver" code="0xb" label="notify the client of a consumer message">
+ <doc>
+ This command delivers a staged file message to the client, via a consumer. In the
+ asynchronous message delivery model, the client starts a consumer using the consume command,
+ then the server responds with Deliver commands as and when messages arrive for that
+ consumer.
+ </doc>
+
+ <rule name="redelivery-tracking">
+ <doc>
+ The server SHOULD track the number of times a message has been delivered to clients and
+ when a message is redelivered a certain number of times - e.g. 5 times - without being
+ acknowledged, the server SHOULD consider the message to be non-processable (possibly
+ causing client applications to abort), and move the message to a dead letter queue.
+ </doc>
+ </rule>
+
+ <implement role="client" handle="MUST" />
+
+ <field name="consumer-tag" type="str8" />
+
+ <field name="delivery-tag" type="uint64" >
+ <doc>
+ The server-assigned and session-specific delivery tag
+ </doc>
+
+ <rule name="non-zero">
+ <doc>
+ The server MUST NOT use a zero value for delivery tags. Zero is reserved for client use,
+ meaning "all messages so far received".
+ </doc>
+ </rule>
+ </field>
+
+ <field name="redelivered" type="bit" label="Indicate possible duplicate delivery">
+ <doc>
+ This boolean flag indicates that the message may have been previously delivered to this
+ or another client.
+ </doc>
+ </field>
+
+ <field name="exchange" type="exchange.name">
+ <doc>
+ Specifies the name of the exchange that the message was originally published to.
+ </doc>
+ </field>
+
+ <field name="routing-key" type="str8" label="Message routing key">
+ <doc>
+ Specifies the routing key name specified when the message was published.
+ </doc>
+ </field>
+
+ <field name="identifier" type="str8" label="staging identifier">
+ <doc>
+ This is the staging identifier of the message to deliver. The message must have been
+ staged. Note that a server can send the Deliver command asynchronously without waiting for
+ staging to finish.
+ </doc>
+ </field>
+ </command>
+
+ <!-- - Command: file.ack - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+ <command name="ack" code="0xc" label="acknowledge one or more messages">
+ <doc>
+ This command acknowledges one or more messages delivered via the Deliver command. The client
+ can ask to confirm a single message or a set of messages up to and including a specific
+ message.
+ </doc>
+
+ <implement role="server" handle="MUST" />
+
+ <field name="delivery-tag" type="uint64" >
+ <doc>
+ The identifier of the message being acknowledged
+ </doc>
+ <rule name="session-local">
+ <doc>
+ The delivery tag is valid only within the session from which the message was received.
+ i.e. A client MUST NOT receive a message on one session and then acknowledge it on
+ another.
+ </doc>
+ </rule>
+ </field>
+
+ <field name="multiple" type="bit" label="acknowledge multiple messages">
+ <doc>
+ If set to 1, the delivery tag is treated as "up to and including", so that the client can
+ acknowledge multiple messages with a single command. If set to zero, the delivery tag
+ refers to a single message. If the multiple field is 1, and the delivery tag is zero,
+ tells the server to acknowledge all outstanding messages.
+ </doc>
+
+ <rule name="validation">
+ <doc>
+ The server MUST validate that a non-zero delivery-tag refers to an delivered message,
+ and raise an exception if this is not the case.
+ </doc>
+ </rule>
+ </field>
+ </command>
+
+ <!-- - Command: file.reject - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+ <command name="reject" code="0xd" label="reject an incoming message">
+ <doc>
+ This command allows a client to reject a message. It can be used to return untreatable
+ messages to their original queue. Note that file content is staged before delivery, so the
+ client will not use this command to interrupt delivery of a large message.
+ </doc>
+
+ <rule name="server-interpretation">
+ <doc>
+ The server SHOULD interpret this command as meaning that the client is unable to process
+ the message at this time.
+ </doc>
+ </rule>
+
+ <rule name="not-selection">
+ <doc>
+ A client MUST NOT use this command as a means of selecting messages to process. A rejected
+ message MAY be discarded or dead-lettered, not necessarily passed to another client.
+ </doc>
+ </rule>
+
+ <implement role="server" handle="MUST" />
+
+ <field name="delivery-tag" type="uint64">
+ <doc>
+ the identifier of the message to be rejected
+ </doc>
+ <rule name="session-local">
+ <doc>
+ The delivery tag is valid only within the session from which the message was received.
+ i.e. A client MUST NOT receive a message on one session and then reject it on another.
+ </doc>
+ </rule>
+ </field>
+
+ <field name="requeue" type="bit" label="requeue the message">
+ <doc>
+ If this field is zero, the message will be discarded. If this bit is 1, the server will
+ attempt to requeue the message.
+ </doc>
+
+ <rule name="requeue-strategy">
+ <doc>
+ The server MUST NOT deliver the message to the same client within the context of the
+ current session. The recommended strategy is to attempt to deliver the message to an
+ alternative consumer, and if that is not possible, to move the message to a dead-letter
+ queue. The server MAY use more sophisticated tracking to hold the message on the queue
+ and redeliver it to the same client at a later stage.
+ </doc>
+ </rule>
+ </field>
+ </command>
+
+ </class>
+
+ <!-- == Class: stream ======================================================================== -->
+
+ <class name="stream" code="0xa" label="work with streaming content">
+ <doc>
+ The stream class provides commands that support multimedia streaming. The stream class uses
+ the following semantics: one message is one packet of data; delivery is unacknowledged and
+ unreliable; the consumer can specify quality of service parameters that the server can try to
+ adhere to; lower-priority messages may be discarded in favor of high priority messages.
+ </doc>
+
+ <doc type="grammar">
+ stream = C:QOS S:QOS-OK
+ / C:CONSUME S:CONSUME-OK
+ / C:CANCEL
+ / C:PUBLISH content
+ / S:RETURN
+ / S:DELIVER content
+ </doc>
+
+ <rule name="overflow-discard">
+ <doc>
+ The server SHOULD discard stream messages on a priority basis if the queue size exceeds some
+ configured limit.
+ </doc>
+ </rule>
+
+ <rule name="priority-levels">
+ <doc>
+ The server MUST implement at least 2 priority levels for stream messages, where priorities
+ 0-4 and 5-9 are treated as two distinct levels. The server MAY implement up to 10 priority
+ levels.
+ </doc>
+ </rule>
+
+ <rule name="acknowledgement-support">
+ <doc>
+ The server MUST implement automatic acknowledgements on stream content. That is, as soon as
+ a message is delivered to a client via a Deliver command, the server must remove it from the
+ queue.
+ </doc>
+ </rule>
+
+ <role name="server" implement="MAY" />
+ <role name="client" implement="MAY" />
+
+ <!-- These are the properties for a Stream content -->
+ <struct name="stream-properties" size="4" code="0x1" pack="2">
+ <field name="content-type" type="str8" label="MIME content type" />
+ <field name="content-encoding" type="str8" label="MIME content encoding" />
+ <field name="headers" type="map" label="message header field table" />
+ <field name="priority" type="uint8" label="message priority, 0 to 9" />
+ <field name="timestamp" type="datetime" label="message timestamp" />
+ </struct>
+
+ <domain name="return-code" type="uint16" label="return code from server">
+ <doc>
+ The return code. The AMQP return codes are defined by this enum.
+ </doc>
+ <enum>
+ <choice name="content-too-large" value="311">
+ <doc>
+ The client attempted to transfer content larger than the server could accept.
+ </doc>
+ </choice>
+
+ <choice name="no-route" value="312">
+ <doc>
+ The exchange cannot route a message, most likely due to an invalid routing key. Only
+ when the mandatory flag is set.
+ </doc>
+ </choice>
+
+ <choice name="no-consumers" value="313">
+ <doc>
+ The exchange cannot deliver to a consumer when the immediate flag is set. As a result of
+ pending data on the queue or the absence of any consumers of the queue.
+ </doc>
+ </choice>
+ </enum>
+ </domain>
+
+ <!-- - Command: stream.qos - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+ <command name="qos" code="0x1" label="specify quality of service">
+ <doc>
+ This command requests a specific quality of service. The QoS can be specified for the
+ current session or for all sessions on the connection. The particular properties and
+ semantics of a qos command always depend on the content class semantics. Though the qos
+ command could in principle apply to both peers, it is currently meaningful only for the
+ server.
+ </doc>
+
+ <implement role="server" handle="MUST" />
+
+ <response name="qos-ok" />
+
+ <field name="prefetch-size" type="uint32" label="pre-fetch window in octets">
+ <doc>
+ The client can request that messages be sent in advance so that when the client finishes
+ processing a message, the following message is already held locally, rather than needing
+ to be sent within the session. Pre-fetching gives a performance improvement. This field
+ specifies the pre-fetch window size in octets. May be set to zero, meaning "no specific
+ limit". Note that other pre-fetch limits may still apply.
+ </doc>
+ </field>
+
+ <field name="prefetch-count" type="uint16" label="pre-fetch window in messages">
+ <doc>
+ Specifies a pre-fetch window in terms of whole messages. This field may be used in
+ combination with the prefetch-size field; a message will only be sent in advance if both
+ pre-fetch windows (and those at the session and connection level) allow it.
+ </doc>
+ </field>
+
+ <field name="consume-rate" type="uint32" label="transfer rate in octets/second">
+ <doc>
+ Specifies a desired transfer rate in octets per second. This is usually determined by the
+ application that uses the streaming data. A value of zero means "no limit", i.e. as
+ rapidly as possible.
+ </doc>
+
+ <rule name="ignore-prefetch">
+ <doc>
+ The server MAY ignore the pre-fetch values and consume rates, depending on the type of
+ stream and the ability of the server to queue and/or reply it.
+ </doc>
+ </rule>
+
+ <rule name="drop-by-priority">
+ <doc>
+ The server MAY drop low-priority messages in favor of high-priority messages.
+ </doc>
+ </rule>
+ </field>
+
+ <field name="global" type="bit" label="apply to entire connection">
+ <doc>
+ By default the QoS settings apply to the current session only. If this field is set, they
+ are applied to the entire connection.
+ </doc>
+ </field>
+ </command>
+
+ <!-- - Command: stream.qos-ok - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+ <command name="qos-ok" code="0x2" label="confirm the requested qos">
+ <doc>
+ This command tells the client that the requested QoS levels could be handled by the server.
+ The requested QoS applies to all active consumers until a new QoS is defined.
+ </doc>
+
+ <implement role="client" handle="MUST" />
+ </command>
+
+ <!-- - Command: stream.consume - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+ <command name="consume" code="0x3" label="start a queue consumer">
+ <doc>
+ This command asks the server to start a "consumer", which is a transient request for
+ messages from a specific queue. Consumers last as long as the session they were created on,
+ or until the client cancels them.
+ </doc>
+
+ <rule name="min-consumers">
+ <doc>
+ The server SHOULD support at least 16 consumers per queue, unless the queue was declared
+ as private, and ideally, impose no limit except as defined by available resources.
+ </doc>
+ </rule>
+
+ <rule name="priority-based-delivery">
+ <doc>
+ Streaming applications SHOULD use different sessions to select different streaming
+ resolutions. AMQP makes no provision for filtering and/or transforming streams except on
+ the basis of priority-based selective delivery of individual messages.
+ </doc>
+ </rule>
+
+ <implement role="server" handle="MUST" />
+
+ <response name="consume-ok" />
+
+ <field name="queue" type="queue.name">
+ <doc>
+ Specifies the name of the queue to consume from.
+ </doc>
+
+ <exception name="queue-exists-if-empty" error-code="not-allowed">
+ <doc>
+ If the queue name in this command is empty, the server MUST raise an exception.
+ </doc>
+ </exception>
+ </field>
+
+ <field name="consumer-tag" type="str8">
+ <doc>
+ Specifies the identifier for the consumer. The consumer tag is local to a connection, so
+ two clients can use the same consumer tags.
+ </doc>
+
+ <exception name="not-existing-consumer" error-code="not-allowed">
+ <doc>
+ The tag MUST NOT refer to an existing consumer. If the client attempts to create two
+ consumers with the same non-empty tag the server MUST raise an exception.
+ </doc>
+ </exception>
+
+ <exception name="not-empty-consumer-tag" error-code="not-allowed">
+ <doc>
+ The client MUST NOT specify a tag that is empty or blank.
+ </doc>
+ <doc type="scenario">
+ Attempt to create a consumers with an empty tag.
+ </doc>
+ </exception>
+ </field>
+
+ <field name="no-local" type="bit">
+ <doc>If the no-local field is set the server will not send messages to the connection that
+ published them.</doc>
+ </field>
+
+ <field name="exclusive" type="bit" label="request exclusive access">
+ <doc>
+ Request exclusive consumer access, meaning only this consumer can access the queue.
+ </doc>
+
+ <exception name="in-use" error-code="resource-locked">
+ <doc>
+ If the server cannot grant exclusive access to the queue when asked, - because there are
+ other consumers active - it MUST raise an exception with return code 405
+ (resource locked).
+ </doc>
+ </exception>
+ </field>
+
+ <field name="nowait" type="bit" label="do not send a reply command">
+ <doc>
+ If set, the server will not respond to the command. The client should not wait for a reply
+ command. If the server could not complete the command it will raise an exception.
+ </doc>
+ </field>
+
+ <field name="arguments" type="map" label="arguments for consuming">
+ <doc>
+ A set of arguments for the consume. The syntax and semantics of these arguments depends on
+ the providers implementation.
+ </doc>
+ </field>
+ </command>
+
+ <!-- - Command: stream.consume-ok - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+ <command name="consume-ok" code="0x4" label="confirm a new consumer">
+ <doc>
+ This command provides the client with a consumer tag which it may use in commands that work
+ with the consumer.
+ </doc>
+
+ <implement role="client" handle="MUST" />
+
+ <field name="consumer-tag" type="str8">
+ <doc>
+ Holds the consumer tag specified by the client or provided by the server.
+ </doc>
+ </field>
+ </command>
+
+ <!-- - Command: stream.cancel - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+ <command name="cancel" code="0x5" label="end a queue consumer">
+ <doc>
+ This command cancels a consumer. Since message delivery is asynchronous the client may
+ continue to receive messages for a short while after cancelling a consumer. It may process
+ or discard these as appropriate.
+ </doc>
+
+ <implement role="server" handle="MUST" />
+
+ <field name="consumer-tag" type="str8" />
+ </command>
+
+ <!-- - Command: stream.publish - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+ <command name="publish" code="0x6" label="publish a message">
+ <doc>
+ This command publishes a message to a specific exchange. The message will be routed to
+ queues as defined by the exchange configuration and distributed to any active consumers as
+ appropriate.
+ </doc>
+
+ <implement role="server" handle="MUST" />
+
+ <field name="exchange" type="exchange.name">
+ <doc>
+ Specifies the name of the exchange to publish to. The exchange name can be empty, meaning
+ the default exchange. If the exchange name is specified, and that exchange does not exist,
+ the server will raise an exception.
+ </doc>
+
+ <rule name="default">
+ <doc>
+ The server MUST accept a blank exchange name to mean the default exchange.
+ </doc>
+ </rule>
+
+ <exception name="refusal" error-code="not-implemented">
+ <doc>
+ The exchange MAY refuse stream content in which case it MUST respond with an exception.
+ </doc>
+ </exception>
+ </field>
+
+ <field name="routing-key" type="str8" label="Message routing key">
+ <doc>
+ Specifies the routing key for the message. The routing key is used for routing messages
+ depending on the exchange configuration.
+ </doc>
+ </field>
+
+ <field name="mandatory" type="bit" label="indicate mandatory routing">
+ <doc>
+ This flag tells the server how to react if the message cannot be routed to a queue. If
+ this flag is set, the server will return an unroutable message with a Return command. If
+ this flag is zero, the server silently drops the message.
+ </doc>
+
+ <rule name="implementation">
+ <doc>
+ The server SHOULD implement the mandatory flag.
+ </doc>
+ </rule>
+ </field>
+
+ <field name="immediate" type="bit" label="request immediate delivery">
+ <doc>
+ This flag tells the server how to react if the message cannot be routed to a queue
+ consumer immediately. If this flag is set, the server will return an undeliverable message
+ with a Return command. If this flag is zero, the server will queue the message, but with
+ no guarantee that it will ever be consumed.
+ </doc>
+
+ <rule name="implementation">
+ <doc>
+ The server SHOULD implement the immediate flag.
+ </doc>
+ </rule>
+ </field>
+
+ <segments>
+ <header required="true">
+ <entry type="stream-properties"/>
+ </header>
+ <body/>
+ </segments>
+ </command>
+
+ <!-- - Command: stream.return - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+ <command name="return" code="0x7" label="return a failed message">
+ <doc>
+ This command returns an undeliverable message that was published with the "immediate" flag
+ set, or an unroutable message published with the "mandatory" flag set. The reply code and
+ text provide information about the reason that the message was undeliverable.
+ </doc>
+
+ <implement role="client" handle="MUST" />
+
+ <field name="reply-code" type="return-code" />
+
+ <field name="reply-text" type="str8" label="The localized reply text.">
+ <doc>
+ The localized reply text. This text can be logged as an aid to resolving issues.
+ </doc>
+ </field>
+
+ <field name="exchange" type="exchange.name">
+ <doc>
+ Specifies the name of the exchange that the message was originally published to.
+ </doc>
+ </field>
+
+ <field name="routing-key" type="str8" label="Message routing key">
+ <doc>
+ Specifies the routing key name specified when the message was published.
+ </doc>
+ </field>
+
+ <segments>
+ <header required="true">
+ <entry type="stream-properties"/>
+ </header>
+ <body/>
+ </segments>
+ </command>
+
+ <!-- - Command: stream.deliver - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+ <command name="deliver" code="0x8" label="notify the client of a consumer message">
+ <doc>
+ This command delivers a message to the client, via a consumer. In the asynchronous message
+ delivery model, the client starts a consumer using the Consume command, then the server
+ responds with Deliver commands as and when messages arrive for that consumer.
+ </doc>
+
+ <implement role="client" handle="MUST" />
+
+ <field name="consumer-tag" type="str8" />
+
+ <field name="delivery-tag" type="uint64">
+ <doc>
+ The server-assigned and session-specific delivery tag
+ </doc>
+ <rule name="session-local">
+ <doc>
+ The delivery tag is valid only within the session from which the message was received.
+ i.e. A client MUST NOT receive a message on one session and then acknowledge it on
+ another.
+ </doc>
+ </rule>
+ </field>
+
+ <field name="exchange" type="exchange.name">
+ <doc>
+ Specifies the name of the exchange that the message was originally published to.
+ </doc>
+ </field>
+
+ <field name="queue" type="queue.name" required="true">
+ <doc>
+ Specifies the name of the queue that the message came from. Note that a single session can
+ start many consumers on different queues.
+ </doc>
+ </field>
+
+ <segments>
+ <header required="true">
+ <entry type="stream-properties"/>
+ </header>
+ <body/>
+ </segments>
+ </command>
+
+ </class>
+
+</amqp>
diff --git a/qpid/ruby/lib/qpid/specs/amqp.0-10.dtd b/qpid/ruby/lib/qpid/specs/amqp.0-10.dtd
new file mode 100644
index 0000000000..2be198525a
--- /dev/null
+++ b/qpid/ruby/lib/qpid/specs/amqp.0-10.dtd
@@ -0,0 +1,246 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+ Copyright Notice
+ ================
+ (c) Copyright Cisco Systems, Credit Suisse, Deutsche Börse Systems, Envoy Technologies, Inc.,
+ Goldman Sachs, IONA Technologies PLC, iMatix Corporation sprl.,JPMorgan Chase Bank Inc. N.A,
+ Novell, Rabbit Technologies Ltd., Red Hat, Inc., TWIST Process Innovations ltd, and 29West Inc
+ 2006, 2007. All rights reserved.
+
+ License
+ =======
+ JPMorgan Chase Bank & Co., Cisco Systems, Inc., Envoy Technologies Inc., iMatix Corporation, IONA
+ Technologies, Red Hat, Inc., TWIST Process Innovations, and 29West Inc. (collectively, the
+ "Authors") each hereby grants to you a worldwide, perpetual, royalty-free, nontransferable,
+ nonexclusive license to (i) copy, display, distribute and implement the Advanced Messaging Queue
+ Protocol ("AMQP") Specification and (ii) the Licensed Claims that are held by the Authors, all for
+ the purpose of implementing the Advanced Messaging Queue Protocol Specification. Your license and
+ any rights under this Agreement will terminate immediately without notice from any Author if you
+ bring any claim, suit, demand, or action related to the Advanced Messaging Queue Protocol
+ Specification against any Author. Upon termination, you shall destroy all copies of the Advanced
+ Messaging Queue Protocol Specification in your possession or control.
+
+ As used hereunder, "Licensed Claims" means those claims of a patent or patent application,
+ throughout the world, excluding design patents and design registrations, owned or controlled, or
+ that can be sublicensed without fee and in compliance with the requirements of this Agreement, by
+ an Author or its affiliates now or at any future time and which would necessarily be infringed by
+ implementation of the Advanced Messaging Queue Protocol Specification. A claim is necessarily
+ infringed hereunder only when it is not possible to avoid infringing it because there is no
+ plausible non-infringing alternative for implementing the required portions of the Advanced
+ Messaging Queue Protocol Specification. Notwithstanding the foregoing, Licensed Claims shall not
+ include any claims other than as set forth above even if contained in the same patent as Licensed
+ Claims; or that read solely on any implementations of any portion of the Advanced Messaging Queue
+ Protocol Specification that are not required by the Advanced Messaging Queue Protocol
+ Specification, or that, if licensed, would require a payment of royalties by the licensor to
+ unaffiliated third parties. Moreover, Licensed Claims shall not include (i) any enabling
+ technologies that may be necessary to make or use any Licensed Product but are not themselves
+ expressly set forth in the Advanced Messaging Queue Protocol Specification (e.g., semiconductor
+ manufacturing technology, compiler technology, object oriented technology, networking technology,
+ operating system technology, and the like); or (ii) the implementation of other published
+ standards developed elsewhere and merely referred to in the body of the Advanced Messaging Queue
+ Protocol Specification, or (iii) any Licensed Product and any combinations thereof the purpose or
+ function of which is not required for compliance with the Advanced Messaging Queue Protocol
+ Specification. For purposes of this definition, the Advanced Messaging Queue Protocol
+ Specification shall be deemed to include both architectural and interconnection requirements
+ essential for interoperability and may also include supporting source code artifacts where such
+ architectural, interconnection requirements and source code artifacts are expressly identified as
+ being required or documentation to achieve compliance with the Advanced Messaging Queue Protocol
+ Specification.
+
+ As used hereunder, "Licensed Products" means only those specific portions of products (hardware,
+ software or combinations thereof) that implement and are compliant with all relevant portions of
+ the Advanced Messaging Queue Protocol Specification.
+
+ The following disclaimers, which you hereby also acknowledge as to any use you may make of the
+ Advanced Messaging Queue Protocol Specification:
+
+ THE ADVANCED MESSAGING QUEUE PROTOCOL SPECIFICATION IS PROVIDED "AS IS," AND THE AUTHORS MAKE NO
+ REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, OR TITLE; THAT THE CONTENTS
+ OF THE ADVANCED MESSAGING QUEUE PROTOCOL SPECIFICATION ARE SUITABLE FOR ANY PURPOSE; NOR THAT THE
+ IMPLEMENTATION OF THE ADVANCED MESSAGING QUEUE PROTOCOL SPECIFICATION WILL NOT INFRINGE ANY THIRD
+ PARTY PATENTS, COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS.
+
+ THE AUTHORS WILL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL
+ DAMAGES ARISING OUT OF OR RELATING TO ANY USE, IMPLEMENTATION OR OF THE ADVANCED
+ MESSAGING QUEUE PROTOCOL SPECIFICATION.
+
+ The name and trademarks of the Authors may NOT be used in any manner, including advertising or
+ publicity pertaining to the Advanced Messaging Queue Protocol Specification or its contents
+ without specific, written prior permission. Title to copyright in the Advanced Messaging Queue
+ Protocol Specification will at all times remain with the Authors.
+
+ No other rights are granted by implication, estoppel or otherwise.
+
+ Upon termination of your license or rights under this Agreement, you shall destroy all copies of
+ the Advanced Messaging Queue Protocol Specification in your possession or control.
+
+ Trademarks
+ ==========
+ "JPMorgan", "JPMorgan Chase", "Chase", the JPMorgan Chase logo and the Octagon Symbol are
+ trademarks of JPMorgan Chase & Co.
+
+ IMATIX and the iMatix logo are trademarks of iMatix Corporation sprl.
+
+ IONA, IONA Technologies, and the IONA logos are trademarks of IONA Technologies PLC and/or its
+ subsidiaries.
+
+ LINUX is a trademark of Linus Torvalds. RED HAT and JBOSS are registered trademarks of Red Hat,
+ Inc. in the US and other countries.
+
+ Java, all Java-based trademarks and OpenOffice.org are trademarks of Sun Microsystems, Inc. in the
+ United States, other countries, or both.
+
+ Other company, product, or service names may be trademarks or service marks of others.
+
+ Links to full AMQP specification:
+ =================================
+ http://www.envoytech.org/spec/amq/
+ http://www.iona.com/opensource/amqp/
+ http://www.redhat.com/solutions/specifications/amqp/
+ http://www.twiststandards.org/tiki-index.php?page=AMQ
+ http://www.imatix.com/amqp
+-->
+
+<!ELEMENT amqp (doc|type|struct|domain|constant|class)*>
+<!ATTLIST amqp
+ xmlns CDATA #IMPLIED
+ major CDATA #REQUIRED
+ minor CDATA #REQUIRED
+ port CDATA #REQUIRED
+ comment CDATA #IMPLIED
+>
+
+<!ELEMENT constant (doc|rule)*>
+<!ATTLIST constant
+ name CDATA #REQUIRED
+ value CDATA #REQUIRED
+ label CDATA #IMPLIED
+>
+
+<!ELEMENT type (doc|rule)*>
+<!ATTLIST type
+ name CDATA #REQUIRED
+ label CDATA #IMPLIED
+ code CDATA #IMPLIED
+ fixed-width CDATA #IMPLIED
+ variable-width CDATA #IMPLIED
+>
+
+<!ELEMENT domain (doc|rule|enum)*>
+<!ATTLIST domain
+ name CDATA #REQUIRED
+ type CDATA #IMPLIED
+ label CDATA #IMPLIED
+>
+
+<!ELEMENT struct (field|doc|rule)*>
+<!ATTLIST struct
+ name CDATA #REQUIRED
+ label CDATA #IMPLIED
+ size (0|1|2|4) #IMPLIED
+ pack (0|1|2|4) #IMPLIED
+ code CDATA #IMPLIED>
+
+<!ELEMENT enum (choice)*>
+
+<!ELEMENT choice (doc|rule)*>
+<!ATTLIST choice
+ name CDATA #REQUIRED
+ value CDATA #REQUIRED
+>
+
+<!ELEMENT class (doc|role|rule|struct|domain|control|command)*>
+<!ATTLIST class
+ name CDATA #REQUIRED
+ code CDATA #REQUIRED
+ label CDATA #IMPLIED
+>
+
+<!ELEMENT role (doc|rule)*>
+<!ATTLIST role
+ name CDATA #REQUIRED
+ implement (MAY|SHOULD|MUST) #REQUIRED
+>
+
+<!ELEMENT control (doc|implement|rule|field|response)*>
+<!ATTLIST control
+ name CDATA #REQUIRED
+ code CDATA #REQUIRED
+ label CDATA #IMPLIED
+>
+
+<!ELEMENT command ((doc|implement|rule|exception|field|response)*, result?, segments?)>
+<!ATTLIST command
+ name CDATA #REQUIRED
+ code CDATA #REQUIRED
+ label CDATA #IMPLIED
+>
+
+<!ELEMENT implement (doc|rule)*>
+<!ATTLIST implement
+ role CDATA #REQUIRED
+ handle (MAY|SHOULD|MUST) #REQUIRED
+ send (MAY|SHOULD|MUST) #IMPLIED
+>
+
+<!ELEMENT field (doc|rule|exception)*>
+<!ATTLIST field
+ name CDATA #REQUIRED
+ type CDATA #IMPLIED
+ default CDATA #IMPLIED
+ code CDATA #IMPLIED
+ label CDATA #IMPLIED
+ required CDATA #IMPLIED
+>
+
+<!ELEMENT rule (doc*)>
+<!ATTLIST rule
+ name CDATA #REQUIRED
+ label CDATA #IMPLIED
+>
+
+<!ELEMENT exception (doc*)>
+<!ATTLIST exception
+ name CDATA #REQUIRED
+ error-code CDATA #IMPLIED
+ label CDATA #IMPLIED
+>
+
+<!ELEMENT response (doc|rule)*>
+<!ATTLIST response
+ name CDATA #IMPLIED
+>
+
+<!ELEMENT result (doc|rule|struct)*>
+<!ATTLIST result
+ type CDATA #IMPLIED
+>
+
+<!ELEMENT segments (doc|rule|header|body)*>
+
+<!ELEMENT header (doc|rule|entry)*>
+<!ATTLIST header
+ required (true|false) #IMPLIED
+>
+
+<!ELEMENT entry (doc|rule)*>
+<!ATTLIST entry
+ type CDATA #REQUIRED
+>
+
+<!ELEMENT body (doc|rule)*>
+<!ATTLIST body
+ required (true|false) #IMPLIED
+>
+
+<!ELEMENT doc (#PCDATA|xref)*>
+<!ATTLIST doc
+ type (grammar|scenario|picture|bnf|todo) #IMPLIED
+ title CDATA #IMPLIED
+>
+
+<!ELEMENT xref (#PCDATA)>
+<!ATTLIST xref
+ ref CDATA #REQUIRED>
diff --git a/qpid/ruby/lib/qpid/test.rb b/qpid/ruby/lib/qpid/test.rb
new file mode 100644
index 0000000000..2e643f4348
--- /dev/null
+++ b/qpid/ruby/lib/qpid/test.rb
@@ -0,0 +1,35 @@
+# 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.
+#
+
+require "qpid/spec08"
+require "qpid/client"
+
+module Qpid08
+
+ module Test
+
+ def connect()
+ spec = Spec.load("../specs/amqp.0-8.xml")
+ c = Client.new("0.0.0.0", 5672, spec)
+ c.start({"LOGIN" => "guest", "PASSWORD" => "guest"})
+ return c
+ end
+
+ end
+
+end
diff --git a/qpid/ruby/lib/qpid/traverse.rb b/qpid/ruby/lib/qpid/traverse.rb
new file mode 100644
index 0000000000..67358a7eb1
--- /dev/null
+++ b/qpid/ruby/lib/qpid/traverse.rb
@@ -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.
+#
+
+class Object
+
+ public
+
+ def traverse()
+ traverse! {|o| yield(o); o}
+ end
+
+ def traverse_children!()
+ instance_variables.each {|v|
+ value = instance_variable_get(v)
+ replacement = yield(value)
+ instance_variable_set(v, replacement) unless replacement.equal? value
+ }
+ end
+
+ def traverse!(replacements = {})
+ return replacements[__id__] if replacements.has_key? __id__
+ replacement = yield(self)
+ replacements[__id__] = replacement
+ traverse_children! {|o| o.traverse!(replacements) {|c| yield(c)}}
+ return replacement
+ end
+
+end
+
+class Array
+ def traverse_children!()
+ map! {|o| yield(o)}
+ end
+end
+
+class Hash
+ def traverse_children!()
+ mods = {}
+ each_pair {|k, v|
+ key = yield(k)
+ value = yield(v)
+ mods[key] = value unless key.equal? k and value.equal? v
+ delete(k) unless key.equal? k
+ }
+
+ merge!(mods)
+ end
+end
diff --git a/qpid/ruby/lib/qpid/util.rb b/qpid/ruby/lib/qpid/util.rb
new file mode 100644
index 0000000000..2dbc37da09
--- /dev/null
+++ b/qpid/ruby/lib/qpid/util.rb
@@ -0,0 +1,75 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+require 'thread'
+require 'monitor'
+
+# Monkeypatch
+class MonitorMixin::ConditionVariable
+
+ # Wait until BLOCK returns TRUE or TIMEOUT seconds have passed
+ # Return TRUE if BLOCK returned TRUE within the TIMEOUT, FALSE
+ # otherswise
+ def wait_for(timeout=nil, &block)
+ start = Time.now
+ passed = 0
+ until yield
+ if timeout.nil?
+ wait
+ elsif passed < timeout
+ wait(timeout)
+ else
+ return false
+ end
+ passed = Time.now - start
+ end
+ return true
+ end
+end
+
+module Qpid::Util
+
+ # Similar to Python's threading.Event
+ class Event
+ def initialize
+ @monitor = Monitor.new
+ @cond = @monitor.new_cond
+ @set = false
+ end
+
+ def set
+ @monitor.synchronize do
+ @set = true
+ @cond.signal
+ end
+ end
+
+ def clear
+ @monitor.synchronize { @set = false }
+ end
+
+ def wait(timeout = nil)
+ @monitor.synchronize do
+ unless @set
+ @cond.wait_for(timeout) { @set }
+ end
+ end
+ end
+ end
+end
diff --git a/qpid/ruby/tests/assembler.rb b/qpid/ruby/tests/assembler.rb
new file mode 100644
index 0000000000..1181ece547
--- /dev/null
+++ b/qpid/ruby/tests/assembler.rb
@@ -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.
+#
+
+require "test/unit"
+require "qpid"
+require 'tests/util'
+
+require 'logger'
+
+class TestAssembler< Test::Unit::TestCase
+
+ Segment = Qpid::Segment
+ Assembler = Qpid::Assembler
+
+ def setup
+ # Qpid::asm_logger = Logger.new(STDOUT)
+
+ @server = Util::ServerThread.new do |socket|
+ asm = Assembler.new(socket)
+ begin
+ header = asm.read_header
+ asm.write_header(header[-2], header[-1])
+ loop do
+ seg = asm.read_segment
+ asm.write_segment(seg)
+ end
+ rescue Qpid::Closed
+ nil # Ignore
+ end
+ end
+ end
+
+ def teardown
+ @server.finish
+ @server.join
+ end
+
+ def test_assembler
+ asm = Assembler.new(@server.client, max_payload = 1)
+ asm.write_header(0, 10)
+ asm.write_segment(Segment.new(true, false, 1, 2, 3, "TEST"))
+ asm.write_segment(Segment.new(false, true, 1, 2, 3, "ING"))
+
+ assert_equal( ["AMQP", 1, 1, 0, 10], asm.read_header)
+
+ seg = asm.read_segment
+ assert_equal(true, seg.first_segment?)
+ assert_equal(false, seg.last_segment?)
+ assert_equal(1, seg.type)
+ assert_equal(2, seg.track)
+ assert_equal(3, seg.channel)
+ assert_equal("TEST", seg.payload)
+
+ seg = asm.read_segment
+ assert_equal(false, seg.first_segment?)
+ assert_equal(true, seg.last_segment?)
+ assert_equal(1, seg.type)
+ assert_equal(2, seg.track)
+ assert_equal(3, seg.channel)
+ assert_equal("ING", seg.payload)
+ end
+end
diff --git a/qpid/ruby/tests/codec010.rb b/qpid/ruby/tests/codec010.rb
new file mode 100644
index 0000000000..a9a5ca81e0
--- /dev/null
+++ b/qpid/ruby/tests/codec010.rb
@@ -0,0 +1,122 @@
+#
+# 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.
+#
+
+require "test/unit"
+require "qpid"
+require "tests/util"
+require "socket"
+
+class CodecTest < Test::Unit::TestCase
+
+ def setup
+ @spec = Qpid::Spec010::load
+ end
+
+ def check(type, value)
+ t = @spec[type]
+ sc = Qpid::StringCodec.new(@spec)
+ t.encode(sc, value)
+ decoded = t.decode(sc)
+ assert_equal(value, decoded)
+ end
+
+
+ def testMapString
+ check("map", {"string" => "this is a test"})
+ end
+
+ def testMapInt
+ check("map", {"int" => 3})
+ end
+
+ def testMapLong
+ check("map", {"long" => 2**32})
+ end
+
+ def testMapNone
+ check("map", {"none" => None})
+ end
+
+ def testMapNested
+ check("map", {"map" => {"string" => "nested test"}})
+ end
+
+ def testMapList
+ check("map", {"list" => [1, "two", 3.0, -4]})
+ end
+
+ def testMapAll
+ check("map", {"string" => "this is a test",
+ "int" => 3,
+ "long" => 2**32,
+ "nil" => nil,
+ "map" => {"string" => "nested map"},
+ "list" => [1, "two", 3.0, -4]})
+ end
+
+ def testMapEmpty
+ check("map", {})
+ end
+
+ def testMapNone
+ check("map", nil)
+ end
+
+ def testList
+ check("list", [1, "two", 3.0, -4])
+ end
+
+ def testListEmpty
+ check("list", [])
+ end
+
+ def testListNone
+ check("list", nil)
+ end
+
+ def testArrayInt
+ check("array", [1, 2, 3, 4])
+ end
+
+ def testArrayString
+ check("array", ["one", "two", "three", "four"])
+ end
+
+ def testArrayEmpty
+ check("array", [])
+ end
+
+ def testArrayNone
+ check("array", nil)
+ end
+
+ def testInt64
+ check("int64", 2 ** 40 * -1 + 43)
+ end
+
+ def testUint64
+ check("int64", 2 ** 42)
+ end
+
+ def testReadNone
+ sc = Qpid::StringCodec.new(@spec)
+ # Python behaves this way
+ assert_equal("", sc.read(nil))
+ end
+end
diff --git a/qpid/ruby/tests/connection.rb b/qpid/ruby/tests/connection.rb
new file mode 100644
index 0000000000..c2a851ec0a
--- /dev/null
+++ b/qpid/ruby/tests/connection.rb
@@ -0,0 +1,246 @@
+#
+# 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.
+#
+
+require 'test/unit'
+require 'qpid'
+require 'tests/util'
+
+class MockServer
+
+ def initialize(queue)
+ @queue = queue
+ end
+
+ def connection(conn, args={})
+ return Qpid::Delegate::Server.new(conn, :delegate => method(:session))
+ end
+
+ def session(ssn, args={})
+ ssn.auto_sync = false
+ return MockSession.new(ssn, @queue)
+ end
+end
+
+class MockSession < Qpid::Session::Delegate
+
+ def initialize(session, queue)
+ @session = session
+ @queue = queue
+ end
+
+ def execution_sync(es)
+ nil
+ end
+
+ def queue_query(qq)
+ return qq.st_type.result.create(qq.queue)
+ end
+
+ def message_transfer(cmd, headers, body)
+ if cmd.destination == "echo"
+ m = Qpid::Message.new(body)
+ m.headers = headers
+ @session.message_transfer(cmd.destination, cmd.accept_mode,
+ cmd.acquire_mode, m)
+ elsif cmd.destination == "abort"
+ @session.channel.connection.sock.close()
+ else
+ @queue.put([cmd, headers, body])
+ end
+ end
+
+ def exchange_declare(ed)
+ # do nothing
+ end
+end
+
+class TestConnectionTest < Test::Unit::TestCase
+
+ def setup
+ # Make sure errors in threads lead to a noisy death of the test
+ Thread.abort_on_exception = true
+
+ @queue = Qpid::Queue.new
+ @running = true
+ ts = MockServer.new(@queue)
+ @server = Util::ServerThread.new do |socket|
+ conn = Qpid::Connection.new(socket, :delegate => ts.method(:connection))
+ begin
+ conn.start(5)
+ rescue Qpid::Closed
+ # Ignore
+ end
+ end
+
+ class << @server
+ def finish
+ @running.lock
+ client.close
+ @sockets.each { |sock| sock.close unless sock.closed? }
+ end
+ end
+
+ @server[:name] = 'server'
+ Thread.current[:name] = 'test'
+ end
+
+ def teardown
+ @server.finish
+ @server.join
+ end
+
+ def connect
+ sock = @server.client
+ return Qpid::Connection.new(sock)
+ end
+
+ def test_basic
+ c = connect
+ c.start(10)
+
+ ssn1 = c.session("test1", :timeout => 10)
+ ssn2 = c.session("test2", :timeout => 10)
+
+ assert_equal(c.sessions["test1"], ssn1)
+ assert_equal(c.sessions["test2"], ssn2)
+ assert_not_nil ssn1.channel
+ assert_not_nil ssn2.channel
+ assert(c.attached.values.include?(ssn1))
+ assert(c.attached.values.include?(ssn2))
+
+ ssn1.close(5)
+
+ assert_nil(ssn1.channel)
+ assert(! c.attached.values.include?(ssn1))
+ assert(c.sessions.values.include?(ssn2))
+
+ ssn2.close(5)
+
+ assert_nil(ssn2.channel)
+ assert(! c.attached.values.include?(ssn2))
+ assert(! c.sessions.values.include?(ssn2))
+
+ ssn = c.session("session", :timeout => 10)
+
+ assert_not_nil(ssn.channel)
+ assert(c.sessions.values.include?(ssn))
+
+ destinations = ["one", "two", "three"]
+
+ destinations.each { |d| ssn.message_transfer(d) }
+
+ destinations.each do |d|
+ cmd, header, body = @queue.get(10)
+ assert_equal(d, cmd.destination)
+ assert_nil(header)
+ assert_nil(body)
+ end
+
+ msg = Qpid::Message.new("this is a test")
+ ssn.message_transfer("four", :message => msg)
+ cmd, header, body = @queue.get(10)
+ assert_equal("four", cmd.destination)
+ assert_nil(header)
+ assert_equal(msg.body, body)
+
+ qq = ssn.queue_query("asdf")
+ assert_equal("asdf", qq.queue)
+ c.close(5)
+ end
+
+ def test_close_get
+ c = connect
+ c.start(10)
+ ssn = c.session("test", :timeout => 10)
+ echos = ssn.incoming("echo")
+
+ 10.times do |i|
+ ssn.message_transfer("echo",
+ :message => Qpid::Message.new("test#{i}"))
+ end
+
+ ssn.auto_sync=false
+ ssn.message_transfer("abort")
+
+ 10.times do |i|
+ m = echos.get(timeout=10)
+ assert_equal("test#{i}", m.body)
+ end
+
+ begin
+ m = echos.get(timeout=10)
+ flunk("Expected Closed")
+ rescue Qpid::Closed
+ # Ignore
+ end
+ end
+
+ def test_close_listen
+ c = connect
+ c.start(10)
+ ssn = c.session("test", :timeout => 10)
+ echos = ssn.incoming("echo")
+
+ messages = []
+ exceptions = []
+ lock = Monitor.new
+ condition = lock.new_cond
+
+ echos.exc_listen do |e|
+ exceptions << e
+ lock.synchronize { condition.signal }
+ end
+ echos.listen do |m|
+ messages << m
+ end
+
+ 10.times do |i|
+ ssn.message_transfer("echo",
+ :message => Qpid::Message.new("test#{i}"))
+ end
+ ssn.auto_sync=false
+ ssn.message_transfer("abort")
+
+ lock.synchronize { condition.wait(10) }
+
+ 10.times do |i|
+ m = messages.shift
+ assert_equal("test#{i}", m.body)
+ end
+
+ assert_equal(1, exceptions.size)
+ end
+
+ def test_sync
+ c = connect
+ c.start(10)
+ s = c.session("test")
+ s.auto_sync = false
+ s.message_transfer("echo",
+ :message => Qpid::Message.new("test"))
+ s.sync(10)
+ end
+
+ def test_exchange_declare
+ c = connect
+ c.start(10)
+ s = c.session("test")
+ s.exchange_declare("test-exchange")
+ end
+end
diff --git a/qpid/ruby/tests/datatypes.rb b/qpid/ruby/tests/datatypes.rb
new file mode 100644
index 0000000000..65b1f9e3f5
--- /dev/null
+++ b/qpid/ruby/tests/datatypes.rb
@@ -0,0 +1,224 @@
+#
+# 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.
+#
+
+require 'test/unit'
+require 'qpid'
+require 'tests/util'
+
+class TestSerial < Test::Unit::TestCase
+
+ def test_cmp
+ [0, 0x8FFFFFFF, 0xFFFFFFFF].each do |s|
+ s = s.to_serial
+ assert(s + 1 > s)
+ assert(s - 1 < s)
+ assert(s < s + 1)
+ assert(s > s - 1)
+ end
+ last = 0xFFFFFFFF.to_serial
+ zero = 0.to_serial
+ assert_equal(zero, last + 1)
+
+ assert_equal(last, [last, zero].min)
+ assert_equal(zero, [last, zero].max)
+ end
+
+ def test_incr
+ s = 0.to_serial
+ s += 1
+ assert_equal(1.to_serial, s)
+ end
+
+ def test_in
+ l = [1, 2, 3, 4].collect { |i| i.to_serial }
+ assert(l.include?(1.to_serial))
+ assert(l.include?((0xFFFFFFFF + 2).to_serial))
+ assert(l.include?(4))
+ end
+
+ def test_none
+ assert_not_equal(nil, 0.to_serial)
+ end
+
+ def test_hash
+ zero = 0.to_serial
+ d = { zero => :zero }
+ # FIXME: this does not work, since Ruby looks up the key and does
+ # a 0.eql?(zero), which bypasses the Qpid::Serial::eql?
+ # assert_equal(:zero, d[0])
+ end
+end
+
+class TestRangedSet < Test::Unit::TestCase
+
+ def assert_contains(rset, elts, nonelts = [])
+ assert_equal(elts, elts.select { |e| rset.include?(e) })
+ assert_equal(nonelts, nonelts.select { |e| ! rset.include?(e) })
+ end
+
+ def assert_ranges(rs, *ranges)
+ assert_equal(ranges.size, rs.ranges.size)
+ assert( ranges.all? { |rng| rs.include?(rng) } )
+ end
+
+ def test_simple
+ rs = Qpid::RangedSet.new
+
+ assert(rs.ranges.empty?)
+
+ rs.add(1)
+ assert_contains(rs, [1], [0,2])
+ assert_ranges(rs, 1..1)
+
+ rs.add(2)
+ assert_contains(rs, [1,2], [0,3])
+ assert_ranges(rs, 1..2)
+
+ rs.add(0)
+ assert_contains(rs, [0,1,2], [-1, 3])
+ assert_ranges(rs, 0..2)
+
+ rs.add(37)
+ assert_contains(rs, [0,1,2,37], [-1, 3, 36, 38])
+ assert_ranges(rs, 0..2, 37..37)
+
+ rs.add(-1)
+ assert_ranges(rs, -1..2, 37..37)
+
+ rs.add(-3)
+ assert_ranges(rs, -1..2, 37..37, -3..-3)
+
+ rs.add(1, 20)
+ assert_contains(rs, [20], [21])
+ assert_ranges(rs, -1..20, 37..37, -3..-3)
+
+ rs.add(21,36)
+ assert_ranges(rs, -1..37, -3..-3)
+
+ rs.add(-3, 5)
+ assert_ranges(rs, -3..37)
+ end
+
+ def test_add_self
+ a = Qpid::RangedSet.new
+ a.add(0, 8)
+ assert_ranges(a, 0..8)
+
+ a.add(0, 8)
+ assert_ranges(a, 0..8)
+ end
+end
+
+class TestRange < Test::Unit::TestCase
+
+ def test_intersect1
+ a = Range.new(0, 10)
+ b = Range.new(9, 20)
+ i1 = a.intersect(b)
+ i2 = b.intersect(a)
+ assert_equal(9..10, i1)
+ assert_equal(9..10, i2)
+ end
+
+ def test_intersect2
+ a = Range.new(0, 10)
+ b = Range.new(11, 20)
+ assert_equal(nil, a.intersect(b))
+ assert_equal(nil, b.intersect(a))
+ end
+
+ def test_intersect3
+ a = Range.new(0, 10)
+ b = Range.new(3, 5)
+ i1 = a.intersect(b)
+ i2 = b.intersect(a)
+ assert_equal(3..5, i1)
+ assert_equal(3..5, i2)
+ end
+end
+
+class TestUUIDTest < Test::Unit::TestCase
+
+ def test_simple
+ # this test is kind of lame, but it does excercise the basic
+ # functionality of the class
+ u = Qpid::UUID::uuid4
+ 1024.times { |i| assert_not_equal(u, Qpid::UUID::uuid4) }
+ assert_raise NotImplementedError do
+ u == 0
+ end
+ end
+end
+
+class TestMessage < Test::Unit::TestCase
+
+ def setup
+ @@spec ||= Qpid::Spec010::load()
+ @mp = Qpid::struct(@@spec["message_properties"])
+ @dp = Qpid::struct(@@spec["delivery_properties"])
+ @fp = Qpid::struct(@@spec["fragment_properties"])
+ end
+
+ def test_has
+ m = Qpid::Message.new(@mp, @dp, @fp, "body")
+ assert m.has("message_properties")
+ assert m.has("delivery_properties")
+ assert m.has("fragment_properties")
+ end
+
+ def test_get
+ m = Qpid::Message.new(@mp, @dp, @fp, "body")
+ assert_same(@mp, m.get("message_properties"))
+ assert_same(@dp, m.get("delivery_properties"))
+ assert_same(@fp, m.get("fragment_properties"))
+ end
+
+ def test_set
+ m = Qpid::Message.new(@mp, @dp, "body")
+ assert_nil m.get("fragment_properties")
+ m.set(@fp)
+ assert_same(@fp, m.get("fragment_properties"), "4")
+ end
+
+ def test_set_on_empty
+ m = Qpid::Message.new("body")
+ assert_nil m.get("delivery_properties")
+ m.set(@dp)
+ assert_same(@dp, m.get("delivery_properties"), "5")
+ end
+
+ def test_set_replace
+ m = Qpid::Message.new(@mp, @dp, @fp, "body")
+ dp = Qpid::struct(@@spec["delivery_properties"])
+ assert_same(@dp, m.get("delivery_properties"), "6")
+ m.set(dp)
+ assert_same(dp, m.get("delivery_properties"), "7")
+ end
+
+ def test_clear
+ m = Qpid::Message.new(@mp, @dp, @fp, "body")
+ assert_same(@mp, m.get("message_properties"), "8")
+ assert_same(@dp, m.get("delivery_properties"), "9")
+ assert_same(@fp, m.get("fragment_properties"), "10")
+ m.clear("fragment_properties")
+ assert_nil m.get("fragment_properties")
+ assert_same(@mp, m.get("message_properties"), "11")
+ assert_same(@dp, m.get("delivery_properties"), "12")
+ end
+end
diff --git a/qpid/ruby/tests/framer.rb b/qpid/ruby/tests/framer.rb
new file mode 100644
index 0000000000..1d56f2faf1
--- /dev/null
+++ b/qpid/ruby/tests/framer.rb
@@ -0,0 +1,99 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+require "test/unit"
+require "qpid"
+require 'tests/util'
+
+require 'logger'
+
+class TestFramer < Test::Unit::TestCase
+
+ include Test
+
+ def setup
+ #Qpid::raw_logger = Logger.new(STDOUT)
+ #Qpid::frm_logger = Logger.new(STDOUT)
+
+ @server = Util::ServerThread.new do |socket|
+ conn = Qpid::Framer.new(socket)
+ begin
+ h = conn.read_header
+ conn.write_header(h[-2], h[-1])
+ loop do
+ frame = conn.read_frame
+ conn.write_frame(frame)
+ conn.flush
+ end
+ rescue Qpid::Closed
+ nil # Ignore
+ end
+ end
+ end
+
+ def teardown
+ @server.finish
+ @server.join
+ end
+
+ Frame = Qpid::Frame
+
+ def test_framer
+ c = Qpid::Framer.new(@server.client)
+
+ c.write_header(0, 10)
+ assert_equal( ["AMQP", 1, 1, 0, 10], c.read_header())
+
+ c.write_frame(Frame.new(Qpid::FIRST_FRM, 1, 2, 3, "THIS"))
+ c.write_frame(Frame.new(0, 1, 2, 3, "IS"))
+ c.write_frame(Frame.new(0, 1, 2, 3, "A"))
+ c.write_frame(Frame.new(Qpid::LAST_FRM, 1, 2, 3, "TEST"))
+ c.flush()
+
+ f = c.read_frame
+ assert(f.first_frame?)
+ assert(! f.last_frame?)
+ assert_equal(1, f.type)
+ assert_equal(2, f.track)
+ assert_equal(3, f.channel)
+ assert_equal("THIS", f.payload)
+
+ f = c.read_frame
+ assert_equal(0, f.flags)
+ assert_equal(1, f.type)
+ assert_equal(2, f.track)
+ assert_equal(3, f.channel)
+ assert_equal("IS", f.payload)
+
+ f = c.read_frame
+ assert_equal(0, f.flags)
+ assert_equal(1, f.type)
+ assert_equal(2, f.track)
+ assert_equal(3, f.channel)
+ assert_equal("A", f.payload)
+
+ f = c.read_frame
+ assert(f.last_frame?)
+ assert(! f.first_frame?)
+ assert_equal(1, f.type)
+ assert_equal(2, f.track)
+ assert_equal(3, f.channel)
+ assert_equal("TEST", f.payload)
+ end
+end
diff --git a/qpid/ruby/tests/qmf.rb b/qpid/ruby/tests/qmf.rb
new file mode 100644
index 0000000000..274e38416e
--- /dev/null
+++ b/qpid/ruby/tests/qmf.rb
@@ -0,0 +1,248 @@
+#
+# 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.
+#
+
+require "test/unit"
+require "qpid"
+require "tests/util"
+require "socket"
+require "monitor.rb"
+
+class QmfTest < Test::Unit::TestCase
+
+ class Handler < Qpid::Qmf::Console
+ include MonitorMixin
+
+ def initialize
+ super()
+ @xmt_list = {}
+ @rcv_list = {}
+ end
+
+ def method_response(broker, seq, response)
+ synchronize do
+ @rcv_list[seq] = response
+ end
+ end
+
+ def request(broker, count)
+ @count = count
+ for idx in 0...count
+ synchronize do
+ seq = broker.echo(idx, "Echo Message", :async => true)
+ @xmt_list[seq] = idx
+ end
+ end
+ end
+
+ def check
+ return "fail (attempted send=%d, actual sent=%d)" % [@count, @xmt_list.size] unless @count == @xmt_list.size
+ lost = 0
+ mismatched = 0
+ @xmt_list.each do |seq, value|
+ if @rcv_list.include?(seq)
+ result = @rcv_list.delete(seq)
+ mismatch += 1 unless result.sequence == value
+ else
+ lost += 1
+ end
+ end
+ spurious = @rcv_list.size
+ if lost == 0 and mismatched == 0 and spurious == 0
+ return "pass"
+ else
+ return "fail (lost=%d, mismatch=%d, spurious=%d)" % [lost, mismatched, spurious]
+ end
+ end
+ end
+
+ def setup()
+ # Make sure errors in threads lead to a noisy death of the test
+ Thread.abort_on_exception = true
+
+ @host = ENV.fetch("QMF_TEST_HOST", 'localhost')
+ @port = ENV.fetch("QMF_TEST_PORT", 5672)
+
+ sock = TCPSocket.new(@host, @port)
+
+ @conn = Qpid::Connection.new(sock)
+ @conn.start()
+
+ @session = @conn.session("test-session")
+ end
+
+ def teardown
+ unless @session.error?
+ @session.close(10)
+ end
+ @conn.close(10)
+ if @qmf
+ @qmf.del_broker(@qmf_broker)
+ end
+ end
+
+ def start_qmf(kwargs = {})
+ @qmf = Qpid::Qmf::Session.new(kwargs)
+ @qmf_broker = @qmf.add_broker("amqp://%s:%d" % [@host, @port])
+
+ brokers = @qmf.objects(:class => "broker")
+ assert_equal(1, brokers.length)
+ @broker = brokers[0]
+ end
+
+ def test_methods_sync()
+ start_qmf
+ body = "Echo Message Body"
+ for seq in 1..10
+ res = @broker.echo(seq, body, :timeout => 10)
+ assert_equal(0, res.status)
+ assert_equal("OK", res.text)
+ assert_equal(seq, res.sequence)
+ assert_equal(body, res.body)
+ end
+ end
+
+ def test_methods_async()
+ handler = Handler.new
+ start_qmf(:console => handler)
+ handler.request(@broker, 20)
+ sleep(1)
+ assert_equal("pass", handler.check)
+ end
+
+ def test_move_queued_messages()
+ """
+ Test ability to move messages from the head of one queue to another.
+ Need to test moveing all and N messages.
+ """
+
+ "Set up source queue"
+ start_qmf
+ @session.queue_declare(:queue => "src-queue", :exclusive => true, :auto_delete => true)
+ @session.exchange_bind(:queue => "src-queue", :exchange => "amq.direct", :binding_key => "routing_key")
+
+ props = @session.delivery_properties(:routing_key => "routing_key")
+ for count in 1..20
+ body = "Move Message %d" % count
+ src_msg = Qpid::Message.new(props, body)
+ @session.message_transfer(:destination => "amq.direct", :message => src_msg)
+ end
+
+ "Set up destination queue"
+ @session.queue_declare(:queue => "dest-queue", :exclusive => true, :auto_delete => true)
+ @session.exchange_bind(:queue => "dest-queue", :exchange => "amq.direct")
+
+ queues = @qmf.objects(:class => "queue")
+
+ "Move 10 messages from src-queue to dest-queue"
+ result = @qmf.objects(:class => "broker")[0].queueMoveMessages("src-queue", "dest-queue", 10)
+ assert_equal(0, result.status)
+
+ sq = @qmf.objects(:class => "queue", "name" => "src-queue")[0]
+ dq = @qmf.objects(:class => "queue", "name" => "dest-queue")[0]
+
+ assert_equal(10, sq.msgDepth)
+ assert_equal(10, dq.msgDepth)
+
+ "Move all remaining messages to destination"
+ result = @qmf.objects(:class => "broker")[0].queueMoveMessages("src-queue", "dest-queue", 0)
+ assert_equal(0, result.status)
+
+ sq = @qmf.objects(:class => "queue", 'name' => "src-queue")[0]
+ dq = @qmf.objects(:class => "queue", 'name' => "dest-queue")[0]
+
+ assert_equal(0, sq.msgDepth)
+ assert_equal(20, dq.msgDepth)
+
+ "Use a bad source queue name"
+ result = @qmf.objects(:class => "broker")[0].queueMoveMessages("bad-src-queue", "dest-queue", 0)
+ assert_equal(4, result.status)
+
+ "Use a bad destination queue name"
+ result = @qmf.objects(:class => "broker")[0].queueMoveMessages("src-queue", "bad-dest-queue", 0)
+ assert_equal(4, result.status)
+
+ " Use a large qty (40) to move from dest-queue back to "
+ " src-queue- should move all "
+ result = @qmf.objects(:class => "broker")[0].queueMoveMessages("dest-queue", "src-queue", 40)
+ assert_equal(0, result.status)
+
+ sq = @qmf.objects(:class => "queue", 'name' => "src-queue")[0]
+ dq = @qmf.objects(:class => "queue", 'name' => "dest-queue")[0]
+
+ assert_equal(20, sq.msgDepth)
+ assert_equal(0, dq.msgDepth)
+
+ "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.message_credit_unit.message,
+ :value => 0xFFFFFFFF)
+ @session.message_flow(:destination => "tag",
+ :unit => @session.message_credit_unit.byte,
+ :value => 0xFFFFFFFF)
+ queue = @session.incoming("tag")
+ for count in 1..20
+ consumed_msg = queue.get(timeout=1)
+ body = "Move Message %d" % count
+ assert_equal(body, consumed_msg.body)
+ end
+ end
+
+ # Test ability to purge messages from the head of a queue. Need to test
+ # moveing all, 1 (top message) and N messages.
+ def test_purge_queue
+ start_qmf
+ # Set up purge queue"
+ @session.queue_declare(:queue => "purge-queue",
+ :exclusive => true,
+ :auto_delete => true)
+ @session.exchange_bind(:queue => "purge-queue",
+ :exchange => "amq.direct",
+ :binding_key => "routing_key")
+
+ props = @session.delivery_properties(:routing_key => "routing_key")
+ 20.times do |count|
+ body = "Purge Message %d" % count
+ msg = Qpid::Message.new(props, body)
+ @session.message_transfer(:destination => "amq.direct",
+ :message => msg)
+ end
+
+ pq = @qmf.objects(:class => "queue", 'name' => "purge-queue")[0]
+
+ "Purge top message from purge-queue"
+ result = pq.purge(1)
+ assert_equal(0, result.status)
+ pq = @qmf.objects(:class => "queue", 'name' => "purge-queue")[0]
+ assert_equal(19, pq.msgDepth)
+
+ "Purge top 9 messages from purge-queue"
+ result = pq.purge(9)
+ assert_equal(0, result.status)
+ pq = @qmf.objects(:class => "queue", 'name' => "purge-queue")[0]
+ assert_equal(10, pq.msgDepth)
+
+ "Purge all messages from purge-queue"
+ result = pq.purge(0)
+ assert_equal(0, result.status)
+ pq = @qmf.objects(:class => "queue", 'name' => "purge-queue")[0]
+ assert_equal(0, pq.msgDepth)
+ end
+end
diff --git a/qpid/ruby/tests/queue.rb b/qpid/ruby/tests/queue.rb
new file mode 100644
index 0000000000..4ec0e07ffb
--- /dev/null
+++ b/qpid/ruby/tests/queue.rb
@@ -0,0 +1,80 @@
+#
+# 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.
+#
+
+require 'test/unit'
+require 'qpid'
+
+class TestQueue < Test::Unit::TestCase
+
+ # The qpid queue class just provides sime simple extensions to
+ # python's standard queue data structure, so we don't need to test
+ # all the queue functionality.
+
+ def setup
+ # Make sure errors in threads lead to a noisy death of the test
+ Thread.abort_on_exception = true
+ end
+
+ def test_listen
+ values = []
+ heard = Qpid::Util::Event.new
+
+ listener = Proc.new do |x|
+ values << x
+ heard.set
+ end
+
+ q = Qpid::Queue.new
+ q.listen(&listener)
+
+ heard.clear
+ q.put(1)
+ heard.wait
+ assert_equal([1], values)
+ heard.clear
+ q.put(2)
+ heard.wait
+ assert_equal([1, 2], values)
+
+ q.listen
+ q.put(3)
+ assert_equal(3, q.get)
+
+ q.listen(&listener)
+ heard.clear
+ q.put(4)
+ heard.wait
+ assert_equal([1,2,4], values)
+ end
+
+ def test_close
+ q = Qpid::Queue.new
+ (1..3).each { |i| q.put(i) }
+ q.close
+ assert_equal(1, q.get)
+ assert_equal(2, q.get)
+ assert_equal(3, q.get)
+ 10.times do |i|
+ assert_raises(Qpid::Closed) do
+ q.get
+ end
+ end
+ end
+
+end
diff --git a/qpid/ruby/tests/spec010.rb b/qpid/ruby/tests/spec010.rb
new file mode 100644
index 0000000000..6db1523455
--- /dev/null
+++ b/qpid/ruby/tests/spec010.rb
@@ -0,0 +1,80 @@
+#
+# 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.
+#
+
+require "test/unit"
+require "qpid/test"
+require "qpid/spec010"
+
+class SpecTest < Test::Unit::TestCase
+
+ def setup()
+ @spec = Qpid::Spec010.load()
+ end
+
+ def testSessionHeader()
+ hdr = @spec[:header]
+ sc = Qpid::StringCodec.new(@spec)
+ hdr.encode(sc, Qpid::struct(hdr, :sync=>true))
+ assert sc.encoded == "\x01\x01"
+
+ sc = Qpid::StringCodec.new(@spec)
+ hdr.encode(sc, Qpid::struct(hdr, :sync=>false))
+ assert sc.encoded == "\x01\x00"
+ end
+
+ def encdec(type, value)
+ sc = Qpid::StringCodec.new(@spec)
+ type.encode(sc, value)
+ decoded = type.decode(sc)
+ return decoded
+ end
+
+ def testMessageProperties()
+ mp = @spec[:message_properties]
+ rt = @spec[:reply_to]
+
+ props = Qpid::struct(mp,
+ :content_length=>3735928559,
+ :reply_to=>Qpid::struct(rt,
+ :exchange=>"the exchange name",
+ :routing_key=>"the routing key"))
+ dec = encdec(mp, props)
+ assert props.content_length == dec.content_length
+ assert props.reply_to.exchange == dec.reply_to.exchange
+ assert props.reply_to.routing_key == dec.reply_to.routing_key
+ end
+
+ def testMessageSubscribe()
+ ms = @spec[:message_subscribe]
+ cmd = Qpid::struct(ms, :exclusive=>true, :destination=>"this is a test")
+ dec = encdec(@spec[:message_subscribe], cmd)
+ assert cmd.exclusive == dec.exclusive
+ assert cmd.destination == dec.destination
+ end
+
+ def testXid()
+ xid = @spec[:xid]
+ sc = Qpid::StringCodec.new(@spec)
+ st = Qpid::struct(xid, :format=>0, :global_id=>"gid", :branch_id=>"bid")
+ xid.encode(sc, st)
+ assert sc.encoded == "\x00\x00\x00\x10\x06\x04\x07\x00\x00\x00\x00\x00\x03gid\x03bid"
+ assert xid.decode(sc) == st
+ end
+
+end
diff --git a/qpid/ruby/tests/util.rb b/qpid/ruby/tests/util.rb
new file mode 100644
index 0000000000..b22a6bab2f
--- /dev/null
+++ b/qpid/ruby/tests/util.rb
@@ -0,0 +1,72 @@
+#
+# 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.
+#
+
+require 'thread'
+require 'socket'
+
+module Util
+
+ TOPDIR = File::dirname(File::dirname(File::expand_path(__FILE__)))
+ SPEC = File::join(TOPDIR, "specs", "amqp.0-10-qpid-errata.xml")
+
+ PORT = 1234
+ HOST = "0.0.0.0"
+
+ def self.connect(host = HOST, port = PORT)
+ TCPSocket.new(host, port)
+ end
+
+ class ServerThread < Thread
+ def initialize(&block)
+ @sockets = []
+ @running = Mutex.new
+ started = Qpid::Util::Event.new
+ super(started, @running) do |started, running|
+ tcp_srv = TCPServer.new(HOST, PORT)
+ begin
+ started.set
+ while ! running.locked? and (session = tcp_srv.accept)
+ yield(session)
+ end
+ rescue Exception => e
+ # Exceptions in the server thread are hard to see
+ # Make sure they apear loudly on the console
+ $stderr.puts "#{ "*" * 20} Server exception #{ "*" * 20}"
+ $stderr.puts e.message
+ $stderr.puts e.backtrace
+ raise
+ ensure
+ tcp_srv.close
+ end
+ end
+ started.wait
+ end
+
+ def finish
+ @running.lock
+ @sockets.each { |sock| sock.close unless sock.closed? }
+ end
+
+ def client(host = HOST, port = PORT)
+ sock = Util::connect(host, port)
+ @sockets << sock
+ sock
+ end
+ end
+end
diff --git a/qpid/ruby/tests_0-8/basic.rb b/qpid/ruby/tests_0-8/basic.rb
new file mode 100644
index 0000000000..10a43b1aab
--- /dev/null
+++ b/qpid/ruby/tests_0-8/basic.rb
@@ -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.
+#
+
+require "test/unit"
+require "qpid/test"
+require "qpid"
+
+class Basic < Test::Unit::TestCase
+
+ include Qpid08::Test
+
+ def publish(body, headers = {})
+ cli = connect()
+ ch = cli.channel(1)
+ ch.channel_open()
+ content = Qpid08::Content.new(headers, body)
+ ch.basic_publish(:content => content)
+ msg = ch.channel_close()
+ assert msg.method.qname == :channel_close_ok
+ end
+
+ def consume(body, headers = {})
+ cli = connect()
+ ch = cli.channel(1)
+ ch.channel_open()
+ ch.queue_declare(:queue => "test-queue")
+ ch.queue_bind(:queue_name => "test-queue")
+ ch.basic_consume(:queue => "test-queue", :consumer_tag => "ctag")
+ content = Qpid08::Content.new(headers, body)
+ ch.basic_publish(:routing_key => "test-queue", :content => content)
+ queue = cli.queue("ctag")
+ msg = queue.pop()
+ assert content.headers == msg.content.headers
+ assert content.body == msg.content.body
+ assert content.children == msg.content.children
+ ch.basic_ack(msg.delivery_tag)
+ msg = ch.channel_close()
+ assert msg.method.qname == :channel_close_ok
+ end
+
+ def test_publish(); publish("hello world") end
+
+ def test_publish_empty(); publish("") end
+
+ def test_publish_headers(); publish("hello world", :content_type => "text/plain") end
+
+ def test_consume(); consume("hello world") end
+
+ def test_consume_empty(); consume("") end
+
+ def test_consume_headers(); consume("hello_world", :content_type => "text/plain") end
+
+end
diff --git a/qpid/ruby/tests_0-8/channel.rb b/qpid/ruby/tests_0-8/channel.rb
new file mode 100644
index 0000000000..1eea8f18d9
--- /dev/null
+++ b/qpid/ruby/tests_0-8/channel.rb
@@ -0,0 +1,48 @@
+#
+# 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.
+#
+
+require "test/unit"
+require "qpid/test"
+require "qpid"
+
+class Channel < Test::Unit::TestCase
+
+ include Qpid08::Test
+
+ def test_channel_open_close()
+ c = connect()
+ ch = c.channel(1)
+ msg = ch.channel_open()
+ assert msg.method.qname == :channel_open_ok
+ msg = ch.channel_close()
+ assert msg.method.qname == :channel_close_ok
+ end
+
+ def test_channel_close()
+ c = connect()
+ ch = c.channel(1)
+ begin
+ ch.channel_close()
+ rescue Qpid::Closed => e
+ assert c.code.method.qname == :connection_close
+ assert c.code.reply_code == 504
+ end
+ end
+
+end
diff --git a/qpid/specs/management-schema.xml b/qpid/specs/management-schema.xml
index 9f54b0cd31..e52e3f23cf 100644
--- a/qpid/specs/management-schema.xml
+++ b/qpid/specs/management-schema.xml
@@ -176,7 +176,6 @@
<statistic name="unackedMessages" type="hilo32" unit="message" desc="Messages consumed but not yet acked"/>
<statistic name="messageLatency" type="mmaTime" unit="nanosecond" desc="Broker latency through this queue"/>
<statistic name="flowStopped" type="bool" desc="Flow control active."/>
- <statistic name="flowStoppedCount" type="count32" desc="Number of times flow control was activated for this queue"/>
<method name="purge" desc="Discard all or some messages on a queue">
<arg name="request" dir="I" type="uint32" desc="0 for all messages or n>0 for n messages"/>
@@ -255,7 +254,6 @@
<property name="address" type="sstr" access="RC" index="y"/>
<property name="incoming" type="bool" access="RC"/>
<property name="SystemConnection" type="bool" access="RC" desc="Infrastucture/ Inter-system connection (Cluster, Federation, ...)"/>
- <property name="userProxyAuth" type="bool" access="RO" desc="Authorization to proxy for users not on broker"/>
<property name="federationLink" type="bool" access="RO" desc="Is this a federation link"/>
<property name="authIdentity" type="sstr" access="RO" desc="authId of connection if authentication enabled"/>
<property name="remoteProcessName" type="lstr" access="RO" optional="y" desc="Name of executable running as remote client"/>
diff --git a/qpid/tests/setup.py b/qpid/tests/setup.py
index 2ea7d347e7..5438275b22 100755
--- a/qpid/tests/setup.py
+++ b/qpid/tests/setup.py
@@ -20,7 +20,7 @@
from distutils.core import setup
setup(name="qpid-tests",
- version="0.13",
+ version="0.9",
author="Apache Qpid",
author_email="dev@qpid.apache.org",
packages=["qpid_tests", "qpid_tests.broker_0_10", "qpid_tests.broker_0_9",
diff --git a/qpid/tests/src/py/qpid_tests/broker_0_10/alternate_exchange.py b/qpid/tests/src/py/qpid_tests/broker_0_10/alternate_exchange.py
index 8cbb5793d9..0ffeb57172 100644
--- a/qpid/tests/src/py/qpid_tests/broker_0_10/alternate_exchange.py
+++ b/qpid/tests/src/py/qpid_tests/broker_0_10/alternate_exchange.py
@@ -18,7 +18,7 @@
#
import traceback
from qpid.queue import Empty
-from qpid.datatypes import Message, RangedSet
+from qpid.datatypes import Message
from qpid.testlib import TestBase010
from qpid.session import SessionException
@@ -77,7 +77,13 @@ class AlternateExchangeTests(TestBase010):
"""
session = self.session
#set up a 'dead letter queue':
- dlq = self.setup_dlq()
+ session.exchange_declare(exchange="dlq", type="fanout")
+ 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=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:
session.queue_declare(queue="delete-me", alternate_exchange="dlq")
@@ -230,121 +236,6 @@ class AlternateExchangeTests(TestBase010):
self.assertEqual("Three", dlq.get(timeout=1).body)
self.assertEmpty(dlq)
- def test_queue_delete_loop(self):
- """
- Test that if a queue is bound to its own alternate exchange,
- then on deletion there is no infinite looping
- """
- session = self.session
- dlq = self.setup_dlq()
-
- #create a queue using the dlq as its alternate exchange:
- session.queue_declare(queue="delete-me", alternate_exchange="dlq")
- #bind that queue to the dlq as well:
- session.exchange_bind(exchange="dlq", queue="delete-me")
- #send it some messages:
- dp=self.session.delivery_properties(routing_key="delete-me")
- for m in ["One", "Two", "Three"]:
- session.message_transfer(message=Message(dp, m))
- #delete it:
- session.queue_delete(queue="delete-me")
- #cleanup:
- session.exchange_delete(exchange="dlq")
-
- #check the messages were delivered to the dlq:
- for m in ["One", "Two", "Three"]:
- self.assertEqual(m, dlq.get(timeout=1).body)
- self.assertEmpty(dlq)
-
- def test_queue_delete_no_match(self):
- """
- Test that on queue deletion, if the queues own alternate
- exchange cannot find a match for the message, the
- alternate-exchange of that exchange will be tried. Note:
- though the spec rules out going to the alternate-exchanges
- alternate exchange when sending to an exchange, it does not
- cover this case.
- """
- session = self.session
- dlq = self.setup_dlq()
-
- #setu up an 'intermediary' exchange
- session.exchange_declare(exchange="my-exchange", type="direct", alternate_exchange="dlq")
-
- #create a queue using the intermediary as its alternate exchange:
- session.queue_declare(queue="delete-me", alternate_exchange="my-exchange")
- #bind that queue to the dlq as well:
- session.exchange_bind(exchange="dlq", queue="delete-me")
- #send it some messages:
- dp=self.session.delivery_properties(routing_key="delete-me")
- for m in ["One", "Two", "Three"]:
- session.message_transfer(message=Message(dp, m))
-
- #delete it:
- session.queue_delete(queue="delete-me")
- #cleanup:
- session.exchange_delete(exchange="my-exchange")
- session.exchange_delete(exchange="dlq")
-
- #check the messages were delivered to the dlq:
- for m in ["One", "Two", "Three"]:
- self.assertEqual(m, dlq.get(timeout=1).body)
- self.assertEmpty(dlq)
-
- def test_reject_no_match(self):
- """
- Test that on rejecting a message, if the queues own alternate
- exchange cannot find a match for the message, the
- alternate-exchange of that exchange will be tried. Note:
- though the spec rules out going to the alternate-exchanges
- alternate exchange when sending to an exchange, it does not
- cover this case.
- """
- session = self.session
- dlq = self.setup_dlq()
-
- #setu up an 'intermediary' exchange
- session.exchange_declare(exchange="my-exchange", type="direct", alternate_exchange="dlq")
-
- #create a queue using the intermediary as its alternate exchange:
- session.queue_declare(queue="delivery-queue", alternate_exchange="my-exchange", auto_delete=True)
- #bind that queue to the dlq as well:
- session.exchange_bind(exchange="dlq", queue="delivery-queue")
- #send it some messages:
- dp=self.session.delivery_properties(routing_key="delivery-queue")
- for m in ["One", "Two", "Three"]:
- session.message_transfer(message=Message(dp, m))
-
- #get and reject those messages:
- session.message_subscribe(destination="a", queue="delivery-queue")
- session.message_flow(destination="a", unit=session.credit_unit.message, value=0xFFFFFFFFL)
- session.message_flow(destination="a", unit=session.credit_unit.byte, value=0xFFFFFFFFL)
- incoming = session.incoming("a")
- for m in ["One", "Two", "Three"]:
- msg = incoming.get(timeout=1)
- self.assertEqual(m, msg.body)
- session.message_reject(RangedSet(msg.id))
- session.message_cancel(destination="a")
-
- #check the messages were delivered to the dlq:
- for m in ["One", "Two", "Three"]:
- self.assertEqual(m, dlq.get(timeout=1).body)
- self.assertEmpty(dlq)
- #cleanup:
- session.exchange_delete(exchange="my-exchange")
- session.exchange_delete(exchange="dlq")
-
- def setup_dlq(self):
- session = self.session
- #set up 'dead-letter' handling:
- session.exchange_declare(exchange="dlq", type="fanout")
- 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=0xFFFFFFFFL)
- session.message_flow(destination="dlq", unit=session.credit_unit.byte, value=0xFFFFFFFFL)
- dlq = session.incoming("dlq")
- return dlq
def assertEmpty(self, queue):
try:
diff --git a/qpid/tests/src/py/qpid_tests/broker_0_10/dtx.py b/qpid/tests/src/py/qpid_tests/broker_0_10/dtx.py
index 19a5c6a8d9..2823385a3b 100644
--- a/qpid/tests/src/py/qpid_tests/broker_0_10/dtx.py
+++ b/qpid/tests/src/py/qpid_tests/broker_0_10/dtx.py
@@ -6,9 +6,9 @@
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
@@ -36,7 +36,7 @@ class DtxTests(TestBase010):
and the appropriate result verified.
The other tests enforce more specific rules and behaviour on a
- per-method or per-field basis.
+ per-method or per-field basis.
"""
XA_RBROLLBACK = 1
@@ -49,8 +49,8 @@ class DtxTests(TestBase010):
self.session = self.conn.session("dtx-session", 1)
def test_simple_commit(self):
- """
- Test basic one-phase commit behaviour.
+ """
+ Test basic one-phase commit behaviour.
"""
guard = self.keepQueuesAlive(["queue-a", "queue-b"])
session = self.session
@@ -73,8 +73,8 @@ class DtxTests(TestBase010):
self.assertMessageId("commit", "queue-b")
def test_simple_prepare_commit(self):
- """
- Test basic two-phase commit behaviour.
+ """
+ Test basic two-phase commit behaviour.
"""
guard = self.keepQueuesAlive(["queue-a", "queue-b"])
session = self.session
@@ -100,8 +100,8 @@ class DtxTests(TestBase010):
def test_simple_rollback(self):
- """
- Test basic rollback behaviour.
+ """
+ Test basic rollback behaviour.
"""
guard = self.keepQueuesAlive(["queue-a", "queue-b"])
session = self.session
@@ -123,8 +123,8 @@ class DtxTests(TestBase010):
self.assertMessageId("rollback", "queue-a")
def test_simple_prepare_rollback(self):
- """
- Test basic rollback behaviour after the transaction has been prepared.
+ """
+ Test basic rollback behaviour after the transaction has been prepared.
"""
guard = self.keepQueuesAlive(["queue-a", "queue-b"])
session = self.session
@@ -146,18 +146,18 @@ class DtxTests(TestBase010):
#check result
self.assertMessageCount(1, "queue-a")
self.assertMessageCount(0, "queue-b")
- self.assertMessageId("prepare-rollback", "queue-a")
+ self.assertMessageId("prepare-rollback", "queue-a")
def test_select_required(self):
"""
check that an error is flagged if select is not issued before
- start or end
+ start or end
"""
session = self.session
tx = self.xid("dummy")
try:
session.dtx_start(xid=tx)
-
+
#if we get here we have failed, but need to do some cleanup:
session.dtx_end(xid=tx)
session.dtx_rollback(xid=tx)
@@ -197,10 +197,10 @@ class DtxTests(TestBase010):
other.close()
session1.dtx_end(xid=tx)
session1.dtx_rollback(xid=tx)
-
+
#verification:
if failed: self.assertEquals(530, error.args[0].error_code)
- else: self.fail("Xid already known, expected exception!")
+ else: self.fail("Xid already known, expected exception!")
def test_forget_xid_on_completion(self):
"""
@@ -210,8 +210,8 @@ class DtxTests(TestBase010):
#do some transactional work & complete the transaction
self.test_simple_commit()
# session has been reset, so reselect for use with dtx
- self.session.dtx_select()
-
+ self.session.dtx_select()
+
#start association for the same xid as the previously completed txn
tx = self.xid("my-xid")
self.session.dtx_start(xid=tx)
@@ -237,9 +237,9 @@ class DtxTests(TestBase010):
self.assertEquals(503, e.args[0].error_code)
def test_start_join(self):
- """
+ """
Verify 'join' behaviour, where a session is associated with a
- transaction that is already associated with another session.
+ transaction that is already associated with another session.
"""
guard = self.keepQueuesAlive(["one", "two"])
#create two sessions & select them for use with dtx:
@@ -269,14 +269,14 @@ class DtxTests(TestBase010):
#mark end on both sessions
session1.dtx_end(xid=tx)
session2.dtx_end(xid=tx)
-
+
#commit and check
session1.dtx_commit(xid=tx, one_phase=True)
self.assertMessageCount(1, "one")
self.assertMessageCount(1, "two")
self.assertMessageId("a", "two")
self.assertMessageId("b", "one")
-
+
def test_suspend_resume(self):
"""
@@ -300,7 +300,7 @@ class DtxTests(TestBase010):
session.dtx_start(xid=tx, resume=True)
self.swap(session, "two", "one")#swap 'b' from 'two' to 'one'
session.dtx_end(xid=tx)
-
+
#commit and check
session.dtx_commit(xid=tx, one_phase=True)
self.assertMessageCount(1, "one")
@@ -308,7 +308,7 @@ class DtxTests(TestBase010):
self.assertMessageId("a", "two")
self.assertMessageId("b", "one")
- def test_suspend_start_end_resume(self):
+ def test_suspend_start_end_resume(self):
"""
Test suspension and resumption of an association with work
done on another transaction when the first transaction is
@@ -332,7 +332,7 @@ class DtxTests(TestBase010):
session.dtx_start(xid=tx, resume=True)
self.swap(session, "two", "one")#swap 'b' from 'two' to 'one'
session.dtx_end(xid=tx)
-
+
#commit and check
session.dtx_commit(xid=tx, one_phase=True)
self.assertMessageCount(1, "one")
@@ -341,10 +341,10 @@ class DtxTests(TestBase010):
self.assertMessageId("b", "one")
def test_end_suspend_and_fail(self):
- """
+ """
Verify that the correct error is signalled if the suspend and
fail flag are both set when disassociating a transaction from
- the session
+ the session
"""
session = self.session
session.dtx_select()
@@ -356,16 +356,16 @@ class DtxTests(TestBase010):
except SessionException, e:
self.assertEquals(503, e.args[0].error_code)
- #cleanup
+ #cleanup
other = self.connect()
session = other.session("cleanup", 1)
session.dtx_rollback(xid=tx)
session.close()
other.close()
-
+
def test_end_unknown_xid(self):
- """
+ """
Verifies that the correct exception is thrown when an attempt
is made to end the association for a xid not previously
associated with the session
@@ -382,7 +382,7 @@ class DtxTests(TestBase010):
def test_end(self):
"""
Verify that the association is terminated by end and subsequent
- operations are non-transactional
+ operations are non-transactional
"""
guard = self.keepQueuesAlive(["tx-queue"])
session = self.conn.session("alternate", 1)
@@ -408,7 +408,7 @@ class DtxTests(TestBase010):
session.message_accept(RangedSet(msg.id))
session.close()
- session = self.session
+ session = self.session
#commit the transaction and check that the first message (and
#only the first message) is then delivered
session.dtx_commit(xid=tx, one_phase=True)
@@ -418,7 +418,7 @@ class DtxTests(TestBase010):
def test_invalid_commit_one_phase_true(self):
"""
Test that a commit with one_phase = True is rejected if the
- transaction in question has already been prepared.
+ transaction in question has already been prepared.
"""
other = self.connect()
tester = other.session("tester", 1)
@@ -447,7 +447,7 @@ class DtxTests(TestBase010):
def test_invalid_commit_one_phase_false(self):
"""
Test that a commit with one_phase = False is rejected if the
- transaction in question has not yet been prepared.
+ transaction in question has not yet been prepared.
"""
other = self.connect()
tester = other.session("tester", 1)
@@ -474,7 +474,7 @@ class DtxTests(TestBase010):
def test_invalid_commit_not_ended(self):
"""
- Test that a commit fails if the xid is still associated with a session.
+ Test that a commit fails if the xid is still associated with a session.
"""
other = self.connect()
tester = other.session("tester", 1)
@@ -502,7 +502,7 @@ class DtxTests(TestBase010):
def test_invalid_rollback_not_ended(self):
"""
- Test that a rollback fails if the xid is still associated with a session.
+ Test that a rollback fails if the xid is still associated with a session.
"""
other = self.connect()
tester = other.session("tester", 1)
@@ -531,7 +531,7 @@ class DtxTests(TestBase010):
def test_invalid_prepare_not_ended(self):
"""
- Test that a prepare fails if the xid is still associated with a session.
+ Test that a prepare fails if the xid is still associated with a session.
"""
other = self.connect()
tester = other.session("tester", 1)
@@ -586,9 +586,9 @@ class DtxTests(TestBase010):
session1.dtx_rollback(xid=tx)
def test_get_timeout(self):
- """
+ """
Check that get-timeout returns the correct value, (and that a
- transaction with a timeout can complete normally)
+ transaction with a timeout can complete normally)
"""
session = self.session
tx = self.xid("dummy")
@@ -599,12 +599,12 @@ class DtxTests(TestBase010):
session.dtx_set_timeout(xid=tx, timeout=60)
self.assertEqual(60, session.dtx_get_timeout(xid=tx).timeout)
self.assertEqual(self.XA_OK, session.dtx_end(xid=tx).status)
- self.assertEqual(self.XA_OK, session.dtx_rollback(xid=tx).status)
-
+ self.assertEqual(self.XA_OK, session.dtx_rollback(xid=tx).status)
+
def test_set_timeout(self):
- """
+ """
Test the timeout of a transaction results in the expected
- behaviour
+ behaviour
"""
guard = self.keepQueuesAlive(["queue-a", "queue-b"])
@@ -627,7 +627,7 @@ class DtxTests(TestBase010):
self.assertMessageId("timeout", "queue-a")
#check the correct codes are returned when we try to complete the txn
self.assertEqual(self.XA_RBTIMEOUT, session.dtx_end(xid=tx).status)
- self.assertEqual(self.XA_RBTIMEOUT, session.dtx_rollback(xid=tx).status)
+ self.assertEqual(self.XA_RBTIMEOUT, session.dtx_rollback(xid=tx).status)
@@ -649,20 +649,20 @@ class DtxTests(TestBase010):
if i in [2, 5, 6, 8]:
session.dtx_prepare(xid=tx)
prepared.append(tx)
- else:
+ else:
session.dtx_rollback(xid=tx)
xids = session.dtx_recover().in_doubt
-
+
#rollback the prepared transactions returned by recover
for x in xids:
- session.dtx_rollback(xid=x)
+ session.dtx_rollback(xid=x)
#validate against the expected list of prepared transactions
actual = set([x.global_id for x in xids]) #TODO: come up with nicer way to test these
expected = set([x.global_id for x in prepared])
intersection = actual.intersection(expected)
-
+
if intersection != expected:
missing = expected.difference(actual)
extra = actual.difference(expected)
@@ -723,7 +723,7 @@ class DtxTests(TestBase010):
session.message_transfer(message=Message(dp, mp, "DtxMessage"))
#start the transaction:
- session.dtx_select()
+ session.dtx_select()
self.assertEqual(self.XA_OK, self.session.dtx_start(xid=tx).status)
#'swap' the message from one queue to the other, under that transaction:
@@ -760,7 +760,7 @@ class DtxTests(TestBase010):
def getMessageProperty(self, msg, prop):
for h in msg.headers:
if hasattr(h, prop): return getattr(h, prop)
- return None
+ return None
def keepQueuesAlive(self, names):
session = self.conn.session("nasty", 99)
@@ -768,7 +768,7 @@ class DtxTests(TestBase010):
session.queue_declare(queue=n, auto_delete=True)
session.message_subscribe(destination=n, queue=n)
return session
-
+
def createMessage(self, session, key, id, body):
dp=session.delivery_properties(routing_key=key)
mp=session.message_properties(correlation_id=id)
diff --git a/qpid/tests/src/py/qpid_tests/broker_0_10/exchange.py b/qpid/tests/src/py/qpid_tests/broker_0_10/exchange.py
index f51923fcf3..9a4cfd37d6 100644
--- a/qpid/tests/src/py/qpid_tests/broker_0_10/exchange.py
+++ b/qpid/tests/src/py/qpid_tests/broker_0_10/exchange.py
@@ -448,9 +448,9 @@ class MiscellaneousErrorsTests(TestHelper):
def testTypeNotKnown(self):
try:
self.session.exchange_declare(exchange="test_type_not_known_exchange", type="invalid_type")
- self.fail("Expected 404 for declaration of unknown exchange type.")
+ self.fail("Expected 503 for declaration of unknown exchange type.")
except SessionException, e:
- self.assertEquals(404, e.args[0].error_code)
+ self.assertEquals(503, e.args[0].error_code)
def testDifferentDeclaredType(self):
self.exchange_declare(exchange="test_different_declared_type_exchange", type="direct")
diff --git a/qpid/tests/src/py/qpid_tests/broker_0_10/extensions.py b/qpid/tests/src/py/qpid_tests/broker_0_10/extensions.py
index 50c0aa3dd1..26ea3cb0e9 100644
--- a/qpid/tests/src/py/qpid_tests/broker_0_10/extensions.py
+++ b/qpid/tests/src/py/qpid_tests/broker_0_10/extensions.py
@@ -20,8 +20,6 @@ from qpid.client import Client, Closed
from qpid.queue import Empty
from qpid.content import Content
from qpid.testlib import TestBase010
-from qpid.session import SessionException
-from qpid.datatypes import uuid4
from time import sleep
class ExtensionTests(TestBase010):
@@ -30,58 +28,10 @@ class ExtensionTests(TestBase010):
def test_timed_autodelete(self):
session = self.session
session2 = self.conn.session("another-session")
- name=str(uuid4())
- session2.queue_declare(queue=name, exclusive=True, auto_delete=True, arguments={"qpid.auto_delete_timeout":3})
+ session2.queue_declare(queue="my-queue", exclusive=True, auto_delete=True, arguments={"qpid.auto_delete_timeout":5})
session2.close()
- result = session.queue_query(queue=name)
- self.assertEqual(name, result.queue)
+ result = session.queue_query(queue="my-queue")
+ self.assertEqual("my-queue", result.queue)
sleep(5)
- result = session.queue_query(queue=name)
+ result = session.queue_query(queue="my-queue")
self.assert_(not result.queue)
-
- def valid_policy_args(self, args, name="test-queue"):
- try:
- self.session.queue_declare(queue=name, arguments=args)
- self.session.queue_delete(queue=name) # cleanup
- except SessionException, e:
- self.fail("declare with valid policy args failed: %s" % (args))
- self.session = self.conn.session("replacement", 2)
-
- def invalid_policy_args(self, args, name="test-queue"):
- # go through invalid declare attempts twice to make sure that
- # the queue doesn't actually get created first time around
- # even if exception is thrown
- for i in range(1, 3):
- try:
- self.session.queue_declare(queue=name, arguments=args)
- self.session.queue_delete(queue=name) # cleanup
- self.fail("declare with invalid policy args suceeded: %s (iteration %d)" % (args, i))
- except SessionException, e:
- self.session = self.conn.session(str(uuid4()))
-
- def test_policy_max_size_as_valid_string(self):
- self.valid_policy_args({"qpid.max_size":"3"})
-
- def test_policy_max_count_as_valid_string(self):
- self.valid_policy_args({"qpid.max_count":"3"})
-
- def test_policy_max_count_and_size_as_valid_strings(self):
- self.valid_policy_args({"qpid.max_count":"3","qpid.max_size":"0"})
-
- def test_policy_negative_count(self):
- self.invalid_policy_args({"qpid.max_count":-1})
-
- def test_policy_negative_size(self):
- self.invalid_policy_args({"qpid.max_size":-1})
-
- def test_policy_size_as_invalid_string(self):
- self.invalid_policy_args({"qpid.max_size":"foo"})
-
- def test_policy_count_as_invalid_string(self):
- self.invalid_policy_args({"qpid.max_count":"foo"})
-
- def test_policy_size_as_float(self):
- self.invalid_policy_args({"qpid.max_size":3.14159})
-
- def test_policy_count_as_float(self):
- self.invalid_policy_args({"qpid.max_count":"2222222.22222"})
diff --git a/qpid/tests/src/py/qpid_tests/broker_0_10/management.py b/qpid/tests/src/py/qpid_tests/broker_0_10/management.py
index 952878e0b7..06f3212a6f 100644
--- a/qpid/tests/src/py/qpid_tests/broker_0_10/management.py
+++ b/qpid/tests/src/py/qpid_tests/broker_0_10/management.py
@@ -242,38 +242,6 @@ class ManagementTest (TestBase010):
pq = self.qmf.getObjects(_class="queue", name="purge-queue")[0]
self.assertEqual (pq.msgDepth,0)
- def test_reroute_priority_queue(self):
- self.startQmf()
- session = self.session
-
- #setup test queue supporting multiple priority levels
- session.queue_declare(queue="test-queue", exclusive=True, auto_delete=True, arguments={'x-qpid-priorities':10})
-
- #send some messages of varying priority to that queue:
- for i in range(0, 5):
- deliveryProps = session.delivery_properties(routing_key="test-queue", priority=i+5)
- session.message_transfer(message=Message(deliveryProps, "Message %d" % (i+1)))
-
-
- #declare and bind a queue to amq.fanout through which rerouted
- #messages can be verified:
- session.queue_declare(queue="rerouted", exclusive=True, auto_delete=True, arguments={'x-qpid-priorities':10})
- session.exchange_bind(queue="rerouted", exchange="amq.fanout")
-
- #reroute messages from test queue to amq.fanout (and hence to
- #rerouted queue):
- pq = self.qmf.getObjects(_class="queue", name="test-queue")[0]
- result = pq.reroute(0, False, "amq.fanout")
- self.assertEqual(result.status, 0)
-
- #verify messages are all rerouted:
- self.subscribe(destination="incoming", queue="rerouted")
- incoming = session.incoming("incoming")
- for i in range(0, 5):
- msg = incoming.get(timeout=1)
- self.assertEqual("Message %d" % (5-i), msg.body)
-
-
def test_reroute_queue(self):
"""
Test ability to reroute messages from the head of a queue.
@@ -341,40 +309,7 @@ class ManagementTest (TestBase010):
self.assertEqual(result.status, 0)
pq.update()
self.assertEqual(pq.msgDepth,20)
-
- def test_reroute_alternate_exchange(self):
- """
- Test that when rerouting, the alternate-exchange is considered if relevant
- """
- self.startQmf()
- session = self.session
- # 1. Create 2 exchanges A and B (fanout) where B is the
- # alternate exchange for A
- session.exchange_declare(exchange="B", type="fanout")
- session.exchange_declare(exchange="A", type="fanout", alternate_exchange="B")
-
- # 2. Bind queue X to B
- session.queue_declare(queue="X", exclusive=True, auto_delete=True)
- session.exchange_bind(queue="X", exchange="B")
-
- # 3. Send 1 message to queue Y
- session.queue_declare(queue="Y", exclusive=True, auto_delete=True)
- props = session.delivery_properties(routing_key="Y")
- session.message_transfer(message=Message(props, "reroute me!"))
-
- # 4. Call reroute on queue Y and specify that messages should
- # be sent to exchange A
- y = self.qmf.getObjects(_class="queue", name="Y")[0]
- result = y.reroute(1, False, "A")
- self.assertEqual(result.status, 0)
-
- # 5. verify that the message is rerouted through B (as A has
- # no matching bindings) to X
- self.subscribe(destination="x", queue="X")
- self.assertEqual("reroute me!", session.incoming("x").get(timeout=1).body)
-
- # Cleanup
- for e in ["A", "B"]: session.exchange_delete(exchange=e)
+
def test_methods_async (self):
"""
diff --git a/qpid/tests/src/py/qpid_tests/broker_0_10/message.py b/qpid/tests/src/py/qpid_tests/broker_0_10/message.py
index b46c446833..e80333a1e6 100644
--- a/qpid/tests/src/py/qpid_tests/broker_0_10/message.py
+++ b/qpid/tests/src/py/qpid_tests/broker_0_10/message.py
@@ -245,19 +245,9 @@ class MessageTests(TestBase010):
self.fail("Got message after cancellation: " + msg)
except Empty: None
- #cancellation of non-existant consumers should be result in 404s
- try:
- session.message_cancel(destination="my-consumer")
- self.fail("Expected 404 for recancellation of subscription.")
- except SessionException, e:
- self.assertEquals(404, e.args[0].error_code)
-
- session = self.conn.session("alternate-session", timeout=10)
- try:
- session.message_cancel(destination="this-never-existed")
- self.fail("Expected 404 for cancellation of unknown subscription.")
- except SessionException, e:
- self.assertEquals(404, e.args[0].error_code)
+ #cancellation of non-existant consumers should be handled without error
+ session.message_cancel(destination="my-consumer")
+ session.message_cancel(destination="this-never-existed")
def test_ack(self):
diff --git a/qpid/tests/src/py/qpid_tests/broker_0_10/priority.py b/qpid/tests/src/py/qpid_tests/broker_0_10/priority.py
index 6a60add97e..3651a1218b 100644
--- a/qpid/tests/src/py/qpid_tests/broker_0_10/priority.py
+++ b/qpid/tests/src/py/qpid_tests/broker_0_10/priority.py
@@ -33,13 +33,13 @@ class PriorityTests (Base):
def setup_session(self):
return self.conn.session()
- def prioritised_delivery(self, priorities, levels=10, key="x-qpid-priorities"):
+ def prioritised_delivery(self, priorities, levels=10):
"""
Test that message on a queue are delivered in priority order.
"""
msgs = [Message(content=str(uuid4()), priority = p) for p in priorities]
- snd = self.ssn.sender("priority-queue; {create: sender, delete: receiver, node: {x-declare:{arguments:{'%s':%s}}}}" % (key, levels),
+ snd = self.ssn.sender("priority-queue; {create: sender, delete: receiver, node: {x-declare:{arguments:{x-qpid-priorities:%s}}}}" % levels,
durable=self.durable())
for m in msgs: snd.send(m)
@@ -50,16 +50,16 @@ class PriorityTests (Base):
assert msg.content == expected.content
self.ssn.acknowledge(msg)
- def fairshare_delivery(self, priorities, default_limit=5, limits=None, levels=10, level_key="x-qpid-priorities", fairshare_key="x-qpid-fairshare"):
+ def fairshare_delivery(self, priorities, default_limit=5, limits=None, levels=10):
msgs = [Message(content=str(uuid4()), priority = p) for p in priorities]
- limit_policy = "'%s':%s" % (fairshare_key, default_limit)
+ limit_policy = "x-qpid-fairshare:%s" % default_limit
if limits:
for k, v in limits.items():
- limit_policy += ", '%s-%s':%s" % (fairshare_key, k, v)
+ limit_policy += ", x-qpid-fairshare-%s:%s" % (k, v)
- snd = self.ssn.sender("priority-queue; {create: sender, delete: receiver, node: {x-declare:{arguments:{'%s':%s, %s}}}}"
- % (level_key, levels, limit_policy),
+ snd = self.ssn.sender("priority-queue; {create: sender, delete: receiver, node: {x-declare:{arguments:{x-qpid-priorities:%s, %s}}}}"
+ % (levels, limit_policy),
durable=self.durable())
for m in msgs: snd.send(m)
@@ -79,18 +79,12 @@ class PriorityTests (Base):
def test_prioritised_delivery_1(self):
self.prioritised_delivery(priorities = [8,9,5,1,2,2,3,4,15,7,8,10,10,2], levels = 10)
- def test_prioritised_delivery_with_alias(self):
- self.prioritised_delivery(priorities = [8,9,5,1,2,2,3,4,15,7,8,10,10,2], levels = 10, key="qpid.priorities")
-
def test_prioritised_delivery_2(self):
self.prioritised_delivery(priorities = [8,9,5,1,2,2,3,4,15,7,8,10,10,2], levels = 5)
def test_fairshare_1(self):
self.fairshare_delivery(priorities = [4,5,3,6,10,10,2,10,2,10,10,1,10,10,10,3,3,3,10,10,3,10,3,10,10,10,10,10,10,2,3])
- def test_fairshare_with_alias(self):
- self.fairshare_delivery(priorities = [4,5,3,6,10,10,2,10,2,10,10,1,10,10,10,3,3,3,10,10,2,3], level_key="qpid.priorities", fairshare_key="qpid.fairshare")
-
def test_fairshare_2(self):
self.fairshare_delivery(priorities = [10 for i in range(30)])
diff --git a/qpid/tests/src/py/qpid_tests/broker_0_10/threshold.py b/qpid/tests/src/py/qpid_tests/broker_0_10/threshold.py
index 6628ae8424..bcd3c507e2 100644
--- a/qpid/tests/src/py/qpid_tests/broker_0_10/threshold.py
+++ b/qpid/tests/src/py/qpid_tests/broker_0_10/threshold.py
@@ -60,18 +60,3 @@ class ThresholdTests (Base):
def test_alert_size_alias(self):
self.do_threshold_test("x-qpid-maximum-message-size", 15, [Message("msg-%s" % i) for i in range(3)])
-
- def test_alert_on_alert_queue(self):
- rcv = self.ssn.receiver("qmf.default.topic/agent.ind.event.org_apache_qpid_broker.queueThresholdExceeded.#; {link:{x-declare:{arguments:{'qpid.alert_count':1}}}}")
- rcvQMFv1 = self.ssn.receiver("qpid.management/console.event.#; {link:{x-declare:{arguments:{'qpid.alert_count':1}}}}")
- snd = self.ssn.sender("ttq; {create:always, node: {x-declare:{auto_delete:True,exclusive:True,arguments:{'qpid.alert_count':1}}}}")
- snd.send(Message("my-message"))
- queues = []
- for i in range(2):
- event = rcv.fetch()
- schema = event.content[0]["_schema_id"]
- assert schema["_class_name"] == "queueThresholdExceeded"
- values = event.content[0]["_values"]
- queues.append(values["qName"])
- assert "ttq" in queues, "expected event for ttq (%s)" % (queues)
-
diff --git a/qpid/tools/setup.py b/qpid/tools/setup.py
index 4231476c90..8811e49682 100755
--- a/qpid/tools/setup.py
+++ b/qpid/tools/setup.py
@@ -20,7 +20,7 @@
from distutils.core import setup
setup(name="qpid-tools",
- version="0.13",
+ version="0.9",
author="Apache Qpid",
author_email="dev@qpid.apache.org",
scripts=["src/py/qpid-cluster",
@@ -30,8 +30,7 @@ setup(name="qpid-tools",
"src/py/qpid-queue-stats",
"src/py/qpid-route",
"src/py/qpid-stat",
- "src/py/qpid-tool",
- "src/py/qmf-tool"],
+ "src/py/qpid-tool"],
url="http://qpid.apache.org/",
license="Apache Software License",
description="Diagnostic and management tools for Apache Qpid brokers.")
diff --git a/qpid/tools/src/py/qpid-cluster b/qpid/tools/src/py/qpid-cluster
index d4f9391dcf..312d59f670 100755
--- a/qpid/tools/src/py/qpid-cluster
+++ b/qpid/tools/src/py/qpid-cluster
@@ -247,7 +247,7 @@ def main(argv=None):
parser.add_option("-k", "--all-stop", action="store_true", default=False, help="Shut down the whole cluster")
parser.add_option("-f", "--force", action="store_true", default=False, help="Suppress the 'are you sure' prompt")
parser.add_option("-n", "--numeric", action="store_true", default=False, help="Don't resolve names")
-
+
opts, args = parser.parse_args(args=argv)
if args:
@@ -268,12 +268,12 @@ def main(argv=None):
if opts.del_connection:
config._delConn = opts.del_connection
- if len(config._delConn.split(":")) != 2:
+ if len(config._delConn.split(":")) != 2:
parser.error("Member ID must be of form: <host or ip>:<number>")
if opts.stop:
- config._stopId = opts.stop
- if len(config._stopId.split(":")) != 2:
+ config._stopID = opts.stop
+ if len(config._stopId.split(":")) != 2:
parser.error("Member ID must be of form: <host or ip>:<number>")
config._stopAll = opts.all_stop
@@ -303,7 +303,6 @@ def main(argv=None):
bm.Disconnect()
except Exception, e:
- raise
print str(e)
return 1
diff --git a/qpid/tools/src/py/qpid-config b/qpid/tools/src/py/qpid-config
index b6eb0558cb..9ff405541c 100755
--- a/qpid/tools/src/py/qpid-config
+++ b/qpid/tools/src/py/qpid-config
@@ -41,15 +41,15 @@ Usage: qpid-config [OPTIONS]
description = """
ADDRESS syntax:
- [username/password@] hostname [:<port>]
- [username/password@] ip-address [:<port>]
+ [username/password@] hostname
+ ip-address [:<port>]
Examples:
$ qpid-config add queue q
-$ qpid-config add exchange direct d -a localhost:5672
-$ qpid-config exchanges -a 10.1.1.7:10000
-$ qpid-config queues -a guest/guest@broker-host:10000
+$ qpid-config add exchange direct d localhost:5672
+$ qpid-config exchanges 10.1.1.7:10000
+$ qpid-config queues guest/guest@broker-host:10000
Add Exchange <type> values:
@@ -101,7 +101,6 @@ class Config:
self._flowResumeCount = None
self._flowStopSize = None
self._flowResumeSize = None
- self._extra_arguments = []
config = Config()
@@ -120,13 +119,6 @@ FLOW_STOP_COUNT = "qpid.flow_stop_count"
FLOW_RESUME_COUNT = "qpid.flow_resume_count"
FLOW_STOP_SIZE = "qpid.flow_stop_size"
FLOW_RESUME_SIZE = "qpid.flow_resume_size"
-#There are various arguments to declare that have specific program
-#options in this utility. However there is now a generic mechanism for
-#passing arguments as well. The SPECIAL_ARGS list contains the
-#arguments for which there are specific program options defined
-#i.e. the arguments for which there is special processing on add and
-#list
-SPECIAL_ARGS=[FILECOUNT,FILESIZE,MAX_QUEUE_SIZE,MAX_QUEUE_COUNT,POLICY_TYPE,CLUSTER_DURABLE,LVQ,LVQNB,MSG_SEQUENCE,IVE,QUEUE_EVENT_GENERATION,FLOW_STOP_COUNT,FLOW_STOP_SIZE,FLOW_RESUME_SIZE]
class JHelpFormatter(IndentedHelpFormatter):
"""Format usage and description without stripping newlines from usage strings
@@ -159,7 +151,7 @@ def OptionsAndArguments(argv):
group1 = OptionGroup(parser, "General Options")
group1.add_option("-t", "--timeout", action="store", type="int", default=10, metavar="<secs>", help="Maximum time to wait for broker connection (in seconds)")
group1.add_option("-b", "--bindings", action="store_true", help="Show bindings in queue or exchange list")
- group1.add_option("-a", "--broker-addr", action="store", type="string", default="localhost:5672", metavar="<address>", help="Address of qpidd broker")
+ group1.add_option("-a", "--broker-addr", action="store", type="string", default="localhost:5672", metavar="<address>", help="Maximum time to wait for broker connection (in seconds)")
group1.add_option("--sasl-mechanism", action="store", type="string", metavar="<mech>", help="SASL mechanism for authentication (e.g. EXTERNAL, ANONYMOUS, PLAIN, CRAM-MD, DIGEST-MD5, GSSAPI). SASL automatically picks the most secure available mechanism - use this option to override.")
parser.add_option_group(group1)
@@ -173,8 +165,8 @@ def OptionsAndArguments(argv):
group3.add_option("--cluster-durable", action="store_true", help="The new queue becomes durable if there is only one functioning cluster node")
group3.add_option("--file-count", action="store", type="int", default=8, metavar="<n>", help="Number of files in queue's persistence journal")
group3.add_option("--file-size", action="store", type="int", default=24, metavar="<n>", help="File size in pages (64Kib/page)")
- group3.add_option("--max-queue-size", action="store", type="int", metavar="<n>", help="Maximum in-memory queue size as bytes")
- group3.add_option("--max-queue-count", action="store", type="int", metavar="<n>", help="Maximum in-memory queue size as a number of messages")
+ group3.add_option("--max-queue-size", action="store", type="int", metavar="<n>", help="Number of files in queue's persistence journal")
+ group3.add_option("--max-queue-count", action="store", type="int", metavar="<n>", help="Number of files in queue's persistence journal")
group3.add_option("--limit-policy", action="store", choices=["none", "reject", "flow-to-disk", "ring", "ring-strict"], metavar="<policy>", help="Action to take when queue limit is reached")
group3.add_option("--order", action="store", choices=["fifo", "lvq", "lvq-no-browse"], metavar="<ordering>", help="Queue ordering policy")
group3.add_option("--generate-queue-events", action="store", type="int", metavar="<n>", help="If set to 1, every enqueue will generate an event that can be processed by registered listeners (e.g. for replication). If set to 2, events will be generated for enqueues and dequeues.")
@@ -186,8 +178,6 @@ def OptionsAndArguments(argv):
help="Turn on sender flow control when the number of queued messages exceeds this value.")
group3.add_option("--flow-resume-count", action="store", type="int", metavar="<n>",
help="Turn off sender flow control when the number of queued messages drops below this value.")
- group3.add_option("--argument", dest="extra_arguments", action="append", default=[],
- metavar="<NAME=VALUE>", help="Specify a key-value pair to add to queue arguments")
# no option for declaring an exclusive queue - which can only be used by the session that creates it.
parser.add_option_group(group3)
@@ -199,7 +189,7 @@ def OptionsAndArguments(argv):
group5 = OptionGroup(parser, "Options for Deleting Queues")
group5.add_option("--force", action="store_true", help="Force delete of queue even if it's currently used or it's not empty")
group5.add_option("--force-if-not-empty", action="store_true", help="Force delete of queue even if it's not empty")
- group5.add_option("--force-if-used", action="store_true", help="Force delete of queue even if it's currently used")
+ group5.add_option("--force-if-not-used", action="store_true", help="Force delete of queue even if it's currently used")
parser.add_option_group(group5)
group6 = OptionGroup(parser, "Options for Declaring Bindings")
@@ -236,7 +226,7 @@ def OptionsAndArguments(argv):
config._fileCount = opts.file_count
if opts.file_size:
config._fileSize = opts.file_size
- if opts.max_queue_size != None:
+ if opts.max_queue_size:
config._maxQueueSize = opts.max_queue_size
if opts.max_queue_count:
config._maxQueueCount = opts.max_queue_count
@@ -255,7 +245,7 @@ def OptionsAndArguments(argv):
config._if_unused = False
if opts.force_if_not_empty:
config._if_empty = False
- if opts.force_if_used:
+ if opts.force_if_not_used:
config._if_unused = False
if opts.sasl_mechanism:
config._sasl_mechanism = opts.sasl_mechanism
@@ -267,8 +257,6 @@ def OptionsAndArguments(argv):
config._flowStopCount = opts.flow_stop_count
if opts.flow_resume_count:
config._flowResumeCount = opts.flow_resume_count
- if opts.extra_arguments:
- config._extra_arguments = opts.extra_arguments
return args
@@ -372,7 +360,6 @@ class BrokerManager:
if self.match(ex.name, filter):
print "%-10s%-*s " % (ex.type, maxNameLen, ex.name),
args = ex.arguments
- if not args: args = {}
if ex.durable: print "--durable",
if MSG_SEQUENCE in args and args[MSG_SEQUENCE] == 1: print "--sequence",
if IVE in args and args[IVE] == 1: print "--ive",
@@ -414,26 +401,25 @@ class BrokerManager:
if self.match(q.name, filter):
print "%-*s " % (maxNameLen, q.name),
args = q.arguments
- if not args: args = {}
if q.durable: print "--durable",
if CLUSTER_DURABLE in args and args[CLUSTER_DURABLE] == 1: print "--cluster-durable",
if q.autoDelete: print "auto-del",
if q.exclusive: print "excl",
- if FILESIZE in args: print "--file-size=%s" % args[FILESIZE],
- if FILECOUNT in args: print "--file-count=%s" % args[FILECOUNT],
- if MAX_QUEUE_SIZE in args: print "--max-queue-size=%s" % args[MAX_QUEUE_SIZE],
- if MAX_QUEUE_COUNT in args: print "--max-queue-count=%s" % args[MAX_QUEUE_COUNT],
+ if FILESIZE in args: print "--file-size=%d" % args[FILESIZE],
+ if FILECOUNT in args: print "--file-count=%d" % args[FILECOUNT],
+ if MAX_QUEUE_SIZE in args: print "--max-queue-size=%d" % args[MAX_QUEUE_SIZE],
+ if MAX_QUEUE_COUNT in args: print "--max-queue-count=%d" % args[MAX_QUEUE_COUNT],
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=%s" % args[QUEUE_EVENT_GENERATION],
+ if QUEUE_EVENT_GENERATION in args: print "--generate-queue-events=%d" % args[QUEUE_EVENT_GENERATION],
if q.altExchange:
print "--alternate-exchange=%s" % q._altExchange_.name,
- if FLOW_STOP_SIZE in args: print "--flow-stop-size=%s" % args[FLOW_STOP_SIZE],
- if FLOW_RESUME_SIZE in args: print "--flow-resume-size=%s" % args[FLOW_RESUME_SIZE],
- if FLOW_STOP_COUNT in args: print "--flow-stop-count=%s" % args[FLOW_STOP_COUNT],
- if FLOW_RESUME_COUNT in args: print "--flow-resume-count=%s" % args[FLOW_RESUME_COUNT],
- print " ".join(["--argument %s=%s" % (k, v) for k,v in args.iteritems() if not k in SPECIAL_ARGS])
+ if FLOW_STOP_SIZE in args: print "--flow-stop-size=%d" % args[FLOW_STOP_SIZE],
+ if FLOW_RESUME_SIZE in args: print "--flow-resume-size=%d" % args[FLOW_RESUME_SIZE],
+ if FLOW_STOP_COUNT in args: print "--flow-stop-count=%d" % args[FLOW_STOP_COUNT],
+ if FLOW_RESUME_COUNT in args: print "--flow-resume-count=%d" % args[FLOW_RESUME_COUNT],
+ print
def QueueListRecurse(self, filter):
exchanges = self.qmf.getObjects(_class="exchange", _agent=self.brokerAgent)
@@ -478,17 +464,11 @@ class BrokerManager:
Usage()
qname = args[0]
declArgs = {}
- for a in config._extra_arguments:
- r = a.split("=", 1)
- if len(r) == 2: value = r[1]
- else: value = None
- declArgs[r[0]] = value
-
if config._durable:
declArgs[FILECOUNT] = config._fileCount
declArgs[FILESIZE] = config._fileSize
- if config._maxQueueSize != None:
+ if config._maxQueueSize:
declArgs[MAX_QUEUE_SIZE] = config._maxQueueSize
if config._maxQueueCount:
declArgs[MAX_QUEUE_COUNT] = config._maxQueueCount
diff --git a/qpid/tools/src/py/qpid-printevents b/qpid/tools/src/py/qpid-printevents
index d56d2899b1..2be2f0be8b 100755
--- a/qpid/tools/src/py/qpid-printevents
+++ b/qpid/tools/src/py/qpid-printevents
@@ -20,7 +20,7 @@
#
import os
-import optparse
+import optparse
from optparse import IndentedHelpFormatter
import sys
import socket
@@ -62,11 +62,11 @@ _usage = "%prog [options] [broker-addr]..."
_description = \
"""
-Collect and print events from one or more Qpid message brokers.
+Collect and print events from one or more Qpid message brokers.
If no broker-addr is supplied, %prog connects to 'localhost:5672'.
-[broker-addr] syntax:
+[broker-addr] syntax:
[username/password@] hostname
ip-address [:<port>]
@@ -91,20 +91,20 @@ def main(argv=None):
session = Session(console, rcvObjects=False, rcvHeartbeats=options.heartbeats, manageConnections=True)
brokers = []
try:
- try:
- for host in arguments:
- brokers.append(session.addBroker(host, None, options.sasl_mechanism))
+ for host in arguments:
+ brokers.append(session.addBroker(host, None, options.sasl_mechanism))
- while (True):
- sleep(10)
+ while (True):
+ sleep(10)
- except KeyboardInterrupt:
- print
- return 0
+ except KeyboardInterrupt:
+ print
+ return 0
+
+ except Exception, e:
+ print "Failed: %s - %s" % (e.__class__.__name__, e)
+ return 1
- except Exception, e:
- print "Failed: %s - %s" % (e.__class__.__name__, e)
- return 1
finally:
while len(brokers):
b = brokers.pop()
diff --git a/qpid/tools/src/py/qpid-route b/qpid/tools/src/py/qpid-route
index d98cefd618..3c4de85d1e 100755
--- a/qpid/tools/src/py/qpid-route
+++ b/qpid/tools/src/py/qpid-route
@@ -27,18 +27,18 @@ import locale
from qmf.console import Session, BrokerURL
usage = """
-Usage: qpid-route [OPTIONS] dynamic add <dest-broker> <src-broker> <exchange> [tag] [exclude-list] [mechanism]
+Usage: qpid-route [OPTIONS] dynamic add <dest-broker> <src-broker> <exchange> [tag] [exclude-list]
qpid-route [OPTIONS] dynamic del <dest-broker> <src-broker> <exchange>
qpid-route [OPTIONS] route add <dest-broker> <src-broker> <exchange> <routing-key> [tag] [exclude-list] [mechanism]
qpid-route [OPTIONS] route del <dest-broker> <src-broker> <exchange> <routing-key>
- qpid-route [OPTIONS] queue add <dest-broker> <src-broker> <exchange> <queue> [mechanism]
+ qpid-route [OPTIONS] queue add <dest-broker> <src-broker> <exchange> <queue>
qpid-route [OPTIONS] queue del <dest-broker> <src-broker> <exchange> <queue>
qpid-route [OPTIONS] route list [<dest-broker>]
qpid-route [OPTIONS] route flush [<dest-broker>]
qpid-route [OPTIONS] route map [<broker>]
- qpid-route [OPTIONS] link add <dest-broker> <src-broker> [mechanism]
+ qpid-route [OPTIONS] link add <dest-broker> <src-broker>
qpid-route [OPTIONS] link del <dest-broker> <src-broker>
qpid-route [OPTIONS] link list [<dest-broker>]"""
@@ -61,7 +61,7 @@ class Config:
self._transport = "tcp"
self._ack = 0
self._connTimeout = 10
- self._client_sasl_mechanism = None
+ self._sasl_mechanism = None
config = Config()
@@ -95,7 +95,7 @@ def OptionsAndArguments(argv):
parser.add_option("--ack", action="store", type="int", metavar="<n>", help="Acknowledge transfers over the bridge in batches of N")
parser.add_option("-t", "--transport", action="store", type="string", default="tcp", metavar="<transport>", help="Transport to use for links, defaults to tcp")
- parser.add_option("--client-sasl-mechanism", action="store", type="string", metavar="<mech>", help="SASL mechanism for authentication (e.g. EXTERNAL, ANONYMOUS, PLAIN, CRAM-MD, DIGEST-MD5, GSSAPI). Used when the client connects to the destination broker (not for authentication between the source and destination brokers - that is specified using the [mechanisms] argument to 'add route'). SASL automatically picks the most secure available mechanism - use this option to override.")
+ parser.add_option("--sasl-mechanism", action="store", type="string", metavar="<mech>", help="SASL mechanism for authentication (e.g. EXTERNAL, ANONYMOUS, PLAIN, CRAM-MD, DIGEST-MD5, GSSAPI). Used when the client connects to the destination broker (not for authentication between the source and destination brokers - that is specified using the [mechanisms] argument to 'add route'). SASL automatically picks the most secure available mechanism - use this option to override.")
opts, encArgs = parser.parse_args(args=argv)
@@ -131,8 +131,8 @@ def OptionsAndArguments(argv):
if opts.ack:
config._ack = opts.ack
- if opts.client_sasl_mechanism:
- config._client_sasl_mechanism = opts.client_sasl_mechanism
+ if opts.sasl_mechanism:
+ config._sasl_mechanism = opts.sasl_mechanism
return args
@@ -143,7 +143,7 @@ class RouteManager:
self.local = BrokerURL(localBroker)
self.remote = None
self.qmf = Session()
- self.broker = self.qmf.addBroker(localBroker, config._connTimeout, config._client_sasl_mechanism)
+ self.broker = self.qmf.addBroker(localBroker, config._connTimeout, config._sasl_mechanism)
self.broker._waitForStable()
self.agent = self.broker.getBrokerAgent()
@@ -166,7 +166,7 @@ class RouteManager:
return link
return None
- def addLink(self, remoteBroker, interbroker_mechanism=""):
+ def addLink(self, remoteBroker, mech="PLAIN"):
self.remote = BrokerURL(remoteBroker)
if self.local.match(self.remote.host, self.remote.port):
raise Exception("Linking broker to itself is not permitted")
@@ -176,7 +176,7 @@ class RouteManager:
link = self.getLink()
if link == None:
res = broker.connect(self.remote.host, self.remote.port, config._durable,
- interbroker_mechanism, self.remote.authName or "", self.remote.authPass or "",
+ mech, self.remote.authName or "", self.remote.authPass or "",
config._transport)
if config._verbose:
print "Connect method returned:", res.status, res.text
@@ -295,11 +295,11 @@ class RouteManager:
if b[0] != self.local.name():
self.qmf.delBroker(b[1])
- def addRoute(self, remoteBroker, exchange, routingKey, tag, excludes, interbroker_mechanism="", dynamic=False):
+ def addRoute(self, remoteBroker, exchange, routingKey, tag, excludes, mech="PLAIN", dynamic=False):
if dynamic and config._srclocal:
raise Exception("--src-local is not permitted on dynamic routes")
- self.addLink(remoteBroker, interbroker_mechanism)
+ self.addLink(remoteBroker, mech)
link = self.getLink()
if link == None:
raise Exception("Link failed to create")
@@ -320,8 +320,8 @@ class RouteManager:
if config._verbose:
print "Bridge method returned:", res.status, res.text
- def addQueueRoute(self, remoteBroker, interbroker_mechanism, exchange, queue ):
- self.addLink(remoteBroker, interbroker_mechanism)
+ def addQueueRoute(self, remoteBroker, exchange, queue):
+ self.addLink(remoteBroker)
link = self.getLink()
if link == None:
raise Exception("Link failed to create")
@@ -504,12 +504,10 @@ def main(argv=None):
rm = RouteManager(localBroker)
if group == "link":
if cmd == "add":
- if nargs < 3 or nargs > 5:
+ if nargs != 4:
Usage()
return(-1)
- interbroker_mechanism = ""
- if nargs > 4: interbroker_mechanism = args[4]
- rm.addLink(remoteBroker, interbroker_mechanism)
+ rm.addLink(remoteBroker)
elif cmd == "del":
if nargs != 4:
Usage()
@@ -520,17 +518,16 @@ def main(argv=None):
elif group == "dynamic":
if cmd == "add":
- if nargs < 5 or nargs > 8:
+ if nargs < 5 or nargs > 7:
Usage()
return(-1)
tag = ""
excludes = ""
- interbroker_mechanism = ""
+ mech = "PLAIN"
if nargs > 5: tag = args[5]
if nargs > 6: excludes = args[6]
- if nargs > 7: interbroker_mechanism = args[7]
- rm.addRoute(remoteBroker, args[4], "", tag, excludes, interbroker_mechanism, dynamic=True)
+ rm.addRoute(remoteBroker, args[4], "", tag, excludes, mech, dynamic=True)
elif cmd == "del":
if nargs != 5:
Usage()
@@ -546,11 +543,11 @@ def main(argv=None):
tag = ""
excludes = ""
- interbroker_mechanism = ""
+ mech = "PLAIN"
if nargs > 6: tag = args[6]
if nargs > 7: excludes = args[7]
- if nargs > 8: interbroker_mechanism = args[8]
- rm.addRoute(remoteBroker, args[4], args[5], tag, excludes, interbroker_mechanism, dynamic=False)
+ if nargs > 8: mech = args[8]
+ rm.addRoute(remoteBroker, args[4], args[5], tag, excludes, mech, dynamic=False)
elif cmd == "del":
if nargs != 6:
Usage()
@@ -568,21 +565,16 @@ def main(argv=None):
return(-1)
elif group == "queue":
- if nargs < 6 or nargs > 7:
+ if nargs != 6:
Usage()
return(-1)
if cmd == "add":
- interbroker_mechanism = ""
- if nargs > 6: interbroker_mechanism = args[6]
- rm.addQueueRoute(remoteBroker, interbroker_mechanism, exchange=args[4], queue=args[5] )
+ rm.addQueueRoute(remoteBroker, exchange=args[4], queue=args[5])
elif cmd == "del":
rm.delQueueRoute(remoteBroker, exchange=args[4], queue=args[5])
else:
Usage()
return(-1)
- else:
- Usage()
- return(-1)
except Exception,e:
if rm:
diff --git a/qpid/tools/src/py/qpid-tool b/qpid/tools/src/py/qpid-tool
index d6bb9bcaea..d3b0aa4097 100755
--- a/qpid/tools/src/py/qpid-tool
+++ b/qpid/tools/src/py/qpid-tool
@@ -259,24 +259,7 @@ class QmfData(Console):
return
displayId = long(tokens[0])
methodName = tokens[1]
- args = []
- for arg in tokens[2:]:
- ##
- ## If the argument is a map, list, boolean, integer, or floating (one decimal point),
- ## run it through the Python evaluator so it is converted to the correct type.
- ##
- ## TODO: use a regex for this instead of this convoluted logic,
- ## or even consider passing all args through eval() [which would
- ## be a minor change to the interface as string args would then
- ## always need to be quoted as strings within a map/list would
- ## now]
- if arg[0] == '{' or arg[0] == '[' or arg[0] == '"' or arg[0] == '\'' or arg == "True" or arg == "False" or \
- ((arg.count('.') < 2 and (arg.count('-') == 0 or \
- (arg.count('-') == 1 and arg[0] == '-')) and \
- arg.replace('.','').replace('-','').isdigit())):
- args.append(eval(arg))
- else:
- args.append(arg)
+ args = tokens[2:]
obj = None
try: